Richard W.M. Jones
2014-Dec-09 14:11 UTC
[Libguestfs] [PATCH] inspection: Not an installer if there are multiple partitions (RHBZ#1171666).
Regular EFI disks have /EFI on the first (VFAT) partition, but they are not installers. Fix this by only considering something to be an installer if it has a single partition (or whole disks like ISOs). Implementing this is quite complex since when checking a filesystem, we don't have information about whether we are even looking at a partition, nor about whether it's the first partition out of how many. The majority of the commit is changing the code to collect that information. --- src/guestfs-internal.h | 1 + src/inspect-fs-unix.c | 31 ++++--------------------------- src/inspect-fs.c | 44 ++++++++++++++++++++++++++++++++++++++------ src/inspect.c | 22 ++++++++++++++++++++++ 4 files changed, 65 insertions(+), 33 deletions(-) diff --git a/src/guestfs-internal.h b/src/guestfs-internal.h index 0a4a6f2..0b25407 100644 --- a/src/guestfs-internal.h +++ b/src/guestfs-internal.h @@ -766,6 +766,7 @@ extern int guestfs___set_backend (guestfs_h *g, const char *method); extern void guestfs___free_inspect_info (guestfs_h *g); extern char *guestfs___download_to_tmp (guestfs_h *g, struct inspect_fs *fs, const char *filename, const char *basename, uint64_t max_size); extern struct inspect_fs *guestfs___search_for_root (guestfs_h *g, const char *root); +extern int guestfs___is_partition (guestfs_h *g, const char *partition); /* inspect-fs.c */ extern int guestfs___is_file_nocase (guestfs_h *g, const char *); diff --git a/src/inspect-fs-unix.c b/src/inspect-fs-unix.c index 750c27b..5ba8beb 100644 --- a/src/inspect-fs-unix.c +++ b/src/inspect-fs-unix.c @@ -96,7 +96,6 @@ static char *resolve_fstab_device (guestfs_h *g, const char *spec, Hash_table *md_map, enum inspect_os_type os_type); static int inspect_with_augeas (guestfs_h *g, struct inspect_fs *fs, const char **configfiles, int (*f) (guestfs_h *, struct inspect_fs *)); -static int is_partition (guestfs_h *g, const char *partition); /* Hash structure for uuid->path lookups */ typedef struct md_uuid { @@ -1431,7 +1430,7 @@ resolve_fstab_device_xdev (guestfs_h *g, const char *type, const char *disk, ITER_DRIVES (g, i, drv) { if (drv->name && STREQ (drv->name, name)) { device = safe_asprintf (g, "%s%s", devices[i], part); - if (!is_partition (g, device)) { + if (!guestfs___is_partition (g, device)) { free (device); return 0; } @@ -1458,7 +1457,7 @@ resolve_fstab_device_xdev (guestfs_h *g, const char *type, const char *disk, */ if (i < count) { device = safe_asprintf (g, "%s%s", devices[i], part); - if (!is_partition (g, device)) { + if (!guestfs___is_partition (g, device)) { free (device); return 0; } @@ -1491,7 +1490,7 @@ resolve_fstab_device_cciss (guestfs_h *g, const char *disk, const char *part, if (drv->name && STREQ (drv->name, disk)) { if (part) { device = safe_asprintf (g, "%s%s", devices[i], part); - if (!is_partition (g, device)) { + if (!guestfs___is_partition (g, device)) { free (device); return 0; } @@ -1536,7 +1535,7 @@ resolve_fstab_device_diskbyid (guestfs_h *g, const char *part, /* Make the partition name and check it exists. */ device = safe_asprintf (g, "/dev/sda%s", part); - if (!is_partition (g, device)) { + if (!guestfs___is_partition (g, device)) { free (device); return 0; } @@ -1786,25 +1785,3 @@ make_augeas_path_expression (guestfs_h *g, const char **configfiles) debug (g, "augeas pathexpr = %s", ret); return ret; } - -static int -is_partition (guestfs_h *g, const char *partition) -{ - CLEANUP_FREE char *device = NULL; - - guestfs_push_error_handler (g, NULL, NULL); - - if ((device = guestfs_part_to_dev (g, partition)) == NULL) { - guestfs_pop_error_handler (g); - return 0; - } - - if (guestfs_device_index (g, device) == -1) { - guestfs_pop_error_handler (g); - return 0; - } - - guestfs_pop_error_handler (g); - - return 1; -} diff --git a/src/inspect-fs.c b/src/inspect-fs.c index e9cc2e9..7b116db 100644 --- a/src/inspect-fs.c +++ b/src/inspect-fs.c @@ -48,6 +48,7 @@ static int check_filesystem (guestfs_h *g, const char *mountable, const struct guestfs_internal_mountable *m, int whole_device); static int extend_fses (guestfs_h *g); +static int get_partition_context (guestfs_h *g, const char *partition, int *partnum_ret, int *nr_partitions_ret); /* Find out if 'device' contains a filesystem. If it does, add * another entry in g->fses. @@ -140,17 +141,18 @@ check_filesystem (guestfs_h *g, const char *mountable, const struct guestfs_internal_mountable *m, int whole_device) { + int partnum = -1, nr_partitions = -1; /* Not CLEANUP_FREE, as it will be cleaned up with inspection info */ char *windows_systemroot = NULL; if (extend_fses (g) == -1) return -1; - int partnum = -1; - if (!whole_device && m->im_type == MOUNTABLE_DEVICE) { - guestfs_push_error_handler (g, NULL, NULL); - partnum = guestfs_part_to_partnum (g, m->im_device); - guestfs_pop_error_handler (g); + if (!whole_device && m->im_type == MOUNTABLE_DEVICE && + guestfs___is_partition (g, m->im_device)) { + if (get_partition_context (g, m->im_device, + &partnum, &nr_partitions) == -1) + return -1; } struct inspect_fs *fs = &g->fses[g->nr_fses-1]; @@ -285,7 +287,7 @@ check_filesystem (guestfs_h *g, const char *mountable, * Skip these checks if it's not a whole device (eg. CD) or the * first partition (eg. bootable USB key). */ - else if ((whole_device || partnum == 1) && + else if ((whole_device || (partnum == 1 && nr_partitions == 1)) && (guestfs_is_file (g, "/isolinux/isolinux.cfg") > 0 || guestfs_is_dir (g, "/EFI/BOOT") > 0 || guestfs_is_file (g, "/images/install.img") > 0 || @@ -330,6 +332,36 @@ extend_fses (guestfs_h *g) return 0; } +/* Given a partition (eg. /dev/sda2) then return the partition number + * (eg. 2) and the total number of other partitions. + */ +static int +get_partition_context (guestfs_h *g, const char *partition, + int *partnum_ret, int *nr_partitions_ret) +{ + int partnum, nr_partitions; + CLEANUP_FREE char *device = NULL; + CLEANUP_FREE_PARTITION_LIST struct guestfs_partition_list *partitions = NULL; + + partnum = guestfs_part_to_partnum (g, partition); + if (partnum == -1) + return -1; + + device = guestfs_part_to_dev (g, partition); + if (device == NULL) + return -1; + + partitions = guestfs_part_list (g, device); + if (partitions == NULL) + return -1; + + nr_partitions = partitions->len; + + *partnum_ret = partnum; + *nr_partitions_ret = nr_partitions; + return 0; +} + int guestfs___is_file_nocase (guestfs_h *g, const char *path) { diff --git a/src/inspect.c b/src/inspect.c index bdb45c3..8c00f80 100644 --- a/src/inspect.c +++ b/src/inspect.c @@ -638,3 +638,25 @@ guestfs___search_for_root (guestfs_h *g, const char *root) root); return NULL; } + +int +guestfs___is_partition (guestfs_h *g, const char *partition) +{ + CLEANUP_FREE char *device = NULL; + + guestfs_push_error_handler (g, NULL, NULL); + + if ((device = guestfs_part_to_dev (g, partition)) == NULL) { + guestfs_pop_error_handler (g); + return 0; + } + + if (guestfs_device_index (g, device) == -1) { + guestfs_pop_error_handler (g); + return 0; + } + + guestfs_pop_error_handler (g); + + return 1; +} -- 2.1.0
Reasonably Related Threads
- [PATCH] inspect: improve UsrMove detection (RHBZ#1186935)
- Re: [PATCH] inspect: improve UsrMove detection (RHBZ#1186935)
- [PATCH] Use safe_realloc() in favor of realloc overall.
- [PATCH 1/2] Fix bogus partition number passed to guestfs___check_for_filesystem_on
- [PATCH v3 7/7] resize: add support to resize logical partitions