conf: Introduce optional startupPolicy attribute for cdrom and floppy

This attribute says what to do with cdrom (or floppy) if
the source is missing. It accepts:
- mandatory - fail if missing for any reason (the default)
- requisite - fail if missing on boot up, drop if missing on
              migrate/restore/revert
- optional  - drop if missing at any start attempt.

However, this patch introduces only XML part of this new
functionality.
This commit is contained in:
Michal Privoznik 2011-10-17 16:54:03 +02:00
parent b1836a254e
commit e5a84d74a2
6 changed files with 127 additions and 8 deletions

View File

@ -891,7 +891,7 @@
<devices> <devices>
<disk type='file' snapshot='external'> <disk type='file' snapshot='external'>
<driver name="tap" type="aio" cache="default"/> <driver name="tap" type="aio" cache="default"/>
<source file='/var/lib/xen/images/fv0'/> <source file='/var/lib/xen/images/fv0'/ startupPolicy='optional'>
<target dev='hda' bus='ide'/> <target dev='hda' bus='ide'/>
<boot order='2'/> <boot order='2'/>
<encryption type='...'> <encryption type='...'>
@ -962,7 +962,29 @@
"network", the <code>source</code> may have zero or "network", the <code>source</code> may have zero or
more <code>host</code> sub-elements used to specify the hosts more <code>host</code> sub-elements used to specify the hosts
to connect. to connect.
<span class="since">Since 0.0.3</span></dd> <span class="since">Since 0.0.3</span>
For "file" disk type which represents cdrom or floppy
(the <code>device</code> attribute) it is possible to define
policy what to do with disk if source is not accessible.
This is done by <code>startupPolicy</code> attribute accepting
these values:
<table class="top_table">
<tr>
<td> mandatory </td>
<td> fail if missing for any reason (the default) </td>
</tr>
<tr>
<td> requisite </td>
<td> fail if missing on boot up,
drop if missing on migrate/restore/revert </td>
</tr>
<tr>
<td> optional </td>
<td> drop if missing at any start attempt </td>
</tr>
</table>
<span class="since">Since 0.9.7</span>
</dd>
<dt><code>target</code></dt> <dt><code>target</code></dt>
<dd>The <code>target</code> element controls the bus / device <dd>The <code>target</code> element controls the bus / device
under which the disk is exposed to the guest under which the disk is exposed to the guest

View File

@ -665,6 +665,17 @@
</interleave> </interleave>
</element> </element>
</define> </define>
<define name="startupPolicy">
<attribute name="startupPolicy">
<choice>
<value>mandatory</value>
<value>requisite</value>
<value>optional</value>
</choice>
</attribute>
</define>
<!-- <!--
A disk description can be either of type file or block A disk description can be either of type file or block
The name of the attribute on the source element depends on the type The name of the attribute on the source element depends on the type
@ -692,9 +703,14 @@
<interleave> <interleave>
<optional> <optional>
<element name="source"> <element name="source">
<optional>
<attribute name="file"> <attribute name="file">
<ref name="absFilePath"/> <ref name="absFilePath"/>
</attribute> </attribute>
</optional>
<optional>
<ref name="startupPolicy"/>
</optional>
<empty/> <empty/>
</element> </element>
</optional> </optional>

View File

