diff --git a/.gitignore b/.gitignore index 47ec0aa..6d71182 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,3 @@ -SOURCES/RHEV-Application_Provisioning_Tool_46267.exe +SOURCES/RHEV-Application-Provisioning-Tool.exe_4.12 SOURCES/libguestfs-1.28.1.tar.gz SOURCES/rhsrvany.exe diff --git a/.libguestfs.metadata b/.libguestfs.metadata index 867d2c9..f4542a4 100644 --- a/.libguestfs.metadata +++ b/.libguestfs.metadata @@ -1,3 +1,3 @@ -c96e9afc69abd384172c20b97a490b7a25684b8a SOURCES/RHEV-Application_Provisioning_Tool_46267.exe +8fec32284530ce6d485629fcbd1f7f3e005ae8a0 SOURCES/RHEV-Application-Provisioning-Tool.exe_4.12 49b32fe74f1e856c9397213a25f2440375574514 SOURCES/libguestfs-1.28.1.tar.gz -4dc7732d691049ea9a936a0d6c415ed9e29b4b1e SOURCES/rhsrvany.exe +2bd96e478fc004cd323b5bd754c856641877dac6 SOURCES/rhsrvany.exe diff --git a/SOURCES/0013-v2v-i-libvirt-Refactor-map_source-functions.patch b/SOURCES/0013-v2v-i-libvirt-Refactor-map_source-functions.patch index 44bd092..42b1743 100644 --- a/SOURCES/0013-v2v-i-libvirt-Refactor-map_source-functions.patch +++ b/SOURCES/0013-v2v-i-libvirt-Refactor-map_source-functions.patch @@ -12,10 +12,10 @@ tests are done, this should be equivalent to the previous code. (cherry picked from commit 3596165282ccf2c5896894ec4e9a71c6da788463) --- - v2v/input_libvirt.ml | 32 +++++++++++++++++++++++--------- + v2v/input_libvirt.ml | 36 +++++++++++++++++++++++++----------- v2v/input_libvirtxml.ml | 31 ++++++++++++------------------- v2v/input_libvirtxml.mli | 11 +---------- - 3 files changed, 36 insertions(+), 38 deletions(-) + 3 files changed, 38 insertions(+), 40 deletions(-) diff --git a/v2v/input_libvirt.ml b/v2v/input_libvirt.ml index e8b1345..9d2869f 100644 @@ -53,19 +53,21 @@ index e8b1345..9d2869f 100644 method source () = if verbose then printf "input_libvirt_xen_ssh: source()\n%!"; -+ error_if_libvirt_backend (); -+ error_if_no_ssh_agent (); -+ - (* Get the libvirt XML. This also checks (as a side-effect) - * that the domain is not running. (RHBZ#1138586) - *) - let xml = Domainxml.dumpxml ?conn:libvirt_uri guest in +- (* Get the libvirt XML. This also checks (as a side-effect) +- * that the domain is not running. (RHBZ#1138586) +- *) +- let xml = Domainxml.dumpxml ?conn:libvirt_uri guest in - -- error_if_libvirt_backend (); -- error_if_no_ssh_agent (); + error_if_libvirt_backend (); + error_if_no_ssh_agent (); + ++ (* Get the libvirt XML. This also checks (as a side-effect) ++ * that the domain is not running. (RHBZ#1138586) ++ *) ++ let xml = Domainxml.dumpxml ?conn:libvirt_uri guest in + let { s_disks = disks } as source = + Input_libvirtxml.parse_libvirt_xml ~verbose xml in - ++ let mapf = Xen.map_path_to_uri verbose parsed_uri scheme server in - Input_libvirtxml.parse_libvirt_xml ~verbose - ~map_source_file:mapf ~map_source_dev:mapf xml diff --git a/SOURCES/0018-v2v-Inline-and-simplify-Xen-and-vCenter-input-method.patch b/SOURCES/0018-v2v-Inline-and-simplify-Xen-and-vCenter-input-method.patch index af085e1..ec99ec3 100644 --- a/SOURCES/0018-v2v-Inline-and-simplify-Xen-and-vCenter-input-method.patch +++ b/SOURCES/0018-v2v-Inline-and-simplify-Xen-and-vCenter-input-method.patch @@ -39,12 +39,14 @@ index 7dde9be..5d98a86 100644 + (match uri.uri_user with Some user -> " " ^ quote user | None -> "") + (quote url) in + let lines = external_command ~prog cmd in -+ + +-let session_cookie = ref "" + let dump_response chan = + fprintf chan "%s\n" cmd; + List.iter (fun x -> fprintf chan "%s\n" x) lines + in -+ + +-(* Map an ESX to a qemu URI using the cURL driver + if verbose then dump_response stdout; + + (* Look for the last HTTP/x.y NNN status code in the output. *) @@ -98,8 +100,7 @@ index 7dde9be..5d98a86 100644 + else + Some !session_cookie + ) - --let session_cookie = ref "" ++ +(* Helper function to extract the datacenter from a URI. *) +let get_datacenter uri scheme = + let default_dc = "ha-datacenter" in @@ -123,8 +124,7 @@ index 7dde9be..5d98a86 100644 + default_dc + | _ -> (* Don't know, so guess. *) + default_dc - --(* Map an ESX to a qemu URI using the cURL driver ++ +(* Map the string to a qemu URI using the cURL driver * in qemu. The 'path' will be something like * diff --git a/SOURCES/0021-v2v-i-libvirtxml-Fix-handling-of-nbd-sources-RHBZ-11.patch b/SOURCES/0021-v2v-i-libvirtxml-Fix-handling-of-nbd-sources-RHBZ-11.patch index e5d8fc0..08a46bc 100644 --- a/SOURCES/0021-v2v-i-libvirtxml-Fix-handling-of-nbd-sources-RHBZ-11.patch +++ b/SOURCES/0021-v2v-i-libvirtxml-Fix-handling-of-nbd-sources-RHBZ-11.patch @@ -20,11 +20,11 @@ This fixes commit 3596165282ccf2c5896894ec4e9a71c6da788463. (cherry picked from commit ad78d1492b02eaf5d810e2f9d012a5fed4f4124b) --- v2v/input_libvirt_other.ml | 5 ++++- - v2v/input_libvirt_vcenter_https.ml | 46 ++++++++++++++++++++++++-------------- + v2v/input_libvirt_vcenter_https.ml | 44 ++++++++++++++++++++++++-------------- v2v/input_libvirt_xen_ssh.ml | 10 ++++++--- - v2v/input_libvirtxml.ml | 38 +++++++++++++++++++++---------- - v2v/input_libvirtxml.mli | 17 ++++++++++++-- - 5 files changed, 81 insertions(+), 35 deletions(-) + v2v/input_libvirtxml.ml | 38 +++++++++++++++++++++----------- + v2v/input_libvirtxml.mli | 17 +++++++++++++-- + 5 files changed, 80 insertions(+), 34 deletions(-) diff --git a/v2v/input_libvirt_other.ml b/v2v/input_libvirt_other.ml index a771aa1..9f3eedb 100644 @@ -100,7 +100,10 @@ index 71c2edd..56097e0 100644 let readahead = readahead_for_copying in - map_source_to_uri ?readahead - verbose parsed_uri scheme server orig_path in -- ++ let backing_qemu_uri = ++ map_source_to_uri ?readahead ++ verbose parsed_uri scheme server orig_path in + - (* Rebase the qcow2 overlay to adjust the readahead parameter. *) - let cmd = - sprintf "qemu-img rebase -u -b %s %s" @@ -108,10 +111,6 @@ index 71c2edd..56097e0 100644 - if verbose then printf "%s\n%!" cmd; - if Sys.command cmd <> 0 then - warning ~prog (f_"qemu-img rebase failed (ignored)") -+ let backing_qemu_uri = -+ map_source_to_uri ?readahead -+ verbose parsed_uri scheme server orig_path in -+ + (* Rebase the qcow2 overlay to adjust the readahead parameter. *) + let cmd = + sprintf "qemu-img rebase -u -b %s %s" diff --git a/SOURCES/0044-inspection-Get-icons-from-RHEL-and-CentOS-7-RHBZ-116.patch b/SOURCES/0044-inspection-Get-icons-from-RHEL-and-CentOS-7-RHBZ-116.patch index 8727cf4..787226b 100644 --- a/SOURCES/0044-inspection-Get-icons-from-RHEL-and-CentOS-7-RHBZ-116.patch +++ b/SOURCES/0044-inspection-Get-icons-from-RHEL-and-CentOS-7-RHBZ-116.patch @@ -39,13 +39,13 @@ index 0ffca72..4f10dfb 100644 + max_size = 17000; + else + max_size = 66000; -+ + +- return get_png (g, fs, SHADOWMAN_ICON, size_r, max_size); + if (fs->major_version <= 6) + shadowman = "/usr/share/pixmaps/redhat/shadowman-transparent.png"; + else + shadowman = "/usr/share/pixmaps/fedora-logo-sprite.png"; - -- return get_png (g, fs, SHADOWMAN_ICON, size_r, max_size); ++ + return get_png (g, fs, shadowman, size_r, max_size); } diff --git a/SOURCES/0050-v2v-Don-t-use-target-dev-attribute-use-target-bus-in.patch b/SOURCES/0050-v2v-Don-t-use-target-dev-attribute-use-target-bus-in.patch index e1393c8..8543aae 100644 --- a/SOURCES/0050-v2v-Don-t-use-target-dev-attribute-use-target-bus-in.patch +++ b/SOURCES/0050-v2v-Don-t-use-target-dev-attribute-use-target-bus-in.patch @@ -247,7 +247,11 @@ index 836b24e..fe71039 100644 - let address = xpath_to_int "rasd:AddressOnParent/text()" 0 in let parent_id = xpath_to_int "rasd:Parent/text()" 0 in -- (* Find the parent controller. *) ++ (* XXX We assume the OVF lists these in order. ++ let address = xpath_to_int "rasd:AddressOnParent/text()" 0 in ++ *) ++ + (* Find the parent controller. *) - let expr = sprintf "/ovf:Envelope/ovf:VirtualSystem/ovf:VirtualHardwareSection/ovf:Item[rasd:InstanceID/text()=%d]/rasd:ResourceType/text()" parent_id in - let controller = xpath_to_int expr 0 in - @@ -256,12 +260,8 @@ index 836b24e..fe71039 100644 - match controller with - | 6 -> "sd" - | 0 | 5 | _ (* XXX floppy should be 'fd'? *) -> "hd" in -+ (* XXX We assume the OVF lists these in order. -+ let address = xpath_to_int "rasd:AddressOnParent/text()" 0 in -+ *) - +- - let target_dev = target_dev ^ drive_name address in -+ (* Find the parent controller. *) + let controller = parent_controller parent_id in Xml.xpathctx_set_current_context xpathctx n; @@ -282,7 +282,11 @@ index 836b24e..fe71039 100644 - let address = xpath_to_int "rasd:AddressOnParent/text()" 0 in let parent_id = xpath_to_int "rasd:Parent/text()" 0 in -- (* Find the parent controller. *) ++ (* XXX We assume the OVF lists these in order. ++ let address = xpath_to_int "rasd:AddressOnParent/text()" 0 in ++ *) ++ + (* Find the parent controller. *) - let expr = sprintf "/ovf:Envelope/ovf:VirtualSystem/ovf:VirtualHardwareSection/ovf:Item[rasd:InstanceID/text()=%d]/rasd:ResourceType/text()" parent_id in - let controller = xpath_to_int expr 0 in - @@ -291,12 +295,8 @@ index 836b24e..fe71039 100644 - match controller with - | 6 -> "sd" - | 0 | 5 | _ (* XXX floppy should be 'fd'? *) -> "hd" in -+ (* XXX We assume the OVF lists these in order. -+ let address = xpath_to_int "rasd:AddressOnParent/text()" 0 in -+ *) - +- - let target_dev = target_dev ^ drive_name address in -+ (* Find the parent controller. *) + let controller = parent_controller parent_id in let typ = diff --git a/SOURCES/0089-RHEL-7-Emphasize-libguestfs-winsupport-package-RHBZ-.patch b/SOURCES/0089-RHEL-7-Emphasize-libguestfs-winsupport-package-RHBZ-.patch deleted file mode 100644 index 02c6aff..0000000 --- a/SOURCES/0089-RHEL-7-Emphasize-libguestfs-winsupport-package-RHBZ-.patch +++ /dev/null @@ -1,96 +0,0 @@ -From c3fd9d491a043a1b2be7755c4ef8335a4525e185 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Mon, 10 Jan 2011 16:07:12 +0000 -Subject: [PATCH] RHEL 7: Emphasize libguestfs-winsupport package - (RHBZ#627468). - -This RHEL-only patch changes the error messages when the -inspection code cannot find an operating system inside the guest -image. For a Windows guest this may happen because the user has not -installed the separate 'libguestfs-winsupport' package. Therefore we -emphasize that the user may need to install this package. - -Notes: - -(1) In RHEL there are two pieces of inspection code, the old Perl code -(deprecated upstream) and the new C core inspection API. Therefore -this patch has to touch two places with essentially the same change. - -(2) This patch doesn't try to be clever and detect if it was a Windows -guest. This should reduce the chance of failure. - -Output from (Perl) virt-inspector now looks like this: - - $ virt-inspector disk.img - No operating system could be detected inside this disk image. - - This may be because the file is not a disk image, or is not a virtual machine - image, or because the OS type is not understood by virt-inspector. - - If you feel this is an error, please file a bug report including as much - information about the disk image as possible. - - RHEL notice - ------------- - libguestfs will return this error for Microsoft Windows guests if the - separate 'libguestfs-winsupport' package is not installed. If the - guest is running Microsoft Windows, please try again after installing - 'libguestfs-winsupport'. - -Output from guestfish (ie. C core inspection API) now looks like this: - - $ guestfish -i disk.img - guestfish: no operating system was found on this disk - - RHEL notice - ------------- - libguestfs will return this error for Microsoft Windows guests if the - separate 'libguestfs-winsupport' package is not installed. If the - guest is running Microsoft Windows, please try again after installing - 'libguestfs-winsupport'. ---- - fish/inspect.c | 14 ++++++++++++++ - 1 file changed, 14 insertions(+) - -diff --git a/fish/inspect.c b/fish/inspect.c -index 841f1da..9b37d87 100644 ---- a/fish/inspect.c -+++ b/fish/inspect.c -@@ -22,6 +22,7 @@ - #include - #include - #include -+#include - #include - - #include "c-ctype.h" -@@ -71,6 +72,10 @@ inspect_mount_handle (guestfs_h *g) - exit (EXIT_FAILURE); - - if (roots[0] == NULL) { -+ int libguestfs_winsupport_installed = -+ access ("/usr/lib/guestfs/supermin.d/zz-winsupport", F_OK) == 0 || -+ access ("/usr/lib64/guestfs/supermin.d/zz-winsupport", F_OK) == 0; -+ - fprintf (stderr, - _("%s: no operating system was found on this disk\n" - "\n" -@@ -87,6 +92,15 @@ inspect_mount_handle (guestfs_h *g) - "with these tools. Use the guestfish equivalent commands\n" - "(see the virt tool manual page).\n"), - program_name); -+ if (!libguestfs_winsupport_installed) -+ fprintf (stderr, -+ _("\nRHEL notice\n" -+ "-------------\n" -+ "libguestfs will return this error for Microsoft Windows guests if the\n" -+ "separate 'libguestfs-winsupport' package is not installed. If the\n" -+ "guest is running Microsoft Windows, please try again after installing\n" -+ "'libguestfs-winsupport'.\n")); -+ - guestfs___free_string_list (roots); - exit (EXIT_FAILURE); - } --- -1.8.3.1 - diff --git a/SOURCES/0089-aarch64-appliance-Use-AAVMF-UEFI-if-available-for-ru.patch b/SOURCES/0089-aarch64-appliance-Use-AAVMF-UEFI-if-available-for-ru.patch new file mode 100644 index 0000000..3485d97 --- /dev/null +++ b/SOURCES/0089-aarch64-appliance-Use-AAVMF-UEFI-if-available-for-ru.patch @@ -0,0 +1,208 @@ +From eb3c98e28ad33606f70602834e455d7e0789153e Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Wed, 21 Jan 2015 05:10:37 -0500 +Subject: [PATCH] aarch64: appliance: Use AAVMF (UEFI) if available for running + the appliance. + +AAVMF is an open source UEFI implementation for aarch64 based on OVMF. +As aarch64 is heading for requiring UEFI even inside guests, if the +AAVMF firmware is installed on the host, use it as a hint that we +should boot the guest using AAVMF instead of the default "empty +machine". + +Note this requires very recent AAVMF, libvirt, qemu. However that's +OK since it's only applicable to aarch64. On non-aarch64, this patch +does nothing. + +Thanks: Laszlo Ersek for a lot of help getting this right. +(cherry picked from commit 7dc837c7be84936690f4f613fea82dba4787ceec) +--- + src/appliance.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++- + src/guestfs-internal.h | 1 + + src/launch-direct.c | 14 +++++++++++ + src/launch-libvirt.c | 25 +++++++++++++++++++ + 4 files changed, 105 insertions(+), 1 deletion(-) + +diff --git a/src/appliance.c b/src/appliance.c +index d7aa6b1..5fa47f2 100644 +--- a/src/appliance.c ++++ b/src/appliance.c +@@ -1,5 +1,5 @@ + /* libguestfs +- * Copyright (C) 2010-2012 Red Hat Inc. ++ * Copyright (C) 2010-2014 Red Hat Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public +@@ -459,3 +459,67 @@ dir_contains_files (const char *dir, ...) + va_end (args); + return 1; + } ++ ++#ifdef __aarch64__ ++ ++#define AAVMF_DIR "/usr/share/AAVMF" ++ ++/* Return the location of firmware needed to boot the appliance. This ++ * is aarch64 only currently, since that's the only architecture where ++ * UEFI is mandatory (and that only for RHEL). ++ * ++ * '*code' is initialized with the path to the read-only UEFI code ++ * file. '*vars' is initialized with the path to a copy of the UEFI ++ * vars file (which is cleaned up automatically on exit). ++ * ++ * If *code == *vars == NULL then no UEFI firmware is available. ++ * ++ * '*code' and '*vars' should be freed by the caller. ++ * ++ * If the function returns -1 then there was a real error which should ++ * cause appliance building to fail (no UEFI firmware is not an ++ * error). ++ */ ++int ++guestfs___get_uefi (guestfs_h *g, char **code, char **vars) ++{ ++ if (access (AAVMF_DIR "/AAVMF_CODE.fd", R_OK) == 0 && ++ access (AAVMF_DIR "/AAVMF_VARS.fd", R_OK) == 0) { ++ CLEANUP_CMD_CLOSE struct command *copycmd = guestfs___new_command (g); ++ char *varst; ++ int r; ++ ++ /* Make a copy of AAVMF_VARS.fd. You can't just map it into the ++ * address space read-only as that triggers a different path ++ * inside UEFI. ++ */ ++ varst = safe_asprintf (g, "%s/AAVMF_VARS.fd.%d", g->tmpdir, ++g->unique); ++ guestfs___cmd_add_arg (copycmd, "cp"); ++ guestfs___cmd_add_arg (copycmd, AAVMF_DIR "/AAVMF_VARS.fd"); ++ guestfs___cmd_add_arg (copycmd, varst); ++ r = guestfs___cmd_run (copycmd); ++ if (r == -1 || !WIFEXITED (r) || WEXITSTATUS (r) != 0) { ++ free (varst); ++ return -1; ++ } ++ ++ /* Caller frees. */ ++ *code = safe_strdup (g, AAVMF_DIR "/AAVMF_CODE.fd"); ++ *vars = varst; ++ return 0; ++ } ++ ++ *code = *vars = NULL; ++ return 0; ++} ++ ++#else /* !__aarch64__ */ ++ ++int ++guestfs___get_uefi (guestfs_h *g, char **code, char **vars) ++{ ++ *code = *vars = NULL; ++ return 0; ++} ++ ++#endif /* !__aarch64__ */ +diff --git a/src/guestfs-internal.h b/src/guestfs-internal.h +index fd0c4a1..d5de345 100644 +--- a/src/guestfs-internal.h ++++ b/src/guestfs-internal.h +@@ -725,6 +725,7 @@ extern const char *guestfs___drive_protocol_to_string (enum drive_protocol proto + + /* appliance.c */ + extern int guestfs___build_appliance (guestfs_h *g, char **kernel, char **dtb, char **initrd, char **appliance); ++extern int guestfs___get_uefi (guestfs_h *g, char **code, char **vars); + + /* launch.c */ + extern int64_t guestfs___timeval_diff (const struct timeval *x, const struct timeval *y); +diff --git a/src/launch-direct.c b/src/launch-direct.c +index 5301176..2834967 100644 +--- a/src/launch-direct.c ++++ b/src/launch-direct.c +@@ -267,6 +267,7 @@ launch_direct (guestfs_h *g, void *datav, const char *arg) + int sv[2]; + char guestfsd_sock[256]; + struct sockaddr_un addr; ++ CLEANUP_FREE char *uefi_code = NULL, *uefi_vars = NULL; + CLEANUP_FREE char *kernel = NULL, *dtb = NULL, + *initrd = NULL, *appliance = NULL; + int has_appliance_drive; +@@ -474,6 +475,19 @@ launch_direct (guestfs_h *g, void *datav, const char *arg) + ADD_CMDLINE ("kvm-pit.lost_tick_policy=discard"); + } + ++ /* UEFI (firmware) if required. */ ++ if (guestfs___get_uefi (g, &uefi_code, &uefi_vars) == -1) ++ goto cleanup0; ++ if (uefi_code) { ++ ADD_CMDLINE ("-drive"); ++ ADD_CMDLINE_PRINTF ("if=pflash,format=raw,file=%s,readonly", uefi_code); ++ if (uefi_vars) { ++ ADD_CMDLINE ("-drive"); ++ ADD_CMDLINE_PRINTF ("if=pflash,format=raw,file=%s", uefi_vars); ++ } ++ } ++ ++ /* Kernel, DTB and initrd. */ + ADD_CMDLINE ("-kernel"); + ADD_CMDLINE (kernel); + if (dtb) { +diff --git a/src/launch-libvirt.c b/src/launch-libvirt.c +index f8f818a..e6899ac 100644 +--- a/src/launch-libvirt.c ++++ b/src/launch-libvirt.c +@@ -109,6 +109,8 @@ struct backend_libvirt_data { + char name[DOMAIN_NAME_LEN]; /* random name */ + bool is_kvm; /* false = qemu, true = kvm (from capabilities)*/ + unsigned long qemu_version; /* qemu version (from libvirt) */ ++ char *uefi_code; /* UEFI (firmware) code and variables. */ ++ char *uefi_vars; + }; + + /* Parameters passed to construct_libvirt_xml and subfunctions. We +@@ -318,6 +320,10 @@ launch_libvirt (guestfs_h *g, void *datav, const char *libvirt_uri) + if (parse_capabilities (g, capabilities_xml, data) == -1) + goto cleanup; + ++ /* UEFI code and variables, on architectures where that is required. */ ++ if (guestfs___get_uefi (g, &data->uefi_code, &data->uefi_vars) == -1) ++ goto cleanup; ++ + /* Misc backend settings. */ + guestfs_push_error_handler (g, NULL, NULL); + data->selinux_label = +@@ -1095,6 +1101,20 @@ construct_libvirt_xml_boot (guestfs_h *g, + string ("hvm"); + } end_element (); + ++ if (params->data->uefi_code) { ++ start_element ("loader") { ++ attribute ("readonly", "yes"); ++ attribute ("type", "pflash"); ++ string (params->data->uefi_code); ++ } end_element (); ++ ++ if (params->data->uefi_vars) { ++ start_element ("nvram") { ++ string (params->data->uefi_vars); ++ } end_element (); ++ } ++ } ++ + start_element ("kernel") { + string (params->kernel); + } end_element (); +@@ -1709,6 +1729,11 @@ shutdown_libvirt (guestfs_h *g, void *datav, int check_for_errors) + free (data->network_bridge); + data->network_bridge = NULL; + ++ free (data->uefi_code); ++ data->uefi_code = NULL; ++ free (data->uefi_vars); ++ data->uefi_vars = NULL; ++ + return ret; + } + +-- +1.8.3.1 + diff --git a/SOURCES/0090-RHEL-7-Remove-libguestfs-live-RHBZ-798980.patch b/SOURCES/0090-RHEL-7-Remove-libguestfs-live-RHBZ-798980.patch deleted file mode 100644 index f0762d4..0000000 --- a/SOURCES/0090-RHEL-7-Remove-libguestfs-live-RHBZ-798980.patch +++ /dev/null @@ -1,38 +0,0 @@ -From c126bb91d103e8e192f118cd07ec584827479e44 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 +++++++ - 1 file changed, 7 insertions(+) - -diff --git a/src/launch-unix.c b/src/launch-unix.c -index 489a046..7956bed 100644 ---- a/src/launch-unix.c -+++ b/src/launch-unix.c -@@ -37,6 +37,12 @@ - static int - launch_unix (guestfs_h *g, void *datav, const char *sockpath) - { -+ error (g, -+ "launch: In RHEL, only the 'libvirt' or 'direct' method is supported.\n" -+ "In particular, \"libguestfs live\" is not supported."); -+ return -1; -+ -+#if 0 - int r, daemon_sock = -1; - struct sockaddr_un addr; - uint32_t size; -@@ -102,6 +108,7 @@ launch_unix (guestfs_h *g, void *datav, const char *sockpath) - g->conn = NULL; - } - return -1; -+#endif - } - - static int --- -1.8.3.1 - diff --git a/SOURCES/0090-aarch64-launch-libvirt-As-a-workaround-pass-cpu-para.patch b/SOURCES/0090-aarch64-launch-libvirt-As-a-workaround-pass-cpu-para.patch new file mode 100644 index 0000000..a98c75d --- /dev/null +++ b/SOURCES/0090-aarch64-launch-libvirt-As-a-workaround-pass-cpu-para.patch @@ -0,0 +1,71 @@ +From 240cd5f90c83bcd0441d8ea079c3e5f6508d1202 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Wed, 21 Jan 2015 05:37:56 -0500 +Subject: [PATCH] aarch64: launch: libvirt: As a workaround, pass -cpu + parameter to qemu. + +When libguestfs is running using TCG on aarch64, we need to pass the +-cpu cortex-a57 parameter to qemu. Libvirt doesn't let us do this, +complaining "Unable to find CPU definition". + +As a temporary workaround only, use to pass this +argument directly to qemu. When libvirt is fixed we can remove this +hack. + +This is a workaround for libvirt bug RHBZ#1184411. + +See: +https://www.redhat.com/archives/libvirt-users/2014-August/msg00043.html +https://bugzilla.redhat.com/show_bug.cgi?id=1184411 +(cherry picked from commit 7e4b7a346a4558a02aeb58f82d518509ce6e5d03) +--- + src/launch-libvirt.c | 21 ++++++++++++++++++++- + 1 file changed, 20 insertions(+), 1 deletion(-) + +diff --git a/src/launch-libvirt.c b/src/launch-libvirt.c +index e6899ac..79bc6fd 100644 +--- a/src/launch-libvirt.c ++++ b/src/launch-libvirt.c +@@ -1035,12 +1035,16 @@ construct_libvirt_xml_cpu (guestfs_h *g, + } end_element (); + } + else { +- /* XXX This does not work, see: ++ /* XXX This does not work on aarch64, see: + * https://www.redhat.com/archives/libvirt-users/2014-August/msg00043.html ++ * https://bugzilla.redhat.com/show_bug.cgi?id=1184411 ++ * Instead we hack around it using below. + */ ++#ifndef __aarch64__ + start_element ("model") { + string (cpu_model); + } end_element (); ++#endif + } + } end_element (); + } +@@ -1670,6 +1674,21 @@ construct_libvirt_xml_qemu_cmdline (guestfs_h *g, + } + } + ++#ifdef __aarch64__ ++ /* This is a temporary hack until RHBZ#1184411 is resolved. ++ * See comments above about cpu model and aarch64. ++ */ ++ const char *cpu_model = guestfs___get_cpu_model (params->data->is_kvm); ++ if (STRNEQ (cpu_model, "host")) { ++ start_element ("qemu:arg") { ++ attribute ("value", "-cpu"); ++ } end_element (); ++ start_element ("qemu:arg") { ++ attribute ("value", cpu_model); ++ } end_element (); ++ } ++#endif ++ + } end_element (); /* */ + + return 0; +-- +1.8.3.1 + diff --git a/SOURCES/0091-RHEL-7-Remove-9p-APIs-from-RHEL-RHBZ-921710.patch b/SOURCES/0091-RHEL-7-Remove-9p-APIs-from-RHEL-RHBZ-921710.patch deleted file mode 100644 index 4afc84b..0000000 --- a/SOURCES/0091-RHEL-7-Remove-9p-APIs-from-RHEL-RHBZ-921710.patch +++ /dev/null @@ -1,346 +0,0 @@ -From 2d902f917506177885481b17172ef7e297300a74 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 | 223 --------------------------------------------------- - daemon/Makefile.am | 1 - - generator/actions.ml | 23 ------ - gobject/Makefile.inc | 2 - - po/POTFILES | 2 - - 6 files changed, 1 insertion(+), 252 deletions(-) - delete mode 100644 daemon/9p.c - -diff --git a/Makefile.am b/Makefile.am -index d55d8d6..207bcb1 100644 ---- a/Makefile.am -+++ b/Makefile.am -@@ -59,7 +59,7 @@ SUBDIRS += tests/xfs - SUBDIRS += tests/charsets - SUBDIRS += tests/xml - SUBDIRS += tests/mount-local --SUBDIRS += tests/9p -+#SUBDIRS += tests/9p - SUBDIRS += tests/rsync - SUBDIRS += tests/bigdirs - SUBDIRS += tests/disk-labels -diff --git a/daemon/9p.c b/daemon/9p.c -deleted file mode 100644 -index fefbb71..0000000 ---- a/daemon/9p.c -+++ /dev/null -@@ -1,223 +0,0 @@ --/* libguestfs - the guestfsd daemon -- * Copyright (C) 2011 Red Hat Inc. -- * -- * This program is free software; you can redistribute it and/or modify -- * it under the terms of the GNU General Public License as published by -- * the Free Software Foundation; either version 2 of the License, or -- * (at your option) any later version. -- * -- * This program is distributed in the hope that it will be useful, -- * but WITHOUT ANY WARRANTY; without even the implied warranty of -- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- * GNU General Public License for more details. -- * -- * You should have received a copy of the GNU General Public License -- * along with this program; if not, write to the Free Software -- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -- */ -- --#include -- --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include -- --#include "daemon.h" --#include "actions.h" -- --#define BUS_PATH "/sys/bus/virtio/drivers/9pnet_virtio" --GUESTFSD_EXT_CMD(str_mount, mount); -- --static char *read_whole_file (const char *filename); -- --/* https://bugzilla.redhat.com/show_bug.cgi?id=714981#c1 */ --char ** --do_list_9p (void) --{ -- DECLARE_STRINGSBUF (r); -- -- DIR *dir; -- -- dir = opendir (BUS_PATH); -- if (!dir) { -- perror ("opendir: " BUS_PATH); -- if (errno != ENOENT) { -- reply_with_perror ("opendir: " BUS_PATH); -- return NULL; -- } -- -- /* If this directory doesn't exist, it probably means that -- * the virtio driver isn't loaded. Don't return an error -- * in this case, but return an empty list. -- */ -- if (end_stringsbuf (&r) == -1) -- return NULL; -- -- return r.argv; -- } -- -- while (1) { -- struct dirent *d; -- -- errno = 0; -- d = readdir (dir); -- 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); -- -- /* A bit unclear, but it looks like the virtio transport allows -- * the mount tag length to be unlimited (or up to 65536 bytes). -- * See: linux/include/linux/virtio_9p.h -- */ -- CLEANUP_FREE char *mount_tag = read_whole_file (mount_tag_path); -- if (mount_tag == 0) -- continue; -- -- if (add_string (&r, mount_tag) == -1) { -- closedir (dir); -- return NULL; -- } -- } -- } -- -- /* Check readdir didn't fail */ -- if (errno != 0) { -- reply_with_perror ("readdir: /sys/block"); -- free_stringslen (r.argv, r.size); -- closedir (dir); -- return NULL; -- } -- -- /* Close the directory handle */ -- if (closedir (dir) == -1) { -- reply_with_perror ("closedir: /sys/block"); -- free_stringslen (r.argv, r.size); -- return NULL; -- } -- -- /* Sort the tags. */ -- if (r.size > 0) -- sort_strings (r.argv, r.size); -- -- /* NULL terminate the list */ -- if (end_stringsbuf (&r) == -1) -- return NULL; -- -- return r.argv; --} -- --/* Read whole file into dynamically allocated array. If there is an -- * error, DON'T call reply_with_perror, just return NULL. Returns a -- * \0-terminated string. -- */ --static char * --read_whole_file (const char *filename) --{ -- char *r = NULL; -- size_t alloc = 0, size = 0; -- int fd; -- -- fd = open (filename, O_RDONLY|O_CLOEXEC); -- if (fd == -1) { -- perror (filename); -- return NULL; -- } -- -- while (1) { -- alloc += 256; -- char *r2 = realloc (r, alloc); -- if (r2 == NULL) { -- perror ("realloc"); -- free (r); -- close (fd); -- return NULL; -- } -- r = r2; -- -- /* The '- 1' in the size calculation ensures there is space below -- * to add \0 to the end of the input. -- */ -- ssize_t n = read (fd, r + size, alloc - size - 1); -- if (n == -1) { -- fprintf (stderr, "read: %s: %m\n", filename); -- free (r); -- close (fd); -- return NULL; -- } -- if (n == 0) -- break; -- size += n; -- } -- -- if (close (fd) == -1) { -- fprintf (stderr, "close: %s: %m\n", filename); -- free (r); -- return NULL; -- } -- -- r[size] = '\0'; -- -- return r; --} -- --/* Takes optional arguments, consult optargs_bitmask. */ --int --do_mount_9p (const char *mount_tag, const char *mountpoint, const char *options) --{ -- CLEANUP_FREE char *mp = NULL, *opts = NULL, *err = NULL; -- struct stat statbuf; -- int r; -- -- ABS_PATH (mountpoint, , return -1); -- -- mp = sysroot_path (mountpoint); -- if (!mp) { -- reply_with_perror ("malloc"); -- return -1; -- } -- -- /* Check the mountpoint exists and is a directory. */ -- if (stat (mp, &statbuf) == -1) { -- reply_with_perror ("%s", mountpoint); -- return -1; -- } -- if (!S_ISDIR (statbuf.st_mode)) { -- reply_with_perror ("%s: mount point is not a directory", mountpoint); -- return -1; -- } -- -- /* Add trans=virtio to the options. */ -- if ((optargs_bitmask & GUESTFS_MOUNT_9P_OPTIONS_BITMASK) && -- STRNEQ (options, "")) { -- if (asprintf (&opts, "trans=virtio,%s", options) == -1) { -- reply_with_perror ("asprintf"); -- return -1; -- } -- } -- else { -- opts = strdup ("trans=virtio"); -- if (opts == NULL) { -- reply_with_perror ("strdup"); -- return -1; -- } -- } -- -- r = command (NULL, &err, -- str_mount, "-o", opts, "-t", "9p", mount_tag, mp, NULL); -- if (r == -1) { -- reply_with_error ("%s on %s: %s", mount_tag, mountpoint, err); -- return -1; -- } -- -- return 0; --} -diff --git a/daemon/Makefile.am b/daemon/Makefile.am -index 8ccf322..ec6fc6f 100644 ---- a/daemon/Makefile.am -+++ b/daemon/Makefile.am -@@ -77,7 +77,6 @@ noinst_PROGRAMS = guestfsd - endif - - guestfsd_SOURCES = \ -- 9p.c \ - acl.c \ - actions.h \ - available.c \ -diff --git a/generator/actions.ml b/generator/actions.ml -index 593e51b..20e9774 100644 ---- a/generator/actions.ml -+++ b/generator/actions.ml -@@ -9150,29 +9150,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"; -- style = RStringList "mounttags", [], []; -- proc_nr = Some 285; -- shortdesc = "list 9p filesystems"; -- longdesc = "\ --List all 9p filesystems attached to the guest. A list of --mount tags is returned." }; -- -- { defaults with -- name = "mount_9p"; -- style = RErr, [String "mounttag"; String "mountpoint"], [OString "options"]; -- proc_nr = Some 286; -- camel_name = "Mount9P"; -- shortdesc = "mount 9p filesystem"; -- longdesc = "\ --Mount the virtio-9p filesystem with the tag C on the --directory C. -- --If required, C will be automatically added to the options. --Any other options required can be passed in the optional C --parameter." }; -- -- { defaults with - name = "list_dm_devices"; - style = RStringList "devices", [], []; - proc_nr = Some 287; -diff --git a/gobject/Makefile.inc b/gobject/Makefile.inc -index c93dace..f2152f2 100644 ---- a/gobject/Makefile.inc -+++ b/gobject/Makefile.inc -@@ -78,7 +78,6 @@ guestfs_gobject_headers= \ - include/guestfs-gobject/optargs-mkfs_btrfs.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 \ -@@ -156,7 +155,6 @@ guestfs_gobject_sources= \ - src/optargs-mkfs_btrfs.c \ - src/optargs-mkswap.c \ - src/optargs-mktemp.c \ -- src/optargs-mount_9p.c \ - src/optargs-mount_local.c \ - src/optargs-ntfsclone_out.c \ - src/optargs-ntfsfix.c \ -diff --git a/po/POTFILES b/po/POTFILES -index 1a088f5..7f3365c 100644 ---- a/po/POTFILES -+++ b/po/POTFILES -@@ -14,7 +14,6 @@ cat/ls.c - cat/visit.c - customize/crypt-c.c - customize/perl_edit-c.c --daemon/9p.c - daemon/acl.c - daemon/augeas.c - daemon/available.c -@@ -203,7 +202,6 @@ gobject/src/optargs-mkfs.c - gobject/src/optargs-mkfs_btrfs.c - gobject/src/optargs-mkswap.c - gobject/src/optargs-mktemp.c --gobject/src/optargs-mount_9p.c - gobject/src/optargs-mount_local.c - gobject/src/optargs-ntfsclone_out.c - gobject/src/optargs-ntfsfix.c --- -1.8.3.1 - diff --git a/SOURCES/0091-aarch64-Increase-default-appliance-memory-size-on-aa.patch b/SOURCES/0091-aarch64-Increase-default-appliance-memory-size-on-aa.patch new file mode 100644 index 0000000..cfe6713 --- /dev/null +++ b/SOURCES/0091-aarch64-Increase-default-appliance-memory-size-on-aa.patch @@ -0,0 +1,41 @@ +From 28ca86d12286aad430378cbf416c966cdfddfbdf Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Sat, 24 Jan 2015 15:40:05 +0000 +Subject: [PATCH] aarch64: Increase default appliance memory size on aarch64. + +Kernel 3.19 has problems uncompressing the RAM disk with <= 500 MB. +(This is likely to be a kernel bug) + +64 KB pages are common on aarch64, so treat this case the same as ppc, +and use a larger default appliance memory size. + +Thanks: Laszlo Ersek for help and reproducing the bug. +(cherry picked from commit c24f242521e882380c28d0952007d8462040d998) +--- + src/guestfs-internal.h | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/src/guestfs-internal.h b/src/guestfs-internal.h +index d5de345..d9ccf5f 100644 +--- a/src/guestfs-internal.h ++++ b/src/guestfs-internal.h +@@ -68,6 +68,16 @@ + # define MIN_MEMSIZE 256 + #endif + ++/* Kernel 3.19 is unable to uncompress the initramfs on aarch64 unless ++ * we have > 500 MB of space. This looks like a kernel bug (earlier ++ * kernels have no problems). However since 64 KB pages are also ++ * common on aarch64, treat this like the ppc case above. ++ */ ++#ifdef __aarch64__ ++# define DEFAULT_MEMSIZE 768 ++# define MIN_MEMSIZE 256 ++#endif ++ + /* Valgrind has a fairly hefty memory overhead. Using the defaults + * caused the C API tests to fail. + */ +-- +1.8.3.1 + diff --git a/SOURCES/0092-RHEL-7-Disable-unsupported-remote-drive-protocols-RH.patch b/SOURCES/0092-RHEL-7-Disable-unsupported-remote-drive-protocols-RH.patch deleted file mode 100644 index 4ea09c8..0000000 --- a/SOURCES/0092-RHEL-7-Disable-unsupported-remote-drive-protocols-RH.patch +++ /dev/null @@ -1,615 +0,0 @@ -From b8877c3a02da7eeef62690f7f829be80c5502241 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 - (RHBZ#962113). - -This disables support for unsupported remote drive protocols: - - * ftp - * ftps - * http - * https - * tftp - * gluster - * iscsi - * rbd - * sheepdog - * ssh - -Note 'nbd' is not disabled, and of course 'file' works. - -We hope to gradually add some of these back over the lifetime of RHEL 7. ---- - fish/guestfish.pod | 69 ------------------- - fish/test-add-uri.sh | 31 --------- - generator/actions.ml | 72 -------------------- - src/drives.c | 8 +++ - src/guestfs.pod | 121 --------------------------------- - tests/disks/test-qemu-drive-libvirt.sh | 40 ----------- - tests/disks/test-qemu-drive.sh | 70 ------------------- - 7 files changed, 8 insertions(+), 403 deletions(-) - -diff --git a/fish/guestfish.pod b/fish/guestfish.pod -index 12bf243..d95cd77 100644 ---- a/fish/guestfish.pod -+++ b/fish/guestfish.pod -@@ -1140,40 +1140,6 @@ The possible I<-a URI> formats are described below. - - Add the local disk image (or device) called C. - --=head2 B<-a ftp://[user@]example.com[:port]/disk.img> -- --=head2 B<-a ftps://[user@]example.com[:port]/disk.img> -- --=head2 B<-a http://[user@]example.com[:port]/disk.img> -- --=head2 B<-a https://[user@]example.com[:port]/disk.img> -- --=head2 B<-a tftp://[user@]example.com[:port]/disk.img> -- --Add a disk located on a remote FTP, HTTP or TFTP server. -- --The equivalent API command would be: -- -- > add /disk.img protocol:(ftp|...) server:tcp:example.com -- --=head2 B<-a gluster://example.com[:port]/volname/image> -- --Add a disk image located on GlusterFS storage. -- --The server is the one running C, and may be C. -- --The equivalent API command would be: -- -- > add volname/image protocol:gluster server:tcp:example.com -- --=head2 B<-a iscsi://example.com[:port]/target-iqn-name[/lun]> -- --Add a disk located on an iSCSI server. -- --The equivalent API command would be: -- -- > add target-iqn-name/lun protocol:iscsi server:tcp:example.com -- - =head2 B<-a nbd://example.com[:port]> - - =head2 B<-a nbd://example.com[:port]/exportname> -@@ -1195,41 +1161,6 @@ The equivalent API command would be (no export name): - - > add "" protocol:nbd server:[tcp:example.com|unix:/socket] - --=head2 B<-a rbd:///pool/disk> -- --=head2 B<-a rbd://example.com[:port]/pool/disk> -- --Add a disk image located on a Ceph (RBD/librbd) storage volume. -- --Although libguestfs and Ceph supports multiple servers, only a single --server can be specified when using this URI syntax. -- --The equivalent API command would be: -- -- > add pool/disk protocol:rbd server:tcp:example.com:port -- --=head2 B<-a sheepdog://[example.com[:port]]/volume/image> -- --Add a disk image located on a Sheepdog volume. -- --The server name is optional. Although libguestfs and Sheepdog --supports multiple servers, only at most one server can be specified --when using this URI syntax. -- --The equivalent API command would be: -- -- > add volume protocol:sheepdog [server:tcp:example.com] -- --=head2 B<-a ssh://[user@]example.com[:port]/disk.img> -- --Add a disk image located on a remote server, accessed using the Secure --Shell (ssh) SFTP protocol. SFTP is supported out of the box by all --major SSH servers. -- --The equivalent API command would be: -- -- > add /disk protocol:ssh server:tcp:example.com [username:user] -- - =head1 PROGRESS BARS - - Some (not all) long-running commands send progress notification -diff --git a/fish/test-add-uri.sh b/fish/test-add-uri.sh -index 2f83754..5ace327 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 - grep -sq 'add_drive ".*/test-add-uri.img"' test-add-uri.out || fail - --# curl --$VG guestfish -x -a ftp://user@example.com/disk.img test-add-uri.out 2>&1 --grep -sq 'add_drive "/disk.img" "protocol:ftp" "server:tcp:example.com" "username:user"' test-add-uri.out || fail -- --# gluster --$VG guestfish -x -a gluster://example.com/disk test-add-uri.out 2>&1 --grep -sq 'add_drive "disk" "protocol:gluster" "server:tcp:example.com"' test-add-uri.out || fail -- - # NBD - $VG guestfish -x -a nbd://example.com test-add-uri.out 2>&1 - grep -sq 'add_drive "" "protocol:nbd" "server:tcp:example.com"' test-add-uri.out || fail -@@ -58,28 +50,5 @@ grep -sq 'add_drive "" "protocol:nbd" "server:unix:/sk"' test-add-uri.out || fai - $VG guestfish -x -a 'nbd:///export?socket=/sk' test-add-uri.out 2>&1 - grep -sq 'add_drive "/export" "protocol:nbd" "server:unix:/sk"' test-add-uri.out || fail - --# rbd --$VG guestfish -x -a rbd://example.com:6789/pool/disk test-add-uri.out 2>&1 --grep -sq 'add_drive "pool/disk" "protocol:rbd" "server:tcp:example.com:6789"' test-add-uri.out || fail --$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 -- --# sheepdog --$VG guestfish -x -a sheepdog:///volume/image test-add-uri.out 2>&1 --grep -sq 'add_drive "volume/image" "protocol:sheepdog"' test-add-uri.out || fail -- --$VG guestfish -x -a sheepdog://example.com:3000/volume/image test-add-uri.out 2>&1 --grep -sq 'add_drive "volume/image" "protocol:sheepdog" "server:tcp:example.com:3000"' test-add-uri.out || fail -- --# ssh --$VG guestfish -x -a ssh://example.com/disk.img test-add-uri.out 2>&1 --grep -sq 'add_drive "/disk.img" "protocol:ssh" "server:tcp:example.com"' test-add-uri.out || fail -- --$VG guestfish -x -a ssh://user@example.com/disk.img test-add-uri.out 2>&1 --grep -sq 'add_drive "/disk.img" "protocol:ssh" "server:tcp:example.com" "username:user"' test-add-uri.out || fail -- --$VG guestfish -x -a ssh://user@example.com:2000/disk.img test-add-uri.out 2>&1 --grep -sq 'add_drive "/disk.img" "protocol:ssh" "server:tcp:example.com:2000" "username:user"' test-add-uri.out || fail -- - rm test-add-uri.out - rm test-add-uri.img -diff --git a/generator/actions.ml b/generator/actions.ml -index 20e9774..88405d0 100644 ---- a/generator/actions.ml -+++ b/generator/actions.ml -@@ -1397,27 +1397,6 @@ C is interpreted as a local file or device. - This is the default if the optional protocol parameter - is omitted. - --=item C -- --Connect to a remote FTP, HTTP or TFTP server. --The C parameter must also be supplied - see below. -- --See also: L -- --=item C -- --Connect to the GlusterFS server. --The C parameter must also be supplied - see below. -- --See also: L -- --=item C -- --Connect to the iSCSI server. --The C parameter must also be supplied - see below. -- --See also: L. -- - =item C - - Connect to the Network Block Device server. -@@ -1425,31 +1404,6 @@ The C parameter must also be supplied - see below. - - See also: L. - --=item C -- --Connect to the Ceph (librbd/RBD) server. --The C parameter must also be supplied - see below. --The C parameter may be supplied. See below. --The C parameter may be supplied. See below. -- --See also: L. -- --=item C -- --Connect to the Sheepdog server. --The C parameter may also be supplied - see below. -- --See also: L. -- --=item C -- --Connect to the Secure Shell (ssh) server. -- --The C parameter must be supplied. --The C parameter may be supplied. See below. -- --See also: L. -- - =back - - =item C -@@ -1460,13 +1414,7 @@ is a list of server(s). - Protocol Number of servers required - -------- -------------------------- - file List must be empty or param not used at all -- ftp|ftps|http|https|tftp Exactly one -- gluster Exactly one -- iscsi Exactly one - nbd Exactly one -- rbd Zero or more -- sheepdog Zero or more -- ssh Exactly one - - Each list element is a string specifying a server. The string must be - in one of the following formats: -@@ -1480,26 +1428,6 @@ in one of the following formats: - If the port number is omitted, then the standard port number - for the protocol is used (see C). - --=item C -- --For the C, C, C, C, C, C, C --and C protocols, this specifies the remote username. -- --If not given, then the local username is used for C, and no authentication --is attempted for ceph. But note this sometimes may give unexpected results, for --example if using the libvirt backend and if the libvirt backend is configured to --start the qemu appliance as a special user such as C. If in doubt, --specify the remote username you want. -- --=item C -- --For the C protocol only, this specifies the 'secret' to use when --connecting to the remote device. -- --If not given, then a secret matching the given username will be looked up in the --default keychain locations, or if no username is given, then no authentication --will be used. -- - =item C - - Choose whether or not libguestfs will obey sync operations (safe but slow) -diff --git a/src/drives.c b/src/drives.c -index 307f267..b80af78 100644 ---- a/src/drives.c -+++ b/src/drives.c -@@ -199,6 +199,7 @@ create_drive_non_file (guestfs_h *g, - return drv; - } - -+#if 0 /* DISABLED IN RHEL 7 */ - static struct drive * - create_drive_curl (guestfs_h *g, - const struct drive_create_data *data) -@@ -257,6 +258,7 @@ create_drive_gluster (guestfs_h *g, - - return create_drive_non_file (g, data); - } -+#endif /* DISABLED IN RHEL 7 */ - - static int - nbd_port (void) -@@ -294,6 +296,7 @@ create_drive_nbd (guestfs_h *g, - return create_drive_non_file (g, data); - } - -+#if 0 /* DISABLED IN RHEL 7 */ - static struct drive * - create_drive_rbd (guestfs_h *g, - const struct drive_create_data *data) -@@ -435,6 +438,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 -@@ -882,6 +886,7 @@ guestfs__add_drive_opts (guestfs_h *g, const char *filename, - drv = create_drive_file (g, &data); - } - } -+#if 0 /* DISABLED IN RHEL 7 */ - else if (STREQ (protocol, "ftp")) { - data.protocol = drive_protocol_ftp; - drv = create_drive_curl (g, &data); -@@ -906,10 +911,12 @@ guestfs__add_drive_opts (guestfs_h *g, const char *filename, - data.protocol = drive_protocol_iscsi; - drv = create_drive_iscsi (g, &data); - } -+#endif /* DISABLED IN RHEL 7 */ - else if (STREQ (protocol, "nbd")) { - data.protocol = drive_protocol_nbd; - drv = create_drive_nbd (g, &data); - } -+#if 0 /* DISABLED IN RHEL 7 */ - else if (STREQ (protocol, "rbd")) { - data.protocol = drive_protocol_rbd; - drv = create_drive_rbd (g, &data); -@@ -926,6 +933,7 @@ guestfs__add_drive_opts (guestfs_h *g, const char *filename, - data.protocol = drive_protocol_tftp; - drv = create_drive_curl (g, &data); - } -+#endif /* DISABLED IN RHEL 7 */ - else { - error (g, _("unknown protocol '%s'"), protocol); - drv = NULL; /*FALLTHROUGH*/ -diff --git a/src/guestfs.pod b/src/guestfs.pod -index c9ac1fa..5792f15 100644 ---- a/src/guestfs.pod -+++ b/src/guestfs.pod -@@ -674,91 +674,6 @@ you don't need to add any disks. - - =head2 REMOTE STORAGE - --=head3 CEPH -- --Libguestfs can access Ceph (librbd/RBD) disks. -- --To do this, set the optional C and C parameters of --L like this: -- -- char **servers = { "ceph1.example.org:3000", /* ... */, NULL }; -- guestfs_add_drive_opts (g, "pool/image", -- GUESTFS_ADD_DRIVE_OPTS_FORMAT, "raw", -- GUESTFS_ADD_DRIVE_OPTS_PROTOCOL, "rbd", -- GUESTFS_ADD_DRIVE_OPTS_SERVER, servers, -- GUESTFS_ADD_DRIVE_OPTS_USERNAME, "rbduser", -- GUESTFS_ADD_DRIVE_OPTS_SECRET, "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==", -- -1); -- --C (the C parameter) is a list of one or more Ceph --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. -- --=head3 FTP, HTTP AND TFTP -- --Libguestfs can access remote disks over FTP, FTPS, HTTP, HTTPS --or TFTP protocols. -- --To do this, set the optional C and C parameters of --L like this: -- -- char **servers = { "www.example.org", NULL }; -- guestfs_add_drive_opts (g, "/disk.img", -- GUESTFS_ADD_DRIVE_OPTS_FORMAT, "raw", -- GUESTFS_ADD_DRIVE_OPTS_PROTOCOL, "http", -- GUESTFS_ADD_DRIVE_OPTS_SERVER, servers, -- -1); -- --The C can be one of C<"ftp">, C<"ftps">, C<"http">, --C<"https"> or C<"tftp">. -- --C (the C parameter) is a list which must have a --single element. The single element is a string defining the web, --FTP or TFTP server. The format of this string is documented in --L. -- --=head3 GLUSTER -- --Libguestfs can access Gluster disks. -- --To do this, set the optional C and C parameters of --L like this: -- -- char **servers = { "gluster.example.org:24007", NULL }; -- guestfs_add_drive_opts (g, "volname/image", -- GUESTFS_ADD_DRIVE_OPTS_FORMAT, "raw", -- GUESTFS_ADD_DRIVE_OPTS_PROTOCOL, "gluster", -- GUESTFS_ADD_DRIVE_OPTS_SERVER, servers, -- -1); -- --C (the C parameter) is a list which must have a --single element. The single element is a string defining the Gluster --server. The format of this string is documented in --L. -- --Note that gluster usually requires the client process (ie. libguestfs) --to run as B and will give unfathomable errors if it is not --(eg. "No data available"). -- --=head3 ISCSI -- --Libguestfs can access iSCSI disks remotely. -- --To do this, set the optional C and C parameters like --this: -- -- char **server = { "iscsi.example.org:3000", NULL }; -- guestfs_add_drive_opts (g, "target-iqn-name/lun", -- GUESTFS_ADD_DRIVE_OPTS_FORMAT, "raw", -- GUESTFS_ADD_DRIVE_OPTS_PROTOCOL, "iscsi", -- GUESTFS_ADD_DRIVE_OPTS_SERVER, server, -- -1); -- --The C parameter is a list which must have a single element. --The single element is a string defining the iSCSI server. The format --of this string is documented in L. -- - =head3 NETWORK BLOCK DEVICE - - Libguestfs can access Network Block Device (NBD) disks remotely. -@@ -821,42 +736,6 @@ L - - =back - --=head3 SHEEPDOG -- --Libguestfs can access Sheepdog disks. -- --To do this, set the optional C and C parameters of --L like this: -- -- char **servers = { /* optional servers ... */ NULL }; -- guestfs_add_drive_opts (g, "volume", -- GUESTFS_ADD_DRIVE_OPTS_FORMAT, "raw", -- GUESTFS_ADD_DRIVE_OPTS_PROTOCOL, "sheepdog", -- GUESTFS_ADD_DRIVE_OPTS_SERVER, servers, -- -1); -- --The optional list of C may be zero or more server addresses --(C<"hostname:port">). The format of the server strings is documented --in L. -- --=head3 SSH -- --Libguestfs can access disks over a Secure Shell (SSH) connection. -- --To do this, set the C and C and (optionally) --C parameters of L like this: -- -- char **server = { "remote.example.com", NULL }; -- guestfs_add_drive_opts (g, "/path/to/disk.img", -- GUESTFS_ADD_DRIVE_OPTS_FORMAT, "raw", -- GUESTFS_ADD_DRIVE_OPTS_PROTOCOL, "ssh", -- GUESTFS_ADD_DRIVE_OPTS_SERVER, server, -- GUESTFS_ADD_DRIVE_OPTS_USERNAME, "remoteuser", -- -1); -- --The format of the server string is documented in --L. -- - =head2 INSPECTION - - Libguestfs has APIs for inspecting an unknown disk image to find out -diff --git a/tests/disks/test-qemu-drive-libvirt.sh b/tests/disks/test-qemu-drive-libvirt.sh -index 9930865..31d4838 100755 ---- a/tests/disks/test-qemu-drive-libvirt.sh -+++ b/tests/disks/test-qemu-drive-libvirt.sh -@@ -64,46 +64,6 @@ function fail () - - rm -f "$DEBUG_QEMU_FILE" - --# Ceph (RBD). -- --$guestfish -d ceph1 run ||: --check_output --grep -sq -- '-drive file=rbd:abc-def/ghi-jkl:mon_host=1.2.3.4\\:1234\\;1.2.3.5\\:1235\\;1.2.3.6\\:1236:auth_supported=none,' "$DEBUG_QEMU_FILE" || fail --rm "$DEBUG_QEMU_FILE" -- --$guestfish -d ceph2 run ||: --check_output --grep -sq -- '-drive file=rbd:abc-def/ghi-jkl:auth_supported=none,' "$DEBUG_QEMU_FILE" || fail --rm "$DEBUG_QEMU_FILE" -- --# Gluster. -- --$guestfish -d gluster run ||: --check_output --grep -sq -- '-drive file=gluster://1.2.3.4:1234/volname/image,' "$DEBUG_QEMU_FILE" || fail --rm "$DEBUG_QEMU_FILE" -- --# iSCSI. -- --$guestfish -d iscsi run ||: --check_output --grep -sq -- '-drive file=iscsi://1.2.3.4:1234/iqn.2003-01.org.linux-iscsi.fedora,' "$DEBUG_QEMU_FILE" || fail --rm "$DEBUG_QEMU_FILE" -- --# NBD. -- --$guestfish -d nbd run ||: --check_output --grep -sq -- '-drive file=nbd:1.2.3.4:1234,' "$DEBUG_QEMU_FILE" || fail --rm "$DEBUG_QEMU_FILE" -- --# Sheepdog. -- --$guestfish -d sheepdog run ||: --check_output --grep -sq -- '-drive file=sheepdog:volume,' "$DEBUG_QEMU_FILE" || fail --rm "$DEBUG_QEMU_FILE" -- - # To do: - - # HTTP - curl not yet supported by libvirt -diff --git a/tests/disks/test-qemu-drive.sh b/tests/disks/test-qemu-drive.sh -index b530e7d..f4e718a 100755 ---- a/tests/disks/test-qemu-drive.sh -+++ b/tests/disks/test-qemu-drive.sh -@@ -42,55 +42,6 @@ function fail () - - rm -f "$DEBUG_QEMU_FILE" - --# Ceph (RBD). -- --guestfish < +Date: Tue, 9 Dec 2014 14:06:18 +0000 +Subject: [PATCH] inspection: Not an installer if there are multiple partitions + (RHBZ#1171666). + +Regular EFI disks have /EFI on the first (VFAT) partition, but they +are not installers. + +Fix this by only considering something to be an installer if it has a +single partition (or whole disks like ISOs). + +Implementing this is quite complex since when checking a filesystem, +we don't have information about whether we are even looking at a +partition, nor about whether it's the first partition out of how many. +The majority of the commit is changing the code to collect that +information. + +(cherry picked from commit bdf772db3286487adefa56b966435f2dd638e0a8) +--- + src/guestfs-internal.h | 1 + + src/inspect-fs-unix.c | 31 ++++--------------------------- + src/inspect-fs.c | 44 ++++++++++++++++++++++++++++++++++++++------ + src/inspect.c | 22 ++++++++++++++++++++++ + 4 files changed, 65 insertions(+), 33 deletions(-) + +diff --git a/src/guestfs-internal.h b/src/guestfs-internal.h +index d9ccf5f..65f3388 100644 +--- a/src/guestfs-internal.h ++++ b/src/guestfs-internal.h +@@ -751,6 +751,7 @@ extern int guestfs___set_backend (guestfs_h *g, const char *method); + extern void guestfs___free_inspect_info (guestfs_h *g); + extern char *guestfs___download_to_tmp (guestfs_h *g, struct inspect_fs *fs, const char *filename, const char *basename, uint64_t max_size); + extern struct inspect_fs *guestfs___search_for_root (guestfs_h *g, const char *root); ++extern int guestfs___is_partition (guestfs_h *g, const char *partition); + + /* inspect-fs.c */ + extern int guestfs___is_file_nocase (guestfs_h *g, const char *); +diff --git a/src/inspect-fs-unix.c b/src/inspect-fs-unix.c +index fb5cc1a..8778e92 100644 +--- a/src/inspect-fs-unix.c ++++ b/src/inspect-fs-unix.c +@@ -185,7 +185,6 @@ static int add_fstab_entry (guestfs_h *g, struct inspect_fs *fs, + static char *resolve_fstab_device (guestfs_h *g, const char *spec, + Hash_table *md_map); + static int inspect_with_augeas (guestfs_h *g, struct inspect_fs *fs, const char **configfiles, int (*f) (guestfs_h *, struct inspect_fs *)); +-static int is_partition (guestfs_h *g, const char *partition); + + /* Hash structure for uuid->path lookups */ + typedef struct md_uuid { +@@ -1436,7 +1435,7 @@ resolve_fstab_device_xdev (guestfs_h *g, const char *type, const char *disk, + ITER_DRIVES (g, i, drv) { + if (drv->name && STREQ (drv->name, name)) { + device = safe_asprintf (g, "%s%s", devices[i], part); +- if (!is_partition (g, device)) { ++ if (!guestfs___is_partition (g, device)) { + free (device); + return 0; + } +@@ -1463,7 +1462,7 @@ resolve_fstab_device_xdev (guestfs_h *g, const char *type, const char *disk, + */ + if (i < count) { + device = safe_asprintf (g, "%s%s", devices[i], part); +- if (!is_partition (g, device)) { ++ if (!guestfs___is_partition (g, device)) { + free (device); + return 0; + } +@@ -1496,7 +1495,7 @@ resolve_fstab_device_cciss (guestfs_h *g, const char *disk, const char *part, + if (drv->name && STREQ (drv->name, disk)) { + if (part) { + device = safe_asprintf (g, "%s%s", devices[i], part); +- if (!is_partition (g, device)) { ++ if (!guestfs___is_partition (g, device)) { + free (device); + return 0; + } +@@ -1541,7 +1540,7 @@ resolve_fstab_device_diskbyid (guestfs_h *g, const char *part, + + /* Make the partition name and check it exists. */ + device = safe_asprintf (g, "/dev/sda%s", part); +- if (!is_partition (g, device)) { ++ if (!guestfs___is_partition (g, device)) { + free (device); + return 0; + } +@@ -1753,25 +1752,3 @@ make_augeas_path_expression (guestfs_h *g, const char **configfiles) + debug (g, "augeas pathexpr = %s", ret); + return ret; + } +- +-static int +-is_partition (guestfs_h *g, const char *partition) +-{ +- CLEANUP_FREE char *device = NULL; +- +- guestfs_push_error_handler (g, NULL, NULL); +- +- if ((device = guestfs_part_to_dev (g, partition)) == NULL) { +- guestfs_pop_error_handler (g); +- return 0; +- } +- +- if (guestfs_device_index (g, device) == -1) { +- guestfs_pop_error_handler (g); +- return 0; +- } +- +- guestfs_pop_error_handler (g); +- +- return 1; +-} +diff --git a/src/inspect-fs.c b/src/inspect-fs.c +index 539d814..686d1ae 100644 +--- a/src/inspect-fs.c ++++ b/src/inspect-fs.c +@@ -83,6 +83,7 @@ static int check_filesystem (guestfs_h *g, const char *mountable, + const struct guestfs_internal_mountable *m, + int whole_device); + static int extend_fses (guestfs_h *g); ++static int get_partition_context (guestfs_h *g, const char *partition, int *partnum_ret, int *nr_partitions_ret); + + /* Find out if 'device' contains a filesystem. If it does, add + * another entry in g->fses. +@@ -175,17 +176,18 @@ check_filesystem (guestfs_h *g, const char *mountable, + const struct guestfs_internal_mountable *m, + int whole_device) + { ++ int partnum = -1, nr_partitions = -1; + /* Not CLEANUP_FREE, as it will be cleaned up with inspection info */ + char *windows_systemroot = NULL; + + if (extend_fses (g) == -1) + return -1; + +- int partnum = -1; +- if (!whole_device && m->im_type == MOUNTABLE_DEVICE) { +- guestfs_push_error_handler (g, NULL, NULL); +- partnum = guestfs_part_to_partnum (g, m->im_device); +- guestfs_pop_error_handler (g); ++ if (!whole_device && m->im_type == MOUNTABLE_DEVICE && ++ guestfs___is_partition (g, m->im_device)) { ++ if (get_partition_context (g, m->im_device, ++ &partnum, &nr_partitions) == -1) ++ return -1; + } + + struct inspect_fs *fs = &g->fses[g->nr_fses-1]; +@@ -324,7 +326,7 @@ check_filesystem (guestfs_h *g, const char *mountable, + * Skip these checks if it's not a whole device (eg. CD) or the + * first partition (eg. bootable USB key). + */ +- else if ((whole_device || partnum == 1) && ++ else if ((whole_device || (partnum == 1 && nr_partitions == 1)) && + (guestfs_is_file (g, "/isolinux/isolinux.cfg") > 0 || + guestfs_is_dir (g, "/EFI/BOOT") > 0 || + guestfs_is_file (g, "/images/install.img") > 0 || +@@ -369,6 +371,36 @@ extend_fses (guestfs_h *g) + return 0; + } + ++/* Given a partition (eg. /dev/sda2) then return the partition number ++ * (eg. 2) and the total number of other partitions. ++ */ ++static int ++get_partition_context (guestfs_h *g, const char *partition, ++ int *partnum_ret, int *nr_partitions_ret) ++{ ++ int partnum, nr_partitions; ++ CLEANUP_FREE char *device = NULL; ++ CLEANUP_FREE_PARTITION_LIST struct guestfs_partition_list *partitions = NULL; ++ ++ partnum = guestfs_part_to_partnum (g, partition); ++ if (partnum == -1) ++ return -1; ++ ++ device = guestfs_part_to_dev (g, partition); ++ if (device == NULL) ++ return -1; ++ ++ partitions = guestfs_part_list (g, device); ++ if (partitions == NULL) ++ return -1; ++ ++ nr_partitions = partitions->len; ++ ++ *partnum_ret = partnum; ++ *nr_partitions_ret = nr_partitions; ++ return 0; ++} ++ + int + guestfs___is_file_nocase (guestfs_h *g, const char *path) + { +diff --git a/src/inspect.c b/src/inspect.c +index 9248b06..03d870f 100644 +--- a/src/inspect.c ++++ b/src/inspect.c +@@ -590,3 +590,25 @@ guestfs___search_for_root (guestfs_h *g, const char *root) + root); + return NULL; + } ++ ++int ++guestfs___is_partition (guestfs_h *g, const char *partition) ++{ ++ CLEANUP_FREE char *device = NULL; ++ ++ guestfs_push_error_handler (g, NULL, NULL); ++ ++ if ((device = guestfs_part_to_dev (g, partition)) == NULL) { ++ guestfs_pop_error_handler (g); ++ return 0; ++ } ++ ++ if (guestfs_device_index (g, device) == -1) { ++ guestfs_pop_error_handler (g); ++ return 0; ++ } ++ ++ guestfs_pop_error_handler (g); ++ ++ return 1; ++} +-- +1.8.3.1 + diff --git a/SOURCES/0093-RHEL-7-Remove-User-Mode-Linux-RHBZ-1144197.patch b/SOURCES/0093-RHEL-7-Remove-User-Mode-Linux-RHBZ-1144197.patch deleted file mode 100644 index 9092e5d..0000000 --- a/SOURCES/0093-RHEL-7-Remove-User-Mode-Linux-RHBZ-1144197.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 30c0036372d20d065579ce2a1148fd526320fc89 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -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 | 7 +++++++ - 1 file changed, 7 insertions(+) - -diff --git a/src/launch-uml.c b/src/launch-uml.c -index 21525e3..b631389 100644 ---- a/src/launch-uml.c -+++ b/src/launch-uml.c -@@ -136,6 +136,12 @@ uml_supported (guestfs_h *g) - static int - launch_uml (guestfs_h *g, void *datav, const char *arg) - { -+ error (g, -+ "launch: In RHEL, only the 'libvirt' or 'direct' method is supported.\n" -+ "In particular, User-Mode Linux (UML) is not supported."); -+ return -1; -+ -+#if 0 - struct backend_uml_data *data = datav; - CLEANUP_FREE_STRINGSBUF DECLARE_STRINGSBUF (cmdline); - int console_sock = -1, daemon_sock = -1; -@@ -503,6 +509,7 @@ launch_uml (guestfs_h *g, void *datav, const char *arg) - } - g->state = CONFIG; - return -1; -+#endif - } - - /* This is called from the forked subprocess just before vmlinux runs, --- -1.8.3.1 - diff --git a/SOURCES/0093-daemon-Fix-whitespace.patch b/SOURCES/0093-daemon-Fix-whitespace.patch new file mode 100644 index 0000000..1f20159 --- /dev/null +++ b/SOURCES/0093-daemon-Fix-whitespace.patch @@ -0,0 +1,26 @@ +From db9bfb914f0510baadea3752b3b0faee6d1ce46a Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Thu, 5 Feb 2015 08:01:48 +0000 +Subject: [PATCH] daemon: Fix whitespace. + +(cherry picked from commit b3e3750b13a96fb6d1b79f7c0dabb4eeb37de5ef) +--- + daemon/parted.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/daemon/parted.c b/daemon/parted.c +index a730477..76c0ce9 100644 +--- a/daemon/parted.c ++++ b/daemon/parted.c +@@ -759,7 +759,7 @@ optgroup_gdisk_available (void) + } + + int +-do_part_set_gpt_type(const char *device, int partnum, const char *guid) ++do_part_set_gpt_type (const char *device, int partnum, const char *guid) + { + if (partnum <= 0) { + reply_with_error ("partition number must be >= 1"); +-- +1.8.3.1 + diff --git a/SOURCES/0094-New-APIs-part-set-gpt-guid-and-part-get-gpt-guid.patch b/SOURCES/0094-New-APIs-part-set-gpt-guid-and-part-get-gpt-guid.patch new file mode 100644 index 0000000..37bba84 --- /dev/null +++ b/SOURCES/0094-New-APIs-part-set-gpt-guid-and-part-get-gpt-guid.patch @@ -0,0 +1,126 @@ +From 3aab860529f7d13b00b3689fa79c72b12d2f9770 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Thu, 5 Feb 2015 08:08:06 +0000 +Subject: [PATCH] New APIs: part-set-gpt-guid and part-get-gpt-guid + +In GPT, each partition has a GUID assigned randomly. Allow this GUID +to be written and read. + +Note this is different from the GUID type code which is used to +identify the type of the partition. + +(cherry picked from commit 40c133b2c81666f6dde43704e66bf59206d5c111) +--- + daemon/parted.c | 33 +++++++++++++++++++++++++++++++++ + generator/actions.ml | 36 ++++++++++++++++++++++++++++++++++++ + src/MAX_PROC_NR | 2 +- + 3 files changed, 70 insertions(+), 1 deletion(-) + +diff --git a/daemon/parted.c b/daemon/parted.c +index 76c0ce9..36844b8 100644 +--- a/daemon/parted.c ++++ b/daemon/parted.c +@@ -784,6 +784,32 @@ do_part_set_gpt_type (const char *device, int partnum, const char *guid) + return 0; + } + ++int ++do_part_set_gpt_guid (const char *device, int partnum, const char *guid) ++{ ++ if (partnum <= 0) { ++ reply_with_error ("partition number must be >= 1"); ++ return -1; ++ } ++ ++ CLEANUP_FREE char *typecode = NULL; ++ if (asprintf (&typecode, "%i:%s", partnum, guid) == -1) { ++ reply_with_perror ("asprintf"); ++ return -1; ++ } ++ ++ CLEANUP_FREE char *err = NULL; ++ int r = commandf (NULL, &err, COMMAND_FLAG_FOLD_STDOUT_ON_STDERR, ++ str_sgdisk, device, "-u", typecode, NULL); ++ ++ if (r == -1) { ++ reply_with_error ("%s %s -u %s: %s", str_sgdisk, device, typecode, err); ++ return -1; ++ } ++ ++ return 0; ++} ++ + static char * + sgdisk_info_extract_field (const char *device, int partnum, const char *field, + char *(*extract) (const char *path)) +@@ -894,6 +920,13 @@ do_part_get_gpt_type (const char *device, int partnum) + } + + char * ++do_part_get_gpt_guid (const char *device, int partnum) ++{ ++ return sgdisk_info_extract_field (device, partnum, ++ "Partition unique GUID", extract_uuid); ++} ++ ++char * + do_part_get_name (const char *device, int partnum) + { + CLEANUP_FREE char *parttype; +diff --git a/generator/actions.ml b/generator/actions.ml +index 593e51b..825acf9 100644 +--- a/generator/actions.ml ++++ b/generator/actions.ml +@@ -11995,6 +11995,42 @@ This is the same as the C system call." }; + longdesc = "\ + This is the internal call which implements C." }; + ++ { defaults with ++ name = "part_set_gpt_guid"; ++ style = RErr, [Device "device"; Int "partnum"; GUID "guid"], []; ++ proc_nr = Some 446; ++ optional = Some "gdisk"; ++ tests = [ ++ InitGPT, Always, TestLastFail ( ++ [["part_set_gpt_guid"; "/dev/sda"; "1"; "f"]]), []; ++ InitGPT, Always, TestResultString ( ++ [["part_set_gpt_guid"; "/dev/sda"; "1"; ++ "01234567-89AB-CDEF-0123-456789ABCDEF"]; ++ ["part_get_gpt_guid"; "/dev/sda"; "1"]], ++ "01234567-89AB-CDEF-0123-456789ABCDEF"), []; ++ ]; ++ shortdesc = "set the GUID of a GPT partition"; ++ longdesc = "\ ++Set the GUID of numbered GPT partition C to C. Return an ++error if the partition table of C isn't GPT, or if C is not a ++valid GUID." }; ++ ++ { defaults with ++ name = "part_get_gpt_guid"; ++ style = RString "guid", [Device "device"; Int "partnum"], []; ++ proc_nr = Some 447; ++ optional = Some "gdisk"; ++ tests = [ ++ InitGPT, Always, TestResultString ( ++ [["part_set_gpt_guid"; "/dev/sda"; "1"; ++ "01234567-89AB-CDEF-0123-456789ABCDEF"]; ++ ["part_get_gpt_guid"; "/dev/sda"; "1"]], ++ "01234567-89AB-CDEF-0123-456789ABCDEF"), []; ++ ]; ++ shortdesc = "get the GUID of a GPT partition"; ++ longdesc = "\ ++Return the GUID of numbered GPT partition C." }; ++ + ] + + (* Non-API meta-commands available only in guestfish. +diff --git a/src/MAX_PROC_NR b/src/MAX_PROC_NR +index 5721413..e9b7520 100644 +--- a/src/MAX_PROC_NR ++++ b/src/MAX_PROC_NR +@@ -1 +1 @@ +-423 ++447 +-- +1.8.3.1 + diff --git a/SOURCES/0094-RHEL-7-v2v-Select-correct-qemu-binary-for-o-qemu-mod.patch b/SOURCES/0094-RHEL-7-v2v-Select-correct-qemu-binary-for-o-qemu-mod.patch deleted file mode 100644 index 8c3e970..0000000 --- a/SOURCES/0094-RHEL-7-v2v-Select-correct-qemu-binary-for-o-qemu-mod.patch +++ /dev/null @@ -1,33 +0,0 @@ -From f69232041b0fa3e35ca62aa5d09ad35af517af06 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 - (RHBZ#1147313). - -RHEL 7 does not have qemu-system-x86_64 (etc), and in addition the -qemu binary is located in /usr/libexec. Encode the path to this -binary directly in the script. - -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 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/v2v/output_qemu.ml b/v2v/output_qemu.ml -index 75644c2..9c17121 100644 ---- a/v2v/output_qemu.ml -+++ b/v2v/output_qemu.ml -@@ -48,7 +48,7 @@ object - let nl = " \\\n\t" in - fpf "#!/bin/sh -\n"; - fpf "\n"; -- 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; --- -1.8.3.1 - diff --git a/SOURCES/0095-RHEL-7-v2v-Disable-the-qemu-boot-option-RHBZ-1147313.patch b/SOURCES/0095-RHEL-7-v2v-Disable-the-qemu-boot-option-RHBZ-1147313.patch deleted file mode 100644 index 03b076a..0000000 --- a/SOURCES/0095-RHEL-7-v2v-Disable-the-qemu-boot-option-RHBZ-1147313.patch +++ /dev/null @@ -1,78 +0,0 @@ -From 508fe3be891f0967577bdf6621564443f3c2309c 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). - -This cannot work because there is no Gtk or SDL output mode -in RHEL 7's qemu-kvm. - -In addition you will have to edit the -display option in the -qemu script. ---- - v2v/cmdline.ml | 4 +++- - v2v/virt-v2v.pod | 13 ------------- - 2 files changed, 3 insertions(+), 14 deletions(-) - -diff --git a/v2v/cmdline.ml b/v2v/cmdline.ml -index 01f3335..14c3fb9 100644 ---- a/v2v/cmdline.ml -+++ b/v2v/cmdline.ml -@@ -168,7 +168,7 @@ let parse_cmdline () = - "-os", Arg.Set_string output_storage, "storage " ^ s_"Set output storage location"; - "--password-file", Arg.Set_string 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)"; -+ "--qemu-boot", Arg.Set qemu_boot, " " ^ s_"This option cannot be used in RHEL"; - "-q", Arg.Set quiet, " " ^ s_"Quiet output"; - "--quiet", Arg.Set quiet, ditto; - "--root", Arg.String set_root_choice,"ask|... " ^ s_"How to choose root filesystem"; -@@ -364,6 +364,8 @@ read the man page virt-v2v(1). - if not (is_directory output_storage) then - error (f_"-os %s: output directory does not exist or is not a directory") - output_storage; -+ if qemu_boot then -+ error (f_"-o qemu: the --qemu-boot option cannot be used in RHEL"); - Output_qemu.output_qemu verbose output_storage qemu_boot - - | `RHEV -> -diff --git a/v2v/virt-v2v.pod b/v2v/virt-v2v.pod -index 5f4d42e..9edb2ca 100644 ---- a/v2v/virt-v2v.pod -+++ b/v2v/virt-v2v.pod -@@ -139,11 +139,6 @@ Since C 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. - --To convert a local disk image and immediately boot it in local --qemu, do: -- -- virt-v2v -i disk disk.img -o qemu -os /var/tmp --qemu-boot -- - =head1 OPTIONS - - =over 4 -@@ -350,9 +345,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> - - Set the output method to I. -@@ -436,11 +428,6 @@ Print information about the source guest and stop. This option is - useful when you are setting up network and bridge maps. - See L. - --=item B<--qemu-boot> -- --When using I<-o qemu> only, this boots the guest immediately after --virt-v2v finishes. -- - =item B<-q> - - =item B<--quiet> --- -1.8.3.1 - diff --git a/SOURCES/0095-resize-Preserve-GPT-GUID-so-we-don-t-break-EFI-bootl.patch b/SOURCES/0095-resize-Preserve-GPT-GUID-so-we-don-t-break-EFI-bootl.patch new file mode 100644 index 0000000..66e31ff --- /dev/null +++ b/SOURCES/0095-resize-Preserve-GPT-GUID-so-we-don-t-break-EFI-bootl.patch @@ -0,0 +1,82 @@ +From 2149aa86bc0b0484e2144c9c441926eab52bd102 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Thu, 5 Feb 2015 08:13:05 +0000 +Subject: [PATCH] resize: Preserve GPT GUID so we don't break EFI bootloaders + (RHBZ#1189284). + +When copying disks that use EFI, we created a new partition table, +randomizing the GPT GUID of the first partition. Since EFI may store +the GUID in its NVRAM variables, this could make the guest unbootable. + +(cherry picked from commit f630677c14c7d5528e1ab39e4f805e0957b2ee3e) +--- + resize/resize.ml | 22 ++++++++++++++++++++-- + 1 file changed, 20 insertions(+), 2 deletions(-) + +diff --git a/resize/resize.ml b/resize/resize.ml +index 2090675..b581b39 100644 +--- a/resize/resize.ml ++++ b/resize/resize.ml +@@ -50,6 +50,7 @@ type partition = { + p_id : partition_id; (* Partition (MBR/GPT) ID. *) + p_type : partition_content; (* Content type and content size. *) + p_label : string option; (* Label/name. *) ++ p_guid : string option; (* Partition GUID (GPT only). *) + + (* What we're going to do: *) + mutable p_operation : partition_operation; +@@ -93,6 +94,11 @@ let rec debug_partition p = + (match p.p_label with + | Some label -> label + | None -> "(none)" ++ ); ++ printf "\tGUID: %s\n" ++ (match p.p_guid with ++ | Some guid -> guid ++ | None -> "(none)" + ) + and string_of_partition_content = function + | ContentUnknown -> "unknown data" +@@ -478,10 +484,16 @@ read the man page virt-resize(1). + let label = + try Some (g#part_get_name "/dev/sda" part_num) + with G.Error _ -> None in ++ let guid = ++ match parttype with ++ | MBR -> None ++ | GPT -> ++ try Some (g#part_get_gpt_guid "/dev/sda" part_num) ++ with G.Error _ -> None in + + { p_name = name; p_part = part; + p_bootable = bootable; p_id = id; p_type = typ; +- p_label = label; ++ p_label = label; p_guid = guid; + p_operation = OpCopy; p_target_partnum = 0; + p_target_start = 0L; p_target_end = 0L } + ) parts in +@@ -1068,7 +1080,7 @@ read the man page virt-resize(1). + p_part = { G.part_num = 0l; part_start = 0L; part_end = 0L; + part_size = 0L }; + p_bootable = false; p_id = No_ID; p_type = ContentUnknown; +- p_label = None; ++ p_label = None; p_guid = None; + + (* Target information is meaningful. *) + p_operation = OpIgnore; +@@ -1162,6 +1174,12 @@ read the man page virt-resize(1). + | None -> () + ); + ++ (match p.p_guid with ++ | Some guid -> ++ g#part_set_gpt_guid "/dev/sdb" p.p_target_partnum guid; ++ | None -> () ++ ); ++ + match parttype, p.p_id with + | GPT, GPT_Type gpt_type -> + g#part_set_gpt_type "/dev/sdb" p.p_target_partnum gpt_type +-- +1.8.3.1 + diff --git a/SOURCES/0096-RHEL-7-Remove-libguestfs-live-RHBZ-798980.patch b/SOURCES/0096-RHEL-7-Remove-libguestfs-live-RHBZ-798980.patch new file mode 100644 index 0000000..d434ece --- /dev/null +++ b/SOURCES/0096-RHEL-7-Remove-libguestfs-live-RHBZ-798980.patch @@ -0,0 +1,38 @@ +From db9af482e1afb7b776de08084c3e6c491ca6937f 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 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/src/launch-unix.c b/src/launch-unix.c +index 489a046..7956bed 100644 +--- a/src/launch-unix.c ++++ b/src/launch-unix.c +@@ -37,6 +37,12 @@ + static int + launch_unix (guestfs_h *g, void *datav, const char *sockpath) + { ++ error (g, ++ "launch: In RHEL, only the 'libvirt' or 'direct' method is supported.\n" ++ "In particular, \"libguestfs live\" is not supported."); ++ return -1; ++ ++#if 0 + int r, daemon_sock = -1; + struct sockaddr_un addr; + uint32_t size; +@@ -102,6 +108,7 @@ launch_unix (guestfs_h *g, void *datav, const char *sockpath) + g->conn = NULL; + } + return -1; ++#endif + } + + static int +-- +1.8.3.1 + diff --git a/SOURCES/0096-RHEL-7-Revert-tests-rsync-Skip-this-test-when-the-ba.patch b/SOURCES/0096-RHEL-7-Revert-tests-rsync-Skip-this-test-when-the-ba.patch deleted file mode 100644 index 5ba8fbb..0000000 --- a/SOURCES/0096-RHEL-7-Revert-tests-rsync-Skip-this-test-when-the-ba.patch +++ /dev/null @@ -1,74 +0,0 @@ -From 0511f916e395ba7f20324c999be60daf7c3463d2 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 - is libvirt." - -This reverts commit 765dc6237ce7b93dd2f33d99be53eae92e048a7a. ---- - tests/rsync/test-rsync.sh | 35 +++++++---------------------------- - 1 file changed, 7 insertions(+), 28 deletions(-) - -diff --git a/tests/rsync/test-rsync.sh b/tests/rsync/test-rsync.sh -index 53fcab8..793d59d 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 - --# Get host IP address. XXX Bit of a hack. --backend="$(guestfish get-backend)" --case "$backend" in -- direct) -- ip=169.254.2.2 -- listen_address=localhost -- ;; -- libvirt|libvirt:*) -- # This would work, except that the host firewall is effective -- # on virbr0, and that is likely to block the non-standard port -- # number that we listen on. --# ip="$(ip -4 -o address show virbr0 | --# awk '{print $4}' | --# awk -F/ '{print $1}')" --# listen_address="$ip" -- echo "$0: skipping test because host firewall will probably prevent this test from working" -- exit 77 -- ;; -- uml) -- echo "$0: skipping test because networking is not available in the UML backend" -- exit 77 -- ;; -- *) -- echo "$0: don't know how to get IP address of backend $backend" -- exit 77 -- ;; --esac -+if [ "$(guestfish get-backend)" = "uml" ]; then -+ echo "$0: skipping test because networking is not available in the UML backend" -+ 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, 18 Jul 2013 18:31:53 +0100 +Subject: [PATCH] RHEL 7: Remove 9p APIs from RHEL (RHBZ#921710). + +--- + Makefile.am | 2 +- + daemon/9p.c | 223 --------------------------------------------------- + daemon/Makefile.am | 1 - + generator/actions.ml | 23 ------ + gobject/Makefile.inc | 2 - + po/POTFILES | 2 - + 6 files changed, 1 insertion(+), 252 deletions(-) + delete mode 100644 daemon/9p.c + +diff --git a/Makefile.am b/Makefile.am +index d55d8d6..207bcb1 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -59,7 +59,7 @@ SUBDIRS += tests/xfs + SUBDIRS += tests/charsets + SUBDIRS += tests/xml + SUBDIRS += tests/mount-local +-SUBDIRS += tests/9p ++#SUBDIRS += tests/9p + SUBDIRS += tests/rsync + SUBDIRS += tests/bigdirs + SUBDIRS += tests/disk-labels +diff --git a/daemon/9p.c b/daemon/9p.c +deleted file mode 100644 +index fefbb71..0000000 +--- a/daemon/9p.c ++++ /dev/null +@@ -1,223 +0,0 @@ +-/* libguestfs - the guestfsd daemon +- * Copyright (C) 2011 Red Hat Inc. +- * +- * This program is free software; you can redistribute it and/or modify +- * it under the terms of the GNU General Public License as published by +- * the Free Software Foundation; either version 2 of the License, or +- * (at your option) any later version. +- * +- * This program is distributed in the hope that it will be useful, +- * but WITHOUT ANY WARRANTY; without even the implied warranty of +- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- * GNU General Public License for more details. +- * +- * You should have received a copy of the GNU General Public License +- * along with this program; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +- */ +- +-#include +- +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +- +-#include "daemon.h" +-#include "actions.h" +- +-#define BUS_PATH "/sys/bus/virtio/drivers/9pnet_virtio" +-GUESTFSD_EXT_CMD(str_mount, mount); +- +-static char *read_whole_file (const char *filename); +- +-/* https://bugzilla.redhat.com/show_bug.cgi?id=714981#c1 */ +-char ** +-do_list_9p (void) +-{ +- DECLARE_STRINGSBUF (r); +- +- DIR *dir; +- +- dir = opendir (BUS_PATH); +- if (!dir) { +- perror ("opendir: " BUS_PATH); +- if (errno != ENOENT) { +- reply_with_perror ("opendir: " BUS_PATH); +- return NULL; +- } +- +- /* If this directory doesn't exist, it probably means that +- * the virtio driver isn't loaded. Don't return an error +- * in this case, but return an empty list. +- */ +- if (end_stringsbuf (&r) == -1) +- return NULL; +- +- return r.argv; +- } +- +- while (1) { +- struct dirent *d; +- +- errno = 0; +- d = readdir (dir); +- 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); +- +- /* A bit unclear, but it looks like the virtio transport allows +- * the mount tag length to be unlimited (or up to 65536 bytes). +- * See: linux/include/linux/virtio_9p.h +- */ +- CLEANUP_FREE char *mount_tag = read_whole_file (mount_tag_path); +- if (mount_tag == 0) +- continue; +- +- if (add_string (&r, mount_tag) == -1) { +- closedir (dir); +- return NULL; +- } +- } +- } +- +- /* Check readdir didn't fail */ +- if (errno != 0) { +- reply_with_perror ("readdir: /sys/block"); +- free_stringslen (r.argv, r.size); +- closedir (dir); +- return NULL; +- } +- +- /* Close the directory handle */ +- if (closedir (dir) == -1) { +- reply_with_perror ("closedir: /sys/block"); +- free_stringslen (r.argv, r.size); +- return NULL; +- } +- +- /* Sort the tags. */ +- if (r.size > 0) +- sort_strings (r.argv, r.size); +- +- /* NULL terminate the list */ +- if (end_stringsbuf (&r) == -1) +- return NULL; +- +- return r.argv; +-} +- +-/* Read whole file into dynamically allocated array. If there is an +- * error, DON'T call reply_with_perror, just return NULL. Returns a +- * \0-terminated string. +- */ +-static char * +-read_whole_file (const char *filename) +-{ +- char *r = NULL; +- size_t alloc = 0, size = 0; +- int fd; +- +- fd = open (filename, O_RDONLY|O_CLOEXEC); +- if (fd == -1) { +- perror (filename); +- return NULL; +- } +- +- while (1) { +- alloc += 256; +- char *r2 = realloc (r, alloc); +- if (r2 == NULL) { +- perror ("realloc"); +- free (r); +- close (fd); +- return NULL; +- } +- r = r2; +- +- /* The '- 1' in the size calculation ensures there is space below +- * to add \0 to the end of the input. +- */ +- ssize_t n = read (fd, r + size, alloc - size - 1); +- if (n == -1) { +- fprintf (stderr, "read: %s: %m\n", filename); +- free (r); +- close (fd); +- return NULL; +- } +- if (n == 0) +- break; +- size += n; +- } +- +- if (close (fd) == -1) { +- fprintf (stderr, "close: %s: %m\n", filename); +- free (r); +- return NULL; +- } +- +- r[size] = '\0'; +- +- return r; +-} +- +-/* Takes optional arguments, consult optargs_bitmask. */ +-int +-do_mount_9p (const char *mount_tag, const char *mountpoint, const char *options) +-{ +- CLEANUP_FREE char *mp = NULL, *opts = NULL, *err = NULL; +- struct stat statbuf; +- int r; +- +- ABS_PATH (mountpoint, , return -1); +- +- mp = sysroot_path (mountpoint); +- if (!mp) { +- reply_with_perror ("malloc"); +- return -1; +- } +- +- /* Check the mountpoint exists and is a directory. */ +- if (stat (mp, &statbuf) == -1) { +- reply_with_perror ("%s", mountpoint); +- return -1; +- } +- if (!S_ISDIR (statbuf.st_mode)) { +- reply_with_perror ("%s: mount point is not a directory", mountpoint); +- return -1; +- } +- +- /* Add trans=virtio to the options. */ +- if ((optargs_bitmask & GUESTFS_MOUNT_9P_OPTIONS_BITMASK) && +- STRNEQ (options, "")) { +- if (asprintf (&opts, "trans=virtio,%s", options) == -1) { +- reply_with_perror ("asprintf"); +- return -1; +- } +- } +- else { +- opts = strdup ("trans=virtio"); +- if (opts == NULL) { +- reply_with_perror ("strdup"); +- return -1; +- } +- } +- +- r = command (NULL, &err, +- str_mount, "-o", opts, "-t", "9p", mount_tag, mp, NULL); +- if (r == -1) { +- reply_with_error ("%s on %s: %s", mount_tag, mountpoint, err); +- return -1; +- } +- +- return 0; +-} +diff --git a/daemon/Makefile.am b/daemon/Makefile.am +index 8ccf322..ec6fc6f 100644 +--- a/daemon/Makefile.am ++++ b/daemon/Makefile.am +@@ -77,7 +77,6 @@ noinst_PROGRAMS = guestfsd + endif + + guestfsd_SOURCES = \ +- 9p.c \ + acl.c \ + actions.h \ + available.c \ +diff --git a/generator/actions.ml b/generator/actions.ml +index 825acf9..2f2ab66 100644 +--- a/generator/actions.ml ++++ b/generator/actions.ml +@@ -9150,29 +9150,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"; +- style = RStringList "mounttags", [], []; +- proc_nr = Some 285; +- shortdesc = "list 9p filesystems"; +- longdesc = "\ +-List all 9p filesystems attached to the guest. A list of +-mount tags is returned." }; +- +- { defaults with +- name = "mount_9p"; +- style = RErr, [String "mounttag"; String "mountpoint"], [OString "options"]; +- proc_nr = Some 286; +- camel_name = "Mount9P"; +- shortdesc = "mount 9p filesystem"; +- longdesc = "\ +-Mount the virtio-9p filesystem with the tag C on the +-directory C. +- +-If required, C will be automatically added to the options. +-Any other options required can be passed in the optional C +-parameter." }; +- +- { defaults with + name = "list_dm_devices"; + style = RStringList "devices", [], []; + proc_nr = Some 287; +diff --git a/gobject/Makefile.inc b/gobject/Makefile.inc +index c93dace..f2152f2 100644 +--- a/gobject/Makefile.inc ++++ b/gobject/Makefile.inc +@@ -78,7 +78,6 @@ guestfs_gobject_headers= \ + include/guestfs-gobject/optargs-mkfs_btrfs.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 \ +@@ -156,7 +155,6 @@ guestfs_gobject_sources= \ + src/optargs-mkfs_btrfs.c \ + src/optargs-mkswap.c \ + src/optargs-mktemp.c \ +- src/optargs-mount_9p.c \ + src/optargs-mount_local.c \ + src/optargs-ntfsclone_out.c \ + src/optargs-ntfsfix.c \ +diff --git a/po/POTFILES b/po/POTFILES +index 1a088f5..7f3365c 100644 +--- a/po/POTFILES ++++ b/po/POTFILES +@@ -14,7 +14,6 @@ cat/ls.c + cat/visit.c + customize/crypt-c.c + customize/perl_edit-c.c +-daemon/9p.c + daemon/acl.c + daemon/augeas.c + daemon/available.c +@@ -203,7 +202,6 @@ gobject/src/optargs-mkfs.c + gobject/src/optargs-mkfs_btrfs.c + gobject/src/optargs-mkswap.c + gobject/src/optargs-mktemp.c +-gobject/src/optargs-mount_9p.c + gobject/src/optargs-mount_local.c + gobject/src/optargs-ntfsclone_out.c + gobject/src/optargs-ntfsfix.c +-- +1.8.3.1 + diff --git a/SOURCES/0097-RHEL-7-Revert-appliance-Change-example-ping-lines-to.patch b/SOURCES/0097-RHEL-7-Revert-appliance-Change-example-ping-lines-to.patch deleted file mode 100644 index 5acb7a3..0000000 --- a/SOURCES/0097-RHEL-7-Revert-appliance-Change-example-ping-lines-to.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 80523b94c4b14b30f75ae7f14785c8f50831f713 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Thu, 2 Oct 2014 16:44:04 +0100 -Subject: [PATCH] RHEL 7: Revert "appliance: Change example ping lines to ping - 8.8.8.8." - -This reverts commit 07c0926b588db5c86214917b609c2f477c817c0e. ---- - appliance/init | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/appliance/init b/appliance/init -index 3d704ba..f719a72 100755 ---- a/appliance/init -+++ b/appliance/init -@@ -114,7 +114,8 @@ if grep -sq guestfs_verbose=1 /proc/cmdline; then - date - echo -n "clocksource: " - cat /sys/devices/system/clocksource/clocksource0/current_clocksource -- #ping -n -v -c 5 8.8.8.8 -+ #ping -n -v -c 5 10.0.2.2 -+ #ping -n -v -c 5 10.0.2.4 - - echo -n "uptime: "; cat /proc/uptime - fi --- -1.8.3.1 - diff --git a/SOURCES/0098-RHEL-7-Disable-unsupported-remote-drive-protocols-RH.patch b/SOURCES/0098-RHEL-7-Disable-unsupported-remote-drive-protocols-RH.patch new file mode 100644 index 0000000..5e3dfc6 --- /dev/null +++ b/SOURCES/0098-RHEL-7-Disable-unsupported-remote-drive-protocols-RH.patch @@ -0,0 +1,586 @@ +From f55cbd578c873ad815bd3f8915a49be430b35b72 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 + (RHBZ#962113). + +This disables support for unsupported remote drive protocols: + + * ftp + * ftps + * http + * https + * tftp + * gluster + * iscsi + * sheepdog + * ssh + +Note 'nbd' is not disabled, and of course 'file' works. + +We hope to gradually add some of these back over the lifetime of RHEL 7. + +In RHEL 7.2: rbd (Ceph) support was enabled. +--- + examples/guestfs-testing.pod | 21 ------- + fish/guestfish.pod | 64 ++------------------- + fish/test-add-uri.sh | 25 --------- + generator/actions.ml | 48 +--------------- + src/drives.c | 8 +++ + src/guestfs.pod | 100 --------------------------------- + tests/disks/test-qemu-drive-libvirt.sh | 28 --------- + tests/disks/test-qemu-drive.sh | 51 ----------------- + 8 files changed, 15 insertions(+), 330 deletions(-) + +diff --git a/examples/guestfs-testing.pod b/examples/guestfs-testing.pod +index 2186ed3..ae23b59 100644 +--- a/examples/guestfs-testing.pod ++++ b/examples/guestfs-testing.pod +@@ -117,27 +117,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 +- +-If you have a disk image available over HTTP/FTP, try to open it. +- +- guestfish --ro -i --format=raw -a http://www.example.com/disk.img +- +-For SSH you will need to make sure that ssh-agent is set up so you +-don't need a password to log in to the remote machine. Then a command +-similar to this should work: +- +- guestfish --ro -i --format=raw \ +- -a ssh://remote.example.com/path/to/disk.img +- +-If you get an error, try enabling debugging (add C<-v> to the command +-line). Also make sure that L succeeds. +- + =head2 Run virt-alignment-scan on all your guests. + + Run L on guests or disk images: +diff --git a/fish/guestfish.pod b/fish/guestfish.pod +index 12bf243..e7423a6 100644 +--- a/fish/guestfish.pod ++++ b/fish/guestfish.pod +@@ -138,9 +138,9 @@ To list what is available do: + + =head2 Remote drives + +-Access a remote disk using ssh: ++Access a remote disk using NBD: + +- guestfish -a ssh://example.com/path/to/disk.img ++ guestfish -a nbd://example.com + + =head2 Remote control + +@@ -1125,12 +1125,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: + +- guestfish -a ssh://root@example.com/disk.img ++ guestfish -a nbd://example.com + + URIs I be used with the L command. The equivalent + command using the API directly is: + +- > add /disk.img protocol:ssh server:tcp:example.com username:root ++ > add /disk.img protocol:nbd server:tcp:example.com + + The possible I<-a URI> formats are described below. + +@@ -1140,40 +1140,6 @@ The possible I<-a URI> formats are described below. + + Add the local disk image (or device) called C. + +-=head2 B<-a ftp://[user@]example.com[:port]/disk.img> +- +-=head2 B<-a ftps://[user@]example.com[:port]/disk.img> +- +-=head2 B<-a http://[user@]example.com[:port]/disk.img> +- +-=head2 B<-a https://[user@]example.com[:port]/disk.img> +- +-=head2 B<-a tftp://[user@]example.com[:port]/disk.img> +- +-Add a disk located on a remote FTP, HTTP or TFTP server. +- +-The equivalent API command would be: +- +- > add /disk.img protocol:(ftp|...) server:tcp:example.com +- +-=head2 B<-a gluster://example.com[:port]/volname/image> +- +-Add a disk image located on GlusterFS storage. +- +-The server is the one running C, and may be C. +- +-The equivalent API command would be: +- +- > add volname/image protocol:gluster server:tcp:example.com +- +-=head2 B<-a iscsi://example.com[:port]/target-iqn-name[/lun]> +- +-Add a disk located on an iSCSI server. +- +-The equivalent API command would be: +- +- > add target-iqn-name/lun protocol:iscsi server:tcp:example.com +- + =head2 B<-a nbd://example.com[:port]> + + =head2 B<-a nbd://example.com[:port]/exportname> +@@ -1208,28 +1174,6 @@ The equivalent API command would be: + + > add pool/disk protocol:rbd server:tcp:example.com:port + +-=head2 B<-a sheepdog://[example.com[:port]]/volume/image> +- +-Add a disk image located on a Sheepdog volume. +- +-The server name is optional. Although libguestfs and Sheepdog +-supports multiple servers, only at most one server can be specified +-when using this URI syntax. +- +-The equivalent API command would be: +- +- > add volume protocol:sheepdog [server:tcp:example.com] +- +-=head2 B<-a ssh://[user@]example.com[:port]/disk.img> +- +-Add a disk image located on a remote server, accessed using the Secure +-Shell (ssh) SFTP protocol. SFTP is supported out of the box by all +-major SSH servers. +- +-The equivalent API command would be: +- +- > add /disk protocol:ssh server:tcp:example.com [username:user] +- + =head1 PROGRESS BARS + + Some (not all) long-running commands send progress notification +diff --git a/fish/test-add-uri.sh b/fish/test-add-uri.sh +index 2f83754..48c12b8 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 + grep -sq 'add_drive ".*/test-add-uri.img"' test-add-uri.out || fail + +-# curl +-$VG guestfish -x -a ftp://user@example.com/disk.img test-add-uri.out 2>&1 +-grep -sq 'add_drive "/disk.img" "protocol:ftp" "server:tcp:example.com" "username:user"' test-add-uri.out || fail +- +-# gluster +-$VG guestfish -x -a gluster://example.com/disk test-add-uri.out 2>&1 +-grep -sq 'add_drive "disk" "protocol:gluster" "server:tcp:example.com"' test-add-uri.out || fail +- + # NBD + $VG guestfish -x -a nbd://example.com test-add-uri.out 2>&1 + grep -sq 'add_drive "" "protocol:nbd" "server:tcp:example.com"' test-add-uri.out || fail +@@ -64,22 +56,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 + +-# sheepdog +-$VG guestfish -x -a sheepdog:///volume/image test-add-uri.out 2>&1 +-grep -sq 'add_drive "volume/image" "protocol:sheepdog"' test-add-uri.out || fail +- +-$VG guestfish -x -a sheepdog://example.com:3000/volume/image test-add-uri.out 2>&1 +-grep -sq 'add_drive "volume/image" "protocol:sheepdog" "server:tcp:example.com:3000"' test-add-uri.out || fail +- +-# ssh +-$VG guestfish -x -a ssh://example.com/disk.img test-add-uri.out 2>&1 +-grep -sq 'add_drive "/disk.img" "protocol:ssh" "server:tcp:example.com"' test-add-uri.out || fail +- +-$VG guestfish -x -a ssh://user@example.com/disk.img test-add-uri.out 2>&1 +-grep -sq 'add_drive "/disk.img" "protocol:ssh" "server:tcp:example.com" "username:user"' test-add-uri.out || fail +- +-$VG guestfish -x -a ssh://user@example.com:2000/disk.img test-add-uri.out 2>&1 +-grep -sq 'add_drive "/disk.img" "protocol:ssh" "server:tcp:example.com:2000" "username:user"' test-add-uri.out || fail +- + rm test-add-uri.out + rm test-add-uri.img +diff --git a/generator/actions.ml b/generator/actions.ml +index 2f2ab66..ea715d0 100644 +--- a/generator/actions.ml ++++ b/generator/actions.ml +@@ -1397,27 +1397,6 @@ C is interpreted as a local file or device. + This is the default if the optional protocol parameter + is omitted. + +-=item C +- +-Connect to a remote FTP, HTTP or TFTP server. +-The C parameter must also be supplied - see below. +- +-See also: L +- +-=item C +- +-Connect to the GlusterFS server. +-The C parameter must also be supplied - see below. +- +-See also: L +- +-=item C +- +-Connect to the iSCSI server. +-The C parameter must also be supplied - see below. +- +-See also: L. +- + =item C + + Connect to the Network Block Device server. +@@ -1434,22 +1413,6 @@ The C parameter may be supplied. See below. + + See also: L. + +-=item C +- +-Connect to the Sheepdog server. +-The C parameter may also be supplied - see below. +- +-See also: L. +- +-=item C +- +-Connect to the Secure Shell (ssh) server. +- +-The C parameter must be supplied. +-The C parameter may be supplied. See below. +- +-See also: L. +- + =back + + =item C +@@ -1460,13 +1423,8 @@ is a list of server(s). + Protocol Number of servers required + -------- -------------------------- + file List must be empty or param not used at all +- ftp|ftps|http|https|tftp Exactly one +- gluster Exactly one +- iscsi Exactly one + nbd Exactly one + rbd Zero or more +- sheepdog Zero or more +- ssh Exactly one + + Each list element is a string specifying a server. The string must be + in one of the following formats: +@@ -1482,10 +1440,10 @@ for the protocol is used (see C). + + =item C + +-For the C, C, C, C, C, C, C +-and C protocols, this specifies the remote username. ++For the C ++protocol, this specifies the remote username. + +-If not given, then the local username is used for C, and no authentication ++If not given, then no authentication + is attempted for ceph. But note this sometimes may give unexpected results, for + example if using the libvirt backend and if the libvirt backend is configured to + start the qemu appliance as a special user such as C. If in doubt, +diff --git a/src/drives.c b/src/drives.c +index 307f267..34cf07a 100644 +--- a/src/drives.c ++++ b/src/drives.c +@@ -199,6 +199,7 @@ create_drive_non_file (guestfs_h *g, + return drv; + } + ++#if 0 /* DISABLED IN RHEL 7 */ + static struct drive * + create_drive_curl (guestfs_h *g, + const struct drive_create_data *data) +@@ -257,6 +258,7 @@ create_drive_gluster (guestfs_h *g, + + return create_drive_non_file (g, data); + } ++#endif /* DISABLED IN RHEL 7 */ + + static int + nbd_port (void) +@@ -325,6 +327,7 @@ create_drive_rbd (guestfs_h *g, + return create_drive_non_file (g, data); + } + ++#if 0 /* DISABLED IN RHEL 7 */ + static struct drive * + create_drive_sheepdog (guestfs_h *g, + const struct drive_create_data *data) +@@ -435,6 +438,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 +@@ -882,6 +886,7 @@ guestfs__add_drive_opts (guestfs_h *g, const char *filename, + drv = create_drive_file (g, &data); + } + } ++#if 0 /* DISABLED IN RHEL 7 */ + else if (STREQ (protocol, "ftp")) { + data.protocol = drive_protocol_ftp; + drv = create_drive_curl (g, &data); +@@ -906,6 +911,7 @@ guestfs__add_drive_opts (guestfs_h *g, const char *filename, + data.protocol = drive_protocol_iscsi; + drv = create_drive_iscsi (g, &data); + } ++#endif /* DISABLED IN RHEL 7 */ + else if (STREQ (protocol, "nbd")) { + data.protocol = drive_protocol_nbd; + drv = create_drive_nbd (g, &data); +@@ -914,6 +920,7 @@ guestfs__add_drive_opts (guestfs_h *g, const char *filename, + data.protocol = drive_protocol_rbd; + drv = create_drive_rbd (g, &data); + } ++#if 0 /* DISABLED IN RHEL 7 */ + else if (STREQ (protocol, "sheepdog")) { + data.protocol = drive_protocol_sheepdog; + drv = create_drive_sheepdog (g, &data); +@@ -926,6 +933,7 @@ guestfs__add_drive_opts (guestfs_h *g, const char *filename, + data.protocol = drive_protocol_tftp; + drv = create_drive_curl (g, &data); + } ++#endif /* DISABLED IN RHEL 7 */ + else { + error (g, _("unknown protocol '%s'"), protocol); + drv = NULL; /*FALLTHROUGH*/ +diff --git a/src/guestfs.pod b/src/guestfs.pod +index c9ac1fa..3c1ad46 100644 +--- a/src/guestfs.pod ++++ b/src/guestfs.pod +@@ -695,70 +695,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. + +-=head3 FTP, HTTP AND TFTP +- +-Libguestfs can access remote disks over FTP, FTPS, HTTP, HTTPS +-or TFTP protocols. +- +-To do this, set the optional C and C parameters of +-L like this: +- +- char **servers = { "www.example.org", NULL }; +- guestfs_add_drive_opts (g, "/disk.img", +- GUESTFS_ADD_DRIVE_OPTS_FORMAT, "raw", +- GUESTFS_ADD_DRIVE_OPTS_PROTOCOL, "http", +- GUESTFS_ADD_DRIVE_OPTS_SERVER, servers, +- -1); +- +-The C can be one of C<"ftp">, C<"ftps">, C<"http">, +-C<"https"> or C<"tftp">. +- +-C (the C parameter) is a list which must have a +-single element. The single element is a string defining the web, +-FTP or TFTP server. The format of this string is documented in +-L. +- +-=head3 GLUSTER +- +-Libguestfs can access Gluster disks. +- +-To do this, set the optional C and C parameters of +-L like this: +- +- char **servers = { "gluster.example.org:24007", NULL }; +- guestfs_add_drive_opts (g, "volname/image", +- GUESTFS_ADD_DRIVE_OPTS_FORMAT, "raw", +- GUESTFS_ADD_DRIVE_OPTS_PROTOCOL, "gluster", +- GUESTFS_ADD_DRIVE_OPTS_SERVER, servers, +- -1); +- +-C (the C parameter) is a list which must have a +-single element. The single element is a string defining the Gluster +-server. The format of this string is documented in +-L. +- +-Note that gluster usually requires the client process (ie. libguestfs) +-to run as B and will give unfathomable errors if it is not +-(eg. "No data available"). +- +-=head3 ISCSI +- +-Libguestfs can access iSCSI disks remotely. +- +-To do this, set the optional C and C parameters like +-this: +- +- char **server = { "iscsi.example.org:3000", NULL }; +- guestfs_add_drive_opts (g, "target-iqn-name/lun", +- GUESTFS_ADD_DRIVE_OPTS_FORMAT, "raw", +- GUESTFS_ADD_DRIVE_OPTS_PROTOCOL, "iscsi", +- GUESTFS_ADD_DRIVE_OPTS_SERVER, server, +- -1); +- +-The C parameter is a list which must have a single element. +-The single element is a string defining the iSCSI server. The format +-of this string is documented in L. +- + =head3 NETWORK BLOCK DEVICE + + Libguestfs can access Network Block Device (NBD) disks remotely. +@@ -821,42 +757,6 @@ L + + =back + +-=head3 SHEEPDOG +- +-Libguestfs can access Sheepdog disks. +- +-To do this, set the optional C and C parameters of +-L like this: +- +- char **servers = { /* optional servers ... */ NULL }; +- guestfs_add_drive_opts (g, "volume", +- GUESTFS_ADD_DRIVE_OPTS_FORMAT, "raw", +- GUESTFS_ADD_DRIVE_OPTS_PROTOCOL, "sheepdog", +- GUESTFS_ADD_DRIVE_OPTS_SERVER, servers, +- -1); +- +-The optional list of C may be zero or more server addresses +-(C<"hostname:port">). The format of the server strings is documented +-in L. +- +-=head3 SSH +- +-Libguestfs can access disks over a Secure Shell (SSH) connection. +- +-To do this, set the C and C and (optionally) +-C parameters of L like this: +- +- char **server = { "remote.example.com", NULL }; +- guestfs_add_drive_opts (g, "/path/to/disk.img", +- GUESTFS_ADD_DRIVE_OPTS_FORMAT, "raw", +- GUESTFS_ADD_DRIVE_OPTS_PROTOCOL, "ssh", +- GUESTFS_ADD_DRIVE_OPTS_SERVER, server, +- GUESTFS_ADD_DRIVE_OPTS_USERNAME, "remoteuser", +- -1); +- +-The format of the server string is documented in +-L. +- + =head2 INSPECTION + + Libguestfs has APIs for inspecting an unknown disk image to find out +diff --git a/tests/disks/test-qemu-drive-libvirt.sh b/tests/disks/test-qemu-drive-libvirt.sh +index 9930865..1367079 100755 +--- a/tests/disks/test-qemu-drive-libvirt.sh ++++ b/tests/disks/test-qemu-drive-libvirt.sh +@@ -76,34 +76,6 @@ check_output + grep -sq -- '-drive file=rbd:abc-def/ghi-jkl:auth_supported=none,' "$DEBUG_QEMU_FILE" || fail + rm "$DEBUG_QEMU_FILE" + +-# Gluster. +- +-$guestfish -d gluster run ||: +-check_output +-grep -sq -- '-drive file=gluster://1.2.3.4:1234/volname/image,' "$DEBUG_QEMU_FILE" || fail +-rm "$DEBUG_QEMU_FILE" +- +-# iSCSI. +- +-$guestfish -d iscsi run ||: +-check_output +-grep -sq -- '-drive file=iscsi://1.2.3.4:1234/iqn.2003-01.org.linux-iscsi.fedora,' "$DEBUG_QEMU_FILE" || fail +-rm "$DEBUG_QEMU_FILE" +- +-# NBD. +- +-$guestfish -d nbd run ||: +-check_output +-grep -sq -- '-drive file=nbd:1.2.3.4:1234,' "$DEBUG_QEMU_FILE" || fail +-rm "$DEBUG_QEMU_FILE" +- +-# Sheepdog. +- +-$guestfish -d sheepdog run ||: +-check_output +-grep -sq -- '-drive file=sheepdog:volume,' "$DEBUG_QEMU_FILE" || fail +-rm "$DEBUG_QEMU_FILE" +- + # To do: + + # HTTP - curl not yet supported by libvirt +diff --git a/tests/disks/test-qemu-drive.sh b/tests/disks/test-qemu-drive.sh +index b530e7d..c0239ff 100755 +--- a/tests/disks/test-qemu-drive.sh ++++ b/tests/disks/test-qemu-drive.sh +@@ -61,36 +61,6 @@ check_output + grep -sq -- '-drive file=rbd:abc-def/ghi-jkl:auth_supported=none,' "$DEBUG_QEMU_FILE" || fail + rm "$DEBUG_QEMU_FILE" + +-# HTTP. +- +-guestfish < -Date: Thu, 2 Oct 2014 16:44:07 +0100 -Subject: [PATCH] RHEL 7: Revert "launch: libvirt: Use qemu-bridge-helper to - implement a full network (RHBZ#1148012)." - -This reverts commit 224de20b9a8d5ea56f6337f19b4ca237bb88eca0. ---- - src/guestfs.pod | 10 ---------- - src/launch-libvirt.c | 44 +++++++++++++++++++++----------------------- - 2 files changed, 21 insertions(+), 33 deletions(-) - -diff --git a/src/guestfs.pod b/src/guestfs.pod -index 5792f15..25991ec 100644 ---- a/src/guestfs.pod -+++ b/src/guestfs.pod -@@ -1398,16 +1398,6 @@ On Fedora, install C for the C file - (containing symbols). Make sure the symbols precisely match the - kernel being used. - --=head3 network_bridge -- --The libvirt backend supports: -- -- export LIBGUESTFS_BACKEND_SETTINGS=network_bridge=virbrX -- --This allows you to override the bridge that is connected to when the --network is enabled. The default is C. See also --L. -- - =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 f8f818a..706ae38 100644 ---- a/src/launch-libvirt.c -+++ b/src/launch-libvirt.c -@@ -105,7 +105,6 @@ struct backend_libvirt_data { - char *selinux_label; - char *selinux_imagelabel; - bool selinux_norelabel_disks; -- char *network_bridge; - char name[DOMAIN_NAME_LEN]; /* random name */ - bool is_kvm; /* false = qemu, true = kvm (from capabilities)*/ - unsigned long qemu_version; /* qemu version (from libvirt) */ -@@ -326,12 +325,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___get_backend_setting_bool (g, "internal_libvirt_norelabel_disks"); -- if (g->enable_network) { -- data->network_bridge = -- guestfs_get_backend_setting (g, "network_bridge"); -- if (!data->network_bridge) -- data->network_bridge = safe_strdup (g, "virbr0"); -- } - guestfs_pop_error_handler (g); - - /* Locate and/or build the appliance. */ -@@ -1243,19 +1236,6 @@ construct_libvirt_xml_devices (guestfs_h *g, - } end_element (); - } end_element (); - -- /* Connect to libvirt bridge (see: RHBZ#1148012). */ -- if (g->enable_network) { -- start_element ("interface") { -- attribute ("type", "bridge"); -- start_element ("source") { -- attribute ("bridge", params->data->network_bridge); -- } end_element (); -- start_element ("model") { -- attribute ("type", "virtio"); -- } end_element (); -- } end_element (); -- } -- - } end_element (); /* */ - - return 0; -@@ -1637,6 +1617,27 @@ construct_libvirt_xml_qemu_cmdline (guestfs_h *g, - attribute ("value", tmpdir); - } end_element (); - -+ /* Workaround because libvirt user networking cannot specify "net=" -+ * parameter. -+ */ -+ if (g->enable_network) { -+ start_element ("qemu:arg") { -+ attribute ("value", "-netdev"); -+ } end_element (); -+ -+ start_element ("qemu:arg") { -+ attribute ("value", "user,id=usernet,net=169.254.0.0/16"); -+ } end_element (); -+ -+ start_element ("qemu:arg") { -+ attribute ("value", "-device"); -+ } end_element (); -+ -+ start_element ("qemu:arg") { -+ attribute ("value", VIRTIO_NET ",netdev=usernet"); -+ } end_element (); -+ } -+ - /* The qemu command line arguments requested by the caller. */ - for (hp = g->hv_params; hp; hp = hp->next) { - start_element ("qemu:arg") { -@@ -1706,9 +1707,6 @@ shutdown_libvirt (guestfs_h *g, void *datav, int check_for_errors) - free (data->selinux_imagelabel); - data->selinux_imagelabel = NULL; - -- free (data->network_bridge); -- data->network_bridge = NULL; -- - return ret; - } - --- -1.8.3.1 - diff --git a/SOURCES/0099-RHEL-7-Remove-User-Mode-Linux-RHBZ-1144197.patch b/SOURCES/0099-RHEL-7-Remove-User-Mode-Linux-RHBZ-1144197.patch new file mode 100644 index 0000000..6252d84 --- /dev/null +++ b/SOURCES/0099-RHEL-7-Remove-User-Mode-Linux-RHBZ-1144197.patch @@ -0,0 +1,72 @@ +From 4727bbbc937f819570ee9dca1d1bfcaff14ee73a Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +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 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/src/launch-uml.c b/src/launch-uml.c +index 21525e3..8643ea8 100644 +--- a/src/launch-uml.c ++++ b/src/launch-uml.c +@@ -47,7 +47,9 @@ struct backend_uml_data { + char umid[UML_UMID_LEN+1]; /* umid=<...> unique ID. */ + }; + ++#if 0 + static void print_vmlinux_command_line (guestfs_h *g, char **argv); ++#endif + + /* Run uml_mkcow to create a COW overlay. */ + static char * +@@ -85,6 +87,7 @@ create_cow_overlay_uml (guestfs_h *g, void *datav, struct drive *drv) + return make_cow_overlay (g, drv->src.u.path); + } + ++#if 0 + /* Test for features which are not supported by the UML backend. + * Possibly some of these should just be warnings, not errors. + */ +@@ -132,10 +135,17 @@ uml_supported (guestfs_h *g) + + return true; + } ++#endif + + static int + launch_uml (guestfs_h *g, void *datav, const char *arg) + { ++ error (g, ++ "launch: In RHEL, only the 'libvirt' or 'direct' method is supported.\n" ++ "In particular, User-Mode Linux (UML) is not supported."); ++ return -1; ++ ++#if 0 + struct backend_uml_data *data = datav; + CLEANUP_FREE_STRINGSBUF DECLARE_STRINGSBUF (cmdline); + int console_sock = -1, daemon_sock = -1; +@@ -503,8 +513,10 @@ launch_uml (guestfs_h *g, void *datav, const char *arg) + } + g->state = CONFIG; + return -1; ++#endif + } + ++#if 0 + /* This is called from the forked subprocess just before vmlinux runs, + * so it can just print the message straight to stderr, where it will + * be picked up and funnelled through the usual appliance event API. +@@ -534,6 +546,7 @@ print_vmlinux_command_line (guestfs_h *g, char **argv) + + fputc ('\n', stderr); + } ++#endif + + static int + shutdown_uml (guestfs_h *g, void *datav, int check_for_errors) +-- +1.8.3.1 + diff --git a/SOURCES/0099-RHEL-7-Revert-appliance-add-dhcp-client-on-Mageia.patch b/SOURCES/0099-RHEL-7-Revert-appliance-add-dhcp-client-on-Mageia.patch deleted file mode 100644 index 9bc39d3..0000000 --- a/SOURCES/0099-RHEL-7-Revert-appliance-add-dhcp-client-on-Mageia.patch +++ /dev/null @@ -1,26 +0,0 @@ -From f7eb90e75b98d95a84cce7a11a4bb5f2993ff98b 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" - -This reverts commit 8f3a2ca5358d5601be7a9247b6d08193c4e2da46. ---- - appliance/packagelist.in | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/appliance/packagelist.in b/appliance/packagelist.in -index e546eb3..a60e532 100644 ---- a/appliance/packagelist.in -+++ b/appliance/packagelist.in -@@ -183,7 +183,7 @@ ifelse(MAGEIA,1, - chkconfig /* for /etc/init.d */ - cdrkit-genisoimage - cdrkit-isotools -- dhcp-client -+ dhclient - extlinux - gfs2-utils - grub --- -1.8.3.1 - diff --git a/SOURCES/0100-RHEL-7-Revert-appliance-add-dhcpcd-and-gptfdisk-on-A.patch b/SOURCES/0100-RHEL-7-Revert-appliance-add-dhcpcd-and-gptfdisk-on-A.patch deleted file mode 100644 index 79910ca..0000000 --- a/SOURCES/0100-RHEL-7-Revert-appliance-add-dhcpcd-and-gptfdisk-on-A.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 38e02668ae697dfeca82e0825ff84d2a647797ac 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 - Archlinux" - -This reverts commit 979e7a49147f4ef1387337db262bf7ea12f627e3. ---- - appliance/packagelist.in | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - -diff --git a/appliance/packagelist.in b/appliance/packagelist.in -index a60e532..9032d7d 100644 ---- a/appliance/packagelist.in -+++ b/appliance/packagelist.in -@@ -104,8 +104,7 @@ ifelse(ARCHLINUX,1, - btrfs-progs - cdrkit - cryptsetup -- dhcpcd -- gptfdisk -+ dhclient - grub - hivex - iproute2 --- -1.8.3.1 - diff --git a/SOURCES/0100-RHEL-7-v2v-Select-correct-qemu-binary-for-o-qemu-mod.patch b/SOURCES/0100-RHEL-7-v2v-Select-correct-qemu-binary-for-o-qemu-mod.patch new file mode 100644 index 0000000..2e43fb7 --- /dev/null +++ b/SOURCES/0100-RHEL-7-v2v-Select-correct-qemu-binary-for-o-qemu-mod.patch @@ -0,0 +1,33 @@ +From 04f1f9879843e6e3005cfe13805856621aca6bcd 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 + (RHBZ#1147313). + +RHEL 7 does not have qemu-system-x86_64 (etc), and in addition the +qemu binary is located in /usr/libexec. Encode the path to this +binary directly in the script. + +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 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/v2v/output_qemu.ml b/v2v/output_qemu.ml +index 75644c2..9c17121 100644 +--- a/v2v/output_qemu.ml ++++ b/v2v/output_qemu.ml +@@ -48,7 +48,7 @@ object + let nl = " \\\n\t" in + fpf "#!/bin/sh -\n"; + fpf "\n"; +- 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; +-- +1.8.3.1 + diff --git a/SOURCES/0101-RHEL-7-Revert-appliance-Use-dhclient-or-dhcpcd-inste.patch b/SOURCES/0101-RHEL-7-Revert-appliance-Use-dhclient-or-dhcpcd-inste.patch deleted file mode 100644 index c57a49c..0000000 --- a/SOURCES/0101-RHEL-7-Revert-appliance-Use-dhclient-or-dhcpcd-inste.patch +++ /dev/null @@ -1,91 +0,0 @@ -From 85e7fcbe46ab46bafb1124cf449ec2173e2aeb51 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 - hard-coding IP address of appliance." - -This reverts commit 67e6f32a240c7c234e6af637c1cd324b36a82cd3. ---- - appliance/init | 13 ++++++------- - appliance/packagelist.in | 6 ------ - 2 files changed, 6 insertions(+), 13 deletions(-) - -diff --git a/appliance/init b/appliance/init -index f719a72..6d62338 100755 ---- a/appliance/init -+++ b/appliance/init -@@ -79,13 +79,12 @@ hwclock -u -s - ip addr add 127.0.0.1/8 brd + dev lo scope host - ip link set dev lo up - --if grep -sq guestfs_network=1 /proc/cmdline; then -- if dhclient --version >/dev/null 2>&1; then -- dhclient -- else -- dhcpcd -- fi --fi -+ip addr add 169.254.2.10/16 brd + dev eth0 scope global -+ip link set dev eth0 up -+ -+ip route add default via 169.254.2.2 -+ -+echo nameserver 169.254.2.3 > /etc/resolv.conf - - # Scan for MDs. - mdadm -As --auto=yes --run -diff --git a/appliance/packagelist.in b/appliance/packagelist.in -index 9032d7d..8fb6eca 100644 ---- a/appliance/packagelist.in -+++ b/appliance/packagelist.in -@@ -27,7 +27,6 @@ ifelse(REDHAT,1, - btrfs-progs - cryptsetup - cryptsetup-luks dnl old name used before Fedora 17 -- dhclient - dnl e4fsprogs only exists on RHEL 5, will be ignored everywhere else. - e4fsprogs - genisoimage -@@ -74,7 +73,6 @@ dnl iproute has been renamed to iproute2 - iputils-ping - iputils-arping - iputils-tracepath -- isc-dhcp-client - libaugeas0 - libc-bin - libcap2 -@@ -104,7 +102,6 @@ ifelse(ARCHLINUX,1, - btrfs-progs - cdrkit - cryptsetup -- dhclient - grub - hivex - iproute2 -@@ -133,7 +130,6 @@ ifelse(SUSE,1, - augeas-lenses - btrfsprogs - cryptsetup -- dhcpcd - genisoimage - glibc-locale - gptfdisk -@@ -154,7 +150,6 @@ ifelse(FRUGALWARE,1, - btrfs-progs - cryptsetup-luks - cdrkit -- dhclient - grub2 - hfsplus - iproute2 -@@ -182,7 +177,6 @@ ifelse(MAGEIA,1, - chkconfig /* for /etc/init.d */ - cdrkit-genisoimage - cdrkit-isotools -- dhclient - extlinux - gfs2-utils - grub --- -1.8.3.1 - diff --git a/SOURCES/0101-RHEL-7-v2v-Disable-the-qemu-boot-option-RHBZ-1147313.patch b/SOURCES/0101-RHEL-7-v2v-Disable-the-qemu-boot-option-RHBZ-1147313.patch new file mode 100644 index 0000000..9e7f474 --- /dev/null +++ b/SOURCES/0101-RHEL-7-v2v-Disable-the-qemu-boot-option-RHBZ-1147313.patch @@ -0,0 +1,78 @@ +From c8eca5fd761f8eb7822ccb765d3e9138d9bcb738 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). + +This cannot work because there is no Gtk or SDL output mode +in RHEL 7's qemu-kvm. + +In addition you will have to edit the -display option in the +qemu script. +--- + v2v/cmdline.ml | 4 +++- + v2v/virt-v2v.pod | 13 ------------- + 2 files changed, 3 insertions(+), 14 deletions(-) + +diff --git a/v2v/cmdline.ml b/v2v/cmdline.ml +index 01f3335..14c3fb9 100644 +--- a/v2v/cmdline.ml ++++ b/v2v/cmdline.ml +@@ -168,7 +168,7 @@ let parse_cmdline () = + "-os", Arg.Set_string output_storage, "storage " ^ s_"Set output storage location"; + "--password-file", Arg.Set_string 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)"; ++ "--qemu-boot", Arg.Set qemu_boot, " " ^ s_"This option cannot be used in RHEL"; + "-q", Arg.Set quiet, " " ^ s_"Quiet output"; + "--quiet", Arg.Set quiet, ditto; + "--root", Arg.String set_root_choice,"ask|... " ^ s_"How to choose root filesystem"; +@@ -364,6 +364,8 @@ read the man page virt-v2v(1). + if not (is_directory output_storage) then + error (f_"-os %s: output directory does not exist or is not a directory") + output_storage; ++ if qemu_boot then ++ error (f_"-o qemu: the --qemu-boot option cannot be used in RHEL"); + Output_qemu.output_qemu verbose output_storage qemu_boot + + | `RHEV -> +diff --git a/v2v/virt-v2v.pod b/v2v/virt-v2v.pod +index 5f4d42e..9edb2ca 100644 +--- a/v2v/virt-v2v.pod ++++ b/v2v/virt-v2v.pod +@@ -139,11 +139,6 @@ Since C 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. + +-To convert a local disk image and immediately boot it in local +-qemu, do: +- +- virt-v2v -i disk disk.img -o qemu -os /var/tmp --qemu-boot +- + =head1 OPTIONS + + =over 4 +@@ -350,9 +345,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> + + Set the output method to I. +@@ -436,11 +428,6 @@ Print information about the source guest and stop. This option is + useful when you are setting up network and bridge maps. + See L. + +-=item B<--qemu-boot> +- +-When using I<-o qemu> only, this boots the guest immediately after +-virt-v2v finishes. +- + =item B<-q> + + =item B<--quiet> +-- +1.8.3.1 + diff --git a/SOURCES/0102-RHEL-7-Revert-tests-rsync-Skip-this-test-when-the-ba.patch b/SOURCES/0102-RHEL-7-Revert-tests-rsync-Skip-this-test-when-the-ba.patch new file mode 100644 index 0000000..489126a --- /dev/null +++ b/SOURCES/0102-RHEL-7-Revert-tests-rsync-Skip-this-test-when-the-ba.patch @@ -0,0 +1,74 @@ +From dd3263f82d6ee73808c31896136b795643cd24c4 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 + is libvirt." + +This reverts commit 765dc6237ce7b93dd2f33d99be53eae92e048a7a. +--- + tests/rsync/test-rsync.sh | 35 +++++++---------------------------- + 1 file changed, 7 insertions(+), 28 deletions(-) + +diff --git a/tests/rsync/test-rsync.sh b/tests/rsync/test-rsync.sh +index 53fcab8..793d59d 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 + +-# Get host IP address. XXX Bit of a hack. +-backend="$(guestfish get-backend)" +-case "$backend" in +- direct) +- ip=169.254.2.2 +- listen_address=localhost +- ;; +- libvirt|libvirt:*) +- # This would work, except that the host firewall is effective +- # on virbr0, and that is likely to block the non-standard port +- # number that we listen on. +-# ip="$(ip -4 -o address show virbr0 | +-# awk '{print $4}' | +-# awk -F/ '{print $1}')" +-# listen_address="$ip" +- echo "$0: skipping test because host firewall will probably prevent this test from working" +- exit 77 +- ;; +- uml) +- echo "$0: skipping test because networking is not available in the UML backend" +- exit 77 +- ;; +- *) +- echo "$0: don't know how to get IP address of backend $backend" +- exit 77 +- ;; +-esac ++if [ "$(guestfish get-backend)" = "uml" ]; then ++ echo "$0: skipping test because networking is not available in the UML backend" ++ 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, 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 709b4b9..67de2b1 100644 ---- a/v2v/convert_linux.ml -+++ b/v2v/convert_linux.ml -@@ -537,6 +537,7 @@ let rec convert ~verbose ~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 = -@@ -627,6 +628,7 @@ let rec convert ~verbose ~keep_serial_console (g : G.guestfs) inspect source = - warning ~prog (f_"VMware tools was detected, but uninstallation failed. The error message was: %s (ignored)") - msg - ) -+*) - - and unconfigure_citrix () = - let pkgs = -@@ -1417,7 +1419,7 @@ let rec convert ~verbose ~keep_serial_console (g : G.guestfs) inspect source = - - unconfigure_xen (); - unconfigure_vbox (); -- unconfigure_vmware (); -+ (*unconfigure_vmware ();*) - unconfigure_citrix (); - unconfigure_efi (); - unconfigure_kudzu (); --- -1.8.3.1 - diff --git a/SOURCES/0103-RHEL-7-Disable-alternate-Augeas-lenses.patch b/SOURCES/0103-RHEL-7-Disable-alternate-Augeas-lenses.patch deleted file mode 100644 index d056aec..0000000 --- a/SOURCES/0103-RHEL-7-Disable-alternate-Augeas-lenses.patch +++ /dev/null @@ -1,84 +0,0 @@ -From cd10f6e4067591c0f6926746eaaa2330e034e66d 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 7b30bbe..c7eca20 100644 ---- a/appliance/Makefile.am -+++ b/appliance/Makefile.am -@@ -82,8 +82,6 @@ supermin.d/daemon.tar.gz: ../daemon/guestfsd guestfsd.suppressions guestfs_lvm_c - 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)/guestfsd.suppressions tmp-d/etc/guestfsd.suppressions -- 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 ce49726..7753e67 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 d82fde0..9e0f570 100644 ---- a/daemon/lvm-filter.c -+++ b/daemon/lvm-filter.c -@@ -121,7 +121,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; -@@ -132,7 +132,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/0103-RHEL-7-Revert-appliance-Change-example-ping-lines-to.patch b/SOURCES/0103-RHEL-7-Revert-appliance-Change-example-ping-lines-to.patch new file mode 100644 index 0000000..b398375 --- /dev/null +++ b/SOURCES/0103-RHEL-7-Revert-appliance-Change-example-ping-lines-to.patch @@ -0,0 +1,28 @@ +From 2bbaa881d67ddaafb7c111ef8ad1f93c9879c52d Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Thu, 2 Oct 2014 16:44:04 +0100 +Subject: [PATCH] RHEL 7: Revert "appliance: Change example ping lines to ping + 8.8.8.8." + +This reverts commit 07c0926b588db5c86214917b609c2f477c817c0e. +--- + appliance/init | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/appliance/init b/appliance/init +index 3d704ba..f719a72 100755 +--- a/appliance/init ++++ b/appliance/init +@@ -114,7 +114,8 @@ if grep -sq guestfs_verbose=1 /proc/cmdline; then + date + echo -n "clocksource: " + cat /sys/devices/system/clocksource/clocksource0/current_clocksource +- #ping -n -v -c 5 8.8.8.8 ++ #ping -n -v -c 5 10.0.2.2 ++ #ping -n -v -c 5 10.0.2.4 + + echo -n "uptime: "; cat /proc/uptime + fi +-- +1.8.3.1 + diff --git a/SOURCES/0104-RHEL-7-Revert-launch-libvirt-Use-qemu-bridge-helper-.patch b/SOURCES/0104-RHEL-7-Revert-launch-libvirt-Use-qemu-bridge-helper-.patch new file mode 100644 index 0000000..74c059d --- /dev/null +++ b/SOURCES/0104-RHEL-7-Revert-launch-libvirt-Use-qemu-bridge-helper-.patch @@ -0,0 +1,119 @@ +From 2392578b6774594eb33188606fd64c415055be63 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 + implement a full network (RHBZ#1148012)." + +This reverts commit 224de20b9a8d5ea56f6337f19b4ca237bb88eca0. +--- + src/guestfs.pod | 10 ---------- + src/launch-libvirt.c | 44 +++++++++++++++++++++----------------------- + 2 files changed, 21 insertions(+), 33 deletions(-) + +diff --git a/src/guestfs.pod b/src/guestfs.pod +index 3c1ad46..81347f3 100644 +--- a/src/guestfs.pod ++++ b/src/guestfs.pod +@@ -1419,16 +1419,6 @@ On Fedora, install C for the C file + (containing symbols). Make sure the symbols precisely match the + kernel being used. + +-=head3 network_bridge +- +-The libvirt backend supports: +- +- export LIBGUESTFS_BACKEND_SETTINGS=network_bridge=virbrX +- +-This allows you to override the bridge that is connected to when the +-network is enabled. The default is C. See also +-L. +- + =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 79bc6fd..026fd5a 100644 +--- a/src/launch-libvirt.c ++++ b/src/launch-libvirt.c +@@ -105,7 +105,6 @@ struct backend_libvirt_data { + char *selinux_label; + char *selinux_imagelabel; + bool selinux_norelabel_disks; +- char *network_bridge; + char name[DOMAIN_NAME_LEN]; /* random name */ + bool is_kvm; /* false = qemu, true = kvm (from capabilities)*/ + unsigned long qemu_version; /* qemu version (from libvirt) */ +@@ -332,12 +331,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___get_backend_setting_bool (g, "internal_libvirt_norelabel_disks"); +- if (g->enable_network) { +- data->network_bridge = +- guestfs_get_backend_setting (g, "network_bridge"); +- if (!data->network_bridge) +- data->network_bridge = safe_strdup (g, "virbr0"); +- } + guestfs_pop_error_handler (g); + + /* Locate and/or build the appliance. */ +@@ -1267,19 +1260,6 @@ construct_libvirt_xml_devices (guestfs_h *g, + } end_element (); + } end_element (); + +- /* Connect to libvirt bridge (see: RHBZ#1148012). */ +- if (g->enable_network) { +- start_element ("interface") { +- attribute ("type", "bridge"); +- start_element ("source") { +- attribute ("bridge", params->data->network_bridge); +- } end_element (); +- start_element ("model") { +- attribute ("type", "virtio"); +- } end_element (); +- } end_element (); +- } +- + } end_element (); /* */ + + return 0; +@@ -1661,6 +1641,27 @@ construct_libvirt_xml_qemu_cmdline (guestfs_h *g, + attribute ("value", tmpdir); + } end_element (); + ++ /* Workaround because libvirt user networking cannot specify "net=" ++ * parameter. ++ */ ++ if (g->enable_network) { ++ start_element ("qemu:arg") { ++ attribute ("value", "-netdev"); ++ } end_element (); ++ ++ start_element ("qemu:arg") { ++ attribute ("value", "user,id=usernet,net=169.254.0.0/16"); ++ } end_element (); ++ ++ start_element ("qemu:arg") { ++ attribute ("value", "-device"); ++ } end_element (); ++ ++ start_element ("qemu:arg") { ++ attribute ("value", VIRTIO_NET ",netdev=usernet"); ++ } end_element (); ++ } ++ + /* The qemu command line arguments requested by the caller. */ + for (hp = g->hv_params; hp; hp = hp->next) { + start_element ("qemu:arg") { +@@ -1745,9 +1746,6 @@ shutdown_libvirt (guestfs_h *g, void *datav, int check_for_errors) + free (data->selinux_imagelabel); + data->selinux_imagelabel = NULL; + +- free (data->network_bridge); +- data->network_bridge = NULL; +- + free (data->uefi_code); + data->uefi_code = NULL; + free (data->uefi_vars); +-- +1.8.3.1 + diff --git a/SOURCES/0105-RHEL-7-Revert-appliance-add-dhcp-client-on-Mageia.patch b/SOURCES/0105-RHEL-7-Revert-appliance-add-dhcp-client-on-Mageia.patch new file mode 100644 index 0000000..a19ac90 --- /dev/null +++ b/SOURCES/0105-RHEL-7-Revert-appliance-add-dhcp-client-on-Mageia.patch @@ -0,0 +1,26 @@ +From 774e8f155f7f9dc369e3fd0e1838a1f309cda235 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" + +This reverts commit 8f3a2ca5358d5601be7a9247b6d08193c4e2da46. +--- + appliance/packagelist.in | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/appliance/packagelist.in b/appliance/packagelist.in +index e546eb3..a60e532 100644 +--- a/appliance/packagelist.in ++++ b/appliance/packagelist.in +@@ -183,7 +183,7 @@ ifelse(MAGEIA,1, + chkconfig /* for /etc/init.d */ + cdrkit-genisoimage + cdrkit-isotools +- dhcp-client ++ dhclient + extlinux + gfs2-utils + grub +-- +1.8.3.1 + diff --git a/SOURCES/0106-RHEL-7-Revert-appliance-add-dhcpcd-and-gptfdisk-on-A.patch b/SOURCES/0106-RHEL-7-Revert-appliance-add-dhcpcd-and-gptfdisk-on-A.patch new file mode 100644 index 0000000..e2317bf --- /dev/null +++ b/SOURCES/0106-RHEL-7-Revert-appliance-add-dhcpcd-and-gptfdisk-on-A.patch @@ -0,0 +1,28 @@ +From 3abf69d23cd95082daedb7cb1a1c98049f310368 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 + Archlinux" + +This reverts commit 979e7a49147f4ef1387337db262bf7ea12f627e3. +--- + appliance/packagelist.in | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/appliance/packagelist.in b/appliance/packagelist.in +index a60e532..9032d7d 100644 +--- a/appliance/packagelist.in ++++ b/appliance/packagelist.in +@@ -104,8 +104,7 @@ ifelse(ARCHLINUX,1, + btrfs-progs + cdrkit + cryptsetup +- dhcpcd +- gptfdisk ++ dhclient + grub + hivex + iproute2 +-- +1.8.3.1 + diff --git a/SOURCES/0107-RHEL-7-Revert-appliance-Use-dhclient-or-dhcpcd-inste.patch b/SOURCES/0107-RHEL-7-Revert-appliance-Use-dhclient-or-dhcpcd-inste.patch new file mode 100644 index 0000000..0ad308e --- /dev/null +++ b/SOURCES/0107-RHEL-7-Revert-appliance-Use-dhclient-or-dhcpcd-inste.patch @@ -0,0 +1,91 @@ +From 8b61f836790e57690852b41bdc0856df42a58867 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 + hard-coding IP address of appliance." + +This reverts commit 67e6f32a240c7c234e6af637c1cd324b36a82cd3. +--- + appliance/init | 13 ++++++------- + appliance/packagelist.in | 6 ------ + 2 files changed, 6 insertions(+), 13 deletions(-) + +diff --git a/appliance/init b/appliance/init +index f719a72..6d62338 100755 +--- a/appliance/init ++++ b/appliance/init +@@ -79,13 +79,12 @@ hwclock -u -s + ip addr add 127.0.0.1/8 brd + dev lo scope host + ip link set dev lo up + +-if grep -sq guestfs_network=1 /proc/cmdline; then +- if dhclient --version >/dev/null 2>&1; then +- dhclient +- else +- dhcpcd +- fi +-fi ++ip addr add 169.254.2.10/16 brd + dev eth0 scope global ++ip link set dev eth0 up ++ ++ip route add default via 169.254.2.2 ++ ++echo nameserver 169.254.2.3 > /etc/resolv.conf + + # Scan for MDs. + mdadm -As --auto=yes --run +diff --git a/appliance/packagelist.in b/appliance/packagelist.in +index 9032d7d..8fb6eca 100644 +--- a/appliance/packagelist.in ++++ b/appliance/packagelist.in +@@ -27,7 +27,6 @@ ifelse(REDHAT,1, + btrfs-progs + cryptsetup + cryptsetup-luks dnl old name used before Fedora 17 +- dhclient + dnl e4fsprogs only exists on RHEL 5, will be ignored everywhere else. + e4fsprogs + genisoimage +@@ -74,7 +73,6 @@ dnl iproute has been renamed to iproute2 + iputils-ping + iputils-arping + iputils-tracepath +- isc-dhcp-client + libaugeas0 + libc-bin + libcap2 +@@ -104,7 +102,6 @@ ifelse(ARCHLINUX,1, + btrfs-progs + cdrkit + cryptsetup +- dhclient + grub + hivex + iproute2 +@@ -133,7 +130,6 @@ ifelse(SUSE,1, + augeas-lenses + btrfsprogs + cryptsetup +- dhcpcd + genisoimage + glibc-locale + gptfdisk +@@ -154,7 +150,6 @@ ifelse(FRUGALWARE,1, + btrfs-progs + cryptsetup-luks + cdrkit +- dhclient + grub2 + hfsplus + iproute2 +@@ -182,7 +177,6 @@ ifelse(MAGEIA,1, + chkconfig /* for /etc/init.d */ + cdrkit-genisoimage + cdrkit-isotools +- dhclient + extlinux + gfs2-utils + grub +-- +1.8.3.1 + diff --git a/SOURCES/0108-RHEL-7-v2v-Disable-unconfiguration-of-VMware-drivers.patch b/SOURCES/0108-RHEL-7-v2v-Disable-unconfiguration-of-VMware-drivers.patch new file mode 100644 index 0000000..c642f83 --- /dev/null +++ b/SOURCES/0108-RHEL-7-v2v-Disable-unconfiguration-of-VMware-drivers.patch @@ -0,0 +1,44 @@ +From 67d28ac629e96912bb7152bbb172217d0f1c70c0 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 709b4b9..67de2b1 100644 +--- a/v2v/convert_linux.ml ++++ b/v2v/convert_linux.ml +@@ -537,6 +537,7 @@ let rec convert ~verbose ~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 = +@@ -627,6 +628,7 @@ let rec convert ~verbose ~keep_serial_console (g : G.guestfs) inspect source = + warning ~prog (f_"VMware tools was detected, but uninstallation failed. The error message was: %s (ignored)") + msg + ) ++*) + + and unconfigure_citrix () = + let pkgs = +@@ -1417,7 +1419,7 @@ let rec convert ~verbose ~keep_serial_console (g : G.guestfs) inspect source = + + unconfigure_xen (); + unconfigure_vbox (); +- unconfigure_vmware (); ++ (*unconfigure_vmware ();*) + unconfigure_citrix (); + unconfigure_efi (); + unconfigure_kudzu (); +-- +1.8.3.1 + diff --git a/SOURCES/0109-RHEL-7-Disable-alternate-Augeas-lenses.patch b/SOURCES/0109-RHEL-7-Disable-alternate-Augeas-lenses.patch new file mode 100644 index 0000000..c11e480 --- /dev/null +++ b/SOURCES/0109-RHEL-7-Disable-alternate-Augeas-lenses.patch @@ -0,0 +1,84 @@ +From 1156f17878c25ba3221105b339ab9ff298bd123d 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 7b30bbe..c7eca20 100644 +--- a/appliance/Makefile.am ++++ b/appliance/Makefile.am +@@ -82,8 +82,6 @@ supermin.d/daemon.tar.gz: ../daemon/guestfsd guestfsd.suppressions guestfs_lvm_c + 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)/guestfsd.suppressions tmp-d/etc/guestfsd.suppressions +- 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 ce49726..7753e67 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 d82fde0..9e0f570 100644 +--- a/daemon/lvm-filter.c ++++ b/daemon/lvm-filter.c +@@ -121,7 +121,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; +@@ -132,7 +132,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/0110-v2v-Add-a-note-about-escaping-username-like-DOMAIN-u.patch b/SOURCES/0110-v2v-Add-a-note-about-escaping-username-like-DOMAIN-u.patch new file mode 100644 index 0000000..99c562a --- /dev/null +++ b/SOURCES/0110-v2v-Add-a-note-about-escaping-username-like-DOMAIN-u.patch @@ -0,0 +1,32 @@ +From 7222c6d14b7d2c9eb5edb43da8ba83dbb002af71 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Tue, 23 Dec 2014 15:29:26 +0000 +Subject: [PATCH] v2v: Add a note about escaping username like DOMAIN\user. + +Thanks: Ben Hooper. +(cherry picked from commit 29df51d9bc24eaae9e42c3794b7dac9c78d8b3bd) +--- + v2v/virt-v2v.pod | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/v2v/virt-v2v.pod b/v2v/virt-v2v.pod +index 9edb2ca..933955a 100644 +--- a/v2v/virt-v2v.pod ++++ b/v2v/virt-v2v.pod +@@ -744,7 +744,12 @@ where: + + =item C + +-is the (optional, but recommended) user to connect as ++is the (optional, but recommended) user to connect as. ++ ++If the username contains a backslash (eg. C) then you ++will need to URI-escape that character using C<%5c>: C ++(5c is the hexadecimal ASCII code for backslash.) Other punctuation ++may also have to be escaped. + + =item C + +-- +1.8.3.1 + diff --git a/SOURCES/0111-v2v-adding-vdsm-ovf-output-option.patch b/SOURCES/0111-v2v-adding-vdsm-ovf-output-option.patch new file mode 100644 index 0000000..f6bc5ee --- /dev/null +++ b/SOURCES/0111-v2v-adding-vdsm-ovf-output-option.patch @@ -0,0 +1,172 @@ +From 93c2eb23dacc9ffa226c92777c498792d7f5a6cf Mon Sep 17 00:00:00 2001 +From: Shahar Havivi +Date: Thu, 25 Dec 2014 11:57:12 +0200 +Subject: [PATCH] v2v: adding --vdsm-ovf-output option + +This option is needed by vdsm for writing the ovf to a specific directory. +The default is current directory. + +Bug-Url: https://bugzilla.redhat.com/show_bug.cgi?id=1176598 +Signed-off-by: Shahar Havivi +(cherry picked from commit 14d11916faf68afb672d1626348931f2b90afd08) +--- + v2v/cmdline.ml | 5 +++++ + v2v/output_vdsm.ml | 16 +++++++--------- + v2v/output_vdsm.mli | 1 + + v2v/test-v2v-o-vdsm-options.sh | 1 + + v2v/virt-v2v.pod | 8 +++++++- + 5 files changed, 21 insertions(+), 10 deletions(-) + +diff --git a/v2v/cmdline.ml b/v2v/cmdline.ml +index 14c3fb9..97167b4 100644 +--- a/v2v/cmdline.ml ++++ b/v2v/cmdline.ml +@@ -47,6 +47,7 @@ let parse_cmdline () = + let qemu_boot = ref false in + let quiet = ref false in + let vdsm_vm_uuid = ref "" in ++ let vdsm_ovf_output = ref "." in + let verbose = ref false in + let trace = ref false in + let vmtype = ref "" in +@@ -178,6 +179,8 @@ let parse_cmdline () = + Arg.String add_vdsm_vol_uuid, "uuid " ^ s_"Output vol UUID(s)"; + "--vdsm-vm-uuid", + Arg.Set_string vdsm_vm_uuid, "uuid " ^ s_"Output VM UUID"; ++ "--vdsm-ovf-output", ++ Arg.Set_string vdsm_ovf_output, " " ^ s_"Output OVF file"; + "-v", Arg.Set verbose, " " ^ s_"Enable debugging messages"; + "--verbose", Arg.Set verbose, ditto; + "-V", Arg.Unit display_version, " " ^ s_"Display version and exit"; +@@ -237,6 +240,7 @@ read the man page virt-v2v(1). + 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 ++ let vdsm_ovf_output = !vdsm_ovf_output in + let verbose = !verbose in + let trace = !trace in + let vmtype = +@@ -386,6 +390,7 @@ read the man page virt-v2v(1). + Output_vdsm.image_uuids = vdsm_image_uuids; + vol_uuids = vdsm_vol_uuids; + vm_uuid = vdsm_vm_uuid; ++ ovf_output = vdsm_ovf_output; + } in + Output_vdsm.output_vdsm verbose output_storage vdsm_params + vmtype output_alloc in +diff --git a/v2v/output_vdsm.ml b/v2v/output_vdsm.ml +index 293f57f..492f586 100644 +--- a/v2v/output_vdsm.ml ++++ b/v2v/output_vdsm.ml +@@ -30,6 +30,7 @@ type vdsm_params = { + image_uuids : string list; + vol_uuids : string list; + vm_uuid : string; ++ ovf_output : string; + } + + class output_vdsm verbose os vdsm_params vmtype output_alloc = +@@ -37,12 +38,13 @@ object + inherit output verbose + + method as_options = +- sprintf "-o vdsm -os %s%s%s --vdsm-vm-uuid %s%s" os ++ sprintf "-o vdsm -os %s%s%s --vdsm-vm-uuid %s --vdsm-ovf-output %s%s" os + (String.concat "" + (List.map (sprintf " --vdsm-image-uuid %s") vdsm_params.image_uuids)) + (String.concat "" + (List.map (sprintf " --vdsm-vol-uuid %s") vdsm_params.vol_uuids)) + vdsm_params.vm_uuid ++ vdsm_params.ovf_output + (match vmtype with + | None -> "" + | Some `Server -> " --vmtype server" +@@ -57,9 +59,6 @@ object + val mutable dd_mp = "" + val mutable dd_uuid = "" + +- (* Target metadata directory. *) +- val mutable ovf_dir = "" +- + (* This is called early on in the conversion and lets us choose the + * name of the target files that eventually get written by the main + * code. +@@ -98,13 +97,12 @@ object + ) vdsm_params.image_uuids; + + (* Note that VDSM has to create this directory too. *) +- ovf_dir <- dd_mp // dd_uuid // "master" // "vms" // vdsm_params.vm_uuid; +- if not (is_directory ovf_dir) then ++ if not (is_directory vdsm_params.ovf_output) then + error (f_"OVF (metadata) directory (%s) does not exist or is not a directory") +- ovf_dir; ++ vdsm_params.ovf_output; + + if verbose then +- eprintf "VDSM: OVF (metadata) directory: %s\n%!" ovf_dir; ++ eprintf "VDSM: OVF (metadata) directory: %s\n%!" vdsm_params.ovf_output; + + (* The final directory structure should look like this: + * ///images/ +@@ -164,7 +162,7 @@ object + vdsm_params.vm_uuid in + + (* Write it to the metadata file. *) +- let file = ovf_dir // vdsm_params.vm_uuid ^ ".ovf" in ++ let file = vdsm_params.ovf_output // vdsm_params.vm_uuid ^ ".ovf" in + let chan = open_out file in + doc_to_chan chan ovf; + close_out chan +diff --git a/v2v/output_vdsm.mli b/v2v/output_vdsm.mli +index 3ee5425..26ac15d 100644 +--- a/v2v/output_vdsm.mli ++++ b/v2v/output_vdsm.mli +@@ -22,6 +22,7 @@ type vdsm_params = { + image_uuids : string list; (* --vdsm-image-uuid (multiple) *) + vol_uuids : string list; (* --vdsm-vol-uuid (multiple) *) + vm_uuid : string; (* --vdsm-vm-uuid *) ++ ovf_output : string; (* --vdsm-ovf-output *) + } + (** 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 8747d8a..e2098fa 100755 +--- a/v2v/test-v2v-o-vdsm-options.sh ++++ b/v2v/test-v2v-o-vdsm-options.sh +@@ -69,6 +69,7 @@ $VG virt-v2v --debug-gc \ + --vdsm-image-uuid IMAGE \ + --vdsm-vol-uuid VOL \ + --vdsm-vm-uuid VM \ ++ --vdsm-ovf-output $d/12345678-1234-1234-1234-123456789abc/master/vms/VM \ + + # Test the OVF metadata was created. + test -f $d/12345678-1234-1234-1234-123456789abc/master/vms/VM/VM.ovf +diff --git a/v2v/virt-v2v.pod b/v2v/virt-v2v.pod +index 933955a..7ed2dda 100644 +--- a/v2v/virt-v2v.pod ++++ b/v2v/virt-v2v.pod +@@ -483,6 +483,8 @@ OS which is not in the first VirtIO disk. + + =item B<--vdsm-vm-uuid> UUID + ++=item B<--vdsm-ovf-output> ++ + Normally the RHEV output mode chooses random UUIDs for the target + guest. However VDSM needs to control the UUIDs and passes these + parameters when virt-v2v runs under VDSM control. The parameters +@@ -502,7 +504,11 @@ is passed once for each guest disk) + + =item * + +-the VM and OVF file (I<--vdsm-vm-uuid>). ++the OVF file name (I<--vdsm-vm-uuid>). ++ ++=item * ++ ++the OVF output directory (default current directory) (I<--vdsm-ovf-output>). + + =back + +-- +1.8.3.1 + diff --git a/SOURCES/0112-v2v-o-vdsm-should-assume-data-domain-at-os-path.patch b/SOURCES/0112-v2v-o-vdsm-should-assume-data-domain-at-os-path.patch new file mode 100644 index 0000000..aac1f2b --- /dev/null +++ b/SOURCES/0112-v2v-o-vdsm-should-assume-data-domain-at-os-path.patch @@ -0,0 +1,89 @@ +From 766c53d1d28006cbefa2837f6f3bd9fd2bee64b8 Mon Sep 17 00:00:00 2001 +From: Shahar Havivi +Date: Mon, 26 Jan 2015 12:13:49 +0200 +Subject: [PATCH] v2v: -o vdsm should assume data domain at -os path + +Unlike -o rhev which have only one data domin, -o vdsm can and usually +does have multiple data domain. +The path to vdsm is pre mounted so no need to assume nfs path with -os +Example: +-o vdsm -os /rhev/data-center// + +Bug-Url: https://bugzilla.redhat.com/1176591 +Signed-off-by: Shahar Havivi +(cherry picked from commit 889e55516869d1eadcdeae15e38dd8d3bbca8d20) +--- + v2v/output_vdsm.ml | 18 ++++++++++++++---- + v2v/test-v2v-o-vdsm-options.sh | 2 +- + v2v/virt-v2v.pod | 6 ++++-- + 3 files changed, 19 insertions(+), 7 deletions(-) + +diff --git a/v2v/output_vdsm.ml b/v2v/output_vdsm.ml +index 492f586..c7a243e 100644 +--- a/v2v/output_vdsm.ml ++++ b/v2v/output_vdsm.ml +@@ -63,9 +63,8 @@ object + * name of the target files that eventually get written by the main + * code. + * +- * 'os' is the output storage (-os nfs:/export). 'source' contains a +- * few useful fields such as the guest name. 'targets' describes the +- * destination files. We modify and return this list. ++ * 'os' is the output storage domain (-os /rhev/data//) ++ * this is already mounted path. + * + * Note it's good to fail here (early) if there are any problems, since + * the next time we are called (in {!create_metadata}) we have already +@@ -79,7 +78,18 @@ object + (List.length targets); + + let mp, uuid = +- Output_rhev.mount_and_check_storage_domain verbose (s_"Data Domain") os in ++ let fields = string_nsplit "/" os in (* ... "data-center" "UUID" *) ++ let fields = List.rev fields in (* "UUID" "data-center" ... *) ++ match fields with ++ | "" :: uuid :: rest (* handles trailing "/" case *) ++ | uuid :: rest ++ when String.length uuid = 36 -> ++ let mp = String.concat "/" (List.rev rest) in ++ mp, uuid ++ | _ -> ++ error (f_"vdsm: invalid -os parameter does not contain a valid UUID: %s") ++ os in ++ + dd_mp <- mp; + dd_uuid <- uuid; + if verbose then +diff --git a/v2v/test-v2v-o-vdsm-options.sh b/v2v/test-v2v-o-vdsm-options.sh +index e2098fa..c170467 100755 +--- a/v2v/test-v2v-o-vdsm-options.sh ++++ b/v2v/test-v2v-o-vdsm-options.sh +@@ -64,7 +64,7 @@ mkdir $d/12345678-1234-1234-1234-123456789abc/master/vms/VM + + $VG virt-v2v --debug-gc \ + -i libvirt -ic "$libvirt_uri" windows \ +- -o vdsm -os $d \ ++ -o vdsm -os $d/12345678-1234-1234-1234-123456789abc \ + --vmtype desktop \ + --vdsm-image-uuid IMAGE \ + --vdsm-vol-uuid VOL \ +diff --git a/v2v/virt-v2v.pod b/v2v/virt-v2v.pod +index 7ed2dda..2e49fbf 100644 +--- a/v2v/virt-v2v.pod ++++ b/v2v/virt-v2v.pod +@@ -360,8 +360,10 @@ See L below. + + Set the output method to I. + +-This mode is similar to I<-o rhev> but is only used by RHEV VDSM +-when it runs virt-v2v under VDSM control. ++This mode is similar to I<-o rhev>, but the full path to the ++data domain must be given: ++Cdata-center-uuidE/Edata-domain-uuidE>. ++This mode is only used when virt-v2v runs under VDSM control. + + =item B<-oa sparse> + +-- +1.8.3.1 + diff --git a/SOURCES/0113-v2v-i-ova-Make-error-message-unsupported-file-format.patch b/SOURCES/0113-v2v-i-ova-Make-error-message-unsupported-file-format.patch new file mode 100644 index 0000000..f4242c9 --- /dev/null +++ b/SOURCES/0113-v2v-i-ova-Make-error-message-unsupported-file-format.patch @@ -0,0 +1,28 @@ +From e4dc8b36f3e7b16b81ea220b10325726c0406bca Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Wed, 28 Jan 2015 13:28:37 +0000 +Subject: [PATCH] v2v: -i ova: Make error message "unsupported file format" + clearer. + +Thanks: Moran Goldboim +(cherry picked from commit 6a195d0f9565ad0e6e46f3e9904a6dea129e59f4) +--- + v2v/input_ova.ml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/v2v/input_ova.ml b/v2v/input_ova.ml +index 1ab0320..e2a1243 100644 +--- a/v2v/input_ova.ml ++++ b/v2v/input_ova.ml +@@ -63,7 +63,7 @@ object + error (f_"error unpacking %s, see earlier error messages") ova; + tmpdir + | `GZip | `XZ | `Unknown -> +- error (f_"%s: unsupported file format") ova ++ error (f_"%s: unsupported file format\n\nFormats which we currently understand for '-i ova' are: uncompressed tar, zip") ova + ) in + + (* Exploded path must be absolute (RHBZ#1155121). *) +-- +1.8.3.1 + diff --git a/SOURCES/0114-v2v-o-libvirt-Prevent-possible-XPath-injection.patch b/SOURCES/0114-v2v-o-libvirt-Prevent-possible-XPath-injection.patch new file mode 100644 index 0000000..3905238 --- /dev/null +++ b/SOURCES/0114-v2v-o-libvirt-Prevent-possible-XPath-injection.patch @@ -0,0 +1,38 @@ +From 3815caab495ce2644eee574bb3564cddf886bebe Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Sat, 20 Dec 2014 17:46:53 +0000 +Subject: [PATCH] v2v: -o libvirt: Prevent possible XPath injection. + +Ensure the arch string is sane before using it in the following XPath +expression. Since the arch string can be derived from untrusted guest +data [see src/filearch.c], this prevents a possible XPath injection +vulnerability. + +(cherry picked from commit 6c6ce85f94c36803fe2db35a98db436bff0c14b0) +--- + v2v/output_libvirt.ml | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/v2v/output_libvirt.ml b/v2v/output_libvirt.ml +index dc9466c..7f9a3a0 100644 +--- a/v2v/output_libvirt.ml ++++ b/v2v/output_libvirt.ml +@@ -30,9 +30,15 @@ module StringSet = Set.Make (String) + let string_set_of_list = + List.fold_left (fun set x -> StringSet.add x set) StringSet.empty + ++let arch_sanity_re = Str.regexp "^[-_A-Za-z0-9]+$" ++ + let target_features_of_capabilities_doc doc arch = + let xpathctx = Xml.xpath_new_context doc in + let expr = ++ (* Check the arch is sane. It comes from untrusted input. This ++ * avoids XPath injection below. ++ *) ++ assert (Str.string_match arch_sanity_re arch 0); + (* NB: Pay attention to the square brackets. This returns the + * nodes! + *) +-- +1.8.3.1 + diff --git a/SOURCES/0115-v2v-Add-note-about-RHEL-4-conversions-hanging-during.patch b/SOURCES/0115-v2v-Add-note-about-RHEL-4-conversions-hanging-during.patch new file mode 100644 index 0000000..3c61206 --- /dev/null +++ b/SOURCES/0115-v2v-Add-note-about-RHEL-4-conversions-hanging-during.patch @@ -0,0 +1,44 @@ +From 6c03f770b86348ec3ce8283e3df245cb22b716e8 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Mon, 30 Mar 2015 13:22:58 +0100 +Subject: [PATCH] v2v: Add note about RHEL 4 conversions hanging during SELinux + relabelling. + +(cherry picked from commit d4ab702dad39fe1f609ee17661f6bfa3a11dee31) +--- + v2v/virt-v2v.pod | 19 +++++++++++++++++++ + 1 file changed, 19 insertions(+) + +diff --git a/v2v/virt-v2v.pod b/v2v/virt-v2v.pod +index 2e49fbf..e3f97f2 100644 +--- a/v2v/virt-v2v.pod ++++ b/v2v/virt-v2v.pod +@@ -618,6 +618,25 @@ below. + Windows Drivers are installed from /usr/share/virtio-win + if present + ++=head1 RHEL 4 ++ ++=head2 SELinux relabel appears to hang forever ++ ++In RHEL E 4.7 there was a bug which causes SELinux relabelling ++to appear to hang forever at: ++ ++ *** Warning -- SELinux relabel is required. *** ++ *** Disabling security enforcement. *** ++ *** Relabeling could take a very long time, *** ++ *** depending on file system size. *** ++ ++In reality it is waiting for you to press a key (but there is no ++visual indication of this). You can either hit the C<[Return]> key, ++at which point the guest will finish relabelling and reboot, or you ++can install policycoreutils E 1.18.1-4.13 before starting the v2v ++conversion. See also ++L ++ + =head1 WINDOWS + + =head2 Boot failure: 0x0000007B +-- +1.8.3.1 + diff --git a/SOURCES/0116-v2v-RHEL-4-You-have-to-update-lvm2-device-mapper-to-.patch b/SOURCES/0116-v2v-RHEL-4-You-have-to-update-lvm2-device-mapper-to-.patch new file mode 100644 index 0000000..c6af10c --- /dev/null +++ b/SOURCES/0116-v2v-RHEL-4-You-have-to-update-lvm2-device-mapper-to-.patch @@ -0,0 +1,34 @@ +From 953e67d5f2545886862e9a403663f919004719f4 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Mon, 30 Mar 2015 13:23:10 +0100 +Subject: [PATCH] v2v: RHEL 4: You have to update lvm2, device-mapper to get + virtio support. + +Also include the updated selinux policy that goes with RHEL 4.8. + +Also mention that policycoreutils should be updated - see previous +commit. + +(cherry picked from commit 453db7e210673cbd361a4d380e07e607ea833b9c) +--- + v2v/virt-v2v.pod | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/v2v/virt-v2v.pod b/v2v/virt-v2v.pod +index e3f97f2..033040e 100644 +--- a/v2v/virt-v2v.pod ++++ b/v2v/virt-v2v.pod +@@ -598,6 +598,10 @@ below. + RHEL 3 No virtio drivers are available + + RHEL 4 kernel >= 2.5.9-89.EL ++ lvm2 >= 2.02.42-5.el4 ++ device-mapper >= 1.02.28-2.el4 ++ selinux-policy-targeted >= 1.17.30-2.152.el4 ++ policycoreutils >= 1.18.1-4.13 + + RHEL 5 kernel >= 2.6.18-128.el5 + lvm2 >= 2.02.40-6.el5 +-- +1.8.3.1 + diff --git a/SOURCES/0117-v2v-Add-support-for-REG_MULTI_SZ-multiple-strings-to.patch b/SOURCES/0117-v2v-Add-support-for-REG_MULTI_SZ-multiple-strings-to.patch new file mode 100644 index 0000000..f8da6d6 --- /dev/null +++ b/SOURCES/0117-v2v-Add-support-for-REG_MULTI_SZ-multiple-strings-to.patch @@ -0,0 +1,52 @@ +From f66959c79ab2d0ed26d9012024ac0ee4068b2aab Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Tue, 7 Apr 2015 16:58:40 +0100 +Subject: [PATCH] v2v: Add support for REG_MULTI_SZ (multiple strings) to + registry editor. + +(cherry picked from commit 4fd70eab4ff7d9a8e49db2938a80dcef45db150c) +--- + mllib/regedit.ml | 8 ++++++++ + mllib/regedit.mli | 1 + + 2 files changed, 9 insertions(+) + +diff --git a/mllib/regedit.ml b/mllib/regedit.ml +index 673b215..0291fe4 100644 +--- a/mllib/regedit.ml ++++ b/mllib/regedit.ml +@@ -30,6 +30,7 @@ and regtype = + | REG_EXPAND_SZ of string + | REG_BINARY of string + | REG_DWORD of int32 ++| REG_MULTI_SZ of string list + + (* Take a 7 bit ASCII string and encode it as UTF16LE. *) + let encode_utf16le str = +@@ -97,5 +98,12 @@ and import_value g node = function + g#hivex_node_set_value node key 3L bin + | key, REG_DWORD dw -> + g#hivex_node_set_value node key 4L (le32_of_int (Int64.of_int32 dw)) ++ | key, REG_MULTI_SZ ss -> ++ (* http://blogs.msdn.com/oldnewthing/archive/2009/10/08/9904646.aspx *) ++ List.iter (fun s -> assert (s <> "")) ss; ++ let ss = ss @ [""] in ++ let ss = List.map (fun s -> encode_utf16le s ^ "\000\000") ss in ++ let ss = String.concat "" ss in ++ g#hivex_node_set_value node key 7L ss + + let reg_import g root = List.iter (import_key g root) +diff --git a/mllib/regedit.mli b/mllib/regedit.mli +index 1f43cdd..985e405 100644 +--- a/mllib/regedit.mli ++++ b/mllib/regedit.mli +@@ -47,6 +47,7 @@ and regtype = + | REG_EXPAND_SZ of string (** String with %env% *) + | REG_BINARY of string (** Blob of binary data *) + | REG_DWORD of int32 (** Little endian 32 bit integer *) ++| REG_MULTI_SZ of string list (** List of strings *) + (* There are more types in the Registry, but we don't support them here... *) + (** Registry value type and data. + +-- +1.8.3.1 + diff --git a/SOURCES/0118-v2v-Document-that-vCenter-5.0-is-required-RHBZ-11742.patch b/SOURCES/0118-v2v-Document-that-vCenter-5.0-is-required-RHBZ-11742.patch new file mode 100644 index 0000000..1b1c3a3 --- /dev/null +++ b/SOURCES/0118-v2v-Document-that-vCenter-5.0-is-required-RHBZ-11742.patch @@ -0,0 +1,31 @@ +From d80e43e17b37af214aa6e81904afc7b7b9c47247 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Mon, 13 Apr 2015 11:46:29 +0100 +Subject: [PATCH] v2v: Document that vCenter >= 5.0 is required (RHBZ#1174200). + +vCenter 5.0 was released in 2011. We have not tested against any +earlier versions, but it was reported that it does not work with +vCenter 4. + +Thanks: Sokratis +(cherry picked from commit abf23ece49972111e19147087664e7442d84fdfd) +--- + v2v/virt-v2v.pod | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/v2v/virt-v2v.pod b/v2v/virt-v2v.pod +index 033040e..7de265b 100644 +--- a/v2v/virt-v2v.pod ++++ b/v2v/virt-v2v.pod +@@ -744,6 +744,8 @@ I<--bridge> option instead. For example: + + Virt-v2v is able to import guests from VMware vCenter Server. + ++vCenter E 5.0 is required. ++ + Note that virt-v2v B import guests directly from an ESXi + hypervisor. + +-- +1.8.3.1 + diff --git a/SOURCES/0119-v2v-Add-a-man-page-section-on-importing-from-OVA-fil.patch b/SOURCES/0119-v2v-Add-a-man-page-section-on-importing-from-OVA-fil.patch new file mode 100644 index 0000000..11f23f2 --- /dev/null +++ b/SOURCES/0119-v2v-Add-a-man-page-section-on-importing-from-OVA-fil.patch @@ -0,0 +1,87 @@ +From 6d1d399ecb2016f12a6bdd6440cd4b5111050098 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Mon, 13 Apr 2015 12:01:22 +0100 +Subject: [PATCH] v2v: Add a man page section on importing from OVA files. + +(cherry picked from commit e062093881d66b56c4935054ad409ecf2531880b) +--- + v2v/virt-v2v.pod | 49 ++++++++++++++++++++++++++++++++++++++++++++----- + 1 file changed, 44 insertions(+), 5 deletions(-) + +diff --git a/v2v/virt-v2v.pod b/v2v/virt-v2v.pod +index 7de265b..91e8f3e 100644 +--- a/v2v/virt-v2v.pod ++++ b/v2v/virt-v2v.pod +@@ -202,7 +202,8 @@ Set the input method to I. + + In this mode you can read a VMware ova file. Virt-v2v will read the + ova manifest file and check the vmdk volumes for validity (checksums) +-as well as analyzing the ovf file, and then convert the guest. ++as well as analyzing the ovf file, and then convert the guest. See ++L below + + =item B<-ic> libvirtURI + +@@ -744,10 +745,9 @@ I<--bridge> option instead. For example: + + Virt-v2v is able to import guests from VMware vCenter Server. + +-vCenter E 5.0 is required. +- +-Note that virt-v2v B import guests directly from an ESXi +-hypervisor. ++vCenter E 5.0 is required. Virt-v2v B import guests ++directly from an ESXi hypervisor. If you don't have vCenter, using ++OVA is recommended instead (see L below). + + 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 +@@ -884,6 +884,45 @@ In this case the output flags are set to write the converted guest to + a temporary directory as this is just an example, but you can also + write to libvirt or any other supported target. + ++=head1 INPUT FROM VMWARE OVA ++ ++Virt-v2v is able to import guests from VMware's OVA (Open ++Virtualization Appliance) files. Only OVAs exported from VMware ++vSphere will work. ++ ++=head2 OVA: 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 OVA: CREATE OVA ++ ++To create an OVA in vSphere, use the "Export OVF Template" option ++(from the VM context menu, or from the File menu). Either "Folder of ++files" (OVF) or "Single file" (OVA) will work, but OVA is probably ++easier to deal with. OVA files are really just uncompressed tar ++files, so you can use commands like C to view their ++contents. ++ ++=head2 OVA: IMPORTING A GUEST ++ ++To import an OVA file called C, do; ++ ++ $ virt-v2v -i ova VM.ova -o local -os /var/tmp ++ ++If you exported the guest as a "Folder of files", I if you ++unpacked the OVA tarball yourself, then you can point virt-v2v at the ++directory containing the files: ++ ++ $ virt-v2v -i ova /path/to/files -o local -os /var/tmp ++ + =head1 INPUT FROM RHEL 5 XEN + + Virt-v2v is able to import Xen guests from RHEL 5 Xen hosts. +-- +1.8.3.1 + diff --git a/SOURCES/0120-resize-fix-No-space-left-on-device-problem-when-copy.patch b/SOURCES/0120-resize-fix-No-space-left-on-device-problem-when-copy.patch new file mode 100644 index 0000000..29b302e --- /dev/null +++ b/SOURCES/0120-resize-fix-No-space-left-on-device-problem-when-copy.patch @@ -0,0 +1,42 @@ +From 67cdc9c732090a47f7f0345d43614c8b4a527f53 Mon Sep 17 00:00:00 2001 +From: Hu Tao +Date: Mon, 8 Dec 2014 11:20:54 +0800 +Subject: [PATCH] resize: fix 'No space left on device' problem when copying to + an extended partition (RHBZ#1169015) + +Because of the size of an extended partition reported by Linux is always 1024 +bytes, so it will always fail to copy to an extended partition. + +This patch fixes this problem by copying to the offset of an extended +partition in the destination disk. + +Signed-off-by: Hu Tao +(cherry picked from commit 9d6f0b6a86d68438b27a3d783677c63f39ec6627) +--- + resize/resize.ml | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/resize/resize.ml b/resize/resize.ml +index b581b39..b4e8990 100644 +--- a/resize/resize.ml ++++ b/resize/resize.ml +@@ -1152,9 +1152,15 @@ read the man page virt-resize(1). + * source = "/dev/sda2", because the device name only covers + * the first 1K of the partition. Instead, copy the + * source bytes from the parent disk (/dev/sda). ++ * ++ * You can't write directly to the extended partition, ++ * because the size of it reported by Linux is always 1024 ++ * bytes. Instead, write to the offset of the extended ++ * partition in the destination disk (/dev/sdb). + *) + let srcoffset = p.p_part.G.part_start in +- g#copy_device_to_device ~srcoffset ~size:copysize "/dev/sda" target ++ let destoffset = p.p_target_start *^ 512L in ++ g#copy_device_to_device ~srcoffset ~destoffset ~size:copysize "/dev/sda" "/dev/sdb" + ) + | OpIgnore | OpDelete -> () + in +-- +1.8.3.1 + diff --git a/SOURCES/0121-launch-libvirt-Implement-drive-secrets-RHBZ-1159016.patch b/SOURCES/0121-launch-libvirt-Implement-drive-secrets-RHBZ-1159016.patch new file mode 100644 index 0000000..f1d587b --- /dev/null +++ b/SOURCES/0121-launch-libvirt-Implement-drive-secrets-RHBZ-1159016.patch @@ -0,0 +1,442 @@ +From a72b602cfabd360335a63e70b6cb1abf7e82f69a Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Fri, 31 Oct 2014 11:02:33 +0000 +Subject: [PATCH] launch: libvirt: Implement drive secrets (RHBZ#1159016). + +Implement the GUESTFS_ADD_DRIVE_OPTS_SECRET argument of +guestfs_add_drive_opts. For libvirt we have to save the secret in +libvirtd first, get a UUID, and then pass the UUID back through the +domain XML. + +(cherry picked from commit 6d6644d52d8092dd4f4add859ebda06bea4b5b56) +--- + bootstrap | 1 + + generator/actions.ml | 2 +- + m4/.gitignore | 4 + + src/launch-libvirt.c | 272 ++++++++++++++++++++++++++++++++++++++++++++++++++- + 4 files changed, 275 insertions(+), 4 deletions(-) + +diff --git a/bootstrap b/bootstrap +index b4afcdb..70789e3 100755 +--- a/bootstrap ++++ b/bootstrap +@@ -41,6 +41,7 @@ accept4 + areadlink + areadlinkat + arpa_inet ++base64 + byteswap + c-ctype + cloexec +diff --git a/generator/actions.ml b/generator/actions.ml +index ea715d0..4bc043b 100644 +--- a/generator/actions.ml ++++ b/generator/actions.ml +@@ -1452,7 +1452,7 @@ specify the remote username you want. + =item C + + For the C protocol only, this specifies the 'secret' to use when +-connecting to the remote device. ++connecting to the remote device. It must be base64 encoded. + + If not given, then a secret matching the given username will be looked up in the + default keychain locations, or if no username is given, then no authentication +diff --git a/m4/.gitignore b/m4/.gitignore +index ed73ab3..b0f8d4b 100644 +--- a/m4/.gitignore ++++ b/m4/.gitignore +@@ -5,6 +5,7 @@ + /argmatch.m4 + /arpa_inet_h.m4 + /asm-underscore.m4 ++/base64.m4 + /btowc.m4 + /byteswap.m4 + /canonicalize-lgpl.m4 +@@ -104,6 +105,7 @@ + /inttypes-pri.m4 + /ioctl.m4 + /i-ring.m4 ++/isatty.m4 + /isc-posix.m4 + /largefile.m4 + /lchown.m4 +@@ -166,6 +168,7 @@ + /printf-posix.m4 + /priv-set.m4 + /progtest.m4 ++/ptsname_r.m4 + /putenv.m4 + /quotearg.m4 + /quote.m4 +@@ -236,6 +239,7 @@ + /thread.m4 + /time_h.m4 + /timespec.m4 ++/ttyname_r.m4 + /uintmax_t.m4 + /ulonglong.m4 + /ungetc.m4 +diff --git a/src/launch-libvirt.c b/src/launch-libvirt.c +index 026fd5a..5daa396 100644 +--- a/src/launch-libvirt.c ++++ b/src/launch-libvirt.c +@@ -49,6 +49,7 @@ + #endif + + #include "glthread/lock.h" ++#include "base64.h" + + #include "guestfs.h" + #include "guestfs-internal.h" +@@ -96,6 +97,27 @@ xmlBufferDetach (xmlBufferPtr buf) + } + #endif + ++#ifdef HAVE_ATTRIBUTE_CLEANUP ++#define CLEANUP_VIRSECRETFREE __attribute__((cleanup(cleanup_virSecretFree))) ++ ++static void ++cleanup_virSecretFree (void *ptr) ++{ ++ virSecretPtr secret_obj = * (virSecretPtr *) ptr; ++ if (secret_obj) ++ virSecretFree (secret_obj); ++} ++ ++#else /* !HAVE_ATTRIBUTE_CLEANUP */ ++#define CLEANUP_VIRSECRETFREE ++#endif ++ ++/* List used to store a mapping of secret to libvirt secret UUID. */ ++struct secret { ++ char *secret; ++ char uuid[VIR_UUID_STRING_BUFLEN]; ++}; ++ + #define DOMAIN_NAME_LEN (8+16+1) /* "guestfs-" + random + \0 */ + + /* Per-handle data. */ +@@ -108,6 +130,8 @@ struct backend_libvirt_data { + char name[DOMAIN_NAME_LEN]; /* random name */ + bool is_kvm; /* false = qemu, true = kvm (from capabilities)*/ + unsigned long qemu_version; /* qemu version (from libvirt) */ ++ struct secret *secrets; /* list of secrets */ ++ size_t nr_secrets; + char *uefi_code; /* UEFI (firmware) code and variables. */ + char *uefi_vars; + }; +@@ -130,6 +154,9 @@ struct libvirt_xml_params { + }; + + static int parse_capabilities (guestfs_h *g, const char *capabilities_xml, struct backend_libvirt_data *data); ++static int add_secret (guestfs_h *g, virConnectPtr conn, struct backend_libvirt_data *data, const struct drive *drv); ++static int find_secret (guestfs_h *g, const struct backend_libvirt_data *data, const struct drive *drv, const char **type, const char **uuid); ++static int have_secret (guestfs_h *g, const struct backend_libvirt_data *data, const struct drive *drv); + static xmlChar *construct_libvirt_xml (guestfs_h *g, const struct libvirt_xml_params *params); + static void debug_appliance_permissions (guestfs_h *g); + static void debug_socket_permissions (guestfs_h *g); +@@ -224,6 +251,8 @@ launch_libvirt (guestfs_h *g, void *datav, const char *libvirt_uri) + CLEANUP_FREE xmlChar *xml = NULL; + CLEANUP_FREE char *appliance = NULL; + struct sockaddr_un addr; ++ struct drive *drv; ++ size_t i; + int r; + uint32_t size; + CLEANUP_FREE void *buf = NULL; +@@ -456,6 +485,14 @@ launch_libvirt (guestfs_h *g, void *datav, const char *libvirt_uri) + debug (g, "cannot find group 'qemu'"); + } + ++ /* Store any secrets in libvirtd, keeping a mapping from the secret ++ * to its UUID. ++ */ ++ ITER_DRIVES (g, i, drv) { ++ if (add_secret (g, conn, data, drv) == -1) ++ goto cleanup; ++ } ++ + /* Construct the libvirt XML. */ + if (g->verbose) + guestfs___print_timestamped_message (g, "create libvirt XML"); +@@ -1275,6 +1312,8 @@ construct_libvirt_xml_disk (guestfs_h *g, + CLEANUP_FREE char *path = NULL; + int is_host_device; + CLEANUP_FREE char *format = NULL; ++ const char *type, *uuid; ++ int r; + + /* XXX We probably could support this if we thought about it some more. */ + if (drv->iface) { +@@ -1386,9 +1425,15 @@ construct_libvirt_xml_disk (guestfs_h *g, + if (drv->src.username != NULL) { + start_element ("auth") { + attribute ("username", drv->src.username); +- /* TODO: write the drive secret, after first storing it separately +- * in libvirt +- */ ++ r = find_secret (g, data, drv, &type, &uuid); ++ if (r == -1) ++ return -1; ++ if (r == 1) { ++ start_element ("secret") { ++ attribute ("type", type); ++ attribute ("uuid", uuid); ++ } end_element (); ++ } + } end_element (); + } + break; +@@ -1696,6 +1741,216 @@ construct_libvirt_xml_qemu_cmdline (guestfs_h *g, + } + + static int ++construct_libvirt_xml_secret (guestfs_h *g, ++ const struct backend_libvirt_data *data, ++ const struct drive *drv, ++ xmlTextWriterPtr xo) ++{ ++ start_element ("secret") { ++ attribute ("ephemeral", "yes"); ++ attribute ("private", "yes"); ++ start_element ("description") { ++ string_format ("guestfs secret associated with %s %s", ++ data->name, drv->src.u.path); ++ } end_element (); ++ } end_element (); ++ ++ return 0; ++} ++ ++/* If drv->src.secret != NULL, store the secret in libvirt, and save ++ * the UUID so we can retrieve it later. Also there is some slight ++ * variation depending on the protocol. See ++ * http://libvirt.org/formatsecret.html ++ */ ++static int ++add_secret (guestfs_h *g, virConnectPtr conn, ++ struct backend_libvirt_data *data, const struct drive *drv) ++{ ++ CLEANUP_XMLBUFFERFREE xmlBufferPtr xb = NULL; ++ xmlOutputBufferPtr ob; ++ CLEANUP_XMLFREETEXTWRITER xmlTextWriterPtr xo = NULL; ++ CLEANUP_FREE xmlChar *xml = NULL; ++ CLEANUP_VIRSECRETFREE virSecretPtr secret_obj = NULL; ++ const char *secret = drv->src.secret; ++ CLEANUP_FREE unsigned char *secret_raw = NULL; ++ size_t secret_raw_len = 0; ++ size_t i; ++ ++ if (secret == NULL) ++ return 0; ++ ++ /* If it was already stored, don't create another secret. */ ++ if (have_secret (g, data, drv)) ++ return 0; ++ ++ /* Create the XML for the secret. */ ++ xb = xmlBufferCreate (); ++ if (xb == NULL) { ++ perrorf (g, "xmlBufferCreate"); ++ return -1; ++ } ++ ob = xmlOutputBufferCreateBuffer (xb, NULL); ++ if (ob == NULL) { ++ perrorf (g, "xmlOutputBufferCreateBuffer"); ++ return -1; ++ } ++ xo = xmlNewTextWriter (ob); ++ if (xo == NULL) { ++ perrorf (g, "xmlNewTextWriter"); ++ return -1; ++ } ++ ++ if (xmlTextWriterSetIndent (xo, 1) == -1 || ++ xmlTextWriterSetIndentString (xo, BAD_CAST " ") == -1) { ++ perrorf (g, "could not set XML indent"); ++ return -1; ++ } ++ if (xmlTextWriterStartDocument (xo, NULL, NULL, NULL) == -1) { ++ perrorf (g, "xmlTextWriterStartDocument"); ++ return -1; ++ } ++ ++ if (construct_libvirt_xml_secret (g, data, drv, xo) == -1) ++ return -1; ++ ++ if (xmlTextWriterEndDocument (xo) == -1) { ++ perrorf (g, "xmlTextWriterEndDocument"); ++ return -1; ++ } ++ xml = xmlBufferDetach (xb); ++ if (xml == NULL) { ++ perrorf (g, "xmlBufferDetach"); ++ return -1; ++ } ++ ++ debug (g, "libvirt secret XML:\n%s", xml); ++ ++ /* Pass the XML to libvirt. */ ++ secret_obj = virSecretDefineXML (conn, (const char *) xml, 0); ++ if (secret_obj == NULL) { ++ libvirt_error (g, _("could not define libvirt secret")); ++ return -1; ++ } ++ ++ /* For Ceph, we have to base64 decode the secret. For others, we ++ * currently just pass the secret straight through. ++ */ ++ switch (drv->src.protocol) { ++ case drive_protocol_rbd: ++ if (!base64_decode_alloc (secret, strlen (secret), ++ (char **) &secret_raw, &secret_raw_len)) { ++ error (g, _("rbd protocol secret must be base64 encoded")); ++ return -1; ++ } ++ if (secret_raw == NULL) { ++ error (g, _("base64_decode_alloc: %m")); ++ return -1; ++ } ++ break; ++ case drive_protocol_file: ++ case drive_protocol_ftp: ++ case drive_protocol_ftps: ++ case drive_protocol_gluster: ++ case drive_protocol_http: ++ case drive_protocol_https: ++ case drive_protocol_iscsi: ++ case drive_protocol_nbd: ++ case drive_protocol_sheepdog: ++ case drive_protocol_ssh: ++ case drive_protocol_tftp: ++ secret_raw = (unsigned char *) safe_strdup (g, secret); ++ secret_raw_len = strlen (secret); ++ } ++ ++ /* Set the secret. */ ++ if (virSecretSetValue (secret_obj, secret_raw, secret_raw_len, 0) == -1) { ++ libvirt_error (g, _("could not set libvirt secret value")); ++ return -1; ++ } ++ ++ /* Get back the UUID and save it in the private data. */ ++ i = data->nr_secrets; ++ data->nr_secrets++; ++ data->secrets = ++ safe_realloc (g, data->secrets, sizeof (struct secret) * data->nr_secrets); ++ ++ data->secrets[i].secret = safe_strdup (g, secret); ++ ++ if (virSecretGetUUIDString (secret_obj, data->secrets[i].uuid) == -1) { ++ libvirt_error (g, _("could not get UUID from libvirt secret")); ++ return -1; ++ } ++ ++ return 0; ++} ++ ++static int ++have_secret (guestfs_h *g, ++ const struct backend_libvirt_data *data, const struct drive *drv) ++{ ++ size_t i; ++ ++ if (drv->src.secret == NULL) ++ return 0; ++ ++ for (i = 0; i < data->nr_secrets; ++i) { ++ if (STREQ (data->secrets[i].secret, drv->src.secret)) ++ return 1; ++ } ++ ++ return 0; ++} ++ ++/* Find a secret previously stored in libvirt. Returns the ++ * attributes. This function returns -1 ++ * if there was an error, 0 if there is no secret, and 1 if the ++ * secret was found and returned. ++ */ ++static int ++find_secret (guestfs_h *g, ++ const struct backend_libvirt_data *data, const struct drive *drv, ++ const char **type, const char **uuid) ++{ ++ size_t i; ++ ++ if (drv->src.secret == NULL) ++ return 0; ++ ++ for (i = 0; i < data->nr_secrets; ++i) { ++ if (STREQ (data->secrets[i].secret, drv->src.secret)) { ++ *uuid = data->secrets[i].uuid; ++ ++ *type = "volume"; ++ ++ switch (drv->src.protocol) { ++ case drive_protocol_rbd: ++ *type = "ceph"; ++ break; ++ case drive_protocol_iscsi: ++ *type = "iscsi"; ++ break; ++ case drive_protocol_file: ++ case drive_protocol_ftp: ++ case drive_protocol_ftps: ++ case drive_protocol_gluster: ++ case drive_protocol_http: ++ case drive_protocol_https: ++ case drive_protocol_nbd: ++ case drive_protocol_sheepdog: ++ case drive_protocol_ssh: ++ case drive_protocol_tftp: ++ /* set to a default value above */ ; ++ } ++ ++ return 1; ++ } ++ } ++ ++ return 0; ++} ++ ++static int + is_blk (const char *path) + { + struct stat statbuf; +@@ -1717,6 +1972,7 @@ shutdown_libvirt (guestfs_h *g, void *datav, int check_for_errors) + struct backend_libvirt_data *data = datav; + virConnectPtr conn = data->conn; + virDomainPtr dom = data->dom; ++ size_t i; + int ret = 0; + int flags; + +@@ -1751,6 +2007,12 @@ shutdown_libvirt (guestfs_h *g, void *datav, int check_for_errors) + free (data->uefi_vars); + data->uefi_vars = NULL; + ++ for (i = 0; i < data->nr_secrets; ++i) ++ free (data->secrets[i].secret); ++ free (data->secrets); ++ data->secrets = NULL; ++ data->nr_secrets = 0; ++ + return ret; + } + +@@ -1855,6 +2117,10 @@ hot_add_drive_libvirt (guestfs_h *g, void *datav, + return -1; + } + ++ /* If the drive has an associated secret, store it in libvirt. */ ++ if (add_secret (g, conn, data, drv) == -1) ++ return -1; ++ + /* Create the XML for the new disk. */ + xml = construct_libvirt_xml_hot_add_disk (g, data, drv, drv_index); + if (xml == NULL) +-- +1.8.3.1 + diff --git a/SOURCES/0122-v2v-allow-configurable-location-for-virtio-drivers.patch b/SOURCES/0122-v2v-allow-configurable-location-for-virtio-drivers.patch new file mode 100644 index 0000000..1f44b95 --- /dev/null +++ b/SOURCES/0122-v2v-allow-configurable-location-for-virtio-drivers.patch @@ -0,0 +1,62 @@ +From b89ad1b8ac7f31511254c383573c812ff93abd91 Mon Sep 17 00:00:00 2001 +From: Roman Kagan +Date: Tue, 31 Mar 2015 16:26:38 +0300 +Subject: [PATCH] v2v: allow configurable location for virtio drivers + +Make the location of the Windows virtio drivers overridable with the +environment variable VIRTIO_WIN_DIR, in the same vein as is done for +virt-tools. + +Signed-off-by: Roman Kagan +(cherry picked from commit b8cb5c0d69e7ab8cd8598c0c49f0d65a1366cd62) +--- + v2v/convert_windows.ml | 4 +++- + v2v/virt-v2v.pod | 10 ++++++++-- + 2 files changed, 11 insertions(+), 3 deletions(-) + +diff --git a/v2v/convert_windows.ml b/v2v/convert_windows.ml +index 1605a91..1e77369 100644 +--- a/v2v/convert_windows.ml ++++ b/v2v/convert_windows.ml +@@ -47,7 +47,9 @@ let convert ~verbose ~keep_serial_console (g : G.guestfs) inspect source = + try Sys.getenv "VIRT_TOOLS_DATA_DIR" + with Not_found -> Config.datadir // "virt-tools" in + +- let virtio_win_dir = "/usr/share/virtio-win" in ++ let virtio_win_dir = ++ try Sys.getenv "VIRTIO_WIN_DIR" ++ with Not_found -> Config.datadir // "virtio-win" in + + (* Check if RHEV-APT exists. This is optional. *) + let rhev_apt_exe = virt_tools_data_dir // "rhev-apt.exe" in +diff --git a/v2v/virt-v2v.pod b/v2v/virt-v2v.pod +index 91e8f3e..5ee3bd8 100644 +--- a/v2v/virt-v2v.pod ++++ b/v2v/virt-v2v.pod +@@ -620,8 +620,9 @@ below. + + OpenSUSE 10 kernel >= 2.6.25.5-1.1 + +- Windows Drivers are installed from /usr/share/virtio-win +- if present ++ Windows Drivers are installed from the directory pointed to by ++ "VIRTIO_WIN_DIR" environment variable ++ (/usr/share/virtio-win by default) if present + + =head1 RHEL 4 + +@@ -1440,6 +1441,11 @@ not distributed with virt-v2v. + + =back + ++=item C ++ ++This is where VirtIO drivers for Windows are searched for ++(F if unset). See L. ++ + =back + + For other environment variables, see L. +-- +1.8.3.1 + diff --git a/SOURCES/0123-daemon-use-btrfs-1-to-get-btrfs-labels.patch b/SOURCES/0123-daemon-use-btrfs-1-to-get-btrfs-labels.patch new file mode 100644 index 0000000..243e978 --- /dev/null +++ b/SOURCES/0123-daemon-use-btrfs-1-to-get-btrfs-labels.patch @@ -0,0 +1,100 @@ +From d16202fa66f981949fc49573030721cda35705dc Mon Sep 17 00:00:00 2001 +From: Pino Toscano +Date: Wed, 14 Jan 2015 18:55:13 +0100 +Subject: [PATCH] daemon: use btrfs(1) to get btrfs labels + +blkid(1) (or actually, libblkid) seems to handle filesystem labels up +to 127 characters. Considering that btrfs labels can be up to 255 +characters, this means long labels are not read correctly (i.e. get +truncated) by blkid. + +Get the filesystem type, and if btrfs is available invoke +`btrfs filesystem` to get the label of btrfs filesystems. + +Related to RHBZ#1164708. + +(cherry picked from commit 6db3c100e7c18820ff9ecc22415940eb5fedc64e) +--- + daemon/blkid.c | 8 ++++++++ + daemon/btrfs.c | 24 ++++++++++++++++++++++++ + daemon/daemon.h | 3 +++ + 3 files changed, 35 insertions(+) + +diff --git a/daemon/blkid.c b/daemon/blkid.c +index b98c155..e8e7b58 100644 +--- a/daemon/blkid.c ++++ b/daemon/blkid.c +@@ -26,6 +26,7 @@ + + #include "daemon.h" + #include "actions.h" ++#include "optgroups.h" + + GUESTFSD_EXT_CMD(str_blkid, blkid); + +@@ -76,6 +77,13 @@ do_vfs_type (const mountable_t *mountable) + char * + do_vfs_label (const mountable_t *mountable) + { ++ CLEANUP_FREE char *type = do_vfs_type (mountable); ++ ++ if (type) { ++ if (STREQ (type, "btrfs") && optgroup_btrfs_available ()) ++ return btrfs_get_label (mountable->device); ++ } ++ + return get_blkid_tag (mountable->device, "LABEL"); + } + +diff --git a/daemon/btrfs.c b/daemon/btrfs.c +index 7a4d43d..86bad36 100644 +--- a/daemon/btrfs.c ++++ b/daemon/btrfs.c +@@ -42,6 +42,30 @@ optgroup_btrfs_available (void) + return prog_exists (str_btrfs) && filesystem_available ("btrfs") > 0; + } + ++char * ++btrfs_get_label (const char *device) ++{ ++ int r; ++ CLEANUP_FREE char *err = NULL; ++ char *out = NULL; ++ size_t len; ++ ++ r = command (&out, &err, str_btrfs, "filesystem", "label", ++ device, NULL); ++ if (r == -1) { ++ reply_with_error ("%s", err); ++ free (out); ++ return NULL; ++ } ++ ++ /* Trim trailing \n if present. */ ++ len = strlen (out); ++ if (len > 0 && out[len-1] == '\n') ++ out[len-1] = '\0'; ++ ++ return out; ++} ++ + /* Takes optional arguments, consult optargs_bitmask. */ + int + do_btrfs_filesystem_resize (const char *filesystem, int64_t size) +diff --git a/daemon/daemon.h b/daemon/daemon.h +index f442efd..24ee46a 100644 +--- a/daemon/daemon.h ++++ b/daemon/daemon.h +@@ -257,6 +257,9 @@ extern int copy_xattrs (const char *src, const char *dest); + /* Documented in xfs_admin(8). */ + #define XFS_LABEL_MAX 12 + ++/*-- in btrfs.c --*/ ++extern char *btrfs_get_label (const char *device); ++ + /* ordinary daemon functions use these to indicate errors + * NB: you don't need to prefix the string with the current command, + * it is added automatically by the client-side RPC stubs. +-- +1.8.3.1 + diff --git a/SOURCES/0124-daemon-use-ntfslabel-1-to-get-ntfs-labels.patch b/SOURCES/0124-daemon-use-ntfslabel-1-to-get-ntfs-labels.patch new file mode 100644 index 0000000..7eb2cd4 --- /dev/null +++ b/SOURCES/0124-daemon-use-ntfslabel-1-to-get-ntfs-labels.patch @@ -0,0 +1,95 @@ +From 0c4c35fc3efe4a82b644dfff8e93119fd10ff5a4 Mon Sep 17 00:00:00 2001 +From: Pino Toscano +Date: Wed, 14 Jan 2015 18:59:57 +0100 +Subject: [PATCH] daemon: use ntfslabel(1) to get ntfs labels + +blkid(1) (or actually, libblkid) seems to handle filesystem labels up +to 127 characters. Considering that btrfs labels can be up to 128 +characters, this means long labels are not read correctly (i.e. get +truncated) by blkid. Furthermore, ntfs labels are actually unicode, +and libblkid seems to not decode them correctly. + +Hence, if ntfsprogs is available invoke `ntfslabel` to get the label +of ntfs filesystems. + +Related to RHBZ#1164708. + +(cherry picked from commit 8ad667f1983e98347f4d292c07f971d5362ff052) +--- + daemon/blkid.c | 2 ++ + daemon/daemon.h | 3 +++ + daemon/ntfs.c | 24 ++++++++++++++++++++++++ + 3 files changed, 29 insertions(+) + +diff --git a/daemon/blkid.c b/daemon/blkid.c +index e8e7b58..1ac42b4 100644 +--- a/daemon/blkid.c ++++ b/daemon/blkid.c +@@ -82,6 +82,8 @@ do_vfs_label (const mountable_t *mountable) + if (type) { + if (STREQ (type, "btrfs") && optgroup_btrfs_available ()) + return btrfs_get_label (mountable->device); ++ if (STREQ (type, "ntfs") && optgroup_ntfsprogs_available ()) ++ return ntfs_get_label (mountable->device); + } + + return get_blkid_tag (mountable->device, "LABEL"); +diff --git a/daemon/daemon.h b/daemon/daemon.h +index 24ee46a..e65bcb0 100644 +--- a/daemon/daemon.h ++++ b/daemon/daemon.h +@@ -260,6 +260,9 @@ extern int copy_xattrs (const char *src, const char *dest); + /*-- in btrfs.c --*/ + extern char *btrfs_get_label (const char *device); + ++/*-- in ntfs.c --*/ ++extern char *ntfs_get_label (const char *device); ++ + /* ordinary daemon functions use these to indicate errors + * NB: you don't need to prefix the string with the current command, + * it is added automatically by the client-side RPC stubs. +diff --git a/daemon/ntfs.c b/daemon/ntfs.c +index 762ca88..f1d12e0 100644 +--- a/daemon/ntfs.c ++++ b/daemon/ntfs.c +@@ -33,6 +33,7 @@ + GUESTFSD_EXT_CMD(str_ntfs3g_probe, ntfs-3g.probe); + GUESTFSD_EXT_CMD(str_ntfsresize, ntfsresize); + GUESTFSD_EXT_CMD(str_ntfsfix, ntfsfix); ++GUESTFSD_EXT_CMD(str_ntfslabel, ntfslabel); + + int + optgroup_ntfs3g_available (void) +@@ -46,6 +47,29 @@ optgroup_ntfsprogs_available (void) + return prog_exists (str_ntfsresize); + } + ++char * ++ntfs_get_label (const char *device) ++{ ++ int r; ++ CLEANUP_FREE char *err = NULL; ++ char *out = NULL; ++ size_t len; ++ ++ r = command (&out, &err, str_ntfslabel, device, NULL); ++ if (r == -1) { ++ reply_with_error ("%s", err); ++ free (out); ++ return NULL; ++ } ++ ++ /* Trim trailing \n if present. */ ++ len = strlen (out); ++ if (len > 0 && out[len-1] == '\n') ++ out[len-1] = '\0'; ++ ++ return out; ++} ++ + int + do_ntfs_3g_probe (int rw, const char *device) + { +-- +1.8.3.1 + diff --git a/SOURCES/0125-mknod-filter-modes-in-mkfifo-mknod_b-mknod_c-RHBZ-11.patch b/SOURCES/0125-mknod-filter-modes-in-mkfifo-mknod_b-mknod_c-RHBZ-11.patch new file mode 100644 index 0000000..ce4ae89 --- /dev/null +++ b/SOURCES/0125-mknod-filter-modes-in-mkfifo-mknod_b-mknod_c-RHBZ-11.patch @@ -0,0 +1,131 @@ +From 549bd2733e2530b74632964b2e28548a5704114e Mon Sep 17 00:00:00 2001 +From: Pino Toscano +Date: Thu, 15 Jan 2015 14:40:17 +0100 +Subject: [PATCH] mknod: filter modes in mkfifo, mknod_b, mknod_c + (RHBZ#1182463). + +Since mkfifo, mknod_b, and mknod_c add the correct file type to the +modes of the resulting file, make sure the specified mode contains only +permissions bits. + +(cherry picked from commit 8b9ca28e111e38eafe8db7265e7fe18c5f31b460) +--- + daemon/mknod.c | 15 +++++++++++++++ + generator/actions.ml | 21 ++++++++++++++++++--- + 2 files changed, 33 insertions(+), 3 deletions(-) + +diff --git a/daemon/mknod.c b/daemon/mknod.c +index 7f71210..9af8701 100644 +--- a/daemon/mknod.c ++++ b/daemon/mknod.c +@@ -38,6 +38,15 @@ optgroup_mknod_available (void) + return 1; + } + ++#define CHECK_MODE \ ++ do { \ ++ if ((mode & ~07777) != 0) { \ ++ reply_with_error ("%o: mode must specify only file permission bits", \ ++ (unsigned int) mode); \ ++ return -1; \ ++ } \ ++ } while (0) ++ + int + do_mknod (int mode, int devmajor, int devminor, const char *path) + { +@@ -63,18 +72,24 @@ do_mknod (int mode, int devmajor, int devminor, const char *path) + int + do_mkfifo (int mode, const char *path) + { ++ CHECK_MODE; ++ + return do_mknod (mode | S_IFIFO, 0, 0, path); + } + + int + do_mknod_b (int mode, int devmajor, int devminor, const char *path) + { ++ CHECK_MODE; ++ + return do_mknod (mode | S_IFBLK, devmajor, devminor, path); + } + + int + do_mknod_c (int mode, int devmajor, int devminor, const char *path) + { ++ CHECK_MODE; ++ + return do_mknod (mode | S_IFCHR, devmajor, devminor, path); + } + +diff --git a/generator/actions.ml b/generator/actions.ml +index 4bc043b..263c6f3 100644 +--- a/generator/actions.ml ++++ b/generator/actions.ml +@@ -6104,7 +6104,9 @@ The mode actually set is affected by the umask." }; + InitScratchFS, Always, TestResult ( + [["mkfifo"; "0o777"; "/mkfifo"]; + ["stat"; "/mkfifo"]], +- "S_ISFIFO (ret->mode) && (ret->mode & 0777) == 0755"), [] ++ "S_ISFIFO (ret->mode) && (ret->mode & 0777) == 0755"), []; ++ InitScratchFS, Always, TestLastFail ( ++ [["mkfifo"; "0o20777"; "/mkfifo-2"]]), []; + ]; + shortdesc = "make FIFO (named pipe)"; + longdesc = "\ +@@ -6112,6 +6114,9 @@ This call creates a FIFO (named pipe) called C with + mode C. It is just a convenient wrapper around + C. + ++Unlike with C, C B contain only permissions ++bits. ++ + The mode actually set is affected by the umask." }; + + { defaults with +@@ -6123,7 +6128,9 @@ The mode actually set is affected by the umask." }; + InitScratchFS, Always, TestResult ( + [["mknod_b"; "0o777"; "99"; "66"; "/mknod_b"]; + ["stat"; "/mknod_b"]], +- "S_ISBLK (ret->mode) && (ret->mode & 0777) == 0755"), [] ++ "S_ISBLK (ret->mode) && (ret->mode & 0777) == 0755"), []; ++ InitScratchFS, Always, TestLastFail ( ++ [["mknod_b"; "0o10777"; "99"; "66"; "/mknod_b-2"]]), []; + ]; + shortdesc = "make block device node"; + longdesc = "\ +@@ -6131,6 +6138,9 @@ This call creates a block device node called C with + mode C and device major/minor C and C. + It is just a convenient wrapper around C. + ++Unlike with C, C B contain only permissions ++bits. ++ + The mode actually set is affected by the umask." }; + + { defaults with +@@ -6142,7 +6152,9 @@ The mode actually set is affected by the umask." }; + InitScratchFS, Always, TestResult ( + [["mknod_c"; "0o777"; "99"; "66"; "/mknod_c"]; + ["stat"; "/mknod_c"]], +- "S_ISCHR (ret->mode) && (ret->mode & 0777) == 0755"), [] ++ "S_ISCHR (ret->mode) && (ret->mode & 0777) == 0755"), []; ++ InitScratchFS, Always, TestLastFail ( ++ [["mknod_c"; "0o20777"; "99"; "66"; "/mknod_c-2"]]), []; + ]; + shortdesc = "make char device node"; + longdesc = "\ +@@ -6150,6 +6162,9 @@ This call creates a char device node called C with + mode C and device major/minor C and C. + It is just a convenient wrapper around C. + ++Unlike with C, C B contain only permissions ++bits. ++ + The mode actually set is affected by the umask." }; + + { defaults with +-- +1.8.3.1 + diff --git a/SOURCES/0126-fish-Move-is_true-function-to-library-utilities.patch b/SOURCES/0126-fish-Move-is_true-function-to-library-utilities.patch new file mode 100644 index 0000000..855f1ab --- /dev/null +++ b/SOURCES/0126-fish-Move-is_true-function-to-library-utilities.patch @@ -0,0 +1,152 @@ +From b361a8a13b4cea045315a018a79374e0203ad1fc Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Wed, 17 Dec 2014 12:34:53 +0000 +Subject: [PATCH] fish: Move 'is_true' function to library utilities. + +The 'is_true' function can be useful elsewhere, not just for parsing +guestfish command parameters. + +This is just code motion. + +(cherry picked from commit bdcd2fabe9a5ba6f61e662986fcd92e352f203c0) +--- + fish/fish.c | 26 -------------------------- + generator/fish.ml | 21 ++++++++++++++++----- + src/guestfs-internal-frontend.h | 1 + + src/utils.c | 23 +++++++++++++++++++++++ + 4 files changed, 40 insertions(+), 31 deletions(-) + +diff --git a/fish/fish.c b/fish/fish.c +index 981a7d4..6d07f36 100644 +--- a/fish/fish.c ++++ b/fish/fish.c +@@ -1293,32 +1293,6 @@ print_table (char *const *argv) + printf ("%s: %s\n", argv[i], argv[i+1]); + } + +-int +-is_true (const char *str) +-{ +- /* Similar to Tcl_GetBoolean. */ +- +- if (STREQ (str, "1") || +- STRCASEEQ (str, "true") || +- STRCASEEQ (str, "t") || +- STRCASEEQ (str, "yes") || +- STRCASEEQ (str, "y") || +- STRCASEEQ (str, "on")) +- return 1; +- +- if (STREQ (str, "0") || +- STRCASEEQ (str, "false") || +- STRCASEEQ (str, "f") || +- STRCASEEQ (str, "no") || +- STRCASEEQ (str, "n") || +- STRCASEEQ (str, "off")) +- return 0; +- +- fprintf (stderr, _("%s: '%s': invalid boolean value, use 'true' or 'false'\n"), +- program_name, str); +- return -1; +-} +- + /* Free strings from a non-NULL terminated char** */ + static void + free_n_strings (char **str, size_t len) +diff --git a/generator/fish.ml b/generator/fish.ml +index 3f53ffa..6d6802a 100644 +--- a/generator/fish.ml ++++ b/generator/fish.ml +@@ -84,12 +84,15 @@ let generate_fish_cmds () = + pr "#include \n"; + pr "#include \n"; + pr "#include \n"; ++ pr "#include \n"; + pr "\n"; + pr "#include \"c-ctype.h\"\n"; + pr "#include \"full-write.h\"\n"; + pr "#include \"xstrtol.h\"\n"; + pr "\n"; +- pr "#include \n"; ++ pr "#include \"guestfs.h\"\n"; ++ pr "#include \"guestfs-internal-frontend.h\"\n"; ++ pr "\n"; + pr "#include \"fish.h\"\n"; + pr "#include \"fish-cmds.h\"\n"; + pr "#include \"options.h\"\n"; +@@ -479,8 +482,12 @@ Guestfish will prompt for these separately." + pr " input_lineno++;\n"; + pr " if (%s == NULL) goto out_%s;\n" name name + | Bool name -> +- pr " switch (is_true (argv[i++])) {\n"; +- pr " case -1: goto out_%s;\n" name; ++ pr " switch (guestfs___is_true (argv[i++])) {\n"; ++ pr " case -1:\n"; ++ pr " fprintf (stderr,\n"; ++ pr " _(\"%%s: '%%s': invalid boolean value, use 'true' or 'false'\\n\"),\n"; ++ pr " program_name, argv[i-1]);\n"; ++ pr " goto out_%s;\n" name; + pr " case 0: %s = 0; break;\n" name; + pr " default: %s = 1;\n" name; + pr " }\n" +@@ -518,8 +525,12 @@ Guestfish will prompt for these separately." + pr "if (STRPREFIX (argv[i], \"%s:\")) {\n" n; + (match argt with + | OBool n -> +- pr " switch (is_true (&argv[i][%d])) {\n" (len+1); +- pr " case -1: goto out;\n"; ++ pr " switch (guestfs___is_true (&argv[i][%d])) {\n" (len+1); ++ pr " case -1:\n"; ++ pr " fprintf (stderr,\n"; ++ pr " _(\"%%s: '%%s': invalid boolean value, use 'true' or 'false'\\n\"),\n"; ++ pr " program_name, &argv[i][%d]);\n" (len+1); ++ pr " goto out;\n"; + pr " case 0: optargs_s.%s = 0; break;\n" n; + pr " default: optargs_s.%s = 1;\n" n; + pr " }\n" +diff --git a/src/guestfs-internal-frontend.h b/src/guestfs-internal-frontend.h +index 5c5d957..ba3ddde 100644 +--- a/src/guestfs-internal-frontend.h ++++ b/src/guestfs-internal-frontend.h +@@ -105,6 +105,7 @@ extern char **guestfs___split_string (char sep, const char *); + extern char *guestfs___exit_status_to_string (int status, const char *cmd_name, char *buffer, size_t buflen); + extern int guestfs___random_string (char *ret, size_t len); + extern char *guestfs___drive_name (size_t index, char *ret); ++extern int guestfs___is_true (const char *str); + + /* 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 be7f643..11c6953 100644 +--- a/src/utils.c ++++ b/src/utils.c +@@ -270,3 +270,26 @@ guestfs___drive_name (size_t index, char *ret) + *ret = '\0'; + return ret; + } ++ ++/* Similar to Tcl_GetBoolean. */ ++int ++guestfs___is_true (const char *str) ++{ ++ if (STREQ (str, "1") || ++ STRCASEEQ (str, "true") || ++ STRCASEEQ (str, "t") || ++ STRCASEEQ (str, "yes") || ++ STRCASEEQ (str, "y") || ++ STRCASEEQ (str, "on")) ++ return 1; ++ ++ if (STREQ (str, "0") || ++ STRCASEEQ (str, "false") || ++ STRCASEEQ (str, "f") || ++ STRCASEEQ (str, "no") || ++ STRCASEEQ (str, "n") || ++ STRCASEEQ (str, "off")) ++ return 0; ++ ++ return -1; ++} +-- +1.8.3.1 + diff --git a/SOURCES/0127-environment-Use-guestfs___is_true-when-parsing-vario.patch b/SOURCES/0127-environment-Use-guestfs___is_true-when-parsing-vario.patch new file mode 100644 index 0000000..aca8466 --- /dev/null +++ b/SOURCES/0127-environment-Use-guestfs___is_true-when-parsing-vario.patch @@ -0,0 +1,188 @@ +From 05105da1347d3d7e9fbc41e0a14b8cd18905b60b Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Wed, 17 Dec 2014 12:52:46 +0000 +Subject: [PATCH] environment: Use guestfs___is_true when parsing various + boolean environment variables (RHBZ#1175196). + +You can now use LIBGUESTFS_DEBUG=true (etc.) + +You can disable debugging/tracing by setting LIBGUESTFS_DEBUG=0 (etc.) + +(cherry picked from commit 5f6677ebd0fd6f6712de808ca27eab4468f966bc) +--- + fuse/test-guestmount-fd.c | 2 +- + src/handle.c | 30 ++++++++++++++++++++------- + tests/charsets/test-charset-fidelity.c | 4 ++-- + tests/mount-local/test-parallel-mount-local.c | 2 +- + tests/parallel/Makefile.am | 1 + + tests/parallel/test-parallel.c | 2 +- + tests/regressions/Makefile.am | 1 + + tests/regressions/rhbz914931.c | 2 +- + 8 files changed, 30 insertions(+), 14 deletions(-) + +diff --git a/fuse/test-guestmount-fd.c b/fuse/test-guestmount-fd.c +index 00eab0c..2b3ce5b 100644 +--- a/fuse/test-guestmount-fd.c ++++ b/fuse/test-guestmount-fd.c +@@ -50,7 +50,7 @@ main (int argc, char *argv[]) + + /* Allow the test to be skipped. */ + skip = getenv ("SKIP_TEST_GUESTMOUNT_FD"); +- if (skip && STREQ (skip, "1")) { ++ if (skip && guestfs___is_true (skip) > 0) { + fprintf (stderr, "%s: test skipped because environment variable set.\n", + program_name); + exit (77); +diff --git a/src/handle.c b/src/handle.c +index 141ba7d..0990082 100644 +--- a/src/handle.c ++++ b/src/handle.c +@@ -176,7 +176,7 @@ parse_environment (guestfs_h *g, + char *(*do_getenv) (const void *data, const char *), + const void *data) + { +- int memsize; ++ int memsize, b; + char *str; + + /* Don't bother checking the return values of functions +@@ -184,12 +184,24 @@ parse_environment (guestfs_h *g, + */ + + str = do_getenv (data, "LIBGUESTFS_TRACE"); +- if (str != NULL && STREQ (str, "1")) +- guestfs_set_trace (g, 1); ++ if (str) { ++ b = guestfs___is_true (str); ++ if (b == -1) { ++ error (g, _("%s=%s: non-boolean value"), "LIBGUESTFS_TRACE", str); ++ return -1; ++ } ++ guestfs_set_trace (g, b); ++ } + + str = do_getenv (data, "LIBGUESTFS_DEBUG"); +- if (str != NULL && STREQ (str, "1")) +- guestfs_set_verbose (g, 1); ++ if (str) { ++ b = guestfs___is_true (str); ++ if (b == -1) { ++ error (g, _("%s=%s: non-boolean value"), "LIBGUESTFS_TRACE", str); ++ return -1; ++ } ++ guestfs_set_verbose (g, b); ++ } + + str = do_getenv (data, "LIBGUESTFS_TMPDIR"); + if (str && STRNEQ (str, "")) { +@@ -816,6 +828,7 @@ int + guestfs___get_backend_setting_bool (guestfs_h *g, const char *name) + { + CLEANUP_FREE char *value = NULL; ++ int b; + + guestfs_push_error_handler (g, NULL, NULL); + value = guestfs_get_backend_setting (g, name); +@@ -827,10 +840,11 @@ guestfs___get_backend_setting_bool (guestfs_h *g, const char *name) + if (value == NULL) + return -1; + +- if (STREQ (value, "1")) +- return 1; ++ b = guestfs___is_true (value); ++ if (b == -1) ++ return -1; + +- return 0; ++ return b; + } + + int +diff --git a/tests/charsets/test-charset-fidelity.c b/tests/charsets/test-charset-fidelity.c +index 4b34b0e..7ce7d94 100644 +--- a/tests/charsets/test-charset-fidelity.c ++++ b/tests/charsets/test-charset-fidelity.c +@@ -81,7 +81,7 @@ main (int argc, char *argv[]) + + /* Allow this test to be skipped. */ + str = getenv (ourenvvar); +- if (str && STREQ (str, "1")) { ++ if (str && guestfs___is_true (str) > 0) { + printf ("%s: test skipped because environment variable is set.\n", + program_name); + exit (77); +@@ -126,7 +126,7 @@ test_filesystem (guestfs_h *g, const struct filesystem *fs) + + snprintf (envvar, sizeof envvar, "%s_%s", ourenvvar, fs->fs_name); + str = getenv (envvar); +- if (str && STREQ (str, "1")) { ++ if (str && guestfs___is_true (str) > 0) { + printf ("skipped test of %s because environment variable is set\n", + fs->fs_name); + return; +diff --git a/tests/mount-local/test-parallel-mount-local.c b/tests/mount-local/test-parallel-mount-local.c +index fa6cd79..88ca2d3 100644 +--- a/tests/mount-local/test-parallel-mount-local.c ++++ b/tests/mount-local/test-parallel-mount-local.c +@@ -94,7 +94,7 @@ main (int argc, char *argv[]) + + /* Allow the test to be skipped by setting an environment variable. */ + skip = getenv ("SKIP_TEST_PARALLEL_MOUNT_LOCAL"); +- if (skip && STREQ (skip, "1")) { ++ if (skip && guestfs___is_true (skip) > 0) { + fprintf (stderr, "%s: test skipped because environment variable set.\n", + program_name); + exit (77); +diff --git a/tests/parallel/Makefile.am b/tests/parallel/Makefile.am +index be63256..9421bfc 100644 +--- a/tests/parallel/Makefile.am ++++ b/tests/parallel/Makefile.am +@@ -34,6 +34,7 @@ test_parallel_CFLAGS = \ + -pthread \ + $(WARN_CFLAGS) $(WERROR_CFLAGS) + test_parallel_LDADD = \ ++ $(top_builddir)/src/libutils.la \ + $(top_builddir)/src/libguestfs.la \ + $(top_builddir)/gnulib/lib/libgnu.la + +diff --git a/tests/parallel/test-parallel.c b/tests/parallel/test-parallel.c +index edd87d9..e412143 100644 +--- a/tests/parallel/test-parallel.c ++++ b/tests/parallel/test-parallel.c +@@ -76,7 +76,7 @@ main (int argc, char *argv[]) + + /* Allow the test to be skipped by setting an environment variable. */ + skip = getenv ("SKIP_TEST_PARALLEL"); +- if (skip && STREQ (skip, "1")) { ++ if (skip && guestfs___is_true (skip) > 0) { + fprintf (stderr, "%s: test skipped because environment variable set.\n", + program_name); + exit (77); +diff --git a/tests/regressions/Makefile.am b/tests/regressions/Makefile.am +index a5e7cfc..de97526 100644 +--- a/tests/regressions/Makefile.am ++++ b/tests/regressions/Makefile.am +@@ -111,6 +111,7 @@ rhbz914931_CFLAGS = \ + -pthread \ + $(WARN_CFLAGS) $(WERROR_CFLAGS) + rhbz914931_LDADD = \ ++ $(top_builddir)/src/libutils.la \ + $(top_builddir)/src/libguestfs.la + + rhbz1055452_SOURCES = rhbz1055452.c +diff --git a/tests/regressions/rhbz914931.c b/tests/regressions/rhbz914931.c +index faa3dd2..569e261 100644 +--- a/tests/regressions/rhbz914931.c ++++ b/tests/regressions/rhbz914931.c +@@ -41,7 +41,7 @@ main (int argc, char *argv[]) + + /* Allow this test to be skipped. */ + str = getenv ("SKIP_TEST_RHBZ914931"); +- if (str && STREQ (str, "1")) { ++ if (str && guestfs___is_true (str) > 0) { + printf ("%s: test skipped because environment variable is set.\n", + program_name); + exit (77); +-- +1.8.3.1 + diff --git a/SOURCES/0128-fish-Add-regression-test-for-RHBZ-1175196.patch b/SOURCES/0128-fish-Add-regression-test-for-RHBZ-1175196.patch new file mode 100644 index 0000000..2a495fc --- /dev/null +++ b/SOURCES/0128-fish-Add-regression-test-for-RHBZ-1175196.patch @@ -0,0 +1,105 @@ +From f724608f41122c82c2deb7a1e66f51fb053080c0 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Wed, 17 Dec 2014 13:02:06 +0000 +Subject: [PATCH] fish: Add regression test for RHBZ#1175196. + +(cherry picked from commit f1ecd6af808f22af913a589754ae11dc1e35b658) +--- + tests/regressions/Makefile.am | 2 ++ + tests/regressions/rhbz1175196.sh | 64 ++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 66 insertions(+) + create mode 100755 tests/regressions/rhbz1175196.sh + +diff --git a/tests/regressions/Makefile.am b/tests/regressions/Makefile.am +index de97526..72d26da 100644 +--- a/tests/regressions/Makefile.am ++++ b/tests/regressions/Makefile.am +@@ -42,6 +42,7 @@ EXTRA_DIST = \ + rhbz1044014.xml \ + rhbz1054761.sh \ + rhbz1091803.sh \ ++ rhbz1175196.sh \ + test-noexec-stack.pl + + TESTS = \ +@@ -66,6 +67,7 @@ TESTS = \ + rhbz1054761.sh \ + rhbz1055452 \ + rhbz1091803.sh \ ++ rhbz1175196.sh \ + test-noexec-stack.pl + + if HAVE_LIBVIRT +diff --git a/tests/regressions/rhbz1175196.sh b/tests/regressions/rhbz1175196.sh +new file mode 100755 +index 0000000..e88f447 +--- /dev/null ++++ b/tests/regressions/rhbz1175196.sh +@@ -0,0 +1,64 @@ ++#!/bin/bash - ++# 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. ++ ++# Regression test for: ++# https://bugzilla.redhat.com/show_bug.cgi?id=1175196 ++# Parse 'LIBGUESTFS_TRACE=0' in the environment. ++ ++set -e ++export LANG=C ++ ++output="$(guestfish < +Date: Thu, 18 Dec 2014 10:59:15 +0000 +Subject: [PATCH] ping-daemon: Fix error in the description of this API + (RHBZ#1175676). + +Thanks: Lingfei Kong +(cherry picked from commit f6e74ecd73d9aeeb4c9ef0044d7112645b09172f) +--- + generator/actions.ml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/generator/actions.ml b/generator/actions.ml +index 263c6f3..c7a1777 100644 +--- a/generator/actions.ml ++++ b/generator/actions.ml +@@ -5273,7 +5273,7 @@ running the program." }; + shortdesc = "ping the guest daemon"; + longdesc = "\ + This is a test probe into the guestfs daemon running inside +-the hypervisor. Calling this function checks that the ++the libguestfs appliance. Calling this function checks that the + daemon responds to the ping message, without affecting the daemon + or attached block device(s) in any other way." }; + +-- +1.8.3.1 + diff --git a/SOURCES/0130-filearch-move-libmagic-code-in-an-own-function.patch b/SOURCES/0130-filearch-move-libmagic-code-in-an-own-function.patch new file mode 100644 index 0000000..828b166 --- /dev/null +++ b/SOURCES/0130-filearch-move-libmagic-code-in-an-own-function.patch @@ -0,0 +1,144 @@ +From 45209466afa76eb93f5c27028c9b5c5e6ea4f572 Mon Sep 17 00:00:00 2001 +From: Pino Toscano +Date: Mon, 13 Apr 2015 11:18:46 +0200 +Subject: [PATCH] filearch: move libmagic code in an own function + +Also use a cleanup attribue to ease the close of the magic_t handle. + +This is mostly code motion, hopefully with no actual behaviour changes. + +(cherry picked from commit 20acc1f124a3f3af365c27b7654bead5beb1ef4c) +--- + src/filearch.c | 100 +++++++++++++++++++++++++++++++++++++++------------------ + 1 file changed, 68 insertions(+), 32 deletions(-) + +diff --git a/src/filearch.c b/src/filearch.c +index c0380d9..e851279 100644 +--- a/src/filearch.c ++++ b/src/filearch.c +@@ -74,6 +74,22 @@ free_regexps (void) + pcre_free (re_elf_ppc64); + } + ++# ifdef HAVE_ATTRIBUTE_CLEANUP ++# define CLEANUP_MAGIC_T_FREE __attribute__((cleanup(cleanup_magic_t_free))) ++ ++static void ++cleanup_magic_t_free (void *ptr) ++{ ++ magic_t m = *(magic_t *) ptr; ++ ++ if (m) ++ magic_close (m); ++} ++ ++# else ++# define CLEANUP_MAGIC_T_FREE ++# endif ++ + /* Convert output from 'file' command on ELF files to the canonical + * architecture string. Caller must free the result. + */ +@@ -120,6 +136,55 @@ is_regular_file (const char *filename) + return lstat (filename, &statbuf) == 0 && S_ISREG (statbuf.st_mode); + } + ++static char * ++magic_for_file (guestfs_h *g, const char *filename, bool *loading_ok, ++ bool *matched) ++{ ++ int flags; ++ CLEANUP_MAGIC_T_FREE magic_t m = NULL; ++ const char *line; ++ char *elf_arch; ++ ++ flags = g->verbose ? MAGIC_DEBUG : 0; ++ flags |= MAGIC_ERROR | MAGIC_RAW; ++ ++ if (loading_ok) ++ *loading_ok = false; ++ if (matched) ++ *matched = false; ++ ++ m = magic_open (flags); ++ if (m == NULL) { ++ perrorf (g, "magic_open"); ++ return NULL; ++ } ++ ++ if (magic_load (m, NULL) == -1) { ++ perrorf (g, "magic_load: default magic database file"); ++ return NULL; ++ } ++ ++ line = magic_file (m, filename); ++ if (line == NULL) { ++ perrorf (g, "magic_file: %s", filename); ++ return NULL; ++ } ++ ++ if (loading_ok) ++ *loading_ok = true; ++ ++ elf_arch = match1 (g, line, re_file_elf); ++ if (elf_arch == NULL) { ++ error (g, "no re_file_elf match in '%s'", line); ++ return NULL; ++ } ++ ++ if (matched) ++ *matched = true; ++ ++ return canonical_elf_arch (g, elf_arch); ++} ++ + /* Download and uncompress the cpio file to find binaries within. */ + static const char *initrd_binaries[] = { + "bin/ls", +@@ -198,40 +263,11 @@ cpio_arch (guestfs_h *g, const char *file, const char *path) + safe_asprintf (g, "%s/%s", dir, initrd_binaries[i]); + + if (is_regular_file (bin)) { +- int flags; +- magic_t m; +- const char *line; +- CLEANUP_FREE char *elf_arch = NULL; ++ bool loading_ok, matched; + +- flags = g->verbose ? MAGIC_DEBUG : 0; +- flags |= MAGIC_ERROR | MAGIC_RAW; +- +- m = magic_open (flags); +- if (m == NULL) { +- perrorf (g, "magic_open"); +- goto out; +- } +- +- if (magic_load (m, NULL) == -1) { +- perrorf (g, "magic_load: default magic database file"); +- magic_close (m); +- goto out; +- } +- +- line = magic_file (m, bin); +- if (line == NULL) { +- perrorf (g, "magic_file: %s", bin); +- magic_close (m); +- goto out; +- } +- +- elf_arch = match1 (g, line, re_file_elf); +- if (elf_arch != NULL) { +- ret = canonical_elf_arch (g, elf_arch); +- magic_close (m); ++ ret = magic_for_file (g, bin, &loading_ok, &matched); ++ if (!loading_ok || matched) + goto out; +- } +- magic_close (m); + } + } + error (g, "file_architecture: could not determine architecture of cpio archive"); +-- +1.8.3.1 + diff --git a/SOURCES/0131-v2v-Reduce-use-of-polymorphic-variants.patch b/SOURCES/0131-v2v-Reduce-use-of-polymorphic-variants.patch new file mode 100644 index 0000000..0d7fb53 --- /dev/null +++ b/SOURCES/0131-v2v-Reduce-use-of-polymorphic-variants.patch @@ -0,0 +1,274 @@ +From a71e0ff19b9cbb8942fbeacecd317ba888452b16 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Wed, 24 Dec 2014 18:10:37 +0000 +Subject: [PATCH] v2v: Reduce use of polymorphic variants. + +Ordinary variants prevent coding errors. + +(cherry picked from commit 3a080c3fbffa5846f71528c6fd978be7853b33b8) +--- + v2v/convert_linux.ml | 6 +++--- + v2v/input_disk.ml | 2 +- + v2v/input_libvirtxml.ml | 20 ++++++++++---------- + v2v/input_ova.ml | 8 ++++---- + v2v/output_libvirt.ml | 4 ++-- + v2v/output_qemu.ml | 6 +++--- + v2v/types.ml | 18 ++++++++++-------- + v2v/types.mli | 13 ++++++++----- + 8 files changed, 41 insertions(+), 36 deletions(-) + +diff --git a/v2v/convert_linux.ml b/v2v/convert_linux.ml +index 67de2b1..718ddaf 100644 +--- a/v2v/convert_linux.ml ++++ b/v2v/convert_linux.ml +@@ -1269,9 +1269,9 @@ let rec convert ~verbose ~keep_serial_console (g : G.guestfs) inspect source = + fun i disk -> + let block_prefix_before_conversion = + match disk.s_controller with +- | Some `IDE -> ide_block_prefix +- | Some `SCSI -> "sd" +- | Some `Virtio_blk -> "vd" ++ | Some Source_IDE -> ide_block_prefix ++ | Some Source_SCSI -> "sd" ++ | Some Source_virtio_blk -> "vd" + | None -> + (* This is basically a guess. It assumes the source used IDE. *) + ide_block_prefix in +diff --git a/v2v/input_disk.ml b/v2v/input_disk.ml +index 8393786..98b321c 100644 +--- a/v2v/input_disk.ml ++++ b/v2v/input_disk.ml +@@ -86,7 +86,7 @@ class input_disk verbose input_format disk = object + s_vcpu = 1; (* 1 vCPU is a safe default *) + s_features = [ "acpi"; "apic"; "pae" ]; + s_display = +- Some { s_display_type = `Window; s_keymap = None; s_password = None }; ++ Some { s_display_type = Window; s_keymap = None; s_password = None }; + s_disks = [disk]; + s_removables = []; + s_nics = [network]; +diff --git a/v2v/input_libvirtxml.ml b/v2v/input_libvirtxml.ml +index d1146f9..8057a00 100644 +--- a/v2v/input_libvirtxml.ml ++++ b/v2v/input_libvirtxml.ml +@@ -96,10 +96,10 @@ let parse_libvirt_xml ~verbose xml = + match xpath_to_string "@type" "" with + | "" -> None + | "vnc" -> +- Some { s_display_type = `VNC; ++ Some { s_display_type = VNC; + s_keymap = keymap; s_password = password } + | "spice" -> +- Some { s_display_type = `Spice; ++ Some { s_display_type = Spice; + s_keymap = keymap; s_password = password } + | "sdl"|"desktop" as t -> + warning ~prog (f_"virt-v2v does not support local displays, so in the input libvirt XML was ignored") t; +@@ -138,9 +138,9 @@ let parse_libvirt_xml ~verbose xml = + let target_bus = xpath_to_string "target/@bus" "" in + match target_bus with + | "" -> None +- | "ide" -> Some `IDE +- | "scsi" -> Some `SCSI +- | "virtio" -> Some `Virtio_blk ++ | "ide" -> Some Source_IDE ++ | "scsi" -> Some Source_SCSI ++ | "virtio" -> Some Source_virtio_blk + | _ -> None in + + let format = +@@ -202,15 +202,15 @@ let parse_libvirt_xml ~verbose xml = + let target_bus = xpath_to_string "target/@bus" "" in + match target_bus with + | "" -> None +- | "ide" -> Some `IDE +- | "scsi" -> Some `SCSI +- | "virtio" -> Some `Virtio_blk ++ | "ide" -> Some Source_IDE ++ | "scsi" -> Some Source_SCSI ++ | "virtio" -> Some Source_virtio_blk + | _ -> None in + + let typ = + match xpath_to_string "@device" "" with +- | "cdrom" -> `CDROM +- | "floppy" -> `Floppy ++ | "cdrom" -> CDROM ++ | "floppy" -> Floppy + | _ -> assert false (* libxml2 error? *) in + + let disk = +diff --git a/v2v/input_ova.ml b/v2v/input_ova.ml +index e2a1243..211db43 100644 +--- a/v2v/input_ova.ml ++++ b/v2v/input_ova.ml +@@ -167,8 +167,8 @@ object + + (* 6: iscsi controller, 5: ide *) + match controller with +- | 6 -> Some `SCSI +- | 5 -> Some `IDE ++ | 6 -> Some Source_SCSI ++ | 5 -> Some Source_IDE + | 0 -> + warning ~prog (f_"ova disk has no parent controller, please report this as a bug supplying the *.ovf file extracted from the ova"); + None +@@ -272,8 +272,8 @@ object + + let typ = + match id with +- | 14 -> `Floppy +- | 15 | 16 -> `CDROM ++ | 14 -> Floppy ++ | 15 | 16 -> CDROM + | _ -> assert false in + let disk = { + s_removable_type = typ; +diff --git a/v2v/output_libvirt.ml b/v2v/output_libvirt.ml +index 7f9a3a0..f4e480a 100644 +--- a/v2v/output_libvirt.ml ++++ b/v2v/output_libvirt.ml +@@ -164,7 +164,7 @@ let create_libvirt_xml ?pool source targets guestcaps target_features = + + List.map ( + function +- | { s_removable_type = `CDROM } -> ++ | { s_removable_type = CDROM } -> + let i = !cdrom_index in + incr cdrom_index; + let name = cdrom_block_prefix ^ drive_name i in +@@ -173,7 +173,7 @@ let create_libvirt_xml ?pool source targets guestcaps target_features = + e "target" [ "dev", name; "bus", cdrom_bus ] [] + ] + +- | { s_removable_type = `Floppy } -> ++ | { s_removable_type = Floppy } -> + let i = !fd_index in + incr fd_index; + let name = "fd" ^ drive_name i in +diff --git a/v2v/output_qemu.ml b/v2v/output_qemu.ml +index 9c17121..4b1d69a 100644 +--- a/v2v/output_qemu.ml ++++ b/v2v/output_qemu.ml +@@ -90,11 +90,11 @@ object + | None -> () + | Some display -> + (match display.s_display_type with +- | `Window -> ++ | Window -> + fpf "%s-display gtk" nl +- | `VNC -> ++ | VNC -> + fpf "%s-display vnc=:0" nl +- | `Spice -> ++ | Spice -> + fpf "%s-spice port=5900,addr=127.0.0.1" nl + ); + fpf "%s-vga %s" nl +diff --git a/v2v/types.ml b/v2v/types.ml +index 28d62fc..97120c2 100644 +--- a/v2v/types.ml ++++ b/v2v/types.ml +@@ -38,11 +38,12 @@ and source_disk = { + s_format : string option; + s_controller : s_controller option; + } +-and s_controller = [`IDE | `SCSI | `Virtio_blk] ++and s_controller = Source_IDE | Source_SCSI | Source_virtio_blk + and source_removable = { +- s_removable_type : [`CDROM|`Floppy]; ++ s_removable_type : s_removable_type; + s_removable_controller : s_controller option; + } ++and s_removable_type = CDROM | Floppy + and source_nic = { + s_mac : string option; + s_vnet : string; +@@ -51,10 +52,11 @@ and source_nic = { + } + and vnet_type = Bridge | Network + and source_display = { +- s_display_type : [`Window|`VNC|`Spice]; ++ s_display_type : s_display_type; + s_keymap : string option; + s_password : string option; + } ++and s_display_type = Window | VNC | Spice + + let rec string_of_source s = + sprintf " source name: %s +@@ -94,14 +96,14 @@ and string_of_source_disk { s_qemu_uri = qemu_uri; s_format = format; + | Some controller -> " [" ^ string_of_controller controller ^ "]") + + and string_of_controller = function +- | `IDE -> "ide" +- | `SCSI -> "scsi" +- | `Virtio_blk -> "virtio" ++ | Source_IDE -> "ide" ++ | Source_SCSI -> "scsi" ++ | Source_virtio_blk -> "virtio" + + and string_of_source_removable { s_removable_type = typ; + s_removable_controller = controller } = + sprintf "\t%s%s" +- (match typ with `CDROM -> "CD-ROM" | `Floppy -> "Floppy") ++ (match typ with CDROM -> "CD-ROM" | Floppy -> "Floppy") + (match controller with + | None -> "" + | Some controller -> " [" ^ string_of_controller controller ^ "]") +@@ -117,7 +119,7 @@ and string_of_source_nic { s_mac = mac; s_vnet = vnet; s_vnet_type = typ } = + and string_of_source_display { s_display_type = typ; + s_keymap = keymap; s_password = password } = + sprintf "%s%s%s" +- (match typ with `Window -> "window" | `VNC -> "vnc" | `Spice -> "spice") ++ (match typ with Window -> "window" | VNC -> "vnc" | Spice -> "spice") + (match keymap with None -> "" | Some km -> " " ^ km) + (match password with None -> "" | Some _ -> " with password") + +diff --git a/v2v/types.mli b/v2v/types.mli +index 07eec98..3d65596 100644 +--- a/v2v/types.mli ++++ b/v2v/types.mli +@@ -42,19 +42,21 @@ and source_disk = { + } + (** A source disk. *) + +-and s_controller = [`IDE | `SCSI | `Virtio_blk] ++and s_controller = Source_IDE | Source_SCSI | Source_virtio_blk + (** Source disk controller. + + For the purposes of this field, we can treat virtio-scsi as +- [`SCSI]. However we don't support conversions from virtio in any ++ [SCSI]. However we don't support conversions from virtio in any + case so virtio is here only to make it work for testing. *) + + and source_removable = { +- s_removable_type : [`CDROM|`Floppy]; (** Type. *) ++ s_removable_type : s_removable_type; (** Type. *) + s_removable_controller : s_controller option; (** Controller, eg. IDE, SCSI.*) + } + (** Removable media. *) + ++and s_removable_type = CDROM | Floppy ++ + and source_nic = { + s_mac : string option; (** MAC address. *) + s_vnet : string; (** Source network name. *) +@@ -65,11 +67,12 @@ and source_nic = { + and vnet_type = Bridge | Network + + and source_display = { +- s_display_type : [`Window|`VNC|`Spice]; (** Display type. *) +- s_keymap : string option; (** Guest keymap. *) ++ s_display_type : s_display_type; (** Display type. *) ++ s_keymap : string option; (** Guest keymap. *) + s_password : string option; (** If required, password to access + the display. *) + } ++and s_display_type = Window | VNC | Spice + + val string_of_source : source -> string + val string_of_source_disk : source_disk -> string +-- +1.8.3.1 + diff --git a/SOURCES/0132-v2v-convert-libvirt-display-listen-configuration-RHB.patch b/SOURCES/0132-v2v-convert-libvirt-display-listen-configuration-RHB.patch new file mode 100644 index 0000000..7a2454c --- /dev/null +++ b/SOURCES/0132-v2v-convert-libvirt-display-listen-configuration-RHB.patch @@ -0,0 +1,156 @@ +From 04426a61a5dc72dbaaee666c94398371bd385f76 Mon Sep 17 00:00:00 2001 +From: Pino Toscano +Date: Tue, 14 Apr 2015 10:38:54 +0200 +Subject: [PATCH] v2v: convert libvirt display listen configuration + (RHBZ#1174073) + +Read the listen configuration from the XML of libvirt domains, restoring +it when writing new libvirt XMLs. + +(cherry picked from commit 9360675dc244a8762e07a8a4289e7a30ca3e1eef) +--- + v2v/input_disk.ml | 3 ++- + v2v/input_libvirtxml.ml | 26 ++++++++++++++++++++++++-- + v2v/output_libvirt.ml | 11 +++++++++++ + v2v/types.ml | 15 +++++++++++++-- + v2v/types.mli | 5 +++++ + 5 files changed, 55 insertions(+), 5 deletions(-) + +diff --git a/v2v/input_disk.ml b/v2v/input_disk.ml +index 98b321c..e5a07b4 100644 +--- a/v2v/input_disk.ml ++++ b/v2v/input_disk.ml +@@ -86,7 +86,8 @@ class input_disk verbose input_format disk = object + s_vcpu = 1; (* 1 vCPU is a safe default *) + s_features = [ "acpi"; "apic"; "pae" ]; + s_display = +- Some { s_display_type = Window; s_keymap = None; s_password = None }; ++ Some { s_display_type = Window; s_keymap = None; s_password = None; ++ s_listen = LNone }; + s_disks = [disk]; + s_removables = []; + s_nics = [network]; +diff --git a/v2v/input_libvirtxml.ml b/v2v/input_libvirtxml.ml +index 8057a00..037405c 100644 +--- a/v2v/input_libvirtxml.ml ++++ b/v2v/input_libvirtxml.ml +@@ -93,14 +93,36 @@ let parse_libvirt_xml ~verbose xml = + match xpath_to_string "@keymap" "" with "" -> None | k -> Some k in + let password = + match xpath_to_string "@passwd" "" with "" -> None | pw -> Some pw in ++ let listen = ++ let obj = Xml.xpath_eval_expression xpathctx "listen" in ++ let nr_nodes = Xml.xpathobj_nr_nodes obj in ++ if nr_nodes < 1 then LNone ++ else ( ++ (* Use only the first configuration. *) ++ match xpath_to_string "listen[1]/@type" "" with ++ | "" -> LNone ++ | "address" -> ++ (match xpath_to_string "listen[1]/@address" "" with ++ | "" -> LNone ++ | a -> LAddress a ++ ) ++ | "network" -> ++ (match xpath_to_string "listen[1]/@network" "" with ++ | "" -> LNone ++ | n -> LNetwork n ++ ) ++ | t -> ++ warning ~prog (f_" in the input libvirt XML was ignored") t; ++ LNone ++ ) in + match xpath_to_string "@type" "" with + | "" -> None + | "vnc" -> + Some { s_display_type = VNC; +- s_keymap = keymap; s_password = password } ++ s_keymap = keymap; s_password = password; s_listen = listen } + | "spice" -> + Some { s_display_type = Spice; +- s_keymap = keymap; s_password = password } ++ s_keymap = keymap; s_password = password; s_listen = listen } + | "sdl"|"desktop" as t -> + warning ~prog (f_"virt-v2v does not support local displays, so in the input libvirt XML was ignored") t; + None +diff --git a/v2v/output_libvirt.ml b/v2v/output_libvirt.ml +index f4e480a..118d4a4 100644 +--- a/v2v/output_libvirt.ml ++++ b/v2v/output_libvirt.ml +@@ -237,6 +237,17 @@ let create_libvirt_xml ?pool source targets guestcaps target_features = + (match source.s_display with + | Some { s_password = Some pw } -> append_attr ("passwd", pw) graphics + | _ -> ()); ++ (match source.s_display with ++ | Some { s_listen = listen } -> ++ (match listen with ++ | LAddress a -> ++ let sub = e "listen" [ "type", "address"; "address", a ] [] in ++ append_child sub graphics ++ | LNetwork n -> ++ let sub = e "listen" [ "type", "network"; "network", n ] [] in ++ append_child sub graphics ++ | LNone -> ()) ++ | _ -> ()); + + video, graphics in + +diff --git a/v2v/types.ml b/v2v/types.ml +index 97120c2..e8ee288 100644 +--- a/v2v/types.ml ++++ b/v2v/types.ml +@@ -55,8 +55,13 @@ and source_display = { + s_display_type : s_display_type; + s_keymap : string option; + s_password : string option; ++ s_listen : s_display_listen; + } + and s_display_type = Window | VNC | Spice ++and s_display_listen = ++ | LNone ++ | LAddress of string ++ | LNetwork of string + + let rec string_of_source s = + sprintf " source name: %s +@@ -117,11 +122,17 @@ and string_of_source_nic { s_mac = mac; s_vnet = vnet; s_vnet_type = typ } = + | Some mac -> " mac: " ^ mac) + + and string_of_source_display { s_display_type = typ; +- s_keymap = keymap; s_password = password } = +- sprintf "%s%s%s" ++ s_keymap = keymap; s_password = password; ++ s_listen = listen } = ++ sprintf "%s%s%s%s" + (match typ with Window -> "window" | VNC -> "vnc" | Spice -> "spice") + (match keymap with None -> "" | Some km -> " " ^ km) + (match password with None -> "" | Some _ -> " with password") ++ (match listen with ++ | LNone -> "" ++ | LAddress a -> sprintf " listening on address %s" a ++ | LNetwork n -> sprintf " listening on network %s" n ++ ) + + type overlay = { + ov_overlay_file : string; +diff --git a/v2v/types.mli b/v2v/types.mli +index 3d65596..e1aa6f9 100644 +--- a/v2v/types.mli ++++ b/v2v/types.mli +@@ -71,8 +71,13 @@ and source_display = { + s_keymap : string option; (** Guest keymap. *) + s_password : string option; (** If required, password to access + the display. *) ++ s_listen : s_display_listen; (** Listen address. *) + } + and s_display_type = Window | VNC | Spice ++and s_display_listen = ++ | LNone ++ | LAddress of string (** Listen address. *) ++ | LNetwork of string (** Listen network. *) + + val string_of_source : source -> string + val string_of_source_disk : source_disk -> string +-- +1.8.3.1 + diff --git a/SOURCES/0133-filearch-support-gzip-xz-compressed-files.patch b/SOURCES/0133-filearch-support-gzip-xz-compressed-files.patch new file mode 100644 index 0000000..7d8f5dc --- /dev/null +++ b/SOURCES/0133-filearch-support-gzip-xz-compressed-files.patch @@ -0,0 +1,172 @@ +From 525a1da911aaccb8587ec4d1b095b2be30f63f90 Mon Sep 17 00:00:00 2001 +From: Pino Toscano +Date: Tue, 14 Apr 2015 11:07:57 +0200 +Subject: [PATCH] filearch: support gzip/xz-compressed files + +Extract them to find out the architecture of the data they hold. +Useful to detect the architecture of e.g. compressed Linux modules. + +Provide in the test.iso two samples (compressing existing test data) of +binaries compressed with gzip and xz. + +(cherry picked from commit 7291b226d1b08c762ae2f2715a2ac9ed7b8d5d14) +--- + .gitignore | 2 ++ + generator/actions.ml | 4 ++++ + src/filearch.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++ + tests/data/Makefile.am | 12 ++++++++++ + 4 files changed, 82 insertions(+) + +diff --git a/.gitignore b/.gitignore +index 269d735..267caa9 100644 +--- a/.gitignore ++++ b/.gitignore +@@ -502,12 +502,14 @@ Makefile.in + /tests/data/100krandom + /tests/data/10klines + /tests/data/abssymlink ++/tests/data/bin-x86_64-dynamic.gz + /tests/data/blank-disk-* + /tests/data/blank-disk-* + /tests/data/hello.b64 + /tests/data/initrd + /tests/data/initrd-x86_64.img + /tests/data/initrd-x86_64.img.gz ++/tests/data/lib-i586.so.xz + /tests/data/test-grep.txt.gz + /tests/data/test.iso + /tests/disks/test-qemu-drive-libvirt.xml +diff --git a/generator/actions.ml b/generator/actions.ml +index c7a1777..ca0208b 100644 +--- a/generator/actions.ml ++++ b/generator/actions.ml +@@ -813,6 +813,10 @@ to specify the QEMU interface emulation to use at run time." }; + [["file_architecture"; "/initrd-x86_64.img"]], "x86_64"), []; + InitISOFS, Always, TestResultString ( + [["file_architecture"; "/initrd-x86_64.img.gz"]], "x86_64"), []; ++ InitISOFS, Always, TestResultString ( ++ [["file_architecture"; "/bin-x86_64-dynamic.gz"]], "x86_64"), []; ++ InitISOFS, Always, TestResultString ( ++ [["file_architecture"; "/lib-i586.so.xz"]], "i386"), []; + ]; + shortdesc = "detect the architecture of a binary file"; + longdesc = "\ +diff --git a/src/filearch.c b/src/filearch.c +index e851279..40e2225 100644 +--- a/src/filearch.c ++++ b/src/filearch.c +@@ -278,6 +278,66 @@ cpio_arch (guestfs_h *g, const char *file, const char *path) + return ret; + } + ++static char * ++compressed_file_arch (guestfs_h *g, const char *path, const char *method) ++{ ++ CLEANUP_FREE char *tmpdir = guestfs_get_tmpdir (g), *dir = NULL; ++ CLEANUP_FREE char *tempfile = NULL, *tempfile_extracted = NULL; ++ CLEANUP_CMD_CLOSE struct command *cmd = guestfs_int_new_command (g); ++ char *ret = NULL; ++ int64_t size; ++ int r; ++ bool matched; ++ ++ if (asprintf (&dir, "%s/libguestfsXXXXXX", tmpdir) == -1) { ++ perrorf (g, "asprintf"); ++ return NULL; ++ } ++ ++ /* Security: Refuse to download file if it is huge. */ ++ size = guestfs_filesize (g, path); ++ if (size == -1 || size > 10000000) { ++ error (g, _("size of %s unreasonable (%" PRIi64 " bytes)"), ++ path, size); ++ goto out; ++ } ++ ++ if (mkdtemp (dir) == NULL) { ++ perrorf (g, "mkdtemp"); ++ goto out; ++ } ++ ++ tempfile = safe_asprintf (g, "%s/file", dir); ++ if (guestfs_download (g, path, tempfile) == -1) ++ goto out; ++ ++ tempfile_extracted = safe_asprintf (g, "%s/file_extracted", dir); ++ ++ /* Construct a command to extract named binaries from the initrd file. */ ++ guestfs_int_cmd_add_string_unquoted (cmd, method); ++ guestfs_int_cmd_add_string_unquoted (cmd, " "); ++ guestfs_int_cmd_add_string_quoted (cmd, tempfile); ++ guestfs_int_cmd_add_string_unquoted (cmd, " > "); ++ guestfs_int_cmd_add_string_quoted (cmd, tempfile_extracted); ++ ++ r = guestfs_int_cmd_run (cmd); ++ if (r == -1) ++ goto out; ++ if (!WIFEXITED (r) || WEXITSTATUS (r) != 0) { ++ guestfs_int_external_command_failed (g, r, method, path); ++ goto out; ++ } ++ ++ ret = magic_for_file (g, tempfile_extracted, NULL, &matched); ++ if (!matched) ++ error (g, "file_architecture: could not determine architecture of compressed file"); ++ ++ out: ++ guestfs_int_recursive_remove_dir (g, dir); ++ ++ return ret; ++} ++ + char * + guestfs__file_architecture (guestfs_h *g, const char *path) + { +@@ -300,6 +360,10 @@ guestfs__file_architecture (guestfs_h *g, const char *path) + ret = safe_strdup (g, "x86_64"); + else if (strstr (file, "cpio archive")) + ret = cpio_arch (g, file, path); ++ else if (strstr (file, "gzip compressed data")) ++ ret = compressed_file_arch (g, path, "zcat"); ++ else if (strstr (file, "XZ compressed data")) ++ ret = compressed_file_arch (g, path, "xzcat"); + else + error (g, "file_architecture: unknown architecture: %s", path); + +diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am +index 3127787..7e0d66a 100644 +--- a/tests/data/Makefile.am ++++ b/tests/data/Makefile.am +@@ -76,6 +76,7 @@ images_files_build = \ + 100kallspaces \ + 100krandom \ + 10klines \ ++ bin-x86_64-dynamic.gz \ + blank-disk-1s.raw \ + blank-disk-1s.qcow2 \ + blank-disk-1K.raw \ +@@ -87,6 +88,7 @@ images_files_build = \ + initrd \ + initrd-x86_64.img \ + initrd-x86_64.img.gz \ ++ lib-i586.so.xz \ + test-grep.txt.gz + + check_DATA = $(images_files_build) test.iso +@@ -193,3 +195,13 @@ test-grep.txt.gz: test-grep.txt + rm -f $@ $@-t + gzip --best -c $< > $@-t + mv $@-t $@ ++ ++bin-x86_64-dynamic.gz: bin-x86_64-dynamic ++ rm -f $@ $@-t ++ gzip --best -c $< > $@-t ++ mv $@-t $@ ++ ++lib-i586.so.xz: lib-i586.so ++ rm -f $@ $@-t ++ xz -c $< > $@-t ++ mv $@-t $@ +-- +1.8.3.1 + diff --git a/SOURCES/0134-v2v-convert-libvirt-display-port-configuration.patch b/SOURCES/0134-v2v-convert-libvirt-display-port-configuration.patch new file mode 100644 index 0000000..7bfe846 --- /dev/null +++ b/SOURCES/0134-v2v-convert-libvirt-display-port-configuration.patch @@ -0,0 +1,129 @@ +From bbafb02ae131fbe920886e7685ccd2b156af87e9 Mon Sep 17 00:00:00 2001 +From: Pino Toscano +Date: Tue, 14 Apr 2015 13:22:10 +0200 +Subject: [PATCH] v2v: convert libvirt display port configuration + +Read the port configuration from the XML of libvirt domains, restoring +it when writing new libvirt XMLs instead of always setting the +"autoport" option. + +(cherry picked from commit 1db249a0cc21c65e0d3192567b6016745cea7e58) +--- + v2v/input_disk.ml | 2 +- + v2v/input_libvirtxml.ml | 13 +++++++++++-- + v2v/output_libvirt.ml | 8 +++++++- + v2v/output_qemu.ml | 3 ++- + v2v/types.ml | 1 + + v2v/types.mli | 1 + + 6 files changed, 23 insertions(+), 5 deletions(-) + +diff --git a/v2v/input_disk.ml b/v2v/input_disk.ml +index e5a07b4..54e0bbe 100644 +--- a/v2v/input_disk.ml ++++ b/v2v/input_disk.ml +@@ -87,7 +87,7 @@ class input_disk verbose input_format disk = object + s_features = [ "acpi"; "apic"; "pae" ]; + s_display = + Some { s_display_type = Window; s_keymap = None; s_password = None; +- s_listen = LNone }; ++ s_listen = LNone; s_port = None }; + s_disks = [disk]; + s_removables = []; + s_nics = [network]; +diff --git a/v2v/input_libvirtxml.ml b/v2v/input_libvirtxml.ml +index 037405c..34f1bd1 100644 +--- a/v2v/input_libvirtxml.ml ++++ b/v2v/input_libvirtxml.ml +@@ -115,14 +115,23 @@ let parse_libvirt_xml ~verbose xml = + warning ~prog (f_" in the input libvirt XML was ignored") t; + LNone + ) in ++ let port = ++ match xpath_to_string "@autoport" "yes" with ++ | "no" -> ++ let port = xpath_to_int "@port" (-1) in ++ if port >= 0 then Some port ++ else None ++ | _ -> None in + match xpath_to_string "@type" "" with + | "" -> None + | "vnc" -> + Some { s_display_type = VNC; +- s_keymap = keymap; s_password = password; s_listen = listen } ++ s_keymap = keymap; s_password = password; s_listen = listen; ++ s_port = port } + | "spice" -> + Some { s_display_type = Spice; +- s_keymap = keymap; s_password = password; s_listen = listen } ++ s_keymap = keymap; s_password = password; s_listen = listen; ++ s_port = port } + | "sdl"|"desktop" as t -> + warning ~prog (f_"virt-v2v does not support local displays, so in the input libvirt XML was ignored") t; + None +diff --git a/v2v/output_libvirt.ml b/v2v/output_libvirt.ml +index 118d4a4..dee432d 100644 +--- a/v2v/output_libvirt.ml ++++ b/v2v/output_libvirt.ml +@@ -230,7 +230,6 @@ let create_libvirt_xml ?pool source targets guestcaps target_features = + + append_attr ("heads", "1") video; + +- append_attr ("autoport", "yes") graphics; + (match source.s_display with + | Some { s_keymap = Some km } -> append_attr ("keymap", km) graphics + | _ -> ()); +@@ -248,6 +247,13 @@ let create_libvirt_xml ?pool source targets guestcaps target_features = + append_child sub graphics + | LNone -> ()) + | _ -> ()); ++ (match source.s_display with ++ | Some { s_port = Some p } -> ++ append_attr ("autoport", "no") graphics; ++ append_attr ("port", string_of_int p) graphics ++ | _ -> ++ append_attr ("autoport", "yes") graphics; ++ append_attr ("port", "-1") graphics); + + video, graphics in + +diff --git a/v2v/output_qemu.ml b/v2v/output_qemu.ml +index 4b1d69a..860e1bf 100644 +--- a/v2v/output_qemu.ml ++++ b/v2v/output_qemu.ml +@@ -95,7 +95,8 @@ object + | VNC -> + fpf "%s-display vnc=:0" nl + | Spice -> +- fpf "%s-spice port=5900,addr=127.0.0.1" nl ++ fpf "%s-spice port=%d,addr=127.0.0.1" nl ++ (match display.s_port with None -> 5900 | Some p -> p) + ); + fpf "%s-vga %s" nl + (match guestcaps.gcaps_video with Cirrus -> "cirrus" | QXL -> "qxl") +diff --git a/v2v/types.ml b/v2v/types.ml +index e8ee288..bbe679a 100644 +--- a/v2v/types.ml ++++ b/v2v/types.ml +@@ -56,6 +56,7 @@ and source_display = { + s_keymap : string option; + s_password : string option; + s_listen : s_display_listen; ++ s_port : int option; + } + and s_display_type = Window | VNC | Spice + and s_display_listen = +diff --git a/v2v/types.mli b/v2v/types.mli +index e1aa6f9..5925c97 100644 +--- a/v2v/types.mli ++++ b/v2v/types.mli +@@ -72,6 +72,7 @@ and source_display = { + s_password : string option; (** If required, password to access + the display. *) + s_listen : s_display_listen; (** Listen address. *) ++ s_port : int option; (** Display port. *) + } + and s_display_type = Window | VNC | Spice + and s_display_listen = +-- +1.8.3.1 + diff --git a/SOURCES/0135-v2v-domainxml-factor-out-connect-and-pool-loading.patch b/SOURCES/0135-v2v-domainxml-factor-out-connect-and-pool-loading.patch new file mode 100644 index 0000000..aac730c --- /dev/null +++ b/SOURCES/0135-v2v-domainxml-factor-out-connect-and-pool-loading.patch @@ -0,0 +1,151 @@ +From a71a1ecad6aa3b64616b35ba2bc2a671db80f1d5 Mon Sep 17 00:00:00 2001 +From: Pino Toscano +Date: Tue, 14 Apr 2015 15:16:01 +0200 +Subject: [PATCH] v2v: domainxml: factor out connect and pool loading + +Factor out the connection and pool loading out of v2v_pool_dumpxml, so +it can be used in later implementations requiring a pool. + +Should be just code motion. + +(cherry picked from commit 9001f61a402dc1820fd4c441e5cc78197c39b73b) +--- + v2v/domainxml-c.c | 101 ++++++++++++++++++++++++++++++++---------------------- + 1 file changed, 60 insertions(+), 41 deletions(-) + +diff --git a/v2v/domainxml-c.c b/v2v/domainxml-c.c +index c9ed8c5..ba2a5bc 100644 +--- a/v2v/domainxml-c.c ++++ b/v2v/domainxml-c.c +@@ -106,6 +106,63 @@ libvirt_auth_default_wrapper (virConnectCredentialPtr cred, + } + } + ++virStoragePoolPtr ++connect_and_load_pool (value connv, value poolnamev) ++{ ++ CAMLparam2 (connv, poolnamev); ++ const char *conn_uri = NULL; ++ const char *poolname; ++ /* We have to assemble the error on the stack because a dynamic ++ * string couldn't be freed. ++ */ ++ char errmsg[256]; ++ virErrorPtr err; ++ virConnectPtr conn; ++ virStoragePoolPtr pool; ++ ++ if (connv != Val_int (0)) ++ conn_uri = String_val (Field (connv, 0)); /* Some conn */ ++ ++ /* We have to call the default authentication handler, not least ++ * since it handles all the PolicyKit crap. However it also makes ++ * coding this simpler. ++ */ ++ conn = virConnectOpenAuth (conn_uri, virConnectAuthPtrDefault, ++ VIR_CONNECT_RO); ++ if (conn == NULL) { ++ if (conn_uri) ++ snprintf (errmsg, sizeof errmsg, ++ _("cannot open libvirt connection '%s'"), conn_uri); ++ else ++ snprintf (errmsg, sizeof errmsg, _("cannot open libvirt connection")); ++ caml_invalid_argument (errmsg); ++ } ++ ++ /* Suppress default behaviour of printing errors to stderr. Note ++ * you can't set this to NULL to ignore errors; setting it to NULL ++ * restores the default error handler ... ++ */ ++ virConnSetErrorFunc (conn, NULL, ignore_errors); ++ ++ /* Look up the pool. */ ++ poolname = String_val (poolnamev); ++ ++ pool = virStoragePoolLookupByUUIDString (conn, poolname); ++ ++ if (!pool) ++ pool = virStoragePoolLookupByName (conn, poolname); ++ ++ if (!pool) { ++ err = virGetLastError (); ++ snprintf (errmsg, sizeof errmsg, ++ _("cannot find libvirt pool '%s': %s"), poolname, err->message); ++ virConnectClose (conn); ++ caml_invalid_argument (errmsg); ++ } ++ ++ CAMLreturnT (virStoragePoolPtr, pool); ++} ++ + value + v2v_dumpxml (value passwordv, value connv, value domnamev) + { +@@ -216,8 +273,6 @@ v2v_pool_dumpxml (value connv, value poolnamev) + { + CAMLparam2 (connv, poolnamev); + CAMLlocal1 (retv); +- const char *conn_uri = NULL; +- const char *poolname; + /* We have to assemble the error on the stack because a dynamic + * string couldn't be freed. + */ +@@ -227,52 +282,16 @@ v2v_pool_dumpxml (value connv, value poolnamev) + virStoragePoolPtr pool; + char *xml; + +- if (connv != Val_int (0)) +- conn_uri = String_val (Field (connv, 0)); /* Some conn */ +- +- /* We have to call the default authentication handler, not least +- * since it handles all the PolicyKit crap. However it also makes +- * coding this simpler. +- */ +- conn = virConnectOpenAuth (conn_uri, virConnectAuthPtrDefault, +- VIR_CONNECT_RO); +- if (conn == NULL) { +- if (conn_uri) +- snprintf (errmsg, sizeof errmsg, +- _("cannot open libvirt connection '%s'"), conn_uri); +- else +- snprintf (errmsg, sizeof errmsg, _("cannot open libvirt connection")); +- caml_invalid_argument (errmsg); +- } +- +- /* Suppress default behaviour of printing errors to stderr. Note +- * you can't set this to NULL to ignore errors; setting it to NULL +- * restores the default error handler ... +- */ +- virConnSetErrorFunc (conn, NULL, ignore_errors); +- + /* Look up the pool. */ +- poolname = String_val (poolnamev); +- +- pool = virStoragePoolLookupByUUIDString (conn, poolname); +- +- if (!pool) +- pool = virStoragePoolLookupByName (conn, poolname); +- +- if (!pool) { +- err = virGetLastError (); +- snprintf (errmsg, sizeof errmsg, +- _("cannot find libvirt pool '%s': %s"), poolname, err->message); +- virConnectClose (conn); +- caml_invalid_argument (errmsg); +- } ++ pool = connect_and_load_pool (connv, poolnamev); ++ conn = virStoragePoolGetConnect (pool); + + xml = virStoragePoolGetXMLDesc (pool, 0); + if (xml == NULL) { + err = virGetLastError (); + snprintf (errmsg, sizeof errmsg, + _("cannot fetch XML description of pool '%s': %s"), +- poolname, err->message); ++ String_val (poolnamev), err->message); + virStoragePoolFree (pool); + virConnectClose (conn); + caml_invalid_argument (errmsg); +-- +1.8.3.1 + diff --git a/SOURCES/0136-v2v-domainxml-add-vol_dumpxml.patch b/SOURCES/0136-v2v-domainxml-add-vol_dumpxml.patch new file mode 100644 index 0000000..060d6b7 --- /dev/null +++ b/SOURCES/0136-v2v-domainxml-add-vol_dumpxml.patch @@ -0,0 +1,117 @@ +From 124edcf9a0900dc8e721180217b550b846b7c8f9 Mon Sep 17 00:00:00 2001 +From: Pino Toscano +Date: Tue, 14 Apr 2015 16:35:51 +0200 +Subject: [PATCH] v2v: domainxml: add vol_dumpxml + +Add a new vol_dumpxml to get the XML dump of a pool's volume. + +(cherry picked from commit 5da2ed95c11af6be6bee27f5b3dce8a6f3a29d74) +--- + v2v/domainxml-c.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ + v2v/domainxml.ml | 1 + + v2v/domainxml.mli | 6 ++++++ + 3 files changed, 68 insertions(+) + +diff --git a/v2v/domainxml-c.c b/v2v/domainxml-c.c +index ba2a5bc..60157e1 100644 +--- a/v2v/domainxml-c.c ++++ b/v2v/domainxml-c.c +@@ -305,6 +305,61 @@ v2v_pool_dumpxml (value connv, value poolnamev) + CAMLreturn (retv); + } + ++value ++v2v_vol_dumpxml (value connv, value poolnamev, value volnamev) ++{ ++ CAMLparam3 (connv, poolnamev, volnamev); ++ CAMLlocal1 (retv); ++ const char *volname; ++ /* We have to assemble the error on the stack because a dynamic ++ * string couldn't be freed. ++ */ ++ char errmsg[256]; ++ virErrorPtr err; ++ virConnectPtr conn; ++ virStoragePoolPtr pool; ++ virStorageVolPtr vol; ++ char *xml; ++ ++ /* Look up the pool. */ ++ pool = connect_and_load_pool (connv, poolnamev); ++ conn = virStoragePoolGetConnect (pool); ++ ++ /* Look up the volume. */ ++ volname = String_val (volnamev); ++ ++ vol = virStorageVolLookupByName (pool, volname); ++ ++ if (!vol) { ++ err = virGetLastError (); ++ snprintf (errmsg, sizeof errmsg, ++ _("cannot find libvirt volume '%s': %s"), volname, err->message); ++ virStoragePoolFree (pool); ++ virConnectClose (conn); ++ caml_invalid_argument (errmsg); ++ } ++ ++ xml = virStorageVolGetXMLDesc (vol, 0); ++ if (xml == NULL) { ++ err = virGetLastError (); ++ snprintf (errmsg, sizeof errmsg, ++ _("cannot fetch XML description of volume '%s': %s"), ++ volname, err->message); ++ virStorageVolFree (vol); ++ virStoragePoolFree (pool); ++ virConnectClose (conn); ++ caml_invalid_argument (errmsg); ++ } ++ virStorageVolFree (vol); ++ virStoragePoolFree (pool); ++ virConnectClose (conn); ++ ++ retv = caml_copy_string (xml); ++ free (xml); ++ ++ CAMLreturn (retv); ++} ++ + #else /* !HAVE_LIBVIRT */ + + value +@@ -319,4 +374,10 @@ v2v_pool_dumpxml (value connv, value poolv) + caml_invalid_argument ("virt-v2v was compiled without libvirt support"); + } + ++value ++v2v_vol_dumpxml (value connv, value poolnamev, value volnamev) ++{ ++ caml_invalid_argument ("virt-v2v was compiled without libvirt support"); ++} ++ + #endif /* !HAVE_LIBVIRT */ +diff --git a/v2v/domainxml.ml b/v2v/domainxml.ml +index 61ed5e0..d8b9ed4 100644 +--- a/v2v/domainxml.ml ++++ b/v2v/domainxml.ml +@@ -20,3 +20,4 @@ + + external dumpxml : ?password:string -> ?conn:string -> string -> string = "v2v_dumpxml" + external pool_dumpxml : ?conn:string -> string -> string = "v2v_pool_dumpxml" ++external vol_dumpxml : ?conn:string -> string -> string -> string = "v2v_vol_dumpxml" +diff --git a/v2v/domainxml.mli b/v2v/domainxml.mli +index ffb1c46..98690fe 100644 +--- a/v2v/domainxml.mli ++++ b/v2v/domainxml.mli +@@ -32,3 +32,9 @@ val pool_dumpxml : ?conn:string -> string -> string + (** [pool_dumpxml ?conn pool] returns the libvirt XML of pool [pool]. + The optional [?conn] parameter is the libvirt connection URI. + [pool] may be a pool name or UUID. *) ++ ++val vol_dumpxml : ?conn:string -> string -> string -> string ++(** [vol_dumpxml ?conn pool vol] returns the libvirt XML of volume [vol], ++ which is part of the pool [pool]. ++ The optional [?conn] parameter is the libvirt connection URI. ++ [pool] may be a pool name or UUID. *) +-- +1.8.3.1 + diff --git a/SOURCES/0137-v2v-pass-libvirt-connection-URI-to-parse_libvirt_xml.patch b/SOURCES/0137-v2v-pass-libvirt-connection-URI-to-parse_libvirt_xml.patch new file mode 100644 index 0000000..fc7e86f --- /dev/null +++ b/SOURCES/0137-v2v-pass-libvirt-connection-URI-to-parse_libvirt_xml.patch @@ -0,0 +1,84 @@ +From 08eea12254c7c6d072028638965101e1a1c9448b Mon Sep 17 00:00:00 2001 +From: Pino Toscano +Date: Tue, 14 Apr 2015 16:37:55 +0200 +Subject: [PATCH] v2v: pass libvirt connection URI to parse_libvirt_xml + +This makes it possible to connect to the right libvirt. + +(cherry picked from commit f7529522ab74d824c550d62953f0b8ecf1e61466) +--- + v2v/input_libvirt_other.ml | 2 +- + v2v/input_libvirt_vcenter_https.ml | 2 +- + v2v/input_libvirt_xen_ssh.ml | 2 +- + v2v/input_libvirtxml.ml | 2 +- + v2v/input_libvirtxml.mli | 2 +- + 5 files changed, 5 insertions(+), 5 deletions(-) + +diff --git a/v2v/input_libvirt_other.ml b/v2v/input_libvirt_other.ml +index c704af6..e675427 100644 +--- a/v2v/input_libvirt_other.ml ++++ b/v2v/input_libvirt_other.ml +@@ -70,7 +70,7 @@ object + *) + let xml = Domainxml.dumpxml ?password ?conn:libvirt_uri guest in + +- let source, disks = Input_libvirtxml.parse_libvirt_xml ~verbose xml in ++ let source, disks = Input_libvirtxml.parse_libvirt_xml ?conn:libvirt_uri ~verbose xml in + let disks = + List.map (fun { Input_libvirtxml.p_source_disk = disk } -> disk) disks in + { source with s_disks = disks } +diff --git a/v2v/input_libvirt_vcenter_https.ml b/v2v/input_libvirt_vcenter_https.ml +index 783b630..d0d860e 100644 +--- a/v2v/input_libvirt_vcenter_https.ml ++++ b/v2v/input_libvirt_vcenter_https.ml +@@ -298,7 +298,7 @@ object + * that the domain is not running. (RHBZ#1138586) + *) + let xml = Domainxml.dumpxml ?password ?conn:libvirt_uri guest in +- let source, disks = parse_libvirt_xml ~verbose xml in ++ let source, disks = parse_libvirt_xml ?conn:libvirt_uri ~verbose xml in + + (* Save the original source paths, so that we can remap them again + * in [#adjust_overlay_parameters]. +diff --git a/v2v/input_libvirt_xen_ssh.ml b/v2v/input_libvirt_xen_ssh.ml +index cf5f1ae..ccb8bd0 100644 +--- a/v2v/input_libvirt_xen_ssh.ml ++++ b/v2v/input_libvirt_xen_ssh.ml +@@ -46,7 +46,7 @@ object + * that the domain is not running. (RHBZ#1138586) + *) + let xml = Domainxml.dumpxml ?password ?conn:libvirt_uri guest in +- let source, disks = parse_libvirt_xml ~verbose xml in ++ let source, disks = parse_libvirt_xml ?conn:libvirt_uri ~verbose xml in + + (* Map the filename (which is relative to the remote + * Xen server) to an ssh URI. This is a JSON URI looking something +diff --git a/v2v/input_libvirtxml.ml b/v2v/input_libvirtxml.ml +index 34f1bd1..357c46f 100644 +--- a/v2v/input_libvirtxml.ml ++++ b/v2v/input_libvirtxml.ml +@@ -33,7 +33,7 @@ and parsed_source = + | P_source_file of string + | P_dont_rewrite + +-let parse_libvirt_xml ~verbose xml = ++let parse_libvirt_xml ?conn ~verbose xml = + if verbose then + printf "libvirt xml is:\n%s\n" xml; + +diff --git a/v2v/input_libvirtxml.mli b/v2v/input_libvirtxml.mli +index e450899..934c9c5 100644 +--- a/v2v/input_libvirtxml.mli ++++ b/v2v/input_libvirtxml.mli +@@ -27,7 +27,7 @@ and parsed_source = + | P_source_file of string (** *) + | P_dont_rewrite (** s_qemu_uri is already set. *) + +-val parse_libvirt_xml : verbose:bool -> string -> Types.source * parsed_disk list ++val parse_libvirt_xml : ?conn:string -> verbose:bool -> string -> Types.source * parsed_disk list + (** Take libvirt XML and parse it into a {!Types.source} structure and a + list of source disks. + +-- +1.8.3.1 + diff --git a/SOURCES/0138-v2v-start-importing-volume-disk-types-RHBZ-1146832.patch b/SOURCES/0138-v2v-start-importing-volume-disk-types-RHBZ-1146832.patch new file mode 100644 index 0000000..9e55e2d --- /dev/null +++ b/SOURCES/0138-v2v-start-importing-volume-disk-types-RHBZ-1146832.patch @@ -0,0 +1,70 @@ +From 88d41fa8dd122a9f90430a4615497dcc29c10231 Mon Sep 17 00:00:00 2001 +From: Pino Toscano +Date: Tue, 14 Apr 2015 16:59:57 +0200 +Subject: [PATCH] v2v: start importing "volume" disk types (RHBZ#1146832) + +Import disks stored as "file"-type volumes. + +Side effect: a guest converted to libvirt using virt-v2v can be +converted again using virt-v2v. + +(cherry picked from commit 08b1ba35cfaa526982911fe9f355ed9c168d942d) +--- + v2v/input_libvirtxml.ml | 34 ++++++++++++++++++++++++++++++++-- + 1 file changed, 32 insertions(+), 2 deletions(-) + +diff --git a/v2v/input_libvirtxml.ml b/v2v/input_libvirtxml.ml +index 357c46f..16a8115 100644 +--- a/v2v/input_libvirtxml.ml ++++ b/v2v/input_libvirtxml.ml +@@ -180,8 +180,8 @@ let parse_libvirt_xml ?conn ~verbose xml = + | "" -> None + | format -> Some format in + +- (* The attribute may be 'block', 'file' or +- * 'network'. We ignore any other types. ++ (* The attribute may be 'block', 'file', ++ * 'network' or 'volume'. We ignore any other types. + *) + match xpath_to_string "@type" "" with + | "block" -> +@@ -213,6 +213,36 @@ let parse_libvirt_xml ?conn ~verbose xml = + warning ~prog (f_"network with was ignored") + protocol + ) ++ | "volume" -> ++ let pool = xpath_to_string "source/@pool" "" in ++ let vol = xpath_to_string "source/@volume" "" in ++ if pool <> "" && vol <> "" then ( ++ let xml = Domainxml.vol_dumpxml ?conn pool vol in ++ let doc = Xml.parse_memory xml in ++ let xpathctx = Xml.xpath_new_context doc in ++ ++ let xpath_to_string expr default = ++ let obj = Xml.xpath_eval_expression xpathctx expr in ++ if Xml.xpathobj_nr_nodes obj < 1 then default ++ else ( ++ let node = Xml.xpathobj_node doc obj 0 in ++ Xml.node_as_string node ++ ) in ++ ++ (* Use the format specified in the volume itself. *) ++ let format = ++ match xpath_to_string "/volume/target/format/@type" "" with ++ | "" -> None ++ | format -> Some format in ++ ++ match xpath_to_string "/volume/@type" "" with ++ | "" | "file" -> ++ let path = xpath_to_string "/volume/target/path/text()" "" in ++ if path <> "" then ++ add_disk path format controller (P_source_file path) ++ | vol_type -> ++ warning ~prog (f_" with was ignored") vol_type ++ ) + | disk_type -> + warning ~prog (f_" was ignored") disk_type + done; +-- +1.8.3.1 + diff --git a/SOURCES/0139-v2v-support-tar.gz-and-tar.xz-ova-files.patch b/SOURCES/0139-v2v-support-tar.gz-and-tar.xz-ova-files.patch new file mode 100644 index 0000000..51a0d3a --- /dev/null +++ b/SOURCES/0139-v2v-support-tar.gz-and-tar.xz-ova-files.patch @@ -0,0 +1,87 @@ +From 54350043efed23af2770a9b5a4b19afb1abdf4e5 Mon Sep 17 00:00:00 2001 +From: Pino Toscano +Date: Wed, 15 Apr 2015 11:21:57 +0200 +Subject: [PATCH] v2v: support tar.gz and tar.xz ova files + +When dealing with a ova detected as gzip of xz, uncompress few bytes of +it to check whether it is a compressed tarball, and if so untar it. + +Related to RHBZ#1186800. + +(cherry picked from commit 3c582cfb8d62013a935953e919c79009452254f9) +--- + v2v/input_ova.ml | 48 ++++++++++++++++++++++++++++++++++++++++++------ + 1 file changed, 42 insertions(+), 6 deletions(-) + +diff --git a/v2v/input_ova.ml b/v2v/input_ova.ml +index 211db43..8079d28 100644 +--- a/v2v/input_ova.ml ++++ b/v2v/input_ova.ml +@@ -43,13 +43,32 @@ object + *) + if is_directory ova then ova + else ( ++ let uncompress_head zcat file = ++ let cmd = sprintf "%s %s" zcat (quote file) in ++ let chan_out, chan_in, chan_err = Unix.open_process_full cmd [||] in ++ let buf = String.create 512 in ++ let len = input chan_out buf 0 (String.length buf) in ++ (* We're expecting the subprocess to fail because we close ++ * the pipe early, so: ++ *) ++ ignore (Unix.close_process_full (chan_out, chan_in, chan_err)); ++ ++ let tmpfile, chan = Filename.open_temp_file ~temp_dir:tmpdir "ova.file." "" in ++ output chan buf 0 len; ++ close_out chan; ++ ++ tmpfile in ++ ++ let untar ?(format = "") file outdir = ++ let cmd = sprintf "tar -x%sf %s -C %s" format (quote file) (quote outdir) in ++ if verbose then printf "%s\n%!" cmd; ++ if Sys.command cmd <> 0 then ++ error (f_"error unpacking %s, see earlier error messages") ova in ++ + match detect_file_type ova with + | `Tar -> + (* Normal ovas are tar file (not compressed). *) +- let cmd = sprintf "tar -xf %s -C %s" (quote ova) (quote tmpdir) in +- if verbose then printf "%s\n%!" cmd; +- if Sys.command cmd <> 0 then +- error (f_"error unpacking %s, see earlier error messages") ova; ++ untar ova tmpdir; + tmpdir + | `Zip -> + (* However, although not permitted by the spec, people ship +@@ -62,8 +81,25 @@ object + if Sys.command cmd <> 0 then + error (f_"error unpacking %s, see earlier error messages") ova; + tmpdir +- | `GZip | `XZ | `Unknown -> +- error (f_"%s: unsupported file format\n\nFormats which we currently understand for '-i ova' are: uncompressed tar, zip") ova ++ | (`GZip|`XZ) as format -> ++ let zcat, tar_fmt = ++ match format with ++ | `GZip -> "zcat", "z" ++ | `XZ -> "xzcat", "J" ++ | _ -> assert false in ++ let tmpfile = uncompress_head zcat ova in ++ let tmpfiletype = detect_file_type tmpfile in ++ (* Remove tmpfile from tmpdir, to leave it empty. *) ++ Sys.remove tmpfile; ++ (match tmpfiletype with ++ | `Tar -> ++ untar ~format:tar_fmt ova tmpdir; ++ tmpdir ++ | `Zip | `GZip | `XZ | `Unknown -> ++ error (f_"%s: unsupported file format\n\nFormats which we currently understand for '-i ova' are: tar (uncompressed, compress with gzip or xz), zip") ova ++ ) ++ | `Unknown -> ++ error (f_"%s: unsupported file format\n\nFormats which we currently understand for '-i ova' are: tar (uncompressed, compress with gzip or xz), zip") ova + ) in + + (* Exploded path must be absolute (RHBZ#1155121). *) +-- +1.8.3.1 + diff --git a/SOURCES/0140-v2v-use-.ovf-and-.mf-files-anywhere-within-ova-files.patch b/SOURCES/0140-v2v-use-.ovf-and-.mf-files-anywhere-within-ova-files.patch new file mode 100644 index 0000000..f882de9 --- /dev/null +++ b/SOURCES/0140-v2v-use-.ovf-and-.mf-files-anywhere-within-ova-files.patch @@ -0,0 +1,131 @@ +From 39536e75adc3444fe77952be8fdc978271dbb2eb Mon Sep 17 00:00:00 2001 +From: Pino Toscano +Date: Wed, 15 Apr 2015 13:22:13 +0200 +Subject: [PATCH] v2v: use .ovf and .mf files anywhere within ova files + +Do not rely on .ovf and .mf files being in the top-level of the ova +archive, but search them anywhere within the content of the ova. + +This also changes the result of the search of the .ovf file: previously, +one (random) file was picked in case there were more than one, while now +this situation triggers an error. + +Related to RHBZ#1186800. + +(cherry picked from commit 8049474636d1a56cb259af6e527fb6b0a42e43e1) +--- + v2v/input_ova.ml | 91 +++++++++++++++++++++++++++++++++----------------------- + 1 file changed, 53 insertions(+), 38 deletions(-) + +diff --git a/v2v/input_ova.ml b/v2v/input_ova.ml +index 8079d28..f530b92 100644 +--- a/v2v/input_ova.ml ++++ b/v2v/input_ova.ml +@@ -107,51 +107,66 @@ object + if not (Filename.is_relative exploded) then exploded + else Sys.getcwd () // exploded in + +- let files = Sys.readdir exploded in +- let ovf = ref "" in ++ (* Find files in [dir] ending with [ext]. *) ++ let find_files dir ext = ++ let rec loop = function ++ | [] -> [] ++ | dir :: rest -> ++ let files = Array.to_list (Sys.readdir dir) in ++ let files = List.map (Filename.concat dir) files in ++ let dirs, files = List.partition Sys.is_directory files in ++ let files = List.filter ( ++ fun x -> ++ Filename.check_suffix x ext ++ ) files in ++ files @ loop (rest @ dirs) ++ in ++ loop [dir] ++ in ++ + (* Search for the ovf file. *) +- Array.iter ( +- fun file -> +- if Filename.check_suffix file ".ovf" then ovf := file +- ) files; +- let ovf = !ovf in +- if ovf = "" then +- error (f_"no .ovf file was found in %s") ova; ++ let ovf = find_files exploded ".ovf" in ++ let ovf = ++ match ovf with ++ | [] -> ++ error (f_"no .ovf file was found in %s") ova ++ | [x] -> x ++ | _ :: _ -> ++ error (f_"more than one .ovf file was found in %s") ova in + + (* Read any .mf (manifest) files and verify sha1. *) ++ let mf = find_files exploded ".mf" in + let rex = Str.regexp "SHA1(\\(.*\\))=\\([0-9a-fA-F]+\\)\r?" in +- Array.iter ( ++ List.iter ( + fun mf -> +- if Filename.check_suffix mf ".mf" then ( +- let chan = open_in (exploded // 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 out = external_command ~prog cmd in +- match out with +- | [] -> +- error (f_"no output from sha1sum command, see previous errors") +- | [line] -> +- let actual, _ = string_split " " line in +- if actual <> expected then +- error (f_"checksum of disk %s does not match manifest %s (actual sha1(%s) = %s, expected sha1 (%s) = %s)") +- disk mf disk actual disk expected; +- if verbose then +- printf "sha1 of %s matches expected checksum %s\n%!" +- disk expected +- | _::_ -> error (f_"cannot parse output of sha1sum command") +- ) +- in +- (try loop () with End_of_file -> ()); +- close_in chan +- ) +- ) files; ++ 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 out = external_command ~prog cmd in ++ match out with ++ | [] -> ++ error (f_"no output from sha1sum command, see previous errors") ++ | [line] -> ++ let actual, _ = string_split " " line in ++ if actual <> expected then ++ error (f_"checksum of disk %s does not match manifest %s (actual sha1(%s) = %s, expected sha1 (%s) = %s)") ++ disk mf disk actual disk expected; ++ if verbose then ++ printf "sha1 of %s matches expected checksum %s\n%!" ++ disk expected ++ | _::_ -> error (f_"cannot parse output of sha1sum command") ++ ) ++ in ++ (try loop () with End_of_file -> ()); ++ close_in chan ++ ) mf; + + (* Parse the ovf file. *) +- let xml = read_whole_file (exploded // ovf) in ++ let xml = read_whole_file ovf in + let doc = Xml.parse_memory xml in + + (* Handle namespaces. *) +-- +1.8.3.1 + diff --git a/SOURCES/0141-v2v-tests-add-port-1-to-test-v2v-i-ova.xml-reference.patch b/SOURCES/0141-v2v-tests-add-port-1-to-test-v2v-i-ova.xml-reference.patch new file mode 100644 index 0000000..4925650 --- /dev/null +++ b/SOURCES/0141-v2v-tests-add-port-1-to-test-v2v-i-ova.xml-reference.patch @@ -0,0 +1,29 @@ +From 0d350c9a950043b95860d95c3aecab41b515feea Mon Sep 17 00:00:00 2001 +From: Pino Toscano +Date: Wed, 15 Apr 2015 14:28:05 +0200 +Subject: [PATCH] v2v: tests: add port='-1' to test-v2v-i-ova.xml reference + +Followup of commit 1db249a0cc21c65e0d3192567b6016745cea7e58, as it +outputs a new port attribute. + +(cherry picked from commit 11450a2d36fd05bd0dc9baff97c2afd08b4c9b07) +--- + v2v/test-v2v-i-ova.xml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/v2v/test-v2v-i-ova.xml b/v2v/test-v2v-i-ova.xml +index 2d611f9..f3ecdc6 100644 +--- a/v2v/test-v2v-i-ova.xml ++++ b/v2v/test-v2v-i-ova.xml +@@ -33,7 +33,7 @@ + + +