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 34949cc..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.1
-
diff --git a/0001-website-Remove-very-old-stable-branches-from-the-ind.patch b/0001-website-Remove-very-old-stable-branches-from-the-ind.patch
new file mode 100644
index 0000000..25726e6
--- /dev/null
+++ b/0001-website-Remove-very-old-stable-branches-from-the-ind.patch
@@ -0,0 +1,31 @@
+From 6b19b97aa6984865a69dcfc4674dc19d8de21e3c Mon Sep 17 00:00:00 2001
+From: "Richard W.M. Jones"
+Date: Fri, 15 Aug 2025 21:37:30 +0100
+Subject: [PATCH] website: Remove very old stable branches from the index page
+
+There's no point linking to anything other than the current stable
+branch.
+---
+ website/index.html.in | 6 +-----
+ 1 file changed, 1 insertion(+), 5 deletions(-)
+
+diff --git a/website/index.html.in b/website/index.html.in
+index 7ce88beb9..71fe5bf9c 100644
+--- a/website/index.html.in
++++ b/website/index.html.in
+@@ -189,11 +189,7 @@ LATEST-VERSION: @PACKAGE_VERSION@
+ Latest development version: @PACKAGE_VERSION@ (released @RELEASE_DATE@).
+ Stable branch:
+
+- 1.56.x,
+- 1.54.x,
+- 1.52.x,
+- 1.50.x,
+- 1.48.x
++ 1.56.x
+
+
+
+--
+2.47.1
+
diff --git a/0002-Update-common-submodule.patch b/0002-Update-common-submodule.patch
new file mode 100644
index 0000000..3e63c3f
--- /dev/null
+++ b/0002-Update-common-submodule.patch
@@ -0,0 +1,170 @@
+From e6f93dfb9f0580bf0f15501e424c99cf3355c4f5 Mon Sep 17 00:00:00 2001
+From: "Richard W.M. Jones"
+Date: Wed, 20 Aug 2025 10:36:48 +0100
+Subject: [PATCH] Update common submodule
+
+Pulls in the commits listed below. This has no effect as all changes
+are confined to the common/mlcustomize subdirectory which we do not
+use or ship.
+
+ Richard W.M. Jones (4):
+ mlcustomize/SELinux_relabel.ml: Add comment
+ mlcustomize/SELinux_relabel.ml: Use new guestfs_setfiles API
+ mlcustomize/SELinux_relabel.ml: Relabel every mountpoint
+ mlcustomize/firstboot.ml: Use quoted string literals for firstboot
+
+ Vadim Rozenfeld (1):
+ Modify the firstboot script to check the scripts execution return status
+---
+ common | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+Submodule common 0e9caa175..7ecf3992b:
+diff --git a/common/mlcustomize/SELinux_relabel.ml b/common/mlcustomize/SELinux_relabel.ml
+index 2f3a09b..f1729e3 100644
+--- a/common/mlcustomize/SELinux_relabel.ml
++++ b/common/mlcustomize/SELinux_relabel.ml
+@@ -1,5 +1,5 @@
+ (* virt-customize
+- * Copyright (C) 2016 Red Hat Inc.
++ * Copyright (C) 2016-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
+@@ -24,6 +24,10 @@ open Printf
+
+ module G = Guestfs
+
++(* XXX A lot of this code could usefully be moved into
++ * [libguestfs.git/daemon/selinux.ml].
++ *)
++
+ let rec relabel (g : G.guestfs) =
+ (* Is the guest using SELinux? (Otherwise this is a no-op). *)
+ if is_selinux_guest g then (
+@@ -109,5 +113,13 @@ and use_setfiles g =
+ g#copy_attributes ~all:true old_specfile specfile
+ );
+
++ (* Get the list of mountpoints, since setfiles does not cross
++ * filesystems (RHEL-108174).
++ *)
++ let mps = g#mountpoints () |>
++ List.map snd |> (* the list of directories *)
++ List.sort compare |> (* sort them for consistency *)
++ Array.of_list in
++
+ (* Relabel everything. *)
+- g#selinux_relabel ~force:true specfile "/"
++ g#setfiles ~force:true specfile mps
+diff --git a/common/mlcustomize/firstboot.ml b/common/mlcustomize/firstboot.ml
+index 6aca4c3..360c33d 100644
+--- a/common/mlcustomize/firstboot.ml
++++ b/common/mlcustomize/firstboot.ml
+@@ -35,8 +35,7 @@ let sanitize_name =
+ module Linux = struct
+ let firstboot_dir = "/usr/lib/virt-sysprep"
+
+- let firstboot_sh = sprintf "\
+-#!/bin/sh -
++ let firstboot_sh = sprintf {|#!/bin/sh -
+
+ ### BEGIN INIT INFO
+ # Provides: virt-sysprep
+@@ -57,14 +56,14 @@ d=%s/scripts
+ d_done=%s/scripts-done
+ logfile=~root/virt-sysprep-firstboot.log
+
+-echo \"$0\" \"$@\" 2>&1 | tee -a $logfile
+-echo \"Scripts dir: $d\" 2>&1 | tee -a $logfile
++echo "$0" "$@" 2>&1 | tee -a $logfile
++echo "Scripts dir: $d" 2>&1 | tee -a $logfile
+
+-if test \"$1\" = \"start\"
++if test "$1" = "start"
+ then
+ mkdir -p $d_done
+ for f in $d/* ; do
+- if test -x \"$f\"
++ if test -x "$f"
+ then
+ # move the script to the 'scripts-done' directory, so it is not
+ # executed again at the next boot
+@@ -75,7 +74,7 @@ then
+ done
+ rm -f $d_done/*
+ fi
+-" firstboot_dir firstboot_dir
++|} firstboot_dir firstboot_dir
+
+ let systemd_target = "multi-user.target"
+
+@@ -282,36 +281,41 @@ module Windows = struct
+ * XXX It would be better to use powershell here. For some ideas see
+ * https://github.com/HCK-CI/HLK-Setup-Scripts/
+ *)
+- let firstboot_script = sprintf "\
+-@echo off
++ let firstboot_script = sprintf {|@echo off
+
+ setlocal EnableDelayedExpansion
+ set firstboot=%s
+-set log=%%firstboot%%\\log.txt
++set log=%%firstboot%%\log.txt
+
+-set scripts=%%firstboot%%\\scripts
+-set scripts_done=%%firstboot%%\\scripts-done
++set scripts=%%firstboot%%\scripts
++set scripts_done=%%firstboot%%\scripts-done
+
+-call :main >> \"%%log%%\" 2>&1
++call :main >> "%%log%%" 2>&1
+ exit /b
+
+ :main
+ echo starting firstboot service
+
+-if not exist \"%%scripts_done%%\" (
+- mkdir \"%%scripts_done%%\"
++if not exist "%%scripts_done%%" (
++ mkdir "%%scripts_done%%"
+ )
+
+ :: Pick the next script to run.
+-for %%%%f in (\"%%scripts%%\"\\*.bat) do (
+- echo running \"%%%%f\"
+- move \"%%%%f\" \"%%scripts_done%%\"
+- pushd \"%%scripts_done%%\"
+- call \"%%%%~nf\"
++for %%%%f in ("%%scripts%%"\*.bat) do (
++ echo running "%%%%f"
++ pushd "%%scripts%%"
++ call "%%%%~nf"
+ set elvl=!errorlevel!
+ echo .... exit code !elvl!
+ popd
+
++ if !elvl! NEQ 249 (
++ echo Script succeeded, moving to scripts-done
++ move "%%%%f" "%%scripts_done%%"
++ ) else (
++ echo Script failed, will retry on next boot
++ )
++
+ :: Reboot the computer. This is necessary to free any locked
+ :: files which may prevent later scripts from running.
+ shutdown /r /t 0 /y
+@@ -323,8 +327,8 @@ for %%%%f in (\"%%scripts%%\"\\*.bat) do (
+
+ :: Fallthrough here if there are no scripts.
+ echo uninstalling firstboot service
+-\"%%firstboot%%\\%s\" -s firstboot uninstall
+-" firstboot_dir_win srvany in
++"%%firstboot%%\%s" -s firstboot uninstall
++|} firstboot_dir_win srvany in
+
+ g#write (firstboot_dir // "firstboot.bat")
+ (String.unix2dos firstboot_script);
+--
+2.47.1
+
diff --git a/0002-lib-libvirt-Debug-error-from-virDomainDestroyFlags.patch b/0002-lib-libvirt-Debug-error-from-virDomainDestroyFlags.patch
deleted file mode 100644
index d0685e2..0000000
--- a/0002-lib-libvirt-Debug-error-from-virDomainDestroyFlags.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From 0a91731356a5bb0ab8eee620fc1fed1656b117f9 Mon Sep 17 00:00:00 2001
-From: "Richard W.M. Jones"
-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.1
-
diff --git a/0003-daemon-selinux.ml-Fix-typo-in-comment.patch b/0003-daemon-selinux.ml-Fix-typo-in-comment.patch
new file mode 100644
index 0000000..745e50e
--- /dev/null
+++ b/0003-daemon-selinux.ml-Fix-typo-in-comment.patch
@@ -0,0 +1,26 @@
+From 91ee98523e364a3052853b330fdd62b3553027d7 Mon Sep 17 00:00:00 2001
+From: "Richard W.M. Jones"
+Date: Wed, 27 Aug 2025 10:41:27 +0100
+Subject: [PATCH] daemon/selinux.ml: Fix typo in comment
+
+Fixes: commit d0d8e6738477148a7b752348f9364a3b8faed67f
+---
+ daemon/selinux.ml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/daemon/selinux.ml b/daemon/selinux.ml
+index db0d71455..ece3a4a14 100644
+--- a/daemon/selinux.ml
++++ b/daemon/selinux.ml
+@@ -74,7 +74,7 @@ let setfiles ?(force = false) specfile paths =
+ 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
++ * in multithreading mode might speed 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.
+--
+2.47.1
+
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 778e106..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.1
-
diff --git a/0017-RHEL-Disable-unsupported-remote-drive-protocols-RHBZ.patch b/0004-RHEL-Disable-unsupported-remote-drive-protocols-RHBZ.patch
similarity index 99%
rename from 0017-RHEL-Disable-unsupported-remote-drive-protocols-RHBZ.patch
rename to 0004-RHEL-Disable-unsupported-remote-drive-protocols-RHBZ.patch
index a141253..da898c4 100644
--- a/0017-RHEL-Disable-unsupported-remote-drive-protocols-RHBZ.patch
+++ b/0004-RHEL-Disable-unsupported-remote-drive-protocols-RHBZ.patch
@@ -1,4 +1,4 @@
-From d1808ea5eb7ad9c38f5f8c5e90d086886300acd8 Mon Sep 17 00:00:00 2001
+From 6345a5b40c93222da6af94b9d4723f175ecf774b 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
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 032c157..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.1
-
diff --git a/0018-RHEL-Reject-use-of-libguestfs-winsupport-features-ex.patch b/0005-RHEL-Reject-use-of-libguestfs-winsupport-features-ex.patch
similarity index 97%
rename from 0018-RHEL-Reject-use-of-libguestfs-winsupport-features-ex.patch
rename to 0005-RHEL-Reject-use-of-libguestfs-winsupport-features-ex.patch
index 29637d7..5e7f523 100644
--- a/0018-RHEL-Reject-use-of-libguestfs-winsupport-features-ex.patch
+++ b/0005-RHEL-Reject-use-of-libguestfs-winsupport-features-ex.patch
@@ -1,4 +1,4 @@
-From f8e4c310bb580e576d4962c395a99278e039fdf4 Mon Sep 17 00:00:00 2001
+From 6d94bb87fe5e39834608586b15feda2ca284f811 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
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 9927ed2..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.1
-
diff --git a/0019-RHEL-appliance-init-Run-depmod-a-to-rebuild-kernel-m.patch b/0006-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 0006-RHEL-appliance-init-Run-depmod-a-to-rebuild-kernel-m.patch
index cb12a60..7ba5b44 100644
--- a/0019-RHEL-appliance-init-Run-depmod-a-to-rebuild-kernel-m.patch
+++ b/0006-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 632ced5b6a599321855d7023170f7e6bef863948 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/0006-docs-Fix-dead-ntfs-3g-doc-links.patch b/0006-docs-Fix-dead-ntfs-3g-doc-links.patch
deleted file mode 100644
index 9bb3e31..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.1
-
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 d8d2c37..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.1
-
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 bfc41fd..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.1
-
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 f82df19..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.1
-
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 d53b776..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.1
-
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 a38d98a..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.1
-
diff --git a/0012-generator-Allow-StringList-Pathname-parameters.patch b/0012-generator-Allow-StringList-Pathname-parameters.patch
deleted file mode 100644
index 6343a38..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.1
-
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 a393125..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.1
-
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 47c4868..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.1
-
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 8a492e3..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.1
-
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 1da6415..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.1
-
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/libguestfs.spec b/libguestfs.spec
index 35b3b24..dc8a1f5 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.57-development
# 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: 3%{?dist}
+Version: 1.57.2
+Release: 1%{?dist}
License: LGPL-2.1-or-later
# Build only for architectures that have a kernel
@@ -77,28 +70,15 @@ 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
+Patch0001: 0001-website-Remove-very-old-stable-branches-from-the-ind.patch
+#Patch0002: 0002-Update-common-submodule.patch
+Patch0003: 0003-daemon-selinux.ml-Fix-typo-in-comment.patch
+Patch0004: 0004-RHEL-Disable-unsupported-remote-drive-protocols-RHBZ.patch
+Patch0005: 0005-RHEL-Reject-use-of-libguestfs-winsupport-features-ex.patch
+Patch0006: 0006-RHEL-appliance-init-Run-depmod-a-to-rebuild-kernel-m.patch
BuildRequires: autoconf, automake, libtool, gettext-devel
@@ -149,6 +129,9 @@ BuildRequires: libldm-devel
BuildRequires: json-c-devel
BuildRequires: systemd-devel
BuildRequires: bash-completion
+%if !0%{?rhel}
+BuildRequires: bash-completion-devel
+%endif
BuildRequires: /usr/bin/ping
BuildRequires: curl
BuildRequires: xz
@@ -969,6 +952,18 @@ rm ocaml/html/.gitignore
%files bash-completion
+%if !0%{?rhel}
+%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
@@ -979,6 +974,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}
@@ -1085,6 +1081,10 @@ rm ocaml/html/.gitignore
%changelog
+* Fri Aug 29 2025 Richard W.M. Jones - 1:1.57.2-1
+- Rebase to libguestfs 1.57.2
+ resolves: RHEL-111240
+
* Thu Aug 14 2025 Richard W.M. Jones - 1:1.56.1-3
- Rebase to libguestfs 1.56.1
resolves: RHEL-81733
diff --git a/sources b/sources
index 046d6b3..91132ae 100644
--- a/sources
+++ b/sources
@@ -1,2 +1,2 @@
-SHA512 (libguestfs-1.56.1.tar.gz) = 8ec8db8b3de7471c7ab77161fa98349d7b6f88a803ab563f1859606a2ef55737f323b1cf3ef2ebb3055770f4140aabb056f97099ef76fa7ad0f7bd792cc699fc
-SHA512 (libguestfs-1.56.1.tar.gz.sig) = 80fcdf73e8a4b453e96b40b8a29d91dcad0418865d8472300f5e1d972f849b0d2cfd0e204bb20b79285471756c9180f259dc4aa10c56cfdf7153ffb1ef646036
+SHA512 (libguestfs-1.57.2.tar.gz) = 3a63c218a755afbc824c158fd9999f75d1b2b4bc2c9b312eaf114414d1694ee5512a43ef806a5720eca83662f7203c5727a802721bc0bc77274e8b5362324fca
+SHA512 (libguestfs-1.57.2.tar.gz.sig) = 660c5ad78b2a1c3066a02445e39eaf894b673afd840d25fe2920514152c20d2b2e7e34a10a0dcaec575ac8ddde9632952fb8fbbad3a99d9aea1b077ba90004e7