]> git.ozlabs.org Git - petitboot/commitdiff
Rework device-path handling
authorJeremy Kerr <jk@ozlabs.org>
Mon, 7 Jan 2008 08:15:03 +0000 (19:15 +1100)
committerJeremy Kerr <jk@ozlabs.org>
Mon, 7 Jan 2008 08:15:03 +0000 (19:15 +1100)
Pass full device paths around, rather than shortened device names and
mountpoints.

The parse() function has been updated to only take a device path; the
mountpoint can be derived with mountpoint_for_device. Also, add
initial handling for uuid= and label= syntaxes.

This allows us to remap ps3 devices where necessary.

Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
15 files changed:
devices/kboot-parser.c
devices/native-parser.c
devices/parser-test.sh
devices/parser-tests/001/expected-output
devices/parser-tests/002/expected-output
devices/parser-tests/003/expected-output [new file with mode: 0644]
devices/parser-tests/003/ps3da1/etc/kboot.conf [new file with mode: 0644]
devices/parser-tests/004/expected-output [new file with mode: 0644]
devices/parser-tests/004/rootdev [new file with mode: 0644]
devices/parser-tests/004/sda1/etc/kboot.conf [new file with mode: 0644]
devices/parser.c
devices/parser.h
devices/paths.c
devices/paths.h
devices/yaboot-parser.c

index b70d5fca82b1290efba3f44550dc95d0ace1c582..9388981883dd9c5e3d59237c33127fdab92e7507 100644 (file)
@@ -15,7 +15,7 @@
 
 #define buf_size 1024
 
-static const char *mountpoint;
+static const char *devpath;
 
 static int param_is_ignored(const char *param)
 {
@@ -138,13 +138,13 @@ static int parse_option(struct boot_option *opt, char *config)
 
        /* if there's no space, it's only a kernel image with no params */
        if (!pos) {
-               opt->boot_image_file = resolve_path(config, mountpoint);
+               opt->boot_image_file = resolve_path(config, devpath);
                opt->description = strdup(config);
                return 1;
        }
 
        *pos = 0;
-       opt->boot_image_file = resolve_path(config, mountpoint);
+       opt->boot_image_file = resolve_path(config, devpath);
 
        cmdline = malloc(buf_size);
        *cmdline = 0;
@@ -179,7 +179,7 @@ static int parse_option(struct boot_option *opt, char *config)
                free(cmdline);
                cmdline = tmp;
 
-               opt->initrd_file = resolve_path(initrd, mountpoint);
+               opt->initrd_file = resolve_path(initrd, devpath);
        }
 
        if (root) {
@@ -236,16 +236,16 @@ static void parse_buf(struct device *dev, char *buf)
        }
 }
 
