summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMatthew Booth <mbooth@redhat.com>2011-10-18 11:01:01 +0100
committerRichard W.M. Jones <rjones@redhat.com>2011-10-19 16:27:38 +0100
commita1df33eac2c0a0a4fbb256871e491e28dd11ce90 (patch)
tree13045adc26abf873d6eb3e4b0c310fa154412e3d /src
parent1f615fddaffd33afc75a582021769583c8f4db4e (diff)
downloadlibguestfs-a1df33eac2c0a0a4fbb256871e491e28dd11ce90.tar.gz
libguestfs-a1df33eac2c0a0a4fbb256871e491e28dd11ce90.tar.xz
libguestfs-a1df33eac2c0a0a4fbb256871e491e28dd11ce90.zip
inspect: Add drive naming hints
We currently use a heuristic to guess how drive names we find referenced in the guest map to drive names in the appliance. If this heuristic fails it can cause inspection to fail. This change adds a new 'name' option to add_drive_opts, which allows the user to explicitly pass the name of a drive to libguestfs if it is known. This change also updates the fstab-parsing inspection code to use this information if it is available.
Diffstat (limited to 'src')
-rw-r--r--src/guestfs-internal.h1
-rw-r--r--src/guestfs.c1
-rw-r--r--src/inspect_fs_unix.c55
-rw-r--r--src/launch.c8
4 files changed, 46 insertions, 19 deletions
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;