Rebase to libguestfs 1.57.2

resolves: RHEL-111240
This commit is contained in:
Richard W.M. Jones 2025-08-29 12:53:16 +01:00
parent 5c2ffa1df5
commit de5bba38cf
25 changed files with 263 additions and 1625 deletions

View File

@ -1,29 +0,0 @@
From dc218b25f0bc2704918748e4e8120ec436783e58 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Tue, 24 Jun 2025 14:04:10 +0100
Subject: [PATCH] appliance: Ignore sit0 network device in the guest
Reported-by: Srikanth Aithal <sraithal@amd.com>
Fixed-by: Stefano Brivio <sbrivio@redhat.com>
Tested-by: Srikanth Aithal <sraithal@amd.com>
See-also: https://lists.libguestfs.org/archives/list/guestfs@lists.libguestfs.org/thread/566LAY7RNM7T7EMQQQYIQA2VK5TXETK5/
---
appliance/init | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/appliance/init b/appliance/init
index 5d35a47dd..47eb97dfc 100755
--- a/appliance/init
+++ b/appliance/init
@@ -127,7 +127,7 @@ ip addr add 127.0.0.1/8 brd + dev lo scope host
ip link set dev lo up
if test "$guestfs_network" = 1; then
- iface=$(ls -I all -I default -I lo /proc/sys/net/ipv4/conf)
+ iface=$(ls -I all -I default -I lo -I sit0 /proc/sys/net/ipv4/conf)
# Two workarounds for Ubuntu:
touch /etc/fstab
rm -f /etc/dhcp/dhclient-enter-hooks.d/resolved
--
2.47.1

View File

@ -0,0 +1,31 @@
From 6b19b97aa6984865a69dcfc4674dc19d8de21e3c Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
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@
<a href="download/1.57-development/">Latest development version: <strong>@PACKAGE_VERSION@</strong></a> (released <strong>@RELEASE_DATE@</strong>).<br/>
Stable branch:
<strong>
- <a href="download/1.56-stable/">1.56.x</a>,
- <a href="download/1.54-stable/">1.54.x</a>,
- <a href="download/1.52-stable/">1.52.x</a>,
- <a href="download/1.50-stable/">1.50.x</a>,
- <a href="download/1.48-stable/">1.48.x</a>
+ <a href="download/1.56-stable/">1.56.x</a>
</strong>
</small></em>
</p>
--
2.47.1

View File

@ -0,0 +1,170 @@
From e6f93dfb9f0580bf0f15501e424c99cf3355c4f5 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
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

View File

@ -1,29 +0,0 @@
From 0a91731356a5bb0ab8eee620fc1fed1656b117f9 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Fri, 25 Jul 2025 09:36:35 +0100
Subject: [PATCH] lib: libvirt: Debug error from virDomainDestroyFlags
It's useful to see the error returned from virDomainDestroyFlags, so
make sure this gets written to debug output.
---
lib/launch-libvirt.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/lib/launch-libvirt.c b/lib/launch-libvirt.c
index 55a4ad41c..8dbde5341 100644
--- a/lib/launch-libvirt.c
+++ b/lib/launch-libvirt.c
@@ -2173,6 +2173,10 @@ destroy_domain (guestfs_h *g, virDomainPtr dom, int check_for_errors)
/* Error returned by virDomainDestroyFlags ... */
err = virGetLastError ();
+ if (err && err->code != 0) {
+ debug (g, "virDomainDestroy: %s [code=%d int1=%d]",
+ err->message, err->code, err->int1);
+ }
/* Retry (indefinitely) if we're just waiting for qemu to shut down. See:
* https://www.redhat.com/archives/libvir-list/2016-January/msg00767.html
--
2.47.1

View File

@ -0,0 +1,26 @@
From 91ee98523e364a3052853b330fdd62b3553027d7 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
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

View File

@ -1,32 +0,0 @@
From c7aaa89fba21499fa6ba11e41fdc8de610819a87 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Fri, 25 Jul 2025 09:39:51 +0100
Subject: [PATCH] lib: libvirt: Sleep before retrying virDomainDestroyFlags
This saves us going into a loop if virDomainDestroyFlags keeps
returning -EBUSY quickly, which apparenrly can happen in containers.
The equivalent 'direct' backend code sleeps for 2 seconds in this case.
---
lib/launch-libvirt.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/lib/launch-libvirt.c b/lib/launch-libvirt.c
index 8dbde5341..c690a444a 100644
--- a/lib/launch-libvirt.c
+++ b/lib/launch-libvirt.c
@@ -2181,8 +2181,10 @@ destroy_domain (guestfs_h *g, virDomainPtr dom, int check_for_errors)
/* Retry (indefinitely) if we're just waiting for qemu to shut down. See:
* https://www.redhat.com/archives/libvir-list/2016-January/msg00767.html
*/
- if (err && err->code == VIR_ERR_SYSTEM_ERROR && err->int1 == EBUSY)
+ if (err && err->code == VIR_ERR_SYSTEM_ERROR && err->int1 == EBUSY) {
+ sleep (1);
goto again;
+ }
/* "Domain not found" is not treated as an error. */
if (err && err->code == VIR_ERR_NO_DOMAIN)
--
2.47.1

View File

@ -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" <rjones@redhat.com>
Date: Mon, 29 Jul 2013 14:47:56 +0100
Subject: [PATCH] RHEL: Disable unsupported remote drive protocols

View File

@ -1,49 +0,0 @@
From f4f84a882468cb7b2dc4c265bdc18a5df79c3d4d Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Wed, 30 Jul 2025 10:53:20 +0100
Subject: [PATCH] daemon: Add contents of /etc/fstab to verbose log
Also some mdadm configuration files. This is useful for debugging.
The output looks like this:
info: /etc/fstab in /dev/VG/Root
LABEL=BOOT /boot ext2 default 0 0$
LABEL=ROOT / ext2 default 0 0$
Fixes: https://issues.redhat.com/browse/RHEL-106490
---
daemon/inspect_fs_unix_fstab.ml | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/daemon/inspect_fs_unix_fstab.ml b/daemon/inspect_fs_unix_fstab.ml
index 8e765454a..b4652a39d 100644
--- a/daemon/inspect_fs_unix_fstab.ml
+++ b/daemon/inspect_fs_unix_fstab.ml
@@ -43,6 +43,23 @@ let rec check_fstab ?(mdadm_conf = false) (root_mountable : Mountable.t)
if mdadm_conf then ["/etc/mdadm.conf"; "/etc/mdadm/mdadm.conf"] else [] in
let configfiles = "/etc/fstab" :: mdadmfiles in
+ (* If verbose, dump the contents of each config file as that can be
+ * useful for debugging.
+ *)
+ if verbose () then (
+ List.iter (
+ fun filename ->
+ let sysroot_filename = Sysroot.sysroot_path filename in
+ if Sys.file_exists sysroot_filename then (
+ eprintf "info: %s in %s\n%!"
+ filename (Mountable.to_string root_mountable);
+ let cmd = sprintf "cat -A %s >&2" (quote sysroot_filename) in
+ ignore (Sys.command cmd);
+ eprintf "\n%!"
+ )
+ ) configfiles
+ );
+
with_augeas ~name:"check_fstab_aug"
configfiles (check_fstab_aug mdadm_conf root_mountable os_type)
--
2.47.1

View File

@ -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" <rjones@redhat.com>
Date: Tue, 7 Jul 2015 09:28:03 -0400
Subject: [PATCH] RHEL: Reject use of libguestfs-winsupport features except for

View File

