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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list