mirror of https://gitee.com/openkylin/libvirt.git
block rebase: add new API virDomainBlockRebase
Qemu is adding the ability to do a partial rebase. That is, given: base <- intermediate <- current virDomainBlockPull will produce: current but qemu now has the ability to leave base in the chain, to produce: base <- current Note that current qemu can only do a forward merge, and only with the current image as the destination, which is fully described by this API without flags. But in the future, it may be possible to enhance this API for additional scenarios by using flags: Merging the current image back into a previous image (that is, undoing a live snapshot), could be done by passing base as the destination and flags with a bit requesting a backward merge. Merging any other part of the image chain, whether forwards (the backing image contents are pulled into the newer file) or backwards (the deltas recorded in the newer file are merged back into the backing file), could also be done by passing a new flag that says that base should be treated as an XML snippet rather than an absolute path name, where the XML could then supply the additional instructions of which part of the image chain is being merged into any other part. * include/libvirt/libvirt.h.in (virDomainBlockRebase): New declaration. * src/libvirt.c (virDomainBlockRebase): Implement it. * src/libvirt_public.syms (LIBVIRT_0.9.10): Export it. * src/driver.h (virDrvDomainBlockRebase): New driver callback. * src/rpc/gendispatch.pl (long_legacy): Add exemption. * docs/apibuild.py (long_legacy_functions): Likewise.
This commit is contained in:
parent
21d13ddc5d
commit
99fd69c3de
|
@ -1649,6 +1649,7 @@ class CParser:
|
|||
"virDomainSetMemoryFlags" : (False, ("memory")),
|
||||
"virDomainBlockJobSetSpeed" : (False, ("bandwidth")),
|
||||
"virDomainBlockPull" : (False, ("bandwidth")),
|
||||
"virDomainBlockRebase" : (False, ("bandwidth")),
|
||||
"virDomainMigrateGetMaxSpeed" : (False, ("bandwidth")) }
|
||||
|
||||
def checkLongLegacyFunction(self, name, return_type, signature):
|
||||
|
|
|
@ -1888,7 +1888,8 @@ int virDomainUpdateDeviceFlags(virDomainPtr domain,
|
|||
/**
|
||||
* virDomainBlockJobType:
|
||||
*
|
||||
* VIR_DOMAIN_BLOCK_JOB_TYPE_PULL: Block Pull (virDomainBlockPull)
|
||||
* VIR_DOMAIN_BLOCK_JOB_TYPE_PULL: Block Pull (virDomainBlockPull or
|
||||
* virDomainBlockRebase)
|
||||
*/
|
||||
typedef enum {
|
||||
VIR_DOMAIN_BLOCK_JOB_TYPE_UNKNOWN = 0,
|
||||
|
@ -1927,6 +1928,9 @@ int virDomainBlockJobSetSpeed(virDomainPtr dom, const char *disk,
|
|||
|
||||
int virDomainBlockPull(virDomainPtr dom, const char *disk,
|
||||
unsigned long bandwidth, unsigned int flags);
|
||||
int virDomainBlockRebase(virDomainPtr dom, const char *disk,
|
||||
const char *base, unsigned long bandwidth,
|
||||
unsigned int flags);
|
||||
|
||||
|
||||
/* Block I/O throttling support */
|
||||
|
@ -3558,7 +3562,8 @@ typedef void (*virConnectDomainEventGraphicsCallback)(virConnectPtr conn,
|
|||
/**
|
||||
* virConnectDomainEventBlockJobStatus:
|
||||
*
|
||||
* The final status of a virDomainBlockPullAll() operation
|
||||
* The final status of a virDomainBlockPull() or virDomainBlockRebase()
|
||||
* operation
|
||||
*/
|
||||
typedef enum {
|
||||
VIR_DOMAIN_BLOCK_JOB_COMPLETED = 0,
|
||||
|
|
|
@ -780,6 +780,10 @@ typedef int
|
|||
typedef int
|
||||
(*virDrvDomainBlockPull)(virDomainPtr dom, const char *path,
|
||||
unsigned long bandwidth, unsigned int flags);
|
||||
typedef int
|
||||
(*virDrvDomainBlockRebase)(virDomainPtr dom, const char *path,
|
||||
const char *base, unsigned long bandwidth,
|
||||
unsigned int flags);
|
||||
|
||||
typedef int
|
||||
(*virDrvSetKeepAlive)(virConnectPtr conn,
|
||||
|
@ -995,6 +999,7 @@ struct _virDriver {
|
|||
virDrvDomainGetBlockJobInfo domainGetBlockJobInfo;
|
||||
virDrvDomainBlockJobSetSpeed domainBlockJobSetSpeed;
|
||||
virDrvDomainBlockPull domainBlockPull;
|
||||
virDrvDomainBlockRebase domainBlockRebase;
|
||||
virDrvSetKeepAlive setKeepAlive;
|
||||
virDrvConnectIsAlive isAlive;
|
||||
virDrvNodeSuspendForDuration nodeSuspendForDuration;
|
||||
|
|
|
@ -17768,7 +17768,7 @@ int virDomainBlockJobAbort(virDomainPtr dom, const char *disk,
|
|||
{
|
||||
virConnectPtr conn;
|
||||
|
||||
VIR_DOMAIN_DEBUG(dom, "disk=%p, flags=%x", disk, flags);
|
||||
VIR_DOMAIN_DEBUG(dom, "disk=%s, flags=%x", disk, flags);
|
||||
|
||||
virResetLastError();
|
||||
|
||||
|
@ -17829,7 +17829,7 @@ int virDomainGetBlockJobInfo(virDomainPtr dom, const char *disk,
|
|||
{
|
||||
virConnectPtr conn;
|
||||
|
||||
VIR_DOMAIN_DEBUG(dom, "disk=%p, info=%p, flags=%x", disk, info, flags);
|
||||
VIR_DOMAIN_DEBUG(dom, "disk=%s, info=%p, flags=%x", disk, info, flags);
|
||||
|
||||
virResetLastError();
|
||||
|
||||
|
@ -17891,7 +17891,7 @@ int virDomainBlockJobSetSpeed(virDomainPtr dom, const char *disk,
|
|||
{
|
||||
virConnectPtr conn;
|
||||
|
||||
VIR_DOMAIN_DEBUG(dom, "disk=%p, bandwidth=%lu, flags=%x",
|
||||
VIR_DOMAIN_DEBUG(dom, "disk=%s, bandwidth=%lu, flags=%x",
|
||||
disk, bandwidth, flags);
|
||||
|
||||
virResetLastError();
|
||||
|
@ -17955,6 +17955,8 @@ error:
|
|||
* suitable default. Some hypervisors do not support this feature and will
|
||||
* return an error if bandwidth is not 0.
|
||||
*
|
||||
* This is shorthand for virDomainBlockRebase() with a NULL base.
|
||||
*
|
||||
* Returns 0 if the operation has started, -1 on failure.
|
||||
*/
|
||||
int virDomainBlockPull(virDomainPtr dom, const char *disk,
|
||||
|
@ -17962,7 +17964,7 @@ int virDomainBlockPull(virDomainPtr dom, const char *disk,
|
|||
{
|
||||
virConnectPtr conn;
|
||||
|
||||
VIR_DOMAIN_DEBUG(dom, "disk=%p, bandwidth=%lu, flags=%x",
|
||||
VIR_DOMAIN_DEBUG(dom, "disk=%s, bandwidth=%lu, flags=%x",
|
||||
disk, bandwidth, flags);
|
||||
|
||||
virResetLastError();
|
||||
|
@ -18001,6 +18003,88 @@ error:
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* virDomainBlockRebase:
|
||||
* @dom: pointer to domain object
|
||||
* @disk: path to the block device, or device shorthand
|
||||
* @base: path to backing file to keep, or NULL for no backing file
|
||||
* @bandwidth: (optional) specify copy bandwidth limit in Mbps
|
||||
* @flags: extra flags; not used yet, so callers should always pass 0
|
||||
*
|
||||
* Populate a disk image with data from its backing image chain, and
|
||||
* setting the backing image to @base. @base must be the absolute
|
||||
* path of one of the backing images further up the chain, or NULL to
|
||||
* convert the disk image so that it has no backing image. Once all
|
||||
* data from its backing image chain has been pulled, the disk no
|
||||
* longer depends on those intermediate backing images. This function
|
||||
* pulls data for the entire device in the background. Progress of
|
||||
* the operation can be checked with virDomainGetBlockJobInfo() and
|
||||
* the operation can be aborted with virDomainBlockJobAbort(). When
|
||||
* finished, an asynchronous event is raised to indicate the final
|
||||
* status.
|
||||
*
|
||||
* The @disk parameter is either an unambiguous source name of the
|
||||
* block device (the <source file='...'/> sub-element, such as
|
||||
* "/path/to/image"), or the device target shorthand (the
|
||||
* <target dev='...'/> sub-element, such as "xvda"). Valid names
|
||||
* can be found by calling virDomainGetXMLDesc() and inspecting
|
||||
* elements within //domain/devices/disk.
|
||||
*
|
||||
* The maximum bandwidth (in Mbps) that will be used to do the copy can be
|
||||
* specified with the bandwidth parameter. If set to 0, libvirt will choose a
|
||||
* suitable default. Some hypervisors do not support this feature and will
|
||||
* return an error if bandwidth is not 0.
|
||||
*
|
||||
* When @base is NULL, this is identical to virDomainBlockPull().
|
||||
*
|
||||
* Returns 0 if the operation has started, -1 on failure.
|
||||
*/
|
||||
int virDomainBlockRebase(virDomainPtr dom, const char *disk,
|
||||
const char *base, unsigned long bandwidth,
|
||||
unsigned int flags)
|
||||
{
|
||||
virConnectPtr conn;
|
||||
|
||||
VIR_DOMAIN_DEBUG(dom, "disk=%s, base=%s bandwidth=%lu, flags=%x",
|
||||
disk, NULLSTR(base), bandwidth, flags);
|
||||
|
||||
virResetLastError();
|
||||
|
||||
if (!VIR_IS_CONNECTED_DOMAIN (dom)) {
|
||||
virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
|
||||
virDispatchError(NULL);
|
||||
return -1;
|
||||
}
|
||||
conn = dom->conn;
|
||||
|
||||
if (dom->conn->flags & VIR_CONNECT_RO) {
|
||||
virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (!disk) {
|
||||
virLibDomainError(VIR_ERR_INVALID_ARG,
|
||||
_("disk is NULL"));
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (conn->driver->domainBlockRebase) {
|
||||
int ret;
|
||||
ret = conn->driver->domainBlockRebase(dom, disk, base, bandwidth,
|
||||
flags);
|
||||
if (ret < 0)
|
||||
goto error;
|
||||
return ret;
|
||||
}
|
||||
|
||||
virLibDomainError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
|
||||
|
||||
error:
|
||||
virDispatchError(dom->conn);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* virDomainOpenGraphics:
|
||||
* @dom: pointer to domain object
|
||||
|
@ -18208,7 +18292,7 @@ int virDomainSetBlockIoTune(virDomainPtr dom,
|
|||
{
|
||||
virConnectPtr conn;
|
||||
|
||||
VIR_DOMAIN_DEBUG(dom, "disk=%p, params=%p, nparams=%d, flags=%x",
|
||||
VIR_DOMAIN_DEBUG(dom, "disk=%s, params=%p, nparams=%d, flags=%x",
|
||||
disk, params, nparams, flags);
|
||||
|
||||
virResetLastError();
|
||||
|
@ -18290,7 +18374,7 @@ int virDomainGetBlockIoTune(virDomainPtr dom,
|
|||
{
|
||||
virConnectPtr conn;
|
||||
|
||||
VIR_DOMAIN_DEBUG(dom, "disk=%p, params=%p, nparams=%d, flags=%x",
|
||||
VIR_DOMAIN_DEBUG(dom, "disk=%s, params=%p, nparams=%d, flags=%x",
|
||||
NULLSTR(disk), params, (nparams) ? *nparams : -1, flags);
|
||||
|
||||
virResetLastError();
|
||||
|
|
|
@ -518,6 +518,7 @@ LIBVIRT_0.9.9 {
|
|||
|
||||
LIBVIRT_0.9.10 {
|
||||
global:
|
||||
virDomainBlockRebase;
|
||||
virDomainGetCPUStats;
|
||||
virDomainGetDiskErrors;
|
||||
virDomainGetMetadata;
|
||||
|
|
|
@ -232,6 +232,7 @@ my $long_legacy = {
|
|||
GetVersion => { ret => { hv_ver => 1 } },
|
||||
NodeGetInfo => { ret => { memory => 1 } },
|
||||
DomainBlockPull => { arg => { bandwidth => 1 } },
|
||||
DomainBlockRebase => { arg => { bandwidth => 1 } },
|
||||
DomainBlockJobSetSpeed => { arg => { bandwidth => 1 } },
|
||||
DomainMigrateGetMaxSpeed => { ret => { bandwidth => 1 } },
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue