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.
---
docs/formatdomain.html.in | 26 +++++++++++-
docs/schemas/domaincommon.rng | 22 +++++++++-
src/conf/domain_conf.c | 43 ++++++++++++++++++-
src/conf/domain_conf.h | 11 +++++
src/libvirt_private.syms | 2 +
.../qemuxml2xmlout-disk-cdrom-empty.xml | 31 ++++++++++++++
6 files changed, 127 insertions(+), 8 deletions(-)
create mode 100644 tests/qemuxml2xmloutdata/qemuxml2xmlout-disk-cdrom-empty.xml
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 12055c2..9102f22 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -891,7 +891,7 @@
<devices>
<disk type='file' snapshot='external'>
<driver name="tap" type="aio"
cache="default"/>
- <source file='/var/lib/xen/images/fv0'/>
+ <source file='/var/lib/xen/images/fv0'/
on_missing='optional'>
<target dev='hda' bus='ide'/>
<boot order='2'/>
<encryption type='...'>
@@ -962,7 +962,29 @@
"network", the <code>source</code> may have zero or
more <code>host</code> sub-elements used to specify the hosts
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>on_missing</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>
<dd>The <code>target</code> element controls the bus / device
under which the disk is exposed to the guest
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index cd1a067..ec92788 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -665,6 +665,17 @@
</interleave>
</element>
</define>
+
+ <define name="on_missing">
+ <attribute name="on_missing">
+ <choice>
+ <value>mandatory</value>
+ <value>requisite</value>
+ <value>optional</value>
+ </choice>
+ </attribute>
+ </define>
+
<!--
A disk description can be either of type file or block
The name of the attribute on the source element depends on the type
@@ -692,9 +703,14 @@
<interleave>
<optional>
<element name="source">
- <attribute name="file">
- <ref name="absFilePath"/>
- </attribute>
+ <optional>
+ <attribute name="file">
+ <ref name="absFilePath"/>
+ </attribute>
+ </optional>
+ <optional>
+ <ref name="on_missing"/>
+ </optional>
<empty/>
</element>
</optional>
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 5959593..607ea58 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -578,6 +578,12 @@ VIR_ENUM_IMPL(virDomainNumatuneMemMode,
VIR_DOMAIN_NUMATUNE_MEM_LAST,
"preferred",
"interleave");
+VIR_ENUM_IMPL(virDomainOnMissing, VIR_DOMAIN_ON_MISSING_LAST,
+ "default",
+ "mandatory",
+ "requisite",
+ "optional");
+
#define virDomainReportError(code, ...) \
virReportErrorHelper(VIR_FROM_DOMAIN, code, __FILE__, \
__FUNCTION__, __LINE__, __VA_ARGS__)
@@ -2319,6 +2325,7 @@ virDomainDiskDefParseXML(virCapsPtr caps,
char *devaddr = NULL;
virStorageEncryptionPtr encryption = NULL;
char *serial = NULL;
+ char *on_missing = NULL;
if (VIR_ALLOC(def) < 0) {
virReportOOMError();
@@ -2347,6 +2354,7 @@ virDomainDiskDefParseXML(virCapsPtr caps,
switch (def->type) {
case VIR_DOMAIN_DISK_TYPE_FILE:
source = virXMLPropString(cur, "file");
+ on_missing = virXMLPropString(cur, "on_missing");
break;
case VIR_DOMAIN_DISK_TYPE_BLOCK:
source = virXMLPropString(cur, "dev");
@@ -2646,6 +2654,27 @@ virDomainDiskDefParseXML(virCapsPtr caps,
goto error;
}
+ if (on_missing) {
+ int i;
+
+ if ((i = virDomainOnMissingTypeFromString(on_missing)) < 0) {
+ virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("unknown on_missing value '%s'"),
+ on_missing);
+ 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"),
+ on_missing);
+ goto error;
+ }
+ def->on_missing = i;
+ }
+
def->src = source;
source = NULL;
def->dst = target;
@@ -2701,6 +2730,7 @@ cleanup:
VIR_FREE(devaddr);
VIR_FREE(serial);
virStorageEncryptionFree(encryption);
+ VIR_FREE(on_missing);
return def;
@@ -9176,6 +9206,7 @@ virDomainDiskDefFormat(virBufferPtr buf,
const char *iomode = virDomainDiskIoTypeToString(def->iomode);
const char *ioeventfd = virDomainIoEventFdTypeToString(def->ioeventfd);
const char *event_idx = virDomainVirtioEventIdxTypeToString(def->event_idx);
+ const char *on_missing = virDomainOnMissingTypeToString(def->on_missing);
if (!type) {
virDomainReportError(VIR_ERR_INTERNAL_ERROR,
@@ -9234,11 +9265,17 @@ virDomainDiskDefFormat(virBufferPtr buf,
virBufferAsprintf(buf, "/>\n");
}
- if (def->src || def->nhosts > 0) {
+ if (def->src || def->nhosts > 0 ||
+ def->on_missing) {
switch (def->type) {
case VIR_DOMAIN_DISK_TYPE_FILE:
- virBufferEscapeString(buf, " <source
file='%s'/>\n",
- def->src);
+ virBufferAsprintf(buf," <source");
+ if (def->src)
+ virBufferEscapeString(buf, " file='%s'", def->src);
+ if (def->on_missing)
+ virBufferEscapeString(buf, " on_missing='%s'",
+ on_missing);
+ virBufferAsprintf(buf, "/>\n");
break;
case VIR_DOMAIN_DISK_TYPE_BLOCK:
virBufferEscapeString(buf, " <source
dev='%s'/>\n",
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 2119b5a..9df6df9 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -269,6 +269,15 @@ enum virDomainSnapshotState {
VIR_DOMAIN_DISK_SNAPSHOT = VIR_DOMAIN_LAST,
};
+enum virDomainOnMissing {
+ VIR_DOMAIN_ON_MISSING_DEFAULT = 0,
+ VIR_DOMAIN_ON_MISSING_MANDATORY,
+ VIR_DOMAIN_ON_MISSING_REQUISITE,
+ VIR_DOMAIN_ON_MISSING_OPTIONAL,
+
+ VIR_DOMAIN_ON_MISSING_LAST
+};
+
/* Stores the virtual disk configuration */
typedef struct _virDomainDiskDef virDomainDiskDef;
typedef virDomainDiskDef *virDomainDiskDefPtr;
@@ -292,6 +301,7 @@ struct _virDomainDiskDef {
int ioeventfd;
int event_idx;
int snapshot; /* enum virDomainDiskSnapshot */
+ int on_missing; /* enum virDomainOnMissing */
unsigned int readonly : 1;
unsigned int shared : 1;
unsigned int transient : 1;
@@ -1935,4 +1945,5 @@ VIR_ENUM_DECL(virDomainTimerTrack)
VIR_ENUM_DECL(virDomainTimerTickpolicy)
VIR_ENUM_DECL(virDomainTimerMode)
+VIR_ENUM_DECL(virDomainOnMissing)
#endif /* __DOMAIN_CONF_H */
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index dedbd16..ae18a0d 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -387,6 +387,8 @@ virDomainObjSetState;
virDomainObjTaint;
virDomainObjUnlock;
virDomainObjUnref;
+virDomainOnMissingTypeFromString;
+virDomainOnMissingTypeToString;
virDomainPausedReasonTypeFromString;
virDomainPausedReasonTypeToString;
virDomainPciRombarModeTypeFromString;
diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-disk-cdrom-empty.xml
b/tests/qemuxml2xmloutdata/qemuxml2xmlout-disk-cdrom-empty.xml
new file mode 100644
index 0000000..a4ec9e0
--- /dev/null
+++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-disk-cdrom-empty.xml
@@ -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 on_missing='optional'/>
+ <readonly/>
+ <address type='drive' controller='0' bus='1'
unit='0'/>
+ </disk>
+ <controller type='ide' index='0'/>
+ <memballoon model='virtio'/>
+ </devices>
+</domain>
--
1.7.3.4