mirror of
https://github.com/libvirt/libvirt.git
synced 2025-02-25 18:55:26 -06:00
virsh: Implement sparse stream to vol-download
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>
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user