summaryrefslogtreecommitdiffstats
path: root/discover/device-handler.c
diff options
context:
space:
mode:
authorSamuel Mendoza-Jonas <sam.mj@au1.ibm.com>2015-05-13 16:45:42 +1000
committerSamuel Mendoza-Jonas <sam.mj@au1.ibm.com>2015-08-06 14:08:20 +1000
commitd2f71341c8077c649c00f75c1f6c3f590c1b2576 (patch)
tree35c4a2efa2d31c24e30c59eb04f32ac6a302cc24 /discover/device-handler.c
parentfa5c9dfa37957d45b13424ade53d477f0b123102 (diff)
downloadtalos-petitboot-d2f71341c8077c649c00f75c1f6c3f590c1b2576.tar.gz
talos-petitboot-d2f71341c8077c649c00f75c1f6c3f590c1b2576.zip
discover: Keep track of available ramdisk devices
Store information on available ramdisk devices when they are recognised by udev, and add functions to 'reserve' and 'release' these devices. This will be used to associate device-mapper snapshots with a backing ramdisk in a following patch. Signed-off-by: Samuel Mendoza-Jonas <sam.mj@au1.ibm.com>
Diffstat (limited to 'discover/device-handler.c')
-rw-r--r--discover/device-handler.c98
1 files changed, 98 insertions, 0 deletions
diff --git a/discover/device-handler.c b/discover/device-handler.c
index d2b50b5..cd16399 100644
--- a/discover/device-handler.c
+++ b/discover/device-handler.c
@@ -56,6 +56,9 @@ struct device_handler {
struct discover_device **devices;
unsigned int n_devices;
+ struct ramdisk_device **ramdisks;
+ unsigned int n_ramdisks;
+
struct waitset *waitset;
struct waiter *timeout_waiter;
bool autoboot_enabled;
@@ -319,6 +322,7 @@ struct device_handler *device_handler_init(struct discover_server *server,
void device_handler_reinit(struct device_handler *handler)
{
struct discover_boot_option *opt, *tmp;
+ struct ramdisk_device *ramdisk;
unsigned int i;
device_handler_cancel_default(handler);
@@ -333,12 +337,17 @@ void device_handler_reinit(struct device_handler *handler)
for (i = 0; i < handler->n_devices; i++) {
discover_server_notify_device_remove(handler->server,
handler->devices[i]->device);
+ ramdisk = handler->devices[i]->ramdisk;
talloc_free(handler->devices[i]);
+ talloc_free(ramdisk);
}
talloc_free(handler->devices);
handler->devices = NULL;
handler->n_devices = 0;
+ talloc_free(handler->ramdisks);
+ handler->ramdisks = NULL;
+ handler->n_ramdisks = 0;
device_handler_reinit_sources(handler);
}
@@ -750,6 +759,95 @@ void device_handler_add_device(struct device_handler *handler,
network_register_device(handler->network, device);
}
+void device_handler_add_ramdisk(struct device_handler *handler,
+ const char *path)
+{
+ struct ramdisk_device *dev;
+ unsigned int i;
+
+ if (!path)
+ return;
+
+ for (i = 0; i < handler->n_ramdisks; i++)
+ if (!strcmp(handler->ramdisks[i]->path, path))
+ return;
+
+ dev = talloc_zero(handler, struct ramdisk_device);
+ if (!dev) {
+ pb_log("Failed to allocate memory to track %s\n", path);
+ return;
+ }
+
+ dev->path = talloc_strdup(handler, path);
+
+ handler->ramdisks = talloc_realloc(handler, handler->ramdisks,
+ struct ramdisk_device *,
+ handler->n_ramdisks + 1);
+ if (!handler->ramdisks) {
+ pb_log("Failed to reallocate memory"
+ "- ramdisk tracking inconsistent!\n");
+ return;
+ }
+
+ handler->ramdisks[i] = dev;
+ i = handler->n_ramdisks++;
+}
+
+struct ramdisk_device *device_handler_get_ramdisk(
+ struct device_handler *handler)
+{
+ unsigned int i;
+ char *name;
+ dev_t id;
+
+ /* Check if free ramdisk exists */
+ for (i = 0; i < handler->n_ramdisks; i++)
+ if (!handler->ramdisks[i]->snapshot &&
+ !handler->ramdisks[i]->origin &&
+ !handler->ramdisks[i]->base)
+ return handler->ramdisks[i];
+
+ /* Otherwise create a new one */
+ name = talloc_asprintf(handler, "/dev/ram%d",
+ handler->n_ramdisks);
+ if (!name) {
+ pb_debug("Failed to allocate memory to name /dev/ram%d",
+ handler->n_ramdisks);
+ return NULL;
+ }
+
+ id = makedev(1, handler->n_ramdisks);
+ if (mknod(name, S_IFBLK, id)) {
+ if (errno == EEXIST) {
+ /* We haven't yet received updates for existing
+ * ramdisks - add and use this one */
+ pb_debug("Using untracked ramdisk %s\n", name);
+ } else {
+ pb_log("Failed to create new ramdisk %s: %s\n",
+ name, strerror(errno));
+ return NULL;
+ }
+ }
+ device_handler_add_ramdisk(handler, name);
+ talloc_free(name);
+
+ return handler->ramdisks[i];
+}
+
+void device_handler_release_ramdisk(struct discover_device *device)
+{
+ struct ramdisk_device *ramdisk = device->ramdisk;
+
+ talloc_free(ramdisk->snapshot);
+ talloc_free(ramdisk->origin);
+ talloc_free(ramdisk->base);
+
+ ramdisk->snapshot = ramdisk->origin = ramdisk->base = NULL;
+ ramdisk->sectors = 0;
+
+ device->ramdisk = NULL;
+}
+
/* Start discovery on a hotplugged device. The device will be in our devices
* array, but has only just been initialised by the hotplug source.
*/
OpenPOWER on IntegriCloud