Expose XFS version in virt-filesystems

resolves: RHEL-144074
This commit is contained in:
Richard W.M. Jones 2026-02-05 14:12:20 +00:00
parent 73c9bab695
commit 37cca35b39
5 changed files with 1582 additions and 3 deletions

View File

@ -0,0 +1,35 @@
From 706d6dfd2a36d1b176f2a64d897b249eeec4d80f Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Thu, 5 Feb 2026 11:57:33 +0000
Subject: [PATCH] Sort some entries in .gitignore into order
(cherry picked from commit 9d7161da76160b2e5d1f3488b3f0a652554d2077)
---
.gitignore | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.gitignore b/.gitignore
index 94f77ac74..023686435 100644
--- a/.gitignore
+++ b/.gitignore
@@ -81,9 +81,9 @@ Makefile.in
/cat/virt-ls
/cat/virt-tail
/config.cache
-/config.log
/config.h
/config.h.in
+/config.log
/config.sh
/config.status
/configure
@@ -112,8 +112,8 @@ Makefile.in
/ocaml-dep.sh
/ocaml-link.sh
/po-docs/*/*.pod
-/podwrapper.pl
/po/*.gmo
+/podwrapper.pl
/resize/.depend
/resize/virt-resize
/run

View File

@ -0,0 +1,35 @@
From c9022d24dbfb5d715668fd810716753d096648f0 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Mon, 22 Sep 2025 10:58:29 +0100
Subject: [PATCH] build: Add $(NULL) as a convenient list terminator
When building lists of things in Makefiles it's convenient to have a
list terminator to avoid hanging backslash problems. eg:
EXTRA_DIST = \
thing1 \
thing2 \
$(NULL)
Cherry picked from virt-v2v commit 09b86c07bf19beba9ccb8fcca0ebfae34dd56406
(cherry picked from commit dad8c0d3803dcbc91e22ca35c630d9e8a01df81b)
---
common-rules.mk | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/common-rules.mk b/common-rules.mk
index 4df1e33f1..7a116c827 100644
--- a/common-rules.mk
+++ b/common-rules.mk
@@ -20,6 +20,10 @@
-include $(top_builddir)/localenv
+# Convenient way to terminate lists in Makefiles, so that we avoid
+# problems with dangling backslashes.
+NULL =
+
# Files that should universally be removed by 'make clean'. Note if
# there is any case in any subdirectory where a file should not be
# removed by 'make clean', it should not be listed here!

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,473 @@
From fb60205807bf7d8ccd7847abdfd532ed54f6614a Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Thu, 5 Feb 2026 13:17:38 +0000
Subject: [PATCH] filesystems: Optionally display filesystem version
Unlike the recent change to virt-inspector (commit bb210ca433
("inspector: For xfs, try to find and print the filesystem version"))
this does not require the ability to mount the XFS v4 filesystem so it
will work on RHEL 10.
$ virt-filesystems -a rhel-7.0.img --long --fs-version
Name Type VFS Label Size Parent FSVersion
/dev/sda1 filesystem ext4 - 510873600 - -
/dev/sda3 filesystem xfs - 4820303872 - 4
$ virt-filesystems -a rhel-7.3.img --long --fs-version
Name Type VFS Label Size Parent FSVersion
/dev/sda1 filesystem ext4 - 510873600 - -
/dev/sda3 filesystem xfs - 4820303872 - 5
Fixes: https://issues.redhat.com/browse/RHEL-144074
(cherry picked from commit fc61c9439d84fdaab71e1628eb5b95f18ff40ce1)
---
.gitignore | 1 +
filesystems/Makefile.am | 6 +++-
filesystems/filesystems.c | 46 ++++++++++++++++++------
filesystems/utils.c | 60 ++++++++++++++++++++++++++++++++
filesystems/utils.h | 30 ++++++++++++++++
filesystems/virt-filesystems.pod | 12 ++++++-
inspector/Makefile.am | 6 +++-
inspector/inspector.c | 39 ++-------------------
8 files changed, 150 insertions(+), 50 deletions(-)
create mode 100644 filesystems/utils.c
create mode 100644 filesystems/utils.h
diff --git a/.gitignore b/.gitignore
index ed850a20f..0b26da37b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -18,6 +18,7 @@
stamp-*.pod
.deps
+.dirstamp
.libs
Makefile
Makefile.in
diff --git a/filesystems/Makefile.am b/filesystems/Makefile.am
index 17e3b9c6f..625592ff3 100644
--- a/filesystems/Makefile.am
+++ b/filesystems/Makefile.am
@@ -25,7 +25,11 @@ EXTRA_DIST = \
bin_PROGRAMS = virt-filesystems
-virt_filesystems_SOURCES = filesystems.c
+virt_filesystems_SOURCES = \
+ filesystems.c \
+ utils.c \
+ utils.h \
+ $(NULL)
virt_filesystems_CPPFLAGS = \
-DGUESTFS_NO_DEPRECATED=1 \
diff --git a/filesystems/filesystems.c b/filesystems/filesystems.c
index ecaeb0bb2..e86d92be0 100644
--- a/filesystems/filesystems.c
+++ b/filesystems/filesystems.c
@@ -39,6 +39,7 @@
#include "structs-cleanups.h"
#include "options.h"
#include "display-options.h"
+#include "utils.h"
/* These globals are shared with options.c. */
guestfs_h *g;
@@ -75,7 +76,8 @@ static int output = 0;
#define COLUMN_SIZE 32 /* bytes, or human-readable if -h */
#define COLUMN_PARENTS 64
#define COLUMN_UUID 128 /* if --uuid */
-#define NR_COLUMNS 8
+#define COLUMN_FS_VERSION 256 /* if --fs-version */
+#define NR_COLUMNS 9
static int columns;
static void do_output_title (void);
@@ -111,6 +113,8 @@ usage (int status)
" --extra Display swap and data filesystems\n"
" --filesystems Display mountable filesystems\n"
" --format[=raw|..] Force disk format for -a option\n"
+ " --fs-version|--fs-versions\n"
+ " Add filesystem version to --long output\n"
" -h|--human-readable Human-readable sizes in --long output\n"
" --help Display brief help\n"
" --keys-from-stdin Read passphrases from stdin\n"
@@ -157,6 +161,8 @@ main (int argc, char *argv[])
{ "extra", 0, 0, 0 },
{ "filesystems", 0, 0, 0 },
{ "format", 2, 0, 0 },
+ { "fs-version", 0, 0, 0 },
+ { "fs-versions", 0, 0, 0 },
{ "help", 0, 0, HELP_OPTION },
{ "human-readable", 0, 0, 'h' },
{ "keys-from-stdin", 0, 0, 0 },
@@ -191,6 +197,7 @@ main (int argc, char *argv[])
int no_title = 0; /* --no-title */
int long_mode = 0; /* --long|-l */
int uuid = 0; /* --uuid */
+ int fs_version = 0; /* --fs-version */
int title;
g = guestfs_create ();
@@ -227,6 +234,9 @@ main (int argc, char *argv[])
output |= OUTPUT_FILESYSTEMS_EXTRA;
} else if (STREQ (long_options[option_index].name, "filesystems")) {
output |= OUTPUT_FILESYSTEMS;
+ } else if (STREQ (long_options[option_index].name, "fs-version") ||
+ STREQ (long_options[option_index].name, "fs-versions")) {
+ fs_version = 1;
} else if (STREQ (long_options[option_index].name, "logical-volumes") ||
STREQ (long_options[option_index].name, "logvols") ||
STREQ (long_options[option_index].name, "lvs")) {
@@ -337,6 +347,8 @@ main (int argc, char *argv[])
columns |= COLUMN_MBR;
if (uuid)
columns |= COLUMN_UUID;
+ if (fs_version)
+ columns |= COLUMN_FS_VERSION;
}
/* Display title by default only in long mode. */
@@ -379,7 +391,7 @@ static void do_output_pvs (void);
static void do_output_partitions (void);
static void do_output_blockdevs (void);
-static void write_row (const char *name, const char *type, const char *vfs_type, const char *vfs_label, int mbr_id, int64_t size, char **parents, const char *uuid);
+static void write_row (const char *name, const char *type, const char *vfs_type, const char *vfs_label, int mbr_id, int64_t size, char **parents, const char *uuid, const char *fs_version);
static void write_row_strings (char **strings, size_t len);
static char **no_parents (void);
@@ -410,6 +422,8 @@ do_output_title (void)
headings[len++] = "Parent";
if ((columns & COLUMN_UUID))
headings[len++] = "UUID";
+ if ((columns & COLUMN_FS_VERSION))
+ headings[len++] = "FSVersion";
assert (len <= NR_COLUMNS);
write_row_strings ((char **) headings, len);
@@ -450,13 +464,15 @@ do_output_filesystems (void)
exit (EXIT_FAILURE);
for (i = 0; fses[i] != NULL; i += 2) {
+ const char *fs_type = fses[i+1];
CLEANUP_FREE char *dev = NULL, *vfs_label = NULL, *vfs_uuid = NULL;
+ CLEANUP_FREE char *fs_version = NULL;
CLEANUP_FREE_STRING_LIST char **parents = NULL;
int64_t size = -1;
/* Skip swap and unknown, unless --extra flag was given. */
if (!(output & OUTPUT_FILESYSTEMS_EXTRA) &&
- (STREQ (fses[i+1], "swap") || STREQ (fses[i+1], "unknown")))
+ (STREQ (fs_type, "swap") || STREQ (fs_type, "unknown")))
continue;
dev = guestfs_canonical_device_name (g, fses[i]);
@@ -486,6 +502,12 @@ do_output_filesystems (void)
error (EXIT_FAILURE, errno, "strdup");
}
}
+ if ((columns & COLUMN_FS_VERSION)) {
+ const char *version = get_filesystem_version (g, fses[i], fs_type);
+ fs_version = strdup (version ? version : "");
+ if (fs_version == NULL)
+ error (EXIT_FAILURE, errno, "strdup");
+ }
if ((columns & COLUMN_SIZE)) {
CLEANUP_FREE char *device = guestfs_mountable_device (g, fses[i]);
CLEANUP_FREE char *subvolume = NULL;
@@ -533,7 +555,7 @@ do_output_filesystems (void)
parents = no_parents ();
write_row (dev, "filesystem",
- fses[i+1], vfs_label, -1, size, parents, vfs_uuid);
+ fs_type, vfs_label, -1, size, parents, vfs_uuid, fs_version);
}
}
@@ -573,7 +595,7 @@ do_output_lvs (void)
}
write_row (lvs[i], "lv",
- NULL, NULL, -1, size, (char **) parents, uuid);
+ NULL, NULL, -1, size, (char **) parents, uuid, NULL);
}
}
@@ -601,7 +623,8 @@ do_output_vgs (void)
parents = parents_of_vg (vgs->val[i].vg_name);
write_row (name, "vg",
- NULL, NULL, -1, (int64_t) vgs->val[i].vg_size, parents, uuid);
+ NULL, NULL, -1, (int64_t) vgs->val[i].vg_size, parents, uuid,
+ NULL);
}
}
@@ -649,7 +672,7 @@ do_output_pvs (void)
uuid[32] = '\0';
write_row (dev, "pv",
NULL, NULL, -1, (int64_t) pvs->val[i].pv_size,
- (char **) parents, uuid);
+ (char **) parents, uuid, NULL);
}
}
@@ -715,7 +738,7 @@ do_output_partitions (void)
}
write_row (dev, "partition",
- NULL, NULL, mbr_id, size, (char **) parents, NULL);
+ NULL, NULL, mbr_id, size, (char **) parents, NULL, NULL);
}
}
@@ -749,7 +772,7 @@ do_output_blockdevs (void)
parents = no_parents ();
write_row (dev, "device",
- NULL, NULL, -1, size, parents, NULL);
+ NULL, NULL, -1, size, parents, NULL, NULL);
}
}
@@ -882,7 +905,8 @@ parents_of_vg (char *vg)
static void
write_row (const char *name, const char *type,
const char *vfs_type, const char *vfs_label, int mbr_id,
- int64_t size, char **parents, const char *uuid)
+ int64_t size, char **parents, const char *uuid,
+ const char *fs_version)
{
const char *strings[NR_COLUMNS];
CLEANUP_FREE char *parents_str = NULL;
@@ -930,6 +954,8 @@ write_row (const char *name, const char *type,
}
if ((columns & COLUMN_UUID))
strings[len++] = uuid;
+ if ((columns & COLUMN_FS_VERSION))
+ strings[len++] = fs_version;
assert (len <= NR_COLUMNS);
write_row_strings ((char **) strings, len);
diff --git a/filesystems/utils.c b/filesystems/utils.c
new file mode 100644
index 000000000..9de32f1bd
--- /dev/null
+++ b/filesystems/utils.c
@@ -0,0 +1,60 @@
+/* Utility function used by virt-filesystems and virrt-inspector
+ * Copyright (C) 2026 Red Hat Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <config.h>
+
+#include "guestfs.h"
+
+#include "guestfs-utils.h"
+#include "utils.h"
+
+const char *
+get_filesystem_version (guestfs_h *g, const char *dev, const char *fs_type)
+{
+ const char *version = NULL;
+
+#ifdef GUESTFS_HAVE_XFS_INFO2
+ /* For type=xfs, try to guess the filesystem version. */
+ if (STREQ (fs_type, "xfs")) {
+ CLEANUP_FREE_STRING_LIST char **hash = NULL;
+ size_t i;
+
+ guestfs_push_error_handler (g, NULL, NULL);
+
+ hash = guestfs_xfs_info2 (g, dev);
+ if (hash) {
+ for (i = 0; hash[i] != NULL; i += 2) {
+ if (STREQ (hash[i], "meta-data.crc")) {
+ if (STREQ (hash[i+1], "0"))
+ version = "4";
+ else if (STREQ (hash[i+1], "1"))
+ version = "5";
+ break;
+ }
+ /* If new XFS versions are added in future then we can test
+ * for new fields here ...
+ */
+ }
+ }
+
+ guestfs_pop_error_handler (g);
+ }
+#endif /* GUESTFS_HAVE_XFS_INFO2 */
+
+ return version;
+}
diff --git a/filesystems/utils.h b/filesystems/utils.h
new file mode 100644
index 000000000..284f8e1ac
--- /dev/null
+++ b/filesystems/utils.h
@@ -0,0 +1,30 @@
+/* Utility function used by virt-filesystems and virrt-inspector
+ * Copyright (C) 2026 Red Hat Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef GUESTFS_FILESYSTEMS_UTILS_H
+#define GUESTFS_FILESYSTEMS_UTILS_H
+
+#include "guestfs.h"
+
+/* For XFS, return the filesystem version (eg. "4" or "5"). This may
+ * return NULL if no filesystem version is known.
+ */
+const char *get_filesystem_version (guestfs_h *g,
+ const char *dev, const char *fs_type);
+
+#endif /* GUESTFS_FILESYSTEMS_UTILS_H */
diff --git a/filesystems/virt-filesystems.pod b/filesystems/virt-filesystems.pod
index 7955d6a84..c72ae3cf7 100644
--- a/filesystems/virt-filesystems.pod
+++ b/filesystems/virt-filesystems.pod
@@ -197,6 +197,14 @@ If you have untrusted raw-format guest disk images, you should use
this option to specify the disk format. This avoids a possible
security problem with malicious guests (CVE-2010-3851).
+=item B<--fs-version>
+
+=item B<--fs-versions>
+
+In I<--long> mode, display the filesystem version. Currently this
+only has any effect for XFS, displaying either C<4> (for XFS v4) or
+C<5> (for XFS v5). XFS v4 support will be removed from Linux in 2030.
+
=item B<-h>
=item B<--human-readable>
@@ -221,7 +229,9 @@ external programs.
Use I<-h> if you want sizes to be displayed in human-readable format.
The default is to show raw numbers of I<bytes>.
-Use I<--uuid> to display UUIDs too.
+Use I<--fs-version> to display filesystem versions.
+
+Use I<--uuid> to display UUIDs.
=item B<--lvs>
diff --git a/inspector/Makefile.am b/inspector/Makefile.am
index 04c608f44..637a10415 100644
--- a/inspector/Makefile.am
+++ b/inspector/Makefile.am
@@ -48,7 +48,10 @@ dist_doc_DATA = \
bin_PROGRAMS = virt-inspector
virt_inspector_SOURCES = \
- inspector.c
+ ../filesystems/utils.c \
+ ../filesystems/utils.h \
+ inspector.c \
+ $(NULL)
virt_inspector_CPPFLAGS = \
-DGUESTFS_NO_DEPRECATED=1 \
@@ -56,6 +59,7 @@ virt_inspector_CPPFLAGS = \
-I$(top_srcdir)/common/utils -I$(top_builddir)/common/utils \
-I$(top_srcdir)/common/structs -I$(top_builddir)/common/structs \
-I$(top_srcdir)/lib -I$(top_builddir)/lib \
+ -I$(top_srcdir)/filesystems -I$(top_builddir)/filesystems \
-I$(top_srcdir)/include \
-I$(top_srcdir)/common/options -I$(top_builddir)/common/options \
-I$(top_srcdir)/fish \
diff --git a/inspector/inspector.c b/inspector/inspector.c
index fc6b9f0d0..be34e8794 100644
--- a/inspector/inspector.c
+++ b/inspector/inspector.c
@@ -44,6 +44,7 @@
#include "options.h"
#include "display-options.h"
#include "libxml2-writer-macros.h"
+#include "utils.h"
/* Currently open libguestfs handle. */
guestfs_h *g;
@@ -569,42 +570,6 @@ output_mountpoints (xmlTextWriterPtr xo, char *root)
} end_element ();
}
-static const char *
-get_filesystem_version (const char *dev, const char *fs_type)
-{
- const char *version = NULL;
-
-#ifdef GUESTFS_HAVE_XFS_INFO2
- /* For type=xfs, try to guess the filesystem version. */
- if (STREQ (fs_type, "xfs")) {
- CLEANUP_FREE_STRING_LIST char **hash = NULL;
- size_t i;
-
- guestfs_push_error_handler (g, NULL, NULL);
-
- hash = guestfs_xfs_info2 (g, dev);
- if (hash) {
- for (i = 0; hash[i] != NULL; i += 2) {
- if (STREQ (hash[i], "meta-data.crc")) {
- if (STREQ (hash[i+1], "0"))
- version = "4";
- else if (STREQ (hash[i+1], "1"))
- version = "5";
- break;
- }
- /* If new XFS versions are added in future then we can test
- * for new fields here ...
- */
- }
- }
-
- guestfs_pop_error_handler (g);
- }
-#endif /* GUESTFS_HAVE_XFS_INFO2 */
-
- return version;
-}
-
static void
output_filesystems (xmlTextWriterPtr xo, char *root)
{
@@ -634,7 +599,7 @@ output_filesystems (xmlTextWriterPtr xo, char *root)
str = guestfs_vfs_type (g, filesystems[i]);
if (str && str[0]) {
- const char *version = get_filesystem_version (dev, str);
+ const char *version = get_filesystem_version (g, dev, str);
start_element ("type") {
if (version)
attribute ("version", version);

View File

@ -16,7 +16,7 @@
Summary: Tools to access and modify virtual machine disk images
Name: guestfs-tools
Version: 1.54.0
Release: 8%{?dist}
Release: 9%{?dist}
License: GPL-2.0-or-later AND LGPL-2.0-or-later
# Build only for architectures that have a kernel
@ -66,6 +66,10 @@ Patch0018: 0018-inspector-Add-windows_group_policy-is-Windows-GPOs-d.patch
Patch0019: 0019-RHEL-Reject-use-of-libguestfs-winsupport-features-ex.patch
Patch0020: 0020-RHEL-builder-Disable-opensuse-repository.patch
Patch0021: 0021-inspector-For-xfs-try-to-find-and-print-the-filesyst.patch
Patch0022: 0022-Sort-some-entries-in-.gitignore-into-order.patch
Patch0023: 0023-build-Add-NULL-as-a-convenient-list-terminator.patch
Patch0024: 0024-Move-virt-filesystems-virt-log-virt-ls-virt-tail-to-.patch
Patch0025: 0025-filesystems-Optionally-display-filesystem-version.patch
# Basic build requirements.
BuildRequires: autoconf, automake, libtool, gettext-devel
@ -417,7 +421,7 @@ end
%changelog
* Mon Jan 26 2026 Richard W.M. Jones <rjones@redhat.com> - 1.54.0-8
* Wed Feb 05 2026 Richard W.M. Jones <rjones@redhat.com> - 1.54.0-9
- Synchronize spec file with Fedora
- Fix pnputils after virt-customize --inject-virtio-win
resolves: RHEL-116537
@ -428,7 +432,7 @@ end
resolves: RHEL-122307
- Add AV and GPOs to virt-inspector output
resolves: RHEL-125955
- Expose XFS version in virt-inspector
- Expose XFS version in virt-filesystems
resolves: RHEL-144074
* Wed Aug 13 2025 Richard W.M. Jones <rjones@redhat.com> - 1.54.0-3