Richard W.M. Jones
2017-Aug-03 17:13 UTC
[Libguestfs] [PATCH 0/6] tests: Fix handling of device API parameters (RHBZ#1477623).
https://bugzilla.redhat.com/show_bug.cgi?id=1477623 The first two patches are cleanups. The third patch changes the way that we handle Device and Dev_or_Path parameters so that a parameter marked as such can really only contain a block device name (and not, for instance, a chardev). Using a chardev here caused hangs in the API. The next two patches fix API usage to conform to this new stricter checking. I removed the ability to use "/dev/urandom" (and similar) non-block devices in place of block devices in such APIs as guestfs_copy_device_to_device. Last patch adds a regression test. Rich.
Richard W.M. Jones
2017-Aug-03 17:13 UTC
[Libguestfs] [PATCH 1/6] daemon: Move utility functions to a separate file.
This allows us to share certain utility functions with OCaml code. --- daemon/Makefile.am | 1 + daemon/daemon.h | 5 +- daemon/guestfsd.c | 733 +-------------------------------------------------- daemon/utils.c | 757 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 766 insertions(+), 730 deletions(-) diff --git a/daemon/Makefile.am b/daemon/Makefile.am index fc1389f67..5bfe409a4 100644 --- a/daemon/Makefile.am +++ b/daemon/Makefile.am @@ -173,6 +173,7 @@ guestfsd_SOURCES = \ truncate.c \ umask.c \ upload.c \ + utils.c \ utimens.c \ utsname.c \ uuids.c \ diff --git a/daemon/daemon.h b/daemon/daemon.h index 0f7ead258..a40dc3834 100644 --- a/daemon/daemon.h +++ b/daemon/daemon.h @@ -50,13 +50,14 @@ typedef struct { char *volume; } mountable_t; -/* guestfsd.c */ +/* utils.c */ extern int verbose; extern int enable_network; extern int autosync_umount; extern int test_mode; extern const char *sysroot; extern size_t sysroot_len; +extern dev_t root_device; extern char *sysroot_path (const char *path); extern char *sysroot_realpath (const char *path); @@ -83,7 +84,7 @@ extern char *get_random_uuid (void); extern char *make_exclude_from_file (const char *function, char *const *excludes); extern int asprintf_nowarn (char **strp, const char *fmt, ...); -/* mountable functions (in guestfsd.c) */ +/* mountable functions (in utils.c) */ extern char *mountable_to_string (const mountable_t *mountable); extern void cleanup_free_mountable (mountable_t *mountable); diff --git a/daemon/guestfsd.c b/daemon/guestfsd.c index 2ceaccbee..94b4839bd 100644 --- a/daemon/guestfsd.c +++ b/daemon/guestfsd.c @@ -18,8 +18,7 @@ /** * This is the guestfs daemon which runs inside the guestfs appliance. - * This file handles start up, connecting back to the library, and has - * several utility functions. + * This file handles start up and connecting back to the library. */ #include <config.h> @@ -32,57 +31,28 @@ #include <stdlib.h> #include <string.h> #include <unistd.h> -#include <rpc/types.h> -#include <rpc/xdr.h> -#include <getopt.h> -#include <sys/param.h> -#include <sys/types.h> -#include <sys/stat.h> #include <fcntl.h> #include <signal.h> -#include <netdb.h> -#include <sys/select.h> -#include <sys/wait.h> -#include <arpa/inet.h> -#include <netinet/in.h> +#include <getopt.h> #include <errno.h> #include <error.h> #include <assert.h> #include <termios.h> +#include <sys/types.h> +#include <sys/stat.h> #ifdef HAVE_PRINTF_H # include <printf.h> #endif -#include <augeas.h> - #include <caml/callback.h> /* for caml_startup */ -#include "sockets.h" #include "c-ctype.h" #include "ignore-value.h" -#include "error.h" +#include "sockets.h" #include "daemon.h" -#ifndef MAX -# define MAX(a,b) ((a)>(b)?(a):(b)) -#endif - -/* Not the end of the world if this open flag is not defined. */ -#ifndef O_CLOEXEC -# define O_CLOEXEC 0 -#endif - -/* If root device is an ext2 filesystem, this is the major and minor. - * This is so we can ignore this device from the point of view of the - * user, eg. in guestfs_list_devices and many other places. - */ -static dev_t root_device = 0; - -int verbose = 0; -int enable_network = 0; - static void makeraw (const char *channel, int fd); static int print_shell_quote (FILE *stream, const struct printf_info *info, const void *const *args); static int print_sysroot_shell_quote (FILE *stream, const struct printf_info *info, const void *const *args); @@ -114,16 +84,6 @@ winsock_init (void) } #endif /* !WIN32 */ -/* Location to mount root device. */ -const char *sysroot = "/sysroot"; /* No trailing slash. */ -size_t sysroot_len = 8; - -/* If set (the default), do 'umount-all' when performing autosync. */ -int autosync_umount = 1; - -/* If set, we are testing the daemon as part of the libguestfs tests. */ -int test_mode = 0; - /* Name of the virtio-serial channel. */ #define VIRTIO_SERIAL_CHANNEL "/dev/virtio-ports/org.libguestfs.channel.0" @@ -393,366 +353,6 @@ makeraw (const char *channel, int fd) } /** - * Return true iff device is the root device (and therefore should be - * ignored from the point of view of user calls). - */ -static int -is_root_device_stat (struct stat *statbuf) -{ - if (statbuf->st_rdev == root_device) return 1; - return 0; -} - -int -is_root_device (const char *device) -{ - struct stat statbuf; - - udev_settle_file (device); - - if (stat (device, &statbuf) == -1) { - perror (device); - return 0; - } - - return is_root_device_stat (&statbuf); -} - -/** - * Turn C<"/path"> into C<"/sysroot/path">. - * - * Returns C<NULL> on failure. The caller I<must> check for this and - * call S<C<reply_with_perror ("malloc")>>. The caller must also free - * the returned string. - * - * See also the custom C<%R> printf formatter which does shell quoting too. - */ -char * -sysroot_path (const char *path) -{ - char *r; - const size_t len = strlen (path) + sysroot_len + 1; - - r = malloc (len); - if (r == NULL) - return NULL; - - snprintf (r, len, "%s%s", sysroot, path); - return r; -} - -/** - * Resolve path within sysroot, calling C<sysroot_path> on the - * resolved path. - * - * Returns C<NULL> on failure. The caller I<must> check for this and - * call S<C<reply_with_perror ("malloc")>>. The caller must also free - * the returned string. - * - * See also the custom C<%R> printf formatter which does shell quoting too. - */ -char * -sysroot_realpath (const char *path) -{ - CLEANUP_FREE char *rp = NULL; - - CHROOT_IN; - rp = realpath (path, NULL); - CHROOT_OUT; - if (rp == NULL) - return NULL; - - return sysroot_path (rp); -} - -int -xwrite (int sock, const void *v_buf, size_t len) -{ - ssize_t r; - const char *buf = v_buf; - - while (len > 0) { - r = write (sock, buf, len); - if (r == -1) { - perror ("write"); - return -1; - } - buf += r; - len -= r; - } - - return 0; -} - -int -xread (int sock, void *v_buf, size_t len) -{ - int r; - char *buf = v_buf; - - while (len > 0) { - r = read (sock, buf, len); - if (r == -1) { - perror ("read"); - return -1; - } - if (r == 0) { - fprintf (stderr, "read: unexpected end of file on fd %d\n", sock); - return -1; - } - buf += r; - len -= r; - } - - return 0; -} - -int -add_string_nodup (struct stringsbuf *sb, char *str) -{ - char **new_argv; - - if (sb->size >= sb->alloc) { - sb->alloc += 64; - new_argv = realloc (sb->argv, sb->alloc * sizeof (char *)); - if (new_argv == NULL) { - reply_with_perror ("realloc"); - free (str); - return -1; - } - sb->argv = new_argv; - } - - sb->argv[sb->size] = str; - sb->size++; - - return 0; -} - -int -add_string (struct stringsbuf *sb, const char *str) -{ - char *new_str = NULL; - - if (str) { - new_str = strdup (str); - if (new_str == NULL) { - reply_with_perror ("strdup"); - return -1; - } - } - - return add_string_nodup (sb, new_str); -} - -int -add_sprintf (struct stringsbuf *sb, const char *fs, ...) -{ - va_list args; - char *str; - int r; - - va_start (args, fs); - r = vasprintf (&str, fs, args); - va_end (args); - if (r == -1) { - reply_with_perror ("vasprintf"); - return -1; - } - - return add_string_nodup (sb, str); -} - -int -end_stringsbuf (struct stringsbuf *sb) -{ - return add_string_nodup (sb, NULL); -} - -void -free_stringsbuf (struct stringsbuf *sb) -{ - if (sb->argv != NULL) - free_stringslen (sb->argv, sb->size); -} - -/* Take the ownership of the strings of the strings buffer, - * resetting it to a null buffer. - */ -char ** -take_stringsbuf (struct stringsbuf *sb) -{ - DECLARE_STRINGSBUF (null); - char **ret = sb->argv; - *sb = null; - return ret; -} - -/** - * Returns true if C<v> is a power of 2. - * - * Uses the algorithm described at - * L<http://graphics.stanford.edu/~seander/bithacks.html#DetermineIfPowerOf2> - */ -int -is_power_of_2 (unsigned long v) -{ - return v && ((v & (v - 1)) == 0); -} - -static int -compare (const void *vp1, const void *vp2) -{ - char * const *p1 = (char * const *) vp1; - char * const *p2 = (char * const *) vp2; - return strcmp (*p1, *p2); -} - -void -sort_strings (char **argv, size_t len) -{ - qsort (argv, len, sizeof (char *), compare); -} - -void -free_stringslen (char **argv, size_t len) -{ - size_t i; - - if (!argv) - return; - - for (i = 0; i < len; ++i) - free (argv[i]); - free (argv); -} - -/** - * Split an output string into a NULL-terminated list of lines, - * wrapped into a stringsbuf. - * - * Typically this is used where we have run an external command - * which has printed out a list of things, and we want to return - * an actual list. - * - * The corner cases here are quite tricky. Note in particular: - * - * =over 4 - * - * =item C<""> - * - * returns C<[]> - * - * =item C<"\n"> - * - * returns C<[""]> - * - * =item C<"a\nb"> - * - * returns C<["a"; "b"]> - * - * =item C<"a\nb\n"> - * - * returns C<["a"; "b"]> - * - * =item C<"a\nb\n\n"> - * - * returns C<["a"; "b"; ""]> - * - * =back - * - * The original string is written over and destroyed by this function - * (which is usually OK because it's the 'out' string from - * C<command*()>). You can free the original string, because - * C<add_string()> strdups the strings. - * - * C<argv> in the C<struct stringsbuf> will be C<NULL> in case of errors. - */ -struct stringsbuf -split_lines_sb (char *str) -{ - DECLARE_STRINGSBUF (lines); - DECLARE_STRINGSBUF (null); - char *p, *pend; - - if (STREQ (str, "")) { - /* No need to check the return value, as the stringsbuf will be - * returned as it is anyway. - */ - end_stringsbuf (&lines); - return lines; - } - - p = str; - while (p) { - /* Empty last line? */ - if (p[0] == '\0') - break; - - pend = strchr (p, '\n'); - if (pend) { - *pend = '\0'; - pend++; - } - - if (add_string (&lines, p) == -1) { - free_stringsbuf (&lines); - return null; - } - - p = pend; - } - - if (end_stringsbuf (&lines) == -1) { - free_stringsbuf (&lines); - return null; - } - - return lines; -} - -char ** -split_lines (char *str) -{ - struct stringsbuf sb = split_lines_sb (str); - return take_stringsbuf (&sb); -} - -char ** -empty_list (void) -{ - DECLARE_STRINGSBUF (ret); - - if (end_stringsbuf (&ret) == -1) - return NULL; - - return ret.argv; -} - -/** - * Skip leading and trailing whitespace, updating the original string - * in-place. - */ -void -trim (char *str) -{ - size_t len = strlen (str); - - while (len > 0 && c_isspace (str[len-1])) { - str[len-1] = '\0'; - len--; - } - - const char *p = str; - while (*p && c_isspace (*p)) { - p++; - len--; - } - - memmove (str, p, len+1); -} - -/** * printf helper function so we can use C<%Q> ("quoted") and C<%R> to * print shell-quoted strings. See L<guestfs-hacking(1)> for more * details. @@ -812,326 +412,3 @@ print_arginfo (const struct printf_info *info, size_t n, int *argtypes) #error "HAVE_REGISTER_PRINTF_{SPECIFIER|FUNCTION} not defined" #endif #endif - -/** - * Parse the mountable descriptor for a btrfs subvolume. Don't call - * this directly; it is only used from the stubs. - * - * A btrfs subvolume is given as: - * - * btrfsvol:/dev/sda3/root - * - * where F</dev/sda3> is a block device containing a btrfs filesystem, - * and root is the name of a subvolume on it. This function is passed - * the string following C<"btrfsvol:">. - * - * On success, C<mountable-E<gt>device> and C<mountable-E<gt>volume> - * must be freed by the caller. - */ -int -parse_btrfsvol (const char *desc_orig, mountable_t *mountable) -{ - CLEANUP_FREE char *desc = NULL; - CLEANUP_FREE char *device = NULL; - const char *volume = NULL; - char *slash; - struct stat statbuf; - - mountable->type = MOUNTABLE_BTRFSVOL; - - if (!STRPREFIX (desc_orig, "/dev/")) - return -1; - - desc = strdup (desc_orig); - if (desc == NULL) { - perror ("strdup"); - return -1; - } - - slash = desc + strlen ("/dev/") - 1; - while ((slash = strchr (slash + 1, '/'))) { - *slash = '\0'; - - free (device); - device = device_name_translation (desc); - if (!device) { - perror (desc); - continue; - } - - if (stat (device, &statbuf) == -1) { - perror (device); - return -1; - } - - if (!S_ISDIR (statbuf.st_mode) && - !is_root_device_stat (&statbuf)) { - volume = slash + 1; - break; - } - - *slash = '/'; - } - - if (!device) return -1; - - if (!volume) return -1; - - mountable->volume = strdup (volume); - if (!mountable->volume) { - perror ("strdup"); - return -1; - } - - mountable->device = device; - device = NULL; /* to stop CLEANUP_FREE from freeing it */ - - return 0; -} - -/** - * Convert a C<mountable_t> back to its string representation - * - * This function can be used in an error path, so must not call - * C<reply_with_error>. - */ -char * -mountable_to_string (const mountable_t *mountable) -{ - char *desc; - - switch (mountable->type) { - case MOUNTABLE_DEVICE: - case MOUNTABLE_PATH: - return strdup (mountable->device); - - case MOUNTABLE_BTRFSVOL: - if (asprintf (&desc, "btrfsvol:%s/%s", - mountable->device, mountable->volume) == -1) - return NULL; - return desc; - - default: - return NULL; - } -} - -#if defined(__GNUC__) && GUESTFS_GCC_VERSION >= 40800 /* gcc >= 4.8.0 */ -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wstack-usage=" -#endif - -/** - * Check program exists and is executable on C<$PATH>. - */ -int -prog_exists (const char *prog) -{ - const char *pathc = getenv ("PATH"); - - if (!pathc) - return 0; - - const size_t proglen = strlen (prog); - const char *elem; - char *saveptr; - const size_t len = strlen (pathc) + 1; - char path[len]; - strcpy (path, pathc); - - elem = strtok_r (path, ":", &saveptr); - while (elem) { - const size_t n = strlen (elem) + proglen + 2; - char testprog[n]; - - snprintf (testprog, n, "%s/%s", elem, prog); - if (access (testprog, X_OK) == 0) - return 1; - - elem = strtok_r (NULL, ":", &saveptr); - } - - /* Not found. */ - return 0; -} - -#if defined(__GNUC__) && GUESTFS_GCC_VERSION >= 40800 /* gcc >= 4.8.0 */ -#pragma GCC diagnostic pop -#endif - -/** - * Pass a template such as C<"/sysroot/XXXXXXXX.XXX">. This updates - * the template to contain a randomly named file. Any C<'X'> - * characters after the final C<'/'> in the template are replaced with - * random characters. - * - * Notes: You should probably use an 8.3 path, so it's compatible with - * all filesystems including basic FAT. Also this only substitutes - * lowercase ASCII letters and numbers, again for compatibility with - * lowest common denominator filesystems. - * - * This doesn't create a file or check whether or not the file exists - * (it would be extremely unlikely to exist as long as the RNG is - * working). - * - * If there is an error, C<-1> is returned. - */ -int -random_name (char *template) -{ - int fd; - unsigned char c; - char *p; - - fd = open ("/dev/urandom", O_RDONLY|O_CLOEXEC); - if (fd == -1) - return -1; - - p = strrchr (template, '/'); - if (p == NULL) - abort (); /* internal error - bad template */ - - while (*p) { - if (*p == 'X') { - if (read (fd, &c, 1) != 1) { - close (fd); - return -1; - } - *p = "0123456789abcdefghijklmnopqrstuvwxyz"[c % 36]; - } - - p++; - } - - close (fd); - return 0; -} - -/** - * LVM and other commands aren't synchronous, especially when udev is - * involved. eg. You can create or remove some device, but the - * C</dev> device node won't appear until some time later. This means - * that you get an error if you run one command followed by another. - * - * Use C<udevadm settle> after certain commands, but don't be too - * fussed if it fails. - */ -void -udev_settle_file (const char *file) -{ - const size_t MAX_ARGS = 64; - const char *argv[MAX_ARGS]; - CLEANUP_FREE char *err = NULL; - size_t i = 0; - int r; - - ADD_ARG (argv, i, "udevadm"); - if (verbose) - ADD_ARG (argv, i, "--debug"); - - ADD_ARG (argv, i, "settle"); - if (file) { - ADD_ARG (argv, i, "-E"); - ADD_ARG (argv, i, file); - } - ADD_ARG (argv, i, NULL); - - r = commandv (NULL, &err, argv); - if (r == -1) - fprintf (stderr, "udevadm settle: %s\n", err); -} - -void -udev_settle (void) -{ - udev_settle_file (NULL); -} - -char * -get_random_uuid (void) -{ - int r; - char *out; - CLEANUP_FREE char *err = NULL; - - r = command (&out, &err, "uuidgen", NULL); - if (r == -1) { - reply_with_error ("%s", err); - return NULL; - } - - /* caller free */ - return out; - -} - -/** - * Turn list C<excludes> into a temporary file, and return a string - * containing the temporary file name. Caller must unlink the file - * and free the string. - * - * C<function> is the function that invoked this helper, and it is - * used mainly for errors/debugging. - */ -char * -make_exclude_from_file (const char *function, char *const *excludes) -{ - size_t i; - int fd; - char template[] = "/tmp/excludesXXXXXX"; - char *ret; - - fd = mkstemp (template); - if (fd == -1) { - reply_with_perror ("mkstemp"); - return NULL; - } - - for (i = 0; excludes[i] != NULL; ++i) { - if (strchr (excludes[i], '\n')) { - reply_with_error ("%s: excludes file patterns cannot contain \\n character", - function); - goto error; - } - - if (xwrite (fd, excludes[i], strlen (excludes[i])) == -1 || - xwrite (fd, "\n", 1) == -1) { - reply_with_perror ("write"); - goto error; - } - - if (verbose) - fprintf (stderr, "%s: adding excludes pattern '%s'\n", - function, excludes[i]); - } - - if (close (fd) == -1) { - reply_with_perror ("close"); - fd = -1; - goto error; - } - fd = -1; - - ret = strdup (template); - if (ret == NULL) { - reply_with_perror ("strdup"); - goto error; - } - - return ret; - - error: - if (fd >= 0) - close (fd); - unlink (template); - return NULL; -} - -void -cleanup_free_mountable (mountable_t *mountable) -{ - if (mountable) { - free (mountable->device); - free (mountable->volume); - } -} diff --git a/daemon/utils.c b/daemon/utils.c new file mode 100644 index 000000000..6ec232252 --- /dev/null +++ b/daemon/utils.c @@ -0,0 +1,757 @@ +/* libguestfs - the guestfsd daemon + * Copyright (C) 2009-2017 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. + */ + +/** + * Miscellaneous utility functions used by the daemon. + */ + +#include <config.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <rpc/types.h> +#include <rpc/xdr.h> +#include <sys/param.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <netdb.h> +#include <sys/select.h> +#include <sys/wait.h> +#include <arpa/inet.h> +#include <netinet/in.h> +#include <errno.h> +#include <error.h> +#include <assert.h> + +#include "c-ctype.h" + +#include "daemon.h" + +#ifndef MAX +# define MAX(a,b) ((a)>(b)?(a):(b)) +#endif + +/* Not the end of the world if this open flag is not defined. */ +#ifndef O_CLOEXEC +# define O_CLOEXEC 0 +#endif + +/* If root device is an ext2 filesystem, this is the major and minor. + * This is so we can ignore this device from the point of view of the + * user, eg. in guestfs_list_devices and many other places. + */ +dev_t root_device = 0; + +int verbose = 0; +int enable_network = 0; + +/* Location to mount root device. */ +const char *sysroot = "/sysroot"; /* No trailing slash. */ +size_t sysroot_len = 8; + +/* If set (the default), do 'umount-all' when performing autosync. */ +int autosync_umount = 1; + +/* If set, we are testing the daemon as part of the libguestfs tests. */ +int test_mode = 0; + +/** + * Return true iff device is the root device (and therefore should be + * ignored from the point of view of user calls). + */ +static int +is_root_device_stat (struct stat *statbuf) +{ + if (statbuf->st_rdev == root_device) return 1; + return 0; +} + +int +is_root_device (const char *device) +{ + struct stat statbuf; + + udev_settle_file (device); + + if (stat (device, &statbuf) == -1) { + perror (device); + return 0; + } + + return is_root_device_stat (&statbuf); +} + +/** + * Turn C<"/path"> into C<"/sysroot/path">. + * + * Returns C<NULL> on failure. The caller I<must> check for this and + * call S<C<reply_with_perror ("malloc")>>. The caller must also free + * the returned string. + * + * See also the custom C<%R> printf formatter which does shell quoting too. + */ +char * +sysroot_path (const char *path) +{ + char *r; + const size_t len = strlen (path) + sysroot_len + 1; + + r = malloc (len); + if (r == NULL) + return NULL; + + snprintf (r, len, "%s%s", sysroot, path); + return r; +} + +/** + * Resolve path within sysroot, calling C<sysroot_path> on the + * resolved path. + * + * Returns C<NULL> on failure. The caller I<must> check for this and + * call S<C<reply_with_perror ("malloc")>>. The caller must also free + * the returned string. + * + * See also the custom C<%R> printf formatter which does shell quoting too. + */ +char * +sysroot_realpath (const char *path) +{ + CLEANUP_FREE char *rp = NULL; + + CHROOT_IN; + rp = realpath (path, NULL); + CHROOT_OUT; + if (rp == NULL) + return NULL; + + return sysroot_path (rp); +} + +int +xwrite (int sock, const void *v_buf, size_t len) +{ + ssize_t r; + const char *buf = v_buf; + + while (len > 0) { + r = write (sock, buf, len); + if (r == -1) { + perror ("write"); + return -1; + } + buf += r; + len -= r; + } + + return 0; +} + +int +xread (int sock, void *v_buf, size_t len) +{ + int r; + char *buf = v_buf; + + while (len > 0) { + r = read (sock, buf, len); + if (r == -1) { + perror ("read"); + return -1; + } + if (r == 0) { + fprintf (stderr, "read: unexpected end of file on fd %d\n", sock); + return -1; + } + buf += r; + len -= r; + } + + return 0; +} + +int +add_string_nodup (struct stringsbuf *sb, char *str) +{ + char **new_argv; + + if (sb->size >= sb->alloc) { + sb->alloc += 64; + new_argv = realloc (sb->argv, sb->alloc * sizeof (char *)); + if (new_argv == NULL) { + reply_with_perror ("realloc"); + free (str); + return -1; + } + sb->argv = new_argv; + } + + sb->argv[sb->size] = str; + sb->size++; + + return 0; +} + +int +add_string (struct stringsbuf *sb, const char *str) +{ + char *new_str = NULL; + + if (str) { + new_str = strdup (str); + if (new_str == NULL) { + reply_with_perror ("strdup"); + return -1; + } + } + + return add_string_nodup (sb, new_str); +} + +int +add_sprintf (struct stringsbuf *sb, const char *fs, ...) +{ + va_list args; + char *str; + int r; + + va_start (args, fs); + r = vasprintf (&str, fs, args); + va_end (args); + if (r == -1) { + reply_with_perror ("vasprintf"); + return -1; + } + + return add_string_nodup (sb, str); +} + +int +end_stringsbuf (struct stringsbuf *sb) +{ + return add_string_nodup (sb, NULL); +} + +void +free_stringsbuf (struct stringsbuf *sb) +{ + if (sb->argv != NULL) + free_stringslen (sb->argv, sb->size); +} + +/* Take the ownership of the strings of the strings buffer, + * resetting it to a null buffer. + */ +char ** +take_stringsbuf (struct stringsbuf *sb) +{ + DECLARE_STRINGSBUF (null); + char **ret = sb->argv; + *sb = null; + return ret; +} + +/** + * Returns true if C<v> is a power of 2. + * + * Uses the algorithm described at + * L<http://graphics.stanford.edu/~seander/bithacks.html#DetermineIfPowerOf2> + */ +int +is_power_of_2 (unsigned long v) +{ + return v && ((v & (v - 1)) == 0); +} + +static int +compare (const void *vp1, const void *vp2) +{ + char * const *p1 = (char * const *) vp1; + char * const *p2 = (char * const *) vp2; + return strcmp (*p1, *p2); +} + +void +sort_strings (char **argv, size_t len) +{ + qsort (argv, len, sizeof (char *), compare); +} + +void +free_stringslen (char **argv, size_t len) +{ + size_t i; + + if (!argv) + return; + + for (i = 0; i < len; ++i) + free (argv[i]); + free (argv); +} + +/** + * Split an output string into a NULL-terminated list of lines, + * wrapped into a stringsbuf. + * + * Typically this is used where we have run an external command + * which has printed out a list of things, and we want to return + * an actual list. + * + * The corner cases here are quite tricky. Note in particular: + * + * =over 4 + * + * =item C<""> + * + * returns C<[]> + * + * =item C<"\n"> + * + * returns C<[""]> + * + * =item C<"a\nb"> + * + * returns C<["a"; "b"]> + * + * =item C<"a\nb\n"> + * + * returns C<["a"; "b"]> + * + * =item C<"a\nb\n\n"> + * + * returns C<["a"; "b"; ""]> + * + * =back + * + * The original string is written over and destroyed by this function + * (which is usually OK because it's the 'out' string from + * C<command*()>). You can free the original string, because + * C<add_string()> strdups the strings. + * + * C<argv> in the C<struct stringsbuf> will be C<NULL> in case of errors. + */ +struct stringsbuf +split_lines_sb (char *str) +{ + DECLARE_STRINGSBUF (lines); + DECLARE_STRINGSBUF (null); + char *p, *pend; + + if (STREQ (str, "")) { + /* No need to check the return value, as the stringsbuf will be + * returned as it is anyway. + */ + end_stringsbuf (&lines); + return lines; + } + + p = str; + while (p) { + /* Empty last line? */ + if (p[0] == '\0') + break; + + pend = strchr (p, '\n'); + if (pend) { + *pend = '\0'; + pend++; + } + + if (add_string (&lines, p) == -1) { + free_stringsbuf (&lines); + return null; + } + + p = pend; + } + + if (end_stringsbuf (&lines) == -1) { + free_stringsbuf (&lines); + return null; + } + + return lines; +} + +char ** +split_lines (char *str) +{ + struct stringsbuf sb = split_lines_sb (str); + return take_stringsbuf (&sb); +} + +char ** +empty_list (void) +{ + DECLARE_STRINGSBUF (ret); + + if (end_stringsbuf (&ret) == -1) + return NULL; + + return ret.argv; +} + +/** + * Skip leading and trailing whitespace, updating the original string + * in-place. + */ +void +trim (char *str) +{ + size_t len = strlen (str); + + while (len > 0 && c_isspace (str[len-1])) { + str[len-1] = '\0'; + len--; + } + + const char *p = str; + while (*p && c_isspace (*p)) { + p++; + len--; + } + + memmove (str, p, len+1); +} + +/** + * Parse the mountable descriptor for a btrfs subvolume. Don't call + * this directly; it is only used from the stubs. + * + * A btrfs subvolume is given as: + * + * btrfsvol:/dev/sda3/root + * + * where F</dev/sda3> is a block device containing a btrfs filesystem, + * and root is the name of a subvolume on it. This function is passed + * the string following C<"btrfsvol:">. + * + * On success, C<mountable-E<gt>device> and C<mountable-E<gt>volume> + * must be freed by the caller. + */ +int +parse_btrfsvol (const char *desc_orig, mountable_t *mountable) +{ + CLEANUP_FREE char *desc = NULL; + CLEANUP_FREE char *device = NULL; + const char *volume = NULL; + char *slash; + struct stat statbuf; + + mountable->type = MOUNTABLE_BTRFSVOL; + + if (!STRPREFIX (desc_orig, "/dev/")) + return -1; + + desc = strdup (desc_orig); + if (desc == NULL) { + perror ("strdup"); + return -1; + } + + slash = desc + strlen ("/dev/") - 1; + while ((slash = strchr (slash + 1, '/'))) { + *slash = '\0'; + + free (device); + device = device_name_translation (desc); + if (!device) { + perror (desc); + continue; + } + + if (stat (device, &statbuf) == -1) { + perror (device); + return -1; + } + + if (!S_ISDIR (statbuf.st_mode) && + !is_root_device_stat (&statbuf)) { + volume = slash + 1; + break; + } + + *slash = '/'; + } + + if (!device) return -1; + + if (!volume) return -1; + + mountable->volume = strdup (volume); + if (!mountable->volume) { + perror ("strdup"); + return -1; + } + + mountable->device = device; + device = NULL; /* to stop CLEANUP_FREE from freeing it */ + + return 0; +} + +/** + * Convert a C<mountable_t> back to its string representation + * + * This function can be used in an error path, so must not call + * C<reply_with_error>. + */ +char * +mountable_to_string (const mountable_t *mountable) +{ + char *desc; + + switch (mountable->type) { + case MOUNTABLE_DEVICE: + case MOUNTABLE_PATH: + return strdup (mountable->device); + + case MOUNTABLE_BTRFSVOL: + if (asprintf (&desc, "btrfsvol:%s/%s", + mountable->device, mountable->volume) == -1) + return NULL; + return desc; + + default: + return NULL; + } +} + +#if defined(__GNUC__) && GUESTFS_GCC_VERSION >= 40800 /* gcc >= 4.8.0 */ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstack-usage=" +#endif + +/** + * Check program exists and is executable on C<$PATH>. + */ +int +prog_exists (const char *prog) +{ + const char *pathc = getenv ("PATH"); + + if (!pathc) + return 0; + + const size_t proglen = strlen (prog); + const char *elem; + char *saveptr; + const size_t len = strlen (pathc) + 1; + char path[len]; + strcpy (path, pathc); + + elem = strtok_r (path, ":", &saveptr); + while (elem) { + const size_t n = strlen (elem) + proglen + 2; + char testprog[n]; + + snprintf (testprog, n, "%s/%s", elem, prog); + if (access (testprog, X_OK) == 0) + return 1; + + elem = strtok_r (NULL, ":", &saveptr); + } + + /* Not found. */ + return 0; +} + +#if defined(__GNUC__) && GUESTFS_GCC_VERSION >= 40800 /* gcc >= 4.8.0 */ +#pragma GCC diagnostic pop +#endif + +/** + * Pass a template such as C<"/sysroot/XXXXXXXX.XXX">. This updates + * the template to contain a randomly named file. Any C<'X'> + * characters after the final C<'/'> in the template are replaced with + * random characters. + * + * Notes: You should probably use an 8.3 path, so it's compatible with + * all filesystems including basic FAT. Also this only substitutes + * lowercase ASCII letters and numbers, again for compatibility with + * lowest common denominator filesystems. + * + * This doesn't create a file or check whether or not the file exists + * (it would be extremely unlikely to exist as long as the RNG is + * working). + * + * If there is an error, C<-1> is returned. + */ +int +random_name (char *template) +{ + int fd; + unsigned char c; + char *p; + + fd = open ("/dev/urandom", O_RDONLY|O_CLOEXEC); + if (fd == -1) + return -1; + + p = strrchr (template, '/'); + if (p == NULL) + abort (); /* internal error - bad template */ + + while (*p) { + if (*p == 'X') { + if (read (fd, &c, 1) != 1) { + close (fd); + return -1; + } + *p = "0123456789abcdefghijklmnopqrstuvwxyz"[c % 36]; + } + + p++; + } + + close (fd); + return 0; +} + +/** + * LVM and other commands aren't synchronous, especially when udev is + * involved. eg. You can create or remove some device, but the + * C</dev> device node won't appear until some time later. This means + * that you get an error if you run one command followed by another. + * + * Use C<udevadm settle> after certain commands, but don't be too + * fussed if it fails. + */ +void +udev_settle_file (const char *file) +{ + const size_t MAX_ARGS = 64; + const char *argv[MAX_ARGS]; + CLEANUP_FREE char *err = NULL; + size_t i = 0; + int r; + + ADD_ARG (argv, i, "udevadm"); + if (verbose) + ADD_ARG (argv, i, "--debug"); + + ADD_ARG (argv, i, "settle"); + if (file) { + ADD_ARG (argv, i, "-E"); + ADD_ARG (argv, i, file); + } + ADD_ARG (argv, i, NULL); + + r = commandv (NULL, &err, argv); + if (r == -1) + fprintf (stderr, "udevadm settle: %s\n", err); +} + +void +udev_settle (void) +{ + udev_settle_file (NULL); +} + +char * +get_random_uuid (void) +{ + int r; + char *out; + CLEANUP_FREE char *err = NULL; + + r = command (&out, &err, "uuidgen", NULL); + if (r == -1) { + reply_with_error ("%s", err); + return NULL; + } + + /* caller free */ + return out; + +} + +/** + * Turn list C<excludes> into a temporary file, and return a string + * containing the temporary file name. Caller must unlink the file + * and free the string. + * + * C<function> is the function that invoked this helper, and it is + * used mainly for errors/debugging. + */ +char * +make_exclude_from_file (const char *function, char *const *excludes) +{ + size_t i; + int fd; + char template[] = "/tmp/excludesXXXXXX"; + char *ret; + + fd = mkstemp (template); + if (fd == -1) { + reply_with_perror ("mkstemp"); + return NULL; + } + + for (i = 0; excludes[i] != NULL; ++i) { + if (strchr (excludes[i], '\n')) { + reply_with_error ("%s: excludes file patterns cannot contain \\n character", + function); + goto error; + } + + if (xwrite (fd, excludes[i], strlen (excludes[i])) == -1 || + xwrite (fd, "\n", 1) == -1) { + reply_with_perror ("write"); + goto error; + } + + if (verbose) + fprintf (stderr, "%s: adding excludes pattern '%s'\n", + function, excludes[i]); + } + + if (close (fd) == -1) { + reply_with_perror ("close"); + fd = -1; + goto error; + } + fd = -1; + + ret = strdup (template); + if (ret == NULL) { + reply_with_perror ("strdup"); + goto error; + } + + return ret; + + error: + if (fd >= 0) + close (fd); + unlink (template); + return NULL; +} + +void +cleanup_free_mountable (mountable_t *mountable) +{ + if (mountable) { + free (mountable->device); + free (mountable->volume); + } +} -- 2.13.1
Richard W.M. Jones
2017-Aug-03 17:13 UTC
[Libguestfs] [PATCH 2/6] daemon: Deduplicate some utility functions.
The following functions were previously reimplemented in OCaml. This commit replaces them with calls to the C functions: - is_root_device - prog_exists - udev_settle plus the internal get_verbose_flag function. However note that we cannot do this for every utility function. In particular the C function must not call any reply* functions. --- daemon/Makefile.am | 25 ++++++++++--- daemon/daemon-c.c | 7 ---- daemon/daemon-c.h | 1 - daemon/daemon-utils-tests-stubs.c | 32 +++++++++++++++++ daemon/daemon.ml | 5 +-- daemon/dummy.c | 2 -- daemon/utils-c.c | 75 +++++++++++++++++++++++++++++++++++++++ daemon/utils.ml | 39 +++----------------- daemon/utils.mli | 7 ++-- docs/C_SOURCE_FILES | 4 ++- 10 files changed, 139 insertions(+), 58 deletions(-) diff --git a/daemon/Makefile.am b/daemon/Makefile.am index 5bfe409a4..63b28f52d 100644 --- a/daemon/Makefile.am +++ b/daemon/Makefile.am @@ -174,6 +174,7 @@ guestfsd_SOURCES = \ umask.c \ upload.c \ utils.c \ + utils-c.c \ utimens.c \ utsname.c \ uuids.c \ @@ -297,7 +298,8 @@ OCAMLPACKAGES = \ -I $(top_srcdir)/common/mlutils \ -I $(top_builddir)/common/utils/.libs \ -I $(top_srcdir)/common/mlpcre \ - -I $(top_builddir)/common/mlpcre/.libs + -I $(top_builddir)/common/mlpcre/.libs \ + -I $(top_builddir)/gnulib/lib/.libs OCAMLFLAGS = $(OCAML_FLAGS) $(OCAML_WARN_FLAGS) @@ -350,12 +352,25 @@ TESTS = \ check-valgrind: $(MAKE) VG="@VG@" check -daemon_utils_tests_SOURCES = dummy.c +daemon_utils_tests_SOURCES = \ + command.c \ + daemon-utils-tests-stubs.c \ + utils.c \ + utils-c.c daemon_utils_tests_CPPFLAGS = \ -I. \ -I$(top_builddir) \ -I$(shell $(OCAMLC) -where) \ - -I$(top_srcdir)/lib + -I$(top_srcdir)/gnulib/lib \ + -I$(top_builddir)/gnulib/lib \ + -I$(top_srcdir)/common/errnostring \ + -I$(top_builddir)/common/errnostring \ + -I$(top_srcdir)/common/protocol \ + -I$(top_builddir)/common/protocol \ + -I$(top_srcdir)/common/utils \ + -I$(top_builddir)/common/utils \ + -I$(top_srcdir)/lib \ + -I$(top_builddir)/lib daemon_utils_tests_BOBJECTS = \ utils.cmo \ daemon_utils_tests.cmo @@ -377,7 +392,9 @@ daemon_utils_tests_DEPENDENCIES = \ $(daemon_utils_tests_THEOBJECTS) \ $(top_srcdir)/ocaml-link.sh daemon_utils_tests_LINK = \ - $(top_srcdir)/ocaml-link.sh -- \ + $(top_srcdir)/ocaml-link.sh \ + -cclib '-lutils -lgnu' \ + -- \ $(OCAMLFIND) $(BEST) $(OCAMLFLAGS) $(OCAMLLINKFLAGS) \ $(OCAMLPACKAGES) \ $(daemon_utils_tests_THEOBJECTS) -o $@ diff --git a/daemon/daemon-c.c b/daemon/daemon-c.c index 3ecaed4ca..3bfa06393 100644 --- a/daemon/daemon-c.c +++ b/daemon/daemon-c.c @@ -76,13 +76,6 @@ guestfs_int_daemon_exn_to_reply_with_error (const char *func, value exn) func, exn_name); } -/* NB: This is a "noalloc" call. */ -value -guestfs_int_daemon_get_verbose_flag (value unitv) -{ - return Val_bool (verbose); -} - /* Implement String (Mountable, _) parameter. */ value guestfs_int_daemon_copy_mountable (const mountable_t *mountable) diff --git a/daemon/daemon-c.h b/daemon/daemon-c.h index 1b9f102ff..1fcfd707c 100644 --- a/daemon/daemon-c.h +++ b/daemon/daemon-c.h @@ -27,7 +27,6 @@ #include <caml/mlvalues.h> -extern value guestfs_int_daemon_get_verbose_flag (value unitv); extern void guestfs_int_daemon_exn_to_reply_with_error (const char *func, value exn); extern value guestfs_int_daemon_copy_mountable (const mountable_t *mountable); extern char **guestfs_int_daemon_return_string_list (value retv); diff --git a/daemon/daemon-utils-tests-stubs.c b/daemon/daemon-utils-tests-stubs.c new file mode 100644 index 000000000..47329a976 --- /dev/null +++ b/daemon/daemon-utils-tests-stubs.c @@ -0,0 +1,32 @@ +/* guestfsd + * Copyright (C) 2017 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 "daemon.h" + +/* This stubs out some functions that we want to link to the unit + * tests, but don't want to actually pull in plus dependencies. + */ + +char *device_name_translation (const char *device) { abort (); } +void reply_with_error_errno (int err, const char *fs, ...) { abort (); } +void reply_with_perror_errno (int err, const char *fs, ...) { abort (); } diff --git a/daemon/daemon.ml b/daemon/daemon.ml index bf486344f..1f8a6d87d 100644 --- a/daemon/daemon.ml +++ b/daemon/daemon.ml @@ -18,9 +18,6 @@ open Printf -external get_verbose_flag : unit -> bool - "guestfs_int_daemon_get_verbose_flag" "noalloc" - (* When guestfsd starts up, early on (after parsing the command line * but not much else), it calls 'caml_startup' which runs all * initialization code in the OCaml modules, including this one. @@ -32,7 +29,7 @@ let () (* Connect the guestfsd [-v] (verbose) flag into 'verbose ()' * used in OCaml code to print debugging messages. *) - if get_verbose_flag () then ( + if Utils.get_verbose_flag () then ( Std_utils.set_verbose (); eprintf "OCaml daemon loaded\n%!" ); diff --git a/daemon/dummy.c b/daemon/dummy.c deleted file mode 100644 index ebab6198c..000000000 --- a/daemon/dummy.c +++ /dev/null @@ -1,2 +0,0 @@ -/* Dummy source, to be used for OCaml-based tools with no C sources. */ -enum { foo = 1 }; diff --git a/daemon/utils-c.c b/daemon/utils-c.c new file mode 100644 index 000000000..22b0d57c6 --- /dev/null +++ b/daemon/utils-c.c @@ -0,0 +1,75 @@ +/* guestfsd + * Copyright (C) 2017 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. + */ + +/** + * Bindings for utility functions. + * + * Note that functions called from OCaml code B<must never> call + * any of the C<reply*> functions. + */ + +#include <config.h> + +#include <stdio.h> +#include <stdlib.h> + +#include <caml/alloc.h> +#include <caml/mlvalues.h> +#include <caml/memory.h> +#include <caml/unixsupport.h> + +#include "daemon.h" + +#pragma GCC diagnostic ignored "-Wmissing-prototypes" + +/* NB: This is a "noalloc" call. */ +value +guestfs_int_daemon_get_verbose_flag (value unitv) +{ + return Val_bool (verbose); +} + +/* NB: This is a "noalloc" call. */ +value +guestfs_int_daemon_is_root_device (value device) +{ + return Val_bool (is_root_device (String_val (device))); +} + +/* NB: This is a "noalloc" call. */ +value +guestfs_int_daemon_prog_exists (value prog) +{ + return Val_bool (prog_exists (String_val (prog))); +} + +/* NB: This is a "noalloc" call. */ +value +guestfs_int_daemon_udev_settle (value optfilenamev, value unitv) +{ + const char *file; + + if (optfilenamev == Val_int (0)) + file = NULL; + else + file = String_val (Field (optfilenamev, 0)); + + udev_settle_file (file); + + return Val_unit; +} diff --git a/daemon/utils.ml b/daemon/utils.ml index b459a2314..9e9e68ab4 100644 --- a/daemon/utils.ml +++ b/daemon/utils.ml @@ -21,9 +21,10 @@ open Printf open Std_utils -let prog_exists prog - try ignore (which prog); true - with Executable_not_found _ -> false +external get_verbose_flag : unit -> bool = "guestfs_int_daemon_get_verbose_flag" "noalloc" +external is_root_device : string -> bool = "guestfs_int_daemon_is_root_device" "noalloc" +external prog_exists : string -> bool = "guestfs_int_daemon_prog_exists" "noalloc" +external udev_settle : ?filename:string -> unit -> unit = "guestfs_int_daemon_udev_settle" "noalloc" let commandr ?(fold_stdout_on_stderr = false) prog args if verbose () then @@ -99,38 +100,6 @@ let command ?fold_stdout_on_stderr prog args failwithf "%s exited with status %d: %s" prog r stderr; stdout -let udev_settle ?filename () - let args = ref [] in - if verbose () then - push_back args "--debug"; - push_back args "settle"; - (match filename with - | None -> () - | Some filename -> - push_back args "-E"; - push_back args filename - ); - let args = !args in - let r, _, err = commandr "udevadm" args in - if r <> 0 then - eprintf "udevadm settle: %s\n" err - -let root_device = lazy ((stat "/").st_dev) - -let is_root_device_stat statbuf - statbuf.st_rdev = Lazy.force root_device - -let is_root_device device - udev_settle ~filename:device (); - try - let statbuf = stat device in - is_root_device_stat statbuf - with - Unix_error (err, func, arg) -> - eprintf "is_root_device: %s: %s: %s: %s\n" - device func arg (error_message err); - false - (* XXX This function is copied from C, but is misconceived. It * cannot by design work for devices like /dev/md0. It would be * better if it checked for the existence of devices and partitions diff --git a/daemon/utils.mli b/daemon/utils.mli index 16569f018..8807b864b 100644 --- a/daemon/utils.mli +++ b/daemon/utils.mli @@ -37,10 +37,6 @@ val udev_settle : ?filename:string -> unit -> unit val is_root_device : string -> bool (** Return true if this is the root (appliance) device. *) -val is_root_device_stat : Unix.stats -> bool -(** As for {!is_root_device} but operates on a statbuf instead of - a device name. *) - val split_device_partition : string -> string * int (** Split a device name like [/dev/sda1] into a device name and partition number, eg. ["sda", 1]. @@ -85,3 +81,6 @@ val commandr : ?fold_stdout_on_stderr:bool -> string -> string list -> (int * st val is_small_file : string -> bool (** Return true if the path is a small regular file. *) + +(**/**) +val get_verbose_flag : unit -> bool diff --git a/docs/C_SOURCE_FILES b/docs/C_SOURCE_FILES index e47469a6a..d02c0bcf7 100644 --- a/docs/C_SOURCE_FILES +++ b/docs/C_SOURCE_FILES @@ -85,6 +85,7 @@ daemon/cpio.c daemon/cpmv.c daemon/daemon-c.c daemon/daemon-c.h +daemon/daemon-utils-tests-stubs.c daemon/daemon.h daemon/dd.c daemon/debug-bmap.c @@ -97,7 +98,6 @@ daemon/dispatch.c daemon/dmesg.c daemon/dropcaches.c daemon/du.c -daemon/dummy.c daemon/echo-daemon.c daemon/ext2.c daemon/fallocate.c @@ -180,6 +180,8 @@ daemon/truncate.c daemon/tsk.c daemon/umask.c daemon/upload.c +daemon/utils-c.c +daemon/utils.c daemon/utimens.c daemon/utsname.c daemon/uuids.c -- 2.13.1
Richard W.M. Jones
2017-Aug-03 17:13 UTC
[Libguestfs] [PATCH 3/6] daemon: Refine check for Device and Dev_or_Path parameters (RHBZ#1477623).
For Device parameters we expect a block device name. However we were only testing for "/dev/..." and so chardevs (from the appliance) could be passed here, resulting in strange effects. This adds a function is_device_parameter which tests for a valid block device name. For Dev_or_Path parameters much the same, except we can also use the is_device_parameter function elsewhere in the daemon to distinguish if we were called with a device or path parameter. Previously we used a simple test if the path begins with "/dev/...". Reported by Mathieu Tarral. --- daemon/daemon.h | 1 + daemon/dd.c | 8 +++--- daemon/ext2.c | 4 +-- daemon/file.ml | 2 +- daemon/mount.c | 2 +- daemon/stubs-macros.h | 11 ++------ daemon/upload.c | 6 ++-- daemon/utils-c.c | 7 +++++ daemon/utils.c | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++ daemon/utils.ml | 1 + daemon/utils.mli | 4 +++ daemon/xfs.c | 4 +-- 12 files changed, 107 insertions(+), 21 deletions(-) diff --git a/daemon/daemon.h b/daemon/daemon.h index a40dc3834..02ae34a6f 100644 --- a/daemon/daemon.h +++ b/daemon/daemon.h @@ -62,6 +62,7 @@ extern dev_t root_device; extern char *sysroot_path (const char *path); extern char *sysroot_realpath (const char *path); extern int is_root_device (const char *device); +extern int is_device_parameter (const char *device); extern int xwrite (int sock, const void *buf, size_t len) __attribute__((__warn_unused_result__)); extern int xread (int sock, void *buf, size_t len) diff --git a/daemon/dd.c b/daemon/dd.c index 15f3f7a6c..0b61c87d8 100644 --- a/daemon/dd.c +++ b/daemon/dd.c @@ -35,7 +35,7 @@ do_dd (const char *src, const char *dest) CLEANUP_FREE char *err = NULL; int r; - src_is_dev = STRPREFIX (src, "/dev/"); + src_is_dev = is_device_parameter (src); if (src_is_dev) r = asprintf (&if_arg, "if=%s", src); @@ -46,7 +46,7 @@ do_dd (const char *src, const char *dest) return -1; } - dest_is_dev = STRPREFIX (dest, "/dev/"); + dest_is_dev = is_device_parameter (dest); if (dest_is_dev) r = asprintf (&of_arg, "of=%s", dest); @@ -71,7 +71,7 @@ do_copy_size (const char *src, const char *dest, int64_t ssize) { int src_fd, dest_fd; - if (STRPREFIX (src, "/dev/")) + if (is_device_parameter (src)) src_fd = open (src, O_RDONLY | O_CLOEXEC); else { CLEANUP_FREE char *buf = sysroot_path (src); @@ -86,7 +86,7 @@ do_copy_size (const char *src, const char *dest, int64_t ssize) return -1; } - if (STRPREFIX (dest, "/dev/")) + if (is_device_parameter (dest)) dest_fd = open (dest, O_WRONLY | O_CLOEXEC); else { CLEANUP_FREE char *buf = sysroot_path (dest); diff --git a/daemon/ext2.c b/daemon/ext2.c index 0c776b6d1..3d16af08e 100644 --- a/daemon/ext2.c +++ b/daemon/ext2.c @@ -1049,7 +1049,7 @@ do_mke2fs (const char *device, /* 0 */ * have to do it manually here, but note that LABEL=.. and * UUID=.. are valid strings which do not require translation. */ - if (STRPREFIX (journaldevice, "/dev/")) { + if (is_device_parameter (journaldevice)) { if (is_root_device (journaldevice)) { reply_with_error ("%s: device not found", journaldevice); return -1; @@ -1068,7 +1068,7 @@ do_mke2fs (const char *device, /* 0 */ sprintf (journaldevice_s, "device=%s", journaldevice_translated); } - else { + else /* XXX check only UUID= or LABEL= should be used here */ { journaldevice_s = malloc (strlen (journaldevice) + 8); if (!journaldevice_s) { reply_with_perror ("malloc"); diff --git a/daemon/file.ml b/daemon/file.ml index b45bd9019..e2c9a0e38 100644 --- a/daemon/file.ml +++ b/daemon/file.ml @@ -25,7 +25,7 @@ open Utils (* This runs the [file] command. *) let file path - let is_dev = String.is_prefix path "/dev/" in + let is_dev = is_device_parameter path in (* For non-dev, check this is a regular file, else just return the * file type as a string (RHBZ#582484). diff --git a/daemon/mount.c b/daemon/mount.c index bf58bd527..61ce64449 100644 --- a/daemon/mount.c +++ b/daemon/mount.c @@ -120,7 +120,7 @@ do_umount (const char *pathordevice, const char *argv[MAX_ARGS]; size_t i = 0; - is_dev = STREQLEN (pathordevice, "/dev/", 5); + is_dev = is_device_parameter (pathordevice); buf = is_dev ? strdup (pathordevice) : sysroot_path (pathordevice); if (buf == NULL) { diff --git a/daemon/stubs-macros.h b/daemon/stubs-macros.h index e9da16227..2a90938c6 100644 --- a/daemon/stubs-macros.h +++ b/daemon/stubs-macros.h @@ -30,16 +30,11 @@ */ #define RESOLVE_DEVICE(path,path_out,is_filein) \ do { \ - if (STRNEQLEN ((path), "/dev/", 5)) { \ + if (!is_device_parameter ((path))) { \ if (is_filein) cancel_receive (); \ reply_with_error ("%s: %s: expecting a device name", __func__, (path)); \ return; \ } \ - if (is_root_device (path)) { \ - if (is_filein) cancel_receive (); \ - reply_with_error ("%s: %s: device not found", __func__, path); \ - return; \ - } \ (path_out) = device_name_translation ((path)); \ if ((path_out) == NULL) { \ const int err = errno; \ @@ -86,7 +81,7 @@ */ #define REQUIRE_ROOT_OR_RESOLVE_DEVICE(path,path_out,is_filein) \ do { \ - if (STREQLEN ((path), "/dev/", 5)) \ + if (is_device_parameter ((path))) \ RESOLVE_DEVICE ((path), (path_out), (is_filein)); \ else { \ NEED_ROOT ((is_filein), return); \ @@ -105,7 +100,7 @@ */ #define REQUIRE_ROOT_OR_RESOLVE_MOUNTABLE(string, mountable, is_filein) \ do { \ - if (STRPREFIX ((string), "/dev/") || (string)[0] != '/') { \ + if (is_device_parameter ((string)) || (string)[0] != '/') { \ RESOLVE_MOUNTABLE ((string), (mountable), (is_filein)); \ } \ else { \ diff --git a/daemon/upload.c b/daemon/upload.c index 8aaeb2570..9ae1df559 100644 --- a/daemon/upload.c +++ b/daemon/upload.c @@ -94,7 +94,7 @@ upload (const char *filename, int flags, int64_t offset) { int err, is_dev, fd; - is_dev = STRPREFIX (filename, "/dev/"); + is_dev = is_device_parameter (filename); if (!is_dev) CHROOT_IN; fd = open (filename, flags, 0666); @@ -170,7 +170,7 @@ do_download (const char *filename) return -1; } - is_dev = STRPREFIX (filename, "/dev/"); + is_dev = is_device_parameter (filename); if (!is_dev) CHROOT_IN; fd = open (filename, O_RDONLY|O_CLOEXEC); @@ -264,7 +264,7 @@ do_download_offset (const char *filename, int64_t offset, int64_t size) } uint64_t usize = (uint64_t) size; - is_dev = STRPREFIX (filename, "/dev/"); + is_dev = is_device_parameter (filename); if (!is_dev) CHROOT_IN; fd = open (filename, O_RDONLY|O_CLOEXEC); diff --git a/daemon/utils-c.c b/daemon/utils-c.c index 22b0d57c6..d3a8f330b 100644 --- a/daemon/utils-c.c +++ b/daemon/utils-c.c @@ -46,6 +46,13 @@ guestfs_int_daemon_get_verbose_flag (value unitv) /* NB: This is a "noalloc" call. */ value +guestfs_int_daemon_is_device_parameter (value device) +{ + return Val_bool (is_device_parameter (String_val (device))); +} + +/* NB: This is a "noalloc" call. */ +value guestfs_int_daemon_is_root_device (value device) { return Val_bool (is_root_device (String_val (device))); diff --git a/daemon/utils.c b/daemon/utils.c index 6ec232252..6d6aad218 100644 --- a/daemon/utils.c +++ b/daemon/utils.c @@ -37,6 +37,8 @@ #include <sys/wait.h> #include <arpa/inet.h> #include <netinet/in.h> +#include <sys/ioctl.h> +#include <linux/fs.h> #include <errno.h> #include <error.h> #include <assert.h> @@ -100,6 +102,82 @@ is_root_device (const char *device) } /** + * Parameters marked as C<Device>, C<Dev_or_Path>, etc can be passed a + * block device name. This function tests if the parameter is a block + * device name. + * + * It can also be used in daemon code to test if the string passed + * as a C<Dev_or_Path> parameter is a device or path. + */ +int +is_device_parameter (const char *device) +{ + struct stat statbuf; + int fd; + uint64_t n; + + udev_settle_file (device); + + if (!STRPREFIX (device, "/dev/")) + return 0; + + /* Allow any /dev/sd device, so device name translation works. */ + if (STRPREFIX (device, "/dev/sd")) + return 1; + + /* Is it a block device in the appliance? */ + if (stat (device, &statbuf) == -1) { + if (verbose) + fprintf (stderr, "%s: stat: %s: %m\n", "is_device_parameter", device); + return 0; + } + + fprintf (stderr, "mode = %o\n", statbuf.st_mode); + if (S_ISBLK (statbuf.st_mode)) + /* continue */; + else if (S_ISDIR (statbuf.st_mode)) { + fprintf (stderr, "S_ISDIR\n"); + /* The lvremove API allows you to remove all LVs by pointing to + * the VG directory. This was misconceived in the extreme, but + * here we are. XXX + */ + return strlen (device) > 5; + } + else + return 0; + + /* Reject the root (appliance) device. */ + if (is_root_device_stat (&statbuf)) { + if (verbose) + fprintf (stderr, "%s: %s is the root device\n", + "is_device_parameter", device); + return 0; + } + + /* Only now is it safe to try opening the device since chardev devices + * might block when opened. + * + * Only disk-like things should support BLKGETSIZE64. + */ + fd = open (device, O_RDONLY|O_CLOEXEC); + if (fd == -1) { + if (verbose) + fprintf (stderr, "%s: open: %s: %m\n", "is_device_parameter", device); + return 0; + } + if (ioctl (fd, BLKGETSIZE64, &n) == -1) { + if (verbose) + fprintf (stderr, "%s: ioctl BLKGETSIZE64: %s: %m\n", + "is_device_parameter", device); + close (fd); + return 0; + } + close (fd); + + return 1; +} + +/** * Turn C<"/path"> into C<"/sysroot/path">. * * Returns C<NULL> on failure. The caller I<must> check for this and diff --git a/daemon/utils.ml b/daemon/utils.ml index 9e9e68ab4..20a82e212 100644 --- a/daemon/utils.ml +++ b/daemon/utils.ml @@ -22,6 +22,7 @@ open Printf open Std_utils external get_verbose_flag : unit -> bool = "guestfs_int_daemon_get_verbose_flag" "noalloc" +external is_device_parameter : string -> bool = "guestfs_int_daemon_is_device_parameter" "noalloc" external is_root_device : string -> bool = "guestfs_int_daemon_is_root_device" "noalloc" external prog_exists : string -> bool = "guestfs_int_daemon_prog_exists" "noalloc" external udev_settle : ?filename:string -> unit -> unit = "guestfs_int_daemon_udev_settle" "noalloc" diff --git a/daemon/utils.mli b/daemon/utils.mli index 8807b864b..9f9f91a49 100644 --- a/daemon/utils.mli +++ b/daemon/utils.mli @@ -37,6 +37,10 @@ val udev_settle : ?filename:string -> unit -> unit val is_root_device : string -> bool (** Return true if this is the root (appliance) device. *) +val is_device_parameter : string -> bool +(** Use this function to tell the difference between a device + or path for [Dev_or_Path] parameters. *) + val split_device_partition : string -> string * int (** Split a device name like [/dev/sda1] into a device name and partition number, eg. ["sda", 1]. diff --git a/daemon/xfs.c b/daemon/xfs.c index 84e361569..3707f56d9 100644 --- a/daemon/xfs.c +++ b/daemon/xfs.c @@ -327,7 +327,7 @@ do_xfs_info (const char *pathordevice) CLEANUP_FREE_STRING_LIST char **lines = NULL; int is_dev; - is_dev = STREQLEN (pathordevice, "/dev/", 5); + is_dev = is_device_parameter (pathordevice); buf = is_dev ? strdup (pathordevice) : sysroot_path (pathordevice); if (buf == NULL) { @@ -631,7 +631,7 @@ do_xfs_repair (const char *device, ADD_ARG (argv, i, rtdev); } - is_device = STREQLEN (device, "/dev/", 5); + is_device = is_device_parameter (device); if (!is_device) { buf = sysroot_path (device); if (buf == NULL) { -- 2.13.1
Richard W.M. Jones
2017-Aug-03 17:13 UTC
[Libguestfs] [PATCH 4/6] tests: discard: Remove dubious use of "/dev/urandom" as a Device parameter.
This API docs don't state that this is permitted. --- tests/discard/test-blkdiscard.pl | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/tests/discard/test-blkdiscard.pl b/tests/discard/test-blkdiscard.pl index 9f136ecd9..4505e678b 100755 --- a/tests/discard/test-blkdiscard.pl +++ b/tests/discard/test-blkdiscard.pl @@ -93,9 +93,21 @@ unless ($g->feature_available (["blkdiscard"])) { my $orig_size = (stat ($disk))[12]; print "original size:\t$orig_size (blocks)\n"; -# Fill the block device with some random data. - -$g->copy_device_to_device ("/dev/urandom", "/dev/sda", size => $size); +# Fill the block device with non-zero data. + +my $i = $size; +my $offset = 0; +while ($i > 0) { + my $data; + if ($i >= 1024*1024) { + $data = "*" x (1024*1024) + } else { + $data = "*" x $i + } + $g->pwrite_device ("/dev/sda", $data, $offset); + $offset += length $data; + $i -= length $data; +} $g->sync (); my $full_size = (stat ($disk))[12]; -- 2.13.1
Richard W.M. Jones
2017-Aug-03 17:13 UTC
[Libguestfs] [PATCH 5/6] daemon: lvm: Pass device parameter of lvm_canonical_lv_name as PlainString.
All sorts of strings might be passed here hoping to make them canonical LV names. We cannot be sure that the strings passed will be devices which exist in the appliance. --- daemon/lvm.c | 13 ++++++++++++- generator/actions_core.ml | 2 +- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/daemon/lvm.c b/daemon/lvm.c index 4026c4f92..9d91b6459 100644 --- a/daemon/lvm.c +++ b/daemon/lvm.c @@ -723,7 +723,18 @@ char * do_lvm_canonical_lv_name (const char *device) { char *canonical; - int r = lv_canonical (device, &canonical); + int r; + + /* The device parameter is passed as PlainString because we can't + * really be sure that the device name will exist (especially for + * "/dev/mapper/..." names). Do some sanity checking on it here. + */ + if (!STRPREFIX (device, "/dev/")) { + reply_with_error ("%s: not a device name", device); + return NULL; + } + + r = lv_canonical (device, &canonical); if (r == -1) return NULL; diff --git a/generator/actions_core.ml b/generator/actions_core.ml index fba6c39ca..81cb99ea8 100644 --- a/generator/actions_core.ml +++ b/generator/actions_core.ml @@ -6002,7 +6002,7 @@ See also C<guestfs_pread>." }; { defaults with name = "lvm_canonical_lv_name"; added = (1, 5, 24); - style = RString (RDevice, "lv"), [String (Device, "lvname")], []; + style = RString (RDevice, "lv"), [String (PlainString, "lvname")], []; tests = [ InitBasicFSonLVM, IfAvailable "lvm2", TestResultString ( [["lvm_canonical_lv_name"; "/dev/mapper/VG-LV"]], "/dev/VG/LV"), []; -- 2.13.1
Richard W.M. Jones
2017-Aug-03 17:13 UTC
[Libguestfs] [PATCH 6/6] tests: Add a regression test for RHBZ#1477623.
--- tests/regressions/Makefile.am | 2 ++ tests/regressions/rhbz1477623.sh | 49 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/tests/regressions/Makefile.am b/tests/regressions/Makefile.am index aef6982d1..25833824c 100644 --- a/tests/regressions/Makefile.am +++ b/tests/regressions/Makefile.am @@ -50,6 +50,7 @@ EXTRA_DIST = \ rhbz1285847.sh \ rhbz1370424.sh \ rhbz1370424.xml \ + rhbz1477623.sh \ test-noexec-stack.pl TESTS = \ @@ -80,6 +81,7 @@ TESTS = \ rhbz1232192.sh \ rhbz1285847.sh \ rhbz1370424.sh \ + rhbz1477623.sh \ test-big-heap \ test-noexec-stack.pl \ $(SLOW_TESTS) diff --git a/tests/regressions/rhbz1477623.sh b/tests/regressions/rhbz1477623.sh new file mode 100755 index 000000000..9892a4d07 --- /dev/null +++ b/tests/regressions/rhbz1477623.sh @@ -0,0 +1,49 @@ +#!/bin/bash - +# libguestfs +# Copyright (C) 2017 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=1477623 +# Check that the 'file' API doesn't break on some chardevs. + +set -e + +$TEST_FUNCTIONS +skip_if_skipped +skip_unless_phony_guest fedora.img + +d=rhbz1477623.img +rm -f $d + +guestfish -- \ + disk-create $d qcow2 -1 \ + backingfile:$top_builddir/test-data/phony-guests/fedora.img \ + backingformat:raw + +guestfish -a $d -i <<EOF + mkdir /dev + mknod-c 0777 5 1 /dev/console + mknod-c 0777 10 175 /dev/agpgart + + # This used to hang. + file /dev/console + + # This used to print "No such file or directory" + file /dev/agpgart +EOF + +rm $d -- 2.13.1
Richard Jones
2017-Aug-03 19:41 UTC
[Libguestfs] check-release success (was: Re: [PATCH 6/6] tests: Add a regression test for RHBZ#1477623.)
]: Entering directory '/var/tmp/tmpFKNosu/libguestfs/erlang' make[3]: Entering directory '/var/tmp/tmpFKNosu/libguestfs/erlang' PASS: tests/010-load.erl PASS: run-bindtests PASS: tests/030-config.erl PASS: tests/070-optargs.erl PASS: tests/060-readdir.erl PASS: tests/050-lvcreate.erl ===========================================================================Testsuite summary for libguestfs 1.37.20 ===========================================================================# TOTAL: 6 # PASS: 6 # SKIP: 0 # XFAIL: 0 # FAIL: 0 # XPASS: 0 # ERROR: 0 ===========================================================================make[3]: Leaving directory '/var/tmp/tmpFKNosu/libguestfs/erlang' make[2]: Leaving directory '/var/tmp/tmpFKNosu/libguestfs/erlang' make[1]: Leaving directory '/var/tmp/tmpFKNosu/libguestfs/erlang' Making check in erlang/examples make[1]: Entering directory '/var/tmp/tmpFKNosu/libguestfs/erlang/examples' make[1]: Nothing to be done for 'check'. make[1]: Leaving directory '/var/tmp/tmpFKNosu/libguestfs/erlang/examples' Making check in lua make[1]: Entering directory '/var/tmp/tmpFKNosu/libguestfs/lua' ln -sf .libs/libluaguestfs.so guestfs.so make check-TESTS make[2]: Entering directory '/var/tmp/tmpFKNosu/libguestfs/lua' make[3]: Entering directory '/var/tmp/tmpFKNosu/libguestfs/lua' PASS: tests/010-load.lua PASS: run-bindtests PASS: tests/015-globals.lua PASS: tests/020-create.lua PASS: tests/025-create-flags.lua PASS: tests/027-create-multiple.lua PASS: tests/030-config.lua PASS: tests/070-optargs.lua PASS: tests/400-events.lua PASS: tests/900-errors.lua PASS: tests/060-readdir.lua PASS: tests/050-lvcreate.lua PASS: tests/400-progress.lua ===========================================================================Testsuite summary for libguestfs 1.37.20 ===========================================================================# TOTAL: 13 # PASS: 13 # SKIP: 0 # XFAIL: 0 # FAIL: 0 # XPASS: 0 # ERROR: 0 ===========================================================================make[3]: Leaving directory '/var/tmp/tmpFKNosu/libguestfs/lua' make[2]: Leaving directory '/var/tmp/tmpFKNosu/libguestfs/lua' make[1]: Leaving directory '/var/tmp/tmpFKNosu/libguestfs/lua' Making check in lua/examples make[1]: Entering directory '/var/tmp/tmpFKNosu/libguestfs/lua/examples' make[1]: Nothing to be done for 'check'. make[1]: Leaving directory '/var/tmp/tmpFKNosu/libguestfs/lua/examples' Making check in gobject make[1]: Entering directory '/var/tmp/tmpFKNosu/libguestfs/gobject' make check-am make[2]: Entering directory '/var/tmp/tmpFKNosu/libguestfs/gobject' make check-TESTS make[3]: Entering directory '/var/tmp/tmpFKNosu/libguestfs/gobject' make[4]: Entering directory '/var/tmp/tmpFKNosu/libguestfs/gobject' SKIP: run-tests PASS: run-tests-retvalues PASS: run-live-tests ===========================================================================Testsuite summary for libguestfs 1.37.20 ===========================================================================# TOTAL: 3 # PASS: 2 # SKIP: 1 # XFAIL: 0 # FAIL: 0 # XPASS: 0 # ERROR: 0 ===========================================================================make[4]: Leaving directory '/var/tmp/tmpFKNosu/libguestfs/gobject' make[3]: Leaving directory '/var/tmp/tmpFKNosu/libguestfs/gobject' make[2]: Leaving directory '/var/tmp/tmpFKNosu/libguestfs/gobject' make[1]: Leaving directory '/var/tmp/tmpFKNosu/libguestfs/gobject' Making check in csharp make[1]: Entering directory '/var/tmp/tmpFKNosu/libguestfs/csharp' make[1]: Nothing to be done for 'check'. make[1]: Leaving directory '/var/tmp/tmpFKNosu/libguestfs/csharp' Making check in common/mlprogress make[1]: Entering directory '/var/tmp/tmpFKNosu/libguestfs/common/mlprogress' make[1]: Nothing to be done for 'check'. make[1]: Leaving directory '/var/tmp/tmpFKNosu/libguestfs/common/mlprogress' Making check in common/mlvisit make[1]: Entering directory '/var/tmp/tmpFKNosu/libguestfs/common/mlvisit' make visit_tests make[2]: Entering directory '/var/tmp/tmpFKNosu/libguestfs/common/mlvisit' CC dummy.o OCAMLOPT visit_tests.cmx File "visit_tests.ml", line 111, characters 25-31: Warning 52: Code should not depend on the actual values of this constructor's arguments. They are only for information and may change in future versions. (See manual section 8.5) File "visit_tests.ml", line 119, characters 16-23: Warning 52: Code should not depend on the actual values of this constructor's arguments. They are only for information and may change in future versions. (See manual section 8.5) GEN visit_tests make[2]: Leaving directory '/var/tmp/tmpFKNosu/libguestfs/common/mlvisit' make check-TESTS make[2]: Entering directory '/var/tmp/tmpFKNosu/libguestfs/common/mlvisit' make[3]: Entering directory '/var/tmp/tmpFKNosu/libguestfs/common/mlvisit' PASS: visit_tests ===========================================================================Testsuite summary for libguestfs 1.37.20 ===========================================================================# TOTAL: 1 # PASS: 1 # SKIP: 0 # XFAIL: 0 # FAIL: 0 # XPASS: 0 # ERROR: 0 ===========================================================================make[3]: Leaving directory '/var/tmp/tmpFKNosu/libguestfs/common/mlvisit' make[2]: Leaving directory '/var/tmp/tmpFKNosu/libguestfs/common/mlvisit' make[1]: Leaving directory '/var/tmp/tmpFKNosu/libguestfs/common/mlvisit' Making check in common/mlxml make[1]: Entering directory '/var/tmp/tmpFKNosu/libguestfs/common/mlxml' make[1]: Nothing to be done for 'check'. make[1]: Leaving directory '/var/tmp/tmpFKNosu/libguestfs/common/mlxml' Making check in mllib make[1]: Entering directory '/var/tmp/tmpFKNosu/libguestfs/mllib' make getopt_tests common_utils_tests JSON_tests make[2]: Entering directory '/var/tmp/tmpFKNosu/libguestfs/mllib' CC getopt_tests-dummy.o OCAMLOPT getopt_tests.cmx CC common_utils_tests-dummy.o OCAMLOPT common_utils_tests.cmx CC dummy.o OCAMLOPT JSON_tests.cmx GEN getopt_tests GEN JSON_tests GEN common_utils_tests make[2]: Leaving directory '/var/tmp/tmpFKNosu/libguestfs/mllib' make check-TESTS make[2]: Entering directory '/var/tmp/tmpFKNosu/libguestfs/mllib' make[3]: Entering directory '/var/tmp/tmpFKNosu/libguestfs/mllib' PASS: common_utils_tests PASS: JSON_tests PASS: test-getopt.sh ===========================================================================Testsuite summary for libguestfs 1.37.20 ===========================================================================# TOTAL: 3 # PASS: 3 # SKIP: 0 # XFAIL: 0 # FAIL: 0 # XPASS: 0 # ERROR: 0 ===========================================================================make[3]: Leaving directory '/var/tmp/tmpFKNosu/libguestfs/mllib' make[2]: Leaving directory '/var/tmp/tmpFKNosu/libguestfs/mllib' make[1]: Leaving directory '/var/tmp/tmpFKNosu/libguestfs/mllib' Making check in customize make[1]: Entering directory '/var/tmp/tmpFKNosu/libguestfs/customize' make check-TESTS make[2]: Entering directory '/var/tmp/tmpFKNosu/libguestfs/customize' make[3]: Entering directory '/var/tmp/tmpFKNosu/libguestfs/customize' rm -f test-firstboot-rhel-4.9.sh test-firstboot-rhel-4.9.sh-t rm -f test-firstboot-rhel-5.11.sh test-firstboot-rhel-5.11.sh-t rm -f test-firstboot-rhel-6.8.sh test-firstboot-rhel-6.8.sh-t f=`echo "test-firstboot-rhel-4.9.sh" | /usr/bin/sed 's/test-firstboot-\(.*\).sh/\1/'`; \ echo 'script=test-firstboot-rhel-4.9.sh exec $srcdir/test-firstboot.sh' "$f" > test-firstboot-rhel-4.9.sh-t f=`echo "test-firstboot-rhel-5.11.sh" | /usr/bin/sed 's/test-firstboot-\(.*\).sh/\1/'`; \ echo 'script=test-firstboot-rhel-5.11.sh exec $srcdir/test-firstboot.sh' "$f" > test-firstboot-rhel-5.11.sh-t f=`echo "test-firstboot-rhel-6.8.sh" | /usr/bin/sed 's/test-firstboot-\(.*\).sh/\1/'`; \ echo 'script=test-firstboot-rhel-6.8.sh exec $srcdir/test-firstboot.sh' "$f" > test-firstboot-rhel-6.8.sh-t chmod 0755 test-firstboot-rhel-4.9.sh-t chmod 0755 test-firstboot-rhel-5.11.sh-t chmod 0755 test-firstboot-rhel-6.8.sh-t mv test-firstboot-rhel-4.9.sh-t test-firstboot-rhel-4.9.sh mv test-firstboot-rhel-5.11.sh-t test-firstboot-rhel-5.11.sh mv test-firstboot-rhel-6.8.sh-t test-firstboot-rhel-6.8.sh rm -f test-firstboot-rhel-7.2.sh test-firstboot-rhel-7.2.sh-t f=`echo "test-firstboot-rhel-7.2.sh" | /usr/bin/sed 's/test-firstboot-\(.*\).sh/\1/'`; \ echo 'script=test-firstboot-rhel-7.2.sh exec $srcdir/test-firstboot.sh' "$f" > test-firstboot-rhel-7.2.sh-t rm -f test-firstboot-debian-6.sh test-firstboot-debian-6.sh-t rm -f test-firstboot-debian-7.sh test-firstboot-debian-7.sh-t f=`echo "test-firstboot-debian-6.sh" | /usr/bin/sed 's/test-firstboot-\(.*\).sh/\1/'`; \ echo 'script=test-firstboot-debian-6.sh exec $srcdir/test-firstboot.sh' "$f" > test-firstboot-debian-6.sh-t f=`echo "test-firstboot-debian-7.sh" | /usr/bin/sed 's/test-firstboot-\(.*\).sh/\1/'`; \ echo 'script=test-firstboot-debian-7.sh exec $srcdir/test-firstboot.sh' "$f" > test-firstboot-debian-7.sh-t chmod 0755 test-firstboot-rhel-7.2.sh-t chmod 0755 test-firstboot-debian-6.sh-t mv test-firstboot-rhel-7.2.sh-t test-firstboot-rhel-7.2.sh mv test-firstboot-debian-6.sh-t test-firstboot-debian-6.sh rm -f test-firstboot-debian-8.sh test-firstboot-debian-8.sh-t chmod 0755 test-firstboot-debian-7.sh-t f=`echo "test-firstboot-debian-8.sh" | /usr/bin/sed 's/test-firstboot-\(.*\).sh/\1/'`; \ echo 'script=test-firstboot-debian-8.sh exec $srcdir/test-firstboot.sh' "$f" > test-firstboot-debian-8.sh-t mv test-firstboot-debian-7.sh-t test-firstboot-debian-7.sh rm -f test-firstboot-fedora-25.sh test-firstboot-fedora-25.sh-t rm -f test-firstboot-fedora-26.sh test-firstboot-fedora-26.sh-t f=`echo "test-firstboot-fedora-25.sh" | /usr/bin/sed 's/test-firstboot-\(.*\).sh/\1/'`; \ echo 'script=test-firstboot-fedora-25.sh exec $srcdir/test-firstboot.sh' "$f" > test-firstboot-fedora-25.sh-t f=`echo "test-firstboot-fedora-26.sh" | /usr/bin/sed 's/test-firstboot-\(.*\).sh/\1/'`; \ echo 'script=test-firstboot-fedora-26.sh exec $srcdir/test-firstboot.sh' "$f" > test-firstboot-fedora-26.sh-t chmod 0755 test-firstboot-debian-8.sh-t chmod 0755 test-firstboot-fedora-25.sh-t mv test-firstboot-debian-8.sh-t test-firstboot-debian-8.sh mv test-firstboot-fedora-25.sh-t test-firstboot-fedora-25.sh rm -f test-firstboot-ubuntu-10.04.sh test-firstboot-ubuntu-10.04.sh-t chmod 0755 test-firstboot-fedora-26.sh-t f=`echo "test-firstboot-ubuntu-10.04.sh" | /usr/bin/sed 's/test-firstboot-\(.*\).sh/\1/'`; \ echo 'script=test-firstboot-ubuntu-10.04.sh exec $srcdir/test-firstboot.sh' "$f" > test-firstboot-ubuntu-10.04.sh-t mv test-firstboot-fedora-26.sh-t test-firstboot-fedora-26.sh rm -f test-firstboot-ubuntu-12.04.sh test-firstboot-ubuntu-12.04.sh-t rm -f test-firstboot-ubuntu-14.04.sh test-firstboot-ubuntu-14.04.sh-t chmod 0755 test-firstboot-ubuntu-10.04.sh-t f=`echo "test-firstboot-ubuntu-12.04.sh" | /usr/bin/sed 's/test-firstboot-\(.*\).sh/\1/'`; \ echo 'script=test-firstboot-ubuntu-12.04.sh exec $srcdir/test-firstboot.sh' "$f" > test-firstboot-ubuntu-12.04.sh-t f=`echo "test-firstboot-ubuntu-14.04.sh" | /usr/bin/sed 's/test-firstboot-\(.*\).sh/\1/'`; \ echo 'script=test-firstboot-ubuntu-14.04.sh exec $srcdir/test-firstboot.sh' "$f" > test-firstboot-ubuntu-14.04.sh-t mv test-firstboot-ubuntu-10.04.sh-t test-firstboot-ubuntu-10.04.sh rm -f test-firstboot-ubuntu-16.04.sh test-firstboot-ubuntu-16.04.sh-t f=`echo "test-firstboot-ubuntu-16.04.sh" | /usr/bin/sed 's/test-firstboot-\(.*\).sh/\1/'`; \ echo 'script=test-firstboot-ubuntu-16.04.sh exec $srcdir/test-firstboot.sh' "$f" > test-firstboot-ubuntu-16.04.sh-t chmod 0755 test-firstboot-ubuntu-14.04.sh-t mv test-firstboot-ubuntu-14.04.sh-t test-firstboot-ubuntu-14.04.sh chmod 0755 test-firstboot-ubuntu-12.04.sh-t chmod 0755 test-firstboot-ubuntu-16.04.sh-t mv test-firstboot-ubuntu-12.04.sh-t test-firstboot-ubuntu-12.04.sh mv test-firstboot-ubuntu-16.04.sh-t test-firstboot-ubuntu-16.04.sh rm -f test-password-centos-7.2.sh test-password-centos-7.2.sh-t rm -f test-password-debian-6.sh test-password-debian-6.sh-t f=`echo "test-password-centos-7.2.sh" | /usr/bin/sed 's/test-password-\(.*\).sh/\1/'`; \ echo 'script=test-password-centos-7.2.sh exec $srcdir/test-password.pl' "$f" > test-password-centos-7.2.sh-t f=`echo "test-password-debian-6.sh" | /usr/bin/sed 's/test-password-\(.*\).sh/\1/'`; \ echo 'script=test-password-debian-6.sh exec $srcdir/test-password.pl' "$f" > test-password-debian-6.sh-t rm -f test-password-debian-7.sh test-password-debian-7.sh-t chmod 0755 test-password-centos-7.2.sh-t chmod 0755 test-password-debian-6.sh-t f=`echo "test-password-debian-7.sh" | /usr/bin/sed 's/test-password-\(.*\).sh/\1/'`; \ echo 'script=test-password-debian-7.sh exec $srcdir/test-password.pl' "$f" > test-password-debian-7.sh-t mv test-password-centos-7.2.sh-t test-password-centos-7.2.sh mv test-password-debian-6.sh-t test-password-debian-6.sh rm -f test-password-debian-8.sh test-password-debian-8.sh-t rm -f test-password-fedora-25.sh test-password-fedora-25.sh-t f=`echo "test-password-debian-8.sh" | /usr/bin/sed 's/test-password-\(.*\).sh/\1/'`; \ echo 'script=test-password-debian-8.sh exec $srcdir/test-password.pl' "$f" > test-password-debian-8.sh-t f=`echo "test-password-fedora-25.sh" | /usr/bin/sed 's/test-password-\(.*\).sh/\1/'`; \ echo 'script=test-password-fedora-25.sh exec $srcdir/test-password.pl' "$f" > test-password-fedora-25.sh-t chmod 0755 test-password-debian-7.sh-t mv test-password-debian-7.sh-t test-password-debian-7.sh chmod 0755 test-password-debian-8.sh-t rm -f test-password-rhel-3.9.sh test-password-rhel-3.9.sh-t mv test-password-debian-8.sh-t test-password-debian-8.sh chmod 0755 test-password-fedora-25.sh-t f=`echo "test-password-rhel-3.9.sh" | /usr/bin/sed 's/test-password-\(.*\).sh/\1/'`; \ echo 'script=test-password-rhel-3.9.sh exec $srcdir/test-password.pl' "$f" > test-password-rhel-3.9.sh-t mv test-password-fedora-25.sh-t test-password-fedora-25.sh rm -f test-password-rhel-4.9.sh test-password-rhel-4.9.sh-t rm -f test-password-rhel-5.11.sh test-password-rhel-5.11.sh-t f=`echo "test-password-rhel-4.9.sh" | /usr/bin/sed 's/test-password-\(.*\).sh/\1/'`; \ echo 'script=test-password-rhel-4.9.sh exec $srcdir/test-password.pl' "$f" > test-password-rhel-4.9.sh-t f=`echo "test-password-rhel-5.11.sh" | /usr/bin/sed 's/test-password-\(.*\).sh/\1/'`; \ echo 'script=test-password-rhel-5.11.sh exec $srcdir/test-password.pl' "$f" > test-password-rhel-5.11.sh-t chmod 0755 test-password-rhel-5.11.sh-t chmod 0755 test-password-rhel-3.9.sh-t mv test-password-rhel-5.11.sh-t test-password-rhel-5.11.sh chmod 0755 test-password-rhel-4.9.sh-t mv test-password-rhel-3.9.sh-t test-password-rhel-3.9.sh mv test-password-rhel-4.9.sh-t test-password-rhel-4.9.sh rm -f test-password-rhel-6.9.sh test-password-rhel-6.9.sh-t rm -f test-password-rhel-7.2.sh test-password-rhel-7.2.sh-t f=`echo "test-password-rhel-6.9.sh" | /usr/bin/sed 's/test-password-\(.*\).sh/\1/'`; \ echo 'script=test-password-rhel-6.9.sh exec $srcdir/test-password.pl' "$f" > test-password-rhel-6.9.sh-t f=`echo "test-password-rhel-7.2.sh" | /usr/bin/sed 's/test-password-\(.*\).sh/\1/'`; \ echo 'script=test-password-rhel-7.2.sh exec $srcdir/test-password.pl' "$f" > test-password-rhel-7.2.sh-t rm -f test-password-ubuntu-10.04.sh test-password-ubuntu-10.04.sh-t f=`echo "test-password-ubuntu-10.04.sh" | /usr/bin/sed 's/test-password-\(.*\).sh/\1/'`; \ echo 'script=test-password-ubuntu-10.04.sh exec $srcdir/test-password.pl' "$f" > test-password-ubuntu-10.04.sh-t chmod 0755 test-password-rhel-7.2.sh-t mv test-password-rhel-7.2.sh-t test-password-rhel-7.2.sh rm -f test-password-ubuntu-12.04.sh test-password-ubuntu-12.04.sh-t f=`echo "test-password-ubuntu-12.04.sh" | /usr/bin/sed 's/test-password-\(.*\).sh/\1/'`; \ echo 'script=test-password-ubuntu-12.04.sh exec $srcdir/test-password.pl' "$f" > test-password-ubuntu-12.04.sh-t chmod 0755 test-password-rhel-6.9.sh-t mv test-password-rhel-6.9.sh-t test-password-rhel-6.9.sh rm -f test-password-ubuntu-14.04.sh test-password-ubuntu-14.04.sh-t f=`echo "test-password-ubuntu-14.04.sh" | /usr/bin/sed 's/test-password-\(.*\).sh/\1/'`; \ echo 'script=test-password-ubuntu-14.04.sh exec $srcdir/test-password.pl' "$f" > test-password-ubuntu-14.04.sh-t chmod 0755 test-password-ubuntu-14.04.sh-t mv test-password-ubuntu-14.04.sh-t test-password-ubuntu-14.04.sh rm -f test-password-ubuntu-16.04.sh test-password-ubuntu-16.04.sh-t f=`echo "test-password-ubuntu-16.04.sh" | /usr/bin/sed 's/test-password-\(.*\).sh/\1/'`; \ echo 'script=test-password-ubuntu-16.04.sh exec $srcdir/test-password.pl' "$f" > test-password-ubuntu-16.04.sh-t chmod 0755 test-password-ubuntu-10.04.sh-t chmod 0755 test-password-ubuntu-12.04.sh-t chmod 0755 test-password-ubuntu-16.04.sh-t mv test-password-ubuntu-10.04.sh-t test-password-ubuntu-10.04.sh mv test-password-ubuntu-12.04.sh-t test-password-ubuntu-12.04.sh mv test-password-ubuntu-16.04.sh-t test-password-ubuntu-16.04.sh rm -f test-settings-rhel-4.9.sh test-settings-rhel-4.9.sh-t rm -f test-settings-rhel-5.11.sh test-settings-rhel-5.11.sh-t f=`echo "test-settings-rhel-4.9.sh" | /usr/bin/sed 's/test-settings-\(.*\).sh/\1/'`; \ echo 'script=test-settings-rhel-4.9.sh exec $srcdir/test-settings.sh' "$f" > test-settings-rhel-4.9.sh-t f=`echo "test-settings-rhel-5.11.sh" | /usr/bin/sed 's/test-settings-\(.*\).sh/\1/'`; \ echo 'script=test-settings-rhel-5.11.sh exec $srcdir/test-settings.sh' "$f" > test-settings-rhel-5.11.sh-t rm -f test-settings-rhel-6.8.sh test-settings-rhel-6.8.sh-t f=`echo "test-settings-rhel-6.8.sh" | /usr/bin/sed 's/test-settings-\(.*\).sh/\1/'`; \ echo 'script=test-settings-rhel-6.8.sh exec $srcdir/test-settings.sh' "$f" > test-settings-rhel-6.8.sh-t chmod 0755 test-settings-rhel-4.9.sh-t mv test-settings-rhel-4.9.sh-t test-settings-rhel-4.9.sh chmod 0755 test-settings-rhel-5.11.sh-t chmod 0755 test-settings-rhel-6.8.sh-t mv test-settings-rhel-5.11.sh-t test-settings-rhel-5.11.sh mv test-settings-rhel-6.8.sh-t test-settings-rhel-6.8.sh rm -f test-settings-rhel-7.2.sh test-settings-rhel-7.2.sh-t rm -f test-settings-debian-6.sh test-settings-debian-6.sh-t f=`echo "test-settings-rhel-7.2.sh" | /usr/bin/sed 's/test-settings-\(.*\).sh/\1/'`; \ echo 'script=test-settings-rhel-7.2.sh exec $srcdir/test-settings.sh' "$f" > test-settings-rhel-7.2.sh-t f=`echo "test-settings-debian-6.sh" | /usr/bin/sed 's/test-settings-\(.*\).sh/\1/'`; \ echo 'script=test-settings-debian-6.sh exec $srcdir/test-settings.sh' "$f" > test-settings-debian-6.sh-t rm -f test-settings-debian-7.sh test-settings-debian-7.sh-t f=`echo "test-settings-debian-7.sh" | /usr/bin/sed 's/test-settings-\(.*\).sh/\1/'`; \ echo 'script=test-settings-debian-7.sh exec $srcdir/test-settings.sh' "$f" > test-settings-debian-7.sh-t chmod 0755 test-settings-rhel-7.2.sh-t chmod 0755 test-settings-debian-6.sh-t mv test-settings-rhel-7.2.sh-t test-settings-rhel-7.2.sh mv test-settings-debian-6.sh-t test-settings-debian-6.sh chmod 0755 test-settings-debian-7.sh-t rm -f test-settings-debian-8.sh test-settings-debian-8.sh-t mv test-settings-debian-7.sh-t test-settings-debian-7.sh f=`echo "test-settings-debian-8.sh" | /usr/bin/sed 's/test-settings-\(.*\).sh/\1/'`; \ echo 'script=test-settings-debian-8.sh exec $srcdir/test-settings.sh' "$f" > test-settings-debian-8.sh-t rm -f test-settings-fedora-25.sh test-settings-fedora-25.sh-t rm -f test-settings-ubuntu-10.04.sh test-settings-ubuntu-10.04.sh-t f=`echo "test-settings-fedora-25.sh" | /usr/bin/sed 's/test-settings-\(.*\).sh/\1/'`; \ echo 'script=test-settings-fedora-25.sh exec $srcdir/test-settings.sh' "$f" > test-settings-fedora-25.sh-t f=`echo "test-settings-ubuntu-10.04.sh" | /usr/bin/sed 's/test-settings-\(.*\).sh/\1/'`; \ echo 'script=test-settings-ubuntu-10.04.sh exec $srcdir/test-settings.sh' "$f" > test-settings-ubuntu-10.04.sh-t chmod 0755 test-settings-debian-8.sh-t mv test-settings-debian-8.sh-t test-settings-debian-8.sh chmod 0755 test-settings-ubuntu-10.04.sh-t chmod 0755 test-settings-fedora-25.sh-t mv test-settings-ubuntu-10.04.sh-t test-settings-ubuntu-10.04.sh mv test-settings-fedora-25.sh-t test-settings-fedora-25.sh rm -f test-settings-ubuntu-12.04.sh test-settings-ubuntu-12.04.sh-t rm -f test-settings-ubuntu-14.04.sh test-settings-ubuntu-14.04.sh-t rm -f test-settings-ubuntu-16.04.sh test-settings-ubuntu-16.04.sh-t f=`echo "test-settings-ubuntu-12.04.sh" | /usr/bin/sed 's/test-settings-\(.*\).sh/\1/'`; \ echo 'script=test-settings-ubuntu-12.04.sh exec $srcdir/test-settings.sh' "$f" > test-settings-ubuntu-12.04.sh-t f=`echo "test-settings-ubuntu-14.04.sh" | /usr/bin/sed 's/test-settings-\(.*\).sh/\1/'`; \ echo 'script=test-settings-ubuntu-14.04.sh exec $srcdir/test-settings.sh' "$f" > test-settings-ubuntu-14.04.sh-t f=`echo "test-settings-ubuntu-16.04.sh" | /usr/bin/sed 's/test-settings-\(.*\).sh/\1/'`; \ echo 'script=test-settings-ubuntu-16.04.sh exec $srcdir/test-settings.sh' "$f" > test-settings-ubuntu-16.04.sh-t chmod 0755 test-settings-ubuntu-12.04.sh-t mv test-settings-ubuntu-12.04.sh-t test-settings-ubuntu-12.04.sh chmod 0755 test-settings-ubuntu-16.04.sh-t mv test-settings-ubuntu-16.04.sh-t test-settings-ubuntu-16.04.sh chmod 0755 test-settings-ubuntu-14.04.sh-t mv test-settings-ubuntu-14.04.sh-t test-settings-ubuntu-14.04.sh PASS: test-virt-customize-docs.sh SKIP: test-firstboot-rhel-6.8.sh SKIP: test-firstboot-rhel-4.9.sh SKIP: test-firstboot-rhel-5.11.sh SKIP: test-firstboot-rhel-7.2.sh SKIP: test-firstboot-debian-6.sh SKIP: test-firstboot-debian-8.sh SKIP: test-firstboot-debian-7.sh SKIP: test-firstboot-fedora-25.sh SKIP: test-firstboot-fedora-26.sh SKIP: test-firstboot-ubuntu-12.04.sh SKIP: test-firstboot-ubuntu-10.04.sh SKIP: test-firstboot-ubuntu-16.04.sh SKIP: test-firstboot-ubuntu-14.04.sh SKIP: test-password-centos-7.2.sh SKIP: test-password-debian-6.sh SKIP: test-password-debian-8.sh SKIP: test-password-debian-7.sh SKIP: test-password-fedora-25.sh SKIP: test-password-rhel-3.9.sh SKIP: test-password-rhel-5.11.sh SKIP: test-password-rhel-4.9.sh SKIP: test-password-rhel-7.2.sh SKIP: test-password-rhel-6.9.sh SKIP: test-password-ubuntu-10.04.sh SKIP: test-password-ubuntu-16.04.sh SKIP: test-password-ubuntu-14.04.sh SKIP: test-password-ubuntu-12.04.sh SKIP: test-settings-rhel-4.9.sh SKIP: test-settings-rhel-5.11.sh SKIP: test-settings-rhel-6.8.sh SKIP: test-settings-rhel-7.2.sh SKIP: test-settings-debian-6.sh SKIP: test-settings-debian-8.sh SKIP: test-settings-debian-7.sh SKIP: test-settings-fedora-25.sh SKIP: test-settings-ubuntu-14.04.sh SKIP: test-settings-ubuntu-10.04.sh SKIP: test-settings-ubuntu-16.04.sh SKIP: test-settings-ubuntu-12.04.sh PASS: test-virt-customize.sh ===========================================================================Testsuite summary for libguestfs 1.37.20 ===========================================================================# TOTAL: 41 # PASS: 2 # SKIP: 39 # XFAIL: 0 # FAIL: 0 # XPASS: 0 # ERROR: 0 ===========================================================================make[3]: Leaving directory '/var/tmp/tmpFKNosu/libguestfs/customize' make[2]: Leaving directory '/var/tmp/tmpFKNosu/libguestfs/customize' make[1]: Leaving directory '/var/tmp/tmpFKNosu/libguestfs/customize' Making check in builder make[1]: Entering directory '/var/tmp/tmpFKNosu/libguestfs/builder' make yajl_tests debian.xz fedora.xz ubuntu.xz windows.xz fedora.qcow2 fedora.qcow2.xz make[2]: Entering directory '/var/tmp/tmpFKNosu/libguestfs/builder' CC yajl_tests-yajl-c.o OCAMLOPT yajl_tests.cmx rm -f debian.xz debian.xz-t rm -f fedora.xz fedora.xz-t xz --best -c ../test-data/phony-guests/debian.img > debian.xz-t xz --best -c ../test-data/phony-guests/fedora.img > fedora.xz-t rm -f ubuntu.xz ubuntu.xz-t xz --best -c ../test-data/phony-guests/ubuntu.img > ubuntu.xz-t rm -f windows.xz windows.xz-t xz --best -c ../test-data/phony-guests/windows.img > windows.xz-t rm -f fedora.qcow2 fedora.qcow2-t qemu-img convert -f raw -O qcow2 ../test-data/phony-guests/fedora.img fedora.qcow2-t mv fedora.qcow2-t fedora.qcow2 GEN yajl_tests rm -f fedora.qcow2.xz fedora.qcow2.xz-t xz --best -c fedora.qcow2 > fedora.qcow2.xz-t mv fedora.qcow2.xz-t fedora.qcow2.xz mv windows.xz-t windows.xz mv ubuntu.xz-t ubuntu.xz mv debian.xz-t debian.xz mv fedora.xz-t fedora.xz make[2]: Leaving directory '/var/tmp/tmpFKNosu/libguestfs/builder' make check-TESTS make[2]: Entering directory '/var/tmp/tmpFKNosu/libguestfs/builder' make[3]: Entering directory '/var/tmp/tmpFKNosu/libguestfs/builder' rm -f test-console-centos-7.2.sh test-console-centos-7.2.sh-t rm -f test-console-rhel-6.8.sh test-console-rhel-6.8.sh-t f=`echo "test-console-centos-7.2.sh" | /usr/bin/sed 's/test-console-\(.*\).sh/\1/'`; \ echo 'script=test-console-centos-7.2.sh exec $srcdir/test-console.sh' "$f" > test-console-centos-7.2.sh-t f=`echo "test-console-rhel-6.8.sh" | /usr/bin/sed 's/test-console-\(.*\).sh/\1/'`; \ echo 'script=test-console-rhel-6.8.sh exec $srcdir/test-console.sh' "$f" > test-console-rhel-6.8.sh-t chmod 0755 test-console-centos-7.2.sh-t mv test-console-centos-7.2.sh-t test-console-centos-7.2.sh chmod 0755 test-console-rhel-6.8.sh-t rm -f test-console-rhel-7.2.sh test-console-rhel-7.2.sh-t mv test-console-rhel-6.8.sh-t test-console-rhel-6.8.sh f=`echo "test-console-rhel-7.2.sh" | /usr/bin/sed 's/test-console-\(.*\).sh/\1/'`; \ echo 'script=test-console-rhel-7.2.sh exec $srcdir/test-console.sh' "$f" > test-console-rhel-7.2.sh-t rm -f test-console-debian-7.sh test-console-debian-7.sh-t f=`echo "test-console-debian-7.sh" | /usr/bin/sed 's/test-console-\(.*\).sh/\1/'`; \ echo 'script=test-console-debian-7.sh exec $srcdir/test-console.sh' "$f" > test-console-debian-7.sh-t chmod 0755 test-console-rhel-7.2.sh-t chmod 0755 test-console-debian-7.sh-t mv test-console-rhel-7.2.sh-t test-console-rhel-7.2.sh mv test-console-debian-7.sh-t test-console-debian-7.sh rm -f test-console-debian-8.sh test-console-debian-8.sh-t f=`echo "test-console-debian-8.sh" | /usr/bin/sed 's/test-console-\(.*\).sh/\1/'`; \ echo 'script=test-console-debian-8.sh exec $srcdir/test-console.sh' "$f" > test-console-debian-8.sh-t rm -f test-console-fedora-24.sh test-console-fedora-24.sh-t f=`echo "test-console-fedora-24.sh" | /usr/bin/sed 's/test-console-\(.*\).sh/\1/'`; \ echo 'script=test-console-fedora-24.sh exec $srcdir/test-console.sh' "$f" > test-console-fedora-24.sh-t chmod 0755 test-console-fedora-24.sh-t mv test-console-fedora-24.sh-t test-console-fedora-24.sh rm -f test-console-ubuntu-12.04.sh test-console-ubuntu-12.04.sh-t f=`echo "test-console-ubuntu-12.04.sh" | /usr/bin/sed 's/test-console-\(.*\).sh/\1/'`; \ echo 'script=test-console-ubuntu-12.04.sh exec $srcdir/test-console.sh' "$f" > test-console-ubuntu-12.04.sh-t chmod 0755 test-console-debian-8.sh-t mv test-console-debian-8.sh-t test-console-debian-8.sh chmod 0755 test-console-ubuntu-12.04.sh-t rm -f test-console-ubuntu-14.04.sh test-console-ubuntu-14.04.sh-t mv test-console-ubuntu-12.04.sh-t test-console-ubuntu-12.04.sh f=`echo "test-console-ubuntu-14.04.sh" | /usr/bin/sed 's/test-console-\(.*\).sh/\1/'`; \ echo 'script=test-console-ubuntu-14.04.sh exec $srcdir/test-console.sh' "$f" > test-console-ubuntu-14.04.sh-t rm -f test-console-ubuntu-16.04.sh test-console-ubuntu-16.04.sh-t chmod 0755 test-console-ubuntu-14.04.sh-t f=`echo "test-console-ubuntu-16.04.sh" | /usr/bin/sed 's/test-console-\(.*\).sh/\1/'`; \ echo 'script=test-console-ubuntu-16.04.sh exec $srcdir/test-console.sh' "$f" > test-console-ubuntu-16.04.sh-t mv test-console-ubuntu-14.04.sh-t test-console-ubuntu-14.04.sh chmod 0755 test-console-ubuntu-16.04.sh-t mv test-console-ubuntu-16.04.sh-t test-console-ubuntu-16.04.sh PASS: test-virt-index-validate.sh SKIP: test-virt-builder-planner.sh PASS: test-virt-builder-docs.sh PASS: test-virt-builder-list.sh PASS: test-virt-builder-list-simplestreams.sh SKIP: test-console-centos-7.2.sh PASS: yajl_tests SKIP: test-console-rhel-6.8.sh SKIP: test-console-rhel-7.2.sh SKIP: test-console-debian-7.sh SKIP: test-console-fedora-24.sh SKIP: test-console-debian-8.sh SKIP: test-console-ubuntu-12.04.sh SKIP: test-console-ubuntu-14.04.sh SKIP: test-console-ubuntu-16.04.sh PASS: test-virt-builder.sh ===========================================================================Testsuite summary for libguestfs 1.37.20 ===========================================================================# TOTAL: 16 # PASS: 6 # SKIP: 10 # XFAIL: 0 # FAIL: 0 # XPASS: 0 # ERROR: 0 ===========================================================================make[3]: Leaving directory '/var/tmp/tmpFKNosu/libguestfs/builder' make[2]: Leaving directory '/var/tmp/tmpFKNosu/libguestfs/builder' make[1]: Leaving directory '/var/tmp/tmpFKNosu/libguestfs/builder' Making check in builder/templates make[1]: Entering directory '/var/tmp/tmpFKNosu/libguestfs/builder/templates' make check-TESTS make[2]: Entering directory '/var/tmp/tmpFKNosu/libguestfs/builder/templates' make[3]: Entering directory '/var/tmp/tmpFKNosu/libguestfs/builder/templates' PASS: validate.sh ===========================================================================Testsuite summary for libguestfs 1.37.20 ===========================================================================# TOTAL: 1 # PASS: 1 # SKIP: 0 # XFAIL: 0 # FAIL: 0 # XPASS: 0 # ERROR: 0 ===========================================================================make[3]: Leaving directory '/var/tmp/tmpFKNosu/libguestfs/builder/templates' make[2]: Leaving directory '/var/tmp/tmpFKNosu/libguestfs/builder/templates' make[1]: Leaving directory '/var/tmp/tmpFKNosu/libguestfs/builder/templates' Making check in get-kernel make[1]: Entering directory '/var/tmp/tmpFKNosu/libguestfs/get-kernel' make check-TESTS make[2]: Entering directory '/var/tmp/tmpFKNosu/libguestfs/get-kernel' make[3]: Entering directory '/var/tmp/tmpFKNosu/libguestfs/get-kernel' PASS: test-virt-get-kernel-docs.sh ===========================================================================Testsuite summary for libguestfs 1.37.20 ===========================================================================# TOTAL: 1 # PASS: 1 # SKIP: 0 # XFAIL: 0 # FAIL: 0 # XPASS: 0 # ERROR: 0 ===========================================================================make[3]: Leaving directory '/var/tmp/tmpFKNosu/libguestfs/get-kernel' make[2]: Leaving directory '/var/tmp/tmpFKNosu/libguestfs/get-kernel' make[1]: Leaving directory '/var/tmp/tmpFKNosu/libguestfs/get-kernel' Making check in resize make[1]: Entering directory '/var/tmp/tmpFKNosu/libguestfs/resize' make check-TESTS make[2]: Entering directory '/var/tmp/tmpFKNosu/libguestfs/resize' make[3]: Entering directory '/var/tmp/tmpFKNosu/libguestfs/resize' PASS: test-virt-resize-docs.sh PASS: test-virt-resize.pl ===========================================================================Testsuite summary for libguestfs 1.37.20 ===========================================================================# TOTAL: 2 # PASS: 2 # SKIP: 0 # XFAIL: 0 # FAIL: 0 # XPASS: 0 # ERROR: 0 ===========================================================================make[3]: Leaving directory '/var/tmp/tmpFKNosu/libguestfs/resize' make[2]: Leaving directory '/var/tmp/tmpFKNosu/libguestfs/resize' make[1]: Leaving directory '/var/tmp/tmpFKNosu/libguestfs/resize' Making check in sparsify make[1]: Entering directory '/var/tmp/tmpFKNosu/libguestfs/sparsify' make check-TESTS make[2]: Entering directory '/var/tmp/tmpFKNosu/libguestfs/sparsify' make[3]: Entering directory '/var/tmp/tmpFKNosu/libguestfs/sparsify' PASS: test-virt-sparsify-docs.sh PASS: test-virt-sparsify-in-place.sh PASS: test-virt-sparsify.sh PASS: test-virt-sparsify-in-place-fstrim-unsupported.sh ===========================================================================Testsuite summary for libguestfs 1.37.20 ===========================================================================# TOTAL: 4 # PASS: 4 # SKIP: 0 # XFAIL: 0 # FAIL: 0 # XPASS: 0 # ERROR: 0 ===========================================================================make[3]: Leaving directory '/var/tmp/tmpFKNosu/libguestfs/sparsify' make[2]: Leaving directory '/var/tmp/tmpFKNosu/libguestfs/sparsify' make[1]: Leaving directory '/var/tmp/tmpFKNosu/libguestfs/sparsify' Making check in sysprep make[1]: Entering directory '/var/tmp/tmpFKNosu/libguestfs/sysprep' make check-TESTS make[2]: Entering directory '/var/tmp/tmpFKNosu/libguestfs/sysprep' make[3]: Entering directory '/var/tmp/tmpFKNosu/libguestfs/sysprep' PASS: test-virt-sysprep-docs.sh PASS: test-virt-sysprep-passwords.sh PASS: test-virt-sysprep-backup-files.sh PASS: test-virt-sysprep.sh PASS: test-virt-sysprep-script.sh ===========================================================================Testsuite summary for libguestfs 1.37.20 ===========================================================================# TOTAL: 5 # PASS: 5 # SKIP: 0 # XFAIL: 0 # FAIL: 0 # XPASS: 0 # ERROR: 0 ===========================================================================make[3]: Leaving directory '/var/tmp/tmpFKNosu/libguestfs/sysprep' make[2]: Leaving directory '/var/tmp/tmpFKNosu/libguestfs/sysprep' make[1]: Leaving directory '/var/tmp/tmpFKNosu/libguestfs/sysprep' Making check in v2v make[1]: Entering directory '/var/tmp/tmpFKNosu/libguestfs/v2v' make v2v_unit_tests windows.vmdk make[2]: Entering directory '/var/tmp/tmpFKNosu/libguestfs/v2v' CC v2v_unit_tests-libvirt_utils-c.o CC v2v_unit_tests-qemuopts-c.o rm -f windows.vmdk windows.vmdk-t OCAMLOPT v2v_unit_tests.cmx if [ -s ../test-data/phony-guests/windows.img ]; then \ qemu-img convert -f raw ../test-data/phony-guests/windows.img -O vmdk windows.vmdk-t; \ mv windows.vmdk-t windows.vmdk; \ else \ touch windows.vmdk; \ fi GEN v2v_unit_tests make[2]: Leaving directory '/var/tmp/tmpFKNosu/libguestfs/v2v' make check-TESTS make[2]: Entering directory '/var/tmp/tmpFKNosu/libguestfs/v2v' make[3]: Entering directory '/var/tmp/tmpFKNosu/libguestfs/v2v' PASS: test-v2v-docs.sh PASS: test-v2v-i-ova-bad-sha256.sh PASS: test-v2v-i-ova-bad-sha1.sh PASS: test-v2v-i-ova-good-checksums.sh PASS: test-v2v-i-ova-formats.sh PASS: test-v2v-i-ova-invalid-manifest1.sh PASS: test-v2v-i-ova-gz.sh PASS: test-v2v-i-ova-subfolders.sh PASS: test-v2v-i-ova-invalid-manifest2.sh PASS: test-v2v-i-ova-tar.sh PASS: test-v2v-copy-to-local.sh PASS: test-v2v-i-ova-two-disks.sh PASS: test-v2v-bad-networks-and-bridges.sh PASS: test-v2v-i-vmx.sh PASS: v2v_unit_tests PASS: test-v2v-machine-readable.sh PASS: test-v2v-i-ova.sh PASS: test-v2v-i-disk.sh PASS: test-v2v-cdrom.sh PASS: test-v2v-windows-conversion.sh PASS: test-v2v-floppy.sh PASS: test-v2v-networks-and-bridges.sh PASS: test-v2v-virtio-win-iso.sh PASS: test-v2v-in-place.sh PASS: test-v2v-o-glance.sh PASS: test-v2v-o-libvirt.sh PASS: test-v2v-o-null.sh PASS: test-v2v-no-copy.sh PASS: test-v2v-o-qemu.sh PASS: test-v2v-o-rhv.sh PASS: test-v2v-print-source.sh PASS: test-v2v-o-vdsm-options.sh rm -f test-v2v-conversion-of-centos-6.sh test-v2v-conversion-of-centos-6.sh-t f=`echo "test-v2v-conversion-of-centos-6.sh" | /usr/bin/sed 's/test-v2v-conversion-of-\(.*\).sh/\1/'`; \ echo 'script=test-v2v-conversion-of-centos-6.sh exec $srcdir/test-v2v-conversion-of.sh' "$f" > test-v2v-conversion-of-centos-6.sh-t chmod 0755 test-v2v-conversion-of-centos-6.sh-t mv test-v2v-conversion-of-centos-6.sh-t test-v2v-conversion-of-centos-6.sh rm -f test-v2v-conversion-of-centos-7.0.sh test-v2v-conversion-of-centos-7.0.sh-t f=`echo "test-v2v-conversion-of-centos-7.0.sh" | /usr/bin/sed 's/test-v2v-conversion-of-\(.*\).sh/\1/'`; \ echo 'script=test-v2v-conversion-of-centos-7.0.sh exec $srcdir/test-v2v-conversion-of.sh' "$f" > test-v2v-conversion-of-centos-7.0.sh-t chmod 0755 test-v2v-conversion-of-centos-7.0.sh-t mv test-v2v-conversion-of-centos-7.0.sh-t test-v2v-conversion-of-centos-7.0.sh rm -f test-v2v-conversion-of-debian-6.sh test-v2v-conversion-of-debian-6.sh-t f=`echo "test-v2v-conversion-of-debian-6.sh" | /usr/bin/sed 's/test-v2v-conversion-of-\(.*\).sh/\1/'`; \ echo 'script=test-v2v-conversion-of-debian-6.sh exec $srcdir/test-v2v-conversion-of.sh' "$f" > test-v2v-conversion-of-debian-6.sh-t chmod 0755 test-v2v-conversion-of-debian-6.sh-t mv test-v2v-conversion-of-debian-6.sh-t test-v2v-conversion-of-debian-6.sh rm -f test-v2v-conversion-of-debian-7.sh test-v2v-conversion-of-debian-7.sh-t f=`echo "test-v2v-conversion-of-debian-7.sh" | /usr/bin/sed 's/test-v2v-conversion-of-\(.*\).sh/\1/'`; \ echo 'script=test-v2v-conversion-of-debian-7.sh exec $srcdir/test-v2v-conversion-of.sh' "$f" > test-v2v-conversion-of-debian-7.sh-t chmod 0755 test-v2v-conversion-of-debian-7.sh-t mv test-v2v-conversion-of-debian-7.sh-t test-v2v-conversion-of-debian-7.sh rm -f test-v2v-conversion-of-debian-8.sh test-v2v-conversion-of-debian-8.sh-t f=`echo "test-v2v-conversion-of-debian-8.sh" | /usr/bin/sed 's/test-v2v-conversion-of-\(.*\).sh/\1/'`; \ echo 'script=test-v2v-conversion-of-debian-8.sh exec $srcdir/test-v2v-conversion-of.sh' "$f" > test-v2v-conversion-of-debian-8.sh-t chmod 0755 test-v2v-conversion-of-debian-8.sh-t mv test-v2v-conversion-of-debian-8.sh-t test-v2v-conversion-of-debian-8.sh rm -f test-v2v-conversion-of-fedora-20.sh test-v2v-conversion-of-fedora-20.sh-t f=`echo "test-v2v-conversion-of-fedora-20.sh" | /usr/bin/sed 's/test-v2v-conversion-of-\(.*\).sh/\1/'`; \ echo 'script=test-v2v-conversion-of-fedora-20.sh exec $srcdir/test-v2v-conversion-of.sh' "$f" > test-v2v-conversion-of-fedora-20.sh-t chmod 0755 test-v2v-conversion-of-fedora-20.sh-t mv test-v2v-conversion-of-fedora-20.sh-t test-v2v-conversion-of-fedora-20.sh rm -f test-v2v-conversion-of-fedora-23.sh test-v2v-conversion-of-fedora-23.sh-t f=`echo "test-v2v-conversion-of-fedora-23.sh" | /usr/bin/sed 's/test-v2v-conversion-of-\(.*\).sh/\1/'`; \ echo 'script=test-v2v-conversion-of-fedora-23.sh exec $srcdir/test-v2v-conversion-of.sh' "$f" > test-v2v-conversion-of-fedora-23.sh-t chmod 0755 test-v2v-conversion-of-fedora-23.sh-t mv test-v2v-conversion-of-fedora-23.sh-t test-v2v-conversion-of-fedora-23.sh rm -f test-v2v-conversion-of-opensuse-13.1.sh test-v2v-conversion-of-opensuse-13.1.sh-t f=`echo "test-v2v-conversion-of-opensuse-13.1.sh" | /usr/bin/sed 's/test-v2v-conversion-of-\(.*\).sh/\1/'`; \ echo 'script=test-v2v-conversion-of-opensuse-13.1.sh exec $srcdir/test-v2v-conversion-of.sh' "$f" > test-v2v-conversion-of-opensuse-13.1.sh-t chmod 0755 test-v2v-conversion-of-opensuse-13.1.sh-t mv test-v2v-conversion-of-opensuse-13.1.sh-t test-v2v-conversion-of-opensuse-13.1.sh rm -f test-v2v-conversion-of-opensuse-13.2.sh test-v2v-conversion-of-opensuse-13.2.sh-t f=`echo "test-v2v-conversion-of-opensuse-13.2.sh" | /usr/bin/sed 's/test-v2v-conversion-of-\(.*\).sh/\1/'`; \ echo 'script=test-v2v-conversion-of-opensuse-13.2.sh exec $srcdir/test-v2v-conversion-of.sh' "$f" > test-v2v-conversion-of-opensuse-13.2.sh-t chmod 0755 test-v2v-conversion-of-opensuse-13.2.sh-t mv test-v2v-conversion-of-opensuse-13.2.sh-t test-v2v-conversion-of-opensuse-13.2.sh rm -f test-v2v-conversion-of-opensuse-42.1.sh test-v2v-conversion-of-opensuse-42.1.sh-t f=`echo "test-v2v-conversion-of-opensuse-42.1.sh" | /usr/bin/sed 's/test-v2v-conversion-of-\(.*\).sh/\1/'`; \ echo 'script=test-v2v-conversion-of-opensuse-42.1.sh exec $srcdir/test-v2v-conversion-of.sh' "$f" > test-v2v-conversion-of-opensuse-42.1.sh-t chmod 0755 test-v2v-conversion-of-opensuse-42.1.sh-t mv test-v2v-conversion-of-opensuse-42.1.sh-t test-v2v-conversion-of-opensuse-42.1.sh rm -f test-v2v-conversion-of-rhel-5.10.sh test-v2v-conversion-of-rhel-5.10.sh-t f=`echo "test-v2v-conversion-of-rhel-5.10.sh" | /usr/bin/sed 's/test-v2v-conversion-of-\(.*\).sh/\1/'`; \ echo 'script=test-v2v-conversion-of-rhel-5.10.sh exec $srcdir/test-v2v-conversion-of.sh' "$f" > test-v2v-conversion-of-rhel-5.10.sh-t chmod 0755 test-v2v-conversion-of-rhel-5.10.sh-t mv test-v2v-conversion-of-rhel-5.10.sh-t test-v2v-conversion-of-rhel-5.10.sh rm -f test-v2v-conversion-of-rhel-6.8.sh test-v2v-conversion-of-rhel-6.8.sh-t f=`echo "test-v2v-conversion-of-rhel-6.8.sh" | /usr/bin/sed 's/test-v2v-conversion-of-\(.*\).sh/\1/'`; \ echo 'script=test-v2v-conversion-of-rhel-6.8.sh exec $srcdir/test-v2v-conversion-of.sh' "$f" > test-v2v-conversion-of-rhel-6.8.sh-t chmod 0755 test-v2v-conversion-of-rhel-6.8.sh-t mv test-v2v-conversion-of-rhel-6.8.sh-t test-v2v-conversion-of-rhel-6.8.sh rm -f test-v2v-conversion-of-rhel-7.0.sh test-v2v-conversion-of-rhel-7.0.sh-t f=`echo "test-v2v-conversion-of-rhel-7.0.sh" | /usr/bin/sed 's/test-v2v-conversion-of-\(.*\).sh/\1/'`; \ echo 'script=test-v2v-conversion-of-rhel-7.0.sh exec $srcdir/test-v2v-conversion-of.sh' "$f" > test-v2v-conversion-of-rhel-7.0.sh-t chmod 0755 test-v2v-conversion-of-rhel-7.0.sh-t mv test-v2v-conversion-of-rhel-7.0.sh-t test-v2v-conversion-of-rhel-7.0.sh rm -f test-v2v-conversion-of-rhel-7.2.sh test-v2v-conversion-of-rhel-7.2.sh-t f=`echo "test-v2v-conversion-of-rhel-7.2.sh" | /usr/bin/sed 's/test-v2v-conversion-of-\(.*\).sh/\1/'`; \ echo 'script=test-v2v-conversion-of-rhel-7.2.sh exec $srcdir/test-v2v-conversion-of.sh' "$f" > test-v2v-conversion-of-rhel-7.2.sh-t chmod 0755 test-v2v-conversion-of-rhel-7.2.sh-t mv test-v2v-conversion-of-rhel-7.2.sh-t test-v2v-conversion-of-rhel-7.2.sh rm -f test-v2v-conversion-of-ubuntu-10.04.sh test-v2v-conversion-of-ubuntu-10.04.sh-t f=`echo "test-v2v-conversion-of-ubuntu-10.04.sh" | /usr/bin/sed 's/test-v2v-conversion-of-\(.*\).sh/\1/'`; \ echo 'script=test-v2v-conversion-of-ubuntu-10.04.sh exec $srcdir/test-v2v-conversion-of.sh' "$f" > test-v2v-conversion-of-ubuntu-10.04.sh-t chmod 0755 test-v2v-conversion-of-ubuntu-10.04.sh-t mv test-v2v-conversion-of-ubuntu-10.04.sh-t test-v2v-conversion-of-ubuntu-10.04.sh rm -f test-v2v-conversion-of-ubuntu-12.04.sh test-v2v-conversion-of-ubuntu-12.04.sh-t f=`echo "test-v2v-conversion-of-ubuntu-12.04.sh" | /usr/bin/sed 's/test-v2v-conversion-of-\(.*\).sh/\1/'`; \ echo 'script=test-v2v-conversion-of-ubuntu-12.04.sh exec $srcdir/test-v2v-conversion-of.sh' "$f" > test-v2v-conversion-of-ubuntu-12.04.sh-t chmod 0755 test-v2v-conversion-of-ubuntu-12.04.sh-t mv test-v2v-conversion-of-ubuntu-12.04.sh-t test-v2v-conversion-of-ubuntu-12.04.sh rm -f test-v2v-conversion-of-ubuntu-14.04.sh test-v2v-conversion-of-ubuntu-14.04.sh-t f=`echo "test-v2v-conversion-of-ubuntu-14.04.sh" | /usr/bin/sed 's/test-v2v-conversion-of-\(.*\).sh/\1/'`; \ echo 'script=test-v2v-conversion-of-ubuntu-14.04.sh exec $srcdir/test-v2v-conversion-of.sh' "$f" > test-v2v-conversion-of-ubuntu-14.04.sh-t chmod 0755 test-v2v-conversion-of-ubuntu-14.04.sh-t mv test-v2v-conversion-of-ubuntu-14.04.sh-t test-v2v-conversion-of-ubuntu-14.04.sh rm -f test-v2v-conversion-of-ubuntu-16.04.sh test-v2v-conversion-of-ubuntu-16.04.sh-t f=`echo "test-v2v-conversion-of-ubuntu-16.04.sh" | /usr/bin/sed 's/test-v2v-conversion-of-\(.*\).sh/\1/'`; \ echo 'script=test-v2v-conversion-of-ubuntu-16.04.sh exec $srcdir/test-v2v-conversion-of.sh' "$f" > test-v2v-conversion-of-ubuntu-16.04.sh-t chmod 0755 test-v2v-conversion-of-ubuntu-16.04.sh-t mv test-v2v-conversion-of-ubuntu-16.04.sh-t test-v2v-conversion-of-ubuntu-16.04.sh PASS: test-v2v-oa-option.sh SKIP: test-v2v-trim.sh SKIP: test-v2v-conversion-of-centos-6.sh SKIP: test-v2v-i-ova-as-root.sh PASS: test-v2v-of-option.sh SKIP: test-v2v-conversion-of-centos-7.0.sh SKIP: test-v2v-conversion-of-debian-6.sh SKIP: test-v2v-conversion-of-debian-7.sh SKIP: test-v2v-conversion-of-debian-8.sh SKIP: test-v2v-conversion-of-fedora-20.sh SKIP: test-v2v-conversion-of-fedora-23.sh SKIP: test-v2v-conversion-of-opensuse-13.1.sh SKIP: test-v2v-conversion-of-opensuse-13.2.sh SKIP: test-v2v-conversion-of-opensuse-42.1.sh SKIP: test-v2v-conversion-of-rhel-5.10.sh SKIP: test-v2v-conversion-of-rhel-6.8.sh SKIP: test-v2v-conversion-of-rhel-7.0.sh SKIP: test-v2v-conversion-of-ubuntu-10.04.sh SKIP: test-v2v-conversion-of-rhel-7.2.sh SKIP: test-v2v-conversion-of-ubuntu-12.04.sh SKIP: test-v2v-conversion-of-ubuntu-14.04.sh SKIP: test-v2v-conversion-of-ubuntu-16.04.sh PASS: test-v2v-on-option.sh PASS: test-v2v-sound.sh ===========================================================================Testsuite summary for libguestfs 1.37.20 ===========================================================================# TOTAL: 56 # PASS: 36 # SKIP: 20 # XFAIL: 0 # FAIL: 0 # XPASS: 0 # ERROR: 0 ===========================================================================make[3]: Leaving directory '/var/tmp/tmpFKNosu/libguestfs/v2v' make[2]: Leaving directory '/var/tmp/tmpFKNosu/libguestfs/v2v' make[1]: Leaving directory '/var/tmp/tmpFKNosu/libguestfs/v2v' Making check in v2v/test-harness make[1]: Entering directory '/var/tmp/tmpFKNosu/libguestfs/v2v/test-harness' make[1]: Nothing to be done for 'check'. make[1]: Leaving directory '/var/tmp/tmpFKNosu/libguestfs/v2v/test-harness' Making check in dib make[1]: Entering directory '/var/tmp/tmpFKNosu/libguestfs/dib' make check-TESTS make[2]: Entering directory '/var/tmp/tmpFKNosu/libguestfs/dib' make[3]: Entering directory '/var/tmp/tmpFKNosu/libguestfs/dib' PASS: test-virt-dib-docs.sh ===========================================================================Testsuite summary for libguestfs 1.37.20 ===========================================================================# TOTAL: 1 # PASS: 1 # SKIP: 0 # XFAIL: 0 # FAIL: 0 # XPASS: 0 # ERROR: 0 ===========================================================================make[3]: Leaving directory '/var/tmp/tmpFKNosu/libguestfs/dib' make[2]: Leaving directory '/var/tmp/tmpFKNosu/libguestfs/dib' make[1]: Leaving directory '/var/tmp/tmpFKNosu/libguestfs/dib' Making check in tools make[1]: Entering directory '/var/tmp/tmpFKNosu/libguestfs/tools' for f in tools/virt-list-filesystems tools/virt-list-partitions tools/virt-tar tools/virt-win-reg; do echo $f; done > ../po/POTFILES-pl make check-TESTS make[2]: Entering directory '/var/tmp/tmpFKNosu/libguestfs/tools' make[3]: Entering directory '/var/tmp/tmpFKNosu/libguestfs/tools' PASS: test-virt-list-filesystems.sh PASS: test-virt-tar.sh ===========================================================================Testsuite summary for libguestfs 1.37.20 ===========================================================================# TOTAL: 2 # PASS: 2 # SKIP: 0 # XFAIL: 0 # FAIL: 0 # XPASS: 0 # ERROR: 0 ===========================================================================make[3]: Leaving directory '/var/tmp/tmpFKNosu/libguestfs/tools' make[2]: Leaving directory '/var/tmp/tmpFKNosu/libguestfs/tools' make[1]: Leaving directory '/var/tmp/tmpFKNosu/libguestfs/tools' Making check in fuse make[1]: Entering directory '/var/tmp/tmpFKNosu/libguestfs/fuse' make test-fuse test-guestmount-fd test-guestunmount-fd make[2]: Entering directory '/var/tmp/tmpFKNosu/libguestfs/fuse' CC test_fuse-test-fuse.o CC test_guestmount_fd-test-guestmount-fd.o CC test_guestunmount_fd-test-guestunmount-fd.o CCLD test-guestunmount-fd CCLD test-guestmount-fd CCLD test-fuse make[2]: Leaving directory '/var/tmp/tmpFKNosu/libguestfs/fuse' make check-TESTS make[2]: Entering directory '/var/tmp/tmpFKNosu/libguestfs/fuse' make[3]: Entering directory '/var/tmp/tmpFKNosu/libguestfs/fuse' PASS: test-guestunmount-not-mounted.sh SKIP: test-fuse-umount-race.sh PASS: test-docs.sh SKIP: /var/tmp/tmpFKNosu/libguestfs/fuse/.libs/lt-test-guestmount-fd PASS: /var/tmp/tmpFKNosu/libguestfs/fuse/.libs/lt-test-guestunmount-fd PASS: /var/tmp/tmpFKNosu/libguestfs/fuse/.libs/lt-test-fuse ===========================================================================Testsuite summary for libguestfs 1.37.20 ===========================================================================# TOTAL: 6 # PASS: 4 # SKIP: 2 # XFAIL: 0 # FAIL: 0 # XPASS: 0 # ERROR: 0 ===========================================================================make[3]: Leaving directory '/var/tmp/tmpFKNosu/libguestfs/fuse' make[2]: Leaving directory '/var/tmp/tmpFKNosu/libguestfs/fuse' make[1]: Leaving directory '/var/tmp/tmpFKNosu/libguestfs/fuse' Making check in utils/boot-analysis make[1]: Entering directory '/var/tmp/tmpFKNosu/libguestfs/utils/boot-analysis' make[1]: Nothing to be done for 'check'. make[1]: Leaving directory '/var/tmp/tmpFKNosu/libguestfs/utils/boot-analysis' Making check in utils/boot-benchmark make[1]: Entering directory '/var/tmp/tmpFKNosu/libguestfs/utils/boot-benchmark' make[1]: Nothing to be done for 'check'. make[1]: Leaving directory '/var/tmp/tmpFKNosu/libguestfs/utils/boot-benchmark' Making check in utils/qemu-boot make[1]: Entering directory '/var/tmp/tmpFKNosu/libguestfs/utils/qemu-boot' make[1]: Nothing to be done for 'check'. make[1]: Leaving directory '/var/tmp/tmpFKNosu/libguestfs/utils/qemu-boot' Making check in utils/qemu-speed-test make[1]: Entering directory '/var/tmp/tmpFKNosu/libguestfs/utils/qemu-speed-test' make[1]: Nothing to be done for 'check'. make[1]: Leaving directory '/var/tmp/tmpFKNosu/libguestfs/utils/qemu-speed-test' Making check in po-docs make[1]: Entering directory '/var/tmp/tmpFKNosu/libguestfs/po-docs' Making check in ja make[2]: Entering directory '/var/tmp/tmpFKNosu/libguestfs/po-docs/ja' make[2]: Nothing to be done for 'check'. make[2]: Leaving directory '/var/tmp/tmpFKNosu/libguestfs/po-docs/ja' Making check in uk make[2]: Entering directory '/var/tmp/tmpFKNosu/libguestfs/po-docs/uk' make[2]: Nothing to be done for 'check'. make[2]: Leaving directory '/var/tmp/tmpFKNosu/libguestfs/po-docs/uk' make[2]: Entering directory '/var/tmp/tmpFKNosu/libguestfs/po-docs' make[2]: Nothing to be done for 'check-am'. make[2]: Leaving directory '/var/tmp/tmpFKNosu/libguestfs/po-docs' make[1]: Leaving directory '/var/tmp/tmpFKNosu/libguestfs/po-docs' make[1]: Entering directory '/var/tmp/tmpFKNosu/libguestfs' make[1]: Leaving directory '/var/tmp/tmpFKNosu/libguestfs'
Pino Toscano
2017-Aug-08 12:32 UTC
Re: [Libguestfs] [PATCH 3/6] daemon: Refine check for Device and Dev_or_Path parameters (RHBZ#1477623).
On Thursday, 3 August 2017 19:13:48 CEST Richard W.M. Jones wrote:> + fprintf (stderr, "mode = %o\n", statbuf.st_mode); > + if (S_ISBLK (statbuf.st_mode)) > + /* continue */; > + else if (S_ISDIR (statbuf.st_mode)) { > + fprintf (stderr, "S_ISDIR\n");The two unconditional fprintf() look like debugging leftovers.> + fd = open (device, O_RDONLY|O_CLOEXEC); > + if (fd == -1) { > + if (verbose) > + fprintf (stderr, "%s: open: %s: %m\n", "is_device_parameter", device); > + return 0; > + } > + if (ioctl (fd, BLKGETSIZE64, &n) == -1) { > + if (verbose) > + fprintf (stderr, "%s: ioctl BLKGETSIZE64: %s: %m\n", > + "is_device_parameter", device); > + close (fd); > + return 0; > + } > + close (fd);Maybe 'fd' can be: CLEANUP_CLOSE int fd = -1; so there is no need to manually close() it on every return path. -- Pino Toscano
Pino Toscano
2017-Aug-08 12:58 UTC
Re: [Libguestfs] [PATCH 0/6] tests: Fix handling of device API parameters (RHBZ#1477623).
On Thursday, 3 August 2017 19:13:45 CEST Richard W.M. Jones wrote:> https://bugzilla.redhat.com/show_bug.cgi?id=1477623 > > The first two patches are cleanups. > > The third patch changes the way that we handle Device and Dev_or_Path > parameters so that a parameter marked as such can really only contain > a block device name (and not, for instance, a chardev). Using a > chardev here caused hangs in the API. > > The next two patches fix API usage to conform to this new stricter > checking. I removed the ability to use "/dev/urandom" (and similar) > non-block devices in place of block devices in such APIs as > guestfs_copy_device_to_device. > > Last patch adds a regression test.Except for the notes for patch #3, the rest LGTM. -- Pino Toscano
Apparently Analagous Threads
- [PATCH 0/6] tests: Fix handling of device API parameters (RHBZ#1477623).
- Re: [PATCH 3/6] daemon: Refine check for Device and Dev_or_Path parameters (RHBZ#1477623).
- [PATCH V3 1/2] umount: add force umount and lazy umount
- [PATCH V2 1/4] mount: add a macro to resolve path or device
- [PATCH V4 1/3] umount: add force umount and lazy umount