X-Git-Url: http://git.ozlabs.org/?p=petitboot;a=blobdiff_plain;f=discover%2Fpaths.c;h=72d07b20c4cee09b354510558e4558e405e4b828;hp=2373c28f560555025d7b522733551b5cb3dffe22;hb=5b71bc5697e403b586ec313148e652406b5426b6;hpb=32e6a41f33e5576716b351bd473a27939fe94fa1 diff --git a/discover/paths.c b/discover/paths.c index 2373c28..72d07b2 100644 --- a/discover/paths.c +++ b/discover/paths.c @@ -4,24 +4,41 @@ #include #include +#include + #include "paths.h" -static char *mount_base; +#define DEVICE_MOUNT_BASE (LOCAL_STATE_DIR "/petitboot/mnt") -struct device_map { +struct mount_map { char *dev, *mnt; }; -#define DEVICE_MAP_SIZE 32 -static struct device_map device_map[DEVICE_MAP_SIZE]; +static struct mount_map *mount_map; +static int mount_map_size; + +static int is_prefix(const char *str, const char *prefix) +{ + return !strncmp(str, prefix, strlen(prefix)); +} + +static int is_prefix_ignorecase(const char *str, const char *prefix) +{ + return !strncasecmp(str, prefix, strlen(prefix)); +} -char *encode_label(const char *label) +const char *mount_base(void) +{ + return DEVICE_MOUNT_BASE; +} + +char *encode_label(void *alloc_ctx, const char *label) { char *str, *c; int i; /* the label can be expanded by up to four times */ - str = malloc(strlen(label) * 4 + 1); + str = talloc_size(alloc_ctx, strlen(label) * 4 + 1); c = str; for (i = 0; i < strlen(label); i++) { @@ -40,60 +57,64 @@ char *encode_label(const char *label) return str; } -char *parse_device_path(const char *dev_str, const char *cur_dev) +char *parse_device_path(void *alloc_ctx, + const char *dev_str, const char *cur_dev) { char *dev, tmp[256], *enc; - if (!strncasecmp(dev_str, "uuid=", 5)) { - asprintf(&dev, "/dev/disk/by-uuid/%s", dev_str + 5); + if (is_prefix_ignorecase(dev_str, "uuid=")) { + dev = talloc_asprintf(alloc_ctx, "/dev/disk/by-uuid/%s", + dev_str + strlen("uuid=")); return dev; } - if (!strncasecmp(dev_str, "label=", 6)) { - enc = encode_label(dev_str + 6); - asprintf(&dev, "/dev/disk/by-label/%s", enc); - free(enc); + if (is_prefix_ignorecase(dev_str, "label=")) { + enc = encode_label(NULL, dev_str + strlen("label=")); + dev = talloc_asprintf(alloc_ctx, "/dev/disk/by-label/%s", enc); + talloc_free(enc); return dev; } /* normalise '/dev/foo' to 'foo' for easy comparisons, we'll expand * back before returning. */ - if (!strncmp(dev_str, "/dev/", 5)) - dev_str += 5; + if (is_prefix(dev_str, "/dev/")) + dev_str += strlen("/dev/"); /* PS3 hack: if we're reading from a ps3dx device, and we refer to * a sdx device, remap to ps3dx */ - if (cur_dev && !strncmp(cur_dev, "/dev/ps3d", 9) - && !strncmp(dev_str, "sd", 2)) { + if (cur_dev && is_prefix(cur_dev, "/dev/ps3d") + && is_prefix(dev_str, "sd")) { snprintf(tmp, 255, "ps3d%s", dev_str + 2); dev_str = tmp; } - return join_paths("/dev", dev_str); + return join_paths(alloc_ctx, "/dev", dev_str); } const char *mountpoint_for_device(const char *dev) { int i; - if (!strncmp(dev, "/dev/", 5)) - dev += 5; + if (is_prefix(dev, "/dev/")) + dev += strlen("/dev/"); /* check existing entries in the map */ - for (i = 0; (i < DEVICE_MAP_SIZE) && device_map[i].dev; i++) - if (!strcmp(device_map[i].dev, dev)) - return device_map[i].mnt; - - if (i == DEVICE_MAP_SIZE) - return NULL; - - device_map[i].dev = strdup(dev); - device_map[i].mnt = join_paths(mount_base, dev); - return device_map[i].mnt; + for (i = 0; i < mount_map_size; i++) + if (!strcmp(mount_map[i].dev, dev)) + return mount_map[i].mnt; + + /* no existing entry, create a new one */ + i = mount_map_size++; + mount_map = talloc_realloc(NULL, mount_map, + struct mount_map, mount_map_size); + + mount_map[i].dev = talloc_strdup(mount_map, dev); + mount_map[i].mnt = join_paths(mount_map, DEVICE_MOUNT_BASE, dev); + return mount_map[i].mnt; } -char *resolve_path(const char *path, const char *current_dev) +char *resolve_path(void *alloc_ctx, const char *path, const char *current_dev) { char *ret; const char *devpath, *sep; @@ -101,35 +122,28 @@ char *resolve_path(const char *path, const char *current_dev) sep = strchr(path, ':'); if (!sep) { devpath = mountpoint_for_device(current_dev); - ret = join_paths(devpath, path); + ret = join_paths(alloc_ctx, devpath, path); } else { /* parse just the device name into dev */ char *tmp, *dev; - tmp = strndup(path, sep - path); - dev = parse_device_path(tmp, current_dev); + tmp = talloc_strndup(NULL, path, sep - path); + dev = parse_device_path(NULL, tmp, current_dev); devpath = mountpoint_for_device(dev); - ret = join_paths(devpath, sep + 1); + ret = join_paths(alloc_ctx, devpath, sep + 1); - free(dev); - free(tmp); + talloc_free(dev); + talloc_free(tmp); } return ret; } -void set_mount_base(const char *path) -{ - if (mount_base) - free(mount_base); - mount_base = strdup(path); -} - -char *join_paths(const char *a, const char *b) +char *join_paths(void *alloc_ctx, const char *a, const char *b) { char *full_path; - full_path = malloc(strlen(a) + strlen(b) + 2); + full_path = talloc_array(alloc_ctx, char, strlen(a) + strlen(b) + 2); strcpy(full_path, a); if (b[0] != '/' && a[strlen(a) - 1] != '/')