]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
virsh: Implement sparse stream to vol-download
authorMichal Privoznik <mprivozn@redhat.com>
Tue, 12 Apr 2016 13:35:04 +0000 (15:35 +0200)
committerMichal Privoznik <mprivozn@redhat.com>
Thu, 18 May 2017 05:42:13 +0000 (07:42 +0200)
Add a new --sparse switch that does nothing more than
enables the sparse streams feature for this command. Among with
the switch new helper function is introduced: virshStreamSkip().
This is the callback that is called whenever daemon sends us a
hole. In the callback we reflect the hole in underlying file by
seeking as many bytes as told.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
tools/virsh-util.c
tools/virsh-util.h
tools/virsh-volume.c
tools/virsh.pod

index 4b86e29cbd4f859aabb85c522382a32c188722a7..198625bdbffbc214db833ec9060351287616337f 100644 (file)
@@ -153,6 +153,24 @@ virshStreamSink(virStreamPtr st ATTRIBUTE_UNUSED,
 }
 
 
+int
+virshStreamSkip(virStreamPtr st ATTRIBUTE_UNUSED,
+                long long offset,
+                void *opaque)
+{
+    int *fd = opaque;
+    off_t cur;
+
+    if ((cur = lseek(*fd, offset, SEEK_CUR)) == (off_t) -1)
+        return -1;
+
+    if (ftruncate(*fd, cur) < 0)
+        return -1;
+
+    return 0;
+}
+
+
 void
 virshDomainFree(virDomainPtr dom)
 {
index 64cef23c02f66381ef8dd09d06d4321b9ad71167..0aba247f6ee3e5a68a77b6fa7a22260cf0f2eca4 100644 (file)
@@ -57,6 +57,11 @@ virshStreamSink(virStreamPtr st,
                 size_t nbytes,
                 void *opaque);
 
+int
+virshStreamSkip(virStreamPtr st,
+                long long offset,
+                void *opaque);
+
 int
 virshDomainGetXMLFromDom(vshControl *ctl,
                          virDomainPtr dom,
index 66fe70ea77551ffa3228b1620fa4a2f572843797..3d19b745e9601ed5e364a5066c83b7a443e8c2a2 100644 (file)
@@ -763,6 +763,10 @@ static const vshCmdOptDef opts_vol_download[] = {
      .type = VSH_OT_INT,
      .help = N_("amount of data to download")
     },
+    {.name = "sparse",
+     .type = VSH_OT_BOOL,
+     .help = N_("preserve sparseness of volume")
+    },
     {.name = NULL}
 };
 
@@ -778,6 +782,7 @@ cmdVolDownload(vshControl *ctl, const vshCmd *cmd)
     unsigned long long offset = 0, length = 0;
     bool created = false;
     virshControlPtr priv = ctl->privData;
+    unsigned int flags = 0;
 
     if (vshCommandOptULongLong(ctl, cmd, "offset", &offset) < 0)
         return false;
@@ -791,6 +796,9 @@ cmdVolDownload(vshControl *ctl, const vshCmd *cmd)
     if (vshCommandOptStringReq(ctl, cmd, "file", &file) < 0)
         goto cleanup;
 
+    if (vshCommandOptBool(cmd, "sparse"))
+        flags |= VIR_STORAGE_VOL_DOWNLOAD_SPARSE_STREAM;
+
     if ((fd = open(file, O_WRONLY|O_CREAT|O_EXCL, 0666)) < 0) {
         if (errno != EEXIST ||
             (fd = open(file, O_WRONLY|O_TRUNC, 0666)) < 0) {
@@ -806,12 +814,12 @@ cmdVolDownload(vshControl *ctl, const vshCmd *cmd)
         goto cleanup;
     }
 
-    if (virStorageVolDownload(vol, st, offset, length, 0) < 0) {
+    if (virStorageVolDownload(vol, st, offset, length, flags) < 0) {
         vshError(ctl, _("cannot download from volume %s"), name);
         goto cleanup;
     }
 
-    if (virStreamRecvAll(st, virshStreamSink, &fd) < 0) {
+    if (virStreamSparseRecvAll(st, virshStreamSink, virshStreamSkip, &fd) < 0) {
         vshError(ctl, _("cannot receive data from volume %s"), name);
         goto cleanup;
     }
index a1124c523c773d2ec6ab2373c698c1bc07291108..8a3ef69194f5e3a9ae086faf1ad15e9ee5513d8a 100644 (file)
@@ -3943,12 +3943,13 @@ regarding possible target volume and pool changes as a result of the
 pool refresh when the upload is attempted.
 
 =item B<vol-download> [I<--pool> I<pool-or-uuid>] [I<--offset> I<bytes>]
-[I<--length> I<bytes>] I<vol-name-or-key-or-path> I<local-file>
+[I<--length> I<bytes>] [I<--sparse>] I<vol-name-or-key-or-path> I<local-file>
 
 Download the contents of a storage volume to I<local-file>.
 I<--pool> I<pool-or-uuid> is the name or UUID of the storage pool the volume
 is in.
 I<vol-name-or-key-or-path> is the name or key or path of the volume to download.
+If I<--sparse> is specified, this command will preserve volume sparseness.
 I<--offset> is the position in the storage volume at which to start reading
 the data. The value must be 0 or larger. I<--length> is an upper bound of
 the amount of data to be downloaded. A negative value is interpreted as