should take part in the backup and using ``no`` excludes the disk from
the backup.
+ ``backupmode``
+ This attribute overrides the implied backup mode inherited from the
+ definition of the backup itself. Value ``full`` forces a full backup
+ even if the backup calls for an incremental backup, and ``incremental``
+ coupled with the attribute ``incremental='CHECKPOINTNAME`` for the disk
+ forces an incremental backup from ``CHECKPOINTNAME``.
+
+ ``incremental``
+ An optional attribute giving the name of an existing checkpoint of the
+ domain which overrides the one set by the ``<incremental>`` element.
+
``exportname``
Allows modification of the NBD export name for the given disk. By
default equal to disk target. Valid only for pull mode backups.
</element>
</define>
+
+ <define name='backupDiskMode'>
+ <optional>
+ <choice>
+ <attribute name='backupmode'>
+ <value>full</value>
+ </attribute>
+ <group>
+ <optional>
+ <attribute name='backupmode'>
+ <value>incremental</value>
+ </attribute>
+ </optional>
+ <optional>
+ <attribute name='incremental'/>
+ </optional>
+ </group>
+ </choice>
+ </optional>
+ </define>
+
<define name='backupPushDriver'>
<optional>
<element name='driver'>
<attribute name='name'>
<ref name='diskTarget'/>
</attribute>
+ <ref name='backupDiskMode'/>
<choice>
<group>
<attribute name='backup'>
<attribute name='name'>
<ref name='diskTarget'/>
</attribute>
+ <ref name='backupDiskMode'/>
<optional>
<attribute name='exportname'>
<text/>
"cancelling",
"cancelled");
+VIR_ENUM_DECL(virDomainBackupDiskBackupMode);
+VIR_ENUM_IMPL(virDomainBackupDiskBackupMode,
+ VIR_DOMAIN_BACKUP_DISK_BACKUP_MODE_LAST,
+ "",
+ "full",
+ "incremental");
+
void
virDomainBackupDefFree(virDomainBackupDefPtr def)
{
g_autofree char *driver = NULL;
g_autofree char *backup = NULL;
g_autofree char *state = NULL;
+ g_autofree char *backupmode = NULL;
int tmp;
xmlNodePtr srcNode;
unsigned int storageSourceParseFlags = 0;
def->exportbitmap = virXMLPropString(node, "exportbitmap");
}
+ if ((backupmode = virXMLPropString(node, "backupmode"))) {
+ if ((tmp = virDomainBackupDiskBackupModeTypeFromString(backupmode)) < 0) {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("invalid backupmode '%s' of disk '%s'"),
+ backupmode, def->name);
+ return -1;
+ }
+
+ def->backupmode = tmp;
+ }
+
+ def->incremental = virXMLPropString(node, "incremental");
+
if (internal) {
if (!(state = virXMLPropString(node, "state")) ||
(tmp = virDomainBackupDiskStateTypeFromString(state)) < 0) {
if (disk->backup == VIR_TRISTATE_BOOL_YES) {
virBufferAsprintf(&attrBuf, " type='%s'", virStorageTypeToString(disk->store->type));
+ if (disk->backupmode != VIR_DOMAIN_BACKUP_DISK_BACKUP_MODE_DEFAULT) {
+ virBufferAsprintf(&attrBuf, " backupmode='%s'",
+ virDomainBackupDiskBackupModeTypeToString(disk->backupmode));
+ }
+
+ virBufferEscapeString(&attrBuf, " incremental='%s'", disk->incremental);
+
virBufferEscapeString(&attrBuf, " exportname='%s'", disk->exportname);
virBufferEscapeString(&attrBuf, " exportbitmap='%s'", disk->exportbitmap);
return -1;
}
+ if (backupdisk->backupmode == VIR_DOMAIN_BACKUP_DISK_BACKUP_MODE_INCREMENTAL &&
+ !backupdisk->incremental &&
+ !def->incremental) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("'incremental' backup mode of disk '%s' requires setting 'incremental' field for disk or backup"),
+ backupdisk->name);
+ return -1;
+ }
+
+
if (backupdisk->backup == VIR_TRISTATE_BOOL_YES &&
virDomainBackupDefAssignStore(backupdisk, domdisk->src, suffix) < 0)
return -1;
for (i = 0; i < def->ndisks; i++) {
virDomainBackupDiskDefPtr backupdisk = &def->disks[i];
- if (def->incremental && !backupdisk->incremental)
+ if (backupdisk->backupmode == VIR_DOMAIN_BACKUP_DISK_BACKUP_MODE_DEFAULT) {
+ if (def->incremental || backupdisk->incremental) {
+ backupdisk->backupmode = VIR_DOMAIN_BACKUP_DISK_BACKUP_MODE_INCREMENTAL;
+ } else {
+ backupdisk->backupmode = VIR_DOMAIN_BACKUP_DISK_BACKUP_MODE_FULL;
+ }
+ }
+
+ if (!backupdisk->incremental &&
+ backupdisk->backupmode == VIR_DOMAIN_BACKUP_DISK_BACKUP_MODE_INCREMENTAL)
backupdisk->incremental = g_strdup(def->incremental);
}
VIR_DOMAIN_BACKUP_DISK_STATE_LAST
} virDomainBackupDiskState;
+
+typedef enum {
+ VIR_DOMAIN_BACKUP_DISK_BACKUP_MODE_DEFAULT = 0,
+ VIR_DOMAIN_BACKUP_DISK_BACKUP_MODE_FULL,
+ VIR_DOMAIN_BACKUP_DISK_BACKUP_MODE_INCREMENTAL,
+
+ VIR_DOMAIN_BACKUP_DISK_BACKUP_MODE_LAST
+} virDomainBackupDiskBackupMode;
+
+
/* Stores disk-backup information */
typedef struct _virDomainBackupDiskDef virDomainBackupDiskDef;
typedef virDomainBackupDiskDef *virDomainBackupDiskDefPtr;
struct _virDomainBackupDiskDef {
char *name; /* name matching the <target dev='...' of the domain */
virTristateBool backup; /* whether backup is requested */
+ virDomainBackupDiskBackupMode backupmode;
char *incremental; /* name of the starting point checkpoint of an incremental backup */
char *exportname; /* name of the NBD export for pull mode backup */
char *exportbitmap; /* name of the bitmap exposed in NBD for pull mode backup */
<scratch file='/path/to/file'/>
</disk>
<disk name='hda' backup='no'/>
+ <disk name='vdc' type='file' backupmode='full'>
+ <scratch file='/path/to/file'/>
+ </disk>
+ <disk name='vdd' type='file' backupmode='incremental'>
+ <scratch file='/path/to/file'/>
+ </disk>
+ <disk name='vde' type='file' backupmode='incremental' incremental='blah'>
+ <scratch file='/path/to/file'/>
+ </disk>
+ <disk name='vdf' type='file' incremental='bleh'>
+ <scratch file='/path/to/file'/>
+ </disk>
</disks>
</domainbackup>
<incremental>1525889631</incremental>
<server transport='tcp' tls='yes' name='localhost' port='10809'/>
<disks>
- <disk name='vda' backup='yes' type='file' exportname='test-vda' exportbitmap='blah'>
+ <disk name='vda' backup='yes' type='file' backupmode='incremental' incremental='1525889631' exportname='test-vda' exportbitmap='blah'>
<driver type='qcow2'/>
<scratch file='/path/to/file'>
<encryption format='luks'>
</encryption>
</scratch>
</disk>
- <disk name='vdb' backup='yes' type='file' exportname='test-vda' exportbitmap='blah'>
+ <disk name='vdb' backup='yes' type='file' backupmode='incremental' incremental='1525889631' exportname='test-vda' exportbitmap='blah'>
<driver type='qcow2'/>
<scratch file='/path/to/file'>
<encryption format='luks'>
</encryption>
</scratch>
</disk>
- <disk name='vdc' backup='yes' type='block'>
+ <disk name='vdc' backup='yes' type='block' backupmode='incremental' incremental='1525889631'>
<driver type='qcow2'/>
<scratch dev='/dev/block'>
<encryption format='luks'>
<incremental>1525889631</incremental>
<server transport='tcp' tls='yes' name='localhost' port='10809'/>
<disks>
- <disk name='vda' backup='yes' state='running' type='file' exportname='test-vda' exportbitmap='blah'>
+ <disk name='vda' backup='yes' state='running' type='file' backupmode='incremental' incremental='1525889631' exportname='test-vda' exportbitmap='blah'>
<driver type='qcow2'/>
<scratch file='/path/to/file'>
<encryption format='luks'>
</encryption>
</scratch>
</disk>
- <disk name='vdb' backup='yes' state='complete' type='file' exportname='test-vda' exportbitmap='blah'>
+ <disk name='vdb' backup='yes' state='complete' type='file' backupmode='incremental' incremental='1525889631' exportname='test-vda' exportbitmap='blah'>
<driver type='qcow2'/>
<scratch file='/path/to/file'>
<encryption format='luks'>
</encryption>
</scratch>
</disk>
- <disk name='vdc' backup='yes' state='running' type='block'>
+ <disk name='vdc' backup='yes' state='running' type='block' backupmode='incremental' incremental='1525889631'>
<driver type='qcow2'/>
<scratch dev='/dev/block'>
<encryption format='luks'>
<incremental>1525889631</incremental>
<server transport='tcp' name='localhost' port='10809'/>
<disks>
- <disk name='vda' backup='yes' type='file' exportname='test-vda' exportbitmap='blah'>
+ <disk name='vda' backup='yes' type='file' backupmode='incremental' incremental='1525889631' exportname='test-vda' exportbitmap='blah'>
<driver type='qcow2'/>
<scratch file='/path/to/file'>
<seclabel model='dac' relabel='no'/>
</scratch>
</disk>
- <disk name='vdb' backup='yes' type='block'>
+ <disk name='vdb' backup='yes' type='block' backupmode='incremental' incremental='1525889631'>
<driver type='qcow2'/>
<scratch dev='/dev/block'>
<seclabel model='dac' relabel='no'/>
<incremental>1525889631</incremental>
<server transport='tcp' name='localhost' port='10809'/>
<disks>
- <disk name='vda' backup='yes' type='file'>
+ <disk name='vda' backup='yes' type='file' backupmode='incremental' incremental='1525889631'>
<scratch file='/path/to/file'/>
</disk>
<disk name='hda' backup='no'/>
+ <disk name='vdc' backup='yes' type='file' backupmode='full'>
+ <scratch file='/path/to/file'/>
+ </disk>
+ <disk name='vdd' backup='yes' type='file' backupmode='incremental' incremental='1525889631'>
+ <scratch file='/path/to/file'/>
+ </disk>
+ <disk name='vde' backup='yes' type='file' backupmode='incremental' incremental='blah'>
+ <scratch file='/path/to/file'/>
+ </disk>
+ <disk name='vdf' backup='yes' type='file' backupmode='incremental' incremental='bleh'>
+ <scratch file='/path/to/file'/>
+ </disk>
<disk name='vdextradisk' backup='no'/>
</disks>
</domainbackup>
<domainbackup mode='push'>
<incremental>1525889631</incremental>
<disks>
- <disk name='vda' backup='yes' type='file'>
+ <disk name='vda' backup='yes' type='file' backupmode='incremental' incremental='1525889631'>
<driver type='qcow2'/>
<target file='/path/to/file'>
<encryption format='luks'>
</encryption>
</target>
</disk>
- <disk name='vdb' backup='yes' type='file'>
+ <disk name='vdb' backup='yes' type='file' backupmode='incremental' incremental='1525889631'>
<driver type='raw'/>
<target file='/path/to/file'>
<encryption format='luks'>
</encryption>
</target>
</disk>
- <disk name='vdc' backup='yes' type='block'>
+ <disk name='vdc' backup='yes' type='block' backupmode='incremental' incremental='1525889631'>
<driver type='qcow2'/>
<target dev='/dev/block'>
<encryption format='luks'>
<domainbackup mode='push'>
<incremental>1525889631</incremental>
<disks>
- <disk name='vda' backup='yes' type='file'>
+ <disk name='vda' backup='yes' type='file' backupmode='incremental' incremental='1525889631'>
<driver type='raw'/>
<target file='/path/to/file'>
<seclabel model='dac' relabel='no'/>
</target>
</disk>
- <disk name='vdb' backup='yes' type='block'>
+ <disk name='vdb' backup='yes' type='block' backupmode='incremental' incremental='1525889631'>
<driver type='qcow2'/>
<target dev='/dev/block'>
<seclabel model='dac' relabel='no'/>
<domainbackup mode='push'>
<incremental>1525889631</incremental>
<disks>
- <disk name='vda' backup='yes' type='file'>
+ <disk name='vda' backup='yes' type='file' backupmode='incremental' incremental='1525889631'>
<driver type='raw'/>
<target file='/path/to/file'/>
</disk>
<domainbackup mode='push'>
<disks>
- <disk name='vdextradisk' backup='yes' type='file'>
+ <disk name='vdextradisk' backup='yes' type='file' backupmode='full'>
<target file='/fake/vdextradisk.qcow2.SUFFIX'/>
</disk>
</disks>