The assumption that Linux will map the MBR partition to /dev/sda1 and the BSD 'a' partition to /dev/sda5 is not always correct.
Signed-off-by: Nikos Skalkotos <[email protected]> --- src/guestfs-internal.h | 1 + src/inspect-fs.c | 55 +++++++++++++++++++++++++++++++++----------------- src/inspect.c | 6 ++++++ 3 files changed, 43 insertions(+), 19 deletions(-) diff --git a/src/guestfs-internal.h b/src/guestfs-internal.h index fd0c4a1..2460d25 100644 --- a/src/guestfs-internal.h +++ b/src/guestfs-internal.h @@ -746,6 +746,7 @@ extern int guestfs___is_file_nocase (guestfs_h *g, const char *); extern int guestfs___is_dir_nocase (guestfs_h *g, const char *); extern int guestfs___check_for_filesystem_on (guestfs_h *g, const char *mountable); +extern void guestfs___check_for_dublicated_bsd_root(guestfs_h *g); extern int guestfs___parse_unsigned_int (guestfs_h *g, const char *str); extern int guestfs___parse_unsigned_int_ignore_trailing (guestfs_h *g, const char *str); extern int guestfs___parse_major_minor (guestfs_h *g, struct inspect_fs *fs); diff --git a/src/inspect-fs.c b/src/inspect-fs.c index 539d814..99a8658 100644 --- a/src/inspect-fs.c +++ b/src/inspect-fs.c @@ -47,7 +47,7 @@ * multiple threads call into the libguestfs API functions below * simultaneously. */ -static pcre *re_first_partition; +static pcre *re_primary_partition; static pcre *re_major_minor; static void compile_regexps (void) __attribute__((constructor)); @@ -68,14 +68,14 @@ compile_regexps (void) } \ } while (0) - COMPILE (re_first_partition, "^/dev/(?:h|s|v)d.1$", 0); + COMPILE (re_primary_partition, "^/dev/(?:h|s|v)d.[1234]$", 0); COMPILE (re_major_minor, "(\\d+)\\.(\\d+)", 0); } static void free_regexps (void) { - pcre_free (re_first_partition); + pcre_free (re_primary_partition); pcre_free (re_major_minor); } @@ -84,6 +84,39 @@ static int check_filesystem (guestfs_h *g, const char *mountable, int whole_device); static int extend_fses (guestfs_h *g); +/* On *BSD systems, sometimes /dev/sda[1234] is a shadow of the real root + * filesystem that is probably /dev/sda5 + * (see: http://www.freebsd.org/doc/handbook/disk-organization.html) + */ +void +guestfs___check_for_dublicated_bsd_root(guestfs_h *g) +{ + size_t i; + bool is_primary, is_bsd; + struct inspect_fs *fs, *bsd_primary = NULL; + + for (i = 0; i < g->nr_fses; ++i) { + fs = &g->fses[i]; + + is_primary = match (g, fs->mountable, re_primary_partition); + is_bsd = ((fs->type == OS_TYPE_FREEBSD) || \ + (fs->type == OS_TYPE_NETBSD) || \ + (fs->type == OS_TYPE_OPENBSD)); + + if (fs->is_root && is_primary && is_bsd) { + bsd_primary = fs; + continue; + } + + if (fs->is_root && bsd_primary && (bsd_primary->type == fs->type)) { + /* remove the is root flag from the bsd_primary */ + bsd_primary->is_root = 0; + bsd_primary->format = OS_FORMAT_UNKNOWN; + return; + } + } +} + /* Find out if 'device' contains a filesystem. If it does, add * another entry in g->fses. */ @@ -207,14 +240,6 @@ check_filesystem (guestfs_h *g, const char *mountable, is_dir_bin && guestfs_is_file (g, "/etc/freebsd-update.conf") > 0 && guestfs_is_file (g, "/etc/fstab") > 0) { - /* Ignore /dev/sda1 which is a shadow of the real root filesystem - * that is probably /dev/sda5 (see: - * http://www.freebsd.org/doc/handbook/disk-organization.html) - */ - if (m->im_type == MOUNTABLE_DEVICE && - match (g, m->im_device, re_first_partition)) - return 0; - fs->is_root = 1; fs->format = OS_FORMAT_INSTALLED; if (guestfs___check_freebsd_root (g, fs) == -1) @@ -225,14 +250,6 @@ check_filesystem (guestfs_h *g, const char *mountable, guestfs_is_file (g, "/netbsd") > 0 && guestfs_is_file (g, "/etc/fstab") > 0 && guestfs_is_file (g, "/etc/release") > 0) { - /* Ignore /dev/sda1 which is a shadow of the real root filesystem - * that is probably /dev/sda5 (see: - * http://www.freebsd.org/doc/handbook/disk-organization.html) - */ - if (m->im_type == MOUNTABLE_DEVICE && - match (g, m->im_device, re_first_partition)) - return 0; - fs->is_root = 1; fs->format = OS_FORMAT_INSTALLED; if (guestfs___check_netbsd_root (g, fs) == -1) diff --git a/src/inspect.c b/src/inspect.c index 9248b06..048b059 100644 --- a/src/inspect.c +++ b/src/inspect.c @@ -64,6 +64,12 @@ guestfs__inspect_os (guestfs_h *g) } } + /* Check if the same filesystem was listed twice as root in g->fses. + * This may happen for the *BSD root partition where an MBR partition + * is a shadow of the real root partition probably /dev/sda5 + */ + guestfs___check_for_dublicated_bsd_root(g); + /* At this point we have, in the handle, a list of all filesystems * found and data about each one. Now we assemble the list of * filesystems which are root devices and return that to the user. -- 2.1.3 _______________________________________________ Libguestfs mailing list [email protected] https://www.redhat.com/mailman/listinfo/libguestfs
