[Problem]
Currently, guest OS's messages can be logged to a local disk of host OS
by creating chadevs with options below.
-chardev file,id=charserial0,path=<log file's path> -device
isa-serial,chardev=chardevserial0,id=serial0
When a hardware failure happens in the disk, qemu-kvm can't create the chardevs.
In this case, guest OS doesn't boot up.
Actually, there are users who don't desire that guest OS goes down due to a hardware
failure
of a log disk only.Therefore, qemu should offer some way to boot guest OS up even if the
log
disk is broken.
[Solution]
This patch supports startupPolicy for chardev.
The starupPolicy is introduced just in case where chardev is "file"
because this patch aims for making guest OS boot up when a hardware failure happens.
In other cases ,pty, dev, pipe and unix, it is not introduced
because they don't access to hardware.
The policy works as follows.
- If the value is "optional", guestOS boots up by dropping the chardev.
- If other values are specified, guestOS fails to boot up. (the default)
Description about original startupPolicy attribute:
http://libvirt.org/git/?p=libvirt.git;a=commitdiff;h=e5a84d74a2789a917bf3...
Signed-off-by: Seiji Aguchi <seiji.aguchi(a)hds.com>
---
docs/formatdomain.html.in | 9 ++++++++-
docs/schemas/domaincommon.rng | 3 +++
src/conf/domain_conf.c | 8 ++++++++
src/conf/domain_conf.h | 1 +
src/qemu/qemu_process.c | 25 ++++++++++++++++++++++++-
tests/virt-aa-helper-test | 3 +++
6 files changed, 47 insertions(+), 2 deletions(-)
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index f325c3c..1e1bf27 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -4044,13 +4044,20 @@ qemu-kvm -net nic,model=? /dev/null
<p>
A file is opened and all data sent to the character
device is written to the file.
+ It is possible to define policy whether guestOS boots up
+ if the file is not accessible. This is done by a startupPolicy
+ attribute:
+ <ul>
+ <li>If the vaule is "optional", guestOS boots up by dropping the
file.</li>
+ <li>If other values are specified, guestOS fails to boot up. (the
default)</li>
+ </ul>
</p>
<pre>
...
<devices>
<serial type="file">
- <source path="/var/log/vm/vm-serial.log"/>
+ <source path="/var/log/vm/vm-serial.log"
startupPolicy="optional"/>
<target port="1"/>
</serial>
</devices>
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 10596dc..6fc0a3c 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -2706,6 +2706,9 @@
</optional>
<optional>
<attribute name="path"/>
+ <optional>
+ <ref name='startupPolicy'/>
+ </optional>
</optional>
<optional>
<attribute name="host"/>
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index a8b5dfd..6680f15 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -6467,6 +6467,7 @@ virDomainChrSourceDefParseXML(virDomainChrSourceDefPtr def,
char *path = NULL;
char *mode = NULL;
char *protocol = NULL;
+ char *startupPolicy = NULL;
int remaining = 0;
while (cur != NULL) {
@@ -6487,6 +6488,9 @@ virDomainChrSourceDefParseXML(virDomainChrSourceDefPtr def,
!(flags & VIR_DOMAIN_XML_INACTIVE)))
path = virXMLPropString(cur, "path");
+ if (startupPolicy == NULL &&
+ def->type == VIR_DOMAIN_CHR_TYPE_FILE)
+ startupPolicy = virXMLPropString(cur,
"startupPolicy");
break;
case VIR_DOMAIN_CHR_TYPE_UDP:
@@ -6559,6 +6563,10 @@ virDomainChrSourceDefParseXML(virDomainChrSourceDefPtr def,
def->data.file.path = path;
path = NULL;
+
+ def->data.file.startupPolicy =
+ virDomainStartupPolicyTypeFromString(startupPolicy);
+ startupPolicy = NULL;
break;
case VIR_DOMAIN_CHR_TYPE_STDIO:
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 3a0f23a..e709951 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -1052,6 +1052,7 @@ struct _virDomainChrSourceDef {
/* no <source> for null, vc, stdio */
struct {
char *path;
+ int startupPolicy; /* enum virDomainStartupPolicy */
} file; /* pty, file, pipe, or device */
struct {
char *host;
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index e75c8c9..6e2f78e 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -2442,7 +2442,30 @@ qemuProcessPrepareChardevDevice(virDomainDefPtr def
ATTRIBUTE_UNUSED,
virReportSystemError(errno,
_("Unable to pre-create chardev file
'%s'"),
dev->source.data.file.path);
- return -1;
+ if (dev->source.data.file.startupPolicy !=
+ VIR_DOMAIN_STARTUP_POLICY_OPTIONAL) {
+ return -1;
+ }
+ VIR_FREE(dev->source.data.file.path);
+ /*
+ * Change a destination to /dev/null to boot guest OS up
+ * even if a log disk is broken.
+ */
+ VIR_WARN("Switch the destination to /dev/null");
+ dev->source.data.file.path = strdup("/dev/null");
+
+ if (!(dev->source.data.file.path)) {
+ virReportOOMError();
+ return -1;
+ }
+
+ if ((fd = open(dev->source.data.file.path,
+ O_CREAT | O_APPEND, S_IRUSR|S_IWUSR)) < 0) {
+ virReportSystemError(errno,
+ _("Unable to pre-create chardev file
'%s'"),
+ dev->source.data.file.path);
+ return -1;
+ }
}
VIR_FORCE_CLOSE(fd);
diff --git a/tests/virt-aa-helper-test b/tests/virt-aa-helper-test
index af91c61..7172fd6 100755
--- a/tests/virt-aa-helper-test
+++ b/tests/virt-aa-helper-test
@@ -255,6 +255,9 @@ testme "0" "disk (empty cdrom)" "-r -u
$valid_uuid" "$test_xml"
sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e
"s,</devices>,<serial type='file'><source
path='$tmpdir/serial.log'/><target
port='0'/></serial></devices>,g" "$template_xml"
> "$test_xml"
testme "0" "serial" "-r -u $valid_uuid"
"$test_xml"
+sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e
"s,</devices>,<serial type='file'><source
path='$tmpdir/serial.log' startupPolicy='optional'/><target
port='0'/></serial></devices>,g" "$template_xml"
> "$test_xml"
+testme "0" "serial" "-r -u $valid_uuid"
"$test_xml"
+
sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e
"s,</devices>,<serial type='pty'><target
port='0'/></serial></devices>,g" "$template_xml"
> "$test_xml"
testme "0" "serial (pty)" "-r -u $valid_uuid"
"$test_xml"
--
1.7.1