]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
virsh: Track if vol-upload or vol-download work over a block device
authorMichal Privoznik <mprivozn@redhat.com>
Thu, 2 Jul 2020 06:51:20 +0000 (08:51 +0200)
committerMichal Privoznik <mprivozn@redhat.com>
Mon, 24 Aug 2020 11:32:53 +0000 (13:32 +0200)
We can't use virFileInData() with block devices, but we can
emulate being in data section all the time (vol-upload case).
Alternatively, we can't just lseek() beyond EOF with block
devices to create a hole, we will have to write zeroes
(vol-download case).  But to decide we need to know if the FD we
are reading data from / writing data to is a block device. Store
this information in _virshStreamCallbackData.

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

index 72653d973543b52b89562f41c4d74485a22bcb6e..9ef28cfe0a559e11e316dd2ddbe83a0bff1ab9d8 100644 (file)
@@ -72,6 +72,7 @@ typedef virshStreamCallbackData *virshStreamCallbackDataPtr;
 struct _virshStreamCallbackData {
     vshControl *ctl;
     int fd;
+    bool isBlock;
 };
 
 int
index d29db6c38dd8778f816a145e51907c9b52dd753b..374bde43182ac35fa039053246a24ca872300ba3 100644 (file)
@@ -676,6 +676,7 @@ cmdVolUpload(vshControl *ctl, const vshCmd *cmd)
     virshControlPtr priv = ctl->privData;
     unsigned int flags = 0;
     virshStreamCallbackData cbData;
+    struct stat sb;
 
     if (vshCommandOptULongLong(ctl, cmd, "offset", &offset) < 0)
         return false;
@@ -694,8 +695,14 @@ cmdVolUpload(vshControl *ctl, const vshCmd *cmd)
         goto cleanup;
     }
 
+    if (fstat(fd, &sb) < 0) {
+        vshError(ctl, _("unable to stat %s"), file);
+        goto cleanup;
+    }
+
     cbData.ctl = ctl;
     cbData.fd = fd;
+    cbData.isBlock = !!S_ISBLK(sb.st_mode);
 
     if (vshCommandOptBool(cmd, "sparse"))
         flags |= VIR_STORAGE_VOL_UPLOAD_SPARSE_STREAM;
@@ -792,6 +799,7 @@ cmdVolDownload(vshControl *ctl, const vshCmd *cmd)
     virshControlPtr priv = ctl->privData;
     virshStreamCallbackData cbData;
     unsigned int flags = 0;
+    struct stat sb;
 
     if (vshCommandOptULongLong(ctl, cmd, "offset", &offset) < 0)
         return false;
@@ -818,8 +826,14 @@ cmdVolDownload(vshControl *ctl, const vshCmd *cmd)
         created = true;
     }
 
+    if (fstat(fd, &sb) < 0) {
+        vshError(ctl, _("unable to stat %s"), file);
+        goto cleanup;
+    }
+
     cbData.ctl = ctl;
     cbData.fd = fd;
+    cbData.isBlock = !!S_ISBLK(sb.st_mode);
 
     if (!(st = virStreamNew(priv->conn, 0))) {
         vshError(ctl, _("cannot create a new stream"));