From: Seiji Aguchi <seiji.agu...@hds.com>

[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 cases 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=e5a84d74a278

Signed-off-by: Seiji Aguchi <seiji.agu...@hds.com>
Signed-off-by: Eric Blake <ebl...@redhat.com>
---

Seiji's patch plus my initial review comments; I've ack'd this much,
but want to add a round-trip xml2xml test before pushing anything
(Seiji, if you want to use this as a starting point, rather than
waiting for my long weekend, feel free to post a v3).

 docs/formatdomain.html.in     | 15 ++++++++++++++-
 docs/schemas/domaincommon.rng |  3 +++
 src/conf/domain_conf.c        |  8 ++++++++
 src/conf/domain_conf.h        |  1 +
 src/qemu/qemu_process.c       | 23 ++++++++++++++++-------
 tests/virt-aa-helper-test     |  3 +++
 6 files changed, 45 insertions(+), 8 deletions(-)

diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 755d084..299fa49 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -4212,13 +4212,26 @@ 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.
+      <span class="since">Since 1.0.6</span>, it is possible to define
+      policy on what happens if the file is not accessible when
+      booting or migrating. This is done by
+      a <code>startupPolicy</code> attribute:
     </p>
+    <ul>
+      <li>If the value is "mandatory" (the default), the guest fails
+      to boot or migrate if the file is not found.</li>
+      <li>If the value is "optional", a missing file is at boot or
+      migration is substituted with /dev/null, so the guest still sees
+      the device but the host no longer tracks guest data on the device.</li>
+      <li>If the value is "requisite", the file is required for
+      booting, but optional on migration.</li>
+    </ul>

 <pre>
   ...
   &lt;devices&gt;
     &lt;serial type="file"&gt;
-      &lt;source path="/var/log/vm/vm-serial.log"/&gt;
+      &lt;source path="/var/log/vm/vm-serial.log" startupPolicy="optional"/&gt;
       &lt;target port="1"/&gt;
     &lt;/serial&gt;
   &lt;/devices&gt;
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 3cace35..e8eec6c 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -2780,6 +2780,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 a9656af..c24a9f0 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -6626,6 +6626,7 @@ virDomainChrSourceDefParseXML(virDomainChrSourceDefPtr 
def,
     char *path = NULL;
     char *mode = NULL;
     char *protocol = NULL;
+    char *startupPolicy = NULL;
     int remaining = 0;

     while (cur != NULL) {
@@ -6646,6 +6647,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:
@@ -6718,6 +6722,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 3a71d6c..4d49dd5 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -1074,6 +1074,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 d4fd4fb..154445d 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -2439,15 +2439,24 @@ qemuProcessPrepareChardevDevice(virDomainDefPtr def 
ATTRIBUTE_UNUSED,
         return 0;

     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;
+                   O_CREAT | O_APPEND | O_RDONLY, S_IRUSR|S_IWUSR)) < 0) {
+        if (dev->source.data.file.startupPolicy !=
+            VIR_DOMAIN_STARTUP_POLICY_OPTIONAL) {
+            virReportSystemError(errno,
+                                 _("Unable to pre-create chardev file '%s'"),
+                                 dev->source.data.file.path);
+            return -1;
+        }
+        /* Change destination to /dev/null to work around missing file. */
+        VIR_WARN("chardev file '%s' not found, switching to /dev/null",
+                 dev->source.data.file.path);
+        VIR_FREE(dev->source.data.file.path);
+        if (VIR_STRDUP(dev->source.data.file.path, "/dev/null") < 0)
+            return -1;
+    } else {
+        VIR_FORCE_CLOSE(fd);
     }

-    VIR_FORCE_CLOSE(fd);
-
     return 0;
 }

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.8.1.4

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Reply via email to