]> git.ozlabs.org Git - petitboot/blobdiff - discover/device-handler.c
discover: allow separate lifetimes for network interfaces and discover devices
[petitboot] / discover / device-handler.c
index 352a477d16230c49b4a14c6201bf3d7ab03de649..7f7081df5f6fc27abd033788d2202c5cca1988c2 100644 (file)
@@ -57,6 +57,7 @@ static int mount_device(struct discover_device *dev);
 static int umount_device(struct discover_device *dev);
 
 static int device_handler_init_sources(struct device_handler *handler);
+static void device_handler_reinit_sources(struct device_handler *handler);
 
 void discover_context_add_boot_option(struct discover_context *ctx,
                struct discover_boot_option *boot_option)
@@ -293,6 +294,31 @@ struct device_handler *device_handler_init(struct discover_server *server,
        return handler;
 }
 
+void device_handler_reinit(struct device_handler *handler)
+{
+       struct discover_boot_option *opt, *tmp;
+       unsigned int i;
+
+       device_handler_cancel_default(handler);
+
+       /* free unresolved boot options */
+       list_for_each_entry_safe(&handler->unresolved_boot_options,
+                       opt, tmp, list)
+               talloc_free(opt);
+       list_init(&handler->unresolved_boot_options);
+
+       /* drop all devices */
+       for (i = 0; i < handler->n_devices; i++)
+               discover_server_notify_device_remove(handler->server,
+                               handler->devices[i]->device);
+
+       talloc_free(handler->devices);
+       handler->devices = NULL;
+       handler->n_devices = 0;
+
+       device_handler_reinit_sources(handler);
+}
+
 void device_handler_remove(struct device_handler *handler,
                struct discover_device *device)
 {
@@ -318,6 +344,11 @@ void device_handler_remove(struct device_handler *handler,
                talloc_free(opt);
        }
 
+       /* if this is a network device, we have to unregister it from the
+        * network code */
+       if (device->device->type == DEVICE_TYPE_NETWORK)
+               network_unregister_device(handler->network, device);
+
        handler->n_devices--;
        memmove(&handler->devices[i], &handler->devices[i + 1],
                (handler->n_devices - i) * sizeof(handler->devices[0]));
@@ -347,7 +378,7 @@ static void countdown_status(struct device_handler *handler,
        status.progress = -1;
        status.detail = NULL;
        status.message = talloc_asprintf(handler,
-                       "Booting %s in %u sec", opt->option->name, sec);
+                       "Booting in %d sec: %s", sec, opt->option->name);
 
        discover_server_notify_boot_status(handler->server, &status);
 
@@ -620,6 +651,8 @@ void device_handler_add_device(struct device_handler *handler,
                                struct discover_device *, handler->n_devices);
        handler->devices[handler->n_devices - 1] = device;
 
+       if (device->device->type == DEVICE_TYPE_NETWORK)
+               network_register_device(handler->network, device);
 }
 
 /* Start discovery on a hotplugged device. The device will be in our devices
@@ -763,6 +796,7 @@ void device_handler_update_config(struct device_handler *handler,
 {
        config_set(config);
        discover_server_notify_config(handler->server, config);
+       device_handler_reinit(handler);
 }
 
 #ifndef PETITBOOT_TEST
@@ -786,6 +820,15 @@ static int device_handler_init_sources(struct device_handler *handler)
        return 0;
 }
 
+static void device_handler_reinit_sources(struct device_handler *handler)
+{
+       udev_reinit(handler->udev);
+
+       network_shutdown(handler->network);
+       handler->network = network_init(handler, handler->waitset,
+                       handler->dry_run);
+}
+
 static bool check_existing_mount(struct discover_device *dev)
 {
        struct stat devstat, mntstat;
@@ -953,6 +996,11 @@ static int device_handler_init_sources(
        return 0;
 }
 
+static void device_handler_reinit_sources(
+               struct device_handler *handler __attribute__((unused)))
+{
+}
+
 static int umount_device(struct discover_device *dev __attribute__((unused)))
 {
        return 0;