X-Git-Url: http://git.annexia.org/?p=libguestfs.git;a=blobdiff_plain;f=src%2Finspect_fs_unix.c;h=34e65bf699771cb508c5ef23733aff4c40d71240;hp=4270712828aa3fc56bf93808c39487705e22041f;hb=1f615fddaffd33afc75a582021769583c8f4db4e;hpb=b648b1813fc8e55db790435b5414d9be3ec765d2 diff --git a/src/inspect_fs_unix.c b/src/inspect_fs_unix.c index 4270712..34e65bf 100644 --- a/src/inspect_fs_unix.c +++ b/src/inspect_fs_unix.c @@ -66,6 +66,7 @@ static pcre *re_aug_seq; static pcre *re_xdev; static pcre *re_first_partition; static pcre *re_freebsd; +static pcre *re_netbsd; static void compile_regexps (void) __attribute__((constructor)); static void free_regexps (void) __attribute__((destructor)); @@ -106,8 +107,9 @@ 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); } static void @@ -127,6 +129,7 @@ free_regexps (void) pcre_free (re_aug_seq); pcre_free (re_xdev); pcre_free (re_freebsd); + pcre_free (re_netbsd); } static void check_architecture (guestfs_h *g, struct inspect_fs *fs); @@ -214,6 +217,11 @@ parse_lsb_release (guestfs_h *g, struct inspect_fs *fs) fs->distro = OS_DISTRO_MANDRIVA; r = 1; } + else if (fs->distro == 0 && + STREQ (lines[i], "DISTRIB_ID=\"Mageia\"")) { + fs->distro = OS_DISTRO_MAGEIA; + r = 1; + } else if (STRPREFIX (lines[i], "DISTRIB_RELEASE=")) { char *major, *minor; if (match2 (g, &lines[i][16], re_major_minor, &major, &minor)) { @@ -414,6 +422,16 @@ guestfs___check_linux_root (guestfs_h *g, struct inspect_fs *fs) if (guestfs___parse_major_minor (g, fs) == -1) return -1; } + else if (guestfs_exists (g, "/etc/SuSE-release") > 0) { + fs->distro = OS_DISTRO_OPENSUSE; + + if (parse_release_file (g, fs, "/etc/SuSE-release") == -1) + return -1; + + if (guestfs___parse_major_minor (g, fs) == -1) + return -1; + } + skip_release_checks:; @@ -468,6 +486,48 @@ guestfs___check_freebsd_root (guestfs_h *g, struct inspect_fs *fs) return 0; } +/* The currently mounted device is maybe to be a *BSD root. */ +int +guestfs___check_netbsd_root (guestfs_h *g, struct inspect_fs *fs) +{ + + if (guestfs_exists (g, "/etc/release") > 0) { + char *major, *minor; + if (parse_release_file (g, fs, "/etc/release") == -1) + return -1; + + if (match2 (g, fs->product_name, re_netbsd, &major, &minor)) { + fs->type = OS_TYPE_NETBSD; + fs->major_version = guestfs___parse_unsigned_int (g, major); + free (major); + if (fs->major_version == -1) { + free (minor); + return -1; + } + fs->minor_version = guestfs___parse_unsigned_int (g, minor); + free (minor); + if (fs->minor_version == -1) + return -1; + } + } else { + return -1; + } + + /* Determine the architecture. */ + check_architecture (g, fs); + + /* We already know /etc/fstab exists because it's part of the test above. */ + if (inspect_with_augeas (g, fs, "/etc/fstab", check_fstab) == -1) + return -1; + + /* Determine hostname. */ + if (check_hostname_unix (g, fs) == -1) + return -1; + + return 0; +} + + static void check_architecture (guestfs_h *g, struct inspect_fs *fs) { @@ -527,6 +587,7 @@ check_hostname_unix (guestfs_h *g, struct inspect_fs *fs) break; case OS_TYPE_FREEBSD: + case OS_TYPE_NETBSD: /* /etc/rc.conf contains the hostname, but there is no Augeas lens * for this file. */ @@ -704,6 +765,9 @@ add_fstab_entry (guestfs_h *g, struct inspect_fs *fs, else if (STRPREFIX (spec, "LABEL=")) device = guestfs_findfs_label (g, &spec[6]); /* Ignore "/.swap" (Pardus) and pseudo-devices like "tmpfs". */ + else if (STREQ (spec, "/dev/root")) + /* Resolve /dev/root to the current device. */ + device = safe_strdup (g, fs->device); else if (STRPREFIX (spec, "/dev/")) /* Resolve guest block device names. */ device = resolve_fstab_device (g, spec); @@ -752,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 @@ -769,48 +832,58 @@ 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) - goto out; - - device = safe_asprintf (g, "/dev/sd%c%d", disk + 'a', part + 5); + 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) { + device = safe_asprintf (g, "/dev/sd%c%d", disk_i + 'a', part_i + 5); + } } - out: /* Didn't match device pattern, return original spec unchanged. */ if (device == NULL) device = safe_strdup (g, spec);