Compare commits
	
		
			No commits in common. "a9" and "c8-stream-rhel" have entirely different histories.
		
	
	
		
			a9
			...
			c8-stream-
		
	
		
							
								
								
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -1,3 +1,2 @@ | |||||||
| SOURCES/libguestfs-1.54.0.tar.gz | SOURCES/libguestfs-1.44.0.tar.gz | ||||||
| SOURCES/libguestfs.keyring | SOURCES/libguestfs.keyring | ||||||
| SOURCES/libguestfs-common-1.50.2.tar.gz |  | ||||||
|  | |||||||
| @ -1,3 +1,2 @@ | |||||||
| 219ca9ffccfb7c6377f50343aeef1b955bbf1961 SOURCES/libguestfs-1.54.0.tar.gz | 99d241dc4a5ba0dc6111954ed7a872e0b0bb6944 SOURCES/libguestfs-1.44.0.tar.gz | ||||||
| 1bbc40f501a7fef9eef2a39b701a71aee2fea7c4 SOURCES/libguestfs.keyring | 1bbc40f501a7fef9eef2a39b701a71aee2fea7c4 SOURCES/libguestfs.keyring | ||||||
| f801826d11e360a906bae5980495ac5425d709ae SOURCES/libguestfs-common-1.50.2.tar.gz |  | ||||||
|  | |||||||
							
								
								
									
										56
									
								
								SOURCES/0001-RHEL-8-Remove-libguestfs-live-RHBZ-798980.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								SOURCES/0001-RHEL-8-Remove-libguestfs-live-RHBZ-798980.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,56 @@ | |||||||
|  | From 5b6d2b05fe0c4035b9791a751e3133d26c7baa2d Mon Sep 17 00:00:00 2001 | ||||||
|  | From: "Richard W.M. Jones" <rjones@redhat.com> | ||||||
|  | Date: Fri, 21 Dec 2012 15:50:11 +0000 | ||||||
|  | Subject: [PATCH] RHEL 8: Remove libguestfs live (RHBZ#798980). | ||||||
|  | 
 | ||||||
|  | This isn't supported in RHEL 8. | ||||||
|  | 
 | ||||||
|  | Disable daemon tests that require the 'unix' backend. | ||||||
|  | ---
 | ||||||
|  |  lib/launch-unix.c        | 7 +++++++ | ||||||
|  |  tests/daemon/Makefile.am | 4 +--- | ||||||
|  |  2 files changed, 8 insertions(+), 3 deletions(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/lib/launch-unix.c b/lib/launch-unix.c
 | ||||||
|  | index 0d344f9df..74dd1bb4a 100644
 | ||||||
|  | --- a/lib/launch-unix.c
 | ||||||
|  | +++ b/lib/launch-unix.c
 | ||||||
|  | @@ -37,6 +37,12 @@
 | ||||||
|  |  static int | ||||||
|  |  launch_unix (guestfs_h *g, void *datav, const char *sockpath) | ||||||
|  |  { | ||||||
|  | +  error (g,
 | ||||||
|  | +	 "launch: In RHEL, only the 'libvirt' or 'direct' method is supported.\n"
 | ||||||
|  | +	 "In particular, \"libguestfs live\" is not supported.");
 | ||||||
|  | +  return -1;
 | ||||||
|  | +
 | ||||||
|  | +#if 0
 | ||||||
|  |    int r, daemon_sock = -1; | ||||||
|  |    struct sockaddr_un addr; | ||||||
|  |    uint32_t size; | ||||||
|  | @@ -106,6 +112,7 @@ launch_unix (guestfs_h *g, void *datav, const char *sockpath)
 | ||||||
|  |      g->conn = NULL; | ||||||
|  |    } | ||||||
|  |    return -1; | ||||||
|  | +#endif
 | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  static int | ||||||
|  | diff --git a/tests/daemon/Makefile.am b/tests/daemon/Makefile.am
 | ||||||
|  | index 921e6d1df..8b2887247 100644
 | ||||||
|  | --- a/tests/daemon/Makefile.am
 | ||||||
|  | +++ b/tests/daemon/Makefile.am
 | ||||||
|  | @@ -23,9 +23,7 @@ include $(top_srcdir)/subdir-rules.mk
 | ||||||
|  |   | ||||||
|  |  check_DATA = captive-daemon.pm | ||||||
|  |   | ||||||
|  | -TESTS = \
 | ||||||
|  | -	test-daemon-start.pl \
 | ||||||
|  | -	test-btrfs.pl
 | ||||||
|  | +TESTS =
 | ||||||
|  |   | ||||||
|  |  TESTS_ENVIRONMENT = $(top_builddir)/run --test | ||||||
|  |   | ||||||
|  | -- 
 | ||||||
|  | 2.31.1 | ||||||
|  | 
 | ||||||
| @ -1,25 +0,0 @@ | |||||||
| From 0edaea8f91bf08025651eeff32f53b9335003842 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: "Richard W.M. Jones" <rjones@redhat.com> |  | ||||||
| Date: Tue, 8 Oct 2024 14:53:38 +0100 |  | ||||||
| Subject: [PATCH] website: Add links for 1.54 and 1.55 download locations |  | ||||||
| 
 |  | ||||||
| ---
 |  | ||||||
|  website/index.html.in | 3 ++- |  | ||||||
|  1 file changed, 2 insertions(+), 1 deletion(-) |  | ||||||
| 
 |  | ||||||
| diff --git a/website/index.html.in b/website/index.html.in
 |  | ||||||
| index a61fca92..2a0d3221 100644
 |  | ||||||
| --- a/website/index.html.in
 |  | ||||||
| +++ b/website/index.html.in
 |  | ||||||
| @@ -186,9 +186,10 @@ git clone <a href="https://github.com/libguestfs/libguestfs">https://github.com/
 |  | ||||||
|  LATEST-URL: http://libguestfs.org/download/1.53-development/libguestfs-@PACKAGE_VERSION@.tar.gz |  | ||||||
|  LATEST-VERSION: @PACKAGE_VERSION@ |  | ||||||
|    --> |  | ||||||
| -  <a href="download/1.53-development/">Latest development version: <strong>@PACKAGE_VERSION@</strong></a> (released <strong>@RELEASE_DATE@</strong>).<br/>
 |  | ||||||
| +  <a href="download/1.55-development/">Latest development version: <strong>@PACKAGE_VERSION@</strong></a> (released <strong>@RELEASE_DATE@</strong>).<br/>
 |  | ||||||
|    Stable branch: |  | ||||||
|    <strong> |  | ||||||
| +  <a href="download/1.54-stable/">1.54.x</a>,
 |  | ||||||
|    <a href="download/1.52-stable/">1.52.x</a>, |  | ||||||
|    <a href="download/1.50-stable/">1.50.x</a>, |  | ||||||
|    <a href="download/1.48-stable/">1.48.x</a> |  | ||||||
							
								
								
									
										330
									
								
								SOURCES/0002-RHEL-8-Remove-9p-APIs-from-RHEL-RHBZ-921710.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										330
									
								
								SOURCES/0002-RHEL-8-Remove-9p-APIs-from-RHEL-RHBZ-921710.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,330 @@ | |||||||
|  | From 91b2a6e50211c58ea31a36351ec63c358f708bf9 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: "Richard W.M. Jones" <rjones@redhat.com> | ||||||
|  | Date: Thu, 18 Jul 2013 18:31:53 +0100 | ||||||
|  | Subject: [PATCH] RHEL 8: Remove 9p APIs from RHEL (RHBZ#921710). | ||||||
|  | 
 | ||||||
|  | ---
 | ||||||
|  |  Makefile.am               |   2 +- | ||||||
|  |  daemon/9p.c               | 182 -------------------------------------- | ||||||
|  |  daemon/Makefile.am        |   1 - | ||||||
|  |  docs/C_SOURCE_FILES       |   1 - | ||||||
|  |  generator/actions_core.ml |  21 ----- | ||||||
|  |  generator/proc_nr.ml      |   2 - | ||||||
|  |  gobject/Makefile.inc      |   2 - | ||||||
|  |  po/POTFILES               |   2 - | ||||||
|  |  8 files changed, 1 insertion(+), 212 deletions(-) | ||||||
|  |  delete mode 100644 daemon/9p.c | ||||||
|  | 
 | ||||||
|  | diff --git a/Makefile.am b/Makefile.am
 | ||||||
|  | index 3df1b6a7a..36e44dfd5 100644
 | ||||||
|  | --- a/Makefile.am
 | ||||||
|  | +++ b/Makefile.am
 | ||||||
|  | @@ -78,7 +78,7 @@ SUBDIRS += tests/xfs
 | ||||||
|  |  SUBDIRS += tests/charsets | ||||||
|  |  SUBDIRS += tests/xml | ||||||
|  |  SUBDIRS += tests/mount-local | ||||||
|  | -SUBDIRS += tests/9p
 | ||||||
|  | +#SUBDIRS += tests/9p
 | ||||||
|  |  SUBDIRS += tests/rsync | ||||||
|  |  SUBDIRS += tests/bigdirs | ||||||
|  |  SUBDIRS += tests/disk-labels | ||||||
|  | diff --git a/daemon/9p.c b/daemon/9p.c
 | ||||||
|  | deleted file mode 100644 | ||||||
|  | index 743a96abd..000000000
 | ||||||
|  | --- a/daemon/9p.c
 | ||||||
|  | +++ /dev/null
 | ||||||
|  | @@ -1,182 +0,0 @@
 | ||||||
|  | -/* libguestfs - the guestfsd daemon
 | ||||||
|  | - * Copyright (C) 2011 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 <stdio.h>
 | ||||||
|  | -#include <stdlib.h>
 | ||||||
|  | -#include <string.h>
 | ||||||
|  | -#include <unistd.h>
 | ||||||
|  | -#include <limits.h>
 | ||||||
|  | -#include <errno.h>
 | ||||||
|  | -#include <sys/types.h>
 | ||||||
|  | -#include <sys/stat.h>
 | ||||||
|  | -#include <dirent.h>
 | ||||||
|  | -#include <fcntl.h>
 | ||||||
|  | -
 | ||||||
|  | -#include "ignore-value.h"
 | ||||||
|  | -
 | ||||||
|  | -#include "daemon.h"
 | ||||||
|  | -#include "actions.h"
 | ||||||
|  | -
 | ||||||
|  | -#define BUS_PATH "/sys/bus/virtio/drivers/9pnet_virtio"
 | ||||||
|  | -
 | ||||||
|  | -static void
 | ||||||
|  | -modprobe_9pnet_virtio (void)
 | ||||||
|  | -{
 | ||||||
|  | -  /* Required with Linux 5.6 and maybe earlier kernels.  For unclear
 | ||||||
|  | -   * reasons the module is not an automatic dependency of the 9p
 | ||||||
|  | -   * module so doesn't get loaded automatically.
 | ||||||
|  | -   */
 | ||||||
|  | -  ignore_value (command (NULL, NULL, "modprobe", "9pnet_virtio", NULL));
 | ||||||
|  | -}
 | ||||||
|  | -
 | ||||||
|  | -/* https://bugzilla.redhat.com/show_bug.cgi?id=714981#c1 */
 | ||||||
|  | -char **
 | ||||||
|  | -do_list_9p (void)
 | ||||||
|  | -{
 | ||||||
|  | -  CLEANUP_FREE_STRINGSBUF DECLARE_STRINGSBUF (r);
 | ||||||
|  | -  DIR *dir;
 | ||||||
|  | -
 | ||||||
|  | -  modprobe_9pnet_virtio ();
 | ||||||
|  | -
 | ||||||
|  | -  dir = opendir (BUS_PATH);
 | ||||||
|  | -  if (!dir) {
 | ||||||
|  | -    perror ("opendir: " BUS_PATH);
 | ||||||
|  | -    if (errno != ENOENT) {
 | ||||||
|  | -      reply_with_perror ("opendir: " BUS_PATH);
 | ||||||
|  | -      return NULL;
 | ||||||
|  | -    }
 | ||||||
|  | -
 | ||||||
|  | -    /* If this directory doesn't exist, it probably means that
 | ||||||
|  | -     * the virtio driver isn't loaded.  Don't return an error
 | ||||||
|  | -     * in this case, but return an empty list.
 | ||||||
|  | -     */
 | ||||||
|  | -    if (end_stringsbuf (&r) == -1)
 | ||||||
|  | -      return NULL;
 | ||||||
|  | -
 | ||||||
|  | -    return take_stringsbuf (&r);
 | ||||||
|  | -  }
 | ||||||
|  | -
 | ||||||
|  | -  while (1) {
 | ||||||
|  | -    struct dirent *d;
 | ||||||
|  | -
 | ||||||
|  | -    errno = 0;
 | ||||||
|  | -    d = readdir (dir);
 | ||||||
|  | -    if (d == NULL) break;
 | ||||||
|  | -
 | ||||||
|  | -    if (STRPREFIX (d->d_name, "virtio")) {
 | ||||||
|  | -      CLEANUP_FREE char *mount_tag_path = NULL;
 | ||||||
|  | -      if (asprintf (&mount_tag_path, BUS_PATH "/%s/mount_tag",
 | ||||||
|  | -                    d->d_name) == -1) {
 | ||||||
|  | -        reply_with_perror ("asprintf");
 | ||||||
|  | -        closedir (dir);
 | ||||||
|  | -        return NULL;
 | ||||||
|  | -      }
 | ||||||
|  | -
 | ||||||
|  | -      /* A bit unclear, but it looks like the virtio transport allows
 | ||||||
|  | -       * the mount tag length to be unlimited (or up to 65536 bytes).
 | ||||||
|  | -       * See: linux/include/linux/virtio_9p.h
 | ||||||
|  | -       */
 | ||||||
|  | -      CLEANUP_FREE char *mount_tag = read_whole_file (mount_tag_path, NULL);
 | ||||||
|  | -      if (mount_tag == 0)
 | ||||||
|  | -        continue;
 | ||||||
|  | -
 | ||||||
|  | -      if (add_string (&r, mount_tag) == -1) {
 | ||||||
|  | -        closedir (dir);
 | ||||||
|  | -        return NULL;
 | ||||||
|  | -      }
 | ||||||
|  | -    }
 | ||||||
|  | -  }
 | ||||||
|  | -
 | ||||||
|  | -  /* Check readdir didn't fail */
 | ||||||
|  | -  if (errno != 0) {
 | ||||||
|  | -    reply_with_perror ("readdir: /sys/block");
 | ||||||
|  | -    closedir (dir);
 | ||||||
|  | -    return NULL;
 | ||||||
|  | -  }
 | ||||||
|  | -
 | ||||||
|  | -  /* Close the directory handle */
 | ||||||
|  | -  if (closedir (dir) == -1) {
 | ||||||
|  | -    reply_with_perror ("closedir: /sys/block");
 | ||||||
|  | -    return NULL;
 | ||||||
|  | -  }
 | ||||||
|  | -
 | ||||||
|  | -  /* Sort the tags. */
 | ||||||
|  | -  if (r.size > 0)
 | ||||||
|  | -    sort_strings (r.argv, r.size);
 | ||||||
|  | -
 | ||||||
|  | -  /* NULL terminate the list */
 | ||||||
|  | -  if (end_stringsbuf (&r) == -1)
 | ||||||
|  | -    return NULL;
 | ||||||
|  | -
 | ||||||
|  | -  return take_stringsbuf (&r);
 | ||||||
|  | -}
 | ||||||
|  | -
 | ||||||
|  | -/* Takes optional arguments, consult optargs_bitmask. */
 | ||||||
|  | -int
 | ||||||
|  | -do_mount_9p (const char *mount_tag, const char *mountpoint, const char *options)
 | ||||||
|  | -{
 | ||||||
|  | -  CLEANUP_FREE char *mp = NULL, *opts = NULL, *err = NULL;
 | ||||||
|  | -  struct stat statbuf;
 | ||||||
|  | -  int r;
 | ||||||
|  | -
 | ||||||
|  | -  ABS_PATH (mountpoint, 0, return -1);
 | ||||||
|  | -
 | ||||||
|  | -  mp = sysroot_path (mountpoint);
 | ||||||
|  | -  if (!mp) {
 | ||||||
|  | -    reply_with_perror ("malloc");
 | ||||||
|  | -    return -1;
 | ||||||
|  | -  }
 | ||||||
|  | -
 | ||||||
|  | -  /* Check the mountpoint exists and is a directory. */
 | ||||||
|  | -  if (stat (mp, &statbuf) == -1) {
 | ||||||
|  | -    reply_with_perror ("%s", mountpoint);
 | ||||||
|  | -    return -1;
 | ||||||
|  | -  }
 | ||||||
|  | -  if (!S_ISDIR (statbuf.st_mode)) {
 | ||||||
|  | -    reply_with_perror ("%s: mount point is not a directory", mountpoint);
 | ||||||
|  | -    return -1;
 | ||||||
|  | -  }
 | ||||||
|  | -
 | ||||||
|  | -  /* Add trans=virtio to the options. */
 | ||||||
|  | -  if ((optargs_bitmask & GUESTFS_MOUNT_9P_OPTIONS_BITMASK) &&
 | ||||||
|  | -      STRNEQ (options, "")) {
 | ||||||
|  | -    if (asprintf (&opts, "trans=virtio,%s", options) == -1) {
 | ||||||
|  | -      reply_with_perror ("asprintf");
 | ||||||
|  | -      return -1;
 | ||||||
|  | -    }
 | ||||||
|  | -  }
 | ||||||
|  | -  else {
 | ||||||
|  | -    opts = strdup ("trans=virtio");
 | ||||||
|  | -    if (opts == NULL) {
 | ||||||
|  | -      reply_with_perror ("strdup");
 | ||||||
|  | -      return -1;
 | ||||||
|  | -    }
 | ||||||
|  | -  }
 | ||||||
|  | -
 | ||||||
|  | -  modprobe_9pnet_virtio ();
 | ||||||
|  | -  r = command (NULL, &err,
 | ||||||
|  | -               "mount", "-o", opts, "-t", "9p", mount_tag, mp, NULL);
 | ||||||
|  | -  if (r == -1) {
 | ||||||
|  | -    reply_with_error ("%s on %s: %s", mount_tag, mountpoint, err);
 | ||||||
|  | -    return -1;
 | ||||||
|  | -  }
 | ||||||
|  | -
 | ||||||
|  | -  return 0;
 | ||||||
|  | -}
 | ||||||
|  | diff --git a/daemon/Makefile.am b/daemon/Makefile.am
 | ||||||
|  | index 038be592c..df9dcc4ee 100644
 | ||||||
|  | --- a/daemon/Makefile.am
 | ||||||
|  | +++ b/daemon/Makefile.am
 | ||||||
|  | @@ -82,7 +82,6 @@ guestfsd_SOURCES = \
 | ||||||
|  |  	../common/protocol/guestfs_protocol.h \ | ||||||
|  |  	../common/utils/cleanups.h \ | ||||||
|  |  	../common/utils/guestfs-utils.h \ | ||||||
|  | -	9p.c \
 | ||||||
|  |  	acl.c \ | ||||||
|  |  	actions.h \ | ||||||
|  |  	available.c \ | ||||||
|  | diff --git a/docs/C_SOURCE_FILES b/docs/C_SOURCE_FILES
 | ||||||
|  | index cd5bd2924..831b7e25a 100644
 | ||||||
|  | --- a/docs/C_SOURCE_FILES
 | ||||||
|  | +++ b/docs/C_SOURCE_FILES
 | ||||||
|  | @@ -63,7 +63,6 @@ common/windows/windows.c
 | ||||||
|  |  common/windows/windows.h | ||||||
|  |  customize/crypt-c.c | ||||||
|  |  customize/perl_edit-c.c | ||||||
|  | -daemon/9p.c
 | ||||||
|  |  daemon/acl.c | ||||||
|  |  daemon/actions.h | ||||||
|  |  daemon/augeas.c | ||||||
|  | diff --git a/generator/actions_core.ml b/generator/actions_core.ml
 | ||||||
|  | index 806565b19..37476c93e 100644
 | ||||||
|  | --- a/generator/actions_core.ml
 | ||||||
|  | +++ b/generator/actions_core.ml
 | ||||||
|  | @@ -6157,27 +6157,6 @@ This returns true iff the device exists and contains all zero bytes.
 | ||||||
|  |   | ||||||
|  |  Note that for large devices this can take a long time to run." }; | ||||||
|  |   | ||||||
|  | -  { defaults with
 | ||||||
|  | -    name = "list_9p"; added = (1, 11, 12);
 | ||||||
|  | -    style = RStringList (RPlainString, "mounttags"), [], [];
 | ||||||
|  | -    shortdesc = "list 9p filesystems";
 | ||||||
|  | -    longdesc = "\
 | ||||||
|  | -List all 9p filesystems attached to the guest.  A list of
 | ||||||
|  | -mount tags is returned." };
 | ||||||
|  | -
 | ||||||
|  | -  { defaults with
 | ||||||
|  | -    name = "mount_9p"; added = (1, 11, 12);
 | ||||||
|  | -    style = RErr, [String (PlainString, "mounttag"); String (PlainString, "mountpoint")], [OString "options"];
 | ||||||
|  | -    camel_name = "Mount9P";
 | ||||||
|  | -    shortdesc = "mount 9p filesystem";
 | ||||||
|  | -    longdesc = "\
 | ||||||
|  | -Mount the virtio-9p filesystem with the tag C<mounttag> on the
 | ||||||
|  | -directory C<mountpoint>.
 | ||||||
|  | -
 | ||||||
|  | -If required, C<trans=virtio> will be automatically added to the options.
 | ||||||
|  | -Any other options required can be passed in the optional C<options>
 | ||||||
|  | -parameter." };
 | ||||||
|  | -
 | ||||||
|  |    { defaults with | ||||||
|  |      name = "list_dm_devices"; added = (1, 11, 15); | ||||||
|  |      style = RStringList (RDevice, "devices"), [], []; | ||||||
|  | diff --git a/generator/proc_nr.ml b/generator/proc_nr.ml
 | ||||||
|  | index 30e42864f..57976be36 100644
 | ||||||
|  | --- a/generator/proc_nr.ml
 | ||||||
|  | +++ b/generator/proc_nr.ml
 | ||||||
|  | @@ -295,8 +295,6 @@ let proc_nr = [
 | ||||||
|  |  282, "internal_autosync"; | ||||||
|  |  283, "is_zero"; | ||||||
|  |  284, "is_zero_device"; | ||||||
|  | -285, "list_9p";
 | ||||||
|  | -286, "mount_9p";
 | ||||||
|  |  287, "list_dm_devices"; | ||||||
|  |  288, "ntfsresize"; | ||||||
|  |  289, "btrfs_filesystem_resize"; | ||||||
|  | diff --git a/gobject/Makefile.inc b/gobject/Makefile.inc
 | ||||||
|  | index 650f8ddac..c4e735967 100644
 | ||||||
|  | --- a/gobject/Makefile.inc
 | ||||||
|  | +++ b/gobject/Makefile.inc
 | ||||||
|  | @@ -94,7 +94,6 @@ guestfs_gobject_headers= \
 | ||||||
|  |    include/guestfs-gobject/optargs-mksquashfs.h \ | ||||||
|  |    include/guestfs-gobject/optargs-mkswap.h \ | ||||||
|  |    include/guestfs-gobject/optargs-mktemp.h \ | ||||||
|  | -  include/guestfs-gobject/optargs-mount_9p.h \
 | ||||||
|  |    include/guestfs-gobject/optargs-mount_local.h \ | ||||||
|  |    include/guestfs-gobject/optargs-ntfsclone_out.h \ | ||||||
|  |    include/guestfs-gobject/optargs-ntfsfix.h \ | ||||||
|  | @@ -188,7 +187,6 @@ guestfs_gobject_sources= \
 | ||||||
|  |    src/optargs-mksquashfs.c \ | ||||||
|  |    src/optargs-mkswap.c \ | ||||||
|  |    src/optargs-mktemp.c \ | ||||||
|  | -  src/optargs-mount_9p.c \
 | ||||||
|  |    src/optargs-mount_local.c \ | ||||||
|  |    src/optargs-ntfsclone_out.c \ | ||||||
|  |    src/optargs-ntfsfix.c \ | ||||||
|  | diff --git a/po/POTFILES b/po/POTFILES
 | ||||||
|  | index 69ea7134a..0782e8ceb 100644
 | ||||||
|  | --- a/po/POTFILES
 | ||||||
|  | +++ b/po/POTFILES
 | ||||||
|  | @@ -47,7 +47,6 @@ common/visit/visit.c
 | ||||||
|  |  common/windows/windows.c | ||||||
|  |  customize/crypt-c.c | ||||||
|  |  customize/perl_edit-c.c | ||||||
|  | -daemon/9p.c
 | ||||||
|  |  daemon/acl.c | ||||||
|  |  daemon/augeas.c | ||||||
|  |  daemon/available.c | ||||||
|  | @@ -277,7 +276,6 @@ gobject/src/optargs-mkfs_btrfs.c
 | ||||||
|  |  gobject/src/optargs-mksquashfs.c | ||||||
|  |  gobject/src/optargs-mkswap.c | ||||||
|  |  gobject/src/optargs-mktemp.c | ||||||
|  | -gobject/src/optargs-mount_9p.c
 | ||||||
|  |  gobject/src/optargs-mount_local.c | ||||||
|  |  gobject/src/optargs-ntfsclone_out.c | ||||||
|  |  gobject/src/optargs-ntfsfix.c | ||||||
|  | -- 
 | ||||||
|  | 2.31.1 | ||||||
|  | 
 | ||||||
| @ -1,28 +0,0 @@ | |||||||
| From c25ff1a8022cf345d3ce29682207ed3732a4244a Mon Sep 17 00:00:00 2001 |  | ||||||
| From: "Richard W.M. Jones" <rjones@redhat.com> |  | ||||||
| Date: Mon, 14 Oct 2024 10:43:08 +0100 |  | ||||||
| Subject: [PATCH] tests/gdisk/test-expand-gpt.pl: Implement SKIP rule for this |  | ||||||
|  test |  | ||||||
| 
 |  | ||||||
| Reported-by: David Runge |  | ||||||
| Related: https://github.com/libguestfs/libguestfs/issues/155 |  | ||||||
| ---
 |  | ||||||
|  tests/gdisk/test-expand-gpt.pl | 5 +++++ |  | ||||||
|  1 file changed, 5 insertions(+) |  | ||||||
| 
 |  | ||||||
| diff --git a/tests/gdisk/test-expand-gpt.pl b/tests/gdisk/test-expand-gpt.pl
 |  | ||||||
| index 23a52b23..5c77247c 100755
 |  | ||||||
| --- a/tests/gdisk/test-expand-gpt.pl
 |  | ||||||
| +++ b/tests/gdisk/test-expand-gpt.pl
 |  | ||||||
| @@ -20,6 +20,11 @@ use warnings;
 |  | ||||||
|   |  | ||||||
|  use Sys::Guestfs; |  | ||||||
|   |  | ||||||
| +if ($ENV{SKIP_TEST_EXPAND_GPT_PL}) {
 |  | ||||||
| +    print "$0: test skipped because SKIP_TEST_EXPAND_GPT_PL is set\n";
 |  | ||||||
| +    exit 77;
 |  | ||||||
| +}
 |  | ||||||
| +
 |  | ||||||
|  sub tests { |  | ||||||
|  	my $g = Sys::Guestfs->new (); |  | ||||||
|   |  | ||||||
| @ -1,7 +1,7 @@ | |||||||
| From 1b6dd045a70a0d44631935f5c47f4a9b9e6a7ccc Mon Sep 17 00:00:00 2001 | From 4dd2f3f56a39411a255ad0a8f38081d46620dbd8 Mon Sep 17 00:00:00 2001 | ||||||
| From: "Richard W.M. Jones" <rjones@redhat.com> | From: "Richard W.M. Jones" <rjones@redhat.com> | ||||||
| Date: Mon, 29 Jul 2013 14:47:56 +0100 | Date: Mon, 29 Jul 2013 14:47:56 +0100 | ||||||
| Subject: [PATCH] RHEL: Disable unsupported remote drive protocols | Subject: [PATCH] RHEL 8: Disable unsupported remote drive protocols | ||||||
|  (RHBZ#962113). |  (RHBZ#962113). | ||||||
| 
 | 
 | ||||||
| This disables support for unsupported remote drive protocols: | This disables support for unsupported remote drive protocols: | ||||||
| @ -10,23 +10,28 @@ This disables support for unsupported remote drive protocols: | |||||||
|  * ftps |  * ftps | ||||||
|  * http |  * http | ||||||
|  * https |  * https | ||||||
|  |  * tftp | ||||||
|  |  * gluster | ||||||
|  * iscsi |  * iscsi | ||||||
|  |  * sheepdog | ||||||
|  * ssh |  * ssh | ||||||
| 
 | 
 | ||||||
| Note 'nbd' is not disabled, and of course 'file' works. | Note 'nbd' is not disabled, and of course 'file' works. | ||||||
|  | 
 | ||||||
|  | We hope to gradually add some of these back over the lifetime of RHEL 8. | ||||||
| ---
 | ---
 | ||||||
|  docs/guestfs-testing.pod               |  20 ----- |  docs/guestfs-testing.pod               |  20 ----- | ||||||
|  fish/guestfish.pod                     |  42 ++------- |  fish/guestfish.pod                     |  66 ++-------------- | ||||||
|  fish/test-add-uri.sh                   |  21 ----- |  fish/test-add-uri.sh                   |  32 -------- | ||||||
|  generator/actions_core.ml              |  34 +------- |  generator/actions_core.ml              |  50 +------------ | ||||||
|  lib/drives.c                           | 113 ------------------------- |  lib/drives.c                           |   8 ++ | ||||||
|  lib/guestfs.pod                        |  67 --------------- |  lib/guestfs.pod                        | 100 ------------------------- | ||||||
|  tests/disks/test-qemu-drive-libvirt.sh |   7 -- |  tests/disks/test-qemu-drive-libvirt.sh |  28 ------- | ||||||
|  tests/disks/test-qemu-drive.sh         |  40 --------- |  tests/disks/test-qemu-drive.sh         |  60 --------------- | ||||||
|  8 files changed, 8 insertions(+), 336 deletions(-) |  8 files changed, 16 insertions(+), 348 deletions(-) | ||||||
| 
 | 
 | ||||||
| diff --git a/docs/guestfs-testing.pod b/docs/guestfs-testing.pod
 | diff --git a/docs/guestfs-testing.pod b/docs/guestfs-testing.pod
 | ||||||
| index f5c09df6..ee4b26d6 100644
 | index f558964bf..8f264ed17 100644
 | ||||||
| --- a/docs/guestfs-testing.pod
 | --- a/docs/guestfs-testing.pod
 | ||||||
| +++ b/docs/guestfs-testing.pod
 | +++ b/docs/guestfs-testing.pod
 | ||||||
| @@ -109,26 +109,6 @@ image.  To exit, type C<exit>.
 | @@ -109,26 +109,6 @@ image.  To exit, type C<exit>.
 | ||||||
| @ -57,7 +62,7 @@ index f5c09df6..ee4b26d6 100644 | |||||||
|   |   | ||||||
|  Run L<virt-alignment-scan(1)> on guests or disk images: |  Run L<virt-alignment-scan(1)> on guests or disk images: | ||||||
| diff --git a/fish/guestfish.pod b/fish/guestfish.pod
 | diff --git a/fish/guestfish.pod b/fish/guestfish.pod
 | ||||||
| index da47c86d..33fc8b2c 100644
 | index 9f086f110..bb4167b06 100644
 | ||||||
| --- a/fish/guestfish.pod
 | --- a/fish/guestfish.pod
 | ||||||
| +++ b/fish/guestfish.pod
 | +++ b/fish/guestfish.pod
 | ||||||
| @@ -131,9 +131,9 @@ To list what is available do:
 | @@ -131,9 +131,9 @@ To list what is available do:
 | ||||||
| @ -72,7 +77,7 @@ index da47c86d..33fc8b2c 100644 | |||||||
|   |   | ||||||
|  =head2 Remote control |  =head2 Remote control | ||||||
|   |   | ||||||
| @@ -1129,12 +1129,12 @@ L<guestfs(3)/REMOTE STORAGE>>.
 | @@ -1134,12 +1134,12 @@ L<guestfs(3)/REMOTE STORAGE>>.
 | ||||||
|  On the command line, you can use the I<-a> option to add network |  On the command line, you can use the I<-a> option to add network | ||||||
|  block devices using a URI-style format, for example: |  block devices using a URI-style format, for example: | ||||||
|   |   | ||||||
| @ -87,7 +92,7 @@ index da47c86d..33fc8b2c 100644 | |||||||
|   |   | ||||||
|  The possible I<-a URI> formats are described below. |  The possible I<-a URI> formats are described below. | ||||||
|   |   | ||||||
| @@ -1144,28 +1144,6 @@ The possible I<-a URI> formats are described below.
 | @@ -1149,40 +1149,6 @@ The possible I<-a URI> formats are described below.
 | ||||||
|   |   | ||||||
|  Add the local disk image (or device) called F<disk.img>. |  Add the local disk image (or device) called F<disk.img>. | ||||||
|   |   | ||||||
| @ -99,12 +104,24 @@ index da47c86d..33fc8b2c 100644 | |||||||
| -
 | -
 | ||||||
| -=head2 B<-a https://[user@]example.com[:port]/disk.img>
 | -=head2 B<-a https://[user@]example.com[:port]/disk.img>
 | ||||||
| -
 | -
 | ||||||
| -Add a disk located on a remote FTP or HTTP server.
 | -=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:
 | -The equivalent API command would be:
 | ||||||
| -
 | -
 | ||||||
| - ><fs> add /disk.img protocol:(ftp|...) server:tcp:example.com
 | - ><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]>
 | -=head2 B<-a iscsi://example.com[:port]/target-iqn-name[/lun]>
 | ||||||
| -
 | -
 | ||||||
| -Add a disk located on an iSCSI server.
 | -Add a disk located on an iSCSI server.
 | ||||||
| @ -116,10 +133,22 @@ index da47c86d..33fc8b2c 100644 | |||||||
|  =head2 B<-a nbd://example.com[:port]> |  =head2 B<-a nbd://example.com[:port]> | ||||||
|   |   | ||||||
|  =head2 B<-a nbd://example.com[:port]/exportname> |  =head2 B<-a nbd://example.com[:port]/exportname> | ||||||
| @@ -1200,23 +1178,13 @@ The equivalent API command would be:
 | @@ -1217,35 +1183,13 @@ The equivalent API command would be:
 | ||||||
|   |   | ||||||
|   ><fs> add pool/disk protocol:rbd server:tcp:example.com:port |   ><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>
 | -=head2 B<-a ssh://[user@]example.com[:port]/disk.img>
 | ||||||
| -
 | -
 | ||||||
| -Add a disk image located on a remote server, accessed using the Secure
 | -Add a disk image located on a remote server, accessed using the Secure
 | ||||||
| @ -142,24 +171,35 @@ index da47c86d..33fc8b2c 100644 | |||||||
|  In this case, the password is C<pass@word>. |  In this case, the password is C<pass@word>. | ||||||
|   |   | ||||||
| diff --git a/fish/test-add-uri.sh b/fish/test-add-uri.sh
 | diff --git a/fish/test-add-uri.sh b/fish/test-add-uri.sh
 | ||||||
| index 533a3ce0..ddabeb63 100755
 | index 21d424984..ddabeb639 100755
 | ||||||
| --- a/fish/test-add-uri.sh
 | --- a/fish/test-add-uri.sh
 | ||||||
| +++ b/fish/test-add-uri.sh
 | +++ b/fish/test-add-uri.sh
 | ||||||
| @@ -40,10 +40,6 @@ function fail ()
 | @@ -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 |  $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 |  grep -sq 'add_drive ".*/test-add-uri.img"' test-add-uri.out || fail | ||||||
|   |   | ||||||
| -# curl
 | -# curl
 | ||||||
| -$VG guestfish -x -a ftp://user@example.com/disk.img </dev/null >test-add-uri.out 2>&1
 | -$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
 | -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 |  # NBD | ||||||
|  $VG guestfish -x -a nbd://example.com </dev/null >test-add-uri.out 2>&1 |  $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 |  grep -sq 'add_drive "" "protocol:nbd" "server:tcp:example.com"' test-add-uri.out || fail | ||||||
| @@ -63,22 +59,5 @@ grep -sq 'add_drive "pool/disk" "protocol:rbd" "server:tcp:example.com:6789"' te
 | @@ -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 |  $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 |  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
 | -# ssh
 | ||||||
| -$VG guestfish -x -a ssh://example.com/disk.img </dev/null >test-add-uri.out 2>&1
 | -$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
 | -grep -sq 'add_drive "/disk.img" "protocol:ssh" "server:tcp:example.com"' test-add-uri.out || fail
 | ||||||
| @ -180,19 +220,26 @@ index 533a3ce0..ddabeb63 100755 | |||||||
|  rm test-add-uri.out |  rm test-add-uri.out | ||||||
|  rm test-add-uri.img |  rm test-add-uri.img | ||||||
| diff --git a/generator/actions_core.ml b/generator/actions_core.ml
 | diff --git a/generator/actions_core.ml b/generator/actions_core.ml
 | ||||||
| index 20f6e843..768f5843 100644
 | index 37476c93e..9f0402510 100644
 | ||||||
| --- a/generator/actions_core.ml
 | --- a/generator/actions_core.ml
 | ||||||
| +++ b/generator/actions_core.ml
 | +++ b/generator/actions_core.ml
 | ||||||
| @@ -350,22 +350,6 @@ F<filename> is interpreted as a local file or device.
 | @@ -297,29 +297,6 @@ F<filename> is interpreted as a local file or device.
 | ||||||
|  This is the default if the optional protocol parameter |  This is the default if the optional protocol parameter | ||||||
|  is omitted. |  is omitted. | ||||||
|   |   | ||||||
| -=item C<protocol = \"ftp\"|\"ftps\"|\"http\"|\"https\">
 | -=item C<protocol = \"ftp\"|\"ftps\"|\"http\"|\"https\"|\"tftp\">
 | ||||||
| -
 | -
 | ||||||
| -Connect to a remote FTP or HTTP server.
 | -Connect to a remote FTP, HTTP or TFTP server.
 | ||||||
| -The C<server> parameter must also be supplied - see below.
 | -The C<server> parameter must also be supplied - see below.
 | ||||||
| -
 | -
 | ||||||
| -See also: L<guestfs(3)/FTP AND HTTP>
 | -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\">
 | -=item C<protocol = \"iscsi\">
 | ||||||
| -
 | -
 | ||||||
| @ -206,10 +253,17 @@ index 20f6e843..768f5843 100644 | |||||||
|  =item C<protocol = \"nbd\"> |  =item C<protocol = \"nbd\"> | ||||||
|   |   | ||||||
|  Connect to the Network Block Device server. |  Connect to the Network Block Device server. | ||||||
| @@ -382,15 +366,6 @@ The C<secret> parameter may be supplied.  See below.
 | @@ -336,22 +313,6 @@ The C<secret> parameter may be supplied.  See below.
 | ||||||
|   |   | ||||||
|  See also: L<guestfs(3)/CEPH>. |  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\">
 | -=item C<protocol = \"ssh\">
 | ||||||
| -
 | -
 | ||||||
| -Connect to the Secure Shell (ssh) server.
 | -Connect to the Secure Shell (ssh) server.
 | ||||||
| @ -222,24 +276,26 @@ index 20f6e843..768f5843 100644 | |||||||
|  =back |  =back | ||||||
|   |   | ||||||
|  =item C<server> |  =item C<server> | ||||||
| @@ -401,11 +376,8 @@ is a list of server(s).
 | @@ -362,13 +323,8 @@ is a list of server(s).
 | ||||||
|   Protocol       Number of servers required |   Protocol       Number of servers required | ||||||
|   --------       -------------------------- |   --------       -------------------------- | ||||||
|   file           List must be empty or param not used at all |   file           List must be empty or param not used at all | ||||||
| - ftp|ftps|http|https  Exactly one
 | - ftp|ftps|http|https|tftp  Exactly one
 | ||||||
|  | - gluster        Exactly one
 | ||||||
| - iscsi          Exactly one
 | - iscsi          Exactly one
 | ||||||
|   nbd            Exactly one |   nbd            Exactly one | ||||||
|   rbd            Zero or more |   rbd            Zero or more | ||||||
|  | - sheepdog       Zero or more
 | ||||||
| - ssh            Exactly one
 | - ssh            Exactly one
 | ||||||
|   |   | ||||||
|  Each list element is a string specifying a server.  The string must be |  Each list element is a string specifying a server.  The string must be | ||||||
|  in one of the following formats: |  in one of the following formats: | ||||||
| @@ -421,10 +393,10 @@ for the protocol is used (see F</etc/services>).
 | @@ -384,10 +340,10 @@ for the protocol is used (see F</etc/services>).
 | ||||||
|   |   | ||||||
|  =item C<username> |  =item C<username> | ||||||
|   |   | ||||||
| -For the C<ftp>, C<ftps>, C<http>, C<https>, C<iscsi>, C<rbd> and C<ssh>
 | -For the C<ftp>, C<ftps>, C<http>, C<https>, C<iscsi>, C<rbd>, C<ssh>
 | ||||||
| -protocols, this specifies the remote username.
 | -and C<tftp> protocols, this specifies the remote username.
 | ||||||
| +For the C<rbd>
 | +For the C<rbd>
 | ||||||
| +protocol, this specifies the remote username.
 | +protocol, this specifies the remote username.
 | ||||||
|   |   | ||||||
| @ -249,162 +305,85 @@ index 20f6e843..768f5843 100644 | |||||||
|  example if using the libvirt backend and if the libvirt backend is configured to |  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, |  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
 | diff --git a/lib/drives.c b/lib/drives.c
 | ||||||
| index c068b8ec..6e4453ce 100644
 | index 46af66db4..c81ded5d7 100644
 | ||||||
| --- a/lib/drives.c
 | --- a/lib/drives.c
 | ||||||
| +++ b/lib/drives.c
 | +++ b/lib/drives.c
 | ||||||
| @@ -166,34 +166,6 @@ create_drive_non_file (guestfs_h *g,
 | @@ -168,6 +168,7 @@ create_drive_non_file (guestfs_h *g,
 | ||||||
|    return drv; |    return drv; | ||||||
|  } |  } | ||||||
|   |   | ||||||
| -static struct drive *
 | +#if 0 /* DISABLED IN RHEL 8 */
 | ||||||
| -create_drive_curl (guestfs_h *g,
 |  static struct drive * | ||||||
| -                   const struct drive_create_data *data)
 |  create_drive_curl (guestfs_h *g, | ||||||
| -{
 |                     const struct drive_create_data *data) | ||||||
| -  if (data->nr_servers != 1) {
 | @@ -226,6 +227,7 @@ create_drive_gluster (guestfs_h *g,
 | ||||||
| -    error (g, _("curl: you must specify exactly one server"));
 |   | ||||||
| -    return NULL;
 |    return create_drive_non_file (g, data); | ||||||
| -  }
 |  } | ||||||
| -
 | +#endif /* DISABLED IN RHEL 8 */
 | ||||||
| -  if (data->servers[0].transport != drive_transport_none &&
 |   | ||||||
| -      data->servers[0].transport != drive_transport_tcp) {
 |  | ||||||
| -    error (g, _("curl: only tcp transport is supported"));
 |  | ||||||
| -    return NULL;
 |  | ||||||
| -  }
 |  | ||||||
| -
 |  | ||||||
| -  if (STREQ (data->exportname, "")) {
 |  | ||||||
| -    error (g, _("curl: pathname should not be an empty string"));
 |  | ||||||
| -    return NULL;
 |  | ||||||
| -  }
 |  | ||||||
| -
 |  | ||||||
| -  if (data->exportname[0] != '/') {
 |  | ||||||
| -    error (g, _("curl: pathname must begin with a '/'"));
 |  | ||||||
| -    return NULL;
 |  | ||||||
| -  }
 |  | ||||||
| -
 |  | ||||||
| -  return create_drive_non_file (g, data);
 |  | ||||||
| -}
 |  | ||||||
| -
 |  | ||||||
|  static int |  static int | ||||||
|  nbd_port (void) |  nbd_port (void) | ||||||
|  { | @@ -294,6 +296,7 @@ create_drive_rbd (guestfs_h *g,
 | ||||||
| @@ -261,67 +233,6 @@ create_drive_rbd (guestfs_h *g,
 |  | ||||||
|    return create_drive_non_file (g, data); |    return create_drive_non_file (g, data); | ||||||
|  } |  } | ||||||
|   |   | ||||||
| -static struct drive *
 | +#if 0 /* DISABLED IN RHEL 8 */
 | ||||||
| -create_drive_ssh (guestfs_h *g,
 |  static struct drive * | ||||||
| -                  const struct drive_create_data *data)
 |  create_drive_sheepdog (guestfs_h *g, | ||||||
| -{
 |                         const struct drive_create_data *data) | ||||||
| -  if (data->nr_servers != 1) {
 | @@ -394,6 +397,7 @@ create_drive_iscsi (guestfs_h *g,
 | ||||||
| -    error (g, _("ssh: you must specify exactly one server"));
 |   | ||||||
| -    return NULL;
 |    return create_drive_non_file (g, data); | ||||||
| -  }
 |  } | ||||||
| -
 | +#endif /* DISABLED IN RHEL 8 */
 | ||||||
| -  if (data->servers[0].transport != drive_transport_none &&
 |   | ||||||
| -      data->servers[0].transport != drive_transport_tcp) {
 |  | ||||||
| -    error (g, _("ssh: only tcp transport is supported"));
 |  | ||||||
| -    return NULL;
 |  | ||||||
| -  }
 |  | ||||||
| -
 |  | ||||||
| -  if (STREQ (data->exportname, "")) {
 |  | ||||||
| -    error (g, _("ssh: pathname should not be an empty string"));
 |  | ||||||
| -    return NULL;
 |  | ||||||
| -  }
 |  | ||||||
| -
 |  | ||||||
| -  if (data->exportname[0] != '/') {
 |  | ||||||
| -    error (g, _("ssh: pathname must begin with a '/'"));
 |  | ||||||
| -    return NULL;
 |  | ||||||
| -  }
 |  | ||||||
| -
 |  | ||||||
| -  if (data->username && STREQ (data->username, "")) {
 |  | ||||||
| -    error (g, _("ssh: username should not be an empty string"));
 |  | ||||||
| -    return NULL;
 |  | ||||||
| -  }
 |  | ||||||
| -
 |  | ||||||
| -  return create_drive_non_file (g, data);
 |  | ||||||
| -}
 |  | ||||||
| -
 |  | ||||||
| -static struct drive *
 |  | ||||||
| -create_drive_iscsi (guestfs_h *g,
 |  | ||||||
| -                    const struct drive_create_data *data)
 |  | ||||||
| -{
 |  | ||||||
| -  if (data->nr_servers != 1) {
 |  | ||||||
| -    error (g, _("iscsi: you must specify exactly one server"));
 |  | ||||||
| -    return NULL;
 |  | ||||||
| -  }
 |  | ||||||
| -
 |  | ||||||
| -  if (data->servers[0].transport != drive_transport_none &&
 |  | ||||||
| -      data->servers[0].transport != drive_transport_tcp) {
 |  | ||||||
| -    error (g, _("iscsi: only tcp transport is supported"));
 |  | ||||||
| -    return NULL;
 |  | ||||||
| -  }
 |  | ||||||
| -
 |  | ||||||
| -  if (STREQ (data->exportname, "")) {
 |  | ||||||
| -    error (g, _("iscsi: target name should not be an empty string"));
 |  | ||||||
| -    return NULL;
 |  | ||||||
| -  }
 |  | ||||||
| -
 |  | ||||||
| -  if (data->exportname[0] == '/') {
 |  | ||||||
| -    error (g, _("iscsi: target string must not begin with a '/'"));
 |  | ||||||
| -    return NULL;
 |  | ||||||
| -  }
 |  | ||||||
| -
 |  | ||||||
| -  return create_drive_non_file (g, data);
 |  | ||||||
| -}
 |  | ||||||
| -
 |  | ||||||
|  /** |  /** | ||||||
|   * Create the special F</dev/null> drive. |   * Create the special F</dev/null> drive. | ||||||
|   * | @@ -856,6 +860,7 @@ guestfs_impl_add_drive_opts (guestfs_h *g, const char *filename,
 | ||||||
| @@ -768,26 +679,6 @@ guestfs_impl_add_drive_opts (guestfs_h *g, const char *filename,
 |  | ||||||
|        drv = create_drive_file (g, &data); |        drv = create_drive_file (g, &data); | ||||||
|      } |      } | ||||||
|    } |    } | ||||||
| -  else if (STREQ (protocol, "ftp")) {
 | +#if 0 /* DISABLED IN RHEL 8 */
 | ||||||
| -    data.protocol = drive_protocol_ftp;
 |    else if (STREQ (protocol, "ftp")) { | ||||||
| -    drv = create_drive_curl (g, &data);
 |      data.protocol = drive_protocol_ftp; | ||||||
| -  }
 |      drv = create_drive_curl (g, &data); | ||||||
| -  else if (STREQ (protocol, "ftps")) {
 | @@ -880,6 +885,7 @@ guestfs_impl_add_drive_opts (guestfs_h *g, const char *filename,
 | ||||||
| -    data.protocol = drive_protocol_ftps;
 |      data.protocol = drive_protocol_iscsi; | ||||||
| -    drv = create_drive_curl (g, &data);
 |      drv = create_drive_iscsi (g, &data); | ||||||
| -  }
 |    } | ||||||
| -  else if (STREQ (protocol, "http")) {
 | +#endif /* DISABLED IN RHEL 8 */
 | ||||||
| -    data.protocol = drive_protocol_http;
 |  | ||||||
| -    drv = create_drive_curl (g, &data);
 |  | ||||||
| -  }
 |  | ||||||
| -  else if (STREQ (protocol, "https")) {
 |  | ||||||
| -    data.protocol = drive_protocol_https;
 |  | ||||||
| -    drv = create_drive_curl (g, &data);
 |  | ||||||
| -  }
 |  | ||||||
| -  else if (STREQ (protocol, "iscsi")) {
 |  | ||||||
| -    data.protocol = drive_protocol_iscsi;
 |  | ||||||
| -    drv = create_drive_iscsi (g, &data);
 |  | ||||||
| -  }
 |  | ||||||
|    else if (STREQ (protocol, "nbd")) { |    else if (STREQ (protocol, "nbd")) { | ||||||
|      data.protocol = drive_protocol_nbd; |      data.protocol = drive_protocol_nbd; | ||||||
|      drv = create_drive_nbd (g, &data); |      drv = create_drive_nbd (g, &data); | ||||||
| @@ -796,10 +687,6 @@ guestfs_impl_add_drive_opts (guestfs_h *g, const char *filename,
 | @@ -888,6 +894,7 @@ guestfs_impl_add_drive_opts (guestfs_h *g, const char *filename,
 | ||||||
|      data.protocol = drive_protocol_rbd; |      data.protocol = drive_protocol_rbd; | ||||||
|      drv = create_drive_rbd (g, &data); |      drv = create_drive_rbd (g, &data); | ||||||
|    } |    } | ||||||
| -  else if (STREQ (protocol, "ssh")) {
 | +#if 0 /* DISABLED IN RHEL 8 */
 | ||||||
| -    data.protocol = drive_protocol_ssh;
 |    else if (STREQ (protocol, "sheepdog")) { | ||||||
| -    drv = create_drive_ssh (g, &data);
 |      data.protocol = drive_protocol_sheepdog; | ||||||
| -  }
 |      drv = create_drive_sheepdog (g, &data); | ||||||
|  | @@ -900,6 +907,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 { |    else { | ||||||
|      error (g, _("unknown protocol ‘%s’"), protocol); |      error (g, _("unknown protocol ‘%s’"), protocol); | ||||||
|      drv = NULL; /*FALLTHROUGH*/ |      drv = NULL; /*FALLTHROUGH*/ | ||||||
| diff --git a/lib/guestfs.pod b/lib/guestfs.pod
 | diff --git a/lib/guestfs.pod b/lib/guestfs.pod
 | ||||||
| index ecab0e1f..dff32cc9 100644
 | index bce9eb79f..2bb13b875 100644
 | ||||||
| --- a/lib/guestfs.pod
 | --- a/lib/guestfs.pod
 | ||||||
| +++ b/lib/guestfs.pod
 | +++ b/lib/guestfs.pod
 | ||||||
| @@ -723,51 +723,6 @@ a qcow2 backing file specification, libvirt does not construct an
 | @@ -715,70 +715,6 @@ servers.  The server string is documented in
 | ||||||
|  ephemeral secret object from those, for Ceph authentication.  Refer to |  L</guestfs_add_drive_opts>. The C<username> and C<secret> parameters are | ||||||
|  L<https://bugzilla.redhat.com/2033247>. |  also optional, and if not given, then no authentication will be used. | ||||||
|   |   | ||||||
| -=head3 FTP AND HTTP
 | -=head3 FTP, HTTP AND TFTP
 | ||||||
| -
 | -
 | ||||||
| -Libguestfs can access remote disks over FTP, FTPS, HTTP or HTTPS
 | -Libguestfs can access remote disks over FTP, FTPS, HTTP, HTTPS
 | ||||||
| -protocols.
 | -or TFTP protocols.
 | ||||||
| -
 | -
 | ||||||
| -To do this, set the optional C<protocol> and C<server> parameters of
 | -To do this, set the optional C<protocol> and C<server> parameters of
 | ||||||
| -L</guestfs_add_drive_opts> like this:
 | -L</guestfs_add_drive_opts> like this:
 | ||||||
| @ -417,16 +396,35 @@ index ecab0e1f..dff32cc9 100644 | |||||||
| -                         -1);
 | -                         -1);
 | ||||||
| -
 | -
 | ||||||
| -The C<protocol> can be one of C<"ftp">, C<"ftps">, C<"http">,
 | -The C<protocol> can be one of C<"ftp">, C<"ftps">, C<"http">,
 | ||||||
| -or C<"https">.
 | -C<"https"> or C<"tftp">.
 | ||||||
| -
 | -
 | ||||||
| -C<servers> (the C<server> parameter) is a list which must have a
 | -C<servers> (the C<server> parameter) is a list which must have a
 | ||||||
| -single element.  The single element is a string defining the web
 | -single element.  The single element is a string defining the web,
 | ||||||
| -or FTP server.  The format of this string is documented in
 | -FTP or TFTP server.  The format of this string is documented in
 | ||||||
| -L</guestfs_add_drive_opts>.
 | -L</guestfs_add_drive_opts>.
 | ||||||
| -
 | -
 | ||||||
| -=head3 GLUSTER
 | -=head3 GLUSTER
 | ||||||
| -
 | -
 | ||||||
| -Glusterfs support was removed in libguestfs 1.54 (2024).
 | -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
 | -=head3 ISCSI
 | ||||||
| -
 | -
 | ||||||
| @ -449,13 +447,27 @@ index ecab0e1f..dff32cc9 100644 | |||||||
|  =head3 NETWORK BLOCK DEVICE |  =head3 NETWORK BLOCK DEVICE | ||||||
|   |   | ||||||
|  Libguestfs can access Network Block Device (NBD) disks remotely. |  Libguestfs can access Network Block Device (NBD) disks remotely. | ||||||
| @@ -830,28 +785,6 @@ L<https://bugs.launchpad.net/qemu/+bug/1155677>
 | @@ -841,42 +777,6 @@ L<https://bugs.launchpad.net/qemu/+bug/1155677>
 | ||||||
|   |   | ||||||
|  =back |  =back | ||||||
|   |   | ||||||
| -=head3 SHEEPDOG
 | -=head3 SHEEPDOG
 | ||||||
| -
 | -
 | ||||||
| -Sheepdog support was removed in libguestfs 1.54 (2024).
 | -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
 | -=head3 SSH
 | ||||||
| -
 | -
 | ||||||
| @ -479,13 +491,20 @@ index ecab0e1f..dff32cc9 100644 | |||||||
|   |   | ||||||
|  Libguestfs has APIs for inspecting an unknown disk image to find out |  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
 | diff --git a/tests/disks/test-qemu-drive-libvirt.sh b/tests/disks/test-qemu-drive-libvirt.sh
 | ||||||
| index afbeddec..93df4be0 100755
 | index 3c5aa592e..f73827bd6 100755
 | ||||||
| --- a/tests/disks/test-qemu-drive-libvirt.sh
 | --- a/tests/disks/test-qemu-drive-libvirt.sh
 | ||||||
| +++ b/tests/disks/test-qemu-drive-libvirt.sh
 | +++ b/tests/disks/test-qemu-drive-libvirt.sh
 | ||||||
| @@ -65,13 +65,6 @@ check_output
 | @@ -64,34 +64,6 @@ check_output
 | ||||||
|  grep -sq -- '-drive file=rbd:abc-def/ghi-jkl:auth_supported=none,' "$DEBUG_QEMU_FILE" || fail ceph2 |  grep -sq -- '-drive file=rbd:abc-def/ghi-jkl:auth_supported=none,' "$DEBUG_QEMU_FILE" || fail ceph2 | ||||||
|  rm "$DEBUG_QEMU_FILE" |  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.
 | -# iSCSI.
 | ||||||
| -
 | -
 | ||||||
| -$guestfish -d iscsi run ||:
 | -$guestfish -d iscsi run ||:
 | ||||||
| @ -493,14 +512,28 @@ index afbeddec..93df4be0 100755 | |||||||
| -grep -sq -- '-drive file=iscsi://1.2.3.4:1234/iqn.2003-01.org.linux-iscsi.fedora' "$DEBUG_QEMU_FILE" || fail iscsi
 | -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"
 | -rm "$DEBUG_QEMU_FILE"
 | ||||||
| -
 | -
 | ||||||
|  # NBD. | -# 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 nbd run ||: |  $guestfish -d pool1 run ||: | ||||||
| diff --git a/tests/disks/test-qemu-drive.sh b/tests/disks/test-qemu-drive.sh
 | diff --git a/tests/disks/test-qemu-drive.sh b/tests/disks/test-qemu-drive.sh
 | ||||||
| index 9ee7df38..b3e4f990 100755
 | index 19dd60a2f..583e031bd 100755
 | ||||||
| --- a/tests/disks/test-qemu-drive.sh
 | --- a/tests/disks/test-qemu-drive.sh
 | ||||||
| +++ b/tests/disks/test-qemu-drive.sh
 | +++ b/tests/disks/test-qemu-drive.sh
 | ||||||
| @@ -62,35 +62,6 @@ check_output
 | @@ -62,45 +62,6 @@ check_output
 | ||||||
|  grep -sq -- '-drive file=rbd:abc-def/ghi-jkl:auth_supported=none,' "$DEBUG_QEMU_FILE" || fail |  grep -sq -- '-drive file=rbd:abc-def/ghi-jkl:auth_supported=none,' "$DEBUG_QEMU_FILE" || fail | ||||||
|  rm "$DEBUG_QEMU_FILE" |  rm "$DEBUG_QEMU_FILE" | ||||||
|   |   | ||||||
| @ -514,6 +547,16 @@ index 9ee7df38..b3e4f990 100755 | |||||||
| -grep -sq -- '-drive file=http://www.example.com/disk.img,' "$DEBUG_QEMU_FILE" || fail
 | -grep -sq -- '-drive file=http://www.example.com/disk.img,' "$DEBUG_QEMU_FILE" || fail
 | ||||||
| -rm "$DEBUG_QEMU_FILE"
 | -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.
 | -# iSCSI.
 | ||||||
| -
 | -
 | ||||||
| -guestfish <<EOF ||:
 | -guestfish <<EOF ||:
 | ||||||
| @ -536,11 +579,21 @@ index 9ee7df38..b3e4f990 100755 | |||||||
|  # NBD. |  # NBD. | ||||||
|   |   | ||||||
|  guestfish <<EOF ||: |  guestfish <<EOF ||: | ||||||
| @@ -108,14 +79,3 @@ EOF
 | @@ -118,24 +79,3 @@ EOF
 | ||||||
|  check_output |  check_output | ||||||
|  grep -sq -- '-drive file=nbd:unix:/socket,' "$DEBUG_QEMU_FILE" || fail |  grep -sq -- '-drive file=nbd:unix:/socket,' "$DEBUG_QEMU_FILE" || fail | ||||||
|  rm "$DEBUG_QEMU_FILE" |  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.
 | -# SSH.
 | ||||||
| -
 | -
 | ||||||
| -guestfish <<EOF ||:
 | -guestfish <<EOF ||:
 | ||||||
| @ -551,3 +604,6 @@ index 9ee7df38..b3e4f990 100755 | |||||||
| -check_output
 | -check_output
 | ||||||
| -grep -sq -- '-drive file=ssh://rich@example.com/disk.img,' "$DEBUG_QEMU_FILE" || fail
 | -grep -sq -- '-drive file=ssh://rich@example.com/disk.img,' "$DEBUG_QEMU_FILE" || fail
 | ||||||
| -rm "$DEBUG_QEMU_FILE"
 | -rm "$DEBUG_QEMU_FILE"
 | ||||||
|  | -- 
 | ||||||
|  | 2.31.1 | ||||||
|  | 
 | ||||||
| @ -1,41 +0,0 @@ | |||||||
| From 0f489f8eec0c02e9ed1d606a2032edccf81ef025 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: "Richard W.M. Jones" <rjones@redhat.com> |  | ||||||
| Date: Thu, 17 Oct 2024 08:59:49 +0100 |  | ||||||
| Subject: [PATCH] lib/inspect-osinfo.c: Add Windows Server 2025 osinfo |  | ||||||
| 
 |  | ||||||
| The guest was found to have these inspection fields: |  | ||||||
| 
 |  | ||||||
|     type: windows |  | ||||||
|     distro: windows |  | ||||||
|     product_name: Windows Server 2025 Standard |  | ||||||
|     product_variant: Server |  | ||||||
|     version: 10.0 |  | ||||||
|     arch: x86_64 |  | ||||||
|     hostname: WIN-84V4KKQ30SM |  | ||||||
|     build ID: 26080 |  | ||||||
|     windows_systemroot: /Windows |  | ||||||
|     windows_software_hive: /Windows/System32/config/SOFTWARE |  | ||||||
|     windows_system_hive: /Windows/System32/config/SYSTEM |  | ||||||
|     windows_current_control_set: ControlSet001 |  | ||||||
| 
 |  | ||||||
| Reported-by: Ming Xie |  | ||||||
| Fixes: https://issues.redhat.com/browse/RHEL-62935 |  | ||||||
| ---
 |  | ||||||
|  lib/inspect-osinfo.c | 4 +++- |  | ||||||
|  1 file changed, 3 insertions(+), 1 deletion(-) |  | ||||||
| 
 |  | ||||||
| diff --git a/lib/inspect-osinfo.c b/lib/inspect-osinfo.c
 |  | ||||||
| index c77344f6..f792d771 100644
 |  | ||||||
| --- a/lib/inspect-osinfo.c
 |  | ||||||
| +++ b/lib/inspect-osinfo.c
 |  | ||||||
| @@ -142,7 +142,9 @@ guestfs_impl_inspect_get_osinfo (guestfs_h *g, const char *root)
 |  | ||||||
|        switch (minor) { |  | ||||||
|        case 0: |  | ||||||
|          if (strstr (product_variant, "Server")) { |  | ||||||
| -          if (strstr (product_name, "2022"))
 |  | ||||||
| +          if (strstr (product_name, "2025"))
 |  | ||||||
| +            return safe_strdup (g, "win2k25");
 |  | ||||||
| +          else if (strstr (product_name, "2022"))
 |  | ||||||
|              return safe_strdup (g, "win2k22"); |  | ||||||
|            else if (strstr (product_name, "2019")) |  | ||||||
|              return safe_strdup (g, "win2k19"); |  | ||||||
| @ -0,0 +1,72 @@ | |||||||
|  | From 34f8c6a5eb0eabfba4ab1831b45e2baa73a4b501 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: "Richard W.M. Jones" <rjones@redhat.com> | ||||||
|  | Date: Fri, 19 Sep 2014 13:38:20 +0100 | ||||||
|  | Subject: [PATCH] RHEL 8: Remove User-Mode Linux (RHBZ#1144197). | ||||||
|  | 
 | ||||||
|  | This isn't supported in RHEL 8. | ||||||
|  | ---
 | ||||||
|  |  lib/launch-uml.c | 13 +++++++++++++ | ||||||
|  |  1 file changed, 13 insertions(+) | ||||||
|  | 
 | ||||||
|  | diff --git a/lib/launch-uml.c b/lib/launch-uml.c
 | ||||||
|  | index 5aec50a57..8b9fcd770 100644
 | ||||||
|  | --- a/lib/launch-uml.c
 | ||||||
|  | +++ b/lib/launch-uml.c
 | ||||||
|  | @@ -44,7 +44,9 @@ struct backend_uml_data {
 | ||||||
|  |    char umid[UML_UMID_LEN+1];    /* umid=<...> unique ID. */ | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  | +#if 0
 | ||||||
|  |  static void print_vmlinux_command_line (guestfs_h *g, char **argv); | ||||||
|  | +#endif
 | ||||||
|  |   | ||||||
|  |  /* Run uml_mkcow to create a COW overlay. */ | ||||||
|  |  static char * | ||||||
|  | @@ -81,6 +83,7 @@ create_cow_overlay_uml (guestfs_h *g, void *datav, struct drive *drv)
 | ||||||
|  |    return make_cow_overlay (g, drv->src.u.path); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +#if 0
 | ||||||
|  |  /* Test for features which are not supported by the UML backend. | ||||||
|  |   * Possibly some of these should just be warnings, not errors. | ||||||
|  |   */ | ||||||
|  | @@ -133,10 +136,17 @@ uml_supported (guestfs_h *g)
 | ||||||
|  |   | ||||||
|  |    return true; | ||||||
|  |  } | ||||||
|  | +#endif
 | ||||||
|  |   | ||||||
|  |  static int | ||||||
|  |  launch_uml (guestfs_h *g, void *datav, const char *arg) | ||||||
|  |  { | ||||||
|  | +  error (g,
 | ||||||
|  | +	 "launch: In RHEL, only the 'libvirt' or 'direct' method is supported.\n"
 | ||||||
|  | +	 "In particular, User-Mode Linux (UML) is not supported.");
 | ||||||
|  | +  return -1;
 | ||||||
|  | +
 | ||||||
|  | +#if 0
 | ||||||
|  |    struct backend_uml_data *data = datav; | ||||||
|  |    CLEANUP_FREE_STRINGSBUF DECLARE_STRINGSBUF (cmdline); | ||||||
|  |    int console_sock = -1, daemon_sock = -1; | ||||||
|  | @@ -496,8 +506,10 @@ launch_uml (guestfs_h *g, void *datav, const char *arg)
 | ||||||
|  |    } | ||||||
|  |    g->state = CONFIG; | ||||||
|  |    return -1; | ||||||
|  | +#endif
 | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +#if 0
 | ||||||
|  |  /* This is called from the forked subprocess just before vmlinux runs, | ||||||
|  |   * so it can just print the message straight to stderr, where it will | ||||||
|  |   * be picked up and funnelled through the usual appliance event API. | ||||||
|  | @@ -527,6 +539,7 @@ print_vmlinux_command_line (guestfs_h *g, char **argv)
 | ||||||
|  |   | ||||||
|  |    fputc ('\n', stderr); | ||||||
|  |  } | ||||||
|  | +#endif
 | ||||||
|  |   | ||||||
|  |  static int | ||||||
|  |  shutdown_uml (guestfs_h *g, void *datav, int check_for_errors) | ||||||
|  | -- 
 | ||||||
|  | 2.31.1 | ||||||
|  | 
 | ||||||
| @ -1,409 +0,0 @@ | |||||||
| From e37768d8892d6f467c7834f8b142b89f8f0af7dc Mon Sep 17 00:00:00 2001 |  | ||||||
| From: "Richard W.M. Jones" <rjones@redhat.com> |  | ||||||
| Date: Fri, 18 Oct 2024 21:52:21 +0100 |  | ||||||
| Subject: [PATCH] build: Assume __attribute__((cleanup)) always works |  | ||||||
| 
 |  | ||||||
| All recent compilers support this (except MS compilers which we don't |  | ||||||
| care about).  Assume it is supported.  We test it in ./configure and |  | ||||||
| hard fail if it doesn't work. |  | ||||||
| 
 |  | ||||||
| We still define HAVE_ATTRIBUTE_CLEANUP but you can now assume it is |  | ||||||
| always defined and don't have to check it. |  | ||||||
| ---
 |  | ||||||
|  common                 |  2 +- |  | ||||||
|  daemon/daemon.h        |  9 --------- |  | ||||||
|  daemon/sh.c            |  5 ----- |  | ||||||
|  daemon/yara.c          |  8 -------- |  | ||||||
|  generator/c.ml         | 10 ---------- |  | ||||||
|  generator/daemon.ml    | 15 --------------- |  | ||||||
|  lib/guestfs-internal.h |  8 -------- |  | ||||||
|  lib/info.c             |  5 ----- |  | ||||||
|  lib/launch-libvirt.c   |  5 ----- |  | ||||||
|  lib/qemu.c             |  5 ----- |  | ||||||
|  m4/guestfs-c.m4        |  7 ++----- |  | ||||||
|  11 files changed, 3 insertions(+), 76 deletions(-) |  | ||||||
| 
 |  | ||||||
| Submodule common b6e703dc..01c53226: |  | ||||||
| diff --git a/common/structs/structs-cleanups.h b/common/structs/structs-cleanups.h
 |  | ||||||
| index b43dbd75..c6e7fd1e 100644
 |  | ||||||
| --- a/common/structs/structs-cleanups.h
 |  | ||||||
| +++ b/common/structs/structs-cleanups.h
 |  | ||||||
| @@ -28,7 +28,6 @@
 |  | ||||||
|  #ifndef GUESTFS_STRUCTS_CLEANUPS_H_ |  | ||||||
|  #define GUESTFS_STRUCTS_CLEANUPS_H_ |  | ||||||
|   |  | ||||||
| -#ifdef HAVE_ATTRIBUTE_CLEANUP
 |  | ||||||
|  #define CLEANUP_FREE_INT_BOOL \ |  | ||||||
|    __attribute__((cleanup(guestfs_int_cleanup_free_int_bool))) |  | ||||||
|  #define CLEANUP_FREE_INT_BOOL_LIST \ |  | ||||||
| @@ -137,62 +136,6 @@
 |  | ||||||
|    __attribute__((cleanup(guestfs_int_cleanup_free_yara_detection))) |  | ||||||
|  #define CLEANUP_FREE_YARA_DETECTION_LIST \ |  | ||||||
|    __attribute__((cleanup(guestfs_int_cleanup_free_yara_detection_list))) |  | ||||||
| -#else /* !HAVE_ATTRIBUTE_CLEANUP */
 |  | ||||||
| -#define CLEANUP_FREE_INT_BOOL
 |  | ||||||
| -#define CLEANUP_FREE_INT_BOOL_LIST
 |  | ||||||
| -#define CLEANUP_FREE_LVM_PV
 |  | ||||||
| -#define CLEANUP_FREE_LVM_PV_LIST
 |  | ||||||
| -#define CLEANUP_FREE_LVM_VG
 |  | ||||||
| -#define CLEANUP_FREE_LVM_VG_LIST
 |  | ||||||
| -#define CLEANUP_FREE_LVM_LV
 |  | ||||||
| -#define CLEANUP_FREE_LVM_LV_LIST
 |  | ||||||
| -#define CLEANUP_FREE_STAT
 |  | ||||||
| -#define CLEANUP_FREE_STAT_LIST
 |  | ||||||
| -#define CLEANUP_FREE_STATNS
 |  | ||||||
| -#define CLEANUP_FREE_STATNS_LIST
 |  | ||||||
| -#define CLEANUP_FREE_STATVFS
 |  | ||||||
| -#define CLEANUP_FREE_STATVFS_LIST
 |  | ||||||
| -#define CLEANUP_FREE_DIRENT
 |  | ||||||
| -#define CLEANUP_FREE_DIRENT_LIST
 |  | ||||||
| -#define CLEANUP_FREE_VERSION
 |  | ||||||
| -#define CLEANUP_FREE_VERSION_LIST
 |  | ||||||
| -#define CLEANUP_FREE_XATTR
 |  | ||||||
| -#define CLEANUP_FREE_XATTR_LIST
 |  | ||||||
| -#define CLEANUP_FREE_INOTIFY_EVENT
 |  | ||||||
| -#define CLEANUP_FREE_INOTIFY_EVENT_LIST
 |  | ||||||
| -#define CLEANUP_FREE_PARTITION
 |  | ||||||
| -#define CLEANUP_FREE_PARTITION_LIST
 |  | ||||||
| -#define CLEANUP_FREE_APPLICATION
 |  | ||||||
| -#define CLEANUP_FREE_APPLICATION_LIST
 |  | ||||||
| -#define CLEANUP_FREE_APPLICATION2
 |  | ||||||
| -#define CLEANUP_FREE_APPLICATION2_LIST
 |  | ||||||
| -#define CLEANUP_FREE_ISOINFO
 |  | ||||||
| -#define CLEANUP_FREE_ISOINFO_LIST
 |  | ||||||
| -#define CLEANUP_FREE_MDSTAT
 |  | ||||||
| -#define CLEANUP_FREE_MDSTAT_LIST
 |  | ||||||
| -#define CLEANUP_FREE_BTRFSSUBVOLUME
 |  | ||||||
| -#define CLEANUP_FREE_BTRFSSUBVOLUME_LIST
 |  | ||||||
| -#define CLEANUP_FREE_BTRFSQGROUP
 |  | ||||||
| -#define CLEANUP_FREE_BTRFSQGROUP_LIST
 |  | ||||||
| -#define CLEANUP_FREE_BTRFSBALANCE
 |  | ||||||
| -#define CLEANUP_FREE_BTRFSBALANCE_LIST
 |  | ||||||
| -#define CLEANUP_FREE_BTRFSSCRUB
 |  | ||||||
| -#define CLEANUP_FREE_BTRFSSCRUB_LIST
 |  | ||||||
| -#define CLEANUP_FREE_XFSINFO
 |  | ||||||
| -#define CLEANUP_FREE_XFSINFO_LIST
 |  | ||||||
| -#define CLEANUP_FREE_UTSNAME
 |  | ||||||
| -#define CLEANUP_FREE_UTSNAME_LIST
 |  | ||||||
| -#define CLEANUP_FREE_HIVEX_NODE
 |  | ||||||
| -#define CLEANUP_FREE_HIVEX_NODE_LIST
 |  | ||||||
| -#define CLEANUP_FREE_HIVEX_VALUE
 |  | ||||||
| -#define CLEANUP_FREE_HIVEX_VALUE_LIST
 |  | ||||||
| -#define CLEANUP_FREE_INTERNAL_MOUNTABLE
 |  | ||||||
| -#define CLEANUP_FREE_INTERNAL_MOUNTABLE_LIST
 |  | ||||||
| -#define CLEANUP_FREE_TSK_DIRENT
 |  | ||||||
| -#define CLEANUP_FREE_TSK_DIRENT_LIST
 |  | ||||||
| -#define CLEANUP_FREE_YARA_DETECTION
 |  | ||||||
| -#define CLEANUP_FREE_YARA_DETECTION_LIST
 |  | ||||||
| -#endif /* !HAVE_ATTRIBUTE_CLEANUP */
 |  | ||||||
|   |  | ||||||
|  /* These functions are used internally by the CLEANUP_* macros. |  | ||||||
|   * Don't call them directly. |  | ||||||
| diff --git a/common/utils/cleanups.h b/common/utils/cleanups.h
 |  | ||||||
| index 932114f6..be52d072 100644
 |  | ||||||
| --- a/common/utils/cleanups.h
 |  | ||||||
| +++ b/common/utils/cleanups.h
 |  | ||||||
| @@ -19,7 +19,6 @@
 |  | ||||||
|  #ifndef GUESTFS_CLEANUPS_H_ |  | ||||||
|  #define GUESTFS_CLEANUPS_H_ |  | ||||||
|   |  | ||||||
| -#ifdef HAVE_ATTRIBUTE_CLEANUP
 |  | ||||||
|  #define CLEANUP_FREE                                    \ |  | ||||||
|    __attribute__((cleanup(guestfs_int_cleanup_free))) |  | ||||||
|  #define CLEANUP_HASH_FREE                                       \ |  | ||||||
| @@ -50,23 +49,6 @@
 |  | ||||||
|    __attribute__((cleanup(guestfs_int_cleanup_xmlXPathFreeObject))) |  | ||||||
|  #define CLEANUP_PCRE2_MATCH_DATA_FREE                                   \ |  | ||||||
|    __attribute__((cleanup(guestfs_int_cleanup_pcre2_match_data_free))) |  | ||||||
| -#else
 |  | ||||||
| -#define CLEANUP_FREE
 |  | ||||||
| -#define CLEANUP_HASH_FREE
 |  | ||||||
| -#define CLEANUP_UNLINK_FREE
 |  | ||||||
| -#define CLEANUP_CLOSE
 |  | ||||||
| -#define CLEANUP_FCLOSE
 |  | ||||||
| -#define CLEANUP_PCLOSE
 |  | ||||||
| -#define CLEANUP_FREE_STRING_LIST
 |  | ||||||
| -#define CLEANUP_XMLFREE
 |  | ||||||
| -#define CLEANUP_XMLBUFFERFREE
 |  | ||||||
| -#define CLEANUP_XMLFREEDOC
 |  | ||||||
| -#define CLEANUP_XMLFREEURI
 |  | ||||||
| -#define CLEANUP_XMLFREETEXTWRITER
 |  | ||||||
| -#define CLEANUP_XMLXPATHFREECONTEXT
 |  | ||||||
| -#define CLEANUP_XMLXPATHFREEOBJECT
 |  | ||||||
| -#define CLEANUP_PCRE2_MATCH_DATA_FREE
 |  | ||||||
| -#endif
 |  | ||||||
|   |  | ||||||
|  /* These functions are used internally by the CLEANUP_* macros. |  | ||||||
|   * Don't call them directly. |  | ||||||
| diff --git a/daemon/daemon.h b/daemon/daemon.h
 |  | ||||||
| index e050588c..5fc53245 100644
 |  | ||||||
| --- a/daemon/daemon.h
 |  | ||||||
| +++ b/daemon/daemon.h
 |  | ||||||
| @@ -93,11 +93,7 @@ extern char *read_whole_file (const char *filename, size_t *size_r);
 |  | ||||||
|  extern char *mountable_to_string (const mountable_t *mountable); |  | ||||||
|  extern void cleanup_free_mountable (mountable_t *mountable); |  | ||||||
|   |  | ||||||
| -#ifdef HAVE_ATTRIBUTE_CLEANUP
 |  | ||||||
|  #define CLEANUP_FREE_MOUNTABLE __attribute__((cleanup(cleanup_free_mountable))) |  | ||||||
| -#else
 |  | ||||||
| -#define CLEANUP_FREE_MOUNTABLE
 |  | ||||||
| -#endif
 |  | ||||||
|   |  | ||||||
|  /* cleanups.c */ |  | ||||||
|  /* These functions are used internally by the CLEANUP_* macros. |  | ||||||
| @@ -106,13 +102,8 @@ extern void cleanup_free_mountable (mountable_t *mountable);
 |  | ||||||
|  extern void cleanup_aug_close (void *ptr); |  | ||||||
|  extern void cleanup_free_stringsbuf (void *ptr); |  | ||||||
|   |  | ||||||
| -#ifdef HAVE_ATTRIBUTE_CLEANUP
 |  | ||||||
|  #define CLEANUP_AUG_CLOSE __attribute__((cleanup(cleanup_aug_close))) |  | ||||||
|  #define CLEANUP_FREE_STRINGSBUF __attribute__((cleanup(cleanup_free_stringsbuf))) |  | ||||||
| -#else
 |  | ||||||
| -#define CLEANUP_AUG_CLOSE
 |  | ||||||
| -#define CLEANUP_FREE_STRINGSBUF
 |  | ||||||
| -#endif
 |  | ||||||
|   |  | ||||||
|  /* mount.c */ |  | ||||||
|  extern int is_root_mounted (void); |  | ||||||
| diff --git a/daemon/sh.c b/daemon/sh.c
 |  | ||||||
| index 92ce08be..21d4deea 100644
 |  | ||||||
| --- a/daemon/sh.c
 |  | ||||||
| +++ b/daemon/sh.c
 |  | ||||||
| @@ -32,13 +32,8 @@
 |  | ||||||
|   |  | ||||||
|  #include "ignore-value.h" |  | ||||||
|   |  | ||||||
| -#ifdef HAVE_ATTRIBUTE_CLEANUP
 |  | ||||||
|  #define CLEANUP_BIND_STATE __attribute__((cleanup(free_bind_state))) |  | ||||||
|  #define CLEANUP_RESOLVER_STATE __attribute__((cleanup(free_resolver_state))) |  | ||||||
| -#else
 |  | ||||||
| -#define CLEANUP_BIND_STATE
 |  | ||||||
| -#define CLEANUP_RESOLVER_STATE
 |  | ||||||
| -#endif
 |  | ||||||
|   |  | ||||||
|  struct bind_state { |  | ||||||
|    bool mounted; |  | ||||||
| diff --git a/daemon/yara.c b/daemon/yara.c
 |  | ||||||
| index 21137b73..9350dd27 100644
 |  | ||||||
| --- a/daemon/yara.c
 |  | ||||||
| +++ b/daemon/yara.c
 |  | ||||||
| @@ -39,12 +39,8 @@
 |  | ||||||
|   |  | ||||||
|  #include <yara.h> |  | ||||||
|   |  | ||||||
| -#ifdef HAVE_ATTRIBUTE_CLEANUP
 |  | ||||||
|  #define CLEANUP_DESTROY_YARA_COMPILER                           \ |  | ||||||
|    __attribute__((cleanup(cleanup_destroy_yara_compiler))) |  | ||||||
| -#else
 |  | ||||||
| -#define CLEANUP_DESTROY_YARA_COMPILER
 |  | ||||||
| -#endif
 |  | ||||||
|   |  | ||||||
|  struct write_callback_data { |  | ||||||
|    int fd; |  | ||||||
| @@ -208,10 +204,6 @@ compile_rules_file (const char *rules_path)
 |  | ||||||
|    } |  | ||||||
|   |  | ||||||
|   err: |  | ||||||
| -#ifndef HAVE_ATTRIBUTE_CLEANUP
 |  | ||||||
| -  yr_compiler_destroy (compiler);
 |  | ||||||
| -#endif
 |  | ||||||
| -
 |  | ||||||
|    return ret; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| diff --git a/generator/c.ml b/generator/c.ml
 |  | ||||||
| index 447059b8..838e7f42 100644
 |  | ||||||
| --- a/generator/c.ml
 |  | ||||||
| +++ b/generator/c.ml
 |  | ||||||
| @@ -817,7 +817,6 @@ and generate_client_structs_cleanups_h () =
 |  | ||||||
|  #ifndef GUESTFS_STRUCTS_CLEANUPS_H_ |  | ||||||
|  #define GUESTFS_STRUCTS_CLEANUPS_H_ |  | ||||||
|   |  | ||||||
| -#ifdef HAVE_ATTRIBUTE_CLEANUP
 |  | ||||||
|  "; |  | ||||||
|   |  | ||||||
|    List.iter ( |  | ||||||
| @@ -828,16 +827,7 @@ and generate_client_structs_cleanups_h () =
 |  | ||||||
|        pr "  __attribute__((cleanup(guestfs_int_cleanup_free_%s_list)))\n" name |  | ||||||
|    ) structs; |  | ||||||
|   |  | ||||||
| -  pr "#else /* !HAVE_ATTRIBUTE_CLEANUP */\n";
 |  | ||||||
| -
 |  | ||||||
| -  List.iter (
 |  | ||||||
| -    fun { s_name = name } ->
 |  | ||||||
| -      pr "#define CLEANUP_FREE_%s\n" (String.uppercase_ascii name);
 |  | ||||||
| -      pr "#define CLEANUP_FREE_%s_LIST\n" (String.uppercase_ascii name)
 |  | ||||||
| -  ) structs;
 |  | ||||||
| -
 |  | ||||||
|    pr "\ |  | ||||||
| -#endif /* !HAVE_ATTRIBUTE_CLEANUP */
 |  | ||||||
|   |  | ||||||
|  /* These functions are used internally by the CLEANUP_* macros. |  | ||||||
|   * Don't call them directly. |  | ||||||
| diff --git a/generator/daemon.ml b/generator/daemon.ml
 |  | ||||||
| index 78a2412d..9ab9e12d 100644
 |  | ||||||
| --- a/generator/daemon.ml
 |  | ||||||
| +++ b/generator/daemon.ml
 |  | ||||||
| @@ -127,8 +127,6 @@ let generate_daemon_stubs actions () =
 |  | ||||||
|                      args_passed_to_daemon in |  | ||||||
|   |  | ||||||
|        if args_passed_to_daemon <> [] then ( |  | ||||||
| -        pr "#ifdef HAVE_ATTRIBUTE_CLEANUP\n";
 |  | ||||||
| -        pr "\n";
 |  | ||||||
|          pr "#define CLEANUP_XDR_FREE_%s_ARGS \\\n" uc_name; |  | ||||||
|          pr "    __attribute__((cleanup(cleanup_xdr_free_%s_args)))\n" name; |  | ||||||
|          pr "\n"; |  | ||||||
| @@ -140,9 +138,6 @@ let generate_daemon_stubs actions () =
 |  | ||||||
|             name; |  | ||||||
|          pr "}\n"; |  | ||||||
|          pr "\n"; |  | ||||||
| -        pr "#else /* !HAVE_ATTRIBUTE_CLEANUP */\n";
 |  | ||||||
| -        pr "#define CLEANUP_XDR_FREE_%s_ARGS\n" uc_name;
 |  | ||||||
| -        pr "#endif /* !HAVE_ATTRIBUTE_CLEANUP */\n";
 |  | ||||||
|          pr "\n" |  | ||||||
|        ); |  | ||||||
|   |  | ||||||
| @@ -1315,7 +1310,6 @@ let generate_daemon_structs_cleanups_h () =
 |  | ||||||
|  #ifndef GUESTFS_DAEMON_STRUCTS_CLEANUPS_H_ |  | ||||||
|  #define GUESTFS_DAEMON_STRUCTS_CLEANUPS_H_ |  | ||||||
|   |  | ||||||
| -#ifdef HAVE_ATTRIBUTE_CLEANUP
 |  | ||||||
|  "; |  | ||||||
|   |  | ||||||
|    List.iter ( |  | ||||||
| @@ -1326,16 +1320,7 @@ let generate_daemon_structs_cleanups_h () =
 |  | ||||||
|        pr "  __attribute__((cleanup(cleanup_free_int_%s_list)))\n" name |  | ||||||
|    ) structs; |  | ||||||
|   |  | ||||||
| -  pr "#else /* !HAVE_ATTRIBUTE_CLEANUP */\n";
 |  | ||||||
| -
 |  | ||||||
| -  List.iter (
 |  | ||||||
| -    fun { s_name = name } ->
 |  | ||||||
| -      pr "#define CLEANUP_FREE_%s\n" (String.uppercase_ascii name);
 |  | ||||||
| -      pr "#define CLEANUP_FREE_%s_LIST\n" (String.uppercase_ascii name)
 |  | ||||||
| -  ) structs;
 |  | ||||||
| -
 |  | ||||||
|    pr "\ |  | ||||||
| -#endif /* !HAVE_ATTRIBUTE_CLEANUP */
 |  | ||||||
|   |  | ||||||
|  /* These functions are used internally by the CLEANUP_* macros. |  | ||||||
|   * Don't call them directly. |  | ||||||
| diff --git a/lib/guestfs-internal.h b/lib/guestfs-internal.h
 |  | ||||||
| index 174ca135..f9f4628a 100644
 |  | ||||||
| --- a/lib/guestfs-internal.h
 |  | ||||||
| +++ b/lib/guestfs-internal.h
 |  | ||||||
| @@ -661,11 +661,7 @@ extern void guestfs_int_end_stringsbuf (guestfs_h *g, struct stringsbuf *sb);
 |  | ||||||
|   |  | ||||||
|  extern void guestfs_int_free_stringsbuf (struct stringsbuf *sb); |  | ||||||
|   |  | ||||||
| -#ifdef HAVE_ATTRIBUTE_CLEANUP
 |  | ||||||
|  #define CLEANUP_FREE_STRINGSBUF __attribute__((cleanup(guestfs_int_cleanup_free_stringsbuf))) |  | ||||||
| -#else
 |  | ||||||
| -#define CLEANUP_FREE_STRINGSBUF
 |  | ||||||
| -#endif
 |  | ||||||
|  extern void guestfs_int_cleanup_free_stringsbuf (struct stringsbuf *sb); |  | ||||||
|   |  | ||||||
|  /* proto.c */ |  | ||||||
| @@ -785,11 +781,7 @@ extern int guestfs_int_cmd_pipe_run (struct command *cmd, const char *mode);
 |  | ||||||
|  extern int guestfs_int_cmd_pipe_wait (struct command *cmd); |  | ||||||
|  extern char *guestfs_int_cmd_get_pipe_errors (struct command *cmd); |  | ||||||
|   |  | ||||||
| -#ifdef HAVE_ATTRIBUTE_CLEANUP
 |  | ||||||
|  #define CLEANUP_CMD_CLOSE __attribute__((cleanup(guestfs_int_cleanup_cmd_close))) |  | ||||||
| -#else
 |  | ||||||
| -#define CLEANUP_CMD_CLOSE
 |  | ||||||
| -#endif
 |  | ||||||
|  extern void guestfs_int_cleanup_cmd_close (struct command **); |  | ||||||
|   |  | ||||||
|  /* launch-*.c constructors */ |  | ||||||
| diff --git a/lib/info.c b/lib/info.c
 |  | ||||||
| index 4dee7a26..b60fc8b3 100644
 |  | ||||||
| --- a/lib/info.c
 |  | ||||||
| +++ b/lib/info.c
 |  | ||||||
| @@ -43,7 +43,6 @@
 |  | ||||||
|  #include "guestfs-internal.h" |  | ||||||
|  #include "guestfs-internal-actions.h" |  | ||||||
|   |  | ||||||
| -#ifdef HAVE_ATTRIBUTE_CLEANUP
 |  | ||||||
|  #define CLEANUP_JSON_T_DECREF __attribute__((cleanup(cleanup_json_t_decref))) |  | ||||||
|   |  | ||||||
|  static void |  | ||||||
| @@ -52,10 +51,6 @@ cleanup_json_t_decref (void *ptr)
 |  | ||||||
|    json_decref (* (json_t **) ptr); |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| -#else
 |  | ||||||
| -#define CLEANUP_JSON_T_DECREF
 |  | ||||||
| -#endif
 |  | ||||||
| -
 |  | ||||||
|  static json_t *get_json_output (guestfs_h *g, const char *filename); |  | ||||||
|  static int qemu_img_supports_U_option (guestfs_h *g); |  | ||||||
|  static void set_child_rlimits (struct command *); |  | ||||||
| diff --git a/lib/launch-libvirt.c b/lib/launch-libvirt.c
 |  | ||||||
| index fed6dcc8..d01f6578 100644
 |  | ||||||
| --- a/lib/launch-libvirt.c
 |  | ||||||
| +++ b/lib/launch-libvirt.c
 |  | ||||||
| @@ -97,7 +97,6 @@ xmlBufferDetach (xmlBufferPtr buf)
 |  | ||||||
|  } |  | ||||||
|  #endif |  | ||||||
|   |  | ||||||
| -#ifdef HAVE_ATTRIBUTE_CLEANUP
 |  | ||||||
|  #define CLEANUP_VIRSECRETFREE __attribute__((cleanup(cleanup_virSecretFree))) |  | ||||||
|   |  | ||||||
|  static void |  | ||||||
| @@ -108,10 +107,6 @@ cleanup_virSecretFree (void *ptr)
 |  | ||||||
|      virSecretFree (secret_obj); |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| -#else /* !HAVE_ATTRIBUTE_CLEANUP */
 |  | ||||||
| -#define CLEANUP_VIRSECRETFREE
 |  | ||||||
| -#endif
 |  | ||||||
| -
 |  | ||||||
|  /* List used to store a mapping of secret to libvirt secret UUID. */ |  | ||||||
|  struct secret { |  | ||||||
|    char *secret; |  | ||||||
| diff --git a/lib/qemu.c b/lib/qemu.c
 |  | ||||||
| index 027790e4..886c92e5 100644
 |  | ||||||
| --- a/lib/qemu.c
 |  | ||||||
| +++ b/lib/qemu.c
 |  | ||||||
| @@ -46,7 +46,6 @@
 |  | ||||||
|  #include "guestfs-internal.h" |  | ||||||
|  #include "guestfs_protocol.h" |  | ||||||
|   |  | ||||||
| -#ifdef HAVE_ATTRIBUTE_CLEANUP
 |  | ||||||
|  #define CLEANUP_JSON_T_DECREF __attribute__((cleanup(cleanup_json_t_decref))) |  | ||||||
|   |  | ||||||
|  static void |  | ||||||
| @@ -55,10 +54,6 @@ cleanup_json_t_decref (void *ptr)
 |  | ||||||
|    json_decref (* (json_t **) ptr); |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| -#else
 |  | ||||||
| -#define CLEANUP_JSON_T_DECREF
 |  | ||||||
| -#endif
 |  | ||||||
| -
 |  | ||||||
|  struct qemu_data { |  | ||||||
|    int generation;               /* MEMO_GENERATION read from qemu.stat */ |  | ||||||
|    uint64_t prev_size;           /* Size of qemu binary when cached. */ |  | ||||||
| diff --git a/m4/guestfs-c.m4 b/m4/guestfs-c.m4
 |  | ||||||
| index 44c64b6d..49109cc8 100644
 |  | ||||||
| --- a/m4/guestfs-c.m4
 |  | ||||||
| +++ b/m4/guestfs-c.m4
 |  | ||||||
| @@ -109,15 +109,12 @@ main (int argc, char *argv[])
 |  | ||||||
|      AC_MSG_RESULT([yes]) |  | ||||||
|      AC_DEFINE([HAVE_ATTRIBUTE_CLEANUP],[1],[Define to 1 if '__attribute__((cleanup(...)))' works with this compiler.]) |  | ||||||
|      ],[ |  | ||||||
| -    AC_MSG_WARN(
 |  | ||||||
| +    AC_MSG_ERROR(
 |  | ||||||
|  ['__attribute__((cleanup(...)))' does not work. |  | ||||||
|   |  | ||||||
|  You may not be using a sufficiently recent version of GCC or CLANG, or |  | ||||||
|  you may be using a C compiler which does not support this attribute, |  | ||||||
| -or the configure test may be wrong.
 |  | ||||||
| -
 |  | ||||||
| -The code will still compile, but is likely to leak memory and other
 |  | ||||||
| -resources when it runs.])])
 |  | ||||||
| +or the configure test may be wrong.])])
 |  | ||||||
|  dnl restore CFLAGS |  | ||||||
|  CFLAGS="${acx_nbdkit_save_CFLAGS}" |  | ||||||
|   |  | ||||||
| @ -1,8 +1,8 @@ | |||||||
| From 0212c0fe22d0da787ca906d32d31f8b6d3e3ae3f Mon Sep 17 00:00:00 2001 | From cb2ac63562447e2780bd7103ed060fd6013b9054 Mon Sep 17 00:00:00 2001 | ||||||
| From: "Richard W.M. Jones" <rjones@redhat.com> | From: "Richard W.M. Jones" <rjones@redhat.com> | ||||||
| Date: Tue, 7 Jul 2015 09:28:03 -0400 | Date: Tue, 7 Jul 2015 09:28:03 -0400 | ||||||
| Subject: [PATCH] RHEL: Reject use of libguestfs-winsupport features except for | Subject: [PATCH] RHEL 8: Reject use of libguestfs-winsupport features except | ||||||
|  virt-* tools (RHBZ#1240276). |  for virt-* tools (RHBZ#1240276). | ||||||
| 
 | 
 | ||||||
| Fix the tests: it doesn't let us use guestfish for arbitrary Windows | Fix the tests: it doesn't let us use guestfish for arbitrary Windows | ||||||
| edits. | edits. | ||||||
| @ -13,14 +13,14 @@ edits. | |||||||
|  3 files changed, 19 insertions(+) |  3 files changed, 19 insertions(+) | ||||||
| 
 | 
 | ||||||
| diff --git a/generator/c.ml b/generator/c.ml
 | diff --git a/generator/c.ml b/generator/c.ml
 | ||||||
| index 838e7f42..09181028 100644
 | index 86d3b26f8..a625361a9 100644
 | ||||||
| --- a/generator/c.ml
 | --- a/generator/c.ml
 | ||||||
| +++ b/generator/c.ml
 | +++ b/generator/c.ml
 | ||||||
| @@ -1836,6 +1836,22 @@ and generate_client_actions actions () =
 | @@ -1846,6 +1846,22 @@ and generate_client_actions actions () =
 | ||||||
|      check_args_validity c_name style; |      check_args_validity c_name style; | ||||||
|      trace_call name c_name style; |      trace_call name c_name style; | ||||||
|   |   | ||||||
| +    (* RHEL *)
 | +    (* RHEL 8 *)
 | ||||||
| +    if name = "mount" || name = "mount_ro" || name = "mount_options" ||
 | +    if name = "mount" || name = "mount_ro" || name = "mount_options" ||
 | ||||||
| +       name = "mount_vfs" then (
 | +       name = "mount_vfs" then (
 | ||||||
| +      pr "  if (g->program && !STRPREFIX (g->program, \"virt-\")) {\n";
 | +      pr "  if (g->program && !STRPREFIX (g->program, \"virt-\")) {\n";
 | ||||||
| @ -40,7 +40,7 @@ index 838e7f42..09181028 100644 | |||||||
|       * as a progress bar hint. |       * 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
 | diff --git a/test-data/phony-guests/make-windows-img.sh b/test-data/phony-guests/make-windows-img.sh
 | ||||||
| index 16debd12..1c13ddac 100755
 | index 30908a918..73cf5144e 100755
 | ||||||
| --- a/test-data/phony-guests/make-windows-img.sh
 | --- a/test-data/phony-guests/make-windows-img.sh
 | ||||||
| +++ b/test-data/phony-guests/make-windows-img.sh
 | +++ b/test-data/phony-guests/make-windows-img.sh
 | ||||||
| @@ -37,6 +37,7 @@ fi
 | @@ -37,6 +37,7 @@ fi
 | ||||||
| @ -52,10 +52,10 @@ index 16debd12..1c13ddac 100755 | |||||||
|  run |  run | ||||||
|   |   | ||||||
| diff --git a/tests/charsets/test-charset-fidelity.c b/tests/charsets/test-charset-fidelity.c
 | diff --git a/tests/charsets/test-charset-fidelity.c b/tests/charsets/test-charset-fidelity.c
 | ||||||
| index 105291dc..5ca4f3b6 100644
 | index 39ccc2068..2b2e2d8a9 100644
 | ||||||
| --- a/tests/charsets/test-charset-fidelity.c
 | --- a/tests/charsets/test-charset-fidelity.c
 | ||||||
| +++ b/tests/charsets/test-charset-fidelity.c
 | +++ b/tests/charsets/test-charset-fidelity.c
 | ||||||
| @@ -96,6 +96,8 @@ main (int argc, char *argv[])
 | @@ -94,6 +94,8 @@ main (int argc, char *argv[])
 | ||||||
|    if (g == NULL) |    if (g == NULL) | ||||||
|      error (EXIT_FAILURE, 0, "failed to create handle"); |      error (EXIT_FAILURE, 0, "failed to create handle"); | ||||||
|   |   | ||||||
| @ -64,3 +64,6 @@ index 105291dc..5ca4f3b6 100644 | |||||||
|    if (guestfs_add_drive_scratch (g, 1024*1024*1024, -1) == -1) |    if (guestfs_add_drive_scratch (g, 1024*1024*1024, -1) == -1) | ||||||
|      exit (EXIT_FAILURE); |      exit (EXIT_FAILURE); | ||||||
|   |   | ||||||
|  | -- 
 | ||||||
|  | 2.31.1 | ||||||
|  | 
 | ||||||
| @ -1,53 +0,0 @@ | |||||||
| From 53632b4b8245a6dd67c95015d52d1f4c562b14ed Mon Sep 17 00:00:00 2001 |  | ||||||
| From: "Richard W.M. Jones" <rjones@redhat.com> |  | ||||||
| Date: Mon, 21 Oct 2024 11:50:05 +0100 |  | ||||||
| Subject: [PATCH] appliance: Use stable owner, group and mtime in appliance |  | ||||||
|  tarballs |  | ||||||
| 
 |  | ||||||
| Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=2320025 |  | ||||||
| Signed-off-by: Richard W.M. Jones <rjones@redhat.com> |  | ||||||
| ---
 |  | ||||||
|  appliance/Makefile.am | 11 ++++++++--- |  | ||||||
|  1 file changed, 8 insertions(+), 3 deletions(-) |  | ||||||
| 
 |  | ||||||
| diff --git a/appliance/Makefile.am b/appliance/Makefile.am
 |  | ||||||
| index 8cb9bd1f..7edc90e6 100644
 |  | ||||||
| --- a/appliance/Makefile.am
 |  | ||||||
| +++ b/appliance/Makefile.am
 |  | ||||||
| @@ -113,12 +113,17 @@ packagelist: packagelist.in Makefile guestfsd.deps
 |  | ||||||
|  	cmp -s $@ $@-t || mv $@-t $@ |  | ||||||
|  	rm -f $@-t |  | ||||||
|   |  | ||||||
| +# Use stable times and owner/group (RHBZ#2320025).
 |  | ||||||
| +TAR_COMMAND := tar -z \
 |  | ||||||
| +	--owner=0 --group=0 \
 |  | ||||||
| +	$${SOURCE_DATE_EPOCH:+--mtime=@"$$SOURCE_DATE_EPOCH"}
 |  | ||||||
| +
 |  | ||||||
|  supermin.d/daemon.tar.gz: ../daemon/guestfsd |  | ||||||
|  	rm -f $@ $@-t |  | ||||||
|  	rm -rf tmp-d |  | ||||||
|  	mkdir -p tmp-d$(DAEMON_SUPERMIN_DIR) tmp-d/etc |  | ||||||
|  	ln ../daemon/guestfsd tmp-d$(DAEMON_SUPERMIN_DIR)/guestfsd |  | ||||||
| -	( cd tmp-d && tar zcf - * ) > $@-t
 |  | ||||||
| +	( cd tmp-d && $(TAR_COMMAND) -cf - * ) > $@-t
 |  | ||||||
|  	rm -r tmp-d |  | ||||||
|  	mv $@-t $@ |  | ||||||
|   |  | ||||||
| @@ -139,7 +144,7 @@ supermin.d/hostfiles: hostfiles.in Makefile
 |  | ||||||
|   |  | ||||||
|  supermin.d/init.tar.gz: init |  | ||||||
|  	rm -f $@ $@-t |  | ||||||
| -	( cd $(srcdir) && tar zcf - init ) > $@-t
 |  | ||||||
| +	( cd $(srcdir) && $(TAR_COMMAND) -cf - init ) > $@-t
 |  | ||||||
|  	mv $@-t $@ |  | ||||||
|   |  | ||||||
|  # We should put this file in /lib/udev/rules.d, but put it in /etc so |  | ||||||
| @@ -149,7 +154,7 @@ supermin.d/udev-rules.tar.gz: 99-guestfs-serial.rules
 |  | ||||||
|  	rm -rf tmp-u |  | ||||||
|  	mkdir -p tmp-u/etc/udev/rules.d |  | ||||||
|  	for f in $^; do ln $$f tmp-u/etc/udev/rules.d/$$(basename $$f); done |  | ||||||
| -	( cd tmp-u && tar zcf - etc ) > $@-t
 |  | ||||||
| +	( cd tmp-u && $(TAR_COMMAND) -cf - etc ) > $@-t
 |  | ||||||
|  	rm -r tmp-u |  | ||||||
|  	mv $@-t $@ |  | ||||||
|   |  | ||||||
| @ -1,55 +0,0 @@ | |||||||
| From 798e3e59b2af5057521c170268c03ab88aaf1307 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: "Richard W.M. Jones" <rjones@redhat.com> |  | ||||||
| Date: Tue, 22 Oct 2024 09:14:15 +0100 |  | ||||||
| Subject: [PATCH] appliance: Refactor the TAR_COMMAND macro |  | ||||||
| 
 |  | ||||||
| No change, just make it easier to understand. |  | ||||||
| 
 |  | ||||||
| Updates: commit 53632b4b8245a6dd67c95015d52d1f4c562b14ed |  | ||||||
| ---
 |  | ||||||
|  appliance/Makefile.am | 11 ++++++----- |  | ||||||
|  1 file changed, 6 insertions(+), 5 deletions(-) |  | ||||||
| 
 |  | ||||||
| diff --git a/appliance/Makefile.am b/appliance/Makefile.am
 |  | ||||||
| index 7edc90e6..ce994035 100644
 |  | ||||||
| --- a/appliance/Makefile.am
 |  | ||||||
| +++ b/appliance/Makefile.am
 |  | ||||||
| @@ -113,8 +113,9 @@ packagelist: packagelist.in Makefile guestfsd.deps
 |  | ||||||
|  	cmp -s $@ $@-t || mv $@-t $@ |  | ||||||
|  	rm -f $@-t |  | ||||||
|   |  | ||||||
| -# Use stable times and owner/group (RHBZ#2320025).
 |  | ||||||
| -TAR_COMMAND := tar -z \
 |  | ||||||
| +# Use stable owner/group and mtimes (RHBZ#2320025).
 |  | ||||||
| +TAR_OPTIONS := \
 |  | ||||||
| +	-z \
 |  | ||||||
|  	--owner=0 --group=0 \ |  | ||||||
|  	$${SOURCE_DATE_EPOCH:+--mtime=@"$$SOURCE_DATE_EPOCH"} |  | ||||||
|   |  | ||||||
| @@ -123,7 +124,7 @@ supermin.d/daemon.tar.gz: ../daemon/guestfsd
 |  | ||||||
|  	rm -rf tmp-d |  | ||||||
|  	mkdir -p tmp-d$(DAEMON_SUPERMIN_DIR) tmp-d/etc |  | ||||||
|  	ln ../daemon/guestfsd tmp-d$(DAEMON_SUPERMIN_DIR)/guestfsd |  | ||||||
| -	( cd tmp-d && $(TAR_COMMAND) -cf - * ) > $@-t
 |  | ||||||
| +	( cd tmp-d && tar $(TAR_OPTIONS) -cf - * ) > $@-t
 |  | ||||||
|  	rm -r tmp-d |  | ||||||
|  	mv $@-t $@ |  | ||||||
|   |  | ||||||
| @@ -144,7 +145,7 @@ supermin.d/hostfiles: hostfiles.in Makefile
 |  | ||||||
|   |  | ||||||
|  supermin.d/init.tar.gz: init |  | ||||||
|  	rm -f $@ $@-t |  | ||||||
| -	( cd $(srcdir) && $(TAR_COMMAND) -cf - init ) > $@-t
 |  | ||||||
| +	( cd $(srcdir) && tar $(TAR_OPTIONS) -cf - init ) > $@-t
 |  | ||||||
|  	mv $@-t $@ |  | ||||||
|   |  | ||||||
|  # We should put this file in /lib/udev/rules.d, but put it in /etc so |  | ||||||
| @@ -154,7 +155,7 @@ supermin.d/udev-rules.tar.gz: 99-guestfs-serial.rules
 |  | ||||||
|  	rm -rf tmp-u |  | ||||||
|  	mkdir -p tmp-u/etc/udev/rules.d |  | ||||||
|  	for f in $^; do ln $$f tmp-u/etc/udev/rules.d/$$(basename $$f); done |  | ||||||
| -	( cd tmp-u && $(TAR_COMMAND) -cf - etc ) > $@-t
 |  | ||||||
| +	( cd tmp-u && tar $(TAR_OPTIONS) -cf - etc ) > $@-t
 |  | ||||||
|  	rm -r tmp-u |  | ||||||
|  	mv $@-t $@ |  | ||||||
|   |  | ||||||
| @ -0,0 +1,37 @@ | |||||||
|  | From dbd1eaab6a478cf0c3ea093a56b3d04c29278615 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: "Richard W.M. Jones" <rjones@redhat.com> | ||||||
|  | Date: Tue, 12 Jan 2021 10:23:11 +0000 | ||||||
|  | Subject: [PATCH] build: Avoid warnings about unknown pragmas. | ||||||
|  | 
 | ||||||
|  | In commit 4bbbf03b8bc266ed2b63c461cd0945250bb134fe we started to | ||||||
|  | ignore bogus GCC 11 warnings.  Unfortunately earlier versions of GCC | ||||||
|  | don't know about those pragmas so give warnings [hence errors in | ||||||
|  | developer builds] like: | ||||||
|  | 
 | ||||||
|  | tsk.c:75:32: error: unknown option after '#pragma GCC diagnostic' kind [-Werror=pragmas] | ||||||
|  | 
 | ||||||
|  | Turn off these warnings. | ||||||
|  | 
 | ||||||
|  | Updates: commit 4bbbf03b8bc266ed2b63c461cd0945250bb134fe | ||||||
|  | (cherry picked from commit 812f837c97f48ce0c26a0e02286fb9180c282923) | ||||||
|  | ---
 | ||||||
|  |  m4/guestfs-c.m4 | 3 +++ | ||||||
|  |  1 file changed, 3 insertions(+) | ||||||
|  | 
 | ||||||
|  | diff --git a/m4/guestfs-c.m4 b/m4/guestfs-c.m4
 | ||||||
|  | index 25ffea0d9..bbb4db464 100644
 | ||||||
|  | --- a/m4/guestfs-c.m4
 | ||||||
|  | +++ b/m4/guestfs-c.m4
 | ||||||
|  | @@ -108,6 +108,9 @@ gl_WARN_ADD([-Wformat-truncation=1])
 | ||||||
|  |  dnl GCC 9 at level 2 gives apparently bogus errors when %.*s is used. | ||||||
|  |  gl_WARN_ADD([-Wformat-overflow=1]) | ||||||
|  |   | ||||||
|  | +dnl GCC < 11 gives warnings when disabling GCC 11 warnings.
 | ||||||
|  | +gl_WARN_ADD([-Wno-pragmas])
 | ||||||
|  | +
 | ||||||
|  |  AC_SUBST([WARN_CFLAGS]) | ||||||
|  |   | ||||||
|  |  NO_SNV_CFLAGS= | ||||||
|  | -- 
 | ||||||
|  | 2.31.1 | ||||||
|  | 
 | ||||||
| @ -1,45 +0,0 @@ | |||||||
| From 53872a0a1a267040677572c30b68bd1e8b62ebe3 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: "Richard W.M. Jones" <rjones@redhat.com> |  | ||||||
| Date: Tue, 22 Oct 2024 11:01:25 +0100 |  | ||||||
| Subject: [PATCH] build: Add new dependency on json-c |  | ||||||
| 
 |  | ||||||
| This will eventually replace Jansson for all JSON parsing.  However |  | ||||||
| this commit simply introduces the new dependency in the configure |  | ||||||
| script and documents it. |  | ||||||
| 
 |  | ||||||
| I chose json-c 0.14 as the baseline since that is the version in RHEL 9. |  | ||||||
| Probably earlier versions would work. |  | ||||||
| ---
 |  | ||||||
|  docs/guestfs-building.pod | 4 ++++ |  | ||||||
|  m4/guestfs-libraries.m4   | 3 +++ |  | ||||||
|  2 files changed, 7 insertions(+) |  | ||||||
| 
 |  | ||||||
| diff --git a/docs/guestfs-building.pod b/docs/guestfs-building.pod
 |  | ||||||
| index 2c084521..de175aaf 100644
 |  | ||||||
| --- a/docs/guestfs-building.pod
 |  | ||||||
| +++ b/docs/guestfs-building.pod
 |  | ||||||
| @@ -189,6 +189,10 @@ I<Required>.
 |  | ||||||
|   |  | ||||||
|  I<Required>. |  | ||||||
|   |  | ||||||
| +=item json-c E<ge> 0.14
 |  | ||||||
| +
 |  | ||||||
| +I<Required>.
 |  | ||||||
| +
 |  | ||||||
|  =item po4a |  | ||||||
|   |  | ||||||
|  I<Required> if compiling from git. |  | ||||||
| diff --git a/m4/guestfs-libraries.m4 b/m4/guestfs-libraries.m4
 |  | ||||||
| index 18c4cd30..ee406d27 100644
 |  | ||||||
| --- a/m4/guestfs-libraries.m4
 |  | ||||||
| +++ b/m4/guestfs-libraries.m4
 |  | ||||||
| @@ -304,6 +304,9 @@ LIBS="$old_LIBS"
 |  | ||||||
|  dnl Check for Jansson JSON library (required). |  | ||||||
|  PKG_CHECK_MODULES([JANSSON], [jansson >= 2.7]) |  | ||||||
|   |  | ||||||
| +dnl Check for JSON-C library (required).
 |  | ||||||
| +PKG_CHECK_MODULES([JSON_C], [json-c >= 0.14])
 |  | ||||||
| +
 |  | ||||||
|  dnl Check for C++ (optional, we just use this to test the header works). |  | ||||||
|  AC_PROG_CXX |  | ||||||
|   |  | ||||||
| @ -0,0 +1,94 @@ | |||||||
|  | From 22416a2329ec531b9608c21b11ff3d53275fe7a0 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: "Richard W.M. Jones" <rjones@redhat.com> | ||||||
|  | Date: Mon, 22 Feb 2021 10:18:45 +0000 | ||||||
|  | Subject: [PATCH] daemon: lvm: Use lvcreate --yes to avoid interactive prompts. | ||||||
|  | 
 | ||||||
|  | See https://bugzilla.redhat.com/show_bug.cgi?id=1930996#c1 | ||||||
|  | 
 | ||||||
|  | Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1930996 | ||||||
|  | (cherry picked from commit 21cd97732c4973db835b8b6540c8ad582ebd2bda) | ||||||
|  | ---
 | ||||||
|  |  daemon/lvm.c                     |  2 +- | ||||||
|  |  tests/regressions/Makefile.am    |  2 ++ | ||||||
|  |  tests/regressions/rhbz1930996.sh | 36 ++++++++++++++++++++++++++++++++ | ||||||
|  |  3 files changed, 39 insertions(+), 1 deletion(-) | ||||||
|  |  create mode 100755 tests/regressions/rhbz1930996.sh | ||||||
|  | 
 | ||||||
|  | diff --git a/daemon/lvm.c b/daemon/lvm.c
 | ||||||
|  | index 841dc4b6b..72c59c3a1 100644
 | ||||||
|  | --- a/daemon/lvm.c
 | ||||||
|  | +++ b/daemon/lvm.c
 | ||||||
|  | @@ -219,7 +219,7 @@ do_lvcreate (const char *logvol, const char *volgroup, int mbytes)
 | ||||||
|  |    snprintf (size, sizeof size, "%d", mbytes); | ||||||
|  |   | ||||||
|  |    r = command (NULL, &err, | ||||||
|  | -               "lvm", "lvcreate",
 | ||||||
|  | +               "lvm", "lvcreate", "--yes",
 | ||||||
|  |                 "-L", size, "-n", logvol, volgroup, NULL); | ||||||
|  |    if (r == -1) { | ||||||
|  |      reply_with_error ("%s", err); | ||||||
|  | diff --git a/tests/regressions/Makefile.am b/tests/regressions/Makefile.am
 | ||||||
|  | index ecb0d68a7..c1e0ee8a9 100644
 | ||||||
|  | --- a/tests/regressions/Makefile.am
 | ||||||
|  | +++ b/tests/regressions/Makefile.am
 | ||||||
|  | @@ -49,6 +49,7 @@ EXTRA_DIST = \
 | ||||||
|  |  	rhbz1370424.sh \ | ||||||
|  |  	rhbz1370424.xml \ | ||||||
|  |  	rhbz1477623.sh \ | ||||||
|  | +	rhbz1930996.sh \
 | ||||||
|  |  	test-noexec-stack.pl | ||||||
|  |   | ||||||
|  |  TESTS = \ | ||||||
|  | @@ -79,6 +80,7 @@ TESTS = \
 | ||||||
|  |  	rhbz1285847.sh \ | ||||||
|  |  	rhbz1370424.sh \ | ||||||
|  |  	rhbz1477623.sh \ | ||||||
|  | +	rhbz1930996.sh \
 | ||||||
|  |  	test-big-heap \ | ||||||
|  |  	test-noexec-stack.pl \ | ||||||
|  |  	$(SLOW_TESTS) | ||||||
|  | diff --git a/tests/regressions/rhbz1930996.sh b/tests/regressions/rhbz1930996.sh
 | ||||||
|  | new file mode 100755 | ||||||
|  | index 000000000..27089beaa
 | ||||||
|  | --- /dev/null
 | ||||||
|  | +++ b/tests/regressions/rhbz1930996.sh
 | ||||||
|  | @@ -0,0 +1,36 @@
 | ||||||
|  | +#!/bin/bash -
 | ||||||
|  | +# libguestfs
 | ||||||
|  | +# Copyright (C) 2017-2021 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.
 | ||||||
|  | +
 | ||||||
|  | +# Regression test for:
 | ||||||
|  | +# https://bugzilla.redhat.com/show_bug.cgi?id=1930996#c1
 | ||||||
|  | +#
 | ||||||
|  | +# Actually a bug/change in LVM, previously we failed to create an LV
 | ||||||
|  | +# if the underlying disk contained a filesystem signature.
 | ||||||
|  | +
 | ||||||
|  | +set -e
 | ||||||
|  | +
 | ||||||
|  | +$TEST_FUNCTIONS
 | ||||||
|  | +skip_if_skipped
 | ||||||
|  | +skip_unless_phony_guest fedora.img
 | ||||||
|  | +
 | ||||||
|  | +f=rhbz1930996.img
 | ||||||
|  | +rm -f $f
 | ||||||
|  | +
 | ||||||
|  | +guestfish -N $f=lvfs vgremove VG : vgcreate VG /dev/sda1 : lvcreate LV2 VG 100
 | ||||||
|  | +
 | ||||||
|  | +rm $f
 | ||||||
|  | -- 
 | ||||||
|  | 2.31.1 | ||||||
|  | 
 | ||||||
| @ -1,231 +0,0 @@ | |||||||
| From 5ea1e899e00f49ed27f25697e632d864760faf96 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: "Richard W.M. Jones" <rjones@redhat.com> |  | ||||||
| Date: Fri, 18 Oct 2024 21:44:13 +0100 |  | ||||||
| Subject: [PATCH] daemon/ldm.c: Replace jansson with json-c |  | ||||||
| 
 |  | ||||||
| ---
 |  | ||||||
|  daemon/Makefile.am |  4 +-- |  | ||||||
|  daemon/ldm.c       | 89 +++++++++++++++++++++++++--------------------- |  | ||||||
|  2 files changed, 51 insertions(+), 42 deletions(-) |  | ||||||
| 
 |  | ||||||
| diff --git a/daemon/Makefile.am b/daemon/Makefile.am
 |  | ||||||
| index bc74b6ef..bb72c024 100644
 |  | ||||||
| --- a/daemon/Makefile.am
 |  | ||||||
| +++ b/daemon/Makefile.am
 |  | ||||||
| @@ -225,7 +225,7 @@ guestfsd_LDADD = \
 |  | ||||||
|  	camldaemon.o \ |  | ||||||
|  	$(ACL_LIBS) \ |  | ||||||
|  	$(CAP_LIBS) \ |  | ||||||
| -	$(JANSSON_LIBS) \
 |  | ||||||
| +	$(JSON_C_LIBS) \
 |  | ||||||
|  	$(SELINUX_LIBS) \ |  | ||||||
|  	$(AUGEAS_LIBS) \ |  | ||||||
|  	$(HIVEX_LIBS) \ |  | ||||||
| @@ -264,7 +264,7 @@ guestfsd_CFLAGS = \
 |  | ||||||
|  	$(AUGEAS_CFLAGS) \ |  | ||||||
|  	$(HIVEX_CFLAGS) \ |  | ||||||
|  	$(SD_JOURNAL_CFLAGS) \ |  | ||||||
| -	$(JANSSON_CFLAGS) \
 |  | ||||||
| +	$(JSON_C_CFLAGS) \
 |  | ||||||
|  	$(PCRE2_CFLAGS) \ |  | ||||||
|  	$(LIBRPM_CFLAGS) |  | ||||||
|   |  | ||||||
| diff --git a/daemon/ldm.c b/daemon/ldm.c
 |  | ||||||
| index be4fb970..1488b925 100644
 |  | ||||||
| --- a/daemon/ldm.c
 |  | ||||||
| +++ b/daemon/ldm.c
 |  | ||||||
| @@ -25,7 +25,7 @@
 |  | ||||||
|  #include <sys/stat.h> |  | ||||||
|  #include <string.h> |  | ||||||
|   |  | ||||||
| -#include <jansson.h>
 |  | ||||||
| +#include <json.h>
 |  | ||||||
|   |  | ||||||
|  #include "daemon.h" |  | ||||||
|  #include "actions.h" |  | ||||||
| @@ -65,44 +65,54 @@ do_ldmtool_remove_all (void)
 |  | ||||||
|    return 0; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| -static json_t *
 |  | ||||||
| -parse_json (const char *json, const char *func)
 |  | ||||||
| +static json_object *
 |  | ||||||
| +parse_json (const char *json, const char *caller)
 |  | ||||||
|  { |  | ||||||
| -  json_t *tree;
 |  | ||||||
| -  json_error_t err;
 |  | ||||||
| +  json_object *tree = NULL;
 |  | ||||||
| +  json_tokener *tok = NULL;
 |  | ||||||
| +  enum json_tokener_error err;
 |  | ||||||
|   |  | ||||||
|    if (verbose) |  | ||||||
| -    fprintf (stderr, "%s: parsing json: %s\n", func, json);
 |  | ||||||
| +    fprintf (stderr, "%s: parsing json: %s\n", caller, json);
 |  | ||||||
|   |  | ||||||
| -  tree = json_loads (json, 0, &err);
 |  | ||||||
| -  if (tree == NULL) {
 |  | ||||||
| -    reply_with_error ("parse error: %s",
 |  | ||||||
| -                      strlen (err.text) ? err.text : "unknown error");
 |  | ||||||
| +  tok = json_tokener_new ();
 |  | ||||||
| +  json_tokener_set_flags (tok,
 |  | ||||||
| +                          JSON_TOKENER_STRICT | JSON_TOKENER_VALIDATE_UTF8);
 |  | ||||||
| +  tree = json_tokener_parse_ex (tok, json, strlen (json));
 |  | ||||||
| +  err = json_tokener_get_error (tok);
 |  | ||||||
| +  if (err != json_tokener_success) {
 |  | ||||||
| +    reply_with_error ("%s: parse error: %s",
 |  | ||||||
| +                      caller, json_tokener_error_desc (err));
 |  | ||||||
| +    json_tokener_free (tok);
 |  | ||||||
|      return NULL; |  | ||||||
|    } |  | ||||||
|   |  | ||||||
| -  /* Caller should free this by doing 'json_decref (tree);'. */
 |  | ||||||
| +  json_tokener_free (tok);
 |  | ||||||
| +
 |  | ||||||
| +  /* Caller should free this by doing json_object_put (tree). */
 |  | ||||||
|    return tree; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|  #define TYPE_ERROR ((char **) -1) |  | ||||||
|   |  | ||||||
|  static char ** |  | ||||||
| -json_value_to_string_list (json_t *node)
 |  | ||||||
| +json_value_to_string_list (json_object *node)
 |  | ||||||
|  { |  | ||||||
|    CLEANUP_FREE_STRINGSBUF DECLARE_STRINGSBUF (strs); |  | ||||||
| -  json_t *n;
 |  | ||||||
| +  json_object *n;
 |  | ||||||
|    size_t i; |  | ||||||
|   |  | ||||||
| -  if (!json_is_array (node))
 |  | ||||||
| +  if (json_object_get_type (node) != json_type_array)
 |  | ||||||
|      return TYPE_ERROR; |  | ||||||
|   |  | ||||||
| -  json_array_foreach (node, i, n) {
 |  | ||||||
| -    if (!json_is_string (n))
 |  | ||||||
| +  for (i = 0; i < json_object_array_length (node); ++i) {
 |  | ||||||
| +    n = json_object_array_get_idx (node, i); /* Doesn't incr the refcount. */
 |  | ||||||
| +    if (json_object_get_type (n) != json_type_string)
 |  | ||||||
|        return TYPE_ERROR; |  | ||||||
| -    if (add_string (&strs, json_string_value (n)) == -1)
 |  | ||||||
| +    if (add_string (&strs, json_object_get_string (n)) == -1)
 |  | ||||||
|        return NULL; |  | ||||||
|    } |  | ||||||
| +
 |  | ||||||
|    if (end_stringsbuf (&strs) == -1) |  | ||||||
|      return NULL; |  | ||||||
|   |  | ||||||
| @@ -111,17 +121,17 @@ json_value_to_string_list (json_t *node)
 |  | ||||||
|   |  | ||||||
|  static char ** |  | ||||||
|  parse_json_get_string_list (const char *json, |  | ||||||
| -                            const char *func, const char *cmd)
 |  | ||||||
| +                            const char *caller, const char *cmd)
 |  | ||||||
|  { |  | ||||||
|    char **ret; |  | ||||||
| -  json_t *tree = NULL;
 |  | ||||||
| +  json_object *tree = NULL;
 |  | ||||||
|   |  | ||||||
| -  tree = parse_json (json, func);
 |  | ||||||
| +  tree = parse_json (json, caller);
 |  | ||||||
|    if (tree == NULL) |  | ||||||
|      return NULL; |  | ||||||
|   |  | ||||||
|    ret = json_value_to_string_list (tree); |  | ||||||
| -  json_decref (tree);
 |  | ||||||
| +  json_object_put (tree);
 |  | ||||||
|    if (ret == TYPE_ERROR) { |  | ||||||
|      reply_with_error ("output of '%s' was not a JSON array of strings", cmd); |  | ||||||
|      return NULL; |  | ||||||
| @@ -133,74 +143,73 @@ parse_json_get_string_list (const char *json,
 |  | ||||||
|   |  | ||||||
|  static char * |  | ||||||
|  parse_json_get_object_string (const char *json, const char *key, int flags, |  | ||||||
| -                              const char *func, const char *cmd)
 |  | ||||||
| +                              const char *caller, const char *cmd)
 |  | ||||||
|  { |  | ||||||
|    const char *str; |  | ||||||
|    char *ret; |  | ||||||
| -  json_t *tree = NULL, *node;
 |  | ||||||
| +  json_object *tree = NULL, *node;
 |  | ||||||
|   |  | ||||||
| -  tree = parse_json (json, func);
 |  | ||||||
| +  tree = parse_json (json, caller);
 |  | ||||||
|    if (tree == NULL) |  | ||||||
|      return NULL; |  | ||||||
|   |  | ||||||
| -  if (!json_is_object (tree))
 |  | ||||||
| +  if (json_object_get_type (tree) != json_type_object)
 |  | ||||||
|      goto bad_type; |  | ||||||
|   |  | ||||||
| -  node = json_object_get (tree, key);
 |  | ||||||
| +  node = json_object_object_get (tree, key);
 |  | ||||||
|    if (node == NULL) |  | ||||||
|      goto bad_type; |  | ||||||
|   |  | ||||||
| -  if ((flags & GET_STRING_NULL_TO_EMPTY) && json_is_null (node))
 |  | ||||||
| +  if ((flags & GET_STRING_NULL_TO_EMPTY) &&
 |  | ||||||
| +      json_object_get_type (node) == json_type_null)
 |  | ||||||
|      ret = strdup (""); |  | ||||||
|    else { |  | ||||||
| -    str = json_string_value (node);
 |  | ||||||
| -    if (str == NULL)
 |  | ||||||
| -      goto bad_type;
 |  | ||||||
| -    ret = strndup (str, json_string_length (node));
 |  | ||||||
| +    str = json_object_get_string (node);
 |  | ||||||
| +    ret = strndup (str, strlen (str));
 |  | ||||||
|    } |  | ||||||
|    if (ret == NULL) |  | ||||||
|      reply_with_perror ("strdup"); |  | ||||||
|   |  | ||||||
| -  json_decref (tree);
 |  | ||||||
| +  json_object_put (tree);
 |  | ||||||
|   |  | ||||||
|    return ret; |  | ||||||
|   |  | ||||||
|   bad_type: |  | ||||||
|    reply_with_error ("output of '%s' was not a JSON object " |  | ||||||
|                      "containing a key '%s' of type string", cmd, key); |  | ||||||
| -  json_decref (tree);
 |  | ||||||
| +  json_object_put (tree);
 |  | ||||||
|    return NULL; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|  static char ** |  | ||||||
|  parse_json_get_object_string_list (const char *json, const char *key, |  | ||||||
| -                                   const char *func, const char *cmd)
 |  | ||||||
| +                                   const char *caller, const char *cmd)
 |  | ||||||
|  { |  | ||||||
|    char **ret; |  | ||||||
| -  json_t *tree, *node;
 |  | ||||||
| +  json_object *tree, *node;
 |  | ||||||
|   |  | ||||||
| -  tree = parse_json (json, func);
 |  | ||||||
| +  tree = parse_json (json, caller);
 |  | ||||||
|    if (tree == NULL) |  | ||||||
|      return NULL; |  | ||||||
|   |  | ||||||
| -  if (!json_is_object (tree))
 |  | ||||||
| +  if (json_object_get_type (tree) != json_type_object)
 |  | ||||||
|      goto bad_type; |  | ||||||
|   |  | ||||||
| -  node = json_object_get (tree, key);
 |  | ||||||
| +  node = json_object_object_get (tree, key);
 |  | ||||||
|    if (node == NULL) |  | ||||||
|      goto bad_type; |  | ||||||
|   |  | ||||||
|    ret = json_value_to_string_list (node); |  | ||||||
|    if (ret == TYPE_ERROR) |  | ||||||
|      goto bad_type; |  | ||||||
| -  json_decref (tree);
 |  | ||||||
| +  json_object_put (tree);
 |  | ||||||
|    return ret; |  | ||||||
|   |  | ||||||
|   bad_type: |  | ||||||
|    reply_with_error ("output of '%s' was not a JSON object " |  | ||||||
|                      "containing a key '%s' of type array of strings", |  | ||||||
|                      cmd, key); |  | ||||||
| -  json_decref (tree);
 |  | ||||||
| +  json_object_put (tree);
 |  | ||||||
|    return NULL; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| @ -0,0 +1,113 @@ | |||||||
|  | From e1b339688e5f8f2a14fe0c7e9d02ad68004e4655 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: "Richard W.M. Jones" <rjones@redhat.com> | ||||||
|  | Date: Thu, 15 Apr 2021 09:18:22 +0100 | ||||||
|  | Subject: [PATCH] inspection: More reliable detection of Linux split /usr | ||||||
|  |  configurations | ||||||
|  | 
 | ||||||
|  | In RHEL 8+, /usr/etc no longer exists.  Since we were looking for this | ||||||
|  | directory in order to detect a separate /usr partition, those were no | ||||||
|  | longer detected, so the merging of /usr data into the root was not | ||||||
|  | being done.  The result was incomplete inspection data and failure of | ||||||
|  | virt-v2v. | ||||||
|  | 
 | ||||||
|  | All Linux systems since forever have had /usr/src but not /src, so | ||||||
|  | detect this instead. | ||||||
|  | 
 | ||||||
|  | Furthermore the merging code didn't work, because we expected that the | ||||||
|  | root filesystem had a distro assigned, but in this configuration we | ||||||
|  | may need to look for that information in /usr/lib/os-release (not on | ||||||
|  | the root filesystem).  This change makes the merging work even if we | ||||||
|  | have incomplete information about the root filesystem, so long as we | ||||||
|  | have an /etc/fstab entry pointing to the /usr mountpoint. | ||||||
|  | 
 | ||||||
|  | Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1949683 | ||||||
|  | Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1930133 | ||||||
|  | Fixes: commit 394d11be49121884295e61964ed47f5a8488c252 | ||||||
|  | (cherry picked from commit 26427b9ecc64e7e5e53a1d577cef9dc080d08877) | ||||||
|  | ---
 | ||||||
|  |  daemon/inspect.ml    | 33 +++++++++++++++------------------ | ||||||
|  |  daemon/inspect_fs.ml |  6 +++--- | ||||||
|  |  2 files changed, 18 insertions(+), 21 deletions(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/daemon/inspect.ml b/daemon/inspect.ml
 | ||||||
|  | index 945a476f6..fb75b4a6c 100644
 | ||||||
|  | --- a/daemon/inspect.ml
 | ||||||
|  | +++ b/daemon/inspect.ml
 | ||||||
|  | @@ -182,11 +182,9 @@ and check_for_duplicated_bsd_root fses =
 | ||||||
|  |  and collect_linux_inspection_info fses = | ||||||
|  |    List.map ( | ||||||
|  |      function | ||||||
|  | -    | { role = RoleRoot { distro = Some d } } as root ->
 | ||||||
|  | -       if d <> DISTRO_COREOS then
 | ||||||
|  | -         collect_linux_inspection_info_for fses root
 | ||||||
|  | -       else
 | ||||||
|  | -         root
 | ||||||
|  | +    | { role = RoleRoot { distro = Some DISTRO_COREOS } } as root -> root
 | ||||||
|  | +    | { role = RoleRoot _ } as root ->
 | ||||||
|  | +       collect_linux_inspection_info_for fses root
 | ||||||
|  |      | fs -> fs | ||||||
|  |    ) fses | ||||||
|  |   | ||||||
|  | @@ -196,29 +194,28 @@ and collect_linux_inspection_info fses =
 | ||||||
|  |   * or other ways to identify the OS). | ||||||
|  |   *) | ||||||
|  |  and collect_linux_inspection_info_for fses root = | ||||||
|  | -  let root_distro, root_fstab =
 | ||||||
|  | +  let root_fstab =
 | ||||||
|  |      match root with | ||||||
|  | -    | { role = RoleRoot { distro = Some d; fstab = f } } -> d, f
 | ||||||
|  | +    | { role = RoleRoot { fstab = f } } -> f
 | ||||||
|  |      | _ -> assert false in | ||||||
|  |   | ||||||
|  |    try | ||||||
|  |      let usr = | ||||||
|  |        List.find ( | ||||||
|  |          function | ||||||
|  | -        | { role = RoleUsr { distro = d } }
 | ||||||
|  | -             when d = Some root_distro || d = None -> true
 | ||||||
|  | +        | { role = RoleUsr _; fs_location = usr_mp } ->
 | ||||||
|  | +           (* This checks that this usr is found in the fstab of
 | ||||||
|  | +            * the root filesystem.
 | ||||||
|  | +            *)
 | ||||||
|  | +           List.exists (
 | ||||||
|  | +             fun (mountable, _) ->
 | ||||||
|  | +               usr_mp.mountable = mountable
 | ||||||
|  | +           ) root_fstab
 | ||||||
|  |          | _ -> false | ||||||
|  |        ) fses in | ||||||
|  |   | ||||||
|  | -    let usr_mountable = usr.fs_location.mountable in
 | ||||||
|  | -
 | ||||||
|  | -    (* This checks that [usr] is found in the fstab of the root
 | ||||||
|  | -     * filesystem.  If not, [Not_found] is thrown.
 | ||||||
|  | -     *)
 | ||||||
|  | -    ignore (
 | ||||||
|  | -      List.find (fun (mountable, _) -> usr_mountable = mountable) root_fstab
 | ||||||
|  | -    );
 | ||||||
|  | -
 | ||||||
|  | +    eprintf "collect_linux_inspection_info_for: merging:\n%sinto:\n%s"
 | ||||||
|  | +      (string_of_fs usr) (string_of_fs root);
 | ||||||
|  |      merge usr root; | ||||||
|  |      root | ||||||
|  |    with | ||||||
|  | diff --git a/daemon/inspect_fs.ml b/daemon/inspect_fs.ml
 | ||||||
|  | index 6e00c7083..02b5a0470 100644
 | ||||||
|  | --- a/daemon/inspect_fs.ml
 | ||||||
|  | +++ b/daemon/inspect_fs.ml
 | ||||||
|  | @@ -164,10 +164,10 @@ and check_filesystem mountable =
 | ||||||
|  |      () | ||||||
|  |    ) | ||||||
|  |    (* Linux /usr? *) | ||||||
|  | -  else if Is.is_dir "/etc" &&
 | ||||||
|  | -          Is.is_dir "/bin" &&
 | ||||||
|  | -          Is.is_dir "/share" &&
 | ||||||
|  | +  else if Is.is_dir "/bin" &&
 | ||||||
|  |            Is.is_dir "/local" && | ||||||
|  | +          Is.is_dir "/share" &&
 | ||||||
|  | +          Is.is_dir "/src" &&
 | ||||||
|  |            not (Is.is_file "/etc/fstab") then ( | ||||||
|  |      debug_matching "Linux /usr"; | ||||||
|  |      role := `Usr; | ||||||
|  | -- 
 | ||||||
|  | 2.31.1 | ||||||
|  | 
 | ||||||
| @ -0,0 +1,49 @@ | |||||||
|  | From 791a16b049ea1ce2c450acd367fce774d9aab5b1 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: "Richard W.M. Jones" <rjones@redhat.com> | ||||||
|  | Date: Tue, 31 Aug 2021 08:27:15 +0100 | ||||||
|  | Subject: [PATCH] lib: Autodetect backing format for qemu-img create -b | ||||||
|  | 
 | ||||||
|  | qemu 6.1 has decided to change qemu-img create so that a backing | ||||||
|  | format (-F) is required if a backing file (-b) is specified.  Since we | ||||||
|  | don't want to change the libguestfs API to force callers to specify | ||||||
|  | this because that would be an API break, autodetect it. | ||||||
|  | 
 | ||||||
|  | This is similar to commit c8c181e8d9 ("launch: libvirt: Autodetect | ||||||
|  | backing format for readonly drive overlays"). | ||||||
|  | 
 | ||||||
|  | Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1998820 | ||||||
|  | (cherry picked from commit 45de287447bb18d59749fbfc1ec5072413090109) | ||||||
|  | ---
 | ||||||
|  |  lib/create.c | 9 +++++++++ | ||||||
|  |  1 file changed, 9 insertions(+) | ||||||
|  | 
 | ||||||
|  | diff --git a/lib/create.c b/lib/create.c
 | ||||||
|  | index 44a7df25f..75a4d3a28 100644
 | ||||||
|  | --- a/lib/create.c
 | ||||||
|  | +++ b/lib/create.c
 | ||||||
|  | @@ -255,6 +255,7 @@ disk_create_qcow2 (guestfs_h *g, const char *filename, int64_t size,
 | ||||||
|  |                     const struct guestfs_disk_create_argv *optargs) | ||||||
|  |  { | ||||||
|  |    const char *backingformat = NULL; | ||||||
|  | +  CLEANUP_FREE char *backingformat_free = NULL;
 | ||||||
|  |    const char *preallocation = NULL; | ||||||
|  |    const char *compat = NULL; | ||||||
|  |    int clustersize = -1; | ||||||
|  | @@ -270,6 +271,14 @@ disk_create_qcow2 (guestfs_h *g, const char *filename, int64_t size,
 | ||||||
|  |        return -1; | ||||||
|  |      } | ||||||
|  |    } | ||||||
|  | +  else if (backingfile) {
 | ||||||
|  | +    /* Since qemu 6.1, qemu-img create has requires a backing format (-F)
 | ||||||
|  | +     * parameter if backing file (-b) is used (RHBZ#1998820).
 | ||||||
|  | +     */
 | ||||||
|  | +    backingformat = backingformat_free = guestfs_disk_format (g, backingfile);
 | ||||||
|  | +    if (!backingformat)
 | ||||||
|  | +      return -1;
 | ||||||
|  | +  }
 | ||||||
|  |    if (optargs->bitmask & GUESTFS_DISK_CREATE_PREALLOCATION_BITMASK) { | ||||||
|  |      if (STREQ (optargs->preallocation, "off") || | ||||||
|  |          STREQ (optargs->preallocation, "sparse")) | ||||||
|  | -- 
 | ||||||
|  | 2.31.1 | ||||||
|  | 
 | ||||||
| @ -0,0 +1,44 @@ | |||||||
|  | From 3435938f43ca3737ec1d73da4d8cad756b5c9508 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: "Richard W.M. Jones" <rjones@redhat.com> | ||||||
|  | Date: Fri, 26 Mar 2021 16:04:43 +0000 | ||||||
|  | Subject: [PATCH] daemon: chroot: Fix long-standing possible deadlock. | ||||||
|  | 
 | ||||||
|  | The child (chrooted) process wrote its answer on the pipe and then | ||||||
|  | exited.  Meanwhile the parent waiting for the child to exit before | ||||||
|  | reading from the pipe.  Thus if the output was larger than a Linux | ||||||
|  | pipebuffer then the whole thing would deadlock. | ||||||
|  | 
 | ||||||
|  | (cherry picked from commit 94e64b28bee3b8dc7ed354a366d6a8f7ba5f245c) | ||||||
|  | ---
 | ||||||
|  |  daemon/chroot.ml | 8 ++++---- | ||||||
|  |  1 file changed, 4 insertions(+), 4 deletions(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/daemon/chroot.ml b/daemon/chroot.ml
 | ||||||
|  | index 5e856c91f..7da8ae29e 100644
 | ||||||
|  | --- a/daemon/chroot.ml
 | ||||||
|  | +++ b/daemon/chroot.ml
 | ||||||
|  | @@ -62,6 +62,10 @@ let f t func arg =
 | ||||||
|  |    (* Parent. *) | ||||||
|  |    close wfd; | ||||||
|  |   | ||||||
|  | +  let chan = in_channel_of_descr rfd in
 | ||||||
|  | +  let ret = input_value chan in
 | ||||||
|  | +  close_in chan;
 | ||||||
|  | +
 | ||||||
|  |    let _, status = waitpid [] pid in | ||||||
|  |    (match status with | ||||||
|  |     | WEXITED 0 -> () | ||||||
|  | @@ -76,10 +80,6 @@ let f t func arg =
 | ||||||
|  |        failwithf "chroot ‘%s’ stopped by signal %d" t.name i | ||||||
|  |    ); | ||||||
|  |   | ||||||
|  | -  let chan = in_channel_of_descr rfd in
 | ||||||
|  | -  let ret = input_value chan in
 | ||||||
|  | -  close_in chan;
 | ||||||
|  | -
 | ||||||
|  |    match ret with | ||||||
|  |    | Either ret -> ret | ||||||
|  |    | Or exn -> raise exn | ||||||
|  | -- 
 | ||||||
|  | 2.31.1 | ||||||
|  | 
 | ||||||
| @ -1,214 +0,0 @@ | |||||||
| From 13e3222f3463578ab18ee8efc8502c6dfd9f51a4 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: "Richard W.M. Jones" <rjones@redhat.com> |  | ||||||
| Date: Tue, 22 Oct 2024 15:55:00 +0100 |  | ||||||
| Subject: [PATCH] lib/info.c: Replace jansson with json-c |  | ||||||
| 
 |  | ||||||
| ---
 |  | ||||||
|  lib/Makefile.am |  4 ++- |  | ||||||
|  lib/info.c      | 85 +++++++++++++++++++++++++------------------------ |  | ||||||
|  2 files changed, 47 insertions(+), 42 deletions(-) |  | ||||||
| 
 |  | ||||||
| diff --git a/lib/Makefile.am b/lib/Makefile.am
 |  | ||||||
| index 0ed1576f..60567b04 100644
 |  | ||||||
| --- a/lib/Makefile.am
 |  | ||||||
| +++ b/lib/Makefile.am
 |  | ||||||
| @@ -138,7 +138,8 @@ libguestfs_la_CFLAGS = \
 |  | ||||||
|  	$(PCRE2_CFLAGS) \ |  | ||||||
|  	$(LIBVIRT_CFLAGS) \ |  | ||||||
|  	$(LIBXML2_CFLAGS) \ |  | ||||||
| -	$(JANSSON_CFLAGS)
 |  | ||||||
| +	$(JANSSON_CFLAGS) \
 |  | ||||||
| +	$(JSON_C_CFLAGS)
 |  | ||||||
|   |  | ||||||
|  libguestfs_la_LIBADD = \ |  | ||||||
|  	../common/errnostring/liberrnostring.la \ |  | ||||||
| @@ -150,6 +151,7 @@ libguestfs_la_LIBADD = \
 |  | ||||||
|  	$(LIBVIRT_LIBS) $(LIBXML2_LIBS) \ |  | ||||||
|  	$(SELINUX_LIBS) \ |  | ||||||
|  	$(JANSSON_LIBS) \ |  | ||||||
| +	$(JSON_C_LIBS) \
 |  | ||||||
|  	../gnulib/lib/libgnu.la \ |  | ||||||
|  	$(LIBSOCKET) \ |  | ||||||
|  	$(LIB_CLOCK_GETTIME) \ |  | ||||||
| diff --git a/lib/info.c b/lib/info.c
 |  | ||||||
| index b60fc8b3..f325bfab 100644
 |  | ||||||
| --- a/lib/info.c
 |  | ||||||
| +++ b/lib/info.c
 |  | ||||||
| @@ -37,42 +37,45 @@
 |  | ||||||
|  #include <sys/resource.h> |  | ||||||
|  #endif |  | ||||||
|   |  | ||||||
| -#include <jansson.h>
 |  | ||||||
| +#include <json.h>
 |  | ||||||
|   |  | ||||||
|  #include "guestfs.h" |  | ||||||
|  #include "guestfs-internal.h" |  | ||||||
|  #include "guestfs-internal-actions.h" |  | ||||||
|   |  | ||||||
| -#define CLEANUP_JSON_T_DECREF __attribute__((cleanup(cleanup_json_t_decref)))
 |  | ||||||
| +#define CLEANUP_JSON_OBJECT_PUT \
 |  | ||||||
| +  __attribute__((cleanup(cleanup_json_object_put)))
 |  | ||||||
|   |  | ||||||
|  static void |  | ||||||
| -cleanup_json_t_decref (void *ptr)
 |  | ||||||
| +cleanup_json_object_put (void *ptr)
 |  | ||||||
|  { |  | ||||||
| -  json_decref (* (json_t **) ptr);
 |  | ||||||
| +  json_object_put (* (json_object **) ptr);
 |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| -static json_t *get_json_output (guestfs_h *g, const char *filename);
 |  | ||||||
| +static json_object *get_json_output (guestfs_h *g, const char *filename);
 |  | ||||||
|  static int qemu_img_supports_U_option (guestfs_h *g); |  | ||||||
|  static void set_child_rlimits (struct command *); |  | ||||||
|   |  | ||||||
|  char * |  | ||||||
|  guestfs_impl_disk_format (guestfs_h *g, const char *filename) |  | ||||||
|  { |  | ||||||
| -  CLEANUP_JSON_T_DECREF json_t *tree = get_json_output (g, filename);
 |  | ||||||
| -  json_t *node;
 |  | ||||||
| +  CLEANUP_JSON_OBJECT_PUT json_object *tree = get_json_output (g, filename);
 |  | ||||||
| +  json_object *node;
 |  | ||||||
| +  const char *format;
 |  | ||||||
|   |  | ||||||
|    if (tree == NULL) |  | ||||||
|      return NULL; |  | ||||||
|   |  | ||||||
| -  if (!json_is_object (tree))
 |  | ||||||
| +  if (json_object_get_type (tree) != json_type_object)
 |  | ||||||
|      goto bad_type; |  | ||||||
|   |  | ||||||
| -  node = json_object_get (tree, "format");
 |  | ||||||
| -  if (!json_is_string (node))
 |  | ||||||
| +  node = json_object_object_get (tree, "format");
 |  | ||||||
| +  if (node == NULL)
 |  | ||||||
|      goto bad_type; |  | ||||||
|   |  | ||||||
| -  return safe_strndup (g, json_string_value (node),
 |  | ||||||
| -                          json_string_length (node)); /* caller frees */
 |  | ||||||
| +  format = json_object_get_string (node);
 |  | ||||||
| +
 |  | ||||||
| +  return safe_strdup (g, format); /* caller frees */
 |  | ||||||
|   |  | ||||||
|   bad_type: |  | ||||||
|    error (g, _("qemu-img info: JSON output did not contain ‘format’ key")); |  | ||||||
| @@ -82,20 +85,20 @@ guestfs_impl_disk_format (guestfs_h *g, const char *filename)
 |  | ||||||
|  int64_t |  | ||||||
|  guestfs_impl_disk_virtual_size (guestfs_h *g, const char *filename) |  | ||||||
|  { |  | ||||||
| -  CLEANUP_JSON_T_DECREF json_t *tree = get_json_output (g, filename);
 |  | ||||||
| -  json_t *node;
 |  | ||||||
| +  CLEANUP_JSON_OBJECT_PUT json_object *tree = get_json_output (g, filename);
 |  | ||||||
| +  json_object *node;
 |  | ||||||
|   |  | ||||||
|    if (tree == NULL) |  | ||||||
|      return -1; |  | ||||||
|   |  | ||||||
| -  if (!json_is_object (tree))
 |  | ||||||
| +  if (json_object_get_type (tree) != json_type_object)
 |  | ||||||
|      goto bad_type; |  | ||||||
|   |  | ||||||
| -  node = json_object_get (tree, "virtual-size");
 |  | ||||||
| -  if (!json_is_integer (node))
 |  | ||||||
| +  node = json_object_object_get (tree, "virtual-size");
 |  | ||||||
| +  if (node == NULL)
 |  | ||||||
|      goto bad_type; |  | ||||||
|   |  | ||||||
| -  return json_integer_value (node);
 |  | ||||||
| +  return json_object_get_int64 (node);
 |  | ||||||
|   |  | ||||||
|   bad_type: |  | ||||||
|    error (g, _("qemu-img info: JSON output did not contain ‘virtual-size’ key")); |  | ||||||
| @@ -105,24 +108,18 @@ guestfs_impl_disk_virtual_size (guestfs_h *g, const char *filename)
 |  | ||||||
|  int |  | ||||||
|  guestfs_impl_disk_has_backing_file (guestfs_h *g, const char *filename) |  | ||||||
|  { |  | ||||||
| -  CLEANUP_JSON_T_DECREF json_t *tree = get_json_output (g, filename);
 |  | ||||||
| -  json_t *node;
 |  | ||||||
| +  CLEANUP_JSON_OBJECT_PUT json_object *tree = get_json_output (g, filename);
 |  | ||||||
| +  json_object *node;
 |  | ||||||
|   |  | ||||||
|    if (tree == NULL) |  | ||||||
|      return -1; |  | ||||||
|   |  | ||||||
| -  if (!json_is_object (tree))
 |  | ||||||
| +  if (json_object_get_type (tree) != json_type_object)
 |  | ||||||
|      goto bad_type; |  | ||||||
|   |  | ||||||
| -  node = json_object_get (tree, "backing-filename");
 |  | ||||||
| +  node = json_object_object_get (tree, "backing-filename");
 |  | ||||||
|    if (node == NULL) |  | ||||||
| -    return 0; /* no backing-filename key means no backing file */
 |  | ||||||
| -
 |  | ||||||
| -  /* Work on the assumption that if this field is null, it means
 |  | ||||||
| -   * no backing file, rather than being an error.
 |  | ||||||
| -   */
 |  | ||||||
| -  if (json_is_null (node))
 |  | ||||||
| -    return 0;
 |  | ||||||
| +    return 0; /* no backing-filename key or null means no backing file */
 |  | ||||||
|    return 1; |  | ||||||
|   |  | ||||||
|   bad_type: |  | ||||||
| @@ -136,12 +133,12 @@ guestfs_impl_disk_has_backing_file (guestfs_h *g, const char *filename)
 |  | ||||||
|  static void parse_json (guestfs_h *g, void *treevp, const char *input, size_t len); |  | ||||||
|  #define PARSE_JSON_NO_OUTPUT ((void *) -1) |  | ||||||
|   |  | ||||||
| -static json_t *
 |  | ||||||
| +static json_object *
 |  | ||||||
|  get_json_output (guestfs_h *g, const char *filename) |  | ||||||
|  { |  | ||||||
|    CLEANUP_CMD_CLOSE struct command *cmd = guestfs_int_new_command (g); |  | ||||||
|    int r; |  | ||||||
| -  json_t *tree = NULL;
 |  | ||||||
| +  json_object *tree = NULL;
 |  | ||||||
|   |  | ||||||
|    guestfs_int_cmd_add_arg (cmd, "qemu-img"); |  | ||||||
|    guestfs_int_cmd_add_arg (cmd, "info"); |  | ||||||
| @@ -176,15 +173,16 @@ get_json_output (guestfs_h *g, const char *filename)
 |  | ||||||
|      return NULL; |  | ||||||
|    } |  | ||||||
|   |  | ||||||
| -  return tree;          /* caller must call json_decref (tree) */
 |  | ||||||
| +  return tree;          /* caller must call json_object_put (tree) */
 |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|  /* Parse the JSON document printed by qemu-img info --output json. */ |  | ||||||
|  static void |  | ||||||
|  parse_json (guestfs_h *g, void *treevp, const char *input, size_t len) |  | ||||||
|  { |  | ||||||
| -  json_t **tree_ret = treevp;
 |  | ||||||
| -  json_error_t err;
 |  | ||||||
| +  json_tokener *tok = NULL;
 |  | ||||||
| +  json_object **tree_ret = treevp;
 |  | ||||||
| +  enum json_tokener_error err;
 |  | ||||||
|   |  | ||||||
|    assert (*tree_ret == NULL); |  | ||||||
|   |  | ||||||
| @@ -197,15 +195,20 @@ parse_json (guestfs_h *g, void *treevp, const char *input, size_t len)
 |  | ||||||
|      return; |  | ||||||
|    } |  | ||||||
|   |  | ||||||
| -  debug (g, "%s: qemu-img info JSON output:\n%.*s\n", __func__, (int) len, input);
 |  | ||||||
| +  debug (g, "%s: qemu-img info JSON output:\n%.*s\n",
 |  | ||||||
| +         __func__, (int) len, input);
 |  | ||||||
|   |  | ||||||
| -  *tree_ret = json_loadb (input, len, 0, &err);
 |  | ||||||
| -  if (*tree_ret == NULL) {
 |  | ||||||
| -    if (strlen (err.text) > 0)
 |  | ||||||
| -      error (g, _("qemu-img info: JSON parse error: %s"), err.text);
 |  | ||||||
| -    else
 |  | ||||||
| -      error (g, _("qemu-img info: unknown JSON parse error"));
 |  | ||||||
| +  tok = json_tokener_new ();
 |  | ||||||
| +  json_tokener_set_flags (tok,
 |  | ||||||
| +                          JSON_TOKENER_STRICT | JSON_TOKENER_VALIDATE_UTF8);
 |  | ||||||
| +  *tree_ret = json_tokener_parse_ex (tok, input, len);
 |  | ||||||
| +  err = json_tokener_get_error (tok);
 |  | ||||||
| +  if (err != json_tokener_success) {
 |  | ||||||
| +    error (g, _("qemu-img info: JSON parse error: %s"),
 |  | ||||||
| +           json_tokener_error_desc (err));
 |  | ||||||
| +    *tree_ret = NULL;           /* should already be */
 |  | ||||||
|    } |  | ||||||
| +  json_tokener_free (tok);
 |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|  static void |  | ||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @ -1,129 +0,0 @@ | |||||||
| From 47857751a78108617e1e25d4949564bc2a182381 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: "Richard W.M. Jones" <rjones@redhat.com> |  | ||||||
| Date: Tue, 22 Oct 2024 16:23:07 +0100 |  | ||||||
| Subject: [PATCH] lib: direct: Remove test for qemu mandatory locking |  | ||||||
| 
 |  | ||||||
| We tested for QEMU >= 2.10 support for mandatory locking.  I believe |  | ||||||
| this is for all practical purposes always enabled now (and qemu 2.10 |  | ||||||
| is ancient history) so simply assume it's true always. |  | ||||||
| ---
 |  | ||||||
|  lib/guestfs-internal.h |  1 - |  | ||||||
|  lib/launch-direct.c    | 19 ++++++----------- |  | ||||||
|  lib/qemu.c             | 48 ------------------------------------------ |  | ||||||
|  3 files changed, 7 insertions(+), 61 deletions(-) |  | ||||||
| 
 |  | ||||||
| diff --git a/lib/guestfs-internal.h b/lib/guestfs-internal.h
 |  | ||||||
| index f9f4628a..bb3772cb 100644
 |  | ||||||
| --- a/lib/guestfs-internal.h
 |  | ||||||
| +++ b/lib/guestfs-internal.h
 |  | ||||||
| @@ -796,7 +796,6 @@ extern struct qemu_data *guestfs_int_test_qemu (guestfs_h *g);
 |  | ||||||
|  extern struct version guestfs_int_qemu_version (guestfs_h *g, struct qemu_data *); |  | ||||||
|  extern int guestfs_int_qemu_supports (guestfs_h *g, const struct qemu_data *, const char *option); |  | ||||||
|  extern int guestfs_int_qemu_supports_device (guestfs_h *g, const struct qemu_data *, const char *device_name); |  | ||||||
| -extern int guestfs_int_qemu_mandatory_locking (guestfs_h *g, const struct qemu_data *data);
 |  | ||||||
|  extern bool guestfs_int_platform_has_kvm (guestfs_h *g, const struct qemu_data *data); |  | ||||||
|  extern char *guestfs_int_drive_source_qemu_param (guestfs_h *g, const struct drive_source *src); |  | ||||||
|  extern bool guestfs_int_discard_possible (guestfs_h *g, struct drive *drv, const struct version *qemu_version); |  | ||||||
| diff --git a/lib/launch-direct.c b/lib/launch-direct.c
 |  | ||||||
| index cdfd25a9..9d0c2215 100644
 |  | ||||||
| --- a/lib/launch-direct.c
 |  | ||||||
| +++ b/lib/launch-direct.c
 |  | ||||||
| @@ -57,7 +57,6 @@ struct backend_direct_data {
 |  | ||||||
|    pid_t recoverypid;            /* Recovery process PID. */ |  | ||||||
|   |  | ||||||
|    struct version qemu_version;  /* qemu version (0 if unable to parse). */ |  | ||||||
| -  int qemu_mandatory_locking;   /* qemu >= 2.10 does mandatory locking */
 |  | ||||||
|    struct qemu_data *qemu_data;  /* qemu -help output etc. */ |  | ||||||
|   |  | ||||||
|    char guestfsd_sock[UNIX_PATH_MAX]; /* Path to daemon socket. */ |  | ||||||
| @@ -240,13 +239,13 @@ add_drive_standard_params (guestfs_h *g, struct backend_direct_data *data,
 |  | ||||||
|      } |  | ||||||
|    } |  | ||||||
|    else { |  | ||||||
| -    /* Writable qcow2 overlay on top of read-only drive. */
 |  | ||||||
| -    if (data->qemu_mandatory_locking &&
 |  | ||||||
| -	/* Add the file-specific locking option only for files, as
 |  | ||||||
| -	 * qemu won't accept options unknown to the block driver in
 |  | ||||||
| -	 * use.
 |  | ||||||
| -	 */
 |  | ||||||
| -	drv->src.protocol == drive_protocol_file) {
 |  | ||||||
| +    /* Writable qcow2 overlay on top of read-only drive.
 |  | ||||||
| +     *
 |  | ||||||
| +     * Add the file-specific locking option only for files, as
 |  | ||||||
| +     * qemu won't accept options unknown to the block driver in
 |  | ||||||
| +     * use.
 |  | ||||||
| +     */
 |  | ||||||
| +    if (drv->src.protocol == drive_protocol_file) {
 |  | ||||||
|        append_list_format ("file.file.filename=%s", drv->overlay); |  | ||||||
|        append_list ("file.driver=qcow2"); |  | ||||||
|        append_list ("file.backing.file.locking=off"); |  | ||||||
| @@ -495,10 +494,6 @@ launch_direct (guestfs_h *g, void *datav, const char *arg)
 |  | ||||||
|      data->qemu_version = guestfs_int_qemu_version (g, data->qemu_data); |  | ||||||
|      debug (g, "qemu version: %d.%d", |  | ||||||
|             data->qemu_version.v_major, data->qemu_version.v_minor); |  | ||||||
| -    data->qemu_mandatory_locking =
 |  | ||||||
| -      guestfs_int_qemu_mandatory_locking (g, data->qemu_data);
 |  | ||||||
| -    debug (g, "qemu mandatory locking: %s",
 |  | ||||||
| -           data->qemu_mandatory_locking ? "yes" : "no");
 |  | ||||||
|    } |  | ||||||
|   |  | ||||||
|    /* Work out if KVM is supported or if the user wants to force TCG. */ |  | ||||||
| diff --git a/lib/qemu.c b/lib/qemu.c
 |  | ||||||
| index 886c92e5..f9270771 100644
 |  | ||||||
| --- a/lib/qemu.c
 |  | ||||||
| +++ b/lib/qemu.c
 |  | ||||||
| @@ -662,54 +662,6 @@ guestfs_int_qemu_supports_device (guestfs_h *g,
 |  | ||||||
|    return strstr (data->qemu_devices, device_name) != NULL; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| -/**
 |  | ||||||
| - * Test if the qemu binary uses mandatory file locking, added in
 |  | ||||||
| - * QEMU >= 2.10 (but sometimes disabled).
 |  | ||||||
| - */
 |  | ||||||
| -int
 |  | ||||||
| -guestfs_int_qemu_mandatory_locking (guestfs_h *g,
 |  | ||||||
| -                                    const struct qemu_data *data)
 |  | ||||||
| -{
 |  | ||||||
| -  json_t *schema, *v, *meta_type, *members, *m, *name;
 |  | ||||||
| -  size_t i, j;
 |  | ||||||
| -
 |  | ||||||
| -  /* If there's no QMP schema, fall back to checking the version. */
 |  | ||||||
| -  if (!data->qmp_schema_tree) {
 |  | ||||||
| -  fallback:
 |  | ||||||
| -    return guestfs_int_version_ge (&data->qemu_version, 2, 10, 0);
 |  | ||||||
| -  }
 |  | ||||||
| -
 |  | ||||||
| -  /* Top element of qmp_schema_tree is the { "return": ... } wrapper.
 |  | ||||||
| -   * Extract the schema from the wrapper.  Note the returned ‘schema’
 |  | ||||||
| -   * will be an array.
 |  | ||||||
| -   */
 |  | ||||||
| -  schema = json_object_get (data->qmp_schema_tree, "return");
 |  | ||||||
| -  if (!json_is_array (schema))
 |  | ||||||
| -    goto fallback;
 |  | ||||||
| -
 |  | ||||||
| -  /* Now look for any member of the array which has:
 |  | ||||||
| -   * { "meta-type": "object",
 |  | ||||||
| -   *   "members": [ ... { "name": "locking", ... } ... ] ... }
 |  | ||||||
| -   */
 |  | ||||||
| -  json_array_foreach (schema, i, v) {
 |  | ||||||
| -    meta_type = json_object_get (v, "meta-type");
 |  | ||||||
| -    if (json_is_string (meta_type) &&
 |  | ||||||
| -        STREQ (json_string_value (meta_type), "object")) {
 |  | ||||||
| -      members = json_object_get (v, "members");
 |  | ||||||
| -      if (json_is_array (members)) {
 |  | ||||||
| -        json_array_foreach (members, j, m) {
 |  | ||||||
| -          name = json_object_get (m, "name");
 |  | ||||||
| -          if (json_is_string (name) &&
 |  | ||||||
| -              STREQ (json_string_value (name), "locking"))
 |  | ||||||
| -            return 1;
 |  | ||||||
| -        }
 |  | ||||||
| -      }
 |  | ||||||
| -    }
 |  | ||||||
| -  }
 |  | ||||||
| -
 |  | ||||||
| -  return 0;
 |  | ||||||
| -}
 |  | ||||||
| -
 |  | ||||||
|  bool |  | ||||||
|  guestfs_int_platform_has_kvm (guestfs_h *g, const struct qemu_data *data) |  | ||||||
|  { |  | ||||||
							
								
								
									
										36
									
								
								SOURCES/0012-inspection-Return-RPM-epoch.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								SOURCES/0012-inspection-Return-RPM-epoch.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,36 @@ | |||||||
|  | From 3ce392c9870a589cc50d2270fcf07b4d129c3dc3 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: "Richard W.M. Jones" <rjones@redhat.com> | ||||||
|  | Date: Sat, 27 Mar 2021 09:31:00 +0000 | ||||||
|  | Subject: [PATCH] inspection: Return RPM epoch. | ||||||
|  | 
 | ||||||
|  | Fixes: commit c9ee831affed55abe0f928134cbbd2ed83b2f510 | ||||||
|  | (cherry picked from commit fef73bce7eec0ce0753a2e150e4e088020d38643) | ||||||
|  | ---
 | ||||||
|  |  daemon/rpm-c.c | 5 ++++- | ||||||
|  |  1 file changed, 4 insertions(+), 1 deletion(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/daemon/rpm-c.c b/daemon/rpm-c.c
 | ||||||
|  | index 92a3abf58..be0e81e22 100644
 | ||||||
|  | --- a/daemon/rpm-c.c
 | ||||||
|  | +++ b/daemon/rpm-c.c
 | ||||||
|  | @@ -108,13 +108,16 @@ guestfs_int_daemon_rpm_next_application (value unitv)
 | ||||||
|  |   | ||||||
|  |    h = headerLink (h); | ||||||
|  |    app.app2_name = headerFormat (h, "%{NAME}", NULL); | ||||||
|  | -  // XXXapp.app2_epoch = headerFormat (h, "%{NAME}", NULL);
 | ||||||
|  |    app.app2_version = headerFormat (h, "%{VERSION}", NULL); | ||||||
|  |    app.app2_release = headerFormat (h, "%{RELEASE}", NULL); | ||||||
|  |    app.app2_arch = headerFormat (h, "%{ARCH}", NULL); | ||||||
|  |    app.app2_url = headerFormat (h, "%{URL}", NULL); | ||||||
|  |    app.app2_summary = headerFormat (h, "%{SUMMARY}", NULL); | ||||||
|  |    app.app2_description = headerFormat (h, "%{DESCRIPTION}", NULL); | ||||||
|  | +
 | ||||||
|  | +  /* epoch is special as the only int field. */
 | ||||||
|  | +  app.app2_epoch = headerGetNumber (h, RPMTAG_EPOCH);
 | ||||||
|  | +
 | ||||||
|  |    headerFree (h); | ||||||
|  |   | ||||||
|  |    /* Convert this to an OCaml struct.  Any NULL fields must be turned | ||||||
|  | -- 
 | ||||||
|  | 2.31.1 | ||||||
|  | 
 | ||||||
| @ -1,155 +0,0 @@ | |||||||
| From 9e3c1f44cafc2ce568462fcedc0033cab7d94cae Mon Sep 17 00:00:00 2001 |  | ||||||
| From: "Richard W.M. Jones" <rjones@redhat.com> |  | ||||||
| Date: Tue, 22 Oct 2024 16:24:30 +0100 |  | ||||||
| Subject: [PATCH] lib/qemu.c: Replace jansson with json-c |  | ||||||
| 
 |  | ||||||
| ---
 |  | ||||||
|  lib/qemu.c | 73 ++++++++++++++++++++++++++++-------------------------- |  | ||||||
|  1 file changed, 38 insertions(+), 35 deletions(-) |  | ||||||
| 
 |  | ||||||
| diff --git a/lib/qemu.c b/lib/qemu.c
 |  | ||||||
| index f9270771..1d7f45f0 100644
 |  | ||||||
| --- a/lib/qemu.c
 |  | ||||||
| +++ b/lib/qemu.c
 |  | ||||||
| @@ -37,7 +37,7 @@
 |  | ||||||
|   |  | ||||||
|  #include <libxml/uri.h> |  | ||||||
|   |  | ||||||
| -#include <jansson.h>
 |  | ||||||
| +#include <json.h>
 |  | ||||||
|   |  | ||||||
|  #include "full-write.h" |  | ||||||
|  #include "ignore-value.h" |  | ||||||
| @@ -46,12 +46,13 @@
 |  | ||||||
|  #include "guestfs-internal.h" |  | ||||||
|  #include "guestfs_protocol.h" |  | ||||||
|   |  | ||||||
| -#define CLEANUP_JSON_T_DECREF __attribute__((cleanup(cleanup_json_t_decref)))
 |  | ||||||
| +#define CLEANUP_JSON_OBJECT_PUT \
 |  | ||||||
| +  __attribute__((cleanup(cleanup_json_object_put)))
 |  | ||||||
|   |  | ||||||
|  static void |  | ||||||
| -cleanup_json_t_decref (void *ptr)
 |  | ||||||
| +cleanup_json_object_put (void *ptr)
 |  | ||||||
|  { |  | ||||||
| -  json_decref (* (json_t **) ptr);
 |  | ||||||
| +  json_object_put (* (json_object **) ptr);
 |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|  struct qemu_data { |  | ||||||
| @@ -66,7 +67,7 @@ struct qemu_data {
 |  | ||||||
|   |  | ||||||
|    /* The following fields are derived from the fields above. */ |  | ||||||
|    struct version qemu_version;  /* Parsed qemu version number. */ |  | ||||||
| -  json_t *qmp_schema_tree;      /* qmp_schema parsed into a JSON tree */
 |  | ||||||
| +  json_object *qmp_schema_tree; /* qmp_schema parsed into a JSON tree */
 |  | ||||||
|    bool has_kvm;                 /* If KVM is available. */ |  | ||||||
|  }; |  | ||||||
|   |  | ||||||
| @@ -86,7 +87,7 @@ static int write_cache_query_kvm (guestfs_h *g, const struct qemu_data *data, co
 |  | ||||||
|  static int read_cache_qemu_stat (guestfs_h *g, struct qemu_data *data, const char *filename); |  | ||||||
|  static int write_cache_qemu_stat (guestfs_h *g, const struct qemu_data *data, const char *filename); |  | ||||||
|  static void parse_qemu_version (guestfs_h *g, const char *, struct version *qemu_version); |  | ||||||
| -static void parse_json (guestfs_h *g, const char *, json_t **);
 |  | ||||||
| +static void parse_json (guestfs_h *g, const char *, json_object **);
 |  | ||||||
|  static void parse_has_kvm (guestfs_h *g, const char *, bool *); |  | ||||||
|  static void read_all (guestfs_h *g, void *retv, const char *buf, size_t len); |  | ||||||
|  static int generic_read_cache (guestfs_h *g, const char *filename, char **strp); |  | ||||||
| @@ -442,20 +443,24 @@ parse_qemu_version (guestfs_h *g, const char *qemu_help,
 |  | ||||||
|   * is not possible. |  | ||||||
|   */ |  | ||||||
|  static void |  | ||||||
| -parse_json (guestfs_h *g, const char *json, json_t **treep)
 |  | ||||||
| +parse_json (guestfs_h *g, const char *json, json_object **treep)
 |  | ||||||
|  { |  | ||||||
| -  json_error_t err;
 |  | ||||||
| +  json_tokener *tok;
 |  | ||||||
| +  enum json_tokener_error err;
 |  | ||||||
|   |  | ||||||
|    if (!json) |  | ||||||
|      return; |  | ||||||
|   |  | ||||||
| -  *treep = json_loads (json, 0, &err);
 |  | ||||||
| -  if (*treep == NULL) {
 |  | ||||||
| -    if (strlen (err.text) > 0)
 |  | ||||||
| -      debug (g, "QMP parse error: %s (ignored)", err.text);
 |  | ||||||
| -    else
 |  | ||||||
| -      debug (g, "QMP unknown parse error (ignored)");
 |  | ||||||
| -  }
 |  | ||||||
| +  tok = json_tokener_new ();
 |  | ||||||
| +  json_tokener_set_flags (tok,
 |  | ||||||
| +                          JSON_TOKENER_STRICT | JSON_TOKENER_VALIDATE_UTF8);
 |  | ||||||
| +  *treep = json_tokener_parse_ex (tok, json, strlen (json));
 |  | ||||||
| +  err = json_tokener_get_error (tok);
 |  | ||||||
| +  if (err != json_tokener_success)
 |  | ||||||
| +    debug (g, "QMP parse error: %s (ignored)", json_tokener_error_desc (err));
 |  | ||||||
| +  json_tokener_free (tok);
 |  | ||||||
| +
 |  | ||||||
| +  /* Caller should do json_object_put (*treep) */
 |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|  /** |  | ||||||
| @@ -469,37 +474,35 @@ parse_json (guestfs_h *g, const char *json, json_t **treep)
 |  | ||||||
|  static void |  | ||||||
|  parse_has_kvm (guestfs_h *g, const char *json, bool *ret) |  | ||||||
|  { |  | ||||||
| -  CLEANUP_JSON_T_DECREF json_t *tree = NULL;
 |  | ||||||
| -  json_error_t err;
 |  | ||||||
| -  json_t *return_node, *enabled_node;
 |  | ||||||
| +  CLEANUP_JSON_OBJECT_PUT json_object *tree = NULL;
 |  | ||||||
| +  json_tokener *tok;
 |  | ||||||
| +  enum json_tokener_error err;
 |  | ||||||
| +  json_object *return_node, *enabled_node;
 |  | ||||||
|   |  | ||||||
|    *ret = true;                  /* Assume KVM is enabled. */ |  | ||||||
|   |  | ||||||
|    if (!json) |  | ||||||
|      return; |  | ||||||
|   |  | ||||||
| -  tree = json_loads (json, 0, &err);
 |  | ||||||
| -  if (tree == NULL) {
 |  | ||||||
| -    if (strlen (err.text) > 0)
 |  | ||||||
| -      debug (g, "QMP parse error: %s (ignored)", err.text);
 |  | ||||||
| -    else
 |  | ||||||
| -      debug (g, "QMP unknown parse error (ignored)");
 |  | ||||||
| +  tok = json_tokener_new ();
 |  | ||||||
| +  json_tokener_set_flags (tok,
 |  | ||||||
| +                          JSON_TOKENER_STRICT | JSON_TOKENER_VALIDATE_UTF8);
 |  | ||||||
| +  tree = json_tokener_parse_ex (tok, json, strlen (json));
 |  | ||||||
| +  err = json_tokener_get_error (tok);
 |  | ||||||
| +  if (err != json_tokener_success) {
 |  | ||||||
| +    debug (g, "QMP parse error: %s (ignored)", json_tokener_error_desc (err));
 |  | ||||||
| +    json_tokener_free (tok);
 |  | ||||||
|      return; |  | ||||||
|    } |  | ||||||
| +  json_tokener_free (tok);
 |  | ||||||
|   |  | ||||||
| -  return_node = json_object_get (tree, "return");
 |  | ||||||
| -  if (!json_is_object (return_node)) {
 |  | ||||||
| +  return_node = json_object_object_get (tree, "return");
 |  | ||||||
| +  if (json_object_get_type (return_node) != json_type_object) {
 |  | ||||||
|      debug (g, "QMP query-kvm: no \"return\" node (ignored)"); |  | ||||||
|      return; |  | ||||||
|    } |  | ||||||
| -  enabled_node = json_object_get (return_node, "enabled");
 |  | ||||||
| -  /* Note that json_is_boolean will check that enabled_node != NULL. */
 |  | ||||||
| -  if (!json_is_boolean (enabled_node)) {
 |  | ||||||
| -    debug (g, "QMP query-kvm: no \"enabled\" node or not a boolean (ignored)");
 |  | ||||||
| -    return;
 |  | ||||||
| -  }
 |  | ||||||
| -
 |  | ||||||
| -  *ret = json_is_true (enabled_node);
 |  | ||||||
| +  enabled_node = json_object_object_get (return_node, "enabled");
 |  | ||||||
| +  *ret = json_object_get_boolean (enabled_node);
 |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|  /** |  | ||||||
| @@ -975,7 +978,7 @@ guestfs_int_free_qemu_data (struct qemu_data *data)
 |  | ||||||
|      free (data->qemu_devices); |  | ||||||
|      free (data->qmp_schema); |  | ||||||
|      free (data->query_kvm); |  | ||||||
| -    json_decref (data->qmp_schema_tree);
 |  | ||||||
| +    json_object_put (data->qmp_schema_tree);
 |  | ||||||
|      free (data); |  | ||||||
|    } |  | ||||||
|  } |  | ||||||
| @ -1,65 +0,0 @@ | |||||||
| From 9255abee029e35dd5c6783b8b6037eb71104650c Mon Sep 17 00:00:00 2001 |  | ||||||
| From: "Richard W.M. Jones" <rjones@redhat.com> |  | ||||||
| Date: Tue, 22 Oct 2024 15:22:18 +0100 |  | ||||||
| Subject: [PATCH] build: Remove Jansson dependency |  | ||||||
| 
 |  | ||||||
| After previous changes, this library is no longer used.  We have |  | ||||||
| switched to json-c, for better compatibility with libvirt. |  | ||||||
| 
 |  | ||||||
| (cherry picked from |  | ||||||
| guestfs-tools commit e6dcf7e3a7e9170978e57ce6df1b34f92fac5ae3) |  | ||||||
| ---
 |  | ||||||
|  docs/guestfs-building.pod | 4 ---- |  | ||||||
|  lib/Makefile.am           | 2 -- |  | ||||||
|  m4/guestfs-libraries.m4   | 3 --- |  | ||||||
|  3 files changed, 9 deletions(-) |  | ||||||
| 
 |  | ||||||
| diff --git a/docs/guestfs-building.pod b/docs/guestfs-building.pod
 |  | ||||||
| index de175aaf..aef716ff 100644
 |  | ||||||
| --- a/docs/guestfs-building.pod
 |  | ||||||
| +++ b/docs/guestfs-building.pod
 |  | ||||||
| @@ -185,10 +185,6 @@ I<Required>.
 |  | ||||||
|   |  | ||||||
|  I<Required>. |  | ||||||
|   |  | ||||||
| -=item Jansson E<ge> 2.7
 |  | ||||||
| -
 |  | ||||||
| -I<Required>.
 |  | ||||||
| -
 |  | ||||||
|  =item json-c E<ge> 0.14 |  | ||||||
|   |  | ||||||
|  I<Required>. |  | ||||||
| diff --git a/lib/Makefile.am b/lib/Makefile.am
 |  | ||||||
| index 60567b04..6949884d 100644
 |  | ||||||
| --- a/lib/Makefile.am
 |  | ||||||
| +++ b/lib/Makefile.am
 |  | ||||||
| @@ -138,7 +138,6 @@ libguestfs_la_CFLAGS = \
 |  | ||||||
|  	$(PCRE2_CFLAGS) \ |  | ||||||
|  	$(LIBVIRT_CFLAGS) \ |  | ||||||
|  	$(LIBXML2_CFLAGS) \ |  | ||||||
| -	$(JANSSON_CFLAGS) \
 |  | ||||||
|  	$(JSON_C_CFLAGS) |  | ||||||
|   |  | ||||||
|  libguestfs_la_LIBADD = \ |  | ||||||
| @@ -150,7 +149,6 @@ libguestfs_la_LIBADD = \
 |  | ||||||
|  	$(PCRE2_LIBS) \ |  | ||||||
|  	$(LIBVIRT_LIBS) $(LIBXML2_LIBS) \ |  | ||||||
|  	$(SELINUX_LIBS) \ |  | ||||||
| -	$(JANSSON_LIBS) \
 |  | ||||||
|  	$(JSON_C_LIBS) \ |  | ||||||
|  	../gnulib/lib/libgnu.la \ |  | ||||||
|  	$(LIBSOCKET) \ |  | ||||||
| diff --git a/m4/guestfs-libraries.m4 b/m4/guestfs-libraries.m4
 |  | ||||||
| index ee406d27..51565171 100644
 |  | ||||||
| --- a/m4/guestfs-libraries.m4
 |  | ||||||
| +++ b/m4/guestfs-libraries.m4
 |  | ||||||
| @@ -301,9 +301,6 @@ LIBS="$LIBS $LIBXML2_LIBS"
 |  | ||||||
|  AC_CHECK_FUNCS([xmlBufferDetach]) |  | ||||||
|  LIBS="$old_LIBS" |  | ||||||
|   |  | ||||||
| -dnl Check for Jansson JSON library (required).
 |  | ||||||
| -PKG_CHECK_MODULES([JANSSON], [jansson >= 2.7])
 |  | ||||||
| -
 |  | ||||||
|  dnl Check for JSON-C library (required). |  | ||||||
|  PKG_CHECK_MODULES([JSON_C], [json-c >= 0.14]) |  | ||||||
|   |  | ||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @ -0,0 +1,34 @@ | |||||||
|  | From 9664527c107d04aab416be87cc4fcd76dcbe5927 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: "Richard W.M. Jones" <rjones@redhat.com> | ||||||
|  | Date: Mon, 29 Mar 2021 18:25:13 +0100 | ||||||
|  | Subject: [PATCH] po/POTFILES: Fix list of files for translation. | ||||||
|  | 
 | ||||||
|  | Fixes: commit c9ee831affed55abe0f928134cbbd2ed83b2f510 | ||||||
|  | (cherry picked from commit df983200d76bac37c811fbd2fb67e7ebe830e759) | ||||||
|  | ---
 | ||||||
|  |  po/POTFILES | 2 +- | ||||||
|  |  1 file changed, 1 insertion(+), 1 deletion(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/po/POTFILES b/po/POTFILES
 | ||||||
|  | index 0782e8ceb..fdc6e8062 100644
 | ||||||
|  | --- a/po/POTFILES
 | ||||||
|  | +++ b/po/POTFILES
 | ||||||
|  | @@ -128,6 +128,7 @@ daemon/pingdaemon.c
 | ||||||
|  |  daemon/proto.c | ||||||
|  |  daemon/readdir.c | ||||||
|  |  daemon/rename.c | ||||||
|  | +daemon/rpm-c.c
 | ||||||
|  |  daemon/rsync.c | ||||||
|  |  daemon/scrub.c | ||||||
|  |  daemon/selinux-relabel.c | ||||||
|  | @@ -353,7 +354,6 @@ lib/command.c
 | ||||||
|  |  lib/conn-socket.c | ||||||
|  |  lib/copy-in-out.c | ||||||
|  |  lib/create.c | ||||||
|  | -lib/dbdump.c
 | ||||||
|  |  lib/drives.c | ||||||
|  |  lib/errors.c | ||||||
|  |  lib/event-string.c | ||||||
|  | -- 
 | ||||||
|  | 2.31.1 | ||||||
|  | 
 | ||||||
| @ -1,23 +0,0 @@ | |||||||
| From a5cc27fc952ec213e82849d7c26f977a6321e0b1 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: "Richard W.M. Jones" <rjones@redhat.com> |  | ||||||
| Date: Tue, 22 Oct 2024 17:44:06 +0100 |  | ||||||
| Subject: [PATCH] website: Fix link to latest development version |  | ||||||
| 
 |  | ||||||
| Fixes: commit 0edaea8f91bf08025651eeff32f53b9335003842 |  | ||||||
| ---
 |  | ||||||
|  website/index.html.in | 2 +- |  | ||||||
|  1 file changed, 1 insertion(+), 1 deletion(-) |  | ||||||
| 
 |  | ||||||
| diff --git a/website/index.html.in b/website/index.html.in
 |  | ||||||
| index 2a0d3221..13c5ff25 100644
 |  | ||||||
| --- a/website/index.html.in
 |  | ||||||
| +++ b/website/index.html.in
 |  | ||||||
| @@ -183,7 +183,7 @@ git clone <a href="https://github.com/libguestfs/libguestfs">https://github.com/
 |  | ||||||
|  <p class="latest"> |  | ||||||
|  <em><small> |  | ||||||
|    <!-- |  | ||||||
| -LATEST-URL: http://libguestfs.org/download/1.53-development/libguestfs-@PACKAGE_VERSION@.tar.gz
 |  | ||||||
| +LATEST-URL: http://libguestfs.org/download/1.55-development/libguestfs-@PACKAGE_VERSION@.tar.gz
 |  | ||||||
|  LATEST-VERSION: @PACKAGE_VERSION@ |  | ||||||
|    --> |  | ||||||
|    <a href="download/1.55-development/">Latest development version: <strong>@PACKAGE_VERSION@</strong></a> (released <strong>@RELEASE_DATE@</strong>).<br/> |  | ||||||
| @ -0,0 +1,64 @@ | |||||||
|  | From 083856d9f9c8fccc629bf0f3a5237d26434c8940 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: "Richard W.M. Jones" <rjones@redhat.com> | ||||||
|  | Date: Mon, 29 Mar 2021 18:35:48 +0100 | ||||||
|  | Subject: [PATCH] m4/guestfs-find-db-tool.m4: Remove unused file. | ||||||
|  | 
 | ||||||
|  | Fixes: commit 42e5e7cfdbca01b2e9bd50c63a9fc65b6da9192f | ||||||
|  | (cherry picked from commit 8317279c3539562ebad9de13c7ac515dded74e4d) | ||||||
|  | ---
 | ||||||
|  |  m4/guestfs-find-db-tool.m4 | 43 -------------------------------------- | ||||||
|  |  1 file changed, 43 deletions(-) | ||||||
|  |  delete mode 100644 m4/guestfs-find-db-tool.m4 | ||||||
|  | 
 | ||||||
|  | diff --git a/m4/guestfs-find-db-tool.m4 b/m4/guestfs-find-db-tool.m4
 | ||||||
|  | deleted file mode 100644 | ||||||
|  | index b404148c6..000000000
 | ||||||
|  | --- a/m4/guestfs-find-db-tool.m4
 | ||||||
|  | +++ /dev/null
 | ||||||
|  | @@ -1,43 +0,0 @@
 | ||||||
|  | -# libguestfs
 | ||||||
|  | -# Copyright (C) 2014 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.
 | ||||||
|  | -
 | ||||||
|  | -AC_DEFUN([GUESTFS_FIND_DB_TOOL],[
 | ||||||
|  | -    pushdef([VARIABLE],$1)
 | ||||||
|  | -    TOOL=$2
 | ||||||
|  | -
 | ||||||
|  | -    db_tool_name="db_$TOOL"
 | ||||||
|  | -    db_versions="53 5.3 5.2 5.1 4.8 4.7 4.6"
 | ||||||
|  | -    db_tool_patterns="dbX_$TOOL dbX.Y_$TOOL"
 | ||||||
|  | -    db_tool_patterns="dbX_$TOOL db_$TOOL-X dbX.Y_$TOOL db_$TOOL-X.Y"
 | ||||||
|  | -
 | ||||||
|  | -    AC_ARG_VAR(VARIABLE, [Absolute path to $db_tool_name executable])
 | ||||||
|  | -
 | ||||||
|  | -    AS_IF(test -z "$VARIABLE", [
 | ||||||
|  | -        exe_list="db_$TOOL"
 | ||||||
|  | -        for ver in $db_versions ; do
 | ||||||
|  | -            ver_maj=`echo $ver | cut -d. -f1`
 | ||||||
|  | -            ver_min=`echo $ver | cut -d. -f2`
 | ||||||
|  | -            for pattern in $db_tool_patterns ; do
 | ||||||
|  | -                exe=`echo "$pattern" | sed -e "s/X/$ver_maj/g;s/Y/$ver_min/g"`
 | ||||||
|  | -                exe_list="$exe_list $exe"
 | ||||||
|  | -            done
 | ||||||
|  | -        done
 | ||||||
|  | -        AC_PATH_PROGS([]VARIABLE[], [$exe_list], [no])
 | ||||||
|  | -    ])
 | ||||||
|  | -
 | ||||||
|  | -    popdef([VARIABLE])
 | ||||||
|  | -])
 | ||||||
|  | -- 
 | ||||||
|  | 2.31.1 | ||||||
|  | 
 | ||||||
| @ -0,0 +1,474 @@ | |||||||
|  | From f8ccce2c7a0c1323e0721f503322df525dd5b139 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: "Richard W.M. Jones" <rjones@redhat.com> | ||||||
|  | Date: Mon, 29 Mar 2021 12:22:12 +0100 | ||||||
|  | Subject: [PATCH] test-data/phony-guests: Fix phony RPM database, fix | ||||||
|  |  virt-inspector test. | ||||||
|  | 
 | ||||||
|  | libguestfs 1.45.3 now reads the RPM database using librpm, which means | ||||||
|  | our old phony database created by db_dump can no longer work.  Instead | ||||||
|  | provide a real (but very minimal) sqlite database. | ||||||
|  | 
 | ||||||
|  | This commit also fixes the virt-inspector test since the RPM database | ||||||
|  | contents are now different. | ||||||
|  | 
 | ||||||
|  | (cherry picked from commit 46bf6fb473889ed28bd7220476120edcda47ae07) | ||||||
|  | ---
 | ||||||
|  |  inspector/expected-fedora-luks.img.xml | 208 +++++++++++++++++++++++-- | ||||||
|  |  inspector/expected-fedora.img.xml      | 208 +++++++++++++++++++++++-- | ||||||
|  |  2 files changed, 398 insertions(+), 18 deletions(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/inspector/expected-fedora-luks.img.xml b/inspector/expected-fedora-luks.img.xml
 | ||||||
|  | index df6060a73..72cddaf88 100644
 | ||||||
|  | --- a/inspector/expected-fedora-luks.img.xml
 | ||||||
|  | +++ b/inspector/expected-fedora-luks.img.xml
 | ||||||
|  | @@ -30,22 +30,212 @@
 | ||||||
|  |      </filesystems> | ||||||
|  |      <applications> | ||||||
|  |        <application> | ||||||
|  | -        <name>test1</name>
 | ||||||
|  | -        <version>1.0</version>
 | ||||||
|  | -        <release>1.fc14</release>
 | ||||||
|  | +        <name>basesystem</name>
 | ||||||
|  | +        <version>11</version>
 | ||||||
|  | +        <release>10.fc33</release>
 | ||||||
|  | +        <arch>noarch</arch>
 | ||||||
|  | +        <url>(none)</url>
 | ||||||
|  | +        <summary>The skeleton package which defines a simple Fedora system</summary>
 | ||||||
|  | +        <description>Basesystem defines the components of a basic Fedora system
 | ||||||
|  | +(for example, the package installation order to use during bootstrapping).
 | ||||||
|  | +Basesystem should be in every installation of a system, and it
 | ||||||
|  | +should never be removed.</description>
 | ||||||
|  | +      </application>
 | ||||||
|  | +      <application>
 | ||||||
|  | +        <name>bash</name>
 | ||||||
|  | +        <version>5.0.17</version>
 | ||||||
|  | +        <release>2.fc33</release>
 | ||||||
|  | +        <arch>x86_64</arch>
 | ||||||
|  | +        <url>https://www.gnu.org/software/bash</url>
 | ||||||
|  | +        <summary>The GNU Bourne Again shell</summary>
 | ||||||
|  | +        <description>The GNU Bourne Again shell (Bash) is a shell or command language
 | ||||||
|  | +interpreter that is compatible with the Bourne shell (sh). Bash
 | ||||||
|  | +incorporates useful features from the Korn shell (ksh) and the C shell
 | ||||||
|  | +(csh). Most sh scripts can be run by bash without modification.</description>
 | ||||||
|  | +      </application>
 | ||||||
|  | +      <application>
 | ||||||
|  | +        <name>fedora-gpg-keys</name>
 | ||||||
|  | +        <version>33</version>
 | ||||||
|  | +        <release>3</release>
 | ||||||
|  | +        <arch>noarch</arch>
 | ||||||
|  | +        <url>https://fedoraproject.org/</url>
 | ||||||
|  | +        <summary>Fedora RPM keys</summary>
 | ||||||
|  | +        <description>This package provides the RPM signature keys.</description>
 | ||||||
|  | +      </application>
 | ||||||
|  | +      <application>
 | ||||||
|  | +        <name>fedora-release</name>
 | ||||||
|  | +        <version>33</version>
 | ||||||
|  | +        <release>3</release>
 | ||||||
|  | +        <arch>noarch</arch>
 | ||||||
|  | +        <url>https://fedoraproject.org/</url>
 | ||||||
|  | +        <summary>Fedora release files</summary>
 | ||||||
|  | +        <description>Fedora release files such as various /etc/ files that define the release
 | ||||||
|  | +and systemd preset files that determine which services are enabled by default.</description>
 | ||||||
|  | +      </application>
 | ||||||
|  | +      <application>
 | ||||||
|  | +        <name>fedora-release-common</name>
 | ||||||
|  | +        <version>33</version>
 | ||||||
|  | +        <release>3</release>
 | ||||||
|  | +        <arch>noarch</arch>
 | ||||||
|  | +        <url>https://fedoraproject.org/</url>
 | ||||||
|  | +        <summary>Fedora release files</summary>
 | ||||||
|  | +        <description>Release files common to all Editions and Spins of Fedora</description>
 | ||||||
|  | +      </application>
 | ||||||
|  | +      <application>
 | ||||||
|  | +        <name>fedora-release-identity-basic</name>
 | ||||||
|  | +        <version>33</version>
 | ||||||
|  | +        <release>3</release>
 | ||||||
|  | +        <arch>noarch</arch>
 | ||||||
|  | +        <url>https://fedoraproject.org/</url>
 | ||||||
|  | +        <summary>Package providing the basic Fedora identity</summary>
 | ||||||
|  | +        <description>Provides the necessary files for a Fedora installation that is not identifying
 | ||||||
|  | +itself as a particular Edition or Spin.</description>
 | ||||||
|  | +      </application>
 | ||||||
|  | +      <application>
 | ||||||
|  | +        <name>fedora-repos</name>
 | ||||||
|  | +        <version>33</version>
 | ||||||
|  | +        <release>3</release>
 | ||||||
|  | +        <arch>noarch</arch>
 | ||||||
|  | +        <url>https://fedoraproject.org/</url>
 | ||||||
|  | +        <summary>Fedora package repositories</summary>
 | ||||||
|  | +        <description>Fedora package repository files for yum and dnf along with gpg public keys.</description>
 | ||||||
|  | +      </application>
 | ||||||
|  | +      <application>
 | ||||||
|  | +        <name>filesystem</name>
 | ||||||
|  | +        <version>3.14</version>
 | ||||||
|  | +        <release>3.fc33</release>
 | ||||||
|  | +        <arch>x86_64</arch>
 | ||||||
|  | +        <url>https://pagure.io/filesystem</url>
 | ||||||
|  | +        <summary>The basic directory layout for a Linux system</summary>
 | ||||||
|  | +        <description>The filesystem package is one of the basic packages that is installed
 | ||||||
|  | +on a Linux system. Filesystem contains the basic directory layout
 | ||||||
|  | +for a Linux operating system, including the correct permissions for
 | ||||||
|  | +the directories.</description>
 | ||||||
|  | +      </application>
 | ||||||
|  | +      <application>
 | ||||||
|  | +        <name>glibc</name>
 | ||||||
|  | +        <version>2.32</version>
 | ||||||
|  | +        <release>4.fc33</release>
 | ||||||
|  | +        <arch>x86_64</arch>
 | ||||||
|  | +        <url>http://www.gnu.org/software/glibc/</url>
 | ||||||
|  | +        <summary>The GNU libc libraries</summary>
 | ||||||
|  | +        <description>The glibc package contains standard libraries which are used by
 | ||||||
|  | +multiple programs on the system. In order to save disk space and
 | ||||||
|  | +memory, as well as to make upgrading easier, common system code is
 | ||||||
|  | +kept in one place and shared between programs. This particular package
 | ||||||
|  | +contains the most important sets of shared libraries: the standard C
 | ||||||
|  | +library and the standard math library. Without these two libraries, a
 | ||||||
|  | +Linux system will not function.</description>
 | ||||||
|  | +      </application>
 | ||||||
|  | +      <application>
 | ||||||
|  | +        <name>glibc-all-langpacks</name>
 | ||||||
|  | +        <version>2.32</version>
 | ||||||
|  | +        <release>4.fc33</release>
 | ||||||
|  | +        <arch>x86_64</arch>
 | ||||||
|  | +        <url>http://www.gnu.org/software/glibc/</url>
 | ||||||
|  | +        <summary>All language packs for glibc.</summary>
 | ||||||
|  | +      </application>
 | ||||||
|  | +      <application>
 | ||||||
|  | +        <name>glibc-common</name>
 | ||||||
|  | +        <version>2.32</version>
 | ||||||
|  | +        <release>4.fc33</release>
 | ||||||
|  |          <arch>x86_64</arch> | ||||||
|  | +        <url>http://www.gnu.org/software/glibc/</url>
 | ||||||
|  | +        <summary>Common binaries and locale data for glibc</summary>
 | ||||||
|  | +        <description>The glibc-common package includes common binaries for the GNU libc
 | ||||||
|  | +libraries, as well as national language (locale) support.</description>
 | ||||||
|  |        </application> | ||||||
|  |        <application> | ||||||
|  | -        <name>test2</name>
 | ||||||
|  | -        <version>2.0</version>
 | ||||||
|  | -        <release>2.fc14</release>
 | ||||||
|  | +        <name>gpg-pubkey</name>
 | ||||||
|  | +        <version>9570ff31</version>
 | ||||||
|  | +        <release>5e3006fb</release>
 | ||||||
|  | +        <arch>(none)</arch>
 | ||||||
|  | +        <url>(none)</url>
 | ||||||
|  | +        <summary>Fedora (33) <fedora-33-primary@fedoraproject.org> public key</summary>
 | ||||||
|  | +        <description>-----BEGIN PGP PUBLIC KEY BLOCK-----
 | ||||||
|  | +Version: rpm-4.16.1.2 (NSS-3)
 | ||||||
|  | +
 | ||||||
|  | +mQINBF4wBvsBEADQmcGbVUbDRUoXADReRmOOEMeydHghtKC9uRs9YNpGYZIB+bie
 | ||||||
|  | +bGYZmflQayfh/wEpO2W/IZfGpHPL42V7SbyvqMjwNls/fnXsCtf4LRofNK8Qd9fN
 | ||||||
|  | +kYargc9R7BEz/mwXKMiRQVx+DzkmqGWy2gq4iD0/mCyf5FdJCE40fOWoIGJXaOI1
 | ||||||
|  | +Tz1vWqKwLS5T0dfmi9U4Tp/XsKOZGvN8oi5h0KmqFk7LEZr1MXarhi2Va86sgxsF
 | ||||||
|  | +QcZEKfu5tgD0r00vXzikoSjn3qA5JW5FW07F1pGP4bF5f9J3CZbQyOjTSWMmmfTm
 | ||||||
|  | +2d2BURWzaDiJN9twY2yjzkoOMuPdXXvovg7KxLcQerKT+FbKbq8DySJX2rnOA77k
 | ||||||
|  | +UG4c9BGf/L1uBkAT8dpHLk6Uf5BfmypxUkydSWT1xfTDnw1MqxO0MsLlAHOR3J7c
 | ||||||
|  | +oW9kLcOLuCQn1hBEwfZv7VSWBkGXSmKfp0LLIxAFgRtv+Dh+rcMMRdJgKr1V3FU+
 | ||||||
|  | +rZ1+ZAfYiBpQJFPjv70vx+rGEgS801D3PJxBZUEy4Ic4ZYaKNhK9x9PRQuWcIBuW
 | ||||||
|  | +6eTe/6lKWZeyxCumLLdiS75mF2oTcBaWeoc3QxrPRV15eDKeYJMbhnUai/7lSrhs
 | ||||||
|  | +EWCkKR1RivgF4slYmtNE5ZPGZ/d61zjwn2xi4xNJVs8q9WRPMpHp0vCyMwARAQAB
 | ||||||
|  | +tDFGZWRvcmEgKDMzKSA8ZmVkb3JhLTMzLXByaW1hcnlAZmVkb3JhcHJvamVjdC5v
 | ||||||
|  | +cmc+iQI4BBMBAgAiBQJeMAb7AhsPBgsJCAcDAgYVCAIJCgsEFgIDAQIeAQIXgAAK
 | ||||||
|  | +CRBJ/XdJlXD/MZm2D/9kriL43vd3+0DNMeA82n2v9mSR2PQqKny39xNlYPyy/1yZ
 | ||||||
|  | +P/KXoa4NYSCA971LSd7lv4n/h5bEKgGHxZfttfOzOnWMVSSTfjRyM/df/NNzTUEV
 | ||||||
|  | +7ORA5GW18g8PEtS7uRxVBf3cLvWu5q+8jmqES5HqTAdGVcuIFQeBXFN8Gy1Jinuz
 | ||||||
|  | +AH8rJSdkUeZ0cehWbERq80BWM9dhad5dW+/+Gv0foFBvP15viwhWqajr8V0B8es+
 | ||||||
|  | +2/tHI0k86FAujV5i0rrXl5UOoLilO57QQNDZH/qW9GsHwVI+2yecLstpUNLq+EZC
 | ||||||
|  | +GqTZCYoxYRpl0gAMbDLztSL/8Bc0tJrCRG3tavJotFYlgUK60XnXlQzRkh9rgsfT
 | ||||||
|  | +EXbQifWdQMMogzjCJr0hzJ+V1d0iozdUxB2ZEgTjukOvatkB77DY1FPZRkSFIQs+
 | ||||||
|  | +fdcjazDIBLIxwJu5QwvTNW8lOLnJ46g4sf1WJoUdNTbR0BaC7HHj1inVWi0p7IuN
 | ||||||
|  | +66EPGzJOSjLK+vW+J0ncPDEgLCV74RF/0nR5fVTdrmiopPrzFuguHf9S9gYI3Zun
 | ||||||
|  | +Yl8FJUu4kRO6JPPTicUXWX+8XZmE94aK14RCJL23nOSi8T1eW8JLW43dCBRO8QUE
 | ||||||
|  | +Aso1t2pypm/1zZexJdOV8yGME3g5l2W6PLgpz58DBECgqc/kda+VWgEAp7rO2A==
 | ||||||
|  | +=EPL3
 | ||||||
|  | +-----END PGP PUBLIC KEY BLOCK-----
 | ||||||
|  | +</description>
 | ||||||
|  | +      </application>
 | ||||||
|  | +      <application>
 | ||||||
|  | +        <name>libgcc</name>
 | ||||||
|  | +        <version>10.2.1</version>
 | ||||||
|  | +        <release>9.fc33</release>
 | ||||||
|  |          <arch>x86_64</arch> | ||||||
|  | +        <url>http://gcc.gnu.org</url>
 | ||||||
|  | +        <summary>GCC version 10 shared support library</summary>
 | ||||||
|  | +        <description>This package contains GCC shared support library which is needed
 | ||||||
|  | +e.g. for exception handling support.</description>
 | ||||||
|  | +      </application>
 | ||||||
|  | +      <application>
 | ||||||
|  | +        <name>ncurses-base</name>
 | ||||||
|  | +        <version>6.2</version>
 | ||||||
|  | +        <release>3.20200222.fc33</release>
 | ||||||
|  | +        <arch>noarch</arch>
 | ||||||
|  | +        <url>https://invisible-island.net/ncurses/ncurses.html</url>
 | ||||||
|  | +        <summary>Descriptions of common terminals</summary>
 | ||||||
|  | +        <description>This package contains descriptions of common terminals. Other terminal
 | ||||||
|  | +descriptions are included in the ncurses-term package.</description>
 | ||||||
|  |        </application> | ||||||
|  |        <application> | ||||||
|  | -        <name>test3</name>
 | ||||||
|  | -        <version>3.0</version>
 | ||||||
|  | -        <release>3.fc14</release>
 | ||||||
|  | +        <name>ncurses-libs</name>
 | ||||||
|  | +        <version>6.2</version>
 | ||||||
|  | +        <release>3.20200222.fc33</release>
 | ||||||
|  |          <arch>x86_64</arch> | ||||||
|  | +        <url>https://invisible-island.net/ncurses/ncurses.html</url>
 | ||||||
|  | +        <summary>Ncurses libraries</summary>
 | ||||||
|  | +        <description>The curses library routines are a terminal-independent method of
 | ||||||
|  | +updating character screens with reasonable optimization.  The ncurses
 | ||||||
|  | +(new curses) library is a freely distributable replacement for the
 | ||||||
|  | +discontinued 4.4 BSD classic curses library.
 | ||||||
|  | +
 | ||||||
|  | +This package contains the ncurses libraries.</description>
 | ||||||
|  | +      </application>
 | ||||||
|  | +      <application>
 | ||||||
|  | +        <name>setup</name>
 | ||||||
|  | +        <version>2.13.7</version>
 | ||||||
|  | +        <release>2.fc33</release>
 | ||||||
|  | +        <arch>noarch</arch>
 | ||||||
|  | +        <url>https://pagure.io/setup/</url>
 | ||||||
|  | +        <summary>A set of system configuration and setup files</summary>
 | ||||||
|  | +        <description>The setup package contains a set of important system configuration and
 | ||||||
|  | +setup files, such as passwd, group, and profile.</description>
 | ||||||
|  | +      </application>
 | ||||||
|  | +      <application>
 | ||||||
|  | +        <name>tzdata</name>
 | ||||||
|  | +        <version>2021a</version>
 | ||||||
|  | +        <release>1.fc33</release>
 | ||||||
|  | +        <arch>noarch</arch>
 | ||||||
|  | +        <url>https://www.iana.org/time-zones</url>
 | ||||||
|  | +        <summary>Timezone data</summary>
 | ||||||
|  | +        <description>This package contains data files with rules for various timezones around
 | ||||||
|  | +the world.</description>
 | ||||||
|  |        </application> | ||||||
|  |      </applications> | ||||||
|  |    </operatingsystem> | ||||||
|  | diff --git a/inspector/expected-fedora.img.xml b/inspector/expected-fedora.img.xml
 | ||||||
|  | index df6060a73..72cddaf88 100644
 | ||||||
|  | --- a/inspector/expected-fedora.img.xml
 | ||||||
|  | +++ b/inspector/expected-fedora.img.xml
 | ||||||
|  | @@ -30,22 +30,212 @@
 | ||||||
|  |      </filesystems> | ||||||
|  |      <applications> | ||||||
|  |        <application> | ||||||
|  | -        <name>test1</name>
 | ||||||
|  | -        <version>1.0</version>
 | ||||||
|  | -        <release>1.fc14</release>
 | ||||||
|  | +        <name>basesystem</name>
 | ||||||
|  | +        <version>11</version>
 | ||||||
|  | +        <release>10.fc33</release>
 | ||||||
|  | +        <arch>noarch</arch>
 | ||||||
|  | +        <url>(none)</url>
 | ||||||
|  | +        <summary>The skeleton package which defines a simple Fedora system</summary>
 | ||||||
|  | +        <description>Basesystem defines the components of a basic Fedora system
 | ||||||
|  | +(for example, the package installation order to use during bootstrapping).
 | ||||||
|  | +Basesystem should be in every installation of a system, and it
 | ||||||
|  | +should never be removed.</description>
 | ||||||
|  | +      </application>
 | ||||||
|  | +      <application>
 | ||||||
|  | +        <name>bash</name>
 | ||||||
|  | +        <version>5.0.17</version>
 | ||||||
|  | +        <release>2.fc33</release>
 | ||||||
|  | +        <arch>x86_64</arch>
 | ||||||
|  | +        <url>https://www.gnu.org/software/bash</url>
 | ||||||
|  | +        <summary>The GNU Bourne Again shell</summary>
 | ||||||
|  | +        <description>The GNU Bourne Again shell (Bash) is a shell or command language
 | ||||||
|  | +interpreter that is compatible with the Bourne shell (sh). Bash
 | ||||||
|  | +incorporates useful features from the Korn shell (ksh) and the C shell
 | ||||||
|  | +(csh). Most sh scripts can be run by bash without modification.</description>
 | ||||||
|  | +      </application>
 | ||||||
|  | +      <application>
 | ||||||
|  | +        <name>fedora-gpg-keys</name>
 | ||||||
|  | +        <version>33</version>
 | ||||||
|  | +        <release>3</release>
 | ||||||
|  | +        <arch>noarch</arch>
 | ||||||
|  | +        <url>https://fedoraproject.org/</url>
 | ||||||
|  | +        <summary>Fedora RPM keys</summary>
 | ||||||
|  | +        <description>This package provides the RPM signature keys.</description>
 | ||||||
|  | +      </application>
 | ||||||
|  | +      <application>
 | ||||||
|  | +        <name>fedora-release</name>
 | ||||||
|  | +        <version>33</version>
 | ||||||
|  | +        <release>3</release>
 | ||||||
|  | +        <arch>noarch</arch>
 | ||||||
|  | +        <url>https://fedoraproject.org/</url>
 | ||||||
|  | +        <summary>Fedora release files</summary>
 | ||||||
|  | +        <description>Fedora release files such as various /etc/ files that define the release
 | ||||||
|  | +and systemd preset files that determine which services are enabled by default.</description>
 | ||||||
|  | +      </application>
 | ||||||
|  | +      <application>
 | ||||||
|  | +        <name>fedora-release-common</name>
 | ||||||
|  | +        <version>33</version>
 | ||||||
|  | +        <release>3</release>
 | ||||||
|  | +        <arch>noarch</arch>
 | ||||||
|  | +        <url>https://fedoraproject.org/</url>
 | ||||||
|  | +        <summary>Fedora release files</summary>
 | ||||||
|  | +        <description>Release files common to all Editions and Spins of Fedora</description>
 | ||||||
|  | +      </application>
 | ||||||
|  | +      <application>
 | ||||||
|  | +        <name>fedora-release-identity-basic</name>
 | ||||||
|  | +        <version>33</version>
 | ||||||
|  | +        <release>3</release>
 | ||||||
|  | +        <arch>noarch</arch>
 | ||||||
|  | +        <url>https://fedoraproject.org/</url>
 | ||||||
|  | +        <summary>Package providing the basic Fedora identity</summary>
 | ||||||
|  | +        <description>Provides the necessary files for a Fedora installation that is not identifying
 | ||||||
|  | +itself as a particular Edition or Spin.</description>
 | ||||||
|  | +      </application>
 | ||||||
|  | +      <application>
 | ||||||
|  | +        <name>fedora-repos</name>
 | ||||||
|  | +        <version>33</version>
 | ||||||
|  | +        <release>3</release>
 | ||||||
|  | +        <arch>noarch</arch>
 | ||||||
|  | +        <url>https://fedoraproject.org/</url>
 | ||||||
|  | +        <summary>Fedora package repositories</summary>
 | ||||||
|  | +        <description>Fedora package repository files for yum and dnf along with gpg public keys.</description>
 | ||||||
|  | +      </application>
 | ||||||
|  | +      <application>
 | ||||||
|  | +        <name>filesystem</name>
 | ||||||
|  | +        <version>3.14</version>
 | ||||||
|  | +        <release>3.fc33</release>
 | ||||||
|  | +        <arch>x86_64</arch>
 | ||||||
|  | +        <url>https://pagure.io/filesystem</url>
 | ||||||
|  | +        <summary>The basic directory layout for a Linux system</summary>
 | ||||||
|  | +        <description>The filesystem package is one of the basic packages that is installed
 | ||||||
|  | +on a Linux system. Filesystem contains the basic directory layout
 | ||||||
|  | +for a Linux operating system, including the correct permissions for
 | ||||||
|  | +the directories.</description>
 | ||||||
|  | +      </application>
 | ||||||
|  | +      <application>
 | ||||||
|  | +        <name>glibc</name>
 | ||||||
|  | +        <version>2.32</version>
 | ||||||
|  | +        <release>4.fc33</release>
 | ||||||
|  | +        <arch>x86_64</arch>
 | ||||||
|  | +        <url>http://www.gnu.org/software/glibc/</url>
 | ||||||
|  | +        <summary>The GNU libc libraries</summary>
 | ||||||
|  | +        <description>The glibc package contains standard libraries which are used by
 | ||||||
|  | +multiple programs on the system. In order to save disk space and
 | ||||||
|  | +memory, as well as to make upgrading easier, common system code is
 | ||||||
|  | +kept in one place and shared between programs. This particular package
 | ||||||
|  | +contains the most important sets of shared libraries: the standard C
 | ||||||
|  | +library and the standard math library. Without these two libraries, a
 | ||||||
|  | +Linux system will not function.</description>
 | ||||||
|  | +      </application>
 | ||||||
|  | +      <application>
 | ||||||
|  | +        <name>glibc-all-langpacks</name>
 | ||||||
|  | +        <version>2.32</version>
 | ||||||
|  | +        <release>4.fc33</release>
 | ||||||
|  | +        <arch>x86_64</arch>
 | ||||||
|  | +        <url>http://www.gnu.org/software/glibc/</url>
 | ||||||
|  | +        <summary>All language packs for glibc.</summary>
 | ||||||
|  | +      </application>
 | ||||||
|  | +      <application>
 | ||||||
|  | +        <name>glibc-common</name>
 | ||||||
|  | +        <version>2.32</version>
 | ||||||
|  | +        <release>4.fc33</release>
 | ||||||
|  |          <arch>x86_64</arch> | ||||||
|  | +        <url>http://www.gnu.org/software/glibc/</url>
 | ||||||
|  | +        <summary>Common binaries and locale data for glibc</summary>
 | ||||||
|  | +        <description>The glibc-common package includes common binaries for the GNU libc
 | ||||||
|  | +libraries, as well as national language (locale) support.</description>
 | ||||||
|  |        </application> | ||||||
|  |        <application> | ||||||
|  | -        <name>test2</name>
 | ||||||
|  | -        <version>2.0</version>
 | ||||||
|  | -        <release>2.fc14</release>
 | ||||||
|  | +        <name>gpg-pubkey</name>
 | ||||||
|  | +        <version>9570ff31</version>
 | ||||||
|  | +        <release>5e3006fb</release>
 | ||||||
|  | +        <arch>(none)</arch>
 | ||||||
|  | +        <url>(none)</url>
 | ||||||
|  | +        <summary>Fedora (33) <fedora-33-primary@fedoraproject.org> public key</summary>
 | ||||||
|  | +        <description>-----BEGIN PGP PUBLIC KEY BLOCK-----
 | ||||||
|  | +Version: rpm-4.16.1.2 (NSS-3)
 | ||||||
|  | +
 | ||||||
|  | +mQINBF4wBvsBEADQmcGbVUbDRUoXADReRmOOEMeydHghtKC9uRs9YNpGYZIB+bie
 | ||||||
|  | +bGYZmflQayfh/wEpO2W/IZfGpHPL42V7SbyvqMjwNls/fnXsCtf4LRofNK8Qd9fN
 | ||||||
|  | +kYargc9R7BEz/mwXKMiRQVx+DzkmqGWy2gq4iD0/mCyf5FdJCE40fOWoIGJXaOI1
 | ||||||
|  | +Tz1vWqKwLS5T0dfmi9U4Tp/XsKOZGvN8oi5h0KmqFk7LEZr1MXarhi2Va86sgxsF
 | ||||||
|  | +QcZEKfu5tgD0r00vXzikoSjn3qA5JW5FW07F1pGP4bF5f9J3CZbQyOjTSWMmmfTm
 | ||||||
|  | +2d2BURWzaDiJN9twY2yjzkoOMuPdXXvovg7KxLcQerKT+FbKbq8DySJX2rnOA77k
 | ||||||
|  | +UG4c9BGf/L1uBkAT8dpHLk6Uf5BfmypxUkydSWT1xfTDnw1MqxO0MsLlAHOR3J7c
 | ||||||
|  | +oW9kLcOLuCQn1hBEwfZv7VSWBkGXSmKfp0LLIxAFgRtv+Dh+rcMMRdJgKr1V3FU+
 | ||||||
|  | +rZ1+ZAfYiBpQJFPjv70vx+rGEgS801D3PJxBZUEy4Ic4ZYaKNhK9x9PRQuWcIBuW
 | ||||||
|  | +6eTe/6lKWZeyxCumLLdiS75mF2oTcBaWeoc3QxrPRV15eDKeYJMbhnUai/7lSrhs
 | ||||||
|  | +EWCkKR1RivgF4slYmtNE5ZPGZ/d61zjwn2xi4xNJVs8q9WRPMpHp0vCyMwARAQAB
 | ||||||
|  | +tDFGZWRvcmEgKDMzKSA8ZmVkb3JhLTMzLXByaW1hcnlAZmVkb3JhcHJvamVjdC5v
 | ||||||
|  | +cmc+iQI4BBMBAgAiBQJeMAb7AhsPBgsJCAcDAgYVCAIJCgsEFgIDAQIeAQIXgAAK
 | ||||||
|  | +CRBJ/XdJlXD/MZm2D/9kriL43vd3+0DNMeA82n2v9mSR2PQqKny39xNlYPyy/1yZ
 | ||||||
|  | +P/KXoa4NYSCA971LSd7lv4n/h5bEKgGHxZfttfOzOnWMVSSTfjRyM/df/NNzTUEV
 | ||||||
|  | +7ORA5GW18g8PEtS7uRxVBf3cLvWu5q+8jmqES5HqTAdGVcuIFQeBXFN8Gy1Jinuz
 | ||||||
|  | +AH8rJSdkUeZ0cehWbERq80BWM9dhad5dW+/+Gv0foFBvP15viwhWqajr8V0B8es+
 | ||||||
|  | +2/tHI0k86FAujV5i0rrXl5UOoLilO57QQNDZH/qW9GsHwVI+2yecLstpUNLq+EZC
 | ||||||
|  | +GqTZCYoxYRpl0gAMbDLztSL/8Bc0tJrCRG3tavJotFYlgUK60XnXlQzRkh9rgsfT
 | ||||||
|  | +EXbQifWdQMMogzjCJr0hzJ+V1d0iozdUxB2ZEgTjukOvatkB77DY1FPZRkSFIQs+
 | ||||||
|  | +fdcjazDIBLIxwJu5QwvTNW8lOLnJ46g4sf1WJoUdNTbR0BaC7HHj1inVWi0p7IuN
 | ||||||
|  | +66EPGzJOSjLK+vW+J0ncPDEgLCV74RF/0nR5fVTdrmiopPrzFuguHf9S9gYI3Zun
 | ||||||
|  | +Yl8FJUu4kRO6JPPTicUXWX+8XZmE94aK14RCJL23nOSi8T1eW8JLW43dCBRO8QUE
 | ||||||
|  | +Aso1t2pypm/1zZexJdOV8yGME3g5l2W6PLgpz58DBECgqc/kda+VWgEAp7rO2A==
 | ||||||
|  | +=EPL3
 | ||||||
|  | +-----END PGP PUBLIC KEY BLOCK-----
 | ||||||
|  | +</description>
 | ||||||
|  | +      </application>
 | ||||||
|  | +      <application>
 | ||||||
|  | +        <name>libgcc</name>
 | ||||||
|  | +        <version>10.2.1</version>
 | ||||||
|  | +        <release>9.fc33</release>
 | ||||||
|  |          <arch>x86_64</arch> | ||||||
|  | +        <url>http://gcc.gnu.org</url>
 | ||||||
|  | +        <summary>GCC version 10 shared support library</summary>
 | ||||||
|  | +        <description>This package contains GCC shared support library which is needed
 | ||||||
|  | +e.g. for exception handling support.</description>
 | ||||||
|  | +      </application>
 | ||||||
|  | +      <application>
 | ||||||
|  | +        <name>ncurses-base</name>
 | ||||||
|  | +        <version>6.2</version>
 | ||||||
|  | +        <release>3.20200222.fc33</release>
 | ||||||
|  | +        <arch>noarch</arch>
 | ||||||
|  | +        <url>https://invisible-island.net/ncurses/ncurses.html</url>
 | ||||||
|  | +        <summary>Descriptions of common terminals</summary>
 | ||||||
|  | +        <description>This package contains descriptions of common terminals. Other terminal
 | ||||||
|  | +descriptions are included in the ncurses-term package.</description>
 | ||||||
|  |        </application> | ||||||
|  |        <application> | ||||||
|  | -        <name>test3</name>
 | ||||||
|  | -        <version>3.0</version>
 | ||||||
|  | -        <release>3.fc14</release>
 | ||||||
|  | +        <name>ncurses-libs</name>
 | ||||||
|  | +        <version>6.2</version>
 | ||||||
|  | +        <release>3.20200222.fc33</release>
 | ||||||
|  |          <arch>x86_64</arch> | ||||||
|  | +        <url>https://invisible-island.net/ncurses/ncurses.html</url>
 | ||||||
|  | +        <summary>Ncurses libraries</summary>
 | ||||||
|  | +        <description>The curses library routines are a terminal-independent method of
 | ||||||
|  | +updating character screens with reasonable optimization.  The ncurses
 | ||||||
|  | +(new curses) library is a freely distributable replacement for the
 | ||||||
|  | +discontinued 4.4 BSD classic curses library.
 | ||||||
|  | +
 | ||||||
|  | +This package contains the ncurses libraries.</description>
 | ||||||
|  | +      </application>
 | ||||||
|  | +      <application>
 | ||||||
|  | +        <name>setup</name>
 | ||||||
|  | +        <version>2.13.7</version>
 | ||||||
|  | +        <release>2.fc33</release>
 | ||||||
|  | +        <arch>noarch</arch>
 | ||||||
|  | +        <url>https://pagure.io/setup/</url>
 | ||||||
|  | +        <summary>A set of system configuration and setup files</summary>
 | ||||||
|  | +        <description>The setup package contains a set of important system configuration and
 | ||||||
|  | +setup files, such as passwd, group, and profile.</description>
 | ||||||
|  | +      </application>
 | ||||||
|  | +      <application>
 | ||||||
|  | +        <name>tzdata</name>
 | ||||||
|  | +        <version>2021a</version>
 | ||||||
|  | +        <release>1.fc33</release>
 | ||||||
|  | +        <arch>noarch</arch>
 | ||||||
|  | +        <url>https://www.iana.org/time-zones</url>
 | ||||||
|  | +        <summary>Timezone data</summary>
 | ||||||
|  | +        <description>This package contains data files with rules for various timezones around
 | ||||||
|  | +the world.</description>
 | ||||||
|  |        </application> | ||||||
|  |      </applications> | ||||||
|  |    </operatingsystem> | ||||||
|  | -- 
 | ||||||
|  | 2.31.1 | ||||||
|  | 
 | ||||||
| @ -1,308 +0,0 @@ | |||||||
| From 42ae34115f1e6bff2b501d8ff3ab9ac26c892a22 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: "Richard W.M. Jones" <rjones@redhat.com> |  | ||||||
| Date: Wed, 19 Feb 2025 11:11:24 +0000 |  | ||||||
| Subject: [PATCH] daemon: New command_out and sh_out APIs |  | ||||||
| 
 |  | ||||||
| These APIs allow you to capture output from guest commands that |  | ||||||
| generate more output than the protocol limit allows. |  | ||||||
| 
 |  | ||||||
| Thanks: Nijin Ashok |  | ||||||
| Fixes: https://issues.redhat.com/browse/RHEL-80159 |  | ||||||
| (cherry picked from commit 47ac4871b2c1dcde317d116c52b13916ab368ea4) |  | ||||||
| ---
 |  | ||||||
|  .gitignore                                |  1 + |  | ||||||
|  daemon/sh.c                               | 42 +++++++++++++ |  | ||||||
|  generator/actions_core.ml                 | 25 ++++++++ |  | ||||||
|  generator/proc_nr.ml                      |  2 + |  | ||||||
|  lib/MAX_PROC_NR                           |  2 +- |  | ||||||
|  tests/Makefile.am                         | 10 ++++ |  | ||||||
|  tests/large-command/test-large-command.c  | 46 ++++++++++++++ |  | ||||||
|  tests/large-command/test-large-command.sh | 73 +++++++++++++++++++++++ |  | ||||||
|  8 files changed, 200 insertions(+), 1 deletion(-) |  | ||||||
|  create mode 100644 tests/large-command/test-large-command.c |  | ||||||
|  create mode 100755 tests/large-command/test-large-command.sh |  | ||||||
| 
 |  | ||||||
| diff --git a/.gitignore b/.gitignore
 |  | ||||||
| index 2fc52e84..68b27c79 100644
 |  | ||||||
| --- a/.gitignore
 |  | ||||||
| +++ b/.gitignore
 |  | ||||||
| @@ -423,6 +423,7 @@ Makefile.in
 |  | ||||||
|  /tests/disks/test-add-disks |  | ||||||
|  /tests/disks/test-qemu-drive-libvirt.xml |  | ||||||
|  /tests/events/test-libvirt-auth-callbacks |  | ||||||
| +/tests/large-command/test-large-command
 |  | ||||||
|  /tests/mount-local/test-parallel-mount-local |  | ||||||
|  /tests/mountable/test-internal-parse-mountable |  | ||||||
|  /tests/parallel/test-parallel |  | ||||||
| diff --git a/daemon/sh.c b/daemon/sh.c
 |  | ||||||
| index 21d4deea..f8440c1d 100644
 |  | ||||||
| --- a/daemon/sh.c
 |  | ||||||
| +++ b/daemon/sh.c
 |  | ||||||
| @@ -294,6 +294,40 @@ do_command_lines (char *const *argv)
 |  | ||||||
|    return lines;			/* Caller frees. */ |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| +/* Has one FileOut parameter. */
 |  | ||||||
| +int
 |  | ||||||
| +do_command_out (char *const *argv)
 |  | ||||||
| +{
 |  | ||||||
| +  /* We could in theory spool the command to output as it is running,
 |  | ||||||
| +   * but error handling mid-command, and progress bars would not work
 |  | ||||||
| +   * if we did that.  If we encounter a case where this is a problem,
 |  | ||||||
| +   * another approach would be to save the output in a temporary file.
 |  | ||||||
| +   */
 |  | ||||||
| +  CLEANUP_FREE char *out = NULL;
 |  | ||||||
| +  size_t i, n;
 |  | ||||||
| +
 |  | ||||||
| +  out = do_command (argv);
 |  | ||||||
| +  if (out == NULL)
 |  | ||||||
| +    return -1;
 |  | ||||||
| +
 |  | ||||||
| +  /* Send the reply message.  We know that we're not going to fail now
 |  | ||||||
| +   * (except for client cancellation).
 |  | ||||||
| +   */
 |  | ||||||
| +  reply (NULL, NULL);
 |  | ||||||
| +
 |  | ||||||
| +  n = strlen (out);
 |  | ||||||
| +  for (i = 0; i < n; i += GUESTFS_MAX_CHUNK_SIZE) {
 |  | ||||||
| +    if (send_file_write (out+i, MIN (GUESTFS_MAX_CHUNK_SIZE, n-i)) < 0)
 |  | ||||||
| +      return -1;
 |  | ||||||
| +    notify_progress (i, n);
 |  | ||||||
| +  }
 |  | ||||||
| +
 |  | ||||||
| +  if (send_file_end (0))
 |  | ||||||
| +    return -1;
 |  | ||||||
| +
 |  | ||||||
| +  return 0;
 |  | ||||||
| +}
 |  | ||||||
| +
 |  | ||||||
|  char * |  | ||||||
|  do_sh (const char *cmd) |  | ||||||
|  { |  | ||||||
| @@ -309,3 +343,11 @@ do_sh_lines (const char *cmd)
 |  | ||||||
|   |  | ||||||
|    return do_command_lines ((char **) argv); |  | ||||||
|  } |  | ||||||
| +
 |  | ||||||
| +int
 |  | ||||||
| +do_sh_out (const char *cmd)
 |  | ||||||
| +{
 |  | ||||||
| +  const char *argv[] = { "/bin/sh", "-c", cmd, NULL };
 |  | ||||||
| +
 |  | ||||||
| +  return do_command_out ((char **) argv);
 |  | ||||||
| +}
 |  | ||||||
| diff --git a/generator/actions_core.ml b/generator/actions_core.ml
 |  | ||||||
| index 768f5843..eb047b6b 100644
 |  | ||||||
| --- a/generator/actions_core.ml
 |  | ||||||
| +++ b/generator/actions_core.ml
 |  | ||||||
| @@ -2352,6 +2352,19 @@ result into a list of lines.
 |  | ||||||
|   |  | ||||||
|  See also: C<guestfs_sh_lines>" }; |  | ||||||
|   |  | ||||||
| +  { defaults with
 |  | ||||||
| +    name = "command_out"; added = (1, 55, 6);
 |  | ||||||
| +    style = RErr, [StringList (PlainString, "arguments"); String (FileOut, "output")], [];
 |  | ||||||
| +    progress = true; cancellable = true;
 |  | ||||||
| +    test_excuse = "there is a separate test in the tests directory";
 |  | ||||||
| +    shortdesc = "run a command from the guest filesystem";
 |  | ||||||
| +    longdesc = "\
 |  | ||||||
| +This is the same as C<guestfs_command>, but streams the output
 |  | ||||||
| +back, handling the case where the output from the command is
 |  | ||||||
| +larger than the protocol limit.
 |  | ||||||
| +
 |  | ||||||
| +See also: C<guestfs_sh_out>" };
 |  | ||||||
| +
 |  | ||||||
|    { defaults with |  | ||||||
|      name = "statvfs"; added = (1, 9, 2); |  | ||||||
|      style = RStruct ("statbuf", "statvfs"), [String (Pathname, "path")], []; |  | ||||||
| @@ -3461,6 +3474,18 @@ into a list of lines.
 |  | ||||||
|   |  | ||||||
|  See also: C<guestfs_command_lines>" }; |  | ||||||
|   |  | ||||||
| +  { defaults with
 |  | ||||||
| +    name = "sh_out"; added = (1, 55, 6);
 |  | ||||||
| +    style = RErr, [String (PlainString, "command"); String (FileOut, "output")], [];
 |  | ||||||
| +    test_excuse = "there is a separate test in the tests directory";
 |  | ||||||
| +    shortdesc = "run a command via the shell";
 |  | ||||||
| +    longdesc = "\
 |  | ||||||
| +This is the same as C<guestfs_sh>, but streams the output
 |  | ||||||
| +back, handling the case where the output from the command is
 |  | ||||||
| +larger than the protocol limit.
 |  | ||||||
| +
 |  | ||||||
| +See also: C<guestfs_command_out>" };
 |  | ||||||
| +
 |  | ||||||
|    { defaults with |  | ||||||
|      name = "glob_expand"; added = (1, 0, 50); |  | ||||||
|      (* Use Pathname here, and hence ABS_PATH (pattern,...) in |  | ||||||
| diff --git a/generator/proc_nr.ml b/generator/proc_nr.ml
 |  | ||||||
| index 56cd97a9..0ce12e66 100644
 |  | ||||||
| --- a/generator/proc_nr.ml
 |  | ||||||
| +++ b/generator/proc_nr.ml
 |  | ||||||
| @@ -518,6 +518,8 @@ let proc_nr = [
 |  | ||||||
|  513, "inspect_get_build_id"; |  | ||||||
|  514, "findfs_partuuid"; |  | ||||||
|  515, "findfs_partlabel"; |  | ||||||
| +516, "command_out";
 |  | ||||||
| +517, "sh_out";
 |  | ||||||
|  ] |  | ||||||
|   |  | ||||||
|  (* 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 3cda32fc..ac953cd0 100644
 |  | ||||||
| --- a/lib/MAX_PROC_NR
 |  | ||||||
| +++ b/lib/MAX_PROC_NR
 |  | ||||||
| @@ -1 +1 @@
 |  | ||||||
| -515
 |  | ||||||
| +517
 |  | ||||||
| diff --git a/tests/Makefile.am b/tests/Makefile.am
 |  | ||||||
| index 52155f64..f23fb6e9 100644
 |  | ||||||
| --- a/tests/Makefile.am
 |  | ||||||
| +++ b/tests/Makefile.am
 |  | ||||||
| @@ -440,6 +440,16 @@ EXTRA_DIST += http/test-http.py
 |  | ||||||
|  TESTS += journal/test-journal.pl |  | ||||||
|  EXTRA_DIST += journal/test-journal.pl |  | ||||||
|   |  | ||||||
| +# This binary must be statically linked.  It is used for testing
 |  | ||||||
| +# the "guestfs_command_out" function.
 |  | ||||||
| +
 |  | ||||||
| +large_command_test_large_command_SOURCES = large-command/test-large-command.c
 |  | ||||||
| +large_command_test_large_command_LDFLAGS = -all-static
 |  | ||||||
| +
 |  | ||||||
| +check_PROGRAMS += large-command/test-large-command
 |  | ||||||
| +TESTS += large-command/test-large-command.sh
 |  | ||||||
| +EXTRA_DIST += large-command/test-large-command.sh
 |  | ||||||
| +
 |  | ||||||
|  TESTS += \ |  | ||||||
|  	luks/test-luks.sh \ |  | ||||||
|  	luks/test-luks-list.sh \ |  | ||||||
| diff --git a/tests/large-command/test-large-command.c b/tests/large-command/test-large-command.c
 |  | ||||||
| new file mode 100644 |  | ||||||
| index 00000000..0abf435e
 |  | ||||||
| --- /dev/null
 |  | ||||||
| +++ b/tests/large-command/test-large-command.c
 |  | ||||||
| @@ -0,0 +1,46 @@
 |  | ||||||
| +/* libguestfs
 |  | ||||||
| + * Copyright (C) 2009-2025 Red Hat Inc.
 |  | ||||||
| + *
 |  | ||||||
| + * This program is free software; you can redistribute it and/or modify
 |  | ||||||
| + * it under the terms of the GNU General Public License as published by
 |  | ||||||
| + * 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.
 |  | ||||||
| + */
 |  | ||||||
| +
 |  | ||||||
| +/* This program, which must be statically linked, is used to test the
 |  | ||||||
| + * guestfs_command_out and guestfs_sh_out functions.
 |  | ||||||
| + */
 |  | ||||||
| +
 |  | ||||||
| +#include <config.h>
 |  | ||||||
| +#include <stdio.h>
 |  | ||||||
| +#include <stdlib.h>
 |  | ||||||
| +#include <string.h>
 |  | ||||||
| +#include <unistd.h>
 |  | ||||||
| +#include <error.h>
 |  | ||||||
| +
 |  | ||||||
| +#define STREQ(a,b) (strcmp((a),(b)) == 0)
 |  | ||||||
| +
 |  | ||||||
| +int
 |  | ||||||
| +main (int argc, char *argv[])
 |  | ||||||
| +{
 |  | ||||||
| +  size_t n, i;
 |  | ||||||
| +
 |  | ||||||
| +  if (argc > 1) {
 |  | ||||||
| +    if (sscanf (argv[1], "%zu", &n) != 1)
 |  | ||||||
| +      error (EXIT_FAILURE, 0, "could not parse parameter: %s", argv[1]);
 |  | ||||||
| +    for (i = 0; i < n; ++i)
 |  | ||||||
| +      putchar ('x');
 |  | ||||||
| +  } else
 |  | ||||||
| +    error (EXIT_FAILURE, 0, "missing parameter");
 |  | ||||||
| +
 |  | ||||||
| +  exit (EXIT_SUCCESS);
 |  | ||||||
| +}
 |  | ||||||
| diff --git a/tests/large-command/test-large-command.sh b/tests/large-command/test-large-command.sh
 |  | ||||||
| new file mode 100755 |  | ||||||
| index 00000000..abcfa868
 |  | ||||||
| --- /dev/null
 |  | ||||||
| +++ b/tests/large-command/test-large-command.sh
 |  | ||||||
| @@ -0,0 +1,73 @@
 |  | ||||||
| +#!/bin/bash -
 |  | ||||||
| +# libguestfs
 |  | ||||||
| +# Copyright (C) 2025 Red Hat Inc.
 |  | ||||||
| +#
 |  | ||||||
| +# This program is free software; you can redistribute it and/or modify
 |  | ||||||
| +# it under the terms of the GNU General Public License as published by
 |  | ||||||
| +# 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.
 |  | ||||||
| +
 |  | ||||||
| +# Test command-out.  We can't easily test sh-out without having a
 |  | ||||||
| +# shell (which requires a full guest), however the code path for both
 |  | ||||||
| +# is essentially identical.
 |  | ||||||
| +
 |  | ||||||
| +set -e
 |  | ||||||
| +
 |  | ||||||
| +$TEST_FUNCTIONS
 |  | ||||||
| +
 |  | ||||||
| +skip_if_skipped
 |  | ||||||
| +
 |  | ||||||
| +skip_unless stat --version
 |  | ||||||
| +
 |  | ||||||
| +# Binary must exist and must be linked statically.
 |  | ||||||
| +bin=large-command/test-large-command
 |  | ||||||
| +skip_unless test -x $bin
 |  | ||||||
| +skip_unless bash -c " ldd $bin |& grep -sq 'not a dynamic executable' "
 |  | ||||||
| +
 |  | ||||||
| +disk=large-command/test.img
 |  | ||||||
| +rm -f $disk
 |  | ||||||
| +
 |  | ||||||
| +out1=large-command/test.out1
 |  | ||||||
| +out2=large-command/test.out2
 |  | ||||||
| +out3=large-command/test.out3
 |  | ||||||
| +out4=large-command/test.out4
 |  | ||||||
| +
 |  | ||||||
| +# Must be larger than protocol size, currently 4MB.
 |  | ||||||
| +size=$((10 * 1024 * 1024))
 |  | ||||||
| +
 |  | ||||||
| +guestfish -x -N $disk=fs -m /dev/sda1 <<EOF
 |  | ||||||
| +upload $bin /test-large-command
 |  | ||||||
| +chmod 0755 /test-large-command
 |  | ||||||
| +command-out "/test-large-command $size" $out1
 |  | ||||||
| +# Check smaller sizes work as well.
 |  | ||||||
| +command-out "/test-large-command 0" $out2
 |  | ||||||
| +command-out "/test-large-command 1" $out3
 |  | ||||||
| +command-out "/test-large-command 80" $out4
 |  | ||||||
| +EOF
 |  | ||||||
| +
 |  | ||||||
| +ls -l $out1 $out2 $out3 $out4
 |  | ||||||
| +
 |  | ||||||
| +cat $out2
 |  | ||||||
| +cat $out3
 |  | ||||||
| +cat $out4
 |  | ||||||
| +
 |  | ||||||
| +# Check the sizes are correct.
 |  | ||||||
| +test "$( stat -c '%s' $out1 )" -eq $size
 |  | ||||||
| +test "$( stat -c '%s' $out2 )" -eq 0
 |  | ||||||
| +test "$( stat -c '%s' $out3 )" -eq 1
 |  | ||||||
| +test "$( stat -c '%s' $out4 )" -eq 80
 |  | ||||||
| +
 |  | ||||||
| +# Check the content is correct, for the smaller files.
 |  | ||||||
| +test `cat $out3` = "x"
 |  | ||||||
| +test `cat $out4` = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
 |  | ||||||
| +
 |  | ||||||
| +rm $disk $out1 $out2 $out3 $out4
 |  | ||||||
| @ -0,0 +1,65 @@ | |||||||
|  | From 6657d0c1018ab44ae680376463ac3f0421548fb4 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Laszlo Ersek <lersek@redhat.com> | ||||||
|  | Date: Thu, 23 Dec 2021 11:36:59 +0100 | ||||||
|  | Subject: [PATCH] launch-libvirt: place our virtio-net-pci device in slot 0x1e | ||||||
|  | 
 | ||||||
|  | The <qemu:commandline> trick we use for adding our virtio-net-pci device | ||||||
|  | in the libvirt backend can conflict with libvirtd's and QEMU's PCI address | ||||||
|  | assignment. Try to mitigate that by placing our device in slot 0x1e on the | ||||||
|  | root bus. In practice this could only conflict with a "dmi-to-pci-bridge" | ||||||
|  | device model, which libvirtd itself places in slot 0x1e. However, given | ||||||
|  | the XMLs we generate, and modern QEMU versions, libvirtd has no reason to | ||||||
|  | auto-add "dmi-to-pci-bridge". Refer to | ||||||
|  | <https://libvirt.org/formatdomain.html#controllers>. | ||||||
|  | 
 | ||||||
|  | Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2034160 | ||||||
|  | Signed-off-by: Laszlo Ersek <lersek@redhat.com> | ||||||
|  | Message-Id: <20211223103701.12702-2-lersek@redhat.com> | ||||||
|  | Reviewed-by: Richard W.M. Jones <rjones@redhat.com> | ||||||
|  | Tested-by: Richard W.M. Jones <rjones@redhat.com> | ||||||
|  | (cherry picked from commit 5ce5ef6a97a58c5e906083ad4e944545712b3f3f) | ||||||
|  | ---
 | ||||||
|  |  lib/guestfs-internal.h | 11 +++++++++++ | ||||||
|  |  lib/launch-libvirt.c   |  4 +++- | ||||||
|  |  2 files changed, 14 insertions(+), 1 deletion(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/lib/guestfs-internal.h b/lib/guestfs-internal.h
 | ||||||
|  | index 4799ee0a1..0b46f0070 100644
 | ||||||
|  | --- a/lib/guestfs-internal.h
 | ||||||
|  | +++ b/lib/guestfs-internal.h
 | ||||||
|  | @@ -147,6 +147,17 @@
 | ||||||
|  |  #define VIRTIO_DEVICE_NAME(type) type "-pci" | ||||||
|  |  #endif | ||||||
|  |   | ||||||
|  | +/* Place the virtio-net controller in slot 0x1e on the root bus, on normal
 | ||||||
|  | + * hardware with PCI. Refer to RHBZ#2034160.
 | ||||||
|  | + */
 | ||||||
|  | +#ifdef HAVE_LIBVIRT_BACKEND
 | ||||||
|  | +#if defined(__arm__) || defined(__s390x__)
 | ||||||
|  | +#define VIRTIO_NET_PCI_ADDR ""
 | ||||||
|  | +#else
 | ||||||
|  | +#define VIRTIO_NET_PCI_ADDR ",addr=1e.0"
 | ||||||
|  | +#endif
 | ||||||
|  | +#endif
 | ||||||
|  | +
 | ||||||
|  |  /* Guestfs handle and associated structures. */ | ||||||
|  |   | ||||||
|  |  /* State. */ | ||||||
|  | diff --git a/lib/launch-libvirt.c b/lib/launch-libvirt.c
 | ||||||
|  | index 026dc6b26..5842319df 100644
 | ||||||
|  | --- a/lib/launch-libvirt.c
 | ||||||
|  | +++ b/lib/launch-libvirt.c
 | ||||||
|  | @@ -1834,7 +1834,9 @@ construct_libvirt_xml_qemu_cmdline (guestfs_h *g,
 | ||||||
|  |        } end_element (); | ||||||
|  |   | ||||||
|  |        start_element ("qemu:arg") { | ||||||
|  | -        attribute ("value", VIRTIO_DEVICE_NAME ("virtio-net") ",netdev=usernet");
 | ||||||
|  | +        attribute ("value", (VIRTIO_DEVICE_NAME ("virtio-net")
 | ||||||
|  | +                             ",netdev=usernet"
 | ||||||
|  | +                             VIRTIO_NET_PCI_ADDR));
 | ||||||
|  |        } end_element (); | ||||||
|  |      } | ||||||
|  |   | ||||||
|  | -- 
 | ||||||
|  | 2.31.1 | ||||||
|  | 
 | ||||||
| @ -1,45 +0,0 @@ | |||||||
| From 19c4d1c8b9f278e054594660b5392d6c08a59d8f Mon Sep 17 00:00:00 2001 |  | ||||||
| From: "Richard W.M. Jones" <rjones@redhat.com> |  | ||||||
| Date: Mon, 10 Mar 2025 18:52:08 +0000 |  | ||||||
| Subject: [PATCH] lib: Print kernel utsname in debug output |  | ||||||
| 
 |  | ||||||
| Useful for debugging problems caused by the host kernel.  In |  | ||||||
| particular we were looking at a problem with passt creating a user |  | ||||||
| namespace but didn't know what exact kernel was being used. |  | ||||||
| 
 |  | ||||||
| (cherry picked from commit 31fa712aa07190f2c5ed789712b92b4be2d51488) |  | ||||||
| ---
 |  | ||||||
|  lib/launch.c | 6 ++++++ |  | ||||||
|  1 file changed, 6 insertions(+) |  | ||||||
| 
 |  | ||||||
| diff --git a/lib/launch.c b/lib/launch.c
 |  | ||||||
| index b9b76e50..9c44612d 100644
 |  | ||||||
| --- a/lib/launch.c
 |  | ||||||
| +++ b/lib/launch.c
 |  | ||||||
| @@ -36,6 +36,7 @@
 |  | ||||||
|  #include <signal.h> |  | ||||||
|  #include <sys/stat.h> |  | ||||||
|  #include <sys/types.h> |  | ||||||
| +#include <sys/utsname.h>
 |  | ||||||
|  #include <sys/wait.h> |  | ||||||
|  #include <errno.h> |  | ||||||
|  #include <assert.h> |  | ||||||
| @@ -93,6 +94,7 @@ guestfs_impl_launch (guestfs_h *g)
 |  | ||||||
|      struct backend *b; |  | ||||||
|      CLEANUP_FREE char *backend = guestfs_get_backend (g); |  | ||||||
|      int mask; |  | ||||||
| +    struct utsname utsname;
 |  | ||||||
|   |  | ||||||
|      debug (g, "launch: program=%s", g->program); |  | ||||||
|      if (STRNEQ (g->identifier, "")) |  | ||||||
| @@ -109,6 +111,10 @@ guestfs_impl_launch (guestfs_h *g)
 |  | ||||||
|      if (mask >= 0) |  | ||||||
|        debug (g, "launch: umask=0%03o", (unsigned) mask); |  | ||||||
|      debug (g, "launch: euid=%ju", (uintmax_t) geteuid ()); |  | ||||||
| +    if (uname (&utsname) == 0)
 |  | ||||||
| +      debug (g, "launch: host: %s %s %s %s %s",
 |  | ||||||
| +             utsname.sysname, utsname.nodename, utsname.release,
 |  | ||||||
| +             utsname.version, utsname.machine);
 |  | ||||||
|    } |  | ||||||
|   |  | ||||||
|    /* Launch the appliance. */ |  | ||||||
| @ -0,0 +1,70 @@ | |||||||
|  | From 4b9eac11db3e2cc9ace397ed4c804356a7d9adbf Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Laszlo Ersek <lersek@redhat.com> | ||||||
|  | Date: Thu, 23 Dec 2021 11:37:00 +0100 | ||||||
|  | Subject: [PATCH] lib: extract NETWORK_ADDRESS and NETWORK_PREFIX as macros | ||||||
|  | 
 | ||||||
|  | The 169.254.0.0/16 network specification (for the appliance) is currently | ||||||
|  | duplicated between the direct backend and the libvirt backend. In a | ||||||
|  | subsequent patch, we're going to need the network specification in yet | ||||||
|  | another spot; extract it now to the NETWORK_ADDRESS and NETWORK_PREFIX | ||||||
|  | macros (simply as strings). | ||||||
|  | 
 | ||||||
|  | Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2034160 | ||||||
|  | Signed-off-by: Laszlo Ersek <lersek@redhat.com> | ||||||
|  | Message-Id: <20211223103701.12702-3-lersek@redhat.com> | ||||||
|  | Reviewed-by: Richard W.M. Jones <rjones@redhat.com> | ||||||
|  | Tested-by: Richard W.M. Jones <rjones@redhat.com> | ||||||
|  | (cherry picked from commit 216de164e091a5c36403f24901698044a43ae0d9) | ||||||
|  | ---
 | ||||||
|  |  lib/guestfs-internal.h | 6 ++++++ | ||||||
|  |  lib/launch-direct.c    | 2 +- | ||||||
|  |  lib/launch-libvirt.c   | 3 ++- | ||||||
|  |  3 files changed, 9 insertions(+), 2 deletions(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/lib/guestfs-internal.h b/lib/guestfs-internal.h
 | ||||||
|  | index 0b46f0070..97a13ff2c 100644
 | ||||||
|  | --- a/lib/guestfs-internal.h
 | ||||||
|  | +++ b/lib/guestfs-internal.h
 | ||||||
|  | @@ -158,6 +158,12 @@
 | ||||||
|  |  #endif | ||||||
|  |  #endif | ||||||
|  |   | ||||||
|  | +/* Network address and network mask (expressed as address prefix) that the
 | ||||||
|  | + * appliance will see (if networking is enabled).
 | ||||||
|  | + */
 | ||||||
|  | +#define NETWORK_ADDRESS "169.254.0.0"
 | ||||||
|  | +#define NETWORK_PREFIX  "16"
 | ||||||
|  | +
 | ||||||
|  |  /* Guestfs handle and associated structures. */ | ||||||
|  |   | ||||||
|  |  /* State. */ | ||||||
|  | diff --git a/lib/launch-direct.c b/lib/launch-direct.c
 | ||||||
|  | index b6ed9766f..de17d2167 100644
 | ||||||
|  | --- a/lib/launch-direct.c
 | ||||||
|  | +++ b/lib/launch-direct.c
 | ||||||
|  | @@ -681,7 +681,7 @@ launch_direct (guestfs_h *g, void *datav, const char *arg)
 | ||||||
|  |      start_list ("-netdev") { | ||||||
|  |        append_list ("user"); | ||||||
|  |        append_list ("id=usernet"); | ||||||
|  | -      append_list ("net=169.254.0.0/16");
 | ||||||
|  | +      append_list ("net=" NETWORK_ADDRESS "/" NETWORK_PREFIX);
 | ||||||
|  |      } end_list (); | ||||||
|  |      start_list ("-device") { | ||||||
|  |        append_list (VIRTIO_DEVICE_NAME ("virtio-net")); | ||||||
|  | diff --git a/lib/launch-libvirt.c b/lib/launch-libvirt.c
 | ||||||
|  | index 5842319df..0f38f0aec 100644
 | ||||||
|  | --- a/lib/launch-libvirt.c
 | ||||||
|  | +++ b/lib/launch-libvirt.c
 | ||||||
|  | @@ -1826,7 +1826,8 @@ construct_libvirt_xml_qemu_cmdline (guestfs_h *g,
 | ||||||
|  |        } end_element (); | ||||||
|  |   | ||||||
|  |        start_element ("qemu:arg") { | ||||||
|  | -        attribute ("value", "user,id=usernet,net=169.254.0.0/16");
 | ||||||
|  | +        attribute ("value",
 | ||||||
|  | +                   "user,id=usernet,net=" NETWORK_ADDRESS "/" NETWORK_PREFIX);
 | ||||||
|  |        } end_element (); | ||||||
|  |   | ||||||
|  |        start_element ("qemu:arg") { | ||||||
|  | -- 
 | ||||||
|  | 2.31.1 | ||||||
|  | 
 | ||||||
| @ -1,29 +0,0 @@ | |||||||
| From fa1c16528267c89de8a2ecebd44405cbd04fa0ee Mon Sep 17 00:00:00 2001 |  | ||||||
| From: "Richard W.M. Jones" <rjones@redhat.com> |  | ||||||
| Date: Tue, 11 Mar 2025 13:36:12 +0000 |  | ||||||
| Subject: [PATCH] daemon: Fix loongarch64 detection on RHEL 9 |  | ||||||
| 
 |  | ||||||
| $ rpm -q file |  | ||||||
| file-5.39-16.el9.x86_64 |  | ||||||
| $ file ./test-data/binaries/bin-loongarch64-dynamic |  | ||||||
| ./test-data/binaries/bin-loongarch64-dynamic: ELF 64-bit LSB pie executable, *unknown arch 0x102* version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-loongarch-lp64d.so.1, BuildID[sha1]=7622a1a70bf6e697851ac3790557e1ca686459b5, for GNU/Linux 5.19.0, stripped |  | ||||||
| 
 |  | ||||||
| Updates: commit 729d6d55ea84494f0398d02450bd29c39c55f0bd |  | ||||||
| (cherry picked from commit 4176b2043f6cf65f8f5f4f7d6fa39beb9c0a22c6) |  | ||||||
| ---
 |  | ||||||
|  daemon/filearch.ml | 2 ++ |  | ||||||
|  1 file changed, 2 insertions(+) |  | ||||||
| 
 |  | ||||||
| diff --git a/daemon/filearch.ml b/daemon/filearch.ml
 |  | ||||||
| index 7dfc1cb7..e2bd5a2c 100644
 |  | ||||||
| --- a/daemon/filearch.ml
 |  | ||||||
| +++ b/daemon/filearch.ml
 |  | ||||||
| @@ -100,6 +100,8 @@ and canonical_elf_arch bits endianness elf_arch =
 |  | ||||||
|    ) |  | ||||||
|    else if substr "LoongArch" then |  | ||||||
|      sprintf "loongarch%s" bits |  | ||||||
| +  else if substr "*unknown arch 0x102*" then (* file command on RHEL 9 *)
 |  | ||||||
| +    sprintf "loongarch%s" bits
 |  | ||||||
|    else |  | ||||||
|      elf_arch |  | ||||||
|   |  | ||||||
| @ -0,0 +1,91 @@ | |||||||
|  | From 8570de6e766297e4c9feab1c54ae05037f33edeb Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Laszlo Ersek <lersek@redhat.com> | ||||||
|  | Date: Thu, 23 Dec 2021 11:37:01 +0100 | ||||||
|  | Subject: [PATCH] launch-libvirt: add virtio-net via the standard <interface> | ||||||
|  |  element | ||||||
|  | 
 | ||||||
|  | Starting with version 3.8.0, libvirt allows us to specify the network | ||||||
|  | address and network mask (as prefix) for SLIRP directly via the | ||||||
|  | <interface> element in the domain XML: | ||||||
|  | <https://libvirt.org/formatdomain.html#userspace-slirp-stack>. This means | ||||||
|  | we don't need the <qemu:commandline> hack for virtio-net on such versions. | ||||||
|  | 
 | ||||||
|  | Restrict the hack in construct_libvirt_xml_qemu_cmdline() to | ||||||
|  | libvirt<3.8.0, and generate the proper <interface> element in | ||||||
|  | construct_libvirt_xml_devices() on libvirt>=3.8.0. | ||||||
|  | 
 | ||||||
|  | Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2034160 | ||||||
|  | Suggested-by: Richard W.M. Jones <rjones@redhat.com> | ||||||
|  | Signed-off-by: Laszlo Ersek <lersek@redhat.com> | ||||||
|  | Message-Id: <20211223103701.12702-4-lersek@redhat.com> | ||||||
|  | Reviewed-by: Richard W.M. Jones <rjones@redhat.com> | ||||||
|  | Tested-by: Richard W.M. Jones <rjones@redhat.com> | ||||||
|  | (cherry picked from commit 5858c2cf6c24b3776e3867eafd9d86a1f4912d9c) | ||||||
|  | ---
 | ||||||
|  |  lib/guestfs-internal.h |  3 ++- | ||||||
|  |  lib/launch-libvirt.c   | 27 +++++++++++++++++++++++++-- | ||||||
|  |  2 files changed, 27 insertions(+), 3 deletions(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/lib/guestfs-internal.h b/lib/guestfs-internal.h
 | ||||||
|  | index 97a13ff2c..b11c945e9 100644
 | ||||||
|  | --- a/lib/guestfs-internal.h
 | ||||||
|  | +++ b/lib/guestfs-internal.h
 | ||||||
|  | @@ -148,7 +148,8 @@
 | ||||||
|  |  #endif | ||||||
|  |   | ||||||
|  |  /* Place the virtio-net controller in slot 0x1e on the root bus, on normal | ||||||
|  | - * hardware with PCI. Refer to RHBZ#2034160.
 | ||||||
|  | + * hardware with PCI. Necessary only before libvirt 3.8.0. Refer to
 | ||||||
|  | + * RHBZ#2034160.
 | ||||||
|  |   */ | ||||||
|  |  #ifdef HAVE_LIBVIRT_BACKEND | ||||||
|  |  #if defined(__arm__) || defined(__s390x__) | ||||||
|  | diff --git a/lib/launch-libvirt.c b/lib/launch-libvirt.c
 | ||||||
|  | index 0f38f0aec..f6bb39d99 100644
 | ||||||
|  | --- a/lib/launch-libvirt.c
 | ||||||
|  | +++ b/lib/launch-libvirt.c
 | ||||||
|  | @@ -1396,6 +1396,28 @@ construct_libvirt_xml_devices (guestfs_h *g,
 | ||||||
|  |        } end_element (); | ||||||
|  |      } end_element (); | ||||||
|  |   | ||||||
|  | +    /* Virtio-net NIC with SLIRP (= userspace) back-end, if networking is
 | ||||||
|  | +     * enabled. Starting with libvirt 3.8.0, we can specify the network address
 | ||||||
|  | +     * and prefix for SLIRP in the domain XML. Therefore, we can add the NIC
 | ||||||
|  | +     * via the standard <interface> element rather than <qemu:commandline>, and
 | ||||||
|  | +     * so libvirt can manage the PCI address of the virtio-net NIC like the PCI
 | ||||||
|  | +     * addresses of all other devices. Refer to RHBZ#2034160.
 | ||||||
|  | +     */
 | ||||||
|  | +    if (g->enable_network &&
 | ||||||
|  | +        guestfs_int_version_ge (¶ms->data->libvirt_version, 3, 8, 0)) {
 | ||||||
|  | +      start_element ("interface") {
 | ||||||
|  | +        attribute ("type", "user");
 | ||||||
|  | +        start_element ("model") {
 | ||||||
|  | +          attribute ("type", "virtio");
 | ||||||
|  | +        } end_element ();
 | ||||||
|  | +        start_element ("ip") {
 | ||||||
|  | +          attribute ("family", "ipv4");
 | ||||||
|  | +          attribute ("address", NETWORK_ADDRESS);
 | ||||||
|  | +          attribute ("prefix", NETWORK_PREFIX);
 | ||||||
|  | +        } end_element ();
 | ||||||
|  | +      } end_element ();
 | ||||||
|  | +    }
 | ||||||
|  | +
 | ||||||
|  |      /* Libvirt adds some devices by default.  Indicate to libvirt | ||||||
|  |       * that we don't want them. | ||||||
|  |       */ | ||||||
|  | @@ -1818,9 +1840,10 @@ construct_libvirt_xml_qemu_cmdline (guestfs_h *g,
 | ||||||
|  |      } end_element (); | ||||||
|  |   | ||||||
|  |      /* Workaround because libvirt user networking cannot specify "net=" | ||||||
|  | -     * parameter.
 | ||||||
|  | +     * parameter. Necessary only before libvirt 3.8.0; refer to RHBZ#2034160.
 | ||||||
|  |       */ | ||||||
|  | -    if (g->enable_network) {
 | ||||||
|  | +    if (g->enable_network &&
 | ||||||
|  | +        !guestfs_int_version_ge (¶ms->data->libvirt_version, 3, 8, 0)) {
 | ||||||
|  |        start_element ("qemu:arg") { | ||||||
|  |          attribute ("value", "-netdev"); | ||||||
|  |        } end_element (); | ||||||
|  | -- 
 | ||||||
|  | 2.31.1 | ||||||
|  | 
 | ||||||
							
								
								
									
										86
									
								
								SOURCES/0020-appliance-Use-cpu-max.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								SOURCES/0020-appliance-Use-cpu-max.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,86 @@ | |||||||
|  | From fbb053fc71c0c072acb3fbf6e5fbbfc3b0667fd2 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: "Richard W.M. Jones" <rjones@redhat.com> | ||||||
|  | Date: Thu, 28 Jan 2021 12:20:49 +0000 | ||||||
|  | Subject: [PATCH] appliance: Use -cpu max. | ||||||
|  | MIME-Version: 1.0 | ||||||
|  | Content-Type: text/plain; charset=UTF-8 | ||||||
|  | Content-Transfer-Encoding: 8bit | ||||||
|  | 
 | ||||||
|  | QEMU has a newish feature (from about 2017 / qemu 2.9) called -cpu max | ||||||
|  | which is supposed to select the best CPU, ideal for libguestfs. | ||||||
|  | 
 | ||||||
|  | After this change, on x86-64: | ||||||
|  | 
 | ||||||
|  |                KVM                          TCG | ||||||
|  | 
 | ||||||
|  | Direct         -cpu max                     -cpu max | ||||||
|  | (non-libvirt) | ||||||
|  | 
 | ||||||
|  | Libvirt   <cpu mode="host-passthrough">     <cpu mode="host-model"> | ||||||
|  |             <model fallback="allow"/>         <model fallback="allow"/> | ||||||
|  |           </cpu>                            </cpu> | ||||||
|  | 
 | ||||||
|  | Thanks: Daniel Berrangé | ||||||
|  | (cherry picked from commit 30f74f38bd6e42e783ba80895f4d6826abddd417) | ||||||
|  | ---
 | ||||||
|  |  lib/appliance-cpu.c  | 16 ++++++++-------- | ||||||
|  |  lib/launch-libvirt.c |  9 +++++++++ | ||||||
|  |  2 files changed, 17 insertions(+), 8 deletions(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/lib/appliance-cpu.c b/lib/appliance-cpu.c
 | ||||||
|  | index 5ef9f5c72..54ac6e2e3 100644
 | ||||||
|  | --- a/lib/appliance-cpu.c
 | ||||||
|  | +++ b/lib/appliance-cpu.c
 | ||||||
|  | @@ -38,6 +38,11 @@
 | ||||||
|  |   * | ||||||
|  |   * The literal string C<"host"> means use C<-cpu host>. | ||||||
|  |   * | ||||||
|  | + * =item C<"max">
 | ||||||
|  | + *
 | ||||||
|  | + * The literal string C<"max"> means use C<-cpu max> (the best
 | ||||||
|  | + * possible).  This requires awkward translation for libvirt.
 | ||||||
|  | + *
 | ||||||
|  |   * =item some string | ||||||
|  |   * | ||||||
|  |   * Some string such as C<"cortex-a57"> means use C<-cpu cortex-a57>. | ||||||
|  | @@ -80,14 +85,9 @@ guestfs_int_get_cpu_model (int kvm)
 | ||||||
|  |    /* See discussion in https://bugzilla.redhat.com/show_bug.cgi?id=1605071 */ | ||||||
|  |    return NULL; | ||||||
|  |  #else | ||||||
|  | -  /* On most architectures, it is faster to pass the CPU host model to
 | ||||||
|  | -   * the appliance, allowing maximum speed for things like checksums
 | ||||||
|  | -   * and encryption.  Only do this with KVM.  It is broken in subtle
 | ||||||
|  | -   * ways on TCG, and fairly pointless when you're emulating anyway.
 | ||||||
|  | +  /* On most architectures we can use "max" to get the best possible CPU.
 | ||||||
|  | +   * For recent qemu this should work even on TCG.
 | ||||||
|  |     */ | ||||||
|  | -  if (kvm)
 | ||||||
|  | -    return "host";
 | ||||||
|  | -  else
 | ||||||
|  | -    return NULL;
 | ||||||
|  | +  return "max";
 | ||||||
|  |  #endif | ||||||
|  |  } | ||||||
|  | diff --git a/lib/launch-libvirt.c b/lib/launch-libvirt.c
 | ||||||
|  | index f6bb39d99..e3ff1ffe0 100644
 | ||||||
|  | --- a/lib/launch-libvirt.c
 | ||||||
|  | +++ b/lib/launch-libvirt.c
 | ||||||
|  | @@ -1169,6 +1169,15 @@ construct_libvirt_xml_cpu (guestfs_h *g,
 | ||||||
|  |            attribute ("fallback", "allow"); | ||||||
|  |          } end_element (); | ||||||
|  |        } | ||||||
|  | +      else if (STREQ (cpu_model, "max")) {
 | ||||||
|  | +        if (params->data->is_kvm)
 | ||||||
|  | +          attribute ("mode", "host-passthrough");
 | ||||||
|  | +        else
 | ||||||
|  | +          attribute ("mode", "host-model");
 | ||||||
|  | +        start_element ("model") {
 | ||||||
|  | +          attribute ("fallback", "allow");
 | ||||||
|  | +        } end_element ();
 | ||||||
|  | +      }
 | ||||||
|  |        else | ||||||
|  |          single_element ("model", cpu_model); | ||||||
|  |      } end_element (); | ||||||
|  | -- 
 | ||||||
|  | 2.31.1 | ||||||
|  | 
 | ||||||
| @ -1,69 +0,0 @@ | |||||||
| From 68cecb64758b8ff6d3af842721cb7cf706cb5d0c Mon Sep 17 00:00:00 2001 |  | ||||||
| From: "Richard W.M. Jones" <rjones@redhat.com> |  | ||||||
| Date: Wed, 16 Apr 2025 10:01:33 +0100 |  | ||||||
| Subject: [PATCH] daemon: inspect: Add some debugging of /usr merging |  | ||||||
| 
 |  | ||||||
| (cherry picked from commit 2d1e8941301373d04a436333219358a72f9660f1) |  | ||||||
| ---
 |  | ||||||
|  daemon/inspect.ml | 15 ++++++++++++++- |  | ||||||
|  1 file changed, 14 insertions(+), 1 deletion(-) |  | ||||||
| 
 |  | ||||||
| diff --git a/daemon/inspect.ml b/daemon/inspect.ml
 |  | ||||||
| index f6e0ce1f..bec9d567 100644
 |  | ||||||
| --- a/daemon/inspect.ml
 |  | ||||||
| +++ b/daemon/inspect.ml
 |  | ||||||
| @@ -47,18 +47,21 @@ let rec inspect_os () =
 |  | ||||||
|     * multiple filesystems. Gather all the inspected information in the |  | ||||||
|     * inspect_fs struct of the root filesystem. |  | ||||||
|     *) |  | ||||||
| +  eprintf "inspect_os: collect_coreos_inspection_info\n%!";
 |  | ||||||
|    let fses = collect_coreos_inspection_info fses in |  | ||||||
|   |  | ||||||
|    (* Check if the same filesystem was listed twice as root in fses. |  | ||||||
|     * This may happen for the *BSD root partition where an MBR partition |  | ||||||
|     * is a shadow of the real root partition probably /dev/sda5 |  | ||||||
|     *) |  | ||||||
| +  eprintf "inspect_os: check_for_duplicated_bsd_root\n%!";
 |  | ||||||
|    let fses = check_for_duplicated_bsd_root fses in |  | ||||||
|   |  | ||||||
|    (* For Linux guests with a separate /usr filesystem, merge some of the |  | ||||||
|     * inspected information in that partition to the inspect_fs struct |  | ||||||
|     * of the root filesystem. |  | ||||||
|     *) |  | ||||||
| +  eprintf "inspect_os: collect_linux_inspection_info\n%!";
 |  | ||||||
|    let fses = collect_linux_inspection_info fses in |  | ||||||
|   |  | ||||||
|    (* Save what we found in a global variable. *) |  | ||||||
| @@ -194,6 +197,9 @@ and collect_linux_inspection_info fses =
 |  | ||||||
|   * or other ways to identify the OS). |  | ||||||
|   *) |  | ||||||
|  and collect_linux_inspection_info_for fses root = |  | ||||||
| +  eprintf "inspect_os: collect_linux_inspection_info_for %s\n"
 |  | ||||||
| +    (string_of_location root.fs_location);
 |  | ||||||
| +
 |  | ||||||
|    let root_fstab = |  | ||||||
|      match root with |  | ||||||
|      | { role = RoleRoot { fstab = f } } -> f |  | ||||||
| @@ -207,14 +213,21 @@ and collect_linux_inspection_info_for fses root =
 |  | ||||||
|             (* This checks that this usr is found in the fstab of |  | ||||||
|              * the root filesystem. |  | ||||||
|              *) |  | ||||||
| +           eprintf "inspect_os: checking if %s found in fstab of this root\n"
 |  | ||||||
| +             (string_of_location usr_mp);
 |  | ||||||
|             List.exists ( |  | ||||||
|               fun (mountable, _) -> |  | ||||||
| +               eprintf "inspect_os: collect_linux_inspection_info_for: \
 |  | ||||||
| +                        compare %s = %s\n"
 |  | ||||||
| +                 (Mountable.to_string usr_mp.mountable)
 |  | ||||||
| +                 (Mountable.to_string mountable);
 |  | ||||||
|                 usr_mp.mountable = mountable |  | ||||||
|             ) root_fstab |  | ||||||
|          | _ -> false |  | ||||||
|        ) fses in |  | ||||||
|   |  | ||||||
| -    eprintf "collect_linux_inspection_info_for: merging:\n%sinto:\n%s"
 |  | ||||||
| +    eprintf "inspect_os: collect_linux_inspection_info_for: merging:\n\
 |  | ||||||
| +             %sinto:\n%s"
 |  | ||||||
|        (string_of_fs usr) (string_of_fs root); |  | ||||||
|      merge usr root; |  | ||||||
|      root |  | ||||||
| @ -0,0 +1,48 @@ | |||||||
|  | From 7dde1007525ec235e769351be15ca5de34eeda4a Mon Sep 17 00:00:00 2001 | ||||||
|  | From: "Richard W.M. Jones" <rjones@redhat.com> | ||||||
|  | Date: Thu, 18 Mar 2021 12:32:26 +0000 | ||||||
|  | Subject: [PATCH] appliance: Use <cpu mode="maximum"/> for -cpu max on libvirt. | ||||||
|  | 
 | ||||||
|  | Note this requires libvirt >= 7.1.0 which was only released in March 2021. | ||||||
|  | 
 | ||||||
|  | With an older libvirt you will see this error: | ||||||
|  | 
 | ||||||
|  |   Original error from libvirt: unsupported configuration: Invalid mode attribute 'maximum' [code=67 int1=-1] | ||||||
|  | 
 | ||||||
|  | In theory we could check if this is supported by looking at the | ||||||
|  | libvirt capabilities and fall back, but this commit does not do that, | ||||||
|  | in the expectation that most people will be using the default backend | ||||||
|  | (direct) and on Fedora/RHEL we will add an explicit minimum version | ||||||
|  | dependency to the package. | ||||||
|  | 
 | ||||||
|  | qemu support has been around quite a bit longer (at least since 2017). | ||||||
|  | 
 | ||||||
|  | Fixes: commit 30f74f38bd6e42e783ba80895f4d6826abddd417 | ||||||
|  | (cherry picked from commit 13ceb6a87b2869909a6a0e3c8caa962b72e4cb0e) | ||||||
|  | ---
 | ||||||
|  |  lib/launch-libvirt.c | 9 ++------- | ||||||
|  |  1 file changed, 2 insertions(+), 7 deletions(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/lib/launch-libvirt.c b/lib/launch-libvirt.c
 | ||||||
|  | index e3ff1ffe0..db619910f 100644
 | ||||||
|  | --- a/lib/launch-libvirt.c
 | ||||||
|  | +++ b/lib/launch-libvirt.c
 | ||||||
|  | @@ -1170,13 +1170,8 @@ construct_libvirt_xml_cpu (guestfs_h *g,
 | ||||||
|  |          } end_element (); | ||||||
|  |        } | ||||||
|  |        else if (STREQ (cpu_model, "max")) { | ||||||
|  | -        if (params->data->is_kvm)
 | ||||||
|  | -          attribute ("mode", "host-passthrough");
 | ||||||
|  | -        else
 | ||||||
|  | -          attribute ("mode", "host-model");
 | ||||||
|  | -        start_element ("model") {
 | ||||||
|  | -          attribute ("fallback", "allow");
 | ||||||
|  | -        } end_element ();
 | ||||||
|  | +        /* https://bugzilla.redhat.com/show_bug.cgi?id=1935572#c11 */
 | ||||||
|  | +        attribute ("mode", "maximum");
 | ||||||
|  |        } | ||||||
|  |        else | ||||||
|  |          single_element ("model", cpu_model); | ||||||
|  | -- 
 | ||||||
|  | 2.31.1 | ||||||
|  | 
 | ||||||
| @ -1,490 +0,0 @@ | |||||||
| From 4e27b259c166d87a57d133a79b8eed3b556288b8 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: "Richard W.M. Jones" <rjones@redhat.com> |  | ||||||
| Date: Wed, 16 Apr 2025 11:35:13 +0100 |  | ||||||
| Subject: [PATCH] generator: Implement struct FDevice type |  | ||||||
| 
 |  | ||||||
| This acts just like FString except that we do reverse device name |  | ||||||
| translation on it.  The only use is in the 'pvs-full' API where we |  | ||||||
| will use it (in a subsequent commit) to reverse translate the pv_name |  | ||||||
| field (a device name) before returning it from the daemon. |  | ||||||
| 
 |  | ||||||
| Compare this to the 'pvs' API which also returns a list of device |  | ||||||
| names, but using the generator's 'RStructList (RDevice,...)'  return |  | ||||||
| type, where RDevice is similarly reverse translated. |  | ||||||
| 
 |  | ||||||
| Note in the library-side bindings, because the name has already been |  | ||||||
| translated in the daemon, we just treat it exactly the same as |  | ||||||
| FString.  The vast majority of this patch is this mechanical change. |  | ||||||
| 
 |  | ||||||
| (cherry picked from commit 0ff73a42c7f4f309fbab11ea2e89ee6f0501367d) |  | ||||||
| ---
 |  | ||||||
|  generator/GObject.ml |  6 +++--- |  | ||||||
|  generator/OCaml.ml   |  6 ++---- |  | ||||||
|  generator/XDR.ml     |  2 +- |  | ||||||
|  generator/c.ml       | 20 +++++++++----------- |  | ||||||
|  generator/csharp.ml  |  2 +- |  | ||||||
|  generator/daemon.ml  | 30 ++++++++++++++++++++++++++---- |  | ||||||
|  generator/erlang.ml  |  2 +- |  | ||||||
|  generator/golang.ml  |  4 ++-- |  | ||||||
|  generator/java.ml    |  7 ++++--- |  | ||||||
|  generator/lua.ml     |  2 +- |  | ||||||
|  generator/perl.ml    |  4 ++-- |  | ||||||
|  generator/php.ml     |  4 ++-- |  | ||||||
|  generator/python.ml  |  2 +- |  | ||||||
|  generator/ruby.ml    |  4 ++-- |  | ||||||
|  generator/rust.ml    |  6 +++--- |  | ||||||
|  generator/types.ml   |  1 + |  | ||||||
|  generator/types.mli  |  1 + |  | ||||||
|  17 files changed, 62 insertions(+), 41 deletions(-) |  | ||||||
| 
 |  | ||||||
| diff --git a/generator/GObject.ml b/generator/GObject.ml
 |  | ||||||
| index 6c74b31b..e7462c0e 100644
 |  | ||||||
| --- a/generator/GObject.ml
 |  | ||||||
| +++ b/generator/GObject.ml
 |  | ||||||
| @@ -206,7 +206,7 @@ let generate_gobject_struct_header filename typ cols () =
 |  | ||||||
|        pr " * @%s: An unsigned 64-bit integer\n" n |  | ||||||
|      | n, FInt64 -> |  | ||||||
|        pr " * @%s: A signed 64-bit integer\n" n |  | ||||||
| -    | n, FString ->
 |  | ||||||
| +    | n, (FString|FDevice) ->
 |  | ||||||
|        pr " * @%s: A NULL-terminated string\n" n |  | ||||||
|      | n, FBuffer -> |  | ||||||
|        pr " * @%s: A GByteArray\n" n |  | ||||||
| @@ -231,7 +231,7 @@ let generate_gobject_struct_header filename typ cols () =
 |  | ||||||
|        pr "  guint64 %s;\n" n |  | ||||||
|      | n, FInt64 -> |  | ||||||
|        pr "  gint64 %s;\n" n |  | ||||||
| -    | n, FString ->
 |  | ||||||
| +    | n, (FString|FDevice) ->
 |  | ||||||
|        pr "  gchar *%s;\n" n |  | ||||||
|      | n, FBuffer -> |  | ||||||
|        pr "  GByteArray *%s;\n" n |  | ||||||
| @@ -1228,7 +1228,7 @@ guestfs_session_close (GuestfsSession *session, GError **err)
 |  | ||||||
|            | n, FUUID -> |  | ||||||
|              pr "%smemcpy (%s%s, %s%s, sizeof (%s%s));\n" |  | ||||||
|                indent dst n src n dst n |  | ||||||
| -          | n, FString ->
 |  | ||||||
| +          | n, (FString|FDevice) ->
 |  | ||||||
|              pr "%sif (%s%s) %s%s = g_strdup (%s%s);\n" |  | ||||||
|                indent src n dst n src n |  | ||||||
|            | n, FBuffer -> |  | ||||||
| diff --git a/generator/OCaml.ml b/generator/OCaml.ml
 |  | ||||||
| index 1e6f603a..4ef07e27 100644
 |  | ||||||
| --- a/generator/OCaml.ml
 |  | ||||||
| +++ b/generator/OCaml.ml
 |  | ||||||
| @@ -512,7 +512,7 @@ copy_table (char * const * argv)
 |  | ||||||
|        List.iteri ( |  | ||||||
|          fun i col -> |  | ||||||
|            (match col with |  | ||||||
| -           | name, FString ->
 |  | ||||||
| +           | name, (FString|FDevice) ->
 |  | ||||||
|                 pr "  v = caml_copy_string (%s->%s);\n" typ name |  | ||||||
|             | name, FBuffer -> |  | ||||||
|                 pr "  v = caml_alloc_initialized_string (%s->%s_len, %s->%s);\n" |  | ||||||
| @@ -839,9 +839,7 @@ and generate_ocaml_structure_decls () =
 |  | ||||||
|        pr "type %s = {\n" typ; |  | ||||||
|        List.iter ( |  | ||||||
|          function |  | ||||||
| -        | name, FString -> pr "  %s : string;\n" name
 |  | ||||||
| -        | name, FBuffer -> pr "  %s : string;\n" name
 |  | ||||||
| -        | name, FUUID -> pr "  %s : string;\n" name
 |  | ||||||
| +        | name, (FString|FDevice|FBuffer|FUUID) -> pr "  %s : string;\n" name
 |  | ||||||
|          | name, (FBytes|FInt64|FUInt64) -> pr "  %s : int64;\n" name |  | ||||||
|          | name, (FInt32|FUInt32) -> pr "  %s : int32;\n" name |  | ||||||
|          | name, FChar -> pr "  %s : char;\n" name |  | ||||||
| diff --git a/generator/XDR.ml b/generator/XDR.ml
 |  | ||||||
| index 566ba69e..e71d97f5 100644
 |  | ||||||
| --- a/generator/XDR.ml
 |  | ||||||
| +++ b/generator/XDR.ml
 |  | ||||||
| @@ -66,7 +66,7 @@ let generate_xdr () =
 |  | ||||||
|          pr "struct guestfs_int_%s {\n" typ; |  | ||||||
|          List.iter (function |  | ||||||
|                     | name, FChar -> pr "  char %s;\n" name |  | ||||||
| -                   | name, FString -> pr "  string %s<>;\n" name
 |  | ||||||
| +                   | name, (FString|FDevice) -> pr "  string %s<>;\n" name
 |  | ||||||
|                     | name, FBuffer -> pr "  opaque %s<>;\n" name |  | ||||||
|                     | name, FUUID -> pr "  opaque %s[32];\n" name |  | ||||||
|                     | name, FInt32 -> pr "  int %s;\n" name |  | ||||||
| diff --git a/generator/c.ml b/generator/c.ml
 |  | ||||||
| index 09181028..124aeb6d 100644
 |  | ||||||
| --- a/generator/c.ml
 |  | ||||||
| +++ b/generator/c.ml
 |  | ||||||
| @@ -352,7 +352,7 @@ and generate_structs_pod () =
 |  | ||||||
|          | name, FInt32 -> pr "   int32_t %s;\n" name |  | ||||||
|          | name, (FUInt64|FBytes) -> pr "   uint64_t %s;\n" name |  | ||||||
|          | name, FInt64 -> pr "   int64_t %s;\n" name |  | ||||||
| -        | name, FString -> pr "   char *%s;\n" name
 |  | ||||||
| +        | name, (FString|FDevice) -> pr "   char *%s;\n" name
 |  | ||||||
|          | name, FBuffer -> |  | ||||||
|              pr "   /* The next two fields describe a byte array. */\n"; |  | ||||||
|              pr "   uint32_t %s_len;\n" name; |  | ||||||
| @@ -609,7 +609,7 @@ extern GUESTFS_DLL_PUBLIC void *guestfs_next_private (guestfs_h *g, const char *
 |  | ||||||
|        List.iter ( |  | ||||||
|          function |  | ||||||
|          | name, FChar -> pr "  char %s;\n" name |  | ||||||
| -        | name, FString -> pr "  char *%s;\n" name
 |  | ||||||
| +        | name, (FString|FDevice) -> pr "  char *%s;\n" name
 |  | ||||||
|          | name, FBuffer -> |  | ||||||
|              pr "  uint32_t %s_len;\n" name; |  | ||||||
|              pr "  char *%s;\n" name |  | ||||||
| @@ -916,7 +916,7 @@ and generate_client_structs_compare () =
 |  | ||||||
|      fun { s_name = typ; s_cols = cols } -> |  | ||||||
|        let has_nonnumeric_cols = |  | ||||||
|          let nonnumeric = function |  | ||||||
| -          | _,(FString|FUUID|FBuffer) -> true
 |  | ||||||
| +          | _,(FString|FDevice|FUUID|FBuffer) -> true
 |  | ||||||
|            | _,(FChar|FUInt32|FInt32|FUInt64|FBytes|FInt64|FOptPercent) -> false |  | ||||||
|          in |  | ||||||
|          List.exists nonnumeric cols in |  | ||||||
| @@ -932,7 +932,7 @@ and generate_client_structs_compare () =
 |  | ||||||
|        ); |  | ||||||
|        List.iter ( |  | ||||||
|          function |  | ||||||
| -        | name, FString ->
 |  | ||||||
| +        | name, (FString|FDevice) ->
 |  | ||||||
|            pr "  r = strcmp (s1->%s, s2->%s);\n" name name; |  | ||||||
|            pr "  if (r != 0) return r;\n" |  | ||||||
|          | name, FBuffer -> |  | ||||||
| @@ -1001,7 +1001,7 @@ and generate_client_structs_copy () =
 |  | ||||||
|      fun { s_name = typ; s_cols = cols } -> |  | ||||||
|        let has_boxed_cols = |  | ||||||
|          let boxed = function |  | ||||||
| -          | _,(FString|FBuffer) -> true
 |  | ||||||
| +          | _,(FString|FDevice|FBuffer) -> true
 |  | ||||||
|            | _,(FChar|FUUID|FUInt32|FInt32|FUInt64|FBytes|FInt64|FOptPercent) -> |  | ||||||
|              false |  | ||||||
|          in |  | ||||||
| @@ -1014,8 +1014,7 @@ and generate_client_structs_copy () =
 |  | ||||||
|          pr "{\n"; |  | ||||||
|          List.iter ( |  | ||||||
|            function |  | ||||||
| -          | name, FString
 |  | ||||||
| -          | name, FBuffer -> pr "  free (s->%s);\n" name
 |  | ||||||
| +          | name, (FString|FDevice|FBuffer) -> pr "  free (s->%s);\n" name
 |  | ||||||
|            | _, FChar |  | ||||||
|            | _, FUUID |  | ||||||
|            | _, FUInt32 |  | ||||||
| @@ -1038,8 +1037,7 @@ and generate_client_structs_copy () =
 |  | ||||||
|          pr "\n"; |  | ||||||
|          List.iter ( |  | ||||||
|            function |  | ||||||
| -          | name, FString
 |  | ||||||
| -          | name, FBuffer -> pr "  out->%s = NULL;\n" name
 |  | ||||||
| +          | name, (FString|FDevice|FBuffer) -> pr "  out->%s = NULL;\n" name
 |  | ||||||
|            | _, FChar |  | ||||||
|            | _, FUUID |  | ||||||
|            | _, FUInt32 |  | ||||||
| @@ -1051,7 +1049,7 @@ and generate_client_structs_copy () =
 |  | ||||||
|          ) cols; |  | ||||||
|          List.iter ( |  | ||||||
|            function |  | ||||||
| -          | name, FString ->
 |  | ||||||
| +          | name, (FString|FDevice) ->
 |  | ||||||
|              pr "  out->%s = strdup (inp->%s);\n" name name; |  | ||||||
|              pr "  if (out->%s == NULL) goto error;\n" name |  | ||||||
|            | name, FBuffer -> |  | ||||||
| @@ -1234,7 +1232,7 @@ and generate_client_structs_print_c () =
 |  | ||||||
|          ); |  | ||||||
|          List.iter ( |  | ||||||
|            function |  | ||||||
| -          | name, FString ->
 |  | ||||||
| +          | name, (FString|FDevice) ->
 |  | ||||||
|                pr "  fprintf (dest, \"%%s%s: %%s%%s\", indent, %s->%s, linesep);\n" |  | ||||||
|                  name typ name |  | ||||||
|            | name, FUUID -> |  | ||||||
| diff --git a/generator/csharp.ml b/generator/csharp.ml
 |  | ||||||
| index 43579df5..6ab6c3c9 100644
 |  | ||||||
| --- a/generator/csharp.ml
 |  | ||||||
| +++ b/generator/csharp.ml
 |  | ||||||
| @@ -119,7 +119,7 @@ namespace Guestfs
 |  | ||||||
|        List.iter ( |  | ||||||
|          function |  | ||||||
|          | name, FChar -> pr "      char %s;\n" name |  | ||||||
| -        | name, FString -> pr "      string %s;\n" name
 |  | ||||||
| +        | name, (FString | FDevice) -> pr "      string %s;\n" name
 |  | ||||||
|          | name, FBuffer -> |  | ||||||
|              pr "      uint %s_len;\n" name; |  | ||||||
|              pr "      string %s;\n" name |  | ||||||
| diff --git a/generator/daemon.ml b/generator/daemon.ml
 |  | ||||||
| index 9ab9e12d..0baa7708 100644
 |  | ||||||
| --- a/generator/daemon.ml
 |  | ||||||
| +++ b/generator/daemon.ml
 |  | ||||||
| @@ -442,15 +442,37 @@ let generate_daemon_stubs actions () =
 |  | ||||||
|              pr "  ret.%s.%s_val = r;\n" n n; |  | ||||||
|              pr "  reply ((xdrproc_t) &xdr_guestfs_%s_ret, (char *) &ret);\n" |  | ||||||
|                name |  | ||||||
| -        | RStruct (n, _) ->
 |  | ||||||
| +        | RStruct (n, typ) ->
 |  | ||||||
| +            (* XXX RStruct containing an FDevice field would require
 |  | ||||||
| +             * reverse device name translation.  That is not implemented.
 |  | ||||||
| +             * See also RStructList immediately below this.
 |  | ||||||
| +             *)
 |  | ||||||
| +            let cols = (Structs.lookup_struct typ).s_cols in
 |  | ||||||
| +            assert (not (List.exists
 |  | ||||||
| +                           (function (_, FDevice) -> true | _ -> false) cols));
 |  | ||||||
|              pr "  struct guestfs_%s_ret ret;\n" name; |  | ||||||
|              pr "  ret.%s = *r;\n" n; |  | ||||||
|              pr "  reply ((xdrproc_t) xdr_guestfs_%s_ret, (char *) &ret);\n" |  | ||||||
|                name; |  | ||||||
|              pr "  xdr_free ((xdrproc_t) xdr_guestfs_%s_ret, (char *) &ret);\n" |  | ||||||
|                name |  | ||||||
| -        | RStructList (n, _) ->
 |  | ||||||
| +        | RStructList (n, typ) ->
 |  | ||||||
|              pr "  struct guestfs_%s_ret ret;\n" name; |  | ||||||
| +            let cols = (Structs.lookup_struct typ).s_cols in
 |  | ||||||
| +            List.iter (
 |  | ||||||
| +              function
 |  | ||||||
| +              | (fname, FDevice) ->
 |  | ||||||
| +                pr "  for (size_t i = 0; i < r->guestfs_int_%s_list_len; ++i) {\n"
 |  | ||||||
| +                  typ;
 |  | ||||||
| +                pr "    char *field = r->guestfs_int_%s_list_val[i].%s;\n"
 |  | ||||||
| +                  typ fname;
 |  | ||||||
| +                pr "    char *rr = reverse_device_name_translation (field);\n";
 |  | ||||||
| +                pr "    if (!rr) abort ();\n";
 |  | ||||||
| +                pr "    free (field);\n";
 |  | ||||||
| +                pr "    r->guestfs_int_%s_list_val[i].%s = rr;\n" typ fname;
 |  | ||||||
| +                pr "  }\n";
 |  | ||||||
| +              | _ -> ()
 |  | ||||||
| +            ) cols;
 |  | ||||||
|              pr "  ret.%s = *r;\n" n; |  | ||||||
|              pr "  reply ((xdrproc_t) xdr_guestfs_%s_ret, (char *) &ret);\n" |  | ||||||
|                name; |  | ||||||
| @@ -619,7 +641,7 @@ let generate_daemon_caml_stubs () =
 |  | ||||||
|        fun i -> |  | ||||||
|          pr "  v = Field (retv, %d);\n" i; |  | ||||||
|          function |  | ||||||
| -        | n, (FString|FUUID) ->
 |  | ||||||
| +        | n, (FString|FDevice|FUUID) ->
 |  | ||||||
|             pr "  ret->%s = strdup (String_val (v));\n" n; |  | ||||||
|             pr "  if (ret->%s == NULL) return NULL;\n" n |  | ||||||
|          | n, FBuffer -> |  | ||||||
| @@ -986,7 +1008,7 @@ let generate_daemon_lvm_tokenization () =
 |  | ||||||
|              pr "  if (*p) next = p+1; else next = NULL;\n"; |  | ||||||
|              pr "  *p = '\\0';\n"; |  | ||||||
|              (match coltype with |  | ||||||
| -             | FString ->
 |  | ||||||
| +             | FString | FDevice ->
 |  | ||||||
|                   pr "  r->%s = strdup (tok);\n" name; |  | ||||||
|                   pr "  if (r->%s == NULL) {\n" name; |  | ||||||
|                   pr "    perror (\"strdup\");\n"; |  | ||||||
| diff --git a/generator/erlang.ml b/generator/erlang.ml
 |  | ||||||
| index 65af75aa..864b3ff0 100644
 |  | ||||||
| --- a/generator/erlang.ml
 |  | ||||||
| +++ b/generator/erlang.ml
 |  | ||||||
| @@ -286,7 +286,7 @@ and generate_erlang_structs () =
 |  | ||||||
|        List.iteri ( |  | ||||||
|          fun i col -> |  | ||||||
|            (match col with |  | ||||||
| -           | name, FString ->
 |  | ||||||
| +           | name, (FString|FDevice) ->
 |  | ||||||
|                 pr "  if (ei_x_encode_string (buff, %s->%s) != 0) return -1;\n" typ name |  | ||||||
|             | name, FBuffer -> |  | ||||||
|                 pr "  if (ei_x_encode_string_len (buff, %s->%s, %s->%s_len) != 0) return -1;\n" |  | ||||||
| diff --git a/generator/golang.ml b/generator/golang.ml
 |  | ||||||
| index 0d6a9236..a5b39f5d 100644
 |  | ||||||
| --- a/generator/golang.ml
 |  | ||||||
| +++ b/generator/golang.ml
 |  | ||||||
| @@ -248,7 +248,7 @@ func return_hashtable (argv **C.char) map[string]string {
 |  | ||||||
|            let n = String.capitalize_ascii n in |  | ||||||
|            match field with |  | ||||||
|            | FChar -> pr "    %s byte\n" n |  | ||||||
| -          | FString -> pr "    %s string\n" n
 |  | ||||||
| +          | FString | FDevice -> pr "    %s string\n" n
 |  | ||||||
|            | FBuffer -> pr "    %s []byte\n" n |  | ||||||
|            | FUInt32 -> pr "    %s uint32\n" n |  | ||||||
|            | FInt32 -> pr "    %s int32\n" n |  | ||||||
| @@ -267,7 +267,7 @@ func return_hashtable (argv **C.char) map[string]string {
 |  | ||||||
|            let gon = String.capitalize_ascii n in |  | ||||||
|            match field with |  | ||||||
|            | FChar -> pr "    r.%s = byte (c.%s)\n" gon n |  | ||||||
| -          | FString -> pr "    r.%s = C.GoString (c.%s)\n" gon n
 |  | ||||||
| +          | FString | FDevice -> pr "    r.%s = C.GoString (c.%s)\n" gon n
 |  | ||||||
|            | FBuffer -> |  | ||||||
|               pr "    r.%s = C.GoBytes (unsafe.Pointer (c.%s), C.int (c.%s_len))\n" |  | ||||||
|                 gon n n |  | ||||||
| diff --git a/generator/java.ml b/generator/java.ml
 |  | ||||||
| index afcddf90..4b74203a 100644
 |  | ||||||
| --- a/generator/java.ml
 |  | ||||||
| +++ b/generator/java.ml
 |  | ||||||
| @@ -560,6 +560,7 @@ public class %s {
 |  | ||||||
|    List.iter ( |  | ||||||
|      function |  | ||||||
|      | name, FString |  | ||||||
| +    | name, FDevice
 |  | ||||||
|      | name, FUUID |  | ||||||
|      | name, FBuffer -> pr "  public String %s;\n" name |  | ||||||
|      | name, (FBytes|FUInt64|FInt64) -> pr "  public long %s;\n" name |  | ||||||
| @@ -947,7 +948,7 @@ and generate_java_struct_return typ jtyp cols =
 |  | ||||||
|    pr "  jr = (*env)->AllocObject (env, cl);\n"; |  | ||||||
|    List.iter ( |  | ||||||
|      function |  | ||||||
| -    | name, FString ->
 |  | ||||||
| +    | name, (FString|FDevice) ->
 |  | ||||||
|          pr "  fl = (*env)->GetFieldID (env, cl, \"%s\", \"Ljava/lang/String;\");\n" name; |  | ||||||
|          pr "  (*env)->SetObjectField (env, jr, fl, (*env)->NewStringUTF (env, r->%s));\n" name; |  | ||||||
|      | name, FUUID -> |  | ||||||
| @@ -997,7 +998,7 @@ and generate_java_struct_list_return typ jtyp cols =
 |  | ||||||
|      fun (name, ftyp) -> |  | ||||||
|        (* Get the field ID in 'fl'. *) |  | ||||||
|        let java_field_type = match ftyp with |  | ||||||
| -        | FString | FUUID | FBuffer -> "Ljava/lang/String;"
 |  | ||||||
| +        | FString | FDevice | FUUID | FBuffer -> "Ljava/lang/String;"
 |  | ||||||
|          | FBytes | FUInt64 | FInt64 -> "J" |  | ||||||
|          | FUInt32 | FInt32 -> "I" |  | ||||||
|          | FOptPercent -> "F" |  | ||||||
| @@ -1007,7 +1008,7 @@ and generate_java_struct_list_return typ jtyp cols =
 |  | ||||||
|   |  | ||||||
|        (* Assign the value to this field. *) |  | ||||||
|        match ftyp with |  | ||||||
| -      | FString ->
 |  | ||||||
| +      | FString | FDevice ->
 |  | ||||||
|          pr "    (*env)->SetObjectField (env, jfl, fl,\n"; |  | ||||||
|          pr "                            (*env)->NewStringUTF (env, r->val[i].%s));\n" name; |  | ||||||
|        | FUUID -> |  | ||||||
| diff --git a/generator/lua.ml b/generator/lua.ml
 |  | ||||||
| index 0d7e63be..685645ab 100644
 |  | ||||||
| --- a/generator/lua.ml
 |  | ||||||
| +++ b/generator/lua.ml
 |  | ||||||
| @@ -824,7 +824,7 @@ push_event (lua_State *L, uint64_t event)
 |  | ||||||
|          (match field with |  | ||||||
|          | FChar -> |  | ||||||
|            pr "  lua_pushlstring (L, &v->%s, 1);\n" n |  | ||||||
| -        | FString ->
 |  | ||||||
| +        | FString | FDevice ->
 |  | ||||||
|            pr "  lua_pushstring (L, v->%s);\n" n |  | ||||||
|          | FBuffer -> |  | ||||||
|            pr "  lua_pushlstring (L, v->%s, v->%s_len);\n" n n |  | ||||||
| diff --git a/generator/perl.ml b/generator/perl.ml
 |  | ||||||
| index 8b9834ef..e0edc249 100644
 |  | ||||||
| --- a/generator/perl.ml
 |  | ||||||
| +++ b/generator/perl.ml
 |  | ||||||
| @@ -607,7 +607,7 @@ and generate_perl_struct_list_code typ cols name style =
 |  | ||||||
|    pr "        hv = newHV ();\n"; |  | ||||||
|    List.iter ( |  | ||||||
|      function |  | ||||||
| -    | name, FString ->
 |  | ||||||
| +    | name, (FString|FDevice) ->
 |  | ||||||
|          pr "        (void) hv_store (hv, \"%s\", %d, newSVpv (r->val[i].%s, 0), 0);\n" |  | ||||||
|            name (String.length name) name |  | ||||||
|      | name, FUUID -> |  | ||||||
| @@ -645,7 +645,7 @@ and generate_perl_struct_code typ cols name style =
 |  | ||||||
|        pr "      PUSHs (sv_2mortal (newSVpv (\"%s\", 0)));\n" name; |  | ||||||
|   |  | ||||||
|        match col with |  | ||||||
| -      | name, FString ->
 |  | ||||||
| +      | name, (FString|FDevice) ->
 |  | ||||||
|            pr "      PUSHs (sv_2mortal (newSVpv (r->%s, 0)));\n" |  | ||||||
|              name |  | ||||||
|        | name, FBuffer -> |  | ||||||
| diff --git a/generator/php.ml b/generator/php.ml
 |  | ||||||
| index 99ec66c7..5023e0c5 100644
 |  | ||||||
| --- a/generator/php.ml
 |  | ||||||
| +++ b/generator/php.ml
 |  | ||||||
| @@ -616,7 +616,7 @@ and generate_php_struct_code typ cols =
 |  | ||||||
|    pr "  array_init (return_value);\n"; |  | ||||||
|    List.iter ( |  | ||||||
|      function |  | ||||||
| -    | name, FString ->
 |  | ||||||
| +    | name, (FString|FDevice) ->
 |  | ||||||
|          pr "  guestfs_add_assoc_string (return_value, \"%s\", r->%s, 1);\n" name name |  | ||||||
|      | name, FBuffer -> |  | ||||||
|          pr "  guestfs_add_assoc_stringl (return_value, \"%s\", r->%s, r->%s_len, 1);\n" |  | ||||||
| @@ -650,7 +650,7 @@ and generate_php_struct_list_code typ cols =
 |  | ||||||
|    pr "    array_init (z_elem);\n"; |  | ||||||
|    List.iter ( |  | ||||||
|      function |  | ||||||
| -    | name, FString ->
 |  | ||||||
| +    | name, (FString|FDevice) ->
 |  | ||||||
|          pr "    guestfs_add_assoc_string (z_elem, \"%s\", r->val[c].%s, 1);\n" |  | ||||||
|            name name |  | ||||||
|      | name, FBuffer -> |  | ||||||
| diff --git a/generator/python.ml b/generator/python.ml
 |  | ||||||
| index ad02ea93..5534e74a 100644
 |  | ||||||
| --- a/generator/python.ml
 |  | ||||||
| +++ b/generator/python.ml
 |  | ||||||
| @@ -168,7 +168,7 @@ and generate_python_structs () =
 |  | ||||||
|        pr "    return NULL;\n"; |  | ||||||
|        List.iter ( |  | ||||||
|          function |  | ||||||
| -        | name, FString ->
 |  | ||||||
| +        | name, (FString|FDevice) ->
 |  | ||||||
|              pr "  value = guestfs_int_py_fromstring (%s->%s);\n" typ name; |  | ||||||
|              pr "  if (value == NULL)\n"; |  | ||||||
|              pr "    goto err;\n"; |  | ||||||
| diff --git a/generator/ruby.ml b/generator/ruby.ml
 |  | ||||||
| index be3238f6..ea5a3194 100644
 |  | ||||||
| --- a/generator/ruby.ml
 |  | ||||||
| +++ b/generator/ruby.ml
 |  | ||||||
| @@ -526,7 +526,7 @@ and generate_ruby_struct_code typ cols =
 |  | ||||||
|    pr "  volatile VALUE rv = rb_hash_new ();\n"; |  | ||||||
|    List.iter ( |  | ||||||
|      function |  | ||||||
| -    | name, FString ->
 |  | ||||||
| +    | name, (FString|FDevice) ->
 |  | ||||||
|          pr "  rb_hash_aset (rv, rb_str_new2 (\"%s\"), rb_str_new2 (r->%s));\n" name name |  | ||||||
|      | name, FBuffer -> |  | ||||||
|          pr "  rb_hash_aset (rv, rb_str_new2 (\"%s\"), rb_str_new (r->%s, r->%s_len));\n" name name name |  | ||||||
| @@ -556,7 +556,7 @@ and generate_ruby_struct_list_code typ cols =
 |  | ||||||
|    pr "    volatile VALUE hv = rb_hash_new ();\n"; |  | ||||||
|    List.iter ( |  | ||||||
|      function |  | ||||||
| -    | name, FString ->
 |  | ||||||
| +    | name, (FString|FDevice) ->
 |  | ||||||
|          pr "    rb_hash_aset (hv, rb_str_new2 (\"%s\"), rb_str_new2 (r->val[i].%s));\n" name name |  | ||||||
|      | name, FBuffer -> |  | ||||||
|          pr "    rb_hash_aset (hv, rb_str_new2 (\"%s\"), rb_str_new (r->val[i].%s, r->val[i].%s_len));\n" name name name |  | ||||||
| diff --git a/generator/rust.ml b/generator/rust.ml
 |  | ||||||
| index 1f5cefa6..f4dcfd72 100644
 |  | ||||||
| --- a/generator/rust.ml
 |  | ||||||
| +++ b/generator/rust.ml
 |  | ||||||
| @@ -115,7 +115,7 @@ extern \"C\" {
 |  | ||||||
|        List.iter ( |  | ||||||
|          function |  | ||||||
|          | n, FChar -> pr "    pub %s: i8,\n" n |  | ||||||
| -        | n, FString -> pr "    pub %s: String,\n" n
 |  | ||||||
| +        | n, (FString|FDevice) -> pr "    pub %s: String,\n" n
 |  | ||||||
|          | n, FBuffer -> pr "    pub %s: Vec<u8>,\n" n |  | ||||||
|          | n, FUInt32 -> pr "    pub %s: u32,\n" n |  | ||||||
|          | n, FInt32 -> pr "    pub %s: i32,\n" n |  | ||||||
| @@ -130,7 +130,7 @@ extern \"C\" {
 |  | ||||||
|        List.iter ( |  | ||||||
|          function |  | ||||||
|          | n, FChar -> pr "    %s: c_char,\n" n |  | ||||||
| -        | n, FString -> pr "    %s: *const c_char,\n" n
 |  | ||||||
| +        | n, (FString|FDevice) -> pr "    %s: *const c_char,\n" n
 |  | ||||||
|          | n, FBuffer -> |  | ||||||
|            pr "    %s_len: usize,\n" n; |  | ||||||
|            pr "    %s: *const c_char,\n" n; |  | ||||||
| @@ -154,7 +154,7 @@ extern \"C\" {
 |  | ||||||
|            match x with |  | ||||||
|            | n, FChar -> |  | ||||||
|              pr "%s: (*raw).%s as i8,\n" n n; |  | ||||||
| -          | n, FString ->
 |  | ||||||
| +          | n, (FString|FDevice) ->
 |  | ||||||
|              pr "%s: char_ptr_to_string((*raw).%s)?,\n" n n; |  | ||||||
|            | n, FBuffer -> |  | ||||||
|              pr "%s: slice::from_raw_parts((*raw).%s as *const u8, (*raw).%s_len).to_vec(),\n" n n n |  | ||||||
| diff --git a/generator/types.ml b/generator/types.ml
 |  | ||||||
| index d9b00885..c901aa73 100644
 |  | ||||||
| --- a/generator/types.ml
 |  | ||||||
| +++ b/generator/types.ml
 |  | ||||||
| @@ -215,6 +215,7 @@ let defaults = { name = "";
 |  | ||||||
|  type field = |  | ||||||
|    | FChar			(* C 'char' (really, a 7 bit byte). *) |  | ||||||
|    | FString			(* nul-terminated ASCII string, NOT NULL. *) |  | ||||||
| +  | FDevice                     (* device name, needs reverse transl. *)
 |  | ||||||
|    | FBuffer			(* opaque buffer of bytes, (char *, int) pair *) |  | ||||||
|    | FUInt32 |  | ||||||
|    | FInt32 |  | ||||||
| diff --git a/generator/types.mli b/generator/types.mli
 |  | ||||||
| index 0ce0d33b..0a4752d5 100644
 |  | ||||||
| --- a/generator/types.mli
 |  | ||||||
| +++ b/generator/types.mli
 |  | ||||||
| @@ -413,6 +413,7 @@ val defaults : action
 |  | ||||||
|  type field = |  | ||||||
|    | FChar			(** C 'char' (really, a 7 bit byte). *) |  | ||||||
|    | FString			(** nul-terminated ASCII string, NOT NULL. *) |  | ||||||
| +  | FDevice                     (** device name, needs reverse transl. *)
 |  | ||||||
|    | FBuffer			(** opaque buffer of bytes, (char *, int) pair*) |  | ||||||
|    | FUInt32 |  | ||||||
|    | FInt32 |  | ||||||
| @ -1,68 +0,0 @@ | |||||||
| From b306532e7a4a3f235b24e5dab22ab36b849ac886 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: "Richard W.M. Jones" <rjones@redhat.com> |  | ||||||
| Date: Wed, 16 Apr 2025 11:50:37 +0100 |  | ||||||
| Subject: [PATCH] generator: Use new FDevice type for the pvs-full pv_name |  | ||||||
|  field |  | ||||||
| 
 |  | ||||||
| Remove the code which did explicit reverse device name translation, |  | ||||||
| and use the generator's code instead. |  | ||||||
| 
 |  | ||||||
| (cherry picked from commit 5a16d1120fb7b046974abde43b1c40250bfd1a95) |  | ||||||
| ---
 |  | ||||||
|  daemon/lvm.c         | 29 +---------------------------- |  | ||||||
|  generator/structs.ml |  2 +- |  | ||||||
|  2 files changed, 2 insertions(+), 29 deletions(-) |  | ||||||
| 
 |  | ||||||
| diff --git a/daemon/lvm.c b/daemon/lvm.c
 |  | ||||||
| index b8c01f71..7e76e17c 100644
 |  | ||||||
| --- a/daemon/lvm.c
 |  | ||||||
| +++ b/daemon/lvm.c
 |  | ||||||
| @@ -146,34 +146,7 @@ do_vgs (void)
 |  | ||||||
|  guestfs_int_lvm_pv_list * |  | ||||||
|  do_pvs_full (void) |  | ||||||
|  { |  | ||||||
| -  guestfs_int_lvm_pv_list *r;
 |  | ||||||
| -  size_t i;
 |  | ||||||
| -  char *din, *dout;
 |  | ||||||
| -
 |  | ||||||
| -  r = parse_command_line_pvs ();
 |  | ||||||
| -  if (r == NULL)
 |  | ||||||
| -    /* parse_command_line_pvs has already called reply_with_error */
 |  | ||||||
| -    return NULL;
 |  | ||||||
| -
 |  | ||||||
| -  /* The pv_name fields contain device names which must be reverse
 |  | ||||||
| -   * translated.  The problem here is that the generator does not have
 |  | ||||||
| -   * a "FMountable" field type in types.mli.
 |  | ||||||
| -   */
 |  | ||||||
| -  for (i = 0; i < r->guestfs_int_lvm_pv_list_len; ++i) {
 |  | ||||||
| -    din = r->guestfs_int_lvm_pv_list_val[i].pv_name;
 |  | ||||||
| -    if (din) {
 |  | ||||||
| -      dout = reverse_device_name_translation (din);
 |  | ||||||
| -      if (!dout) {
 |  | ||||||
| -        /* reverse_device_name_translation has already called reply_with_error*/
 |  | ||||||
| -        /* XXX memory leak here */
 |  | ||||||
| -        return NULL;
 |  | ||||||
| -      }
 |  | ||||||
| -      r->guestfs_int_lvm_pv_list_val[i].pv_name = dout;
 |  | ||||||
| -      free (din);
 |  | ||||||
| -    }
 |  | ||||||
| -  }
 |  | ||||||
| -
 |  | ||||||
| -  return r;
 |  | ||||||
| +  return parse_command_line_pvs ();
 |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|  guestfs_int_lvm_vg_list * |  | ||||||
| diff --git a/generator/structs.ml b/generator/structs.ml
 |  | ||||||
| index c1408804..93a3ed03 100644
 |  | ||||||
| --- a/generator/structs.ml
 |  | ||||||
| +++ b/generator/structs.ml
 |  | ||||||
| @@ -35,7 +35,7 @@ type struc = {
 |  | ||||||
|   * we have to pull out the LVM columns separately here. |  | ||||||
|   *) |  | ||||||
|  let lvm_pv_cols = [ |  | ||||||
| -  "pv_name", FString;
 |  | ||||||
| +  "pv_name", FDevice;
 |  | ||||||
|    "pv_uuid", FUUID; |  | ||||||
|    "pv_fmt", FString; |  | ||||||
|    "pv_size", FBytes; |  | ||||||
| @ -0,0 +1,92 @@ | |||||||
|  | From bb19cc0cdd43619ccf830e1e608f79e46f8ddf86 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: "Richard W.M. Jones" <rjones@redhat.com> | ||||||
|  | Date: Thu, 12 May 2022 08:36:37 +0100 | ||||||
|  | Subject: [PATCH] lib: Disable 5-level page tables when using -cpu max | ||||||
|  | 
 | ||||||
|  | In https://bugzilla.redhat.com/show_bug.cgi?id=2082806 we've been | ||||||
|  | tracking an insidious qemu bug which intermittently prevents the | ||||||
|  | libguestfs appliance from starting.  The symptoms are that SeaBIOS | ||||||
|  | starts and displays its messages, but the kernel isn't reached.  We | ||||||
|  | found that the kernel does in fact start, but when it tries to set up | ||||||
|  | page tables and jump to protected mode it gets a triple fault which | ||||||
|  | causes the emulated CPU in qemu to reset (qemu exits). | ||||||
|  | 
 | ||||||
|  | This seems to only affect TCG (not KVM). | ||||||
|  | 
 | ||||||
|  | Yesterday I found that this is caused by using -cpu max which enables | ||||||
|  | the "la57" feature (5-level page tables[0]), and that we can make the | ||||||
|  | problem go away using -cpu max,la57=off.  Note that I still don't | ||||||
|  | fully understand the qemu bug, so this is only a workaround. | ||||||
|  | 
 | ||||||
|  | I chose to disable 5-level page tables for both TCG and KVM, partly to | ||||||
|  | make the patch simpler, and partly because I guess it's not a feature | ||||||
|  | (ie. 57 bit linear addresses) that is useful for the libguestfs | ||||||
|  | appliance case, where we have limited physical memory and no need to | ||||||
|  | run any programs with huge address spaces. | ||||||
|  | 
 | ||||||
|  | I tested this by running both the direct & libvirt paths overnight.  I | ||||||
|  | expect that this patch will fail with old qemu/libvirt which doesn't | ||||||
|  | understand the "la57" feature, but this is only intended as a | ||||||
|  | temporary workaround. | ||||||
|  | 
 | ||||||
|  | [0] Article about 5-level page tables as background: | ||||||
|  | https://lwn.net/Articles/717293/ | ||||||
|  | 
 | ||||||
|  | Thanks: Laszlo Ersek | ||||||
|  | Fixes: https://answers.launchpad.net/ubuntu/+source/libguestfs/+question/701625 | ||||||
|  | 
 | ||||||
|  | [RHEL 8.7: Patch is not upstream.  This is the initial patch as posted | ||||||
|  | to the mailing list here: | ||||||
|  | https://listman.redhat.com/archives/libguestfs/2022-May/028853.html] | ||||||
|  | ---
 | ||||||
|  |  lib/launch-direct.c  | 15 +++++++++++++-- | ||||||
|  |  lib/launch-libvirt.c |  7 +++++++ | ||||||
|  |  2 files changed, 20 insertions(+), 2 deletions(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/lib/launch-direct.c b/lib/launch-direct.c
 | ||||||
|  | index de17d2167..6b28e4724 100644
 | ||||||
|  | --- a/lib/launch-direct.c
 | ||||||
|  | +++ b/lib/launch-direct.c
 | ||||||
|  | @@ -534,8 +534,19 @@ launch_direct (guestfs_h *g, void *datav, const char *arg)
 | ||||||
|  |    } end_list (); | ||||||
|  |   | ||||||
|  |    cpu_model = guestfs_int_get_cpu_model (has_kvm && !force_tcg); | ||||||
|  | -  if (cpu_model)
 | ||||||
|  | -    arg ("-cpu", cpu_model);
 | ||||||
|  | +  if (cpu_model) {
 | ||||||
|  | +#if defined(__x86_64__)
 | ||||||
|  | +    /* Temporary workaround for RHBZ#2082806 */
 | ||||||
|  | +    if (STREQ (cpu_model, "max")) {
 | ||||||
|  | +      start_list ("-cpu") {
 | ||||||
|  | +        append_list (cpu_model);
 | ||||||
|  | +        append_list ("la57=off");
 | ||||||
|  | +      } end_list ();
 | ||||||
|  | +    }
 | ||||||
|  | +    else
 | ||||||
|  | +#endif
 | ||||||
|  | +      arg ("-cpu", cpu_model);
 | ||||||
|  | +  }
 | ||||||
|  |   | ||||||
|  |    if (g->smp > 1) | ||||||
|  |      arg_format ("-smp", "%d", g->smp); | ||||||
|  | diff --git a/lib/launch-libvirt.c b/lib/launch-libvirt.c
 | ||||||
|  | index db619910f..bad4a54ea 100644
 | ||||||
|  | --- a/lib/launch-libvirt.c
 | ||||||
|  | +++ b/lib/launch-libvirt.c
 | ||||||
|  | @@ -1172,6 +1172,13 @@ construct_libvirt_xml_cpu (guestfs_h *g,
 | ||||||
|  |        else if (STREQ (cpu_model, "max")) { | ||||||
|  |          /* https://bugzilla.redhat.com/show_bug.cgi?id=1935572#c11 */ | ||||||
|  |          attribute ("mode", "maximum"); | ||||||
|  | +#if defined(__x86_64__)
 | ||||||
|  | +        /* Temporary workaround for RHBZ#2082806 */
 | ||||||
|  | +        start_element ("feature") {
 | ||||||
|  | +          attribute ("policy", "disable");
 | ||||||
|  | +          attribute ("name", "la57");
 | ||||||
|  | +        } end_element ();
 | ||||||
|  | +#endif
 | ||||||
|  |        } | ||||||
|  |        else | ||||||
|  |          single_element ("model", cpu_model); | ||||||
|  | -- 
 | ||||||
|  | 2.31.1 | ||||||
|  | 
 | ||||||
| @ -1,46 +0,0 @@ | |||||||
| From 0d466cb25e86ab6f7f6838d35afb37b99f83e0e4 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: "Richard W.M. Jones" <rjones@redhat.com> |  | ||||||
| Date: Wed, 16 Apr 2025 10:13:52 +0100 |  | ||||||
| Subject: [PATCH] daemon: inspect: Resolve Ubuntu 22+ /dev/disk/by-uuid/ in |  | ||||||
|  fstab |  | ||||||
| 
 |  | ||||||
| Ubuntu 22= uses /dev/disk/by-uuid/ followed by a filesystem UUID in |  | ||||||
| fstab entries.  Resolve these to mountables. |  | ||||||
| 
 |  | ||||||
| A typical fstab entry looks like this: |  | ||||||
| 
 |  | ||||||
|   # /boot was on /dev/vda2 during curtin installation |  | ||||||
|   /dev/disk/by-uuid/b4e56462-5a64-4272-b76d-f5e58bd8f128 /boot ext4 defaults 0 1 |  | ||||||
| 
 |  | ||||||
| The comment is generated by the installer and appears in the fstab. |  | ||||||
| This entry would be translated to /dev/sda2. |  | ||||||
| 
 |  | ||||||
| (cherry picked from commit 7a1ffd744b12c4c79fa1b78341ea714d831f4205) |  | ||||||
| ---
 |  | ||||||
|  daemon/inspect_fs_unix_fstab.ml | 13 +++++++++++++ |  | ||||||
|  1 file changed, 13 insertions(+) |  | ||||||
| 
 |  | ||||||
| diff --git a/daemon/inspect_fs_unix_fstab.ml b/daemon/inspect_fs_unix_fstab.ml
 |  | ||||||
| index f5817a31..45c62175 100644
 |  | ||||||
| --- a/daemon/inspect_fs_unix_fstab.ml
 |  | ||||||
| +++ b/daemon/inspect_fs_unix_fstab.ml
 |  | ||||||
| @@ -394,6 +394,19 @@ and resolve_fstab_device spec md_map os_type =
 |  | ||||||
|      resolve_diskbyid part default |  | ||||||
|    ) |  | ||||||
|   |  | ||||||
| +  (* Ubuntu 22+ uses /dev/disk/by-uuid/ followed by a UUID. *)
 |  | ||||||
| +  else if String.is_prefix spec "/dev/disk/by-uuid/" then (
 |  | ||||||
| +    debug_matching "diskbyuuid";
 |  | ||||||
| +    let uuid = String.sub spec 18 (String.length spec - 18) in
 |  | ||||||
| +    try
 |  | ||||||
| +      (* Try a filesystem UUID.  Unclear if this could be a partition UUID
 |  | ||||||
| +       * as well, but in the Ubuntu guest I tried it was an fs UUID XXX.
 |  | ||||||
| +       *)
 |  | ||||||
| +      Mountable.of_device (Findfs.findfs_uuid uuid)
 |  | ||||||
| +    with
 |  | ||||||
| +      Failure _ -> default
 |  | ||||||
| +  )
 |  | ||||||
| +
 |  | ||||||
|    else if PCRE.matches re_freebsd_gpt spec then ( |  | ||||||
|      debug_matching "FreeBSD GPT"; |  | ||||||
|      (* group 1 (type) is not used *) |  | ||||||
							
								
								
									
										103
									
								
								SOURCES/0023-docs-guestfs-security-document-CVE-2022-2211.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										103
									
								
								SOURCES/0023-docs-guestfs-security-document-CVE-2022-2211.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,103 @@ | |||||||
|  | From 22d779d5982dc82d629710d41973ed6545707bd9 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Laszlo Ersek <lersek@redhat.com> | ||||||
|  | Date: Tue, 28 Jun 2022 13:54:16 +0200 | ||||||
|  | Subject: [PATCH] docs/guestfs-security: document CVE-2022-2211 | ||||||
|  | 
 | ||||||
|  | Short log for the common submodule, commit range | ||||||
|  | f8de5508fe75..35467027f657: | ||||||
|  | 
 | ||||||
|  | Laszlo Ersek (2): | ||||||
|  |       mlcustomize: factor out pkg install/update/uninstall from guestfs-tools | ||||||
|  |       options: fix buffer overflow in get_keys() [CVE-2022-2211] | ||||||
|  | 
 | ||||||
|  | Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1809453 | ||||||
|  | Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2100862 | ||||||
|  | Signed-off-by: Laszlo Ersek <lersek@redhat.com> | ||||||
|  | Message-Id: <20220628115418.5376-2-lersek@redhat.com> | ||||||
|  | Reviewed-by: Richard W.M. Jones <rjones@redhat.com> | ||||||
|  | 
 | ||||||
|  | Cherry picked from commit 99844660b48ed809e37378262c65d63df6ce4a53. | ||||||
|  | For the cherry pick I only added one submodule commit: | ||||||
|  | 
 | ||||||
|  | options: fix buffer overflow in get_keys() [CVE-2022-2211] | ||||||
|  | ---
 | ||||||
|  |  common                    |  2 +- | ||||||
|  |  docs/guestfs-security.pod | 28 ++++++++++++++++++++++++++++ | ||||||
|  |  2 files changed, 29 insertions(+), 1 deletion(-) | ||||||
|  | 
 | ||||||
|  | Submodule common be09523d6..1174b443a: | ||||||
|  | diff --git a/common/options/keys.c b/common/options/keys.c
 | ||||||
|  | index 798315c..d27a712 100644
 | ||||||
|  | --- a/common/options/keys.c
 | ||||||
|  | +++ b/common/options/keys.c
 | ||||||
|  | @@ -128,17 +128,23 @@ read_first_line_from_file (const char *filename)
 | ||||||
|  |  char ** | ||||||
|  |  get_keys (struct key_store *ks, const char *device, const char *uuid) | ||||||
|  |  { | ||||||
|  | -  size_t i, j, len;
 | ||||||
|  | +  size_t i, j, nmemb;
 | ||||||
|  |    char **r; | ||||||
|  |    char *s; | ||||||
|  |   | ||||||
|  |    /* We know the returned list must have at least one element and not | ||||||
|  |     * more than ks->nr_keys. | ||||||
|  |     */ | ||||||
|  | -  len = 1;
 | ||||||
|  | -  if (ks)
 | ||||||
|  | -    len = MIN (1, ks->nr_keys);
 | ||||||
|  | -  r = calloc (len+1, sizeof (char *));
 | ||||||
|  | +  nmemb = 1;
 | ||||||
|  | +  if (ks && ks->nr_keys > nmemb)
 | ||||||
|  | +    nmemb = ks->nr_keys;
 | ||||||
|  | +
 | ||||||
|  | +  /* make room for the terminating NULL */
 | ||||||
|  | +  if (nmemb == (size_t)-1)
 | ||||||
|  | +    error (EXIT_FAILURE, 0, _("size_t overflow"));
 | ||||||
|  | +  nmemb++;
 | ||||||
|  | +
 | ||||||
|  | +  r = calloc (nmemb, sizeof (char *));
 | ||||||
|  |    if (r == NULL) | ||||||
|  |      error (EXIT_FAILURE, errno, "calloc"); | ||||||
|  |   | ||||||
|  | diff --git a/docs/guestfs-security.pod b/docs/guestfs-security.pod
 | ||||||
|  | index 9ceef5623..efa35b29d 100644
 | ||||||
|  | --- a/docs/guestfs-security.pod
 | ||||||
|  | +++ b/docs/guestfs-security.pod
 | ||||||
|  | @@ -406,6 +406,34 @@ The libvirt backend is not affected.
 | ||||||
|  |  The solution is to update qemu to a version containing the fix (see | ||||||
|  |  L<https://lists.gnu.org/archive/html/qemu-devel/2018-06/msg01012.html>). | ||||||
|  |   | ||||||
|  | +=head2 CVE-2022-2211
 | ||||||
|  | +
 | ||||||
|  | +L<https://bugzilla.redhat.com/CVE-2022-2211>
 | ||||||
|  | +
 | ||||||
|  | +The C<get_keys> function in F<libguestfs-common/options/keys.c> collects
 | ||||||
|  | +those I<--key> options from the command line into a new array that match
 | ||||||
|  | +a particular block device that's being decrypted for inspection. The
 | ||||||
|  | +function intends to size the result array such that potentially all
 | ||||||
|  | +I<--key> options, plus a terminating C<NULL> element, fit into it. The
 | ||||||
|  | +code mistakenly uses the C<MIN> macro instead of C<MAX>, and therefore
 | ||||||
|  | +only one element is allocated before the C<NULL> terminator.
 | ||||||
|  | +
 | ||||||
|  | +Passing precisely two I<--key ID:...> options on the command line for
 | ||||||
|  | +the encrypted block device C<ID> causes C<get_keys> to overwrite the
 | ||||||
|  | +terminating C<NULL>, leading to an out-of-bounds read in
 | ||||||
|  | +C<decrypt_mountables>, file F<libguestfs-common/options/decrypt.c>.
 | ||||||
|  | +
 | ||||||
|  | +Passing more than two I<--key ID:...> options on the command line for
 | ||||||
|  | +the encrypted block device C<ID> causes C<get_keys> itself to perform
 | ||||||
|  | +out-of-bounds writes. The most common symptom is a crash with C<SIGSEGV>
 | ||||||
|  | +later on.
 | ||||||
|  | +
 | ||||||
|  | +This issue affects -- broadly speaking -- all libguestfs-based utilities
 | ||||||
|  | +that accept I<--key>, namely: C<guestfish>, C<guestmount>, C<virt-cat>,
 | ||||||
|  | +C<virt-customize>, C<virt-diff>, C<virt-edit>, C<virt-get-kernel>,
 | ||||||
|  | +C<virt-inspector>, C<virt-log>, C<virt-ls>, C<virt-sparsify>,
 | ||||||
|  | +C<virt-sysprep>, C<virt-tail>, C<virt-v2v>.
 | ||||||
|  | +
 | ||||||
|  |  =head1 SEE ALSO | ||||||
|  |   | ||||||
|  |  L<guestfs(3)>, | ||||||
|  | -- 
 | ||||||
|  | 2.31.1 | ||||||
|  | 
 | ||||||
| @ -1,43 +0,0 @@ | |||||||
| From 1b64c54b8a7f3a0ada0cc52fc74d800a55318112 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: "Richard W.M. Jones" <rjones@redhat.com> |  | ||||||
| Date: Wed, 16 Apr 2025 13:19:17 +0100 |  | ||||||
| Subject: [PATCH] generator: Fix implementation of FUUID for OCaml functions |  | ||||||
| 
 |  | ||||||
| This was implemented wrongly.  In the XDR protocol, UUIDs are fixed |  | ||||||
| buffers of length 32.  We can just use memcpy to copy from the OCaml |  | ||||||
| string to the UUID, but we have to ensure the string length returned |  | ||||||
| by OCaml is correct (if not we just assert, it's an internal error). |  | ||||||
| 
 |  | ||||||
| (It didn't even compile before, so we know it was never used). |  | ||||||
| 
 |  | ||||||
| (cherry picked from commit bcd6b3ec3a1038d840e832732b3910f939566436) |  | ||||||
| ---
 |  | ||||||
|  generator/daemon.ml | 6 +++++- |  | ||||||
|  1 file changed, 5 insertions(+), 1 deletion(-) |  | ||||||
| 
 |  | ||||||
| diff --git a/generator/daemon.ml b/generator/daemon.ml
 |  | ||||||
| index 0baa7708..91decf40 100644
 |  | ||||||
| --- a/generator/daemon.ml
 |  | ||||||
| +++ b/generator/daemon.ml
 |  | ||||||
| @@ -606,6 +606,7 @@ let generate_daemon_caml_stubs () =
 |  | ||||||
|  #include <string.h> |  | ||||||
|  #include <inttypes.h> |  | ||||||
|  #include <errno.h> |  | ||||||
| +#include <assert.h>
 |  | ||||||
|   |  | ||||||
|  #include <caml/alloc.h> |  | ||||||
|  #include <caml/callback.h> |  | ||||||
| @@ -641,9 +642,12 @@ let generate_daemon_caml_stubs () =
 |  | ||||||
|        fun i -> |  | ||||||
|          pr "  v = Field (retv, %d);\n" i; |  | ||||||
|          function |  | ||||||
| -        | n, (FString|FDevice|FUUID) ->
 |  | ||||||
| +        | n, (FString|FDevice) ->
 |  | ||||||
|             pr "  ret->%s = strdup (String_val (v));\n" n; |  | ||||||
|             pr "  if (ret->%s == NULL) return NULL;\n" n |  | ||||||
| +        | n, FUUID ->
 |  | ||||||
| +           pr "  assert (caml_string_length (v) == sizeof ret->%s);\n" n;
 |  | ||||||
| +           pr "  memcpy (ret->%s, String_val (v), sizeof ret->%s);\n" n n
 |  | ||||||
|          | n, FBuffer -> |  | ||||||
|             pr "  ret->%s_len = caml_string_length (v);\n" n; |  | ||||||
|             pr "  ret->%s = strdup (String_val (v));\n" n; |  | ||||||
| @ -1,42 +0,0 @@ | |||||||
| From c7930f21405720f51d74efa9f6f7b9da0132a929 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: "Richard W.M. Jones" <rjones@redhat.com> |  | ||||||
| Date: Wed, 16 Apr 2025 21:31:49 +0100 |  | ||||||
| Subject: [PATCH] Update common submodule |  | ||||||
| 
 |  | ||||||
|   Richard W.M. Jones (1): |  | ||||||
|       mlstdutils: Implement String.implode |  | ||||||
| ---
 |  | ||||||
|  common | 2 +- |  | ||||||
|  1 file changed, 1 insertion(+), 1 deletion(-) |  | ||||||
| 
 |  | ||||||
| Submodule common e9eea65a..8aed7b6a: |  | ||||||
| diff --git a/common/mlstdutils/std_utils.ml b/common/mlstdutils/std_utils.ml
 |  | ||||||
| index 86b21a7c..1177ff69 100644
 |  | ||||||
| --- a/common/mlstdutils/std_utils.ml
 |  | ||||||
| +++ b/common/mlstdutils/std_utils.ml
 |  | ||||||
| @@ -256,6 +256,12 @@ module String = struct
 |  | ||||||
|      let map_chars f str = |  | ||||||
|        List.map f (explode str) |  | ||||||
|   |  | ||||||
| +    let implode cs =
 |  | ||||||
| +      let n = List.length cs in
 |  | ||||||
| +      let b = Bytes.create n in
 |  | ||||||
| +      List.iteri (Bytes.unsafe_set b) cs;
 |  | ||||||
| +      Bytes.to_string b
 |  | ||||||
| +
 |  | ||||||
|      let spaces n = String.make n ' ' |  | ||||||
|   |  | ||||||
|      let span str accept = |  | ||||||
| diff --git a/common/mlstdutils/std_utils.mli b/common/mlstdutils/std_utils.mli
 |  | ||||||
| index a39ac5f3..6811b4bc 100644
 |  | ||||||
| --- a/common/mlstdutils/std_utils.mli
 |  | ||||||
| +++ b/common/mlstdutils/std_utils.mli
 |  | ||||||
| @@ -123,6 +123,8 @@ module String : sig
 |  | ||||||
|      (** Explode a string into a list of characters. *) |  | ||||||
|      val map_chars : (char -> 'a) -> string -> 'a list |  | ||||||
|      (** Explode string, then map function over the characters. *) |  | ||||||
| +    val implode : char list -> string
 |  | ||||||
| +    (** Join list of characters into a single string. *)
 |  | ||||||
|      val spaces : int -> string |  | ||||||
|      (** [spaces n] creates a string of n spaces. *) |  | ||||||
|      val span : string -> string -> int |  | ||||||
| @ -1,659 +0,0 @@ | |||||||
| From 80b2fcb243613bc16217b5908941ed2607f398fd Mon Sep 17 00:00:00 2001 |  | ||||||
| From: "Richard W.M. Jones" <rjones@redhat.com> |  | ||||||
| Date: Wed, 16 Apr 2025 10:41:59 +0100 |  | ||||||
| Subject: [PATCH] daemon: Rewrite {pvs,vgs,lvs}-full APIs in OCaml |  | ||||||
| 
 |  | ||||||
| These were previously written in very convoluted C which had to deal |  | ||||||
| with parsing the crazy output of the "lvm" command.  In fact the |  | ||||||
| parsing was so complex that it was generated by the generator.  It's |  | ||||||
| easier to do this in OCaml. |  | ||||||
| 
 |  | ||||||
| These are basically legacy APIs.  They cannot be expanded and LVM |  | ||||||
| already supports many more fields.  We should replace these with APIs |  | ||||||
| for getting single named fields from LVM. |  | ||||||
| 
 |  | ||||||
| (cherry picked from commit a73f248369d35249a9324a0e0df9f7ccd1420d3f) |  | ||||||
| ---
 |  | ||||||
|  .gitignore                |   2 +- |  | ||||||
|  daemon/Makefile.am        |   5 +- |  | ||||||
|  daemon/lvm.c              |  22 ---- |  | ||||||
|  daemon/lvm_full.ml        | 221 ++++++++++++++++++++++++++++++++++++++ |  | ||||||
|  docs/C_SOURCE_FILES       |   1 - |  | ||||||
|  generator/actions_core.ml |   3 + |  | ||||||
|  generator/daemon.ml       | 190 -------------------------------- |  | ||||||
|  generator/daemon.mli      |   1 - |  | ||||||
|  generator/main.ml         |   2 - |  | ||||||
|  generator/structs.ml      |   4 +- |  | ||||||
|  generator/structs.mli     |   7 -- |  | ||||||
|  po/POTFILES               |   1 - |  | ||||||
|  12 files changed, 229 insertions(+), 230 deletions(-) |  | ||||||
|  create mode 100644 daemon/lvm_full.ml |  | ||||||
| 
 |  | ||||||
| diff --git a/.gitignore b/.gitignore
 |  | ||||||
| index 68b27c79..c5e8f802 100644
 |  | ||||||
| --- a/.gitignore
 |  | ||||||
| +++ b/.gitignore
 |  | ||||||
| @@ -97,7 +97,7 @@ Makefile.in
 |  | ||||||
|  /daemon/listfs.mli |  | ||||||
|  /daemon/lvm.mli |  | ||||||
|  /daemon/lvm_dm.mli |  | ||||||
| -/daemon/lvm-tokenization.c
 |  | ||||||
| +/daemon/lvm_full.mli
 |  | ||||||
|  /daemon/md.mli |  | ||||||
|  /daemon/mount.mli |  | ||||||
|  /daemon/names.c |  | ||||||
| diff --git a/daemon/Makefile.am b/daemon/Makefile.am
 |  | ||||||
| index bb72c024..90ece846 100644
 |  | ||||||
| --- a/daemon/Makefile.am
 |  | ||||||
| +++ b/daemon/Makefile.am
 |  | ||||||
| @@ -22,7 +22,6 @@ BUILT_SOURCES = \
 |  | ||||||
|  	caml-stubs.c \ |  | ||||||
|  	dispatch.c \ |  | ||||||
|  	names.c \ |  | ||||||
| -	lvm-tokenization.c \
 |  | ||||||
|  	structs-cleanups.c \ |  | ||||||
|  	structs-cleanups.h \ |  | ||||||
|  	stubs-0.c \ |  | ||||||
| @@ -52,6 +51,7 @@ generator_built = \
 |  | ||||||
|  	listfs.mli \ |  | ||||||
|  	lvm.mli \ |  | ||||||
|  	lvm_dm.mli \ |  | ||||||
| +	lvm_full.mli \
 |  | ||||||
|  	md.mli \ |  | ||||||
|  	mount.mli \ |  | ||||||
|  	optgroups.ml \ |  | ||||||
| @@ -152,7 +152,6 @@ guestfsd_SOURCES = \
 |  | ||||||
|  	luks.c \ |  | ||||||
|  	lvm.c \ |  | ||||||
|  	lvm-filter.c \ |  | ||||||
| -	lvm-tokenization.c \
 |  | ||||||
|  	md.c \ |  | ||||||
|  	mkfs.c \ |  | ||||||
|  	mknod.c \ |  | ||||||
| @@ -298,6 +297,7 @@ SOURCES_MLI = \
 |  | ||||||
|  	listfs.mli \ |  | ||||||
|  	lvm.mli \ |  | ||||||
|  	lvm_dm.mli \ |  | ||||||
| +	lvm_full.mli \
 |  | ||||||
|  	lvm_utils.mli \ |  | ||||||
|  	md.mli \ |  | ||||||
|  	mount.mli \ |  | ||||||
| @@ -333,6 +333,7 @@ SOURCES_ML = \
 |  | ||||||
|  	ldm.ml \ |  | ||||||
|  	link.ml \ |  | ||||||
|  	lvm.ml \ |  | ||||||
| +	lvm_full.ml \
 |  | ||||||
|  	lvm_utils.ml \ |  | ||||||
|  	lvm_dm.ml \ |  | ||||||
|  	findfs.ml \ |  | ||||||
| diff --git a/daemon/lvm.c b/daemon/lvm.c
 |  | ||||||
| index 7e76e17c..001aacb2 100644
 |  | ||||||
| --- a/daemon/lvm.c
 |  | ||||||
| +++ b/daemon/lvm.c
 |  | ||||||
| @@ -139,28 +139,6 @@ do_vgs (void)
 |  | ||||||
|    return convert_lvm_output (out, NULL); |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| -/* These were so complex to implement that I ended up auto-generating
 |  | ||||||
| - * the code.  That code is in stubs.c, and it is generated as usual
 |  | ||||||
| - * by generator.ml.
 |  | ||||||
| - */
 |  | ||||||
| -guestfs_int_lvm_pv_list *
 |  | ||||||
| -do_pvs_full (void)
 |  | ||||||
| -{
 |  | ||||||
| -  return parse_command_line_pvs ();
 |  | ||||||
| -}
 |  | ||||||
| -
 |  | ||||||
| -guestfs_int_lvm_vg_list *
 |  | ||||||
| -do_vgs_full (void)
 |  | ||||||
| -{
 |  | ||||||
| -  return parse_command_line_vgs ();
 |  | ||||||
| -}
 |  | ||||||
| -
 |  | ||||||
| -guestfs_int_lvm_lv_list *
 |  | ||||||
| -do_lvs_full (void)
 |  | ||||||
| -{
 |  | ||||||
| -  return parse_command_line_lvs ();
 |  | ||||||
| -}
 |  | ||||||
| -
 |  | ||||||
|  int |  | ||||||
|  do_pvcreate (const char *device) |  | ||||||
|  { |  | ||||||
| diff --git a/daemon/lvm_full.ml b/daemon/lvm_full.ml
 |  | ||||||
| new file mode 100644 |  | ||||||
| index 00000000..d5653d2f
 |  | ||||||
| --- /dev/null
 |  | ||||||
| +++ b/daemon/lvm_full.ml
 |  | ||||||
| @@ -0,0 +1,221 @@
 |  | ||||||
| +(* guestfs-inspection
 |  | ||||||
| + * Copyright (C) 2009-2025 Red Hat Inc.
 |  | ||||||
| + *
 |  | ||||||
| + * This program is free software; you can redistribute it and/or modify
 |  | ||||||
| + * it under the terms of the GNU General Public License as published by
 |  | ||||||
| + * 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.
 |  | ||||||
| + *)
 |  | ||||||
| +
 |  | ||||||
| +(* This file implements the complicated lvs-full, vgs-full and pvs-full APIs
 |  | ||||||
| + *
 |  | ||||||
| + * XXX Deprecate these APIs are replace with APIs for getting single
 |  | ||||||
| + * named fields from LVM.  That will be slower but far more flexible
 |  | ||||||
| + * and extensible.
 |  | ||||||
| + *)
 |  | ||||||
| +
 |  | ||||||
| +open Unix
 |  | ||||||
| +open Printf
 |  | ||||||
| +
 |  | ||||||
| +open Std_utils
 |  | ||||||
| +
 |  | ||||||
| +open Utils
 |  | ||||||
| +
 |  | ||||||
| +(* LVM UUIDs are basically 32 byte strings with '-' inserted.
 |  | ||||||
| + * Remove the '-' characters and check it's the right length.
 |  | ||||||
| + *)
 |  | ||||||
| +let parse_uuid uuid =
 |  | ||||||
| +  let uuid' =
 |  | ||||||
| +    uuid |> String.explode |> List.filter ((<>) '-') |> String.implode in
 |  | ||||||
| +  if String.length uuid' <> 32 then
 |  | ||||||
| +    failwithf "lvm-full: parse_uuid: unexpected UUID format: %S" uuid;
 |  | ||||||
| +  uuid'
 |  | ||||||
| +
 |  | ||||||
| +(* Parse the percent fields.  These can be empty. *)
 |  | ||||||
| +let parse_percent pc = if pc = "" then None else Some (float_of_string pc)
 |  | ||||||
| +
 |  | ||||||
| +(* XXX These must match generator/structs.ml *)
 |  | ||||||
| +let lvm_pv_cols = [
 |  | ||||||
| +  "pv_name";                    (* FString *)
 |  | ||||||
| +  "pv_uuid";                    (* FUUID *)
 |  | ||||||
| +  "pv_fmt";                     (* FString *)
 |  | ||||||
| +  "pv_size";                    (* FBytes *)
 |  | ||||||
| +  "dev_size";                   (* FBytes *)
 |  | ||||||
| +  "pv_free";                    (* FBytes *)
 |  | ||||||
| +  "pv_used";                    (* FBytes *)
 |  | ||||||
| +  "pv_attr";                    (* FString (* XXX *) *)
 |  | ||||||
| +  "pv_pe_count";                (* FInt64 *)
 |  | ||||||
| +  "pv_pe_alloc_count";          (* FInt64 *)
 |  | ||||||
| +  "pv_tags";                    (* FString *)
 |  | ||||||
| +  "pe_start";                   (* FBytes *)
 |  | ||||||
| +  "pv_mda_count";               (* FInt64 *)
 |  | ||||||
| +  "pv_mda_free";                (* FBytes *)
 |  | ||||||
| +]
 |  | ||||||
| +
 |  | ||||||
| +let tokenize_pvs = function
 |  | ||||||
| +  | [ pv_name; pv_uuid; pv_fmt; pv_size; dev_size; pv_free;
 |  | ||||||
| +      pv_used; pv_attr; pv_pe_count; pv_pe_alloc_count; pv_tags;
 |  | ||||||
| +      pe_start; pv_mda_count; pv_mda_free ] ->
 |  | ||||||
| +     { Structs.pv_name =                   pv_name;
 |  | ||||||
| +       pv_uuid =           parse_uuid      pv_uuid;
 |  | ||||||
| +       pv_fmt =                            pv_fmt;
 |  | ||||||
| +       pv_size =           Int64.of_string pv_size;
 |  | ||||||
| +       dev_size =          Int64.of_string dev_size;
 |  | ||||||
| +       pv_free =           Int64.of_string pv_free;
 |  | ||||||
| +       pv_used =           Int64.of_string pv_used;
 |  | ||||||
| +       pv_attr =                           pv_attr;
 |  | ||||||
| +       pv_pe_count =       Int64.of_string pv_pe_count;
 |  | ||||||
| +       pv_pe_alloc_count = Int64.of_string pv_pe_alloc_count;
 |  | ||||||
| +       pv_tags =                           pv_tags;
 |  | ||||||
| +       pe_start =          Int64.of_string pe_start;
 |  | ||||||
| +       pv_mda_count =      Int64.of_string pv_mda_count;
 |  | ||||||
| +       pv_mda_free =       Int64.of_string pv_mda_free }
 |  | ||||||
| +
 |  | ||||||
| +  | fields ->
 |  | ||||||
| +     failwithf "pvs-full: tokenize_pvs: unexpected number of fields: %d"
 |  | ||||||
| +       (List.length fields)
 |  | ||||||
| +
 |  | ||||||
| +(* XXX These must match generator/structs.ml *)
 |  | ||||||
| +let lvm_vg_cols = [
 |  | ||||||
| +  "vg_name";                    (* FString *)
 |  | ||||||
| +  "vg_uuid";                    (* FUUID *)
 |  | ||||||
| +  "vg_fmt";                     (* FString *)
 |  | ||||||
| +  "vg_attr";                    (* FString (* XXX *) *)
 |  | ||||||
| +  "vg_size";                    (* FBytes *)
 |  | ||||||
| +  "vg_free";                    (* FBytes *)
 |  | ||||||
| +  "vg_sysid";                   (* FString *)
 |  | ||||||
| +  "vg_extent_size";             (* FBytes *)
 |  | ||||||
| +  "vg_extent_count";            (* FInt64 *)
 |  | ||||||
| +  "vg_free_count";              (* FInt64 *)
 |  | ||||||
| +  "max_lv";                     (* FInt64 *)
 |  | ||||||
| +  "max_pv";                     (* FInt64 *)
 |  | ||||||
| +  "pv_count";                   (* FInt64 *)
 |  | ||||||
| +  "lv_count";                   (* FInt64 *)
 |  | ||||||
| +  "snap_count";                 (* FInt64 *)
 |  | ||||||
| +  "vg_seqno";                   (* FInt64 *)
 |  | ||||||
| +  "vg_tags";                    (* FString *)
 |  | ||||||
| +  "vg_mda_count";               (* FInt64 *)
 |  | ||||||
| +  "vg_mda_free";                (* FBytes *)
 |  | ||||||
| +]
 |  | ||||||
| +
 |  | ||||||
| +let tokenize_vgs = function
 |  | ||||||
| +  | [ vg_name; vg_uuid; vg_fmt; vg_attr; vg_size; vg_free; vg_sysid;
 |  | ||||||
| +      vg_extent_size; vg_extent_count; vg_free_count; max_lv;
 |  | ||||||
| +      max_pv; pv_count; lv_count; snap_count; vg_seqno; vg_tags;
 |  | ||||||
| +      vg_mda_count; vg_mda_free ] ->
 |  | ||||||
| +     { Structs.vg_name =                 vg_name;
 |  | ||||||
| +       vg_uuid =         parse_uuid      vg_uuid;
 |  | ||||||
| +       vg_fmt =                          vg_fmt;
 |  | ||||||
| +       vg_attr =                         vg_attr;
 |  | ||||||
| +       vg_size =         Int64.of_string vg_size;
 |  | ||||||
| +       vg_free =         Int64.of_string vg_free;
 |  | ||||||
| +       vg_sysid =                        vg_sysid;
 |  | ||||||
| +       vg_extent_size =  Int64.of_string vg_extent_size;
 |  | ||||||
| +       vg_extent_count = Int64.of_string vg_extent_count;
 |  | ||||||
| +       vg_free_count =   Int64.of_string vg_free_count;
 |  | ||||||
| +       max_lv =          Int64.of_string max_lv;
 |  | ||||||
| +       max_pv =          Int64.of_string max_pv;
 |  | ||||||
| +       pv_count =        Int64.of_string pv_count;
 |  | ||||||
| +       lv_count =        Int64.of_string lv_count;
 |  | ||||||
| +       snap_count =      Int64.of_string snap_count;
 |  | ||||||
| +       vg_seqno =        Int64.of_string vg_seqno;
 |  | ||||||
| +       vg_tags =                         vg_tags;
 |  | ||||||
| +       vg_mda_count =    Int64.of_string vg_mda_count;
 |  | ||||||
| +       vg_mda_free =     Int64.of_string vg_mda_free }
 |  | ||||||
| +
 |  | ||||||
| +  | fields ->
 |  | ||||||
| +     failwithf "pvs-full: tokenize_vgs: unexpected number of fields: %d"
 |  | ||||||
| +       (List.length fields)
 |  | ||||||
| +
 |  | ||||||
| +(* XXX These must match generator/structs.ml *)
 |  | ||||||
| +let lvm_lv_cols = [
 |  | ||||||
| +  "lv_name";                    (* FString *)
 |  | ||||||
| +  "lv_uuid";                    (* FUUID *)
 |  | ||||||
| +  "lv_attr";                    (* FString (* XXX *) *)
 |  | ||||||
| +  "lv_major";                   (* FInt64 *)
 |  | ||||||
| +  "lv_minor";                   (* FInt64 *)
 |  | ||||||
| +  "lv_kernel_major";            (* FInt64 *)
 |  | ||||||
| +  "lv_kernel_minor";            (* FInt64 *)
 |  | ||||||
| +  "lv_size";                    (* FBytes *)
 |  | ||||||
| +  "seg_count";                  (* FInt64 *)
 |  | ||||||
| +  "origin";                     (* FString *)
 |  | ||||||
| +  "snap_percent";               (* FOptPercent *)
 |  | ||||||
| +  "copy_percent";               (* FOptPercent *)
 |  | ||||||
| +  "move_pv";                    (* FString *)
 |  | ||||||
| +  "lv_tags";                    (* FString *)
 |  | ||||||
| +  "mirror_log";                 (* FString *)
 |  | ||||||
| +  "modules";                    (* FString *)
 |  | ||||||
| +]
 |  | ||||||
| +
 |  | ||||||
| +let tokenize_lvs = function
 |  | ||||||
| +  | [ lv_name; lv_uuid; lv_attr; lv_major; lv_minor; lv_kernel_major;
 |  | ||||||
| +      lv_kernel_minor; lv_size; seg_count; origin; snap_percent;
 |  | ||||||
| +      copy_percent; move_pv; lv_tags; mirror_log; modules ] ->
 |  | ||||||
| +     { Structs.lv_name =                 lv_name;
 |  | ||||||
| +       lv_uuid =         parse_uuid      lv_uuid;
 |  | ||||||
| +       lv_attr =                         lv_attr;
 |  | ||||||
| +       lv_major =        Int64.of_string lv_major;
 |  | ||||||
| +       lv_minor =        Int64.of_string lv_minor;
 |  | ||||||
| +       lv_kernel_major = Int64.of_string lv_kernel_major;
 |  | ||||||
| +       lv_kernel_minor = Int64.of_string lv_kernel_minor;
 |  | ||||||
| +       lv_size =         Int64.of_string lv_size;
 |  | ||||||
| +       seg_count =       Int64.of_string seg_count;
 |  | ||||||
| +       origin =                          origin;
 |  | ||||||
| +       snap_percent =    parse_percent   snap_percent;
 |  | ||||||
| +       copy_percent =    parse_percent   copy_percent;
 |  | ||||||
| +       move_pv =                         move_pv;
 |  | ||||||
| +       lv_tags =                         lv_tags;
 |  | ||||||
| +       mirror_log =                      mirror_log;
 |  | ||||||
| +       modules =                         modules }
 |  | ||||||
| +
 |  | ||||||
| +  | fields ->
 |  | ||||||
| +    failwithf "pvs-full: tokenize_vgs: unexpected number of fields: %d"
 |  | ||||||
| +      (List.length fields)
 |  | ||||||
| +
 |  | ||||||
| +let rec pvs_full () =
 |  | ||||||
| +  let out = run_lvm_command "pvs" lvm_pv_cols in
 |  | ||||||
| +  let lines = trim_and_split out in
 |  | ||||||
| +  let pvs = List.map tokenize_pvs lines in
 |  | ||||||
| +  pvs
 |  | ||||||
| +
 |  | ||||||
| +and vgs_full () =
 |  | ||||||
| +  let out = run_lvm_command "vgs" lvm_vg_cols in
 |  | ||||||
| +  let lines = trim_and_split out in
 |  | ||||||
| +  let vgs = List.map tokenize_vgs lines in
 |  | ||||||
| +  vgs
 |  | ||||||
| +
 |  | ||||||
| +and lvs_full () =
 |  | ||||||
| +  let out = run_lvm_command "lvs" lvm_lv_cols in
 |  | ||||||
| +  let lines = trim_and_split out in
 |  | ||||||
| +  let lvs = List.map tokenize_lvs lines in
 |  | ||||||
| +  lvs
 |  | ||||||
| +
 |  | ||||||
| +and run_lvm_command typ cols =
 |  | ||||||
| +  let cols = String.concat "," cols in
 |  | ||||||
| +  let cmd = [ typ; "-o"; cols;
 |  | ||||||
| +              "--unbuffered"; "--noheadings"; "--nosuffix";
 |  | ||||||
| +              "--separator"; "\r"; "--units"; "b" ] in
 |  | ||||||
| +  command "lvm" cmd
 |  | ||||||
| +
 |  | ||||||
| +and trim_and_split out =
 |  | ||||||
| +  (* Split the output into lines. *)
 |  | ||||||
| +  let lines = String.nsplit "\n" out in
 |  | ||||||
| +
 |  | ||||||
| +  (* LVM puts leading whitespace on each line so remove that. *)
 |  | ||||||
| +  let lines = List.map String.triml lines in
 |  | ||||||
| +
 |  | ||||||
| +  (* Ignore any blank lines. *)
 |  | ||||||
| +  let lines = List.filter ((<>) "") lines in
 |  | ||||||
| +
 |  | ||||||
| +  (* Split each line into fields. *)
 |  | ||||||
| +  let lines = List.map (String.nsplit "\r") lines in
 |  | ||||||
| +  lines
 |  | ||||||
| diff --git a/docs/C_SOURCE_FILES b/docs/C_SOURCE_FILES
 |  | ||||||
| index 0038f95e..cdfb1d61 100644
 |  | ||||||
| --- a/docs/C_SOURCE_FILES
 |  | ||||||
| +++ b/docs/C_SOURCE_FILES
 |  | ||||||
| @@ -111,7 +111,6 @@ daemon/link.c
 |  | ||||||
|  daemon/ls.c |  | ||||||
|  daemon/luks.c |  | ||||||
|  daemon/lvm-filter.c |  | ||||||
| -daemon/lvm-tokenization.c
 |  | ||||||
|  daemon/lvm.c |  | ||||||
|  daemon/md.c |  | ||||||
|  daemon/mkfs.c |  | ||||||
| diff --git a/generator/actions_core.ml b/generator/actions_core.ml
 |  | ||||||
| index eb047b6b..01991dd0 100644
 |  | ||||||
| --- a/generator/actions_core.ml
 |  | ||||||
| +++ b/generator/actions_core.ml
 |  | ||||||
| @@ -1767,6 +1767,7 @@ See also C<guestfs_lvs_full>, C<guestfs_list_filesystems>." };
 |  | ||||||
|    { defaults with |  | ||||||
|      name = "pvs_full"; added = (0, 0, 4); |  | ||||||
|      style = RStructList ("physvols", "lvm_pv"), [], []; |  | ||||||
| +    impl = OCaml "Lvm_full.pvs_full";
 |  | ||||||
|      optional = Some "lvm2"; |  | ||||||
|      shortdesc = "list the LVM physical volumes (PVs)"; |  | ||||||
|      longdesc = "\ |  | ||||||
| @@ -1776,6 +1777,7 @@ of the L<pvs(8)> command.  The \"full\" version includes all fields." };
 |  | ||||||
|    { defaults with |  | ||||||
|      name = "vgs_full"; added = (0, 0, 4); |  | ||||||
|      style = RStructList ("volgroups", "lvm_vg"), [], []; |  | ||||||
| +    impl = OCaml "Lvm_full.vgs_full";
 |  | ||||||
|      optional = Some "lvm2"; |  | ||||||
|      shortdesc = "list the LVM volume groups (VGs)"; |  | ||||||
|      longdesc = "\ |  | ||||||
| @@ -1785,6 +1787,7 @@ of the L<vgs(8)> command.  The \"full\" version includes all fields." };
 |  | ||||||
|    { defaults with |  | ||||||
|      name = "lvs_full"; added = (0, 0, 4); |  | ||||||
|      style = RStructList ("logvols", "lvm_lv"), [], []; |  | ||||||
| +    impl = OCaml "Lvm_full.lvs_full";
 |  | ||||||
|      optional = Some "lvm2"; |  | ||||||
|      shortdesc = "list the LVM logical volumes (LVs)"; |  | ||||||
|      longdesc = "\ |  | ||||||
| diff --git a/generator/daemon.ml b/generator/daemon.ml
 |  | ||||||
| index 91decf40..f9b77a18 100644
 |  | ||||||
| --- a/generator/daemon.ml
 |  | ||||||
| +++ b/generator/daemon.ml
 |  | ||||||
| @@ -951,196 +951,6 @@ let generate_daemon_dispatch () =
 |  | ||||||
|    pr "}\n"; |  | ||||||
|    pr "\n" |  | ||||||
|   |  | ||||||
| -let generate_daemon_lvm_tokenization () =
 |  | ||||||
| -  generate_header CStyle GPLv2plus;
 |  | ||||||
| -
 |  | ||||||
| -  pr "\
 |  | ||||||
| -#include <config.h>
 |  | ||||||
| -
 |  | ||||||
| -#include <stdio.h>
 |  | ||||||
| -#include <stdlib.h>
 |  | ||||||
| -#include <string.h>
 |  | ||||||
| -#include <inttypes.h>
 |  | ||||||
| -#include <errno.h>
 |  | ||||||
| -#include <rpc/types.h>
 |  | ||||||
| -#include <rpc/xdr.h>
 |  | ||||||
| -
 |  | ||||||
| -#include \"daemon.h\"
 |  | ||||||
| -#include \"c-ctype.h\"
 |  | ||||||
| -#include \"guestfs_protocol.h\"
 |  | ||||||
| -#include \"actions.h\"
 |  | ||||||
| -#include \"optgroups.h\"
 |  | ||||||
| -
 |  | ||||||
| -";
 |  | ||||||
| -
 |  | ||||||
| -  (* LVM columns and tokenization functions. *)
 |  | ||||||
| -  (* XXX This generates crap code.  We should rethink how we
 |  | ||||||
| -   * do this parsing.
 |  | ||||||
| -   *)
 |  | ||||||
| -  List.iter (
 |  | ||||||
| -    function
 |  | ||||||
| -    | typ, cols ->
 |  | ||||||
| -        pr "static const char lvm_%s_cols[] = \"%s\";\n"
 |  | ||||||
| -          typ (String.concat "," (List.map fst cols));
 |  | ||||||
| -        pr "\n";
 |  | ||||||
| -
 |  | ||||||
| -        pr "static int lvm_tokenize_%s (char *str, guestfs_int_lvm_%s *r)\n" typ typ;
 |  | ||||||
| -        pr "{\n";
 |  | ||||||
| -        pr "  char *tok, *p, *next;\n";
 |  | ||||||
| -        pr "  size_t i, j;\n";
 |  | ||||||
| -        pr "\n";
 |  | ||||||
| -        (*
 |  | ||||||
| -          pr "  fprintf (stderr, \"%%s: <<%%s>>\\n\", __func__, str);\n";
 |  | ||||||
| -          pr "\n";
 |  | ||||||
| -        *)
 |  | ||||||
| -        pr "  if (!str) {\n";
 |  | ||||||
| -        pr "    fprintf (stderr, \"%%s: failed: passed a NULL string\\n\", __func__);\n";
 |  | ||||||
| -        pr "    return -1;\n";
 |  | ||||||
| -        pr "  }\n";
 |  | ||||||
| -        pr "  if (!*str || c_isspace (*str)) {\n";
 |  | ||||||
| -        pr "    fprintf (stderr, \"%%s: failed: passed a empty string or one beginning with whitespace\\n\", __func__);\n";
 |  | ||||||
| -        pr "    return -1;\n";
 |  | ||||||
| -        pr "  }\n";
 |  | ||||||
| -        pr "  tok = str;\n";
 |  | ||||||
| -        List.iter (
 |  | ||||||
| -          fun (name, coltype) ->
 |  | ||||||
| -            pr "  if (!tok) {\n";
 |  | ||||||
| -            pr "    fprintf (stderr, \"%%s: failed: string finished early, around token %%s\\n\", __func__, \"%s\");\n" name;
 |  | ||||||
| -            pr "    return -1;\n";
 |  | ||||||
| -            pr "  }\n";
 |  | ||||||
| -            pr "  p = strchrnul (tok, '\\r');\n";
 |  | ||||||
| -            pr "  if (*p) next = p+1; else next = NULL;\n";
 |  | ||||||
| -            pr "  *p = '\\0';\n";
 |  | ||||||
| -            (match coltype with
 |  | ||||||
| -             | FString | FDevice ->
 |  | ||||||
| -                 pr "  r->%s = strdup (tok);\n" name;
 |  | ||||||
| -                 pr "  if (r->%s == NULL) {\n" name;
 |  | ||||||
| -                 pr "    perror (\"strdup\");\n";
 |  | ||||||
| -                 pr "    return -1;\n";
 |  | ||||||
| -                 pr "  }\n"
 |  | ||||||
| -             | FUUID ->
 |  | ||||||
| -                 pr "  for (i = j = 0; i < 32; ++j) {\n";
 |  | ||||||
| -                 pr "    if (tok[j] == '\\0') {\n";
 |  | ||||||
| -                 pr "      fprintf (stderr, \"%%s: failed to parse UUID from '%%s'\\n\", __func__, tok);\n";
 |  | ||||||
| -                 pr "      return -1;\n";
 |  | ||||||
| -                 pr "    } else if (tok[j] != '-')\n";
 |  | ||||||
| -                 pr "      r->%s[i++] = tok[j];\n" name;
 |  | ||||||
| -                 pr "  }\n";
 |  | ||||||
| -             | FBytes ->
 |  | ||||||
| -                 pr "  if (sscanf (tok, \"%%\" SCNi64, &r->%s) != 1) {\n" name;
 |  | ||||||
| -                 pr "    fprintf (stderr, \"%%s: failed to parse size '%%s' from token %%s\\n\", __func__, tok, \"%s\");\n" name;
 |  | ||||||
| -                 pr "    return -1;\n";
 |  | ||||||
| -                 pr "  }\n";
 |  | ||||||
| -             | FInt64 ->
 |  | ||||||
| -                 pr "  if (sscanf (tok, \"%%\" SCNi64, &r->%s) != 1) {\n" name;
 |  | ||||||
| -                 pr "    fprintf (stderr, \"%%s: failed to parse int '%%s' from token %%s\\n\", __func__, tok, \"%s\");\n" name;
 |  | ||||||
| -                 pr "    return -1;\n";
 |  | ||||||
| -                 pr "  }\n";
 |  | ||||||
| -             | FOptPercent ->
 |  | ||||||
| -                 pr "  if (tok[0] == '\\0')\n";
 |  | ||||||
| -                 pr "    r->%s = -1;\n" name;
 |  | ||||||
| -                 pr "  else if (sscanf (tok, \"%%f\", &r->%s) != 1) {\n" name;
 |  | ||||||
| -                 pr "    fprintf (stderr, \"%%s: failed to parse float '%%s' from token %%s\\n\", __func__, tok, \"%s\");\n" name;
 |  | ||||||
| -                 pr "    return -1;\n";
 |  | ||||||
| -                 pr "  }\n";
 |  | ||||||
| -             | FBuffer | FInt32 | FUInt32 | FUInt64 | FChar ->
 |  | ||||||
| -                 assert false (* can never be an LVM column *)
 |  | ||||||
| -            );
 |  | ||||||
| -            pr "  tok = next;\n";
 |  | ||||||
| -        ) cols;
 |  | ||||||
| -
 |  | ||||||
| -        pr "  if (tok != NULL) {\n";
 |  | ||||||
| -        pr "    fprintf (stderr, \"%%s: failed: extra tokens at end of string\\n\", __func__);\n";
 |  | ||||||
| -        pr "    return -1;\n";
 |  | ||||||
| -        pr "  }\n";
 |  | ||||||
| -        pr "  return 0;\n";
 |  | ||||||
| -        pr "}\n";
 |  | ||||||
| -        pr "\n";
 |  | ||||||
| -
 |  | ||||||
| -        pr "guestfs_int_lvm_%s_list *\n" typ;
 |  | ||||||
| -        pr "parse_command_line_%ss (void)\n" typ;
 |  | ||||||
| -        pr "{\n";
 |  | ||||||
| -        pr "  char *out, *err;\n";
 |  | ||||||
| -        pr "  char *p, *pend;\n";
 |  | ||||||
| -        pr "  int r, i;\n";
 |  | ||||||
| -        pr "  guestfs_int_lvm_%s_list *ret;\n" typ;
 |  | ||||||
| -        pr "  void *newp;\n";
 |  | ||||||
| -        pr "\n";
 |  | ||||||
| -        pr "  ret = malloc (sizeof *ret);\n";
 |  | ||||||
| -        pr "  if (!ret) {\n";
 |  | ||||||
| -        pr "    reply_with_perror (\"malloc\");\n";
 |  | ||||||
| -        pr "    return NULL;\n";
 |  | ||||||
| -        pr "  }\n";
 |  | ||||||
| -        pr "\n";
 |  | ||||||
| -        pr "  ret->guestfs_int_lvm_%s_list_len = 0;\n" typ;
 |  | ||||||
| -        pr "  ret->guestfs_int_lvm_%s_list_val = NULL;\n" typ;
 |  | ||||||
| -        pr "\n";
 |  | ||||||
| -        pr "  r = command (&out, &err,\n";
 |  | ||||||
| -        pr "	       \"lvm\", \"%ss\",\n" typ;
 |  | ||||||
| -        pr "	       \"-o\", lvm_%s_cols, \"--unbuffered\", \"--noheadings\",\n" typ;
 |  | ||||||
| -        pr "	       \"--nosuffix\", \"--separator\", \"\\r\", \"--units\", \"b\", NULL);\n";
 |  | ||||||
| -        pr "  if (r == -1) {\n";
 |  | ||||||
| -        pr "    reply_with_error (\"%%s\", err);\n";
 |  | ||||||
| -        pr "    free (out);\n";
 |  | ||||||
| -        pr "    free (err);\n";
 |  | ||||||
| -        pr "    free (ret);\n";
 |  | ||||||
| -        pr "    return NULL;\n";
 |  | ||||||
| -        pr "  }\n";
 |  | ||||||
| -        pr "\n";
 |  | ||||||
| -        pr "  free (err);\n";
 |  | ||||||
| -        pr "\n";
 |  | ||||||
| -        pr "  /* Tokenize each line of the output. */\n";
 |  | ||||||
| -        pr "  p = out;\n";
 |  | ||||||
| -        pr "  i = 0;\n";
 |  | ||||||
| -        pr "  while (p) {\n";
 |  | ||||||
| -        pr "    pend = strchr (p, '\\n');	/* Get the next line of output. */\n";
 |  | ||||||
| -        pr "    if (pend) {\n";
 |  | ||||||
| -        pr "      *pend = '\\0';\n";
 |  | ||||||
| -        pr "      pend++;\n";
 |  | ||||||
| -        pr "    }\n";
 |  | ||||||
| -        pr "\n";
 |  | ||||||
| -        pr "    while (*p && c_isspace (*p))	/* Skip any leading whitespace. */\n";
 |  | ||||||
| -        pr "      p++;\n";
 |  | ||||||
| -        pr "\n";
 |  | ||||||
| -        pr "    if (!*p) {			/* Empty line?  Skip it. */\n";
 |  | ||||||
| -        pr "      p = pend;\n";
 |  | ||||||
| -        pr "      continue;\n";
 |  | ||||||
| -        pr "    }\n";
 |  | ||||||
| -        pr "\n";
 |  | ||||||
| -        pr "    /* Allocate some space to store this next entry. */\n";
 |  | ||||||
| -        pr "    newp = realloc (ret->guestfs_int_lvm_%s_list_val,\n" typ;
 |  | ||||||
| -        pr "		    sizeof (guestfs_int_lvm_%s) * (i+1));\n" typ;
 |  | ||||||
| -        pr "    if (newp == NULL) {\n";
 |  | ||||||
| -        pr "      reply_with_perror (\"realloc\");\n";
 |  | ||||||
| -        pr "      free (ret->guestfs_int_lvm_%s_list_val);\n" typ;
 |  | ||||||
| -        pr "      free (ret);\n";
 |  | ||||||
| -        pr "      free (out);\n";
 |  | ||||||
| -        pr "      return NULL;\n";
 |  | ||||||
| -        pr "    }\n";
 |  | ||||||
| -        pr "    ret->guestfs_int_lvm_%s_list_val = newp;\n" typ;
 |  | ||||||
| -        pr "\n";
 |  | ||||||
| -        pr "    /* Tokenize the next entry. */\n";
 |  | ||||||
| -        pr "    r = lvm_tokenize_%s (p, &ret->guestfs_int_lvm_%s_list_val[i]);\n" typ typ;
 |  | ||||||
| -        pr "    if (r == -1) {\n";
 |  | ||||||
| -        pr "      reply_with_error (\"failed to parse output of '%ss' command\");\n" typ;
 |  | ||||||
| -        pr "      free (ret->guestfs_int_lvm_%s_list_val);\n" typ;
 |  | ||||||
| -        pr "      free (ret);\n";
 |  | ||||||
| -        pr "      free (out);\n";
 |  | ||||||
| -        pr "      return NULL;\n";
 |  | ||||||
| -        pr "    }\n";
 |  | ||||||
| -        pr "\n";
 |  | ||||||
| -        pr "    ++i;\n";
 |  | ||||||
| -        pr "    p = pend;\n";
 |  | ||||||
| -        pr "  }\n";
 |  | ||||||
| -        pr "\n";
 |  | ||||||
| -        pr "  ret->guestfs_int_lvm_%s_list_len = i;\n" typ;
 |  | ||||||
| -        pr "\n";
 |  | ||||||
| -        pr "  free (out);\n";
 |  | ||||||
| -        pr "  return ret;\n";
 |  | ||||||
| -        pr "}\n"
 |  | ||||||
| -
 |  | ||||||
| -  ) ["pv", lvm_pv_cols; "vg", lvm_vg_cols; "lv", lvm_lv_cols]
 |  | ||||||
| -
 |  | ||||||
|  (* Generate a list of function names, for debugging in the daemon.. *) |  | ||||||
|  let generate_daemon_names () = |  | ||||||
|    generate_header CStyle GPLv2plus; |  | ||||||
| diff --git a/generator/daemon.mli b/generator/daemon.mli
 |  | ||||||
| index edf331a9..77c6e632 100644
 |  | ||||||
| --- a/generator/daemon.mli
 |  | ||||||
| +++ b/generator/daemon.mli
 |  | ||||||
| @@ -23,7 +23,6 @@ val generate_daemon_caml_stubs : unit -> unit
 |  | ||||||
|  val generate_daemon_caml_callbacks_ml : unit -> unit |  | ||||||
|  val generate_daemon_caml_interface : string -> unit -> unit |  | ||||||
|  val generate_daemon_dispatch : unit -> unit |  | ||||||
| -val generate_daemon_lvm_tokenization : unit -> unit
 |  | ||||||
|  val generate_daemon_names : unit -> unit |  | ||||||
|  val generate_daemon_optgroups_c : unit -> unit |  | ||||||
|  val generate_daemon_optgroups_h : unit -> unit |  | ||||||
| diff --git a/generator/main.ml b/generator/main.ml
 |  | ||||||
| index ff5e964a..6e36d9c7 100644
 |  | ||||||
| --- a/generator/main.ml
 |  | ||||||
| +++ b/generator/main.ml
 |  | ||||||
| @@ -147,8 +147,6 @@ Run it from the top source directory using the command
 |  | ||||||
|              Daemon.generate_daemon_optgroups_ml; |  | ||||||
|    output_to "daemon/optgroups.mli" |  | ||||||
|              Daemon.generate_daemon_optgroups_mli; |  | ||||||
| -  output_to "daemon/lvm-tokenization.c"
 |  | ||||||
| -            Daemon.generate_daemon_lvm_tokenization;
 |  | ||||||
|    output_to "daemon/structs-cleanups.c" |  | ||||||
|              Daemon.generate_daemon_structs_cleanups_c; |  | ||||||
|    output_to "daemon/structs-cleanups.h" |  | ||||||
| diff --git a/generator/structs.ml b/generator/structs.ml
 |  | ||||||
| index 93a3ed03..239a5d5e 100644
 |  | ||||||
| --- a/generator/structs.ml
 |  | ||||||
| +++ b/generator/structs.ml
 |  | ||||||
| @@ -31,9 +31,7 @@ type struc = {
 |  | ||||||
|    s_unused : unit; (* Silences warning 23 when using 'defaults with ...' *) |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| -(* Because we generate extra parsing code for LVM command line tools,
 |  | ||||||
| - * we have to pull out the LVM columns separately here.
 |  | ||||||
| - *)
 |  | ||||||
| +(* XXX These must match daemon/lvm_full.ml *)
 |  | ||||||
|  let lvm_pv_cols = [ |  | ||||||
|    "pv_name", FDevice; |  | ||||||
|    "pv_uuid", FUUID; |  | ||||||
| diff --git a/generator/structs.mli b/generator/structs.mli
 |  | ||||||
| index e7a29b01..b3444623 100644
 |  | ||||||
| --- a/generator/structs.mli
 |  | ||||||
| +++ b/generator/structs.mli
 |  | ||||||
| @@ -34,13 +34,6 @@ type struc = {
 |  | ||||||
|  val structs : struc list |  | ||||||
|  (** List of structures. *) |  | ||||||
|   |  | ||||||
| -val lvm_pv_cols : cols
 |  | ||||||
| -val lvm_vg_cols : cols
 |  | ||||||
| -val lvm_lv_cols : cols
 |  | ||||||
| -(** These are exported to the daemon code generator where they are
 |  | ||||||
| -    used to generate code for parsing the output of commands like
 |  | ||||||
| -    [lvs].  One day replace this with liblvm API calls. *)
 |  | ||||||
| -
 |  | ||||||
|  val lookup_struct : string -> struc |  | ||||||
|  (** Lookup a struct by name. *) |  | ||||||
|   |  | ||||||
| diff --git a/po/POTFILES b/po/POTFILES
 |  | ||||||
| index 75b040c0..d10f9710 100644
 |  | ||||||
| --- a/po/POTFILES
 |  | ||||||
| +++ b/po/POTFILES
 |  | ||||||
| @@ -90,7 +90,6 @@ daemon/link.c
 |  | ||||||
|  daemon/ls.c |  | ||||||
|  daemon/luks.c |  | ||||||
|  daemon/lvm-filter.c |  | ||||||
| -daemon/lvm-tokenization.c
 |  | ||||||
|  daemon/lvm.c |  | ||||||
|  daemon/md.c |  | ||||||
|  daemon/mkfs.c |  | ||||||
| @ -1,70 +0,0 @@ | |||||||
| From 180293338e0d127d0545fe03b6141ed04e22e441 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: "Richard W.M. Jones" <rjones@redhat.com> |  | ||||||
| Date: Wed, 16 Apr 2025 10:27:25 +0100 |  | ||||||
| Subject: [PATCH] daemon: inspect: Resolve Ubuntu 22+ |  | ||||||
|  /dev/disk/by-id/dm-uuid-LVM-... in fstab |  | ||||||
| 
 |  | ||||||
| Linux + LVM supports device names like /dev/disk/by-id/dm-uuid-LVM- |  | ||||||
| followed by two concatenated UUIDs, firstly for the volume group and |  | ||||||
| secondly for the logical volume.  We can reverse those to get the |  | ||||||
| device name (/dev/VG/LV). |  | ||||||
| 
 |  | ||||||
| fstab entries look like: |  | ||||||
| 
 |  | ||||||
|   # / was on /dev/vg0/lv-0 during curtin installation |  | ||||||
|   /dev/disk/by-id/dm-uuid-LVM-OzFWT6NHkstr1hcmrWRRMDGPn9xdZj1YOOycQ533186x288FdU6UubU3OlnWJz6D / ext4 defaults 0 1 |  | ||||||
|   # /usr was on /dev/vg0/lv-1 during curtin installation |  | ||||||
|   /dev/disk/by-id/dm-uuid-LVM-OzFWT6NHkstr1hcmrWRRMDGPn9xdZj1YZu53m4ZssZ8Jeb3I14RAJwIj5YlHIb9P /usr ext4 defaults 0 1 |  | ||||||
| 
 |  | ||||||
| The upshot of this fix is that we are now able to correctly inspect |  | ||||||
| and run virt-v2v on Ubuntu 22+ guests with split /usr.  In particular, |  | ||||||
| we correctly map /etc/fstab entries like the above to LV device names, |  | ||||||
| which means that /usr merging now works correctly. |  | ||||||
| 
 |  | ||||||
| Reported-by: Jaroslav Spanko |  | ||||||
| Thanks: Daniel Berrange |  | ||||||
| Fixes: https://issues.redhat.com/browse/RHEL-87493 |  | ||||||
| (cherry picked from commit e43ca1912973b3ddfa73b09a4690aa8bb26e08af) |  | ||||||
| ---
 |  | ||||||
|  daemon/inspect_fs_unix_fstab.ml | 21 +++++++++++++++++++++ |  | ||||||
|  1 file changed, 21 insertions(+) |  | ||||||
| 
 |  | ||||||
| diff --git a/daemon/inspect_fs_unix_fstab.ml b/daemon/inspect_fs_unix_fstab.ml
 |  | ||||||
| index 45c62175..dcbdab3c 100644
 |  | ||||||
| --- a/daemon/inspect_fs_unix_fstab.ml
 |  | ||||||
| +++ b/daemon/inspect_fs_unix_fstab.ml
 |  | ||||||
| @@ -27,6 +27,7 @@ open Inspect_utils
 |  | ||||||
|   |  | ||||||
|  let re_cciss = PCRE.compile "^/dev/(cciss/c\\d+d\\d+)(?:p(\\d+))?$" |  | ||||||
|  let re_diskbyid = PCRE.compile "^/dev/disk/by-id/.*-part(\\d+)$" |  | ||||||
| +let re_dmuuid = PCRE.compile "^/dev/disk/by-id/dm-uuid-LVM-([0-9a-zA-Z]{32})([0-9a-zA-Z]{32})$"
 |  | ||||||
|  let re_freebsd_gpt = PCRE.compile "^/dev/(ada{0,1}|vtbd)(\\d+)p(\\d+)$" |  | ||||||
|  let re_freebsd_mbr = PCRE.compile "^/dev/(ada{0,1}|vtbd)(\\d+)s(\\d+)([a-z])$" |  | ||||||
|  let re_hurd_dev = PCRE.compile "^/dev/(h)d(\\d+)s(\\d+)$" |  | ||||||
| @@ -407,6 +408,26 @@ and resolve_fstab_device spec md_map os_type =
 |  | ||||||
|        Failure _ -> default |  | ||||||
|    ) |  | ||||||
|   |  | ||||||
| +  (* Ubuntu 22+ uses /dev/disk/by-id/dm-uuid-LVM-... followed by a
 |  | ||||||
| +   * double UUID which identifies an LV.  The first part of the UUID
 |  | ||||||
| +   * is the VG UUID.  The second part is the LV UUID.
 |  | ||||||
| +   *)
 |  | ||||||
| +  else if PCRE.matches re_dmuuid spec then (
 |  | ||||||
| +    debug_matching "dmuuid";
 |  | ||||||
| +    let vg_uuid_spec = PCRE.sub 1 and lv_uuid_spec = PCRE.sub 2 in
 |  | ||||||
| +    try
 |  | ||||||
| +      (* Get the list of all VGs and LVs. *)
 |  | ||||||
| +      let vgs = Lvm_full.vgs_full () and lvs = Lvm_full.lvs_full () in
 |  | ||||||
| +      (* Find one VG & LV (hopefully) that matches the UUIDs. *)
 |  | ||||||
| +      let vg =
 |  | ||||||
| +        List.find (fun { Structs.vg_uuid } -> vg_uuid = vg_uuid_spec) vgs
 |  | ||||||
| +      and lv =
 |  | ||||||
| +        List.find (fun { Structs.lv_uuid } -> lv_uuid = lv_uuid_spec) lvs in
 |  | ||||||
| +      Mountable.of_device (sprintf "/dev/%s/%s" vg.vg_name lv.lv_name)
 |  | ||||||
| +    with
 |  | ||||||
| +      Failure _ | Not_found -> default
 |  | ||||||
| +  )
 |  | ||||||
| +
 |  | ||||||
|    else if PCRE.matches re_freebsd_gpt spec then ( |  | ||||||
|      debug_matching "FreeBSD GPT"; |  | ||||||
|      (* group 1 (type) is not used *) |  | ||||||
| @ -1,38 +0,0 @@ | |||||||
| From 14b2ac2d5f087b0d8fc8c1e0451cae22af753734 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: "Richard W.M. Jones" <rjones@redhat.com> |  | ||||||
| Date: Fri, 25 Apr 2025 15:14:24 +0100 |  | ||||||
| Subject: [PATCH] RHEL 9: daemon/fstrim.c: Run the fstrim command twice |  | ||||||
| 
 |  | ||||||
| Workaround for https://issues.redhat.com/browse/RHEL-88450 |  | ||||||
| 
 |  | ||||||
| Fixes: https://issues.redhat.com/browse/RHEL-88508 |  | ||||||
| Related: https://issues.redhat.com/browse/RHEL-88450 |  | ||||||
| Thanks: Eric Sandeen |  | ||||||
| ---
 |  | ||||||
|  daemon/fstrim.c | 11 +++++++++++ |  | ||||||
|  1 file changed, 11 insertions(+) |  | ||||||
| 
 |  | ||||||
| diff --git a/daemon/fstrim.c b/daemon/fstrim.c
 |  | ||||||
| index f6869042..06707a7f 100644
 |  | ||||||
| --- a/daemon/fstrim.c
 |  | ||||||
| +++ b/daemon/fstrim.c
 |  | ||||||
| @@ -101,8 +101,19 @@ do_fstrim (const char *path,
 |  | ||||||
|    ADD_ARG (argv, i, buf); |  | ||||||
|    ADD_ARG (argv, i, NULL); |  | ||||||
|   |  | ||||||
| +  /* Run the command twice to workaround
 |  | ||||||
| +   * https://issues.redhat.com/browse/RHEL-88450
 |  | ||||||
| +   */
 |  | ||||||
| +  r = commandv (&out, &err, argv);
 |  | ||||||
| +  if (r == -1) goto error;
 |  | ||||||
| +  if (verbose)
 |  | ||||||
| +    fprintf (stderr, "%s\n", out);
 |  | ||||||
| +  free (out); out = NULL;
 |  | ||||||
| +  free (err); err = NULL;
 |  | ||||||
| +
 |  | ||||||
|    r = commandv (&out, &err, argv); |  | ||||||
|    if (r == -1) { |  | ||||||
| +  error:
 |  | ||||||
|      /* If the error is about the kernel operation not being supported |  | ||||||
|       * for this filesystem type, then return errno ENOTSUP here. |  | ||||||
|       */ |  | ||||||
| @ -1,29 +0,0 @@ | |||||||
| From e9a7378d730477d6a548c18244ba0bde9c7dc93d Mon Sep 17 00:00:00 2001 |  | ||||||
| From: "Richard W.M. Jones" <rjones@redhat.com> |  | ||||||
| Date: Fri, 25 Apr 2025 15:24:43 +0100 |  | ||||||
| Subject: [PATCH] daemon/fstrim.c: Issue sync_disks after fstrim |  | ||||||
| 
 |  | ||||||
| Thanks: Eric Sandeen |  | ||||||
| (cherry picked from commit e127edcafc95c75bf484bf2199eb746a392c58c0) |  | ||||||
| ---
 |  | ||||||
|  daemon/fstrim.c | 8 ++++++++ |  | ||||||
|  1 file changed, 8 insertions(+) |  | ||||||
| 
 |  | ||||||
| diff --git a/daemon/fstrim.c b/daemon/fstrim.c
 |  | ||||||
| index 06707a7f..474ef72d 100644
 |  | ||||||
| --- a/daemon/fstrim.c
 |  | ||||||
| +++ b/daemon/fstrim.c
 |  | ||||||
| @@ -127,5 +127,13 @@ do_fstrim (const char *path,
 |  | ||||||
|    if (verbose) |  | ||||||
|      fprintf (stderr, "%s\n", out); |  | ||||||
|   |  | ||||||
| +  /* Sync the disks again.  In practice we always call fstrim
 |  | ||||||
| +   * expecting that afterwards the results are visible in the qemu
 |  | ||||||
| +   * devices backing the guest.  Depending on the Linux filesystem,
 |  | ||||||
| +   * fstrim may issue asynch discard requests, so it's not necessarily
 |  | ||||||
| +   * true that everything has been written out before this point.
 |  | ||||||
| +   */
 |  | ||||||
| +  sync_disks ();
 |  | ||||||
| +
 |  | ||||||
|    return 0; |  | ||||||
|  } |  | ||||||
| @ -1,127 +0,0 @@ | |||||||
| From 682765a63ec7c3140e6332f15d9833072eea05e1 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: "Richard W.M. Jones" <rjones@redhat.com> |  | ||||||
| Date: Thu, 8 May 2025 09:10:38 +0100 |  | ||||||
| Subject: [PATCH] daemon: inspect: Remove duplicate root mountpoints in |  | ||||||
|  /etc/fstab |  | ||||||
| 
 |  | ||||||
| A customer case was found where /etc/fstab contained multiple root |  | ||||||
| mountpoints, something like: |  | ||||||
| 
 |  | ||||||
|   LABEL=System / xfs ... |  | ||||||
|   LABEL=Boot /boot ext2 ... |  | ||||||
|   LABEL=System / xfs ... |  | ||||||
| 
 |  | ||||||
| This causes libguestfs and virt-v2v to fail.  Either (on RHEL 9) we |  | ||||||
| try to mount the second instance of / which gives an error.  Or (on |  | ||||||
| upstream kernels) we are able to mount the second instance but then |  | ||||||
| libguestfs gets confused when trying to unmount them. |  | ||||||
| 
 |  | ||||||
| In this case as the mounted devices are the same we can just delete |  | ||||||
| the duplicate.  It's also possible that there could be multiple |  | ||||||
| non-identical root mountpoints, in which case we have to pick one, and |  | ||||||
| this code arbitrarily picks the first[*] (but emits a warning). |  | ||||||
| 
 |  | ||||||
| We don't do anything for non-root mountpoints. |  | ||||||
| 
 |  | ||||||
| Update common submodule to add 'List.same' function from mlstdutils. |  | ||||||
| 
 |  | ||||||
| [*] Which one is "the first" depends on what version of ocaml-augeas |  | ||||||
| we are using.  ocaml-augeas version 0.6 Augeas.matches function |  | ||||||
| returns entries in reverse order (compared to augeas itself).  This is |  | ||||||
| fixed in version 0.7: |  | ||||||
| http://git.annexia.org/?p=ocaml-augeas.git;a=commitdiff;h=b703b92e3d26690aa6f7b822132049ce5435983e |  | ||||||
| 
 |  | ||||||
| Fixes: https://issues.redhat.com/browse/RHEL-90168 |  | ||||||
| (cherry picked from commit 5441d3dd0c8843897f65c8d40c82e0d204748b4e) |  | ||||||
| ---
 |  | ||||||
|  common                          |  2 +- |  | ||||||
|  daemon/inspect_fs_unix_fstab.ml | 31 +++++++++++++++++++++++++++++-- |  | ||||||
|  2 files changed, 30 insertions(+), 3 deletions(-) |  | ||||||
| 
 |  | ||||||
| Submodule common 8aed7b6a..9053edae: |  | ||||||
| diff --git a/common/mlstdutils/std_utils.ml b/common/mlstdutils/std_utils.ml
 |  | ||||||
| index 1177ff69..a0745d38 100644
 |  | ||||||
| --- a/common/mlstdutils/std_utils.ml
 |  | ||||||
| +++ b/common/mlstdutils/std_utils.ml
 |  | ||||||
| @@ -396,6 +396,18 @@ module List = struct
 |  | ||||||
|   |  | ||||||
|      let push_back_list xsp xs = xsp := !xsp @ xs |  | ||||||
|      let push_front_list xs xsp = xsp := xs @ !xsp |  | ||||||
| +
 |  | ||||||
| +    let make n x =
 |  | ||||||
| +      let rec loop acc = function
 |  | ||||||
| +        | 0 -> acc
 |  | ||||||
| +        | i when i > 0 -> loop (x :: acc) (i-1)
 |  | ||||||
| +        | _ -> invalid_arg "make"
 |  | ||||||
| +      in
 |  | ||||||
| +      loop [] n
 |  | ||||||
| +
 |  | ||||||
| +    let same = function
 |  | ||||||
| +      | [] -> true
 |  | ||||||
| +      | x :: xs -> List.for_all ((=) x) xs
 |  | ||||||
|  end |  | ||||||
|   |  | ||||||
|  module Option = struct |  | ||||||
| diff --git a/common/mlstdutils/std_utils.mli b/common/mlstdutils/std_utils.mli
 |  | ||||||
| index 6811b4bc..f5ff3470 100644
 |  | ||||||
| --- a/common/mlstdutils/std_utils.mli
 |  | ||||||
| +++ b/common/mlstdutils/std_utils.mli
 |  | ||||||
| @@ -289,6 +289,12 @@ module List : sig
 |  | ||||||
|   |  | ||||||
|          [push_front_list] is like {!push_front} above, except it prepends |  | ||||||
|          a list to the list reference. *) |  | ||||||
| +
 |  | ||||||
| +    val make : int -> 'a -> 'a list
 |  | ||||||
| +    (** [make n x] returns a list with [x] repeated [n] times. *)
 |  | ||||||
| +    val same : 'a list -> bool
 |  | ||||||
| +    (** [same xs] returns true iff the list contains only identical elements,
 |  | ||||||
| +        or is the empty list. *)
 |  | ||||||
|  end |  | ||||||
|  (** Override the List module from stdlib. *) |  | ||||||
|   |  | ||||||
| diff --git a/daemon/inspect_fs_unix_fstab.ml b/daemon/inspect_fs_unix_fstab.ml
 |  | ||||||
| index dcbdab3c..b0de55e4 100644
 |  | ||||||
| --- a/daemon/inspect_fs_unix_fstab.ml
 |  | ||||||
| +++ b/daemon/inspect_fs_unix_fstab.ml
 |  | ||||||
| @@ -53,8 +53,10 @@ and check_fstab_aug mdadm_conf root_mountable os_type aug =
 |  | ||||||
|    let md_map = if mdadm_conf then map_md_devices aug else StringMap.empty in |  | ||||||
|   |  | ||||||
|    let path = "/files/etc/fstab/*[label() != '#comment']" in |  | ||||||
| -  let entries = aug_matches_noerrors aug path in
 |  | ||||||
| -  List.filter_map (check_fstab_entry md_map root_mountable os_type aug) entries
 |  | ||||||
| +  path |>
 |  | ||||||
| +    aug_matches_noerrors aug |>
 |  | ||||||
| +    List.filter_map (check_fstab_entry md_map root_mountable os_type aug) |>
 |  | ||||||
| +    remove_duplicate_root_mountpoints
 |  | ||||||
|   |  | ||||||
|  and check_fstab_entry md_map root_mountable os_type aug entry = |  | ||||||
|    with_return (fun {return} -> |  | ||||||
| @@ -604,3 +606,28 @@ and resolve_diskbyid part default =
 |  | ||||||
|      if is_partition dev then Mountable.of_device dev |  | ||||||
|      else default |  | ||||||
|    ) |  | ||||||
| +
 |  | ||||||
| +(* Remove duplicate root mountpoints if they are identical.  If
 |  | ||||||
| + * there are multiple non-identical roots we pick the first and
 |  | ||||||
| + * emit a warning (RHEL-90168).
 |  | ||||||
| + *)
 |  | ||||||
| +and remove_duplicate_root_mountpoints (entries : fstab_entry list) =
 |  | ||||||
| +  let root_entries, non_root_entries =
 |  | ||||||
| +    List.partition (function (_, "/") -> true | _ -> false) entries in
 |  | ||||||
| +  (* If there is one root entry (the normal case) return the list unmodified. *)
 |  | ||||||
| +  if List.length root_entries <= 1 then entries
 |  | ||||||
| +  else (
 |  | ||||||
| +    (* If they are not the same, issue a warning. *)
 |  | ||||||
| +    if not (List.same root_entries) then
 |  | ||||||
| +      eprintf "check_fstab: multiple, non-identical root mountpoints found \
 |  | ||||||
| +               in the /etc/fstab of this guest, picking the first.  The \
 |  | ||||||
| +               root entries were: [%s]\n"
 |  | ||||||
| +        (String.concat "; "
 |  | ||||||
| +           (List.map (fun (mountable, mp) ->
 |  | ||||||
| +                sprintf "%s -> %s" (Mountable.to_string mountable) mp)
 |  | ||||||
| +              root_entries)
 |  | ||||||
| +        );
 |  | ||||||
| +
 |  | ||||||
| +    (* Choose the first root entry and return it. *)
 |  | ||||||
| +    List.hd root_entries :: non_root_entries
 |  | ||||||
| +  )
 |  | ||||||
| @ -8,7 +8,8 @@ list: | |||||||
| 
 | 
 | ||||||
|   http://www.redhat.com/mailman/listinfo/libguestfs |   http://www.redhat.com/mailman/listinfo/libguestfs | ||||||
| 
 | 
 | ||||||
| This package comes with a lot of help and examples to get you started. | This Red Hat Enterprise Linux package comes with a lot of help and | ||||||
|  | examples to get you started. | ||||||
| 
 | 
 | ||||||
| The first place to start are the manual pages.  Type: | The first place to start are the manual pages.  Type: | ||||||
| 
 | 
 | ||||||
| @ -19,19 +20,19 @@ The first place to start are the manual pages.  Type: | |||||||
|   man virt-cat   # and other virt-* tools |   man virt-cat   # and other virt-* tools | ||||||
| 
 | 
 | ||||||
| If you install the libguestfs-devel package, then in the | If you install the libguestfs-devel package, then in the | ||||||
| /usr/share/doc/libguestfs-devel/ directory you will find other | /usr/share/doc/libguestfs-devel/ directory you will also | ||||||
| documentation including: | find: | ||||||
| 
 | 
 | ||||||
|  - BUGS: list of open bugs in this version |  - BUGS: list of open bugs in this version | ||||||
| 
 | 
 | ||||||
|  - ChangeLog.gz: the detailed list of changes in this version |  - ChangeLog: the detailed list of changes in this version | ||||||
| 
 | 
 | ||||||
|  - HACKING: how to extend libguestfs |  - ROADMAP: the roadmap for future versions | ||||||
| 
 | 
 | ||||||
|  - TODO: ideas for extending libguestfs |  - TODO: ideas for extending libguestfs | ||||||
| 
 | 
 | ||||||
|  - *.c: example C programs using the API |  - *.c: example C programs using the API | ||||||
| 
 | 
 | ||||||
|  - *.xml.gz: example virt-inspector output (compressed) |  - *.xml: example virt-inspector output | ||||||
| 
 | 
 | ||||||
|  - virt-inspector.rng: virt-inspector RelaxNG schema |  - *.rng: virt-inspector RelaxNG schema | ||||||
|  | |||||||
| @ -6,29 +6,24 @@ set -e | |||||||
| # directory.  Use it like this: | # directory.  Use it like this: | ||||||
| #   ./copy-patches.sh | #   ./copy-patches.sh | ||||||
| 
 | 
 | ||||||
| project=libguestfs | rhel_version=8.7.0 | ||||||
| rhel_version=9.6 |  | ||||||
| 
 | 
 | ||||||
| # Check we're in the right directory. | # Check we're in the right directory. | ||||||
| if [ ! -f $project.spec ]; then | if [ ! -f libguestfs.spec ]; then | ||||||
|     echo "$0: run this from the directory containing '$project.spec'" |     echo "$0: run this from the directory containing 'libguestfs.spec'" | ||||||
|     exit 1 |     exit 1 | ||||||
| fi | fi | ||||||
| 
 | 
 | ||||||
| case `id -un` in | git_checkout=$HOME/d/libguestfs-rhel-$rhel_version | ||||||
|     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 | if [ ! -d $git_checkout ]; then | ||||||
|     echo "$0: $git_checkout does not exist" |     echo "$0: $git_checkout does not exist" | ||||||
|     echo "This script is only for use by the maintainer when preparing a" |     echo "This script is only for use by the maintainer when preparing a" | ||||||
|     echo "$project release on RHEL." |     echo "libguestfs release on RHEL." | ||||||
|     exit 1 |     exit 1 | ||||||
| fi | fi | ||||||
| 
 | 
 | ||||||
| # Get the base version of the project. | # Get the base version of libguestfs. | ||||||
| version=`grep '^Version:' $project.spec | awk '{print $2}'` | version=`grep '^Version:' libguestfs.spec | awk '{print $2}'` | ||||||
| tag="v$version" | tag="v$version" | ||||||
| 
 | 
 | ||||||
| # Remove any existing patches. | # Remove any existing patches. | ||||||
| @ -36,12 +31,7 @@ git rm -f [0-9]*.patch ||: | |||||||
| rm -f [0-9]*.patch | rm -f [0-9]*.patch | ||||||
| 
 | 
 | ||||||
| # Get the patches. | # Get the patches. | ||||||
| ( | (cd $git_checkout; rm -f [0-9]*.patch; git format-patch -N --submodule=diff $tag) | ||||||
|   cd $git_checkout |  | ||||||
|   rm -f [0-9]*.patch |  | ||||||
|   git -c core.abbrev=8 format-patch -O/dev/null --subject-prefix=PATCH -N \ |  | ||||||
|       --submodule=diff --no-signature --patience $tag |  | ||||||
| ) |  | ||||||
| mv $git_checkout/[0-9]*.patch . | mv $git_checkout/[0-9]*.patch . | ||||||
| 
 | 
 | ||||||
| # Remove any not to be applied. | # Remove any not to be applied. | ||||||
| @ -52,7 +42,7 @@ git add [0-9]*.patch | |||||||
| 
 | 
 | ||||||
| # Print out the patch lines. | # Print out the patch lines. | ||||||
| echo | echo | ||||||
| echo "--- Copy the following text into $project.spec file" | echo "--- Copy the following text into libguestfs.spec file" | ||||||
| echo | echo | ||||||
| 
 | 
 | ||||||
| echo "# Patches." | echo "# Patches." | ||||||
|  | |||||||
							
								
								
									
										17
									
								
								SOURCES/libguestfs-1.44.0.tar.gz.sig
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								SOURCES/libguestfs-1.44.0.tar.gz.sig
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,17 @@ | |||||||
|  | -----BEGIN PGP SIGNATURE----- | ||||||
|  | 
 | ||||||
|  | iQJFBAABCAAvFiEE93dPsa0HSn6Mh2fqkXOPc+G3aKAFAl/1jrcRHHJpY2hAYW5u | ||||||
|  | ZXhpYS5vcmcACgkQkXOPc+G3aKCBcQ/+JwE8JTm3PdTPGoKxCqSgAOirbqE4ZvMY | ||||||
|  | p/3y5mexagcWXx6X2Y+u6dlybS06jFR8TkbjdE3VAhhJo0C8l1vfvUTWKVDZoBhG | ||||||
|  | 3jZ6e+exff3VEUY4nFIVvYPNP+/J1BCiexMO0/2f1MDKwnJ73je9GlzwPEpdqPj/ | ||||||
|  | jSxaAy1G/rA5qV5rWQd4n5S9m8zRnf1lnM7YI7I0PunC2Wt/U6BZidL/FVVWVBxV | ||||||
|  | DGKTIy7GgWnfGWdqJ+Wi9o9QCJH/9FGTP35xonyQEM/7GI+jLz+a9g2xgvv584Ni | ||||||
|  | FF0Gqywrp5QFd13Nj3MPM7MXjGjUY5vB964k3mgE4fH91CnVvisRWfUCCo+c/9wG | ||||||
|  | odS0YTrveWJpm0oYU2tL3AjahRclskAxXEIxx9kbnWMUTrpXG0r8G4+vE+estCjb | ||||||
|  | mbyK5FQh2KASqNgmeopjK9DAEwD7SfPyHmPQ07Q76Pgl8X+FfBX2uyXBjaR5IJJJ | ||||||
|  | qVVamdVtPilqwWqQ8hGkKE0qVKqZHGCOJ8+AkQjHjUtSVegT6zHmCG/bM4im1dGV | ||||||
|  | r9fv6oQ7kWViz8mBluoETWr5sd2AfLOdLS8A42JaOnU7ASJUX/9eN0Y9u4BYC9P3 | ||||||
|  | l+QXikyq6T/4iC+tADOYGBr9uNitksLwSSUYScpnN+4AY+M+qjXTBq38MEHmwcgK | ||||||
|  | 5mwscgQefcY= | ||||||
|  | =UrAA | ||||||
|  | -----END PGP SIGNATURE----- | ||||||
| @ -1,17 +0,0 @@ | |||||||
| -----BEGIN PGP SIGNATURE----- |  | ||||||
| 
 |  | ||||||
| iQJFBAABCAAvFiEE93dPsa0HSn6Mh2fqkXOPc+G3aKAFAmcFNYwRHHJpY2hAYW5u |  | ||||||
| ZXhpYS5vcmcACgkQkXOPc+G3aKAn2xAArWoo5hKyREZW+WqEv40ZDD9jRG2WNUyl |  | ||||||
| BJcEvLEtcAySv71nftVQOhxoZhcfRbanSFKCTD0O/rzf5MjDhPIi9jbeGkFDg22c |  | ||||||
| zyuSJ4vGnkUCa1dDg5hJZdhCfe/gSb5RHR8GF+QRZDVXqCZg/PO+KEFh0112htUW |  | ||||||
| 1y6rc9oe2f5aSNO9wgsVCYLXGcZ80wT/JyXe/NhqJoZOvps4SlEFHcpoYdV0wzOG |  | ||||||
| 1UkuPy1UteDOTLHGx5JyMqR/+mzy3O59FaIU1eAXwrtlksBfzgmMyEt7ntizk3/M |  | ||||||
| qGgaE4KK3GURZUoDNc6WS856EMaoeMy6Dd6np8rMKeDn3d0PCNcrn2+7kSiNyRP0 |  | ||||||
| guM+7gwcZUnI9UOi6/vwbmmDCAgRkSPP130fKagBtK2BqQ1FyTow4mOLXkVpHrlZ |  | ||||||
| zF2lDIBs/rDC1fdDXtcsZ/N4nc2OkZwvZ+jxjhsY4xnSLaZSK+C3Le7Yqj04vOzh |  | ||||||
| KfqgqorqaEw1MnqRY6czGc5VntXsK/5f+zBeS4KGn7znJN/jVXzjFDn3o0X6R1MW |  | ||||||
| IMv2ZHk0NInGFaVHyBD7ob3vh2+hWX0QIVTouqmPRVPIbVs4hAIVHGeOkkUCO8y9 |  | ||||||
| MerGQuJSPlaegndGfRmp4R6q882QxTXRiY4tAnhdoDj5bLzss89kSKqxUHBDknZA |  | ||||||
| Fe+4R67G9zg= |  | ||||||
| =RmmC |  | ||||||
| -----END PGP SIGNATURE----- |  | ||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
		Loading…
	
		Reference in New Issue
	
	Block a user