Jan, Thank you for reviewing. I will fix the patch in accordance with your comments. Seiji > -----Original Message----- > From: Ján Tomko [mailto:jtomko@xxxxxxxxxx] > Sent: Thursday, August 15, 2013 5:36 AM > To: Seiji Aguchi > Cc: libvir-list@xxxxxxxxxx > Subject: Re: [PATCH v3] xml: introduce startupPolicy for chardev device > > On 07/24/2013 10:05 PM, Seiji Aguchi wrote: > > [Problem] > > Currently, guest OS's messages can be logged to a local disk of host OS > > by creating chadevs with options below. > > s/chadevs/chardevs/ > > > -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" > > s/starupPolicy/startupPolicy/ > > > 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. > > s/to// > > > > > 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.aguchi@xxxxxxx> > > Signed-off-by: Eric Blake <eblake@xxxxxxxxxx> > > --- > > Change from v2 > > - To pass "make check", add followings. > > - Add serial source optional testing. > > - check if startupPolicy is NULL in virDomainChrSourceDefParseXML(). > > - Add xml format of startupPolicy in virDomainChrSourceDefFormat(). > > > > Patch v2 and comment from Eric Blake > > - https://www.redhat.com/archives/libvir-list/2013-May/msg01814.html > > - https://www.redhat.com/archives/libvir-list/2013-May/msg01943.html > > --- > > docs/formatdomain.html.in | 16 ++++++++- > > docs/schemas/domaincommon.rng | 3 ++ > > src/conf/domain_conf.c | 22 +++++++++++- > > src/conf/domain_conf.h | 1 + > > src/qemu/qemu_process.c | 25 +++++++++++++- > > .../qemuxml2argv-serial-source-optional.args | 9 +++++ > > .../qemuxml2argv-serial-source-optional.xml | 35 ++++++++++++++++++++ > > tests/qemuxml2argvtest.c | 2 + > > tests/qemuxml2xmltest.c | 1 + > > tests/virt-aa-helper-test | 3 ++ > > 10 files changed, 113 insertions(+), 4 deletions(-) > > create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-serial-source-optional.args > > create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-serial-source-optional.xml > > > > diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in > > index 7601aaa..5c9d4fb 100644 > > --- a/docs/formatdomain.html.in > > +++ b/docs/formatdomain.html.in > > @@ -4281,13 +4281,27 @@ 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> > > This isn't mentioned in the commit message or implemented in the patch. > We should either implement it or reject the "requisite" value. > > > + </ul> > > + > > <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 745b959..10b3365 100644 > > --- a/docs/schemas/domaincommon.rng > > +++ b/docs/schemas/domaincommon.rng > > @@ -2817,6 +2817,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 10cb7f6..279ff9e 100644 > > --- a/src/conf/domain_conf.c > > +++ b/src/conf/domain_conf.c > > @@ -6819,6 +6819,7 @@ virDomainChrSourceDefParseXML(virDomainChrSourceDefPtr def, > > char *path = NULL; > > char *mode = NULL; > > char *protocol = NULL; > > + char *startupPolicy = NULL; > > int remaining = 0; > > > > while (cur != NULL) { > > @@ -6839,6 +6840,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: > > @@ -6911,6 +6915,13 @@ virDomainChrSourceDefParseXML(virDomainChrSourceDefPtr def, > > > > def->data.file.path = path; > > path = NULL; > > + > > + if (startupPolicy) { > > + def->data.file.startupPolicy = > > + virDomainStartupPolicyTypeFromString(startupPolicy); > > > + startupPolicy = NULL; > > This line is pointless, the value of startupPolicy is not used after. > We need to VIR_FREE(startupPolicy) in the cleanup section instead, since > virXMLPropString allocates memory. > > > + } > > + > > break; > > > > case VIR_DOMAIN_CHR_TYPE_STDIO: > > @@ -15014,8 +15025,15 @@ virDomainChrSourceDefFormat(virBufferPtr buf, > > if (def->type != VIR_DOMAIN_CHR_TYPE_PTY || > > (def->data.file.path && > > !(flags & VIR_DOMAIN_XML_INACTIVE))) { > > - virBufferEscapeString(buf, " <source path='%s'/>\n", > > - def->data.file.path); > > + virBufferEscapeString(buf, " <source path='%s'", > > + def->data.file.path); > > + > > + if (def->data.file.path && def->data.file.startupPolicy) { > > + const char *policy = > > +virDomainStartupPolicyTypeToString(def->data.file.startupPolicy); > > + virBufferAsprintf(buf, " startupPolicy='%s'", policy); > > + } > > + virBufferAddLit(buf, "/>\n"); > > } > > break; > > > > diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h > > index f265966..0899556 100644 > > --- a/src/conf/domain_conf.h > > +++ b/src/conf/domain_conf.h > > @@ -1102,6 +1102,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 a46d944..35d63d5 100644 > > --- a/src/qemu/qemu_process.c > > +++ b/src/qemu/qemu_process.c > > @@ -2511,7 +2511,30 @@ qemuProcessPrepareChardevDevice(virDomainDefPtr def ATTRIBUTE_UNUSED, > > virReportSystemError(errno, > > _("Unable to pre-create chardev file '%s'"), > > dev->source.data.file.path); > > I think we should only report this error when startupPolicy is mandatory... > > > - 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"); > > .. and extend this warning to include the path, or even the system error, > or we should call virResetLastError here. > > > + dev->source.data.file.path = strdup("/dev/null"); > > + > > + if (!(dev->source.data.file.path)) { > > + virReportOOMError(); > > + return -1; > > + } > > + > > This can be reduced to: > if (VIR_STRDUP(dev->source.data.file.path, "/dev/null") < 0) > 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; > > + } > > } > > I think we can safely assume /dev/null to exist on any system where QEMU runs > and there's no need to pre-create it. > > Jan -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list