From ea0f9cf0743c3e50a996a9d7ec488d58a9312b11 Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Wed, 13 Aug 2025 16:51:39 +0100 Subject: [PATCH] customize: Fixes for selinux relabelling and Windows firstboot This updates the common submodule to add the fixes below. These changes allow SELinux relabelling to work correctly on Linux split- /usr configurations, and allow Windows firstboot scripts to be deferred until after a reboot. The SELinux relabelling change requires libguestfs >= 1.57.1 (for the new guestfs_setfiles API). Richard W.M. Jones (4): mlstdutils: Add List.combine4 function mlcustomize/SELinux_relabel.ml: Add comment mlcustomize/SELinux_relabel.ml: Use new guestfs_setfiles API mlcustomize/SELinux_relabel.ml: Relabel every mountpoint Vadim Rozenfeld (1): Modify the firstboot script to check the scripts execution return status Fixes: https://issues.redhat.com/browse/RHEL-108174 Related: https://issues.redhat.com/browse/RHEL-100682 --- common | 2 +- m4/guestfs-libraries.m4 | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) Submodule common d4a81e9dd..89f1eb2d3: diff --git a/common/mlcustomize/SELinux_relabel.ml b/common/mlcustomize/SELinux_relabel.ml index 2f3a09bf7..f1729e3f4 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 6aca4c34a..5f2642b06 100644 --- a/common/mlcustomize/firstboot.ml +++ b/common/mlcustomize/firstboot.ml @@ -305,13 +305,19 @@ if not exist \"%%scripts_done%%\" ( :: Pick the next script to run. for %%%%f in (\"%%scripts%%\"\\*.bat) do ( echo running \"%%%%f\" - move \"%%%%f\" \"%%scripts_done%%\" - pushd \"%%scripts_done%%\" + 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 diff --git a/common/mlstdutils/std_utils.ml b/common/mlstdutils/std_utils.ml index 4850a5598..16032d992 100644 --- a/common/mlstdutils/std_utils.ml +++ b/common/mlstdutils/std_utils.ml @@ -80,6 +80,12 @@ module List = struct | x::xs, y::ys, z::zs -> (x, y, z) :: combine3 xs ys zs | _ -> invalid_arg "combine3" + let rec combine4 ws xs ys zs = + match ws, xs, ys, zs with + | [], [], [], [] -> [] + | w::ws, x::xs, y::ys, z::zs -> (w, x, y, z) :: combine4 ws xs ys zs + | _ -> invalid_arg "combine4" + let rec assoc_lbl ?(cmp = Stdlib.compare) ~default x = function | [] -> default | (y, y') :: _ when cmp x y = 0 -> y' diff --git a/common/mlstdutils/std_utils.mli b/common/mlstdutils/std_utils.mli index fe6bf1a7c..a20e720c2 100644 --- a/common/mlstdutils/std_utils.mli +++ b/common/mlstdutils/std_utils.mli @@ -106,6 +106,11 @@ module List : sig (** Like {!List.combine} but for triples. All lists must be the same length. *) + val combine4 : 'a list -> 'b list -> 'c list -> 'd list -> + ('a * 'b * 'c * 'd) list + (** Like {!List.combine} but for 4-tuples. + All lists must be the same length. *) + val assoc_lbl : ?cmp:('a -> 'a -> int) -> default:'b -> 'a -> ('a * 'b) list -> 'b (** Like {!assoc} but with a user-defined comparison function, and instead of raising [Not_found], it returns the [~default] value. *) diff --git a/m4/guestfs-libraries.m4 b/m4/guestfs-libraries.m4 index c9fbf58b2..82e62d54f 100644 --- a/m4/guestfs-libraries.m4 +++ b/m4/guestfs-libraries.m4 @@ -19,8 +19,8 @@ dnl Any C libraries required by the libguestfs C library (not the daemon). dnl Of course we need libguestfs. dnl -dnl We need libguestfs 1.55.6 for guestfs_sh_out. -PKG_CHECK_MODULES([LIBGUESTFS], [libguestfs >= 1.55.6]) +dnl We need libguestfs 1.57.1 for guestfs_setfiles. +PKG_CHECK_MODULES([LIBGUESTFS], [libguestfs >= 1.57.1]) printf "libguestfs version is "; $PKG_CONFIG --modversion libguestfs dnl Test if it's GNU or XSI strerror_r.