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