struct discover_context *ctx)
{
struct discover_device *dev = ctx->device;
+ struct discover_boot_option *opt, *tmp;
unsigned int i, existing_device;
- struct boot_option *opt, *tmp;
/* do we already have this device? */
for (i = 0; i < handler->n_devices; i++) {
/* move boot options from the context to the device */
list_for_each_entry_safe(&ctx->boot_options, opt, tmp, list) {
list_remove(&opt->list);
- list_add(&dev->device->boot_options, &opt->list);
- dev->device->n_options++;
- discover_server_notify_boot_option_add(handler->server, opt);
+ list_add(&dev->boot_options, &opt->list);
+ talloc_steal(dev, opt);
+ discover_server_notify_boot_option_add(handler->server,
+ opt->option);
}
}
void discover_context_add_boot_option(struct discover_context *ctx,
- struct boot_option *boot_option)
+ struct discover_boot_option *boot_option)
{
list_add(&ctx->boot_options, &boot_option->list);
talloc_steal(ctx, boot_option);
* device_handler_get_device - Get a handler device by index.
*/
-const struct device *device_handler_get_device(
+const struct discover_device *device_handler_get_device(
const struct device_handler *handler, unsigned int index)
{
if (index >= handler->n_devices) {
return NULL;
}
- return handler->devices[index]->device;
+ return handler->devices[index];
}
-static void setup_device_links(struct discover_context *ctx)
+static void setup_device_links(struct discover_device *dev)
{
- struct discover_device *dev = ctx->device;
struct link {
- char *env, *dir;
+ const char *dir, *val;
} *link, links[] = {
{
- .env = "ID_FS_UUID",
- .dir = "disk/by-uuid"
+ .dir = "disk/by-uuid",
+ .val = dev->uuid,
},
{
- .env = "ID_FS_LABEL",
- .dir = "disk/by-label"
+ .dir = "disk/by-label",
+ .val = dev->label,
},
{
- .env = NULL
+ .dir = NULL
}
};
- for (link = links; link->env; link++) {
+ for (link = links; link->dir; link++) {
char *enc, *dir, *path;
- const char *value;
- value = event_get_param(ctx->event, link->env);
- if (!value || !*value)
+ if (!link->val || !*link->val)
continue;
- enc = encode_label(ctx, value);
- dir = join_paths(ctx, mount_base(), link->dir);
- path = join_paths(dev, dir, value);
+ enc = encode_label(dev, link->val);
+ dir = join_paths(dev, mount_base(), link->dir);
+ path = join_paths(dev, dir, enc);
if (!pb_mkdir_recursive(dir)) {
unlink(path);
unlink(dev->links[i]);
}
-static int mount_device(struct discover_context *ctx)
+static int mount_device(struct discover_device *dev)
{
- struct discover_device *dev = ctx->device;
const char *mountpoint;
const char *argv[6];
goto out_rmdir;
}
- setup_device_links(ctx);
+ setup_device_links(dev);
return 0;
out_rmdir:
dev = talloc_zero(ctx, struct discover_device);
dev->device = talloc_zero(dev, struct device);
- list_init(&dev->device->boot_options);
+ list_init(&dev->boot_options);
devname = event_get_param(ctx->event, "DEVNAME");
if (devname)
return dev;
}
+struct discover_boot_option *discover_boot_option_create(
+ struct discover_context *ctx,
+ struct discover_device *device)
+{
+ struct discover_boot_option *opt;
+
+ opt = talloc_zero(ctx, struct discover_boot_option);
+ opt->option = talloc_zero(opt, struct boot_option);
+ opt->device = device;
+
+ return opt;
+}
+
+
static int handle_add_udev_event(struct device_handler *handler,
struct event *event)
{
struct discover_context *ctx;
struct discover_device *dev;
+ const char *param;
int rc;
/* create our context */
ctx->device = dev;
- rc = mount_device(ctx);
+ /* try to parse UUID and labels */
+ param = event_get_param(ctx->event, "ID_FS_UUID");
+ if (param)
+ dev->uuid = talloc_strdup(dev, param);
+
+ param = event_get_param(ctx->event, "ID_FS_LABEL");
+ if (param)
+ dev->label = talloc_strdup(dev, param);
+
+ rc = mount_device(dev);
if (rc) {
talloc_free(ctx);
return 0;
talloc_free(handler);
}
-static struct boot_option *find_boot_option_by_id(
+static int device_match_path(struct discover_device *dev, const char *path)
+{
+ return !strcmp(dev->device_path, path);
+}
+
+static int device_match_uuid(struct discover_device *dev, const char *uuid)
+{
+ return dev->uuid && !strcmp(dev->uuid, uuid);
+}
+
+static int device_match_label(struct discover_device *dev, const char *label)
+{
+ return dev->label && !strcmp(dev->label, label);
+}
+
+static int device_match_id(struct discover_device *dev, const char *id)
+{
+ return !strcmp(dev->device->id, id);
+}
+
+static struct discover_device *device_lookup(
+ struct device_handler *device_handler,
+ int (match_fn)(struct discover_device *, const char *),
+ const char *str)
+{
+ struct discover_device *dev;
+ unsigned int i;
+
+ if (!str)
+ return NULL;
+
+ for (i = 0; i < device_handler->n_devices; i++) {
+ dev = device_handler->devices[i];
+
+ if (match_fn(dev, str))
+ return dev;
+ }
+
+ return NULL;
+}
+
+struct discover_device *device_lookup_by_name(struct device_handler *handler,
+ const char *name)
+{
+ struct discover_device *dev;
+ char *path;
+
+ if (strncmp(name, "/dev/", strlen("/dev/")))
+ path = talloc_asprintf(NULL, "/dev/%s", name);
+ else
+ path = talloc_strdup(NULL, name);
+
+ dev = device_lookup_by_path(handler, path);
+
+ talloc_free(path);
+
+ return dev;
+}
+
+struct discover_device *device_lookup_by_path(
+ struct device_handler *device_handler,
+ const char *path)
+{
+ return device_lookup(device_handler, device_match_path, path);
+}
+
+struct discover_device *device_lookup_by_uuid(
+ struct device_handler *device_handler,
+ const char *uuid)
+{
+ return device_lookup(device_handler, device_match_uuid, uuid);
+}
+
+struct discover_device *device_lookup_by_label(
+ struct device_handler *device_handler,
+ const char *label)
+{
+ return device_lookup(device_handler, device_match_label, label);
+}
+
+struct discover_device *device_lookup_by_id(
+ struct device_handler *device_handler,
+ const char *id)
+{
+ return device_lookup(device_handler, device_match_id, id);
+}
+
+static struct discover_boot_option *find_boot_option_by_id(
struct device_handler *handler, const char *id)
{
unsigned int i;
for (i = 0; i < handler->n_devices; i++) {
struct discover_device *dev = handler->devices[i];
- struct boot_option *opt;
+ struct discover_boot_option *opt;
- list_for_each_entry(&dev->device->boot_options, opt, list)
- if (!strcmp(opt->id, id))
+ list_for_each_entry(&dev->boot_options, opt, list)
+ if (!strcmp(opt->option->id, id))
return opt;
}
void device_handler_boot(struct device_handler *handler,
struct boot_command *cmd)
{
- struct boot_option *opt;
+ struct discover_boot_option *opt;
opt = find_boot_option_by_id(handler, cmd->option_id);
- boot(handler, opt, cmd, handler->dry_run);
+ boot(handler, opt->option, cmd, handler->dry_run);
}