summaryrefslogtreecommitdiffstats
path: root/discover
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
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')
-rw-r--r--discover/device-handler.c98
-rw-r--r--discover/device-handler.h14
2 files changed, 112 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.
*/
diff --git a/discover/device-handler.h b/discover/device-handler.h
index b592c46..5877733 100644
--- a/discover/device-handler.h
+++ b/discover/device-handler.h
@@ -26,6 +26,7 @@ struct discover_device {
char *mount_path;
const char *device_path;
+ struct ramdisk_device *ramdisk;
bool mounted;
bool mounted_rw;
bool unmount;
@@ -59,6 +60,14 @@ struct discover_context {
void *test_data;
};
+struct ramdisk_device {
+ const char *path;
+ char *snapshot;
+ char *origin;
+ char *base;
+ unsigned int sectors;
+};
+
struct device_handler *device_handler_init(struct discover_server *server,
struct waitset *waitset, int dry_run);
@@ -72,6 +81,11 @@ struct discover_device *discover_device_create(struct device_handler *handler,
const char *id);
void device_handler_add_device(struct device_handler *handler,
struct discover_device *device);
+void device_handler_add_ramdisk(struct device_handler *handler,
+ const char *path);
+struct ramdisk_device *device_handler_get_ramdisk(
+ struct device_handler *handler);
+void device_handler_release_ramdisk(struct discover_device *device);
int device_handler_discover(struct device_handler *handler,
struct discover_device *dev);
int device_handler_dhcp(struct device_handler *handler,
OpenPOWER on IntegriCloud