virsh: Track if vol-upload or vol-download work over a block device

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>
This commit is contained in:
Michal Privoznik 2020-07-02 08:51:20 +02:00
parent 9e745a9717
commit 8a0c327f11
2 changed files with 15 additions and 0 deletions

View File

@ -72,6 +72,7 @@ typedef virshStreamCallbackData *virshStreamCallbackDataPtr;
struct _virshStreamCallbackData {
vshControl *ctl;
int fd;
bool isBlock;
};
int

View 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"));