|
|
aa0300 |
From ba1ee149fe81cf4061e53eecb0ec0cc1aee63da7 Mon Sep 17 00:00:00 2001
|
|
|
aa0300 |
From: Pino Toscano <ptoscano@redhat.com>
|
|
|
aa0300 |
Date: Tue, 6 Dec 2016 16:08:12 +0100
|
|
|
aa0300 |
Subject: [PATCH] inspect: gather info from /usr filesystems as well
|
|
|
aa0300 |
(RHBZ#1401474)
|
|
|
aa0300 |
|
|
|
aa0300 |
Flag the filesystems for Linux /usr properly as USR role, and detect
|
|
|
aa0300 |
some data out of it, like the distro information from an os-release
|
|
|
aa0300 |
(if present), and the architecture (since the binaries used for our
|
|
|
aa0300 |
architecture check will be available there only).
|
|
|
aa0300 |
|
|
|
aa0300 |
Later on, collect the results in a way similar to what is done for
|
|
|
aa0300 |
CoreOS: for each non-CoreOS root, try to find its /usr filesystem, and
|
|
|
aa0300 |
if found then merge what is missing from root; in the last case, also
|
|
|
aa0300 |
override the distro inspection data (version, product name) if available
|
|
|
aa0300 |
in /usr.
|
|
|
aa0300 |
|
|
|
aa0300 |
(cherry picked from commit 1d86b3768956f818262a5189bb1ba996dedbf531)
|
|
|
aa0300 |
---
|
|
|
aa0300 |
src/guestfs-internal.h | 1 +
|
|
|
aa0300 |
src/inspect-fs-unix.c | 26 ++++++++++++++++
|
|
|
aa0300 |
src/inspect-fs.c | 6 ++--
|
|
|
aa0300 |
src/inspect.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++++--
|
|
|
aa0300 |
4 files changed, 109 insertions(+), 5 deletions(-)
|
|
|
aa0300 |
|
|
|
aa0300 |
diff --git a/src/guestfs-internal.h b/src/guestfs-internal.h
|
|
|
aa0300 |
index eb201aa..0f5f975 100644
|
|
|
aa0300 |
--- a/src/guestfs-internal.h
|
|
|
aa0300 |
+++ b/src/guestfs-internal.h
|
|
|
aa0300 |
@@ -795,6 +795,7 @@ extern void guestfs_int_merge_fs_inspections (guestfs_h *g, struct inspect_fs *d
|
|
|
aa0300 |
|
|
|
aa0300 |
/* inspect-fs-unix.c */
|
|
|
aa0300 |
extern int guestfs_int_check_linux_root (guestfs_h *g, struct inspect_fs *fs);
|
|
|
aa0300 |
+extern int guestfs_int_check_linux_usr (guestfs_h *g, struct inspect_fs *fs);
|
|
|
aa0300 |
extern int guestfs_int_check_freebsd_root (guestfs_h *g, struct inspect_fs *fs);
|
|
|
aa0300 |
extern int guestfs_int_check_netbsd_root (guestfs_h *g, struct inspect_fs *fs);
|
|
|
aa0300 |
extern int guestfs_int_check_openbsd_root (guestfs_h *g, struct inspect_fs *fs);
|
|
|
aa0300 |
diff --git a/src/inspect-fs-unix.c b/src/inspect-fs-unix.c
|
|
|
aa0300 |
index 8b7a7ee..48c4fd2 100644
|
|
|
aa0300 |
--- a/src/inspect-fs-unix.c
|
|
|
aa0300 |
+++ b/src/inspect-fs-unix.c
|
|
|
aa0300 |
@@ -813,6 +813,32 @@ guestfs_int_check_linux_root (guestfs_h *g, struct inspect_fs *fs)
|
|
|
aa0300 |
return 0;
|
|
|
aa0300 |
}
|
|
|
aa0300 |
|
|
|
aa0300 |
+/* The currently mounted device looks like a Linux /usr. */
|
|
|
aa0300 |
+int
|
|
|
aa0300 |
+guestfs_int_check_linux_usr (guestfs_h *g, struct inspect_fs *fs)
|
|
|
aa0300 |
+{
|
|
|
aa0300 |
+ int r;
|
|
|
aa0300 |
+
|
|
|
aa0300 |
+ fs->type = OS_TYPE_LINUX;
|
|
|
aa0300 |
+ fs->role = OS_ROLE_USR;
|
|
|
aa0300 |
+
|
|
|
aa0300 |
+ if (guestfs_is_file_opts (g, "/lib/os-release",
|
|
|
aa0300 |
+ GUESTFS_IS_FILE_OPTS_FOLLOWSYMLINKS, 1, -1) > 0) {
|
|
|
aa0300 |
+ r = parse_os_release (g, fs, "/lib/os-release");
|
|
|
aa0300 |
+ if (r == -1) /* error */
|
|
|
aa0300 |
+ return -1;
|
|
|
aa0300 |
+ if (r == 1) /* ok - detected the release from this file */
|
|
|
aa0300 |
+ goto skip_release_checks;
|
|
|
aa0300 |
+ }
|
|
|
aa0300 |
+
|
|
|
aa0300 |
+ skip_release_checks:;
|
|
|
aa0300 |
+
|
|
|
aa0300 |
+ /* Determine the architecture. */
|
|
|
aa0300 |
+ check_architecture (g, fs);
|
|
|
aa0300 |
+
|
|
|
aa0300 |
+ return 0;
|
|
|
aa0300 |
+}
|
|
|
aa0300 |
+
|
|
|
aa0300 |
/* The currently mounted device is known to be a FreeBSD root. */
|
|
|
aa0300 |
int
|
|
|
aa0300 |
guestfs_int_check_freebsd_root (guestfs_h *g, struct inspect_fs *fs)
|
|
|
aa0300 |
diff --git a/src/inspect-fs.c b/src/inspect-fs.c
|
|
|
aa0300 |
index 58f08b8..f6c2656 100644
|
|
|
aa0300 |
--- a/src/inspect-fs.c
|
|
|
aa0300 |
+++ b/src/inspect-fs.c
|
|
|
aa0300 |
@@ -247,8 +247,10 @@ check_filesystem (guestfs_h *g, const char *mountable,
|
|
|
aa0300 |
is_dir_bin &&
|
|
|
aa0300 |
is_dir_share &&
|
|
|
aa0300 |
guestfs_is_dir (g, "/local") > 0 &&
|
|
|
aa0300 |
- guestfs_is_file (g, "/etc/fstab") == 0)
|
|
|
aa0300 |
- ;
|
|
|
aa0300 |
+ guestfs_is_file (g, "/etc/fstab") == 0) {
|
|
|
aa0300 |
+ if (guestfs_int_check_linux_usr (g, fs) == -1)
|
|
|
aa0300 |
+ return -1;
|
|
|
aa0300 |
+ }
|
|
|
aa0300 |
/* CoreOS /usr? */
|
|
|
aa0300 |
else if (is_dir_bin &&
|
|
|
aa0300 |
is_dir_share &&
|
|
|
aa0300 |
diff --git a/src/inspect.c b/src/inspect.c
|
|
|
aa0300 |
index e805291..db2a125 100644
|
|
|
aa0300 |
--- a/src/inspect.c
|
|
|
aa0300 |
+++ b/src/inspect.c
|
|
|
aa0300 |
@@ -26,6 +26,7 @@
|
|
|
aa0300 |
#include <string.h>
|
|
|
aa0300 |
#include <sys/stat.h>
|
|
|
aa0300 |
#include <libintl.h>
|
|
|
aa0300 |
+#include <assert.h>
|
|
|
aa0300 |
|
|
|
aa0300 |
#ifdef HAVE_ENDIAN_H
|
|
|
aa0300 |
#include <endian.h>
|
|
|
aa0300 |
@@ -41,6 +42,8 @@ COMPILE_REGEXP (re_primary_partition, "^/dev/(?:h|s|v)d.[1234]$", 0)
|
|
|
aa0300 |
|
|
|
aa0300 |
static void check_for_duplicated_bsd_root (guestfs_h *g);
|
|
|
aa0300 |
static void collect_coreos_inspection_info (guestfs_h *g);
|
|
|
aa0300 |
+static void collect_linux_inspection_info (guestfs_h *g);
|
|
|
aa0300 |
+static void collect_linux_inspection_info_for (guestfs_h *g, struct inspect_fs *root);
|
|
|
aa0300 |
|
|
|
aa0300 |
/* The main inspection code. */
|
|
|
aa0300 |
char **
|
|
|
aa0300 |
@@ -81,6 +84,12 @@ guestfs_impl_inspect_os (guestfs_h *g)
|
|
|
aa0300 |
*/
|
|
|
aa0300 |
check_for_duplicated_bsd_root (g);
|
|
|
aa0300 |
|
|
|
aa0300 |
+ /* For Linux guests with a separate /usr filesyste, merge some of the
|
|
|
aa0300 |
+ * inspected information in that partition to the inspect_fs struct
|
|
|
aa0300 |
+ * of the root filesystem.
|
|
|
aa0300 |
+ */
|
|
|
aa0300 |
+ collect_linux_inspection_info (g);
|
|
|
aa0300 |
+
|
|
|
aa0300 |
/* At this point we have, in the handle, a list of all filesystems
|
|
|
aa0300 |
* found and data about each one. Now we assemble the list of
|
|
|
aa0300 |
* filesystems which are root devices and return that to the user.
|
|
|
aa0300 |
@@ -143,9 +152,75 @@ collect_coreos_inspection_info (guestfs_h *g)
|
|
|
aa0300 |
guestfs_int_merge_fs_inspections (g, root, usr);
|
|
|
aa0300 |
}
|
|
|
aa0300 |
|
|
|
aa0300 |
-/* On *BSD systems, sometimes /dev/sda[1234] is a shadow of the real root
|
|
|
aa0300 |
- * filesystem that is probably /dev/sda5
|
|
|
aa0300 |
- * (see: http://www.freebsd.org/doc/handbook/disk-organization.html)
|
|
|
aa0300 |
+/**
|
|
|
aa0300 |
+ * Traverse through the filesystems and find the /usr filesystem for
|
|
|
aa0300 |
+ * the specified C<root>: if found, merge its basic inspection details
|
|
|
aa0300 |
+ * to the root when they were set (i.e. because the /usr had os-release
|
|
|
aa0300 |
+ * or other ways to identify the OS).
|
|
|
aa0300 |
+ */
|
|
|
aa0300 |
+static void
|
|
|
aa0300 |
+collect_linux_inspection_info_for (guestfs_h *g, struct inspect_fs *root)
|
|
|
aa0300 |
+{
|
|
|
aa0300 |
+ size_t i;
|
|
|
aa0300 |
+ struct inspect_fs *usr = NULL;
|
|
|
aa0300 |
+
|
|
|
aa0300 |
+ for (i = 0; i < g->nr_fses; ++i) {
|
|
|
aa0300 |
+ struct inspect_fs *fs = &g->fses[i];
|
|
|
aa0300 |
+ size_t j;
|
|
|
aa0300 |
+
|
|
|
aa0300 |
+ if (!(fs->distro == root->distro || fs->distro == OS_DISTRO_UNKNOWN) ||
|
|
|
aa0300 |
+ fs->role != OS_ROLE_USR)
|
|
|
aa0300 |
+ continue;
|
|
|
aa0300 |
+
|
|
|
aa0300 |
+ for (j = 0; j < root->nr_fstab; ++j) {
|
|
|
aa0300 |
+ if (STREQ (fs->mountable, root->fstab[j].mountable)) {
|
|
|
aa0300 |
+ usr = fs;
|
|
|
aa0300 |
+ goto got_usr;
|
|
|
aa0300 |
+ }
|
|
|
aa0300 |
+ }
|
|
|
aa0300 |
+ }
|
|
|
aa0300 |
+
|
|
|
aa0300 |
+ assert (usr == NULL);
|
|
|
aa0300 |
+ return;
|
|
|
aa0300 |
+
|
|
|
aa0300 |
+ got_usr:
|
|
|
aa0300 |
+ /* If the version information in /usr is not null, then most probably
|
|
|
aa0300 |
+ * there was an os-release file there, so reset what is in root
|
|
|
aa0300 |
+ * and pick the results from /usr.
|
|
|
aa0300 |
+ */
|
|
|
aa0300 |
+ if (!(usr->major_version == 0 && usr->minor_version == 0)) {
|
|
|
aa0300 |
+ root->distro = OS_DISTRO_UNKNOWN;
|
|
|
aa0300 |
+ free (root->product_name);
|
|
|
aa0300 |
+ root->product_name = NULL;
|
|
|
aa0300 |
+ }
|
|
|
aa0300 |
+
|
|
|
aa0300 |
+ guestfs_int_merge_fs_inspections (g, root, usr);
|
|
|
aa0300 |
+}
|
|
|
aa0300 |
+
|
|
|
aa0300 |
+/**
|
|
|
aa0300 |
+ * Traverse through the filesystem list and find out if it contains
|
|
|
aa0300 |
+ * the C and C</usr> filesystems of a Linux image (but not CoreOS,
|
|
|
aa0300 |
+ * for which there is a separate C<collect_coreos_inspection_info>).
|
|
|
aa0300 |
+ * If this is the case, sum up all the collected information on each
|
|
|
aa0300 |
+ * root fs from the respective /usr filesystems.
|
|
|
aa0300 |
+ */
|
|
|
aa0300 |
+static void
|
|
|
aa0300 |
+collect_linux_inspection_info (guestfs_h *g)
|
|
|
aa0300 |
+{
|
|
|
aa0300 |
+ size_t i;
|
|
|
aa0300 |
+
|
|
|
aa0300 |
+ for (i = 0; i < g->nr_fses; ++i) {
|
|
|
aa0300 |
+ struct inspect_fs *fs = &g->fses[i];
|
|
|
aa0300 |
+
|
|
|
aa0300 |
+ if (fs->distro != OS_DISTRO_COREOS && fs->role == OS_ROLE_ROOT)
|
|
|
aa0300 |
+ collect_linux_inspection_info_for (g, fs);
|
|
|
aa0300 |
+ }
|
|
|
aa0300 |
+}
|
|
|
aa0300 |
+
|
|
|
aa0300 |
+/**
|
|
|
aa0300 |
+ * On *BSD systems, sometimes F</dev/sda[1234]> is a shadow of the
|
|
|
aa0300 |
+ * real root filesystem that is probably F</dev/sda5> (see:
|
|
|
aa0300 |
+ * L<http://www.freebsd.org/doc/handbook/disk-organization.html>)
|
|
|
aa0300 |
*/
|
|
|
aa0300 |
static void
|
|
|
aa0300 |
check_for_duplicated_bsd_root (guestfs_h *g)
|
|
|
aa0300 |
--
|
|
|
aa0300 |
2.7.4
|
|
|
aa0300 |
|