[libvirt] [PATCH 2/5] Add public APIs for storage volume upload/download

Daniel P. Berrange berrange at redhat.com
Tue Mar 15 12:30:07 UTC 2011


New APIs are added allowing streaming of content to/from
storage volumes. A new API for creating volumes is also
added allowing the content to be provided immediately at
time of creation

* include/libvirt/libvirt.h.in: Add virStorageVolUpload and
  virStorageVolDownload, virStorageVolCreateUpload APIs
* src/driver.h, src/libvirt.c, src/libvirt_public.syms: Stub
  code for new APIs
* src/storage/storage_driver.c, src/esx/esx_storage_driver.c:
  Add dummy entries in driver table for new APIs
---
 include/libvirt/libvirt.h.in |   10 ++++
 include/libvirt/virterror.h  |    1 +
 src/driver.h                 |   14 +++++
 src/esx/esx_storage_driver.c |    2 +
 src/libvirt.c                |  120 ++++++++++++++++++++++++++++++++++++++++++
 src/libvirt_public.syms      |    2 +
 src/storage/storage_driver.c |    2 +
 src/util/virterror.c         |    6 ++
 8 files changed, 157 insertions(+), 0 deletions(-)

diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index eaeccd6..17ed09d 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -1499,6 +1499,16 @@ virStorageVolPtr        virStorageVolCreateXMLFrom      (virStoragePoolPtr pool,
                                                          const char *xmldesc,
                                                          virStorageVolPtr clonevol,
                                                          unsigned int flags);
