提交 f03b44b2 编写于 作者: M Michal Privoznik

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: NMichal Privoznik <mprivozn@redhat.com>
上级 1f43aa67
...@@ -153,6 +153,24 @@ virshStreamSink(virStreamPtr st ATTRIBUTE_UNUSED, ...@@ -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 void
virshDomainFree(virDomainPtr dom) virshDomainFree(virDomainPtr dom)
{ {
......
...@@ -57,6 +57,11 @@ virshStreamSink(virStreamPtr st, ...@@ -57,6 +57,11 @@ virshStreamSink(virStreamPtr st,
size_t nbytes, size_t nbytes,
void *opaque); void *opaque);
int
virshStreamSkip(virStreamPtr st,
long long offset,
void *opaque);
int int
virshDomainGetXMLFromDom(vshControl *ctl, virshDomainGetXMLFromDom(vshControl *ctl,
virDomainPtr dom, virDomainPtr dom,
......
...@@ -763,6 +763,10 @@ static const vshCmdOptDef opts_vol_download[] = { ...@@ -763,6 +763,10 @@ static const vshCmdOptDef opts_vol_download[] = {
.type = VSH_OT_INT, .type = VSH_OT_INT,
.help = N_("amount of data to download") .help = N_("amount of data to download")
}, },
{.name = "sparse",
.type = VSH_OT_BOOL,
.help = N_("preserve sparseness of volume")
},
{.name = NULL} {.name = NULL}
}; };
...@@ -778,6 +782,7 @@ cmdVolDownload(vshControl *ctl, const vshCmd *cmd) ...@@ -778,6 +782,7 @@ cmdVolDownload(vshControl *ctl, const vshCmd *cmd)
unsigned long long offset = 0, length = 0; unsigned long long offset = 0, length = 0;
bool created = false; bool created = false;
virshControlPtr priv = ctl->privData; virshControlPtr priv = ctl->privData;
unsigned int flags = 0;
if (vshCommandOptULongLong(ctl, cmd, "offset", &offset) < 0) if (vshCommandOptULongLong(ctl, cmd, "offset", &offset) < 0)
return false; return false;
...@@ -791,6 +796,9 @@ cmdVolDownload(vshControl *ctl, const vshCmd *cmd) ...@@ -791,6 +796,9 @@ cmdVolDownload(vshControl *ctl, const vshCmd *cmd)
if (vshCommandOptStringReq(ctl, cmd, "file", &file) < 0) if (vshCommandOptStringReq(ctl, cmd, "file", &file) < 0)
goto cleanup; 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 ((fd = open(file, O_WRONLY|O_CREAT|O_EXCL, 0666)) < 0) {
if (errno != EEXIST || if (errno != EEXIST ||
(fd = open(file, O_WRONLY|O_TRUNC, 0666)) < 0) { (fd = open(file, O_WRONLY|O_TRUNC, 0666)) < 0) {
...@@ -806,12 +814,12 @@ cmdVolDownload(vshControl *ctl, const vshCmd *cmd) ...@@ -806,12 +814,12 @@ cmdVolDownload(vshControl *ctl, const vshCmd *cmd)
goto cleanup; 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); vshError(ctl, _("cannot download from volume %s"), name);
goto cleanup; goto cleanup;
} }
if (virStreamRecvAll(st, virshStreamSink, &fd) < 0) { if (virStreamSparseRecvAll(st, virshStreamSink, virshStreamSkip, &fd) < 0) {
vshError(ctl, _("cannot receive data from volume %s"), name); vshError(ctl, _("cannot receive data from volume %s"), name);
goto cleanup; goto cleanup;
} }
......
...@@ -3943,12 +3943,13 @@ regarding possible target volume and pool changes as a result of the ...@@ -3943,12 +3943,13 @@ regarding possible target volume and pool changes as a result of the
pool refresh when the upload is attempted. pool refresh when the upload is attempted.
=item B<vol-download> [I<--pool> I<pool-or-uuid>] [I<--offset> I<bytes>] =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>. 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 I<--pool> I<pool-or-uuid> is the name or UUID of the storage pool the volume
is in. is in.
I<vol-name-or-key-or-path> is the name or key or path of the volume to download. 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 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 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 the amount of data to be downloaded. A negative value is interpreted as
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册