mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-30 16:35:24 +00:00
backup: Introduce virDomainBackup APIs
Introduce a few new public APIs related to incremental backups. This builds on the previous notion of a checkpoint (without an existing checkpoint, the new API is a full backup, differing from virDomainBlockCopy in the point of time chosen and in operation on multiple disks at once); and also allows creation of a new checkpoint at the same time as starting the backup (after all, an incremental backup is only useful if it covers the state since the previous backup). A backup job also affects filtering a listing of domains, as well as adding event reporting for signaling when a push model backup completes (where the hypervisor creates the backup); note that the pull model does not have an event (starting the backup lets a third party access the data, and only the third party knows when it is finished). The full list of new APIs: virDomainBackupBegin; virDomainBackupGetXMLDesc; Signed-off-by: Eric Blake <eblake@redhat.com> Signed-off-by: Peter Krempa <pkrempa@redhat.com> Reviewed-by: Daniel P. Berrangé <berrange@redhat.com> Reviewed-by: Ján Tomko <jtomko@redhat.com>
This commit is contained in:
parent
252958ee16
commit
74ca70507a
@ -4143,8 +4143,10 @@ typedef void (*virConnectDomainEventMigrationIterationCallback)(virConnectPtr co
|
||||
* @nparams: size of the params array
|
||||
* @opaque: application specific data
|
||||
*
|
||||
* This callback occurs when a job (such as migration) running on the domain
|
||||
* is completed. The params array will contain statistics of the just completed
|
||||
* This callback occurs when a job (such as migration or backup) running on
|
||||
* the domain is completed.
|
||||
*
|
||||
* The params array will contain statistics of the just completed
|
||||
* job as virDomainGetJobStats would return. The callback must not free @params
|
||||
* (the array will be freed once the callback finishes).
|
||||
*
|
||||
@ -4963,4 +4965,17 @@ int virDomainAgentSetResponseTimeout(virDomainPtr domain,
|
||||
int timeout,
|
||||
unsigned int flags);
|
||||
|
||||
typedef enum {
|
||||
VIR_DOMAIN_BACKUP_BEGIN_REUSE_EXTERNAL = (1 << 0), /* reuse separately
|
||||
provided images */
|
||||
} virDomainBackupBeginFlags;
|
||||
|
||||
int virDomainBackupBegin(virDomainPtr domain,
|
||||
const char *backupXML,
|
||||
const char *checkpointXML,
|
||||
unsigned int flags);
|
||||
|
||||
char *virDomainBackupGetXMLDesc(virDomainPtr domain,
|
||||
unsigned int flags);
|
||||
|
||||
#endif /* LIBVIRT_DOMAIN_H */
|
||||
|
@ -1377,6 +1377,16 @@ typedef int
|
||||
int timeout,
|
||||
unsigned int flags);
|
||||
|
||||
typedef int
|
||||
(*virDrvDomainBackupBegin)(virDomainPtr domain,
|
||||
const char *backupXML,
|
||||
const char *checkpointXML,
|
||||
unsigned int flags);
|
||||
|
||||
typedef char *
|
||||
(*virDrvDomainBackupGetXMLDesc)(virDomainPtr domain,
|
||||
unsigned int flags);
|
||||
|
||||
typedef struct _virHypervisorDriver virHypervisorDriver;
|
||||
typedef virHypervisorDriver *virHypervisorDriverPtr;
|
||||
|
||||
@ -1638,4 +1648,6 @@ struct _virHypervisorDriver {
|
||||
virDrvDomainCheckpointDelete domainCheckpointDelete;
|
||||
virDrvDomainGetGuestInfo domainGetGuestInfo;
|
||||
virDrvDomainAgentSetResponseTimeout domainAgentSetResponseTimeout;
|
||||
virDrvDomainBackupBegin domainBackupBegin;
|
||||
virDrvDomainBackupGetXMLDesc domainBackupGetXMLDesc;
|
||||
};
|
||||
|
@ -102,8 +102,11 @@ virDomainCheckpointGetConnect(virDomainCheckpointPtr checkpoint)
|
||||
* @flags: bitwise-OR of supported virDomainCheckpointCreateFlags
|
||||
*
|
||||
* Create a new checkpoint using @xmlDesc, with a top-level
|
||||
* <domaincheckpoint> element, on a running @domain. Note that @xmlDesc
|
||||
* must validate against the <domaincheckpoint> XML schema.
|
||||
* <domaincheckpoint> element, on a running @domain. Note that
|
||||
* @xmlDesc must validate against the <domaincheckpoint> XML schema.
|
||||
* Typically, it is more common to create a new checkpoint as part of
|
||||
* kicking off a backup job with virDomainBackupBegin(); however, it
|
||||
* is also possible to start a checkpoint without a backup.
|
||||
*
|
||||
* See <a href="formatcheckpoint.html#CheckpointAttributes">Checkpoint XML</a>
|
||||
* for more details on @xmlDesc. In particular, some hypervisors may require
|
||||
|
@ -12541,3 +12541,146 @@ virDomainAgentSetResponseTimeout(virDomainPtr domain,
|
||||
virDispatchError(conn);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* virDomainBackupBegin:
|
||||
* @domain: a domain object
|
||||
* @backupXML: description of the requested backup
|
||||
* @checkpointXML: description of a checkpoint to create or NULL
|
||||
* @flags: bitwise or of virDomainBackupBeginFlags
|
||||
*
|
||||
* Start a point-in-time backup job for the specified disks of a
|
||||
* running domain.
|
||||
*
|
||||
* A backup job is a domain job and thus mutually exclusive with any other
|
||||
* domain job such as migration.
|
||||
*
|
||||
* For now, backup jobs are also mutually exclusive with any
|
||||
* other block job on the same device, although this restriction may
|
||||
* be lifted in a future release. Progress of the backup job can be
|
||||
* tracked via virDomainGetJobStats(). Completion of the job is also announced
|
||||
* asynchronously via VIR_DOMAIN_EVENT_ID_JOB_COMPLETED event.
|
||||
*
|
||||
* There are two fundamental backup approaches. The first, called a
|
||||
* push model, instructs the hypervisor to copy the state of the guest
|
||||
* disk to the designated storage destination (which may be on the
|
||||
* local file system or a network device). In this mode, the
|
||||
* hypervisor writes the content of the guest disk to the destination,
|
||||
* then emits VIR_DOMAIN_EVENT_ID_JOB_COMPLETED when the backup is
|
||||
* either complete or failed (the backup image is invalid if the job
|
||||
* fails or virDomainAbortJob() is used prior to the event being
|
||||
* emitted). This kind of the job finishes automatically. Users can
|
||||
* determine success by using virDomainGetJobStats() with
|
||||
* VIR_DOMAIN_JOB_STATS_COMPLETED flag.
|
||||
*
|
||||
* The second, called a pull model, instructs the hypervisor to expose
|
||||
* the state of the guest disk over an NBD export. A third-party
|
||||
* client can then connect to this export and read whichever portions
|
||||
* of the disk it desires. In this mode libvirt has to be informed via
|
||||
* virDomainAbortJob() when the third-party NBD client is done and the backup
|
||||
* resources can be released.
|
||||
*
|
||||
* The @backupXML parameter contains details about the backup in the top-level
|
||||
* element <domainbackup>, including which backup mode to use, whether the
|
||||
* backup is incremental from a previous checkpoint, which disks
|
||||
* participate in the backup, the destination for a push model backup,
|
||||
* and the temporary storage and NBD server details for a pull model
|
||||
* backup.
|
||||
*
|
||||
* virDomainBackupGetXMLDesc() can be called to learn actual
|
||||
* values selected. For more information, see
|
||||
* formatcheckpoint.html#BackupAttributes.
|
||||
*
|
||||
* The @checkpointXML parameter is optional; if non-NULL, then libvirt
|
||||
* behaves as if virDomainCheckpointCreateXML() were called to create
|
||||
* a checkpoint atomically covering the same point in time as the
|
||||
* backup.
|
||||
*
|
||||
* The VIR_DOMAIN_BACKUP_BEGIN_REUSE_EXTERNAL specifies that the output or
|
||||
* temporary files described by the @backupXML document were created by the
|
||||
* caller with correct format and size to hold the backup or temporary data.
|
||||
*
|
||||
* The creation of a new checkpoint allows for future incremental backups.
|
||||
* Note that some hypervisors may require a particular disk format, such as
|
||||
* qcow2, in order to take advantage of checkpoints, while allowing arbitrary
|
||||
* formats if checkpoints are not involved.
|
||||
*
|
||||
* Returns 0 on success or -1 on failure.
|
||||
*/
|
||||
int
|
||||
virDomainBackupBegin(virDomainPtr domain,
|
||||
const char *backupXML,
|
||||
const char *checkpointXML,
|
||||
unsigned int flags)
|
||||
{
|
||||
virConnectPtr conn;
|
||||
|
||||
VIR_DOMAIN_DEBUG(domain, "backupXML=%s, checkpointXML=%s, flags=0x%x",
|
||||
NULLSTR(backupXML), NULLSTR(checkpointXML), flags);
|
||||
|
||||
virResetLastError();
|
||||
|
||||
virCheckDomainReturn(domain, -1);
|
||||
conn = domain->conn;
|
||||
|
||||
virCheckNonNullArgGoto(backupXML, error);
|
||||
virCheckReadOnlyGoto(conn->flags, error);
|
||||
|
||||
if (conn->driver->domainBackupBegin) {
|
||||
int ret;
|
||||
ret = conn->driver->domainBackupBegin(domain, backupXML, checkpointXML,
|
||||
flags);
|
||||
if (ret < 0)
|
||||
goto error;
|
||||
return ret;
|
||||
}
|
||||
|
||||
virReportUnsupportedError();
|
||||
error:
|
||||
virDispatchError(conn);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* virDomainBackupGetXMLDesc:
|
||||
* @domain: a domain object
|
||||
* @flags: extra flags; not used yet, so callers should always pass 0
|
||||
*
|
||||
* Queries the configuration of the active backup job.
|
||||
*
|
||||
* In some cases, a user can start a backup job without supplying all
|
||||
* details and rely on libvirt to fill in the rest (for example,
|
||||
* selecting the port used for an NBD export). This API can then be
|
||||
* used to learn what default values were chosen.
|
||||
*
|
||||
* Returns a NUL-terminated UTF-8 encoded XML instance or NULL in
|
||||
* case of error. The caller must free() the returned value.
|
||||
*/
|
||||
char *
|
||||
virDomainBackupGetXMLDesc(virDomainPtr domain,
|
||||
unsigned int flags)
|
||||
{
|
||||
virConnectPtr conn;
|
||||
|
||||
VIR_DOMAIN_DEBUG(domain, "flags=0x%x", flags);
|
||||
|
||||
virResetLastError();
|
||||
|
||||
virCheckDomainReturn(domain, NULL);
|
||||
conn = domain->conn;
|
||||
|
||||
if (conn->driver->domainBackupGetXMLDesc) {
|
||||
char *ret;
|
||||
ret = conn->driver->domainBackupGetXMLDesc(domain, flags);
|
||||
if (!ret)
|
||||
goto error;
|
||||
return ret;
|
||||
}
|
||||
|
||||
virReportUnsupportedError();
|
||||
error:
|
||||
virDispatchError(conn);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -867,4 +867,10 @@ LIBVIRT_5.10.0 {
|
||||
virDomainAgentSetResponseTimeout;
|
||||
} LIBVIRT_5.8.0;
|
||||
|
||||
LIBVIRT_6.0.0 {
|
||||
global:
|
||||
virDomainBackupBegin;
|
||||
virDomainBackupGetXMLDesc;
|
||||
} LIBVIRT_5.10.0;
|
||||
|
||||
# .... define new API here using predicted next version number ....
|
||||
|
Loading…
x
Reference in New Issue
Block a user