import libguestfs-1.48.4-4.el9

i9c-beta changed/i9c-beta/libguestfs-1.48.4-4.el9
MSVSphere Packaging Team 2 years ago
commit 92eed50d63

2
.gitignore vendored

@ -0,0 +1,2 @@
SOURCES/libguestfs-1.48.4.tar.gz
SOURCES/libguestfs.keyring

@ -0,0 +1,2 @@
a8754a62256ac488eec3e18bed20f570f785d069 SOURCES/libguestfs-1.48.4.tar.gz
1bbc40f501a7fef9eef2a39b701a71aee2fea7c4 SOURCES/libguestfs.keyring

@ -0,0 +1,96 @@
From e3ebd50abde3b05db86c8965868c866152cd3287 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Thu, 28 Apr 2022 13:16:54 +0100
Subject: [PATCH] New API: guestfs_device_name returning the drive name
For each drive added, return the name. For example calling this with
index 0 will return the string "/dev/sda". I called it
guestfs_device_name (not drive_name) for consistency with the existing
guestfs_device_index function.
You don't really need to call this function. You can follow the
advice here:
https://libguestfs.org/guestfs.3.html#block-device-naming
and assume that drives are added with predictable names like
"/dev/sda", "/dev/sdb", etc.
However it's useful to expose the internal guestfs_int_drive_name
function since especially handling names beyond index 26 is tricky
(https://rwmj.wordpress.com/2011/01/09/how-are-linux-drives-named-beyond-drive-26-devsdz/)
Fixes: https://github.com/libguestfs/libguestfs/issues/80
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
(cherry picked from commit ac00e603f83802634f1d53b1629aee4670eaf31c)
---
generator/actions_core.ml | 24 +++++++++++++++++++++++-
lib/drives.c | 15 +++++++++++++++
2 files changed, 38 insertions(+), 1 deletion(-)
diff --git a/generator/actions_core.ml b/generator/actions_core.ml
index ce9ee39cc..dc12fdc33 100644
--- a/generator/actions_core.ml
+++ b/generator/actions_core.ml
@@ -737,7 +737,29 @@ returns the index of the device in the list of devices.
Index numbers start from 0. The named device must exist,
for example as a string returned from C<guestfs_list_devices>.
-See also C<guestfs_list_devices>, C<guestfs_part_to_dev>." };
+See also C<guestfs_list_devices>, C<guestfs_part_to_dev>,
+C<guestfs_device_name>." };
+
+ { defaults with
+ name = "device_name"; added = (1, 49, 1);
+ style = RString (RPlainString, "name"), [Int "index"], [];
+ tests = [
+ InitEmpty, Always, TestResult (
+ [["device_name"; "0"]], "STREQ (ret, \"/dev/sda\")"), [];
+ InitEmpty, Always, TestResult (
+ [["device_name"; "1"]], "STREQ (ret, \"/dev/sdb\")"), [];
+ InitEmpty, Always, TestLastFail (
+ [["device_name"; "99"]]), []
+ ];
+ shortdesc = "convert device index to name";
+ longdesc = "\
+This function takes a device index and returns the device
+name. For example index C<0> will return the string C</dev/sda>.
+
+The drive index must have been added to the handle.
+
+See also C<guestfs_list_devices>, C<guestfs_part_to_dev>,
+C<guestfs_device_index>." };
{ defaults with
name = "shutdown"; added = (1, 19, 16);
diff --git a/lib/drives.c b/lib/drives.c
index fd95308d2..a6179fc36 100644
--- a/lib/drives.c
+++ b/lib/drives.c
@@ -31,6 +31,7 @@
#include <netdb.h>
#include <arpa/inet.h>
#include <assert.h>
+#include <errno.h>
#include <libintl.h>
#include "c-ctype.h"
@@ -1084,3 +1085,17 @@ guestfs_impl_device_index (guestfs_h *g, const char *device)
error (g, _("%s: device not found"), device);
return r;
}
+
+char *
+guestfs_impl_device_name (guestfs_h *g, int index)
+{
+ char drive_name[64];
+
+ if (index < 0 || index >= g->nr_drives) {
+ guestfs_int_error_errno (g, EINVAL, _("drive index out of range"));
+ return NULL;
+ }
+
+ guestfs_int_drive_name (index, drive_name);
+ return safe_asprintf (g, "/dev/sd%s", drive_name);
+}
--
2.31.1

@ -0,0 +1,565 @@
From b97b90779d5ea261d5e737f073bb4ec5dc546511 Mon Sep 17 00:00:00 2001
From: Laszlo Ersek <lersek@redhat.com>
Date: Mon, 2 May 2022 10:56:00 +0200
Subject: [PATCH] guestfs_readdir(): rewrite with FileOut transfer, to lift
protocol limit
Currently the guestfs_readdir() API can not list long directories, due to
it sending back the whole directory listing in a single guestfs protocol
response, which is limited to GUESTFS_MESSAGE_MAX (approx. 4MB) in size.
Introduce the "internal_readdir" action, for transferring the directory
listing from the daemon to the library through a FileOut parameter.
Rewrite guestfs_readdir() on top of this new internal function:
- The new "internal_readdir" action is a daemon action. Do not repurpose
the "readdir" proc_nr (138) for "internal_readdir", as some distros ship
the binary appliance to their users, and reusing the proc_nr could
create a mismatch between library & appliance with obscure symptoms.
Replace the old proc_nr (138) with a new proc_nr (511) instead; a
mismatch would then produce a clear error message. Assume the new action
will first be released in libguestfs-1.48.2.
- Turn "readdir" from a daemon action into a non-daemon one. Call the
daemon action guestfs_internal_readdir() manually, receive the FileOut
parameter into a temp file, then deserialize the dirents array from the
temp file.
This patch sneakily fixes an independent bug, too. In the pre-patch
do_readdir() function [daemon/readdir.c], when readdir() returns NULL, we
don't distinguish "end of directory stream" from "readdir() failed". This
rewrite fixes this problem -- I didn't see much value separating out the
fix for the original do_readdir().
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1674392
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Message-Id: <20220502085601.15012-2-lersek@redhat.com>
Reviewed-by: Richard W.M. Jones <rjones@redhat.com>
(cherry picked from commit 45b7f1736b64e9f0741e21e5a9d83a837bd863bf)
---
TODO | 8 ---
daemon/readdir.c | 132 +++++++++++++++++++-------------------
generator/actions_core.ml | 127 +++++++++++++++++++-----------------
generator/proc_nr.ml | 2 +-
lib/MAX_PROC_NR | 2 +-
lib/Makefile.am | 1 +
lib/readdir.c | 131 +++++++++++++++++++++++++++++++++++++
7 files changed, 267 insertions(+), 136 deletions(-)
create mode 100644 lib/readdir.c
diff --git a/TODO b/TODO
index a50f7d73c..513e55f92 100644
--- a/TODO
+++ b/TODO
@@ -484,14 +484,6 @@ this approach works, it doesn't solve the MBR problem, so likely we'd
have to write a library for that (or perhaps go back to sfdisk but
using a very abstracted interface over sfdisk).
-Reimplement some APIs to avoid protocol limits
-----------------------------------------------
-
-Mostly this item was done (eg. commits a69f44f56f and before). The
-most notable API with a protocol limit remaining is:
-
- - guestfs_readdir
-
hivex
-----
diff --git a/daemon/readdir.c b/daemon/readdir.c
index e488f93e7..9ab0b0aec 100644
--- a/daemon/readdir.c
+++ b/daemon/readdir.c
@@ -16,77 +16,67 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-#include <config.h>
+#include <config.h> /* HAVE_STRUCT_DIRENT_D_TYPE */
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <dirent.h>
+#include <dirent.h> /* readdir() */
+#include <errno.h> /* errno */
+#include <rpc/xdr.h> /* xdrmem_create() */
+#include <stdio.h> /* perror() */
+#include <stdlib.h> /* malloc() */
+#include <sys/types.h> /* opendir() */
-#include "daemon.h"
-#include "actions.h"
+#include "daemon.h" /* reply_with_perror() */
-static void
-free_int_dirent_list (guestfs_int_dirent *p, size_t len)
+/* Has one FileOut parameter. */
+int
+do_internal_readdir (const char *dir)
{
- size_t i;
+ int ret;
+ DIR *dirstream;
+ void *xdr_buf;
+ XDR xdr;
- for (i = 0; i < len; ++i) {
- free (p[i].name);
- }
- free (p);
-}
-
-guestfs_int_dirent_list *
-do_readdir (const char *path)
-{
- guestfs_int_dirent_list *ret;
- guestfs_int_dirent v;
- DIR *dir;
- struct dirent *d;
- size_t i;
-
- ret = malloc (sizeof *ret);
- if (ret == NULL) {
- reply_with_perror ("malloc");
- return NULL;
- }
-
- ret->guestfs_int_dirent_list_len = 0;
- ret->guestfs_int_dirent_list_val = NULL;
+ /* Prepare to fail. */
+ ret = -1;
CHROOT_IN;
- dir = opendir (path);
+ dirstream = opendir (dir);
CHROOT_OUT;
- if (dir == NULL) {
- reply_with_perror ("opendir: %s", path);
- free (ret);
- return NULL;
+ if (dirstream == NULL) {
+ reply_with_perror ("opendir: %s", dir);
+ return ret;
}
- i = 0;
- while ((d = readdir (dir)) != NULL) {
- guestfs_int_dirent *p;
+ xdr_buf = malloc (GUESTFS_MAX_CHUNK_SIZE);
+ if (xdr_buf == NULL) {
+ reply_with_perror ("malloc");
+ goto close_dir;
+ }
+ xdrmem_create (&xdr, xdr_buf, GUESTFS_MAX_CHUNK_SIZE, XDR_ENCODE);
+
+ /* Send an "OK" reply, before starting the file transfer. */
+ reply (NULL, NULL);
+
+ /* From this point on, we can only report errors by canceling the file
+ * transfer.
+ */
+ for (;;) {
+ struct dirent *d;
+ guestfs_int_dirent v;
+
+ errno = 0;
+ d = readdir (dirstream);
+ if (d == NULL) {
+ if (errno == 0)
+ ret = 0;
+ else
+ perror ("readdir");
- p = realloc (ret->guestfs_int_dirent_list_val,
- sizeof (guestfs_int_dirent) * (i+1));
- v.name = strdup (d->d_name);
- if (!p || !v.name) {
- reply_with_perror ("allocate");
- if (p) {
- free_int_dirent_list (p, i);
- } else {
- free_int_dirent_list (ret->guestfs_int_dirent_list_val, i);
- }
- free (v.name);
- free (ret);
- closedir (dir);
- return NULL;
+ break;
}
- ret->guestfs_int_dirent_list_val = p;
+ v.name = d->d_name;
v.ino = d->d_ino;
#ifdef HAVE_STRUCT_DIRENT_D_TYPE
switch (d->d_type) {
@@ -104,19 +94,29 @@ do_readdir (const char *path)
v.ftyp = 'u';
#endif
- ret->guestfs_int_dirent_list_val[i] = v;
+ if (!xdr_guestfs_int_dirent (&xdr, &v)) {
+ fprintf (stderr, "xdr_guestfs_int_dirent failed\n");
+ break;
+ }
- i++;
+ if (send_file_write (xdr_buf, xdr_getpos (&xdr)) != 0)
+ break;
+
+ xdr_setpos (&xdr, 0);
}
- ret->guestfs_int_dirent_list_len = i;
+ /* Finish or cancel the transfer. Note that if (ret == -1) because the library
+ * canceled, we still need to cancel back!
+ */
+ send_file_end (ret == -1);
- if (closedir (dir) == -1) {
- reply_with_perror ("closedir");
- free (ret->guestfs_int_dirent_list_val);
- free (ret);
- return NULL;
- }
+ xdr_destroy (&xdr);
+ free (xdr_buf);
+
+close_dir:
+ if (closedir (dirstream) == -1)
+ /* Best we can do here is log an error. */
+ perror ("closedir");
return ret;
}
diff --git a/generator/actions_core.ml b/generator/actions_core.ml
index dc12fdc33..807150615 100644
--- a/generator/actions_core.ml
+++ b/generator/actions_core.ml
@@ -141,6 +141,66 @@ only useful for printing debug and internal error messages.
For more information on states, see L<guestfs(3)>." };
+ { defaults with
+ name = "readdir"; added = (1, 0, 55);
+ style = RStructList ("entries", "dirent"), [String (Pathname, "dir")], [];
+ progress = true; cancellable = true;
+ shortdesc = "read directories entries";
+ longdesc = "\
+This returns the list of directory entries in directory C<dir>.
+
+All entries in the directory are returned, including C<.> and
+C<..>. The entries are I<not> sorted, but returned in the same
+order as the underlying filesystem.
+
+Also this call returns basic file type information about each
+file. The C<ftyp> field will contain one of the following characters:
+
+=over 4
+
+=item 'b'
+
+Block special
+
+=item 'c'
+
+Char special
+
+=item 'd'
+
+Directory
+
+=item 'f'
+
+FIFO (named pipe)
+
+=item 'l'
+
+Symbolic link
+
+=item 'r'
+
+Regular file
+
+=item 's'
+
+Socket
+
+=item 'u'
+
+Unknown file type
+
+=item '?'
+
+The L<readdir(3)> call returned a C<d_type> field with an
+unexpected value
+
+=back
+
+This function is primarily intended for use by programs. To
+get a simple list of names, use C<guestfs_ls>. To get a printable
+directory for human consumption, use C<guestfs_ll>." };
+
{ defaults with
name = "version"; added = (1, 0, 58);
style = RStruct ("version", "version"), [], [];
@@ -3939,66 +3999,6 @@ L<umask(2)>, C<guestfs_mknod>, C<guestfs_mkdir>.
This call returns the previous umask." };
- { defaults with
- name = "readdir"; added = (1, 0, 55);
- style = RStructList ("entries", "dirent"), [String (Pathname, "dir")], [];
- protocol_limit_warning = true;
- shortdesc = "read directories entries";
- longdesc = "\
-This returns the list of directory entries in directory C<dir>.
-
-All entries in the directory are returned, including C<.> and
-C<..>. The entries are I<not> sorted, but returned in the same
-order as the underlying filesystem.
-
-Also this call returns basic file type information about each
-file. The C<ftyp> field will contain one of the following characters:
-
-=over 4
-
-=item 'b'
-
-Block special
-
-=item 'c'
-
-Char special
-
-=item 'd'
-
-Directory
-
-=item 'f'
-
-FIFO (named pipe)
-
-=item 'l'
-
-Symbolic link
-
-=item 'r'
-
-Regular file
-
-=item 's'
-
-Socket
-
-=item 'u'
-
-Unknown file type
-
-=item '?'
-
-The L<readdir(3)> call returned a C<d_type> field with an
-unexpected value
-
-=back
-
-This function is primarily intended for use by programs. To
-get a simple list of names, use C<guestfs_ls>. To get a printable
-directory for human consumption, use C<guestfs_ll>." };
-
{ defaults with
name = "getxattrs"; added = (1, 0, 59);
style = RStructList ("xattrs", "xattr"), [String (Pathname, "path")], [];
@@ -9713,4 +9713,11 @@ C<guestfs_cryptsetup_open>. The C<device> parameter must be
the name of the mapping device (ie. F</dev/mapper/mapname>)
and I<not> the name of the underlying block device." };
+ { defaults with
+ name = "internal_readdir"; added = (1, 48, 2);
+ style = RErr, [String (Pathname, "dir"); String (FileOut, "filename")], [];
+ visibility = VInternal;
+ shortdesc = "read directories entries";
+ longdesc = "Internal function for readdir." };
+
]
diff --git a/generator/proc_nr.ml b/generator/proc_nr.ml
index b20672ff0..bdced51c9 100644
--- a/generator/proc_nr.ml
+++ b/generator/proc_nr.ml
@@ -152,7 +152,6 @@ let proc_nr = [
135, "mknod_b";
136, "mknod_c";
137, "umask";
-138, "readdir";
139, "sfdiskM";
140, "zfile";
141, "getxattrs";
@@ -514,6 +513,7 @@ let proc_nr = [
508, "cryptsetup_open";
509, "cryptsetup_close";
510, "internal_list_rpm_applications";
+511, "internal_readdir";
]
(* End of list. If adding a new entry, add it at the end of the list
diff --git a/lib/MAX_PROC_NR b/lib/MAX_PROC_NR
index 2bc4cd64b..c0556fb20 100644
--- a/lib/MAX_PROC_NR
+++ b/lib/MAX_PROC_NR
@@ -1 +1 @@
-510
+511
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 144c45588..212bcb94a 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -105,6 +105,7 @@ libguestfs_la_SOURCES = \
private-data.c \
proto.c \
qemu.c \
+ readdir.c \
rescue.c \
stringsbuf.c \
structs-compare.c \
diff --git a/lib/readdir.c b/lib/readdir.c
new file mode 100644
index 000000000..9cb0d7cf6
--- /dev/null
+++ b/lib/readdir.c
@@ -0,0 +1,131 @@
+/* libguestfs
+ * Copyright (C) 2016-2022 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> /* UNIX_PATH_MAX, needed by "guestfs-internal.h" */
+
+#include <rpc/xdr.h> /* xdrstdio_create() */
+#include <stdint.h> /* UINT32_MAX */
+#include <stdio.h> /* fopen() */
+#include <string.h> /* memset() */
+
+#include "guestfs.h" /* guestfs_internal_readdir() */
+#include "guestfs_protocol.h" /* guestfs_int_dirent */
+#include "guestfs-internal.h" /* guestfs_int_make_temp_path() */
+#include "guestfs-internal-actions.h" /* guestfs_impl_readdir */
+
+struct guestfs_dirent_list *
+guestfs_impl_readdir (guestfs_h *g, const char *dir)
+{
+ struct guestfs_dirent_list *ret;
+ char *tmpfn;
+ FILE *f;
+ off_t fsize;
+ XDR xdr;
+ struct guestfs_dirent_list *dirents;
+ uint32_t alloc_entries;
+ size_t alloc_bytes;
+
+ /* Prepare to fail. */
+ ret = NULL;
+
+ tmpfn = guestfs_int_make_temp_path (g, "readdir", NULL);
+ if (tmpfn == NULL)
+ return ret;
+
+ if (guestfs_internal_readdir (g, dir, tmpfn) == -1)
+ goto drop_tmpfile;
+
+ f = fopen (tmpfn, "r");
+ if (f == NULL) {
+ perrorf (g, "fopen: %s", tmpfn);
+ goto drop_tmpfile;
+ }
+
+ if (fseeko (f, 0, SEEK_END) == -1) {
+ perrorf (g, "fseeko");
+ goto close_tmpfile;
+ }
+ fsize = ftello (f);
+ if (fsize == -1) {
+ perrorf (g, "ftello");
+ goto close_tmpfile;
+ }
+ if (fseeko (f, 0, SEEK_SET) == -1) {
+ perrorf (g, "fseeko");
+ goto close_tmpfile;
+ }
+
+ xdrstdio_create (&xdr, f, XDR_DECODE);
+
+ dirents = safe_malloc (g, sizeof *dirents);
+ dirents->len = 0;
+ alloc_entries = 8;
+ alloc_bytes = alloc_entries * sizeof *dirents->val;
+ dirents->val = safe_malloc (g, alloc_bytes);
+
+ while (xdr_getpos (&xdr) < fsize) {
+ guestfs_int_dirent v;
+ struct guestfs_dirent *d;
+
+ if (dirents->len == alloc_entries) {
+ if (alloc_entries > UINT32_MAX / 2 || alloc_bytes > (size_t)-1 / 2) {
+ error (g, "integer overflow");
+ goto free_dirents;
+ }
+ alloc_entries *= 2u;
+ alloc_bytes *= 2u;
+ dirents->val = safe_realloc (g, dirents->val, alloc_bytes);
+ }
+
+ /* Decoding does not work unless the target buffer is zero-initialized. */
+ memset (&v, 0, sizeof v);
+ if (!xdr_guestfs_int_dirent (&xdr, &v)) {
+ error (g, "xdr_guestfs_int_dirent failed");
+ goto free_dirents;
+ }
+
+ d = &dirents->val[dirents->len];
+ d->ino = v.ino;
+ d->ftyp = v.ftyp;
+ d->name = v.name; /* transfer malloc'd string to "d" */
+
+ dirents->len++;
+ }
+
+ /* Success; transfer "dirents" to "ret". */
+ ret = dirents;
+ dirents = NULL;
+
+ /* Clean up. */
+ xdr_destroy (&xdr);
+
+free_dirents:
+ guestfs_free_dirent_list (dirents);
+
+close_tmpfile:
+ fclose (f);
+
+drop_tmpfile:
+ /* In case guestfs_internal_readdir() failed, it may or may not have created
+ * the temporary file.
+ */
+ unlink (tmpfn);
+ free (tmpfn);
+
+ return ret;
+}
--
2.31.1

@ -0,0 +1,108 @@
From 62cd6c9d2dd62dd24cc04b16437bfb816a6f4357 Mon Sep 17 00:00:00 2001
From: Laszlo Ersek <lersek@redhat.com>
Date: Mon, 2 May 2022 10:56:01 +0200
Subject: [PATCH] guestfs_readdir(): minimize the number of send_file_write()
calls
In guestfs_readdir(), the daemon currently sends each XDR-encoded
"guestfs_int_dirent" to the library with a separate send_file_write()
call.
Determine the largest encoded size (from the longest filename that a
"guestfs_int_dirent" could carry, from readdir()'s "struct dirent"), and
batch up the XDR encodings until the next encoding might not fit in
GUESTFS_MAX_CHUNK_SIZE. Call send_file_write() only then.
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1674392
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Message-Id: <20220502085601.15012-3-lersek@redhat.com>
Reviewed-by: Richard W.M. Jones <rjones@redhat.com>
(cherry picked from commit 4864d21cb8eb991f0fc98d03a068173837cba50e)
---
daemon/readdir.c | 38 ++++++++++++++++++++++++++++++++------
1 file changed, 32 insertions(+), 6 deletions(-)
diff --git a/daemon/readdir.c b/daemon/readdir.c
index 9ab0b0aec..3084ba939 100644
--- a/daemon/readdir.c
+++ b/daemon/readdir.c
@@ -35,6 +35,9 @@ do_internal_readdir (const char *dir)
DIR *dirstream;
void *xdr_buf;
XDR xdr;
+ struct dirent fill;
+ guestfs_int_dirent v;
+ unsigned max_encoded;
/* Prepare to fail. */
ret = -1;
@@ -55,6 +58,20 @@ do_internal_readdir (const char *dir)
}
xdrmem_create (&xdr, xdr_buf, GUESTFS_MAX_CHUNK_SIZE, XDR_ENCODE);
+ /* Calculate the max number of bytes a "guestfs_int_dirent" can be encoded to.
+ */
+ memset (fill.d_name, 'a', sizeof fill.d_name - 1);
+ fill.d_name[sizeof fill.d_name - 1] = '\0';
+ v.ino = INT64_MAX;
+ v.ftyp = '?';
+ v.name = fill.d_name;
+ if (!xdr_guestfs_int_dirent (&xdr, &v)) {
+ fprintf (stderr, "xdr_guestfs_int_dirent failed\n");
+ goto release_xdr;
+ }
+ max_encoded = xdr_getpos (&xdr);
+ xdr_setpos (&xdr, 0);
+
/* Send an "OK" reply, before starting the file transfer. */
reply (NULL, NULL);
@@ -63,7 +80,6 @@ do_internal_readdir (const char *dir)
*/
for (;;) {
struct dirent *d;
- guestfs_int_dirent v;
errno = 0;
d = readdir (dirstream);
@@ -94,22 +110,32 @@ do_internal_readdir (const char *dir)
v.ftyp = 'u';
#endif
+ /* Flush "xdr_buf" if we may not have enough room for encoding "v". */
+ if (GUESTFS_MAX_CHUNK_SIZE - xdr_getpos (&xdr) < max_encoded) {
+ if (send_file_write (xdr_buf, xdr_getpos (&xdr)) != 0)
+ break;
+
+ xdr_setpos (&xdr, 0);
+ }
+
if (!xdr_guestfs_int_dirent (&xdr, &v)) {
fprintf (stderr, "xdr_guestfs_int_dirent failed\n");
break;
}
-
- if (send_file_write (xdr_buf, xdr_getpos (&xdr)) != 0)
- break;
-
- xdr_setpos (&xdr, 0);
}
+ /* Flush "xdr_buf" if the loop completed successfully and "xdr_buf" is not
+ * empty. */
+ if (ret == 0 && xdr_getpos (&xdr) > 0 &&
+ send_file_write (xdr_buf, xdr_getpos (&xdr)) != 0)
+ ret = -1;
+
/* Finish or cancel the transfer. Note that if (ret == -1) because the library
* canceled, we still need to cancel back!
*/
send_file_end (ret == -1);
+release_xdr:
xdr_destroy (&xdr);
free (xdr_buf);
--
2.31.1

@ -0,0 +1,123 @@
From e4901a4e83f0ab59a525095d2fe1c7f1a38c0aac Mon Sep 17 00:00:00 2001
From: Laszlo Ersek <lersek@redhat.com>
Date: Wed, 4 May 2022 15:41:52 +0200
Subject: [PATCH] lib: launch-direct: ignore drive "iface" parameter
Rich said in <https://bugzilla.redhat.com/show_bug.cgi?id=1844341#c1>:
> The libvirt backend has never allowed the iface parameter. We should
> probably ignore it in the direct backend since it's never been possible
> to use this parameter correctly.
Remove the handling of "iface" in the direct (QEMU) backend. Refresh the
documentation regarding both backends.
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1844341
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Message-Id: <20220504134155.11832-2-lersek@redhat.com>
Reviewed-by: Richard W.M. Jones <rjones@redhat.com>
(cherry picked from commit 3eb830dbaee12c8dc4566cab226ed2af0e0f2d8c)
---
generator/actions_core_deprecated.ml | 8 +++-
lib/launch-direct.c | 59 ++++++----------------------
2 files changed, 19 insertions(+), 48 deletions(-)
diff --git a/generator/actions_core_deprecated.ml b/generator/actions_core_deprecated.ml
index 00dde3d2a..f1040a0e9 100644
--- a/generator/actions_core_deprecated.ml
+++ b/generator/actions_core_deprecated.ml
@@ -73,7 +73,9 @@ of C<guestfs_add_drive_ro>." };
shortdesc = "add a drive specifying the QEMU block emulation to use";
longdesc = "\
This is the same as C<guestfs_add_drive> but it allows you
-to specify the QEMU interface emulation to use at run time." };
+to specify the QEMU interface emulation to use at run time.
+The libvirt backend rejects a non-empty C<iface> argument.
+The direct backend ignores C<iface>." };
{ defaults with
name = "add_drive_ro_with_if"; added = (1, 0, 84);
@@ -83,7 +85,9 @@ to specify the QEMU interface emulation to use at run time." };
shortdesc = "add a drive read-only specifying the QEMU block emulation to use";
longdesc = "\
This is the same as C<guestfs_add_drive_ro> but it allows you
-to specify the QEMU interface emulation to use at run time." };
+to specify the QEMU interface emulation to use at run time.
+The libvirt backend rejects a non-empty C<iface> argument.
+The direct backend ignores C<iface>." };
{ defaults with
name = "lstatlist"; added = (1, 0, 77);
diff --git a/lib/launch-direct.c b/lib/launch-direct.c
index b292b9c26..ff0eaeb62 100644
--- a/lib/launch-direct.c
+++ b/lib/launch-direct.c
@@ -296,52 +296,19 @@ static int
add_drive (guestfs_h *g, struct backend_direct_data *data,
struct qemuopts *qopts, size_t i, struct drive *drv)
{
- /* If there's an explicit 'iface', use it. Otherwise default to
- * virtio-scsi.
- */
- if (drv->iface && STREQ (drv->iface, "virtio")) { /* virtio-blk */
- start_list ("-drive") {
- if (add_drive_standard_params (g, data, qopts, i, drv) == -1)
- return -1;
- append_list ("if=none");
- } end_list ();
- start_list ("-device") {
- append_list (VIRTIO_DEVICE_NAME ("virtio-blk"));
- append_list_format ("drive=hd%zu", i);
- if (drv->disk_label)
- append_list_format ("serial=%s", drv->disk_label);
- if (add_device_blocksize_params (g, qopts, drv) == -1)
- return -1;
- } end_list ();
- }
-#if defined(__arm__) || defined(__aarch64__) || defined(__powerpc__)
- else if (drv->iface && STREQ (drv->iface, "ide")) {
- error (g, "'ide' interface does not work on ARM or PowerPC");
- return -1;
- }
-#endif
- else if (drv->iface) {
- start_list ("-drive") {
- if (add_drive_standard_params (g, data, qopts, i, drv) == -1)
- return -1;
- append_list_format ("if=%s", drv->iface);
- } end_list ();
- }
- else /* default case: virtio-scsi */ {
- start_list ("-drive") {
- if (add_drive_standard_params (g, data, qopts, i, drv) == -1)
- return -1;
- append_list ("if=none");
- } end_list ();
- start_list ("-device") {
- append_list ("scsi-hd");
- append_list_format ("drive=hd%zu", i);
- if (drv->disk_label)
- append_list_format ("serial=%s", drv->disk_label);
- if (add_device_blocksize_params (g, qopts, drv) == -1)
- return -1;
- } end_list ();
- }
+ start_list ("-drive") {
+ if (add_drive_standard_params (g, data, qopts, i, drv) == -1)
+ return -1;
+ append_list ("if=none");
+ } end_list ();
+ start_list ("-device") {
+ append_list ("scsi-hd");
+ append_list_format ("drive=hd%zu", i);
+ if (drv->disk_label)
+ append_list_format ("serial=%s", drv->disk_label);
+ if (add_device_blocksize_params (g, qopts, drv) == -1)
+ return -1;
+ } end_list ();
return 0;
--
2.31.1

@ -0,0 +1,245 @@
From f13297315495144775f6249e9e24dc5f18f6f902 Mon Sep 17 00:00:00 2001
From: Laszlo Ersek <lersek@redhat.com>
Date: Wed, 4 May 2022 15:41:53 +0200
Subject: [PATCH] lib: drive_create_data, drive: remove field "iface"
Representing "iface" in the "drive_create_data" and "drive" structures is
now useless; the direct backend ignores "iface", while the libvirt one
rejects it unless it is empty. Unify both backends -- make them both
ignore "iface". (Which only relaxes the libvirt backend, so it cannot
cause compatibility problems.) This lets us remove the fields. Update the
documentation as well.
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1844341
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Message-Id: <20220504134155.11832-3-lersek@redhat.com>
Reviewed-by: Richard W.M. Jones <rjones@redhat.com>
(cherry picked from commit f68eaee1d6c41f91e7dfd2aa9e7d238cca7b8a4c)
---
generator/actions_core_deprecated.ml | 6 ++----
lib/drives.c | 31 +++++-----------------------
lib/guestfs-internal.h | 1 -
lib/launch-libvirt.c | 6 ------
lib/libvirt-domain.c | 15 --------------
5 files changed, 7 insertions(+), 52 deletions(-)
diff --git a/generator/actions_core_deprecated.ml b/generator/actions_core_deprecated.ml
index f1040a0e9..c23f4a330 100644
--- a/generator/actions_core_deprecated.ml
+++ b/generator/actions_core_deprecated.ml
@@ -74,8 +74,7 @@ of C<guestfs_add_drive_ro>." };
longdesc = "\
This is the same as C<guestfs_add_drive> but it allows you
to specify the QEMU interface emulation to use at run time.
-The libvirt backend rejects a non-empty C<iface> argument.
-The direct backend ignores C<iface>." };
+Both the direct and the libvirt backends ignore C<iface>." };
{ defaults with
name = "add_drive_ro_with_if"; added = (1, 0, 84);
@@ -86,8 +85,7 @@ The direct backend ignores C<iface>." };
longdesc = "\
This is the same as C<guestfs_add_drive_ro> but it allows you
to specify the QEMU interface emulation to use at run time.
-The libvirt backend rejects a non-empty C<iface> argument.
-The direct backend ignores C<iface>." };
+Both the direct and the libvirt backends ignore C<iface>." };
{ defaults with
name = "lstatlist"; added = (1, 0, 77);
diff --git a/lib/drives.c b/lib/drives.c
index a6179fc36..8fe46a41c 100644
--- a/lib/drives.c
+++ b/lib/drives.c
@@ -53,7 +53,6 @@ struct drive_create_data {
const char *secret;
bool readonly;
const char *format;
- const char *iface;
const char *name;
const char *disk_label;
const char *cachemode;
@@ -110,7 +109,6 @@ create_drive_file (guestfs_h *g,
drv->src.format = data->format ? safe_strdup (g, data->format) : NULL;
drv->readonly = data->readonly;
- drv->iface = data->iface ? safe_strdup (g, data->iface) : NULL;
drv->name = data->name ? safe_strdup (g, data->name) : NULL;
drv->disk_label = data->disk_label ? safe_strdup (g, data->disk_label) : NULL;
drv->cachemode = data->cachemode ? safe_strdup (g, data->cachemode) : NULL;
@@ -147,7 +145,6 @@ create_drive_non_file (guestfs_h *g,
drv->src.format = data->format ? safe_strdup (g, data->format) : NULL;
drv->readonly = data->readonly;
- drv->iface = data->iface ? safe_strdup (g, data->iface) : NULL;
drv->name = data->name ? safe_strdup (g, data->name) : NULL;
drv->disk_label = data->disk_label ? safe_strdup (g, data->disk_label) : NULL;
drv->cachemode = data->cachemode ? safe_strdup (g, data->cachemode) : NULL;
@@ -470,7 +467,6 @@ free_drive_struct (struct drive *drv)
{
free_drive_source (&drv->src);
free (drv->overlay);
- free (drv->iface);
free (drv->name);
free (drv->disk_label);
free (drv->cachemode);
@@ -511,14 +507,12 @@ drive_to_string (guestfs_h *g, const struct drive *drv)
s_blocksize = safe_asprintf (g, "%d", drv->blocksize);
return safe_asprintf
- (g, "%s%s%s%s protocol=%s%s%s%s%s%s%s%s%s%s%s%s%s",
+ (g, "%s%s%s%s protocol=%s%s%s%s%s%s%s%s%s%s%s",
drv->src.u.path,
drv->readonly ? " readonly" : "",
drv->src.format ? " format=" : "",
drv->src.format ? : "",
guestfs_int_drive_protocol_to_string (drv->src.protocol),
- drv->iface ? " iface=" : "",
- drv->iface ? : "",
drv->name ? " name=" : "",
drv->name ? : "",
drv->disk_label ? " label=" : "",
@@ -747,8 +741,6 @@ guestfs_impl_add_drive_opts (guestfs_h *g, const char *filename,
? optargs->readonly : false;
data.format = optargs->bitmask & GUESTFS_ADD_DRIVE_OPTS_FORMAT_BITMASK
? optargs->format : NULL;
- data.iface = optargs->bitmask & GUESTFS_ADD_DRIVE_OPTS_IFACE_BITMASK
- ? optargs->iface : NULL;
data.name = optargs->bitmask & GUESTFS_ADD_DRIVE_OPTS_NAME_BITMASK
? optargs->name : NULL;
data.disk_label = optargs->bitmask & GUESTFS_ADD_DRIVE_OPTS_LABEL_BITMASK
@@ -804,12 +796,6 @@ guestfs_impl_add_drive_opts (guestfs_h *g, const char *filename,
free_drive_servers (data.servers, data.nr_servers);
return -1;
}
- if (data.iface && !VALID_FORMAT_IFACE (data.iface)) {
- error (g, _("%s parameter is empty or contains disallowed characters"),
- "iface");
- free_drive_servers (data.servers, data.nr_servers);
- return -1;
- }
if (data.disk_label && !VALID_DISK_LABEL (data.disk_label)) {
error (g, _("label parameter is empty, too long, or contains disallowed characters"));
free_drive_servers (data.servers, data.nr_servers);
@@ -935,24 +921,17 @@ guestfs_impl_add_drive_ro (guestfs_h *g, const char *filename)
int
guestfs_impl_add_drive_with_if (guestfs_h *g, const char *filename,
- const char *iface)
+ const char *iface ATTRIBUTE_UNUSED)
{
- const struct guestfs_add_drive_opts_argv optargs = {
- .bitmask = GUESTFS_ADD_DRIVE_OPTS_IFACE_BITMASK,
- .iface = iface,
- };
-
- return guestfs_add_drive_opts_argv (g, filename, &optargs);
+ return guestfs_add_drive_opts_argv (g, filename, NULL);
}
int
guestfs_impl_add_drive_ro_with_if (guestfs_h *g, const char *filename,
- const char *iface)
+ const char *iface ATTRIBUTE_UNUSED)
{
const struct guestfs_add_drive_opts_argv optargs = {
- .bitmask = GUESTFS_ADD_DRIVE_OPTS_IFACE_BITMASK
- | GUESTFS_ADD_DRIVE_OPTS_READONLY_BITMASK,
- .iface = iface,
+ .bitmask = GUESTFS_ADD_DRIVE_OPTS_READONLY_BITMASK,
.readonly = true,
};
diff --git a/lib/guestfs-internal.h b/lib/guestfs-internal.h
index 5bb00bc10..16755cfb3 100644
--- a/lib/guestfs-internal.h
+++ b/lib/guestfs-internal.h
@@ -298,7 +298,6 @@ struct drive {
/* Various per-drive flags. */
bool readonly;
- char *iface;
char *name;
char *disk_label;
char *cachemode;
diff --git a/lib/launch-libvirt.c b/lib/launch-libvirt.c
index de342b425..03d69e027 100644
--- a/lib/launch-libvirt.c
+++ b/lib/launch-libvirt.c
@@ -1472,12 +1472,6 @@ construct_libvirt_xml_disk (guestfs_h *g,
const char *type, *uuid;
int r;
- /* XXX We probably could support this if we thought about it some more. */
- if (drv->iface) {
- error (g, _("iface parameter is not supported by the libvirt backend"));
- return -1;
- }
-
start_element ("disk") {
attribute ("device", "disk");
diff --git a/lib/libvirt-domain.c b/lib/libvirt-domain.c
index 3050680fa..fafbf50ea 100644
--- a/lib/libvirt-domain.c
+++ b/lib/libvirt-domain.c
@@ -68,7 +68,6 @@ guestfs_impl_add_domain (guestfs_h *g, const char *domain_name,
int live;
int allowuuid;
const char *readonlydisk;
- const char *iface;
const char *cachemode;
const char *discard;
bool copyonread;
@@ -78,8 +77,6 @@ guestfs_impl_add_domain (guestfs_h *g, const char *domain_name,
? optargs->libvirturi : NULL;
readonly = optargs->bitmask & GUESTFS_ADD_DOMAIN_READONLY_BITMASK
? optargs->readonly : 0;
- iface = optargs->bitmask & GUESTFS_ADD_DOMAIN_IFACE_BITMASK
- ? optargs->iface : NULL;
live = optargs->bitmask & GUESTFS_ADD_DOMAIN_LIVE_BITMASK
? optargs->live : 0;
allowuuid = optargs->bitmask & GUESTFS_ADD_DOMAIN_ALLOWUUID_BITMASK
@@ -136,10 +133,6 @@ guestfs_impl_add_domain (guestfs_h *g, const char *domain_name,
optargs2.bitmask |= GUESTFS_ADD_LIBVIRT_DOM_READONLY_BITMASK;
optargs2.readonly = readonly;
}
- if (iface) {
- optargs2.bitmask |= GUESTFS_ADD_LIBVIRT_DOM_IFACE_BITMASK;
- optargs2.iface = iface;
- }
if (live) {
error (g, _("libguestfs live support was removed in libguestfs 1.48"));
goto cleanup;
@@ -193,7 +186,6 @@ guestfs_impl_add_libvirt_dom (guestfs_h *g, void *domvp,
virDomainPtr dom = domvp;
ssize_t r;
int readonly;
- const char *iface;
const char *cachemode;
const char *discard;
bool copyonread;
@@ -208,9 +200,6 @@ guestfs_impl_add_libvirt_dom (guestfs_h *g, void *domvp,
readonly =
optargs->bitmask & GUESTFS_ADD_LIBVIRT_DOM_READONLY_BITMASK
? optargs->readonly : 0;
- iface =
- optargs->bitmask & GUESTFS_ADD_LIBVIRT_DOM_IFACE_BITMASK
- ? optargs->iface : NULL;
live =
optargs->bitmask & GUESTFS_ADD_LIBVIRT_DOM_LIVE_BITMASK
? optargs->live : 0;
@@ -289,10 +278,6 @@ guestfs_impl_add_libvirt_dom (guestfs_h *g, void *domvp,
data.optargs.bitmask = 0;
data.readonly = readonly;
data.readonlydisk = readonlydisk;
- if (iface) {
- data.optargs.bitmask |= GUESTFS_ADD_DRIVE_OPTS_IFACE_BITMASK;
- data.optargs.iface = iface;
- }
if (cachemode) {
data.optargs.bitmask |= GUESTFS_ADD_DRIVE_OPTS_CACHEMODE_BITMASK;
data.optargs.cachemode = cachemode;
--
2.31.1

@ -0,0 +1,82 @@
From f408b24d8d8f5b5f4e1a25c1046c3a18107c8d80 Mon Sep 17 00:00:00 2001
From: Laszlo Ersek <lersek@redhat.com>
Date: Wed, 4 May 2022 15:41:54 +0200
Subject: [PATCH] lib: rename VALID_FORMAT_IFACE to VALID_FORMAT
We no longer use VALID_FORMAT_IFACE for validating "iface"; rename the
macro to reflect that we only check "format" with it.
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1844341
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Message-Id: <20220504134155.11832-4-lersek@redhat.com>
Reviewed-by: Richard W.M. Jones <rjones@redhat.com>
(cherry picked from commit c8e3caf9e6000ea2f5cfbe30ffe1240317bb4578)
---
lib/drives.c | 4 ++--
lib/unit-tests.c | 16 ++++++++--------
2 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/lib/drives.c b/lib/drives.c
index 8fe46a41c..c5a208468 100644
--- a/lib/drives.c
+++ b/lib/drives.c
@@ -593,7 +593,7 @@ guestfs_int_free_drives (guestfs_h *g)
* Check string parameter matches regular expression
* C<^[-_[:alnum:]]+$> (in C locale).
*/
-#define VALID_FORMAT_IFACE(str) \
+#define VALID_FORMAT(str) \
guestfs_int_string_is_valid ((str), 1, 0, \
VALID_FLAG_ALPHA|VALID_FLAG_DIGIT, "-_")
@@ -790,7 +790,7 @@ guestfs_impl_add_drive_opts (guestfs_h *g, const char *filename,
return -1;
}
- if (data.format && !VALID_FORMAT_IFACE (data.format)) {
+ if (data.format && !VALID_FORMAT (data.format)) {
error (g, _("%s parameter is empty or contains disallowed characters"),
"format");
free_drive_servers (data.servers, data.nr_servers);
diff --git a/lib/unit-tests.c b/lib/unit-tests.c
index 62457ccba..0e550cb98 100644
--- a/lib/unit-tests.c
+++ b/lib/unit-tests.c
@@ -434,7 +434,7 @@ test_stringsbuf (void)
}
/* Use the same macros as in lib/drives.c */
-#define VALID_FORMAT_IFACE(str) \
+#define VALID_FORMAT(str) \
guestfs_int_string_is_valid ((str), 1, 0, \
VALID_FLAG_ALPHA|VALID_FLAG_DIGIT, "-_")
#define VALID_DISK_LABEL(str) \
@@ -446,18 +446,18 @@ test_stringsbuf (void)
static void
test_valid (void)
{
- assert (!VALID_FORMAT_IFACE (""));
+ assert (!VALID_FORMAT (""));
assert (!VALID_DISK_LABEL (""));
assert (!VALID_HOSTNAME (""));
assert (!VALID_DISK_LABEL ("012345678901234567890"));
- assert (VALID_FORMAT_IFACE ("abc"));
- assert (VALID_FORMAT_IFACE ("ABC"));
- assert (VALID_FORMAT_IFACE ("abc123"));
- assert (VALID_FORMAT_IFACE ("abc123-"));
- assert (VALID_FORMAT_IFACE ("abc123_"));
- assert (!VALID_FORMAT_IFACE ("abc123."));
+ assert (VALID_FORMAT ("abc"));
+ assert (VALID_FORMAT ("ABC"));
+ assert (VALID_FORMAT ("abc123"));
+ assert (VALID_FORMAT ("abc123-"));
+ assert (VALID_FORMAT ("abc123_"));
+ assert (!VALID_FORMAT ("abc123."));
assert (VALID_DISK_LABEL ("abc"));
assert (VALID_DISK_LABEL ("ABC"));
--
2.31.1

@ -0,0 +1,74 @@
From 431ca828e9f7d7a6c7e315b410f381304986ba44 Mon Sep 17 00:00:00 2001
From: Laszlo Ersek <lersek@redhat.com>
Date: Wed, 4 May 2022 15:41:55 +0200
Subject: [PATCH] tests/regressions: remove "iface"-based restrictions
Now that "iface" is ignored by both backends, the regression tests for
RHBZ 690819 and 975797 can be enabled on all arches (regardless of
backend).
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1844341
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Message-Id: <20220504134155.11832-5-lersek@redhat.com>
Reviewed-by: Richard W.M. Jones <rjones@redhat.com>
(cherry picked from commit ddf276884c04418a32902689cf8fc3506be3ca4b)
---
tests/regressions/rhbz690819.sh | 10 +++-------
tests/regressions/rhbz975797.sh | 10 +++-------
2 files changed, 6 insertions(+), 14 deletions(-)
diff --git a/tests/regressions/rhbz690819.sh b/tests/regressions/rhbz690819.sh
index e6f61d00d..9e1bcda84 100755
--- a/tests/regressions/rhbz690819.sh
+++ b/tests/regressions/rhbz690819.sh
@@ -19,18 +19,14 @@
# https://bugzilla.redhat.com/show_bug.cgi?id=690819
# mkfs fails creating a filesytem on a disk device when using a disk
# with 'ide' interface
+#
+# The 'iface' parameter is now ignored:
+# https://bugzilla.redhat.com/show_bug.cgi?id=1844341
set -e
$TEST_FUNCTIONS
skip_if_skipped
-# These architectures don't support the 'ide' interface.
-skip_if_arch arm
-skip_if_arch aarch64
-skip_if_arch ppc64
-skip_if_arch ppc64le
-skip_if_arch s390x
-skip_if_backend libvirt
rm -f rhbz690819.img
diff --git a/tests/regressions/rhbz975797.sh b/tests/regressions/rhbz975797.sh
index c676abfa3..feecf1f2b 100755
--- a/tests/regressions/rhbz975797.sh
+++ b/tests/regressions/rhbz975797.sh
@@ -19,18 +19,14 @@
# Regression test for:
# https://bugzilla.redhat.com/show_bug.cgi?id=975797
# Ensure the appliance doesn't hang when using the 'iface' parameter.
+#
+# The 'iface' parameter is now ignored:
+# https://bugzilla.redhat.com/show_bug.cgi?id=1844341
set -e
$TEST_FUNCTIONS
skip_if_skipped
-# These architectures don't support the 'ide' interface.
-skip_if_arch arm
-skip_if_arch aarch64
-skip_if_arch ppc64
-skip_if_arch ppc64le
-skip_if_arch s390x
-skip_if_backend libvirt
rm -f rhbz975797-*.img
--
2.31.1

@ -0,0 +1,56 @@
From 8f800b369ada05ea690cebb0bb5e0fed0ba1c548 Mon Sep 17 00:00:00 2001
From: Laszlo Ersek <lersek@redhat.com>
Date: Tue, 10 May 2022 12:27:57 +0200
Subject: [PATCH] generator/customize: invert SELinux relabeling default
Replace the "--selinux-relabel" option with "--no-selinux-relabel",
inverting the default behavior (for guests with SELinux support, that is
-- relabeling is always skipped for guests that don't support SELinux.)
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1554735
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2075718
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Message-Id: <20220510102757.14466-3-lersek@redhat.com>
Acked-by: Richard W.M. Jones <rjones@redhat.com>
(cherry picked from commit 2f6a27f1077d32d1ab526427052fc88e188356f7)
---
generator/customize.ml | 19 +++++++++++--------
1 file changed, 11 insertions(+), 8 deletions(-)
diff --git a/generator/customize.ml b/generator/customize.ml
index 3b3eec6d2..9634dad85 100644
--- a/generator/customize.ml
+++ b/generator/customize.ml
@@ -564,18 +564,21 @@ to modify C</etc/sysconfig/authconfig> (Fedora, RHEL) or
C</etc/pam.d/common-password> (Debian, Ubuntu).";
};
- { flag_name = "selinux-relabel";
+ { flag_name = "no-selinux-relabel";
flag_type = FlagBool false (* XXX - the default in virt-builder *);
- flag_ml_var = "selinux_relabel";
- flag_shortdesc = "Relabel files with correct SELinux labels";
+ flag_ml_var = "no_selinux_relabel";
+ flag_shortdesc = "Do not relabel files with correct SELinux labels";
flag_pod_longdesc = "\
-Relabel files in the guest so that they have the correct SELinux label.
+Do not attempt to correct the SELinux labels of files in the guest.
-This will attempt to relabel files immediately, but if the operation fails
-this will instead touch F</.autorelabel> on the image to schedule a
-relabel operation for the next time the image boots.
+In such guests that support SELinux, customization automatically
+relabels files so that they have the correct SELinux label. (The
+relabeling is performed immediately, but if the operation fails,
+customization will instead touch F</.autorelabel> on the image to
+schedule a relabel operation for the next time the image boots.) This
+option disables the automatic relabeling.
-This option is a no-op for guests that do not support SELinux.";
+The option is a no-op for guests that do not support SELinux.";
};
{ flag_name = "sm-credentials";
--
2.31.1

@ -0,0 +1,42 @@
From 4cfba19fa2b087c4b2c5a1b67aa70eb16e9d5a59 Mon Sep 17 00:00:00 2001
From: Laszlo Ersek <lersek@redhat.com>
Date: Wed, 25 May 2022 09:19:58 +0200
Subject: [PATCH] generator/customize: reintroduce "--selinux-relabel" as a
compat option
Removing "--selinux-relabel" in commit 2f6a27f1077d ("generator/customize:
invert SELinux relabeling default", 2022-05-11) breaks existing scripts
that invoke virt-customize and/or virt-sysprep with that option. Restore
the option, with no functionality tied to it.
Fixes: 2f6a27f1077d32d1ab526427052fc88e188356f7
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2089748
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Message-Id: <20220525071958.9612-1-lersek@redhat.com>
Reviewed-by: Richard W.M. Jones <rjones@redhat.com>
(cherry picked from commit 4b9ee1052a4396621485fdd56d6826714e7481b1)
---
generator/customize.ml | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/generator/customize.ml b/generator/customize.ml
index 9634dad85..5abaf206f 100644
--- a/generator/customize.ml
+++ b/generator/customize.ml
@@ -581,6 +581,13 @@ option disables the automatic relabeling.
The option is a no-op for guests that do not support SELinux.";
};
+ { flag_name = "selinux-relabel";
+ flag_type = FlagBool false;
+ flag_ml_var = "selinux_relabel_ignored";
+ flag_shortdesc = "Compatibility option doing nothing";
+ flag_pod_longdesc = "This is a compatibility option that does nothing.";
+ };
+
{ flag_name = "sm-credentials";
flag_type = FlagSMCredentials "SELECTOR";
flag_ml_var = "sm_credentials";
--
2.31.1

@ -0,0 +1,609 @@
From 010cd5ff441166c01125fc588398a1fb8367a852 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
(RHBZ#962113).
This disables support for unsupported remote drive protocols:
* ftp
* ftps
* http
* https
* tftp
* gluster
* iscsi
* sheepdog
* ssh
Note 'nbd' is not disabled, and of course 'file' works.
We hope to gradually add some of these back over the lifetime of RHEL.
---
docs/guestfs-testing.pod | 20 -----
fish/guestfish.pod | 66 ++--------------
fish/test-add-uri.sh | 32 --------
generator/actions_core.ml | 50 +------------
lib/drives.c | 8 ++
lib/guestfs.pod | 100 -------------------------
tests/disks/test-qemu-drive-libvirt.sh | 28 -------
tests/disks/test-qemu-drive.sh | 60 ---------------
8 files changed, 16 insertions(+), 348 deletions(-)
diff --git a/docs/guestfs-testing.pod b/docs/guestfs-testing.pod
index f558964bf..8f264ed17 100644
--- a/docs/guestfs-testing.pod
+++ b/docs/guestfs-testing.pod
@@ -109,26 +109,6 @@ image. To exit, type C<exit>.
If you get an error, try enabling debugging (add C<-v> to the command
line). Also make sure that L<libguestfs-test-tool(1)> succeeds.
-=head2 Try to open a remote guest image with guestfish.
-
-You may also have to disable libvirt by setting this:
-
- export LIBGUESTFS_BACKEND=direct
-
-If you have a disk image available over HTTP/FTP, try to open it.
-
- guestfish --ro -i --format=raw -a http://www.example.com/disk.img
-
-For SSH you will need to make sure that ssh-agent is set up so you
-don't need a password to log in to the remote machine. Then a command
-similar to this should work:
-
- guestfish --ro -i --format=raw \
- -a ssh://remote.example.com/path/to/disk.img
-
-If you get an error, try enabling debugging (add C<-v> to the command
-line). Also make sure that L<libguestfs-test-tool(1)> succeeds.
-
=head2 Run virt-alignment-scan on all your guests.
Run L<virt-alignment-scan(1)> on guests or disk images:
diff --git a/fish/guestfish.pod b/fish/guestfish.pod
index ae2445571..46cba64ff 100644
--- a/fish/guestfish.pod
+++ b/fish/guestfish.pod
@@ -131,9 +131,9 @@ To list what is available do:
=head2 Remote drives
-Access a remote disk using ssh:
+Access a remote disk using NBD:
- guestfish -a ssh://example.com/path/to/disk.img
+ guestfish -a nbd://example.com
=head2 Remote control
@@ -1129,12 +1129,12 @@ L<guestfs(3)/REMOTE STORAGE>>.
On the command line, you can use the I<-a> option to add network
block devices using a URI-style format, for example:
- guestfish -a ssh://root@example.com/disk.img
+ guestfish -a nbd://example.com
URIs I<cannot> be used with the L</add> command. The equivalent
command using the API directly is:
- ><fs> add /disk.img protocol:ssh server:tcp:example.com username:root
+ ><fs> add /disk.img protocol:nbd server:tcp:example.com
The possible I<-a URI> formats are described below.
@@ -1144,40 +1144,6 @@ The possible I<-a URI> formats are described below.
Add the local disk image (or device) called F<disk.img>.
-=head2 B<-a ftp://[user@]example.com[:port]/disk.img>
-
-=head2 B<-a ftps://[user@]example.com[:port]/disk.img>
-
-=head2 B<-a http://[user@]example.com[:port]/disk.img>
-
-=head2 B<-a https://[user@]example.com[:port]/disk.img>
-
-=head2 B<-a tftp://[user@]example.com[:port]/disk.img>
-
-Add a disk located on a remote FTP, HTTP or TFTP server.
-
-The equivalent API command would be:
-
- ><fs> add /disk.img protocol:(ftp|...) server:tcp:example.com
-
-=head2 B<-a gluster://example.com[:port]/volname/image>
-
-Add a disk image located on GlusterFS storage.
-
-The server is the one running C<glusterd>, and may be C<localhost>.
-
-The equivalent API command would be:
-
- ><fs> add volname/image protocol:gluster server:tcp:example.com
-
-=head2 B<-a iscsi://example.com[:port]/target-iqn-name[/lun]>
-
-Add a disk located on an iSCSI server.
-
-The equivalent API command would be:
-
- ><fs> add target-iqn-name/lun protocol:iscsi server:tcp:example.com
-
=head2 B<-a nbd://example.com[:port]>
=head2 B<-a nbd://example.com[:port]/exportname>
@@ -1212,35 +1178,13 @@ The equivalent API command would be:
><fs> add pool/disk protocol:rbd server:tcp:example.com:port
-=head2 B<-a sheepdog://[example.com[:port]]/volume/image>
-
-Add a disk image located on a Sheepdog volume.
-
-The server name is optional. Although libguestfs and Sheepdog
-supports multiple servers, only at most one server can be specified
-when using this URI syntax.
-
-The equivalent API command would be:
-
- ><fs> add volume protocol:sheepdog [server:tcp:example.com]
-
-=head2 B<-a ssh://[user@]example.com[:port]/disk.img>
-
-Add a disk image located on a remote server, accessed using the Secure
-Shell (ssh) SFTP protocol. SFTP is supported out of the box by all
-major SSH servers.
-
-The equivalent API command would be:
-
- ><fs> add /disk protocol:ssh server:tcp:example.com [username:user]
-
Note that the URIs follow the syntax of
L<RFC 3986|https://tools.ietf.org/html/rfc3986>: in particular, there
are restrictions on the allowed characters for the various components
of the URI. Characters such as C<:>, C<@>, and C</> B<must> be
percent-encoded:
- $ guestfish -a ssh://user:pass%40word@example.com/disk.img
+ $ guestfish -a rbd://user:pass%40word@example.com[:port]/pool/disk
In this case, the password is C<pass@word>.
diff --git a/fish/test-add-uri.sh b/fish/test-add-uri.sh
index 21d424984..ddabeb639 100755
--- a/fish/test-add-uri.sh
+++ b/fish/test-add-uri.sh
@@ -40,14 +40,6 @@ function fail ()
$VG guestfish -x -a file://$abs_builddir/test-add-uri.img </dev/null >test-add-uri.out 2>&1
grep -sq 'add_drive ".*/test-add-uri.img"' test-add-uri.out || fail
-# curl
-$VG guestfish -x -a ftp://user@example.com/disk.img </dev/null >test-add-uri.out 2>&1
-grep -sq 'add_drive "/disk.img" "protocol:ftp" "server:tcp:example.com" "username:user"' test-add-uri.out || fail
-
-# gluster
-$VG guestfish -x -a gluster://example.com/disk </dev/null >test-add-uri.out 2>&1
-grep -sq 'add_drive "disk" "protocol:gluster" "server:tcp:example.com"' test-add-uri.out || fail
-
# NBD
$VG guestfish -x -a nbd://example.com </dev/null >test-add-uri.out 2>&1
grep -sq 'add_drive "" "protocol:nbd" "server:tcp:example.com"' test-add-uri.out || fail
@@ -67,29 +59,5 @@ grep -sq 'add_drive "pool/disk" "protocol:rbd" "server:tcp:example.com:6789"' te
$VG guestfish -x -a rbd:///pool/disk </dev/null >test-add-uri.out 2>&1
grep -sq 'add_drive "pool/disk" "protocol:rbd"' test-add-uri.out || fail
-# sheepdog
-$VG guestfish -x -a sheepdog:///volume/image </dev/null >test-add-uri.out 2>&1
-grep -sq 'add_drive "volume/image" "protocol:sheepdog"' test-add-uri.out || fail
-
-$VG guestfish -x -a sheepdog://example.com:3000/volume/image </dev/null >test-add-uri.out 2>&1
-grep -sq 'add_drive "volume/image" "protocol:sheepdog" "server:tcp:example.com:3000"' test-add-uri.out || fail
-
-# ssh
-$VG guestfish -x -a ssh://example.com/disk.img </dev/null >test-add-uri.out 2>&1
-grep -sq 'add_drive "/disk.img" "protocol:ssh" "server:tcp:example.com"' test-add-uri.out || fail
-
-$VG guestfish -x -a ssh://user@example.com/disk.img </dev/null >test-add-uri.out 2>&1
-grep -sq 'add_drive "/disk.img" "protocol:ssh" "server:tcp:example.com" "username:user"' test-add-uri.out || fail
-
-$VG guestfish -x -a ssh://user@example.com:2000/disk.img </dev/null >test-add-uri.out 2>&1
-grep -sq 'add_drive "/disk.img" "protocol:ssh" "server:tcp:example.com:2000" "username:user"' test-add-uri.out || fail
-
-# iSCSI
-$VG guestfish -x -a iscsi://example.com/iqn.2015-12.com.libguestfs:test1/0 </dev/null >test-add-uri.out 2>&1
-grep -sq 'add_drive "iqn.2015-12.com.libguestfs:test1/0" "protocol:iscsi" "server:tcp:example.com"' test-add-uri.out || fail
-
-$VG guestfish -x -a iscsi://user:password@example.com/iqn.2015-12.com.libguestfs:test2/0 </dev/null >test-add-uri.out 2>&1
-grep -sq 'add_drive "iqn.2015-12.com.libguestfs:test2/0" "protocol:iscsi" "server:tcp:example.com" "username:user" "secret:password"' test-add-uri.out || fail
-
rm test-add-uri.out
rm test-add-uri.img
diff --git a/generator/actions_core.ml b/generator/actions_core.ml
index 807150615..6cd42a290 100644
--- a/generator/actions_core.ml
+++ b/generator/actions_core.ml
@@ -350,29 +350,6 @@ F<filename> is interpreted as a local file or device.
This is the default if the optional protocol parameter
is omitted.
-=item C<protocol = \"ftp\"|\"ftps\"|\"http\"|\"https\"|\"tftp\">
-
-Connect to a remote FTP, HTTP or TFTP server.
-The C<server> parameter must also be supplied - see below.
-
-See also: L<guestfs(3)/FTP, HTTP AND TFTP>
-
-=item C<protocol = \"gluster\">
-
-Connect to the GlusterFS server.
-The C<server> parameter must also be supplied - see below.
-
-See also: L<guestfs(3)/GLUSTER>
-
-=item C<protocol = \"iscsi\">
-
-Connect to the iSCSI server.
-The C<server> parameter must also be supplied - see below.
-The C<username> parameter may be supplied. See below.
-The C<secret> parameter may be supplied. See below.
-
-See also: L<guestfs(3)/ISCSI>.
-
=item C<protocol = \"nbd\">
Connect to the Network Block Device server.
@@ -389,22 +366,6 @@ The C<secret> parameter may be supplied. See below.
See also: L<guestfs(3)/CEPH>.
-=item C<protocol = \"sheepdog\">
-
-Connect to the Sheepdog server.
-The C<server> parameter may also be supplied - see below.
-
-See also: L<guestfs(3)/SHEEPDOG>.
-
-=item C<protocol = \"ssh\">
-
-Connect to the Secure Shell (ssh) server.
-
-The C<server> parameter must be supplied.
-The C<username> parameter may be supplied. See below.
-
-See also: L<guestfs(3)/SSH>.
-
=back
=item C<server>
@@ -415,13 +376,8 @@ is a list of server(s).
Protocol Number of servers required
-------- --------------------------
file List must be empty or param not used at all
- ftp|ftps|http|https|tftp Exactly one
- gluster Exactly one
- iscsi Exactly one
nbd Exactly one
rbd Zero or more
- sheepdog Zero or more
- ssh Exactly one
Each list element is a string specifying a server. The string must be
in one of the following formats:
@@ -437,10 +393,10 @@ for the protocol is used (see F</etc/services>).
=item C<username>
-For the C<ftp>, C<ftps>, C<http>, C<https>, C<iscsi>, C<rbd>, C<ssh>
-and C<tftp> protocols, this specifies the remote username.
+For the C<rbd>
+protocol, this specifies the remote username.
-If not given, then the local username is used for C<ssh>, and no authentication
+If not given, then no authentication
is attempted for ceph. But note this sometimes may give unexpected results, for
example if using the libvirt backend and if the libvirt backend is configured to
start the qemu appliance as a special user such as C<qemu.qemu>. If in doubt,
diff --git a/lib/drives.c b/lib/drives.c
index c5a208468..efb289254 100644
--- a/lib/drives.c
+++ b/lib/drives.c
@@ -166,6 +166,7 @@ create_drive_non_file (guestfs_h *g,
return drv;
}
+#if 0 /* DISABLED IN RHEL 8 */
static struct drive *
create_drive_curl (guestfs_h *g,
const struct drive_create_data *data)
@@ -224,6 +225,7 @@ create_drive_gluster (guestfs_h *g,
return create_drive_non_file (g, data);
}
+#endif /* DISABLED IN RHEL 8 */
static int
nbd_port (void)
@@ -292,6 +294,7 @@ create_drive_rbd (guestfs_h *g,
return create_drive_non_file (g, data);
}
+#if 0 /* DISABLED IN RHEL 8 */
static struct drive *
create_drive_sheepdog (guestfs_h *g,
const struct drive_create_data *data)
@@ -392,6 +395,7 @@ create_drive_iscsi (guestfs_h *g,
return create_drive_non_file (g, data);
}
+#endif /* DISABLED IN RHEL 8 */
/**
* Create the special F</dev/null> drive.
@@ -842,6 +846,7 @@ guestfs_impl_add_drive_opts (guestfs_h *g, const char *filename,
drv = create_drive_file (g, &data);
}
}
+#if 0 /* DISABLED IN RHEL 8 */
else if (STREQ (protocol, "ftp")) {
data.protocol = drive_protocol_ftp;
drv = create_drive_curl (g, &data);
@@ -866,6 +871,7 @@ guestfs_impl_add_drive_opts (guestfs_h *g, const char *filename,
data.protocol = drive_protocol_iscsi;
drv = create_drive_iscsi (g, &data);
}
+#endif /* DISABLED IN RHEL 8 */
else if (STREQ (protocol, "nbd")) {
data.protocol = drive_protocol_nbd;
drv = create_drive_nbd (g, &data);
@@ -874,6 +880,7 @@ guestfs_impl_add_drive_opts (guestfs_h *g, const char *filename,
data.protocol = drive_protocol_rbd;
drv = create_drive_rbd (g, &data);
}
+#if 0 /* DISABLED IN RHEL 8 */
else if (STREQ (protocol, "sheepdog")) {
data.protocol = drive_protocol_sheepdog;
drv = create_drive_sheepdog (g, &data);
@@ -886,6 +893,7 @@ guestfs_impl_add_drive_opts (guestfs_h *g, const char *filename,
data.protocol = drive_protocol_tftp;
drv = create_drive_curl (g, &data);
}
+#endif /* DISABLED IN RHEL 8 */
else {
error (g, _("unknown protocol %s"), protocol);
drv = NULL; /*FALLTHROUGH*/
diff --git a/lib/guestfs.pod b/lib/guestfs.pod
index 1ad44e7c2..946ce2d36 100644
--- a/lib/guestfs.pod
+++ b/lib/guestfs.pod
@@ -712,70 +712,6 @@ a qcow2 backing file specification, libvirt does not construct an
ephemeral secret object from those, for Ceph authentication. Refer to
L<https://bugzilla.redhat.com/2033247>.
-=head3 FTP, HTTP AND TFTP
-
-Libguestfs can access remote disks over FTP, FTPS, HTTP, HTTPS
-or TFTP protocols.
-
-To do this, set the optional C<protocol> and C<server> parameters of
-L</guestfs_add_drive_opts> like this:
-
- char **servers = { "www.example.org", NULL };
- guestfs_add_drive_opts (g, "/disk.img",
- GUESTFS_ADD_DRIVE_OPTS_FORMAT, "raw",
- GUESTFS_ADD_DRIVE_OPTS_PROTOCOL, "http",
- GUESTFS_ADD_DRIVE_OPTS_SERVER, servers,
- -1);
-
-The C<protocol> can be one of C<"ftp">, C<"ftps">, C<"http">,
-C<"https"> or C<"tftp">.
-
-C<servers> (the C<server> parameter) is a list which must have a
-single element. The single element is a string defining the web,
-FTP or TFTP server. The format of this string is documented in
-L</guestfs_add_drive_opts>.
-
-=head3 GLUSTER
-
-Libguestfs can access Gluster disks.
-
-To do this, set the optional C<protocol> and C<server> parameters of
-L</guestfs_add_drive_opts> like this:
-
- char **servers = { "gluster.example.org:24007", NULL };
- guestfs_add_drive_opts (g, "volname/image",
- GUESTFS_ADD_DRIVE_OPTS_FORMAT, "raw",
- GUESTFS_ADD_DRIVE_OPTS_PROTOCOL, "gluster",
- GUESTFS_ADD_DRIVE_OPTS_SERVER, servers,
- -1);
-
-C<servers> (the C<server> parameter) is a list which must have a
-single element. The single element is a string defining the Gluster
-server. The format of this string is documented in
-L</guestfs_add_drive_opts>.
-
-Note that gluster usually requires the client process (ie. libguestfs)
-to run as B<root> and will give unfathomable errors if it is not
-(eg. "No data available").
-
-=head3 ISCSI
-
-Libguestfs can access iSCSI disks remotely.
-
-To do this, set the optional C<protocol> and C<server> parameters like
-this:
-
- char **server = { "iscsi.example.org:3000", NULL };
- guestfs_add_drive_opts (g, "target-iqn-name/lun",
- GUESTFS_ADD_DRIVE_OPTS_FORMAT, "raw",
- GUESTFS_ADD_DRIVE_OPTS_PROTOCOL, "iscsi",
- GUESTFS_ADD_DRIVE_OPTS_SERVER, server,
- -1);
-
-The C<server> parameter is a list which must have a single element.
-The single element is a string defining the iSCSI server. The format
-of this string is documented in L</guestfs_add_drive_opts>.
-
=head3 NETWORK BLOCK DEVICE
Libguestfs can access Network Block Device (NBD) disks remotely.
@@ -838,42 +774,6 @@ L<https://bugs.launchpad.net/qemu/+bug/1155677>
=back
-=head3 SHEEPDOG
-
-Libguestfs can access Sheepdog disks.
-
-To do this, set the optional C<protocol> and C<server> parameters of
-L</guestfs_add_drive_opts> like this:
-
- char **servers = { /* optional servers ... */ NULL };
- guestfs_add_drive_opts (g, "volume",
- GUESTFS_ADD_DRIVE_OPTS_FORMAT, "raw",
- GUESTFS_ADD_DRIVE_OPTS_PROTOCOL, "sheepdog",
- GUESTFS_ADD_DRIVE_OPTS_SERVER, servers,
- -1);
-
-The optional list of C<servers> may be zero or more server addresses
-(C<"hostname:port">). The format of the server strings is documented
-in L</guestfs_add_drive_opts>.
-
-=head3 SSH
-
-Libguestfs can access disks over a Secure Shell (SSH) connection.
-
-To do this, set the C<protocol> and C<server> and (optionally)
-C<username> parameters of L</guestfs_add_drive_opts> like this:
-
- char **server = { "remote.example.com", NULL };
- guestfs_add_drive_opts (g, "/path/to/disk.img",
- GUESTFS_ADD_DRIVE_OPTS_FORMAT, "raw",
- GUESTFS_ADD_DRIVE_OPTS_PROTOCOL, "ssh",
- GUESTFS_ADD_DRIVE_OPTS_SERVER, server,
- GUESTFS_ADD_DRIVE_OPTS_USERNAME, "remoteuser",
- -1);
-
-The format of the server string is documented in
-L</guestfs_add_drive_opts>.
-
=head2 INSPECTION
Libguestfs has APIs for inspecting an unknown disk image to find out
diff --git a/tests/disks/test-qemu-drive-libvirt.sh b/tests/disks/test-qemu-drive-libvirt.sh
index 595a95a5e..b49534c94 100755
--- a/tests/disks/test-qemu-drive-libvirt.sh
+++ b/tests/disks/test-qemu-drive-libvirt.sh
@@ -65,34 +65,6 @@ check_output
grep -sq -- '-drive file=rbd:abc-def/ghi-jkl:auth_supported=none,' "$DEBUG_QEMU_FILE" || fail ceph2
rm "$DEBUG_QEMU_FILE"
-# Gluster.
-
-$guestfish -d gluster run ||:
-check_output
-grep -sq -- '-drive file=gluster://1.2.3.4:1234/volname/image,' "$DEBUG_QEMU_FILE" || fail gluster
-rm "$DEBUG_QEMU_FILE"
-
-# iSCSI.
-
-$guestfish -d iscsi run ||:
-check_output
-grep -sq -- '-drive file=iscsi://1.2.3.4:1234/iqn.2003-01.org.linux-iscsi.fedora' "$DEBUG_QEMU_FILE" || fail iscsi
-rm "$DEBUG_QEMU_FILE"
-
-# NBD.
-
-$guestfish -d nbd run ||:
-check_output
-grep -sq -- '-drive file=nbd:1.2.3.4:1234,' "$DEBUG_QEMU_FILE" || fail nbd
-rm "$DEBUG_QEMU_FILE"
-
-# Sheepdog.
-
-$guestfish -d sheepdog run ||:
-check_output
-grep -sq -- '-drive file=sheepdog:volume,' "$DEBUG_QEMU_FILE" || fail sheepdog
-rm "$DEBUG_QEMU_FILE"
-
# Local, stored in a pool.
$guestfish -d pool1 run ||:
diff --git a/tests/disks/test-qemu-drive.sh b/tests/disks/test-qemu-drive.sh
index 12937fb30..b3e4f9903 100755
--- a/tests/disks/test-qemu-drive.sh
+++ b/tests/disks/test-qemu-drive.sh
@@ -62,45 +62,6 @@ check_output
grep -sq -- '-drive file=rbd:abc-def/ghi-jkl:auth_supported=none,' "$DEBUG_QEMU_FILE" || fail
rm "$DEBUG_QEMU_FILE"
-# HTTP.
-
-guestfish <<EOF ||:
- add "/disk.img" "format:raw" "protocol:http" "server:www.example.com"
- run
-EOF
-check_output
-grep -sq -- '-drive file=http://www.example.com/disk.img,' "$DEBUG_QEMU_FILE" || fail
-rm "$DEBUG_QEMU_FILE"
-
-# Gluster.
-
-guestfish <<EOF ||:
- add "volname/image" "format:raw" "protocol:gluster" "server:www.example.com:24007"
- run
-EOF
-check_output
-grep -sq -- '-drive file=gluster://www.example.com:24007/volname/image,' "$DEBUG_QEMU_FILE" || fail
-rm "$DEBUG_QEMU_FILE"
-
-# iSCSI.
-
-guestfish <<EOF ||:
- add "target-iqn-name/lun" "format:raw" "protocol:iscsi" "server:www.example.com:3000"
- run
-EOF
-check_output
-grep -sq -- '-drive file=iscsi://www.example.com:3000/target-iqn-name/lun,' "$DEBUG_QEMU_FILE" || fail
-rm "$DEBUG_QEMU_FILE"
-
-guestfish <<EOF ||:
- add "target-iqn-name/lun" "format:raw" "protocol:iscsi" "server:www.example.com:3000" \
- "username:user" "secret:pass"
- run
-EOF
-check_output
-grep -sq -- '-drive file=iscsi://user%pass@www.example.com:3000/target-iqn-name/lun,' "$DEBUG_QEMU_FILE" || fail
-rm "$DEBUG_QEMU_FILE"
-
# NBD.
guestfish <<EOF ||:
@@ -118,24 +79,3 @@ EOF
check_output
grep -sq -- '-drive file=nbd:unix:/socket,' "$DEBUG_QEMU_FILE" || fail
rm "$DEBUG_QEMU_FILE"
-
-# Sheepdog.
-
-guestfish <<EOF ||:
- add "volume" "format:raw" "protocol:sheepdog"
- run
-EOF
-check_output
-grep -sq -- '-drive file=sheepdog:volume,' "$DEBUG_QEMU_FILE" || fail
-rm "$DEBUG_QEMU_FILE"
-
-# SSH.
-
-guestfish <<EOF ||:
- add "/disk.img" "format:raw" "protocol:ssh" "server:example.com" \
- "username:rich"
- run
-EOF
-check_output
-grep -sq -- '-drive file=ssh://rich@example.com/disk.img,' "$DEBUG_QEMU_FILE" || fail
-rm "$DEBUG_QEMU_FILE"
--
2.31.1

@ -0,0 +1,69 @@
From d59942a7a3d1ca2248a94099d28f7555378d7993 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
virt-* tools (RHBZ#1240276).
Fix the tests: it doesn't let us use guestfish for arbitrary Windows
edits.
---
generator/c.ml | 16 ++++++++++++++++
test-data/phony-guests/make-windows-img.sh | 1 +
tests/charsets/test-charset-fidelity.c | 2 ++
3 files changed, 19 insertions(+)
diff --git a/generator/c.ml b/generator/c.ml
index ea69abf76..56ee38aa4 100644
--- a/generator/c.ml
+++ b/generator/c.ml
@@ -1846,6 +1846,22 @@ and generate_client_actions actions () =
check_args_validity c_name style;
trace_call name c_name style;
+ (* RHEL 8 *)
+ if name = "mount" || name = "mount_ro" || name = "mount_options" ||
+ name = "mount_vfs" then (
+ pr " if (g->program && !STRPREFIX (g->program, \"virt-\")) {\n";
+ pr " CLEANUP_FREE char *vfs_type = guestfs_vfs_type (g, mountable);\n";
+ pr " if (vfs_type && STREQ (vfs_type, \"ntfs\")) {\n";
+ pr " error (g, \"mount: unsupported filesystem type\");\n";
+ pr " if (trace_flag)\n";
+ pr " guestfs_int_trace (g, \"%%s = %%s (error)\",\n";
+ pr " \"%s\", \"-1\");\n" name;
+ pr " return %s;\n" (string_of_errcode errcode);
+ pr " }\n";
+ pr " }\n";
+ pr "\n";
+ );
+
(* Calculate the total size of all FileIn arguments to pass
* as a progress bar hint.
*)
diff --git a/test-data/phony-guests/make-windows-img.sh b/test-data/phony-guests/make-windows-img.sh
index 30908a918..73cf5144e 100755
--- a/test-data/phony-guests/make-windows-img.sh
+++ b/test-data/phony-guests/make-windows-img.sh
@@ -37,6 +37,7 @@ fi
# Create a disk image.
guestfish <<EOF
+set-program virt-testing
sparse windows.img-t 512M
run
diff --git a/tests/charsets/test-charset-fidelity.c b/tests/charsets/test-charset-fidelity.c
index 105291dc3..5ca4f3b6d 100644
--- a/tests/charsets/test-charset-fidelity.c
+++ b/tests/charsets/test-charset-fidelity.c
@@ -96,6 +96,8 @@ main (int argc, char *argv[])
if (g == NULL)
error (EXIT_FAILURE, 0, "failed to create handle");
+ guestfs_set_program (g, "virt-testing");
+
if (guestfs_add_drive_scratch (g, 1024*1024*1024, -1) == -1)
exit (EXIT_FAILURE);
--
2.31.1

@ -0,0 +1,32 @@
From c1ff450bcee1465f0eaca00a4d6c8c731f175488 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Tue, 29 Jun 2021 15:29:11 +0100
Subject: [PATCH] RHEL: Create /etc/crypto-policies/back-ends/opensslcnf.config
https://bugzilla.redhat.com/show_bug.cgi?id=1977214#c13
---
appliance/init | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/appliance/init b/appliance/init
index 19aa151b7..e67d88280 100755
--- a/appliance/init
+++ b/appliance/init
@@ -76,6 +76,14 @@ if ! test -e /etc/mtab; then
ln -s /proc/mounts /etc/mtab
fi
+# openssl 3 requires /etc/crypto-policies/back-ends/opensslcnf.config
+# to exist, but it is created in a %post script in crypto-policies
+# https://bugzilla.redhat.com/show_bug.cgi?id=1977214#c13
+if ! test -r /etc/crypto-policies/back-ends/opensslcnf.config &&
+ test -f /usr/share/crypto-policies/DEFAULT/opensslcnf.txt; then
+ ln -s /usr/share/crypto-policies/DEFAULT/opensslcnf.txt /etc/crypto-policies/back-ends/opensslcnf.config
+fi
+
# Static nodes must happen before udev is started.
# Set up kmod static-nodes (RHBZ#1011907).
--
2.31.1

@ -0,0 +1,90 @@
From d451e0e42c75429279426e9eb5a7701cd4681d07 Mon Sep 17 00:00:00 2001
From: Geoff Amey <gamey@datto.com>
Date: Wed, 15 Jun 2022 17:06:56 -0400
Subject: [PATCH] php: add arginfo to php bindings
Starting with PHP8, arginfo is mandatory for PHP extensions. This patch
updates the generator for the PHP bindings to generate the arginfo
structures, using the Zend API macros. Only basic arginfo is added,
without full documentation of argument and return types, in order to
ensure compatibility with as many versions of PHP as possible.
(cherry picked from commit ec27979398b0871c1a3e0e244849f8435c9c9a8d)
---
.gitignore | 1 +
generator/php.ml | 37 ++++++++++++++++++++++++++++++++++---
2 files changed, 35 insertions(+), 3 deletions(-)
diff --git a/.gitignore b/.gitignore
index a36ccc86a..356c01fbd 100644
--- a/.gitignore
+++ b/.gitignore
@@ -325,6 +325,7 @@ Makefile.in
/php/extension/configure.in
/php/extension/env
/php/extension/guestfs_php.c
+/php/extension/guestfs_php.dep
/php/extension/install-sh
/php/extension/libtool
/php/extension/ltmain.sh
diff --git a/generator/php.ml b/generator/php.ml
index 5c7ef48e8..acdc7b877 100644
--- a/generator/php.ml
+++ b/generator/php.ml
@@ -130,6 +130,37 @@ typedef size_t guestfs_string_length;
typedef int guestfs_string_length;
#endif
+/* Declare argument info structures */
+ZEND_BEGIN_ARG_INFO_EX(arginfo_create, 0, 0, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_last_error, 0, 0, 1)
+ ZEND_ARG_INFO(0, g)
+ZEND_END_ARG_INFO()
+
+";
+ List.iter (
+ fun { name = shortname; style = ret, args, optargs; } ->
+ let len = List.length args in
+ pr "ZEND_BEGIN_ARG_INFO_EX(arginfo_%s, 0, 0, %d)\n" shortname (len + 1);
+ pr " ZEND_ARG_INFO(0, g)\n";
+ List.iter (
+ function
+ | BufferIn n | Bool n | Int n | Int64 n | OptString n
+ | Pointer(_, n) | String (_, n) | StringList (_, n) ->
+ pr " ZEND_ARG_INFO(0, %s)\n" n
+ ) args;
+
+ List.iter (
+ function
+ | OBool n | OInt n | OInt64 n | OString n | OStringList n ->
+ pr " ZEND_ARG_INFO(0, %s)\n" n
+ ) optargs;
+ pr "ZEND_END_ARG_INFO()\n\n";
+ ) (actions |> external_functions |> sort);
+
+ pr "
+
/* Convert array to list of strings.
* http://marc.info/?l=pecl-dev&m=112205192100631&w=2
*/
@@ -204,12 +235,12 @@ PHP_MINIT_FUNCTION (guestfs_php)
}
static zend_function_entry guestfs_php_functions[] = {
- PHP_FE (guestfs_create, NULL)
- PHP_FE (guestfs_last_error, NULL)
+ PHP_FE (guestfs_create, arginfo_create)
+ PHP_FE (guestfs_last_error, arginfo_last_error)
";
List.iter (
- fun { name } -> pr " PHP_FE (guestfs_%s, NULL)\n" name
+ fun { name } -> pr " PHP_FE (guestfs_%s, arginfo_%s)\n" name name
) (actions |> external_functions |> sort);
pr " { NULL, NULL, NULL }
--
2.31.1

@ -0,0 +1,252 @@
From 51ea2e3af9caa434e847ca74a86f5de5ade6058f Mon Sep 17 00:00:00 2001
From: Laszlo Ersek <lersek@redhat.com>
Date: Thu, 30 Jun 2022 14:20:47 +0200
Subject: [PATCH] introduce the "clevis_luks_unlock" API
Introduce a new guestfs API called "clevis_luks_unlock". At the libguestfs
level, it is quite simple; it wraps the "clevis luks unlock" guest command
(implemented by the "clevis-luks-unlock" executable, which is in fact a
shell script).
The complexity is instead in the network-based disk encryption
(Clevis/Tang) scheme. Useful documentation:
- https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/9/html-single/security_hardening/index#configuring-automated-unlocking-of-encrypted-volumes-using-policy-based-decryption_security-hardening
- https://github.com/latchset/clevis#clevis
- https://github.com/latchset/tang#tang
The package providing "clevis-luks-unlock" is usually called
"clevis-luks", occasionally "clevis". Some distros don't package clevis at
all. Add the new API under a new option group (which may not be available)
called "clevisluks".
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1809453
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Message-Id: <20220630122048.19335-3-lersek@redhat.com>
Reviewed-by: Richard W.M. Jones <rjones@redhat.com>
(cherry picked from commit 9a3e9a6c03eaffe60196bc4c7ae4699beae01dc3)
---
appliance/packagelist.in | 4 +++
daemon/Makefile.am | 1 +
daemon/clevis-luks.c | 58 +++++++++++++++++++++++++++++++++++++++
generator/actions_core.ml | 40 +++++++++++++++++++++++++++
generator/proc_nr.ml | 1 +
lib/MAX_PROC_NR | 2 +-
lib/guestfs.pod | 19 ++++++++++---
7 files changed, 120 insertions(+), 5 deletions(-)
create mode 100644 daemon/clevis-luks.c
diff --git a/appliance/packagelist.in b/appliance/packagelist.in
index 77a07acc6..0b79edcdd 100644
--- a/appliance/packagelist.in
+++ b/appliance/packagelist.in
@@ -23,6 +23,7 @@ dnl Basically the same with a few minor tweaks.
ifelse(UBUNTU,1,`define(`DEBIAN',1)')
ifelse(REDHAT,1,
+ clevis-luks
cryptsetup
cryptsetup-luks dnl old name used before Fedora 17
dhclient
@@ -53,6 +54,7 @@ ifelse(DEBIAN,1,
bsdmainutils
dnl old name used in Jessie and earlier
btrfs-tools
+ clevis-luks
cryptsetup
dash
extlinux
@@ -92,6 +94,7 @@ dnl iproute has been renamed to iproute2
ifelse(ARCHLINUX,1,
cdrkit
cdrtools
+ clevis
cryptsetup
dhclient
dhcpcd
@@ -119,6 +122,7 @@ ifelse(SUSE,1,
augeas-lenses
btrfsprogs
cdrkit-cdrtools-compat
+ clevis
cryptsetup
dhcpcd
dhcp-client
diff --git a/daemon/Makefile.am b/daemon/Makefile.am
index bbd49f9ea..f50faecd6 100644
--- a/daemon/Makefile.am
+++ b/daemon/Makefile.am
@@ -98,6 +98,7 @@ guestfsd_SOURCES = \
cap.c \
checksum.c \
cleanups.c \
+ clevis-luks.c \
cmp.c \
command.c \
command.h \
diff --git a/daemon/clevis-luks.c b/daemon/clevis-luks.c
new file mode 100644
index 000000000..d3d970d78
--- /dev/null
+++ b/daemon/clevis-luks.c
@@ -0,0 +1,58 @@
+/* libguestfs - the guestfsd daemon
+ * Copyright (C) 2009-2022 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 "daemon.h"
+#include "actions.h"
+#include "optgroups.h"
+
+#define MAX_ARGS 8
+
+int
+optgroup_clevisluks_available (void)
+{
+ return prog_exists ("clevis-luks-unlock");
+}
+
+int
+do_clevis_luks_unlock (const char *device, const char *mapname)
+{
+ const char *argv[MAX_ARGS];
+ size_t i = 0;
+ int r;
+ CLEANUP_FREE char *err = NULL;
+
+ ADD_ARG (argv, i, "clevis");
+ ADD_ARG (argv, i, "luks");
+ ADD_ARG (argv, i, "unlock");
+ ADD_ARG (argv, i, "-d");
+ ADD_ARG (argv, i, device);
+ ADD_ARG (argv, i, "-n");
+ ADD_ARG (argv, i, mapname);
+ ADD_ARG (argv, i, NULL);
+
+ r = commandv (NULL, &err, argv);
+ if (r == -1) {
+ reply_with_error ("%s: %s: %s", device, mapname, err);
+ return -1;
+ }
+
+ udev_settle ();
+ return 0;
+}
diff --git a/generator/actions_core.ml b/generator/actions_core.ml
index 6cd42a290..3c9b0a9b2 100644
--- a/generator/actions_core.ml
+++ b/generator/actions_core.ml
@@ -9676,4 +9676,44 @@ and I<not> the name of the underlying block device." };
shortdesc = "read directories entries";
longdesc = "Internal function for readdir." };
+ { defaults with
+ name = "clevis_luks_unlock"; added = (1, 49, 3);
+ style = RErr,
+ [String (Device, "device"); String (PlainString, "mapname")],
+ [];
+ optional = Some "clevisluks";
+ test_excuse = "needs networking and a configured Tang server";
+ shortdesc = "open an encrypted LUKS block device with Clevis and Tang";
+ longdesc = "\
+This command opens a block device that has been encrypted according to
+the Linux Unified Key Setup (LUKS) standard, using network-bound disk
+encryption (NBDE).
+
+C<device> is the encrypted block device.
+
+The appliance will connect to the Tang servers noted in the tree of
+Clevis pins that is bound to a keyslot of the LUKS header. The Clevis
+pin tree may comprise C<sss> (redudancy) pins as internal nodes
+(optionally), and C<tang> pins as leaves. C<tpm2> pins are not
+supported. The appliance unlocks the encrypted block device by
+combining responses from the Tang servers with metadata from the LUKS
+header; there is no C<key> parameter.
+
+This command will fail if networking has not been enabled for the
+appliance. Refer to C<guestfs_set_network>.
+
+The command creates a new block device called F</dev/mapper/mapname>.
+Reads and writes to this block device are decrypted from and encrypted
+to the underlying C<device> respectively. Close the decrypted block
+device with C<guestfs_cryptsetup_close>.
+
+C<mapname> cannot be C<\"control\"> because that name is reserved by
+device-mapper.
+
+If this block device contains LVM volume groups, then calling
+C<guestfs_lvm_scan> with the C<activate> parameter C<true> will make
+them visible.
+
+Use C<guestfs_list_dm_devices> to list all device mapper devices." };
+
]
diff --git a/generator/proc_nr.ml b/generator/proc_nr.ml
index bdced51c9..edd9bd99d 100644
--- a/generator/proc_nr.ml
+++ b/generator/proc_nr.ml
@@ -514,6 +514,7 @@ let proc_nr = [
509, "cryptsetup_close";
510, "internal_list_rpm_applications";
511, "internal_readdir";
+512, "clevis_luks_unlock"
]
(* End of list. If adding a new entry, add it at the end of the list
diff --git a/lib/MAX_PROC_NR b/lib/MAX_PROC_NR
index c0556fb20..4d0e90cbc 100644
--- a/lib/MAX_PROC_NR
+++ b/lib/MAX_PROC_NR
@@ -1 +1 @@
-511
+512
diff --git a/lib/guestfs.pod b/lib/guestfs.pod
index 946ce2d36..0fbe114a5 100644
--- a/lib/guestfs.pod
+++ b/lib/guestfs.pod
@@ -591,11 +591,22 @@ For Windows BitLocker it returns C<BitLocker>.
Then open these devices by calling L</guestfs_cryptsetup_open>.
Obviously you will require the passphrase!
+Passphrase-less unlocking is supported for LUKS (not BitLocker)
+block devices that have been encrypted with network-bound disk
+encryption (NBDE), using Clevis on the Linux guest side, and
+Tang on a separate Linux server. Open such devices with
+L</guestfs_clevis_luks_unlock>. The appliance will need
+networking enabled (refer to L</guestfs_set_network>) and actual
+connectivity to the Tang servers noted in the C<tang> Clevis
+pins that are bound to the LUKS header. (This includes the
+ability to resolve the names of the Tang servers.)
+
Opening an encrypted device creates a new device mapper device
-called F</dev/mapper/mapname> (where C<mapname> is the
-string you supply to L</guestfs_cryptsetup_open>).
-Reads and writes to this mapper device are decrypted from and
-encrypted to the underlying block device respectively.
+called F</dev/mapper/mapname> (where C<mapname> is the string
+you supply to L</guestfs_cryptsetup_open> or
+L</guestfs_clevis_luks_unlock>). Reads and writes to this mapper
+device are decrypted from and encrypted to the underlying block
+device respectively.
LVM volume groups on the device can be made visible by calling
L</guestfs_vgscan> followed by L</guestfs_vg_activate_all>.
--
2.31.1

@ -0,0 +1,69 @@
From 5ae97d7d83d8cdb6e8428774282167dd774aaf70 Mon Sep 17 00:00:00 2001
From: Laszlo Ersek <lersek@redhat.com>
Date: Thu, 30 Jun 2022 14:20:48 +0200
Subject: [PATCH] guestfish, guestmount: enable networking for "--key
ID:clevis"
Call the C-language helper key_store_requires_network() in guestfish and
guestmount.
(Short log for the "common" submodule, commit range
35467027f657..af6cb55bc58a:
Laszlo Ersek (12):
options: fix UUID comparison logic bug in get_keys()
mltools/tools_utils: remove unused function "key_store_to_cli"
mltools/tools_utils: allow multiple "--key" options for OCaml tools too
options: replace NULL-termination with number-of-elements in get_keys()
options: wrap each passphrase from get_keys() into a struct
options: add back-end for LUKS decryption with Clevis+Tang
options: introduce selector type "key_clevis"
options: generalize "--key" selector parsing for C-language utilities
mltools/tools_utils-c: handle internal type error with abort()
mltools/tools_utils: generalize "--key" selector parsing for OCaml utils
options, mltools/tools_utils: parse "--key ID:clevis" options
options, mltools/tools_utils: add helper for network dependency
).
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1809453
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Richard W.M. Jones <rjones@redhat.com>
Message-Id: <20220630122048.19335-4-lersek@redhat.com>
(cherry picked from commit 6a5b44f538065a9f661510234a4235bf38348213)
---
fish/fish.c | 3 +++
fuse/guestmount.c | 4 ++++
2 files changed, 7 insertions(+)
diff --git a/fish/fish.c b/fish/fish.c
index 23d9bb94f..19e3d2799 100644
--- a/fish/fish.c
+++ b/fish/fish.c
@@ -476,6 +476,9 @@ main (int argc, char *argv[])
/* If we've got drives to add, add them now. */
add_drives (drvs);
+ if (key_store_requires_network (ks) && guestfs_set_network (g, 1) == -1)
+ exit (EXIT_FAILURE);
+
/* If we've got mountpoints or prepared drives or -i option, we must
* launch the guest and mount them.
*/
diff --git a/fuse/guestmount.c b/fuse/guestmount.c
index 77c534828..3c6d57bde 100644
--- a/fuse/guestmount.c
+++ b/fuse/guestmount.c
@@ -348,6 +348,10 @@ main (int argc, char *argv[])
/* Do the guest drives and mountpoints. */
add_drives (drvs);
+
+ if (key_store_requires_network (ks) && guestfs_set_network (g, 1) == -1)
+ exit (EXIT_FAILURE);
+
if (guestfs_launch (g) == -1)
exit (EXIT_FAILURE);
if (inspector)
--
2.31.1

@ -0,0 +1,182 @@
From 4807dacb577167b89cb5ffb1fa1a68ddf30b9319 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Tue, 9 Aug 2022 18:39:30 +0100
Subject: [PATCH] daemon: Add zstd support to guestfs_file_architecture
This is required so we can determine the file architecture of
zstd-compressed Linux kernel modules as used by OpenSUSE and maybe
other distros in future.
Note that zstd becomes a required package, but it is widely available
in current Linux distros.
The package names come from https://pkgs.org/download/zstd and my own
research.
(cherry picked from commit 0e784824e82a88e522873fec5db1a11943d637ed)
---
.gitignore | 1 +
appliance/packagelist.in | 6 ++++++
daemon/filearch.ml | 1 +
docs/guestfs-building.pod | 4 ++++
generator/actions_core.ml | 2 ++
m4/guestfs-progs.m4 | 4 ++++
test-data/Makefile.am | 1 +
test-data/files/Makefile.am | 6 ++++++
8 files changed, 25 insertions(+)
diff --git a/.gitignore b/.gitignore
index 356c01fbd..ee5ea74dd 100644
--- a/.gitignore
+++ b/.gitignore
@@ -448,6 +448,7 @@ Makefile.in
/test-data/files/initrd-x86_64.img
/test-data/files/initrd-x86_64.img.gz
/test-data/files/lib-i586.so.xz
+/test-data/files/lib-i586.so.zst
/test-data/files/test-grep.txt.gz
/test-data/phony-guests/archlinux.img
/test-data/phony-guests/blank-*.img
diff --git a/appliance/packagelist.in b/appliance/packagelist.in
index 0b79edcdd..0fc11f6ae 100644
--- a/appliance/packagelist.in
+++ b/appliance/packagelist.in
@@ -48,6 +48,7 @@ ifelse(REDHAT,1,
vim-minimal
xz
zfs-fuse
+ zstd
)
ifelse(DEBIAN,1,
@@ -88,6 +89,7 @@ dnl iproute has been renamed to iproute2
vim-tiny
xz-utils
zfs-fuse
+ zstd
uuid-runtime
)
@@ -115,6 +117,7 @@ ifelse(ARCHLINUX,1,
systemd
vim
xz
+ zstd
)
ifelse(SUSE,1,
@@ -140,6 +143,7 @@ ifelse(SUSE,1,
systemd-sysvinit
vim
xz
+ zstd
)
ifelse(FRUGALWARE,1,
@@ -185,6 +189,7 @@ ifelse(MAGEIA,1,
systemd /* for /sbin/reboot and udevd */
vim-minimal
xz
+ zstd
)
ifelse(OPENMANDRIVA,1,
@@ -203,6 +208,7 @@ ifelse(OPENMANDRIVA,1,
systemd /* for /sbin/reboot and udevd */
vim-minimal
xz
+ zstd
)
include(guestfsd.deps)
diff --git a/daemon/filearch.ml b/daemon/filearch.ml
index 67a7339e0..4d7e912c0 100644
--- a/daemon/filearch.ml
+++ b/daemon/filearch.ml
@@ -106,6 +106,7 @@ and cpio_arch magic orig_path path =
if String.find magic "gzip" >= 0 then "zcat"
else if String.find magic "bzip2" >= 0 then "bzcat"
else if String.find magic "XZ compressed" >= 0 then "xzcat"
+ else if String.find magic "Zstandard compressed" >= 0 then "zstdcat"
else "cat" in
let tmpdir = Mkdtemp.temp_dir "filearch" in
diff --git a/docs/guestfs-building.pod b/docs/guestfs-building.pod
index b93a611a6..7a7240f78 100644
--- a/docs/guestfs-building.pod
+++ b/docs/guestfs-building.pod
@@ -172,6 +172,10 @@ I<Required>.
I<Required>.
+=item zstd
+
+I<Required>.
+
=item Jansson E<ge> 2.7
I<Required>.
diff --git a/generator/actions_core.ml b/generator/actions_core.ml
index 3c9b0a9b2..553e4ec3b 100644
--- a/generator/actions_core.ml
+++ b/generator/actions_core.ml
@@ -9373,6 +9373,8 @@ with large files, such as the resulting squashfs will be over 3GB big." };
[["file_architecture"; "/bin-x86_64-dynamic.gz"]], "x86_64"), [];
InitISOFS, Always, TestResultString (
[["file_architecture"; "/lib-i586.so.xz"]], "i386"), [];
+ InitISOFS, Always, TestResultString (
+ [["file_architecture"; "/lib-i586.so.zst"]], "i386"), [];
];
shortdesc = "detect the architecture of a binary file";
longdesc = "\
diff --git a/m4/guestfs-progs.m4 b/m4/guestfs-progs.m4
index cd8662e86..22fc61367 100644
--- a/m4/guestfs-progs.m4
+++ b/m4/guestfs-progs.m4
@@ -95,6 +95,10 @@ AC_PATH_PROGS([XZCAT],[xzcat],[no])
test "x$XZCAT" = "xno" && AC_MSG_ERROR([xzcat must be installed])
AC_DEFINE_UNQUOTED([XZCAT],["$XZCAT"],[Name of xzcat program.])
+dnl Check for zstdcat (required).
+AC_PATH_PROGS([ZSTDCAT],[zstdcat],[no])
+test "x$ZSTDCAT" = "xno" && AC_MSG_ERROR([zstdcat must be installed])
+
dnl (f)lex and bison for virt-builder (required).
dnl XXX Could be optional with some work.
AC_PROG_LEX
diff --git a/test-data/Makefile.am b/test-data/Makefile.am
index b603311a1..dbecd74b9 100644
--- a/test-data/Makefile.am
+++ b/test-data/Makefile.am
@@ -85,6 +85,7 @@ image_files = \
files/initrd-x86_64.img \
files/initrd-x86_64.img.gz \
files/lib-i586.so.xz \
+ files/lib-i586.so.zst \
files/test-grep.txt.gz
noinst_DATA = test.iso
diff --git a/test-data/files/Makefile.am b/test-data/files/Makefile.am
index a3d7288f9..06b0c6585 100644
--- a/test-data/files/Makefile.am
+++ b/test-data/files/Makefile.am
@@ -40,6 +40,7 @@ noinst_DATA = \
initrd-x86_64.img \
initrd-x86_64.img.gz \
lib-i586.so.xz \
+ lib-i586.so.zst \
test-grep.txt.gz
CLEANFILES += $(noinst_DATA)
@@ -116,3 +117,8 @@ lib-i586.so.xz: $(top_srcdir)/test-data/binaries/lib-i586.so
rm -f $@ $@-t
xz -c $< > $@-t
mv $@-t $@
+
+lib-i586.so.zst: $(top_srcdir)/test-data/binaries/lib-i586.so
+ rm -f $@ $@-t
+ zstd -c $< > $@-t
+ mv $@-t $@
--
2.31.1

@ -0,0 +1,184 @@
From 7dbcddd5bd5939493db74843593316f7101f8fde Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Thu, 1 Dec 2022 10:00:46 +0000
Subject: [PATCH] New API: inspect_get_build_id
Add an API to return the build ID of the guest. This to allow a
future change to be able to distinguish between Windows 10 and Windows 11
which can only be done using the build ID.
For Windows we can read the CurrentBuildNumber key from the registry.
For Linux there happens to be a BUILD_ID field in /etc/os-release.
I've never seen a Linux distro that actually uses this.
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
(cherry picked from commit f3dd67affe3c657af64ee9f6d70a16e965309556)
---
daemon/inspect.ml | 6 ++++++
daemon/inspect_fs_unix.ml | 2 ++
daemon/inspect_fs_windows.ml | 14 ++++++++++++++
daemon/inspect_types.ml | 5 +++++
daemon/inspect_types.mli | 1 +
generator/actions_inspection.ml | 19 +++++++++++++++++++
generator/proc_nr.ml | 3 ++-
lib/MAX_PROC_NR | 2 +-
8 files changed, 50 insertions(+), 2 deletions(-)
diff --git a/daemon/inspect.ml b/daemon/inspect.ml
index fb75b4a6c..20217c025 100644
--- a/daemon/inspect.ml
+++ b/daemon/inspect.ml
@@ -335,6 +335,12 @@ and inspect_get_hostname root =
| Some v -> v
| None -> "unknown"
+and inspect_get_build_id root =
+ let root = search_for_root root in
+ match root.inspection_data.build_id with
+ | Some v -> v
+ | None -> "unknown"
+
and inspect_get_windows_systemroot root =
let root = search_for_root root in
match root.inspection_data.windows_systemroot with
diff --git a/daemon/inspect_fs_unix.ml b/daemon/inspect_fs_unix.ml
index 63cb279d0..009195f80 100644
--- a/daemon/inspect_fs_unix.ml
+++ b/daemon/inspect_fs_unix.ml
@@ -96,6 +96,8 @@ let rec parse_os_release release_file data =
data.product_name <- Some value
else if key = "VERSION_ID" then
parse_os_release_version_id value data
+ else if key = "BUILD_ID" then
+ data.build_id <- Some value
) values;
(* If we haven't got all the fields, exit right away. *)
diff --git a/daemon/inspect_fs_windows.ml b/daemon/inspect_fs_windows.ml
index c4a05bc38..7bc5de7f7 100644
--- a/daemon/inspect_fs_windows.ml
+++ b/daemon/inspect_fs_windows.ml
@@ -263,6 +263,20 @@ and check_windows_software_registry software_hive data =
with
Not_found -> ()
);
+
+ (* CurrentBuildNumber (build_id).
+ *
+ * In modern Windows, the "CurrentBuild" and "CurrentBuildNumber"
+ * keys are the same. But in Windows XP, "CurrentBuild"
+ * contained something quite different. So always use
+ * "CurrentBuildNumber".
+ *)
+ (try
+ let v = List.assoc "CurrentBuildNumber" values in
+ data.build_id <- Some (Hivex.value_string h v)
+ with
+ Not_found -> ()
+ );
with
| Not_found ->
if verbose () then
diff --git a/daemon/inspect_types.ml b/daemon/inspect_types.ml
index 9395c51f9..328a2146b 100644
--- a/daemon/inspect_types.ml
+++ b/daemon/inspect_types.ml
@@ -48,6 +48,7 @@ and inspection_data = {
mutable version : version option;
mutable arch : string option;
mutable hostname : string option;
+ mutable build_id : string option;
mutable fstab : fstab_entry list;
mutable windows_systemroot : string option;
mutable windows_software_hive : string option;
@@ -167,6 +168,8 @@ and string_of_inspection_data data =
data.arch;
Option.may (fun v -> bpf " hostname: %s\n" v)
data.hostname;
+ Option.may (fun v -> bpf " build ID: %s\n" v)
+ data.build_id;
if data.fstab <> [] then (
let v = List.map (
fun (a, b) -> sprintf "(%s, %s)" (Mountable.to_string a) b
@@ -272,6 +275,7 @@ let null_inspection_data = {
version = None;
arch = None;
hostname = None;
+ build_id = None;
fstab = [];
windows_systemroot = None;
windows_software_hive = None;
@@ -294,6 +298,7 @@ let merge_inspection_data child parent =
parent.version <- merge child.version parent.version;
parent.arch <- merge child.arch parent.arch;
parent.hostname <- merge child.hostname parent.hostname;
+ parent.build_id <- merge child.build_id parent.build_id;
parent.fstab <- child.fstab @ parent.fstab;
parent.windows_systemroot <-
merge child.windows_systemroot parent.windows_systemroot;
diff --git a/daemon/inspect_types.mli b/daemon/inspect_types.mli
index 29c76e8ab..05a3ffd4e 100644
--- a/daemon/inspect_types.mli
+++ b/daemon/inspect_types.mli
@@ -51,6 +51,7 @@ and inspection_data = {
mutable version : version option;
mutable arch : string option;
mutable hostname : string option;
+ mutable build_id : string option;
mutable fstab : fstab_entry list;
mutable windows_systemroot : string option;
mutable windows_software_hive : string option;
diff --git a/generator/actions_inspection.ml b/generator/actions_inspection.ml
index f8b744993..70de22ec0 100644
--- a/generator/actions_inspection.ml
+++ b/generator/actions_inspection.ml
@@ -529,6 +529,25 @@ hive is a valid Windows Registry hive.
You can use C<guestfs_hivex_open> to read or write to the hive.
+Please read L<guestfs(3)/INSPECTION> for more details." };
+
+ { defaults with
+ name = "inspect_get_build_id"; added = (1, 49, 8);
+ style = RString (RPlainString, "buildid"), [String (Mountable, "root")], [];
+ impl = OCaml "Inspect.inspect_get_build_id";
+ shortdesc = "get the system build ID";
+ longdesc = "\
+This returns the build ID of the system, or the string
+C<\"unknown\"> if the system does not have a build ID.
+
+For Windows, this gets the build number. Although it is
+returned as a string, it is (so far) always a number. See
+L<https://en.wikipedia.org/wiki/List_of_Microsoft_Windows_versions>
+for some possible values.
+
+For Linux, this returns the C<BUILD_ID> string from
+F</etc/os-release>, although this is not often used.
+
Please read L<guestfs(3)/INSPECTION> for more details." };
{ defaults with
diff --git a/generator/proc_nr.ml b/generator/proc_nr.ml
index edd9bd99d..0f17b1c06 100644
--- a/generator/proc_nr.ml
+++ b/generator/proc_nr.ml
@@ -514,7 +514,8 @@ let proc_nr = [
509, "cryptsetup_close";
510, "internal_list_rpm_applications";
511, "internal_readdir";
-512, "clevis_luks_unlock"
+512, "clevis_luks_unlock";
+513, "inspect_get_build_id";
]
(* End of list. If adding a new entry, add it at the end of the list
diff --git a/lib/MAX_PROC_NR b/lib/MAX_PROC_NR
index 4d0e90cbc..31cf34b8d 100644
--- a/lib/MAX_PROC_NR
+++ b/lib/MAX_PROC_NR
@@ -1 +1 @@
-512
+513
--
2.31.1

@ -0,0 +1,82 @@
From 363bbb7e9bd39fc1683fb600c76266f67ad2063c Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Thu, 1 Dec 2022 10:14:43 +0000
Subject: [PATCH] lib: Return correct osinfo field for Windows 11
For Windows Client, we can only distinguish between Windows 10 and
Windows 11 using the build ID. The product name in both cases is
"Windows 10 <something>", apparently intentionally.
References:
https://learn.microsoft.com/en-us/answers/questions/586619/windows-11-build-ver-is-still-10022000194.html
https://github.com/cygwin/cygwin/blob/a263fe0b268580273c1adc4b1bad256147990222/winsup/cygwin/wincap.cc#L429
https://en.wikipedia.org/wiki/List_of_Microsoft_Windows_versions
After this fix, the output of virt-inspector changes to this, which is
a bit odd, but correct:
<name>windows</name>
<arch>x86_64</arch>
<distro>windows</distro>
<product_name>Windows 10 Pro</product_name>
<product_variant>Client</product_variant>
<major_version>10</major_version>
<minor_version>0</minor_version>
<windows_systemroot>/Windows</windows_systemroot>
<windows_current_control_set>ControlSet001</windows_current_control_set>
<osinfo>win11</osinfo>
Thanks: Yaakov Selkowitz
Reported-by: Yongkui Guo
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=2012658
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
(cherry picked from commit 824c7457489366494f0f10fd3369dc30f3a3c360)
---
lib/inspect-osinfo.c | 24 ++++++++++++++++++++++--
1 file changed, 22 insertions(+), 2 deletions(-)
diff --git a/lib/inspect-osinfo.c b/lib/inspect-osinfo.c
index 90e57e6df..1c10ff469 100644
--- a/lib/inspect-osinfo.c
+++ b/lib/inspect-osinfo.c
@@ -86,6 +86,8 @@ guestfs_impl_inspect_get_osinfo (guestfs_h *g, const char *root)
else if (STREQ (type, "windows")) {
CLEANUP_FREE char *product_name = NULL;
CLEANUP_FREE char *product_variant = NULL;
+ CLEANUP_FREE char *build_id_str = NULL;
+ int build_id;
product_name = guestfs_inspect_get_product_name (g, root);
if (!product_name)
@@ -142,8 +144,26 @@ guestfs_impl_inspect_get_osinfo (guestfs_h *g, const char *root)
return safe_strdup (g, "win2k19");
else
return safe_strdup (g, "win2k16");
- } else
- return safe_strdup (g, "win10");
+ }
+ else {
+ /* For Windows >= 10 Client we can only distinguish between
+ * versions by looking at the build ID. See:
+ * https://learn.microsoft.com/en-us/answers/questions/586619/windows-11-build-ver-is-still-10022000194.html
+ * https://github.com/cygwin/cygwin/blob/a263fe0b268580273c1adc4b1bad256147990222/winsup/cygwin/wincap.cc#L429
+ */
+ build_id_str = guestfs_inspect_get_build_id (g, root);
+ if (!build_id_str)
+ return NULL;
+
+ build_id = guestfs_int_parse_unsigned_int (g, build_id_str);
+ if (build_id == -1)
+ return NULL;
+
+ if (build_id >= 22000)
+ return safe_strdup (g, "win11");
+ else
+ return safe_strdup (g, "win10");
+ }
}
break;
}
--
2.31.1

@ -0,0 +1,37 @@
Libguestfs is a set of tools and a library for accessing and modifying
guest disk images. For more information see the home page:
http://libguestfs.org/
For discussion, development, patches, etc. please use the mailing
list:
http://www.redhat.com/mailman/listinfo/libguestfs
This package comes with a lot of help and examples to get you started.
The first place to start are the manual pages. Type:
man guestfs
man guestfs-faq
man guestfs-release-notes
man guestfish
man virt-cat # and other virt-* tools
If you install the libguestfs-devel package, then in the
/usr/share/doc/libguestfs-devel/ directory you will find other
documentation including:
- BUGS: list of open bugs in this version
- ChangeLog.gz: the detailed list of changes in this version
- HACKING: how to extend libguestfs
- TODO: ideas for extending libguestfs
- *.c: example C programs using the API
- *.xml.gz: example virt-inspector output (compressed)
- virt-inspector.rng: virt-inspector RelaxNG schema

@ -0,0 +1,61 @@
#!/bin/bash -
set -e
# Maintainer script to copy patches from the git repo to the current
# directory. It's normally only used downstream (ie. in RHEL). Use
# it like this:
# ./copy-patches.sh
project=libguestfs
rhel_version=9.2
# Check we're in the right directory.
if [ ! -f $project.spec ]; then
echo "$0: run this from the directory containing '$project.spec'"
exit 1
fi
case `id -un` in
rjones) git_checkout=$HOME/d/$project-rhel-$rhel_version ;;
lacos) git_checkout=$HOME/src/v2v/$project ;;
*) git_checkout=$HOME/d/$project-rhel-$rhel_version ;;
esac
if [ ! -d $git_checkout ]; then
echo "$0: $git_checkout does not exist"
echo "This script is only for use by the maintainer when preparing a"
echo "$project release on RHEL."
exit 1
fi
# Get the base version of the project.
version=`grep '^Version:' $project.spec | awk '{print $2}'`
tag="v$version"
# Remove any existing patches.
git rm -f [0-9]*.patch ||:
rm -f [0-9]*.patch
# Get the patches.
(cd $git_checkout; rm -f [0-9]*.patch; git -c core.abbrev=9 format-patch -O/dev/null -N --submodule=diff $tag)
mv $git_checkout/[0-9]*.patch .
# Remove any not to be applied.
rm -f *NOT-FOR-RPM*.patch
# Add the patches.
git add [0-9]*.patch
# Print out the patch lines.
echo
echo "--- Copy the following text into $project.spec file"
echo
echo "# Patches."
for f in [0-9]*.patch; do
n=`echo $f | awk -F- '{print $1}'`
echo "Patch$n: $f"
done
echo
echo "--- End of text"

@ -0,0 +1,6 @@
# Guestfish colour prompts. See PROMPT in guestfish(1).
GUESTFISH_PS1='\[\e[1;32m\]><fs>\[\e[0;31m\] '
GUESTFISH_OUTPUT='\e[0m'
GUESTFISH_RESTORE="$GUESTFISH_OUTPUT"
GUESTFISH_INIT='\e[1;34m'
export GUESTFISH_PS1 GUESTFISH_OUTPUT GUESTFISH_RESTORE GUESTFISH_INIT

@ -0,0 +1,17 @@
-----BEGIN PGP SIGNATURE-----
iQJFBAABCAAvFiEE93dPsa0HSn6Mh2fqkXOPc+G3aKAFAmLFql8RHHJpY2hAYW5u
ZXhpYS5vcmcACgkQkXOPc+G3aKAV2hAAzOcZseFTUFFoj4M5riqXqtBN3W+fr/O7
v0wzJ9sY31Ftk8KFKKgpwOn4UFXYMPXY7Hm94GRAYjYBAtx9Viyyt7B6PbV7mVZ0
WHLlZcg3ZsliF23s3EoHfgTGFfKLkjDwfPlmChC260Ffhq4KKvnwu/DobY/CDLHG
0cvrjb0OOYibBGbq58AHYR6QlVH/ScAuLSA1aRAd06bbpixufRR1oh1MtFA1iSvC
yjNH0joLFiu0uuD7KFH66YX2nFNrO24r0LxJkwT5G7GHlZJStJUpvs/QHa8Tw5Zt
Z1JMk9yB9EMPYimdVDm7m6eDBxTx8YbF7u6G8JdHRXgAPBt4O09XX7WGxxmh9Dc4
M+QkpiubEOG6qwBythJJ6sTSRLKIAPeVfHEOauXg8n45Tbk5jYwthMKbnD9ETb3t
QKdMr5g+DZUO0LfbOvP0GtD+b1jK4iu4BcWDquQBXpDTbx7LUfSuTDrWItehEnBp
/K6FRbakNZEroLR5VA9WAa6sE+2B3gg1OG+KHypHuw4hfpmutvVA8wnPgyw3j+WK
xdcRp65NUMUkKRE/FTwp1MkY1Y2S9M9iAPX+CopdHPVoq9O2YE+K6Rv1EdJjmKZK
EwLzX08Xcj9T/U9GEfV+QdIzitCuxf7x9ULEDcFozFnuHXww+JLdR0EmIDkUwl7C
Z0KKsy18Eq8=
=WB1H
-----END PGP SIGNATURE-----

@ -0,0 +1,17 @@
[main]
cachedir=@PWD@/cachedir
debuglevel=1
logfile=@PWD@/yum.log
retries=20
obsoletes=1
gpgcheck=0
assumeyes=1
reposdir=/dev/null
modulesdir=@PWD@/modules
[local]
name=local
baseurl=file://@PWD@/repo
failovermethod=priority
enabled=1
gpgcheck=0

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save