Add disk error policy to domain XML

* 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
* Re-add empty tag
This commit is contained in:
David Allan 2010-03-24 11:32:10 -04:00
parent 508da563b9
commit 447c586a0d
9 changed files with 93 additions and 1 deletions

View File

@ -521,6 +521,9 @@
<ref name="driverCache"/>
</group>
</choice>
<optional>
<ref name="driverErrorPolicy"/>
</optional>
<empty/>
</element>
</define>
@ -543,6 +546,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>

View File

@ -124,6 +124,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",
@ -1303,6 +1308,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;
@ -1368,6 +1374,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")) {
@ -1484,6 +1491,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,
@ -1526,6 +1540,7 @@ cleanup:
VIR_FREE(driverType);
VIR_FREE(driverName);
VIR_FREE(cachetag);
VIR_FREE(error_policy);
VIR_FREE(devaddr);
VIR_FREE(serial);
virStorageEncryptionFree(encryption);
@ -4651,6 +4666,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,
@ -4685,6 +4701,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");
}

View File

@ -152,6 +152,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;
@ -165,6 +173,7 @@ struct _virDomainDiskDef {
char *driverType;
char *serial;
int cachemode;
int error_policy;
unsigned int readonly : 1;
unsigned int shared : 1;
virDomainDeviceInfo info;
@ -941,6 +950,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)

View File

@ -194,7 +194,7 @@ virDomainDefClearDeviceAliases;
virDomainDeviceInfoIterate;
virDomainClockOffsetTypeToString;
virDomainClockOffsetTypeFromString;
virDomainDiskErrorPolicyTypeToString;
# domain_event.h
virDomainEventCallbackListAdd;

View File

@ -2470,6 +2470,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;
@ -4759,6 +4767,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);

View File

@ -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 |

View File

@ -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

View File

@ -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>

View File

@ -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 |