summaryrefslogtreecommitdiffstats
path: root/src/inspect_fs_unix.c
diff options
context:
space:
mode:
authorMatthew Booth <mbooth@redhat.com>2011-10-14 15:00:32 +0100
committerRichard W.M. Jones <rjones@redhat.com>2011-10-19 16:26:42 +0100
commit472f02d08b077a5c1ee233d9dcef92ac9b09d4ae (patch)
tree5f3896226f9df4132c23f24102e1aff2f22e36da /src/inspect_fs_unix.c
parent138e118d62046b197b715462072256082ecfc0f7 (diff)
downloadlibguestfs-472f02d08b077a5c1ee233d9dcef92ac9b09d4ae.tar.gz
libguestfs-472f02d08b077a5c1ee233d9dcef92ac9b09d4ae.tar.xz
libguestfs-472f02d08b077a5c1ee233d9dcef92ac9b09d4ae.zip
inspect: Fix fstab device mapping for >26 disks
The regular expression matching disk name assumed that there was only a single letter suffix. This change handles a naming scheme for any number of disks.
Diffstat (limited to 'src/inspect_fs_unix.c')
-rw-r--r--src/inspect_fs_unix.c51
1 files changed, 31 insertions, 20 deletions
diff --git a/src/inspect_fs_unix.c b/src/inspect_fs_unix.c
index 12bda688..04430e40 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);
}
@@ -816,9 +816,8 @@ add_fstab_entry (guestfs_h *g, struct inspect_fs *fs,
static char *
resolve_fstab_device (guestfs_h *g, const char *spec)
{
- char *a1;
char *device = NULL;
- char *bsddisk, *bsdslice, *bsdpart;
+ char *slice, *disk, *part;
if (STRPREFIX (spec, "/dev/mapper/")) {
/* LVM2 does some strange munging on /dev/mapper paths for VGs and
@@ -833,45 +832,57 @@ resolve_fstab_device (guestfs_h *g, const char *spec)
*/
device = guestfs_lvm_canonical_lv_name (g, spec);
}
- else if ((a1 = match1 (g, spec, re_xdev)) != NULL) {
+ else if (match2 (g, spec, re_xdev, &disk, &part)) {
+ /* 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++)
;
- size_t i = a1[0] - 'a'; /* a1[0] is always [a-z] because of regex. */
+ /* 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';
+ }
+
+ /* 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 (a1) + 16;
+ size_t len = strlen (devices[i]) + strlen (part) + 1;
device = safe_malloc (g, len);
- snprintf (device, len, "%s%s", devices[i], &a1[1]);
+ snprintf (device, len, "%s%s", devices[i], part);
}
- free (a1);
+ free (disk);
+ free (part);
guestfs___free_string_list (devices);
}
- else if (match3 (g, spec, re_freebsd, &bsddisk, &bsdslice, &bsdpart)) {
+ else if (match3 (g, spec, re_freebsd, &disk, &slice, &part)) {
/* FreeBSD disks are organized quite differently. See:
* http://www.freebsd.org/doc/handbook/disk-organization.html
* FreeBSD "partitions" are exposed as quasi-extended partitions
* numbered from 5 in Linux. I have no idea what happens when you
* have multiple "slices" (the FreeBSD term for MBR partitions).
*/
- int disk = guestfs___parse_unsigned_int (g, bsddisk);
- int slice = guestfs___parse_unsigned_int (g, bsdslice);
- int part = bsdpart[0] - 'a' /* counting from 0 */;
- free (bsddisk);
- free (bsdslice);
- free (bsdpart);
-
- if (disk == -1 || disk > 26 ||
- slice <= 0 || slice > 1 /* > 4 .. see comment above */ ||
- part < 0 || part >= 26)
+ int disk_i = guestfs___parse_unsigned_int (g, disk);
+ int slice_i = guestfs___parse_unsigned_int (g, slice);
+ int part_i = part[0] - 'a' /* counting from 0 */;
+ free (disk);
+ free (slice);
+ free (part);
+
+ if (disk_i == -1 || disk_i > 26 ||
+ slice_i <= 0 || slice_i > 1 /* > 4 .. see comment above */ ||
+ part_i < 0 || part_i >= 26)
goto out;
- device = safe_asprintf (g, "/dev/sd%c%d", disk + 'a', part + 5);
+ device = safe_asprintf (g, "/dev/sd%c%d", disk_i + 'a', part_i + 5);
}
out: