|
|
ffd6ed |
From 83c910778cc461dd72421b52d4fae7df7426bff6 Mon Sep 17 00:00:00 2001
|
|
|
ffd6ed |
From: "Richard W.M. Jones" <rjones@redhat.com>
|
|
|
ffd6ed |
Date: Tue, 9 Dec 2014 14:06:18 +0000
|
|
|
ffd6ed |
Subject: [PATCH] inspection: Not an installer if there are multiple partitions
|
|
|
ffd6ed |
(RHBZ#1171666).
|
|
|
ffd6ed |
|
|
|
ffd6ed |
Regular EFI disks have /EFI on the first (VFAT) partition, but they
|
|
|
ffd6ed |
are not installers.
|
|
|
ffd6ed |
|
|
|
ffd6ed |
Fix this by only considering something to be an installer if it has a
|
|
|
ffd6ed |
single partition (or whole disks like ISOs).
|
|
|
ffd6ed |
|
|
|
ffd6ed |
Implementing this is quite complex since when checking a filesystem,
|
|
|
ffd6ed |
we don't have information about whether we are even looking at a
|
|
|
ffd6ed |
partition, nor about whether it's the first partition out of how many.
|
|
|
ffd6ed |
The majority of the commit is changing the code to collect that
|
|
|
ffd6ed |
information.
|
|
|
ffd6ed |
|
|
|
ffd6ed |
(cherry picked from commit bdf772db3286487adefa56b966435f2dd638e0a8)
|
|
|
ffd6ed |
---
|
|
|
ffd6ed |
src/guestfs-internal.h | 1 +
|
|
|
ffd6ed |
src/inspect-fs-unix.c | 31 ++++---------------------------
|
|
|
ffd6ed |
src/inspect-fs.c | 44 ++++++++++++++++++++++++++++++++++++++------
|
|
|
ffd6ed |
src/inspect.c | 22 ++++++++++++++++++++++
|
|
|
ffd6ed |
4 files changed, 65 insertions(+), 33 deletions(-)
|
|
|
ffd6ed |
|
|
|
ffd6ed |
diff --git a/src/guestfs-internal.h b/src/guestfs-internal.h
|
|
|
ffd6ed |
index d9ccf5f..65f3388 100644
|
|
|
ffd6ed |
--- a/src/guestfs-internal.h
|
|
|
ffd6ed |
+++ b/src/guestfs-internal.h
|
|
|
ffd6ed |
@@ -751,6 +751,7 @@ extern int guestfs___set_backend (guestfs_h *g, const char *method);
|
|
|
ffd6ed |
extern void guestfs___free_inspect_info (guestfs_h *g);
|
|
|
ffd6ed |
extern char *guestfs___download_to_tmp (guestfs_h *g, struct inspect_fs *fs, const char *filename, const char *basename, uint64_t max_size);
|
|
|
ffd6ed |
extern struct inspect_fs *guestfs___search_for_root (guestfs_h *g, const char *root);
|
|
|
ffd6ed |
+extern int guestfs___is_partition (guestfs_h *g, const char *partition);
|
|
|
ffd6ed |
|
|
|
ffd6ed |
/* inspect-fs.c */
|
|
|
ffd6ed |
extern int guestfs___is_file_nocase (guestfs_h *g, const char *);
|
|
|
ffd6ed |
diff --git a/src/inspect-fs-unix.c b/src/inspect-fs-unix.c
|
|
|
ffd6ed |
index fb5cc1a..8778e92 100644
|
|
|
ffd6ed |
--- a/src/inspect-fs-unix.c
|
|
|
ffd6ed |
+++ b/src/inspect-fs-unix.c
|
|
|
ffd6ed |
@@ -185,7 +185,6 @@ static int add_fstab_entry (guestfs_h *g, struct inspect_fs *fs,
|
|
|
ffd6ed |
static char *resolve_fstab_device (guestfs_h *g, const char *spec,
|
|
|
ffd6ed |
Hash_table *md_map);
|
|
|
ffd6ed |
static int inspect_with_augeas (guestfs_h *g, struct inspect_fs *fs, const char **configfiles, int (*f) (guestfs_h *, struct inspect_fs *));
|
|
|
ffd6ed |
-static int is_partition (guestfs_h *g, const char *partition);
|
|
|
ffd6ed |
|
|
|
ffd6ed |
/* Hash structure for uuid->path lookups */
|
|
|
ffd6ed |
typedef struct md_uuid {
|
|
|
ffd6ed |
@@ -1436,7 +1435,7 @@ resolve_fstab_device_xdev (guestfs_h *g, const char *type, const char *disk,
|
|
|
ffd6ed |
ITER_DRIVES (g, i, drv) {
|
|
|
ffd6ed |
if (drv->name && STREQ (drv->name, name)) {
|
|
|
ffd6ed |
device = safe_asprintf (g, "%s%s", devices[i], part);
|
|
|
ffd6ed |
- if (!is_partition (g, device)) {
|
|
|
ffd6ed |
+ if (!guestfs___is_partition (g, device)) {
|
|
|
ffd6ed |
free (device);
|
|
|
ffd6ed |
return 0;
|
|
|
ffd6ed |
}
|
|
|
ffd6ed |
@@ -1463,7 +1462,7 @@ resolve_fstab_device_xdev (guestfs_h *g, const char *type, const char *disk,
|
|
|
ffd6ed |
*/
|
|
|
ffd6ed |
if (i < count) {
|
|
|
ffd6ed |
device = safe_asprintf (g, "%s%s", devices[i], part);
|
|
|
ffd6ed |
- if (!is_partition (g, device)) {
|
|
|
ffd6ed |
+ if (!guestfs___is_partition (g, device)) {
|
|
|
ffd6ed |
free (device);
|
|
|
ffd6ed |
return 0;
|
|
|
ffd6ed |
}
|
|
|
ffd6ed |
@@ -1496,7 +1495,7 @@ resolve_fstab_device_cciss (guestfs_h *g, const char *disk, const char *part,
|
|
|
ffd6ed |
if (drv->name && STREQ (drv->name, disk)) {
|
|
|
ffd6ed |
if (part) {
|
|
|
ffd6ed |
device = safe_asprintf (g, "%s%s", devices[i], part);
|
|
|
ffd6ed |
- if (!is_partition (g, device)) {
|
|
|
ffd6ed |
+ if (!guestfs___is_partition (g, device)) {
|
|
|
ffd6ed |
free (device);
|
|
|
ffd6ed |
return 0;
|
|
|
ffd6ed |
}
|
|
|
ffd6ed |
@@ -1541,7 +1540,7 @@ resolve_fstab_device_diskbyid (guestfs_h *g, const char *part,
|
|
|
ffd6ed |
|
|
|
ffd6ed |
/* Make the partition name and check it exists. */
|
|
|
ffd6ed |
device = safe_asprintf (g, "/dev/sda%s", part);
|
|
|
ffd6ed |
- if (!is_partition (g, device)) {
|
|
|
ffd6ed |
+ if (!guestfs___is_partition (g, device)) {
|
|
|
ffd6ed |
free (device);
|
|
|
ffd6ed |
return 0;
|
|
|
ffd6ed |
}
|
|
|
ffd6ed |
@@ -1753,25 +1752,3 @@ make_augeas_path_expression (guestfs_h *g, const char **configfiles)
|
|
|
ffd6ed |
debug (g, "augeas pathexpr = %s", ret);
|
|
|
ffd6ed |
return ret;
|
|
|
ffd6ed |
}
|
|
|
ffd6ed |
-
|
|
|
ffd6ed |
-static int
|
|
|
ffd6ed |
-is_partition (guestfs_h *g, const char *partition)
|
|
|
ffd6ed |
-{
|
|
|
ffd6ed |
- CLEANUP_FREE char *device = NULL;
|
|
|
ffd6ed |
-
|
|
|
ffd6ed |
- guestfs_push_error_handler (g, NULL, NULL);
|
|
|
ffd6ed |
-
|
|
|
ffd6ed |
- if ((device = guestfs_part_to_dev (g, partition)) == NULL) {
|
|
|
ffd6ed |
- guestfs_pop_error_handler (g);
|
|
|
ffd6ed |
- return 0;
|
|
|
ffd6ed |
- }
|
|
|
ffd6ed |
-
|
|
|
ffd6ed |
- if (guestfs_device_index (g, device) == -1) {
|
|
|
ffd6ed |
- guestfs_pop_error_handler (g);
|
|
|
ffd6ed |
- return 0;
|
|
|
ffd6ed |
- }
|
|
|
ffd6ed |
-
|
|
|
ffd6ed |
- guestfs_pop_error_handler (g);
|
|
|
ffd6ed |
-
|
|
|
ffd6ed |
- return 1;
|
|
|
ffd6ed |
-}
|
|
|
ffd6ed |
diff --git a/src/inspect-fs.c b/src/inspect-fs.c
|
|
|
ffd6ed |
index 539d814..686d1ae 100644
|
|
|
ffd6ed |
--- a/src/inspect-fs.c
|
|
|
ffd6ed |
+++ b/src/inspect-fs.c
|
|
|
ffd6ed |
@@ -83,6 +83,7 @@ static int check_filesystem (guestfs_h *g, const char *mountable,
|
|
|
ffd6ed |
const struct guestfs_internal_mountable *m,
|
|
|
ffd6ed |
int whole_device);
|
|
|
ffd6ed |
static int extend_fses (guestfs_h *g);
|
|
|
ffd6ed |
+static int get_partition_context (guestfs_h *g, const char *partition, int *partnum_ret, int *nr_partitions_ret);
|
|
|
ffd6ed |
|
|
|
ffd6ed |
/* Find out if 'device' contains a filesystem. If it does, add
|
|
|
ffd6ed |
* another entry in g->fses.
|
|
|
ffd6ed |
@@ -175,17 +176,18 @@ check_filesystem (guestfs_h *g, const char *mountable,
|
|
|
ffd6ed |
const struct guestfs_internal_mountable *m,
|
|
|
ffd6ed |
int whole_device)
|
|
|
ffd6ed |
{
|
|
|
ffd6ed |
+ int partnum = -1, nr_partitions = -1;
|
|
|
ffd6ed |
/* Not CLEANUP_FREE, as it will be cleaned up with inspection info */
|
|
|
ffd6ed |
char *windows_systemroot = NULL;
|
|
|
ffd6ed |
|
|
|
ffd6ed |
if (extend_fses (g) == -1)
|
|
|
ffd6ed |
return -1;
|
|
|
ffd6ed |
|
|
|
ffd6ed |
- int partnum = -1;
|
|
|
ffd6ed |
- if (!whole_device && m->im_type == MOUNTABLE_DEVICE) {
|
|
|
ffd6ed |
- guestfs_push_error_handler (g, NULL, NULL);
|
|
|
ffd6ed |
- partnum = guestfs_part_to_partnum (g, m->im_device);
|
|
|
ffd6ed |
- guestfs_pop_error_handler (g);
|
|
|
ffd6ed |
+ if (!whole_device && m->im_type == MOUNTABLE_DEVICE &&
|
|
|
ffd6ed |
+ guestfs___is_partition (g, m->im_device)) {
|
|
|
ffd6ed |
+ if (get_partition_context (g, m->im_device,
|
|
|
ffd6ed |
+ &partnum, &nr_partitions) == -1)
|
|
|
ffd6ed |
+ return -1;
|
|
|
ffd6ed |
}
|
|
|
ffd6ed |
|
|
|
ffd6ed |
struct inspect_fs *fs = &g->fses[g->nr_fses-1];
|
|
|
ffd6ed |
@@ -324,7 +326,7 @@ check_filesystem (guestfs_h *g, const char *mountable,
|
|
|
ffd6ed |
* Skip these checks if it's not a whole device (eg. CD) or the
|
|
|
ffd6ed |
* first partition (eg. bootable USB key).
|
|
|
ffd6ed |
*/
|
|
|
ffd6ed |
- else if ((whole_device || partnum == 1) &&
|
|
|
ffd6ed |
+ else if ((whole_device || (partnum == 1 && nr_partitions == 1)) &&
|
|
|
ffd6ed |
(guestfs_is_file (g, "/isolinux/isolinux.cfg") > 0 ||
|
|
|
ffd6ed |
guestfs_is_dir (g, "/EFI/BOOT") > 0 ||
|
|
|
ffd6ed |
guestfs_is_file (g, "/images/install.img") > 0 ||
|
|
|
ffd6ed |
@@ -369,6 +371,36 @@ extend_fses (guestfs_h *g)
|
|
|
ffd6ed |
return 0;
|
|
|
ffd6ed |
}
|
|
|
ffd6ed |
|
|
|
ffd6ed |
+/* Given a partition (eg. /dev/sda2) then return the partition number
|
|
|
ffd6ed |
+ * (eg. 2) and the total number of other partitions.
|
|
|
ffd6ed |
+ */
|
|
|
ffd6ed |
+static int
|
|
|
ffd6ed |
+get_partition_context (guestfs_h *g, const char *partition,
|
|
|
ffd6ed |
+ int *partnum_ret, int *nr_partitions_ret)
|
|
|
ffd6ed |
+{
|
|
|
ffd6ed |
+ int partnum, nr_partitions;
|
|
|
ffd6ed |
+ CLEANUP_FREE char *device = NULL;
|
|
|
ffd6ed |
+ CLEANUP_FREE_PARTITION_LIST struct guestfs_partition_list *partitions = NULL;
|
|
|
ffd6ed |
+
|
|
|
ffd6ed |
+ partnum = guestfs_part_to_partnum (g, partition);
|
|
|
ffd6ed |
+ if (partnum == -1)
|
|
|
ffd6ed |
+ return -1;
|
|
|
ffd6ed |
+
|
|
|
ffd6ed |
+ device = guestfs_part_to_dev (g, partition);
|
|
|
ffd6ed |
+ if (device == NULL)
|
|
|
ffd6ed |
+ return -1;
|
|
|
ffd6ed |
+
|
|
|
ffd6ed |
+ partitions = guestfs_part_list (g, device);
|
|
|
ffd6ed |
+ if (partitions == NULL)
|
|
|
ffd6ed |
+ return -1;
|
|
|
ffd6ed |
+
|
|
|
ffd6ed |
+ nr_partitions = partitions->len;
|
|
|
ffd6ed |
+
|
|
|
ffd6ed |
+ *partnum_ret = partnum;
|
|
|
ffd6ed |
+ *nr_partitions_ret = nr_partitions;
|
|
|
ffd6ed |
+ return 0;
|
|
|
ffd6ed |
+}
|
|
|
ffd6ed |
+
|
|
|
ffd6ed |
int
|
|
|
ffd6ed |
guestfs___is_file_nocase (guestfs_h *g, const char *path)
|
|
|
ffd6ed |
{
|
|
|
ffd6ed |
diff --git a/src/inspect.c b/src/inspect.c
|
|
|
ffd6ed |
index 9248b06..03d870f 100644
|
|
|
ffd6ed |
--- a/src/inspect.c
|
|
|
ffd6ed |
+++ b/src/inspect.c
|
|
|
ffd6ed |
@@ -590,3 +590,25 @@ guestfs___search_for_root (guestfs_h *g, const char *root)
|
|
|
ffd6ed |
root);
|
|
|
ffd6ed |
return NULL;
|
|
|
ffd6ed |
}
|
|
|
ffd6ed |
+
|
|
|
ffd6ed |
+int
|
|
|
ffd6ed |
+guestfs___is_partition (guestfs_h *g, const char *partition)
|
|
|
ffd6ed |
+{
|
|
|
ffd6ed |
+ CLEANUP_FREE char *device = NULL;
|
|
|
ffd6ed |
+
|
|
|
ffd6ed |
+ guestfs_push_error_handler (g, NULL, NULL);
|
|
|
ffd6ed |
+
|
|
|
ffd6ed |
+ if ((device = guestfs_part_to_dev (g, partition)) == NULL) {
|
|
|
ffd6ed |
+ guestfs_pop_error_handler (g);
|
|
|
ffd6ed |
+ return 0;
|
|
|
ffd6ed |
+ }
|
|
|
ffd6ed |
+
|
|
|
ffd6ed |
+ if (guestfs_device_index (g, device) == -1) {
|
|
|
ffd6ed |
+ guestfs_pop_error_handler (g);
|
|
|
ffd6ed |
+ return 0;
|
|
|
ffd6ed |
+ }
|
|
|
ffd6ed |
+
|
|
|
ffd6ed |
+ guestfs_pop_error_handler (g);
|
|
|
ffd6ed |
+
|
|
|
ffd6ed |
+ return 1;
|
|
|
ffd6ed |
+}
|
|
|
ffd6ed |
--
|
|
|
ffd6ed |
1.8.3.1
|
|
|
ffd6ed |
|