diff options
-rw-r--r-- | generator/generator_actions.ml | 7 | ||||
-rwxr-xr-x | regressions/test-inspect-fstab.sh | 36 | ||||
-rw-r--r-- | src/guestfs-internal.h | 1 | ||||
-rw-r--r-- | src/guestfs.c | 1 | ||||
-rw-r--r-- | src/inspect_fs_unix.c | 55 | ||||
-rw-r--r-- | src/launch.c | 8 |
6 files changed, 84 insertions, 24 deletions
diff --git a/generator/generator_actions.ml b/generator/generator_actions.ml index 4967ce20..e8a32ac0 100644 --- a/generator/generator_actions.ml +++ b/generator/generator_actions.ml @@ -1007,7 +1007,7 @@ be mountable but require special options. Filesystems may not all belong to a single logical operating system (use C<guestfs_inspect_os> to look for OSes)."); - ("add_drive_opts", (RErr, [String "filename"], [Bool "readonly"; String "format"; String "iface"]), -1, [FishAlias "add"], + ("add_drive_opts", (RErr, [String "filename"], [Bool "readonly"; String "format"; String "iface"; String "name"]), -1, [FishAlias "add"], [], "add an image to examine or modify", "\ @@ -1050,6 +1050,11 @@ this security hole. This rarely-used option lets you emulate the behaviour of the deprecated C<guestfs_add_drive_with_if> call (q.v.) +=item C<name> + +The name the drive had in the original guest, e.g. /dev/sdb. This is used as a +hint to the guest inspection process if it is available. + =back"); ("inspect_get_windows_systemroot", (RString "systemroot", [Device "root"], []), -1, [], diff --git a/regressions/test-inspect-fstab.sh b/regressions/test-inspect-fstab.sh index fb284152..bb79a817 100755 --- a/regressions/test-inspect-fstab.sh +++ b/regressions/test-inspect-fstab.sh @@ -49,15 +49,11 @@ $guestfish -a test1.img <<'EOF' upload test.fstab /etc/fstab EOF -rm test.fstab - # This will give a warning, but should not fail. $guestfish -a test1.img -i <<'EOF' | sort > test.output inspect-get-mountpoints /dev/VG/Root EOF -rm test1.img - if [ "$(cat test.output)" != "/: /dev/VG/Root /boot: /dev/vda1 /nosuchfile: /dev/VG/LV1 @@ -67,4 +63,36 @@ if [ "$(cat test.output)" != "/: /dev/VG/Root exit 1 fi +# Test device name hints + +cat <<'EOF' > test.fstab +/dev/VG/Root / ext2 default 0 0 + +# Device name which requires a hint +/dev/xvdg1 /boot ext2 default 0 0 +EOF + +$guestfish -a test1.img <<'EOF' + run + mount-options "" /dev/VG/Root / + upload test.fstab /etc/fstab +EOF + +$guestfish <<'EOF' > test.output + add-drive-opts test1.img readonly:true name:xvdg + run + inspect-os + inspect-get-mountpoints /dev/VG/Root +EOF + +if [ "$(cat test.output)" != "/dev/VG/Root +/: /dev/VG/Root +/boot: /dev/vda1" ]; then + echo "$0: error: unexpected output from inspect-get-mountpoints command" + cat test.output + exit 1 +fi + +rm test.fstab +rm test1.img rm test.output diff --git a/src/guestfs-internal.h b/src/guestfs-internal.h index 7bdb4e44..9b690b4a 100644 --- a/src/guestfs-internal.h +++ b/src/guestfs-internal.h @@ -158,6 +158,7 @@ struct drive { int readonly; char *format; char *iface; + char *name; int use_cache_off; }; diff --git a/src/guestfs.c b/src/guestfs.c index 170d0d32..f4b79e76 100644 --- a/src/guestfs.c +++ b/src/guestfs.c @@ -1008,6 +1008,7 @@ guestfs___free_drives (struct drive **drives) free (i->path); free (i->format); free (i->iface); + free (i->name); free (i); i = next; diff --git a/src/inspect_fs_unix.c b/src/inspect_fs_unix.c index 34e65bf6..77834a1d 100644 --- a/src/inspect_fs_unix.c +++ b/src/inspect_fs_unix.c @@ -107,7 +107,7 @@ compile_regexps (void) "Scientific Linux.*release (\\d+)", 0); COMPILE (re_major_minor, "(\\d+)\\.(\\d+)", 0); COMPILE (re_aug_seq, "/\\d+$", 0); - COMPILE (re_xdev, "^/dev/(?:h|s|v|xv)d([a-z]+)(\\d*)$", 0); + COMPILE (re_xdev, "^/dev/(h|s|v|xv)d([a-z]+)(\\d*)$", 0); COMPILE (re_freebsd, "^/dev/ad(\\d+)s(\\d+)([a-z])$", 0); COMPILE (re_netbsd, "^NetBSD (\\d+)\\.(\\d+)", 0); } @@ -817,7 +817,7 @@ static char * resolve_fstab_device (guestfs_h *g, const char *spec) { char *device = NULL; - char *slice, *disk, *part; + char *type, *slice, *disk, *part; if (STRPREFIX (spec, "/dev/mapper/")) { /* LVM2 does some strange munging on /dev/mapper paths for VGs and @@ -832,33 +832,50 @@ resolve_fstab_device (guestfs_h *g, const char *spec) */ device = guestfs_lvm_canonical_lv_name (g, spec); } - else if (match2 (g, spec, re_xdev, &disk, &part)) { - /* disk: ([a-z]+) + else if (match3 (g, spec, re_xdev, &type, &disk, &part)) { + /* type: (h|s|v|xv) + * disk: ([a-z]+) * part: (\d*) */ char **devices = guestfs_list_devices (g); if (devices == NULL) return NULL; - /* Count how many disks the libguestfs appliance has */ - size_t count; - for (count = 0; devices[count] != NULL; count++) - ; + /* Check any hints we were passed for a non-heuristic mapping */ + char *name = safe_asprintf (g, "%sd%s", type, disk); + size_t i = 0; + struct drive *drive = g->drives; + while (drive) { + if (drive->name && STREQ(drive->name, name)) { + device = safe_asprintf (g, "%s%s", devices[i], part); + break; + } - /* Calculate the numerical index of the disk */ - size_t i = disk[0] - 'a'; - for (char *p = disk + 1; *p != '\0'; p++) { - i += 1; i *= 26; - i += *p - 'a'; + i++; drive = drive->next; } + free (name); + + /* Guess the appliance device name if we didn't find a matching hint */ + if (!device) { + /* Count how many disks the libguestfs appliance has */ + size_t count; + for (count = 0; devices[count] != NULL; count++) + ; + + /* Calculate the numerical index of the disk */ + i = disk[0] - 'a'; + for (char *p = disk + 1; *p != '\0'; p++) { + i += 1; i *= 26; + i += *p - 'a'; + } - /* Check the index makes sense wrt the number of disks the appliance has. - * If it does, map it to an appliance disk. */ - if (i < count) { - size_t len = strlen (devices[i]) + strlen (part) + 1; - device = safe_malloc (g, len); - snprintf (device, len, "%s%s", devices[i], part); + /* Check the index makes sense wrt the number of disks the appliance has. + * If it does, map it to an appliance disk. */ + if (i < count) { + device = safe_asprintf (g, "%s%s", devices[i], part); + } } + free (type); free (disk); free (part); guestfs___free_string_list (devices); diff --git a/src/launch.c b/src/launch.c index d6e99f72..ed8d9bdd 100644 --- a/src/launch.c +++ b/src/launch.c @@ -289,6 +289,7 @@ guestfs__add_drive_opts (guestfs_h *g, const char *filename, int readonly; char *format; char *iface; + char *name; int use_cache_off; if (strchr (filename, ',') != NULL) { @@ -302,12 +303,15 @@ guestfs__add_drive_opts (guestfs_h *g, const char *filename, ? safe_strdup (g, optargs->format) : NULL; iface = optargs->bitmask & GUESTFS_ADD_DRIVE_OPTS_IFACE_BITMASK ? safe_strdup (g, optargs->iface) : safe_strdup (g, DRIVE_IF); + name = optargs->bitmask & GUESTFS_ADD_DRIVE_OPTS_NAME_BITMASK + ? safe_strdup (g, optargs->name) : NULL; if (format && !valid_format_iface (format)) { error (g, _("%s parameter is empty or contains disallowed characters"), "format"); free (format); free (iface); + free (name); return -1; } if (!valid_format_iface (iface)) { @@ -315,6 +319,7 @@ guestfs__add_drive_opts (guestfs_h *g, const char *filename, "iface"); free (format); free (iface); + free (name); return -1; } @@ -326,6 +331,7 @@ guestfs__add_drive_opts (guestfs_h *g, const char *filename, if (use_cache_off == -1) { free (format); free (iface); + free (name); return -1; } @@ -334,6 +340,7 @@ guestfs__add_drive_opts (guestfs_h *g, const char *filename, perrorf (g, "%s", filename); free (format); free (iface); + free (name); return -1; } } @@ -347,6 +354,7 @@ guestfs__add_drive_opts (guestfs_h *g, const char *filename, (*i)->readonly = readonly; (*i)->format = format; (*i)->iface = iface; + (*i)->name = name; (*i)->use_cache_off = use_cache_off; return 0; |