diff --git a/0001-New-API-guestfs_device_name-returning-the-drive-name.patch b/0001-New-API-guestfs_device_name-returning-the-drive-name.patch new file mode 100644 index 0000000..c588b72 --- /dev/null +++ b/0001-New-API-guestfs_device_name-returning-the-drive-name.patch @@ -0,0 +1,96 @@ +From 135a1767a9cfee6501b39821e4cfbf8310096b70 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +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 +(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. + +-See also C, C." }; ++See also C, C, ++C." }; ++ ++ { 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. ++ ++The drive index must have been added to the handle. ++ ++See also C, C, ++C." }; + + { 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 + #include + #include ++#include + #include + + #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 + diff --git a/0002-guestfs_readdir-rewrite-with-FileOut-transfer-to-lif.patch b/0002-guestfs_readdir-rewrite-with-FileOut-transfer-to-lif.patch new file mode 100644 index 0000000..ea48daa --- /dev/null +++ b/0002-guestfs_readdir-rewrite-with-FileOut-transfer-to-lif.patch @@ -0,0 +1,565 @@ +From 21cf5aadf26305ccbd4de25462648344602643e9 Mon Sep 17 00:00:00 2001 +From: Laszlo Ersek +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 +Message-Id: <20220502085601.15012-2-lersek@redhat.com> +Reviewed-by: Richard W.M. Jones +(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 ++#include /* HAVE_STRUCT_DIRENT_D_TYPE */ + +-#include +-#include +-#include +-#include +-#include ++#include /* readdir() */ ++#include /* errno */ ++#include /* xdrmem_create() */ ++#include /* perror() */ ++#include /* malloc() */ ++#include /* 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." }; + ++ { 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. ++ ++All entries in the directory are returned, including C<.> and ++C<..>. The entries are I sorted, but returned in the same ++order as the underlying filesystem. ++ ++Also this call returns basic file type information about each ++file. The C 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 call returned a C field with an ++unexpected value ++ ++=back ++ ++This function is primarily intended for use by programs. To ++get a simple list of names, use C. To get a printable ++directory for human consumption, use C." }; ++ + { defaults with + name = "version"; added = (1, 0, 58); + style = RStruct ("version", "version"), [], []; +@@ -3939,66 +3999,6 @@ L, C, C. + + 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. +- +-All entries in the directory are returned, including C<.> and +-C<..>. The entries are I sorted, but returned in the same +-order as the underlying filesystem. +- +-Also this call returns basic file type information about each +-file. The C 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 call returned a C field with an +-unexpected value +- +-=back +- +-This function is primarily intended for use by programs. To +-get a simple list of names, use C. To get a printable +-directory for human consumption, use C." }; +- + { defaults with + name = "getxattrs"; added = (1, 0, 59); + style = RStructList ("xattrs", "xattr"), [String (Pathname, "path")], []; +@@ -9713,4 +9713,11 @@ C. The C parameter must be + the name of the mapping device (ie. F) + and I 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 /* UNIX_PATH_MAX, needed by "guestfs-internal.h" */ ++ ++#include /* xdrstdio_create() */ ++#include /* UINT32_MAX */ ++#include /* fopen() */ ++#include /* 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 + diff --git a/0003-guestfs_readdir-minimize-the-number-of-send_file_wri.patch b/0003-guestfs_readdir-minimize-the-number-of-send_file_wri.patch new file mode 100644 index 0000000..0a8dcbe --- /dev/null +++ b/0003-guestfs_readdir-minimize-the-number-of-send_file_wri.patch @@ -0,0 +1,108 @@ +From e5d1521137dd824b53531299118197eced338673 Mon Sep 17 00:00:00 2001 +From: Laszlo Ersek +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 +Message-Id: <20220502085601.15012-3-lersek@redhat.com> +Reviewed-by: Richard W.M. Jones +(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 + diff --git a/0004-lib-launch-direct-ignore-drive-iface-parameter.patch b/0004-lib-launch-direct-ignore-drive-iface-parameter.patch new file mode 100644 index 0000000..3615b67 --- /dev/null +++ b/0004-lib-launch-direct-ignore-drive-iface-parameter.patch @@ -0,0 +1,123 @@ +From fd9a584f39b6fdab3588715597bdd2d7677f70e9 Mon Sep 17 00:00:00 2001 +From: Laszlo Ersek +Date: Wed, 4 May 2022 15:41:52 +0200 +Subject: [PATCH] lib: launch-direct: ignore drive "iface" parameter + +Rich said in : + +> 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 +Message-Id: <20220504134155.11832-2-lersek@redhat.com> +Reviewed-by: Richard W.M. Jones +(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." }; + shortdesc = "add a drive specifying the QEMU block emulation to use"; + longdesc = "\ + This is the same as C 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 argument. ++The direct backend ignores C." }; + + { 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 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 argument. ++The direct backend ignores C." }; + + { defaults with + name = "lstatlist"; added = (1, 0, 77); +diff --git a/lib/launch-direct.c b/lib/launch-direct.c +index 5c91822fb..c07a8d78f 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 + diff --git a/0005-lib-drive_create_data-drive-remove-field-iface.patch b/0005-lib-drive_create_data-drive-remove-field-iface.patch new file mode 100644 index 0000000..4b2134a --- /dev/null +++ b/0005-lib-drive_create_data-drive-remove-field-iface.patch @@ -0,0 +1,245 @@ +From cb6b7ce718cb33567a06746208dc4d4e7cab8be6 Mon Sep 17 00:00:00 2001 +From: Laszlo Ersek +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 +Message-Id: <20220504134155.11832-3-lersek@redhat.com> +Reviewed-by: Richard W.M. Jones +(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." }; + longdesc = "\ + This is the same as C but it allows you + to specify the QEMU interface emulation to use at run time. +-The libvirt backend rejects a non-empty C argument. +-The direct backend ignores C." }; ++Both the direct and the libvirt backends ignore C." }; + + { defaults with + name = "add_drive_ro_with_if"; added = (1, 0, 84); +@@ -86,8 +85,7 @@ The direct backend ignores C." }; + longdesc = "\ + This is the same as C but it allows you + to specify the QEMU interface emulation to use at run time. +-The libvirt backend rejects a non-empty C argument. +-The direct backend ignores C." }; ++Both the direct and the libvirt backends ignore C." }; + + { 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 44764f3cc..87da2f40e 100644 +--- a/lib/launch-libvirt.c ++++ b/lib/launch-libvirt.c +@@ -1465,12 +1465,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 + diff --git a/0006-lib-rename-VALID_FORMAT_IFACE-to-VALID_FORMAT.patch b/0006-lib-rename-VALID_FORMAT_IFACE-to-VALID_FORMAT.patch new file mode 100644 index 0000000..e1e5dff --- /dev/null +++ b/0006-lib-rename-VALID_FORMAT_IFACE-to-VALID_FORMAT.patch @@ -0,0 +1,82 @@ +From 1eba1113850c4e5b6b6f89d26bd11d8685b25a26 Mon Sep 17 00:00:00 2001 +From: Laszlo Ersek +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 +Message-Id: <20220504134155.11832-4-lersek@redhat.com> +Reviewed-by: Richard W.M. Jones +(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 + diff --git a/0007-tests-regressions-remove-iface-based-restrictions.patch b/0007-tests-regressions-remove-iface-based-restrictions.patch new file mode 100644 index 0000000..7c6bbb2 --- /dev/null +++ b/0007-tests-regressions-remove-iface-based-restrictions.patch @@ -0,0 +1,74 @@ +From b436e306ecf93450651e023763bda3fd954e428e Mon Sep 17 00:00:00 2001 +From: Laszlo Ersek +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 +Message-Id: <20220504134155.11832-5-lersek@redhat.com> +Reviewed-by: Richard W.M. Jones +(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 + diff --git a/0008-generator-customize-invert-SELinux-relabeling-defaul.patch b/0008-generator-customize-invert-SELinux-relabeling-defaul.patch new file mode 100644 index 0000000..04f2ec7 --- /dev/null +++ b/0008-generator-customize-invert-SELinux-relabeling-defaul.patch @@ -0,0 +1,56 @@ +From 16043bb219a5fb4e121550513779af074f2ce0ca Mon Sep 17 00:00:00 2001 +From: Laszlo Ersek +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 +Message-Id: <20220510102757.14466-3-lersek@redhat.com> +Acked-by: Richard W.M. Jones +(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 (Fedora, RHEL) or + C (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 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 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 + diff --git a/0009-update-common-submodule.patch b/0009-update-common-submodule.patch new file mode 100644 index 0000000..e93575f --- /dev/null +++ b/0009-update-common-submodule.patch @@ -0,0 +1,46 @@ +From 6a2a4adfefd9c80884c6a5a565d2d781ba7227fb Mon Sep 17 00:00:00 2001 +From: Laszlo Ersek +Date: Wed, 11 May 2022 05:26:48 +0200 +Subject: [PATCH] update common submodule + +Laszlo Ersek (2): + mlcustomize: refresh generated files + remove non-generated "--selinux-relabel" options + +Richard W.M. Jones (2): + options/uri.c: Fix missing word in error message + options/uri.c: Free variable on error path + +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 +(cherry picked from commit 08c4ac90f5a3c08b48444e2faf3d0f58d6ddc206) +--- + common | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +Submodule common 0a231b3e6..48527b876: +diff --git a/common/options/uri.c b/common/options/uri.c +index 6b696fc2d..84d393c1e 100644 +--- a/common/options/uri.c ++++ b/common/options/uri.c +@@ -135,7 +135,7 @@ parse (const char *arg, char **path_ret, char **protocol_ret, + socket = query_get (uri, "socket"); + + if (uri->server && STRNEQ (uri->server, "") && socket) { +- fprintf (stderr, _("%s: %s: cannot both a server name and a socket query parameter\n"), ++ fprintf (stderr, _("%s: %s: cannot have both a server name and a socket query parameter\n"), + getprogname (), arg); + return -1; + } +@@ -347,6 +347,7 @@ make_server (xmlURIPtr uri, const char *socket, char ***ret) + *ret = malloc (sizeof (char *) * 2); + if (*ret == NULL) { + perror ("malloc"); ++ free (server); + return -1; + } + (*ret)[0] = server; +-- +2.31.1 + diff --git a/0001-RHEL-Disable-unsupported-remote-drive-protocols-RHBZ.patch b/0010-RHEL-Disable-unsupported-remote-drive-protocols-RHBZ.patch similarity index 95% rename from 0001-RHEL-Disable-unsupported-remote-drive-protocols-RHBZ.patch rename to 0010-RHEL-Disable-unsupported-remote-drive-protocols-RHBZ.patch index 7d24840..104886d 100644 --- a/0001-RHEL-Disable-unsupported-remote-drive-protocols-RHBZ.patch +++ b/0010-RHEL-Disable-unsupported-remote-drive-protocols-RHBZ.patch @@ -1,4 +1,4 @@ -From ca7663dd28d0e95bc5bf8f468dc7823033c26328 Mon Sep 17 00:00:00 2001 +From fc738cbe77b4f058c3d3367512cb64aeb0248a98 Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Mon, 29 Jul 2013 14:47:56 +0100 Subject: [PATCH] RHEL: Disable unsupported remote drive protocols @@ -220,10 +220,10 @@ index 21d424984..ddabeb639 100755 rm test-add-uri.out rm test-add-uri.img diff --git a/generator/actions_core.ml b/generator/actions_core.ml -index e757140aa..e3d098deb 100644 +index 807150615..6cd42a290 100644 --- a/generator/actions_core.ml +++ b/generator/actions_core.ml -@@ -291,29 +291,6 @@ F is interpreted as a local file or device. +@@ -350,29 +350,6 @@ F is interpreted as a local file or device. This is the default if the optional protocol parameter is omitted. @@ -253,7 +253,7 @@ index e757140aa..e3d098deb 100644 =item C Connect to the Network Block Device server. -@@ -330,22 +307,6 @@ The C parameter may be supplied. See below. +@@ -389,22 +366,6 @@ The C parameter may be supplied. See below. See also: L. @@ -276,7 +276,7 @@ index e757140aa..e3d098deb 100644 =back =item C -@@ -356,13 +317,8 @@ is a list of server(s). +@@ -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 @@ -290,7 +290,7 @@ index e757140aa..e3d098deb 100644 Each list element is a string specifying a server. The string must be in one of the following formats: -@@ -378,10 +334,10 @@ for the protocol is used (see F). +@@ -437,10 +393,10 @@ for the protocol is used (see F). =item C @@ -305,10 +305,10 @@ index e757140aa..e3d098deb 100644 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. If in doubt, diff --git a/lib/drives.c b/lib/drives.c -index fd95308d2..dfea88af4 100644 +index c5a208468..efb289254 100644 --- a/lib/drives.c +++ b/lib/drives.c -@@ -168,6 +168,7 @@ create_drive_non_file (guestfs_h *g, +@@ -166,6 +166,7 @@ create_drive_non_file (guestfs_h *g, return drv; } @@ -316,7 +316,7 @@ index fd95308d2..dfea88af4 100644 static struct drive * create_drive_curl (guestfs_h *g, const struct drive_create_data *data) -@@ -226,6 +227,7 @@ create_drive_gluster (guestfs_h *g, +@@ -224,6 +225,7 @@ create_drive_gluster (guestfs_h *g, return create_drive_non_file (g, data); } @@ -324,7 +324,7 @@ index fd95308d2..dfea88af4 100644 static int nbd_port (void) -@@ -294,6 +296,7 @@ create_drive_rbd (guestfs_h *g, +@@ -292,6 +294,7 @@ create_drive_rbd (guestfs_h *g, return create_drive_non_file (g, data); } @@ -332,7 +332,7 @@ index fd95308d2..dfea88af4 100644 static struct drive * create_drive_sheepdog (guestfs_h *g, const struct drive_create_data *data) -@@ -394,6 +397,7 @@ create_drive_iscsi (guestfs_h *g, +@@ -392,6 +395,7 @@ create_drive_iscsi (guestfs_h *g, return create_drive_non_file (g, data); } @@ -340,7 +340,7 @@ index fd95308d2..dfea88af4 100644 /** * Create the special F drive. -@@ -855,6 +859,7 @@ guestfs_impl_add_drive_opts (guestfs_h *g, const char *filename, +@@ -842,6 +846,7 @@ guestfs_impl_add_drive_opts (guestfs_h *g, const char *filename, drv = create_drive_file (g, &data); } } @@ -348,7 +348,7 @@ index fd95308d2..dfea88af4 100644 else if (STREQ (protocol, "ftp")) { data.protocol = drive_protocol_ftp; drv = create_drive_curl (g, &data); -@@ -879,6 +884,7 @@ guestfs_impl_add_drive_opts (guestfs_h *g, const char *filename, +@@ -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); } @@ -356,7 +356,7 @@ index fd95308d2..dfea88af4 100644 else if (STREQ (protocol, "nbd")) { data.protocol = drive_protocol_nbd; drv = create_drive_nbd (g, &data); -@@ -887,6 +893,7 @@ guestfs_impl_add_drive_opts (guestfs_h *g, const char *filename, +@@ -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); } @@ -364,7 +364,7 @@ index fd95308d2..dfea88af4 100644 else if (STREQ (protocol, "sheepdog")) { data.protocol = drive_protocol_sheepdog; drv = create_drive_sheepdog (g, &data); -@@ -899,6 +906,7 @@ guestfs_impl_add_drive_opts (guestfs_h *g, const char *filename, +@@ -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); } diff --git a/0002-RHEL-Reject-use-of-libguestfs-winsupport-features-ex.patch b/0011-RHEL-Reject-use-of-libguestfs-winsupport-features-ex.patch similarity index 97% rename from 0002-RHEL-Reject-use-of-libguestfs-winsupport-features-ex.patch rename to 0011-RHEL-Reject-use-of-libguestfs-winsupport-features-ex.patch index 8064cec..d5dd69d 100644 --- a/0002-RHEL-Reject-use-of-libguestfs-winsupport-features-ex.patch +++ b/0011-RHEL-Reject-use-of-libguestfs-winsupport-features-ex.patch @@ -1,4 +1,4 @@ -From dda9d8a5df1a2bf1c187c96c60c4da06c7c3e24a Mon Sep 17 00:00:00 2001 +From a026536353871472bddfb6e39c13149e09243b8c Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Tue, 7 Jul 2015 09:28:03 -0400 Subject: [PATCH] RHEL: Reject use of libguestfs-winsupport features except for diff --git a/0003-RHEL-Create-etc-crypto-policies-back-ends-opensslcnf.patch b/0012-RHEL-Create-etc-crypto-policies-back-ends-opensslcnf.patch similarity index 94% rename from 0003-RHEL-Create-etc-crypto-policies-back-ends-opensslcnf.patch rename to 0012-RHEL-Create-etc-crypto-policies-back-ends-opensslcnf.patch index c2b8ba8..463d4b0 100644 --- a/0003-RHEL-Create-etc-crypto-policies-back-ends-opensslcnf.patch +++ b/0012-RHEL-Create-etc-crypto-policies-back-ends-opensslcnf.patch @@ -1,4 +1,4 @@ -From cf6c2cf52bbfb8ee8c300d79212e9a75931392d8 Mon Sep 17 00:00:00 2001 +From 4ce969732bb8424237e26c5dd3b56507025aae82 Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Tue, 29 Jun 2021 15:29:11 +0100 Subject: [PATCH] RHEL: Create /etc/crypto-policies/back-ends/opensslcnf.config diff --git a/libguestfs.spec b/libguestfs.spec index 434f88e..af4388a 100644 --- a/libguestfs.spec +++ b/libguestfs.spec @@ -47,7 +47,7 @@ Summary: Access and modify virtual machine disk images Name: libguestfs Epoch: 1 -Version: 1.48.1 +Version: 1.48.2 Release: 1%{?dist} License: LGPLv2+ @@ -86,9 +86,21 @@ Source8: copy-patches.sh # https://github.com/libguestfs/libguestfs/commits/rhel-9.1 # Patches. -Patch0001: 0001-RHEL-Disable-unsupported-remote-drive-protocols-RHBZ.patch -Patch0002: 0002-RHEL-Reject-use-of-libguestfs-winsupport-features-ex.patch -Patch0003: 0003-RHEL-Create-etc-crypto-policies-back-ends-opensslcnf.patch +Patch0001: 0001-New-API-guestfs_device_name-returning-the-drive-name.patch +Patch0002: 0002-guestfs_readdir-rewrite-with-FileOut-transfer-to-lif.patch +Patch0003: 0003-guestfs_readdir-minimize-the-number-of-send_file_wri.patch +Patch0004: 0004-lib-launch-direct-ignore-drive-iface-parameter.patch +Patch0005: 0005-lib-drive_create_data-drive-remove-field-iface.patch +Patch0006: 0006-lib-rename-VALID_FORMAT_IFACE-to-VALID_FORMAT.patch +Patch0007: 0007-tests-regressions-remove-iface-based-restrictions.patch +Patch0008: 0008-generator-customize-invert-SELinux-relabeling-defaul.patch + # *NB* I modified this patch by hand to remove references to any + # files in common/mlcustomize. This directory is not included + # in the libguestfs tarball. +Patch0009: 0009-update-common-submodule.patch +Patch0010: 0010-RHEL-Disable-unsupported-remote-drive-protocols-RHBZ.patch +Patch0011: 0011-RHEL-Reject-use-of-libguestfs-winsupport-features-ex.patch +Patch0012: 0012-RHEL-Create-etc-crypto-policies-back-ends-opensslcnf.patch %if 0%{patches_touch_autotools} BuildRequires: autoconf, automake, libtool, gettext-devel @@ -1131,9 +1143,17 @@ rm ocaml/html/.gitignore %changelog -* Thu Apr 14 2022 Richard W.M. Jones - 1:1.48.1-1 -- Rebase to new stable branch version 1.48.1 +* Thu May 12 2022 Richard W.M. Jones - 1:1.48.2-1 +- Rebase to new stable branch version 1.48.2 resolves: rhbz#2059285 +- Disable 5-level page tables when using -cpu max + resolves: rhbz#2084568 +- SELinux relabelling should not stop on ext4 immutable bits + resolves: rhbz#1794518 +- Ignore "iface" in add-drive variants + resolves: rhbz#1844341 +- Lift protocol limit on guestfs_readdir() + resolves: rhbz#1674392 * Thu Mar 17 2022 Richard W.M. Jones - 1:1.48.0-2 - Disable signature checking in librpm diff --git a/sources b/sources index 6f7bd92..c7103a7 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (libguestfs-1.48.1.tar.gz) = 34cad3cb9ebfe2d6294fda8eede873470d75aad2eadc5b245556122a3e09b5d51fc012c0144997b66070feb97fe9613f0f9328a973c30839dae74f446a4a4b3c -SHA512 (libguestfs-1.48.1.tar.gz.sig) = 2addd2767237cc5e00031b68d50d50e0ac6f1da570aefd6e2bba76e919d10f3648802b113bfe99efe9e8c336e96bf6e6e179731d686b09cb5f4bf29f4790ffc0 +SHA512 (libguestfs-1.48.2.tar.gz) = 3cbec961fbed3bfdb2ba6ab240756ffd61fed76be1e754b0286a87e298ba95dae6d7435aa5f5cff84dd2f42aa7576a2f197df83f987f0e44ed4d268f76be5e19 +SHA512 (libguestfs-1.48.2.tar.gz.sig) = 1554d1a911c06fb59cea2e56b845272d1e33056e36b74f9e6507d5cff433340ba3e90b8957dbd706f0f2ea32e45d1dc11f394212a314c5b954677faa66c4c8de