-static int parse(const char *devicepath, const char *_mountpoint)
+static int parse(const char *device)
 {
        char *filepath, *buf;
        int fd, len, rc = 0;
        struct stat stat;
        struct device *dev;
 
-       mountpoint = _mountpoint;
+       devpath = device;
 
-       filepath = join_paths(mountpoint, "/etc/kboot.conf");
+       filepath = resolve_path("/etc/kboot.conf", devpath);
 
        fd = open(filepath, O_RDONLY);
        if (fd < 0)
@@ -265,7 +265,7 @@ static int parse(const char *devicepath, const char *_mountpoint)
 
        dev = malloc(sizeof(*dev));
        memset(dev, 0, sizeof(*dev));
-       dev->id = strdup(devicepath);
+       dev->id = strdup(device);
        dev->icon_file = strdup(generic_icon_file(guess_device_type()));
 
        parse_buf(dev, buf);
index 5f7945111fcfa6e4712a55df2024167e951d8598..24713b19542da150de6b101c2adab1b036245f2b 100644 (file)
@@ -1,6 +1,7 @@
 
 #include "parser.h"
 #include "params.h"
+#include "paths.h"
 
 #include <stdlib.h>
 #include <stdio.h>
@@ -10,7 +11,7 @@ const char *conf_filename = "/boot/petitboot.conf";
 
 static struct boot_option *cur_opt;
 static struct device *dev;
-static const char *mountpoint;
+static const char *devpath;
 int device_added;
 
 int check_and_add_device(struct device *dev)
@@ -47,13 +48,13 @@ static void set_boot_option_parameter(struct boot_option *opt,
                opt->description = strdup(value);
 
        else if (streq(name, "image"))
-               opt->boot_image_file = join_paths(mountpoint, value);
+               opt->boot_image_file = resolve_path(value, devpath);
 
        else if (streq(name, "icon"))
-               opt->icon_file = join_paths(mountpoint, value);
+               opt->icon_file = resolve_path(value, devpath);
 
        else if (streq(name, "initrd"))
-               opt->initrd_file = join_paths(mountpoint, value);
+               opt->initrd_file =resolve_path(value, devpath);
 
        else if (streq(name, "args"))
                opt->boot_args = strdup(value);
@@ -72,7 +73,7 @@ static void set_device_parameter(struct device *dev,
                dev->description = strdup(value);
 
        else if (streq(name, "icon"))
-               dev->icon_file = join_paths(mountpoint, value);
+               dev->icon_file = resolve_path(value, devpath);
 }
 
 static int parameter(char *param_name, char *param_value)
@@ -85,19 +86,17 @@ static int parameter(char *param_name, char *param_value)
 }
 
 
-int parse(const char *devicepath, const char *_mountpoint)
+int parse(const char *device)
 {
        char *filepath;
        int rc;
 
-       mountpoint = _mountpoint;
-
-       filepath = join_paths(mountpoint, conf_filename);
+       filepath = resolve_path(conf_filename, device);
 
        cur_opt = NULL;
        dev = malloc(sizeof(*dev));
        memset(dev, 0, sizeof(*dev));
-       dev->id = strdup(devicepath);
+       dev->id = strdup(device);
 
        rc = pm_process(filepath, section, parameter);
        if (!rc)
index cdd814b7c13b53fe35e91fe42cde9b9600f508ff..140601e70ad7de5cea7f6395931616cbbf11aaf5 100755 (executable)
@@ -11,7 +11,7 @@ function test_dir()
        then
                rootdev=$(cat "$dir/rootdev")
        fi
-       ./parser-test "$dir" $rootdev 2>/dev/null |
+       ./parser-test "$dir" /dev/$rootdev 2>/dev/null |
                diff -u "$dir/expected-output" -
 }
 
index 9d2d0ecc8c7181f4b055b236fec0f99078e35799..bace9f78c4b74a209383b546743c0dbba05f62b2 100644 (file)
@@ -1,24 +1,24 @@
-[dev  0] id: ps3da1
+[dev  0] id: /dev/ps3da1
 [dev  0] name: (null)
 [dev  0] description: (null)
 [dev  0] boot_image: /usr/share/petitboot/artwork/hdd.png
 [opt  0] name: live
 [opt  0] description: /casper/vmlinux root=/dev/ram0 initrd=/casper/initrd.gz   file=/cdrom/preseed/ubuntu.seed boot=casper quiet splash --
-[opt  0] boot_image: devices/parser-tests/001/ps3da1//casper/vmlinux
-[opt  0] initrd: devices/parser-tests/001/ps3da1//casper/initrd.gz
+[opt  0] boot_image: devices/parser-tests/001/ps3da1/casper/vmlinux
+[opt  0] initrd: devices/parser-tests/001/ps3da1/casper/initrd.gz
 [opt  0] boot_args: root=/dev/ram0 initrd=/casper/initrd.gz   file=/cdrom/preseed/ubuntu.seed boot=casper quiet splash --
 [opt  1] name: live_nosplash
 [opt  1] description: /casper/vmlinux root=/dev/ram0 initrd=/casper/initrd.gz   file=/cdrom/preseed/ubuntu.seed boot=casper quiet --
-[opt  1] boot_image: devices/parser-tests/001/ps3da1//casper/vmlinux
-[opt  1] initrd: devices/parser-tests/001/ps3da1//casper/initrd.gz
+[opt  1] boot_image: devices/parser-tests/001/ps3da1/casper/vmlinux
+[opt  1] initrd: devices/parser-tests/001/ps3da1/casper/initrd.gz
 [opt  1] boot_args: root=/dev/ram0 initrd=/casper/initrd.gz   file=/cdrom/preseed/ubuntu.seed boot=casper quiet --
 [opt  2] name: driverupdates
 [opt  2] description: /casper/vmlinux root=/dev/ram0 initrd=/casper/initrd.gz   file=/cdrom/preseed/ubuntu.seed boot=casper debian-installer/driver-update=true quiet splash --
-[opt  2] boot_image: devices/parser-tests/001/ps3da1//casper/vmlinux
-[opt  2] initrd: devices/parser-tests/001/ps3da1//casper/initrd.gz
+[opt  2] boot_image: devices/parser-tests/001/ps3da1/casper/vmlinux
+[opt  2] initrd: devices/parser-tests/001/ps3da1/casper/initrd.gz
 [opt  2] boot_args: root=/dev/ram0 initrd=/casper/initrd.gz   file=/cdrom/preseed/ubuntu.seed boot=casper debian-installer/driver-update=true quiet splash --
 [opt  3] name: check
 [opt  3] description: /casper/vmlinux root=/dev/ram0 initrd=/casper/initrd.gz   boot=casper integrity-check quiet splash --
-[opt  3] boot_image: devices/parser-tests/001/ps3da1//casper/vmlinux
-[opt  3] initrd: devices/parser-tests/001/ps3da1//casper/initrd.gz
+[opt  3] boot_image: devices/parser-tests/001/ps3da1/casper/vmlinux
+[opt  3] initrd: devices/parser-tests/001/ps3da1/casper/initrd.gz
 [opt  3] boot_args: root=/dev/ram0 initrd=/casper/initrd.gz   boot=casper integrity-check quiet splash --
index 9d2a1468290411da9493ebe2ee87b85c2fc6d75d..304f15c0fb05ecead557f99a633223212530586b 100644 (file)
@@ -1,9 +1,9 @@
-[dev  0] id: ps3da1
+[dev  0] id: /dev/ps3da1
 [dev  0] name: (null)
 [dev  0] description: 
 [dev  0] boot_image: /usr/share/petitboot/artwork/hdd.png
 [opt  0] name: linux
 [opt  0] description: (null)
-[opt  0] boot_image: devices/parser-tests/002/ps3da1//ppc/ppc64/vmlinux
-[opt  0] initrd: devices/parser-tests/002/ps3da1//ppc/ppc64/ramdisk.image.gz
+[opt  0] boot_image: devices/parser-tests/002/ps3da1/ppc/ppc64/vmlinux
+[opt  0] initrd: devices/parser-tests/002/ps3da1/ppc/ppc64/ramdisk.image.gz
 [opt  0] boot_args: ro 
diff --git a/devices/parser-tests/003/expected-output b/devices/parser-tests/003/expected-output
new file mode 100644 (file)
index 0000000..4f60310
--- /dev/null
@@ -0,0 +1,9 @@
+[dev  0] id: /dev/ps3da1
+[dev  0] name: (null)
+[dev  0] description: (null)
+[dev  0] boot_image: /usr/share/petitboot/artwork/hdd.png
+[opt  0] name: test
+[opt  0] description: /dev/sda1:/vmlinux
+[opt  0] boot_image: devices/parser-tests/003/ps3da1/vmlinux
+[opt  0] initrd: (null)
+[opt  0] boot_args: (null)
diff --git a/devices/parser-tests/003/ps3da1/etc/kboot.conf b/devices/parser-tests/003/ps3da1/etc/kboot.conf
new file mode 100644 (file)
index 0000000..a7bb199
--- /dev/null
@@ -0,0 +1,4 @@
+# test remapping sda to ps3da, when mounted from a ps3da device
+
+test='/dev/sda1:/vmlinux'
+
diff --git a/devices/parser-tests/004/expected-output b/devices/parser-tests/004/expected-output
new file mode 100644 (file)
index 0000000..76a90a2
--- /dev/null
@@ -0,0 +1,9 @@
+[dev  0] id: /dev/sda1
+[dev  0] name: (null)
+[dev  0] description: (null)
+[dev  0] boot_image: /usr/share/petitboot/artwork/hdd.png
+[opt  0] name: test
+[opt  0] description: /dev/sda1:/vmlinux
+[opt  0] boot_image: devices/parser-tests/004/sda1/vmlinux
+[opt  0] initrd: (null)
+[opt  0] boot_args: (null)
diff --git a/devices/parser-tests/004/rootdev b/devices/parser-tests/004/rootdev
new file mode 100644 (file)
index 0000000..36cfa0d
--- /dev/null
@@ -0,0 +1 @@
+sda1
diff --git a/devices/parser-tests/004/sda1/etc/kboot.conf b/devices/parser-tests/004/sda1/etc/kboot.conf
new file mode 100644 (file)
index 0000000..9755f77
--- /dev/null
@@ -0,0 +1,4 @@
+# test remapping sda to ps3da, when mounted from a plain sd device
+
+test='/dev/sda1:/vmlinux'
+
index 00f36598f0e25e4431feab15cf2cc67c3bd447ba..5e50dcbdafc292f8c05a29f986f1d5510259938b 100644 (file)
@@ -26,7 +26,7 @@ void iterate_parsers(const char *devpath, const char *mountpoint)
        for (i = 0; parsers[i]; i++) {
                pb_log("\ttrying parser '%s'\n", parsers[i]->name);
                /* just use a dummy device path for now */
-               if (parsers[i]->parse(devpath, mountpoint_for_device(devpath)))
+               if (parsers[i]->parse(devpath))
                        return;
        }
        pb_log("\tno boot_options found\n");
@@ -67,20 +67,6 @@ void free_boot_option(struct boot_option *opt)
        free(opt);
 }
 
