This shouldn't change the effect of this code.
---
mlcustomize/SELinux_relabel.ml | 121 ++++++++++++++++++---------------
1 file changed, 65 insertions(+), 56 deletions(-)
diff --git a/mlcustomize/SELinux_relabel.ml b/mlcustomize/SELinux_relabel.ml
index 44995df..5df1f08 100644
--- a/mlcustomize/SELinux_relabel.ml
+++ b/mlcustomize/SELinux_relabel.ml
@@ -28,65 +28,74 @@ module G = Guestfs
let array_find a l =
List.mem a (Array.to_list l)
-let relabel (g : G.guestfs) =
- (* Is the guest using SELinux? *)
- if g#is_file ~followsymlinks:true "/usr/sbin/load_policy" &&
- g#is_file ~followsymlinks:true "/etc/selinux/config" then (
- (* Is setfiles / SELinux relabelling functionality available? *)
- if g#feature_available [| "selinuxrelabel" |] then (
- (* Use Augeas to parse /etc/selinux/config. *)
- g#aug_init "/" (16+32) (* AUG_SAVE_NOOP | AUG_NO_LOAD *);
- (* See:
https://bugzilla.redhat.com/show_bug.cgi?id=975412#c0 *)
- ignore (g#aug_rm "/augeas/load/*[\"/etc/selinux/config/\" !~
regexp('^') + glob(incl) + regexp('/.*')]");
- g#aug_load ();
- debug_augeas_errors g;
-
- (* Get the SELinux policy name, eg. "targeted", "minimum".
- * Use "targeted" if not specified, just like libselinux does.
+let rec relabel (g : G.guestfs) =
+ (* Is the guest using SELinux? (Otherwise this is a no-op). *)
+ if is_selinux_guest g then (
+ try
+ use_setfiles g;
+ (* That worked, so we don't need to autorelabel. *)
+ g#rm_f "/.autorelabel"
+ with Failure _ ->
+ (* This is the fallback in case something in the setfiles
+ * method didn't work. That includes the case where a non-SELinux
+ * host is processing an SELinux guest, and other things.
*)
- let policy =
- let config_path = "/files/etc/selinux/config" in
- let selinuxtype_path = config_path ^ "/SELINUXTYPE" in
- let keys = g#aug_ls config_path in
- if array_find selinuxtype_path keys then
- g#aug_get selinuxtype_path
- else
- "targeted" in
+ g#touch "/.autorelabel"
+ )
- g#aug_close ();
+and is_selinux_guest g =
+ g#is_file ~followsymlinks:true "/usr/sbin/load_policy" &&
+ g#is_file ~followsymlinks:true "/etc/selinux/config"
- (* Get the spec file name. *)
- let specfile =
- sprintf "/etc/selinux/%s/contexts/files/file_contexts" policy in
+and use_setfiles g =
+ (* Is setfiles / SELinux relabelling functionality available? *)
+ if not (g#feature_available [| "selinuxrelabel" |]) then
+ failwith "no selinux relabel feature";
- (* RHEL 6.2 - 6.5 had a malformed specfile that contained the
- * invalid regular expression "/var/run/spice-vdagentd.\pid"
- * (instead of "\.p"). This stops setfiles from working on
- * the guest.
- *
- * Because an SELinux relabel writes all over the filesystem,
- * it seems reasonable to fix this problem in the specfile
- * at the same time. (RHBZ#1374232)
- *)
- if g#grep ~fixed:true "vdagentd.\\pid" specfile <> [||] then (
- debug "fixing invalid regular expression in %s" specfile;
- let old_specfile = specfile ^ "~" in
- g#mv specfile old_specfile;
- let content = g#read_file old_specfile in
- let content =
- String.replace content "vdagentd.\\pid" "vdagentd\\.pid"
in
- g#write specfile content;
- g#copy_attributes ~all:true old_specfile specfile
- );
+ (* Use Augeas to parse /etc/selinux/config. *)
+ g#aug_init "/" (16+32) (* AUG_SAVE_NOOP | AUG_NO_LOAD *);
+ (* See:
https://bugzilla.redhat.com/show_bug.cgi?id=975412#c0 *)
+ ignore (g#aug_rm "/augeas/load/*[\"/etc/selinux/config/\" !~
regexp('^') + glob(incl) + regexp('/.*')]");
+ g#aug_load ();
+ debug_augeas_errors g;
- (* Relabel everything. *)
- g#selinux_relabel ~force:true specfile "/";
+ (* Get the SELinux policy name, eg. "targeted", "minimum".
+ * Use "targeted" if not specified, just like libselinux does.
+ *)
+ let policy =
+ let config_path = "/files/etc/selinux/config" in
+ let selinuxtype_path = config_path ^ "/SELINUXTYPE" in
+ let keys = g#aug_ls config_path in
+ if array_find selinuxtype_path keys then
+ g#aug_get selinuxtype_path
+ else
+ "targeted" in
- (* If that worked, we don't need to autorelabel. *)
- g#rm_f "/.autorelabel"
- )
- else (
- (* SELinux guest, but not SELinux host. Fallback to this. *)
- g#touch "/.autorelabel"
- )
- )
+ g#aug_close ();
+
+ (* Get the spec file name. *)
+ let specfile =
+ sprintf "/etc/selinux/%s/contexts/files/file_contexts" policy in
+
+ (* RHEL 6.2 - 6.5 had a malformed specfile that contained the
+ * invalid regular expression "/var/run/spice-vdagentd.\pid"
+ * (instead of "\.p"). This stops setfiles from working on
+ * the guest.
+ *
+ * Because an SELinux relabel writes all over the filesystem,
+ * it seems reasonable to fix this problem in the specfile
+ * at the same time. (RHBZ#1374232)
+ *)
+ if g#grep ~fixed:true "vdagentd.\\pid" specfile <> [||] then (
+ debug "fixing invalid regular expression in %s" specfile;
+ let old_specfile = specfile ^ "~" in
+ g#mv specfile old_specfile;
+ let content = g#read_file old_specfile in
+ let content =
+ String.replace content "vdagentd.\\pid" "vdagentd\\.pid" in
+ g#write specfile content;
+ g#copy_attributes ~all:true old_specfile specfile
+ );
+
+ (* Relabel everything. *)
+ g#selinux_relabel ~force:true specfile "/"
--
2.24.1