From 90a56e0c132982e3907ed1c849177c87642baf8b Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Aug 01 2017 03:39:58 +0000 Subject: import libguestfs-1.36.3-6.el7 --- diff --git a/.gitignore b/.gitignore index 7ed2d79..35a8cbc 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ SOURCES/RHEV-Application-Provisioning-Tool.exe_4.12 -SOURCES/libguestfs-1.32.7.tar.gz +SOURCES/libguestfs-1.36.3.tar.gz SOURCES/libguestfs.keyring SOURCES/rhsrvany.exe diff --git a/.libguestfs.metadata b/.libguestfs.metadata index f133307..c246969 100644 --- a/.libguestfs.metadata +++ b/.libguestfs.metadata @@ -1,4 +1,4 @@ 8fec32284530ce6d485629fcbd1f7f3e005ae8a0 SOURCES/RHEV-Application-Provisioning-Tool.exe_4.12 -601e78445b168478ac761517593716b3772f1c7b SOURCES/libguestfs-1.32.7.tar.gz +269b49a6e6fcbc7beb287b27829cacbc35d4882b SOURCES/libguestfs-1.36.3.tar.gz 1bbc40f501a7fef9eef2a39b701a71aee2fea7c4 SOURCES/libguestfs.keyring 2bd96e478fc004cd323b5bd754c856641877dac6 SOURCES/rhsrvany.exe diff --git a/SOURCES/0001-RHEL-7-Remove-libguestfs-live-RHBZ-798980.patch b/SOURCES/0001-RHEL-7-Remove-libguestfs-live-RHBZ-798980.patch index ad68535..30b854e 100644 --- a/SOURCES/0001-RHEL-7-Remove-libguestfs-live-RHBZ-798980.patch +++ b/SOURCES/0001-RHEL-7-Remove-libguestfs-live-RHBZ-798980.patch @@ -1,17 +1,17 @@ -From bd1a920c9ada1d55f79f9e9e2693bd78a624f2ba Mon Sep 17 00:00:00 2001 +From c1b189f662e4dccce0c3ef72a458f5eba298e949 Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Fri, 21 Dec 2012 15:50:11 +0000 Subject: [PATCH] RHEL 7: Remove libguestfs live (RHBZ#798980). This isn't supported in RHEL 7. --- - src/launch-unix.c | 7 +++++++ + lib/launch-unix.c | 7 +++++++ 1 file changed, 7 insertions(+) -diff --git a/src/launch-unix.c b/src/launch-unix.c -index 973e14b..428fdc6 100644 ---- a/src/launch-unix.c -+++ b/src/launch-unix.c +diff --git a/lib/launch-unix.c b/lib/launch-unix.c +index 8ce4ca5..9be2b9c 100644 +--- a/lib/launch-unix.c ++++ b/lib/launch-unix.c @@ -37,6 +37,12 @@ static int launch_unix (guestfs_h *g, void *datav, const char *sockpath) @@ -25,7 +25,7 @@ index 973e14b..428fdc6 100644 int r, daemon_sock = -1; struct sockaddr_un addr; uint32_t size; -@@ -108,6 +114,7 @@ launch_unix (guestfs_h *g, void *datav, const char *sockpath) +@@ -106,6 +112,7 @@ launch_unix (guestfs_h *g, void *datav, const char *sockpath) g->conn = NULL; } return -1; @@ -34,5 +34,5 @@ index 973e14b..428fdc6 100644 static int -- -1.8.3.1 +2.9.4 diff --git a/SOURCES/0002-RHEL-7-Remove-9p-APIs-from-RHEL-RHBZ-921710.patch b/SOURCES/0002-RHEL-7-Remove-9p-APIs-from-RHEL-RHBZ-921710.patch index 1f12198..62a0362 100644 --- a/SOURCES/0002-RHEL-7-Remove-9p-APIs-from-RHEL-RHBZ-921710.patch +++ b/SOURCES/0002-RHEL-7-Remove-9p-APIs-from-RHEL-RHBZ-921710.patch @@ -1,23 +1,25 @@ -From 46238a80e68fcb4c8b65b6f4aab050aa0316a8e7 Mon Sep 17 00:00:00 2001 +From ee68d9b7941ced89bc91878f09eb528773e624db Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Thu, 18 Jul 2013 18:31:53 +0100 Subject: [PATCH] RHEL 7: Remove 9p APIs from RHEL (RHBZ#921710). --- - Makefile.am | 2 +- - daemon/9p.c | 221 --------------------------------------------------- - daemon/Makefile.am | 1 - - generator/actions.ml | 23 ------ - gobject/Makefile.inc | 2 - - po/POTFILES | 2 - - 6 files changed, 1 insertion(+), 250 deletions(-) + Makefile.am | 2 +- + daemon/9p.c | 225 ---------------------------------------------- + daemon/Makefile.am | 1 - + docs/C_SOURCE_FILES | 1 - + generator/actions_core.ml | 21 ----- + generator/proc_nr.ml | 2 - + gobject/Makefile.inc | 2 - + po/POTFILES | 2 - + 8 files changed, 1 insertion(+), 255 deletions(-) delete mode 100644 daemon/9p.c diff --git a/Makefile.am b/Makefile.am -index 524e397..c77fc34 100644 +index 12486de..14b277a 100644 --- a/Makefile.am +++ b/Makefile.am -@@ -71,7 +71,7 @@ SUBDIRS += tests/xfs +@@ -73,7 +73,7 @@ SUBDIRS += tests/xfs SUBDIRS += tests/charsets SUBDIRS += tests/xml SUBDIRS += tests/mount-local @@ -28,10 +30,10 @@ index 524e397..c77fc34 100644 SUBDIRS += tests/disk-labels diff --git a/daemon/9p.c b/daemon/9p.c deleted file mode 100644 -index a9e36d1..0000000 +index bd564a5..0000000 --- a/daemon/9p.c +++ /dev/null -@@ -1,221 +0,0 @@ +@@ -1,225 +0,0 @@ -/* libguestfs - the guestfsd daemon - * Copyright (C) 2011 Red Hat Inc. - * @@ -105,9 +107,13 @@ index a9e36d1..0000000 - if (d == NULL) break; - - if (STRPREFIX (d->d_name, "virtio")) { -- char mount_tag_path[256]; -- snprintf (mount_tag_path, sizeof mount_tag_path, -- BUS_PATH "/%s/mount_tag", d->d_name); +- CLEANUP_FREE char *mount_tag_path = NULL; +- if (asprintf (&mount_tag_path, BUS_PATH "/%s/mount_tag", +- d->d_name) == -1) { +- reply_with_perror ("asprintf"); +- closedir (dir); +- return NULL; +- } - - /* A bit unclear, but it looks like the virtio transport allows - * the mount tag length to be unlimited (or up to 65536 bytes). @@ -254,28 +260,39 @@ index a9e36d1..0000000 - return 0; -} diff --git a/daemon/Makefile.am b/daemon/Makefile.am -index 997d89f..20a6289 100644 +index 9381742..0670cda 100644 --- a/daemon/Makefile.am +++ b/daemon/Makefile.am -@@ -83,7 +83,6 @@ endif - # https://rwmj.wordpress.com/2015/09/30/make-and-queuing-theory/#content +@@ -48,7 +48,6 @@ endif guestfsd_SOURCES = \ - stubs.c \ + ../common/errnostring/errnostring.h \ + ../common/protocol/guestfs_protocol.h \ - 9p.c \ acl.c \ actions.h \ available.c \ -diff --git a/generator/actions.ml b/generator/actions.ml -index 304fd80..9248ded 100644 ---- a/generator/actions.ml -+++ b/generator/actions.ml -@@ -9359,29 +9359,6 @@ This returns true iff the device exists and contains all zero bytes. +diff --git a/docs/C_SOURCE_FILES b/docs/C_SOURCE_FILES +index 26abcc9..608eaea 100644 +--- a/docs/C_SOURCE_FILES ++++ b/docs/C_SOURCE_FILES +@@ -49,7 +49,6 @@ common/windows/windows.h + customize/crypt-c.c + customize/dummy.c + customize/perl_edit-c.c +-daemon/9p.c + daemon/acl.c + daemon/actions.h + daemon/augeas.c +diff --git a/generator/actions_core.ml b/generator/actions_core.ml +index ed89f74..2567981 100644 +--- a/generator/actions_core.ml ++++ b/generator/actions_core.ml +@@ -6372,27 +6372,6 @@ This returns true iff the device exists and contains all zero bytes. Note that for large devices this can take a long time to run." }; { defaults with - name = "list_9p"; added = (1, 11, 12); - style = RStringList "mounttags", [], []; -- proc_nr = Some 285; - shortdesc = "list 9p filesystems"; - longdesc = "\ -List all 9p filesystems attached to the guest. A list of @@ -284,7 +301,6 @@ index 304fd80..9248ded 100644 - { defaults with - name = "mount_9p"; added = (1, 11, 12); - style = RErr, [String "mounttag"; String "mountpoint"], [OString "options"]; -- proc_nr = Some 286; - camel_name = "Mount9P"; - shortdesc = "mount 9p filesystem"; - longdesc = "\ @@ -298,21 +314,34 @@ index 304fd80..9248ded 100644 - { defaults with name = "list_dm_devices"; added = (1, 11, 15); style = RStringList "devices", [], []; - proc_nr = Some 287; + shortdesc = "list device mapper devices"; +diff --git a/generator/proc_nr.ml b/generator/proc_nr.ml +index b3be319..7f92e04 100644 +--- a/generator/proc_nr.ml ++++ b/generator/proc_nr.ml +@@ -295,8 +295,6 @@ let proc_nr = [ + 282, "internal_autosync"; + 283, "is_zero"; + 284, "is_zero_device"; +-285, "list_9p"; +-286, "mount_9p"; + 287, "list_dm_devices"; + 288, "ntfsresize"; + 289, "btrfs_filesystem_resize"; diff --git a/gobject/Makefile.inc b/gobject/Makefile.inc -index 3bb8041..20c98ff 100644 +index 8fa8599..7a52726 100644 --- a/gobject/Makefile.inc +++ b/gobject/Makefile.inc -@@ -87,7 +87,6 @@ guestfs_gobject_headers= \ - include/guestfs-gobject/optargs-mkfs_btrfs.h \ +@@ -92,7 +92,6 @@ guestfs_gobject_headers= \ + include/guestfs-gobject/optargs-mksquashfs.h \ include/guestfs-gobject/optargs-mkswap.h \ include/guestfs-gobject/optargs-mktemp.h \ - include/guestfs-gobject/optargs-mount_9p.h \ include/guestfs-gobject/optargs-mount_local.h \ include/guestfs-gobject/optargs-ntfsclone_out.h \ include/guestfs-gobject/optargs-ntfsfix.h \ -@@ -173,7 +172,6 @@ guestfs_gobject_sources= \ - src/optargs-mkfs_btrfs.c \ +@@ -184,7 +183,6 @@ guestfs_gobject_sources= \ + src/optargs-mksquashfs.c \ src/optargs-mkswap.c \ src/optargs-mktemp.c \ - src/optargs-mount_9p.c \ @@ -320,19 +349,19 @@ index 3bb8041..20c98ff 100644 src/optargs-ntfsclone_out.c \ src/optargs-ntfsfix.c \ diff --git a/po/POTFILES b/po/POTFILES -index d025941..d4058ac 100644 +index 904e751..143d1cd 100644 --- a/po/POTFILES +++ b/po/POTFILES -@@ -14,7 +14,6 @@ cat/ls.c - cat/visit.c - customize/crypt-c.c +@@ -39,7 +39,6 @@ customize/crypt-c.c + customize/dummy.c customize/perl_edit-c.c + customize/test-password.pl -daemon/9p.c daemon/acl.c daemon/augeas.c daemon/available.c -@@ -213,7 +212,6 @@ gobject/src/optargs-mkfs.c - gobject/src/optargs-mkfs_btrfs.c +@@ -266,7 +265,6 @@ gobject/src/optargs-mkfs_btrfs.c + gobject/src/optargs-mksquashfs.c gobject/src/optargs-mkswap.c gobject/src/optargs-mktemp.c -gobject/src/optargs-mount_9p.c @@ -340,5 +369,5 @@ index d025941..d4058ac 100644 gobject/src/optargs-ntfsclone_out.c gobject/src/optargs-ntfsfix.c -- -1.8.3.1 +2.9.4 diff --git a/SOURCES/0003-RHEL-7-Disable-unsupported-remote-drive-protocols-RH.patch b/SOURCES/0003-RHEL-7-Disable-unsupported-remote-drive-protocols-RH.patch index 56746fa..efc13f1 100644 --- a/SOURCES/0003-RHEL-7-Disable-unsupported-remote-drive-protocols-RH.patch +++ b/SOURCES/0003-RHEL-7-Disable-unsupported-remote-drive-protocols-RH.patch @@ -1,4 +1,4 @@ -From b541b1915be389651e44954143e73531163cb1af Mon Sep 17 00:00:00 2001 +From a000794c30a6c6603f000d39b6674bfb3be26037 Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Mon, 29 Jul 2013 14:47:56 +0100 Subject: [PATCH] RHEL 7: Disable unsupported remote drive protocols @@ -22,27 +22,26 @@ We hope to gradually add some of these back over the lifetime of RHEL 7. In RHEL 7.2: rbd (Ceph) support was enabled. --- - docs/guestfs-testing.pod | 21 ------- + docs/guestfs-testing.pod | 20 ------- fish/guestfish.pod | 64 ++------------------- fish/test-add-uri.sh | 32 ----------- - generator/actions.ml | 50 +---------------- - src/drives.c | 8 +++ - src/guestfs.pod | 100 --------------------------------- + generator/actions_core.ml | 50 +---------------- + lib/drives.c | 8 +++ + lib/guestfs.pod | 100 --------------------------------- tests/disks/test-qemu-drive-libvirt.sh | 28 --------- tests/disks/test-qemu-drive.sh | 60 -------------------- - 8 files changed, 15 insertions(+), 348 deletions(-) + 8 files changed, 15 insertions(+), 347 deletions(-) diff --git a/docs/guestfs-testing.pod b/docs/guestfs-testing.pod -index 2528604..b8093ee 100644 +index 1e88ed4..ce64755 100644 --- a/docs/guestfs-testing.pod +++ b/docs/guestfs-testing.pod -@@ -117,27 +117,6 @@ image. To exit, type C. +@@ -113,26 +113,6 @@ image. To exit, type C. If you get an error, try enabling debugging (add C<-v> to the command line). Also make sure that L succeeds. -=head2 Try to open a remote guest image with guestfish. - --B this test requires S 1.22> and S 1.5>. -You may also have to disable libvirt by setting this: - - export LIBGUESTFS_BACKEND=direct @@ -65,7 +64,7 @@ index 2528604..b8093ee 100644 Run L on guests or disk images: diff --git a/fish/guestfish.pod b/fish/guestfish.pod -index c6f5663..05105e8 100644 +index 3b71c3a..cbaaca5 100644 --- a/fish/guestfish.pod +++ b/fish/guestfish.pod @@ -131,9 +131,9 @@ To list what is available do: @@ -80,7 +79,7 @@ index c6f5663..05105e8 100644 =head2 Remote control -@@ -1118,12 +1118,12 @@ L>. +@@ -1120,12 +1120,12 @@ L>. On the command line, you can use the I<-a> option to add network block devices using a URI-style format, for example: @@ -95,7 +94,7 @@ index c6f5663..05105e8 100644 The possible I<-a URI> formats are described below. -@@ -1133,40 +1133,6 @@ The possible I<-a URI> formats are described below. +@@ -1135,40 +1135,6 @@ The possible I<-a URI> formats are described below. Add the local disk image (or device) called F. @@ -136,7 +135,7 @@ index c6f5663..05105e8 100644 =head2 B<-a nbd://example.com[:port]> =head2 B<-a nbd://example.com[:port]/exportname> -@@ -1201,28 +1167,6 @@ The equivalent API command would be: +@@ -1203,28 +1169,6 @@ The equivalent API command would be: > add pool/disk protocol:rbd server:tcp:example.com:port @@ -166,11 +165,11 @@ index c6f5663..05105e8 100644 Some (not all) long-running commands send progress notification diff --git a/fish/test-add-uri.sh b/fish/test-add-uri.sh -index 07b68c4..48c12b8 100755 +index 756df99..8f84fd3 100755 --- a/fish/test-add-uri.sh +++ b/fish/test-add-uri.sh -@@ -37,14 +37,6 @@ function fail () - $VG guestfish -x -a file://$(pwd)/test-add-uri.img test-add-uri.out 2>&1 +@@ -40,14 +40,6 @@ function fail () + $VG guestfish -x -a file://$abs_builddir/test-add-uri.img test-add-uri.out 2>&1 grep -sq 'add_drive ".*/test-add-uri.img"' test-add-uri.out || fail -# curl @@ -184,7 +183,7 @@ index 07b68c4..48c12b8 100755 # NBD $VG guestfish -x -a nbd://example.com test-add-uri.out 2>&1 grep -sq 'add_drive "" "protocol:nbd" "server:tcp:example.com"' test-add-uri.out || fail -@@ -64,29 +56,5 @@ grep -sq 'add_drive "pool/disk" "protocol:rbd" "server:tcp:example.com:6789"' te +@@ -67,29 +59,5 @@ grep -sq 'add_drive "pool/disk" "protocol:rbd" "server:tcp:example.com:6789"' te $VG guestfish -x -a rbd:///pool/disk test-add-uri.out 2>&1 grep -sq 'add_drive "pool/disk" "protocol:rbd"' test-add-uri.out || fail @@ -214,11 +213,11 @@ index 07b68c4..48c12b8 100755 - rm test-add-uri.out rm test-add-uri.img -diff --git a/generator/actions.ml b/generator/actions.ml -index 9248ded..dfeb34c 100644 ---- a/generator/actions.ml -+++ b/generator/actions.ml -@@ -1439,29 +1439,6 @@ F is interpreted as a local file or device. +diff --git a/generator/actions_core.ml b/generator/actions_core.ml +index 2567981..e4b2b8c 100644 +--- a/generator/actions_core.ml ++++ b/generator/actions_core.ml +@@ -522,29 +522,6 @@ F is interpreted as a local file or device. This is the default if the optional protocol parameter is omitted. @@ -248,7 +247,7 @@ index 9248ded..dfeb34c 100644 =item C Connect to the Network Block Device server. -@@ -1478,22 +1455,6 @@ The C parameter may be supplied. See below. +@@ -561,22 +538,6 @@ The C parameter may be supplied. See below. See also: L. @@ -271,7 +270,7 @@ index 9248ded..dfeb34c 100644 =back =item C -@@ -1504,13 +1465,8 @@ is a list of server(s). +@@ -587,13 +548,8 @@ is a list of server(s). Protocol Number of servers required -------- -------------------------- file List must be empty or param not used at all @@ -285,7 +284,7 @@ index 9248ded..dfeb34c 100644 Each list element is a string specifying a server. The string must be in one of the following formats: -@@ -1526,10 +1482,10 @@ for the protocol is used (see F). +@@ -609,10 +565,10 @@ for the protocol is used (see F). =item C @@ -299,11 +298,11 @@ index 9248ded..dfeb34c 100644 is attempted for ceph. But note this sometimes may give unexpected results, for example if using the libvirt backend and if the libvirt backend is configured to start the qemu appliance as a special user such as C. If in doubt, -diff --git a/src/drives.c b/src/drives.c -index 5b54eca..309e312 100644 ---- a/src/drives.c -+++ b/src/drives.c -@@ -161,6 +161,7 @@ create_drive_non_file (guestfs_h *g, +diff --git a/lib/drives.c b/lib/drives.c +index 4cf41cd..2d86ca8 100644 +--- a/lib/drives.c ++++ b/lib/drives.c +@@ -165,6 +165,7 @@ create_drive_non_file (guestfs_h *g, return drv; } @@ -311,7 +310,7 @@ index 5b54eca..309e312 100644 static struct drive * create_drive_curl (guestfs_h *g, const struct drive_create_data *data) -@@ -219,6 +220,7 @@ create_drive_gluster (guestfs_h *g, +@@ -223,6 +224,7 @@ create_drive_gluster (guestfs_h *g, return create_drive_non_file (g, data); } @@ -319,7 +318,7 @@ index 5b54eca..309e312 100644 static int nbd_port (void) -@@ -287,6 +289,7 @@ create_drive_rbd (guestfs_h *g, +@@ -291,6 +293,7 @@ create_drive_rbd (guestfs_h *g, return create_drive_non_file (g, data); } @@ -327,15 +326,15 @@ index 5b54eca..309e312 100644 static struct drive * create_drive_sheepdog (guestfs_h *g, const struct drive_create_data *data) -@@ -387,6 +390,7 @@ create_drive_iscsi (guestfs_h *g, +@@ -391,6 +394,7 @@ create_drive_iscsi (guestfs_h *g, return create_drive_non_file (g, data); } +#endif /* DISABLED IN RHEL 7 */ - /* Traditionally you have been able to use /dev/null as a filename, as - * many times as you like. Ancient KVM (RHEL 5) cannot handle adding -@@ -840,6 +844,7 @@ guestfs_impl_add_drive_opts (guestfs_h *g, const char *filename, + /** + * Create the special F drive. +@@ -826,6 +830,7 @@ guestfs_impl_add_drive_opts (guestfs_h *g, const char *filename, drv = create_drive_file (g, &data); } } @@ -343,7 +342,7 @@ index 5b54eca..309e312 100644 else if (STREQ (protocol, "ftp")) { data.protocol = drive_protocol_ftp; drv = create_drive_curl (g, &data); -@@ -864,6 +869,7 @@ guestfs_impl_add_drive_opts (guestfs_h *g, const char *filename, +@@ -850,6 +855,7 @@ guestfs_impl_add_drive_opts (guestfs_h *g, const char *filename, data.protocol = drive_protocol_iscsi; drv = create_drive_iscsi (g, &data); } @@ -351,7 +350,7 @@ index 5b54eca..309e312 100644 else if (STREQ (protocol, "nbd")) { data.protocol = drive_protocol_nbd; drv = create_drive_nbd (g, &data); -@@ -872,6 +878,7 @@ guestfs_impl_add_drive_opts (guestfs_h *g, const char *filename, +@@ -858,6 +864,7 @@ guestfs_impl_add_drive_opts (guestfs_h *g, const char *filename, data.protocol = drive_protocol_rbd; drv = create_drive_rbd (g, &data); } @@ -359,7 +358,7 @@ index 5b54eca..309e312 100644 else if (STREQ (protocol, "sheepdog")) { data.protocol = drive_protocol_sheepdog; drv = create_drive_sheepdog (g, &data); -@@ -884,6 +891,7 @@ guestfs_impl_add_drive_opts (guestfs_h *g, const char *filename, +@@ -870,6 +877,7 @@ guestfs_impl_add_drive_opts (guestfs_h *g, const char *filename, data.protocol = drive_protocol_tftp; drv = create_drive_curl (g, &data); } @@ -367,11 +366,11 @@ index 5b54eca..309e312 100644 else { error (g, _("unknown protocol '%s'"), protocol); drv = NULL; /*FALLTHROUGH*/ -diff --git a/src/guestfs.pod b/src/guestfs.pod -index dc41864..17d9a62 100644 ---- a/src/guestfs.pod -+++ b/src/guestfs.pod -@@ -705,70 +705,6 @@ servers. The server string is documented in +diff --git a/lib/guestfs.pod b/lib/guestfs.pod +index e02cda6..41aa7ad 100644 +--- a/lib/guestfs.pod ++++ b/lib/guestfs.pod +@@ -714,70 +714,6 @@ servers. The server string is documented in L. The C and C parameters are also optional, and if not given, then no authentication will be used. @@ -442,7 +441,7 @@ index dc41864..17d9a62 100644 =head3 NETWORK BLOCK DEVICE Libguestfs can access Network Block Device (NBD) disks remotely. -@@ -831,42 +767,6 @@ L +@@ -840,42 +776,6 @@ L =back @@ -486,10 +485,10 @@ index dc41864..17d9a62 100644 Libguestfs has APIs for inspecting an unknown disk image to find out diff --git a/tests/disks/test-qemu-drive-libvirt.sh b/tests/disks/test-qemu-drive-libvirt.sh -index 215a99e..894e9df 100755 +index a1a7b89..aefd7cb 100755 --- a/tests/disks/test-qemu-drive-libvirt.sh +++ b/tests/disks/test-qemu-drive-libvirt.sh -@@ -76,34 +76,6 @@ check_output +@@ -64,34 +64,6 @@ check_output grep -sq -- '-drive file=rbd:abc-def/ghi-jkl:auth_supported=none,' "$DEBUG_QEMU_FILE" || fail rm "$DEBUG_QEMU_FILE" @@ -521,14 +520,14 @@ index 215a99e..894e9df 100755 -grep -sq -- '-drive file=sheepdog:volume,' "$DEBUG_QEMU_FILE" || fail -rm "$DEBUG_QEMU_FILE" - - # To do: + # Local, stored in a pool. - # HTTP - curl not yet supported by libvirt + $guestfish -d pool1 run ||: diff --git a/tests/disks/test-qemu-drive.sh b/tests/disks/test-qemu-drive.sh -index bcb7841..c0239ff 100755 +index 19dd60a..583e031 100755 --- a/tests/disks/test-qemu-drive.sh +++ b/tests/disks/test-qemu-drive.sh -@@ -61,45 +61,6 @@ check_output +@@ -62,45 +62,6 @@ check_output grep -sq -- '-drive file=rbd:abc-def/ghi-jkl:auth_supported=none,' "$DEBUG_QEMU_FILE" || fail rm "$DEBUG_QEMU_FILE" @@ -574,7 +573,7 @@ index bcb7841..c0239ff 100755 # NBD. guestfish < Date: Fri, 19 Sep 2014 13:38:20 +0100 Subject: [PATCH] RHEL 7: Remove User-Mode Linux (RHBZ#1144197). This isn't supported in RHEL 7. --- - src/launch-uml.c | 13 +++++++++++++ + lib/launch-uml.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) -diff --git a/src/launch-uml.c b/src/launch-uml.c -index 0e2149e..38be7a8 100644 ---- a/src/launch-uml.c -+++ b/src/launch-uml.c +diff --git a/lib/launch-uml.c b/lib/launch-uml.c +index c391af3..3033daa 100644 +--- a/lib/launch-uml.c ++++ b/lib/launch-uml.c @@ -44,7 +44,9 @@ struct backend_uml_data { char umid[UML_UMID_LEN+1]; /* umid=<...> unique ID. */ }; @@ -48,7 +48,7 @@ index 0e2149e..38be7a8 100644 struct backend_uml_data *data = datav; CLEANUP_FREE_STRINGSBUF DECLARE_STRINGSBUF (cmdline); int console_sock = -1, daemon_sock = -1; -@@ -488,8 +498,10 @@ launch_uml (guestfs_h *g, void *datav, const char *arg) +@@ -486,8 +496,10 @@ launch_uml (guestfs_h *g, void *datav, const char *arg) } g->state = CONFIG; return -1; @@ -59,7 +59,7 @@ index 0e2149e..38be7a8 100644 /* This is called from the forked subprocess just before vmlinux runs, * so it can just print the message straight to stderr, where it will * be picked up and funnelled through the usual appliance event API. -@@ -519,6 +531,7 @@ print_vmlinux_command_line (guestfs_h *g, char **argv) +@@ -517,6 +529,7 @@ print_vmlinux_command_line (guestfs_h *g, char **argv) fputc ('\n', stderr); } @@ -68,5 +68,5 @@ index 0e2149e..38be7a8 100644 static int shutdown_uml (guestfs_h *g, void *datav, int check_for_errors) -- -1.8.3.1 +2.9.4 diff --git a/SOURCES/0005-RHEL-7-v2v-Select-correct-qemu-binary-for-o-qemu-mod.patch b/SOURCES/0005-RHEL-7-v2v-Select-correct-qemu-binary-for-o-qemu-mod.patch index 65138cc..0481f61 100644 --- a/SOURCES/0005-RHEL-7-v2v-Select-correct-qemu-binary-for-o-qemu-mod.patch +++ b/SOURCES/0005-RHEL-7-v2v-Select-correct-qemu-binary-for-o-qemu-mod.patch @@ -1,4 +1,4 @@ -From dde41f2d45bcefb187d471deaf989a262a1f37f8 Mon Sep 17 00:00:00 2001 +From 9185b9edc455e72ae44abc98b98aaef79b0a7a69 Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Sun, 28 Sep 2014 19:14:43 +0100 Subject: [PATCH] RHEL 7: v2v: Select correct qemu binary for -o qemu mode @@ -12,22 +12,22 @@ Note that we don't support people running qemu directly like this. It's just for quick testing of converted VMs, and to help us with support cases. --- - v2v/output_qemu.ml | 2 +- + v2v/qemu_command.ml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) -diff --git a/v2v/output_qemu.ml b/v2v/output_qemu.ml -index 9bef83b..d079ccd 100644 ---- a/v2v/output_qemu.ml -+++ b/v2v/output_qemu.ml -@@ -76,7 +76,7 @@ object - fpf "\n" - ); +diff --git a/v2v/qemu_command.ml b/v2v/qemu_command.ml +index ccdda8a..19757e0 100644 +--- a/v2v/qemu_command.ml ++++ b/v2v/qemu_command.ml +@@ -32,7 +32,7 @@ and arg = + | Commas of string * string list -- fpf "qemu-system-%s" guestcaps.gcaps_arch; -+ fpf "/usr/libexec/qemu-kvm"; - fpf "%s-no-user-config -nodefaults" nl; - fpf "%s-name %s" nl (quote source.s_name); - fpf "%s-machine accel=kvm:tcg" nl; + let create ?(arch = "x86_64") () = +- { cmd = "qemu-system-" ^ arch; args = [] } ++ { cmd = "/usr/libexec/qemu-kvm"; args = [] } + + let flag t k = + assert (String.is_prefix k "-"); -- -1.8.3.1 +2.9.4 diff --git a/SOURCES/0006-RHEL-7-v2v-Disable-the-qemu-boot-option-RHBZ-1147313.patch b/SOURCES/0006-RHEL-7-v2v-Disable-the-qemu-boot-option-RHBZ-1147313.patch index 03d6b7d..d2f5dc3 100644 --- a/SOURCES/0006-RHEL-7-v2v-Disable-the-qemu-boot-option-RHBZ-1147313.patch +++ b/SOURCES/0006-RHEL-7-v2v-Disable-the-qemu-boot-option-RHBZ-1147313.patch @@ -1,4 +1,4 @@ -From a613c11f034b736741b053e65823935161961ddd Mon Sep 17 00:00:00 2001 +From d4f2cb392ed4b88b14f3c3f8e08b02b5f52a9430 Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Tue, 30 Sep 2014 10:50:27 +0100 Subject: [PATCH] RHEL 7: v2v: Disable the --qemu-boot option (RHBZ#1147313). @@ -14,28 +14,28 @@ qemu script. 2 files changed, 2 insertions(+), 14 deletions(-) diff --git a/v2v/cmdline.ml b/v2v/cmdline.ml -index e8785c4..32eb873 100644 +index c294e57..9f02098 100644 --- a/v2v/cmdline.ml +++ b/v2v/cmdline.ml -@@ -214,7 +214,6 @@ let parse_cmdline () = - "--password-file", Arg.String (set_string_option_once "--password-file" password_file), - "file " ^ s_"Use password from file"; - "--print-source", Arg.Set print_source, " " ^ s_"Print source and stop"; -- "--qemu-boot", Arg.Set qemu_boot, " " ^ s_"Boot in qemu (-o qemu only)"; - "--root", Arg.String set_root_choice,"ask|... " ^ s_"How to choose root filesystem"; - "--vdsm-image-uuid", Arg.String add_vdsm_image_uuid, "uuid " ^ s_"Output image UUID(s)"; - "--vdsm-vol-uuid", Arg.String add_vdsm_vol_uuid, "uuid " ^ s_"Output vol UUID(s)"; -@@ -416,6 +415,8 @@ read the man page virt-v2v(1). +@@ -199,7 +199,6 @@ let parse_cmdline () = + [ L"password-file" ], Getopt.String ("file", set_string_option_once "--password-file" password_file), + s_"Use password from file"; + [ L"print-source" ], Getopt.Set print_source, s_"Print source and stop"; +- [ L"qemu-boot" ], Getopt.Set qemu_boot, s_"Boot in qemu (-o qemu only)"; + [ L"root" ], Getopt.String ("ask|... ", set_root_choice), s_"How to choose root filesystem"; + [ L"vdsm-compat" ], Getopt.Symbol ("0.10|1.1", ["0.10"; "1.1"], set_vdsm_compat), s_"Write qcow2 with compat=0.10|1.1"; + [ L"vdsm-image-uuid" ], Getopt.String ("uuid", add_vdsm_image_uuid), s_"Output image UUID(s)"; +@@ -403,6 +402,8 @@ read the man page virt-v2v(1). | Some d when not (is_directory d) -> error (f_"-os %s: output directory does not exist or is not a directory") d | Some d -> d in + if qemu_boot then + error (f_"-o qemu: the --qemu-boot option cannot be used in RHEL"); - Output_qemu.output_qemu os qemu_boot + Output_qemu.output_qemu os qemu_boot, + output_format, output_alloc - | `RHEV -> diff --git a/v2v/virt-v2v.pod b/v2v/virt-v2v.pod -index 0cde486..dcbaec2 100644 +index 838b598..79c742e 100644 --- a/v2v/virt-v2v.pod +++ b/v2v/virt-v2v.pod @@ -145,11 +145,6 @@ Since F contains the path(s) to the guest disk @@ -50,17 +50,17 @@ index 0cde486..dcbaec2 100644 =head1 SUPPORT MATRIX =head2 Hypervisors (Input) -@@ -478,9 +473,6 @@ This is similar to I<-o local>, except that a shell script is written +@@ -466,9 +461,6 @@ This is similar to I<-o local>, except that a shell script is written which you can use to boot the guest in qemu. The converted disks and shell script are written to the directory specified by I<-os>. -When using this output mode, you can also specify the I<--qemu-boot> -option which boots the guest under qemu immediately. - - =item B<-o rhev> + =item B<-o> B - Set the output method to I. -@@ -566,11 +558,6 @@ Print information about the source guest and stop. This option is + This is the same as I<-o rhv>. +@@ -558,11 +550,6 @@ Print information about the source guest and stop. This option is useful when you are setting up network and bridge maps. See L. @@ -73,5 +73,5 @@ index 0cde486..dcbaec2 100644 =item B<--quiet> -- -1.8.3.1 +2.9.4 diff --git a/SOURCES/0007-RHEL-7-Revert-tests-rsync-Skip-this-test-when-the-ba.patch b/SOURCES/0007-RHEL-7-Revert-tests-rsync-Skip-this-test-when-the-ba.patch index 687cec7..1a74e54 100644 --- a/SOURCES/0007-RHEL-7-Revert-tests-rsync-Skip-this-test-when-the-ba.patch +++ b/SOURCES/0007-RHEL-7-Revert-tests-rsync-Skip-this-test-when-the-ba.patch @@ -1,4 +1,4 @@ -From bad8f20afb430335fe956354233dc5b7fc2d583c Mon Sep 17 00:00:00 2001 +From d40e0b93a58edc9c67184e0108731556bc44b46f Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Thu, 2 Oct 2014 16:44:00 +0100 Subject: [PATCH] RHEL 7: Revert "tests: rsync: Skip this test when the backend @@ -10,12 +10,12 @@ This reverts commit 765dc6237ce7b93dd2f33d99be53eae92e048a7a. 1 file changed, 7 insertions(+), 28 deletions(-) diff --git a/tests/rsync/test-rsync.sh b/tests/rsync/test-rsync.sh -index c7bfa24..214b5cd 100755 +index c6d98cf..2463962 100755 --- a/tests/rsync/test-rsync.sh +++ b/tests/rsync/test-rsync.sh -@@ -33,33 +33,10 @@ if ! rsync --help >/dev/null 2>&1; then - exit 77 - fi +@@ -26,33 +26,10 @@ skip_if_skipped + skip_unless rsync --help + skip_unless_feature_available rsync -# Get host IP address. XXX Bit of a hack. -backend="$(guestfish get-backend)" @@ -49,9 +49,9 @@ index c7bfa24..214b5cd 100755 + exit 77 +fi - # If rsync is not available, bail. - if ! guestfish -a /dev/null run : available rsync; then -@@ -79,7 +56,7 @@ port="$(awk 'BEGIN{srand(); print 65000+int(500*rand())}' rsyncd.conf < Date: Thu, 2 Oct 2014 16:44:04 +0100 Subject: [PATCH] RHEL 7: Revert "appliance: Change example ping lines to ping @@ -10,10 +10,10 @@ This reverts commit 07c0926b588db5c86214917b609c2f477c817c0e. 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/appliance/init b/appliance/init -index 311a0d4..a36d52b 100755 +index 8a26e1a..624e20f 100755 --- a/appliance/init +++ b/appliance/init -@@ -146,7 +146,8 @@ if test "$guestfs_verbose" = 1; then +@@ -154,7 +154,8 @@ if test "$guestfs_verbose" = 1 && test "$guestfs_boot_analysis" != 1; then date echo -n "clocksource: " cat /sys/devices/system/clocksource/clocksource0/current_clocksource @@ -24,5 +24,5 @@ index 311a0d4..a36d52b 100755 echo -n "uptime: "; cat /proc/uptime fi -- -1.8.3.1 +2.9.4 diff --git a/SOURCES/0009-RHEL-7-Revert-launch-libvirt-Use-qemu-bridge-helper-.patch b/SOURCES/0009-RHEL-7-Revert-launch-libvirt-Use-qemu-bridge-helper-.patch index 7cd408b..fbfbaa9 100644 --- a/SOURCES/0009-RHEL-7-Revert-launch-libvirt-Use-qemu-bridge-helper-.patch +++ b/SOURCES/0009-RHEL-7-Revert-launch-libvirt-Use-qemu-bridge-helper-.patch @@ -1,4 +1,4 @@ -From 59f2770eb35f03d61fc708a6241628c83c4f786a Mon Sep 17 00:00:00 2001 +From 706ec2c841cda0de58a52001b1567d2b72fdacdf Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Thu, 2 Oct 2014 16:44:07 +0100 Subject: [PATCH] RHEL 7: Revert "launch: libvirt: Use qemu-bridge-helper to @@ -6,15 +6,15 @@ Subject: [PATCH] RHEL 7: Revert "launch: libvirt: Use qemu-bridge-helper to This reverts commit 224de20b9a8d5ea56f6337f19b4ca237bb88eca0. --- - src/guestfs.pod | 10 ---------- - src/launch-libvirt.c | 44 +++++++++++++++++++++----------------------- + lib/guestfs.pod | 10 ---------- + lib/launch-libvirt.c | 44 +++++++++++++++++++++----------------------- 2 files changed, 21 insertions(+), 33 deletions(-) -diff --git a/src/guestfs.pod b/src/guestfs.pod -index 17d9a62..af30406 100644 ---- a/src/guestfs.pod -+++ b/src/guestfs.pod -@@ -1432,16 +1432,6 @@ On Fedora, install C for the C file +diff --git a/lib/guestfs.pod b/lib/guestfs.pod +index 41aa7ad..6443e3b 100644 +--- a/lib/guestfs.pod ++++ b/lib/guestfs.pod +@@ -1441,16 +1441,6 @@ On Fedora, install C for the C file (containing symbols). Make sure the symbols precisely match the kernel being used. @@ -31,10 +31,10 @@ index 17d9a62..af30406 100644 =head2 ATTACHING TO RUNNING DAEMONS I This is B and has a tendency to eat -diff --git a/src/launch-libvirt.c b/src/launch-libvirt.c -index ec23fab..38ca4a5 100644 ---- a/src/launch-libvirt.c -+++ b/src/launch-libvirt.c +diff --git a/lib/launch-libvirt.c b/lib/launch-libvirt.c +index 168bba6..bc5d4d2 100644 +--- a/lib/launch-libvirt.c ++++ b/lib/launch-libvirt.c @@ -115,7 +115,6 @@ struct backend_libvirt_data { char *selinux_label; char *selinux_imagelabel; @@ -42,8 +42,8 @@ index ec23fab..38ca4a5 100644 - char *network_bridge; char name[DOMAIN_NAME_LEN]; /* random name */ bool is_kvm; /* false = qemu, true = kvm (from capabilities)*/ - unsigned long libvirt_version; /* libvirt version */ -@@ -422,12 +421,6 @@ launch_libvirt (guestfs_h *g, void *datav, const char *libvirt_uri) + struct version libvirt_version; /* libvirt version */ +@@ -436,12 +435,6 @@ launch_libvirt (guestfs_h *g, void *datav, const char *libvirt_uri) guestfs_get_backend_setting (g, "internal_libvirt_imagelabel"); data->selinux_norelabel_disks = guestfs_int_get_backend_setting_bool (g, "internal_libvirt_norelabel_disks"); @@ -56,7 +56,7 @@ index ec23fab..38ca4a5 100644 guestfs_pop_error_handler (g); if (g->enable_network && check_bridge_exists (g, data->network_bridge) == -1) -@@ -1366,19 +1359,6 @@ construct_libvirt_xml_devices (guestfs_h *g, +@@ -1384,19 +1377,6 @@ construct_libvirt_xml_devices (guestfs_h *g, } end_element (); } end_element (); @@ -73,10 +73,10 @@ index ec23fab..38ca4a5 100644 - } end_element (); - } - - } end_element (); /* */ - - return 0; -@@ -1741,6 +1721,27 @@ construct_libvirt_xml_qemu_cmdline (guestfs_h *g, + /* Libvirt adds some devices by default. Indicate to libvirt + * that we don't want them. + */ +@@ -1771,6 +1751,27 @@ construct_libvirt_xml_qemu_cmdline (guestfs_h *g, attribute ("value", tmpdir); } end_element (); @@ -104,7 +104,7 @@ index ec23fab..38ca4a5 100644 /* The qemu command line arguments requested by the caller. */ for (hp = g->hv_params; hp; hp = hp->next) { start_element ("qemu:arg") { -@@ -2056,9 +2057,6 @@ shutdown_libvirt (guestfs_h *g, void *datav, int check_for_errors) +@@ -2096,9 +2097,6 @@ shutdown_libvirt (guestfs_h *g, void *datav, int check_for_errors) free (data->selinux_imagelabel); data->selinux_imagelabel = NULL; @@ -115,5 +115,5 @@ index ec23fab..38ca4a5 100644 free (data->secrets[i].secret); free (data->secrets); -- -1.8.3.1 +2.9.4 diff --git a/SOURCES/0010-RHEL-7-Revert-launch-libvirt-Better-error-when-bridg.patch b/SOURCES/0010-RHEL-7-Revert-launch-libvirt-Better-error-when-bridg.patch index ffb289b..9176533 100644 --- a/SOURCES/0010-RHEL-7-Revert-launch-libvirt-Better-error-when-bridg.patch +++ b/SOURCES/0010-RHEL-7-Revert-launch-libvirt-Better-error-when-bridg.patch @@ -1,4 +1,4 @@ -From e43178e3a02b89cf7119be371c9eab4b8101bff3 Mon Sep 17 00:00:00 2001 +From 39c453f02083fa1b17a826a3b44b3405b601d792 Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Mon, 21 Sep 2015 12:38:50 -0400 Subject: [PATCH] RHEL 7: Revert "launch: libvirt: Better error when bridge / @@ -6,14 +6,14 @@ Subject: [PATCH] RHEL 7: Revert "launch: libvirt: Better error when bridge / This reverts commit edcd02a965ae6675c0ee9ecd8d98a1a641c6ef60. --- - src/launch-libvirt.c | 47 ----------------------------------------------- + lib/launch-libvirt.c | 47 ----------------------------------------------- 1 file changed, 47 deletions(-) -diff --git a/src/launch-libvirt.c b/src/launch-libvirt.c -index 38ca4a5..4b87301 100644 ---- a/src/launch-libvirt.c -+++ b/src/launch-libvirt.c -@@ -156,7 +156,6 @@ static int is_blk (const char *path); +diff --git a/lib/launch-libvirt.c b/lib/launch-libvirt.c +index bc5d4d2..0c2879d 100644 +--- a/lib/launch-libvirt.c ++++ b/lib/launch-libvirt.c +@@ -155,7 +155,6 @@ static int is_blk (const char *path); static void ignore_errors (void *ignore, virErrorPtr ignore2); static void set_socket_create_context (guestfs_h *g); static void clear_socket_create_context (guestfs_h *g); @@ -21,7 +21,7 @@ index 38ca4a5..4b87301 100644 #if HAVE_LIBSELINUX static void selinux_warning (guestfs_h *g, const char *func, const char *selinux_op, const char *data); -@@ -423,9 +422,6 @@ launch_libvirt (guestfs_h *g, void *datav, const char *libvirt_uri) +@@ -437,9 +436,6 @@ launch_libvirt (guestfs_h *g, void *datav, const char *libvirt_uri) guestfs_int_get_backend_setting_bool (g, "internal_libvirt_norelabel_disks"); guestfs_pop_error_handler (g); @@ -31,7 +31,7 @@ index 38ca4a5..4b87301 100644 /* Locate and/or build the appliance. */ TRACE0 (launch_build_libvirt_appliance_start); -@@ -1979,49 +1975,6 @@ is_blk (const char *path) +@@ -2009,49 +2005,6 @@ is_blk (const char *path) return S_ISBLK (statbuf.st_mode); } @@ -82,5 +82,5 @@ index 38ca4a5..4b87301 100644 ignore_errors (void *ignore, virErrorPtr ignore2) { -- -1.8.3.1 +2.9.4 diff --git a/SOURCES/0011-RHEL-7-Revert-appliance-add-dhcp-client-on-Mageia.patch b/SOURCES/0011-RHEL-7-Revert-appliance-add-dhcp-client-on-Mageia.patch index cb923f4..fb9c9d3 100644 --- a/SOURCES/0011-RHEL-7-Revert-appliance-add-dhcp-client-on-Mageia.patch +++ b/SOURCES/0011-RHEL-7-Revert-appliance-add-dhcp-client-on-Mageia.patch @@ -1,4 +1,4 @@ -From 6d6400678ed8c13071ff78e955e811182757037c Mon Sep 17 00:00:00 2001 +From 8d2911ce34aca7ba67c9921fb8cb9207e2215fa8 Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Fri, 10 Oct 2014 17:45:39 +0100 Subject: [PATCH] RHEL 7: Revert "appliance: add dhcp-client on Mageia" @@ -9,10 +9,10 @@ This reverts commit 8f3a2ca5358d5601be7a9247b6d08193c4e2da46. 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appliance/packagelist.in b/appliance/packagelist.in -index 70af72d2..4696a73 100644 +index 8ed3afe..0477bfc 100644 --- a/appliance/packagelist.in +++ b/appliance/packagelist.in -@@ -184,7 +184,7 @@ ifelse(MAGEIA,1, +@@ -188,7 +188,7 @@ ifelse(MAGEIA,1, chkconfig /* for /etc/init.d */ cdrkit-genisoimage cdrkit-isotools @@ -22,5 +22,5 @@ index 70af72d2..4696a73 100644 gfs2-utils grub -- -1.8.3.1 +2.9.4 diff --git a/SOURCES/0012-RHEL-7-Revert-appliance-add-dhcpcd-and-gptfdisk-on-A.patch b/SOURCES/0012-RHEL-7-Revert-appliance-add-dhcpcd-and-gptfdisk-on-A.patch index e3584f3..61105e3 100644 --- a/SOURCES/0012-RHEL-7-Revert-appliance-add-dhcpcd-and-gptfdisk-on-A.patch +++ b/SOURCES/0012-RHEL-7-Revert-appliance-add-dhcpcd-and-gptfdisk-on-A.patch @@ -1,4 +1,4 @@ -From a9e90c5dd3b73d14f1312a8ee07b0eae795d0596 Mon Sep 17 00:00:00 2001 +From b70a988f7ecc6c446d88c1172332fe7c3c74dec3 Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Fri, 10 Oct 2014 17:45:48 +0100 Subject: [PATCH] RHEL 7: Revert "appliance: add dhcpcd and gptfdisk on @@ -10,12 +10,12 @@ This reverts commit 979e7a49147f4ef1387337db262bf7ea12f627e3. 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/appliance/packagelist.in b/appliance/packagelist.in -index 4696a73..306b920 100644 +index 0477bfc..961a2a3 100644 --- a/appliance/packagelist.in +++ b/appliance/packagelist.in -@@ -102,8 +102,7 @@ ifelse(ARCHLINUX,1, - augeas +@@ -105,8 +105,7 @@ ifelse(ARCHLINUX,1, cdrkit + cdrtools cryptsetup - dhcpcd - gptfdisk @@ -24,5 +24,5 @@ index 4696a73..306b920 100644 hivex iproute2 -- -1.8.3.1 +2.9.4 diff --git a/SOURCES/0013-RHEL-7-Revert-appliance-Use-dhclient-or-dhcpcd-inste.patch b/SOURCES/0013-RHEL-7-Revert-appliance-Use-dhclient-or-dhcpcd-inste.patch index 9cee57f..b010896 100644 --- a/SOURCES/0013-RHEL-7-Revert-appliance-Use-dhclient-or-dhcpcd-inste.patch +++ b/SOURCES/0013-RHEL-7-Revert-appliance-Use-dhclient-or-dhcpcd-inste.patch @@ -1,4 +1,4 @@ -From e2d8231c9ba4ac839f303b7e44f135506c4098fa Mon Sep 17 00:00:00 2001 +From 1b565df653cff8421e7af40728e27c79d563d474 Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Fri, 10 Oct 2014 17:46:02 +0100 Subject: [PATCH] RHEL 7: Revert "appliance: Use dhclient or dhcpcd instead of @@ -11,10 +11,10 @@ This reverts commit 67e6f32a240c7c234e6af637c1cd324b36a82cd3. 2 files changed, 6 insertions(+), 16 deletions(-) diff --git a/appliance/init b/appliance/init -index a36d52b..ff8f5df 100755 +index 624e20f..2e18be4 100755 --- a/appliance/init +++ b/appliance/init -@@ -109,15 +109,12 @@ eval `grep -Eo 'guestfs_channel=[^[:space:]]+' /proc/cmdline` +@@ -118,15 +118,12 @@ shopt -u nullglob ip addr add 127.0.0.1/8 brd + dev lo scope host ip link set dev lo up @@ -37,7 +37,7 @@ index a36d52b..ff8f5df 100755 # Scan for MDs. mdadm -As --auto=yes --run diff --git a/appliance/packagelist.in b/appliance/packagelist.in -index 306b920..e93e5e8 100644 +index 961a2a3..b437b02 100644 --- a/appliance/packagelist.in +++ b/appliance/packagelist.in @@ -26,7 +26,6 @@ ifelse(REDHAT,1, @@ -48,23 +48,23 @@ index 306b920..e93e5e8 100644 genisoimage gfs-utils gfs2-utils -@@ -72,7 +71,6 @@ dnl iproute has been renamed to iproute2 +@@ -73,7 +72,6 @@ dnl iproute has been renamed to iproute2 iputils-ping iputils-arping iputils-tracepath - isc-dhcp-client + ldmtool libaugeas0 libc-bin - libcap2 -@@ -102,7 +100,6 @@ ifelse(ARCHLINUX,1, - augeas +@@ -105,7 +103,6 @@ ifelse(ARCHLINUX,1, cdrkit + cdrtools cryptsetup - dhclient grub hivex iproute2 -@@ -131,8 +128,6 @@ ifelse(SUSE,1, +@@ -133,8 +130,6 @@ ifelse(SUSE,1, augeas-lenses btrfsprogs cryptsetup @@ -73,7 +73,7 @@ index 306b920..e93e5e8 100644 genisoimage glibc-locale gptfdisk -@@ -156,7 +151,6 @@ ifelse(FRUGALWARE,1, +@@ -160,7 +155,6 @@ ifelse(FRUGALWARE,1, augeas cryptsetup-luks cdrkit @@ -81,7 +81,7 @@ index 306b920..e93e5e8 100644 grub2 hfsplus iproute2 -@@ -183,7 +177,6 @@ ifelse(MAGEIA,1, +@@ -187,7 +181,6 @@ ifelse(MAGEIA,1, chkconfig /* for /etc/init.d */ cdrkit-genisoimage cdrkit-isotools @@ -90,5 +90,5 @@ index 306b920..e93e5e8 100644 gfs2-utils grub -- -1.8.3.1 +2.9.4 diff --git a/SOURCES/0014-RHEL-7-Disable-alternate-Augeas-lenses.patch b/SOURCES/0014-RHEL-7-Disable-alternate-Augeas-lenses.patch new file mode 100644 index 0000000..60d4c93 --- /dev/null +++ b/SOURCES/0014-RHEL-7-Disable-alternate-Augeas-lenses.patch @@ -0,0 +1,84 @@ +From 08a8b9cf677d1c21890e14fcb34f49bf0800e912 Mon Sep 17 00:00:00 2001 +From: Pino Toscano +Date: Fri, 24 Oct 2014 16:33:50 +0100 +Subject: [PATCH] RHEL 7: Disable alternate Augeas lenses. + +These are included in the RHEL 7.1 augeas package, and therefore +not required in RHEL. + +See: +https://www.redhat.com/archives/libguestfs/2014-October/msg00220.html +--- + appliance/Makefile.am | 2 -- + daemon/augeas.c | 5 ++++- + daemon/lvm-filter.c | 4 ++-- + 3 files changed, 6 insertions(+), 5 deletions(-) + +diff --git a/appliance/Makefile.am b/appliance/Makefile.am +index 05b9d42..1e142cb 100644 +--- a/appliance/Makefile.am ++++ b/appliance/Makefile.am +@@ -92,8 +92,6 @@ supermin.d/daemon.tar.gz: ../daemon/guestfsd guestfs_lvm_conf.aug guestfs_shadow + rm -rf tmp-d + mkdir -p tmp-d$(DAEMON_SUPERMIN_DIR) tmp-d/etc tmp-d/usr/share/guestfs + ln ../daemon/guestfsd tmp-d$(DAEMON_SUPERMIN_DIR)/guestfsd +- ln $(srcdir)/guestfs_lvm_conf.aug tmp-d/usr/share/guestfs/guestfs_lvm_conf.aug +- ln $(srcdir)/guestfs_shadow.aug tmp-d/usr/share/guestfs/guestfs_shadow.aug + ( cd tmp-d && tar zcf - * ) > $@-t + rm -r tmp-d + mv $@-t $@ +diff --git a/daemon/augeas.c b/daemon/augeas.c +index 5adc959..dc5266e 100644 +--- a/daemon/augeas.c ++++ b/daemon/augeas.c +@@ -134,7 +134,7 @@ do_aug_init (const char *root, int flags) + } + + /* Pass AUG_NO_ERR_CLOSE so we can display detailed errors. */ +- aug = aug_init (buf, "/usr/share/guestfs/", flags | AUG_NO_ERR_CLOSE); ++ aug = aug_init (buf, NULL, flags | AUG_NO_ERR_CLOSE); + + if (!aug) { + reply_with_error ("augeas initialization failed"); +@@ -148,6 +148,8 @@ do_aug_init (const char *root, int flags) + return -1; + } + ++ /* We already have the needed lenses in RHEL 7 */ ++#if 0 + if (!augeas_is_version (1, 2, 1)) { + int r = aug_transform (aug, "guestfs_shadow", "/etc/shadow", + 0 /* = included */); +@@ -166,6 +168,7 @@ do_aug_init (const char *root, int flags) + } + } + } ++#endif + + return 0; + } +diff --git a/daemon/lvm-filter.c b/daemon/lvm-filter.c +index 5c9ce18..bd32626 100644 +--- a/daemon/lvm-filter.c ++++ b/daemon/lvm-filter.c +@@ -140,7 +140,7 @@ set_filter (char *const *filters) + * but do that only after having applied the transformation. + */ + const int flags = AUG_NO_ERR_CLOSE | AUG_NO_LOAD; +- aug = aug_init (lvm_system_dir, "/usr/share/guestfs/", flags); ++ aug = aug_init (lvm_system_dir, NULL, flags); + if (!aug) { + reply_with_error ("augeas initialization failed"); + return -1; +@@ -151,7 +151,7 @@ set_filter (char *const *filters) + return -1; + } + +- r = aug_transform (aug, "guestfs_lvm_conf", "/lvm/lvm.conf", ++ r = aug_transform (aug, "lvm", "/lvm/lvm.conf", + 0 /* = included */); + if (r == -1) { + AUGEAS_ERROR ("aug_transform"); +-- +2.9.4 + diff --git a/SOURCES/0014-RHEL-7-v2v-Disable-unconfiguration-of-VMware-drivers.patch b/SOURCES/0014-RHEL-7-v2v-Disable-unconfiguration-of-VMware-drivers.patch deleted file mode 100644 index e4473b6..0000000 --- a/SOURCES/0014-RHEL-7-v2v-Disable-unconfiguration-of-VMware-drivers.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 5af7ba1b2e7e833fc0cb1f0cbb6cbde0f4bb89fe Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Thu, 23 Oct 2014 08:41:56 +0100 -Subject: [PATCH] RHEL 7: v2v: Disable unconfiguration of VMware drivers on - Linux (RHBZ#1155610). - -This is currently broken and breaks conversions. For details see: -https://bugzilla.redhat.com/show_bug.cgi?id=1155610 ---- - v2v/convert_linux.ml | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/v2v/convert_linux.ml b/v2v/convert_linux.ml -index 17fda7c..bdbd06b 100644 ---- a/v2v/convert_linux.ml -+++ b/v2v/convert_linux.ml -@@ -540,6 +540,7 @@ let rec convert ~keep_serial_console (g : G.guestfs) inspect source = - msg - ) - -+(* Disabled in RHEL 7.1: see https://bugzilla.redhat.com/show_bug.cgi?id=1155610 - and unconfigure_vmware () = - (* Look for any configured VMware yum repos and disable them. *) - let repos = -@@ -630,6 +631,7 @@ let rec convert ~keep_serial_console (g : G.guestfs) inspect source = - warning (f_"VMware tools was detected, but uninstallation failed. The error message was: %s (ignored)") - msg - ) -+*) - - and unconfigure_citrix () = - let pkgs = -@@ -1385,7 +1387,7 @@ let rec convert ~keep_serial_console (g : G.guestfs) inspect source = - - unconfigure_xen (); - unconfigure_vbox (); -- unconfigure_vmware (); -+ (*unconfigure_vmware ();*) - unconfigure_citrix (); - unconfigure_kudzu (); - --- -1.8.3.1 - diff --git a/SOURCES/0015-RHEL-7-Disable-alternate-Augeas-lenses.patch b/SOURCES/0015-RHEL-7-Disable-alternate-Augeas-lenses.patch deleted file mode 100644 index 4f83aa2..0000000 --- a/SOURCES/0015-RHEL-7-Disable-alternate-Augeas-lenses.patch +++ /dev/null @@ -1,84 +0,0 @@ -From 689121835dc22f576fa0182c6f0e94a27a24ba6a Mon Sep 17 00:00:00 2001 -From: Pino Toscano -Date: Fri, 24 Oct 2014 16:33:50 +0100 -Subject: [PATCH] RHEL 7: Disable alternate Augeas lenses. - -These are included in the RHEL 7.1 augeas package, and therefore -not required in RHEL. - -See: -https://www.redhat.com/archives/libguestfs/2014-October/msg00220.html ---- - appliance/Makefile.am | 2 -- - daemon/augeas.c | 5 ++++- - daemon/lvm-filter.c | 4 ++-- - 3 files changed, 6 insertions(+), 5 deletions(-) - -diff --git a/appliance/Makefile.am b/appliance/Makefile.am -index d8fb15b..56dffa6 100644 ---- a/appliance/Makefile.am -+++ b/appliance/Makefile.am -@@ -77,8 +77,6 @@ supermin.d/daemon.tar.gz: ../daemon/guestfsd guestfs_lvm_conf.aug guestfs_shadow - rm -rf tmp-d - mkdir -p tmp-d$(DAEMON_SUPERMIN_DIR) tmp-d/etc tmp-d/usr/share/guestfs - ln ../daemon/guestfsd tmp-d$(DAEMON_SUPERMIN_DIR)/guestfsd -- ln $(srcdir)/guestfs_lvm_conf.aug tmp-d/usr/share/guestfs/guestfs_lvm_conf.aug -- ln $(srcdir)/guestfs_shadow.aug tmp-d/usr/share/guestfs/guestfs_shadow.aug - ( cd tmp-d && tar zcf - * ) > $@-t - rm -r tmp-d - mv $@-t $@ -diff --git a/daemon/augeas.c b/daemon/augeas.c -index 14cc0cf..fc13143 100644 ---- a/daemon/augeas.c -+++ b/daemon/augeas.c -@@ -134,7 +134,7 @@ do_aug_init (const char *root, int flags) - } - - /* Pass AUG_NO_ERR_CLOSE so we can display detailed errors. */ -- aug = aug_init (buf, "/usr/share/guestfs/", flags | AUG_NO_ERR_CLOSE); -+ aug = aug_init (buf, NULL, flags | AUG_NO_ERR_CLOSE); - - if (!aug) { - reply_with_error ("augeas initialization failed"); -@@ -148,6 +148,8 @@ do_aug_init (const char *root, int flags) - return -1; - } - -+ /* We already have the needed lenses in RHEL 7 */ -+#if 0 - if (!augeas_is_version (1, 2, 1)) { - int r = aug_transform (aug, "guestfs_shadow", "/etc/shadow", - 0 /* = included */); -@@ -166,6 +168,7 @@ do_aug_init (const char *root, int flags) - } - } - } -+#endif - - return 0; - } -diff --git a/daemon/lvm-filter.c b/daemon/lvm-filter.c -index aa8fd59..83150d1 100644 ---- a/daemon/lvm-filter.c -+++ b/daemon/lvm-filter.c -@@ -122,7 +122,7 @@ set_filter (char *const *filters) - * but do that only after having applied the transformation. - */ - const int flags = AUG_NO_ERR_CLOSE | AUG_NO_LOAD; -- aug = aug_init (lvm_system_dir, "/usr/share/guestfs/", flags); -+ aug = aug_init (lvm_system_dir, NULL, flags); - if (!aug) { - reply_with_error ("augeas initialization failed"); - return -1; -@@ -133,7 +133,7 @@ set_filter (char *const *filters) - return -1; - } - -- r = aug_transform (aug, "guestfs_lvm_conf", "/lvm/lvm.conf", -+ r = aug_transform (aug, "lvm", "/lvm/lvm.conf", - 0 /* = included */); - if (r == -1) { - AUGEAS_ERROR ("aug_transform"); --- -1.8.3.1 - diff --git a/SOURCES/0015-RHEL-7-Fix-list-of-supported-sound-cards-to-match-RH.patch b/SOURCES/0015-RHEL-7-Fix-list-of-supported-sound-cards-to-match-RH.patch new file mode 100644 index 0000000..9d3b2e1 --- /dev/null +++ b/SOURCES/0015-RHEL-7-Fix-list-of-supported-sound-cards-to-match-RH.patch @@ -0,0 +1,34 @@ +From 53e3905783593eaa4a06ea3ee416e9dc1da3a60a Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Fri, 24 Apr 2015 09:45:41 -0400 +Subject: [PATCH] RHEL 7: Fix list of supported sound cards to match RHEL qemu + (RHBZ#1176493). + +--- + v2v/utils.ml | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/v2v/utils.ml b/v2v/utils.ml +index e53f9fe..8f1053e 100644 +--- a/v2v/utils.ml ++++ b/v2v/utils.ml +@@ -40,13 +40,14 @@ let kvm_arch = function + (* Does qemu support the given sound card? *) + let qemu_supports_sound_card = function + | Types.AC97 +- | Types.ES1370 + | Types.ICH6 + | Types.ICH9 + | Types.PCSpeaker ++ -> true ++ | Types.ES1370 + | Types.SB16 + | Types.USBAudio +- -> true ++ -> false + + (* Find the UEFI firmware. *) + let find_uefi_firmware guest_arch = +-- +2.9.4 + diff --git a/SOURCES/0016-RHEL-7-Fix-list-of-supported-sound-cards-to-match-RH.patch b/SOURCES/0016-RHEL-7-Fix-list-of-supported-sound-cards-to-match-RH.patch deleted file mode 100644 index e0b3666..0000000 --- a/SOURCES/0016-RHEL-7-Fix-list-of-supported-sound-cards-to-match-RH.patch +++ /dev/null @@ -1,34 +0,0 @@ -From f171a8a9df024c92e58d34c5b8aa6fed114f7cb4 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Fri, 24 Apr 2015 09:45:41 -0400 -Subject: [PATCH] RHEL 7: Fix list of supported sound cards to match RHEL qemu - (RHBZ#1176493). - ---- - v2v/utils.ml | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/v2v/utils.ml b/v2v/utils.ml -index d1ef7b0..898b8d4 100644 ---- a/v2v/utils.ml -+++ b/v2v/utils.ml -@@ -73,13 +73,14 @@ let kvm_arch = function - (* Does qemu support the given sound card? *) - let qemu_supports_sound_card = function - | Types.AC97 -- | Types.ES1370 - | Types.ICH6 - | Types.ICH9 - | Types.PCSpeaker -+ -> true -+ | Types.ES1370 - | Types.SB16 - | Types.USBAudio -- -> true -+ -> false - - external ovmf_i386_firmware : unit -> (string * string) list = "v2v_utils_ovmf_i386_firmware" - external ovmf_x86_64_firmware : unit -> (string * string) list = "v2v_utils_ovmf_x86_64_firmware" --- -1.8.3.1 - diff --git a/SOURCES/0016-RHEL-7-v2v-efi-Remove-references-to-Fedora-kraxel-s-.patch b/SOURCES/0016-RHEL-7-v2v-efi-Remove-references-to-Fedora-kraxel-s-.patch new file mode 100644 index 0000000..563ccdf --- /dev/null +++ b/SOURCES/0016-RHEL-7-v2v-efi-Remove-references-to-Fedora-kraxel-s-.patch @@ -0,0 +1,52 @@ +From 8fb7f81181a566fac5ee572ee630946294f735ff Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Thu, 30 Apr 2015 17:20:26 -0400 +Subject: [PATCH] RHEL 7: v2v: efi: Remove references to Fedora / kraxel's OVMF + packages. + +--- + generator/UEFI.ml | 6 ------ + v2v/utils.ml | 3 +-- + 2 files changed, 1 insertion(+), 8 deletions(-) + +diff --git a/generator/UEFI.ml b/generator/UEFI.ml +index 95797aa..881009c 100644 +--- a/generator/UEFI.ml ++++ b/generator/UEFI.ml +@@ -30,12 +30,6 @@ open Docstrings + + (* Order is significant *within architectures only*. *) + let firmware = [ +- "i386", +- "/usr/share/edk2.git/ovmf-ia32/OVMF_CODE-pure-efi.fd", +- None, +- "/usr/share/edk2.git/ovmf-ia32/OVMF_VARS-pure-efi.fd", +- []; +- + "x86_64", + "/usr/share/OVMF/OVMF_CODE.fd", + None, +diff --git a/v2v/utils.ml b/v2v/utils.ml +index 8f1053e..212c8a0 100644 +--- a/v2v/utils.ml ++++ b/v2v/utils.ml +@@ -54,7 +54,6 @@ let find_uefi_firmware guest_arch = + let files = + (* The lists of firmware are actually defined in common/utils/uefi.c. *) + match guest_arch with +- | "i386" | "i486" | "i586" | "i686" -> Uefi.uefi_i386_firmware + | "x86_64" -> Uefi.uefi_x86_64_firmware + | "aarch64" -> Uefi.uefi_aarch64_firmware + | arch -> +@@ -62,7 +61,7 @@ let find_uefi_firmware guest_arch = + guest_arch in + let rec loop = function + | [] -> +- error (f_"cannot find firmware for UEFI guests.\n\nYou probably need to install OVMF, or Gerd's firmware repo (https://www.kraxel.org/repos/), or AAVMF (if using aarch64)") ++ error (f_"cannot find firmware for UEFI guests.\n\nYou probably need to install OVMF, or AAVMF (if using aarch64)") + | ({ Uefi.code = code; vars = vars_template } as ret) :: rest -> + if Sys.file_exists code && Sys.file_exists vars_template then ret + else loop rest +-- +2.9.4 + diff --git a/SOURCES/0017-RHEL-7-Reject-use-of-libguestfs-winsupport-features-.patch b/SOURCES/0017-RHEL-7-Reject-use-of-libguestfs-winsupport-features-.patch new file mode 100644 index 0000000..18ec5c3 --- /dev/null +++ b/SOURCES/0017-RHEL-7-Reject-use-of-libguestfs-winsupport-features-.patch @@ -0,0 +1,47 @@ +From 0c01f7c2c9acb1336d996df65acddb33c2dc0181 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Tue, 7 Jul 2015 09:28:03 -0400 +Subject: [PATCH] RHEL 7: Reject use of libguestfs-winsupport features except + for virt-* tools (RHBZ#1240276). + +--- + generator/c.ml | 17 +++++++++++++++++ + 1 file changed, 17 insertions(+) + +diff --git a/generator/c.ml b/generator/c.ml +index 606c898..bba57c5 100644 +--- a/generator/c.ml ++++ b/generator/c.ml +@@ -1856,12 +1856,29 @@ and generate_client_actions actions () = + pr " const uint64_t progress_hint = 0;\n"; + + pr "\n"; ++ + enter_event name; + check_null_strings c_name style; + reject_unknown_optargs c_name style; + check_args_validity c_name style; + trace_call name c_name style; + ++ (* RHEL 7 *) ++ if name = "mount" || name = "mount_ro" || name = "mount_options" || ++ name = "mount_vfs" then ( ++ pr " if (g->program && !STRPREFIX (g->program, \"virt-\")) {\n"; ++ pr " CLEANUP_FREE char *vfs_type = guestfs_vfs_type (g, mountable);\n"; ++ pr " if (vfs_type && STREQ (vfs_type, \"ntfs\")) {\n"; ++ pr " error (g, \"mount: unsupported filesystem type\");\n"; ++ pr " if (trace_flag)\n"; ++ pr " guestfs_int_trace (g, \"%%s = %%s (error)\",\n"; ++ pr " \"%s\", \"-1\");\n" name; ++ pr " return %s;\n" (string_of_errcode errcode); ++ pr " }\n"; ++ pr " }\n"; ++ pr "\n"; ++ ); ++ + (* Calculate the total size of all FileIn arguments to pass + * as a progress bar hint. + *) +-- +2.9.4 + diff --git a/SOURCES/0017-RHEL-7-v2v-efi-Remove-references-to-Fedora-kraxel-s-.patch b/SOURCES/0017-RHEL-7-v2v-efi-Remove-references-to-Fedora-kraxel-s-.patch deleted file mode 100644 index 04b86c3..0000000 --- a/SOURCES/0017-RHEL-7-v2v-efi-Remove-references-to-Fedora-kraxel-s-.patch +++ /dev/null @@ -1,64 +0,0 @@ -From 4449e2ac20e70e85533ce0bd38d53b9980a49cb5 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Thu, 30 Apr 2015 17:20:26 -0400 -Subject: [PATCH] RHEL 7: v2v: efi: Remove references to Fedora / kraxel's OVMF - packages. - ---- - src/utils.c | 12 ------------ - v2v/utils.ml | 2 +- - 2 files changed, 1 insertion(+), 13 deletions(-) - -diff --git a/src/utils.c b/src/utils.c -index dbb9a44..8ffc1ed 100644 ---- a/src/utils.c -+++ b/src/utils.c -@@ -324,9 +324,6 @@ guestfs_int_is_true (const char *str) - /* See src/appliance.c:guestfs_int_get_uefi. */ - const char * - guestfs_int_ovmf_i386_firmware[] = { -- "/usr/share/edk2.git/ovmf-ia32/OVMF_CODE-pure-efi.fd", -- "/usr/share/edk2.git/ovmf-ia32/OVMF_VARS-pure-efi.fd", -- - NULL - }; - -@@ -335,12 +332,6 @@ guestfs_int_ovmf_x86_64_firmware[] = { - "/usr/share/OVMF/OVMF_CODE.fd", - "/usr/share/OVMF/OVMF_VARS.fd", - -- "/usr/share/edk2.git/ovmf-x64/OVMF_CODE-pure-efi.fd", -- "/usr/share/edk2.git/ovmf-x64/OVMF_VARS-pure-efi.fd", -- -- "/usr/share/qemu/ovmf-x86_64-code.bin", -- "/usr/share/qemu/ovmf-x86_64-vars.bin", -- - NULL - }; - -@@ -349,9 +340,6 @@ guestfs_int_aavmf_firmware[] = { - "/usr/share/AAVMF/AAVMF_CODE.fd", - "/usr/share/AAVMF/AAVMF_VARS.fd", - -- "/usr/share/edk2.git/aarch64/QEMU_EFI-pflash.raw", -- "/usr/share/edk2.git/aarch64/vars-template-pflash.raw", -- - NULL - }; - -diff --git a/v2v/utils.ml b/v2v/utils.ml -index 898b8d4..d88f8ad 100644 ---- a/v2v/utils.ml -+++ b/v2v/utils.ml -@@ -99,7 +99,7 @@ let find_uefi_firmware guest_arch = - guest_arch in - let rec loop = function - | [] -> -- error (f_"cannot find firmware for UEFI guests.\n\nYou probably need to install OVMF, or Gerd's firmware repo (https://www.kraxel.org/repos/), or AAVMF (if using aarch64)") -+ error (f_"cannot find firmware for UEFI guests.\n\nYou probably need to install OVMF, or AAVMF (if using aarch64)") - | ((code, vars_template) as ret) :: rest -> - if Sys.file_exists code && Sys.file_exists vars_template then ret - else loop rest --- -1.8.3.1 - diff --git a/SOURCES/0018-RHEL-7-Reject-use-of-libguestfs-winsupport-features-.patch b/SOURCES/0018-RHEL-7-Reject-use-of-libguestfs-winsupport-features-.patch deleted file mode 100644 index f0d45a2..0000000 --- a/SOURCES/0018-RHEL-7-Reject-use-of-libguestfs-winsupport-features-.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 60d6a74fcc330c5910fa5fb64ac403e42b3b5c86 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Tue, 7 Jul 2015 09:28:03 -0400 -Subject: [PATCH] RHEL 7: Reject use of libguestfs-winsupport features except - for virt-* tools (RHBZ#1240276). - ---- - generator/c.ml | 17 +++++++++++++++++ - 1 file changed, 17 insertions(+) - -diff --git a/generator/c.ml b/generator/c.ml -index 8dcdd67..5714900 100644 ---- a/generator/c.ml -+++ b/generator/c.ml -@@ -1857,12 +1857,29 @@ and generate_client_actions hash () = - pr " const uint64_t progress_hint = 0;\n"; - - pr "\n"; -+ - enter_event name; - check_null_strings c_name style; - reject_unknown_optargs c_name style; - check_args_validity c_name style; - trace_call name c_name style; - -+ (* RHEL 7 *) -+ if name = "mount" || name = "mount_ro" || name = "mount_options" || -+ name = "mount_vfs" then ( -+ pr " if (g->program && !STRPREFIX (g->program, \"virt-\")) {\n"; -+ pr " CLEANUP_FREE char *vfs_type = guestfs_vfs_type (g, mountable);\n"; -+ pr " if (vfs_type && STREQ (vfs_type, \"ntfs\")) {\n"; -+ pr " error (g, \"mount: unsupported filesystem type\");\n"; -+ pr " if (trace_flag)\n"; -+ pr " guestfs_int_trace (g, \"%%s = %%s (error)\",\n"; -+ pr " \"%s\", \"-1\");\n" name; -+ pr " return %s;\n" (string_of_errcode errcode); -+ pr " }\n"; -+ pr " }\n"; -+ pr "\n"; -+ ); -+ - (* Calculate the total size of all FileIn arguments to pass - * as a progress bar hint. - *) --- -1.8.3.1 - diff --git a/SOURCES/0018-RHEL-7-daemon-umount-all-Hack-to-avoid-umount-sysroo.patch b/SOURCES/0018-RHEL-7-daemon-umount-all-Hack-to-avoid-umount-sysroo.patch new file mode 100644 index 0000000..729018e --- /dev/null +++ b/SOURCES/0018-RHEL-7-daemon-umount-all-Hack-to-avoid-umount-sysroo.patch @@ -0,0 +1,40 @@ +From 006717a7f2c939fd99154d0b7af6447c30ef7ec1 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Thu, 23 Jul 2015 18:15:36 -0400 +Subject: [PATCH] RHEL 7: daemon: umount-all: Hack to avoid umount: /sysroot: + target is busy (RHBZ#1246032). + +This bug is not properly understood (although readily reproducible). +However this hack makes it go away for now. + +https://bugzilla.redhat.com/show_bug.cgi?id=1246032 +--- + daemon/mount.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/daemon/mount.c b/daemon/mount.c +index f2aedfd..14b24bf 100644 +--- a/daemon/mount.c ++++ b/daemon/mount.c +@@ -28,6 +28,8 @@ + #include + #include + ++#include "ignore-value.h" ++ + #include "daemon.h" + #include "actions.h" + +@@ -408,6 +410,9 @@ do_umount_all (void) + if (mounts.size > 0) + qsort (mounts.argv, mounts.size, sizeof (char *), compare_longest_first); + ++ /* Hack to work around RHBZ#1246032. */ ++ ignore_value (system ("lsof /sysroot")); ++ + /* Unmount them. */ + for (i = 0; i < mounts.size; ++i) { + CLEANUP_FREE char *err = NULL; +-- +2.9.4 + diff --git a/SOURCES/0019-RHEL-7-Fix-tests-for-libguestfs-winsupport-7.2.patch b/SOURCES/0019-RHEL-7-Fix-tests-for-libguestfs-winsupport-7.2.patch new file mode 100644 index 0000000..37977e9 --- /dev/null +++ b/SOURCES/0019-RHEL-7-Fix-tests-for-libguestfs-winsupport-7.2.patch @@ -0,0 +1,93 @@ +From 93d34d8282b48c737fe2e1e749dfa916086b15c9 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Sun, 30 Aug 2015 03:21:57 -0400 +Subject: [PATCH] RHEL 7: Fix tests for libguestfs-winsupport 7.2. + +It doesn't let us use guestfish for arbitrary Windows edits. +--- + test-data/phony-guests/make-windows-img.sh | 1 + + tests/charsets/test-charset-fidelity.c | 2 ++ + v2v/test-v2v-virtio-win-iso.sh | 8 +++++++- + v2v/test-v2v-windows-conversion.sh | 8 +++++++- + 4 files changed, 17 insertions(+), 2 deletions(-) + +diff --git a/test-data/phony-guests/make-windows-img.sh b/test-data/phony-guests/make-windows-img.sh +index 2d18ea4..9eed756 100755 +--- a/test-data/phony-guests/make-windows-img.sh ++++ b/test-data/phony-guests/make-windows-img.sh +@@ -37,6 +37,7 @@ fi + + # Create a disk image. + guestfish < "$script" + :> "$expected" + ++cat >> "$script" < "$response" ++guestfish --ro -a "$d/windows-sda" < "$script" > "$response" + diff -u "$expected" "$response" + + rm -r $d +diff --git a/v2v/test-v2v-windows-conversion.sh b/v2v/test-v2v-windows-conversion.sh +index f1da222..ff94fe3 100755 +--- a/v2v/test-v2v-windows-conversion.sh ++++ b/v2v/test-v2v-windows-conversion.sh +@@ -73,6 +73,12 @@ mktest () + :> "$script" + :> "$expected" + ++cat >> "$script" < "$response" ++guestfish --ro -a "$d/windows-sda" < "$script" > "$response" + diff -u "$expected" "$response" + + # We also update the Registry several times, for firstboot, and (ONLY +-- +2.9.4 + diff --git a/SOURCES/0019-RHEL-7-daemon-umount-all-Hack-to-avoid-umount-sysroo.patch b/SOURCES/0019-RHEL-7-daemon-umount-all-Hack-to-avoid-umount-sysroo.patch deleted file mode 100644 index fc82564..0000000 --- a/SOURCES/0019-RHEL-7-daemon-umount-all-Hack-to-avoid-umount-sysroo.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 7e25abeffd2c7a68a06fa72fff274377637453ab Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Thu, 23 Jul 2015 18:15:36 -0400 -Subject: [PATCH] RHEL 7: daemon: umount-all: Hack to avoid umount: /sysroot: - target is busy (RHBZ#1246032). - -This bug is not properly understood (although readily reproducible). -However this hack makes it go away for now. - -https://bugzilla.redhat.com/show_bug.cgi?id=1246032 ---- - daemon/mount.c | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/daemon/mount.c b/daemon/mount.c -index 869c9b8..7903bc2 100644 ---- a/daemon/mount.c -+++ b/daemon/mount.c -@@ -26,6 +26,8 @@ - #include - #include - -+#include "ignore-value.h" -+ - #include "daemon.h" - #include "actions.h" - -@@ -414,6 +416,9 @@ do_umount_all (void) - if (mounts.size > 0) - qsort (mounts.argv, mounts.size, sizeof (char *), compare_longest_first); - -+ /* Hack to work around RHBZ#1246032. */ -+ ignore_value (system ("lsof /sysroot")); -+ - /* Unmount them. */ - for (i = 0; i < mounts.size; ++i) { - CLEANUP_FREE char *err = NULL; --- -1.8.3.1 - diff --git a/SOURCES/0020-RHEL-7-Fix-tests-for-libguestfs-winsupport-7.2.patch b/SOURCES/0020-RHEL-7-Fix-tests-for-libguestfs-winsupport-7.2.patch deleted file mode 100644 index 9992bfd..0000000 --- a/SOURCES/0020-RHEL-7-Fix-tests-for-libguestfs-winsupport-7.2.patch +++ /dev/null @@ -1,93 +0,0 @@ -From e8784cd78f864c9d21eca6a3bccaa9d8cf8cefdf Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Sun, 30 Aug 2015 03:21:57 -0400 -Subject: [PATCH] RHEL 7: Fix tests for libguestfs-winsupport 7.2. - -It doesn't let us use guestfish for arbitrary Windows edits. ---- - test-data/phony-guests/make-windows-img.sh | 1 + - tests/charsets/test-charset-fidelity.c | 2 ++ - v2v/test-v2v-virtio-win-iso.sh | 8 +++++++- - v2v/test-v2v-windows-conversion.sh | 8 +++++++- - 4 files changed, 17 insertions(+), 2 deletions(-) - -diff --git a/test-data/phony-guests/make-windows-img.sh b/test-data/phony-guests/make-windows-img.sh -index d5c4501..9255b25 100755 ---- a/test-data/phony-guests/make-windows-img.sh -+++ b/test-data/phony-guests/make-windows-img.sh -@@ -37,6 +37,7 @@ fi - - # Create a disk image. - guestfish < "$script" - :> "$expected" - -+cat >> "$script" < "$response" -+guestfish --ro -a "$d/windows-sda" < "$script" > "$response" - diff -u "$expected" "$response" - - rm -r $d -diff --git a/v2v/test-v2v-windows-conversion.sh b/v2v/test-v2v-windows-conversion.sh -index 8406743..40f651e 100755 ---- a/v2v/test-v2v-windows-conversion.sh -+++ b/v2v/test-v2v-windows-conversion.sh -@@ -86,6 +86,12 @@ mktest () - :> "$script" - :> "$expected" - -+cat >> "$script" < "$response" -+guestfish --ro -a "$d/windows-sda" < "$script" > "$response" - diff -u "$expected" "$response" - - # We also update the Registry several times, for firstboot, and (ONLY --- -1.8.3.1 - diff --git a/SOURCES/0020-RHEL-7-Revert-v2v-Add-a-support-matrix-to-the-manual.patch b/SOURCES/0020-RHEL-7-Revert-v2v-Add-a-support-matrix-to-the-manual.patch new file mode 100644 index 0000000..0e29100 --- /dev/null +++ b/SOURCES/0020-RHEL-7-Revert-v2v-Add-a-support-matrix-to-the-manual.patch @@ -0,0 +1,122 @@ +From db662b2d47088d792bb158103719ac07dfc8e3e0 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Mon, 21 Sep 2015 15:49:17 +0100 +Subject: [PATCH] RHEL 7: Revert "v2v: Add a support matrix to the manual + page." + +This reverts commit a03bffa15a5357d5d0244595caf99607be1ec3ab. +--- + v2v/virt-v2v.pod | 97 -------------------------------------------------------- + 1 file changed, 97 deletions(-) + +diff --git a/v2v/virt-v2v.pod b/v2v/virt-v2v.pod +index 79c742e..fca0a2a 100644 +--- a/v2v/virt-v2v.pod ++++ b/v2v/virt-v2v.pod +@@ -145,103 +145,6 @@ Since F contains the path(s) to the guest disk + image(s) you do not need to specify the name of the disk image on the + command line. + +-=head1 SUPPORT MATRIX +- +-=head2 Hypervisors (Input) +- +-=over 4 +- +-=item VMware ESXi +- +-Must be managed by VMware vCenter E 5.0. Unmanaged, direct input +-from ESXi is not supported. +- +-=item OVA exported from VMware +- +-OVAs from other hypervisors will not work. +- +-=item RHEL 5 Xen +- +-=item SUSE Xen +- +-=item Citrix Xen +- +-Citrix Xen has not been recently tested. +- +-=item Hyper-V +- +-Not recently tested. Requires that you export the disk or use +-L on Hyper-V. +- +-=item Direct from disk images +- +-Only disk images exported from supported hypervisors, and using +-container formats supported by qemu. +- +-=item Physical machines +- +-Using the L tool. +- +-=back +- +-=head2 Hypervisors (Output) +- +-QEMU and KVM only. +- +-=head2 Virtualization management systems (Output) +- +-=over 4 +- +-=item OpenStack Glance +- +-=item Red Hat Virtualization (RHV) 4.1 and up +- +-=item Local libvirt +- +-And hence L, L, and similar tools. +- +-=item Local disk +- +-=back +- +-=head2 Guests +- +-=over 4 +- +-=item Red Hat Enterprise Linux 3, 4, 5, 6, 7 +- +-=item CentOS 3, 4, 5, 6, 7 +- +-=item Scientific Linux 3, 4, 5, 6, 7 +- +-=item Oracle Linux +- +-=item Fedora +- +-=item SLES 10 and up +- +-=item OpenSUSE 10 and up +- +-=item Debian 6 and up +- +-=item Ubuntu 10.04, 12.04, 14.04, 16.04, and up +- +-=item Windows XP to Windows 8.1 / Windows Server 2012 R2 +- +-We use Windows internal version numbers, see +-L +- +-Currently NT 5.2 to NT 6.3 are supported. +- +-See L below for additional notes on converting Windows +-guests. +- +-=back +- +-=head2 Guest firmware +- +-BIOS or UEFI for all guest types (but see L below). +- + =head1 OPTIONS + + =over 4 +-- +2.9.4 + diff --git a/SOURCES/0021-RHEL-7-All-qemu-kvm-in-RHEL-7-supports-discard-of-qc.patch b/SOURCES/0021-RHEL-7-All-qemu-kvm-in-RHEL-7-supports-discard-of-qc.patch new file mode 100644 index 0000000..e932d34 --- /dev/null +++ b/SOURCES/0021-RHEL-7-All-qemu-kvm-in-RHEL-7-supports-discard-of-qc.patch @@ -0,0 +1,46 @@ +From 1995428106fe0e14832e0b0d07e5b71740b193a4 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Wed, 27 May 2015 10:03:00 -0400 +Subject: [PATCH] RHEL 7: All qemu-kvm in RHEL 7 supports discard of qcow2 + (RHBZ#1225467). + +For rationale behind this, see: + + https://bugzilla.redhat.com/show_bug.cgi?id=1225467#c2 +--- + lib/qemu.c | 12 ++---------- + 1 file changed, 2 insertions(+), 10 deletions(-) + +diff --git a/lib/qemu.c b/lib/qemu.c +index d60692f..6bb54b7 100644 +--- a/lib/qemu.c ++++ b/lib/qemu.c +@@ -610,10 +610,6 @@ guestfs_int_discard_possible (guestfs_h *g, struct drive *drv, + * discard option on -drive at all. + */ + bool qemu15 = guestfs_int_version_ge (qemu_version, 1, 5, 0); +- /* qemu >= 1.6. This was the first version that supported unmap on +- * qcow2 backing files. +- */ +- bool qemu16 = guestfs_int_version_ge (qemu_version, 1, 6, 0); + + if (!qemu15) + NOT_SUPPORTED (g, false, +@@ -638,12 +634,8 @@ guestfs_int_discard_possible (guestfs_h *g, struct drive *drv, + } + else if (STREQ (drv->src.format, "raw")) + /* OK */ ; +- else if (STREQ (drv->src.format, "qcow2")) { +- if (!qemu16) +- NOT_SUPPORTED (g, false, +- _("discard cannot be enabled on this drive: " +- "qemu < 1.6 cannot do discard on qcow2 files")); +- } ++ else if (STREQ (drv->src.format, "qcow2")) ++ /* OK */ ; + else { + /* It's possible in future other formats will support discard, but + * currently (qemu 1.7) none of them do. +-- +2.9.4 + diff --git a/SOURCES/0021-RHEL-7-Revert-v2v-Add-a-support-matrix-to-the-manual.patch b/SOURCES/0021-RHEL-7-Revert-v2v-Add-a-support-matrix-to-the-manual.patch deleted file mode 100644 index 53f367a..0000000 --- a/SOURCES/0021-RHEL-7-Revert-v2v-Add-a-support-matrix-to-the-manual.patch +++ /dev/null @@ -1,116 +0,0 @@ -From 40e4e2a02cac87754cd734287c2eeeb7e31cc264 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Mon, 21 Sep 2015 15:49:17 +0100 -Subject: [PATCH] RHEL 7: Revert "v2v: Add a support matrix to the manual - page." - -This reverts commit a03bffa15a5357d5d0244595caf99607be1ec3ab. ---- - v2v/virt-v2v.pod | 91 -------------------------------------------------------- - 1 file changed, 91 deletions(-) - -diff --git a/v2v/virt-v2v.pod b/v2v/virt-v2v.pod -index dcbaec2..8e5cf1d 100644 ---- a/v2v/virt-v2v.pod -+++ b/v2v/virt-v2v.pod -@@ -145,97 +145,6 @@ Since F contains the path(s) to the guest disk - image(s) you do not need to specify the name of the disk image on the - command line. - --=head1 SUPPORT MATRIX -- --=head2 Hypervisors (Input) -- --=over 4 -- --=item VMware ESXi -- --Must be managed by VMware vCenter E 5.0. Unmanaged, direct input --from ESXi is not supported. -- --=item OVA exported from VMware -- --OVAs from other hypervisors will not work. -- --=item RHEL 5 Xen -- --=item Citrix Xen -- --Citrix Xen has not been recently tested. -- --=item Hyper-V -- --Not recently tested. Requires that you export the disk or use --L on Hyper-V. -- --=item Direct from disk images -- --Only disk images exported from supported hypervisors, and using --container formats supported by qemu. -- --=item Physical machines -- --Using the L tool. -- --=back -- --=head2 Hypervisors (Output) -- --QEMU and KVM only. -- --=head2 Virtualization management systems (Output) -- --=over 4 -- --=item OpenStack Glance -- --=item Red Hat Enterprise Virtualization (RHEV) 2.2 and up -- --=item Local libvirt -- --And hence L, L, and similar tools. -- --=item Local disk -- --=back -- --=head2 Guests -- --=over 4 -- --=item Red Hat Enterprise Linux 3, 4, 5, 6, 7 -- --=item CentOS 3, 4, 5, 6, 7 -- --=item Scientific Linux 3, 4, 5, 6, 7 -- --=item Oracle Linux -- --=item Fedora -- --=item SLES 10 and up -- --=item OpenSUSE 10 and up -- --=item Windows XP to Windows 8.1 / Windows Server 2012 R2 -- --We use Windows internal version numbers, see --L -- --Currently NT 5.2 to NT 6.3 are supported. -- --See L below for additional notes on converting Windows --guests. -- --=back -- --=head2 Guest firmware -- --BIOS or UEFI for all guest types (but see L below). -- - =head1 OPTIONS - - =over 4 --- -1.8.3.1 - diff --git a/SOURCES/0022-RHEL-7-All-qemu-kvm-in-RHEL-7-supports-discard-of-qc.patch b/SOURCES/0022-RHEL-7-All-qemu-kvm-in-RHEL-7-supports-discard-of-qc.patch deleted file mode 100644 index 1a78327..0000000 --- a/SOURCES/0022-RHEL-7-All-qemu-kvm-in-RHEL-7-supports-discard-of-qc.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 410fa0a977ce7d950c38b86361b3cf7d0e60c773 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Wed, 27 May 2015 10:03:00 -0400 -Subject: [PATCH] RHEL 7: All qemu-kvm in RHEL 7 supports discard of qcow2 - (RHBZ#1225467). - -For rationale behind this, see: - - https://bugzilla.redhat.com/show_bug.cgi?id=1225467#c2 ---- - src/launch-direct.c | 12 ++---------- - 1 file changed, 2 insertions(+), 10 deletions(-) - -diff --git a/src/launch-direct.c b/src/launch-direct.c -index 52f73ec..cbaf4f3 100644 ---- a/src/launch-direct.c -+++ b/src/launch-direct.c -@@ -1408,10 +1408,6 @@ guestfs_int_discard_possible (guestfs_h *g, struct drive *drv, - * discard option on -drive at all. - */ - bool qemu15 = qemu_version >= 1005000; -- /* qemu >= 1.6. This was the first version that supported unmap on -- * qcow2 backing files. -- */ -- bool qemu16 = qemu_version >= 1006000; - - if (!qemu15) - NOT_SUPPORTED (g, false, -@@ -1436,12 +1432,8 @@ guestfs_int_discard_possible (guestfs_h *g, struct drive *drv, - } - else if (STREQ (drv->src.format, "raw")) - /* OK */ ; -- else if (STREQ (drv->src.format, "qcow2")) { -- if (!qemu16) -- NOT_SUPPORTED (g, false, -- _("discard cannot be enabled on this drive: " -- "qemu < 1.6 cannot do discard on qcow2 files")); -- } -+ else if (STREQ (drv->src.format, "qcow2")) -+ /* OK */ ; - else { - /* It's possible in future other formats will support discard, but - * currently (qemu 1.7) none of them do. --- -1.8.3.1 - diff --git a/SOURCES/0022-RHEL-7-tests-Disable-daemon-tests-that-require-the-u.patch b/SOURCES/0022-RHEL-7-tests-Disable-daemon-tests-that-require-the-u.patch new file mode 100644 index 0000000..2640435 --- /dev/null +++ b/SOURCES/0022-RHEL-7-tests-Disable-daemon-tests-that-require-the-u.patch @@ -0,0 +1,28 @@ +From ec0693476e8459771fa74cb820b7f9f89a6ba915 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Mon, 21 Sep 2015 13:12:43 -0400 +Subject: [PATCH] RHEL 7: tests: Disable daemon tests that require the 'unix' + backend. + +--- + tests/daemon/Makefile.am | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/tests/daemon/Makefile.am b/tests/daemon/Makefile.am +index 053cad3..0d723fe 100644 +--- a/tests/daemon/Makefile.am ++++ b/tests/daemon/Makefile.am +@@ -23,9 +23,7 @@ include $(top_srcdir)/subdir-rules.mk + + check_DATA = captive-daemon.pm + +-TESTS = \ +- test-daemon-start.pl \ +- test-btrfs.pl ++TESTS = + + TESTS_ENVIRONMENT = $(top_builddir)/run --test + +-- +2.9.4 + diff --git a/SOURCES/0023-RHEL-7-tests-Disable-daemon-tests-that-require-the-u.patch b/SOURCES/0023-RHEL-7-tests-Disable-daemon-tests-that-require-the-u.patch deleted file mode 100644 index 5226c27..0000000 --- a/SOURCES/0023-RHEL-7-tests-Disable-daemon-tests-that-require-the-u.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 11d82bf8764acb181364742eef6045aaef2fd711 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Mon, 21 Sep 2015 13:12:43 -0400 -Subject: [PATCH] RHEL 7: tests: Disable daemon tests that require the 'unix' - backend. - ---- - tests/daemon/Makefile.am | 4 +--- - 1 file changed, 1 insertion(+), 3 deletions(-) - -diff --git a/tests/daemon/Makefile.am b/tests/daemon/Makefile.am -index 053cad3..0d723fe 100644 ---- a/tests/daemon/Makefile.am -+++ b/tests/daemon/Makefile.am -@@ -23,9 +23,7 @@ include $(top_srcdir)/subdir-rules.mk - - check_DATA = captive-daemon.pm - --TESTS = \ -- test-daemon-start.pl \ -- test-btrfs.pl -+TESTS = - - TESTS_ENVIRONMENT = $(top_builddir)/run --test - --- -1.8.3.1 - diff --git a/SOURCES/0023-RHEL-7-v2v-Disable-the-virt-v2v-in-place-option.patch b/SOURCES/0023-RHEL-7-v2v-Disable-the-virt-v2v-in-place-option.patch new file mode 100644 index 0000000..a6d404c --- /dev/null +++ b/SOURCES/0023-RHEL-7-v2v-Disable-the-virt-v2v-in-place-option.patch @@ -0,0 +1,273 @@ +From c299f3e835dd3480960df3ea941099a43f399b96 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Thu, 14 Jan 2016 11:53:42 -0500 +Subject: [PATCH] RHEL 7: v2v: Disable the virt-v2v --in-place option. + +This disables the virt-v2v --in-place option which we do not +wish to support in RHEL. +(See commit d0069559a939e47e5f29973ed9a69a13f0b58301). +--- + v2v/Makefile.am | 2 - + v2v/cmdline.ml | 6 ++- + v2v/test-v2v-docs.sh | 2 +- + v2v/test-v2v-in-place.sh | 108 ----------------------------------------------- + v2v/virt-v2v.pod | 46 +------------------- + 5 files changed, 7 insertions(+), 157 deletions(-) + delete mode 100755 v2v/test-v2v-in-place.sh + +diff --git a/v2v/Makefile.am b/v2v/Makefile.am +index 133a411..2974064 100644 +--- a/v2v/Makefile.am ++++ b/v2v/Makefile.am +@@ -291,7 +291,6 @@ if HAVE_LIBVIRT + TESTS += \ + test-v2v-cdrom.sh \ + test-v2v-floppy.sh \ +- test-v2v-in-place.sh \ + test-v2v-networks-and-bridges.sh \ + test-v2v-no-copy.sh \ + test-v2v-o-glance.sh \ +@@ -412,7 +411,6 @@ EXTRA_DIST += \ + test-v2v-i-ova.ovf \ + test-v2v-i-ova.sh \ + test-v2v-i-ova.xml \ +- test-v2v-in-place.sh \ + test-v2v-machine-readable.sh \ + test-v2v-networks-and-bridges-expected.xml \ + test-v2v-networks-and-bridges.sh \ +diff --git a/v2v/cmdline.ml b/v2v/cmdline.ml +index 9f02098..9aecb5c 100644 +--- a/v2v/cmdline.ml ++++ b/v2v/cmdline.ml +@@ -179,7 +179,7 @@ let parse_cmdline () = + s_"Libvirt URI"; + [ M"if" ], Getopt.String ("format", set_string_option_once "-if" input_format), + s_"Input format (for -i disk)"; +- [ L"in-place" ], Getopt.Set in_place, s_"Only tune the guest in the input VM"; ++ [ L"in-place" ], Getopt.Set in_place, ""; + [ L"machine-readable" ], Getopt.Set machine_readable, s_"Make output machine readable"; + [ S 'n'; L"network" ], Getopt.String ("in:out", add_network), s_"Map network 'in' to 'out'"; + [ L"no-copy" ], Getopt.Clear do_copy, s_"Just write the metadata"; +@@ -333,6 +333,10 @@ read the man page virt-v2v(1). + error (f_"expecting an OVA file name on the command line") in + Input_ova.input_ova filename in + ++ (* Prevent use of --in-place option in RHEL. *) ++ if in_place then ++ error (f_"--in-place cannot be used in RHEL 7"); ++ + (* Common error message. *) + let error_option_cannot_be_used_in_output_mode mode opt = + error (f_"-o %s: %s option cannot be used in this output mode") mode opt +diff --git a/v2v/test-v2v-docs.sh b/v2v/test-v2v-docs.sh +index d341852..c5d98de 100755 +--- a/v2v/test-v2v-docs.sh ++++ b/v2v/test-v2v-docs.sh +@@ -22,4 +22,4 @@ $TEST_FUNCTIONS + skip_if_skipped + + $top_srcdir/podcheck.pl virt-v2v.pod virt-v2v \ +- --ignore=--dcPath,--debug-overlay,--ic,--if,--no-trim,--oa,--oc,--of,--on,--os,--vmtype ++ --ignore=--dcPath,--debug-overlay,--ic,--if,--in-place,--no-trim,--oa,--oc,--of,--on,--os,--vmtype +diff --git a/v2v/test-v2v-in-place.sh b/v2v/test-v2v-in-place.sh +deleted file mode 100755 +index 6f7d78f..0000000 +--- a/v2v/test-v2v-in-place.sh ++++ /dev/null +@@ -1,108 +0,0 @@ +-#!/bin/bash - +-# libguestfs virt-v2v test script +-# Copyright (C) 2014 Red Hat Inc. +-# Copyright (C) 2015 Parallels IP Holdings GmbH. +-# +-# This program is free software; you can redistribute it and/or modify +-# it under the terms of the GNU General Public License as published by +-# the Free Software Foundation; either version 2 of the License, or +-# (at your option) any later version. +-# +-# This program is distributed in the hope that it will be useful, +-# but WITHOUT ANY WARRANTY; without even the implied warranty of +-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-# GNU General Public License for more details. +-# +-# You should have received a copy of the GNU General Public License +-# along with this program; if not, write to the Free Software +-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +- +-# Test --in-place. +- +-unset CDPATH +-export LANG=C +-set -e +- +-$TEST_FUNCTIONS +-skip_if_skipped +-skip_if_backend uml +-skip_unless_phony_guest windows.img +- +-img_base="$abs_top_builddir/test-data/phony-guests/windows.img" +- +-export VIRT_TOOLS_DATA_DIR="$top_srcdir/test-data/fake-virt-tools" +-export VIRTIO_WIN="$top_srcdir/test-data/fake-virtio-win" +- +-d=$PWD/test-v2v-in-place.d +-rm -rf $d +-mkdir $d +- +-img="$d/test.qcow2" +-rm -f $img +-qemu-img create -f qcow2 -b $img_base -o compat=1.1,backing_fmt=raw $img +-md5="$(do_md5 $img_base)" +- +-libvirt_xml="$d/test.xml" +-rm -f $libvirt_xml +-n=windows-overlay +-cat > $libvirt_xml < +- +- $n +- 1048576 +- +- hvm +- +- +- +- +- +- +- +- +- +- +- +-EOF +- +-$VG virt-v2v --debug-gc -i libvirt -ic "test://$libvirt_xml" $n --in-place +- +-# Test that the drivers have been copied over into the guest +-script="$d/test.fish" +-expected="$d/expected" +-response="$d/response" +- +-mktest () +-{ +- local cmd="$1" exp="$2" +- +- echo "echo '$cmd'" >> "$script" +- echo "$cmd" >> "$expected" +- +- echo "$cmd" >> "$script" +- echo "$exp" >> "$expected" +-} +- +-:> "$script" +-:> "$expected" +- +-firstboot_dir="/Program Files/Guestfs/Firstboot" +-mktest "is-dir \"$firstboot_dir\"" true +-mktest "is-file \"$firstboot_dir/firstboot.bat\"" true +-mktest "is-dir \"$firstboot_dir/scripts\"" true +-virtio_dir="/Windows/Drivers/VirtIO" +-mktest "is-dir \"$virtio_dir\"" true +-for drv in netkvm qxl vioscsi viostor; do +- for sfx in cat inf sys; do +- mktest "is-file \"$virtio_dir/$drv.$sfx\"" true +- done +-done +- +-guestfish --ro -a "$img" -i < "$script" > "$response" +-diff -u "$expected" "$response" +- +-# Test the base image remained untouched +-test "$md5" = "$(do_md5 $img_base)" +- +-# Clean up. +-rm -r $d +diff --git a/v2v/virt-v2v.pod b/v2v/virt-v2v.pod +index fca0a2a..c45828b 100644 +--- a/v2v/virt-v2v.pod ++++ b/v2v/virt-v2v.pod +@@ -15,8 +15,6 @@ virt-v2v - Convert a guest to use KVM + + virt-v2v -i disk disk.img -o glance + +- virt-v2v -ic qemu:///system qemu_guest --in-place +- + =head1 DESCRIPTION + + Virt-v2v converts guests from a foreign hypervisor to run on KVM. It +@@ -77,9 +75,6 @@ booting the guest directly in qemu (mainly for testing). + I<-o rhv> is used to write to a RHV / oVirt target. I<-o vdsm> + is only used when virt-v2v runs under VDSM control. + +-I<--in-place> instructs virt-v2v to customize the guest OS in the input +-virtual machine, instead of creating a new VM in the target hypervisor. +- + =head1 EXAMPLES + + =head2 Convert from VMware vCenter server to local libvirt +@@ -251,20 +246,6 @@ For I<-i disk> only, this specifies the format of the input disk + image. For other input methods you should specify the input + format in the metadata. + +-=item B<--in-place> +- +-Do not create an output virtual machine in the target hypervisor. +-Instead, adjust the guest OS in the source VM to run in the input +-hypervisor. +- +-This mode is meant for integration with other toolsets, which take the +-responsibility of converting the VM configuration, providing for +-rollback in case of errors, transforming the storage, etc. +- +-See L below. +- +-Conflicts with all I<-o *> options. +- + =item B<--machine-readable> + + This option is used to make the output more machine friendly +@@ -1632,7 +1613,7 @@ Minimum free space: 10 MB + =head2 Minimum free space check in the host + + You must have sufficient free space in the host directory used to +-store temporary overlays (except in I<--in-place> mode). To find out ++store temporary overlays. To find out + which directory this is, use: + + $ df -h "`guestfish get-cachedir`" +@@ -1750,31 +1731,6 @@ that instead. + + + +-=head1 IN PLACE CONVERSION +- +-It is also possible to use virt-v2v in scenarios where a foreign VM +-has already been imported into a KVM-based hypervisor, but still needs +-adjustments in the guest to make it run in the new virtual hardware. +- +-In that case it is assumed that a third-party tool has created the +-target VM in the supported KVM-based hypervisor based on the source VM +-configuration and contents, but using virtual devices more appropriate +-for KVM (e.g. virtio storage and network, etc.). +- +-Then, to make the guest OS boot and run in the changed environment, +-one can use: +- +- virt-v2v -ic qemu:///system converted_vm --in-place +- +-Virt-v2v will analyze the configuration of C in the +-C libvirt instance, and apply various fixups to the +-guest OS configuration to make it match the VM configuration. This +-may include installing virtio drivers, configuring the bootloader, the +-mountpoints, the network interfaces, and so on. +- +-Should an error occur during the operation, virt-v2v exits with an +-error code leaving the VM in an undefined state. +- + =head1 MACHINE READABLE OUTPUT + + The I<--machine-readable> option can be used to make the output more +-- +2.9.4 + diff --git a/SOURCES/0024-RHEL-7-v2v-Disable-the-virt-v2v-in-place-option.patch b/SOURCES/0024-RHEL-7-v2v-Disable-the-virt-v2v-in-place-option.patch deleted file mode 100644 index 2d4f370..0000000 --- a/SOURCES/0024-RHEL-7-v2v-Disable-the-virt-v2v-in-place-option.patch +++ /dev/null @@ -1,224 +0,0 @@ -From 7a19cd75929d88d5b3512895138e5bde6b92b157 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Thu, 14 Jan 2016 11:53:42 -0500 -Subject: [PATCH] RHEL 7: v2v: Disable the virt-v2v --in-place option. - -This disables the virt-v2v --in-place option which we do not -wish to support in RHEL. -(See commit d0069559a939e47e5f29973ed9a69a13f0b58301). ---- - v2v/Makefile.am | 1 - - v2v/cmdline.ml | 6 ++- - v2v/test-v2v-in-place.sh | 121 ----------------------------------------------- - v2v/virt-v2v.pod | 17 ------- - 4 files changed, 5 insertions(+), 140 deletions(-) - delete mode 100755 v2v/test-v2v-in-place.sh - -diff --git a/v2v/Makefile.am b/v2v/Makefile.am -index 8a79a6f..d9cf986 100644 ---- a/v2v/Makefile.am -+++ b/v2v/Makefile.am -@@ -296,7 +296,6 @@ TESTS += \ - test-v2v-cdrom.sh \ - test-v2v-i-ova.sh \ - test-v2v-i-disk.sh \ -- test-v2v-in-place.sh \ - test-v2v-machine-readable.sh \ - test-v2v-networks-and-bridges.sh \ - test-v2v-no-copy.sh \ -diff --git a/v2v/cmdline.ml b/v2v/cmdline.ml -index 32eb873..4623af9 100644 ---- a/v2v/cmdline.ml -+++ b/v2v/cmdline.ml -@@ -194,7 +194,7 @@ let parse_cmdline () = - "uri " ^ s_"Libvirt URI"; - "-if", Arg.String (set_string_option_once "-if" input_format), - "format " ^ s_"Input format (for -i disk)"; -- "--in-place", Arg.Set in_place, " " ^ s_"Only tune the guest in the input VM"; -+ "--in-place", Arg.Set in_place, " " ^ s_"Unsupported option in RHEL 7"; - "--machine-readable", Arg.Set machine_readable, " " ^ s_"Make output machine readable"; - "-n", Arg.String add_network, "in:out " ^ s_"Map network 'in' to 'out'"; - "--network", Arg.String add_network, "in:out " ^ ditto; -@@ -352,6 +352,10 @@ read the man page virt-v2v(1). - error (f_"expecting an OVA file name on the command line") in - Input_ova.input_ova filename in - -+ (* Prevent use of --in-place option in RHEL. *) -+ if in_place then -+ error (f_"--in-place cannot be used in RHEL 7"); -+ - (* Parse the output mode. *) - if output_mode <> `Not_set && in_place then - error (f_"-o and --in-place cannot be used at the same time"); -diff --git a/v2v/test-v2v-in-place.sh b/v2v/test-v2v-in-place.sh -deleted file mode 100755 -index e55daa0..0000000 ---- a/v2v/test-v2v-in-place.sh -+++ /dev/null -@@ -1,121 +0,0 @@ --#!/bin/bash - --# libguestfs virt-v2v test script --# Copyright (C) 2014 Red Hat Inc. --# Copyright (C) 2015 Parallels IP Holdings GmbH. --# --# This program is free software; you can redistribute it and/or modify --# it under the terms of the GNU General Public License as published by --# the Free Software Foundation; either version 2 of the License, or --# (at your option) any later version. --# --# This program is distributed in the hope that it will be useful, --# but WITHOUT ANY WARRANTY; without even the implied warranty of --# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --# GNU General Public License for more details. --# --# You should have received a copy of the GNU General Public License --# along with this program; if not, write to the Free Software --# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -- --# Test --in-place. -- --unset CDPATH --export LANG=C --set -e -- --if [ -n "$SKIP_TEST_V2V_IN_PLACE_SH" ]; then -- echo "$0: test skipped because environment variable is set" -- exit 77 --fi -- --if [ "$(guestfish get-backend)" = "uml" ]; then -- echo "$0: test skipped because UML backend does not support network" -- exit 77 --fi -- --abs_top_builddir="$(cd ..; pwd)" -- --img_base="$abs_top_builddir/test-data/phony-guests/windows.img" --if ! test -f $img_base || ! test -s $img_base; then -- echo "$0: test skipped because phony Windows image was not created" -- exit 77 --fi -- --export VIRT_TOOLS_DATA_DIR="$srcdir/../test-data/fake-virt-tools" --export VIRTIO_WIN="$srcdir/../test-data/fake-virtio-win" -- --. $srcdir/../test-data/guestfs-hashsums.sh -- --d=$PWD/test-v2v-in-place.d --rm -rf $d --mkdir $d -- --img="$d/test.qcow2" --rm -f $img --qemu-img create -f qcow2 -b $img_base -o compat=1.1,backing_fmt=raw $img --md5="$(do_md5 $img_base)" -- --libvirt_xml="$d/test.xml" --rm -f $libvirt_xml --n=windows-overlay --cat > $libvirt_xml < -- -- $n -- 1048576 -- -- hvm -- -- -- -- -- -- -- -- -- -- -- --EOF -- --$VG virt-v2v --debug-gc -i libvirt -ic "test://$libvirt_xml" $n --in-place -- --# Test that the drivers have been copied over into the guest --script="$d/test.fish" --expected="$d/expected" --response="$d/response" -- --mktest () --{ -- local cmd="$1" exp="$2" -- -- echo "echo '$cmd'" >> "$script" -- echo "$cmd" >> "$expected" -- -- echo "$cmd" >> "$script" -- echo "$exp" >> "$expected" --} -- --:> "$script" --:> "$expected" -- --firstboot_dir="/Program Files/Red Hat/Firstboot" --mktest "is-dir \"$firstboot_dir\"" true --mktest "is-file \"$firstboot_dir/firstboot.bat\"" true --mktest "is-dir \"$firstboot_dir/scripts\"" true --virtio_dir="/Windows/Drivers/VirtIO" --mktest "is-dir \"$virtio_dir\"" true --for drv in netkvm qxl vioscsi viostor; do -- for sfx in cat inf sys; do -- mktest "is-file \"$virtio_dir/$drv.$sfx\"" true -- done --done -- --guestfish --ro -a "$img" -i < "$script" > "$response" --diff -u "$expected" "$response" -- --# Test the base image remained untouched --test "$md5" = "$(do_md5 $img_base)" -- --# Clean up. --rm -r $d -diff --git a/v2v/virt-v2v.pod b/v2v/virt-v2v.pod -index 8e5cf1d..5800b34 100644 ---- a/v2v/virt-v2v.pod -+++ b/v2v/virt-v2v.pod -@@ -15,8 +15,6 @@ virt-v2v - Convert a guest to use KVM - - virt-v2v -i disk disk.img -o glance - -- virt-v2v -ic qemu:///system qemu_guest --in-place -- - =head1 DESCRIPTION - - Virt-v2v converts guests from a foreign hypervisor to run on KVM. It -@@ -77,9 +75,6 @@ booting the guest directly in qemu (mainly for testing). - I<-o rhev> is used to write to a RHEV-M / oVirt target. I<-o vdsm> - is only used when virt-v2v runs under VDSM control. - --I<--in-place> instructs virt-v2v to customize the guest OS in the input --virtual machine, instead of creating a new VM in the target hypervisor. -- - =head1 EXAMPLES - - =head2 Convert from VMware vCenter server to local libvirt -@@ -248,18 +243,6 @@ For I<-i disk> only, this specifies the format of the input disk - image. For other input methods you should specify the input - format in the metadata. - --=item B<--in-place> -- --Do not create an output virtual machine in the target hypervisor. --Instead, adjust the guest OS in the source VM to run in the input --hypervisor. -- --This mode is meant for integration with other toolsets, which take the --responsibility of converting the VM configuration, providing for --rollback in case of errors, transforming the storage, etc. -- --Conflicts with all I<-o *> options. -- - =item B<--machine-readable> - - This option is used to make the output more machine friendly --- -1.8.3.1 - diff --git a/SOURCES/0024-RHEL-7-v2v-Remove-dcpath-option-RHBZ-1315237-RHBZ-14.patch b/SOURCES/0024-RHEL-7-v2v-Remove-dcpath-option-RHBZ-1315237-RHBZ-14.patch new file mode 100644 index 0000000..156fc8e --- /dev/null +++ b/SOURCES/0024-RHEL-7-v2v-Remove-dcpath-option-RHBZ-1315237-RHBZ-14.patch @@ -0,0 +1,63 @@ +From c04a77d09ad5b0a5238681f6e2b9b485f44f1599 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Thu, 23 Jun 2016 10:38:47 -0400 +Subject: [PATCH] RHEL 7: v2v: Remove --dcpath option (RHBZ#1315237, + RHBZ#1429430) + +This is no longer required, since RHEL 7.3. +--- + v2v/cmdline.ml | 2 +- + v2v/test-v2v-docs.sh | 2 +- + v2v/virt-v2v.pod | 13 ------------- + 3 files changed, 2 insertions(+), 15 deletions(-) + +diff --git a/v2v/cmdline.ml b/v2v/cmdline.ml +index 9aecb5c..a2f132b 100644 +--- a/v2v/cmdline.ml ++++ b/v2v/cmdline.ml +@@ -172,7 +172,7 @@ let parse_cmdline () = + [ S 'b'; L"bridge" ], Getopt.String ("in:out", add_bridge), s_"Map bridge 'in' to 'out'"; + [ L"compressed" ], Getopt.Set compressed, s_"Compress output file"; + [ L"dcpath"; L"dcPath" ], Getopt.String ("path", set_string_option_once "--dcpath" dcpath), +- s_"Override dcPath (for vCenter)"; ++ ""; + [ L"debug-overlay"; L"debug-overlays" ], Getopt.Set debug_overlays, s_"Save overlay files"; + [ S 'i' ], Getopt.String (i_options, set_input_mode), s_"Set input mode (default: libvirt)"; + [ M"ic" ], Getopt.String ("uri", set_string_option_once "-ic" input_conn), +diff --git a/v2v/test-v2v-docs.sh b/v2v/test-v2v-docs.sh +index c5d98de..02750fa 100755 +--- a/v2v/test-v2v-docs.sh ++++ b/v2v/test-v2v-docs.sh +@@ -22,4 +22,4 @@ $TEST_FUNCTIONS + skip_if_skipped + + $top_srcdir/podcheck.pl virt-v2v.pod virt-v2v \ +- --ignore=--dcPath,--debug-overlay,--ic,--if,--in-place,--no-trim,--oa,--oc,--of,--on,--os,--vmtype ++ --ignore=--dcpath,--dcPath,--debug-overlay,--ic,--if,--in-place,--no-trim,--oa,--oc,--of,--on,--os,--vmtype +diff --git a/v2v/virt-v2v.pod b/v2v/virt-v2v.pod +index c45828b..f4def73 100644 +--- a/v2v/virt-v2v.pod ++++ b/v2v/virt-v2v.pod +@@ -169,19 +169,6 @@ Write a compressed output file. This is only allowed if the output + format is qcow2 (see I<-of> below), and is equivalent to the I<-c> + option of L. + +-=item B<--dcpath> Folder/Datacenter +- +-B You don't need to use this parameter if you have +-S 1.2.20>. +- +-For VMware vCenter, override the C parameter used to +-select the datacenter. Virt-v2v can usually calculate this from the +-C URI, but if it gets it wrong, then you can override it using +-this setting. Go to your vCenter web folder interface, eg. +-C (I a trailing slash), +-and examine the C parameter in the URLs that appear on this +-page. +- + =item B<--debug-overlays> + + Save the overlay file(s) created during conversion. This option is +-- +2.9.4 + diff --git a/SOURCES/0025-RHEL-7-v2v-i-disk-force-VNC-as-display-RHBZ-1372671.patch b/SOURCES/0025-RHEL-7-v2v-i-disk-force-VNC-as-display-RHBZ-1372671.patch new file mode 100644 index 0000000..6bb8256 --- /dev/null +++ b/SOURCES/0025-RHEL-7-v2v-i-disk-force-VNC-as-display-RHBZ-1372671.patch @@ -0,0 +1,26 @@ +From ba326a8e1e0258a4254d1304f3c7447e996e3dc4 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Thu, 2 Mar 2017 14:21:37 +0100 +Subject: [PATCH] RHEL 7: v2v: -i disk: force VNC as display (RHBZ#1372671) + +The SDL output mode is not supported in RHEL 7's qemu-kvm. +--- + v2v/input_disk.ml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/v2v/input_disk.ml b/v2v/input_disk.ml +index 27f8553..1f319a4 100644 +--- a/v2v/input_disk.ml ++++ b/v2v/input_disk.ml +@@ -83,7 +83,7 @@ class input_disk input_format disk = object + s_features = [ "acpi"; "apic"; "pae" ]; + s_firmware = UnknownFirmware; (* causes virt-v2v to autodetect *) + s_display = +- Some { s_display_type = Window; s_keymap = None; s_password = None; ++ Some { s_display_type = VNC; s_keymap = None; s_password = None; + s_listen = LNoListen; s_port = None }; + s_video = None; + s_sound = None; +-- +2.9.4 + diff --git a/SOURCES/0025-p2v-User-can-click-on-an-interface-name-to-identify-.patch b/SOURCES/0025-p2v-User-can-click-on-an-interface-name-to-identify-.patch deleted file mode 100644 index 254d8b7..0000000 --- a/SOURCES/0025-p2v-User-can-click-on-an-interface-name-to-identify-.patch +++ /dev/null @@ -1,137 +0,0 @@ -From a45d0183563fb3bb3b08d5d0a8ffcc5205d40a9b Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Tue, 26 Jan 2016 15:34:09 +0000 -Subject: [PATCH] p2v: User can click on an interface name to identify the - physical interface. - -When the user clicks on the second column of the list of network -interfaces, run 'ethtool --identify 10', which (on supported -cards) flashes a light on the physical interface for 10 seconds, -allowing it to be identified by the operator. - -(cherry picked from commit 81ff8c5d23642667569833cd820e84814157580b) ---- - p2v/gui.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- - p2v/virt-p2v.pod | 4 ++++ - 2 files changed, 73 insertions(+), 1 deletion(-) - -diff --git a/p2v/gui.c b/p2v/gui.c -index c345e34..569a295 100644 ---- a/p2v/gui.c -+++ b/p2v/gui.c -@@ -418,6 +418,7 @@ static void populate_removable (GtkTreeView *removable_list); - static void populate_interfaces (GtkTreeView *interfaces_list); - static void toggled (GtkCellRendererToggle *cell, gchar *path_str, gpointer data); - static void network_edited_callback (GtkCellRendererToggle *cell, gchar *path_str, gchar *new_text, gpointer data); -+static gboolean maybe_identify_click (GtkWidget *interfaces_list, GdkEventButton *event, gpointer data); - static void set_disks_from_ui (struct config *); - static void set_removable_from_ui (struct config *); - static void set_interfaces_from_ui (struct config *); -@@ -653,6 +654,10 @@ create_conversion_dialog (struct config *config) - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (interfaces_sw), - GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); - interfaces_list = gtk_tree_view_new (); -+ /* See maybe_identify_click below for what we're doing. */ -+ g_signal_connect (interfaces_list, "button-press-event", -+ G_CALLBACK (maybe_identify_click), NULL); -+ gtk_widget_set_tooltip_markup (interfaces_list, _("Left click on an interface name to flash the light on the physical interface.")); - populate_interfaces (GTK_TREE_VIEW (interfaces_list)); - gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (interfaces_sw), - interfaces_list); -@@ -944,7 +949,8 @@ populate_interfaces (GtkTreeView *interfaces_list) - "" - "%s\n" - "%s" -- "", -+ "\n" -+ "Identify interface", - if_name, - if_addr ? : _("Unknown"), - if_vendor ? : _("Unknown")) == -1) { -@@ -1034,6 +1040,68 @@ network_edited_callback (GtkCellRendererToggle *cell, gchar *path_str, - gtk_tree_path_free (path); - } - -+/* When the user clicks on the interface name on the list of -+ * interfaces, we want to run 'ethtool --identify', which usually -+ * makes some lights flash on the physical interface. We cannot catch -+ * clicks on the cell itself, so we have to go via a more obscure -+ * route. See http://stackoverflow.com/a/27207433 and -+ * https://en.wikibooks.org/wiki/GTK%2B_By_Example/Tree_View/Events -+ */ -+static gboolean -+maybe_identify_click (GtkWidget *interfaces_list, GdkEventButton *event, -+ gpointer data) -+{ -+ gboolean ret = FALSE; /* Did we handle this event? */ -+ -+ /* Single left click only. */ -+ if (event->type == GDK_BUTTON_PRESS && event->button == 1) { -+ GtkTreePath *path; -+ GtkTreeViewColumn *column; -+ -+ if (gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (interfaces_list), -+ event->x, event->y, -+ &path, &column, NULL, NULL)) { -+ GList *cols; -+ gint column_index; -+ -+ /* Get column index. */ -+ cols = gtk_tree_view_get_columns (GTK_TREE_VIEW (interfaces_list)); -+ column_index = g_list_index (cols, (gpointer) column); -+ g_list_free (cols); -+ -+ if (column_index == INTERFACES_COL_DEVICE) { -+ const gint *indices; -+ gint row_index; -+ const char *if_name; -+ char *cmd; -+ -+ /* Get the row index. */ -+ indices = gtk_tree_path_get_indices (path); -+ row_index = indices[0]; -+ -+ /* And the interface name. */ -+ if_name = all_interfaces[row_index]; -+ -+ /* Issue the ethtool command in the background. */ -+ if (asprintf (&cmd, "ethtool --identify '%s' 10 &", if_name) == -1) { -+ perror ("asprintf"); -+ exit (EXIT_FAILURE); -+ } -+ printf ("%s\n", cmd); -+ ignore_value (system (cmd)); -+ -+ free (cmd); -+ -+ ret = TRUE; /* We handled this event. */ -+ } -+ -+ gtk_tree_path_free (path); -+ } -+ } -+ -+ return ret; -+} -+ - static void - set_from_ui_generic (char **all, char ***ret, GtkTreeView *list) - { -diff --git a/p2v/virt-p2v.pod b/p2v/virt-p2v.pod -index a3987f4..3e4ef99 100644 ---- a/p2v/virt-p2v.pod -+++ b/p2v/virt-p2v.pod -@@ -232,6 +232,10 @@ should be created in the guest after conversion. You can also connect - these to target hypervisor networks (for further information about - this feature, see L). - -+On supported hardware, left-clicking on the device name (eg. C) -+causes a light to start flashing on the physical interface, allowing -+the interface to be identified by the operator. -+ - When you are ready to begin the conversion, press the - C button: - --- -1.8.3.1 - diff --git a/SOURCES/0026-RHEL-7-v2v-do-not-mention-SUSE-Xen-hosts-RHBZ-143020.patch b/SOURCES/0026-RHEL-7-v2v-do-not-mention-SUSE-Xen-hosts-RHBZ-143020.patch new file mode 100644 index 0000000..27828ef --- /dev/null +++ b/SOURCES/0026-RHEL-7-v2v-do-not-mention-SUSE-Xen-hosts-RHBZ-143020.patch @@ -0,0 +1,27 @@ +From 6a753511ad8624efd71529aae0644b84ca0336f6 Mon Sep 17 00:00:00 2001 +From: Pino Toscano +Date: Wed, 8 Mar 2017 11:03:40 +0100 +Subject: [PATCH] RHEL 7: v2v: do not mention SUSE Xen hosts (RHBZ#1430203) + +They are not supported in RHEL 7. +--- + v2v/virt-v2v.pod | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/v2v/virt-v2v.pod b/v2v/virt-v2v.pod +index f4def73..7ad674d 100644 +--- a/v2v/virt-v2v.pod ++++ b/v2v/virt-v2v.pod +@@ -1178,8 +1178,7 @@ Remove the F and F files. + + =head1 INPUT FROM XEN + +-Virt-v2v is able to import Xen guests from RHEL 5 Xen or SLES and +-openSUSE Xen hosts. ++Virt-v2v is able to import Xen guests from RHEL 5 Xen hosts. + + Virt-v2v uses libvirt for access to the remote Xen host, and therefore + the input mode should be I<-i libvirt>. As this is the default, you +-- +2.9.4 + diff --git a/SOURCES/0026-p2v-virt-p2v-make-disk-Make-os-version-parameter-opt.patch b/SOURCES/0026-p2v-virt-p2v-make-disk-Make-os-version-parameter-opt.patch deleted file mode 100644 index 8366416..0000000 --- a/SOURCES/0026-p2v-virt-p2v-make-disk-Make-os-version-parameter-opt.patch +++ /dev/null @@ -1,130 +0,0 @@ -From 57b9f5b7827c0545ee286b3f0cfab7ae5fcadeb1 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Wed, 27 Jan 2016 11:48:53 +0000 -Subject: [PATCH] p2v: virt-p2v-make-disk: Make os-version parameter optional. - -Having to choose the os-version of the virt-p2v disk was confusing. -Users thought it had something to do with the physical machine being -converted. - -In some cases, virt-p2v-make-disk can now choose a suitable os-version -for the user. Usually it's the latest numeric version of Fedora or -Debian, depending on the host distro. If we don't recognize the host -distro, we bail and ask the user to choose, but this is still an -improvement. - -(cherry picked from commit 3aaa4c9419d539dada31004b47121bbaac5241c6) ---- - p2v/virt-p2v-make-disk.in | 26 ++++++++++++++++++++++---- - p2v/virt-p2v-make-disk.pod | 30 ++++++++++++++++++------------ - 2 files changed, 40 insertions(+), 16 deletions(-) - -diff --git a/p2v/virt-p2v-make-disk.in b/p2v/virt-p2v-make-disk.in -index 6769707..88c171f 100644 ---- a/p2v/virt-p2v-make-disk.in -+++ b/p2v/virt-p2v-make-disk.in -@@ -38,7 +38,7 @@ upload= - usage () - { - echo "Usage:" -- echo " $program [--options] -o /dev/sdX os-version" -+ echo " $program [--options] -o /dev/sdX [os-version]" - echo - echo "Read $program(1) man page for more information." - exit $1 -@@ -71,12 +71,30 @@ if [ -z "$output" ]; then - exit 1 - fi - --if [ $# -ne 1 ]; then -- echo "$program: Missing os-version. See $program(1)." -+if [ $# -gt 1 ]; then -+ echo "$program: Too many parameters. See $program(1)." - exit 1 - fi - --osversion="$1" -+if [ $# -eq 1 ]; then -+ osversion="$1" -+else -+ # If osversion was not set, then we must guess a good value -+ # based on the host distro. -+ if test -f /etc/redhat-release; then -+ osversion="$(virt-builder -l | sort | -+ @AWK@ '/^fedora-[1-9]/ {print $1}' | tail -1)" -+ elif test -f /etc/debian_version; then -+ osversion="$(virt-builder -l | sort | -+ @AWK@ '/^debian-[1-9]/ {print $1}' | tail -1)" -+ fi -+ if [ "x$osversion" = "x" ]; then -+ echo "$program: unable to guess a suitable os-version." -+ echo "You must supply one on the command line and output of 'virt-builder -l'." -+ echo "See $program(1) for further details." -+ exit 1 -+ fi -+fi - - # Create a temporary directory and clean it up when we finish. - tmpdir="$(mktemp -d)" -diff --git a/p2v/virt-p2v-make-disk.pod b/p2v/virt-p2v-make-disk.pod -index d401097..79bf499 100644 ---- a/p2v/virt-p2v-make-disk.pod -+++ b/p2v/virt-p2v-make-disk.pod -@@ -4,7 +4,7 @@ virt-p2v-make-disk - Build the virt-p2v disk using virt-builder - - =head1 SYNOPSIS - -- virt-p2v-make-disk -o /dev/sdX os-version -+ virt-p2v-make-disk -o /dev/sdX [os-version] - - =head1 DESCRIPTION - -@@ -17,28 +17,34 @@ virt-p2v-make-disk is a script which creates a bootable disk image or - USB key containing virt-p2v. It uses L to do this, - and is just a small shell script around virt-builder. - --virt-p2v-make-disk has two required parameters: -+The required I<-o> parameter specifies where the output should go, for -+example to a USB key (eg. C<-o /dev/sdX>) or to a file. If you pass a -+device name, then B. - --The I<-o> parameter specifies where the output should go, for example --to a USB key (eg. C<-o /dev/sdX>) or to a file. If you pass a device --name, then B. -+=head2 C parameter - --The C parameter is the base Linux distro to use for the --operating system on the ISO. To list possible C --combinations, do: -+The optional C parameter is the base Linux distro to use -+for the operating system on the ISO. If you don't set this parameter, -+the script tries to choose a suitable default for you. Most users -+should I use the C parameter. -+ -+The base OS selected for virt-p2v is not related in any way to the OS -+of the physical machine that you are trying to convert. -+ -+To list possible C combinations, do: - - virt-builder -l - --=head2 EXAMPLES -+=head1 EXAMPLES - - Write a virt-p2v bootable USB key on F (any existing content --is erased), using Fedora 20 as the base distribution: -+on F is erased): - -- virt-p2v-make-disk -o /dev/sdX fedora-20 -+ virt-p2v-make-disk -o /dev/sdX - - Write a virt-p2v bootable virtual disk image, and boot it under qemu: - -- virt-p2v-make-disk -o /var/tmp/p2v.img fedora-20 -+ virt-p2v-make-disk -o /var/tmp/p2v.img - qemu-kvm -m 1024 -boot c \ - -drive file=/var/tmp/p2v.img,if=virtio,index=0 \ - -drive file=/var/tmp/guest.img,if=virtio,index=1 --- -1.8.3.1 - diff --git a/SOURCES/0027-daemon-glob-add-optarg-to-control-trailing-slash-for.patch b/SOURCES/0027-daemon-glob-add-optarg-to-control-trailing-slash-for.patch deleted file mode 100644 index 5d5ef7b..0000000 --- a/SOURCES/0027-daemon-glob-add-optarg-to-control-trailing-slash-for.patch +++ /dev/null @@ -1,138 +0,0 @@ -From f0891277008c6535aa12e2e9b1b52eb8da6bc678 Mon Sep 17 00:00:00 2001 -From: Pino Toscano -Date: Thu, 4 Feb 2016 10:45:20 +0100 -Subject: [PATCH] daemon: glob: add optarg to control trailing slash for dirs - -Add a new optional bool "directoryslash" to indicate whether the caller -wants trailing slashes in names of directories, defaulting to true (the -current behaviour); this helps with interoperability with other tools -(such as rm). - -Related to RHBZ#1293271. - -(cherry picked from commit 01f46e4e3128b8d8ab009ca198de440e776c2cd6) ---- - daemon/glob.c | 11 +++++++++-- - generator/actions.ml | 21 ++++++++++++++++----- - gobject/Makefile.inc | 2 ++ - po/POTFILES | 1 + - 4 files changed, 28 insertions(+), 7 deletions(-) - -diff --git a/daemon/glob.c b/daemon/glob.c -index 45fb30f..a22fd33 100644 ---- a/daemon/glob.c -+++ b/daemon/glob.c -@@ -26,14 +26,21 @@ - #include "actions.h" - - char ** --do_glob_expand (const char *pattern) -+do_glob_expand (const char *pattern, int directoryslash) - { - int r; - glob_t buf = { .gl_pathc = 0, .gl_pathv = NULL, .gl_offs = 0 }; -+ int flags = GLOB_BRACE | GLOB_MARK; -+ -+ /* GLOB_MARK is default, unless the user explicitly disabled it. */ -+ if ((optargs_bitmask & GUESTFS_GLOB_EXPAND_DIRECTORYSLASH_BITMASK) -+ && !directoryslash) { -+ flags &= ~GLOB_MARK; -+ } - - /* glob(3) in glibc never calls chdir, so this seems to be safe: */ - CHROOT_IN; -- r = glob (pattern, GLOB_MARK|GLOB_BRACE, NULL, &buf); -+ r = glob (pattern, flags, NULL, &buf); - CHROOT_OUT; - - if (r == GLOB_NOMATCH) { /* Return an empty list instead of an error. */ -diff --git a/generator/actions.ml b/generator/actions.ml -index dfeb34c..998caa5 100644 ---- a/generator/actions.ml -+++ b/generator/actions.ml -@@ -5908,27 +5908,34 @@ See also: C" }; - * start with "/". There is no concept of "cwd" in libguestfs, - * hence no "."-relative names. - *) -- style = RStringList "paths", [Pathname "pattern"], []; -+ style = RStringList "paths", [Pathname "pattern"], [OBool "directoryslash"]; - proc_nr = Some 113; -+ once_had_no_optargs = true; - tests = [ - InitScratchFS, Always, TestResult ( - [["mkdir_p"; "/glob_expand/b/c"]; - ["touch"; "/glob_expand/b/c/d"]; - ["touch"; "/glob_expand/b/c/e"]; -- ["glob_expand"; "/glob_expand/b/c/*"]], -+ ["glob_expand"; "/glob_expand/b/c/*"; ""]], - "is_string_list (ret, 2, \"/glob_expand/b/c/d\", \"/glob_expand/b/c/e\")"), []; - InitScratchFS, Always, TestResult ( - [["mkdir_p"; "/glob_expand2/b/c"]; - ["touch"; "/glob_expand2/b/c/d"]; - ["touch"; "/glob_expand2/b/c/e"]; -- ["glob_expand"; "/glob_expand2/*/c/*"]], -+ ["glob_expand"; "/glob_expand2/*/c/*"; ""]], - "is_string_list (ret, 2, \"/glob_expand2/b/c/d\", \"/glob_expand2/b/c/e\")"), []; - InitScratchFS, Always, TestResult ( - [["mkdir_p"; "/glob_expand3/b/c"]; - ["touch"; "/glob_expand3/b/c/d"]; - ["touch"; "/glob_expand3/b/c/e"]; -- ["glob_expand"; "/glob_expand3/*/x/*"]], -- "is_string_list (ret, 0)"), [] -+ ["glob_expand"; "/glob_expand3/*/x/*"; ""]], -+ "is_string_list (ret, 0)"), []; -+ InitScratchFS, Always, TestResult ( -+ [["mkdir_p"; "/glob_expand4/b/c"]; -+ ["touch"; "/glob_expand4/b1"]; -+ ["touch"; "/glob_expand4/c1"]; -+ ["glob_expand"; "/glob_expand4/b*"; "false"]], -+ "is_string_list (ret, 2, \"/glob_expand4/b\", \"/glob_expand4/b1\")"), []; - ]; - shortdesc = "expand a wildcard path"; - longdesc = "\ -@@ -5943,6 +5950,10 @@ It is just a wrapper around the C L function - with flags C. - See that manual page for more details. - -+C controls whether use the C flag for -+L, and it defaults to true. It can be explicitly set as -+off to return no trailing slashes in filenames of directories. -+ - Notice that there is no equivalent command for expanding a device - name (eg. F). Use C, - C etc functions instead." }; -diff --git a/gobject/Makefile.inc b/gobject/Makefile.inc -index 20c98ff..4b99a78 100644 ---- a/gobject/Makefile.inc -+++ b/gobject/Makefile.inc -@@ -69,6 +69,7 @@ guestfs_gobject_headers= \ - include/guestfs-gobject/optargs-disk_create.h \ - include/guestfs-gobject/optargs-e2fsck.h \ - include/guestfs-gobject/optargs-fstrim.h \ -+ include/guestfs-gobject/optargs-glob_expand.h \ - include/guestfs-gobject/optargs-grep.h \ - include/guestfs-gobject/optargs-hivex_open.h \ - include/guestfs-gobject/optargs-inspect_get_icon.h \ -@@ -154,6 +155,7 @@ guestfs_gobject_sources= \ - src/optargs-disk_create.c \ - src/optargs-e2fsck.c \ - src/optargs-fstrim.c \ -+ src/optargs-glob_expand.c \ - src/optargs-grep.c \ - src/optargs-hivex_open.c \ - src/optargs-inspect_get_icon.c \ -diff --git a/po/POTFILES b/po/POTFILES -index d4058ac..a5f3f9e 100644 ---- a/po/POTFILES -+++ b/po/POTFILES -@@ -194,6 +194,7 @@ gobject/src/optargs-cpio_out.c - gobject/src/optargs-disk_create.c - gobject/src/optargs-e2fsck.c - gobject/src/optargs-fstrim.c -+gobject/src/optargs-glob_expand.c - gobject/src/optargs-grep.c - gobject/src/optargs-hivex_open.c - gobject/src/optargs-inspect_get_icon.c --- -1.8.3.1 - diff --git a/SOURCES/0027-sysprep-Remove-DHCP_HOSTNAME-from-ifcfg-files-RHBZ-1.patch b/SOURCES/0027-sysprep-Remove-DHCP_HOSTNAME-from-ifcfg-files-RHBZ-1.patch new file mode 100644 index 0000000..3d5bfda --- /dev/null +++ b/SOURCES/0027-sysprep-Remove-DHCP_HOSTNAME-from-ifcfg-files-RHBZ-1.patch @@ -0,0 +1,42 @@ +From db166d40204d854d852880c154ae55a18b6f8acf Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Tue, 28 Feb 2017 15:48:18 +0000 +Subject: [PATCH] sysprep: Remove DHCP_HOSTNAME= from ifcfg-* files + (RHBZ#1427529). + +(cherry picked from commit 0f99537cb69c88f7ceb6c69a9d9ae10baaaa3623) +--- + sysprep/sysprep_operation_net_hostname.ml | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +diff --git a/sysprep/sysprep_operation_net_hostname.ml b/sysprep/sysprep_operation_net_hostname.ml +index 3824d42..7284d63 100644 +--- a/sysprep/sysprep_operation_net_hostname.ml ++++ b/sysprep/sysprep_operation_net_hostname.ml +@@ -30,10 +30,12 @@ let net_hostname_perform (g : Guestfs.guestfs) root side_effects = + let filenames = g#glob_expand "/etc/sysconfig/network-scripts/ifcfg-*" in + Array.iter ( + fun filename -> +- (* Replace HOSTNAME=... entry. *) ++ (* Remove HOSTNAME=... and DHCP_HOSTNAME=... entries. *) + let lines = Array.to_list (g#read_lines filename) in + let lines = List.filter ( +- fun line -> not (String.is_prefix line "HOSTNAME=") ++ fun line -> ++ not (String.is_prefix line "HOSTNAME=") && ++ not (String.is_prefix line "DHCP_HOSTNAME=") + ) lines in + let file = String.concat "\n" lines ^ "\n" in + g#write filename file; +@@ -46,7 +48,7 @@ let op = { + defaults with + name = "net-hostname"; + enabled_by_default = true; +- heading = s_"Remove HOSTNAME in network interface configuration"; ++ heading = s_"Remove HOSTNAME and DHCP_HOSTNAME in network interface configuration"; + pod_description = Some (s_"\ + For Fedora and Red Hat Enterprise Linux, + this is removed from C files."); +-- +2.9.4 + diff --git a/SOURCES/0028-customize-add-globbing-for-delete.patch b/SOURCES/0028-customize-add-globbing-for-delete.patch deleted file mode 100644 index 4373004..0000000 --- a/SOURCES/0028-customize-add-globbing-for-delete.patch +++ /dev/null @@ -1,50 +0,0 @@ -From faa050d685a7c7005d683b716bcb657bdf958440 Mon Sep 17 00:00:00 2001 -From: Pino Toscano -Date: Thu, 4 Feb 2016 10:49:31 +0100 -Subject: [PATCH] customize: add globbing for --delete - -Support globbing in paths passed to --delete, telling glob to not -return directories with leading slash. - -This re-adds back globbing for --delete in virt-sysprep, which was -available before the integration with common code from virt-customize. - -(cherry picked from commit 13c3698358a4de82179dba3c8855f56746525aa7) ---- - customize/customize_run.ml | 2 +- - generator/customize.ml | 6 ++++++ - 2 files changed, 7 insertions(+), 1 deletion(-) - -diff --git a/customize/customize_run.ml b/customize/customize_run.ml -index 2caaa98..8c38d62 100644 ---- a/customize/customize_run.ml -+++ b/customize/customize_run.ml -@@ -205,7 +205,7 @@ exec >>%s 2>&1 - - | `Delete path -> - message (f_"Deleting: %s") path; -- g#rm_rf path -+ Array.iter g#rm_rf (g#glob_expand ~directoryslash:false path) - - | `Edit (path, expr) -> - message (f_"Editing: %s") path; -diff --git a/generator/customize.ml b/generator/customize.ml -index 63e4246..403bb89 100644 ---- a/generator/customize.ml -+++ b/generator/customize.ml -@@ -117,6 +117,12 @@ Wildcards cannot be used."; - Delete a file from the guest. Or delete a directory (and all its - contents, recursively). - -+You can use shell glob characters in the specified path. Be careful -+to escape glob characters from the host shell, if that is required. -+For example: -+ -+ virt-customize --delete '/var/log/*.log'. -+ - See also: I<--upload>, I<--scrub>."; - }; - --- -1.8.3.1 - diff --git a/SOURCES/0028-p2v-v2v-Ensure-the-full-version-is-always-available-.patch b/SOURCES/0028-p2v-v2v-Ensure-the-full-version-is-always-available-.patch new file mode 100644 index 0000000..28b0f4a --- /dev/null +++ b/SOURCES/0028-p2v-v2v-Ensure-the-full-version-is-always-available-.patch @@ -0,0 +1,181 @@ +From a1385efa3499d7668128c90e26790e08e61897de Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Tue, 28 Mar 2017 23:03:31 +0100 +Subject: [PATCH] p2v, v2v: Ensure the full version is always available in + several places. + +Ensure the full version of virt-v2v and virt-p2v is available in the +conversion log file, the only log file that we reliably get from users +and customers. "Full version" means the major, minor, release and +extra fields. The extra field is especially important as it contains +the downstream package release in Fedora, RHEL etc. + +This change saves the virt-p2v version as a comment in the +physical.xml file, which is included in full in the conversion log (by +virt-v2v). + +It also ensures that the initial virt-v2v debug message contains the +full version number including the 'extra' field. + + $ cat virt-v2v-conversion-log.txt + virt-v2v: libguestfs 1.37.7local,libvirt (x86_64) + ... + + +It also adds 'p2v-version' and 'v2v-version' files in the virt-p2v +debug directory. These are strictly superfluous but could be useful +for end users. + + $ cat p2v-version + virt-p2v 1.37.7local,libvirt + $ cat v2v-version + virt-v2v 1.37.7local,libvirt + +(cherry picked from commit 7cae10f0c11ebde643ec575f7f779aa1e7103d6b) +--- + p2v/conversion.c | 40 ++++++++++++++++++++++++++++++++++++---- + p2v/virt-p2v.pod | 8 ++++++++ + v2v/v2v.ml | 4 ++-- + 3 files changed, 46 insertions(+), 6 deletions(-) + +diff --git a/p2v/conversion.c b/p2v/conversion.c +index 0c17ef2..beda2b8 100644 +--- a/p2v/conversion.c ++++ b/p2v/conversion.c +@@ -95,6 +95,7 @@ static void generate_libvirt_xml (struct config *, struct data_conn *, const cha + static void generate_wrapper_script (struct config *, const char *remote_dir, const char *filename); + static void generate_system_data (const char *dmesg_file, const char *lscpu_file, const char *lspci_file, const char *lsscsi_file, const char *lsusb_file); + static const char *map_interface_to_network (struct config *, const char *interface); ++static void generate_p2v_version_file (const char *p2v_version_file); + static void print_quoted (FILE *fp, const char *s); + + static char *conversion_error; +@@ -206,6 +207,7 @@ start_conversion (struct config *config, + char lspci_file[] = "/tmp/p2v.XXXXXX/lspci"; + char lsscsi_file[] = "/tmp/p2v.XXXXXX/lsscsi"; + char lsusb_file[] = "/tmp/p2v.XXXXXX/lsusb"; ++ char p2v_version_file[] = "/tmp/p2v.XXXXXX/p2v-version"; + int inhibit_fd = -1; + + #if DEBUG_STDERR +@@ -342,6 +344,7 @@ start_conversion (struct config *config, + memcpy (lspci_file, tmpdir, strlen (tmpdir)); + memcpy (lsscsi_file, tmpdir, strlen (tmpdir)); + memcpy (lsusb_file, tmpdir, strlen (tmpdir)); ++ memcpy (p2v_version_file, tmpdir, strlen (tmpdir)); + + /* Generate the static files. */ + generate_name (config, name_file); +@@ -349,6 +352,7 @@ start_conversion (struct config *config, + generate_wrapper_script (config, remote_dir, wrapper_script); + generate_system_data (dmesg_file, + lscpu_file, lspci_file, lsscsi_file, lsusb_file); ++ generate_p2v_version_file (p2v_version_file); + + /* Open the control connection. This also creates remote_dir. */ + if (notify_ui) +@@ -383,6 +387,7 @@ start_conversion (struct config *config, + ignore_value (scp_file (config, lspci_file, remote_dir)); + ignore_value (scp_file (config, lsscsi_file, remote_dir)); + ignore_value (scp_file (config, lsusb_file, remote_dir)); ++ ignore_value (scp_file (config, p2v_version_file, remote_dir)); + + /* Do the conversion. This runs until virt-v2v exits. */ + if (notify_ui) +@@ -546,10 +551,10 @@ cleanup_data_conns (struct data_conn *data_conns, size_t nr) + } while (0) + + /* An XML comment. */ +-#define comment(str) \ +- do { \ +- if (xmlTextWriterWriteComment (xo, BAD_CAST (str)) == -1) \ +- error (EXIT_FAILURE, errno, "xmlTextWriterWriteComment"); \ ++#define comment(fs,...) \ ++ do { \ ++ if (xmlTextWriterWriteFormatComment (xo, fs, ##__VA_ARGS__) == -1) \ ++ error (EXIT_FAILURE, errno, "xmlTextWriterWriteFormatComment"); \ + } while (0) + + /** +@@ -579,6 +584,8 @@ generate_libvirt_xml (struct config *config, struct data_conn *data_conns, + + memkb = config->memory / 1024; + ++ comment (" %s %s ", getprogname (), PACKAGE_VERSION_FULL); ++ + comment + (" NOTE!\n" + "\n" +@@ -859,6 +866,13 @@ generate_wrapper_script (struct config *config, const char *remote_dir, + fprintf (fp, "\n"); + + fprintf (fp, ++ "# Log the version of virt-v2v (for information only).\n"); ++ if (config->sudo) ++ fprintf (fp, "sudo -n "); ++ fprintf (fp, "virt-v2v --version > v2v-version\n"); ++ fprintf (fp, "\n"); ++ ++ fprintf (fp, + "# Run virt-v2v. Send stdout back to virt-p2v. Send stdout\n" + "# and stderr (debugging info) to the log file.\n"); + fprintf (fp, "v2v 2>> $log | tee -a $log\n"); +@@ -939,3 +953,21 @@ generate_system_data (const char *dmesg_file, + + ignore_value (system (cmd)); + } ++ ++/** ++ * Generate a file containing the version of virt-p2v. ++ * ++ * The version of virt-v2v is contained in the conversion log. ++ */ ++static void ++generate_p2v_version_file (const char *p2v_version_file) ++{ ++ FILE *fp = fopen (p2v_version_file, "w"); ++ if (fp == NULL) { ++ perror (p2v_version_file); ++ return; /* non-fatal */ ++ } ++ fprintf (fp, "%s %s\n", ++ getprogname (), PACKAGE_VERSION_FULL); ++ fclose (fp); ++} +diff --git a/p2v/virt-p2v.pod b/p2v/virt-p2v.pod +index 4a5f587..ee870fd 100644 +--- a/p2v/virt-p2v.pod ++++ b/p2v/virt-p2v.pod +@@ -767,6 +767,14 @@ Note this is not "real" libvirt XML (and must B be loaded into + libvirt, which would reject it anyhow). Also it is not the same as + the libvirt XML which virt-v2v generates in certain output modes. + ++=item F ++ ++=item F ++ ++I<(before conversion)> ++ ++The versions of virt-p2v and virt-v2v respectively. ++ + =item F + + I<(after conversion)> +diff --git a/v2v/v2v.ml b/v2v/v2v.ml +index 551524d..cc7b889 100644 +--- a/v2v/v2v.ml ++++ b/v2v/v2v.ml +@@ -42,8 +42,8 @@ let rec main () = + + (* Print the version, easier than asking users to tell us. *) + debug "%s: %s %s (%s)" +- prog Guestfs_config.package_name +- Guestfs_config.package_version Guestfs_config.host_cpu; ++ prog Guestfs_config.package_name Guestfs_config.package_version_full ++ Guestfs_config.host_cpu; + + (* Print the libvirt version if debugging. Note that if + * we're configured --without-libvirt, then this will throw +-- +2.9.4 + diff --git a/SOURCES/0029-p2v-Run-fewer-scp-commands.patch b/SOURCES/0029-p2v-Run-fewer-scp-commands.patch new file mode 100644 index 0000000..275cc4c --- /dev/null +++ b/SOURCES/0029-p2v-Run-fewer-scp-commands.patch @@ -0,0 +1,134 @@ +From f047435a1087f438c645d729f68f6578e8cb861d Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Thu, 30 Mar 2017 13:13:03 +0100 +Subject: [PATCH] p2v: Run fewer 'scp' commands. + +Each scp command takes a considerable amount of time -- several +seconds -- because it must set up, authenticate and tear down a new +connection. Avoid this by combining several copies into a single +command. + +We still have to use two scp commands because we want to check that +some files are copied and ignore failures in a second set of +informational files. + +(cherry picked from commit d178deeeb814471b9d70431626b6cd515a21d0c1) +--- + p2v/conversion.c | 31 +++++++++++-------------------- + p2v/p2v.h | 2 +- + p2v/ssh.c | 25 +++++++++++++++++++++---- + 3 files changed, 33 insertions(+), 25 deletions(-) + +diff --git a/p2v/conversion.c b/p2v/conversion.c +index beda2b8..0da9a62 100644 +--- a/p2v/conversion.c ++++ b/p2v/conversion.c +@@ -366,28 +366,19 @@ start_conversion (struct config *config, + } + + /* Copy the static files to the remote dir. */ +- if (scp_file (config, name_file, remote_dir) == -1) { +- set_conversion_error ("scp: %s to %s: %s", +- name_file, remote_dir, get_ssh_error ()); ++ ++ /* These three files must not fail, so check for errors here. */ ++ if (scp_file (config, remote_dir, ++ name_file, libvirt_xml_file, wrapper_script, NULL) == -1) { ++ set_conversion_error ("scp: %s: %s", ++ remote_dir, get_ssh_error ()); + goto out; + } +- if (scp_file (config, libvirt_xml_file, remote_dir) == -1) { +- set_conversion_error ("scp: %s to %s: %s", +- libvirt_xml_file, remote_dir, get_ssh_error ()); +- goto out; +- } +- if (scp_file (config, wrapper_script, remote_dir) == -1) { +- set_conversion_error ("scp: %s to %s: %s", +- wrapper_script, remote_dir, get_ssh_error ()); +- goto out; +- } +- /* It's not essential that these files are copied. */ +- ignore_value (scp_file (config, dmesg_file, remote_dir)); +- ignore_value (scp_file (config, lscpu_file, remote_dir)); +- ignore_value (scp_file (config, lspci_file, remote_dir)); +- ignore_value (scp_file (config, lsscsi_file, remote_dir)); +- ignore_value (scp_file (config, lsusb_file, remote_dir)); +- ignore_value (scp_file (config, p2v_version_file, remote_dir)); ++ ++ /* It's not essential that these files are copied, so ignore errors. */ ++ ignore_value (scp_file (config, remote_dir, ++ dmesg_file, lscpu_file, lspci_file, lsscsi_file, ++ lsusb_file, p2v_version_file, NULL)); + + /* Do the conversion. This runs until virt-v2v exits. */ + if (notify_ui) +diff --git a/p2v/p2v.h b/p2v/p2v.h +index 5223aa2..b26648a 100644 +--- a/p2v/p2v.h ++++ b/p2v/p2v.h +@@ -128,7 +128,7 @@ extern int test_connection (struct config *); + extern mexp_h *open_data_connection (struct config *, const char *local_ipaddr, int local_port, int *remote_port); + extern mexp_h *start_remote_connection (struct config *, const char *remote_dir); + extern const char *get_ssh_error (void); +-extern int scp_file (struct config *config, const char *localfile, const char *remotefile); ++extern int scp_file (struct config *config, const char *target, const char *local, ...) __attribute__((sentinel)); + + /* nbd.c */ + extern void set_nbd_option (const char *opt); +diff --git a/p2v/ssh.c b/p2v/ssh.c +index 8beaf74..bfeb806 100644 +--- a/p2v/ssh.c ++++ b/p2v/ssh.c +@@ -572,14 +572,18 @@ start_ssh (unsigned spawn_flags, struct config *config, + #endif + + /** +- * Upload a file to remote using L. ++ * Upload file(s) to remote using L. ++ * ++ * Note that the target (directory or file) comes before the list of ++ * local files, because the list of local files is a varargs list. + * + * This is a simplified version of L above. + */ + int +-scp_file (struct config *config, const char *localfile, const char *remotefile) ++scp_file (struct config *config, const char *target, const char *local, ...) + { + size_t i = 0; ++ va_list args; + const size_t MAX_ARGS = 64; + const char *argv[MAX_ARGS]; + char port_str[64]; +@@ -618,12 +622,25 @@ scp_file (struct config *config, const char *localfile, const char *remotefile) + ADD_ARG (argv, i, "-i"); + ADD_ARG (argv, i, config->identity_file); + } +- ADD_ARG (argv, i, localfile); ++ ++ /* Source files or directories. ++ * Strictly speaking this could abort() if the list of files is ++ * too long, but that never happens in virt-p2v. XXX ++ */ ++ va_start (args, local); ++ do ADD_ARG (argv, i, local); ++ while ((local = va_arg (args, const char *)) != NULL); ++ va_end (args); ++ ++ /* The target file or directory. We need to rewrite this as ++ * "username@server:target". ++ */ + if (asprintf (&remote, "%s@%s:%s", + config->username ? config->username : "root", +- config->server, remotefile) == -1) ++ config->server, target) == -1) + error (EXIT_FAILURE, errno, "asprintf"); + ADD_ARG (argv, i, remote); ++ + ADD_ARG (argv, i, NULL); + + #if DEBUG_STDERR +-- +2.9.4 + diff --git a/SOURCES/0029-p2v-tests-Don-t-supply-os-version-in-test.patch b/SOURCES/0029-p2v-tests-Don-t-supply-os-version-in-test.patch deleted file mode 100644 index fab8627..0000000 --- a/SOURCES/0029-p2v-tests-Don-t-supply-os-version-in-test.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 903abf29254069bbc3f867b36f5d23b61a0be5a8 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Wed, 27 Jan 2016 12:03:23 +0000 -Subject: [PATCH] p2v: tests: Don't supply os-version in test. - -(cherry picked from commit c323bb7db73a28f05d70fa774c702d48bd631bfa) ---- - p2v/Makefile.am | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - -diff --git a/p2v/Makefile.am b/p2v/Makefile.am -index 17745b2..487e198 100644 ---- a/p2v/Makefile.am -+++ b/p2v/Makefile.am -@@ -204,8 +204,7 @@ test-virt-p2v-pxe.img: \ - virt-p2v-make-disk - $(top_builddir)/run virt-p2v-make-disk \ - --inject-ssh-identity=test-virt-p2v-pxe.id_rsa \ -- -o $@-t \ -- fedora-22 -+ -o $@-t - mv $@-t $@ - - test-virt-p2v-pxe.vmlinuz test-virt-p2v-pxe.initramfs: stamp-test-virt-p2v-pxe-kernel --- -1.8.3.1 - diff --git a/SOURCES/0030-appliance-Pass-quiet-option-to-kernel-when-verbose.patch b/SOURCES/0030-appliance-Pass-quiet-option-to-kernel-when-verbose.patch deleted file mode 100644 index 1694abb..0000000 --- a/SOURCES/0030-appliance-Pass-quiet-option-to-kernel-when-verbose.patch +++ /dev/null @@ -1,73 +0,0 @@ -From 26a13abce6cc73595eb2adf3db46d25c017c2e06 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Thu, 17 Mar 2016 08:35:54 +0000 -Subject: [PATCH] appliance: Pass "quiet" option to kernel when !verbose. - -The quiet option suppresses kernel messages. On my laptop it improves -appliance boot times by about 40% (3.5s -> 2.5s). - -The emulated UART is slow and has a fixed, small FIFO (16 bytes). But -it has the advantage of being a simple ISA device which is available -very early in boot, thus enabling us to diagnose early boot problems. -So the aim is to reduce our usage of this UART on fast paths. - -Of course when we are in verbose mode, we should not add this flag -because we want to see all the messages. - -This change is not entirely invisible: - -(1) Progress messages use the "Linux version ..." string from kernel -output in order to determine part of where we are in the boot process. -This string will no longer be detected. We should probably use a BIOS -message or maybe drop this altogether. I have added a comment to the -code. - -(2) It is possible for programs to be listening for -GUESTFS_EVENT_APPLIANCE events, and they will see fewer messages now -(although what kernel messages programs see is never defined). - -(cherry picked from commit ed739e71f634b363c3cf6a0a4eca559eaae7f7b3) ---- - src/launch.c | 4 ++-- - src/proto.c | 3 +++ - 2 files changed, 5 insertions(+), 2 deletions(-) - -diff --git a/src/launch.c b/src/launch.c -index de50774..229069f 100644 ---- a/src/launch.c -+++ b/src/launch.c -@@ -359,7 +359,7 @@ guestfs_int_appliance_command_line (guestfs_h *g, const char *appliance_dev, - " cgroup_disable=memory" /* saves us about 5 MB of RAM */ - "%s" /* root=appliance_dev */ - " %s" /* selinux */ -- "%s" /* verbose */ -+ " %s" /* quiet/verbose */ - "%s" /* network */ - " TERM=%s" /* TERM environment variable */ - "%s%s" /* handle identifier */ -@@ -370,7 +370,7 @@ guestfs_int_appliance_command_line (guestfs_h *g, const char *appliance_dev, - lpj_s, - root, - g->selinux ? "selinux=1 enforcing=0" : "selinux=0", -- g->verbose ? " guestfs_verbose=1" : "", -+ g->verbose ? "guestfs_verbose=1" : "quiet", - g->enable_network ? " guestfs_network=1" : "", - term ? term : "linux", - STRNEQ (g->identifier, "") ? " guestfs_identifier=" : "", -diff --git a/src/proto.c b/src/proto.c -index a4fc987..1bc349a 100644 ---- a/src/proto.c -+++ b/src/proto.c -@@ -129,6 +129,9 @@ guestfs_int_log_message_callback (guestfs_h *g, const char *buf, size_t len) - const char *sentinel; - size_t slen; - -+ /* Since 2016-03, if !verbose, then we add the "quiet" flag to the -+ * kernel, so the following sentinel will never be produced. XXX -+ */ - sentinel = "Linux version"; /* kernel up */ - slen = strlen (sentinel); - if (memmem (buf, len, sentinel, slen) != NULL) --- -1.8.3.1 - diff --git a/SOURCES/0030-p2v-Fix-list-of-files-in-documentation.patch b/SOURCES/0030-p2v-Fix-list-of-files-in-documentation.patch new file mode 100644 index 0000000..ce7471d --- /dev/null +++ b/SOURCES/0030-p2v-Fix-list-of-files-in-documentation.patch @@ -0,0 +1,66 @@ +From 90ee2a3d8b55cf983d765c2c7666cad16e16250f Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Thu, 30 Mar 2017 14:45:47 +0100 +Subject: [PATCH] p2v: Fix list of files in documentation. + +(cherry picked from commit 38e7a1e038a91e34010ca0f89b0da077be821421) +--- + p2v/virt-p2v.pod | 28 +++++++++++++--------------- + 1 file changed, 13 insertions(+), 15 deletions(-) + +diff --git a/p2v/virt-p2v.pod b/p2v/virt-p2v.pod +index ee870fd..7fd6371 100644 +--- a/p2v/virt-p2v.pod ++++ b/p2v/virt-p2v.pod +@@ -724,18 +724,6 @@ Into this directory are written various files which include: + + =item F + +-I<(before conversion)> +- +-The dmesg output from the physical machine. Useful for detecting +-problems such as missing device drivers or firmware on the virt-p2v +-ISO. +- +-=item F +- +-I<(before conversion)> +- +-The content of the environment where L will run. +- + =item F + + =item F +@@ -746,8 +734,18 @@ The content of the environment where L will run. + + I<(before conversion)> + +-The output of the corresponding commands (ie L etc) on the +-physical machine. Useful for debugging novel hardware configurations. ++The output of the corresponding commands (ie L, L ++etc) on the physical machine. ++ ++The dmesg output is useful for detecting problems such as missing ++device drivers or firmware on the virt-p2v ISO. The others are useful ++for debugging novel hardware configurations. ++ ++=item F ++ ++I<(before conversion)> ++ ++The content of the environment where L will run. + + =item F + +@@ -799,7 +797,7 @@ B log file in any bug reports or support tickets. + + =item F + +-I<(during/after conversion)> ++I<(before conversion)> + + This is the wrapper script which is used when running virt-v2v. For + interest only, do not attempt to run this script yourself. +-- +2.9.4 + diff --git a/SOURCES/0031-appliance-Quiet-some-warnings-about-missing-files.patch b/SOURCES/0031-appliance-Quiet-some-warnings-about-missing-files.patch deleted file mode 100644 index 00fdb9c..0000000 --- a/SOURCES/0031-appliance-Quiet-some-warnings-about-missing-files.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 1296acc7014092eb7765e3216ac5b18b4eb13db5 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Thu, 17 Mar 2016 10:05:00 +0000 -Subject: [PATCH] appliance: Quiet some warnings about missing files. - -Try to make the appliance script as quiet as possible along -the fast path. - -(cherry picked from commit 5897b3bbad8c234be2b20685c7714628ea5ec5a0) ---- - appliance/init | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/appliance/init b/appliance/init -index ff8f5df..3b76486 100755 ---- a/appliance/init -+++ b/appliance/init -@@ -83,9 +83,11 @@ fi - - # Disk optimizations. - # Increase the SCSI timeout so we can read remote images. -+shopt -s nullglob - for f in /sys/block/sd*/device/timeout; do echo 300 > $f; done - # https://access.redhat.com/site/solutions/5427 - for f in /sys/block/{h,s,ub,v}d*/queue/scheduler; do echo noop > $f; done -+shopt -u nullglob - - # Update the system clock. - hwclock -u -s --- -1.8.3.1 - diff --git a/SOURCES/0031-p2v-tests-Fix-fake-scp-command-so-it-can-handle-mult.patch b/SOURCES/0031-p2v-tests-Fix-fake-scp-command-so-it-can-handle-mult.patch new file mode 100644 index 0000000..2a37eb6 --- /dev/null +++ b/SOURCES/0031-p2v-tests-Fix-fake-scp-command-so-it-can-handle-mult.patch @@ -0,0 +1,46 @@ +From 2fd825ed1984d761697f0b8814c425e69ff31719 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Thu, 30 Mar 2017 19:34:29 +0100 +Subject: [PATCH] p2v: tests: Fix fake scp command so it can handle multiple + local files. + +Fixes commit d178deeeb814471b9d70431626b6cd515a21d0c1. + +(cherry picked from commit b417c877f4ea848af8f8538957ab677c65637027) +--- + p2v/test-virt-p2v-scp.sh | 16 ++++++++++------ + 1 file changed, 10 insertions(+), 6 deletions(-) + +diff --git a/p2v/test-virt-p2v-scp.sh b/p2v/test-virt-p2v-scp.sh +index c8a405d..29900b6 100755 +--- a/p2v/test-virt-p2v-scp.sh ++++ b/p2v/test-virt-p2v-scp.sh +@@ -44,15 +44,19 @@ while true ; do + esac + done + +-# Hopefully there are two arguments left, the source (local) file +-# and a remote file of the form user@server:remote. +-if [ $# -ne 2 ]; then ++# Hopefully there are >= two arguments left, the source (local) ++# file(s) and a remote file of the form user@server:remote. ++if [ $# -lt 2 ]; then + echo "$0: incorrect number of arguments found:" "$@" + exit 1 + fi + +-local="$1" +-remote="$(echo $2 | awk -F: '{print $2}')" ++# https://stackoverflow.com/questions/1853946/getting-the-last-argument-passed-to-a-shell-script/1854031#1854031 ++remote="${@: -1}" ++# https://stackoverflow.com/questions/20398499/remove-last-argument-from-argument-list-of-shell-script-bash/26163980#26163980 ++set -- "${@:1:$(($#-1))}" ++ ++remote="$(echo $remote | awk -F: '{print $2}')" + + # Use the copy command. +-exec cp "$local" "$remote" ++exec cp "$@" "$remote" +-- +2.9.4 + diff --git a/SOURCES/0032-appliance-use-bash-features-for-string-matching-in-f.patch b/SOURCES/0032-appliance-use-bash-features-for-string-matching-in-f.patch deleted file mode 100644 index 46a5c0f..0000000 --- a/SOURCES/0032-appliance-use-bash-features-for-string-matching-in-f.patch +++ /dev/null @@ -1,54 +0,0 @@ -From a9ce8e635ebac7e3924757c93a84619943862167 Mon Sep 17 00:00:00 2001 -From: Pino Toscano -Date: Tue, 22 Mar 2016 15:48:53 +0100 -Subject: [PATCH] appliance: use bash features for string matching in files - -Read the content of /proc/cmdline using bash features, and use its -[[ ... ]] expression to find texts in a variable. - -This shaves off 5 grep invocations. - -(cherry picked from commit bb5d30ab2af5720775c63179afdec3ad9efd510d) ---- - appliance/init | 12 +++++++----- - 1 file changed, 7 insertions(+), 5 deletions(-) - -diff --git a/appliance/init b/appliance/init -index 3b76486..fd56033 100755 ---- a/appliance/init -+++ b/appliance/init -@@ -77,7 +77,9 @@ $UDEVD --daemon #--debug - udevadm trigger - udevadm settle --timeout=600 - --if grep -sq selinux=1 /proc/cmdline; then -+cmdline=$( +Date: Mon, 3 Apr 2017 19:44:45 +0300 +Subject: [PATCH] v2v: windows convert: fix virtio block driver installation + for w10/w2k16 + +This patch fixes the problem of the first boot after installation virtio block +drivers on Windows 10 / Server 2016. The problem is related to the change in +the behavior of Windows-Kernel-Pnp. To fix we need to add a field "Version" to +HKLM/SYSTEM/DriverDatabase/DriverPackages/drv_inf_label then Windows-Kernel-Pnp +will be able to correctly install the virtio block driver. + +Signed-off-by: Pavel Butsykin +(cherry picked from commit cc162b49e6c87bf3535168853dadf10f7610865f) +--- + v2v/windows_virtio.ml | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/v2v/windows_virtio.ml b/v2v/windows_virtio.ml +index 2f5349d..965d6ac 100644 +--- a/v2v/windows_virtio.ml ++++ b/v2v/windows_virtio.ml +@@ -220,6 +220,13 @@ and ddb_regedits inspect drv_name drv_pciid = + [ "DriverDatabase"; "DeviceIds"; "PCI"; drv_pciid ], + [ drv_inf, REG_BINARY "\x01\xff\x00\x00" ]; + ++ [ "DriverDatabase"; "DriverPackages"; drv_inf_label ], ++ [ "Version", REG_BINARY ("\x00\xff\x09\x00\x00\x00\x00\x00" ^ ++ "\x7b\xe9\x36\x4d\x25\xe3\xce\x11" ^ ++ "\xbf\xc1\x08\x00\x2b\xe1\x03\x18" ^ ++ (String.make 24 '\x00')) ]; ++ (* Version is necessary for Windows-Kernel-Pnp in w10/w2k16 *) ++ + [ "DriverDatabase"; "DriverPackages"; drv_inf_label; + "Configurations"; drv_config ], + [ "ConfigFlags", REG_DWORD 0_l; +-- +2.9.4 + diff --git a/SOURCES/0033-launch-Factor-out-earlyprintk-from-the-command-line.patch b/SOURCES/0033-launch-Factor-out-earlyprintk-from-the-command-line.patch deleted file mode 100644 index 5795ed8..0000000 --- a/SOURCES/0033-launch-Factor-out-earlyprintk-from-the-command-line.patch +++ /dev/null @@ -1,48 +0,0 @@ -From f375978572e5be4edb0e84fcbb7ae5dd06e93163 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Tue, 22 Mar 2016 09:43:50 +0000 -Subject: [PATCH] launch: Factor out earlyprintk from the command line. - -Just code motion. - -In theory we could also add earlyprintk=ttyS0,115200 on x86, but I -cannot get it to work. - -(cherry picked from commit b3e843e5b471b1e6e72901a98b3aa39820edaa6a) ---- - src/launch.c | 11 +++++++++-- - 1 file changed, 9 insertions(+), 2 deletions(-) - -diff --git a/src/launch.c b/src/launch.c -index 229069f..40b4810 100644 ---- a/src/launch.c -+++ b/src/launch.c -@@ -311,6 +311,12 @@ guestfs_impl_config (guestfs_h *g, - #define SERIAL_CONSOLE "console=ttyS0" - #endif - -+#if defined(__aarch64__) -+#define EARLYPRINTK " earlyprintk=pl011,0x9000000" -+#else -+#define EARLYPRINTK "" -+#endif -+ - char * - guestfs_int_appliance_command_line (guestfs_h *g, const char *appliance_dev, - int flags) -@@ -339,9 +345,10 @@ guestfs_int_appliance_command_line (guestfs_h *g, const char *appliance_dev, - #ifdef __i386__ - " noapic" /* workaround for RHBZ#857026 */ - #endif -- " " SERIAL_CONSOLE /* serial console */ -+ " " SERIAL_CONSOLE /* serial console */ -+ EARLYPRINTK /* get messages from early boot */ - #ifdef __aarch64__ -- " earlyprintk=pl011,0x9000000 ignore_loglevel" -+ " ignore_loglevel" - /* This option turns off the EFI RTC device. QEMU VMs don't - * currently provide EFI, and if the device is compiled in it - * will try to call the EFI function GetTime unconditionally --- -1.8.3.1 - diff --git a/SOURCES/0033-v2v-o-qemu-Fix-creation-of-ICH6-sound-device.patch b/SOURCES/0033-v2v-o-qemu-Fix-creation-of-ICH6-sound-device.patch new file mode 100644 index 0000000..dd86178 --- /dev/null +++ b/SOURCES/0033-v2v-o-qemu-Fix-creation-of-ICH6-sound-device.patch @@ -0,0 +1,28 @@ +From 9b24787dab3d5dea740a1667f69bc75b763cf699 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Tue, 11 Apr 2017 12:16:51 +0100 +Subject: [PATCH] v2v: -o qemu: Fix creation of ICH6 sound device. + +Fixes commit f6ece2c01a9a1a43d6715103e7dbdda0f09ee862. + +(cherry picked from commit e562f52c95fe8eefdab778918d152335f56012c6) +--- + v2v/output_qemu.ml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/v2v/output_qemu.ml b/v2v/output_qemu.ml +index 84efd45..abff29c 100644 +--- a/v2v/output_qemu.ml ++++ b/v2v/output_qemu.ml +@@ -183,7 +183,7 @@ object + match model with + | AC97 -> arg "-device" "AC97" + | ES1370 -> arg "-device" "ES1370" +- | ICH6 -> arg "-device" "intel-hda -device hda-duplex" ++ | ICH6 -> arg "-device" "intel-hda"; arg "-device" "hda-duplex" + | ICH9 -> arg "-device" "ich9-intel-hda" + | PCSpeaker -> arg "-soundhw" "pcspk" (* not qdev-ified *) + | SB16 -> arg "-device" "sb16" +-- +2.9.4 + diff --git a/SOURCES/0034-launch-direct-Don-t-run-qemu-version.patch b/SOURCES/0034-launch-direct-Don-t-run-qemu-version.patch deleted file mode 100644 index c59ab6a..0000000 --- a/SOURCES/0034-launch-direct-Don-t-run-qemu-version.patch +++ /dev/null @@ -1,141 +0,0 @@ -From c29743cdbdd8f5b526704705de7cc2ae3d0790c7 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Tue, 22 Mar 2016 14:04:26 +0000 -Subject: [PATCH] launch: direct: Don't run qemu -version. - -Dr. David Gilbert pointed out to me that the first line of the -qemu -help output includes the qemu version, so we don't need -to run qemu -version at all. - -This saves about 0.04s on the launch time when using the direct -backend. - -(cherry picked from commit b7b34119766349522528fdfe56237bede0794b6a) ---- - src/launch-direct.c | 54 +++++++++++++++++++---------------------------------- - 1 file changed, 19 insertions(+), 35 deletions(-) - -diff --git a/src/launch-direct.c b/src/launch-direct.c -index cbaf4f3..646f9c6 100644 ---- a/src/launch-direct.c -+++ b/src/launch-direct.c -@@ -61,7 +61,6 @@ struct backend_direct_data { - pid_t recoverypid; /* Recovery process PID. */ - - char *qemu_help; /* Output of qemu -help. */ -- char *qemu_version; /* Output of qemu -version. */ - char *qemu_devices; /* Output of qemu -device ? */ - - /* qemu version (0, 0 if unable to parse). */ -@@ -935,22 +934,18 @@ print_qemu_command_line (guestfs_h *g, char **argv) - static void parse_qemu_version (guestfs_h *g, struct backend_direct_data *data); - static void read_all (guestfs_h *g, void *retv, const char *buf, size_t len); - --/* Test qemu binary (or wrapper) runs, and do 'qemu -help' and -- * 'qemu -version' so we know what options this qemu supports and -- * the version. -+/* Test qemu binary (or wrapper) runs, and do 'qemu -help' so we know -+ * the version of qemu what options this qemu supports. - */ - static int - test_qemu (guestfs_h *g, struct backend_direct_data *data) - { - CLEANUP_CMD_CLOSE struct command *cmd1 = guestfs_int_new_command (g); - CLEANUP_CMD_CLOSE struct command *cmd2 = guestfs_int_new_command (g); -- CLEANUP_CMD_CLOSE struct command *cmd3 = guestfs_int_new_command (g); - int r; - - free (data->qemu_help); - data->qemu_help = NULL; -- free (data->qemu_version); -- data->qemu_version = NULL; - free (data->qemu_devices); - data->qemu_devices = NULL; - -@@ -964,34 +959,24 @@ test_qemu (guestfs_h *g, struct backend_direct_data *data) - if (r == -1 || !WIFEXITED (r) || WEXITSTATUS (r) != 0) - goto error; - -+ parse_qemu_version (g, data); -+ - guestfs_int_cmd_add_arg (cmd2, g->hv); - guestfs_int_cmd_add_arg (cmd2, "-display"); - guestfs_int_cmd_add_arg (cmd2, "none"); -- guestfs_int_cmd_add_arg (cmd2, "-version"); -- guestfs_int_cmd_set_stdout_callback (cmd2, read_all, &data->qemu_version, -- CMD_STDOUT_FLAG_WHOLE_BUFFER); -- r = guestfs_int_cmd_run (cmd2); -- if (r == -1 || !WIFEXITED (r) || WEXITSTATUS (r) != 0) -- goto error; -- -- parse_qemu_version (g, data); -- -- guestfs_int_cmd_add_arg (cmd3, g->hv); -- guestfs_int_cmd_add_arg (cmd3, "-display"); -- guestfs_int_cmd_add_arg (cmd3, "none"); -- guestfs_int_cmd_add_arg (cmd3, "-machine"); -- guestfs_int_cmd_add_arg (cmd3, -+ guestfs_int_cmd_add_arg (cmd2, "-machine"); -+ guestfs_int_cmd_add_arg (cmd2, - #ifdef MACHINE_TYPE - MACHINE_TYPE "," - #endif - "accel=kvm:tcg"); -- guestfs_int_cmd_add_arg (cmd3, "-device"); -- guestfs_int_cmd_add_arg (cmd3, "?"); -- guestfs_int_cmd_clear_capture_errors (cmd3); -- guestfs_int_cmd_set_stderr_to_stdout (cmd3); -- guestfs_int_cmd_set_stdout_callback (cmd3, read_all, &data->qemu_devices, -+ guestfs_int_cmd_add_arg (cmd2, "-device"); -+ guestfs_int_cmd_add_arg (cmd2, "?"); -+ guestfs_int_cmd_clear_capture_errors (cmd2); -+ guestfs_int_cmd_set_stderr_to_stdout (cmd2); -+ guestfs_int_cmd_set_stdout_callback (cmd2, read_all, &data->qemu_devices, - CMD_STDOUT_FLAG_WHOLE_BUFFER); -- r = guestfs_int_cmd_run (cmd3); -+ r = guestfs_int_cmd_run (cmd2); - if (r == -1 || !WIFEXITED (r) || WEXITSTATUS (r) != 0) - goto error; - -@@ -1005,8 +990,9 @@ test_qemu (guestfs_h *g, struct backend_direct_data *data) - return -1; - } - --/* Parse data->qemu_version (if not NULL) into the major and minor -- * version of qemu, but don't fail if parsing is not possible. -+/* Parse the first line of data->qemu_help (if not NULL) into the -+ * major and minor version of qemu, but don't fail if parsing is not -+ * possible. - */ - static void - parse_qemu_version (guestfs_h *g, struct backend_direct_data *data) -@@ -1017,13 +1003,13 @@ parse_qemu_version (guestfs_h *g, struct backend_direct_data *data) - data->qemu_version_major = 0; - data->qemu_version_minor = 0; - -- if (!data->qemu_version) -+ if (!data->qemu_help) - return; - -- if (!match2 (g, data->qemu_version, re_major_minor, &major_s, &minor_s)) { -+ if (!match2 (g, data->qemu_help, re_major_minor, &major_s, &minor_s)) { - parse_failed: -- debug (g, "%s: failed to parse qemu version string '%s'", -- __func__, data->qemu_version); -+ debug (g, "%s: failed to parse qemu version string from the first line of the output of '%s -help'. When reporting this bug please include the -help output.", -+ __func__, g->hv); - return; - } - -@@ -1505,8 +1491,6 @@ shutdown_direct (guestfs_h *g, void *datav, int check_for_errors) - - free (data->qemu_help); - data->qemu_help = NULL; -- free (data->qemu_version); -- data->qemu_version = NULL; - free (data->qemu_devices); - data->qemu_devices = NULL; - --- -1.8.3.1 - diff --git a/SOURCES/0034-ocaml-Add-Bytes.sub_string-function-to-Bytes-compat-.patch b/SOURCES/0034-ocaml-Add-Bytes.sub_string-function-to-Bytes-compat-.patch new file mode 100644 index 0000000..7d170f7 --- /dev/null +++ b/SOURCES/0034-ocaml-Add-Bytes.sub_string-function-to-Bytes-compat-.patch @@ -0,0 +1,28 @@ +From 12d1057fba45b534d0cfbbcc900e5032e314b150 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Tue, 11 Apr 2017 08:29:47 +0100 +Subject: [PATCH] ocaml: Add Bytes.sub_string function to Bytes compat module. + +This is only used when OCaml < 4.02 (eg. RHEL 7). For more recent +versions the real Bytes.sub_string function is used instead. + +(cherry picked from commit bb846887de7a252204152c3e6df80d39a5ea33af) +--- + m4/guestfs_ocaml.m4 | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/m4/guestfs_ocaml.m4 b/m4/guestfs_ocaml.m4 +index 0479e70..d8bd89f 100644 +--- a/m4/guestfs_ocaml.m4 ++++ b/m4/guestfs_ocaml.m4 +@@ -120,6 +120,7 @@ AS_IF([test "x$have_Bytes_module" = "xno"],[ + include String + let of_string = String.copy + let to_string = String.copy ++let sub_string = String.sub + EOF + ln -s ../generator/bytes.ml mllib/bytes.ml + OCAML_GENERATOR_BYTES_COMPAT_CMO='$(top_builddir)/generator/bytes.cmo' +-- +2.9.4 + diff --git a/SOURCES/0035-launch-Remove-guestfs_int_print_timestamped_message-.patch b/SOURCES/0035-launch-Remove-guestfs_int_print_timestamped_message-.patch deleted file mode 100644 index 41b671f..0000000 --- a/SOURCES/0035-launch-Remove-guestfs_int_print_timestamped_message-.patch +++ /dev/null @@ -1,250 +0,0 @@ -From 076ecc7fd7987d9fd023a3b0e11bf15024b96957 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Sat, 19 Mar 2016 21:27:32 +0000 -Subject: [PATCH] launch: Remove guestfs_int_print_timestamped_message - function. - -This function was kind of like debug(), except that it didn't check -the g->verbose flag and it only worked in the library (it would crash -if used after fork). - -It also wasn't very useful. The sort of boot analysis done by -[forthcoming program] tests/qemu/boot-analysis.c means that -timestamping (some) messages is even less interesting than before. - -Remove it and replace calls with debug() instead. - -(cherry picked from commit e94e61f76f5b0dcdcb0d1b7c74e53c7e3d7da5b2) ---- - src/appliance.c | 9 +++------ - src/guestfs-internal.h | 1 - - src/launch-direct.c | 9 +++------ - src/launch-libvirt.c | 21 +++++++-------------- - src/launch-uml.c | 3 +-- - src/launch-unix.c | 6 ++---- - src/launch.c | 25 ------------------------- - 7 files changed, 16 insertions(+), 58 deletions(-) - -diff --git a/src/appliance.c b/src/appliance.c -index cf13091..1687a93 100644 ---- a/src/appliance.c -+++ b/src/appliance.c -@@ -220,18 +220,15 @@ build_supermin_appliance (guestfs_h *g, - appliancedir = safe_asprintf (g, "%s/appliance.d", cachedir); - lockfile = safe_asprintf (g, "%s/lock", cachedir); - -- if (g->verbose) -- guestfs_int_print_timestamped_message (g, "begin building supermin appliance"); -+ debug (g, "begin building supermin appliance"); - - /* Build the appliance if it needs to be built. */ -- if (g->verbose) -- guestfs_int_print_timestamped_message (g, "run supermin"); -+ debug (g, "run supermin"); - - if (run_supermin_build (g, lockfile, appliancedir, supermin_path) == -1) - return -1; - -- if (g->verbose) -- guestfs_int_print_timestamped_message (g, "finished building supermin appliance"); -+ debug (g, "finished building supermin appliance"); - - /* Return the appliance filenames. */ - *kernel = safe_asprintf (g, "%s/kernel", appliancedir); -diff --git a/src/guestfs-internal.h b/src/guestfs-internal.h -index 5dd0a32..44dae32 100644 ---- a/src/guestfs-internal.h -+++ b/src/guestfs-internal.h -@@ -760,7 +760,6 @@ extern int guestfs_int_get_uefi (guestfs_h *g, char **code, char **vars); - - /* launch.c */ - extern int64_t guestfs_int_timeval_diff (const struct timeval *x, const struct timeval *y); --extern void guestfs_int_print_timestamped_message (guestfs_h *g, const char *fs, ...) __attribute__((format (printf,2,3))); - extern void guestfs_int_launch_send_progress (guestfs_h *g, int perdozen); - extern char *guestfs_int_appliance_command_line (guestfs_h *g, const char *appliance_dev, int flags); - #define APPLIANCE_COMMAND_LINE_IS_TCG 1 -diff --git a/src/launch-direct.c b/src/launch-direct.c -index 646f9c6..8d99979 100644 ---- a/src/launch-direct.c -+++ b/src/launch-direct.c -@@ -290,8 +290,7 @@ launch_direct (guestfs_h *g, void *datav, const char *arg) - - guestfs_int_launch_send_progress (g, 3); - -- if (g->verbose) -- guestfs_int_print_timestamped_message (g, "begin testing qemu features"); -+ debug (g, "begin testing qemu features"); - - /* Get qemu help text and version. */ - if (qemu_supports (g, data, NULL) == -1) -@@ -331,8 +330,7 @@ launch_direct (guestfs_h *g, void *datav, const char *arg) - } - } - -- if (g->verbose) -- guestfs_int_print_timestamped_message (g, "finished testing qemu features"); -+ debug (g, "finished testing qemu features"); - - /* Construct the qemu command line. We have to do this before - * forking, because after fork we are not allowed to use -@@ -818,8 +816,7 @@ launch_direct (guestfs_h *g, void *datav, const char *arg) - goto cleanup1; - } - -- if (g->verbose) -- guestfs_int_print_timestamped_message (g, "appliance is up"); -+ debug (g, "appliance is up"); - - /* This is possible in some really strange situations, such as - * guestfsd starts up OK but then qemu immediately exits. Check for -diff --git a/src/launch-libvirt.c b/src/launch-libvirt.c -index 4b87301..ceaa696 100644 ---- a/src/launch-libvirt.c -+++ b/src/launch-libvirt.c -@@ -347,8 +347,7 @@ launch_libvirt (guestfs_h *g, void *datav, const char *libvirt_uri) - } - debug (g, "guest random name = %s", data->name); - -- if (g->verbose) -- guestfs_int_print_timestamped_message (g, "connect to libvirt"); -+ debug (g, "connect to libvirt"); - - /* Decode the URI string. */ - if (!libvirt_uri) { /* "libvirt" */ -@@ -387,8 +386,7 @@ launch_libvirt (guestfs_h *g, void *datav, const char *libvirt_uri) - data->qemu_version = 0; - } - -- if (g->verbose) -- guestfs_int_print_timestamped_message (g, "get libvirt capabilities"); -+ debug (g, "get libvirt capabilities"); - - capabilities_xml = virConnectGetCapabilities (conn); - if (!capabilities_xml) { -@@ -400,8 +398,7 @@ launch_libvirt (guestfs_h *g, void *datav, const char *libvirt_uri) - * struct, and can also fail if we detect that the hypervisor cannot - * run qemu guests (RHBZ#886915). - */ -- if (g->verbose) -- guestfs_int_print_timestamped_message (g, "parsing capabilities XML"); -+ debug (g, "parsing capabilities XML"); - - if (parse_capabilities (g, capabilities_xml, data) == -1) - goto cleanup; -@@ -425,8 +422,7 @@ launch_libvirt (guestfs_h *g, void *datav, const char *libvirt_uri) - /* Locate and/or build the appliance. */ - TRACE0 (launch_build_libvirt_appliance_start); - -- if (g->verbose) -- guestfs_int_print_timestamped_message (g, "build appliance"); -+ debug (g, "build appliance"); - - if (guestfs_int_build_appliance (g, ¶ms.kernel, ¶ms.dtb, - ¶ms.initrd, &appliance) == -1) -@@ -555,8 +551,7 @@ launch_libvirt (guestfs_h *g, void *datav, const char *libvirt_uri) - } - - /* Construct the libvirt XML. */ -- if (g->verbose) -- guestfs_int_print_timestamped_message (g, "create libvirt XML"); -+ debug (g, "create libvirt XML"); - - params.appliance_index = g->nr_drives; - strcpy (params.appliance_dev, "/dev/sd"); -@@ -574,8 +569,7 @@ launch_libvirt (guestfs_h *g, void *datav, const char *libvirt_uri) - } - - /* Launch the libvirt guest. */ -- if (g->verbose) -- guestfs_int_print_timestamped_message (g, "launch libvirt guest"); -+ debug (g, "launch libvirt guest"); - - dom = virDomainCreateXML (conn, (char *) xml, VIR_DOMAIN_START_AUTODESTROY); - if (!dom) { -@@ -643,8 +637,7 @@ launch_libvirt (guestfs_h *g, void *datav, const char *libvirt_uri) - goto cleanup; - } - -- if (g->verbose) -- guestfs_int_print_timestamped_message (g, "appliance is up"); -+ debug (g, "appliance is up"); - - /* This is possible in some really strange situations, such as - * guestfsd starts up OK but then qemu immediately exits. Check for -diff --git a/src/launch-uml.c b/src/launch-uml.c -index 38be7a8..f6ed516 100644 ---- a/src/launch-uml.c -+++ b/src/launch-uml.c -@@ -456,8 +456,7 @@ launch_uml (guestfs_h *g, void *datav, const char *arg) - goto cleanup1; - } - -- if (g->verbose) -- guestfs_int_print_timestamped_message (g, "appliance is up"); -+ debug (g, "appliance is up"); - - /* This is possible in some really strange situations, such as - * guestfsd starts up OK but then vmlinux immediately exits. Check -diff --git a/src/launch-unix.c b/src/launch-unix.c -index 428fdc6..f44c746 100644 ---- a/src/launch-unix.c -+++ b/src/launch-unix.c -@@ -59,8 +59,7 @@ launch_unix (guestfs_h *g, void *datav, const char *sockpath) - return -1; - } - -- if (g->verbose) -- guestfs_int_print_timestamped_message (g, "connecting to %s", sockpath); -+ debug (g, "connecting to %s", sockpath); - - daemon_sock = socket (AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0); - if (daemon_sock == -1) { -@@ -96,8 +95,7 @@ launch_unix (guestfs_h *g, void *datav, const char *sockpath) - goto cleanup; - } - -- if (g->verbose) -- guestfs_int_print_timestamped_message (g, "connected"); -+ debug (g, "connected"); - - if (g->state != READY) { - error (g, _("contacted guestfsd, but state != READY")); -diff --git a/src/launch.c b/src/launch.c -index 40b4810..0eb7d18 100644 ---- a/src/launch.c -+++ b/src/launch.c -@@ -127,31 +127,6 @@ guestfs_int_launch_send_progress (guestfs_h *g, int perdozen) - } - } - --/* Note that since this calls 'debug' it should only be called -- * from the parent process. -- */ --void --guestfs_int_print_timestamped_message (guestfs_h *g, const char *fs, ...) --{ -- va_list args; -- char *msg; -- int err; -- struct timeval tv; -- -- va_start (args, fs); -- err = vasprintf (&msg, fs, args); -- va_end (args); -- -- if (err < 0) return; -- -- gettimeofday (&tv, NULL); -- -- debug (g, "[%05" PRIi64 "ms] %s", -- guestfs_int_timeval_diff (&g->launch_t, &tv), msg); -- -- free (msg); --} -- - /* Compute Y - X and return the result in milliseconds. - * Approximately the same as this code: - * http://www.mpp.mpg.de/~huber/util/timevaldiff.c --- -1.8.3.1 - diff --git a/SOURCES/0035-mllib-Add-Char.hexdigit-function.patch b/SOURCES/0035-mllib-Add-Char.hexdigit-function.patch new file mode 100644 index 0000000..cde0448 --- /dev/null +++ b/SOURCES/0035-mllib-Add-Char.hexdigit-function.patch @@ -0,0 +1,61 @@ +From 0279339ee9a7b61ebcb3f64846d94f8171872737 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Tue, 11 Apr 2017 08:32:04 +0100 +Subject: [PATCH] mllib: Add Char.hexdigit function. + +Same as the function defined in fish/fish.c. + +(cherry picked from commit ef261d69ed199cc07474a36c890f63df461b35a7) +--- + mllib/common_utils.ml | 19 +++++++++++++++++++ + mllib/common_utils.mli | 4 ++++ + 2 files changed, 23 insertions(+) + +diff --git a/mllib/common_utils.ml b/mllib/common_utils.ml +index e1d6329..4593614 100644 +--- a/mllib/common_utils.ml ++++ b/mllib/common_utils.ml +@@ -70,6 +70,25 @@ module Char = struct + | 'a'..'z' -> true + | 'A'..'Z' -> true + | _ -> false ++ ++ let hexdigit = function ++ | '0' -> 0 ++ | '1' -> 1 ++ | '2' -> 2 ++ | '3' -> 3 ++ | '4' -> 4 ++ | '5' -> 5 ++ | '6' -> 6 ++ | '7' -> 7 ++ | '8' -> 8 ++ | '9' -> 9 ++ | 'a' | 'A' -> 10 ++ | 'b' | 'B' -> 11 ++ | 'c' | 'C' -> 12 ++ | 'd' | 'D' -> 13 ++ | 'e' | 'E' -> 14 ++ | 'f' | 'F' -> 15 ++ | _ -> -1 + end + + module String = struct +diff --git a/mllib/common_utils.mli b/mllib/common_utils.mli +index 1cd38ba..ec41a8f 100644 +--- a/mllib/common_utils.mli ++++ b/mllib/common_utils.mli +@@ -43,6 +43,10 @@ module Char : sig + (** Return true if the character is a US ASCII 7 bit alphabetic. *) + val isalnum : char -> bool + (** Return true if the character is a US ASCII 7 bit alphanumeric. *) ++ ++ val hexdigit : char -> int ++ (** Return the value of a hex digit. If the char is not in ++ the set [[0-9a-fA-F]] then this returns [-1]. *) + end + (** Override the Char module from stdlib. *) + +-- +2.9.4 + diff --git a/SOURCES/0036-launch-Add-a-virtio-rng-device-to-the-guest.patch b/SOURCES/0036-launch-Add-a-virtio-rng-device-to-the-guest.patch deleted file mode 100644 index 25d9c58..0000000 --- a/SOURCES/0036-launch-Add-a-virtio-rng-device-to-the-guest.patch +++ /dev/null @@ -1,61 +0,0 @@ -From a8c286e9a7972833e1c8cf7da8d91406fa8d0f79 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Tue, 22 Mar 2016 14:51:19 +0000 -Subject: [PATCH] launch: Add a virtio-rng device to the guest. - -(cherry picked from commit 9423c16607259b30985c46d04db9958ec079aa42) ---- - src/launch-direct.c | 11 +++++++++++ - src/launch-libvirt.c | 14 ++++++++++++++ - 2 files changed, 25 insertions(+) - -diff --git a/src/launch-direct.c b/src/launch-direct.c -index 8d99979..25c97a7 100644 ---- a/src/launch-direct.c -+++ b/src/launch-direct.c -@@ -454,6 +454,17 @@ launch_direct (guestfs_h *g, void *datav, const char *arg) - ADD_CMDLINE ("-initrd"); - ADD_CMDLINE (initrd); - -+ /* Add a random number generator (backend for virtio-rng). This -+ * isn't strictly necessary but means we won't need to hang around -+ * when needing entropy. -+ */ -+ if (qemu_supports_device (g, data, "virtio-rng-pci")) { -+ ADD_CMDLINE ("-object"); -+ ADD_CMDLINE ("rng-random,filename=/dev/urandom,id=rng0"); -+ ADD_CMDLINE ("-device"); -+ ADD_CMDLINE ("virtio-rng-pci,rng=rng0"); -+ } -+ - /* Add drives */ - virtio_scsi = qemu_supports_virtio_scsi (g, data); - -diff --git a/src/launch-libvirt.c b/src/launch-libvirt.c -index ceaa696..3df1833 100644 ---- a/src/launch-libvirt.c -+++ b/src/launch-libvirt.c -@@ -1304,6 +1304,20 @@ construct_libvirt_xml_devices (guestfs_h *g, - } - #endif - -+ /* Add a random number generator (backend for virtio-rng). */ -+ start_element ("rng") { -+ attribute ("model", "virtio"); -+ start_element ("backend") { -+ attribute ("model", "random"); -+ /* It'd be nice to do this, but libvirt says: -+ * file '/dev/urandom' is not a supported random source -+ * Let libvirt pick /dev/random automatically instead. -+ * See also: https://bugzilla.redhat.com/show_bug.cgi?id=1074464 -+ */ -+ //string ("/dev/urandom"); -+ } end_element (); -+ } end_element (); -+ - /* virtio-scsi controller. */ - start_element ("controller") { - attribute ("type", "scsi"); --- -1.8.3.1 - diff --git a/SOURCES/0036-v2v-Implement-i-vmx-to-read-VMware-vmx-files-directl.patch b/SOURCES/0036-v2v-Implement-i-vmx-to-read-VMware-vmx-files-directl.patch new file mode 100644 index 0000000..d67e5ad --- /dev/null +++ b/SOURCES/0036-v2v-Implement-i-vmx-to-read-VMware-vmx-files-directl.patch @@ -0,0 +1,1954 @@ +From 79c0796259820d1ee49bf442392bc3cc5d82322d Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Mon, 10 Apr 2017 15:24:26 +0100 +Subject: [PATCH] v2v: Implement -i vmx to read VMware vmx files directly + (RHBZ#1441197). + +This is a mostly complete implementation of a VMX parser and input +class for virt-v2v. It parses the name, memory size, CPU topology, +firmware, video, sound, hard disks, removable disks and network +interfaces from the VMX file. It only omits support for floppies and +SCSI CD-ROMs. + +The input class is split into two major parts: a generic VMX file +parser (Parse_vmx), and the Input_vmx module which translates the VMX +tree into the source device model. + +This also contains tests. There are simple unit tests of the +Parse_vmx module, and also some more complete parsing tests taken from +real guests. + +(cherry picked from commit ca40078cdda9167d4658ddfe24c828c7ee76be37) +--- + v2v/Makefile.am | 15 ++ + v2v/cmdline.ml | 12 +- + v2v/input_vmx.ml | 349 ++++++++++++++++++++++++++++++++++++++ + v2v/input_vmx.mli | 22 +++ + v2v/name_from_disk.ml | 2 +- + v2v/parse_vmx.ml | 381 ++++++++++++++++++++++++++++++++++++++++++ + v2v/parse_vmx.mli | 89 ++++++++++ + v2v/test-v2v-i-vmx-1.expected | 42 +++++ + v2v/test-v2v-i-vmx-1.vmx | 172 +++++++++++++++++++ + v2v/test-v2v-i-vmx-2.expected | 22 +++ + v2v/test-v2v-i-vmx-2.vmx | 84 ++++++++++ + v2v/test-v2v-i-vmx-3.expected | 22 +++ + v2v/test-v2v-i-vmx-3.vmx | 91 ++++++++++ + v2v/test-v2v-i-vmx-4.expected | 22 +++ + v2v/test-v2v-i-vmx-4.vmx | 88 ++++++++++ + v2v/test-v2v-i-vmx.sh | 48 ++++++ + v2v/v2v_unit_tests.ml | 143 ++++++++++++++++ + v2v/virt-v2v.pod | 72 +++++++- + 18 files changed, 1667 insertions(+), 9 deletions(-) + create mode 100644 v2v/input_vmx.ml + create mode 100644 v2v/input_vmx.mli + create mode 100644 v2v/parse_vmx.ml + create mode 100644 v2v/parse_vmx.mli + create mode 100644 v2v/test-v2v-i-vmx-1.expected + create mode 100644 v2v/test-v2v-i-vmx-1.vmx + create mode 100644 v2v/test-v2v-i-vmx-2.expected + create mode 100644 v2v/test-v2v-i-vmx-2.vmx + create mode 100644 v2v/test-v2v-i-vmx-3.expected + create mode 100644 v2v/test-v2v-i-vmx-3.vmx + create mode 100644 v2v/test-v2v-i-vmx-4.expected + create mode 100644 v2v/test-v2v-i-vmx-4.vmx + create mode 100755 v2v/test-v2v-i-vmx.sh + +diff --git a/v2v/Makefile.am b/v2v/Makefile.am +index 2974064..0df759e 100644 +--- a/v2v/Makefile.am ++++ b/v2v/Makefile.am +@@ -38,6 +38,7 @@ SOURCES_MLI = \ + input_libvirt_xen_ssh.mli \ + input_libvirtxml.mli \ + input_ova.mli \ ++ input_vmx.mli \ + inspect_source.mli \ + libvirt_utils.mli \ + linux.mli \ +@@ -55,6 +56,7 @@ SOURCES_MLI = \ + OVF.mli \ + parse_ovf_from_ova.mli \ + parse_libvirt_xml.mli \ ++ parse_vmx.mli \ + qemu_command.mli \ + target_bus_assignment.mli \ + types.mli \ +@@ -80,6 +82,7 @@ SOURCES_ML = \ + windows_virtio.ml \ + modules_list.ml \ + input_disk.ml \ ++ parse_vmx.ml \ + parse_libvirt_xml.ml \ + create_libvirt_xml.ml \ + qemu_command.ml \ +@@ -89,6 +92,7 @@ SOURCES_ML = \ + input_libvirt_xen_ssh.ml \ + input_libvirt.ml \ + input_ova.ml \ ++ input_vmx.ml \ + linux_bootloaders.ml \ + linux_kernels.ml \ + convert_linux.ml \ +@@ -268,6 +272,7 @@ TESTS = \ + test-v2v-i-ova-subfolders.sh \ + test-v2v-i-ova-tar.sh \ + test-v2v-i-ova-two-disks.sh \ ++ test-v2v-i-vmx.sh \ + test-v2v-bad-networks-and-bridges.sh + + if HAVE_LIBVIRT +@@ -411,6 +416,15 @@ EXTRA_DIST += \ + test-v2v-i-ova.ovf \ + test-v2v-i-ova.sh \ + test-v2v-i-ova.xml \ ++ test-v2v-i-vmx.sh \ ++ test-v2v-i-vmx-1.expected \ ++ test-v2v-i-vmx-2.expected \ ++ test-v2v-i-vmx-3.expected \ ++ test-v2v-i-vmx-4.expected \ ++ test-v2v-i-vmx-1.vmx \ ++ test-v2v-i-vmx-2.vmx \ ++ test-v2v-i-vmx-3.vmx \ ++ test-v2v-i-vmx-4.vmx \ + test-v2v-machine-readable.sh \ + test-v2v-networks-and-bridges-expected.xml \ + test-v2v-networks-and-bridges.sh \ +@@ -450,6 +464,7 @@ v2v_unit_tests_BOBJECTS = \ + windows.cmo \ + windows_virtio.cmo \ + linux.cmo \ ++ parse_vmx.cmo \ + v2v_unit_tests.cmo + v2v_unit_tests_XOBJECTS = $(v2v_unit_tests_BOBJECTS:.cmo=.cmx) + +diff --git a/v2v/cmdline.ml b/v2v/cmdline.ml +index a2f132b..0850f91 100644 +--- a/v2v/cmdline.ml ++++ b/v2v/cmdline.ml +@@ -86,6 +86,7 @@ let parse_cmdline () = + | "libvirt" -> input_mode := `Libvirt + | "libvirtxml" -> input_mode := `LibvirtXML + | "ova" -> input_mode := `OVA ++ | "vmx" -> input_mode := `VMX + | s -> + error (f_"unknown -i option: %s") s + in +@@ -331,7 +332,16 @@ read the man page virt-v2v(1). + | [filename] -> filename + | _ -> + error (f_"expecting an OVA file name on the command line") in +- Input_ova.input_ova filename in ++ Input_ova.input_ova filename ++ ++ | `VMX -> ++ (* -i vmx: Expecting an vmx filename. *) ++ let filename = ++ match args with ++ | [filename] -> filename ++ | _ -> ++ error (f_"expecting a VMX file name on the command line") in ++ Input_vmx.input_vmx filename in + + (* Prevent use of --in-place option in RHEL. *) + if in_place then +diff --git a/v2v/input_vmx.ml b/v2v/input_vmx.ml +new file mode 100644 +index 0000000..bb09f0b +--- /dev/null ++++ b/v2v/input_vmx.ml +@@ -0,0 +1,349 @@ ++(* virt-v2v ++ * 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. ++ *) ++ ++open Printf ++open Scanf ++ ++open Common_gettext.Gettext ++open Common_utils ++ ++open Types ++open Utils ++open Name_from_disk ++ ++external identity : 'a -> 'a = "%identity" ++ ++let rec find_disks vmx vmx_filename = ++ find_scsi_disks vmx vmx_filename @ find_ide_disks vmx vmx_filename ++ ++(* Find all SCSI hard disks. ++ * ++ * In the VMX file: ++ * scsi0.virtualDev = "pvscsi" # or may be "lsilogic" etc. ++ * scsi0:0.deviceType = "scsi-hardDisk" ++ * scsi0:0.fileName = "guest.vmdk" ++ *) ++and find_scsi_disks vmx vmx_filename = ++ let get_scsi_controller_target ns = ++ sscanf ns "scsi%d:%d" (fun c t -> c, t) ++ in ++ let is_scsi_controller_target ns = ++ try ignore (get_scsi_controller_target ns); true ++ with Scanf.Scan_failure _ | End_of_file | Failure _ -> false ++ in ++ let scsi_device_types = [ "scsi-harddisk" ] in ++ let scsi_controller = Source_SCSI in ++ ++ find_hdds vmx vmx_filename ++ get_scsi_controller_target is_scsi_controller_target ++ scsi_device_types scsi_controller ++ ++(* Find all IDE hard disks. ++ * ++ * In the VMX file: ++ * ide0:0.deviceType = "ata-hardDisk" ++ * ide0:0.fileName = "guest.vmdk" ++ *) ++and find_ide_disks vmx vmx_filename = ++ let get_ide_controller_target ns = ++ sscanf ns "ide%d:%d" (fun c t -> c, t) ++ in ++ let is_ide_controller_target ns = ++ try ignore (get_ide_controller_target ns); true ++ with Scanf.Scan_failure _ | End_of_file | Failure _ -> false ++ in ++ let ide_device_types = [ "ata-harddisk" ] in ++ let ide_controller = Source_IDE in ++ ++ find_hdds vmx vmx_filename ++ get_ide_controller_target is_ide_controller_target ++ ide_device_types ide_controller ++ ++and find_hdds vmx vmx_filename ++ get_controller_target is_controller_target ++ device_types controller = ++ (* Find namespaces matching '(ide|scsi)X:Y' with suitable deviceType. *) ++ let hdds = ++ Parse_vmx.select_namespaces ( ++ function ++ | [ns] -> ++ (* Check the namespace is '(ide|scsi)X:Y' *) ++ if not (is_controller_target ns) then false ++ else ( ++ (* Check the deviceType is one we are looking for. *) ++ match Parse_vmx.get_string vmx [ns; "deviceType"] with ++ | Some str -> ++ let str = String.lowercase_ascii str in ++ List.mem str device_types ++ | None -> false ++ ) ++ | _ -> false ++ ) vmx in ++ ++ (* Map the subset to a list of disks. *) ++ let hdds = ++ Parse_vmx.map ( ++ fun path v -> ++ match path, v with ++ | [ns; "filename"], Some filename -> ++ let c, t = get_controller_target ns in ++ let s = { s_disk_id = (-1); ++ s_qemu_uri = qemu_uri_of_filename vmx_filename filename; ++ s_format = Some "vmdk"; ++ s_controller = Some controller } in ++ Some (c, t, s) ++ | _ -> None ++ ) hdds in ++ let hdds = filter_map identity hdds in ++ ++ (* We don't have a way to return the controllers and targets, so ++ * just make sure the disks are sorted into order, since Parse_vmx ++ * won't return them in any particular order. ++ *) ++ let hdds = List.sort compare hdds in ++ let hdds = List.map (fun (_, _, source) -> source) hdds in ++ ++ (* Set the s_disk_id field to an incrementing number. *) ++ let hdds = mapi (fun i source -> { source with s_disk_id = i }) hdds in ++ ++ hdds ++ ++(* The filename can be an absolute path, but is more often a ++ * path relative to the location of the vmx file. ++ * ++ * Note that we always end up with an absolute path, which is ++ * also useful because it means we won't have any paths that ++ * could be misinterpreted by qemu. ++ *) ++and qemu_uri_of_filename vmx_filename filename = ++ if not (Filename.is_relative filename) then ++ filename ++ else ( ++ let dir = Filename.dirname (absolute_path vmx_filename) in ++ dir // filename ++ ) ++ ++(* Find all removable disks. ++ * ++ * In the VMX file: ++ * ide1:0.deviceType = "cdrom-image" ++ * ide1:0.fileName = "boot.iso" ++ * ++ * XXX This only supports IDE CD-ROMs, but we could support SCSI ++ * CD-ROMs and floppies in future. ++ *) ++and find_removables vmx = ++ let get_ide_controller_target ns = ++ sscanf ns "ide%d:%d" (fun c t -> c, t) ++ in ++ let is_ide_controller_target ns = ++ try ignore (get_ide_controller_target ns); true ++ with Scanf.Scan_failure _ | End_of_file | Failure _ -> false ++ in ++ let device_types = [ "atapi-cdrom"; ++ "cdrom-image"; "cdrom-raw" ] in ++ ++ (* Find namespaces matching 'ideX:Y' with suitable deviceType. *) ++ let devs = ++ Parse_vmx.select_namespaces ( ++ function ++ | [ns] -> ++ (* Check the namespace is 'ideX:Y' *) ++ if not (is_ide_controller_target ns) then false ++ else ( ++ (* Check the deviceType is one we are looking for. *) ++ match Parse_vmx.get_string vmx [ns; "deviceType"] with ++ | Some str -> ++ let str = String.lowercase_ascii str in ++ List.mem str device_types ++ | None -> false ++ ) ++ | _ -> false ++ ) vmx in ++ ++ (* Map the subset to a list of CD-ROMs. *) ++ let devs = ++ Parse_vmx.map ( ++ fun path v -> ++ match path, v with ++ | [ns], None -> ++ let c, t = get_ide_controller_target ns in ++ let s = { s_removable_type = CDROM; ++ s_removable_controller = Some Source_IDE; ++ s_removable_slot = Some (ide_slot c t) } in ++ Some s ++ | _ -> None ++ ) devs in ++ let devs = filter_map identity devs in ++ ++ (* Sort by slot. *) ++ let devs = ++ List.sort ++ (fun { s_removable_slot = s1 } { s_removable_slot = s2 } -> ++ compare s1 s2) ++ devs in ++ ++ devs ++ ++and ide_slot c t = ++ (* Assuming the old master/slave arrangement. *) ++ c * 2 + t ++ ++(* Find all ethernet cards. ++ * ++ * In the VMX file: ++ * ethernet0.virtualDev = "vmxnet3" ++ * ethernet0.networkName = "VM Network" ++ * ethernet0.generatedAddress = "00:01:02:03:04:05" ++ * ethernet0.connectionType = "bridged" # also: "custom", "nat" or not present ++ *) ++and find_nics vmx = ++ let get_ethernet_port ns = ++ sscanf ns "ethernet%d" (fun p -> p) ++ in ++ let is_ethernet_port ns = ++ try ignore (get_ethernet_port ns); true ++ with Scanf.Scan_failure _ | End_of_file | Failure _ -> false ++ in ++ ++ (* Find namespaces matching 'ethernetX'. *) ++ let nics = ++ Parse_vmx.select_namespaces ( ++ function ++ | [ns] -> is_ethernet_port ns ++ | _ -> false ++ ) vmx in ++ ++ (* Map the subset to a list of NICs. *) ++ let nics = ++ Parse_vmx.map ( ++ fun path v -> ++ match path, v with ++ | [ns], None -> ++ let port = get_ethernet_port ns in ++ let mac = Parse_vmx.get_string vmx [ns; "generatedAddress"] in ++ let model = Parse_vmx.get_string vmx [ns; "virtualDev"] in ++ let model = ++ match model with ++ | Some m when String.lowercase_ascii m = "e1000" -> ++ Some Source_e1000 ++ | Some model -> ++ Some (Source_other_nic (String.lowercase_ascii model)) ++ | None -> None in ++ let vnet = Parse_vmx.get_string vmx [ns; "networkName"] in ++ let vnet = ++ match vnet with ++ | Some vnet -> vnet ++ | None -> ns (* "ethernetX" *) in ++ let vnet_type = ++ match Parse_vmx.get_string vmx [ns; "connectionType"] with ++ | Some b when String.lowercase_ascii b = "bridged" -> ++ Bridge ++ | Some _ | None -> Network in ++ Some (port, ++ { s_mac = mac; s_nic_model = model; ++ s_vnet = vnet; s_vnet_orig = vnet; ++ s_vnet_type = vnet_type }) ++ | _ -> None ++ ) nics in ++ let nics = filter_map identity nics in ++ ++ (* Sort by port. *) ++ let nics = List.sort compare nics in ++ ++ let nics = List.map (fun (_, source) -> source) nics in ++ nics ++ ++class input_vmx vmx_filename = object ++ inherit input ++ ++ method as_options = "-i vmx " ^ vmx_filename ++ ++ method source () = ++ (* Parse the VMX file. *) ++ let vmx = Parse_vmx.parse_file vmx_filename in ++ ++ let name = ++ match Parse_vmx.get_string vmx ["displayName"] with ++ | None -> ++ warning (f_"no displayName key found in VMX file"); ++ name_from_disk vmx_filename ++ | Some s -> s in ++ ++ let memory_mb = ++ match Parse_vmx.get_int64 vmx ["memSize"] with ++ | None -> 32_L (* default is really 32 MB! *) ++ | Some i -> i in ++ let memory = memory_mb *^ 1024L *^ 1024L in ++ ++ let vcpu = ++ match Parse_vmx.get_int vmx ["numvcpus"] with ++ | None -> 1 ++ | Some i -> i in ++ ++ let firmware = ++ match Parse_vmx.get_string vmx ["firmware"] with ++ | None -> BIOS ++ | Some "efi" -> UEFI ++ (* Other values are not documented for this field ... *) ++ | Some fw -> ++ warning (f_"unknown firmware value '%s', assuming BIOS") fw; ++ BIOS in ++ ++ let video = ++ if Parse_vmx.namespace_present vmx ["svga"] then ++ (* We could also parse svga.vramSize. *) ++ Some (Source_other_video "vmvga") ++ else ++ None in ++ ++ let sound = ++ match Parse_vmx.get_string vmx ["sound"; "virtualDev"] with ++ | Some ("sb16") -> Some { s_sound_model = SB16 } ++ | Some ("es1371") -> Some { s_sound_model = ES1370 (* hmmm ... *) } ++ | Some "hdaudio" -> Some { s_sound_model = ICH6 (* intel-hda *) } ++ | Some model -> ++ warning (f_"unknown sound device '%s' ignored") model; ++ None ++ | None -> None in ++ ++ let disks = find_disks vmx vmx_filename in ++ let removables = find_removables vmx in ++ let nics = find_nics vmx in ++ ++ let source = { ++ s_hypervisor = VMware; ++ s_name = name; ++ s_orig_name = name; ++ s_memory = memory; ++ s_vcpu = vcpu; ++ s_features = []; ++ s_firmware = firmware; ++ s_display = None; ++ s_video = video; ++ s_sound = sound; ++ s_disks = disks; ++ s_removables = removables; ++ s_nics = nics; ++ } in ++ ++ source ++end ++ ++let input_vmx = new input_vmx ++let () = Modules_list.register_input_module "vmx" +diff --git a/v2v/input_vmx.mli b/v2v/input_vmx.mli +new file mode 100644 +index 0000000..f236f87 +--- /dev/null ++++ b/v2v/input_vmx.mli +@@ -0,0 +1,22 @@ ++(* virt-v2v ++ * 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. ++ *) ++ ++(** [-i vmx] source. *) ++ ++val input_vmx : string -> Types.input ++(** [input_vmx filename] sets up an input from vmware vmx file. *) +diff --git a/v2v/name_from_disk.ml b/v2v/name_from_disk.ml +index 82f0925..452d946 100644 +--- a/v2v/name_from_disk.ml ++++ b/v2v/name_from_disk.ml +@@ -24,7 +24,7 @@ let name_from_disk disk = + (* Remove the extension (or suffix), only if it's one usually + * used for disk images. *) + let suffixes = [ +- ".img"; ".ova"; ".qcow2"; ".raw"; ".vmdk"; ++ ".img"; ".ova"; ".qcow2"; ".raw"; ".vmdk"; ".vmx"; + "-sda"; + ] in + let rec loop = function +diff --git a/v2v/parse_vmx.ml b/v2v/parse_vmx.ml +new file mode 100644 +index 0000000..33ec17d +--- /dev/null ++++ b/v2v/parse_vmx.ml +@@ -0,0 +1,381 @@ ++(* virt-v2v ++ * 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. ++ *) ++ ++open Printf ++ ++open Common_utils ++open Common_gettext.Gettext ++ ++(* As far as I can tell the VMX format is totally unspecified. ++ * However libvirt has a useful selection of .vmx files in the ++ * sources which explore some of the darker regions of this ++ * format. ++ * ++ * So here are some facts about VMX derived from libvirt and ++ * other places: ++ * ++ * - Keys are compared case insensitively. We assume here ++ * that keys are 7-bit ASCII. ++ * ++ * - Multiple keys with the same name are not allowed. ++ * ++ * - Escaping in the value string is possible using a very weird ++ * escape format: "|22" means the character '\x22'. To write ++ * a pipe character you must use "|7C". ++ * ++ * - Boolean values are written "TRUE", "FALSE", "True", "true", etc. ++ * Because of the quotes they cannot be distinguished from strings. ++ * ++ * - Comments (#...) and blank lines are ignored. Some files start ++ * with a hash-bang path, but we ignore those as comments. This ++ * parser also ignores any other line which it doesn't understand, ++ * but will print a warning. ++ * ++ * - Multi-line values are not permitted. ++ * ++ * - Keys are namespaced using dots, eg. scsi0:0.deviceType has ++ * the namespace "scsi0:0" and the key name "deviceType". ++ * ++ * - Using namespace.present = "FALSE" means that all other keys ++ * in and under the namespace are ignored. ++ * ++ * - You cannot have a namespace and a key with the same name, eg. ++ * this is not allowed: ++ * namespace = "some value" ++ * namespace.foo = "another value" ++ * ++ * - The Hashicorp packer VMX writer considers some special keys ++ * as not requiring any quotes around their values, but I'm ++ * ignoring that for now. ++ *) ++ ++(* This VMX file: ++ * ++ * foo.a = "abc" ++ * foo.b = "def" ++ * foo.bar.c = "abc" ++ * foo.bar.d = "def" ++ * ++ * would be represented by this structure: ++ * ++ * "foo" => Namespace ( # "foo" is a namespace ++ * "a" => Key "abc"; # "foo.a" is a key with value "abc" ++ * "b" => Key "def"; ++ * "bar" => Namespace ( # "foo.bar" is another namespace ++ * "c" => Key "abc"; ++ * "d" => Key "def"; ++ * ) ++ * ) ++ * ‘( => )’s represent the StringMap type. ++ *) ++type t = key StringMap.t ++ ++and key = ++ | Key of string ++ | Namespace of t ++ ++let empty = StringMap.empty ++ ++(* Compare two trees for equality. *) ++let rec equal vmx1 vmx2 = ++ let cmp k1 k2 = ++ match k1, k2 with ++ | Key v1, Key v2 -> v1 = v2 ++ | Key _, Namespace _ -> false ++ | Namespace _, Key _ -> false ++ | Namespace vmx1, Namespace vmx2 -> equal vmx1 vmx2 ++ in ++ StringMap.equal cmp vmx1 vmx2 ++ ++(* Higher-order functions. *) ++let rec select_namespaces pred vmx = ++ _select_namespaces [] pred vmx ++ ++and _select_namespaces path pred vmx = ++ StringMap.fold ( ++ fun k v new_vmx -> ++ let path = path @ [k] in ++ match v with ++ | Key _ -> new_vmx ++ | Namespace _ when pred path -> ++ StringMap.add k v new_vmx ++ | Namespace t -> ++ let t = _select_namespaces path pred t in ++ if not (equal t empty) then ++ StringMap.add k (Namespace t) new_vmx ++ else ++ new_vmx ++ ) vmx empty ++ ++let rec map f vmx = ++ _map [] f vmx ++ ++and _map path f vmx = ++ StringMap.fold ( ++ fun k v r -> ++ let path = path @ [k] in ++ match v with ++ | Key v -> r @ [ f path (Some v) ] ++ | Namespace t -> r @ [ f path None ] @ _map path f t ++ ) vmx [] ++ ++let rec namespace_present vmx = function ++ | [] -> false ++ | [ns] -> ++ let ns = String.lowercase_ascii ns in ++ (try ++ let v = StringMap.find ns vmx in ++ match v with ++ | Key _ -> false ++ | Namespace _ -> true ++ with ++ Not_found -> false ++ ) ++ | ns :: path -> ++ let ns = String.lowercase_ascii ns in ++ (try ++ let v = StringMap.find ns vmx in ++ match v with ++ | Key _ -> false ++ | Namespace vmx -> namespace_present vmx path ++ with ++ Not_found -> false ++ ) ++ ++(* Dump the vmx structure to [chan]. Used for debugging. *) ++let rec print chan indent vmx = ++ StringMap.iter (print_key chan indent) vmx ++ ++and print_key chan indent k = function ++ | Key v -> ++ output_spaces chan indent; ++ fprintf chan "%s = \"%s\"\n" k v ++ | Namespace vmx -> ++ output_spaces chan indent; ++ fprintf chan "namespace '%s':\n" k; ++ print chan (indent+4) vmx ++ ++(* As above, but creates a string instead. *) ++let rec to_string indent vmx = ++ StringMap.fold (fun k v str -> str ^ to_string_key indent k v) vmx "" ++ ++and to_string_key indent k = function ++ | Key v -> ++ String.spaces indent ^ sprintf "%s = \"%s\"\n" k v ++ | Namespace vmx -> ++ String.spaces indent ^ sprintf "namespace '%s':\n" k ^ ++ to_string (indent+4) vmx ++ ++(* Access keys in the tree. *) ++let rec get_string vmx = function ++ | [] -> None ++ | [k] -> ++ let k = String.lowercase_ascii k in ++ (try ++ let v = StringMap.find k vmx in ++ match v with ++ | Key v -> Some v ++ | Namespace _ -> None ++ with Not_found -> None ++ ) ++ | ns :: path -> ++ let ns = String.lowercase_ascii ns in ++ (try ++ let v = StringMap.find ns vmx in ++ match v with ++ | Key v -> None ++ | Namespace vmx -> get_string vmx path ++ with ++ Not_found -> None ++ ) ++ ++let get_int64 vmx path = ++ match get_string vmx path with ++ | None -> None ++ | Some i -> Some (Int64.of_string i) ++ ++let get_int vmx path = ++ match get_string vmx path with ++ | None -> None ++ | Some i -> Some (int_of_string i) ++ ++let rec get_bool vmx path = ++ match get_string vmx path with ++ | None -> None ++ | Some t -> Some (vmx_bool_of_string t) ++ ++and vmx_bool_of_string t = ++ if String.lowercase_ascii t = "true" then true ++ else if String.lowercase_ascii t = "false" then false ++ else failwith "bool_of_string" ++ ++(* Regular expression used to match key = "value" in VMX file. *) ++let rex = Str.regexp "^\\([^ \t=]+\\)[ \t]*=[ \t]*\"\\(.*\\)\"$" ++ ++(* Remove the weird escapes used in value strings. See description above. *) ++let remove_vmx_escapes str = ++ let len = String.length str in ++ let out = Bytes.make len '\000' in ++ let j = ref 0 in ++ ++ let rec loop i = ++ if i >= len then () ++ else ( ++ let c = String.unsafe_get str i in ++ if i <= len-3 && c = '|' then ( ++ let c1 = str.[i+1] and c2 = str.[i+2] in ++ if Char.isxdigit c1 && Char.isxdigit c2 then ( ++ let x = Char.hexdigit c1 * 0x10 + Char.hexdigit c2 in ++ Bytes.set out !j (Char.chr x); ++ incr j; ++ loop (i+3) ++ ) ++ else ( ++ Bytes.set out !j c; ++ incr j; ++ loop (i+1) ++ ) ++ ) ++ else ( ++ Bytes.set out !j c; ++ incr j; ++ loop (i+1) ++ ) ++ ) ++ in ++ loop 0; ++ ++ (* Truncate the output string to its real size and return it ++ * as an immutable string. ++ *) ++ Bytes.sub_string out 0 !j ++ ++(* Parsing. *) ++let rec parse_file vmx_filename = ++ (* Read the whole file as a list of lines. *) ++ let str = read_whole_file vmx_filename in ++ if verbose () then eprintf "VMX file:\n%s\n" str; ++ parse_string str ++ ++and parse_string str = ++ let lines = String.nsplit "\n" str in ++ ++ (* I've never seen any VMX file with CR-LF endings, and VMware ++ * itself is Linux-based, but to be on the safe side ... ++ *) ++ let lines = List.map (String.trimr ~test:((=) '\r')) lines in ++ ++ (* Ignore blank lines and comments. *) ++ let lines = List.filter ( ++ fun line -> ++ let line = String.triml line in ++ let len = String.length line in ++ len > 0 && line.[0] != '#' ++ ) lines in ++ ++ (* Parse the lines into key = "value". *) ++ let lines = filter_map ( ++ fun line -> ++ if Str.string_match rex line 0 then ( ++ let key = Str.matched_group 1 line in ++ let key = String.lowercase_ascii key in ++ let value = Str.matched_group 2 line in ++ let value = remove_vmx_escapes value in ++ Some (key, value) ++ ) ++ else ( ++ warning (f_"vmx parser: cannot parse this line, ignoring: %s") line; ++ None ++ ) ++ ) lines in ++ ++ (* Split the keys into namespace paths. *) ++ let lines = ++ List.map (fun (key, value) -> String.nsplit "." key, value) lines in ++ ++ (* Build a tree from the flat list and return it. This is horribly ++ * inefficient, at least O(n²), possibly even O(n².log n). Hope ++ * there are no large VMX files! (XXX) ++ *) ++ let vmx = ++ List.fold_left ( ++ fun vmx (path, value) -> insert vmx value path ++ ) empty lines in ++ ++ (* If we're verbose, dump the parsed VMX for debugging purposes. *) ++ if verbose () then ( ++ eprintf "parsed VMX tree:\n"; ++ print stderr 0 vmx ++ ); ++ ++ (* Drop all present = "FALSE" namespaces. *) ++ let vmx = drop_not_present vmx in ++ ++ vmx ++ ++and insert vmx value = function ++ | [] -> assert false ++ | [k] -> ++ if StringMap.mem k vmx then ( ++ warning (f_"vmx parser: duplicate key '%s' ignored") k; ++ vmx ++ ) else ++ StringMap.add k (Key value) vmx ++ | ns :: path -> ++ let v = ++ try ++ (match StringMap.find ns vmx with ++ | Namespace vmx -> Some vmx ++ | Key _ -> None ++ ) ++ with Not_found -> None in ++ let v = ++ match v with ++ | None -> ++ (* Completely new namespace. *) ++ insert empty value path ++ | Some v -> ++ (* Insert the subkey into the previously created namespace. *) ++ insert v value path in ++ StringMap.add ns (Namespace v) vmx ++ ++(* Find any "present" keys. If we find present = "FALSE", then ++ * drop the containing namespace and all subkeys and subnamespaces. ++ *) ++and drop_not_present vmx = ++ StringMap.fold ( ++ fun k v new_vmx -> ++ match v with ++ | Key _ -> ++ StringMap.add k v new_vmx ++ | Namespace vmx when contains_key_present_false vmx -> ++ (* drop this namespace and all sub-spaces *) ++ new_vmx ++ | Namespace v -> ++ (* recurse into sub-namespace and do the same check *) ++ let v = drop_not_present v in ++ StringMap.add k (Namespace v) new_vmx ++ ) vmx empty ++ ++and contains_key_present_false vmx = ++ try ++ match StringMap.find "present" vmx with ++ | Key v when vmx_bool_of_string v = false -> true ++ | Key _ | Namespace _ -> false ++ with ++ Failure _ | Not_found -> false +diff --git a/v2v/parse_vmx.mli b/v2v/parse_vmx.mli +new file mode 100644 +index 0000000..0e4f21f +--- /dev/null ++++ b/v2v/parse_vmx.mli +@@ -0,0 +1,89 @@ ++(* virt-v2v ++ * 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. ++ *) ++ ++(** A simple parser for VMware [.vmx] files. *) ++ ++type t ++ ++val parse_file : string -> t ++(** [parse_file filename] parses a VMX file. *) ++ ++val parse_string : string -> t ++(** [parse_string s] parses VMX from a string. *) ++ ++val get_string : t -> string list -> string option ++(** Find a key and return it as a string. If not present, returns [None]. ++ ++ Note that if [namespace.present = "FALSE"] is found in the file ++ then all keys in [namespace] and below it are ignored. This ++ applies to all [get_*] functions. *) ++ ++val get_int64 : t -> string list -> int64 option ++(** Find a key and return it as an [int64]. ++ If not present, returns [None]. ++ ++ Raises [Failure _] if the key is present but was not parseable ++ as an integer. *) ++ ++val get_int : t -> string list -> int option ++(** Find a key and return it as an [int]. ++ If not present, returns [None]. ++ ++ Raises [Failure _] if the key is present but was not parseable ++ as an integer. *) ++ ++val get_bool : t -> string list -> bool option ++(** Find a key and return it as a boolean. ++ ++ You cannot return [namespace.present = "FALSE"] booleans this way. ++ They are processed by the parser and the namespace and anything ++ below it are removed from the tree. ++ ++ Raises [Failure _] if the key is present but was not parseable ++ as a boolean. *) ++ ++val namespace_present : t -> string list -> bool ++(** Returns true iff the namespace ({b note:} not key) is present. *) ++ ++val select_namespaces : (string list -> bool) -> t -> t ++(** Filter the VMX file, selecting exactly namespaces (and their ++ keys) matching the predicate. The predicate is a function which ++ is called on each {i namespace} path ({b note:} not on ++ namespace + key paths). If the predicate matches a ++ namespace, then all sub-namespaces under that namespace are ++ selected implicitly. *) ++ ++val map : (string list -> string option -> 'a) -> t -> 'a list ++(** Map all the entries in the VMX file into a list using the ++ map function. The map function takes two arguments. The ++ first is the path to the namespace or key, and the second ++ is the key value (or [None] if the path refers to a namespace). *) ++ ++val equal : t -> t -> bool ++(** Compare two VMX files for equality. This is mainly used for ++ testing the parser. *) ++ ++val empty : t ++(** An empty VMX file. *) ++ ++val print : out_channel -> int -> t -> unit ++(** [print chan indent] prints the VMX file to the output channel. ++ [indent] is the indentation applied to each line of output. *) ++ ++val to_string : int -> t -> string ++(** Same as {!print} but it creates a printable (multiline) string. *) +diff --git a/v2v/test-v2v-i-vmx-1.expected b/v2v/test-v2v-i-vmx-1.expected +new file mode 100644 +index 0000000..d32a299 +--- /dev/null ++++ b/v2v/test-v2v-i-vmx-1.expected +@@ -0,0 +1,42 @@ ++[ 0.0] Opening the source -i vmx test-v2v-i-vmx-1.vmx ++Source guest information (--print-source option): ++ ++ source name: BZ1308535_21disks ++hypervisor type: vmware ++ memory: 2147483648 (bytes) ++ nr vCPUs: 1 ++ CPU vendor: ++ CPU model: ++ CPU topology: sockets: - cores/socket: - threads/core: - ++ CPU features: ++ firmware: bios ++ display: ++ video: vmvga ++ sound: ++disks: ++ /BZ1308535_21disks.vmdk (vmdk) [scsi] ++ /BZ1308535_21disks_1.vmdk (vmdk) [scsi] ++ /BZ1308535_21disks_2.vmdk (vmdk) [scsi] ++ /BZ1308535_21disks_3.vmdk (vmdk) [scsi] ++ /BZ1308535_21disks_4.vmdk (vmdk) [scsi] ++ /BZ1308535_21disks_5.vmdk (vmdk) [scsi] ++ /BZ1308535_21disks_6.vmdk (vmdk) [scsi] ++ /BZ1308535_21disks_7.vmdk (vmdk) [scsi] ++ /BZ1308535_21disks_8.vmdk (vmdk) [scsi] ++ /BZ1308535_21disks_9.vmdk (vmdk) [scsi] ++ /BZ1308535_21disks_10.vmdk (vmdk) [scsi] ++ /BZ1308535_21disks_11.vmdk (vmdk) [scsi] ++ /BZ1308535_21disks_12.vmdk (vmdk) [scsi] ++ /BZ1308535_21disks_13.vmdk (vmdk) [scsi] ++ /BZ1308535_21disks_14.vmdk (vmdk) [scsi] ++ /BZ1308535_21disks_15.vmdk (vmdk) [scsi] ++ /BZ1308535_21disks_16.vmdk (vmdk) [scsi] ++ /BZ1308535_21disks_17.vmdk (vmdk) [scsi] ++ /BZ1308535_21disks_18.vmdk (vmdk) [scsi] ++ /BZ1308535_21disks_19.vmdk (vmdk) [scsi] ++ /BZ1308535_21disks_20.vmdk (vmdk) [scsi] ++removable media: ++ CD-ROM [ide] in slot 2 ++NICs: ++ Network "VM Network" mac: 00:0c:29:36:ef:31 [vmxnet3] ++ +diff --git a/v2v/test-v2v-i-vmx-1.vmx b/v2v/test-v2v-i-vmx-1.vmx +new file mode 100644 +index 0000000..3f2f060 +--- /dev/null ++++ b/v2v/test-v2v-i-vmx-1.vmx +@@ -0,0 +1,172 @@ ++.encoding = "UTF-8" ++config.version = "8" ++virtualHW.version = "8" ++nvram = "BZ1308535_21disks.nvram" ++pciBridge0.present = "TRUE" ++svga.present = "TRUE" ++pciBridge4.present = "TRUE" ++pciBridge4.virtualDev = "pcieRootPort" ++pciBridge4.functions = "8" ++pciBridge5.present = "TRUE" ++pciBridge5.virtualDev = "pcieRootPort" ++pciBridge5.functions = "8" ++pciBridge6.present = "TRUE" ++pciBridge6.virtualDev = "pcieRootPort" ++pciBridge6.functions = "8" ++pciBridge7.present = "TRUE" ++pciBridge7.virtualDev = "pcieRootPort" ++pciBridge7.functions = "8" ++vmci0.present = "TRUE" ++hpet0.present = "TRUE" ++displayName = "BZ1308535_21disks" ++extendedConfigFile = "BZ1308535_21disks.vmxf" ++virtualHW.productCompatibility = "hosted" ++memSize = "2048" ++sched.cpu.units = "mhz" ++powerType.powerOff = "soft" ++powerType.suspend = "hard" ++powerType.reset = "soft" ++scsi0.virtualDev = "pvscsi" ++scsi0.present = "TRUE" ++scsi1.virtualDev = "pvscsi" ++scsi1.present = "TRUE" ++ide1:0.deviceType = "cdrom-image" ++ide1:0.fileName = "/vmfs/volumes/5458b680-34ec3500-9f36-001320f5f6ca/ISOs/RHEL-7.1-20150219.1-Server-x86_64-boot.iso" ++ide1:0.present = "TRUE" ++floppy0.startConnected = "FALSE" ++floppy0.clientDevice = "TRUE" ++floppy0.fileName = "vmware-null-remote-floppy" ++ethernet0.virtualDev = "vmxnet3" ++ethernet0.networkName = "VM Network" ++ethernet0.addressType = "generated" ++ethernet0.present = "TRUE" ++scsi0:0.deviceType = "scsi-hardDisk" ++scsi0:0.fileName = "BZ1308535_21disks.vmdk" ++scsi0:0.present = "TRUE" ++scsi0:1.deviceType = "scsi-hardDisk" ++scsi0:1.fileName = "BZ1308535_21disks_1.vmdk" ++scsi0:1.present = "TRUE" ++scsi0:2.deviceType = "scsi-hardDisk" ++scsi0:2.fileName = "BZ1308535_21disks_2.vmdk" ++scsi0:2.present = "TRUE" ++scsi0:3.deviceType = "scsi-hardDisk" ++scsi0:3.fileName = "BZ1308535_21disks_3.vmdk" ++scsi0:3.present = "TRUE" ++scsi0:4.deviceType = "scsi-hardDisk" ++scsi0:4.fileName = "BZ1308535_21disks_4.vmdk" ++scsi0:4.present = "TRUE" ++scsi0:5.deviceType = "scsi-hardDisk" ++scsi0:5.fileName = "BZ1308535_21disks_5.vmdk" ++scsi0:5.present = "TRUE" ++scsi0:6.deviceType = "scsi-hardDisk" ++scsi0:6.fileName = "BZ1308535_21disks_6.vmdk" ++scsi0:6.present = "TRUE" ++scsi0:8.deviceType = "scsi-hardDisk" ++scsi0:8.fileName = "BZ1308535_21disks_7.vmdk" ++scsi0:8.present = "TRUE" ++scsi0:9.deviceType = "scsi-hardDisk" ++scsi0:9.fileName = "BZ1308535_21disks_8.vmdk" ++scsi0:9.present = "TRUE" ++scsi0:10.deviceType = "scsi-hardDisk" ++scsi0:10.fileName = "BZ1308535_21disks_9.vmdk" ++scsi0:10.present = "TRUE" ++scsi0:11.deviceType = "scsi-hardDisk" ++scsi0:11.fileName = "BZ1308535_21disks_10.vmdk" ++scsi0:11.present = "TRUE" ++scsi0:12.deviceType = "scsi-hardDisk" ++scsi0:12.fileName = "BZ1308535_21disks_11.vmdk" ++scsi0:12.present = "TRUE" ++scsi0:13.deviceType = "scsi-hardDisk" ++scsi0:13.fileName = "BZ1308535_21disks_12.vmdk" ++scsi0:13.present = "TRUE" ++scsi0:14.deviceType = "scsi-hardDisk" ++scsi0:14.fileName = "BZ1308535_21disks_13.vmdk" ++scsi0:14.present = "TRUE" ++scsi0:15.deviceType = "scsi-hardDisk" ++scsi0:15.fileName = "BZ1308535_21disks_14.vmdk" ++scsi0:15.present = "TRUE" ++scsi1:0.deviceType = "scsi-hardDisk" ++scsi1:0.fileName = "BZ1308535_21disks_15.vmdk" ++scsi1:0.present = "TRUE" ++scsi1:1.deviceType = "scsi-hardDisk" ++scsi1:1.fileName = "BZ1308535_21disks_16.vmdk" ++scsi1:1.present = "TRUE" ++scsi1:2.deviceType = "scsi-hardDisk" ++scsi1:2.fileName = "BZ1308535_21disks_17.vmdk" ++scsi1:2.present = "TRUE" ++scsi1:3.deviceType = "scsi-hardDisk" ++scsi1:3.fileName = "BZ1308535_21disks_18.vmdk" ++scsi1:3.present = "TRUE" ++scsi1:4.deviceType = "scsi-hardDisk" ++scsi1:4.fileName = "BZ1308535_21disks_19.vmdk" ++scsi1:4.present = "TRUE" ++scsi1:5.deviceType = "scsi-hardDisk" ++scsi1:5.fileName = "BZ1308535_21disks_20.vmdk" ++scsi1:5.present = "TRUE" ++guestOS = "rhel6-64" ++toolScripts.afterPowerOn = "TRUE" ++toolScripts.afterResume = "TRUE" ++toolScripts.beforeSuspend = "TRUE" ++toolScripts.beforePowerOff = "TRUE" ++uuid.bios = "56 4d 96 af e6 46 bd 86-5c 4d 65 4e 77 36 ef 31" ++uuid.location = "56 4d 96 af e6 46 bd 86-5c 4d 65 4e 77 36 ef 31" ++vc.uuid = "52 31 cb fc c1 3f 96 32-83 c0 bb 70 6c 90 5c fd" ++chipset.onlineStandby = "FALSE" ++sched.cpu.min = "0" ++sched.cpu.shares = "normal" ++sched.mem.min = "0" ++sched.mem.minSize = "0" ++sched.mem.shares = "normal" ++svga.vramSize = "8388608" ++sched.swap.derivedName = "/vmfs/volumes/5458b680-34ec3500-9f36-001320f5f6ca/BZ1308535_21disks/BZ1308535_21disks-6a024f8a.vswp" ++replay.supported = "FALSE" ++replay.filename = "" ++scsi0:0.redo = "" ++scsi0:1.redo = "" ++scsi0:2.redo = "" ++scsi0:3.redo = "" ++scsi0:4.redo = "" ++scsi0:5.redo = "" ++scsi0:6.redo = "" ++scsi0:8.redo = "" ++scsi0:9.redo = "" ++scsi0:10.redo = "" ++scsi0:11.redo = "" ++scsi0:12.redo = "" ++scsi0:13.redo = "" ++scsi0:14.redo = "" ++scsi0:15.redo = "" ++scsi1:0.redo = "" ++scsi1:1.redo = "" ++scsi1:2.redo = "" ++scsi1:3.redo = "" ++scsi1:4.redo = "" ++scsi1:5.redo = "" ++pciBridge0.pciSlotNumber = "17" ++pciBridge4.pciSlotNumber = "21" ++pciBridge5.pciSlotNumber = "22" ++pciBridge6.pciSlotNumber = "23" ++pciBridge7.pciSlotNumber = "24" ++scsi0.pciSlotNumber = "160" ++scsi1.pciSlotNumber = "192" ++ethernet0.pciSlotNumber = "224" ++vmci0.pciSlotNumber = "32" ++scsi0.sasWWID = "50 05 05 6f e6 46 bd 80" ++scsi1.sasWWID = "50 05 05 6f e6 46 bc 80" ++ethernet0.generatedAddress = "00:0c:29:36:ef:31" ++ethernet0.generatedAddressOffset = "0" ++vmci0.id = "2000088881" ++hostCPUID.0 = "0000000d756e65476c65746e49656e69" ++hostCPUID.1 = "000206a700100800179ae3bfbfebfbff" ++hostCPUID.80000001 = "00000000000000000000000128100800" ++guestCPUID.0 = "0000000d756e65476c65746e49656e69" ++guestCPUID.1 = "000206a700010800969822030fabfbff" ++guestCPUID.80000001 = "00000000000000000000000128100800" ++userCPUID.0 = "0000000d756e65476c65746e49656e69" ++userCPUID.1 = "000206a700100800169822030fabfbff" ++userCPUID.80000001 = "00000000000000000000000128100800" ++evcCompatibilityMode = "FALSE" ++vmotion.checkpointFBSize = "8388608" ++cleanShutdown = "TRUE" ++softPowerOff = "TRUE" ++tools.remindInstall = "TRUE" +diff --git a/v2v/test-v2v-i-vmx-2.expected b/v2v/test-v2v-i-vmx-2.expected +new file mode 100644 +index 0000000..dc3eb60 +--- /dev/null ++++ b/v2v/test-v2v-i-vmx-2.expected +@@ -0,0 +1,22 @@ ++[ 0.0] Opening the source -i vmx test-v2v-i-vmx-2.vmx ++Source guest information (--print-source option): ++ ++ source name: Fedora 20 ++hypervisor type: vmware ++ memory: 2147483648 (bytes) ++ nr vCPUs: 1 ++ CPU vendor: ++ CPU model: ++ CPU topology: sockets: - cores/socket: - threads/core: - ++ CPU features: ++ firmware: bios ++ display: ++ video: vmvga ++ sound: ++disks: ++ /Fedora 20.vmdk (vmdk) [scsi] ++removable media: ++ ++NICs: ++ Network "VM Network" mac: 00:50:56:9b:5f:0d [vmxnet3] ++ +diff --git a/v2v/test-v2v-i-vmx-2.vmx b/v2v/test-v2v-i-vmx-2.vmx +new file mode 100644 +index 0000000..d9dcf3a +--- /dev/null ++++ b/v2v/test-v2v-i-vmx-2.vmx +@@ -0,0 +1,84 @@ ++.encoding = "UTF-8" ++config.version = "8" ++virtualHW.version = "10" ++nvram = "Fedora 20.nvram" ++pciBridge0.present = "TRUE" ++svga.present = "TRUE" ++pciBridge4.present = "TRUE" ++pciBridge4.virtualDev = "pcieRootPort" ++pciBridge4.functions = "8" ++pciBridge5.present = "TRUE" ++pciBridge5.virtualDev = "pcieRootPort" ++pciBridge5.functions = "8" ++pciBridge6.present = "TRUE" ++pciBridge6.virtualDev = "pcieRootPort" ++pciBridge6.functions = "8" ++pciBridge7.present = "TRUE" ++pciBridge7.virtualDev = "pcieRootPort" ++pciBridge7.functions = "8" ++vmci0.present = "TRUE" ++hpet0.present = "TRUE" ++displayName = "Fedora 20" ++extendedConfigFile = "Fedora 20.vmxf" ++virtualHW.productCompatibility = "hosted" ++svga.vramSize = "8388608" ++memSize = "2048" ++sched.cpu.units = "mhz" ++sched.cpu.affinity = "all" ++powerType.powerOff = "soft" ++powerType.suspend = "hard" ++powerType.reset = "soft" ++scsi0.virtualDev = "pvscsi" ++scsi0.present = "TRUE" ++sata0.present = "TRUE" ++scsi0:0.deviceType = "scsi-hardDisk" ++scsi0:0.fileName = "Fedora 20.vmdk" ++sched.scsi0:0.shares = "normal" ++sched.scsi0:0.throughputCap = "off" ++scsi0:0.present = "TRUE" ++ethernet0.virtualDev = "vmxnet3" ++ethernet0.networkName = "VM Network" ++ethernet0.addressType = "vpx" ++ethernet0.generatedAddress = "00:50:56:9b:5f:0d" ++ethernet0.present = "TRUE" ++sata0:0.startConnected = "FALSE" ++sata0:0.deviceType = "cdrom-image" ++sata0:0.fileName = "/vmfs/volumes/5458b680-34ec3500-9f36-001320f5f6ca/ISOs/Fedora-20-x86_64-netinst.iso" ++sata0:0.present = "TRUE" ++floppy0.startConnected = "FALSE" ++floppy0.clientDevice = "TRUE" ++floppy0.fileName = "vmware-null-remote-floppy" ++vmci.filter.enable = "TRUE" ++guestOS = "rhel7-64" ++toolScripts.afterPowerOn = "TRUE" ++toolScripts.afterResume = "TRUE" ++toolScripts.beforeSuspend = "TRUE" ++toolScripts.beforePowerOff = "TRUE" ++uuid.bios = "42 1b 4b 87 e6 b7 d8 81-07 a0 c9 d2 21 cd 3c 6b" ++vc.uuid = "50 1b 1f 1b 73 00 32 bf-93 a1 1c b2 b4 e6 17 d6" ++sched.cpu.min = "0" ++sched.cpu.shares = "normal" ++sched.mem.min = "0" ++sched.mem.minSize = "0" ++sched.mem.shares = "normal" ++sched.swap.derivedName = "/vmfs/volumes/5458b680-34ec3500-9f36-001320f5f6ca/Fedora 20/Fedora 20-c71e4118.vswp" ++uuid.location = "56 4d 0f 53 00 63 d5 55-41 01 4c f7 55 ce 03 0e" ++replay.supported = "TRUE" ++replay.filename = "" ++scsi0:0.redo = "" ++pciBridge0.pciSlotNumber = "17" ++pciBridge4.pciSlotNumber = "21" ++pciBridge5.pciSlotNumber = "22" ++pciBridge6.pciSlotNumber = "23" ++pciBridge7.pciSlotNumber = "24" ++scsi0.pciSlotNumber = "160" ++ethernet0.pciSlotNumber = "192" ++vmci0.pciSlotNumber = "32" ++sata0.pciSlotNumber = "33" ++scsi0.sasWWID = "50 05 05 67 e6 b7 d8 80" ++vmci0.id = "567098475" ++vmotion.checkpointFBSize = "8388608" ++cleanShutdown = "TRUE" ++softPowerOff = "TRUE" ++sata0:0.allowGuestConnectionControl = "TRUE" ++tools.syncTime = "FALSE" +diff --git a/v2v/test-v2v-i-vmx-3.expected b/v2v/test-v2v-i-vmx-3.expected +new file mode 100644 +index 0000000..9e64352 +--- /dev/null ++++ b/v2v/test-v2v-i-vmx-3.expected +@@ -0,0 +1,22 @@ ++[ 0.0] Opening the source -i vmx test-v2v-i-vmx-3.vmx ++Source guest information (--print-source option): ++ ++ source name: RHEL 7.1 UEFI ++hypervisor type: vmware ++ memory: 2147483648 (bytes) ++ nr vCPUs: 1 ++ CPU vendor: ++ CPU model: ++ CPU topology: sockets: - cores/socket: - threads/core: - ++ CPU features: ++ firmware: uefi ++ display: ++ video: vmvga ++ sound: ++disks: ++ /RHEL 7.1 UEFI.vmdk (vmdk) [scsi] ++removable media: ++ CD-ROM [ide] in slot 2 ++NICs: ++ Network "VM Network" mac: 00:0c:29:4b:2b:8c [vmxnet3] ++ +diff --git a/v2v/test-v2v-i-vmx-3.vmx b/v2v/test-v2v-i-vmx-3.vmx +new file mode 100644 +index 0000000..c392155 +--- /dev/null ++++ b/v2v/test-v2v-i-vmx-3.vmx +@@ -0,0 +1,91 @@ ++.encoding = "UTF-8" ++config.version = "8" ++virtualHW.version = "8" ++nvram = "RHEL 7.1 UEFI.nvram" ++pciBridge0.present = "TRUE" ++svga.present = "TRUE" ++pciBridge4.present = "TRUE" ++pciBridge4.virtualDev = "pcieRootPort" ++pciBridge4.functions = "8" ++pciBridge5.present = "TRUE" ++pciBridge5.virtualDev = "pcieRootPort" ++pciBridge5.functions = "8" ++pciBridge6.present = "TRUE" ++pciBridge6.virtualDev = "pcieRootPort" ++pciBridge6.functions = "8" ++pciBridge7.present = "TRUE" ++pciBridge7.virtualDev = "pcieRootPort" ++pciBridge7.functions = "8" ++vmci0.present = "TRUE" ++hpet0.present = "TRUE" ++displayName = "RHEL 7.1 UEFI" ++extendedConfigFile = "RHEL 7.1 UEFI.vmxf" ++virtualHW.productCompatibility = "hosted" ++memSize = "2048" ++firmware = "efi" ++sched.cpu.units = "mhz" ++powerType.powerOff = "soft" ++powerType.suspend = "hard" ++powerType.reset = "soft" ++scsi0.virtualDev = "pvscsi" ++scsi0.present = "TRUE" ++ide1:0.startConnected = "FALSE" ++ide1:0.deviceType = "cdrom-image" ++ide1:0.fileName = "/vmfs/volumes/5458b680-34ec3500-9f36-001320f5f6ca/ISOs/RHEL-7.1-20150219.1-Server-x86_64-boot.iso" ++ide1:0.present = "TRUE" ++floppy0.startConnected = "FALSE" ++floppy0.clientDevice = "TRUE" ++floppy0.fileName = "vmware-null-remote-floppy" ++ethernet0.virtualDev = "vmxnet3" ++ethernet0.networkName = "VM Network" ++ethernet0.addressType = "generated" ++ethernet0.present = "TRUE" ++scsi0:0.deviceType = "scsi-hardDisk" ++scsi0:0.fileName = "RHEL 7.1 UEFI.vmdk" ++scsi0:0.present = "TRUE" ++guestOS = "rhel6-64" ++toolScripts.afterPowerOn = "TRUE" ++toolScripts.afterResume = "TRUE" ++toolScripts.beforeSuspend = "TRUE" ++toolScripts.beforePowerOff = "TRUE" ++uuid.bios = "56 4d 99 89 a7 21 91 0d-cc 28 e2 db d5 4b 2b 8c" ++uuid.location = "56 4d 99 89 a7 21 91 0d-cc 28 e2 db d5 4b 2b 8c" ++vc.uuid = "52 3f 29 10 d3 81 16 43-fa b0 e3 af 3b ba 36 e5" ++chipset.onlineStandby = "FALSE" ++sched.cpu.min = "0" ++sched.cpu.shares = "normal" ++sched.mem.min = "0" ++sched.mem.minSize = "0" ++sched.mem.shares = "normal" ++svga.vramSize = "8388608" ++sched.swap.derivedName = "/vmfs/volumes/5458b680-34ec3500-9f36-001320f5f6ca/RHEL 7.1 UEFI/RHEL 7.1 UEFI-58ff6e6f.vswp" ++replay.supported = "FALSE" ++replay.filename = "" ++scsi0:0.redo = "" ++pciBridge0.pciSlotNumber = "17" ++pciBridge4.pciSlotNumber = "21" ++pciBridge5.pciSlotNumber = "22" ++pciBridge6.pciSlotNumber = "23" ++pciBridge7.pciSlotNumber = "24" ++scsi0.pciSlotNumber = "160" ++ethernet0.pciSlotNumber = "192" ++vmci0.pciSlotNumber = "32" ++scsi0.sasWWID = "50 05 05 69 a7 21 91 00" ++ethernet0.generatedAddress = "00:0c:29:4b:2b:8c" ++ethernet0.generatedAddressOffset = "0" ++vmci0.id = "-716493940" ++hostCPUID.0 = "0000000d756e65476c65746e49656e69" ++hostCPUID.1 = "000206a700100800179ae3bfbfebfbff" ++hostCPUID.80000001 = "00000000000000000000000128100800" ++guestCPUID.0 = "0000000d756e65476c65746e49656e69" ++guestCPUID.1 = "000206a700010800969822030fabfbff" ++guestCPUID.80000001 = "00000000000000000000000128100800" ++userCPUID.0 = "0000000d756e65476c65746e49656e69" ++userCPUID.1 = "000206a700100800169822030fabfbff" ++userCPUID.80000001 = "00000000000000000000000128100800" ++evcCompatibilityMode = "FALSE" ++vmotion.checkpointFBSize = "8388608" ++cleanShutdown = "TRUE" ++softPowerOff = "TRUE" ++ide1:0.allowGuestConnectionControl = "TRUE" ++tools.syncTime = "FALSE" +diff --git a/v2v/test-v2v-i-vmx-4.expected b/v2v/test-v2v-i-vmx-4.expected +new file mode 100644 +index 0000000..a70533d +--- /dev/null ++++ b/v2v/test-v2v-i-vmx-4.expected +@@ -0,0 +1,22 @@ ++[ 0.0] Opening the source -i vmx test-v2v-i-vmx-4.vmx ++Source guest information (--print-source option): ++ ++ source name: Windows 7 x64 ++hypervisor type: vmware ++ memory: 2147483648 (bytes) ++ nr vCPUs: 1 ++ CPU vendor: ++ CPU model: ++ CPU topology: sockets: - cores/socket: - threads/core: - ++ CPU features: ++ firmware: bios ++ display: ++ video: vmvga ++ sound: ++disks: ++ /Windows 7 x64.vmdk (vmdk) [scsi] ++removable media: ++ CD-ROM [ide] in slot 2 ++NICs: ++ Network "VM Network" mac: 00:0c:29:94:89:23 [e1000] ++ +diff --git a/v2v/test-v2v-i-vmx-4.vmx b/v2v/test-v2v-i-vmx-4.vmx +new file mode 100644 +index 0000000..7756cf2 +--- /dev/null ++++ b/v2v/test-v2v-i-vmx-4.vmx +@@ -0,0 +1,88 @@ ++.encoding = "UTF-8" ++config.version = "8" ++virtualHW.version = "8" ++nvram = "Windows 7 x64.nvram" ++pciBridge0.present = "TRUE" ++svga.present = "TRUE" ++pciBridge4.present = "TRUE" ++pciBridge4.virtualDev = "pcieRootPort" ++pciBridge4.functions = "8" ++pciBridge5.present = "TRUE" ++pciBridge5.virtualDev = "pcieRootPort" ++pciBridge5.functions = "8" ++pciBridge6.present = "TRUE" ++pciBridge6.virtualDev = "pcieRootPort" ++pciBridge6.functions = "8" ++pciBridge7.present = "TRUE" ++pciBridge7.virtualDev = "pcieRootPort" ++pciBridge7.functions = "8" ++vmci0.present = "TRUE" ++hpet0.present = "TRUE" ++displayName = "Windows 7 x64" ++extendedConfigFile = "Windows 7 x64.vmxf" ++virtualHW.productCompatibility = "hosted" ++memSize = "2048" ++sched.cpu.units = "mhz" ++powerType.powerOff = "soft" ++powerType.suspend = "hard" ++powerType.reset = "soft" ++scsi0.virtualDev = "lsisas1068" ++scsi0.present = "TRUE" ++ide1:0.deviceType = "cdrom-image" ++ide1:0.fileName = "/vmfs/volumes/5458b680-34ec3500-9f36-001320f5f6ca/ISOs/en_windows_7_ultimate_with_sp1_x64_dvd_u_677332.iso" ++ide1:0.present = "TRUE" ++floppy0.startConnected = "FALSE" ++floppy0.clientDevice = "TRUE" ++floppy0.fileName = "vmware-null-remote-floppy" ++ethernet0.virtualDev = "e1000" ++ethernet0.networkName = "VM Network" ++ethernet0.addressType = "generated" ++ethernet0.present = "TRUE" ++scsi0:0.deviceType = "scsi-hardDisk" ++scsi0:0.fileName = "Windows 7 x64.vmdk" ++scsi0:0.present = "TRUE" ++guestOS = "windows7-64" ++toolScripts.afterPowerOn = "TRUE" ++toolScripts.afterResume = "TRUE" ++toolScripts.beforeSuspend = "TRUE" ++toolScripts.beforePowerOff = "TRUE" ++uuid.bios = "56 4d 6f ca 63 a5 a8 3e-13 ec 73 89 1d 94 89 23" ++uuid.location = "56 4d 6f ca 63 a5 a8 3e-13 ec 73 89 1d 94 89 23" ++vc.uuid = "52 7a 63 e1 2c 2f 50 46-91 66 3a e8 fa f9 c4 65" ++chipset.onlineStandby = "FALSE" ++sched.cpu.min = "0" ++sched.cpu.shares = "normal" ++sched.mem.min = "0" ++sched.mem.minSize = "0" ++sched.mem.shares = "normal" ++svga.vramSize = "8388608" ++sched.swap.derivedName = "/vmfs/volumes/5458b680-34ec3500-9f36-001320f5f6ca/Windows 7 x64/Windows 7 x64-8e3b0929.vswp" ++replay.supported = "FALSE" ++replay.filename = "" ++scsi0:0.redo = "" ++pciBridge0.pciSlotNumber = "17" ++pciBridge4.pciSlotNumber = "21" ++pciBridge5.pciSlotNumber = "22" ++pciBridge6.pciSlotNumber = "23" ++pciBridge7.pciSlotNumber = "24" ++scsi0.pciSlotNumber = "160" ++ethernet0.pciSlotNumber = "32" ++vmci0.pciSlotNumber = "33" ++scsi0.sasWWID = "50 05 05 6a 63 a5 a8 30" ++ethernet0.generatedAddress = "00:0c:29:94:89:23" ++ethernet0.generatedAddressOffset = "0" ++vmci0.id = "496273699" ++hostCPUID.0 = "0000000b756e65476c65746e49656e69" ++hostCPUID.1 = "000206c220200800029ee3ffbfebfbff" ++hostCPUID.80000001 = "0000000000000000000000012c100800" ++guestCPUID.0 = "0000000b756e65476c65746e49656e69" ++guestCPUID.1 = "000206c200010800829822030fabfbff" ++guestCPUID.80000001 = "00000000000000000000000128100800" ++userCPUID.0 = "0000000b756e65476c65746e49656e69" ++userCPUID.1 = "000206c220200800029822030fabfbff" ++userCPUID.80000001 = "00000000000000000000000128100800" ++evcCompatibilityMode = "FALSE" ++vmotion.checkpointFBSize = "8388608" ++cleanShutdown = "TRUE" ++softPowerOff = "TRUE" ++tools.remindInstall = "TRUE" +diff --git a/v2v/test-v2v-i-vmx.sh b/v2v/test-v2v-i-vmx.sh +new file mode 100755 +index 0000000..5353e7e +--- /dev/null ++++ b/v2v/test-v2v-i-vmx.sh +@@ -0,0 +1,48 @@ ++#!/bin/bash - ++# libguestfs virt-v2v test script ++# 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. ++ ++# Test -i ova option. ++ ++set -e ++ ++$TEST_FUNCTIONS ++skip_if_skipped ++skip_if_backend uml ++ ++export VIRT_TOOLS_DATA_DIR="$top_srcdir/test-data/fake-virt-tools" ++export VIRTIO_WIN="$top_srcdir/test-data/fake-virtio-win" ++ ++rm -f test-v2v-i-vmx-*.actual ++ ++for i in 1 2 3 4; do ++ $VG virt-v2v --debug-gc \ ++ -i vmx test-v2v-i-vmx-$i.vmx \ ++ --print-source > test-v2v-i-vmx-$i.actual ++ ++ # Normalize the print-source output. ++ mv test-v2v-i-vmx-$i.actual test-v2v-i-vmx-$i.actual.old ++ sed \ ++ -e "s,$(pwd),," \ ++ < test-v2v-i-vmx-$i.actual.old > test-v2v-i-vmx-$i.actual ++ rm test-v2v-i-vmx-$i.actual.old ++ ++ # Check the output. ++ diff -u test-v2v-i-vmx-$i.expected test-v2v-i-vmx-$i.actual ++done ++ ++rm test-v2v-i-vmx-*.actual +diff --git a/v2v/v2v_unit_tests.ml b/v2v/v2v_unit_tests.ml +index bd65788..dd805a3 100644 +--- a/v2v/v2v_unit_tests.ml ++++ b/v2v/v2v_unit_tests.ml +@@ -787,6 +787,148 @@ let test_qemu_img_supports ctx = + *) + ignore (Utils.qemu_img_supports_offset_and_size ()) + ++(* Test the VMX file parser in the Parse_vmx module. *) ++let test_vmx_parse_string ctx = ++ let cmp = Parse_vmx.equal in ++ let printer = Parse_vmx.to_string 0 in ++ ++ (* This should be identical to the empty file. *) ++ let t = Parse_vmx.parse_string "\ ++test.foo = \"a\" ++test.bar = \"b\" ++test.present = \"FALSE\" ++" in ++ assert_equal ~cmp ~printer Parse_vmx.empty t; ++ ++ (* Test weird escapes. *) ++ let t1 = Parse_vmx.parse_string "\ ++foo = \"a|20|21b\" ++" in ++ let t2 = Parse_vmx.parse_string "\ ++foo = \"a !b\" ++" in ++ assert_equal ~cmp ~printer t1 t2; ++ ++ (* Test case insensitivity. *) ++ let t1 = Parse_vmx.parse_string "\ ++foo = \"abc\" ++" in ++ let t2 = Parse_vmx.parse_string "\ ++fOO = \"abc\" ++" in ++ assert_equal ~cmp ~printer t1 t2; ++ let t = Parse_vmx.parse_string "\ ++flag = \"true\" ++" in ++ assert_bool "parse_vmx: failed case insensitivity test for booleans #1" ++ (Parse_vmx.get_bool t ["FLAG"] = Some true); ++ let t = Parse_vmx.parse_string "\ ++flag = \"TRUE\" ++" in ++ assert_bool "parse_vmx: failed case insensitivity test for booleans #2" ++ (Parse_vmx.get_bool t ["Flag"] = Some true); ++ ++ (* Missing keys. *) ++ let t = Parse_vmx.parse_string "\ ++foo = \"a\" ++" in ++ assert_bool "parse_vmx: failed missing key test" ++ (Parse_vmx.get_string t ["bar"] = None); ++ ++ (* namespace_present function *) ++ let t = Parse_vmx.parse_string "\ ++foo.bar.present = \"TRUE\" ++foo.baz.present = \"FALSE\" ++foo.a.b = \"abc\" ++foo.a.c = \"abc\" ++foo.b = \"abc\" ++foo.c.a = \"abc\" ++foo.c.b = \"abc\" ++" in ++ assert_bool "parse_vmx: namespace_present #1" ++ (Parse_vmx.namespace_present t ["foo"] = true); ++ assert_bool "parse_vmx: namespace_present #2" ++ (Parse_vmx.namespace_present t ["foo"; "bar"] = true); ++ assert_bool "parse_vmx: namespace_present #3" ++ (* this whole namespace should have been culled *) ++ (Parse_vmx.namespace_present t ["foo"; "baz"] = false); ++ assert_bool "parse_vmx: namespace_present #4" ++ (Parse_vmx.namespace_present t ["foo"; "a"] = true); ++ assert_bool "parse_vmx: namespace_present #5" ++ (* this is a key, not a namespace *) ++ (Parse_vmx.namespace_present t ["foo"; "a"; "b"] = false); ++ assert_bool "parse_vmx: namespace_present #6" ++ (Parse_vmx.namespace_present t ["foo"; "b"] = false); ++ assert_bool "parse_vmx: namespace_present #7" ++ (Parse_vmx.namespace_present t ["foo"; "c"] = true); ++ assert_bool "parse_vmx: namespace_present #8" ++ (Parse_vmx.namespace_present t ["foo"; "d"] = false); ++ ++ (* map function *) ++ let t = Parse_vmx.parse_string "\ ++foo.bar.present = \"TRUE\" ++foo.baz.present = \"FALSE\" ++foo.a.b = \"abc\" ++foo.a.c = \"abc\" ++foo.b = \"abc\" ++foo.c.a = \"abc\" ++foo.c.b = \"abc\" ++" in ++ let xs = ++ Parse_vmx.map ( ++ fun path -> ++ let path = String.concat "." path in ++ function ++ | None -> sprintf "%s.present = \"true\"\n" path ++ | Some v -> sprintf "%s = \"%s\"\n" path v ++ ) t in ++ let xs = List.sort compare xs in ++ let s = String.concat "" xs in ++ assert_equal ~printer:identity "\ ++foo.a.b = \"abc\" ++foo.a.c = \"abc\" ++foo.a.present = \"true\" ++foo.b = \"abc\" ++foo.bar.present = \"TRUE\" ++foo.bar.present = \"true\" ++foo.c.a = \"abc\" ++foo.c.b = \"abc\" ++foo.c.present = \"true\" ++foo.present = \"true\" ++" s; ++ ++ (* select_namespaces function *) ++ let t1 = Parse_vmx.parse_string "\ ++foo.bar.present = \"TRUE\" ++foo.a.b = \"abc\" ++foo.a.c = \"abc\" ++foo.b = \"abc\" ++foo.c.a = \"abc\" ++foo.c.b = \"abc\" ++" in ++ let t2 = ++ Parse_vmx.select_namespaces ++ (function ["foo"] -> true | _ -> false) t1 in ++ assert_equal ~cmp ~printer t1 t2; ++ ++ let t1 = Parse_vmx.parse_string "\ ++foo.bar.present = \"TRUE\" ++foo.a.b = \"abc\" ++foo.a.c = \"abc\" ++foo.b = \"abc\" ++foo.c.a = \"abc\" ++foo.c.b = \"abc\" ++foo.c.c.d.e.f = \"abc\" ++" in ++ let t1 = ++ Parse_vmx.select_namespaces ++ (function ["foo"; "a"] -> true | _ -> false) t1 in ++ let t2 = Parse_vmx.parse_string "\ ++foo.a.b = \"abc\" ++foo.a.c = \"abc\" ++" in ++ assert_equal ~cmp ~printer t2 t1 ++ + (* Suites declaration. *) + let suite = + "virt-v2v" >::: +@@ -798,6 +940,7 @@ let suite = + test_virtio_iso_path_matches_guest_os; + "Utils.shell_unquote" >:: test_shell_unquote; + "Utils.qemu_img_supports" >:: test_qemu_img_supports; ++ "Parse_vmx.parse_string" >::test_vmx_parse_string; + ] + + let () = +diff --git a/v2v/virt-v2v.pod b/v2v/virt-v2v.pod +index 7ad674d..31d1ce0 100644 +--- a/v2v/virt-v2v.pod ++++ b/v2v/virt-v2v.pod +@@ -41,7 +41,8 @@ libguestfs E 1.28. + ... ───▶│ (default) │ │ │ ──┐ └────────────┘ + └────────────┘ │ │ ─┐└──────▶ -o glance + -i libvirtxml ─────────▶ │ │ ┐└─────────▶ -o rhv +- └────────────┘ └──────────▶ -o vdsm ++ -i vmx ────────────────▶ │ │ └──────────▶ -o vdsm ++ └────────────┘ + + Virt-v2v has a number of possible input and output modes, selected + using the I<-i> and I<-o> options. Only one input and output mode can +@@ -60,6 +61,8 @@ method used by L behind the scenes. + + I<-i ova> is used for reading from a VMware ova source file. + ++I<-i vmx> is used for reading from a VMware vmx file. ++ + I<-o glance> is used for writing to OpenStack Glance. + + I<-o libvirt> is used for writing to any libvirt target. Libvirt can +@@ -215,6 +218,14 @@ ova manifest file and check the vmdk volumes for validity (checksums) + as well as analyzing the ovf file, and then convert the guest. See + L below + ++=item B<-i> B ++ ++Set the input method to I. ++ ++In this mode you can read a VMware vmx file directly. This is useful ++when VMware VMs are stored on an NFS server which you can mount ++directly. See L below ++ + =item B<-ic> libvirtURI + + Specify a libvirt connection URI to use when reading the guest. This +@@ -843,9 +854,10 @@ I<--bridge> option instead. For example: + + Virt-v2v is able to import guests from VMware vCenter Server. + +-vCenter E 5.0 is required. If you don't have vCenter, using OVA +-is recommended instead (see L below), or if +-that is not possible then see L. ++vCenter E 5.0 is required. If you don’t have vCenter, using OVA ++or VMX is recommended instead (see L and/or ++L below), or if that is not possible then see ++L. + + Virt-v2v uses libvirt for access to vCenter, and therefore the input + mode should be I<-i libvirt>. As this is the default, you don't need +@@ -1116,12 +1128,58 @@ directory containing the files: + + $ virt-v2v -i ova /path/to/files -o local -os /var/tmp + ++=head1 INPUT FROM VMWARE VMX ++ ++Virt-v2v is able to import guests from VMware’s vmx files. This is ++useful where VMware virtual machines are stored on a separate NFS ++server and you are able to mount the NFS storage directly. ++ ++If you find a folder of files called F.vmx>, ++F.vmxf>, F.nvram> and one or more F<.vmdk> disk ++images, then you can use this method. ++ ++=head2 VMX: REMOVE VMWARE TOOLS FROM WINDOWS GUESTS ++ ++For Windows guests, you should remove VMware tools before conversion. ++Although this is not strictly necessary, and the guest will still be ++able to run, if you don't do this then the converted guest will ++complain on every boot. The tools cannot be removed after conversion ++because the uninstaller checks if it is running on VMware and refuses ++to start (which is also the reason that virt-v2v cannot remove them). ++ ++This is not necessary for Linux guests, as virt-v2v is able to remove ++VMware tools. ++ ++=head2 VMX: GUEST MUST BE SHUT DOWN ++ ++B. If you don't ++shut it down, you will end up with a corrupted VM disk on the target. ++With other methods, virt-v2v tries to prevent concurrent access, but ++because the I<-i vmx> method works directly against the storage, ++checking for concurrent access is not possible. ++ ++=head2 VMX: MOUNT THE NFS STORAGE ON THE CONVERSION SERVER ++ ++Virt-v2v must be able to access the F<.vmx> file and any local ++F<.vmdk> disks. Normally this means you must mount the NFS storage ++containing these files. ++ ++=head2 VMX: IMPORTING A GUEST ++ ++To import a vmx file, do: ++ ++ $ virt-v2v -i vmx guest.vmx -o local -os /var/tmp ++ ++Virt-v2v processes the vmx file and uses it to find the location of ++any vmdk disks. ++ + =head1 INPUT FROM VMWARE ESXi HYPERVISOR + + Virt-v2v cannot access an ESXi hypervisor directly. You should use +-the OVA method above (see L) if possible, as +-it is much faster and requires much less disk space than the method +-described in this section. ++the OVA or VMX methods above (see L and/or ++L) if possible, as it is much faster and ++requires much less disk space than the method described in this ++section. + + You can use the L tool to copy the guest + off the hypervisor into a local file, and then convert it. +-- +2.9.4 + diff --git a/SOURCES/0037-appliance-When-using-verbose-mode-set-x-in-the-appli.patch b/SOURCES/0037-appliance-When-using-verbose-mode-set-x-in-the-appli.patch deleted file mode 100644 index e728121..0000000 --- a/SOURCES/0037-appliance-When-using-verbose-mode-set-x-in-the-appli.patch +++ /dev/null @@ -1,26 +0,0 @@ -From a2c3958c1487b9d3fe929498f53e71637ff8d53b Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Sat, 19 Mar 2016 18:26:39 +0000 -Subject: [PATCH] appliance: When using verbose mode, 'set -x' in the appliance - init script. - -(cherry picked from commit d368fa08955a17feed39baaab990dae361fede13) ---- - appliance/init | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/appliance/init b/appliance/init -index fd56033..239b50e 100755 ---- a/appliance/init -+++ b/appliance/init -@@ -97,6 +97,7 @@ hwclock -u -s - # Parse the kernel command line. - if [[ $cmdline == *guestfs_verbose=1* ]]; then - guestfs_verbose=1 -+ set -x - fi - if [[ $cmdline == *guestfs_network=1* ]]; then - guestfs_network=1 --- -1.8.3.1 - diff --git a/SOURCES/0037-v2v-tests-Fix-i-vmx-test-so-it-is-more-stable.patch b/SOURCES/0037-v2v-tests-Fix-i-vmx-test-so-it-is-more-stable.patch new file mode 100644 index 0000000..848213a --- /dev/null +++ b/SOURCES/0037-v2v-tests-Fix-i-vmx-test-so-it-is-more-stable.patch @@ -0,0 +1,75 @@ +From 427106e2ca70009c30706f0a55ba72c51cd13e0d Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Wed, 12 Apr 2017 08:32:58 +0100 +Subject: [PATCH] v2v: tests: Fix -i vmx test so it is more stable. + +When running under valgrind, the process takes a fraction of a second +to start up, changing the "Opening the guest" timestamp, which broke +the test. + +Fixes commit ca40078cdda9167d4658ddfe24c828c7ee76be37. + +(cherry picked from commit ec61873d397f050fe28987f10ec919778d27818a) +--- + v2v/test-v2v-i-vmx-1.expected | 2 +- + v2v/test-v2v-i-vmx-2.expected | 2 +- + v2v/test-v2v-i-vmx-3.expected | 2 +- + v2v/test-v2v-i-vmx-4.expected | 2 +- + v2v/test-v2v-i-vmx.sh | 1 + + 5 files changed, 5 insertions(+), 4 deletions(-) + +diff --git a/v2v/test-v2v-i-vmx-1.expected b/v2v/test-v2v-i-vmx-1.expected +index d32a299..902a850 100644 +--- a/v2v/test-v2v-i-vmx-1.expected ++++ b/v2v/test-v2v-i-vmx-1.expected +@@ -1,4 +1,4 @@ +-[ 0.0] Opening the source -i vmx test-v2v-i-vmx-1.vmx ++ + Source guest information (--print-source option): + + source name: BZ1308535_21disks +diff --git a/v2v/test-v2v-i-vmx-2.expected b/v2v/test-v2v-i-vmx-2.expected +index dc3eb60..6e87862 100644 +--- a/v2v/test-v2v-i-vmx-2.expected ++++ b/v2v/test-v2v-i-vmx-2.expected +@@ -1,4 +1,4 @@ +-[ 0.0] Opening the source -i vmx test-v2v-i-vmx-2.vmx ++ + Source guest information (--print-source option): + + source name: Fedora 20 +diff --git a/v2v/test-v2v-i-vmx-3.expected b/v2v/test-v2v-i-vmx-3.expected +index 9e64352..0d1585b 100644 +--- a/v2v/test-v2v-i-vmx-3.expected ++++ b/v2v/test-v2v-i-vmx-3.expected +@@ -1,4 +1,4 @@ +-[ 0.0] Opening the source -i vmx test-v2v-i-vmx-3.vmx ++ + Source guest information (--print-source option): + + source name: RHEL 7.1 UEFI +diff --git a/v2v/test-v2v-i-vmx-4.expected b/v2v/test-v2v-i-vmx-4.expected +index a70533d..06f58d7 100644 +--- a/v2v/test-v2v-i-vmx-4.expected ++++ b/v2v/test-v2v-i-vmx-4.expected +@@ -1,4 +1,4 @@ +-[ 0.0] Opening the source -i vmx test-v2v-i-vmx-4.vmx ++ + Source guest information (--print-source option): + + source name: Windows 7 x64 +diff --git a/v2v/test-v2v-i-vmx.sh b/v2v/test-v2v-i-vmx.sh +index 5353e7e..997103d 100755 +--- a/v2v/test-v2v-i-vmx.sh ++++ b/v2v/test-v2v-i-vmx.sh +@@ -37,6 +37,7 @@ for i in 1 2 3 4; do + # Normalize the print-source output. + mv test-v2v-i-vmx-$i.actual test-v2v-i-vmx-$i.actual.old + sed \ ++ -e "s,.*Opening the source.*,," \ + -e "s,$(pwd),," \ + < test-v2v-i-vmx-$i.actual.old > test-v2v-i-vmx-$i.actual + rm test-v2v-i-vmx-$i.actual.old +-- +2.9.4 + diff --git a/SOURCES/0038-appliance-init-Move-cmdline-parsing-earlier.patch b/SOURCES/0038-appliance-init-Move-cmdline-parsing-earlier.patch deleted file mode 100644 index a429161..0000000 --- a/SOURCES/0038-appliance-init-Move-cmdline-parsing-earlier.patch +++ /dev/null @@ -1,96 +0,0 @@ -From 2bb0c9f0596ef616992a248dec535c3dffc0337d Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Sat, 19 Mar 2016 18:27:07 +0000 -Subject: [PATCH] appliance: init: Move cmdline parsing earlier. - -Since commit bb5d30ab2af5720775c63179afdec3ad9efd510d, we don't -require any external programs like grep to parse the command line. We -only use bash intrinsics. - -Therefore we can do it early (but after /proc is mounted). - -This allows verbose mode to enable set -x early on, so we can trace -most things that the init script does. - -(cherry picked from commit cb8f69e95929e512fcb8882ffb647dc72fc4a865) ---- - appliance/init | 39 +++++++++++++++++++++------------------ - 1 file changed, 21 insertions(+), 18 deletions(-) - -diff --git a/appliance/init b/appliance/init -index 239b50e..55b1a35 100755 ---- a/appliance/init -+++ b/appliance/init -@@ -33,9 +33,29 @@ done - - mkdir -p /sysroot - -+# Mount /proc. - if [ ! -d /proc ]; then rm -f /proc; fi - mkdir -p /proc - mount -t proc /proc /proc -+ -+# Parse the kernel command line early (must be after /proc is mounted). -+cmdline=$( +Date: Thu, 13 Apr 2017 09:57:37 +0100 +Subject: [PATCH] v2v: -o rhv: Quote parameter to rm -rf. + +This was safe before, the change just prevents accidental errors. + +(cherry picked from commit 24a6c5b57c25e0e59697831b55000d6f8e21fd38) +--- + v2v/output_rhv.ml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/v2v/output_rhv.ml b/v2v/output_rhv.ml +index f407b4e..02bd312 100644 +--- a/v2v/output_rhv.ml ++++ b/v2v/output_rhv.ml +@@ -205,7 +205,7 @@ object + List.iter ( + fun image_uuid -> + let d = images_dir // image_uuid in +- let cmd = sprintf "rm -rf %s" d in ++ let cmd = sprintf "rm -rf %s" (quote d) in + Changeuid.command changeuid_t cmd + ) image_uuids + ) +-- +2.9.4 + diff --git a/SOURCES/0039-appliance-init-Mount-selinuxfs-along-with-other-spec.patch b/SOURCES/0039-appliance-init-Mount-selinuxfs-along-with-other-spec.patch deleted file mode 100644 index c65ec3e..0000000 --- a/SOURCES/0039-appliance-init-Mount-selinuxfs-along-with-other-spec.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 51917bc60573b85bc354e573a3d22e6dde2cec35 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Wed, 23 Mar 2016 12:13:03 +0000 -Subject: [PATCH] appliance: init: Mount selinuxfs along with other special - filesystems. - -Move this earlier. - -(cherry picked from commit 705b721b4224f43149e52d8741d2aa5c4a67b735) ---- - appliance/init | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - -diff --git a/appliance/init b/appliance/init -index 55b1a35..6793d57 100755 ---- a/appliance/init -+++ b/appliance/init -@@ -74,6 +74,10 @@ fi - # devtmpfs is required since udev 176 - mount -t devtmpfs /dev /dev - -+if [[ $cmdline == *selinux=1* ]]; then -+ mount -t selinuxfs none /sys/fs/selinux -+fi -+ - # Static nodes must happen before udev is started. - - # Set up kmod static-nodes (RHBZ#1011907). -@@ -97,10 +101,6 @@ $UDEVD --daemon #--debug - udevadm trigger - udevadm settle --timeout=600 - --if [[ $cmdline == *selinux=1* ]]; then -- mount -t selinuxfs none /sys/fs/selinux --fi -- - # Disk optimizations. - # Increase the SCSI timeout so we can read remote images. - shopt -s nullglob --- -1.8.3.1 - diff --git a/SOURCES/0039-v2v-windows-Install-both-legacy-and-modern-virtio-ke.patch b/SOURCES/0039-v2v-windows-Install-both-legacy-and-modern-virtio-ke.patch new file mode 100644 index 0000000..0ad4055 --- /dev/null +++ b/SOURCES/0039-v2v-windows-Install-both-legacy-and-modern-virtio-ke.patch @@ -0,0 +1,53 @@ +From 30ffdce6bc603f1aaf0ee77270bd1d8ff09cbf0c Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Wed, 12 Apr 2017 23:09:32 +0100 +Subject: [PATCH] v2v: windows: Install both legacy and modern virtio keys in + the registry (RHBZ#1431579). + +Thanks: Kun Wei (for finding the bug) +Thanks: Ladi Prosek (for diagnosing the problem and proposing the fix) +(cherry picked from commit d8e1c4bb474203d71903261fb06fe267c3cce3c7) +--- + v2v/windows_virtio.ml | 12 ++++++++---- + 1 file changed, 8 insertions(+), 4 deletions(-) + +diff --git a/v2v/windows_virtio.ml b/v2v/windows_virtio.ml +index 965d6ac..9e6088c 100644 +--- a/v2v/windows_virtio.ml ++++ b/v2v/windows_virtio.ml +@@ -34,8 +34,10 @@ let virtio_win = + Guestfs_config.datadir // "virtio-win" + + let scsi_class_guid = "{4D36E97B-E325-11CE-BFC1-08002BE10318}" +-let viostor_pciid = "VEN_1AF4&DEV_1001&SUBSYS_00021AF4&REV_00" +-let vioscsi_pciid = "VEN_1AF4&DEV_1004&SUBSYS_00081AF4&REV_00" ++let viostor_legacy_pciid = "VEN_1AF4&DEV_1001&SUBSYS_00021AF4&REV_00" ++let viostor_modern_pciid = "VEN_1AF4&DEV_1042&SUBSYS_11001AF4&REV_01" ++let vioscsi_legacy_pciid = "VEN_1AF4&DEV_1004&SUBSYS_00081AF4&REV_00" ++let vioscsi_modern_pciid = "VEN_1AF4&DEV_1048&SUBSYS_11001AF4&REV_01" + + let rec install_drivers ((g, _) as reg) inspect rcaps = + (* Copy the virtio drivers to the guest. *) +@@ -102,7 +104,8 @@ let rec install_drivers ((g, _) as reg) inspect rcaps = + inspect.i_windows_systemroot driver_name in + let target = g#case_sensitive_path target in + g#cp source target; +- add_guestor_to_registry reg inspect driver_name viostor_pciid; ++ add_guestor_to_registry reg inspect driver_name viostor_legacy_pciid; ++ add_guestor_to_registry reg inspect driver_name viostor_modern_pciid; + Virtio_blk + + | Some Virtio_SCSI, _, true -> +@@ -113,7 +116,8 @@ let rec install_drivers ((g, _) as reg) inspect rcaps = + inspect.i_windows_systemroot in + let target = g#case_sensitive_path target in + g#cp source target; +- add_guestor_to_registry reg inspect "vioscsi" vioscsi_pciid; ++ add_guestor_to_registry reg inspect "vioscsi" vioscsi_legacy_pciid; ++ add_guestor_to_registry reg inspect "vioscsi" vioscsi_modern_pciid; + Virtio_SCSI + + | Some IDE, _, _ -> +-- +2.9.4 + diff --git a/SOURCES/0040-appliance-init-Don-t-run-hwclock-command.patch b/SOURCES/0040-appliance-init-Don-t-run-hwclock-command.patch deleted file mode 100644 index cb8fe49..0000000 --- a/SOURCES/0040-appliance-init-Don-t-run-hwclock-command.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 28b8442ec5aaf87b7937a1753c13af6f1ab6c8e1 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Sat, 19 Mar 2016 20:13:49 +0000 -Subject: [PATCH] appliance: init: Don't run hwclock command. - -This command alone took 0.3 seconds which is about 10% of the current -launch time. It appears to be unnecessary. - -This reverts commit 508f1ee87e816bf6b6fc8e629ccbb2d61a971169. - -(cherry picked from commit f36ba3888654b55a25158edd23a40fd0e28545a8) ---- - appliance/init | 3 --- - 1 file changed, 3 deletions(-) - -diff --git a/appliance/init b/appliance/init -index 6793d57..4407bbb 100755 ---- a/appliance/init -+++ b/appliance/init -@@ -109,9 +109,6 @@ for f in /sys/block/sd*/device/timeout; do echo 300 > $f; done - for f in /sys/block/{h,s,ub,v}d*/queue/scheduler; do echo noop > $f; done - shopt -u nullglob - --# Update the system clock. --hwclock -u -s -- - # Set up the network. - ip addr add 127.0.0.1/8 brd + dev lo scope host - ip link set dev lo up --- -1.8.3.1 - diff --git a/SOURCES/0040-v2v-o-rhv-Add-Windows-2016-Server-type-in-OVF-output.patch b/SOURCES/0040-v2v-o-rhv-Add-Windows-2016-Server-type-in-OVF-output.patch new file mode 100644 index 0000000..cba1b1f --- /dev/null +++ b/SOURCES/0040-v2v-o-rhv-Add-Windows-2016-Server-type-in-OVF-output.patch @@ -0,0 +1,38 @@ +From e2ebd5a963612aec0f9035c7603739cf8245ce59 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Tue, 2 May 2017 10:57:53 +0100 +Subject: [PATCH] v2v: -o rhv: Add Windows 2016 Server type in OVF output + (RHBZ#1447202). + +Thanks: Kun Wei + +See also: +https://github.com/oVirt/ovirt-engine/commit/d233325d7b808e8bae83645ac645dfea9dfe8407 + +(cherry picked from commit d0344f3522c116d3ccba6d52cd100562ee6e1e23) +--- + v2v/OVF.ml | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/v2v/OVF.ml b/v2v/OVF.ml +index 1f838f5..e380d35 100644 +--- a/v2v/OVF.ml ++++ b/v2v/OVF.ml +@@ -194,9 +194,13 @@ and get_ostype = function + "windows_10" + + | { i_type = "windows"; i_major_version = 10; i_minor_version = 0; +- i_arch = "x86_64" } -> ++ i_arch = "x86_64"; i_product_variant = "Client" } -> + "windows_10x64" + ++ | { i_type = "windows"; i_major_version = 10; i_minor_version = 0; ++ i_arch = "x86_64" } -> ++ "windows_2016x64" ++ + | { i_type = typ; i_distro = distro; + i_major_version = major; i_minor_version = minor; i_arch = arch; + i_product_name = product } -> +-- +2.9.4 + diff --git a/SOURCES/0041-conn-Pretend-to-be-a-serial-terminal-so-sgabios-does.patch b/SOURCES/0041-conn-Pretend-to-be-a-serial-terminal-so-sgabios-does.patch deleted file mode 100644 index 000ae21..0000000 --- a/SOURCES/0041-conn-Pretend-to-be-a-serial-terminal-so-sgabios-does.patch +++ /dev/null @@ -1,77 +0,0 @@ -From 4f88b55bfad9d72675ef09480dd4d8ad96047842 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Sun, 20 Mar 2016 15:50:31 +0000 -Subject: [PATCH] conn: Pretend to be a serial terminal, so sgabios doesn't - hang. - -This tedious workaround avoids a 0.26 second pause when using sgabios -(the Serial Graphics Adapter). It's basically a workaround for buggy -code in sgabios, but much easier than fixing the assembler. - -(cherry picked from commit cd578510197eb87abf996a3a050779806682e83f) ---- - src/conn-socket.c | 34 +++++++++++++++++++++++++++++++++- - 1 file changed, 33 insertions(+), 1 deletion(-) - -diff --git a/src/conn-socket.c b/src/conn-socket.c -index 9db0bfd..8a4b9d0 100644 ---- a/src/conn-socket.c -+++ b/src/conn-socket.c -@@ -33,6 +33,8 @@ - #include - #include - -+#include "ignore-value.h" -+ - #include "guestfs.h" - #include "guestfs-internal.h" - -@@ -314,6 +316,9 @@ handle_log_message (guestfs_h *g, - { - char buf[BUFSIZ]; - ssize_t n; -+ const char dsr_request[] = "\033[6n"; -+ const char dsr_reply[] = "\033[24;80R"; -+ const char dsr_reply_padding[] = "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"; - - /* Carried over from ancient proto.c code. The comment there was: - * -@@ -341,7 +346,34 @@ handle_log_message (guestfs_h *g, - return -1; - } - -- /* It's an actual log message, send it upwards. */ -+ /* It's an actual log message. */ -+ -+ /* SGABIOS tries to query the "serial console" for its size using the -+ * ISO/IEC 6429 Device Status Report (ESC [ 6 n). If it doesn't -+ * read anything back, then it unfortunately hangs for 0.26 seconds. -+ * Therefore we detect this situation and send back a fake console -+ * size. -+ */ -+ if (memmem (buf, n, dsr_request, sizeof dsr_request - 1) != NULL) { -+ debug (g, "responding to serial console Device Status Report"); -+ -+ /* Ignore any error from this write, as it's just an optimization. -+ * We can't even be sure that console_sock is a socket or that -+ * it's writable. -+ */ -+ ignore_value (write (conn->console_sock, dsr_reply, -+ sizeof dsr_reply - 1)); -+ /* Additionally, because of a bug in sgabios, it will still pause -+ * unless you write at least 14 bytes, so we have to pad the -+ * reply. We can't pad with NULs since sgabios's input routine -+ * ignores these, so we have to use some other safe padding -+ * characters. Backspace seems innocuous. -+ */ -+ ignore_value (write (conn->console_sock, dsr_reply_padding, -+ sizeof dsr_reply_padding - 1)); -+ } -+ -+ /* Send it upwards. */ - guestfs_int_log_message_callback (g, buf, n); - - return 1; --- -1.8.3.1 - diff --git a/SOURCES/0041-daemon-lvm-Pass-yes-option-to-force-pvresize-RHBZ-14.patch b/SOURCES/0041-daemon-lvm-Pass-yes-option-to-force-pvresize-RHBZ-14.patch new file mode 100644 index 0000000..9304171 --- /dev/null +++ b/SOURCES/0041-daemon-lvm-Pass-yes-option-to-force-pvresize-RHBZ-14.patch @@ -0,0 +1,36 @@ +From 8b72cf35f3c758aca31269f454339fdffeccbcf0 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Mon, 12 Jun 2017 13:15:34 +0100 +Subject: [PATCH] daemon: lvm: Pass --yes option to force pvresize + (RHBZ#1460577). +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +LVM2 >= 2.02.171 requires the ‘--yes’ option to force pvresize to work +in various circumstances, eg. reducing the size of an existing PV. + +Pass this flag unconditionally. + +Note this does NOT break earlier versions which just ignore this flag. + +(cherry picked from commit 8a98fe91b889f666c8160f4c23af220247b4b8f3) +--- + daemon/lvm.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/daemon/lvm.c b/daemon/lvm.c +index a270b13..085e852 100644 +--- a/daemon/lvm.c ++++ b/daemon/lvm.c +@@ -625,6 +625,7 @@ do_pvresize_size (const char *device, int64_t size) + + r = command (NULL, &err, + str_lvm, "pvresize", ++ "--yes", + "--setphysicalvolumesize", buf, + device, NULL); + if (r == -1) { +-- +2.9.4 + diff --git a/SOURCES/0042-resize-make-sure-the-input-disk-is-read-only.patch b/SOURCES/0042-resize-make-sure-the-input-disk-is-read-only.patch new file mode 100644 index 0000000..8618a8f --- /dev/null +++ b/SOURCES/0042-resize-make-sure-the-input-disk-is-read-only.patch @@ -0,0 +1,28 @@ +From f1ed6a32939717d89e7bc3f9c0934b7788f2708a Mon Sep 17 00:00:00 2001 +From: Pino Toscano +Date: Wed, 21 Jun 2017 16:34:05 +0200 +Subject: [PATCH] resize: make sure the input disk is read-only + +Fixes commit 8a2b0738d1b79f288b14fc35294567430d10b7ec. + +(cherry picked from commit 1ca2a8b7ba41d7e4baf1aec5d65ace3b66f2dc37) +--- + resize/resize.ml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/resize/resize.ml b/resize/resize.ml +index dc96b23..4028aa1 100644 +--- a/resize/resize.ml ++++ b/resize/resize.ml +@@ -348,7 +348,7 @@ read the man page virt-resize(1). + (* Add in and out disks to the handle and launch. *) + let connect_both_disks () = + let g = open_guestfs () in +- add_drive_uri g ?format (snd infile); ++ add_drive_uri g ?format ~readonly:true (snd infile); + (* The output disk is being created, so use cache=unsafe here. *) + add_drive_uri g ?format:output_format ~readonly:false ~cachemode:"unsafe" + (snd outfile); +-- +2.9.4 + diff --git a/SOURCES/0042-tests-qemu-Add-program-for-tracing-and-analyzing-boo.patch b/SOURCES/0042-tests-qemu-Add-program-for-tracing-and-analyzing-boo.patch deleted file mode 100644 index 16e010a..0000000 --- a/SOURCES/0042-tests-qemu-Add-program-for-tracing-and-analyzing-boo.patch +++ /dev/null @@ -1,1711 +0,0 @@ -From 07954ad0663456014c56ed4db0c1ab3f71846678 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Fri, 18 Mar 2016 18:00:51 +0000 -Subject: [PATCH] tests/qemu: Add program for tracing and analyzing boot times. - -(cherry picked from commit 0ba59db611fc2620bf47b50c6d0a71242a0800d7) ---- - .gitignore | 1 + - appliance/init | 5 +- - tests/qemu/Makefile.am | 26 +- - tests/qemu/boot-analysis-timeline.c | 468 ++++++++++++++++ - tests/qemu/boot-analysis.c | 1030 +++++++++++++++++++++++++++++++++++ - tests/qemu/boot-analysis.h | 94 ++++ - 6 files changed, 1620 insertions(+), 4 deletions(-) - create mode 100644 tests/qemu/boot-analysis-timeline.c - create mode 100644 tests/qemu/boot-analysis.c - create mode 100644 tests/qemu/boot-analysis.h - -diff --git a/.gitignore b/.gitignore -index 6436eeb..9c45df7 100644 ---- a/.gitignore -+++ b/.gitignore -@@ -509,6 +509,7 @@ Makefile.in - /tests/mountable/test-internal-parse-mountable - /tests/parallel/test-parallel - /tests/protocol/test-error-messages -+/tests/qemu/boot-analysis - /tests/qemu/qemu-boot - /tests/qemu/qemu-speed-test - /tests/regressions/rhbz501893 -diff --git a/appliance/init b/appliance/init -index 4407bbb..4a04bce 100755 ---- a/appliance/init -+++ b/appliance/init -@@ -54,6 +54,9 @@ fi - if [[ $cmdline == *guestfs_noreboot=1* ]]; then - guestfs_noreboot=1 - fi -+if [[ $cmdline == *guestfs_boot_analysis=1* ]]; then -+ guestfs_boot_analysis=1 -+fi - - # Mount the other special filesystems. - if [ ! -d /sys ]; then rm -f /sys; fi -@@ -133,7 +136,7 @@ lvm vgchange -aay --sysinit - ldmtool create all - - # These are useful when debugging. --if test "$guestfs_verbose" = 1; then -+if test "$guestfs_verbose" = 1 && test "$guestfs_boot_analysis" != 1; then - uname -a - ls -lR /dev - cat /proc/mounts -diff --git a/tests/qemu/Makefile.am b/tests/qemu/Makefile.am -index fe45d88..bea1c85 100644 ---- a/tests/qemu/Makefile.am -+++ b/tests/qemu/Makefile.am -@@ -33,10 +33,10 @@ EXTRA_DIST = \ - qemu-boot.c \ - qemu-speed-test.c - --# qemu-boot & qemu-speed-test are built but not run by default as they --# are mainly qemu & kernel diagnostic tools. -+# qemu-boot, qemu-speed-test and boot-analysis are built but not run -+# by default as they are mainly qemu & kernel diagnostic tools. - --check_PROGRAMS = qemu-boot qemu-speed-test -+check_PROGRAMS = qemu-boot qemu-speed-test boot-analysis - - qemu_boot_SOURCES = \ - ../../df/estimate-max-threads.c \ -@@ -73,6 +73,26 @@ qemu_speed_test_LDADD = \ - $(LTLIBINTL) \ - $(top_builddir)/gnulib/lib/libgnu.la - -+boot_analysis_SOURCES = \ -+ boot-analysis.c \ -+ boot-analysis.h \ -+ boot-analysis-timeline.c -+boot_analysis_CPPFLAGS = \ -+ -I$(top_srcdir)/gnulib/lib -I$(top_builddir)/gnulib/lib \ -+ -I$(top_srcdir)/src -I$(top_builddir)/src -+boot_analysis_CFLAGS = \ -+ $(WARN_CFLAGS) $(WERROR_CFLAGS) \ -+ $(PCRE_CFLAGS) -+boot_analysis_LDADD = \ -+ $(top_builddir)/src/libutils.la \ -+ $(top_builddir)/src/libguestfs.la \ -+ $(PCRE_LIBS) \ -+ $(LIBXML2_LIBS) \ -+ $(LIBVIRT_LIBS) \ -+ $(LTLIBINTL) \ -+ $(top_builddir)/gnulib/lib/libgnu.la \ -+ -lm -+ - # Don't run these tests in parallel, since they are designed to check - # the integrity of qemu. - .NOTPARALLEL: -diff --git a/tests/qemu/boot-analysis-timeline.c b/tests/qemu/boot-analysis-timeline.c -new file mode 100644 -index 0000000..8753805 ---- /dev/null -+++ b/tests/qemu/boot-analysis-timeline.c -@@ -0,0 +1,468 @@ -+/* libguestfs -+ * Copyright (C) 2016 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 -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include "ignore-value.h" -+ -+#include "guestfs.h" -+#include "guestfs-internal-frontend.h" -+ -+#include "boot-analysis.h" -+ -+COMPILE_REGEXP(re_initcall_calling_module, -+ "calling ([_A-Za-z0-9]+)\\+.*\\[([_A-Za-z0-9]+)]", 0) -+COMPILE_REGEXP(re_initcall_calling, -+ "calling ([_A-Za-z0-9]+)\\+", 0) -+ -+static void construct_initcall_timeline (void); -+ -+/* "supermin: internal insmod xx.ko" -> "insmod xx.ko" */ -+static char * -+translate_supermin_insmod_message (const char *message) -+{ -+ char *ret; -+ -+ assert (STRPREFIX (message, "supermin: internal ")); -+ -+ ret = strdup (message + strlen ("supermin: internal ")); -+ if (ret == NULL) -+ error (EXIT_FAILURE, errno, "strdup"); -+ return ret; -+} -+ -+/* Analyze significant events from the events array, to form a -+ * timeline of activities. -+ */ -+void -+construct_timeline (void) -+{ -+ size_t i, j, k; -+ struct pass_data *data; -+ struct activity *activity; -+ -+ for (i = 0; i < NR_TEST_PASSES; ++i) { -+ data = &pass_data[i]; -+ -+ /* Find an activity, by matching an event with the condition -+ * `begin_cond' through to the second event `end_cond'. Create an -+ * activity object in the timeline from the result. -+ */ -+#define FIND(name, flags, begin_cond, end_cond) \ -+ do { \ -+ activity = NULL; \ -+ for (j = 0; j < data->nr_events; ++j) { \ -+ if (begin_cond) { \ -+ for (k = j+1; k < data->nr_events; ++k) { \ -+ if (end_cond) { \ -+ if (i == 0) \ -+ activity = add_activity (name, flags); \ -+ else \ -+ activity = find_activity (name); \ -+ break; \ -+ } \ -+ } \ -+ break; \ -+ } \ -+ } \ -+ if (activity) { \ -+ activity->start_event[i] = j; \ -+ activity->end_event[i] = k; \ -+ } \ -+ else \ -+ error (EXIT_FAILURE, 0, "could not find activity '%s' in pass '%zu'", \ -+ name, i); \ -+ } while (0) -+ -+ /* Same as FIND() macro, but if no matching events are found, -+ * ignore it. -+ */ -+#define FIND_OPTIONAL(name, flags, begin_cond, end_cond) \ -+ do { \ -+ activity = NULL; \ -+ for (j = 0; j < data->nr_events; ++j) { \ -+ if (begin_cond) { \ -+ for (k = j+1; k < data->nr_events; ++k) { \ -+ if (end_cond) { \ -+ if (i == 0) \ -+ activity = add_activity (name, flags); \ -+ else \ -+ activity = find_activity (name); \ -+ break; \ -+ } \ -+ } \ -+ break; \ -+ } \ -+ } \ -+ if (activity) { \ -+ activity->start_event[i] = j; \ -+ activity->end_event[i] = k; \ -+ } \ -+ } while (0) -+ -+ /* Find multiple entries, where we check for: -+ * next_cond -+ * next_cond -+ * next_cond -+ * end_cond -+ */ -+#define FIND_MULTIPLE(debug_name, flags, next_cond, end_cond, translate_message) \ -+ do { \ -+ activity = NULL; \ -+ for (j = 0; j < data->nr_events; ++j) { \ -+ if (next_cond) { \ -+ CLEANUP_FREE char *message = translate_message (data->events[j].message); \ -+ if (activity) \ -+ activity->end_event[i] = j; \ -+ if (i == 0) \ -+ activity = add_activity (message, flags); \ -+ else \ -+ activity = find_activity (message); \ -+ activity->start_event[i] = j; \ -+ } \ -+ else if (end_cond) \ -+ break; \ -+ } \ -+ if (j < data->nr_events && activity) \ -+ activity->end_event[i] = j; \ -+ else \ -+ error (EXIT_FAILURE, 0, "could not find activity '%s' in pass '%zu'", \ -+ debug_name, i); \ -+ } while (0) -+ -+ /* Add one activity which is going to cover the whole process -+ * from launch to close. The launch event is always event 0. -+ * NB: This activity must be called "run" (see below). -+ */ -+ FIND ("run", LONG_ACTIVITY, -+ j == 0, data->events[k].source == GUESTFS_EVENT_CLOSE); -+ -+ /* Find where we invoke supermin --build. This should be a null -+ * operation, but it still takes time to run the external command. -+ */ -+ FIND ("supermin:build", 0, -+ data->events[j].source == GUESTFS_EVENT_LIBRARY && -+ strstr (data->events[j].message, -+ "begin building supermin appliance"), -+ data->events[k].source == GUESTFS_EVENT_LIBRARY && -+ strstr (data->events[k].message, -+ "finished building supermin appliance")); -+ -+ /* Find where we invoke qemu to test features. */ -+ FIND ("qemu:feature-detect", 0, -+ data->events[j].source == GUESTFS_EVENT_LIBRARY && -+ strstr (data->events[j].message, -+ "begin testing qemu features"), -+ data->events[k].source == GUESTFS_EVENT_LIBRARY && -+ strstr (data->events[k].message, -+ "finished testing qemu features")); -+ -+ /* Find where we run qemu. */ -+ FIND ("qemu", LONG_ACTIVITY, -+ data->events[j].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[j].message, "-nodefconfig"), -+ data->events[k].source == GUESTFS_EVENT_CLOSE); -+ -+#define SGABIOS_STRING "\033[1;256r\033[256;256H\033[6n" -+ -+ /* From starting qemu up to entering the BIOS is the qemu overhead. */ -+ FIND ("qemu:overhead", 0, -+ data->events[j].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[j].message, "-nodefconfig"), -+ data->events[k].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[k].message, SGABIOS_STRING)); -+ -+ /* From entering the BIOS to starting the kernel is the BIOS overhead. */ -+ FIND_OPTIONAL ("bios:overhead", 0, -+ data->events[j].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[j].message, SGABIOS_STRING), -+ data->events[k].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[k].message, "Probing EDD")); -+ -+ /* SGABIOS (option ROM). */ -+ FIND_OPTIONAL ("sgabios", 0, -+ data->events[j].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[j].message, SGABIOS_STRING), -+ data->events[k].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[k].message, "SeaBIOS (version")); -+ -+ /* SeaBIOS. */ -+ FIND ("seabios", 0, -+ data->events[j].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[j].message, "SeaBIOS (version"), -+ data->events[k].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[k].message, "Probing EDD")); -+ -+ /* SeaBIOS - only available when using debug messages. */ -+ FIND_OPTIONAL ("seabios:pci-probe", 0, -+ data->events[j].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[j].message, "Searching bootorder for: /pci@"), -+ data->events[k].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[k].message, "Scan for option roms")); -+ -+ /* Find where we run the guest kernel. */ -+ FIND ("kernel", LONG_ACTIVITY, -+ data->events[j].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[j].message, "Probing EDD"), -+ data->events[k].source == GUESTFS_EVENT_CLOSE); -+ -+ /* Kernel startup to userspace. */ -+ FIND ("kernel:overhead", 0, -+ data->events[j].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[j].message, "Probing EDD"), -+ data->events[k].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[k].message, "supermin:") && -+ strstr (data->events[k].message, "starting up")); -+ -+ /* The time taken to get into start_kernel function. */ -+ FIND ("kernel:entry", 0, -+ data->events[j].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[j].message, "Probing EDD"), -+ data->events[k].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[k].message, "Linux version")); -+ -+ /* Alternatives patching instructions (XXX not very accurate we -+ * really need some debug messages inserted into the code). -+ */ -+ FIND ("kernel:alternatives", 0, -+ data->events[j].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[j].message, "Last level dTLB entries"), -+ data->events[k].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[k].message, "Freeing SMP alternatives")); -+ -+ /* ftrace patching instructions. */ -+ FIND ("kernel:ftrace", 0, -+ data->events[j].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[j].message, "ftrace: allocating"), -+ 1); -+ -+ /* Find where we run supermin mini-initrd. */ -+ FIND ("supermin:mini-initrd", 0, -+ data->events[j].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[j].message, "supermin:") && -+ strstr (data->events[j].message, "starting up"), -+ data->events[k].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[k].message, "supermin: chroot")); -+ -+ /* Loading kernel modules from supermin initrd. */ -+ FIND_MULTIPLE -+ ("supermin insmod", 0, -+ data->events[j].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[j].message, "supermin: internal insmod"), -+ data->events[j].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[j].message, "supermin: picked"), -+ translate_supermin_insmod_message); -+ -+ /* Find where we run the /init script. */ -+ FIND ("/init", 0, -+ data->events[j].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[j].message, "supermin: chroot"), -+ data->events[k].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[k].message, "guestfsd --verbose")); -+ -+ /* Everything from the chroot to the first echo in the /init -+ * script counts as bash overhead. -+ */ -+ FIND ("bash:overhead", 0, -+ data->events[j].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[j].message, "supermin: chroot"), -+ data->events[k].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[k].message, "Starting /init script")); -+ -+ /* /init: Mount special filesystems. */ -+ FIND ("/init:mount-special", 0, -+ data->events[j].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[j].message, "*guestfs_boot_analysis=1*"), -+ data->events[k].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[k].message, "kmod static-nodes")); -+ -+ /* /init: Run kmod static-nodes */ -+ FIND ("/init:kmod-static-nodes", 0, -+ data->events[j].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[j].message, "kmod static-nodes"), -+ data->events[k].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[k].message, "systemd-tmpfiles")); -+ -+ /* /init: systemd-tmpfiles. */ -+ FIND ("/init:systemd-tmpfiles", 0, -+ data->events[j].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[j].message, "systemd-tmpfiles"), -+ data->events[k].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[k].message, "udev")); -+ -+ /* /init: start udevd. */ -+ FIND ("/init:udev-overhead", 0, -+ data->events[j].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[j].message, "udevd --daemon"), -+ data->events[k].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[k].message, "nullglob")); -+ -+ /* /init: set up network. */ -+ FIND ("/init:network-overhead", 0, -+ data->events[j].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[j].message, "+ ip addr"), -+ data->events[k].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[k].message, "+ test")); -+ -+ /* /init: probe MD arrays. */ -+ FIND ("/init:md-probe", 0, -+ data->events[j].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[j].message, "+ mdadm"), -+ data->events[k].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[k].message, "+ modprobe dm_mod")); -+ -+ /* /init: probe DM/LVM. */ -+ FIND ("/init:lvm-probe", 0, -+ data->events[j].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[j].message, "+ modprobe dm_mod"), -+ data->events[k].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[k].message, "+ ldmtool")); -+ -+ /* /init: probe Windows dynamic disks. */ -+ FIND ("/init:windows-dynamic-disks-probe", 0, -+ data->events[j].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[j].message, "+ ldmtool"), -+ data->events[k].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[k].message, "+ test")); -+ -+ /* Find where we run guestfsd. */ -+ FIND ("guestfsd", 0, -+ data->events[j].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[j].message, "guestfsd --verbose"), -+ data->events[k].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[k].message, "fsync /dev/sda")); -+ -+ /* Shutdown process. */ -+ FIND ("shutdown", 0, -+ data->events[j].source == GUESTFS_EVENT_TRACE && -+ STREQ (data->events[j].message, "close"), -+ data->events[k].source == GUESTFS_EVENT_CLOSE); -+ } -+ -+ construct_initcall_timeline (); -+} -+ -+/* Handling of initcall is so peculiar that we hide it in a separate -+ * function from the rest. -+ */ -+static void -+construct_initcall_timeline (void) -+{ -+ size_t i, j, k; -+ struct pass_data *data; -+ struct activity *activity; -+ -+ for (i = 0; i < NR_TEST_PASSES; ++i) { -+ data = &pass_data[i]; -+ -+ /* Each kernel initcall is bracketed by: -+ * -+ * calling ehci_hcd_init+0x0/0xc1 @ 1" -+ * initcall ehci_hcd_init+0x0/0xc1 returned 0 after 420 usecs" -+ * -+ * For initcall functions in modules: -+ * -+ * calling virtio_mmio_init+0x0/0x1000 [virtio_mmio] @ 1" -+ * initcall virtio_mmio_init+0x0/0x1000 [virtio_mmio] returned 0 after 14 usecs" -+ * -+ * Initcall functions can be nested, and do not have unique names. -+ */ -+ for (j = 0; j < data->nr_events; ++j) { -+ int vec[30], r; -+ const char *message = data->events[j].message; -+ -+ if (data->events[j].source == GUESTFS_EVENT_APPLIANCE && -+ ((r = pcre_exec (re_initcall_calling_module, NULL, -+ message, strlen (message), -+ 0, 0, vec, sizeof vec / sizeof vec[0])) >= 1 || -+ (r = pcre_exec (re_initcall_calling, NULL, -+ message, strlen (message), -+ 0, 0, vec, sizeof vec / sizeof vec[0])) >= 1)) { -+ -+ CLEANUP_FREE char *fn_name = NULL, *module_name = NULL; -+ if (r >= 2) /* because pcre_exec returns 1 + number of captures */ -+ fn_name = strndup (message + vec[2], vec[3]-vec[2]); -+ if (r >= 3) -+ module_name = strndup (message + vec[4], vec[5]-vec[4]); -+ -+ CLEANUP_FREE char *fullname; -+ if (asprintf (&fullname, "%s.%s", -+ module_name ? module_name : "kernel", fn_name) == -1) -+ error (EXIT_FAILURE, errno, "asprintf"); -+ -+ CLEANUP_FREE char *initcall_match; -+ if (asprintf (&initcall_match, "initcall %s", fn_name) == -1) -+ error (EXIT_FAILURE, errno, "asprintf"); -+ -+ /* Get a unique name for this activity. Unfortunately -+ * kernel initcall function names are not unique! -+ */ -+ CLEANUP_FREE char *activity_name; -+ if (asprintf (&activity_name, "initcall %s", fullname) == -1) -+ error (EXIT_FAILURE, errno, "asprintf"); -+ -+ if (i == 0) { -+ int n = 1; -+ while (activity_exists (activity_name)) { -+ free (activity_name); -+ if (asprintf (&activity_name, "initcall %s:%d", fullname, n) == -1) -+ error (EXIT_FAILURE, errno, "asprintf"); -+ n++; -+ } -+ } -+ else { -+ int n = 1; -+ while (!activity_exists_with_no_data (activity_name, i)) { -+ free (activity_name); -+ if (asprintf (&activity_name, "initcall %s:%d", fullname, n) == -1) -+ error (EXIT_FAILURE, errno, "asprintf"); -+ n++; -+ } -+ } -+ -+ /* Find the matching end event. It might be some time later, -+ * since it appears initcalls can be nested. -+ */ -+ for (k = j+1; k < data->nr_events; ++k) { -+ if (data->events[k].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[k].message, initcall_match)) { -+ if (i == 0) -+ activity = add_activity (activity_name, 0); -+ else -+ activity = find_activity (activity_name); -+ activity->start_event[i] = j; -+ activity->end_event[i] = k; -+ break; -+ } -+ } -+ } -+ } -+ } -+} -diff --git a/tests/qemu/boot-analysis.c b/tests/qemu/boot-analysis.c -new file mode 100644 -index 0000000..71b265a ---- /dev/null -+++ b/tests/qemu/boot-analysis.c -@@ -0,0 +1,1030 @@ -+/* libguestfs -+ * Copyright (C) 2016 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. -+ */ -+ -+/* Trace and analyze the appliance boot process to find out which -+ * steps are taking the most time. It is not part of the standard -+ * tests. -+ * -+ * This needs to be run on a quiet machine, so that other processes -+ * disturb the timing as little as possible. The program is -+ * completely safe to run at any time. It doesn't read or write any -+ * external files, and it doesn't require root. -+ * -+ * You can run it from the build directory like this: -+ * -+ * make -+ * make -C tests/qemu boot-analysis -+ * ./run tests/qemu/boot-analysis -+ * -+ * The way it works is roughly like this: -+ * -+ * We create a libguestfs handle and register callback handlers so we -+ * can see appliance messages, trace events and so on. -+ * -+ * We then launch the handle and shut it down as quickly as possible. -+ * -+ * While the handle is running, events (seen by the callback handlers) -+ * are written verbatim into an in-memory buffer, with timestamps. -+ * -+ * Afterwards we analyze the result using regular expressions to try -+ * to identify a "timeline" for the handle (eg. at what time did the -+ * BIOS hand control to the kernel). This analysis is done in -+ * 'boot-analysis-timeline.c'. -+ * -+ * The whole process is repeated across a few runs, and the final -+ * timeline (including statistical analysis of the variation between -+ * runs) gets printed. -+ * -+ * The program is very sensitive to the specific messages printed by -+ * BIOS/kernel/supermin/userspace, so it won't work on non-x86, and it -+ * will require periodic adjustment of the regular expressions in -+ * order to keep things up to date. -+ */ -+ -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "ignore-value.h" -+ -+#include "guestfs.h" -+#include "guestfs-internal-frontend.h" -+ -+#include "boot-analysis.h" -+ -+/* Activities taking longer than this % of the total time, except -+ * those flagged as LONG_ACTIVITY, are highlighted in red. -+ */ -+#define WARNING_THRESHOLD 1.0 -+ -+struct pass_data pass_data[NR_TEST_PASSES]; -+size_t nr_activities; -+struct activity *activities; -+ -+static int force_colour = 0; -+static int verbose = 0; -+ -+static void run_test (void); -+static void get_time (struct timespec *ts); -+static int64_t timespec_diff (const struct timespec *x, const struct timespec *y); -+static struct event *add_event (struct pass_data *, uint64_t source); -+static guestfs_h *create_handle (void); -+static void set_up_event_handlers (guestfs_h *g, size_t pass); -+static void add_drive (guestfs_h *g); -+static void check_pass_data (void); -+static void dump_pass_data (void); -+static void analyze_timeline (void); -+static void dump_timeline (void); -+static void print_info (void); -+static void print_analysis (void); -+static void print_longest_to_shortest (void); -+static void free_pass_data (void); -+static void free_final_timeline (void); -+static void ansi_green (void); -+static void ansi_red (void); -+static void ansi_blue (void); -+static void ansi_magenta (void); -+static void ansi_restore (void); -+ -+static void -+usage (int exitcode) -+{ -+ fprintf (stderr, -+ "boot-analysis: Trace and analyze the appliance boot process.\n" -+ "Usage:\n" -+ " boot-analysis [--options]\n" -+ "Options:\n" -+ " --help Display this usage text and exit.\n" -+ " --colour Output colours, even if not a terminal.\n" -+ " -v|--verbose Verbose output, useful for debugging.\n"); -+ exit (exitcode); -+} -+ -+int -+main (int argc, char *argv[]) -+{ -+ enum { HELP_OPTION = CHAR_MAX + 1 }; -+ static const char *options = "v"; -+ static const struct option long_options[] = { -+ { "help", 0, 0, HELP_OPTION }, -+ { "color", 0, 0, 0 }, -+ { "colour", 0, 0, 0 }, -+ { "verbose", 0, 0, 'v' }, -+ { 0, 0, 0, 0 } -+ }; -+ int c, option_index; -+ -+ for (;;) { -+ c = getopt_long (argc, argv, options, long_options, &option_index); -+ if (c == -1) break; -+ -+ switch (c) { -+ case 0: /* Options which are long only. */ -+ if (STREQ (long_options[option_index].name, "color") || -+ STREQ (long_options[option_index].name, "colour")) { -+ force_colour = 1; -+ break; -+ } -+ fprintf (stderr, "%s: unknown long option: %s (%d)\n", -+ guestfs_int_program_name, long_options[option_index].name, option_index); -+ exit (EXIT_FAILURE); -+ -+ case 'v': -+ verbose = 1; -+ break; -+ -+ case HELP_OPTION: -+ usage (EXIT_SUCCESS); -+ -+ default: -+ usage (EXIT_FAILURE); -+ } -+ } -+ -+ if (STRNEQ (host_cpu, "x86_64")) -+ fprintf (stderr, "WARNING: host_cpu != x86_64: This program may not work or give bogus results.\n"); -+ -+ run_test (); -+} -+ -+static void -+run_test (void) -+{ -+ guestfs_h *g; -+ size_t i; -+ -+ printf ("Warming up the libguestfs cache ...\n"); -+ for (i = 0; i < NR_WARMUP_PASSES; ++i) { -+ g = create_handle (); -+ add_drive (g); -+ if (guestfs_launch (g) == -1) -+ exit (EXIT_FAILURE); -+ guestfs_close (g); -+ } -+ -+ printf ("Running the tests in %d passes ...\n", NR_TEST_PASSES); -+ for (i = 0; i < NR_TEST_PASSES; ++i) { -+ g = create_handle (); -+ set_up_event_handlers (g, i); -+ add_drive (g); -+ if (guestfs_launch (g) == -1) -+ exit (EXIT_FAILURE); -+ guestfs_close (g); -+ -+ printf (" pass %zu: %zu events collected in %" PRIi64 " ns\n", -+ i+1, pass_data[i].nr_events, pass_data[i].elapsed_ns); -+ } -+ -+ if (verbose) -+ dump_pass_data (); -+ -+ printf ("Analyzing the results ...\n"); -+ check_pass_data (); -+ construct_timeline (); -+ analyze_timeline (); -+ -+ if (verbose) -+ dump_timeline (); -+ -+ printf ("\n"); -+ print_info (); -+ printf ("\n"); -+ print_analysis (); -+ printf ("\n"); -+ printf ("Longest activities:\n"); -+ printf ("\n"); -+ print_longest_to_shortest (); -+ -+ free_pass_data (); -+ free_final_timeline (); -+} -+ -+static void -+get_time (struct timespec *ts) -+{ -+ if (clock_gettime (CLOCK_REALTIME, ts) == -1) -+ error (EXIT_FAILURE, errno, "clock_gettime: CLOCK_REALTIME"); -+} -+ -+/* Computes Y - X, returning nanoseconds. */ -+static int64_t -+timespec_diff (const struct timespec *x, const struct timespec *y) -+{ -+ int64_t nsec; -+ -+ nsec = (y->tv_sec - x->tv_sec) * UINT64_C(1000000000); -+ nsec += y->tv_nsec - x->tv_nsec; -+ return nsec; -+} -+ -+static struct event * -+add_event (struct pass_data *data, uint64_t source) -+{ -+ struct event *ret; -+ -+ data->nr_events++; -+ data->events = realloc (data->events, -+ sizeof (struct event) * data->nr_events); -+ if (data->events == NULL) -+ error (EXIT_FAILURE, errno, "realloc"); -+ ret = &data->events[data->nr_events-1]; -+ get_time (&ret->t); -+ ret->source = source; -+ ret->message = NULL; -+ return ret; -+} -+ -+/* Common function to create the handle and set various defaults. */ -+static guestfs_h * -+create_handle (void) -+{ -+ guestfs_h *g; -+ -+ g = guestfs_create (); -+ if (!g) error (EXIT_FAILURE, errno, "guestfs_create"); -+ -+ /* We always run these tests using LIBGUESTFS_BACKEND=direct. It -+ * may be in future we need to test libvirt as well, in case -+ * performance issues are suspected there, but so far libvirt has -+ * not been a bottleneck. -+ */ -+ if (guestfs_set_backend (g, "direct") == -1) -+ exit (EXIT_FAILURE); -+ -+ /* This changes some details in appliance/init and enables a -+ * detailed trace of calls to initcall functions in the kernel. -+ */ -+ if (guestfs_set_append (g, -+ "guestfs_boot_analysis=1 " -+ "ignore_loglevel initcall_debug") == -1) -+ exit (EXIT_FAILURE); -+ -+ return g; -+} -+ -+/* Common function to add the /dev/null drive. */ -+static void -+add_drive (guestfs_h *g) -+{ -+ if (guestfs_add_drive_opts (g, "/dev/null", -+ GUESTFS_ADD_DRIVE_OPTS_FORMAT, "raw", -+ GUESTFS_ADD_DRIVE_OPTS_READONLY, 1, -+ -1) == -1) -+ exit (EXIT_FAILURE); -+} -+ -+/* Called when the handle is closed. Perform any cleanups required in -+ * the pass_data here. -+ */ -+static void -+close_callback (guestfs_h *g, void *datavp, uint64_t source, -+ int eh, int flags, -+ const char *buf, size_t buf_len, -+ const uint64_t *array, size_t array_len) -+{ -+ struct pass_data *data = datavp; -+ struct event *event; -+ -+ if (!data->seen_launch) -+ return; -+ -+ event = add_event (data, source); -+ event->message = strdup ("close callback"); -+ if (event->message == NULL) -+ error (EXIT_FAILURE, errno, "strdup"); -+ -+ get_time (&data->end_t); -+ data->elapsed_ns = timespec_diff (&data->start_t, &data->end_t); -+} -+ -+/* Called when the qemu subprocess exits. -+ * XXX This is never called - why? -+ */ -+static void -+subprocess_quit_callback (guestfs_h *g, void *datavp, uint64_t source, -+ int eh, int flags, -+ const char *buf, size_t buf_len, -+ const uint64_t *array, size_t array_len) -+{ -+ struct pass_data *data = datavp; -+ struct event *event; -+ -+ if (!data->seen_launch) -+ return; -+ -+ event = add_event (data, source); -+ event->message = strdup ("subprocess quit callback"); -+ if (event->message == NULL) -+ error (EXIT_FAILURE, errno, "strdup"); -+} -+ -+/* Called when the launch operation is complete (the library and the -+ * guestfs daemon and talking to each other). -+ */ -+static void -+launch_done_callback (guestfs_h *g, void *datavp, uint64_t source, -+ int eh, int flags, -+ const char *buf, size_t buf_len, -+ const uint64_t *array, size_t array_len) -+{ -+ struct pass_data *data = datavp; -+ struct event *event; -+ -+ if (!data->seen_launch) -+ return; -+ -+ event = add_event (data, source); -+ event->message = strdup ("launch done callback"); -+ if (event->message == NULL) -+ error (EXIT_FAILURE, errno, "strdup"); -+} -+ -+/* Trim \r (multiple) from the end of a string. */ -+static void -+trim_r (char *message) -+{ -+ size_t len = strlen (message); -+ -+ while (len > 0 && message[len-1] == '\r') { -+ message[len-1] = '\0'; -+ len--; -+ } -+} -+ -+/* Called when we get (possibly part of) a log message (or more than -+ * one log message) from the appliance (which may include qemu, the -+ * BIOS, kernel, etc). -+ */ -+static void -+appliance_callback (guestfs_h *g, void *datavp, uint64_t source, -+ int eh, int flags, -+ const char *buf, size_t buf_len, -+ const uint64_t *array, size_t array_len) -+{ -+ struct pass_data *data = datavp; -+ struct event *event; -+ size_t i, len, slen; -+ -+ if (!data->seen_launch) -+ return; -+ -+ /* If the previous log message was incomplete, but time has moved on -+ * a lot, record a new log message anyway, so it gets a new -+ * timestamp. -+ */ -+ if (data->incomplete_log_message >= 0) { -+ struct timespec ts; -+ get_time (&ts); -+ if (timespec_diff (&data->events[data->incomplete_log_message].t, -+ &ts) >= 10000000 /* 10ms */) -+ data->incomplete_log_message = -1; -+ } -+ -+ /* If the previous log message was incomplete then we may need to -+ * append part of the current log message to a previous one. -+ */ -+ if (data->incomplete_log_message >= 0) { -+ len = buf_len; -+ for (i = 0; i < buf_len; ++i) { -+ if (buf[i] == '\n') { -+ len = i; -+ break; -+ } -+ } -+ -+ event = &data->events[data->incomplete_log_message]; -+ slen = strlen (event->message); -+ event->message = realloc (event->message, slen + len + 1); -+ if (event->message == NULL) -+ error (EXIT_FAILURE, errno, "realloc"); -+ memcpy (event->message + slen, buf, len); -+ event->message[slen + len] = '\0'; -+ trim_r (event->message); -+ -+ /* Skip what we just added to the previous incomplete message. */ -+ buf += len; -+ buf_len -= len; -+ -+ if (buf_len == 0) /* still not complete, more to come! */ -+ return; -+ -+ /* Skip the \n in the buffer. */ -+ buf++; -+ buf_len--; -+ data->incomplete_log_message = -1; -+ } -+ -+ /* Add the event, or perhaps multiple events if the message -+ * contains \n characters. -+ */ -+ while (buf_len > 0) { -+ len = buf_len; -+ for (i = 0; i < buf_len; ++i) { -+ if (buf[i] == '\n') { -+ len = i; -+ break; -+ } -+ } -+ -+ event = add_event (data, source); -+ event->message = strndup (buf, len); -+ if (event->message == NULL) -+ error (EXIT_FAILURE, errno, "strndup"); -+ trim_r (event->message); -+ -+ /* Skip what we just added to the event. */ -+ buf += len; -+ buf_len -= len; -+ -+ if (buf_len == 0) { -+ /* Event is incomplete (doesn't end with \n). We'll finish it -+ * in the next callback. -+ */ -+ data->incomplete_log_message = event - data->events; -+ return; -+ } -+ -+ /* Skip the \n in the buffer. */ -+ buf++; -+ buf_len--; -+ } -+} -+ -+/* Called when we get a debug message from the library side. These -+ * are always delivered as complete messages. -+ */ -+static void -+library_callback (guestfs_h *g, void *datavp, uint64_t source, -+ int eh, int flags, -+ const char *buf, size_t buf_len, -+ const uint64_t *array, size_t array_len) -+{ -+ struct pass_data *data = datavp; -+ struct event *event; -+ -+ if (!data->seen_launch) -+ return; -+ -+ event = add_event (data, source); -+ event->message = strndup (buf, buf_len); -+ if (event->message == NULL) -+ error (EXIT_FAILURE, errno, "strndup"); -+} -+ -+/* Called when we get a call trace message (a libguestfs API function -+ * has been called or is returning). These are always delivered as -+ * complete messages. -+ */ -+static void -+trace_callback (guestfs_h *g, void *datavp, uint64_t source, -+ int eh, int flags, -+ const char *buf, size_t buf_len, -+ const uint64_t *array, size_t array_len) -+{ -+ struct pass_data *data = datavp; -+ struct event *event; -+ char *message; -+ -+ message = strndup (buf, buf_len); -+ if (message == NULL) -+ error (EXIT_FAILURE, errno, "strndup"); -+ -+ if (STREQ (message, "launch")) -+ data->seen_launch = 1; -+ -+ if (!data->seen_launch) { -+ free (message); -+ return; -+ } -+ -+ event = add_event (data, source); -+ event->message = message; -+} -+ -+/* Common function to set up event callbacks and record data in memory -+ * for a particular pass (0 <= pass < NR_TEST_PASSES). -+ */ -+static void -+set_up_event_handlers (guestfs_h *g, size_t pass) -+{ -+ struct pass_data *data; -+ -+ assert (/* 0 <= pass && */ pass < NR_TEST_PASSES); -+ -+ data = &pass_data[pass]; -+ data->pass = pass; -+ data->nr_events = 0; -+ data->events = NULL; -+ get_time (&data->start_t); -+ data->incomplete_log_message = -1; -+ data->seen_launch = 0; -+ -+ guestfs_set_event_callback (g, close_callback, -+ GUESTFS_EVENT_CLOSE, 0, data); -+ guestfs_set_event_callback (g, subprocess_quit_callback, -+ GUESTFS_EVENT_SUBPROCESS_QUIT, 0, data); -+ guestfs_set_event_callback (g, launch_done_callback, -+ GUESTFS_EVENT_LAUNCH_DONE, 0, data); -+ guestfs_set_event_callback (g, appliance_callback, -+ GUESTFS_EVENT_APPLIANCE, 0, data); -+ guestfs_set_event_callback (g, library_callback, -+ GUESTFS_EVENT_LIBRARY, 0, data); -+ guestfs_set_event_callback (g, trace_callback, -+ GUESTFS_EVENT_TRACE, 0, data); -+ -+ guestfs_set_verbose (g, 1); -+ guestfs_set_trace (g, 1); -+} -+ -+/* Sanity check the collected events. */ -+static void -+check_pass_data (void) -+{ -+ size_t i, j, len; -+ int64_t ns; -+ const char *message; -+ -+ for (i = 0; i < NR_TEST_PASSES; ++i) { -+ assert (pass_data[i].pass == i); -+ assert (pass_data[i].elapsed_ns > 1000); -+ assert (pass_data[i].nr_events > 0); -+ assert (pass_data[i].events != NULL); -+ -+ for (j = 0; j < pass_data[i].nr_events; ++j) { -+ assert (pass_data[i].events[j].t.tv_sec > 0); -+ if (j > 0) { -+ ns = timespec_diff (&pass_data[i].events[j-1].t, -+ &pass_data[i].events[j].t); -+ assert (ns >= 0); -+ } -+ assert (pass_data[i].events[j].source != 0); -+ message = pass_data[i].events[j].message; -+ assert (message != NULL); -+ assert (strchr (message, '\n') == NULL); -+ len = strlen (message); -+ assert (len == 0 || message[len-1] != '\r'); -+ } -+ } -+} -+ -+static void -+print_escaped_string (const char *message) -+{ -+ while (*message) { -+ if (isprint (*message)) -+ putchar (*message); -+ else -+ printf ("\\x%02x", (unsigned int) *message); -+ message++; -+ } -+} -+ -+/* Dump the events to stdout, if verbose is set. */ -+static void -+dump_pass_data (void) -+{ -+ size_t i, j; -+ -+ for (i = 0; i < NR_TEST_PASSES; ++i) { -+ printf ("pass %zu\n", pass_data[i].pass); -+ printf (" number of events collected %zu\n", pass_data[i].nr_events); -+ printf (" elapsed time %" PRIi64 " ns\n", pass_data[i].elapsed_ns); -+ for (j = 0; j < pass_data[i].nr_events; ++j) { -+ int64_t ns; -+ CLEANUP_FREE char *event_str = NULL; -+ -+ ns = timespec_diff (&pass_data[i].start_t, &pass_data[i].events[j].t); -+ event_str = guestfs_event_to_string (pass_data[i].events[j].source); -+ printf (" #%zu: +%" PRIi64 " [%s] \"", j, ns, event_str); -+ print_escaped_string (pass_data[i].events[j].message); -+ printf ("\"\n"); -+ } -+ } -+} -+ -+int -+activity_exists (const char *name) -+{ -+ size_t i; -+ -+ for (i = 0; i < nr_activities; ++i) -+ if (STREQ (activities[i].name, name)) -+ return 1; -+ return 0; -+} -+ -+/* Add an activity to the global list. */ -+struct activity * -+add_activity (const char *name, int flags) -+{ -+ struct activity *ret; -+ size_t i; -+ -+ /* You shouldn't have two activities with the same name. */ -+ assert (!activity_exists (name)); -+ -+ nr_activities++; -+ activities = realloc (activities, sizeof (struct activity) * nr_activities); -+ if (activities == NULL) -+ error (EXIT_FAILURE, errno, "realloc"); -+ ret = &activities[nr_activities-1]; -+ ret->name = strdup (name); -+ if (ret->name == NULL) -+ error (EXIT_FAILURE, errno, "strdup"); -+ ret->flags = flags; -+ -+ for (i = 0; i < NR_TEST_PASSES; ++i) -+ ret->start_event[i] = ret->end_event[i] = 0; -+ -+ return ret; -+} -+ -+struct activity * -+find_activity (const char *name) -+{ -+ size_t i; -+ -+ for (i = 0; i < nr_activities; ++i) -+ if (STREQ (activities[i].name, name)) -+ return &activities[i]; -+ error (EXIT_FAILURE, 0, -+ "internal error: could not find activity '%s'", name); -+ /*NOTREACHED*/ -+ abort (); -+} -+ -+int -+activity_exists_with_no_data (const char *name, size_t pass) -+{ -+ size_t i; -+ -+ for (i = 0; i < nr_activities; ++i) -+ if (STREQ (activities[i].name, name) && -+ activities[i].start_event[pass] == 0 && -+ activities[i].end_event[pass] == 0) -+ return 1; -+ return 0; -+} -+ -+static int -+compare_activities_by_t (const void *av, const void *bv) -+{ -+ const struct activity *a = av; -+ const struct activity *b = bv; -+ -+ return a->t - b->t; -+} -+ -+/* Go through the activities, computing the start and elapsed time. */ -+static void -+analyze_timeline (void) -+{ -+ struct activity *activity; -+ size_t i, j; -+ int64_t delta_ns; -+ -+ for (j = 0; j < nr_activities; ++j) { -+ activity = &activities[j]; -+ -+ activity->t = 0; -+ activity->mean = 0; -+ for (i = 0; i < NR_TEST_PASSES; ++i) { -+ delta_ns = -+ timespec_diff (&pass_data[i].events[0].t, -+ &pass_data[i].events[activity->start_event[i]].t); -+ activity->t += delta_ns; -+ -+ delta_ns = -+ timespec_diff (&pass_data[i].events[activity->start_event[i]].t, -+ &pass_data[i].events[activity->end_event[i]].t); -+ activity->mean += delta_ns; -+ } -+ -+ /* Divide through to get real start time and mean of each activity. */ -+ activity->t /= NR_TEST_PASSES; -+ activity->mean /= NR_TEST_PASSES; -+ -+ /* Calculate the end time of this activity. It's convenient when -+ * drawing the timeline for one activity to finish just before the -+ * next activity starts, rather than having them end and start at -+ * the same time, hence ``- 1'' here. -+ */ -+ activity->end_t = activity->t + activity->mean - 1; -+ -+ /* The above only calculated mean. Now we are able to -+ * calculate from the mean the variance and the standard -+ * deviation. -+ */ -+ activity->variance = 0; -+ for (i = 0; i < NR_TEST_PASSES; ++i) { -+ delta_ns = -+ timespec_diff (&pass_data[i].events[activity->start_event[i]].t, -+ &pass_data[i].events[activity->end_event[i]].t); -+ activity->variance += pow (delta_ns - activity->mean, 2); -+ } -+ activity->variance /= NR_TEST_PASSES; -+ -+ activity->sd = sqrt (activity->variance); -+ } -+ -+ /* Get the total mean elapsed time from the special "run" activity. */ -+ activity = find_activity ("run"); -+ for (j = 0; j < nr_activities; ++j) { -+ activities[j].percent = 100.0 * activities[j].mean / activity->mean; -+ -+ activities[j].warning = -+ !(activities[j].flags & LONG_ACTIVITY) && -+ activities[j].percent >= WARNING_THRESHOLD; -+ } -+ -+ /* Sort the activities by start time. */ -+ qsort (activities, nr_activities, sizeof (struct activity), -+ compare_activities_by_t); -+} -+ -+/* Dump the timeline to stdout, if verbose is set. */ -+static void -+dump_timeline (void) -+{ -+ size_t i; -+ -+ for (i = 0; i < nr_activities; ++i) { -+ printf ("activity %zu:\n", i); -+ printf (" name = %s\n", activities[i].name); -+ printf (" start - end = %.1f - %.1f\n", -+ activities[i].t, activities[i].end_t); -+ printf (" mean elapsed = %.1f\n", activities[i].mean); -+ printf (" variance = %.1f\n", activities[i].variance); -+ printf (" s.d = %.1f\n", activities[i].sd); -+ printf (" percent = %.1f\n", activities[i].percent); -+ } -+} -+ -+/* Print some information that will allow us to determine the test -+ * system when reviewing the results in future. -+ */ -+static void -+print_info (void) -+{ -+ size_t i; -+ -+ printf ("%s %s\n", PACKAGE_NAME, PACKAGE_VERSION_FULL); -+ -+ printf ("Host:\n"); -+ ignore_value (system ("uname -a")); -+ ignore_value (system ("grep '^model name' /proc/cpuinfo | head -1")); -+ -+ /* We can dig some information about qemu and the appliance out of -+ * the events. -+ */ -+ printf ("Appliance:\n"); -+ assert (NR_TEST_PASSES > 0); -+ for (i = 0; i < pass_data[0].nr_events; ++i) { -+ const char *message = pass_data[0].events[i].message; -+ if (strstr (message, "qemu version") || -+ (strstr (message, "SeaBIOS") && strstr (message, "version")) || -+ strstr (message, "Linux version") || -+ (strstr (message, "supermin") && strstr (message, "starting up"))) { -+ print_escaped_string (message); -+ putchar ('\n'); -+ } -+ } -+} -+ -+static void -+print_activity (struct activity *activity) -+{ -+ if (activity->warning) ansi_red (); else ansi_green (); -+ print_escaped_string (activity->name); -+ ansi_restore (); -+ printf (" %1.6fs ±%.1fms ", -+ activity->mean / 1000000000, activity->sd / 1000000); -+ if (activity->warning) ansi_red (); else ansi_green (); -+ printf ("(%.1f%%) ", activity->percent); -+ ansi_restore (); -+} -+ -+static void -+print_analysis (void) -+{ -+ double t = -1; /* Current time. */ -+ /* Which columns contain activities that we are displaying now? -+ * -1 == unused column, else index of an activity -+ */ -+ CLEANUP_FREE ssize_t *columns = NULL; -+ const size_t nr_columns = nr_activities; -+ size_t last_free_column = 0; -+ -+ size_t i, j; -+ double last_t, smallest_next_t; -+ const double MAX_T = 1e20; -+ -+ columns = malloc (nr_columns * sizeof (ssize_t)); -+ if (columns == NULL) error (EXIT_FAILURE, errno, "malloc"); -+ for (j = 0; j < nr_columns; ++j) -+ columns[j] = -1; -+ -+ for (;;) { -+ /* Find the next significant time to display, which is a time when -+ * some activity started or ended. -+ */ -+ smallest_next_t = MAX_T; -+ for (i = 0; i < nr_activities; ++i) { -+ if (t < activities[i].t && activities[i].t < smallest_next_t) -+ smallest_next_t = activities[i].t; -+ else if (t < activities[i].end_t && activities[i].end_t < smallest_next_t) -+ smallest_next_t = activities[i].end_t; -+ } -+ if (smallest_next_t == MAX_T) -+ break; /* Finished. */ -+ -+ last_t = t; -+ t = smallest_next_t; -+ -+ /* Draw a spacer line, but only if last_t -> t is a large jump. */ -+ if (t - last_t >= 1000000 /* ns */) { -+ printf (" "); -+ ansi_magenta (); -+ for (j = 0; j < last_free_column; ++j) { -+ if (columns[j] >= 0 && -+ activities[columns[j]].end_t != last_t /* !▼ */) -+ printf ("│ "); -+ else -+ printf (" "); -+ } -+ ansi_restore (); -+ printf ("\n"); -+ } -+ -+ /* If there are any activities that ended before this time, drop -+ * them from the columns list. -+ */ -+ for (i = 0; i < nr_activities; ++i) { -+ if (activities[i].end_t < t) { -+ for (j = 0; j < nr_columns; ++j) -+ if (columns[j] == (ssize_t) i) { -+ columns[j] = -1; -+ break; -+ } -+ } -+ } -+ -+ /* May need to adjust last_free_column after previous operation. */ -+ while (last_free_column > 0 && columns[last_free_column-1] == -1) -+ last_free_column--; -+ -+ /* If there are any activities starting at this time, add them to -+ * the right hand end of the columns list. -+ */ -+ for (i = 0; i < nr_activities; ++i) { -+ if (activities[i].t == t) -+ columns[last_free_column++] = i; -+ } -+ -+ /* Draw the line. */ -+ ansi_blue (); -+ printf ("%1.6fs: ", t / 1000000000); -+ -+ ansi_magenta (); -+ for (j = 0; j < last_free_column; ++j) { -+ if (columns[j] >= 0) { -+ if (activities[columns[j]].t == t) -+ printf ("▲ "); -+ else if (activities[columns[j]].end_t == t) -+ printf ("▼ "); -+ else -+ printf ("│ "); -+ } -+ else -+ printf (" "); -+ } -+ ansi_restore (); -+ -+ for (j = 0; j < last_free_column; ++j) { -+ if (columns[j] >= 0 && activities[columns[j]].t == t) /* ▲ */ -+ print_activity (&activities[columns[j]]); -+ } -+ -+ printf ("\n"); -+ } -+} -+ -+static int -+compare_activities_pointers_by_mean (const void *av, const void *bv) -+{ -+ const struct activity * const *a = av; -+ const struct activity * const *b = bv; -+ -+ return (*b)->mean - (*a)->mean; -+} -+ -+static void -+print_longest_to_shortest (void) -+{ -+ size_t i; -+ CLEANUP_FREE struct activity **longest; -+ -+ /* Sort the activities longest first. In order not to affect the -+ * global activities array, sort an array of pointers to the -+ * activities instead. -+ */ -+ longest = malloc (sizeof (struct activity *) * nr_activities); -+ for (i = 0; i < nr_activities; ++i) -+ longest[i] = &activities[i]; -+ -+ qsort (longest, nr_activities, sizeof (struct activity *), -+ compare_activities_pointers_by_mean); -+ -+ /* Display the activities, longest first. */ -+ for (i = 0; i < nr_activities; ++i) { -+ print_activity (longest[i]); -+ printf ("\n"); -+ } -+} -+ -+/* Free the non-static part of the pass_data structures. */ -+static void -+free_pass_data (void) -+{ -+ size_t i, j; -+ -+ for (i = 0; i < NR_TEST_PASSES; ++i) { -+ for (j = 0; j < pass_data[i].nr_events; ++j) -+ free (pass_data[i].events[j].message); -+ free (pass_data[i].events); -+ } -+} -+ -+static void -+free_final_timeline (void) -+{ -+ size_t i; -+ -+ for (i = 0; i < nr_activities; ++i) -+ free (activities[i].name); -+ free (activities); -+} -+ -+/* Colours. */ -+static void -+ansi_green (void) -+{ -+ if (force_colour || isatty (1)) -+ fputs ("\033[0;32m", stdout); -+} -+ -+static void -+ansi_red (void) -+{ -+ if (force_colour || isatty (1)) -+ fputs ("\033[1;31m", stdout); -+} -+ -+static void -+ansi_blue (void) -+{ -+ if (force_colour || isatty (1)) -+ fputs ("\033[1;34m", stdout); -+} -+ -+static void -+ansi_magenta (void) -+{ -+ if (force_colour || isatty (1)) -+ fputs ("\033[1;35m", stdout); -+} -+ -+static void -+ansi_restore (void) -+{ -+ if (force_colour || isatty (1)) -+ fputs ("\033[0m", stdout); -+} -diff --git a/tests/qemu/boot-analysis.h b/tests/qemu/boot-analysis.h -new file mode 100644 -index 0000000..86d403e ---- /dev/null -+++ b/tests/qemu/boot-analysis.h -@@ -0,0 +1,94 @@ -+/* libguestfs -+ * Copyright (C) 2016 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. -+ */ -+ -+#ifndef GUESTFS_BOOT_ANALYSIS_H_ -+#define GUESTFS_BOOT_ANALYSIS_H_ -+ -+#define NR_WARMUP_PASSES 3 -+#define NR_TEST_PASSES 5 -+ -+/* Per-pass data collected. */ -+struct pass_data { -+ size_t pass; -+ struct timespec start_t; -+ struct timespec end_t; -+ int64_t elapsed_ns; -+ -+ /* Array of timestamped events. */ -+ size_t nr_events; -+ struct event *events; -+ -+ /* Was the previous appliance log message incomplete? If so, this -+ * contains the index of that incomplete message in the events -+ * array. -+ */ -+ ssize_t incomplete_log_message; -+ -+ /* Have we seen the launch event yet? We don't record events until -+ * this one has been received. This makes it easy to base the -+ * timeline at event 0. -+ */ -+ int seen_launch; -+}; -+ -+struct event { -+ struct timespec t; -+ uint64_t source; -+ char *message; -+}; -+ -+extern struct pass_data pass_data[NR_TEST_PASSES]; -+ -+/* The final timeline consisting of various activities starting and -+ * ending. We're interested in when the activities start, and how -+ * long they take (mean, variance, standard deviation of length). -+ */ -+struct activity { -+ char *name; /* Name of this activity. */ -+ int flags; -+#define LONG_ACTIVITY 1 /* Expected to take a long time. */ -+ -+ /* For each pass, record the actual start & end events of this -+ * activity. -+ */ -+ size_t start_event[NR_TEST_PASSES]; -+ size_t end_event[NR_TEST_PASSES]; -+ -+ double t; /* Start (ns offset). */ -+ double end_t; /* t + mean - 1 */ -+ -+ /* Length of this activity. */ -+ double mean; /* Mean time elapsed (ns). */ -+ double variance; /* Variance. */ -+ double sd; /* Standard deviation. */ -+ double percent; /* Percent of total elapsed time. */ -+ -+ int warning; /* Appears in red. */ -+}; -+ -+extern size_t nr_activities; -+extern struct activity *activities; -+ -+extern int activity_exists (const char *name); -+extern struct activity *add_activity (const char *name, int flags); -+extern struct activity *find_activity (const char *name); -+extern int activity_exists_with_no_data (const char *name, size_t pass); -+ -+extern void construct_timeline (void); -+ -+#endif /* GUESTFS_BOOT_ANALYSIS_H_ */ --- -1.8.3.1 - diff --git a/SOURCES/0043-rescue-Suggest-using-recursive-bind-mounts.patch b/SOURCES/0043-rescue-Suggest-using-recursive-bind-mounts.patch deleted file mode 100644 index 69e3b01..0000000 --- a/SOURCES/0043-rescue-Suggest-using-recursive-bind-mounts.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 5c9715d182c95601c63282050ddc9ae1d45a22ac Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Thu, 24 Mar 2016 10:46:31 +0000 -Subject: [PATCH] rescue: Suggest using recursive bind mounts. - -Since /dev and other directories contain sub-mounts, suggest using ---rbind instead of --bind. This also allows us to remove the /dev/pts -line. - -(cherry picked from commit 72fd0531ab8446dc00d565cf2f526f5c9bcee968) ---- - rescue/rescue.c | 7 +++---- - 1 file changed, 3 insertions(+), 4 deletions(-) - -diff --git a/rescue/rescue.c b/rescue/rescue.c -index 08c8062..16028a7 100644 ---- a/rescue/rescue.c -+++ b/rescue/rescue.c -@@ -461,10 +461,9 @@ do_suggestion (struct drv *drvs) - - /* If it's Linux, print the bind-mounts. */ - if (type && STREQ (type, "linux")) { -- printf ("mount --bind /dev /sysroot/dev\n"); -- printf ("mount --bind /dev/pts /sysroot/dev/pts\n"); -- printf ("mount --bind /proc /sysroot/proc\n"); -- printf ("mount --bind /sys /sysroot/sys\n"); -+ printf ("mount --rbind /dev /sysroot/dev\n"); -+ printf ("mount --rbind /proc /sysroot/proc\n"); -+ printf ("mount --rbind /sys /sysroot/sys\n"); - } - - printf ("\n"); --- -1.8.3.1 - diff --git a/SOURCES/0044-rescue-Print-chroot-suggestion-for-Linux-guests.patch b/SOURCES/0044-rescue-Print-chroot-suggestion-for-Linux-guests.patch deleted file mode 100644 index 3633323..0000000 --- a/SOURCES/0044-rescue-Print-chroot-suggestion-for-Linux-guests.patch +++ /dev/null @@ -1,33 +0,0 @@ -From f1f0123903cb2cfa66832284ca25424e903883f2 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Thu, 24 Mar 2016 10:48:03 +0000 -Subject: [PATCH] rescue: Print chroot suggestion for Linux guests. - -(cherry picked from commit a5507a16c68b6ee56258d44087b4e4529290934a) ---- - rescue/rescue.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/rescue/rescue.c b/rescue/rescue.c -index 16028a7..982f3c4 100644 ---- a/rescue/rescue.c -+++ b/rescue/rescue.c -@@ -459,11 +459,14 @@ do_suggestion (struct drv *drvs) - for (j = 0; mps[j] != NULL; j += 2) - printf ("mount %s /sysroot%s\n", mps[j+1], mps[j]); - -- /* If it's Linux, print the bind-mounts. */ -+ /* If it's Linux, print the bind-mounts and a chroot command. */ - if (type && STREQ (type, "linux")) { - printf ("mount --rbind /dev /sysroot/dev\n"); - printf ("mount --rbind /proc /sysroot/proc\n"); - printf ("mount --rbind /sys /sysroot/sys\n"); -+ printf ("\n"); -+ printf ("cd /sysroot\n"); -+ printf ("chroot /sysroot\n"); - } - - printf ("\n"); --- -1.8.3.1 - diff --git a/SOURCES/0045-rescue-Fix-test-to-deal-with-new-suggest-output.patch b/SOURCES/0045-rescue-Fix-test-to-deal-with-new-suggest-output.patch deleted file mode 100644 index e8b9433..0000000 --- a/SOURCES/0045-rescue-Fix-test-to-deal-with-new-suggest-output.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 74c5a924edaf9abdb1f6998658d2035f3c9496a8 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Thu, 24 Mar 2016 17:58:42 +0000 -Subject: [PATCH] rescue: Fix test to deal with new --suggest output. - -Fixed commit 72fd0531ab8446dc00d565cf2f526f5c9bcee968. - -(cherry picked from commit c3fb5deab693c0e193a684f7aba21785a8795828) ---- - rescue/test-virt-rescue-suggest.sh | 7 +++---- - 1 file changed, 3 insertions(+), 4 deletions(-) - -diff --git a/rescue/test-virt-rescue-suggest.sh b/rescue/test-virt-rescue-suggest.sh -index e3cb59d..a8b41e2 100755 ---- a/rescue/test-virt-rescue-suggest.sh -+++ b/rescue/test-virt-rescue-suggest.sh -@@ -34,10 +34,9 @@ $VG virt-rescue --suggest --format=raw -a "$guest" | - - if [ "$(cat virt-rescue-suggest.out)" != "mount /dev/VG/Root /sysroot/ - mount /dev/sda1 /sysroot/boot --mount --bind /dev /sysroot/dev --mount --bind /dev/pts /sysroot/dev/pts --mount --bind /proc /sysroot/proc --mount --bind /sys /sysroot/sys" ]; then -+mount --rbind /dev /sysroot/dev -+mount --rbind /proc /sysroot/proc -+mount --rbind /sys /sysroot/sys" ]; then - echo "$0: unexpected output from virt-rescue --suggest command:" - cat virt-rescue-suggest.out - exit 1 --- -1.8.3.1 - diff --git a/SOURCES/0046-boot-analysis-Add-memsize-smp-and-append-options.patch b/SOURCES/0046-boot-analysis-Add-memsize-smp-and-append-options.patch deleted file mode 100644 index b974b4d..0000000 --- a/SOURCES/0046-boot-analysis-Add-memsize-smp-and-append-options.patch +++ /dev/null @@ -1,158 +0,0 @@ -From 66292c8c5f8b35ac5ce198cdc6996ba5c0cb3741 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Tue, 29 Mar 2016 11:59:36 +0100 -Subject: [PATCH] boot-analysis: Add --memsize, --smp and --append options. - -These options allow you to control the appliance memory size, number -of vCPUs, and extra kernel options respectively. - -Note that using --smp is not usually a good idea. Not only does it -slow down the appliance, but it tends to break the boot analysis -program because it makes runs (more) non-deterministic. - -(cherry picked from commit da7e22b648ce470980c17943efcc0c5c255c33bf) ---- - tests/qemu/boot-analysis.c | 72 ++++++++++++++++++++++++++++++++++++++++------ - 1 file changed, 63 insertions(+), 9 deletions(-) - -diff --git a/tests/qemu/boot-analysis.c b/tests/qemu/boot-analysis.c -index 71b265a..fc2c93b 100644 ---- a/tests/qemu/boot-analysis.c -+++ b/tests/qemu/boot-analysis.c -@@ -89,7 +89,10 @@ struct pass_data pass_data[NR_TEST_PASSES]; - size_t nr_activities; - struct activity *activities; - -+static const char *append = NULL; - static int force_colour = 0; -+static int memsize = 0; -+static int smp = 1; - static int verbose = 0; - - static void run_test (void); -@@ -117,14 +120,28 @@ static void ansi_restore (void); - static void - usage (int exitcode) - { -+ guestfs_h *g; -+ int default_memsize = -1; -+ -+ g = guestfs_create (); -+ if (g) { -+ default_memsize = guestfs_get_memsize (g); -+ guestfs_close (g); -+ } -+ - fprintf (stderr, - "boot-analysis: Trace and analyze the appliance boot process.\n" - "Usage:\n" - " boot-analysis [--options]\n" - "Options:\n" -- " --help Display this usage text and exit.\n" -- " --colour Output colours, even if not a terminal.\n" -- " -v|--verbose Verbose output, useful for debugging.\n"); -+ " --help Display this usage text and exit.\n" -+ " --append OPTS Append OPTS to kernel command line.\n" -+ " --colour Output colours, even if not a terminal.\n" -+ " -m MB\n" -+ " --memsize MB Set memory size in MB (default: %d).\n" -+ " --smp N Enable N virtual CPUs (default: 1).\n" -+ " -v|--verbose Verbose output, useful for debugging.\n", -+ default_memsize); - exit (exitcode); - } - -@@ -132,11 +149,14 @@ int - main (int argc, char *argv[]) - { - enum { HELP_OPTION = CHAR_MAX + 1 }; -- static const char *options = "v"; -+ static const char *options = "m:v"; - static const struct option long_options[] = { - { "help", 0, 0, HELP_OPTION }, -+ { "append", 1, 0, 0 }, - { "color", 0, 0, 0 }, - { "colour", 0, 0, 0 }, -+ { "memsize", 1, 0, 'm' }, -+ { "smp", 1, 0, 0 }, - { "verbose", 0, 0, 'v' }, - { 0, 0, 0, 0 } - }; -@@ -148,15 +168,35 @@ main (int argc, char *argv[]) - - switch (c) { - case 0: /* Options which are long only. */ -- if (STREQ (long_options[option_index].name, "color") || -- STREQ (long_options[option_index].name, "colour")) { -+ if (STREQ (long_options[option_index].name, "append")) { -+ append = optarg; -+ break; -+ } -+ else if (STREQ (long_options[option_index].name, "color") || -+ STREQ (long_options[option_index].name, "colour")) { - force_colour = 1; - break; - } -+ else if (STREQ (long_options[option_index].name, "smp")) { -+ if (sscanf (optarg, "%d", &smp) != 1) { -+ fprintf (stderr, "%s: could not parse smp parameter: %s\n", -+ guestfs_int_program_name, optarg); -+ exit (EXIT_FAILURE); -+ } -+ break; -+ } - fprintf (stderr, "%s: unknown long option: %s (%d)\n", - guestfs_int_program_name, long_options[option_index].name, option_index); - exit (EXIT_FAILURE); - -+ case 'm': -+ if (sscanf (optarg, "%d", &memsize) != 1) { -+ fprintf (stderr, "%s: could not parse memsize parameter: %s\n", -+ guestfs_int_program_name, optarg); -+ exit (EXIT_FAILURE); -+ } -+ break; -+ - case 'v': - verbose = 1; - break; -@@ -267,6 +307,7 @@ static guestfs_h * - create_handle (void) - { - guestfs_h *g; -+ CLEANUP_FREE char *full_append = NULL; - - g = guestfs_create (); - if (!g) error (EXIT_FAILURE, errno, "guestfs_create"); -@@ -279,12 +320,25 @@ create_handle (void) - if (guestfs_set_backend (g, "direct") == -1) - exit (EXIT_FAILURE); - -+ if (memsize != 0) -+ if (guestfs_set_memsize (g, memsize) == -1) -+ exit (EXIT_FAILURE); -+ -+ if (smp >= 2) -+ if (guestfs_set_smp (g, smp) == -1) -+ exit (EXIT_FAILURE); -+ - /* This changes some details in appliance/init and enables a - * detailed trace of calls to initcall functions in the kernel. - */ -- if (guestfs_set_append (g, -- "guestfs_boot_analysis=1 " -- "ignore_loglevel initcall_debug") == -1) -+ if (asprintf (&full_append, -+ "guestfs_boot_analysis=1 " -+ "ignore_loglevel initcall_debug " -+ "%s", -+ append != NULL ? append : "") == -1) -+ error (EXIT_FAILURE, errno, "asprintf"); -+ -+ if (guestfs_set_append (g, full_append) == -1) - exit (EXIT_FAILURE); - - return g; --- -1.8.3.1 - diff --git a/SOURCES/0047-appliance-init-generate-etc-machine-id.patch b/SOURCES/0047-appliance-init-generate-etc-machine-id.patch deleted file mode 100644 index 8acb68a..0000000 --- a/SOURCES/0047-appliance-init-generate-etc-machine-id.patch +++ /dev/null @@ -1,38 +0,0 @@ -From f7e32e558df19e875ecb5424903923160ed2da1c Mon Sep 17 00:00:00 2001 -From: Pino Toscano -Date: Wed, 30 Mar 2016 10:15:49 +0200 -Subject: [PATCH] appliance: init: generate /etc/machine-id - -Some of the systemd-tmpfiles snippets need the machine ID of the running -system; the current lack of this file produces warning messages during -the appliance boot like: - -[/usr/lib/tmpfiles.d/systemd.conf:26] Failed to replace specifiers: /run/log/journal/%m -[/usr/lib/tmpfiles.d/systemd.conf:28] Failed to replace specifiers: /run/log/journal/%m -[/usr/lib/tmpfiles.d/systemd.conf:29] Failed to replace specifiers: /run/log/journal/%m - -Thus create a new randomly-generated /etc/machine-id on boot. - -(cherry picked from commit 807433bc230987270680ad28643e9c1741790c29) ---- - appliance/init | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/appliance/init b/appliance/init -index 4a04bce..b05c0ed 100755 ---- a/appliance/init -+++ b/appliance/init -@@ -87,6 +87,10 @@ fi - mkdir -p /run/tmpfiles.d - kmod static-nodes --format=tmpfiles --output=/run/tmpfiles.d/kmod.conf - -+# Create a machine-id with a random UUID -+machine_id=$(dd if=/dev/urandom bs=16 count=1 status=none | od -x -A n) -+echo "${machine_id// /}" > /etc/machine-id -+ - # Set up tmpfiles (must run after kmod.conf is created above). - systemd-tmpfiles --prefix=/dev --create --boot - --- -1.8.3.1 - diff --git a/SOURCES/0048-launch-direct-Add-a-comment-about-use-of-display-non.patch b/SOURCES/0048-launch-direct-Add-a-comment-about-use-of-display-non.patch deleted file mode 100644 index 95be665..0000000 --- a/SOURCES/0048-launch-direct-Add-a-comment-about-use-of-display-non.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 9c51d502dee18a07950fac664773993bcc2350af Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Fri, 1 Apr 2016 10:01:32 +0100 -Subject: [PATCH] launch: direct: Add a comment about use of -display none. - -No functional change. - -(cherry picked from commit 77e1ac5a9737d2bc6fc963baa2c2c8f1b8f1b92d) ---- - src/launch-direct.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/src/launch-direct.c b/src/launch-direct.c -index 25c97a7..92b45fd 100644 ---- a/src/launch-direct.c -+++ b/src/launch-direct.c -@@ -376,6 +376,7 @@ launch_direct (guestfs_h *g, void *datav, const char *arg) - if (qemu_supports (g, data, "-nodefaults")) - ADD_CMDLINE ("-nodefaults"); - -+ /* This disables the host-side display (SDL, Gtk). */ - ADD_CMDLINE ("-display"); - ADD_CMDLINE ("none"); - --- -1.8.3.1 - diff --git a/SOURCES/0049-launch-Only-use-sgabios-when-verbose-is-enabled.patch b/SOURCES/0049-launch-Only-use-sgabios-when-verbose-is-enabled.patch deleted file mode 100644 index 69b53ea..0000000 --- a/SOURCES/0049-launch-Only-use-sgabios-when-verbose-is-enabled.patch +++ /dev/null @@ -1,50 +0,0 @@ -From 43c9804c2b433687b6ed31288be50d91d881c74a Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Fri, 1 Apr 2016 10:05:59 +0100 -Subject: [PATCH] launch: Only use sgabios when verbose is enabled. - -The sgabios option ROM is slow. Only use it when we're debugging. - -Thanks: Paolo Bonzini. -(cherry picked from commit 6c99a17dc56ab0479b439dece549c89960b21ccc) ---- - src/launch-direct.c | 3 ++- - src/launch-libvirt.c | 8 +++++--- - 2 files changed, 7 insertions(+), 4 deletions(-) - -diff --git a/src/launch-direct.c b/src/launch-direct.c -index 92b45fd..1081445 100644 ---- a/src/launch-direct.c -+++ b/src/launch-direct.c -@@ -591,7 +591,8 @@ launch_direct (guestfs_h *g, void *datav, const char *arg) - ADD_CMDLINE ("-serial"); - ADD_CMDLINE ("stdio"); - -- if (qemu_supports_device (g, data, "Serial Graphics Adapter")) { -+ if (g->verbose && -+ qemu_supports_device (g, data, "Serial Graphics Adapter")) { - /* Use sgabios instead of vgabios. This means we'll see BIOS - * messages on the serial port, and also works around this bug - * in qemu 1.1.0: -diff --git a/src/launch-libvirt.c b/src/launch-libvirt.c -index 3df1833..f9edac0 100644 ---- a/src/launch-libvirt.c -+++ b/src/launch-libvirt.c -@@ -1219,9 +1219,11 @@ construct_libvirt_xml_boot (guestfs_h *g, - } end_element (); - - #if defined(__i386__) || defined(__x86_64__) -- start_element ("bios") { -- attribute ("useserial", "yes"); -- } end_element (); -+ if (g->verbose) { -+ start_element ("bios") { -+ attribute ("useserial", "yes"); -+ } end_element (); -+ } - #endif - - } end_element (); --- -1.8.3.1 - diff --git a/SOURCES/0050-launch-Add-a-comment-about-why-acpi-off-because-it-s.patch b/SOURCES/0050-launch-Add-a-comment-about-why-acpi-off-because-it-s.patch deleted file mode 100644 index 29e9e69..0000000 --- a/SOURCES/0050-launch-Add-a-comment-about-why-acpi-off-because-it-s.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 45589f477baba375e3a5caa39dea4526b0fe7cbf Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Fri, 1 Apr 2016 12:28:18 +0100 -Subject: [PATCH] launch: Add a comment about why acpi=off (because it's slow). - -(cherry picked from commit 2cc8a4c1ff2bca9df39db3401ffefaf1b603954c) ---- - src/launch.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/launch.c b/src/launch.c -index 0eb7d18..98eca07 100644 ---- a/src/launch.c -+++ b/src/launch.c -@@ -336,7 +336,7 @@ guestfs_int_appliance_command_line (guestfs_h *g, const char *appliance_dev, - " udev.event-timeout=6000" /* for newer udevd */ - " no_timer_check" /* fix for RHBZ#502058 */ - "%s" /* lpj */ -- " acpi=off" /* we don't need ACPI, turn it off */ -+ " acpi=off" /* ACPI is slow - 150-200ms extra on my laptop */ - " printk.time=1" /* display timestamp before kernel messages */ - " cgroup_disable=memory" /* saves us about 5 MB of RAM */ - "%s" /* root=appliance_dev */ --- -1.8.3.1 - diff --git a/SOURCES/0051-docs-Link-to-boot-analysis-program-from-guestfs-perf.patch b/SOURCES/0051-docs-Link-to-boot-analysis-program-from-guestfs-perf.patch deleted file mode 100644 index 9b00034..0000000 --- a/SOURCES/0051-docs-Link-to-boot-analysis-program-from-guestfs-perf.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 72a5b6bd7893c5c955a8c4e1957ac9453c71c285 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Fri, 1 Apr 2016 17:46:53 +0100 -Subject: [PATCH] docs: Link to boot-analysis program from - guestfs-performance(1). - -(cherry picked from commit 2e04be377a71e9e76d7c8483889a717e9d4f8ec9) ---- - docs/guestfs-performance.pod | 22 +++++++++++++++++++--- - 1 file changed, 19 insertions(+), 3 deletions(-) - -diff --git a/docs/guestfs-performance.pod b/docs/guestfs-performance.pod -index 2a7a4a4..4ba6faf 100644 ---- a/docs/guestfs-performance.pod -+++ b/docs/guestfs-performance.pod -@@ -429,7 +429,23 @@ example). - In Xen, dom0 is a virtual machine, and so hardware virtualization is - not available. - --=head1 DETAILED TIMINGS USING TS -+=head1 DETAILED ANALYSIS -+ -+=head2 Boot analysis -+ -+In the libguestfs source directory, in F is a program -+called C. This program is able to produce a very -+detailed breakdown of the boot steps (eg. qemu, BIOS, kernel, -+libguestfs init script), and can measure how long it takes to perform -+each step. -+ -+To run this program, do: -+ -+ make -+ make -C tests/qemu boot-analysis -+ ./run ./tests/qemu/boot-analysis -+ -+=head2 Detailed timings using ts - - Use the L command (from moreutils) to show detailed - timings: -@@ -450,7 +466,7 @@ timings: - - The timestamps are seconds (incrementally since the previous line). - --=head1 DETAILED TIMINGS USING SYSTEMTAP -+=head2 Detailed timings using SystemTap - - You can use SystemTap (L) to get detailed timings from - libguestfs programs. -@@ -516,7 +532,7 @@ example: - You will need to consult, and even modify, the source to libguestfs to - fully understand the output. - --=head1 DETAILED DEBUGGING USING GDB -+=head2 Detailed debugging using gdb - - You can attach to the appliance BIOS/kernel using gdb. If you know - what you're doing, this can be a useful way to diagnose boot --- -1.8.3.1 - diff --git a/SOURCES/0052-tests-qemu-Add-boot-benchmark.patch b/SOURCES/0052-tests-qemu-Add-boot-benchmark.patch deleted file mode 100644 index 5957442..0000000 --- a/SOURCES/0052-tests-qemu-Add-boot-benchmark.patch +++ /dev/null @@ -1,499 +0,0 @@ -From 8a9557041411dbb6739fb81c7ea992ef4109aa22 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Fri, 1 Apr 2016 19:19:51 +0100 -Subject: [PATCH] tests/qemu: Add boot-benchmark. - -Add a new test program called 'boot-benchmark'. This is similar to -'boot-analysis' but it simply boots and shuts down the appliance -several times in a row and measures how long it takes, calculating -mean and standard deviation. - -(cherry picked from commit 96ce2f9afedc6a7ecb2f7781958c3940255f453b) ---- - .gitignore | 1 + - docs/guestfs-performance.pod | 15 ++- - tests/qemu/Makefile.am | 30 ++++- - tests/qemu/boot-analysis-utils.c | 47 ++++++++ - tests/qemu/boot-analysis-utils.h | 30 +++++ - tests/qemu/boot-analysis.c | 21 +--- - tests/qemu/boot-benchmark.c | 230 +++++++++++++++++++++++++++++++++++++++ - 7 files changed, 346 insertions(+), 28 deletions(-) - create mode 100644 tests/qemu/boot-analysis-utils.c - create mode 100644 tests/qemu/boot-analysis-utils.h - create mode 100644 tests/qemu/boot-benchmark.c - -diff --git a/.gitignore b/.gitignore -index 9c45df7..46a6e65 100644 ---- a/.gitignore -+++ b/.gitignore -@@ -510,6 +510,7 @@ Makefile.in - /tests/parallel/test-parallel - /tests/protocol/test-error-messages - /tests/qemu/boot-analysis -+/tests/qemu/boot-benchmark - /tests/qemu/qemu-boot - /tests/qemu/qemu-speed-test - /tests/regressions/rhbz501893 -diff --git a/docs/guestfs-performance.pod b/docs/guestfs-performance.pod -index 4ba6faf..cf30fdc 100644 ---- a/docs/guestfs-performance.pod -+++ b/docs/guestfs-performance.pod -@@ -29,11 +29,20 @@ appliance: - Run this command several times in a row and discard the first few - runs, so that you are measuring a typical "hot cache" case. - -+I If you are compiling libguestfs from -+source, there is a program called F which -+does the same thing, but performs multiple runs and prints the mean -+and standard deviation. To run it, do: -+ -+ make -+ make -C tests/qemu boot-benchmark -+ ./run ./tests/qemu/boot-benchmark -+ - =head3 Explanation - --This command starts up the libguestfs appliance on a null disk, and --then immediately shuts it down. The first time you run the command, --it will create an appliance and cache it (usually under -+The guestfish command above starts up the libguestfs appliance on a -+null disk, and then immediately shuts it down. The first time you run -+the command, it will create an appliance and cache it (usually under - F). Subsequent runs should reuse the cached - appliance. - -diff --git a/tests/qemu/Makefile.am b/tests/qemu/Makefile.am -index bea1c85..cc5cb6a 100644 ---- a/tests/qemu/Makefile.am -+++ b/tests/qemu/Makefile.am -@@ -1,5 +1,5 @@ - # libguestfs --# Copyright (C) 2011 Red Hat Inc. -+# Copyright (C) 2011-2016 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 -@@ -33,10 +33,11 @@ EXTRA_DIST = \ - qemu-boot.c \ - qemu-speed-test.c - --# qemu-boot, qemu-speed-test and boot-analysis are built but not run --# by default as they are mainly qemu & kernel diagnostic tools. -+# qemu-boot, qemu-speed-test, boot-analysis and boot-benchmark are -+# built but not run by default as they are mainly qemu & kernel -+# diagnostic tools. - --check_PROGRAMS = qemu-boot qemu-speed-test boot-analysis -+check_PROGRAMS = qemu-boot qemu-speed-test boot-analysis boot-benchmark - - qemu_boot_SOURCES = \ - ../../df/estimate-max-threads.c \ -@@ -76,7 +77,9 @@ qemu_speed_test_LDADD = \ - boot_analysis_SOURCES = \ - boot-analysis.c \ - boot-analysis.h \ -- boot-analysis-timeline.c -+ boot-analysis-timeline.c \ -+ boot-analysis-utils.c \ -+ boot-analysis-utils.h - boot_analysis_CPPFLAGS = \ - -I$(top_srcdir)/gnulib/lib -I$(top_builddir)/gnulib/lib \ - -I$(top_srcdir)/src -I$(top_builddir)/src -@@ -93,6 +96,23 @@ boot_analysis_LDADD = \ - $(top_builddir)/gnulib/lib/libgnu.la \ - -lm - -+boot_benchmark_SOURCES = \ -+ boot-benchmark.c \ -+ boot-analysis-utils.c \ -+ boot-analysis-utils.h -+boot_benchmark_CPPFLAGS = \ -+ -I$(top_srcdir)/gnulib/lib -I$(top_builddir)/gnulib/lib \ -+ -I$(top_srcdir)/src -I$(top_builddir)/src -+boot_benchmark_CFLAGS = \ -+ $(WARN_CFLAGS) $(WERROR_CFLAGS) -+boot_benchmark_LDADD = \ -+ $(top_builddir)/src/libutils.la \ -+ $(top_builddir)/src/libguestfs.la \ -+ $(LIBXML2_LIBS) \ -+ $(LTLIBINTL) \ -+ $(top_builddir)/gnulib/lib/libgnu.la \ -+ -lm -+ - # Don't run these tests in parallel, since they are designed to check - # the integrity of qemu. - .NOTPARALLEL: -diff --git a/tests/qemu/boot-analysis-utils.c b/tests/qemu/boot-analysis-utils.c -new file mode 100644 -index 0000000..e885f3b ---- /dev/null -+++ b/tests/qemu/boot-analysis-utils.c -@@ -0,0 +1,47 @@ -+/* libguestfs -+ * Copyright (C) 2016 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 -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include "guestfs.h" -+#include "guestfs-internal-frontend.h" -+ -+#include "boot-analysis-utils.h" -+ -+void -+get_time (struct timespec *ts) -+{ -+ if (clock_gettime (CLOCK_REALTIME, ts) == -1) -+ error (EXIT_FAILURE, errno, "clock_gettime: CLOCK_REALTIME"); -+} -+ -+int64_t -+timespec_diff (const struct timespec *x, const struct timespec *y) -+{ -+ int64_t nsec; -+ -+ nsec = (y->tv_sec - x->tv_sec) * UINT64_C(1000000000); -+ nsec += y->tv_nsec - x->tv_nsec; -+ return nsec; -+} -diff --git a/tests/qemu/boot-analysis-utils.h b/tests/qemu/boot-analysis-utils.h -new file mode 100644 -index 0000000..83fc494 ---- /dev/null -+++ b/tests/qemu/boot-analysis-utils.h -@@ -0,0 +1,30 @@ -+/* libguestfs -+ * Copyright (C) 2016 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. -+ */ -+ -+#ifndef GUESTFS_BOOT_ANALYSIS_UTILS_H_ -+#define GUESTFS_BOOT_ANALYSIS_UTILS_H_ -+ -+/* Get current time, returning it in *ts. If there is a system call -+ * failure, this exits. -+ */ -+extern void get_time (struct timespec *ts); -+ -+/* Computes Y - X, returning nanoseconds. */ -+extern int64_t timespec_diff (const struct timespec *x, const struct timespec *y); -+ -+#endif /* GUESTFS_BOOT_ANALYSIS_UTILS_H_ */ -diff --git a/tests/qemu/boot-analysis.c b/tests/qemu/boot-analysis.c -index fc2c93b..022eaab 100644 ---- a/tests/qemu/boot-analysis.c -+++ b/tests/qemu/boot-analysis.c -@@ -79,6 +79,7 @@ - #include "guestfs-internal-frontend.h" - - #include "boot-analysis.h" -+#include "boot-analysis-utils.h" - - /* Activities taking longer than this % of the total time, except - * those flagged as LONG_ACTIVITY, are highlighted in red. -@@ -96,8 +97,6 @@ static int smp = 1; - static int verbose = 0; - - static void run_test (void); --static void get_time (struct timespec *ts); --static int64_t timespec_diff (const struct timespec *x, const struct timespec *y); - static struct event *add_event (struct pass_data *, uint64_t source); - static guestfs_h *create_handle (void); - static void set_up_event_handlers (guestfs_h *g, size_t pass); -@@ -267,24 +266,6 @@ run_test (void) - free_final_timeline (); - } - --static void --get_time (struct timespec *ts) --{ -- if (clock_gettime (CLOCK_REALTIME, ts) == -1) -- error (EXIT_FAILURE, errno, "clock_gettime: CLOCK_REALTIME"); --} -- --/* Computes Y - X, returning nanoseconds. */ --static int64_t --timespec_diff (const struct timespec *x, const struct timespec *y) --{ -- int64_t nsec; -- -- nsec = (y->tv_sec - x->tv_sec) * UINT64_C(1000000000); -- nsec += y->tv_nsec - x->tv_nsec; -- return nsec; --} -- - static struct event * - add_event (struct pass_data *data, uint64_t source) - { -diff --git a/tests/qemu/boot-benchmark.c b/tests/qemu/boot-benchmark.c -new file mode 100644 -index 0000000..2a6a038 ---- /dev/null -+++ b/tests/qemu/boot-benchmark.c -@@ -0,0 +1,230 @@ -+/* libguestfs -+ * Copyright (C) 2016 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. -+ */ -+ -+/* Benchmark the time taken to boot the libguestfs appliance. */ -+ -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "guestfs.h" -+#include "guestfs-internal-frontend.h" -+ -+#include "boot-analysis-utils.h" -+ -+#define NR_WARMUP_PASSES 3 -+#define NR_TEST_PASSES 10 -+ -+static const char *append = NULL; -+static int memsize = 0; -+static int smp = 1; -+ -+static void run_test (void); -+static guestfs_h *create_handle (void); -+static void add_drive (guestfs_h *g); -+ -+static void -+usage (int exitcode) -+{ -+ guestfs_h *g; -+ int default_memsize = -1; -+ -+ g = guestfs_create (); -+ if (g) { -+ default_memsize = guestfs_get_memsize (g); -+ guestfs_close (g); -+ } -+ -+ fprintf (stderr, -+ "boot-benchmark: Benchmark the time taken to boot the libguestfs appliance.\n" -+ "Usage:\n" -+ " boot-benchmark [--options]\n" -+ "Options:\n" -+ " --help Display this usage text and exit.\n" -+ " --append OPTS Append OPTS to kernel command line.\n" -+ " -m MB\n" -+ " --memsize MB Set memory size in MB (default: %d).\n" -+ " --smp N Enable N virtual CPUs (default: 1).\n", -+ default_memsize); -+ exit (exitcode); -+} -+ -+int -+main (int argc, char *argv[]) -+{ -+ enum { HELP_OPTION = CHAR_MAX + 1 }; -+ static const char *options = "m:"; -+ static const struct option long_options[] = { -+ { "help", 0, 0, HELP_OPTION }, -+ { "append", 1, 0, 0 }, -+ { "memsize", 1, 0, 'm' }, -+ { "smp", 1, 0, 0 }, -+ { 0, 0, 0, 0 } -+ }; -+ int c, option_index; -+ -+ for (;;) { -+ c = getopt_long (argc, argv, options, long_options, &option_index); -+ if (c == -1) break; -+ -+ switch (c) { -+ case 0: /* Options which are long only. */ -+ if (STREQ (long_options[option_index].name, "append")) { -+ append = optarg; -+ break; -+ } -+ else if (STREQ (long_options[option_index].name, "smp")) { -+ if (sscanf (optarg, "%d", &smp) != 1) { -+ fprintf (stderr, "%s: could not parse smp parameter: %s\n", -+ guestfs_int_program_name, optarg); -+ exit (EXIT_FAILURE); -+ } -+ break; -+ } -+ fprintf (stderr, "%s: unknown long option: %s (%d)\n", -+ guestfs_int_program_name, long_options[option_index].name, option_index); -+ exit (EXIT_FAILURE); -+ -+ case 'm': -+ if (sscanf (optarg, "%d", &memsize) != 1) { -+ fprintf (stderr, "%s: could not parse memsize parameter: %s\n", -+ guestfs_int_program_name, optarg); -+ exit (EXIT_FAILURE); -+ } -+ break; -+ -+ case HELP_OPTION: -+ usage (EXIT_SUCCESS); -+ -+ default: -+ usage (EXIT_FAILURE); -+ } -+ } -+ -+ run_test (); -+} -+ -+static void -+run_test (void) -+{ -+ guestfs_h *g; -+ size_t i; -+ int64_t ns[NR_TEST_PASSES]; -+ double mean; -+ double variance; -+ double sd; -+ -+ printf ("Warming up the libguestfs cache ...\n"); -+ for (i = 0; i < NR_WARMUP_PASSES; ++i) { -+ g = create_handle (); -+ add_drive (g); -+ if (guestfs_launch (g) == -1) -+ exit (EXIT_FAILURE); -+ guestfs_close (g); -+ } -+ -+ printf ("Running the tests ...\n"); -+ for (i = 0; i < NR_TEST_PASSES; ++i) { -+ struct timespec start_t, end_t; -+ -+ g = create_handle (); -+ add_drive (g); -+ get_time (&start_t); -+ if (guestfs_launch (g) == -1) -+ exit (EXIT_FAILURE); -+ guestfs_close (g); -+ get_time (&end_t); -+ -+ ns[i] = timespec_diff (&start_t, &end_t); -+ } -+ -+ /* Calculate the mean. */ -+ mean = 0; -+ for (i = 0; i < NR_TEST_PASSES; ++i) -+ mean += ns[i]; -+ mean /= NR_TEST_PASSES; -+ -+ /* Calculate the variance and standard deviation. */ -+ variance = 0; -+ for (i = 0; i < NR_TEST_PASSES; ++i) -+ variance = pow (ns[i] - mean, 2); -+ variance /= NR_TEST_PASSES; -+ sd = sqrt (variance); -+ -+ /* Print the test parameters. */ -+ printf ("\n"); -+ printf (" passes %d\n", NR_TEST_PASSES); -+ g = create_handle (); -+ printf (" append %s\n", guestfs_get_append (g) ? : ""); -+ printf ("backend %s\n", guestfs_get_backend (g)); -+ printf (" hv %s\n", guestfs_get_hv (g)); -+ printf ("memsize %d\n", guestfs_get_memsize (g)); -+ printf (" smp %d\n", guestfs_get_smp (g)); -+ guestfs_close (g); -+ -+ /* Print the result. */ -+ printf ("\n"); -+ printf ("Result: %.1fms ±%.1fms\n", mean / 1000000, sd / 1000000); -+} -+ -+/* Common function to create the handle and set various defaults. */ -+static guestfs_h * -+create_handle (void) -+{ -+ guestfs_h *g; -+ CLEANUP_FREE char *full_append = NULL; -+ -+ g = guestfs_create (); -+ if (!g) error (EXIT_FAILURE, errno, "guestfs_create"); -+ -+ if (memsize != 0) -+ if (guestfs_set_memsize (g, memsize) == -1) -+ exit (EXIT_FAILURE); -+ -+ if (smp >= 2) -+ if (guestfs_set_smp (g, smp) == -1) -+ exit (EXIT_FAILURE); -+ -+ if (append != NULL) -+ if (guestfs_set_append (g, full_append) == -1) -+ exit (EXIT_FAILURE); -+ -+ return g; -+} -+ -+/* Common function to add the /dev/null drive. */ -+static void -+add_drive (guestfs_h *g) -+{ -+ if (guestfs_add_drive_opts (g, "/dev/null", -+ GUESTFS_ADD_DRIVE_OPTS_FORMAT, "raw", -+ GUESTFS_ADD_DRIVE_OPTS_READONLY, 1, -+ -1) == -1) -+ exit (EXIT_FAILURE); -+} --- -1.8.3.1 - diff --git a/SOURCES/0053-tests-qemu-boot-analysis-Display-all-times-in-ms.patch b/SOURCES/0053-tests-qemu-boot-analysis-Display-all-times-in-ms.patch deleted file mode 100644 index 34911fc..0000000 --- a/SOURCES/0053-tests-qemu-boot-analysis-Display-all-times-in-ms.patch +++ /dev/null @@ -1,50 +0,0 @@ -From 2e75e1584b4ad34df3999f9e0b270a0fdc246c67 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Sat, 2 Apr 2016 10:42:12 +0100 -Subject: [PATCH] tests/qemu: boot-analysis: Display all times in ms. - -It was confusing to have a mix of seconds and milliseconds. For all -upstream testing (eg. with SeaBIOS) we are discussing everything in -milliseconds, so use those exclusively. - -(cherry picked from commit d470480b3564b45301a79047f919051b4e2e58b4) ---- - tests/qemu/boot-analysis.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - -diff --git a/tests/qemu/boot-analysis.c b/tests/qemu/boot-analysis.c -index 022eaab..9ab228a 100644 ---- a/tests/qemu/boot-analysis.c -+++ b/tests/qemu/boot-analysis.c -@@ -860,8 +860,8 @@ print_activity (struct activity *activity) - if (activity->warning) ansi_red (); else ansi_green (); - print_escaped_string (activity->name); - ansi_restore (); -- printf (" %1.6fs ±%.1fms ", -- activity->mean / 1000000000, activity->sd / 1000000); -+ printf (" %.1fms ±%.1fms ", -+ activity->mean / 1000000, activity->sd / 1000000); - if (activity->warning) ansi_red (); else ansi_green (); - printf ("(%.1f%%) ", activity->percent); - ansi_restore (); -@@ -906,7 +906,7 @@ print_analysis (void) - - /* Draw a spacer line, but only if last_t -> t is a large jump. */ - if (t - last_t >= 1000000 /* ns */) { -- printf (" "); -+ printf (" "); - ansi_magenta (); - for (j = 0; j < last_free_column; ++j) { - if (columns[j] >= 0 && -@@ -946,7 +946,7 @@ print_analysis (void) - - /* Draw the line. */ - ansi_blue (); -- printf ("%1.6fs: ", t / 1000000000); -+ printf ("%6.1fms: ", t / 1000000); - - ansi_magenta (); - for (j = 0; j < last_free_column; ++j) { --- -1.8.3.1 - diff --git a/SOURCES/0054-tests-qemu-Standardize-test-info-printed-by-boot-tes.patch b/SOURCES/0054-tests-qemu-Standardize-test-info-printed-by-boot-tes.patch deleted file mode 100644 index 1455472..0000000 --- a/SOURCES/0054-tests-qemu-Standardize-test-info-printed-by-boot-tes.patch +++ /dev/null @@ -1,185 +0,0 @@ -From 900151dff1bbea9d37848143989583bf91c5d344 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Sat, 2 Apr 2016 11:01:30 +0100 -Subject: [PATCH] tests/qemu: Standardize test info printed by boot-* tests. - -It now looks like: - -test version: libguestfs 1.33.16 - test passes: 5 -host version: Linux moo 4.4.4-301.fc23.x86_64 #1 SMP Fri Mar 4 17:42:42 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux - host CPU: Intel(R) Core(TM) i7-5600U CPU @ 2.60GHz - backend: direct - qemu: /home/rjones/d/qemu/x86_64-softmmu/qemu-system-x86_64 -qemu version: QEMU emulator version 2.5.90, Copyright (c) 2003-2008 Fabrice Bellard - smp: 1 - memsize: 500 - append: guestfs_boot_analysis=1 ignore_loglevel initcall_debug - -(cherry picked from commit 014b7c0ced2dc57ca2dda0c43873359497f8672b) ---- - tests/qemu/boot-analysis-utils.c | 37 +++++++++++++++++++++++++++++++++++++ - tests/qemu/boot-analysis-utils.h | 6 ++++++ - tests/qemu/boot-analysis.c | 38 +++----------------------------------- - tests/qemu/boot-benchmark.c | 7 +------ - 4 files changed, 47 insertions(+), 41 deletions(-) - -diff --git a/tests/qemu/boot-analysis-utils.c b/tests/qemu/boot-analysis-utils.c -index e885f3b..bcd470e 100644 ---- a/tests/qemu/boot-analysis-utils.c -+++ b/tests/qemu/boot-analysis-utils.c -@@ -24,6 +24,8 @@ - #include - #include - -+#include "ignore-value.h" -+ - #include "guestfs.h" - #include "guestfs-internal-frontend.h" - -@@ -45,3 +47,38 @@ timespec_diff (const struct timespec *x, const struct timespec *y) - nsec += y->tv_nsec - x->tv_nsec; - return nsec; - } -+ -+void -+test_info (guestfs_h *g, int nr_test_passes) -+{ -+ const char *qemu = guestfs_get_hv (g); -+ CLEANUP_FREE char *cmd = NULL; -+ -+ /* Related to the test program. */ -+ printf ("test version: %s %s\n", PACKAGE_NAME, PACKAGE_VERSION_FULL); -+ printf (" test passes: %d\n", nr_test_passes); -+ -+ /* Related to the host. */ -+ printf ("host version: "); -+ fflush (stdout); -+ ignore_value (system ("uname -a")); -+ printf (" host CPU: "); -+ fflush (stdout); -+ ignore_value (system ("perl -n -e 'if (/^model name.*: (.*)/) { print \"$1\\n\"; exit }' /proc/cpuinfo")); -+ -+ /* Related to qemu. */ -+ printf (" backend: %s\n", guestfs_get_backend (g)); -+ printf (" qemu: %s\n", qemu); -+ printf ("qemu version: "); -+ fflush (stdout); -+ if (asprintf (&cmd, "%s -version", qemu) == -1) -+ error (EXIT_FAILURE, errno, "asprintf"); -+ ignore_value (system (cmd)); -+ printf (" smp: %d\n", guestfs_get_smp (g)); -+ printf (" memsize: %d\n", guestfs_get_memsize (g)); -+ -+ /* Related to the guest kernel. Be nice to get the guest -+ * kernel version here somehow (XXX). -+ */ -+ printf (" append: %s\n", guestfs_get_append (g) ? : ""); -+} -diff --git a/tests/qemu/boot-analysis-utils.h b/tests/qemu/boot-analysis-utils.h -index 83fc494..95e4f06 100644 ---- a/tests/qemu/boot-analysis-utils.h -+++ b/tests/qemu/boot-analysis-utils.h -@@ -27,4 +27,10 @@ extern void get_time (struct timespec *ts); - /* Computes Y - X, returning nanoseconds. */ - extern int64_t timespec_diff (const struct timespec *x, const struct timespec *y); - -+/* Display host machine and test parameters (to stdout). 'g' should -+ * be an open libguestfs handle. It is used for reading hv, memsize -+ * etc. and is not modified. -+ */ -+extern void test_info (guestfs_h *g, int nr_test_passes); -+ - #endif /* GUESTFS_BOOT_ANALYSIS_UTILS_H_ */ -diff --git a/tests/qemu/boot-analysis.c b/tests/qemu/boot-analysis.c -index 9ab228a..f4c1d6c 100644 ---- a/tests/qemu/boot-analysis.c -+++ b/tests/qemu/boot-analysis.c -@@ -73,8 +73,6 @@ - #include - #include - --#include "ignore-value.h" -- - #include "guestfs.h" - #include "guestfs-internal-frontend.h" - -@@ -105,7 +103,6 @@ static void check_pass_data (void); - static void dump_pass_data (void); - static void analyze_timeline (void); - static void dump_timeline (void); --static void print_info (void); - static void print_analysis (void); - static void print_longest_to_shortest (void); - static void free_pass_data (void); -@@ -254,7 +251,9 @@ run_test (void) - dump_timeline (); - - printf ("\n"); -- print_info (); -+ g = create_handle (); -+ test_info (g, NR_TEST_PASSES); -+ guestfs_close (g); - printf ("\n"); - print_analysis (); - printf ("\n"); -@@ -823,37 +822,6 @@ dump_timeline (void) - } - } - --/* Print some information that will allow us to determine the test -- * system when reviewing the results in future. -- */ --static void --print_info (void) --{ -- size_t i; -- -- printf ("%s %s\n", PACKAGE_NAME, PACKAGE_VERSION_FULL); -- -- printf ("Host:\n"); -- ignore_value (system ("uname -a")); -- ignore_value (system ("grep '^model name' /proc/cpuinfo | head -1")); -- -- /* We can dig some information about qemu and the appliance out of -- * the events. -- */ -- printf ("Appliance:\n"); -- assert (NR_TEST_PASSES > 0); -- for (i = 0; i < pass_data[0].nr_events; ++i) { -- const char *message = pass_data[0].events[i].message; -- if (strstr (message, "qemu version") || -- (strstr (message, "SeaBIOS") && strstr (message, "version")) || -- strstr (message, "Linux version") || -- (strstr (message, "supermin") && strstr (message, "starting up"))) { -- print_escaped_string (message); -- putchar ('\n'); -- } -- } --} -- - static void - print_activity (struct activity *activity) - { -diff --git a/tests/qemu/boot-benchmark.c b/tests/qemu/boot-benchmark.c -index 2a6a038..0508ee9 100644 ---- a/tests/qemu/boot-benchmark.c -+++ b/tests/qemu/boot-benchmark.c -@@ -179,13 +179,8 @@ run_test (void) - - /* Print the test parameters. */ - printf ("\n"); -- printf (" passes %d\n", NR_TEST_PASSES); - g = create_handle (); -- printf (" append %s\n", guestfs_get_append (g) ? : ""); -- printf ("backend %s\n", guestfs_get_backend (g)); -- printf (" hv %s\n", guestfs_get_hv (g)); -- printf ("memsize %d\n", guestfs_get_memsize (g)); -- printf (" smp %d\n", guestfs_get_smp (g)); -+ test_info (g, NR_TEST_PASSES); - guestfs_close (g); - - /* Print the result. */ --- -1.8.3.1 - diff --git a/SOURCES/0055-tests-qemu-boot-analysis-Don-t-force-backend-direct.patch b/SOURCES/0055-tests-qemu-boot-analysis-Don-t-force-backend-direct.patch deleted file mode 100644 index 27d3194..0000000 --- a/SOURCES/0055-tests-qemu-boot-analysis-Don-t-force-backend-direct.patch +++ /dev/null @@ -1,128 +0,0 @@ -From 180a681da1f2ffa7be27a854b60a5c556288f567 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Sat, 2 Apr 2016 11:03:33 +0100 -Subject: [PATCH] tests/qemu: boot-analysis: Don't force backend direct. - -Current libvirt overhead is 220ms. That didn't matter when our launch -time was 4000ms. Now we're launching in 900ms, it really does. - -(cherry picked from commit 03b68d436c61e9e0baac7c4fb305b62f41185173) ---- - tests/qemu/boot-analysis-timeline.c | 65 ++++++++++++++++++++++++++++--------- - tests/qemu/boot-analysis.c | 11 ++----- - 2 files changed, 51 insertions(+), 25 deletions(-) - -diff --git a/tests/qemu/boot-analysis-timeline.c b/tests/qemu/boot-analysis-timeline.c -index 8753805..d35fb49 100644 ---- a/tests/qemu/boot-analysis-timeline.c -+++ b/tests/qemu/boot-analysis-timeline.c -@@ -176,28 +176,61 @@ construct_timeline (void) - "finished building supermin appliance")); - - /* Find where we invoke qemu to test features. */ -- FIND ("qemu:feature-detect", 0, -- data->events[j].source == GUESTFS_EVENT_LIBRARY && -- strstr (data->events[j].message, -- "begin testing qemu features"), -- data->events[k].source == GUESTFS_EVENT_LIBRARY && -- strstr (data->events[k].message, -- "finished testing qemu features")); -+ FIND_OPTIONAL ("qemu:feature-detect", 0, -+ data->events[j].source == GUESTFS_EVENT_LIBRARY && -+ strstr (data->events[j].message, -+ "begin testing qemu features"), -+ data->events[k].source == GUESTFS_EVENT_LIBRARY && -+ strstr (data->events[k].message, -+ "finished testing qemu features")); - - /* Find where we run qemu. */ -- FIND ("qemu", LONG_ACTIVITY, -- data->events[j].source == GUESTFS_EVENT_APPLIANCE && -- strstr (data->events[j].message, "-nodefconfig"), -- data->events[k].source == GUESTFS_EVENT_CLOSE); -+ FIND_OPTIONAL ("qemu", LONG_ACTIVITY, -+ data->events[j].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[j].message, "-nodefconfig"), -+ data->events[k].source == GUESTFS_EVENT_CLOSE); -+ -+ /* For the libvirt backend, connecting to libvirt, getting -+ * capabilities, parsing capabilities etc. -+ */ -+ FIND_OPTIONAL ("libvirt:connect", 0, -+ data->events[j].source == GUESTFS_EVENT_LIBRARY && -+ strstr (data->events[j].message, "connect to libvirt"), -+ data->events[k].source == GUESTFS_EVENT_LIBRARY && -+ strstr (data->events[k].message, "successfully opened libvirt handle")); -+ FIND_OPTIONAL ("libvirt:get-libvirt-capabilities", 0, -+ data->events[j].source == GUESTFS_EVENT_LIBRARY && -+ strstr (data->events[j].message, "get libvirt capabilities"), -+ data->events[k].source == GUESTFS_EVENT_LIBRARY && -+ strstr (data->events[k].message, "parsing capabilities XML")); -+ -+ FIND_OPTIONAL ("libguestfs:parse-libvirt-capabilities", 0, -+ data->events[j].source == GUESTFS_EVENT_LIBRARY && -+ strstr (data->events[j].message, "parsing capabilities XML"), -+ data->events[k].source == GUESTFS_EVENT_LIBRARY && -+ strstr (data->events[k].message, "get_backend_setting")); -+ -+ FIND_OPTIONAL ("libguestfs:create-libvirt-xml", 0, -+ data->events[j].source == GUESTFS_EVENT_LIBRARY && -+ strstr (data->events[j].message, "create libvirt XML"), -+ data->events[k].source == GUESTFS_EVENT_LIBRARY && -+ strstr (data->events[k].message, "libvirt XML:")); - - #define SGABIOS_STRING "\033[1;256r\033[256;256H\033[6n" - -+ /* For the libvirt backend, find the overhead of libvirt. */ -+ FIND_OPTIONAL ("libvirt:overhead", 0, -+ data->events[j].source == GUESTFS_EVENT_LIBRARY && -+ strstr (data->events[j].message, "launch libvirt guest"), -+ data->events[k].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[k].message, SGABIOS_STRING)); -+ - /* From starting qemu up to entering the BIOS is the qemu overhead. */ -- FIND ("qemu:overhead", 0, -- data->events[j].source == GUESTFS_EVENT_APPLIANCE && -- strstr (data->events[j].message, "-nodefconfig"), -- data->events[k].source == GUESTFS_EVENT_APPLIANCE && -- strstr (data->events[k].message, SGABIOS_STRING)); -+ FIND_OPTIONAL ("qemu:overhead", 0, -+ data->events[j].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[j].message, "-nodefconfig"), -+ data->events[k].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[k].message, SGABIOS_STRING)); - - /* From entering the BIOS to starting the kernel is the BIOS overhead. */ - FIND_OPTIONAL ("bios:overhead", 0, -diff --git a/tests/qemu/boot-analysis.c b/tests/qemu/boot-analysis.c -index f4c1d6c..37d8b3c 100644 ---- a/tests/qemu/boot-analysis.c -+++ b/tests/qemu/boot-analysis.c -@@ -292,14 +292,6 @@ create_handle (void) - g = guestfs_create (); - if (!g) error (EXIT_FAILURE, errno, "guestfs_create"); - -- /* We always run these tests using LIBGUESTFS_BACKEND=direct. It -- * may be in future we need to test libvirt as well, in case -- * performance issues are suspected there, but so far libvirt has -- * not been a bottleneck. -- */ -- if (guestfs_set_backend (g, "direct") == -1) -- exit (EXIT_FAILURE); -- - if (memsize != 0) - if (guestfs_set_memsize (g, memsize) == -1) - exit (EXIT_FAILURE); -@@ -622,7 +614,8 @@ check_pass_data (void) - assert (pass_data[i].events[j].source != 0); - message = pass_data[i].events[j].message; - assert (message != NULL); -- assert (strchr (message, '\n') == NULL); -+ assert (pass_data[i].events[j].source != GUESTFS_EVENT_APPLIANCE || -+ strchr (message, '\n') == NULL); - len = strlen (message); - assert (len == 0 || message[len-1] != '\r'); - } --- -1.8.3.1 - diff --git a/SOURCES/0056-launch-libvirt-Disable-virtio-rng-in-libvirt-backend.patch b/SOURCES/0056-launch-libvirt-Disable-virtio-rng-in-libvirt-backend.patch deleted file mode 100644 index 468de1e..0000000 --- a/SOURCES/0056-launch-libvirt-Disable-virtio-rng-in-libvirt-backend.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 19b262aeeb71b690099d5169eaea5d817674fdbe Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Tue, 5 Apr 2016 15:02:20 +0100 -Subject: [PATCH] launch: libvirt: Disable virtio-rng in libvirt backend until - we can use /dev/urandom. - -This updates commit 9423c16607259b30985c46d04db9958ec079aa42. - -(cherry picked from commit b2c845333f66d4d3135d3b6a8d4b992d6160bf0a) ---- - src/launch-libvirt.c | 7 +++++++ - 1 file changed, 7 insertions(+) - -diff --git a/src/launch-libvirt.c b/src/launch-libvirt.c -index f9edac0..96c5913 100644 ---- a/src/launch-libvirt.c -+++ b/src/launch-libvirt.c -@@ -1306,6 +1306,12 @@ construct_libvirt_xml_devices (guestfs_h *g, - } - #endif - -+#if 0 -+ /* This is disabled. Pulling random numbers from /dev/random -+ * causes the appliance to pause for long periods. We should -+ * use /dev/urandom, but for bogus reasons libvirt prevents that. -+ * https://bugzilla.redhat.com/show_bug.cgi?id=1074464#c7 -+ */ - /* Add a random number generator (backend for virtio-rng). */ - start_element ("rng") { - attribute ("model", "virtio"); -@@ -1319,6 +1325,7 @@ construct_libvirt_xml_devices (guestfs_h *g, - //string ("/dev/urandom"); - } end_element (); - } end_element (); -+#endif - - /* virtio-scsi controller. */ - start_element ("controller") { --- -1.8.3.1 - diff --git a/SOURCES/0057-tests-qemu-Don-t-leak-backend-variable-in-boot-analy.patch b/SOURCES/0057-tests-qemu-Don-t-leak-backend-variable-in-boot-analy.patch deleted file mode 100644 index 134a40d..0000000 --- a/SOURCES/0057-tests-qemu-Don-t-leak-backend-variable-in-boot-analy.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 7f277fb1bbb480fdd616d0ac785a6e08b764b644 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Wed, 6 Apr 2016 10:42:21 +0100 -Subject: [PATCH] tests/qemu: Don't leak backend variable in - boot-analysis/boot-benchmark programs. - -(cherry picked from commit 0008d794cf00b07842bc5403b53684e2bad5053a) ---- - tests/qemu/boot-analysis-utils.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/tests/qemu/boot-analysis-utils.c b/tests/qemu/boot-analysis-utils.c -index bcd470e..4ed2d48 100644 ---- a/tests/qemu/boot-analysis-utils.c -+++ b/tests/qemu/boot-analysis-utils.c -@@ -53,6 +53,7 @@ test_info (guestfs_h *g, int nr_test_passes) - { - const char *qemu = guestfs_get_hv (g); - CLEANUP_FREE char *cmd = NULL; -+ CLEANUP_FREE char *backend = NULL; - - /* Related to the test program. */ - printf ("test version: %s %s\n", PACKAGE_NAME, PACKAGE_VERSION_FULL); -@@ -67,7 +68,8 @@ test_info (guestfs_h *g, int nr_test_passes) - ignore_value (system ("perl -n -e 'if (/^model name.*: (.*)/) { print \"$1\\n\"; exit }' /proc/cpuinfo")); - - /* Related to qemu. */ -- printf (" backend: %s\n", guestfs_get_backend (g)); -+ backend = guestfs_get_backend (g); -+ printf (" backend: %s\n", backend); - printf (" qemu: %s\n", qemu); - printf ("qemu version: "); - fflush (stdout); --- -1.8.3.1 - diff --git a/SOURCES/0058-tests-qemu-boot-analysis-Add-support-for-logging-lib.patch b/SOURCES/0058-tests-qemu-boot-analysis-Add-support-for-logging-lib.patch deleted file mode 100644 index 555225c..0000000 --- a/SOURCES/0058-tests-qemu-boot-analysis-Add-support-for-logging-lib.patch +++ /dev/null @@ -1,353 +0,0 @@ -From f009e084782ac692ce1a519b5255e9abf4a79632 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Wed, 6 Apr 2016 10:43:00 +0100 -Subject: [PATCH] tests/qemu: boot-analysis: Add support for logging libvirt - events. - -(cherry picked from commit b332d91bc9685e8992ede2c8a10655f26fd0395e) ---- - tests/qemu/Makefile.am | 1 + - tests/qemu/boot-analysis.c | 236 +++++++++++++++++++++++++++++++++++++++++++-- - 2 files changed, 227 insertions(+), 10 deletions(-) - -diff --git a/tests/qemu/Makefile.am b/tests/qemu/Makefile.am -index cc5cb6a..fdf643f 100644 ---- a/tests/qemu/Makefile.am -+++ b/tests/qemu/Makefile.am -@@ -84,6 +84,7 @@ boot_analysis_CPPFLAGS = \ - -I$(top_srcdir)/gnulib/lib -I$(top_builddir)/gnulib/lib \ - -I$(top_srcdir)/src -I$(top_builddir)/src - boot_analysis_CFLAGS = \ -+ -pthread \ - $(WARN_CFLAGS) $(WERROR_CFLAGS) \ - $(PCRE_CFLAGS) - boot_analysis_LDADD = \ -diff --git a/tests/qemu/boot-analysis.c b/tests/qemu/boot-analysis.c -index 37d8b3c..2a43976 100644 ---- a/tests/qemu/boot-analysis.c -+++ b/tests/qemu/boot-analysis.c -@@ -64,6 +64,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -71,7 +72,10 @@ - #include - #include - #include -+#include -+#include - #include -+#include - - #include "guestfs.h" - #include "guestfs-internal-frontend.h" -@@ -84,20 +88,32 @@ - */ - #define WARNING_THRESHOLD 1.0 - --struct pass_data pass_data[NR_TEST_PASSES]; --size_t nr_activities; --struct activity *activities; -- - static const char *append = NULL; - static int force_colour = 0; - static int memsize = 0; - static int smp = 1; - static int verbose = 0; - -+static int libvirt_pipe[2] = { -1, -1 }; -+static ssize_t libvirt_pass = -1; -+ -+/* Because there is a separate thread which collects libvirt log data, -+ * we must protect the pass_data struct with a mutex. This only -+ * applies during the data collection passes. -+ */ -+static pthread_mutex_t pass_data_lock = PTHREAD_MUTEX_INITIALIZER; -+struct pass_data pass_data[NR_TEST_PASSES]; -+ -+size_t nr_activities; -+struct activity *activities; -+ - static void run_test (void); - static struct event *add_event (struct pass_data *, uint64_t source); - static guestfs_h *create_handle (void); - static void set_up_event_handlers (guestfs_h *g, size_t pass); -+static void libvirt_log_hack (int argc, char **argv); -+static void start_libvirt_thread (size_t pass); -+static void stop_libvirt_thread (void); - static void add_drive (guestfs_h *g); - static void check_pass_data (void); - static void dump_pass_data (void); -@@ -152,6 +168,8 @@ main (int argc, char *argv[]) - { "color", 0, 0, 0 }, - { "colour", 0, 0, 0 }, - { "memsize", 1, 0, 'm' }, -+ { "libvirt-pipe-0", 1, 0, 0 }, /* see libvirt_log_hack */ -+ { "libvirt-pipe-1", 1, 0, 0 }, - { "smp", 1, 0, 0 }, - { "verbose", 0, 0, 'v' }, - { 0, 0, 0, 0 } -@@ -173,12 +191,22 @@ main (int argc, char *argv[]) - force_colour = 1; - break; - } -+ else if (STREQ (long_options[option_index].name, "libvirt-pipe-0")) { -+ if (sscanf (optarg, "%d", &libvirt_pipe[0]) != 1) -+ error (EXIT_FAILURE, 0, -+ "could not parse libvirt-pipe-0 parameter: %s", optarg); -+ break; -+ } -+ else if (STREQ (long_options[option_index].name, "libvirt-pipe-1")) { -+ if (sscanf (optarg, "%d", &libvirt_pipe[1]) != 1) -+ error (EXIT_FAILURE, 0, -+ "could not parse libvirt-pipe-1 parameter: %s", optarg); -+ break; -+ } - else if (STREQ (long_options[option_index].name, "smp")) { -- if (sscanf (optarg, "%d", &smp) != 1) { -- fprintf (stderr, "%s: could not parse smp parameter: %s\n", -- guestfs_int_program_name, optarg); -- exit (EXIT_FAILURE); -- } -+ if (sscanf (optarg, "%d", &smp) != 1) -+ error (EXIT_FAILURE, 0, -+ "could not parse smp parameter: %s", optarg); - break; - } - fprintf (stderr, "%s: unknown long option: %s (%d)\n", -@@ -205,6 +233,8 @@ main (int argc, char *argv[]) - } - } - -+ libvirt_log_hack (argc, argv); -+ - if (STRNEQ (host_cpu, "x86_64")) - fprintf (stderr, "WARNING: host_cpu != x86_64: This program may not work or give bogus results.\n"); - -@@ -230,10 +260,12 @@ run_test (void) - for (i = 0; i < NR_TEST_PASSES; ++i) { - g = create_handle (); - set_up_event_handlers (g, i); -+ start_libvirt_thread (i); - add_drive (g); - if (guestfs_launch (g) == -1) - exit (EXIT_FAILURE); - guestfs_close (g); -+ stop_libvirt_thread (); - - printf (" pass %zu: %zu events collected in %" PRIi64 " ns\n", - i+1, pass_data[i].nr_events, pass_data[i].elapsed_ns); -@@ -266,7 +298,7 @@ run_test (void) - } - - static struct event * --add_event (struct pass_data *data, uint64_t source) -+add_event_unlocked (struct pass_data *data, uint64_t source) - { - struct event *ret; - -@@ -282,6 +314,17 @@ add_event (struct pass_data *data, uint64_t source) - return ret; - } - -+static struct event * -+add_event (struct pass_data *data, uint64_t source) -+{ -+ struct event *ret; -+ -+ pthread_mutex_lock (&pass_data_lock); -+ ret = add_event_unlocked (data, source); -+ pthread_mutex_unlock (&pass_data_lock); -+ return ret; -+} -+ - /* Common function to create the handle and set various defaults. */ - static guestfs_h * - create_handle (void) -@@ -590,6 +633,179 @@ set_up_event_handlers (guestfs_h *g, size_t pass) - guestfs_set_trace (g, 1); - } - -+/* libvirt debugging sucks in a number of concrete ways: -+ * -+ * - you can't get a synchronous callback from a log message -+ * - you can't enable logging per handle (only globally -+ * by setting environment variables) -+ * - you can't debug the daemon easily -+ * - it's very complex -+ * - it's very complex but not in ways that are practical or useful -+ * -+ * To get log messages at all, we need to create a pipe connected to a -+ * second thread, and when libvirt prints something to the pipe we log -+ * that. -+ * -+ * However that's not sufficient. Because logging is only enabled -+ * when libvirt examines environment variables at the start of the -+ * program, we need to create the pipe and then fork+exec a new -+ * instance of the whole program with the pipe and environment -+ * variables set up. -+ */ -+static int is_libvirt_backend (guestfs_h *g); -+static void *libvirt_log_thread (void *datavp); -+ -+static void -+libvirt_log_hack (int argc, char **argv) -+{ -+ guestfs_h *g; -+ -+ g = guestfs_create (); -+ if (!is_libvirt_backend (g)) { -+ guestfs_close (g); -+ return; -+ } -+ guestfs_close (g); -+ -+ /* Have we set up the pipes and environment and forked yet? If not, -+ * do that first. -+ */ -+ if (libvirt_pipe[0] == -1 || libvirt_pipe[1] == -1) { -+ char log_outputs[64]; -+ char **new_argv; -+ char param1[64], param2[64]; -+ size_t i; -+ pid_t pid; -+ int status; -+ -+ /* Create the pipe. NB: do NOT use O_CLOEXEC since we want to pass -+ * this pipe into a child process. -+ */ -+ if (pipe (libvirt_pipe) == -1) -+ error (EXIT_FAILURE, 0, "pipe2"); -+ -+ /* Create the environment variables to enable logging in libvirt. */ -+ setenv ("LIBVIRT_DEBUG", "1", 1); -+ snprintf (log_outputs, sizeof log_outputs, -+ "1:file:/dev/fd/%d", libvirt_pipe[1]); -+ setenv ("LIBVIRT_LOG_OUTPUTS", log_outputs, 1); -+ -+ /* Run self again. */ -+ new_argv = malloc ((argc+3) * sizeof (char *)); -+ if (new_argv == NULL) -+ error (EXIT_FAILURE, errno, "malloc"); -+ -+ for (i = 0; i < (size_t) argc; ++i) -+ new_argv[i] = argv[i]; -+ -+ snprintf (param1, sizeof param1, "--libvirt-pipe-0=%d", libvirt_pipe[0]); -+ new_argv[argc] = param1; -+ snprintf (param2, sizeof param2, "--libvirt-pipe-1=%d", libvirt_pipe[1]); -+ new_argv[argc+1] = param2; -+ new_argv[argc+2] = NULL; -+ -+ pid = fork (); -+ if (pid == -1) -+ error (EXIT_FAILURE, errno, "fork"); -+ if (pid == 0) { /* Child process. */ -+ execvp (argv[0], new_argv); -+ perror ("execvp"); -+ _exit (EXIT_FAILURE); -+ } -+ -+ if (waitpid (pid, &status, 0) == -1) -+ error (EXIT_FAILURE, errno, "waitpid"); -+ if (WIFEXITED (status)) -+ exit (WEXITSTATUS (status)); -+ error (EXIT_FAILURE, 0, "unexpected exit status from process: %d", status); -+ } -+ -+ /* If we reach this else clause, then we have forked. Now we must -+ * create a thread to read events from the pipe. This must be -+ * constantly reading from the pipe, otherwise we will deadlock. -+ * During the warm-up phase we end up throwing away messages. -+ */ -+ else { -+ pthread_t thread; -+ pthread_attr_t attr; -+ int r; -+ -+ r = pthread_attr_init (&attr); -+ if (r != 0) -+ error (EXIT_FAILURE, r, "pthread_attr_init"); -+ r = pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED); -+ if (r != 0) -+ error (EXIT_FAILURE, r, "pthread_attr_setdetachstate"); -+ r = pthread_create (&thread, &attr, libvirt_log_thread, NULL); -+ if (r != 0) -+ error (EXIT_FAILURE, r, "pthread_create"); -+ pthread_attr_destroy (&attr); -+ } -+} -+ -+static void -+start_libvirt_thread (size_t pass) -+{ -+ /* In the non-libvirt case, this variable is ignored. */ -+ pthread_mutex_lock (&pass_data_lock); -+ libvirt_pass = pass; -+ pthread_mutex_unlock (&pass_data_lock); -+} -+ -+static void -+stop_libvirt_thread (void) -+{ -+ /* In the non-libvirt case, this variable is ignored. */ -+ pthread_mutex_lock (&pass_data_lock); -+ libvirt_pass = -1; -+ pthread_mutex_unlock (&pass_data_lock); -+} -+ -+/* The separate "libvirt thread". It loops reading debug messages -+ * printed by libvirt and adds them to the pass_data. -+ */ -+static void * -+libvirt_log_thread (void *arg) -+{ -+ struct event *event; -+ CLEANUP_FREE char *buf = NULL; -+ ssize_t r; -+ -+ buf = malloc (BUFSIZ); -+ if (buf == NULL) -+ error (EXIT_FAILURE, errno, "malloc"); -+ -+ while ((r = read (libvirt_pipe[0], buf, BUFSIZ)) > 0) { -+ pthread_mutex_lock (&pass_data_lock); -+ if (libvirt_pass == -1) goto discard; -+ event = -+ add_event_unlocked (&pass_data[libvirt_pass], GUESTFS_EVENT_LIBRARY); -+ event->message = strndup (buf, r); -+ if (event->message == NULL) -+ error (EXIT_FAILURE, errno, "strndup"); -+ discard: -+ pthread_mutex_unlock (&pass_data_lock); -+ } -+ -+ if (r == -1) -+ error (EXIT_FAILURE, errno, "libvirt_log_thread: read"); -+ -+ /* It's possible for the pipe to be closed (r == 0) if thread -+ * cancellation is delayed after the main thread exits, so just -+ * ignore that case and exit. -+ */ -+ pthread_exit (NULL); -+} -+ -+static int -+is_libvirt_backend (guestfs_h *g) -+{ -+ CLEANUP_FREE char *backend = guestfs_get_backend (g); -+ -+ return backend && -+ (STREQ (backend, "libvirt") || STRPREFIX (backend, "libvirt:")); -+} -+ - /* Sanity check the collected events. */ - static void - check_pass_data (void) --- -1.8.3.1 - diff --git a/SOURCES/0059-tests-qemu-boot-analysis-Don-t-set-LIBVIRT_LOG_FILTE.patch b/SOURCES/0059-tests-qemu-boot-analysis-Don-t-set-LIBVIRT_LOG_FILTE.patch deleted file mode 100644 index e665855..0000000 --- a/SOURCES/0059-tests-qemu-boot-analysis-Don-t-set-LIBVIRT_LOG_FILTE.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 095179b51623522f35cc1a2f46dd01ddc5e8d685 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Wed, 6 Apr 2016 17:44:49 +0100 -Subject: [PATCH] tests/qemu: boot-analysis: (Don't) set LIBVIRT_LOG_FILTERS. - -Setting LIBVIRT_LOG_FILTERS is supposed to be better than setting -LIBVIRT_DEBUG, but I couldn't get it to work. - -This updates commit b332d91bc9685e8992ede2c8a10655f26fd0395e. - -(cherry picked from commit f24753ebb01ac96c092ee11aaa3f08df40d7ca00) ---- - tests/qemu/boot-analysis.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/tests/qemu/boot-analysis.c b/tests/qemu/boot-analysis.c -index 2a43976..444226c 100644 ---- a/tests/qemu/boot-analysis.c -+++ b/tests/qemu/boot-analysis.c -@@ -686,6 +686,8 @@ libvirt_log_hack (int argc, char **argv) - - /* Create the environment variables to enable logging in libvirt. */ - setenv ("LIBVIRT_DEBUG", "1", 1); -+ //setenv ("LIBVIRT_LOG_FILTERS", -+ // "1:qemu 1:securit 3:file 3:event 3:object 1:util", 1); - snprintf (log_outputs, sizeof log_outputs, - "1:file:/dev/fd/%d", libvirt_pipe[1]); - setenv ("LIBVIRT_LOG_OUTPUTS", log_outputs, 1); --- -1.8.3.1 - diff --git a/SOURCES/0060-p2v-Allow-p2v-kernel-options-to-override-GUI-configu.patch b/SOURCES/0060-p2v-Allow-p2v-kernel-options-to-override-GUI-configu.patch deleted file mode 100644 index e14721b..0000000 --- a/SOURCES/0060-p2v-Allow-p2v-kernel-options-to-override-GUI-configu.patch +++ /dev/null @@ -1,228 +0,0 @@ -From fe1e9ab849a7443907dd1968b34e89c58dba91f8 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Mon, 18 Apr 2016 14:40:29 +0100 -Subject: [PATCH] p2v: Allow p2v kernel options to override GUI configuration - (RHBZ#1327488). - -Allow kernel options such as p2v.o=libvirt to override internal -defaults, even for GUI configuration. - -The main change is to split up the kernel conversion into two steps: -reading the kernel command line configuration, and performing the -conversion. The kernel command line can then be read by the main -program and used to initialize the config structure for either kernel -conversion or GUI conversion. - -A small adjustment is required in the test because p2v.pre no longer -runs before kernel command line parsing. (The aim is to have -p2v.pre/post/fail still only run when doing a kernel conversion, not -in the GUI case.) - -(cherry picked from commit fb74a275c1438e6e0569b7fea85d2a4841a07a4e) ---- - p2v/gui.c | 2 +- - p2v/kernel.c | 57 +++++++++++++++++++++++++++----------------- - p2v/main.c | 27 +++++++++++---------- - p2v/p2v.h | 5 ++-- - p2v/test-virt-p2v-cmdline.sh | 4 +--- - 5 files changed, 54 insertions(+), 41 deletions(-) - -diff --git a/p2v/gui.c b/p2v/gui.c -index 569a295..015fa21 100644 ---- a/p2v/gui.c -+++ b/p2v/gui.c -@@ -75,7 +75,7 @@ static GtkWidget *run_dlg, - * Note that gtk_init etc have already been called in main. - */ - void --gui_application (struct config *config) -+gui_conversion (struct config *config) - { - /* Create the dialogs. */ - create_connection_dialog (config); -diff --git a/p2v/kernel.c b/p2v/kernel.c -index e904502..6d9388b 100644 ---- a/p2v/kernel.c -+++ b/p2v/kernel.c -@@ -38,18 +38,19 @@ static void notify_ui_callback (int type, const char *data); - static void run_command (int verbose, const char *stage, const char *command); - - void --kernel_configuration (struct config *config, char **cmdline, int cmdline_source) -+update_config_from_kernel_cmdline (struct config *config, char **cmdline) - { - const char *p; - -- p = get_cmdline_key (cmdline, "p2v.pre"); -+ p = get_cmdline_key (cmdline, "p2v.debug"); - if (p) -- run_command (config->verbose, "p2v.pre", p); -+ config->verbose = 1; - - p = get_cmdline_key (cmdline, "p2v.server"); -- assert (p); /* checked by caller */ -- free (config->server); -- config->server = strdup (p); -+ if (p) { -+ free (config->server); -+ config->server = strdup (p); -+ } - - p = get_cmdline_key (cmdline, "p2v.port"); - if (p) { -@@ -83,21 +84,6 @@ kernel_configuration (struct config *config, char **cmdline, int cmdline_source) - if (p) - config->sudo = 1; - -- /* We should now be able to connect and interrogate virt-v2v -- * on the conversion server. -- */ -- p = get_cmdline_key (cmdline, "p2v.skip_test_connection"); -- if (!p) { -- wait_network_online (config); -- if (test_connection (config) == -1) { -- const char *err = get_ssh_error (); -- -- fprintf (stderr, "%s: error opening control connection to %s:%d: %s\n", -- guestfs_int_program_name, config->server, config->port, err); -- exit (EXIT_FAILURE); -- } -- } -- - p = get_cmdline_key (cmdline, "p2v.name"); - if (p) { - free (config->guestname); -@@ -207,12 +193,39 @@ kernel_configuration (struct config *config, char **cmdline, int cmdline_source) - config->output_storage = strdup (p); - } - -- /* Undocumented command line tool used for testing command line parsing. */ -+ /* Undocumented command line parameter used for testing command line -+ * parsing. -+ */ - p = get_cmdline_key (cmdline, "p2v.dump_config_and_exit"); - if (p) { - print_config (config, stdout); - exit (EXIT_SUCCESS); - } -+} -+ -+/* Perform conversion using the kernel method. */ -+void -+kernel_conversion (struct config *config, char **cmdline, int cmdline_source) -+{ -+ const char *p; -+ -+ /* Pre-conversion command. */ -+ p = get_cmdline_key (cmdline, "p2v.pre"); -+ if (p) -+ run_command (config->verbose, "p2v.pre", p); -+ -+ /* Connect to and interrogate virt-v2v on the conversion server. */ -+ p = get_cmdline_key (cmdline, "p2v.skip_test_connection"); -+ if (!p) { -+ wait_network_online (config); -+ if (test_connection (config) == -1) { -+ const char *err = get_ssh_error (); -+ -+ error (EXIT_FAILURE, 0, -+ "error opening control connection to %s:%d: %s", -+ config->server, config->port, err); -+ } -+ } - - /* Some disks must have been specified for conversion. */ - if (config->disks == NULL || guestfs_int_count_strings (config->disks) == 0) { -diff --git a/p2v/main.c b/p2v/main.c -index f037716..99da3e4 100644 ---- a/p2v/main.c -+++ b/p2v/main.c -@@ -191,25 +191,26 @@ main (int argc, char *argv[]) - - set_config_defaults (config); - -- /* If /proc/cmdline exists and contains "p2v.server=" then we enable -- * non-interactive configuration. -- * If /proc/cmdline contains p2v.debug then we enable verbose mode -- * even for interactive configuration. -+ /* Parse /proc/cmdline (if it exists) or use the --cmdline parameter -+ * to initialize the configuration. This allows defaults to be pass -+ * using the kernel command line, with additional GUI configuration -+ * later. - */ - if (cmdline == NULL) { - cmdline = parse_proc_cmdline (); -- if (cmdline == NULL) -- goto gui; -- cmdline_source = CMDLINE_SOURCE_PROC_CMDLINE; -+ if (cmdline != NULL) -+ cmdline_source = CMDLINE_SOURCE_PROC_CMDLINE; - } - -- if (get_cmdline_key (cmdline, "p2v.debug") != NULL) -- config->verbose = 1; -+ if (cmdline) -+ update_config_from_kernel_cmdline (config, cmdline); - -- if (get_cmdline_key (cmdline, "p2v.server") != NULL) -- kernel_configuration (config, cmdline, cmdline_source); -+ /* If p2v.server exists, then we use the non-interactive kernel -+ * conversion. Otherwise we run the GUI. -+ */ -+ if (config->server != NULL) -+ kernel_conversion (config, cmdline, cmdline_source); - else { -- gui: - if (!gui_possible) { - fprintf (stderr, - _("%s: gtk_init_check returned false, indicating that\n" -@@ -217,7 +218,7 @@ main (int argc, char *argv[]) - guestfs_int_program_name); - exit (EXIT_FAILURE); - } -- gui_application (config); -+ gui_conversion (config); - } - - guestfs_int_free_string_list (cmdline); -diff --git a/p2v/p2v.h b/p2v/p2v.h -index 097f294..9ccaf0f 100644 ---- a/p2v/p2v.h -+++ b/p2v/p2v.h -@@ -106,10 +106,11 @@ extern const char *get_cmdline_key (char **cmdline, const char *key); - #define CMDLINE_SOURCE_PROC_CMDLINE 2 /* /proc/cmdline */ - - /* kernel.c */ --extern void kernel_configuration (struct config *, char **cmdline, int cmdline_source); -+extern void update_config_from_kernel_cmdline (struct config *config, char **cmdline); -+extern void kernel_conversion (struct config *, char **cmdline, int cmdline_source); - - /* gui.c */ --extern void gui_application (struct config *); -+extern void gui_conversion (struct config *); - - /* conversion.c */ - extern int start_conversion (struct config *, void (*notify_ui) (int type, const char *data)); -diff --git a/p2v/test-virt-p2v-cmdline.sh b/p2v/test-virt-p2v-cmdline.sh -index bdd51d3..9629a05 100755 ---- a/p2v/test-virt-p2v-cmdline.sh -+++ b/p2v/test-virt-p2v-cmdline.sh -@@ -31,14 +31,12 @@ out=test-virt-p2v-cmdline.out - rm -f $out - - # The Linux kernel command line. --virt-p2v --cmdline='p2v.pre="echo 1 2 3" p2v.server=localhost p2v.port=123 p2v.username=user p2v.password=secret p2v.skip_test_connection p2v.name=test p2v.vcpus=4 p2v.memory=1G p2v.disks=sda,sdb,sdc p2v.removable=sdd p2v.interfaces=eth0,eth1 p2v.o=local p2v.oa=sparse p2v.oc=qemu:///session p2v.of=raw p2v.os=/var/tmp p2v.network=em1:wired,other p2v.dump_config_and_exit' > $out -+virt-p2v --cmdline='p2v.server=localhost p2v.port=123 p2v.username=user p2v.password=secret p2v.skip_test_connection p2v.name=test p2v.vcpus=4 p2v.memory=1G p2v.disks=sda,sdb,sdc p2v.removable=sdd p2v.interfaces=eth0,eth1 p2v.o=local p2v.oa=sparse p2v.oc=qemu:///session p2v.of=raw p2v.os=/var/tmp p2v.network=em1:wired,other p2v.dump_config_and_exit' > $out - - # For debugging purposes. - cat $out - - # Check the output contains what we expect. --grep "^echo 1 2 3" $out --grep "^1 2 3" $out - grep "^conversion server.*localhost" $out - grep "^port.*123" $out - grep "^username.*user" $out --- -1.8.3.1 - diff --git a/SOURCES/0061-tests-boot-analysis-Add-text-to-describe-how-to-chan.patch b/SOURCES/0061-tests-boot-analysis-Add-text-to-describe-how-to-chan.patch deleted file mode 100644 index 014d635..0000000 --- a/SOURCES/0061-tests-boot-analysis-Add-text-to-describe-how-to-chan.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 13fc1ca307552c6a71c3fa28c7c1fbc846cc65dc Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Fri, 22 Apr 2016 14:52:03 +0100 -Subject: [PATCH] tests: boot analysis: Add text to describe how to change - settings. - -(cherry picked from commit 45f84601b05aef0408b55011fb02579c147ca853) ---- - tests/qemu/boot-analysis-utils.c | 14 +++++++++----- - 1 file changed, 9 insertions(+), 5 deletions(-) - -diff --git a/tests/qemu/boot-analysis-utils.c b/tests/qemu/boot-analysis-utils.c -index 4ed2d48..693b6f4 100644 ---- a/tests/qemu/boot-analysis-utils.c -+++ b/tests/qemu/boot-analysis-utils.c -@@ -69,18 +69,22 @@ test_info (guestfs_h *g, int nr_test_passes) - - /* Related to qemu. */ - backend = guestfs_get_backend (g); -- printf (" backend: %s\n", backend); -- printf (" qemu: %s\n", qemu); -+ printf (" backend: %-20s [to change set LIBGUESTFS_BACKEND]\n", -+ backend); -+ printf (" qemu: %-20s [to change set $LIBGUESTFS_HV]\n", qemu); - printf ("qemu version: "); - fflush (stdout); - if (asprintf (&cmd, "%s -version", qemu) == -1) - error (EXIT_FAILURE, errno, "asprintf"); - ignore_value (system (cmd)); -- printf (" smp: %d\n", guestfs_get_smp (g)); -- printf (" memsize: %d\n", guestfs_get_memsize (g)); -+ printf (" smp: %-20d [to change use --smp option]\n", -+ guestfs_get_smp (g)); -+ printf (" memsize: %-20d [to change use --memsize option]\n", -+ guestfs_get_memsize (g)); - - /* Related to the guest kernel. Be nice to get the guest - * kernel version here somehow (XXX). - */ -- printf (" append: %s\n", guestfs_get_append (g) ? : ""); -+ printf (" append: %-20s [to change use --append option]\n", -+ guestfs_get_append (g) ? : ""); - } --- -1.8.3.1 - diff --git a/SOURCES/0062-tests-Add-boot-benchmark-range-script.patch b/SOURCES/0062-tests-Add-boot-benchmark-range-script.patch deleted file mode 100644 index 6f6500c..0000000 --- a/SOURCES/0062-tests-Add-boot-benchmark-range-script.patch +++ /dev/null @@ -1,289 +0,0 @@ -From 7b8c5efa52161bcd99006e7986c6cb67f6475023 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Fri, 22 Apr 2016 16:32:24 +0100 -Subject: [PATCH] tests: Add boot-benchmark-range script. - -Add a script we can use to benchmark performance across a range of -commits in another project. - -(cherry picked from commit 8299d7087a6457828a57ecace54c01b73912a9c7) ---- - docs/guestfs-performance.pod | 14 +++ - tests/qemu/boot-benchmark-range.pl | 240 +++++++++++++++++++++++++++++++++++++ - 2 files changed, 254 insertions(+) - create mode 100755 tests/qemu/boot-benchmark-range.pl - -diff --git a/docs/guestfs-performance.pod b/docs/guestfs-performance.pod -index cf30fdc..d9c76ac 100644 ---- a/docs/guestfs-performance.pod -+++ b/docs/guestfs-performance.pod -@@ -589,6 +589,20 @@ breakpoints, etc. Note that when you are past the BIOS and into the - Linux kernel, you'll want to change the architecture back to 32 or 64 - bit. - -+=head1 PERFORMANCE REGRESSIONS IN OTHER PROGRAMS -+ -+Sometimes performance regressions happen in other programs (eg. qemu, -+the kernel) that cause problems for libguestfs. -+ -+In the libguestfs source, F is a -+script which can be used to benchmark libguestfs across a range of git -+commits in another project to find out if any commit is causing a -+slowdown (or speedup). -+ -+To find out how to use this script, consult the manual: -+ -+ ./tests/qemu/boot-benchmark-range.pl --man -+ - =head1 SEE ALSO - - L, -diff --git a/tests/qemu/boot-benchmark-range.pl b/tests/qemu/boot-benchmark-range.pl -new file mode 100755 -index 0000000..0e31c4d ---- /dev/null -+++ b/tests/qemu/boot-benchmark-range.pl -@@ -0,0 +1,240 @@ -+#!/usr/bin/env perl -+# Copyright (C) 2016 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. -+ -+use warnings; -+use strict; -+ -+use Pod::Usage; -+use Getopt::Long; -+ -+=head1 NAME -+ -+boot-benchmark-range.pl - Benchmark libguestfs across a range of commits -+from another project -+ -+=head1 SYNOPSIS -+ -+ LIBGUESTFS_BACKEND=direct \ -+ LIBGUESTFS_HV=/path/to/qemu/x86_64-softmmu/qemu-system-x86_64 \ -+ ./run \ -+ tests/qemu/boot-benchmark-range.pl /path/to/qemu HEAD~50..HEAD -+ -+=head1 -+ -+Run F across a range of commits in another -+project. This is useful for finding performance regressions in other -+programs such as qemu or the Linux kernel which might be affecting -+libguestfs. -+ -+For example, suppose you suspect there has been a performance -+regression in qemu, somewhere between C. You could run -+the script like this: -+ -+ LIBGUESTFS_BACKEND=direct \ -+ LIBGUESTFS_HV=/path/to/qemu/x86_64-softmmu/qemu-system-x86_64 \ -+ ./run \ -+ tests/qemu/boot-benchmark-range.pl /path/to/qemu HEAD~50..HEAD -+ -+where F is the path to the qemu git repository. -+ -+The output is a list of the qemu commits, annotated by the benchmark -+time and some other information about how the time compares to the -+previous commit. -+ -+You should run these tests on an unloaded machine. In particular -+running a desktop environment, web browser and so on can make the -+benchmarks useless. -+ -+=head1 OPTIONS -+ -+=over 4 -+ -+=cut -+ -+my $help; -+ -+=item B<--help> -+ -+Display brief help. -+ -+=cut -+ -+my $man; -+ -+=item B<--man> -+ -+Display full documentation (man page). -+ -+=cut -+ -+my $benchmark_command; -+ -+=item B<--benchmark> C -+ -+Set the name of the benchmark to run. You only need to use this if -+the script cannot find the right path to the libguestfs -+F program. By default the script looks for -+this file in the same directory as its executable. -+ -+=cut -+ -+my $make_command = "make"; -+ -+=item B<--make> C -+ -+Set the command used to build the other project. The default is -+to run C. -+ -+If the command fails, then the commit is skipped. -+ -+=back -+ -+=cut -+ -+# Clean up the program name. -+my $progname = $0; -+$progname =~ s{.*/}{}; -+ -+# Parse options. -+GetOptions ("help|?" => \$help, -+ "man" => \$man, -+ "benchmark=s" => \$benchmark_command, -+ "make=s" => \$make_command, -+ ) or pod2usage (2); -+pod2usage (-exitval => 0) if $help; -+pod2usage (-exitval => 0, -verbose => 2) if $man; -+ -+die "$progname: missing argument: requires path to git repository and range of commits\n" unless @ARGV == 2; -+ -+my $dir = $ARGV[0]; -+my $range = $ARGV[1]; -+ -+die "$progname: $dir is not a git repository\n" -+ unless -d $dir && -d "$dir/.git"; -+ -+sub silently_run -+{ -+ open my $saveout, ">&STDOUT"; -+ open my $saveerr, ">&STDERR"; -+ open STDOUT, ">/dev/null"; -+ open STDERR, ">/dev/null"; -+ my $ret = system (@_); -+ open STDOUT, ">&", $saveout; -+ open STDERR, ">&", $saveerr; -+ return $ret; -+} -+ -+# Find the benchmark program and check it works. -+unless (defined $benchmark_command) { -+ $benchmark_command = $0; -+ $benchmark_command =~ s{/[^/]+$}{}; -+ $benchmark_command .= "/boot-benchmark"; -+ -+ my $r = silently_run ("$benchmark_command", "--help"); -+ die "$progname: cannot locate boot-benchmark program, try using --benchmark\n" unless $r == 0; -+} -+ -+# Get the top-most commit from the remote, and restore it on exit. -+my $top_commit = `git -C '$dir' rev-parse HEAD`; -+chomp $top_commit; -+ -+sub checkout -+{ -+ my $sha = shift; -+ my $ret = silently_run ("git", "-C", $dir, "checkout", $sha); -+ return $ret; -+} -+ -+END { -+ checkout ($top_commit); -+} -+ -+# Get the range of commits and log messages. -+my @range = (); -+open RANGE, "git -C '$dir' log --reverse --oneline $range |" or die; -+while () { -+ if (m/^([0-9a-f]+) (.*)/) { -+ my $sha = $1; -+ my $msg = $2; -+ push @range, [ $sha, $msg ]; -+ } -+} -+close RANGE or die; -+ -+# Run the test. -+my $prev_ms; -+foreach (@range) { -+ my ($sha, $msg) = @$_; -+ my $r; -+ -+ print "\n"; -+ print "$sha $msg\n"; -+ -+ # Checkout this commit in the other repo. -+ $r = checkout ($sha); -+ if ($r != 0) { -+ print "git checkout failed\n"; -+ next; -+ } -+ -+ # Build the repo, silently. -+ $r = silently_run ("cd $dir && $make_command"); -+ if ($r != 0) { -+ print "build failed\n"; -+ next; -+ } -+ -+ # Run the benchmark program and get the timing. -+ my ($time_ms, $time_str); -+ open BENCHMARK, "$benchmark_command | grep '^Result:' |" or die; -+ while () { -+ die unless m/^Result: (([\d.]+)ms ±[\d.]+ms)/; -+ $time_ms = $2; -+ $time_str = $1; -+ } -+ close BENCHMARK; -+ -+ print "\t", $time_str; -+ if (defined $prev_ms) { -+ if ($prev_ms > $time_ms) { -+ my $pc = 100 * ($prev_ms-$time_ms) / $time_ms; -+ if ($pc >= 1) { -+ printf (" ↑ improves performance by %0.1f%%", $pc); -+ } -+ } elsif ($prev_ms < $time_ms) { -+ my $pc = 100 * ($time_ms-$prev_ms) / $prev_ms; -+ if ($pc >= 1) { -+ printf (" ↓ degrades performance by %0.1f%%", $pc); -+ } -+ } -+ } -+ print "\n"; -+ $prev_ms = $time_ms; -+} -+ -+=head1 SEE ALSO -+ -+L, -+L. -+ -+=head1 AUTHOR -+ -+Richard W.M. Jones. -+ -+=head1 COPYRIGHT -+ -+Copyright (C) 2016 Red Hat Inc. --- -1.8.3.1 - diff --git a/SOURCES/0063-v2v-Move-target_bus_assignment-to-separate-module.patch b/SOURCES/0063-v2v-Move-target_bus_assignment-to-separate-module.patch deleted file mode 100644 index d564406..0000000 --- a/SOURCES/0063-v2v-Move-target_bus_assignment-to-separate-module.patch +++ /dev/null @@ -1,277 +0,0 @@ -From ea4e7be22f84cadf9418f8d031ed7cc7f6914908 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Sat, 23 Apr 2016 18:15:19 +0100 -Subject: [PATCH] v2v: Move target_bus_assignment to separate module. - -This is just code motion. - -(cherry picked from commit 9e3182b4c5fc3abb55e0fe072c5fa3af1ffb0ee3) ---- - po/POTFILES-ml | 1 + - v2v/Makefile.am | 2 + - v2v/target_bus_assignment.ml | 91 +++++++++++++++++++++++++++++++++++++++++++ - v2v/target_bus_assignment.mli | 24 ++++++++++++ - v2v/v2v.ml | 79 ++----------------------------------- - 5 files changed, 121 insertions(+), 76 deletions(-) - create mode 100644 v2v/target_bus_assignment.ml - create mode 100644 v2v/target_bus_assignment.mli - -diff --git a/po/POTFILES-ml b/po/POTFILES-ml -index b94d616..b7f3cc2 100644 ---- a/po/POTFILES-ml -+++ b/po/POTFILES-ml -@@ -122,6 +122,7 @@ v2v/output_qemu.ml - v2v/output_rhev.ml - v2v/output_vdsm.ml - v2v/stringMap.ml -+v2v/target_bus_assignment.ml - v2v/test-harness/v2v_test_harness.ml - v2v/types.ml - v2v/utils.ml -diff --git a/v2v/Makefile.am b/v2v/Makefile.am -index d9cf986..2d52ab8 100644 ---- a/v2v/Makefile.am -+++ b/v2v/Makefile.am -@@ -67,6 +67,7 @@ SOURCES_MLI = \ - output_vdsm.mli \ - OVF.mli \ - stringMap.mli \ -+ target_bus_assignment.mli \ - types.mli \ - utils.mli \ - vCenter.mli \ -@@ -105,6 +106,7 @@ SOURCES_ML = \ - output_rhev.ml \ - output_vdsm.ml \ - inspect_source.ml \ -+ target_bus_assignment.ml \ - cmdline.ml \ - v2v.ml - -diff --git a/v2v/target_bus_assignment.ml b/v2v/target_bus_assignment.ml -new file mode 100644 -index 0000000..b82915b ---- /dev/null -+++ b/v2v/target_bus_assignment.ml -@@ -0,0 +1,91 @@ -+(* virt-v2v -+ * Copyright (C) 2009-2016 Red Hat Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License along -+ * with this program; if not, write to the Free Software Foundation, Inc., -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -+ *) -+ -+open Common_utils -+open Common_gettext.Gettext -+ -+open Types -+ -+(* XXX This doesn't do the right thing for PC legacy floppy devices. -+ * XXX This could handle slot assignment better when we have a mix of -+ * devices desiring their own slot, and others that don't care. Allocate -+ * the first group in the first pass, then the second group afterwards. -+ *) -+let rec target_bus_assignment source targets guestcaps = -+ let virtio_blk_bus = ref [| |] -+ and ide_bus = ref [| |] -+ and scsi_bus = ref [| |] in -+ -+ (* Add the fixed disks (targets) to either the virtio-blk or IDE bus, -+ * depending on whether the guest has virtio drivers or not. -+ *) -+ iteri ( -+ fun i t -> -+ let t = BusSlotTarget t in -+ match guestcaps.gcaps_block_bus with -+ | Virtio_blk -> insert virtio_blk_bus i t -+ | IDE -> insert ide_bus i t -+ ) targets; -+ -+ (* Now try to add the removable disks to the bus at the same slot -+ * they originally occupied, but if the slot is occupied, emit a -+ * a warning and insert the disk in the next empty slot in that bus. -+ *) -+ List.iter ( -+ fun r -> -+ let bus = match r.s_removable_controller with -+ | None -> ide_bus (* Wild guess, but should be safe. *) -+ | Some Source_virtio_blk -> virtio_blk_bus -+ | Some Source_IDE -> ide_bus -+ | Some Source_SCSI -> scsi_bus in -+ match r.s_removable_slot with -+ | None -> ignore (insert_after bus 0 (BusSlotRemovable r)) -+ | Some desired_slot_nr -> -+ if not (insert_after bus desired_slot_nr (BusSlotRemovable r)) then -+ warning (f_"removable %s device in slot %d clashes with another disk, so it has been moved to a higher numbered slot on the same bus. This may mean that this removable device has a different name inside the guest (for example a CD-ROM originally called /dev/hdc might move to /dev/hdd, or from D: to E: on a Windows guest).") -+ (match r.s_removable_type with -+ | CDROM -> s_"CD-ROM" -+ | Floppy -> s_"floppy disk") -+ desired_slot_nr -+ ) source.s_removables; -+ -+ { target_virtio_blk_bus = !virtio_blk_bus; -+ target_ide_bus = !ide_bus; -+ target_scsi_bus = !scsi_bus } -+ -+(* Insert a slot into the bus array, making the array bigger if necessary. *) -+and insert bus i slot = -+ let oldbus = !bus in -+ let oldlen = Array.length oldbus in -+ if i >= oldlen then ( -+ bus := Array.make (i+1) BusSlotEmpty; -+ Array.blit oldbus 0 !bus 0 oldlen -+ ); -+ Array.set !bus i slot -+ -+(* Insert a slot into the bus, but if the desired slot is not empty, then -+ * increment the slot number until we find an empty one. Returns -+ * true if we got the desired slot. -+ *) -+and insert_after bus i slot = -+ let len = Array.length !bus in -+ if i >= len || Array.get !bus i = BusSlotEmpty then ( -+ insert bus i slot; true -+ ) else ( -+ ignore (insert_after bus (i+1) slot); false -+ ) -diff --git a/v2v/target_bus_assignment.mli b/v2v/target_bus_assignment.mli -new file mode 100644 -index 0000000..6a30b2c ---- /dev/null -+++ b/v2v/target_bus_assignment.mli -@@ -0,0 +1,24 @@ -+(* virt-v2v -+ * Copyright (C) 2009-2016 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. -+ *) -+ -+(** Assign fixed and removable disks to target buses. -+ -+ Do this as best we can. This is not solvable for all guests, -+ but at least avoid overlapping disks (RHBZ#1238053). *) -+ -+val target_bus_assignment : Types.source -> Types.target list -> Types.guestcaps -> Types.target_buses -diff --git a/v2v/v2v.ml b/v2v/v2v.ml -index c73482b..f2f1cff 100644 ---- a/v2v/v2v.ml -+++ b/v2v/v2v.ml -@@ -118,7 +118,9 @@ let rec main () = - get_target_firmware inspect guestcaps source output in - - message (f_"Assigning disks to buses"); -- let target_buses = target_bus_assignment source targets guestcaps in -+ let target_buses = -+ Target_bus_assignment.target_bus_assignment source targets -+ guestcaps in - debug "%s" (string_of_target_buses target_buses); - - let targets = -@@ -716,81 +718,6 @@ and actual_target_size target = - with Failure _ | Invalid_argument _ -> None in - { target with target_actual_size = size } - --(* Assign fixed and removable disks to target buses, as best we can. -- * This is not solvable for all guests, but at least avoid overlapping -- * disks (RHBZ#1238053). -- * -- * XXX This doesn't do the right thing for PC legacy floppy devices. -- * XXX This could handle slot assignment better when we have a mix of -- * devices desiring their own slot, and others that don't care. Allocate -- * the first group in the first pass, then the second group afterwards. -- *) --and target_bus_assignment source targets guestcaps = -- let virtio_blk_bus = ref [| |] -- and ide_bus = ref [| |] -- and scsi_bus = ref [| |] in -- -- (* Insert a slot into the bus array, making the array bigger if necessary. *) -- let insert bus i slot = -- let oldbus = !bus in -- let oldlen = Array.length oldbus in -- if i >= oldlen then ( -- bus := Array.make (i+1) BusSlotEmpty; -- Array.blit oldbus 0 !bus 0 oldlen -- ); -- Array.set !bus i slot -- in -- -- (* Insert a slot into the bus, but if the desired slot is not empty, then -- * increment the slot number until we find an empty one. Returns -- * true if we got the desired slot. -- *) -- let rec insert_after bus i slot = -- let len = Array.length !bus in -- if i >= len || Array.get !bus i = BusSlotEmpty then ( -- insert bus i slot; true -- ) else ( -- ignore (insert_after bus (i+1) slot); false -- ) -- in -- -- (* Add the fixed disks (targets) to either the virtio-blk or IDE bus, -- * depending on whether the guest has virtio drivers or not. -- *) -- iteri ( -- fun i t -> -- let t = BusSlotTarget t in -- match guestcaps.gcaps_block_bus with -- | Virtio_blk -> insert virtio_blk_bus i t -- | IDE -> insert ide_bus i t -- ) targets; -- -- (* Now try to add the removable disks to the bus at the same slot -- * they originally occupied, but if the slot is occupied, emit a -- * a warning and insert the disk in the next empty slot in that bus. -- *) -- List.iter ( -- fun r -> -- let bus = match r.s_removable_controller with -- | None -> ide_bus (* Wild guess, but should be safe. *) -- | Some Source_virtio_blk -> virtio_blk_bus -- | Some Source_IDE -> ide_bus -- | Some Source_SCSI -> scsi_bus in -- match r.s_removable_slot with -- | None -> ignore (insert_after bus 0 (BusSlotRemovable r)) -- | Some desired_slot_nr -> -- if not (insert_after bus desired_slot_nr (BusSlotRemovable r)) then -- warning (f_"removable %s device in slot %d clashes with another disk, so it has been moved to a higher numbered slot on the same bus. This may mean that this removable device has a different name inside the guest (for example a CD-ROM originally called /dev/hdc might move to /dev/hdd, or from D: to E: on a Windows guest).") -- (match r.s_removable_type with -- | CDROM -> s_"CD-ROM" -- | Floppy -> s_"floppy disk") -- desired_slot_nr -- ) source.s_removables; -- -- { target_virtio_blk_bus = !virtio_blk_bus; -- target_ide_bus = !ide_bus; -- target_scsi_bus = !scsi_bus } -- - (* Save overlays if --debug-overlays option was used. *) - and preserve_overlays overlays src_name = - let overlay_dir = (open_guestfs ())#get_cachedir () in --- -1.8.3.1 - diff --git a/SOURCES/0064-v2v-Assert-fail-if-we-overwrite-an-existing-disk-in-.patch b/SOURCES/0064-v2v-Assert-fail-if-we-overwrite-an-existing-disk-in-.patch deleted file mode 100644 index 2ff5502..0000000 --- a/SOURCES/0064-v2v-Assert-fail-if-we-overwrite-an-existing-disk-in-.patch +++ /dev/null @@ -1,30 +0,0 @@ -From be941dc3b54a4ff176a08ffdb635f6998621bbda Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Sun, 24 Apr 2016 11:33:28 +0100 -Subject: [PATCH] v2v: Assert fail if we overwrite an existing disk in a bus - slot. - -Prevents us from accidentally "losing" a disk during conversion. I -believe from code inspection that this assertion is always true for -the current code, so this should have no effect. - -(cherry picked from commit 6193b2b273f603bbe7b361d858e5b2fca0082ef6) ---- - v2v/target_bus_assignment.ml | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/v2v/target_bus_assignment.ml b/v2v/target_bus_assignment.ml -index b82915b..eb3ed58 100644 ---- a/v2v/target_bus_assignment.ml -+++ b/v2v/target_bus_assignment.ml -@@ -76,6 +76,7 @@ and insert bus i slot = - bus := Array.make (i+1) BusSlotEmpty; - Array.blit oldbus 0 !bus 0 oldlen - ); -+ assert (!bus.(i) = BusSlotEmpty); - Array.set !bus i slot - - (* Insert a slot into the bus, but if the desired slot is not empty, then --- -1.8.3.1 - diff --git a/SOURCES/0065-v2v-target_bus_assignment-Various-refactorings.patch b/SOURCES/0065-v2v-target_bus_assignment-Various-refactorings.patch deleted file mode 100644 index 62689cd..0000000 --- a/SOURCES/0065-v2v-target_bus_assignment-Various-refactorings.patch +++ /dev/null @@ -1,83 +0,0 @@ -From 6d2cf9eebf4bddbf868aae7e80a2a0f3b22c4545 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Sun, 24 Apr 2016 11:36:20 +0100 -Subject: [PATCH] v2v: target_bus_assignment: Various refactorings. - -No functional change. - -(cherry picked from commit c1adbe61dfd23ba28e286e0ecaf97bba6de9cdcd) ---- - v2v/target_bus_assignment.ml | 28 +++++++++++++++++----------- - 1 file changed, 17 insertions(+), 11 deletions(-) - -diff --git a/v2v/target_bus_assignment.ml b/v2v/target_bus_assignment.ml -index eb3ed58..0546004 100644 ---- a/v2v/target_bus_assignment.ml -+++ b/v2v/target_bus_assignment.ml -@@ -34,13 +34,16 @@ let rec target_bus_assignment source targets guestcaps = - (* Add the fixed disks (targets) to either the virtio-blk or IDE bus, - * depending on whether the guest has virtio drivers or not. - *) -- iteri ( -- fun i t -> -- let t = BusSlotTarget t in -+ let () = -+ let bus = - match guestcaps.gcaps_block_bus with -- | Virtio_blk -> insert virtio_blk_bus i t -- | IDE -> insert ide_bus i t -- ) targets; -+ | Virtio_blk -> virtio_blk_bus -+ | IDE -> ide_bus in -+ iteri ( -+ fun i t -> -+ let t = BusSlotTarget t in -+ insert bus i t -+ ) targets in - - (* Now try to add the removable disks to the bus at the same slot - * they originally occupied, but if the slot is occupied, emit a -@@ -48,15 +51,16 @@ let rec target_bus_assignment source targets guestcaps = - *) - List.iter ( - fun r -> -+ let t = BusSlotRemovable r in - let bus = match r.s_removable_controller with - | None -> ide_bus (* Wild guess, but should be safe. *) - | Some Source_virtio_blk -> virtio_blk_bus - | Some Source_IDE -> ide_bus - | Some Source_SCSI -> scsi_bus in - match r.s_removable_slot with -- | None -> ignore (insert_after bus 0 (BusSlotRemovable r)) -+ | None -> ignore (insert_after bus 0 t) - | Some desired_slot_nr -> -- if not (insert_after bus desired_slot_nr (BusSlotRemovable r)) then -+ if not (insert_after bus desired_slot_nr t) then - warning (f_"removable %s device in slot %d clashes with another disk, so it has been moved to a higher numbered slot on the same bus. This may mean that this removable device has a different name inside the guest (for example a CD-ROM originally called /dev/hdc might move to /dev/hdd, or from D: to E: on a Windows guest).") - (match r.s_removable_type with - | CDROM -> s_"CD-ROM" -@@ -77,16 +81,18 @@ and insert bus i slot = - Array.blit oldbus 0 !bus 0 oldlen - ); - assert (!bus.(i) = BusSlotEmpty); -- Array.set !bus i slot -+ !bus.(i) <- slot - - (* Insert a slot into the bus, but if the desired slot is not empty, then - * increment the slot number until we find an empty one. Returns - * true if we got the desired slot. - *) - and insert_after bus i slot = -- let len = Array.length !bus in -- if i >= len || Array.get !bus i = BusSlotEmpty then ( -+ if slot_is_empty bus i then ( - insert bus i slot; true - ) else ( - ignore (insert_after bus (i+1) slot); false - ) -+ -+(* Return true if slot i is empty in the bus. *) -+and slot_is_empty bus i = i >= Array.length !bus || !bus.(i) = BusSlotEmpty --- -1.8.3.1 - diff --git a/SOURCES/0066-v2v-target_bus_assignment-Assign-removables-with-slo.patch b/SOURCES/0066-v2v-target_bus_assignment-Assign-removables-with-slo.patch deleted file mode 100644 index 73d905f..0000000 --- a/SOURCES/0066-v2v-target_bus_assignment-Assign-removables-with-slo.patch +++ /dev/null @@ -1,103 +0,0 @@ -From 4bcb2ea57c7e06fe88306e34e1ae34caa4a563c4 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Sun, 24 Apr 2016 12:00:10 +0100 -Subject: [PATCH] v2v: target_bus_assignment: Assign removables with slot pref - first. - -(cherry picked from commit 672eff4a34a962293e3c3d6ac8b61d5abd28f747) ---- - v2v/target_bus_assignment.ml | 70 ++++++++++++++++++++++++++++---------------- - 1 file changed, 44 insertions(+), 26 deletions(-) - -diff --git a/v2v/target_bus_assignment.ml b/v2v/target_bus_assignment.ml -index 0546004..5ad8582 100644 ---- a/v2v/target_bus_assignment.ml -+++ b/v2v/target_bus_assignment.ml -@@ -21,11 +21,7 @@ open Common_gettext.Gettext - - open Types - --(* XXX This doesn't do the right thing for PC legacy floppy devices. -- * XXX This could handle slot assignment better when we have a mix of -- * devices desiring their own slot, and others that don't care. Allocate -- * the first group in the first pass, then the second group afterwards. -- *) -+(* XXX This doesn't do the right thing for PC legacy floppy devices. *) - let rec target_bus_assignment source targets guestcaps = - let virtio_blk_bus = ref [| |] - and ide_bus = ref [| |] -@@ -45,28 +41,50 @@ let rec target_bus_assignment source targets guestcaps = - insert bus i t - ) targets in - -- (* Now try to add the removable disks to the bus at the same slot -- * they originally occupied, but if the slot is occupied, emit a -- * a warning and insert the disk in the next empty slot in that bus. -+ (* Now we have to assign the removable disks. These go in the -+ * same slot they originally occupied, except in two cases: (1) That -+ * slot is now occupied by a target disk, or (2) we don't -+ * have information about the original slot. In these cases -+ * insert the disk in the next empty slot in that bus. - *) -- List.iter ( -- fun r -> -- let t = BusSlotRemovable r in -- let bus = match r.s_removable_controller with -- | None -> ide_bus (* Wild guess, but should be safe. *) -- | Some Source_virtio_blk -> virtio_blk_bus -- | Some Source_IDE -> ide_bus -- | Some Source_SCSI -> scsi_bus in -- match r.s_removable_slot with -- | None -> ignore (insert_after bus 0 t) -- | Some desired_slot_nr -> -- if not (insert_after bus desired_slot_nr t) then -- warning (f_"removable %s device in slot %d clashes with another disk, so it has been moved to a higher numbered slot on the same bus. This may mean that this removable device has a different name inside the guest (for example a CD-ROM originally called /dev/hdc might move to /dev/hdd, or from D: to E: on a Windows guest).") -- (match r.s_removable_type with -- | CDROM -> s_"CD-ROM" -- | Floppy -> s_"floppy disk") -- desired_slot_nr -- ) source.s_removables; -+ -+ (* Split the removables into a list of devices that desire a -+ * particular slot, and those that don't care. Assign the first -+ * group first so they have a greater chance of getting the -+ * desired slot. -+ *) -+ let removables_desire, removables_no_desire = -+ List.partition ( -+ function -+ | { s_removable_slot = Some _ } -> true -+ | { s_removable_slot = None } -> false -+ ) source.s_removables in -+ -+ let assign_removables removables = -+ List.iter ( -+ fun r -> -+ let t = BusSlotRemovable r in -+ let bus = -+ match r.s_removable_controller with -+ | None -> ide_bus (* Wild guess, but should be safe. *) -+ | Some Source_virtio_blk -> virtio_blk_bus -+ | Some Source_IDE -> ide_bus -+ | Some Source_SCSI -> scsi_bus in -+ -+ match r.s_removable_slot with -+ | None -> -+ ignore (insert_after bus 0 t) -+ | Some desired_slot_nr -> -+ if not (insert_after bus desired_slot_nr t) then -+ warning (f_"removable %s device in slot %d clashes with another disk, so it has been moved to a higher numbered slot on the same bus. This may mean that this removable device has a different name inside the guest (for example a CD-ROM originally called /dev/hdc might move to /dev/hdd, or from D: to E: on a Windows guest).") -+ (match r.s_removable_type with -+ | CDROM -> s_"CD-ROM" -+ | Floppy -> s_"floppy disk") -+ desired_slot_nr -+ ) removables -+ in -+ assign_removables removables_desire; -+ assign_removables removables_no_desire; - - { target_virtio_blk_bus = !virtio_blk_bus; - target_ide_bus = !ide_bus; --- -1.8.3.1 - diff --git a/SOURCES/0067-tests-Add-tests-qemu-boot-benchmark-range.pl-to-EXTR.patch b/SOURCES/0067-tests-Add-tests-qemu-boot-benchmark-range.pl-to-EXTR.patch deleted file mode 100644 index 91ab11a..0000000 --- a/SOURCES/0067-tests-Add-tests-qemu-boot-benchmark-range.pl-to-EXTR.patch +++ /dev/null @@ -1,27 +0,0 @@ -From a52f3154da33115580953e5fc1abc0dfa062743e Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Sun, 24 Apr 2016 19:00:03 +0100 -Subject: [PATCH] tests: Add tests/qemu/boot-benchmark-range.pl to EXTRA_DIST. - -Updates commit 8299d7087a6457828a57ecace54c01b73912a9c7. - -(cherry picked from commit 7f572434f0acc47b5091eb4fd12bd1936198bec8) ---- - tests/qemu/Makefile.am | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/tests/qemu/Makefile.am b/tests/qemu/Makefile.am -index fdf643f..f2171cd 100644 ---- a/tests/qemu/Makefile.am -+++ b/tests/qemu/Makefile.am -@@ -30,6 +30,7 @@ TESTS_ENVIRONMENT = $(top_builddir)/run --test - - EXTRA_DIST = \ - $(TESTS) \ -+ boot-benchmark-range.pl \ - qemu-boot.c \ - qemu-speed-test.c - --- -1.8.3.1 - diff --git a/SOURCES/0068-tests-qemu-boot-analysis-Add-analysis-of-initcalls-b.patch b/SOURCES/0068-tests-qemu-boot-analysis-Add-analysis-of-initcalls-b.patch deleted file mode 100644 index 4f83085..0000000 --- a/SOURCES/0068-tests-qemu-boot-analysis-Add-analysis-of-initcalls-b.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 6143e307900ba1484c5768da05d98b88a83a8a1a Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Thu, 28 Apr 2016 13:33:51 +0100 -Subject: [PATCH] tests/qemu: boot-analysis: Add analysis of initcalls before - entering userspace. - -(cherry picked from commit 606f1586064ed5b45b9d25dc9bf2e518dd910ba7) ---- - tests/qemu/boot-analysis-timeline.c | 7 +++++++ - 1 file changed, 7 insertions(+) - -diff --git a/tests/qemu/boot-analysis-timeline.c b/tests/qemu/boot-analysis-timeline.c -index d35fb49..1c57d05 100644 ---- a/tests/qemu/boot-analysis-timeline.c -+++ b/tests/qemu/boot-analysis-timeline.c -@@ -296,6 +296,13 @@ construct_timeline (void) - strstr (data->events[j].message, "ftrace: allocating"), - 1); - -+ /* All initcall functions, before we enter userspace. */ -+ FIND ("kernel:initcalls-before-userspace", 0, -+ data->events[j].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[j].message, "calling "), -+ data->events[k].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[k].message, "Freeing unused kernel memory")); -+ - /* Find where we run supermin mini-initrd. */ - FIND ("supermin:mini-initrd", 0, - data->events[j].source == GUESTFS_EVENT_APPLIANCE && --- -1.8.3.1 - diff --git a/SOURCES/0069-tests-qemu-boot-analysis-Port-this-program-to-aarch6.patch b/SOURCES/0069-tests-qemu-boot-analysis-Port-this-program-to-aarch6.patch deleted file mode 100644 index ac1523f..0000000 --- a/SOURCES/0069-tests-qemu-boot-analysis-Port-this-program-to-aarch6.patch +++ /dev/null @@ -1,136 +0,0 @@ -From f86fc53b962ba7d6383561162ce5a96560dca7af Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Sat, 30 Apr 2016 12:45:54 +0100 -Subject: [PATCH] tests/qemu: boot-analysis: Port this program to aarch64 - (using UEFI). - -(cherry picked from commit d5c40262fa80cebcc48a73c04a22cf4a635dcb7b) ---- - tests/qemu/boot-analysis-timeline.c | 31 +++++++++++++++++++++++-------- - tests/qemu/boot-analysis.c | 4 ++-- - 2 files changed, 25 insertions(+), 10 deletions(-) - -diff --git a/tests/qemu/boot-analysis-timeline.c b/tests/qemu/boot-analysis-timeline.c -index 1c57d05..09a78ef 100644 ---- a/tests/qemu/boot-analysis-timeline.c -+++ b/tests/qemu/boot-analysis-timeline.c -@@ -216,60 +216,73 @@ construct_timeline (void) - data->events[k].source == GUESTFS_EVENT_LIBRARY && - strstr (data->events[k].message, "libvirt XML:")); - -+#if defined(__aarch64__) -+#define FIRST_KERNEL_MESSAGE "Booting Linux on physical CPU" -+#define FIRST_FIRMWARE_MESSAGE "UEFI firmware starting" -+#else - #define SGABIOS_STRING "\033[1;256r\033[256;256H\033[6n" -+#define FIRST_KERNEL_MESSAGE "Probing EDD" -+#define FIRST_FIRMWARE_MESSAGE SGABIOS_STRING -+#endif - - /* For the libvirt backend, find the overhead of libvirt. */ - FIND_OPTIONAL ("libvirt:overhead", 0, - data->events[j].source == GUESTFS_EVENT_LIBRARY && - strstr (data->events[j].message, "launch libvirt guest"), - data->events[k].source == GUESTFS_EVENT_APPLIANCE && -- strstr (data->events[k].message, SGABIOS_STRING)); -+ strstr (data->events[k].message, FIRST_FIRMWARE_MESSAGE)); - - /* From starting qemu up to entering the BIOS is the qemu overhead. */ - FIND_OPTIONAL ("qemu:overhead", 0, - data->events[j].source == GUESTFS_EVENT_APPLIANCE && - strstr (data->events[j].message, "-nodefconfig"), - data->events[k].source == GUESTFS_EVENT_APPLIANCE && -- strstr (data->events[k].message, SGABIOS_STRING)); -+ strstr (data->events[k].message, FIRST_FIRMWARE_MESSAGE)); - - /* From entering the BIOS to starting the kernel is the BIOS overhead. */ - FIND_OPTIONAL ("bios:overhead", 0, - data->events[j].source == GUESTFS_EVENT_APPLIANCE && -- strstr (data->events[j].message, SGABIOS_STRING), -+ strstr (data->events[j].message, FIRST_FIRMWARE_MESSAGE), - data->events[k].source == GUESTFS_EVENT_APPLIANCE && -- strstr (data->events[k].message, "Probing EDD")); -+ strstr (data->events[k].message, FIRST_KERNEL_MESSAGE)); - -+#if defined(__i386__) || defined(__x86_64__) - /* SGABIOS (option ROM). */ - FIND_OPTIONAL ("sgabios", 0, - data->events[j].source == GUESTFS_EVENT_APPLIANCE && - strstr (data->events[j].message, SGABIOS_STRING), - data->events[k].source == GUESTFS_EVENT_APPLIANCE && - strstr (data->events[k].message, "SeaBIOS (version")); -+#endif - -+#if defined(__i386__) || defined(__x86_64__) - /* SeaBIOS. */ - FIND ("seabios", 0, - data->events[j].source == GUESTFS_EVENT_APPLIANCE && - strstr (data->events[j].message, "SeaBIOS (version"), - data->events[k].source == GUESTFS_EVENT_APPLIANCE && -- strstr (data->events[k].message, "Probing EDD")); -+ strstr (data->events[k].message, FIRST_KERNEL_MESSAGE)); -+#endif - -+#if defined(__i386__) || defined(__x86_64__) - /* SeaBIOS - only available when using debug messages. */ - FIND_OPTIONAL ("seabios:pci-probe", 0, - data->events[j].source == GUESTFS_EVENT_APPLIANCE && - strstr (data->events[j].message, "Searching bootorder for: /pci@"), - data->events[k].source == GUESTFS_EVENT_APPLIANCE && - strstr (data->events[k].message, "Scan for option roms")); -+#endif - - /* Find where we run the guest kernel. */ - FIND ("kernel", LONG_ACTIVITY, - data->events[j].source == GUESTFS_EVENT_APPLIANCE && -- strstr (data->events[j].message, "Probing EDD"), -+ strstr (data->events[j].message, FIRST_KERNEL_MESSAGE), - data->events[k].source == GUESTFS_EVENT_CLOSE); - - /* Kernel startup to userspace. */ - FIND ("kernel:overhead", 0, - data->events[j].source == GUESTFS_EVENT_APPLIANCE && -- strstr (data->events[j].message, "Probing EDD"), -+ strstr (data->events[j].message, FIRST_KERNEL_MESSAGE), - data->events[k].source == GUESTFS_EVENT_APPLIANCE && - strstr (data->events[k].message, "supermin:") && - strstr (data->events[k].message, "starting up")); -@@ -277,10 +290,11 @@ construct_timeline (void) - /* The time taken to get into start_kernel function. */ - FIND ("kernel:entry", 0, - data->events[j].source == GUESTFS_EVENT_APPLIANCE && -- strstr (data->events[j].message, "Probing EDD"), -+ strstr (data->events[j].message, FIRST_KERNEL_MESSAGE), - data->events[k].source == GUESTFS_EVENT_APPLIANCE && - strstr (data->events[k].message, "Linux version")); - -+#if defined(__i386__) || defined(__x86_64__) - /* Alternatives patching instructions (XXX not very accurate we - * really need some debug messages inserted into the code). - */ -@@ -289,6 +303,7 @@ construct_timeline (void) - strstr (data->events[j].message, "Last level dTLB entries"), - data->events[k].source == GUESTFS_EVENT_APPLIANCE && - strstr (data->events[k].message, "Freeing SMP alternatives")); -+#endif - - /* ftrace patching instructions. */ - FIND ("kernel:ftrace", 0, -diff --git a/tests/qemu/boot-analysis.c b/tests/qemu/boot-analysis.c -index 444226c..ace4653 100644 ---- a/tests/qemu/boot-analysis.c -+++ b/tests/qemu/boot-analysis.c -@@ -235,8 +235,8 @@ main (int argc, char *argv[]) - - libvirt_log_hack (argc, argv); - -- if (STRNEQ (host_cpu, "x86_64")) -- fprintf (stderr, "WARNING: host_cpu != x86_64: This program may not work or give bogus results.\n"); -+ if (STRNEQ (host_cpu, "x86_64") && STRNEQ (host_cpu, "aarch64")) -+ fprintf (stderr, "WARNING: host_cpu != x86_64|aarch64: This program may not work or give bogus results.\n"); - - run_test (); - } --- -1.8.3.1 - diff --git a/SOURCES/0070-v2v-OVF-Better-mapping-for-inspection-data-to-vmtype.patch b/SOURCES/0070-v2v-OVF-Better-mapping-for-inspection-data-to-vmtype.patch deleted file mode 100644 index fc9c868..0000000 --- a/SOURCES/0070-v2v-OVF-Better-mapping-for-inspection-data-to-vmtype.patch +++ /dev/null @@ -1,108 +0,0 @@ -From 165d9fbc3bb53daff1c1e1336610fba672a9412a Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Tue, 26 Apr 2016 12:27:14 +0100 -Subject: [PATCH] v2v: OVF: Better mapping for inspection data to vmtype. - -The old mapping code was directly copied from old virt-v2v, translated -from Perl to OCaml. - -The new mapping code does a few things more accurately: - - - Use the i_product_variant field (Windows InstallationType) if available. - - - Simplify rules, so there is only one special case needed for RHEL 3/4. - - - Don't assume Fedora == Desktop. - - - Don't assume all later Windows variants are server. - - - Works for Windows > 7. - -(cherry picked from commit 5ec42a62384f87a4de841d202e31d0337c64f5af) ---- - v2v/OVF.ml | 61 ++++++++++++++++++++----------------------------------------- - 1 file changed, 20 insertions(+), 41 deletions(-) - -diff --git a/v2v/OVF.ml b/v2v/OVF.ml -index 8dc3fea..f1d8de5 100644 ---- a/v2v/OVF.ml -+++ b/v2v/OVF.ml -@@ -46,55 +46,34 @@ let iso_time = - * when the [--vmtype] parameter is NOT passed. - *) - let get_vmtype = function -- | { i_type = "linux"; i_distro = "rhel"; i_major_version = major; -+ (* Special cases for RHEL 3 & RHEL 4. *) -+ | { i_type = "linux"; i_distro = "rhel"; i_major_version = (3|4); - i_product_name = product } -- when major >= 5 && String.find product "Server" >= 0 -> -- Server -+ when String.find product "ES" >= 0 -> -+ Server - -- | { i_type = "linux"; i_distro = "rhel"; i_major_version = major } -- when major >= 5 -> -- Desktop -- -- | { i_type = "linux"; i_distro = "rhel"; i_major_version = major; -- i_product_name = product } -- when major >= 3 && String.find product "ES" >= 0 -> -- Server -- -- | { i_type = "linux"; i_distro = "rhel"; i_major_version = major; -+ | { i_type = "linux"; i_distro = "rhel"; i_major_version = (3|4); - i_product_name = product } -- when major >= 3 && String.find product "AS" >= 0 -> -- Server -- -- | { i_type = "linux"; i_distro = "rhel"; i_major_version = major } -- when major >= 3 -> -- Desktop -- -- | { i_type = "linux"; i_distro = "fedora" } -> Desktop -- -- | { i_type = "windows"; i_major_version = 5; i_minor_version = 1 } -> -- Desktop (* Windows XP *) -- -- | { i_type = "windows"; i_major_version = 5; i_minor_version = 2; -- i_product_name = product } when String.find product "XP" >= 0 -> -- Desktop (* Windows XP *) -- -- | { i_type = "windows"; i_major_version = 5; i_minor_version = 2 } -> -- Server (* Windows 2003 *) -+ when String.find product "AS" >= 0 -> -+ Server - -- | { i_type = "windows"; i_major_version = 6; i_minor_version = 0; -- i_product_name = product } when String.find product "Server" >= 0 -> -- Server (* Windows 2008 *) -+ | { i_type = "linux"; i_distro = "rhel"; i_major_version = (3|4) } -> -+ Desktop - -- | { i_type = "windows"; i_major_version = 6; i_minor_version = 0 } -> -- Desktop (* Vista *) -+ (* For Windows (and maybe Linux in future, but it is not set now), -+ * use the i_product_variant field. -+ *) -+ | { i_product_variant = ("Server"|"Server Core"|"Embedded") } -> Server -+ | { i_product_variant = "Client" } -> Desktop - -- | { i_type = "windows"; i_major_version = 6; i_minor_version = 1; -- i_product_name = product } when String.find product "Server" >= 0 -> -- Server (* Windows 2008R2 *) -+ (* If the product name has "Server" or "Desktop" in it, use that. *) -+ | { i_product_name = product } when String.find product "Server" >= 0 -> -+ Server - -- | { i_type = "windows"; i_major_version = 6; i_minor_version = 1 } -> -- Server (* Windows 7 *) -+ | { i_product_name = product } when String.find product "Desktop" >= 0 -> -+ Desktop - -+ (* Otherwise return server, a safe choice. *) - | _ -> Server - - (* Determine the ovf:OperatingSystemSection_Type from libguestfs --- -1.8.3.1 - diff --git a/SOURCES/0071-launch-Disable-USB-in-the-appliance.patch b/SOURCES/0071-launch-Disable-USB-in-the-appliance.patch deleted file mode 100644 index 09b9d83..0000000 --- a/SOURCES/0071-launch-Disable-USB-in-the-appliance.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 7aa71ddf263e09afdcb75013b8582aafd9ca00d4 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Thu, 28 Apr 2016 14:12:23 +0100 -Subject: [PATCH] launch: Disable USB in the appliance. - -Only saves a tiny amount of time, but as we don't use USB -we might as well disable it. - -(cherry picked from commit 29cb8d60d25f650b077e631269ee05c3e4441d75) ---- - src/launch.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/src/launch.c b/src/launch.c -index 98eca07..9f5b14f 100644 ---- a/src/launch.c -+++ b/src/launch.c -@@ -339,6 +339,7 @@ guestfs_int_appliance_command_line (guestfs_h *g, const char *appliance_dev, - " acpi=off" /* ACPI is slow - 150-200ms extra on my laptop */ - " printk.time=1" /* display timestamp before kernel messages */ - " cgroup_disable=memory" /* saves us about 5 MB of RAM */ -+ " usbcore.nousb" /* disable USB, only saves about 1ms */ - "%s" /* root=appliance_dev */ - " %s" /* selinux */ - " %s" /* quiet/verbose */ --- -1.8.3.1 - diff --git a/SOURCES/0072-launch-libvirt-Add-a-dev-urandom-based-virtio-rng-de.patch b/SOURCES/0072-launch-libvirt-Add-a-dev-urandom-based-virtio-rng-de.patch deleted file mode 100644 index 7bdc845..0000000 --- a/SOURCES/0072-launch-libvirt-Add-a-dev-urandom-based-virtio-rng-de.patch +++ /dev/null @@ -1,63 +0,0 @@ -From 3281d502733b198697bd076ae71d278c0e8b1912 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Thu, 28 Apr 2016 15:58:05 +0100 -Subject: [PATCH] launch: libvirt: Add a /dev/urandom-based virtio-rng device - to the appliance. - -It is safe to use /dev/urandom to seed the guest. In libvirt 1.3.4 -this silly restriction has been lifted. - -This restores commit b2c845333f66d4d3135d3b6a8d4b992d6160bf0a. -See also commit 9423c16607259b30985c46d04db9958ec079aa42. - -Thanks: Cole Robinson for doing the libvirt implementation. -(cherry picked from commit 2b9f58f87b0dc2553061b4d8b301ff8e08121cb7) ---- - src/launch-libvirt.c | 29 +++++++++++------------------ - 1 file changed, 11 insertions(+), 18 deletions(-) - -diff --git a/src/launch-libvirt.c b/src/launch-libvirt.c -index 96c5913..4c29409 100644 ---- a/src/launch-libvirt.c -+++ b/src/launch-libvirt.c -@@ -1306,26 +1306,19 @@ construct_libvirt_xml_devices (guestfs_h *g, - } - #endif - --#if 0 -- /* This is disabled. Pulling random numbers from /dev/random -- * causes the appliance to pause for long periods. We should -- * use /dev/urandom, but for bogus reasons libvirt prevents that. -- * https://bugzilla.redhat.com/show_bug.cgi?id=1074464#c7 -+ /* Add a random number generator (backend for virtio-rng). This -+ * requires Cole Robinson's patch to permit /dev/urandom to be -+ * used, which was added in libvirt 1.3.4. - */ -- /* Add a random number generator (backend for virtio-rng). */ -- start_element ("rng") { -- attribute ("model", "virtio"); -- start_element ("backend") { -- attribute ("model", "random"); -- /* It'd be nice to do this, but libvirt says: -- * file '/dev/urandom' is not a supported random source -- * Let libvirt pick /dev/random automatically instead. -- * See also: https://bugzilla.redhat.com/show_bug.cgi?id=1074464 -- */ -- //string ("/dev/urandom"); -+ if (params->data->libvirt_version >= 1003004) { -+ start_element ("rng") { -+ attribute ("model", "virtio"); -+ start_element ("backend") { -+ attribute ("model", "random"); -+ string ("/dev/urandom"); -+ } end_element (); - } end_element (); -- } end_element (); --#endif -+ } - - /* virtio-scsi controller. */ - start_element ("controller") { --- -1.8.3.1 - diff --git a/SOURCES/0073-launch-Don-t-initialize-all-UARTs-serial-ports.patch b/SOURCES/0073-launch-Don-t-initialize-all-UARTs-serial-ports.patch deleted file mode 100644 index a3a134b..0000000 --- a/SOURCES/0073-launch-Don-t-initialize-all-UARTs-serial-ports.patch +++ /dev/null @@ -1,28 +0,0 @@ -From d4a8bb04cc7fd7dbab6501e16b2f4d8a9a92acac Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Thu, 28 Apr 2016 22:37:04 +0100 -Subject: [PATCH] launch: Don't initialize all UARTs (serial ports). - -This doesn't save very much time, perhaps under 1ms, but it avoids -some useless scanning. - -(cherry picked from commit d76129aa0cca856994c1a65b55dc18d2a2049d34) ---- - src/launch.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/src/launch.c b/src/launch.c -index 9f5b14f..04b0e94 100644 ---- a/src/launch.c -+++ b/src/launch.c -@@ -340,6 +340,7 @@ guestfs_int_appliance_command_line (guestfs_h *g, const char *appliance_dev, - " printk.time=1" /* display timestamp before kernel messages */ - " cgroup_disable=memory" /* saves us about 5 MB of RAM */ - " usbcore.nousb" /* disable USB, only saves about 1ms */ -+ " 8250.nr_uarts=1" /* don't scan all 8250 UARTS */ - "%s" /* root=appliance_dev */ - " %s" /* selinux */ - " %s" /* quiet/verbose */ --- -1.8.3.1 - diff --git a/SOURCES/0074-appliance-Add-pciutils-to-the-appliance.patch b/SOURCES/0074-appliance-Add-pciutils-to-the-appliance.patch deleted file mode 100644 index 539652d..0000000 --- a/SOURCES/0074-appliance-Add-pciutils-to-the-appliance.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 6be1f908d1e39c702b35966c5617ace37a187d61 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Sat, 30 Apr 2016 12:48:42 +0100 -Subject: [PATCH] appliance: Add pciutils to the appliance. - -This adds the 'lspci' program, useful for debugging -appliance / qemu problems. - -(cherry picked from commit 03e2d000360ad4e496e8ce6c1b9b01086a2d2aac) ---- - appliance/packagelist.in | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/appliance/packagelist.in b/appliance/packagelist.in -index e93e5e8..6349922 100644 ---- a/appliance/packagelist.in -+++ b/appliance/packagelist.in -@@ -232,6 +232,7 @@ dnl Enabling this pulls out 140 extra packages - dnl into the appliance: - dnl ocfs2-tools - parted -+pciutils - procps - procps-ng - psmisc --- -1.8.3.1 - diff --git a/SOURCES/0075-tests-qemu-boot-analysis-Dump-pass-data-times-in-ms-.patch b/SOURCES/0075-tests-qemu-boot-analysis-Dump-pass-data-times-in-ms-.patch deleted file mode 100644 index 4efbe60..0000000 --- a/SOURCES/0075-tests-qemu-boot-analysis-Dump-pass-data-times-in-ms-.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 4248b89b10c88503e6a2c1e3a476571973b309d6 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Sat, 30 Apr 2016 16:02:30 +0100 -Subject: [PATCH] tests/qemu: boot-analysis: Dump pass data times in ms, with - diffs. - -When (in --verbose mode) we dump the pass data, dump the times in -milliseconds (instead of nanoseconds) so they are consistent with -other output. Also dump the time difference from the previous event. - -Useful for detailed debugging/analysis of problems. - -(cherry picked from commit 2fd05203e461445c8053116b4276beb81b4d95d8) ---- - tests/qemu/boot-analysis.c | 10 ++++++++-- - 1 file changed, 8 insertions(+), 2 deletions(-) - -diff --git a/tests/qemu/boot-analysis.c b/tests/qemu/boot-analysis.c -index ace4653..a203f94 100644 ---- a/tests/qemu/boot-analysis.c -+++ b/tests/qemu/boot-analysis.c -@@ -863,12 +863,18 @@ dump_pass_data (void) - printf (" number of events collected %zu\n", pass_data[i].nr_events); - printf (" elapsed time %" PRIi64 " ns\n", pass_data[i].elapsed_ns); - for (j = 0; j < pass_data[i].nr_events; ++j) { -- int64_t ns; -+ int64_t ns, diff_ns; - CLEANUP_FREE char *event_str = NULL; - - ns = timespec_diff (&pass_data[i].start_t, &pass_data[i].events[j].t); - event_str = guestfs_event_to_string (pass_data[i].events[j].source); -- printf (" #%zu: +%" PRIi64 " [%s] \"", j, ns, event_str); -+ printf (" %.1fms ", ns / 1000000.0); -+ if (j > 0) { -+ diff_ns = timespec_diff (&pass_data[i].events[j-1].t, -+ &pass_data[i].events[j].t); -+ printf ("(+%.1f) ", diff_ns / 1000000.0); -+ } -+ printf ("[%s] \"", event_str); - print_escaped_string (pass_data[i].events[j].message); - printf ("\"\n"); - } --- -1.8.3.1 - diff --git a/SOURCES/0076-tests-qemu-boot-analysis-Display-libvirt-as-distinct.patch b/SOURCES/0076-tests-qemu-boot-analysis-Display-libvirt-as-distinct.patch deleted file mode 100644 index 6173437..0000000 --- a/SOURCES/0076-tests-qemu-boot-analysis-Display-libvirt-as-distinct.patch +++ /dev/null @@ -1,95 +0,0 @@ -From 3c45504da7143d54820cf2b375ed151553c06a4c Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Sat, 30 Apr 2016 16:41:31 +0100 -Subject: [PATCH] tests/qemu: boot-analysis: Display libvirt as distinct - source. - -Don't display libvirt events as '[library]', but as '[libvirt]'. - -(cherry picked from commit 9cd00805b06528f99c9a986195cc46b787541d11) ---- - tests/qemu/boot-analysis.c | 27 +++++++++++++++++++++++---- - tests/qemu/boot-analysis.h | 8 ++++++++ - 2 files changed, 31 insertions(+), 4 deletions(-) - -diff --git a/tests/qemu/boot-analysis.c b/tests/qemu/boot-analysis.c -index a203f94..2067dfc 100644 ---- a/tests/qemu/boot-analysis.c -+++ b/tests/qemu/boot-analysis.c -@@ -781,7 +781,7 @@ libvirt_log_thread (void *arg) - pthread_mutex_lock (&pass_data_lock); - if (libvirt_pass == -1) goto discard; - event = -- add_event_unlocked (&pass_data[libvirt_pass], GUESTFS_EVENT_LIBRARY); -+ add_event_unlocked (&pass_data[libvirt_pass], SOURCE_LIBVIRT); - event->message = strndup (buf, r); - if (event->message == NULL) - error (EXIT_FAILURE, errno, "strndup"); -@@ -864,23 +864,42 @@ dump_pass_data (void) - printf (" elapsed time %" PRIi64 " ns\n", pass_data[i].elapsed_ns); - for (j = 0; j < pass_data[i].nr_events; ++j) { - int64_t ns, diff_ns; -- CLEANUP_FREE char *event_str = NULL; -+ CLEANUP_FREE char *source_str = NULL; - - ns = timespec_diff (&pass_data[i].start_t, &pass_data[i].events[j].t); -- event_str = guestfs_event_to_string (pass_data[i].events[j].source); -+ source_str = source_to_string (pass_data[i].events[j].source); - printf (" %.1fms ", ns / 1000000.0); - if (j > 0) { - diff_ns = timespec_diff (&pass_data[i].events[j-1].t, - &pass_data[i].events[j].t); - printf ("(+%.1f) ", diff_ns / 1000000.0); - } -- printf ("[%s] \"", event_str); -+ printf ("[%s] \"", source_str); - print_escaped_string (pass_data[i].events[j].message); - printf ("\"\n"); - } - } - } - -+/* Convert source to a printable string. The caller must free the -+ * returned string. -+ */ -+char * -+source_to_string (uint64_t source) -+{ -+ char *ret; -+ -+ if (source == SOURCE_LIBVIRT) { -+ ret = strdup ("libvirt"); -+ if (ret == NULL) -+ error (EXIT_FAILURE, errno, "strdup"); -+ } -+ else -+ ret = guestfs_event_to_string (source); -+ -+ return ret; /* caller frees */ -+} -+ - int - activity_exists (const char *name) - { -diff --git a/tests/qemu/boot-analysis.h b/tests/qemu/boot-analysis.h -index 86d403e..a07f12e 100644 ---- a/tests/qemu/boot-analysis.h -+++ b/tests/qemu/boot-analysis.h -@@ -46,6 +46,14 @@ struct pass_data { - int seen_launch; - }; - -+/* The 'source' field in the event is a guestfs event -+ * (GUESTFS_EVENT_*). We also wish to encode libvirt as a source, so -+ * we use a magic/impossible value for that here. Note that events -+ * are bitmasks, and normally no more than one bit may be set. -+ */ -+#define SOURCE_LIBVIRT ((uint64_t)~0) -+extern char *source_to_string (uint64_t source); -+ - struct event { - struct timespec t; - uint64_t source; --- -1.8.3.1 - diff --git a/SOURCES/0077-launch-Add-cryptomgr.notests-to-the-appliance-comman.patch b/SOURCES/0077-launch-Add-cryptomgr.notests-to-the-appliance-comman.patch deleted file mode 100644 index feadbd8..0000000 --- a/SOURCES/0077-launch-Add-cryptomgr.notests-to-the-appliance-comman.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 9d72134f9b6c1b2391ee75973971f414eb2c83a1 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Sat, 30 Apr 2016 12:49:00 +0100 -Subject: [PATCH] launch: Add cryptomgr.notests to the appliance command line. - -Save 28ms by not running the crypto self-tests when Linux boots. - -(cherry picked from commit c34995c6b3a60c78aefd12ad73f6c453a127a8ad) ---- - src/launch.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/src/launch.c b/src/launch.c -index 04b0e94..e7cb325 100644 ---- a/src/launch.c -+++ b/src/launch.c -@@ -340,6 +340,7 @@ guestfs_int_appliance_command_line (guestfs_h *g, const char *appliance_dev, - " printk.time=1" /* display timestamp before kernel messages */ - " cgroup_disable=memory" /* saves us about 5 MB of RAM */ - " usbcore.nousb" /* disable USB, only saves about 1ms */ -+ " cryptomgr.notests" /* disable crypto tests, saves 28ms */ - " 8250.nr_uarts=1" /* don't scan all 8250 UARTS */ - "%s" /* root=appliance_dev */ - " %s" /* selinux */ --- -1.8.3.1 - diff --git a/SOURCES/0078-utils-Move-tests-qemu-boot-analysis-etc-tools-to-new.patch b/SOURCES/0078-utils-Move-tests-qemu-boot-analysis-etc-tools-to-new.patch deleted file mode 100644 index 351ace5..0000000 --- a/SOURCES/0078-utils-Move-tests-qemu-boot-analysis-etc-tools-to-new.patch +++ /dev/null @@ -1,7329 +0,0 @@ -From 5b03f23e01dfeb68846fcd280ba6ee9d4dd6113a Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Tue, 3 May 2016 11:53:57 +0100 -Subject: [PATCH] utils: Move tests/qemu/ boot-analysis etc tools to new utils - top level directory. - -Create a new top level directory called 'utils' and move the -following programs there: - - tests/qemu/boot-analysis -> utils/boot-analysis/ - tests/qemu/boot-benchmark -> utils/boot-benchmark/ - tests/qemu/qemu-boot -> utils/qemu-boot/ - tests/qemu/qemu-speed-test -> utils/qemu-speed-test/ - -Also we only build the boot-analysis program on x86-64 and aarch64, -since it requires custom porting to each architecture. - -(cherry picked from commit 3b581a727c9e906f9d9b10e2f73ed853ab324fd0) ---- - .gitignore | 8 +- - Makefile.am | 9 + - configure.ac | 10 +- - docs/guestfs-hacking.pod | 4 + - docs/guestfs-performance.pod | 30 +- - m4/guestfs_misc.m4 | 28 + - po/POTFILES | 7 + - tests/qemu/Makefile.am | 87 +- - tests/qemu/boot-analysis-timeline.c | 523 ----------- - tests/qemu/boot-analysis-utils.c | 90 -- - tests/qemu/boot-analysis-utils.h | 36 - - tests/qemu/boot-analysis.c | 1269 -------------------------- - tests/qemu/boot-analysis.h | 102 --- - tests/qemu/boot-benchmark-range.pl | 240 ----- - tests/qemu/boot-benchmark.c | 225 ----- - tests/qemu/qemu-boot.c | 362 -------- - tests/qemu/qemu-speed-test.c | 480 ---------- - utils/boot-analysis/Makefile.am | 43 + - utils/boot-analysis/boot-analysis-timeline.c | 523 +++++++++++ - utils/boot-analysis/boot-analysis-utils.c | 90 ++ - utils/boot-analysis/boot-analysis-utils.h | 36 + - utils/boot-analysis/boot-analysis.c | 1268 +++++++++++++++++++++++++ - utils/boot-analysis/boot-analysis.h | 102 +++ - utils/boot-benchmark/Makefile.am | 44 + - utils/boot-benchmark/boot-benchmark-range.pl | 240 +++++ - utils/boot-benchmark/boot-benchmark.c | 225 +++++ - utils/qemu-boot/Makefile.am | 39 + - utils/qemu-boot/qemu-boot.c | 362 ++++++++ - utils/qemu-speed-test/Makefile.am | 36 + - utils/qemu-speed-test/qemu-speed-test.c | 480 ++++++++++ - 30 files changed, 3562 insertions(+), 3436 deletions(-) - create mode 100644 m4/guestfs_misc.m4 - delete mode 100644 tests/qemu/boot-analysis-timeline.c - delete mode 100644 tests/qemu/boot-analysis-utils.c - delete mode 100644 tests/qemu/boot-analysis-utils.h - delete mode 100644 tests/qemu/boot-analysis.c - delete mode 100644 tests/qemu/boot-analysis.h - delete mode 100755 tests/qemu/boot-benchmark-range.pl - delete mode 100644 tests/qemu/boot-benchmark.c - delete mode 100644 tests/qemu/qemu-boot.c - delete mode 100644 tests/qemu/qemu-speed-test.c - create mode 100644 utils/boot-analysis/Makefile.am - create mode 100644 utils/boot-analysis/boot-analysis-timeline.c - create mode 100644 utils/boot-analysis/boot-analysis-utils.c - create mode 100644 utils/boot-analysis/boot-analysis-utils.h - create mode 100644 utils/boot-analysis/boot-analysis.c - create mode 100644 utils/boot-analysis/boot-analysis.h - create mode 100644 utils/boot-benchmark/Makefile.am - create mode 100755 utils/boot-benchmark/boot-benchmark-range.pl - create mode 100644 utils/boot-benchmark/boot-benchmark.c - create mode 100644 utils/qemu-boot/Makefile.am - create mode 100644 utils/qemu-boot/qemu-boot.c - create mode 100644 utils/qemu-speed-test/Makefile.am - create mode 100644 utils/qemu-speed-test/qemu-speed-test.c - -diff --git a/.gitignore b/.gitignore -index 46a6e65..d79dc98 100644 ---- a/.gitignore -+++ b/.gitignore -@@ -509,10 +509,6 @@ Makefile.in - /tests/mountable/test-internal-parse-mountable - /tests/parallel/test-parallel - /tests/protocol/test-error-messages --/tests/qemu/boot-analysis --/tests/qemu/boot-benchmark --/tests/qemu/qemu-boot --/tests/qemu/qemu-speed-test - /tests/regressions/rhbz501893 - /tests/regressions/rhbz790721 - /tests/regressions/rhbz914931 -@@ -561,6 +557,10 @@ Makefile.in - /test-tool/stamp-libguestfs-test-tool.pod - /tools/stamp-virt-*.pod - /tools/virt-*.1 -+/utils/boot-analysis/boot-analysis -+/utils/boot-benchmark/boot-benchmark -+/utils/qemu-boot/qemu-boot -+/utils/qemu-speed-test/qemu-speed-test - /v2v/.depend - /v2v/centos-6.img - /v2v/centos-7.0.img -diff --git a/Makefile.am b/Makefile.am -index c77fc34..079aa7d 100644 ---- a/Makefile.am -+++ b/Makefile.am -@@ -165,6 +165,15 @@ if HAVE_FUSE - SUBDIRS += fuse - endif - -+# Miscellaneous utilities. -+if HAVE_BOOT_ANALYSIS -+SUBDIRS += utils/boot-analysis -+endif -+SUBDIRS += \ -+ utils/boot-benchmark \ -+ utils/qemu-boot \ -+ utils/qemu-speed-test -+ - # po-docs must come after tools, inspector. - if HAVE_PO4A - SUBDIRS += po-docs -diff --git a/configure.ac b/configure.ac -index 6cef0a7..0bff74f 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -124,10 +124,8 @@ m4_include([m4/guestfs_gobject.m4]) - dnl Bash completion. - m4_include([m4/guestfs_bash_completion.m4]) - --dnl Replace libtool with a wrapper that clobbers dependency_libs in *.la files --dnl http://lists.fedoraproject.org/pipermail/devel/2010-November/146343.html --LIBTOOL='bash $(top_srcdir)/libtool-kill-dependency_libs.sh $(top_builddir)/libtool' --AC_SUBST([LIBTOOL]) -+dnl Miscellaneous configuration that doesn't fit anywhere else. -+m4_include([m4/guestfs_misc.m4]) - - dnl Work around autoconf's lack of expanded variables. - eval my_sysconfdir="\"[$]sysconfdir\"" -@@ -283,6 +281,10 @@ AC_CONFIG_FILES([Makefile - tests/xfs/Makefile - tests/xml/Makefile - tools/Makefile -+ utils/boot-analysis/Makefile -+ utils/boot-benchmark/Makefile -+ utils/qemu-boot/Makefile -+ utils/qemu-speed-test/Makefile - v2v/Makefile - v2v/test-harness/Makefile - v2v/test-harness/META -diff --git a/docs/guestfs-hacking.pod b/docs/guestfs-hacking.pod -index 756c6f2..f2f8207 100644 ---- a/docs/guestfs-hacking.pod -+++ b/docs/guestfs-hacking.pod -@@ -694,6 +694,10 @@ created by another. - - Command line tools written in Perl (L and many others). - -+=item F -+ -+Miscellaneous utilities, such as C. -+ - =item F - - L command and documentation. -diff --git a/docs/guestfs-performance.pod b/docs/guestfs-performance.pod -index d9c76ac..7304b63 100644 ---- a/docs/guestfs-performance.pod -+++ b/docs/guestfs-performance.pod -@@ -30,13 +30,13 @@ Run this command several times in a row and discard the first few - runs, so that you are measuring a typical "hot cache" case. - - I If you are compiling libguestfs from --source, there is a program called F which --does the same thing, but performs multiple runs and prints the mean --and standard deviation. To run it, do: -+source, there is a program called -+F which does the same thing, but -+performs multiple runs and prints the mean and standard deviation. To -+run it, do: - - make -- make -C tests/qemu boot-benchmark -- ./run ./tests/qemu/boot-benchmark -+ ./run utils/boot-benchmark/boot-benchmark - - =head3 Explanation - -@@ -442,17 +442,16 @@ not available. - - =head2 Boot analysis - --In the libguestfs source directory, in F is a program --called C. This program is able to produce a very --detailed breakdown of the boot steps (eg. qemu, BIOS, kernel, -+In the libguestfs source directory, in F is a -+program called C. This program is able to produce a -+very detailed breakdown of the boot steps (eg. qemu, BIOS, kernel, - libguestfs init script), and can measure how long it takes to perform - each step. - - To run this program, do: - - make -- make -C tests/qemu boot-analysis -- ./run ./tests/qemu/boot-analysis -+ ./run utils/boot-analysis/boot-analysis - - =head2 Detailed timings using ts - -@@ -594,14 +593,15 @@ bit. - Sometimes performance regressions happen in other programs (eg. qemu, - the kernel) that cause problems for libguestfs. - --In the libguestfs source, F is a --script which can be used to benchmark libguestfs across a range of git --commits in another project to find out if any commit is causing a --slowdown (or speedup). -+In the libguestfs source, -+F is a script which can -+be used to benchmark libguestfs across a range of git commits in -+another project to find out if any commit is causing a slowdown (or -+speedup). - - To find out how to use this script, consult the manual: - -- ./tests/qemu/boot-benchmark-range.pl --man -+ ./utils/boot-benchmark/boot-benchmark-range.pl --man - - =head1 SEE ALSO - -diff --git a/m4/guestfs_misc.m4 b/m4/guestfs_misc.m4 -new file mode 100644 -index 0000000..e6f4b05 ---- /dev/null -+++ b/m4/guestfs_misc.m4 -@@ -0,0 +1,28 @@ -+# libguestfs -+# Copyright (C) 2009-2016 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. -+ -+dnl Miscellaneous configuration that doesn't fit anywhere else. -+ -+dnl Replace libtool with a wrapper that clobbers dependency_libs in *.la files -+dnl http://lists.fedoraproject.org/pipermail/devel/2010-November/146343.html -+LIBTOOL='bash $(top_srcdir)/libtool-kill-dependency_libs.sh $(top_builddir)/libtool' -+AC_SUBST([LIBTOOL]) -+ -+dnl Only build boot-analysis program on x86-64 and aarch64. It -+dnl requires custom work to port to each architecture. -+AM_CONDITIONAL([HAVE_BOOT_ANALYSIS], -+ [test "$host_cpu" = "x86_64" || test "$host_cpu" = "aarch64"]) -diff --git a/po/POTFILES b/po/POTFILES -index a5f3f9e..ebee244 100644 ---- a/po/POTFILES -+++ b/po/POTFILES -@@ -359,6 +359,13 @@ src/utils.c - src/wait.c - src/whole-file.c - test-tool/test-tool.c -+utils/boot-analysis/boot-analysis-timeline.c -+utils/boot-analysis/boot-analysis-utils.c -+utils/boot-analysis/boot-analysis.c -+utils/boot-benchmark/boot-benchmark-range.pl -+utils/boot-benchmark/boot-benchmark.c -+utils/qemu-boot/qemu-boot.c -+utils/qemu-speed-test/qemu-speed-test.c - v2v/changeuid-c.c - v2v/domainxml-c.c - v2v/utils-c.c -diff --git a/tests/qemu/Makefile.am b/tests/qemu/Makefile.am -index f2171cd..472788a 100644 ---- a/tests/qemu/Makefile.am -+++ b/tests/qemu/Makefile.am -@@ -28,92 +28,7 @@ TESTS = \ - - TESTS_ENVIRONMENT = $(top_builddir)/run --test - --EXTRA_DIST = \ -- $(TESTS) \ -- boot-benchmark-range.pl \ -- qemu-boot.c \ -- qemu-speed-test.c -- --# qemu-boot, qemu-speed-test, boot-analysis and boot-benchmark are --# built but not run by default as they are mainly qemu & kernel --# diagnostic tools. -- --check_PROGRAMS = qemu-boot qemu-speed-test boot-analysis boot-benchmark -- --qemu_boot_SOURCES = \ -- ../../df/estimate-max-threads.c \ -- ../../df/estimate-max-threads.h \ -- qemu-boot.c --qemu_boot_CPPFLAGS = \ -- -I$(top_srcdir)/gnulib/lib -I$(top_builddir)/gnulib/lib \ -- -I$(top_srcdir)/src -I$(top_builddir)/src \ -- -I$(top_srcdir)/df --qemu_boot_CFLAGS = \ -- -pthread \ -- $(WARN_CFLAGS) $(WERROR_CFLAGS) --qemu_boot_LDADD = \ -- $(top_builddir)/src/libutils.la \ -- $(top_builddir)/src/libguestfs.la \ -- $(LIBXML2_LIBS) \ -- $(LIBVIRT_LIBS) \ -- $(LTLIBINTL) \ -- $(top_builddir)/gnulib/lib/libgnu.la -- --qemu_speed_test_SOURCES = \ -- qemu-speed-test.c --qemu_speed_test_CPPFLAGS = \ -- -I$(top_srcdir)/gnulib/lib -I$(top_builddir)/gnulib/lib \ -- -I$(top_srcdir)/src -I$(top_builddir)/src \ -- -I$(top_srcdir)/df --qemu_speed_test_CFLAGS = \ -- $(WARN_CFLAGS) $(WERROR_CFLAGS) --qemu_speed_test_LDADD = \ -- $(top_builddir)/src/libutils.la \ -- $(top_builddir)/src/libguestfs.la \ -- $(LIBXML2_LIBS) \ -- $(LIBVIRT_LIBS) \ -- $(LTLIBINTL) \ -- $(top_builddir)/gnulib/lib/libgnu.la -- --boot_analysis_SOURCES = \ -- boot-analysis.c \ -- boot-analysis.h \ -- boot-analysis-timeline.c \ -- boot-analysis-utils.c \ -- boot-analysis-utils.h --boot_analysis_CPPFLAGS = \ -- -I$(top_srcdir)/gnulib/lib -I$(top_builddir)/gnulib/lib \ -- -I$(top_srcdir)/src -I$(top_builddir)/src --boot_analysis_CFLAGS = \ -- -pthread \ -- $(WARN_CFLAGS) $(WERROR_CFLAGS) \ -- $(PCRE_CFLAGS) --boot_analysis_LDADD = \ -- $(top_builddir)/src/libutils.la \ -- $(top_builddir)/src/libguestfs.la \ -- $(PCRE_LIBS) \ -- $(LIBXML2_LIBS) \ -- $(LIBVIRT_LIBS) \ -- $(LTLIBINTL) \ -- $(top_builddir)/gnulib/lib/libgnu.la \ -- -lm -- --boot_benchmark_SOURCES = \ -- boot-benchmark.c \ -- boot-analysis-utils.c \ -- boot-analysis-utils.h --boot_benchmark_CPPFLAGS = \ -- -I$(top_srcdir)/gnulib/lib -I$(top_builddir)/gnulib/lib \ -- -I$(top_srcdir)/src -I$(top_builddir)/src --boot_benchmark_CFLAGS = \ -- $(WARN_CFLAGS) $(WERROR_CFLAGS) --boot_benchmark_LDADD = \ -- $(top_builddir)/src/libutils.la \ -- $(top_builddir)/src/libguestfs.la \ -- $(LIBXML2_LIBS) \ -- $(LTLIBINTL) \ -- $(top_builddir)/gnulib/lib/libgnu.la \ -- -lm -+EXTRA_DIST = $(TESTS) - - # Don't run these tests in parallel, since they are designed to check - # the integrity of qemu. -diff --git a/tests/qemu/boot-analysis-timeline.c b/tests/qemu/boot-analysis-timeline.c -deleted file mode 100644 -index 09a78ef..0000000 ---- a/tests/qemu/boot-analysis-timeline.c -+++ /dev/null -@@ -1,523 +0,0 @@ --/* libguestfs -- * Copyright (C) 2016 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 -- --#include --#include --#include --#include --#include --#include --#include --#include --#include -- --#include -- --#include "ignore-value.h" -- --#include "guestfs.h" --#include "guestfs-internal-frontend.h" -- --#include "boot-analysis.h" -- --COMPILE_REGEXP(re_initcall_calling_module, -- "calling ([_A-Za-z0-9]+)\\+.*\\[([_A-Za-z0-9]+)]", 0) --COMPILE_REGEXP(re_initcall_calling, -- "calling ([_A-Za-z0-9]+)\\+", 0) -- --static void construct_initcall_timeline (void); -- --/* "supermin: internal insmod xx.ko" -> "insmod xx.ko" */ --static char * --translate_supermin_insmod_message (const char *message) --{ -- char *ret; -- -- assert (STRPREFIX (message, "supermin: internal ")); -- -- ret = strdup (message + strlen ("supermin: internal ")); -- if (ret == NULL) -- error (EXIT_FAILURE, errno, "strdup"); -- return ret; --} -- --/* Analyze significant events from the events array, to form a -- * timeline of activities. -- */ --void --construct_timeline (void) --{ -- size_t i, j, k; -- struct pass_data *data; -- struct activity *activity; -- -- for (i = 0; i < NR_TEST_PASSES; ++i) { -- data = &pass_data[i]; -- -- /* Find an activity, by matching an event with the condition -- * `begin_cond' through to the second event `end_cond'. Create an -- * activity object in the timeline from the result. -- */ --#define FIND(name, flags, begin_cond, end_cond) \ -- do { \ -- activity = NULL; \ -- for (j = 0; j < data->nr_events; ++j) { \ -- if (begin_cond) { \ -- for (k = j+1; k < data->nr_events; ++k) { \ -- if (end_cond) { \ -- if (i == 0) \ -- activity = add_activity (name, flags); \ -- else \ -- activity = find_activity (name); \ -- break; \ -- } \ -- } \ -- break; \ -- } \ -- } \ -- if (activity) { \ -- activity->start_event[i] = j; \ -- activity->end_event[i] = k; \ -- } \ -- else \ -- error (EXIT_FAILURE, 0, "could not find activity '%s' in pass '%zu'", \ -- name, i); \ -- } while (0) -- -- /* Same as FIND() macro, but if no matching events are found, -- * ignore it. -- */ --#define FIND_OPTIONAL(name, flags, begin_cond, end_cond) \ -- do { \ -- activity = NULL; \ -- for (j = 0; j < data->nr_events; ++j) { \ -- if (begin_cond) { \ -- for (k = j+1; k < data->nr_events; ++k) { \ -- if (end_cond) { \ -- if (i == 0) \ -- activity = add_activity (name, flags); \ -- else \ -- activity = find_activity (name); \ -- break; \ -- } \ -- } \ -- break; \ -- } \ -- } \ -- if (activity) { \ -- activity->start_event[i] = j; \ -- activity->end_event[i] = k; \ -- } \ -- } while (0) -- -- /* Find multiple entries, where we check for: -- * next_cond -- * next_cond -- * next_cond -- * end_cond -- */ --#define FIND_MULTIPLE(debug_name, flags, next_cond, end_cond, translate_message) \ -- do { \ -- activity = NULL; \ -- for (j = 0; j < data->nr_events; ++j) { \ -- if (next_cond) { \ -- CLEANUP_FREE char *message = translate_message (data->events[j].message); \ -- if (activity) \ -- activity->end_event[i] = j; \ -- if (i == 0) \ -- activity = add_activity (message, flags); \ -- else \ -- activity = find_activity (message); \ -- activity->start_event[i] = j; \ -- } \ -- else if (end_cond) \ -- break; \ -- } \ -- if (j < data->nr_events && activity) \ -- activity->end_event[i] = j; \ -- else \ -- error (EXIT_FAILURE, 0, "could not find activity '%s' in pass '%zu'", \ -- debug_name, i); \ -- } while (0) -- -- /* Add one activity which is going to cover the whole process -- * from launch to close. The launch event is always event 0. -- * NB: This activity must be called "run" (see below). -- */ -- FIND ("run", LONG_ACTIVITY, -- j == 0, data->events[k].source == GUESTFS_EVENT_CLOSE); -- -- /* Find where we invoke supermin --build. This should be a null -- * operation, but it still takes time to run the external command. -- */ -- FIND ("supermin:build", 0, -- data->events[j].source == GUESTFS_EVENT_LIBRARY && -- strstr (data->events[j].message, -- "begin building supermin appliance"), -- data->events[k].source == GUESTFS_EVENT_LIBRARY && -- strstr (data->events[k].message, -- "finished building supermin appliance")); -- -- /* Find where we invoke qemu to test features. */ -- FIND_OPTIONAL ("qemu:feature-detect", 0, -- data->events[j].source == GUESTFS_EVENT_LIBRARY && -- strstr (data->events[j].message, -- "begin testing qemu features"), -- data->events[k].source == GUESTFS_EVENT_LIBRARY && -- strstr (data->events[k].message, -- "finished testing qemu features")); -- -- /* Find where we run qemu. */ -- FIND_OPTIONAL ("qemu", LONG_ACTIVITY, -- data->events[j].source == GUESTFS_EVENT_APPLIANCE && -- strstr (data->events[j].message, "-nodefconfig"), -- data->events[k].source == GUESTFS_EVENT_CLOSE); -- -- /* For the libvirt backend, connecting to libvirt, getting -- * capabilities, parsing capabilities etc. -- */ -- FIND_OPTIONAL ("libvirt:connect", 0, -- data->events[j].source == GUESTFS_EVENT_LIBRARY && -- strstr (data->events[j].message, "connect to libvirt"), -- data->events[k].source == GUESTFS_EVENT_LIBRARY && -- strstr (data->events[k].message, "successfully opened libvirt handle")); -- FIND_OPTIONAL ("libvirt:get-libvirt-capabilities", 0, -- data->events[j].source == GUESTFS_EVENT_LIBRARY && -- strstr (data->events[j].message, "get libvirt capabilities"), -- data->events[k].source == GUESTFS_EVENT_LIBRARY && -- strstr (data->events[k].message, "parsing capabilities XML")); -- -- FIND_OPTIONAL ("libguestfs:parse-libvirt-capabilities", 0, -- data->events[j].source == GUESTFS_EVENT_LIBRARY && -- strstr (data->events[j].message, "parsing capabilities XML"), -- data->events[k].source == GUESTFS_EVENT_LIBRARY && -- strstr (data->events[k].message, "get_backend_setting")); -- -- FIND_OPTIONAL ("libguestfs:create-libvirt-xml", 0, -- data->events[j].source == GUESTFS_EVENT_LIBRARY && -- strstr (data->events[j].message, "create libvirt XML"), -- data->events[k].source == GUESTFS_EVENT_LIBRARY && -- strstr (data->events[k].message, "libvirt XML:")); -- --#if defined(__aarch64__) --#define FIRST_KERNEL_MESSAGE "Booting Linux on physical CPU" --#define FIRST_FIRMWARE_MESSAGE "UEFI firmware starting" --#else --#define SGABIOS_STRING "\033[1;256r\033[256;256H\033[6n" --#define FIRST_KERNEL_MESSAGE "Probing EDD" --#define FIRST_FIRMWARE_MESSAGE SGABIOS_STRING --#endif -- -- /* For the libvirt backend, find the overhead of libvirt. */ -- FIND_OPTIONAL ("libvirt:overhead", 0, -- data->events[j].source == GUESTFS_EVENT_LIBRARY && -- strstr (data->events[j].message, "launch libvirt guest"), -- data->events[k].source == GUESTFS_EVENT_APPLIANCE && -- strstr (data->events[k].message, FIRST_FIRMWARE_MESSAGE)); -- -- /* From starting qemu up to entering the BIOS is the qemu overhead. */ -- FIND_OPTIONAL ("qemu:overhead", 0, -- data->events[j].source == GUESTFS_EVENT_APPLIANCE && -- strstr (data->events[j].message, "-nodefconfig"), -- data->events[k].source == GUESTFS_EVENT_APPLIANCE && -- strstr (data->events[k].message, FIRST_FIRMWARE_MESSAGE)); -- -- /* From entering the BIOS to starting the kernel is the BIOS overhead. */ -- FIND_OPTIONAL ("bios:overhead", 0, -- data->events[j].source == GUESTFS_EVENT_APPLIANCE && -- strstr (data->events[j].message, FIRST_FIRMWARE_MESSAGE), -- data->events[k].source == GUESTFS_EVENT_APPLIANCE && -- strstr (data->events[k].message, FIRST_KERNEL_MESSAGE)); -- --#if defined(__i386__) || defined(__x86_64__) -- /* SGABIOS (option ROM). */ -- FIND_OPTIONAL ("sgabios", 0, -- data->events[j].source == GUESTFS_EVENT_APPLIANCE && -- strstr (data->events[j].message, SGABIOS_STRING), -- data->events[k].source == GUESTFS_EVENT_APPLIANCE && -- strstr (data->events[k].message, "SeaBIOS (version")); --#endif -- --#if defined(__i386__) || defined(__x86_64__) -- /* SeaBIOS. */ -- FIND ("seabios", 0, -- data->events[j].source == GUESTFS_EVENT_APPLIANCE && -- strstr (data->events[j].message, "SeaBIOS (version"), -- data->events[k].source == GUESTFS_EVENT_APPLIANCE && -- strstr (data->events[k].message, FIRST_KERNEL_MESSAGE)); --#endif -- --#if defined(__i386__) || defined(__x86_64__) -- /* SeaBIOS - only available when using debug messages. */ -- FIND_OPTIONAL ("seabios:pci-probe", 0, -- data->events[j].source == GUESTFS_EVENT_APPLIANCE && -- strstr (data->events[j].message, "Searching bootorder for: /pci@"), -- data->events[k].source == GUESTFS_EVENT_APPLIANCE && -- strstr (data->events[k].message, "Scan for option roms")); --#endif -- -- /* Find where we run the guest kernel. */ -- FIND ("kernel", LONG_ACTIVITY, -- data->events[j].source == GUESTFS_EVENT_APPLIANCE && -- strstr (data->events[j].message, FIRST_KERNEL_MESSAGE), -- data->events[k].source == GUESTFS_EVENT_CLOSE); -- -- /* Kernel startup to userspace. */ -- FIND ("kernel:overhead", 0, -- data->events[j].source == GUESTFS_EVENT_APPLIANCE && -- strstr (data->events[j].message, FIRST_KERNEL_MESSAGE), -- data->events[k].source == GUESTFS_EVENT_APPLIANCE && -- strstr (data->events[k].message, "supermin:") && -- strstr (data->events[k].message, "starting up")); -- -- /* The time taken to get into start_kernel function. */ -- FIND ("kernel:entry", 0, -- data->events[j].source == GUESTFS_EVENT_APPLIANCE && -- strstr (data->events[j].message, FIRST_KERNEL_MESSAGE), -- data->events[k].source == GUESTFS_EVENT_APPLIANCE && -- strstr (data->events[k].message, "Linux version")); -- --#if defined(__i386__) || defined(__x86_64__) -- /* Alternatives patching instructions (XXX not very accurate we -- * really need some debug messages inserted into the code). -- */ -- FIND ("kernel:alternatives", 0, -- data->events[j].source == GUESTFS_EVENT_APPLIANCE && -- strstr (data->events[j].message, "Last level dTLB entries"), -- data->events[k].source == GUESTFS_EVENT_APPLIANCE && -- strstr (data->events[k].message, "Freeing SMP alternatives")); --#endif -- -- /* ftrace patching instructions. */ -- FIND ("kernel:ftrace", 0, -- data->events[j].source == GUESTFS_EVENT_APPLIANCE && -- strstr (data->events[j].message, "ftrace: allocating"), -- 1); -- -- /* All initcall functions, before we enter userspace. */ -- FIND ("kernel:initcalls-before-userspace", 0, -- data->events[j].source == GUESTFS_EVENT_APPLIANCE && -- strstr (data->events[j].message, "calling "), -- data->events[k].source == GUESTFS_EVENT_APPLIANCE && -- strstr (data->events[k].message, "Freeing unused kernel memory")); -- -- /* Find where we run supermin mini-initrd. */ -- FIND ("supermin:mini-initrd", 0, -- data->events[j].source == GUESTFS_EVENT_APPLIANCE && -- strstr (data->events[j].message, "supermin:") && -- strstr (data->events[j].message, "starting up"), -- data->events[k].source == GUESTFS_EVENT_APPLIANCE && -- strstr (data->events[k].message, "supermin: chroot")); -- -- /* Loading kernel modules from supermin initrd. */ -- FIND_MULTIPLE -- ("supermin insmod", 0, -- data->events[j].source == GUESTFS_EVENT_APPLIANCE && -- strstr (data->events[j].message, "supermin: internal insmod"), -- data->events[j].source == GUESTFS_EVENT_APPLIANCE && -- strstr (data->events[j].message, "supermin: picked"), -- translate_supermin_insmod_message); -- -- /* Find where we run the /init script. */ -- FIND ("/init", 0, -- data->events[j].source == GUESTFS_EVENT_APPLIANCE && -- strstr (data->events[j].message, "supermin: chroot"), -- data->events[k].source == GUESTFS_EVENT_APPLIANCE && -- strstr (data->events[k].message, "guestfsd --verbose")); -- -- /* Everything from the chroot to the first echo in the /init -- * script counts as bash overhead. -- */ -- FIND ("bash:overhead", 0, -- data->events[j].source == GUESTFS_EVENT_APPLIANCE && -- strstr (data->events[j].message, "supermin: chroot"), -- data->events[k].source == GUESTFS_EVENT_APPLIANCE && -- strstr (data->events[k].message, "Starting /init script")); -- -- /* /init: Mount special filesystems. */ -- FIND ("/init:mount-special", 0, -- data->events[j].source == GUESTFS_EVENT_APPLIANCE && -- strstr (data->events[j].message, "*guestfs_boot_analysis=1*"), -- data->events[k].source == GUESTFS_EVENT_APPLIANCE && -- strstr (data->events[k].message, "kmod static-nodes")); -- -- /* /init: Run kmod static-nodes */ -- FIND ("/init:kmod-static-nodes", 0, -- data->events[j].source == GUESTFS_EVENT_APPLIANCE && -- strstr (data->events[j].message, "kmod static-nodes"), -- data->events[k].source == GUESTFS_EVENT_APPLIANCE && -- strstr (data->events[k].message, "systemd-tmpfiles")); -- -- /* /init: systemd-tmpfiles. */ -- FIND ("/init:systemd-tmpfiles", 0, -- data->events[j].source == GUESTFS_EVENT_APPLIANCE && -- strstr (data->events[j].message, "systemd-tmpfiles"), -- data->events[k].source == GUESTFS_EVENT_APPLIANCE && -- strstr (data->events[k].message, "udev")); -- -- /* /init: start udevd. */ -- FIND ("/init:udev-overhead", 0, -- data->events[j].source == GUESTFS_EVENT_APPLIANCE && -- strstr (data->events[j].message, "udevd --daemon"), -- data->events[k].source == GUESTFS_EVENT_APPLIANCE && -- strstr (data->events[k].message, "nullglob")); -- -- /* /init: set up network. */ -- FIND ("/init:network-overhead", 0, -- data->events[j].source == GUESTFS_EVENT_APPLIANCE && -- strstr (data->events[j].message, "+ ip addr"), -- data->events[k].source == GUESTFS_EVENT_APPLIANCE && -- strstr (data->events[k].message, "+ test")); -- -- /* /init: probe MD arrays. */ -- FIND ("/init:md-probe", 0, -- data->events[j].source == GUESTFS_EVENT_APPLIANCE && -- strstr (data->events[j].message, "+ mdadm"), -- data->events[k].source == GUESTFS_EVENT_APPLIANCE && -- strstr (data->events[k].message, "+ modprobe dm_mod")); -- -- /* /init: probe DM/LVM. */ -- FIND ("/init:lvm-probe", 0, -- data->events[j].source == GUESTFS_EVENT_APPLIANCE && -- strstr (data->events[j].message, "+ modprobe dm_mod"), -- data->events[k].source == GUESTFS_EVENT_APPLIANCE && -- strstr (data->events[k].message, "+ ldmtool")); -- -- /* /init: probe Windows dynamic disks. */ -- FIND ("/init:windows-dynamic-disks-probe", 0, -- data->events[j].source == GUESTFS_EVENT_APPLIANCE && -- strstr (data->events[j].message, "+ ldmtool"), -- data->events[k].source == GUESTFS_EVENT_APPLIANCE && -- strstr (data->events[k].message, "+ test")); -- -- /* Find where we run guestfsd. */ -- FIND ("guestfsd", 0, -- data->events[j].source == GUESTFS_EVENT_APPLIANCE && -- strstr (data->events[j].message, "guestfsd --verbose"), -- data->events[k].source == GUESTFS_EVENT_APPLIANCE && -- strstr (data->events[k].message, "fsync /dev/sda")); -- -- /* Shutdown process. */ -- FIND ("shutdown", 0, -- data->events[j].source == GUESTFS_EVENT_TRACE && -- STREQ (data->events[j].message, "close"), -- data->events[k].source == GUESTFS_EVENT_CLOSE); -- } -- -- construct_initcall_timeline (); --} -- --/* Handling of initcall is so peculiar that we hide it in a separate -- * function from the rest. -- */ --static void --construct_initcall_timeline (void) --{ -- size_t i, j, k; -- struct pass_data *data; -- struct activity *activity; -- -- for (i = 0; i < NR_TEST_PASSES; ++i) { -- data = &pass_data[i]; -- -- /* Each kernel initcall is bracketed by: -- * -- * calling ehci_hcd_init+0x0/0xc1 @ 1" -- * initcall ehci_hcd_init+0x0/0xc1 returned 0 after 420 usecs" -- * -- * For initcall functions in modules: -- * -- * calling virtio_mmio_init+0x0/0x1000 [virtio_mmio] @ 1" -- * initcall virtio_mmio_init+0x0/0x1000 [virtio_mmio] returned 0 after 14 usecs" -- * -- * Initcall functions can be nested, and do not have unique names. -- */ -- for (j = 0; j < data->nr_events; ++j) { -- int vec[30], r; -- const char *message = data->events[j].message; -- -- if (data->events[j].source == GUESTFS_EVENT_APPLIANCE && -- ((r = pcre_exec (re_initcall_calling_module, NULL, -- message, strlen (message), -- 0, 0, vec, sizeof vec / sizeof vec[0])) >= 1 || -- (r = pcre_exec (re_initcall_calling, NULL, -- message, strlen (message), -- 0, 0, vec, sizeof vec / sizeof vec[0])) >= 1)) { -- -- CLEANUP_FREE char *fn_name = NULL, *module_name = NULL; -- if (r >= 2) /* because pcre_exec returns 1 + number of captures */ -- fn_name = strndup (message + vec[2], vec[3]-vec[2]); -- if (r >= 3) -- module_name = strndup (message + vec[4], vec[5]-vec[4]); -- -- CLEANUP_FREE char *fullname; -- if (asprintf (&fullname, "%s.%s", -- module_name ? module_name : "kernel", fn_name) == -1) -- error (EXIT_FAILURE, errno, "asprintf"); -- -- CLEANUP_FREE char *initcall_match; -- if (asprintf (&initcall_match, "initcall %s", fn_name) == -1) -- error (EXIT_FAILURE, errno, "asprintf"); -- -- /* Get a unique name for this activity. Unfortunately -- * kernel initcall function names are not unique! -- */ -- CLEANUP_FREE char *activity_name; -- if (asprintf (&activity_name, "initcall %s", fullname) == -1) -- error (EXIT_FAILURE, errno, "asprintf"); -- -- if (i == 0) { -- int n = 1; -- while (activity_exists (activity_name)) { -- free (activity_name); -- if (asprintf (&activity_name, "initcall %s:%d", fullname, n) == -1) -- error (EXIT_FAILURE, errno, "asprintf"); -- n++; -- } -- } -- else { -- int n = 1; -- while (!activity_exists_with_no_data (activity_name, i)) { -- free (activity_name); -- if (asprintf (&activity_name, "initcall %s:%d", fullname, n) == -1) -- error (EXIT_FAILURE, errno, "asprintf"); -- n++; -- } -- } -- -- /* Find the matching end event. It might be some time later, -- * since it appears initcalls can be nested. -- */ -- for (k = j+1; k < data->nr_events; ++k) { -- if (data->events[k].source == GUESTFS_EVENT_APPLIANCE && -- strstr (data->events[k].message, initcall_match)) { -- if (i == 0) -- activity = add_activity (activity_name, 0); -- else -- activity = find_activity (activity_name); -- activity->start_event[i] = j; -- activity->end_event[i] = k; -- break; -- } -- } -- } -- } -- } --} -diff --git a/tests/qemu/boot-analysis-utils.c b/tests/qemu/boot-analysis-utils.c -deleted file mode 100644 -index 693b6f4..0000000 ---- a/tests/qemu/boot-analysis-utils.c -+++ /dev/null -@@ -1,90 +0,0 @@ --/* libguestfs -- * Copyright (C) 2016 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 -- --#include --#include --#include --#include --#include -- --#include "ignore-value.h" -- --#include "guestfs.h" --#include "guestfs-internal-frontend.h" -- --#include "boot-analysis-utils.h" -- --void --get_time (struct timespec *ts) --{ -- if (clock_gettime (CLOCK_REALTIME, ts) == -1) -- error (EXIT_FAILURE, errno, "clock_gettime: CLOCK_REALTIME"); --} -- --int64_t --timespec_diff (const struct timespec *x, const struct timespec *y) --{ -- int64_t nsec; -- -- nsec = (y->tv_sec - x->tv_sec) * UINT64_C(1000000000); -- nsec += y->tv_nsec - x->tv_nsec; -- return nsec; --} -- --void --test_info (guestfs_h *g, int nr_test_passes) --{ -- const char *qemu = guestfs_get_hv (g); -- CLEANUP_FREE char *cmd = NULL; -- CLEANUP_FREE char *backend = NULL; -- -- /* Related to the test program. */ -- printf ("test version: %s %s\n", PACKAGE_NAME, PACKAGE_VERSION_FULL); -- printf (" test passes: %d\n", nr_test_passes); -- -- /* Related to the host. */ -- printf ("host version: "); -- fflush (stdout); -- ignore_value (system ("uname -a")); -- printf (" host CPU: "); -- fflush (stdout); -- ignore_value (system ("perl -n -e 'if (/^model name.*: (.*)/) { print \"$1\\n\"; exit }' /proc/cpuinfo")); -- -- /* Related to qemu. */ -- backend = guestfs_get_backend (g); -- printf (" backend: %-20s [to change set LIBGUESTFS_BACKEND]\n", -- backend); -- printf (" qemu: %-20s [to change set $LIBGUESTFS_HV]\n", qemu); -- printf ("qemu version: "); -- fflush (stdout); -- if (asprintf (&cmd, "%s -version", qemu) == -1) -- error (EXIT_FAILURE, errno, "asprintf"); -- ignore_value (system (cmd)); -- printf (" smp: %-20d [to change use --smp option]\n", -- guestfs_get_smp (g)); -- printf (" memsize: %-20d [to change use --memsize option]\n", -- guestfs_get_memsize (g)); -- -- /* Related to the guest kernel. Be nice to get the guest -- * kernel version here somehow (XXX). -- */ -- printf (" append: %-20s [to change use --append option]\n", -- guestfs_get_append (g) ? : ""); --} -diff --git a/tests/qemu/boot-analysis-utils.h b/tests/qemu/boot-analysis-utils.h -deleted file mode 100644 -index 95e4f06..0000000 ---- a/tests/qemu/boot-analysis-utils.h -+++ /dev/null -@@ -1,36 +0,0 @@ --/* libguestfs -- * Copyright (C) 2016 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. -- */ -- --#ifndef GUESTFS_BOOT_ANALYSIS_UTILS_H_ --#define GUESTFS_BOOT_ANALYSIS_UTILS_H_ -- --/* Get current time, returning it in *ts. If there is a system call -- * failure, this exits. -- */ --extern void get_time (struct timespec *ts); -- --/* Computes Y - X, returning nanoseconds. */ --extern int64_t timespec_diff (const struct timespec *x, const struct timespec *y); -- --/* Display host machine and test parameters (to stdout). 'g' should -- * be an open libguestfs handle. It is used for reading hv, memsize -- * etc. and is not modified. -- */ --extern void test_info (guestfs_h *g, int nr_test_passes); -- --#endif /* GUESTFS_BOOT_ANALYSIS_UTILS_H_ */ -diff --git a/tests/qemu/boot-analysis.c b/tests/qemu/boot-analysis.c -deleted file mode 100644 -index 2067dfc..0000000 ---- a/tests/qemu/boot-analysis.c -+++ /dev/null -@@ -1,1269 +0,0 @@ --/* libguestfs -- * Copyright (C) 2016 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. -- */ -- --/* Trace and analyze the appliance boot process to find out which -- * steps are taking the most time. It is not part of the standard -- * tests. -- * -- * This needs to be run on a quiet machine, so that other processes -- * disturb the timing as little as possible. The program is -- * completely safe to run at any time. It doesn't read or write any -- * external files, and it doesn't require root. -- * -- * You can run it from the build directory like this: -- * -- * make -- * make -C tests/qemu boot-analysis -- * ./run tests/qemu/boot-analysis -- * -- * The way it works is roughly like this: -- * -- * We create a libguestfs handle and register callback handlers so we -- * can see appliance messages, trace events and so on. -- * -- * We then launch the handle and shut it down as quickly as possible. -- * -- * While the handle is running, events (seen by the callback handlers) -- * are written verbatim into an in-memory buffer, with timestamps. -- * -- * Afterwards we analyze the result using regular expressions to try -- * to identify a "timeline" for the handle (eg. at what time did the -- * BIOS hand control to the kernel). This analysis is done in -- * 'boot-analysis-timeline.c'. -- * -- * The whole process is repeated across a few runs, and the final -- * timeline (including statistical analysis of the variation between -- * runs) gets printed. -- * -- * The program is very sensitive to the specific messages printed by -- * BIOS/kernel/supermin/userspace, so it won't work on non-x86, and it -- * will require periodic adjustment of the regular expressions in -- * order to keep things up to date. -- */ -- --#include -- --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include -- --#include "guestfs.h" --#include "guestfs-internal-frontend.h" -- --#include "boot-analysis.h" --#include "boot-analysis-utils.h" -- --/* Activities taking longer than this % of the total time, except -- * those flagged as LONG_ACTIVITY, are highlighted in red. -- */ --#define WARNING_THRESHOLD 1.0 -- --static const char *append = NULL; --static int force_colour = 0; --static int memsize = 0; --static int smp = 1; --static int verbose = 0; -- --static int libvirt_pipe[2] = { -1, -1 }; --static ssize_t libvirt_pass = -1; -- --/* Because there is a separate thread which collects libvirt log data, -- * we must protect the pass_data struct with a mutex. This only -- * applies during the data collection passes. -- */ --static pthread_mutex_t pass_data_lock = PTHREAD_MUTEX_INITIALIZER; --struct pass_data pass_data[NR_TEST_PASSES]; -- --size_t nr_activities; --struct activity *activities; -- --static void run_test (void); --static struct event *add_event (struct pass_data *, uint64_t source); --static guestfs_h *create_handle (void); --static void set_up_event_handlers (guestfs_h *g, size_t pass); --static void libvirt_log_hack (int argc, char **argv); --static void start_libvirt_thread (size_t pass); --static void stop_libvirt_thread (void); --static void add_drive (guestfs_h *g); --static void check_pass_data (void); --static void dump_pass_data (void); --static void analyze_timeline (void); --static void dump_timeline (void); --static void print_analysis (void); --static void print_longest_to_shortest (void); --static void free_pass_data (void); --static void free_final_timeline (void); --static void ansi_green (void); --static void ansi_red (void); --static void ansi_blue (void); --static void ansi_magenta (void); --static void ansi_restore (void); -- --static void --usage (int exitcode) --{ -- guestfs_h *g; -- int default_memsize = -1; -- -- g = guestfs_create (); -- if (g) { -- default_memsize = guestfs_get_memsize (g); -- guestfs_close (g); -- } -- -- fprintf (stderr, -- "boot-analysis: Trace and analyze the appliance boot process.\n" -- "Usage:\n" -- " boot-analysis [--options]\n" -- "Options:\n" -- " --help Display this usage text and exit.\n" -- " --append OPTS Append OPTS to kernel command line.\n" -- " --colour Output colours, even if not a terminal.\n" -- " -m MB\n" -- " --memsize MB Set memory size in MB (default: %d).\n" -- " --smp N Enable N virtual CPUs (default: 1).\n" -- " -v|--verbose Verbose output, useful for debugging.\n", -- default_memsize); -- exit (exitcode); --} -- --int --main (int argc, char *argv[]) --{ -- enum { HELP_OPTION = CHAR_MAX + 1 }; -- static const char *options = "m:v"; -- static const struct option long_options[] = { -- { "help", 0, 0, HELP_OPTION }, -- { "append", 1, 0, 0 }, -- { "color", 0, 0, 0 }, -- { "colour", 0, 0, 0 }, -- { "memsize", 1, 0, 'm' }, -- { "libvirt-pipe-0", 1, 0, 0 }, /* see libvirt_log_hack */ -- { "libvirt-pipe-1", 1, 0, 0 }, -- { "smp", 1, 0, 0 }, -- { "verbose", 0, 0, 'v' }, -- { 0, 0, 0, 0 } -- }; -- int c, option_index; -- -- for (;;) { -- c = getopt_long (argc, argv, options, long_options, &option_index); -- if (c == -1) break; -- -- switch (c) { -- case 0: /* Options which are long only. */ -- if (STREQ (long_options[option_index].name, "append")) { -- append = optarg; -- break; -- } -- else if (STREQ (long_options[option_index].name, "color") || -- STREQ (long_options[option_index].name, "colour")) { -- force_colour = 1; -- break; -- } -- else if (STREQ (long_options[option_index].name, "libvirt-pipe-0")) { -- if (sscanf (optarg, "%d", &libvirt_pipe[0]) != 1) -- error (EXIT_FAILURE, 0, -- "could not parse libvirt-pipe-0 parameter: %s", optarg); -- break; -- } -- else if (STREQ (long_options[option_index].name, "libvirt-pipe-1")) { -- if (sscanf (optarg, "%d", &libvirt_pipe[1]) != 1) -- error (EXIT_FAILURE, 0, -- "could not parse libvirt-pipe-1 parameter: %s", optarg); -- break; -- } -- else if (STREQ (long_options[option_index].name, "smp")) { -- if (sscanf (optarg, "%d", &smp) != 1) -- error (EXIT_FAILURE, 0, -- "could not parse smp parameter: %s", optarg); -- break; -- } -- fprintf (stderr, "%s: unknown long option: %s (%d)\n", -- guestfs_int_program_name, long_options[option_index].name, option_index); -- exit (EXIT_FAILURE); -- -- case 'm': -- if (sscanf (optarg, "%d", &memsize) != 1) { -- fprintf (stderr, "%s: could not parse memsize parameter: %s\n", -- guestfs_int_program_name, optarg); -- exit (EXIT_FAILURE); -- } -- break; -- -- case 'v': -- verbose = 1; -- break; -- -- case HELP_OPTION: -- usage (EXIT_SUCCESS); -- -- default: -- usage (EXIT_FAILURE); -- } -- } -- -- libvirt_log_hack (argc, argv); -- -- if (STRNEQ (host_cpu, "x86_64") && STRNEQ (host_cpu, "aarch64")) -- fprintf (stderr, "WARNING: host_cpu != x86_64|aarch64: This program may not work or give bogus results.\n"); -- -- run_test (); --} -- --static void --run_test (void) --{ -- guestfs_h *g; -- size_t i; -- -- printf ("Warming up the libguestfs cache ...\n"); -- for (i = 0; i < NR_WARMUP_PASSES; ++i) { -- g = create_handle (); -- add_drive (g); -- if (guestfs_launch (g) == -1) -- exit (EXIT_FAILURE); -- guestfs_close (g); -- } -- -- printf ("Running the tests in %d passes ...\n", NR_TEST_PASSES); -- for (i = 0; i < NR_TEST_PASSES; ++i) { -- g = create_handle (); -- set_up_event_handlers (g, i); -- start_libvirt_thread (i); -- add_drive (g); -- if (guestfs_launch (g) == -1) -- exit (EXIT_FAILURE); -- guestfs_close (g); -- stop_libvirt_thread (); -- -- printf (" pass %zu: %zu events collected in %" PRIi64 " ns\n", -- i+1, pass_data[i].nr_events, pass_data[i].elapsed_ns); -- } -- -- if (verbose) -- dump_pass_data (); -- -- printf ("Analyzing the results ...\n"); -- check_pass_data (); -- construct_timeline (); -- analyze_timeline (); -- -- if (verbose) -- dump_timeline (); -- -- printf ("\n"); -- g = create_handle (); -- test_info (g, NR_TEST_PASSES); -- guestfs_close (g); -- printf ("\n"); -- print_analysis (); -- printf ("\n"); -- printf ("Longest activities:\n"); -- printf ("\n"); -- print_longest_to_shortest (); -- -- free_pass_data (); -- free_final_timeline (); --} -- --static struct event * --add_event_unlocked (struct pass_data *data, uint64_t source) --{ -- struct event *ret; -- -- data->nr_events++; -- data->events = realloc (data->events, -- sizeof (struct event) * data->nr_events); -- if (data->events == NULL) -- error (EXIT_FAILURE, errno, "realloc"); -- ret = &data->events[data->nr_events-1]; -- get_time (&ret->t); -- ret->source = source; -- ret->message = NULL; -- return ret; --} -- --static struct event * --add_event (struct pass_data *data, uint64_t source) --{ -- struct event *ret; -- -- pthread_mutex_lock (&pass_data_lock); -- ret = add_event_unlocked (data, source); -- pthread_mutex_unlock (&pass_data_lock); -- return ret; --} -- --/* Common function to create the handle and set various defaults. */ --static guestfs_h * --create_handle (void) --{ -- guestfs_h *g; -- CLEANUP_FREE char *full_append = NULL; -- -- g = guestfs_create (); -- if (!g) error (EXIT_FAILURE, errno, "guestfs_create"); -- -- if (memsize != 0) -- if (guestfs_set_memsize (g, memsize) == -1) -- exit (EXIT_FAILURE); -- -- if (smp >= 2) -- if (guestfs_set_smp (g, smp) == -1) -- exit (EXIT_FAILURE); -- -- /* This changes some details in appliance/init and enables a -- * detailed trace of calls to initcall functions in the kernel. -- */ -- if (asprintf (&full_append, -- "guestfs_boot_analysis=1 " -- "ignore_loglevel initcall_debug " -- "%s", -- append != NULL ? append : "") == -1) -- error (EXIT_FAILURE, errno, "asprintf"); -- -- if (guestfs_set_append (g, full_append) == -1) -- exit (EXIT_FAILURE); -- -- return g; --} -- --/* Common function to add the /dev/null drive. */ --static void --add_drive (guestfs_h *g) --{ -- if (guestfs_add_drive_opts (g, "/dev/null", -- GUESTFS_ADD_DRIVE_OPTS_FORMAT, "raw", -- GUESTFS_ADD_DRIVE_OPTS_READONLY, 1, -- -1) == -1) -- exit (EXIT_FAILURE); --} -- --/* Called when the handle is closed. Perform any cleanups required in -- * the pass_data here. -- */ --static void --close_callback (guestfs_h *g, void *datavp, uint64_t source, -- int eh, int flags, -- const char *buf, size_t buf_len, -- const uint64_t *array, size_t array_len) --{ -- struct pass_data *data = datavp; -- struct event *event; -- -- if (!data->seen_launch) -- return; -- -- event = add_event (data, source); -- event->message = strdup ("close callback"); -- if (event->message == NULL) -- error (EXIT_FAILURE, errno, "strdup"); -- -- get_time (&data->end_t); -- data->elapsed_ns = timespec_diff (&data->start_t, &data->end_t); --} -- --/* Called when the qemu subprocess exits. -- * XXX This is never called - why? -- */ --static void --subprocess_quit_callback (guestfs_h *g, void *datavp, uint64_t source, -- int eh, int flags, -- const char *buf, size_t buf_len, -- const uint64_t *array, size_t array_len) --{ -- struct pass_data *data = datavp; -- struct event *event; -- -- if (!data->seen_launch) -- return; -- -- event = add_event (data, source); -- event->message = strdup ("subprocess quit callback"); -- if (event->message == NULL) -- error (EXIT_FAILURE, errno, "strdup"); --} -- --/* Called when the launch operation is complete (the library and the -- * guestfs daemon and talking to each other). -- */ --static void --launch_done_callback (guestfs_h *g, void *datavp, uint64_t source, -- int eh, int flags, -- const char *buf, size_t buf_len, -- const uint64_t *array, size_t array_len) --{ -- struct pass_data *data = datavp; -- struct event *event; -- -- if (!data->seen_launch) -- return; -- -- event = add_event (data, source); -- event->message = strdup ("launch done callback"); -- if (event->message == NULL) -- error (EXIT_FAILURE, errno, "strdup"); --} -- --/* Trim \r (multiple) from the end of a string. */ --static void --trim_r (char *message) --{ -- size_t len = strlen (message); -- -- while (len > 0 && message[len-1] == '\r') { -- message[len-1] = '\0'; -- len--; -- } --} -- --/* Called when we get (possibly part of) a log message (or more than -- * one log message) from the appliance (which may include qemu, the -- * BIOS, kernel, etc). -- */ --static void --appliance_callback (guestfs_h *g, void *datavp, uint64_t source, -- int eh, int flags, -- const char *buf, size_t buf_len, -- const uint64_t *array, size_t array_len) --{ -- struct pass_data *data = datavp; -- struct event *event; -- size_t i, len, slen; -- -- if (!data->seen_launch) -- return; -- -- /* If the previous log message was incomplete, but time has moved on -- * a lot, record a new log message anyway, so it gets a new -- * timestamp. -- */ -- if (data->incomplete_log_message >= 0) { -- struct timespec ts; -- get_time (&ts); -- if (timespec_diff (&data->events[data->incomplete_log_message].t, -- &ts) >= 10000000 /* 10ms */) -- data->incomplete_log_message = -1; -- } -- -- /* If the previous log message was incomplete then we may need to -- * append part of the current log message to a previous one. -- */ -- if (data->incomplete_log_message >= 0) { -- len = buf_len; -- for (i = 0; i < buf_len; ++i) { -- if (buf[i] == '\n') { -- len = i; -- break; -- } -- } -- -- event = &data->events[data->incomplete_log_message]; -- slen = strlen (event->message); -- event->message = realloc (event->message, slen + len + 1); -- if (event->message == NULL) -- error (EXIT_FAILURE, errno, "realloc"); -- memcpy (event->message + slen, buf, len); -- event->message[slen + len] = '\0'; -- trim_r (event->message); -- -- /* Skip what we just added to the previous incomplete message. */ -- buf += len; -- buf_len -= len; -- -- if (buf_len == 0) /* still not complete, more to come! */ -- return; -- -- /* Skip the \n in the buffer. */ -- buf++; -- buf_len--; -- data->incomplete_log_message = -1; -- } -- -- /* Add the event, or perhaps multiple events if the message -- * contains \n characters. -- */ -- while (buf_len > 0) { -- len = buf_len; -- for (i = 0; i < buf_len; ++i) { -- if (buf[i] == '\n') { -- len = i; -- break; -- } -- } -- -- event = add_event (data, source); -- event->message = strndup (buf, len); -- if (event->message == NULL) -- error (EXIT_FAILURE, errno, "strndup"); -- trim_r (event->message); -- -- /* Skip what we just added to the event. */ -- buf += len; -- buf_len -= len; -- -- if (buf_len == 0) { -- /* Event is incomplete (doesn't end with \n). We'll finish it -- * in the next callback. -- */ -- data->incomplete_log_message = event - data->events; -- return; -- } -- -- /* Skip the \n in the buffer. */ -- buf++; -- buf_len--; -- } --} -- --/* Called when we get a debug message from the library side. These -- * are always delivered as complete messages. -- */ --static void --library_callback (guestfs_h *g, void *datavp, uint64_t source, -- int eh, int flags, -- const char *buf, size_t buf_len, -- const uint64_t *array, size_t array_len) --{ -- struct pass_data *data = datavp; -- struct event *event; -- -- if (!data->seen_launch) -- return; -- -- event = add_event (data, source); -- event->message = strndup (buf, buf_len); -- if (event->message == NULL) -- error (EXIT_FAILURE, errno, "strndup"); --} -- --/* Called when we get a call trace message (a libguestfs API function -- * has been called or is returning). These are always delivered as -- * complete messages. -- */ --static void --trace_callback (guestfs_h *g, void *datavp, uint64_t source, -- int eh, int flags, -- const char *buf, size_t buf_len, -- const uint64_t *array, size_t array_len) --{ -- struct pass_data *data = datavp; -- struct event *event; -- char *message; -- -- message = strndup (buf, buf_len); -- if (message == NULL) -- error (EXIT_FAILURE, errno, "strndup"); -- -- if (STREQ (message, "launch")) -- data->seen_launch = 1; -- -- if (!data->seen_launch) { -- free (message); -- return; -- } -- -- event = add_event (data, source); -- event->message = message; --} -- --/* Common function to set up event callbacks and record data in memory -- * for a particular pass (0 <= pass < NR_TEST_PASSES). -- */ --static void --set_up_event_handlers (guestfs_h *g, size_t pass) --{ -- struct pass_data *data; -- -- assert (/* 0 <= pass && */ pass < NR_TEST_PASSES); -- -- data = &pass_data[pass]; -- data->pass = pass; -- data->nr_events = 0; -- data->events = NULL; -- get_time (&data->start_t); -- data->incomplete_log_message = -1; -- data->seen_launch = 0; -- -- guestfs_set_event_callback (g, close_callback, -- GUESTFS_EVENT_CLOSE, 0, data); -- guestfs_set_event_callback (g, subprocess_quit_callback, -- GUESTFS_EVENT_SUBPROCESS_QUIT, 0, data); -- guestfs_set_event_callback (g, launch_done_callback, -- GUESTFS_EVENT_LAUNCH_DONE, 0, data); -- guestfs_set_event_callback (g, appliance_callback, -- GUESTFS_EVENT_APPLIANCE, 0, data); -- guestfs_set_event_callback (g, library_callback, -- GUESTFS_EVENT_LIBRARY, 0, data); -- guestfs_set_event_callback (g, trace_callback, -- GUESTFS_EVENT_TRACE, 0, data); -- -- guestfs_set_verbose (g, 1); -- guestfs_set_trace (g, 1); --} -- --/* libvirt debugging sucks in a number of concrete ways: -- * -- * - you can't get a synchronous callback from a log message -- * - you can't enable logging per handle (only globally -- * by setting environment variables) -- * - you can't debug the daemon easily -- * - it's very complex -- * - it's very complex but not in ways that are practical or useful -- * -- * To get log messages at all, we need to create a pipe connected to a -- * second thread, and when libvirt prints something to the pipe we log -- * that. -- * -- * However that's not sufficient. Because logging is only enabled -- * when libvirt examines environment variables at the start of the -- * program, we need to create the pipe and then fork+exec a new -- * instance of the whole program with the pipe and environment -- * variables set up. -- */ --static int is_libvirt_backend (guestfs_h *g); --static void *libvirt_log_thread (void *datavp); -- --static void --libvirt_log_hack (int argc, char **argv) --{ -- guestfs_h *g; -- -- g = guestfs_create (); -- if (!is_libvirt_backend (g)) { -- guestfs_close (g); -- return; -- } -- guestfs_close (g); -- -- /* Have we set up the pipes and environment and forked yet? If not, -- * do that first. -- */ -- if (libvirt_pipe[0] == -1 || libvirt_pipe[1] == -1) { -- char log_outputs[64]; -- char **new_argv; -- char param1[64], param2[64]; -- size_t i; -- pid_t pid; -- int status; -- -- /* Create the pipe. NB: do NOT use O_CLOEXEC since we want to pass -- * this pipe into a child process. -- */ -- if (pipe (libvirt_pipe) == -1) -- error (EXIT_FAILURE, 0, "pipe2"); -- -- /* Create the environment variables to enable logging in libvirt. */ -- setenv ("LIBVIRT_DEBUG", "1", 1); -- //setenv ("LIBVIRT_LOG_FILTERS", -- // "1:qemu 1:securit 3:file 3:event 3:object 1:util", 1); -- snprintf (log_outputs, sizeof log_outputs, -- "1:file:/dev/fd/%d", libvirt_pipe[1]); -- setenv ("LIBVIRT_LOG_OUTPUTS", log_outputs, 1); -- -- /* Run self again. */ -- new_argv = malloc ((argc+3) * sizeof (char *)); -- if (new_argv == NULL) -- error (EXIT_FAILURE, errno, "malloc"); -- -- for (i = 0; i < (size_t) argc; ++i) -- new_argv[i] = argv[i]; -- -- snprintf (param1, sizeof param1, "--libvirt-pipe-0=%d", libvirt_pipe[0]); -- new_argv[argc] = param1; -- snprintf (param2, sizeof param2, "--libvirt-pipe-1=%d", libvirt_pipe[1]); -- new_argv[argc+1] = param2; -- new_argv[argc+2] = NULL; -- -- pid = fork (); -- if (pid == -1) -- error (EXIT_FAILURE, errno, "fork"); -- if (pid == 0) { /* Child process. */ -- execvp (argv[0], new_argv); -- perror ("execvp"); -- _exit (EXIT_FAILURE); -- } -- -- if (waitpid (pid, &status, 0) == -1) -- error (EXIT_FAILURE, errno, "waitpid"); -- if (WIFEXITED (status)) -- exit (WEXITSTATUS (status)); -- error (EXIT_FAILURE, 0, "unexpected exit status from process: %d", status); -- } -- -- /* If we reach this else clause, then we have forked. Now we must -- * create a thread to read events from the pipe. This must be -- * constantly reading from the pipe, otherwise we will deadlock. -- * During the warm-up phase we end up throwing away messages. -- */ -- else { -- pthread_t thread; -- pthread_attr_t attr; -- int r; -- -- r = pthread_attr_init (&attr); -- if (r != 0) -- error (EXIT_FAILURE, r, "pthread_attr_init"); -- r = pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED); -- if (r != 0) -- error (EXIT_FAILURE, r, "pthread_attr_setdetachstate"); -- r = pthread_create (&thread, &attr, libvirt_log_thread, NULL); -- if (r != 0) -- error (EXIT_FAILURE, r, "pthread_create"); -- pthread_attr_destroy (&attr); -- } --} -- --static void --start_libvirt_thread (size_t pass) --{ -- /* In the non-libvirt case, this variable is ignored. */ -- pthread_mutex_lock (&pass_data_lock); -- libvirt_pass = pass; -- pthread_mutex_unlock (&pass_data_lock); --} -- --static void --stop_libvirt_thread (void) --{ -- /* In the non-libvirt case, this variable is ignored. */ -- pthread_mutex_lock (&pass_data_lock); -- libvirt_pass = -1; -- pthread_mutex_unlock (&pass_data_lock); --} -- --/* The separate "libvirt thread". It loops reading debug messages -- * printed by libvirt and adds them to the pass_data. -- */ --static void * --libvirt_log_thread (void *arg) --{ -- struct event *event; -- CLEANUP_FREE char *buf = NULL; -- ssize_t r; -- -- buf = malloc (BUFSIZ); -- if (buf == NULL) -- error (EXIT_FAILURE, errno, "malloc"); -- -- while ((r = read (libvirt_pipe[0], buf, BUFSIZ)) > 0) { -- pthread_mutex_lock (&pass_data_lock); -- if (libvirt_pass == -1) goto discard; -- event = -- add_event_unlocked (&pass_data[libvirt_pass], SOURCE_LIBVIRT); -- event->message = strndup (buf, r); -- if (event->message == NULL) -- error (EXIT_FAILURE, errno, "strndup"); -- discard: -- pthread_mutex_unlock (&pass_data_lock); -- } -- -- if (r == -1) -- error (EXIT_FAILURE, errno, "libvirt_log_thread: read"); -- -- /* It's possible for the pipe to be closed (r == 0) if thread -- * cancellation is delayed after the main thread exits, so just -- * ignore that case and exit. -- */ -- pthread_exit (NULL); --} -- --static int --is_libvirt_backend (guestfs_h *g) --{ -- CLEANUP_FREE char *backend = guestfs_get_backend (g); -- -- return backend && -- (STREQ (backend, "libvirt") || STRPREFIX (backend, "libvirt:")); --} -- --/* Sanity check the collected events. */ --static void --check_pass_data (void) --{ -- size_t i, j, len; -- int64_t ns; -- const char *message; -- -- for (i = 0; i < NR_TEST_PASSES; ++i) { -- assert (pass_data[i].pass == i); -- assert (pass_data[i].elapsed_ns > 1000); -- assert (pass_data[i].nr_events > 0); -- assert (pass_data[i].events != NULL); -- -- for (j = 0; j < pass_data[i].nr_events; ++j) { -- assert (pass_data[i].events[j].t.tv_sec > 0); -- if (j > 0) { -- ns = timespec_diff (&pass_data[i].events[j-1].t, -- &pass_data[i].events[j].t); -- assert (ns >= 0); -- } -- assert (pass_data[i].events[j].source != 0); -- message = pass_data[i].events[j].message; -- assert (message != NULL); -- assert (pass_data[i].events[j].source != GUESTFS_EVENT_APPLIANCE || -- strchr (message, '\n') == NULL); -- len = strlen (message); -- assert (len == 0 || message[len-1] != '\r'); -- } -- } --} -- --static void --print_escaped_string (const char *message) --{ -- while (*message) { -- if (isprint (*message)) -- putchar (*message); -- else -- printf ("\\x%02x", (unsigned int) *message); -- message++; -- } --} -- --/* Dump the events to stdout, if verbose is set. */ --static void --dump_pass_data (void) --{ -- size_t i, j; -- -- for (i = 0; i < NR_TEST_PASSES; ++i) { -- printf ("pass %zu\n", pass_data[i].pass); -- printf (" number of events collected %zu\n", pass_data[i].nr_events); -- printf (" elapsed time %" PRIi64 " ns\n", pass_data[i].elapsed_ns); -- for (j = 0; j < pass_data[i].nr_events; ++j) { -- int64_t ns, diff_ns; -- CLEANUP_FREE char *source_str = NULL; -- -- ns = timespec_diff (&pass_data[i].start_t, &pass_data[i].events[j].t); -- source_str = source_to_string (pass_data[i].events[j].source); -- printf (" %.1fms ", ns / 1000000.0); -- if (j > 0) { -- diff_ns = timespec_diff (&pass_data[i].events[j-1].t, -- &pass_data[i].events[j].t); -- printf ("(+%.1f) ", diff_ns / 1000000.0); -- } -- printf ("[%s] \"", source_str); -- print_escaped_string (pass_data[i].events[j].message); -- printf ("\"\n"); -- } -- } --} -- --/* Convert source to a printable string. The caller must free the -- * returned string. -- */ --char * --source_to_string (uint64_t source) --{ -- char *ret; -- -- if (source == SOURCE_LIBVIRT) { -- ret = strdup ("libvirt"); -- if (ret == NULL) -- error (EXIT_FAILURE, errno, "strdup"); -- } -- else -- ret = guestfs_event_to_string (source); -- -- return ret; /* caller frees */ --} -- --int --activity_exists (const char *name) --{ -- size_t i; -- -- for (i = 0; i < nr_activities; ++i) -- if (STREQ (activities[i].name, name)) -- return 1; -- return 0; --} -- --/* Add an activity to the global list. */ --struct activity * --add_activity (const char *name, int flags) --{ -- struct activity *ret; -- size_t i; -- -- /* You shouldn't have two activities with the same name. */ -- assert (!activity_exists (name)); -- -- nr_activities++; -- activities = realloc (activities, sizeof (struct activity) * nr_activities); -- if (activities == NULL) -- error (EXIT_FAILURE, errno, "realloc"); -- ret = &activities[nr_activities-1]; -- ret->name = strdup (name); -- if (ret->name == NULL) -- error (EXIT_FAILURE, errno, "strdup"); -- ret->flags = flags; -- -- for (i = 0; i < NR_TEST_PASSES; ++i) -- ret->start_event[i] = ret->end_event[i] = 0; -- -- return ret; --} -- --struct activity * --find_activity (const char *name) --{ -- size_t i; -- -- for (i = 0; i < nr_activities; ++i) -- if (STREQ (activities[i].name, name)) -- return &activities[i]; -- error (EXIT_FAILURE, 0, -- "internal error: could not find activity '%s'", name); -- /*NOTREACHED*/ -- abort (); --} -- --int --activity_exists_with_no_data (const char *name, size_t pass) --{ -- size_t i; -- -- for (i = 0; i < nr_activities; ++i) -- if (STREQ (activities[i].name, name) && -- activities[i].start_event[pass] == 0 && -- activities[i].end_event[pass] == 0) -- return 1; -- return 0; --} -- --static int --compare_activities_by_t (const void *av, const void *bv) --{ -- const struct activity *a = av; -- const struct activity *b = bv; -- -- return a->t - b->t; --} -- --/* Go through the activities, computing the start and elapsed time. */ --static void --analyze_timeline (void) --{ -- struct activity *activity; -- size_t i, j; -- int64_t delta_ns; -- -- for (j = 0; j < nr_activities; ++j) { -- activity = &activities[j]; -- -- activity->t = 0; -- activity->mean = 0; -- for (i = 0; i < NR_TEST_PASSES; ++i) { -- delta_ns = -- timespec_diff (&pass_data[i].events[0].t, -- &pass_data[i].events[activity->start_event[i]].t); -- activity->t += delta_ns; -- -- delta_ns = -- timespec_diff (&pass_data[i].events[activity->start_event[i]].t, -- &pass_data[i].events[activity->end_event[i]].t); -- activity->mean += delta_ns; -- } -- -- /* Divide through to get real start time and mean of each activity. */ -- activity->t /= NR_TEST_PASSES; -- activity->mean /= NR_TEST_PASSES; -- -- /* Calculate the end time of this activity. It's convenient when -- * drawing the timeline for one activity to finish just before the -- * next activity starts, rather than having them end and start at -- * the same time, hence ``- 1'' here. -- */ -- activity->end_t = activity->t + activity->mean - 1; -- -- /* The above only calculated mean. Now we are able to -- * calculate from the mean the variance and the standard -- * deviation. -- */ -- activity->variance = 0; -- for (i = 0; i < NR_TEST_PASSES; ++i) { -- delta_ns = -- timespec_diff (&pass_data[i].events[activity->start_event[i]].t, -- &pass_data[i].events[activity->end_event[i]].t); -- activity->variance += pow (delta_ns - activity->mean, 2); -- } -- activity->variance /= NR_TEST_PASSES; -- -- activity->sd = sqrt (activity->variance); -- } -- -- /* Get the total mean elapsed time from the special "run" activity. */ -- activity = find_activity ("run"); -- for (j = 0; j < nr_activities; ++j) { -- activities[j].percent = 100.0 * activities[j].mean / activity->mean; -- -- activities[j].warning = -- !(activities[j].flags & LONG_ACTIVITY) && -- activities[j].percent >= WARNING_THRESHOLD; -- } -- -- /* Sort the activities by start time. */ -- qsort (activities, nr_activities, sizeof (struct activity), -- compare_activities_by_t); --} -- --/* Dump the timeline to stdout, if verbose is set. */ --static void --dump_timeline (void) --{ -- size_t i; -- -- for (i = 0; i < nr_activities; ++i) { -- printf ("activity %zu:\n", i); -- printf (" name = %s\n", activities[i].name); -- printf (" start - end = %.1f - %.1f\n", -- activities[i].t, activities[i].end_t); -- printf (" mean elapsed = %.1f\n", activities[i].mean); -- printf (" variance = %.1f\n", activities[i].variance); -- printf (" s.d = %.1f\n", activities[i].sd); -- printf (" percent = %.1f\n", activities[i].percent); -- } --} -- --static void --print_activity (struct activity *activity) --{ -- if (activity->warning) ansi_red (); else ansi_green (); -- print_escaped_string (activity->name); -- ansi_restore (); -- printf (" %.1fms ±%.1fms ", -- activity->mean / 1000000, activity->sd / 1000000); -- if (activity->warning) ansi_red (); else ansi_green (); -- printf ("(%.1f%%) ", activity->percent); -- ansi_restore (); --} -- --static void --print_analysis (void) --{ -- double t = -1; /* Current time. */ -- /* Which columns contain activities that we are displaying now? -- * -1 == unused column, else index of an activity -- */ -- CLEANUP_FREE ssize_t *columns = NULL; -- const size_t nr_columns = nr_activities; -- size_t last_free_column = 0; -- -- size_t i, j; -- double last_t, smallest_next_t; -- const double MAX_T = 1e20; -- -- columns = malloc (nr_columns * sizeof (ssize_t)); -- if (columns == NULL) error (EXIT_FAILURE, errno, "malloc"); -- for (j = 0; j < nr_columns; ++j) -- columns[j] = -1; -- -- for (;;) { -- /* Find the next significant time to display, which is a time when -- * some activity started or ended. -- */ -- smallest_next_t = MAX_T; -- for (i = 0; i < nr_activities; ++i) { -- if (t < activities[i].t && activities[i].t < smallest_next_t) -- smallest_next_t = activities[i].t; -- else if (t < activities[i].end_t && activities[i].end_t < smallest_next_t) -- smallest_next_t = activities[i].end_t; -- } -- if (smallest_next_t == MAX_T) -- break; /* Finished. */ -- -- last_t = t; -- t = smallest_next_t; -- -- /* Draw a spacer line, but only if last_t -> t is a large jump. */ -- if (t - last_t >= 1000000 /* ns */) { -- printf (" "); -- ansi_magenta (); -- for (j = 0; j < last_free_column; ++j) { -- if (columns[j] >= 0 && -- activities[columns[j]].end_t != last_t /* !▼ */) -- printf ("│ "); -- else -- printf (" "); -- } -- ansi_restore (); -- printf ("\n"); -- } -- -- /* If there are any activities that ended before this time, drop -- * them from the columns list. -- */ -- for (i = 0; i < nr_activities; ++i) { -- if (activities[i].end_t < t) { -- for (j = 0; j < nr_columns; ++j) -- if (columns[j] == (ssize_t) i) { -- columns[j] = -1; -- break; -- } -- } -- } -- -- /* May need to adjust last_free_column after previous operation. */ -- while (last_free_column > 0 && columns[last_free_column-1] == -1) -- last_free_column--; -- -- /* If there are any activities starting at this time, add them to -- * the right hand end of the columns list. -- */ -- for (i = 0; i < nr_activities; ++i) { -- if (activities[i].t == t) -- columns[last_free_column++] = i; -- } -- -- /* Draw the line. */ -- ansi_blue (); -- printf ("%6.1fms: ", t / 1000000); -- -- ansi_magenta (); -- for (j = 0; j < last_free_column; ++j) { -- if (columns[j] >= 0) { -- if (activities[columns[j]].t == t) -- printf ("▲ "); -- else if (activities[columns[j]].end_t == t) -- printf ("▼ "); -- else -- printf ("│ "); -- } -- else -- printf (" "); -- } -- ansi_restore (); -- -- for (j = 0; j < last_free_column; ++j) { -- if (columns[j] >= 0 && activities[columns[j]].t == t) /* ▲ */ -- print_activity (&activities[columns[j]]); -- } -- -- printf ("\n"); -- } --} -- --static int --compare_activities_pointers_by_mean (const void *av, const void *bv) --{ -- const struct activity * const *a = av; -- const struct activity * const *b = bv; -- -- return (*b)->mean - (*a)->mean; --} -- --static void --print_longest_to_shortest (void) --{ -- size_t i; -- CLEANUP_FREE struct activity **longest; -- -- /* Sort the activities longest first. In order not to affect the -- * global activities array, sort an array of pointers to the -- * activities instead. -- */ -- longest = malloc (sizeof (struct activity *) * nr_activities); -- for (i = 0; i < nr_activities; ++i) -- longest[i] = &activities[i]; -- -- qsort (longest, nr_activities, sizeof (struct activity *), -- compare_activities_pointers_by_mean); -- -- /* Display the activities, longest first. */ -- for (i = 0; i < nr_activities; ++i) { -- print_activity (longest[i]); -- printf ("\n"); -- } --} -- --/* Free the non-static part of the pass_data structures. */ --static void --free_pass_data (void) --{ -- size_t i, j; -- -- for (i = 0; i < NR_TEST_PASSES; ++i) { -- for (j = 0; j < pass_data[i].nr_events; ++j) -- free (pass_data[i].events[j].message); -- free (pass_data[i].events); -- } --} -- --static void --free_final_timeline (void) --{ -- size_t i; -- -- for (i = 0; i < nr_activities; ++i) -- free (activities[i].name); -- free (activities); --} -- --/* Colours. */ --static void --ansi_green (void) --{ -- if (force_colour || isatty (1)) -- fputs ("\033[0;32m", stdout); --} -- --static void --ansi_red (void) --{ -- if (force_colour || isatty (1)) -- fputs ("\033[1;31m", stdout); --} -- --static void --ansi_blue (void) --{ -- if (force_colour || isatty (1)) -- fputs ("\033[1;34m", stdout); --} -- --static void --ansi_magenta (void) --{ -- if (force_colour || isatty (1)) -- fputs ("\033[1;35m", stdout); --} -- --static void --ansi_restore (void) --{ -- if (force_colour || isatty (1)) -- fputs ("\033[0m", stdout); --} -diff --git a/tests/qemu/boot-analysis.h b/tests/qemu/boot-analysis.h -deleted file mode 100644 -index a07f12e..0000000 ---- a/tests/qemu/boot-analysis.h -+++ /dev/null -@@ -1,102 +0,0 @@ --/* libguestfs -- * Copyright (C) 2016 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. -- */ -- --#ifndef GUESTFS_BOOT_ANALYSIS_H_ --#define GUESTFS_BOOT_ANALYSIS_H_ -- --#define NR_WARMUP_PASSES 3 --#define NR_TEST_PASSES 5 -- --/* Per-pass data collected. */ --struct pass_data { -- size_t pass; -- struct timespec start_t; -- struct timespec end_t; -- int64_t elapsed_ns; -- -- /* Array of timestamped events. */ -- size_t nr_events; -- struct event *events; -- -- /* Was the previous appliance log message incomplete? If so, this -- * contains the index of that incomplete message in the events -- * array. -- */ -- ssize_t incomplete_log_message; -- -- /* Have we seen the launch event yet? We don't record events until -- * this one has been received. This makes it easy to base the -- * timeline at event 0. -- */ -- int seen_launch; --}; -- --/* The 'source' field in the event is a guestfs event -- * (GUESTFS_EVENT_*). We also wish to encode libvirt as a source, so -- * we use a magic/impossible value for that here. Note that events -- * are bitmasks, and normally no more than one bit may be set. -- */ --#define SOURCE_LIBVIRT ((uint64_t)~0) --extern char *source_to_string (uint64_t source); -- --struct event { -- struct timespec t; -- uint64_t source; -- char *message; --}; -- --extern struct pass_data pass_data[NR_TEST_PASSES]; -- --/* The final timeline consisting of various activities starting and -- * ending. We're interested in when the activities start, and how -- * long they take (mean, variance, standard deviation of length). -- */ --struct activity { -- char *name; /* Name of this activity. */ -- int flags; --#define LONG_ACTIVITY 1 /* Expected to take a long time. */ -- -- /* For each pass, record the actual start & end events of this -- * activity. -- */ -- size_t start_event[NR_TEST_PASSES]; -- size_t end_event[NR_TEST_PASSES]; -- -- double t; /* Start (ns offset). */ -- double end_t; /* t + mean - 1 */ -- -- /* Length of this activity. */ -- double mean; /* Mean time elapsed (ns). */ -- double variance; /* Variance. */ -- double sd; /* Standard deviation. */ -- double percent; /* Percent of total elapsed time. */ -- -- int warning; /* Appears in red. */ --}; -- --extern size_t nr_activities; --extern struct activity *activities; -- --extern int activity_exists (const char *name); --extern struct activity *add_activity (const char *name, int flags); --extern struct activity *find_activity (const char *name); --extern int activity_exists_with_no_data (const char *name, size_t pass); -- --extern void construct_timeline (void); -- --#endif /* GUESTFS_BOOT_ANALYSIS_H_ */ -diff --git a/tests/qemu/boot-benchmark-range.pl b/tests/qemu/boot-benchmark-range.pl -deleted file mode 100755 -index 0e31c4d..0000000 ---- a/tests/qemu/boot-benchmark-range.pl -+++ /dev/null -@@ -1,240 +0,0 @@ --#!/usr/bin/env perl --# Copyright (C) 2016 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. -- --use warnings; --use strict; -- --use Pod::Usage; --use Getopt::Long; -- --=head1 NAME -- --boot-benchmark-range.pl - Benchmark libguestfs across a range of commits --from another project -- --=head1 SYNOPSIS -- -- LIBGUESTFS_BACKEND=direct \ -- LIBGUESTFS_HV=/path/to/qemu/x86_64-softmmu/qemu-system-x86_64 \ -- ./run \ -- tests/qemu/boot-benchmark-range.pl /path/to/qemu HEAD~50..HEAD -- --=head1 -- --Run F across a range of commits in another --project. This is useful for finding performance regressions in other --programs such as qemu or the Linux kernel which might be affecting --libguestfs. -- --For example, suppose you suspect there has been a performance --regression in qemu, somewhere between C. You could run --the script like this: -- -- LIBGUESTFS_BACKEND=direct \ -- LIBGUESTFS_HV=/path/to/qemu/x86_64-softmmu/qemu-system-x86_64 \ -- ./run \ -- tests/qemu/boot-benchmark-range.pl /path/to/qemu HEAD~50..HEAD -- --where F is the path to the qemu git repository. -- --The output is a list of the qemu commits, annotated by the benchmark --time and some other information about how the time compares to the --previous commit. -- --You should run these tests on an unloaded machine. In particular --running a desktop environment, web browser and so on can make the --benchmarks useless. -- --=head1 OPTIONS -- --=over 4 -- --=cut -- --my $help; -- --=item B<--help> -- --Display brief help. -- --=cut -- --my $man; -- --=item B<--man> -- --Display full documentation (man page). -- --=cut -- --my $benchmark_command; -- --=item B<--benchmark> C -- --Set the name of the benchmark to run. You only need to use this if --the script cannot find the right path to the libguestfs --F program. By default the script looks for --this file in the same directory as its executable. -- --=cut -- --my $make_command = "make"; -- --=item B<--make> C -- --Set the command used to build the other project. The default is --to run C. -- --If the command fails, then the commit is skipped. -- --=back -- --=cut -- --# Clean up the program name. --my $progname = $0; --$progname =~ s{.*/}{}; -- --# Parse options. --GetOptions ("help|?" => \$help, -- "man" => \$man, -- "benchmark=s" => \$benchmark_command, -- "make=s" => \$make_command, -- ) or pod2usage (2); --pod2usage (-exitval => 0) if $help; --pod2usage (-exitval => 0, -verbose => 2) if $man; -- --die "$progname: missing argument: requires path to git repository and range of commits\n" unless @ARGV == 2; -- --my $dir = $ARGV[0]; --my $range = $ARGV[1]; -- --die "$progname: $dir is not a git repository\n" -- unless -d $dir && -d "$dir/.git"; -- --sub silently_run --{ -- open my $saveout, ">&STDOUT"; -- open my $saveerr, ">&STDERR"; -- open STDOUT, ">/dev/null"; -- open STDERR, ">/dev/null"; -- my $ret = system (@_); -- open STDOUT, ">&", $saveout; -- open STDERR, ">&", $saveerr; -- return $ret; --} -- --# Find the benchmark program and check it works. --unless (defined $benchmark_command) { -- $benchmark_command = $0; -- $benchmark_command =~ s{/[^/]+$}{}; -- $benchmark_command .= "/boot-benchmark"; -- -- my $r = silently_run ("$benchmark_command", "--help"); -- die "$progname: cannot locate boot-benchmark program, try using --benchmark\n" unless $r == 0; --} -- --# Get the top-most commit from the remote, and restore it on exit. --my $top_commit = `git -C '$dir' rev-parse HEAD`; --chomp $top_commit; -- --sub checkout --{ -- my $sha = shift; -- my $ret = silently_run ("git", "-C", $dir, "checkout", $sha); -- return $ret; --} -- --END { -- checkout ($top_commit); --} -- --# Get the range of commits and log messages. --my @range = (); --open RANGE, "git -C '$dir' log --reverse --oneline $range |" or die; --while () { -- if (m/^([0-9a-f]+) (.*)/) { -- my $sha = $1; -- my $msg = $2; -- push @range, [ $sha, $msg ]; -- } --} --close RANGE or die; -- --# Run the test. --my $prev_ms; --foreach (@range) { -- my ($sha, $msg) = @$_; -- my $r; -- -- print "\n"; -- print "$sha $msg\n"; -- -- # Checkout this commit in the other repo. -- $r = checkout ($sha); -- if ($r != 0) { -- print "git checkout failed\n"; -- next; -- } -- -- # Build the repo, silently. -- $r = silently_run ("cd $dir && $make_command"); -- if ($r != 0) { -- print "build failed\n"; -- next; -- } -- -- # Run the benchmark program and get the timing. -- my ($time_ms, $time_str); -- open BENCHMARK, "$benchmark_command | grep '^Result:' |" or die; -- while () { -- die unless m/^Result: (([\d.]+)ms ±[\d.]+ms)/; -- $time_ms = $2; -- $time_str = $1; -- } -- close BENCHMARK; -- -- print "\t", $time_str; -- if (defined $prev_ms) { -- if ($prev_ms > $time_ms) { -- my $pc = 100 * ($prev_ms-$time_ms) / $time_ms; -- if ($pc >= 1) { -- printf (" ↑ improves performance by %0.1f%%", $pc); -- } -- } elsif ($prev_ms < $time_ms) { -- my $pc = 100 * ($time_ms-$prev_ms) / $prev_ms; -- if ($pc >= 1) { -- printf (" ↓ degrades performance by %0.1f%%", $pc); -- } -- } -- } -- print "\n"; -- $prev_ms = $time_ms; --} -- --=head1 SEE ALSO -- --L, --L. -- --=head1 AUTHOR -- --Richard W.M. Jones. -- --=head1 COPYRIGHT -- --Copyright (C) 2016 Red Hat Inc. -diff --git a/tests/qemu/boot-benchmark.c b/tests/qemu/boot-benchmark.c -deleted file mode 100644 -index 0508ee9..0000000 ---- a/tests/qemu/boot-benchmark.c -+++ /dev/null -@@ -1,225 +0,0 @@ --/* libguestfs -- * Copyright (C) 2016 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. -- */ -- --/* Benchmark the time taken to boot the libguestfs appliance. */ -- --#include -- --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include -- --#include "guestfs.h" --#include "guestfs-internal-frontend.h" -- --#include "boot-analysis-utils.h" -- --#define NR_WARMUP_PASSES 3 --#define NR_TEST_PASSES 10 -- --static const char *append = NULL; --static int memsize = 0; --static int smp = 1; -- --static void run_test (void); --static guestfs_h *create_handle (void); --static void add_drive (guestfs_h *g); -- --static void --usage (int exitcode) --{ -- guestfs_h *g; -- int default_memsize = -1; -- -- g = guestfs_create (); -- if (g) { -- default_memsize = guestfs_get_memsize (g); -- guestfs_close (g); -- } -- -- fprintf (stderr, -- "boot-benchmark: Benchmark the time taken to boot the libguestfs appliance.\n" -- "Usage:\n" -- " boot-benchmark [--options]\n" -- "Options:\n" -- " --help Display this usage text and exit.\n" -- " --append OPTS Append OPTS to kernel command line.\n" -- " -m MB\n" -- " --memsize MB Set memory size in MB (default: %d).\n" -- " --smp N Enable N virtual CPUs (default: 1).\n", -- default_memsize); -- exit (exitcode); --} -- --int --main (int argc, char *argv[]) --{ -- enum { HELP_OPTION = CHAR_MAX + 1 }; -- static const char *options = "m:"; -- static const struct option long_options[] = { -- { "help", 0, 0, HELP_OPTION }, -- { "append", 1, 0, 0 }, -- { "memsize", 1, 0, 'm' }, -- { "smp", 1, 0, 0 }, -- { 0, 0, 0, 0 } -- }; -- int c, option_index; -- -- for (;;) { -- c = getopt_long (argc, argv, options, long_options, &option_index); -- if (c == -1) break; -- -- switch (c) { -- case 0: /* Options which are long only. */ -- if (STREQ (long_options[option_index].name, "append")) { -- append = optarg; -- break; -- } -- else if (STREQ (long_options[option_index].name, "smp")) { -- if (sscanf (optarg, "%d", &smp) != 1) { -- fprintf (stderr, "%s: could not parse smp parameter: %s\n", -- guestfs_int_program_name, optarg); -- exit (EXIT_FAILURE); -- } -- break; -- } -- fprintf (stderr, "%s: unknown long option: %s (%d)\n", -- guestfs_int_program_name, long_options[option_index].name, option_index); -- exit (EXIT_FAILURE); -- -- case 'm': -- if (sscanf (optarg, "%d", &memsize) != 1) { -- fprintf (stderr, "%s: could not parse memsize parameter: %s\n", -- guestfs_int_program_name, optarg); -- exit (EXIT_FAILURE); -- } -- break; -- -- case HELP_OPTION: -- usage (EXIT_SUCCESS); -- -- default: -- usage (EXIT_FAILURE); -- } -- } -- -- run_test (); --} -- --static void --run_test (void) --{ -- guestfs_h *g; -- size_t i; -- int64_t ns[NR_TEST_PASSES]; -- double mean; -- double variance; -- double sd; -- -- printf ("Warming up the libguestfs cache ...\n"); -- for (i = 0; i < NR_WARMUP_PASSES; ++i) { -- g = create_handle (); -- add_drive (g); -- if (guestfs_launch (g) == -1) -- exit (EXIT_FAILURE); -- guestfs_close (g); -- } -- -- printf ("Running the tests ...\n"); -- for (i = 0; i < NR_TEST_PASSES; ++i) { -- struct timespec start_t, end_t; -- -- g = create_handle (); -- add_drive (g); -- get_time (&start_t); -- if (guestfs_launch (g) == -1) -- exit (EXIT_FAILURE); -- guestfs_close (g); -- get_time (&end_t); -- -- ns[i] = timespec_diff (&start_t, &end_t); -- } -- -- /* Calculate the mean. */ -- mean = 0; -- for (i = 0; i < NR_TEST_PASSES; ++i) -- mean += ns[i]; -- mean /= NR_TEST_PASSES; -- -- /* Calculate the variance and standard deviation. */ -- variance = 0; -- for (i = 0; i < NR_TEST_PASSES; ++i) -- variance = pow (ns[i] - mean, 2); -- variance /= NR_TEST_PASSES; -- sd = sqrt (variance); -- -- /* Print the test parameters. */ -- printf ("\n"); -- g = create_handle (); -- test_info (g, NR_TEST_PASSES); -- guestfs_close (g); -- -- /* Print the result. */ -- printf ("\n"); -- printf ("Result: %.1fms ±%.1fms\n", mean / 1000000, sd / 1000000); --} -- --/* Common function to create the handle and set various defaults. */ --static guestfs_h * --create_handle (void) --{ -- guestfs_h *g; -- CLEANUP_FREE char *full_append = NULL; -- -- g = guestfs_create (); -- if (!g) error (EXIT_FAILURE, errno, "guestfs_create"); -- -- if (memsize != 0) -- if (guestfs_set_memsize (g, memsize) == -1) -- exit (EXIT_FAILURE); -- -- if (smp >= 2) -- if (guestfs_set_smp (g, smp) == -1) -- exit (EXIT_FAILURE); -- -- if (append != NULL) -- if (guestfs_set_append (g, full_append) == -1) -- exit (EXIT_FAILURE); -- -- return g; --} -- --/* Common function to add the /dev/null drive. */ --static void --add_drive (guestfs_h *g) --{ -- if (guestfs_add_drive_opts (g, "/dev/null", -- GUESTFS_ADD_DRIVE_OPTS_FORMAT, "raw", -- GUESTFS_ADD_DRIVE_OPTS_READONLY, 1, -- -1) == -1) -- exit (EXIT_FAILURE); --} -diff --git a/tests/qemu/qemu-boot.c b/tests/qemu/qemu-boot.c -deleted file mode 100644 -index 336c26e..0000000 ---- a/tests/qemu/qemu-boot.c -+++ /dev/null -@@ -1,362 +0,0 @@ --/* libguestfs -- * Copyright (C) 2014-2016 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. -- */ -- --/* Ancient libguestfs had a script called test-bootbootboot which just -- * booted up the appliance in a loop. This was necessary back in the -- * bad old days when qemu was not very reliable. This is the -- * spiritual successor of that script, designed to find bugs in -- * aarch64 KVM. You can control the number of boots that are done and -- * the amount of parallelism. -- */ -- --#include -- --#include --#include --#include --#include --#include --#include --#include -- --#include "guestfs.h" --#include "guestfs-internal-frontend.h" --#include "estimate-max-threads.h" -- --#define MIN(a,b) ((a)<(b)?(a):(b)) -- --/* Maximum number of threads we would ever run. Note this should not -- * be > 20, unless libvirt is modified to increase the maximum number -- * of clients. User can override this limit using -P. -- */ --#define MAX_THREADS 12 -- --static size_t n; /* Number of qemu processes to run in total. */ --static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; -- --static int ignore_errors = 0; --static const char *log_template = NULL; --static size_t log_file_size; --static int trace = 0; --static int verbose = 0; -- --/* Events captured by the --log option. */ --static const uint64_t event_bitmask = -- GUESTFS_EVENT_LIBRARY | -- GUESTFS_EVENT_WARNING | -- GUESTFS_EVENT_APPLIANCE | -- GUESTFS_EVENT_TRACE; -- --struct thread_data { -- int thread_num; -- int r; --}; -- --static void *start_thread (void *thread_data_vp); --static void message_callback (guestfs_h *g, void *opaque, uint64_t event, int event_handle, int flags, const char *buf, size_t buf_len, const uint64_t *array, size_t array_len); -- --static void --usage (int exitcode) --{ -- fprintf (stderr, -- "qemu-boot: A program for repeatedly running the libguestfs appliance.\n" -- "qemu-boot [-i] [--log output.%%] [-P ] -n \n" -- " -i Ignore errors\n" -- " --log \n" -- " Write per-appliance logs to file (%% in name replaced by boot number)\n" -- " -P Set number of parallel threads\n" -- " (default is based on the amount of free memory)\n" -- " -n Set number of appliances to run before exiting\n" -- " -v Verbose appliance\n" -- " -x Enable libguestfs tracing\n"); -- exit (exitcode); --} -- --int --main (int argc, char *argv[]) --{ -- enum { HELP_OPTION = CHAR_MAX + 1 }; -- static const char options[] = "in:P:vx"; -- static const struct option long_options[] = { -- { "help", 0, 0, HELP_OPTION }, -- { "ignore", 0, 0, 'i' }, -- { "log", 1, 0, 0 }, -- { "number", 1, 0, 'n' }, -- { "processes", 1, 0, 'P' }, -- { "trace", 0, 0, 'x' }, -- { "verbose", 0, 0, 'v' }, -- { 0, 0, 0, 0 } -- }; -- size_t P = 0, i, errors; -- int c, option_index; -- int err; -- void *status; -- -- for (;;) { -- c = getopt_long (argc, argv, options, long_options, &option_index); -- if (c == -1) break; -- -- switch (c) { -- case 0: -- /* Options which are long only. */ -- if (STREQ (long_options[option_index].name, "log")) { -- log_template = optarg; -- log_file_size = strlen (log_template); -- for (i = 0; i < strlen (log_template); ++i) { -- if (log_template[i] == '%') -- log_file_size += 64; -- } -- } -- else { -- fprintf (stderr, "%s: unknown long option: %s (%d)\n", -- guestfs_int_program_name, long_options[option_index].name, option_index); -- exit (EXIT_FAILURE); -- } -- break; -- -- case 'i': -- ignore_errors = 1; -- break; -- -- case 'n': -- if (sscanf (optarg, "%zu", &n) != 1 || n == 0) { -- fprintf (stderr, "%s: -n option not numeric and greater than 0\n", -- guestfs_int_program_name); -- exit (EXIT_FAILURE); -- } -- break; -- -- case 'P': -- if (sscanf (optarg, "%zu", &P) != 1) { -- fprintf (stderr, "%s: -P option not numeric\n", guestfs_int_program_name); -- exit (EXIT_FAILURE); -- } -- break; -- -- case 'v': -- verbose = 1; -- break; -- -- case 'x': -- trace = 1; -- break; -- -- case HELP_OPTION: -- usage (EXIT_SUCCESS); -- -- default: -- usage (EXIT_FAILURE); -- } -- } -- -- if (n == 0) { -- fprintf (stderr, -- "%s: must specify number of processes to run (-n option)\n", -- guestfs_int_program_name); -- exit (EXIT_FAILURE); -- } -- -- if (optind != argc) { -- fprintf (stderr, "%s: extra arguments found on the command line\n", -- guestfs_int_program_name); -- exit (EXIT_FAILURE); -- } -- -- /* Calculate the number of threads to use. */ -- if (P > 0) -- P = MIN (n, P); -- else -- P = MIN (n, MIN (MAX_THREADS, estimate_max_threads ())); -- -- /* Start the worker threads. */ -- struct thread_data thread_data[P]; -- pthread_t threads[P]; -- -- for (i = 0; i < P; ++i) { -- thread_data[i].thread_num = i; -- err = pthread_create (&threads[i], NULL, start_thread, &thread_data[i]); -- if (err != 0) { -- fprintf (stderr, "%s: pthread_create[%zu]: %s\n", -- guestfs_int_program_name, i, strerror (err)); -- exit (EXIT_FAILURE); -- } -- } -- -- /* Wait for the threads to exit. */ -- errors = 0; -- for (i = 0; i < P; ++i) { -- err = pthread_join (threads[i], &status); -- if (err != 0) { -- fprintf (stderr, "%s: pthread_join[%zu]: %s\n", -- guestfs_int_program_name, i, strerror (err)); -- errors++; -- } -- if (*(int *)status == -1) -- errors++; -- } -- -- exit (errors == 0 ? EXIT_SUCCESS : EXIT_FAILURE); --} -- --/* Worker thread. */ --static void * --start_thread (void *thread_data_vp) --{ -- struct thread_data *thread_data = thread_data_vp; -- int quit = 0; -- int err; -- size_t i; -- guestfs_h *g; -- unsigned errors = 0; -- char id[64]; -- -- for (;;) { -- CLEANUP_FREE char *log_file = NULL; -- CLEANUP_FCLOSE FILE *log_fp = NULL; -- -- /* Take the next process. */ -- err = pthread_mutex_lock (&mutex); -- if (err != 0) { -- fprintf (stderr, "%s: pthread_mutex_lock: %s", -- guestfs_int_program_name, strerror (err)); -- goto error; -- } -- -- i = n; -- if (i > 0) { -- printf ("%zu to go ... \r", n); -- fflush (stdout); -- -- n--; -- } -- else -- quit = 1; -- -- err = pthread_mutex_unlock (&mutex); -- if (err != 0) { -- fprintf (stderr, "%s: pthread_mutex_unlock: %s", -- guestfs_int_program_name, strerror (err)); -- goto error; -- } -- -- if (quit) /* Work finished. */ -- break; -- -- g = guestfs_create (); -- if (g == NULL) { -- perror ("guestfs_create"); -- errors++; -- if (!ignore_errors) -- goto error; -- } -- -- /* Only if using --log, set up a callback. See examples/debug-logging.c */ -- if (log_template != NULL) { -- size_t j, k; -- -- log_file = malloc (log_file_size + 1); -- if (log_file == NULL) abort (); -- for (j = 0, k = 0; j < strlen (log_template); ++j) { -- if (log_template[j] == '%') { -- snprintf (&log_file[k], log_file_size - k, "%zu", i); -- k += strlen (&log_file[k]); -- } -- else -- log_file[k++] = log_template[j]; -- } -- log_file[k] = '\0'; -- log_fp = fopen (log_file, "w"); -- if (log_fp == NULL) { -- perror (log_file); -- abort (); -- } -- guestfs_set_event_callback (g, message_callback, -- event_bitmask, 0, log_fp); -- } -- -- snprintf (id, sizeof id, "%zu", i); -- guestfs_set_identifier (g, id); -- -- guestfs_set_trace (g, trace); -- guestfs_set_verbose (g, verbose); -- -- if (guestfs_add_drive_ro (g, "/dev/null") == -1) { -- errors++; -- if (!ignore_errors) -- goto error; -- } -- -- if (guestfs_launch (g) == -1) { -- errors++; -- if (!ignore_errors) -- goto error; -- } -- -- if (guestfs_shutdown (g) == -1) { -- errors++; -- if (!ignore_errors) -- goto error; -- } -- -- guestfs_close (g); -- } -- -- if (errors > 0) { -- fprintf (stderr, "%s: thread %d: %u errors were ignored\n", -- guestfs_int_program_name, thread_data->thread_num, errors); -- goto error; -- } -- -- thread_data->r = 0; -- return &thread_data->r; -- -- error: -- thread_data->r = -1; -- return &thread_data->r; --} -- --/* If using --log, this is called to write messages to the log file. */ --static void --message_callback (guestfs_h *g, void *opaque, -- uint64_t event, int event_handle, -- int flags, -- const char *buf, size_t buf_len, -- const uint64_t *array, size_t array_len) --{ -- FILE *fp = opaque; -- -- if (buf_len > 0) { -- CLEANUP_FREE char *msg = strndup (buf, buf_len); -- -- switch (event) { -- case GUESTFS_EVENT_APPLIANCE: -- fprintf (fp, "%s", msg); -- break; -- case GUESTFS_EVENT_LIBRARY: -- fprintf (fp, "libguestfs: %s\n", msg); -- break; -- case GUESTFS_EVENT_WARNING: -- fprintf (fp, "libguestfs: warning: %s\n", msg); -- break; -- case GUESTFS_EVENT_TRACE: -- fprintf (fp, "libguestfs: trace: %s\n", msg); -- break; -- } -- fflush (fp); -- } --} -diff --git a/tests/qemu/qemu-speed-test.c b/tests/qemu/qemu-speed-test.c -deleted file mode 100644 -index d5e34c3..0000000 ---- a/tests/qemu/qemu-speed-test.c -+++ /dev/null -@@ -1,480 +0,0 @@ --/* libguestfs -- * Copyright (C) 2014 Red Hat Inc. -- * -- * This program is free software; you can redistribute it and/or modify -- * it under the terms of the GNU General Public License as published by -- * the Free Software Foundation; either version 2 of the License, or -- * (at your option) any later version. -- * -- * This program is distributed in the hope that it will be useful, -- * but WITHOUT ANY WARRANTY; without even the implied warranty of -- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- * GNU General Public License for more details. -- * -- * You should have received a copy of the GNU General Public License along -- * with this program; if not, write to the Free Software Foundation, Inc., -- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -- */ -- --/* Test the speed of various qemu features. Currently tested are: -- * - virtio-serial upload -- * - virtio-serial download -- * - block device read -- * - block device write -- * More to come in future. -- */ -- --#include -- --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include -- --#include "guestfs.h" --#include "guestfs-internal-frontend.h" -- --static void test_virtio_serial (void); --static void test_block_device (void); -- --/* Which tests are enabled? -- All by default. */ --static int virtio_serial_upload = 1; --static int virtio_serial_download = 1; --static int block_device_write = 1; --static int block_device_read = 1; -- --static int max_time_override = 0; -- --static void --reset_default_tests (int *flag) --{ -- if (*flag) { -- virtio_serial_upload = 0; -- virtio_serial_download = 0; -- block_device_write = 0; -- block_device_read = 0; -- *flag = 0; -- } --} -- --static void --usage (int exitcode) --{ -- fprintf (stderr, -- "qemu-speed-test: Test the speed of qemu features.\n" -- "\n" -- "To run all tests (recommended), do:\n" -- " qemu-speed-test\n" -- "\n" -- "To run only specific tests, do:\n" -- " qemu-speed-test --option [--option ...]\n" -- "where the test options are:\n" -- " --virtio-serial-upload\n" -- " --virtio-serial-download\n" -- " --block-device-write\n" -- " --block-device-read\n" -- "\n" -- "Other options:\n" -- " --help Display help output and exit\n" -- " -t | --time= Set max length of test in seconds\n" -- ); -- exit (exitcode); --} -- --int --main (int argc, char *argv[]) --{ -- enum { HELP_OPTION = CHAR_MAX + 1 }; -- static const char options[] = "t:"; -- static const struct option long_options[] = { -- { "help", 0, 0, HELP_OPTION }, -- { "time", 1, 0, 't' }, -- -- /* Tests. */ -- { "virtio-serial-upload", 0, 0, 0 }, -- { "virtio-serial-download", 0, 0, 0 }, -- { "block-device-write", 0, 0, 0 }, -- { "block-device-read", 0, 0, 0 }, -- -- { 0, 0, 0, 0 } -- }; -- int c, option_index; -- int reset_flag = 1; -- -- for (;;) { -- c = getopt_long (argc, argv, options, long_options, &option_index); -- if (c == -1) break; -- -- switch (c) { -- case 0: -- /* Options which are long only. */ -- if (STREQ (long_options[option_index].name, "virtio-serial-upload")) { -- reset_default_tests (&reset_flag); -- virtio_serial_upload = 1; -- } -- else if (STREQ (long_options[option_index].name, "virtio-serial-download")) { -- reset_default_tests (&reset_flag); -- virtio_serial_download = 1; -- } -- else if (STREQ (long_options[option_index].name, "block-device-write")) { -- reset_default_tests (&reset_flag); -- block_device_write = 1; -- } -- else if (STREQ (long_options[option_index].name, "block-device-read")) { -- reset_default_tests (&reset_flag); -- block_device_read = 1; -- } -- else { -- fprintf (stderr, "%s: unknown long option: %s (%d)\n", -- guestfs_int_program_name, long_options[option_index].name, option_index); -- exit (EXIT_FAILURE); -- } -- break; -- -- case 't': -- if (sscanf (optarg, "%d", &max_time_override) != 1 || -- max_time_override < 0) { -- fprintf (stderr, "%s: -t: argument is not a positive integer\n", -- guestfs_int_program_name); -- exit (EXIT_FAILURE); -- } -- break; -- -- case HELP_OPTION: -- usage (EXIT_SUCCESS); -- -- default: -- usage (EXIT_FAILURE); -- } -- } -- -- if (optind != argc) { -- fprintf (stderr, "%s: extra arguments found on the command line\n", -- guestfs_int_program_name); -- exit (EXIT_FAILURE); -- } -- -- test_virtio_serial (); -- test_block_device (); -- -- exit (EXIT_SUCCESS); --} -- --static void --print_rate (const char *msg, int64_t rate) --{ -- printf ("%-40s %" PRIi64 " bytes/sec (%" PRIi64 " Mbytes/sec)\n", -- msg, rate, rate / 1024 / 1024); -- fflush (stdout); --} -- --/* The maximum time we will spend running the test (seconds). */ --#define TEST_SERIAL_MAX_TIME 30 -- --/* The maximum amount of data to copy. You can safely make this very -- * large because it's only making sparse files. -- */ --#define TEST_SERIAL_MAX_SIZE \ -- (INT64_C(1024) * INT64_C(1024) * INT64_C(1024) * INT64_C(1024)) -- --static guestfs_h *g; --static struct timeval start; --static const char *operation; --static int64_t rate; -- --static void --stop_transfer (int sig) --{ -- guestfs_user_cancel (g); --} -- --/* Compute Y - X and return the result in milliseconds. -- * Approximately the same as this code: -- * http://www.mpp.mpg.de/~huber/util/timevaldiff.c -- */ --static int64_t --timeval_diff (const struct timeval *x, const struct timeval *y) --{ -- int64_t msec; -- -- msec = (y->tv_sec - x->tv_sec) * 1000; -- msec += (y->tv_usec - x->tv_usec) / 1000; -- return msec; --} -- --static void --progress_cb (guestfs_h *g, void *vp, uint64_t event, -- int eh, int flags, -- const char *buf, size_t buflen, -- const uint64_t *array, size_t arraylen) --{ -- uint64_t transferred; -- struct timeval now; -- int64_t millis; -- -- assert (event == GUESTFS_EVENT_PROGRESS); -- assert (arraylen >= 4); -- -- gettimeofday (&now, NULL); -- -- /* Bytes transferred. */ -- transferred = array[2]; -- -- /* Calculate the speed of the upload or download. */ -- millis = timeval_diff (&start, &now); -- assert (millis >= 0); -- -- if (millis != 0) { -- rate = 1000 * transferred / millis; -- printf ("%s: %" PRIi64 " bytes/sec \r", -- operation, rate); -- fflush (stdout); -- } --} -- --static void --test_virtio_serial (void) --{ -- int fd, r, eh; -- char tmpfile[] = "/tmp/speedtestXXXXXX"; -- struct sigaction sa, old_sa; -- -- if (!virtio_serial_upload && !virtio_serial_download) -- return; -- -- /* Create a sparse file. We could upload from /dev/zero, but we -- * won't get progress messages because libguestfs tests if the -- * source file is a regular file. -- */ -- fd = mkstemp (tmpfile); -- if (fd == -1) { -- perror ("mkstemp"); -- exit (EXIT_FAILURE); -- } -- if (ftruncate (fd, TEST_SERIAL_MAX_SIZE) == -1) { -- perror ("ftruncate"); -- exit (EXIT_FAILURE); -- } -- if (close (fd) == -1) { -- perror ("close"); -- exit (EXIT_FAILURE); -- } -- -- g = guestfs_create (); -- if (!g) { -- perror ("guestfs_create"); -- exit (EXIT_FAILURE); -- } -- -- if (guestfs_add_drive_scratch (g, INT64_C (100*1024*1024), -1) == -1) -- exit (EXIT_FAILURE); -- -- if (guestfs_launch (g) == -1) -- exit (EXIT_FAILURE); -- -- /* Make and mount a filesystem which will be used by the download test. */ -- if (guestfs_mkfs (g, "ext4", "/dev/sda") == -1) -- exit (EXIT_FAILURE); -- if (guestfs_mount (g, "/dev/sda", "/") == -1) -- exit (EXIT_FAILURE); -- -- /* Time out the upload after TEST_SERIAL_MAX_TIME seconds have passed. */ -- memset (&sa, 0, sizeof sa); -- sa.sa_handler = stop_transfer; -- sa.sa_flags = SA_RESTART; -- sigaction (SIGALRM, &sa, &old_sa); -- -- /* Get progress messages, which will tell us how much data has been -- * transferred. -- */ -- eh = guestfs_set_event_callback (g, progress_cb, GUESTFS_EVENT_PROGRESS, -- 0, NULL); -- if (eh == -1) -- exit (EXIT_FAILURE); -- -- if (virtio_serial_upload) { -- gettimeofday (&start, NULL); -- rate = -1; -- operation = "upload"; -- alarm (max_time_override > 0 ? max_time_override : TEST_SERIAL_MAX_TIME); -- -- /* For the upload test, upload the sparse file to /dev/null in the -- * appliance. Hopefully this is mostly testing just virtio-serial. -- */ -- guestfs_push_error_handler (g, NULL, NULL); -- r = guestfs_upload (g, tmpfile, "/dev/null"); -- alarm (0); -- unlink (tmpfile); -- guestfs_pop_error_handler (g); -- -- /* It's possible that the upload will finish before the alarm fires, -- * or that the upload will be stopped by the alarm. -- */ -- if (r == -1 && guestfs_last_errno (g) != EINTR) { -- fprintf (stderr, -- "%s: expecting upload command to return EINTR\n%s\n", -- guestfs_int_program_name, guestfs_last_error (g)); -- exit (EXIT_FAILURE); -- } -- -- if (rate == -1) { -- rate_error: -- fprintf (stderr, "%s: internal error: progress callback was not called! (r=%d, errno=%d)\n", -- guestfs_int_program_name, -- r, guestfs_last_errno (g)); -- exit (EXIT_FAILURE); -- } -- -- print_rate ("virtio-serial upload rate:", rate); -- } -- -- if (virtio_serial_download) { -- /* For the download test, download a sparse file within the -- * appliance to /dev/null on the host. -- */ -- if (guestfs_touch (g, "/sparse") == -1) -- exit (EXIT_FAILURE); -- if (guestfs_truncate_size (g, "/sparse", TEST_SERIAL_MAX_SIZE) == -1) -- exit (EXIT_FAILURE); -- -- gettimeofday (&start, NULL); -- rate = -1; -- operation = "download"; -- alarm (max_time_override > 0 ? max_time_override : TEST_SERIAL_MAX_TIME); -- guestfs_push_error_handler (g, NULL, NULL); -- r = guestfs_download (g, "/sparse", "/dev/null"); -- alarm (0); -- guestfs_pop_error_handler (g); -- -- if (r == -1 && guestfs_last_errno (g) != EINTR) { -- fprintf (stderr, -- "%s: expecting download command to return EINTR\n%s\n", -- guestfs_int_program_name, guestfs_last_error (g)); -- exit (EXIT_FAILURE); -- } -- -- if (rate == -1) -- goto rate_error; -- -- print_rate ("virtio-serial download rate:", rate); -- } -- -- if (guestfs_shutdown (g) == -1) -- exit (EXIT_FAILURE); -- -- guestfs_close (g); -- -- /* Restore SIGALRM signal handler. */ -- sigaction (SIGALRM, &old_sa, NULL); --} -- --/* The time we will spend running the test (seconds). */ --#define TEST_BLOCK_DEVICE_TIME 30 -- --static void --test_block_device (void) --{ -- int fd; -- char tmpfile[] = "/tmp/speedtestXXXXXX"; -- CLEANUP_FREE char **devices = NULL; -- char *r; -- const char *argv[4]; -- const int t = -- max_time_override > 0 ? max_time_override : TEST_BLOCK_DEVICE_TIME; -- char tbuf[64]; -- int64_t bytes_written, bytes_read; -- -- if (!block_device_write && !block_device_read) -- return; -- -- snprintf (tbuf, sizeof tbuf, "%d", t); -- -- g = guestfs_create (); -- if (!g) { -- perror ("guestfs_create"); -- exit (EXIT_FAILURE); -- } -- -- /* Create a fully allocated backing file. Note we are not testing -- * the speed of allocation on the host. -- */ -- fd = mkstemp (tmpfile); -- if (fd == -1) { -- perror ("mkstemp"); -- exit (EXIT_FAILURE); -- } -- close (fd); -- -- if (guestfs_disk_create (g, tmpfile, "raw", -- INT64_C (1024*1024*1024), -- GUESTFS_DISK_CREATE_PREALLOCATION, "full", -- -1) == -1) -- exit (EXIT_FAILURE); -- -- if (guestfs_add_drive (g, tmpfile) == -1) -- exit (EXIT_FAILURE); -- -- if (guestfs_launch (g) == -1) -- exit (EXIT_FAILURE); -- -- devices = guestfs_list_devices (g); -- if (devices == NULL) -- exit (EXIT_FAILURE); -- if (devices[0] == NULL) { -- fprintf (stderr, "%s: expected guestfs_list_devices to return at least 1 device\n", -- guestfs_int_program_name); -- exit (EXIT_FAILURE); -- } -- -- if (block_device_write) { -- /* Test write speed. */ -- argv[0] = devices[0]; -- argv[1] = "w"; -- argv[2] = tbuf; -- argv[3] = NULL; -- r = guestfs_debug (g, "device_speed", (char **) argv); -- if (r == NULL) -- exit (EXIT_FAILURE); -- -- if (sscanf (r, "%" SCNi64, &bytes_written) != 1) { -- fprintf (stderr, "%s: could not parse device_speed output\n", -- guestfs_int_program_name); -- exit (EXIT_FAILURE); -- } -- -- print_rate ("block device writes:", bytes_written / t); -- } -- -- if (block_device_read) { -- /* Test read speed. */ -- argv[0] = devices[0]; -- argv[1] = "r"; -- argv[2] = tbuf; -- argv[3] = NULL; -- r = guestfs_debug (g, "device_speed", (char **) argv); -- if (r == NULL) -- exit (EXIT_FAILURE); -- -- if (sscanf (r, "%" SCNi64, &bytes_read) != 1) { -- fprintf (stderr, "%s: could not parse device_speed output\n", -- guestfs_int_program_name); -- exit (EXIT_FAILURE); -- } -- -- print_rate ("block device reads:", bytes_read / t); -- } -- -- if (guestfs_shutdown (g) == -1) -- exit (EXIT_FAILURE); -- -- guestfs_close (g); -- -- /* Remove temporary file. */ -- unlink (tmpfile); --} -diff --git a/utils/boot-analysis/Makefile.am b/utils/boot-analysis/Makefile.am -new file mode 100644 -index 0000000..ef9b2cb ---- /dev/null -+++ b/utils/boot-analysis/Makefile.am -@@ -0,0 +1,43 @@ -+# libguestfs -+# Copyright (C) 2011-2016 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 $(top_srcdir)/subdir-rules.mk -+ -+noinst_PROGRAMS = boot-analysis -+ -+boot_analysis_SOURCES = \ -+ boot-analysis.c \ -+ boot-analysis.h \ -+ boot-analysis-timeline.c \ -+ boot-analysis-utils.c \ -+ boot-analysis-utils.h -+boot_analysis_CPPFLAGS = \ -+ -I$(top_srcdir)/gnulib/lib -I$(top_builddir)/gnulib/lib \ -+ -I$(top_srcdir)/src -I$(top_builddir)/src -+boot_analysis_CFLAGS = \ -+ -pthread \ -+ $(WARN_CFLAGS) $(WERROR_CFLAGS) \ -+ $(PCRE_CFLAGS) -+boot_analysis_LDADD = \ -+ $(top_builddir)/src/libutils.la \ -+ $(top_builddir)/src/libguestfs.la \ -+ $(PCRE_LIBS) \ -+ $(LIBXML2_LIBS) \ -+ $(LIBVIRT_LIBS) \ -+ $(LTLIBINTL) \ -+ $(top_builddir)/gnulib/lib/libgnu.la \ -+ -lm -diff --git a/utils/boot-analysis/boot-analysis-timeline.c b/utils/boot-analysis/boot-analysis-timeline.c -new file mode 100644 -index 0000000..09a78ef ---- /dev/null -+++ b/utils/boot-analysis/boot-analysis-timeline.c -@@ -0,0 +1,523 @@ -+/* libguestfs -+ * Copyright (C) 2016 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 -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include "ignore-value.h" -+ -+#include "guestfs.h" -+#include "guestfs-internal-frontend.h" -+ -+#include "boot-analysis.h" -+ -+COMPILE_REGEXP(re_initcall_calling_module, -+ "calling ([_A-Za-z0-9]+)\\+.*\\[([_A-Za-z0-9]+)]", 0) -+COMPILE_REGEXP(re_initcall_calling, -+ "calling ([_A-Za-z0-9]+)\\+", 0) -+ -+static void construct_initcall_timeline (void); -+ -+/* "supermin: internal insmod xx.ko" -> "insmod xx.ko" */ -+static char * -+translate_supermin_insmod_message (const char *message) -+{ -+ char *ret; -+ -+ assert (STRPREFIX (message, "supermin: internal ")); -+ -+ ret = strdup (message + strlen ("supermin: internal ")); -+ if (ret == NULL) -+ error (EXIT_FAILURE, errno, "strdup"); -+ return ret; -+} -+ -+/* Analyze significant events from the events array, to form a -+ * timeline of activities. -+ */ -+void -+construct_timeline (void) -+{ -+ size_t i, j, k; -+ struct pass_data *data; -+ struct activity *activity; -+ -+ for (i = 0; i < NR_TEST_PASSES; ++i) { -+ data = &pass_data[i]; -+ -+ /* Find an activity, by matching an event with the condition -+ * `begin_cond' through to the second event `end_cond'. Create an -+ * activity object in the timeline from the result. -+ */ -+#define FIND(name, flags, begin_cond, end_cond) \ -+ do { \ -+ activity = NULL; \ -+ for (j = 0; j < data->nr_events; ++j) { \ -+ if (begin_cond) { \ -+ for (k = j+1; k < data->nr_events; ++k) { \ -+ if (end_cond) { \ -+ if (i == 0) \ -+ activity = add_activity (name, flags); \ -+ else \ -+ activity = find_activity (name); \ -+ break; \ -+ } \ -+ } \ -+ break; \ -+ } \ -+ } \ -+ if (activity) { \ -+ activity->start_event[i] = j; \ -+ activity->end_event[i] = k; \ -+ } \ -+ else \ -+ error (EXIT_FAILURE, 0, "could not find activity '%s' in pass '%zu'", \ -+ name, i); \ -+ } while (0) -+ -+ /* Same as FIND() macro, but if no matching events are found, -+ * ignore it. -+ */ -+#define FIND_OPTIONAL(name, flags, begin_cond, end_cond) \ -+ do { \ -+ activity = NULL; \ -+ for (j = 0; j < data->nr_events; ++j) { \ -+ if (begin_cond) { \ -+ for (k = j+1; k < data->nr_events; ++k) { \ -+ if (end_cond) { \ -+ if (i == 0) \ -+ activity = add_activity (name, flags); \ -+ else \ -+ activity = find_activity (name); \ -+ break; \ -+ } \ -+ } \ -+ break; \ -+ } \ -+ } \ -+ if (activity) { \ -+ activity->start_event[i] = j; \ -+ activity->end_event[i] = k; \ -+ } \ -+ } while (0) -+ -+ /* Find multiple entries, where we check for: -+ * next_cond -+ * next_cond -+ * next_cond -+ * end_cond -+ */ -+#define FIND_MULTIPLE(debug_name, flags, next_cond, end_cond, translate_message) \ -+ do { \ -+ activity = NULL; \ -+ for (j = 0; j < data->nr_events; ++j) { \ -+ if (next_cond) { \ -+ CLEANUP_FREE char *message = translate_message (data->events[j].message); \ -+ if (activity) \ -+ activity->end_event[i] = j; \ -+ if (i == 0) \ -+ activity = add_activity (message, flags); \ -+ else \ -+ activity = find_activity (message); \ -+ activity->start_event[i] = j; \ -+ } \ -+ else if (end_cond) \ -+ break; \ -+ } \ -+ if (j < data->nr_events && activity) \ -+ activity->end_event[i] = j; \ -+ else \ -+ error (EXIT_FAILURE, 0, "could not find activity '%s' in pass '%zu'", \ -+ debug_name, i); \ -+ } while (0) -+ -+ /* Add one activity which is going to cover the whole process -+ * from launch to close. The launch event is always event 0. -+ * NB: This activity must be called "run" (see below). -+ */ -+ FIND ("run", LONG_ACTIVITY, -+ j == 0, data->events[k].source == GUESTFS_EVENT_CLOSE); -+ -+ /* Find where we invoke supermin --build. This should be a null -+ * operation, but it still takes time to run the external command. -+ */ -+ FIND ("supermin:build", 0, -+ data->events[j].source == GUESTFS_EVENT_LIBRARY && -+ strstr (data->events[j].message, -+ "begin building supermin appliance"), -+ data->events[k].source == GUESTFS_EVENT_LIBRARY && -+ strstr (data->events[k].message, -+ "finished building supermin appliance")); -+ -+ /* Find where we invoke qemu to test features. */ -+ FIND_OPTIONAL ("qemu:feature-detect", 0, -+ data->events[j].source == GUESTFS_EVENT_LIBRARY && -+ strstr (data->events[j].message, -+ "begin testing qemu features"), -+ data->events[k].source == GUESTFS_EVENT_LIBRARY && -+ strstr (data->events[k].message, -+ "finished testing qemu features")); -+ -+ /* Find where we run qemu. */ -+ FIND_OPTIONAL ("qemu", LONG_ACTIVITY, -+ data->events[j].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[j].message, "-nodefconfig"), -+ data->events[k].source == GUESTFS_EVENT_CLOSE); -+ -+ /* For the libvirt backend, connecting to libvirt, getting -+ * capabilities, parsing capabilities etc. -+ */ -+ FIND_OPTIONAL ("libvirt:connect", 0, -+ data->events[j].source == GUESTFS_EVENT_LIBRARY && -+ strstr (data->events[j].message, "connect to libvirt"), -+ data->events[k].source == GUESTFS_EVENT_LIBRARY && -+ strstr (data->events[k].message, "successfully opened libvirt handle")); -+ FIND_OPTIONAL ("libvirt:get-libvirt-capabilities", 0, -+ data->events[j].source == GUESTFS_EVENT_LIBRARY && -+ strstr (data->events[j].message, "get libvirt capabilities"), -+ data->events[k].source == GUESTFS_EVENT_LIBRARY && -+ strstr (data->events[k].message, "parsing capabilities XML")); -+ -+ FIND_OPTIONAL ("libguestfs:parse-libvirt-capabilities", 0, -+ data->events[j].source == GUESTFS_EVENT_LIBRARY && -+ strstr (data->events[j].message, "parsing capabilities XML"), -+ data->events[k].source == GUESTFS_EVENT_LIBRARY && -+ strstr (data->events[k].message, "get_backend_setting")); -+ -+ FIND_OPTIONAL ("libguestfs:create-libvirt-xml", 0, -+ data->events[j].source == GUESTFS_EVENT_LIBRARY && -+ strstr (data->events[j].message, "create libvirt XML"), -+ data->events[k].source == GUESTFS_EVENT_LIBRARY && -+ strstr (data->events[k].message, "libvirt XML:")); -+ -+#if defined(__aarch64__) -+#define FIRST_KERNEL_MESSAGE "Booting Linux on physical CPU" -+#define FIRST_FIRMWARE_MESSAGE "UEFI firmware starting" -+#else -+#define SGABIOS_STRING "\033[1;256r\033[256;256H\033[6n" -+#define FIRST_KERNEL_MESSAGE "Probing EDD" -+#define FIRST_FIRMWARE_MESSAGE SGABIOS_STRING -+#endif -+ -+ /* For the libvirt backend, find the overhead of libvirt. */ -+ FIND_OPTIONAL ("libvirt:overhead", 0, -+ data->events[j].source == GUESTFS_EVENT_LIBRARY && -+ strstr (data->events[j].message, "launch libvirt guest"), -+ data->events[k].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[k].message, FIRST_FIRMWARE_MESSAGE)); -+ -+ /* From starting qemu up to entering the BIOS is the qemu overhead. */ -+ FIND_OPTIONAL ("qemu:overhead", 0, -+ data->events[j].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[j].message, "-nodefconfig"), -+ data->events[k].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[k].message, FIRST_FIRMWARE_MESSAGE)); -+ -+ /* From entering the BIOS to starting the kernel is the BIOS overhead. */ -+ FIND_OPTIONAL ("bios:overhead", 0, -+ data->events[j].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[j].message, FIRST_FIRMWARE_MESSAGE), -+ data->events[k].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[k].message, FIRST_KERNEL_MESSAGE)); -+ -+#if defined(__i386__) || defined(__x86_64__) -+ /* SGABIOS (option ROM). */ -+ FIND_OPTIONAL ("sgabios", 0, -+ data->events[j].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[j].message, SGABIOS_STRING), -+ data->events[k].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[k].message, "SeaBIOS (version")); -+#endif -+ -+#if defined(__i386__) || defined(__x86_64__) -+ /* SeaBIOS. */ -+ FIND ("seabios", 0, -+ data->events[j].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[j].message, "SeaBIOS (version"), -+ data->events[k].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[k].message, FIRST_KERNEL_MESSAGE)); -+#endif -+ -+#if defined(__i386__) || defined(__x86_64__) -+ /* SeaBIOS - only available when using debug messages. */ -+ FIND_OPTIONAL ("seabios:pci-probe", 0, -+ data->events[j].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[j].message, "Searching bootorder for: /pci@"), -+ data->events[k].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[k].message, "Scan for option roms")); -+#endif -+ -+ /* Find where we run the guest kernel. */ -+ FIND ("kernel", LONG_ACTIVITY, -+ data->events[j].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[j].message, FIRST_KERNEL_MESSAGE), -+ data->events[k].source == GUESTFS_EVENT_CLOSE); -+ -+ /* Kernel startup to userspace. */ -+ FIND ("kernel:overhead", 0, -+ data->events[j].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[j].message, FIRST_KERNEL_MESSAGE), -+ data->events[k].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[k].message, "supermin:") && -+ strstr (data->events[k].message, "starting up")); -+ -+ /* The time taken to get into start_kernel function. */ -+ FIND ("kernel:entry", 0, -+ data->events[j].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[j].message, FIRST_KERNEL_MESSAGE), -+ data->events[k].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[k].message, "Linux version")); -+ -+#if defined(__i386__) || defined(__x86_64__) -+ /* Alternatives patching instructions (XXX not very accurate we -+ * really need some debug messages inserted into the code). -+ */ -+ FIND ("kernel:alternatives", 0, -+ data->events[j].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[j].message, "Last level dTLB entries"), -+ data->events[k].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[k].message, "Freeing SMP alternatives")); -+#endif -+ -+ /* ftrace patching instructions. */ -+ FIND ("kernel:ftrace", 0, -+ data->events[j].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[j].message, "ftrace: allocating"), -+ 1); -+ -+ /* All initcall functions, before we enter userspace. */ -+ FIND ("kernel:initcalls-before-userspace", 0, -+ data->events[j].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[j].message, "calling "), -+ data->events[k].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[k].message, "Freeing unused kernel memory")); -+ -+ /* Find where we run supermin mini-initrd. */ -+ FIND ("supermin:mini-initrd", 0, -+ data->events[j].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[j].message, "supermin:") && -+ strstr (data->events[j].message, "starting up"), -+ data->events[k].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[k].message, "supermin: chroot")); -+ -+ /* Loading kernel modules from supermin initrd. */ -+ FIND_MULTIPLE -+ ("supermin insmod", 0, -+ data->events[j].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[j].message, "supermin: internal insmod"), -+ data->events[j].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[j].message, "supermin: picked"), -+ translate_supermin_insmod_message); -+ -+ /* Find where we run the /init script. */ -+ FIND ("/init", 0, -+ data->events[j].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[j].message, "supermin: chroot"), -+ data->events[k].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[k].message, "guestfsd --verbose")); -+ -+ /* Everything from the chroot to the first echo in the /init -+ * script counts as bash overhead. -+ */ -+ FIND ("bash:overhead", 0, -+ data->events[j].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[j].message, "supermin: chroot"), -+ data->events[k].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[k].message, "Starting /init script")); -+ -+ /* /init: Mount special filesystems. */ -+ FIND ("/init:mount-special", 0, -+ data->events[j].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[j].message, "*guestfs_boot_analysis=1*"), -+ data->events[k].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[k].message, "kmod static-nodes")); -+ -+ /* /init: Run kmod static-nodes */ -+ FIND ("/init:kmod-static-nodes", 0, -+ data->events[j].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[j].message, "kmod static-nodes"), -+ data->events[k].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[k].message, "systemd-tmpfiles")); -+ -+ /* /init: systemd-tmpfiles. */ -+ FIND ("/init:systemd-tmpfiles", 0, -+ data->events[j].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[j].message, "systemd-tmpfiles"), -+ data->events[k].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[k].message, "udev")); -+ -+ /* /init: start udevd. */ -+ FIND ("/init:udev-overhead", 0, -+ data->events[j].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[j].message, "udevd --daemon"), -+ data->events[k].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[k].message, "nullglob")); -+ -+ /* /init: set up network. */ -+ FIND ("/init:network-overhead", 0, -+ data->events[j].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[j].message, "+ ip addr"), -+ data->events[k].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[k].message, "+ test")); -+ -+ /* /init: probe MD arrays. */ -+ FIND ("/init:md-probe", 0, -+ data->events[j].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[j].message, "+ mdadm"), -+ data->events[k].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[k].message, "+ modprobe dm_mod")); -+ -+ /* /init: probe DM/LVM. */ -+ FIND ("/init:lvm-probe", 0, -+ data->events[j].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[j].message, "+ modprobe dm_mod"), -+ data->events[k].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[k].message, "+ ldmtool")); -+ -+ /* /init: probe Windows dynamic disks. */ -+ FIND ("/init:windows-dynamic-disks-probe", 0, -+ data->events[j].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[j].message, "+ ldmtool"), -+ data->events[k].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[k].message, "+ test")); -+ -+ /* Find where we run guestfsd. */ -+ FIND ("guestfsd", 0, -+ data->events[j].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[j].message, "guestfsd --verbose"), -+ data->events[k].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[k].message, "fsync /dev/sda")); -+ -+ /* Shutdown process. */ -+ FIND ("shutdown", 0, -+ data->events[j].source == GUESTFS_EVENT_TRACE && -+ STREQ (data->events[j].message, "close"), -+ data->events[k].source == GUESTFS_EVENT_CLOSE); -+ } -+ -+ construct_initcall_timeline (); -+} -+ -+/* Handling of initcall is so peculiar that we hide it in a separate -+ * function from the rest. -+ */ -+static void -+construct_initcall_timeline (void) -+{ -+ size_t i, j, k; -+ struct pass_data *data; -+ struct activity *activity; -+ -+ for (i = 0; i < NR_TEST_PASSES; ++i) { -+ data = &pass_data[i]; -+ -+ /* Each kernel initcall is bracketed by: -+ * -+ * calling ehci_hcd_init+0x0/0xc1 @ 1" -+ * initcall ehci_hcd_init+0x0/0xc1 returned 0 after 420 usecs" -+ * -+ * For initcall functions in modules: -+ * -+ * calling virtio_mmio_init+0x0/0x1000 [virtio_mmio] @ 1" -+ * initcall virtio_mmio_init+0x0/0x1000 [virtio_mmio] returned 0 after 14 usecs" -+ * -+ * Initcall functions can be nested, and do not have unique names. -+ */ -+ for (j = 0; j < data->nr_events; ++j) { -+ int vec[30], r; -+ const char *message = data->events[j].message; -+ -+ if (data->events[j].source == GUESTFS_EVENT_APPLIANCE && -+ ((r = pcre_exec (re_initcall_calling_module, NULL, -+ message, strlen (message), -+ 0, 0, vec, sizeof vec / sizeof vec[0])) >= 1 || -+ (r = pcre_exec (re_initcall_calling, NULL, -+ message, strlen (message), -+ 0, 0, vec, sizeof vec / sizeof vec[0])) >= 1)) { -+ -+ CLEANUP_FREE char *fn_name = NULL, *module_name = NULL; -+ if (r >= 2) /* because pcre_exec returns 1 + number of captures */ -+ fn_name = strndup (message + vec[2], vec[3]-vec[2]); -+ if (r >= 3) -+ module_name = strndup (message + vec[4], vec[5]-vec[4]); -+ -+ CLEANUP_FREE char *fullname; -+ if (asprintf (&fullname, "%s.%s", -+ module_name ? module_name : "kernel", fn_name) == -1) -+ error (EXIT_FAILURE, errno, "asprintf"); -+ -+ CLEANUP_FREE char *initcall_match; -+ if (asprintf (&initcall_match, "initcall %s", fn_name) == -1) -+ error (EXIT_FAILURE, errno, "asprintf"); -+ -+ /* Get a unique name for this activity. Unfortunately -+ * kernel initcall function names are not unique! -+ */ -+ CLEANUP_FREE char *activity_name; -+ if (asprintf (&activity_name, "initcall %s", fullname) == -1) -+ error (EXIT_FAILURE, errno, "asprintf"); -+ -+ if (i == 0) { -+ int n = 1; -+ while (activity_exists (activity_name)) { -+ free (activity_name); -+ if (asprintf (&activity_name, "initcall %s:%d", fullname, n) == -1) -+ error (EXIT_FAILURE, errno, "asprintf"); -+ n++; -+ } -+ } -+ else { -+ int n = 1; -+ while (!activity_exists_with_no_data (activity_name, i)) { -+ free (activity_name); -+ if (asprintf (&activity_name, "initcall %s:%d", fullname, n) == -1) -+ error (EXIT_FAILURE, errno, "asprintf"); -+ n++; -+ } -+ } -+ -+ /* Find the matching end event. It might be some time later, -+ * since it appears initcalls can be nested. -+ */ -+ for (k = j+1; k < data->nr_events; ++k) { -+ if (data->events[k].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[k].message, initcall_match)) { -+ if (i == 0) -+ activity = add_activity (activity_name, 0); -+ else -+ activity = find_activity (activity_name); -+ activity->start_event[i] = j; -+ activity->end_event[i] = k; -+ break; -+ } -+ } -+ } -+ } -+ } -+} -diff --git a/utils/boot-analysis/boot-analysis-utils.c b/utils/boot-analysis/boot-analysis-utils.c -new file mode 100644 -index 0000000..693b6f4 ---- /dev/null -+++ b/utils/boot-analysis/boot-analysis-utils.c -@@ -0,0 +1,90 @@ -+/* libguestfs -+ * Copyright (C) 2016 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 -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include "ignore-value.h" -+ -+#include "guestfs.h" -+#include "guestfs-internal-frontend.h" -+ -+#include "boot-analysis-utils.h" -+ -+void -+get_time (struct timespec *ts) -+{ -+ if (clock_gettime (CLOCK_REALTIME, ts) == -1) -+ error (EXIT_FAILURE, errno, "clock_gettime: CLOCK_REALTIME"); -+} -+ -+int64_t -+timespec_diff (const struct timespec *x, const struct timespec *y) -+{ -+ int64_t nsec; -+ -+ nsec = (y->tv_sec - x->tv_sec) * UINT64_C(1000000000); -+ nsec += y->tv_nsec - x->tv_nsec; -+ return nsec; -+} -+ -+void -+test_info (guestfs_h *g, int nr_test_passes) -+{ -+ const char *qemu = guestfs_get_hv (g); -+ CLEANUP_FREE char *cmd = NULL; -+ CLEANUP_FREE char *backend = NULL; -+ -+ /* Related to the test program. */ -+ printf ("test version: %s %s\n", PACKAGE_NAME, PACKAGE_VERSION_FULL); -+ printf (" test passes: %d\n", nr_test_passes); -+ -+ /* Related to the host. */ -+ printf ("host version: "); -+ fflush (stdout); -+ ignore_value (system ("uname -a")); -+ printf (" host CPU: "); -+ fflush (stdout); -+ ignore_value (system ("perl -n -e 'if (/^model name.*: (.*)/) { print \"$1\\n\"; exit }' /proc/cpuinfo")); -+ -+ /* Related to qemu. */ -+ backend = guestfs_get_backend (g); -+ printf (" backend: %-20s [to change set LIBGUESTFS_BACKEND]\n", -+ backend); -+ printf (" qemu: %-20s [to change set $LIBGUESTFS_HV]\n", qemu); -+ printf ("qemu version: "); -+ fflush (stdout); -+ if (asprintf (&cmd, "%s -version", qemu) == -1) -+ error (EXIT_FAILURE, errno, "asprintf"); -+ ignore_value (system (cmd)); -+ printf (" smp: %-20d [to change use --smp option]\n", -+ guestfs_get_smp (g)); -+ printf (" memsize: %-20d [to change use --memsize option]\n", -+ guestfs_get_memsize (g)); -+ -+ /* Related to the guest kernel. Be nice to get the guest -+ * kernel version here somehow (XXX). -+ */ -+ printf (" append: %-20s [to change use --append option]\n", -+ guestfs_get_append (g) ? : ""); -+} -diff --git a/utils/boot-analysis/boot-analysis-utils.h b/utils/boot-analysis/boot-analysis-utils.h -new file mode 100644 -index 0000000..95e4f06 ---- /dev/null -+++ b/utils/boot-analysis/boot-analysis-utils.h -@@ -0,0 +1,36 @@ -+/* libguestfs -+ * Copyright (C) 2016 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. -+ */ -+ -+#ifndef GUESTFS_BOOT_ANALYSIS_UTILS_H_ -+#define GUESTFS_BOOT_ANALYSIS_UTILS_H_ -+ -+/* Get current time, returning it in *ts. If there is a system call -+ * failure, this exits. -+ */ -+extern void get_time (struct timespec *ts); -+ -+/* Computes Y - X, returning nanoseconds. */ -+extern int64_t timespec_diff (const struct timespec *x, const struct timespec *y); -+ -+/* Display host machine and test parameters (to stdout). 'g' should -+ * be an open libguestfs handle. It is used for reading hv, memsize -+ * etc. and is not modified. -+ */ -+extern void test_info (guestfs_h *g, int nr_test_passes); -+ -+#endif /* GUESTFS_BOOT_ANALYSIS_UTILS_H_ */ -diff --git a/utils/boot-analysis/boot-analysis.c b/utils/boot-analysis/boot-analysis.c -new file mode 100644 -index 0000000..b90806b ---- /dev/null -+++ b/utils/boot-analysis/boot-analysis.c -@@ -0,0 +1,1268 @@ -+/* libguestfs -+ * Copyright (C) 2016 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. -+ */ -+ -+/* Trace and analyze the appliance boot process to find out which -+ * steps are taking the most time. It is not part of the standard -+ * tests. -+ * -+ * This needs to be run on a quiet machine, so that other processes -+ * disturb the timing as little as possible. The program is -+ * completely safe to run at any time. It doesn't read or write any -+ * external files, and it doesn't require root. -+ * -+ * You can run it from the build directory like this: -+ * -+ * make -+ * ./run utils/boot-analysis/boot-analysis -+ * -+ * The way it works is roughly like this: -+ * -+ * We create a libguestfs handle and register callback handlers so we -+ * can see appliance messages, trace events and so on. -+ * -+ * We then launch the handle and shut it down as quickly as possible. -+ * -+ * While the handle is running, events (seen by the callback handlers) -+ * are written verbatim into an in-memory buffer, with timestamps. -+ * -+ * Afterwards we analyze the result using regular expressions to try -+ * to identify a "timeline" for the handle (eg. at what time did the -+ * BIOS hand control to the kernel). This analysis is done in -+ * 'boot-analysis-timeline.c'. -+ * -+ * The whole process is repeated across a few runs, and the final -+ * timeline (including statistical analysis of the variation between -+ * runs) gets printed. -+ * -+ * The program is very sensitive to the specific messages printed by -+ * BIOS/kernel/supermin/userspace, so it won't work on non-x86, and it -+ * will require periodic adjustment of the regular expressions in -+ * order to keep things up to date. -+ */ -+ -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "guestfs.h" -+#include "guestfs-internal-frontend.h" -+ -+#include "boot-analysis.h" -+#include "boot-analysis-utils.h" -+ -+/* Activities taking longer than this % of the total time, except -+ * those flagged as LONG_ACTIVITY, are highlighted in red. -+ */ -+#define WARNING_THRESHOLD 1.0 -+ -+static const char *append = NULL; -+static int force_colour = 0; -+static int memsize = 0; -+static int smp = 1; -+static int verbose = 0; -+ -+static int libvirt_pipe[2] = { -1, -1 }; -+static ssize_t libvirt_pass = -1; -+ -+/* Because there is a separate thread which collects libvirt log data, -+ * we must protect the pass_data struct with a mutex. This only -+ * applies during the data collection passes. -+ */ -+static pthread_mutex_t pass_data_lock = PTHREAD_MUTEX_INITIALIZER; -+struct pass_data pass_data[NR_TEST_PASSES]; -+ -+size_t nr_activities; -+struct activity *activities; -+ -+static void run_test (void); -+static struct event *add_event (struct pass_data *, uint64_t source); -+static guestfs_h *create_handle (void); -+static void set_up_event_handlers (guestfs_h *g, size_t pass); -+static void libvirt_log_hack (int argc, char **argv); -+static void start_libvirt_thread (size_t pass); -+static void stop_libvirt_thread (void); -+static void add_drive (guestfs_h *g); -+static void check_pass_data (void); -+static void dump_pass_data (void); -+static void analyze_timeline (void); -+static void dump_timeline (void); -+static void print_analysis (void); -+static void print_longest_to_shortest (void); -+static void free_pass_data (void); -+static void free_final_timeline (void); -+static void ansi_green (void); -+static void ansi_red (void); -+static void ansi_blue (void); -+static void ansi_magenta (void); -+static void ansi_restore (void); -+ -+static void -+usage (int exitcode) -+{ -+ guestfs_h *g; -+ int default_memsize = -1; -+ -+ g = guestfs_create (); -+ if (g) { -+ default_memsize = guestfs_get_memsize (g); -+ guestfs_close (g); -+ } -+ -+ fprintf (stderr, -+ "boot-analysis: Trace and analyze the appliance boot process.\n" -+ "Usage:\n" -+ " boot-analysis [--options]\n" -+ "Options:\n" -+ " --help Display this usage text and exit.\n" -+ " --append OPTS Append OPTS to kernel command line.\n" -+ " --colour Output colours, even if not a terminal.\n" -+ " -m MB\n" -+ " --memsize MB Set memory size in MB (default: %d).\n" -+ " --smp N Enable N virtual CPUs (default: 1).\n" -+ " -v|--verbose Verbose output, useful for debugging.\n", -+ default_memsize); -+ exit (exitcode); -+} -+ -+int -+main (int argc, char *argv[]) -+{ -+ enum { HELP_OPTION = CHAR_MAX + 1 }; -+ static const char *options = "m:v"; -+ static const struct option long_options[] = { -+ { "help", 0, 0, HELP_OPTION }, -+ { "append", 1, 0, 0 }, -+ { "color", 0, 0, 0 }, -+ { "colour", 0, 0, 0 }, -+ { "memsize", 1, 0, 'm' }, -+ { "libvirt-pipe-0", 1, 0, 0 }, /* see libvirt_log_hack */ -+ { "libvirt-pipe-1", 1, 0, 0 }, -+ { "smp", 1, 0, 0 }, -+ { "verbose", 0, 0, 'v' }, -+ { 0, 0, 0, 0 } -+ }; -+ int c, option_index; -+ -+ for (;;) { -+ c = getopt_long (argc, argv, options, long_options, &option_index); -+ if (c == -1) break; -+ -+ switch (c) { -+ case 0: /* Options which are long only. */ -+ if (STREQ (long_options[option_index].name, "append")) { -+ append = optarg; -+ break; -+ } -+ else if (STREQ (long_options[option_index].name, "color") || -+ STREQ (long_options[option_index].name, "colour")) { -+ force_colour = 1; -+ break; -+ } -+ else if (STREQ (long_options[option_index].name, "libvirt-pipe-0")) { -+ if (sscanf (optarg, "%d", &libvirt_pipe[0]) != 1) -+ error (EXIT_FAILURE, 0, -+ "could not parse libvirt-pipe-0 parameter: %s", optarg); -+ break; -+ } -+ else if (STREQ (long_options[option_index].name, "libvirt-pipe-1")) { -+ if (sscanf (optarg, "%d", &libvirt_pipe[1]) != 1) -+ error (EXIT_FAILURE, 0, -+ "could not parse libvirt-pipe-1 parameter: %s", optarg); -+ break; -+ } -+ else if (STREQ (long_options[option_index].name, "smp")) { -+ if (sscanf (optarg, "%d", &smp) != 1) -+ error (EXIT_FAILURE, 0, -+ "could not parse smp parameter: %s", optarg); -+ break; -+ } -+ fprintf (stderr, "%s: unknown long option: %s (%d)\n", -+ guestfs_int_program_name, long_options[option_index].name, option_index); -+ exit (EXIT_FAILURE); -+ -+ case 'm': -+ if (sscanf (optarg, "%d", &memsize) != 1) { -+ fprintf (stderr, "%s: could not parse memsize parameter: %s\n", -+ guestfs_int_program_name, optarg); -+ exit (EXIT_FAILURE); -+ } -+ break; -+ -+ case 'v': -+ verbose = 1; -+ break; -+ -+ case HELP_OPTION: -+ usage (EXIT_SUCCESS); -+ -+ default: -+ usage (EXIT_FAILURE); -+ } -+ } -+ -+ libvirt_log_hack (argc, argv); -+ -+ if (STRNEQ (host_cpu, "x86_64") && STRNEQ (host_cpu, "aarch64")) -+ fprintf (stderr, "WARNING: host_cpu != x86_64|aarch64: This program may not work or give bogus results.\n"); -+ -+ run_test (); -+} -+ -+static void -+run_test (void) -+{ -+ guestfs_h *g; -+ size_t i; -+ -+ printf ("Warming up the libguestfs cache ...\n"); -+ for (i = 0; i < NR_WARMUP_PASSES; ++i) { -+ g = create_handle (); -+ add_drive (g); -+ if (guestfs_launch (g) == -1) -+ exit (EXIT_FAILURE); -+ guestfs_close (g); -+ } -+ -+ printf ("Running the tests in %d passes ...\n", NR_TEST_PASSES); -+ for (i = 0; i < NR_TEST_PASSES; ++i) { -+ g = create_handle (); -+ set_up_event_handlers (g, i); -+ start_libvirt_thread (i); -+ add_drive (g); -+ if (guestfs_launch (g) == -1) -+ exit (EXIT_FAILURE); -+ guestfs_close (g); -+ stop_libvirt_thread (); -+ -+ printf (" pass %zu: %zu events collected in %" PRIi64 " ns\n", -+ i+1, pass_data[i].nr_events, pass_data[i].elapsed_ns); -+ } -+ -+ if (verbose) -+ dump_pass_data (); -+ -+ printf ("Analyzing the results ...\n"); -+ check_pass_data (); -+ construct_timeline (); -+ analyze_timeline (); -+ -+ if (verbose) -+ dump_timeline (); -+ -+ printf ("\n"); -+ g = create_handle (); -+ test_info (g, NR_TEST_PASSES); -+ guestfs_close (g); -+ printf ("\n"); -+ print_analysis (); -+ printf ("\n"); -+ printf ("Longest activities:\n"); -+ printf ("\n"); -+ print_longest_to_shortest (); -+ -+ free_pass_data (); -+ free_final_timeline (); -+} -+ -+static struct event * -+add_event_unlocked (struct pass_data *data, uint64_t source) -+{ -+ struct event *ret; -+ -+ data->nr_events++; -+ data->events = realloc (data->events, -+ sizeof (struct event) * data->nr_events); -+ if (data->events == NULL) -+ error (EXIT_FAILURE, errno, "realloc"); -+ ret = &data->events[data->nr_events-1]; -+ get_time (&ret->t); -+ ret->source = source; -+ ret->message = NULL; -+ return ret; -+} -+ -+static struct event * -+add_event (struct pass_data *data, uint64_t source) -+{ -+ struct event *ret; -+ -+ pthread_mutex_lock (&pass_data_lock); -+ ret = add_event_unlocked (data, source); -+ pthread_mutex_unlock (&pass_data_lock); -+ return ret; -+} -+ -+/* Common function to create the handle and set various defaults. */ -+static guestfs_h * -+create_handle (void) -+{ -+ guestfs_h *g; -+ CLEANUP_FREE char *full_append = NULL; -+ -+ g = guestfs_create (); -+ if (!g) error (EXIT_FAILURE, errno, "guestfs_create"); -+ -+ if (memsize != 0) -+ if (guestfs_set_memsize (g, memsize) == -1) -+ exit (EXIT_FAILURE); -+ -+ if (smp >= 2) -+ if (guestfs_set_smp (g, smp) == -1) -+ exit (EXIT_FAILURE); -+ -+ /* This changes some details in appliance/init and enables a -+ * detailed trace of calls to initcall functions in the kernel. -+ */ -+ if (asprintf (&full_append, -+ "guestfs_boot_analysis=1 " -+ "ignore_loglevel initcall_debug " -+ "%s", -+ append != NULL ? append : "") == -1) -+ error (EXIT_FAILURE, errno, "asprintf"); -+ -+ if (guestfs_set_append (g, full_append) == -1) -+ exit (EXIT_FAILURE); -+ -+ return g; -+} -+ -+/* Common function to add the /dev/null drive. */ -+static void -+add_drive (guestfs_h *g) -+{ -+ if (guestfs_add_drive_opts (g, "/dev/null", -+ GUESTFS_ADD_DRIVE_OPTS_FORMAT, "raw", -+ GUESTFS_ADD_DRIVE_OPTS_READONLY, 1, -+ -1) == -1) -+ exit (EXIT_FAILURE); -+} -+ -+/* Called when the handle is closed. Perform any cleanups required in -+ * the pass_data here. -+ */ -+static void -+close_callback (guestfs_h *g, void *datavp, uint64_t source, -+ int eh, int flags, -+ const char *buf, size_t buf_len, -+ const uint64_t *array, size_t array_len) -+{ -+ struct pass_data *data = datavp; -+ struct event *event; -+ -+ if (!data->seen_launch) -+ return; -+ -+ event = add_event (data, source); -+ event->message = strdup ("close callback"); -+ if (event->message == NULL) -+ error (EXIT_FAILURE, errno, "strdup"); -+ -+ get_time (&data->end_t); -+ data->elapsed_ns = timespec_diff (&data->start_t, &data->end_t); -+} -+ -+/* Called when the qemu subprocess exits. -+ * XXX This is never called - why? -+ */ -+static void -+subprocess_quit_callback (guestfs_h *g, void *datavp, uint64_t source, -+ int eh, int flags, -+ const char *buf, size_t buf_len, -+ const uint64_t *array, size_t array_len) -+{ -+ struct pass_data *data = datavp; -+ struct event *event; -+ -+ if (!data->seen_launch) -+ return; -+ -+ event = add_event (data, source); -+ event->message = strdup ("subprocess quit callback"); -+ if (event->message == NULL) -+ error (EXIT_FAILURE, errno, "strdup"); -+} -+ -+/* Called when the launch operation is complete (the library and the -+ * guestfs daemon and talking to each other). -+ */ -+static void -+launch_done_callback (guestfs_h *g, void *datavp, uint64_t source, -+ int eh, int flags, -+ const char *buf, size_t buf_len, -+ const uint64_t *array, size_t array_len) -+{ -+ struct pass_data *data = datavp; -+ struct event *event; -+ -+ if (!data->seen_launch) -+ return; -+ -+ event = add_event (data, source); -+ event->message = strdup ("launch done callback"); -+ if (event->message == NULL) -+ error (EXIT_FAILURE, errno, "strdup"); -+} -+ -+/* Trim \r (multiple) from the end of a string. */ -+static void -+trim_r (char *message) -+{ -+ size_t len = strlen (message); -+ -+ while (len > 0 && message[len-1] == '\r') { -+ message[len-1] = '\0'; -+ len--; -+ } -+} -+ -+/* Called when we get (possibly part of) a log message (or more than -+ * one log message) from the appliance (which may include qemu, the -+ * BIOS, kernel, etc). -+ */ -+static void -+appliance_callback (guestfs_h *g, void *datavp, uint64_t source, -+ int eh, int flags, -+ const char *buf, size_t buf_len, -+ const uint64_t *array, size_t array_len) -+{ -+ struct pass_data *data = datavp; -+ struct event *event; -+ size_t i, len, slen; -+ -+ if (!data->seen_launch) -+ return; -+ -+ /* If the previous log message was incomplete, but time has moved on -+ * a lot, record a new log message anyway, so it gets a new -+ * timestamp. -+ */ -+ if (data->incomplete_log_message >= 0) { -+ struct timespec ts; -+ get_time (&ts); -+ if (timespec_diff (&data->events[data->incomplete_log_message].t, -+ &ts) >= 10000000 /* 10ms */) -+ data->incomplete_log_message = -1; -+ } -+ -+ /* If the previous log message was incomplete then we may need to -+ * append part of the current log message to a previous one. -+ */ -+ if (data->incomplete_log_message >= 0) { -+ len = buf_len; -+ for (i = 0; i < buf_len; ++i) { -+ if (buf[i] == '\n') { -+ len = i; -+ break; -+ } -+ } -+ -+ event = &data->events[data->incomplete_log_message]; -+ slen = strlen (event->message); -+ event->message = realloc (event->message, slen + len + 1); -+ if (event->message == NULL) -+ error (EXIT_FAILURE, errno, "realloc"); -+ memcpy (event->message + slen, buf, len); -+ event->message[slen + len] = '\0'; -+ trim_r (event->message); -+ -+ /* Skip what we just added to the previous incomplete message. */ -+ buf += len; -+ buf_len -= len; -+ -+ if (buf_len == 0) /* still not complete, more to come! */ -+ return; -+ -+ /* Skip the \n in the buffer. */ -+ buf++; -+ buf_len--; -+ data->incomplete_log_message = -1; -+ } -+ -+ /* Add the event, or perhaps multiple events if the message -+ * contains \n characters. -+ */ -+ while (buf_len > 0) { -+ len = buf_len; -+ for (i = 0; i < buf_len; ++i) { -+ if (buf[i] == '\n') { -+ len = i; -+ break; -+ } -+ } -+ -+ event = add_event (data, source); -+ event->message = strndup (buf, len); -+ if (event->message == NULL) -+ error (EXIT_FAILURE, errno, "strndup"); -+ trim_r (event->message); -+ -+ /* Skip what we just added to the event. */ -+ buf += len; -+ buf_len -= len; -+ -+ if (buf_len == 0) { -+ /* Event is incomplete (doesn't end with \n). We'll finish it -+ * in the next callback. -+ */ -+ data->incomplete_log_message = event - data->events; -+ return; -+ } -+ -+ /* Skip the \n in the buffer. */ -+ buf++; -+ buf_len--; -+ } -+} -+ -+/* Called when we get a debug message from the library side. These -+ * are always delivered as complete messages. -+ */ -+static void -+library_callback (guestfs_h *g, void *datavp, uint64_t source, -+ int eh, int flags, -+ const char *buf, size_t buf_len, -+ const uint64_t *array, size_t array_len) -+{ -+ struct pass_data *data = datavp; -+ struct event *event; -+ -+ if (!data->seen_launch) -+ return; -+ -+ event = add_event (data, source); -+ event->message = strndup (buf, buf_len); -+ if (event->message == NULL) -+ error (EXIT_FAILURE, errno, "strndup"); -+} -+ -+/* Called when we get a call trace message (a libguestfs API function -+ * has been called or is returning). These are always delivered as -+ * complete messages. -+ */ -+static void -+trace_callback (guestfs_h *g, void *datavp, uint64_t source, -+ int eh, int flags, -+ const char *buf, size_t buf_len, -+ const uint64_t *array, size_t array_len) -+{ -+ struct pass_data *data = datavp; -+ struct event *event; -+ char *message; -+ -+ message = strndup (buf, buf_len); -+ if (message == NULL) -+ error (EXIT_FAILURE, errno, "strndup"); -+ -+ if (STREQ (message, "launch")) -+ data->seen_launch = 1; -+ -+ if (!data->seen_launch) { -+ free (message); -+ return; -+ } -+ -+ event = add_event (data, source); -+ event->message = message; -+} -+ -+/* Common function to set up event callbacks and record data in memory -+ * for a particular pass (0 <= pass < NR_TEST_PASSES). -+ */ -+static void -+set_up_event_handlers (guestfs_h *g, size_t pass) -+{ -+ struct pass_data *data; -+ -+ assert (/* 0 <= pass && */ pass < NR_TEST_PASSES); -+ -+ data = &pass_data[pass]; -+ data->pass = pass; -+ data->nr_events = 0; -+ data->events = NULL; -+ get_time (&data->start_t); -+ data->incomplete_log_message = -1; -+ data->seen_launch = 0; -+ -+ guestfs_set_event_callback (g, close_callback, -+ GUESTFS_EVENT_CLOSE, 0, data); -+ guestfs_set_event_callback (g, subprocess_quit_callback, -+ GUESTFS_EVENT_SUBPROCESS_QUIT, 0, data); -+ guestfs_set_event_callback (g, launch_done_callback, -+ GUESTFS_EVENT_LAUNCH_DONE, 0, data); -+ guestfs_set_event_callback (g, appliance_callback, -+ GUESTFS_EVENT_APPLIANCE, 0, data); -+ guestfs_set_event_callback (g, library_callback, -+ GUESTFS_EVENT_LIBRARY, 0, data); -+ guestfs_set_event_callback (g, trace_callback, -+ GUESTFS_EVENT_TRACE, 0, data); -+ -+ guestfs_set_verbose (g, 1); -+ guestfs_set_trace (g, 1); -+} -+ -+/* libvirt debugging sucks in a number of concrete ways: -+ * -+ * - you can't get a synchronous callback from a log message -+ * - you can't enable logging per handle (only globally -+ * by setting environment variables) -+ * - you can't debug the daemon easily -+ * - it's very complex -+ * - it's very complex but not in ways that are practical or useful -+ * -+ * To get log messages at all, we need to create a pipe connected to a -+ * second thread, and when libvirt prints something to the pipe we log -+ * that. -+ * -+ * However that's not sufficient. Because logging is only enabled -+ * when libvirt examines environment variables at the start of the -+ * program, we need to create the pipe and then fork+exec a new -+ * instance of the whole program with the pipe and environment -+ * variables set up. -+ */ -+static int is_libvirt_backend (guestfs_h *g); -+static void *libvirt_log_thread (void *datavp); -+ -+static void -+libvirt_log_hack (int argc, char **argv) -+{ -+ guestfs_h *g; -+ -+ g = guestfs_create (); -+ if (!is_libvirt_backend (g)) { -+ guestfs_close (g); -+ return; -+ } -+ guestfs_close (g); -+ -+ /* Have we set up the pipes and environment and forked yet? If not, -+ * do that first. -+ */ -+ if (libvirt_pipe[0] == -1 || libvirt_pipe[1] == -1) { -+ char log_outputs[64]; -+ char **new_argv; -+ char param1[64], param2[64]; -+ size_t i; -+ pid_t pid; -+ int status; -+ -+ /* Create the pipe. NB: do NOT use O_CLOEXEC since we want to pass -+ * this pipe into a child process. -+ */ -+ if (pipe (libvirt_pipe) == -1) -+ error (EXIT_FAILURE, 0, "pipe2"); -+ -+ /* Create the environment variables to enable logging in libvirt. */ -+ setenv ("LIBVIRT_DEBUG", "1", 1); -+ //setenv ("LIBVIRT_LOG_FILTERS", -+ // "1:qemu 1:securit 3:file 3:event 3:object 1:util", 1); -+ snprintf (log_outputs, sizeof log_outputs, -+ "1:file:/dev/fd/%d", libvirt_pipe[1]); -+ setenv ("LIBVIRT_LOG_OUTPUTS", log_outputs, 1); -+ -+ /* Run self again. */ -+ new_argv = malloc ((argc+3) * sizeof (char *)); -+ if (new_argv == NULL) -+ error (EXIT_FAILURE, errno, "malloc"); -+ -+ for (i = 0; i < (size_t) argc; ++i) -+ new_argv[i] = argv[i]; -+ -+ snprintf (param1, sizeof param1, "--libvirt-pipe-0=%d", libvirt_pipe[0]); -+ new_argv[argc] = param1; -+ snprintf (param2, sizeof param2, "--libvirt-pipe-1=%d", libvirt_pipe[1]); -+ new_argv[argc+1] = param2; -+ new_argv[argc+2] = NULL; -+ -+ pid = fork (); -+ if (pid == -1) -+ error (EXIT_FAILURE, errno, "fork"); -+ if (pid == 0) { /* Child process. */ -+ execvp (argv[0], new_argv); -+ perror ("execvp"); -+ _exit (EXIT_FAILURE); -+ } -+ -+ if (waitpid (pid, &status, 0) == -1) -+ error (EXIT_FAILURE, errno, "waitpid"); -+ if (WIFEXITED (status)) -+ exit (WEXITSTATUS (status)); -+ error (EXIT_FAILURE, 0, "unexpected exit status from process: %d", status); -+ } -+ -+ /* If we reach this else clause, then we have forked. Now we must -+ * create a thread to read events from the pipe. This must be -+ * constantly reading from the pipe, otherwise we will deadlock. -+ * During the warm-up phase we end up throwing away messages. -+ */ -+ else { -+ pthread_t thread; -+ pthread_attr_t attr; -+ int r; -+ -+ r = pthread_attr_init (&attr); -+ if (r != 0) -+ error (EXIT_FAILURE, r, "pthread_attr_init"); -+ r = pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED); -+ if (r != 0) -+ error (EXIT_FAILURE, r, "pthread_attr_setdetachstate"); -+ r = pthread_create (&thread, &attr, libvirt_log_thread, NULL); -+ if (r != 0) -+ error (EXIT_FAILURE, r, "pthread_create"); -+ pthread_attr_destroy (&attr); -+ } -+} -+ -+static void -+start_libvirt_thread (size_t pass) -+{ -+ /* In the non-libvirt case, this variable is ignored. */ -+ pthread_mutex_lock (&pass_data_lock); -+ libvirt_pass = pass; -+ pthread_mutex_unlock (&pass_data_lock); -+} -+ -+static void -+stop_libvirt_thread (void) -+{ -+ /* In the non-libvirt case, this variable is ignored. */ -+ pthread_mutex_lock (&pass_data_lock); -+ libvirt_pass = -1; -+ pthread_mutex_unlock (&pass_data_lock); -+} -+ -+/* The separate "libvirt thread". It loops reading debug messages -+ * printed by libvirt and adds them to the pass_data. -+ */ -+static void * -+libvirt_log_thread (void *arg) -+{ -+ struct event *event; -+ CLEANUP_FREE char *buf = NULL; -+ ssize_t r; -+ -+ buf = malloc (BUFSIZ); -+ if (buf == NULL) -+ error (EXIT_FAILURE, errno, "malloc"); -+ -+ while ((r = read (libvirt_pipe[0], buf, BUFSIZ)) > 0) { -+ pthread_mutex_lock (&pass_data_lock); -+ if (libvirt_pass == -1) goto discard; -+ event = -+ add_event_unlocked (&pass_data[libvirt_pass], SOURCE_LIBVIRT); -+ event->message = strndup (buf, r); -+ if (event->message == NULL) -+ error (EXIT_FAILURE, errno, "strndup"); -+ discard: -+ pthread_mutex_unlock (&pass_data_lock); -+ } -+ -+ if (r == -1) -+ error (EXIT_FAILURE, errno, "libvirt_log_thread: read"); -+ -+ /* It's possible for the pipe to be closed (r == 0) if thread -+ * cancellation is delayed after the main thread exits, so just -+ * ignore that case and exit. -+ */ -+ pthread_exit (NULL); -+} -+ -+static int -+is_libvirt_backend (guestfs_h *g) -+{ -+ CLEANUP_FREE char *backend = guestfs_get_backend (g); -+ -+ return backend && -+ (STREQ (backend, "libvirt") || STRPREFIX (backend, "libvirt:")); -+} -+ -+/* Sanity check the collected events. */ -+static void -+check_pass_data (void) -+{ -+ size_t i, j, len; -+ int64_t ns; -+ const char *message; -+ -+ for (i = 0; i < NR_TEST_PASSES; ++i) { -+ assert (pass_data[i].pass == i); -+ assert (pass_data[i].elapsed_ns > 1000); -+ assert (pass_data[i].nr_events > 0); -+ assert (pass_data[i].events != NULL); -+ -+ for (j = 0; j < pass_data[i].nr_events; ++j) { -+ assert (pass_data[i].events[j].t.tv_sec > 0); -+ if (j > 0) { -+ ns = timespec_diff (&pass_data[i].events[j-1].t, -+ &pass_data[i].events[j].t); -+ assert (ns >= 0); -+ } -+ assert (pass_data[i].events[j].source != 0); -+ message = pass_data[i].events[j].message; -+ assert (message != NULL); -+ assert (pass_data[i].events[j].source != GUESTFS_EVENT_APPLIANCE || -+ strchr (message, '\n') == NULL); -+ len = strlen (message); -+ assert (len == 0 || message[len-1] != '\r'); -+ } -+ } -+} -+ -+static void -+print_escaped_string (const char *message) -+{ -+ while (*message) { -+ if (isprint (*message)) -+ putchar (*message); -+ else -+ printf ("\\x%02x", (unsigned int) *message); -+ message++; -+ } -+} -+ -+/* Dump the events to stdout, if verbose is set. */ -+static void -+dump_pass_data (void) -+{ -+ size_t i, j; -+ -+ for (i = 0; i < NR_TEST_PASSES; ++i) { -+ printf ("pass %zu\n", pass_data[i].pass); -+ printf (" number of events collected %zu\n", pass_data[i].nr_events); -+ printf (" elapsed time %" PRIi64 " ns\n", pass_data[i].elapsed_ns); -+ for (j = 0; j < pass_data[i].nr_events; ++j) { -+ int64_t ns, diff_ns; -+ CLEANUP_FREE char *source_str = NULL; -+ -+ ns = timespec_diff (&pass_data[i].start_t, &pass_data[i].events[j].t); -+ source_str = source_to_string (pass_data[i].events[j].source); -+ printf (" %.1fms ", ns / 1000000.0); -+ if (j > 0) { -+ diff_ns = timespec_diff (&pass_data[i].events[j-1].t, -+ &pass_data[i].events[j].t); -+ printf ("(+%.1f) ", diff_ns / 1000000.0); -+ } -+ printf ("[%s] \"", source_str); -+ print_escaped_string (pass_data[i].events[j].message); -+ printf ("\"\n"); -+ } -+ } -+} -+ -+/* Convert source to a printable string. The caller must free the -+ * returned string. -+ */ -+char * -+source_to_string (uint64_t source) -+{ -+ char *ret; -+ -+ if (source == SOURCE_LIBVIRT) { -+ ret = strdup ("libvirt"); -+ if (ret == NULL) -+ error (EXIT_FAILURE, errno, "strdup"); -+ } -+ else -+ ret = guestfs_event_to_string (source); -+ -+ return ret; /* caller frees */ -+} -+ -+int -+activity_exists (const char *name) -+{ -+ size_t i; -+ -+ for (i = 0; i < nr_activities; ++i) -+ if (STREQ (activities[i].name, name)) -+ return 1; -+ return 0; -+} -+ -+/* Add an activity to the global list. */ -+struct activity * -+add_activity (const char *name, int flags) -+{ -+ struct activity *ret; -+ size_t i; -+ -+ /* You shouldn't have two activities with the same name. */ -+ assert (!activity_exists (name)); -+ -+ nr_activities++; -+ activities = realloc (activities, sizeof (struct activity) * nr_activities); -+ if (activities == NULL) -+ error (EXIT_FAILURE, errno, "realloc"); -+ ret = &activities[nr_activities-1]; -+ ret->name = strdup (name); -+ if (ret->name == NULL) -+ error (EXIT_FAILURE, errno, "strdup"); -+ ret->flags = flags; -+ -+ for (i = 0; i < NR_TEST_PASSES; ++i) -+ ret->start_event[i] = ret->end_event[i] = 0; -+ -+ return ret; -+} -+ -+struct activity * -+find_activity (const char *name) -+{ -+ size_t i; -+ -+ for (i = 0; i < nr_activities; ++i) -+ if (STREQ (activities[i].name, name)) -+ return &activities[i]; -+ error (EXIT_FAILURE, 0, -+ "internal error: could not find activity '%s'", name); -+ /*NOTREACHED*/ -+ abort (); -+} -+ -+int -+activity_exists_with_no_data (const char *name, size_t pass) -+{ -+ size_t i; -+ -+ for (i = 0; i < nr_activities; ++i) -+ if (STREQ (activities[i].name, name) && -+ activities[i].start_event[pass] == 0 && -+ activities[i].end_event[pass] == 0) -+ return 1; -+ return 0; -+} -+ -+static int -+compare_activities_by_t (const void *av, const void *bv) -+{ -+ const struct activity *a = av; -+ const struct activity *b = bv; -+ -+ return a->t - b->t; -+} -+ -+/* Go through the activities, computing the start and elapsed time. */ -+static void -+analyze_timeline (void) -+{ -+ struct activity *activity; -+ size_t i, j; -+ int64_t delta_ns; -+ -+ for (j = 0; j < nr_activities; ++j) { -+ activity = &activities[j]; -+ -+ activity->t = 0; -+ activity->mean = 0; -+ for (i = 0; i < NR_TEST_PASSES; ++i) { -+ delta_ns = -+ timespec_diff (&pass_data[i].events[0].t, -+ &pass_data[i].events[activity->start_event[i]].t); -+ activity->t += delta_ns; -+ -+ delta_ns = -+ timespec_diff (&pass_data[i].events[activity->start_event[i]].t, -+ &pass_data[i].events[activity->end_event[i]].t); -+ activity->mean += delta_ns; -+ } -+ -+ /* Divide through to get real start time and mean of each activity. */ -+ activity->t /= NR_TEST_PASSES; -+ activity->mean /= NR_TEST_PASSES; -+ -+ /* Calculate the end time of this activity. It's convenient when -+ * drawing the timeline for one activity to finish just before the -+ * next activity starts, rather than having them end and start at -+ * the same time, hence ``- 1'' here. -+ */ -+ activity->end_t = activity->t + activity->mean - 1; -+ -+ /* The above only calculated mean. Now we are able to -+ * calculate from the mean the variance and the standard -+ * deviation. -+ */ -+ activity->variance = 0; -+ for (i = 0; i < NR_TEST_PASSES; ++i) { -+ delta_ns = -+ timespec_diff (&pass_data[i].events[activity->start_event[i]].t, -+ &pass_data[i].events[activity->end_event[i]].t); -+ activity->variance += pow (delta_ns - activity->mean, 2); -+ } -+ activity->variance /= NR_TEST_PASSES; -+ -+ activity->sd = sqrt (activity->variance); -+ } -+ -+ /* Get the total mean elapsed time from the special "run" activity. */ -+ activity = find_activity ("run"); -+ for (j = 0; j < nr_activities; ++j) { -+ activities[j].percent = 100.0 * activities[j].mean / activity->mean; -+ -+ activities[j].warning = -+ !(activities[j].flags & LONG_ACTIVITY) && -+ activities[j].percent >= WARNING_THRESHOLD; -+ } -+ -+ /* Sort the activities by start time. */ -+ qsort (activities, nr_activities, sizeof (struct activity), -+ compare_activities_by_t); -+} -+ -+/* Dump the timeline to stdout, if verbose is set. */ -+static void -+dump_timeline (void) -+{ -+ size_t i; -+ -+ for (i = 0; i < nr_activities; ++i) { -+ printf ("activity %zu:\n", i); -+ printf (" name = %s\n", activities[i].name); -+ printf (" start - end = %.1f - %.1f\n", -+ activities[i].t, activities[i].end_t); -+ printf (" mean elapsed = %.1f\n", activities[i].mean); -+ printf (" variance = %.1f\n", activities[i].variance); -+ printf (" s.d = %.1f\n", activities[i].sd); -+ printf (" percent = %.1f\n", activities[i].percent); -+ } -+} -+ -+static void -+print_activity (struct activity *activity) -+{ -+ if (activity->warning) ansi_red (); else ansi_green (); -+ print_escaped_string (activity->name); -+ ansi_restore (); -+ printf (" %.1fms ±%.1fms ", -+ activity->mean / 1000000, activity->sd / 1000000); -+ if (activity->warning) ansi_red (); else ansi_green (); -+ printf ("(%.1f%%) ", activity->percent); -+ ansi_restore (); -+} -+ -+static void -+print_analysis (void) -+{ -+ double t = -1; /* Current time. */ -+ /* Which columns contain activities that we are displaying now? -+ * -1 == unused column, else index of an activity -+ */ -+ CLEANUP_FREE ssize_t *columns = NULL; -+ const size_t nr_columns = nr_activities; -+ size_t last_free_column = 0; -+ -+ size_t i, j; -+ double last_t, smallest_next_t; -+ const double MAX_T = 1e20; -+ -+ columns = malloc (nr_columns * sizeof (ssize_t)); -+ if (columns == NULL) error (EXIT_FAILURE, errno, "malloc"); -+ for (j = 0; j < nr_columns; ++j) -+ columns[j] = -1; -+ -+ for (;;) { -+ /* Find the next significant time to display, which is a time when -+ * some activity started or ended. -+ */ -+ smallest_next_t = MAX_T; -+ for (i = 0; i < nr_activities; ++i) { -+ if (t < activities[i].t && activities[i].t < smallest_next_t) -+ smallest_next_t = activities[i].t; -+ else if (t < activities[i].end_t && activities[i].end_t < smallest_next_t) -+ smallest_next_t = activities[i].end_t; -+ } -+ if (smallest_next_t == MAX_T) -+ break; /* Finished. */ -+ -+ last_t = t; -+ t = smallest_next_t; -+ -+ /* Draw a spacer line, but only if last_t -> t is a large jump. */ -+ if (t - last_t >= 1000000 /* ns */) { -+ printf (" "); -+ ansi_magenta (); -+ for (j = 0; j < last_free_column; ++j) { -+ if (columns[j] >= 0 && -+ activities[columns[j]].end_t != last_t /* !▼ */) -+ printf ("│ "); -+ else -+ printf (" "); -+ } -+ ansi_restore (); -+ printf ("\n"); -+ } -+ -+ /* If there are any activities that ended before this time, drop -+ * them from the columns list. -+ */ -+ for (i = 0; i < nr_activities; ++i) { -+ if (activities[i].end_t < t) { -+ for (j = 0; j < nr_columns; ++j) -+ if (columns[j] == (ssize_t) i) { -+ columns[j] = -1; -+ break; -+ } -+ } -+ } -+ -+ /* May need to adjust last_free_column after previous operation. */ -+ while (last_free_column > 0 && columns[last_free_column-1] == -1) -+ last_free_column--; -+ -+ /* If there are any activities starting at this time, add them to -+ * the right hand end of the columns list. -+ */ -+ for (i = 0; i < nr_activities; ++i) { -+ if (activities[i].t == t) -+ columns[last_free_column++] = i; -+ } -+ -+ /* Draw the line. */ -+ ansi_blue (); -+ printf ("%6.1fms: ", t / 1000000); -+ -+ ansi_magenta (); -+ for (j = 0; j < last_free_column; ++j) { -+ if (columns[j] >= 0) { -+ if (activities[columns[j]].t == t) -+ printf ("▲ "); -+ else if (activities[columns[j]].end_t == t) -+ printf ("▼ "); -+ else -+ printf ("│ "); -+ } -+ else -+ printf (" "); -+ } -+ ansi_restore (); -+ -+ for (j = 0; j < last_free_column; ++j) { -+ if (columns[j] >= 0 && activities[columns[j]].t == t) /* ▲ */ -+ print_activity (&activities[columns[j]]); -+ } -+ -+ printf ("\n"); -+ } -+} -+ -+static int -+compare_activities_pointers_by_mean (const void *av, const void *bv) -+{ -+ const struct activity * const *a = av; -+ const struct activity * const *b = bv; -+ -+ return (*b)->mean - (*a)->mean; -+} -+ -+static void -+print_longest_to_shortest (void) -+{ -+ size_t i; -+ CLEANUP_FREE struct activity **longest; -+ -+ /* Sort the activities longest first. In order not to affect the -+ * global activities array, sort an array of pointers to the -+ * activities instead. -+ */ -+ longest = malloc (sizeof (struct activity *) * nr_activities); -+ for (i = 0; i < nr_activities; ++i) -+ longest[i] = &activities[i]; -+ -+ qsort (longest, nr_activities, sizeof (struct activity *), -+ compare_activities_pointers_by_mean); -+ -+ /* Display the activities, longest first. */ -+ for (i = 0; i < nr_activities; ++i) { -+ print_activity (longest[i]); -+ printf ("\n"); -+ } -+} -+ -+/* Free the non-static part of the pass_data structures. */ -+static void -+free_pass_data (void) -+{ -+ size_t i, j; -+ -+ for (i = 0; i < NR_TEST_PASSES; ++i) { -+ for (j = 0; j < pass_data[i].nr_events; ++j) -+ free (pass_data[i].events[j].message); -+ free (pass_data[i].events); -+ } -+} -+ -+static void -+free_final_timeline (void) -+{ -+ size_t i; -+ -+ for (i = 0; i < nr_activities; ++i) -+ free (activities[i].name); -+ free (activities); -+} -+ -+/* Colours. */ -+static void -+ansi_green (void) -+{ -+ if (force_colour || isatty (1)) -+ fputs ("\033[0;32m", stdout); -+} -+ -+static void -+ansi_red (void) -+{ -+ if (force_colour || isatty (1)) -+ fputs ("\033[1;31m", stdout); -+} -+ -+static void -+ansi_blue (void) -+{ -+ if (force_colour || isatty (1)) -+ fputs ("\033[1;34m", stdout); -+} -+ -+static void -+ansi_magenta (void) -+{ -+ if (force_colour || isatty (1)) -+ fputs ("\033[1;35m", stdout); -+} -+ -+static void -+ansi_restore (void) -+{ -+ if (force_colour || isatty (1)) -+ fputs ("\033[0m", stdout); -+} -diff --git a/utils/boot-analysis/boot-analysis.h b/utils/boot-analysis/boot-analysis.h -new file mode 100644 -index 0000000..a07f12e ---- /dev/null -+++ b/utils/boot-analysis/boot-analysis.h -@@ -0,0 +1,102 @@ -+/* libguestfs -+ * Copyright (C) 2016 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. -+ */ -+ -+#ifndef GUESTFS_BOOT_ANALYSIS_H_ -+#define GUESTFS_BOOT_ANALYSIS_H_ -+ -+#define NR_WARMUP_PASSES 3 -+#define NR_TEST_PASSES 5 -+ -+/* Per-pass data collected. */ -+struct pass_data { -+ size_t pass; -+ struct timespec start_t; -+ struct timespec end_t; -+ int64_t elapsed_ns; -+ -+ /* Array of timestamped events. */ -+ size_t nr_events; -+ struct event *events; -+ -+ /* Was the previous appliance log message incomplete? If so, this -+ * contains the index of that incomplete message in the events -+ * array. -+ */ -+ ssize_t incomplete_log_message; -+ -+ /* Have we seen the launch event yet? We don't record events until -+ * this one has been received. This makes it easy to base the -+ * timeline at event 0. -+ */ -+ int seen_launch; -+}; -+ -+/* The 'source' field in the event is a guestfs event -+ * (GUESTFS_EVENT_*). We also wish to encode libvirt as a source, so -+ * we use a magic/impossible value for that here. Note that events -+ * are bitmasks, and normally no more than one bit may be set. -+ */ -+#define SOURCE_LIBVIRT ((uint64_t)~0) -+extern char *source_to_string (uint64_t source); -+ -+struct event { -+ struct timespec t; -+ uint64_t source; -+ char *message; -+}; -+ -+extern struct pass_data pass_data[NR_TEST_PASSES]; -+ -+/* The final timeline consisting of various activities starting and -+ * ending. We're interested in when the activities start, and how -+ * long they take (mean, variance, standard deviation of length). -+ */ -+struct activity { -+ char *name; /* Name of this activity. */ -+ int flags; -+#define LONG_ACTIVITY 1 /* Expected to take a long time. */ -+ -+ /* For each pass, record the actual start & end events of this -+ * activity. -+ */ -+ size_t start_event[NR_TEST_PASSES]; -+ size_t end_event[NR_TEST_PASSES]; -+ -+ double t; /* Start (ns offset). */ -+ double end_t; /* t + mean - 1 */ -+ -+ /* Length of this activity. */ -+ double mean; /* Mean time elapsed (ns). */ -+ double variance; /* Variance. */ -+ double sd; /* Standard deviation. */ -+ double percent; /* Percent of total elapsed time. */ -+ -+ int warning; /* Appears in red. */ -+}; -+ -+extern size_t nr_activities; -+extern struct activity *activities; -+ -+extern int activity_exists (const char *name); -+extern struct activity *add_activity (const char *name, int flags); -+extern struct activity *find_activity (const char *name); -+extern int activity_exists_with_no_data (const char *name, size_t pass); -+ -+extern void construct_timeline (void); -+ -+#endif /* GUESTFS_BOOT_ANALYSIS_H_ */ -diff --git a/utils/boot-benchmark/Makefile.am b/utils/boot-benchmark/Makefile.am -new file mode 100644 -index 0000000..429832a ---- /dev/null -+++ b/utils/boot-benchmark/Makefile.am -@@ -0,0 +1,44 @@ -+# libguestfs -+# Copyright (C) 2011-2016 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. -+ -+# Safety and liveness tests of components that libguestfs depends upon -+# (not of libguestfs itself). Mainly this is for qemu and the kernel. -+# This test is the first to run. -+ -+include $(top_srcdir)/subdir-rules.mk -+ -+noinst_PROGRAMS = boot-benchmark -+ -+boot_benchmark_SOURCES = \ -+ boot-benchmark.c \ -+ ../boot-analysis/boot-analysis-utils.c \ -+ ../boot-analysis/boot-analysis-utils.h -+boot_benchmark_CPPFLAGS = \ -+ -I$(top_srcdir)/gnulib/lib -I$(top_builddir)/gnulib/lib \ -+ -I$(top_srcdir)/src -I$(top_builddir)/src \ -+ -I$(top_srcdir)/utils/boot-analysis -+boot_benchmark_CFLAGS = \ -+ $(WARN_CFLAGS) $(WERROR_CFLAGS) -+boot_benchmark_LDADD = \ -+ $(top_builddir)/src/libutils.la \ -+ $(top_builddir)/src/libguestfs.la \ -+ $(LIBXML2_LIBS) \ -+ $(LTLIBINTL) \ -+ $(top_builddir)/gnulib/lib/libgnu.la \ -+ -lm -+ -+EXTRA_DIST = boot-benchmark-range.pl -diff --git a/utils/boot-benchmark/boot-benchmark-range.pl b/utils/boot-benchmark/boot-benchmark-range.pl -new file mode 100755 -index 0000000..b69a835 ---- /dev/null -+++ b/utils/boot-benchmark/boot-benchmark-range.pl -@@ -0,0 +1,240 @@ -+#!/usr/bin/env perl -+# Copyright (C) 2016 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. -+ -+use warnings; -+use strict; -+ -+use Pod::Usage; -+use Getopt::Long; -+ -+=head1 NAME -+ -+boot-benchmark-range.pl - Benchmark libguestfs across a range of commits -+from another project -+ -+=head1 SYNOPSIS -+ -+ LIBGUESTFS_BACKEND=direct \ -+ LIBGUESTFS_HV=/path/to/qemu/x86_64-softmmu/qemu-system-x86_64 \ -+ ./run \ -+ utils/boot-benchmark/boot-benchmark-range.pl /path/to/qemu HEAD~50..HEAD -+ -+=head1 -+ -+Run F across a range of commits -+in another project. This is useful for finding performance -+regressions in other programs such as qemu or the Linux kernel which -+might be affecting libguestfs. -+ -+For example, suppose you suspect there has been a performance -+regression in qemu, somewhere between C. You could run -+the script like this: -+ -+ LIBGUESTFS_BACKEND=direct \ -+ LIBGUESTFS_HV=/path/to/qemu/x86_64-softmmu/qemu-system-x86_64 \ -+ ./run \ -+ utils/boot-benchmark/boot-benchmark-range.pl /path/to/qemu HEAD~50..HEAD -+ -+where F is the path to the qemu git repository. -+ -+The output is a list of the qemu commits, annotated by the benchmark -+time and some other information about how the time compares to the -+previous commit. -+ -+You should run these tests on an unloaded machine. In particular -+running a desktop environment, web browser and so on can make the -+benchmarks useless. -+ -+=head1 OPTIONS -+ -+=over 4 -+ -+=cut -+ -+my $help; -+ -+=item B<--help> -+ -+Display brief help. -+ -+=cut -+ -+my $man; -+ -+=item B<--man> -+ -+Display full documentation (man page). -+ -+=cut -+ -+my $benchmark_command; -+ -+=item B<--benchmark> C -+ -+Set the name of the benchmark to run. You only need to use this if -+the script cannot find the right path to the libguestfs -+F program. By default the script -+looks for this file in the same directory as its executable. -+ -+=cut -+ -+my $make_command = "make"; -+ -+=item B<--make> C -+ -+Set the command used to build the other project. The default is -+to run C. -+ -+If the command fails, then the commit is skipped. -+ -+=back -+ -+=cut -+ -+# Clean up the program name. -+my $progname = $0; -+$progname =~ s{.*/}{}; -+ -+# Parse options. -+GetOptions ("help|?" => \$help, -+ "man" => \$man, -+ "benchmark=s" => \$benchmark_command, -+ "make=s" => \$make_command, -+ ) or pod2usage (2); -+pod2usage (-exitval => 0) if $help; -+pod2usage (-exitval => 0, -verbose => 2) if $man; -+ -+die "$progname: missing argument: requires path to git repository and range of commits\n" unless @ARGV == 2; -+ -+my $dir = $ARGV[0]; -+my $range = $ARGV[1]; -+ -+die "$progname: $dir is not a git repository\n" -+ unless -d $dir && -d "$dir/.git"; -+ -+sub silently_run -+{ -+ open my $saveout, ">&STDOUT"; -+ open my $saveerr, ">&STDERR"; -+ open STDOUT, ">/dev/null"; -+ open STDERR, ">/dev/null"; -+ my $ret = system (@_); -+ open STDOUT, ">&", $saveout; -+ open STDERR, ">&", $saveerr; -+ return $ret; -+} -+ -+# Find the benchmark program and check it works. -+unless (defined $benchmark_command) { -+ $benchmark_command = $0; -+ $benchmark_command =~ s{/[^/]+$}{}; -+ $benchmark_command .= "/boot-benchmark"; -+ -+ my $r = silently_run ("$benchmark_command", "--help"); -+ die "$progname: cannot locate boot-benchmark program, try using --benchmark\n" unless $r == 0; -+} -+ -+# Get the top-most commit from the remote, and restore it on exit. -+my $top_commit = `git -C '$dir' rev-parse HEAD`; -+chomp $top_commit; -+ -+sub checkout -+{ -+ my $sha = shift; -+ my $ret = silently_run ("git", "-C", $dir, "checkout", $sha); -+ return $ret; -+} -+ -+END { -+ checkout ($top_commit); -+} -+ -+# Get the range of commits and log messages. -+my @range = (); -+open RANGE, "git -C '$dir' log --reverse --oneline $range |" or die; -+while () { -+ if (m/^([0-9a-f]+) (.*)/) { -+ my $sha = $1; -+ my $msg = $2; -+ push @range, [ $sha, $msg ]; -+ } -+} -+close RANGE or die; -+ -+# Run the test. -+my $prev_ms; -+foreach (@range) { -+ my ($sha, $msg) = @$_; -+ my $r; -+ -+ print "\n"; -+ print "$sha $msg\n"; -+ -+ # Checkout this commit in the other repo. -+ $r = checkout ($sha); -+ if ($r != 0) { -+ print "git checkout failed\n"; -+ next; -+ } -+ -+ # Build the repo, silently. -+ $r = silently_run ("cd $dir && $make_command"); -+ if ($r != 0) { -+ print "build failed\n"; -+ next; -+ } -+ -+ # Run the benchmark program and get the timing. -+ my ($time_ms, $time_str); -+ open BENCHMARK, "$benchmark_command | grep '^Result:' |" or die; -+ while () { -+ die unless m/^Result: (([\d.]+)ms ±[\d.]+ms)/; -+ $time_ms = $2; -+ $time_str = $1; -+ } -+ close BENCHMARK; -+ -+ print "\t", $time_str; -+ if (defined $prev_ms) { -+ if ($prev_ms > $time_ms) { -+ my $pc = 100 * ($prev_ms-$time_ms) / $time_ms; -+ if ($pc >= 1) { -+ printf (" ↑ improves performance by %0.1f%%", $pc); -+ } -+ } elsif ($prev_ms < $time_ms) { -+ my $pc = 100 * ($time_ms-$prev_ms) / $prev_ms; -+ if ($pc >= 1) { -+ printf (" ↓ degrades performance by %0.1f%%", $pc); -+ } -+ } -+ } -+ print "\n"; -+ $prev_ms = $time_ms; -+} -+ -+=head1 SEE ALSO -+ -+L, -+L. -+ -+=head1 AUTHOR -+ -+Richard W.M. Jones. -+ -+=head1 COPYRIGHT -+ -+Copyright (C) 2016 Red Hat Inc. -diff --git a/utils/boot-benchmark/boot-benchmark.c b/utils/boot-benchmark/boot-benchmark.c -new file mode 100644 -index 0000000..0508ee9 ---- /dev/null -+++ b/utils/boot-benchmark/boot-benchmark.c -@@ -0,0 +1,225 @@ -+/* libguestfs -+ * Copyright (C) 2016 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. -+ */ -+ -+/* Benchmark the time taken to boot the libguestfs appliance. */ -+ -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "guestfs.h" -+#include "guestfs-internal-frontend.h" -+ -+#include "boot-analysis-utils.h" -+ -+#define NR_WARMUP_PASSES 3 -+#define NR_TEST_PASSES 10 -+ -+static const char *append = NULL; -+static int memsize = 0; -+static int smp = 1; -+ -+static void run_test (void); -+static guestfs_h *create_handle (void); -+static void add_drive (guestfs_h *g); -+ -+static void -+usage (int exitcode) -+{ -+ guestfs_h *g; -+ int default_memsize = -1; -+ -+ g = guestfs_create (); -+ if (g) { -+ default_memsize = guestfs_get_memsize (g); -+ guestfs_close (g); -+ } -+ -+ fprintf (stderr, -+ "boot-benchmark: Benchmark the time taken to boot the libguestfs appliance.\n" -+ "Usage:\n" -+ " boot-benchmark [--options]\n" -+ "Options:\n" -+ " --help Display this usage text and exit.\n" -+ " --append OPTS Append OPTS to kernel command line.\n" -+ " -m MB\n" -+ " --memsize MB Set memory size in MB (default: %d).\n" -+ " --smp N Enable N virtual CPUs (default: 1).\n", -+ default_memsize); -+ exit (exitcode); -+} -+ -+int -+main (int argc, char *argv[]) -+{ -+ enum { HELP_OPTION = CHAR_MAX + 1 }; -+ static const char *options = "m:"; -+ static const struct option long_options[] = { -+ { "help", 0, 0, HELP_OPTION }, -+ { "append", 1, 0, 0 }, -+ { "memsize", 1, 0, 'm' }, -+ { "smp", 1, 0, 0 }, -+ { 0, 0, 0, 0 } -+ }; -+ int c, option_index; -+ -+ for (;;) { -+ c = getopt_long (argc, argv, options, long_options, &option_index); -+ if (c == -1) break; -+ -+ switch (c) { -+ case 0: /* Options which are long only. */ -+ if (STREQ (long_options[option_index].name, "append")) { -+ append = optarg; -+ break; -+ } -+ else if (STREQ (long_options[option_index].name, "smp")) { -+ if (sscanf (optarg, "%d", &smp) != 1) { -+ fprintf (stderr, "%s: could not parse smp parameter: %s\n", -+ guestfs_int_program_name, optarg); -+ exit (EXIT_FAILURE); -+ } -+ break; -+ } -+ fprintf (stderr, "%s: unknown long option: %s (%d)\n", -+ guestfs_int_program_name, long_options[option_index].name, option_index); -+ exit (EXIT_FAILURE); -+ -+ case 'm': -+ if (sscanf (optarg, "%d", &memsize) != 1) { -+ fprintf (stderr, "%s: could not parse memsize parameter: %s\n", -+ guestfs_int_program_name, optarg); -+ exit (EXIT_FAILURE); -+ } -+ break; -+ -+ case HELP_OPTION: -+ usage (EXIT_SUCCESS); -+ -+ default: -+ usage (EXIT_FAILURE); -+ } -+ } -+ -+ run_test (); -+} -+ -+static void -+run_test (void) -+{ -+ guestfs_h *g; -+ size_t i; -+ int64_t ns[NR_TEST_PASSES]; -+ double mean; -+ double variance; -+ double sd; -+ -+ printf ("Warming up the libguestfs cache ...\n"); -+ for (i = 0; i < NR_WARMUP_PASSES; ++i) { -+ g = create_handle (); -+ add_drive (g); -+ if (guestfs_launch (g) == -1) -+ exit (EXIT_FAILURE); -+ guestfs_close (g); -+ } -+ -+ printf ("Running the tests ...\n"); -+ for (i = 0; i < NR_TEST_PASSES; ++i) { -+ struct timespec start_t, end_t; -+ -+ g = create_handle (); -+ add_drive (g); -+ get_time (&start_t); -+ if (guestfs_launch (g) == -1) -+ exit (EXIT_FAILURE); -+ guestfs_close (g); -+ get_time (&end_t); -+ -+ ns[i] = timespec_diff (&start_t, &end_t); -+ } -+ -+ /* Calculate the mean. */ -+ mean = 0; -+ for (i = 0; i < NR_TEST_PASSES; ++i) -+ mean += ns[i]; -+ mean /= NR_TEST_PASSES; -+ -+ /* Calculate the variance and standard deviation. */ -+ variance = 0; -+ for (i = 0; i < NR_TEST_PASSES; ++i) -+ variance = pow (ns[i] - mean, 2); -+ variance /= NR_TEST_PASSES; -+ sd = sqrt (variance); -+ -+ /* Print the test parameters. */ -+ printf ("\n"); -+ g = create_handle (); -+ test_info (g, NR_TEST_PASSES); -+ guestfs_close (g); -+ -+ /* Print the result. */ -+ printf ("\n"); -+ printf ("Result: %.1fms ±%.1fms\n", mean / 1000000, sd / 1000000); -+} -+ -+/* Common function to create the handle and set various defaults. */ -+static guestfs_h * -+create_handle (void) -+{ -+ guestfs_h *g; -+ CLEANUP_FREE char *full_append = NULL; -+ -+ g = guestfs_create (); -+ if (!g) error (EXIT_FAILURE, errno, "guestfs_create"); -+ -+ if (memsize != 0) -+ if (guestfs_set_memsize (g, memsize) == -1) -+ exit (EXIT_FAILURE); -+ -+ if (smp >= 2) -+ if (guestfs_set_smp (g, smp) == -1) -+ exit (EXIT_FAILURE); -+ -+ if (append != NULL) -+ if (guestfs_set_append (g, full_append) == -1) -+ exit (EXIT_FAILURE); -+ -+ return g; -+} -+ -+/* Common function to add the /dev/null drive. */ -+static void -+add_drive (guestfs_h *g) -+{ -+ if (guestfs_add_drive_opts (g, "/dev/null", -+ GUESTFS_ADD_DRIVE_OPTS_FORMAT, "raw", -+ GUESTFS_ADD_DRIVE_OPTS_READONLY, 1, -+ -1) == -1) -+ exit (EXIT_FAILURE); -+} -diff --git a/utils/qemu-boot/Makefile.am b/utils/qemu-boot/Makefile.am -new file mode 100644 -index 0000000..d4716cc ---- /dev/null -+++ b/utils/qemu-boot/Makefile.am -@@ -0,0 +1,39 @@ -+# libguestfs -+# Copyright (C) 2011-2016 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 $(top_srcdir)/subdir-rules.mk -+ -+noinst_PROGRAMS = qemu-boot -+ -+qemu_boot_SOURCES = \ -+ ../../df/estimate-max-threads.c \ -+ ../../df/estimate-max-threads.h \ -+ qemu-boot.c -+qemu_boot_CPPFLAGS = \ -+ -I$(top_srcdir)/gnulib/lib -I$(top_builddir)/gnulib/lib \ -+ -I$(top_srcdir)/src -I$(top_builddir)/src \ -+ -I$(top_srcdir)/df -+qemu_boot_CFLAGS = \ -+ -pthread \ -+ $(WARN_CFLAGS) $(WERROR_CFLAGS) -+qemu_boot_LDADD = \ -+ $(top_builddir)/src/libutils.la \ -+ $(top_builddir)/src/libguestfs.la \ -+ $(LIBXML2_LIBS) \ -+ $(LIBVIRT_LIBS) \ -+ $(LTLIBINTL) \ -+ $(top_builddir)/gnulib/lib/libgnu.la -diff --git a/utils/qemu-boot/qemu-boot.c b/utils/qemu-boot/qemu-boot.c -new file mode 100644 -index 0000000..336c26e ---- /dev/null -+++ b/utils/qemu-boot/qemu-boot.c -@@ -0,0 +1,362 @@ -+/* libguestfs -+ * Copyright (C) 2014-2016 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. -+ */ -+ -+/* Ancient libguestfs had a script called test-bootbootboot which just -+ * booted up the appliance in a loop. This was necessary back in the -+ * bad old days when qemu was not very reliable. This is the -+ * spiritual successor of that script, designed to find bugs in -+ * aarch64 KVM. You can control the number of boots that are done and -+ * the amount of parallelism. -+ */ -+ -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "guestfs.h" -+#include "guestfs-internal-frontend.h" -+#include "estimate-max-threads.h" -+ -+#define MIN(a,b) ((a)<(b)?(a):(b)) -+ -+/* Maximum number of threads we would ever run. Note this should not -+ * be > 20, unless libvirt is modified to increase the maximum number -+ * of clients. User can override this limit using -P. -+ */ -+#define MAX_THREADS 12 -+ -+static size_t n; /* Number of qemu processes to run in total. */ -+static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; -+ -+static int ignore_errors = 0; -+static const char *log_template = NULL; -+static size_t log_file_size; -+static int trace = 0; -+static int verbose = 0; -+ -+/* Events captured by the --log option. */ -+static const uint64_t event_bitmask = -+ GUESTFS_EVENT_LIBRARY | -+ GUESTFS_EVENT_WARNING | -+ GUESTFS_EVENT_APPLIANCE | -+ GUESTFS_EVENT_TRACE; -+ -+struct thread_data { -+ int thread_num; -+ int r; -+}; -+ -+static void *start_thread (void *thread_data_vp); -+static void message_callback (guestfs_h *g, void *opaque, uint64_t event, int event_handle, int flags, const char *buf, size_t buf_len, const uint64_t *array, size_t array_len); -+ -+static void -+usage (int exitcode) -+{ -+ fprintf (stderr, -+ "qemu-boot: A program for repeatedly running the libguestfs appliance.\n" -+ "qemu-boot [-i] [--log output.%%] [-P ] -n \n" -+ " -i Ignore errors\n" -+ " --log \n" -+ " Write per-appliance logs to file (%% in name replaced by boot number)\n" -+ " -P Set number of parallel threads\n" -+ " (default is based on the amount of free memory)\n" -+ " -n Set number of appliances to run before exiting\n" -+ " -v Verbose appliance\n" -+ " -x Enable libguestfs tracing\n"); -+ exit (exitcode); -+} -+ -+int -+main (int argc, char *argv[]) -+{ -+ enum { HELP_OPTION = CHAR_MAX + 1 }; -+ static const char options[] = "in:P:vx"; -+ static const struct option long_options[] = { -+ { "help", 0, 0, HELP_OPTION }, -+ { "ignore", 0, 0, 'i' }, -+ { "log", 1, 0, 0 }, -+ { "number", 1, 0, 'n' }, -+ { "processes", 1, 0, 'P' }, -+ { "trace", 0, 0, 'x' }, -+ { "verbose", 0, 0, 'v' }, -+ { 0, 0, 0, 0 } -+ }; -+ size_t P = 0, i, errors; -+ int c, option_index; -+ int err; -+ void *status; -+ -+ for (;;) { -+ c = getopt_long (argc, argv, options, long_options, &option_index); -+ if (c == -1) break; -+ -+ switch (c) { -+ case 0: -+ /* Options which are long only. */ -+ if (STREQ (long_options[option_index].name, "log")) { -+ log_template = optarg; -+ log_file_size = strlen (log_template); -+ for (i = 0; i < strlen (log_template); ++i) { -+ if (log_template[i] == '%') -+ log_file_size += 64; -+ } -+ } -+ else { -+ fprintf (stderr, "%s: unknown long option: %s (%d)\n", -+ guestfs_int_program_name, long_options[option_index].name, option_index); -+ exit (EXIT_FAILURE); -+ } -+ break; -+ -+ case 'i': -+ ignore_errors = 1; -+ break; -+ -+ case 'n': -+ if (sscanf (optarg, "%zu", &n) != 1 || n == 0) { -+ fprintf (stderr, "%s: -n option not numeric and greater than 0\n", -+ guestfs_int_program_name); -+ exit (EXIT_FAILURE); -+ } -+ break; -+ -+ case 'P': -+ if (sscanf (optarg, "%zu", &P) != 1) { -+ fprintf (stderr, "%s: -P option not numeric\n", guestfs_int_program_name); -+ exit (EXIT_FAILURE); -+ } -+ break; -+ -+ case 'v': -+ verbose = 1; -+ break; -+ -+ case 'x': -+ trace = 1; -+ break; -+ -+ case HELP_OPTION: -+ usage (EXIT_SUCCESS); -+ -+ default: -+ usage (EXIT_FAILURE); -+ } -+ } -+ -+ if (n == 0) { -+ fprintf (stderr, -+ "%s: must specify number of processes to run (-n option)\n", -+ guestfs_int_program_name); -+ exit (EXIT_FAILURE); -+ } -+ -+ if (optind != argc) { -+ fprintf (stderr, "%s: extra arguments found on the command line\n", -+ guestfs_int_program_name); -+ exit (EXIT_FAILURE); -+ } -+ -+ /* Calculate the number of threads to use. */ -+ if (P > 0) -+ P = MIN (n, P); -+ else -+ P = MIN (n, MIN (MAX_THREADS, estimate_max_threads ())); -+ -+ /* Start the worker threads. */ -+ struct thread_data thread_data[P]; -+ pthread_t threads[P]; -+ -+ for (i = 0; i < P; ++i) { -+ thread_data[i].thread_num = i; -+ err = pthread_create (&threads[i], NULL, start_thread, &thread_data[i]); -+ if (err != 0) { -+ fprintf (stderr, "%s: pthread_create[%zu]: %s\n", -+ guestfs_int_program_name, i, strerror (err)); -+ exit (EXIT_FAILURE); -+ } -+ } -+ -+ /* Wait for the threads to exit. */ -+ errors = 0; -+ for (i = 0; i < P; ++i) { -+ err = pthread_join (threads[i], &status); -+ if (err != 0) { -+ fprintf (stderr, "%s: pthread_join[%zu]: %s\n", -+ guestfs_int_program_name, i, strerror (err)); -+ errors++; -+ } -+ if (*(int *)status == -1) -+ errors++; -+ } -+ -+ exit (errors == 0 ? EXIT_SUCCESS : EXIT_FAILURE); -+} -+ -+/* Worker thread. */ -+static void * -+start_thread (void *thread_data_vp) -+{ -+ struct thread_data *thread_data = thread_data_vp; -+ int quit = 0; -+ int err; -+ size_t i; -+ guestfs_h *g; -+ unsigned errors = 0; -+ char id[64]; -+ -+ for (;;) { -+ CLEANUP_FREE char *log_file = NULL; -+ CLEANUP_FCLOSE FILE *log_fp = NULL; -+ -+ /* Take the next process. */ -+ err = pthread_mutex_lock (&mutex); -+ if (err != 0) { -+ fprintf (stderr, "%s: pthread_mutex_lock: %s", -+ guestfs_int_program_name, strerror (err)); -+ goto error; -+ } -+ -+ i = n; -+ if (i > 0) { -+ printf ("%zu to go ... \r", n); -+ fflush (stdout); -+ -+ n--; -+ } -+ else -+ quit = 1; -+ -+ err = pthread_mutex_unlock (&mutex); -+ if (err != 0) { -+ fprintf (stderr, "%s: pthread_mutex_unlock: %s", -+ guestfs_int_program_name, strerror (err)); -+ goto error; -+ } -+ -+ if (quit) /* Work finished. */ -+ break; -+ -+ g = guestfs_create (); -+ if (g == NULL) { -+ perror ("guestfs_create"); -+ errors++; -+ if (!ignore_errors) -+ goto error; -+ } -+ -+ /* Only if using --log, set up a callback. See examples/debug-logging.c */ -+ if (log_template != NULL) { -+ size_t j, k; -+ -+ log_file = malloc (log_file_size + 1); -+ if (log_file == NULL) abort (); -+ for (j = 0, k = 0; j < strlen (log_template); ++j) { -+ if (log_template[j] == '%') { -+ snprintf (&log_file[k], log_file_size - k, "%zu", i); -+ k += strlen (&log_file[k]); -+ } -+ else -+ log_file[k++] = log_template[j]; -+ } -+ log_file[k] = '\0'; -+ log_fp = fopen (log_file, "w"); -+ if (log_fp == NULL) { -+ perror (log_file); -+ abort (); -+ } -+ guestfs_set_event_callback (g, message_callback, -+ event_bitmask, 0, log_fp); -+ } -+ -+ snprintf (id, sizeof id, "%zu", i); -+ guestfs_set_identifier (g, id); -+ -+ guestfs_set_trace (g, trace); -+ guestfs_set_verbose (g, verbose); -+ -+ if (guestfs_add_drive_ro (g, "/dev/null") == -1) { -+ errors++; -+ if (!ignore_errors) -+ goto error; -+ } -+ -+ if (guestfs_launch (g) == -1) { -+ errors++; -+ if (!ignore_errors) -+ goto error; -+ } -+ -+ if (guestfs_shutdown (g) == -1) { -+ errors++; -+ if (!ignore_errors) -+ goto error; -+ } -+ -+ guestfs_close (g); -+ } -+ -+ if (errors > 0) { -+ fprintf (stderr, "%s: thread %d: %u errors were ignored\n", -+ guestfs_int_program_name, thread_data->thread_num, errors); -+ goto error; -+ } -+ -+ thread_data->r = 0; -+ return &thread_data->r; -+ -+ error: -+ thread_data->r = -1; -+ return &thread_data->r; -+} -+ -+/* If using --log, this is called to write messages to the log file. */ -+static void -+message_callback (guestfs_h *g, void *opaque, -+ uint64_t event, int event_handle, -+ int flags, -+ const char *buf, size_t buf_len, -+ const uint64_t *array, size_t array_len) -+{ -+ FILE *fp = opaque; -+ -+ if (buf_len > 0) { -+ CLEANUP_FREE char *msg = strndup (buf, buf_len); -+ -+ switch (event) { -+ case GUESTFS_EVENT_APPLIANCE: -+ fprintf (fp, "%s", msg); -+ break; -+ case GUESTFS_EVENT_LIBRARY: -+ fprintf (fp, "libguestfs: %s\n", msg); -+ break; -+ case GUESTFS_EVENT_WARNING: -+ fprintf (fp, "libguestfs: warning: %s\n", msg); -+ break; -+ case GUESTFS_EVENT_TRACE: -+ fprintf (fp, "libguestfs: trace: %s\n", msg); -+ break; -+ } -+ fflush (fp); -+ } -+} -diff --git a/utils/qemu-speed-test/Makefile.am b/utils/qemu-speed-test/Makefile.am -new file mode 100644 -index 0000000..bf1c915 ---- /dev/null -+++ b/utils/qemu-speed-test/Makefile.am -@@ -0,0 +1,36 @@ -+# libguestfs -+# Copyright (C) 2011-2016 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 $(top_srcdir)/subdir-rules.mk -+ -+noinst_PROGRAMS = qemu-speed-test -+ -+qemu_speed_test_SOURCES = \ -+ qemu-speed-test.c -+qemu_speed_test_CPPFLAGS = \ -+ -I$(top_srcdir)/gnulib/lib -I$(top_builddir)/gnulib/lib \ -+ -I$(top_srcdir)/src -I$(top_builddir)/src \ -+ -I$(top_srcdir)/df -+qemu_speed_test_CFLAGS = \ -+ $(WARN_CFLAGS) $(WERROR_CFLAGS) -+qemu_speed_test_LDADD = \ -+ $(top_builddir)/src/libutils.la \ -+ $(top_builddir)/src/libguestfs.la \ -+ $(LIBXML2_LIBS) \ -+ $(LIBVIRT_LIBS) \ -+ $(LTLIBINTL) \ -+ $(top_builddir)/gnulib/lib/libgnu.la -diff --git a/utils/qemu-speed-test/qemu-speed-test.c b/utils/qemu-speed-test/qemu-speed-test.c -new file mode 100644 -index 0000000..d5e34c3 ---- /dev/null -+++ b/utils/qemu-speed-test/qemu-speed-test.c -@@ -0,0 +1,480 @@ -+/* libguestfs -+ * Copyright (C) 2014 Red Hat Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License along -+ * with this program; if not, write to the Free Software Foundation, Inc., -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -+ */ -+ -+/* Test the speed of various qemu features. Currently tested are: -+ * - virtio-serial upload -+ * - virtio-serial download -+ * - block device read -+ * - block device write -+ * More to come in future. -+ */ -+ -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "guestfs.h" -+#include "guestfs-internal-frontend.h" -+ -+static void test_virtio_serial (void); -+static void test_block_device (void); -+ -+/* Which tests are enabled? -- All by default. */ -+static int virtio_serial_upload = 1; -+static int virtio_serial_download = 1; -+static int block_device_write = 1; -+static int block_device_read = 1; -+ -+static int max_time_override = 0; -+ -+static void -+reset_default_tests (int *flag) -+{ -+ if (*flag) { -+ virtio_serial_upload = 0; -+ virtio_serial_download = 0; -+ block_device_write = 0; -+ block_device_read = 0; -+ *flag = 0; -+ } -+} -+ -+static void -+usage (int exitcode) -+{ -+ fprintf (stderr, -+ "qemu-speed-test: Test the speed of qemu features.\n" -+ "\n" -+ "To run all tests (recommended), do:\n" -+ " qemu-speed-test\n" -+ "\n" -+ "To run only specific tests, do:\n" -+ " qemu-speed-test --option [--option ...]\n" -+ "where the test options are:\n" -+ " --virtio-serial-upload\n" -+ " --virtio-serial-download\n" -+ " --block-device-write\n" -+ " --block-device-read\n" -+ "\n" -+ "Other options:\n" -+ " --help Display help output and exit\n" -+ " -t | --time= Set max length of test in seconds\n" -+ ); -+ exit (exitcode); -+} -+ -+int -+main (int argc, char *argv[]) -+{ -+ enum { HELP_OPTION = CHAR_MAX + 1 }; -+ static const char options[] = "t:"; -+ static const struct option long_options[] = { -+ { "help", 0, 0, HELP_OPTION }, -+ { "time", 1, 0, 't' }, -+ -+ /* Tests. */ -+ { "virtio-serial-upload", 0, 0, 0 }, -+ { "virtio-serial-download", 0, 0, 0 }, -+ { "block-device-write", 0, 0, 0 }, -+ { "block-device-read", 0, 0, 0 }, -+ -+ { 0, 0, 0, 0 } -+ }; -+ int c, option_index; -+ int reset_flag = 1; -+ -+ for (;;) { -+ c = getopt_long (argc, argv, options, long_options, &option_index); -+ if (c == -1) break; -+ -+ switch (c) { -+ case 0: -+ /* Options which are long only. */ -+ if (STREQ (long_options[option_index].name, "virtio-serial-upload")) { -+ reset_default_tests (&reset_flag); -+ virtio_serial_upload = 1; -+ } -+ else if (STREQ (long_options[option_index].name, "virtio-serial-download")) { -+ reset_default_tests (&reset_flag); -+ virtio_serial_download = 1; -+ } -+ else if (STREQ (long_options[option_index].name, "block-device-write")) { -+ reset_default_tests (&reset_flag); -+ block_device_write = 1; -+ } -+ else if (STREQ (long_options[option_index].name, "block-device-read")) { -+ reset_default_tests (&reset_flag); -+ block_device_read = 1; -+ } -+ else { -+ fprintf (stderr, "%s: unknown long option: %s (%d)\n", -+ guestfs_int_program_name, long_options[option_index].name, option_index); -+ exit (EXIT_FAILURE); -+ } -+ break; -+ -+ case 't': -+ if (sscanf (optarg, "%d", &max_time_override) != 1 || -+ max_time_override < 0) { -+ fprintf (stderr, "%s: -t: argument is not a positive integer\n", -+ guestfs_int_program_name); -+ exit (EXIT_FAILURE); -+ } -+ break; -+ -+ case HELP_OPTION: -+ usage (EXIT_SUCCESS); -+ -+ default: -+ usage (EXIT_FAILURE); -+ } -+ } -+ -+ if (optind != argc) { -+ fprintf (stderr, "%s: extra arguments found on the command line\n", -+ guestfs_int_program_name); -+ exit (EXIT_FAILURE); -+ } -+ -+ test_virtio_serial (); -+ test_block_device (); -+ -+ exit (EXIT_SUCCESS); -+} -+ -+static void -+print_rate (const char *msg, int64_t rate) -+{ -+ printf ("%-40s %" PRIi64 " bytes/sec (%" PRIi64 " Mbytes/sec)\n", -+ msg, rate, rate / 1024 / 1024); -+ fflush (stdout); -+} -+ -+/* The maximum time we will spend running the test (seconds). */ -+#define TEST_SERIAL_MAX_TIME 30 -+ -+/* The maximum amount of data to copy. You can safely make this very -+ * large because it's only making sparse files. -+ */ -+#define TEST_SERIAL_MAX_SIZE \ -+ (INT64_C(1024) * INT64_C(1024) * INT64_C(1024) * INT64_C(1024)) -+ -+static guestfs_h *g; -+static struct timeval start; -+static const char *operation; -+static int64_t rate; -+ -+static void -+stop_transfer (int sig) -+{ -+ guestfs_user_cancel (g); -+} -+ -+/* Compute Y - X and return the result in milliseconds. -+ * Approximately the same as this code: -+ * http://www.mpp.mpg.de/~huber/util/timevaldiff.c -+ */ -+static int64_t -+timeval_diff (const struct timeval *x, const struct timeval *y) -+{ -+ int64_t msec; -+ -+ msec = (y->tv_sec - x->tv_sec) * 1000; -+ msec += (y->tv_usec - x->tv_usec) / 1000; -+ return msec; -+} -+ -+static void -+progress_cb (guestfs_h *g, void *vp, uint64_t event, -+ int eh, int flags, -+ const char *buf, size_t buflen, -+ const uint64_t *array, size_t arraylen) -+{ -+ uint64_t transferred; -+ struct timeval now; -+ int64_t millis; -+ -+ assert (event == GUESTFS_EVENT_PROGRESS); -+ assert (arraylen >= 4); -+ -+ gettimeofday (&now, NULL); -+ -+ /* Bytes transferred. */ -+ transferred = array[2]; -+ -+ /* Calculate the speed of the upload or download. */ -+ millis = timeval_diff (&start, &now); -+ assert (millis >= 0); -+ -+ if (millis != 0) { -+ rate = 1000 * transferred / millis; -+ printf ("%s: %" PRIi64 " bytes/sec \r", -+ operation, rate); -+ fflush (stdout); -+ } -+} -+ -+static void -+test_virtio_serial (void) -+{ -+ int fd, r, eh; -+ char tmpfile[] = "/tmp/speedtestXXXXXX"; -+ struct sigaction sa, old_sa; -+ -+ if (!virtio_serial_upload && !virtio_serial_download) -+ return; -+ -+ /* Create a sparse file. We could upload from /dev/zero, but we -+ * won't get progress messages because libguestfs tests if the -+ * source file is a regular file. -+ */ -+ fd = mkstemp (tmpfile); -+ if (fd == -1) { -+ perror ("mkstemp"); -+ exit (EXIT_FAILURE); -+ } -+ if (ftruncate (fd, TEST_SERIAL_MAX_SIZE) == -1) { -+ perror ("ftruncate"); -+ exit (EXIT_FAILURE); -+ } -+ if (close (fd) == -1) { -+ perror ("close"); -+ exit (EXIT_FAILURE); -+ } -+ -+ g = guestfs_create (); -+ if (!g) { -+ perror ("guestfs_create"); -+ exit (EXIT_FAILURE); -+ } -+ -+ if (guestfs_add_drive_scratch (g, INT64_C (100*1024*1024), -1) == -1) -+ exit (EXIT_FAILURE); -+ -+ if (guestfs_launch (g) == -1) -+ exit (EXIT_FAILURE); -+ -+ /* Make and mount a filesystem which will be used by the download test. */ -+ if (guestfs_mkfs (g, "ext4", "/dev/sda") == -1) -+ exit (EXIT_FAILURE); -+ if (guestfs_mount (g, "/dev/sda", "/") == -1) -+ exit (EXIT_FAILURE); -+ -+ /* Time out the upload after TEST_SERIAL_MAX_TIME seconds have passed. */ -+ memset (&sa, 0, sizeof sa); -+ sa.sa_handler = stop_transfer; -+ sa.sa_flags = SA_RESTART; -+ sigaction (SIGALRM, &sa, &old_sa); -+ -+ /* Get progress messages, which will tell us how much data has been -+ * transferred. -+ */ -+ eh = guestfs_set_event_callback (g, progress_cb, GUESTFS_EVENT_PROGRESS, -+ 0, NULL); -+ if (eh == -1) -+ exit (EXIT_FAILURE); -+ -+ if (virtio_serial_upload) { -+ gettimeofday (&start, NULL); -+ rate = -1; -+ operation = "upload"; -+ alarm (max_time_override > 0 ? max_time_override : TEST_SERIAL_MAX_TIME); -+ -+ /* For the upload test, upload the sparse file to /dev/null in the -+ * appliance. Hopefully this is mostly testing just virtio-serial. -+ */ -+ guestfs_push_error_handler (g, NULL, NULL); -+ r = guestfs_upload (g, tmpfile, "/dev/null"); -+ alarm (0); -+ unlink (tmpfile); -+ guestfs_pop_error_handler (g); -+ -+ /* It's possible that the upload will finish before the alarm fires, -+ * or that the upload will be stopped by the alarm. -+ */ -+ if (r == -1 && guestfs_last_errno (g) != EINTR) { -+ fprintf (stderr, -+ "%s: expecting upload command to return EINTR\n%s\n", -+ guestfs_int_program_name, guestfs_last_error (g)); -+ exit (EXIT_FAILURE); -+ } -+ -+ if (rate == -1) { -+ rate_error: -+ fprintf (stderr, "%s: internal error: progress callback was not called! (r=%d, errno=%d)\n", -+ guestfs_int_program_name, -+ r, guestfs_last_errno (g)); -+ exit (EXIT_FAILURE); -+ } -+ -+ print_rate ("virtio-serial upload rate:", rate); -+ } -+ -+ if (virtio_serial_download) { -+ /* For the download test, download a sparse file within the -+ * appliance to /dev/null on the host. -+ */ -+ if (guestfs_touch (g, "/sparse") == -1) -+ exit (EXIT_FAILURE); -+ if (guestfs_truncate_size (g, "/sparse", TEST_SERIAL_MAX_SIZE) == -1) -+ exit (EXIT_FAILURE); -+ -+ gettimeofday (&start, NULL); -+ rate = -1; -+ operation = "download"; -+ alarm (max_time_override > 0 ? max_time_override : TEST_SERIAL_MAX_TIME); -+ guestfs_push_error_handler (g, NULL, NULL); -+ r = guestfs_download (g, "/sparse", "/dev/null"); -+ alarm (0); -+ guestfs_pop_error_handler (g); -+ -+ if (r == -1 && guestfs_last_errno (g) != EINTR) { -+ fprintf (stderr, -+ "%s: expecting download command to return EINTR\n%s\n", -+ guestfs_int_program_name, guestfs_last_error (g)); -+ exit (EXIT_FAILURE); -+ } -+ -+ if (rate == -1) -+ goto rate_error; -+ -+ print_rate ("virtio-serial download rate:", rate); -+ } -+ -+ if (guestfs_shutdown (g) == -1) -+ exit (EXIT_FAILURE); -+ -+ guestfs_close (g); -+ -+ /* Restore SIGALRM signal handler. */ -+ sigaction (SIGALRM, &old_sa, NULL); -+} -+ -+/* The time we will spend running the test (seconds). */ -+#define TEST_BLOCK_DEVICE_TIME 30 -+ -+static void -+test_block_device (void) -+{ -+ int fd; -+ char tmpfile[] = "/tmp/speedtestXXXXXX"; -+ CLEANUP_FREE char **devices = NULL; -+ char *r; -+ const char *argv[4]; -+ const int t = -+ max_time_override > 0 ? max_time_override : TEST_BLOCK_DEVICE_TIME; -+ char tbuf[64]; -+ int64_t bytes_written, bytes_read; -+ -+ if (!block_device_write && !block_device_read) -+ return; -+ -+ snprintf (tbuf, sizeof tbuf, "%d", t); -+ -+ g = guestfs_create (); -+ if (!g) { -+ perror ("guestfs_create"); -+ exit (EXIT_FAILURE); -+ } -+ -+ /* Create a fully allocated backing file. Note we are not testing -+ * the speed of allocation on the host. -+ */ -+ fd = mkstemp (tmpfile); -+ if (fd == -1) { -+ perror ("mkstemp"); -+ exit (EXIT_FAILURE); -+ } -+ close (fd); -+ -+ if (guestfs_disk_create (g, tmpfile, "raw", -+ INT64_C (1024*1024*1024), -+ GUESTFS_DISK_CREATE_PREALLOCATION, "full", -+ -1) == -1) -+ exit (EXIT_FAILURE); -+ -+ if (guestfs_add_drive (g, tmpfile) == -1) -+ exit (EXIT_FAILURE); -+ -+ if (guestfs_launch (g) == -1) -+ exit (EXIT_FAILURE); -+ -+ devices = guestfs_list_devices (g); -+ if (devices == NULL) -+ exit (EXIT_FAILURE); -+ if (devices[0] == NULL) { -+ fprintf (stderr, "%s: expected guestfs_list_devices to return at least 1 device\n", -+ guestfs_int_program_name); -+ exit (EXIT_FAILURE); -+ } -+ -+ if (block_device_write) { -+ /* Test write speed. */ -+ argv[0] = devices[0]; -+ argv[1] = "w"; -+ argv[2] = tbuf; -+ argv[3] = NULL; -+ r = guestfs_debug (g, "device_speed", (char **) argv); -+ if (r == NULL) -+ exit (EXIT_FAILURE); -+ -+ if (sscanf (r, "%" SCNi64, &bytes_written) != 1) { -+ fprintf (stderr, "%s: could not parse device_speed output\n", -+ guestfs_int_program_name); -+ exit (EXIT_FAILURE); -+ } -+ -+ print_rate ("block device writes:", bytes_written / t); -+ } -+ -+ if (block_device_read) { -+ /* Test read speed. */ -+ argv[0] = devices[0]; -+ argv[1] = "r"; -+ argv[2] = tbuf; -+ argv[3] = NULL; -+ r = guestfs_debug (g, "device_speed", (char **) argv); -+ if (r == NULL) -+ exit (EXIT_FAILURE); -+ -+ if (sscanf (r, "%" SCNi64, &bytes_read) != 1) { -+ fprintf (stderr, "%s: could not parse device_speed output\n", -+ guestfs_int_program_name); -+ exit (EXIT_FAILURE); -+ } -+ -+ print_rate ("block device reads:", bytes_read / t); -+ } -+ -+ if (guestfs_shutdown (g) == -1) -+ exit (EXIT_FAILURE); -+ -+ guestfs_close (g); -+ -+ /* Remove temporary file. */ -+ unlink (tmpfile); -+} --- -1.8.3.1 - diff --git a/SOURCES/0079-utils-boot-analysis-utils-boot-benchmark-Add-manual-.patch b/SOURCES/0079-utils-boot-analysis-utils-boot-benchmark-Add-manual-.patch deleted file mode 100644 index 5de75e7..0000000 --- a/SOURCES/0079-utils-boot-analysis-utils-boot-benchmark-Add-manual-.patch +++ /dev/null @@ -1,356 +0,0 @@ -From 915d73995f518d7592dbbca8776ddbfcb3f205de Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Tue, 3 May 2016 13:05:54 +0100 -Subject: [PATCH] utils/boot-analysis, utils/boot-benchmark: Add manual pages. - -(cherry picked from commit 98b28b15c61e871c3b3c5efdf4387e570133c4f9) ---- - .gitignore | 2 + - docs/guestfs-performance.pod | 4 ++ - utils/boot-analysis/Makefile.am | 13 +++++ - utils/boot-analysis/boot-analysis.c | 39 +------------ - utils/boot-analysis/boot-analysis.pod | 99 +++++++++++++++++++++++++++++++++ - utils/boot-benchmark/Makefile.am | 13 ++++- - utils/boot-benchmark/boot-benchmark.c | 2 +- - utils/boot-benchmark/boot-benchmark.pod | 68 ++++++++++++++++++++++ - 8 files changed, 200 insertions(+), 40 deletions(-) - create mode 100644 utils/boot-analysis/boot-analysis.pod - create mode 100644 utils/boot-benchmark/boot-benchmark.pod - -diff --git a/.gitignore b/.gitignore -index d79dc98..85b19d4 100644 ---- a/.gitignore -+++ b/.gitignore -@@ -558,7 +558,9 @@ Makefile.in - /tools/stamp-virt-*.pod - /tools/virt-*.1 - /utils/boot-analysis/boot-analysis -+/utils/boot-analysis/boot-analysis.1 - /utils/boot-benchmark/boot-benchmark -+/utils/boot-benchmark/boot-benchmark.1 - /utils/qemu-boot/qemu-boot - /utils/qemu-speed-test/qemu-speed-test - /v2v/.depend -diff --git a/docs/guestfs-performance.pod b/docs/guestfs-performance.pod -index 7304b63..b6c25e1 100644 ---- a/docs/guestfs-performance.pod -+++ b/docs/guestfs-performance.pod -@@ -38,6 +38,8 @@ run it, do: - make - ./run utils/boot-benchmark/boot-benchmark - -+There is a manual page F -+ - =head3 Explanation - - The guestfish command above starts up the libguestfs appliance on a -@@ -453,6 +455,8 @@ To run this program, do: - make - ./run utils/boot-analysis/boot-analysis - -+There is a manual page F -+ - =head2 Detailed timings using ts - - Use the L command (from moreutils) to show detailed -diff --git a/utils/boot-analysis/Makefile.am b/utils/boot-analysis/Makefile.am -index ef9b2cb..d708de2 100644 ---- a/utils/boot-analysis/Makefile.am -+++ b/utils/boot-analysis/Makefile.am -@@ -17,6 +17,8 @@ - - include $(top_srcdir)/subdir-rules.mk - -+EXTRA_DIST = boot-analysis.pod -+ - noinst_PROGRAMS = boot-analysis - - boot_analysis_SOURCES = \ -@@ -41,3 +43,14 @@ boot_analysis_LDADD = \ - $(LTLIBINTL) \ - $(top_builddir)/gnulib/lib/libgnu.la \ - -lm -+ -+# Manual page. -+# It should be noinst_MANS but that doesn't work. -+noinst_DATA = boot-analysis.1 -+ -+boot-analysis.1: boot-analysis.pod -+ $(PODWRAPPER) \ -+ --man $@ \ -+ --license GPLv2+ \ -+ --warning safe \ -+ $< -diff --git a/utils/boot-analysis/boot-analysis.c b/utils/boot-analysis/boot-analysis.c -index b90806b..461c69e 100644 ---- a/utils/boot-analysis/boot-analysis.c -+++ b/utils/boot-analysis/boot-analysis.c -@@ -16,44 +16,7 @@ - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - --/* Trace and analyze the appliance boot process to find out which -- * steps are taking the most time. It is not part of the standard -- * tests. -- * -- * This needs to be run on a quiet machine, so that other processes -- * disturb the timing as little as possible. The program is -- * completely safe to run at any time. It doesn't read or write any -- * external files, and it doesn't require root. -- * -- * You can run it from the build directory like this: -- * -- * make -- * ./run utils/boot-analysis/boot-analysis -- * -- * The way it works is roughly like this: -- * -- * We create a libguestfs handle and register callback handlers so we -- * can see appliance messages, trace events and so on. -- * -- * We then launch the handle and shut it down as quickly as possible. -- * -- * While the handle is running, events (seen by the callback handlers) -- * are written verbatim into an in-memory buffer, with timestamps. -- * -- * Afterwards we analyze the result using regular expressions to try -- * to identify a "timeline" for the handle (eg. at what time did the -- * BIOS hand control to the kernel). This analysis is done in -- * 'boot-analysis-timeline.c'. -- * -- * The whole process is repeated across a few runs, and the final -- * timeline (including statistical analysis of the variation between -- * runs) gets printed. -- * -- * The program is very sensitive to the specific messages printed by -- * BIOS/kernel/supermin/userspace, so it won't work on non-x86, and it -- * will require periodic adjustment of the regular expressions in -- * order to keep things up to date. -- */ -+/* See instructions in boot-analysis.1 */ - - #include - -diff --git a/utils/boot-analysis/boot-analysis.pod b/utils/boot-analysis/boot-analysis.pod -new file mode 100644 -index 0000000..07cc801 ---- /dev/null -+++ b/utils/boot-analysis/boot-analysis.pod -@@ -0,0 +1,99 @@ -+=head1 NAME -+ -+boot-analysis - Trace and analyze the appliance boot process -+ -+=head1 SYNOPSIS -+ -+ ./run utils/boot-analysis/boot-analysis -+ -+=head1 DESCRIPTION -+ -+Trace and analyze the appliance boot process to find out which steps -+are taking the most time. It is not part of the standard tests. -+ -+This needs to be run on a quiet machine, so that other processes -+disturb the timing as little as possible. The program is completely -+safe to run at any time. It doesn't read or write any external files, -+and it doesn't require root. -+ -+You can run it from the build directory on the built copy of -+libguestfs like this: -+ -+ make -+ ./run utils/boot-analysis/boot-analysis -+ -+If you omit C<./run> then it is run on the installed copy of libguestfs. -+ -+=head2 How it works -+ -+We create a libguestfs handle and register callback handlers so we -+can see appliance messages, trace events and so on. -+ -+We then launch the handle and shut it down as quickly as possible. -+ -+While the handle is running, events (seen by the callback handlers) -+are written verbatim into an in-memory buffer, with timestamps. -+ -+Afterwards we analyze the result using regular expressions to try to -+identify a "timeline" for the handle (eg. at what time did the BIOS -+hand control to the kernel). This analysis is done in -+F. -+ -+The whole process is repeated across a few runs, and the final -+timeline (including statistical analysis of the variation between -+runs) gets printed. -+ -+The program is very sensitive to the specific messages printed by -+BIOS/kernel/supermin/userspace. It only works on x86-64 or aarch64. -+It will require periodic adjustment of the regular expressions in -+order to keep things up to date. -+ -+=head1 OPTIONS -+ -+=over 4 -+ -+=item B<--help> -+ -+Display brief help. -+ -+=item B<--append> "OPTIONS" -+ -+Append C to the kernel command line. -+ -+=item B<--color> -+ -+=item B<--colour> -+ -+Output colours (as ANSI escape sequences), even if the output is not a -+terminal. -+ -+=item B<-m> MB -+ -+=item B<--memsize> MB -+ -+Set the appliance memory size in MB. -+ -+=item B<--smp> N -+ -+Enable C virtual CPUs. -+ -+=item B<-v> -+ -+=item B<--verbose> -+ -+More verbose output, useful for debugging problems. -+ -+=back -+ -+=head1 SEE ALSO -+ -+L, -+L. -+ -+=head1 AUTHOR -+ -+Richard W.M. Jones L -+ -+=head1 COPYRIGHT -+ -+Copyright (C) 2016 Red Hat Inc. -diff --git a/utils/boot-benchmark/Makefile.am b/utils/boot-benchmark/Makefile.am -index 429832a..fed2428 100644 ---- a/utils/boot-benchmark/Makefile.am -+++ b/utils/boot-benchmark/Makefile.am -@@ -21,6 +21,8 @@ - - include $(top_srcdir)/subdir-rules.mk - -+EXTRA_DIST = boot-benchmark.pod boot-benchmark-range.pl -+ - noinst_PROGRAMS = boot-benchmark - - boot_benchmark_SOURCES = \ -@@ -41,4 +43,13 @@ boot_benchmark_LDADD = \ - $(top_builddir)/gnulib/lib/libgnu.la \ - -lm - --EXTRA_DIST = boot-benchmark-range.pl -+# Manual page. -+# It should be noinst_MANS but that doesn't work. -+noinst_DATA = boot-benchmark.1 -+ -+boot-benchmark.1: boot-benchmark.pod -+ $(PODWRAPPER) \ -+ --man $@ \ -+ --license GPLv2+ \ -+ --warning safe \ -+ $< -diff --git a/utils/boot-benchmark/boot-benchmark.c b/utils/boot-benchmark/boot-benchmark.c -index 0508ee9..05cab50 100644 ---- a/utils/boot-benchmark/boot-benchmark.c -+++ b/utils/boot-benchmark/boot-benchmark.c -@@ -16,7 +16,7 @@ - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - --/* Benchmark the time taken to boot the libguestfs appliance. */ -+/* See instructions in boot-benchmark.1 */ - - #include - -diff --git a/utils/boot-benchmark/boot-benchmark.pod b/utils/boot-benchmark/boot-benchmark.pod -new file mode 100644 -index 0000000..b34546a ---- /dev/null -+++ b/utils/boot-benchmark/boot-benchmark.pod -@@ -0,0 +1,68 @@ -+=head1 NAME -+ -+boot-benchmark - Benchmark the time taken to boot the libguestfs appliance -+ -+=head1 SYNOPSIS -+ -+ ./run utils/boot-benchmark/boot-benchmark -+ -+=head1 DESCRIPTION -+ -+Benchmark the time taken to boot the libguestfs appliance. -+ -+It is essentially the same as doing: -+ -+ time guestfish -a /dev/null run -+ -+except that it warms up the caches and repeats the test many times, -+printing out the mean time and standard deviation. -+ -+This needs to be run on a quiet machine, so that other processes -+disturb the timing as little as possible. The program is completely -+safe to run at any time. It doesn't read or write any external files, -+and it doesn't require root. -+ -+You can run it from the build directory on the built copy of -+libguestfs like this: -+ -+ make -+ ./run utils/boot-benchmark/boot-benchmark -+ -+If you omit C<./run> then it is run on the installed copy of libguestfs. -+ -+=head1 OPTIONS -+ -+=over 4 -+ -+=item B<--help> -+ -+Display brief help. -+ -+=item B<--append> "OPTIONS" -+ -+Append C to the kernel command line. -+ -+=item B<-m> MB -+ -+=item B<--memsize> MB -+ -+Set the appliance memory size in MB. -+ -+=item B<--smp> N -+ -+Enable C virtual CPUs. -+ -+=back -+ -+=head1 SEE ALSO -+ -+L, -+L. -+ -+=head1 AUTHOR -+ -+Richard W.M. Jones L -+ -+=head1 COPYRIGHT -+ -+Copyright (C) 2016 Red Hat Inc. --- -1.8.3.1 - diff --git a/SOURCES/0080-utils-Add-a-README-file-describing-briefly-the-purpo.patch b/SOURCES/0080-utils-Add-a-README-file-describing-briefly-the-purpo.patch deleted file mode 100644 index 135a0e3..0000000 --- a/SOURCES/0080-utils-Add-a-README-file-describing-briefly-the-purpo.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 506b831d7993cf5074195c749f594d5d06c4a147 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Tue, 3 May 2016 21:47:11 +0100 -Subject: [PATCH] utils: Add a README file describing briefly the purpose of - this directory. - -.. and where to find the real documentation. - -Updates commit 3b581a727c9e906f9d9b10e2f73ed853ab324fd0. - -(cherry picked from commit bbec1b570b8b1edff7f2a39b0b86d625445dbaf2) ---- - utils/README | 7 +++++++ - 1 file changed, 7 insertions(+) - create mode 100644 utils/README - -diff --git a/utils/README b/utils/README -new file mode 100644 -index 0000000..ceaaadd ---- /dev/null -+++ b/utils/README -@@ -0,0 +1,7 @@ -+This directory contains miscellaneous utilities for profiling and -+testing libguestfs. For more information see guestfs-performance(1). -+ -+For libguestfs tools you should look in the specific tool directories -+such as cat/, df/, etc. -+ -+For an overview of libguestfs directories, see guestfs-hacking(1). --- -1.8.3.1 - diff --git a/SOURCES/0081-utils-Add-README-to-EXTRA_DIST.patch b/SOURCES/0081-utils-Add-README-to-EXTRA_DIST.patch deleted file mode 100644 index d717d51..0000000 --- a/SOURCES/0081-utils-Add-README-to-EXTRA_DIST.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 0f11af1c633ede0bf8efe6aa057b6500178c25fb Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Wed, 4 May 2016 18:16:26 +0100 -Subject: [PATCH] utils: Add README to EXTRA_DIST. - -Updates commit 3b581a727c9e906f9d9b10e2f73ed853ab324fd0 -and commit bbec1b570b8b1edff7f2a39b0b86d625445dbaf2. - -(cherry picked from commit ff7e755f954d1385d0d352d38f5d34c0e426972e) ---- - Makefile.am | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/Makefile.am b/Makefile.am -index 079aa7d..5be6876 100644 ---- a/Makefile.am -+++ b/Makefile.am -@@ -222,6 +222,7 @@ EXTRA_DIST = \ - tests/automake2junit.ml \ - tmp/.gitignore \ - update-bugs.sh \ -+ utils/README \ - valgrind-suppressions \ - website/bugs.png \ - website/communicate.png \ --- -1.8.3.1 - diff --git a/SOURCES/0082-utils-boot-analysis-Fix-minor-typo-in-string.patch b/SOURCES/0082-utils-boot-analysis-Fix-minor-typo-in-string.patch deleted file mode 100644 index c6e7284..0000000 --- a/SOURCES/0082-utils-boot-analysis-Fix-minor-typo-in-string.patch +++ /dev/null @@ -1,26 +0,0 @@ -From b107e5b149b871caf80ce765c11b87c69fa86359 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Mon, 9 May 2016 12:19:16 +0100 -Subject: [PATCH] utils: boot-analysis: Fix minor typo in string. - -(cherry picked from commit 320b0faeaf67d80bccf8f81b9ebfcbcb68516fa1) ---- - utils/boot-analysis/boot-analysis-utils.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/utils/boot-analysis/boot-analysis-utils.c b/utils/boot-analysis/boot-analysis-utils.c -index 693b6f4..4308bea 100644 ---- a/utils/boot-analysis/boot-analysis-utils.c -+++ b/utils/boot-analysis/boot-analysis-utils.c -@@ -69,7 +69,7 @@ test_info (guestfs_h *g, int nr_test_passes) - - /* Related to qemu. */ - backend = guestfs_get_backend (g); -- printf (" backend: %-20s [to change set LIBGUESTFS_BACKEND]\n", -+ printf (" backend: %-20s [to change set $LIBGUESTFS_BACKEND]\n", - backend); - printf (" qemu: %-20s [to change set $LIBGUESTFS_HV]\n", qemu); - printf ("qemu version: "); --- -1.8.3.1 - diff --git a/SOURCES/0083-boot-analysis-Make-ftrace-optional-in-the-timeline.patch b/SOURCES/0083-boot-analysis-Make-ftrace-optional-in-the-timeline.patch deleted file mode 100644 index 66c61de..0000000 --- a/SOURCES/0083-boot-analysis-Make-ftrace-optional-in-the-timeline.patch +++ /dev/null @@ -1,29 +0,0 @@ -From a5d102f5b31dc98373bc73f2a1ea261d14baac73 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Tue, 10 May 2016 12:16:36 +0100 -Subject: [PATCH] boot-analysis: Make ftrace optional in the timeline. - -This allows me to test minimal kernels with ftrace disabled at -compile time. - -(cherry picked from commit e4edede3641f3c8d3ac729c1a6c871f532b2b996) ---- - utils/boot-analysis/boot-analysis-timeline.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/utils/boot-analysis/boot-analysis-timeline.c b/utils/boot-analysis/boot-analysis-timeline.c -index 09a78ef..905d1e3 100644 ---- a/utils/boot-analysis/boot-analysis-timeline.c -+++ b/utils/boot-analysis/boot-analysis-timeline.c -@@ -306,7 +306,7 @@ construct_timeline (void) - #endif - - /* ftrace patching instructions. */ -- FIND ("kernel:ftrace", 0, -+ FIND_OPTIONAL ("kernel:ftrace", 0, - data->events[j].source == GUESTFS_EVENT_APPLIANCE && - strstr (data->events[j].message, "ftrace: allocating"), - 1); --- -1.8.3.1 - diff --git a/SOURCES/0084-boot-analysis-Flush-out-debug-data-after-printing-it.patch b/SOURCES/0084-boot-analysis-Flush-out-debug-data-after-printing-it.patch deleted file mode 100644 index b0a60e1..0000000 --- a/SOURCES/0084-boot-analysis-Flush-out-debug-data-after-printing-it.patch +++ /dev/null @@ -1,38 +0,0 @@ -From e8c04a323238bf2838520ae44a1d930b5d777bc7 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Tue, 10 May 2016 12:17:28 +0100 -Subject: [PATCH] boot-analysis: Flush out debug data after printing it. - -Just makes it easier to see bugs causing the analysis stage to -hang / infinite loop. - -(cherry picked from commit 754b8f5ef391ec4ee1b39db66b4923f9a8aa5cd9) ---- - utils/boot-analysis/boot-analysis.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/utils/boot-analysis/boot-analysis.c b/utils/boot-analysis/boot-analysis.c -index 461c69e..3d38fe2 100644 ---- a/utils/boot-analysis/boot-analysis.c -+++ b/utils/boot-analysis/boot-analysis.c -@@ -841,6 +841,8 @@ dump_pass_data (void) - printf ("\"\n"); - } - } -+ -+ fflush (stdout); - } - - /* Convert source to a printable string. The caller must free the -@@ -1018,6 +1020,8 @@ dump_timeline (void) - printf (" s.d = %.1f\n", activities[i].sd); - printf (" percent = %.1f\n", activities[i].percent); - } -+ -+ fflush (stdout); - } - - static void --- -1.8.3.1 - diff --git a/SOURCES/0085-Revert-appliance-init-run-ldconfig.patch b/SOURCES/0085-Revert-appliance-init-run-ldconfig.patch deleted file mode 100644 index 26801c3..0000000 --- a/SOURCES/0085-Revert-appliance-init-run-ldconfig.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 16ac3aa74628ceb63b9cbc995300f9107cd48a0c Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Thu, 12 May 2016 16:24:10 +0100 -Subject: [PATCH] Revert "appliance: init: run ldconfig" - -Running ldconfig adds about 100ms to the boot time. I would prefer -that we understood which libraries need ldconfig to be run, and fix -that. We could also consider running ldconfig in parallel, but since -it might be required by just about any binary that the init script -runs it's not clear what benefit that gives. - -This reverts commit 66aa98265dd215dcd4c717e7ef6845fbac859e54. - -(cherry picked from commit ba8e8d277daba14ea8e33faee7dfb6ddb613bb07) ---- - appliance/init | 4 ---- - 1 file changed, 4 deletions(-) - -diff --git a/appliance/init b/appliance/init -index b05c0ed..d168b5e 100755 ---- a/appliance/init -+++ b/appliance/init -@@ -17,10 +17,6 @@ if [ ! -d /tmp ] || [ ! -d /var/tmp ]; then - chmod 1777 /tmp /var/tmp - fi - --# Make sure to find all the libraries, also those in non-standard place --# but with a proper ld.so configuration pointing at them --ldconfig -- - # Try to print a stack trace for segfaults inside the appliance. - for d in /lib64 /lib; do - f=$d/libSegFault.so --- -1.8.3.1 - diff --git a/SOURCES/0086-appliance-Copy-etc-ld.so.cache-from-the-host-into-th.patch b/SOURCES/0086-appliance-Copy-etc-ld.so.cache-from-the-host-into-th.patch deleted file mode 100644 index 3fa0a3a..0000000 --- a/SOURCES/0086-appliance-Copy-etc-ld.so.cache-from-the-host-into-th.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 470d49add9f9b75f963b5cd523950541d9fa3bee Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Thu, 12 May 2016 16:51:53 +0100 -Subject: [PATCH] appliance: Copy /etc/ld.so.cache from the host into the - appliance. - -Previously we were running ldconfig to create /etc/ld.so.cache. - -This is required, at least on Fedora, if we need to run any binary -that uses a library with a weird path. libiscsi (a dependency of -qemu-img, used by virt-dib) is an example of such a weird library, -since it puts its single library into /usr/lib64/iscsi for no readily -understandable reason, and drops a configuration file into -/etc/ld.so.conf.d/ so that this new directory gets picked up. - -By copying the /etc/ld.so.cache from the host we get an already -configured cache which should contain every library on the host, so -there is no need to run ldconfig. - -(cherry picked from commit 634f47e6d4f1cf7ce343789d8b6257d89001f74f) ---- - appliance/hostfiles.in | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/appliance/hostfiles.in b/appliance/hostfiles.in -index 8ff53b5..268d712 100644 ---- a/appliance/hostfiles.in -+++ b/appliance/hostfiles.in -@@ -13,5 +13,6 @@ dnl SUSE=1 For OpenSUSE. - dnl FRUGALWARE=1 For Frugalware. - dnl MAGEIA=1 For Mageia. - -+/etc/ld.so.cache - /lib/lsb/* - /usr/share/augeas/lenses/*.aug --- -1.8.3.1 - diff --git a/SOURCES/0087-utils-boot-analysis-Make-handling-of-first-kernel-me.patch b/SOURCES/0087-utils-boot-analysis-Make-handling-of-first-kernel-me.patch deleted file mode 100644 index aa78e1d..0000000 --- a/SOURCES/0087-utils-boot-analysis-Make-handling-of-first-kernel-me.patch +++ /dev/null @@ -1,108 +0,0 @@ -From 88f2135d9b788cdeec7dff8ac9c2b882f314009d Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Tue, 10 May 2016 21:53:59 +0100 -Subject: [PATCH] utils: boot-analysis: Make handling of first kernel message - more flexible. - -Allows us to disable EDD completely, and still have boot-analysis work. - -(cherry picked from commit b6f5a0cd90c356ab1d7e519c0e24e66bfe33cfcc) ---- - utils/boot-analysis/boot-analysis-timeline.c | 35 +++++++++++++++++++++------- - 1 file changed, 26 insertions(+), 9 deletions(-) - -diff --git a/utils/boot-analysis/boot-analysis-timeline.c b/utils/boot-analysis/boot-analysis-timeline.c -index 905d1e3..a4b71a1 100644 ---- a/utils/boot-analysis/boot-analysis-timeline.c -+++ b/utils/boot-analysis/boot-analysis-timeline.c -@@ -67,6 +67,7 @@ construct_timeline (void) - size_t i, j, k; - struct pass_data *data; - struct activity *activity; -+ const char *first_kernel_message; - - for (i = 0; i < NR_TEST_PASSES; ++i) { - data = &pass_data[i]; -@@ -217,14 +218,30 @@ construct_timeline (void) - strstr (data->events[k].message, "libvirt XML:")); - - #if defined(__aarch64__) --#define FIRST_KERNEL_MESSAGE "Booting Linux on physical CPU" - #define FIRST_FIRMWARE_MESSAGE "UEFI firmware starting" - #else - #define SGABIOS_STRING "\033[1;256r\033[256;256H\033[6n" --#define FIRST_KERNEL_MESSAGE "Probing EDD" - #define FIRST_FIRMWARE_MESSAGE SGABIOS_STRING - #endif - -+ /* Try to determine the first message that the kernel prints. */ -+#if defined(__aarch64__) -+ first_kernel_message = "Booting Linux on physical CPU"; -+#else -+ first_kernel_message = "Probing EDD"; -+ for (j = 0; j < data->nr_events; ++j) -+ if (data->events[j].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[j].message, first_kernel_message)) -+ goto found_first_kernel_message; -+ first_kernel_message = "Linux version "; -+ for (j = 0; j < data->nr_events; ++j) -+ if (data->events[j].source == GUESTFS_EVENT_APPLIANCE && -+ strstr (data->events[j].message, first_kernel_message)) -+ goto found_first_kernel_message; -+ error (EXIT_FAILURE, 0, "could not determine first message printed by the kernel"); -+ found_first_kernel_message: -+#endif -+ - /* For the libvirt backend, find the overhead of libvirt. */ - FIND_OPTIONAL ("libvirt:overhead", 0, - data->events[j].source == GUESTFS_EVENT_LIBRARY && -@@ -244,7 +261,7 @@ construct_timeline (void) - data->events[j].source == GUESTFS_EVENT_APPLIANCE && - strstr (data->events[j].message, FIRST_FIRMWARE_MESSAGE), - data->events[k].source == GUESTFS_EVENT_APPLIANCE && -- strstr (data->events[k].message, FIRST_KERNEL_MESSAGE)); -+ strstr (data->events[k].message, first_kernel_message)); - - #if defined(__i386__) || defined(__x86_64__) - /* SGABIOS (option ROM). */ -@@ -261,7 +278,7 @@ construct_timeline (void) - data->events[j].source == GUESTFS_EVENT_APPLIANCE && - strstr (data->events[j].message, "SeaBIOS (version"), - data->events[k].source == GUESTFS_EVENT_APPLIANCE && -- strstr (data->events[k].message, FIRST_KERNEL_MESSAGE)); -+ strstr (data->events[k].message, first_kernel_message)); - #endif - - #if defined(__i386__) || defined(__x86_64__) -@@ -276,23 +293,23 @@ construct_timeline (void) - /* Find where we run the guest kernel. */ - FIND ("kernel", LONG_ACTIVITY, - data->events[j].source == GUESTFS_EVENT_APPLIANCE && -- strstr (data->events[j].message, FIRST_KERNEL_MESSAGE), -+ strstr (data->events[j].message, first_kernel_message), - data->events[k].source == GUESTFS_EVENT_CLOSE); - - /* Kernel startup to userspace. */ - FIND ("kernel:overhead", 0, - data->events[j].source == GUESTFS_EVENT_APPLIANCE && -- strstr (data->events[j].message, FIRST_KERNEL_MESSAGE), -+ strstr (data->events[j].message, first_kernel_message), - data->events[k].source == GUESTFS_EVENT_APPLIANCE && - strstr (data->events[k].message, "supermin:") && - strstr (data->events[k].message, "starting up")); - - /* The time taken to get into start_kernel function. */ -- FIND ("kernel:entry", 0, -+ FIND_OPTIONAL ("kernel:entry", 0, - data->events[j].source == GUESTFS_EVENT_APPLIANCE && -- strstr (data->events[j].message, FIRST_KERNEL_MESSAGE), -+ strstr (data->events[j].message, first_kernel_message), - data->events[k].source == GUESTFS_EVENT_APPLIANCE && -- strstr (data->events[k].message, "Linux version")); -+ strstr (data->events[k].message, "Linux version ")); - - #if defined(__i386__) || defined(__x86_64__) - /* Alternatives patching instructions (XXX not very accurate we --- -1.8.3.1 - diff --git a/SOURCES/0088-utils-boot-analysis-Add-magic-asserts-to-some-struct.patch b/SOURCES/0088-utils-boot-analysis-Add-magic-asserts-to-some-struct.patch deleted file mode 100644 index d0afac3..0000000 --- a/SOURCES/0088-utils-boot-analysis-Add-magic-asserts-to-some-struct.patch +++ /dev/null @@ -1,97 +0,0 @@ -From 3b2ac7b9ac4d8a40c17ae28e255f50704180782b Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Sat, 14 May 2016 18:45:25 +0100 -Subject: [PATCH] utils: boot-analysis: Add magic & asserts to some structs. - -I suspected data corruption (but didn't prove it). This commit just -adds some magic numbers to the structs so we will see data corruption -quickly if it happens again. - -(cherry picked from commit bf80587367d5f01e493426bbb2cda6099a15e7ab) ---- - utils/boot-analysis/boot-analysis.c | 9 +++++++++ - utils/boot-analysis/boot-analysis.h | 6 ++++++ - 2 files changed, 15 insertions(+) - -diff --git a/utils/boot-analysis/boot-analysis.c b/utils/boot-analysis/boot-analysis.c -index 3d38fe2..3690ed4 100644 ---- a/utils/boot-analysis/boot-analysis.c -+++ b/utils/boot-analysis/boot-analysis.c -@@ -571,6 +571,7 @@ set_up_event_handlers (guestfs_h *g, size_t pass) - assert (/* 0 <= pass && */ pass < NR_TEST_PASSES); - - data = &pass_data[pass]; -+ data->magic = PASS_MAGIC; - data->pass = pass; - data->nr_events = 0; - data->events = NULL; -@@ -779,6 +780,7 @@ check_pass_data (void) - const char *message; - - for (i = 0; i < NR_TEST_PASSES; ++i) { -+ assert (pass_data[i].magic == PASS_MAGIC); - assert (pass_data[i].pass == i); - assert (pass_data[i].elapsed_ns > 1000); - assert (pass_data[i].nr_events > 0); -@@ -890,6 +892,7 @@ add_activity (const char *name, int flags) - if (activities == NULL) - error (EXIT_FAILURE, errno, "realloc"); - ret = &activities[nr_activities-1]; -+ ret->magic = ACTIVITY_MAGIC; - ret->name = strdup (name); - if (ret->name == NULL) - error (EXIT_FAILURE, errno, "strdup"); -@@ -934,6 +937,9 @@ compare_activities_by_t (const void *av, const void *bv) - const struct activity *a = av; - const struct activity *b = bv; - -+ assert (a->magic == ACTIVITY_MAGIC); -+ assert (b->magic == ACTIVITY_MAGIC); -+ - return a->t - b->t; - } - -@@ -1028,6 +1034,7 @@ static void - print_activity (struct activity *activity) - { - if (activity->warning) ansi_red (); else ansi_green (); -+ assert (activity->magic == ACTIVITY_MAGIC); - print_escaped_string (activity->name); - ansi_restore (); - printf (" %.1fms ±%.1fms ", -@@ -1148,6 +1155,8 @@ compare_activities_pointers_by_mean (const void *av, const void *bv) - const struct activity * const *a = av; - const struct activity * const *b = bv; - -+ assert ((*a)->magic == ACTIVITY_MAGIC); -+ assert ((*b)->magic == ACTIVITY_MAGIC); - return (*b)->mean - (*a)->mean; - } - -diff --git a/utils/boot-analysis/boot-analysis.h b/utils/boot-analysis/boot-analysis.h -index a07f12e..38cd339 100644 ---- a/utils/boot-analysis/boot-analysis.h -+++ b/utils/boot-analysis/boot-analysis.h -@@ -24,6 +24,9 @@ - - /* Per-pass data collected. */ - struct pass_data { -+#define PASS_MAGIC 0x45545545 -+ uint32_t magic; /* Struct magic. */ -+ - size_t pass; - struct timespec start_t; - struct timespec end_t; -@@ -67,6 +70,9 @@ extern struct pass_data pass_data[NR_TEST_PASSES]; - * long they take (mean, variance, standard deviation of length). - */ - struct activity { -+#define ACTIVITY_MAGIC 0xAC1AC1AC -+ uint32_t magic; /* Struct magic. */ -+ - char *name; /* Name of this activity. */ - int flags; - #define LONG_ACTIVITY 1 /* Expected to take a long time. */ --- -1.8.3.1 - diff --git a/SOURCES/0089-utils-boot-analysis-Avoid-overflow-when-comparing-la.patch b/SOURCES/0089-utils-boot-analysis-Avoid-overflow-when-comparing-la.patch deleted file mode 100644 index 33459f2..0000000 --- a/SOURCES/0089-utils-boot-analysis-Avoid-overflow-when-comparing-la.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 832609cc5f16a955648880ebc69b8f226f8782bb Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Sat, 14 May 2016 19:22:49 +0100 -Subject: [PATCH] utils: boot-analysis: Avoid overflow when comparing large - doubles. - -(cherry picked from commit 1f4a0bd90df35df56eb86c2386d801b51828cb22) ---- - utils/boot-analysis/boot-analysis.c | 11 ++++++++++- - 1 file changed, 10 insertions(+), 1 deletion(-) - -diff --git a/utils/boot-analysis/boot-analysis.c b/utils/boot-analysis/boot-analysis.c -index 3690ed4..d06d9a1 100644 ---- a/utils/boot-analysis/boot-analysis.c -+++ b/utils/boot-analysis/boot-analysis.c -@@ -1157,7 +1157,16 @@ compare_activities_pointers_by_mean (const void *av, const void *bv) - - assert ((*a)->magic == ACTIVITY_MAGIC); - assert ((*b)->magic == ACTIVITY_MAGIC); -- return (*b)->mean - (*a)->mean; -+ -+ /* The mean field is a double in nanoseconds. For the result of the -+ * comparison we want an integer. If it is larger than around 2^32, -+ * the following will produce an incorrect result. Therefore we use -+ * this trick. Note we want to return largest first. -+ */ -+ double a_mean = (*a)->mean; -+ double b_mean = (*b)->mean; -+ -+ return (b_mean > a_mean) - (b_mean < a_mean); - } - - static void --- -1.8.3.1 - diff --git a/SOURCES/0090-appliance-Reenable-ACPI.patch b/SOURCES/0090-appliance-Reenable-ACPI.patch deleted file mode 100644 index b460467..0000000 --- a/SOURCES/0090-appliance-Reenable-ACPI.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 8ebb42e25a62bf587c84c109e5e4efe722b35881 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Mon, 16 May 2016 22:29:58 +0100 -Subject: [PATCH] appliance: Reenable ACPI. - -Previously I disabled ACPI because it was not necessary and was slow. -However measuring it again now, I can see no significant difference in -performance, and it is necessary if we are going to use DAX. - -It's also useful to keep the appliance kernel state as similar to the -ordinary state, and setting acpi=off is a massive change to the way -that the kernel boots. - -Therefore, reenable it. - -(cherry picked from commit db1f811b29b055625ae1b03cf0daa9fed0d443ac) ---- - src/launch.c | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/src/launch.c b/src/launch.c -index e7cb325..269eeca 100644 ---- a/src/launch.c -+++ b/src/launch.c -@@ -336,7 +336,6 @@ guestfs_int_appliance_command_line (guestfs_h *g, const char *appliance_dev, - " udev.event-timeout=6000" /* for newer udevd */ - " no_timer_check" /* fix for RHBZ#502058 */ - "%s" /* lpj */ -- " acpi=off" /* ACPI is slow - 150-200ms extra on my laptop */ - " printk.time=1" /* display timestamp before kernel messages */ - " cgroup_disable=memory" /* saves us about 5 MB of RAM */ - " usbcore.nousb" /* disable USB, only saves about 1ms */ --- -1.8.3.1 - diff --git a/SOURCES/0091-appliance-Find-udevd-a-bit-faster.patch b/SOURCES/0091-appliance-Find-udevd-a-bit-faster.patch deleted file mode 100644 index 20b0925..0000000 --- a/SOURCES/0091-appliance-Find-udevd-a-bit-faster.patch +++ /dev/null @@ -1,38 +0,0 @@ -From aac825766ceab91e5d234fba83d03dc25b1de882 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Tue, 17 May 2016 13:20:14 +0100 -Subject: [PATCH] appliance: Find udevd a bit faster. - -Rearrange the paths that we check for udevd so that the systemd paths -are first. Break from the loop as soon as we find udevd. - -(cherry picked from commit 8a4dcde16accef1a2e1a1bc5a71146295ed6a214) ---- - appliance/init | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - -diff --git a/appliance/init b/appliance/init -index d168b5e..1f38a0e 100755 ---- a/appliance/init -+++ b/appliance/init -@@ -91,13 +91,13 @@ echo "${machine_id// /}" > /etc/machine-id - systemd-tmpfiles --prefix=/dev --create --boot - - # Find udevd and run it directly. --for f in /sbin/udevd /lib/udev/udevd \ -- /lib/systemd/systemd-udevd /usr/lib/systemd/systemd-udevd \ -+for f in /lib/systemd/systemd-udevd /usr/lib/systemd/systemd-udevd \ -+ /sbin/udevd /lib/udev/udevd \ - /usr/lib/udev/udevd; do -- if [ -x "$f" ]; then UDEVD="$f"; fi -+ if [ -x "$f" ]; then UDEVD="$f"; break; fi - done - if [ -z "$UDEVD" ]; then -- echo "udev not found! Things will probably not work ..." -+ echo "error: udev not found! Things will probably not work ..." - fi - - $UDEVD --daemon #--debug --- -1.8.3.1 - diff --git a/SOURCES/0092-utils-boot-analysis-Make-insmod-message-handling-a-b.patch b/SOURCES/0092-utils-boot-analysis-Make-insmod-message-handling-a-b.patch deleted file mode 100644 index 1952b77..0000000 --- a/SOURCES/0092-utils-boot-analysis-Make-insmod-message-handling-a-b.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 50bcb7aa73d899dda1a994d3ed8e4cab83c6678a Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Tue, 17 May 2016 15:34:42 +0100 -Subject: [PATCH] utils: boot-analysis: Make insmod message handling a bit more - robust. - -(cherry picked from commit 613fe4c089d132d63edddf1ccb53c082c20aded3) ---- - utils/boot-analysis/boot-analysis-timeline.c | 11 +++++++++-- - 1 file changed, 9 insertions(+), 2 deletions(-) - -diff --git a/utils/boot-analysis/boot-analysis-timeline.c b/utils/boot-analysis/boot-analysis-timeline.c -index a4b71a1..8198c56 100644 ---- a/utils/boot-analysis/boot-analysis-timeline.c -+++ b/utils/boot-analysis/boot-analysis-timeline.c -@@ -48,13 +48,20 @@ static void construct_initcall_timeline (void); - static char * - translate_supermin_insmod_message (const char *message) - { -+ const char *p, *q; - char *ret; - - assert (STRPREFIX (message, "supermin: internal ")); -+ p = message + strlen ("supermin: internal "); - -- ret = strdup (message + strlen ("supermin: internal ")); -+ /* Strip off the .ko and anything that follows. */ -+ q = strstr (p, ".ko"); -+ if (q == NULL) -+ error (EXIT_FAILURE, 0, "cannot find '.ko' suffix in '%s'", message); -+ -+ ret = strndup (p, q-p); - if (ret == NULL) -- error (EXIT_FAILURE, errno, "strdup"); -+ error (EXIT_FAILURE, errno, "strndup"); - return ret; - } - --- -1.8.3.1 - diff --git a/SOURCES/0093-v2v-handle-subfolders-in-ova-files.patch b/SOURCES/0093-v2v-handle-subfolders-in-ova-files.patch deleted file mode 100644 index a4bb5a0..0000000 --- a/SOURCES/0093-v2v-handle-subfolders-in-ova-files.patch +++ /dev/null @@ -1,312 +0,0 @@ -From a9c07400e8ac1bca21f6d55c311b2e64f12c27eb Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?C=C3=A9dric=20Bosdonnat?= -Date: Mon, 23 May 2016 15:31:46 +0200 -Subject: [PATCH] v2v: handle subfolders in ova files - -Some ova files like those produced by SUSE Studio have their ovf, mf -and other files inside a folder rather than at the root of the -tarball. Consider the paths relative to the ovf and mf files to cover -this case too. - -(cherry picked from commit 9de9300e8b7a99fa06e290f20ef1aaa1eb6f7431) ---- - v2v/Makefile.am | 1 + - v2v/input_ova.ml | 6 +- - v2v/test-v2v-i-ova-subfolders.expected | 17 ++++ - v2v/test-v2v-i-ova-subfolders.ovf | 138 +++++++++++++++++++++++++++++++++ - v2v/test-v2v-i-ova-subfolders.sh | 65 ++++++++++++++++ - 5 files changed, 225 insertions(+), 2 deletions(-) - create mode 100644 v2v/test-v2v-i-ova-subfolders.expected - create mode 100644 v2v/test-v2v-i-ova-subfolders.ovf - create mode 100755 v2v/test-v2v-i-ova-subfolders.sh - -diff --git a/v2v/Makefile.am b/v2v/Makefile.am -index 2d52ab8..8354560 100644 ---- a/v2v/Makefile.am -+++ b/v2v/Makefile.am -@@ -285,6 +285,7 @@ TESTS_ENVIRONMENT = $(top_builddir)/run --test - TESTS = \ - test-v2v-i-ova-formats.sh \ - test-v2v-i-ova-gz.sh \ -+ test-v2v-i-ova-subfolders.sh \ - test-v2v-i-ova-two-disks.sh \ - test-v2v-copy-to-local.sh \ - test-v2v-bad-networks-and-bridges.sh -diff --git a/v2v/input_ova.ml b/v2v/input_ova.ml -index 28dafe6..0a4dfd5 100644 ---- a/v2v/input_ova.ml -+++ b/v2v/input_ova.ml -@@ -134,13 +134,14 @@ object - let rex = Str.regexp "SHA1(\\(.*\\))=\\([0-9a-fA-F]+\\)\r?" in - List.iter ( - fun mf -> -+ let mf_folder = Filename.dirname mf in - let chan = open_in mf in - let rec loop () = - let line = input_line chan in - if Str.string_match rex line 0 then ( - let disk = Str.matched_group 1 line in - let expected = Str.matched_group 2 line in -- let cmd = sprintf "sha1sum %s" (quote (exploded // disk)) in -+ let cmd = sprintf "sha1sum %s" (quote (mf_folder // disk)) in - let out = external_command cmd in - match out with - | [] -> -@@ -159,6 +160,7 @@ object - ) mf; - - (* Parse the ovf file. *) -+ let ovf_folder = Filename.dirname ovf in - let xml = read_whole_file ovf in - let doc = Xml.parse_memory xml in - -@@ -259,7 +261,7 @@ object - | Some s -> s in - - (* Does the file exist and is it readable? *) -- let filename = exploded // filename in -+ let filename = ovf_folder // filename in - Unix.access filename [Unix.R_OK]; - - (* The spec allows the file to be gzip-compressed, in which case -diff --git a/v2v/test-v2v-i-ova-subfolders.expected b/v2v/test-v2v-i-ova-subfolders.expected -new file mode 100644 -index 0000000..7037b9e ---- /dev/null -+++ b/v2v/test-v2v-i-ova-subfolders.expected -@@ -0,0 +1,17 @@ -+Source guest information (--print-source option): -+ -+ source name: 2K8R2EESP1_2_Medium -+hypervisor type: vmware -+ memory: 1073741824 (bytes) -+ nr vCPUs: 1 -+ CPU features: -+ firmware: uefi -+ display: -+ sound: -+disks: -+ subfolder/disk1.vmdk (vmdk) [scsi] -+removable media: -+ CD-ROM [ide] in slot 0 -+NICs: -+ Network "Network adapter 1" -+ -diff --git a/v2v/test-v2v-i-ova-subfolders.ovf b/v2v/test-v2v-i-ova-subfolders.ovf -new file mode 100644 -index 0000000..4827c7e ---- /dev/null -+++ b/v2v/test-v2v-i-ova-subfolders.ovf -@@ -0,0 +1,138 @@ -+ -+ -+ -+ -+ -+ -+ Virtual disk information -+ -+ -+ -+ The list of logical networks -+ -+ The PG-VLAN60 network -+ -+ -+ -+ A virtual machine -+ 2K8R2EESP1_2_Medium -+ -+ The kind of installed guest operating system -+ Microsoft Windows Server 2008 R2 (64-bit) -+ -+ -+ Virtual hardware requirements -+ -+ Virtual Hardware Family -+ 0 -+ 2K8R2EESP1_2_Medium -+ vmx-10 -+ -+ -+ hertz * 10^6 -+ Number of Virtual CPUs -+ 1 virtual CPU(s) -+ 1 -+ 3 -+ 1 -+ -+ -+ byte * 2^20 -+ Memory Size -+ 1024MB of memory -+ 2 -+ 4 -+ 1024 -+ -+ -+ 0 -+ SCSI Controller -+ SCSI controller 0 -+ 3 -+ lsilogicsas -+ 6 -+ -+ -+ -+ 1 -+ IDE Controller -+ IDE 1 -+ 4 -+ 5 -+ -+ -+ 0 -+ IDE Controller -+ IDE 0 -+ 5 -+ 5 -+ -+ -+ false -+ Video card -+ 6 -+ 24 -+ -+ -+ -+ -+ -+ -+ false -+ VMCI device -+ 7 -+ vmware.vmci -+ 1 -+ -+ -+ -+ -+ 0 -+ false -+ CD/DVD drive 1 -+ 8 -+ 4 -+ vmware.cdrom.atapi -+ 15 -+ -+ -+ 0 -+ Hard disk 1 -+ ovf:/disk/vmdisk1 -+ 9 -+ 3 -+ 17 -+ -+ -+ -+ 7 -+ true -+ PG-VLAN60 -+ E1000 ethernet adapter on "PG-VLAN60" -+ Network adapter 1 -+ 11 -+ E1000 -+ 10 -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -diff --git a/v2v/test-v2v-i-ova-subfolders.sh b/v2v/test-v2v-i-ova-subfolders.sh -new file mode 100755 -index 0000000..a590fcc ---- /dev/null -+++ b/v2v/test-v2v-i-ova-subfolders.sh -@@ -0,0 +1,65 @@ -+#!/bin/bash - -+# libguestfs virt-v2v test script -+# Copyright (C) 2014 Red Hat Inc. -+# -+# This program is free software; you can redistribute it and/or modify -+# it under the terms of the GNU General Public License as published by -+# the Free Software Foundation; either version 2 of the License, or -+# (at your option) any later version. -+# -+# This program is distributed in the hope that it will be useful, -+# but WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+# GNU General Public License for more details. -+# -+# You should have received a copy of the GNU General Public License -+# along with this program; if not, write to the Free Software -+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -+ -+# Test -i ova option with files located in a subfolder. -+ -+unset CDPATH -+export LANG=C -+set -e -+ -+if [ -n "$SKIP_TEST_V2V_I_OVA_SUBFOLDERS_SH" ]; then -+ echo "$0: test skipped because environment variable is set" -+ exit 77 -+fi -+ -+if [ "$(guestfish get-backend)" = "uml" ]; then -+ echo "$0: test skipped because UML backend does not support network" -+ exit 77 -+fi -+ -+export VIRT_TOOLS_DATA_DIR="$srcdir/../test-data/fake-virt-tools" -+ -+. $srcdir/../test-data/guestfs-hashsums.sh -+ -+d=test-v2v-i-ova-subfolders.d -+rm -rf $d -+mkdir -p $d/subfolder -+ -+cp test-v2v-i-ova-subfolders.ovf $d/subfolder/ -+ -+pushd $d/subfolder -+ -+truncate -s 10k disk1.vmdk -+sha=`do_sha1 disk1.vmdk` -+echo -e "SHA1(disk1.vmdk)=$sha\r" > disk1.mf -+ -+cd .. -+tar -cf test.ova subfolder -+popd -+ -+# Run virt-v2v but only as far as the --print-source stage, and -+# normalize the output. -+$VG virt-v2v --debug-gc --quiet \ -+ -i ova $d/test.ova \ -+ --print-source | -+sed 's,[^ \t]*\(subfolder/disk.*\.vmdk\),\1,' > $d/source -+ -+# Check the parsed source is what we expect. -+diff -u test-v2v-i-ova-subfolders.expected $d/source -+ -+rm -rf $d --- -1.8.3.1 - diff --git a/SOURCES/0094-v2v-Add-test-v2v-i-ova-subfolders-test-files-to-EXTR.patch b/SOURCES/0094-v2v-Add-test-v2v-i-ova-subfolders-test-files-to-EXTR.patch deleted file mode 100644 index 6436599..0000000 --- a/SOURCES/0094-v2v-Add-test-v2v-i-ova-subfolders-test-files-to-EXTR.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 78e75d5bbbd2230d1052356fee097bacceba875b Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Thu, 26 May 2016 12:54:08 +0100 -Subject: [PATCH] v2v: Add test-v2v-i-ova-subfolders test files to EXTRA_DIST. - -Fixes commit 9de9300e8b7a99fa06e290f20ef1aaa1eb6f7431. - -(cherry picked from commit e516b85bd72986568690db0169516923297c6918) ---- - v2v/Makefile.am | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/v2v/Makefile.am b/v2v/Makefile.am -index 8354560..5d0ce95 100644 ---- a/v2v/Makefile.am -+++ b/v2v/Makefile.am -@@ -31,6 +31,8 @@ EXTRA_DIST = \ - test-v2v-i-ova-formats.ovf \ - test-v2v-i-ova-gz.expected \ - test-v2v-i-ova-gz.ovf \ -+ test-v2v-i-ova-subfolders.expected \ -+ test-v2v-i-ova-subfolders.ovf \ - test-v2v-i-ova-two-disks.expected \ - test-v2v-i-ova-two-disks.ovf \ - test-v2v-networks-and-bridges-expected.xml \ --- -1.8.3.1 - diff --git a/SOURCES/0095-p2v-Add-xterm-to-the-virt-p2v-ISO.patch b/SOURCES/0095-p2v-Add-xterm-to-the-virt-p2v-ISO.patch deleted file mode 100644 index 01f339f..0000000 --- a/SOURCES/0095-p2v-Add-xterm-to-the-virt-p2v-ISO.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 2212f2464c070f8117d4723cc668c081d5330a90 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Sat, 28 May 2016 22:45:41 +0100 -Subject: [PATCH] p2v: Add xterm to the virt-p2v ISO. - -You can run `xterm -display :0' at the virtual console in order to get -a shell in the graphical environment. - -This is useful for debugging and doesn't have much overhead unlike -other terminals. - -(cherry picked from commit d3b2a5bbd2491808148b10dba966d1e898078bf8) ---- - p2v/dependencies.m4 | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/p2v/dependencies.m4 b/p2v/dependencies.m4 -index 7acccaa..6cf2961 100644 ---- a/p2v/dependencies.m4 -+++ b/p2v/dependencies.m4 -@@ -42,6 +42,7 @@ ifelse(REDHAT,1, - util-linux - - dnl X11 environment -+ xterm - /usr/bin/xinit - /usr/bin/Xorg - xorg-x11-drivers -@@ -77,6 +78,7 @@ ifelse(DEBIAN,1, - smartmontools - util-linux - xorg -+ xterm - xserver-xorg-video-all - fonts-dejavu - metacity -@@ -100,6 +102,7 @@ ifelse(ARCHLINUX,1, - hdparm - smartmontools - util-linux -+ xterm - xorg-xinit - xorg-server - xf86-video-* -@@ -127,6 +130,7 @@ ifelse(SUSE,1, - util-linux - xinit - xorg-x11-server -+ xterm - xf86-video-* - dejavu-fonts - NetworkManager --- -1.8.3.1 - diff --git a/SOURCES/0096-p2v-Add-verbose-option-to-virt-p2v-make-disk-kicksta.patch b/SOURCES/0096-p2v-Add-verbose-option-to-virt-p2v-make-disk-kicksta.patch deleted file mode 100644 index d0b5333..0000000 --- a/SOURCES/0096-p2v-Add-verbose-option-to-virt-p2v-make-disk-kicksta.patch +++ /dev/null @@ -1,139 +0,0 @@ -From 34ab1cf2d4f849b69a01ddb2eb7e87c80523f03f Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Thu, 2 Jun 2016 13:53:37 +0100 -Subject: [PATCH] p2v: Add --verbose option to virt-p2v-make-{disk,kickstart}. - -For virt-p2v-make-kickstart this doesn't do very much. But for -virt-p2v-make-disk it enables verbose mode in virt-builder which is -extremely useful for debugging problems. - -Thanks: Ming Xie. -(cherry picked from commit 6358633bf22d19c1bc9b9638dfff8e5ac50a37eb) ---- - p2v/virt-p2v-make-disk.in | 13 ++++++++++++- - p2v/virt-p2v-make-disk.pod | 7 +++++++ - p2v/virt-p2v-make-kickstart.in | 9 +++++++-- - p2v/virt-p2v-make-kickstart.pod | 7 +++++++ - 4 files changed, 33 insertions(+), 3 deletions(-) - -diff --git a/p2v/virt-p2v-make-disk.in b/p2v/virt-p2v-make-disk.in -index 88c171f..d58e7f1 100644 ---- a/p2v/virt-p2v-make-disk.in -+++ b/p2v/virt-p2v-make-disk.in -@@ -24,7 +24,7 @@ version="@PACKAGE_VERSION@" - - TEMP=`getopt \ - -o o:V \ -- --long help,inject-ssh-identity:,output:,version \ -+ --long help,inject-ssh-identity:,output:,verbose,version \ - -n $program -- "$@"` - if [ $? != 0 ]; then - echo "$program: problem parsing the command line arguments" -@@ -34,6 +34,7 @@ eval set -- "$TEMP" - - output= - upload= -+verbose= - - usage () - { -@@ -52,6 +53,10 @@ while true; do - -o|--output) - output="$2" - shift 2;; -+ -v|--verbose) -+ set +x -+ verbose=1 -+ shift;; - -V|--version) - echo "$program $version" - exit 0;; -@@ -170,9 +175,15 @@ while read line; do - fi - done < $depsfile - -+# Add -v -x if we're in verbose mode. -+if [ "x$verbose" = "x1" ]; then -+ verbose_option="-v -x" -+fi -+ - # Run virt-builder. Note we controversially assume systemd here. We - # could provide a sysvinit fallback if required. - virt-builder "$osversion" \ -+ $verbose_option \ - --output "$output" \ - --update \ - --install "$install" \ -diff --git a/p2v/virt-p2v-make-disk.pod b/p2v/virt-p2v-make-disk.pod -index 79bf499..d5a5db5 100644 ---- a/p2v/virt-p2v-make-disk.pod -+++ b/p2v/virt-p2v-make-disk.pod -@@ -106,6 +106,13 @@ See L above. - Write output to C, which can be a local file or block device. - B. - -+=item B<-v> -+ -+=item B<--verbose> -+ -+Enable verbose output. Use this if you need to debug problems with -+the script or if you are filing a bug. -+ - =item B<-V> - - =item B<--version> -diff --git a/p2v/virt-p2v-make-kickstart.in b/p2v/virt-p2v-make-kickstart.in -index 74bee61..8a6e4d8 100644 ---- a/p2v/virt-p2v-make-kickstart.in -+++ b/p2v/virt-p2v-make-kickstart.in -@@ -23,8 +23,8 @@ program="virt-p2v-make-kickstart" - version="@PACKAGE_VERSION@" - - TEMP=`getopt \ -- -o o:V \ -- --long help,inject-ssh-identity:,output:,proxy:,version \ -+ -o o:vV \ -+ --long help,inject-ssh-identity:,output:,proxy:,verbose,version \ - -n $program -- "$@"` - if [ $? != 0 ]; then - echo "$program: problem parsing the command line arguments" -@@ -44,6 +44,7 @@ usage () - output=p2v.ks - proxy= - ssh_identity= -+verbose= - - while true; do - case "$1" in -@@ -59,6 +60,10 @@ while true; do - --repo) - repo="$2" - shift 2;; -+ -v|--verbose) -+ set +x -+ verbose=1 -+ shift;; - -V|--version) - echo "$program $version" - exit 0;; -diff --git a/p2v/virt-p2v-make-kickstart.pod b/p2v/virt-p2v-make-kickstart.pod -index 6e65c07..cea3787 100644 ---- a/p2v/virt-p2v-make-kickstart.pod -+++ b/p2v/virt-p2v-make-kickstart.pod -@@ -254,6 +254,13 @@ F in the current directory. - - Tell the kickstart to use a proxy server or web cache for downloads. - -+=item B<-v> -+ -+=item B<--verbose> -+ -+Enable verbose output. Use this if you need to debug problems with -+the script or if you are filing a bug. -+ - =item B<-V> - - =item B<--version> --- -1.8.3.1 - diff --git a/SOURCES/0097-mllib-Add-bindings-for-makedev-3-major-3-and-minor-3.patch b/SOURCES/0097-mllib-Add-bindings-for-makedev-3-major-3-and-minor-3.patch deleted file mode 100644 index 5898e8b..0000000 --- a/SOURCES/0097-mllib-Add-bindings-for-makedev-3-major-3-and-minor-3.patch +++ /dev/null @@ -1,192 +0,0 @@ -From 18c35c397d37144d4ec0e2815dc6333977397b91 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Thu, 2 Jun 2016 14:50:44 +0100 -Subject: [PATCH] mllib: Add bindings for makedev(3), major(3) and minor(3). - -(cherry picked from commit dd2ce98d242c0598a3bd484110f8cb0f9e88ec54) ---- - mllib/Makefile.am | 3 +++ - mllib/dev_t-c.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ - mllib/dev_t.ml | 21 +++++++++++++++++++++ - mllib/dev_t.mli | 28 ++++++++++++++++++++++++++++ - po/POTFILES | 1 + - po/POTFILES-ml | 1 + - 6 files changed, 106 insertions(+) - create mode 100644 mllib/dev_t-c.c - create mode 100644 mllib/dev_t.ml - create mode 100644 mllib/dev_t.mli - -diff --git a/mllib/Makefile.am b/mllib/Makefile.am -index fc4dd95..e44abed 100644 ---- a/mllib/Makefile.am -+++ b/mllib/Makefile.am -@@ -29,6 +29,7 @@ CLEANFILES = *~ *.annot *.cmi *.cmo *.cmx *.cmxa *.o - SOURCES_MLI = \ - common_utils.mli \ - curl.mli \ -+ dev_t.mli \ - fsync.mli \ - JSON.mli \ - mkdtemp.mli \ -@@ -41,6 +42,7 @@ SOURCES_ML = \ - guestfs_config.ml \ - libdir.ml \ - common_gettext.ml \ -+ dev_t.ml \ - common_utils.ml \ - fsync.ml \ - progress.ml \ -@@ -54,6 +56,7 @@ SOURCES_ML = \ - SOURCES_C = \ - ../fish/progress.c \ - ../fish/uri.c \ -+ dev_t-c.c \ - fsync-c.c \ - mkdtemp-c.c \ - progress-c.c \ -diff --git a/mllib/dev_t-c.c b/mllib/dev_t-c.c -new file mode 100644 -index 0000000..036b60d ---- /dev/null -+++ b/mllib/dev_t-c.c -@@ -0,0 +1,52 @@ -+/* libguestfs OCaml tools common code -+ * Copyright (C) 2016 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 -+ -+#include -+#include -+#include -+ -+#include -+ -+/* OCaml doesn't bind the dev_t calls makedev, major and minor. */ -+ -+extern value guestfs_int_mllib_dev_t_makedev (value majv, value minv); -+extern value guestfs_int_mllib_dev_t_major (value devv); -+extern value guestfs_int_mllib_dev_t_minor (value devv); -+ -+/* NB: This is a "noalloc" call. */ -+value -+guestfs_int_mllib_dev_t_makedev (value majv, value minv) -+{ -+ return Val_int (makedev (Int_val (majv), Int_val (minv))); -+} -+ -+/* NB: This is a "noalloc" call. */ -+value -+guestfs_int_mllib_dev_t_major (value devv) -+{ -+ return Val_int (major (Int_val (devv))); -+} -+ -+/* NB: This is a "noalloc" call. */ -+value -+guestfs_int_mllib_dev_t_minor (value devv) -+{ -+ return Val_int (minor (Int_val (devv))); -+} -diff --git a/mllib/dev_t.ml b/mllib/dev_t.ml -new file mode 100644 -index 0000000..143954a ---- /dev/null -+++ b/mllib/dev_t.ml -@@ -0,0 +1,21 @@ -+(* libguestfs OCaml tools common code -+ * Copyright (C) 2016 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. -+ *) -+ -+external makedev : int -> int -> int = "guestfs_int_mllib_dev_t_makedev" "noalloc" -+external major : int -> int = "guestfs_int_mllib_dev_t_major" "noalloc" -+external minor : int -> int = "guestfs_int_mllib_dev_t_minor" "noalloc" -diff --git a/mllib/dev_t.mli b/mllib/dev_t.mli -new file mode 100644 -index 0000000..340ead0 ---- /dev/null -+++ b/mllib/dev_t.mli -@@ -0,0 +1,28 @@ -+(* virt-resize -+ * Copyright (C) 2016 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 [dev_t] related functions [makedev], [major] and [minor]. *) -+ -+val makedev : int -> int -> int -+(** makedev(3) *) -+ -+val major : int -> int -+(** major(3) *) -+ -+val minor : int -> int -+(** minor(3) *) -diff --git a/po/POTFILES b/po/POTFILES -index ebee244..1252d8b 100644 ---- a/po/POTFILES -+++ b/po/POTFILES -@@ -261,6 +261,7 @@ inspector/inspector.c - java/com_redhat_et_libguestfs_GuestFS.c - lua/lua-guestfs.c - make-fs/make-fs.c -+mllib/dev_t-c.c - mllib/dummy.c - mllib/fsync-c.c - mllib/mkdtemp-c.c -diff --git a/po/POTFILES-ml b/po/POTFILES-ml -index b7f3cc2..2b9bba1 100644 ---- a/po/POTFILES-ml -+++ b/po/POTFILES-ml -@@ -43,6 +43,7 @@ mllib/common_gettext.ml - mllib/common_utils.ml - mllib/common_utils_tests.ml - mllib/curl.ml -+mllib/dev_t.ml - mllib/fsync.ml - mllib/guestfs_config.ml - mllib/libdir.ml --- -1.8.3.1 - diff --git a/SOURCES/0098-mllib-Add-Common_utils.is_partition-function.patch b/SOURCES/0098-mllib-Add-Common_utils.is_partition-function.patch deleted file mode 100644 index 932e336..0000000 --- a/SOURCES/0098-mllib-Add-Common_utils.is_partition-function.patch +++ /dev/null @@ -1,251 +0,0 @@ -From 53ea0055668938fc7b77431d54f36f9daa6da03f Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Thu, 2 Jun 2016 15:10:04 +0100 -Subject: [PATCH] mllib: Add Common_utils.is_partition function. - -Returns true if the device is a host partition. - -The only tedious bit of this patch is that now Common_utils depends on -Dev_t so we have to add extra objects every time something links with -Common_utils. - -(cherry picked from commit df7a33768eab2381b958ede2c8a40bc9cbc87928) ---- - builder/Makefile.am | 2 ++ - customize/Makefile.am | 2 ++ - dib/Makefile.am | 2 ++ - get-kernel/Makefile.am | 2 ++ - mllib/common_utils.ml | 13 +++++++++++++ - mllib/common_utils.mli | 4 ++++ - resize/Makefile.am | 2 ++ - sparsify/Makefile.am | 2 ++ - sysprep/Makefile.am | 2 ++ - v2v/Makefile.am | 5 +++++ - 10 files changed, 36 insertions(+) - -diff --git a/builder/Makefile.am b/builder/Makefile.am -index f31aef9..54aa10b 100644 ---- a/builder/Makefile.am -+++ b/builder/Makefile.am -@@ -89,6 +89,7 @@ SOURCES_ML = \ - builder.ml - - SOURCES_C = \ -+ ../mllib/dev_t-c.c \ - ../mllib/fsync-c.c \ - ../mllib/uri-c.c \ - ../mllib/mkdtemp-c.c \ -@@ -134,6 +135,7 @@ BOBJECTS = \ - $(top_builddir)/mllib/libdir.cmo \ - $(top_builddir)/mllib/guestfs_config.cmo \ - $(top_builddir)/mllib/common_gettext.cmo \ -+ $(top_builddir)/mllib/dev_t.cmo \ - $(top_builddir)/mllib/common_utils.cmo \ - $(top_builddir)/mllib/fsync.cmo \ - $(top_builddir)/mllib/planner.cmo \ -diff --git a/customize/Makefile.am b/customize/Makefile.am -index 033816c..661917a 100644 ---- a/customize/Makefile.am -+++ b/customize/Makefile.am -@@ -69,6 +69,7 @@ SOURCES_C = \ - ../fish/uri.c \ - ../fish/file-edit.c \ - ../fish/file-edit.h \ -+ ../mllib/dev_t-c.c \ - ../mllib/uri-c.c \ - crypt-c.c \ - perl_edit-c.c -@@ -93,6 +94,7 @@ virt_customize_CFLAGS = \ - BOBJECTS = \ - $(top_builddir)/mllib/guestfs_config.cmo \ - $(top_builddir)/mllib/common_gettext.cmo \ -+ $(top_builddir)/mllib/dev_t.cmo \ - $(top_builddir)/mllib/common_utils.cmo \ - $(top_builddir)/mllib/regedit.cmo \ - $(top_builddir)/mllib/URI.cmo \ -diff --git a/dib/Makefile.am b/dib/Makefile.am -index b969677..d1674a9 100644 ---- a/dib/Makefile.am -+++ b/dib/Makefile.am -@@ -33,6 +33,7 @@ SOURCES_ML = \ - dib.ml - - SOURCES_C = \ -+ ../mllib/dev_t-c.c \ - ../mllib/mkdtemp-c.c - - bin_PROGRAMS = -@@ -57,6 +58,7 @@ BOBJECTS = \ - $(top_builddir)/mllib/libdir.cmo \ - $(top_builddir)/mllib/guestfs_config.cmo \ - $(top_builddir)/mllib/common_gettext.cmo \ -+ $(top_builddir)/mllib/dev_t.cmo \ - $(top_builddir)/mllib/common_utils.cmo \ - $(top_builddir)/mllib/mkdtemp.cmo \ - $(SOURCES_ML:.ml=.cmo) -diff --git a/get-kernel/Makefile.am b/get-kernel/Makefile.am -index da94ece..9d8fc61 100644 ---- a/get-kernel/Makefile.am -+++ b/get-kernel/Makefile.am -@@ -27,6 +27,7 @@ SOURCES_ML = \ - get_kernel.ml - - SOURCES_C = \ -+ ../mllib/dev_t-c.c \ - ../mllib/uri-c.c \ - ../fish/uri.c - -@@ -56,6 +57,7 @@ BOBJECTS = \ - $(top_builddir)/mllib/libdir.cmo \ - $(top_builddir)/mllib/guestfs_config.cmo \ - $(top_builddir)/mllib/common_gettext.cmo \ -+ $(top_builddir)/mllib/dev_t.cmo \ - $(top_builddir)/mllib/common_utils.cmo \ - $(top_builddir)/mllib/URI.cmo \ - $(SOURCES_ML:.ml=.cmo) -diff --git a/mllib/common_utils.ml b/mllib/common_utils.ml -index 2ba8f9a..c29dfa0 100644 ---- a/mllib/common_utils.ml -+++ b/mllib/common_utils.ml -@@ -819,6 +819,19 @@ let is_char_device file = - try (Unix.stat file).Unix.st_kind = Unix.S_CHR - with Unix.Unix_error _ -> false - -+let is_partition dev = -+ try -+ if not (is_block_device dev) then false -+ else ( -+ let rdev = (Unix.stat dev).Unix.st_rdev in -+ let major = Dev_t.major rdev in -+ let minor = Dev_t.minor rdev in -+ let path = sprintf "/sys/dev/block/%d:%d/partition" major minor in -+ Unix.access path [F_OK]; -+ true -+ ) -+ with Unix.Unix_error _ -> false -+ - (* Annoyingly Sys.is_directory throws an exception on failure - * (RHBZ#1022431). - *) -diff --git a/mllib/common_utils.mli b/mllib/common_utils.mli -index ae89fd6..4cfe7d0 100644 ---- a/mllib/common_utils.mli -+++ b/mllib/common_utils.mli -@@ -327,6 +327,10 @@ val is_char_device : string -> bool - val is_directory : string -> bool - (** These don't throw exceptions, unlike the [Sys] functions. *) - -+val is_partition : string -> bool -+(** Return true if the host device [dev] is a partition. If it's -+ anything else, or missing, returns false. *) -+ - val absolute_path : string -> string - (** Convert any path to an absolute path. *) - -diff --git a/resize/Makefile.am b/resize/Makefile.am -index f4d1626..e9f48da 100644 ---- a/resize/Makefile.am -+++ b/resize/Makefile.am -@@ -30,6 +30,7 @@ SOURCES_ML = \ - resize.ml - - SOURCES_C = \ -+ ../mllib/dev_t-c.c \ - ../mllib/fsync-c.c \ - ../fish/progress.c \ - ../mllib/progress-c.c \ -@@ -58,6 +59,7 @@ BOBJECTS = \ - $(top_builddir)/mllib/URI.cmo \ - $(top_builddir)/mllib/guestfs_config.cmo \ - $(top_builddir)/mllib/common_gettext.cmo \ -+ $(top_builddir)/mllib/dev_t.cmo \ - $(top_builddir)/mllib/common_utils.cmo \ - $(SOURCES_ML:.ml=.cmo) - XOBJECTS = $(BOBJECTS:.cmo=.cmx) -diff --git a/sparsify/Makefile.am b/sparsify/Makefile.am -index 3da7a7a..9df3e1f 100644 ---- a/sparsify/Makefile.am -+++ b/sparsify/Makefile.am -@@ -37,6 +37,7 @@ SOURCES_ML = \ - - SOURCES_C = \ - ../fish/progress.c \ -+ ../mllib/dev_t-c.c \ - ../mllib/progress-c.c \ - statvfs-c.c - -@@ -57,6 +58,7 @@ virt_sparsify_CFLAGS = \ - BOBJECTS = \ - $(top_builddir)/mllib/guestfs_config.cmo \ - $(top_builddir)/mllib/common_gettext.cmo \ -+ $(top_builddir)/mllib/dev_t.cmo \ - $(top_builddir)/mllib/common_utils.cmo \ - $(top_builddir)/mllib/progress.cmo \ - $(SOURCES_ML:.ml=.cmo) -diff --git a/sysprep/Makefile.am b/sysprep/Makefile.am -index b890bca..e439a88 100644 ---- a/sysprep/Makefile.am -+++ b/sysprep/Makefile.am -@@ -80,6 +80,7 @@ SOURCES_ML = \ - main.ml - - SOURCES_C = \ -+ ../mllib/dev_t-c.c \ - ../mllib/uri-c.c \ - ../mllib/mkdtemp-c.c \ - ../customize/crypt-c.c \ -@@ -106,6 +107,7 @@ virt_sysprep_CFLAGS = \ - BOBJECTS = \ - $(top_builddir)/mllib/guestfs_config.cmo \ - $(top_builddir)/mllib/common_gettext.cmo \ -+ $(top_builddir)/mllib/dev_t.cmo \ - $(top_builddir)/mllib/common_utils.cmo \ - $(top_builddir)/mllib/URI.cmo \ - $(top_builddir)/mllib/mkdtemp.cmo \ -diff --git a/v2v/Makefile.am b/v2v/Makefile.am -index 5d0ce95..5bffbfe 100644 ---- a/v2v/Makefile.am -+++ b/v2v/Makefile.am -@@ -113,6 +113,7 @@ SOURCES_ML = \ - v2v.ml - - SOURCES_C = \ -+ ../mllib/dev_t-c.c \ - ../mllib/mkdtemp-c.c \ - domainxml-c.c \ - changeuid-c.c \ -@@ -137,6 +138,7 @@ virt_v2v_CFLAGS = \ - BOBJECTS = \ - $(top_builddir)/mllib/guestfs_config.cmo \ - $(top_builddir)/mllib/common_gettext.cmo \ -+ $(top_builddir)/mllib/dev_t.cmo \ - $(top_builddir)/mllib/common_utils.cmo \ - $(top_builddir)/mllib/regedit.cmo \ - $(top_builddir)/mllib/mkdtemp.cmo \ -@@ -187,6 +189,7 @@ virt_v2v_LINK = \ - $(OBJECTS) -o $@ - - virt_v2v_copy_to_local_SOURCES = \ -+ ../mllib/dev_t-c.c \ - domainxml-c.c \ - utils-c.c \ - xml-c.c -@@ -203,6 +206,7 @@ virt_v2v_copy_to_local_CFLAGS = \ - COPY_TO_LOCAL_BOBJECTS = \ - $(top_builddir)/mllib/guestfs_config.cmo \ - $(top_builddir)/mllib/common_gettext.cmo \ -+ $(top_builddir)/mllib/dev_t.cmo \ - $(top_builddir)/mllib/common_utils.cmo \ - $(top_builddir)/mllib/JSON.cmo \ - $(top_builddir)/mllib/curl.cmo \ -@@ -361,6 +365,7 @@ endif - v2v_unit_tests_BOBJECTS = \ - $(top_builddir)/mllib/guestfs_config.cmo \ - $(top_builddir)/mllib/common_gettext.cmo \ -+ $(top_builddir)/mllib/dev_t.cmo \ - $(top_builddir)/mllib/common_utils.cmo \ - $(top_builddir)/mllib/regedit.cmo \ - stringMap.cmo \ --- -1.8.3.1 - diff --git a/SOURCES/0099-builder-Warn-if-output-is-a-host-partition-RHBZ-1342.patch b/SOURCES/0099-builder-Warn-if-output-is-a-host-partition-RHBZ-1342.patch deleted file mode 100644 index 23fa2d8..0000000 --- a/SOURCES/0099-builder-Warn-if-output-is-a-host-partition-RHBZ-1342.patch +++ /dev/null @@ -1,125 +0,0 @@ -From 44afd4c1f26379b32f62690cf19e06022cafa994 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Thu, 2 Jun 2016 14:51:12 +0100 -Subject: [PATCH] builder: Warn if --output is a host partition (RHBZ#1342337). - -But allow the warning to be turned off using --no-warn-if-partition. - -Ming Xie tried to create a bootable USB key using -'virt-p2v-make-disk -o /dev/sdX1'. That works, but doesn't create a -bootable key because it puts everything into the first partition. - -Emit a warning if someone tries to do this to try to prevent user -error: - - virt-builder: warning: output device (/dev/sdb1) is a partition. If you - are writing to a USB key or external drive then you probably need to write - to the whole device, not to a partition. If this warning is wrong then you - can disable it with --no-warn-if-partition - -(cherry picked from commit 7274f11ad408bcd4299ba82b3b26f46e62930d03) ---- - builder/builder.ml | 9 +++++++++ - builder/cmdline.ml | 6 ++++++ - builder/cmdline.mli | 1 + - builder/virt-builder.pod | 9 +++++++++ - 4 files changed, 25 insertions(+) - -diff --git a/builder/builder.ml b/builder/builder.ml -index a6f92c7..ac4c748 100644 ---- a/builder/builder.ml -+++ b/builder/builder.ml -@@ -268,6 +268,15 @@ let main () = - - (* --- If we get here, we want to create a guest. --- *) - -+ (* Warn if the user might be writing to a partition on a USB key. *) -+ (match cmdline.output with -+ | Some device when is_partition device -> -+ if cmdline.warn_if_partition then -+ warning (f_"output device (%s) is a partition. If you are writing to a USB key or external drive then you probably need to write to the whole device, not to a partition. If this warning is wrong then you can disable it with --no-warn-if-partition") -+ device; -+ | Some _ | None -> () -+ ); -+ - (* Download the template, or it may be in the cache. *) - let template = - let template, delete_on_exit = -diff --git a/builder/cmdline.ml b/builder/cmdline.ml -index 4893cbf..5205fe6 100644 ---- a/builder/cmdline.ml -+++ b/builder/cmdline.ml -@@ -51,6 +51,7 @@ type cmdline = { - smp : int option; - sources : (string * string) list; - sync : bool; -+ warn_if_partition : bool; - } - - let parse_cmdline () = -@@ -115,6 +116,7 @@ let parse_cmdline () = - let add_source arg = push_front arg sources in - - let sync = ref true in -+ let warn_if_partition = ref true in - - let argspec = [ - "--arch", Arg.Set_string arch, "arch" ^ " " ^ s_"Set the output architecture"; -@@ -163,6 +165,8 @@ let parse_cmdline () = - "--smp", Arg.Int set_smp, "vcpus" ^ " " ^ s_"Set number of vCPUs"; - "--source", Arg.String add_source, "URL" ^ " " ^ s_"Set source URL"; - "--no-sync", Arg.Clear sync, " " ^ s_"Do not fsync output file on exit"; -+ "--no-warn-if-partition", Arg.Clear warn_if_partition, -+ " " ^ s_"Do not warn if writing to a partition"; - ] in - let customize_argspec, get_customize_ops = Customize_cmdline.argspec () in - let customize_argspec = -@@ -212,6 +216,7 @@ read the man page virt-builder(1). - let smp = !smp in - let sources = List.rev !sources in - let sync = !sync in -+ let warn_if_partition = !warn_if_partition in - - (* No arguments and machine-readable mode? Print some facts. *) - if args = [] && machine_readable then ( -@@ -323,4 +328,5 @@ read the man page virt-builder(1). - gpg = gpg; list_format = list_format; memsize = memsize; - network = network; ops = ops; output = output; - size = size; smp = smp; sources = sources; sync = sync; -+ warn_if_partition = warn_if_partition; - } -diff --git a/builder/cmdline.mli b/builder/cmdline.mli -index 4c201dd..854db61 100644 ---- a/builder/cmdline.mli -+++ b/builder/cmdline.mli -@@ -39,6 +39,7 @@ type cmdline = { - smp : int option; - sources : (string * string) list; - sync : bool; -+ warn_if_partition : bool; - } - - val parse_cmdline : unit -> cmdline -diff --git a/builder/virt-builder.pod b/builder/virt-builder.pod -index 545b134..94ba430 100644 ---- a/builder/virt-builder.pod -+++ b/builder/virt-builder.pod -@@ -495,6 +495,15 @@ Note that you should not point I<--source> to sources that you don't - trust (unless the source is signed by someone you do trust). See also - the I<--no-network> option. - -+=item B<--no-warn-if-partition> -+ -+Do not emit a warning if the output device is a partition. This -+warning avoids a common user error when writing to a USB key or -+external drive, when you should normally write to the whole device -+(S>), not to a partition on the device -+(S>). Use this option to I this -+warning. -+ - =item B<-v> - - =item B<--verbose> --- -1.8.3.1 - diff --git a/SOURCES/0100-p2v-Add-XTerm-button-which-launches-a-terminal-windo.patch b/SOURCES/0100-p2v-Add-XTerm-button-which-launches-a-terminal-windo.patch deleted file mode 100644 index df53afd..0000000 --- a/SOURCES/0100-p2v-Add-XTerm-button-which-launches-a-terminal-windo.patch +++ /dev/null @@ -1,81 +0,0 @@ -From a364cdd1d65a11f7672c22ae9d2d7ef553327d7c Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Fri, 3 Jun 2016 10:29:46 +0100 -Subject: [PATCH] p2v: Add "XTerm" button which launches a terminal window. - -(cherry picked from commit bf434bdb3523b7629d50144f35a6bccc05bf94e6) ---- - p2v/gui.c | 23 +++++++++++++++++++---- - 1 file changed, 19 insertions(+), 4 deletions(-) - -diff --git a/p2v/gui.c b/p2v/gui.c -index 015fa21..b8d61b5 100644 ---- a/p2v/gui.c -+++ b/p2v/gui.c -@@ -95,6 +95,7 @@ gui_conversion (struct config *config) - static void test_connection_clicked (GtkWidget *w, gpointer data); - static void *test_connection_thread (void *data); - static void configure_network_button_clicked (GtkWidget *w, gpointer data); -+static void xterm_button_clicked (GtkWidget *w, gpointer data); - static void about_button_clicked (GtkWidget *w, gpointer data); - static void connection_next_clicked (GtkWidget *w, gpointer data); - static void repopulate_output_combo (struct config *config); -@@ -112,6 +113,7 @@ create_connection_dialog (struct config *config) - GtkWidget *test_hbox, *test; - GtkWidget *about; - GtkWidget *configure_network; -+ GtkWidget *xterm; - char port_str[64]; - - conn_dlg = gtk_dialog_new (); -@@ -220,16 +222,18 @@ create_connection_dialog (struct config *config) - /* Buttons. */ - gtk_dialog_add_buttons (GTK_DIALOG (conn_dlg), - _("Configure network ..."), 1, -- _("About virt-p2v " PACKAGE_VERSION " ..."), 2, -- _("Next"), 3, -+ _("XTerm ..."), 2, -+ _("About virt-p2v " PACKAGE_VERSION " ..."), 3, -+ _("Next"), 4, - NULL); - -- next_button = gtk_dialog_get_widget_for_response (GTK_DIALOG (conn_dlg), 3); -+ next_button = gtk_dialog_get_widget_for_response (GTK_DIALOG (conn_dlg), 4); - gtk_widget_set_sensitive (next_button, FALSE); - - configure_network = - gtk_dialog_get_widget_for_response (GTK_DIALOG (conn_dlg), 1); -- about = gtk_dialog_get_widget_for_response (GTK_DIALOG (conn_dlg), 2); -+ xterm = gtk_dialog_get_widget_for_response (GTK_DIALOG (conn_dlg), 2); -+ about = gtk_dialog_get_widget_for_response (GTK_DIALOG (conn_dlg), 3); - - /* Signals. */ - g_signal_connect_swapped (G_OBJECT (conn_dlg), "destroy", -@@ -238,6 +242,8 @@ create_connection_dialog (struct config *config) - G_CALLBACK (test_connection_clicked), config); - g_signal_connect (G_OBJECT (configure_network), "clicked", - G_CALLBACK (configure_network_button_clicked), NULL); -+ g_signal_connect (G_OBJECT (xterm), "clicked", -+ G_CALLBACK (xterm_button_clicked), NULL); - g_signal_connect (G_OBJECT (about), "clicked", - G_CALLBACK (about_button_clicked), NULL); - g_signal_connect (G_OBJECT (next_button), "clicked", -@@ -387,6 +393,15 @@ configure_network_button_clicked (GtkWidget *w, gpointer data) - ignore_value (system ("nm-connection-editor &")); - } - -+/** -+ * Callback from the C button. -+ */ -+static void -+xterm_button_clicked (GtkWidget *w, gpointer data) -+{ -+ ignore_value (system ("xterm &")); -+} -+ - static void - about_button_clicked (GtkWidget *w, gpointer data) - { --- -1.8.3.1 - diff --git a/SOURCES/0101-p2v-Place-conversion-server-name-and-port-side-by-si.patch b/SOURCES/0101-p2v-Place-conversion-server-name-and-port-side-by-si.patch deleted file mode 100644 index f517476..0000000 --- a/SOURCES/0101-p2v-Place-conversion-server-name-and-port-side-by-si.patch +++ /dev/null @@ -1,138 +0,0 @@ -From b8e5dd108de16061210a965d84a83909b97fd472 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Fri, 3 Jun 2016 11:10:20 +0100 -Subject: [PATCH] p2v: Place conversion server name and port side by side. - -Just a small rearrangement of the UI. - -(cherry picked from commit 9f3b6aa6e207b22792973577d7c6b21e6166b77e) ---- - p2v/gui.c | 37 ++++++++++++++++++------------------- - p2v/virt-p2v.pod | 4 +--- - 2 files changed, 19 insertions(+), 22 deletions(-) - -diff --git a/p2v/gui.c b/p2v/gui.c -index b8d61b5..832d72a 100644 ---- a/p2v/gui.c -+++ b/p2v/gui.c -@@ -105,7 +105,8 @@ create_connection_dialog (struct config *config) - { - GtkWidget *intro, *table; - GtkWidget *server_label; -- GtkWidget *port_label; -+ GtkWidget *server_hbox; -+ GtkWidget *port_colon_label; - GtkWidget *username_label; - GtkWidget *password_label; - GtkWidget *identity_label; -@@ -125,44 +126,42 @@ create_connection_dialog (struct config *config) - gtk_label_set_line_wrap (GTK_LABEL (intro), TRUE); - gtk_misc_set_padding (GTK_MISC (intro), 10, 10); - -- table = gtk_table_new (7, 2, FALSE); -+ table = gtk_table_new (6, 2, FALSE); - server_label = gtk_label_new (_("Conversion server:")); - gtk_misc_set_alignment (GTK_MISC (server_label), 1., 0.5); - gtk_table_attach (GTK_TABLE (table), server_label, - 0, 1, 0, 1, GTK_FILL, GTK_FILL, 4, 4); -+ server_hbox = gtk_hbox_new (FALSE, 4); - server_entry = gtk_entry_new (); - if (config->server != NULL) - gtk_entry_set_text (GTK_ENTRY (server_entry), config->server); -- gtk_table_attach (GTK_TABLE (table), server_entry, -- 1, 2, 0, 1, GTK_FILL, GTK_FILL, 4, 4); -- -- port_label = gtk_label_new (_("SSH port:")); -- gtk_misc_set_alignment (GTK_MISC (port_label), 1., 0.5); -- gtk_table_attach (GTK_TABLE (table), port_label, -- 0, 1, 1, 2, GTK_FILL, GTK_FILL, 4, 4); -+ port_colon_label = gtk_label_new (":"); - port_entry = gtk_entry_new (); - gtk_entry_set_width_chars (GTK_ENTRY (port_entry), 6); - snprintf (port_str, sizeof port_str, "%d", config->port); - gtk_entry_set_text (GTK_ENTRY (port_entry), port_str); -- gtk_table_attach (GTK_TABLE (table), port_entry, -- 1, 2, 1, 2, GTK_FILL, GTK_FILL, 4, 4); -+ gtk_box_pack_start (GTK_BOX (server_hbox), server_entry, TRUE, TRUE, 0); -+ gtk_box_pack_start (GTK_BOX (server_hbox), port_colon_label, FALSE, FALSE, 0); -+ gtk_box_pack_start (GTK_BOX (server_hbox), port_entry, FALSE, FALSE, 0); -+ gtk_table_attach (GTK_TABLE (table), server_hbox, -+ 1, 2, 0, 1, GTK_EXPAND|GTK_FILL, GTK_FILL, 4, 4); - - username_label = gtk_label_new (_("User name:")); - gtk_misc_set_alignment (GTK_MISC (username_label), 1., 0.5); - gtk_table_attach (GTK_TABLE (table), username_label, -- 0, 1, 2, 3, GTK_FILL, GTK_FILL, 4, 4); -+ 0, 1, 1, 2, GTK_FILL, GTK_FILL, 4, 4); - username_entry = gtk_entry_new (); - if (config->username != NULL) - gtk_entry_set_text (GTK_ENTRY (username_entry), config->username); - else - gtk_entry_set_text (GTK_ENTRY (username_entry), "root"); - gtk_table_attach (GTK_TABLE (table), username_entry, -- 1, 2, 2, 3, GTK_FILL, GTK_FILL, 4, 4); -+ 1, 2, 1, 2, GTK_EXPAND|GTK_FILL, GTK_FILL, 4, 4); - - password_label = gtk_label_new (_("Password:")); - gtk_misc_set_alignment (GTK_MISC (password_label), 1., 0.5); - gtk_table_attach (GTK_TABLE (table), password_label, -- 0, 1, 3, 4, GTK_FILL, GTK_FILL, 4, 4); -+ 0, 1, 2, 3, GTK_FILL, GTK_FILL, 4, 4); - password_entry = gtk_entry_new (); - gtk_entry_set_visibility (GTK_ENTRY (password_entry), FALSE); - #ifdef GTK_INPUT_PURPOSE_PASSWORD -@@ -172,31 +171,31 @@ create_connection_dialog (struct config *config) - if (config->password != NULL) - gtk_entry_set_text (GTK_ENTRY (password_entry), config->password); - gtk_table_attach (GTK_TABLE (table), password_entry, -- 1, 2, 3, 4, GTK_FILL, GTK_FILL, 4, 4); -+ 1, 2, 2, 3, GTK_EXPAND|GTK_FILL, GTK_FILL, 4, 4); - - identity_label = gtk_label_new (_("SSH Identity URL:")); - gtk_misc_set_alignment (GTK_MISC (identity_label), 1., 0.5); - gtk_table_attach (GTK_TABLE (table), identity_label, -- 0, 1, 4, 5, GTK_FILL, GTK_FILL, 4, 4); -+ 0, 1, 3, 4, GTK_FILL, GTK_FILL, 4, 4); - identity_entry = gtk_entry_new (); - if (config->identity_url != NULL) - gtk_entry_set_text (GTK_ENTRY (identity_entry), config->identity_url); - gtk_table_attach (GTK_TABLE (table), identity_entry, -- 1, 2, 4, 5, GTK_FILL, GTK_FILL, 4, 4); -+ 1, 2, 3, 4, GTK_EXPAND|GTK_FILL, GTK_FILL, 4, 4); - - identity_tip_label = gtk_label_new (NULL); - gtk_label_set_markup (GTK_LABEL (identity_tip_label), - _("If using password authentication, leave the SSH Identity URL blank")); - gtk_label_set_line_wrap (GTK_LABEL (identity_tip_label), TRUE); - gtk_table_attach (GTK_TABLE (table), identity_tip_label, -- 1, 2, 5, 6, GTK_FILL, GTK_FILL, 4, 4); -+ 1, 2, 4, 5, GTK_FILL, GTK_FILL, 4, 4); - - sudo_button = - gtk_check_button_new_with_label (_("Use sudo when running virt-v2v")); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (sudo_button), - config->sudo); - gtk_table_attach (GTK_TABLE (table), sudo_button, -- 1, 2, 6, 7, GTK_FILL, GTK_FILL, 4, 4); -+ 1, 2, 5, 6, GTK_FILL, GTK_FILL, 4, 4); - - test_hbox = gtk_hbox_new (FALSE, 0); - test = gtk_button_new_with_label (_("Test connection")); -diff --git a/p2v/virt-p2v.pod b/p2v/virt-p2v.pod -index 3e4ef99..5ceafa7 100644 ---- a/p2v/virt-p2v.pod -+++ b/p2v/virt-p2v.pod -@@ -81,9 +81,7 @@ When virt-p2v starts up in GUI mode, the first dialog looks like this: - ┌────────────────────────────────────────────────────────┐ - │ virt-p2v │ - │ │ -- │ Conversion server: [_________________________________] │ -- │ │ -- │ SSH port: [22_______________________________] │ -+ │ Conversion server: [_______________________] : [22___] │ - │ │ - │ User name: [root_____________________________] │ - │ │ --- -1.8.3.1 - diff --git a/SOURCES/0102-mllib-Fix-other-places-where-Dev_t-module-must-be-li.patch b/SOURCES/0102-mllib-Fix-other-places-where-Dev_t-module-must-be-li.patch deleted file mode 100644 index 9b5c3ef..0000000 --- a/SOURCES/0102-mllib-Fix-other-places-where-Dev_t-module-must-be-li.patch +++ /dev/null @@ -1,60 +0,0 @@ -From d332931de1e874ee398bb88c88bd3d7850cba91f Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Fri, 3 Jun 2016 14:21:59 +0100 -Subject: [PATCH] mllib: Fix other places where Dev_t module must be linked to - Common_utils. - -Fixes commit df7a33768eab2381b958ede2c8a40bc9cbc87928. - -(cherry picked from commit c97ca67a5c000dac24fdd3f3f749e77501eecd3f) ---- - mllib/Makefile.am | 9 ++++++++- - v2v/test-harness/Makefile.am | 2 ++ - 2 files changed, 10 insertions(+), 1 deletion(-) - -diff --git a/mllib/Makefile.am b/mllib/Makefile.am -index e44abed..e0f1987 100644 ---- a/mllib/Makefile.am -+++ b/mllib/Makefile.am -@@ -136,10 +136,17 @@ libdir.ml: Makefile - - # Tests. - --common_utils_tests_SOURCES = dummy.c -+common_utils_tests_SOURCES = \ -+ dev_t-c.c \ -+ dummy.c -+common_utils_tests_CPPFLAGS = \ -+ -I. \ -+ -I$(top_builddir) \ -+ -I$(shell $(OCAMLC) -where) - common_utils_tests_BOBJECTS = \ - guestfs_config.cmo \ - common_gettext.cmo \ -+ dev_t.cmo \ - common_utils.cmo \ - common_utils_tests.cmo - common_utils_tests_XOBJECTS = $(common_utils_tests_BOBJECTS:.cmo=.cmx) -diff --git a/v2v/test-harness/Makefile.am b/v2v/test-harness/Makefile.am -index a3c980a..cba5b41 100644 ---- a/v2v/test-harness/Makefile.am -+++ b/v2v/test-harness/Makefile.am -@@ -60,6 +60,7 @@ OCAMLFLAGS = $(OCAML_FLAGS) $(OCAML_WARN_ERROR) - BOBJECTS = \ - $(top_builddir)/mllib/guestfs_config.cmo \ - $(top_builddir)/mllib/common_gettext.cmo \ -+ $(top_builddir)/mllib/dev_t.cmo \ - $(top_builddir)/mllib/common_utils.cmo \ - $(top_builddir)/v2v/xml.cmo \ - $(SOURCES_ML:.ml=.cmo) \ -@@ -94,6 +95,7 @@ libv2vth_a_CFLAGS = \ - -fPIC - - libv2vth_a_SOURCES = \ -+ ../../mllib/dev_t-c.c \ - ../xml-c.c - - v2v_test_harness.cmi: $(top_builddir)/ocaml/guestfs.cmi --- -1.8.3.1 - diff --git a/SOURCES/0103-p2v-Add-more-authors-who-have-worked-on-virt-v2v-and.patch b/SOURCES/0103-p2v-Add-more-authors-who-have-worked-on-virt-v2v-and.patch deleted file mode 100644 index be701fc..0000000 --- a/SOURCES/0103-p2v-Add-more-authors-who-have-worked-on-virt-v2v-and.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 305f1ed089bdf8eda3fa0020397bd50e9a7adf3d Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Sat, 4 Jun 2016 14:46:20 +0100 -Subject: [PATCH] p2v: Add more authors who have worked on virt-v2v and - virt-p2v. - -Use this command as a starting point: - - git shortlog -s -- p2v v2v | awk -F'\t' '{print $2}' | sort -f - -However note the above will include people who made only incidental -code changes, and also misses out QA team members, so the actual list -still has to be curated by hand. - -(cherry picked from commit 3a231afcfa295489fc07cafb60108e0d05ecf4bb) ---- - p2v/about-authors.c | 8 +++++++- - 1 file changed, 7 insertions(+), 1 deletion(-) - -diff --git a/p2v/about-authors.c b/p2v/about-authors.c -index c6a4235..88f48f9 100644 ---- a/p2v/about-authors.c -+++ b/p2v/about-authors.c -@@ -20,12 +20,18 @@ - - #include "p2v.h" - --/* The list of authors of virt-p2v and virt-v2v, for the About dialog. */ -+/* The list of authors of virt-p2v and virt-v2v, for the About dialog. -+ * -+ * Note: In alphabetical order of surname / family name. -+ */ - - const char *authors[] = { - "Matthew Booth", -+ "Cédric Bosdonnat", - "John Eckersberg", - "Richard W.M. Jones", -+ "Shahar Havivi", -+ "Roman Kagan", - "Mike Latimer", - "Pino Toscano", - "Ming Xie", --- -1.8.3.1 - diff --git a/SOURCES/0104-customize-Add-uninstall-operation-RHBZ-1343375.patch b/SOURCES/0104-customize-Add-uninstall-operation-RHBZ-1343375.patch deleted file mode 100644 index 9308f80..0000000 --- a/SOURCES/0104-customize-Add-uninstall-operation-RHBZ-1343375.patch +++ /dev/null @@ -1,103 +0,0 @@ -From a99e410a2dc450569bc3218005fbc38e60e2d4af Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Tue, 7 Jun 2016 10:24:54 +0100 -Subject: [PATCH] customize: Add --uninstall operation (RHBZ#1343375). - -(cherry picked from commit 6425a8824b13a60ddf5d04270808da00568b1b53) ---- - customize/customize_run.ml | 29 +++++++++++++++++++++++++++++ - generator/customize.ml | 17 +++++++++++++++-- - 2 files changed, 44 insertions(+), 2 deletions(-) - -diff --git a/customize/customize_run.ml b/customize/customize_run.ml -index 8c38d62..10647fd 100644 ---- a/customize/customize_run.ml -+++ b/customize/customize_run.ml -@@ -154,6 +154,30 @@ exec >>%s 2>&1 - | pm -> - error_unimplemented_package_manager (s_"--update") pm - -+ and guest_uninstall_command packages = -+ let quoted_args = String.concat " " (List.map quote packages) in -+ match g#inspect_get_package_management root with -+ | "apk" -> sprintf "apk del %s" quoted_args -+ | "apt" -> -+ (* http://unix.stackexchange.com/questions/22820 *) -+ sprintf " -+ export DEBIAN_FRONTEND=noninteractive -+ apt_opts='-q -y -o Dpkg::Options::=--force-confnew' -+ apt-get $apt_opts remove %s -+ " quoted_args -+ | "dnf" -> sprintf "dnf -y remove %s" quoted_args -+ | "pisi" -> sprintf "pisi rm %s" quoted_args -+ | "pacman" -> sprintf "pacman -R %s" quoted_args -+ | "urpmi" -> sprintf "urpme %s" quoted_args -+ | "xbps" -> sprintf "xbps-remove -Sy %s" quoted_args -+ | "yum" -> sprintf "yum -y remove %s" quoted_args -+ | "zypper" -> sprintf "zypper -n rm -l %s" quoted_args -+ -+ | "unknown" -> -+ error_unknown_package_manager (s_"--uninstall") -+ | pm -> -+ error_unimplemented_package_manager (s_"--uninstall") pm -+ - (* Windows has package_management == "unknown". *) - and error_unknown_package_manager flag = - error (f_"cannot use '%s' because no package manager has been detected for this guest OS.\n\nIf this guest OS is a common one with ordinary package management then this may have been caused by a failure of libguestfs inspection.\n\nFor OSes such as Windows that lack package management, this is not possible. Try using one of the '--firstboot*' flags instead (described in the manual).") flag -@@ -334,6 +358,11 @@ exec >>%s 2>&1 - message (f_"Running touch: %s") path; - g#touch path - -+ | `UninstallPackages pkgs -> -+ message (f_"Uninstalling packages: %s") (String.concat " " pkgs); -+ let cmd = guest_uninstall_command pkgs in -+ do_run ~display:cmd cmd -+ - | `Update -> - message (f_"Updating packages"); - let cmd = guest_update_command () in -diff --git a/generator/customize.ml b/generator/customize.ml -index 403bb89..8caf2b5 100644 ---- a/generator/customize.ml -+++ b/generator/customize.ml -@@ -214,7 +214,7 @@ installed during the image build using the guest's package manager - For an overview on the different ways to install packages, see - L. - --See also I<--update>."; -+See also I<--update>, I<--uninstall>."; - }; - - { op_name = "link"; -@@ -424,6 +424,19 @@ string like C"; - This command performs a L-like operation on C."; - }; - -+ { op_name = "uninstall"; -+ op_type = StringList "PKG,PKG.."; -+ op_discrim = "`UninstallPackages"; -+ op_shortdesc = "Uninstall package(s)"; -+ op_pod_longdesc = "\ -+Uninstall the named packages (a comma-separated list). These are -+removed during the image build using the guest's package manager -+(eg. apt, yum, etc.). Dependent packages may also need to be -+uninstalled to satisfy the request. -+ -+See also I<--install>, I<--update>."; -+ }; -+ - { op_name = "update"; - op_type = Unit; - op_discrim = "`Update"; -@@ -433,7 +446,7 @@ Do the equivalent of C, C, or whatever - command is required to update the packages already installed in the - template to their latest versions. - --See also I<--install>."; -+See also I<--install>, I<--uninstall>."; - }; - - { op_name = "upload"; --- -1.8.3.1 - diff --git a/SOURCES/0105-p2v-Print-full-curl-error-when-failing-to-fetch-SSH-.patch b/SOURCES/0105-p2v-Print-full-curl-error-when-failing-to-fetch-SSH-.patch deleted file mode 100644 index 26fae55..0000000 --- a/SOURCES/0105-p2v-Print-full-curl-error-when-failing-to-fetch-SSH-.patch +++ /dev/null @@ -1,81 +0,0 @@ -From 6440601758720bd1390e768a8f26f313d7bb4ca9 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Tue, 7 Jun 2016 14:50:47 +0100 -Subject: [PATCH] p2v: Print full curl error when failing to fetch SSH identify - URL (RHBZ#1343423). - -(cherry picked from commit 0e0a350c02b9c4d7a4108d2743ee1a61ce88a1f1) ---- - p2v/ssh.c | 23 +++++++++++++++++------ - 1 file changed, 17 insertions(+), 6 deletions(-) - -diff --git a/p2v/ssh.c b/p2v/ssh.c -index c4d7e2e..ce2b17b 100644 ---- a/p2v/ssh.c -+++ b/p2v/ssh.c -@@ -45,6 +45,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -168,11 +169,18 @@ static int - curl_download (const char *url, const char *local_file) - { - char curl_config_file[] = "/tmp/curl.XXXXXX"; -+ char error_file[] = "/tmp/curlerr.XXXXXX"; -+ CLEANUP_FREE char *error_message = NULL; - int fd, r; - size_t i, len; - FILE *fp; - CLEANUP_FREE char *curl_cmd = NULL; - -+ fd = mkstemp (error_file); -+ if (fd == -1) -+ error (EXIT_FAILURE, errno, "mkstemp: %s", error_file); -+ close (fd); -+ - /* Use a secure curl config file because escaping is easier. */ - fd = mkstemp (curl_config_file); - if (fd == -1) { -@@ -201,8 +209,8 @@ curl_download (const char *url, const char *local_file) - fclose (fp); - - /* Run curl to download the URL to a file. */ -- if (asprintf (&curl_cmd, "curl -f -o %s -K %s", -- local_file, curl_config_file) == -1) { -+ if (asprintf (&curl_cmd, "curl -f -s -S -o %s -K %s 2>%s", -+ local_file, curl_config_file, error_file) == -1) { - perror ("asprintf"); - exit (EXIT_FAILURE); - } -@@ -216,17 +224,20 @@ curl_download (const char *url, const char *local_file) - - /* Did curl subprocess fail? */ - if (WIFEXITED (r) && WEXITSTATUS (r) != 0) { -- /* XXX Better error handling. The codes can be looked up in -- * the curl(1) man page. -- */ -- set_ssh_error ("%s: curl error %d", url, WEXITSTATUS (r)); -+ if (read_whole_file (error_file, &error_message, NULL) == 0) -+ set_ssh_error ("%s: %s", url, error_message); -+ else -+ set_ssh_error ("%s: curl error %d", url, WEXITSTATUS (r)); -+ unlink (error_file); - return -1; - } - else if (!WIFEXITED (r)) { - set_ssh_error ("curl subprocess got a signal (%d)", r); -+ unlink (error_file); - return -1; - } - -+ unlink (error_file); - return 0; - } - --- -1.8.3.1 - diff --git a/SOURCES/0106-mllib-Use-Unix.F_OK-instead-of-plain-F_OK.patch b/SOURCES/0106-mllib-Use-Unix.F_OK-instead-of-plain-F_OK.patch deleted file mode 100644 index 4401fd7..0000000 --- a/SOURCES/0106-mllib-Use-Unix.F_OK-instead-of-plain-F_OK.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 4e0b14a89cceb48b8ed1c63bcceb6a2c48dec167 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Tue, 14 Jun 2016 18:54:44 +0100 -Subject: [PATCH] mllib: Use Unix.F_OK instead of plain F_OK. - -Removes this warning: - - File "common_utils.ml", line 826, characters 24-28: - Warning 40: F_OK was selected from type Unix.access_permission. - It is not visible in the current scope, and will not - be selected if the type becomes unknown. - -(cherry picked from commit 2ecdc46114f564a42f8d6c51c2c2763ba3dda15e) ---- - mllib/common_utils.ml | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/mllib/common_utils.ml b/mllib/common_utils.ml -index c29dfa0..be8810a 100644 ---- a/mllib/common_utils.ml -+++ b/mllib/common_utils.ml -@@ -827,7 +827,7 @@ let is_partition dev = - let major = Dev_t.major rdev in - let minor = Dev_t.minor rdev in - let path = sprintf "/sys/dev/block/%d:%d/partition" major minor in -- Unix.access path [F_OK]; -+ Unix.access path [Unix.F_OK]; - true - ) - with Unix.Unix_error _ -> false --- -1.8.3.1 - diff --git a/SOURCES/0107-p2v-ssh-Print-ssh-error-if-user-gives-invalid-conver.patch b/SOURCES/0107-p2v-ssh-Print-ssh-error-if-user-gives-invalid-conver.patch deleted file mode 100644 index c501800..0000000 --- a/SOURCES/0107-p2v-ssh-Print-ssh-error-if-user-gives-invalid-conver.patch +++ /dev/null @@ -1,87 +0,0 @@ -From e65b2e73ff4f3c6bf692d12c34a0188aa51b552b Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Thu, 16 Jun 2016 21:22:16 +0100 -Subject: [PATCH] p2v: ssh: Print ssh error if user gives invalid conversion - server (RHBZ#1167916). - -Instead of throwing away the ssh error and printing the generic -message "unexpected end of file waiting for password prompt", we -capture the ssh error and print it. The user will see the ssh -diagnostic, eg. "No route to host". - -(cherry picked from commit 8717a110120f84973f1148adf48e59222cf45e73) ---- - p2v/ssh.c | 23 ++++++++++++++++++++++- - 1 file changed, 22 insertions(+), 1 deletion(-) - -diff --git a/p2v/ssh.c b/p2v/ssh.c -index ce2b17b..d9210f3 100644 ---- a/p2v/ssh.c -+++ b/p2v/ssh.c -@@ -97,6 +97,7 @@ static void compile_regexps (void) __attribute__((constructor)); - static void free_regexps (void) __attribute__((destructor)); - - static pcre *password_re; -+static pcre *ssh_message_re; - static pcre *prompt_re; - static pcre *version_re; - static pcre *feature_libguestfs_rewrite_re; -@@ -138,6 +139,7 @@ compile_regexps (void) - } while (0) - - COMPILE (password_re, "password:", 0); -+ COMPILE (ssh_message_re, "(ssh: .*)", 0); - /* The magic synchronization strings all match this expression. See - * start_ssh function below. - */ -@@ -156,6 +158,7 @@ static void - free_regexps (void) - { - pcre_free (password_re); -+ pcre_free (ssh_message_re); - pcre_free (prompt_re); - pcre_free (version_re); - pcre_free (feature_libguestfs_rewrite_re); -@@ -350,10 +353,14 @@ start_ssh (struct config *config, char **extra_args, int wait_prompt) - - if (using_password_auth && - config->password && strlen (config->password) > 0) { -+ CLEANUP_FREE char *ssh_message = NULL; -+ - /* Wait for the password prompt. */ -+ wait_password_again: - switch (mexp_expect (h, - (mexp_regexp[]) { - { 100, .re = password_re }, -+ { 101, .re = ssh_message_re }, - { 0 } - }, ovector, ovecsize)) { - case 100: /* Got password prompt. */ -@@ -364,9 +371,23 @@ start_ssh (struct config *config, char **extra_args, int wait_prompt) - } - break; - -+ case 101: -+ free (ssh_message); -+ ssh_message = strndup (&h->buffer[ovector[2]], ovector[3]-ovector[2]); -+ goto wait_password_again; -+ - case MEXP_EOF: - mexp_close (h); -- set_ssh_error ("unexpected end of file waiting for password prompt"); -+ /* This is where we get to if the user enters an incorrect or -+ * impossible hostname or port number. Hopefully ssh printed an -+ * error message, and we picked it up and put it in -+ * 'ssh_message' in case 101 above. If not we have to print a -+ * generic error instead. -+ */ -+ if (ssh_message) -+ set_ssh_error ("%s", ssh_message); -+ else -+ set_ssh_error ("unknown ssh error"); - return NULL; - - case MEXP_TIMEOUT: --- -1.8.3.1 - diff --git a/SOURCES/0108-p2v-Don-t-allow-password-SSH-identity-URL-fields-to-.patch b/SOURCES/0108-p2v-Don-t-allow-password-SSH-identity-URL-fields-to-.patch deleted file mode 100644 index 5e754b1..0000000 --- a/SOURCES/0108-p2v-Don-t-allow-password-SSH-identity-URL-fields-to-.patch +++ /dev/null @@ -1,109 +0,0 @@ -From b07b91cdc973bcaa65e9df0fa0e304943dcaffa6 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Fri, 17 Jun 2016 21:32:33 +0100 -Subject: [PATCH] p2v: Don't allow password & SSH identity URL fields to both - be non-empty. - -It makes no sense. By setting one field to non-sensitive when the -other field is populated, we can avoid this happening, and also make -tabbing between the fields simpler. - -As a consequence of making this change, I also got rid of the now -unnecessary explanatory text telling you to leave one field blank. - -(cherry picked from commit b0d2d697e03a11642ab36f4a92b1f849085d2db9) ---- - p2v/gui.c | 44 ++++++++++++++++++++++++++++++++++---------- - 1 file changed, 34 insertions(+), 10 deletions(-) - -diff --git a/p2v/gui.c b/p2v/gui.c -index 832d72a..dad8f6e 100644 ---- a/p2v/gui.c -+++ b/p2v/gui.c -@@ -92,6 +92,7 @@ gui_conversion (struct config *config) - /*----------------------------------------------------------------------*/ - /* Connection dialog. */ - -+static void password_or_identity_changed_callback (GtkWidget *w, gpointer data); - static void test_connection_clicked (GtkWidget *w, gpointer data); - static void *test_connection_thread (void *data); - static void configure_network_button_clicked (GtkWidget *w, gpointer data); -@@ -110,7 +111,6 @@ create_connection_dialog (struct config *config) - GtkWidget *username_label; - GtkWidget *password_label; - GtkWidget *identity_label; -- GtkWidget *identity_tip_label; - GtkWidget *test_hbox, *test; - GtkWidget *about; - GtkWidget *configure_network; -@@ -126,7 +126,7 @@ create_connection_dialog (struct config *config) - gtk_label_set_line_wrap (GTK_LABEL (intro), TRUE); - gtk_misc_set_padding (GTK_MISC (intro), 10, 10); - -- table = gtk_table_new (6, 2, FALSE); -+ table = gtk_table_new (5, 2, FALSE); - server_label = gtk_label_new (_("Conversion server:")); - gtk_misc_set_alignment (GTK_MISC (server_label), 1., 0.5); - gtk_table_attach (GTK_TABLE (table), server_label, -@@ -183,19 +183,12 @@ create_connection_dialog (struct config *config) - gtk_table_attach (GTK_TABLE (table), identity_entry, - 1, 2, 3, 4, GTK_EXPAND|GTK_FILL, GTK_FILL, 4, 4); - -- identity_tip_label = gtk_label_new (NULL); -- gtk_label_set_markup (GTK_LABEL (identity_tip_label), -- _("If using password authentication, leave the SSH Identity URL blank")); -- gtk_label_set_line_wrap (GTK_LABEL (identity_tip_label), TRUE); -- gtk_table_attach (GTK_TABLE (table), identity_tip_label, -- 1, 2, 4, 5, GTK_FILL, GTK_FILL, 4, 4); -- - sudo_button = - gtk_check_button_new_with_label (_("Use sudo when running virt-v2v")); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (sudo_button), - config->sudo); - gtk_table_attach (GTK_TABLE (table), sudo_button, -- 1, 2, 5, 6, GTK_FILL, GTK_FILL, 4, 4); -+ 1, 2, 4, 5, GTK_FILL, GTK_FILL, 4, 4); - - test_hbox = gtk_hbox_new (FALSE, 0); - test = gtk_button_new_with_label (_("Test connection")); -@@ -247,6 +240,37 @@ create_connection_dialog (struct config *config) - G_CALLBACK (about_button_clicked), NULL); - g_signal_connect (G_OBJECT (next_button), "clicked", - G_CALLBACK (connection_next_clicked), NULL); -+ g_signal_connect (G_OBJECT (password_entry), "changed", -+ G_CALLBACK (password_or_identity_changed_callback), NULL); -+ g_signal_connect (G_OBJECT (identity_entry), "changed", -+ G_CALLBACK (password_or_identity_changed_callback), NULL); -+} -+ -+/** -+ * The password or SSH identity URL entries are mutually exclusive, so -+ * if one contains text then disable the other. This function is -+ * called when the "changed" signal is received on either. -+ */ -+static void -+password_or_identity_changed_callback (GtkWidget *w, gpointer data) -+{ -+ const char *str; -+ int password_set; -+ int identity_set; -+ -+ str = gtk_entry_get_text (GTK_ENTRY (password_entry)); -+ password_set = str != NULL && STRNEQ (str, ""); -+ str = gtk_entry_get_text (GTK_ENTRY (identity_entry)); -+ identity_set = str != NULL && STRNEQ (str, ""); -+ -+ if (!password_set && !identity_set) { -+ gtk_widget_set_sensitive (password_entry, TRUE); -+ gtk_widget_set_sensitive (identity_entry, TRUE); -+ } -+ else if (identity_set) -+ gtk_widget_set_sensitive (password_entry, FALSE); -+ else if (password_set) -+ gtk_widget_set_sensitive (identity_entry, FALSE); - } - - static void --- -1.8.3.1 - diff --git a/SOURCES/0109-p2v-Disable-the-sudo-button-when-the-username-is-roo.patch b/SOURCES/0109-p2v-Disable-the-sudo-button-when-the-username-is-roo.patch deleted file mode 100644 index 6c55c30..0000000 --- a/SOURCES/0109-p2v-Disable-the-sudo-button-when-the-username-is-roo.patch +++ /dev/null @@ -1,64 +0,0 @@ -From 8bc5cc1f3b8ec7c71f7dc961a575abadfb578ace Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Fri, 17 Jun 2016 22:24:45 +0100 -Subject: [PATCH] p2v: Disable the sudo button when the username is root. - -(cherry picked from commit 072cf26dc3fdd90e8301b15f430b3f34a9bbf85b) ---- - p2v/gui.c | 29 +++++++++++++++++++++++++++++ - 1 file changed, 29 insertions(+) - -diff --git a/p2v/gui.c b/p2v/gui.c -index dad8f6e..93b086a 100644 ---- a/p2v/gui.c -+++ b/p2v/gui.c -@@ -92,6 +92,7 @@ gui_conversion (struct config *config) - /*----------------------------------------------------------------------*/ - /* Connection dialog. */ - -+static void username_changed_callback (GtkWidget *w, gpointer data); - static void password_or_identity_changed_callback (GtkWidget *w, gpointer data); - static void test_connection_clicked (GtkWidget *w, gpointer data); - static void *test_connection_thread (void *data); -@@ -240,10 +241,38 @@ create_connection_dialog (struct config *config) - G_CALLBACK (about_button_clicked), NULL); - g_signal_connect (G_OBJECT (next_button), "clicked", - G_CALLBACK (connection_next_clicked), NULL); -+ g_signal_connect (G_OBJECT (username_entry), "changed", -+ G_CALLBACK (username_changed_callback), NULL); - g_signal_connect (G_OBJECT (password_entry), "changed", - G_CALLBACK (password_or_identity_changed_callback), NULL); - g_signal_connect (G_OBJECT (identity_entry), "changed", - G_CALLBACK (password_or_identity_changed_callback), NULL); -+ -+ /* Call this signal to initialize the sensitivity of the sudo -+ * button correctly. -+ */ -+ username_changed_callback (NULL, NULL); -+} -+ -+/** -+ * If the username is "root", disable the sudo button. -+ */ -+static void -+username_changed_callback (GtkWidget *w, gpointer data) -+{ -+ const char *str; -+ int username_is_root; -+ int sudo_is_set; -+ -+ str = gtk_entry_get_text (GTK_ENTRY (username_entry)); -+ username_is_root = str != NULL && STREQ (str, "root"); -+ sudo_is_set = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (sudo_button)); -+ -+ /* The sudo button is sensitive if: -+ * - The username is not "root", or -+ * - The button is not already checked (to allow the user to uncheck it) -+ */ -+ gtk_widget_set_sensitive (sudo_button, !username_is_root || sudo_is_set); - } - - /** --- -1.8.3.1 - diff --git a/SOURCES/0110-p2v-Add-a-dialog-confirming-the-user-really-means-to.patch b/SOURCES/0110-p2v-Add-a-dialog-confirming-the-user-really-means-to.patch deleted file mode 100644 index bfdeafb..0000000 --- a/SOURCES/0110-p2v-Add-a-dialog-confirming-the-user-really-means-to.patch +++ /dev/null @@ -1,83 +0,0 @@ -From eabb2aee8770ca07282138ea23f66b3c9e56f85b Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Sat, 18 Jun 2016 09:19:10 +0100 -Subject: [PATCH] p2v: Add a dialog confirming the user really means to cancel - (RHBZ#1340464). - -Thanks: Kean Li -(cherry picked from commit 4f4f0f1fe98dbc82227c3a393d76498b6624a400) ---- - p2v/gui.c | 34 ++++++++++++++++++++++++++++------ - 1 file changed, 28 insertions(+), 6 deletions(-) - -diff --git a/p2v/gui.c b/p2v/gui.c -index 93b086a..142d2eb 100644 ---- a/p2v/gui.c -+++ b/p2v/gui.c -@@ -1409,7 +1409,7 @@ static void set_status (const char *msg); - static void add_v2v_output (const char *msg); - static void add_v2v_output_2 (const char *msg, size_t len); - static void *start_conversion_thread (void *data); --static void cancel_conversion_clicked (GtkWidget *w, gpointer data); -+static void cancel_conversion_dialog (GtkWidget *w, gpointer data); - static void reboot_clicked (GtkWidget *w, gpointer data); - static gboolean close_running_dialog (GtkWidget *w, GdkEvent *event, gpointer data); - -@@ -1447,7 +1447,7 @@ create_running_dialog (void) - - /* Buttons. */ - gtk_dialog_add_buttons (GTK_DIALOG (run_dlg), -- _("Cancel conversion"), 1, -+ _("Cancel conversion ..."), 1, - _("Reboot"), 2, - NULL); - cancel_button = gtk_dialog_get_widget_for_response (GTK_DIALOG (run_dlg), 1); -@@ -1461,7 +1461,7 @@ create_running_dialog (void) - g_signal_connect_swapped (G_OBJECT (run_dlg), "destroy", - G_CALLBACK (gtk_main_quit), NULL); - g_signal_connect (G_OBJECT (cancel_button), "clicked", -- G_CALLBACK (cancel_conversion_clicked), NULL); -+ G_CALLBACK (cancel_conversion_dialog), NULL); - g_signal_connect (G_OBJECT (reboot_button), "clicked", - G_CALLBACK (reboot_clicked), NULL); - } -@@ -1753,11 +1753,33 @@ close_running_dialog (GtkWidget *w, GdkEvent *event, gpointer data) - return FALSE; - } - -+/** -+ * This is called when the user clicks on the "Cancel conversion" -+ * button. Since conversions can run for a long time, and cancelling -+ * the conversion is non-recoverable, this function displays a -+ * confirmation dialog before cancelling the conversion. -+ */ - static void --cancel_conversion_clicked (GtkWidget *w, gpointer data) -+cancel_conversion_dialog (GtkWidget *w, gpointer data) - { -- /* This makes start_conversion return an error (eventually). */ -- cancel_conversion (); -+ GtkWidget *dlg; -+ -+ if (!conversion_is_running ()) -+ return; -+ -+ dlg = gtk_message_dialog_new (GTK_WINDOW (run_dlg), -+ GTK_DIALOG_DESTROY_WITH_PARENT, -+ GTK_MESSAGE_QUESTION, -+ GTK_BUTTONS_YES_NO, -+ _("Really cancel the conversion? " -+ "To convert this machine you will need to " -+ "re-run the conversion from the beginning.")); -+ gtk_window_set_title (GTK_WINDOW (dlg), _("Cancel the conversion")); -+ if (gtk_dialog_run (GTK_DIALOG (dlg)) == GTK_RESPONSE_YES) -+ /* This makes start_conversion return an error (eventually). */ -+ cancel_conversion (); -+ -+ gtk_widget_destroy (dlg); - } - - static void --- -1.8.3.1 - diff --git a/SOURCES/0111-virt-tools-Add-common-colours-option.patch b/SOURCES/0111-virt-tools-Add-common-colours-option.patch deleted file mode 100644 index 628b170..0000000 --- a/SOURCES/0111-virt-tools-Add-common-colours-option.patch +++ /dev/null @@ -1,269 +0,0 @@ -From 3b7c70dea311561c4ffe69ceee65a994a5543862 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Sat, 18 Jun 2016 10:22:46 +0100 -Subject: [PATCH] virt tools: Add common --colours option. - -This option (alternately spelled: --color, --colour, --colors, or ---colours) enables ANSI colour sequences output even if that would be -disabled becaues the output is not a TTY. - -(cherry picked from commit b000d6bc68543035e3fc14853c8a9f518ed1b0f3) ---- - builder/virt-builder.pod | 9 +++++++++ - customize/virt-customize.pod | 9 +++++++++ - dib/virt-dib.pod | 9 +++++++++ - get-kernel/virt-get-kernel.pod | 9 +++++++++ - mllib/common_utils.ml | 42 +++++++++++++++++++++++++----------------- - resize/virt-resize.pod | 9 +++++++++ - sparsify/virt-sparsify.pod | 9 +++++++++ - sysprep/virt-sysprep.pod | 9 +++++++++ - v2v/cmdline.ml | 1 + - v2v/virt-v2v.pod | 9 +++++++++ - 10 files changed, 98 insertions(+), 17 deletions(-) - -diff --git a/builder/virt-builder.pod b/builder/virt-builder.pod -index 94ba430..5e344de 100644 ---- a/builder/virt-builder.pod -+++ b/builder/virt-builder.pod -@@ -241,6 +241,15 @@ Using I<--no-check-signature> bypasses this check. - - See also I<--fingerprint>. - -+=item B<--colors> -+ -+=item B<--colours> -+ -+Use ANSI colour sequences to colourize messages. This is the default -+when the output is a tty. If the output of the program is redirected -+to a file, ANSI colour sequences are disabled unless you use this -+option. -+ - =item B<--curl> CURL - - Specify an alternate L binary. You can also use this to add -diff --git a/customize/virt-customize.pod b/customize/virt-customize.pod -index 8fb9931..e8eb148 100644 ---- a/customize/virt-customize.pod -+++ b/customize/virt-customize.pod -@@ -74,6 +74,15 @@ disk format (not just an ISO). - Specify the disk format for the next I<--attach> option. The - C is usually C or C. Use C for ISOs. - -+=item B<--colors> -+ -+=item B<--colours> -+ -+Use ANSI colour sequences to colourize messages. This is the default -+when the output is a tty. If the output of the program is redirected -+to a file, ANSI colour sequences are disabled unless you use this -+option. -+ - =item B<-c> URI - - =item B<--connect> URI -diff --git a/dib/virt-dib.pod b/dib/virt-dib.pod -index 9baae23..8ccb9f5 100644 ---- a/dib/virt-dib.pod -+++ b/dib/virt-dib.pod -@@ -72,6 +72,15 @@ Right now this option does nothing more than setting the C - environment variable for the elements, and it's up to them to - produce an image for the requested architecture. - -+=item B<--colors> -+ -+=item B<--colours> -+ -+Use ANSI colour sequences to colourize messages. This is the default -+when the output is a tty. If the output of the program is redirected -+to a file, ANSI colour sequences are disabled unless you use this -+option. -+ - =item B<--debug> LEVEL - - Set the debug level to C, which is a non-negative integer -diff --git a/get-kernel/virt-get-kernel.pod b/get-kernel/virt-get-kernel.pod -index 92d6cb6..97a159c 100644 ---- a/get-kernel/virt-get-kernel.pod -+++ b/get-kernel/virt-get-kernel.pod -@@ -44,6 +44,15 @@ force a particular format use the I<--format> option. - Add a remote disk. The URI format is compatible with guestfish. - See L. - -+=item B<--colors> -+ -+=item B<--colours> -+ -+Use ANSI colour sequences to colourize messages. This is the default -+when the output is a tty. If the output of the program is redirected -+to a file, ANSI colour sequences are disabled unless you use this -+option. -+ - =item B<-c> URI - - =item B<--connect> URI -diff --git a/mllib/common_utils.ml b/mllib/common_utils.ml -index be8810a..7bd02f8 100644 ---- a/mllib/common_utils.ml -+++ b/mllib/common_utils.ml -@@ -299,27 +299,16 @@ let protect ~f ~finally = - finally (); - match r with Either ret -> ret | Or exn -> raise exn - --let istty chan = -- Unix.isatty (Unix.descr_of_out_channel chan) -- --(* ANSI terminal colours. *) --let ansi_green ?(chan = stdout) () = -- if istty chan then output_string chan "\x1b[0;32m" --let ansi_red ?(chan = stdout) () = -- if istty chan then output_string chan "\x1b[1;31m" --let ansi_blue ?(chan = stdout) () = -- if istty chan then output_string chan "\x1b[1;34m" --let ansi_magenta ?(chan = stdout) () = -- if istty chan then output_string chan "\x1b[1;35m" --let ansi_restore ?(chan = stdout) () = -- if istty chan then output_string chan "\x1b[0m" -- - (* Program name. *) - let prog = Filename.basename Sys.executable_name - --(* Stores the quiet (--quiet), trace (-x) and verbose (-v) flags in a -- * global variable. -+(* Stores the colours (--colours), quiet (--quiet), trace (-x) and -+ * verbose (-v) flags in a global variable. - *) -+let colours = ref false -+let set_colours () = colours := true -+let colours () = !colours -+ - let quiet = ref false - let set_quiet () = quiet := true - let quiet () = !quiet -@@ -332,6 +321,21 @@ let verbose = ref false - let set_verbose () = verbose := true - let verbose () = !verbose - -+(* ANSI terminal colours. *) -+let istty chan = -+ Unix.isatty (Unix.descr_of_out_channel chan) -+ -+let ansi_green ?(chan = stdout) () = -+ if colours () || istty chan then output_string chan "\x1b[0;32m" -+let ansi_red ?(chan = stdout) () = -+ if colours () || istty chan then output_string chan "\x1b[1;31m" -+let ansi_blue ?(chan = stdout) () = -+ if colours () || istty chan then output_string chan "\x1b[1;34m" -+let ansi_magenta ?(chan = stdout) () = -+ if colours () || istty chan then output_string chan "\x1b[1;35m" -+let ansi_restore ?(chan = stdout) () = -+ if colours () || istty chan then output_string chan "\x1b[0m" -+ - (* Timestamped progress messages, used for ordinary messages when not - * --quiet. - *) -@@ -596,6 +600,10 @@ let set_standard_options argspec = - "--debug-gc", Arg.Unit set_debug_gc, " " ^ s_"Debug GC and memory allocations (internal)"; - "-q", Arg.Unit set_quiet, " " ^ s_"Don't print progress messages"; - "--quiet", Arg.Unit set_quiet, " " ^ s_"Don't print progress messages"; -+ "--color", Arg.Unit set_colours, " " ^ s_"Use ANSI colour sequences even if not tty"; -+ "--colors", Arg.Unit set_colours, " " ^ s_"Use ANSI colour sequences even if not tty"; -+ "--colour", Arg.Unit set_colours, " " ^ s_"Use ANSI colour sequences even if not tty"; -+ "--colours", Arg.Unit set_colours, " " ^ s_"Use ANSI colour sequences even if not tty"; - ] @ argspec in - let argspec = - let cmp (arg1, _, _) (arg2, _, _) = compare_command_line_args arg1 arg2 in -diff --git a/resize/virt-resize.pod b/resize/virt-resize.pod -index a0ab459..2b2a485 100644 ---- a/resize/virt-resize.pod -+++ b/resize/virt-resize.pod -@@ -327,6 +327,15 @@ since around 2008. - - =back - -+=item B<--colors> -+ -+=item B<--colours> -+ -+Use ANSI colour sequences to colourize messages. This is the default -+when the output is a tty. If the output of the program is redirected -+to a file, ANSI colour sequences are disabled unless you use this -+option. -+ - =item B<-d> - - =item B<--debug> -diff --git a/sparsify/virt-sparsify.pod b/sparsify/virt-sparsify.pod -index b841251..44f7d4e 100644 ---- a/sparsify/virt-sparsify.pod -+++ b/sparsify/virt-sparsify.pod -@@ -155,6 +155,15 @@ B and exit. - - You cannot use this option and I<--in-place> together. - -+=item B<--colors> -+ -+=item B<--colours> -+ -+Use ANSI colour sequences to colourize messages. This is the default -+when the output is a tty. If the output of the program is redirected -+to a file, ANSI colour sequences are disabled unless you use this -+option. -+ - =item B<--compress> - - Compress the output file. This I works if the output format is -diff --git a/sysprep/virt-sysprep.pod b/sysprep/virt-sysprep.pod -index 44cf7f8..d671443 100644 ---- a/sysprep/virt-sysprep.pod -+++ b/sysprep/virt-sysprep.pod -@@ -59,6 +59,15 @@ force a particular format use the I<--format> option. - Add a remote disk. The URI format is compatible with guestfish. - See L. - -+=item B<--colors> -+ -+=item B<--colours> -+ -+Use ANSI colour sequences to colourize messages. This is the default -+when the output is a tty. If the output of the program is redirected -+to a file, ANSI colour sequences are disabled unless you use this -+option. -+ - =item B<-c> URI - - =item B<--connect> URI -diff --git a/v2v/cmdline.ml b/v2v/cmdline.ml -index 4623af9..b9992eb 100644 ---- a/v2v/cmdline.ml -+++ b/v2v/cmdline.ml -@@ -296,6 +296,7 @@ read the man page virt-v2v(1). - if args = [] && machine_readable then ( - printf "virt-v2v\n"; - printf "libguestfs-rewrite\n"; -+ printf "colours-option\n"; - List.iter (printf "input:%s\n") (Modules_list.input_modules ()); - List.iter (printf "output:%s\n") (Modules_list.output_modules ()); - List.iter (printf "convert:%s\n") (Modules_list.convert_modules ()); -diff --git a/v2v/virt-v2v.pod b/v2v/virt-v2v.pod -index 5800b34..93f0e77 100644 ---- a/v2v/virt-v2v.pod -+++ b/v2v/virt-v2v.pod -@@ -154,6 +154,15 @@ Display help. - - See I<--network> below. - -+=item B<--colors> -+ -+=item B<--colours> -+ -+Use ANSI colour sequences to colourize messages. This is the default -+when the output is a tty. If the output of the program is redirected -+to a file, ANSI colour sequences are disabled unless you use this -+option. -+ - =item B<--compressed> - - Write a compressed output file. This is only allowed if the output --- -1.8.3.1 - diff --git a/SOURCES/0112-p2v-Use-virt-v2v-colours-option-support-colour-in-th.patch b/SOURCES/0112-p2v-Use-virt-v2v-colours-option-support-colour-in-th.patch deleted file mode 100644 index 1520e88..0000000 --- a/SOURCES/0112-p2v-Use-virt-v2v-colours-option-support-colour-in-th.patch +++ /dev/null @@ -1,359 +0,0 @@ -From 16bd3feeb15684fa729012b419e9722904907bab Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Sat, 18 Jun 2016 10:40:09 +0100 -Subject: [PATCH] p2v: Use virt-v2v --colours option, support colour in the run - dialog (RHBZ#1314244). - -(cherry picked from commit 5e8f820494e70766a48fee38bc617c37b0c61a48) ---- - p2v/conversion.c | 5 +- - p2v/gui.c | 179 +++++++++++++++++++++++++++++++++++++++++++++---------- - p2v/main.c | 1 + - p2v/p2v.h | 3 + - p2v/ssh.c | 24 ++++++-- - 5 files changed, 172 insertions(+), 40 deletions(-) - -diff --git a/p2v/conversion.c b/p2v/conversion.c -index f221f84..5265a76 100644 ---- a/p2v/conversion.c -+++ b/p2v/conversion.c -@@ -320,9 +320,10 @@ start_conversion (struct config *config, - /* Build the virt-v2v command up in pieces to make the quoting - * slightly more sane. - */ -- if (mexp_printf (control_h, "( %s virt-v2v%s -i libvirtxml", -+ if (mexp_printf (control_h, "( %s virt-v2v%s%s -i libvirtxml", - config->sudo ? "sudo -n " : "", -- config->verbose ? " -v -x" : "") == -1) { -+ config->verbose ? " -v -x" : "", -+ feature_colours_option ? " --colours" : "") == -1) { - printf_fail: - set_conversion_error ("mexp_printf: virt-v2v command: %m"); - goto out; -diff --git a/p2v/gui.c b/p2v/gui.c -index 142d2eb..a3b4af9 100644 ---- a/p2v/gui.c -+++ b/p2v/gui.c -@@ -26,6 +26,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -71,6 +72,9 @@ static GtkWidget *run_dlg, - *v2v_output_sw, *v2v_output, *log_label, *status_label, - *cancel_button, *reboot_button; - -+/* Colour tags used in the v2v_output GtkTextBuffer. */ -+static GtkTextTag *v2v_output_tags[16]; -+ - /* The entry point from the main program. - * Note that gtk_init etc have already been called in main. - */ -@@ -1407,7 +1411,6 @@ get_memory_from_conv_dlg (void) - static void set_log_dir (const char *remote_dir); - static void set_status (const char *msg); - static void add_v2v_output (const char *msg); --static void add_v2v_output_2 (const char *msg, size_t len); - static void *start_conversion_thread (void *data); - static void cancel_conversion_dialog (GtkWidget *w, gpointer data); - static void reboot_clicked (GtkWidget *w, gpointer data); -@@ -1416,6 +1419,12 @@ static gboolean close_running_dialog (GtkWidget *w, GdkEvent *event, gpointer da - static void - create_running_dialog (void) - { -+ size_t i; -+ static const char *tags[16] = -+ { "black", "maroon", "green", "olive", "navy", "purple", "teal", "silver", -+ "gray", "red", "lime", "yellow", "blue", "fuchsia", "cyan", "white" }; -+ GtkTextBuffer *buf; -+ - run_dlg = gtk_dialog_new (); - gtk_window_set_title (GTK_WINDOW (run_dlg), guestfs_int_program_name); - gtk_window_set_resizable (GTK_WINDOW (run_dlg), FALSE); -@@ -1428,6 +1437,17 @@ create_running_dialog (void) - gtk_text_view_set_editable (GTK_TEXT_VIEW (v2v_output), FALSE); - gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (v2v_output), GTK_WRAP_CHAR); - gtk_widget_set_size_request (v2v_output, 700, 400); -+ -+ buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (v2v_output)); -+ for (i = 0; i < 16; ++i) { -+ CLEANUP_FREE char *tag_name; -+ -+ if (asprintf (&tag_name, "tag_%s", tags[i]) == -1) -+ error (EXIT_FAILURE, errno, "asprintf"); -+ v2v_output_tags[i] = -+ gtk_text_buffer_create_tag (buf, tag_name, "foreground", tags[i], NULL); -+ } -+ - log_label = gtk_label_new (NULL); - gtk_misc_set_alignment (GTK_MISC (log_label), 0., 0.5); - gtk_misc_set_padding (GTK_MISC (log_label), 10, 10); -@@ -1510,38 +1530,133 @@ set_status (const char *msg) - static void - add_v2v_output (const char *msg) - { -+ const char *p; - static size_t linelen = 0; -- const char *p0, *p; -- -- /* Gtk2 (in ~ Fedora 23) has a regression where it takes much -- * longer to display long lines, to the point where the virt-p2v -- * UI would still be slowly display kernel modules while the -- * conversion had finished. For this reason, arbitrarily break -- * long lines. -- */ -- for (p0 = p = msg; *p; ++p) { -- linelen++; -- if (*p == '\n' || linelen > 1024) { -- add_v2v_output_2 (p0, p-p0+1); -- if (*p != '\n') -- add_v2v_output_2 ("\n", 1); -- linelen = 0; -- p0 = p+1; -- } -- } -- add_v2v_output_2 (p0, p-p0); --} -- --static void --add_v2v_output_2 (const char *msg, size_t len) --{ -- GtkTextBuffer *buf; -- GtkTextIter iter; -- -- /* Insert it at the end. */ -- buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (v2v_output)); -- gtk_text_buffer_get_end_iter (buf, &iter); -- gtk_text_buffer_insert (buf, &iter, msg, len); -+ static enum { -+ state_normal, -+ state_escape1, /* seen ESC, expecting [ */ -+ state_escape2, /* seen ESC [, expecting 0 or 1 */ -+ state_escape3, /* seen ESC [ 0/1, expecting ; or m */ -+ state_escape4, /* seen ESC [ 0/1 ;, expecting 3 */ -+ state_escape5, /* seen ESC [ 0/1 ; 3, expecting 1/2/4/5 */ -+ state_escape6, /* seen ESC [ 0/1 ; 3 1/2/5/5, expecting m */ -+ state_cr, /* seen CR */ -+ state_truncating, /* truncating line until next \n */ -+ } state = state_normal; -+ static int colour = 0; -+ static GtkTextTag *tag = NULL; -+ GtkTextBuffer *buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (v2v_output)); -+ GtkTextIter iter, iter2; -+ const char *dots = " [...]"; -+ -+ for (p = msg; *p != '\0'; ++p) { -+ char c = *p; -+ -+ switch (state) { -+ case state_normal: -+ if (c == '\r') /* Start of possible CRLF sequence. */ -+ state = state_cr; -+ else if (c == '\x1b') { /* Start of an escape sequence. */ -+ state = state_escape1; -+ colour = 0; -+ } -+ else if (c != '\n' && linelen >= 256) { -+ /* Gtk2 (in ~ Fedora 23) has a regression where it takes much -+ * longer to display long lines, to the point where the -+ * virt-p2v UI would still be slowly displaying kernel modules -+ * while the conversion had finished. For this reason, -+ * arbitrarily truncate very long lines. -+ */ -+ gtk_text_buffer_get_end_iter (buf, &iter); -+ gtk_text_buffer_insert_with_tags (buf, &iter, -+ dots, strlen (dots), tag, NULL); -+ state = state_truncating; -+ colour = 0; -+ tag = NULL; -+ } -+ else { /* Treat everything else as a normal char. */ -+ if (c != '\n') linelen++; else linelen = 0; -+ gtk_text_buffer_get_end_iter (buf, &iter); -+ gtk_text_buffer_insert_with_tags (buf, &iter, &c, 1, tag, NULL); -+ } -+ break; -+ -+ case state_escape1: -+ if (c == '[') -+ state = state_escape2; -+ else -+ state = state_normal; -+ break; -+ -+ case state_escape2: -+ if (c == '0') -+ state = state_escape3; -+ else if (c == '1') { -+ state = state_escape3; -+ colour += 8; -+ } -+ else -+ state = state_normal; -+ break; -+ -+ case state_escape3: -+ if (c == ';') -+ state = state_escape4; -+ else if (c == 'm') { -+ tag = NULL; /* restore text colour */ -+ state = state_normal; -+ } -+ else -+ state = state_normal; -+ break; -+ -+ case state_escape4: -+ if (c == '3') -+ state = state_escape5; -+ else -+ state = state_normal; -+ break; -+ -+ case state_escape5: -+ if (c >= '0' && c <= '7') { -+ state = state_escape6; -+ colour += c - '0'; -+ } -+ else -+ state = state_normal; -+ break; -+ -+ case state_escape6: -+ if (c == 'm') { -+ assert (colour >= 0 && colour <= 15); -+ tag = v2v_output_tags[colour]; /* set colour tag */ -+ } -+ state = state_normal; -+ break; -+ -+ case state_cr: -+ if (c == '\n') -+ /* Process CRLF as single a newline character. */ -+ p--; -+ else { /* Delete current (== last) line. */ -+ linelen = 0; -+ gtk_text_buffer_get_end_iter (buf, &iter); -+ iter2 = iter; -+ gtk_text_iter_set_line_offset (&iter, 0); -+ /* Delete from iter..iter2 */ -+ gtk_text_buffer_delete (buf, &iter, &iter2); -+ } -+ state = state_normal; -+ break; -+ -+ case state_truncating: -+ if (c == '\n') { -+ p--; -+ state = state_normal; -+ } -+ break; -+ } /* switch (state) */ -+ } /* for */ - - /* Scroll to the end of the buffer. */ - gtk_text_buffer_get_end_iter (buf, &iter); -diff --git a/p2v/main.c b/p2v/main.c -index 99da3e4..99d0011 100644 ---- a/p2v/main.c -+++ b/p2v/main.c -@@ -42,6 +42,7 @@ char **all_disks; - char **all_removable; - char **all_interfaces; - int is_iso_environment = 0; -+int feature_colours_option = 0; - - static void udevadm_settle (void); - static void set_config_defaults (struct config *config); -diff --git a/p2v/p2v.h b/p2v/p2v.h -index 9ccaf0f..12dd210 100644 ---- a/p2v/p2v.h -+++ b/p2v/p2v.h -@@ -58,6 +58,9 @@ extern char **all_interfaces; - */ - extern int is_iso_environment; - -+/* True if virt-v2v supports the --colours option. */ -+extern int feature_colours_option; -+ - /* config.c */ - struct config { - int verbose; -diff --git a/p2v/ssh.c b/p2v/ssh.c -index d9210f3..266c236 100644 ---- a/p2v/ssh.c -+++ b/p2v/ssh.c -@@ -101,6 +101,7 @@ static pcre *ssh_message_re; - static pcre *prompt_re; - static pcre *version_re; - static pcre *feature_libguestfs_rewrite_re; -+static pcre *feature_colours_option_re; - static pcre *feature_input_re; - static pcre *feature_output_re; - static pcre *portfwd_re; -@@ -149,6 +150,7 @@ compile_regexps (void) - "virt-v2v ([1-9].*)", - 0); - COMPILE (feature_libguestfs_rewrite_re, "libguestfs-rewrite", 0); -+ COMPILE (feature_colours_option_re, "colours-option", 0); - COMPILE (feature_input_re, "input:((?:\\w)*)", 0); - COMPILE (feature_output_re, "output:((?:\\w)*)", 0); - COMPILE (portfwd_re, "Allocated port ((?:\\d)+) for remote forward", 0); -@@ -162,6 +164,7 @@ free_regexps (void) - pcre_free (prompt_re); - pcre_free (version_re); - pcre_free (feature_libguestfs_rewrite_re); -+ pcre_free (feature_colours_option_re); - pcre_free (feature_input_re); - pcre_free (feature_output_re); - pcre_free (portfwd_re); -@@ -613,28 +616,37 @@ test_connection (struct config *config) - switch (mexp_expect (h, - (mexp_regexp[]) { - { 100, .re = feature_libguestfs_rewrite_re }, -- { 101, .re = feature_input_re }, -- { 102, .re = feature_output_re }, -- { 103, .re = prompt_re }, -+ { 101, .re = feature_colours_option_re }, -+ { 102, .re = feature_input_re }, -+ { 103, .re = feature_output_re }, -+ { 104, .re = prompt_re }, - { 0 } - }, ovector, ovecsize)) { - case 100: /* libguestfs-rewrite. */ - feature_libguestfs_rewrite = 1; - break; - -- case 101: -+ case 101: /* virt-v2v supports --colours option */ -+#if DEBUG_STDERR -+ fprintf (stderr, "%s: remote virt-v2v supports --colours option\n", -+ guestfs_int_program_name); -+#endif -+ feature_colours_option = 1; -+ break; -+ -+ case 102: - /* input: corresponds to an -i option in virt-v2v. */ - add_input_driver (&h->buffer[ovector[2]], - (size_t) (ovector[3]-ovector[2])); - break; - -- case 102: -+ case 103: - /* output: corresponds to an -o option in virt-v2v. */ - add_output_driver (&h->buffer[ovector[2]], - (size_t) (ovector[3]-ovector[2])); - break; - -- case 103: /* Got prompt, so end of output. */ -+ case 104: /* Got prompt, so end of output. */ - goto end_of_machine_readable; - - case MEXP_EOF: --- -1.8.3.1 - diff --git a/SOURCES/0113-p2v-Use-a-wrapper-script-instead-of-long-virt-v2v-co.patch b/SOURCES/0113-p2v-Use-a-wrapper-script-instead-of-long-virt-v2v-co.patch deleted file mode 100644 index 416debf..0000000 --- a/SOURCES/0113-p2v-Use-a-wrapper-script-instead-of-long-virt-v2v-co.patch +++ /dev/null @@ -1,384 +0,0 @@ -From 11ef6d48abcfc90c0a6e795a067547c289e883d6 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Sat, 18 Jun 2016 14:44:24 +0100 -Subject: [PATCH] p2v: Use a wrapper script instead of long virt-v2v command - lne. - -Instead of constructing and directly executing a long virt-v2v command -line, build a wrapper script with the same command line and send it to -the remote server (stored in //virt-v2v-wrapper.sh). - -This will make it a bit easier to construct more complex virt-v2v -wrappers. - -Note this commit on its own is a simple refactoring and does not -change any functionality. - -(cherry picked from commit 514893b68b6180b3adc5bb762e9d67054a9a7f63) ---- - p2v/conversion.c | 203 +++++++++++++++++++++++++++++++++---------------------- - p2v/p2v.h | 2 +- - p2v/ssh.c | 25 ++++++- - p2v/virt-p2v.pod | 17 +++-- - 4 files changed, 159 insertions(+), 88 deletions(-) - -diff --git a/p2v/conversion.c b/p2v/conversion.c -index 5265a76..decaf7c 100644 ---- a/p2v/conversion.c -+++ b/p2v/conversion.c -@@ -27,6 +27,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -78,11 +79,11 @@ struct data_conn { - int nbd_remote_port; /* remote NBD port on conversion server */ - }; - --static int send_quoted (mexp_h *, const char *s); - static pid_t start_qemu_nbd (int nbd_local_port, const char *device); - static int wait_qemu_nbd (int nbd_local_port, int timeout_seconds); - static void cleanup_data_conns (struct data_conn *data_conns, size_t nr); - static char *generate_libvirt_xml (struct config *, struct data_conn *); -+static char *generate_wrapper_script (struct config *, const char *remote_dir); - static const char *map_interface_to_network (struct config *, const char *interface); - - static char *conversion_error; -@@ -168,7 +169,8 @@ start_conversion (struct config *config, - size_t i, len; - const size_t nr_disks = guestfs_int_count_strings (config->disks); - struct data_conn data_conns[nr_disks]; -- CLEANUP_FREE char *remote_dir = NULL, *libvirt_xml = NULL; -+ CLEANUP_FREE char *remote_dir = NULL, *libvirt_xml = NULL, -+ *wrapper_script = NULL; - time_t now; - struct tm tm; - mexp_h *control_h = NULL; -@@ -276,7 +278,18 @@ start_conversion (struct config *config, - goto out; - - #if DEBUG_STDERR -- fprintf (stderr, "%s: libvirt XML:\n%s", guestfs_int_program_name, libvirt_xml); -+ fprintf (stderr, "%s: libvirt XML:\n%s", -+ guestfs_int_program_name, libvirt_xml); -+#endif -+ -+ /* Generate the virt-v2v wrapper script. */ -+ wrapper_script = generate_wrapper_script (config, remote_dir); -+ if (wrapper_script == NULL) -+ goto out; -+ -+#if DEBUG_STDERR -+ fprintf (stderr, "%s: wrapper script:\n%s", -+ guestfs_int_program_name, wrapper_script); - #endif - - /* Get the output from the 'dmesg' command. We will store this -@@ -305,7 +318,9 @@ start_conversion (struct config *config, - if (notify_ui) - notify_ui (NOTIFY_STATUS, _("Setting up the control connection ...")); - -- control_h = start_remote_connection (config, remote_dir, libvirt_xml, dmesg); -+ control_h = start_remote_connection (config, -+ remote_dir, libvirt_xml, -+ wrapper_script, dmesg); - if (control_h == NULL) { - const char *err = get_ssh_error (); - -@@ -317,66 +332,18 @@ start_conversion (struct config *config, - if (notify_ui) - notify_ui (NOTIFY_STATUS, _("Doing conversion ...")); - -- /* Build the virt-v2v command up in pieces to make the quoting -- * slightly more sane. -- */ -- if (mexp_printf (control_h, "( %s virt-v2v%s%s -i libvirtxml", -- config->sudo ? "sudo -n " : "", -- config->verbose ? " -v -x" : "", -- feature_colours_option ? " --colours" : "") == -1) { -- printf_fail: -- set_conversion_error ("mexp_printf: virt-v2v command: %m"); -+ if (mexp_printf (control_h, -+ /* To simplify things in the wrapper script, it -+ * writes virt-v2v's exit status to -+ * /remote_dir/status, and here we read that and -+ * exit the ssh shell with the same status. -+ */ -+ "%s/virt-v2v-wrapper.sh; " -+ "exit $(< %s/status)\n", -+ remote_dir, remote_dir) == -1) { -+ set_conversion_error ("mexp_printf: virt-v2v: %m"); - goto out; - } -- if (config->output) { /* -o */ -- if (mexp_printf (control_h, " -o ") == -1) -- goto printf_fail; -- if (send_quoted (control_h, config->output) == -1) -- goto printf_fail; -- } -- switch (config->output_allocation) { /* -oa */ -- case OUTPUT_ALLOCATION_NONE: -- /* nothing */ -- break; -- case OUTPUT_ALLOCATION_SPARSE: -- if (mexp_printf (control_h, " -oa sparse") == -1) -- goto printf_fail; -- break; -- case OUTPUT_ALLOCATION_PREALLOCATED: -- if (mexp_printf (control_h, " -oa preallocated") == -1) -- goto printf_fail; -- break; -- default: -- abort (); -- } -- if (config->output_format) { /* -of */ -- if (mexp_printf (control_h, " -of ") == -1) -- goto printf_fail; -- if (send_quoted (control_h, config->output_format) == -1) -- goto printf_fail; -- } -- if (config->output_storage) { /* -os */ -- if (mexp_printf (control_h, " -os ") == -1) -- goto printf_fail; -- if (send_quoted (control_h, config->output_storage) == -1) -- goto printf_fail; -- } -- if (mexp_printf (control_h, " --root first") == -1) -- goto printf_fail; -- if (mexp_printf (control_h, " %s/physical.xml", remote_dir) == -1) -- goto printf_fail; -- /* no stdin, and send stdout and stderr to the same place */ -- if (mexp_printf (control_h, " &1") == -1) -- goto printf_fail; -- if (mexp_printf (control_h, " ; echo $? > %s/status", remote_dir) == -1) -- goto printf_fail; -- if (mexp_printf (control_h, " ) | tee %s/virt-v2v-conversion-log.txt", -- remote_dir) == -1) -- goto printf_fail; -- if (mexp_printf (control_h, "; exit $(< %s/status)", remote_dir) == -1) -- goto printf_fail; -- if (mexp_printf (control_h, "\n") == -1) -- goto printf_fail; - - /* Read output from the virt-v2v process and echo it through the - * notify function, until virt-v2v closes the connection. -@@ -443,26 +410,6 @@ cancel_conversion (void) - set_cancel_requested (1); - } - --/* Send a shell-quoted string to remote. */ --static int --send_quoted (mexp_h *h, const char *s) --{ -- if (mexp_printf (h, "\"") == -1) -- return -1; -- while (*s) { -- if (*s == '$' || *s == '`' || *s == '\\' || *s == '"') { -- if (mexp_printf (h, "\\") == -1) -- return -1; -- } -- if (mexp_printf (h, "%c", *s) == -1) -- return -1; -- ++s; -- } -- if (mexp_printf (h, "\"") == -1) -- return -1; -- return 0; --} -- - /* Note: returns process ID (> 0) or 0 if there is an error. */ - static pid_t - start_qemu_nbd (int port, const char *device) -@@ -980,3 +927,95 @@ map_interface_to_network (struct config *config, const char *interface) - /* No mapping found. */ - return "default"; - } -+ -+/** -+ * Print a shell-quoted string on C. -+ */ -+static void -+print_quoted (FILE *fp, const char *s) -+{ -+ fprintf (fp, "\""); -+ while (*s) { -+ if (*s == '$' || *s == '`' || *s == '\\' || *s == '"') -+ fprintf (fp, "\\"); -+ fprintf (fp, "%c", *s); -+ ++s; -+ } -+ fprintf (fp, "\""); -+} -+ -+/** -+ * Construct the virt-v2v wrapper script. -+ * -+ * This will be sent to the remote server, and is easier than trying -+ * to "type" a long and complex single command line into the ssh -+ * connection when we start the conversion. -+ */ -+static char * -+generate_wrapper_script (struct config *config, const char *remote_dir) -+{ -+ FILE *fp; -+ char *output = NULL; -+ size_t output_len = 0; -+ -+ fp = open_memstream (&output, &output_len); -+ if (fp == NULL) -+ error (EXIT_FAILURE, errno, "open_memstream"); -+ -+ fprintf (fp, "#!/bin/sh -\n"); -+ fprintf (fp, "\n"); -+ -+ /* The virt-v2v command. */ -+ fprintf (fp, "(\n"); -+ if (config->sudo) -+ fprintf (fp, "sudo -n "); -+ fprintf (fp, "virt-v2v"); -+ if (config->verbose) -+ fprintf (fp, " -v -x"); -+ if (feature_colours_option) -+ fprintf (fp, " --colours"); -+ fprintf (fp, " -i libvirtxml"); -+ -+ if (config->output) { /* -o */ -+ fprintf (fp, " -o "); -+ print_quoted (fp, config->output); -+ } -+ -+ switch (config->output_allocation) { /* -oa */ -+ case OUTPUT_ALLOCATION_NONE: -+ /* nothing */ -+ break; -+ case OUTPUT_ALLOCATION_SPARSE: -+ fprintf (fp, " -oa sparse"); -+ break; -+ case OUTPUT_ALLOCATION_PREALLOCATED: -+ fprintf (fp, " -oa preallocated"); -+ break; -+ default: -+ abort (); -+ } -+ -+ if (config->output_format) { /* -of */ -+ fprintf (fp, " -of "); -+ print_quoted (fp, config->output_format); -+ } -+ -+ if (config->output_storage) { /* -os */ -+ fprintf (fp, " -os "); -+ print_quoted (fp, config->output_storage); -+ } -+ -+ fprintf (fp, " --root first"); -+ fprintf (fp, " %s/physical.xml", remote_dir); -+ /* no stdin, and send stdout and stderr to the same place */ -+ fprintf (fp, " &1"); -+ fprintf (fp, "\n"); -+ fprintf (fp, "echo $? > %s/status", remote_dir); -+ fprintf (fp, "\n"); -+ fprintf (fp, " ) | tee %s/virt-v2v-conversion-log.txt", remote_dir); -+ fprintf (fp, "\n"); -+ -+ fclose (fp); -+ -+ return output; /* caller frees */ -+} -diff --git a/p2v/p2v.h b/p2v/p2v.h -index 12dd210..49c97b6 100644 ---- a/p2v/p2v.h -+++ b/p2v/p2v.h -@@ -127,7 +127,7 @@ extern int conversion_is_running (void); - /* ssh.c */ - extern int test_connection (struct config *); - extern mexp_h *open_data_connection (struct config *, int *local_port, int *remote_port); --extern mexp_h *start_remote_connection (struct config *, const char *remote_dir, const char *libvirt_xml, const char *dmesg); -+extern mexp_h *start_remote_connection (struct config *, const char *remote_dir, const char *libvirt_xml, const char *wrapper_script, const char *dmesg); - extern const char *get_ssh_error (void); - - /* utils.c */ -diff --git a/p2v/ssh.c b/p2v/ssh.c -index 266c236..a8c762d 100644 ---- a/p2v/ssh.c -+++ b/p2v/ssh.c -@@ -904,7 +904,7 @@ wait_for_prompt (mexp_h *h) - mexp_h * - start_remote_connection (struct config *config, - const char *remote_dir, const char *libvirt_xml, -- const char *dmesg) -+ const char *wrapper_script, const char *dmesg) - { - mexp_h *h; - char magic[9]; -@@ -960,6 +960,29 @@ start_remote_connection (struct config *config, - if (wait_for_prompt (h) == -1) - goto error; - -+ /* Upload the wrapper script to the remote directory. */ -+ if (mexp_printf (h, -+ "cat > '%s/virt-v2v-wrapper.sh' << '__%s__'\n" -+ "%s" -+ "__%s__\n", -+ remote_dir, magic, -+ wrapper_script, -+ magic) == -1) { -+ set_ssh_error ("mexp_printf: %m"); -+ goto error; -+ } -+ -+ if (wait_for_prompt (h) == -1) -+ goto error; -+ -+ if (mexp_printf (h, "chmod +x %s/virt-v2v-wrapper.sh\n", remote_dir) == -1) { -+ set_ssh_error ("mexp_printf: %m"); -+ goto error; -+ } -+ -+ if (wait_for_prompt (h) == -1) -+ goto error; -+ - if (dmesg != NULL) { - /* Upload the physical host dmesg to the remote directory. */ - if (mexp_printf (h, -diff --git a/p2v/virt-p2v.pod b/p2v/virt-p2v.pod -index 5ceafa7..0c233c5 100644 ---- a/p2v/virt-p2v.pod -+++ b/p2v/virt-p2v.pod -@@ -693,6 +693,13 @@ on the conversion server. If conversion fails, you should examine - this log file, and you may be asked to supply the B, - B log file in any bug reports or support tickets. - -+=item F -+ -+I<(during/after conversion)> -+ -+This is the wrapper script which is used when running virt-v2v. For -+interest only, do not attempt to run this script yourself. -+ - =back - - Before conversion actually begins, virt-p2v then makes one or more -@@ -729,10 +736,12 @@ used. Secondly libguestfs creates an overlay on top of the NBD - connection which stores writes in a temporary file on the conversion - file. - --The final step is to send the S> --command to the conversion server over the control connection. This --references the F file (see above), which in turn --references the NBD listening port(s) of the data connection(s). -+The long S> command is -+wrapped inside a wrapper script and uploaded to the conversion server. -+The final step is to run this wrapper script, in turn running the -+virt-v2v command. The virt-v2v command references the F -+file (see above), which in turn references the NBD listening port(s) -+of the data connection(s). - - Output from the virt-v2v command (messages, debugging etc) is saved - both in the log file on the conversion server, and sent over the --- -1.8.3.1 - diff --git a/SOURCES/0114-p2v-Don-t-display-debugging-messages-in-the-run-dial.patch b/SOURCES/0114-p2v-Don-t-display-debugging-messages-in-the-run-dial.patch deleted file mode 100644 index e7cc555..0000000 --- a/SOURCES/0114-p2v-Don-t-display-debugging-messages-in-the-run-dial.patch +++ /dev/null @@ -1,121 +0,0 @@ -From 60edfe4cb0126a27de8c7f264dde6eaa49135436 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Sat, 18 Jun 2016 15:12:08 +0100 -Subject: [PATCH] p2v: Don't display debugging messages in the run dialog. - -Previously we displayed the complete output of virt-v2v in the run -dialog. This output included all the debugging messages, and was very -long and confusing for users (especially we had false bug reports -about "errors" appearing in the debug output). - -Only display stdout in the run dialog. However make sure everything -(stdout and stderr) is still logged to the conversion log. - -(cherry picked from commit 7447fe2478e49f5121a40db973f8a1fb1daaec53) ---- - p2v/conversion.c | 50 ++++++++++++++++++++++++++++++++++++++++++-------- - p2v/virt-p2v.pod | 7 ++++--- - 2 files changed, 46 insertions(+), 11 deletions(-) - -diff --git a/p2v/conversion.c b/p2v/conversion.c -index decaf7c..a7d1f11 100644 ---- a/p2v/conversion.c -+++ b/p2v/conversion.c -@@ -962,11 +962,15 @@ generate_wrapper_script (struct config *config, const char *remote_dir) - if (fp == NULL) - error (EXIT_FAILURE, errno, "open_memstream"); - -- fprintf (fp, "#!/bin/sh -\n"); -+ fprintf (fp, "#!/bin/bash -\n"); - fprintf (fp, "\n"); - -- /* The virt-v2v command. */ -- fprintf (fp, "(\n"); -+ fprintf (fp, "cd %s\n", remote_dir); -+ fprintf (fp, "\n"); -+ -+ /* The virt-v2v command, as a shell function called "v2v". */ -+ fprintf (fp, "v2v ()\n"); -+ fprintf (fp, "{\n"); - if (config->sudo) - fprintf (fp, "sudo -n "); - fprintf (fp, "virt-v2v"); -@@ -1006,15 +1010,45 @@ generate_wrapper_script (struct config *config, const char *remote_dir) - } - - fprintf (fp, " --root first"); -- fprintf (fp, " %s/physical.xml", remote_dir); -- /* no stdin, and send stdout and stderr to the same place */ -- fprintf (fp, " &1"); -+ fprintf (fp, " physical.xml"); -+ fprintf (fp, " %s/status", remote_dir); -+ fprintf (fp, -+ "# Save the exit code of virt-v2v into the 'status' file.\n"); -+ fprintf (fp, "echo $? > status\n"); -+ fprintf (fp, "}\n"); - fprintf (fp, "\n"); -- fprintf (fp, " ) | tee %s/virt-v2v-conversion-log.txt", remote_dir); -+ -+ fprintf (fp, -+ "# Write a pre-emptive error status, in case the virt-v2v\n" -+ "# command doesn't get to run at all. This will be\n" -+ "# overwritten with the true exit code when virt-v2v runs.\n"); -+ fprintf (fp, "echo 99 > status\n"); - fprintf (fp, "\n"); - -+ fprintf (fp, "log=virt-v2v-conversion-log.txt\n"); -+ fprintf (fp, "rm -f $log\n"); -+ fprintf (fp, "\n"); -+ -+ fprintf (fp, -+ "# Run virt-v2v. Send stdout back to virt-p2v. Send stdout\n" -+ "# and stderr (debugging info) to the log file.\n"); -+ fprintf (fp, "v2v 2>> $log | tee -a $log\n"); -+ fprintf (fp, "\n"); -+ -+ fprintf (fp, -+ "# If virt-v2v failed then the error message (sent to stderr)\n" -+ "# will not be seen in virt-p2v. Send the last few lines of\n" -+ "# the log back to virt-p2v in this case.\n"); -+ fprintf (fp, -+ "if [ \"$(< status)\" -ne 0 ]; then\n" -+ " echo\n" -+ " echo\n" -+ " echo\n" -+ " echo '*** virt-v2v command failed ***'\n" -+ " tail -30 $log\n" -+ "fi\n"); -+ - fclose (fp); - - return output; /* caller frees */ -diff --git a/p2v/virt-p2v.pod b/p2v/virt-p2v.pod -index 0c233c5..b996541 100644 ---- a/p2v/virt-p2v.pod -+++ b/p2v/virt-p2v.pod -@@ -267,7 +267,7 @@ When conversion is running you will see this dialog: - │ │ - └────────────────────────────────────────────────────────┘ - --In the main scrolling area you will see log messages from the virt-v2v -+In the main scrolling area you will see messages from the virt-v2v - process. - - Below the main area, virt-p2v shows you the location of the directory -@@ -744,8 +744,9 @@ file (see above), which in turn references the NBD listening port(s) - of the data connection(s). - - Output from the virt-v2v command (messages, debugging etc) is saved --both in the log file on the conversion server, and sent over the --control connection to be displayed in the graphical UI. -+both in the log file on the conversion server. Only informational -+messages are sent back over the control connection to be displayed in -+the graphical UI. - - =head1 SEE ALSO - --- -1.8.3.1 - diff --git a/SOURCES/0115-p2v-Use-a-monospace-font-for-the-run-dialog.patch b/SOURCES/0115-p2v-Use-a-monospace-font-for-the-run-dialog.patch deleted file mode 100644 index 462a626..0000000 --- a/SOURCES/0115-p2v-Use-a-monospace-font-for-the-run-dialog.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 5239a0d260109d33d1e436bc63fee4b6e58c44c8 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Sat, 18 Jun 2016 15:31:34 +0100 -Subject: [PATCH] p2v: Use a monospace font for the run dialog. - -(cherry picked from commit ca6fea7616f89775180ab686133052eca18f0e00) ---- - p2v/gui.c | 14 ++++++++++++++ - 1 file changed, 14 insertions(+) - -diff --git a/p2v/gui.c b/p2v/gui.c -index a3b4af9..764b0f8 100644 ---- a/p2v/gui.c -+++ b/p2v/gui.c -@@ -1448,6 +1448,20 @@ create_running_dialog (void) - gtk_text_buffer_create_tag (buf, tag_name, "foreground", tags[i], NULL); - } - -+#if GTK_CHECK_VERSION(3,16,0) /* gtk >= 3.16 */ -+ /* XXX This only sets the "CSS" style. It's not clear how to set -+ * the particular font. However (by accident) this does at least -+ * set the widget to use a monospace font. -+ */ -+ GtkStyleContext *context = gtk_widget_get_style_context (v2v_output); -+ gtk_style_context_add_class (context, "monospace"); -+#else -+ PangoFontDescription *font; -+ font = pango_font_description_from_string ("Monospace 11"); -+ gtk_widget_modify_font (v2v_output, font); -+ pango_font_description_free (font); -+#endif -+ - log_label = gtk_label_new (NULL); - gtk_misc_set_alignment (GTK_MISC (log_label), 0., 0.5); - gtk_misc_set_padding (GTK_MISC (log_label), 10, 10); --- -1.8.3.1 - diff --git a/SOURCES/0116-p2v-Display-up-to-50-lines-of-the-virt-v2v-conversio.patch b/SOURCES/0116-p2v-Display-up-to-50-lines-of-the-virt-v2v-conversio.patch deleted file mode 100644 index 6c68815..0000000 --- a/SOURCES/0116-p2v-Display-up-to-50-lines-of-the-virt-v2v-conversio.patch +++ /dev/null @@ -1,57 +0,0 @@ -From d1f7ebc29a819c4ff1156169fa3a04efa7046685 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Mon, 20 Jun 2016 09:56:48 +0100 -Subject: [PATCH] p2v: Display up to 50 lines of the virt-v2v conversion log on - failure. - -For some failures, 30 lines was not sufficient and only part of the -error was shown. Increase the number of lines shown to 50. - -This also colourizes the failure message, and prominently displays the -location of the full log. The following message is now shown: - - *** virt-v2v command failed *** - - The full log is available on the conversion server in: - /tmp/virt-p2v-20160620-sga9rhk7/virt-v2v-conversion-log.txt - Only the last 50 lines are shown below. - - [followed by up to 50 lines of log] - -Updates and fixes commit 7447fe2478e49f5121a40db973f8a1fb1daaec53. - -(cherry picked from commit 6f5abc9539a4d47c98898b4c491d6b017d9abbbb) ---- - p2v/conversion.c | 16 +++++++++++++--- - 1 file changed, 13 insertions(+), 3 deletions(-) - -diff --git a/p2v/conversion.c b/p2v/conversion.c -index a7d1f11..fe18b4a 100644 ---- a/p2v/conversion.c -+++ b/p2v/conversion.c -@@ -1045,9 +1045,19 @@ generate_wrapper_script (struct config *config, const char *remote_dir) - " echo\n" - " echo\n" - " echo\n" -- " echo '*** virt-v2v command failed ***'\n" -- " tail -30 $log\n" -- "fi\n"); -+ " echo -ne '\\e[1;31m'\n" -+ " echo '***' virt-v2v command failed '***'\n" -+ " echo\n" -+ " echo The full log is available on the conversion server in:\n" -+ " echo ' ' %s/$log\n" -+ " echo Only the last 50 lines are shown below.\n" -+ " echo -ne '\\e[0m'\n" -+ " echo\n" -+ " echo\n" -+ " echo\n" -+ " tail -50 $log\n" -+ "fi\n", -+ remote_dir); - - fclose (fp); - --- -1.8.3.1 - diff --git a/SOURCES/0117-p2v-Don-t-display-libvirt-XML-and-wrapper-script-on-.patch b/SOURCES/0117-p2v-Don-t-display-libvirt-XML-and-wrapper-script-on-.patch deleted file mode 100644 index 7cf280a..0000000 --- a/SOURCES/0117-p2v-Don-t-display-libvirt-XML-and-wrapper-script-on-.patch +++ /dev/null @@ -1,38 +0,0 @@ -From c29e8831ed1414ff57811921afe323f223743f8b Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Mon, 20 Jun 2016 10:02:11 +0100 -Subject: [PATCH] p2v: Don't display libvirt XML and wrapper script on stderr. - -Confusing for end users, and not necessary for debugging since those -files are saved on the conversion server. - -(cherry picked from commit 55a0ab845d570c781d321b09213aa43a709e91cd) ---- - p2v/conversion.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/p2v/conversion.c b/p2v/conversion.c -index fe18b4a..b54f971 100644 ---- a/p2v/conversion.c -+++ b/p2v/conversion.c -@@ -277,7 +277,7 @@ start_conversion (struct config *config, - if (libvirt_xml == NULL) - goto out; - --#if DEBUG_STDERR -+#if DEBUG_STDERR && 0 - fprintf (stderr, "%s: libvirt XML:\n%s", - guestfs_int_program_name, libvirt_xml); - #endif -@@ -287,7 +287,7 @@ start_conversion (struct config *config, - if (wrapper_script == NULL) - goto out; - --#if DEBUG_STDERR -+#if DEBUG_STDERR && 0 - fprintf (stderr, "%s: wrapper script:\n%s", - guestfs_int_program_name, wrapper_script); - #endif --- -1.8.3.1 - diff --git a/SOURCES/0118-p2v-Poll-to-make-Cancel-Conversion-button-more-respo.patch b/SOURCES/0118-p2v-Poll-to-make-Cancel-Conversion-button-more-respo.patch deleted file mode 100644 index f6b2c00..0000000 --- a/SOURCES/0118-p2v-Poll-to-make-Cancel-Conversion-button-more-respo.patch +++ /dev/null @@ -1,72 +0,0 @@ -From a5806c1b4be3f74b25ec733328259e7966af6af6 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Mon, 20 Jun 2016 10:18:22 +0100 -Subject: [PATCH] p2v: Poll to make Cancel Conversion button more responsive. - -Previously cancelling the conversion only set a flag, which was -checked when the run dialog displayed new output from virt-v2v. When -virt-v2v was showing hundreds of debugging messages, this wasn't a -problem, but now that we are hiding those messages, cancelling the -conversion might mean a wait of seconds or minutes. - -By polling (albeit infrequently) we can make the cancel button more -responsive. - -(cherry picked from commit 6da4941db7f8a85997d6281b9b4c5165768e6489) ---- - p2v/conversion.c | 27 +++++++++++++++++++++++++-- - 1 file changed, 25 insertions(+), 2 deletions(-) - -diff --git a/p2v/conversion.c b/p2v/conversion.c -index b54f971..de2a4b2 100644 ---- a/p2v/conversion.c -+++ b/p2v/conversion.c -@@ -25,6 +25,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -346,13 +347,35 @@ start_conversion (struct config *config, - } - - /* Read output from the virt-v2v process and echo it through the -- * notify function, until virt-v2v closes the connection. -+ * notify function, until virt-v2v closes the connection. We -+ * actually poll in this loop (albeit it only every 2 seconds) so -+ * that the user won't have to wait too long between pressing the -+ * cancel button and having the conversion cancelled. - */ - while (!is_cancel_requested ()) { -+ int fd = mexp_get_fd (control_h); -+ struct pollfd fds[1]; -+ int rp; - char buf[257]; - ssize_t r; - -- r = read (mexp_get_fd (control_h), buf, sizeof buf - 1); -+ fds[0].fd = fd; -+ fds[0].events = POLLIN; -+ fds[0].revents = 0; -+ rp = poll (fds, 1, 2000 /* ms */); -+ if (rp == -1) { -+ /* See comment about this in miniexpect.c. */ -+ if (errno == EIO) -+ break; -+ set_conversion_error ("poll: %m"); -+ goto out; -+ } -+ else if (rp == 0) -+ /* Timeout. */ -+ continue; -+ /* ... else rp == 1, ignore revents and just do the read. */ -+ -+ r = read (fd, buf, sizeof buf - 1); - if (r == -1) { - /* See comment about this in miniexpect.c. */ - if (errno == EIO) --- -1.8.3.1 - diff --git a/SOURCES/0119-p2v-Gtk-3-workaround-for-RHEL-7.patch b/SOURCES/0119-p2v-Gtk-3-workaround-for-RHEL-7.patch deleted file mode 100644 index 9acd3c4..0000000 --- a/SOURCES/0119-p2v-Gtk-3-workaround-for-RHEL-7.patch +++ /dev/null @@ -1,34 +0,0 @@ -From eebe36dcdd8343b38c4b8d0327fd09413981a7dd Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Tue, 21 Jun 2016 14:11:57 +0100 -Subject: [PATCH] p2v: Gtk 3 workaround for RHEL 7. - -New enough to complain about gtk_widget_modify_font, not new enough to -have gtk_style_context. - -Fixes commit ca6fea7616f89775180ab686133052eca18f0e00. - -(cherry picked from commit c87eab35c0b206306f98a2a267e299be32a9e5f2) ---- - p2v/gui.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/p2v/gui.c b/p2v/gui.c -index 764b0f8..7414037 100644 ---- a/p2v/gui.c -+++ b/p2v/gui.c -@@ -1458,7 +1458,11 @@ create_running_dialog (void) - #else - PangoFontDescription *font; - font = pango_font_description_from_string ("Monospace 11"); -+#if GTK_CHECK_VERSION(3,0,0) /* gtk >= 3 */ -+ gtk_widget_override_font (v2v_output, font); -+#else - gtk_widget_modify_font (v2v_output, font); -+#endif - pango_font_description_free (font); - #endif - --- -1.8.3.1 - diff --git a/SOURCES/0120-RHEL-7-v2v-Remove-dcpath-option-from-manual-page-RHB.patch b/SOURCES/0120-RHEL-7-v2v-Remove-dcpath-option-from-manual-page-RHB.patch deleted file mode 100644 index 32ece16..0000000 --- a/SOURCES/0120-RHEL-7-v2v-Remove-dcpath-option-from-manual-page-RHB.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 6842d01281169683b6654c7629e21b5acf57ff6d Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Thu, 23 Jun 2016 10:38:47 -0400 -Subject: [PATCH] RHEL 7: v2v: Remove --dcpath option from manual page - (RHBZ#1315237). - -This is no longer required, since RHEL 7.3. ---- - v2v/virt-v2v.pod | 13 ------------- - 1 file changed, 13 deletions(-) - -diff --git a/v2v/virt-v2v.pod b/v2v/virt-v2v.pod -index 93f0e77..4ea02ab 100644 ---- a/v2v/virt-v2v.pod -+++ b/v2v/virt-v2v.pod -@@ -169,19 +169,6 @@ Write a compressed output file. This is only allowed if the output - format is qcow2 (see I<-of> below), and is equivalent to the I<-c> - option of L. - --=item B<--dcpath> Folder/Datacenter -- --B You don't need to use this parameter if you have --S 1.2.20>. -- --For VMware vCenter, override the C parameter used to --select the datacenter. Virt-v2v can usually calculate this from the --C URI, but if it gets it wrong, then you can override it using --this setting. Go to your vCenter web folder interface, eg. --C (I a trailing slash), --and examine the C parameter in the URLs that appear on this --page. -- - =item B<--debug-gc> - - Debug garbage collection and memory allocation. This is only useful --- -1.8.3.1 - diff --git a/SOURCES/0121-v2v-Fix-conversion-of-floppy-removable-devices-RHBZ-.patch b/SOURCES/0121-v2v-Fix-conversion-of-floppy-removable-devices-RHBZ-.patch deleted file mode 100644 index a6503fa..0000000 --- a/SOURCES/0121-v2v-Fix-conversion-of-floppy-removable-devices-RHBZ-.patch +++ /dev/null @@ -1,203 +0,0 @@ -From 8bd7c9c0d10699757e4edd6d3b5b9ae8667fb4a4 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Wed, 22 Jun 2016 15:04:26 +0100 -Subject: [PATCH] v2v: Fix conversion of floppy removable devices - (RHBZ#1309706). - -The previous code treated floppy disks and CD-ROMs as the same kind of -thing, resulting in malformed libvirt XML. You would see the -following error when importing a guest into libvirt: - - error: Failed to define domain from /tmp/v2vlibvirt063486.xml - error: internal error: Invalid floppy device name: hdb - -because we incorrectly generated this bogus libvirt XML fragment: - - - - - - -This commit models floppy devices as a distinct type, occupying their -own bus ("/dev/fdX"). When writing to libvirt, we generate correct -XML fragments, looking like this: - - - - - - -Miscellaneous other changes were required in the code. There is also -a regression test (see following commit). - -Note this ignores floppy disks in '-o qemu' mode. - -(cherry picked from commit b9613acb94e3328204d96efab0dfc8b8ed1d3368) ---- - v2v/input_libvirtxml.ml | 1 + - v2v/output_libvirt.ml | 6 ++++-- - v2v/output_qemu.ml | 4 ++++ - v2v/target_bus_assignment.ml | 20 ++++++++++++-------- - v2v/test-v2v-i-ova.xml | 2 +- - v2v/types.ml | 1 + - v2v/types.mli | 10 +++++++--- - 7 files changed, 30 insertions(+), 14 deletions(-) - -diff --git a/v2v/input_libvirtxml.ml b/v2v/input_libvirtxml.ml -index 1202302..a547edd 100644 ---- a/v2v/input_libvirtxml.ml -+++ b/v2v/input_libvirtxml.ml -@@ -297,6 +297,7 @@ let parse_libvirt_xml ?conn xml = - | Some s when String.is_prefix s "sd" -> get_drive_slot s 2 - | Some s when String.is_prefix s "vd" -> get_drive_slot s 2 - | Some s when String.is_prefix s "xvd" -> get_drive_slot s 3 -+ | Some s when String.is_prefix s "fd" -> get_drive_slot s 2 - | Some s -> - warning (f_" was ignored because the device name could not be recognized") s; - None in -diff --git a/v2v/output_libvirt.ml b/v2v/output_libvirt.ml -index 05ad931..5a404ee 100644 ---- a/v2v/output_libvirt.ml -+++ b/v2v/output_libvirt.ml -@@ -173,7 +173,6 @@ let create_libvirt_xml ?pool source target_buses guestcaps - e "driver" [ "name", "qemu"; "type", "raw" ] []; - e "target" [ - "dev", drive_prefix ^ drive_name i; -- "bus", bus_name - ] [] - ] - in -@@ -187,7 +186,10 @@ let create_libvirt_xml ?pool source target_buses guestcaps - target_buses.target_ide_bus); - Array.to_list - (Array.mapi (make_disk "scsi" "sd") -- target_buses.target_scsi_bus) -+ target_buses.target_scsi_bus); -+ Array.to_list -+ (Array.mapi (make_disk "floppy" "fd") -+ target_buses.target_floppy_bus) - ] in - append devices disks; - -diff --git a/v2v/output_qemu.ml b/v2v/output_qemu.ml -index d079ccd..94f80c2 100644 ---- a/v2v/output_qemu.ml -+++ b/v2v/output_qemu.ml -@@ -137,6 +137,10 @@ object - in - Array.iteri make_scsi target_buses.target_scsi_bus; - -+ (* XXX Highly unlikely that anyone cares, but the current -+ * code ignores target_buses.target_floppy_bus. -+ *) -+ - let net_bus = - match guestcaps.gcaps_net_bus with - | Virtio_net -> "virtio-net-pci" -diff --git a/v2v/target_bus_assignment.ml b/v2v/target_bus_assignment.ml -index 5ad8582..bce3a88 100644 ---- a/v2v/target_bus_assignment.ml -+++ b/v2v/target_bus_assignment.ml -@@ -21,11 +21,11 @@ open Common_gettext.Gettext - - open Types - --(* XXX This doesn't do the right thing for PC legacy floppy devices. *) - let rec target_bus_assignment source targets guestcaps = - let virtio_blk_bus = ref [| |] - and ide_bus = ref [| |] -- and scsi_bus = ref [| |] in -+ and scsi_bus = ref [| |] -+ and floppy_bus = ref [| |] in - - (* Add the fixed disks (targets) to either the virtio-blk or IDE bus, - * depending on whether the guest has virtio drivers or not. -@@ -65,11 +65,14 @@ let rec target_bus_assignment source targets guestcaps = - fun r -> - let t = BusSlotRemovable r in - let bus = -- match r.s_removable_controller with -- | None -> ide_bus (* Wild guess, but should be safe. *) -- | Some Source_virtio_blk -> virtio_blk_bus -- | Some Source_IDE -> ide_bus -- | Some Source_SCSI -> scsi_bus in -+ match r.s_removable_type with -+ | Floppy -> floppy_bus -+ | CDROM -> -+ match r.s_removable_controller with -+ | None -> ide_bus (* Wild guess, but should be safe. *) -+ | Some Source_virtio_blk -> virtio_blk_bus -+ | Some Source_IDE -> ide_bus -+ | Some Source_SCSI -> scsi_bus in - - match r.s_removable_slot with - | None -> -@@ -88,7 +91,8 @@ let rec target_bus_assignment source targets guestcaps = - - { target_virtio_blk_bus = !virtio_blk_bus; - target_ide_bus = !ide_bus; -- target_scsi_bus = !scsi_bus } -+ target_scsi_bus = !scsi_bus; -+ target_floppy_bus = !floppy_bus } - - (* Insert a slot into the bus array, making the array bigger if necessary. *) - and insert bus i slot = -diff --git a/v2v/test-v2v-i-ova.xml b/v2v/test-v2v-i-ova.xml -index bb765e3..6dcfc31 100644 ---- a/v2v/test-v2v-i-ova.xml -+++ b/v2v/test-v2v-i-ova.xml -@@ -27,7 +27,7 @@ - - - -- -+ - - - -diff --git a/v2v/types.ml b/v2v/types.ml -index d082594..7491be4 100644 ---- a/v2v/types.ml -+++ b/v2v/types.ml -@@ -363,6 +363,7 @@ type target_buses = { - target_virtio_blk_bus : target_bus_slot array; - target_ide_bus : target_bus_slot array; - target_scsi_bus : target_bus_slot array; -+ target_floppy_bus : target_bus_slot array; - } - - and target_bus_slot = -diff --git a/v2v/types.mli b/v2v/types.mli -index 18ac138..c1cb245 100644 ---- a/v2v/types.mli -+++ b/v2v/types.mli -@@ -254,10 +254,11 @@ type target_buses = { - target_virtio_blk_bus : target_bus_slot array; - target_ide_bus : target_bus_slot array; - target_scsi_bus : target_bus_slot array; -+ target_floppy_bus : target_bus_slot array; - } - (** Mapping of fixed and removable disks to buses. - -- As shown in the diagram below, there are (currently) three buses -+ As shown in the diagram below, there are (currently) four buses - attached to the target VM. Each contains a chain of fixed or - removable disks. Slots can also be empty. - -@@ -276,8 +277,11 @@ type target_buses = { - ├────┤ hda ├───┤ hdb ├───┤ hdc ├───┤ hdd │ IDE bus - │ └─────┘ └─────┘ └─────┘ └─────┘ - │ ┌─────┐ ┌─────┐ -- └────┤ - ├───┤ vdb │ Virtio-blk bus -- └─────┘ └─────┘ -+ ├────┤ - ├───┤ vdb │ Virtio-blk bus -+ │ └─────┘ └─────┘ -+ │ ┌─────┐ -+ └────┤ fda │ Floppy disks -+ └─────┘ - v} - *) - --- -1.8.3.1 - diff --git a/SOURCES/0122-v2v-Add-a-regression-test-for-floppy-assignment-RHBZ.patch b/SOURCES/0122-v2v-Add-a-regression-test-for-floppy-assignment-RHBZ.patch deleted file mode 100644 index 7c4e501..0000000 --- a/SOURCES/0122-v2v-Add-a-regression-test-for-floppy-assignment-RHBZ.patch +++ /dev/null @@ -1,186 +0,0 @@ -From f5ce839611e01ae4aed4125d24690644bb609ef8 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Wed, 22 Jun 2016 14:48:22 +0100 -Subject: [PATCH] v2v: Add a regression test for floppy assignment - (RHBZ#1309706). - -(cherry picked from commit 0421c5afa330b80c17d8dce88abed2cb53f4f5cc) ---- - v2v/Makefile.am | 3 ++ - v2v/test-v2v-floppy.expected | 8 +++++ - v2v/test-v2v-floppy.sh | 77 ++++++++++++++++++++++++++++++++++++++++++++ - v2v/test-v2v-floppy.xml | 42 ++++++++++++++++++++++++ - 4 files changed, 130 insertions(+) - create mode 100644 v2v/test-v2v-floppy.expected - create mode 100755 v2v/test-v2v-floppy.sh - create mode 100644 v2v/test-v2v-floppy.xml - -diff --git a/v2v/Makefile.am b/v2v/Makefile.am -index 5bffbfe..a996e5d 100644 ---- a/v2v/Makefile.am -+++ b/v2v/Makefile.am -@@ -25,6 +25,8 @@ EXTRA_DIST = \ - HACKING \ - test-v2v-cdrom.expected \ - test-v2v-cdrom.xml \ -+ test-v2v-floppy.expected \ -+ test-v2v-floppy.xml \ - test-v2v-i-ova.ovf \ - test-v2v-i-ova.xml \ - test-v2v-i-ova-formats.expected \ -@@ -303,6 +305,7 @@ endif - if ENABLE_APPLIANCE - TESTS += \ - test-v2v-cdrom.sh \ -+ test-v2v-floppy.sh \ - test-v2v-i-ova.sh \ - test-v2v-i-disk.sh \ - test-v2v-machine-readable.sh \ -diff --git a/v2v/test-v2v-floppy.expected b/v2v/test-v2v-floppy.expected -new file mode 100644 -index 0000000..dd74ed9 ---- /dev/null -+++ b/v2v/test-v2v-floppy.expected -@@ -0,0 +1,8 @@ -+ -+ -+ -+ -+ -+ -+ -+ -diff --git a/v2v/test-v2v-floppy.sh b/v2v/test-v2v-floppy.sh -new file mode 100755 -index 0000000..d4ecfba ---- /dev/null -+++ b/v2v/test-v2v-floppy.sh -@@ -0,0 +1,77 @@ -+#!/bin/bash - -+# libguestfs virt-v2v test script -+# Copyright (C) 2015-2016 Red Hat Inc. -+# -+# This program is free software; you can redistribute it and/or modify -+# it under the terms of the GNU General Public License as published by -+# the Free Software Foundation; either version 2 of the License, or -+# (at your option) any later version. -+# -+# This program is distributed in the hope that it will be useful, -+# but WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+# GNU General Public License for more details. -+# -+# You should have received a copy of the GNU General Public License -+# along with this program; if not, write to the Free Software -+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -+ -+# Test converting a guest with a floppy disk. -+# https://bugzilla.redhat.com/show_bug.cgi?id=1309706 -+ -+unset CDPATH -+export LANG=C -+set -e -+ -+if [ -n "$SKIP_TEST_V2V_FLOPPY_SH" ]; then -+ echo "$0: test skipped because environment variable is set" -+ exit 77 -+fi -+ -+if [ "$(guestfish get-backend)" = "uml" ]; then -+ echo "$0: test skipped because UML backend does not support network" -+ exit 77 -+fi -+ -+abs_builddir="$(pwd)" -+libvirt_uri="test://$abs_builddir/test-v2v-floppy.xml" -+ -+f=../test-data/phony-guests/windows.img -+if ! test -f $f || ! test -s $f; then -+ echo "$0: test skipped because phony Windows image was not created" -+ exit 77 -+fi -+ -+f=../test-data/phony-guests/blank-disk.img -+if ! test -f $f || ! test -s $f; then -+ echo "$0: test skipped because blank-disk.img was not created" -+ exit 77 -+fi -+ -+export VIRT_TOOLS_DATA_DIR="$srcdir/../test-data/fake-virt-tools" -+export VIRTIO_WIN="$srcdir/../test-data/fake-virtio-win" -+ -+d=test-v2v-floppy.d -+rm -rf $d -+mkdir $d -+ -+$VG virt-v2v --debug-gc \ -+ -i libvirt -ic "$libvirt_uri" windows \ -+ -o local -os $d --no-copy -+ -+# Test the libvirt XML metadata was created. -+test -f $d/windows.xml -+ -+# Grab just the .. output and compare it to what we -+# expect. https://stackoverflow.com/questions/16587218 -+awk '//{p=0;print;next} ;p' \ -+ $d/windows.xml | -+ grep -v ' $d/disks -+ -+if ! diff -u test-v2v-floppy.expected $d/disks; then -+ echo "$0: unexpected disk assignments" -+ cat $d/disks -+ exit 1 -+fi -+ -+rm -r $d -diff --git a/v2v/test-v2v-floppy.xml b/v2v/test-v2v-floppy.xml -new file mode 100644 -index 0000000..41e1bef ---- /dev/null -+++ b/v2v/test-v2v-floppy.xml -@@ -0,0 +1,42 @@ -+ -+ -+ -+ windows -+ 1048576 -+ -+ hvm -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ --- -1.8.3.1 - diff --git a/SOURCES/0123-p2v-improve-error-message-for-sudo-with-password.patch b/SOURCES/0123-p2v-improve-error-message-for-sudo-with-password.patch deleted file mode 100644 index 5e5a84c..0000000 --- a/SOURCES/0123-p2v-improve-error-message-for-sudo-with-password.patch +++ /dev/null @@ -1,66 +0,0 @@ -From 112cec4ab7334c92aaea99f11ce4a669d0691839 Mon Sep 17 00:00:00 2001 -From: Pino Toscano -Date: Thu, 23 Jun 2016 11:07:18 +0200 -Subject: [PATCH] p2v: improve error message for sudo with password - -Print a better error message when the non-root user on the conversion -server requires a password to use sudo, and p2v is told to use sudo. - -See also RHZ#1340809. - -(cherry picked from commit 5b6a8e086264c85fb048c0eadff6c34351663133) ---- - p2v/ssh.c | 9 +++++++++ - 1 file changed, 9 insertions(+) - -diff --git a/p2v/ssh.c b/p2v/ssh.c -index a8c762d..f2c849f 100644 ---- a/p2v/ssh.c -+++ b/p2v/ssh.c -@@ -98,6 +98,7 @@ static void free_regexps (void) __attribute__((destructor)); - - static pcre *password_re; - static pcre *ssh_message_re; -+static pcre *sudo_password_re; - static pcre *prompt_re; - static pcre *version_re; - static pcre *feature_libguestfs_rewrite_re; -@@ -141,6 +142,7 @@ compile_regexps (void) - - COMPILE (password_re, "password:", 0); - COMPILE (ssh_message_re, "(ssh: .*)", 0); -+ COMPILE (sudo_password_re, "sudo: a password is required", 0); - /* The magic synchronization strings all match this expression. See - * start_ssh function below. - */ -@@ -161,6 +163,7 @@ free_regexps (void) - { - pcre_free (password_re); - pcre_free (ssh_message_re); -+ pcre_free (sudo_password_re); - pcre_free (prompt_re); - pcre_free (version_re); - pcre_free (feature_libguestfs_rewrite_re); -@@ -546,6 +549,7 @@ test_connection (struct config *config) - (mexp_regexp[]) { - { 100, .re = version_re }, - { 101, .re = prompt_re }, -+ { 102, .re = sudo_password_re }, - { 0 } - }, ovector, ovecsize)) { - case 100: /* Got version string. */ -@@ -560,6 +564,11 @@ test_connection (struct config *config) - case 101: /* Got the prompt. */ - goto end_of_version; - -+ case 102: -+ mexp_close (h); -+ set_ssh_error ("sudo for user '%s' requires a password", config->username); -+ return -1; -+ - case MEXP_EOF: - mexp_close (h); - set_ssh_error ("unexpected end of file waiting virt-v2v --version output"); --- -1.8.3.1 - diff --git a/SOURCES/0124-p2v-Force-bash-as-the-remote-shell.patch b/SOURCES/0124-p2v-Force-bash-as-the-remote-shell.patch deleted file mode 100644 index 5fac537..0000000 --- a/SOURCES/0124-p2v-Force-bash-as-the-remote-shell.patch +++ /dev/null @@ -1,60 +0,0 @@ -From 2a0fc9580c0b169f3c1d884e300d8b3d59678431 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Thu, 23 Jun 2016 11:19:37 +0100 -Subject: [PATCH] p2v: Force bash as the remote shell. - -As described in the comment, this solves a number of problems with -non-standard remote configurations. - -I tested this with: - - - tcsh - - zsh - - ksh - -and all behaved correctly. - -(cherry picked from commit d41cf142e1eb285eca798889d3b6a955afffbe32) ---- - p2v/ssh.c | 21 ++++++++++++++++++--- - 1 file changed, 18 insertions(+), 3 deletions(-) - -diff --git a/p2v/ssh.c b/p2v/ssh.c -index f2c849f..d2c8035 100644 ---- a/p2v/ssh.c -+++ b/p2v/ssh.c -@@ -416,13 +416,28 @@ start_ssh (struct config *config, char **extra_args, int wait_prompt) - if (!wait_prompt) - return h; - -- /* Synchronize with the command prompt and set it to a known string. */ -- -- /* Note that we cannot control the initial prompt. It would involve -+ /* Ensure we are running bash, set environment variables, and -+ * synchronize with the command prompt and set it to a known -+ * string. There are multiple issues being solved here: -+ * -+ * We cannot control the initial shell prompt. It would involve - * changing the remote SSH configuration (AcceptEnv). However what - * we can do is to repeatedly send 'export PS1=' commands - * until we synchronize with the remote shell. -+ * -+ * We don't know if the user is using a Bourne-like shell (eg sh, -+ * bash) or csh/tcsh. Setting environment variables works -+ * differently. -+ * -+ * We don't know how command line editing is set up -+ * (https://bugzilla.redhat.com/1314244#c9). - */ -+ if (mexp_printf (h, "exec bash --noediting --noprofile\n") == -1) { -+ set_ssh_error ("setting bash as remote shell: %m"); -+ mexp_close (h); -+ return NULL; -+ } -+ - saved_timeout = mexp_get_timeout_ms (h); - mexp_set_timeout (h, 2); - --- -1.8.3.1 - diff --git a/SOURCES/0125-p2v-Set-LANG-C-in-the-remote-shell-so-we-can-match-o.patch b/SOURCES/0125-p2v-Set-LANG-C-in-the-remote-shell-so-we-can-match-o.patch deleted file mode 100644 index 2ec43cf..0000000 --- a/SOURCES/0125-p2v-Set-LANG-C-in-the-remote-shell-so-we-can-match-o.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 5ca9876f652f093230ed8c4f50463a64b76dce62 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Thu, 23 Jun 2016 11:27:01 +0100 -Subject: [PATCH] p2v: Set LANG=C in the remote shell so we can match on error - messages. - -Since commit 5b6a8e086264c85fb048c0eadff6c34351663133 we are now -matching on error messages, and therefore we must set LANG=C. - -(cherry picked from commit 5e794b86072cfaa1d2017d93bd3a24be72636c02) ---- - p2v/ssh.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/p2v/ssh.c b/p2v/ssh.c -index d2c8035..aa070d5 100644 ---- a/p2v/ssh.c -+++ b/p2v/ssh.c -@@ -425,6 +425,8 @@ start_ssh (struct config *config, char **extra_args, int wait_prompt) - * we can do is to repeatedly send 'export PS1=' commands - * until we synchronize with the remote shell. - * -+ * Since we parse error messages, we must set LANG=C. -+ * - * We don't know if the user is using a Bourne-like shell (eg sh, - * bash) or csh/tcsh. Setting environment variables works - * differently. -@@ -455,7 +457,7 @@ start_ssh (struct config *config, char **extra_args, int wait_prompt) - /* The purpose of the '' inside the string is to ensure we don't - * mistake the command echo for the prompt. - */ -- if (mexp_printf (h, "export PS1='###''%s''### '\n", magic) == -1) { -+ if (mexp_printf (h, "export LANG=C PS1='###''%s''### '\n", magic) == -1) { - set_ssh_error ("random_string: %m"); - mexp_close (h); - return NULL; --- -1.8.3.1 - diff --git a/SOURCES/0126-sparsify-Move-statvfs-wrapper-function-to-mllib.patch b/SOURCES/0126-sparsify-Move-statvfs-wrapper-function-to-mllib.patch deleted file mode 100644 index 0c3b0f6..0000000 --- a/SOURCES/0126-sparsify-Move-statvfs-wrapper-function-to-mllib.patch +++ /dev/null @@ -1,302 +0,0 @@ -From c2f3c3eadc4f130a411c6fc259e65d30291bfd0c Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Thu, 23 Jun 2016 13:10:35 +0100 -Subject: [PATCH] sparsify: Move statvfs wrapper function to mllib. - -We wish to use this function in virt-v2v too, so move it to the common -directory. - -No functional change. - -(cherry picked from commit 24130d787256dc3d9e37e85b1ba35ac7dbeb86a1) ---- - mllib/Makefile.am | 3 +++ - mllib/StatVFS.ml | 21 +++++++++++++++++++++ - mllib/StatVFS.mli | 23 +++++++++++++++++++++++ - mllib/statvfs-c.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ - po/POTFILES | 2 +- - po/POTFILES-ml | 1 + - sparsify/Makefile.am | 3 ++- - sparsify/copying.ml | 5 +---- - sparsify/statvfs-c.c | 50 -------------------------------------------------- - 9 files changed, 102 insertions(+), 56 deletions(-) - create mode 100644 mllib/StatVFS.ml - create mode 100644 mllib/StatVFS.mli - create mode 100644 mllib/statvfs-c.c - delete mode 100644 sparsify/statvfs-c.c - -diff --git a/mllib/Makefile.am b/mllib/Makefile.am -index e0f1987..0a6dd93 100644 ---- a/mllib/Makefile.am -+++ b/mllib/Makefile.am -@@ -36,6 +36,7 @@ SOURCES_MLI = \ - planner.mli \ - progress.mli \ - regedit.mli \ -+ StatVFS.mli \ - URI.mli - - SOURCES_ML = \ -@@ -50,6 +51,7 @@ SOURCES_ML = \ - mkdtemp.ml \ - planner.ml \ - regedit.ml \ -+ StatVFS.ml \ - JSON.ml \ - curl.ml - -@@ -60,6 +62,7 @@ SOURCES_C = \ - fsync-c.c \ - mkdtemp-c.c \ - progress-c.c \ -+ statvfs-c.c \ - uri-c.c - - if HAVE_OCAML -diff --git a/mllib/StatVFS.ml b/mllib/StatVFS.ml -new file mode 100644 -index 0000000..98e6d22 ---- /dev/null -+++ b/mllib/StatVFS.ml -@@ -0,0 +1,21 @@ -+(* virt tools interface to statvfs -+ * Copyright (C) 2016 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. -+ *) -+ -+(** Binding for [statvfs], but just for getting disk free space. *) -+ -+external free_space : string -> int64 = "guestfs_int_mllib_statvfs_free_space" -diff --git a/mllib/StatVFS.mli b/mllib/StatVFS.mli -new file mode 100644 -index 0000000..b1b8834 ---- /dev/null -+++ b/mllib/StatVFS.mli -@@ -0,0 +1,23 @@ -+(* virt tools interface to statvfs -+ * Copyright (C) 2016 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. -+ *) -+ -+(** Binding for [statvfs], but just for getting disk free space. *) -+ -+val free_space : string -> int64 -+(** [free_space path] returns the free space available on the -+ filesystem that contains [path], in bytes. *) -diff --git a/mllib/statvfs-c.c b/mllib/statvfs-c.c -new file mode 100644 -index 0000000..5c10531 ---- /dev/null -+++ b/mllib/statvfs-c.c -@@ -0,0 +1,50 @@ -+/* virt tools interface to statvfs -+ * Copyright (C) 2013-2016 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 -+ -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+ -+extern value guestfs_int_mllib_statvfs_free_space (value pathv); -+ -+value -+guestfs_int_mllib_statvfs_free_space (value pathv) -+{ -+ CAMLparam1 (pathv); -+ CAMLlocal1 (rv); -+ struct statvfs buf; -+ int64_t free_space; -+ -+ if (statvfs (String_val (pathv), &buf) == -1) { -+ perror ("statvfs"); -+ caml_failwith ("statvfs"); -+ } -+ -+ free_space = (int64_t) buf.f_bsize * buf.f_bavail; -+ rv = caml_copy_int64 (free_space); -+ -+ CAMLreturn (rv); -+} -diff --git a/po/POTFILES b/po/POTFILES -index 1252d8b..bef6540 100644 ---- a/po/POTFILES -+++ b/po/POTFILES -@@ -266,6 +266,7 @@ mllib/dummy.c - mllib/fsync-c.c - mllib/mkdtemp-c.c - mllib/progress-c.c -+mllib/statvfs-c.c - mllib/uri-c.c - ocaml/guestfs-c-actions.c - ocaml/guestfs-c-errnos.c -@@ -292,7 +293,6 @@ rescue/rescue.c - rescue/test-virt-rescue.pl - resize/test-virt-resize.pl - ruby/ext/guestfs/_guestfs.c --sparsify/statvfs-c.c - src/actions-0.c - src/actions-1.c - src/actions-2.c -diff --git a/po/POTFILES-ml b/po/POTFILES-ml -index 2b9bba1..5937ff5 100644 ---- a/po/POTFILES-ml -+++ b/po/POTFILES-ml -@@ -38,6 +38,7 @@ dib/utils.ml - get-kernel/get_kernel.ml - mllib/JSON.ml - mllib/JSON_tests.ml -+mllib/StatVFS.ml - mllib/URI.ml - mllib/common_gettext.ml - mllib/common_utils.ml -diff --git a/sparsify/Makefile.am b/sparsify/Makefile.am -index 9df3e1f..9dd9179 100644 ---- a/sparsify/Makefile.am -+++ b/sparsify/Makefile.am -@@ -39,7 +39,7 @@ SOURCES_C = \ - ../fish/progress.c \ - ../mllib/dev_t-c.c \ - ../mllib/progress-c.c \ -- statvfs-c.c -+ ../mllib/statvfs-c.c - - if HAVE_OCAML - -@@ -61,6 +61,7 @@ BOBJECTS = \ - $(top_builddir)/mllib/dev_t.cmo \ - $(top_builddir)/mllib/common_utils.cmo \ - $(top_builddir)/mllib/progress.cmo \ -+ $(top_builddir)/mllib/StatVFS.cmo \ - $(SOURCES_ML:.ml=.cmo) - XOBJECTS = $(BOBJECTS:.cmo=.cmx) - -diff --git a/sparsify/copying.ml b/sparsify/copying.ml -index 83cbec7..003dbf8 100644 ---- a/sparsify/copying.ml -+++ b/sparsify/copying.ml -@@ -31,9 +31,6 @@ open Cmdline - - module G = Guestfs - --external statvfs_free_space : string -> int64 = -- "virt_sparsify_statvfs_free_space" -- - type tmp_place = - | Directory of string | Block_device of string | Prebuilt_file of string - -@@ -100,7 +97,7 @@ let run indisk outdisk check_tmpdir compress convert - virtual_size (human_size virtual_size); - - let print_warning () = -- let free_space = statvfs_free_space tmpdir in -+ let free_space = StatVFS.free_space tmpdir in - let extra_needed = virtual_size -^ free_space in - if extra_needed > 0L then ( - warning (f_"\ -diff --git a/sparsify/statvfs-c.c b/sparsify/statvfs-c.c -deleted file mode 100644 -index 76bff0b..0000000 ---- a/sparsify/statvfs-c.c -+++ /dev/null -@@ -1,50 +0,0 @@ --/* virt-sparsify - interface to statvfs -- * Copyright (C) 2013 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 -- --#include --#include --#include --#include -- --#include --#include --#include --#include -- --#pragma GCC diagnostic ignored "-Wmissing-prototypes" -- --value --virt_sparsify_statvfs_free_space (value pathv) --{ -- CAMLparam1 (pathv); -- CAMLlocal1 (rv); -- struct statvfs buf; -- int64_t free_space; -- -- if (statvfs (String_val (pathv), &buf) == -1) { -- perror ("statvfs"); -- caml_failwith ("statvfs"); -- } -- -- free_space = (int64_t) buf.f_bsize * buf.f_bavail; -- rv = caml_copy_int64 (free_space); -- -- CAMLreturn (rv); --} --- -1.8.3.1 - diff --git a/SOURCES/0127-v2v-Move-calculation-of-overlay-directory-to-common-.patch b/SOURCES/0127-v2v-Move-calculation-of-overlay-directory-to-common-.patch deleted file mode 100644 index 4803abd..0000000 --- a/SOURCES/0127-v2v-Move-calculation-of-overlay-directory-to-common-.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 3064454f1a56589e47907e9c7a2742643e9fde91 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Thu, 23 Jun 2016 13:11:45 +0100 -Subject: [PATCH] v2v: Move calculation of overlay directory to common code. - -There is a tiny functional change in this patch, since overlay_dir is -now always evaluated once (eg. even in --inplace mode), whereas -previously it was evaluated twice but only in copying mode. - -(cherry picked from commit a7fb3d601ab2ae3cdf2074d4c47afe59f00eea6d) ---- - v2v/v2v.ml | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/v2v/v2v.ml b/v2v/v2v.ml -index f2f1cff..ebbfa68 100644 ---- a/v2v/v2v.ml -+++ b/v2v/v2v.ml -@@ -201,10 +201,11 @@ and amend_source cmdline source = - - { source with s_nics = nics } - -+and overlay_dir = (open_guestfs ())#get_cachedir () -+ - (* Create a qcow2 v3 overlay to protect the source image(s). *) - and create_overlays src_disks = - message (f_"Creating an overlay to protect the source from being modified"); -- let overlay_dir = (open_guestfs ())#get_cachedir () in - List.mapi ( - fun i ({ s_qemu_uri = qemu_uri; s_format = format } as source) -> - let overlay_file = -@@ -720,7 +721,6 @@ and actual_target_size target = - - (* Save overlays if --debug-overlays option was used. *) - and preserve_overlays overlays src_name = -- let overlay_dir = (open_guestfs ())#get_cachedir () in - List.iter ( - fun ov -> - let saved_filename = --- -1.8.3.1 - diff --git a/SOURCES/0128-v2v-Rename-check_free_space-check_guest_free_space.patch b/SOURCES/0128-v2v-Rename-check_free_space-check_guest_free_space.patch deleted file mode 100644 index 3ef5b40..0000000 --- a/SOURCES/0128-v2v-Rename-check_free_space-check_guest_free_space.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 9482990df8ef561a4824e960c254075bac611027 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Thu, 23 Jun 2016 13:12:44 +0100 -Subject: [PATCH] v2v: Rename check_free_space -> check_guest_free_space. - -(cherry picked from commit d8a465a14c3596a9fea53560bc7ad2ee6c3111bc) ---- - v2v/v2v.ml | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/v2v/v2v.ml b/v2v/v2v.ml -index ebbfa68..f3eae43 100644 ---- a/v2v/v2v.ml -+++ b/v2v/v2v.ml -@@ -78,7 +78,7 @@ let rec main () = - let inspect = Inspect_source.inspect_source cmdline.root_choice g in - - let mpstats = get_mpstats g in -- check_free_space mpstats; -+ check_guest_free_space mpstats; - (match conversion_mode with - | Copying (_, targets) -> - check_target_free_space mpstats source targets output -@@ -327,7 +327,7 @@ and get_mpstats g = - * (RHBZ#1139543). To avoid this situation, check there is some - * headroom. Mainly we care about the root filesystem. - *) --and check_free_space mpstats = -+and check_guest_free_space mpstats = - message (f_"Checking for sufficient free disk space in the guest"); - List.iter ( - fun { mp_path = mp; --- -1.8.3.1 - diff --git a/SOURCES/0129-v2v-Refuse-to-convert-if-1GB-of-free-space-in-tempor.patch b/SOURCES/0129-v2v-Refuse-to-convert-if-1GB-of-free-space-in-tempor.patch deleted file mode 100644 index a09bd9e..0000000 --- a/SOURCES/0129-v2v-Refuse-to-convert-if-1GB-of-free-space-in-tempor.patch +++ /dev/null @@ -1,144 +0,0 @@ -From 923789a842239fa18e45f42f22126ef0f4aa6802 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Thu, 23 Jun 2016 13:27:09 +0100 -Subject: [PATCH] v2v: Refuse to convert if < 1GB of free space in temporary - directory (RHBZ#1316479). - -The error you would see is: - - virt-v2v: error: insufficient free space in the conversion server temporary - directory /var/tmp (853.8M). - - Either free up space in that directory, or set the LIBGUESTFS_CACHEDIR - environment variable to point to another directory with more than 1GB of - free space. - - See also the virt-v2v(1) manual, section "Minimum free space check in the - host". - -Also adds some documentation. - -Thanks: Ming Xie and Xiaodai Wang -(cherry picked from commit 9221ef6f7959ae3b979fd05007363810bc66062b) ---- - v2v/Makefile.am | 4 ++++ - v2v/v2v.ml | 15 +++++++++++++++ - v2v/virt-v2v.pod | 19 +++++++++++++++++++ - 3 files changed, 38 insertions(+) - -diff --git a/v2v/Makefile.am b/v2v/Makefile.am -index a996e5d..e0d013a 100644 ---- a/v2v/Makefile.am -+++ b/v2v/Makefile.am -@@ -117,6 +117,7 @@ SOURCES_ML = \ - SOURCES_C = \ - ../mllib/dev_t-c.c \ - ../mllib/mkdtemp-c.c \ -+ ../mllib/statvfs-c.c \ - domainxml-c.c \ - changeuid-c.c \ - utils-c.c \ -@@ -145,6 +146,7 @@ BOBJECTS = \ - $(top_builddir)/mllib/regedit.cmo \ - $(top_builddir)/mllib/mkdtemp.cmo \ - $(top_builddir)/mllib/JSON.cmo \ -+ $(top_builddir)/mllib/StatVFS.cmo \ - $(top_builddir)/mllib/curl.cmo \ - $(top_builddir)/customize/customize_utils.cmo \ - $(top_builddir)/customize/firstboot.cmo \ -@@ -192,6 +194,7 @@ virt_v2v_LINK = \ - - virt_v2v_copy_to_local_SOURCES = \ - ../mllib/dev_t-c.c \ -+ ../mllib/statvfs-c.c \ - domainxml-c.c \ - utils-c.c \ - xml-c.c -@@ -211,6 +214,7 @@ COPY_TO_LOCAL_BOBJECTS = \ - $(top_builddir)/mllib/dev_t.cmo \ - $(top_builddir)/mllib/common_utils.cmo \ - $(top_builddir)/mllib/JSON.cmo \ -+ $(top_builddir)/mllib/StatVFS.cmo \ - $(top_builddir)/mllib/curl.cmo \ - xml.cmo \ - utils.cmo \ -diff --git a/v2v/v2v.ml b/v2v/v2v.ml -index f3eae43..4b06bc1 100644 ---- a/v2v/v2v.ml -+++ b/v2v/v2v.ml -@@ -49,6 +49,7 @@ let rec main () = - - let conversion_mode = - if not cmdline.in_place then ( -+ check_host_free_space (); - let overlays = create_overlays source.s_disks in - let targets = init_targets cmdline output source overlays in - Copying (overlays, targets) -@@ -203,6 +204,20 @@ and amend_source cmdline source = - - and overlay_dir = (open_guestfs ())#get_cachedir () - -+(* Conversion can fail or hang if there is insufficient free space in -+ * the temporary directory used to store overlays on the host -+ * (RHBZ#1316479). Although only a few hundred MB is actually -+ * required, make the minimum be 1 GB to allow for the possible 500 MB -+ * guestfs appliance which is also stored here. -+ *) -+and check_host_free_space () = -+ let free_space = StatVFS.free_space overlay_dir in -+ debug "check_host_free_space: overlay_dir=%s free_space=%Ld" -+ overlay_dir free_space; -+ if free_space < 1_073_741_824L then -+ error (f_"insufficient free space in the conversion server temporary directory %s (%s).\n\nEither free up space in that directory, or set the LIBGUESTFS_CACHEDIR environment variable to point to another directory with more than 1GB of free space.\n\nSee also the virt-v2v(1) manual, section \"Minimum free space check in the host\".") -+ overlay_dir (human_size free_space) -+ - (* Create a qcow2 v3 overlay to protect the source image(s). *) - and create_overlays src_disks = - message (f_"Creating an overlay to protect the source from being modified"); -diff --git a/v2v/virt-v2v.pod b/v2v/virt-v2v.pod -index 4ea02ab..c68bcb5 100644 ---- a/v2v/virt-v2v.pod -+++ b/v2v/virt-v2v.pod -@@ -1495,6 +1495,8 @@ This temporarily places a full copy of the output disks in C<$TMPDIR>. - - =back - -+See also L below. -+ - =head2 VMware vCenter resources - - Copying from VMware vCenter is currently quite slow, but we believe -@@ -1546,6 +1548,8 @@ prevent the guest from subsequently booting correctly. - - =head1 FREE SPACE FOR CONVERSION - -+=head2 Free space in the guest -+ - Virt-v2v checks there is sufficient free space in the guest filesystem - to perform the conversion. Currently it checks: - -@@ -1568,6 +1572,21 @@ Minimum free space: 10 MB - - =back - -+=head2 Minimum free space check in the host -+ -+You must have sufficient free space in the host directory used to -+store temporary overlays (except in [--in-place] mode). To find out -+which directory this is, use: -+ -+ $ df -h "`guestfish get-cachedir`" -+ Filesystem Size Used Avail Use% Mounted on -+ /dev/mapper/root 50G 40G 6.8G 86% / -+ -+and look under the C column. Virt-v2v will refuse to do the -+conversion at all unless at least 1GB is available there. -+ -+See also L above. -+ - =head1 RUNNING VIRT-V2V AS ROOT OR NON-ROOT - - Nothing in virt-v2v inherently needs root access, and it will run just --- -1.8.3.1 - diff --git a/SOURCES/0130-p2v-Make-the-sudo-error-message-actionable.patch b/SOURCES/0130-p2v-Make-the-sudo-error-message-actionable.patch deleted file mode 100644 index a80330a..0000000 --- a/SOURCES/0130-p2v-Make-the-sudo-error-message-actionable.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 0d3ac31739bcfa3c4dc4adb66de07d6859735c35 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Thu, 23 Jun 2016 13:52:46 +0100 -Subject: [PATCH] p2v: Make the sudo error message actionable. - -Updates commit 5b6a8e086264c85fb048c0eadff6c34351663133. - -(cherry picked from commit 323c3e20a4d47fc5a0f1b5fcd3352f746c8bd9dd) ---- - p2v/ssh.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/p2v/ssh.c b/p2v/ssh.c -index aa070d5..083e04e 100644 ---- a/p2v/ssh.c -+++ b/p2v/ssh.c -@@ -583,7 +583,8 @@ test_connection (struct config *config) - - case 102: - mexp_close (h); -- set_ssh_error ("sudo for user '%s' requires a password", config->username); -+ set_ssh_error ("sudo for user \"%s\" requires a password. Edit /etc/sudoers on the conversion server to ensure the \"NOPASSWD:\" option is set for this user.", -+ config->username); - return -1; - - case MEXP_EOF: --- -1.8.3.1 - diff --git a/SOURCES/0131-p2v-ssh-Improve-consistency-of-error-messages.patch b/SOURCES/0131-p2v-ssh-Improve-consistency-of-error-messages.patch deleted file mode 100644 index 08a991b..0000000 --- a/SOURCES/0131-p2v-ssh-Improve-consistency-of-error-messages.patch +++ /dev/null @@ -1,482 +0,0 @@ -From af87d247df5ebe6b94e04624c35b59155ae99eb5 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Thu, 23 Jun 2016 14:25:23 +0100 -Subject: [PATCH] p2v: ssh: Improve consistency of error messages. - -(cherry picked from commit 8f8a651e591064d87974bd322a995519347ebae7) ---- - p2v/ssh.c | 133 +++++++++++++++++++++++++++++++++++--------------------------- - 1 file changed, 75 insertions(+), 58 deletions(-) - -diff --git a/p2v/ssh.c b/p2v/ssh.c -index 083e04e..93c4c55 100644 ---- a/p2v/ssh.c -+++ b/p2v/ssh.c -@@ -93,6 +93,21 @@ get_ssh_error (void) - return ssh_error; - } - -+/* Like set_ssh_error, but for errors that aren't supposed to happen. */ -+#define set_ssh_internal_error(fs, ...) \ -+ set_ssh_error ("internal error: " fs, ##__VA_ARGS__) -+#define set_ssh_mexp_error(fn) \ -+ set_ssh_internal_error ("%s: %m", fn) -+#define set_ssh_pcre_error() \ -+ set_ssh_internal_error ("pcre error: %d\n", mexp_get_pcre_error (h)) -+ -+#define set_ssh_unexpected_eof(fs, ...) \ -+ set_ssh_error ("remote server closed the connection unexpectedly, " \ -+ "waiting for: " fs, ##__VA_ARGS__) -+#define set_ssh_unexpected_timeout(fs, ...) \ -+ set_ssh_error ("remote server timed out unexpectedly, " \ -+ "waiting for: " fs, ##__VA_ARGS__) -+ - static void compile_regexps (void) __attribute__((constructor)); - static void free_regexps (void) __attribute__((destructor)); - -@@ -241,7 +256,7 @@ curl_download (const char *url, const char *local_file) - return -1; - } - else if (!WIFEXITED (r)) { -- set_ssh_error ("curl subprocess got a signal (%d)", r); -+ set_ssh_internal_error ("curl subprocess got a signal (%d)", r); - unlink (error_file); - return -1; - } -@@ -353,7 +368,7 @@ start_ssh (struct config *config, char **extra_args, int wait_prompt) - - h = mexp_spawnv ("ssh", (char **) args); - if (h == NULL) { -- set_ssh_error ("internal error: ssh: mexp_spawnv: %m"); -+ set_ssh_internal_error ("ssh: mexp_spawnv: %m"); - return NULL; - } - -@@ -371,7 +386,7 @@ start_ssh (struct config *config, char **extra_args, int wait_prompt) - }, ovector, ovecsize)) { - case 100: /* Got password prompt. */ - if (mexp_printf (h, "%s\n", config->password) == -1) { -- set_ssh_error ("mexp_printf: %m"); -+ set_ssh_mexp_error ("mexp_printf"); - mexp_close (h); - return NULL; - } -@@ -383,7 +398,6 @@ start_ssh (struct config *config, char **extra_args, int wait_prompt) - goto wait_password_again; - - case MEXP_EOF: -- mexp_close (h); - /* This is where we get to if the user enters an incorrect or - * impossible hostname or port number. Hopefully ssh printed an - * error message, and we picked it up and put it in -@@ -393,21 +407,22 @@ start_ssh (struct config *config, char **extra_args, int wait_prompt) - if (ssh_message) - set_ssh_error ("%s", ssh_message); - else -- set_ssh_error ("unknown ssh error"); -+ set_ssh_error ("ssh closed the connection without printing an error."); -+ mexp_close (h); - return NULL; - - case MEXP_TIMEOUT: -+ set_ssh_unexpected_timeout ("password prompt"); - mexp_close (h); -- set_ssh_error ("timeout waiting for password prompt"); - return NULL; - - case MEXP_ERROR: -- set_ssh_error ("mexp_expect: %m"); -+ set_ssh_mexp_error ("mexp_expect"); - mexp_close (h); - return NULL; - - case MEXP_PCRE_ERROR: -- set_ssh_error ("PCRE error: %d\n", mexp_get_pcre_error (h)); -+ set_ssh_pcre_error (); - mexp_close (h); - return NULL; - } -@@ -435,7 +450,7 @@ start_ssh (struct config *config, char **extra_args, int wait_prompt) - * (https://bugzilla.redhat.com/1314244#c9). - */ - if (mexp_printf (h, "exec bash --noediting --noprofile\n") == -1) { -- set_ssh_error ("setting bash as remote shell: %m"); -+ set_ssh_mexp_error ("mexp_printf"); - mexp_close (h); - return NULL; - } -@@ -449,7 +464,7 @@ start_ssh (struct config *config, char **extra_args, int wait_prompt) - int r; - - if (guestfs_int_random_string (magic, 8) == -1) { -- set_ssh_error ("random_string: %m"); -+ set_ssh_internal_error ("random_string: %m"); - mexp_close (h); - return NULL; - } -@@ -458,7 +473,7 @@ start_ssh (struct config *config, char **extra_args, int wait_prompt) - * mistake the command echo for the prompt. - */ - if (mexp_printf (h, "export LANG=C PS1='###''%s''### '\n", magic) == -1) { -- set_ssh_error ("random_string: %m"); -+ set_ssh_mexp_error ("mexp_printf"); - mexp_close (h); - return NULL; - } -@@ -472,8 +487,8 @@ start_ssh (struct config *config, char **extra_args, int wait_prompt) - { 0 } - }, ovector, ovecsize)) { - case 100: /* Got password prompt unexpectedly. */ -+ set_ssh_error ("Login failed. Probably the username and/or password is wrong."); - mexp_close (h); -- set_ssh_error ("login failed - probably the username and/or password is wrong"); - return NULL; - - case 101: -@@ -483,7 +498,7 @@ start_ssh (struct config *config, char **extra_args, int wait_prompt) - r = pcre_get_substring (h->buffer, ovector, - mexp_get_pcre_error (h), 1, &matched); - if (r < 0) { -- fprintf (stderr, "error: PCRE error reading substring (%d)\n", r); -+ fprintf (stderr, "error: pcre error reading substring (%d)\n", r); - exit (EXIT_FAILURE); - } - r = STREQ (magic, matched); -@@ -493,8 +508,8 @@ start_ssh (struct config *config, char **extra_args, int wait_prompt) - goto got_prompt; - - case MEXP_EOF: -+ set_ssh_unexpected_eof ("the command prompt"); - mexp_close (h); -- set_ssh_error ("unexpected end of file waiting for command prompt"); - return NULL; - - case MEXP_TIMEOUT: -@@ -504,19 +519,19 @@ start_ssh (struct config *config, char **extra_args, int wait_prompt) - break; - - case MEXP_ERROR: -- set_ssh_error ("mexp_expect: %m"); -+ set_ssh_mexp_error ("mexp_expect"); - mexp_close (h); - return NULL; - - case MEXP_PCRE_ERROR: -- set_ssh_error ("PCRE error: %d\n", mexp_get_pcre_error (h)); -+ set_ssh_pcre_error (); - mexp_close (h); - return NULL; - } - } - -+ set_ssh_error ("Failed to synchronize with remote shell after 60 seconds."); - mexp_close (h); -- set_ssh_error ("failed to synchronize with remote shell after 60 seconds"); - return NULL; - - got_prompt: -@@ -556,7 +571,7 @@ test_connection (struct config *config) - if (mexp_printf (h, - "%svirt-v2v --version\n", - config->sudo ? "sudo -n " : "") == -1) { -- set_ssh_error ("mexp_printf: %m"); -+ set_ssh_mexp_error ("mexp_printf"); - mexp_close (h); - return -1; - } -@@ -582,28 +597,28 @@ test_connection (struct config *config) - goto end_of_version; - - case 102: -- mexp_close (h); - set_ssh_error ("sudo for user \"%s\" requires a password. Edit /etc/sudoers on the conversion server to ensure the \"NOPASSWD:\" option is set for this user.", - config->username); -+ mexp_close (h); - return -1; - - case MEXP_EOF: -+ set_ssh_unexpected_eof ("\"virt-v2v --version\" output"); - mexp_close (h); -- set_ssh_error ("unexpected end of file waiting virt-v2v --version output"); - return -1; - - case MEXP_TIMEOUT: -+ set_ssh_unexpected_timeout ("\"virt-v2v --version\" output"); - mexp_close (h); -- set_ssh_error ("timeout waiting for virt-v2v --version output"); - return -1; - - case MEXP_ERROR: -- set_ssh_error ("mexp_expect: %m"); -+ set_ssh_mexp_error ("mexp_expect"); - mexp_close (h); - return -1; - - case MEXP_PCRE_ERROR: -- set_ssh_error ("PCRE error: %d\n", mexp_get_pcre_error (h)); -+ set_ssh_pcre_error (); - mexp_close (h); - return -1; - } -@@ -612,9 +627,9 @@ test_connection (struct config *config) - - /* Got the prompt but no version number. */ - if (v2v_version == NULL) { -- mexp_close (h); - set_ssh_error ("virt-v2v is not installed on the conversion server, " -- "or it might be a too old version"); -+ "or it might be a too old version."); -+ mexp_close (h); - return -1; - } - -@@ -634,7 +649,7 @@ test_connection (struct config *config) - /* Get virt-v2v features. See: v2v/cmdline.ml */ - if (mexp_printf (h, "%svirt-v2v --machine-readable\n", - config->sudo ? "sudo -n " : "") == -1) { -- set_ssh_error ("mexp_printf: %m"); -+ set_ssh_mexp_error ("mexp_printf"); - mexp_close (h); - return -1; - } -@@ -677,22 +692,22 @@ test_connection (struct config *config) - goto end_of_machine_readable; - - case MEXP_EOF: -+ set_ssh_unexpected_eof ("\"virt-v2v --machine-readable\" output"); - mexp_close (h); -- set_ssh_error ("unexpected end of file waiting virt-v2v --machine-readable output"); - return -1; - - case MEXP_TIMEOUT: -+ set_ssh_unexpected_timeout ("\"virt-v2v --machine-readable\" output"); - mexp_close (h); -- set_ssh_error ("timeout waiting virt-v2v --machine-readable output"); - return -1; - - case MEXP_ERROR: -- set_ssh_error ("mexp_expect: %m"); -+ set_ssh_mexp_error ("mexp_expect"); - mexp_close (h); - return -1; - - case MEXP_PCRE_ERROR: -- set_ssh_error ("PCRE error: %d\n", mexp_get_pcre_error (h)); -+ set_ssh_pcre_error (); - mexp_close (h); - return -1; - } -@@ -700,14 +715,14 @@ test_connection (struct config *config) - end_of_machine_readable: - - if (!feature_libguestfs_rewrite) { -+ set_ssh_error ("Invalid output of \"virt-v2v --machine-readable\" command."); - mexp_close (h); -- set_ssh_error ("invalid output of virt-v2v --machine-readable command"); - return -1; - } - - /* Test finished, shut down ssh. */ - if (mexp_printf (h, "exit\n") == -1) { -- set_ssh_error ("mexp_printf: %m"); -+ set_ssh_mexp_error ("mexp_printf"); - mexp_close (h); - return -1; - } -@@ -717,30 +732,31 @@ test_connection (struct config *config) - break; - - case MEXP_TIMEOUT: -+ set_ssh_unexpected_timeout ("end of ssh session"); - mexp_close (h); -- set_ssh_error ("timeout waiting for end of ssh session"); - return -1; - - case MEXP_ERROR: -- set_ssh_error ("mexp_expect: %m"); -+ set_ssh_mexp_error ("mexp_expect"); - mexp_close (h); - return -1; - - case MEXP_PCRE_ERROR: -- set_ssh_error ("PCRE error: %d\n", mexp_get_pcre_error (h)); -+ set_ssh_pcre_error (); - mexp_close (h); - return -1; - } - - status = mexp_close (h); - if (status == -1) { -- set_ssh_error ("mexp_close: %m"); -+ set_ssh_internal_error ("mexp_close: %m"); - return -1; - } - if (WIFSIGNALED (status) && WTERMSIG (status) == SIGHUP) - return 0; /* not an error */ - if (!WIFEXITED (status) || WEXITSTATUS (status) != 0) { -- set_ssh_error ("unexpected close status from ssh subprocess (%d)", status); -+ set_ssh_internal_error ("unexpected close status from ssh subprocess (%d)", -+ status); - return -1; - } - return 0; -@@ -799,7 +815,7 @@ compatible_version (const char *v2v_version) - /* The major version must always be 1. */ - if (!STRPREFIX (v2v_version, "1.")) { - set_ssh_error ("virt-v2v major version is not 1 (\"%s\"), " -- "this version of virt-p2v is not compatible", -+ "this version of virt-p2v is not compatible.", - v2v_version); - return 0; - } -@@ -810,15 +826,15 @@ compatible_version (const char *v2v_version) - * We should remain compatible with any virt-v2v after 1.28. - */ - if (sscanf (v2v_version, "1.%u", &v2v_minor) != 1) { -- set_ssh_error ("cannot parse virt-v2v version string (\"%s\")", -- v2v_version); -+ set_ssh_internal_error ("cannot parse virt-v2v version string (\"%s\")", -+ v2v_version); - return 0; - } - - if (v2v_minor < 28) { - set_ssh_error ("virt-v2v version is < 1.28 (\"%s\"), " - "you must upgrade to virt-v2v >= 1.28 on " -- "the conversion server", v2v_version); -+ "the conversion server.", v2v_version); - return 0; - } - -@@ -858,34 +874,35 @@ open_data_connection (struct config *config, int *local_port, int *remote_port) - case 100: /* Ephemeral port. */ - port_str = strndup (&h->buffer[ovector[2]], ovector[3]-ovector[2]); - if (port_str == NULL) { -- set_ssh_error ("not enough memory for strndup"); -+ set_ssh_internal_error ("strndup: %m"); - mexp_close (h); - return NULL; - } - if (sscanf (port_str, "%d", remote_port) != 1) { -- set_ssh_error ("cannot extract the port number from '%s'", port_str); -+ set_ssh_internal_error ("cannot extract the port number from '%s'", -+ port_str); - mexp_close (h); - return NULL; - } - break; - - case MEXP_EOF: -+ set_ssh_unexpected_eof ("\"ssh -R\" output"); - mexp_close (h); -- set_ssh_error ("unexpected end of file waiting ssh -R output"); - return NULL; - - case MEXP_TIMEOUT: -+ set_ssh_unexpected_timeout ("\"ssh -R\" output"); - mexp_close (h); -- set_ssh_error ("timeout waiting for ssh -R output"); - return NULL; - - case MEXP_ERROR: -- set_ssh_error ("mexp_expect: %m"); -+ set_ssh_mexp_error ("mexp_expect"); - mexp_close (h); - return NULL; - - case MEXP_PCRE_ERROR: -- set_ssh_error ("PCRE error: %d\n", mexp_get_pcre_error (h)); -+ set_ssh_pcre_error (); - mexp_close (h); - return NULL; - } -@@ -909,19 +926,19 @@ wait_for_prompt (mexp_h *h) - return 0; - - case MEXP_EOF: -- set_ssh_error ("unexpected end of file waiting for prompt"); -+ set_ssh_unexpected_eof ("command prompt"); - return -1; - - case MEXP_TIMEOUT: -- set_ssh_error ("timeout waiting for prompt"); -+ set_ssh_unexpected_timeout ("command prompt"); - return -1; - - case MEXP_ERROR: -- set_ssh_error ("mexp_expect: %m"); -+ set_ssh_mexp_error ("mexp_expect"); - return -1; - - case MEXP_PCRE_ERROR: -- set_ssh_error ("PCRE error: %d\n", mexp_get_pcre_error (h)); -+ set_ssh_pcre_error (); - return -1; - } - -@@ -947,7 +964,7 @@ start_remote_connection (struct config *config, - - /* Create the remote directory. */ - if (mexp_printf (h, "mkdir %s\n", remote_dir) == -1) { -- set_ssh_error ("mexp_printf: %m"); -+ set_ssh_mexp_error ("mexp_printf"); - goto error; - } - -@@ -957,7 +974,7 @@ start_remote_connection (struct config *config, - /* Write some useful config information to files in the remote directory. */ - if (mexp_printf (h, "echo '%s' > %s/name\n", - config->guestname, remote_dir) == -1) { -- set_ssh_error ("mexp_printf: %m"); -+ set_ssh_mexp_error ("mexp_printf"); - goto error; - } - -@@ -965,7 +982,7 @@ start_remote_connection (struct config *config, - goto error; - - if (mexp_printf (h, "date > %s/time\n", remote_dir) == -1) { -- set_ssh_error ("mexp_printf: %m"); -+ set_ssh_mexp_error ("mexp_printf"); - goto error; - } - -@@ -980,7 +997,7 @@ start_remote_connection (struct config *config, - remote_dir, magic, - libvirt_xml, - magic) == -1) { -- set_ssh_error ("mexp_printf: %m"); -+ set_ssh_mexp_error ("mexp_printf"); - goto error; - } - -@@ -995,7 +1012,7 @@ start_remote_connection (struct config *config, - remote_dir, magic, - wrapper_script, - magic) == -1) { -- set_ssh_error ("mexp_printf: %m"); -+ set_ssh_mexp_error ("mexp_printf"); - goto error; - } - -@@ -1003,7 +1020,7 @@ start_remote_connection (struct config *config, - goto error; - - if (mexp_printf (h, "chmod +x %s/virt-v2v-wrapper.sh\n", remote_dir) == -1) { -- set_ssh_error ("mexp_printf: %m"); -+ set_ssh_mexp_error ("mexp_printf"); - goto error; - } - -@@ -1020,7 +1037,7 @@ start_remote_connection (struct config *config, - remote_dir, magic, - dmesg, - magic) == -1) { -- set_ssh_error ("mexp_printf: %m"); -+ set_ssh_mexp_error ("mexp_printf"); - goto error; - } - --- -1.8.3.1 - diff --git a/SOURCES/0132-inspect-get-windows-drive-letters-for-GPT-disks.patch b/SOURCES/0132-inspect-get-windows-drive-letters-for-GPT-disks.patch deleted file mode 100644 index 5cda32c..0000000 --- a/SOURCES/0132-inspect-get-windows-drive-letters-for-GPT-disks.patch +++ /dev/null @@ -1,159 +0,0 @@ -From 3d23c51e654f479de8ddbfd1cd7e44753d4bb19d Mon Sep 17 00:00:00 2001 -From: Dawid Zamirski -Date: Sat, 6 Feb 2016 11:50:05 -0500 -Subject: [PATCH] inspect: get windows drive letters for GPT disks. - -This patch updates the guestfs_inspect_get_drive_mappings API call to -also return drive letters for GPT paritions. Previously this worked -only for MBR partitions. This is achieved by matching the GPT partition -GUID with the info stored in the blob from -HKLM\SYSTEM\MountedDevices\DosDevices keys. For GPT partions this blob -contains a "DMIO:ID:" prefix followed by a 16 byte binary GUID. - -(cherry picked from commit 7cb28488a6b974c86a9dd0264d892cd01739c36e) ---- - src/inspect-fs-windows.c | 96 +++++++++++++++++++++++++++++++++++++++++++++++- - 1 file changed, 94 insertions(+), 2 deletions(-) - -diff --git a/src/inspect-fs-windows.c b/src/inspect-fs-windows.c -index 7e3ead5..f8717fc 100644 ---- a/src/inspect-fs-windows.c -+++ b/src/inspect-fs-windows.c -@@ -25,6 +25,7 @@ - #include - #include - #include -+#include - - #ifdef HAVE_ENDIAN_H - #include -@@ -57,6 +58,8 @@ static int check_windows_arch (guestfs_h *g, struct inspect_fs *fs); - static int check_windows_software_registry (guestfs_h *g, struct inspect_fs *fs); - static int check_windows_system_registry (guestfs_h *g, struct inspect_fs *fs); - static char *map_registry_disk_blob (guestfs_h *g, const void *blob); -+static char *map_registry_disk_blob_gpt (guestfs_h *g, const void *blob); -+static char *extract_guid_from_registry_blob (guestfs_h *g, const void *blob); - - /* XXX Handling of boot.ini in the Perl version was pretty broken. It - * essentially didn't do anything for modern Windows guests. -@@ -386,6 +389,7 @@ check_windows_system_registry (guestfs_h *g, struct inspect_fs *fs) - int r; - size_t len = strlen (fs->windows_systemroot) + 64; - char system[len]; -+ char gpt_prefix[] = "DMIO:ID:"; - snprintf (system, len, "%s/system32/config/system", - fs->windows_systemroot); - -@@ -490,12 +494,18 @@ check_windows_system_registry (guestfs_h *g, struct inspect_fs *fs) - CLEANUP_FREE char *blob = NULL; - char *device; - int64_t type; -+ bool is_gpt; - - type = guestfs_hivex_value_type (g, v); - blob = guestfs_hivex_value_value (g, v, &len); -- if (blob != NULL && type == 3 && len == 12) { -+ is_gpt = memcmp (blob, gpt_prefix, 8) == 0; -+ if (blob != NULL && type == 3 && (len == 12 || is_gpt)) { - /* Try to map the blob to a known disk and partition. */ -- device = map_registry_disk_blob (g, blob); -+ if (is_gpt) -+ device = map_registry_disk_blob_gpt (g, blob); -+ else -+ device = map_registry_disk_blob (g, blob); -+ - if (device != NULL) { - fs->drive_mappings[count++] = safe_strndup (g, &key[12], 1); - fs->drive_mappings[count++] = device; -@@ -605,6 +615,88 @@ map_registry_disk_blob (guestfs_h *g, const void *blob) - return safe_asprintf (g, "%s%d", devices[i], partitions->val[j].part_num); - } - -+/* Matches Windows registry HKLM\SYSYTEM\MountedDevices\DosDevices blob to -+ * to libguestfs GPT partition device. For GPT disks, the blob is made of -+ * "DMIO:ID:" prefix followed by the GPT partition GUID. -+ */ -+static char * -+map_registry_disk_blob_gpt (guestfs_h *g, const void *blob) -+{ -+ CLEANUP_FREE_STRING_LIST char **parts = NULL; -+ CLEANUP_FREE char *blob_guid = extract_guid_from_registry_blob (g, blob); -+ size_t i; -+ -+ parts = guestfs_list_partitions (g); -+ if (parts == NULL) -+ return NULL; -+ -+ for (i = 0; parts[i] != NULL; ++i) { -+ CLEANUP_FREE char *fs_guid = NULL; -+ int partnum; -+ CLEANUP_FREE char *device = NULL; -+ CLEANUP_FREE char *type = NULL; -+ -+ partnum = guestfs_part_to_partnum (g, parts[i]); -+ if (partnum == -1) -+ continue; -+ -+ device = guestfs_part_to_dev (g, parts[i]); -+ if (device == NULL) -+ continue; -+ -+ type = guestfs_part_get_parttype (g, device); -+ if (type == NULL) -+ continue; -+ -+ if (STRCASENEQ (type, "gpt")) -+ continue; -+ -+ /* get the GPT parition GUID from the partition block device */ -+ fs_guid = guestfs_part_get_gpt_guid (g, device, partnum); -+ if (fs_guid == NULL) -+ continue; -+ -+ /* if both GUIDs match, we have found the mapping for our device */ -+ if (STRCASEEQ (fs_guid, blob_guid)) -+ return safe_strdup (g, parts[i]); -+ } -+ -+ return NULL; -+} -+ -+/* Extracts the binary GUID stored in blob from Windows registry -+ * HKLM\SYSTYEM\MountedDevices\DosDevices value and converts it to a -+ * GUID string so that it can be matched against libguestfs partition -+ * device GPT GUID. -+ */ -+static char * -+extract_guid_from_registry_blob (guestfs_h *g, const void *blob) -+{ -+ char guid_bytes[16]; -+ uint32_t data1; -+ uint16_t data2, data3; -+ uint64_t data4; -+ -+ /* get the GUID bytes from blob (skip 8 byte "DMIO:ID:" prefix) */ -+ memcpy (&guid_bytes, (char *) blob + 8, sizeof (guid_bytes)); -+ -+ /* copy relevant sections from blob to respective ints */ -+ memcpy (&data1, guid_bytes, sizeof (data1)); -+ memcpy (&data2, guid_bytes + 4, sizeof (data2)); -+ memcpy (&data3, guid_bytes + 6, sizeof (data3)); -+ memcpy (&data4, guid_bytes + 8, sizeof (data4)); -+ -+ /* ensure proper endianness */ -+ data1 = le32toh (data1); -+ data2 = le16toh (data2); -+ data3 = le16toh (data3); -+ data4 = be64toh (data4); -+ -+ return safe_asprintf (g, -+ "%08" PRIX32 "-%04" PRIX16 "-%04" PRIX16 "-%04" PRIX64 "-%012" PRIX64, -+ data1, data2, data3, data4 >> 48, data4 & 0xffffffffffff); -+} -+ - /* NB: This function DOES NOT test for the existence of the file. It - * will return non-NULL even if the file/directory does not exist. - * You have to call guestfs_is_file{,_opts} etc. --- -1.8.3.1 - diff --git a/SOURCES/0133-p2v-Refactor-into-get_blockdev_size-and-get_blockdev.patch b/SOURCES/0133-p2v-Refactor-into-get_blockdev_size-and-get_blockdev.patch deleted file mode 100644 index b0a9675..0000000 --- a/SOURCES/0133-p2v-Refactor-into-get_blockdev_size-and-get_blockdev.patch +++ /dev/null @@ -1,180 +0,0 @@ -From a9d9b7d3cf9fa9928498273974830e9ba2002e5f Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Fri, 24 Jun 2016 14:45:05 +0100 -Subject: [PATCH] p2v: Refactor into get_blockdev_size and get_blockdev_model - functions. - -This is just refactoring, but it reveals and fixes a bug too. The -size_gb field was left as NULL when the --test-disk option was used. -Apparently passing NULL to gtk_list_store_set is fine, but just in -case I replaced it with "". - -(cherry picked from commit 68ff3ffd1de7b72255ee5098c0bfef90e6236cb5) ---- - p2v/gui.c | 40 ++++++++----------------------------- - p2v/p2v.h | 2 ++ - p2v/utils.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 75 insertions(+), 32 deletions(-) - -diff --git a/p2v/gui.c b/p2v/gui.c -index 7414037..1bae4d8 100644 ---- a/p2v/gui.c -+++ b/p2v/gui.c -@@ -869,47 +869,23 @@ populate_disks (GtkTreeView *disks_list) - G_TYPE_STRING, G_TYPE_STRING); - if (all_disks != NULL) { - for (i = 0; all_disks[i] != NULL; ++i) { -- CLEANUP_FREE char *size_filename = NULL; -- CLEANUP_FREE char *model_filename = NULL; -- CLEANUP_FREE char *size_str = NULL; -+ uint64_t size; - CLEANUP_FREE char *size_gb = NULL; - CLEANUP_FREE char *model = NULL; -- uint64_t size; - -- if (asprintf (&size_filename, "/sys/block/%s/size", -- all_disks[i]) == -1) { -- perror ("asprintf"); -- exit (EXIT_FAILURE); -- } -- if (g_file_get_contents (size_filename, &size_str, NULL, NULL) && -- sscanf (size_str, "%" SCNu64, &size) == 1) { -- size /= 2*1024*1024; /* size from kernel is given in sectors? */ -- if (asprintf (&size_gb, "%" PRIu64, size) == -1) { -- perror ("asprintf"); -- exit (EXIT_FAILURE); -- } -- } -- -- if (asprintf (&model_filename, "/sys/block/%s/device/model", -- all_disks[i]) == -1) { -- perror ("asprintf"); -- exit (EXIT_FAILURE); -- } -- if (g_file_get_contents (model_filename, &model, NULL, NULL)) { -- /* Need to chomp trailing \n from the content. */ -- size_t len = strlen (model); -- if (len > 0 && model[len-1] == '\n') -- model[len-1] = '\0'; -- } else { -- model = strdup (""); -+ if (all_disks[i][0] != '/') { /* not using --test-disk */ -+ size = get_blockdev_size (all_disks[i]); -+ if (asprintf (&size_gb, "%" PRIu64, size) == -1) -+ error (EXIT_FAILURE, errno, "asprintf"); -+ model = get_blockdev_model (all_disks[i]); - } - - gtk_list_store_append (disks_store, &iter); - gtk_list_store_set (disks_store, &iter, - DISKS_COL_CONVERT, TRUE, - DISKS_COL_DEVICE, all_disks[i], -- DISKS_COL_SIZE, size_gb, -- DISKS_COL_MODEL, model, -+ DISKS_COL_SIZE, size_gb ? size_gb : "", -+ DISKS_COL_MODEL, model ? model : "", - -1); - } - } -diff --git a/p2v/p2v.h b/p2v/p2v.h -index 49c97b6..40b05b8 100644 ---- a/p2v/p2v.h -+++ b/p2v/p2v.h -@@ -131,6 +131,8 @@ extern mexp_h *start_remote_connection (struct config *, const char *remote_dir, - extern const char *get_ssh_error (void); - - /* utils.c */ -+extern uint64_t get_blockdev_size (const char *dev); -+extern char *get_blockdev_model (const char *dev); - extern char *get_if_addr (const char *if_name); - extern char *get_if_vendor (const char *if_name, int truncate); - extern void wait_network_online (const struct config *); -diff --git a/p2v/utils.c b/p2v/utils.c -index 3781a8d..18c2b7c 100644 ---- a/p2v/utils.c -+++ b/p2v/utils.c -@@ -20,9 +20,12 @@ - - #include - #include -+#include - #include - #include - #include -+#include -+#include - #include - #include - -@@ -38,6 +41,68 @@ - } \ - } while (0) - -+/** -+ * Return size of a block device, from F/size>. -+ * -+ * This function always succeeds, or else exits (since we expect -+ * C to always be valid and the C file to always exist). -+ */ -+uint64_t -+get_blockdev_size (const char *dev) -+{ -+ CLEANUP_FCLOSE FILE *fp = NULL; -+ CLEANUP_FREE char *path = NULL; -+ CLEANUP_FREE char *size_str = NULL; -+ size_t len; -+ uint64_t size; -+ -+ if (asprintf (&path, "/sys/block/%s/size", dev) == -1) -+ error (EXIT_FAILURE, errno, "asprintf"); -+ -+ fp = fopen (path, "r"); -+ if (fp == NULL) -+ error (EXIT_FAILURE, errno, "fopen: %s", path); -+ if (getline (&size_str, &len, fp) == -1) -+ error (EXIT_FAILURE, errno, "getline: %s", path); -+ -+ if (sscanf (size_str, "%" SCNu64, &size) != 1) -+ error (EXIT_FAILURE, 0, "cannot parse %s: %s", path, size_str); -+ -+ size /= 2*1024*1024; /* size from kernel is given in sectors? */ -+ return size; -+} -+ -+/** -+ * Return model of a block device, from F/device/model>. -+ * -+ * Returns C if the file was not found. The caller must -+ * free the returned string. -+ */ -+char * -+get_blockdev_model (const char *dev) -+{ -+ CLEANUP_FCLOSE FILE *fp = NULL; -+ CLEANUP_FREE char *path = NULL; -+ char *model = NULL; -+ size_t len = 0; -+ ssize_t n; -+ -+ if (asprintf (&path, "/sys/block/%s/device/model", dev) == -1) -+ error (EXIT_FAILURE, errno, "asprintf"); -+ fp = fopen (path, "r"); -+ if (fp == NULL) { -+ perror (path); -+ return NULL; -+ } -+ if ((n = getline (&model, &len, fp)) == -1) { -+ perror (path); -+ free (model); -+ return NULL; -+ } -+ CHOMP (model, n); -+ return model; -+} -+ - /* Return contents of /sys/class/net//address (if found). */ - char * - get_if_addr (const char *if_name) --- -1.8.3.1 - diff --git a/SOURCES/0134-p2v-Combine-size-model-columns-into-the-device-colum.patch b/SOURCES/0134-p2v-Combine-size-model-columns-into-the-device-colum.patch deleted file mode 100644 index b29a794..0000000 --- a/SOURCES/0134-p2v-Combine-size-model-columns-into-the-device-colum.patch +++ /dev/null @@ -1,154 +0,0 @@ -From 4ada7cd307f4cfb177e0f033eae05592030fc1e0 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Fri, 24 Jun 2016 14:53:52 +0100 -Subject: [PATCH] p2v: Combine size & model columns into the device column. - -In the GUI disks block, instead of using separate "Size" and "Model" -columns, combine that information into a markup column under "Device". - -To make the GUI look consistent I also had to change the removables -"Device" column to be a markup column and embolden the device name -there too. - -(cherry picked from commit 6aba5a49448d8ed9776164005080620d37bb97e0) ---- - p2v/gui.c | 51 ++++++++++++++++++++++----------------------------- - p2v/virt-p2v.pod | 8 +++++--- - 2 files changed, 27 insertions(+), 32 deletions(-) - -diff --git a/p2v/gui.c b/p2v/gui.c -index 1bae4d8..49c703d 100644 ---- a/p2v/gui.c -+++ b/p2v/gui.c -@@ -503,8 +503,6 @@ static uint64_t get_memory_from_conv_dlg (void); - enum { - DISKS_COL_CONVERT = 0, - DISKS_COL_DEVICE, -- DISKS_COL_SIZE, -- DISKS_COL_MODEL, - NUM_DISKS_COLS, - }; - -@@ -859,33 +857,39 @@ static void - populate_disks (GtkTreeView *disks_list) - { - GtkListStore *disks_store; -- GtkCellRenderer *disks_col_convert, *disks_col_device, -- *disks_col_size, *disks_col_model; -+ GtkCellRenderer *disks_col_convert, *disks_col_device; - GtkTreeIter iter; - size_t i; - - disks_store = gtk_list_store_new (NUM_DISKS_COLS, -- G_TYPE_BOOLEAN, G_TYPE_STRING, -- G_TYPE_STRING, G_TYPE_STRING); -+ G_TYPE_BOOLEAN, G_TYPE_STRING); - if (all_disks != NULL) { - for (i = 0; all_disks[i] != NULL; ++i) { - uint64_t size; - CLEANUP_FREE char *size_gb = NULL; - CLEANUP_FREE char *model = NULL; -+ CLEANUP_FREE char *device_descr = NULL; - - if (all_disks[i][0] != '/') { /* not using --test-disk */ - size = get_blockdev_size (all_disks[i]); -- if (asprintf (&size_gb, "%" PRIu64, size) == -1) -+ if (asprintf (&size_gb, "%" PRIu64 "G", size) == -1) - error (EXIT_FAILURE, errno, "asprintf"); - model = get_blockdev_model (all_disks[i]); - } - -+ if (asprintf (&device_descr, -+ "%s\n" -+ "" -+ "%s %s" -+ "\n", -+ all_disks[i], -+ size_gb ? size_gb : "", model ? model : "") == -1) -+ error (EXIT_FAILURE, errno, "asprintf"); -+ - gtk_list_store_append (disks_store, &iter); - gtk_list_store_set (disks_store, &iter, - DISKS_COL_CONVERT, TRUE, -- DISKS_COL_DEVICE, all_disks[i], -- DISKS_COL_SIZE, size_gb ? size_gb : "", -- DISKS_COL_MODEL, model ? model : "", -+ DISKS_COL_DEVICE, device_descr, - -1); - } - } -@@ -905,25 +909,9 @@ populate_disks (GtkTreeView *disks_list) - -1, - _("Device"), - disks_col_device, -- "text", DISKS_COL_DEVICE, -+ "markup", DISKS_COL_DEVICE, - NULL); - gtk_cell_renderer_set_alignment (disks_col_device, 0.0, 0.0); -- disks_col_size = gtk_cell_renderer_text_new (); -- gtk_tree_view_insert_column_with_attributes (disks_list, -- -1, -- _("Size (GB)"), -- disks_col_size, -- "text", DISKS_COL_SIZE, -- NULL); -- gtk_cell_renderer_set_alignment (disks_col_size, 0.0, 0.0); -- disks_col_model = gtk_cell_renderer_text_new (); -- gtk_tree_view_insert_column_with_attributes (disks_list, -- -1, -- _("Model"), -- disks_col_model, -- "text", DISKS_COL_MODEL, -- NULL); -- gtk_cell_renderer_set_alignment (disks_col_model, 0.0, 0.0); - - g_signal_connect (disks_col_convert, "toggled", - G_CALLBACK (toggled), disks_store); -@@ -941,10 +929,15 @@ populate_removable (GtkTreeView *removable_list) - G_TYPE_BOOLEAN, G_TYPE_STRING); - if (all_removable != NULL) { - for (i = 0; all_removable[i] != NULL; ++i) { -+ CLEANUP_FREE char *device_descr = NULL; -+ -+ if (asprintf (&device_descr, "%s\n", all_removable[i]) == -1) -+ error (EXIT_FAILURE, errno, "asprintf"); -+ - gtk_list_store_append (removable_store, &iter); - gtk_list_store_set (removable_store, &iter, - REMOVABLE_COL_CONVERT, TRUE, -- REMOVABLE_COL_DEVICE, all_removable[i], -+ REMOVABLE_COL_DEVICE, device_descr, - -1); - } - } -@@ -964,7 +957,7 @@ populate_removable (GtkTreeView *removable_list) - -1, - _("Device"), - removable_col_device, -- "text", REMOVABLE_COL_DEVICE, -+ "markup", REMOVABLE_COL_DEVICE, - NULL); - gtk_cell_renderer_set_alignment (removable_col_device, 0.0, 0.0); - -diff --git a/p2v/virt-p2v.pod b/p2v/virt-p2v.pod -index b996541..032a480 100644 ---- a/p2v/virt-p2v.pod -+++ b/p2v/virt-p2v.pod -@@ -194,9 +194,11 @@ settings is fine. - ─ ─ ───────────────────────────────────────┐ - Fixed hard disks │ - │ -- Convert Device Size (GB) Model │ -- [✔] sda 1024 HITACHI │ -- [✔] sdb 119 HITACHI │ -+ Convert Device │ -+ [✔] sda │ -+ 1024G HITACHI │ -+ [✔] sdb │ -+ 119G HITACHI │ - │ - - Normally you would want to convert all hard disks. If you want --- -1.8.3.1 - diff --git a/SOURCES/0135-p2v-Display-serial-number-of-fixed-disks-RHBZ-855058.patch b/SOURCES/0135-p2v-Display-serial-number-of-fixed-disks-RHBZ-855058.patch deleted file mode 100644 index e7a8483..0000000 --- a/SOURCES/0135-p2v-Display-serial-number-of-fixed-disks-RHBZ-855058.patch +++ /dev/null @@ -1,184 +0,0 @@ -From 97add8b77aebc8032b7d186f36e264e1d9ffa733 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Fri, 24 Jun 2016 15:28:46 +0100 -Subject: [PATCH] p2v: Display serial number of fixed disks (RHBZ#855058). - -Use "lsblk -o serial" to get the serial number of each fixed disk, and -if it is available display that in the GUI. - -(cherry picked from commit 9270a27650abaf586070c51cb90b6a77ec13e0cf) ---- - p2v/dependencies.m4 | 8 ++++---- - p2v/gui.c | 8 ++++++-- - p2v/p2v.h | 1 + - p2v/utils.c | 34 ++++++++++++++++++++++++++++++++++ - p2v/virt-p2v.pod | 2 ++ - 5 files changed, 47 insertions(+), 6 deletions(-) - -diff --git a/p2v/dependencies.m4 b/p2v/dependencies.m4 -index 6cf2961..80d6c92 100644 ---- a/p2v/dependencies.m4 -+++ b/p2v/dependencies.m4 -@@ -30,6 +30,7 @@ ifelse(REDHAT,1, - /usr/bin/qemu-nbd - curl - ethtool -+ util-linux - - dnl The hwdata package contains PCI IDs, used by virt-p2v to display - dnl network vendor information (RHBZ#855059). -@@ -39,7 +40,6 @@ ifelse(REDHAT,1, - pciutils - hdparm - smartmontools -- util-linux - - dnl X11 environment - xterm -@@ -72,11 +72,11 @@ ifelse(DEBIAN,1, - qemu-utils - curl - ethtool -+ util-linux - hwdata - pciutils - hdparm - smartmontools -- util-linux - xorg - xterm - xserver-xorg-video-all -@@ -97,11 +97,11 @@ ifelse(ARCHLINUX,1, - qemu - curl - ethtool -+ util-linux - hwdata - pciutils - hdparm - smartmontools -- util-linux - xterm - xorg-xinit - xorg-server -@@ -123,11 +123,11 @@ ifelse(SUSE,1, - openssh - curl - ethtool -+ util-linux - hwdata - pciutils - hdparm - smartmontools -- util-linux - xinit - xorg-x11-server - xterm -diff --git a/p2v/gui.c b/p2v/gui.c -index 49c703d..58e9ea3 100644 ---- a/p2v/gui.c -+++ b/p2v/gui.c -@@ -868,6 +868,7 @@ populate_disks (GtkTreeView *disks_list) - uint64_t size; - CLEANUP_FREE char *size_gb = NULL; - CLEANUP_FREE char *model = NULL; -+ CLEANUP_FREE char *serial = NULL; - CLEANUP_FREE char *device_descr = NULL; - - if (all_disks[i][0] != '/') { /* not using --test-disk */ -@@ -875,15 +876,18 @@ populate_disks (GtkTreeView *disks_list) - if (asprintf (&size_gb, "%" PRIu64 "G", size) == -1) - error (EXIT_FAILURE, errno, "asprintf"); - model = get_blockdev_model (all_disks[i]); -+ serial = get_blockdev_serial (all_disks[i]); - } - - if (asprintf (&device_descr, - "%s\n" - "" -- "%s %s" -+ "%s %s\n" -+ "%s%s" - "\n", - all_disks[i], -- size_gb ? size_gb : "", model ? model : "") == -1) -+ size_gb ? size_gb : "", model ? model : "", -+ serial ? "s/n " : "", serial ? serial : "") == -1) - error (EXIT_FAILURE, errno, "asprintf"); - - gtk_list_store_append (disks_store, &iter); -diff --git a/p2v/p2v.h b/p2v/p2v.h -index 40b05b8..3e75690 100644 ---- a/p2v/p2v.h -+++ b/p2v/p2v.h -@@ -133,6 +133,7 @@ extern const char *get_ssh_error (void); - /* utils.c */ - extern uint64_t get_blockdev_size (const char *dev); - extern char *get_blockdev_model (const char *dev); -+extern char *get_blockdev_serial (const char *dev); - extern char *get_if_addr (const char *if_name); - extern char *get_if_vendor (const char *if_name, int truncate); - extern void wait_network_online (const struct config *); -diff --git a/p2v/utils.c b/p2v/utils.c -index 18c2b7c..c9fbd2f 100644 ---- a/p2v/utils.c -+++ b/p2v/utils.c -@@ -103,6 +103,40 @@ get_blockdev_model (const char *dev) - return model; - } - -+/** -+ * Return the serial number of a block device. -+ * -+ * This is found using the lsblk command. -+ * -+ * Returns C if we could not get the serial number. The caller -+ * must free the returned string. -+ */ -+char * -+get_blockdev_serial (const char *dev) -+{ -+ CLEANUP_PCLOSE FILE *fp = NULL; -+ CLEANUP_FREE char *cmd = NULL; -+ char *serial = NULL; -+ size_t len = 0; -+ ssize_t n; -+ -+ if (asprintf (&cmd, "lsblk -o serial /dev/%s --nodeps --noheadings", -+ dev) == -1) -+ error (EXIT_FAILURE, errno, "asprintf"); -+ fp = popen (cmd, "r"); -+ if (fp == NULL) { -+ perror (cmd); -+ return NULL; -+ } -+ if ((n = getline (&serial, &len, fp)) == -1) { -+ perror (cmd); -+ free (serial); -+ return NULL; -+ } -+ CHOMP (serial, n); -+ return serial; -+} -+ - /* Return contents of /sys/class/net//address (if found). */ - char * - get_if_addr (const char *if_name) -diff --git a/p2v/virt-p2v.pod b/p2v/virt-p2v.pod -index 032a480..421925f 100644 ---- a/p2v/virt-p2v.pod -+++ b/p2v/virt-p2v.pod -@@ -197,8 +197,10 @@ settings is fine. - Convert Device │ - [✔] sda │ - 1024G HITACHI │ -+ s/n 12345 │ - [✔] sdb │ - 119G HITACHI │ -+ s/n 12346 │ - │ - - Normally you would want to convert all hard disks. If you want --- -1.8.3.1 - diff --git a/SOURCES/0136-p2v-Make-the-conversion-dialog-slightly-higher.patch b/SOURCES/0136-p2v-Make-the-conversion-dialog-slightly-higher.patch deleted file mode 100644 index cc2ac09..0000000 --- a/SOURCES/0136-p2v-Make-the-conversion-dialog-slightly-higher.patch +++ /dev/null @@ -1,28 +0,0 @@ -From ca78e55220627878ce3808615953ec9ea8cba16c Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Fri, 24 Jun 2016 22:28:40 +0100 -Subject: [PATCH] p2v: Make the conversion dialog slightly higher. - -Otherwise the information pane is smaller than its content. - -(cherry picked from commit 40448d6d0d63d79da540c2a9e5eb098b537ede50) ---- - p2v/gui.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/p2v/gui.c b/p2v/gui.c -index 58e9ea3..5ffe3d8 100644 ---- a/p2v/gui.c -+++ b/p2v/gui.c -@@ -541,7 +541,7 @@ create_conversion_dialog (struct config *config) - /* XXX It would be nice not to have to set this explicitly, but - * if we don't then Gtk chooses a very small window. - */ -- gtk_widget_set_size_request (conv_dlg, 900, 560); -+ gtk_widget_set_size_request (conv_dlg, 900, 600); - - /* The main dialog area. */ - hbox = gtk_hbox_new (TRUE, 1); --- -1.8.3.1 - diff --git a/SOURCES/0137-p2v-Fix-timeout-error-when-connecting-to-unresponsiv.patch b/SOURCES/0137-p2v-Fix-timeout-error-when-connecting-to-unresponsiv.patch deleted file mode 100644 index fa100fe..0000000 --- a/SOURCES/0137-p2v-Fix-timeout-error-when-connecting-to-unresponsiv.patch +++ /dev/null @@ -1,106 +0,0 @@ -From 0d49c72d27dd400062c5632a14c4ff225de22832 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Mon, 27 Jun 2016 10:16:51 +0100 -Subject: [PATCH] p2v: Fix timeout error when connecting to unresponsive ssh - server (RHBZ#1350363). - -If an ssh server is completely unresponsive (ie. it doesn't even send -back ICMP errors), then eventually ssh times out after ConnectTimeout -seconds [ConnectTimeout is an ssh option]. - -Unfortunately the miniexpect timeout (default 60 seconds) was less -than ConnectTimeout so we never saw the ssh error. Instead we would -see the internal error: - - remote server closed the connection unexpectedly, - waiting for: password prompt - -This commit sets the ssh ConnectTimeout to an explicit value, and sets -the miniexpect timeout to be 20 seconds larger than ConnectTimeout, so -that in most cases we will see the ssh error message before miniexpect -times out. - -Thanks: Ming Xie for finding and diagnosing the problem -(cherry picked from commit 0b836c40f2674e8632212363b9ad4f7781e5622e) ---- - p2v/ssh.c | 29 +++++++++++++++++++++++++++-- - 1 file changed, 27 insertions(+), 2 deletions(-) - -diff --git a/p2v/ssh.c b/p2v/ssh.c -index 93c4c55..f4adde4 100644 ---- a/p2v/ssh.c -+++ b/p2v/ssh.c -@@ -57,6 +57,8 @@ - #include "miniexpect.h" - #include "p2v.h" - -+#define SSH_TIMEOUT 60 /* seconds */ -+ - char *v2v_version = NULL; - char **input_drivers = NULL; - char **output_drivers = NULL; -@@ -309,6 +311,7 @@ start_ssh (struct config *config, char **extra_args, int wait_prompt) - { - size_t i, j, nr_args, count; - char port_str[64]; -+ char connect_timeout_str[128]; - CLEANUP_FREE /* [sic] */ const char **args = NULL; - mexp_h *h; - const int ovecsize = 12; -@@ -328,9 +331,9 @@ start_ssh (struct config *config, char **extra_args, int wait_prompt) - nr_args = guestfs_int_count_strings (extra_args); - - if (using_password_auth) -- nr_args += 11; -- else - nr_args += 13; -+ else -+ nr_args += 15; - args = malloc (sizeof (char *) * nr_args); - if (args == NULL) { - perror ("malloc"); -@@ -346,6 +349,10 @@ start_ssh (struct config *config, char **extra_args, int wait_prompt) - args[j++] = config->username ? config->username : "root"; - args[j++] = "-o"; /* Host key will always be novel. */ - args[j++] = "StrictHostKeyChecking=no"; -+ args[j++] = "-o"; /* ConnectTimeout */ -+ snprintf (connect_timeout_str, sizeof connect_timeout_str, -+ "ConnectTimeout=%d", SSH_TIMEOUT); -+ args[j++] = connect_timeout_str; - if (using_password_auth) { - /* Only use password authentication. */ - args[j++] = "-o"; -@@ -366,12 +373,30 @@ start_ssh (struct config *config, char **extra_args, int wait_prompt) - args[j++] = NULL; - assert (j == nr_args); - -+#if DEBUG_STDERR && 0 -+ fputs ("ssh command: ", stderr); -+ for (i = 0; i < nr_args - 1; ++i) { -+ if (i > 0) fputc (' ', stderr); -+ fputs (args[i], stderr); -+ } -+ fputc ('\n', stderr); -+#endif -+ -+ /* Create the miniexpect handle. */ - h = mexp_spawnv ("ssh", (char **) args); - if (h == NULL) { - set_ssh_internal_error ("ssh: mexp_spawnv: %m"); - return NULL; - } - -+ /* We want the ssh ConnectTimeout to be less than the miniexpect -+ * timeout, so that if the server is completely unresponsive we -+ * still see the error from ssh, not a timeout from miniexpect. The -+ * obvious solution to this is to set ConnectTimeout (above) and to -+ * set the miniexpect timeout to be a little bit larger. -+ */ -+ mexp_set_timeout (h, SSH_TIMEOUT + 20); -+ - if (using_password_auth && - config->password && strlen (config->password) > 0) { - CLEANUP_FREE char *ssh_message = NULL; --- -1.8.3.1 - diff --git a/SOURCES/0138-p2v-virt-p2v-make-disk-passes-through-no-warn-if-par.patch b/SOURCES/0138-p2v-virt-p2v-make-disk-passes-through-no-warn-if-par.patch deleted file mode 100644 index cd9da22..0000000 --- a/SOURCES/0138-p2v-virt-p2v-make-disk-passes-through-no-warn-if-par.patch +++ /dev/null @@ -1,88 +0,0 @@ -From e46c64da93c82c765a36c75df65094d0221f99fc Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Mon, 27 Jun 2016 11:18:43 +0100 -Subject: [PATCH] p2v: virt-p2v-make-disk passes through --no-warn-if-partition - to virt-builder. - -See: https://bugzilla.redhat.com/show_bug.cgi?id=1342337#c4 - -Thanks: Junqin Zhou -(cherry picked from commit 07137ea565653ca22e055cef09a08add6ad5f1c9) ---- - p2v/virt-p2v-make-disk.in | 17 +++++++++++++---- - p2v/virt-p2v-make-disk.pod | 7 +++++++ - 2 files changed, 20 insertions(+), 4 deletions(-) - -diff --git a/p2v/virt-p2v-make-disk.in b/p2v/virt-p2v-make-disk.in -index d58e7f1..cbbc9ff 100644 ---- a/p2v/virt-p2v-make-disk.in -+++ b/p2v/virt-p2v-make-disk.in -@@ -24,7 +24,7 @@ version="@PACKAGE_VERSION@" - - TEMP=`getopt \ - -o o:V \ -- --long help,inject-ssh-identity:,output:,verbose,version \ -+ --long help,inject-ssh-identity:,no-warn-if-partition,output:,verbose,version \ - -n $program -- "$@"` - if [ $? != 0 ]; then - echo "$program: problem parsing the command line arguments" -@@ -35,6 +35,7 @@ eval set -- "$TEMP" - output= - upload= - verbose= -+declare -a passthru - - usage () - { -@@ -57,11 +58,18 @@ while true; do - set +x - verbose=1 - shift;; -+ -+ # virt-builder parameters that are passed through. -+ --no-warn-if-partition) -+ passthru[${#passthru[*]}]="$1" -+ shift;; -+ -+ # help etc. -+ --help) -+ usage 0;; - -V|--version) - echo "$program $version" - exit 0;; -- --help) -- usage 0;; - --) - shift - break;; -@@ -206,7 +214,8 @@ virt-builder "$osversion" \ - s/^[Login]/[Login]\nReserveVT=1\n/ - ' \ - $upload \ -- $extra_args -+ $extra_args \ -+ "${passthru[@]}" - - # We have to do this so the cleanup() handler runs. - exit $? -diff --git a/p2v/virt-p2v-make-disk.pod b/p2v/virt-p2v-make-disk.pod -index d5a5db5..2e1bffb 100644 ---- a/p2v/virt-p2v-make-disk.pod -+++ b/p2v/virt-p2v-make-disk.pod -@@ -99,6 +99,13 @@ Display help. - Add an SSH identity (private key) file into the image. - See L above. - -+=item B<--no-warn-if-partition> -+ -+Normally you should not write to a partition on a USB drive (ie. don't -+use S>, use S> to make a bootable USB -+drive). If you do this, virt-builder prints a warning. This option -+suppresses that warning. -+ - =item B<-o> OUTPUT - - =item B<--output> OUTPUT --- -1.8.3.1 - diff --git a/SOURCES/0139-p2v-Add-install-option-to-virt-p2v-make-disk-virt-p2.patch b/SOURCES/0139-p2v-Add-install-option-to-virt-p2v-make-disk-virt-p2.patch deleted file mode 100644 index 9d5dffa..0000000 --- a/SOURCES/0139-p2v-Add-install-option-to-virt-p2v-make-disk-virt-p2.patch +++ /dev/null @@ -1,173 +0,0 @@ -From 7708cc27dff5cd6836c855e3ec3df771617d473f Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Mon, 27 Jun 2016 11:40:18 +0100 -Subject: [PATCH] p2v: Add --install option to virt-p2v-make-disk, - virt-p2v-make-kickstart. - -This allows you to install extra packages in the disk/ISO. The -implementation of this option in virt-p2v-make-disk was particularly -simple and followed naturally from the previous commit. - -(cherry picked from commit 2783f695ff425ba4ff9cd59f28bb6046a3bb1114) ---- - p2v/p2v.ks.in | 4 ++++ - p2v/virt-p2v-make-disk.in | 7 ++++++- - p2v/virt-p2v-make-disk.pod | 14 ++++++++++++++ - p2v/virt-p2v-make-kickstart.in | 8 +++++++- - p2v/virt-p2v-make-kickstart.pod | 14 ++++++++++++++ - 5 files changed, 45 insertions(+), 2 deletions(-) - -diff --git a/p2v/p2v.ks.in b/p2v/p2v.ks.in -index 384843d..62a9d01 100644 ---- a/p2v/p2v.ks.in -+++ b/p2v/p2v.ks.in -@@ -76,6 +76,10 @@ dracut-live - # The dependencies of virt-p2v. - __DEPENDENCIES__ - -+# Extra packages requested by the user via the virt-p2v-make-kickstart -+# --install option (if any). -+__EXTRA_PACKAGES__ -+ - %end - - # Post-install configuration. -diff --git a/p2v/virt-p2v-make-disk.in b/p2v/virt-p2v-make-disk.in -index cbbc9ff..cc7ee93 100644 ---- a/p2v/virt-p2v-make-disk.in -+++ b/p2v/virt-p2v-make-disk.in -@@ -24,7 +24,7 @@ version="@PACKAGE_VERSION@" - - TEMP=`getopt \ - -o o:V \ -- --long help,inject-ssh-identity:,no-warn-if-partition,output:,verbose,version \ -+ --long help,inject-ssh-identity:,install:,no-warn-if-partition,output:,verbose,version \ - -n $program -- "$@"` - if [ $? != 0 ]; then - echo "$program: problem parsing the command line arguments" -@@ -60,6 +60,11 @@ while true; do - shift;; - - # virt-builder parameters that are passed through. -+ --install) -+ passthru[${#passthru[*]}]="$1" -+ passthru[${#passthru[*]}]="$2" -+ shift 2;; -+ - --no-warn-if-partition) - passthru[${#passthru[*]}]="$1" - shift;; -diff --git a/p2v/virt-p2v-make-disk.pod b/p2v/virt-p2v-make-disk.pod -index 2e1bffb..514ddb0 100644 ---- a/p2v/virt-p2v-make-disk.pod -+++ b/p2v/virt-p2v-make-disk.pod -@@ -52,6 +52,15 @@ Write a virt-p2v bootable virtual disk image, and boot it under qemu: - where F would be the disk image of some guest that - you want to convert (for testing only). - -+=head1 ADDING EXTRA PACKAGES -+ -+You can install extra packages using the I<--install> option. This -+can be useful for making a more fully-featured virt-p2v disk with -+extra tools for debugging and troubleshooting. Give a list of -+packages, separated by commas. For example: -+ -+ virt-p2v-make-disk -o /var/tmp/p2v.img --install tcpdump,traceroute -+ - =head1 ADDING AN SSH IDENTITY - - You can inject an SSH identity (private key) file to the image using -@@ -99,6 +108,11 @@ Display help. - Add an SSH identity (private key) file into the image. - See L above. - -+=item B<--install> pkg,pkg,... -+ -+Add extra packages to the image. -+See L above. -+ - =item B<--no-warn-if-partition> - - Normally you should not write to a partition on a USB drive (ie. don't -diff --git a/p2v/virt-p2v-make-kickstart.in b/p2v/virt-p2v-make-kickstart.in -index 8a6e4d8..c57e212 100644 ---- a/p2v/virt-p2v-make-kickstart.in -+++ b/p2v/virt-p2v-make-kickstart.in -@@ -24,7 +24,7 @@ version="@PACKAGE_VERSION@" - - TEMP=`getopt \ - -o o:vV \ -- --long help,inject-ssh-identity:,output:,proxy:,verbose,version \ -+ --long help,inject-ssh-identity:,install:,output:,proxy:,verbose,version \ - -n $program -- "$@"` - if [ $? != 0 ]; then - echo "$program: problem parsing the command line arguments" -@@ -41,6 +41,7 @@ usage () - exit $1 - } - -+extra_packages= - output=p2v.ks - proxy= - ssh_identity= -@@ -51,6 +52,9 @@ while true; do - --inject-ssh-identity) - ssh_identity="$2" - shift 2;; -+ --install) -+ extra_packages="${extra_packages:+${extra_packages},}$2" -+ shift 2;; - -o|--output) - output="$2" - shift 2;; -@@ -186,6 +190,7 @@ done < $depsfile - -v "base64_ssh_identity=$base64_ssh_identity" \ - -v "base64_virt_p2v=$base64_virt_p2v" \ - -v "dependencies=$dependencies" \ -+ -v "extra_packages=$extra_packages" \ - -v "md5sum_virt_p2v=$md5sum_virt_p2v" \ - -v "repos=$repos" \ - -v "libexecdir=$libexecdir" \ -@@ -199,6 +204,7 @@ done < $depsfile - gsub (/__BASE64_SSH_IDENTITY__/, base64_ssh_identity); - gsub (/__BASE64_VIRT_P2V__/, base64_virt_p2v); - gsub (/__DEPENDENCIES__/, dependencies); -+ gsub (/__EXTRA_PACKAGES__/, gensub (/,/, "\n", "g", extra_packages)); - gsub (/__MD5SUM_VIRT_P2V__/, md5sum_virt_p2v); - gsub (/__REPOS__/, repos); - gsub (/__LIBEXECDIR__/, libexecdir); -diff --git a/p2v/virt-p2v-make-kickstart.pod b/p2v/virt-p2v-make-kickstart.pod -index cea3787..7e41c9d 100644 ---- a/p2v/virt-p2v-make-kickstart.pod -+++ b/p2v/virt-p2v-make-kickstart.pod -@@ -191,6 +191,15 @@ pxelinux starts up. - - =back - -+=head1 ADDING EXTRA PACKAGES -+ -+You can install extra packages using the I<--install> option. This -+can be useful for making a more fully-featured virt-p2v disk with -+extra tools for debugging and troubleshooting. Give a list of -+packages, separated by commas. For example: -+ -+ virt-p2v-make-kickstart [...] --install tcpdump,traceroute -+ - =head1 ADDING AN SSH IDENTITY - - You can inject an SSH identity (private key) file to the kickstart and -@@ -243,6 +252,11 @@ Display help. - Add an SSH identity (private key) file into the kickstart. - See L above. - -+=item B<--install> pkg,pkg,... -+ -+Add extra packages to the kickstart C<%packages> section. -+See L above. -+ - =item B<-o> OUTPUT - - =item B<--output> OUTPUT --- -1.8.3.1 - diff --git a/SOURCES/0140-p2v-Add-less-package-to-the-ISO.patch b/SOURCES/0140-p2v-Add-less-package-to-the-ISO.patch deleted file mode 100644 index 4560fe8..0000000 --- a/SOURCES/0140-p2v-Add-less-package-to-the-ISO.patch +++ /dev/null @@ -1,85 +0,0 @@ -From 7f790117b1a5d6ce5d57dcae6e82517dfa8de350 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Mon, 27 Jun 2016 15:31:37 +0100 -Subject: [PATCH] p2v: Add 'less' package to the ISO. - -When running the xterm it is very useful to be able to do: - - dmesg | less - -(cherry picked from commit 5f248dcd395907f80e5a7a1ccb0d5f56b3e2e015) ---- - p2v/dependencies.m4 | 12 ++++++++---- - 1 file changed, 8 insertions(+), 4 deletions(-) - -diff --git a/p2v/dependencies.m4 b/p2v/dependencies.m4 -index 80d6c92..6acae8c 100644 ---- a/p2v/dependencies.m4 -+++ b/p2v/dependencies.m4 -@@ -31,6 +31,7 @@ ifelse(REDHAT,1, - curl - ethtool - util-linux -+ xterm - - dnl The hwdata package contains PCI IDs, used by virt-p2v to display - dnl network vendor information (RHBZ#855059). -@@ -40,9 +41,9 @@ ifelse(REDHAT,1, - pciutils - hdparm - smartmontools -+ less - - dnl X11 environment -- xterm - /usr/bin/xinit - /usr/bin/Xorg - xorg-x11-drivers -@@ -73,12 +74,13 @@ ifelse(DEBIAN,1, - curl - ethtool - util-linux -+ xterm - hwdata - pciutils - hdparm - smartmontools -+ less - xorg -- xterm - xserver-xorg-video-all - fonts-dejavu - metacity -@@ -98,11 +100,12 @@ ifelse(ARCHLINUX,1, - curl - ethtool - util-linux -+ xterm - hwdata - pciutils - hdparm - smartmontools -- xterm -+ less - xorg-xinit - xorg-server - xf86-video-* -@@ -124,13 +127,14 @@ ifelse(SUSE,1, - curl - ethtool - util-linux -+ xterm - hwdata - pciutils - hdparm - smartmontools -+ less - xinit - xorg-x11-server -- xterm - xf86-video-* - dejavu-fonts - NetworkManager --- -1.8.3.1 - diff --git a/SOURCES/0141-p2v-Remove-trailing-n-from-fixed-disks-device-box.patch b/SOURCES/0141-p2v-Remove-trailing-n-from-fixed-disks-device-box.patch deleted file mode 100644 index a858fd8..0000000 --- a/SOURCES/0141-p2v-Remove-trailing-n-from-fixed-disks-device-box.patch +++ /dev/null @@ -1,28 +0,0 @@ -From ec9c4fa9e396b110bca94845d2d752081b6c5e4c Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Tue, 28 Jun 2016 13:38:34 +0100 -Subject: [PATCH] p2v: Remove trailing \n from fixed disks device box. - -Fixes commit 6aba5a49448d8ed9776164005080620d37bb97e0. - -(cherry picked from commit 13307325e8a4bf12016897224d069309deb34135) ---- - p2v/gui.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/p2v/gui.c b/p2v/gui.c -index 5ffe3d8..9e9043a 100644 ---- a/p2v/gui.c -+++ b/p2v/gui.c -@@ -884,7 +884,7 @@ populate_disks (GtkTreeView *disks_list) - "" - "%s %s\n" - "%s%s" -- "\n", -+ "", - all_disks[i], - size_gb ? size_gb : "", model ? model : "", - serial ? "s/n " : "", serial ? serial : "") == -1) --- -1.8.3.1 - diff --git a/SOURCES/0142-p2v-Add-more-utilities-to-the-virt-p2v-ISO.patch b/SOURCES/0142-p2v-Add-more-utilities-to-the-virt-p2v-ISO.patch deleted file mode 100644 index 64b3f52..0000000 --- a/SOURCES/0142-p2v-Add-more-utilities-to-the-virt-p2v-ISO.patch +++ /dev/null @@ -1,86 +0,0 @@ -From 17fa83b8c262958a1cd8779d77f97895d4e64165 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Tue, 28 Jun 2016 16:43:40 +0100 -Subject: [PATCH] p2v: Add more utilities to the virt-p2v ISO. - -- iscsi-initiator-utils (open-iscsi), as a partial fix for RHBZ#1337052 - -- vi (Vim), to use as an editor inside the XTerm window. - -(cherry picked from commit b221863f220ee3bb7aea986a17660f2d1f62ec76) ---- - p2v/dependencies.m4 | 18 ++++++++++++++---- - 1 file changed, 14 insertions(+), 4 deletions(-) - -diff --git a/p2v/dependencies.m4 b/p2v/dependencies.m4 -index 6acae8c..d339b2f 100644 ---- a/p2v/dependencies.m4 -+++ b/p2v/dependencies.m4 -@@ -33,6 +33,10 @@ ifelse(REDHAT,1, - util-linux - xterm - -+ dnl Generally useful tools to use within xterm -+ less -+ vim-minimal -+ - dnl The hwdata package contains PCI IDs, used by virt-p2v to display - dnl network vendor information (RHBZ#855059). - hwdata -@@ -41,7 +45,7 @@ ifelse(REDHAT,1, - pciutils - hdparm - smartmontools -- less -+ iscsi-initiator-utils - - dnl X11 environment - /usr/bin/xinit -@@ -75,11 +79,13 @@ ifelse(DEBIAN,1, - ethtool - util-linux - xterm -+ less -+ vim-tiny - hwdata - pciutils - hdparm - smartmontools -- less -+ open-iscsi - xorg - xserver-xorg-video-all - fonts-dejavu -@@ -101,11 +107,13 @@ ifelse(ARCHLINUX,1, - ethtool - util-linux - xterm -+ less -+ vim-tiny - hwdata - pciutils - hdparm - smartmontools -- less -+ open-iscsi - xorg-xinit - xorg-server - xf86-video-* -@@ -128,11 +136,13 @@ ifelse(SUSE,1, - ethtool - util-linux - xterm -+ less -+ vim - hwdata - pciutils - hdparm - smartmontools -- less -+ open-iscsi - xinit - xorg-x11-server - xf86-video-* --- -1.8.3.1 - diff --git a/SOURCES/0143-utils-Move-ansi_-functions-to-header-guestfs-interna.patch b/SOURCES/0143-utils-Move-ansi_-functions-to-header-guestfs-interna.patch deleted file mode 100644 index afc72c7..0000000 --- a/SOURCES/0143-utils-Move-ansi_-functions-to-header-guestfs-interna.patch +++ /dev/null @@ -1,180 +0,0 @@ -From 685108da60b663059570e5a5a4a72c91b0ca4da9 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Wed, 29 Jun 2016 12:49:46 +0100 -Subject: [PATCH] utils: Move ansi_* functions to header - guestfs-internal-frontend.h. - -This is just code motion. - -(cherry picked from commit d2abfc7b486039efdfb3fa9b910e14911215b85a) ---- - src/guestfs-internal-frontend.h | 29 ++++++++++++++++++ - utils/boot-analysis/boot-analysis.c | 61 ++++++------------------------------- - 2 files changed, 39 insertions(+), 51 deletions(-) - -diff --git a/src/guestfs-internal-frontend.h b/src/guestfs-internal-frontend.h -index cf0eebc..ed9165a 100644 ---- a/src/guestfs-internal-frontend.h -+++ b/src/guestfs-internal-frontend.h -@@ -179,4 +179,33 @@ extern void guestfs_int_cleanup_pclose (void *ptr); - NULL \ - ) - -+/* ANSI colours. These are defined as macros so that we don't have to -+ * define the force_colour global variable in the library. -+ */ -+#define ansi_green(fp) \ -+ do { \ -+ if (force_colour || isatty (fileno (fp))) \ -+ fputs ("\033[0;32m", (fp)); \ -+ } while (0) -+#define ansi_red(fp) \ -+ do { \ -+ if (force_colour || isatty (fileno (fp))) \ -+ fputs ("\033[1;31m", (fp)); \ -+ } while (0) -+#define ansi_blue(fp) \ -+ do { \ -+ if (force_colour || isatty (fileno (fp))) \ -+ fputs ("\033[1;34m", (fp)); \ -+ } while (0) -+#define ansi_magenta(fp) \ -+ do { \ -+ if (force_colour || isatty (fileno (fp))) \ -+ fputs ("\033[1;35m", (fp)); \ -+ } while (0) -+#define ansi_restore(fp) \ -+ do { \ -+ if (force_colour || isatty (fileno (fp))) \ -+ fputs ("\033[0m", (fp)); \ -+ } while (0) -+ - #endif /* GUESTFS_INTERNAL_FRONTEND_H_ */ -diff --git a/utils/boot-analysis/boot-analysis.c b/utils/boot-analysis/boot-analysis.c -index d06d9a1..1b491c4 100644 ---- a/utils/boot-analysis/boot-analysis.c -+++ b/utils/boot-analysis/boot-analysis.c -@@ -51,7 +51,7 @@ - #define WARNING_THRESHOLD 1.0 - - static const char *append = NULL; --static int force_colour = 0; -+static int force_colour = 0; /* used by ansi_* macros */ - static int memsize = 0; - static int smp = 1; - static int verbose = 0; -@@ -85,11 +85,6 @@ static void print_analysis (void); - static void print_longest_to_shortest (void); - static void free_pass_data (void); - static void free_final_timeline (void); --static void ansi_green (void); --static void ansi_red (void); --static void ansi_blue (void); --static void ansi_magenta (void); --static void ansi_restore (void); - - static void - usage (int exitcode) -@@ -1033,15 +1028,15 @@ dump_timeline (void) - static void - print_activity (struct activity *activity) - { -- if (activity->warning) ansi_red (); else ansi_green (); -+ if (activity->warning) ansi_red (stdout); else ansi_green (stdout); - assert (activity->magic == ACTIVITY_MAGIC); - print_escaped_string (activity->name); -- ansi_restore (); -+ ansi_restore (stdout); - printf (" %.1fms ±%.1fms ", - activity->mean / 1000000, activity->sd / 1000000); -- if (activity->warning) ansi_red (); else ansi_green (); -+ if (activity->warning) ansi_red (stdout); else ansi_green (stdout); - printf ("(%.1f%%) ", activity->percent); -- ansi_restore (); -+ ansi_restore (stdout); - } - - static void -@@ -1084,7 +1079,7 @@ print_analysis (void) - /* Draw a spacer line, but only if last_t -> t is a large jump. */ - if (t - last_t >= 1000000 /* ns */) { - printf (" "); -- ansi_magenta (); -+ ansi_magenta (stdout); - for (j = 0; j < last_free_column; ++j) { - if (columns[j] >= 0 && - activities[columns[j]].end_t != last_t /* !▼ */) -@@ -1092,7 +1087,7 @@ print_analysis (void) - else - printf (" "); - } -- ansi_restore (); -+ ansi_restore (stdout); - printf ("\n"); - } - -@@ -1122,10 +1117,10 @@ print_analysis (void) - } - - /* Draw the line. */ -- ansi_blue (); -+ ansi_blue (stdout); - printf ("%6.1fms: ", t / 1000000); - -- ansi_magenta (); -+ ansi_magenta (stdout); - for (j = 0; j < last_free_column; ++j) { - if (columns[j] >= 0) { - if (activities[columns[j]].t == t) -@@ -1138,7 +1133,7 @@ print_analysis (void) - else - printf (" "); - } -- ansi_restore (); -+ ansi_restore (stdout); - - for (j = 0; j < last_free_column; ++j) { - if (columns[j] >= 0 && activities[columns[j]].t == t) /* ▲ */ -@@ -1215,39 +1210,3 @@ free_final_timeline (void) - free (activities[i].name); - free (activities); - } -- --/* Colours. */ --static void --ansi_green (void) --{ -- if (force_colour || isatty (1)) -- fputs ("\033[0;32m", stdout); --} -- --static void --ansi_red (void) --{ -- if (force_colour || isatty (1)) -- fputs ("\033[1;31m", stdout); --} -- --static void --ansi_blue (void) --{ -- if (force_colour || isatty (1)) -- fputs ("\033[1;34m", stdout); --} -- --static void --ansi_magenta (void) --{ -- if (force_colour || isatty (1)) -- fputs ("\033[1;35m", stdout); --} -- --static void --ansi_restore (void) --{ -- if (force_colour || isatty (1)) -- fputs ("\033[0m", stdout); --} --- -1.8.3.1 - diff --git a/SOURCES/0144-p2v-Colourize-kernel-conversion-status-messages-from.patch b/SOURCES/0144-p2v-Colourize-kernel-conversion-status-messages-from.patch deleted file mode 100644 index fdae05a..0000000 --- a/SOURCES/0144-p2v-Colourize-kernel-conversion-status-messages-from.patch +++ /dev/null @@ -1,185 +0,0 @@ -From b7dd708d309d86625e3d6cb2f479bed5e5b55ee1 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Wed, 29 Jun 2016 12:51:39 +0100 -Subject: [PATCH] p2v: Colourize kernel-conversion status messages from - virt-p2v. - -The messages that come "through" from virt-v2v are already colourized. -However the other messages are not. This colourizes the ones -generated during kernel-mode conversions. - -Note that because of the way journal/syslog works we have to write the -ansi_restore before the end of line, thus code like this: - - ansi_magenta (stdout); - printf ("%s: %s", guestfs_int_program_name, data); - ansi_restore (stdout); - putchar ('\n'); - -This also adds a "Conversion finished successfully" message (in green). - -Thanks: Ming Xie -(cherry picked from commit b15b6e69e37cb3b6520d301442a67b9971ae8d51) ---- - p2v/kernel.c | 23 +++++++++++++++++++---- - p2v/launch-virt-p2v.in | 4 ++-- - p2v/main.c | 12 ++++++++++++ - p2v/p2v.h | 3 +++ - p2v/virt-p2v.pod | 9 +++++++++ - 5 files changed, 45 insertions(+), 6 deletions(-) - -diff --git a/p2v/kernel.c b/p2v/kernel.c -index 6d9388b..6914ab5 100644 ---- a/p2v/kernel.c -+++ b/p2v/kernel.c -@@ -250,6 +250,11 @@ kernel_conversion (struct config *config, char **cmdline, int cmdline_source) - exit (EXIT_FAILURE); - } - -+ ansi_green (stdout); -+ printf ("Conversion finished successfully."); -+ ansi_restore (stdout); -+ putchar ('\n'); -+ - p = get_cmdline_key (cmdline, "p2v.post"); - if (!p) { - if (geteuid () == 0 && cmdline_source == CMDLINE_SOURCE_PROC_CMDLINE) -@@ -264,8 +269,12 @@ notify_ui_callback (int type, const char *data) - { - switch (type) { - case NOTIFY_LOG_DIR: -- printf ("%s: remote log directory location: %s\n", -- guestfs_int_program_name, data); -+ ansi_magenta (stdout); -+ printf ("%s: remote log directory location: ", guestfs_int_program_name); -+ ansi_red (stdout); -+ fputs (data, stdout); -+ ansi_restore (stdout); -+ putchar ('\n'); - break; - - case NOTIFY_REMOTE_MESSAGE: -@@ -273,12 +282,18 @@ notify_ui_callback (int type, const char *data) - break; - - case NOTIFY_STATUS: -- printf ("%s: %s\n", guestfs_int_program_name, data); -+ ansi_magenta (stdout); -+ printf ("%s: %s", guestfs_int_program_name, data); -+ ansi_restore (stdout); -+ putchar ('\n'); - break; - - default: -- printf ("%s: unknown message during conversion: type=%d data=%s\n", -+ ansi_red (stdout); -+ printf ("%s: unknown message during conversion: type=%d data=%s", - guestfs_int_program_name, type, data); -+ ansi_restore (stdout); -+ putchar ('\n'); - } - - fflush (stdout); -diff --git a/p2v/launch-virt-p2v.in b/p2v/launch-virt-p2v.in -index 3e4f1f9..ca971a0 100755 ---- a/p2v/launch-virt-p2v.in -+++ b/p2v/launch-virt-p2v.in -@@ -23,7 +23,7 @@ - cmdline=$(, parse the string parameter C. - -+=item B<--colors> -+ -+=item B<--colours> -+ -+Use ANSI colour sequences to colourize messages. This is the default -+when the output is a tty. If the output of the program is redirected -+to a file, ANSI colour sequences are disabled unless you use this -+option. -+ - =item B<--iso> - - This flag is passed to virt-p2v when it is launched inside the --- -1.8.3.1 - diff --git a/SOURCES/0145-p2v-Use-scp-to-copy-the-files-to-remote-debugging-di.patch b/SOURCES/0145-p2v-Use-scp-to-copy-the-files-to-remote-debugging-di.patch deleted file mode 100644 index 161fbc3..0000000 --- a/SOURCES/0145-p2v-Use-scp-to-copy-the-files-to-remote-debugging-di.patch +++ /dev/null @@ -1,849 +0,0 @@ -From a87ea830a0dba6260d9e996ad25f50472200ad8e Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Thu, 30 Jun 2016 13:42:53 +0100 -Subject: [PATCH] p2v: Use 'scp' to copy the files to remote debugging - directory. - -Previously we copied / creates files in the remote dir by running -complex shell commands like: - - cat > file <<'EOF' - ## the file was copied in here - EOF - -This was a little hairy, but in particular it doesn't allow us to set -the ssh session to cooked mode (so we can send ^C to cancel a -conversion). - -A cleaner way to do it is to use 'scp' to copy the files over. - -(cherry picked from commit 6d9bac80b20024a397232f42d136fb48a537a7c4) ---- - p2v/Makefile.am | 1 + - p2v/conversion.c | 279 ++++++++++++++++++++++++----------------------- - p2v/p2v.h | 3 +- - p2v/ssh.c | 255 ++++++++++++++++++++++++++++++------------- - p2v/test-virt-p2v-scp.sh | 58 ++++++++++ - p2v/test-virt-p2v.sh | 5 +- - p2v/virt-p2v.pod | 4 + - 7 files changed, 388 insertions(+), 217 deletions(-) - create mode 100755 p2v/test-virt-p2v-scp.sh - -diff --git a/p2v/Makefile.am b/p2v/Makefile.am -index 487e198..9bee6f6 100644 ---- a/p2v/Makefile.am -+++ b/p2v/Makefile.am -@@ -26,6 +26,7 @@ EXTRA_DIST = \ - p2v.ks.in \ - p2v.service \ - test-virt-p2v-pxe.sshd_config.in \ -+ test-virt-p2v-scp.sh \ - test-virt-p2v-ssh.sh \ - virt-p2v.pod \ - virt-p2v-make-disk.in \ -diff --git a/p2v/conversion.c b/p2v/conversion.c -index de2a4b2..f9b8350 100644 ---- a/p2v/conversion.c -+++ b/p2v/conversion.c -@@ -32,6 +32,7 @@ - #include - #include - #include -+#include - #include - #include - -@@ -83,9 +84,12 @@ struct data_conn { - static pid_t start_qemu_nbd (int nbd_local_port, const char *device); - static int wait_qemu_nbd (int nbd_local_port, int timeout_seconds); - static void cleanup_data_conns (struct data_conn *data_conns, size_t nr); --static char *generate_libvirt_xml (struct config *, struct data_conn *); --static char *generate_wrapper_script (struct config *, const char *remote_dir); -+static void generate_name (struct config *, const char *filename); -+static void generate_libvirt_xml (struct config *, struct data_conn *, const char *filename); -+static void generate_wrapper_script (struct config *, const char *remote_dir, const char *filename); -+static void generate_dmesg_file (const char *filename); - static const char *map_interface_to_network (struct config *, const char *interface); -+static void print_quoted (FILE *fp, const char *s); - - static char *conversion_error; - -@@ -169,15 +173,16 @@ start_conversion (struct config *config, - int status; - size_t i, len; - const size_t nr_disks = guestfs_int_count_strings (config->disks); -- struct data_conn data_conns[nr_disks]; -- CLEANUP_FREE char *remote_dir = NULL, *libvirt_xml = NULL, -- *wrapper_script = NULL; - time_t now; - struct tm tm; - mexp_h *control_h = NULL; -- char dmesg_cmd[] = "dmesg > /tmp/dmesg.XXXXXX", *dmesg_file = &dmesg_cmd[8]; -- CLEANUP_FREE char *dmesg = NULL; -- int fd, r; -+ struct data_conn data_conns[nr_disks]; -+ CLEANUP_FREE char *remote_dir = NULL; -+ char tmpdir[] = "/tmp/p2v.XXXXXX"; -+ char name_file[] = "/tmp/p2v.XXXXXX/name"; -+ char libvirt_xml_file[] = "/tmp/p2v.XXXXXX/physical.xml"; -+ char wrapper_script[] = "/tmp/p2v.XXXXXX/virt-v2v-wrapper.sh"; -+ char dmesg_file[] = "/tmp/p2v.XXXXXX/dmesg"; - - #if DEBUG_STDERR - print_config (config, stderr); -@@ -273,59 +278,53 @@ start_conversion (struct config *config, - if (notify_ui) - notify_ui (NOTIFY_LOG_DIR, remote_dir); - -- /* Generate the libvirt XML. */ -- libvirt_xml = generate_libvirt_xml (config, data_conns); -- if (libvirt_xml == NULL) -- goto out; -- --#if DEBUG_STDERR && 0 -- fprintf (stderr, "%s: libvirt XML:\n%s", -- guestfs_int_program_name, libvirt_xml); --#endif -- -- /* Generate the virt-v2v wrapper script. */ -- wrapper_script = generate_wrapper_script (config, remote_dir); -- if (wrapper_script == NULL) -- goto out; -- --#if DEBUG_STDERR && 0 -- fprintf (stderr, "%s: wrapper script:\n%s", -- guestfs_int_program_name, wrapper_script); --#endif -- -- /* Get the output from the 'dmesg' command. We will store this -- * on the remote server. -- */ -- fd = mkstemp (dmesg_file); -- if (fd == -1) { -- perror ("mkstemp"); -- goto skip_dmesg; -- } -- close (fd); -- r = system (dmesg_cmd); -- if (r == -1) { -- perror ("system"); -- goto skip_dmesg; -- } -- if (!WIFEXITED (r) || WEXITSTATUS (r) != 0) { -- fprintf (stderr, "'dmesg' failed (ignored)\n"); -- goto skip_dmesg; -+ /* Generate the local temporary directory. */ -+ if (mkdtemp (tmpdir) == NULL) { -+ perror ("mkdtemp"); -+ cleanup_data_conns (data_conns, nr_disks); -+ exit (EXIT_FAILURE); - } -+ memcpy (name_file, tmpdir, strlen (tmpdir)); -+ memcpy (libvirt_xml_file, tmpdir, strlen (tmpdir)); -+ memcpy (wrapper_script, tmpdir, strlen (tmpdir)); -+ memcpy (dmesg_file, tmpdir, strlen (tmpdir)); - -- ignore_value (read_whole_file (dmesg_file, &dmesg, NULL)); -- skip_dmesg: -+ /* Generate the static files. */ -+ generate_name (config, name_file); -+ generate_libvirt_xml (config, data_conns, libvirt_xml_file); -+ generate_wrapper_script (config, remote_dir, wrapper_script); -+ generate_dmesg_file (dmesg_file); - -- /* Open the control connection and start conversion */ -+ /* Open the control connection. This also creates remote_dir. */ - if (notify_ui) - notify_ui (NOTIFY_STATUS, _("Setting up the control connection ...")); - -- control_h = start_remote_connection (config, -- remote_dir, libvirt_xml, -- wrapper_script, dmesg); -+ control_h = start_remote_connection (config, remote_dir); - if (control_h == NULL) { -- const char *err = get_ssh_error (); -+ set_conversion_error ("could not open control connection over SSH to the conversion server: %s", -+ get_ssh_error ()); -+ goto out; -+ } - -- set_conversion_error ("could not open control connection over SSH to the conversion server: %s", err); -+ /* Copy the static files to the remote dir. */ -+ if (scp_file (config, name_file, remote_dir) == -1) { -+ set_conversion_error ("scp: %s to %s: %s", -+ name_file, remote_dir, get_ssh_error ()); -+ goto out; -+ } -+ if (scp_file (config, libvirt_xml_file, remote_dir) == -1) { -+ set_conversion_error ("scp: %s to %s: %s", -+ libvirt_xml_file, remote_dir, get_ssh_error ()); -+ goto out; -+ } -+ if (scp_file (config, wrapper_script, remote_dir) == -1) { -+ set_conversion_error ("scp: %s to %s: %s", -+ wrapper_script, remote_dir, get_ssh_error ()); -+ goto out; -+ } -+ if (scp_file (config, dmesg_file, remote_dir) == -1) { -+ set_conversion_error ("scp: %s to %s: %s", -+ dmesg_file, remote_dir, get_ssh_error ()); - goto out; - } - -@@ -667,20 +666,16 @@ cleanup_data_conns (struct data_conn *data_conns, size_t nr) - /* Macros "inspired" by src/launch-libvirt.c */ - /* */ - #define end_element() \ - while (0); \ - do { \ -- if (xmlTextWriterEndElement (xo) == -1) { \ -- set_conversion_error ("xmlTextWriterEndElement: %m"); \ -- return NULL; \ -- } \ -+ if (xmlTextWriterEndElement (xo) == -1) \ -+ error (EXIT_FAILURE, errno, "xmlTextWriterEndElement"); \ - } while (0) - - /* */ -@@ -689,80 +684,62 @@ cleanup_data_conns (struct data_conn *data_conns, size_t nr) - - /* key=value attribute of the current element. */ - #define attribute(key,value) \ -- if (xmlTextWriterWriteAttribute (xo, BAD_CAST (key), BAD_CAST (value)) == -1) { \ -- set_conversion_error ("xmlTextWriterWriteAttribute: %m"); \ -- return NULL; \ -- } -+ do { \ -+ if (xmlTextWriterWriteAttribute (xo, BAD_CAST (key), BAD_CAST (value)) == -1) \ -+ error (EXIT_FAILURE, errno, "xmlTextWriterWriteAttribute"); \ -+ } while (0) - - /* key=value, but value is a printf-style format string. */ - #define attribute_format(key,fs,...) \ -- if (xmlTextWriterWriteFormatAttribute (xo, BAD_CAST (key), \ -- fs, ##__VA_ARGS__) == -1) { \ -- set_conversion_error ("xmlTextWriterWriteFormatAttribute: %m"); \ -- return NULL; \ -- } -+ do { \ -+ if (xmlTextWriterWriteFormatAttribute (xo, BAD_CAST (key), \ -+ fs, ##__VA_ARGS__) == -1) \ -+ error (EXIT_FAILURE, errno, "xmlTextWriterWriteFormatAttribute"); \ -+ } while (0) - - /* A string, eg. within an element. */ --#define string(str) \ -- if (xmlTextWriterWriteString (xo, BAD_CAST (str)) == -1) { \ -- set_conversion_error ("xmlTextWriterWriteString: %m"); \ -- return NULL; \ -- } -+#define string(str) \ -+ do { \ -+ if (xmlTextWriterWriteString (xo, BAD_CAST (str)) == -1) \ -+ error (EXIT_FAILURE, errno, "xmlTextWriterWriteString"); \ -+ } while (0) - - /* A string, using printf-style formatting. */ - #define string_format(fs,...) \ -- if (xmlTextWriterWriteFormatString (xo, fs, ##__VA_ARGS__) == -1) { \ -- set_conversion_error ("xmlTextWriterWriteFormatString: %m"); \ -- return NULL; \ -- } -+ do { \ -+ if (xmlTextWriterWriteFormatString (xo, fs, ##__VA_ARGS__) == -1) \ -+ error (EXIT_FAILURE, errno, "xmlTextWriterWriteFormatString"); \ -+ } while (0) - - /* An XML comment. */ - #define comment(str) \ -- if (xmlTextWriterWriteComment (xo, BAD_CAST (str)) == -1) { \ -- set_conversion_error ("xmlTextWriterWriteComment: %m"); \ -- return NULL; \ -- } -+ do { \ -+ if (xmlTextWriterWriteComment (xo, BAD_CAST (str)) == -1) \ -+ error (EXIT_FAILURE, errno, "xmlTextWriterWriteComment"); \ -+ } while (0) - - /* Write the libvirt XML for this physical machine. Note this is not - * actually input for libvirt. It's input for virt-v2v on the - * conversion server, and virt-v2v will (if necessary) generate the - * final libvirt XML. - */ --static char * --generate_libvirt_xml (struct config *config, struct data_conn *data_conns) -+static void -+generate_libvirt_xml (struct config *config, struct data_conn *data_conns, -+ const char *filename) - { - uint64_t memkb; -- char *ret; -- CLEANUP_XMLBUFFERFREE xmlBufferPtr xb = NULL; -- xmlOutputBufferPtr ob; - CLEANUP_XMLFREETEXTWRITER xmlTextWriterPtr xo = NULL; - size_t i; - -- xb = xmlBufferCreate (); -- if (xb == NULL) { -- set_conversion_error ("xmlBufferCreate: %m"); -- return NULL; -- } -- ob = xmlOutputBufferCreateBuffer (xb, NULL); -- if (ob == NULL) { -- set_conversion_error ("xmlOutputBufferCreateBuffer: %m"); -- return NULL; -- } -- xo = xmlNewTextWriter (ob); -- if (xo == NULL) { -- set_conversion_error ("xmlNewTextWriter: %m"); -- return NULL; -- } -+ xo = xmlNewTextWriterFilename (filename, 0); -+ if (xo == NULL) -+ error (EXIT_FAILURE, errno, "xmlNewTextWriterFilename"); - - if (xmlTextWriterSetIndent (xo, 1) == -1 || -- xmlTextWriterSetIndentString (xo, BAD_CAST " ") == -1) { -- set_conversion_error ("could not set XML indent: %m"); -- return NULL; -- } -- if (xmlTextWriterStartDocument (xo, NULL, NULL, NULL) == -1) { -- set_conversion_error ("xmlTextWriterStartDocument: %m"); -- return NULL; -- } -+ xmlTextWriterSetIndentString (xo, BAD_CAST " ") == -1) -+ error (EXIT_FAILURE, errno, "could not set XML indent"); -+ if (xmlTextWriterStartDocument (xo, NULL, NULL, NULL) == -1) -+ error (EXIT_FAILURE, errno, "xmlTextWriterStartDocument"); - - memkb = config->memory / 1024; - -@@ -907,17 +884,8 @@ generate_libvirt_xml (struct config *config, struct data_conn *data_conns) - - } end_element (); /* */ - -- if (xmlTextWriterEndDocument (xo) == -1) { -- set_conversion_error ("xmlTextWriterEndDocument: %m"); -- return NULL; -- } -- ret = (char *) xmlBufferDetach (xb); /* caller frees */ -- if (ret == NULL) { -- set_conversion_error ("xmlBufferDetach: %m"); -- return NULL; -- } -- -- return ret; -+ if (xmlTextWriterEndDocument (xo) == -1) -+ error (EXIT_FAILURE, errno, "xmlTextWriterEndDocument"); - } - - /* Using config->network_map, map the interface to a target network -@@ -952,19 +920,18 @@ map_interface_to_network (struct config *config, const char *interface) - } - - /** -- * Print a shell-quoted string on C. -+ * Write the guest name into C. - */ - static void --print_quoted (FILE *fp, const char *s) -+generate_name (struct config *config, const char *filename) - { -- fprintf (fp, "\""); -- while (*s) { -- if (*s == '$' || *s == '`' || *s == '\\' || *s == '"') -- fprintf (fp, "\\"); -- fprintf (fp, "%c", *s); -- ++s; -- } -- fprintf (fp, "\""); -+ FILE *fp; -+ -+ fp = fopen (filename, "w"); -+ if (fp == NULL) -+ error (EXIT_FAILURE, errno, "fopen: %s", filename); -+ fprintf (fp, "%s\n", config->guestname); -+ fclose (fp); - } - - /** -@@ -974,16 +941,15 @@ print_quoted (FILE *fp, const char *s) - * to "type" a long and complex single command line into the ssh - * connection when we start the conversion. - */ --static char * --generate_wrapper_script (struct config *config, const char *remote_dir) -+static void -+generate_wrapper_script (struct config *config, const char *remote_dir, -+ const char *filename) - { - FILE *fp; -- char *output = NULL; -- size_t output_len = 0; - -- fp = open_memstream (&output, &output_len); -+ fp = fopen (filename, "w"); - if (fp == NULL) -- error (EXIT_FAILURE, errno, "open_memstream"); -+ error (EXIT_FAILURE, errno, "fopen: %s", filename); - - fprintf (fp, "#!/bin/bash -\n"); - fprintf (fp, "\n"); -@@ -1082,7 +1048,42 @@ generate_wrapper_script (struct config *config, const char *remote_dir) - "fi\n", - remote_dir); - -+ fprintf (fp, "\n"); -+ fprintf (fp, "# EOF\n"); - fclose (fp); - -- return output; /* caller frees */ -+ if (chmod (filename, 0755) == -1) -+ error (EXIT_FAILURE, errno, "chmod: %s", filename); -+} -+ -+/** -+ * Print a shell-quoted string on C. -+ */ -+static void -+print_quoted (FILE *fp, const char *s) -+{ -+ fprintf (fp, "\""); -+ while (*s) { -+ if (*s == '$' || *s == '`' || *s == '\\' || *s == '"') -+ fprintf (fp, "\\"); -+ fprintf (fp, "%c", *s); -+ ++s; -+ } -+ fprintf (fp, "\""); -+} -+ -+/** -+ * Put the output of the C command into C. -+ * -+ * If the command fails, this is non-fatal. -+ */ -+static void -+generate_dmesg_file (const char *filename) -+{ -+ CLEANUP_FREE char *cmd = NULL; -+ -+ if (asprintf (&cmd, "dmesg >%s 2>&1", filename) == -1) -+ error (EXIT_FAILURE, errno, "asprintf"); -+ -+ ignore_value (system (cmd)); - } -diff --git a/p2v/p2v.h b/p2v/p2v.h -index 52d5ccb..da30340 100644 ---- a/p2v/p2v.h -+++ b/p2v/p2v.h -@@ -130,8 +130,9 @@ extern int conversion_is_running (void); - /* ssh.c */ - extern int test_connection (struct config *); - extern mexp_h *open_data_connection (struct config *, int *local_port, int *remote_port); --extern mexp_h *start_remote_connection (struct config *, const char *remote_dir, const char *libvirt_xml, const char *wrapper_script, const char *dmesg); -+extern mexp_h *start_remote_connection (struct config *, const char *remote_dir); - extern const char *get_ssh_error (void); -+extern int scp_file (struct config *config, const char *localfile, const char *remotefile); - - /* utils.c */ - extern uint64_t get_blockdev_size (const char *dev); -diff --git a/p2v/ssh.c b/p2v/ssh.c -index f4adde4..270f1e5 100644 ---- a/p2v/ssh.c -+++ b/p2v/ssh.c -@@ -565,6 +565,182 @@ start_ssh (struct config *config, char **extra_args, int wait_prompt) - return h; - } - -+/** -+ * Upload a file to remote using L. -+ * -+ * This is a simplified version of L above. -+ */ -+int -+scp_file (struct config *config, const char *localfile, const char *remotefile) -+{ -+ size_t j, nr_args; -+ char port_str[64]; -+ char connect_timeout_str[128]; -+ CLEANUP_FREE char *remote = NULL; -+ CLEANUP_FREE /* [sic] */ const char **args = NULL; -+ mexp_h *h; -+ const int ovecsize = 12; -+ int ovector[ovecsize]; -+ int using_password_auth; -+ -+ if (cache_ssh_identity (config) == -1) -+ return -1; -+ -+ /* Are we using password or identity authentication? */ -+ using_password_auth = config->identity_file == NULL; -+ -+ /* Create the scp argument array. */ -+ if (using_password_auth) -+ nr_args = 12; -+ else -+ nr_args = 14; -+ args = malloc (sizeof (char *) * nr_args); -+ if (args == NULL) -+ error (EXIT_FAILURE, errno, "malloc"); -+ -+ j = 0; -+ args[j++] = "scp"; -+ args[j++] = "-P"; /* Port. */ -+ snprintf (port_str, sizeof port_str, "%d", config->port); -+ args[j++] = port_str; -+ args[j++] = "-o"; /* Host key will always be novel. */ -+ args[j++] = "StrictHostKeyChecking=no"; -+ args[j++] = "-o"; /* ConnectTimeout */ -+ snprintf (connect_timeout_str, sizeof connect_timeout_str, -+ "ConnectTimeout=%d", SSH_TIMEOUT); -+ args[j++] = connect_timeout_str; -+ if (using_password_auth) { -+ /* Only use password authentication. */ -+ args[j++] = "-o"; -+ args[j++] = "PreferredAuthentications=keyboard-interactive,password"; -+ } -+ else { -+ /* Use identity file (private key). */ -+ args[j++] = "-o"; -+ args[j++] = "PreferredAuthentications=publickey"; -+ args[j++] = "-i"; -+ args[j++] = config->identity_file; -+ } -+ args[j++] = localfile; -+ if (asprintf (&remote, "%s@%s:%s", -+ config->username ? config->username : "root", -+ config->server, remotefile) == -1) -+ error (EXIT_FAILURE, errno, "asprintf"); -+ args[j++] = remote; -+ args[j++] = NULL; -+ assert (j == nr_args); -+ -+#if DEBUG_STDERR && 0 -+ size_t i; -+ -+ fputs ("scp command: ", stderr); -+ for (i = 0; i < nr_args - 1; ++i) { -+ if (i > 0) fputc (' ', stderr); -+ fputs (args[i], stderr); -+ } -+ fputc ('\n', stderr); -+#endif -+ -+ /* Create the miniexpect handle. */ -+ h = mexp_spawnv ("scp", (char **) args); -+ if (h == NULL) { -+ set_ssh_internal_error ("scp: mexp_spawnv: %m"); -+ return -1; -+ } -+ -+ /* We want the ssh ConnectTimeout to be less than the miniexpect -+ * timeout, so that if the server is completely unresponsive we -+ * still see the error from ssh, not a timeout from miniexpect. The -+ * obvious solution to this is to set ConnectTimeout (above) and to -+ * set the miniexpect timeout to be a little bit larger. -+ */ -+ mexp_set_timeout (h, SSH_TIMEOUT + 20); -+ -+ if (using_password_auth && -+ config->password && strlen (config->password) > 0) { -+ CLEANUP_FREE char *ssh_message = NULL; -+ -+ /* Wait for the password prompt. */ -+ wait_password_again: -+ switch (mexp_expect (h, -+ (mexp_regexp[]) { -+ { 100, .re = password_re }, -+ { 101, .re = ssh_message_re }, -+ { 0 } -+ }, ovector, ovecsize)) { -+ case 100: /* Got password prompt. */ -+ if (mexp_printf (h, "%s\n", config->password) == -1) { -+ set_ssh_mexp_error ("mexp_printf"); -+ mexp_close (h); -+ return -1; -+ } -+ break; -+ -+ case 101: -+ free (ssh_message); -+ ssh_message = strndup (&h->buffer[ovector[2]], ovector[3]-ovector[2]); -+ goto wait_password_again; -+ -+ case MEXP_EOF: -+ /* This is where we get to if the user enters an incorrect or -+ * impossible hostname or port number. Hopefully scp printed an -+ * error message, and we picked it up and put it in -+ * 'ssh_message' in case 101 above. If not we have to print a -+ * generic error instead. -+ */ -+ if (ssh_message) -+ set_ssh_error ("%s", ssh_message); -+ else -+ set_ssh_error ("scp closed the connection without printing an error."); -+ mexp_close (h); -+ return -1; -+ -+ case MEXP_TIMEOUT: -+ set_ssh_unexpected_timeout ("password prompt"); -+ mexp_close (h); -+ return -1; -+ -+ case MEXP_ERROR: -+ set_ssh_mexp_error ("mexp_expect"); -+ mexp_close (h); -+ return -1; -+ -+ case MEXP_PCRE_ERROR: -+ set_ssh_pcre_error (); -+ mexp_close (h); -+ return -1; -+ } -+ } -+ -+ /* Wait for the scp subprocess to finish. */ -+ switch (mexp_expect (h, NULL, NULL, 0)) { -+ case MEXP_EOF: -+ break; -+ -+ case MEXP_TIMEOUT: -+ set_ssh_unexpected_timeout ("copying (scp) file"); -+ mexp_close (h); -+ return -1; -+ -+ case MEXP_ERROR: -+ set_ssh_mexp_error ("mexp_expect"); -+ mexp_close (h); -+ return -1; -+ -+ case MEXP_PCRE_ERROR: -+ set_ssh_pcre_error (); -+ mexp_close (h); -+ return -1; -+ } -+ -+ if (mexp_close (h) == -1) { -+ set_ssh_internal_error ("scp: mexp_close: %m"); -+ return -1; -+ } -+ -+ return 0; -+} -+ - static void add_input_driver (const char *name, size_t len); - static void add_output_driver (const char *name, size_t len); - static int compatible_version (const char *v2v_version); -@@ -971,17 +1147,9 @@ wait_for_prompt (mexp_h *h) - } - - mexp_h * --start_remote_connection (struct config *config, -- const char *remote_dir, const char *libvirt_xml, -- const char *wrapper_script, const char *dmesg) -+start_remote_connection (struct config *config, const char *remote_dir) - { - mexp_h *h; -- char magic[9]; -- -- if (guestfs_int_random_string (magic, 8) == -1) { -- perror ("random_string"); -- return NULL; -- } - - h = start_ssh (config, NULL, 1); - if (h == NULL) -@@ -996,16 +1164,9 @@ start_remote_connection (struct config *config, - if (wait_for_prompt (h) == -1) - goto error; - -- /* Write some useful config information to files in the remote directory. */ -- if (mexp_printf (h, "echo '%s' > %s/name\n", -- config->guestname, remote_dir) == -1) { -- set_ssh_mexp_error ("mexp_printf"); -- goto error; -- } -- -- if (wait_for_prompt (h) == -1) -- goto error; -- -+ /* It's simplest to create the remote 'time' file by running the date -+ * command, as that won't send any special control characters. -+ */ - if (mexp_printf (h, "date > %s/time\n", remote_dir) == -1) { - set_ssh_mexp_error ("mexp_printf"); - goto error; -@@ -1014,62 +1175,6 @@ start_remote_connection (struct config *config, - if (wait_for_prompt (h) == -1) - goto error; - -- /* Upload the guest libvirt XML to the remote directory. */ -- if (mexp_printf (h, -- "cat > '%s/physical.xml' << '__%s__'\n" -- "%s" -- "__%s__\n", -- remote_dir, magic, -- libvirt_xml, -- magic) == -1) { -- set_ssh_mexp_error ("mexp_printf"); -- goto error; -- } -- -- if (wait_for_prompt (h) == -1) -- goto error; -- -- /* Upload the wrapper script to the remote directory. */ -- if (mexp_printf (h, -- "cat > '%s/virt-v2v-wrapper.sh' << '__%s__'\n" -- "%s" -- "__%s__\n", -- remote_dir, magic, -- wrapper_script, -- magic) == -1) { -- set_ssh_mexp_error ("mexp_printf"); -- goto error; -- } -- -- if (wait_for_prompt (h) == -1) -- goto error; -- -- if (mexp_printf (h, "chmod +x %s/virt-v2v-wrapper.sh\n", remote_dir) == -1) { -- set_ssh_mexp_error ("mexp_printf"); -- goto error; -- } -- -- if (wait_for_prompt (h) == -1) -- goto error; -- -- if (dmesg != NULL) { -- /* Upload the physical host dmesg to the remote directory. */ -- if (mexp_printf (h, -- "cat > '%s/dmesg' << '__%s__'\n" -- "%s" -- "\n" -- "__%s__\n", -- remote_dir, magic, -- dmesg, -- magic) == -1) { -- set_ssh_mexp_error ("mexp_printf"); -- goto error; -- } -- -- if (wait_for_prompt (h) == -1) -- goto error; -- } -- - return h; - - error: -diff --git a/p2v/test-virt-p2v-scp.sh b/p2v/test-virt-p2v-scp.sh -new file mode 100755 -index 0000000..be37a03 ---- /dev/null -+++ b/p2v/test-virt-p2v-scp.sh -@@ -0,0 +1,58 @@ -+#!/bin/bash - -+# Copyright (C) 2014-2016 Red Hat Inc. -+# -+# This program is free software; you can redistribute it and/or modify -+# it under the terms of the GNU General Public License as published by -+# the Free Software Foundation; either version 2 of the License, or -+# (at your option) any later version. -+# -+# This program is distributed in the hope that it will be useful, -+# but WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+# GNU General Public License for more details. -+# -+# You should have received a copy of the GNU General Public License -+# along with this program; if not, write to the Free Software -+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -+ -+# This is an scp substitute used by test-virt-p2v.sh. -+ -+TEMP=`getopt \ -+ -o 'o:P:' \ -+ -- "$@"` -+if [ $? != 0 ]; then -+ echo "$0: problem parsing the command line arguments" -+ exit 1 -+fi -+eval set -- "$TEMP" -+ -+while true ; do -+ case "$1" in -+ # Regular arguments that we can just ignore. -+ -o|-P) -+ shift 2 -+ ;; -+ -+ --) -+ shift -+ break -+ ;; -+ *) -+ echo "$0: internal error ($1)" -+ exit 1 -+ ;; -+ esac -+done -+ -+# Hopefully there are two arguments left, the source (local) file -+# and a remote file of the form user@server:remote. -+if [ $# -ne 2 ]; then -+ echo "$0: incorrect number of arguments found:" "$@" -+ exit 1 -+fi -+ -+local="$1" -+remote="$(echo $2 | awk -F: '{print $2}')" -+ -+# Use the copy command. -+exec cp "$local" "$remote" -diff --git a/p2v/test-virt-p2v.sh b/p2v/test-virt-p2v.sh -index 692894b..e232d42 100755 ---- a/p2v/test-virt-p2v.sh -+++ b/p2v/test-virt-p2v.sh -@@ -50,10 +50,11 @@ d=test-virt-p2v.d - rm -rf $d - mkdir $d - --# We don't want the program under test to run real 'ssh'. It's --# unlikely to work. Therefore create a dummy 'ssh' binary. -+# We don't want the program under test to run real 'ssh' or 'scp'. -+# They won't work. Therefore create dummy 'ssh' and 'scp' binaries. - pushd $d - ln -sf ../test-virt-p2v-ssh.sh ssh -+ln -sf ../test-virt-p2v-scp.sh scp - popd - export PATH=$d:$PATH - -diff --git a/p2v/virt-p2v.pod b/p2v/virt-p2v.pod -index 247acce..ef6a9db 100644 ---- a/p2v/virt-p2v.pod -+++ b/p2v/virt-p2v.pod -@@ -56,6 +56,10 @@ by virt-p2v, and it will not work if this is disabled on the - conversion server. (C must be C in the - L file on the conversion server). - -+The scp (secure copy) feature of ssh is required by virt-p2v so it can -+send over small files (this is I the method by which disks are -+copied). -+ - The conversion server does not need to be a physical machine. It - could be a virtual machine, as long as it has sufficient memory and - disk space to do the conversion, and as long as the physical machine --- -1.8.3.1 - diff --git a/SOURCES/0146-p2v-ssh-Set-cooked-mode-on-the-ssh-session-which-run.patch b/SOURCES/0146-p2v-ssh-Set-cooked-mode-on-the-ssh-session-which-run.patch deleted file mode 100644 index 952f6c7..0000000 --- a/SOURCES/0146-p2v-ssh-Set-cooked-mode-on-the-ssh-session-which-run.patch +++ /dev/null @@ -1,72 +0,0 @@ -From bddb2e72e53439f3626656b9bd6c971eed502308 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Thu, 30 Jun 2016 13:52:43 +0100 -Subject: [PATCH] p2v: ssh: Set cooked mode on the ssh session which runs - virt-v2v. - -(cherry picked from commit fa6402a0f8c54397588597e3553bc05576a3863d) ---- - p2v/ssh.c | 18 ++++++++++++------ - 1 file changed, 12 insertions(+), 6 deletions(-) - -diff --git a/p2v/ssh.c b/p2v/ssh.c -index 270f1e5..4cae732 100644 ---- a/p2v/ssh.c -+++ b/p2v/ssh.c -@@ -307,7 +307,8 @@ cache_ssh_identity (struct config *config) - * optional arguments. Also handles authentication. - */ - static mexp_h * --start_ssh (struct config *config, char **extra_args, int wait_prompt) -+start_ssh (unsigned spawn_flags, struct config *config, -+ char **extra_args, int wait_prompt) - { - size_t i, j, nr_args, count; - char port_str[64]; -@@ -383,9 +384,9 @@ start_ssh (struct config *config, char **extra_args, int wait_prompt) - #endif - - /* Create the miniexpect handle. */ -- h = mexp_spawnv ("ssh", (char **) args); -+ h = mexp_spawnvf (spawn_flags, "ssh", (char **) args); - if (h == NULL) { -- set_ssh_internal_error ("ssh: mexp_spawnv: %m"); -+ set_ssh_internal_error ("ssh: mexp_spawnvf: %m"); - return NULL; - } - -@@ -756,7 +757,7 @@ test_connection (struct config *config) - const int ovecsize = 12; - int ovector[ovecsize]; - -- h = start_ssh (config, NULL, 1); -+ h = start_ssh (0, config, NULL, 1); - if (h == NULL) - return -1; - -@@ -1063,7 +1064,7 @@ open_data_connection (struct config *config, int *local_port, int *remote_port) - *local_port = nbd_local_port; - nbd_local_port++; - -- h = start_ssh (config, (char **) extra_args, 0); -+ h = start_ssh (0, config, (char **) extra_args, 0); - if (h == NULL) - return NULL; - -@@ -1151,7 +1152,12 @@ start_remote_connection (struct config *config, const char *remote_dir) - { - mexp_h *h; - -- h = start_ssh (config, NULL, 1); -+ /* This connection is opened in cooked mode so that we can send ^C -+ * if the conversion needs to be cancelled. However that also means -+ * we must be careful not to accidentally send any control -+ * characters over this connection at other times. -+ */ -+ h = start_ssh (MEXP_SPAWN_COOKED_MODE, config, NULL, 1); - if (h == NULL) - return NULL; - --- -1.8.3.1 - diff --git a/SOURCES/0147-p2v-Send-C-to-remote-end-to-cancel-the-conversion.patch b/SOURCES/0147-p2v-Send-C-to-remote-end-to-cancel-the-conversion.patch deleted file mode 100644 index 52058f1..0000000 --- a/SOURCES/0147-p2v-Send-C-to-remote-end-to-cancel-the-conversion.patch +++ /dev/null @@ -1,147 +0,0 @@ -From 547504706ea62956201d40c230d2ab85bd99fbc4 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Thu, 30 Jun 2016 14:13:24 +0100 -Subject: [PATCH] p2v: Send ^C to remote end to cancel the conversion. - -We are now able to cancel the conversion instantly by sending ^C to -the remote virt-v2v process. - -Also, this reverts: -"p2v: Poll to make Cancel Conversion button more responsive." -(commit 6da4941db7f8a85997d6281b9b4c5165768e6489) - -(cherry picked from commit 87131d8681b6e72dac4d8c952f3b3fb7ade02eed) ---- - p2v/conversion.c | 60 +++++++++++++++++++++++++++----------------------------- - 1 file changed, 29 insertions(+), 31 deletions(-) - -diff --git a/p2v/conversion.c b/p2v/conversion.c -index f9b8350..484c0e4 100644 ---- a/p2v/conversion.c -+++ b/p2v/conversion.c -@@ -25,7 +25,6 @@ - #include - #include - #include --#include - #include - #include - #include -@@ -127,6 +126,7 @@ static pthread_mutex_t running_mutex = PTHREAD_MUTEX_INITIALIZER; - static int running = 0; - static pthread_mutex_t cancel_requested_mutex = PTHREAD_MUTEX_INITIALIZER; - static int cancel_requested = 0; -+static mexp_h *control_h = NULL; - - static int - is_running (void) -@@ -161,6 +161,21 @@ set_cancel_requested (int r) - { - pthread_mutex_lock (&cancel_requested_mutex); - cancel_requested = r; -+ -+ /* Send ^C to the remote so that virt-v2v "knows" the connection has -+ * been cancelled. mexp_send_interrupt is a single write(2) call. -+ */ -+ if (r && control_h) -+ ignore_value (mexp_send_interrupt (control_h)); -+ -+ pthread_mutex_unlock (&cancel_requested_mutex); -+} -+ -+static void -+set_control_h (mexp_h *new_h) -+{ -+ pthread_mutex_lock (&cancel_requested_mutex); -+ control_h = new_h; - pthread_mutex_unlock (&cancel_requested_mutex); - } - -@@ -175,7 +190,6 @@ start_conversion (struct config *config, - const size_t nr_disks = guestfs_int_count_strings (config->disks); - time_t now; - struct tm tm; -- mexp_h *control_h = NULL; - struct data_conn data_conns[nr_disks]; - CLEANUP_FREE char *remote_dir = NULL; - char tmpdir[] = "/tmp/p2v.XXXXXX"; -@@ -189,6 +203,7 @@ start_conversion (struct config *config, - fprintf (stderr, "\n"); - #endif - -+ set_control_h (NULL); - set_running (1); - set_cancel_requested (0); - -@@ -299,7 +314,7 @@ start_conversion (struct config *config, - if (notify_ui) - notify_ui (NOTIFY_STATUS, _("Setting up the control connection ...")); - -- control_h = start_remote_connection (config, remote_dir); -+ set_control_h (start_remote_connection (config, remote_dir)); - if (control_h == NULL) { - set_conversion_error ("could not open control connection over SSH to the conversion server: %s", - get_ssh_error ()); -@@ -346,35 +361,13 @@ start_conversion (struct config *config, - } - - /* Read output from the virt-v2v process and echo it through the -- * notify function, until virt-v2v closes the connection. We -- * actually poll in this loop (albeit it only every 2 seconds) so -- * that the user won't have to wait too long between pressing the -- * cancel button and having the conversion cancelled. -+ * notify function, until virt-v2v closes the connection. - */ - while (!is_cancel_requested ()) { -- int fd = mexp_get_fd (control_h); -- struct pollfd fds[1]; -- int rp; - char buf[257]; - ssize_t r; - -- fds[0].fd = fd; -- fds[0].events = POLLIN; -- fds[0].revents = 0; -- rp = poll (fds, 1, 2000 /* ms */); -- if (rp == -1) { -- /* See comment about this in miniexpect.c. */ -- if (errno == EIO) -- break; -- set_conversion_error ("poll: %m"); -- goto out; -- } -- else if (rp == 0) -- /* Timeout. */ -- continue; -- /* ... else rp == 1, ignore revents and just do the read. */ -- -- r = read (fd, buf, sizeof buf - 1); -+ r = read (mexp_get_fd (control_h), buf, sizeof buf - 1); - if (r == -1) { - /* See comment about this in miniexpect.c. */ - if (errno == EIO) -@@ -402,12 +395,17 @@ start_conversion (struct config *config, - ret = 0; - out: - if (control_h) { -- if ((status = mexp_close (control_h)) == -1) { -+ mexp_h *h = control_h; -+ set_control_h (NULL); -+ status = mexp_close (h); -+ -+ if (status == -1) { - set_conversion_error ("mexp_close: %m"); - ret = -1; -- } else if (ret == 0 && -- WIFEXITED (status) && -- WEXITSTATUS (status) != 0) { -+ } -+ else if (ret == 0 && -+ WIFEXITED (status) && -+ WEXITSTATUS (status) != 0) { - set_conversion_error ("virt-v2v exited with status %d", - WEXITSTATUS (status)); - ret = -1; --- -1.8.3.1 - diff --git a/SOURCES/0148-p2v-Remove-the-Enable-debugging-option-v-p2v.debug.patch b/SOURCES/0148-p2v-Remove-the-Enable-debugging-option-v-p2v.debug.patch deleted file mode 100644 index d7b417c..0000000 --- a/SOURCES/0148-p2v-Remove-the-Enable-debugging-option-v-p2v.debug.patch +++ /dev/null @@ -1,310 +0,0 @@ -From 9b713219612d9ad012729a98d58f033c2bb40ccf Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Wed, 6 Jul 2016 12:58:49 -0400 -Subject: [PATCH] p2v: Remove the Enable debugging option, -v, p2v.debug. - -This is now enabled by default and cannot be changed/disabled by the -user. The output is saved into /tmp/.../virt-v2v-conversion-log.txt -on the conversion server. - -(cherry picked from commit 0c04919f50685c583842b48ca035626753e959e5) ---- - p2v/config.c | 5 ----- - p2v/conversion.c | 4 +--- - p2v/gui.c | 11 ----------- - p2v/kernel.c | 22 +++++++++------------- - p2v/main.c | 4 +++- - p2v/p2v.h | 7 ------- - p2v/ssh.c | 7 +++---- - p2v/utils.c | 10 +++++----- - p2v/virt-p2v.pod | 19 ++----------------- - 9 files changed, 23 insertions(+), 66 deletions(-) - -diff --git a/p2v/config.c b/p2v/config.c -index 79b7e4d..40c758e 100644 ---- a/p2v/config.c -+++ b/p2v/config.c -@@ -40,9 +40,6 @@ new_config (void) - exit (EXIT_FAILURE); - } - --#if FORCE_REMOTE_DEBUG -- c->verbose = 1; --#endif - c->port = 22; - - c->output_allocation = OUTPUT_ALLOCATION_NONE; -@@ -119,8 +116,6 @@ print_config (struct config *config, FILE *fp) - fprintf (fp, "local version . %s\n", PACKAGE_VERSION_FULL); - fprintf (fp, "remote version . %s\n", - v2v_version ? v2v_version : "unknown"); -- fprintf (fp, "remote debugging %s\n", -- config->verbose ? "true" : "false"); - fprintf (fp, "conversion server %s\n", - config->server ? config->server : "none"); - fprintf (fp, "port . . . . . . %d\n", config->port); -diff --git a/p2v/conversion.c b/p2v/conversion.c -index 484c0e4..2d125a8 100644 ---- a/p2v/conversion.c -+++ b/p2v/conversion.c -@@ -960,9 +960,7 @@ generate_wrapper_script (struct config *config, const char *remote_dir, - fprintf (fp, "{\n"); - if (config->sudo) - fprintf (fp, "sudo -n "); -- fprintf (fp, "virt-v2v"); -- if (config->verbose) -- fprintf (fp, " -v -x"); -+ fprintf (fp, "virt-v2v -v -x"); - if (feature_colours_option) - fprintf (fp, " --colours"); - fprintf (fp, " -i libvirtxml"); -diff --git a/p2v/gui.c b/p2v/gui.c -index 9e9043a..e0b455a 100644 ---- a/p2v/gui.c -+++ b/p2v/gui.c -@@ -63,7 +63,6 @@ static GtkWidget *conv_dlg, - *vcpus_warning, *memory_warning, *target_warning_label, - *o_combo, *oc_entry, *os_entry, *of_entry, *oa_combo, - *info_label, -- *debug_button, - *disks_list, *removable_list, *interfaces_list, - *start_button; - -@@ -674,14 +673,7 @@ create_conversion_dialog (struct config *config) - gtk_table_attach (GTK_TABLE (output_tbl), oa_combo, - 1, 2, 4, 5, GTK_FILL, GTK_FILL, 1, 1); - -- debug_button = -- gtk_check_button_new_with_label (_("Enable server-side debugging\n" -- "(This is saved in /tmp on the conversion server)")); -- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (debug_button), -- config->verbose); -- - gtk_box_pack_start (GTK_BOX (output_vbox), output_tbl, TRUE, TRUE, 0); -- gtk_box_pack_start (GTK_BOX (output_vbox), debug_button, TRUE, TRUE, 0); - gtk_container_add (GTK_CONTAINER (output_frame), output_vbox); - - info_frame = gtk_frame_new (_("Information")); -@@ -1688,9 +1680,6 @@ start_conversion_clicked (GtkWidget *w, gpointer data) - config->vcpus = get_vcpus_from_conv_dlg (); - config->memory = get_memory_from_conv_dlg (); - -- config->verbose = -- gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (debug_button)); -- - /* Get the list of disks to be converted. */ - set_disks_from_ui (config); - -diff --git a/p2v/kernel.c b/p2v/kernel.c -index 6914ab5..455af3e 100644 ---- a/p2v/kernel.c -+++ b/p2v/kernel.c -@@ -35,17 +35,13 @@ - #include "p2v.h" - - static void notify_ui_callback (int type, const char *data); --static void run_command (int verbose, const char *stage, const char *command); -+static void run_command (const char *stage, const char *command); - - void - update_config_from_kernel_cmdline (struct config *config, char **cmdline) - { - const char *p; - -- p = get_cmdline_key (cmdline, "p2v.debug"); -- if (p) -- config->verbose = 1; -- - p = get_cmdline_key (cmdline, "p2v.server"); - if (p) { - free (config->server); -@@ -212,7 +208,7 @@ kernel_conversion (struct config *config, char **cmdline, int cmdline_source) - /* Pre-conversion command. */ - p = get_cmdline_key (cmdline, "p2v.pre"); - if (p) -- run_command (config->verbose, "p2v.pre", p); -+ run_command ("p2v.pre", p); - - /* Connect to and interrogate virt-v2v on the conversion server. */ - p = get_cmdline_key (cmdline, "p2v.skip_test_connection"); -@@ -245,7 +241,7 @@ kernel_conversion (struct config *config, char **cmdline, int cmdline_source) - - p = get_cmdline_key (cmdline, "p2v.fail"); - if (p) -- run_command (config->verbose, "p2v.fail", p); -+ run_command ("p2v.fail", p); - - exit (EXIT_FAILURE); - } -@@ -261,7 +257,7 @@ kernel_conversion (struct config *config, char **cmdline, int cmdline_source) - p = "poweroff"; - } - if (p) -- run_command (config->verbose, "p2v.post", p); -+ run_command ("p2v.post", p); - } - - static void -@@ -300,17 +296,17 @@ notify_ui_callback (int type, const char *data) - } - - static void --run_command (int verbose, const char *stage, const char *command) -+run_command (const char *stage, const char *command) - { - int r; - - if (STREQ (command, "")) - return; - -- if (verbose) { -- printf ("%s\n", command); -- fflush (stdout); -- } -+#if DEBUG_STDERR -+ fprintf (stderr, "%s\n", command); -+ fflush (stderr); -+#endif - - r = system (command); - if (r == -1) { -diff --git a/p2v/main.c b/p2v/main.c -index c5ab233..4441b99 100644 ---- a/p2v/main.c -+++ b/p2v/main.c -@@ -181,7 +181,9 @@ main (int argc, char *argv[]) - break; - - case 'v': -- config->verbose = 1; -+ /* This option does nothing since 1.33.41. Verbose is always -+ * enabled. -+ */ - break; - - case 'V': -diff --git a/p2v/p2v.h b/p2v/p2v.h -index da30340..1282a17 100644 ---- a/p2v/p2v.h -+++ b/p2v/p2v.h -@@ -26,12 +26,6 @@ - */ - #define DEBUG_STDERR 1 - --/* Force remote debugging even if user doesn't enable it. Since -- * remote debugging is mostly free, we might as well enable this even -- * in production. -- */ --#define FORCE_REMOTE_DEBUG 1 -- - #include "miniexpect.h" - - /* We don't use libguestfs directly here, and we don't link to it -@@ -66,7 +60,6 @@ extern int force_colour; - - /* config.c */ - struct config { -- int verbose; - char *server; - int port; - char *username; -diff --git a/p2v/ssh.c b/p2v/ssh.c -index 4cae732..7507ed6 100644 ---- a/p2v/ssh.c -+++ b/p2v/ssh.c -@@ -374,7 +374,7 @@ start_ssh (unsigned spawn_flags, struct config *config, - args[j++] = NULL; - assert (j == nr_args); - --#if DEBUG_STDERR && 0 -+#if DEBUG_STDERR - fputs ("ssh command: ", stderr); - for (i = 0; i < nr_args - 1; ++i) { - if (i > 0) fputc (' ', stderr); -@@ -583,6 +583,7 @@ scp_file (struct config *config, const char *localfile, const char *remotefile) - const int ovecsize = 12; - int ovector[ovecsize]; - int using_password_auth; -+ size_t i; - - if (cache_ssh_identity (config) == -1) - return -1; -@@ -631,9 +632,7 @@ scp_file (struct config *config, const char *localfile, const char *remotefile) - args[j++] = NULL; - assert (j == nr_args); - --#if DEBUG_STDERR && 0 -- size_t i; -- -+#if DEBUG_STDERR - fputs ("scp command: ", stderr); - for (i = 0; i < nr_args - 1; ++i) { - if (i > 0) fputc (' ', stderr); -diff --git a/p2v/utils.c b/p2v/utils.c -index c9fbd2f..71f5916 100644 ---- a/p2v/utils.c -+++ b/p2v/utils.c -@@ -247,11 +247,11 @@ get_if_vendor (const char *if_name, int truncate) - void - wait_network_online (const struct config *config) - { -- if (config->verbose) { -- printf ("waiting for the network to come online ...\n"); -- printf ("%s\n", NETWORK_ONLINE_COMMAND); -- fflush (stdout); -- } -+#ifdef DEBUG_STDERR -+ fprintf (stderr, "waiting for the network to come online ...\n"); -+ fprintf (stderr, "%s\n", NETWORK_ONLINE_COMMAND); -+ fflush (stderr); -+#endif - - ignore_value (system (NETWORK_ONLINE_COMMAND)); - } -diff --git a/p2v/virt-p2v.pod b/p2v/virt-p2v.pod -index ef6a9db..6532240 100644 ---- a/p2v/virt-p2v.pod -+++ b/p2v/virt-p2v.pod -@@ -177,14 +177,6 @@ first-time virt-p2v user. - All output options and paths are relative to the conversion server - (I to the physical server). - --The final option in this panel enables server-side debugging. This --produces a lot of output, but is essential if you are tracking down --virt-p2v or virt-v2v problems, and can generally be left enabled: -- -- │ -- │ [✔] Enable server-side debugging -- │ -- - Finally in the left hand column is an information box giving the - version of virt-p2v (on the physical server) and virt-v2v (on the - conversion server). You should supply this information when reporting -@@ -371,14 +363,6 @@ C. - The default is to use the same amount of RAM as on the physical - machine. - --=item B -- --Use this to enable full debugging of virt-v2v. -- --If asked to diagnose a problem with virt-p2v, you should add --C to the kernel command line, and examine the log file --which is left in F on the conversion server. -- - =item B - - A list of physical hard disks to convert, for example: -@@ -615,7 +599,8 @@ features such as the Reboot button. - - =item B<--verbose> - --Enable debugging (on the conversion server). -+In libguestfs E 1.33.41, debugging is always enabled on the -+conversion server, and this option does nothing. - - =item B<-V> - --- -1.8.3.1 - diff --git a/SOURCES/0149-p2v-Remove-p2v.debug-option-from-test-command-lines.patch b/SOURCES/0149-p2v-Remove-p2v.debug-option-from-test-command-lines.patch deleted file mode 100644 index 84f7ed7..0000000 --- a/SOURCES/0149-p2v-Remove-p2v.debug-option-from-test-command-lines.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 4df430d654c0055fe1d726d96b82ef0599a0e047 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Sat, 2 Jul 2016 10:16:55 +0100 -Subject: [PATCH] p2v: Remove p2v.debug option from test command lines. - -Fixes commit 0c04919f50685c583842b48ca035626753e959e5. - -(cherry picked from commit d6744dac60be0b99f6b6fcfb6a1209a8cc5faabc) ---- - p2v/test-virt-p2v-pxe.sh | 2 +- - p2v/test-virt-p2v.sh | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/p2v/test-virt-p2v-pxe.sh b/p2v/test-virt-p2v-pxe.sh -index 70bd2e4..334808d 100755 ---- a/p2v/test-virt-p2v-pxe.sh -+++ b/p2v/test-virt-p2v-pxe.sh -@@ -97,7 +97,7 @@ username="$(id -un)" - os="$(cd $d; pwd)" - - # The Linux kernel command line. --cmdline="root=/dev/sda3 ro console=ttyS0 printk.time=1 p2v.debug p2v.server=10.0.2.2 p2v.port=$port p2v.username=$username p2v.identity=file:///var/tmp/id_rsa p2v.name=windows p2v.o=local p2v.os=$os" -+cmdline="root=/dev/sda3 ro console=ttyS0 printk.time=1 p2v.server=10.0.2.2 p2v.port=$port p2v.username=$username p2v.identity=file:///var/tmp/id_rsa p2v.name=windows p2v.o=local p2v.os=$os" - - # Run virt-p2v inside qemu. - $qemu \ -diff --git a/p2v/test-virt-p2v.sh b/p2v/test-virt-p2v.sh -index e232d42..d464a46 100755 ---- a/p2v/test-virt-p2v.sh -+++ b/p2v/test-virt-p2v.sh -@@ -62,7 +62,7 @@ export PATH=$d:$PATH - # binaries under test (because of the ./run script). - - # The Linux kernel command line. --cmdline="p2v.server=localhost p2v.name=windows p2v.debug p2v.disks=$f1,$f2 p2v.o=local p2v.os=$(pwd)/$d p2v.network=em1:wired,other p2v.post=" -+cmdline="p2v.server=localhost p2v.name=windows p2v.disks=$f1,$f2 p2v.o=local p2v.os=$(pwd)/$d p2v.network=em1:wired,other p2v.post=" - - virt-p2v --cmdline="$cmdline" - --- -1.8.3.1 - diff --git a/SOURCES/0150-v2v-Fix-documentation-in-place-I-in-place.patch b/SOURCES/0150-v2v-Fix-documentation-in-place-I-in-place.patch deleted file mode 100644 index ec1348d..0000000 --- a/SOURCES/0150-v2v-Fix-documentation-in-place-I-in-place.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 465b54da95256ed7c38bf5245ff1ead2186f5f87 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Wed, 6 Jul 2016 10:46:21 +0100 -Subject: [PATCH] v2v: Fix documentation, [--in-place] -> I<--in-place>. - -Fixes commit 9221ef6f7959ae3b979fd05007363810bc66062b. - -(cherry picked from commit 70faafddbad555bd01ab00b09b1e63a60663b82f) ---- - v2v/virt-v2v.pod | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/v2v/virt-v2v.pod b/v2v/virt-v2v.pod -index c68bcb5..9fc0b72 100644 ---- a/v2v/virt-v2v.pod -+++ b/v2v/virt-v2v.pod -@@ -1575,7 +1575,7 @@ Minimum free space: 10 MB - =head2 Minimum free space check in the host - - You must have sufficient free space in the host directory used to --store temporary overlays (except in [--in-place] mode). To find out -+store temporary overlays (except in I<--in-place> mode). To find out - which directory this is, use: - - $ df -h "`guestfish get-cachedir`" --- -1.8.3.1 - diff --git a/SOURCES/0151-v2v-Add-support-for-Win2016-virtio-drivers.patch b/SOURCES/0151-v2v-Add-support-for-Win2016-virtio-drivers.patch deleted file mode 100644 index 60862a6..0000000 --- a/SOURCES/0151-v2v-Add-support-for-Win2016-virtio-drivers.patch +++ /dev/null @@ -1,32 +0,0 @@ -From a1b6b441af71dbc032eed3d4707e851e1f019270 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Golembiovsk=C3=BD?= -Date: Tue, 12 Jul 2016 05:53:49 +0200 -Subject: [PATCH] v2v: Add support for Win2016 virtio drivers -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Support virtio drivers for Windows Server 2016 once they are available. - -Signed-off-by: Tomáš Golembiovský -(cherry picked from commit e93d4ea320485e68b2e629ca3498d5475a373781) ---- - v2v/windows_virtio.ml | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/v2v/windows_virtio.ml b/v2v/windows_virtio.ml -index 6237a09..c5d6c91 100644 ---- a/v2v/windows_virtio.ml -+++ b/v2v/windows_virtio.ml -@@ -456,6 +456,8 @@ and virtio_iso_path_matches_guest_os path inspect = - (6, 3, not_client) - else if pathelem "w10" || pathelem "win10" then - (10, 0, is_client) -+ else if pathelem "2k16" || pathelem "win2016" then -+ (10, 0, not_client) - else - raise Not_found in - --- -1.8.3.1 - diff --git a/SOURCES/0152-v2v-Move-augeas_debug_errors-renamed-debug_augeas_er.patch b/SOURCES/0152-v2v-Move-augeas_debug_errors-renamed-debug_augeas_er.patch deleted file mode 100644 index 6147cef..0000000 --- a/SOURCES/0152-v2v-Move-augeas_debug_errors-renamed-debug_augeas_er.patch +++ /dev/null @@ -1,581 +0,0 @@ -From 3efce06fd92ef66098f84bd9955ff9b4c16cb6f4 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Wed, 13 Jul 2016 19:16:07 +0100 -Subject: [PATCH] v2v: Move augeas_debug_errors (renamed debug_augeas_errors) - to common code. - -Since the function uses the StringMap module, I also had to -move this to mllib. - -The function is renamed and the 'if verbose ()' part is moved into the -function, but apart from that, it's all just code motion. - -(cherry picked from commit eb22e2d36e3a28805f36e43b2be549ccbd3457b1) ---- - builder/Makefile.am | 1 + - customize/Makefile.am | 1 + - dib/Makefile.am | 1 + - get-kernel/Makefile.am | 1 + - mllib/Makefile.am | 3 +++ - mllib/common_utils.ml | 63 +++++++++++++++++++++++++++++++++++++++++++ - mllib/common_utils.mli | 14 ++++++++++ - mllib/stringMap.ml | 21 +++++++++++++++ - mllib/stringMap.mli | 54 +++++++++++++++++++++++++++++++++++++ - po/POTFILES-ml | 2 +- - resize/Makefile.am | 1 + - sparsify/Makefile.am | 1 + - sysprep/Makefile.am | 1 + - v2v/Makefile.am | 6 ++--- - v2v/linux.ml | 64 ++------------------------------------------ - v2v/stringMap.ml | 21 --------------- - v2v/stringMap.mli | 54 ------------------------------------- - v2v/test-harness/Makefile.am | 1 + - 18 files changed, 169 insertions(+), 141 deletions(-) - create mode 100644 mllib/stringMap.ml - create mode 100644 mllib/stringMap.mli - delete mode 100644 v2v/stringMap.ml - delete mode 100644 v2v/stringMap.mli - -diff --git a/builder/Makefile.am b/builder/Makefile.am -index 54aa10b..d69e7ec 100644 ---- a/builder/Makefile.am -+++ b/builder/Makefile.am -@@ -136,6 +136,7 @@ BOBJECTS = \ - $(top_builddir)/mllib/guestfs_config.cmo \ - $(top_builddir)/mllib/common_gettext.cmo \ - $(top_builddir)/mllib/dev_t.cmo \ -+ $(top_builddir)/mllib/stringMap.cmo \ - $(top_builddir)/mllib/common_utils.cmo \ - $(top_builddir)/mllib/fsync.cmo \ - $(top_builddir)/mllib/planner.cmo \ -diff --git a/customize/Makefile.am b/customize/Makefile.am -index 661917a..05f144f 100644 ---- a/customize/Makefile.am -+++ b/customize/Makefile.am -@@ -95,6 +95,7 @@ BOBJECTS = \ - $(top_builddir)/mllib/guestfs_config.cmo \ - $(top_builddir)/mllib/common_gettext.cmo \ - $(top_builddir)/mllib/dev_t.cmo \ -+ $(top_builddir)/mllib/stringMap.cmo \ - $(top_builddir)/mllib/common_utils.cmo \ - $(top_builddir)/mllib/regedit.cmo \ - $(top_builddir)/mllib/URI.cmo \ -diff --git a/dib/Makefile.am b/dib/Makefile.am -index d1674a9..ff6a933 100644 ---- a/dib/Makefile.am -+++ b/dib/Makefile.am -@@ -59,6 +59,7 @@ BOBJECTS = \ - $(top_builddir)/mllib/guestfs_config.cmo \ - $(top_builddir)/mllib/common_gettext.cmo \ - $(top_builddir)/mllib/dev_t.cmo \ -+ $(top_builddir)/mllib/stringMap.cmo \ - $(top_builddir)/mllib/common_utils.cmo \ - $(top_builddir)/mllib/mkdtemp.cmo \ - $(SOURCES_ML:.ml=.cmo) -diff --git a/get-kernel/Makefile.am b/get-kernel/Makefile.am -index 9d8fc61..e2d78b0 100644 ---- a/get-kernel/Makefile.am -+++ b/get-kernel/Makefile.am -@@ -58,6 +58,7 @@ BOBJECTS = \ - $(top_builddir)/mllib/guestfs_config.cmo \ - $(top_builddir)/mllib/common_gettext.cmo \ - $(top_builddir)/mllib/dev_t.cmo \ -+ $(top_builddir)/mllib/stringMap.cmo \ - $(top_builddir)/mllib/common_utils.cmo \ - $(top_builddir)/mllib/URI.cmo \ - $(SOURCES_ML:.ml=.cmo) -diff --git a/mllib/Makefile.am b/mllib/Makefile.am -index 0a6dd93..8807d86 100644 ---- a/mllib/Makefile.am -+++ b/mllib/Makefile.am -@@ -37,11 +37,13 @@ SOURCES_MLI = \ - progress.mli \ - regedit.mli \ - StatVFS.mli \ -+ stringMap.mli \ - URI.mli - - SOURCES_ML = \ - guestfs_config.ml \ - libdir.ml \ -+ stringMap.ml \ - common_gettext.ml \ - dev_t.ml \ - common_utils.ml \ -@@ -150,6 +152,7 @@ common_utils_tests_BOBJECTS = \ - guestfs_config.cmo \ - common_gettext.cmo \ - dev_t.cmo \ -+ stringMap.cmo \ - common_utils.cmo \ - common_utils_tests.cmo - common_utils_tests_XOBJECTS = $(common_utils_tests_BOBJECTS:.cmo=.cmx) -diff --git a/mllib/common_utils.ml b/mllib/common_utils.ml -index 7bd02f8..2dfe475 100644 ---- a/mllib/common_utils.ml -+++ b/mllib/common_utils.ml -@@ -796,6 +796,69 @@ let truncate_recursive (g : Guestfs.guestfs) dir = - let files = List.filter g#is_file files in - List.iter g#truncate files - -+let debug_augeas_errors g = -+ if verbose () then ( -+ try -+ let errors = g#aug_match "/augeas/files//error" in -+ let errors = Array.to_list errors in -+ let map = -+ List.fold_left ( -+ fun map error -> -+ let detail_paths = g#aug_match (error ^ "//*") in -+ let detail_paths = Array.to_list detail_paths in -+ List.fold_left ( -+ fun map path -> -+ (* path is "/augeas/files//error/". Put -+ * , and the value of this Augeas field -+ * into a map. -+ *) -+ let i = String.find path "/error/" in -+ assert (i >= 0); -+ let filename = String.sub path 13 (i-13) in -+ let field = -+ String.sub path (i+7) (String.length path - (i+7)) in -+ -+ let detail = g#aug_get path in -+ -+ let fmap : string StringMap.t = -+ try StringMap.find filename map -+ with Not_found -> StringMap.empty in -+ let fmap = StringMap.add field detail fmap in -+ StringMap.add filename fmap map -+ ) map detail_paths -+ ) StringMap.empty errors in -+ -+ let filenames = StringMap.keys map in -+ let filenames = List.sort compare filenames in -+ -+ List.iter ( -+ fun filename -> -+ eprintf "augeas failed to parse %s:\n" filename; -+ let fmap = StringMap.find filename map in -+ (try -+ let msg = StringMap.find "message" fmap in -+ eprintf " error \"%s\"" msg -+ with Not_found -> () -+ ); -+ (try -+ let line = StringMap.find "line" fmap -+ and char = StringMap.find "char" fmap in -+ eprintf " at line %s char %s" line char -+ with Not_found -> () -+ ); -+ (try -+ let lens = StringMap.find "lens" fmap in -+ eprintf " in lens %s" lens -+ with Not_found -> () -+ ); -+ eprintf "\n" -+ ) filenames; -+ -+ flush stderr -+ with -+ Guestfs.Error msg -> eprintf "%s: augeas: %s (ignored)\n" prog msg -+ ) -+ - (* Detect type of a file. *) - let detect_file_type filename = - let chan = open_in filename in -diff --git a/mllib/common_utils.mli b/mllib/common_utils.mli -index 4cfe7d0..c66efa7 100644 ---- a/mllib/common_utils.mli -+++ b/mllib/common_utils.mli -@@ -319,6 +319,20 @@ val truncate_recursive : Guestfs.guestfs -> string -> unit - (** Using the libguestfs API, recurse into the given directory and - truncate all files found to zero size. *) - -+val debug_augeas_errors : Guestfs.guestfs -> unit -+(** In verbose mode, any Augeas errors which happened most recently -+ on the handle and printed on standard error. You should usually -+ call this just after either [g#aug_init] or [g#aug_load]. -+ -+ Note this doesn't call {!error} if there were any errors on the -+ handle. It is just for debugging. It is expected that a -+ subsequent Augeas command will fail, eg. when trying to match -+ an Augeas path which is expected to exist but does not exist -+ because of a parsing error. In that case turning on debugging -+ will reveal the parse error. -+ -+ If not in verbose mode, this does nothing. *) -+ - val detect_file_type : string -> [`GZip | `Tar | `XZ | `Zip | `Unknown] - (** Detect type of a file (for a very limited range of file types). *) - -diff --git a/mllib/stringMap.ml b/mllib/stringMap.ml -new file mode 100644 -index 0000000..ea47a6e ---- /dev/null -+++ b/mllib/stringMap.ml -@@ -0,0 +1,21 @@ -+(* virt-v2v -+ * Copyright (C) 2009-2016 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 Map.Make (String) -+ -+let keys map = fold (fun k _ ks -> k :: ks) map [] -diff --git a/mllib/stringMap.mli b/mllib/stringMap.mli -new file mode 100644 -index 0000000..b668538 ---- /dev/null -+++ b/mllib/stringMap.mli -@@ -0,0 +1,54 @@ -+(* virt-v2v -+ * Copyright (C) 2009-2016 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. -+ *) -+ -+type key = String.t -+type 'a t = 'a Map.Make(String).t -+ -+val empty : 'a t -+val is_empty : 'a t -> bool -+val mem : key -> 'a t -> bool -+val add : key -> 'a -> 'a t -> 'a t -+(* -+val singleton : key -> 'a -> 'a t -+*) -+val remove : key -> 'a t -> 'a t -+(* -+val merge : (key -> 'a option -> 'b option -> 'c option) -> 'a t -> 'b t -> 'c t -+*) -+val compare : ('a -> 'a -> int) -> 'a t -> 'a t -> int -+val equal : ('a -> 'a -> bool) -> 'a t -> 'a t -> bool -+val iter : (key -> 'a -> unit) -> 'a t -> unit -+val fold : (key -> 'a -> 'b -> 'b) -> 'a t -> 'b -> 'b -+(* -+val for_all : (key -> 'a -> bool) -> 'a t -> bool -+val exists : (key -> 'a -> bool) -> 'a t -> bool -+val filter : (key -> 'a -> bool) -> 'a t -> 'a t -+val partition : (key -> 'a -> bool) -> 'a t -> 'a t * 'a t -+val cardinal : 'a t -> int -+val bindings : 'a t -> (key * 'a) list -+val min_binding : 'a t -> key * 'a -+val max_binding : 'a t -> key * 'a -+val choose : 'a t -> key * 'a -+val split : key -> 'a t -> 'a t * 'a option * 'a t -+*) -+val find : key -> 'a t -> 'a -+val map : ('a -> 'b) -> 'a t -> 'b t -+(* -+val mapi : (key -> 'a -> 'b) -> 'a t -> 'b t -+*) -+val keys : 'a t -> key list -diff --git a/po/POTFILES-ml b/po/POTFILES-ml -index 5937ff5..4ea49a5 100644 ---- a/po/POTFILES-ml -+++ b/po/POTFILES-ml -@@ -52,6 +52,7 @@ mllib/mkdtemp.ml - mllib/planner.ml - mllib/progress.ml - mllib/regedit.ml -+mllib/stringMap.ml - resize/resize.ml - sparsify/cmdline.ml - sparsify/copying.ml -@@ -123,7 +124,6 @@ v2v/output_null.ml - v2v/output_qemu.ml - v2v/output_rhev.ml - v2v/output_vdsm.ml --v2v/stringMap.ml - v2v/target_bus_assignment.ml - v2v/test-harness/v2v_test_harness.ml - v2v/types.ml -diff --git a/resize/Makefile.am b/resize/Makefile.am -index e9f48da..c3c025d 100644 ---- a/resize/Makefile.am -+++ b/resize/Makefile.am -@@ -60,6 +60,7 @@ BOBJECTS = \ - $(top_builddir)/mllib/guestfs_config.cmo \ - $(top_builddir)/mllib/common_gettext.cmo \ - $(top_builddir)/mllib/dev_t.cmo \ -+ $(top_builddir)/mllib/stringMap.cmo \ - $(top_builddir)/mllib/common_utils.cmo \ - $(SOURCES_ML:.ml=.cmo) - XOBJECTS = $(BOBJECTS:.cmo=.cmx) -diff --git a/sparsify/Makefile.am b/sparsify/Makefile.am -index 9dd9179..22a684b 100644 ---- a/sparsify/Makefile.am -+++ b/sparsify/Makefile.am -@@ -59,6 +59,7 @@ BOBJECTS = \ - $(top_builddir)/mllib/guestfs_config.cmo \ - $(top_builddir)/mllib/common_gettext.cmo \ - $(top_builddir)/mllib/dev_t.cmo \ -+ $(top_builddir)/mllib/stringMap.cmo \ - $(top_builddir)/mllib/common_utils.cmo \ - $(top_builddir)/mllib/progress.cmo \ - $(top_builddir)/mllib/StatVFS.cmo \ -diff --git a/sysprep/Makefile.am b/sysprep/Makefile.am -index e439a88..46cc324 100644 ---- a/sysprep/Makefile.am -+++ b/sysprep/Makefile.am -@@ -108,6 +108,7 @@ BOBJECTS = \ - $(top_builddir)/mllib/guestfs_config.cmo \ - $(top_builddir)/mllib/common_gettext.cmo \ - $(top_builddir)/mllib/dev_t.cmo \ -+ $(top_builddir)/mllib/stringMap.cmo \ - $(top_builddir)/mllib/common_utils.cmo \ - $(top_builddir)/mllib/URI.cmo \ - $(top_builddir)/mllib/mkdtemp.cmo \ -diff --git a/v2v/Makefile.am b/v2v/Makefile.am -index e0d013a..09a63a0 100644 ---- a/v2v/Makefile.am -+++ b/v2v/Makefile.am -@@ -70,7 +70,6 @@ SOURCES_MLI = \ - output_rhev.mli \ - output_vdsm.mli \ - OVF.mli \ -- stringMap.mli \ - target_bus_assignment.mli \ - types.mli \ - utils.mli \ -@@ -80,7 +79,6 @@ SOURCES_MLI = \ - xml.mli - - SOURCES_ML = \ -- stringMap.ml \ - types.ml \ - xml.ml \ - utils.ml \ -@@ -142,6 +140,7 @@ BOBJECTS = \ - $(top_builddir)/mllib/guestfs_config.cmo \ - $(top_builddir)/mllib/common_gettext.cmo \ - $(top_builddir)/mllib/dev_t.cmo \ -+ $(top_builddir)/mllib/stringMap.cmo \ - $(top_builddir)/mllib/common_utils.cmo \ - $(top_builddir)/mllib/regedit.cmo \ - $(top_builddir)/mllib/mkdtemp.cmo \ -@@ -212,6 +211,7 @@ COPY_TO_LOCAL_BOBJECTS = \ - $(top_builddir)/mllib/guestfs_config.cmo \ - $(top_builddir)/mllib/common_gettext.cmo \ - $(top_builddir)/mllib/dev_t.cmo \ -+ $(top_builddir)/mllib/stringMap.cmo \ - $(top_builddir)/mllib/common_utils.cmo \ - $(top_builddir)/mllib/JSON.cmo \ - $(top_builddir)/mllib/StatVFS.cmo \ -@@ -373,9 +373,9 @@ v2v_unit_tests_BOBJECTS = \ - $(top_builddir)/mllib/guestfs_config.cmo \ - $(top_builddir)/mllib/common_gettext.cmo \ - $(top_builddir)/mllib/dev_t.cmo \ -+ $(top_builddir)/mllib/stringMap.cmo \ - $(top_builddir)/mllib/common_utils.cmo \ - $(top_builddir)/mllib/regedit.cmo \ -- stringMap.cmo \ - types.cmo \ - xml.cmo \ - utils.cmo \ -diff --git a/v2v/linux.ml b/v2v/linux.ml -index 8c1fde2..46cb3ba 100644 ---- a/v2v/linux.ml -+++ b/v2v/linux.ml -@@ -31,71 +31,11 @@ module G = Guestfs - *) - let rec augeas_init g = - g#aug_init "/" 1; -- if verbose () then augeas_debug_errors g -+ debug_augeas_errors g - - and augeas_reload g = - g#aug_load (); -- if verbose () then augeas_debug_errors g -- --and augeas_debug_errors g = -- try -- let errors = g#aug_match "/augeas/files//error" in -- let errors = Array.to_list errors in -- let map = -- List.fold_left ( -- fun map error -> -- let detail_paths = g#aug_match (error ^ "//*") in -- let detail_paths = Array.to_list detail_paths in -- List.fold_left ( -- fun map path -> -- (* path is "/augeas/files//error/". Put -- * , and the value of this Augeas field -- * into a map. -- *) -- let i = String.find path "/error/" in -- assert (i >= 0); -- let filename = String.sub path 13 (i-13) in -- let field = String.sub path (i+7) (String.length path - (i+7)) in -- -- let detail = g#aug_get path in -- -- let fmap : string StringMap.t = -- try StringMap.find filename map -- with Not_found -> StringMap.empty in -- let fmap = StringMap.add field detail fmap in -- StringMap.add filename fmap map -- ) map detail_paths -- ) StringMap.empty errors in -- -- let filenames = StringMap.keys map in -- let filenames = List.sort compare filenames in -- -- List.iter ( -- fun filename -> -- eprintf "augeas failed to parse %s:\n" filename; -- let fmap = StringMap.find filename map in -- (try -- let msg = StringMap.find "message" fmap in -- eprintf " error \"%s\"" msg -- with Not_found -> () -- ); -- (try -- let line = StringMap.find "line" fmap -- and char = StringMap.find "char" fmap in -- eprintf " at line %s char %s" line char -- with Not_found -> () -- ); -- (try -- let lens = StringMap.find "lens" fmap in -- eprintf " in lens %s" lens -- with Not_found -> () -- ); -- eprintf "\n" -- ) filenames; -- -- flush stderr -- with -- Guestfs.Error msg -> eprintf "%s: augeas: %s (ignored)\n" prog msg -+ debug_augeas_errors g - - let remove g inspect packages = - if packages <> [] then ( -diff --git a/v2v/stringMap.ml b/v2v/stringMap.ml -deleted file mode 100644 -index ea47a6e..0000000 ---- a/v2v/stringMap.ml -+++ /dev/null -@@ -1,21 +0,0 @@ --(* virt-v2v -- * Copyright (C) 2009-2016 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 Map.Make (String) -- --let keys map = fold (fun k _ ks -> k :: ks) map [] -diff --git a/v2v/stringMap.mli b/v2v/stringMap.mli -deleted file mode 100644 -index b668538..0000000 ---- a/v2v/stringMap.mli -+++ /dev/null -@@ -1,54 +0,0 @@ --(* virt-v2v -- * Copyright (C) 2009-2016 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. -- *) -- --type key = String.t --type 'a t = 'a Map.Make(String).t -- --val empty : 'a t --val is_empty : 'a t -> bool --val mem : key -> 'a t -> bool --val add : key -> 'a -> 'a t -> 'a t --(* --val singleton : key -> 'a -> 'a t --*) --val remove : key -> 'a t -> 'a t --(* --val merge : (key -> 'a option -> 'b option -> 'c option) -> 'a t -> 'b t -> 'c t --*) --val compare : ('a -> 'a -> int) -> 'a t -> 'a t -> int --val equal : ('a -> 'a -> bool) -> 'a t -> 'a t -> bool --val iter : (key -> 'a -> unit) -> 'a t -> unit --val fold : (key -> 'a -> 'b -> 'b) -> 'a t -> 'b -> 'b --(* --val for_all : (key -> 'a -> bool) -> 'a t -> bool --val exists : (key -> 'a -> bool) -> 'a t -> bool --val filter : (key -> 'a -> bool) -> 'a t -> 'a t --val partition : (key -> 'a -> bool) -> 'a t -> 'a t * 'a t --val cardinal : 'a t -> int --val bindings : 'a t -> (key * 'a) list --val min_binding : 'a t -> key * 'a --val max_binding : 'a t -> key * 'a --val choose : 'a t -> key * 'a --val split : key -> 'a t -> 'a t * 'a option * 'a t --*) --val find : key -> 'a t -> 'a --val map : ('a -> 'b) -> 'a t -> 'b t --(* --val mapi : (key -> 'a -> 'b) -> 'a t -> 'b t --*) --val keys : 'a t -> key list -diff --git a/v2v/test-harness/Makefile.am b/v2v/test-harness/Makefile.am -index cba5b41..5b376f0 100644 ---- a/v2v/test-harness/Makefile.am -+++ b/v2v/test-harness/Makefile.am -@@ -61,6 +61,7 @@ BOBJECTS = \ - $(top_builddir)/mllib/guestfs_config.cmo \ - $(top_builddir)/mllib/common_gettext.cmo \ - $(top_builddir)/mllib/dev_t.cmo \ -+ $(top_builddir)/mllib/stringMap.cmo \ - $(top_builddir)/mllib/common_utils.cmo \ - $(top_builddir)/v2v/xml.cmo \ - $(SOURCES_ML:.ml=.cmo) \ --- -1.8.3.1 - diff --git a/SOURCES/0153-New-API-selinux_relabel-SELinux-relabel-parts-of-the.patch b/SOURCES/0153-New-API-selinux_relabel-SELinux-relabel-parts-of-the.patch deleted file mode 100644 index 25ef14b..0000000 --- a/SOURCES/0153-New-API-selinux_relabel-SELinux-relabel-parts-of-the.patch +++ /dev/null @@ -1,250 +0,0 @@ -From dfb5c5ef41f696da5224ed28cc60bb47c8bed0fa Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Wed, 13 Jul 2016 18:33:55 +0100 -Subject: [PATCH] New API: selinux_relabel - SELinux relabel parts of the - filesystem. - -(cherry picked from commit 9d205f1c284a69390907120ca44f5c723fecc244) ---- - TODO | 6 --- - appliance/packagelist.in | 1 + - daemon/Makefile.am | 1 + - daemon/selinux-relabel.c | 100 +++++++++++++++++++++++++++++++++++++++++++++++ - generator/actions.ml | 23 +++++++++++ - gobject/Makefile.inc | 2 + - po/POTFILES | 2 + - src/MAX_PROC_NR | 2 +- - 8 files changed, 130 insertions(+), 7 deletions(-) - create mode 100644 daemon/selinux-relabel.c - -diff --git a/TODO b/TODO -index 90f6f68..fc20b2a 100644 ---- a/TODO -+++ b/TODO -@@ -59,12 +59,6 @@ Ideas for extra commands - - SELinux: - chcat -- restorecon -- [Wanlong Gao submitted patches for restorecon, but -- there are problems with using the restorecon binary -- from the host on the guest. Most of the time it -- would do more harm than good.] -- setfiles - - Oddball: - pivot_root -diff --git a/appliance/packagelist.in b/appliance/packagelist.in -index 6349922..38d39f8 100644 ---- a/appliance/packagelist.in -+++ b/appliance/packagelist.in -@@ -42,6 +42,7 @@ ifelse(REDHAT,1, - ntfs-3g - openssh-clients - pcre -+ policycoreutils - reiserfs-utils - libselinux - syslinux-extlinux -diff --git a/daemon/Makefile.am b/daemon/Makefile.am -index 20a6289..ac75439 100644 ---- a/daemon/Makefile.am -+++ b/daemon/Makefile.am -@@ -167,6 +167,7 @@ guestfsd_SOURCES = \ - rsync.c \ - scrub.c \ - selinux.c \ -+ selinux-relabel.c \ - sfdisk.c \ - sh.c \ - sleep.c \ -diff --git a/daemon/selinux-relabel.c b/daemon/selinux-relabel.c -new file mode 100644 -index 0000000..daafe9e ---- /dev/null -+++ b/daemon/selinux-relabel.c -@@ -0,0 +1,100 @@ -+/* libguestfs - the guestfsd daemon -+ * Copyright (C) 2016 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 -+ -+#include -+#include -+#include -+ -+#include "guestfs_protocol.h" -+#include "daemon.h" -+#include "actions.h" -+#include "optgroups.h" -+ -+GUESTFSD_EXT_CMD(str_setfiles, setfiles); -+ -+#define MAX_ARGS 64 -+ -+int -+optgroup_selinuxrelabel_available (void) -+{ -+ return prog_exists (str_setfiles); -+} -+ -+/* Takes optional arguments, consult optargs_bitmask. */ -+int -+do_selinux_relabel (const char *specfile, const char *path, -+ int force) -+{ -+ const char *argv[MAX_ARGS]; -+ CLEANUP_FREE char *s_dev = NULL, *s_proc = NULL, *s_selinux = NULL, -+ *s_sys = NULL, *s_specfile = NULL, *s_path = NULL; -+ CLEANUP_FREE char *err = NULL; -+ size_t i = 0; -+ -+ s_dev = sysroot_path ("/dev"); -+ if (!s_dev) { -+ malloc_error: -+ reply_with_perror ("malloc"); -+ return -1; -+ } -+ s_proc = sysroot_path ("/proc"); if (!s_proc) goto malloc_error; -+ s_selinux = sysroot_path ("/selinux"); if (!s_selinux) goto malloc_error; -+ s_sys = sysroot_path ("/sys"); if (!s_sys) goto malloc_error; -+ s_specfile = sysroot_path (specfile); if (!s_specfile) goto malloc_error; -+ s_path = sysroot_path (path); if (!s_path) goto malloc_error; -+ -+ /* Default settings if not selected. */ -+ if (!(optargs_bitmask & GUESTFS_SELINUX_RELABEL_FORCE_BITMASK)) -+ force = 0; -+ -+ ADD_ARG (argv, i, str_setfiles); -+ if (force) -+ ADD_ARG (argv, i, "-F"); -+ -+ /* Exclude some directories that should never be relabelled in -+ * ordinary Linux guests. These won't be mounted anyway. We have -+ * to prefix all these with the sysroot path. -+ */ -+ ADD_ARG (argv, i, "-e"); ADD_ARG (argv, i, s_dev); -+ ADD_ARG (argv, i, "-e"); ADD_ARG (argv, i, s_proc); -+ ADD_ARG (argv, i, "-e"); ADD_ARG (argv, i, s_selinux); -+ ADD_ARG (argv, i, "-e"); ADD_ARG (argv, i, s_sys); -+ -+ /* Relabelling in a chroot. */ -+ if (STRNEQ (sysroot, "/")) { -+ ADD_ARG (argv, i, "-r"); -+ ADD_ARG (argv, i, sysroot); -+ } -+ -+ /* Suppress non-error output. */ -+ ADD_ARG (argv, i, "-q"); -+ -+ /* Add parameters. */ -+ ADD_ARG (argv, i, s_specfile); -+ ADD_ARG (argv, i, s_path); -+ ADD_ARG (argv, i, NULL); -+ -+ if (commandv (NULL, &err, argv) == -1) { -+ reply_with_perror ("%s", err); -+ return -1; -+ } -+ -+ return 0; -+} -diff --git a/generator/actions.ml b/generator/actions.ml -index 998caa5..964a42b 100644 ---- a/generator/actions.ml -+++ b/generator/actions.ml -@@ -12753,6 +12753,29 @@ See also L, L, L, L." }; - longdesc = "\ - This is the internal call which implements C." }; - -+ { defaults with -+ name = "selinux_relabel"; added = (1, 33, 43); -+ style = RErr, [String "specfile"; Pathname "path"], [OBool "force"]; -+ proc_nr = Some 467; -+ optional = Some "selinuxrelabel"; -+ test_excuse = "tests are in the tests/relabel directory"; -+ shortdesc = "relabel parts of the filesystem"; -+ longdesc = "\ -+SELinux relabel parts of the filesystem. -+ -+The C parameter controls the policy spec file used. -+You have to parse C to find the correct -+SELinux policy and then pass the spec file, usually: -+C + I + C. -+ -+The required C parameter is the top level directory where -+relabelling starts. Normally you should pass C as C -+to relabel the whole guest filesystem. -+ -+The optional C boolean controls whether the context -+is reset for customizable files, and also whether the -+user, role and range parts of the file context is changed." }; -+ - ] - - (* Non-API meta-commands available only in guestfish. -diff --git a/gobject/Makefile.inc b/gobject/Makefile.inc -index 4b99a78..349f650 100644 ---- a/gobject/Makefile.inc -+++ b/gobject/Makefile.inc -@@ -96,6 +96,7 @@ guestfs_gobject_headers= \ - include/guestfs-gobject/optargs-rsync.h \ - include/guestfs-gobject/optargs-rsync_in.h \ - include/guestfs-gobject/optargs-rsync_out.h \ -+ include/guestfs-gobject/optargs-selinux_relabel.h \ - include/guestfs-gobject/optargs-set_e2attrs.h \ - include/guestfs-gobject/optargs-syslinux.h \ - include/guestfs-gobject/optargs-tar_in.h \ -@@ -182,6 +183,7 @@ guestfs_gobject_sources= \ - src/optargs-rsync.c \ - src/optargs-rsync_in.c \ - src/optargs-rsync_out.c \ -+ src/optargs-selinux_relabel.c \ - src/optargs-set_e2attrs.c \ - src/optargs-syslinux.c \ - src/optargs-tar_in.c \ -diff --git a/po/POTFILES b/po/POTFILES -index bef6540..98d4623 100644 ---- a/po/POTFILES -+++ b/po/POTFILES -@@ -94,6 +94,7 @@ daemon/realpath.c - daemon/rename.c - daemon/rsync.c - daemon/scrub.c -+daemon/selinux-relabel.c - daemon/selinux.c - daemon/sfdisk.c - daemon/sh.c -@@ -221,6 +222,7 @@ gobject/src/optargs-remount.c - gobject/src/optargs-rsync.c - gobject/src/optargs-rsync_in.c - gobject/src/optargs-rsync_out.c -+gobject/src/optargs-selinux_relabel.c - gobject/src/optargs-set_e2attrs.c - gobject/src/optargs-syslinux.c - gobject/src/optargs-tar_in.c -diff --git a/src/MAX_PROC_NR b/src/MAX_PROC_NR -index c92ddb6..5873851 100644 ---- a/src/MAX_PROC_NR -+++ b/src/MAX_PROC_NR -@@ -1 +1 @@ --458 -+467 --- -1.8.3.1 - diff --git a/SOURCES/0154-tests-Add-a-test-of-the-setfiles-API.patch b/SOURCES/0154-tests-Add-a-test-of-the-setfiles-API.patch deleted file mode 100644 index 002a21d..0000000 --- a/SOURCES/0154-tests-Add-a-test-of-the-setfiles-API.patch +++ /dev/null @@ -1,216 +0,0 @@ -From fe88effca288d963c776880bf01b10f1c3579d67 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Thu, 14 Jul 2016 09:03:19 +0100 -Subject: [PATCH] tests: Add a test of the setfiles API. - -(cherry picked from commit 6ec75f8cfe455493b46f1a3a5a00282359e588a5) ---- - Makefile.am | 1 + - configure.ac | 1 + - tests/relabel/Makefile.am | 28 +++++++++ - tests/relabel/test-relabel.pl | 134 ++++++++++++++++++++++++++++++++++++++++++ - 4 files changed, 164 insertions(+) - create mode 100644 tests/relabel/Makefile.am - create mode 100755 tests/relabel/test-relabel.pl - -diff --git a/Makefile.am b/Makefile.am -index 5be6876..ce20058 100644 ---- a/Makefile.am -+++ b/Makefile.am -@@ -65,6 +65,7 @@ SUBDIRS += tests/lvm - SUBDIRS += tests/luks - SUBDIRS += tests/md - SUBDIRS += tests/selinux -+SUBDIRS += tests/relabel - SUBDIRS += tests/ntfsclone - SUBDIRS += tests/btrfs - SUBDIRS += tests/xfs -diff --git a/configure.ac b/configure.ac -index 0bff74f..c971f0d 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -273,6 +273,7 @@ AC_CONFIG_FILES([Makefile - tests/protocol/Makefile - tests/qemu/Makefile - tests/regressions/Makefile -+ tests/relabel/Makefile - tests/relative-paths/Makefile - tests/rsync/Makefile - tests/selinux/Makefile -diff --git a/tests/relabel/Makefile.am b/tests/relabel/Makefile.am -new file mode 100644 -index 0000000..3407bef ---- /dev/null -+++ b/tests/relabel/Makefile.am -@@ -0,0 +1,28 @@ -+# libguestfs -+# Copyright (C) 2016 Red Hat Inc. -+# -+# This program is free software; you can redistribute it and/or modify -+# it under the terms of the GNU General Public License as published by -+# the Free Software Foundation; either version 2 of the License, or -+# (at your option) any later version. -+# -+# This program is distributed in the hope that it will be useful, -+# but WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+# GNU General Public License for more details. -+# -+# You should have received a copy of the GNU General Public License -+# along with this program; if not, write to the Free Software -+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -+ -+# Test setfiles function. -+ -+include $(top_srcdir)/subdir-rules.mk -+ -+TESTS = \ -+ test-relabel.pl -+ -+TESTS_ENVIRONMENT = $(top_builddir)/run --test -+ -+EXTRA_DIST = \ -+ test-relabel.pl -diff --git a/tests/relabel/test-relabel.pl b/tests/relabel/test-relabel.pl -new file mode 100755 -index 0000000..744d1f5 ---- /dev/null -+++ b/tests/relabel/test-relabel.pl -@@ -0,0 +1,134 @@ -+#!/usr/bin/env perl -+# Copyright (C) 2016 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. -+ -+use strict; -+use warnings; -+ -+use Sys::Guestfs; -+ -+my $prog = $0; -+$prog =~ s{.*/}{}; -+ -+# Because we parse error message strings below. -+$ENV{LANG} = "C"; -+ -+if ($ENV{"SKIP_TEST_RELABEL_PL"}) { -+ print "$prog: test skipped because environment variable is set.\n"; -+ exit 77 -+} -+ -+# SELinux labelling won't work (and can be skipped) if SELinux isn't -+# installed on the host. -+if (! -f "/etc/selinux/config" || ! -x "/usr/sbin/load_policy") { -+ print "$prog: test skipped because SELinux is not available.\n"; -+ exit 77 -+} -+ -+# Create a filesystem. -+my $g = Sys::Guestfs->new (); -+ -+$g->add_drive_scratch (256*1024*1024); -+$g->launch (); -+ -+# If Linux extended attrs aren't available then we cannot test this. -+unless ($g->feature_available (["linuxxattrs"])) { -+ print "$prog: test skipped because 'linuxxattrs' feature not available.\n"; -+ $g->close (); -+ exit 77 -+} -+ -+$g->part_disk ("/dev/sda", "mbr"); -+$g->mkfs ("ext4", "/dev/sda1"); -+ -+$g->mount_options ("user_xattr", "/dev/sda1", "/"); -+ -+# Create some files and directories that we want to have relabelled. -+$g->mkdir ("/bin"); -+$g->touch ("/bin/ls"); -+$g->mkdir ("/etc"); -+$g->mkdir ("/tmp"); -+$g->touch ("/tmp/test"); -+$g->mkdir ("/var"); -+$g->mkdir ("/var/log"); -+$g->touch ("/var/log/messages"); -+ -+# Create a spec file. -+# This doesn't test the optional file_type field. XXX -+# See also file_contexts(5). -+$g->write ("/etc/file_contexts", <<'EOF'); -+/.* system_u:object_r:default_t:s0 -+/bin/.* system_u:object_r:bin_t:s0 -+/etc/.* system_u:object_r:etc_t:s0 -+/etc/file_contexts <> -+/tmp/.* <> -+/var/.* system_u:object_r:var_t:s0 -+/var/log/.* system_u:object_r:var_log_t:s0 -+EOF -+ -+# Do the relabel. -+$g->selinux_relabel ("/etc/file_contexts", "/", force => 1); -+ -+# Check the labels were set correctly. -+my $errors = 0; -+ -+sub check_label -+{ -+ my $file = shift; -+ my $expected_label = shift; -+ -+ my $actual_label = $g->lgetxattr ($file, "security.selinux"); -+ # The label returned from lgetxattr has \0 appended. -+ if ("$expected_label\0" ne $actual_label) { -+ print STDERR "$prog: expected label on file $file: expected=$expected_label actual=$actual_label\n"; -+ $errors++; -+ } -+} -+ -+sub check_label_none -+{ -+ my $file = shift; -+ my $r; -+ -+ eval { -+ $r = $g->lgetxattr ($file, "security.selinux"); -+ }; -+ if (defined $r) { -+ print STDERR "$prog: expecting no label on file $file, but got $r\n"; -+ $errors++; -+ } elsif ($@) { -+ if ($@ !~ /No data available/) { -+ print STDERR "$prog: expecting an error reading label from file $file, but got $@\n"; -+ $errors++; -+ } -+ } -+} -+ -+check_label ("/bin", "system_u:object_r:default_t:s0"); -+check_label ("/bin/ls", "system_u:object_r:bin_t:s0"); -+check_label ("/etc", "system_u:object_r:default_t:s0"); -+check_label_none ("/etc/file_contexts"); -+check_label ("/tmp", "system_u:object_r:default_t:s0"); -+check_label_none ("/tmp/test"); -+check_label ("/var", "system_u:object_r:default_t:s0"); -+check_label ("/var/log", "system_u:object_r:var_t:s0"); -+check_label ("/var/log/messages", "system_u:object_r:var_log_t:s0"); -+ -+# Finish up. -+$g->shutdown (); -+$g->close (); -+ -+exit ($errors == 0 ? 0 : 1); --- -1.8.3.1 - diff --git a/SOURCES/0155-customize-Add-module-for-doing-SELinux-relabel-of-fi.patch b/SOURCES/0155-customize-Add-module-for-doing-SELinux-relabel-of-fi.patch deleted file mode 100644 index ed2b7e9..0000000 --- a/SOURCES/0155-customize-Add-module-for-doing-SELinux-relabel-of-fi.patch +++ /dev/null @@ -1,248 +0,0 @@ -From 6ea415aa049adaa8339e36a90e7ca6592e7090a4 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Wed, 13 Jul 2016 18:34:21 +0100 -Subject: [PATCH] customize: Add module for doing SELinux relabel of filesystem - (RHBZ#554829, RHBZ#983969, RHBZ#1089100). - -This implements the --selinux-relabel option for virt-customize, -virt-builder and virt-sysprep. There is no need to autorelabel -functionality now. - -Thanks: Stephen Smalley -(cherry picked from commit f3c69fe60bc29ebfcef0ea9d86d407e1a88686b0) ---- - builder/Makefile.am | 1 + - builder/virt-builder.pod | 18 ++++++-------- - customize/Makefile.am | 2 ++ - customize/SELinux_relabel.ml | 57 +++++++++++++++++++++++++++++++++++++++++++ - customize/SELinux_relabel.mli | 29 ++++++++++++++++++++++ - customize/customize_run.ml | 14 +---------- - po/POTFILES-ml | 1 + - sysprep/Makefile.am | 1 + - 8 files changed, 100 insertions(+), 23 deletions(-) - create mode 100644 customize/SELinux_relabel.ml - create mode 100644 customize/SELinux_relabel.mli - -diff --git a/builder/Makefile.am b/builder/Makefile.am -index d69e7ec..d306293 100644 ---- a/builder/Makefile.am -+++ b/builder/Makefile.am -@@ -154,6 +154,7 @@ BOBJECTS = \ - $(top_builddir)/customize/perl_edit.cmo \ - $(top_builddir)/customize/crypt.cmo \ - $(top_builddir)/customize/password.cmo \ -+ $(top_builddir)/customize/SELinux_relabel.cmo \ - $(top_builddir)/customize/ssh_key.cmo \ - $(top_builddir)/customize/subscription_manager.cmo \ - $(top_builddir)/customize/customize_cmdline.cmo \ -diff --git a/builder/virt-builder.pod b/builder/virt-builder.pod -index 5e344de..4209245 100644 ---- a/builder/virt-builder.pod -+++ b/builder/virt-builder.pod -@@ -1754,20 +1754,19 @@ two possible strategies it can use to ensure correct labelling: - - =item Using I<--selinux-relabel> - --This runs L just before finalizing the guest, which sets -+This runs L just before finalizing the guest, which sets - SELinux labels correctly in the disk image. - --Sometimes fixfiles is not possible during installation, in which case --this option falls back on: -+This is the recommended method. - --=item Touching F -+=item I<--touch> F - --Guest templates may already contain a file called F, or --it is touched if I<--selinux-relabel> cannot run fixfiles. -+Guest templates may already contain a file called F or -+you may touch it. - --For guests that use SELinux, this causes fixfiles to run at first --boot. Guests will reboot themselves once the first time you use them, --which is normal and harmless. -+For guests that use SELinux, this causes L to run at -+first boot. Guests will reboot themselves once the first time you use -+them, which is normal and harmless. - - =back - -@@ -1876,7 +1875,6 @@ L, - L, - L, - L, --L, - L. - - =head1 AUTHOR -diff --git a/customize/Makefile.am b/customize/Makefile.am -index 05f144f..9b48e8f 100644 ---- a/customize/Makefile.am -+++ b/customize/Makefile.am -@@ -43,6 +43,7 @@ SOURCES_MLI = \ - password.mli \ - perl_edit.mli \ - random_seed.mli \ -+ SELinux_relabel.mli \ - ssh_key.mli \ - subscription_manager.mli \ - timezone.mli \ -@@ -58,6 +59,7 @@ SOURCES_ML = \ - password.ml \ - perl_edit.ml \ - random_seed.ml \ -+ SELinux_relabel.ml \ - ssh_key.ml \ - subscription_manager.ml \ - timezone.ml \ -diff --git a/customize/SELinux_relabel.ml b/customize/SELinux_relabel.ml -new file mode 100644 -index 0000000..fa9603c ---- /dev/null -+++ b/customize/SELinux_relabel.ml -@@ -0,0 +1,57 @@ -+(* virt-customize -+ * Copyright (C) 2016 Red Hat Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License along -+ * with this program; if not, write to the Free Software Foundation, Inc., -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -+ *) -+ -+open Common_gettext.Gettext -+open Common_utils -+ -+open Printf -+ -+module G = Guestfs -+ -+let relabel (g : G.guestfs) = -+ (* Is the guest using SELinux? *) -+ if g#is_file ~followsymlinks:true "/usr/sbin/load_policy" && -+ g#is_file ~followsymlinks:true "/etc/selinux/config" then ( -+ (* Is setfiles / SELinux relabelling functionality available? *) -+ if g#feature_available [| "selinuxrelabel" |] then ( -+ (* Use Augeas to parse /etc/selinux/config. *) -+ g#aug_init "/" (16+32) (* AUG_SAVE_NOOP | AUG_NO_LOAD *); -+ (* See: https://bugzilla.redhat.com/show_bug.cgi?id=975412#c0 *) -+ ignore (g#aug_rm "/augeas/load/*[\"/etc/selinux/config/\" !~ regexp('^') + glob(incl) + regexp('/.*')]"); -+ g#aug_load (); -+ debug_augeas_errors g; -+ -+ (* Get the SELinux policy name, eg. "targeted", "minimum". *) -+ let policy = g#aug_get "/files/etc/selinux/config/SELINUXTYPE" in -+ g#aug_close (); -+ -+ (* Get the spec file name. *) -+ let specfile = -+ sprintf "/etc/selinux/%s/contexts/files/file_contexts" policy in -+ -+ (* Relabel everything. *) -+ g#selinux_relabel ~force:true specfile "/"; -+ -+ (* If that worked, we don't need to autorelabel. *) -+ g#rm_f "/.autorelabel" -+ ) -+ else ( -+ (* SELinux guest, but not SELinux host. Fallback to this. *) -+ g#touch "/.autorelabel" -+ ) -+ ) -diff --git a/customize/SELinux_relabel.mli b/customize/SELinux_relabel.mli -new file mode 100644 -index 0000000..7b4f7ff ---- /dev/null -+++ b/customize/SELinux_relabel.mli -@@ -0,0 +1,29 @@ -+(* virt-customize -+ * Copyright (C) 2016 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. -+ *) -+ -+(** SELinux-relabel the filesystem. *) -+ -+val relabel : Guestfs.guestfs -> unit -+(** Relabel the mounted guestfs filesystem using the current SELinux -+ policy that applies to the guest. -+ -+ If the guest does not look like it uses SELinux, this does nothing. -+ -+ In case relabelling is not possible (since it is an optional -+ feature which requires the setfiles(8) program), instead we -+ fall back to touching [/.autorelabel]. *) -diff --git a/customize/customize_run.ml b/customize/customize_run.ml -index 10647fd..7d1c806 100644 ---- a/customize/customize_run.ml -+++ b/customize/customize_run.ml -@@ -412,19 +412,7 @@ exec >>%s 2>&1 - - if ops.flags.selinux_relabel then ( - message (f_"SELinux relabelling"); -- if guest_arch_compatible then ( -- let cmd = sprintf " -- if load_policy && fixfiles restore; then -- rm -f /.autorelabel -- else -- touch /.autorelabel -- echo '%s: SELinux relabelling failed, will relabel at boot instead.' -- fi -- " prog in -- do_run ~display:"load_policy && fixfiles restore" cmd -- ) else ( -- g#touch "/.autorelabel" -- ) -+ SELinux_relabel.relabel g - ); - - (* Clean up the log file: -diff --git a/po/POTFILES-ml b/po/POTFILES-ml -index 4ea49a5..f5e8eba 100644 ---- a/po/POTFILES-ml -+++ b/po/POTFILES-ml -@@ -17,6 +17,7 @@ builder/sources.ml - builder/utils.ml - builder/yajl.ml - builder/yajl_tests.ml -+customize/SELinux_relabel.ml - customize/crypt.ml - customize/customize_cmdline.ml - customize/customize_main.ml -diff --git a/sysprep/Makefile.am b/sysprep/Makefile.am -index 46cc324..b689aef 100644 ---- a/sysprep/Makefile.am -+++ b/sysprep/Makefile.am -@@ -122,6 +122,7 @@ BOBJECTS = \ - $(top_builddir)/customize/timezone.cmo \ - $(top_builddir)/customize/firstboot.cmo \ - $(top_builddir)/customize/perl_edit.cmo \ -+ $(top_builddir)/customize/SELinux_relabel.cmo \ - $(top_builddir)/customize/ssh_key.cmo \ - $(top_builddir)/customize/subscription_manager.cmo \ - $(top_builddir)/customize/customize_cmdline.cmo \ --- -1.8.3.1 - diff --git a/SOURCES/0156-builder-Use-virt-sysprep-selinux-relabel-when-prepar.patch b/SOURCES/0156-builder-Use-virt-sysprep-selinux-relabel-when-prepar.patch deleted file mode 100644 index 1780dc3..0000000 --- a/SOURCES/0156-builder-Use-virt-sysprep-selinux-relabel-when-prepar.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 2291f5b40cca88a305fbe822bebffb6aeecf681c Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Wed, 13 Jul 2016 20:16:23 +0100 -Subject: [PATCH] builder: Use virt-sysprep --selinux-relabel when preparing - templates. - -Don't need to be clever now. - -(cherry picked from commit b6e92b1100b4ca462a35549bd36322f0510739bc) ---- - builder/website/compress.sh | 15 ++------------- - 1 file changed, 2 insertions(+), 13 deletions(-) - -diff --git a/builder/website/compress.sh b/builder/website/compress.sh -index bb5500c..1036a60 100644 ---- a/builder/website/compress.sh -+++ b/builder/website/compress.sh -@@ -23,22 +23,11 @@ output=$1 - relabel_args=() - - if [ -n "$DO_RELABEL" ]; then -- os_arch=$(uname -m) -- guest_arch=$(virt-inspector -a "$output" | virt-inspector --xpath "string(/operatingsystems/operatingsystem/arch)") -- -- if [ "$os_arch" = "$guest_arch" ] || [ "$os_arch" = "x86_64" -a "$guest_arch" = "i386" ]; then -- # this is what --selinux-relabel should really do, but do it ourselves -- # in the meanwhile -- see RHBZ#1089100. -- relabel_args+=(--run-command "setfiles /etc/selinux/targeted/contexts/files/file_contexts /") -- else -- relabel_args+=(--selinux-relabel) -- fi -+ relabel_args="--selinux-relabel" - fi - - # Sysprep (removes logfiles and so on). --# Note this also touches /.autorelabel so the further installation --# changes that we make will be labelled properly at first boot. --virt-sysprep -a $output "${relabel_args[@]}" -+virt-sysprep -a $output $relabel_args - - # Sparsify. - mv $output $output.old --- -1.8.3.1 - diff --git a/SOURCES/0157-lib-Deprecate-old-SELinux-APIs-rewrite-SELinux-docum.patch b/SOURCES/0157-lib-Deprecate-old-SELinux-APIs-rewrite-SELinux-docum.patch deleted file mode 100644 index 679cd7e..0000000 --- a/SOURCES/0157-lib-Deprecate-old-SELinux-APIs-rewrite-SELinux-docum.patch +++ /dev/null @@ -1,335 +0,0 @@ -From b70675c87da92ca74019a177214deea2597a9b46 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Wed, 13 Jul 2016 21:21:07 +0100 -Subject: [PATCH] lib: Deprecate old SELinux APIs, rewrite SELinux - documentation (RHBZ#1152825). - -Also turns the --selinux option of guestfish, guestmount and -virt-rescue into a no-op -- it didn't work before so this is -effectively no change. - -(cherry picked from commit 35bac3a6501354e4a3805877d950e741429f169b) ---- - builder/builder.ml | 6 ----- - customize/customize_main.ml | 5 ---- - dib/dib.ml | 6 ----- - fish/fish.c | 5 ++-- - fish/guestfish.pod | 2 +- - fuse/guestmount.c | 5 ++-- - fuse/guestmount.pod | 2 +- - generator/actions.ml | 5 ++++ - rescue/rescue.c | 5 ++-- - rescue/virt-rescue.pod | 3 +-- - src/guestfs.pod | 59 +++++++++++++++------------------------------ - test-tool/test-tool.c | 1 - - tests/selinux/run-test.pl | 2 -- - 13 files changed, 33 insertions(+), 73 deletions(-) - -diff --git a/builder/builder.ml b/builder/builder.ml -index ac4c748..0bffc9a 100644 ---- a/builder/builder.ml -+++ b/builder/builder.ml -@@ -630,12 +630,6 @@ let main () = - may g#set_smp cmdline.smp; - g#set_network cmdline.network; - -- (* Make sure to turn SELinux off to avoid awkward interactions -- * between the appliance kernel and applications/libraries interacting -- * with SELinux xattrs. -- *) -- g#set_selinux false; -- - (* The output disk is being created, so use cache=unsafe here. *) - g#add_drive_opts ~format:output_format ~cachemode:"unsafe" output_filename; - -diff --git a/customize/customize_main.ml b/customize/customize_main.ml -index 1aa2fb4..7011335 100644 ---- a/customize/customize_main.ml -+++ b/customize/customize_main.ml -@@ -169,11 +169,6 @@ read the man page virt-customize(1). - may g#set_memsize memsize; - may g#set_smp smp; - g#set_network network; -- (* Make sure to turn SELinux off to avoid awkward interactions -- * between the appliance kernel and applications/libraries interacting -- * with SELinux xattrs. -- *) -- g#set_selinux false; - - (* Add disks. *) - add g dryrun; -diff --git a/dib/dib.ml b/dib/dib.ml -index 382c9d2..de4f242 100644 ---- a/dib/dib.ml -+++ b/dib/dib.ml -@@ -634,12 +634,6 @@ let main () = - may g#set_smp cmdline.smp; - g#set_network cmdline.network; - -- (* Make sure to turn SELinux off to avoid awkward interactions -- * between the appliance kernel and applications/libraries interacting -- * with SELinux xattrs. -- *) -- g#set_selinux false; -- - (* Main disk with the built image. *) - let fmt = "raw" in - let fn = -diff --git a/fish/fish.c b/fish/fish.c -index ed851ac..bf591e5 100644 ---- a/fish/fish.c -+++ b/fish/fish.c -@@ -137,7 +137,7 @@ usage (int status) - " --no-progress-bars Disable progress bars\n" - " --remote[=pid] Send commands to remote %s\n" - " -r|--ro Mount read-only\n" -- " --selinux Enable SELinux support\n" -+ " --selinux For backwards compat only, does nothing\n" - " -v|--verbose Verbose messages\n" - " -V|--version Display version and exit\n" - " -w|--rw Mount read-write\n" -@@ -268,8 +268,7 @@ main (int argc, char *argv[]) - } - } - } else if (STREQ (long_options[option_index].name, "selinux")) { -- if (guestfs_set_selinux (g, 1) == -1) -- exit (EXIT_FAILURE); -+ /* nothing */ - } else if (STREQ (long_options[option_index].name, "keys-from-stdin")) { - keys_from_stdin = 1; - } else if (STREQ (long_options[option_index].name, "progress-bars")) { -diff --git a/fish/guestfish.pod b/fish/guestfish.pod -index 05105e8..bdc2298 100644 ---- a/fish/guestfish.pod -+++ b/fish/guestfish.pod -@@ -407,7 +407,7 @@ See also L below. - - =item B<--selinux> - --Enable SELinux support for the guest. See L. -+This option is provided for backwards compatibility and does nothing. - - =item B<-v> - -diff --git a/fuse/guestmount.c b/fuse/guestmount.c -index 4e9cf86..1fd2f72 100644 ---- a/fuse/guestmount.c -+++ b/fuse/guestmount.c -@@ -124,7 +124,7 @@ usage (int status) - " -o|--option opt Pass extra option to FUSE\n" - " --pid-file filename Write PID to filename\n" - " -r|--ro Mount read-only\n" -- " --selinux Enable SELinux support\n" -+ " --selinux For backwards compat only, does nothing\n" - " -v|--verbose Verbose messages\n" - " -V|--version Display version and exit\n" - " -w|--rw Mount read-write\n" -@@ -228,8 +228,7 @@ main (int argc, char *argv[]) - else if (STREQ (long_options[option_index].name, "fuse-help")) - fuse_help (); - else if (STREQ (long_options[option_index].name, "selinux")) { -- if (guestfs_set_selinux (g, 1) == -1) -- exit (EXIT_FAILURE); -+ /* nothing */ - } else if (STREQ (long_options[option_index].name, "format")) { - OPTION_format; - } else if (STREQ (long_options[option_index].name, "keys-from-stdin")) { -diff --git a/fuse/guestmount.pod b/fuse/guestmount.pod -index e7f37ae..be075e5 100644 ---- a/fuse/guestmount.pod -+++ b/fuse/guestmount.pod -@@ -362,7 +362,7 @@ See also L. - - =item B<--selinux> - --Enable SELinux support for the guest. -+This option is provided for backwards compatibility and does nothing. - - =item B<-v> - -diff --git a/generator/actions.ml b/generator/actions.ml -index 964a42b..a515c4c 100644 ---- a/generator/actions.ml -+++ b/generator/actions.ml -@@ -645,6 +645,7 @@ Use C or C instead." }; - style = RErr, [Bool "selinux"], []; - fish_alias = ["selinux"]; config_only = true; - blocking = false; -+ deprecated_by = Some "selinux_relabel"; - shortdesc = "set SELinux enabled or disabled at appliance boot"; - longdesc = "\ - This sets the selinux flag that is passed to the appliance -@@ -660,6 +661,7 @@ see L." }; - name = "get_selinux"; added = (1, 0, 67); - style = RBool "selinux", [], []; - blocking = false; -+ deprecated_by = Some "selinux_relabel"; - shortdesc = "get SELinux enabled flag"; - longdesc = "\ - This returns the current setting of the selinux flag which -@@ -7315,6 +7317,7 @@ away any pending events, and deallocates all resources." }; - style = RErr, [String "context"], []; - proc_nr = Some 185; - optional = Some "selinux"; -+ deprecated_by = Some "selinux_relabel"; - shortdesc = "set SELinux security context"; - longdesc = "\ - This sets the SELinux security context of the daemon -@@ -7327,6 +7330,7 @@ See the documentation about SELINUX in L." }; - style = RString "context", [], []; - proc_nr = Some 186; - optional = Some "selinux"; -+ deprecated_by = Some "selinux_relabel"; - shortdesc = "get SELinux security context"; - longdesc = "\ - This gets the SELinux security context of the daemon. -@@ -9863,6 +9867,7 @@ This option may not be specified at the same time as the C option. - name = "llz"; added = (1, 17, 6); - style = RString "listing", [Pathname "directory"], []; - proc_nr = Some 305; -+ deprecated_by = Some "lgetxattrs"; - shortdesc = "list the files in a directory (long format with SELinux contexts)"; - longdesc = "\ - List the files in F in the format of 'ls -laZ'. -diff --git a/rescue/rescue.c b/rescue/rescue.c -index 982f3c4..f753e6d 100644 ---- a/rescue/rescue.c -+++ b/rescue/rescue.c -@@ -72,7 +72,7 @@ usage (int status) - " --network Enable network\n" - " -r|--ro Access read-only\n" - " --scratch[=N] Add scratch disk(s)\n" -- " --selinux Enable SELinux\n" -+ " --selinux For backwards compat only, does nothing\n" - " --smp N Enable SMP with N >= 2 virtual CPUs\n" - " --suggest Suggest mount commands for this guest\n" - " -v|--verbose Verbose messages\n" -@@ -148,8 +148,7 @@ main (int argc, char *argv[]) - else if (STREQ (long_options[option_index].name, "short-options")) - display_short_options (options); - else if (STREQ (long_options[option_index].name, "selinux")) { -- if (guestfs_set_selinux (g, 1) == -1) -- exit (EXIT_FAILURE); -+ /* nothing */ - } else if (STREQ (long_options[option_index].name, "append")) { - append = optarg; - } else if (STREQ (long_options[option_index].name, "network")) { -diff --git a/rescue/virt-rescue.pod b/rescue/virt-rescue.pod -index bb563bc..00f03aa 100644 ---- a/rescue/virt-rescue.pod -+++ b/rescue/virt-rescue.pod -@@ -209,8 +209,7 @@ command line. - - =item B<--selinux> - --Enable SELinux in the rescue appliance. You should read --L before using this option. -+This option is provided for backwards compatibility and does nothing. - - =item B<--smp> N - -diff --git a/src/guestfs.pod b/src/guestfs.pod -index af30406..9ac7792 100644 ---- a/src/guestfs.pod -+++ b/src/guestfs.pod -@@ -433,8 +433,8 @@ an X86 host). - - =item * - --For SELinux guests, you may need to enable SELinux and load policy --first. See L in this manpage. -+For SELinux guests, you may need to relabel the guest after -+creating new files. See L below. - - =item * - -@@ -486,44 +486,23 @@ L, L. - - =head2 SELINUX - --We support SELinux guests. To ensure that labeling happens correctly --in SELinux guests, you need to enable SELinux and load the guest's --policy: -- --=over 4 -- --=item 1. -- --Before launching, do: -- -- guestfs_set_selinux (g, 1); -- --=item 2. -- --After mounting the guest's filesystem(s), load the policy. This --is best done by running the L command in the --guest itself: -- -- guestfs_sh (g, "/usr/sbin/load_policy"); -- --(Older versions of C require you to specify the --name of the policy file). -- --=item 3. -- --Optionally, set the security context for the API. The correct --security context to use can only be known by inspecting the --guest. As an example: -- -- guestfs_setcon (g, "unconfined_u:unconfined_r:unconfined_t:s0"); -- --=back -- --This will work for running commands and editing existing files. -- --When new files are created, you may need to label them explicitly, --for example by running the external command --C. -+We support SELinux guests. However it is not possible to load the -+SELinux policy of the guest into the appliance kernel. Therefore the -+strategy for dealing with SELinux guests is to relabel them after -+making changes. -+ -+In libguestfs E 1.34 there is a new API, L, -+which can be used for this. To properly use this API you have to -+parse the guest SELinux configuration. See the L -+module F for how to do this. -+ -+A simpler but slower alternative is to touch F in the -+guest, which means that the guest will relabel itself at next boot. -+ -+Libguestfs E 1.32 had APIs C, -+C, C and C. -+These did not work properly, are deprecated, and should not be used in -+new code. - - =head2 UMASK - -diff --git a/test-tool/test-tool.c b/test-tool/test-tool.c -index a5ecf5c..6699fc3 100644 ---- a/test-tool/test-tool.c -+++ b/test-tool/test-tool.c -@@ -253,7 +253,6 @@ main (int argc, char *argv[]) - printf ("guestfs_get_pgroup: %d\n", guestfs_get_pgroup (g)); - printf ("guestfs_get_program: %s\n", guestfs_get_program (g)); - printf ("guestfs_get_recovery_proc: %d\n", guestfs_get_recovery_proc (g)); -- printf ("guestfs_get_selinux: %d\n", guestfs_get_selinux (g)); - printf ("guestfs_get_smp: %d\n", guestfs_get_smp (g)); - p = guestfs_get_tmpdir (g); - printf ("guestfs_get_tmpdir: %s\n", p ? : "(null)"); -diff --git a/tests/selinux/run-test.pl b/tests/selinux/run-test.pl -index f0f241f..7e4620f 100755 ---- a/tests/selinux/run-test.pl -+++ b/tests/selinux/run-test.pl -@@ -105,8 +105,6 @@ if ($test_type eq "selinux" && $test_via eq "fuse") { - # Create a filesystem that could support xattrs and SELinux labels. - my $g = Sys::Guestfs->new (); - --#$g->set_selinux (1) if $test_type eq "selinux"; -- - $g->add_drive_scratch (256*1024*1024); - $g->launch (); - --- -1.8.3.1 - diff --git a/SOURCES/0158-v2v-linux-Use-new-SELinux_relabel-module-to-relabel-.patch b/SOURCES/0158-v2v-linux-Use-new-SELinux_relabel-module-to-relabel-.patch deleted file mode 100644 index eed0fe8..0000000 --- a/SOURCES/0158-v2v-linux-Use-new-SELinux_relabel-module-to-relabel-.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 98fff91388ecefeb7e2b9cb830b2e971b228be9d Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Wed, 13 Jul 2016 22:50:10 +0100 -Subject: [PATCH] v2v: linux: Use new SELinux_relabel module to relabel Linux - guests. - -(cherry picked from commit fc114904848559e02d8f4e4a8bfb57277c349f0f) ---- - v2v/Makefile.am | 1 + - v2v/convert_linux.ml | 10 ++-------- - 2 files changed, 3 insertions(+), 8 deletions(-) - -diff --git a/v2v/Makefile.am b/v2v/Makefile.am -index 09a63a0..73a2d68 100644 ---- a/v2v/Makefile.am -+++ b/v2v/Makefile.am -@@ -149,6 +149,7 @@ BOBJECTS = \ - $(top_builddir)/mllib/curl.cmo \ - $(top_builddir)/customize/customize_utils.cmo \ - $(top_builddir)/customize/firstboot.cmo \ -+ $(top_builddir)/customize/SELinux_relabel.cmo \ - $(SOURCES_ML:.ml=.cmo) - XOBJECTS = $(BOBJECTS:.cmo=.cmx) - -diff --git a/v2v/convert_linux.ml b/v2v/convert_linux.ml -index bdbd06b..825dae8 100644 ---- a/v2v/convert_linux.ml -+++ b/v2v/convert_linux.ml -@@ -406,13 +406,6 @@ let rec convert ~keep_serial_console (g : G.guestfs) inspect source = - - | `Grub2 -> () (* Not necessary for grub2. *) - -- and autorelabel () = -- (* Only do autorelabel if load_policy binary exists. Actually -- * loading the policy is problematic. -- *) -- if g#is_file ~followsymlinks:true "/usr/sbin/load_policy" then -- g#touch "/.autorelabel"; -- - and unconfigure_xen () = - (* Remove kmod-xenpv-* (RHEL 3). *) - let xenmods = -@@ -1383,7 +1376,6 @@ let rec convert ~keep_serial_console (g : G.guestfs) inspect source = - in - - augeas_grub_configuration (); -- autorelabel (); - - unconfigure_xen (); - unconfigure_vbox (); -@@ -1409,6 +1401,8 @@ let rec convert ~keep_serial_console (g : G.guestfs) inspect source = - configure_kernel_modules virtio; - rebuild_initrd kernel; - -+ SELinux_relabel.relabel g; -+ - let guestcaps = { - gcaps_block_bus = if virtio then Virtio_blk else IDE; - gcaps_net_bus = if virtio then Virtio_net else E1000; --- -1.8.3.1 - diff --git a/SOURCES/0159-Revert-p2v-Disable-SELinux-in-virt-p2v-make-disk.patch b/SOURCES/0159-Revert-p2v-Disable-SELinux-in-virt-p2v-make-disk.patch deleted file mode 100644 index 2097dc8..0000000 --- a/SOURCES/0159-Revert-p2v-Disable-SELinux-in-virt-p2v-make-disk.patch +++ /dev/null @@ -1,45 +0,0 @@ -From ffc6d1c3e3bd51dc5cbfc602c66b860ffadfe245 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Thu, 21 Jul 2016 22:29:05 +0100 -Subject: [PATCH] Revert "p2v: Disable SELinux in virt-p2v-make-disk." - -The commit claimed that SELinux was disabled in the -virt-p2v-make-kickstart script, and so this was just making things -consistent. However this is not true. SELinux *is* enabled in the -kickstart version. There is some code to disable it, but it is -commented out (admittedly it's hard to tell because the code is buried -in a multi-line sed expression). - -The commit message also claimed (this time correctly) that the -'--selinux-relabel' step caused an extra reboot each time virt-p2v is -run from the ISO. However we have recently fixed this so it can -usually do the relabelling during the build, not at boot time, so this -is no longer a problem. - -This reverts commit 25ffcc7d436cd8f6bcf29d8bde5efd4b8823d6cc. - -(cherry picked from commit fcce1f694e46933dd5d6a0ef1369cef3c5152fc5) ---- - p2v/virt-p2v-make-disk.in | 5 ++--- - 1 file changed, 2 insertions(+), 3 deletions(-) - -diff --git a/p2v/virt-p2v-make-disk.in b/p2v/virt-p2v-make-disk.in -index cc7ee93..a199e1e 100644 ---- a/p2v/virt-p2v-make-disk.in -+++ b/p2v/virt-p2v-make-disk.in -@@ -149,10 +149,9 @@ EOF - latest_version="$(cd /lib/modules; ls -1vr | head -1)" - dracut -f --kver $latest_version - EOF -- # Double quotes because we want $tmpdir to be expanded. -- # Disable SELinux for consistency with virt-p2v-make-kickstart. -+ # Double quotes because we want $tmpdir to be expanded: - extra_args=" -- --edit /etc/selinux/config:s/^SELINUX=.*/SELINUX=disabled/g -+ --selinux-relabel - --upload $tmpdir/p2v.conf:/etc/dracut.conf.d/ - --run $tmpdir/post-install - " --- -1.8.3.1 - diff --git a/SOURCES/0160-mllib-move-which-and-its-exception-from-dib.patch b/SOURCES/0160-mllib-move-which-and-its-exception-from-dib.patch deleted file mode 100644 index bf7f0a4..0000000 --- a/SOURCES/0160-mllib-move-which-and-its-exception-from-dib.patch +++ /dev/null @@ -1,124 +0,0 @@ -From 9ad21a8ae34fc60198afb46cb64a3325b2720b07 Mon Sep 17 00:00:00 2001 -From: Pino Toscano -Date: Tue, 2 Aug 2016 18:34:09 +0200 -Subject: [PATCH] mllib: move which and its exception from dib - -Rename it from "tool" to "executable" in the process, but otherwise -it is just code motion (with minimal adjustments in dib). - -(cherry picked from commit 398b940ea4a6069b1d0233c8a6f5d6ed823eddb9) ---- - dib/dib.ml | 2 +- - dib/utils.ml | 16 +--------------- - mllib/common_utils.ml | 14 ++++++++++++++ - mllib/common_utils.mli | 9 +++++++++ - 4 files changed, 25 insertions(+), 16 deletions(-) - -diff --git a/dib/dib.ml b/dib/dib.ml -index de4f242..87af4eb 100644 ---- a/dib/dib.ml -+++ b/dib/dib.ml -@@ -297,7 +297,7 @@ $cmd \"$@\" - (try - let loc = which "dib-run-parts" in - do_cp loc (destdir // "fake-bin") -- with Tool_not_found _ -> -+ with Executable_not_found _ -> - let fake_dib_run_parts = "\ - #!/bin/sh - echo \"Please install dib-run-parts on the host\" -diff --git a/dib/utils.ml b/dib/utils.ml -index f316264..a2046cb 100644 ---- a/dib/utils.ml -+++ b/dib/utils.ml -@@ -21,8 +21,6 @@ open Common_utils - - open Printf - --exception Tool_not_found of string (* tool *) -- - let quote = Filename.quote - - let unit_GB howmany = -@@ -97,21 +95,9 @@ let rec remove_dups = function - | [] -> [] - | x :: xs -> x :: (remove_dups (List.filter ((<>) x) xs)) - --let which tool = -- let paths = String.nsplit ":" (Sys.getenv "PATH") in -- let paths = filter_map ( -- fun p -> -- let path = p // tool in -- try Unix.access path [Unix.X_OK]; Some path -- with Unix.Unix_error _ -> None -- ) paths in -- match paths with -- | [] -> raise (Tool_not_found tool) -- | x :: _ -> x -- - let require_tool tool = - try ignore (which tool) -- with Tool_not_found tool -> -+ with Executable_not_found tool -> - error (f_"%s needed but not found") tool - - let do_cp src destdir = -diff --git a/mllib/common_utils.ml b/mllib/common_utils.ml -index 2dfe475..7e44029 100644 ---- a/mllib/common_utils.ml -+++ b/mllib/common_utils.ml -@@ -141,6 +141,8 @@ module String = struct - ) - end - -+exception Executable_not_found of string (* executable *) -+ - let (//) = Filename.concat - - let ( +^ ) = Int64.add -@@ -299,6 +301,18 @@ let protect ~f ~finally = - finally (); - match r with Either ret -> ret | Or exn -> raise exn - -+let which executable = -+ let paths = String.nsplit ":" (Sys.getenv "PATH") in -+ let paths = filter_map ( -+ fun p -> -+ let path = p // executable in -+ try Unix.access path [Unix.X_OK]; Some path -+ with Unix.Unix_error _ -> None -+ ) paths in -+ match paths with -+ | [] -> raise (Executable_not_found executable) -+ | x :: _ -> x -+ - (* Program name. *) - let prog = Filename.basename Sys.executable_name - -diff --git a/mllib/common_utils.mli b/mllib/common_utils.mli -index c66efa7..8179dde 100644 ---- a/mllib/common_utils.mli -+++ b/mllib/common_utils.mli -@@ -85,6 +85,10 @@ module String : sig - end - (** Override the String module from stdlib. *) - -+(** Exception thrown by [which] when the specified executable is not found -+ in [$PATH]. *) -+exception Executable_not_found of string (* executable *) -+ - val ( // ) : string -> string -> string - (** Concatenate directory and filename. *) - -@@ -372,3 +376,8 @@ val read_first_line_from_file : string -> string - - val is_regular_file : string -> bool - (** Checks whether the file is a regular file. *) -+ -+val which : string -> string -+(** Return the full path of the specified executable from [$PATH]. -+ -+ Throw [Executable_not_found] if not available. *) --- -1.8.3.1 - diff --git a/SOURCES/0161-mllib-check-for-executable-existance-in-run_command-.patch b/SOURCES/0161-mllib-check-for-executable-existance-in-run_command-.patch deleted file mode 100644 index e98c062..0000000 --- a/SOURCES/0161-mllib-check-for-executable-existance-in-run_command-.patch +++ /dev/null @@ -1,69 +0,0 @@ -From 037e340e348af57468920caee842bfb73aa03a3a Mon Sep 17 00:00:00 2001 -From: Pino Toscano -Date: Tue, 2 Aug 2016 18:45:34 +0200 -Subject: [PATCH] mllib: check for executable existance in run_command - (RHBZ#1362357) - -run_command uses Unix.create_process which forks a child process, and -executes execve: the latter fails when the executable does not exist, -triggering the exit which, in older OCaml versions [1], also runs the -at_exit handlers. - -Since there is not much that can be done to avoid this on the OCaml -side, to keep run_command working also in older OCaml version then -manually search for the existance of the given executable, exiting with -code 127 (as a shell does) in this case. - -[1] http://caml.inria.fr/mantis/view.php?id=7209 - -(cherry picked from commit 2cb053d3fea709b1f72681f1c556c5623c8f6fa7) ---- - mllib/common_utils.ml | 32 ++++++++++++++++++++------------ - 1 file changed, 20 insertions(+), 12 deletions(-) - -diff --git a/mllib/common_utils.ml b/mllib/common_utils.ml -index 7e44029..51449ad 100644 ---- a/mllib/common_utils.ml -+++ b/mllib/common_utils.ml -@@ -707,18 +707,26 @@ let external_command ?(echo_cmd = true) cmd = - let run_command ?(echo_cmd = true) args = - if echo_cmd then - debug "%s" (stringify_args args); -- let pid = -- Unix.create_process (List.hd args) (Array.of_list args) Unix.stdin -- Unix.stdout Unix.stderr in -- let _, stat = Unix.waitpid [] pid in -- match stat with -- | Unix.WEXITED i -> i -- | Unix.WSIGNALED i -> -- error (f_"external command '%s' killed by signal %d") -- (stringify_args args) i -- | Unix.WSTOPPED i -> -- error (f_"external command '%s' stopped by signal %d") -- (stringify_args args) i -+ let app = List.hd args in -+ try -+ let app = -+ if Filename.is_relative app then which app -+ else (Unix.access app [Unix.X_OK]; app) in -+ let pid = -+ Unix.create_process app (Array.of_list args) Unix.stdin -+ Unix.stdout Unix.stderr in -+ let _, stat = Unix.waitpid [] pid in -+ match stat with -+ | Unix.WEXITED i -> i -+ | Unix.WSIGNALED i -> -+ error (f_"external command '%s' killed by signal %d") -+ (stringify_args args) i -+ | Unix.WSTOPPED i -> -+ error (f_"external command '%s' stopped by signal %d") -+ (stringify_args args) i -+ with -+ | Executable_not_found tool -> 127 -+ | Unix.Unix_error (errcode, _, _) when errcode = Unix.ENOENT -> 127 - - let shell_command ?(echo_cmd = true) cmd = - if echo_cmd then --- -1.8.3.1 - diff --git a/SOURCES/0162-podcheck-Check-tool-help-output.patch b/SOURCES/0162-podcheck-Check-tool-help-output.patch deleted file mode 100644 index adf88ae..0000000 --- a/SOURCES/0162-podcheck-Check-tool-help-output.patch +++ /dev/null @@ -1,35 +0,0 @@ -From b0caba7a6614f8c756690d66487a5fb4dd8c1572 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Tue, 19 Jul 2016 12:31:23 +0100 -Subject: [PATCH] podcheck: Check tool --help output. - -For OCaml tools this does essentially nothing useful because the ---help output is automatically generated from the options, and so -cannot be wrong. However for C tools this is a useful check. - -It would be nice to generate C tools --help output, but there isn't -enough information in the getopt data to do that. - -This commit also includes fixes to the --help output for a few tools. - -(cherry picked from commit 5e65da07fa3b80413465def0a30a5961d98234a8) ---- - p2v/main.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/p2v/main.c b/p2v/main.c -index 4441b99..b9a4177 100644 ---- a/p2v/main.c -+++ b/p2v/main.c -@@ -82,7 +82,7 @@ usage (int status) - "Options:\n" - " --help Display brief help\n" - " --cmdline=CMDLINE Used to debug command line parsing\n" -- " --colours Use ANSI colour sequences even if not tty\n" -+ " --colors|--colours Use ANSI colour sequences even if not tty\n" - " --iso Running in the ISO environment\n" - " -v|--verbose Verbose messages\n" - " -V|--version Display version and exit\n" --- -1.8.3.1 - diff --git a/SOURCES/0163-mllib-move-_exit-from-v2v-as-Exit-module.patch b/SOURCES/0163-mllib-move-_exit-from-v2v-as-Exit-module.patch deleted file mode 100644 index 0299cfd..0000000 --- a/SOURCES/0163-mllib-move-_exit-from-v2v-as-Exit-module.patch +++ /dev/null @@ -1,266 +0,0 @@ -From 42c6c4c7130e4cc88458428edb0fb4654c52c2ab Mon Sep 17 00:00:00 2001 -From: Pino Toscano -Date: Wed, 3 Aug 2016 15:01:59 +0200 -Subject: [PATCH] mllib: move _exit from v2v as Exit module - -Move the OCaml binding to C _exit to an own module. - -Just code motion, adapting v2v in the process. - -(cherry picked from commit 5077c020469827e104995cb2143d6d4eda981b9f) ---- - mllib/Makefile.am | 5 ++++- - mllib/exit-c.c | 33 +++++++++++++++++++++++++++++++++ - mllib/exit.ml | 19 +++++++++++++++++++ - mllib/exit.mli | 20 ++++++++++++++++++++ - po/POTFILES | 2 +- - po/POTFILES-ml | 1 + - v2v/Makefile.am | 3 ++- - v2v/changeuid-c.c | 33 --------------------------------- - v2v/changeuid.ml | 7 ++----- - 9 files changed, 82 insertions(+), 41 deletions(-) - create mode 100644 mllib/exit-c.c - create mode 100644 mllib/exit.ml - create mode 100644 mllib/exit.mli - delete mode 100644 v2v/changeuid-c.c - -diff --git a/mllib/Makefile.am b/mllib/Makefile.am -index 8807d86..22ee5db 100644 ---- a/mllib/Makefile.am -+++ b/mllib/Makefile.am -@@ -30,6 +30,7 @@ SOURCES_MLI = \ - common_utils.mli \ - curl.mli \ - dev_t.mli \ -+ exit.mli \ - fsync.mli \ - JSON.mli \ - mkdtemp.mli \ -@@ -55,12 +56,14 @@ SOURCES_ML = \ - regedit.ml \ - StatVFS.ml \ - JSON.ml \ -- curl.ml -+ curl.ml \ -+ exit.ml - - SOURCES_C = \ - ../fish/progress.c \ - ../fish/uri.c \ - dev_t-c.c \ -+ exit-c.c \ - fsync-c.c \ - mkdtemp-c.c \ - progress-c.c \ -diff --git a/mllib/exit-c.c b/mllib/exit-c.c -new file mode 100644 -index 0000000..eed58a3 ---- /dev/null -+++ b/mllib/exit-c.c -@@ -0,0 +1,33 @@ -+/* libguestfs OCaml tools common code -+ * Copyright (C) 2009-2016 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 -+ -+#include -+#include -+#include -+ -+#include -+ -+extern int guestfs_int_mllib_exit (value rv) __attribute__((noreturn)); -+ -+int -+guestfs_int_mllib_exit (value rv) -+{ -+ _exit (Int_val (rv)); -+} -diff --git a/mllib/exit.ml b/mllib/exit.ml -new file mode 100644 -index 0000000..e752bfe ---- /dev/null -+++ b/mllib/exit.ml -@@ -0,0 +1,19 @@ -+(* libguestfs OCaml tools common code -+ * Copyright (C) 2016 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. -+ *) -+ -+external _exit : int -> unit = "guestfs_int_mllib_exit" "noalloc" -diff --git a/mllib/exit.mli b/mllib/exit.mli -new file mode 100644 -index 0000000..c1f0ab5 ---- /dev/null -+++ b/mllib/exit.mli -@@ -0,0 +1,20 @@ -+(* libguestfs OCaml tools common code -+ * Copyright (C) 2016 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. -+ *) -+ -+val _exit : int -> unit -+(** Call _exit directly, ie. do not run OCaml atexit handlers. *) -diff --git a/po/POTFILES b/po/POTFILES -index 98d4623..756fc5e 100644 ---- a/po/POTFILES -+++ b/po/POTFILES -@@ -265,6 +265,7 @@ lua/lua-guestfs.c - make-fs/make-fs.c - mllib/dev_t-c.c - mllib/dummy.c -+mllib/exit-c.c - mllib/fsync-c.c - mllib/mkdtemp-c.c - mllib/progress-c.c -@@ -369,7 +370,6 @@ utils/boot-benchmark/boot-benchmark-range.pl - utils/boot-benchmark/boot-benchmark.c - utils/qemu-boot/qemu-boot.c - utils/qemu-speed-test/qemu-speed-test.c --v2v/changeuid-c.c - v2v/domainxml-c.c - v2v/utils-c.c - v2v/xml-c.c -diff --git a/po/POTFILES-ml b/po/POTFILES-ml -index f5e8eba..8b1cad7 100644 ---- a/po/POTFILES-ml -+++ b/po/POTFILES-ml -@@ -46,6 +46,7 @@ mllib/common_utils.ml - mllib/common_utils_tests.ml - mllib/curl.ml - mllib/dev_t.ml -+mllib/exit.ml - mllib/fsync.ml - mllib/guestfs_config.ml - mllib/libdir.ml -diff --git a/v2v/Makefile.am b/v2v/Makefile.am -index 73a2d68..0486cfe 100644 ---- a/v2v/Makefile.am -+++ b/v2v/Makefile.am -@@ -116,8 +116,8 @@ SOURCES_C = \ - ../mllib/dev_t-c.c \ - ../mllib/mkdtemp-c.c \ - ../mllib/statvfs-c.c \ -+ ../mllib/exit-c.c \ - domainxml-c.c \ -- changeuid-c.c \ - utils-c.c \ - xml-c.c - -@@ -146,6 +146,7 @@ BOBJECTS = \ - $(top_builddir)/mllib/mkdtemp.cmo \ - $(top_builddir)/mllib/JSON.cmo \ - $(top_builddir)/mllib/StatVFS.cmo \ -+ $(top_builddir)/mllib/exit.cmo \ - $(top_builddir)/mllib/curl.cmo \ - $(top_builddir)/customize/customize_utils.cmo \ - $(top_builddir)/customize/firstboot.cmo \ -diff --git a/v2v/changeuid-c.c b/v2v/changeuid-c.c -deleted file mode 100644 -index 0de5a30..0000000 ---- a/v2v/changeuid-c.c -+++ /dev/null -@@ -1,33 +0,0 @@ --/* virt-v2v -- * Copyright (C) 2009-2016 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 -- --#include --#include --#include -- --#include -- --extern int v2v_exit (value rv) __attribute__((noreturn)); -- --int --v2v_exit (value rv) --{ -- _exit (Int_val (rv)); --} -diff --git a/v2v/changeuid.ml b/v2v/changeuid.ml -index 07cf6fb..53c0bc3 100644 ---- a/v2v/changeuid.ml -+++ b/v2v/changeuid.ml -@@ -33,9 +33,6 @@ type t = { - - let create ?uid ?gid () = { uid = uid; gid = gid } - --(* Call _exit directly, ie. do not run OCaml atexit handlers. *) --external _exit : int -> unit = "v2v_exit" "noalloc" -- - let with_fork { uid = uid; gid = gid } name f = - let pid = fork () in - -@@ -46,9 +43,9 @@ let with_fork { uid = uid; gid = gid } name f = - (try f () - with exn -> - eprintf "%s: changeuid: %s: %s\n%!" prog name (Printexc.to_string exn); -- _exit 1 -+ Exit._exit 1 - ); -- _exit 0 -+ Exit._exit 0 - ); - - (* Parent. *) --- -1.8.3.1 - diff --git a/SOURCES/0164-dib-rework-run-of-extra-data.d-hooks-RHBZ-1362354.patch b/SOURCES/0164-dib-rework-run-of-extra-data.d-hooks-RHBZ-1362354.patch deleted file mode 100644 index 748aa31..0000000 --- a/SOURCES/0164-dib-rework-run-of-extra-data.d-hooks-RHBZ-1362354.patch +++ /dev/null @@ -1,320 +0,0 @@ -From 89edc42bc6e62851dffc32276b0c24f2a4bf8cf6 Mon Sep 17 00:00:00 2001 -From: Pino Toscano -Date: Wed, 3 Aug 2016 16:40:20 +0200 -Subject: [PATCH] dib: rework run of extra-data.d hooks (RHBZ#1362354) - -Instead of running them before lanching the appliance with the disks and -then uploading the result after root.d hooks run, mount the root in the -local temporary directory using FUSE and then run the hooks on the -guest. Other than being closer to what diskimage-builder does, it also -avoids issues with the extra-data.d scripts assuming to find things -already, and we don't error out while trying to unpack files on the -guest. - -Since virt-dib requires FUSE now, build it only if FUSE is supported. - -(cherry picked from commit d12be6625a74b4a088c75da5ae3a968678d814fd) ---- - Makefile.am | 4 +- - dib/Makefile.am | 4 +- - dib/dib.ml | 123 +++++++++++++++++++++++++++++++------------------------ - dib/virt-dib.pod | 23 ----------- - 4 files changed, 76 insertions(+), 78 deletions(-) - -diff --git a/Makefile.am b/Makefile.am -index ce20058..0945993 100644 ---- a/Makefile.am -+++ b/Makefile.am -@@ -145,7 +145,6 @@ SUBDIRS += \ - mllib \ - customize \ - builder builder/website \ -- dib \ - get-kernel \ - resize \ - sparsify \ -@@ -154,6 +153,9 @@ SUBDIRS += \ - if HAVE_OCAML_PKG_LIBVIRT - SUBDIRS += v2v/test-harness - endif -+if HAVE_FUSE -+SUBDIRS += dib -+endif - endif - - # Perl tools. -diff --git a/dib/Makefile.am b/dib/Makefile.am -index ff6a933..ac0af26 100644 ---- a/dib/Makefile.am -+++ b/dib/Makefile.am -@@ -34,7 +34,8 @@ SOURCES_ML = \ - - SOURCES_C = \ - ../mllib/dev_t-c.c \ -- ../mllib/mkdtemp-c.c -+ ../mllib/mkdtemp-c.c \ -+ ../mllib/exit-c.c - - bin_PROGRAMS = - -@@ -62,6 +63,7 @@ BOBJECTS = \ - $(top_builddir)/mllib/stringMap.cmo \ - $(top_builddir)/mllib/common_utils.cmo \ - $(top_builddir)/mllib/mkdtemp.cmo \ -+ $(top_builddir)/mllib/exit.cmo \ - $(SOURCES_ML:.ml=.cmo) - XOBJECTS = $(BOBJECTS:.cmo=.cmx) - -diff --git a/dib/dib.ml b/dib/dib.ml -index 87af4eb..17775d8 100644 ---- a/dib/dib.ml -+++ b/dib/dib.ml -@@ -69,13 +69,15 @@ let envvars_string l = - - let prepare_external ~envvars ~dib_args ~dib_vars ~out_name ~root_label - ~rootfs_uuid ~image_cache ~arch ~network ~debug -- destdir libdir hooksdir tmpdir fakebindir all_elements element_paths = -+ destdir libdir hooksdir fakebindir all_elements element_paths = - let network_string = if network then "" else "1" in - - let run_extra = sprintf "\ - #!/bin/bash - set -e - %s -+mount_dir=$1 -+shift - target_dir=$1 - shift - script=$1 -@@ -87,7 +89,7 @@ shift - export PATH=%s:$PATH - - # d-i-b variables --export TMP_MOUNT_PATH=%s -+export TMP_MOUNT_PATH=\"$mount_dir\" - export DIB_OFFLINE=%s - export IMAGE_NAME=\"%s\" - export DIB_ROOT_LABEL=\"%s\" -@@ -120,7 +122,6 @@ $target_dir/$script - (if debug >= 1 then "set -x\n" else "") - (envvars_string envvars) - fakebindir -- (quote tmpdir) - network_string - out_name - root_label -@@ -134,10 +135,7 @@ $target_dir/$script - (String.concat ":" element_paths) - (quote dib_vars) - debug in -- write_script (destdir // "run-part-extra.sh") run_extra; -- -- (* Needed as TMPDIR for the extra-data hooks *) -- do_mkdir (tmpdir // "tmp") -+ write_script (destdir // "run-part-extra.sh") run_extra - - let prepare_aux ~envvars ~dib_args ~dib_vars ~log_file ~out_name ~rootfs_uuid - ~arch ~network ~root_label ~install_type ~debug ~extra_packages -@@ -392,26 +390,61 @@ let run_parts ~debug ~sysroot ~blockdev ~log_file ?(new_wd = "") - flush_all (); - Buffer.contents outbuf - --let run_parts_host ~debug hooks_dir hook_name scripts run_script = -+let run_parts_host ~debug (g : Guestfs.guestfs) hooks_dir hook_name base_mount_dir scripts run_script = - let hook_dir = hooks_dir // hook_name in - let scripts = List.sort digit_prefix_compare scripts in -- let timings = Hashtbl.create 13 in -- List.iter ( -- fun x -> -- message (f_"Running: %s/%s") hook_name x; -- let cmd = [ run_script; hook_dir; x ] in -- let run () = -- run_command cmd in -- let delta_t = timed_run run in -- if debug >= 1 then ( -- printf "\n"; -- printf "%s completed after %.3f s\n" x delta_t -- ); -- Hashtbl.add timings x delta_t; -- ) scripts; -- if debug >= 1 then ( -- print_string (timing_output ~target_name:hook_name scripts timings) -+ let mount_dir = base_mount_dir // hook_name in -+ do_mkdir mount_dir; -+ -+ let rec fork_and_run () = -+ let pid = Unix.fork () in -+ if pid = 0 then ( (* child *) -+ let retcode = run_scripts () in -+ flush_all (); -+ let cmd = [ "guestunmount"; mount_dir ] in -+ ignore (run_command cmd); -+ Exit._exit retcode -+ ); -+ pid -+ and run_scripts () = -+ let timings = Hashtbl.create 13 in -+ let rec loop = function -+ | x :: xs -> -+ message (f_"Running: %s/%s") hook_name x; -+ let cmd = [ run_script; mount_dir; hook_dir; x ] in -+ let retcode = ref 0 in -+ let run () = -+ retcode := run_command cmd in -+ let delta_t = timed_run run in -+ if debug >= 1 then ( -+ printf "\n"; -+ printf "%s completed after %.3f s\n" x delta_t -+ ); -+ Hashtbl.add timings x delta_t; -+ let retcode = !retcode in -+ if retcode <> 0 then retcode -+ else loop xs -+ | [] -> 0 -+ in -+ let retcode = loop scripts in -+ if debug >= 1 then ( -+ print_string (timing_output ~target_name:hook_name scripts timings) -+ ); -+ retcode -+ in -+ -+ g#mount_local mount_dir; -+ let pid = fork_and_run () in -+ g#mount_local_run (); -+ -+ (match snd (Unix.waitpid [] pid) with -+ | Unix.WEXITED 0 -> () -+ | Unix.WEXITED i -> exit i -+ | Unix.WSIGNALED i -+ | Unix.WSTOPPED i -> -+ error (f_"sub-process killed by signal (%d)") i - ); -+ - flush_all () - - let run_install_packages ~debug ~blockdev ~log_file -@@ -455,8 +488,6 @@ let main () = - do_mkdir auxtmpdir; - let hookstmpdir = auxtmpdir // "hooks" in - do_mkdir (hookstmpdir // "environment.d"); (* Just like d-i-b does. *) -- let extradatatmpdir = tmpdir // "extra-data" in -- do_mkdir extradatatmpdir; - do_mkdir (auxtmpdir // "out" // image_basename_d); - let elements = - if cmdline.use_base then ["base"] @ cmdline.elements -@@ -575,20 +606,11 @@ let main () = - prepare_external ~envvars ~dib_args ~dib_vars ~out_name:image_basename - ~root_label ~rootfs_uuid ~image_cache ~arch - ~network:cmdline.network ~debug -- tmpdir cmdline.basepath hookstmpdir extradatatmpdir -+ tmpdir cmdline.basepath hookstmpdir - (auxtmpdir // "fake-bin") - all_elements cmdline.element_paths; - -- let run_hook_host hook = -- try -- let scripts = Hashtbl.find final_hooks hook in -- if debug >= 1 then ( -- printf "Running hooks for %s...\n%!" hook; -- ); -- run_parts_host ~debug hookstmpdir hook scripts -- (tmpdir // "run-part-extra.sh") -- with Not_found -> () -- and run_hook ~blockdev ~sysroot ?(new_wd = "") (g : Guestfs.guestfs) hook = -+ let run_hook ~blockdev ~sysroot ?(new_wd = "") (g : Guestfs.guestfs) hook = - try - let scripts = Hashtbl.find final_hooks hook in - if debug >= 1 then ( -@@ -597,8 +619,6 @@ let main () = - run_parts ~debug ~sysroot ~blockdev ~log_file ~new_wd g hook scripts - with Not_found -> "" in - -- run_hook_host "extra-data.d"; -- - let copy_in (g : Guestfs.guestfs) srcdir destdir = - let desttar = Filename.temp_file ~temp_dir:tmpdir "virt-dib." ".tar.gz" in - let cmd = [ "tar"; "czf"; desttar; "-C"; srcdir; "--owner=root"; -@@ -608,18 +628,6 @@ let main () = - g#tar_in ~compress:"gzip" desttar destdir; - Sys.remove desttar in - -- let copy_preserve_in (g : Guestfs.guestfs) srcdir destdir = -- let desttar = Filename.temp_file ~temp_dir:tmpdir "virt-dib." ".tar.gz" in -- let remotetar = "/tmp/aux/" ^ (Filename.basename desttar) in -- let cmd = [ "tar"; "czf"; desttar; "-C"; srcdir; "--owner=root"; -- "--group=root"; "." ] in -- if run_command cmd <> 0 then exit 1; -- g#upload desttar remotetar; -- let verbose_flag = if debug > 0 then "v" else "" in -- ignore (g#debug "sh" [| "tar"; "-C"; "/sysroot" ^ destdir; "--no-overwrite-dir"; "-x" ^ verbose_flag ^ "zf"; "/sysroot" ^ remotetar |]); -- Sys.remove desttar; -- g#rm remotetar in -- - if debug >= 1 then - ignore (run_command [ "tree"; "-ps"; tmpdir ]); - -@@ -747,7 +755,16 @@ let main () = - and run_hook_subroot hook = - do_run_hooks_noout ~sysroot:Subroot hook - and do_run_hooks_noout ~sysroot ?(new_wd = "") hook = -- ignore (run_hook ~sysroot ~blockdev ~new_wd g hook) in -+ ignore (run_hook ~sysroot ~blockdev ~new_wd g hook) -+ and run_hook_host hook = -+ try -+ let scripts = Hashtbl.find final_hooks hook in -+ if debug >= 1 then ( -+ printf "Running hooks for %s...\n%!" hook; -+ ); -+ run_parts_host ~debug g hookstmpdir hook tmpdir scripts -+ (tmpdir // "run-part-extra.sh") -+ with Not_found -> () in - - g#sync (); - checked_umount_all (); -@@ -799,7 +816,7 @@ let main () = - mount_aux (); - g#ln_s "aux/hooks" "/tmp/in_target.d"; - -- copy_preserve_in g extradatatmpdir "/"; -+ run_hook_host "extra-data.d"; - - run_hook_in "pre-install.d"; - -diff --git a/dib/virt-dib.pod b/dib/virt-dib.pod -index 8ccb9f5..41e7ec7 100644 ---- a/dib/virt-dib.pod -+++ b/dib/virt-dib.pod -@@ -577,29 +577,6 @@ arguments - - =item - --C scripts run in the host environment, before all the --other ones (even C); this means that, depending on the --configuration for the elements, some of them may fail due to missing --content (usually directories) in C. -- --Workarounds for this may be either: -- --=over 4 -- --=item -- --fix the C scripts to create the missing directories -- --=item -- --create (and use) a simple element with a C script --named e.g. F<00-create-missing-dirs> to create the missing --directories -- --=back -- --=item -- - extra tools needed on some out-of-chroot phases need to be available - in the appliance, see L. - --- -1.8.3.1 - diff --git a/SOURCES/0165-mllib-_exit-should-return-a.patch b/SOURCES/0165-mllib-_exit-should-return-a.patch deleted file mode 100644 index 594f93c..0000000 --- a/SOURCES/0165-mllib-_exit-should-return-a.patch +++ /dev/null @@ -1,37 +0,0 @@ -From a65e9185fb8d4b20c41b612e4c461db60ab393f2 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Thu, 4 Aug 2016 09:25:55 +0100 -Subject: [PATCH] mllib: _exit should return 'a - -Fixes commit 0dfa96c043cee4ce82c0a45c3ad09b0a61798b79. - -(cherry picked from commit 9fc0418db541065841af53632ae2406efc968416) ---- - mllib/exit.ml | 2 +- - mllib/exit.mli | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/mllib/exit.ml b/mllib/exit.ml -index e752bfe..4ca8a27 100644 ---- a/mllib/exit.ml -+++ b/mllib/exit.ml -@@ -16,4 +16,4 @@ - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - *) - --external _exit : int -> unit = "guestfs_int_mllib_exit" "noalloc" -+external _exit : int -> 'a = "guestfs_int_mllib_exit" "noalloc" -diff --git a/mllib/exit.mli b/mllib/exit.mli -index c1f0ab5..ddf3072 100644 ---- a/mllib/exit.mli -+++ b/mllib/exit.mli -@@ -16,5 +16,5 @@ - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - *) - --val _exit : int -> unit -+val _exit : int -> 'a - (** Call _exit directly, ie. do not run OCaml atexit handlers. *) --- -1.8.3.1 - diff --git a/SOURCES/0166-sparsify-Exit-with-error-code-3-if-fstrim-is-not-sup.patch b/SOURCES/0166-sparsify-Exit-with-error-code-3-if-fstrim-is-not-sup.patch deleted file mode 100644 index 03b1c20..0000000 --- a/SOURCES/0166-sparsify-Exit-with-error-code-3-if-fstrim-is-not-sup.patch +++ /dev/null @@ -1,64 +0,0 @@ -From e93dd9f2736f84942e1171a61b6f6739c3242f2f Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Fri, 5 Aug 2016 12:09:59 +0100 -Subject: [PATCH] sparsify: Exit with error code 3 if fstrim is not supported - by the appliance. - -This replaces the indirect exception catching from -commit 931aec5b8846ce63b0e2b6beba5861a019b5f694 with a direct feature -test. - -Fixes commit 931aec5b8846ce63b0e2b6beba5861a019b5f694. - -(cherry picked from commit 97b6b4a4ebc6f6e333ee448f61e1d6142cfffe27) ---- - sparsify/in_place.ml | 19 +++++++------------ - 1 file changed, 7 insertions(+), 12 deletions(-) - -diff --git a/sparsify/in_place.ml b/sparsify/in_place.ml -index 389ea44..5cd03ef 100644 ---- a/sparsify/in_place.ml -+++ b/sparsify/in_place.ml -@@ -29,7 +29,7 @@ open Cmdline - - module G = Guestfs - --let rec run disk format ignores machine_readable zeroes = -+let run disk format ignores machine_readable zeroes = - (* Connect to libguestfs. *) - let g = open_guestfs () in - -@@ -40,17 +40,6 @@ let rec run disk format ignores machine_readable zeroes = - Sys.set_signal Sys.sigquit (Sys.Signal_handle set_quit); - g#set_pgroup true; - -- try -- perform g disk format ignores machine_readable zeroes quit -- with -- G.Error msg as exn -> -- if g#last_errno () = G.Errno.errno_ENOTSUP then ( -- (* for exit code 3, see man page *) -- error ~exit_code:3 (f_"discard/trim is not supported: %s") msg; -- ) -- else raise exn -- --and perform g disk format ignores machine_readable zeroes quit = - (* XXX Current limitation of the API. Can remove this hunk in future. *) - let format = - match format with -@@ -62,6 +51,12 @@ and perform g disk format ignores machine_readable zeroes quit = - if not (quiet ()) then Progress.set_up_progress_bar ~machine_readable g; - g#launch (); - -+ (* If discard is not supported in the appliance, we must return exit -+ * code 3. See the man page. -+ *) -+ if not (g#feature_available [|"fstrim"|]) then -+ error ~exit_code:3 (f_"discard/trim is not supported"); -+ - (* Discard non-ignored filesystems that we are able to mount, and - * selected swap partitions. - *) --- -1.8.3.1 - diff --git a/SOURCES/0167-daemon-fstrim-Turn-discard-operation-is-not-supporte.patch b/SOURCES/0167-daemon-fstrim-Turn-discard-operation-is-not-supporte.patch deleted file mode 100644 index 630411c..0000000 --- a/SOURCES/0167-daemon-fstrim-Turn-discard-operation-is-not-supporte.patch +++ /dev/null @@ -1,53 +0,0 @@ -From be25e1106975afe3be160953a85e0054694eb526 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Fri, 5 Aug 2016 12:18:53 +0100 -Subject: [PATCH] daemon: fstrim: Turn "discard operation is not supported" - into ENOTSUP. - -Because we run the external fstrim command we don't have access to the -kernel errno when it fails. However in the case where it prints this -specific error message, turn that into errno ENOTSUP. - -(cherry picked from commit 116a41d04877fda40bc986abc43e98f6c787a59e) ---- - daemon/fstrim.c | 8 +++++++- - generator/actions.ml | 4 ++++ - 2 files changed, 11 insertions(+), 1 deletion(-) - -diff --git a/daemon/fstrim.c b/daemon/fstrim.c -index 1ad3630..527acfd 100644 ---- a/daemon/fstrim.c -+++ b/daemon/fstrim.c -@@ -105,7 +105,13 @@ do_fstrim (const char *path, - - r = commandv (&out, &err, argv); - if (r == -1) { -- reply_with_error ("%s", err); -+ /* If the error is about the kernel operation not being supported -+ * for this filesystem type, then return errno ENOTSUP here. -+ */ -+ if (strstr (err, "discard operation is not supported")) -+ reply_with_error_errno (ENOTSUP, "%s", err); -+ else -+ reply_with_error ("%s", err); - return -1; - } - -diff --git a/generator/actions.ml b/generator/actions.ml -index a515c4c..6cadc32 100644 ---- a/generator/actions.ml -+++ b/generator/actions.ml -@@ -10588,6 +10588,10 @@ filesystem, the host filesystem, qemu and the host kernel. - If this support isn't present it may give an error or even - appear to run but do nothing. - -+In the case where the kernel vfs driver does not support -+trimming, this call will fail with errno set to C. -+Currently this happens when trying to trim FAT filesystems. -+ - See also C. That is a slightly - different operation that turns free space in the filesystem - into zeroes. It is valid to call C either --- -1.8.3.1 - diff --git a/SOURCES/0168-sparsify-Warn-instead-of-error-if-a-filesystem-canno.patch b/SOURCES/0168-sparsify-Warn-instead-of-error-if-a-filesystem-canno.patch deleted file mode 100644 index 32a2ba5..0000000 --- a/SOURCES/0168-sparsify-Warn-instead-of-error-if-a-filesystem-canno.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 27194a339768ec34de52f4e00d3fca36f7e65058 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Fri, 5 Aug 2016 12:20:00 +0100 -Subject: [PATCH] sparsify: Warn instead of error if a filesystem cannot be - fstrimmed (RHBZ#1364347). - -Thanks: Xianghua Chen -(cherry picked from commit 4d5335a56d709fdd4357ab9ae04ba0a758b12fe9) ---- - sparsify/in_place.ml | 9 ++++++++- - 1 file changed, 8 insertions(+), 1 deletion(-) - -diff --git a/sparsify/in_place.ml b/sparsify/in_place.ml -index 5cd03ef..e2ee9d9 100644 ---- a/sparsify/in_place.ml -+++ b/sparsify/in_place.ml -@@ -89,7 +89,14 @@ let run disk format ignores machine_readable zeroes = - if mounted then ( - message (f_"Trimming %s") fs; - -- g#fstrim "/" -+ try g#fstrim "/" -+ with G.Error msg as exn -> -+ if g#last_errno () = G.Errno.errno_ENOTSUP then ( -+ let vfs_type = try g#vfs_type fs with _ -> "unknown" in -+ warning (f_"fstrim operation is not supported on %s (%s). Suppress this warning using '--ignore %s', or use copying mode instead.") -+ fs vfs_type fs -+ ) -+ else raise exn - ) else ( - let is_linux_x86_swap = - (* Look for the signature for Linux swap on i386. --- -1.8.3.1 - diff --git a/SOURCES/0169-sparsify-Add-a-regression-test-for-RHBZ-1364347.patch b/SOURCES/0169-sparsify-Add-a-regression-test-for-RHBZ-1364347.patch deleted file mode 100644 index 6a8ca37..0000000 --- a/SOURCES/0169-sparsify-Add-a-regression-test-for-RHBZ-1364347.patch +++ /dev/null @@ -1,135 +0,0 @@ -From 0772a6866796bced2d4694e40ad87b8b8f6be902 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Fri, 5 Aug 2016 12:20:49 +0100 -Subject: [PATCH] sparsify: Add a regression test for RHBZ#1364347. - -Add a regression test for the previous commit. - -(cherry picked from commit 71de3d49a395b4b91d282ad01bb2d382060c8392) - -Conflicts: - sparsify/Makefile.am ---- - sparsify/Makefile.am | 7 +- - ...st-virt-sparsify-in-place-fstrim-unsupported.sh | 84 ++++++++++++++++++++++ - 2 files changed, 89 insertions(+), 2 deletions(-) - create mode 100755 sparsify/test-virt-sparsify-in-place-fstrim-unsupported.sh - -diff --git a/sparsify/Makefile.am b/sparsify/Makefile.am -index 22a684b..61f28bc 100644 ---- a/sparsify/Makefile.am -+++ b/sparsify/Makefile.am -@@ -21,7 +21,9 @@ EXTRA_DIST = \ - $(SOURCES_MLI) $(SOURCES_ML) $(SOURCES_C) \ - virt-sparsify.pod \ - test-virt-sparsify.sh \ -- test-virt-sparsify-in-place.sh -+ test-virt-sparsify-in-place.sh \ -+ test-virt-sparsify-in-place-fstrim-unsupported.sh \ -+ virt-sparsify.pod - - CLEANFILES = *~ *.annot *.cmi *.cmo *.cmx *.cmxa *.o virt-sparsify - -@@ -128,7 +130,8 @@ TESTS_ENVIRONMENT = $(top_builddir)/run --test - if ENABLE_APPLIANCE - TESTS = \ - test-virt-sparsify.sh \ -- test-virt-sparsify-in-place.sh -+ test-virt-sparsify-in-place.sh \ -+ test-virt-sparsify-in-place-fstrim-unsupported.sh - endif ENABLE_APPLIANCE - - check-valgrind: -diff --git a/sparsify/test-virt-sparsify-in-place-fstrim-unsupported.sh b/sparsify/test-virt-sparsify-in-place-fstrim-unsupported.sh -new file mode 100755 -index 0000000..d6a300d ---- /dev/null -+++ b/sparsify/test-virt-sparsify-in-place-fstrim-unsupported.sh -@@ -0,0 +1,84 @@ -+#!/bin/bash - -+# libguestfs virt-sparsify --in-place test script -+# Copyright (C) 2011-2016 Red Hat Inc. -+# -+# This program is free software; you can redistribute it and/or modify -+# it under the terms of the GNU General Public License as published by -+# the Free Software Foundation; either version 2 of the License, or -+# (at your option) any later version. -+# -+# This program is distributed in the hope that it will be useful, -+# but WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+# GNU General Public License for more details. -+# -+# You should have received a copy of the GNU General Public License -+# along with this program; if not, write to the Free Software -+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -+ -+# Test that we do the right thing for filesystems where the fstrim -+# operation is not supported. -+# -+# https://bugzilla.redhat.com/show_bug.cgi?id=1364347 -+# -+# This test assumes that the kernel vfat driver does not support -+# fstrim. It might become supported in a future kernel version in -+# which case we could use a different filesystem for this test, or -+# delete the test if we are confident that all common filesystems are -+# supported. -+# -+# The reason why vfat is significant is because UEFI guests use it. -+ -+export LANG=C -+set -e -+set -x -+ -+if [ -n "$SKIP_TEST_VIRT_SPARSIFY_IN_PLACE_FSTRIM_UNSUPPORTED_SH" ]; then -+ echo "$0: skipping test (environment variable set)" -+ exit 77 -+fi -+ -+if [ "$(guestfish get-backend)" = "uml" ]; then -+ echo "$0: skipping test because uml backend does not support discard" -+ exit 77 -+fi -+ -+img=test-virt-sparsify-in-place-fstrim-unsupported.img -+log=test-virt-sparsify-in-place-fstrim-unsupported.log -+rm -f $img $log -+ -+# Create a test filesystem with a single vfat filesystem. -+guestfish -N $img=fs:vfat exit -+ -+# This should warn. -+virt-sparsify --in-place $img |& tee $log -+ -+# Check the warning was emitted. -+grep "warning:.*fstrim" $log -+ -+# This should ignore the filesystem and not warn. -+virt-sparsify --in-place --ignore /dev/sda1 $img |& tee $log -+ -+if grep "warning:.*fstrim.*not supported" $log; then -+ echo "$0: filesystem /dev/sda1 was not ignored" -+ exit 1 -+fi -+ -+# Create a test filesystem with vfat and ext4 filesystems. -+guestfish -N $img=bootroot:vfat:ext4 exit -+ -+# This should warn. -+virt-sparsify --in-place $img |& tee $log -+ -+# Check the warning was emitted. -+grep "warning:.*fstrim" $log -+ -+# This should ignore the filesystem and not warn. -+virt-sparsify --in-place --ignore /dev/sda1 $img |& tee $log -+ -+if grep "warning:.*fstrim.*not supported" $log; then -+ echo "$0: filesystem /dev/sda1 was not ignored" -+ exit 1 -+fi -+ -+rm $img $log --- -1.8.3.1 - diff --git a/SOURCES/0170-p2v-Fix-s-is-are-in-GUI-message.patch b/SOURCES/0170-p2v-Fix-s-is-are-in-GUI-message.patch deleted file mode 100644 index be17871..0000000 --- a/SOURCES/0170-p2v-Fix-s-is-are-in-GUI-message.patch +++ /dev/null @@ -1,31 +0,0 @@ -From b95d44a2d68e506be4fb996e8e0a140457d5dbe7 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Fri, 12 Aug 2016 10:43:44 +0100 -Subject: [PATCH] p2v: Fix s/is/are/ in GUI message. - -I reordered the 'and' clause to make it sound a bit more natural. - -Thanks: Junqin Zhou. -(cherry picked from commit d33e28c98807757d53ff87870a83604b4f8381d5) ---- - p2v/gui.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/p2v/gui.c b/p2v/gui.c -index e0b455a..2e46370 100644 ---- a/p2v/gui.c -+++ b/p2v/gui.c -@@ -1489,8 +1489,8 @@ set_log_dir (const char *remote_dir) - CLEANUP_FREE char *msg; - - if (asprintf (&msg, -- _("Log files and debug information " -- "is saved to this directory " -+ _("Debug information and log files " -+ "are saved to this directory " - "on the conversion server:\n" - "%s"), - remote_dir ? remote_dir : "") == -1) { --- -1.8.3.1 - diff --git a/SOURCES/0171-v2v-Make-fstrim-warning-clearer-RHBZ-1366456.patch b/SOURCES/0171-v2v-Make-fstrim-warning-clearer-RHBZ-1366456.patch deleted file mode 100644 index 001f781..0000000 --- a/SOURCES/0171-v2v-Make-fstrim-warning-clearer-RHBZ-1366456.patch +++ /dev/null @@ -1,75 +0,0 @@ -From 91db4de9f068eb7d90f30e1d7205b3f0c988cce7 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Fri, 12 Aug 2016 10:32:26 +0100 -Subject: [PATCH] v2v: Make fstrim warning clearer (RHBZ#1366456). - -This reverts the change made for RHBZ#1168144. The warning is now -always displayed. - -It would be nice to make the warning actionable, but there is not a -lot that end users can do since fstrim is such a complex topic -interacting with all filesystem and storage layers. - -(cherry picked from commit 66816e11332b07a07efd6821e7ecf090691ce441) ---- - v2v/v2v.ml | 6 +----- - v2v/virt-v2v.pod | 26 ++++++++++++++++++++++++++ - 2 files changed, 27 insertions(+), 5 deletions(-) - -diff --git a/v2v/v2v.ml b/v2v/v2v.ml -index 4b06bc1..21f8d77 100644 ---- a/v2v/v2v.ml -+++ b/v2v/v2v.ml -@@ -425,11 +425,7 @@ and do_fstrim g no_trim inspect = - if mounted then ( - try g#fstrim "/" - with G.Error msg -> -- (* Only emit this warning when debugging, because otherwise -- * it causes distress (RHBZ#1168144). -- *) -- if verbose () then -- warning (f_"%s (ignored)") msg -+ warning (f_"fstrim on guest filesystem %s failed. Usually you can ignore this message. To find out more read \"Trimming\" in virt-v2v(1).\n\nOriginal message: %s") dev msg - ) - ) fses - -diff --git a/v2v/virt-v2v.pod b/v2v/virt-v2v.pod -index 9fc0b72..434f57e 100644 ---- a/v2v/virt-v2v.pod -+++ b/v2v/virt-v2v.pod -@@ -1512,6 +1512,32 @@ one CPU core and between 512 MB and 1 GB of RAM per running instance. - - Virt-v2v can be run in a virtual machine. - -+=head2 Trimming -+ -+Virt-v2v attempts to optimize the speed of conversion by ignoring -+guest filesystem data which is not used. This would include unused -+filesystem blocks, blocks containing zeroes, and deleted files. -+ -+To do this, virt-v2v issues a non-destructive L operation. -+As this happens to an overlay placed over the guest data, it does -+B affect the source in any way. -+ -+If this fstrim operation fails, you will see a warning, but virt-v2v -+will continue anyway. It may run more slowly (in some cases much more -+slowly), because it is copying the unused parts of the disk. -+ -+Unfortunately support for fstrim is not universal, and it also depends -+on specific details of the filesystem, partition alignment, and -+backing storage. As an example, NTFS filesystems cannot be fstrimmed -+if they occupy a partition which is not aligned to the underlying -+storage. That was the default on Windows before Vista. As another -+example, VFAT filesystems (used by UEFI guests) cannot be trimmed at -+all. -+ -+fstrim support in the Linux kernel is improving gradually, so over -+time some of these restrictions will be lifted and virt-v2v will work -+faster. -+ - =head1 POST-CONVERSION TASKS - - =head2 Guest network configuration --- -1.8.3.1 - diff --git a/SOURCES/0172-v2v-Add-o-discard-option-when-fstrimming.patch b/SOURCES/0172-v2v-Add-o-discard-option-when-fstrimming.patch deleted file mode 100644 index 03f301f..0000000 --- a/SOURCES/0172-v2v-Add-o-discard-option-when-fstrimming.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 2e9687c784cd19f6ac1c426d7578de65e55025c9 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Fri, 12 Aug 2016 10:34:54 +0100 -Subject: [PATCH] v2v: Add -o discard option when fstrimming. - -This *may* be required by some filesystems in order for fstrim to -work. I'm not actually sure if this is true, but it's what -virt-sparsify --in-place does, and that utility has been tested a lot -more in regards to trimming. - -(cherry picked from commit dd22e376c4ec8fd7c78c78f94c60bb763ddcf08f) ---- - v2v/v2v.ml | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/v2v/v2v.ml b/v2v/v2v.ml -index 21f8d77..561317c 100644 ---- a/v2v/v2v.ml -+++ b/v2v/v2v.ml -@@ -421,7 +421,10 @@ and do_fstrim g no_trim inspect = - List.iter ( - fun dev -> - g#umount_all (); -- let mounted = try g#mount dev "/"; true with G.Error _ -> false in -+ let mounted = -+ try g#mount_options "discard" dev "/"; true -+ with G.Error _ -> false in -+ - if mounted then ( - try g#fstrim "/" - with G.Error msg -> --- -1.8.3.1 - diff --git a/SOURCES/0173-v2v-OVMF-is-now-fully-open-source-fix-the-man-page.patch b/SOURCES/0173-v2v-OVMF-is-now-fully-open-source-fix-the-man-page.patch deleted file mode 100644 index 10a7cdd..0000000 --- a/SOURCES/0173-v2v-OVMF-is-now-fully-open-source-fix-the-man-page.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 98f1746640771f2382c3e0d2b78ceb535a8d2cd0 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Wed, 17 Aug 2016 14:36:44 +0100 -Subject: [PATCH] v2v: OVMF is now fully open source, fix the man page. - -(cherry picked from commit 5c03a2ca8b0bcc5ea31a0c169dd022cad30d2ace) ---- - v2v/virt-v2v.pod | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/v2v/virt-v2v.pod b/v2v/virt-v2v.pod -index 434f57e..3e24025 100644 ---- a/v2v/virt-v2v.pod -+++ b/v2v/virt-v2v.pod -@@ -768,8 +768,8 @@ VMware allows you to present UEFI firmware to guests (instead of the - ordinary PC BIOS). Virt-v2v can convert these guests, but requires - that UEFI is supported by the target hypervisor. - --Currently KVM supports OVMF, a partially open source UEFI firmware, --and can run these guests. -+Currently KVM supports OVMF, an open source UEFI firmware, and can run -+these guests. - - Since OVMF support was only recently added to KVM (in 2014/2015), not - all target environments support UEFI guests yet: --- -1.8.3.1 - diff --git a/SOURCES/0174-Generate-the-lists-of-UEFI-firmware-paths.patch b/SOURCES/0174-Generate-the-lists-of-UEFI-firmware-paths.patch deleted file mode 100644 index 43eeded..0000000 --- a/SOURCES/0174-Generate-the-lists-of-UEFI-firmware-paths.patch +++ /dev/null @@ -1,625 +0,0 @@ -From 5ba28e31fde4b758ecdb5aea88d4aab7b9894f46 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Thu, 18 Aug 2016 12:35:16 +0100 -Subject: [PATCH] Generate the lists of UEFI firmware paths. - -Previously we had a list of UEFI paths in src/uefi.c, which was -accessed in virt-v2v using a private (guestfs_int_*) API and some C -binding code. This was clumsy and required the paths to be replicated -in the virt-v2v unit tests. - -Instead just generate the list of paths from the generator, creating -src/uefi.c and v2v/uefi.ml with the same content. - -Remove the C bindings and the virt-v2v unit tests associated with UEFI -paths. - -Cherry picked from commit 04fc67775e27851ce9b6c7a082ff80f1e1793365. -For this complex cherry pick I had to take into account earlier -RHEL-only patches where we removed several sets of firmware. ---- - .gitignore | 3 + - generator/Makefile.am | 3 + - generator/main.ml | 5 ++ - generator/uefi.ml | 126 ++++++++++++++++++++++++++++++++++++++++ - generator/uefi.mli | 21 +++++++ - generator/utils.ml | 16 +++++ - generator/utils.mli | 6 ++ - po/POTFILES | 1 + - po/POTFILES-ml | 1 + - src/Makefile.am | 1 + - src/appliance.c | 13 ++++- - src/guestfs-internal-frontend.h | 14 ++++- - src/utils.c | 22 ------- - v2v/Makefile.am | 4 ++ - v2v/output_libvirt.ml | 3 +- - v2v/output_qemu.ml | 4 +- - v2v/utils-c.c | 45 -------------- - v2v/utils.ml | 11 +--- - v2v/utils.mli | 7 +-- - 19 files changed, 218 insertions(+), 88 deletions(-) - create mode 100644 generator/uefi.ml - create mode 100644 generator/uefi.mli - -diff --git a/.gitignore b/.gitignore -index 85b19d4..2baf137 100644 ---- a/.gitignore -+++ b/.gitignore -@@ -469,6 +469,7 @@ Makefile.in - /src/structs-free.c - /src/structs-print.c - /src/structs-print.h -+/src/uefi.c - /src/unit-tests - /stamp-h1 - /sysprep/.depend -@@ -579,6 +580,8 @@ Makefile.in - /v2v/test-harness/dllv2v_test_harness.so - /v2v/test-harness/stamp-virt-v2v-test-harness.pod - /v2v/test-harness/virt-v2v-test-harness.1 -+/v2v/uefi.ml -+/v2v/uefi.mli - /v2v/v2v_unit_tests - /v2v/virt-v2v - /v2v/virt-v2v.1 -diff --git a/generator/Makefile.am b/generator/Makefile.am -index 393c566..3a53054 100644 ---- a/generator/Makefile.am -+++ b/generator/Makefile.am -@@ -75,6 +75,8 @@ sources = \ - tests_c_api.ml \ - tests_c_api.mli \ - types.ml \ -+ uefi.ml \ -+ uefi.mli \ - utils.ml \ - utils.mli \ - xdr.ml \ -@@ -112,6 +114,7 @@ objects = \ - bindtests.cmo \ - errnostring.cmo \ - customize.cmo \ -+ uefi.cmo \ - main.cmo - - EXTRA_DIST = $(sources) files-generated.txt -diff --git a/generator/main.ml b/generator/main.ml -index 42f6f8b..f242ed9 100644 ---- a/generator/main.ml -+++ b/generator/main.ml -@@ -45,6 +45,7 @@ open Gobject - open Golang - open Bindtests - open Errnostring -+open Uefi - open Customize - - let perror msg = function -@@ -210,6 +211,10 @@ Run it from the top source directory using the command - generate_gobject_session_header; - output_to "gobject/src/session.c" generate_gobject_session_source; - -+ output_to "src/uefi.c" generate_uefi_c; -+ output_to "v2v/uefi.ml" generate_uefi_ml; -+ output_to "v2v/uefi.mli" generate_uefi_mli; -+ - output_to "customize/customize_cmdline.mli" generate_customize_cmdline_mli; - output_to "customize/customize_cmdline.ml" generate_customize_cmdline_ml; - output_to "customize/customize-synopsis.pod" generate_customize_synopsis_pod; -diff --git a/generator/uefi.ml b/generator/uefi.ml -new file mode 100644 -index 0000000..3b371b8 ---- /dev/null -+++ b/generator/uefi.ml -@@ -0,0 +1,126 @@ -+(* libguestfs -+ * Copyright (C) 2016 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 -+ *) -+ -+(* Please read generator/README first. *) -+ -+open Utils -+open Pr -+open Docstrings -+ -+(* danpb is proposing that libvirt supports Eloader type="efi"/E -+ * (L). If that happens we can -+ * simplify or even remove this code. -+ *) -+ -+(* Order is significant *within architectures only*. *) -+let firmware = [ -+ "x86_64", -+ "/usr/share/OVMF/OVMF_CODE.fd", -+ None, -+ "/usr/share/OVMF/OVMF_VARS.fd", -+ []; -+ -+ "aarch64", -+ "/usr/share/AAVMF/AAVMF_CODE.fd", -+ None, -+ "/usr/share/AAVMF/AAVMF_VARS.fd", -+ []; -+] -+ -+let arches = sort_uniq (List.map (fun (arch, _, _, _, _) -> arch) firmware) -+ -+let generate_uefi_c () = -+ generate_header CStyle LGPLv2plus; -+ -+ pr "#include \n"; -+ pr "\n"; -+ pr "#include \n"; -+ pr "\n"; -+ pr "#include \"guestfs.h\"\n"; -+ pr "#include \"guestfs-internal-frontend.h\"\n"; -+ -+ List.iter ( -+ fun arch -> -+ let firmware = -+ List.filter (fun (arch', _, _, _, _) -> arch = arch') firmware in -+ pr "\n"; -+ pr "struct uefi_firmware\n"; -+ pr "guestfs_int_uefi_%s_firmware[] = {\n" arch; -+ List.iter ( -+ fun (_, code, code_debug, vars, flags) -> -+ assert (flags = []); -+ pr " { \"%s\",\n" (c_quote code); -+ (match code_debug with -+ | None -> pr " NULL,\n" -+ | Some code_debug -> pr " \"%s\",\n" (c_quote code_debug) -+ ); -+ pr " \"%s\",\n" (c_quote vars); -+ pr " 0\n"; -+ pr " },\n"; -+ ) firmware; -+ pr "};\n"; -+ ) arches -+ -+let generate_uefi_ml () = -+ generate_header OCamlStyle GPLv2plus; -+ -+ pr "\ -+type uefi_firmware = { -+ code : string; -+ code_debug : string option; -+ vars : string; -+ flags : unit list; -+} -+"; -+ List.iter ( -+ fun arch -> -+ let firmware = -+ List.filter (fun (arch', _, _, _, _) -> arch = arch') firmware in -+ pr "\n"; -+ pr "let uefi_%s_firmware = [\n" arch; -+ List.iter ( -+ fun (_, code, code_debug, vars, flags) -> -+ assert (flags = []); -+ pr " { code = %S;\n" code; -+ (match code_debug with -+ | None -> pr " code_debug = None;\n" -+ | Some code_debug -> pr " code_debug = Some %S;\n" code_debug -+ ); -+ pr " vars = %S;\n" vars; -+ pr " flags = [];\n"; -+ pr " };\n"; -+ ) firmware; -+ pr "]\n"; -+ ) arches -+ -+let generate_uefi_mli () = -+ generate_header OCamlStyle GPLv2plus; -+ -+ pr "\ -+(** UEFI paths. *) -+ -+type uefi_firmware = { -+ code : string; (** code file *) -+ code_debug : string option; (** code debug file *) -+ vars : string; (** vars template file *) -+ flags : unit list; (** flags *) -+} -+ -+"; -+ -+ List.iter (pr "val uefi_%s_firmware : uefi_firmware list\n") arches -diff --git a/generator/uefi.mli b/generator/uefi.mli -new file mode 100644 -index 0000000..64aa1f8 ---- /dev/null -+++ b/generator/uefi.mli -@@ -0,0 +1,21 @@ -+(* libguestfs -+ * Copyright (C) 2016 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 -+ *) -+ -+val generate_uefi_c : unit -> unit -+val generate_uefi_ml : unit -> unit -+val generate_uefi_mli : unit -> unit -diff --git a/generator/utils.ml b/generator/utils.ml -index 6fb04dc..fdb2b9b 100644 ---- a/generator/utils.ml -+++ b/generator/utils.ml -@@ -231,6 +231,22 @@ let mapi f xs = - in - loop 0 xs - -+let uniq ?(cmp = Pervasives.compare) xs = -+ let rec loop acc = function -+ | [] -> acc -+ | [x] -> x :: acc -+ | x :: (y :: _ as xs) when cmp x y = 0 -> -+ loop acc xs -+ | x :: (y :: _ as xs) -> -+ loop (x :: acc) xs -+ in -+ List.rev (loop [] xs) -+ -+let sort_uniq ?(cmp = Pervasives.compare) xs = -+ let xs = List.sort cmp xs in -+ let xs = uniq ~cmp xs in -+ xs -+ - let count_chars c str = - let count = ref 0 in - for i = 0 to String.length str - 1 do -diff --git a/generator/utils.mli b/generator/utils.mli -index 41dd47d..a69328f 100644 ---- a/generator/utils.mli -+++ b/generator/utils.mli -@@ -84,6 +84,12 @@ val iteri : (int -> 'a -> unit) -> 'a list -> unit - - val mapi : (int -> 'a -> 'b) -> 'a list -> 'b list - -+val uniq : ?cmp:('a -> 'a -> int) -> 'a list -> 'a list -+(** Uniquify a list (the list must be sorted first). *) -+ -+val sort_uniq : ?cmp:('a -> 'a -> int) -> 'a list -> 'a list -+(** Sort and uniquify a list. *) -+ - val count_chars : char -> string -> int - (** Count number of times the character occurs in string. *) - -diff --git a/po/POTFILES b/po/POTFILES -index 756fc5e..a45744b 100644 ---- a/po/POTFILES -+++ b/po/POTFILES -@@ -357,6 +357,7 @@ src/structs-copy.c - src/structs-free.c - src/structs-print.c - src/tmpdirs.c -+src/uefi.c - src/umask.c - src/unit-tests.c - src/utils.c -diff --git a/po/POTFILES-ml b/po/POTFILES-ml -index 8b1cad7..0c6cfe5 100644 ---- a/po/POTFILES-ml -+++ b/po/POTFILES-ml -@@ -129,6 +129,7 @@ v2v/output_vdsm.ml - v2v/target_bus_assignment.ml - v2v/test-harness/v2v_test_harness.ml - v2v/types.ml -+v2v/uefi.ml - v2v/utils.ml - v2v/v2v.ml - v2v/v2v_unit_tests.ml -diff --git a/src/Makefile.am b/src/Makefile.am -index ab36329..e4fc5b6 100644 ---- a/src/Makefile.am -+++ b/src/Makefile.am -@@ -232,6 +232,7 @@ libutils_la_SOURCES = \ - structs-cleanup.c \ - structs-print.c \ - structs-print.h \ -+ uefi.c \ - utils.c - libutils_la_CPPFLAGS = $(libguestfs_la_CPPFLAGS) - libutils_la_CFLAGS = $(libguestfs_la_CFLAGS) -diff --git a/src/appliance.c b/src/appliance.c -index 1687a93..6409cfb 100644 ---- a/src/appliance.c -+++ b/src/appliance.c -@@ -435,9 +435,10 @@ guestfs_int_get_uefi (guestfs_h *g, char **code, char **vars) - #ifdef __aarch64__ - size_t i; - -- for (i = 0; guestfs_int_aavmf_firmware[i] != NULL; i += 2) { -- const char *codefile = guestfs_int_aavmf_firmware[i]; -- const char *varsfile = guestfs_int_aavmf_firmware[i+1]; -+ for (i = 0; guestfs_int_aavmf_firmware[i].code != NULL; ++i) { -+ const char *codefile = guestfs_int_aavmf_firmware[i].code; -+ const char *code_debug_file = guestfs_int_aavmf_firmware[i].code_debug; -+ const char *varsfile = guestfs_int_aavmf_firmware[i].vars; - - if (access (codefile, R_OK) == 0 && access (varsfile, R_OK) == 0) { - CLEANUP_CMD_CLOSE struct command *copycmd = guestfs_int_new_command (g); -@@ -458,6 +459,12 @@ guestfs_int_get_uefi (guestfs_h *g, char **code, char **vars) - return -1; - } - -+ /* If debugging is enabled and we can find the code file with -+ * debugging enabled, use that instead. -+ */ -+ if (g->verbose && access (code_debug_file, R_OK) == 0) -+ codefile = code_debug_file; -+ - /* Caller frees. */ - *code = safe_strdup (g, codefile); - *vars = varst; -diff --git a/src/guestfs-internal-frontend.h b/src/guestfs-internal-frontend.h -index ed9165a..1dba172 100644 ---- a/src/guestfs-internal-frontend.h -+++ b/src/guestfs-internal-frontend.h -@@ -110,9 +110,6 @@ extern int guestfs_int_random_string (char *ret, size_t len); - extern char *guestfs_int_drive_name (size_t index, char *ret); - extern ssize_t guestfs_int_drive_index (const char *); - extern int guestfs_int_is_true (const char *str); --extern const char *guestfs_int_ovmf_i386_firmware[]; --extern const char *guestfs_int_ovmf_x86_64_firmware[]; --extern const char *guestfs_int_aavmf_firmware[]; - //extern void guestfs_int_fadvise_normal (int fd); - extern void guestfs_int_fadvise_sequential (int fd); - extern void guestfs_int_fadvise_random (int fd); -@@ -121,6 +118,17 @@ extern void guestfs_int_fadvise_noreuse (int fd); - //extern void guestfs_int_fadvise_willneed (int fd); - extern char *guestfs_int_shell_unquote (const char *str); - -+/* uefi.c */ -+struct uefi_firmware { -+ const char *code; /* code file (NULL = end of list) */ -+ const char *code_debug; /* code file with debugging msgs (may be NULL)*/ -+ const char *vars; /* vars template file */ -+ int flags; /* flags */ -+}; -+extern struct uefi_firmware guestfs_int_ovmf_i386_firmware[]; -+extern struct uefi_firmware guestfs_int_ovmf_x86_64_firmware[]; -+extern struct uefi_firmware guestfs_int_aavmf_firmware[]; -+ - /* These functions are used internally by the CLEANUP_* macros. - * Don't call them directly. - */ -diff --git a/src/utils.c b/src/utils.c -index 8ffc1ed..ab18f52 100644 ---- a/src/utils.c -+++ b/src/utils.c -@@ -321,28 +321,6 @@ guestfs_int_is_true (const char *str) - return -1; - } - --/* See src/appliance.c:guestfs_int_get_uefi. */ --const char * --guestfs_int_ovmf_i386_firmware[] = { -- NULL --}; -- --const char * --guestfs_int_ovmf_x86_64_firmware[] = { -- "/usr/share/OVMF/OVMF_CODE.fd", -- "/usr/share/OVMF/OVMF_VARS.fd", -- -- NULL --}; -- --const char * --guestfs_int_aavmf_firmware[] = { -- "/usr/share/AAVMF/AAVMF_CODE.fd", -- "/usr/share/AAVMF/AAVMF_VARS.fd", -- -- NULL --}; -- - #if 0 /* not used yet */ - /** - * Hint that we will read or write the file descriptor normally. -diff --git a/v2v/Makefile.am b/v2v/Makefile.am -index 0486cfe..c1ebb17 100644 ---- a/v2v/Makefile.am -+++ b/v2v/Makefile.am -@@ -72,6 +72,7 @@ SOURCES_MLI = \ - OVF.mli \ - target_bus_assignment.mli \ - types.mli \ -+ uefi.mli \ - utils.mli \ - vCenter.mli \ - windows.mli \ -@@ -81,6 +82,7 @@ SOURCES_MLI = \ - SOURCES_ML = \ - types.ml \ - xml.ml \ -+ uefi.ml \ - utils.ml \ - vCenter.ml \ - domainxml.ml \ -@@ -219,6 +221,7 @@ COPY_TO_LOCAL_BOBJECTS = \ - $(top_builddir)/mllib/StatVFS.cmo \ - $(top_builddir)/mllib/curl.cmo \ - xml.cmo \ -+ uefi.cmo \ - utils.cmo \ - vCenter.cmo \ - domainxml.cmo \ -@@ -380,6 +383,7 @@ v2v_unit_tests_BOBJECTS = \ - $(top_builddir)/mllib/regedit.cmo \ - types.cmo \ - xml.cmo \ -+ uefi.cmo \ - utils.cmo \ - DOM.cmo \ - OVF.cmo \ -diff --git a/v2v/output_libvirt.ml b/v2v/output_libvirt.ml -index 5a404ee..df0963e 100644 ---- a/v2v/output_libvirt.ml -+++ b/v2v/output_libvirt.ml -@@ -118,7 +118,8 @@ let create_libvirt_xml ?pool source target_buses guestcaps - * (https://bugzilla.redhat.com/show_bug.cgi?id=1217444#c6) but - * until that day we have to use a bunch of heuristics. XXX - *) -- let code, vars_template = find_uefi_firmware guestcaps.gcaps_arch in -+ let { Uefi.code = code; vars = vars_template } = -+ find_uefi_firmware guestcaps.gcaps_arch in - [ e "loader" ["readonly", "yes"; "type", "pflash"] [ PCData code ]; - e "nvram" ["template", vars_template] [] ] in - -diff --git a/v2v/output_qemu.ml b/v2v/output_qemu.ml -index 94f80c2..2a944d7 100644 ---- a/v2v/output_qemu.ml -+++ b/v2v/output_qemu.ml -@@ -69,7 +69,7 @@ object - - (match uefi_firmware with - | None -> () -- | Some (_, vars_template) -> -+ | Some { Uefi.vars = vars_template } -> - fpf "# Make a copy of the UEFI variables template\n"; - fpf "uefi_vars=\"$(mktemp)\"\n"; - fpf "cp %s \"$uefi_vars\"\n" (quote vars_template); -@@ -83,7 +83,7 @@ object - - (match uefi_firmware with - | None -> () -- | Some (code, _) -> -+ | Some { Uefi.code = code } -> - fpf "%s-drive if=pflash,format=raw,file=%s,readonly" nl (quote code); - fpf "%s-drive if=pflash,format=raw,file=\"$uefi_vars\"" nl - ); -diff --git a/v2v/utils-c.c b/v2v/utils-c.c -index 77de321..af74c12 100644 ---- a/v2v/utils-c.c -+++ b/v2v/utils-c.c -@@ -66,51 +66,6 @@ v2v_utils_drive_index (value strv) - CAMLreturn (Val_int (r)); - } - --static value --get_firmware (char **firmware) --{ -- CAMLparam0 (); -- CAMLlocal5 (rv, v, v1, v2, cons); -- size_t i, len; -- -- rv = Val_int (0); -- -- /* Build the list backwards so we don't have to reverse it at the end. */ -- len = guestfs_int_count_strings (firmware); -- -- for (i = len; i > 0; i -= 2) { -- v1 = caml_copy_string (firmware[i-2]); -- v2 = caml_copy_string (firmware[i-1]); -- v = caml_alloc (2, 0); -- Store_field (v, 0, v1); -- Store_field (v, 1, v2); -- cons = caml_alloc (2, 0); -- Store_field (cons, 1, rv); -- rv = cons; -- Store_field (cons, 0, v); -- } -- -- CAMLreturn (rv); --} -- --value --v2v_utils_ovmf_i386_firmware (value unitv) --{ -- return get_firmware ((char **) guestfs_int_ovmf_i386_firmware); --} -- --value --v2v_utils_ovmf_x86_64_firmware (value unitv) --{ -- return get_firmware ((char **) guestfs_int_ovmf_x86_64_firmware); --} -- --value --v2v_utils_aavmf_firmware (value unitv) --{ -- return get_firmware ((char **) guestfs_int_aavmf_firmware); --} -- - value - v2v_utils_shell_unquote (value strv) - { -diff --git a/v2v/utils.ml b/v2v/utils.ml -index d88f8ad..e7aef79 100644 ---- a/v2v/utils.ml -+++ b/v2v/utils.ml -@@ -82,25 +82,20 @@ let qemu_supports_sound_card = function - | Types.USBAudio - -> false - --external ovmf_i386_firmware : unit -> (string * string) list = "v2v_utils_ovmf_i386_firmware" --external ovmf_x86_64_firmware : unit -> (string * string) list = "v2v_utils_ovmf_x86_64_firmware" --external aavmf_firmware : unit -> (string * string) list = "v2v_utils_aavmf_firmware" -- - (* Find the UEFI firmware. *) - let find_uefi_firmware guest_arch = - let files = - (* The lists of firmware are actually defined in src/utils.c. *) - match guest_arch with -- | "i386" | "i486" | "i586" | "i686" -> ovmf_i386_firmware () -- | "x86_64" -> ovmf_x86_64_firmware () -- | "aarch64" -> aavmf_firmware () -+ | "x86_64" -> Uefi.uefi_x86_64_firmware -+ | "aarch64" -> Uefi.uefi_aarch64_firmware - | arch -> - error (f_"don't know how to convert UEFI guests for architecture %s") - guest_arch in - let rec loop = function - | [] -> - error (f_"cannot find firmware for UEFI guests.\n\nYou probably need to install OVMF, or AAVMF (if using aarch64)") -- | ((code, vars_template) as ret) :: rest -> -+ | ({ Uefi.code = code; vars = vars_template } as ret) :: rest -> - if Sys.file_exists code && Sys.file_exists vars_template then ret - else loop rest - in -diff --git a/v2v/utils.mli b/v2v/utils.mli -index 4daf38c..bdabab4 100644 ---- a/v2v/utils.mli -+++ b/v2v/utils.mli -@@ -43,10 +43,9 @@ val kvm_arch : string -> string - val qemu_supports_sound_card : Types.source_sound_model -> bool - (** Does qemu support the given sound card? *) - --val find_uefi_firmware : string -> string * string --(** Find the UEFI firmware for the guest architecture. Returns a -- pair [(code_file, vars_file)]. This cannot return an error, it -- calls [error] and fails instead. *) -+val find_uefi_firmware : string -> Uefi.uefi_firmware -+(** Find the UEFI firmware for the guest architecture. -+ This cannot return an error, it calls [error] and fails instead. *) - - val compare_app2_versions : Guestfs.application2 -> Guestfs.application2 -> int - (** Compare two app versions. *) --- -1.8.3.1 - diff --git a/SOURCES/0175-v2v-Use-OVMF-secure-boot-file-RHBZ-1367615.patch b/SOURCES/0175-v2v-Use-OVMF-secure-boot-file-RHBZ-1367615.patch deleted file mode 100644 index 5692f92..0000000 --- a/SOURCES/0175-v2v-Use-OVMF-secure-boot-file-RHBZ-1367615.patch +++ /dev/null @@ -1,362 +0,0 @@ -From 263e0ff554c4c68962fb689dec541dabf5cc71c9 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Wed, 17 Aug 2016 14:27:24 +0100 -Subject: [PATCH] v2v: Use OVMF secure boot file (RHBZ#1367615). - -From RHEL 7.3, Red Hat have decided to only compile the secure boot -version of OVMF on x86-64, with flags -D SECURE_BOOT_ENABLE -D SMM_REQUIRE. - -The filename has also changed to reflect this - it is now -/usr/share/OVMF/OVMF_CODE.secboot.fd. The old file -/usr/share/OVMF/OVMF_CODE.fd is no longer shipped. - -However switching to using this variant of OVMF for UEFI guests is not -just a matter of changing the filename. The new OVMF variant won't -run unless we also change: - - - The qemu machine model, from the default ("pc" == - "pc-i440fx-rhel7.3.0" or later) to Q35 ("q35" == "pc-q35-rhel7.3.0" - or later). - - - Add under . - - - Set . - -NB: On RHEL the changes requires qemu-kvm-rhev. It is no longer -possible to convert UEFI guests using the basic qemu-kvm. - -Thanks: Laszlo Ersek, Ming Xie. -(cherry picked from commit ba5c5a8713c4418c861edecacff761f4d3720508) ---- - generator/uefi.ml | 24 ++++++++++++++++++------ - src/appliance.c | 6 ++++-- - src/guestfs-internal-frontend.h | 3 ++- - src/guestfs-internal.h | 2 +- - src/launch-direct.c | 15 ++++++++++++++- - src/launch-libvirt.c | 16 +++++++++++++++- - v2v/output_libvirt.ml | 40 +++++++++++++++++++++++++++++----------- - v2v/output_qemu.ml | 13 ++++++++++--- - v2v/virt-v2v.pod | 2 ++ - 9 files changed, 95 insertions(+), 26 deletions(-) - -diff --git a/generator/uefi.ml b/generator/uefi.ml -index 3b371b8..661c1d7 100644 ---- a/generator/uefi.ml -+++ b/generator/uefi.ml -@@ -35,6 +35,16 @@ let firmware = [ - "/usr/share/OVMF/OVMF_VARS.fd", - []; - -+ (* From RHEL 7.3, only secure boot variants of UEFI are shipped. -+ * This requires additional qemu options, see RHBZ#1367615 for -+ * details. -+ *) -+ "x86_64", -+ "/usr/share/OVMF/OVMF_CODE.secboot.fd", -+ None, -+ "/usr/share/OVMF/OVMF_VARS.fd", -+ [ "UEFI_FLAG_SECURE_BOOT_REQUIRED" ]; -+ - "aarch64", - "/usr/share/AAVMF/AAVMF_CODE.fd", - None, -@@ -63,14 +73,13 @@ let generate_uefi_c () = - pr "guestfs_int_uefi_%s_firmware[] = {\n" arch; - List.iter ( - fun (_, code, code_debug, vars, flags) -> -- assert (flags = []); - pr " { \"%s\",\n" (c_quote code); - (match code_debug with - | None -> pr " NULL,\n" - | Some code_debug -> pr " \"%s\",\n" (c_quote code_debug) - ); - pr " \"%s\",\n" (c_quote vars); -- pr " 0\n"; -+ pr " %s\n" (if flags <> [] then String.concat "|" flags else "0"); - pr " },\n"; - ) firmware; - pr "};\n"; -@@ -84,8 +93,10 @@ type uefi_firmware = { - code : string; - code_debug : string option; - vars : string; -- flags : unit list; -+ flags : uefi_flags; - } -+and uefi_flags = uefi_flag list -+and uefi_flag = UEFI_FLAG_SECURE_BOOT_REQUIRED - "; - List.iter ( - fun arch -> -@@ -95,14 +106,13 @@ type uefi_firmware = { - pr "let uefi_%s_firmware = [\n" arch; - List.iter ( - fun (_, code, code_debug, vars, flags) -> -- assert (flags = []); - pr " { code = %S;\n" code; - (match code_debug with - | None -> pr " code_debug = None;\n" - | Some code_debug -> pr " code_debug = Some %S;\n" code_debug - ); - pr " vars = %S;\n" vars; -- pr " flags = [];\n"; -+ pr " flags = [%s];\n" (String.concat "; " flags); - pr " };\n"; - ) firmware; - pr "]\n"; -@@ -118,8 +128,10 @@ type uefi_firmware = { - code : string; (** code file *) - code_debug : string option; (** code debug file *) - vars : string; (** vars template file *) -- flags : unit list; (** flags *) -+ flags : uefi_flags; (** flags *) - } -+and uefi_flags = uefi_flag list -+and uefi_flag = UEFI_FLAG_SECURE_BOOT_REQUIRED - - "; - -diff --git a/src/appliance.c b/src/appliance.c -index 6409cfb..a3af164 100644 ---- a/src/appliance.c -+++ b/src/appliance.c -@@ -427,10 +427,10 @@ dir_contains_files (const char *dir, ...) - * cause appliance building to fail (no UEFI firmware is not an - * error). - * -- * XXX See also v2v/utils.ml:find_uefi_firmware -+ * See also v2v/utils.ml:find_uefi_firmware - */ - int --guestfs_int_get_uefi (guestfs_h *g, char **code, char **vars) -+guestfs_int_get_uefi (guestfs_h *g, char **code, char **vars, int *flags) - { - #ifdef __aarch64__ - size_t i; -@@ -468,6 +468,7 @@ guestfs_int_get_uefi (guestfs_h *g, char **code, char **vars) - /* Caller frees. */ - *code = safe_strdup (g, codefile); - *vars = varst; -+ *flags = guestfs_int_aavmf_firmware[i].flags; - return 0; - } - } -@@ -475,5 +476,6 @@ guestfs_int_get_uefi (guestfs_h *g, char **code, char **vars) - - /* Not found. */ - *code = *vars = NULL; -+ *flags = 0; - return 0; - } -diff --git a/src/guestfs-internal-frontend.h b/src/guestfs-internal-frontend.h -index 1dba172..ebf8063 100644 ---- a/src/guestfs-internal-frontend.h -+++ b/src/guestfs-internal-frontend.h -@@ -123,7 +123,8 @@ struct uefi_firmware { - const char *code; /* code file (NULL = end of list) */ - const char *code_debug; /* code file with debugging msgs (may be NULL)*/ - const char *vars; /* vars template file */ -- int flags; /* flags */ -+ int flags; /* various flags, see below */ -+#define UEFI_FLAG_SECURE_BOOT_REQUIRED 1 /* secure boot (see RHBZ#1367615) */ - }; - extern struct uefi_firmware guestfs_int_ovmf_i386_firmware[]; - extern struct uefi_firmware guestfs_int_ovmf_x86_64_firmware[]; -diff --git a/src/guestfs-internal.h b/src/guestfs-internal.h -index 44dae32..2002253 100644 ---- a/src/guestfs-internal.h -+++ b/src/guestfs-internal.h -@@ -756,7 +756,7 @@ extern const char *guestfs_int_drive_protocol_to_string (enum drive_protocol pro - - /* appliance.c */ - extern int guestfs_int_build_appliance (guestfs_h *g, char **kernel, char **dtb, char **initrd, char **appliance); --extern int guestfs_int_get_uefi (guestfs_h *g, char **code, char **vars); -+extern int guestfs_int_get_uefi (guestfs_h *g, char **code, char **vars, int *flags); - - /* launch.c */ - extern int64_t guestfs_int_timeval_diff (const struct timeval *x, const struct timeval *y); -diff --git a/src/launch-direct.c b/src/launch-direct.c -index 1081445..426bb60 100644 ---- a/src/launch-direct.c -+++ b/src/launch-direct.c -@@ -242,6 +242,7 @@ launch_direct (guestfs_h *g, void *datav, const char *arg) - CLEANUP_FREE char *uefi_code = NULL, *uefi_vars = NULL; - CLEANUP_FREE char *kernel = NULL, *dtb = NULL, - *initrd = NULL, *appliance = NULL; -+ int uefi_flags; - int has_appliance_drive; - CLEANUP_FREE char *appliance_dev = NULL; - uint32_t size; -@@ -434,8 +435,20 @@ launch_direct (guestfs_h *g, void *datav, const char *arg) - } - - /* UEFI (firmware) if required. */ -- if (guestfs_int_get_uefi (g, &uefi_code, &uefi_vars) == -1) -+ if (guestfs_int_get_uefi (g, &uefi_code, &uefi_vars, &uefi_flags) == -1) - goto cleanup0; -+ if (uefi_flags & UEFI_FLAG_SECURE_BOOT_REQUIRED) { -+ /* Implementing this requires changes to the qemu command line. -+ * See RHBZ#1367615 for details. As the guestfs_int_get_uefi -+ * function is only implemented for aarch64, and UEFI secure boot -+ * is some way off on aarch64 (2017/2018), we only need to worry -+ * about this later. -+ */ -+ error (g, "internal error: direct backend " -+ "does not implement UEFI secure boot, " -+ "see comments in the code"); -+ goto cleanup0; -+ } - if (uefi_code) { - ADD_CMDLINE ("-drive"); - ADD_CMDLINE_PRINTF ("if=pflash,format=raw,file=%s,readonly", uefi_code); -diff --git a/src/launch-libvirt.c b/src/launch-libvirt.c -index 4c29409..505f3f0 100644 ---- a/src/launch-libvirt.c -+++ b/src/launch-libvirt.c -@@ -312,6 +312,7 @@ launch_libvirt (guestfs_h *g, void *datav, const char *libvirt_uri) - int r; - uint32_t size; - CLEANUP_FREE void *buf = NULL; -+ int uefi_flags; - - params.current_proc_is_root = geteuid () == 0; - -@@ -404,8 +405,21 @@ launch_libvirt (guestfs_h *g, void *datav, const char *libvirt_uri) - goto cleanup; - - /* UEFI code and variables, on architectures where that is required. */ -- if (guestfs_int_get_uefi (g, &data->uefi_code, &data->uefi_vars) == -1) -+ if (guestfs_int_get_uefi (g, &data->uefi_code, &data->uefi_vars, -+ &uefi_flags) == -1) - goto cleanup; -+ if (uefi_flags & UEFI_FLAG_SECURE_BOOT_REQUIRED) { -+ /* Implementing this requires changes to the libvirt XML. See -+ * RHBZ#1367615 for details. As the guestfs_int_get_uefi function -+ * is only implemented for aarch64, and UEFI secure boot is some -+ * way off on aarch64 (2017/2018), we only need to worry about -+ * this later. -+ */ -+ error (g, "internal error: libvirt backend " -+ "does not implement UEFI secure boot, " -+ "see comments in the code"); -+ goto cleanup; -+ } - - /* Misc backend settings. */ - guestfs_push_error_handler (g, NULL, NULL); -diff --git a/v2v/output_libvirt.ml b/v2v/output_libvirt.ml -index df0963e..ed430a2 100644 ---- a/v2v/output_libvirt.ml -+++ b/v2v/output_libvirt.ml -@@ -71,6 +71,16 @@ let target_features_of_capabilities_doc doc arch = - - let create_libvirt_xml ?pool source target_buses guestcaps - target_features target_firmware = -+ let uefi_firmware = -+ match target_firmware with -+ | TargetBIOS -> None -+ | TargetUEFI -> Some (find_uefi_firmware guestcaps.gcaps_arch) in -+ let secure_boot_required = -+ match uefi_firmware with -+ | Some { Uefi.flags = flags } -+ when List.mem Uefi.UEFI_FLAG_SECURE_BOOT_REQUIRED flags -> true -+ | _ -> false in -+ - let memory_k = source.s_memory /^ 1024L in - - (* We have the machine features of the guest when it was on the -@@ -106,24 +116,32 @@ let create_libvirt_xml ?pool source target_buses guestcaps - StringSet.inter(*section*) force_features target_features in - let features = StringSet.union features force_features in - -+ (* Add feature if UEFI requires it. Note that libvirt -+ * capabilities doesn't list this feature even if it is supported -+ * by qemu, so we have to blindly add it, which might cause libvirt -+ * to fail. (XXX) -+ *) -+ let features = -+ if secure_boot_required then StringSet.add "smm" features else features in -+ - let features = List.sort compare (StringSet.elements features) in - - (* The section subelements. *) - let os_section = -+ let machine = if secure_boot_required then [ "machine", "q35" ] else [] in -+ - let loader = -- match target_firmware with -- | TargetBIOS -> [] -- | TargetUEFI -> -- (* danpb is proposing that libvirt supports , -- * (https://bugzilla.redhat.com/show_bug.cgi?id=1217444#c6) but -- * until that day we have to use a bunch of heuristics. XXX -- *) -- let { Uefi.code = code; vars = vars_template } = -- find_uefi_firmware guestcaps.gcaps_arch in -- [ e "loader" ["readonly", "yes"; "type", "pflash"] [ PCData code ]; -+ match uefi_firmware with -+ | None -> [] -+ | Some { Uefi.code = code; vars = vars_template } -> -+ let secure = -+ if secure_boot_required then [ "secure", "yes" ] else [] in -+ [ e "loader" (["readonly", "yes"; "type", "pflash"] @ secure) -+ [ PCData code ]; - e "nvram" ["template", vars_template] [] ] in - -- (e "type" ["arch", guestcaps.gcaps_arch] [PCData "hvm"]) :: loader in -+ (e "type" (["arch", guestcaps.gcaps_arch] @ machine) [PCData "hvm"]) -+ :: loader in - - (* The devices. *) - let devices = ref [] in -diff --git a/v2v/output_qemu.ml b/v2v/output_qemu.ml -index 2a944d7..55620d1 100644 ---- a/v2v/output_qemu.ml -+++ b/v2v/output_qemu.ml -@@ -57,8 +57,12 @@ object - let uefi_firmware = - match target_firmware with - | TargetBIOS -> None -- | TargetUEFI -> -- Some (find_uefi_firmware guestcaps.gcaps_arch) in -+ | TargetUEFI -> Some (find_uefi_firmware guestcaps.gcaps_arch) in -+ let secure_boot_required = -+ match uefi_firmware with -+ | Some { Uefi.flags = flags } -+ when List.mem Uefi.UEFI_FLAG_SECURE_BOOT_REQUIRED flags -> true -+ | _ -> false in - - let chan = open_out file in - -@@ -79,11 +83,14 @@ object - fpf "/usr/libexec/qemu-kvm"; - fpf "%s-no-user-config -nodefaults" nl; - fpf "%s-name %s" nl (quote source.s_name); -- fpf "%s-machine accel=kvm:tcg" nl; -+ fpf "%s-machine %saccel=kvm:tcg" nl -+ (if secure_boot_required then "q35,smm=on," else ""); - - (match uefi_firmware with - | None -> () - | Some { Uefi.code = code } -> -+ if secure_boot_required then -+ fpf "%s-global driver=cfi.pflash01,property=secure,value=on" nl; - fpf "%s-drive if=pflash,format=raw,file=%s,readonly" nl (quote code); - fpf "%s-drive if=pflash,format=raw,file=\"$uefi_vars\"" nl - ); -diff --git a/v2v/virt-v2v.pod b/v2v/virt-v2v.pod -index 3e24025..32085c1 100644 ---- a/v2v/virt-v2v.pod -+++ b/v2v/virt-v2v.pod -@@ -783,6 +783,8 @@ automatically, but note that the same version of OVMF must be - installed on the conversion host as is installed on the target - hypervisor, else you will have to adjust paths in the metadata. - -+On RHEL E 7.3, only qemu-kvm-rhev (not qemu-kvm) is supported. -+ - =item UEFI on OpenStack - - Not supported. --- -1.8.3.1 - diff --git a/SOURCES/0176-aarch64-uefi-Fix-the-build-on-aarch64.patch b/SOURCES/0176-aarch64-uefi-Fix-the-build-on-aarch64.patch deleted file mode 100644 index 4d9fee0..0000000 --- a/SOURCES/0176-aarch64-uefi-Fix-the-build-on-aarch64.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 0e2785dda84709d9be80be85e4d551b1d8a26616 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Thu, 18 Aug 2016 16:13:12 +0100 -Subject: [PATCH] aarch64: uefi: Fix the build on aarch64. - -Fixes commit 0c396650b0018dc3fcd7ca809202ad46ae2c327d. - -(cherry picked from commit c711b517094375d4c321af4800e747b955643133) ---- - src/appliance.c | 11 ++++++----- - src/guestfs-internal-frontend.h | 6 +++--- - 2 files changed, 9 insertions(+), 8 deletions(-) - -diff --git a/src/appliance.c b/src/appliance.c -index a3af164..19a697b 100644 ---- a/src/appliance.c -+++ b/src/appliance.c -@@ -435,10 +435,11 @@ guestfs_int_get_uefi (guestfs_h *g, char **code, char **vars, int *flags) - #ifdef __aarch64__ - size_t i; - -- for (i = 0; guestfs_int_aavmf_firmware[i].code != NULL; ++i) { -- const char *codefile = guestfs_int_aavmf_firmware[i].code; -- const char *code_debug_file = guestfs_int_aavmf_firmware[i].code_debug; -- const char *varsfile = guestfs_int_aavmf_firmware[i].vars; -+ for (i = 0; guestfs_int_uefi_aarch64_firmware[i].code != NULL; ++i) { -+ const char *codefile = guestfs_int_uefi_aarch64_firmware[i].code; -+ const char *code_debug_file = -+ guestfs_int_uefi_aarch64_firmware[i].code_debug; -+ const char *varsfile = guestfs_int_uefi_aarch64_firmware[i].vars; - - if (access (codefile, R_OK) == 0 && access (varsfile, R_OK) == 0) { - CLEANUP_CMD_CLOSE struct command *copycmd = guestfs_int_new_command (g); -@@ -468,7 +469,7 @@ guestfs_int_get_uefi (guestfs_h *g, char **code, char **vars, int *flags) - /* Caller frees. */ - *code = safe_strdup (g, codefile); - *vars = varst; -- *flags = guestfs_int_aavmf_firmware[i].flags; -+ *flags = guestfs_int_uefi_aarch64_firmware[i].flags; - return 0; - } - } -diff --git a/src/guestfs-internal-frontend.h b/src/guestfs-internal-frontend.h -index ebf8063..868122d 100644 ---- a/src/guestfs-internal-frontend.h -+++ b/src/guestfs-internal-frontend.h -@@ -126,9 +126,9 @@ struct uefi_firmware { - int flags; /* various flags, see below */ - #define UEFI_FLAG_SECURE_BOOT_REQUIRED 1 /* secure boot (see RHBZ#1367615) */ - }; --extern struct uefi_firmware guestfs_int_ovmf_i386_firmware[]; --extern struct uefi_firmware guestfs_int_ovmf_x86_64_firmware[]; --extern struct uefi_firmware guestfs_int_aavmf_firmware[]; -+extern struct uefi_firmware guestfs_int_uefi_i386_firmware[]; -+extern struct uefi_firmware guestfs_int_uefi_x86_64_firmware[]; -+extern struct uefi_firmware guestfs_int_uefi_aarch64_firmware[]; - - /* These functions are used internally by the CLEANUP_* macros. - * Don't call them directly. --- -1.8.3.1 - diff --git a/SOURCES/0177-RHEL-7-p2v-Fix-build-warning.patch b/SOURCES/0177-RHEL-7-p2v-Fix-build-warning.patch deleted file mode 100644 index 9fdad0c..0000000 --- a/SOURCES/0177-RHEL-7-p2v-Fix-build-warning.patch +++ /dev/null @@ -1,24 +0,0 @@ -From dd2c47a7e2fead8fe8c4399def4ffb2d441b1483 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Thu, 18 Aug 2016 11:18:19 -0400 -Subject: [PATCH] RHEL 7: p2v: Fix build warning. - ---- - p2v/kernel.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/p2v/kernel.c b/p2v/kernel.c -index 455af3e..07d0d83 100644 ---- a/p2v/kernel.c -+++ b/p2v/kernel.c -@@ -26,6 +26,7 @@ - #include - #include - #include -+#include - #include - #include - #include --- -1.8.3.1 - diff --git a/SOURCES/0178-lib-Don-t-assert-fail-if-port-is-missing-in-XML-RHBZ.patch b/SOURCES/0178-lib-Don-t-assert-fail-if-port-is-missing-in-XML-RHBZ.patch deleted file mode 100644 index f0e81e8..0000000 --- a/SOURCES/0178-lib-Don-t-assert-fail-if-port-is-missing-in-XML-RHBZ.patch +++ /dev/null @@ -1,46 +0,0 @@ -From ac74238773ad287eaa2bfb7f4b85e71aa12b124e Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Sat, 27 Aug 2016 08:51:29 +0100 -Subject: [PATCH] lib: Don't assert fail if port is missing in XML - (RHBZ#1370424). - -Thanks: Xiaodai Wang -(cherry picked from commit 9e7b564fc1d9fa0e99a46e4739614820812ca42b) ---- - src/libvirt-domain.c | 17 +++++++++++------ - 1 file changed, 11 insertions(+), 6 deletions(-) - -diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c -index b096fb3..7d5da2f 100644 ---- a/src/libvirt-domain.c -+++ b/src/libvirt-domain.c -@@ -604,15 +604,20 @@ for_each_disk (guestfs_h *g, - for (hi = 0; hi < xphost->nodesetval->nodeNr ; hi++) { - xmlChar *name, *port; - xmlNodePtr h = xphost->nodesetval->nodeTab[hi]; -+ int r; - - assert (h); - assert (h->type == XML_ELEMENT_NODE); -- name = xmlGetProp(h, BAD_CAST "name"); -- assert(name); -- port = xmlGetProp(h, BAD_CAST "port"); -- assert (port); -- debug (g, _("disk[%zu]: host: %s:%s"), i, name, port); -- if (asprintf(&server[hi], "%s:%s", name, port) == -1) { -+ name = xmlGetProp (h, BAD_CAST "name"); -+ assert (name); // libvirt checks this -+ port = xmlGetProp (h, BAD_CAST "port"); -+ debug (g, "disk[%zu]: hostname: %s port: %s", -+ i, name, port ? (char *) port : "(not set)"); -+ if (port) -+ r = asprintf (&server[hi], "%s:%s", name, port); -+ else -+ r = asprintf (&server[hi], "%s", name); -+ if (r == -1) { - perrorf (g, "asprintf"); - return -1; - } --- -1.8.3.1 - diff --git a/SOURCES/0179-tests-Add-a-regression-test-for-RHBZ-1370424.patch b/SOURCES/0179-tests-Add-a-regression-test-for-RHBZ-1370424.patch deleted file mode 100644 index 953709e..0000000 --- a/SOURCES/0179-tests-Add-a-regression-test-for-RHBZ-1370424.patch +++ /dev/null @@ -1,123 +0,0 @@ -From c32b1c0b3fe1f2b2e365f6e336c2720f6b15ff81 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Sat, 27 Aug 2016 07:32:49 +0100 -Subject: [PATCH] tests: Add a regression test for RHBZ#1370424. - -Regression test for previous commit which just tests that -guestfs_add_domain doesn't assert-fail on guests with no port -attribute. - -(cherry picked from commit 98aa78f288e44868bcccf56b777d57d9fd4ec6a6) ---- - tests/regressions/Makefile.am | 2 ++ - tests/regressions/rhbz1370424.sh | 42 +++++++++++++++++++++++++++++++++++++++ - tests/regressions/rhbz1370424.xml | 28 ++++++++++++++++++++++++++ - 3 files changed, 72 insertions(+) - create mode 100755 tests/regressions/rhbz1370424.sh - create mode 100644 tests/regressions/rhbz1370424.xml - -diff --git a/tests/regressions/Makefile.am b/tests/regressions/Makefile.am -index 77a5ff5..407c5b0 100644 ---- a/tests/regressions/Makefile.am -+++ b/tests/regressions/Makefile.am -@@ -48,6 +48,7 @@ EXTRA_DIST = \ - rhbz1232192.sh \ - rhbz1232192.xml \ - rhbz1285847.sh \ -+ rhbz1370424.sh \ - test-noexec-stack.pl - - TESTS = \ -@@ -77,6 +78,7 @@ TESTS = \ - rhbz1175196.sh \ - rhbz1232192.sh \ - rhbz1285847.sh \ -+ rhbz1370424.sh \ - test-big-heap \ - test-noexec-stack.pl \ - $(SLOW_TESTS) -diff --git a/tests/regressions/rhbz1370424.sh b/tests/regressions/rhbz1370424.sh -new file mode 100755 -index 0000000..5b21a32 ---- /dev/null -+++ b/tests/regressions/rhbz1370424.sh -@@ -0,0 +1,42 @@ -+#!/bin/bash - -+# libguestfs -+# Copyright (C) 2016 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=1370424 -+# Handle a network disk without a port attribute. -+ -+set -e -+export LANG=C -+ -+if [ -n "$SKIP_TEST_RHBZ1370424_SH" ]; then -+ echo "$0: test skipped because environment variable is set" -+ exit 77 -+fi -+ -+if [ "$(guestfish get-backend)" = "uml" ]; then -+ echo "$0: test skipped because UML backend does not support network" -+ exit 77 -+fi -+ -+guestfish < -+ -+ rhbz1370424 -+ 1048576 -+ 2 -+ -+ hvm -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+
-+ -+ -+ -+ --- -1.8.3.1 - diff --git a/SOURCES/0180-tests-add-rhbz1370424.xml-to-EXTRA_DIST.patch b/SOURCES/0180-tests-add-rhbz1370424.xml-to-EXTRA_DIST.patch deleted file mode 100644 index 7574323..0000000 --- a/SOURCES/0180-tests-add-rhbz1370424.xml-to-EXTRA_DIST.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 6802e1b79c12a043ab36fe577f8819aeac0040b0 Mon Sep 17 00:00:00 2001 -From: Pino Toscano -Date: Mon, 29 Aug 2016 10:18:00 +0200 -Subject: [PATCH] tests: add rhbz1370424.xml to EXTRA_DIST - -Fixes commit 98aa78f288e44868bcccf56b777d57d9fd4ec6a6. - -(cherry picked from commit f14dd26d361d9dd4a8f9278c0d5860db35eb63e3) ---- - tests/regressions/Makefile.am | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/tests/regressions/Makefile.am b/tests/regressions/Makefile.am -index 407c5b0..32bbc83 100644 ---- a/tests/regressions/Makefile.am -+++ b/tests/regressions/Makefile.am -@@ -49,6 +49,7 @@ EXTRA_DIST = \ - rhbz1232192.xml \ - rhbz1285847.sh \ - rhbz1370424.sh \ -+ rhbz1370424.xml \ - test-noexec-stack.pl - - TESTS = \ --- -1.8.3.1 - diff --git a/SOURCES/0181-inspect-change-is_root-flag-into-enum.patch b/SOURCES/0181-inspect-change-is_root-flag-into-enum.patch deleted file mode 100644 index fdc8e31..0000000 --- a/SOURCES/0181-inspect-change-is_root-flag-into-enum.patch +++ /dev/null @@ -1,210 +0,0 @@ -From a8532145296a97ffe1df63f9be91c88b63cbf603 Mon Sep 17 00:00:00 2001 -From: Pino Toscano -Date: Mon, 5 Dec 2016 16:10:20 +0100 -Subject: [PATCH] inspect: change is_root flag into enum - -Introduce a new enum to classify the role of a filesystem, if available. -This will help later on when doing operations on non-root filesystems, -like detecting particular mountpoints such as /usr. - -The new enum has only "root" as known role, which replaces the is_root -flag. - -(cherry picked from commit 0c4edcecbaa82be2251d296e524e3bb50840ba9e) ---- - src/guestfs-internal.h | 7 ++++++- - src/inspect-fs-cd.c | 2 +- - src/inspect-fs.c | 20 ++++++++++---------- - src/inspect.c | 17 +++++++++-------- - 4 files changed, 26 insertions(+), 20 deletions(-) - -diff --git a/src/guestfs-internal.h b/src/guestfs-internal.h -index 2002253..6f31438 100644 ---- a/src/guestfs-internal.h -+++ b/src/guestfs-internal.h -@@ -594,8 +594,13 @@ enum inspect_os_package_management { - OS_PACKAGE_MANAGEMENT_APK, - }; - -+enum inspect_os_role { -+ OS_ROLE_UNKNOWN = 0, -+ OS_ROLE_ROOT, -+}; -+ - struct inspect_fs { -- int is_root; -+ enum inspect_os_role role; - char *mountable; - enum inspect_os_type type; - enum inspect_os_distro distro; -diff --git a/src/inspect-fs-cd.c b/src/inspect-fs-cd.c -index 09974b5..ab6ee4e 100644 ---- a/src/inspect-fs-cd.c -+++ b/src/inspect-fs-cd.c -@@ -525,7 +525,7 @@ guestfs_int_check_installer_iso (guestfs_h *g, struct inspect_fs *fs, - - /* Otherwise we matched an ISO, so fill in the fs fields. */ - fs->mountable = safe_strdup (g, device); -- fs->is_root = 1; -+ fs->role = OS_ROLE_ROOT; - if (osinfo->is_installer) - fs->format = OS_FORMAT_INSTALLER; - fs->type = osinfo->type; -diff --git a/src/inspect-fs.c b/src/inspect-fs.c -index 87609ab..58f08b8 100644 ---- a/src/inspect-fs.c -+++ b/src/inspect-fs.c -@@ -166,7 +166,7 @@ check_filesystem (guestfs_h *g, const char *mountable, - is_dir_bin && - guestfs_is_file (g, "/etc/freebsd-update.conf") > 0 && - guestfs_is_file (g, "/etc/fstab") > 0) { -- fs->is_root = 1; -+ fs->role = OS_ROLE_ROOT; - fs->format = OS_FORMAT_INSTALLED; - if (guestfs_int_check_freebsd_root (g, fs) == -1) - return -1; -@@ -177,7 +177,7 @@ check_filesystem (guestfs_h *g, const char *mountable, - guestfs_is_file (g, "/netbsd") > 0 && - guestfs_is_file (g, "/etc/fstab") > 0 && - guestfs_is_file (g, "/etc/release") > 0) { -- fs->is_root = 1; -+ fs->role = OS_ROLE_ROOT; - fs->format = OS_FORMAT_INSTALLED; - if (guestfs_int_check_netbsd_root (g, fs) == -1) - return -1; -@@ -188,7 +188,7 @@ check_filesystem (guestfs_h *g, const char *mountable, - guestfs_is_file (g, "/bsd") > 0 && - guestfs_is_file (g, "/etc/fstab") > 0 && - guestfs_is_file (g, "/etc/motd") > 0) { -- fs->is_root = 1; -+ fs->role = OS_ROLE_ROOT; - fs->format = OS_FORMAT_INSTALLED; - if (guestfs_int_check_openbsd_root (g, fs) == -1) - return -1; -@@ -197,7 +197,7 @@ check_filesystem (guestfs_h *g, const char *mountable, - else if (guestfs_is_file (g, "/hurd/console") > 0 && - guestfs_is_file (g, "/hurd/hello") > 0 && - guestfs_is_file (g, "/hurd/null") > 0) { -- fs->is_root = 1; -+ fs->role = OS_ROLE_ROOT; - fs->format = OS_FORMAT_INSTALLED; /* XXX could be more specific */ - if (guestfs_int_check_hurd_root (g, fs) == -1) - return -1; -@@ -208,7 +208,7 @@ check_filesystem (guestfs_h *g, const char *mountable, - guestfs_is_file (g, "/service/vm") > 0 && - guestfs_is_file (g, "/etc/fstab") > 0 && - guestfs_is_file (g, "/etc/version") > 0) { -- fs->is_root = 1; -+ fs->role = OS_ROLE_ROOT; - fs->format = OS_FORMAT_INSTALLED; - if (guestfs_int_check_minix_root (g, fs) == -1) - return -1; -@@ -219,7 +219,7 @@ check_filesystem (guestfs_h *g, const char *mountable, - is_symlink_to (g, "/bin", "usr/bin") > 0) && - (guestfs_is_file (g, "/etc/fstab") > 0 || - guestfs_is_file (g, "/etc/hosts") > 0)) { -- fs->is_root = 1; -+ fs->role = OS_ROLE_ROOT; - fs->format = OS_FORMAT_INSTALLED; - if (guestfs_int_check_linux_root (g, fs) == -1) - return -1; -@@ -230,7 +230,7 @@ check_filesystem (guestfs_h *g, const char *mountable, - guestfs_is_dir (g, "/home") > 0 && - guestfs_is_dir (g, "/usr") > 0 && - guestfs_is_file (g, "/etc/coreos/update.conf") > 0) { -- fs->is_root = 1; -+ fs->role = OS_ROLE_ROOT; - fs->format = OS_FORMAT_INSTALLED; - if (guestfs_int_check_coreos_root (g, fs) == -1) - return -1; -@@ -265,7 +265,7 @@ check_filesystem (guestfs_h *g, const char *mountable, - /* Windows root? */ - else if ((windows_systemroot = guestfs_int_get_windows_systemroot (g)) != NULL) - { -- fs->is_root = 1; -+ fs->role = OS_ROLE_ROOT; - fs->format = OS_FORMAT_INSTALLED; - if (guestfs_int_check_windows_root (g, fs, windows_systemroot) == -1) - return -1; -@@ -280,7 +280,7 @@ check_filesystem (guestfs_h *g, const char *mountable, - /* FreeDOS? */ - else if (guestfs_int_is_dir_nocase (g, "/FDOS") > 0 && - guestfs_int_is_file_nocase (g, "/FDOS/FREEDOS.BSS") > 0) { -- fs->is_root = 1; -+ fs->role = OS_ROLE_ROOT; - fs->format = OS_FORMAT_INSTALLED; - fs->type = OS_TYPE_DOS; - fs->distro = OS_DISTRO_FREEDOS; -@@ -308,7 +308,7 @@ check_filesystem (guestfs_h *g, const char *mountable, - guestfs_is_file (g, "/amd64/txtsetup.sif") > 0 || - guestfs_is_file (g, "/freedos/freedos.ico") > 0 || - guestfs_is_file (g, "/boot/loader.rc") > 0)) { -- fs->is_root = 1; -+ fs->role = OS_ROLE_ROOT; - fs->format = OS_FORMAT_INSTALLER; - if (guestfs_int_check_installer_root (g, fs) == -1) - return -1; -diff --git a/src/inspect.c b/src/inspect.c -index 497794e..e82c476 100644 ---- a/src/inspect.c -+++ b/src/inspect.c -@@ -105,7 +105,7 @@ collect_coreos_inspection_info (guestfs_h *g) - for (i = 0; i < g->nr_fses; ++i) { - struct inspect_fs *fs = &g->fses[i]; - -- if (fs->distro == OS_DISTRO_COREOS && fs->is_root) -+ if (fs->distro == OS_DISTRO_COREOS && fs->role == OS_ROLE_ROOT) - root = fs; - } - -@@ -115,7 +115,7 @@ collect_coreos_inspection_info (guestfs_h *g) - for (i = 0; i < g->nr_fses; ++i) { - struct inspect_fs *fs = &g->fses[i]; - -- if (fs->distro != OS_DISTRO_COREOS || fs->is_root != 0) -+ if (fs->distro != OS_DISTRO_COREOS || fs->role == OS_ROLE_ROOT) - continue; - - /* CoreOS is designed to contain 2 /usr partitions (USR-A, USR-B): -@@ -162,15 +162,16 @@ check_for_duplicated_bsd_root (guestfs_h *g) - fs->type == OS_TYPE_NETBSD || - fs->type == OS_TYPE_OPENBSD; - -- if (fs->is_root && is_bsd && -+ if (fs->role == OS_ROLE_ROOT && is_bsd && - match (g, fs->mountable, re_primary_partition)) { - bsd_primary = fs; - continue; - } - -- if (fs->is_root && bsd_primary && bsd_primary->type == fs->type) { -- /* remove the is root flag from the bsd_primary */ -- bsd_primary->is_root = 0; -+ if (fs->role == OS_ROLE_ROOT && bsd_primary && -+ bsd_primary->type == fs->type) { -+ /* remove the root role from the bsd_primary */ -+ bsd_primary->role = OS_ROLE_UNKNOWN; - bsd_primary->format = OS_FORMAT_UNKNOWN; - return; - } -@@ -196,7 +197,7 @@ guestfs_impl_inspect_get_roots (guestfs_h *g) - * list in this case. - */ - for (i = 0; i < g->nr_fses; ++i) { -- if (g->fses[i].is_root) -+ if (g->fses[i].role == OS_ROLE_ROOT) - guestfs_int_add_string (g, &ret, g->fses[i].mountable); - } - guestfs_int_end_stringsbuf (g, &ret); -@@ -694,7 +695,7 @@ guestfs_int_search_for_root (guestfs_h *g, const char *root) - - for (i = 0; i < g->nr_fses; ++i) { - struct inspect_fs *fs = &g->fses[i]; -- if (fs->is_root && STREQ (root, fs->mountable)) -+ if (fs->role == OS_ROLE_ROOT && STREQ (root, fs->mountable)) - return fs; - } - --- -1.8.3.1 - diff --git a/SOURCES/0182-inspect-mark-CoreOS-usr-partitions-with-own-USR-role.patch b/SOURCES/0182-inspect-mark-CoreOS-usr-partitions-with-own-USR-role.patch deleted file mode 100644 index 6e606b6..0000000 --- a/SOURCES/0182-inspect-mark-CoreOS-usr-partitions-with-own-USR-role.patch +++ /dev/null @@ -1,57 +0,0 @@ -From 950cff00671c2412b2bff0f88b699892783962e5 Mon Sep 17 00:00:00 2001 -From: Pino Toscano -Date: Mon, 5 Dec 2016 17:20:58 +0100 -Subject: [PATCH] inspect: mark CoreOS /usr partitions with own USR role - -Add a new inspect role for "/usr" partitions, and use that to mark the -/usr partition in CoreOS: this additional role allows to ease its lookup -later on, when merging its results into those of the root. - -(cherry picked from commit e77e1ef95ed79d34dfcbaa08e26a333462471899) ---- - src/guestfs-internal.h | 1 + - src/inspect-fs-unix.c | 2 ++ - src/inspect.c | 2 +- - 3 files changed, 4 insertions(+), 1 deletion(-) - -diff --git a/src/guestfs-internal.h b/src/guestfs-internal.h -index 6f31438..eb201aa 100644 ---- a/src/guestfs-internal.h -+++ b/src/guestfs-internal.h -@@ -597,6 +597,7 @@ enum inspect_os_package_management { - enum inspect_os_role { - OS_ROLE_UNKNOWN = 0, - OS_ROLE_ROOT, -+ OS_ROLE_USR, - }; - - struct inspect_fs { -diff --git a/src/inspect-fs-unix.c b/src/inspect-fs-unix.c -index 149ad85..8e27ade 100644 ---- a/src/inspect-fs-unix.c -+++ b/src/inspect-fs-unix.c -@@ -1055,6 +1055,8 @@ guestfs_int_check_coreos_usr (guestfs_h *g, struct inspect_fs *fs) - - fs->type = OS_TYPE_LINUX; - fs->distro = OS_DISTRO_COREOS; -+ fs->role = OS_ROLE_USR; -+ - if (guestfs_is_file_opts (g, "/share/coreos/lsb-release", - GUESTFS_IS_FILE_OPTS_FOLLOWSYMLINKS, 1, -1) > 0) { - r = parse_lsb_release (g, fs, "/share/coreos/lsb-release"); -diff --git a/src/inspect.c b/src/inspect.c -index e82c476..e805291 100644 ---- a/src/inspect.c -+++ b/src/inspect.c -@@ -115,7 +115,7 @@ collect_coreos_inspection_info (guestfs_h *g) - for (i = 0; i < g->nr_fses; ++i) { - struct inspect_fs *fs = &g->fses[i]; - -- if (fs->distro != OS_DISTRO_COREOS || fs->role == OS_ROLE_ROOT) -+ if (fs->distro != OS_DISTRO_COREOS || fs->role != OS_ROLE_USR) - continue; - - /* CoreOS is designed to contain 2 /usr partitions (USR-A, USR-B): --- -1.8.3.1 - diff --git a/SOURCES/0183-inspect-fix-existance-check-of-dev-mapper-devices.patch b/SOURCES/0183-inspect-fix-existance-check-of-dev-mapper-devices.patch deleted file mode 100644 index 05b4b06..0000000 --- a/SOURCES/0183-inspect-fix-existance-check-of-dev-mapper-devices.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 60e21f49f1da66af4531b4472670e075d83cd0c1 Mon Sep 17 00:00:00 2001 -From: Pino Toscano -Date: Tue, 6 Dec 2016 15:18:34 +0100 -Subject: [PATCH] inspect: fix existance check of /dev/mapper devices - -When checking for the existance of /dev/mapper devices found in the -fstab of a filesystem, using guestfs_exists means they are checked as -files in the guest, while they really appear as devices on the -appliance. Instead, try the lvm name resolution anyway, and ignore them -when they are reported as missing. - -Thanks to: Richard W.M. Jones. - -Fixes commit 96b6504b09461aeb6850bb2e7b870a0a4c2f5edf. - -(cherry picked from commit dad35e55fac526dbcd50964500f2d5047ae011af) ---- - src/inspect-fs-unix.c | 13 ++++++++++++- - 1 file changed, 12 insertions(+), 1 deletion(-) - -diff --git a/src/inspect-fs-unix.c b/src/inspect-fs-unix.c -index 8e27ade..8b7a7ee 100644 ---- a/src/inspect-fs-unix.c -+++ b/src/inspect-fs-unix.c -@@ -24,6 +24,7 @@ - #include - #include - #include -+#include - - #ifdef HAVE_ENDIAN_H - #include -@@ -1850,7 +1851,7 @@ resolve_fstab_device (guestfs_h *g, const char *spec, Hash_table *md_map, - char *type, *slice, *disk, *part; - int r; - -- if (STRPREFIX (spec, "/dev/mapper/") && guestfs_exists (g, spec) > 0) { -+ if (STRPREFIX (spec, "/dev/mapper/")) { - /* LVM2 does some strange munging on /dev/mapper paths for VGs and - * LVs which contain '-' character: - * -@@ -1861,7 +1862,17 @@ resolve_fstab_device (guestfs_h *g, const char *spec, Hash_table *md_map, - * This makes it impossible to reverse those paths directly, so - * we have implemented lvm_canonical_lv_name in the daemon. - */ -+ guestfs_push_error_handler (g, NULL, NULL); - device = guestfs_lvm_canonical_lv_name (g, spec); -+ guestfs_pop_error_handler (g); -+ if (device == NULL) { -+ if (guestfs_last_errno (g) == ENOENT) { -+ /* Ignore devices that don't exist. (RHBZ#811872) */ -+ } else { -+ guestfs_int_error_errno (g, guestfs_last_errno (g), "%s", guestfs_last_error (g)); -+ return NULL; -+ } -+ } - } - else if (match3 (g, spec, re_xdev, &type, &disk, &part)) { - r = resolve_fstab_device_xdev (g, type, disk, part, &device); --- -1.8.3.1 - diff --git a/SOURCES/0184-inspect-gather-info-from-usr-filesystems-as-well-RHB.patch b/SOURCES/0184-inspect-gather-info-from-usr-filesystems-as-well-RHB.patch deleted file mode 100644 index 211ba51..0000000 --- a/SOURCES/0184-inspect-gather-info-from-usr-filesystems-as-well-RHB.patch +++ /dev/null @@ -1,207 +0,0 @@ -From ba1ee149fe81cf4061e53eecb0ec0cc1aee63da7 Mon Sep 17 00:00:00 2001 -From: Pino Toscano -Date: Tue, 6 Dec 2016 16:08:12 +0100 -Subject: [PATCH] inspect: gather info from /usr filesystems as well - (RHBZ#1401474) - -Flag the filesystems for Linux /usr properly as USR role, and detect -some data out of it, like the distro information from an os-release -(if present), and the architecture (since the binaries used for our -architecture check will be available there only). - -Later on, collect the results in a way similar to what is done for -CoreOS: for each non-CoreOS root, try to find its /usr filesystem, and -if found then merge what is missing from root; in the last case, also -override the distro inspection data (version, product name) if available -in /usr. - -(cherry picked from commit 1d86b3768956f818262a5189bb1ba996dedbf531) ---- - src/guestfs-internal.h | 1 + - src/inspect-fs-unix.c | 26 ++++++++++++++++ - src/inspect-fs.c | 6 ++-- - src/inspect.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++++-- - 4 files changed, 109 insertions(+), 5 deletions(-) - -diff --git a/src/guestfs-internal.h b/src/guestfs-internal.h -index eb201aa..0f5f975 100644 ---- a/src/guestfs-internal.h -+++ b/src/guestfs-internal.h -@@ -795,6 +795,7 @@ extern void guestfs_int_merge_fs_inspections (guestfs_h *g, struct inspect_fs *d - - /* inspect-fs-unix.c */ - extern int guestfs_int_check_linux_root (guestfs_h *g, struct inspect_fs *fs); -+extern int guestfs_int_check_linux_usr (guestfs_h *g, struct inspect_fs *fs); - extern int guestfs_int_check_freebsd_root (guestfs_h *g, struct inspect_fs *fs); - extern int guestfs_int_check_netbsd_root (guestfs_h *g, struct inspect_fs *fs); - extern int guestfs_int_check_openbsd_root (guestfs_h *g, struct inspect_fs *fs); -diff --git a/src/inspect-fs-unix.c b/src/inspect-fs-unix.c -index 8b7a7ee..48c4fd2 100644 ---- a/src/inspect-fs-unix.c -+++ b/src/inspect-fs-unix.c -@@ -813,6 +813,32 @@ guestfs_int_check_linux_root (guestfs_h *g, struct inspect_fs *fs) - return 0; - } - -+/* The currently mounted device looks like a Linux /usr. */ -+int -+guestfs_int_check_linux_usr (guestfs_h *g, struct inspect_fs *fs) -+{ -+ int r; -+ -+ fs->type = OS_TYPE_LINUX; -+ fs->role = OS_ROLE_USR; -+ -+ if (guestfs_is_file_opts (g, "/lib/os-release", -+ GUESTFS_IS_FILE_OPTS_FOLLOWSYMLINKS, 1, -1) > 0) { -+ r = parse_os_release (g, fs, "/lib/os-release"); -+ if (r == -1) /* error */ -+ return -1; -+ if (r == 1) /* ok - detected the release from this file */ -+ goto skip_release_checks; -+ } -+ -+ skip_release_checks:; -+ -+ /* Determine the architecture. */ -+ check_architecture (g, fs); -+ -+ return 0; -+} -+ - /* The currently mounted device is known to be a FreeBSD root. */ - int - guestfs_int_check_freebsd_root (guestfs_h *g, struct inspect_fs *fs) -diff --git a/src/inspect-fs.c b/src/inspect-fs.c -index 58f08b8..f6c2656 100644 ---- a/src/inspect-fs.c -+++ b/src/inspect-fs.c -@@ -247,8 +247,10 @@ check_filesystem (guestfs_h *g, const char *mountable, - is_dir_bin && - is_dir_share && - guestfs_is_dir (g, "/local") > 0 && -- guestfs_is_file (g, "/etc/fstab") == 0) -- ; -+ guestfs_is_file (g, "/etc/fstab") == 0) { -+ if (guestfs_int_check_linux_usr (g, fs) == -1) -+ return -1; -+ } - /* CoreOS /usr? */ - else if (is_dir_bin && - is_dir_share && -diff --git a/src/inspect.c b/src/inspect.c -index e805291..db2a125 100644 ---- a/src/inspect.c -+++ b/src/inspect.c -@@ -26,6 +26,7 @@ - #include - #include - #include -+#include - - #ifdef HAVE_ENDIAN_H - #include -@@ -41,6 +42,8 @@ COMPILE_REGEXP (re_primary_partition, "^/dev/(?:h|s|v)d.[1234]$", 0) - - static void check_for_duplicated_bsd_root (guestfs_h *g); - static void collect_coreos_inspection_info (guestfs_h *g); -+static void collect_linux_inspection_info (guestfs_h *g); -+static void collect_linux_inspection_info_for (guestfs_h *g, struct inspect_fs *root); - - /* The main inspection code. */ - char ** -@@ -81,6 +84,12 @@ guestfs_impl_inspect_os (guestfs_h *g) - */ - check_for_duplicated_bsd_root (g); - -+ /* For Linux guests with a separate /usr filesyste, merge some of the -+ * inspected information in that partition to the inspect_fs struct -+ * of the root filesystem. -+ */ -+ collect_linux_inspection_info (g); -+ - /* At this point we have, in the handle, a list of all filesystems - * found and data about each one. Now we assemble the list of - * filesystems which are root devices and return that to the user. -@@ -143,9 +152,75 @@ collect_coreos_inspection_info (guestfs_h *g) - guestfs_int_merge_fs_inspections (g, root, usr); - } - --/* On *BSD systems, sometimes /dev/sda[1234] is a shadow of the real root -- * filesystem that is probably /dev/sda5 -- * (see: http://www.freebsd.org/doc/handbook/disk-organization.html) -+/** -+ * Traverse through the filesystems and find the /usr filesystem for -+ * the specified C: if found, merge its basic inspection details -+ * to the root when they were set (i.e. because the /usr had os-release -+ * or other ways to identify the OS). -+ */ -+static void -+collect_linux_inspection_info_for (guestfs_h *g, struct inspect_fs *root) -+{ -+ size_t i; -+ struct inspect_fs *usr = NULL; -+ -+ for (i = 0; i < g->nr_fses; ++i) { -+ struct inspect_fs *fs = &g->fses[i]; -+ size_t j; -+ -+ if (!(fs->distro == root->distro || fs->distro == OS_DISTRO_UNKNOWN) || -+ fs->role != OS_ROLE_USR) -+ continue; -+ -+ for (j = 0; j < root->nr_fstab; ++j) { -+ if (STREQ (fs->mountable, root->fstab[j].mountable)) { -+ usr = fs; -+ goto got_usr; -+ } -+ } -+ } -+ -+ assert (usr == NULL); -+ return; -+ -+ got_usr: -+ /* If the version information in /usr is not null, then most probably -+ * there was an os-release file there, so reset what is in root -+ * and pick the results from /usr. -+ */ -+ if (!(usr->major_version == 0 && usr->minor_version == 0)) { -+ root->distro = OS_DISTRO_UNKNOWN; -+ free (root->product_name); -+ root->product_name = NULL; -+ } -+ -+ guestfs_int_merge_fs_inspections (g, root, usr); -+} -+ -+/** -+ * Traverse through the filesystem list and find out if it contains -+ * the C and C filesystems of a Linux image (but not CoreOS, -+ * for which there is a separate C). -+ * If this is the case, sum up all the collected information on each -+ * root fs from the respective /usr filesystems. -+ */ -+static void -+collect_linux_inspection_info (guestfs_h *g) -+{ -+ size_t i; -+ -+ for (i = 0; i < g->nr_fses; ++i) { -+ struct inspect_fs *fs = &g->fses[i]; -+ -+ if (fs->distro != OS_DISTRO_COREOS && fs->role == OS_ROLE_ROOT) -+ collect_linux_inspection_info_for (g, fs); -+ } -+} -+ -+/** -+ * On *BSD systems, sometimes F is a shadow of the -+ * real root filesystem that is probably F (see: -+ * L) - */ - static void - check_for_duplicated_bsd_root (guestfs_h *g) --- -1.8.3.1 - diff --git a/SOURCES/0185-appliance-Disable-EDD-edd-off-RHBZ-1404287.patch b/SOURCES/0185-appliance-Disable-EDD-edd-off-RHBZ-1404287.patch deleted file mode 100644 index 4708038..0000000 --- a/SOURCES/0185-appliance-Disable-EDD-edd-off-RHBZ-1404287.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 0e7af58f29e49aba87f3c0d968b084c124fe5dbe Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Sun, 18 Dec 2016 19:27:20 +0000 -Subject: [PATCH] appliance: Disable EDD (edd=off) (RHBZ#1404287). - -EDD (https://en.wikipedia.org/wiki/Enhanced_Disk_Drive) is a BIOS INT 13h -subcall for communicating the extended size of the boot disk over 8GB -to the OS. Since libguestfs doesn't use a boot disk, and the -appliance disk is limited to 4GB, and we use virtio-scsi, this is all -useless. - -EDD is also broken currently on RHEL 7.3, see: -https://bugzilla.redhat.com/show_bug.cgi?id=1404287 - -Also the EDD probing takes significant extra time (about 80ms on my -laptop), and using edd=off reduces this time although doesn't entirely -eliminate it. - -(cherry picked from commit 764fd3fcc629ff91582ec8549ff80c240ba8393b) ---- - src/launch.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/src/launch.c b/src/launch.c -index 269eeca..0075ea7 100644 ---- a/src/launch.c -+++ b/src/launch.c -@@ -332,6 +332,7 @@ guestfs_int_appliance_command_line (guestfs_h *g, const char *appliance_dev, - */ - " efi-rtc=noprobe" - #endif -+ " edd=off" /* RHBZ#1404287 */ - " udevtimeout=6000"/* for slow systems (RHBZ#480319, RHBZ#1096579) */ - " udev.event-timeout=6000" /* for newer udevd */ - " no_timer_check" /* fix for RHBZ#502058 */ --- -1.8.3.1 - diff --git a/SOURCES/0186-v2v-o-vdsm-Add-vdsm-compat-flag.-o-rhev-Drop-support.patch b/SOURCES/0186-v2v-o-vdsm-Add-vdsm-compat-flag.-o-rhev-Drop-support.patch deleted file mode 100644 index 97fd302..0000000 --- a/SOURCES/0186-v2v-o-vdsm-Add-vdsm-compat-flag.-o-rhev-Drop-support.patch +++ /dev/null @@ -1,239 +0,0 @@ -From b7a00e7b473add0fa94776292be45a25b31c1407 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Wed, 30 Nov 2016 16:52:42 +0000 -Subject: [PATCH] v2v: -o vdsm: Add --vdsm-compat flag. -o rhev: Drop support - for RHV < 4.1 (RHBZ#1400205). - -Support for RHEV with RHEL 6 nodes required us to output the old style -qcow2 compat=0.10 images. Since RHEV 3.6 GA, RHEL 6 has not been -supported as a RHEV node type. Since RHV 4.1, compat=1.1 is -supported. (Support for compat=1.1 is uncertain in RHV 4.0 even on -RHEL 7 nodes.) - -There are significant downsides to using qcow2 compat=0.10 instead of -the modern default (compat=1.1). - -Therefore this patch does two things: - -For -o rhev, it drops support for compat=0.10 completely. You must -use RHV 4.1. - -For -o vdsm, it adds an interim flag (--vdsm-compat=0.10 or ---vdsm-compat=1.1) which controls the compat level of the qcow2 output -file. VDSM should use --vdsm-compat=1.1 when it is known that modern -qemu is available. We can make this the default later when all RHV -instances have moved to 4.1. - -It also adds: - - vdsm-compat-option - -to the `virt-v2v --machine-readable' output to indicate that this flag -can be used. - -Thanks: Yaniv Kaul, Michal Skrivanek. -(cherry picked from commit bdaeeb4e606f3828887da87ad5acb4f7b49cfed5) ---- - v2v/cmdline.ml | 8 ++++++++ - v2v/output_rhev.ml | 4 ---- - v2v/output_vdsm.ml | 11 ++++++++--- - v2v/output_vdsm.mli | 1 + - v2v/test-v2v-o-vdsm-options.sh | 9 ++++++++- - v2v/virt-v2v.pod | 19 +++++++++++++++++++ - 6 files changed, 44 insertions(+), 8 deletions(-) - -diff --git a/v2v/cmdline.ml b/v2v/cmdline.ml -index b9992eb..f5fb3b3 100644 ---- a/v2v/cmdline.ml -+++ b/v2v/cmdline.ml -@@ -66,6 +66,10 @@ let parse_cmdline () = - let vdsm_vm_uuid = ref None in - let vdsm_ovf_output = ref None in (* default "." *) - let vmtype = ref None in -+ -+ let vdsm_compat = ref "0.10" in -+ let set_vdsm_compat s = vdsm_compat := s in -+ - let set_string_option_once optname optref arg = - match !optref with - | Some _ -> -@@ -215,6 +219,7 @@ let parse_cmdline () = - "file " ^ s_"Use password from file"; - "--print-source", Arg.Set print_source, " " ^ s_"Print source and stop"; - "--root", Arg.String set_root_choice,"ask|... " ^ s_"How to choose root filesystem"; -+ "--vdsm-compat", Arg.Symbol (["0.10"; "1.1"], set_vdsm_compat), " " ^ s_"Write qcow2 with compat=0.10|1.1"; - "--vdsm-image-uuid", Arg.String add_vdsm_image_uuid, "uuid " ^ s_"Output image UUID(s)"; - "--vdsm-vol-uuid", Arg.String add_vdsm_vol_uuid, "uuid " ^ s_"Output vol UUID(s)"; - "--vdsm-vm-uuid", Arg.String (set_string_option_once "--vdsm-vm-uuid" vdsm_vm_uuid), -@@ -277,6 +282,7 @@ read the man page virt-v2v(1). - let print_source = !print_source in - let qemu_boot = !qemu_boot in - let root_choice = !root_choice in -+ let vdsm_compat = !vdsm_compat in - let vdsm_image_uuids = List.rev !vdsm_image_uuids in - let vdsm_vol_uuids = List.rev !vdsm_vol_uuids in - let vdsm_vm_uuid = !vdsm_vm_uuid in -@@ -297,6 +303,7 @@ read the man page virt-v2v(1). - printf "virt-v2v\n"; - printf "libguestfs-rewrite\n"; - printf "colours-option\n"; -+ printf "vdsm-compat-option\n"; - List.iter (printf "input:%s\n") (Modules_list.input_modules ()); - List.iter (printf "output:%s\n") (Modules_list.output_modules ()); - List.iter (printf "convert:%s\n") (Modules_list.convert_modules ()); -@@ -454,6 +461,7 @@ read the man page virt-v2v(1). - vol_uuids = vdsm_vol_uuids; - vm_uuid = vdsm_vm_uuid; - ovf_output = vdsm_ovf_output; -+ compat = vdsm_compat; - } in - Output_vdsm.output_vdsm os vdsm_params vmtype output_alloc in - -diff --git a/v2v/output_rhev.ml b/v2v/output_rhev.ml -index ae37a3f..7bd94df 100644 ---- a/v2v/output_rhev.ml -+++ b/v2v/output_rhev.ml -@@ -253,10 +253,6 @@ object - Changeuid.func changeuid_t ( - fun () -> - let g = open_guestfs ~identifier:"rhev_disk_create" () in -- (* For qcow2, override v2v-supplied compat option, because RHEL 6 -- * nodes cannot handle qcow2 v3 (RHBZ#1145582). -- *) -- let compat = if format <> "qcow2" then compat else Some "0.10" in - g#disk_create ?backingfile ?backingformat ?preallocation ?compat - ?clustersize path format size; - (* Make it sufficiently writable so that possibly root, or -diff --git a/v2v/output_vdsm.ml b/v2v/output_vdsm.ml -index 7bb28a9..57b5352 100644 ---- a/v2v/output_vdsm.ml -+++ b/v2v/output_vdsm.ml -@@ -30,6 +30,7 @@ type vdsm_params = { - vol_uuids : string list; - vm_uuid : string; - ovf_output : string; -+ compat : string; - } - - class output_vdsm os vdsm_params vmtype output_alloc = -@@ -37,7 +38,7 @@ object - inherit output - - method as_options = -- sprintf "-o vdsm -os %s%s%s --vdsm-vm-uuid %s --vdsm-ovf-output %s%s" os -+ sprintf "-o vdsm -os %s%s%s --vdsm-vm-uuid %s --vdsm-ovf-output %s%s%s" os - (String.concat "" - (List.map (sprintf " --vdsm-image-uuid %s") vdsm_params.image_uuids)) - (String.concat "" -@@ -48,6 +49,9 @@ object - | None -> "" - | Some Server -> " --vmtype server" - | Some Desktop -> " --vmtype desktop") -+ (match vdsm_params.compat with -+ | "0.10" -> "" (* currently this is the default, so don't print it *) -+ | s -> sprintf " --vdsm-compat=%s" s) - - method supported_firmware = [ TargetBIOS ] - -@@ -153,9 +157,10 @@ object - ?clustersize path format size = - let g = open_guestfs ~identifier:"vdsm_disk_create" () in - (* For qcow2, override v2v-supplied compat option, because RHEL 6 -- * nodes cannot handle qcow2 v3 (RHBZ#1145582). -+ * nodes cannot handle qcow2 v3 (RHBZ#1145582, RHBZ#1400205). - *) -- let compat = if format <> "qcow2" then compat else Some "0.10" in -+ let compat = -+ if format <> "qcow2" then compat else Some vdsm_params.compat in - g#disk_create ?backingfile ?backingformat ?preallocation ?compat - ?clustersize path format size - -diff --git a/v2v/output_vdsm.mli b/v2v/output_vdsm.mli -index 1a88eaa..40eceee 100644 ---- a/v2v/output_vdsm.mli -+++ b/v2v/output_vdsm.mli -@@ -23,6 +23,7 @@ type vdsm_params = { - vol_uuids : string list; (* --vdsm-vol-uuid (multiple) *) - vm_uuid : string; (* --vdsm-vm-uuid *) - ovf_output : string; (* --vdsm-ovf-output *) -+ compat : string; (* --vdsm-compat=0.10|1.1 *) - } - (** Miscellaneous extra command line parameters used by VDSM. *) - -diff --git a/v2v/test-v2v-o-vdsm-options.sh b/v2v/test-v2v-o-vdsm-options.sh -index 6ae5d56..de07b9c 100755 ---- a/v2v/test-v2v-o-vdsm-options.sh -+++ b/v2v/test-v2v-o-vdsm-options.sh -@@ -1,6 +1,6 @@ - #!/bin/bash - - # libguestfs virt-v2v test script --# Copyright (C) 2014 Red Hat Inc. -+# Copyright (C) 2014-2016 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 -@@ -21,6 +21,7 @@ - unset CDPATH - export LANG=C - set -e -+set -x - - if [ -n "$SKIP_TEST_V2V_O_VDSM_OPTIONS_SH" ]; then - echo "$0: test skipped because environment variable is set" -@@ -62,10 +63,12 @@ $VG virt-v2v --debug-gc \ - -i libvirt -ic "$libvirt_uri" windows \ - -o vdsm -os $d/12345678-1234-1234-1234-123456789abc \ - --vmtype desktop \ -+ -of qcow2 \ - --vdsm-image-uuid IMAGE \ - --vdsm-vol-uuid VOL \ - --vdsm-vm-uuid VM \ - --vdsm-ovf-output $d/12345678-1234-1234-1234-123456789abc/master/vms/VM \ -+ --vdsm-compat=1.1 - - # Test the OVF metadata was created. - test -f $d/12345678-1234-1234-1234-123456789abc/master/vms/VM/VM.ovf -@@ -82,6 +85,10 @@ test -f VOL.meta - # Test the disk file was created. - test -f VOL - -+# Test that a qcow2 file with compat=1.1 was generated. -+test "$(guestfish disk-format VOL)" = "qcow2" -+qemu-img info VOL | grep 'compat: 1.1' -+ - popd - - rm -r $d -diff --git a/v2v/virt-v2v.pod b/v2v/virt-v2v.pod -index 32085c1..fb00e82 100644 ---- a/v2v/virt-v2v.pod -+++ b/v2v/virt-v2v.pod -@@ -495,6 +495,25 @@ boot an operating system from the first VirtIO disk. Specifically, - F must be on the first VirtIO disk, and it cannot chainload an - OS which is not in the first VirtIO disk. - -+=item B<--vdsm-compat=0.10> -+ -+=item B<--vdsm-compat=1.1> -+ -+If I<-o vdsm> and the output format is qcow2, then we add the qcow2 -+I option to the output file for compatibility with RHEL 6 -+(see L). -+ -+If I<--vdsm-compat=1.1> is used then modern qcow2 (I) -+files are generated instead. -+ -+Currently I<--vdsm-compat=0.10> is the default, but this will change -+to I<--vdsm-compat=1.1> in a future version of virt-v2v (when we can -+assume that everyone is using a modern version of qemu). -+ -+B output>. All other output -+modes (including I<-o rhev>) generate modern qcow2 I -+files, always. -+ - =item B<--vdsm-image-uuid> UUID - - =item B<--vdsm-vol-uuid> UUID --- -1.8.3.1 - diff --git a/SOURCES/0187-virt-v2v-Support-for-ova-exported-from-AWS-RHBZ-1371.patch b/SOURCES/0187-virt-v2v-Support-for-ova-exported-from-AWS-RHBZ-1371.patch deleted file mode 100644 index b2a1943..0000000 --- a/SOURCES/0187-virt-v2v-Support-for-ova-exported-from-AWS-RHBZ-1371.patch +++ /dev/null @@ -1,47 +0,0 @@ -From d84af86948e82322f95a99d2ecd46bec04977d26 Mon Sep 17 00:00:00 2001 -From: Shahar Havivi -Date: Thu, 8 Sep 2016 09:53:37 +0300 -Subject: [PATCH] virt-v2v: Support for ova exported from AWS (RHBZ#1371843). - -1. AWS the name tag is not mandatory - using default as a name -2. AWD doesn't prefix 'ovf:' as prefix to disk path - -There is an open bug for oVirt: -https://bugzilla.redhat.com/show_bug.cgi?id=1371843 - -Signed-off-by: Shahar Havivi -(cherry picked from commit 1ae4252c93c685cb8561b55c1231502b37212b5a) ---- - v2v/input_ova.ml | 7 ++++--- - 1 file changed, 4 insertions(+), 3 deletions(-) - -diff --git a/v2v/input_ova.ml b/v2v/input_ova.ml -index 0a4dfd5..932c96b 100644 ---- a/v2v/input_ova.ml -+++ b/v2v/input_ova.ml -@@ -185,7 +185,8 @@ object - let name = - match xpath_string "/ovf:Envelope/ovf:VirtualSystem/ovf:Name/text()" with - | None | Some "" -> -- error (f_"could not parse ovf:Name from OVF document") -+ warning (f_"could not parse ovf:Name from OVF document"); -+ "default" - | Some name -> name in - - (* Search for memory. *) -@@ -245,10 +246,10 @@ object - - Xml.xpathctx_set_current_context xpathctx n; - let file_id = xpath_string_default "rasd:HostResource/text()" "" in -- let rex = Str.regexp "^ovf:/disk/\\(.*\\)" in -+ let rex = Str.regexp "^\\(ovf:\\)?/disk/\\(.*\\)" in - if Str.string_match rex file_id 0 then ( - (* Chase the references through to the actual file name. *) -- let file_id = Str.matched_group 1 file_id in -+ let file_id = Str.matched_group 2 file_id in - let expr = sprintf "/ovf:Envelope/ovf:DiskSection/ovf:Disk[@ovf:diskId='%s']/@ovf:fileRef" file_id in - let file_ref = - match xpath_string expr with --- -1.8.3.1 - diff --git a/SOURCES/0188-v2v-i-disk-Move-code-that-creates-name-from-disk-to-.patch b/SOURCES/0188-v2v-i-disk-Move-code-that-creates-name-from-disk-to-.patch deleted file mode 100644 index 0c2d785..0000000 --- a/SOURCES/0188-v2v-i-disk-Move-code-that-creates-name-from-disk-to-.patch +++ /dev/null @@ -1,157 +0,0 @@ -From 2ddaafb1b90169e4cb35b2e47116a95ff9045f6b Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Fri, 9 Sep 2016 14:45:05 +0100 -Subject: [PATCH] v2v: -i disk: Move code that creates name from disk to - separate module. - -Simple code motion. - -(cherry picked from commit 312379c8a61cd4a16aa7c80c1adda3081e601d43) ---- - v2v/Makefile.am | 2 ++ - v2v/input_disk.ml | 21 ++------------------- - v2v/name_from_disk.ml | 41 +++++++++++++++++++++++++++++++++++++++++ - v2v/name_from_disk.mli | 24 ++++++++++++++++++++++++ - 4 files changed, 69 insertions(+), 19 deletions(-) - create mode 100644 v2v/name_from_disk.ml - create mode 100644 v2v/name_from_disk.mli - -diff --git a/v2v/Makefile.am b/v2v/Makefile.am -index c1ebb17..f9a0796 100644 ---- a/v2v/Makefile.am -+++ b/v2v/Makefile.am -@@ -62,6 +62,7 @@ SOURCES_MLI = \ - inspect_source.mli \ - linux.mli \ - modules_list.mli \ -+ name_from_disk.mli \ - output_glance.mli \ - output_libvirt.mli \ - output_local.mli \ -@@ -84,6 +85,7 @@ SOURCES_ML = \ - xml.ml \ - uefi.ml \ - utils.ml \ -+ name_from_disk.ml \ - vCenter.ml \ - domainxml.ml \ - DOM.ml \ -diff --git a/v2v/input_disk.ml b/v2v/input_disk.ml -index b6c9089..9a2ef08 100644 ---- a/v2v/input_disk.ml -+++ b/v2v/input_disk.ml -@@ -23,6 +23,7 @@ open Common_utils - - open Types - open Utils -+open Name_from_disk - - class input_disk input_format disk = object - inherit input -@@ -42,25 +43,7 @@ class input_disk input_format disk = object - * the filename passed in. Users can override this using the - * `-on name' option. - *) -- let name = -- let name = Filename.basename disk in -- (* Remove the extension (or suffix), only if it's one usually -- * used for disk images. *) -- let suffixes = [ -- ".img"; ".qcow2"; ".raw"; ".vmdk"; -- "-sda"; -- ] in -- let rec loop = function -- | suff :: xs -> -- if Filename.check_suffix name suff then -- Filename.chop_suffix name suff -- else -- loop xs -- | [] -> name -- in -- loop suffixes in -- if name = "" then -- error (f_"-i disk: invalid input filename (%s)") disk; -+ let name = name_from_disk disk in - - (* Get the absolute path to the disk file. *) - let disk_absolute = absolute_path disk in -diff --git a/v2v/name_from_disk.ml b/v2v/name_from_disk.ml -new file mode 100644 -index 0000000..73caf34 ---- /dev/null -+++ b/v2v/name_from_disk.ml -@@ -0,0 +1,41 @@ -+(* virt-v2v -+ * Copyright (C) 2009-2016 Red Hat Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License along -+ * with this program; if not, write to the Free Software Foundation, Inc., -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -+ *) -+ -+open Common_gettext.Gettext -+open Common_utils -+ -+let name_from_disk disk = -+ let name = Filename.basename disk in -+ (* Remove the extension (or suffix), only if it's one usually -+ * used for disk images. *) -+ let suffixes = [ -+ ".img"; ".qcow2"; ".raw"; ".vmdk"; -+ "-sda"; -+ ] in -+ let rec loop = function -+ | suff :: xs -> -+ if Filename.check_suffix name suff then -+ Filename.chop_suffix name suff -+ else -+ loop xs -+ | [] -> name -+ in -+ let name = loop suffixes in -+ if name = "" then -+ error (f_"invalid input filename (%s)") disk; -+ name -diff --git a/v2v/name_from_disk.mli b/v2v/name_from_disk.mli -new file mode 100644 -index 0000000..db3ee17 ---- /dev/null -+++ b/v2v/name_from_disk.mli -@@ -0,0 +1,24 @@ -+(* virt-v2v -+ * Copyright (C) 2009-2016 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. -+ *) -+ -+(** Derive the source name from a disk name. *) -+ -+val name_from_disk : string -> string -+(** Take a disk name and derive from it a suitable source name. -+ -+ Used in particular by [-i disk] mode. *) --- -1.8.3.1 - diff --git a/SOURCES/0189-v2v-i-ova-Derive-the-name-from-the-OVA-filename.patch b/SOURCES/0189-v2v-i-ova-Derive-the-name-from-the-OVA-filename.patch deleted file mode 100644 index 6564e5a..0000000 --- a/SOURCES/0189-v2v-i-ova-Derive-the-name-from-the-OVA-filename.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 83aad5289c4c1f1ee7c5b2efabcd27d3b7a08420 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Fri, 9 Sep 2016 14:56:11 +0100 -Subject: [PATCH] v2v: -i ova: Derive the name from the OVA filename. - -If the guest has no element in the OVF, previously we chose -"default" as the name. This changes that so it uses a name derived -from the basename of the OVA file instead. - -For example: - - virt-v2v -i ova /path/to/myguest.ova [...] - -would use "myguest" as the name (assuming no was present). - -Modifies the behaviour of -commit 1ae4252c93c685cb8561b55c1231502b37212b5a. - -(cherry picked from commit 98619f9c26076d034574b8822dfcc6799741ed96) ---- - v2v/input_ova.ml | 3 ++- - v2v/name_from_disk.ml | 2 +- - 2 files changed, 3 insertions(+), 2 deletions(-) - -diff --git a/v2v/input_ova.ml b/v2v/input_ova.ml -index 932c96b..c5ff19c 100644 ---- a/v2v/input_ova.ml -+++ b/v2v/input_ova.ml -@@ -23,6 +23,7 @@ open Common_utils - - open Types - open Utils -+open Name_from_disk - - class input_ova ova = - let tmpdir = -@@ -186,7 +187,7 @@ object - match xpath_string "/ovf:Envelope/ovf:VirtualSystem/ovf:Name/text()" with - | None | Some "" -> - warning (f_"could not parse ovf:Name from OVF document"); -- "default" -+ name_from_disk ova - | Some name -> name in - - (* Search for memory. *) -diff --git a/v2v/name_from_disk.ml b/v2v/name_from_disk.ml -index 73caf34..9ed02ce 100644 ---- a/v2v/name_from_disk.ml -+++ b/v2v/name_from_disk.ml -@@ -24,7 +24,7 @@ let name_from_disk disk = - (* Remove the extension (or suffix), only if it's one usually - * used for disk images. *) - let suffixes = [ -- ".img"; ".qcow2"; ".raw"; ".vmdk"; -+ ".img"; ".ova"; ".qcow2"; ".raw"; ".vmdk"; - "-sda"; - ] in - let rec loop = function --- -1.8.3.1 - diff --git a/SOURCES/0190-v2v-o-glance-set-all-properties-during-creation-RHBZ.patch b/SOURCES/0190-v2v-o-glance-set-all-properties-during-creation-RHBZ.patch deleted file mode 100644 index 64c6fcc..0000000 --- a/SOURCES/0190-v2v-o-glance-set-all-properties-during-creation-RHBZ.patch +++ /dev/null @@ -1,76 +0,0 @@ -From dfbc0114d8269d05e699d9f12e3176c29eb260d5 Mon Sep 17 00:00:00 2001 -From: Pino Toscano -Date: Tue, 13 Sep 2016 15:30:52 +0200 -Subject: [PATCH] v2v: -o glance: set all properties during creation - (RHBZ#1374405) - -The glance client v1.0.0 defaults to the Image v2 API: this means that -an image can be referenced only by its UUID, and not anymore by the name -as well (which does not need to be unique). This caused our glance -invocation to set the properties for the newly created image to fail, -since we are using the name as identifier. - -Instead of first creating the image and then setting all the properties -for it, set all the properties when creating the image: other than being -simpler, it also avoid parsing the output of the 'glance image-create' -command for the UUID ('id') of the image. - -(cherry picked from commit 1497a9f722f9a3c4c75282fb19578573e3cc89db) ---- - v2v/output_glance.ml | 28 +++++++--------------------- - 1 file changed, 7 insertions(+), 21 deletions(-) - -diff --git a/v2v/output_glance.ml b/v2v/output_glance.ml -index 71f237c..d6c5727 100644 ---- a/v2v/output_glance.ml -+++ b/v2v/output_glance.ml -@@ -73,12 +73,6 @@ object - if i == 0 then source.s_name - else sprintf "%s-disk%d" source.s_name (i+1) in - -- let cmd = [ "glance"; "image-create"; "--name"; name; -- "--disk-format=" ^ target_format; -- "--container-format=bare"; "--file"; target_file ] in -- if run_command cmd <> 0 then -- error (f_"glance: image upload to glance failed, see earlier errors"); -- - (* Set the properties (ie. metadata). *) - let min_ram = source.s_memory /^ 1024L /^ 1024L in - let properties = [ -@@ -109,26 +103,18 @@ object - | x, 0 -> ("os_version", string_of_int x) :: properties - | x, y -> ("os_version", sprintf "%d.%d" x y) :: properties in - -- (* Glance doesn't appear to check the properties. *) -- let cmd = [ "glance"; "image-update"; "--min-ram"; -- Int64.to_string min_ram ] @ -+ let cmd = [ "glance"; "image-create"; "--name"; name; -+ "--disk-format=" ^ target_format; -+ "--container-format=bare"; "--file"; target_file; -+ "--min-ram"; Int64.to_string min_ram ] @ - (List.flatten - (List.map ( - fun (k, v) -> - [ "--property"; sprintf "%s=%s" k v ] - ) properties -- )) @ -- [ name ] in -- if run_command cmd <> 0 then ( -- warning (f_"glance: failed to set image properties (ignored)"); -- (* Dump out the image properties so the user can set them. *) -- eprintf "Image properties:\n"; -- eprintf " --min-ram %Ld\n" min_ram; -- List.iter ( -- fun (k, v) -> -- eprintf " --property %s=%s" (quote k) (quote v) -- ) properties -- ) -+ )) in -+ if run_command cmd <> 0 then -+ error (f_"glance: image upload to glance failed, see earlier errors"); - ) targets - end - --- -1.8.3.1 - diff --git a/SOURCES/brew-overrides.sh b/SOURCES/brew-overrides.sh index 7fcf66d..38baffe 100755 --- a/SOURCES/brew-overrides.sh +++ b/SOURCES/brew-overrides.sh @@ -10,29 +10,28 @@ set -x # The kernel package doesn't install unless xfsprogs >= 4.3.0 # is installed. -xfsprogs="$(brew -q latest-pkg rhel-7.3-candidate xfsprogs | +xfsprogs="$(brew -q latest-pkg rhel-7.4-candidate xfsprogs | awk '{print $1}')" # linux-firmware is for virt-p2v, see RHBZ#1364419 -linux_firmware="$(brew -q latest-pkg rhel-7.3-candidate linux-firmware | +linux_firmware="$(brew -q latest-pkg rhel-7.4-candidate linux-firmware | awk '{print $1}')" -# libsemanage.so.1 is needed by new selinux-policy package in 7.3. pkgs=" - copy-jdk-configs-1.1-5.el7 + hivex-1.3.10-5.8.el7 + libvirt-3.1.0-2.el7 + libselinux-2.5-9.el7 $linux_firmware - mozjs17-17.0.0-19.el7 - ocaml-4.01.0-22.7.el7 - polkit-0.112-9.el7 - systemd-219-24.el7 - supermin-5.1.16-4.el7 + ocaml-findlib-1.3.3-7.el7 + policycoreutils-2.5-12.el7 + rdma-core-13-1.el7 $xfsprogs " for pkg in $pkgs ; do - brew tag-pkg rhel-7.3-temp-override $pkg + brew tag-pkg rhel-7.4-temp-override $pkg done for pkg in $pkgs ; do - brew wait-repo rhel-7.3-build --build=$pkg + brew wait-repo rhel-7.4-build --build=$pkg done diff --git a/SOURCES/copy-patches.sh b/SOURCES/copy-patches.sh index a2940b0..48bf28f 100755 --- a/SOURCES/copy-patches.sh +++ b/SOURCES/copy-patches.sh @@ -6,7 +6,7 @@ set -e # directory. Use it like this: # ./copy-patches.sh -rhel_version=7.3 +rhel_version=7.4 # Check we're in the right directory. if [ ! -f libguestfs.spec ]; then @@ -24,13 +24,14 @@ fi # Get the base version of libguestfs. version=`grep '^Version:' libguestfs.spec | awk '{print $2}'` +tag="v$version" # Remove any existing patches. git rm -f [0-9]*.patch ||: rm -f [0-9]*.patch # Get the patches. -(cd $git_checkout; rm -f [0-9]*.patch; git format-patch -N $version) +(cd $git_checkout; rm -f [0-9]*.patch; git format-patch -N $tag) mv $git_checkout/[0-9]*.patch . # Remove any not to be applied. diff --git a/SOURCES/libguestfs-1.32.7.tar.gz.sig b/SOURCES/libguestfs-1.32.7.tar.gz.sig deleted file mode 100644 index befa469..0000000 --- a/SOURCES/libguestfs-1.32.7.tar.gz.sig +++ /dev/null @@ -1,17 +0,0 @@ ------BEGIN PGP SIGNATURE----- -Version: GnuPG v1 - -iQIcBAABAgAGBQJXqYeSAAoJEJFzj3Pht2iglTcP/3ho7mz8eIDxnXtnsgLEnC+2 -UXC32aF+CUJA+MIYAVpsrKigA4cVlFb15+ZYYUrtWtu/Dy9HM0uIepDxUSXLsYBS -rxNUV2xVMJWi6gzSHljcdzJ7mJ/wzdeoypOnm6DxMRSAEk7W0XNFqH7n5v7uKK3/ -IUpzg07BKIBo2XcdZSuv4/OugUaexfKDDskC2LE3alhYSJFMm7n47HLPhJEdMz2d -Yb1ScQggOxW8D5ghC728Hpz+ufmGhvb+obNhf+vunQUJ1pGAAeEF272DihwhxOgQ -jbp9SnVFo91Es2RiD7QN8fvuVAua50nkud6MGFg6w9LkWQazPk5ao+E7h+m6jzfY -kbDaHHD6i545TNCTL2XLIOlVwj0jKPWSvGEbtLgoFJWDzMBPHcqCaEA6jviiyEHP -hdJNSQwKD4X9gY3/tM/xv9YemlKpYizH4zDai4xlhgzYzqIJlNYr4ECvv9PC3mod -zMWXbtERMTzgttT+J/Kl2uRKAu4/HTkb6p4MOxhlgbwvXchHCWJ087R1s5bk08PO -QlivWqpA2gvoziTxzMbB7XLZR0HG6tSqnTf5DGm/1I1DhtrD79ilAnv+A3M94YZX -tTruc4qzbmoA1MSfUHR84ol9rqlk9ey/ewsPH90L8LIGBDzc746KNVyzkaOdDH7G -7qpboAH44wyaoXeUh7tm -=BISR ------END PGP SIGNATURE----- diff --git a/SOURCES/libguestfs-1.36.3.tar.gz.sig b/SOURCES/libguestfs-1.36.3.tar.gz.sig new file mode 100644 index 0000000..10265fa --- /dev/null +++ b/SOURCES/libguestfs-1.36.3.tar.gz.sig @@ -0,0 +1,16 @@ +-----BEGIN PGP SIGNATURE----- + +iQIcBAABAgAGBQJY1YWwAAoJEJFzj3Pht2ign80QAK4985NZFaRJn6cgoWtQJflH +jjxSFkNokPUrA1LS3BFcHJyCaNldBn4FzMscdWYkVhVDe2K8HOq2wdWSt8tM1fFD +A9pDMIWfdL2/t3UPDGlvf/h43mxE1y86i9LrHfKsjHUR22AGSJBrb5IUHNHS30P4 +4/4pik7t99ExDlMPHiAS4F0+Mnz22ATbVTsquewpBjB3S1jPTN5JQILY7NqAXvht +Ua74xm6luDFNyr5XnKXRMW/oUxgsMY5cLXzwbGCREodjcvdWwBwdMjAHK0dXiOqC +Y0oNF4/91wbn1yapAhR09t205A10n6J0ZswNWwEqgYQledahu7XFjkH0PRt1iDnd +0Im29uuaEZP2PABrAIy95XLKiDBiKqBGFjIcqF3fmobPS3mLxVznLynmMOtQe2dJ +gAULb/IcqonGXesL5npltAC6JPnMj9l+hFcyij+jGjBHAFF53lyq32lSvZ2gZ6K8 +B/Y9gNz2L3I7QZZCUIUxa+9KqIRndg2pDbEyJU5NOc2TEtbgo9JsVMxLtSAvDCNz +UC6XZNZ4fh8qD4sLcgpWj2YLf+s1s+DSutcdMf6WR5Qae0rGx62z2ASJrIgPng79 +zU21SxdAOfL/h9VlCAVrLJ2vSf2WS91s1rf5WYAijS2tlz885wIUqZL91Nr1ivnf +ZPMqpz6AVJXrgzDn2iQE +=3M1c +-----END PGP SIGNATURE----- diff --git a/SOURCES/yum.conf.in b/SOURCES/yum.conf.in new file mode 100644 index 0000000..b71abc9 --- /dev/null +++ b/SOURCES/yum.conf.in @@ -0,0 +1,16 @@ +[main] +cachedir=@PWD@/yum +debuglevel=1 +logfile=@PWD@/yum.log +retries=20 +obsoletes=1 +gpgcheck=0 +assumeyes=1 +reposdir=/dev/null + +[local] +name=local +baseurl=file://@PWD@/repo +failovermethod=priority +enabled=1 +gpgcheck=0 diff --git a/SPECS/libguestfs.spec b/SPECS/libguestfs.spec index 9b3c24b..3cb330f 100644 --- a/SPECS/libguestfs.spec +++ b/SPECS/libguestfs.spec @@ -13,22 +13,22 @@ Summary: Access and modify virtual machine disk images Name: libguestfs Epoch: 1 -Version: 1.32.7 -Release: 3%{?dist}.3 +Version: 1.36.3 +Release: 6%{?dist} License: LGPLv2+ # Source and patches. URL: http://libguestfs.org/ -Source0: http://libguestfs.org/download/1.32-stable/%{name}-%{version}.tar.gz +Source0: http://libguestfs.org/download/1.36-stable/%{name}-%{version}.tar.gz %if 0%{verify_tarball_signature} -Source2: http://libguestfs.org/download/1.32-stable/%{name}-%{version}.tar.gz.sig +Source1: http://libguestfs.org/download/1.36-stable/%{name}-%{version}.tar.gz.sig %endif ExclusiveArch: x86_64 %{power64} aarch64 # RHEL 7 git repository is: -# https://github.com/libguestfs/libguestfs/tree/rhel-7.3 +# https://github.com/libguestfs/libguestfs/tree/rhel-7.4 # Use 'copy-patches.sh' to copy the patches from the git repo # to the current directory. @@ -46,183 +46,35 @@ Patch0010: 0010-RHEL-7-Revert-launch-libvirt-Better-error-when-bridg.patch Patch0011: 0011-RHEL-7-Revert-appliance-add-dhcp-client-on-Mageia.patch Patch0012: 0012-RHEL-7-Revert-appliance-add-dhcpcd-and-gptfdisk-on-A.patch Patch0013: 0013-RHEL-7-Revert-appliance-Use-dhclient-or-dhcpcd-inste.patch -Patch0014: 0014-RHEL-7-v2v-Disable-unconfiguration-of-VMware-drivers.patch -Patch0015: 0015-RHEL-7-Disable-alternate-Augeas-lenses.patch -Patch0016: 0016-RHEL-7-Fix-list-of-supported-sound-cards-to-match-RH.patch -Patch0017: 0017-RHEL-7-v2v-efi-Remove-references-to-Fedora-kraxel-s-.patch -Patch0018: 0018-RHEL-7-Reject-use-of-libguestfs-winsupport-features-.patch -Patch0019: 0019-RHEL-7-daemon-umount-all-Hack-to-avoid-umount-sysroo.patch -Patch0020: 0020-RHEL-7-Fix-tests-for-libguestfs-winsupport-7.2.patch -Patch0021: 0021-RHEL-7-Revert-v2v-Add-a-support-matrix-to-the-manual.patch -Patch0022: 0022-RHEL-7-All-qemu-kvm-in-RHEL-7-supports-discard-of-qc.patch -Patch0023: 0023-RHEL-7-tests-Disable-daemon-tests-that-require-the-u.patch -Patch0024: 0024-RHEL-7-v2v-Disable-the-virt-v2v-in-place-option.patch -Patch0025: 0025-p2v-User-can-click-on-an-interface-name-to-identify-.patch -Patch0026: 0026-p2v-virt-p2v-make-disk-Make-os-version-parameter-opt.patch -Patch0027: 0027-daemon-glob-add-optarg-to-control-trailing-slash-for.patch -Patch0028: 0028-customize-add-globbing-for-delete.patch -Patch0029: 0029-p2v-tests-Don-t-supply-os-version-in-test.patch -Patch0030: 0030-appliance-Pass-quiet-option-to-kernel-when-verbose.patch -Patch0031: 0031-appliance-Quiet-some-warnings-about-missing-files.patch -Patch0032: 0032-appliance-use-bash-features-for-string-matching-in-f.patch -Patch0033: 0033-launch-Factor-out-earlyprintk-from-the-command-line.patch -Patch0034: 0034-launch-direct-Don-t-run-qemu-version.patch -Patch0035: 0035-launch-Remove-guestfs_int_print_timestamped_message-.patch -Patch0036: 0036-launch-Add-a-virtio-rng-device-to-the-guest.patch -Patch0037: 0037-appliance-When-using-verbose-mode-set-x-in-the-appli.patch -Patch0038: 0038-appliance-init-Move-cmdline-parsing-earlier.patch -Patch0039: 0039-appliance-init-Mount-selinuxfs-along-with-other-spec.patch -Patch0040: 0040-appliance-init-Don-t-run-hwclock-command.patch -Patch0041: 0041-conn-Pretend-to-be-a-serial-terminal-so-sgabios-does.patch -Patch0042: 0042-tests-qemu-Add-program-for-tracing-and-analyzing-boo.patch -Patch0043: 0043-rescue-Suggest-using-recursive-bind-mounts.patch -Patch0044: 0044-rescue-Print-chroot-suggestion-for-Linux-guests.patch -Patch0045: 0045-rescue-Fix-test-to-deal-with-new-suggest-output.patch -Patch0046: 0046-boot-analysis-Add-memsize-smp-and-append-options.patch -Patch0047: 0047-appliance-init-generate-etc-machine-id.patch -Patch0048: 0048-launch-direct-Add-a-comment-about-use-of-display-non.patch -Patch0049: 0049-launch-Only-use-sgabios-when-verbose-is-enabled.patch -Patch0050: 0050-launch-Add-a-comment-about-why-acpi-off-because-it-s.patch -Patch0051: 0051-docs-Link-to-boot-analysis-program-from-guestfs-perf.patch -Patch0052: 0052-tests-qemu-Add-boot-benchmark.patch -Patch0053: 0053-tests-qemu-boot-analysis-Display-all-times-in-ms.patch -Patch0054: 0054-tests-qemu-Standardize-test-info-printed-by-boot-tes.patch -Patch0055: 0055-tests-qemu-boot-analysis-Don-t-force-backend-direct.patch -Patch0056: 0056-launch-libvirt-Disable-virtio-rng-in-libvirt-backend.patch -Patch0057: 0057-tests-qemu-Don-t-leak-backend-variable-in-boot-analy.patch -Patch0058: 0058-tests-qemu-boot-analysis-Add-support-for-logging-lib.patch -Patch0059: 0059-tests-qemu-boot-analysis-Don-t-set-LIBVIRT_LOG_FILTE.patch -Patch0060: 0060-p2v-Allow-p2v-kernel-options-to-override-GUI-configu.patch -Patch0061: 0061-tests-boot-analysis-Add-text-to-describe-how-to-chan.patch -Patch0062: 0062-tests-Add-boot-benchmark-range-script.patch -Patch0063: 0063-v2v-Move-target_bus_assignment-to-separate-module.patch -Patch0064: 0064-v2v-Assert-fail-if-we-overwrite-an-existing-disk-in-.patch -Patch0065: 0065-v2v-target_bus_assignment-Various-refactorings.patch -Patch0066: 0066-v2v-target_bus_assignment-Assign-removables-with-slo.patch -Patch0067: 0067-tests-Add-tests-qemu-boot-benchmark-range.pl-to-EXTR.patch -Patch0068: 0068-tests-qemu-boot-analysis-Add-analysis-of-initcalls-b.patch -Patch0069: 0069-tests-qemu-boot-analysis-Port-this-program-to-aarch6.patch -Patch0070: 0070-v2v-OVF-Better-mapping-for-inspection-data-to-vmtype.patch -Patch0071: 0071-launch-Disable-USB-in-the-appliance.patch -Patch0072: 0072-launch-libvirt-Add-a-dev-urandom-based-virtio-rng-de.patch -Patch0073: 0073-launch-Don-t-initialize-all-UARTs-serial-ports.patch -Patch0074: 0074-appliance-Add-pciutils-to-the-appliance.patch -Patch0075: 0075-tests-qemu-boot-analysis-Dump-pass-data-times-in-ms-.patch -Patch0076: 0076-tests-qemu-boot-analysis-Display-libvirt-as-distinct.patch -Patch0077: 0077-launch-Add-cryptomgr.notests-to-the-appliance-comman.patch -Patch0078: 0078-utils-Move-tests-qemu-boot-analysis-etc-tools-to-new.patch -Patch0079: 0079-utils-boot-analysis-utils-boot-benchmark-Add-manual-.patch -Patch0080: 0080-utils-Add-a-README-file-describing-briefly-the-purpo.patch -Patch0081: 0081-utils-Add-README-to-EXTRA_DIST.patch -Patch0082: 0082-utils-boot-analysis-Fix-minor-typo-in-string.patch -Patch0083: 0083-boot-analysis-Make-ftrace-optional-in-the-timeline.patch -Patch0084: 0084-boot-analysis-Flush-out-debug-data-after-printing-it.patch -Patch0085: 0085-Revert-appliance-init-run-ldconfig.patch -Patch0086: 0086-appliance-Copy-etc-ld.so.cache-from-the-host-into-th.patch -Patch0087: 0087-utils-boot-analysis-Make-handling-of-first-kernel-me.patch -Patch0088: 0088-utils-boot-analysis-Add-magic-asserts-to-some-struct.patch -Patch0089: 0089-utils-boot-analysis-Avoid-overflow-when-comparing-la.patch -Patch0090: 0090-appliance-Reenable-ACPI.patch -Patch0091: 0091-appliance-Find-udevd-a-bit-faster.patch -Patch0092: 0092-utils-boot-analysis-Make-insmod-message-handling-a-b.patch -Patch0093: 0093-v2v-handle-subfolders-in-ova-files.patch -Patch0094: 0094-v2v-Add-test-v2v-i-ova-subfolders-test-files-to-EXTR.patch -Patch0095: 0095-p2v-Add-xterm-to-the-virt-p2v-ISO.patch -Patch0096: 0096-p2v-Add-verbose-option-to-virt-p2v-make-disk-kicksta.patch -Patch0097: 0097-mllib-Add-bindings-for-makedev-3-major-3-and-minor-3.patch -Patch0098: 0098-mllib-Add-Common_utils.is_partition-function.patch -Patch0099: 0099-builder-Warn-if-output-is-a-host-partition-RHBZ-1342.patch -Patch0100: 0100-p2v-Add-XTerm-button-which-launches-a-terminal-windo.patch -Patch0101: 0101-p2v-Place-conversion-server-name-and-port-side-by-si.patch -Patch0102: 0102-mllib-Fix-other-places-where-Dev_t-module-must-be-li.patch -Patch0103: 0103-p2v-Add-more-authors-who-have-worked-on-virt-v2v-and.patch -Patch0104: 0104-customize-Add-uninstall-operation-RHBZ-1343375.patch -Patch0105: 0105-p2v-Print-full-curl-error-when-failing-to-fetch-SSH-.patch -Patch0106: 0106-mllib-Use-Unix.F_OK-instead-of-plain-F_OK.patch -Patch0107: 0107-p2v-ssh-Print-ssh-error-if-user-gives-invalid-conver.patch -Patch0108: 0108-p2v-Don-t-allow-password-SSH-identity-URL-fields-to-.patch -Patch0109: 0109-p2v-Disable-the-sudo-button-when-the-username-is-roo.patch -Patch0110: 0110-p2v-Add-a-dialog-confirming-the-user-really-means-to.patch -Patch0111: 0111-virt-tools-Add-common-colours-option.patch -Patch0112: 0112-p2v-Use-virt-v2v-colours-option-support-colour-in-th.patch -Patch0113: 0113-p2v-Use-a-wrapper-script-instead-of-long-virt-v2v-co.patch -Patch0114: 0114-p2v-Don-t-display-debugging-messages-in-the-run-dial.patch -Patch0115: 0115-p2v-Use-a-monospace-font-for-the-run-dialog.patch -Patch0116: 0116-p2v-Display-up-to-50-lines-of-the-virt-v2v-conversio.patch -Patch0117: 0117-p2v-Don-t-display-libvirt-XML-and-wrapper-script-on-.patch -Patch0118: 0118-p2v-Poll-to-make-Cancel-Conversion-button-more-respo.patch -Patch0119: 0119-p2v-Gtk-3-workaround-for-RHEL-7.patch -Patch0120: 0120-RHEL-7-v2v-Remove-dcpath-option-from-manual-page-RHB.patch -Patch0121: 0121-v2v-Fix-conversion-of-floppy-removable-devices-RHBZ-.patch -Patch0122: 0122-v2v-Add-a-regression-test-for-floppy-assignment-RHBZ.patch -Patch0123: 0123-p2v-improve-error-message-for-sudo-with-password.patch -Patch0124: 0124-p2v-Force-bash-as-the-remote-shell.patch -Patch0125: 0125-p2v-Set-LANG-C-in-the-remote-shell-so-we-can-match-o.patch -Patch0126: 0126-sparsify-Move-statvfs-wrapper-function-to-mllib.patch -Patch0127: 0127-v2v-Move-calculation-of-overlay-directory-to-common-.patch -Patch0128: 0128-v2v-Rename-check_free_space-check_guest_free_space.patch -Patch0129: 0129-v2v-Refuse-to-convert-if-1GB-of-free-space-in-tempor.patch -Patch0130: 0130-p2v-Make-the-sudo-error-message-actionable.patch -Patch0131: 0131-p2v-ssh-Improve-consistency-of-error-messages.patch -Patch0132: 0132-inspect-get-windows-drive-letters-for-GPT-disks.patch -Patch0133: 0133-p2v-Refactor-into-get_blockdev_size-and-get_blockdev.patch -Patch0134: 0134-p2v-Combine-size-model-columns-into-the-device-colum.patch -Patch0135: 0135-p2v-Display-serial-number-of-fixed-disks-RHBZ-855058.patch -Patch0136: 0136-p2v-Make-the-conversion-dialog-slightly-higher.patch -Patch0137: 0137-p2v-Fix-timeout-error-when-connecting-to-unresponsiv.patch -Patch0138: 0138-p2v-virt-p2v-make-disk-passes-through-no-warn-if-par.patch -Patch0139: 0139-p2v-Add-install-option-to-virt-p2v-make-disk-virt-p2.patch -Patch0140: 0140-p2v-Add-less-package-to-the-ISO.patch -Patch0141: 0141-p2v-Remove-trailing-n-from-fixed-disks-device-box.patch -Patch0142: 0142-p2v-Add-more-utilities-to-the-virt-p2v-ISO.patch -Patch0143: 0143-utils-Move-ansi_-functions-to-header-guestfs-interna.patch -Patch0144: 0144-p2v-Colourize-kernel-conversion-status-messages-from.patch -Patch0145: 0145-p2v-Use-scp-to-copy-the-files-to-remote-debugging-di.patch -Patch0146: 0146-p2v-ssh-Set-cooked-mode-on-the-ssh-session-which-run.patch -Patch0147: 0147-p2v-Send-C-to-remote-end-to-cancel-the-conversion.patch -Patch0148: 0148-p2v-Remove-the-Enable-debugging-option-v-p2v.debug.patch -Patch0149: 0149-p2v-Remove-p2v.debug-option-from-test-command-lines.patch -Patch0150: 0150-v2v-Fix-documentation-in-place-I-in-place.patch -Patch0151: 0151-v2v-Add-support-for-Win2016-virtio-drivers.patch -Patch0152: 0152-v2v-Move-augeas_debug_errors-renamed-debug_augeas_er.patch -Patch0153: 0153-New-API-selinux_relabel-SELinux-relabel-parts-of-the.patch -Patch0154: 0154-tests-Add-a-test-of-the-setfiles-API.patch -Patch0155: 0155-customize-Add-module-for-doing-SELinux-relabel-of-fi.patch -Patch0156: 0156-builder-Use-virt-sysprep-selinux-relabel-when-prepar.patch -Patch0157: 0157-lib-Deprecate-old-SELinux-APIs-rewrite-SELinux-docum.patch -Patch0158: 0158-v2v-linux-Use-new-SELinux_relabel-module-to-relabel-.patch -Patch0159: 0159-Revert-p2v-Disable-SELinux-in-virt-p2v-make-disk.patch -Patch0160: 0160-mllib-move-which-and-its-exception-from-dib.patch -Patch0161: 0161-mllib-check-for-executable-existance-in-run_command-.patch -Patch0162: 0162-podcheck-Check-tool-help-output.patch -Patch0163: 0163-mllib-move-_exit-from-v2v-as-Exit-module.patch -Patch0164: 0164-dib-rework-run-of-extra-data.d-hooks-RHBZ-1362354.patch -Patch0165: 0165-mllib-_exit-should-return-a.patch -Patch0166: 0166-sparsify-Exit-with-error-code-3-if-fstrim-is-not-sup.patch -Patch0167: 0167-daemon-fstrim-Turn-discard-operation-is-not-supporte.patch -Patch0168: 0168-sparsify-Warn-instead-of-error-if-a-filesystem-canno.patch -Patch0169: 0169-sparsify-Add-a-regression-test-for-RHBZ-1364347.patch -Patch0170: 0170-p2v-Fix-s-is-are-in-GUI-message.patch -Patch0171: 0171-v2v-Make-fstrim-warning-clearer-RHBZ-1366456.patch -Patch0172: 0172-v2v-Add-o-discard-option-when-fstrimming.patch -Patch0173: 0173-v2v-OVMF-is-now-fully-open-source-fix-the-man-page.patch -Patch0174: 0174-Generate-the-lists-of-UEFI-firmware-paths.patch -Patch0175: 0175-v2v-Use-OVMF-secure-boot-file-RHBZ-1367615.patch -Patch0176: 0176-aarch64-uefi-Fix-the-build-on-aarch64.patch -Patch0177: 0177-RHEL-7-p2v-Fix-build-warning.patch -Patch0178: 0178-lib-Don-t-assert-fail-if-port-is-missing-in-XML-RHBZ.patch -Patch0179: 0179-tests-Add-a-regression-test-for-RHBZ-1370424.patch -Patch0180: 0180-tests-add-rhbz1370424.xml-to-EXTRA_DIST.patch -Patch0181: 0181-inspect-change-is_root-flag-into-enum.patch -Patch0182: 0182-inspect-mark-CoreOS-usr-partitions-with-own-USR-role.patch -Patch0183: 0183-inspect-fix-existance-check-of-dev-mapper-devices.patch -Patch0184: 0184-inspect-gather-info-from-usr-filesystems-as-well-RHB.patch -Patch0185: 0185-appliance-Disable-EDD-edd-off-RHBZ-1404287.patch -Patch0186: 0186-v2v-o-vdsm-Add-vdsm-compat-flag.-o-rhev-Drop-support.patch -Patch0187: 0187-virt-v2v-Support-for-ova-exported-from-AWS-RHBZ-1371.patch -Patch0188: 0188-v2v-i-disk-Move-code-that-creates-name-from-disk-to-.patch -Patch0189: 0189-v2v-i-ova-Derive-the-name-from-the-OVA-filename.patch -patch0190: 0190-v2v-o-glance-set-all-properties-during-creation-RHBZ.patch +Patch0014: 0014-RHEL-7-Disable-alternate-Augeas-lenses.patch +Patch0015: 0015-RHEL-7-Fix-list-of-supported-sound-cards-to-match-RH.patch +Patch0016: 0016-RHEL-7-v2v-efi-Remove-references-to-Fedora-kraxel-s-.patch +Patch0017: 0017-RHEL-7-Reject-use-of-libguestfs-winsupport-features-.patch +Patch0018: 0018-RHEL-7-daemon-umount-all-Hack-to-avoid-umount-sysroo.patch +Patch0019: 0019-RHEL-7-Fix-tests-for-libguestfs-winsupport-7.2.patch +Patch0020: 0020-RHEL-7-Revert-v2v-Add-a-support-matrix-to-the-manual.patch +Patch0021: 0021-RHEL-7-All-qemu-kvm-in-RHEL-7-supports-discard-of-qc.patch +Patch0022: 0022-RHEL-7-tests-Disable-daemon-tests-that-require-the-u.patch +Patch0023: 0023-RHEL-7-v2v-Disable-the-virt-v2v-in-place-option.patch +Patch0024: 0024-RHEL-7-v2v-Remove-dcpath-option-RHBZ-1315237-RHBZ-14.patch +Patch0025: 0025-RHEL-7-v2v-i-disk-force-VNC-as-display-RHBZ-1372671.patch +Patch0026: 0026-RHEL-7-v2v-do-not-mention-SUSE-Xen-hosts-RHBZ-143020.patch +Patch0027: 0027-sysprep-Remove-DHCP_HOSTNAME-from-ifcfg-files-RHBZ-1.patch +Patch0028: 0028-p2v-v2v-Ensure-the-full-version-is-always-available-.patch +Patch0029: 0029-p2v-Run-fewer-scp-commands.patch +Patch0030: 0030-p2v-Fix-list-of-files-in-documentation.patch +Patch0031: 0031-p2v-tests-Fix-fake-scp-command-so-it-can-handle-mult.patch +Patch0032: 0032-v2v-windows-convert-fix-virtio-block-driver-installa.patch +Patch0033: 0033-v2v-o-qemu-Fix-creation-of-ICH6-sound-device.patch +Patch0034: 0034-ocaml-Add-Bytes.sub_string-function-to-Bytes-compat-.patch +Patch0035: 0035-mllib-Add-Char.hexdigit-function.patch +Patch0036: 0036-v2v-Implement-i-vmx-to-read-VMware-vmx-files-directl.patch +Patch0037: 0037-v2v-tests-Fix-i-vmx-test-so-it-is-more-stable.patch +Patch0038: 0038-v2v-o-rhv-Quote-parameter-to-rm-rf.patch +Patch0039: 0039-v2v-windows-Install-both-legacy-and-modern-virtio-ke.patch +Patch0040: 0040-v2v-o-rhv-Add-Windows-2016-Server-type-in-OVF-output.patch +Patch0041: 0041-daemon-lvm-Pass-yes-option-to-force-pvresize-RHBZ-14.patch +Patch0042: 0042-resize-make-sure-the-input-disk-is-read-only.patch # Use git for patch management. BuildRequires: git @@ -230,15 +82,39 @@ BuildRequires: git # Run autotools after applying the patches. BuildRequires: autoconf, automake, libtool, gettext-devel -# Basic build requirements: -BuildRequires: perl-macros +# Replacement README file for RHEL users. +Source4: README-replacement.in + +# Guestfish colour prompts. +Source5: guestfish.sh + +# Used to build the supermin appliance in Koji. +Source6: yum.conf.in + +# Keyring used to verify tarball signature. +%if 0%{verify_tarball_signature} +Source7: libguestfs.keyring +%endif + +# RHSRVANY and RHEV-APT, used for Windows virt-v2v conversions. +# RHSRVANY is built from source under Fedora from +# mingw32-srvany-1.0-15.20150115gitfd659e77.fc23.noarch +# RHEV-APT is taken from the RHEV Tools CD +# See https://bugzilla.redhat.com/show_bug.cgi?id=1186850 +Source96: rhsrvany.exe +Source97: RHEV-Application-Provisioning-Tool.exe_4.12 + +Source98: brew-overrides.sh +Source99: copy-patches.sh + +# Basic build requirements for the library and virt tools. +BuildRequires: gcc +BuildRequires: supermin5-devel >= 5.1.16-2 +BuildRequires: hivex-devel >= 1.3.10-5.8.el7 BuildRequires: perl(Pod::Simple) BuildRequires: perl(Pod::Man) BuildRequires: /usr/bin/pod2text -BuildRequires: supermin5-devel >= 5.1.16-2 -BuildRequires: hivex-devel -BuildRequires: perl(Win::Hivex) -BuildRequires: perl(Win::Hivex::Regedit) +BuildRequires: po4a BuildRequires: augeas-devel BuildRequires: readline-devel BuildRequires: genisoimage @@ -251,7 +127,6 @@ BuildRequires: fuse, fuse-devel BuildRequires: pcre-devel BuildRequires: file-devel BuildRequires: libvirt-devel -BuildRequires: po4a BuildRequires: gperf BuildRequires: flex BuildRequires: bison @@ -261,11 +136,6 @@ BuildRequires: libconfig-devel BuildRequires: xz-devel BuildRequires: zip BuildRequires: unzip -# Build using OCaml with fix for CVE-2015-8869. -BuildRequires: ocaml >= 4.01.0-22.7.el7 -BuildRequires: ocaml-ocamldoc -BuildRequires: ocaml-findlib-devel -BuildRequires: ocaml-gettext-devel BuildRequires: systemd-units BuildRequires: netpbm-progs BuildRequires: icoutils @@ -274,8 +144,6 @@ BuildRequires: icoutils BuildRequires: libvirt-daemon-kvm %endif #BuildRequires: perl(Expect) -BuildRequires: lua -BuildRequires: lua-devel BuildRequires: libacl-devel BuildRequires: libcap-devel #BuildRequires: libldm-devel @@ -286,12 +154,27 @@ BuildRequires: /usr/bin/ping BuildRequires: /usr/bin/wget BuildRequires: curl BuildRequires: xz -BuildRequires: gtk2-devel +BuildRequires: gtk3-devel +BuildRequires: dbus-devel +BuildRequires: /usr/bin/qemu-img +BuildRequires: perl(Win::Hivex) +BuildRequires: perl(Win::Hivex::Regedit) %if 0%{verify_tarball_signature} BuildRequires: gnupg2 %endif + +# For language bindings. +# Build using OCaml with fix for CVE-2015-8869. +BuildRequires: ocaml >= 4.01.0-22.7.el7 +BuildRequires: ocaml-ocamldoc +# Make sure to get the performance fix for findlib. +BuildRequires: ocaml-findlib-devel >= 1.3.3-7.el7 +BuildRequires: ocaml-gettext-devel +BuildRequires: lua +BuildRequires: lua-devel +BuildRequires: perl-devel +BuildRequires: perl-macros BuildRequires: perl(Sys::Virt) -BuildRequires: /usr/bin/qemu-img BuildRequires: perl(Test::More) BuildRequires: perl(Test::Pod) >= 1.00 BuildRequires: perl(Test::Pod::Coverage) >= 1.00 @@ -299,6 +182,7 @@ BuildRequires: perl(Module::Build) BuildRequires: perl(ExtUtils::CBuilder) BuildRequires: perl(Locale::TextDomain) BuildRequires: python-devel +BuildRequires: libvirt-python BuildRequires: ruby-devel BuildRequires: rubygem-rake BuildRequires: rubygem(minitest) @@ -323,7 +207,7 @@ BuildRequires: gjs # for f in `cat appliance/packagelist`; do echo $f; done | sort -u # However you have to edit the list down to packages which exist in # current RHEL, since supermin ignores non-existent packages. -BuildRequires: acl attr augeas-libs bash binutils btrfs-progs bzip2 coreutils cpio cryptsetup diffutils dosfstools e2fsprogs file findutils gawk gdisk genisoimage grep gzip hivex iproute iputils kernel kmod less libcap libselinux libxml2 lsof lsscsi lvm2 lzop mdadm openssh-clients parted pcre policycoreutils procps psmisc rsync scrub sed strace systemd tar udev util-linux vim-minimal xfsprogs xz yajl +BuildRequires: acl attr augeas-libs bash binutils btrfs-progs bzip2 coreutils cpio cryptsetup curl diffutils dosfstools e2fsprogs file findutils gawk gdisk genisoimage grep gzip hivex iproute iputils kernel kmod kpartx less libcap libselinux libxml2 lsof lsscsi lvm2 lzop mdadm openssh-clients parted pciutils pcre policycoreutils procps psmisc qemu-img rsync scrub sed squashfs-tools strace systemd tar udev util-linux vim-minimal which xfsprogs xz yajl %ifarch x86_64 BuildRequires: gfs2-utils %endif @@ -339,7 +223,7 @@ Requires: supermin5 >= 5.1.16-2 Requires: augeas-libs Requires: libacl Requires: libcap -Requires: hivex +Requires: hivex >= 1.3.10-5.8.el7 Requires: pcre Requires: libselinux Requires: systemd-libs @@ -348,9 +232,14 @@ Requires: yajl # RHBZ#1211321 Requires: kernel +# Older lvmetad "forgets" VGs if you change their UUID. libguestfs +# since 1.34 enables lvmetad. So we must ensure we have new enough +# LVM: +Requires: lvm2 >= 7:2.02.166-1.el7 + # For core inspection API. Requires: libdb-utils -Requires: libosinfo +Requires: osinfo-db # For core mount-local (FUSE) API. Requires: fuse @@ -364,41 +253,22 @@ Requires: libvirt-daemon-kvm >= 1.2.8-3 %endif %ifarch aarch64 Requires: AAVMF +# RHBZ#1177910 +# RHBZ#1463646 +Requires: qemu-kvm %endif -%ifarch aarch64 %{power64} +%ifarch %{power64} # RHBZ#1177910 Requires: qemu-kvm-rhev %endif +# https://fedoraproject.org/wiki/Packaging:No_Bundled_Libraries#Packages_granted_exceptions +Provides: bundled(gnulib) + # Conflicts with libguestfs-winsupport from RHEL 7.0. You need to # use the RHEL 7.2+ package. Conflicts: libguestfs-winsupport < 7.2 -# Replacement README file for RHEL users. -Source4: README-replacement.in - -# Guestfish colour prompts. -Source5: guestfish.sh - -# RHSRVANY and RHEV-APT, used for Windows virt-v2v conversions. -# RHSRVANY is built from source under Fedora from -# mingw32-srvany-1.0-15.20150115gitfd659e77.fc23.noarch -# RHEV-APT is taken from the RHEV Tools CD -# See https://bugzilla.redhat.com/show_bug.cgi?id=1186850 -Source6: rhsrvany.exe -Source7: RHEV-Application-Provisioning-Tool.exe_4.12 - -Source98: brew-overrides.sh -Source99: copy-patches.sh - -# Keyring used to verify tarball signature. -%if 0%{verify_tarball_signature} -Source8: libguestfs.keyring -%endif - -# https://fedoraproject.org/wiki/Packaging:No_Bundled_Libraries#Packages_granted_exceptions -Provides: bundled(gnulib) - %description Libguestfs is a library for accessing and modifying virtual machine @@ -423,8 +293,8 @@ The basic subpackages are: libguestfs-tools-c only the subset of virt tools written in C (for reduced dependencies) virt-dib safe and secure diskimage-builder replacement - virt-v2v convert virtual or physical machines to run - on KVM (also known as V2V and P2V) + virt-v2v convert virtual machines to run on KVM (V2V) + virt-p2v-maker convert physical machines to run on KVM (P2V) For enhanced features, install: @@ -434,9 +304,13 @@ For enhanced features, install: libguestfs-rsync rsync to/from guest filesystems libguestfs-xfs adds XFS support -Language bindings: +For developers: libguestfs-devel C/C++ header files and library + libguestfs-benchmarking Benchmarking utilities + +Language bindings: + libguestfs-gobject-devel GObject bindings and GObject Introspection libguestfs-java-devel Java bindings lua-guestfs Lua bindings @@ -446,6 +320,20 @@ Language bindings: ruby-libguestfs Ruby bindings +%ifarch aarch64 x86_64 +%package benchmarking +Summary: Benchmarking utilities for %{name} +Requires: %{name} = %{epoch}:%{version}-%{release} + + +%description benchmarking +%{name}-benchmarking contains utilities for benchmarking and +performance analysis of %{name}, and also for general +understanding of the performance of the kernel and qemu when booting +small appliances. +%endif + + %package devel Summary: Development tools and libraries for %{name} Requires: %{name} = %{epoch}:%{version}-%{release} @@ -643,6 +531,8 @@ Virt-sparsify makes virtual machine disk images sparse (thin-provisioned). Virt-sysprep lets you reset or unconfigure virtual machines in preparation for cloning them. +Virt-tail follows (tails) a log file within a guest, like 'tail -f'. + Virt-tar-in and virt-tar-out are archive, backup and upload tools for virtual machines. These replace the deprecated program virt-tar. @@ -674,14 +564,6 @@ Requires: %{name}-tools-c = %{epoch}:%{version}-%{release} # (RHBZ#1226683, RHBZ#1226684, RHBZ#1226697). Requires: qemu-kvm >= 1.5.3-92.el7 -# First version of libvirt which enabled Secure Boot, required for -# conversion of UEFI guests (RHBZ#1367615). -# -# Note that qemu-kvm-rhev is also required for UEFI guest conversion, -# but we don't make it a hard dependency in order to allow more common -# conversions using basic qemu-kvm. -Requires: libvirt-client >= 2.0.0-5.el7 - # For Windows conversions. %ifarch x86_64 aarch64 Requires: libguestfs-winsupport >= 7.2 @@ -692,16 +574,51 @@ Requires: gzip Requires: unzip Requires: curl Requires: /usr/bin/virsh -# 'strip' binary is required by virt-p2v-make-kickstart. -Requires: binutils + +# Ensure the UEFI firmware is available, to properly convert +# EFI guests (RHBZ#1429643). +%ifarch x86_64 +Requires: OVMF +%endif +%ifarch aarch64 +Requires: AAVMF +%endif %description -n virt-v2v -Virt-v2v and virt-p2v are tools that convert virtual machines from -non-KVM hypervisors, or physical machines, to run under KVM. +Virt-v2v converts virtual machines from non-KVM hypervisors +to run under KVM. + +To convert physical machines, see the virt-p2v-maker package. %endif +%package -n virt-p2v-maker +Summary: Convert a physical machine to run on KVM +License: GPLv2+ + +Requires: gawk +Requires: gzip + +# virt-p2v-make-disk runs virt-builder: +Requires: %{name}-tools-c = %{epoch}:%{version}-%{release} + +# virt-p2v-make-kickstart runs strip: +Requires: binutils + + +%description -n virt-p2v-maker +Virt-p2v converts (virtualizes) physical machines so they can be run +as virtual machines under KVM. + +This package contains the tools needed to make a virt-p2v boot CD or +USB key which is booted on the physical machine to perform the +conversion. You also need virt-v2v installed somewhere else to +complete the conversion. + +To convert virtual machines from other hypervisors, see virt-v2v. + + %package bash-completion Summary: Bash tab-completion scripts for %{name} tools BuildArch: noarch @@ -771,7 +688,7 @@ ruby-%{name} contains Ruby bindings for %{name}. %package java Summary: Java bindings for %{name} Requires: %{name} = %{epoch}:%{version}-%{release} -Requires: java-headless >= 1.5.0 +Requires: java-headless >= 1.7.0 Requires: jpackage-utils %description java @@ -869,7 +786,7 @@ for %{name}. %prep %if 0%{verify_tarball_signature} tmphome="$(mktemp -d)" -gpgv2 --homedir "$tmphome" --keyring %{SOURCE8} %{SOURCE2} %{SOURCE0} +gpgv2 --homedir "$tmphome" --keyring %{SOURCE7} %{SOURCE1} %{SOURCE0} %endif %setup -q @@ -910,28 +827,12 @@ ip route list ||: if ping -c 3 -w 20 8.8.8.8 && wget http://libguestfs.org -O /dev/null; then extra= else - mkdir repo + mkdir cachedir repo # -n 1 because of RHBZ#980502. - find /var/cache/yum -type f -name '*.rpm' -print0 | xargs -0 -n 1 cp -t repo + find /var/cache/{dnf,yum} -type f -name '*.rpm' -print0 | \ + xargs -0 -n 1 cp -t repo createrepo repo - cat > yum.conf < yum.conf extra=--with-supermin-packager-config=$(pwd)/yum.conf fi @@ -985,7 +886,7 @@ export LIBGUESTFS_DEBUG=1 export LIBGUESTFS_TRACE=1 export LIBVIRT_DEBUG=1 -if ! make quickcheck; then +if ! make quickcheck QUICKCHECK_TEST_TOOL_ARGS="-t 1200"; then cat $HOME/.cache/libvirt/qemu/log/* exit 1 fi @@ -1043,42 +944,37 @@ function move_to echo "$1" >> "$2" } move_to curl zz-packages-dib +move_to kpartx zz-packages-dib +move_to qemu-img zz-packages-dib move_to which zz-packages-dib %ifarch x86_64 move_to gfs2-utils zz-packages-gfs2 %endif move_to iputils zz-packages-rescue move_to openssh-clients zz-packages-rescue +move_to pciutils zz-packages-rescue move_to strace zz-packages-rescue move_to vim-minimal zz-packages-rescue move_to rsync zz-packages-rsync move_to xfsprogs zz-packages-xfs popd -# If there is a bogus dependency on kernel-rt, rename it to 'kernel' -# instead. This happens when the version of kernel-rt in brew is -# greater than the version of kernel (kernel-rt 'Provides: kernel'). -pushd $RPM_BUILD_ROOT%{_libdir}/guestfs/supermin.d -sed 's/^kernel-rt$/kernel/' < packages > packages-t -mv packages-t packages -popd - # Guestfish colour prompts. mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/profile.d install -m 0644 %{SOURCE5} $RPM_BUILD_ROOT%{_sysconfdir}/profile.d # Virt-tools data directory. mkdir -p $RPM_BUILD_ROOT%{_datadir}/virt-tools -cp %{SOURCE6} $RPM_BUILD_ROOT%{_datadir}/virt-tools/rhsrvany.exe -cp %{SOURCE7} $RPM_BUILD_ROOT%{_datadir}/virt-tools/rhev-apt.exe +cp %{SOURCE96} $RPM_BUILD_ROOT%{_datadir}/virt-tools/rhsrvany.exe +cp %{SOURCE97} $RPM_BUILD_ROOT%{_datadir}/virt-tools/rhev-apt.exe %ifarch %{power64} # We don't ship virt-v2v on POWER (RHBZ#1287826). rm $RPM_BUILD_ROOT%{_bindir}/virt-p2v* rm $RPM_BUILD_ROOT%{_bindir}/virt-v2v* -rm $RPM_BUILD_ROOT%{_libexecdir}/virt-p2v rm $RPM_BUILD_ROOT%{_mandir}/man1/virt-p2v* rm $RPM_BUILD_ROOT%{_mandir}/man1/virt-v2v* +rm -r $RPM_BUILD_ROOT%{_libdir}/virt-p2v rm -r $RPM_BUILD_ROOT%{_datadir}/virt-p2v rm -r $RPM_BUILD_ROOT%{_datadir}/virt-tools %endif @@ -1090,9 +986,25 @@ rm -rf $RPM_BUILD_ROOT%{_libdir}/ocaml/v2v_test_harness rm -rf $RPM_BUILD_ROOT%{_libdir}/ocaml/stublibs/dllv2v_test_harness* rm -f $RPM_BUILD_ROOT%{_mandir}/man1/virt-v2v-test-harness.1* +%ifnarch %{power64} +# Delete kiwi tools. +rm $RPM_BUILD_ROOT%{_bindir}/virt-p2v-make-kiwi +rm $RPM_BUILD_ROOT%{_mandir}/man1/virt-p2v-make-kiwi.1* +%endif + # Remove the .gitignore file from ocaml/html which will be copied to docdir. rm ocaml/html/.gitignore +%ifarch aarch64 x86_64 +# Copy the benchmarking tools and man pages, since upstream doesn't +# install them by default. NB Don't install the libtool wrapper scripts. +libtool --mode=install install -m 0755 utils/boot-analysis/boot-analysis $RPM_BUILD_ROOT%{_bindir}/libguestfs-boot-analysis +libtool --mode=install install -m 0755 utils/boot-benchmark/boot-benchmark $RPM_BUILD_ROOT%{_bindir}/libguestfs-boot-benchmark +install -m 0755 utils/boot-benchmark/boot-benchmark-range.pl $RPM_BUILD_ROOT%{_bindir}/libguestfs-boot-benchmark-range.pl +install -m 0644 utils/boot-analysis/boot-analysis.1 $RPM_BUILD_ROOT%{_mandir}/man1/libguestfs-boot-analysis.1 +install -m 0644 utils/boot-benchmark/boot-benchmark.1 $RPM_BUILD_ROOT%{_mandir}/man1/libguestfs-boot-benchmark.1 +%endif + # Find locale files. %find_lang %{name} @@ -1113,22 +1025,33 @@ rm ocaml/html/.gitignore %exclude %{_libdir}/guestfs/supermin.d/zz-packages-* %{_libdir}/libguestfs.so.* %{_mandir}/man1/guestfs-faq.1* -%{_mandir}/man1/guestfs-hacking.1* -%{_mandir}/man1/guestfs-internals.1* %{_mandir}/man1/guestfs-performance.1* %{_mandir}/man1/guestfs-recipes.1* %{_mandir}/man1/guestfs-release-notes.1* %{_mandir}/man1/guestfs-security.1* -%{_mandir}/man1/guestfs-testing.1* %{_mandir}/man1/libguestfs-test-tool.1* +%ifarch aarch64 x86_64 +%files benchmarking +%{_bindir}/libguestfs-boot-analysis +%{_bindir}/libguestfs-boot-benchmark +%{_bindir}/libguestfs-boot-benchmark-range.pl +%{_mandir}/man1/libguestfs-boot-analysis.1* +%{_mandir}/man1/libguestfs-boot-benchmark.1* +%endif + + %files devel %doc AUTHORS BUGS ChangeLog.gz HACKING TODO README %doc examples/*.c %doc installed-docs/* %{_libdir}/libguestfs.so %{_sbindir}/libguestfs-make-fixed-appliance +%{_mandir}/man1/guestfs-building.1* +%{_mandir}/man1/guestfs-hacking.1* +%{_mandir}/man1/guestfs-internals.1* +%{_mandir}/man1/guestfs-testing.1* %{_mandir}/man1/libguestfs-make-fixed-appliance.1* %{_mandir}/man3/guestfs.3* %{_mandir}/man3/guestfs-examples.3* @@ -1212,6 +1135,8 @@ rm ocaml/html/.gitignore %{_mandir}/man1/virt-sparsify.1* %{_bindir}/virt-sysprep %{_mandir}/man1/virt-sysprep.1* +%{_bindir}/virt-tail +%{_mandir}/man1/virt-tail.1* %{_bindir}/virt-tar-in %{_mandir}/man1/virt-tar-in.1* %{_bindir}/virt-tar-out @@ -1234,18 +1159,22 @@ rm ocaml/html/.gitignore %ifnarch %{power64} %files -n virt-v2v %doc COPYING README v2v/TODO -%{_libexecdir}/virt-p2v -%{_bindir}/virt-p2v-make-disk -%{_bindir}/virt-p2v-make-kickstart %{_bindir}/virt-v2v %{_bindir}/virt-v2v-copy-to-local +%{_mandir}/man1/virt-v2v.1* +%{_mandir}/man1/virt-v2v-copy-to-local.1* +%{_datadir}/virt-tools + + +%files -n virt-p2v-maker +%doc COPYING README +%{_bindir}/virt-p2v-make-disk +%{_bindir}/virt-p2v-make-kickstart %{_mandir}/man1/virt-p2v.1* %{_mandir}/man1/virt-p2v-make-disk.1* %{_mandir}/man1/virt-p2v-make-kickstart.1* -%{_mandir}/man1/virt-v2v.1* -%{_mandir}/man1/virt-v2v-copy-to-local.1* %{_datadir}/virt-p2v -%{_datadir}/virt-tools +%{_libdir}/virt-p2v %endif @@ -1253,6 +1182,7 @@ rm ocaml/html/.gitignore %dir %{_datadir}/bash-completion/completions %{_datadir}/bash-completion/completions/guestfish %{_datadir}/bash-completion/completions/guestmount +%{_datadir}/bash-completion/completions/guestunmount %{_datadir}/bash-completion/completions/virt-* @@ -1352,22 +1282,124 @@ rm ocaml/html/.gitignore %changelog -* Fri May 19 2017 Richard W.M. Jones - 1:1.32.7-3.el7_3.3 -- v2v: -o glance: set all properties during creation - resolves: rhbz#1452570 - -* Thu Dec 22 2016 Pino Toscano - 1:1.32.7-3.el7_3.2 -- v2v: improve import compatibility with OVAs produced by AWS - resolves: rhbz#1408124 -- Avoid spurious dependency on kernel-rt. - -* Wed Dec 21 2016 Pino Toscano - 1:1.32.7-3.el7_3.1 +* Thu Jun 22 2017 Pino Toscano - 1:1.36.3-6 +- Rebase to libguestfs 1.36 in RHEL 7.4. + resolves: rhbz#1359086 +- v2v: always use names for libvirt pools + resolves: rhbz#1141631 +- v2v: correctly find GRUB in RHEL UEFI guests +- v2v: uninstall VMware tools packages from guests + resolves: rhbz#1155150 +- v2v: install RHEV-APT only when using -o rhev/-o vdsm + resolves: rhbz#1161019 +- New API: btrfs-filesystem-show + resolves: rhbz#1164765 +- p2v: always enable debugging when running virt-v2v + resolves: rhbz#1167623 +- libguestfs prefers virtio-pci on aarch64 + resolves: rhbz#1237250 +- v2v: make sure to copy all the driver files on Windows + resolves: rhbz#1255610 +- Better tolerate corrupted Windows hivex; bump the hivex BuildRequires and + Requires to >= 1.3.10-5.8.el7 + resolves: rhbz#1311890 +- v2v: ignore all the environment variables for proxy when exporting from + vCenter + resolves: rhbz#1354507 +- virt-sysprep can deal with full-LUKS encrypted guests + resolves: rhbz#1362649 +- All the tools have bash completion scripts. + resolves: rhbz#1367738 +- v2v: do not remove Processor and Intelppm nodes in Windows guests + resolves: rhbz#1372668 +- Fix SELinux relabelling in old RHEL 6 guests, by adjusting a broken + regular expression in file_contexts file + resolves: rhbz#1374232 +- v2v: set all the properties on creation when exporting to Glance + resolves: rhbz#1374405 +- v2v: set hw_video_model when exporting to Glance + resolves: rhbz#1374651 +- v2v: fix OVA conversion as root using the libvirt backend + resolves: rhbz#1375157 +- Various improvements and fixes to the documentation + resolves: rhbz#1377081 + resolves: rhbz#1390876 + resolves: rhbz#1398070 + resolves: rhbz#1425306 +- v2v: support and + resolves: rhbz#1378022 +- v2v: allow libvirt >= 2.1.0 for vCenter conversions + resolves: rhbz#1379240 +- p2v: enable mnemonics in the GUI + resolves: rhbz#1379289 +- Split virt-p2v, and the tools for it, in an own package: virt-p2v-maker + resolves: rhbz#1382275 +- Correctly parse mount options in btrfs entries in /etc/fstab. + resolves: rhbz#1383517 +- Read secrets from libvirt domains, when inspecting them + resolves: rhbz#1392798 +- v2v: add --vdsm-compat=1.1 flag for VDSM + resolves: rhbz#1400205 - Fix inspection with UsrMove and /usr in a separate partition - resolves: rhbz#1406289 + resolves: rhbz#1401474 +- v2v: improve import compatibility with OVAs produced by AWS + resolves: rhbz#1402301 +- resize: allow URIs for the output disk + resolves: rhbz#1404182 - Disable EDD when launching the appliance - resolves: rhbz#1406393 -- v2v: add --vdsm-compat=1.1 flag for VDSM - resolves: rhbz#1406854 + resolves: rhbz#1404287 +- v2v: increase the memory allocated to the appliance + resolves: rhbz#1418283 +- p2v: switch from GTK+ 2 to GTK+ 3 +- p2v: add dbus-devel as BuildRequires to disable suspension during the + conversion +- libguestfs-java: bump the java-headless Require to >= 1.7.0, matching the + Build-Require, and the generated bytecode + resolves: rhbz#1364518 +- Do not try to use/write to /var/cache/yum & /var/log/yum.log +- Bump ocaml-findlib-devel BuildRequires to >= 1.3.3-7.el7, because of + RHBZ#1403897 +- v2v: remove --dcpath & --dcPath from --help output too + resolves: rhbz#1429430 +- v2v: force VNC as display for -i disk, as SDL is not supported + resolves: rhbz#1372671 +- v2v, p2v: rename rhvm network to ovirtmgmt + resolves: rhbz#1429491 +- v2v: when exporting to local disk, check that UEFI firmware is installed + before conversion + resolves: rhbz#1429506 +- dib: actually generate SHA256 checksums when using --checksum + resolves: rhbz#1430184 +- v2v: do not mention SUSE Xen hosts as supported + resolves: rhbz#1430203 +- v2v: depend on OVMF/AAVMF, for converting EFI guests + resolves: rhbz#1429643 +- v2v: use absolute path when using an OVA as backing file + resolves: rhbz#1430680 +- v2v: support Debian/Ubuntu guests + resolves: rhbz#1387213 +- sysprep: remove DHCP_HOSTNAME entries + resolves: rhbz#1427529 +- v2v: avoid repeated "run virt-v2v -v -x" message on error + resolves: rhbz#1167623 +- bash-completion: add script for virt-v2v-copy-to-local + resolves: rhbz#1367738 +- v2v: fix virtio block driver installation for Windows 10 and Windows 2016 + resolves: rhbz#1434737 +- Replace the libosinfo dependency with osinfo-db, since we are only using + the osinfo database. +- v2v: fix virtio driver installation for Windows 8 UEFI + resolves: rhbz#1431579 +- v2v: new 'vmx' import method + resolves: rhbz#1441197 +- v2v: properly identify Windows 2016 guests when exporting them to RHV-M + resolves: rhbz#1447202 +- Run pvresize in non-interactive mode + resolves: rhbz#1460692 +- resize: make sure the input disk is read-only + resolves: rhbz#1463714 +- Switch qemu-kvm-rhev dependency to qemu-kvm on aarch64 + resolves: rhbz#1463646 * Tue Aug 30 2016 Richard W.M. Jones - 1:1.32.7-3 - Rebase to libguestfs 1.32 in RHEL 7.3