Update to libguestfs-1.58.1-6
Patch series (24) regenerated from public sources: - https://github.com/libguestfs/libguestfs (branch rhel-10.2) - https://github.com/libguestfs/libguestfs-common (submodule) Apply patches with %autosetup -S git (BuildRequires: git): a patch adds binary test data that /usr/bin/patch cannot apply. Retains AlmaLinux ppc64le build enablement (.alma.1).
This commit is contained in:
parent
b9f12a4084
commit
e7e9a5e032
@ -0,0 +1,87 @@
|
||||
From 14313b0191d7a1e28b2ed1d923427ed544859e08 Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Thu, 16 Apr 2026 08:06:50 +0100
|
||||
Subject: [PATCH] daemon/listfs.ml: Refactor is_partition_can_hold_filesystem
|
||||
|
||||
Refactor and simplify the function.
|
||||
|
||||
This is just code motion, there is no functional change.
|
||||
|
||||
(cherry picked from commit 88bd07f350407619d4f5fe406c5594b50cf541dd)
|
||||
---
|
||||
daemon/listfs.ml | 53 ++++++++++++++++++++----------------------------
|
||||
1 file changed, 22 insertions(+), 31 deletions(-)
|
||||
|
||||
diff --git a/daemon/listfs.ml b/daemon/listfs.ml
|
||||
index 4c90796ef..067314c47 100644
|
||||
--- a/daemon/listfs.ml
|
||||
+++ b/daemon/listfs.ml
|
||||
@@ -115,43 +115,34 @@ and is_not_partitioned_device device =
|
||||
* Windows Snapshot Partition as well as MBR extended partitions.
|
||||
*)
|
||||
and is_partition_can_hold_filesystem partition =
|
||||
- let device = Devsparts.part_to_dev partition in
|
||||
- let partnum = Devsparts.part_to_partnum partition in
|
||||
- let parttype = Parted.part_get_parttype device in
|
||||
+ let device = Devsparts.part_to_dev partition
|
||||
+ and partnum = Devsparts.part_to_partnum partition in
|
||||
|
||||
- let is_gpt = parttype = "gpt" in
|
||||
- let is_mbr = parttype = "msdos" in
|
||||
- let is_gpt_or_mbr = is_gpt || is_mbr in
|
||||
+ match Parted.part_get_parttype device with
|
||||
+ | "msdos" ->
|
||||
+ if Parted.part_get_mbr_part_type device partnum = "extended" then
|
||||
+ false
|
||||
+ else if partnum = 1 && Utils.has_bogus_mbr device then
|
||||
+ true
|
||||
+ else
|
||||
+ true
|
||||
|
||||
- if is_gpt_or_mbr then (
|
||||
- if is_mbr_extended parttype device partnum then
|
||||
- false
|
||||
- else if is_mbr_bogus parttype device partnum then
|
||||
- true
|
||||
- else if is_mbr then
|
||||
- true
|
||||
- else (
|
||||
- let gpt_type = Sfdisk.part_get_gpt_type device partnum in
|
||||
- match gpt_type with
|
||||
+ | "gpt" ->
|
||||
+ let gpt_type = Sfdisk.part_get_gpt_type device partnum in
|
||||
+ (match gpt_type with
|
||||
(* Windows Logical Disk Manager metadata partition. *)
|
||||
| "5808C8AA-7E8F-42E0-85D2-E1E90434CFB3"
|
||||
- (* Windows Logical Disk Manager data partition. *)
|
||||
- | "AF9B60A0-1431-4F62-BC68-3311714A69AD"
|
||||
- (* Microsoft Reserved Partition. *)
|
||||
- | "E3C9E316-0B5C-4DB8-817D-F92DF00215AE"
|
||||
- (* Windows Snapshot Partition. *)
|
||||
- | "CADDEBF1-4400-4DE8-B103-12117DCF3CCF" -> false
|
||||
+ (* Windows Logical Disk Manager data partition. *)
|
||||
+ | "AF9B60A0-1431-4F62-BC68-3311714A69AD"
|
||||
+ (* Microsoft Reserved Partition. *)
|
||||
+ | "E3C9E316-0B5C-4DB8-817D-F92DF00215AE"
|
||||
+ (* Windows Snapshot Partition. *)
|
||||
+ | "CADDEBF1-4400-4DE8-B103-12117DCF3CCF" -> false
|
||||
| _ -> true
|
||||
- )
|
||||
- )
|
||||
- else true
|
||||
+ )
|
||||
|
||||
-and is_mbr_extended parttype device partnum =
|
||||
- parttype = "msdos" &&
|
||||
- Parted.part_get_mbr_part_type device partnum = "extended"
|
||||
-
|
||||
-and is_mbr_bogus parttype device partnum =
|
||||
- parttype = "msdos" && partnum = 1 && Utils.has_bogus_mbr device
|
||||
+ | _ -> (* unknown or other *)
|
||||
+ true
|
||||
|
||||
(* Use vfs-type to check for a filesystem of some sort of [device].
|
||||
* Appends (device, vfs_type) to the ret parameter (there may be
|
||||
--
|
||||
2.47.3
|
||||
|
||||
114
0013-daemon-listfs.ml-Ignore-CHS-geometry-error-from-part.patch
Normal file
114
0013-daemon-listfs.ml-Ignore-CHS-geometry-error-from-part.patch
Normal file
@ -0,0 +1,114 @@
|
||||
From 41cfc0423316acf42fd1122c9b345b49636d9214 Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Thu, 16 Apr 2026 08:34:38 +0100
|
||||
Subject: [PATCH] daemon/listfs.ml: Ignore CHS geometry error from parted
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
parted has an annoying bug where it fails to parse Sun partition
|
||||
tables (still used by Veritas). It tries to check the CHS geometry
|
||||
stored in the header matches the physical CHS geometry, which is a
|
||||
meaningless test.
|
||||
|
||||
In function is_partition_can_hold_filesystem we are only interested in
|
||||
MBR and GPT partition types, so catch and ignore this specific parted
|
||||
error.
|
||||
|
||||
I tested this by adding a Sun disk as a second disk to a Fedora
|
||||
guest and doing inspection. Previously the operation would
|
||||
fail:
|
||||
|
||||
$ guestfish --ro -a /var/tmp/fedora-41.img -a /var/tmp/dump.img -i
|
||||
libguestfs: error: inspect_os: parted exited with status 1: Warning:
|
||||
The disk CHS geometry (205603,255,2) reported by the operating
|
||||
system does not match the geometry stored on the disk label
|
||||
(64887,16,101).
|
||||
|
||||
After this change it succeeds:
|
||||
|
||||
$ guestfish --ro -a /var/tmp/fedora-41.img -a /var/tmp/dump.img -i
|
||||
|
||||
Welcome to guestfish, the guest filesystem shell for
|
||||
editing virtual machine filesystems and disk images.
|
||||
|
||||
Type: ‘help’ for help on commands
|
||||
‘man’ to read the manual
|
||||
‘quit’ to quit the shell
|
||||
|
||||
Operating system: Fedora Linux 41 (Forty One)
|
||||
/dev/sda3 mounted on /
|
||||
/dev/sda2 mounted on /boot
|
||||
|
||||
Fixes: https://redhat.atlassian.net/browse/RHEL-165220
|
||||
(cherry picked from commit 8d83bf2bcf31c5206b6deaa5e993009a85ff174f)
|
||||
---
|
||||
daemon/listfs.ml | 44 ++++++++++++++++++++++++++++----------------
|
||||
1 file changed, 28 insertions(+), 16 deletions(-)
|
||||
|
||||
diff --git a/daemon/listfs.ml b/daemon/listfs.ml
|
||||
index 067314c47..8ca5ca8a8 100644
|
||||
--- a/daemon/listfs.ml
|
||||
+++ b/daemon/listfs.ml
|
||||
@@ -118,30 +118,42 @@ and is_partition_can_hold_filesystem partition =
|
||||
let device = Devsparts.part_to_dev partition
|
||||
and partnum = Devsparts.part_to_partnum partition in
|
||||
|
||||
- match Parted.part_get_parttype device with
|
||||
- | "msdos" ->
|
||||
- if Parted.part_get_mbr_part_type device partnum = "extended" then
|
||||
- false
|
||||
- else if partnum = 1 && Utils.has_bogus_mbr device then
|
||||
- true
|
||||
- else
|
||||
- true
|
||||
+ try
|
||||
+ match Parted.part_get_parttype device with
|
||||
+ | "msdos" ->
|
||||
+ if Parted.part_get_mbr_part_type device partnum = "extended" then
|
||||
+ false
|
||||
+ else if partnum = 1 && Utils.has_bogus_mbr device then
|
||||
+ true
|
||||
+ else
|
||||
+ true
|
||||
|
||||
- | "gpt" ->
|
||||
- let gpt_type = Sfdisk.part_get_gpt_type device partnum in
|
||||
- (match gpt_type with
|
||||
- (* Windows Logical Disk Manager metadata partition. *)
|
||||
- | "5808C8AA-7E8F-42E0-85D2-E1E90434CFB3"
|
||||
+ | "gpt" ->
|
||||
+ let gpt_type = Sfdisk.part_get_gpt_type device partnum in
|
||||
+ (match gpt_type with
|
||||
+ (* Windows Logical Disk Manager metadata partition. *)
|
||||
+ | "5808C8AA-7E8F-42E0-85D2-E1E90434CFB3"
|
||||
(* Windows Logical Disk Manager data partition. *)
|
||||
| "AF9B60A0-1431-4F62-BC68-3311714A69AD"
|
||||
(* Microsoft Reserved Partition. *)
|
||||
| "E3C9E316-0B5C-4DB8-817D-F92DF00215AE"
|
||||
(* Windows Snapshot Partition. *)
|
||||
| "CADDEBF1-4400-4DE8-B103-12117DCF3CCF" -> false
|
||||
- | _ -> true
|
||||
- )
|
||||
+ | _ -> true
|
||||
+ )
|
||||
|
||||
- | _ -> (* unknown or other *)
|
||||
+ | _ -> (* unknown or other *)
|
||||
+ true
|
||||
+
|
||||
+ with
|
||||
+ | Failure msg when String.find msg "CHS geometry" >= 0 ->
|
||||
+ (* Parted has poor handling of "sun" partition types, always
|
||||
+ * issuing a warning because the CHS doesn't match the physical
|
||||
+ * geometry. Ignore this as we don't care about it in this
|
||||
+ * function (RHEL-165220).
|
||||
+ *)
|
||||
+ eprintf "is_partition_can_hold_filesystem: \
|
||||
+ ignoring warning from parted: %s\n%!" msg;
|
||||
true
|
||||
|
||||
(* Use vfs-type to check for a filesystem of some sort of [device].
|
||||
--
|
||||
2.47.3
|
||||
|
||||
684
0014-daemon-Move-read_whole_file-to-common-utils.patch
Normal file
684
0014-daemon-Move-read_whole_file-to-common-utils.patch
Normal file
@ -0,0 +1,684 @@
|
||||
From 1308ee6c911cdaaa9ed15e9fb45a0c59d45c2490 Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Tue, 28 Apr 2026 11:51:30 +0100
|
||||
Subject: [PATCH] daemon: Move read_whole_file to common/utils
|
||||
|
||||
Remove our read_whole_file function. A similar function will be added
|
||||
to common/utils which we will use instead.
|
||||
|
||||
Update common submodule, pulling in:
|
||||
|
||||
Richard W.M. Jones (2):
|
||||
mldrivers/firmware.ml: Ignore CHS geometry error from parted
|
||||
utils: Add read_whole_file function
|
||||
|
||||
Srihari Parimi (2):
|
||||
mltools: add prefix to debug () output
|
||||
mltools: for external commands include function name in debug() output
|
||||
|
||||
Susant Sahani (1):
|
||||
smp: respect cgroup v2 CPU limits for appliance SMP
|
||||
|
||||
(cherry picked from commit 76f590de0626ccc10d8aaecc1a7d9761189b6117)
|
||||
---
|
||||
common | 2 +-
|
||||
daemon/daemon.h | 1 -
|
||||
daemon/ntfsclone.c | 3 +--
|
||||
daemon/tar.c | 3 +--
|
||||
daemon/utils.c | 58 ----------------------------------------------
|
||||
5 files changed, 3 insertions(+), 64 deletions(-)
|
||||
|
||||
Submodule common 3ac5d1841..800510306:
|
||||
diff --git a/common/edit/file-edit.c b/common/edit/file-edit.c
|
||||
index ef56ed1..a10d61c 100644
|
||||
--- a/common/edit/file-edit.c
|
||||
+++ b/common/edit/file-edit.c
|
||||
@@ -119,7 +119,7 @@ edit_file_editor (guestfs_h *g, const char *filename, const char *editor,
|
||||
fprintf (stderr, "%s\n", cmd);
|
||||
|
||||
r = system (cmd);
|
||||
- if (r == -1 || WEXITSTATUS (r) != 0) {
|
||||
+ if (r == -1 || !WIFEXITED (r) || WEXITSTATUS (r) != 0) {
|
||||
perror (cmd);
|
||||
return -1;
|
||||
}
|
||||
@@ -194,7 +194,7 @@ edit_file_perl (guestfs_h *g, const char *filename, const char *perl_expr,
|
||||
fprintf (stderr, "%s\n", cmd);
|
||||
|
||||
r = system (cmd);
|
||||
- if (r == -1 || WEXITSTATUS (r) != 0)
|
||||
+ if (r == -1 || !WIFEXITED (r) || WEXITSTATUS (r) != 0)
|
||||
return -1;
|
||||
|
||||
if (rename (outfile, tmpfilename) == -1) {
|
||||
diff --git a/common/mlpcre/Makefile.am b/common/mlpcre/Makefile.am
|
||||
index a1d8b02..30a60f6 100644
|
||||
--- a/common/mlpcre/Makefile.am
|
||||
+++ b/common/mlpcre/Makefile.am
|
||||
@@ -83,7 +83,7 @@ endif
|
||||
libmlpcre_a_DEPENDENCIES = $(OBJECTS)
|
||||
|
||||
$(MLPCRE_CMA): $(OBJECTS) libmlpcre.a
|
||||
- $(OCAMLFIND) mklib $(OCAMLPACKAGES) \
|
||||
+ $(AM_V_GEN) $(OCAMLFIND) mklib $(OCAMLPACKAGES) \
|
||||
$(OBJECTS) $(libmlpcre_a_OBJECTS) -cclib -lpcre2-8 -o mlpcre
|
||||
|
||||
# Tests.
|
||||
diff --git a/common/mlstdutils/Makefile.am b/common/mlstdutils/Makefile.am
|
||||
index b9632b0..0f88190 100644
|
||||
--- a/common/mlstdutils/Makefile.am
|
||||
+++ b/common/mlstdutils/Makefile.am
|
||||
@@ -84,11 +84,11 @@ endif
|
||||
libmlstdutils_a_DEPENDENCIES = $(OBJECTS)
|
||||
|
||||
mlstdutils.cma: $(BOBJECTS)
|
||||
- $(OCAMLFIND) ocamlc $(OCAMLPACKAGES) -a $^ -o $@
|
||||
+ $(AM_V_GEN) $(OCAMLFIND) ocamlc $(OCAMLPACKAGES) -a $^ -o $@
|
||||
|
||||
if HAVE_OCAMLOPT
|
||||
mlstdutils.cmxa: $(XOBJECTS)
|
||||
- $(OCAMLFIND) ocamlopt $(OCAMLPACKAGES) -a $^ -o $@
|
||||
+ $(AM_V_GEN) $(OCAMLFIND) ocamlopt $(OCAMLPACKAGES) -a $^ -o $@
|
||||
endif
|
||||
|
||||
# Tests.
|
||||
diff --git a/common/mlstdutils/std_utils.mli b/common/mlstdutils/std_utils.mli
|
||||
index 6c1911d..77cf107 100644
|
||||
--- a/common/mlstdutils/std_utils.mli
|
||||
+++ b/common/mlstdutils/std_utils.mli
|
||||
@@ -51,6 +51,7 @@ module List : sig
|
||||
val find_all : ('a -> bool) -> 'a list -> 'a list
|
||||
val partition : ('a -> bool) -> 'a list -> 'a list * 'a list
|
||||
val assoc : 'a -> ('a * 'b) list -> 'b
|
||||
+ val assoc_opt : 'a -> ('a * 'b) list -> 'b option
|
||||
val assq : 'a -> ('a * 'b) list -> 'b
|
||||
val mem_assoc : 'a -> ('a * 'b) list -> bool
|
||||
val mem_assq : 'a -> ('a * 'b) list -> bool
|
||||
diff --git a/common/mlutils/Makefile.am b/common/mlutils/Makefile.am
|
||||
index d52cb9c..084ce63 100644
|
||||
--- a/common/mlutils/Makefile.am
|
||||
+++ b/common/mlutils/Makefile.am
|
||||
@@ -86,7 +86,7 @@ endif
|
||||
libmlcutils_a_DEPENDENCIES = $(OBJECTS)
|
||||
|
||||
$(MLCUTILS_CMA): $(OBJECTS) libmlcutils.a
|
||||
- $(OCAMLFIND) mklib $(OCAMLPACKAGES) \
|
||||
+ $(AM_V_GEN) $(OCAMLFIND) mklib $(OCAMLPACKAGES) \
|
||||
$(OBJECTS) $(libmlcutils_a_OBJECTS) \
|
||||
-cclib -lutils \
|
||||
-o mlcutils
|
||||
diff --git a/common/mlutils/c_utils-c.c b/common/mlutils/c_utils-c.c
|
||||
index d9c1a48..f0e2798 100644
|
||||
--- a/common/mlutils/c_utils-c.c
|
||||
+++ b/common/mlutils/c_utils-c.c
|
||||
@@ -68,7 +68,7 @@ guestfs_int_mlutils_shell_unquote (value strv)
|
||||
|
||||
ret = guestfs_int_shell_unquote (String_val (strv));
|
||||
if (ret == NULL)
|
||||
- unix_error (errno, (char *) "guestfs_int_shell_unquote", Nothing);
|
||||
+ caml_unix_error (errno, (char *) "guestfs_int_shell_unquote", Nothing);
|
||||
|
||||
retv = caml_copy_string (ret);
|
||||
free (ret);
|
||||
@@ -101,6 +101,8 @@ guestfs_int_mlutils_full_path (value dirv, value namev)
|
||||
name = String_val (Field (namev, 0));
|
||||
|
||||
ret = guestfs_int_full_path (String_val (dirv), name);
|
||||
+ if (ret == NULL)
|
||||
+ caml_unix_error (errno, (char *) "guestfs_int_full_path", dirv);
|
||||
rv = caml_copy_string (ret);
|
||||
free (ret);
|
||||
|
||||
diff --git a/common/mlutils/unix_utils-c.c b/common/mlutils/unix_utils-c.c
|
||||
index ee5a379..919f526 100644
|
||||
--- a/common/mlutils/unix_utils-c.c
|
||||
+++ b/common/mlutils/unix_utils-c.c
|
||||
@@ -65,6 +65,8 @@
|
||||
#include <caml/mlvalues.h>
|
||||
#include <caml/unixsupport.h>
|
||||
|
||||
+#include "guestfs-utils.h"
|
||||
+
|
||||
extern value guestfs_int_mllib_dev_t_makedev (value majv, value minv);
|
||||
extern value guestfs_int_mllib_dev_t_major (value devv);
|
||||
extern value guestfs_int_mllib_dev_t_minor (value devv);
|
||||
@@ -147,7 +149,7 @@ guestfs_int_mllib_fnmatch (value patternv, value strv, value flagsv)
|
||||
/* XXX The fnmatch specification doesn't mention what errors can
|
||||
* be returned by fnmatch. Assume they are errnos for now.
|
||||
*/
|
||||
- unix_error (errno, (char *) "fnmatch", patternv);
|
||||
+ caml_unix_error (errno, (char *) "fnmatch", patternv);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -180,16 +182,16 @@ guestfs_int_mllib_fsync_file (value filenamev)
|
||||
/* Note to do fsync you have to open for write. */
|
||||
fd = open (filename, O_RDWR);
|
||||
if (fd == -1)
|
||||
- unix_error (errno, (char *) "open", filenamev);
|
||||
+ caml_unix_error (errno, (char *) "open", filenamev);
|
||||
|
||||
if (fsync (fd) == -1) {
|
||||
err = errno;
|
||||
close (fd);
|
||||
- unix_error (err, (char *) "fsync", filenamev);
|
||||
+ caml_unix_error (err, (char *) "fsync", filenamev);
|
||||
}
|
||||
|
||||
if (close (fd) == -1)
|
||||
- unix_error (errno, (char *) "close", filenamev);
|
||||
+ caml_unix_error (errno, (char *) "close", filenamev);
|
||||
|
||||
CAMLreturn (Val_unit);
|
||||
}
|
||||
@@ -203,11 +205,14 @@ guestfs_int_mllib_mkdtemp (value val_pattern)
|
||||
|
||||
pattern = strdup (String_val (val_pattern));
|
||||
if (pattern == NULL)
|
||||
- unix_error (errno, (char *) "strdup", val_pattern);
|
||||
+ caml_unix_error (errno, (char *) "strdup", val_pattern);
|
||||
|
||||
ret = mkdtemp (pattern);
|
||||
- if (ret == NULL)
|
||||
- unix_error (errno, (char *) "mkdtemp", val_pattern);
|
||||
+ if (ret == NULL) {
|
||||
+ int err = errno;
|
||||
+ free (pattern);
|
||||
+ caml_unix_error (err, (char *) "mkdtemp", val_pattern);
|
||||
+ }
|
||||
|
||||
rv = caml_copy_string (ret);
|
||||
free (pattern);
|
||||
@@ -224,7 +229,7 @@ guestfs_int_mllib_realpath (value pathv)
|
||||
|
||||
r = realpath (String_val (pathv), NULL);
|
||||
if (r == NULL)
|
||||
- unix_error (errno, (char *) "realpath", pathv);
|
||||
+ caml_unix_error (errno, (char *) "realpath", pathv);
|
||||
|
||||
rv = caml_copy_string (r);
|
||||
free (r);
|
||||
@@ -252,7 +257,7 @@ guestfs_int_mllib_statvfs_statvfs (value pathv)
|
||||
struct statvfs buf;
|
||||
|
||||
if (statvfs (String_val (pathv), &buf) == -1)
|
||||
- unix_error (errno, (char *) "statvfs", pathv);
|
||||
+ caml_unix_error (errno, (char *) "statvfs", pathv);
|
||||
|
||||
f_bsize = buf.f_bsize;
|
||||
f_frsize = buf.f_frsize;
|
||||
@@ -276,7 +281,7 @@ guestfs_int_mllib_statvfs_statvfs (value pathv)
|
||||
(PULARGE_INTEGER) &free_bytes_available,
|
||||
(PULARGE_INTEGER) &total_number_of_bytes,
|
||||
(PULARGE_INTEGER) &total_number_of_free_bytes))
|
||||
- unix_error (EIO, (char *) "statvfs: GetDiskFreeSpaceEx", pathv);
|
||||
+ caml_unix_error (EIO, (char *) "statvfs: GetDiskFreeSpaceEx", pathv);
|
||||
|
||||
/* XXX I couldn't determine how to get block size. MSDN has a
|
||||
* unhelpful hard-coded list here:
|
||||
@@ -341,15 +346,17 @@ guestfs_int_mllib_statvfs_statvfs (value pathv)
|
||||
CAMLreturn (rv);
|
||||
}
|
||||
|
||||
-/* NB: This is a [@@noalloc] call. */
|
||||
value
|
||||
guestfs_int_mllib_statvfs_is_network_filesystem (value pathv)
|
||||
{
|
||||
+ CAMLparam1 (pathv);
|
||||
+ CAMLlocal1 (rv);
|
||||
+
|
||||
#ifdef HAVE_STATFS
|
||||
struct statfs buf;
|
||||
|
||||
if (statfs (String_val (pathv), &buf) == -1)
|
||||
- unix_error (errno, (char *) "statvfs", pathv);
|
||||
+ caml_unix_error (errno, (char *) "statvfs", pathv);
|
||||
|
||||
/* Some but not all of these are defined in <linux/magic.h>. */
|
||||
#ifndef CIFS_MAGIC_NUMBER
|
||||
@@ -362,12 +369,14 @@ guestfs_int_mllib_statvfs_is_network_filesystem (value pathv)
|
||||
#define SMB_SUPER_MAGIC 0x517b
|
||||
#endif
|
||||
|
||||
- return Val_bool ((unsigned int) buf.f_type == CIFS_MAGIC_NUMBER ||
|
||||
- (unsigned int) buf.f_type == NFS_SUPER_MAGIC ||
|
||||
- (unsigned int) buf.f_type == SMB_SUPER_MAGIC);
|
||||
+ rv = Val_bool ((unsigned int) buf.f_type == CIFS_MAGIC_NUMBER ||
|
||||
+ (unsigned int) buf.f_type == NFS_SUPER_MAGIC ||
|
||||
+ (unsigned int) buf.f_type == SMB_SUPER_MAGIC);
|
||||
#else
|
||||
- return Val_bool (0);
|
||||
+ rv = Val_bool (0);
|
||||
#endif
|
||||
+
|
||||
+ CAMLreturn (rv);
|
||||
}
|
||||
|
||||
/* NB: This is a [@@noalloc] call. */
|
||||
diff --git a/common/mlutils/unix_utils.ml b/common/mlutils/unix_utils.ml
|
||||
index b79144a..9d7e11a 100644
|
||||
--- a/common/mlutils/unix_utils.ml
|
||||
+++ b/common/mlutils/unix_utils.ml
|
||||
@@ -82,10 +82,35 @@ module StatVFS = struct
|
||||
let free_space { f_bsize = bsize; f_bavail = bavail } = bsize *^ bavail
|
||||
|
||||
external is_network_filesystem : string -> bool =
|
||||
- "guestfs_int_mllib_statvfs_is_network_filesystem" [@@noalloc]
|
||||
+ "guestfs_int_mllib_statvfs_is_network_filesystem"
|
||||
end
|
||||
|
||||
module Sysconf = struct
|
||||
external nr_processors_online : unit -> int =
|
||||
"guestfs_int_mllib_sysconf_nr_processors_online" [@@noalloc]
|
||||
end
|
||||
+
|
||||
+module Cgroup = struct
|
||||
+ let v2_cpus () =
|
||||
+ let file = "/sys/fs/cgroup/cpu.max" in
|
||||
+ if Sys.file_exists file then
|
||||
+ try
|
||||
+ let line = read_first_line_from_file file in
|
||||
+ if String.starts_with ~prefix:"max" line then
|
||||
+ None
|
||||
+ else
|
||||
+ let quota, period =
|
||||
+ Scanf.sscanf line "%Ld %Ld" (fun q p -> (q, p)) in
|
||||
+ if period > 0L then
|
||||
+ Some (max 1 (Int64.to_int (Int64.div quota period)))
|
||||
+ else None
|
||||
+ with
|
||||
+ | Scanf.Scan_failure _ | Failure _ | End_of_file -> None
|
||||
+ else
|
||||
+ None
|
||||
+
|
||||
+ let nr_cpus_available () =
|
||||
+ match v2_cpus () with
|
||||
+ | Some cpus -> cpus
|
||||
+ | None -> Sysconf.nr_processors_online ()
|
||||
+end
|
||||
diff --git a/common/mlutils/unix_utils.mli b/common/mlutils/unix_utils.mli
|
||||
index aead4df..cb4f042 100644
|
||||
--- a/common/mlutils/unix_utils.mli
|
||||
+++ b/common/mlutils/unix_utils.mli
|
||||
@@ -130,3 +130,21 @@ module Sysconf : sig
|
||||
Note this never fails. In case we cannot get the number of
|
||||
cores it returns 1. *)
|
||||
end
|
||||
+
|
||||
+module Cgroup : sig
|
||||
+ (** Functions to read CPU limits from cgroup filesystems. *)
|
||||
+
|
||||
+ val v2_cpus : unit -> int option
|
||||
+ (** [v2_cpus ()] reads the cgroup v2 CPU quota from
|
||||
+ [/sys/fs/cgroup/cpu.max] and returns the number of CPUs
|
||||
+ allocated (quota / period), or [None] if the file does not
|
||||
+ exist, the quota is "max" (unlimited), or the file cannot
|
||||
+ be parsed. The kernel stores quota and period as [long]
|
||||
+ values in microseconds, so we parse them as [Int64]. *)
|
||||
+
|
||||
+ val nr_cpus_available : unit -> int
|
||||
+ (** [nr_cpus_available ()] returns the number of CPUs available,
|
||||
+ taking into account cgroup v2 CPU limits.
|
||||
+ Falls back to {!Sysconf.nr_processors_online} if no cgroup
|
||||
+ limits are set. *)
|
||||
+end
|
||||
diff --git a/common/options/keys.c b/common/options/keys.c
|
||||
index 7027104..b8f19ce 100644
|
||||
--- a/common/options/keys.c
|
||||
+++ b/common/options/keys.c
|
||||
@@ -78,6 +78,7 @@ read_key (const char *param)
|
||||
len = getline (&ret, &allocsize, infp);
|
||||
if (len == -1) {
|
||||
perror ("getline");
|
||||
+ free (ret);
|
||||
ret = NULL;
|
||||
goto error;
|
||||
}
|
||||
diff --git a/common/parallel/parallel.c b/common/parallel/parallel.c
|
||||
index 18b0607..88ad819 100644
|
||||
--- a/common/parallel/parallel.c
|
||||
+++ b/common/parallel/parallel.c
|
||||
@@ -221,6 +221,7 @@ worker_thread (void *thread_data_vp)
|
||||
g = guestfs_create ();
|
||||
if (g == NULL) {
|
||||
perror ("guestfs_create");
|
||||
+ fclose (fp);
|
||||
thread_data->r = -1;
|
||||
return &thread_data->r;
|
||||
}
|
||||
diff --git a/common/qemuopts/qemuopts.c b/common/qemuopts/qemuopts.c
|
||||
index 7dd9136..e351465 100644
|
||||
--- a/common/qemuopts/qemuopts.c
|
||||
+++ b/common/qemuopts/qemuopts.c
|
||||
@@ -756,6 +756,11 @@ qemuopts_to_channel (struct qemuopts *qopts, FILE *fp)
|
||||
}
|
||||
fputc ('\n', fp);
|
||||
|
||||
+ if (ferror (fp)) {
|
||||
+ errno = EIO;
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1035,5 +1040,10 @@ qemuopts_to_config_channel (struct qemuopts *qopts, FILE *fp)
|
||||
fprintf (fp, "\n");
|
||||
}
|
||||
|
||||
+ if (ferror (fp)) {
|
||||
+ errno = EIO;
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
diff --git a/common/update-submodule.sh b/common/update-submodule.sh
|
||||
new file mode 100755
|
||||
index 0000000..ecf22f1
|
||||
--- /dev/null
|
||||
+++ b/common/update-submodule.sh
|
||||
@@ -0,0 +1,52 @@
|
||||
+#!/bin/bash
|
||||
+# (C) Copyright 2026 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
+
|
||||
+# Generate a submodule update commit, with formatted shortlog output.
|
||||
+# Run this from the parent repo like: ./common/update-submodule.sh
|
||||
+# Then `git commit --amend ...` as desired.
|
||||
+
|
||||
+set -euo pipefail
|
||||
+
|
||||
+if ! git submodule status common &>/dev/null; then
|
||||
+ echo "Error: this script must be run from the top directory of a repo with a 'common/' submodule" >&2
|
||||
+ exit 1
|
||||
+fi
|
||||
+
|
||||
+if ! git diff --quiet --exit-code; then
|
||||
+ echo "Error: working tree has uncommitted changes" >&2
|
||||
+ exit 1
|
||||
+fi
|
||||
+
|
||||
+echo "Running: git submodule update --remote common"
|
||||
+git submodule update --remote common
|
||||
+
|
||||
+if git diff --quiet --exit-code; then
|
||||
+ echo "'common' submodule already up to date"
|
||||
+ exit 0
|
||||
+fi
|
||||
+
|
||||
+OLD_COMMIT=$(git ls-tree HEAD common | awk '{print $3}')
|
||||
+NEW_COMMIT=$(git -C common rev-parse HEAD)
|
||||
+echo "Old 'common' commit: $OLD_COMMIT"
|
||||
+echo "New 'common' commit: $NEW_COMMIT"
|
||||
+
|
||||
+SHORTLOG=$(git -C common shortlog --no-merges "${OLD_COMMIT}..${NEW_COMMIT}" | sed '/^$/!s/^/ /')
|
||||
+git commit -F - common <<EOF
|
||||
+common: update submodule
|
||||
+
|
||||
+$SHORTLOG
|
||||
+EOF
|
||||
diff --git a/common/utils/Makefile.am b/common/utils/Makefile.am
|
||||
index 25c6100..f328dca 100644
|
||||
--- a/common/utils/Makefile.am
|
||||
+++ b/common/utils/Makefile.am
|
||||
@@ -30,6 +30,7 @@ libutils_la_SOURCES = \
|
||||
libxml2-writer-macros.h \
|
||||
pcre2-cleanups.c \
|
||||
stringlists-utils.c \
|
||||
+ whole-file.c \
|
||||
utils.c
|
||||
libutils_la_CPPFLAGS = \
|
||||
-DGUESTFS_NO_DEPRECATED=1 \
|
||||
diff --git a/common/utils/guestfs-utils.h b/common/utils/guestfs-utils.h
|
||||
index e861e7d..a8bd9ac 100644
|
||||
--- a/common/utils/guestfs-utils.h
|
||||
+++ b/common/utils/guestfs-utils.h
|
||||
@@ -113,4 +113,8 @@ extern const char *guestfs_int_strerror (int errnum, char *buf, size_t buflen);
|
||||
/* environ.c */
|
||||
extern char **guestfs_int_copy_environ (char **env, ...);
|
||||
|
||||
+/* whole-file.c */
|
||||
+extern int read_whole_file (const char *filename,
|
||||
+ char **data_r, size_t *size_r);
|
||||
+
|
||||
#endif /* GUESTFS_UTILS_H_ */
|
||||
diff --git a/common/utils/whole-file.c b/common/utils/whole-file.c
|
||||
new file mode 100644
|
||||
index 0000000..a896e02
|
||||
--- /dev/null
|
||||
+++ b/common/utils/whole-file.c
|
||||
@@ -0,0 +1,111 @@
|
||||
+/* libguestfs
|
||||
+ * Copyright (C) 2011-2026 Red Hat Inc.
|
||||
+ *
|
||||
+ * This library is free software; you can redistribute it and/or
|
||||
+ * modify it under the terms of the GNU Lesser General Public
|
||||
+ * License as published by the Free Software Foundation; either
|
||||
+ * version 2 of the License, or (at your option) any later version.
|
||||
+ *
|
||||
+ * This library 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
|
||||
+ * Lesser General Public License for more details.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU Lesser General Public
|
||||
+ * License along with this library; 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 <unistd.h>
|
||||
+#include <fcntl.h>
|
||||
+#include <sys/stat.h>
|
||||
+#include <libintl.h>
|
||||
+
|
||||
+#include "guestfs-utils.h"
|
||||
+
|
||||
+/**
|
||||
+ * Read the whole file C<filename> into a memory buffer.
|
||||
+ *
|
||||
+ * The memory buffer is initialized and returned in C<data_r>. The
|
||||
+ * size of the file in bytes is returned in C<size_r>. The return
|
||||
+ * buffer must be freed by the caller.
|
||||
+ *
|
||||
+ * On error this prints an error on C<stderr> and returns -1. Unlike
|
||||
+ * the similar C<guestfs_int_read_whole_file> this does not use the
|
||||
+ * libguestfs handle or call C<error()>.
|
||||
+ *
|
||||
+ * For the convenience of callers, the returned buffer is
|
||||
+ * NUL-terminated (the NUL is not included in the size).
|
||||
+ *
|
||||
+ * The file must be a B<regular>, B<local>, B<trusted> file. In
|
||||
+ * particular, do not use this function to read files that might be
|
||||
+ * under control of an untrusted user since that will lead to a
|
||||
+ * denial-of-service attack.
|
||||
+ */
|
||||
+int
|
||||
+read_whole_file (const char *filename, char **data_r, size_t *size_r)
|
||||
+{
|
||||
+ int fd;
|
||||
+ char *data;
|
||||
+ off_t size;
|
||||
+ off_t n;
|
||||
+ ssize_t r;
|
||||
+ struct stat statbuf;
|
||||
+
|
||||
+ fd = open (filename, O_RDONLY|O_CLOEXEC);
|
||||
+ if (fd == -1) {
|
||||
+ perror (filename);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ if (fstat (fd, &statbuf) == -1) {
|
||||
+ perror (filename);
|
||||
+ close (fd);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ size = statbuf.st_size;
|
||||
+ data = malloc (size + 1);
|
||||
+ if (data == NULL) {
|
||||
+ perror ("malloc");
|
||||
+ close (fd);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ n = 0;
|
||||
+ while (n < size) {
|
||||
+ r = read (fd, &data[n], size - n);
|
||||
+ if (r == -1) {
|
||||
+ perror (filename);
|
||||
+ free (data);
|
||||
+ close (fd);
|
||||
+ return -1;
|
||||
+ }
|
||||
+ if (r == 0) {
|
||||
+ fprintf (stderr, "%s: unexpected end of input", filename);
|
||||
+ free (data);
|
||||
+ close (fd);
|
||||
+ return -1;
|
||||
+ }
|
||||
+ n += r;
|
||||
+ }
|
||||
+
|
||||
+ if (close (fd) == -1) {
|
||||
+ perror (filename);
|
||||
+ free (data);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ /* For convenience of callers, \0-terminate the data. */
|
||||
+ data[size] = '\0';
|
||||
+
|
||||
+ *data_r = data;
|
||||
+ if (size_r != NULL)
|
||||
+ *size_r = size;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
diff --git a/daemon/daemon.h b/daemon/daemon.h
|
||||
index 72b9e97c0..d3ed90924 100644
|
||||
--- a/daemon/daemon.h
|
||||
+++ b/daemon/daemon.h
|
||||
@@ -87,7 +87,6 @@ extern void udev_settle (void);
|
||||
extern int random_name (char *template);
|
||||
extern char *get_random_uuid (void);
|
||||
extern char *make_exclude_from_file (const char *function, char *const *excludes);
|
||||
-extern char *read_whole_file (const char *filename, size_t *size_r);
|
||||
|
||||
/* mountable functions (in utils.c) */
|
||||
extern char *mountable_to_string (const mountable_t *mountable);
|
||||
diff --git a/daemon/ntfsclone.c b/daemon/ntfsclone.c
|
||||
index e9a4c3ea9..3a3e9a7a7 100644
|
||||
--- a/daemon/ntfsclone.c
|
||||
+++ b/daemon/ntfsclone.c
|
||||
@@ -39,8 +39,7 @@ read_error_file (char *error_file)
|
||||
size_t len;
|
||||
char *str;
|
||||
|
||||
- str = read_whole_file (error_file, &len);
|
||||
- if (str == NULL) {
|
||||
+ if (read_whole_file (error_file, &str, &len) == -1) {
|
||||
str = strdup ("(no error)");
|
||||
if (str == NULL)
|
||||
error (EXIT_FAILURE, errno, "strdup"); /* XXX */
|
||||
diff --git a/daemon/tar.c b/daemon/tar.c
|
||||
index 1d6a4b7eb..faf46051b 100644
|
||||
--- a/daemon/tar.c
|
||||
+++ b/daemon/tar.c
|
||||
@@ -108,8 +108,7 @@ read_error_file (char *error_file)
|
||||
size_t len;
|
||||
char *str;
|
||||
|
||||
- str = read_whole_file (error_file, &len);
|
||||
- if (str == NULL) {
|
||||
+ if (read_whole_file (error_file, &str, &len) == -1) {
|
||||
str = strdup ("(no error)");
|
||||
if (str == NULL)
|
||||
error (EXIT_FAILURE, errno, "strdup"); /* XXX */
|
||||
diff --git a/daemon/utils.c b/daemon/utils.c
|
||||
index 2da33b9aa..d359d3c3b 100644
|
||||
--- a/daemon/utils.c
|
||||
+++ b/daemon/utils.c
|
||||
@@ -845,61 +845,3 @@ cleanup_free_mountable (mountable_t *mountable)
|
||||
free (mountable->volume);
|
||||
}
|
||||
}
|
||||
-
|
||||
-/**
|
||||
- * Read whole file into dynamically allocated array. If there is an
|
||||
- * error, DON'T call reply_with_perror, just return NULL. Returns a
|
||||
- * C<\0>-terminated string. C<size_r> can be specified to get the
|
||||
- * size of the returned data.
|
||||
- */
|
||||
-char *
|
||||
-read_whole_file (const char *filename, size_t *size_r)
|
||||
-{
|
||||
- char *r = NULL;
|
||||
- size_t alloc = 0, size = 0;
|
||||
- int fd;
|
||||
-
|
||||
- fd = open (filename, O_RDONLY|O_CLOEXEC);
|
||||
- if (fd == -1) {
|
||||
- perror (filename);
|
||||
- return NULL;
|
||||
- }
|
||||
-
|
||||
- while (1) {
|
||||
- alloc += 256;
|
||||
- char *r2 = realloc (r, alloc);
|
||||
- if (r2 == NULL) {
|
||||
- perror ("realloc");
|
||||
- free (r);
|
||||
- close (fd);
|
||||
- return NULL;
|
||||
- }
|
||||
- r = r2;
|
||||
-
|
||||
- /* The '- 1' in the size calculation ensures there is space below
|
||||
- * to add \0 to the end of the input.
|
||||
- */
|
||||
- ssize_t n = read (fd, r + size, alloc - size - 1);
|
||||
- if (n == -1) {
|
||||
- fprintf (stderr, "read: %s: %m\n", filename);
|
||||
- free (r);
|
||||
- close (fd);
|
||||
- return NULL;
|
||||
- }
|
||||
- if (n == 0)
|
||||
- break;
|
||||
- size += n;
|
||||
- }
|
||||
-
|
||||
- if (close (fd) == -1) {
|
||||
- fprintf (stderr, "close: %s: %m\n", filename);
|
||||
- free (r);
|
||||
- return NULL;
|
||||
- }
|
||||
-
|
||||
- r[size] = '\0';
|
||||
- if (size_r != NULL)
|
||||
- *size_r = size;
|
||||
-
|
||||
- return r;
|
||||
-}
|
||||
--
|
||||
2.47.3
|
||||
|
||||
40
0015-generator-Adjust-comment-for-String-Key.patch
Normal file
40
0015-generator-Adjust-comment-for-String-Key.patch
Normal file
@ -0,0 +1,40 @@
|
||||
From 84bc5dc2c9c9c82a27270e8068e224af51b7ac89 Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Tue, 28 Apr 2026 09:18:27 +0100
|
||||
Subject: [PATCH] generator: Adjust comment for String(Key)
|
||||
|
||||
Just tidy up the comment.
|
||||
|
||||
(cherry picked from commit f2b1d9de9b2adaf9e372438f27da710d243e628d)
|
||||
---
|
||||
generator/types.mli | 14 ++++++++------
|
||||
1 file changed, 8 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/generator/types.mli b/generator/types.mli
|
||||
index 0e1b89846..01f00044e 100644
|
||||
--- a/generator/types.mli
|
||||
+++ b/generator/types.mli
|
||||
@@ -185,12 +185,14 @@ and stringt =
|
||||
stdin or write to stdout. *)
|
||||
|
||||
| Key
|
||||
- (** Key material / passphrase. Eventually we should treat this
|
||||
- as sensitive and mlock it into physical RAM. However this
|
||||
- is highly complex because of all the places that XDR-encoded
|
||||
- strings can end up. So currently the only difference from
|
||||
- 'PlainString' is the way that guestfish requests these
|
||||
- parameters from the user. *)
|
||||
+ (** Key material / passphrase.
|
||||
+
|
||||
+ Currently the only difference from 'PlainString' is the way
|
||||
+ that guestfish requests these parameters from the user.
|
||||
+
|
||||
+ Eventually we should treat this as sensitive and mlock it
|
||||
+ into physical RAM. This is highly complex because of all
|
||||
+ the places that XDR-encoded strings can end up. *)
|
||||
|
||||
| GUID
|
||||
(** A GUID string.
|
||||
--
|
||||
2.47.3
|
||||
|
||||
151
0016-daemon-Move-some-deprecated-functions-to-new-Luks-mo.patch
Normal file
151
0016-daemon-Move-some-deprecated-functions-to-new-Luks-mo.patch
Normal file
@ -0,0 +1,151 @@
|
||||
From 9ad80afc0c79311c7d67b4dd67aa80a41e039263 Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Tue, 28 Apr 2026 09:36:18 +0100
|
||||
Subject: [PATCH] daemon: Move some deprecated functions to new Luks module
|
||||
|
||||
No change, just code movement.
|
||||
|
||||
(cherry picked from commit 5e7aef40c2e9a81f5ad3f8c2e1ff1389e7825efb)
|
||||
---
|
||||
.gitignore | 1 +
|
||||
daemon/Makefile.am | 3 +++
|
||||
daemon/cryptsetup.ml | 9 +-------
|
||||
daemon/luks.ml | 32 ++++++++++++++++++++++++++++
|
||||
generator/actions_core_deprecated.ml | 6 +++---
|
||||
5 files changed, 40 insertions(+), 11 deletions(-)
|
||||
create mode 100644 daemon/luks.ml
|
||||
|
||||
diff --git a/.gitignore b/.gitignore
|
||||
index c8a8312fa..7715d2cfc 100644
|
||||
--- a/.gitignore
|
||||
+++ b/.gitignore
|
||||
@@ -95,6 +95,7 @@ Makefile.in
|
||||
/daemon/ldm.mli
|
||||
/daemon/link.mli
|
||||
/daemon/listfs.mli
|
||||
+/daemon/luks.mli
|
||||
/daemon/lvm.mli
|
||||
/daemon/lvm_dm.mli
|
||||
/daemon/lvm_full.mli
|
||||
diff --git a/daemon/Makefile.am b/daemon/Makefile.am
|
||||
index d4a805046..6f3b9e7d5 100644
|
||||
--- a/daemon/Makefile.am
|
||||
+++ b/daemon/Makefile.am
|
||||
@@ -49,6 +49,7 @@ generator_built = \
|
||||
ldm.mli \
|
||||
link.mli \
|
||||
listfs.mli \
|
||||
+ luks.mli \
|
||||
lvm.mli \
|
||||
lvm_dm.mli \
|
||||
lvm_full.mli \
|
||||
@@ -296,6 +297,7 @@ SOURCES_MLI = \
|
||||
ldm.mli \
|
||||
link.mli \
|
||||
listfs.mli \
|
||||
+ luks.mli \
|
||||
lvm.mli \
|
||||
lvm_dm.mli \
|
||||
lvm_full.mli \
|
||||
@@ -327,6 +329,7 @@ SOURCES_ML = \
|
||||
blkid.ml \
|
||||
btrfs.ml \
|
||||
cryptsetup.ml \
|
||||
+ luks.ml \
|
||||
devsparts.ml \
|
||||
file_helper.ml \
|
||||
file.ml \
|
||||
diff --git a/daemon/cryptsetup.ml b/daemon/cryptsetup.ml
|
||||
index 6f677aef0..002e0993a 100644
|
||||
--- a/daemon/cryptsetup.ml
|
||||
+++ b/daemon/cryptsetup.ml
|
||||
@@ -1,5 +1,5 @@
|
||||
(* guestfs-inspection
|
||||
- * Copyright (C) 2009-2025 Red Hat Inc.
|
||||
+ * Copyright (C) 2009-2026 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
|
||||
@@ -70,10 +70,3 @@ let cryptsetup_close device =
|
||||
ignore (command "cryptsetup" ["close"; mapname]);
|
||||
|
||||
udev_settle ()
|
||||
-
|
||||
-(* Deprecated APIs for backwards compatibility. *)
|
||||
-let luks_open device key mapname =
|
||||
- cryptsetup_open ~crypttype:"luks" device key mapname
|
||||
-let luks_open_ro device key mapname =
|
||||
- cryptsetup_open ~crypttype:"luks" ~readonly:true device key mapname
|
||||
-let luks_close = cryptsetup_close
|
||||
diff --git a/daemon/luks.ml b/daemon/luks.ml
|
||||
new file mode 100644
|
||||
index 000000000..e7e6deefe
|
||||
--- /dev/null
|
||||
+++ b/daemon/luks.ml
|
||||
@@ -0,0 +1,32 @@
|
||||
+(* guestfs-inspection
|
||||
+ * Copyright (C) 2009-2026 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 Unix
|
||||
+
|
||||
+open Std_utils
|
||||
+
|
||||
+open Utils
|
||||
+
|
||||
+(* Deprecated APIs for backwards compatibility. *)
|
||||
+let luks_open device key mapname =
|
||||
+ Cryptsetup.cryptsetup_open ~crypttype:"luks" device key mapname
|
||||
+let luks_open_ro device key mapname =
|
||||
+ Cryptsetup.cryptsetup_open ~crypttype:"luks" ~readonly:true device key mapname
|
||||
+let luks_close =
|
||||
+ Cryptsetup.cryptsetup_close
|
||||
diff --git a/generator/actions_core_deprecated.ml b/generator/actions_core_deprecated.ml
|
||||
index 308495c45..d930b8b88 100644
|
||||
--- a/generator/actions_core_deprecated.ml
|
||||
+++ b/generator/actions_core_deprecated.ml
|
||||
@@ -843,7 +843,7 @@ physical volumes, volume groups and logical volumes." };
|
||||
{ defaults with
|
||||
name = "luks_open"; added = (1, 5, 1);
|
||||
style = RErr, [String (Device, "device"); String (Key, "key"); String (PlainString, "mapname")], [];
|
||||
- impl = OCaml "Cryptsetup.luks_open";
|
||||
+ impl = OCaml "Luks.luks_open";
|
||||
optional = Some "luks";
|
||||
deprecated_by = Replaced_by "cryptsetup_open";
|
||||
shortdesc = "open a LUKS-encrypted block device";
|
||||
@@ -869,7 +869,7 @@ devices.|} };
|
||||
{ defaults with
|
||||
name = "luks_open_ro"; added = (1, 5, 1);
|
||||
style = RErr, [String (Device, "device"); String (Key, "key"); String (PlainString, "mapname")], [];
|
||||
- impl = OCaml "Cryptsetup.luks_open_ro";
|
||||
+ impl = OCaml "Luks.luks_open_ro";
|
||||
optional = Some "luks";
|
||||
deprecated_by = Replaced_by "cryptsetup_open";
|
||||
shortdesc = "open a LUKS-encrypted block device read-only";
|
||||
@@ -880,7 +880,7 @@ mapping is created." };
|
||||
{ defaults with
|
||||
name = "luks_close"; added = (1, 5, 1);
|
||||
style = RErr, [String (Device, "device")], [];
|
||||
- impl = OCaml "Cryptsetup.luks_close";
|
||||
+ impl = OCaml "Luks.luks_close";
|
||||
optional = Some "luks";
|
||||
deprecated_by = Replaced_by "cryptsetup_close";
|
||||
shortdesc = "close a LUKS device";
|
||||
--
|
||||
2.47.3
|
||||
|
||||
323
0017-daemon-Rewrite-some-luks_-APIs-in-OCaml.patch
Normal file
323
0017-daemon-Rewrite-some-luks_-APIs-in-OCaml.patch
Normal file
@ -0,0 +1,323 @@
|
||||
From fcc511920866437fbe71739f0c170e377e18f73e Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Tue, 28 Apr 2026 09:57:27 +0100
|
||||
Subject: [PATCH] daemon: Rewrite some luks_* APIs in OCaml
|
||||
|
||||
No change. Just rewriting these to so that all functions that handle
|
||||
cryptsetup Key parameters are written in OCaml, so we can use a common
|
||||
function in future for handling base64.
|
||||
|
||||
Note that the previous versions of these functions ignored the case of
|
||||
cryptsetup exiting with a non-zero error code, as does existing
|
||||
Cryptsetup.cryptsetup_open. Unclear if this is right or not, but this
|
||||
change keeps the same behaviour.
|
||||
|
||||
(cherry picked from commit ec3548af1e6c75e021e49887fd27efa9262be98b)
|
||||
---
|
||||
daemon/luks.c | 182 --------------------------------------
|
||||
daemon/luks.ml | 59 ++++++++++++
|
||||
generator/actions_core.ml | 4 +
|
||||
3 files changed, 63 insertions(+), 182 deletions(-)
|
||||
|
||||
diff --git a/daemon/luks.c b/daemon/luks.c
|
||||
index 9d120b0eb..db061fe66 100644
|
||||
--- a/daemon/luks.c
|
||||
+++ b/daemon/luks.c
|
||||
@@ -34,188 +34,6 @@ optgroup_luks_available (void)
|
||||
return prog_exists ("cryptsetup");
|
||||
}
|
||||
|
||||
-#pragma GCC diagnostic push
|
||||
-#pragma GCC diagnostic ignored "-Wanalyzer-possible-null-argument"
|
||||
-/* Callers must also call remove_temp (tempfile). */
|
||||
-static char *
|
||||
-write_key_to_temp (const char *key)
|
||||
-{
|
||||
- char *tempfile;
|
||||
- int fd;
|
||||
- size_t len;
|
||||
-
|
||||
- tempfile = strdup ("/tmp/luksXXXXXX");
|
||||
- if (!tempfile) {
|
||||
- reply_with_perror ("strdup");
|
||||
- return NULL;
|
||||
- }
|
||||
-
|
||||
- fd = mkstemp (tempfile);
|
||||
- if (fd == -1) {
|
||||
- reply_with_perror ("mkstemp");
|
||||
- goto error;
|
||||
- }
|
||||
-
|
||||
- len = strlen (key);
|
||||
- if (xwrite (fd, key, len) == -1) {
|
||||
- reply_with_perror ("write");
|
||||
- close (fd);
|
||||
- goto error;
|
||||
- }
|
||||
-
|
||||
- if (close (fd) == -1) {
|
||||
- reply_with_perror ("close");
|
||||
- goto error;
|
||||
- }
|
||||
-
|
||||
- return tempfile;
|
||||
-
|
||||
- error:
|
||||
- unlink (tempfile);
|
||||
- free (tempfile);
|
||||
- return NULL;
|
||||
-}
|
||||
-#pragma GCC diagnostic pop
|
||||
-
|
||||
-#pragma GCC diagnostic push
|
||||
-#pragma GCC diagnostic ignored "-Wanalyzer-double-free"
|
||||
-static void
|
||||
-remove_temp (char *tempfile)
|
||||
-{
|
||||
- unlink (tempfile);
|
||||
- free (tempfile);
|
||||
-}
|
||||
-#pragma GCC diagnostic pop
|
||||
-
|
||||
-static int
|
||||
-luks_format (const char *device, const char *key, int keyslot,
|
||||
- const char *cipher)
|
||||
-{
|
||||
- char *tempfile = write_key_to_temp (key);
|
||||
- if (!tempfile)
|
||||
- return -1;
|
||||
-
|
||||
- const char *argv[MAX_ARGS];
|
||||
- char keyslot_s[16];
|
||||
- size_t i = 0;
|
||||
-
|
||||
- ADD_ARG (argv, i, "cryptsetup");
|
||||
- ADD_ARG (argv, i, "-q");
|
||||
- if (cipher) {
|
||||
- ADD_ARG (argv, i, "--cipher");
|
||||
- ADD_ARG (argv, i, cipher);
|
||||
- }
|
||||
- ADD_ARG (argv, i, "--key-slot");
|
||||
- snprintf (keyslot_s, sizeof keyslot_s, "%d", keyslot);
|
||||
- ADD_ARG (argv, i, keyslot_s);
|
||||
- ADD_ARG (argv, i, "luksFormat");
|
||||
- ADD_ARG (argv, i, device);
|
||||
- ADD_ARG (argv, i, tempfile);
|
||||
- ADD_ARG (argv, i, NULL);
|
||||
-
|
||||
- CLEANUP_FREE char *err = NULL;
|
||||
- int r = commandv (NULL, &err, (const char * const *) argv);
|
||||
- remove_temp (tempfile);
|
||||
-
|
||||
- if (r == -1) {
|
||||
- reply_with_error ("%s", err);
|
||||
- return -1;
|
||||
- }
|
||||
-
|
||||
- udev_settle ();
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-int
|
||||
-do_luks_format (const char *device, const char *key, int keyslot)
|
||||
-{
|
||||
- return luks_format (device, key, keyslot, NULL);
|
||||
-}
|
||||
-
|
||||
-int
|
||||
-do_luks_format_cipher (const char *device, const char *key, int keyslot,
|
||||
- const char *cipher)
|
||||
-{
|
||||
- return luks_format (device, key, keyslot, cipher);
|
||||
-}
|
||||
-
|
||||
-int
|
||||
-do_luks_add_key (const char *device, const char *key, const char *newkey,
|
||||
- int keyslot)
|
||||
-{
|
||||
- char *keyfile = write_key_to_temp (key);
|
||||
- if (!keyfile)
|
||||
- return -1;
|
||||
-
|
||||
- char *newkeyfile = write_key_to_temp (newkey);
|
||||
- if (!newkeyfile) {
|
||||
- remove_temp (keyfile);
|
||||
- return -1;
|
||||
- }
|
||||
-
|
||||
- const char *argv[MAX_ARGS];
|
||||
- char keyslot_s[16];
|
||||
- size_t i = 0;
|
||||
-
|
||||
- ADD_ARG (argv, i, "cryptsetup");
|
||||
- ADD_ARG (argv, i, "-q");
|
||||
- ADD_ARG (argv, i, "-d");
|
||||
- ADD_ARG (argv, i, keyfile);
|
||||
- ADD_ARG (argv, i, "--key-slot");
|
||||
- snprintf (keyslot_s, sizeof keyslot_s, "%d", keyslot);
|
||||
- ADD_ARG (argv, i, keyslot_s);
|
||||
- ADD_ARG (argv, i, "luksAddKey");
|
||||
- ADD_ARG (argv, i, device);
|
||||
- ADD_ARG (argv, i, newkeyfile);
|
||||
- ADD_ARG (argv, i, NULL);
|
||||
-
|
||||
- CLEANUP_FREE char *err = NULL;
|
||||
- int r = commandv (NULL, &err, (const char * const *) argv);
|
||||
- remove_temp (keyfile);
|
||||
- remove_temp (newkeyfile);
|
||||
-
|
||||
- if (r == -1) {
|
||||
- reply_with_error ("%s", err);
|
||||
- return -1;
|
||||
- }
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-int
|
||||
-do_luks_kill_slot (const char *device, const char *key, int keyslot)
|
||||
-{
|
||||
- char *tempfile = write_key_to_temp (key);
|
||||
- if (!tempfile)
|
||||
- return -1;
|
||||
-
|
||||
- const char *argv[MAX_ARGS];
|
||||
- char keyslot_s[16];
|
||||
- size_t i = 0;
|
||||
-
|
||||
- ADD_ARG (argv, i, "cryptsetup");
|
||||
- ADD_ARG (argv, i, "-q");
|
||||
- ADD_ARG (argv, i, "-d");
|
||||
- ADD_ARG (argv, i, tempfile);
|
||||
- ADD_ARG (argv, i, "luksKillSlot");
|
||||
- ADD_ARG (argv, i, device);
|
||||
- snprintf (keyslot_s, sizeof keyslot_s, "%d", keyslot);
|
||||
- ADD_ARG (argv, i, keyslot_s);
|
||||
- ADD_ARG (argv, i, NULL);
|
||||
-
|
||||
- CLEANUP_FREE char *err = NULL;
|
||||
- int r = commandv (NULL, &err, (const char * const *) argv);
|
||||
- remove_temp (tempfile);
|
||||
-
|
||||
- if (r == -1) {
|
||||
- reply_with_error ("%s", err);
|
||||
- return -1;
|
||||
- }
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
char *
|
||||
do_luks_uuid (const char *device)
|
||||
{
|
||||
diff --git a/daemon/luks.ml b/daemon/luks.ml
|
||||
index e7e6deefe..4e6531755 100644
|
||||
--- a/daemon/luks.ml
|
||||
+++ b/daemon/luks.ml
|
||||
@@ -23,6 +23,65 @@ open Std_utils
|
||||
|
||||
open Utils
|
||||
|
||||
+let write_key_to_tmp_file key =
|
||||
+ let filename, chan = Filename.open_temp_file "luks" ".out" in
|
||||
+ output_string chan key;
|
||||
+ close_out chan;
|
||||
+ filename
|
||||
+
|
||||
+let rec luks_format device key keyslot =
|
||||
+ _luks_format device key keyslot
|
||||
+
|
||||
+and luks_format_cipher device key keyslot cipher =
|
||||
+ _luks_format ~cipher device key keyslot
|
||||
+
|
||||
+and _luks_format ?cipher device key keyslot =
|
||||
+ let tmp = write_key_to_tmp_file key in
|
||||
+ Fun.protect ~finally:(fun () -> unlink tmp) (
|
||||
+ fun () ->
|
||||
+ let args = ref [] in
|
||||
+ List.push_back args "-q";
|
||||
+ Option.iter (fun s -> List.push_back_list args ["--cipher"; s]) cipher;
|
||||
+ List.push_back args "--key-slot";
|
||||
+ List.push_back args (string_of_int keyslot);
|
||||
+ List.push_back args "luksFormat";
|
||||
+ List.push_back args device;
|
||||
+ List.push_back args tmp;
|
||||
+ ignore (command "cryptsetup" !args)
|
||||
+ );
|
||||
+ udev_settle ()
|
||||
+
|
||||
+let luks_add_key device key newkey keyslot =
|
||||
+ let keyfile = write_key_to_tmp_file key
|
||||
+ and newkeyfile = write_key_to_tmp_file newkey in
|
||||
+ Fun.protect ~finally:(fun () -> unlink keyfile; unlink newkeyfile) (
|
||||
+ fun () ->
|
||||
+ let args = ref [] in
|
||||
+ List.push_back args "-q";
|
||||
+ List.push_back args "-d";
|
||||
+ List.push_back args keyfile;
|
||||
+ List.push_back args "--key-slot";
|
||||
+ List.push_back args (string_of_int keyslot);
|
||||
+ List.push_back args "luksAddKey";
|
||||
+ List.push_back args device;
|
||||
+ List.push_back args newkeyfile;
|
||||
+ ignore (command "cryptsetup" !args)
|
||||
+ )
|
||||
+
|
||||
+let luks_kill_slot device key keyslot =
|
||||
+ let tmp = write_key_to_tmp_file key in
|
||||
+ Fun.protect ~finally:(fun () -> unlink tmp) (
|
||||
+ fun () ->
|
||||
+ let args = ref [] in
|
||||
+ List.push_back args "-q";
|
||||
+ List.push_back args "-d";
|
||||
+ List.push_back args tmp;
|
||||
+ List.push_back args "luksKillSlot";
|
||||
+ List.push_back args device;
|
||||
+ List.push_back args (string_of_int keyslot);
|
||||
+ ignore (command "cryptsetup" !args)
|
||||
+ )
|
||||
+
|
||||
(* Deprecated APIs for backwards compatibility. *)
|
||||
let luks_open device key mapname =
|
||||
Cryptsetup.cryptsetup_open ~crypttype:"luks" device key mapname
|
||||
diff --git a/generator/actions_core.ml b/generator/actions_core.ml
|
||||
index 26d77c667..5876188e9 100644
|
||||
--- a/generator/actions_core.ml
|
||||
+++ b/generator/actions_core.ml
|
||||
@@ -5503,6 +5503,7 @@ group scan.|} };
|
||||
{ defaults with
|
||||
name = "luks_format"; added = (1, 5, 2);
|
||||
style = RErr, [String (Device, "device"); String (Key, "key"); Int "keyslot"], [];
|
||||
+ impl = OCaml "Luks.luks_format";
|
||||
optional = Some "luks";
|
||||
shortdesc = "format a block device as a LUKS encrypted device";
|
||||
longdesc = "\
|
||||
@@ -5514,6 +5515,7 @@ supports 8 key slots, numbered 0-7)." };
|
||||
{ defaults with
|
||||
name = "luks_format_cipher"; added = (1, 5, 2);
|
||||
style = RErr, [String (Device, "device"); String (Key, "key"); Int "keyslot"; String (PlainString, "cipher")], [];
|
||||
+ impl = OCaml "Luks.luks_format_cipher";
|
||||
optional = Some "luks";
|
||||
shortdesc = "format a block device as a LUKS encrypted device";
|
||||
longdesc = "\
|
||||
@@ -5523,6 +5525,7 @@ it also allows you to set the C<cipher> used." };
|
||||
{ defaults with
|
||||
name = "luks_add_key"; added = (1, 5, 2);
|
||||
style = RErr, [String (Device, "device"); String (Key, "key"); String (Key, "newkey"); Int "keyslot"], [];
|
||||
+ impl = OCaml "Luks.luks_add_key";
|
||||
optional = Some "luks";
|
||||
shortdesc = "add a key on a LUKS encrypted device";
|
||||
longdesc = {|This command adds a new key on LUKS device C<device>.
|
||||
@@ -5537,6 +5540,7 @@ first to remove that key.|} };
|
||||
{ defaults with
|
||||
name = "luks_kill_slot"; added = (1, 5, 2);
|
||||
style = RErr, [String (Device, "device"); String (Key, "key"); Int "keyslot"], [];
|
||||
+ impl = OCaml "Luks.luks_kill_slot";
|
||||
optional = Some "luks";
|
||||
shortdesc = "remove a key from a LUKS encrypted device";
|
||||
longdesc = "\
|
||||
--
|
||||
2.47.3
|
||||
|
||||
@ -0,0 +1,50 @@
|
||||
From ac9b4454413097667158a54cbd2d4d646d25e600 Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Tue, 28 Apr 2026 14:22:51 +0100
|
||||
Subject: [PATCH] daemon/cryptsetup.ml: Reformat this code for consistency
|
||||
|
||||
No functional change, simply reformat the code for consistency with
|
||||
the Luks module.
|
||||
|
||||
(cherry picked from commit e3a79166d9a3ce07e3434e6d2504495248160061)
|
||||
---
|
||||
daemon/cryptsetup.ml | 23 ++++++++++++++---------
|
||||
1 file changed, 14 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/daemon/cryptsetup.ml b/daemon/cryptsetup.ml
|
||||
index 002e0993a..47b17856c 100644
|
||||
--- a/daemon/cryptsetup.ml
|
||||
+++ b/daemon/cryptsetup.ml
|
||||
@@ -49,15 +49,20 @@ let cryptsetup_open ?(readonly = false) ?crypttype ?cipher device key mapname =
|
||||
output_string chan key;
|
||||
close_out chan;
|
||||
|
||||
- let args = ref [] in
|
||||
- List.push_back_list args ["-d"; keyfile];
|
||||
- if readonly then List.push_back args "--readonly";
|
||||
- List.push_back_list args ["open"; device; mapname; "--type"; crypttype];
|
||||
- Option.iter (fun s -> List.push_back_list args ["--cipher"; s]) cipher;
|
||||
-
|
||||
- (* Make sure we always remove the temporary file. *)
|
||||
- Fun.protect (fun () -> ignore (command "cryptsetup" !args))
|
||||
- ~finally:(fun () -> unlink keyfile);
|
||||
+ Fun.protect ~finally:(fun () -> unlink keyfile) (
|
||||
+ fun () ->
|
||||
+ let args = ref [] in
|
||||
+ List.push_back args "-d";
|
||||
+ List.push_back args keyfile;
|
||||
+ if readonly then List.push_back args "--readonly";
|
||||
+ List.push_back args "open";
|
||||
+ List.push_back args device;
|
||||
+ List.push_back args mapname;
|
||||
+ List.push_back args "--type";
|
||||
+ List.push_back args crypttype;
|
||||
+ Option.iter (fun s -> List.push_back_list args ["--cipher"; s]) cipher;
|
||||
+ ignore (command "cryptsetup" !args)
|
||||
+ );
|
||||
|
||||
udev_settle ()
|
||||
|
||||
--
|
||||
2.47.3
|
||||
|
||||
81
0019-daemon-Use-common-Utils.write_key_to_tmp_file.patch
Normal file
81
0019-daemon-Use-common-Utils.write_key_to_tmp_file.patch
Normal file
@ -0,0 +1,81 @@
|
||||
From fabe35d7b170eccac917de451fb955be4af0808d Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Tue, 28 Apr 2026 10:09:09 +0100
|
||||
Subject: [PATCH] daemon: Use common Utils.write_key_to_tmp_file
|
||||
|
||||
Move this function to Utils module, and ensure it is called from all
|
||||
places where we use Key parameters.
|
||||
|
||||
(cherry picked from commit 8a36eb4afa10186bf9c62e121ca4db6ef0ec5a8a)
|
||||
---
|
||||
daemon/cryptsetup.ml | 4 +---
|
||||
daemon/luks.ml | 6 ------
|
||||
daemon/utils.ml | 6 ++++++
|
||||
daemon/utils.mli | 6 ++++++
|
||||
4 files changed, 13 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/daemon/cryptsetup.ml b/daemon/cryptsetup.ml
|
||||
index 47b17856c..29f3acc4d 100644
|
||||
--- a/daemon/cryptsetup.ml
|
||||
+++ b/daemon/cryptsetup.ml
|
||||
@@ -45,9 +45,7 @@ let cryptsetup_open ?(readonly = false) ?crypttype ?cipher device key mapname =
|
||||
failwithf "%s: unknown encrypted device type" t in
|
||||
|
||||
(* Write the key to a temporary file. *)
|
||||
- let keyfile, chan = Filename.open_temp_file "crypt" ".key" in
|
||||
- output_string chan key;
|
||||
- close_out chan;
|
||||
+ let keyfile = write_key_to_tmp_file key in
|
||||
|
||||
Fun.protect ~finally:(fun () -> unlink keyfile) (
|
||||
fun () ->
|
||||
diff --git a/daemon/luks.ml b/daemon/luks.ml
|
||||
index 4e6531755..371c656ef 100644
|
||||
--- a/daemon/luks.ml
|
||||
+++ b/daemon/luks.ml
|
||||
@@ -23,12 +23,6 @@ open Std_utils
|
||||
|
||||
open Utils
|
||||
|
||||
-let write_key_to_tmp_file key =
|
||||
- let filename, chan = Filename.open_temp_file "luks" ".out" in
|
||||
- output_string chan key;
|
||||
- close_out chan;
|
||||
- filename
|
||||
-
|
||||
let rec luks_format device key keyslot =
|
||||
_luks_format device key keyslot
|
||||
|
||||
diff --git a/daemon/utils.ml b/daemon/utils.ml
|
||||
index 3aa1d7ed2..2a03c7190 100644
|
||||
--- a/daemon/utils.ml
|
||||
+++ b/daemon/utils.ml
|
||||
@@ -295,3 +295,9 @@ let parse_key_value_strings ?unquote lines =
|
||||
let hex_of_string s =
|
||||
let bytes = String.map_chars (fun c -> sprintf "%02x" (Char.code c)) s in
|
||||
String.concat " " bytes
|
||||
+
|
||||
+let write_key_to_tmp_file key =
|
||||
+ let filename, chan = Filename.open_temp_file "key" ".out" in
|
||||
+ output_string chan key;
|
||||
+ close_out chan;
|
||||
+ filename
|
||||
diff --git a/daemon/utils.mli b/daemon/utils.mli
|
||||
index e14735038..730e4af38 100644
|
||||
--- a/daemon/utils.mli
|
||||
+++ b/daemon/utils.mli
|
||||
@@ -125,5 +125,11 @@ val hex_of_string : string -> string
|
||||
(** Return a string as a list of hex bytes.
|
||||
Use this for debugging msgs only. *)
|
||||
|
||||
+val write_key_to_tmp_file : string -> string
|
||||
+(** Write a Key parameter to a temporary file. Returns the name of
|
||||
+ the temporary file.
|
||||
+
|
||||
+ The caller must call {!Unix.unlink} on the file. *)
|
||||
+
|
||||
(**/**)
|
||||
val get_verbose_flag : unit -> bool
|
||||
--
|
||||
2.47.3
|
||||
|
||||
126
0020-daemon-Allow-base64-text-as-a-prefix-on-Key-paramete.patch
Normal file
126
0020-daemon-Allow-base64-text-as-a-prefix-on-Key-paramete.patch
Normal file
@ -0,0 +1,126 @@
|
||||
From 20b5a3f5d4a4ebd51354b0ab92141dd4f80e0ef9 Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Tue, 28 Apr 2026 09:33:06 +0100
|
||||
Subject: [PATCH] daemon: Allow base64:/text: as a prefix on Key parameters
|
||||
|
||||
To support 8 bit keys, allow Key parameters to be passed with the
|
||||
prefix "base64:..." where the key that follows is base64-encoded.
|
||||
|
||||
"text:..." can be used to prefix plaintext passphrases. Or, for
|
||||
backwards compat, they can be passed without prefix, but this is now
|
||||
slightly ambiguous.
|
||||
|
||||
Base64 keys are passed through all the APIs as opaque strings, and
|
||||
then decoded in the daemon just before calling the cryptsetup command.
|
||||
|
||||
(cherry picked from commit 9324859875bd8845e63edd918885ef70bb47211b)
|
||||
---
|
||||
daemon/utils.ml | 23 ++++++++++++++++++++++-
|
||||
daemon/utils.mli | 3 +++
|
||||
generator/types.mli | 6 ++++++
|
||||
lib/guestfs.pod | 23 +++++++++++++++++++++++
|
||||
4 files changed, 54 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/daemon/utils.ml b/daemon/utils.ml
|
||||
index 2a03c7190..2ee303a41 100644
|
||||
--- a/daemon/utils.ml
|
||||
+++ b/daemon/utils.ml
|
||||
@@ -296,8 +296,29 @@ let hex_of_string s =
|
||||
let bytes = String.map_chars (fun c -> sprintf "%02x" (Char.code c)) s in
|
||||
String.concat " " bytes
|
||||
|
||||
-let write_key_to_tmp_file key =
|
||||
+let rec write_key_to_tmp_file key =
|
||||
+ (* If the key starts with a prefix then it may need decoding. *)
|
||||
+ let len = String.length key in
|
||||
+ if String.starts_with "base64:" key then
|
||||
+ _decode_base64_key (String.sub key 7 (len-7))
|
||||
+ else if String.starts_with "text:" key then
|
||||
+ _write_key (String.sub key 5 (len-5))
|
||||
+ else
|
||||
+ _write_key key
|
||||
+
|
||||
+and _write_key key =
|
||||
let filename, chan = Filename.open_temp_file "key" ".out" in
|
||||
output_string chan key;
|
||||
close_out chan;
|
||||
filename
|
||||
+
|
||||
+and _decode_base64_key b64 =
|
||||
+ let b64file, chan = Filename.open_temp_file "key" ".b64" in
|
||||
+ output_string chan b64;
|
||||
+ close_out chan;
|
||||
+ let keyfile = Filename.temp_file "key" ".out" in
|
||||
+ let cmd = sprintf "base64 -d < %s > %s" (quote b64file) (quote keyfile) in
|
||||
+ if Sys.command cmd <> 0 then
|
||||
+ failwithf "could not decode base64-encoded key";
|
||||
+ unlink b64file;
|
||||
+ keyfile
|
||||
diff --git a/daemon/utils.mli b/daemon/utils.mli
|
||||
index 730e4af38..57f33dea8 100644
|
||||
--- a/daemon/utils.mli
|
||||
+++ b/daemon/utils.mli
|
||||
@@ -129,6 +129,9 @@ val write_key_to_tmp_file : string -> string
|
||||
(** Write a Key parameter to a temporary file. Returns the name of
|
||||
the temporary file.
|
||||
|
||||
+ This handles the special "base64:..." or "text:..." prefixes
|
||||
+ introduced in libguestfs 1.60.
|
||||
+
|
||||
The caller must call {!Unix.unlink} on the file. *)
|
||||
|
||||
(**/**)
|
||||
diff --git a/generator/types.mli b/generator/types.mli
|
||||
index 01f00044e..9416974db 100644
|
||||
--- a/generator/types.mli
|
||||
+++ b/generator/types.mli
|
||||
@@ -190,6 +190,12 @@ and stringt =
|
||||
Currently the only difference from 'PlainString' is the way
|
||||
that guestfish requests these parameters from the user.
|
||||
|
||||
+ In libguestfs >= 1.60, these strings can be prefixed with
|
||||
+ 'base64:...' to pass in a base64 encoded string (supporting
|
||||
+ arbitrary 8 bit binary). 'text:...' can be used for plain
|
||||
+ passphrases, or (for backwards compat) the passphrase can be
|
||||
+ unprefixed.
|
||||
+
|
||||
Eventually we should treat this as sensitive and mlock it
|
||||
into physical RAM. This is highly complex because of all
|
||||
the places that XDR-encoded strings can end up. *)
|
||||
diff --git a/lib/guestfs.pod b/lib/guestfs.pod
|
||||
index 07737c839..fe74f5542 100644
|
||||
--- a/lib/guestfs.pod
|
||||
+++ b/lib/guestfs.pod
|
||||
@@ -1218,6 +1218,29 @@ representation. Also consider how it might work in guestfish.
|
||||
Certain libguestfs calls take a parameter that contains sensitive key
|
||||
material, passed in as a C string.
|
||||
|
||||
+In libguestfs E<ge> 1.60 you can pass in 8 bit binary key data
|
||||
+(allowing C<'\n'> or C<'\0'>) by prefixing the string with:
|
||||
+
|
||||
+=over 4
|
||||
+
|
||||
+=item C<base64:...>
|
||||
+
|
||||
+Pass in base64-encoded key data. This supports 8 bit binary key
|
||||
+data.
|
||||
+
|
||||
+=item C<text:...>
|
||||
+
|
||||
+Pass in regular text passphrase. This does not support 8 bit binary
|
||||
+key data.
|
||||
+
|
||||
+=item Unprefixed
|
||||
+
|
||||
+For backwards compatibility with libguestfs E<le> 1.58, a text
|
||||
+passphrase can be passed in unprefixed. However this does not support
|
||||
+8 bit binary key data.
|
||||
+
|
||||
+=back
|
||||
+
|
||||
In the future we would hope to change the libguestfs implementation so
|
||||
that keys are L<mlock(2)>-ed into physical RAM, and thus can never end
|
||||
up in swap. However this is I<not> done at the moment, because of the
|
||||
--
|
||||
2.47.3
|
||||
|
||||
174
0021-Update-common-submodule.patch
Normal file
174
0021-Update-common-submodule.patch
Normal file
@ -0,0 +1,174 @@
|
||||
From 7508991c1356155c8fa9dd65d0d5c2c90eea75aa Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Tue, 28 Apr 2026 12:34:08 +0100
|
||||
Subject: [PATCH] Update common submodule
|
||||
|
||||
Richard W.M. Jones (3):
|
||||
options/keys.c: When reading key from user, prefix with "text:"
|
||||
options/keys.c: When using --key <dev>:key:<string>, prefix with "text:"
|
||||
options/keys.c: When reading the key from a file, encode it with base64
|
||||
|
||||
Fixes: https://redhat.atlassian.net/browse/RHEL-170864
|
||||
Fixes: https://redhat.atlassian.net/browse/RHEL-171895
|
||||
Fixes: https://redhat.atlassian.net/browse/RHEL-171896
|
||||
(cherry picked from commit 6a181ecc7abe8cd67ce0ac15a1a75fd58837091e)
|
||||
---
|
||||
common | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
Submodule common 800510306..cf2e12078:
|
||||
diff --git a/common/options/keys.c b/common/options/keys.c
|
||||
index b8f19ce..432e26d 100644
|
||||
--- a/common/options/keys.c
|
||||
+++ b/common/options/keys.c
|
||||
@@ -37,17 +37,23 @@
|
||||
* Read a passphrase ('Key') from F</dev/tty> with echo off.
|
||||
*
|
||||
* The caller (F<fish/cmds.c>) will call free on the string
|
||||
- * afterwards. Based on the code in cryptsetup file F<lib/utils.c>.
|
||||
+ * afterwards.
|
||||
+ *
|
||||
+ * The entered string is prefixed with "text:..." to avoid ambiguity
|
||||
+ * (with libguestfs >= 1.60). Base64 encoding cannot be used here.
|
||||
+ *
|
||||
+ * Based on the code in cryptsetup file F<lib/utils.c>.
|
||||
*/
|
||||
char *
|
||||
read_key (const char *param)
|
||||
{
|
||||
FILE *infp, *outfp;
|
||||
struct termios orig, temp;
|
||||
+ CLEANUP_FREE char *key = NULL;
|
||||
+ size_t keysize = 0;
|
||||
char *ret = NULL;
|
||||
int tty;
|
||||
int tcset = 0;
|
||||
- size_t allocsize = 0;
|
||||
ssize_t len;
|
||||
|
||||
/* Read and write to /dev/tty if available. */
|
||||
@@ -75,17 +81,21 @@ read_key (const char *param)
|
||||
}
|
||||
}
|
||||
|
||||
- len = getline (&ret, &allocsize, infp);
|
||||
+ len = getline (&key, &keysize, infp);
|
||||
if (len == -1) {
|
||||
perror ("getline");
|
||||
- free (ret);
|
||||
- ret = NULL;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Remove the terminating \n if there is one. */
|
||||
- if (len > 0 && ret[len-1] == '\n')
|
||||
- ret[len-1] = '\0';
|
||||
+ if (len > 0 && key[len-1] == '\n')
|
||||
+ key[len-1] = '\0';
|
||||
+
|
||||
+ /* Prefix with "text:". */
|
||||
+ if (asprintf (&ret, "text:%s", key) == -1) {
|
||||
+ perror ("asprintf");
|
||||
+ goto error;
|
||||
+ }
|
||||
|
||||
error:
|
||||
/* Restore echo, close file descriptor. */
|
||||
@@ -100,27 +110,60 @@ read_key (const char *param)
|
||||
return ret;
|
||||
}
|
||||
|
||||
+/* Read a key from a file and base64 encode it, returning "base64:..." */
|
||||
static char *
|
||||
-read_first_line_from_file (const char *filename)
|
||||
+read_key_and_base64_encode (const char *filename)
|
||||
{
|
||||
- CLEANUP_FCLOSE FILE *fp = NULL;
|
||||
- char *ret = NULL;
|
||||
- size_t allocsize = 0;
|
||||
- ssize_t len;
|
||||
+ CLEANUP_FREE char *inp = NULL;
|
||||
+ char *out;
|
||||
+ size_t inplen, outlen, i, j;
|
||||
|
||||
- fp = fopen (filename, "r");
|
||||
- if (!fp)
|
||||
- error (EXIT_FAILURE, errno, "fopen: %s", filename);
|
||||
+ if (read_whole_file (filename, &inp, &inplen) == -1)
|
||||
+ error (EXIT_FAILURE, 0, "read_key_and_base64_encode: read_whole_file: %s",
|
||||
+ filename);
|
||||
|
||||
- len = getline (&ret, &allocsize, fp);
|
||||
- if (len == -1)
|
||||
- error (EXIT_FAILURE, errno, "getline: %s", filename);
|
||||
+ /* From https://stackoverflow.com/a/6782480 */
|
||||
+ static char encoding_table[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
|
||||
+ 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
|
||||
+ 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
|
||||
+ 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
|
||||
+ 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
|
||||
+ 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
|
||||
+ 'w', 'x', 'y', 'z', '0', '1', '2', '3',
|
||||
+ '4', '5', '6', '7', '8', '9', '+', '/'};
|
||||
+ static int mod_table[] = {0, 2, 1};
|
||||
|
||||
- /* Remove the terminating \n if there is one. */
|
||||
- if (len > 0 && ret[len-1] == '\n')
|
||||
- ret[len-1] = '\0';
|
||||
+ outlen = 4 * ((inplen + 2) / 3);
|
||||
+ out = malloc (outlen + 7 + 1);
|
||||
+ if (!out)
|
||||
+ error (EXIT_FAILURE, errno, "read_key_and_base64_encode: %s: malloc",
|
||||
+ filename);
|
||||
|
||||
- return ret;
|
||||
+ /* Add prefix and NUL-termination, then adjust 'out' to make the
|
||||
+ * rest of the code simpler.
|
||||
+ */
|
||||
+ memcpy (out, "base64:", 7);
|
||||
+ out[7 + outlen] = '\0';
|
||||
+ out += 7;
|
||||
+
|
||||
+ for (i = 0, j = 0; i < inplen;) {
|
||||
+ uint32_t octet_a = i < inplen ? (unsigned char) inp[i++] : 0;
|
||||
+ uint32_t octet_b = i < inplen ? (unsigned char) inp[i++] : 0;
|
||||
+ uint32_t octet_c = i < inplen ? (unsigned char) inp[i++] : 0;
|
||||
+
|
||||
+ uint32_t triple = (octet_a << 0x10) + (octet_b << 0x08) + octet_c;
|
||||
+
|
||||
+ assert (j <= outlen-4);
|
||||
+ out[j++] = encoding_table[(triple >> 3 * 6) & 0x3F];
|
||||
+ out[j++] = encoding_table[(triple >> 2 * 6) & 0x3F];
|
||||
+ out[j++] = encoding_table[(triple >> 1 * 6) & 0x3F];
|
||||
+ out[j++] = encoding_table[(triple >> 0 * 6) & 0x3F];
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < mod_table[inplen % 3]; i++)
|
||||
+ out[outlen - 1 - i] = '=';
|
||||
+
|
||||
+ return out - 7 /* see above */;
|
||||
}
|
||||
|
||||
/* Return the key(s) matching this particular device from the
|
||||
@@ -164,15 +207,14 @@ get_keys (struct key_store *ks, const char *device, const char *uuid,
|
||||
|
||||
switch (key->type) {
|
||||
case key_string:
|
||||
- s = strdup (key->string.s);
|
||||
- if (!s)
|
||||
- error (EXIT_FAILURE, errno, "strdup");
|
||||
+ if (asprintf (&s, "text:%s", key->string.s) == -1)
|
||||
+ error (EXIT_FAILURE, errno, "asprintf");
|
||||
match->clevis = false;
|
||||
match->passphrase = s;
|
||||
++match;
|
||||
break;
|
||||
case key_file:
|
||||
- s = read_first_line_from_file (key->file.name);
|
||||
+ s = read_key_and_base64_encode (key->file.name);
|
||||
match->clevis = false;
|
||||
match->passphrase = s;
|
||||
++match;
|
||||
--
|
||||
2.47.3
|
||||
|
||||
114
0022-tests-luks-Test-handling-of-a-binary-key-dev-file-fi.patch
Normal file
114
0022-tests-luks-Test-handling-of-a-binary-key-dev-file-fi.patch
Normal file
@ -0,0 +1,114 @@
|
||||
From b105fe3e7c470ca8b2f51dce10666b6d320e5ba0 Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Tue, 28 Apr 2026 12:47:12 +0100
|
||||
Subject: [PATCH] tests/luks: Test handling of a binary --key <dev>:file:<file>
|
||||
|
||||
(cherry picked from commit 2ddbff5c2939fe987388428c8d8aed2575bdec33)
|
||||
---
|
||||
test-data/phony-guests/make-fedora-img.pl | 7 +++++--
|
||||
tests/Makefile.am | 3 ++-
|
||||
tests/luks/fedora-lv3.key | Bin 0 -> 10 bytes
|
||||
tests/luks/test-key-option-inspect-luks-on-lvm.sh | 10 +++++-----
|
||||
4 files changed, 12 insertions(+), 8 deletions(-)
|
||||
create mode 100644 tests/luks/fedora-lv3.key
|
||||
|
||||
diff --git a/test-data/phony-guests/make-fedora-img.pl b/test-data/phony-guests/make-fedora-img.pl
|
||||
index e4ea07841..6025bc838 100755
|
||||
--- a/test-data/phony-guests/make-fedora-img.pl
|
||||
+++ b/test-data/phony-guests/make-fedora-img.pl
|
||||
@@ -234,7 +234,10 @@ EOF
|
||||
$g->luks_format ('/dev/Volume-Group/Root', 'FEDORA-Root', 0);
|
||||
$g->luks_format ('/dev/Volume-Group/Logical-Volume-1', 'FEDORA-LV1', 0);
|
||||
$g->luks_format ('/dev/Volume-Group/Logical-Volume-2', 'FEDORA-LV2', 0);
|
||||
- $g->luks_format ('/dev/Volume-Group/Logical-Volume-3', 'FEDORA-LV3', 0);
|
||||
+ # This is a little different, because we use a binary passphrase.
|
||||
+ # The base64 string is "FEDORA\0LV3" (containing ASCII NUL).
|
||||
+ my $base64_key3 = 'base64:RkVET1JBAExWMw==';
|
||||
+ $g->luks_format ('/dev/Volume-Group/Logical-Volume-3', $base64_key3, 0);
|
||||
|
||||
# Open the LUKS devices. This creates nodes like /dev/mapper/*-luks.
|
||||
$g->cryptsetup_open ('/dev/Volume-Group/Root',
|
||||
@@ -244,7 +247,7 @@ EOF
|
||||
$g->cryptsetup_open ('/dev/Volume-Group/Logical-Volume-2',
|
||||
'FEDORA-LV2', 'LV2-luks');
|
||||
$g->cryptsetup_open ('/dev/Volume-Group/Logical-Volume-3',
|
||||
- 'FEDORA-LV3', 'LV3-luks');
|
||||
+ $base64_key3, 'LV3-luks');
|
||||
|
||||
# Phony root filesystem.
|
||||
$g->mkfs ('ext2', '/dev/mapper/Root-luks', blocksize => 4096, label => 'ROOT');
|
||||
diff --git a/tests/Makefile.am b/tests/Makefile.am
|
||||
index 91e917b50..f4d92eaa7 100644
|
||||
--- a/tests/Makefile.am
|
||||
+++ b/tests/Makefile.am
|
||||
@@ -441,7 +441,8 @@ EXTRA_DIST += \
|
||||
luks/test-luks-list.sh \
|
||||
luks/test-key-option.sh \
|
||||
luks/test-key-option-inspect-luks-on-lvm.sh \
|
||||
- luks/test-key-option-inspect-lvm-on-luks.sh
|
||||
+ luks/test-key-option-inspect-lvm-on-luks.sh \
|
||||
+ luks/fedora-lv3.key
|
||||
|
||||
TESTS += \
|
||||
lvm/test-lvm-filtering.sh \
|
||||
diff --git a/tests/luks/fedora-lv3.key b/tests/luks/fedora-lv3.key
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..89c372fd5df2216b6d2ca9ccb7879dc8ade8ec5c
|
||||
GIT binary patch
|
||||
literal 10
|
||||
RcmZ>Bb@2~!Wbg?y1^^Cl0*3$q
|
||||
|
||||
literal 0
|
||||
HcmV?d00001
|
||||
|
||||
diff --git a/tests/luks/test-key-option-inspect-luks-on-lvm.sh b/tests/luks/test-key-option-inspect-luks-on-lvm.sh
|
||||
index 6109c4eec..2ee83332c 100755
|
||||
--- a/tests/luks/test-key-option-inspect-luks-on-lvm.sh
|
||||
+++ b/tests/luks/test-key-option-inspect-luks-on-lvm.sh
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash -
|
||||
# libguestfs
|
||||
-# Copyright (C) 2019-2025 Red Hat Inc.
|
||||
+# Copyright (C) 2019-2026 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
|
||||
@@ -34,7 +34,7 @@ guestfish=(guestfish --listen --ro --inspector
|
||||
keys_by_lvname=(--key /dev/Volume-Group/Root:key:FEDORA-Root
|
||||
--key /dev/Volume-Group/Logical-Volume-1:key:FEDORA-LV1
|
||||
--key /dev/Volume-Group/Logical-Volume-2:key:FEDORA-LV2
|
||||
- --key /dev/Volume-Group/Logical-Volume-3:key:FEDORA-LV3)
|
||||
+ --key /dev/Volume-Group/Logical-Volume-3:file:luks/fedora-lv3.key)
|
||||
|
||||
# The variable assignment below will fail, and abort the script, if guestfish
|
||||
# refuses to start up.
|
||||
@@ -96,7 +96,7 @@ GUESTFISH_PID=
|
||||
keys_by_uuid=(--key "$uuid_root":key:FEDORA-Root
|
||||
--key "$uuid_lv1":key:FEDORA-LV1
|
||||
--key "$uuid_lv2":key:FEDORA-LV2
|
||||
- --key "$uuid_lv3":key:FEDORA-LV3)
|
||||
+ --key "$uuid_lv3":file:luks/fedora-lv3.key)
|
||||
fish_ref=$("${guestfish[@]}" "${keys_by_uuid[@]}")
|
||||
eval "$fish_ref"
|
||||
|
||||
@@ -113,7 +113,7 @@ keys_by_mapper_lvname=(
|
||||
--key /dev/mapper/Volume--Group-Root:key:FEDORA-Root
|
||||
--key /dev/mapper/Volume--Group-Logical--Volume--1:key:FEDORA-LV1
|
||||
--key /dev/mapper/Volume--Group-Logical--Volume--2:key:FEDORA-LV2
|
||||
- --key /dev/mapper/Volume--Group-Logical--Volume--3:key:FEDORA-LV3
|
||||
+ --key /dev/mapper/Volume--Group-Logical--Volume--3:file:luks/fedora-lv3.key
|
||||
)
|
||||
fish_ref=$("${guestfish[@]}" "${keys_by_mapper_lvname[@]}")
|
||||
eval "$fish_ref"
|
||||
@@ -130,7 +130,7 @@ keys_by_mapper_lvname=(
|
||||
--key all:key:FEDORA-Root
|
||||
--key all:key:FEDORA-LV1
|
||||
--key all:key:FEDORA-LV2
|
||||
- --key all:key:FEDORA-LV3
|
||||
+ --key all:file:luks/fedora-lv3.key
|
||||
)
|
||||
fish_ref=$("${guestfish[@]}" "${keys_by_mapper_lvname[@]}")
|
||||
eval "$fish_ref"
|
||||
--
|
||||
2.47.3
|
||||
|
||||
@ -0,0 +1,31 @@
|
||||
From ae3a26d4a26fd446054ba2b53082b0dd1406d29c Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Tue, 5 May 2026 12:03:11 +0100
|
||||
Subject: [PATCH] docs/guestfs-recipes.pod: Remove reference to deleted
|
||||
documentation
|
||||
|
||||
guestfs-tools commit 82edee0cdc ("sysprep: Remove documentation about
|
||||
copying and cloning") removed this documentation from the
|
||||
virt-sysprep(1) man page, so remove the reference here.
|
||||
|
||||
(cherry picked from commit c08fbe10db0b54916b6a52b2340106a0193a394d)
|
||||
---
|
||||
docs/guestfs-recipes.pod | 2 --
|
||||
1 file changed, 2 deletions(-)
|
||||
|
||||
diff --git a/docs/guestfs-recipes.pod b/docs/guestfs-recipes.pod
|
||||
index 305bd92f6..4a54696c6 100644
|
||||
--- a/docs/guestfs-recipes.pod
|
||||
+++ b/docs/guestfs-recipes.pod
|
||||
@@ -68,8 +68,6 @@ Use a combination of tools like L<cp(1)>, L<dd(1)>, and
|
||||
virt tools like L<virt-sysprep(1)>, L<virt-sparsify(1)>
|
||||
and L<virt-resize(1)>.
|
||||
|
||||
-For more details, see: L<virt-sysprep(1)/COPYING AND CLONING>.
|
||||
-
|
||||
=head1 Convert a CD-ROM / DVD / ISO to a tarball
|
||||
|
||||
This converts input F<cd.iso> to output F<cd.tar.gz>:
|
||||
--
|
||||
2.47.3
|
||||
|
||||
@ -0,0 +1,55 @@
|
||||
From 596d6c6dc194e914064b53fa68d6834d2e8e78a1 Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Tue, 5 May 2026 12:22:18 +0100
|
||||
Subject: [PATCH] generator: Refer to new virt-customize(1)/FIRSTBOOT section
|
||||
|
||||
Documentation about firstboot scripts was consolidated and reworked
|
||||
into a new section of the virt-customize(1) manual. Change the
|
||||
existing references.
|
||||
|
||||
Update common submodule:
|
||||
|
||||
Richard W.M. Jones (1):
|
||||
mlcustomize: Update generated files
|
||||
|
||||
Srihari Parimi (1):
|
||||
mlcustomize: firstboot.bat must not reboot VM on error code 250
|
||||
|
||||
(cherry picked from commit 1f00e533610dc9291337c81669997ebebae23719)
|
||||
---
|
||||
common | 2 +-
|
||||
generator/customize.ml | 10 ++--------
|
||||
2 files changed, 3 insertions(+), 9 deletions(-)
|
||||
|
||||
Submodule common cf2e12078..dd34aebb4:
|
||||
diff --git a/generator/customize.ml b/generator/customize.ml
|
||||
index 19511dcdc..8df20ac1d 100644
|
||||
--- a/generator/customize.ml
|
||||
+++ b/generator/customize.ml
|
||||
@@ -224,10 +224,7 @@ conveniently wraps the command up in a single line script for you.
|
||||
You can have multiple I<--firstboot> options. They run in the same
|
||||
order that they appear on the command line.
|
||||
|
||||
-Please take a look at L<virt-builder(1)/FIRST BOOT SCRIPTS> for more
|
||||
-information and caveats about the first boot scripts.
|
||||
-
|
||||
-See also I<--run>.|};
|
||||
+See also: L<virt-customize(1)/FIRSTBOOT>, I<--run>.|};
|
||||
};
|
||||
|
||||
{ op_name = "firstboot-command";
|
||||
@@ -241,10 +238,7 @@ boots up (as root, late in the boot process).
|
||||
You can have multiple I<--firstboot> options. They run in the same
|
||||
order that they appear on the command line.
|
||||
|
||||
-Please take a look at L<virt-builder(1)/FIRST BOOT SCRIPTS> for more
|
||||
-information and caveats about the first boot scripts.
|
||||
-
|
||||
-See also I<--run>.|};
|
||||
+See also: L<virt-customize(1)/FIRSTBOOT>, I<--run>.|};
|
||||
};
|
||||
|
||||
{ op_name = "firstboot-install";
|
||||
--
|
||||
2.47.3
|
||||
|
||||
@ -35,7 +35,7 @@ Summary: Access and modify virtual machine disk images
|
||||
Name: libguestfs
|
||||
Epoch: 1
|
||||
Version: 1.58.1
|
||||
Release: 2%{?dist}.alma.1
|
||||
Release: 6%{?dist}.alma.1
|
||||
License: LGPL-2.1-or-later
|
||||
|
||||
# Build only for architectures that have a kernel
|
||||
@ -86,6 +86,22 @@ Patch0008: 0008-New-API-xfs_info2.patch
|
||||
Patch0009: 0009-daemon-Reimplement-xfs_info-using-xfs_info2.patch
|
||||
Patch0010: 0010-generator-Deprecate-xfs_info-replaced-by-xfs_info2.patch
|
||||
Patch0011: 0011-tests-disks-debug-qemu.sh-Fix-test-for-update-QMP-te.patch
|
||||
Patch0012: 0012-daemon-listfs.ml-Refactor-is_partition_can_hold_file.patch
|
||||
Patch0013: 0013-daemon-listfs.ml-Ignore-CHS-geometry-error-from-part.patch
|
||||
Patch0014: 0014-daemon-Move-read_whole_file-to-common-utils.patch
|
||||
Patch0015: 0015-generator-Adjust-comment-for-String-Key.patch
|
||||
Patch0016: 0016-daemon-Move-some-deprecated-functions-to-new-Luks-mo.patch
|
||||
Patch0017: 0017-daemon-Rewrite-some-luks_-APIs-in-OCaml.patch
|
||||
Patch0018: 0018-daemon-cryptsetup.ml-Reformat-this-code-for-consiste.patch
|
||||
Patch0019: 0019-daemon-Use-common-Utils.write_key_to_tmp_file.patch
|
||||
Patch0020: 0020-daemon-Allow-base64-text-as-a-prefix-on-Key-paramete.patch
|
||||
Patch0021: 0021-Update-common-submodule.patch
|
||||
Patch0022: 0022-tests-luks-Test-handling-of-a-binary-key-dev-file-fi.patch
|
||||
Patch0023: 0023-docs-guestfs-recipes.pod-Remove-reference-to-deleted.patch
|
||||
Patch0024: 0024-generator-Refer-to-new-virt-customize-1-FIRSTBOOT-se.patch
|
||||
|
||||
# For applying patches:
|
||||
BuildRequires: git
|
||||
|
||||
BuildRequires: autoconf, automake, libtool, gettext-devel
|
||||
|
||||
@ -676,8 +692,7 @@ for %{name}.
|
||||
%if 0%{verify_tarball_signature}
|
||||
%{gpgverify} --keyring='%{SOURCE7}' --signature='%{SOURCE1}' --data='%{SOURCE0}'
|
||||
%endif
|
||||
%setup -q
|
||||
%autopatch -p1
|
||||
%autosetup -S git -p1
|
||||
|
||||
autoreconf -fiv
|
||||
|
||||
@ -1097,6 +1112,14 @@ rm ocaml/html/.gitignore
|
||||
|
||||
|
||||
%changelog
|
||||
* Mon Jun 08 2026 Andrew Lukoshko <alukoshko@almalinux.org> - 1:1.58.1-6.alma.1
|
||||
- Update to libguestfs-1.58.1-6
|
||||
- daemon/listfs.ml: ignore CHS geometry error from parted (Veritas/Sun)
|
||||
- daemon: allow base64:/text: prefixes on Key parameters (binary LUKS keys)
|
||||
- daemon: move read_whole_file to common/utils and rewrite luks_* APIs in OCaml
|
||||
- Update common submodule
|
||||
- Apply patches with %%autosetup -S git (a patch now adds binary test data)
|
||||
|
||||
* Tue Jan 27 2026 Eduard Abdullin <eabdullin@almalinux.org> - 1:1.58.1-2.alma.1
|
||||
- Enable building for ppc64le
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user