Re: [libvirt] [PATCH v3 31/31] virsh: Implement sparse stream to vol-upload

2017-05-17 Thread John Ferlan


On 05/16/2017 10:04 AM, Michal Privoznik wrote:
> 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 
> ---
>  tools/virsh-util.c   | 47 +++
>  tools/virsh-util.h   | 24 
>  tools/virsh-volume.c | 38 +-
>  tools/virsh.pod  |  3 ++-
>  4 files changed, 98 insertions(+), 14 deletions(-)
> 

Reviewed-by: John Ferlan 

John

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v3 31/31] virsh: Implement sparse stream to vol-upload

2017-05-16 Thread Michal Privoznik
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 
---
 tools/virsh-util.c   | 47 +++
 tools/virsh-util.h   | 24 
 tools/virsh-volume.c | 38 +-
 tools/virsh.pod  |  3 ++-
 4 files changed, 98 insertions(+), 14 deletions(-)

diff --git a/tools/virsh-util.c b/tools/virsh-util.c
index 198625bdb..44be3ad64 100644
--- a/tools/virsh-util.c
+++ b/tools/virsh-util.c
@@ -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)
 {
diff --git a/tools/virsh-util.h b/tools/virsh-util.h
index 0aba247f6..9a0af3513 100644
--- a/tools/virsh-util.h
+++ b/tools/virsh-util.h
@@ -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,
diff --git a/tools/virsh-volume.c b/tools/virsh-volume.c
index 3d19b745e..0736bdcdb 100644
--- a/tools/virsh-volume.c
+++ b/tools/virsh-volume.c
@@ -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_V