@ -578,6 +578,12 @@ VIR_ENUM_IMPL(virDomainNumatuneMemMode, VIR_DOMAIN_NUMATUNE_MEM_LAST,
"preferred", "preferred",
"interleave"); "interleave");
VIR_ENUM_IMPL(virDomainStartupPolicy, VIR_DOMAIN_STARTUP_POLICY_LAST,
"default",
"mandatory",
"requisite",
"optional");
#define virDomainReportError(code, ...) \ #define virDomainReportError(code, ...) \
virReportErrorHelper(VIR_FROM_DOMAIN, code, __FILE__, \ virReportErrorHelper(VIR_FROM_DOMAIN, code, __FILE__, \
__FUNCTION__, __LINE__, __VA_ARGS__) __FUNCTION__, __LINE__, __VA_ARGS__)
@ -2319,6 +2325,7 @@ virDomainDiskDefParseXML(virCapsPtr caps,
char *devaddr = NULL; char *devaddr = NULL;
virStorageEncryptionPtr encryption = NULL; virStorageEncryptionPtr encryption = NULL;
char *serial = NULL; char *serial = NULL;
char *startupPolicy = NULL;
if (VIR_ALLOC(def) < 0) { if (VIR_ALLOC(def) < 0) {
virReportOOMError(); virReportOOMError();
@ -2347,6 +2354,7 @@ virDomainDiskDefParseXML(virCapsPtr caps,
switch (def->type) { switch (def->type) {
case VIR_DOMAIN_DISK_TYPE_FILE: case VIR_DOMAIN_DISK_TYPE_FILE:
source = virXMLPropString(cur, "file"); source = virXMLPropString(cur, "file");
startupPolicy = virXMLPropString(cur, "startupPolicy");
break; break;
case VIR_DOMAIN_DISK_TYPE_BLOCK: case VIR_DOMAIN_DISK_TYPE_BLOCK:
source = virXMLPropString(cur, "dev"); source = virXMLPropString(cur, "dev");
@ -2646,6 +2654,27 @@ virDomainDiskDefParseXML(virCapsPtr caps,
goto error; goto error;
} }
if (startupPolicy) {
int i;
if ((i = virDomainStartupPolicyTypeFromString(startupPolicy)) < 0) {
virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("unknown startupPolicy value '%s'"),
startupPolicy);
goto error;
}
if (def->device != VIR_DOMAIN_DISK_DEVICE_CDROM &&
def->device != VIR_DOMAIN_DISK_DEVICE_FLOPPY) {
virDomainReportError(VIR_ERR_INVALID_ARG,
_("Setting disk %s is allowed only for "
"cdrom or floppy"),
startupPolicy);
goto error;
}
def->startupPolicy = i;
}
def->src = source; def->src = source;
source = NULL; source = NULL;
def->dst = target; def->dst = target;
@ -2701,6 +2730,7 @@ cleanup:
VIR_FREE(devaddr); VIR_FREE(devaddr);
VIR_FREE(serial); VIR_FREE(serial);
virStorageEncryptionFree(encryption); virStorageEncryptionFree(encryption);
VIR_FREE(startupPolicy);
return def; return def;
@ -9176,6 +9206,7 @@ virDomainDiskDefFormat(virBufferPtr buf,
const char *iomode = virDomainDiskIoTypeToString(def->iomode); const char *iomode = virDomainDiskIoTypeToString(def->iomode);
const char *ioeventfd = virDomainIoEventFdTypeToString(def->ioeventfd); const char *ioeventfd = virDomainIoEventFdTypeToString(def->ioeventfd);
const char *event_idx = virDomainVirtioEventIdxTypeToString(def->event_idx); const char *event_idx = virDomainVirtioEventIdxTypeToString(def->event_idx);
const char *startupPolicy = virDomainStartupPolicyTypeToString(def->startupPolicy);
if (!type) { if (!type) {
virDomainReportError(VIR_ERR_INTERNAL_ERROR, virDomainReportError(VIR_ERR_INTERNAL_ERROR,
@ -9234,11 +9265,17 @@ virDomainDiskDefFormat(virBufferPtr buf,
virBufferAsprintf(buf, "/>\n"); virBufferAsprintf(buf, "/>\n");
} }
if (def->src || def->nhosts > 0) { if (def->src || def->nhosts > 0 ||
def->startupPolicy) {
switch (def->type) { switch (def->type) {
case VIR_DOMAIN_DISK_TYPE_FILE: case VIR_DOMAIN_DISK_TYPE_FILE:
virBufferEscapeString(buf, " <source file='%s'/>\n", virBufferAsprintf(buf," <source");
def->src); if (def->src)
virBufferEscapeString(buf, " file='%s'", def->src);
if (def->startupPolicy)
virBufferEscapeString(buf, " startupPolicy='%s'",
startupPolicy);
virBufferAsprintf(buf, "/>\n");
break; break;
case VIR_DOMAIN_DISK_TYPE_BLOCK: case VIR_DOMAIN_DISK_TYPE_BLOCK:
virBufferEscapeString(buf, " <source dev='%s'/>\n", virBufferEscapeString(buf, " <source dev='%s'/>\n",

View File

@ -269,6 +269,15 @@ enum virDomainSnapshotState {
VIR_DOMAIN_DISK_SNAPSHOT = VIR_DOMAIN_LAST, VIR_DOMAIN_DISK_SNAPSHOT = VIR_DOMAIN_LAST,
}; };
enum virDomainStartupPolicy {
VIR_DOMAIN_STARTUP_POLICY_DEFAULT = 0,
VIR_DOMAIN_STARTUP_POLICY_MANDATORY,
VIR_DOMAIN_STARTUP_POLICY_REQUISITE,
VIR_DOMAIN_STARTUP_POLICY_OPTIONAL,
VIR_DOMAIN_STARTUP_POLICY_LAST
};
/* Stores the virtual disk configuration */ /* Stores the virtual disk configuration */
typedef struct _virDomainDiskDef virDomainDiskDef; typedef struct _virDomainDiskDef virDomainDiskDef;
typedef virDomainDiskDef *virDomainDiskDefPtr; typedef virDomainDiskDef *virDomainDiskDefPtr;
@ -292,6 +301,7 @@ struct _virDomainDiskDef {
int ioeventfd; int ioeventfd;
int event_idx; int event_idx;
int snapshot; /* enum virDomainDiskSnapshot */ int snapshot; /* enum virDomainDiskSnapshot */
int startupPolicy; /* enum virDomainStartupPolicy */
unsigned int readonly : 1; unsigned int readonly : 1;
unsigned int shared : 1; unsigned int shared : 1;
unsigned int transient : 1; unsigned int transient : 1;
@ -1938,4 +1948,5 @@ VIR_ENUM_DECL(virDomainTimerTrack)
VIR_ENUM_DECL(virDomainTimerTickpolicy) VIR_ENUM_DECL(virDomainTimerTickpolicy)
VIR_ENUM_DECL(virDomainTimerMode) VIR_ENUM_DECL(virDomainTimerMode)
VIR_ENUM_DECL(virDomainStartupPolicy)
#endif /* __DOMAIN_CONF_H */ #endif /* __DOMAIN_CONF_H */

View File

@ -430,6 +430,8 @@ virDomainSnapshotUpdateRelations;
virDomainSoundDefFree; virDomainSoundDefFree;
virDomainSoundModelTypeFromString; virDomainSoundModelTypeFromString;
virDomainSoundModelTypeToString; virDomainSoundModelTypeToString;
virDomainStartupPolicyTypeFromString;
virDomainStartupPolicyTypeToString;
virDomainStateReasonFromString; virDomainStateReasonFromString;
virDomainStateReasonToString; virDomainStateReasonToString;
virDomainStateTypeFromString; virDomainStateTypeFromString;

View File

@ -0,0 +1,31 @@
<domain type='qemu'>
<name>QEMUGuest1</name>
<uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
<memory>219100</memory>
<currentMemory>219100</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'>
<source dev='/dev/HostVG/QEMUGuest1'/>
<target dev='hda' bus='ide'/>
<address type='drive' controller='0' bus='0' unit='0'/>
</disk>
<disk type='file' device='cdrom'>
<target dev='hdc' bus='ide'/>
<source startupPolicy='optional'/>
<readonly/>
<address type='drive' controller='0' bus='1' unit='0'/>
</disk>
<controller type='ide' index='0'/>
<memballoon model='virtio'/>
</devices>
</domain>