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 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 | 123 ++++++++++++++++++++++++++++++++++++++++++
src/libvirt_public.syms | 2 +
src/storage/storage_driver.c | 2 +
src/util/virterror.c | 6 ++
8 files changed, 160 insertions(+), 0 deletions(-)
diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index fcca39d..bd728f2 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -1500,6 +1500,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 1d8275b..59f7731 100644
--- a/include/libvirt/virterror.h
+++ b/include/libvirt/virterror.h
@@ -230,6 +230,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 f03d290..2ec8529 100644
--- a/src/driver.h
+++ b/src/driver.h
@@ -900,6 +900,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);
@@ -954,6 +966,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 33bb17c..e94c940 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -9065,6 +9065,129 @@ 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. If @length
+ * is zero, then the entire file contents will be downloaded.
+ *
+ * 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. If @length
+ * is non-zero, and an error will be raised if an attempt is
+ * made to upload greater than @length bytes of data.
+ *
+ * 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 160c953..b7d8924 100644
--- a/src/util/virterror.c
+++ b/src/util/virterror.c
@@ -1201,6 +1201,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");
+ else
+ errmsg = _("invalid stream pointer in %s");
+ break;
}
return (errmsg);
}
--
1.7.4