mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-02-01 17:35:17 +00:00
blockcommit: track job type in xml
A future patch is going to wire up qemu active block commit jobs; but as they have similar events and are canceled/pivoted in the same way as block copy jobs, it is easiest to track all bookkeeping for the commit job by reusing the <mirror> element. This patch adds domain XML to track which job was responsible for creating a mirroring situation, and adds a job='copy' attribute to all existing uses of <mirror>. Along the way, it also massages the qemu monitor backend to read the new field in order to generate the correct type of libvirt job (even though it requires a future patch to actually cause a qemu event that can be reported as an active commit). It also prepares to update persistent XML to match changes made to live XML when a copy completes. * docs/schemas/domaincommon.rng: Enhance schema. * docs/formatdomain.html.in: Document it. * src/conf/domain_conf.h (_virDomainDiskDef): Add a field. * src/conf/domain_conf.c (virDomainBlockJobType): String conversion. (virDomainDiskDefParseXML): Parse job type. (virDomainDiskDefFormat): Output job type. * src/qemu/qemu_process.c (qemuProcessHandleBlockJob): Distinguish active from regular commit. * src/qemu/qemu_driver.c (qemuDomainBlockCopy): Set job type. (qemuDomainBlockPivot, qemuDomainBlockJobImpl): Clean up job type on completion. * tests/qemuxml2xmloutdata/qemuxml2xmlout-disk-mirror-old.xml: Update tests. * tests/qemuxml2argvdata/qemuxml2argv-disk-mirror.xml: Likewise. * tests/qemuxml2argvdata/qemuxml2argv-disk-active-commit.xml: New file. * tests/qemuxml2xmltest.c (mymain): Drive new test. Signed-off-by: Eric Blake <eblake@redhat.com>
This commit is contained in:
parent
251d75a863
commit
232a31bea3
@ -1913,16 +1913,19 @@
|
|||||||
</dd>
|
</dd>
|
||||||
<dt><code>mirror</code></dt>
|
<dt><code>mirror</code></dt>
|
||||||
<dd>
|
<dd>
|
||||||
This element is present if the hypervisor has started a block
|
This element is present if the hypervisor has started a
|
||||||
copy operation (via the <code>virDomainBlockRebase</code>
|
long-running block job operation, where the mirror location in
|
||||||
API), where the mirror location in the <code>source</code>
|
the <code>source</code> sub-element will eventually have the
|
||||||
sub-element will eventually have the same contents as the
|
same contents as the source, and with the file format in the
|
||||||
source, and with the file format in the
|
|
||||||
sub-element <code>format</code> (which might differ from the
|
sub-element <code>format</code> (which might differ from the
|
||||||
format of the source). The details of the <code>source</code>
|
format of the source). The details of the <code>source</code>
|
||||||
sub-element are determined by the <code>type</code> attribute
|
sub-element are determined by the <code>type</code> attribute
|
||||||
of the mirror, similar to what is done for the
|
of the mirror, similar to what is done for the
|
||||||
overall <code>disk</code> device element. The
|
overall <code>disk</code> device element. The <code>job</code>
|
||||||
|
attribute mentions which API started the operation ("copy" for
|
||||||
|
the <code>virDomainBlockRebase</code> API, or "active-commit"
|
||||||
|
for the <code>virDomainBlockCommit</code>
|
||||||
|
API), <span class="since">since 1.2.7</span>. The
|
||||||
attribute <code>ready</code>, if present, tracks progress of
|
attribute <code>ready</code>, if present, tracks progress of
|
||||||
the job: <code>yes</code> if the disk is known to be ready to
|
the job: <code>yes</code> if the disk is known to be ready to
|
||||||
pivot, or, <span class="since">since
|
pivot, or, <span class="since">since
|
||||||
|
@ -4289,6 +4289,13 @@
|
|||||||
<ref name='storageFormat'/>
|
<ref name='storageFormat'/>
|
||||||
</attribute>
|
</attribute>
|
||||||
</optional>
|
</optional>
|
||||||
|
<optional>
|
||||||
|
<attribute name='job'>
|
||||||
|
<choice>
|
||||||
|
<value>copy</value>
|
||||||
|
</choice>
|
||||||
|
</attribute>
|
||||||
|
</optional>
|
||||||
<optional>
|
<optional>
|
||||||
<interleave>
|
<interleave>
|
||||||
<ref name='diskSourceFile'/>
|
<ref name='diskSourceFile'/>
|
||||||
@ -4299,6 +4306,12 @@
|
|||||||
</optional>
|
</optional>
|
||||||
</group>
|
</group>
|
||||||
<group> <!-- preferred format -->
|
<group> <!-- preferred format -->
|
||||||
|
<attribute name='job'>
|
||||||
|
<choice>
|
||||||
|
<value>copy</value>
|
||||||
|
<value>active-commit</value>
|
||||||
|
</choice>
|
||||||
|
</attribute>
|
||||||
<interleave>
|
<interleave>
|
||||||
<ref name="diskSource"/>
|
<ref name="diskSource"/>
|
||||||
<optional>
|
<optional>
|
||||||
|
@ -753,6 +753,12 @@ VIR_ENUM_IMPL(virDomainDiskMirrorState, VIR_DOMAIN_DISK_MIRROR_STATE_LAST,
|
|||||||
"abort",
|
"abort",
|
||||||
"pivot")
|
"pivot")
|
||||||
|
|
||||||
|
/* Internal mapping: subset of block job types that can be present in
|
||||||
|
* <mirror> XML (remaining types are not two-phase). */
|
||||||
|
VIR_ENUM_DECL(virDomainBlockJob)
|
||||||
|
VIR_ENUM_IMPL(virDomainBlockJob, VIR_DOMAIN_BLOCK_JOB_TYPE_LAST,
|
||||||
|
"", "", "copy", "", "active-commit")
|
||||||
|
|
||||||
#define VIR_DOMAIN_XML_WRITE_FLAGS VIR_DOMAIN_XML_SECURE
|
#define VIR_DOMAIN_XML_WRITE_FLAGS VIR_DOMAIN_XML_SECURE
|
||||||
#define VIR_DOMAIN_XML_READ_FLAGS VIR_DOMAIN_XML_INACTIVE
|
#define VIR_DOMAIN_XML_READ_FLAGS VIR_DOMAIN_XML_INACTIVE
|
||||||
|
|
||||||
@ -5437,10 +5443,26 @@ virDomainDiskDefParseXML(virDomainXMLOptionPtr xmlopt,
|
|||||||
xmlStrEqual(cur->name, BAD_CAST "mirror") &&
|
xmlStrEqual(cur->name, BAD_CAST "mirror") &&
|
||||||
!(flags & VIR_DOMAIN_XML_INACTIVE)) {
|
!(flags & VIR_DOMAIN_XML_INACTIVE)) {
|
||||||
char *ready;
|
char *ready;
|
||||||
|
char *blockJob;
|
||||||
|
|
||||||
if (VIR_ALLOC(def->mirror) < 0)
|
if (VIR_ALLOC(def->mirror) < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
blockJob = virXMLPropString(cur, "job");
|
||||||
|
if (blockJob) {
|
||||||
|
def->mirrorJob = virDomainBlockJobTypeFromString(blockJob);
|
||||||
|
if (def->mirrorJob <= 0) {
|
||||||
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
||||||
|
_("unknown mirror job type '%s'"),
|
||||||
|
blockJob);
|
||||||
|
VIR_FREE(blockJob);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
VIR_FREE(blockJob);
|
||||||
|
} else {
|
||||||
|
def->mirrorJob = VIR_DOMAIN_BLOCK_JOB_TYPE_COPY;
|
||||||
|
}
|
||||||
|
|
||||||
mirrorType = virXMLPropString(cur, "type");
|
mirrorType = virXMLPropString(cur, "type");
|
||||||
if (mirrorType) {
|
if (mirrorType) {
|
||||||
def->mirror->type = virStorageTypeFromString(mirrorType);
|
def->mirror->type = virStorageTypeFromString(mirrorType);
|
||||||
@ -5463,6 +5485,12 @@ virDomainDiskDefParseXML(virDomainXMLOptionPtr xmlopt,
|
|||||||
_("mirror requires file name"));
|
_("mirror requires file name"));
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
if (def->mirrorJob != VIR_DOMAIN_BLOCK_JOB_TYPE_COPY) {
|
||||||
|
virReportError(VIR_ERR_XML_ERROR, "%s",
|
||||||
|
_("mirror without type only supported "
|
||||||
|
"by copy job"));
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
mirrorFormat = virXMLPropString(cur, "format");
|
mirrorFormat = virXMLPropString(cur, "format");
|
||||||
}
|
}
|
||||||
if (mirrorFormat) {
|
if (mirrorFormat) {
|
||||||
@ -15401,10 +15429,13 @@ virDomainDiskDefFormat(virBufferPtr buf,
|
|||||||
formatStr = virStorageFileFormatTypeToString(def->mirror->format);
|
formatStr = virStorageFileFormatTypeToString(def->mirror->format);
|
||||||
virBufferAsprintf(buf, "<mirror type='%s'",
|
virBufferAsprintf(buf, "<mirror type='%s'",
|
||||||
virStorageTypeToString(def->mirror->type));
|
virStorageTypeToString(def->mirror->type));
|
||||||
if (def->mirror->type == VIR_STORAGE_TYPE_FILE) {
|
if (def->mirror->type == VIR_STORAGE_TYPE_FILE &&
|
||||||
|
def->mirrorJob == VIR_DOMAIN_BLOCK_JOB_TYPE_COPY) {
|
||||||
virBufferEscapeString(buf, " file='%s'", def->mirror->path);
|
virBufferEscapeString(buf, " file='%s'", def->mirror->path);
|
||||||
virBufferEscapeString(buf, " format='%s'", formatStr);
|
virBufferEscapeString(buf, " format='%s'", formatStr);
|
||||||
}
|
}
|
||||||
|
virBufferEscapeString(buf, " job='%s'",
|
||||||
|
virDomainBlockJobTypeToString(def->mirrorJob));
|
||||||
if (def->mirrorState) {
|
if (def->mirrorState) {
|
||||||
const char *mirror;
|
const char *mirror;
|
||||||
|
|
||||||
|
@ -632,6 +632,7 @@ struct _virDomainDiskDef {
|
|||||||
|
|
||||||
virStorageSourcePtr mirror;
|
virStorageSourcePtr mirror;
|
||||||
int mirrorState; /* enum virDomainDiskMirrorState */
|
int mirrorState; /* enum virDomainDiskMirrorState */
|
||||||
|
int mirrorJob; /* virDomainBlockJobType */
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
unsigned int cylinders;
|
unsigned int cylinders;
|
||||||
|
@ -14938,6 +14938,7 @@ qemuDomainBlockPivot(virConnectPtr conn,
|
|||||||
virStorageSourceFree(disk->mirror);
|
virStorageSourceFree(disk->mirror);
|
||||||
disk->mirror = NULL;
|
disk->mirror = NULL;
|
||||||
disk->mirrorState = VIR_DOMAIN_DISK_MIRROR_STATE_NONE;
|
disk->mirrorState = VIR_DOMAIN_DISK_MIRROR_STATE_NONE;
|
||||||
|
disk->mirrorJob = VIR_DOMAIN_BLOCK_JOB_TYPE_UNKNOWN;
|
||||||
}
|
}
|
||||||
if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm) < 0)
|
if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm) < 0)
|
||||||
ret = -1;
|
ret = -1;
|
||||||
@ -15413,6 +15414,7 @@ qemuDomainBlockCopy(virDomainObjPtr vm,
|
|||||||
need_unlink = false;
|
need_unlink = false;
|
||||||
disk->mirror = mirror;
|
disk->mirror = mirror;
|
||||||
mirror = NULL;
|
mirror = NULL;
|
||||||
|
disk->mirrorJob = VIR_DOMAIN_BLOCK_JOB_TYPE_COPY;
|
||||||
|
|
||||||
if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm) < 0)
|
if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm) < 0)
|
||||||
VIR_WARN("Unable to save status on vm %s after state change",
|
VIR_WARN("Unable to save status on vm %s after state change",
|
||||||
|
@ -1017,6 +1017,7 @@ qemuProcessHandleBlockJob(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
|
|||||||
const char *path;
|
const char *path;
|
||||||
virDomainDiskDefPtr disk;
|
virDomainDiskDefPtr disk;
|
||||||
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
|
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
|
||||||
|
virDomainDiskDefPtr persistDisk = NULL;
|
||||||
bool save = false;
|
bool save = false;
|
||||||
|
|
||||||
virObjectLock(vm);
|
virObjectLock(vm);
|
||||||
@ -1025,6 +1026,9 @@ qemuProcessHandleBlockJob(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
|
|||||||
if (disk) {
|
if (disk) {
|
||||||
/* Have to generate two variants of the event for old vs. new
|
/* Have to generate two variants of the event for old vs. new
|
||||||
* client callbacks */
|
* client callbacks */
|
||||||
|
if (type == VIR_DOMAIN_BLOCK_JOB_TYPE_COMMIT &&
|
||||||
|
disk->mirrorJob == VIR_DOMAIN_BLOCK_JOB_TYPE_ACTIVE_COMMIT)
|
||||||
|
type = disk->mirrorJob;
|
||||||
path = virDomainDiskGetSource(disk);
|
path = virDomainDiskGetSource(disk);
|
||||||
event = virDomainEventBlockJobNewFromObj(vm, path, type, status);
|
event = virDomainEventBlockJobNewFromObj(vm, path, type, status);
|
||||||
event2 = virDomainEventBlockJob2NewFromObj(vm, disk->dst, type,
|
event2 = virDomainEventBlockJob2NewFromObj(vm, disk->dst, type,
|
||||||
@ -1034,6 +1038,31 @@ qemuProcessHandleBlockJob(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
|
|||||||
* to match. */
|
* to match. */
|
||||||
if (status == VIR_DOMAIN_BLOCK_JOB_COMPLETED) {
|
if (status == VIR_DOMAIN_BLOCK_JOB_COMPLETED) {
|
||||||
if (disk->mirrorState == VIR_DOMAIN_DISK_MIRROR_STATE_PIVOT) {
|
if (disk->mirrorState == VIR_DOMAIN_DISK_MIRROR_STATE_PIVOT) {
|
||||||
|
if (vm->newDef) {
|
||||||
|
int indx = virDomainDiskIndexByName(vm->newDef, disk->dst,
|
||||||
|
false);
|
||||||
|
virStorageSourcePtr copy = NULL;
|
||||||
|
|
||||||
|
if (indx >= 0) {
|
||||||
|
persistDisk = vm->newDef->disks[indx];
|
||||||
|
copy = virStorageSourceCopy(disk->mirror, false);
|
||||||
|
if (virStorageSourceInitChainElement(copy,
|
||||||
|
persistDisk->src,
|
||||||
|
false) < 0) {
|
||||||
|
VIR_WARN("Unable to update persistent definition "
|
||||||
|
"on vm %s after block job",
|
||||||
|
vm->def->name);
|
||||||
|
virStorageSourceFree(copy);
|
||||||
|
copy = NULL;
|
||||||
|
persistDisk = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (copy) {
|
||||||
|
virStorageSourceFree(persistDisk->src);
|
||||||
|
persistDisk->src = copy;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* XXX We want to revoke security labels and disk
|
/* XXX We want to revoke security labels and disk
|
||||||
* lease, as well as audit that revocation, before
|
* lease, as well as audit that revocation, before
|
||||||
* dropping the original source. But it gets tricky
|
* dropping the original source. But it gets tricky
|
||||||
@ -1054,8 +1083,11 @@ qemuProcessHandleBlockJob(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
|
|||||||
disk->mirror = NULL;
|
disk->mirror = NULL;
|
||||||
save = disk->mirrorState != VIR_DOMAIN_DISK_MIRROR_STATE_NONE;
|
save = disk->mirrorState != VIR_DOMAIN_DISK_MIRROR_STATE_NONE;
|
||||||
disk->mirrorState = VIR_DOMAIN_DISK_MIRROR_STATE_NONE;
|
disk->mirrorState = VIR_DOMAIN_DISK_MIRROR_STATE_NONE;
|
||||||
|
disk->mirrorJob = VIR_DOMAIN_BLOCK_JOB_TYPE_UNKNOWN;
|
||||||
qemuDomainDetermineDiskChain(driver, vm, disk, true);
|
qemuDomainDetermineDiskChain(driver, vm, disk, true);
|
||||||
} else if (disk->mirror && type == VIR_DOMAIN_BLOCK_JOB_TYPE_COPY) {
|
} else if (disk->mirror &&
|
||||||
|
(type == VIR_DOMAIN_BLOCK_JOB_TYPE_COPY ||
|
||||||
|
type == VIR_DOMAIN_BLOCK_JOB_TYPE_ACTIVE_COMMIT)) {
|
||||||
if (status == VIR_DOMAIN_BLOCK_JOB_READY) {
|
if (status == VIR_DOMAIN_BLOCK_JOB_READY) {
|
||||||
disk->mirrorState = VIR_DOMAIN_DISK_MIRROR_STATE_READY;
|
disk->mirrorState = VIR_DOMAIN_DISK_MIRROR_STATE_READY;
|
||||||
save = true;
|
save = true;
|
||||||
@ -1063,6 +1095,7 @@ qemuProcessHandleBlockJob(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
|
|||||||
virStorageSourceFree(disk->mirror);
|
virStorageSourceFree(disk->mirror);
|
||||||
disk->mirror = NULL;
|
disk->mirror = NULL;
|
||||||
disk->mirrorState = VIR_DOMAIN_DISK_MIRROR_STATE_NONE;
|
disk->mirrorState = VIR_DOMAIN_DISK_MIRROR_STATE_NONE;
|
||||||
|
disk->mirrorJob = VIR_DOMAIN_BLOCK_JOB_TYPE_UNKNOWN;
|
||||||
save = true;
|
save = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1072,6 +1105,10 @@ qemuProcessHandleBlockJob(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
|
|||||||
if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm) < 0)
|
if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm) < 0)
|
||||||
VIR_WARN("Unable to save status on vm %s after block job",
|
VIR_WARN("Unable to save status on vm %s after block job",
|
||||||
vm->def->name);
|
vm->def->name);
|
||||||
|
if (persistDisk && virDomainSaveConfig(cfg->configDir,
|
||||||
|
vm->newDef) < 0)
|
||||||
|
VIR_WARN("Unable to update persistent definition on vm %s "
|
||||||
|
"after block job", vm->def->name);
|
||||||
}
|
}
|
||||||
virObjectUnlock(vm);
|
virObjectUnlock(vm);
|
||||||
virObjectUnref(cfg);
|
virObjectUnref(cfg);
|
||||||
|
37
tests/qemuxml2argvdata/qemuxml2argv-disk-active-commit.xml
Normal file
37
tests/qemuxml2argvdata/qemuxml2argv-disk-active-commit.xml
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
<domain type='qemu' id='1'>
|
||||||
|
<name>QEMUGuest1</name>
|
||||||
|
<uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
|
||||||
|
<memory unit='KiB'>219136</memory>
|
||||||
|
<currentMemory unit='KiB'>219136</currentMemory>
|
||||||
|
<vcpu placement='static'>1</vcpu>
|
||||||
|
<os>
|
||||||
|
<type arch='i686' machine='pc'>hvm</type>
|
||||||
|
<boot dev='hd'/>
|
||||||
|
</os>
|
||||||
|
<clock offset='utc'/>
|
||||||
|
<on_poweroff>destroy</on_poweroff>
|
||||||
|
<on_reboot>restart</on_reboot>
|
||||||
|
<on_crash>destroy</on_crash>
|
||||||
|
<devices>
|
||||||
|
<emulator>/usr/bin/qemu</emulator>
|
||||||
|
<disk type='file' device='disk'>
|
||||||
|
<driver name='qemu' type='qcow2'/>
|
||||||
|
<source file='/tmp/HostVG/QEMUGuest1-snap'/>
|
||||||
|
<backingStore type='block' index='1'>
|
||||||
|
<format type='raw'/>
|
||||||
|
<source dev='/dev/HostVG/QEMUGuest1'/>
|
||||||
|
<backingStore/>
|
||||||
|
</backingStore>
|
||||||
|
<mirror type='block' job='active-commit'>
|
||||||
|
<format type='raw'/>
|
||||||
|
<source dev='/dev/HostVG/QEMUGuest1'/>
|
||||||
|
</mirror>
|
||||||
|
<target dev='hda' bus='ide'/>
|
||||||
|
<address type='drive' controller='0' bus='0' target='0' unit='0'/>
|
||||||
|
</disk>
|
||||||
|
<controller type='usb' index='0'/>
|
||||||
|
<controller type='ide' index='0'/>
|
||||||
|
<controller type='pci' index='0' model='pci-root'/>
|
||||||
|
<memballoon model='virtio'/>
|
||||||
|
</devices>
|
||||||
|
</domain>
|
@ -17,7 +17,7 @@
|
|||||||
<disk type='block' device='disk'>
|
<disk type='block' device='disk'>
|
||||||
<source dev='/dev/HostVG/QEMUGuest1'/>
|
<source dev='/dev/HostVG/QEMUGuest1'/>
|
||||||
<backingStore/>
|
<backingStore/>
|
||||||
<mirror type='file' file='/dev/HostVG/QEMUGuest1Copy' ready='yes'>
|
<mirror type='file' file='/dev/HostVG/QEMUGuest1Copy' job='copy' ready='yes'>
|
||||||
<source file='/dev/HostVG/QEMUGuest1Copy'/>
|
<source file='/dev/HostVG/QEMUGuest1Copy'/>
|
||||||
</mirror>
|
</mirror>
|
||||||
<target dev='hda' bus='ide'/>
|
<target dev='hda' bus='ide'/>
|
||||||
@ -33,7 +33,7 @@
|
|||||||
<disk type='file' device='disk'>
|
<disk type='file' device='disk'>
|
||||||
<source file='/tmp/data.img'/>
|
<source file='/tmp/data.img'/>
|
||||||
<backingStore/>
|
<backingStore/>
|
||||||
<mirror type='file' file='/tmp/copy.img' format='qcow2'>
|
<mirror type='file' file='/tmp/copy.img' format='qcow2' job='copy'>
|
||||||
<format type='qcow2'/>
|
<format type='qcow2'/>
|
||||||
<source file='/tmp/copy.img'/>
|
<source file='/tmp/copy.img'/>
|
||||||
</mirror>
|
</mirror>
|
||||||
@ -42,7 +42,7 @@
|
|||||||
<disk type='file' device='disk'>
|
<disk type='file' device='disk'>
|
||||||
<source file='/tmp/logs.img'/>
|
<source file='/tmp/logs.img'/>
|
||||||
<backingStore/>
|
<backingStore/>
|
||||||
<mirror type='file' file='/tmp/logcopy.img' format='qcow2' ready='abort'>
|
<mirror type='file' file='/tmp/logcopy.img' format='qcow2' job='copy' ready='abort'>
|
||||||
<format type='qcow2'/>
|
<format type='qcow2'/>
|
||||||
<source file='/tmp/logcopy.img'/>
|
<source file='/tmp/logcopy.img'/>
|
||||||
</mirror>
|
</mirror>
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
<disk type='block' device='disk'>
|
<disk type='block' device='disk'>
|
||||||
<source dev='/dev/HostVG/QEMUGuest1'/>
|
<source dev='/dev/HostVG/QEMUGuest1'/>
|
||||||
<backingStore/>
|
<backingStore/>
|
||||||
<mirror type='file' file='/dev/HostVG/QEMUGuest1Copy' ready='yes'>
|
<mirror type='file' file='/dev/HostVG/QEMUGuest1Copy' job='copy' ready='yes'>
|
||||||
<source file='/dev/HostVG/QEMUGuest1Copy'/>
|
<source file='/dev/HostVG/QEMUGuest1Copy'/>
|
||||||
</mirror>
|
</mirror>
|
||||||
<target dev='hda' bus='ide'/>
|
<target dev='hda' bus='ide'/>
|
||||||
@ -33,7 +33,7 @@
|
|||||||
<disk type='file' device='disk'>
|
<disk type='file' device='disk'>
|
||||||
<source file='/tmp/data.img'/>
|
<source file='/tmp/data.img'/>
|
||||||
<backingStore/>
|
<backingStore/>
|
||||||
<mirror type='file' file='/tmp/copy.img' format='qcow2'>
|
<mirror type='file' file='/tmp/copy.img' format='qcow2' job='copy'>
|
||||||
<format type='qcow2'/>
|
<format type='qcow2'/>
|
||||||
<source file='/tmp/copy.img'/>
|
<source file='/tmp/copy.img'/>
|
||||||
</mirror>
|
</mirror>
|
||||||
|
@ -232,6 +232,7 @@ mymain(void)
|
|||||||
DO_TEST_DIFFERENT("disk-mirror-old");
|
DO_TEST_DIFFERENT("disk-mirror-old");
|
||||||
DO_TEST_FULL("disk-mirror", false, WHEN_ACTIVE);
|
DO_TEST_FULL("disk-mirror", false, WHEN_ACTIVE);
|
||||||
DO_TEST_FULL("disk-mirror", true, WHEN_INACTIVE);
|
DO_TEST_FULL("disk-mirror", true, WHEN_INACTIVE);
|
||||||
|
DO_TEST_FULL("disk-active-commit", false, WHEN_ACTIVE);
|
||||||
DO_TEST("graphics-listen-network");
|
DO_TEST("graphics-listen-network");
|
||||||
DO_TEST("graphics-vnc");
|
DO_TEST("graphics-vnc");
|
||||||
DO_TEST("graphics-vnc-websocket");
|
DO_TEST("graphics-vnc-websocket");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user