Pino Toscano
2017-Feb-06 14:59 UTC
[Libguestfs] [PATCH v3] resize: support non-local output disks (RHBZ#1404182)
Parse the output disk as URI, and use all its attributes just like it is done for the input disk. The only change is that the fsync of the output disk is limited now for local URIs only, since it will not work with remote protocols. --- resize/resize.ml | 56 ++++++++++++++++++++++++++++++++++---------------- resize/virt-resize.pod | 6 +++--- 2 files changed, 41 insertions(+), 21 deletions(-) diff --git a/resize/resize.ml b/resize/resize.ml index 19cd8df..2fce9ee 100644 --- a/resize/resize.ml +++ b/resize/resize.ml @@ -315,6 +315,13 @@ read the man page virt-resize(1). error (f_"error parsing URI '%s'. Look for error messages printed above.") infile in + (* outfile can be a URI. *) + let outfile + try (outfile, URI.parse_uri outfile) + with Invalid_argument "URI.parse_uri" -> + error (f_"error parsing URI '%s'. Look for error messages printed above.") + outfile in + infile, outfile, align_first, alignment, copy_boot_loader, deletes, dryrun, expand, expand_content, extra_partition, format, ignores, @@ -326,16 +333,25 @@ read the man page virt-resize(1). let btrfs_available = ref true in let xfs_available = ref true in + (* Add a drive to an handle using the elements of the URI, + * and few additional parameters. + *) + let add_drive_uri (g : Guestfs.guestfs) ?format ?readonly ?cachemode + uri + let { URI.path = path; protocol = protocol; + server = server; username = username; + password = password } = uri in + g#add_drive ?format ?readonly ?cachemode + ~protocol ?server ?username ?secret:password path + in + (* Add in and out disks to the handle and launch. *) let connect_both_disks () let g = open_guestfs () in - let _, { URI.path = path; protocol = protocol; - server = server; username = username; - password = password } = infile in - g#add_drive ?format ~readonly:true ~protocol ?server ?username ?secret:password path; + add_drive_uri g ?format (snd infile); (* The output disk is being created, so use cache=unsafe here. *) - g#add_drive ?format:output_format ~readonly:false ~cachemode:"unsafe" - outfile; + add_drive_uri g ?format:output_format ~readonly:false ~cachemode:"unsafe" + (snd outfile); if not (quiet ()) then Progress.set_up_progress_bar ~machine_readable g; g#launch (); @@ -368,7 +384,7 @@ read the man page virt-resize(1). let insize = g#blockdev_getsize64 "/dev/sda" in let outsize = g#blockdev_getsize64 "/dev/sdb" in debug "%s size %Ld bytes" (fst infile) insize; - debug "%s size %Ld bytes" outfile outsize; + debug "%s size %Ld bytes" (fst outfile) outsize; sectsize, insize, outsize in let max_bootloader @@ -390,7 +406,7 @@ read the man page virt-resize(1). (fst infile) insize; if outsize < Int64.of_int max_bootloader then error (f_"%s: file is too small to be a disk image (%Ld bytes)") - outfile outsize; + (fst outfile) outsize; (* Get the source partition type. *) let parttype, parttype_string @@ -983,7 +999,7 @@ read the man page virt-resize(1). (* Try hard to initialize the partition table. This might involve * relaunching another handle. *) - message (f_"Setting up initial partition table on %s") outfile; + message (f_"Setting up initial partition table on %s") (fst outfile); let last_error = ref "" in let rec initialize_partition_table g attempts @@ -1301,8 +1317,8 @@ read the man page virt-resize(1). let g = open_guestfs () in (* The output disk is being created, so use cache=unsafe here. *) - g#add_drive ?format:output_format ~readonly:false ~cachemode:"unsafe" - outfile; + add_drive_uri g ?format:output_format ~readonly:false ~cachemode:"unsafe" + (snd outfile); if not (quiet ()) then Progress.set_up_progress_bar ~machine_readable g; g#launch (); @@ -1378,13 +1394,17 @@ read the man page virt-resize(1). g#shutdown (); g#close (); - (* Because we used cache=unsafe when writing the output file, the - * file might not be committed to disk. This is a problem if qemu is - * immediately used afterwards with cache=none (which uses O_DIRECT - * and therefore bypasses the host cache). In general you should not - * use cache=none. - *) - Fsync.file outfile; + (* Try to sync the destination disk only if it is a local file. *) + (match outfile with + | _, { URI.protocol = (""|"file"); path = path } -> + (* Because we used cache=unsafe when writing the output file, the + * file might not be committed to disk. This is a problem if qemu is + * immediately used afterwards with cache=none (which uses O_DIRECT + * and therefore bypasses the host cache). In general you should not + * use cache=none. + *) + Fsync.file path + | _ -> ()); if not (quiet ()) then ( print_newline (); diff --git a/resize/virt-resize.pod b/resize/virt-resize.pod index 2344056..98c4b10 100644 --- a/resize/virt-resize.pod +++ b/resize/virt-resize.pod @@ -121,9 +121,9 @@ Or use L<virsh(1)> vol-create-as to create a libvirt storage volume: =item 5. Resize -virt-resize takes two mandatory parameters, the input disk -(eg. device, file, or a URI to a remote disk) and the output disk. -The output disk is the one created in the previous step. +virt-resize takes two mandatory parameters, the input disk and the +output disk (both can be e.g. a device, a file, or a URI to a remote +disk). The output disk is the one created in the previous step. # virt-resize indisk outdisk -- 2.9.3
Richard W.M. Jones
2017-Feb-06 15:19 UTC
Re: [Libguestfs] [PATCH v3] resize: support non-local output disks (RHBZ#1404182)
On Mon, Feb 06, 2017 at 03:59:52PM +0100, Pino Toscano wrote:> Parse the output disk as URI, and use all its attributes just like > it is done for the input disk. The only change is that the fsync of the > output disk is limited now for local URIs only, since it will not work > with remote protocols.ACK. I'll just note a possible simplification ...> + (* Add a drive to an handle using the elements of the URI, > + * and few additional parameters. > + *) > + let add_drive_uri (g : Guestfs.guestfs) ?format ?readonly ?cachemode > + uri > + let { URI.path = path; protocol = protocol; > + server = server; username = username; > + password = password } = uri inYou could unpack the uri in the parameters if you wanted: let add_drive_uri (g : Guestfs.guestfs) ?format ?readonly ?cachemode { URI.path = path; protocol = protocol; server = server; username = username; password = password } g#add_drive ?format ?readonly ?cachemode ~protocol ?server ?username ?secret:password path in Rich. -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones Read my programming and virtualization blog: http://rwmj.wordpress.com virt-p2v converts physical machines to virtual machines. Boot with a live CD or over the network (PXE) and turn machines into KVM guests. http://libguestfs.org/virt-v2v
Apparently Analagous Threads
- [PATCH] resize: support non-local output disks (RHBZ#1404182)
- [PATCH v2] resize: support non-local output disks (RHBZ#1404182)
- Re: [PATCH v2] resize: support non-local output disks (RHBZ#1404182)
- [PATCH 2/2] OCaml tools: simplify machine-readable handling
- [PATCH 2/2] ocaml tools: Use a common debug function.