+ 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.
+ */
+int device_handler_discover(struct device_handler *handler,
+ struct discover_device *dev)
+{
+ struct discover_context *ctx;
+ struct boot_status *status;
+ int rc;
+
+ status = talloc_zero(handler, struct boot_status);
+ status->type = BOOT_STATUS_INFO;
+ status->message = talloc_asprintf(status, "Processing %s device %s",
+ device_type_display_name(dev->device->type),
+ dev->device->id);
+ boot_status(handler, status);
+
+ process_boot_option_queue(handler);
+
+ /* create our context */
+ ctx = device_handler_discover_context_create(handler, dev);
+
+ rc = mount_device(dev);
+ if (rc)
+ goto out;
+
+ /* add this device to our system info */
+ system_info_register_blockdev(dev->device->id, dev->uuid,
+ dev->mount_path);
+