mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-10 05:17:59 +03:00
Add public APIs for storage volume upload/download
New APIs are added allowing streaming of content to/from storage volumes. * 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
This commit is contained in:
parent
e886237af5
commit
7300f68dff
@ -1504,6 +1504,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,
|
||||
|
@ -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;
|
||||
|
||||
/**
|
||||
|
14
src/driver.h
14
src/driver.h
@ -905,6 +905,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);
|
||||
@ -959,6 +971,8 @@ struct _virStorageDriver {
|
||||
virDrvStorageVolLookupByPath volLookupByPath;
|
||||
virDrvStorageVolCreateXML volCreateXML;
|
||||
virDrvStorageVolCreateXMLFrom volCreateXMLFrom;
|
||||
virDrvStorageVolDownload volDownload;
|
||||
virDrvStorageVolUpload volUpload;
|
||||
virDrvStorageVolDelete volDelete;
|
||||
virDrvStorageVolWipe volWipe;
|
||||
virDrvStorageVolGetInfo volGetInfo;
|
||||
|
@ -1671,6 +1671,8 @@ static virStorageDriver esxStorageDriver = {
|
||||
esxStorageVolumeLookupByPath, /* volLookupByPath */
|
||||
esxStorageVolumeCreateXML, /* volCreateXML */
|
||||
esxStorageVolumeCreateXMLFrom, /* volCreateXMLFrom */
|
||||
NULL, /* volDownload */
|
||||
NULL, /* volUpload */
|
||||
esxStorageVolumeDelete, /* volDelete */
|
||||
esxStorageVolumeWipe, /* volWipe */
|
||||
esxStorageVolumeGetInfo, /* volGetInfo */
|
||||
|
140
src/libvirt.c
140
src/libvirt.c
@ -9065,6 +9065,146 @@ error:
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* virStorageVolDownload:
|
||||
* @vol: pointer to volume to download from
|
||||
* @stream: stream to use as output
|
||||
* @offset: position in @vol to start reading from
|
||||
* @length: limit on amount of data to download
|
||||
* @flags: future flags (unused, pass 0)
|
||||
*
|
||||
* Download the content of the volume as a stream. If @length
|
||||
* is zero, then the remaining contents of the volume after
|
||||
* @offset will be downloaded.
|
||||
*
|
||||
* This call sets up an asynchronous stream; subsequent use of
|
||||
* stream APIs is necessary to transfer the actual data,
|
||||
* determine how much data is successfully transferred, and
|
||||
* detect any errors. The results will be unpredictable if
|
||||
* another active stream is writing to the storage volume.
|
||||
*
|
||||
* 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:
|
||||
* @vol: pointer to volume to upload
|
||||
* @stream: stream to use as input
|
||||
* @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. This call
|
||||
* will fail if @offset + @length exceeds the size of the
|
||||
* volume. Otherwise, if @length is non-zero, an error
|
||||
* will be raised if an attempt is made to upload greater
|
||||
* than @length bytes of data.
|
||||
*
|
||||
* This call sets up an asynchronous stream; subsequent use of
|
||||
* stream APIs is necessary to transfer the actual data,
|
||||
* determine how much data is successfully transferred, and
|
||||
* detect any errors. The results will be unpredictable if
|
||||
* another active stream is writing to the storage volume.
|
||||
*
|
||||
* 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
|
||||
|
@ -432,6 +432,8 @@ LIBVIRT_0.9.0 {
|
||||
virDomainSetMemoryFlags;
|
||||
virEventRegisterDefaultImpl;
|
||||
virEventRunDefaultImpl;
|
||||
virStorageVolDownload;
|
||||
virStorageVolUpload;
|
||||
} LIBVIRT_0.8.8;
|
||||
|
||||
# .... define new API here using predicted next version number ....
|
||||
|
@ -1989,6 +1989,8 @@ static virStorageDriver storageDriver = {
|
||||
.volLookupByPath = storageVolumeLookupByPath,
|
||||
.volCreateXML = storageVolumeCreateXML,
|
||||
.volCreateXMLFrom = storageVolumeCreateXMLFrom,
|
||||
.volDownload = NULL,
|
||||
.volUpload = NULL,
|
||||
.volDelete = storageVolumeDelete,
|
||||
.volWipe = storageVolumeWipe,
|
||||
.volGetInfo = storageVolumeGetInfo,
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user