-char *join_paths(const char *a, const char *b)
-{
-       char *full_path;
-
-       full_path = malloc(strlen(a) + strlen(b) + 2);
-
-       strcpy(full_path, a);
-       if (b[0] != '/')
-               strcat(full_path, "/");
-       strcat(full_path, b);
-
-       return full_path;
-}
-
 const char *generic_icon_file(enum generic_icon_type type)
 {
        switch (type) {
index 840ca1b9d477ee56b50984af58ee5993ee71f0bb..9c6fb352e84337b14ce647e538e7f23bb07bd6f2 100644 (file)
@@ -8,7 +8,7 @@
 struct parser {
        char *name;
        int priority;
-       int (*parse)(const char *devicepath, const char *mountpoint);
+       int (*parse)(const char *device);
        struct parser *next;
 };
 
@@ -28,8 +28,6 @@ void iterate_parsers(const char *devpath, const char *mountpoint);
 void free_device(struct device *dev);
 void free_boot_option(struct boot_option *opt);
 
-char *join_paths(const char *a, const char *b);
-
 const char *generic_icon_file(enum generic_icon_type type);
 
 /* functions provided by udev-helper or the test wrapper */
@@ -37,7 +35,7 @@ void pb_log(const char *fmt, ...);
 
 int mount_device(const char *dev_path);
 
-char *resolve_path(const char *path, const char *default_mountpoint);
+char *resolve_path(const char *path, const char *current_dev);
 const char *mountpoint_for_device(const char *dev_path);
 
 enum generic_icon_type guess_device_type(void);
index a1df5d27a452e6fb3ed522e79605d84cd86cc599..e9bf6cbcc9c7c49fcb6f4ab03ad9a64e89eba61c 100644 (file)
@@ -15,46 +15,104 @@ struct device_map {
 #define DEVICE_MAP_SIZE 32
 static struct device_map device_map[DEVICE_MAP_SIZE];
 
-const char *mountpoint_for_device(const char *dev_path)
+static char *encode_label(const char *label)
 {
+       char *str, *c;
        int i;
-       const char *basename;
 
-       /* shorten '/dev/foo' to 'foo' */
-       basename = strrchr(dev_path, '/');
-       if (basename)
-               basename++;
-       else
-               basename = dev_path;
+       /* the label can be expanded by up to four times */
+       str = malloc(strlen(label) * 4 + 1);
+       c = str;
+
+       for (i = 0; i < strlen(label); i++) {
+
+               if (label[i] == '/' || label[i] == '\\') {
+                       sprintf(c, "\\x%02x", label[i]);
+                       c += 4;
+                       continue;
+               }
+
+               *(c++) = label[i];
+       }
+
+       *c = '\0';
+
+       return str;
+}
+
+char *parse_device_path(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);
+               return dev;
+       }
+
+       if (!strncasecmp(dev_str, "label=", 6)) {
+               enc = encode_label(dev_str + 6);
+               asprintf(&dev, "/dev/disk/by-label/%s", enc);
+               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;
+
+       /* 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)) {
+               snprintf(tmp, 255, "ps3d%s", dev_str + 2);
+               dev_str = tmp;
+       }
+
+       return join_paths("/dev", dev_str);
+}
+
+const char *mountpoint_for_device(const char *dev)
+{
+       int i;
+
+       if (!strncmp(dev, "/dev/", 5))
+               dev += 5;
 
        /* check existing entries in the map */
        for (i = 0; (i < DEVICE_MAP_SIZE) && device_map[i].dev; i++)
-               if (!strcmp(device_map[i].dev, basename))
+               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_path);
-       asprintf(&device_map[i].mnt, "%s/%s", mount_base, basename);
+       device_map[i].dev = strdup(dev);
+       device_map[i].mnt = join_paths(mount_base, dev);
        return device_map[i].mnt;
 }
 
-char *resolve_path(const char *path, const char *current_mountpoint)
+char *resolve_path(const char *path, const char *current_dev)
 {
        char *ret;
        const char *devpath, *sep;
 
        sep = strchr(path, ':');
        if (!sep) {
-               devpath = current_mountpoint;
-               asprintf(&ret, "%s/%s", devpath, path);
+               devpath = mountpoint_for_device(current_dev);
+               ret = join_paths(devpath, path);
        } else {
-               /* copy just the device name into tmp */
-               char *dev = strndup(path, sep - path);
+               /* parse just the device name into dev */
+               char *tmp, *dev;
+               tmp = strndup(path, sep - path);
+               dev = parse_device_path(tmp, current_dev);
+
                devpath = mountpoint_for_device(dev);
-               asprintf(&ret, "%s/%s", devpath, sep + 1);
+               ret = join_paths(devpath, sep + 1);
+
                free(dev);
+               free(tmp);
        }
 
        return ret;
@@ -67,3 +125,17 @@ void set_mount_base(const char *path)
        mount_base = strdup(path);
 }
 
+char *join_paths(const char *a, const char *b)
+{
+       char *full_path;
+
+       full_path = malloc(strlen(a) + strlen(b) + 2);
+
+       strcpy(full_path, a);
+       if (b[0] != '/' && a[strlen(a) - 1] != '/')
+               strcat(full_path, "/");
+       strcat(full_path, b);
+
+       return full_path;
+}
+
index eca66894873c28f560466700fe615fe204d38b64..a6f01c4ca56454e0db6032ea992327f1cb01bfb1 100644 (file)
@@ -2,9 +2,21 @@
 #define PATHS_H
 
 /**
- * Get the mountpoint for a device
+ * Given a string (eg /dev/sda1, sda1 or UUID=B8E53381CA9EA0E3), parse the
+ * device path (eg /dev/sda1). Any device descriptions read from config files
+ * should be parsed into the path first.
+ *
+ * The cur_dev is provided for some remapping situations. If NULL is provided,
+ * no remapping will be done.
+ *
+ * Returns a newly-allocated string.
+ */
+char *parse_device_path(const char *dev_str, const char *current_device);
+
+/**
+ * Get the mountpoint for a device.
  */
-const char *mountpoint_for_device(const char *dev_path);
+const char *mountpoint_for_device(const char *dev);
 
 /**
  * Resolve a path given in a config file, to a path in the local filesystem.
@@ -17,11 +29,21 @@ const char *mountpoint_for_device(const char *dev_path);
  *
  * Returns a newly-allocated string containing a full path to the file in path
  */
-char *resolve_path(const char *path, const char *current_mountpoint);
+char *resolve_path(const char *path, const char *current_device);
+
 
 /**
  * Set the base directory for newly-created mountpoints
  */
 void set_mount_base(const char *path);
 
+/**
+ * Utility function for joining two paths. Adds a / between a and b if
+ * required.
+ *
+ * Returns a newly-allocated string.
+ */
+char *join_paths(const char *a, const char *b);
+
+
 #endif /* PATHS_H */
index 8d65ce27e1cc7bd6f29268785b0df31d6394b0fc..27b4b782306594c05cbaec0fd3b01bc826a409de 100644 (file)
@@ -1,6 +1,7 @@
 
 #include "parser.h"
 #include "params.h"
+#include "paths.h"
 #include "yaboot-cfg.h"
 
 #include <stdlib.h>
@@ -14,7 +15,7 @@
 #include <sys/param.h>
 
 static struct device *dev;
-static const char *mountpoint;
+static char *devpath;
 static char *defimage;
 
 char *
@@ -102,13 +103,13 @@ void process_image(char *label)
 
        opt.name = label;
        cfgopt = cfg_get_strg(label, "image");
-       opt.boot_image_file = resolve_path(cfgopt, mountpoint);
+       opt.boot_image_file = resolve_path(cfgopt, devpath);
        if (cfgopt == defimage)
                pb_log("This one is default. What do we do about it?\n");
 
        cfgopt = cfg_get_strg(label, "initrd");
        if (cfgopt)
-               opt.initrd_file = resolve_path(cfgopt, mountpoint);
+               opt.initrd_file = resolve_path(cfgopt, devpath);
 
        opt.boot_args = make_params(label, NULL);
 
@@ -118,7 +119,7 @@ void process_image(char *label)
                free(opt.initrd_file);
 }
 
