* Fixes per feedback from Dan and Daniel
* Added test datafiles
* Re-disabled JSON flags
* Added code to print the error policy attribute when generating XML
---
docs/schemas/domain.rng | 12 +++++++-
src/conf/domain_conf.c | 18 +++++++++++
src/conf/domain_conf.h | 10 ++++++
src/libvirt_private.syms | 2 +-
src/qemu/qemu_conf.c | 17 +++++++++-
tests/qemuargv2xmltest.c | 3 ++
.../qemuxml2argv-disk-drive-error-policy-stop.args | 1 +
.../qemuxml2argv-disk-drive-error-policy-stop.xml | 32 ++++++++++++++++++++
tests/qemuxml2argvtest.c | 3 ++
9 files changed, 94 insertions(+), 4 deletions(-)
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-drive-error-policy-stop.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-drive-error-policy-stop.xml
diff --git a/docs/schemas/domain.rng b/docs/schemas/domain.rng
index 5a8c82b..b276da7 100644
--- a/docs/schemas/domain.rng
+++ b/docs/schemas/domain.rng
@@ -521,7 +521,9 @@
<ref name="driverCache"/>
</group>
</choice>
- <empty/>
+ <optional>
+ <ref name="driverErrorPolicy"/>
+ </optional>
</element>
</define>
<define name="driverFormat">
@@ -543,6 +545,14 @@
</choice>
</attribute>
</define>
+ <define name="driverErrorPolicy">
+ <attribute name="error_policy">
+ <choice>
+ <value>stop</value>
+ <value>ignore</value>
+ </choice>
+ </attribute>
+ </define>
<define name="controller">
<element name="controller">
<choice>
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index ffbb26f..17f6220 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -123,6 +123,11 @@ VIR_ENUM_IMPL(virDomainDiskCache, VIR_DOMAIN_DISK_CACHE_LAST,
"writethrough",
"writeback")
+VIR_ENUM_IMPL(virDomainDiskErrorPolicy, VIR_DOMAIN_DISK_ERROR_POLICY_LAST,
+ "default",
+ "stop",
+ "ignore")
+
VIR_ENUM_IMPL(virDomainController, VIR_DOMAIN_CONTROLLER_TYPE_LAST,
"ide",
"fdc",
@@ -1295,6 +1300,7 @@ virDomainDiskDefParseXML(xmlNodePtr node,
char *target = NULL;
char *bus = NULL;
char *cachetag = NULL;
+ char *error_policy = NULL;
char *devaddr = NULL;
virStorageEncryptionPtr encryption = NULL;
char *serial = NULL;
@@ -1360,6 +1366,7 @@ virDomainDiskDefParseXML(xmlNodePtr node,
driverName = virXMLPropString(cur, "name");
driverType = virXMLPropString(cur, "type");
cachetag = virXMLPropString(cur, "cache");
+ error_policy = virXMLPropString(cur, "error_policy");
} else if (xmlStrEqual(cur->name, BAD_CAST "readonly")) {
def->readonly = 1;
} else if (xmlStrEqual(cur->name, BAD_CAST "shareable")) {
@@ -1476,6 +1483,13 @@ virDomainDiskDefParseXML(xmlNodePtr node,
goto error;
}
+ if (error_policy &&
+ (def->error_policy = virDomainDiskErrorPolicyTypeFromString(error_policy))
< 0) {
+ virDomainReportError(VIR_ERR_INTERNAL_ERROR,
+ _("unknown disk error policy '%s'"),
error_policy);
+ goto error;
+ }
+
if (devaddr) {
if (sscanf(devaddr, "%x:%x:%x",
&def->info.addr.pci.domain,
@@ -1518,6 +1532,7 @@ cleanup:
VIR_FREE(driverType);
VIR_FREE(driverName);
VIR_FREE(cachetag);
+ VIR_FREE(error_policy);
VIR_FREE(devaddr);
VIR_FREE(serial);
virStorageEncryptionFree(encryption);
@@ -4616,6 +4631,7 @@ virDomainDiskDefFormat(virBufferPtr buf,
const char *device = virDomainDiskDeviceTypeToString(def->device);
const char *bus = virDomainDiskBusTypeToString(def->bus);
const char *cachemode = virDomainDiskCacheTypeToString(def->cachemode);
+ const char *error_policy =
virDomainDiskErrorPolicyTypeToString(def->error_policy);
if (!type) {
virDomainReportError(VIR_ERR_INTERNAL_ERROR,
@@ -4650,6 +4666,8 @@ virDomainDiskDefFormat(virBufferPtr buf,
virBufferVSprintf(buf, " type='%s'", def->driverType);
if (def->cachemode)
virBufferVSprintf(buf, " cache='%s'", cachemode);
+ if (def->error_policy)
+ virBufferVSprintf(buf, " error_policy='%s'",
error_policy);
virBufferVSprintf(buf, "/>\n");
}
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index efd5db6..e275d35 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -150,6 +150,14 @@ enum virDomainDiskCache {
VIR_DOMAIN_DISK_CACHE_LAST
};
+enum virDomainDiskErrorPolicy {
+ VIR_DOMAIN_DISK_ERROR_POLICY_DEFAULT,
+ VIR_DOMAIN_DISK_ERROR_POLICY_STOP,
+ VIR_DOMAIN_DISK_ERROR_POLICY_IGNORE,
+
+ VIR_DOMAIN_DISK_ERROR_POLICY_LAST
+};
+
/* Stores the virtual disk configuration */
typedef struct _virDomainDiskDef virDomainDiskDef;
typedef virDomainDiskDef *virDomainDiskDefPtr;
@@ -163,6 +171,7 @@ struct _virDomainDiskDef {
char *driverType;
char *serial;
int cachemode;
+ int error_policy;
unsigned int readonly : 1;
unsigned int shared : 1;
virDomainDeviceInfo info;
@@ -937,6 +946,7 @@ VIR_ENUM_DECL(virDomainDisk)
VIR_ENUM_DECL(virDomainDiskDevice)
VIR_ENUM_DECL(virDomainDiskBus)
VIR_ENUM_DECL(virDomainDiskCache)
+VIR_ENUM_DECL(virDomainDiskErrorPolicy)
VIR_ENUM_DECL(virDomainController)
VIR_ENUM_DECL(virDomainFS)
VIR_ENUM_DECL(virDomainNet)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 0033d2a..513be99 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -192,7 +192,7 @@ virDomainDefClearDeviceAliases;
virDomainDeviceInfoIterate;
virDomainClockOffsetTypeToString;
virDomainClockOffsetTypeFromString;
-
+virDomainDiskErrorPolicyTypeToString;
# domain_event.h
virDomainEventCallbackListAdd;
diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
index 902eecb..e2a7070 100644
--- a/src/qemu/qemu_conf.c
+++ b/src/qemu/qemu_conf.c
@@ -1213,13 +1213,12 @@ static unsigned long long qemudComputeCmdFlags(const char *help,
if (version >= 10000)
flags |= QEMUD_CMD_FLAG_0_10;
+#if 0
/* Keep disabled till we're actually ready to turn on JSON mode
* The plan is todo it in 0.13.0 QEMU, but lets wait & see... */
-#if 0
if (version >= 13000)
flags |= QEMUD_CMD_FLAG_MONITOR_JSON;
#endif
-
return flags;
}
@@ -2448,6 +2447,14 @@ qemuBuildDriveStr(virDomainDiskDefPtr disk,
virBufferAddLit(&opt, ",cache=off");
}
+ if (qemuCmdFlags & QEMUD_CMD_FLAG_MONITOR_JSON) {
+ if (disk->error_policy) {
+ virBufferVSprintf(&opt, ",werror=%s,rerror=%s",
+
virDomainDiskErrorPolicyTypeToString(disk->error_policy),
+
virDomainDiskErrorPolicyTypeToString(disk->error_policy));
+ }
+ }
+
if (virBufferError(&opt)) {
virReportOOMError();
goto error;
@@ -4722,6 +4729,12 @@ qemuParseCommandLineDisk(const char *val,
def->cachemode = VIR_DOMAIN_DISK_CACHE_WRITEBACK;
else if (STREQ(values[i], "writethrough"))
def->cachemode = VIR_DOMAIN_DISK_CACHE_WRITETHRU;
+ } else if (STREQ(keywords[i], "werror") ||
+ STREQ(keywords[i], "rerror")) {
+ if (STREQ(values[i], "stop"))
+ def->error_policy = VIR_DOMAIN_DISK_ERROR_POLICY_STOP;
+ else if (STREQ(values[i], "ignore"))
+ def->error_policy = VIR_DOMAIN_DISK_ERROR_POLICY_IGNORE;
} else if (STREQ(keywords[i], "index")) {
if (virStrToLong_i(values[i], NULL, 10, &idx) < 0) {
virDomainDiskDefFree(def);
diff --git a/tests/qemuargv2xmltest.c b/tests/qemuargv2xmltest.c
index 2197438..b330238 100644
--- a/tests/qemuargv2xmltest.c
+++ b/tests/qemuargv2xmltest.c
@@ -162,6 +162,9 @@ mymain(int argc, char **argv)
/*DO_TEST("disk-drive-cache-v1-wt", QEMUD_CMD_FLAG_DRIVE);*/
DO_TEST("disk-drive-cache-v1-wb", QEMUD_CMD_FLAG_DRIVE);
DO_TEST("disk-drive-cache-v1-none", QEMUD_CMD_FLAG_DRIVE);
+ DO_TEST("disk-drive-error-policy-stop", QEMUD_CMD_FLAG_DRIVE |
+ QEMUD_CMD_FLAG_MONITOR_JSON |
+ QEMUD_CMD_FLAG_DRIVE_FORMAT);
DO_TEST("disk-drive-cache-v2-wt", QEMUD_CMD_FLAG_DRIVE |
QEMUD_CMD_FLAG_DRIVE_CACHE_V2);
DO_TEST("disk-drive-cache-v2-wb", QEMUD_CMD_FLAG_DRIVE |
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-error-policy-stop.args
b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-error-policy-stop.args
new file mode 100644
index 0000000..765f6a4
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-error-policy-stop.args
@@ -0,0 +1 @@
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214
-smp 1 -nographic -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -drive
file=/dev/HostVG/QEMUGuest1,if=ide,bus=0,unit=0,format=qcow2,cache=off,werror=stop,rerror=stop
-drive file=/dev/HostVG/QEMUGuest2,if=ide,media=cdrom,bus=1,unit=0,format=raw -net none
-serial none -parallel none -usb
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-error-policy-stop.xml
b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-error-policy-stop.xml
new file mode 100644
index 0000000..67e23cc
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-error-policy-stop.xml
@@ -0,0 +1,32 @@
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory>219200</memory>
+ <currentMemory>219200</currentMemory>
+ <vcpu>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='block' device='disk'>
+ <driver name='qemu' type='qcow2' cache='none'
error_policy='stop'/>
+ <source dev='/dev/HostVG/QEMUGuest1'/>
+ <target dev='hda' bus='ide'/>
+ <address type='drive' controller='0' bus='0'
unit='0'/>
+ </disk>
+ <disk type='block' device='cdrom'>
+ <driver name='qemu' type='raw'/>
+ <source dev='/dev/HostVG/QEMUGuest2'/>
+ <target dev='hdc' bus='ide'/>
+ <readonly/>
+ <address type='drive' controller='0' bus='1'
unit='0'/>
+ </disk>
+ <controller type='ide' index='0'/>
+ </devices>
+</domain>
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index e3762c9..c98de19 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -261,6 +261,9 @@ mymain(int argc, char **argv)
QEMUD_CMD_FLAG_DRIVE_FORMAT);
DO_TEST("disk-drive-cache-v1-none", QEMUD_CMD_FLAG_DRIVE |
QEMUD_CMD_FLAG_DRIVE_FORMAT);
+ DO_TEST("disk-drive-error-policy-stop", QEMUD_CMD_FLAG_DRIVE |
+ QEMUD_CMD_FLAG_MONITOR_JSON |
+ QEMUD_CMD_FLAG_DRIVE_FORMAT);
DO_TEST("disk-drive-cache-v2-wt", QEMUD_CMD_FLAG_DRIVE |
QEMUD_CMD_FLAG_DRIVE_CACHE_V2 | QEMUD_CMD_FLAG_DRIVE_FORMAT);
DO_TEST("disk-drive-cache-v2-wb", QEMUD_CMD_FLAG_DRIVE |
--
1.7.0.1