<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Sat, Apr 28, 2018 at 1:11 AM, John Ferlan <span dir="ltr"><<a href="mailto:jferlan@redhat.com" target="_blank">jferlan@redhat.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class=""><br>
<br>
On 04/20/2018 04:59 AM, Prerna Saxena wrote:<br>
> So far libvirt domain XML only allows local filepaths that can be<br>
> used to specify a loader element or its matching NVRAM disk.<br>
> Given that Vms may themselves move across hypervisor hosts, it should be<br>
> possible to allocate loaders/NVRAM disks on network storage for<br>
> uninterrupted access.<br>
> <br>
> Signed-off-by: Prerna Saxena <<a href="mailto:saxenap.ltc@gmail.com">saxenap.ltc@gmail.com</a>><br>
> ---<br>
>  docs/schemas/domaincommon.rng   | 108 +++++++++++++++++++----<br>
>  src/conf/domain_conf.c          | 188 ++++++++++++++++++++++++++++++<wbr>++++++----<br>
>  src/conf/domain_conf.h          |   7 +-<br>
>  src/qemu/qemu_cgroup.c          |  13 ++-<br>
>  src/qemu/qemu_command.c         |  21 +++--<br>
>  src/qemu/qemu_domain.c          |  16 ++--<br>
>  src/qemu/qemu_driver.c          |   7 +-<br>
>  src/qemu/qemu_parse_command.c   |  30 ++++++-<br>
>  src/qemu/qemu_process.c         |  33 ++++---<br>
>  src/security/security_dac.c     |   6 +-<br>
>  src/security/security_selinux.<wbr>c |   6 +-<br>
>  11 files changed, 361 insertions(+), 74 deletions(-)<br>
> <br>
<br>
</span>I know on IRC you asked Peter or Michal to review (and they're CC'd<br>
here), but before they get a chance next week some time - I'll give you<br></blockquote><div><br></div><div>Thank you for taking a look.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
a quick look. You do understand Peter, Michal, myself, and other Red Hat<br>
libvirt developers follow libvir-list anyway - so CC'ing any of us<br>
doesn't do much since we filter into a mail folder anyway...<br>
<br></blockquote><div><br></div><div>I understand. Peter & Michal had participated in the original IRC discussion around the need for extending loader as a network backed device, and I had cc'ed them for context.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
This will need a v2 anyway because the patch has too much going on and<br>
needs to be split up more.<br></blockquote><div><br></div><div>Will do. I should have properly mentioned this was an RFC rather than a ready-to-merge patch, and that this currently excluded test and documentation fixes.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
You need to break out the domain_conf, docs, etc. changes into one<br>
patch. Much of what you put into the cover that describes the XML should </blockquote><div><br></div><div>Got it.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
go into this patch's commit message. There should be xml2xml test<br>
changes as well as adjustments to <a href="http://formatdomain.html.in" rel="noreferrer" target="_blank">formatdomain.html.in</a> to describe the<br>
new options. The part of the cover that says automatically reformatting<br>
to use the storage source cannot happen. There's precedence for that </blockquote><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
when the <encryption> and <auth> moved *into* the storage source we<br>
still have to accommodate for them outside. Internally, it can be placed<br>
as expected, but when formatting, we have to format as we read. After<br></blockquote><div><br></div><div><div style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:small;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial">Ok. I had explicitly asked around on IRC if it was okay "breaking" the existing XML  semantics. Peter had mentioned it was okay to have the XML read as its old semantic. The formatter could later "translate" the old -style absolute filepaths into the "new-style" source-description that is introduced.</div><div style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:small;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial">I had kept that in mind while implementing this patch. If that is not to be done, I will need to redo parts of this patch.</div></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
that, perhaps add the security changes in another, the cgroup in<br>
another, and finally the qemu adjustments in the last.  Not even sure if<br>
you need a capability as well.<br>
<br></blockquote><div><br></div><div>Why do you think we'd need a capability for this?  I'd be keen to understand why c<span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:small;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline">hanges to XML spec  </span>is not enough.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Finally this doesn't even compile for me.  You removed @path from<br>
_virDomainLoaderDef but neglected to adjust all consumers. I suggest<br>
using cscope and egrep'ing on "os.*loader->path" as well as ->nvram<br>
since you changed it's type.<br></blockquote><div><br></div><div>I know why. I had run and tested this to work, but my build configuration included the qemu driver and excluded every other driver. Given that this element extends to other drivers, I can understand the build issues. Again, should have mentioned this was an RFC.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
I assume you've considered that network storage types need to deal with<br>
authentication and encryption passphrases, right?  What about using a<br>
srcpool storage source?<br>
<br></blockquote><div><br></div><div>Erm, no. This patch does not include support for encryption/authenticaton. I will need to add those.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
I'll briefly scan the rest.<br>
<div><div class="h5"><br>
> diff --git a/docs/schemas/domaincommon.<wbr>rng b/docs/schemas/domaincommon.<wbr>rng<br>
> index 4cab55f..32db395 100644<br>
> --- a/docs/schemas/domaincommon.<wbr>rng<br>
> +++ b/docs/schemas/domaincommon.<wbr>rng<br>
> @@ -276,7 +276,42 @@<br>
>                  </choice><br>
>                </attribute><br>
>              </optional><br>
> -            <ref name="absFilePath"/><br>
> +            <optional><br>
> +              <attribute name="backing"><br>
> +                <choice><br>
> +                  <value>file</value><br>
> +                  <value>network</value><br>
> +                </choice><br>
> +              </attribute><br>
> +            </optional><br>
> +            <optional><br>
> +              <choice><br>
> +                 <group><br>
> +                  <ref name="absFilePath"/><br>
> +                 </group><br>
> +                 <group><br>
> +                  <ref name="diskSourceFileElement"/><br>
> +                 </group><br>
> +                 <group><br>
> +                  <ref name="<wbr>diskSourceNetworkProtocolNBD"/<wbr>><br>
> +                 </group><br>
> +                 <group><br>
> +                  <ref name="<wbr>diskSourceNetworkProtocolGlust<wbr>er"/><br>
> +                 </group><br>
> +                 <group><br>
> +                  <ref name="<wbr>diskSourceNetworkProtocolRBD"/<wbr>><br>
> +                 </group><br>
> +                 <group><br>
> +                  <ref name="<wbr>diskSourceNetworkProtocolISCSI<wbr>"/><br>
> +                 </group><br>
> +                 <group><br>
> +                  <ref name="<wbr>diskSourceNetworkProtocolHTTP"<wbr>/><br>
> +                 </group><br>
> +                 <group><br>
> +                  <ref name="<wbr>diskSourceNetworkProtocolSimpl<wbr>e"/><br>
> +                 </group><br>
> +              </choice><br>
> +            </optional><br>
>            </element><br>
>          </optional><br>
>          <optional><br>
> @@ -287,7 +322,40 @@<br>
>                </attribute><br>
>              </optional><br>
>              <optional><br>
> -              <ref name="absFilePath"/><br>
> +              <attribute name="backing"><br>
> +                <choice><br>
> +                  <value>file</value><br>
> +                  <value>network</value><br>
> +                </choice><br>
> +              </attribute><br>
> +            </optional><br>
> +            <optional><br>
> +              <choice><br>
> +                 <group><br>
> +                  <ref name="absFilePath"/><br>
> +                 </group><br>
> +                 <group><br>
> +                  <ref name="diskSourceFileElement"/><br>
> +                 </group><br>
> +                 <group><br>
> +                  <ref name="<wbr>diskSourceNetworkProtocolNBD"/<wbr>><br>
> +                 </group><br>
> +                 <group><br>
> +                  <ref name="<wbr>diskSourceNetworkProtocolGlust<wbr>er"/><br>
> +                 </group><br>
> +                 <group><br>
> +                  <ref name="<wbr>diskSourceNetworkProtocolRBD"/<wbr>><br>
> +                 </group><br>
> +                 <group><br>
> +                  <ref name="<wbr>diskSourceNetworkProtocolISCSI<wbr>"/><br>
> +                 </group><br>
> +                 <group><br>
> +                  <ref name="<wbr>diskSourceNetworkProtocolHTTP"<wbr>/><br>
> +                 </group><br>
> +                 <group><br>
> +                  <ref name="<wbr>diskSourceNetworkProtocolSimpl<wbr>e"/><br>
> +                 </group><br>
> +              </choice><br>
>              </optional><br>
>            </element><br>
>          </optional><br>
> @@ -1494,25 +1562,29 @@<br>
>        </attribute><br>
>      </optional><br>
>      <optional><br>
> -      <element name="source"><br>
> -        <optional><br>
> -          <attribute name="file"><br>
> -            <ref name="absFilePath"/><br>
> -          </attribute><br>
> -        </optional><br>
> -        <optional><br>
> -          <ref name="storageStartupPolicy"/><br>
> -        </optional><br>
> -        <optional><br>
> -          <ref name="encryption"/><br>
> -        </optional><br>
> -        <zeroOrMore><br>
> -          <ref name='devSeclabel'/><br>
> -        </zeroOrMore><br>
> -      </element><br>
> +      <ref name='diskSourceFileElement'/><br>
>      </optional><br>
>    </define><br>
>  <br>
> +  <define name="diskSourceFileElement"><br>
> +    <element name="source"><br>
> +      <optional><br>
> +        <attribute name="file"><br>
> +          <ref name="absFilePath"/><br>
> +        </attribute><br>
> +      </optional><br>
> +      <optional><br>
> +        <ref name="storageStartupPolicy"/><br>
> +      </optional><br>
> +      <optional><br>
> +        <ref name="encryption"/><br>
> +      </optional><br>
> +      <zeroOrMore><br>
> +        <ref name='devSeclabel'/><br>
> +      </zeroOrMore><br>
> +    </element><br>
> +  </define><br>
> +<br>
>    <define name="diskSourceBlock"><br>
>      <attribute name="type"><br>
>        <value>block</value><br>
> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c<br>
> index 35666c1..c80f9d9 100644<br>
> --- a/src/conf/domain_conf.c<br>
> +++ b/src/conf/domain_conf.c<br>
> @@ -2883,8 +2883,8 @@ virDomainLoaderDefFree(<wbr>virDomainLoaderDefPtr loader)<br>
>      if (!loader)<br>
>          return;<br>
>  <br>
> -    VIR_FREE(loader->path);<br>
> -    VIR_FREE(loader->nvram);<br>
> +    virStorageSourceFree(loader-><wbr>loader_src);<br>
<br>
</div></div>loader_src is redundant to loader isn't it?<br></blockquote><div><br></div><div>Should this just be called "src" ? I was not sure if this sounded ambiguous.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<span class=""><br>
> +    virStorageSourceFree(loader-><wbr>nvram);<br>
>      VIR_FREE(loader->templt);<br>
>      VIR_FREE(loader);<br>
>  }<br>
> @@ -17961,17 +17961,59 @@ virDomainDefMaybeAddHostdevSCS<wbr>Icontroller(virDomainDefPtr def)<br>
>  <br>
>  static int<br>
>  virDomainLoaderDefParseXML(<wbr>xmlNodePtr node,<br>
> +                           xmlXPathContextPtr ctxt,<br>
>                             virDomainLoaderDefPtr loader)<br>
>  {<br>
>      int ret = -1;<br>
>      char *readonly_str = NULL;<br>
>      char *secure_str = NULL;<br>
>      char *type_str = NULL;<br>
> +    char *tmp = NULL;<br>
> +    xmlNodePtr cur;<br>
> +    xmlXPathContextPtr cur_ctxt = ctxt;<br>
> +<br>
> +    if (VIR_ALLOC(loader->loader_src)<wbr>) {<br>
> +        goto cleanup;<br>
> +    }<br>
<br>
</span>syntax-check would choke here with the unnecessary { }<br></blockquote><div><br></div><div>Will remove.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<span class=""><br>
> +    loader->loader_src->type = VIR_STORAGE_TYPE_LAST;<br>
<br>
</span>ug, ah, no.<br>
<br>
Consider my comment from above - you have either "path" or "source" and<br>
deal with it from there. When you format you need to format as you read.<br>
<div><div class="h5"><br></div></div></blockquote><div><br></div><div>As I mentioned above, I had understood that we deprecate the old format in favour of the new. I also believe that the new is a superset of the old:</div><div>Eg, the old spec said :</div><div><loader>/usr/share/OVMF/OVMF_CODE.fd</loader></div><div><br></div><div>The new one should expect the same thing as:</div><div><loader backing='file'><source file='/usr/share/OVMF/OVMF_CODE.fd'/></loader></div><div><br></div><div>So, if you notice, the two are not really distinct but rather the new spec is a better description of the old.</div><div>So personally, I would prefer deprecating the old style format in favour of new. </div><div>However, I'd go with community recommendation.</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div class="h5">
>  <br>
>      readonly_str = virXMLPropString(node, "readonly");<br>
>      secure_str = virXMLPropString(node, "secure");<br>
>      type_str = virXMLPropString(node, "type");<br>
> -    loader->path = (char *) xmlNodeGetContent(node);<br>
> +<br>
> +    if ((tmp = virXMLPropString(node, "backing")) &&<br>
> +        (loader->loader_src->type = virStorageTypeFromString(tmp)) <= 0) {<br>
> +        virReportError(VIR_ERR_CONFIG_<wbr>UNSUPPORTED,<br>
> +                       _("unknown loader type '%s'"), tmp);<br>
> +        goto cleanup;<br>
> +    }<br>
> +    VIR_FREE(tmp);<br>
> +<br>
> +    for (cur = node->children; cur != NULL; cur = cur->next) {<br>
> +        if (cur->type != XML_ELEMENT_NODE) {<br>
> +            continue;<br>
> +        }<br>
> +<br>
> +        if (virXMLNodeNameEqual(cur, "source")) {<br>
> +            if (virDomainStorageSourceParse(<wbr>cur, cur_ctxt, loader->loader_src, 0) < 0) {<br>
> +                virReportError(VIR_ERR_XML_<wbr>DETAIL,<br>
> +                               _("Error parsing Loader source element"));<br>
> +                goto cleanup;<br>
> +            }<br>
> +            break;<br>
> +        }<br>
> +    }<br>
> +<br>
> +    /* Old-style absolute path found ? */<br>
> +    if (loader->loader_src->type == VIR_STORAGE_TYPE_LAST) {<br>
> +        if (!(loader->loader_src->path = (char *) xmlNodeGetContent(node))) {<br>
> +            virReportError(VIR_ERR_XML_<wbr>ERROR, "%s",<br>
> +                           _("missing loader source"));<br>
> +            goto cleanup;<br>
> +        } else {<br>
> +            loader->loader_src->type = VIR_STORAGE_TYPE_FILE;<br>
> +        }<br>
> +    }<br>
<br>
</div></div>You need to find a different way.  If you find <source>, then parse it.<br>
If you find <path> then you parse it instead.<br>
<span class=""><br></span></blockquote><div><br></div><div>Pls see my comment above on why the two should not be treated as distinct options.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">
>  <br>
>      if (readonly_str &&<br>
>          (loader->readonly = virTristateBoolTypeFromString(<wbr>readonly_str)) <= 0) {<br>
> @@ -17998,13 +18040,78 @@ virDomainLoaderDefParseXML(<wbr>xmlNodePtr node,<br>
>      }<br>
>  <br>
>      ret = 0;<br>
> - cleanup:<br>
> +    goto exit;<br>
> +cleanup:<br>
> +    if (loader->loader_src)<br>
> +      VIR_FREE(loader->loader_src);<br>
> +exit:<br>
<br>
</span>This is not the way we handle this.<br>
<br></blockquote><div><br></div><div>Will fix.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
>      VIR_FREE(readonly_str);<br>
>      VIR_FREE(secure_str);<br>
>      VIR_FREE(type_str);<br>
> +<br>
<br>
extraneous<br></blockquote><div><br></div><div>Will remove.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
>      return ret;<br>
>  }<br>
>  <br>
<br>
Two blank lines.<br></blockquote><div><br></div><div>Will remove.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<span class=""><br>
> +static int<br>
> +<wbr>virDomainLoaderNvramDefParseXM<wbr>L(xmlNodePtr node,<br>
> +                           xmlXPathContextPtr ctxt,<br>
> +                           virDomainLoaderDefPtr loader)<br>
> +{<br>
> +    int ret = -1;<br>
> +    char *tmp = NULL;<br>
> +    xmlNodePtr cur;<br>
> +<br>
> +    if (VIR_ALLOC(loader->nvram)) {<br>
> +        goto cleanup;<br>
> +    }<br>
<br>
</span>Again { }<br></blockquote><div><br></div><div>Sorry.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
Similar problem to before w/r/t the XML processing here.<br>
<div><div class="h5"><br>
> +<br>
> +    loader->nvram->type = VIR_STORAGE_TYPE_LAST;<br>
> +<br>
> +    if ((tmp = virXMLPropString(node, "backing")) &&<br>
> +        (loader->nvram->type = virStorageTypeFromString(tmp)) <= 0) {<br>
> +        virReportError(VIR_ERR_CONFIG_<wbr>UNSUPPORTED,<br>
> +                       _("unknown nvram type '%s'"), tmp);<br>
> +        goto cleanup;<br>
> +    }<br>
> +    VIR_FREE(tmp);<br>
> +<br>
> +    for (cur = node->children; cur != NULL; cur = cur->next) {<br>
> +        if (cur->type != XML_ELEMENT_NODE) {<br>
> +            continue;<br>
> +        }<br>
> +<br>
> +        if (virXMLNodeNameEqual(cur, "template")) {<br>
> +            loader->templt = virXPathString("string(./os/<wbr>nvram[1]/@template)", ctxt);<br>
> +            continue;<br>
> +        }<br>
> +<br>
> +        if (virXMLNodeNameEqual(cur, "source")) {<br>
> +            if (virDomainStorageSourceParse(<wbr>cur, ctxt, loader->nvram, 0) < 0) {<br>
> +                virReportError(VIR_ERR_XML_<wbr>DETAIL,<br>
> +                               _("Error parsing nvram source element"));<br>
> +                goto cleanup;<br>
> +            }<br>
> +            ret = 0;<br>
> +        }<br>
> +    }<br>
> +<br>
> +    if (loader->nvram->type == VIR_STORAGE_TYPE_LAST) {<br>
> +        if (!(loader->nvram->path = (char *) xmlNodeGetContent(node))) {<br>
> +            virReportError(VIR_ERR_XML_<wbr>ERROR, "%s",<br>
> +                           _("missing nvram source"));<br>
> +            goto cleanup;<br>
> +        } else {<br>
> +            loader->nvram->type = VIR_STORAGE_TYPE_FILE;<br>
> +            ret = 0;<br>
> +        }<br>
> +    }<br>
> +    return ret;<br>
> +<br>
> +cleanup:<br>
> +    if (loader->nvram)<br>
> +      VIR_FREE(loader->nvram);<br>
> +    return ret;<br>
> +}<br>
>  <br>
>  static virBitmapPtr<br>
>  virDomainSchedulerParse(<wbr>xmlNodePtr node,<br>
> @@ -18397,11 +18504,15 @@ virDomainDefParseBootOptions(<wbr>virDomainDefPtr def,<br>
>              if (VIR_ALLOC(def->os.loader) < 0)<br>
>                  goto error;<br>
>  <br>
> -            if (virDomainLoaderDefParseXML(<wbr>loader_node, def->os.loader) < 0)<br>
> +            def->os.loader->loader_src = NULL;<br>
> +            def->os.loader->nvram = NULL;<br>
> +            if (virDomainLoaderDefParseXML(<wbr>loader_node, ctxt, def->os.loader) < 0)<br>
>                  goto error;<br>
>  <br>
> -            def->os.loader->nvram = virXPathString("string(./os/<wbr>nvram[1])", ctxt);<br>
> -            def->os.loader->templt = virXPathString("string(./os/<wbr>nvram[1]/@template)", ctxt);<br>
> +            if ((loader_node = virXPathNode("./os/nvram[1]", ctxt)) &&<br>
> +                (<wbr>virDomainLoaderNvramDefParseXM<wbr>L(loader_node, ctxt,<br>
> +                                                 def->os.loader) < 0))<br>
> +                    goto error;<br>
<br>
</div></div>don't reuse "loader_node" for "nvram_node".<br></blockquote><div><br></div><div>Will add a separate ptr.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
I think you need to separate loader patches from nvram patches too.<br>
It'll perhaps make things easier to review again eventually.<br></blockquote><div><br></div><div>Will do.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<span class=""><br>
>          }<br>
>      }<br>
>  <br>
> @@ -26070,11 +26181,19 @@ virDomainHugepagesFormat(<wbr>virBufferPtr buf,<br>
>  <br>
>  static void<br>
>  virDomainLoaderDefFormat(<wbr>virBufferPtr buf,<br>
> -                         virDomainLoaderDefPtr loader)<br>
> +                         virDomainLoaderDefPtr loader,<br>
> +                         unsigned int flags)<br>
<br>
</span>As noted earlier reading in one format means we write out in the same<br>
format. If someone wants to use the new format, then they can.<br></blockquote><div><br></div><div>Hmm, as mentioned, this was not the assumption on which this patch was based. </div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div><div class="h5"><br>
>  {<br>
>      const char *readonly = virTristateBoolTypeToString(<wbr>loader->readonly);<br>
>      const char *secure = virTristateBoolTypeToString(<wbr>loader->secure);<br>
>      const char *type = virDomainLoaderTypeToString(<wbr>loader->type);<br>
> +    const char *backing = NULL;<br>
> +<br>
> +    virBuffer attrBuf = VIR_BUFFER_INITIALIZER;<br>
> +    virBuffer childBuf = VIR_BUFFER_INITIALIZER;<br>
> +<br>
> +    virBufferSetChildIndent(&<wbr>childBuf, buf);<br>
> +<br>
>  <br>
>      virBufferAddLit(buf, "<loader");<br>
>  <br>
> @@ -26084,17 +26203,54 @@ virDomainLoaderDefFormat(<wbr>virBufferPtr buf,<br>
>      if (loader->secure)<br>
>          virBufferAsprintf(buf, " secure='%s'", secure);<br>
>  <br>
> -    virBufferAsprintf(buf, " type='%s'>", type);<br>
> +    virBufferAsprintf(buf, " type='%s'", type);<br>
> +    if (loader->loader_src &&<br>
> +        loader->loader_src->type != VIR_STORAGE_TYPE_LAST) {<br>
> +        if (virDomainStorageSourceFormat(<wbr>&attrBuf, &childBuf, loader->loader_src,<br>
> +                                     flags, 0) < 0)<br>
> +            goto cleanup;<br>
> +<br>
> +        backing = virStorageTypeToString(loader-<wbr>>loader_src->type);<br>
> +        virBufferAsprintf(buf, " backing='%s'>", backing);<br>
> +<br>
> +        if (virXMLFormatElement(buf, "source", &attrBuf, &childBuf) < 0)<br>
> +            goto cleanup;<br>
> +    } else {<br>
> +        virBufferAddLit(buf, ">\n");<br>
> +    }<br>
> +<br>
> +    virBufferAddLit(buf, "</loader>\n");<br>
>  <br>
> -    virBufferEscapeString(buf, "%s</loader>\n", loader->path);<br>
>      if (loader->nvram || loader->templt) {<br>
> -        virBufferAddLit(buf, "<nvram");<br>
> -        virBufferEscapeString(buf, " template='%s'", loader->templt);<br>
> +        ignore_value(<wbr>virBufferContentAndReset(&<wbr>attrBuf));<br>
> +        ignore_value(<wbr>virBufferContentAndReset(&<wbr>childBuf));<br>
> +        virBufferSetChildIndent(&<wbr>childBuf, buf);<br>
> +<br>
>          if (loader->nvram)<br>
> -            virBufferEscapeString(buf, ">%s</nvram>\n", loader->nvram);<br>
> -        else<br>
> -            virBufferAddLit(buf, "/>\n");<br>
> +            backing = virStorageTypeToString(loader-<wbr>>nvram->type);<br>
> +<br>
> +        virBufferAddLit(buf, "<nvram");<br>
> +        if (loader->templt) {<br>
> +            virBufferEscapeString(buf, " template='%s'", loader->templt);<br>
> +        }<br>
> +        if (loader->nvram &&<br>
> +            (virDomainStorageSourceFormat(<wbr>&attrBuf, &childBuf,<br>
> +                                         loader->nvram, flags, 0) < 0)) {<br>
> +            virBufferAddLit(buf, ">\n</nvram>\n");<br>
> +            goto cleanup;<br>
> +        }<br>
> +<br>
> +        virBufferEscapeString(buf, " backing='%s'>", backing);<br>
> +        if (virXMLFormatElement(buf, "source", &attrBuf, &childBuf) < 0) {<br>
> +            virBufferAddLit(buf, "</nvram>\n");<br>
> +            goto cleanup;<br>
> +        }<br>
> +        virBufferAddLit(buf, "</nvram>\n");<br>
>      }<br>
> +cleanup:<br>
> +    virBufferFreeAndReset(&<wbr>attrBuf);<br>
> +    virBufferFreeAndReset(&<wbr>childBuf);<br>
> +    return;<br>
>  }<br>
>  <br>
>  static void<br>
> @@ -26757,7 +26913,7 @@ virDomainDefFormatInternal(<wbr>virDomainDefPtr def,<br>
>          virBufferAsprintf(buf, "<initgroup>%s</initgroup>\n", def->os.initgroup);<br>
>  <br>
>      if (def->os.loader)<br>
> -        virDomainLoaderDefFormat(buf, def->os.loader);<br>
> +        virDomainLoaderDefFormat(buf, def->os.loader, flags);<br>
>      virBufferEscapeString(buf, "<kernel>%s</kernel>\n",<br>
>                            def->os.kernel);<br>
>      virBufferEscapeString(buf, "<initrd>%s</initrd>\n",<br>
> diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h<br>
> index 3c7eccb..50d5ac3 100644<br>
> --- a/src/conf/domain_conf.h<br>
> +++ b/src/conf/domain_conf.h<br>
> @@ -1857,14 +1857,17 @@ typedef enum {<br>
>  <br>
>  VIR_ENUM_DECL(virDomainLoader)<br>
>  <br>
> +struct _virStorageSource;<br>
> +typedef struct _virStorageSource* virStorageSourcePtr;<br>
> +<br>
>  typedef struct _virDomainLoaderDef virDomainLoaderDef;<br>
>  typedef virDomainLoaderDef *virDomainLoaderDefPtr;<br>
>  struct _virDomainLoaderDef {<br>
> -    char *path;<br>
> +    virStorageSourcePtr loader_src;<br>
<br>
</div></div>You'll probably need a way to booleanize which format was read. I forget<br>
how things were done for encryption and auth changes that I made.<br></blockquote><div><br></div><div>Will check.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div><div class="h5"><br>
>      int readonly;   /* enum virTristateBool */<br>
>      virDomainLoader type;<br>
>      int secure;     /* enum virTristateBool */<br>
> -    char *nvram;    /* path to non-volatile RAM */<br>
> +    virStorageSourcePtr nvram;  /* path to non-voliatile RAM */<br>
>      char *templt;   /* user override of path to master nvram */<br>
>  };<br>
>  <br>
> diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c<br>
> index d88eb78..aa5d071 100644<br>
> --- a/src/qemu/qemu_cgroup.c<br>
> +++ b/src/qemu/qemu_cgroup.c<br>
> @@ -580,16 +580,21 @@ qemuSetupMemoryCgroup(<wbr>virDomainObjPtr vm)<br>
>  static int<br>
>  qemuSetupFirmwareCgroup(<wbr>virDomainObjPtr vm)<br>
>  {<br>
> +    virStorageSourcePtr src = NULL;<br>
> +<br>
>      if (!vm->def->os.loader)<br>
>          return 0;<br>
>  <br>
> -    if (vm->def->os.loader->path &&<br>
> -        qemuSetupImagePathCgroup(vm, vm->def->os.loader->path,<br>
> -                                 vm->def->os.loader->readonly == VIR_TRISTATE_BOOL_YES) < 0)<br>
> +    src = vm->def->os.loader->loader_<wbr>src;<br>
> +    if (src->path &&<br>
> +        src->type == VIR_STORAGE_TYPE_FILE &&<br>
> +        qemuSetupImagePathCgroup(vm, src->path,<br>
> +                                 src->readonly == VIR_TRISTATE_BOOL_YES) < 0)<br>
>          return -1;<br>
>  <br>
>      if (vm->def->os.loader->nvram &&<br>
> -        qemuSetupImagePathCgroup(vm, vm->def->os.loader->nvram, false) < 0)<br>
> +        vm->def->os.loader->nvram-><wbr>type == VIR_STORAGE_TYPE_FILE &&<br>
> +        qemuSetupImagePathCgroup(vm, vm->def->os.loader->nvram-><wbr>path, false) < 0)<br>
>          return -1;<br>
>  <br>
>      return 0;<br>
> diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c<br>
> index 238c6ed..279a06c 100644<br>
> --- a/src/qemu/qemu_command.c<br>
> +++ b/src/qemu/qemu_command.c<br>
> @@ -9293,6 +9293,7 @@ qemuBuildDomainLoaderCommandLi<wbr>ne(virCommandPtr cmd,<br>
>      virDomainLoaderDefPtr loader = def->os.loader;<br>
>      virBuffer buf = VIR_BUFFER_INITIALIZER;<br>
>      int unit = 0;<br>
> +    char *source = NULL;<br>
>  <br>
>      if (!loader)<br>
>          return;<br>
> @@ -9300,7 +9301,7 @@ qemuBuildDomainLoaderCommandLi<wbr>ne(virCommandPtr cmd,<br>
>      switch ((virDomainLoader) loader->type) {<br>
>      case VIR_DOMAIN_LOADER_TYPE_ROM:<br>
>          virCommandAddArg(cmd, "-bios");<br>
> -        virCommandAddArg(cmd, loader->path);<br>
> +        virCommandAddArg(cmd, loader->loader_src->path);<br>
>          break;<br>
>  <br>
>      case VIR_DOMAIN_LOADER_TYPE_PFLASH:<br>
> @@ -9312,9 +9313,14 @@ qemuBuildDomainLoaderCommandLi<wbr>ne(virCommandPtr cmd,<br>
>                                   NULL);<br>
>          }<br>
>  <br>
> +        if (qemuGetDriveSourceString(<wbr>loader->loader_src, NULL, &source) < 0)<br>
> +            break;<br>
> +<br>
>          virBufferAddLit(&buf, "file=");<br>
> -        virQEMUBuildBufferEscapeComma(<wbr>&buf, loader->path);<br>
> -        virBufferAsprintf(&buf, ",if=pflash,format=raw,unit=%<wbr>d", unit);<br>
> +        virQEMUBuildBufferEscapeComma(<wbr>&buf, source);<br>
> +        free(source);<br>
> +        virBufferAsprintf(&buf, ",if=pflash,format=raw,unit=%<wbr>d",<br>
> +                          unit);<br>
<br>
</div></div>What happens if there's authentication or encryption? is that not supported?<br></blockquote><div><br></div><div>Not supported in this patch, as I had not scoped for it. Will add.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div><div class="h5"><br>
>          unit++;<br>
>  <br>
>          if (loader->readonly) {<br>
> @@ -9327,9 +9333,14 @@ qemuBuildDomainLoaderCommandLi<wbr>ne(virCommandPtr cmd,<br>
>  <br>
>          if (loader->nvram) {<br>
>              virBufferFreeAndReset(&buf);<br>
> +            if (qemuGetDriveSourceString(<wbr>loader->nvram, NULL, &source) < 0)<br>
> +                break;<br>
> +<br>
>              virBufferAddLit(&buf, "file=");<br>
> -            virQEMUBuildBufferEscapeComma(<wbr>&buf, loader->nvram);<br>
> -            virBufferAsprintf(&buf, ",if=pflash,format=raw,unit=%<wbr>d", unit);<br>
> +            virQEMUBuildBufferEscapeComma(<wbr>&buf, source);<br>
> +            virBufferAsprintf(&buf, ",if=pflash,format=raw,unit=%<wbr>d",<br>
> +                              unit);<br>
> +            unit++;<br>
>  <br>
>              virCommandAddArg(cmd, "-drive");<br>
>              virCommandAddArgBuffer(cmd, &buf);<br>
> diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c<br>
> index 21897cb..c1cb751 100644<br>
> --- a/src/qemu/qemu_domain.c<br>
> +++ b/src/qemu/qemu_domain.c<br>
> @@ -3312,8 +3312,10 @@ qemuDomainDefPostParse(<wbr>virDomainDefPtr def,<br>
>      if (def->os.loader &&<br>
>          def->os.loader->type == VIR_DOMAIN_LOADER_TYPE_PFLASH &&<br>
>          def->os.loader->readonly == VIR_TRISTATE_SWITCH_ON &&<br>
> -        !def->os.loader->nvram) {<br>
> -        if (virAsprintf(&def->os.loader-><wbr>nvram, "%s/%s_VARS.fd",<br>
> +        def->os.loader->nvram &&<br>
> +        def->os.loader->nvram->type == VIR_STORAGE_TYPE_FILE &&<br>
> +        !def->os.loader->nvram->path) {<br>
> +        if (virAsprintf(&def->os.loader-><wbr>nvram->path, "%s/%s_VARS.fd",<br>
>                          cfg->nvramDir, def->name) < 0)<br>
>              goto cleanup;<br>
>      }<br>
> @@ -10477,19 +10479,21 @@ qemuDomainSetupLoader(<wbr>virQEMUDriverConfigPtr cfg ATTRIBUTE_UNUSED,<br>
>  <br>
>      VIR_DEBUG("Setting up loader");<br>
>  <br>
> -    if (loader) {<br>
> +    if (loader && loader->loader_src &&<br>
> +        loader->loader_src->type == VIR_STORAGE_TYPE_FILE) {<br>
>          switch ((virDomainLoader) loader->type) {<br>
>          case VIR_DOMAIN_LOADER_TYPE_ROM:<br>
> -            if (qemuDomainCreateDevice(<wbr>loader->path, data, false) < 0)<br>
> +            if (qemuDomainCreateDevice(<wbr>loader->loader_src->path, data, false) < 0)<br>
>                  goto cleanup;<br>
>              break;<br>
>  <br>
>          case VIR_DOMAIN_LOADER_TYPE_PFLASH:<br>
> -            if (qemuDomainCreateDevice(<wbr>loader->path, data, false) < 0)<br>
> +            if (qemuDomainCreateDevice(<wbr>loader->loader_src->path, data, false) < 0)<br>
>                  goto cleanup;<br>
>  <br>
>              if (loader->nvram &&<br>
> -                qemuDomainCreateDevice(loader-<wbr>>nvram, data, false) < 0)<br>
> +                loader->nvram->type == VIR_STORAGE_TYPE_FILE &&<br>
> +                qemuDomainCreateDevice(loader-<wbr>>nvram->path, data, false) < 0)<br>
>                  goto cleanup;<br>
>              break;<br>
>  <br>
> diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c<br>
> index 5673d9f..ce6339d 100644<br>
> --- a/src/qemu/qemu_driver.c<br>
> +++ b/src/qemu/qemu_driver.c<br>
> @@ -7542,12 +7542,13 @@ qemuDomainUndefineFlags(<wbr>virDomainPtr dom,<br>
>  <br>
>      if (vm->def->os.loader &&<br>
>          vm->def->os.loader->nvram &&<br>
> -        virFileExists(vm->def->os.<wbr>loader->nvram)) {<br>
> +        vm->def->os.loader->nvram-><wbr>type == VIR_STORAGE_TYPE_FILE &&<br>
> +        virFileExists(vm->def->os.<wbr>loader->nvram->path)) {<br>
>          if ((flags & VIR_DOMAIN_UNDEFINE_NVRAM)) {<br>
> -            if (unlink(vm->def->os.loader-><wbr>nvram) < 0) {<br>
> +            if (unlink(vm->def->os.loader-><wbr>nvram->path) < 0) {<br>
>                  virReportSystemError(errno,<br>
>                                       _("failed to remove nvram: %s"),<br>
> -                                     vm->def->os.loader->nvram);<br>
> +                                     vm->def->os.loader->nvram-><wbr>path);<br>
>                  goto endjob;<br>
>              }<br>
>          } else if (!(flags & VIR_DOMAIN_UNDEFINE_KEEP_<wbr>NVRAM)) {<br>
> diff --git a/src/qemu/qemu_parse_command.<wbr>c b/src/qemu/qemu_parse_command.<wbr>c<br>
> index 0ce9632..2a0b200 100644<br>
> --- a/src/qemu/qemu_parse_command.<wbr>c<br>
> +++ b/src/qemu/qemu_parse_command.<wbr>c<br>
> @@ -650,6 +650,7 @@ qemuParseCommandLineDisk(<wbr>virDomainXMLOptionPtr xmlopt,<br>
>      int idx = -1;<br>
>      int busid = -1;<br>
>      int unitid = -1;<br>
> +    bool is_firmware = false;<br>
<br>
</div></div>wow - changing this code too...  not everyone does this!  I really doubt<br>
the code even really works very well any more.<br></blockquote><div><br></div><div>Added for completeness. Pls let me know if you would want me to drop this.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div><div class="h5"><br>
>  <br>
>      if (qemuParseKeywords(val,<br>
>                            &keywords,<br>
> @@ -772,6 +773,9 @@ qemuParseCommandLineDisk(<wbr>virDomainXMLOptionPtr xmlopt,<br>
>                  def->bus = VIR_DOMAIN_DISK_BUS_VIRTIO;<br>
>              } else if (STREQ(values[i], "xen")) {<br>
>                  def->bus = VIR_DOMAIN_DISK_BUS_XEN;<br>
> +            } else if (STREQ(values[i], "pflash")) {<br>
> +                def->bus = VIR_DOMAIN_DISK_BUS_LAST;<br>
> +                is_firmware = true;<br>
>              } else if (STREQ(values[i], "sd")) {<br>
>                  def->bus = VIR_DOMAIN_DISK_BUS_SD;<br>
>              }<br>
> @@ -943,8 +947,25 @@ qemuParseCommandLineDisk(<wbr>virDomainXMLOptionPtr xmlopt,<br>
>          ignore_value(VIR_STRDUP(def-><wbr>dst, "hda"));<br>
>      }<br>
>  <br>
> -    if (!def->dst)<br>
> -        goto error;<br>
> +    if (!def->dst) {<br>
> +        if (is_firmware && def->bus == VIR_DOMAIN_DISK_BUS_LAST) {<br>
> +            if (!dom->os.loader && (VIR_ALLOC(dom->os.loader) < 0))<br>
> +                goto error;<br>
> +            if (def->src->readonly) {<br>
> +                /* Loader spec */<br>
> +                dom->os.loader->loader_src = def->src;<br>
> +                dom->os.loader->type = VIR_DOMAIN_LOADER_TYPE_PFLASH;<br>
> +            } else {<br>
> +                /* NVRAM Spec */<br>
> +                if (!dom->os.loader->nvram && (VIR_ALLOC(dom->os.loader-><wbr>nvram) < 0))<br>
> +                    goto error;<br>
> +                dom->os.loader->nvram = def->src;<br>
> +            }<br>
> +        } else {<br>
> +            goto error;<br>
> +        }<br>
> +    }<br>
> +<br>
>      if (STREQ(def->dst, "xvda"))<br>
>          def->dst[3] = 'a' + idx;<br>
>      else<br>
> @@ -2215,8 +2236,11 @@ qemuParseCommandLine(<wbr>virCapsPtr caps,<br>
>          } else if (STREQ(arg, "-bios")) {<br>
>              WANT_VALUE();<br>
>              if (VIR_ALLOC(def->os.loader) < 0 ||<br>
> -                VIR_STRDUP(def->os.loader-><wbr>path, val) < 0)<br>
> +                VIR_ALLOC(def->os.loader-><wbr>loader_src) < 0 ||<br>
> +                VIR_STRDUP(def->os.loader-><wbr>loader_src->path, val) < 0)<br>
>                  goto error;<br>
> +            def->os.loader->loader_src-><wbr>type = VIR_STORAGE_TYPE_FILE;<br>
> +            def->os.loader->type = VIR_DOMAIN_LOADER_TYPE_ROM;<br>
>          } else if (STREQ(arg, "-initrd")) {<br>
>              WANT_VALUE();<br>
>              if (VIR_STRDUP(def->os.initrd, val) < 0)<br>
> diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c<br>
> index 6a5262a..725dd6e 100644<br>
> --- a/src/qemu/qemu_process.c<br>
> +++ b/src/qemu/qemu_process.c<br>
> @@ -3994,25 +3994,32 @@ qemuPrepareNVRAM(<wbr>virQEMUDriverConfigPtr cfg,<br>
>      const char *master_nvram_path;<br>
>      ssize_t r;<br>
>  <br>
> -    if (!loader || !loader->nvram || virFileExists(loader->nvram))<br>
> +    if (!loader || !loader->loader_src || !loader->nvram ||<br>
> +        loader->nvram->type == VIR_STORAGE_TYPE_NETWORK)<br>
>          return 0;<br>
>  <br>
>      master_nvram_path = loader->templt;<br>
> -    if (!loader->templt) {<br>
> +    /* Even if a template is not specified, we associate "known" EFI firmware<br>
> +     * to their NVRAM templates.<br>
> +     * Ofcourse this only applies to local firmware paths, as it is diffcult<br>
> +     * for libvirt to parse all network paths.<br>
> +     */<br>
> +    if (!loader->templt && loader->loader_src->type == VIR_STORAGE_TYPE_FILE) {<br>
>          size_t i;<br>
>          for (i = 0; i < cfg->nfirmwares; i++) {<br>
> -            if (STREQ(cfg->firmwares[i]-><wbr>name, loader->path)) {<br>
> +            if (STREQ(cfg->firmwares[i]-><wbr>name, loader->loader_src->path)) {<br>
>                  master_nvram_path = cfg->firmwares[i]->nvram;<br>
>                  break;<br>
>              }<br>
>          }<br>
>      }<br>
>  <br>
> -    if (!master_nvram_path) {<br>
> -        virReportError(VIR_ERR_<wbr>OPERATION_FAILED,<br>
> -                       _("unable to find any master var store for "<br>
> -                         "loader: %s"), loader->path);<br>
> -        goto cleanup;<br>
> +    if (!master_nvram_path && loader->nvram) {<br>
> +        /* There is no template description, but an NVRAM spec<br>
> +         * has already been provided.<br>
> +         * Trust the client to have generated the right spec here<br>
> +         */<br>
> +        return 0;<br>
>      }<br>
>  <br>
>      if ((srcFD = virFileOpenAs(master_nvram_<wbr>path, O_RDONLY,<br>
> @@ -4022,13 +4029,13 @@ qemuPrepareNVRAM(<wbr>virQEMUDriverConfigPtr cfg,<br>
>                               master_nvram_path);<br>
>          goto cleanup;<br>
>      }<br>
> -    if ((dstFD = virFileOpenAs(loader->nvram,<br>
> +    if ((dstFD = virFileOpenAs(loader->nvram-><wbr>path,<br>
>                                 O_WRONLY | O_CREAT | O_EXCL,<br>
>                                 S_IRUSR | S_IWUSR,<br>
>                                 cfg->user, cfg->group, 0)) < 0) {<br>
>          virReportSystemError(-dstFD,<br>
>                               _("Failed to create file '%s'"),<br>
> -                             loader->nvram);<br>
> +                             loader->nvram->path);<br>
>          goto cleanup;<br>
>      }<br>
>      created = true;<br>
> @@ -4046,7 +4053,7 @@ qemuPrepareNVRAM(<wbr>virQEMUDriverConfigPtr cfg,<br>
>          if (safewrite(dstFD, buf, r) < 0) {<br>
>              virReportSystemError(errno,<br>
>                                   _("Unable to write to file '%s'"),<br>
> -                                 loader->nvram);<br>
> +                                 loader->nvram->path);<br>
>              goto cleanup;<br>
>          }<br>
>      } while (r);<br>
> @@ -4060,7 +4067,7 @@ qemuPrepareNVRAM(<wbr>virQEMUDriverConfigPtr cfg,<br>
>      if (VIR_CLOSE(dstFD) < 0) {<br>
>          virReportSystemError(errno,<br>
>                               _("Unable to close file '%s'"),<br>
> -                             loader->nvram);<br>
> +                             loader->nvram->path);<br>
>          goto cleanup;<br>
>      }<br>
>  <br>
> @@ -4070,7 +4077,7 @@ qemuPrepareNVRAM(<wbr>virQEMUDriverConfigPtr cfg,<br>
>       * copy the file content. Roll back. */<br>
>      if (ret < 0) {<br>
>          if (created)<br>
> -            unlink(loader->nvram);<br>
> +            unlink(loader->nvram->path);<br>
>      }<br>
>  <br>
>      VIR_FORCE_CLOSE(srcFD);<br>
> diff --git a/src/security/security_dac.c b/src/security/security_dac.c<br>
> index 663c8c9..fce4204 100644<br>
> --- a/src/security/security_dac.c<br>
> +++ b/src/security/security_dac.c<br>
> @@ -1604,7 +1604,8 @@ virSecurityDACRestoreAllLabel(<wbr>virSecurityManagerPtr mgr,<br>
>      }<br>
>  <br>
>      if (def->os.loader && def->os.loader->nvram &&<br>
> -        virSecurityDACRestoreFileLabel<wbr>(priv, def->os.loader->nvram) < 0)<br>
> +        def->os.loader->nvram->type == VIR_STORAGE_TYPE_FILE &&<br>
> +        virSecurityDACRestoreFileLabel<wbr>(priv, def->os.loader->nvram->path) < 0)<br>
>          rc = -1;<br>
>  <br>
>      return rc;<br>
> @@ -1732,8 +1733,9 @@ virSecurityDACSetAllLabel(<wbr>virSecurityManagerPtr mgr,<br>
>          return -1;<br>
>  <br>
>      if (def->os.loader && def->os.loader->nvram &&<br>
> +        def->os.loader->nvram->type == VIR_STORAGE_TYPE_FILE &&<br>
>          virSecurityDACSetOwnership(<wbr>priv, NULL,<br>
> -                                   def->os.loader->nvram, user, group) < 0)<br>
> +                                   def->os.loader->nvram->path, user, group) < 0)<br>
>          return -1;<br>
>  <br>
>      if (def->os.kernel &&<br>
> diff --git a/src/security/security_<wbr>selinux.c b/src/security/security_<wbr>selinux.c<br>
> index c26cdac..396e7fc 100644<br>
> --- a/src/security/security_<wbr>selinux.c<br>
> +++ b/src/security/security_<wbr>selinux.c<br>
> @@ -2459,7 +2459,8 @@ virSecuritySELinuxRestoreAllLa<wbr>bel(virSecurityManagerPtr mgr,<br>
>          rc = -1;<br>
>  <br>
>      if (def->os.loader && def->os.loader->nvram &&<br>
> -        virSecuritySELinuxRestoreFileL<wbr>abel(mgr, def->os.loader->nvram) < 0)<br>
> +        def->os.loader->nvram->type == VIR_STORAGE_TYPE_FILE &&<br>
> +        virSecuritySELinuxRestoreFileL<wbr>abel(mgr, def->os.loader->nvram->path) < 0)<br>
>          rc = -1;<br>
>  <br>
>      return rc;<br>
> @@ -2851,8 +2852,9 @@ virSecuritySELinuxSetAllLabel(<wbr>virSecurityManagerPtr mgr,<br>
>      /* This is different than kernel or initrd. The nvram store<br>
>       * is really a disk, qemu can read and write to it. */<br>
>      if (def->os.loader && def->os.loader->nvram &&<br>
> +        def->os.loader->nvram->type == VIR_STORAGE_TYPE_FILE &&<br>
>          secdef && secdef->imagelabel &&<br>
> -        virSecuritySELinuxSetFilecon(<wbr>mgr, def->os.loader->nvram,<br>
> +        virSecuritySELinuxSetFilecon(<wbr>mgr, def->os.loader->nvram->path,<br>
>                                       secdef->imagelabel) < 0)<br>
>          return -1;<br>
>  <br>
> <br>
<br>
</div></div>There's still far too much missing... even in the qemu side - there<br>
needs to be xml2argv test changes... *.args output...<br>
<br></blockquote><div><br></div><div>Yes, test and documentation fixes are missing as I'd mentioned.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Perhaps best to generate a v2 with things separated better and more<br>
complete changes and take it from there.<br></blockquote><div><br></div><div>Agree with that. If only you could pls clarify whether we should format-as-is-read or change-old-format-to-new.</div><div>Thanks once again for the review.</div><div><br></div><div>Regards,</div><div>Prerna</div><div><br></div></div></div></div>