+int                     virStorageVolDownload           (virStorageVolPtr vol,
+                                                         virStreamPtr stream,
+                                                         unsigned long long offset,
+                                                         unsigned long long length,
+                                                         unsigned int flags);
+int                     virStorageVolUpload             (virStorageVolPtr vol,
+                                                         virStreamPtr stream,
+                                                         unsigned long long offset,
+                                                         unsigned long long length,
+                                                         unsigned int flags);
 int                     virStorageVolDelete             (virStorageVolPtr vol,
                                                          unsigned int flags);
 int                     virStorageVolWipe               (virStorageVolPtr vol,
diff --git a/include/libvirt/virterror.h b/include/libvirt/virterror.h
index 6b8c789..64bdcec 100644
--- a/include/libvirt/virterror.h
+++ b/include/libvirt/virterror.h
@@ -229,6 +229,7 @@ typedef enum {
     VIR_ERR_HOOK_SCRIPT_FAILED = 70,	/* a synchronous hook script failed */
     VIR_ERR_INVALID_DOMAIN_SNAPSHOT = 71,/* invalid domain snapshot */
     VIR_ERR_NO_DOMAIN_SNAPSHOT = 72,	/* domain snapshot not found */
+    VIR_ERR_INVALID_STREAM = 73         /* stream pointer not valid */
 } virErrorNumber;
 
 /**
diff --git a/src/driver.h b/src/driver.h
index 6a83325..0ab23c0 100644
--- a/src/driver.h
+++ b/src/driver.h
@@ -899,6 +899,18 @@ typedef virStorageVolPtr
                                               const char *xmldesc,
                                               virStorageVolPtr clone,
                                               unsigned int flags);
+typedef int
+    (*virDrvStorageVolDownload) (virStorageVolPtr vol,
+                                 virStreamPtr stream,
+                                 unsigned long long offset,
+                                 unsigned long long length,
+                                 unsigned int flags);
+typedef int
+    (*virDrvStorageVolUpload) (virStorageVolPtr vol,
+                               virStreamPtr stream,
+                               unsigned long long offset,
+                               unsigned long long length,
+                               unsigned int flags);
 
 typedef int
         (*virDrvStoragePoolIsActive)(virStoragePoolPtr pool);
@@ -953,6 +965,8 @@ struct _virStorageDriver {
     virDrvStorageVolLookupByPath volLookupByPath;
     virDrvStorageVolCreateXML volCreateXML;
     virDrvStorageVolCreateXMLFrom volCreateXMLFrom;
+    virDrvStorageVolDownload volDownload;
+    virDrvStorageVolUpload volUpload;
     virDrvStorageVolDelete volDelete;
     virDrvStorageVolWipe volWipe;
     virDrvStorageVolGetInfo volGetInfo;
diff --git a/src/esx/esx_storage_driver.c b/src/esx/esx_storage_driver.c
index 136a90b..9e4dd9e 100644
--- a/src/esx/esx_storage_driver.c
+++ b/src/esx/esx_storage_driver.c
@@ -1671,6 +1671,8 @@ static virStorageDriver esxStorageDriver = {
     esxStorageVolumeLookupByPath,          /* volLookupByPath */
     esxStorageVolumeCreateXML,             /* volCreateXML */
     esxStorageVolumeCreateXMLFrom,         /* volCreateXMLFrom */
+    NULL, /* volDownload */
+    NULL, /* volUpload */
     esxStorageVolumeDelete,                /* volDelete */
     esxStorageVolumeWipe,                  /* volWipe */
     esxStorageVolumeGetInfo,               /* volGetInfo */
diff --git a/src/libvirt.c b/src/libvirt.c
index 713291f..77b9074 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -9059,6 +9059,126 @@ error:
 
 
 /**
+ * virStorageVolDownload:
+ * @pool: pointer to volume to download
+ * @stream: stream to use as output
+ * @offset: position to start reading from
+ * @length: limit on amount of data to download
+ * @flags: flags for creation (unused, pass 0)
+ *
+ * Download the content of the volume as a stream.
+ *
+ * Returns 0, or -1 upon error.
+ */
+int
+virStorageVolDownload(virStorageVolPtr vol,
+                      virStreamPtr stream,
+                      unsigned long long offset,
+                      unsigned long long length,
+                      unsigned int flags)
+{
+    VIR_DEBUG("vol=%p stream=%p offset=%llu length=%llu flags=%u", vol, stream, offset, length, flags);
+
+    virResetLastError();
+
+    if (!VIR_IS_STORAGE_VOL(vol)) {
+        virLibConnError(VIR_ERR_INVALID_STORAGE_VOL, __FUNCTION__);
+        return -1;
+    }
+
+    if (!VIR_IS_STREAM(stream)) {
+        virLibConnError(VIR_ERR_INVALID_STREAM, __FUNCTION__);
+        return -1;
+    }
+
+    if (vol->conn->flags & VIR_CONNECT_RO ||
+        stream->conn->flags & VIR_CONNECT_RO) {
+        virLibConnError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
+        goto error;
+    }
+
+    if (vol->conn->storageDriver &&
+        vol->conn->storageDriver->volDownload) {
+        int ret;
+        ret = vol->conn->storageDriver->volDownload(vol,
+                                                    stream,
+                                                    offset,
+                                                    length,
+                                                    flags);
+        if (ret < 0)
+            goto error;
+        return ret;
+    }
+
+    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+    virDispatchError(vol->conn);
+    return -1;
+}
+
+
+/**
+ * virStorageVolUpload:
+ * @pool: pointer to volume to download
+ * @stream: stream to use as output
+ * @offset: position to start writing to
+ * @length: limit on amount of data to upload
+ * @flags: flags for creation (unused, pass 0)
+ *
+ * Upload new content to the volume from a stream.
+ *
+ * Returns 0, or -1 upon error.
+ */
+int
+virStorageVolUpload(virStorageVolPtr vol,
+                    virStreamPtr stream,
+                    unsigned long long offset,
+                    unsigned long long length,
+                    unsigned int flags)
+{
+    VIR_DEBUG("vol=%p stream=%p offset=%llu length=%llu flags=%u", vol, stream, offset, length, flags);
+
+    virResetLastError();
+
+    if (!VIR_IS_STORAGE_VOL(vol)) {
+        virLibConnError(VIR_ERR_INVALID_STORAGE_VOL, __FUNCTION__);
+        return -1;
+    }
+
+    if (!VIR_IS_STREAM(stream)) {
+        virLibConnError(VIR_ERR_INVALID_STREAM, __FUNCTION__);
+        return -1;
+    }
+
+    if (vol->conn->flags & VIR_CONNECT_RO ||
+        stream->conn->flags & VIR_CONNECT_RO) {
+        virLibConnError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
+        goto error;
+    }
+
+    if (vol->conn->storageDriver &&
+        vol->conn->storageDriver->volUpload) {
+        int ret;
+        ret = vol->conn->storageDriver->volUpload(vol,
+                                                  stream,
+                                                  offset,
+                                                  length,
+                                                  flags);
+        if (ret < 0)
+            goto error;
+        return ret;
+    }
+
+    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+    virDispatchError(vol->conn);
+    return -1;
+}
+
+
+/**
  * virStorageVolDelete:
  * @vol: pointer to storage volume
  * @flags: future flags, use 0 for now
diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms
index c027bf7..dfe0196 100644
--- a/src/libvirt_public.syms
+++ b/src/libvirt_public.syms
@@ -431,6 +431,8 @@ LIBVIRT_0.9.0 {
         virDomainSetMemoryFlags;
         virEventRegisterDefaultImpl;
         virEventRunDefaultImpl;
+        virStorageVolDownload;
+        virStorageVolUpload;
 } LIBVIRT_0.8.8;
 
 # .... define new API here using predicted next version number ....
diff --git a/src/storage/storage_driver.c b/src/storage/storage_driver.c
index 5373025..ce528cf 100644
--- a/src/storage/storage_driver.c
+++ b/src/storage/storage_driver.c
@@ -1989,6 +1989,8 @@ static virStorageDriver storageDriver = {
     .volLookupByPath = storageVolumeLookupByPath,
     .volCreateXML = storageVolumeCreateXML,
     .volCreateXMLFrom = storageVolumeCreateXMLFrom,
+    .volDownload = NULL,
+    .volUpload = NULL,
     .volDelete = storageVolumeDelete,
     .volWipe = storageVolumeWipe,
     .volGetInfo = storageVolumeGetInfo,
diff --git a/src/util/virterror.c b/src/util/virterror.c
index f136054..dc00957 100644
--- a/src/util/virterror.c
+++ b/src/util/virterror.c
@@ -1198,6 +1198,12 @@ virErrorMsg(virErrorNumber error, const char *info)
             else
                 errmsg = _("Domain snapshot not found: %s");
             break;
+        case VIR_ERR_INVALID_STREAM:
+            if (info == NULL)
+                errmsg = _("invalid stream pointer in");
+            else
+                errmsg = _("invalid stream pointer in %s");
+            break;
     }
     return (errmsg);
 }
-- 
1.7.4




More information about the libvir-list mailing list