mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-22 17:34:18 +03:00
virsh: Implement sparse stream to vol-upload
Similarly to previous commit, implement sparse streams feature for vol-upload. This is, however, slightly different approach, because we must implement a function that will tell us whether we are in a data section or in a hole. But there's no magic hidden in here. Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
This commit is contained in:
parent
f03b44b2df
commit
7823e2561b
@ -153,6 +153,35 @@ virshStreamSink(virStreamPtr st ATTRIBUTE_UNUSED,
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
virshStreamSource(virStreamPtr st ATTRIBUTE_UNUSED,
|
||||
char *bytes,
|
||||
size_t nbytes,
|
||||
void *opaque)
|
||||
{
|
||||
virshStreamCallbackDataPtr cbData = opaque;
|
||||
int fd = cbData->fd;
|
||||
|
||||
return saferead(fd, bytes, nbytes);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
virshStreamSourceSkip(virStreamPtr st ATTRIBUTE_UNUSED,
|
||||
long long offset,
|
||||
void *opaque)
|
||||
{
|
||||
virshStreamCallbackDataPtr cbData = opaque;
|
||||
int fd = cbData->fd;
|
||||
off_t cur;
|
||||
|
||||
if ((cur = lseek(fd, offset, SEEK_CUR)) == (off_t) -1)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
virshStreamSkip(virStreamPtr st ATTRIBUTE_UNUSED,
|
||||
long long offset,
|
||||
@ -171,6 +200,24 @@ virshStreamSkip(virStreamPtr st ATTRIBUTE_UNUSED,
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
virshStreamInData(virStreamPtr st ATTRIBUTE_UNUSED,
|
||||
int *inData,
|
||||
long long *offset,
|
||||
void *opaque)
|
||||
{
|
||||
virshStreamCallbackDataPtr cbData = opaque;
|
||||
vshControl *ctl = cbData->ctl;
|
||||
int fd = cbData->fd;
|
||||
int ret;
|
||||
|
||||
if ((ret = virFileInData(fd, inData, offset)) < 0)
|
||||
vshError(ctl, "%s", _("Unable to get current position in stream"));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
virshDomainFree(virDomainPtr dom)
|
||||
{
|
||||
|
@ -57,11 +57,35 @@ virshStreamSink(virStreamPtr st,
|
||||
size_t nbytes,
|
||||
void *opaque);
|
||||
|
||||
typedef struct _virshStreamCallbackData virshStreamCallbackData;
|
||||
typedef virshStreamCallbackData *virshStreamCallbackDataPtr;
|
||||
struct _virshStreamCallbackData {
|
||||
vshControl *ctl;
|
||||
int fd;
|
||||
};
|
||||
|
||||
int
|
||||
virshStreamSource(virStreamPtr st,
|
||||
char *bytes,
|
||||
size_t nbytes,
|
||||
void *opaque);
|
||||
|
||||
int
|
||||
virshStreamSourceSkip(virStreamPtr st,
|
||||
long long offset,
|
||||
void *opaque);
|
||||
|
||||
int
|
||||
virshStreamSkip(virStreamPtr st,
|
||||
long long offset,
|
||||
void *opaque);
|
||||
|
||||
int
|
||||
virshStreamInData(virStreamPtr st,
|
||||
int *inData,
|
||||
long long *offset,
|
||||
void *opaque);
|
||||
|
||||
int
|
||||
virshDomainGetXMLFromDom(vshControl *ctl,
|
||||
virDomainPtr dom,
|
||||
|
@ -660,18 +660,13 @@ static const vshCmdOptDef opts_vol_upload[] = {
|
||||
.type = VSH_OT_INT,
|
||||
.help = N_("amount of data to upload")
|
||||
},
|
||||
{.name = "sparse",
|
||||
.type = VSH_OT_BOOL,
|
||||
.help = N_("preserve sparseness of volume")
|
||||
},
|
||||
{.name = NULL}
|
||||
};
|
||||
|
||||
static int
|
||||
cmdVolUploadSource(virStreamPtr st ATTRIBUTE_UNUSED,
|
||||
char *bytes, size_t nbytes, void *opaque)
|
||||
{
|
||||
int *fd = opaque;
|
||||
|
||||
return saferead(*fd, bytes, nbytes);
|
||||
}
|
||||
|
||||
static bool
|
||||
cmdVolUpload(vshControl *ctl, const vshCmd *cmd)
|
||||
{
|
||||
@ -683,6 +678,8 @@ cmdVolUpload(vshControl *ctl, const vshCmd *cmd)
|
||||
const char *name = NULL;
|
||||
unsigned long long offset = 0, length = 0;
|
||||
virshControlPtr priv = ctl->privData;
|
||||
unsigned int flags = 0;
|
||||
virshStreamCallbackData cbData;
|
||||
|
||||
if (vshCommandOptULongLong(ctl, cmd, "offset", &offset) < 0)
|
||||
return false;
|
||||
@ -701,19 +698,34 @@ cmdVolUpload(vshControl *ctl, const vshCmd *cmd)
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
cbData.ctl = ctl;
|
||||
cbData.fd = fd;
|
||||
|
||||
if (vshCommandOptBool(cmd, "sparse"))
|
||||
flags |= VIR_STORAGE_VOL_UPLOAD_SPARSE_STREAM;
|
||||
|
||||
if (!(st = virStreamNew(priv->conn, 0))) {
|
||||
vshError(ctl, _("cannot create a new stream"));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (virStorageVolUpload(vol, st, offset, length, 0) < 0) {
|
||||
if (virStorageVolUpload(vol, st, offset, length, flags) < 0) {
|
||||
vshError(ctl, _("cannot upload to volume %s"), name);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (virStreamSendAll(st, cmdVolUploadSource, &fd) < 0) {
|
||||
vshError(ctl, _("cannot send data to volume %s"), name);
|
||||
goto cleanup;
|
||||
if (flags & VIR_STORAGE_VOL_UPLOAD_SPARSE_STREAM) {
|
||||
if (virStreamSparseSendAll(st, virshStreamSource,
|
||||
virshStreamInData,
|
||||
virshStreamSourceSkip, &cbData) < 0) {
|
||||
vshError(ctl, _("cannot send data to volume %s"), name);
|
||||
goto cleanup;
|
||||
}
|
||||
} else {
|
||||
if (virStreamSendAll(st, virshStreamSource, &cbData) < 0) {
|
||||
vshError(ctl, _("cannot send data to volume %s"), name);
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
if (VIR_CLOSE(fd) < 0) {
|
||||
|
@ -3925,13 +3925,14 @@ the storage volume should be deleted as well. Not all storage drivers
|
||||
support this option, presently only rbd.
|
||||
|
||||
=item B<vol-upload> [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>
|
||||
|
||||
Upload the contents of I<local-file> to a storage volume.
|
||||
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 where the
|
||||
file will be uploaded.
|
||||
If I<--sparse> is specified, this command will preserve volume sparseness.
|
||||
I<--offset> is the position in the storage volume at which to start writing
|
||||
the data. The value must be 0 or larger. I<--length> is an upper bound
|
||||
of the amount of data to be uploaded. A negative value is interpreted
|
||||
|
Loading…
Reference in New Issue
Block a user