From b9f12a4084361e077e45a6a35daec6a98feb6c86 Mon Sep 17 00:00:00 2001 From: Andrew Lukoshko Date: Mon, 8 Jun 2026 13:23:54 +0000 Subject: [PATCH] Sync with a10-beta --- .gitignore | 11 +- ...ore-sit0-network-device-in-the-guest.patch | 29 -- ....ml-Avoid-not-available-macro-for-OC.patch | 42 ++ ...upported-remote-drive-protocols-RHBZ.patch | 32 +- ...bug-error-from-virDomainDestroyFlags.patch | 29 -- ...of-libguestfs-winsupport-features-ex.patch | 4 +- ...p-before-retrying-virDomainDestroyFl.patch | 32 -- ...nit-Run-depmod-a-to-rebuild-kernel-m.patch | 2 +- ...contents-of-etc-fstab-to-verbose-log.patch | 49 --- ...dd-lsblk-and-blkid-output-to-verbose.patch | 47 -- ...achine-type-none-when-inspecting-QMP.patch | 47 ++ 0006-docs-Fix-dead-ntfs-3g-doc-links.patch | 50 --- ...erator-Fix-description-of-xfs_growfs.patch | 33 ++ ...ct-check-etc-crypttab-for-dev-mapper.patch | 178 -------- ...enerator-Fix-description-of-xfs_info.patch | 36 ++ 0008-New-API-xfs_info2.patch | 351 +++++++++++++++ ...void-double-when-creating-sysroot-pa.patch | 42 -- ...Reimplement-xfs_info-using-xfs_info2.patch | 411 ++++++++++++++++++ ...void-copying-the-path-every-time-we-.patch | 49 --- ...ent-guestfs_selinux_relabel-in-OCaml.patch | 406 ----------------- ...ecate-xfs_info-replaced-by-xfs_info2.patch | 80 ++++ ...ement-StringList-for-OCaml-functions.patch | 99 ----- ...g-qemu.sh-Fix-test-for-update-QMP-te.patch | 33 ++ ...Allow-StringList-Pathname-parameters.patch | 83 ---- ...-guestfs_selinux_relabel-replace-wit.patch | 311 ------------- ...s_windows.ml-Add-debugging-for-MBR-d.patch | 75 ---- ...s_windows.ml-Add-debugging-when-we-s.patch | 32 -- ...s_windows.ml-Ignore-blank-disks-in-d.patch | 78 ---- ...me-translation.c-Fix-btrfs-volume-re.patch | 78 ---- ...-Refactor-is_partition_can_hold_file.patch | 87 ---- ...-Ignore-CHS-geometry-error-from-part.patch | 114 ----- copy-patches.sh | 2 +- gating.yaml | 6 + libguestfs-1.56.1.tar.gz.sig | 17 - libguestfs.keyring | Bin 0 -> 2823 bytes libguestfs.spec | 112 +++-- sources | 4 +- tests/run-libguestfs-test-tool.sh | 10 + tests/tests.yml | 14 + 39 files changed, 1158 insertions(+), 1957 deletions(-) delete mode 100644 0001-appliance-Ignore-sit0-network-device-in-the-guest.patch create mode 100644 0001-generator-daemon.ml-Avoid-not-available-macro-for-OC.patch rename 0017-RHEL-Disable-unsupported-remote-drive-protocols-RHBZ.patch => 0002-RHEL-Disable-unsupported-remote-drive-protocols-RHBZ.patch (95%) delete mode 100644 0002-lib-libvirt-Debug-error-from-virDomainDestroyFlags.patch rename 0018-RHEL-Reject-use-of-libguestfs-winsupport-features-ex.patch => 0003-RHEL-Reject-use-of-libguestfs-winsupport-features-ex.patch (96%) delete mode 100644 0003-lib-libvirt-Sleep-before-retrying-virDomainDestroyFl.patch rename 0019-RHEL-appliance-init-Run-depmod-a-to-rebuild-kernel-m.patch => 0004-RHEL-appliance-init-Run-depmod-a-to-rebuild-kernel-m.patch (90%) delete mode 100644 0004-daemon-Add-contents-of-etc-fstab-to-verbose-log.patch delete mode 100644 0005-appliance-init-Add-lsblk-and-blkid-output-to-verbose.patch create mode 100644 0005-lib-qemu.c-Use-machine-type-none-when-inspecting-QMP.patch delete mode 100644 0006-docs-Fix-dead-ntfs-3g-doc-links.patch create mode 100644 0006-generator-Fix-description-of-xfs_growfs.patch delete mode 100644 0007-daemon-inspect-check-etc-crypttab-for-dev-mapper.patch create mode 100644 0007-generator-Fix-description-of-xfs_info.patch create mode 100644 0008-New-API-xfs_info2.patch delete mode 100644 0008-daemon-sysroot-Avoid-double-when-creating-sysroot-pa.patch create mode 100644 0009-daemon-Reimplement-xfs_info-using-xfs_info2.patch delete mode 100644 0009-daemon-sysroot-Avoid-copying-the-path-every-time-we-.patch delete mode 100644 0010-daemon-Reimplement-guestfs_selinux_relabel-in-OCaml.patch create mode 100644 0010-generator-Deprecate-xfs_info-replaced-by-xfs_info2.patch delete mode 100644 0011-generator-Implement-StringList-for-OCaml-functions.patch create mode 100644 0011-tests-disks-debug-qemu.sh-Fix-test-for-update-QMP-te.patch delete mode 100644 0012-generator-Allow-StringList-Pathname-parameters.patch delete mode 100644 0013-daemon-Deprecate-guestfs_selinux_relabel-replace-wit.patch delete mode 100644 0014-daemon-inspect_fs_windows.ml-Add-debugging-for-MBR-d.patch delete mode 100644 0015-daemon-inspect_fs_windows.ml-Add-debugging-when-we-s.patch delete mode 100644 0016-daemon-inspect_fs_windows.ml-Ignore-blank-disks-in-d.patch delete mode 100644 0020-daemon-device-name-translation.c-Fix-btrfs-volume-re.patch delete mode 100644 0021-daemon-listfs.ml-Refactor-is_partition_can_hold_file.patch delete mode 100644 0022-daemon-listfs.ml-Ignore-CHS-geometry-error-from-part.patch create mode 100755 gating.yaml delete mode 100644 libguestfs-1.56.1.tar.gz.sig create mode 100644 libguestfs.keyring create mode 100755 tests/run-libguestfs-test-tool.sh create mode 100644 tests/tests.yml diff --git a/.gitignore b/.gitignore index 415bf79..93a4f26 100644 --- a/.gitignore +++ b/.gitignore @@ -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 diff --git a/0001-appliance-Ignore-sit0-network-device-in-the-guest.patch b/0001-appliance-Ignore-sit0-network-device-in-the-guest.patch deleted file mode 100644 index 371e69b..0000000 --- a/0001-appliance-Ignore-sit0-network-device-in-the-guest.patch +++ /dev/null @@ -1,29 +0,0 @@ -From dc218b25f0bc2704918748e4e8120ec436783e58 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Tue, 24 Jun 2025 14:04:10 +0100 -Subject: [PATCH] appliance: Ignore sit0 network device in the guest - -Reported-by: Srikanth Aithal -Fixed-by: Stefano Brivio -Tested-by: Srikanth Aithal -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 - diff --git a/0001-generator-daemon.ml-Avoid-not-available-macro-for-OC.patch b/0001-generator-daemon.ml-Avoid-not-available-macro-for-OC.patch new file mode 100644 index 0000000..4091d0b --- /dev/null +++ b/0001-generator-daemon.ml-Avoid-not-available-macro-for-OC.patch @@ -0,0 +1,42 @@ +From 07ea5915766d829b62255fb2a94239a28f433159 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +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 + diff --git a/0017-RHEL-Disable-unsupported-remote-drive-protocols-RHBZ.patch b/0002-RHEL-Disable-unsupported-remote-drive-protocols-RHBZ.patch similarity index 95% rename from 0017-RHEL-Disable-unsupported-remote-drive-protocols-RHBZ.patch rename to 0002-RHEL-Disable-unsupported-remote-drive-protocols-RHBZ.patch index 438f3a5..5308aac 100644 --- a/0017-RHEL-Disable-unsupported-remote-drive-protocols-RHBZ.patch +++ b/0002-RHEL-Disable-unsupported-remote-drive-protocols-RHBZ.patch @@ -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" 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 is interpreted as a local file or device. +@@ -343,22 +343,6 @@ F is interpreted as a local file or device. This is the default if the optional protocol parameter is omitted. --=item C +-=item C - -Connect to a remote FTP or HTTP server. -The C parameter must also be supplied - see below. - -See also: L - --=item C +-=item C - -Connect to the iSCSI server. -The C parameter must also be supplied - see below. @@ -203,14 +203,14 @@ index 60d3140ed..d374ffbf8 100644 - -See also: L. - - =item C + =item C Connect to the Network Block Device server. -@@ -382,15 +366,6 @@ The C parameter may be supplied. See below. +@@ -375,15 +359,6 @@ The C parameter may be supplied. See below. See also: L. --=item C +-=item C - -Connect to the Secure Shell (ssh) server. - @@ -222,7 +222,7 @@ index 60d3140ed..d374ffbf8 100644 =back =item C -@@ -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). +@@ -414,10 +386,10 @@ for the protocol is used (see F). =item C @@ -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. 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 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 < -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 - diff --git a/0018-RHEL-Reject-use-of-libguestfs-winsupport-features-ex.patch b/0003-RHEL-Reject-use-of-libguestfs-winsupport-features-ex.patch similarity index 96% rename from 0018-RHEL-Reject-use-of-libguestfs-winsupport-features-ex.patch rename to 0003-RHEL-Reject-use-of-libguestfs-winsupport-features-ex.patch index 8db12a7..70a1b8f 100644 --- a/0018-RHEL-Reject-use-of-libguestfs-winsupport-features-ex.patch +++ b/0003-RHEL-Reject-use-of-libguestfs-winsupport-features-ex.patch @@ -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" 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 () = diff --git a/0003-lib-libvirt-Sleep-before-retrying-virDomainDestroyFl.patch b/0003-lib-libvirt-Sleep-before-retrying-virDomainDestroyFl.patch deleted file mode 100644 index 671a6e7..0000000 --- a/0003-lib-libvirt-Sleep-before-retrying-virDomainDestroyFl.patch +++ /dev/null @@ -1,32 +0,0 @@ -From c7aaa89fba21499fa6ba11e41fdc8de610819a87 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -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 - diff --git a/0019-RHEL-appliance-init-Run-depmod-a-to-rebuild-kernel-m.patch b/0004-RHEL-appliance-init-Run-depmod-a-to-rebuild-kernel-m.patch similarity index 90% rename from 0019-RHEL-appliance-init-Run-depmod-a-to-rebuild-kernel-m.patch rename to 0004-RHEL-appliance-init-Run-depmod-a-to-rebuild-kernel-m.patch index 4081d05..72dfae0 100644 --- a/0019-RHEL-appliance-init-Run-depmod-a-to-rebuild-kernel-m.patch +++ b/0004-RHEL-appliance-init-Run-depmod-a-to-rebuild-kernel-m.patch @@ -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" Date: Tue, 13 May 2025 17:28:25 +0100 Subject: [PATCH] RHEL: appliance/init: Run depmod -a to rebuild kernel module diff --git a/0004-daemon-Add-contents-of-etc-fstab-to-verbose-log.patch b/0004-daemon-Add-contents-of-etc-fstab-to-verbose-log.patch deleted file mode 100644 index b6817a0..0000000 --- a/0004-daemon-Add-contents-of-etc-fstab-to-verbose-log.patch +++ /dev/null @@ -1,49 +0,0 @@ -From f4f84a882468cb7b2dc4c265bdc18a5df79c3d4d Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -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 - diff --git a/0005-appliance-init-Add-lsblk-and-blkid-output-to-verbose.patch b/0005-appliance-init-Add-lsblk-and-blkid-output-to-verbose.patch deleted file mode 100644 index f5cf68b..0000000 --- a/0005-appliance-init-Add-lsblk-and-blkid-output-to-verbose.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 217823da95aad095a1c86a90aa4b1db8d46319e4 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -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 - diff --git a/0005-lib-qemu.c-Use-machine-type-none-when-inspecting-QMP.patch b/0005-lib-qemu.c-Use-machine-type-none-when-inspecting-QMP.patch new file mode 100644 index 0000000..a77013f --- /dev/null +++ b/0005-lib-qemu.c-Use-machine-type-none-when-inspecting-QMP.patch @@ -0,0 +1,47 @@ +From d448d69171b5c1ee14a4eca5dc4964840ba99507 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +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é +(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 + diff --git a/0006-docs-Fix-dead-ntfs-3g-doc-links.patch b/0006-docs-Fix-dead-ntfs-3g-doc-links.patch deleted file mode 100644 index db57b16..0000000 --- a/0006-docs-Fix-dead-ntfs-3g-doc-links.patch +++ /dev/null @@ -1,50 +0,0 @@ -From 701667b6f581a824059c4da50eb4df176decbb82 Mon Sep 17 00:00:00 2001 -From: Cole Robinson -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 may appear as F or F - they were created. In Windows itself this would not be - a problem. - --Bug or feature? You decide: --L -+Bug or feature? You decide. See the relevant entry in the ntfs-3g FAQ: -+L - - C 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 -+L - - 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). See: - --L -+L - - =head3 WINDOWS HIBERNATION AND WINDOWS 8 FAST STARTUP - --- -2.47.3 - diff --git a/0006-generator-Fix-description-of-xfs_growfs.patch b/0006-generator-Fix-description-of-xfs_growfs.patch new file mode 100644 index 0000000..3e5d6fd --- /dev/null +++ b/0006-generator-Fix-description-of-xfs_growfs.patch @@ -0,0 +1,33 @@ +From 43d8a4970bbd908ed4b583335f1f4f42a3f6f354 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +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. +- +-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.|} }; + + { defaults with + name = "rsync"; added = (1, 19, 29); +-- +2.47.3 + diff --git a/0007-daemon-inspect-check-etc-crypttab-for-dev-mapper.patch b/0007-daemon-inspect-check-etc-crypttab-for-dev-mapper.patch deleted file mode 100644 index 87ae01e..0000000 --- a/0007-daemon-inspect-check-etc-crypttab-for-dev-mapper.patch +++ /dev/null @@ -1,178 +0,0 @@ -From 06db19c56c0a4e81596b24a7ab74ed545b422e4c Mon Sep 17 00:00:00 2001 -From: Cole Robinson -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 ---- - 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: -- * -- * > lvcreate LV--test VG--test 32 -- * > 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: -+ * -+ * > lvcreate LV--test VG--test 32 -+ * > 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 - diff --git a/0007-generator-Fix-description-of-xfs_info.patch b/0007-generator-Fix-description-of-xfs_info.patch new file mode 100644 index 0000000..36a8105 --- /dev/null +++ b/0007-generator-Fix-description-of-xfs_info.patch @@ -0,0 +1,36 @@ +From d5daad98cfe254c14f4f4f12348f1589838c36a8 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +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.|} }; + ["mount"; "/dev/sda1"; "/"]; + ["xfs_info"; "/"]], "ret->xfs_blocksize == 4096"), [] + ]; +- shortdesc = "get geometry of XFS filesystem"; ++ shortdesc = "get information about the XFS filesystem"; + longdesc = {|C 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 + diff --git a/0008-New-API-xfs_info2.patch b/0008-New-API-xfs_info2.patch new file mode 100644 index 0000000..4bce713 --- /dev/null +++ b/0008-New-API-xfs_info2.patch @@ -0,0 +1,351 @@ +From aac2ec68202f2913ae6000aa117a8ed5dffbd6bb Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +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 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 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, ++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.|} }; + ] +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 + diff --git a/0008-daemon-sysroot-Avoid-double-when-creating-sysroot-pa.patch b/0008-daemon-sysroot-Avoid-double-when-creating-sysroot-pa.patch deleted file mode 100644 index 41d5726..0000000 --- a/0008-daemon-sysroot-Avoid-double-when-creating-sysroot-pa.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 1e0099671a2cd75e3407fc02cd16584fce3ba4ee Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -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 - diff --git a/0009-daemon-Reimplement-xfs_info-using-xfs_info2.patch b/0009-daemon-Reimplement-xfs_info-using-xfs_info2.patch new file mode 100644 index 0000000..811f5b2 --- /dev/null +++ b/0009-daemon-Reimplement-xfs_info-using-xfs_info2.patch @@ -0,0 +1,411 @@ +From fb77334e1c40ac64535f2e36ee6edbdf54a5a6ac Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +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.|} }; + { 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 + diff --git a/0009-daemon-sysroot-Avoid-copying-the-path-every-time-we-.patch b/0009-daemon-sysroot-Avoid-copying-the-path-every-time-we-.patch deleted file mode 100644 index f378637..0000000 --- a/0009-daemon-sysroot-Avoid-copying-the-path-every-time-we-.patch +++ /dev/null @@ -1,49 +0,0 @@ -From c931ab3bc807cff785b1271c575855f0906e27b3 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -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 - diff --git a/0010-daemon-Reimplement-guestfs_selinux_relabel-in-OCaml.patch b/0010-daemon-Reimplement-guestfs_selinux_relabel-in-OCaml.patch deleted file mode 100644 index f0a54e8..0000000 --- a/0010-daemon-Reimplement-guestfs_selinux_relabel-in-OCaml.patch +++ /dev/null @@ -1,406 +0,0 @@ -From ed40333a23ae8f20ac0360df444d10db369fa6d9 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -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 -- --#include --#include --#include --#include -- --#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 is set to C." }; - { 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 - diff --git a/0010-generator-Deprecate-xfs_info-replaced-by-xfs_info2.patch b/0010-generator-Deprecate-xfs_info-replaced-by-xfs_info2.patch new file mode 100644 index 0000000..82e2b45 --- /dev/null +++ b/0010-generator-Deprecate-xfs_info-replaced-by-xfs_info2.patch @@ -0,0 +1,80 @@ +From 5b3de10b018e891ef7cc7fae0e8b1b32445eb392 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +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. + To find out the maximum number of devices that could be added, + call C.|} }; + +- { 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 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 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 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 + diff --git a/0011-generator-Implement-StringList-for-OCaml-functions.patch b/0011-generator-Implement-StringList-for-OCaml-functions.patch deleted file mode 100644 index 07af1bc..0000000 --- a/0011-generator-Implement-StringList-for-OCaml-functions.patch +++ /dev/null @@ -1,99 +0,0 @@ -From fd4db60cffd9d0ece25a436932aca5411e13b94e Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -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 - diff --git a/0011-tests-disks-debug-qemu.sh-Fix-test-for-update-QMP-te.patch b/0011-tests-disks-debug-qemu.sh-Fix-test-for-update-QMP-te.patch new file mode 100644 index 0000000..670aa32 --- /dev/null +++ b/0011-tests-disks-debug-qemu.sh-Fix-test-for-update-QMP-te.patch @@ -0,0 +1,33 @@ +From 4a5ee2fbcbef5f10b8faf8f8659ba5f82145f42d Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +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 + diff --git a/0012-generator-Allow-StringList-Pathname-parameters.patch b/0012-generator-Allow-StringList-Pathname-parameters.patch deleted file mode 100644 index 8fb52f2..0000000 --- a/0012-generator-Allow-StringList-Pathname-parameters.patch +++ /dev/null @@ -1,83 +0,0 @@ -From e4d9ee3fbc58c5993db0c75c647fdf904c520918 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -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 - diff --git a/0013-daemon-Deprecate-guestfs_selinux_relabel-replace-wit.patch b/0013-daemon-Deprecate-guestfs_selinux_relabel-replace-wit.patch deleted file mode 100644 index 0acc873..0000000 --- a/0013-daemon-Deprecate-guestfs_selinux_relabel-replace-wit.patch +++ /dev/null @@ -1,311 +0,0 @@ -From 1c0b56158aa63359d1e53f7a31b483194f235a34 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -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 is spanned over. - If not all the devices for the filesystems are present, then this function - fails and the C is set to C." }; - -- { 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 parameter controls the policy spec file used. --You have to parse C to find the correct --SELinux policy and then pass the spec file, usually: --C + I + C. -- --The required C parameter is the top level directory where --relabelling starts. Normally you should pass C as C --to relabel the whole guest filesystem. -- --The optional C 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 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 command which is a low -+level tool used to relabel parts of the filesystem. -+ -+The C parameter controls the policy spec file used. -+You have to parse C to find the correct -+SELinux policy and then pass the spec file, usually: -+C + I + C. -+ -+The required C parameter is the list of top level directories -+where relabelling starts. C 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 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 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 parameter controls the policy spec file used. -+You have to parse C to find the correct -+SELinux policy and then pass the spec file, usually: -+C + I + C. -+ -+The required C parameter is the top level directory where -+relabelling starts. Normally you should pass C as C -+to relabel the whole guest filesystem. -+ -+The optional C 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 - diff --git a/0014-daemon-inspect_fs_windows.ml-Add-debugging-for-MBR-d.patch b/0014-daemon-inspect_fs_windows.ml-Add-debugging-for-MBR-d.patch deleted file mode 100644 index 1deb210..0000000 --- a/0014-daemon-inspect_fs_windows.ml-Add-debugging-for-MBR-d.patch +++ /dev/null @@ -1,75 +0,0 @@ -From b43ca06ea69cebbdd774ed03bc0da63eb3955d66 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -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 - diff --git a/0015-daemon-inspect_fs_windows.ml-Add-debugging-when-we-s.patch b/0015-daemon-inspect_fs_windows.ml-Add-debugging-when-we-s.patch deleted file mode 100644 index a49381d..0000000 --- a/0015-daemon-inspect_fs_windows.ml-Add-debugging-when-we-s.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 7bbadaec5ab9c60bd5ad8e1feee39af9f170b552 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -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 - diff --git a/0016-daemon-inspect_fs_windows.ml-Ignore-blank-disks-in-d.patch b/0016-daemon-inspect_fs_windows.ml-Ignore-blank-disks-in-d.patch deleted file mode 100644 index 8d742c1..0000000 --- a/0016-daemon-inspect_fs_windows.ml-Ignore-blank-disks-in-d.patch +++ /dev/null @@ -1,78 +0,0 @@ -From 42afed95dc6611dc9585ab23134bdcc39a5b75ec Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -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 - diff --git a/0020-daemon-device-name-translation.c-Fix-btrfs-volume-re.patch b/0020-daemon-device-name-translation.c-Fix-btrfs-volume-re.patch deleted file mode 100644 index 09f4d20..0000000 --- a/0020-daemon-device-name-translation.c-Fix-btrfs-volume-re.patch +++ /dev/null @@ -1,78 +0,0 @@ -From 2613e5301b9e484b5e241afeaff96413597eaf7c Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -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 - diff --git a/0021-daemon-listfs.ml-Refactor-is_partition_can_hold_file.patch b/0021-daemon-listfs.ml-Refactor-is_partition_can_hold_file.patch deleted file mode 100644 index 4f2aaa6..0000000 --- a/0021-daemon-listfs.ml-Refactor-is_partition_can_hold_file.patch +++ /dev/null @@ -1,87 +0,0 @@ -From 8613ec938e6670bf2043eed7634a502e59e261a7 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -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 - diff --git a/0022-daemon-listfs.ml-Ignore-CHS-geometry-error-from-part.patch b/0022-daemon-listfs.ml-Ignore-CHS-geometry-error-from-part.patch deleted file mode 100644 index 7c088b4..0000000 --- a/0022-daemon-listfs.ml-Ignore-CHS-geometry-error-from-part.patch +++ /dev/null @@ -1,114 +0,0 @@ -From 7349b7c5aa58b937394f5a44844238ff38e2f80d Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -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 - diff --git a/copy-patches.sh b/copy-patches.sh index 8b312fd..8b91c5f 100755 --- a/copy-patches.sh +++ b/copy-patches.sh @@ -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 diff --git a/gating.yaml b/gating.yaml new file mode 100755 index 0000000..309384e --- /dev/null +++ b/gating.yaml @@ -0,0 +1,6 @@ +--- !Policy +product_versions: + - rhel-* +decision_context: osci_compose_gate +rules: + - !PassingTestCaseRule {test_case_name: xen-ci.brew-build.tier1.functional} diff --git a/libguestfs-1.56.1.tar.gz.sig b/libguestfs-1.56.1.tar.gz.sig deleted file mode 100644 index e1b05f5..0000000 --- a/libguestfs-1.56.1.tar.gz.sig +++ /dev/null @@ -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----- diff --git a/libguestfs.keyring b/libguestfs.keyring new file mode 100644 index 0000000000000000000000000000000000000000..bb3eb5537b7c398a10b7e2b26ca00af011d1a73e GIT binary patch literal 2823 zcma*oXEYm(0><$qB7$nPViakqqNG)u+FR_sQdc{DRukabMCqKo^wCkug~Y-bN=ZdDzIiUZ#$40(0^!V6(C-KH79?s=m3cGghyAo z1|dJMm+eiM>Vb)QYy4I#;Xu&Z^B~&YVZ!Whl6YA`T0fY9jOhHw z+Y;*35;Jx(8F=n(3o5j*bNOr3S) zCOp0NiMsuh^>)x<=&*u##pa25u9;{ZZc=y@%)4CE$a$A}A*UQGOC-D04;}dULUfuV z)^qc0R62lhwbK5pAcC9hk{LK2KJQ&jd|seog-6NxEVm_4X)8y7DYjWwHK2eI$lRku zmeq4z0zkjTs4a++z4bu{k^$N0>0MkG^k~>}tQQd>eap=1)cK}mGM_yYhtaPw3u{n! zU9d7X%GZbXT!~-iaePA-_ZF&Sz{>(|!tON<`4C)es{n-Uesd{GoD$><>+YS*e%6$X zv}81ZQEu&BDa*m|%?xc}K? ztXy1dUpQFtxVqa*MT11aG(ZsGE-C15Js>6$2qig`j06Osg@VW_D8Y0f5+LX{5JVpY zpdhDC^oaLZsK??x8DJOWJSw`FnKV|{5~fVJ%k`yWLJxgLVDcRdn^Wa_F@huK2}*V{VwcRgyv*)4g2Qgt1JGlabiOx*7Fj?B<+5~s41Ba znTns*;eGgN*mTv0;L>wfxeCI*{K-s;9kSV!?`oEYYHR#>`F5iO`ZuDJL%yslOO9&w zhbbHM^ngdugCnWhKqq{uTHT9qS(fk}s?L44SS*-LzWFNMdJ_cZV+Pj}Fc0 z$z?*yD| z^ee!4Z%nhXNm_MKw>GfR!|#AT7wI=d8;#FBd0Dn`;z*2sFEnNL=50xc+d7>-sr4hc z1H^ZFsD|Tz3VZsuG#PhW4A#n%$Hvw9zllAj{C|nDDp3Q9IoOo59u_f15UB-d(i^Ft zm}W~GSou3Y2Zae}aUVFWKJ)XZ-FcZ)f7}5VNSmEBezlPwny+1V!c|G1q2)yJu^>SU zBG(uFdMTFhV(LalnV(s$P>l{I_IXET&d9&(TxDa{R*NCzcuMf&q78elSLN9YIaoM7X!j3`9@_C^pJ@OJh;qD77 z`}&Nz_D*Iq6f;t7?Bqxowet8!npZ$`6NXiVD@~AY_g*>B){{F>D1? zN$g|68|pA_wcr~kt)JAUlnukx>iU8KA)f_4{X1&=@-!^E^P8QCNsCiKiUK_F>Xsli+q$Z*{a2b32CMwb3D{%D_`*E!rm9<3xmVE)l89dYVw5nlryxm zap55S(@vrBI7zH^ydCt_O(Ugr9>qJgQm;i{)`fD?)7n|Jj)=c?=qu9x3%|TVwl?!x z?-#a4>J7h7(TrYP9;;VFFnL~q)11l=W{2zM0PM_#^G-;w9~Y(6gf0(xy$5NJB{8G) z2_PZQC}tF@|I|RCJ_Ct6H6l-=E50j$d5Ku9&`{QVe8Z;T+VX2372^TDbVX-o_tL$y zfM36H?e10e)+AoUd;Ar?$c*rS7DBr*maRLN9n|78-|^BE1bP6RW%uVWO+Eh#-^#2q zU1o2OGeEnJe`vc1&bKa=PK5K>MrUoy*4Di*xQ~Hr8YK=ae$S@5;A6m-C*^N>H6QiE z+Z~%eGDDNK_vktjC^nxMUEXZReG3G^_uml$%lONCD~B)o&u@Ar}fQG5;T#E%^U88SI<&z@~yy|THGE%E1PbI z?F^r&ZTiw{?xi@{*DAy6C4z2C)^HACOJ!QTq)OKNiy$F_ao^+$ziBa!`o*phmK_>s za)NY_nGb%M+@h1zb zdfh2x>9W=SlC19X_yB5T8jPIITr(IuajP65y|~iU>niq=mN|NI*0)B&ixQw`dlhcIFP)G9WnV`}K3C{4m}cRO<&1vJ^K5DAVUo*Z<@ zunwMvxU0NO;ORRnw0-LRLg3}q^7?BlO`eOGFQ3pD@ literal 0 HcmV?d00001 diff --git a/libguestfs.spec b/libguestfs.spec index 799da82..992d67e 100644 --- a/libguestfs.spec +++ b/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 - 1:1.56.1-6.alma.1 +* Tue Jan 27 2026 Eduard Abdullin - 1:1.58.1-2.alma.1 - Enable building for ppc64le -* Fri Apr 17 2026 Richard W.M. Jones - 1:1.56.1-6 -- Fix CHS geometry error for Veritas/Sun partitions - resolves: RHEL-169224 - -* Mon Mar 09 2026 Richard W.M. Jones - 1:1.56.1-4 -- Fix btrfs volume reverse translation - resolves: RHEL-149119 +* Mon Jan 26 2026 Richard W.M. Jones - 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 - 1:1.56.1-3 - Rebase to libguestfs 1.56.1 diff --git a/sources b/sources index 1f2b5b1..84556cd 100644 --- a/sources +++ b/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 diff --git a/tests/run-libguestfs-test-tool.sh b/tests/run-libguestfs-test-tool.sh new file mode 100755 index 0000000..d36d5ea --- /dev/null +++ b/tests/run-libguestfs-test-tool.sh @@ -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 diff --git a/tests/tests.yml b/tests/tests.yml new file mode 100644 index 0000000..3809111 --- /dev/null +++ b/tests/tests.yml @@ -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