@ -1,47 +0,0 @@
From 217823da95aad095a1c86a90aa4b1db8d46319e4 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Wed, 30 Jul 2025 11:05:17 +0100
Subject: [PATCH] appliance/init: Add lsblk and blkid output to verbose log
This is useful for debugging. The output looks like:
+ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
sda 8:0 0 1G 0 disk
|-sda1 8:1 0 512M 0 part
`-sda2 8:2 0 512M 0 part
|-VG-Root 252:0 0 32M 0 lvm
|-VG-LV1 252:1 0 32M 0 lvm
|-VG-LV2 252:2 0 32M 0 lvm
`-VG-LV3 252:3 0 64M 0 lvm
sdb 8:16 0 4G 0 disk /
+ blkid
/dev/mapper/VG-LV1: UUID="cc8a3437-4169-4b1c-b432-ee8adc563f6d" BLOCK_SIZE="4096" TYPE="ext2"
/dev/sdb: UUID="30c70ddc-d00b-4620-a408-025890e59aa6" BLOCK_SIZE="4096" TYPE="ext2"
/dev/mapper/VG-LV2: UUID="747009aa-e183-46ba-a034-0c437b15cebc" BLOCK_SIZE="1024" TYPE="ext2"
/dev/mapper/VG-Root: LABEL="ROOT" UUID="01234567-0123-0123-0123-012345678902" BLOCK_SIZE="4096" TYPE="ext2"
/dev/sda2: UUID="DfEjc1-wRU6-vh8U-we7U-ivEl-FRwo-rG0ZuL" TYPE="LVM2_member" PARTUUID="184cbb43-02"
/dev/sda1: LABEL="BOOT" UUID="01234567-0123-0123-0123-012345678901" BLOCK_SIZE="4096" TYPE="ext2" PARTUUID="184cbb43-01"
/dev/mapper/VG-LV3: UUID="f9e5dc21-9a2a-45a0-85b0-e2889607139a" BLOCK_SIZE="2048" TYPE="ext2"
Fixes: https://issues.redhat.com/browse/RHEL-106490
---
appliance/init | 2 ++
1 file changed, 2 insertions(+)
diff --git a/appliance/init b/appliance/init
index 47eb97dfc..62526ac77 100755
--- a/appliance/init
+++ b/appliance/init
@@ -184,6 +184,8 @@ if test "$guestfs_verbose" = 1 && test "$guestfs_boot_analysis" != 1; then
ls -lR /dev
cat /proc/mounts
cat /proc/mdstat
+ lsblk
+ blkid
lvm config
lvm pvs
lvm vgs
--
2.47.1

View File

@ -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" <rjones@redhat.com>
Date: Tue, 13 May 2025 17:28:25 +0100
Subject: [PATCH] RHEL: appliance/init: Run depmod -a to rebuild kernel module

View File

@ -1,50 +0,0 @@
From 701667b6f581a824059c4da50eb4df176decbb82 Mon Sep 17 00:00:00 2001
From: Cole Robinson <crobinso@redhat.com>
Date: Thu, 31 Jul 2025 15:27:38 -0400
Subject: [PATCH] docs: Fix dead ntfs-3g doc links
---
generator/actions_core.ml | 4 ++--
lib/guestfs.pod | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/generator/actions_core.ml b/generator/actions_core.ml
index 0f39fd509..108494ece 100644
--- a/generator/actions_core.ml
+++ b/generator/actions_core.ml
@@ -4661,8 +4661,8 @@ as F<C:\\windows> may appear as F</WINDOWS> or F</windows>
they were created. In Windows itself this would not be
a problem.
-Bug or feature? You decide:
-L<https://www.tuxera.com/community/ntfs-3g-faq/#posixfilenames1>
+Bug or feature? You decide. See the relevant entry in the ntfs-3g FAQ:
+L<https://github.com/tuxera/ntfs-3g/wiki/NTFS-3G-FAQ>
C<guestfs_case_sensitive_path> attempts to resolve the true case of
each element in the path. It will return a resolved path if either the
diff --git a/lib/guestfs.pod b/lib/guestfs.pod
index f69d5a070..505978aa1 100644
--- a/lib/guestfs.pod
+++ b/lib/guestfs.pod
@@ -984,7 +984,7 @@ Ntfs-3g tries to rewrite "Junction Points" and NTFS "symbolic links"
to provide something which looks like a Linux symlink. The way it
tries to do the rewriting is described here:
-L<http://www.tuxera.com/community/ntfs-3g-advanced/junction-points-and-symbolic-links/>
+L<https://github.com/tuxera/ntfs-3g/wiki/Junctions-Points,-Symbolic-Links-and-Reparse-Points>
The essential problem is that ntfs-3g simply does not have enough
information to do a correct job. NTFS links can contain drive letters
@@ -1003,7 +1003,7 @@ format documented in various places around the web).
There are other useful extended attributes that can be read from
ntfs-3g filesystems (using L</guestfs_getxattr>). See:
-L<http://www.tuxera.com/community/ntfs-3g-advanced/extended-attributes/>
+L<https://github.com/tuxera/ntfs-3g/wiki/Using-Extended-Attributes>
=head3 WINDOWS HIBERNATION AND WINDOWS 8 FAST STARTUP
--
2.47.1

View File