-static int yaboot_parse(const char *devicepath, const char *_mountpoint)
+static int yaboot_parse(const char *device)
 {
        char *filepath;
        char *conf_file;
@@ -128,14 +129,14 @@ static int yaboot_parse(const char *devicepath, const char *_mountpoint)
        struct stat st;
        char *label;
 
-       mountpoint = _mountpoint;
+       devpath = strdup(device);
 
-       filepath = join_paths(mountpoint, "/etc/yaboot.conf");
+       filepath = resolve_path("/etc/yaboot.conf", devpath);
 
        fd = open(filepath, O_RDONLY);
        if (fd < 0) {
                free(filepath);
-               filepath = join_paths(mountpoint, "/yaboot.conf");
+               filepath = resolve_path("/yaboot.conf", devpath);
                fd = open(filepath, O_RDONLY);
                
                if (fd < 0)
@@ -171,7 +172,7 @@ static int yaboot_parse(const char *devicepath, const char *_mountpoint)
 
        dev = malloc(sizeof(*dev));
        memset(dev, 0, sizeof(*dev));
-       dev->id = strdup(devicepath);
+       dev->id = strdup(devpath);
        if (cfg_get_strg(0, "init-message")) {
                char *newline;
                dev->description = strdup(cfg_get_strg(0, "init-message"));
@@ -181,28 +182,32 @@ static int yaboot_parse(const char *devicepath, const char *_mountpoint)
        }
        dev->icon_file = strdup(generic_icon_file(guess_device_type()));
 
-       /* If we have a 'partiton=' directive, update the default mountpoint
-        * to use that instead of the current mountpoint */
+       /* If we have a 'partiton=' directive, update the default devpath
+        * to use that instead of the current device */
        tmpstr = cfg_get_strg(0, "partition");
        if (tmpstr) {
                char *endp;
                int partnr = strtol(tmpstr, &endp, 10);
                if (endp != tmpstr && !*endp) {
-                       char *new_dev = malloc(strlen(devicepath) + strlen(tmpstr) + 1);
+                       char *new_dev, *tmp;
+
+                       new_dev = malloc(strlen(devpath) + strlen(tmpstr) + 1);
                        if (!new_dev)
                                return 0;
 
-                       strcpy(new_dev, devicepath);
+                       strcpy(new_dev, devpath);
 
                        /* Strip digits (partition number) from string */
-                       endp = &new_dev[strlen(devicepath) - 1];
+                       endp = new_dev + strlen(devpath) - 1;
                        while (isdigit(*endp))
                                *(endp--) = 0;
 
                        /* and add our own... */
-                       sprintf(endp+1, "%d", partnr);
+                       sprintf(endp + 1, "%d", partnr);
 
-                       mountpoint = mountpoint_for_device(new_dev);
+                       tmp = devpath;
+                       devpath = parse_device_path(new_dev, devpath);
+                       free(tmp);
                        free(new_dev);
                }
        }