10 #include <talloc/talloc.h>
12 #include "device-handler.h"
16 static int is_prefix_ignorecase(const char *str, const char *prefix)
18 return !strncasecmp(str, prefix, strlen(prefix));
21 struct devpath_resource_info {
25 static struct discover_device *parse_device_string(
26 struct device_handler *handler, const char *devstr)
28 if (is_prefix_ignorecase(devstr, "uuid="))
29 return device_lookup_by_uuid(handler, devstr + strlen("uuid"));
31 if (is_prefix_ignorecase(devstr, "label="))
32 return device_lookup_by_label(handler,
33 devstr + strlen("label="));
35 return device_lookup_by_name(handler, devstr);
37 static void resolve_devpath_against_device(struct resource *res,
38 struct discover_device *dev, const char *path)
40 char *resolved_path = join_paths(res, dev->mount_path, path);
41 res->url = pb_url_parse(res, resolved_path);
45 struct resource *create_devpath_resource(struct discover_boot_option *opt,
46 struct discover_device *orig_device,
49 struct devpath_resource_info *info;
50 char *pos, *devstr, *path;
54 res = talloc(opt, struct resource);
56 pos = strchr(devpath, ':');
58 /* do we have a "://" scheme separator? */
59 if (pos && pos[1] && pos[1] == '/' && pos[2] && pos[2] == '/') {
60 url = pb_url_parse(res, devpath);
62 if (url->scheme != pb_url_file) {
63 /* not a file? we're ready to go */
67 /* we've been passed a file:// URL, which has no device
68 * specifier. We can resolve against the original
70 resolve_devpath_against_device(res, orig_device,
77 /* if there was no device specified, we can resolve now */
79 resolve_devpath_against_device(res, orig_device, devpath);
83 devstr = talloc_strndup(res, devpath, pos - devpath);
84 path = talloc_strdup(res, pos + 1);
86 pb_log("%s: resource depends on device %s\n", __func__, devstr);
88 /* defer resolution until we can find a suitable matching device */
89 info = talloc(res, struct devpath_resource_info);
93 res->resolved = false;
99 bool resolve_devpath_resource(struct device_handler *handler,
100 struct resource *res)
102 struct devpath_resource_info *info = res->info;
103 struct discover_device *dev;
105 assert(!res->resolved);
107 dev = parse_device_string(handler, info->dev);
112 resolve_devpath_against_device(res, dev, info->path);
118 struct resource *create_url_resource(struct discover_boot_option *opt,
121 struct resource *res;
123 res = talloc(opt, struct resource);
125 res->resolved = true;