@ -1,178 +0,0 @@
From 06db19c56c0a4e81596b24a7ab74ed545b422e4c Mon Sep 17 00:00:00 2001
From: Cole Robinson <crobinso@redhat.com>
Date: Thu, 12 Jun 2025 14:42:33 -0400
Subject: [PATCH] daemon: inspect: check /etc/crypttab for /dev/mapper/*
Encrypted root fs on SUSE distros will present itself like so:
```
/dev/mapper/cr_root / btrfs defaults 0 0
UUID=588905f9-bfa4-47b5-9fe8-893cb8ad4a0b /var btrfs subvol=/@/var 0 0
... more subvols here ...
UUID=8a278363-3042-4dea-a878-592f5e1b7381 swap btrfs defaults 0 0
/dev/mapper/cr_root /.snapshots btrfs subvol=/@/.snapshots 0 0
cr_root UUID=5289379a-a707-41b5-994c-c383f7ed54cc none x-initrd.attach
```
This breaks `-i` inspection, since libguestfs doesn't know what
/dev/mapper/cr_root is supposed to be, and nothing in the appliance
will autopopulate that path. This isn't a problem on Fedora, where
it uses UUID= instead of a /dev/mapper path.
Currently when we see /dev/mapper as a mount prefix, we only attempt
to do some LVM name mapping. This extends libguestfs to check
/etc/crypttab first. If we find an entry for the mapper path, and it
points to the encrypted luks UUID, we use that UUID to build the
associated /dev/disk/by-id/dm-uuid-CRYPT-* path, which is a symlink
to the unencrypted /dev/dm-X path
Resolves: https://issues.redhat.com/browse/RHEL-93584
Signed-off-by: Cole Robinson <crobinso@redhat.com>
---
daemon/inspect_fs_unix_fstab.ml | 93 +++++++++++++++++++++++++--------
1 file changed, 70 insertions(+), 23 deletions(-)
diff --git a/daemon/inspect_fs_unix_fstab.ml b/daemon/inspect_fs_unix_fstab.ml
index b4652a39d..bd1b8e540 100644
--- a/daemon/inspect_fs_unix_fstab.ml
+++ b/daemon/inspect_fs_unix_fstab.ml
@@ -41,7 +41,7 @@ let rec check_fstab ?(mdadm_conf = false) (root_mountable : Mountable.t)
os_type =
let mdadmfiles =
if mdadm_conf then ["/etc/mdadm.conf"; "/etc/mdadm/mdadm.conf"] else [] in
- let configfiles = "/etc/fstab" :: mdadmfiles in
+ let configfiles = "/etc/fstab" :: "/etc/crypttab" :: mdadmfiles in
(* If verbose, dump the contents of each config file as that can be
* useful for debugging.
@@ -179,7 +179,7 @@ and check_fstab_entry md_map root_mountable os_type aug entry =
root_mountable
(* Resolve guest block device names. *)
else if String.starts_with "/dev/" spec then
- resolve_fstab_device spec md_map os_type
+ resolve_fstab_device spec md_map os_type aug
(* In OpenBSD's fstab you can specify partitions
* on a disk by appending a period and a partition
* letter to a Disklable Unique Identifier. The
@@ -194,7 +194,7 @@ and check_fstab_entry md_map root_mountable os_type aug entry =
* assume that this is the first disk.
*)
let device = sprintf "/dev/sd0%c" part in
- resolve_fstab_device device md_map os_type
+ resolve_fstab_device device md_map os_type aug
)
(* Ignore "/.swap" (Pardus) and pseudo-devices
* like "tmpfs". If we haven't resolved the device
@@ -353,7 +353,7 @@ and parse_md_uuid uuid =
* the real VM, which is a reasonable assumption to make. Return
* anything we don't recognize unchanged.
*)
-and resolve_fstab_device spec md_map os_type =
+and resolve_fstab_device spec md_map os_type aug =
(* In any case where we didn't match a device pattern or there was
* another problem, return this default mountable derived from [spec].
*)
@@ -366,7 +366,7 @@ and resolve_fstab_device spec md_map os_type =
if String.starts_with "/dev/mapper" spec then (
debug_matching "/dev/mapper";
- resolve_dev_mapper spec default
+ resolve_dev_mapper spec default aug
)
else if PCRE.matches re_xdev spec then (
@@ -540,24 +540,71 @@ and resolve_fstab_device spec md_map os_type =
default
)
-and resolve_dev_mapper spec default =
- (* LVM2 does some strange munging on /dev/mapper paths for VGs and
- * LVs which contain '-' character:
- *
- * ><fs> lvcreate LV--test VG--test 32
- * ><fs> debug ls /dev/mapper
- * VG----test-LV----test
- *
- * This makes it impossible to reverse those paths directly, so
- * we have implemented lvm_canonical_lv_name in the daemon.
- *)
- try
- match Lvm_utils.lv_canonical spec with
- | None -> default
- | Some device -> Mountable.of_device device
- with
- (* Ignore devices that don't exist. (RHBZ#811872) *)
- | Unix.Unix_error (Unix.ENOENT, _, _) -> default
+and resolve_dev_mapper spec default aug =
+ let augpath =
+ sprintf "/files/etc/crypttab/*[target='%s']/device"
+ (Filename.basename spec) in
+ match aug_get_noerrors aug augpath with
+ | Some device ->
+ (* /dev/mapper name is present in /etc/crypttab *)
+ if verbose() then eprintf "mapped to crypttab device=%s\n%!" device;
+ (* device string is one of:
+ * + UUID=... without any shell quoting
+ * + An absolute path
+ *)
+ if String.starts_with "UUID=" device then (
+ (* We found the UUID for the encrypted LUKS partition, now we use
+ * that to get the unencrypted /dev/dm-X via
+ * /dev/disk/by-id/dm-uuid-CRYPT-* automagic paths. The format is
+ *
+ * /dev/disk/by-id/dm-uuid-CRYPT-$TYPE-$LUKSUUID-$DMNAME
+ *
+ * The fields are
+ * + $TYPE: `LUKS1` or `LUKS2`
+ * + $LUKSUUID: The UUID we got from crypttab, but with `-` removed
+ * + $DMNAME: this would be `cr_root` for `/dev/mapper/cr_root`, but
+ * we just ignore that.
+ *)
+ let byid_dir = "/dev/disk/by-id" in
+ let uuid = String.sub device 5 (String.length device - 5) in
+ let short_uuid = String.replace uuid "-" "" in
+ let regstr = sprintf "^dm-uuid-CRYPT-LUKS.-%s-.*$" short_uuid in
+ let re_dmcrypt = PCRE.compile regstr in
+ let entries = Sys.readdir byid_dir |> Array.to_list in
+ try
+ let filename = List.find (fun f -> PCRE.matches re_dmcrypt f) entries in
+ let fullpath = Filename.concat byid_dir filename in
+ let resolved_path = Unix_utils.Realpath.realpath fullpath in
+ eprintf("Found crypttab mapping %s -> %s\n%!") fullpath resolved_path;
+ Mountable.of_device (resolved_path)
+ with
+ Failure _ | Not_found ->
+ eprintf("Failed to find matching regex %s/%s\n%!") byid_dir regstr;
+ Mountable.of_device spec
+ ) else (
+ Mountable.of_device spec
+ )
+ | None ->
+ (* Assume /dev/mapper device is LVM *)
+
+ (* LVM2 does some strange munging on /dev/mapper paths for VGs and
+ * LVs which contain '-' character:
+ *
+ * ><fs> lvcreate LV--test VG--test 32
+ * ><fs> debug ls /dev/mapper
+ * VG----test-LV----test
+ *
+ * This makes it impossible to reverse those paths directly, so
+ * we have implemented lvm_canonical_lv_name in the daemon.
+ *)
+ try
+ match Lvm_utils.lv_canonical spec with
+ | None -> default
+ | Some device -> Mountable.of_device device
+ with
+ (* Ignore devices that don't exist. (RHBZ#811872) *)
+ | Unix.Unix_error (Unix.ENOENT, _, _) -> default
+
(* type: (h|s|v|xv)
* disk: [a-z]+
--
2.47.1

View File

@ -1,42 +0,0 @@
From 1e0099671a2cd75e3407fc02cd16584fce3ba4ee Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Tue, 12 Aug 2025 13:04:45 +0100
Subject: [PATCH] daemon: sysroot: Avoid double-/ when creating sysroot paths
in OCaml
Previously calling 'sysroot_path "/dev"' for example would return the
string "/sysroot//dev". While this is not wrong, it confuses some
external programs (hello, setfiles), and it's not very "clean". Be a
bit more careful to avoid doubling the '/' character in the common case.
---
daemon/sysroot.ml | 6 +++++-
daemon/sysroot.mli | 2 +-
2 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/daemon/sysroot.ml b/daemon/sysroot.ml
index 286d125b9..57e727066 100644
--- a/daemon/sysroot.ml
+++ b/daemon/sysroot.ml
@@ -20,4 +20,8 @@ open Std_utils
external sysroot : unit -> string = "guestfs_int_daemon_sysroot"
-let sysroot_path path = sysroot () // path
+let sysroot_path path =
+ let sysroot = sysroot () in
+ if path = "" then sysroot
+ else if path.[0] = '/' then sysroot ^ path
+ else sysroot // path
diff --git a/daemon/sysroot.mli b/daemon/sysroot.mli
index 7f8970cd8..1e6e75902 100644
--- a/daemon/sysroot.mli
+++ b/daemon/sysroot.mli
@@ -22,4 +22,4 @@ val sysroot : unit -> string
in default. *)
val sysroot_path : string -> string
-(** Equivalent to calling [sysroot () // path] *)
+(** Prepend [path] parameter with the sysroot. *)
--
2.47.1

View File

@ -1,49 +0,0 @@
From c931ab3bc807cff785b1271c575855f0906e27b3 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Tue, 12 Aug 2025 13:09:16 +0100
Subject: [PATCH] daemon: sysroot: Avoid copying the path every time we call
sysroot ()
This path never changes once the daemon has started up, so we don't
need to call into C code and copy the string every time.
---
daemon/sysroot-c.c | 4 ++--
daemon/sysroot.ml | 5 ++++-
2 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/daemon/sysroot-c.c b/daemon/sysroot-c.c
index ad31d36ee..e664232b0 100644
--- a/daemon/sysroot-c.c
+++ b/daemon/sysroot-c.c
@@ -28,10 +28,10 @@
#include "daemon.h"
-extern value guestfs_int_daemon_sysroot (value unitv);
+extern value guestfs_int_daemon_get_sysroot (value unitv);
value
-guestfs_int_daemon_sysroot (value unitv)
+guestfs_int_daemon_get_sysroot (value unitv)
{
return caml_copy_string (sysroot);
}
diff --git a/daemon/sysroot.ml b/daemon/sysroot.ml
index 57e727066..35ae11f3f 100644
--- a/daemon/sysroot.ml
+++ b/daemon/sysroot.ml
@@ -18,7 +18,10 @@
open Std_utils
-external sysroot : unit -> string = "guestfs_int_daemon_sysroot"
+external get_sysroot : unit -> string = "guestfs_int_daemon_get_sysroot"
+
+let sysroot = lazy (get_sysroot ())
+let sysroot () = Lazy.force sysroot
let sysroot_path path =
let sysroot = sysroot () in
--
2.47.1

View File

@ -1,406 +0,0 @@
From ed40333a23ae8f20ac0360df444d10db369fa6d9 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Tue, 12 Aug 2025 12:22:42 +0100
Subject: [PATCH] daemon: Reimplement guestfs_selinux_relabel in OCaml
No change, just reimplement the existing C implementation in OCaml.
---
.gitignore | 1 +
daemon/Makefile.am | 4 +-
daemon/selinux-relabel.c | 169 --------------------------------------
daemon/selinux.c | 7 ++
daemon/selinux.ml | 101 +++++++++++++++++++++++
docs/C_SOURCE_FILES | 1 -
generator/actions_core.ml | 1 +
po/POTFILES | 1 -
8 files changed, 113 insertions(+), 172 deletions(-)
delete mode 100644 daemon/selinux-relabel.c
create mode 100644 daemon/selinux.ml
diff --git a/.gitignore b/.gitignore
index 81cd278cc..02160caff 100644
--- a/.gitignore
+++ b/.gitignore
@@ -108,6 +108,7 @@ Makefile.in
/daemon/parted.mli
/daemon/realpath.mli
/daemon/rpm.mli
+/daemon/selinux.mli
/daemon/sfdisk.mli
/daemon/stamp-guestfsd.pod
/daemon/statvfs.mli
diff --git a/daemon/Makefile.am b/daemon/Makefile.am
index 6d7492013..c644d9881 100644
--- a/daemon/Makefile.am
+++ b/daemon/Makefile.am
@@ -59,6 +59,7 @@ generator_built = \
parted.mli \
realpath.mli \
rpm.mli \
+ selinux.mli \
sfdisk.mli \
statvfs.mli \
structs.ml \
@@ -173,7 +174,6 @@ guestfsd_SOURCES = \
rsync.c \
scrub.c \
selinux.c \
- selinux-relabel.c \
sfdisk.c \
sh.c \
sleep.c \
@@ -307,6 +307,7 @@ SOURCES_MLI = \
parted.mli \
realpath.mli \
rpm.mli \
+ selinux.mli \
sfdisk.mli \
statvfs.mli \
structs.mli \
@@ -345,6 +346,7 @@ SOURCES_ML = \
listfs.ml \
realpath.ml \
statvfs.ml \
+ selinux.ml \
inspect_types.ml \
inspect_utils.ml \
inspect_fs_unix_fstab.ml \
diff --git a/daemon/selinux-relabel.c b/daemon/selinux-relabel.c
deleted file mode 100644
index cfc5a31d9..000000000
--- a/daemon/selinux-relabel.c
+++ /dev/null
@@ -1,169 +0,0 @@
-/* libguestfs - the guestfsd daemon
- * Copyright (C) 2016 Red Hat Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include <config.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/stat.h>
-
-#include "guestfs_protocol.h"
-#include "daemon.h"
-#include "actions.h"
-#include "optgroups.h"
-
-#include "ignore-value.h"
-
-#define MAX_ARGS 64
-
-int
-optgroup_selinuxrelabel_available (void)
-{
- return prog_exists ("setfiles");
-}
-
-static int
-dir_exists (const char *dir)
-{
- struct stat statbuf;
-
- if (stat (dir, &statbuf) == 0 && S_ISDIR (statbuf.st_mode))
- return 1;
- else
- return 0;
-}
-
-static int
-setfiles_has_option (int *flag, char opt_char)
-{
- CLEANUP_FREE char *err = NULL;
-
- if (*flag == -1) {
- char option[] = { '-', opt_char, '\0' }; /* "-X" */
- char err_opt[32]; /* "invalid option -- 'X'" */
-
- snprintf(err_opt, sizeof(err_opt), "invalid option -- '%c'", opt_char);
- ignore_value (command (NULL, &err, "setfiles", option, NULL));
- *flag = err && strstr (err, /* "invalid option -- " */ err_opt) == NULL;
- }
-
- return *flag;
-}
-
-/* Takes optional arguments, consult optargs_bitmask. */
-int
-do_selinux_relabel (const char *specfile, const char *path,
- int force)
-{
- static int flag_m = -1;
- static int flag_C = -1;
- static int flag_T = -1;
- const char *argv[MAX_ARGS];
- CLEANUP_FREE char *s_dev = NULL, *s_proc = NULL, *s_selinux = NULL,
- *s_sys = NULL, *s_specfile = NULL, *s_path = NULL;
- CLEANUP_FREE char *err = NULL;
- size_t i = 0;
- int setfiles_status;
-
- s_dev = sysroot_path ("/dev");
- if (!s_dev) {
- malloc_error:
- reply_with_perror ("malloc");
- return -1;
- }
- s_proc = sysroot_path ("/proc"); if (!s_proc) goto malloc_error;
- s_selinux = sysroot_path ("/selinux"); if (!s_selinux) goto malloc_error;
- s_sys = sysroot_path ("/sys"); if (!s_sys) goto malloc_error;
- s_specfile = sysroot_path (specfile); if (!s_specfile) goto malloc_error;
- s_path = sysroot_path (path); if (!s_path) goto malloc_error;
-
- /* Default settings if not selected. */
- if (!(optargs_bitmask & GUESTFS_SELINUX_RELABEL_FORCE_BITMASK))
- force = 0;
-
- /* If setfiles takes an excessively long time to run (but still
- * completes) then removing .../contexts/files/file_contexts.bin
- * appears to help. If you find any such cases, please add
- * observations to the bug report:
- * https://bugzilla.redhat.com/show_bug.cgi?id=1396297
- */
- ADD_ARG (argv, i, "setfiles");
- if (force)
- ADD_ARG (argv, i, "-F");
-
- /* Exclude some directories that should never be relabelled in
- * ordinary Linux guests. These won't be mounted anyway. We have
- * to prefix all these with the sysroot path.
- */
- ADD_ARG (argv, i, "-e"); ADD_ARG (argv, i, s_dev);
- ADD_ARG (argv, i, "-e"); ADD_ARG (argv, i, s_proc);
- ADD_ARG (argv, i, "-e"); ADD_ARG (argv, i, s_sys);
- if (dir_exists (s_selinux)) {
- ADD_ARG (argv, i, "-e"); ADD_ARG (argv, i, s_selinux);
- }
-
- /* You have to use the -m option (where available) otherwise
- * setfiles puts all the mountpoints on the excludes list for no
- * useful reason (RHBZ#1433577).
- */
- if (setfiles_has_option (&flag_m, 'm'))
- ADD_ARG (argv, i, "-m");
-
- /* Not only do we want setfiles to trudge through individual relabeling
- * errors, we also want the setfiles exit status to differentiate a fatal
- * error from "relabeling errors only". See RHBZ#1794518.
- */
- if (setfiles_has_option (&flag_C, 'C'))
- ADD_ARG (argv, i, "-C");
-
- /* If the appliance is being run with multiple vCPUs, running setfiles
- * in multithreading mode might speeds up the process. Option "-T" was
- * introduced in SELinux userspace v3.4, and we need to check whether it's
- * supported. Passing "-T 0" creates as many threads as there're available
- * vCPU cores.
- * https://github.com/SELinuxProject/selinux/releases/tag/3.4
- */
- if (setfiles_has_option (&flag_T, 'T')) {
- ADD_ARG (argv, i, "-T"); ADD_ARG (argv, i, "0");
- }
-
- /* Relabelling in a chroot. */
- if (STRNEQ (sysroot, "/")) {
- ADD_ARG (argv, i, "-r");
- ADD_ARG (argv, i, sysroot);
- }
-
- if (verbose)
- ADD_ARG (argv, i, "-v");
- else
- /* Suppress non-error output. */
- ADD_ARG (argv, i, "-q");
-
- /* Add parameters. */
- ADD_ARG (argv, i, s_specfile);
- ADD_ARG (argv, i, s_path);
- ADD_ARG (argv, i, NULL);
-
- setfiles_status = commandrv (NULL, &err, argv);
- if ((setfiles_status == 0) || (setfiles_status == 1 && flag_C))
- return 0;
-
- reply_with_error ("%s", err);
- return -1;
-}
diff --git a/daemon/selinux.c b/daemon/selinux.c
index f4d839c19..4500d0096 100644
--- a/daemon/selinux.c
+++ b/daemon/selinux.c
@@ -39,6 +39,13 @@ optgroup_selinux_available (void)
return 1;
}
+/* For historical reasons, this is really "is setfiles available" */
+int
+optgroup_selinuxrelabel_available (void)
+{
+ return prog_exists ("setfiles");
+}
+
/* setcon is only valid under the following circumstances:
* - single threaded
* - enforcing=0
diff --git a/daemon/selinux.ml b/daemon/selinux.ml
new file mode 100644
index 000000000..d954fdead
--- /dev/null
+++ b/daemon/selinux.ml
@@ -0,0 +1,101 @@
+(* SELinux functions.
+ * Copyright (C) 2009-2025 Red Hat Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *)
+
+open Printf
+
+open Std_utils
+
+open Sysroot
+open Utils
+
+(* Test if setfiles has various options.
+ *
+ * The only way to do this is to run setfiles with the option alone, and
+ * test for the stderr message [invalid option -- 'X'].
+ *)
+let setfiles_has_option_m,
+ setfiles_has_option_C,
+ setfiles_has_option_T =
+ let setfiles_has_option flag =
+ let err_msg = sprintf "invalid option -- '%c'" flag in
+ let opt = sprintf "-%c" flag in
+ let _, _, err = commandr "setfiles" [opt] in
+ String.find err err_msg = -1
+ in
+ let setfiles_has_option_m = lazy (setfiles_has_option 'm')
+ and setfiles_has_option_C = lazy (setfiles_has_option 'C')
+ and setfiles_has_option_T = lazy (setfiles_has_option 'T') in
+ (fun () -> Lazy.force setfiles_has_option_m),
+ (fun () -> Lazy.force setfiles_has_option_C),
+ (fun () -> Lazy.force setfiles_has_option_T)
+
+let selinux_relabel ?(force = false) specfile path =
+ (* Prefix /sysroot on all paths. *)
+ let ignored_paths =
+ [ "/dev"; "/proc"; "/selinux"; "/sys" ] |>
+ List.map sysroot_path in
+ let specfile = sysroot_path specfile in
+ let path = sysroot_path path in
+
+ let args = ref [] in
+ if force then List.push_back args "-F";
+ List.iter (
+ fun ignored_path ->
+ List.push_back_list args [ "-e"; ignored_path ]
+ ) ignored_paths;
+
+ (* You have to use the -m option (where available) otherwise
+ * setfiles puts all the mountpoints on the excludes list for no
+ * useful reason (RHBZ#1433577).
+ *)
+ if setfiles_has_option_m () then List.push_back args "-m";
+
+ (* Not only do we want setfiles to trudge through individual relabeling
+ * errors, we also want the setfiles exit status to differentiate a fatal
+ * error from "relabeling errors only". See RHBZ#1794518.
+ *)
+ if setfiles_has_option_C () then List.push_back args "-C";
+
+ (* If the appliance is being run with multiple vCPUs, running setfiles
+ * in multithreading mode might speeds up the process. Option "-T" was
+ * introduced in SELinux userspace v3.4, and we need to check whether it's
+ * supported. Passing "-T 0" creates as many threads as there're available
+ * vCPU cores.
+ * https://github.com/SELinuxProject/selinux/releases/tag/3.4
+ *)
+ if setfiles_has_option_T () then
+ List.push_back_list args [ "-T"; "0" ];
+
+ (* Relabelling in a chroot. *)
+ if sysroot () <> "/" then
+ List.push_back_list args [ "-r"; sysroot () ];
+
+ if verbose () then
+ List.push_back args "-v"
+ else
+ (* Suppress non-error output. *)
+ List.push_back args "-q";
+
+ (* Add parameters. *)
+ List.push_back_list args [ specfile; path ];
+
+ let args = !args in
+ let r, _, err = commandr "setfiles" args in
+
+ let ok = r = 0 || r = 1 && setfiles_has_option_C () in
+ if not ok then failwithf "setfiles: %s" err
diff --git a/docs/C_SOURCE_FILES b/docs/C_SOURCE_FILES
index cdfb1d615..5270667bf 100644
--- a/docs/C_SOURCE_FILES
+++ b/docs/C_SOURCE_FILES
@@ -132,7 +132,6 @@ daemon/rename.c
daemon/rpm-c.c
daemon/rsync.c
daemon/scrub.c
-daemon/selinux-relabel.c
daemon/selinux.c
daemon/sfdisk.c
daemon/sh.c
diff --git a/generator/actions_core.ml b/generator/actions_core.ml
index 108494ece..128cbe0e9 100644
--- a/generator/actions_core.ml
+++ b/generator/actions_core.ml
@@ -9359,6 +9359,7 @@ fails and the C<errno> is set to C<ENODEV>." };
{ defaults with
name = "selinux_relabel"; added = (1, 33, 43);
style = RErr, [String (PlainString, "specfile"); String (Pathname, "path")], [OBool "force"];
+ impl = OCaml "Selinux.selinux_relabel";
optional = Some "selinuxrelabel";
test_excuse = "tests are in the tests/relabel directory";
shortdesc = "relabel parts of the filesystem";
diff --git a/po/POTFILES b/po/POTFILES
index acf3a68d7..fbe0a7fe2 100644
--- a/po/POTFILES
+++ b/po/POTFILES
@@ -110,7 +110,6 @@ daemon/rename.c
daemon/rpm-c.c
daemon/rsync.c
daemon/scrub.c
-daemon/selinux-relabel.c
daemon/selinux.c
daemon/sfdisk.c
daemon/sh.c
--
2.47.1

View File

@ -1,99 +0,0 @@
From fd4db60cffd9d0ece25a436932aca5411e13b94e Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Tue, 12 Aug 2025 14:05:44 +0100
Subject: [PATCH] generator: Implement StringList for OCaml functions
No existing OCaml functions have a StringList parameter, but we would
like to add one.
The original plan seems to have been to map these to 'string array'
types, but 'string list' is more natural, albeit marginally less
efficient. The implementation here just has to convert the 'char **'
into the OCaml linked list of values.
---
daemon/daemon-c.c | 24 ++++++++++++++++++++++++
daemon/daemon-c.h | 1 +
generator/daemon.ml | 6 ++++--
3 files changed, 29 insertions(+), 2 deletions(-)
diff --git a/daemon/daemon-c.c b/daemon/daemon-c.c
index 1754cf0d2..371c2a9e4 100644
--- a/daemon/daemon-c.c
+++ b/daemon/daemon-c.c
@@ -114,6 +114,30 @@ guestfs_int_daemon_copy_mountable (const mountable_t *mountable)
CAMLreturn (r);
}
+/* Implement StringList(...) parameter. */
+value
+guestfs_int_daemon_copy_string_list (char * const *strs)
+{
+ CAMLparam0 ();
+ CAMLlocal3 (v, tlv, rv);
+ size_t i;
+
+ /* We need to build the list backwards so start at the end. */
+ for (i = 0; strs[i] != NULL; ++i)
+ ;
+
+ while (i > 0) {
+ --i;
+ v = caml_copy_string (strs[i]);
+ rv = caml_alloc (2, 0);
+ Store_field (rv, 0, v);
+ Store_field (rv, 1, tlv);
+ tlv = rv;
+ }
+
+ CAMLreturn (rv);
+}
+
/* Implement RStringList. */
char **
guestfs_int_daemon_return_string_list (value retv)
diff --git a/daemon/daemon-c.h b/daemon/daemon-c.h
index 9b7085bce..b06efc0cf 100644
--- a/daemon/daemon-c.h
+++ b/daemon/daemon-c.h
@@ -29,6 +29,7 @@
extern void guestfs_int_daemon_exn_to_reply_with_error (const char *func, value exn);
extern value guestfs_int_daemon_copy_mountable (const mountable_t *mountable);
+extern value guestfs_int_daemon_copy_string_list (char * const *strs);
extern char **guestfs_int_daemon_return_string_list (value retv);
extern char *guestfs_int_daemon_return_string_mountable (value retv);
extern char **guestfs_int_daemon_return_string_mountable_list (value retv);
diff --git a/generator/daemon.ml b/generator/daemon.ml
index 6221531d2..2b74f3059 100644
--- a/generator/daemon.ml
+++ b/generator/daemon.ml
@@ -558,7 +558,7 @@ and generate_ocaml_daemon_prototype name (ret, args, optargs) =
| OInt n -> pr "?%s:int -> " n
| OInt64 n -> pr "?%s:int64 -> " n
| OString n -> pr "?%s:string -> " n
- | OStringList n -> pr "?%s:string array -> " n
+ | OStringList n -> pr "?%s:string list -> " n
) optargs;
if args <> [] then
List.iter (
@@ -566,7 +566,7 @@ and generate_ocaml_daemon_prototype name (ret, args, optargs) =
| String (typ, _) -> pr "%s -> " (type_for_stringt typ)
| BufferIn _ -> pr "string -> "
| OptString _ -> pr "string option -> "
- | StringList (typ, _) -> pr "%s array -> " (type_for_stringt typ)
+ | StringList (typ, _) -> pr "%s list -> " (type_for_stringt typ)
| Bool _ -> pr "bool -> "
| Int _ -> pr "int -> "
| Int64 _ | Pointer _ -> pr "int64 -> "
@@ -820,6 +820,8 @@ let generate_daemon_caml_stubs () =
pr "guestfs_int_daemon_copy_mountable (%s)" n
| String _ -> assert false
| OptString _ -> assert false
+ | StringList ((PlainString|Filename|Pathname), n) ->
+ pr "guestfs_int_daemon_copy_string_list (%s)" n
| StringList _ -> assert false
| BufferIn _ -> assert false
| Pointer _ -> assert false
--
2.47.1

View File

@ -1,83 +0,0 @@
From e4d9ee3fbc58c5993db0c75c647fdf904c520918 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Tue, 12 Aug 2025 14:04:42 +0100
Subject: [PATCH] generator: Allow StringList(Pathname) parameters
This was previously not implemented. It just requires us to call
ABS_PATH on each parameter. ABS_PATH checks the parameter is an
absolute path.
---
generator/checks.ml | 1 -
generator/daemon.ml | 16 ++++++++++++----
2 files changed, 12 insertions(+), 5 deletions(-)
diff --git a/generator/checks.ml b/generator/checks.ml
index d64d49d66..4207c0677 100644
--- a/generator/checks.ml
+++ b/generator/checks.ml
@@ -166,7 +166,6 @@ let () =
| StringList (FileIn, _)
| StringList (FileOut, _)
| StringList (Mountable, _)
- | StringList (Pathname, _)
| StringList (Dev_or_Path, _)
| StringList (Mountable_or_Path, _)
| StringList (Key, _)
diff --git a/generator/daemon.ml b/generator/daemon.ml
index 2b74f3059..6197288df 100644
--- a/generator/daemon.ml
+++ b/generator/daemon.ml
@@ -173,7 +173,7 @@ let generate_daemon_stubs actions () =
| String ((Mountable|Mountable_or_Path), n) ->
pr " CLEANUP_FREE_MOUNTABLE mountable_t %s\n" n;
pr " = { .device = NULL, .volume = NULL };\n"
- | StringList ((PlainString|Filename), n) ->
+ | StringList ((PlainString|Filename|Pathname), n) ->
pr " char **%s;\n" n
| StringList (Device, n) ->
pr " CLEANUP_FREE_STRING_LIST char **%s = NULL;\n" n
@@ -184,7 +184,7 @@ let generate_daemon_stubs actions () =
pr " const char *%s;\n" n;
pr " size_t %s_size;\n" n
| String ((FileIn|FileOut|Filename), _)
- | StringList ((Mountable|Pathname|FileIn|FileOut|Key|GUID
+ | StringList ((Mountable|FileIn|FileOut|Key|GUID
|Dev_or_Path|Mountable_or_Path), _)
| Pointer _ -> assert false
) args_passed_to_daemon
@@ -260,7 +260,7 @@ let generate_daemon_stubs actions () =
n n is_filein;
| String ((PlainString|Key|GUID), n) -> pr_args n
| OptString n -> pr " %s = args.%s ? *args.%s : NULL;\n" n n n
- | StringList ((PlainString|Filename) as arg, n) ->
+ | StringList ((PlainString|Filename|Pathname) as arg, n) ->
(match arg with
| Filename ->
pr " {\n";
@@ -275,6 +275,14 @@ let generate_daemon_stubs actions () =
pr " }\n";
pr " }\n";
pr " }\n"
+ | Pathname ->
+ pr " {\n";
+ pr " size_t i;\n";
+ pr " for (i = 0; i < args.%s.%s_len; ++i) {\n" n n;
+ pr " ABS_PATH (args.%s.%s_val[i], %b, return);\n"
+ n n is_filein;
+ pr " }\n";
+ pr " }\n"
| _ -> ()
);
pr " /* Ugly, but safe and avoids copying the strings. */\n";
@@ -307,7 +315,7 @@ let generate_daemon_stubs actions () =
pr " %s = args.%s.%s_val;\n" n n n;
pr " %s_size = args.%s.%s_len;\n" n n n
| String ((FileIn|FileOut|Filename), _)
- | StringList ((Mountable|Pathname|FileIn|FileOut|Key|GUID
+ | StringList ((Mountable|FileIn|FileOut|Key|GUID
|Dev_or_Path|Mountable_or_Path), _)
| Pointer _ -> assert false
) args_passed_to_daemon;
--
2.47.1

View File

@ -1,311 +0,0 @@
From 1c0b56158aa63359d1e53f7a31b483194f235a34 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Tue, 12 Aug 2025 13:27:32 +0100
Subject: [PATCH] daemon: Deprecate guestfs_selinux_relabel, replace with
guestfs_setfiles
The guestfs_selinux_relabel function was very hard to use. In
particular it didn't just do an SELinux relabel as you might expect.
Instead you have to write a whole bunch of code around it (example[1])
to make it useful.
Another problem is that it doesn't let you pass multiple paths to the
setfiles command, but the command itself does permit that (and, as it
turns out, will require it). There is no backwards compatible way to
extend the existing definition to allow a list parameter without
breaking API.
So deprecate guestfs_selinux_relabel. Reimplement it as
guestfs_setfiles. The new function is basically the same as the old
one, but allows you to pass a list of paths. The old function calls
the new function with a single path parameter.
[1] https://github.com/libguestfs/libguestfs-common/blob/master/mlcustomize/SELinux_relabel.ml
---
daemon/selinux.ml | 117 ++++++++++++++-------------
generator/actions_core.ml | 49 +++++------
generator/actions_core_deprecated.ml | 24 ++++++
generator/proc_nr.ml | 1 +
gobject/Makefile.inc | 2 +
lib/MAX_PROC_NR | 2 +-
tests/relabel/test-relabel.pl | 2 +-
7 files changed, 117 insertions(+), 80 deletions(-)
diff --git a/daemon/selinux.ml b/daemon/selinux.ml
index d954fdead..db0d71455 100644
--- a/daemon/selinux.ml
+++ b/daemon/selinux.ml
@@ -44,58 +44,65 @@ let setfiles_has_option_m,
(fun () -> Lazy.force setfiles_has_option_C),
(fun () -> Lazy.force setfiles_has_option_T)
-let selinux_relabel ?(force = false) specfile path =
- (* Prefix /sysroot on all paths. *)
- let ignored_paths =
- [ "/dev"; "/proc"; "/selinux"; "/sys" ] |>
- List.map sysroot_path in
- let specfile = sysroot_path specfile in
- let path = sysroot_path path in
-
- let args = ref [] in
- if force then List.push_back args "-F";
- List.iter (
- fun ignored_path ->
- List.push_back_list args [ "-e"; ignored_path ]
- ) ignored_paths;
-
- (* You have to use the -m option (where available) otherwise
- * setfiles puts all the mountpoints on the excludes list for no
- * useful reason (RHBZ#1433577).
- *)
- if setfiles_has_option_m () then List.push_back args "-m";
-
- (* Not only do we want setfiles to trudge through individual relabeling
- * errors, we also want the setfiles exit status to differentiate a fatal
- * error from "relabeling errors only". See RHBZ#1794518.
- *)
- if setfiles_has_option_C () then List.push_back args "-C";
-
- (* If the appliance is being run with multiple vCPUs, running setfiles
- * in multithreading mode might speeds up the process. Option "-T" was
- * introduced in SELinux userspace v3.4, and we need to check whether it's
- * supported. Passing "-T 0" creates as many threads as there're available
- * vCPU cores.
- * https://github.com/SELinuxProject/selinux/releases/tag/3.4
- *)
- if setfiles_has_option_T () then
- List.push_back_list args [ "-T"; "0" ];
-
- (* Relabelling in a chroot. *)
- if sysroot () <> "/" then
- List.push_back_list args [ "-r"; sysroot () ];
-
- if verbose () then
- List.push_back args "-v"
- else
- (* Suppress non-error output. *)
- List.push_back args "-q";
-
- (* Add parameters. *)
- List.push_back_list args [ specfile; path ];
-
- let args = !args in
- let r, _, err = commandr "setfiles" args in
-
- let ok = r = 0 || r = 1 && setfiles_has_option_C () in
- if not ok then failwithf "setfiles: %s" err
+let setfiles ?(force = false) specfile paths =
+ if paths = [] then ()
+ else (
+ (* Prefix /sysroot on all paths. *)
+ let ignored_paths =
+ [ "/dev"; "/proc"; "/selinux"; "/sys" ] |>
+ List.map sysroot_path in
+ let specfile = sysroot_path specfile in
+ let paths = List.map sysroot_path paths in
+
+ let args = ref [] in
+ if force then List.push_back args "-F";
+ List.iter (
+ fun ignored_path ->
+ List.push_back_list args [ "-e"; ignored_path ]
+ ) ignored_paths;
+
+ (* You have to use the -m option (where available) otherwise
+ * setfiles puts all the mountpoints on the excludes list for no
+ * useful reason (RHBZ#1433577).
+ *)
+ if setfiles_has_option_m () then List.push_back args "-m";
+
+ (* Not only do we want setfiles to trudge through individual relabeling
+ * errors, we also want the setfiles exit status to differentiate a fatal
+ * error from "relabeling errors only". See RHBZ#1794518.
+ *)
+ if setfiles_has_option_C () then List.push_back args "-C";
+
+ (* If the appliance is being run with multiple vCPUs, running setfiles
+ * in multithreading mode might speeds up the process. Option "-T" was
+ * introduced in SELinux userspace v3.4, and we need to check whether it's
+ * supported. Passing "-T 0" creates as many threads as there're available
+ * vCPU cores.
+ * https://github.com/SELinuxProject/selinux/releases/tag/3.4
+ *)
+ if setfiles_has_option_T () then
+ List.push_back_list args [ "-T"; "0" ];
+
+ (* Relabelling in a chroot. *)
+ if sysroot () <> "/" then
+ List.push_back_list args [ "-r"; sysroot () ];
+
+ if verbose () then
+ List.push_back args "-v"
+ else
+ (* Suppress non-error output. *)
+ List.push_back args "-q";
+
+ (* Add parameters. *)
+ List.push_back args specfile;
+ List.push_back_list args paths;
+
+ let args = !args in
+ let r, _, err = commandr "setfiles" args in
+
+ let ok = r = 0 || r = 1 && setfiles_has_option_C () in
+ if not ok then failwithf "setfiles: %s" err
+ )
+
+(* This is the deprecated selinux_relabel function from libguestfs <= 1.56. *)
+let selinux_relabel ?force specfile path = setfiles ?force specfile [path]
diff --git a/generator/actions_core.ml b/generator/actions_core.ml
index 128cbe0e9..60d3140ed 100644
--- a/generator/actions_core.ml
+++ b/generator/actions_core.ml
@@ -9356,29 +9356,6 @@ Show all the devices where the filesystems in C<device> is spanned over.
If not all the devices for the filesystems are present, then this function
fails and the C<errno> is set to C<ENODEV>." };
- { defaults with
- name = "selinux_relabel"; added = (1, 33, 43);
- style = RErr, [String (PlainString, "specfile"); String (Pathname, "path")], [OBool "force"];
- impl = OCaml "Selinux.selinux_relabel";
- optional = Some "selinuxrelabel";
- test_excuse = "tests are in the tests/relabel directory";
- shortdesc = "relabel parts of the filesystem";
- longdesc = "\
-SELinux relabel parts of the filesystem.
-
-The C<specfile> parameter controls the policy spec file used.
-You have to parse C</etc/selinux/config> to find the correct
-SELinux policy and then pass the spec file, usually:
-C</etc/selinux/> + I<selinuxtype> + C</contexts/files/file_contexts>.
-
-The required C<path> parameter is the top level directory where
-relabelling starts. Normally you should pass C<path> as C</>
-to relabel the whole guest filesystem.
-
-The optional C<force> boolean controls whether the context
-is reset for customizable files, and also whether the
-user, role and range parts of the file context is changed." };
-
{ defaults with
name = "mksquashfs"; added = (1, 35, 25);
style = RErr, [String (Pathname, "path"); String (FileOut, "filename")], [OString "compress"; OStringList "excludes"];
@@ -9820,4 +9797,30 @@ them visible.
Use C<guestfs_list_dm_devices> to list all device mapper devices." };
+ { defaults with
+ name = "setfiles"; added = (1, 57, 1);
+ style = RErr, [String (PlainString, "specfile"); StringList (Pathname, "paths")], [OBool "force"];
+ impl = OCaml "Selinux.setfiles";
+ optional = Some "selinuxrelabel";
+ test_excuse = "tests are in the tests/relabel directory";
+ shortdesc = "low level relabel parts of the filesystem";
+ longdesc = "\
+This invokes the SELinux C<setfiles> command which is a low
+level tool used to relabel parts of the filesystem.
+
+The C<specfile> parameter controls the policy spec file used.
+You have to parse C</etc/selinux/config> to find the correct
+SELinux policy and then pass the spec file, usually:
+C</etc/selinux/> + I<selinuxtype> + C</contexts/files/file_contexts>.
+
+The required C<paths> parameter is the list of top level directories
+where relabelling starts. C<setfiles> will only relabel up to
+filesystem boundaries so, for example, passing just C<\"/\"> will
+relabel the whole root filesystem, but no other mounted filesystems.
+If the list is empty, setfiles is not called.
+
+The optional C<force> boolean controls whether the context
+is reset for customizable files, and also whether the
+user, role and range parts of the file context is changed." };
+
]
diff --git a/generator/actions_core_deprecated.ml b/generator/actions_core_deprecated.ml
index 9d4b29f9d..2b1f5cdb4 100644
--- a/generator/actions_core_deprecated.ml
+++ b/generator/actions_core_deprecated.ml
@@ -942,4 +942,28 @@ This call does nothing and returns an error." };
Used to check a btrfs filesystem, C<device> is the device file where the
filesystem is stored." };
+ { defaults with
+ name = "selinux_relabel"; added = (1, 33, 43);
+ style = RErr, [String (PlainString, "specfile"); String (Pathname, "path")], [OBool "force"];
+ impl = OCaml "Selinux.selinux_relabel";
+ optional = Some "selinuxrelabel";
+ deprecated_by = Replaced_by "setfiles";
+ test_excuse = "tests are in the tests/relabel directory";
+ shortdesc = "relabel parts of the filesystem";
+ longdesc = "\
+SELinux relabel parts of the filesystem.
+
+The C<specfile> parameter controls the policy spec file used.
+You have to parse C</etc/selinux/config> to find the correct
+SELinux policy and then pass the spec file, usually:
+C</etc/selinux/> + I<selinuxtype> + C</contexts/files/file_contexts>.
+
+The required C<path> parameter is the top level directory where
+relabelling starts. Normally you should pass C<path> as C</>
+to relabel the whole guest filesystem.
+
+The optional C<force> boolean controls whether the context
+is reset for customizable files, and also whether the
+user, role and range parts of the file context is changed." };
+
]
diff --git a/generator/proc_nr.ml b/generator/proc_nr.ml
index 63cd72a3c..42624afef 100644
--- a/generator/proc_nr.ml
+++ b/generator/proc_nr.ml
@@ -521,6 +521,7 @@ let proc_nr = [
516, "command_out";
517, "sh_out";
518, "btrfs_scrub_full";
+519, "setfiles";
]
(* End of list. If adding a new entry, add it at the end of the list
diff --git a/gobject/Makefile.inc b/gobject/Makefile.inc
index b54245977..b828113c6 100644
--- a/gobject/Makefile.inc
+++ b/gobject/Makefile.inc
@@ -106,6 +106,7 @@ guestfs_gobject_headers= \
include/guestfs-gobject/optargs-rsync_out.h \
include/guestfs-gobject/optargs-selinux_relabel.h \
include/guestfs-gobject/optargs-set_e2attrs.h \
+ include/guestfs-gobject/optargs-setfiles.h \
include/guestfs-gobject/optargs-syslinux.h \
include/guestfs-gobject/optargs-tar_in.h \
include/guestfs-gobject/optargs-tar_out.h \
@@ -201,6 +202,7 @@ guestfs_gobject_sources= \
src/optargs-rsync_out.c \
src/optargs-selinux_relabel.c \
src/optargs-set_e2attrs.c \
+ src/optargs-setfiles.c \
src/optargs-syslinux.c \
src/optargs-tar_in.c \
src/optargs-tar_out.c \
diff --git a/lib/MAX_PROC_NR b/lib/MAX_PROC_NR
index 9a26b94d0..08f851b6e 100644
--- a/lib/MAX_PROC_NR
+++ b/lib/MAX_PROC_NR
@@ -1 +1 @@
-518
+519
diff --git a/tests/relabel/test-relabel.pl b/tests/relabel/test-relabel.pl
index 06fb0840b..4d4f6c7ba 100755
--- a/tests/relabel/test-relabel.pl
+++ b/tests/relabel/test-relabel.pl
@@ -87,7 +87,7 @@ $g->write ("/etc/file_contexts", <<'EOF');
EOF
# Do the relabel.
-$g->selinux_relabel ("/etc/file_contexts", "/", force => 1);
+$g->setfiles ("/etc/file_contexts", ["/"], force => 1);
# Check the labels were set correctly.
my $errors = 0;
--
2.47.1

View File

@ -1,75 +0,0 @@
From b43ca06ea69cebbdd774ed03bc0da63eb3955d66 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Thu, 14 Aug 2025 14:56:47 +0100
Subject: [PATCH] daemon/inspect_fs_windows.ml: Add debugging for MBR drive
mappings
The function 'map_registry_disk_blob_gpt' immediately below this one
has a debugging statement. Add the equivalent to the function
'map_registry_disk_blob_mbr'.
The output looks like:
map_registry_disk_blob_mbr: searching for MBR disk ID 31 32 33 34
map_registry_disk_blob_mbr: searching for MBR partition offset 00 00 00 10 00 00 00 00
---
daemon/inspect_fs_windows.ml | 8 ++++++++
daemon/utils.ml | 4 ++++
daemon/utils.mli | 4 ++++
3 files changed, 16 insertions(+)
diff --git a/daemon/inspect_fs_windows.ml b/daemon/inspect_fs_windows.ml
index dbaf4c362..5991cdba3 100644
--- a/daemon/inspect_fs_windows.ml
+++ b/daemon/inspect_fs_windows.ml
@@ -376,6 +376,10 @@ and map_registry_disk_blob_mbr devices blob =
* disk with this disk ID.
*)
let diskid = String.sub blob 0 4 in
+ if verbose () then
+ eprintf "map_registry_disk_blob_mbr: searching for MBR disk ID %s\n%!"
+ (hex_of_string diskid);
+
let device =
List.find (
fun dev ->
@@ -388,6 +392,10 @@ and map_registry_disk_blob_mbr devices blob =
* partition byte offset from Parted.part_list.
*)
let offset = String.sub blob 4 8 in
+ if verbose () then
+ eprintf "map_registry_disk_blob_mbr: searching for MBR partition offset \
+ %s\n%!"
+ (hex_of_string offset);
let offset = int_of_le64 offset in
let partitions = Parted.part_list device in
let partition =
diff --git a/daemon/utils.ml b/daemon/utils.ml
index 40584c9f1..3aa1d7ed2 100644
--- a/daemon/utils.ml
+++ b/daemon/utils.ml
@@ -291,3 +291,7 @@ let parse_key_value_strings ?unquote lines =
match unquote with
| None -> lines
| Some f -> List.map (fun (k, v) -> (k, f v)) lines
+
+let hex_of_string s =
+ let bytes = String.map_chars (fun c -> sprintf "%02x" (Char.code c)) s in
+ String.concat " " bytes
diff --git a/daemon/utils.mli b/daemon/utils.mli
index 0f2ae471f..e14735038 100644
--- a/daemon/utils.mli
+++ b/daemon/utils.mli
@@ -121,5 +121,9 @@ val parse_key_value_strings : ?unquote:(string -> string) -> string list -> (str
it is applied on the values as unquote function. Empty lines,
or that start with a comment character [#], are ignored. *)
+val hex_of_string : string -> string
+(** Return a string as a list of hex bytes.
+ Use this for debugging msgs only. *)
+
(**/**)
val get_verbose_flag : unit -> bool
--
2.47.1

View File

@ -1,32 +0,0 @@
From 7bbadaec5ab9c60bd5ad8e1feee39af9f170b552 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Thu, 14 Aug 2025 14:57:45 +0100
Subject: [PATCH] daemon/inspect_fs_windows.ml: Add debugging when we start
registry analysis
Add some debugging when we begin the process of analyzing the Windows
registry of a guest.
---
daemon/inspect_fs_windows.ml | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/daemon/inspect_fs_windows.ml b/daemon/inspect_fs_windows.ml
index 5991cdba3..00acf5196 100644
--- a/daemon/inspect_fs_windows.ml
+++ b/daemon/inspect_fs_windows.ml
@@ -207,6 +207,12 @@ and check_windows_registry systemroot data =
if Is.is_file system_hive then Some system_hive else None in
data.windows_system_hive <- system_hive;
+ if verbose () then
+ eprintf "check_windows_registry: software hive: %s\n\
+ check_windows_registry: system hive: %s\n%!"
+ (Option.value ~default:"None" software_hive)
+ (Option.value ~default:"None" system_hive);
+
match software_hive, system_hive with
| None, _ | Some _, None -> ()
| Some software_hive, Some system_hive ->
--
2.47.1

View File

@ -1,78 +0,0 @@
From 42afed95dc6611dc9585ab23134bdcc39a5b75ec Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Thu, 14 Aug 2025 15:17:59 +0100
Subject: [PATCH] daemon/inspect_fs_windows.ml: Ignore blank disks in drive
mapping
If HKLM\System\MountedDevices references a blank disk, then when we
try to search for the actual backing device we will get an error from
parted:
parted: /dev/sdb: parted exited with status 1: Error: /dev/sdb: unrecognised disk label: Invalid argument
Just ignore these errors instead of failing inspection.
Fixes: https://issues.redhat.com/browse/RHEL-108803
Reported-by: Ameen Barakat
Thanks: Ming Xie
---
daemon/inspect_fs_windows.ml | 35 ++++++++++++++++++++++++++---------
1 file changed, 26 insertions(+), 9 deletions(-)
diff --git a/daemon/inspect_fs_windows.ml b/daemon/inspect_fs_windows.ml
index 00acf5196..ba8ef4ee3 100644
--- a/daemon/inspect_fs_windows.ml
+++ b/daemon/inspect_fs_windows.ml
@@ -389,8 +389,18 @@ and map_registry_disk_blob_mbr devices blob =
let device =
List.find (
fun dev ->
- Parted.part_get_parttype dev = "msdos" &&
+ try
+ Parted.part_get_parttype dev = "msdos" &&
pread dev 4 0x01b8 = diskid
+ with Unix.Unix_error (EINVAL, "parted", msg) ->
+ (* Errors can happen here if the disk is empty. Just ignore
+ * them. It means the drive mapping might have missing
+ * entries but that's not important. (RHEL-108803)
+ *)
+ if verbose () then
+ eprintf "map_registry_disk_blob_mbr: parted returned: \
+ %s (ignored)\n" msg;
+ false
) devices in
(* Next 8 bytes are the offset of the partition in bytes(!) given as
@@ -428,14 +438,21 @@ and map_registry_disk_blob_gpt partitions blob =
let partition =
List.find (
fun part ->
- let partnum = Devsparts.part_to_partnum part in
- let device = Devsparts.part_to_dev part in
- let typ = Parted.part_get_parttype device in
- if typ <> "gpt" then false
- else (
- let guid = Sfdisk.part_get_gpt_guid device partnum in
- String.lowercase_ascii guid = blob_guid
- )
+ try
+ let partnum = Devsparts.part_to_partnum part in
+ let device = Devsparts.part_to_dev part in
+ let typ = Parted.part_get_parttype device in
+ if typ <> "gpt" then false
+ else (
+ let guid = Sfdisk.part_get_gpt_guid device partnum in
+ String.lowercase_ascii guid = blob_guid
+ )
+ with Unix.Unix_error (EINVAL, "parted", msg) ->
+ (* See comment in MBR code above (RHEL-108803) *)
+ if verbose () then
+ eprintf "map_registry_disk_blob_gpt: parted returned: \
+ %s (ignored)\n" msg;
+ false
) partitions in
Some partition
with
--
2.47.1

View File

@ -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

View File

@ -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 <rjones@redhat.com> - 1:1.57.2-1
- Rebase to libguestfs 1.57.2
resolves: RHEL-111240
* Thu Aug 14 2025 Richard W.M. Jones <rjones@redhat.com> - 1:1.56.1-3
- Rebase to libguestfs 1.56.1
resolves: RHEL-81733

View File

@ -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