Sync with a10-beta
This commit is contained in:
parent
dbe3130b9c
commit
b9f12a4084
11
.gitignore
vendored
11
.gitignore
vendored
@ -1,2 +1,9 @@
|
||||
libguestfs-1.56.1.tar.gz
|
||||
libguestfs.keyring
|
||||
*~
|
||||
.build*.log
|
||||
*.rpm
|
||||
clog
|
||||
/x86_64/
|
||||
/i386/
|
||||
/noarch/
|
||||
/libguestfs-*.tar.gz
|
||||
/libguestfs-*.tar.gz.sig
|
||||
|
||||
@ -1,29 +0,0 @@
|
||||
From dc218b25f0bc2704918748e4e8120ec436783e58 Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Tue, 24 Jun 2025 14:04:10 +0100
|
||||
Subject: [PATCH] appliance: Ignore sit0 network device in the guest
|
||||
|
||||
Reported-by: Srikanth Aithal <sraithal@amd.com>
|
||||
Fixed-by: Stefano Brivio <sbrivio@redhat.com>
|
||||
Tested-by: Srikanth Aithal <sraithal@amd.com>
|
||||
See-also: https://lists.libguestfs.org/archives/list/guestfs@lists.libguestfs.org/thread/566LAY7RNM7T7EMQQQYIQA2VK5TXETK5/
|
||||
---
|
||||
appliance/init | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/appliance/init b/appliance/init
|
||||
index 5d35a47dd..47eb97dfc 100755
|
||||
--- a/appliance/init
|
||||
+++ b/appliance/init
|
||||
@@ -127,7 +127,7 @@ ip addr add 127.0.0.1/8 brd + dev lo scope host
|
||||
ip link set dev lo up
|
||||
|
||||
if test "$guestfs_network" = 1; then
|
||||
- iface=$(ls -I all -I default -I lo /proc/sys/net/ipv4/conf)
|
||||
+ iface=$(ls -I all -I default -I lo -I sit0 /proc/sys/net/ipv4/conf)
|
||||
# Two workarounds for Ubuntu:
|
||||
touch /etc/fstab
|
||||
rm -f /etc/dhcp/dhclient-enter-hooks.d/resolved
|
||||
--
|
||||
2.47.3
|
||||
|
||||
@ -0,0 +1,42 @@
|
||||
From 07ea5915766d829b62255fb2a94239a28f433159 Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Mon, 19 Jan 2026 21:36:08 +0000
|
||||
Subject: [PATCH] generator/daemon.ml: Avoid not available macro for OCaml
|
||||
functions
|
||||
|
||||
Reported-by: Toolybird
|
||||
Fixes: https://github.com/libguestfs/libguestfs/issues/290
|
||||
(cherry picked from commit 1b79e22be443b48dc2bdb518cfea14342b3d8136)
|
||||
---
|
||||
generator/daemon.ml | 8 +++++++-
|
||||
1 file changed, 7 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/generator/daemon.ml b/generator/daemon.ml
|
||||
index 65844309e..f1f954087 100644
|
||||
--- a/generator/daemon.ml
|
||||
+++ b/generator/daemon.ml
|
||||
@@ -1054,7 +1054,8 @@ let generate_daemon_optgroups_h () =
|
||||
pr "#define OPTGROUP_%s_NOT_AVAILABLE \\\n"
|
||||
(String.uppercase_ascii group);
|
||||
List.iter (
|
||||
- fun { name; style = ret, args, optargs } ->
|
||||
+ function
|
||||
+ | { name; style = ret, args, optargs; impl = C } ->
|
||||
let style = ret, args @ args_of_optargs optargs, [] in
|
||||
pr " ";
|
||||
generate_prototype
|
||||
@@ -1065,6 +1066,11 @@ let generate_daemon_optgroups_h () =
|
||||
~semicolon:false
|
||||
name style;
|
||||
pr " { abort (); } \\\n"
|
||||
+ | { impl = OCaml _ } ->
|
||||
+ (* Don't need to generate anything for OCaml functions since
|
||||
+ * the caml-stubs do_* function will still exist.
|
||||
+ *)
|
||||
+ ()
|
||||
) fns;
|
||||
pr " int optgroup_%s_available (void) { return 0; }\n" group;
|
||||
pr "\n"
|
||||
--
|
||||
2.47.3
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
From d1808ea5eb7ad9c38f5f8c5e90d086886300acd8 Mon Sep 17 00:00:00 2001
|
||||
From d9e9cc39c92288b713320b4d7f6f66d1b1e4ff42 Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Mon, 29 Jul 2013 14:47:56 +0100
|
||||
Subject: [PATCH] RHEL: Disable unsupported remote drive protocols
|
||||
@ -180,21 +180,21 @@ index e4e1021db..8419ce78a 100755
|
||||
rm test-add-uri.out
|
||||
rm test-add-uri.img
|
||||
diff --git a/generator/actions_core.ml b/generator/actions_core.ml
|
||||
index 60d3140ed..d374ffbf8 100644
|
||||
index b4ec6db87..9c23da008 100644
|
||||
--- a/generator/actions_core.ml
|
||||
+++ b/generator/actions_core.ml
|
||||
@@ -350,22 +350,6 @@ F<filename> is interpreted as a local file or device.
|
||||
@@ -343,22 +343,6 @@ F<filename> is interpreted as a local file or device.
|
||||
This is the default if the optional protocol parameter
|
||||
is omitted.
|
||||
|
||||
-=item C<protocol = \"ftp\"|\"ftps\"|\"http\"|\"https\">
|
||||
-=item C<protocol = "ftp"|"ftps"|"http"|"https">
|
||||
-
|
||||
-Connect to a remote FTP or HTTP server.
|
||||
-The C<server> parameter must also be supplied - see below.
|
||||
-
|
||||
-See also: L<guestfs(3)/FTP AND HTTP>
|
||||
-
|
||||
-=item C<protocol = \"iscsi\">
|
||||
-=item C<protocol = "iscsi">
|
||||
-
|
||||
-Connect to the iSCSI server.
|
||||
-The C<server> parameter must also be supplied - see below.
|
||||
@ -203,14 +203,14 @@ index 60d3140ed..d374ffbf8 100644
|
||||
-
|
||||
-See also: L<guestfs(3)/ISCSI>.
|
||||
-
|
||||
=item C<protocol = \"nbd\">
|
||||
=item C<protocol = "nbd">
|
||||
|
||||
Connect to the Network Block Device server.
|
||||
@@ -382,15 +366,6 @@ The C<secret> parameter may be supplied. See below.
|
||||
@@ -375,15 +359,6 @@ The C<secret> parameter may be supplied. See below.
|
||||
|
||||
See also: L<guestfs(3)/CEPH>.
|
||||
|
||||
-=item C<protocol = \"ssh\">
|
||||
-=item C<protocol = "ssh">
|
||||
-
|
||||
-Connect to the Secure Shell (ssh) server.
|
||||
-
|
||||
@ -222,7 +222,7 @@ index 60d3140ed..d374ffbf8 100644
|
||||
=back
|
||||
|
||||
=item C<server>
|
||||
@@ -401,11 +376,8 @@ is a list of server(s).
|
||||
@@ -394,11 +369,8 @@ is a list of server(s).
|
||||
Protocol Number of servers required
|
||||
-------- --------------------------
|
||||
file List must be empty or param not used at all
|
||||
@ -234,7 +234,7 @@ index 60d3140ed..d374ffbf8 100644
|
||||
|
||||
Each list element is a string specifying a server. The string must be
|
||||
in one of the following formats:
|
||||
@@ -421,10 +393,10 @@ for the protocol is used (see F</etc/services>).
|
||||
@@ -414,10 +386,10 @@ for the protocol is used (see F</etc/services>).
|
||||
|
||||
=item C<username>
|
||||
|
||||
@ -249,7 +249,7 @@ index 60d3140ed..d374ffbf8 100644
|
||||
example if using the libvirt backend and if the libvirt backend is configured to
|
||||
start the qemu appliance as a special user such as C<qemu.qemu>. If in doubt,
|
||||
diff --git a/lib/drives.c b/lib/drives.c
|
||||
index c068b8ecb..6e4453ce5 100644
|
||||
index 6a62623d5..8c334c6c7 100644
|
||||
--- a/lib/drives.c
|
||||
+++ b/lib/drives.c
|
||||
@@ -166,34 +166,6 @@ create_drive_non_file (guestfs_h *g,
|
||||
@ -355,7 +355,7 @@ index c068b8ecb..6e4453ce5 100644
|
||||
/**
|
||||
* Create the special F</dev/null> drive.
|
||||
*
|
||||
@@ -768,26 +679,6 @@ guestfs_impl_add_drive_opts (guestfs_h *g, const char *filename,
|
||||
@@ -769,26 +680,6 @@ guestfs_impl_add_drive_opts (guestfs_h *g,
|
||||
drv = create_drive_file (g, &data);
|
||||
}
|
||||
}
|
||||
@ -382,7 +382,7 @@ index c068b8ecb..6e4453ce5 100644
|
||||
else if (STREQ (protocol, "nbd")) {
|
||||
data.protocol = drive_protocol_nbd;
|
||||
drv = create_drive_nbd (g, &data);
|
||||
@@ -796,10 +687,6 @@ guestfs_impl_add_drive_opts (guestfs_h *g, const char *filename,
|
||||
@@ -797,10 +688,6 @@ guestfs_impl_add_drive_opts (guestfs_h *g,
|
||||
data.protocol = drive_protocol_rbd;
|
||||
drv = create_drive_rbd (g, &data);
|
||||
}
|
||||
@ -497,10 +497,10 @@ index 485d75718..e917cd1a6 100755
|
||||
|
||||
$guestfish -d nbd run ||:
|
||||
diff --git a/tests/disks/test-qemu-drive.sh b/tests/disks/test-qemu-drive.sh
|
||||
index d6ce0f07f..153b9c8cc 100755
|
||||
index f5ecccc3c..d699d37ca 100755
|
||||
--- a/tests/disks/test-qemu-drive.sh
|
||||
+++ b/tests/disks/test-qemu-drive.sh
|
||||
@@ -63,35 +63,6 @@ check_output
|
||||
@@ -64,35 +64,6 @@ check_output
|
||||
grep -sq -- '-drive file=rbd:abc-def/ghi-jkl:auth_supported=none,' "$DEBUG_QEMU_FILE" || fail
|
||||
rm "$DEBUG_QEMU_FILE"
|
||||
|
||||
@ -536,7 +536,7 @@ index d6ce0f07f..153b9c8cc 100755
|
||||
# NBD.
|
||||
|
||||
guestfish <<EOF ||:
|
||||
@@ -109,14 +80,3 @@ EOF
|
||||
@@ -110,14 +81,3 @@ EOF
|
||||
check_output
|
||||
grep -sq -- '-drive file=nbd:unix:/socket,' "$DEBUG_QEMU_FILE" || fail
|
||||
rm "$DEBUG_QEMU_FILE"
|
||||
@ -1,29 +0,0 @@
|
||||
From 0a91731356a5bb0ab8eee620fc1fed1656b117f9 Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Fri, 25 Jul 2025 09:36:35 +0100
|
||||
Subject: [PATCH] lib: libvirt: Debug error from virDomainDestroyFlags
|
||||
|
||||
It's useful to see the error returned from virDomainDestroyFlags, so
|
||||
make sure this gets written to debug output.
|
||||
---
|
||||
lib/launch-libvirt.c | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/lib/launch-libvirt.c b/lib/launch-libvirt.c
|
||||
index 55a4ad41c..8dbde5341 100644
|
||||
--- a/lib/launch-libvirt.c
|
||||
+++ b/lib/launch-libvirt.c
|
||||
@@ -2173,6 +2173,10 @@ destroy_domain (guestfs_h *g, virDomainPtr dom, int check_for_errors)
|
||||
|
||||
/* Error returned by virDomainDestroyFlags ... */
|
||||
err = virGetLastError ();
|
||||
+ if (err && err->code != 0) {
|
||||
+ debug (g, "virDomainDestroy: %s [code=%d int1=%d]",
|
||||
+ err->message, err->code, err->int1);
|
||||
+ }
|
||||
|
||||
/* Retry (indefinitely) if we're just waiting for qemu to shut down. See:
|
||||
* https://www.redhat.com/archives/libvir-list/2016-January/msg00767.html
|
||||
--
|
||||
2.47.3
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
From f8e4c310bb580e576d4962c395a99278e039fdf4 Mon Sep 17 00:00:00 2001
|
||||
From 3319a68b51de8ded8a76dcd72f8fce804dd581a4 Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Tue, 7 Jul 2015 09:28:03 -0400
|
||||
Subject: [PATCH] RHEL: Reject use of libguestfs-winsupport features except for
|
||||
@ -13,7 +13,7 @@ edits.
|
||||
3 files changed, 19 insertions(+)
|
||||
|
||||
diff --git a/generator/c.ml b/generator/c.ml
|
||||
index c6e5dd994..b6cc0da20 100644
|
||||
index f1217c659..923c2be38 100644
|
||||
--- a/generator/c.ml
|
||||
+++ b/generator/c.ml
|
||||
@@ -1834,6 +1834,22 @@ and generate_client_actions actions () =
|
||||
@ -1,32 +0,0 @@
|
||||
From c7aaa89fba21499fa6ba11e41fdc8de610819a87 Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Fri, 25 Jul 2025 09:39:51 +0100
|
||||
Subject: [PATCH] lib: libvirt: Sleep before retrying virDomainDestroyFlags
|
||||
|
||||
This saves us going into a loop if virDomainDestroyFlags keeps
|
||||
returning -EBUSY quickly, which apparenrly can happen in containers.
|
||||
|
||||
The equivalent 'direct' backend code sleeps for 2 seconds in this case.
|
||||
---
|
||||
lib/launch-libvirt.c | 4 +++-
|
||||
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/lib/launch-libvirt.c b/lib/launch-libvirt.c
|
||||
index 8dbde5341..c690a444a 100644
|
||||
--- a/lib/launch-libvirt.c
|
||||
+++ b/lib/launch-libvirt.c
|
||||
@@ -2181,8 +2181,10 @@ destroy_domain (guestfs_h *g, virDomainPtr dom, int check_for_errors)
|
||||
/* Retry (indefinitely) if we're just waiting for qemu to shut down. See:
|
||||
* https://www.redhat.com/archives/libvir-list/2016-January/msg00767.html
|
||||
*/
|
||||
- if (err && err->code == VIR_ERR_SYSTEM_ERROR && err->int1 == EBUSY)
|
||||
+ if (err && err->code == VIR_ERR_SYSTEM_ERROR && err->int1 == EBUSY) {
|
||||
+ sleep (1);
|
||||
goto again;
|
||||
+ }
|
||||
|
||||
/* "Domain not found" is not treated as an error. */
|
||||
if (err && err->code == VIR_ERR_NO_DOMAIN)
|
||||
--
|
||||
2.47.3
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
From 7a16a0b3580b081abc4880644ed0e34b30670cae Mon Sep 17 00:00:00 2001
|
||||
From 4641910dc6aff98c3451041919dcca62b96e4cb7 Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Tue, 13 May 2025 17:28:25 +0100
|
||||
Subject: [PATCH] RHEL: appliance/init: Run depmod -a to rebuild kernel module
|
||||
@ -1,49 +0,0 @@
|
||||
From f4f84a882468cb7b2dc4c265bdc18a5df79c3d4d Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Wed, 30 Jul 2025 10:53:20 +0100
|
||||
Subject: [PATCH] daemon: Add contents of /etc/fstab to verbose log
|
||||
|
||||
Also some mdadm configuration files. This is useful for debugging.
|
||||
|
||||
The output looks like this:
|
||||
|
||||
info: /etc/fstab in /dev/VG/Root
|
||||
LABEL=BOOT /boot ext2 default 0 0$
|
||||
LABEL=ROOT / ext2 default 0 0$
|
||||
|
||||
Fixes: https://issues.redhat.com/browse/RHEL-106490
|
||||
---
|
||||
daemon/inspect_fs_unix_fstab.ml | 17 +++++++++++++++++
|
||||
1 file changed, 17 insertions(+)
|
||||
|
||||
diff --git a/daemon/inspect_fs_unix_fstab.ml b/daemon/inspect_fs_unix_fstab.ml
|
||||
index 8e765454a..b4652a39d 100644
|
||||
--- a/daemon/inspect_fs_unix_fstab.ml
|
||||
+++ b/daemon/inspect_fs_unix_fstab.ml
|
||||
@@ -43,6 +43,23 @@ let rec check_fstab ?(mdadm_conf = false) (root_mountable : Mountable.t)
|
||||
if mdadm_conf then ["/etc/mdadm.conf"; "/etc/mdadm/mdadm.conf"] else [] in
|
||||
let configfiles = "/etc/fstab" :: mdadmfiles in
|
||||
|
||||
+ (* If verbose, dump the contents of each config file as that can be
|
||||
+ * useful for debugging.
|
||||
+ *)
|
||||
+ if verbose () then (
|
||||
+ List.iter (
|
||||
+ fun filename ->
|
||||
+ let sysroot_filename = Sysroot.sysroot_path filename in
|
||||
+ if Sys.file_exists sysroot_filename then (
|
||||
+ eprintf "info: %s in %s\n%!"
|
||||
+ filename (Mountable.to_string root_mountable);
|
||||
+ let cmd = sprintf "cat -A %s >&2" (quote sysroot_filename) in
|
||||
+ ignore (Sys.command cmd);
|
||||
+ eprintf "\n%!"
|
||||
+ )
|
||||
+ ) configfiles
|
||||
+ );
|
||||
+
|
||||
with_augeas ~name:"check_fstab_aug"
|
||||
configfiles (check_fstab_aug mdadm_conf root_mountable os_type)
|
||||
|
||||
--
|
||||
2.47.3
|
||||
|
||||
@ -1,47 +0,0 @@
|
||||
From 217823da95aad095a1c86a90aa4b1db8d46319e4 Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Wed, 30 Jul 2025 11:05:17 +0100
|
||||
Subject: [PATCH] appliance/init: Add lsblk and blkid output to verbose log
|
||||
|
||||
This is useful for debugging. The output looks like:
|
||||
|
||||
+ lsblk
|
||||
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
|
||||
sda 8:0 0 1G 0 disk
|
||||
|-sda1 8:1 0 512M 0 part
|
||||
`-sda2 8:2 0 512M 0 part
|
||||
|-VG-Root 252:0 0 32M 0 lvm
|
||||
|-VG-LV1 252:1 0 32M 0 lvm
|
||||
|-VG-LV2 252:2 0 32M 0 lvm
|
||||
`-VG-LV3 252:3 0 64M 0 lvm
|
||||
sdb 8:16 0 4G 0 disk /
|
||||
+ blkid
|
||||
/dev/mapper/VG-LV1: UUID="cc8a3437-4169-4b1c-b432-ee8adc563f6d" BLOCK_SIZE="4096" TYPE="ext2"
|
||||
/dev/sdb: UUID="30c70ddc-d00b-4620-a408-025890e59aa6" BLOCK_SIZE="4096" TYPE="ext2"
|
||||
/dev/mapper/VG-LV2: UUID="747009aa-e183-46ba-a034-0c437b15cebc" BLOCK_SIZE="1024" TYPE="ext2"
|
||||
/dev/mapper/VG-Root: LABEL="ROOT" UUID="01234567-0123-0123-0123-012345678902" BLOCK_SIZE="4096" TYPE="ext2"
|
||||
/dev/sda2: UUID="DfEjc1-wRU6-vh8U-we7U-ivEl-FRwo-rG0ZuL" TYPE="LVM2_member" PARTUUID="184cbb43-02"
|
||||
/dev/sda1: LABEL="BOOT" UUID="01234567-0123-0123-0123-012345678901" BLOCK_SIZE="4096" TYPE="ext2" PARTUUID="184cbb43-01"
|
||||
/dev/mapper/VG-LV3: UUID="f9e5dc21-9a2a-45a0-85b0-e2889607139a" BLOCK_SIZE="2048" TYPE="ext2"
|
||||
|
||||
Fixes: https://issues.redhat.com/browse/RHEL-106490
|
||||
---
|
||||
appliance/init | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/appliance/init b/appliance/init
|
||||
index 47eb97dfc..62526ac77 100755
|
||||
--- a/appliance/init
|
||||
+++ b/appliance/init
|
||||
@@ -184,6 +184,8 @@ if test "$guestfs_verbose" = 1 && test "$guestfs_boot_analysis" != 1; then
|
||||
ls -lR /dev
|
||||
cat /proc/mounts
|
||||
cat /proc/mdstat
|
||||
+ lsblk
|
||||
+ blkid
|
||||
lvm config
|
||||
lvm pvs
|
||||
lvm vgs
|
||||
--
|
||||
2.47.3
|
||||
|
||||
@ -0,0 +1,47 @@
|
||||
From d448d69171b5c1ee14a4eca5dc4964840ba99507 Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Mon, 26 Jan 2026 14:30:46 +0000
|
||||
Subject: [PATCH] lib/qemu.c: Use machine type none when inspecting QMP
|
||||
properties
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Dan mentioned that there is a special machine type ("none") we can use
|
||||
when querying for KVM. It has no CPU, memory, etc and does not run,
|
||||
but you can still enable KVM for it.
|
||||
|
||||
Note we have to remove the -cpu parameter, otherwise qemu prints this
|
||||
error:
|
||||
|
||||
qemu-kvm: apic-id property was not initialized properly
|
||||
|
||||
Updates: commit 5da8102f5f59b9781075440dc68c8d08f9c8691e
|
||||
Suggested-by: Daniel P. Berrangé <berrange@redhat.com>
|
||||
(cherry picked from commit f7a24b2ea81f3c5c2754fcf43e0347c7c5378b4a)
|
||||
---
|
||||
lib/qemu.c | 8 +-------
|
||||
1 file changed, 1 insertion(+), 7 deletions(-)
|
||||
|
||||
diff --git a/lib/qemu.c b/lib/qemu.c
|
||||
index 19b5aa336..9edbe8208 100644
|
||||
--- a/lib/qemu.c
|
||||
+++ b/lib/qemu.c
|
||||
@@ -81,13 +81,7 @@ generic_qmp_test (guestfs_h *g, const char *qmp_command, char **outp)
|
||||
guestfs_int_cmd_add_string_unquoted (cmd, "QEMU_AUDIO_DRV=none ");
|
||||
guestfs_int_cmd_add_string_quoted (cmd, g->hv);
|
||||
guestfs_int_cmd_add_string_unquoted (cmd, " -display none");
|
||||
- guestfs_int_cmd_add_string_unquoted (cmd, " -cpu max");
|
||||
- guestfs_int_cmd_add_string_unquoted (cmd, " -machine ");
|
||||
- guestfs_int_cmd_add_string_quoted (cmd,
|
||||
-#ifdef MACHINE_TYPE
|
||||
- MACHINE_TYPE ","
|
||||
-#endif
|
||||
- "accel=kvm:hvf:tcg");
|
||||
+ guestfs_int_cmd_add_string_unquoted (cmd, " -machine none,accel=kvm:hvf:tcg");
|
||||
guestfs_int_cmd_add_string_unquoted (cmd, " -qmp stdio");
|
||||
guestfs_int_cmd_add_string_unquoted (cmd, " -S");
|
||||
guestfs_int_cmd_clear_capture_errors (cmd);
|
||||
--
|
||||
2.47.3
|
||||
|
||||
@ -1,50 +0,0 @@
|
||||
From 701667b6f581a824059c4da50eb4df176decbb82 Mon Sep 17 00:00:00 2001
|
||||
From: Cole Robinson <crobinso@redhat.com>
|
||||
Date: Thu, 31 Jul 2025 15:27:38 -0400
|
||||
Subject: [PATCH] docs: Fix dead ntfs-3g doc links
|
||||
|
||||
---
|
||||
generator/actions_core.ml | 4 ++--
|
||||
lib/guestfs.pod | 4 ++--
|
||||
2 files changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/generator/actions_core.ml b/generator/actions_core.ml
|
||||
index 0f39fd509..108494ece 100644
|
||||
--- a/generator/actions_core.ml
|
||||
+++ b/generator/actions_core.ml
|
||||
@@ -4661,8 +4661,8 @@ as F<C:\\windows> may appear as F</WINDOWS> or F</windows>
|
||||
they were created. In Windows itself this would not be
|
||||
a problem.
|
||||
|
||||
-Bug or feature? You decide:
|
||||
-L<https://www.tuxera.com/community/ntfs-3g-faq/#posixfilenames1>
|
||||
+Bug or feature? You decide. See the relevant entry in the ntfs-3g FAQ:
|
||||
+L<https://github.com/tuxera/ntfs-3g/wiki/NTFS-3G-FAQ>
|
||||
|
||||
C<guestfs_case_sensitive_path> attempts to resolve the true case of
|
||||
each element in the path. It will return a resolved path if either the
|
||||
diff --git a/lib/guestfs.pod b/lib/guestfs.pod
|
||||
index f69d5a070..505978aa1 100644
|
||||
--- a/lib/guestfs.pod
|
||||
+++ b/lib/guestfs.pod
|
||||
@@ -984,7 +984,7 @@ Ntfs-3g tries to rewrite "Junction Points" and NTFS "symbolic links"
|
||||
to provide something which looks like a Linux symlink. The way it
|
||||
tries to do the rewriting is described here:
|
||||
|
||||
-L<http://www.tuxera.com/community/ntfs-3g-advanced/junction-points-and-symbolic-links/>
|
||||
+L<https://github.com/tuxera/ntfs-3g/wiki/Junctions-Points,-Symbolic-Links-and-Reparse-Points>
|
||||
|
||||
The essential problem is that ntfs-3g simply does not have enough
|
||||
information to do a correct job. NTFS links can contain drive letters
|
||||
@@ -1003,7 +1003,7 @@ format documented in various places around the web).
|
||||
There are other useful extended attributes that can be read from
|
||||
ntfs-3g filesystems (using L</guestfs_getxattr>). See:
|
||||
|
||||
-L<http://www.tuxera.com/community/ntfs-3g-advanced/extended-attributes/>
|
||||
+L<https://github.com/tuxera/ntfs-3g/wiki/Using-Extended-Attributes>
|
||||
|
||||
=head3 WINDOWS HIBERNATION AND WINDOWS 8 FAST STARTUP
|
||||
|
||||
--
|
||||
2.47.3
|
||||
|
||||
33
0006-generator-Fix-description-of-xfs_growfs.patch
Normal file
33
0006-generator-Fix-description-of-xfs_growfs.patch
Normal file
@ -0,0 +1,33 @@
|
||||
From 43d8a4970bbd908ed4b583335f1f4f42a3f6f354 Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Fri, 23 Jan 2026 08:47:42 +0000
|
||||
Subject: [PATCH] generator: Fix description of xfs_growfs
|
||||
|
||||
This function does not return "geometry information". Remove
|
||||
the bogus description.
|
||||
|
||||
(cherry picked from commit 6166304be685b2fafb8cc968a4558a906bb0609b)
|
||||
---
|
||||
generator/actions_core.ml | 6 +-----
|
||||
1 file changed, 1 insertion(+), 5 deletions(-)
|
||||
|
||||
diff --git a/generator/actions_core.ml b/generator/actions_core.ml
|
||||
index 9c23da008..de95bdaf0 100644
|
||||
--- a/generator/actions_core.ml
|
||||
+++ b/generator/actions_core.ml
|
||||
@@ -7332,11 +7332,7 @@ in the returned structure is defined by the API." };
|
||||
["xfs_info"; "/"]], "ret->xfs_blocksize == 4096"), [];
|
||||
];
|
||||
shortdesc = "expand an existing XFS filesystem";
|
||||
- longdesc = {|Grow the XFS filesystem mounted at C<path>.
|
||||
-
|
||||
-The returned struct contains geometry information. Missing
|
||||
-fields are returned as C<-1> (for numeric fields) or empty
|
||||
-string.|} };
|
||||
+ longdesc = {|Grow the XFS filesystem mounted at C<path>.|} };
|
||||
|
||||
{ defaults with
|
||||
name = "rsync"; added = (1, 19, 29);
|
||||
--
|
||||
2.47.3
|
||||
|
||||
@ -1,178 +0,0 @@
|
||||
From 06db19c56c0a4e81596b24a7ab74ed545b422e4c Mon Sep 17 00:00:00 2001
|
||||
From: Cole Robinson <crobinso@redhat.com>
|
||||
Date: Thu, 12 Jun 2025 14:42:33 -0400
|
||||
Subject: [PATCH] daemon: inspect: check /etc/crypttab for /dev/mapper/*
|
||||
|
||||
Encrypted root fs on SUSE distros will present itself like so:
|
||||
|
||||
```
|
||||
/dev/mapper/cr_root / btrfs defaults 0 0
|
||||
UUID=588905f9-bfa4-47b5-9fe8-893cb8ad4a0b /var btrfs subvol=/@/var 0 0
|
||||
... more subvols here ...
|
||||
UUID=8a278363-3042-4dea-a878-592f5e1b7381 swap btrfs defaults 0 0
|
||||
/dev/mapper/cr_root /.snapshots btrfs subvol=/@/.snapshots 0 0
|
||||
|
||||
cr_root UUID=5289379a-a707-41b5-994c-c383f7ed54cc none x-initrd.attach
|
||||
```
|
||||
|
||||
This breaks `-i` inspection, since libguestfs doesn't know what
|
||||
/dev/mapper/cr_root is supposed to be, and nothing in the appliance
|
||||
will autopopulate that path. This isn't a problem on Fedora, where
|
||||
it uses UUID= instead of a /dev/mapper path.
|
||||
|
||||
Currently when we see /dev/mapper as a mount prefix, we only attempt
|
||||
to do some LVM name mapping. This extends libguestfs to check
|
||||
/etc/crypttab first. If we find an entry for the mapper path, and it
|
||||
points to the encrypted luks UUID, we use that UUID to build the
|
||||
associated /dev/disk/by-id/dm-uuid-CRYPT-* path, which is a symlink
|
||||
to the unencrypted /dev/dm-X path
|
||||
|
||||
Resolves: https://issues.redhat.com/browse/RHEL-93584
|
||||
|
||||
Signed-off-by: Cole Robinson <crobinso@redhat.com>
|
||||
---
|
||||
daemon/inspect_fs_unix_fstab.ml | 93 +++++++++++++++++++++++++--------
|
||||
1 file changed, 70 insertions(+), 23 deletions(-)
|
||||
|
||||
diff --git a/daemon/inspect_fs_unix_fstab.ml b/daemon/inspect_fs_unix_fstab.ml
|
||||
index b4652a39d..bd1b8e540 100644
|
||||
--- a/daemon/inspect_fs_unix_fstab.ml
|
||||
+++ b/daemon/inspect_fs_unix_fstab.ml
|
||||
@@ -41,7 +41,7 @@ let rec check_fstab ?(mdadm_conf = false) (root_mountable : Mountable.t)
|
||||
os_type =
|
||||
let mdadmfiles =
|
||||
if mdadm_conf then ["/etc/mdadm.conf"; "/etc/mdadm/mdadm.conf"] else [] in
|
||||
- let configfiles = "/etc/fstab" :: mdadmfiles in
|
||||
+ let configfiles = "/etc/fstab" :: "/etc/crypttab" :: mdadmfiles in
|
||||
|
||||
(* If verbose, dump the contents of each config file as that can be
|
||||
* useful for debugging.
|
||||
@@ -179,7 +179,7 @@ and check_fstab_entry md_map root_mountable os_type aug entry =
|
||||
root_mountable
|
||||
(* Resolve guest block device names. *)
|
||||
else if String.starts_with "/dev/" spec then
|
||||
- resolve_fstab_device spec md_map os_type
|
||||
+ resolve_fstab_device spec md_map os_type aug
|
||||
(* In OpenBSD's fstab you can specify partitions
|
||||
* on a disk by appending a period and a partition
|
||||
* letter to a Disklable Unique Identifier. The
|
||||
@@ -194,7 +194,7 @@ and check_fstab_entry md_map root_mountable os_type aug entry =
|
||||
* assume that this is the first disk.
|
||||
*)
|
||||
let device = sprintf "/dev/sd0%c" part in
|
||||
- resolve_fstab_device device md_map os_type
|
||||
+ resolve_fstab_device device md_map os_type aug
|
||||
)
|
||||
(* Ignore "/.swap" (Pardus) and pseudo-devices
|
||||
* like "tmpfs". If we haven't resolved the device
|
||||
@@ -353,7 +353,7 @@ and parse_md_uuid uuid =
|
||||
* the real VM, which is a reasonable assumption to make. Return
|
||||
* anything we don't recognize unchanged.
|
||||
*)
|
||||
-and resolve_fstab_device spec md_map os_type =
|
||||
+and resolve_fstab_device spec md_map os_type aug =
|
||||
(* In any case where we didn't match a device pattern or there was
|
||||
* another problem, return this default mountable derived from [spec].
|
||||
*)
|
||||
@@ -366,7 +366,7 @@ and resolve_fstab_device spec md_map os_type =
|
||||
|
||||
if String.starts_with "/dev/mapper" spec then (
|
||||
debug_matching "/dev/mapper";
|
||||
- resolve_dev_mapper spec default
|
||||
+ resolve_dev_mapper spec default aug
|
||||
)
|
||||
|
||||
else if PCRE.matches re_xdev spec then (
|
||||
@@ -540,24 +540,71 @@ and resolve_fstab_device spec md_map os_type =
|
||||
default
|
||||
)
|
||||
|
||||
-and resolve_dev_mapper spec default =
|
||||
- (* LVM2 does some strange munging on /dev/mapper paths for VGs and
|
||||
- * LVs which contain '-' character:
|
||||
- *
|
||||
- * ><fs> lvcreate LV--test VG--test 32
|
||||
- * ><fs> debug ls /dev/mapper
|
||||
- * VG----test-LV----test
|
||||
- *
|
||||
- * This makes it impossible to reverse those paths directly, so
|
||||
- * we have implemented lvm_canonical_lv_name in the daemon.
|
||||
- *)
|
||||
- try
|
||||
- match Lvm_utils.lv_canonical spec with
|
||||
- | None -> default
|
||||
- | Some device -> Mountable.of_device device
|
||||
- with
|
||||
- (* Ignore devices that don't exist. (RHBZ#811872) *)
|
||||
- | Unix.Unix_error (Unix.ENOENT, _, _) -> default
|
||||
+and resolve_dev_mapper spec default aug =
|
||||
+ let augpath =
|
||||
+ sprintf "/files/etc/crypttab/*[target='%s']/device"
|
||||
+ (Filename.basename spec) in
|
||||
+ match aug_get_noerrors aug augpath with
|
||||
+ | Some device ->
|
||||
+ (* /dev/mapper name is present in /etc/crypttab *)
|
||||
+ if verbose() then eprintf "mapped to crypttab device=%s\n%!" device;
|
||||
+ (* device string is one of:
|
||||
+ * + UUID=... without any shell quoting
|
||||
+ * + An absolute path
|
||||
+ *)
|
||||
+ if String.starts_with "UUID=" device then (
|
||||
+ (* We found the UUID for the encrypted LUKS partition, now we use
|
||||
+ * that to get the unencrypted /dev/dm-X via
|
||||
+ * /dev/disk/by-id/dm-uuid-CRYPT-* automagic paths. The format is
|
||||
+ *
|
||||
+ * /dev/disk/by-id/dm-uuid-CRYPT-$TYPE-$LUKSUUID-$DMNAME
|
||||
+ *
|
||||
+ * The fields are
|
||||
+ * + $TYPE: `LUKS1` or `LUKS2`
|
||||
+ * + $LUKSUUID: The UUID we got from crypttab, but with `-` removed
|
||||
+ * + $DMNAME: this would be `cr_root` for `/dev/mapper/cr_root`, but
|
||||
+ * we just ignore that.
|
||||
+ *)
|
||||
+ let byid_dir = "/dev/disk/by-id" in
|
||||
+ let uuid = String.sub device 5 (String.length device - 5) in
|
||||
+ let short_uuid = String.replace uuid "-" "" in
|
||||
+ let regstr = sprintf "^dm-uuid-CRYPT-LUKS.-%s-.*$" short_uuid in
|
||||
+ let re_dmcrypt = PCRE.compile regstr in
|
||||
+ let entries = Sys.readdir byid_dir |> Array.to_list in
|
||||
+ try
|
||||
+ let filename = List.find (fun f -> PCRE.matches re_dmcrypt f) entries in
|
||||
+ let fullpath = Filename.concat byid_dir filename in
|
||||
+ let resolved_path = Unix_utils.Realpath.realpath fullpath in
|
||||
+ eprintf("Found crypttab mapping %s -> %s\n%!") fullpath resolved_path;
|
||||
+ Mountable.of_device (resolved_path)
|
||||
+ with
|
||||
+ Failure _ | Not_found ->
|
||||
+ eprintf("Failed to find matching regex %s/%s\n%!") byid_dir regstr;
|
||||
+ Mountable.of_device spec
|
||||
+ ) else (
|
||||
+ Mountable.of_device spec
|
||||
+ )
|
||||
+ | None ->
|
||||
+ (* Assume /dev/mapper device is LVM *)
|
||||
+
|
||||
+ (* LVM2 does some strange munging on /dev/mapper paths for VGs and
|
||||
+ * LVs which contain '-' character:
|
||||
+ *
|
||||
+ * ><fs> lvcreate LV--test VG--test 32
|
||||
+ * ><fs> debug ls /dev/mapper
|
||||
+ * VG----test-LV----test
|
||||
+ *
|
||||
+ * This makes it impossible to reverse those paths directly, so
|
||||
+ * we have implemented lvm_canonical_lv_name in the daemon.
|
||||
+ *)
|
||||
+ try
|
||||
+ match Lvm_utils.lv_canonical spec with
|
||||
+ | None -> default
|
||||
+ | Some device -> Mountable.of_device device
|
||||
+ with
|
||||
+ (* Ignore devices that don't exist. (RHBZ#811872) *)
|
||||
+ | Unix.Unix_error (Unix.ENOENT, _, _) -> default
|
||||
+
|
||||
|
||||
(* type: (h|s|v|xv)
|
||||
* disk: [a-z]+
|
||||
--
|
||||
2.47.3
|
||||
|
||||
36
0007-generator-Fix-description-of-xfs_info.patch
Normal file
36
0007-generator-Fix-description-of-xfs_info.patch
Normal file
@ -0,0 +1,36 @@
|
||||
From d5daad98cfe254c14f4f4f12348f1589838c36a8 Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Fri, 23 Jan 2026 08:49:14 +0000
|
||||
Subject: [PATCH] generator: Fix description of xfs_info
|
||||
|
||||
The returned struct contains filesystem metadata, not "geometry
|
||||
information" (whatever that means).
|
||||
|
||||
(cherry picked from commit 1c9c03bcd40ede11e7f4ece44dab908dcd36a657)
|
||||
---
|
||||
generator/actions_core.ml | 7 ++++---
|
||||
1 file changed, 4 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/generator/actions_core.ml b/generator/actions_core.ml
|
||||
index de95bdaf0..b57cf56b0 100644
|
||||
--- a/generator/actions_core.ml
|
||||
+++ b/generator/actions_core.ml
|
||||
@@ -7236,11 +7236,12 @@ call C<guestfs_max_disks>.|} };
|
||||
["mount"; "/dev/sda1"; "/"];
|
||||
["xfs_info"; "/"]], "ret->xfs_blocksize == 4096"), []
|
||||
];
|
||||
- shortdesc = "get geometry of XFS filesystem";
|
||||
+ shortdesc = "get information about the XFS filesystem";
|
||||
longdesc = {|C<pathordevice> is a mounted XFS filesystem or a device containing
|
||||
-an XFS filesystem. This command returns the geometry of the filesystem.
|
||||
+an XFS filesystem. This command returns miscellaneous
|
||||
+metadata about the XFS filesystem.
|
||||
|
||||
-The returned struct contains geometry information. Missing
|
||||
+The returned struct contains miscellaneous metadata. Missing
|
||||
fields are returned as C<-1> (for numeric fields) or empty
|
||||
string.|} };
|
||||
|
||||
--
|
||||
2.47.3
|
||||
|
||||
351
0008-New-API-xfs_info2.patch
Normal file
351
0008-New-API-xfs_info2.patch
Normal file
@ -0,0 +1,351 @@
|
||||
From aac2ec68202f2913ae6000aa117a8ed5dffbd6bb Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Fri, 23 Jan 2026 08:58:07 +0000
|
||||
Subject: [PATCH] New API: xfs_info2
|
||||
|
||||
Reimplement xfs_info by returning a hash table of values (rather than
|
||||
a limited struct), and by writing it in OCaml with PCRE which makes
|
||||
string parsing a lot simpler. This will now flexibly return all the
|
||||
fields from the underlying xfs_info command, even (hopefully) future
|
||||
fields.
|
||||
|
||||
Note the field values are returned as strings, because the actual
|
||||
fields in xfs_info output are fairly random and free-form. There is a
|
||||
trade off here between returning as much information as we can, and
|
||||
requiring the user to do a bit of (simple) field parsing.
|
||||
|
||||
Fixes: https://issues.redhat.com/browse/RHEL-143673
|
||||
(cherry picked from commit dfd2700616dee92d75e91936fb56b5de0450f992)
|
||||
---
|
||||
.gitignore | 1 +
|
||||
common | 2 +-
|
||||
daemon/Makefile.am | 7 ++-
|
||||
daemon/xfs.ml | 128 ++++++++++++++++++++++++++++++++++++++
|
||||
generator/actions_core.ml | 35 +++++++++++
|
||||
generator/proc_nr.ml | 1 +
|
||||
lib/MAX_PROC_NR | 2 +-
|
||||
7 files changed, 172 insertions(+), 4 deletions(-)
|
||||
create mode 100644 daemon/xfs.ml
|
||||
|
||||
diff --git a/.gitignore b/.gitignore
|
||||
index 02160caff..c8a8312fa 100644
|
||||
--- a/.gitignore
|
||||
+++ b/.gitignore
|
||||
@@ -119,6 +119,7 @@ Makefile.in
|
||||
/daemon/stubs-?.c
|
||||
/daemon/stubs.h
|
||||
/daemon/types.ml
|
||||
+/daemon/xfs.mli
|
||||
/depcomp
|
||||
/docs/guestfs-building.1
|
||||
/docs/guestfs-faq.1
|
||||
Submodule common b54ba2031..3ac5d1841:
|
||||
diff --git a/common/mlpcre/PCRE.ml b/common/mlpcre/PCRE.ml
|
||||
index 077290e..33074af 100644
|
||||
--- a/common/mlpcre/PCRE.ml
|
||||
+++ b/common/mlpcre/PCRE.ml
|
||||
@@ -22,7 +22,7 @@ exception Error of string * int
|
||||
|
||||
type regexp
|
||||
|
||||
-external compile : ?caseless:bool -> ?dotall:bool -> ?extended:bool -> ?multiline:bool -> string -> regexp = "guestfs_int_pcre_compile"
|
||||
+external compile : ?anchored:bool -> ?caseless:bool -> ?dotall:bool -> ?extended:bool -> ?multiline:bool -> string -> regexp = "guestfs_int_pcre_compile_byte" "guestfs_int_pcre_compile"
|
||||
external matches : ?offset:int -> regexp -> string -> bool = "guestfs_int_pcre_matches"
|
||||
external sub : int -> string = "guestfs_int_pcre_sub"
|
||||
external subi : int -> int * int = "guestfs_int_pcre_subi"
|
||||
diff --git a/common/mlpcre/PCRE.mli b/common/mlpcre/PCRE.mli
|
||||
index b69a56b..0fdc2bd 100644
|
||||
--- a/common/mlpcre/PCRE.mli
|
||||
+++ b/common/mlpcre/PCRE.mli
|
||||
@@ -52,11 +52,12 @@ exception Error of string * int
|
||||
type regexp
|
||||
(** The type of a compiled regular expression. *)
|
||||
|
||||
-val compile : ?caseless:bool -> ?dotall:bool -> ?extended:bool -> ?multiline:bool -> string -> regexp
|
||||
+val compile : ?anchored:bool -> ?caseless:bool -> ?dotall:bool ->
|
||||
+ ?extended:bool -> ?multiline:bool -> string -> regexp
|
||||
(** Compile a regular expression. This can raise {!Error}.
|
||||
|
||||
- The flags [?caseless], [?dotall], [?extended], [?multiline]
|
||||
- correspond to the [pcre_compile] flags [PCRE_CASELESS] etc.
|
||||
+ The flags [?anchored], [?caseless], [?dotall], [?extended], [?multiline]
|
||||
+ correspond to the [pcre_compile] flags [PCRE_ANCHORED] etc.
|
||||
See pcre2api(3) for details of what they do.
|
||||
All flags default to false. *)
|
||||
|
||||
diff --git a/common/mlpcre/pcre-c.c b/common/mlpcre/pcre-c.c
|
||||
index 3959fd5..11be157 100644
|
||||
--- a/common/mlpcre/pcre-c.c
|
||||
+++ b/common/mlpcre/pcre-c.c
|
||||
@@ -154,11 +154,12 @@ Optint_val (value intv, int defval)
|
||||
}
|
||||
|
||||
value
|
||||
-guestfs_int_pcre_compile (value caselessv, value dotallv,
|
||||
- value extendedv, value multilinev,
|
||||
+guestfs_int_pcre_compile (value anchoredv, value caselessv,
|
||||
+ value dotallv, value extendedv,
|
||||
+ value multilinev,
|
||||
value pattv)
|
||||
{
|
||||
- CAMLparam4 (caselessv, dotallv, extendedv, multilinev);
|
||||
+ CAMLparam5 (anchoredv, caselessv, dotallv, extendedv, multilinev);
|
||||
CAMLxparam1 (pattv);
|
||||
const char *patt;
|
||||
int options = 0;
|
||||
@@ -167,6 +168,8 @@ guestfs_int_pcre_compile (value caselessv, value dotallv,
|
||||
PCRE2_SIZE errnum;
|
||||
|
||||
/* Flag parameters are all ‘bool option’, defaulting to false. */
|
||||
+ if (is_Some_true (anchoredv))
|
||||
+ options |= PCRE2_ANCHORED;
|
||||
if (is_Some_true (caselessv))
|
||||
options |= PCRE2_CASELESS;
|
||||
if (is_Some_true (dotallv))
|
||||
@@ -186,6 +189,14 @@ guestfs_int_pcre_compile (value caselessv, value dotallv,
|
||||
CAMLreturn (Val_regexp (re));
|
||||
}
|
||||
|
||||
+value
|
||||
+guestfs_int_pcre_compile_byte (value *argv, int argn)
|
||||
+{
|
||||
+ assert (argn == 6);
|
||||
+ return guestfs_int_pcre_compile (argv[0], argv[1], argv[2],
|
||||
+ argv[3], argv[4], argv[5]);
|
||||
+}
|
||||
+
|
||||
value
|
||||
guestfs_int_pcre_matches (value offsetv, value rev, value strv)
|
||||
{
|
||||
diff --git a/daemon/Makefile.am b/daemon/Makefile.am
|
||||
index c644d9881..d4a805046 100644
|
||||
--- a/daemon/Makefile.am
|
||||
+++ b/daemon/Makefile.am
|
||||
@@ -63,7 +63,8 @@ generator_built = \
|
||||
sfdisk.mli \
|
||||
statvfs.mli \
|
||||
structs.ml \
|
||||
- structs.mli
|
||||
+ structs.mli \
|
||||
+ xfs.mli
|
||||
|
||||
CONFIGURE_GENERATED_ML = \
|
||||
daemon_config.ml
|
||||
@@ -312,7 +313,8 @@ SOURCES_MLI = \
|
||||
statvfs.mli \
|
||||
structs.mli \
|
||||
sysroot.mli \
|
||||
- utils.mli
|
||||
+ utils.mli \
|
||||
+ xfs.mli
|
||||
|
||||
SOURCES_ML = \
|
||||
$(CONFIGURE_GENERATED_ML) \
|
||||
@@ -347,6 +349,7 @@ SOURCES_ML = \
|
||||
realpath.ml \
|
||||
statvfs.ml \
|
||||
selinux.ml \
|
||||
+ xfs.ml \
|
||||
inspect_types.ml \
|
||||
inspect_utils.ml \
|
||||
inspect_fs_unix_fstab.ml \
|
||||
diff --git a/daemon/xfs.ml b/daemon/xfs.ml
|
||||
new file mode 100644
|
||||
index 000000000..142b26775
|
||||
--- /dev/null
|
||||
+++ b/daemon/xfs.ml
|
||||
@@ -0,0 +1,128 @@
|
||||
+(* guestfs-inspection
|
||||
+ * Copyright (C) 2009-2025 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.
|
||||
+ *)
|
||||
+
|
||||
+open Printf
|
||||
+
|
||||
+open Std_utils
|
||||
+
|
||||
+open Utils
|
||||
+
|
||||
+(* The output is horrific ...
|
||||
+
|
||||
+meta-data=/dev/sda1 isize=512 agcount=4, agsize=122094659 blks
|
||||
+ = sectsz=4096 attr=2, projid32bit=1
|
||||
+ = crc=1 finobt=1, sparse=1, rmapbt=0
|
||||
+ = reflink=1 bigtime=1 inobtcount=1 nrext64=0
|
||||
+ = exchange=0 metadir=0
|
||||
+data = bsize=4096 blocks=488378636, imaxpct=5
|
||||
+ = sunit=0 swidth=0 blks
|
||||
+naming =version 2 bsize=4096 ascii-ci=0, ftype=1, parent=0
|
||||
+log =internal log bsize=4096 blocks=238466, version=2
|
||||
+ = sectsz=4096 sunit=1 blks, lazy-count=1
|
||||
+realtime =none extsz=4096 blocks=0, rtextents=0
|
||||
+ = rgcount=0 rgsize=0 extents
|
||||
+ = zoned=0 start=0 reserved=0
|
||||
+
|
||||
+^heading ^"stuff" ^ data fields vaguely related to heading
|
||||
+
|
||||
+Note also the inconsistent use of commas.
|
||||
+*)
|
||||
+
|
||||
+(* Split into groups using a positive lookahead assertion. *)
|
||||
+let re1 = PCRE.compile ~extended:true {| \n (?=[a-z]) |}
|
||||
+
|
||||
+(* Separate group heading and the rest. *)
|
||||
+let re2 = PCRE.compile ~extended:true {| = |}
|
||||
+
|
||||
+(* Match the first field in a group (if present). *)
|
||||
+let re3 = PCRE.compile ~anchored:true ~extended:true {|
|
||||
+ (version\s\d+|\S+\slog|\S+).*
|
||||
+|}
|
||||
+
|
||||
+(* Match next field=value in group. *)
|
||||
+let re4 = PCRE.compile ~extended:true {|
|
||||
+ ([-\w]+)=(\d+(\s(blks|extents))?)
|
||||
+|}
|
||||
+
|
||||
+let xfs_info2 dev =
|
||||
+ (* Uncomment the first line to enable extra debugging. *)
|
||||
+ (*let extra_debug = verbose () in*)
|
||||
+ let extra_debug = false in
|
||||
+
|
||||
+ let is_dev = is_device_parameter dev in
|
||||
+ let arg = if is_dev then dev else Sysroot.sysroot_path dev in
|
||||
+ let out = command "xfs_info" [arg] in
|
||||
+
|
||||
+ (* Split the output by heading. *)
|
||||
+ let groups = PCRE.nsplit re1 out in
|
||||
+ let groups = List.map (PCRE.split re2) groups in
|
||||
+ let groups = List.map (fun (name, rest) -> String.trim name, rest) groups in
|
||||
+
|
||||
+ if extra_debug then (
|
||||
+ List.iteri (
|
||||
+ fun i (name, rest) ->
|
||||
+ eprintf "xfs_info2: group %d: %S: %S\n%!" i name rest
|
||||
+ ) groups
|
||||
+ );
|
||||
+
|
||||
+ (* Parse each group into the final list of values. *)
|
||||
+ let values = ref [] in
|
||||
+ List.iter (
|
||||
+ fun (group_name, rest) ->
|
||||
+ let len = String.length rest in
|
||||
+
|
||||
+ (* If there is some string at the beginning of the
|
||||
+ * group then we create a (group_name, string) value,
|
||||
+ * eg. ("meta-data", "/dev/sda1")
|
||||
+ *)
|
||||
+ let start =
|
||||
+ if PCRE.matches re3 rest then (
|
||||
+ let value = PCRE.sub 1 in
|
||||
+ List.push_front (group_name, value) values;
|
||||
+ (* Start parsing after this. *)
|
||||
+ String.length value
|
||||
+ )
|
||||
+ else 0 in
|
||||
+
|
||||
+ let rec loop i =
|
||||
+ if extra_debug then
|
||||
+ eprintf "xfs_info2: parsing group %S from %d\n%!" group_name i;
|
||||
+ if i <= len && PCRE.matches ~offset:i re4 rest then (
|
||||
+ let field_name = PCRE.sub 1 in
|
||||
+ if extra_debug then eprintf "xfs_info2: sub1=%S\n%!" field_name;
|
||||
+ let value = PCRE.sub 2 in
|
||||
+ if extra_debug then eprintf "xfs_info2: sub2=%S\n%!" value;
|
||||
+ let name = sprintf "%s.%s" group_name field_name in
|
||||
+ List.push_front (name, value) values;
|
||||
+
|
||||
+ (* Next time round the loop, start parsing after the
|
||||
+ * current matched subexpression.
|
||||
+ *)
|
||||
+ loop (snd (PCRE.subi 2) + 1)
|
||||
+ )
|
||||
+ in
|
||||
+ (try
|
||||
+ loop start
|
||||
+ with
|
||||
+ Not_found ->
|
||||
+ failwithf "xfs_info2: internal error: unexpected Not_found exception. Enable debug and send the full output in a bug report."
|
||||
+ );
|
||||
+
|
||||
+ ) groups;
|
||||
+
|
||||
+ List.rev !values
|
||||
diff --git a/generator/actions_core.ml b/generator/actions_core.ml
|
||||
index b57cf56b0..b7e4dae45 100644
|
||||
--- a/generator/actions_core.ml
|
||||
+++ b/generator/actions_core.ml
|
||||
@@ -9575,4 +9575,39 @@ The optional C<force> boolean controls whether the context
|
||||
is reset for customizable files, and also whether the
|
||||
user, role and range parts of the file context is changed.|} };
|
||||
|
||||
+ { defaults with
|
||||
+ name = "xfs_info2"; added = (1, 59, 2);
|
||||
+ style = RHashtable (RPlainString, RPlainString, "info"), [String (Dev_or_Path, "pathordevice")], [];
|
||||
+ impl = OCaml "Xfs.xfs_info2";
|
||||
+ optional = Some "xfs";
|
||||
+ tests = [
|
||||
+ InitEmpty, Always, TestResult (
|
||||
+ [["part_disk"; "/dev/sda"; "mbr"];
|
||||
+ ["mkfs"; "xfs"; "/dev/sda1"; ""; "NOARG"; ""; ""; "NOARG"];
|
||||
+ ["mount"; "/dev/sda1"; "/"];
|
||||
+ ["xfs_info2"; "/"]],
|
||||
+ "check_hash (ret, \"data.bsize\", \"4096\") == 0"), []
|
||||
+ ];
|
||||
+ shortdesc = "get information about the XFS filesystem";
|
||||
+ longdesc = {|C<pathordevice> is a mounted XFS filesystem or
|
||||
+a device containing an XFS filesystem. This command returns
|
||||
+miscellaneous metadata about the XFS filesystem.
|
||||
+
|
||||
+The output is a hash derived from the output of L<xfs_info(8)>,
|
||||
+and generally looks like:
|
||||
+
|
||||
+ meta-data: /dev/sda1
|
||||
+ meta-data.isize: 512
|
||||
+ meta-data.agcount: 4
|
||||
+ meta-data.agsize: 65528 blks
|
||||
+ meta-data.sectsz: 512
|
||||
+ meta-data.attr: 2
|
||||
+ meta-data.projid32bit: 1
|
||||
+ meta-data.crc: 1
|
||||
+ [...]
|
||||
+ data.bsize: 4096
|
||||
+ data.blocks: 262112
|
||||
+ [...]
|
||||
+
|
||||
+More information can be found by reading L<xfs_info(8)>.|} };
|
||||
]
|
||||
diff --git a/generator/proc_nr.ml b/generator/proc_nr.ml
|
||||
index 11e7b9d1b..b22d88b58 100644
|
||||
--- a/generator/proc_nr.ml
|
||||
+++ b/generator/proc_nr.ml
|
||||
@@ -524,6 +524,7 @@ let proc_nr = [
|
||||
519, "setfiles";
|
||||
520, "ntfs_chmod";
|
||||
521, "inspect_get_windows_group_policy";
|
||||
+522, "xfs_info2";
|
||||
]
|
||||
|
||||
(* End of list. If adding a new entry, add it at the end of the list
|
||||
diff --git a/lib/MAX_PROC_NR b/lib/MAX_PROC_NR
|
||||
index 5a232f264..ec0e415d0 100644
|
||||
--- a/lib/MAX_PROC_NR
|
||||
+++ b/lib/MAX_PROC_NR
|
||||
@@ -1 +1 @@
|
||||
-521
|
||||
+522
|
||||
--
|
||||
2.47.3
|
||||
|
||||
@ -1,42 +0,0 @@
|
||||
From 1e0099671a2cd75e3407fc02cd16584fce3ba4ee Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Tue, 12 Aug 2025 13:04:45 +0100
|
||||
Subject: [PATCH] daemon: sysroot: Avoid double-/ when creating sysroot paths
|
||||
in OCaml
|
||||
|
||||
Previously calling 'sysroot_path "/dev"' for example would return the
|
||||
string "/sysroot//dev". While this is not wrong, it confuses some
|
||||
external programs (hello, setfiles), and it's not very "clean". Be a
|
||||
bit more careful to avoid doubling the '/' character in the common case.
|
||||
---
|
||||
daemon/sysroot.ml | 6 +++++-
|
||||
daemon/sysroot.mli | 2 +-
|
||||
2 files changed, 6 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/daemon/sysroot.ml b/daemon/sysroot.ml
|
||||
index 286d125b9..57e727066 100644
|
||||
--- a/daemon/sysroot.ml
|
||||
+++ b/daemon/sysroot.ml
|
||||
@@ -20,4 +20,8 @@ open Std_utils
|
||||
|
||||
external sysroot : unit -> string = "guestfs_int_daemon_sysroot"
|
||||
|
||||
-let sysroot_path path = sysroot () // path
|
||||
+let sysroot_path path =
|
||||
+ let sysroot = sysroot () in
|
||||
+ if path = "" then sysroot
|
||||
+ else if path.[0] = '/' then sysroot ^ path
|
||||
+ else sysroot // path
|
||||
diff --git a/daemon/sysroot.mli b/daemon/sysroot.mli
|
||||
index 7f8970cd8..1e6e75902 100644
|
||||
--- a/daemon/sysroot.mli
|
||||
+++ b/daemon/sysroot.mli
|
||||
@@ -22,4 +22,4 @@ val sysroot : unit -> string
|
||||
in default. *)
|
||||
|
||||
val sysroot_path : string -> string
|
||||
-(** Equivalent to calling [sysroot () // path] *)
|
||||
+(** Prepend [path] parameter with the sysroot. *)
|
||||
--
|
||||
2.47.3
|
||||
|
||||
411
0009-daemon-Reimplement-xfs_info-using-xfs_info2.patch
Normal file
411
0009-daemon-Reimplement-xfs_info-using-xfs_info2.patch
Normal file
@ -0,0 +1,411 @@
|
||||
From fb77334e1c40ac64535f2e36ee6edbdf54a5a6ac Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Fri, 23 Jan 2026 12:27:39 +0000
|
||||
Subject: [PATCH] daemon: Reimplement xfs_info using xfs_info2
|
||||
|
||||
Remove all the complicated old C parsing code and reimplement xfs_info
|
||||
using xfs_info2. Note that this function will be deprecated.
|
||||
|
||||
(cherry picked from commit e1deb358ce19685e4d078a64edfdbe1da7ddf63c)
|
||||
---
|
||||
daemon/xfs.c | 310 --------------------------------------
|
||||
daemon/xfs.ml | 45 ++++++
|
||||
generator/actions_core.ml | 1 +
|
||||
3 files changed, 46 insertions(+), 310 deletions(-)
|
||||
|
||||
diff --git a/daemon/xfs.c b/daemon/xfs.c
|
||||
index aa056ddff..06e5fc072 100644
|
||||
--- a/daemon/xfs.c
|
||||
+++ b/daemon/xfs.c
|
||||
@@ -38,316 +38,6 @@ optgroup_xfs_available (void)
|
||||
return prog_exists ("mkfs.xfs");
|
||||
}
|
||||
|
||||
-/* Return everything up to the first comma, equals or space in the input
|
||||
- * string, strdup'ing the return value.
|
||||
- */
|
||||
-static char *
|
||||
-split_strdup (char *string)
|
||||
-{
|
||||
- size_t len;
|
||||
- char *ret;
|
||||
-
|
||||
- len = strcspn (string, " ,=");
|
||||
- ret = strndup (string, len);
|
||||
- if (!ret) {
|
||||
- reply_with_perror ("malloc");
|
||||
- return NULL;
|
||||
- }
|
||||
- return ret;
|
||||
-}
|
||||
-
|
||||
-static int
|
||||
-parse_uint32 (uint32_t *ret, const char *str)
|
||||
-{
|
||||
- uint32_t r;
|
||||
-
|
||||
- if (sscanf (str, "%" SCNu32, &r) != 1) {
|
||||
- reply_with_error ("cannot parse numeric field from xfs_info: %s", str);
|
||||
- return -1;
|
||||
- }
|
||||
-
|
||||
- *ret = r;
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-static int
|
||||
-parse_uint64 (uint64_t *ret, const char *str)
|
||||
-{
|
||||
- uint64_t r;
|
||||
-
|
||||
- if (sscanf (str, "%" SCNu64, &r) != 1) {
|
||||
- reply_with_error ("cannot parse numeric field from xfs_info: %s", str);
|
||||
- return -1;
|
||||
- }
|
||||
-
|
||||
- *ret = r;
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-/* Typical crazy output from the xfs_info command:
|
||||
- *
|
||||
- * meta-data=/dev/sda1 isize=256 agcount=4, agsize=6392 blks
|
||||
- * = sectsz=512 attr=2
|
||||
- *[ = crc=0 ]
|
||||
- * data = bsize=4096 blocks=25568, imaxpct=25
|
||||
- * = sunit=0 swidth=0 blks
|
||||
- * naming =version 2 bsize=4096 ascii-ci=0
|
||||
- * log =internal bsize=4096 blocks=1200, version=2
|
||||
- * = sectsz=512 sunit=0 blks, lazy-count=1
|
||||
- * realtime =none extsz=4096 blocks=0, rtextents=0
|
||||
- *
|
||||
- * [...] line only appears in Fedora >= 21
|
||||
- *
|
||||
- * We may need to revisit this parsing code if the output changes
|
||||
- * in future.
|
||||
- */
|
||||
-static guestfs_int_xfsinfo *
|
||||
-parse_xfs_info (char **lines)
|
||||
-{
|
||||
- guestfs_int_xfsinfo *ret;
|
||||
- CLEANUP_FREE char *section = NULL; /* first column, eg "meta-data", "data" */
|
||||
- char *p;
|
||||
- size_t i;
|
||||
-
|
||||
- ret = malloc (sizeof *ret);
|
||||
- if (ret == NULL) {
|
||||
- reply_with_error ("malloc");
|
||||
- return NULL;
|
||||
- }
|
||||
-
|
||||
- /* Initialize fields to NULL or -1 so the caller can tell which fields
|
||||
- * were updated in the code below.
|
||||
- */
|
||||
- ret->xfs_mntpoint = NULL;
|
||||
- ret->xfs_inodesize = -1;
|
||||
- ret->xfs_agcount = -1;
|
||||
- ret->xfs_agsize = -1;
|
||||
- ret->xfs_sectsize = -1;
|
||||
- ret->xfs_attr = -1;
|
||||
- ret->xfs_blocksize = -1;
|
||||
- ret->xfs_datablocks = -1;
|
||||
- ret->xfs_imaxpct = -1;
|
||||
- ret->xfs_sunit = -1;
|
||||
- ret->xfs_swidth = -1;
|
||||
- ret->xfs_dirversion = -1;
|
||||
- ret->xfs_dirblocksize = -1;
|
||||
- ret->xfs_cimode = -1;
|
||||
- ret->xfs_logname = NULL;
|
||||
- ret->xfs_logblocksize = -1;
|
||||
- ret->xfs_logblocks = -1;
|
||||
- ret->xfs_logversion = -1;
|
||||
- ret->xfs_logsectsize = -1;
|
||||
- ret->xfs_logsunit = -1;
|
||||
- ret->xfs_lazycount = -1;
|
||||
- ret->xfs_rtname = NULL;
|
||||
- ret->xfs_rtextsize = -1;
|
||||
- ret->xfs_rtblocks = -1;
|
||||
- ret->xfs_rtextents = -1;
|
||||
-
|
||||
- for (i = 0; lines[i] != NULL; ++i) {
|
||||
- if (verbose)
|
||||
- fprintf (stderr, "xfs_info: lines[%zu] = \'%s\'\n", i, lines[i]);
|
||||
-
|
||||
- if (c_isalpha (lines[i][0])) {
|
||||
- free (section);
|
||||
- section = split_strdup (lines[i]);
|
||||
- if (!section) goto error;
|
||||
-
|
||||
- if (verbose)
|
||||
- fprintf (stderr, "xfs_info: new section %s\n", section);
|
||||
- }
|
||||
-
|
||||
- if ((p = strstr (lines[i], "meta-data="))) {
|
||||
- ret->xfs_mntpoint = split_strdup (p + 10);
|
||||
- if (ret->xfs_mntpoint == NULL) goto error;
|
||||
- }
|
||||
- if ((p = strstr (lines[i], "isize="))) {
|
||||
- CLEANUP_FREE char *buf = split_strdup (p + 6);
|
||||
- if (buf == NULL) goto error;
|
||||
- if (parse_uint32 (&ret->xfs_inodesize, buf) == -1)
|
||||
- goto error;
|
||||
- }
|
||||
- if ((p = strstr (lines[i], "agcount="))) {
|
||||
- CLEANUP_FREE char *buf = split_strdup (p + 8);
|
||||
- if (buf == NULL) goto error;
|
||||
- if (parse_uint32 (&ret->xfs_agcount, buf) == -1)
|
||||
- goto error;
|
||||
- }
|
||||
- if ((p = strstr (lines[i], "agsize="))) {
|
||||
- CLEANUP_FREE char *buf = split_strdup (p + 7);
|
||||
- if (buf == NULL) goto error;
|
||||
- if (parse_uint32 (&ret->xfs_agsize, buf) == -1)
|
||||
- goto error;
|
||||
- }
|
||||
- if ((p = strstr (lines[i], "sectsz="))) {
|
||||
- if (section) {
|
||||
- CLEANUP_FREE char *buf = split_strdup (p + 7);
|
||||
- if (buf == NULL) goto error;
|
||||
- if (STREQ (section, "meta-data")) {
|
||||
- if (parse_uint32 (&ret->xfs_sectsize, buf) == -1)
|
||||
- goto error;
|
||||
- } else if (STREQ (section, "log")) {
|
||||
- if (parse_uint32 (&ret->xfs_logsectsize, buf) == -1)
|
||||
- goto error;
|
||||
- }
|
||||
- }
|
||||
- }
|
||||
- if ((p = strstr (lines[i], "attr="))) {
|
||||
- CLEANUP_FREE char *buf = split_strdup (p + 5);
|
||||
- if (buf == NULL) goto error;
|
||||
- if (parse_uint32 (&ret->xfs_attr, buf) == -1)
|
||||
- goto error;
|
||||
- }
|
||||
- if ((p = strstr (lines[i], "bsize="))) {
|
||||
- if (section) {
|
||||
- CLEANUP_FREE char *buf = split_strdup (p + 6);
|
||||
- if (buf == NULL) goto error;
|
||||
- if (STREQ (section, "data")) {
|
||||
- if (parse_uint32 (&ret->xfs_blocksize, buf) == -1)
|
||||
- goto error;
|
||||
- } else if (STREQ (section, "naming")) {
|
||||
- if (parse_uint32 (&ret->xfs_dirblocksize, buf) == -1)
|
||||
- goto error;
|
||||
- } else if (STREQ (section, "log")) {
|
||||
- if (parse_uint32 (&ret->xfs_logblocksize, buf) == -1)
|
||||
- goto error;
|
||||
- }
|
||||
- }
|
||||
- }
|
||||
- if ((p = strstr (lines[i], "blocks="))) {
|
||||
- if (section) {
|
||||
- CLEANUP_FREE char *buf = split_strdup (p + 7);
|
||||
- if (buf == NULL) goto error;
|
||||
- if (STREQ (section, "data")) {
|
||||
- if (parse_uint64 (&ret->xfs_datablocks, buf) == -1)
|
||||
- goto error;
|
||||
- } else if (STREQ (section, "log")) {
|
||||
- if (parse_uint32 (&ret->xfs_logblocks, buf) == -1)
|
||||
- goto error;
|
||||
- } else if (STREQ (section, "realtime")) {
|
||||
- if (parse_uint64 (&ret->xfs_rtblocks, buf) == -1)
|
||||
- goto error;
|
||||
- }
|
||||
- }
|
||||
- }
|
||||
- if ((p = strstr (lines[i], "imaxpct="))) {
|
||||
- CLEANUP_FREE char *buf = split_strdup (p + 8);
|
||||
- if (buf == NULL) goto error;
|
||||
- if (parse_uint32 (&ret->xfs_imaxpct, buf) == -1)
|
||||
- goto error;
|
||||
- }
|
||||
- if ((p = strstr (lines[i], "sunit="))) {
|
||||
- if (section) {
|
||||
- CLEANUP_FREE char *buf = split_strdup (p + 6);
|
||||
- if (buf == NULL) goto error;
|
||||
- if (STREQ (section, "data")) {
|
||||
- if (parse_uint32 (&ret->xfs_sunit, buf) == -1)
|
||||
- goto error;
|
||||
- } else if (STREQ (section, "log")) {
|
||||
- if (parse_uint32 (&ret->xfs_logsunit, buf) == -1)
|
||||
- goto error;
|
||||
- }
|
||||
- }
|
||||
- }
|
||||
- if ((p = strstr (lines[i], "swidth="))) {
|
||||
- CLEANUP_FREE char *buf = split_strdup (p + 7);
|
||||
- if (buf == NULL) goto error;
|
||||
- if (parse_uint32 (&ret->xfs_swidth, buf) == -1)
|
||||
- goto error;
|
||||
- }
|
||||
- if ((p = strstr (lines[i], "naming =version "))) {
|
||||
- CLEANUP_FREE char *buf = split_strdup (p + 18);
|
||||
- if (buf == NULL) goto error;
|
||||
- if (parse_uint32 (&ret->xfs_dirversion, buf) == -1)
|
||||
- goto error;
|
||||
- }
|
||||
- if ((p = strstr (lines[i], "ascii-ci="))) {
|
||||
- CLEANUP_FREE char *buf = split_strdup (p + 9);
|
||||
- if (buf == NULL) goto error;
|
||||
- if (parse_uint32 (&ret->xfs_cimode, buf) == -1)
|
||||
- goto error;
|
||||
- }
|
||||
- if ((p = strstr (lines[i], "log ="))) {
|
||||
- ret->xfs_logname = split_strdup (p + 10);
|
||||
- if (ret->xfs_logname == NULL) goto error;
|
||||
- }
|
||||
- if ((p = strstr (lines[i], "version="))) {
|
||||
- CLEANUP_FREE char *buf = split_strdup (p + 8);
|
||||
- if (buf == NULL) goto error;
|
||||
- if (parse_uint32 (&ret->xfs_logversion, buf) == -1)
|
||||
- goto error;
|
||||
- }
|
||||
- if ((p = strstr (lines[i], "lazy-count="))) {
|
||||
- CLEANUP_FREE char *buf = split_strdup (p + 11);
|
||||
- if (buf == NULL) goto error;
|
||||
- if (parse_uint32 (&ret->xfs_lazycount, buf) == -1)
|
||||
- goto error;
|
||||
- }
|
||||
- if ((p = strstr (lines[i], "realtime ="))) {
|
||||
- ret->xfs_rtname = split_strdup (p + 10);
|
||||
- if (ret->xfs_rtname == NULL) goto error;
|
||||
- }
|
||||
- if ((p = strstr (lines[i], "rtextents="))) {
|
||||
- CLEANUP_FREE char *buf = split_strdup (p + 10);
|
||||
- if (buf == NULL) goto error;
|
||||
- if (parse_uint64 (&ret->xfs_rtextents, buf) == -1)
|
||||
- goto error;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- if (ret->xfs_mntpoint == NULL) {
|
||||
- ret->xfs_mntpoint = strdup ("");
|
||||
- if (ret->xfs_mntpoint == NULL) goto error;
|
||||
- }
|
||||
- if (ret->xfs_logname == NULL) {
|
||||
- ret->xfs_logname = strdup ("");
|
||||
- if (ret->xfs_logname == NULL) goto error;
|
||||
- }
|
||||
- if (ret->xfs_rtname == NULL) {
|
||||
- ret->xfs_rtname = strdup ("");
|
||||
- if (ret->xfs_rtname == NULL) goto error;
|
||||
- }
|
||||
-
|
||||
- return ret;
|
||||
-
|
||||
- error:
|
||||
- free (ret->xfs_mntpoint);
|
||||
- free (ret->xfs_logname);
|
||||
- free (ret->xfs_rtname);
|
||||
- free (ret);
|
||||
- return NULL;
|
||||
-}
|
||||
-
|
||||
-guestfs_int_xfsinfo *
|
||||
-do_xfs_info (const char *pathordevice)
|
||||
-{
|
||||
- int r;
|
||||
- CLEANUP_FREE char *buf = NULL;
|
||||
- CLEANUP_FREE char *out = NULL, *err = NULL;
|
||||
- CLEANUP_FREE_STRING_LIST char **lines = NULL;
|
||||
- int is_dev;
|
||||
-
|
||||
- is_dev = is_device_parameter (pathordevice);
|
||||
- buf = is_dev ? strdup (pathordevice)
|
||||
- : sysroot_path (pathordevice);
|
||||
- if (buf == NULL) {
|
||||
- reply_with_perror ("malloc");
|
||||
- return NULL;
|
||||
- }
|
||||
-
|
||||
- r = command (&out, &err, "xfs_info", buf, NULL);
|
||||
- if (r == -1) {
|
||||
- reply_with_error ("%s", err);
|
||||
- return NULL;
|
||||
- }
|
||||
-
|
||||
- lines = split_lines (out);
|
||||
- if (lines == NULL)
|
||||
- return NULL;
|
||||
-
|
||||
- return parse_xfs_info (lines);
|
||||
-}
|
||||
-
|
||||
int
|
||||
do_xfs_growfs (const char *path,
|
||||
int datasec, int logsec, int rtsec,
|
||||
diff --git a/daemon/xfs.ml b/daemon/xfs.ml
|
||||
index 142b26775..157a84058 100644
|
||||
--- a/daemon/xfs.ml
|
||||
+++ b/daemon/xfs.ml
|
||||
@@ -17,6 +17,7 @@
|
||||
*)
|
||||
|
||||
open Printf
|
||||
+open Scanf
|
||||
|
||||
open Std_utils
|
||||
|
||||
@@ -126,3 +127,47 @@ let xfs_info2 dev =
|
||||
) groups;
|
||||
|
||||
List.rev !values
|
||||
+
|
||||
+(* Deprecated xfs_info. *)
|
||||
+let xfs_info dev =
|
||||
+ let h = xfs_info2 dev in
|
||||
+
|
||||
+ let find field parsefn =
|
||||
+ try List.assoc field h |> parsefn
|
||||
+ with
|
||||
+ | Not_found ->
|
||||
+ failwithf "xfs_info: unexpected missing field: %s" field
|
||||
+ | exn ->
|
||||
+ failwithf "xfs_info: failure finding field: %s: %s"
|
||||
+ field (Printexc.to_string exn)
|
||||
+ in
|
||||
+
|
||||
+ let parse_blks s = sscanf s "%ld blks" Fun.id in
|
||||
+ let parse_version s = sscanf s "version %ld" Fun.id in
|
||||
+
|
||||
+ { Structs.xfs_mntpoint = find "meta-data" Fun.id;
|
||||
+ xfs_inodesize = find "meta-data.isize" Int32.of_string;
|
||||
+ xfs_agcount = find "meta-data.agcount" Int32.of_string;
|
||||
+ xfs_agsize = find "meta-data.agsize" parse_blks;
|
||||
+ xfs_sectsize = find "meta-data.sectsz" Int32.of_string;
|
||||
+ xfs_attr = find "meta-data.attr" Int32.of_string;
|
||||
+ xfs_blocksize = find "data.bsize" Int32.of_string;
|
||||
+ xfs_datablocks = find "data.blocks" Int64.of_string;
|
||||
+ xfs_imaxpct = find "data.imaxpct" Int32.of_string;
|
||||
+ xfs_sunit = find "data.sunit" Int32.of_string;
|
||||
+ xfs_swidth = find "data.swidth" parse_blks;
|
||||
+ xfs_dirversion = find "naming" parse_version;
|
||||
+ xfs_dirblocksize = find "naming.bsize" Int32.of_string;
|
||||
+ xfs_cimode = find "naming.ascii-ci" Int32.of_string;
|
||||
+ xfs_logname = find "log" Fun.id;
|
||||
+ xfs_logblocksize = find "log.bsize" Int32.of_string;
|
||||
+ xfs_logblocks = find "log.blocks" Int32.of_string;
|
||||
+ xfs_logversion = find "log.version" Int32.of_string;
|
||||
+ xfs_logsectsize = find "log.sectsz" Int32.of_string;
|
||||
+ xfs_logsunit = find "log.sunit" parse_blks;
|
||||
+ xfs_lazycount = find "log.lazy-count" Int32.of_string;
|
||||
+ xfs_rtname = find "realtime" Fun.id;
|
||||
+ xfs_rtextsize = find "realtime.extsz" Int32.of_string;
|
||||
+ xfs_rtblocks = find "realtime.blocks" Int64.of_string;
|
||||
+ xfs_rtextents = find "realtime.rtextents" Int64.of_string;
|
||||
+ }
|
||||
diff --git a/generator/actions_core.ml b/generator/actions_core.ml
|
||||
index b7e4dae45..f2cf83440 100644
|
||||
--- a/generator/actions_core.ml
|
||||
+++ b/generator/actions_core.ml
|
||||
@@ -7228,6 +7228,7 @@ call C<guestfs_max_disks>.|} };
|
||||
{ defaults with
|
||||
name = "xfs_info"; added = (1, 19, 21);
|
||||
style = RStruct ("info", "xfsinfo"), [String (Dev_or_Path, "pathordevice")], [];
|
||||
+ impl = OCaml "Xfs.xfs_info";
|
||||
optional = Some "xfs";
|
||||
tests = [
|
||||
InitEmpty, Always, TestResult (
|
||||
--
|
||||
2.47.3
|
||||
|
||||
@ -1,49 +0,0 @@
|
||||
From c931ab3bc807cff785b1271c575855f0906e27b3 Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Tue, 12 Aug 2025 13:09:16 +0100
|
||||
Subject: [PATCH] daemon: sysroot: Avoid copying the path every time we call
|
||||
sysroot ()
|
||||
|
||||
This path never changes once the daemon has started up, so we don't
|
||||
need to call into C code and copy the string every time.
|
||||
---
|
||||
daemon/sysroot-c.c | 4 ++--
|
||||
daemon/sysroot.ml | 5 ++++-
|
||||
2 files changed, 6 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/daemon/sysroot-c.c b/daemon/sysroot-c.c
|
||||
index ad31d36ee..e664232b0 100644
|
||||
--- a/daemon/sysroot-c.c
|
||||
+++ b/daemon/sysroot-c.c
|
||||
@@ -28,10 +28,10 @@
|
||||
|
||||
#include "daemon.h"
|
||||
|
||||
-extern value guestfs_int_daemon_sysroot (value unitv);
|
||||
+extern value guestfs_int_daemon_get_sysroot (value unitv);
|
||||
|
||||
value
|
||||
-guestfs_int_daemon_sysroot (value unitv)
|
||||
+guestfs_int_daemon_get_sysroot (value unitv)
|
||||
{
|
||||
return caml_copy_string (sysroot);
|
||||
}
|
||||
diff --git a/daemon/sysroot.ml b/daemon/sysroot.ml
|
||||
index 57e727066..35ae11f3f 100644
|
||||
--- a/daemon/sysroot.ml
|
||||
+++ b/daemon/sysroot.ml
|
||||
@@ -18,7 +18,10 @@
|
||||
|
||||
open Std_utils
|
||||
|
||||
-external sysroot : unit -> string = "guestfs_int_daemon_sysroot"
|
||||
+external get_sysroot : unit -> string = "guestfs_int_daemon_get_sysroot"
|
||||
+
|
||||
+let sysroot = lazy (get_sysroot ())
|
||||
+let sysroot () = Lazy.force sysroot
|
||||
|
||||
let sysroot_path path =
|
||||
let sysroot = sysroot () in
|
||||
--
|
||||
2.47.3
|
||||
|
||||
@ -1,406 +0,0 @@
|
||||
From ed40333a23ae8f20ac0360df444d10db369fa6d9 Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Tue, 12 Aug 2025 12:22:42 +0100
|
||||
Subject: [PATCH] daemon: Reimplement guestfs_selinux_relabel in OCaml
|
||||
|
||||
No change, just reimplement the existing C implementation in OCaml.
|
||||
---
|
||||
.gitignore | 1 +
|
||||
daemon/Makefile.am | 4 +-
|
||||
daemon/selinux-relabel.c | 169 --------------------------------------
|
||||
daemon/selinux.c | 7 ++
|
||||
daemon/selinux.ml | 101 +++++++++++++++++++++++
|
||||
docs/C_SOURCE_FILES | 1 -
|
||||
generator/actions_core.ml | 1 +
|
||||
po/POTFILES | 1 -
|
||||
8 files changed, 113 insertions(+), 172 deletions(-)
|
||||
delete mode 100644 daemon/selinux-relabel.c
|
||||
create mode 100644 daemon/selinux.ml
|
||||
|
||||
diff --git a/.gitignore b/.gitignore
|
||||
index 81cd278cc..02160caff 100644
|
||||
--- a/.gitignore
|
||||
+++ b/.gitignore
|
||||
@@ -108,6 +108,7 @@ Makefile.in
|
||||
/daemon/parted.mli
|
||||
/daemon/realpath.mli
|
||||
/daemon/rpm.mli
|
||||
+/daemon/selinux.mli
|
||||
/daemon/sfdisk.mli
|
||||
/daemon/stamp-guestfsd.pod
|
||||
/daemon/statvfs.mli
|
||||
diff --git a/daemon/Makefile.am b/daemon/Makefile.am
|
||||
index 6d7492013..c644d9881 100644
|
||||
--- a/daemon/Makefile.am
|
||||
+++ b/daemon/Makefile.am
|
||||
@@ -59,6 +59,7 @@ generator_built = \
|
||||
parted.mli \
|
||||
realpath.mli \
|
||||
rpm.mli \
|
||||
+ selinux.mli \
|
||||
sfdisk.mli \
|
||||
statvfs.mli \
|
||||
structs.ml \
|
||||
@@ -173,7 +174,6 @@ guestfsd_SOURCES = \
|
||||
rsync.c \
|
||||
scrub.c \
|
||||
selinux.c \
|
||||
- selinux-relabel.c \
|
||||
sfdisk.c \
|
||||
sh.c \
|
||||
sleep.c \
|
||||
@@ -307,6 +307,7 @@ SOURCES_MLI = \
|
||||
parted.mli \
|
||||
realpath.mli \
|
||||
rpm.mli \
|
||||
+ selinux.mli \
|
||||
sfdisk.mli \
|
||||
statvfs.mli \
|
||||
structs.mli \
|
||||
@@ -345,6 +346,7 @@ SOURCES_ML = \
|
||||
listfs.ml \
|
||||
realpath.ml \
|
||||
statvfs.ml \
|
||||
+ selinux.ml \
|
||||
inspect_types.ml \
|
||||
inspect_utils.ml \
|
||||
inspect_fs_unix_fstab.ml \
|
||||
diff --git a/daemon/selinux-relabel.c b/daemon/selinux-relabel.c
|
||||
deleted file mode 100644
|
||||
index cfc5a31d9..000000000
|
||||
--- a/daemon/selinux-relabel.c
|
||||
+++ /dev/null
|
||||
@@ -1,169 +0,0 @@
|
||||
-/* libguestfs - the guestfsd daemon
|
||||
- * Copyright (C) 2016 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 <stdio.h>
|
||||
-#include <stdlib.h>
|
||||
-#include <string.h>
|
||||
-#include <sys/stat.h>
|
||||
-
|
||||
-#include "guestfs_protocol.h"
|
||||
-#include "daemon.h"
|
||||
-#include "actions.h"
|
||||
-#include "optgroups.h"
|
||||
-
|
||||
-#include "ignore-value.h"
|
||||
-
|
||||
-#define MAX_ARGS 64
|
||||
-
|
||||
-int
|
||||
-optgroup_selinuxrelabel_available (void)
|
||||
-{
|
||||
- return prog_exists ("setfiles");
|
||||
-}
|
||||
-
|
||||
-static int
|
||||
-dir_exists (const char *dir)
|
||||
-{
|
||||
- struct stat statbuf;
|
||||
-
|
||||
- if (stat (dir, &statbuf) == 0 && S_ISDIR (statbuf.st_mode))
|
||||
- return 1;
|
||||
- else
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-static int
|
||||
-setfiles_has_option (int *flag, char opt_char)
|
||||
-{
|
||||
- CLEANUP_FREE char *err = NULL;
|
||||
-
|
||||
- if (*flag == -1) {
|
||||
- char option[] = { '-', opt_char, '\0' }; /* "-X" */
|
||||
- char err_opt[32]; /* "invalid option -- 'X'" */
|
||||
-
|
||||
- snprintf(err_opt, sizeof(err_opt), "invalid option -- '%c'", opt_char);
|
||||
- ignore_value (command (NULL, &err, "setfiles", option, NULL));
|
||||
- *flag = err && strstr (err, /* "invalid option -- " */ err_opt) == NULL;
|
||||
- }
|
||||
-
|
||||
- return *flag;
|
||||
-}
|
||||
-
|
||||
-/* Takes optional arguments, consult optargs_bitmask. */
|
||||
-int
|
||||
-do_selinux_relabel (const char *specfile, const char *path,
|
||||
- int force)
|
||||
-{
|
||||
- static int flag_m = -1;
|
||||
- static int flag_C = -1;
|
||||
- static int flag_T = -1;
|
||||
- const char *argv[MAX_ARGS];
|
||||
- CLEANUP_FREE char *s_dev = NULL, *s_proc = NULL, *s_selinux = NULL,
|
||||
- *s_sys = NULL, *s_specfile = NULL, *s_path = NULL;
|
||||
- CLEANUP_FREE char *err = NULL;
|
||||
- size_t i = 0;
|
||||
- int setfiles_status;
|
||||
-
|
||||
- s_dev = sysroot_path ("/dev");
|
||||
- if (!s_dev) {
|
||||
- malloc_error:
|
||||
- reply_with_perror ("malloc");
|
||||
- return -1;
|
||||
- }
|
||||
- s_proc = sysroot_path ("/proc"); if (!s_proc) goto malloc_error;
|
||||
- s_selinux = sysroot_path ("/selinux"); if (!s_selinux) goto malloc_error;
|
||||
- s_sys = sysroot_path ("/sys"); if (!s_sys) goto malloc_error;
|
||||
- s_specfile = sysroot_path (specfile); if (!s_specfile) goto malloc_error;
|
||||
- s_path = sysroot_path (path); if (!s_path) goto malloc_error;
|
||||
-
|
||||
- /* Default settings if not selected. */
|
||||
- if (!(optargs_bitmask & GUESTFS_SELINUX_RELABEL_FORCE_BITMASK))
|
||||
- force = 0;
|
||||
-
|
||||
- /* If setfiles takes an excessively long time to run (but still
|
||||
- * completes) then removing .../contexts/files/file_contexts.bin
|
||||
- * appears to help. If you find any such cases, please add
|
||||
- * observations to the bug report:
|
||||
- * https://bugzilla.redhat.com/show_bug.cgi?id=1396297
|
||||
- */
|
||||
- ADD_ARG (argv, i, "setfiles");
|
||||
- if (force)
|
||||
- ADD_ARG (argv, i, "-F");
|
||||
-
|
||||
- /* Exclude some directories that should never be relabelled in
|
||||
- * ordinary Linux guests. These won't be mounted anyway. We have
|
||||
- * to prefix all these with the sysroot path.
|
||||
- */
|
||||
- ADD_ARG (argv, i, "-e"); ADD_ARG (argv, i, s_dev);
|
||||
- ADD_ARG (argv, i, "-e"); ADD_ARG (argv, i, s_proc);
|
||||
- ADD_ARG (argv, i, "-e"); ADD_ARG (argv, i, s_sys);
|
||||
- if (dir_exists (s_selinux)) {
|
||||
- ADD_ARG (argv, i, "-e"); ADD_ARG (argv, i, s_selinux);
|
||||
- }
|
||||
-
|
||||
- /* You have to use the -m option (where available) otherwise
|
||||
- * setfiles puts all the mountpoints on the excludes list for no
|
||||
- * useful reason (RHBZ#1433577).
|
||||
- */
|
||||
- if (setfiles_has_option (&flag_m, 'm'))
|
||||
- ADD_ARG (argv, i, "-m");
|
||||
-
|
||||
- /* Not only do we want setfiles to trudge through individual relabeling
|
||||
- * errors, we also want the setfiles exit status to differentiate a fatal
|
||||
- * error from "relabeling errors only". See RHBZ#1794518.
|
||||
- */
|
||||
- if (setfiles_has_option (&flag_C, 'C'))
|
||||
- ADD_ARG (argv, i, "-C");
|
||||
-
|
||||
- /* If the appliance is being run with multiple vCPUs, running setfiles
|
||||
- * in multithreading mode might speeds up the process. Option "-T" was
|
||||
- * introduced in SELinux userspace v3.4, and we need to check whether it's
|
||||
- * supported. Passing "-T 0" creates as many threads as there're available
|
||||
- * vCPU cores.
|
||||
- * https://github.com/SELinuxProject/selinux/releases/tag/3.4
|
||||
- */
|
||||
- if (setfiles_has_option (&flag_T, 'T')) {
|
||||
- ADD_ARG (argv, i, "-T"); ADD_ARG (argv, i, "0");
|
||||
- }
|
||||
-
|
||||
- /* Relabelling in a chroot. */
|
||||
- if (STRNEQ (sysroot, "/")) {
|
||||
- ADD_ARG (argv, i, "-r");
|
||||
- ADD_ARG (argv, i, sysroot);
|
||||
- }
|
||||
-
|
||||
- if (verbose)
|
||||
- ADD_ARG (argv, i, "-v");
|
||||
- else
|
||||
- /* Suppress non-error output. */
|
||||
- ADD_ARG (argv, i, "-q");
|
||||
-
|
||||
- /* Add parameters. */
|
||||
- ADD_ARG (argv, i, s_specfile);
|
||||
- ADD_ARG (argv, i, s_path);
|
||||
- ADD_ARG (argv, i, NULL);
|
||||
-
|
||||
- setfiles_status = commandrv (NULL, &err, argv);
|
||||
- if ((setfiles_status == 0) || (setfiles_status == 1 && flag_C))
|
||||
- return 0;
|
||||
-
|
||||
- reply_with_error ("%s", err);
|
||||
- return -1;
|
||||
-}
|
||||
diff --git a/daemon/selinux.c b/daemon/selinux.c
|
||||
index f4d839c19..4500d0096 100644
|
||||
--- a/daemon/selinux.c
|
||||
+++ b/daemon/selinux.c
|
||||
@@ -39,6 +39,13 @@ optgroup_selinux_available (void)
|
||||
return 1;
|
||||
}
|
||||
|
||||
+/* For historical reasons, this is really "is setfiles available" */
|
||||
+int
|
||||
+optgroup_selinuxrelabel_available (void)
|
||||
+{
|
||||
+ return prog_exists ("setfiles");
|
||||
+}
|
||||
+
|
||||
/* setcon is only valid under the following circumstances:
|
||||
* - single threaded
|
||||
* - enforcing=0
|
||||
diff --git a/daemon/selinux.ml b/daemon/selinux.ml
|
||||
new file mode 100644
|
||||
index 000000000..d954fdead
|
||||
--- /dev/null
|
||||
+++ b/daemon/selinux.ml
|
||||
@@ -0,0 +1,101 @@
|
||||
+(* SELinux functions.
|
||||
+ * Copyright (C) 2009-2025 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.
|
||||
+ *)
|
||||
+
|
||||
+open Printf
|
||||
+
|
||||
+open Std_utils
|
||||
+
|
||||
+open Sysroot
|
||||
+open Utils
|
||||
+
|
||||
+(* Test if setfiles has various options.
|
||||
+ *
|
||||
+ * The only way to do this is to run setfiles with the option alone, and
|
||||
+ * test for the stderr message [invalid option -- 'X'].
|
||||
+ *)
|
||||
+let setfiles_has_option_m,
|
||||
+ setfiles_has_option_C,
|
||||
+ setfiles_has_option_T =
|
||||
+ let setfiles_has_option flag =
|
||||
+ let err_msg = sprintf "invalid option -- '%c'" flag in
|
||||
+ let opt = sprintf "-%c" flag in
|
||||
+ let _, _, err = commandr "setfiles" [opt] in
|
||||
+ String.find err err_msg = -1
|
||||
+ in
|
||||
+ let setfiles_has_option_m = lazy (setfiles_has_option 'm')
|
||||
+ and setfiles_has_option_C = lazy (setfiles_has_option 'C')
|
||||
+ and setfiles_has_option_T = lazy (setfiles_has_option 'T') in
|
||||
+ (fun () -> Lazy.force setfiles_has_option_m),
|
||||
+ (fun () -> Lazy.force setfiles_has_option_C),
|
||||
+ (fun () -> Lazy.force setfiles_has_option_T)
|
||||
+
|
||||
+let selinux_relabel ?(force = false) specfile path =
|
||||
+ (* Prefix /sysroot on all paths. *)
|
||||
+ let ignored_paths =
|
||||
+ [ "/dev"; "/proc"; "/selinux"; "/sys" ] |>
|
||||
+ List.map sysroot_path in
|
||||
+ let specfile = sysroot_path specfile in
|
||||
+ let path = sysroot_path path in
|
||||
+
|
||||
+ let args = ref [] in
|
||||
+ if force then List.push_back args "-F";
|
||||
+ List.iter (
|
||||
+ fun ignored_path ->
|
||||
+ List.push_back_list args [ "-e"; ignored_path ]
|
||||
+ ) ignored_paths;
|
||||
+
|
||||
+ (* You have to use the -m option (where available) otherwise
|
||||
+ * setfiles puts all the mountpoints on the excludes list for no
|
||||
+ * useful reason (RHBZ#1433577).
|
||||
+ *)
|
||||
+ if setfiles_has_option_m () then List.push_back args "-m";
|
||||
+
|
||||
+ (* Not only do we want setfiles to trudge through individual relabeling
|
||||
+ * errors, we also want the setfiles exit status to differentiate a fatal
|
||||
+ * error from "relabeling errors only". See RHBZ#1794518.
|
||||
+ *)
|
||||
+ if setfiles_has_option_C () then List.push_back args "-C";
|
||||
+
|
||||
+ (* If the appliance is being run with multiple vCPUs, running setfiles
|
||||
+ * in multithreading mode might speeds up the process. Option "-T" was
|
||||
+ * introduced in SELinux userspace v3.4, and we need to check whether it's
|
||||
+ * supported. Passing "-T 0" creates as many threads as there're available
|
||||
+ * vCPU cores.
|
||||
+ * https://github.com/SELinuxProject/selinux/releases/tag/3.4
|
||||
+ *)
|
||||
+ if setfiles_has_option_T () then
|
||||
+ List.push_back_list args [ "-T"; "0" ];
|
||||
+
|
||||
+ (* Relabelling in a chroot. *)
|
||||
+ if sysroot () <> "/" then
|
||||
+ List.push_back_list args [ "-r"; sysroot () ];
|
||||
+
|
||||
+ if verbose () then
|
||||
+ List.push_back args "-v"
|
||||
+ else
|
||||
+ (* Suppress non-error output. *)
|
||||
+ List.push_back args "-q";
|
||||
+
|
||||
+ (* Add parameters. *)
|
||||
+ List.push_back_list args [ specfile; path ];
|
||||
+
|
||||
+ let args = !args in
|
||||
+ let r, _, err = commandr "setfiles" args in
|
||||
+
|
||||
+ let ok = r = 0 || r = 1 && setfiles_has_option_C () in
|
||||
+ if not ok then failwithf "setfiles: %s" err
|
||||
diff --git a/docs/C_SOURCE_FILES b/docs/C_SOURCE_FILES
|
||||
index cdfb1d615..5270667bf 100644
|
||||
--- a/docs/C_SOURCE_FILES
|
||||
+++ b/docs/C_SOURCE_FILES
|
||||
@@ -132,7 +132,6 @@ daemon/rename.c
|
||||
daemon/rpm-c.c
|
||||
daemon/rsync.c
|
||||
daemon/scrub.c
|
||||
-daemon/selinux-relabel.c
|
||||
daemon/selinux.c
|
||||
daemon/sfdisk.c
|
||||
daemon/sh.c
|
||||
diff --git a/generator/actions_core.ml b/generator/actions_core.ml
|
||||
index 108494ece..128cbe0e9 100644
|
||||
--- a/generator/actions_core.ml
|
||||
+++ b/generator/actions_core.ml
|
||||
@@ -9359,6 +9359,7 @@ fails and the C<errno> is set to C<ENODEV>." };
|
||||
{ defaults with
|
||||
name = "selinux_relabel"; added = (1, 33, 43);
|
||||
style = RErr, [String (PlainString, "specfile"); String (Pathname, "path")], [OBool "force"];
|
||||
+ impl = OCaml "Selinux.selinux_relabel";
|
||||
optional = Some "selinuxrelabel";
|
||||
test_excuse = "tests are in the tests/relabel directory";
|
||||
shortdesc = "relabel parts of the filesystem";
|
||||
diff --git a/po/POTFILES b/po/POTFILES
|
||||
index acf3a68d7..fbe0a7fe2 100644
|
||||
--- a/po/POTFILES
|
||||
+++ b/po/POTFILES
|
||||
@@ -110,7 +110,6 @@ daemon/rename.c
|
||||
daemon/rpm-c.c
|
||||
daemon/rsync.c
|
||||
daemon/scrub.c
|
||||
-daemon/selinux-relabel.c
|
||||
daemon/selinux.c
|
||||
daemon/sfdisk.c
|
||||
daemon/sh.c
|
||||
--
|
||||
2.47.3
|
||||
|
||||
@ -0,0 +1,80 @@
|
||||
From 5b3de10b018e891ef7cc7fae0e8b1b32445eb392 Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Fri, 23 Jan 2026 08:51:11 +0000
|
||||
Subject: [PATCH] generator: Deprecate xfs_info (replaced by xfs_info2)
|
||||
|
||||
Deprecate this function, and suggest using xfs_info2 as its
|
||||
replacement.
|
||||
|
||||
(cherry picked from commit 7833461af76d1feaf2dd1e779f7f04bcca91a6bc)
|
||||
---
|
||||
generator/actions_core.ml | 21 ---------------------
|
||||
generator/actions_core_deprecated.ml | 22 ++++++++++++++++++++++
|
||||
2 files changed, 22 insertions(+), 21 deletions(-)
|
||||
|
||||
diff --git a/generator/actions_core.ml b/generator/actions_core.ml
|
||||
index f2cf83440..26d77c667 100644
|
||||
--- a/generator/actions_core.ml
|
||||
+++ b/generator/actions_core.ml
|
||||
@@ -7225,27 +7225,6 @@ be returned if you called C<guestfs_list_devices>.
|
||||
To find out the maximum number of devices that could be added,
|
||||
call C<guestfs_max_disks>.|} };
|
||||
|
||||
- { defaults with
|
||||
- name = "xfs_info"; added = (1, 19, 21);
|
||||
- style = RStruct ("info", "xfsinfo"), [String (Dev_or_Path, "pathordevice")], [];
|
||||
- impl = OCaml "Xfs.xfs_info";
|
||||
- optional = Some "xfs";
|
||||
- tests = [
|
||||
- InitEmpty, Always, TestResult (
|
||||
- [["part_disk"; "/dev/sda"; "mbr"];
|
||||
- ["mkfs"; "xfs"; "/dev/sda1"; ""; "NOARG"; ""; ""; "NOARG"];
|
||||
- ["mount"; "/dev/sda1"; "/"];
|
||||
- ["xfs_info"; "/"]], "ret->xfs_blocksize == 4096"), []
|
||||
- ];
|
||||
- shortdesc = "get information about the XFS filesystem";
|
||||
- longdesc = {|C<pathordevice> is a mounted XFS filesystem or a device containing
|
||||
-an XFS filesystem. This command returns miscellaneous
|
||||
-metadata about the XFS filesystem.
|
||||
-
|
||||
-The returned struct contains miscellaneous metadata. Missing
|
||||
-fields are returned as C<-1> (for numeric fields) or empty
|
||||
-string.|} };
|
||||
-
|
||||
{ defaults with
|
||||
name = "pvchange_uuid"; added = (1, 19, 26);
|
||||
style = RErr, [String (Device, "device")], [];
|
||||
diff --git a/generator/actions_core_deprecated.ml b/generator/actions_core_deprecated.ml
|
||||
index aa98bd5fe..308495c45 100644
|
||||
--- a/generator/actions_core_deprecated.ml
|
||||
+++ b/generator/actions_core_deprecated.ml
|
||||
@@ -945,4 +945,26 @@ The optional C<force> boolean controls whether the context
|
||||
is reset for customizable files, and also whether the
|
||||
user, role and range parts of the file context is changed.|} };
|
||||
|
||||
+ { defaults with
|
||||
+ name = "xfs_info"; added = (1, 19, 21);
|
||||
+ style = RStruct ("info", "xfsinfo"), [String (Dev_or_Path, "pathordevice")], [];
|
||||
+ impl = OCaml "Xfs.xfs_info";
|
||||
+ optional = Some "xfs";
|
||||
+ deprecated_by = Replaced_by "xfs_info2";
|
||||
+ tests = [
|
||||
+ InitEmpty, Always, TestResult (
|
||||
+ [["part_disk"; "/dev/sda"; "mbr"];
|
||||
+ ["mkfs"; "xfs"; "/dev/sda1"; ""; "NOARG"; ""; ""; "NOARG"];
|
||||
+ ["mount"; "/dev/sda1"; "/"];
|
||||
+ ["xfs_info"; "/"]], "ret->xfs_blocksize == 4096"), []
|
||||
+ ];
|
||||
+ shortdesc = "get information about the XFS filesystem";
|
||||
+ longdesc = {|C<pathordevice> is a mounted XFS filesystem or a device containing
|
||||
+an XFS filesystem. This command returns miscellaneous
|
||||
+metadata about the XFS filesystem.
|
||||
+
|
||||
+The returned struct contains miscellaneous metadata. Missing
|
||||
+fields are returned as C<-1> (for numeric fields) or empty
|
||||
+string.|} };
|
||||
+
|
||||
]
|
||||
--
|
||||
2.47.3
|
||||
|
||||
@ -1,99 +0,0 @@
|
||||
From fd4db60cffd9d0ece25a436932aca5411e13b94e Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Tue, 12 Aug 2025 14:05:44 +0100
|
||||
Subject: [PATCH] generator: Implement StringList for OCaml functions
|
||||
|
||||
No existing OCaml functions have a StringList parameter, but we would
|
||||
like to add one.
|
||||
|
||||
The original plan seems to have been to map these to 'string array'
|
||||
types, but 'string list' is more natural, albeit marginally less
|
||||
efficient. The implementation here just has to convert the 'char **'
|
||||
into the OCaml linked list of values.
|
||||
---
|
||||
daemon/daemon-c.c | 24 ++++++++++++++++++++++++
|
||||
daemon/daemon-c.h | 1 +
|
||||
generator/daemon.ml | 6 ++++--
|
||||
3 files changed, 29 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/daemon/daemon-c.c b/daemon/daemon-c.c
|
||||
index 1754cf0d2..371c2a9e4 100644
|
||||
--- a/daemon/daemon-c.c
|
||||
+++ b/daemon/daemon-c.c
|
||||
@@ -114,6 +114,30 @@ guestfs_int_daemon_copy_mountable (const mountable_t *mountable)
|
||||
CAMLreturn (r);
|
||||
}
|
||||
|
||||
+/* Implement StringList(...) parameter. */
|
||||
+value
|
||||
+guestfs_int_daemon_copy_string_list (char * const *strs)
|
||||
+{
|
||||
+ CAMLparam0 ();
|
||||
+ CAMLlocal3 (v, tlv, rv);
|
||||
+ size_t i;
|
||||
+
|
||||
+ /* We need to build the list backwards so start at the end. */
|
||||
+ for (i = 0; strs[i] != NULL; ++i)
|
||||
+ ;
|
||||
+
|
||||
+ while (i > 0) {
|
||||
+ --i;
|
||||
+ v = caml_copy_string (strs[i]);
|
||||
+ rv = caml_alloc (2, 0);
|
||||
+ Store_field (rv, 0, v);
|
||||
+ Store_field (rv, 1, tlv);
|
||||
+ tlv = rv;
|
||||
+ }
|
||||
+
|
||||
+ CAMLreturn (rv);
|
||||
+}
|
||||
+
|
||||
/* Implement RStringList. */
|
||||
char **
|
||||
guestfs_int_daemon_return_string_list (value retv)
|
||||
diff --git a/daemon/daemon-c.h b/daemon/daemon-c.h
|
||||
index 9b7085bce..b06efc0cf 100644
|
||||
--- a/daemon/daemon-c.h
|
||||
+++ b/daemon/daemon-c.h
|
||||
@@ -29,6 +29,7 @@
|
||||
|
||||
extern void guestfs_int_daemon_exn_to_reply_with_error (const char *func, value exn);
|
||||
extern value guestfs_int_daemon_copy_mountable (const mountable_t *mountable);
|
||||
+extern value guestfs_int_daemon_copy_string_list (char * const *strs);
|
||||
extern char **guestfs_int_daemon_return_string_list (value retv);
|
||||
extern char *guestfs_int_daemon_return_string_mountable (value retv);
|
||||
extern char **guestfs_int_daemon_return_string_mountable_list (value retv);
|
||||
diff --git a/generator/daemon.ml b/generator/daemon.ml
|
||||
index 6221531d2..2b74f3059 100644
|
||||
--- a/generator/daemon.ml
|
||||
+++ b/generator/daemon.ml
|
||||
@@ -558,7 +558,7 @@ and generate_ocaml_daemon_prototype name (ret, args, optargs) =
|
||||
| OInt n -> pr "?%s:int -> " n
|
||||
| OInt64 n -> pr "?%s:int64 -> " n
|
||||
| OString n -> pr "?%s:string -> " n
|
||||
- | OStringList n -> pr "?%s:string array -> " n
|
||||
+ | OStringList n -> pr "?%s:string list -> " n
|
||||
) optargs;
|
||||
if args <> [] then
|
||||
List.iter (
|
||||
@@ -566,7 +566,7 @@ and generate_ocaml_daemon_prototype name (ret, args, optargs) =
|
||||
| String (typ, _) -> pr "%s -> " (type_for_stringt typ)
|
||||
| BufferIn _ -> pr "string -> "
|
||||
| OptString _ -> pr "string option -> "
|
||||
- | StringList (typ, _) -> pr "%s array -> " (type_for_stringt typ)
|
||||
+ | StringList (typ, _) -> pr "%s list -> " (type_for_stringt typ)
|
||||
| Bool _ -> pr "bool -> "
|
||||
| Int _ -> pr "int -> "
|
||||
| Int64 _ | Pointer _ -> pr "int64 -> "
|
||||
@@ -820,6 +820,8 @@ let generate_daemon_caml_stubs () =
|
||||
pr "guestfs_int_daemon_copy_mountable (%s)" n
|
||||
| String _ -> assert false
|
||||
| OptString _ -> assert false
|
||||
+ | StringList ((PlainString|Filename|Pathname), n) ->
|
||||
+ pr "guestfs_int_daemon_copy_string_list (%s)" n
|
||||
| StringList _ -> assert false
|
||||
| BufferIn _ -> assert false
|
||||
| Pointer _ -> assert false
|
||||
--
|
||||
2.47.3
|
||||
|
||||
@ -0,0 +1,33 @@
|
||||
From 4a5ee2fbcbef5f10b8faf8f8659ba5f82145f42d Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Mon, 26 Jan 2026 14:59:13 +0000
|
||||
Subject: [PATCH] tests/disks/debug-qemu.sh: Fix test for update QMP test
|
||||
|
||||
Commit f7a24b2ea8 ("lib/qemu.c: Use machine type none when inspecting
|
||||
QMP properties") changed the number of command line parameters used
|
||||
before the '-qmp stdio' option when libguestfs queries qemu features.
|
||||
This broke some tests which rely on the exact order of parameters.
|
||||
|
||||
Fixes: commit f7a24b2ea81f3c5c2754fcf43e0347c7c5378b4a
|
||||
Updates: commit 5da8102f5f59b9781075440dc68c8d08f9c8691e
|
||||
(cherry picked from commit 45d0e66d02adf1a42c8eca979fa38d2f91d9f3c2)
|
||||
---
|
||||
tests/disks/debug-qemu.sh | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/tests/disks/debug-qemu.sh b/tests/disks/debug-qemu.sh
|
||||
index 96c90553b..e6e80abe3 100755
|
||||
--- a/tests/disks/debug-qemu.sh
|
||||
+++ b/tests/disks/debug-qemu.sh
|
||||
@@ -25,7 +25,7 @@ fi
|
||||
|
||||
# The direct backend runs qemu ... -qmp stdio to query for KVM. For
|
||||
# the test to pass we have to provide an answer here.
|
||||
-if [ "x$7" = "x-qmp" ]; then
|
||||
+if [ "x$5" = "x-qmp" ]; then
|
||||
# Consume stdin first.
|
||||
cat >/dev/null
|
||||
# Write some fake output.
|
||||
--
|
||||
2.47.3
|
||||
|
||||
@ -1,83 +0,0 @@
|
||||
From e4d9ee3fbc58c5993db0c75c647fdf904c520918 Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Tue, 12 Aug 2025 14:04:42 +0100
|
||||
Subject: [PATCH] generator: Allow StringList(Pathname) parameters
|
||||
|
||||
This was previously not implemented. It just requires us to call
|
||||
ABS_PATH on each parameter. ABS_PATH checks the parameter is an
|
||||
absolute path.
|
||||
---
|
||||
generator/checks.ml | 1 -
|
||||
generator/daemon.ml | 16 ++++++++++++----
|
||||
2 files changed, 12 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/generator/checks.ml b/generator/checks.ml
|
||||
index d64d49d66..4207c0677 100644
|
||||
--- a/generator/checks.ml
|
||||
+++ b/generator/checks.ml
|
||||
@@ -166,7 +166,6 @@ let () =
|
||||
| StringList (FileIn, _)
|
||||
| StringList (FileOut, _)
|
||||
| StringList (Mountable, _)
|
||||
- | StringList (Pathname, _)
|
||||
| StringList (Dev_or_Path, _)
|
||||
| StringList (Mountable_or_Path, _)
|
||||
| StringList (Key, _)
|
||||
diff --git a/generator/daemon.ml b/generator/daemon.ml
|
||||
index 2b74f3059..6197288df 100644
|
||||
--- a/generator/daemon.ml
|
||||
+++ b/generator/daemon.ml
|
||||
@@ -173,7 +173,7 @@ let generate_daemon_stubs actions () =
|
||||
| String ((Mountable|Mountable_or_Path), n) ->
|
||||
pr " CLEANUP_FREE_MOUNTABLE mountable_t %s\n" n;
|
||||
pr " = { .device = NULL, .volume = NULL };\n"
|
||||
- | StringList ((PlainString|Filename), n) ->
|
||||
+ | StringList ((PlainString|Filename|Pathname), n) ->
|
||||
pr " char **%s;\n" n
|
||||
| StringList (Device, n) ->
|
||||
pr " CLEANUP_FREE_STRING_LIST char **%s = NULL;\n" n
|
||||
@@ -184,7 +184,7 @@ let generate_daemon_stubs actions () =
|
||||
pr " const char *%s;\n" n;
|
||||
pr " size_t %s_size;\n" n
|
||||
| String ((FileIn|FileOut|Filename), _)
|
||||
- | StringList ((Mountable|Pathname|FileIn|FileOut|Key|GUID
|
||||
+ | StringList ((Mountable|FileIn|FileOut|Key|GUID
|
||||
|Dev_or_Path|Mountable_or_Path), _)
|
||||
| Pointer _ -> assert false
|
||||
) args_passed_to_daemon
|
||||
@@ -260,7 +260,7 @@ let generate_daemon_stubs actions () =
|
||||
n n is_filein;
|
||||
| String ((PlainString|Key|GUID), n) -> pr_args n
|
||||
| OptString n -> pr " %s = args.%s ? *args.%s : NULL;\n" n n n
|
||||
- | StringList ((PlainString|Filename) as arg, n) ->
|
||||
+ | StringList ((PlainString|Filename|Pathname) as arg, n) ->
|
||||
(match arg with
|
||||
| Filename ->
|
||||
pr " {\n";
|
||||
@@ -275,6 +275,14 @@ let generate_daemon_stubs actions () =
|
||||
pr " }\n";
|
||||
pr " }\n";
|
||||
pr " }\n"
|
||||
+ | Pathname ->
|
||||
+ pr " {\n";
|
||||
+ pr " size_t i;\n";
|
||||
+ pr " for (i = 0; i < args.%s.%s_len; ++i) {\n" n n;
|
||||
+ pr " ABS_PATH (args.%s.%s_val[i], %b, return);\n"
|
||||
+ n n is_filein;
|
||||
+ pr " }\n";
|
||||
+ pr " }\n"
|
||||
| _ -> ()
|
||||
);
|
||||
pr " /* Ugly, but safe and avoids copying the strings. */\n";
|
||||
@@ -307,7 +315,7 @@ let generate_daemon_stubs actions () =
|
||||
pr " %s = args.%s.%s_val;\n" n n n;
|
||||
pr " %s_size = args.%s.%s_len;\n" n n n
|
||||
| String ((FileIn|FileOut|Filename), _)
|
||||
- | StringList ((Mountable|Pathname|FileIn|FileOut|Key|GUID
|
||||
+ | StringList ((Mountable|FileIn|FileOut|Key|GUID
|
||||
|Dev_or_Path|Mountable_or_Path), _)
|
||||
| Pointer _ -> assert false
|
||||
) args_passed_to_daemon;
|
||||
--
|
||||
2.47.3
|
||||
|
||||
@ -1,311 +0,0 @@
|
||||
From 1c0b56158aa63359d1e53f7a31b483194f235a34 Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Tue, 12 Aug 2025 13:27:32 +0100
|
||||
Subject: [PATCH] daemon: Deprecate guestfs_selinux_relabel, replace with
|
||||
guestfs_setfiles
|
||||
|
||||
The guestfs_selinux_relabel function was very hard to use. In
|
||||
particular it didn't just do an SELinux relabel as you might expect.
|
||||
Instead you have to write a whole bunch of code around it (example[1])
|
||||
to make it useful.
|
||||
|
||||
Another problem is that it doesn't let you pass multiple paths to the
|
||||
setfiles command, but the command itself does permit that (and, as it
|
||||
turns out, will require it). There is no backwards compatible way to
|
||||
extend the existing definition to allow a list parameter without
|
||||
breaking API.
|
||||
|
||||
So deprecate guestfs_selinux_relabel. Reimplement it as
|
||||
guestfs_setfiles. The new function is basically the same as the old
|
||||
one, but allows you to pass a list of paths. The old function calls
|
||||
the new function with a single path parameter.
|
||||
|
||||
[1] https://github.com/libguestfs/libguestfs-common/blob/master/mlcustomize/SELinux_relabel.ml
|
||||
---
|
||||
daemon/selinux.ml | 117 ++++++++++++++-------------
|
||||
generator/actions_core.ml | 49 +++++------
|
||||
generator/actions_core_deprecated.ml | 24 ++++++
|
||||
generator/proc_nr.ml | 1 +
|
||||
gobject/Makefile.inc | 2 +
|
||||
lib/MAX_PROC_NR | 2 +-
|
||||
tests/relabel/test-relabel.pl | 2 +-
|
||||
7 files changed, 117 insertions(+), 80 deletions(-)
|
||||
|
||||
diff --git a/daemon/selinux.ml b/daemon/selinux.ml
|
||||
index d954fdead..db0d71455 100644
|
||||
--- a/daemon/selinux.ml
|
||||
+++ b/daemon/selinux.ml
|
||||
@@ -44,58 +44,65 @@ let setfiles_has_option_m,
|
||||
(fun () -> Lazy.force setfiles_has_option_C),
|
||||
(fun () -> Lazy.force setfiles_has_option_T)
|
||||
|
||||
-let selinux_relabel ?(force = false) specfile path =
|
||||
- (* Prefix /sysroot on all paths. *)
|
||||
- let ignored_paths =
|
||||
- [ "/dev"; "/proc"; "/selinux"; "/sys" ] |>
|
||||
- List.map sysroot_path in
|
||||
- let specfile = sysroot_path specfile in
|
||||
- let path = sysroot_path path in
|
||||
-
|
||||
- let args = ref [] in
|
||||
- if force then List.push_back args "-F";
|
||||
- List.iter (
|
||||
- fun ignored_path ->
|
||||
- List.push_back_list args [ "-e"; ignored_path ]
|
||||
- ) ignored_paths;
|
||||
-
|
||||
- (* You have to use the -m option (where available) otherwise
|
||||
- * setfiles puts all the mountpoints on the excludes list for no
|
||||
- * useful reason (RHBZ#1433577).
|
||||
- *)
|
||||
- if setfiles_has_option_m () then List.push_back args "-m";
|
||||
-
|
||||
- (* Not only do we want setfiles to trudge through individual relabeling
|
||||
- * errors, we also want the setfiles exit status to differentiate a fatal
|
||||
- * error from "relabeling errors only". See RHBZ#1794518.
|
||||
- *)
|
||||
- if setfiles_has_option_C () then List.push_back args "-C";
|
||||
-
|
||||
- (* If the appliance is being run with multiple vCPUs, running setfiles
|
||||
- * in multithreading mode might speeds up the process. Option "-T" was
|
||||
- * introduced in SELinux userspace v3.4, and we need to check whether it's
|
||||
- * supported. Passing "-T 0" creates as many threads as there're available
|
||||
- * vCPU cores.
|
||||
- * https://github.com/SELinuxProject/selinux/releases/tag/3.4
|
||||
- *)
|
||||
- if setfiles_has_option_T () then
|
||||
- List.push_back_list args [ "-T"; "0" ];
|
||||
-
|
||||
- (* Relabelling in a chroot. *)
|
||||
- if sysroot () <> "/" then
|
||||
- List.push_back_list args [ "-r"; sysroot () ];
|
||||
-
|
||||
- if verbose () then
|
||||
- List.push_back args "-v"
|
||||
- else
|
||||
- (* Suppress non-error output. *)
|
||||
- List.push_back args "-q";
|
||||
-
|
||||
- (* Add parameters. *)
|
||||
- List.push_back_list args [ specfile; path ];
|
||||
-
|
||||
- let args = !args in
|
||||
- let r, _, err = commandr "setfiles" args in
|
||||
-
|
||||
- let ok = r = 0 || r = 1 && setfiles_has_option_C () in
|
||||
- if not ok then failwithf "setfiles: %s" err
|
||||
+let setfiles ?(force = false) specfile paths =
|
||||
+ if paths = [] then ()
|
||||
+ else (
|
||||
+ (* Prefix /sysroot on all paths. *)
|
||||
+ let ignored_paths =
|
||||
+ [ "/dev"; "/proc"; "/selinux"; "/sys" ] |>
|
||||
+ List.map sysroot_path in
|
||||
+ let specfile = sysroot_path specfile in
|
||||
+ let paths = List.map sysroot_path paths in
|
||||
+
|
||||
+ let args = ref [] in
|
||||
+ if force then List.push_back args "-F";
|
||||
+ List.iter (
|
||||
+ fun ignored_path ->
|
||||
+ List.push_back_list args [ "-e"; ignored_path ]
|
||||
+ ) ignored_paths;
|
||||
+
|
||||
+ (* You have to use the -m option (where available) otherwise
|
||||
+ * setfiles puts all the mountpoints on the excludes list for no
|
||||
+ * useful reason (RHBZ#1433577).
|
||||
+ *)
|
||||
+ if setfiles_has_option_m () then List.push_back args "-m";
|
||||
+
|
||||
+ (* Not only do we want setfiles to trudge through individual relabeling
|
||||
+ * errors, we also want the setfiles exit status to differentiate a fatal
|
||||
+ * error from "relabeling errors only". See RHBZ#1794518.
|
||||
+ *)
|
||||
+ if setfiles_has_option_C () then List.push_back args "-C";
|
||||
+
|
||||
+ (* If the appliance is being run with multiple vCPUs, running setfiles
|
||||
+ * in multithreading mode might speeds up the process. Option "-T" was
|
||||
+ * introduced in SELinux userspace v3.4, and we need to check whether it's
|
||||
+ * supported. Passing "-T 0" creates as many threads as there're available
|
||||
+ * vCPU cores.
|
||||
+ * https://github.com/SELinuxProject/selinux/releases/tag/3.4
|
||||
+ *)
|
||||
+ if setfiles_has_option_T () then
|
||||
+ List.push_back_list args [ "-T"; "0" ];
|
||||
+
|
||||
+ (* Relabelling in a chroot. *)
|
||||
+ if sysroot () <> "/" then
|
||||
+ List.push_back_list args [ "-r"; sysroot () ];
|
||||
+
|
||||
+ if verbose () then
|
||||
+ List.push_back args "-v"
|
||||
+ else
|
||||
+ (* Suppress non-error output. *)
|
||||
+ List.push_back args "-q";
|
||||
+
|
||||
+ (* Add parameters. *)
|
||||
+ List.push_back args specfile;
|
||||
+ List.push_back_list args paths;
|
||||
+
|
||||
+ let args = !args in
|
||||
+ let r, _, err = commandr "setfiles" args in
|
||||
+
|
||||
+ let ok = r = 0 || r = 1 && setfiles_has_option_C () in
|
||||
+ if not ok then failwithf "setfiles: %s" err
|
||||
+ )
|
||||
+
|
||||
+(* This is the deprecated selinux_relabel function from libguestfs <= 1.56. *)
|
||||
+let selinux_relabel ?force specfile path = setfiles ?force specfile [path]
|
||||
diff --git a/generator/actions_core.ml b/generator/actions_core.ml
|
||||
index 128cbe0e9..60d3140ed 100644
|
||||
--- a/generator/actions_core.ml
|
||||
+++ b/generator/actions_core.ml
|
||||
@@ -9356,29 +9356,6 @@ Show all the devices where the filesystems in C<device> is spanned over.
|
||||
If not all the devices for the filesystems are present, then this function
|
||||
fails and the C<errno> is set to C<ENODEV>." };
|
||||
|
||||
- { defaults with
|
||||
- name = "selinux_relabel"; added = (1, 33, 43);
|
||||
- style = RErr, [String (PlainString, "specfile"); String (Pathname, "path")], [OBool "force"];
|
||||
- impl = OCaml "Selinux.selinux_relabel";
|
||||
- optional = Some "selinuxrelabel";
|
||||
- test_excuse = "tests are in the tests/relabel directory";
|
||||
- shortdesc = "relabel parts of the filesystem";
|
||||
- longdesc = "\
|
||||
-SELinux relabel parts of the filesystem.
|
||||
-
|
||||
-The C<specfile> parameter controls the policy spec file used.
|
||||
-You have to parse C</etc/selinux/config> to find the correct
|
||||
-SELinux policy and then pass the spec file, usually:
|
||||
-C</etc/selinux/> + I<selinuxtype> + C</contexts/files/file_contexts>.
|
||||
-
|
||||
-The required C<path> parameter is the top level directory where
|
||||
-relabelling starts. Normally you should pass C<path> as C</>
|
||||
-to relabel the whole guest filesystem.
|
||||
-
|
||||
-The optional C<force> boolean controls whether the context
|
||||
-is reset for customizable files, and also whether the
|
||||
-user, role and range parts of the file context is changed." };
|
||||
-
|
||||
{ defaults with
|
||||
name = "mksquashfs"; added = (1, 35, 25);
|
||||
style = RErr, [String (Pathname, "path"); String (FileOut, "filename")], [OString "compress"; OStringList "excludes"];
|
||||
@@ -9820,4 +9797,30 @@ them visible.
|
||||
|
||||
Use C<guestfs_list_dm_devices> to list all device mapper devices." };
|
||||
|
||||
+ { defaults with
|
||||
+ name = "setfiles"; added = (1, 57, 1);
|
||||
+ style = RErr, [String (PlainString, "specfile"); StringList (Pathname, "paths")], [OBool "force"];
|
||||
+ impl = OCaml "Selinux.setfiles";
|
||||
+ optional = Some "selinuxrelabel";
|
||||
+ test_excuse = "tests are in the tests/relabel directory";
|
||||
+ shortdesc = "low level relabel parts of the filesystem";
|
||||
+ longdesc = "\
|
||||
+This invokes the SELinux C<setfiles> command which is a low
|
||||
+level tool used to relabel parts of the filesystem.
|
||||
+
|
||||
+The C<specfile> parameter controls the policy spec file used.
|
||||
+You have to parse C</etc/selinux/config> to find the correct
|
||||
+SELinux policy and then pass the spec file, usually:
|
||||
+C</etc/selinux/> + I<selinuxtype> + C</contexts/files/file_contexts>.
|
||||
+
|
||||
+The required C<paths> parameter is the list of top level directories
|
||||
+where relabelling starts. C<setfiles> will only relabel up to
|
||||
+filesystem boundaries so, for example, passing just C<\"/\"> will
|
||||
+relabel the whole root filesystem, but no other mounted filesystems.
|
||||
+If the list is empty, setfiles is not called.
|
||||
+
|
||||
+The optional C<force> boolean controls whether the context
|
||||
+is reset for customizable files, and also whether the
|
||||
+user, role and range parts of the file context is changed." };
|
||||
+
|
||||
]
|
||||
diff --git a/generator/actions_core_deprecated.ml b/generator/actions_core_deprecated.ml
|
||||
index 9d4b29f9d..2b1f5cdb4 100644
|
||||
--- a/generator/actions_core_deprecated.ml
|
||||
+++ b/generator/actions_core_deprecated.ml
|
||||
@@ -942,4 +942,28 @@ This call does nothing and returns an error." };
|
||||
Used to check a btrfs filesystem, C<device> is the device file where the
|
||||
filesystem is stored." };
|
||||
|
||||
+ { defaults with
|
||||
+ name = "selinux_relabel"; added = (1, 33, 43);
|
||||
+ style = RErr, [String (PlainString, "specfile"); String (Pathname, "path")], [OBool "force"];
|
||||
+ impl = OCaml "Selinux.selinux_relabel";
|
||||
+ optional = Some "selinuxrelabel";
|
||||
+ deprecated_by = Replaced_by "setfiles";
|
||||
+ test_excuse = "tests are in the tests/relabel directory";
|
||||
+ shortdesc = "relabel parts of the filesystem";
|
||||
+ longdesc = "\
|
||||
+SELinux relabel parts of the filesystem.
|
||||
+
|
||||
+The C<specfile> parameter controls the policy spec file used.
|
||||
+You have to parse C</etc/selinux/config> to find the correct
|
||||
+SELinux policy and then pass the spec file, usually:
|
||||
+C</etc/selinux/> + I<selinuxtype> + C</contexts/files/file_contexts>.
|
||||
+
|
||||
+The required C<path> parameter is the top level directory where
|
||||
+relabelling starts. Normally you should pass C<path> as C</>
|
||||
+to relabel the whole guest filesystem.
|
||||
+
|
||||
+The optional C<force> boolean controls whether the context
|
||||
+is reset for customizable files, and also whether the
|
||||
+user, role and range parts of the file context is changed." };
|
||||
+
|
||||
]
|
||||
diff --git a/generator/proc_nr.ml b/generator/proc_nr.ml
|
||||
index 63cd72a3c..42624afef 100644
|
||||
--- a/generator/proc_nr.ml
|
||||
+++ b/generator/proc_nr.ml
|
||||
@@ -521,6 +521,7 @@ let proc_nr = [
|
||||
516, "command_out";
|
||||
517, "sh_out";
|
||||
518, "btrfs_scrub_full";
|
||||
+519, "setfiles";
|
||||
]
|
||||
|
||||
(* End of list. If adding a new entry, add it at the end of the list
|
||||
diff --git a/gobject/Makefile.inc b/gobject/Makefile.inc
|
||||
index b54245977..b828113c6 100644
|
||||
--- a/gobject/Makefile.inc
|
||||
+++ b/gobject/Makefile.inc
|
||||
@@ -106,6 +106,7 @@ guestfs_gobject_headers= \
|
||||
include/guestfs-gobject/optargs-rsync_out.h \
|
||||
include/guestfs-gobject/optargs-selinux_relabel.h \
|
||||
include/guestfs-gobject/optargs-set_e2attrs.h \
|
||||
+ include/guestfs-gobject/optargs-setfiles.h \
|
||||
include/guestfs-gobject/optargs-syslinux.h \
|
||||
include/guestfs-gobject/optargs-tar_in.h \
|
||||
include/guestfs-gobject/optargs-tar_out.h \
|
||||
@@ -201,6 +202,7 @@ guestfs_gobject_sources= \
|
||||
src/optargs-rsync_out.c \
|
||||
src/optargs-selinux_relabel.c \
|
||||
src/optargs-set_e2attrs.c \
|
||||
+ src/optargs-setfiles.c \
|
||||
src/optargs-syslinux.c \
|
||||
src/optargs-tar_in.c \
|
||||
src/optargs-tar_out.c \
|
||||
diff --git a/lib/MAX_PROC_NR b/lib/MAX_PROC_NR
|
||||
index 9a26b94d0..08f851b6e 100644
|
||||
--- a/lib/MAX_PROC_NR
|
||||
+++ b/lib/MAX_PROC_NR
|
||||
@@ -1 +1 @@
|
||||
-518
|
||||
+519
|
||||
diff --git a/tests/relabel/test-relabel.pl b/tests/relabel/test-relabel.pl
|
||||
index 06fb0840b..4d4f6c7ba 100755
|
||||
--- a/tests/relabel/test-relabel.pl
|
||||
+++ b/tests/relabel/test-relabel.pl
|
||||
@@ -87,7 +87,7 @@ $g->write ("/etc/file_contexts", <<'EOF');
|
||||
EOF
|
||||
|
||||
# Do the relabel.
|
||||
-$g->selinux_relabel ("/etc/file_contexts", "/", force => 1);
|
||||
+$g->setfiles ("/etc/file_contexts", ["/"], force => 1);
|
||||
|
||||
# Check the labels were set correctly.
|
||||
my $errors = 0;
|
||||
--
|
||||
2.47.3
|
||||
|
||||
@ -1,75 +0,0 @@
|
||||
From b43ca06ea69cebbdd774ed03bc0da63eb3955d66 Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Thu, 14 Aug 2025 14:56:47 +0100
|
||||
Subject: [PATCH] daemon/inspect_fs_windows.ml: Add debugging for MBR drive
|
||||
mappings
|
||||
|
||||
The function 'map_registry_disk_blob_gpt' immediately below this one
|
||||
has a debugging statement. Add the equivalent to the function
|
||||
'map_registry_disk_blob_mbr'.
|
||||
|
||||
The output looks like:
|
||||
|
||||
map_registry_disk_blob_mbr: searching for MBR disk ID 31 32 33 34
|
||||
map_registry_disk_blob_mbr: searching for MBR partition offset 00 00 00 10 00 00 00 00
|
||||
---
|
||||
daemon/inspect_fs_windows.ml | 8 ++++++++
|
||||
daemon/utils.ml | 4 ++++
|
||||
daemon/utils.mli | 4 ++++
|
||||
3 files changed, 16 insertions(+)
|
||||
|
||||
diff --git a/daemon/inspect_fs_windows.ml b/daemon/inspect_fs_windows.ml
|
||||
index dbaf4c362..5991cdba3 100644
|
||||
--- a/daemon/inspect_fs_windows.ml
|
||||
+++ b/daemon/inspect_fs_windows.ml
|
||||
@@ -376,6 +376,10 @@ and map_registry_disk_blob_mbr devices blob =
|
||||
* disk with this disk ID.
|
||||
*)
|
||||
let diskid = String.sub blob 0 4 in
|
||||
+ if verbose () then
|
||||
+ eprintf "map_registry_disk_blob_mbr: searching for MBR disk ID %s\n%!"
|
||||
+ (hex_of_string diskid);
|
||||
+
|
||||
let device =
|
||||
List.find (
|
||||
fun dev ->
|
||||
@@ -388,6 +392,10 @@ and map_registry_disk_blob_mbr devices blob =
|
||||
* partition byte offset from Parted.part_list.
|
||||
*)
|
||||
let offset = String.sub blob 4 8 in
|
||||
+ if verbose () then
|
||||
+ eprintf "map_registry_disk_blob_mbr: searching for MBR partition offset \
|
||||
+ %s\n%!"
|
||||
+ (hex_of_string offset);
|
||||
let offset = int_of_le64 offset in
|
||||
let partitions = Parted.part_list device in
|
||||
let partition =
|
||||
diff --git a/daemon/utils.ml b/daemon/utils.ml
|
||||
index 40584c9f1..3aa1d7ed2 100644
|
||||
--- a/daemon/utils.ml
|
||||
+++ b/daemon/utils.ml
|
||||
@@ -291,3 +291,7 @@ let parse_key_value_strings ?unquote lines =
|
||||
match unquote with
|
||||
| None -> lines
|
||||
| Some f -> List.map (fun (k, v) -> (k, f v)) lines
|
||||
+
|
||||
+let hex_of_string s =
|
||||
+ let bytes = String.map_chars (fun c -> sprintf "%02x" (Char.code c)) s in
|
||||
+ String.concat " " bytes
|
||||
diff --git a/daemon/utils.mli b/daemon/utils.mli
|
||||
index 0f2ae471f..e14735038 100644
|
||||
--- a/daemon/utils.mli
|
||||
+++ b/daemon/utils.mli
|
||||
@@ -121,5 +121,9 @@ val parse_key_value_strings : ?unquote:(string -> string) -> string list -> (str
|
||||
it is applied on the values as unquote function. Empty lines,
|
||||
or that start with a comment character [#], are ignored. *)
|
||||
|
||||
+val hex_of_string : string -> string
|
||||
+(** Return a string as a list of hex bytes.
|
||||
+ Use this for debugging msgs only. *)
|
||||
+
|
||||
(**/**)
|
||||
val get_verbose_flag : unit -> bool
|
||||
--
|
||||
2.47.3
|
||||
|
||||
@ -1,32 +0,0 @@
|
||||
From 7bbadaec5ab9c60bd5ad8e1feee39af9f170b552 Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Thu, 14 Aug 2025 14:57:45 +0100
|
||||
Subject: [PATCH] daemon/inspect_fs_windows.ml: Add debugging when we start
|
||||
registry analysis
|
||||
|
||||
Add some debugging when we begin the process of analyzing the Windows
|
||||
registry of a guest.
|
||||
---
|
||||
daemon/inspect_fs_windows.ml | 6 ++++++
|
||||
1 file changed, 6 insertions(+)
|
||||
|
||||
diff --git a/daemon/inspect_fs_windows.ml b/daemon/inspect_fs_windows.ml
|
||||
index 5991cdba3..00acf5196 100644
|
||||
--- a/daemon/inspect_fs_windows.ml
|
||||
+++ b/daemon/inspect_fs_windows.ml
|
||||
@@ -207,6 +207,12 @@ and check_windows_registry systemroot data =
|
||||
if Is.is_file system_hive then Some system_hive else None in
|
||||
data.windows_system_hive <- system_hive;
|
||||
|
||||
+ if verbose () then
|
||||
+ eprintf "check_windows_registry: software hive: %s\n\
|
||||
+ check_windows_registry: system hive: %s\n%!"
|
||||
+ (Option.value ~default:"None" software_hive)
|
||||
+ (Option.value ~default:"None" system_hive);
|
||||
+
|
||||
match software_hive, system_hive with
|
||||
| None, _ | Some _, None -> ()
|
||||
| Some software_hive, Some system_hive ->
|
||||
--
|
||||
2.47.3
|
||||
|
||||
@ -1,78 +0,0 @@
|
||||
From 42afed95dc6611dc9585ab23134bdcc39a5b75ec Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Thu, 14 Aug 2025 15:17:59 +0100
|
||||
Subject: [PATCH] daemon/inspect_fs_windows.ml: Ignore blank disks in drive
|
||||
mapping
|
||||
|
||||
If HKLM\System\MountedDevices references a blank disk, then when we
|
||||
try to search for the actual backing device we will get an error from
|
||||
parted:
|
||||
|
||||
parted: /dev/sdb: parted exited with status 1: Error: /dev/sdb: unrecognised disk label: Invalid argument
|
||||
|
||||
Just ignore these errors instead of failing inspection.
|
||||
|
||||
Fixes: https://issues.redhat.com/browse/RHEL-108803
|
||||
Reported-by: Ameen Barakat
|
||||
Thanks: Ming Xie
|
||||
---
|
||||
daemon/inspect_fs_windows.ml | 35 ++++++++++++++++++++++++++---------
|
||||
1 file changed, 26 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/daemon/inspect_fs_windows.ml b/daemon/inspect_fs_windows.ml
|
||||
index 00acf5196..ba8ef4ee3 100644
|
||||
--- a/daemon/inspect_fs_windows.ml
|
||||
+++ b/daemon/inspect_fs_windows.ml
|
||||
@@ -389,8 +389,18 @@ and map_registry_disk_blob_mbr devices blob =
|
||||
let device =
|
||||
List.find (
|
||||
fun dev ->
|
||||
- Parted.part_get_parttype dev = "msdos" &&
|
||||
+ try
|
||||
+ Parted.part_get_parttype dev = "msdos" &&
|
||||
pread dev 4 0x01b8 = diskid
|
||||
+ with Unix.Unix_error (EINVAL, "parted", msg) ->
|
||||
+ (* Errors can happen here if the disk is empty. Just ignore
|
||||
+ * them. It means the drive mapping might have missing
|
||||
+ * entries but that's not important. (RHEL-108803)
|
||||
+ *)
|
||||
+ if verbose () then
|
||||
+ eprintf "map_registry_disk_blob_mbr: parted returned: \
|
||||
+ %s (ignored)\n" msg;
|
||||
+ false
|
||||
) devices in
|
||||
|
||||
(* Next 8 bytes are the offset of the partition in bytes(!) given as
|
||||
@@ -428,14 +438,21 @@ and map_registry_disk_blob_gpt partitions blob =
|
||||
let partition =
|
||||
List.find (
|
||||
fun part ->
|
||||
- let partnum = Devsparts.part_to_partnum part in
|
||||
- let device = Devsparts.part_to_dev part in
|
||||
- let typ = Parted.part_get_parttype device in
|
||||
- if typ <> "gpt" then false
|
||||
- else (
|
||||
- let guid = Sfdisk.part_get_gpt_guid device partnum in
|
||||
- String.lowercase_ascii guid = blob_guid
|
||||
- )
|
||||
+ try
|
||||
+ let partnum = Devsparts.part_to_partnum part in
|
||||
+ let device = Devsparts.part_to_dev part in
|
||||
+ let typ = Parted.part_get_parttype device in
|
||||
+ if typ <> "gpt" then false
|
||||
+ else (
|
||||
+ let guid = Sfdisk.part_get_gpt_guid device partnum in
|
||||
+ String.lowercase_ascii guid = blob_guid
|
||||
+ )
|
||||
+ with Unix.Unix_error (EINVAL, "parted", msg) ->
|
||||
+ (* See comment in MBR code above (RHEL-108803) *)
|
||||
+ if verbose () then
|
||||
+ eprintf "map_registry_disk_blob_gpt: parted returned: \
|
||||
+ %s (ignored)\n" msg;
|
||||
+ false
|
||||
) partitions in
|
||||
Some partition
|
||||
with
|
||||
--
|
||||
2.47.3
|
||||
|
||||
@ -1,78 +0,0 @@
|
||||
From 2613e5301b9e484b5e241afeaff96413597eaf7c Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Wed, 3 Dec 2025 11:15:39 +0000
|
||||
Subject: [PATCH] daemon/device-name-translation.c: Fix btrfs volume reverse
|
||||
translation
|
||||
|
||||
Devices associated with btrfs volumes are not reverse-translated
|
||||
(e.g., btrfsvol:/dev/sdX to sdY).
|
||||
|
||||
Forward translation occurs, creating a path mismatch. This causes
|
||||
errors in subsequent btrfs commands.
|
||||
|
||||
Thanks: Arye Yurkovsky
|
||||
(cherry picked from commit c7b204bce3c860c10663fcb9250dd934eaf3390a)
|
||||
---
|
||||
daemon/device-name-translation.c | 36 ++++++++++++++++++++++++++++++++
|
||||
1 file changed, 36 insertions(+)
|
||||
|
||||
diff --git a/daemon/device-name-translation.c b/daemon/device-name-translation.c
|
||||
index cfebc6495..74b8b686e 100644
|
||||
--- a/daemon/device-name-translation.c
|
||||
+++ b/daemon/device-name-translation.c
|
||||
@@ -248,12 +248,17 @@ device_name_translation (const char *device)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+static char *reverse_btrfsvol (const char *device);
|
||||
+
|
||||
char *
|
||||
reverse_device_name_translation (const char *device)
|
||||
{
|
||||
char *ret = NULL;
|
||||
size_t i;
|
||||
|
||||
+ if (STRPREFIX (device, "btrfsvol:"))
|
||||
+ return reverse_btrfsvol (device);
|
||||
+
|
||||
/* Look it up in the cache, and if found return the canonical name.
|
||||
* If not found return a copy of the original string.
|
||||
*/
|
||||
@@ -287,3 +292,34 @@ reverse_device_name_translation (const char *device)
|
||||
|
||||
return ret;
|
||||
}
|
||||
+
|
||||
+/* btrfsvol:/dev/sdX also needs reversing. */
|
||||
+static char *
|
||||
+reverse_btrfsvol (const char *device)
|
||||
+{
|
||||
+ const char prefix[] = "btrfsvol:";
|
||||
+ const char *device_start, *device_end;
|
||||
+ CLEANUP_FREE char *device_name = NULL;
|
||||
+ CLEANUP_FREE char *reversed_device = NULL;
|
||||
+ char *ret;
|
||||
+
|
||||
+ device_start = device + strlen (prefix);
|
||||
+ device_end = strchr (device_start + strlen ("/dev/"), '/');
|
||||
+ device_name = strndup (device_start, device_end - device_start);
|
||||
+ if (device_name == NULL) {
|
||||
+ reply_with_perror ("strndup");
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ reversed_device = reverse_device_name_translation (device_name);
|
||||
+ if (reversed_device == NULL)
|
||||
+ return NULL;
|
||||
+
|
||||
+ /* Construct the final btrfsvol: and return it, caller frees. */
|
||||
+ if (asprintf (&ret, "%s%s%s", prefix, reversed_device, device_end) == -1) {
|
||||
+ reply_with_perror ("asprintf");
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
--
|
||||
2.47.3
|
||||
|
||||
@ -1,87 +0,0 @@
|
||||
From 8613ec938e6670bf2043eed7634a502e59e261a7 Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Thu, 16 Apr 2026 08:06:50 +0100
|
||||
Subject: [PATCH] daemon/listfs.ml: Refactor is_partition_can_hold_filesystem
|
||||
|
||||
Refactor and simplify the function.
|
||||
|
||||
This is just code motion, there is no functional change.
|
||||
|
||||
(cherry picked from commit 88bd07f350407619d4f5fe406c5594b50cf541dd)
|
||||
---
|
||||
daemon/listfs.ml | 53 ++++++++++++++++++++----------------------------
|
||||
1 file changed, 22 insertions(+), 31 deletions(-)
|
||||
|
||||
diff --git a/daemon/listfs.ml b/daemon/listfs.ml
|
||||
index 4c90796ef..067314c47 100644
|
||||
--- a/daemon/listfs.ml
|
||||
+++ b/daemon/listfs.ml
|
||||
@@ -115,43 +115,34 @@ and is_not_partitioned_device device =
|
||||
* Windows Snapshot Partition as well as MBR extended partitions.
|
||||
*)
|
||||
and is_partition_can_hold_filesystem partition =
|
||||
- let device = Devsparts.part_to_dev partition in
|
||||
- let partnum = Devsparts.part_to_partnum partition in
|
||||
- let parttype = Parted.part_get_parttype device in
|
||||
+ let device = Devsparts.part_to_dev partition
|
||||
+ and partnum = Devsparts.part_to_partnum partition in
|
||||
|
||||
- let is_gpt = parttype = "gpt" in
|
||||
- let is_mbr = parttype = "msdos" in
|
||||
- let is_gpt_or_mbr = is_gpt || is_mbr in
|
||||
+ match Parted.part_get_parttype device with
|
||||
+ | "msdos" ->
|
||||
+ if Parted.part_get_mbr_part_type device partnum = "extended" then
|
||||
+ false
|
||||
+ else if partnum = 1 && Utils.has_bogus_mbr device then
|
||||
+ true
|
||||
+ else
|
||||
+ true
|
||||
|
||||
- if is_gpt_or_mbr then (
|
||||
- if is_mbr_extended parttype device partnum then
|
||||
- false
|
||||
- else if is_mbr_bogus parttype device partnum then
|
||||
- true
|
||||
- else if is_mbr then
|
||||
- true
|
||||
- else (
|
||||
- let gpt_type = Sfdisk.part_get_gpt_type device partnum in
|
||||
- match gpt_type with
|
||||
+ | "gpt" ->
|
||||
+ let gpt_type = Sfdisk.part_get_gpt_type device partnum in
|
||||
+ (match gpt_type with
|
||||
(* Windows Logical Disk Manager metadata partition. *)
|
||||
| "5808C8AA-7E8F-42E0-85D2-E1E90434CFB3"
|
||||
- (* Windows Logical Disk Manager data partition. *)
|
||||
- | "AF9B60A0-1431-4F62-BC68-3311714A69AD"
|
||||
- (* Microsoft Reserved Partition. *)
|
||||
- | "E3C9E316-0B5C-4DB8-817D-F92DF00215AE"
|
||||
- (* Windows Snapshot Partition. *)
|
||||
- | "CADDEBF1-4400-4DE8-B103-12117DCF3CCF" -> false
|
||||
+ (* Windows Logical Disk Manager data partition. *)
|
||||
+ | "AF9B60A0-1431-4F62-BC68-3311714A69AD"
|
||||
+ (* Microsoft Reserved Partition. *)
|
||||
+ | "E3C9E316-0B5C-4DB8-817D-F92DF00215AE"
|
||||
+ (* Windows Snapshot Partition. *)
|
||||
+ | "CADDEBF1-4400-4DE8-B103-12117DCF3CCF" -> false
|
||||
| _ -> true
|
||||
- )
|
||||
- )
|
||||
- else true
|
||||
+ )
|
||||
|
||||
-and is_mbr_extended parttype device partnum =
|
||||
- parttype = "msdos" &&
|
||||
- Parted.part_get_mbr_part_type device partnum = "extended"
|
||||
-
|
||||
-and is_mbr_bogus parttype device partnum =
|
||||
- parttype = "msdos" && partnum = 1 && Utils.has_bogus_mbr device
|
||||
+ | _ -> (* unknown or other *)
|
||||
+ true
|
||||
|
||||
(* Use vfs-type to check for a filesystem of some sort of [device].
|
||||
* Appends (device, vfs_type) to the ret parameter (there may be
|
||||
--
|
||||
2.47.3
|
||||
|
||||
@ -1,114 +0,0 @@
|
||||
From 7349b7c5aa58b937394f5a44844238ff38e2f80d Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Thu, 16 Apr 2026 08:34:38 +0100
|
||||
Subject: [PATCH] daemon/listfs.ml: Ignore CHS geometry error from parted
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
parted has an annoying bug where it fails to parse Sun partition
|
||||
tables (still used by Veritas). It tries to check the CHS geometry
|
||||
stored in the header matches the physical CHS geometry, which is a
|
||||
meaningless test.
|
||||
|
||||
In function is_partition_can_hold_filesystem we are only interested in
|
||||
MBR and GPT partition types, so catch and ignore this specific parted
|
||||
error.
|
||||
|
||||
I tested this by adding a Sun disk as a second disk to a Fedora
|
||||
guest and doing inspection. Previously the operation would
|
||||
fail:
|
||||
|
||||
$ guestfish --ro -a /var/tmp/fedora-41.img -a /var/tmp/dump.img -i
|
||||
libguestfs: error: inspect_os: parted exited with status 1: Warning:
|
||||
The disk CHS geometry (205603,255,2) reported by the operating
|
||||
system does not match the geometry stored on the disk label
|
||||
(64887,16,101).
|
||||
|
||||
After this change it succeeds:
|
||||
|
||||
$ guestfish --ro -a /var/tmp/fedora-41.img -a /var/tmp/dump.img -i
|
||||
|
||||
Welcome to guestfish, the guest filesystem shell for
|
||||
editing virtual machine filesystems and disk images.
|
||||
|
||||
Type: ‘help’ for help on commands
|
||||
‘man’ to read the manual
|
||||
‘quit’ to quit the shell
|
||||
|
||||
Operating system: Fedora Linux 41 (Forty One)
|
||||
/dev/sda3 mounted on /
|
||||
/dev/sda2 mounted on /boot
|
||||
|
||||
Fixes: https://redhat.atlassian.net/browse/RHEL-165220
|
||||
(cherry picked from commit 8d83bf2bcf31c5206b6deaa5e993009a85ff174f)
|
||||
---
|
||||
daemon/listfs.ml | 44 ++++++++++++++++++++++++++++----------------
|
||||
1 file changed, 28 insertions(+), 16 deletions(-)
|
||||
|
||||
diff --git a/daemon/listfs.ml b/daemon/listfs.ml
|
||||
index 067314c47..8ca5ca8a8 100644
|
||||
--- a/daemon/listfs.ml
|
||||
+++ b/daemon/listfs.ml
|
||||
@@ -118,30 +118,42 @@ and is_partition_can_hold_filesystem partition =
|
||||
let device = Devsparts.part_to_dev partition
|
||||
and partnum = Devsparts.part_to_partnum partition in
|
||||
|
||||
- match Parted.part_get_parttype device with
|
||||
- | "msdos" ->
|
||||
- if Parted.part_get_mbr_part_type device partnum = "extended" then
|
||||
- false
|
||||
- else if partnum = 1 && Utils.has_bogus_mbr device then
|
||||
- true
|
||||
- else
|
||||
- true
|
||||
+ try
|
||||
+ match Parted.part_get_parttype device with
|
||||
+ | "msdos" ->
|
||||
+ if Parted.part_get_mbr_part_type device partnum = "extended" then
|
||||
+ false
|
||||
+ else if partnum = 1 && Utils.has_bogus_mbr device then
|
||||
+ true
|
||||
+ else
|
||||
+ true
|
||||
|
||||
- | "gpt" ->
|
||||
- let gpt_type = Sfdisk.part_get_gpt_type device partnum in
|
||||
- (match gpt_type with
|
||||
- (* Windows Logical Disk Manager metadata partition. *)
|
||||
- | "5808C8AA-7E8F-42E0-85D2-E1E90434CFB3"
|
||||
+ | "gpt" ->
|
||||
+ let gpt_type = Sfdisk.part_get_gpt_type device partnum in
|
||||
+ (match gpt_type with
|
||||
+ (* Windows Logical Disk Manager metadata partition. *)
|
||||
+ | "5808C8AA-7E8F-42E0-85D2-E1E90434CFB3"
|
||||
(* Windows Logical Disk Manager data partition. *)
|
||||
| "AF9B60A0-1431-4F62-BC68-3311714A69AD"
|
||||
(* Microsoft Reserved Partition. *)
|
||||
| "E3C9E316-0B5C-4DB8-817D-F92DF00215AE"
|
||||
(* Windows Snapshot Partition. *)
|
||||
| "CADDEBF1-4400-4DE8-B103-12117DCF3CCF" -> false
|
||||
- | _ -> true
|
||||
- )
|
||||
+ | _ -> true
|
||||
+ )
|
||||
|
||||
- | _ -> (* unknown or other *)
|
||||
+ | _ -> (* unknown or other *)
|
||||
+ true
|
||||
+
|
||||
+ with
|
||||
+ | Failure msg when String.find msg "CHS geometry" >= 0 ->
|
||||
+ (* Parted has poor handling of "sun" partition types, always
|
||||
+ * issuing a warning because the CHS doesn't match the physical
|
||||
+ * geometry. Ignore this as we don't care about it in this
|
||||
+ * function (RHEL-165220).
|
||||
+ *)
|
||||
+ eprintf "is_partition_can_hold_filesystem: \
|
||||
+ ignoring warning from parted: %s\n%!" msg;
|
||||
true
|
||||
|
||||
(* Use vfs-type to check for a filesystem of some sort of [device].
|
||||
--
|
||||
2.47.3
|
||||
|
||||
@ -7,7 +7,7 @@ set -e
|
||||
# it like this:
|
||||
# ./copy-patches.sh
|
||||
|
||||
rhel_version=10.1
|
||||
rhel_version=10.2
|
||||
|
||||
# Check we're in the right directory.
|
||||
if [ ! -f libguestfs.spec ]; then
|
||||
|
||||
6
gating.yaml
Executable file
6
gating.yaml
Executable file
@ -0,0 +1,6 @@
|
||||
--- !Policy
|
||||
product_versions:
|
||||
- rhel-*
|
||||
decision_context: osci_compose_gate
|
||||
rules:
|
||||
- !PassingTestCaseRule {test_case_name: xen-ci.brew-build.tier1.functional}
|
||||
@ -1,17 +0,0 @@
|
||||
-----BEGIN PGP SIGNATURE-----
|
||||
|
||||
iQJFBAABCgAvFiEE93dPsa0HSn6Mh2fqkXOPc+G3aKAFAmhQPkcRHHJpY2hAYW5u
|
||||
ZXhpYS5vcmcACgkQkXOPc+G3aKBzGBAAnhwMRwtiYaw94nMMhZA+896zxzBDi6Wx
|
||||
YhWiJ7wrlgx7qchP21Y+As4mz5ldDeiFFsFMXXuIBz2m+G73yM1EGbcwxYlpWV+h
|
||||
bSBca5Vd14WFAVX497fWTzcz3UXAvkYmqLJqCliSJ4BdnCuTcCoKK4+sl/F0kwXe
|
||||
F2x0YNaUxCMiuscFhmLIkz1r+RDUyuQfCeb+ilkkdsd+Gugq42CkW5kLxCfy/dn7
|
||||
gSyj/oaYIaE2bsYW39EKXuJX1qb4DlmwZa8JUsYsi9uZGQbwH+gka9XkKVvbSd6Q
|
||||
s7q68xl3DIna7rfIrnLdf/OGcwmPQ0U02Yhfam7tM/4FY2t5hBOSCahBSrZVfuQt
|
||||
Q/QXpXiYzoD/nmgUNHgFqgN1kgm22E/qaqwwbKf6k412NDfF+Ez84sZHCcgJH+LR
|
||||
/eJrp7lde74QxGervdQ5dYmwNBuv5IPrRJA2kWv97wVDqaOlMgpjpmYNTFyxppZm
|
||||
9H2NyI8x+jSZ9KQT0vEjIWpe3Yr5l0zUkLLzLoD7t0DcxTZGVIeHV7n8ITLlK0dH
|
||||
Ki/BmkWqs2p39Izv7IWWBlRV/URVxW5zK4zEvRtTQtFidlaRqAy5oWUrARnmO4Te
|
||||
sT7Y7ZQss9ZJkcz3JF9lh27JCvD4aRW62y4n2zreq7FXPA67YjbsMJ43BLQ7Gek2
|
||||
I0nROw3mmHw=
|
||||
=OxmC
|
||||
-----END PGP SIGNATURE-----
|
||||
BIN
libguestfs.keyring
Normal file
BIN
libguestfs.keyring
Normal file
Binary file not shown.
112
libguestfs.spec
112
libguestfs.spec
@ -13,14 +13,7 @@ ExcludeArch: %{ix86}
|
||||
# we only do a sanity check that kernel/qemu/libvirt/appliance is not
|
||||
# broken. To perform the full test suite, see instructions here:
|
||||
# https://www.redhat.com/archives/libguestfs/2015-September/msg00078.html
|
||||
%if !0%{?rhel}
|
||||
%global test_arches aarch64 %{power64} s390x x86_64
|
||||
%else
|
||||
# RHEL 9 only:
|
||||
# x86-64: "/lib64/libc.so.6: CPU ISA level is lower than required"
|
||||
# (RHBZ#1919389)
|
||||
%global test_arches NONE
|
||||
%endif
|
||||
|
||||
# Trim older changelog entries.
|
||||
# https://lists.fedoraproject.org/pipermail/devel/2013-April/thread.html#181627
|
||||
@ -30,7 +23,7 @@ ExcludeArch: %{ix86}
|
||||
%global verify_tarball_signature 1
|
||||
|
||||
# The source directory.
|
||||
%global source_directory 1.56-stable
|
||||
%global source_directory 1.58-stable
|
||||
|
||||
# Filter perl provides.
|
||||
%{?perl_default_filter}
|
||||
@ -41,8 +34,8 @@ ExcludeArch: %{ix86}
|
||||
Summary: Access and modify virtual machine disk images
|
||||
Name: libguestfs
|
||||
Epoch: 1
|
||||
Version: 1.56.1
|
||||
Release: 6%{?dist}.alma.1
|
||||
Version: 1.58.1
|
||||
Release: 2%{?dist}.alma.1
|
||||
License: LGPL-2.1-or-later
|
||||
|
||||
# Build only for architectures that have a kernel
|
||||
@ -79,31 +72,20 @@ Source7: libguestfs.keyring
|
||||
Source8: copy-patches.sh
|
||||
|
||||
# Patches are maintained in the following repository:
|
||||
# https://github.com/libguestfs/libguestfs/commits/rhel-10.1
|
||||
# https://github.com/libguestfs/libguestfs/commits/rhel-10.2
|
||||
|
||||
# Patches.
|
||||
Patch0001: 0001-appliance-Ignore-sit0-network-device-in-the-guest.patch
|
||||
Patch0002: 0002-lib-libvirt-Debug-error-from-virDomainDestroyFlags.patch
|
||||
Patch0003: 0003-lib-libvirt-Sleep-before-retrying-virDomainDestroyFl.patch
|
||||
Patch0004: 0004-daemon-Add-contents-of-etc-fstab-to-verbose-log.patch
|
||||
Patch0005: 0005-appliance-init-Add-lsblk-and-blkid-output-to-verbose.patch
|
||||
Patch0006: 0006-docs-Fix-dead-ntfs-3g-doc-links.patch
|
||||
Patch0007: 0007-daemon-inspect-check-etc-crypttab-for-dev-mapper.patch
|
||||
Patch0008: 0008-daemon-sysroot-Avoid-double-when-creating-sysroot-pa.patch
|
||||
Patch0009: 0009-daemon-sysroot-Avoid-copying-the-path-every-time-we-.patch
|
||||
Patch0010: 0010-daemon-Reimplement-guestfs_selinux_relabel-in-OCaml.patch
|
||||
Patch0011: 0011-generator-Implement-StringList-for-OCaml-functions.patch
|
||||
Patch0012: 0012-generator-Allow-StringList-Pathname-parameters.patch
|
||||
Patch0013: 0013-daemon-Deprecate-guestfs_selinux_relabel-replace-wit.patch
|
||||
Patch0014: 0014-daemon-inspect_fs_windows.ml-Add-debugging-for-MBR-d.patch
|
||||
Patch0015: 0015-daemon-inspect_fs_windows.ml-Add-debugging-when-we-s.patch
|
||||
Patch0016: 0016-daemon-inspect_fs_windows.ml-Ignore-blank-disks-in-d.patch
|
||||
Patch0017: 0017-RHEL-Disable-unsupported-remote-drive-protocols-RHBZ.patch
|
||||
Patch0018: 0018-RHEL-Reject-use-of-libguestfs-winsupport-features-ex.patch
|
||||
Patch0019: 0019-RHEL-appliance-init-Run-depmod-a-to-rebuild-kernel-m.patch
|
||||
Patch0020: 0020-daemon-device-name-translation.c-Fix-btrfs-volume-re.patch
|
||||
Patch0021: 0021-daemon-listfs.ml-Refactor-is_partition_can_hold_file.patch
|
||||
Patch0022: 0022-daemon-listfs.ml-Ignore-CHS-geometry-error-from-part.patch
|
||||
Patch0001: 0001-generator-daemon.ml-Avoid-not-available-macro-for-OC.patch
|
||||
Patch0002: 0002-RHEL-Disable-unsupported-remote-drive-protocols-RHBZ.patch
|
||||
Patch0003: 0003-RHEL-Reject-use-of-libguestfs-winsupport-features-ex.patch
|
||||
Patch0004: 0004-RHEL-appliance-init-Run-depmod-a-to-rebuild-kernel-m.patch
|
||||
Patch0005: 0005-lib-qemu.c-Use-machine-type-none-when-inspecting-QMP.patch
|
||||
Patch0006: 0006-generator-Fix-description-of-xfs_growfs.patch
|
||||
Patch0007: 0007-generator-Fix-description-of-xfs_info.patch
|
||||
Patch0008: 0008-New-API-xfs_info2.patch
|
||||
Patch0009: 0009-daemon-Reimplement-xfs_info-using-xfs_info2.patch
|
||||
Patch0010: 0010-generator-Deprecate-xfs_info-replaced-by-xfs_info2.patch
|
||||
Patch0011: 0011-tests-disks-debug-qemu.sh-Fix-test-for-update-QMP-te.patch
|
||||
|
||||
BuildRequires: autoconf, automake, libtool, gettext-devel
|
||||
|
||||
@ -130,7 +112,7 @@ BuildRequires: libselinux-utils
|
||||
BuildRequires: libselinux-devel
|
||||
BuildRequires: fuse, fuse-devel
|
||||
BuildRequires: pcre2-devel
|
||||
BuildRequires: libvirt-devel
|
||||
BuildRequires: libvirt-devel >= 11.10.0
|
||||
BuildRequires: gperf
|
||||
BuildRequires: rpm-devel
|
||||
BuildRequires: cpio
|
||||
@ -142,7 +124,7 @@ BuildRequires: unzip
|
||||
BuildRequires: systemd-units
|
||||
BuildRequires: netpbm-progs
|
||||
BuildRequires: icoutils
|
||||
BuildRequires: libvirt-daemon-kvm >= 7.1.0
|
||||
BuildRequires: libvirt-daemon-kvm
|
||||
%if !0%{?rhel}
|
||||
BuildRequires: perl(Expect)
|
||||
%endif
|
||||
@ -154,12 +136,15 @@ BuildRequires: libldm-devel
|
||||
BuildRequires: json-c-devel
|
||||
BuildRequires: systemd-devel
|
||||
BuildRequires: bash-completion
|
||||
%if 0%{?fedora} || 0%{?rhel} >= 11
|
||||
BuildRequires: bash-completion-devel
|
||||
%endif
|
||||
BuildRequires: /usr/bin/ping
|
||||
BuildRequires: curl
|
||||
BuildRequires: xz
|
||||
BuildRequires: zstd
|
||||
BuildRequires: libzstd-devel
|
||||
BuildRequires: /usr/bin/qemu-img
|
||||
BuildRequires: qemu-img >= 7.2.0
|
||||
|
||||
%if 0%{verify_tarball_signature}
|
||||
BuildRequires: gnupg2
|
||||
@ -316,7 +301,7 @@ Requires: systemd-libs%{?_isa}
|
||||
Requires: fuse
|
||||
|
||||
# For core APIs:
|
||||
Requires: /usr/bin/qemu-img
|
||||
Requires: qemu-img
|
||||
Requires: coreutils
|
||||
Requires: grep
|
||||
Requires: tar
|
||||
@ -325,7 +310,7 @@ Requires: tar
|
||||
Requires: xz
|
||||
|
||||
# For qemu direct and libvirt backends.
|
||||
Requires: qemu-kvm-core
|
||||
Requires: qemu-kvm-core >= 7.2.0
|
||||
%if !0%{?rhel}
|
||||
Suggests: qemu-block-curl
|
||||
Suggests: qemu-block-iscsi
|
||||
@ -335,10 +320,10 @@ Suggests: qemu-block-rbd
|
||||
Suggests: qemu-block-ssh
|
||||
%endif
|
||||
Recommends: libvirt-daemon-config-network
|
||||
Requires: libvirt-daemon-driver-qemu >= 7.1.0
|
||||
Requires: libvirt-daemon-driver-qemu >= 11.10.0
|
||||
Requires: libvirt-daemon-driver-secret
|
||||
Requires: libvirt-daemon-driver-storage-core
|
||||
Recommends: passt
|
||||
Requires: passt
|
||||
Requires: (selinux-policy >= 3.11.1-63 if selinux-policy)
|
||||
|
||||
%ifarch aarch64
|
||||
@ -783,6 +768,15 @@ if ! make quickcheck QUICKCHECK_TEST_TOOL_ARGS="-t 1200"; then
|
||||
cat $HOME/.cache/libvirt/qemu/log/*
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# As libvirt is the default backend, test that the direct backend
|
||||
# works too. It's a good place to get test coverage across all the
|
||||
# architectures.
|
||||
if ! LIBGUESTFS_BACKEND=direct \
|
||||
make quickcheck QUICKCHECK_TEST_TOOL_ARGS="-t 1200"; then
|
||||
cat $HOME/.cache/libvirt/qemu/log/*
|
||||
exit 1
|
||||
fi
|
||||
%endif
|
||||
|
||||
|
||||
@ -974,6 +968,18 @@ rm ocaml/html/.gitignore
|
||||
|
||||
|
||||
%files bash-completion
|
||||
%if 0%{?fedora} || 0%{?rhel} >= 11
|
||||
%dir %{bash_completions_dir}
|
||||
%{bash_completions_dir}/guestfish
|
||||
%{bash_completions_dir}/guestmount
|
||||
%{bash_completions_dir}/guestunmount
|
||||
%{bash_completions_dir}/libguestfs-test-tool
|
||||
%{bash_completions_dir}/virt-copy-in
|
||||
%{bash_completions_dir}/virt-copy-out
|
||||
%{bash_completions_dir}/virt-rescue
|
||||
%{bash_completions_dir}/virt-tar-in
|
||||
%{bash_completions_dir}/virt-tar-out
|
||||
%else
|
||||
%dir %{_datadir}/bash-completion/completions
|
||||
%{_datadir}/bash-completion/completions/guestfish
|
||||
%{_datadir}/bash-completion/completions/guestmount
|
||||
@ -984,6 +990,7 @@ rm ocaml/html/.gitignore
|
||||
%{_datadir}/bash-completion/completions/virt-rescue
|
||||
%{_datadir}/bash-completion/completions/virt-tar-in
|
||||
%{_datadir}/bash-completion/completions/virt-tar-out
|
||||
%endif
|
||||
|
||||
|
||||
%files -n ocaml-%{name}
|
||||
@ -1090,16 +1097,25 @@ rm ocaml/html/.gitignore
|
||||
|
||||
|
||||
%changelog
|
||||
* Wed May 06 2026 Eduard Abdullin <eabdullin@almalinux.org> - 1:1.56.1-6.alma.1
|
||||
* Tue Jan 27 2026 Eduard Abdullin <eabdullin@almalinux.org> - 1:1.58.1-2.alma.1
|
||||
- Enable building for ppc64le
|
||||
|
||||
* Fri Apr 17 2026 Richard W.M. Jones <rjones@redhat.com> - 1:1.56.1-6
|
||||
- Fix CHS geometry error for Veritas/Sun partitions
|
||||
resolves: RHEL-169224
|
||||
|
||||
* Mon Mar 09 2026 Richard W.M. Jones <rjones@redhat.com> - 1:1.56.1-4
|
||||
- Fix btrfs volume reverse translation
|
||||
resolves: RHEL-149119
|
||||
* Mon Jan 26 2026 Richard W.M. Jones <rjones@redhat.com> - 1:1.58.1-2
|
||||
- Rebase to libguestfs 1.58.1
|
||||
resolves: RHEL-111240
|
||||
- Synchronize spec file with Fedora
|
||||
- Add new libguestfs ntfs_chmod API
|
||||
resolves: RHEL-113833
|
||||
- Use setfiles -A option if available to reduce memory usage
|
||||
resolves: RHEL-114292
|
||||
- Add -cpu max when testing for KVM via QMP
|
||||
resolves: RHEL-121076
|
||||
- Require passt
|
||||
resolves: RHEL-122315
|
||||
- Add AV and GPOs to inspection info
|
||||
resolves: RHEL-125846
|
||||
- Add new xfs_info2 API
|
||||
resolves: RHEL-143673
|
||||
|
||||
* Thu Aug 14 2025 Richard W.M. Jones <rjones@redhat.com> - 1:1.56.1-3
|
||||
- Rebase to libguestfs 1.56.1
|
||||
|
||||
4
sources
4
sources
@ -1,2 +1,2 @@
|
||||
SHA512 (libguestfs-1.56.1.tar.gz) = 8ec8db8b3de7471c7ab77161fa98349d7b6f88a803ab563f1859606a2ef55737f323b1cf3ef2ebb3055770f4140aabb056f97099ef76fa7ad0f7bd792cc699fc
|
||||
SHA512 (libguestfs.keyring) = 297a15edc7c220222b9f650e0a9361ae132d3f0fed04aeb2237a1d9c3f6dac6f336846434f66480faed72635a33f659e849b052e74b88d1508aeff03f8c9a2ac
|
||||
SHA512 (libguestfs-1.58.1.tar.gz) = 56e8f21592b4c63a14cfaa3255180c3d83bea7d3cc1a404befb121513b7287dd09ae96477b80b3f8794b2cde49febb1909b9716c3b896a313e4445f7f2a5072a
|
||||
SHA512 (libguestfs-1.58.1.tar.gz.sig) = 9d8bca8928bfa360d0d307373676ea587af9e5154ddfd954c70283f3125b397df9294c1504e188bea5a5cfbb4bae9f27cdbacf92bc9a3e8cb05b7c900c0bfac5
|
||||
|
||||
10
tests/run-libguestfs-test-tool.sh
Executable file
10
tests/run-libguestfs-test-tool.sh
Executable file
@ -0,0 +1,10 @@
|
||||
#!/bin/bash -
|
||||
set -e
|
||||
set -x
|
||||
|
||||
# This only makes sure that libguestfs isn't totally broken.
|
||||
|
||||
# Fix libvirt.
|
||||
systemctl restart virtqemud virtsecretd virtstoraged virtnetworkd
|
||||
|
||||
libguestfs-test-tool
|
||||
14
tests/tests.yml
Normal file
14
tests/tests.yml
Normal file
@ -0,0 +1,14 @@
|
||||
# https://fedoraproject.org/wiki/CI/Tests
|
||||
# https://fedoraproject.org/wiki/CI/Standard_Test_Roles
|
||||
- hosts: localhost
|
||||
roles:
|
||||
- role: standard-test-basic
|
||||
tags:
|
||||
- classic
|
||||
required_packages:
|
||||
- libguestfs
|
||||
- libvirt-daemon-kvm
|
||||
tests:
|
||||
- libguestfs-test-tool:
|
||||
dir: .
|
||||
run: ./run-libguestfs-test-tool.sh
|
||||
Loading…
Reference in New Issue
Block a user