[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=e5a84d74a2789a917bf394f15de9989ec48fded0 Signed-off-by: Seiji Aguchi <seiji.aguchi@xxxxxxx> --- 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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list