[PATCH] Introduce network-backed NVRAM

Rohit Kumar rohit.kumar3 at nutanix.com
Mon Mar 28 08:38:08 UTC 2022


Ping.
Hi, please review this patch.
Thanks !

On 21/03/22 9:58 am, Rohit Kumar wrote:
> Libvirt domain XML allows only local filepaths to specify a NVRAM
> element. Since VMs can move across different hosts, it should be
> possibe to allocate NVRAM disks on network storage for uninturrupted
> access.
>
> This Patch extends the NVRAM disk elements to be described as
> virStorageSource* elements.
>
> Sample XML with new annotation:
>
> <nvram>
>    <source protocol='iscsi' name='iqn.2013-07.com.example:iscsi-nopool/0'>
>      <host name='example.com' port='6000'/>
>    </source>
> </nvram>
>
> or
>
> <nvram>
>    <source file='/var/lib/libvirt/nvram/guest_VARS.fd'/>
> </nvram>
>
> Signed-off-by: Prerna Saxena <prerna.saxena at nutanix.com>
> Signed-off-by: Florian Schmidt <flosch at nutanix.com>
> Signed-off-by: Rohit Kumar <rohit.kumar3 at nutanix.com>
> ---
>   docs/schemas/domaincommon.rng                 | 72 +++++++++------
>   src/conf/domain_conf.c                        | 90 +++++++++++++++----
>   src/conf/domain_conf.h                        |  2 +-
>   src/qemu/qemu_cgroup.c                        |  3 +-
>   src/qemu/qemu_command.c                       |  5 +-
>   src/qemu/qemu_domain.c                        | 23 +++--
>   src/qemu/qemu_driver.c                        |  5 +-
>   src/qemu/qemu_firmware.c                      | 17 ++--
>   src/qemu/qemu_namespace.c                     |  5 +-
>   src/qemu/qemu_process.c                       |  5 +-
>   src/security/security_dac.c                   |  6 +-
>   src/security/security_selinux.c               |  6 +-
>   src/security/virt-aa-helper.c                 |  5 +-
>   src/vbox/vbox_common.c                        |  8 +-
>   .../qemuxml2argvdata/bios-nvram-network.args  | 35 ++++++++
>   tests/qemuxml2argvdata/bios-nvram-network.xml | 40 +++++++++
>   tests/qemuxml2argvtest.c                      |  1 +
>   17 files changed, 256 insertions(+), 72 deletions(-)
>   create mode 100644 tests/qemuxml2argvdata/bios-nvram-network.args
>   create mode 100644 tests/qemuxml2argvdata/bios-nvram-network.xml
>
> diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
> index 9c1b64a644..a25c84a0b7 100644
> --- a/docs/schemas/domaincommon.rng
> +++ b/docs/schemas/domaincommon.rng
> @@ -330,7 +330,17 @@
>                 </attribute>
>               </optional>
>               <optional>
> -              <ref name="absFilePath"/>
> +              <choice>
> +                <group>
> +                  <ref name="absFilePath"/>
> +                </group>
> +                <group>
> +                  <ref name="diskSourceFileElement"/>
> +                </group>
> +                <group>
> +                  <ref name="diskSourceNetworkElement"/>
> +                </group>
> +              </choice>
>               </optional>
>             </element>
>           </optional>
> @@ -1714,6 +1724,31 @@
>       </choice>
>     </define>
>   
> +  <define name="diskSourceFileElement">
> +    <element name="source">
> +      <interleave>
> +        <optional>
> +          <attribute name="file">
> +            <choice>
> +                <ref name="absFilePath"/>
> +                <ref name="vmwarePath"/>
> +            </choice>
> +          </attribute>
> +        </optional>
> +        <ref name="diskSourceCommon"/>
> +        <optional>
> +          <ref name="storageStartupPolicy"/>
> +        </optional>
> +        <optional>
> +          <ref name="encryption"/>
> +        </optional>
> +        <zeroOrMore>
> +          <ref name="devSeclabel"/>
> +        </zeroOrMore>
> +      </interleave>
> +    </element>
> +  </define>
> +
>     <define name="diskSourceFile">
>       <optional>
>         <attribute name="type">
> @@ -1721,28 +1756,7 @@
>         </attribute>
>       </optional>
>       <optional>
> -      <element name="source">
> -        <interleave>
> -          <optional>
> -            <attribute name="file">
> -              <choice>
> -                <ref name="absFilePath"/>
> -                <ref name="vmwarePath"/>
> -              </choice>
> -            </attribute>
> -          </optional>
> -          <ref name="diskSourceCommon"/>
> -          <optional>
> -            <ref name="storageStartupPolicy"/>
> -          </optional>
> -          <optional>
> -            <ref name="encryption"/>
> -          </optional>
> -          <zeroOrMore>
> -            <ref name="devSeclabel"/>
> -          </zeroOrMore>
> -        </interleave>
> -      </element>
> +      <ref name="diskSourceFileElement"/>
>       </optional>
>     </define>
>   
> @@ -2137,10 +2151,7 @@
>       </element>
>     </define>
>   
> -  <define name="diskSourceNetwork">
> -    <attribute name="type">
> -      <value>network</value>
> -    </attribute>
> +  <define name="diskSourceNetworkElement">
>       <choice>
>         <ref name="diskSourceNetworkProtocolNBD"/>
>         <ref name="diskSourceNetworkProtocolGluster"/>
> @@ -2155,6 +2166,13 @@
>       </choice>
>     </define>
>   
> +  <define name="diskSourceNetwork">
> +    <attribute name="type">
> +      <value>network</value>
> +    </attribute>
> +    <ref name="diskSourceNetworkElement"/>
> +  </define>
> +
>     <define name="diskSourceVolume">
>       <attribute name="type">
>         <value>volume</value>
> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
> index e0dfc9e45f..5fcc09db05 100644
> --- a/src/conf/domain_conf.c
> +++ b/src/conf/domain_conf.c
> @@ -3535,7 +3535,7 @@ virDomainLoaderDefFree(virDomainLoaderDef *loader)
>           return;
>   
>       g_free(loader->path);
> -    g_free(loader->nvram);
> +    virObjectUnref(loader->nvram);
>       g_free(loader->nvramTemplate);
>       g_free(loader);
>   }
> @@ -17834,6 +17834,37 @@ virDomainLoaderDefParseXML(xmlNodePtr node,
>   }
>   
>   
> +static int
> +virDomainNvramDefParseXML(virStorageSource *nvram,
> +                          xmlXPathContextPtr ctxt,
> +                          virDomainXMLOption *opt,
> +                          unsigned int flags)
> +{
> +    g_autofree char *srcTypeFile = NULL;
> +    g_autofree char *srcTypeNetwork = NULL;
> +    xmlNodePtr source;
> +
> +    srcTypeFile =  virXPathString("string(./os/nvram/source/@file)", ctxt);
> +    srcTypeNetwork =  virXPathString("string(./os/nvram/source/@protocol)", ctxt);
> +
> +    if (!srcTypeFile && !srcTypeNetwork) {
> +        nvram->type = VIR_STORAGE_TYPE_FILE;
> +        nvram->path = virXPathString("string(./os/nvram[1])", ctxt);
> +        return 0;
> +    } else {
> +        if (srcTypeFile) {
> +            nvram->type = VIR_STORAGE_TYPE_FILE;
> +        } else {
> +            nvram->type = VIR_STORAGE_TYPE_NETWORK;
> +        }
> +        source = virXPathNode("./os/nvram/source[1]", ctxt);
> +        if (!source)
> +            return -1;
> +        return virDomainStorageSourceParse(source, ctxt, nvram, flags, opt);
> +    }
> +
> +}
> +
>   static int
>   virDomainSchedulerParseCommonAttrs(xmlNodePtr node,
>                                      virProcessSchedPolicy *policy,
> @@ -18219,7 +18250,9 @@ virDomainDefParseBootFirmwareOptions(virDomainDef *def,
>   
>   static int
>   virDomainDefParseBootLoaderOptions(virDomainDef *def,
> -                                   xmlXPathContextPtr ctxt)
> +                                   xmlXPathContextPtr ctxt,
> +                                   virDomainXMLOption *xmlopt,
> +                                   unsigned int flags)
>   {
>       xmlNodePtr loader_node = virXPathNode("./os/loader[1]", ctxt);
>       const bool fwAutoSelect = def->os.firmware != VIR_DOMAIN_OS_DEF_FIRMWARE_NONE;
> @@ -18234,7 +18267,14 @@ virDomainDefParseBootLoaderOptions(virDomainDef *def,
>                                      fwAutoSelect) < 0)
>           return -1;
>   
> -    def->os.loader->nvram = virXPathString("string(./os/nvram[1])", ctxt);
> +    if (virXPathNode("./os/nvram[1]", ctxt)) {
> +        def->os.loader->nvram = g_new0(virStorageSource, 1);
> +
> +        if (virDomainNvramDefParseXML(def->os.loader->nvram,
> +                                      ctxt, xmlopt, flags) < 0)
> +            return -1;
> +    }
> +
>       if (!fwAutoSelect)
>           def->os.loader->nvramTemplate = virXPathString("string(./os/nvram[1]/@template)", ctxt);
>   
> @@ -18288,7 +18328,9 @@ virDomainDefParseBootAcpiOptions(virDomainDef *def,
>   
>   static int
>   virDomainDefParseBootOptions(virDomainDef *def,
> -                             xmlXPathContextPtr ctxt)
> +                             xmlXPathContextPtr ctxt,
> +                             virDomainXMLOption *xmlopt,
> +                             unsigned int flags)
>   {
>       /*
>        * Booting options for different OS types....
> @@ -18306,7 +18348,7 @@ virDomainDefParseBootOptions(virDomainDef *def,
>           if (virDomainDefParseBootFirmwareOptions(def, ctxt) < 0)
>               return -1;
>   
> -        if (virDomainDefParseBootLoaderOptions(def, ctxt) < 0)
> +        if (virDomainDefParseBootLoaderOptions(def, ctxt, xmlopt, flags) < 0)
>               return -1;
>   
>           if (virDomainDefParseBootAcpiOptions(def, ctxt) < 0)
> @@ -18322,7 +18364,7 @@ virDomainDefParseBootOptions(virDomainDef *def,
>       case VIR_DOMAIN_OSTYPE_UML:
>           virDomainDefParseBootKernelOptions(def, ctxt);
>   
> -        if (virDomainDefParseBootLoaderOptions(def, ctxt) < 0)
> +        if (virDomainDefParseBootLoaderOptions(def, ctxt, xmlopt, flags) < 0)
>               return -1;
>   
>           break;
> @@ -19606,7 +19648,7 @@ virDomainDefParseXML(xmlXPathContextPtr ctxt,
>       if (virDomainDefClockParse(def, ctxt) < 0)
>           return NULL;
>   
> -    if (virDomainDefParseBootOptions(def, ctxt) < 0)
> +    if (virDomainDefParseBootOptions(def, ctxt, xmlopt, flags) < 0)
>           return NULL;
>   
>       /* analysis of the disk devices */
> @@ -26899,7 +26941,9 @@ virDomainHugepagesFormat(virBuffer *buf,
>   
>   static void
>   virDomainLoaderDefFormat(virBuffer *buf,
> -                         virDomainLoaderDef *loader)
> +                         virDomainLoaderDef *loader,
> +                         virDomainXMLOption *xmlopt,
> +                         unsigned int flags)
>   {
>       const char *readonly = virTristateBoolTypeToString(loader->readonly);
>       const char *secure = virTristateBoolTypeToString(loader->secure);
> @@ -26921,13 +26965,27 @@ virDomainLoaderDefFormat(virBuffer *buf,
>       else
>           virBufferAddLit(buf, "/>\n");
>   
> -    if (loader->nvram || loader->nvramTemplate) {
> -        virBufferAddLit(buf, "<nvram");
> -        virBufferEscapeString(buf, " template='%s'", loader->nvramTemplate);
> -        if (loader->nvram)
> -            virBufferEscapeString(buf, ">%s</nvram>\n", loader->nvram);
> -        else
> -            virBufferAddLit(buf, "/>\n");
> +    if (loader->nvram) {
> +        if (loader->nvram->type == VIR_STORAGE_TYPE_FILE) {
> +            virBufferAddLit(buf, "<nvram");
> +            virBufferEscapeString(buf, " template='%s'", loader->nvramTemplate);
> +            if (loader->nvram->path)
> +                virBufferEscapeString(buf, ">%s</nvram>\n", loader->nvram->path);
> +            else
> +                virBufferAddLit(buf, "/>\n");
> +        } else {
> +            virBufferAddLit(buf, "<nvram");
> +            virBufferEscapeString(buf, " template='%s'", loader->nvramTemplate);
> +            virBufferAdjustIndent(buf, 2);
> +            if (virDomainDiskSourceFormat(buf, loader->nvram, "source", 0,
> +                                          0, false, flags, true, xmlopt) < 0) {
> +                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> +                               _("Cannot format NVRAM source"));
> +                return;
> +            }
> +            virBufferAdjustIndent(buf, -2);
> +            virBufferAddLit(buf, "</nvram>\n");
> +        }
>       }
>   }
>   
> @@ -28122,7 +28180,7 @@ virDomainDefFormatInternalSetRootName(virDomainDef *def,
>           virBufferAsprintf(buf, "<initgroup>%s</initgroup>\n", def->os.initgroup);
>   
>       if (def->os.loader)
> -        virDomainLoaderDefFormat(buf, def->os.loader);
> +        virDomainLoaderDefFormat(buf, def->os.loader, xmlopt, flags);
>       virBufferEscapeString(buf, "<kernel>%s</kernel>\n",
>                             def->os.kernel);
>       virBufferEscapeString(buf, "<initrd>%s</initrd>\n",
> diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
> index a4de46773c..f65558e82d 100644
> --- a/src/conf/domain_conf.h
> +++ b/src/conf/domain_conf.h
> @@ -2231,7 +2231,7 @@ struct _virDomainLoaderDef {
>       virTristateBool readonly;
>       virDomainLoader type;
>       virTristateBool secure;
> -    char *nvram;    /* path to non-volatile RAM */
> +    virStorageSource *nvram;
>       char *nvramTemplate;   /* user override of path to master nvram */
>   };
>   
> diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c
> index aa0c927578..d46c9ff36a 100644
> --- a/src/qemu/qemu_cgroup.c
> +++ b/src/qemu/qemu_cgroup.c
> @@ -581,7 +581,8 @@ qemuSetupFirmwareCgroup(virDomainObj *vm)
>           return -1;
>   
>       if (vm->def->os.loader->nvram &&
> -        qemuSetupImagePathCgroup(vm, vm->def->os.loader->nvram, false) < 0)
> +        vm->def->os.loader->nvram->type == VIR_STORAGE_TYPE_FILE &&
> +        qemuSetupImagePathCgroup(vm, vm->def->os.loader->nvram->path, false) < 0)
>           return -1;
>   
>       return 0;
> diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
> index c836799888..649a6f5b55 100644
> --- a/src/qemu/qemu_command.c
> +++ b/src/qemu/qemu_command.c
> @@ -9583,6 +9583,7 @@ qemuBuildDomainLoaderPflashCommandLine(virCommand *cmd,
>                                         virQEMUCaps *qemuCaps)
>   {
>       g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER;
> +    g_autofree char *nvramPath = NULL;
>       int unit = 0;
>   
>       if (loader->secure == VIR_TRISTATE_BOOL_YES) {
> @@ -9610,8 +9611,10 @@ qemuBuildDomainLoaderPflashCommandLine(virCommand *cmd,
>       virCommandAddArgBuffer(cmd, &buf);
>   
>       if (loader->nvram) {
> +        if (qemuGetDriveSourceString(loader->nvram, NULL, &nvramPath) < 0)
> +            return;
>           virBufferAddLit(&buf, "file=");
> -        virQEMUBuildBufferEscapeComma(&buf, loader->nvram);
> +        virQEMUBuildBufferEscapeComma(&buf, nvramPath);
>           virBufferAsprintf(&buf, ",if=pflash,format=raw,unit=%d", unit);
>   
>           virCommandAddArg(cmd, "-drive");
> diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
> index 7180ae616b..303d9661a4 100644
> --- a/src/qemu/qemu_domain.c
> +++ b/src/qemu/qemu_domain.c
> @@ -4452,8 +4452,13 @@ qemuDomainDefPostParse(virDomainDef *def,
>       }
>   
>       if (virDomainDefHasOldStyleROUEFI(def) &&
> -        !def->os.loader->nvram)
> -        qemuDomainNVRAMPathFormat(cfg, def, &def->os.loader->nvram);
> +        (!def->os.loader->nvram || !def->os.loader->nvram->path)) {
> +
> +        if (!def->os.loader->nvram)
> +            def->os.loader->nvram = g_new0(virStorageSource, 1);
> +        def->os.loader->nvram->type = VIR_STORAGE_TYPE_FILE;
> +        qemuDomainNVRAMPathFormat(cfg, def, &def->os.loader->nvram->path);
> +    }
>   
>       if (qemuDomainDefAddDefaultDevices(driver, def, qemuCaps) < 0)
>           return -1;
> @@ -11133,15 +11138,23 @@ qemuDomainInitializePflashStorageSource(virDomainObj *vm)
>       pflash0->nodeformat = g_strdup("libvirt-pflash0-format");
>       pflash0->nodestorage = g_strdup("libvirt-pflash0-storage");
>   
> -
>       if (def->os.loader->nvram) {
>           pflash1 = virStorageSourceNew();
> -        pflash1->type = VIR_STORAGE_TYPE_FILE;
>           pflash1->format = VIR_STORAGE_FILE_RAW;
> -        pflash1->path = g_strdup(def->os.loader->nvram);
> +        pflash1->path = g_strdup(def->os.loader->nvram->path);
>           pflash1->readonly = false;
>           pflash1->nodeformat = g_strdup("libvirt-pflash1-format");
>           pflash1->nodestorage = g_strdup("libvirt-pflash1-storage");
> +
> +        if (def->os.loader->nvram->type == VIR_STORAGE_TYPE_FILE) {
> +             pflash1->type = VIR_STORAGE_TYPE_FILE;
> +        } else if (def->os.loader->nvram->type == VIR_STORAGE_TYPE_NETWORK) {
> +            pflash1->protocol = def->os.loader->nvram->protocol;
> +            pflash1->hosts =  g_new0(virStorageNetHostDef, 1);
> +            pflash1->nhosts = 1;
> +            pflash1->hosts[0].name = def->os.loader->nvram->hosts[0].name;
> +            pflash1->hosts[0].port = def->os.loader->nvram->hosts[0].port;
> +        }
>       }
>   
>       priv->pflash0 = g_steal_pointer(&pflash0);
> diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
> index b7e83c769a..4f4098975c 100644
> --- a/src/qemu/qemu_driver.c
> +++ b/src/qemu/qemu_driver.c
> @@ -6605,8 +6605,9 @@ qemuDomainUndefineFlags(virDomainPtr dom,
>           }
>       }
>   
> -    if (vm->def->os.loader && vm->def->os.loader->nvram) {
> -        nvram_path = g_strdup(vm->def->os.loader->nvram);
> +    if (vm->def->os.loader && vm->def->os.loader->nvram &&
> +        vm->def->os.loader->nvram->type == VIR_STORAGE_TYPE_FILE) {
> +        nvram_path = g_strdup(vm->def->os.loader->nvram->path);
>       } else if (vm->def->os.firmware == VIR_DOMAIN_OS_DEF_FIRMWARE_EFI) {
>           qemuDomainNVRAMPathFormat(cfg, vm->def, &nvram_path);
>       }
> diff --git a/src/qemu/qemu_firmware.c b/src/qemu/qemu_firmware.c
> index 51223faadf..fa99c7d217 100644
> --- a/src/qemu/qemu_firmware.c
> +++ b/src/qemu/qemu_firmware.c
> @@ -1192,13 +1192,16 @@ qemuFirmwareEnableFeatures(virQEMUDriver *driver,
>           VIR_FREE(def->os.loader->nvramTemplate);
>           def->os.loader->nvramTemplate = g_strdup(flash->nvram_template.filename);
>   
> -        if (!def->os.loader->nvram)
> -            qemuDomainNVRAMPathFormat(cfg, def, &def->os.loader->nvram);
> +        if (!def->os.loader->nvram) {
> +            def->os.loader->nvram = g_new0(virStorageSource, 1);
> +            def->os.loader->nvram->type = VIR_STORAGE_TYPE_FILE;
> +            qemuDomainNVRAMPathFormat(cfg, def, &def->os.loader->nvram->path);
> +        }
>   
>           VIR_DEBUG("decided on firmware '%s' template '%s' NVRAM '%s'",
>                     def->os.loader->path,
>                     def->os.loader->nvramTemplate,
> -                  def->os.loader->nvram);
> +                  def->os.loader->nvram->path);
>           break;
>   
>       case QEMU_FIRMWARE_DEVICE_KERNEL:
> @@ -1364,8 +1367,12 @@ qemuFirmwareFillDomain(virQEMUDriver *driver,
>            * its path in domain XML) but no template for NVRAM was
>            * specified and the varstore doesn't exist ... */
>           if (!virDomainDefHasOldStyleROUEFI(def) ||
> -            def->os.loader->nvramTemplate ||
> -            (!reset_nvram && virFileExists(def->os.loader->nvram)))
> +            def->os.loader->nvramTemplate  ||
> +            (def->os.loader->nvram &&
> +             !reset_nvram && ((def->os.loader->nvram->type == VIR_STORAGE_TYPE_FILE
> +             && virFileExists(def->os.loader->nvram->path)) ||
> +             (def->os.loader->nvram->type == VIR_STORAGE_TYPE_NETWORK &&
> +             def->os.loader->nvram->path))))
>               return 0;
>   
>           /* ... then we want to consult JSON FW descriptors first,
> diff --git a/src/qemu/qemu_namespace.c b/src/qemu/qemu_namespace.c
> index 23681b14a4..18a24635ad 100644
> --- a/src/qemu/qemu_namespace.c
> +++ b/src/qemu/qemu_namespace.c
> @@ -572,8 +572,9 @@ qemuDomainSetupLoader(virDomainObj *vm,
>           case VIR_DOMAIN_LOADER_TYPE_PFLASH:
>               *paths = g_slist_prepend(*paths, g_strdup(loader->path));
>   
> -            if (loader->nvram)
> -                *paths = g_slist_prepend(*paths, g_strdup(loader->nvram));
> +            if (loader->nvram &&
> +                loader->nvram->type == VIR_STORAGE_TYPE_FILE)
> +                *paths = g_slist_prepend(*paths, g_strdup(loader->nvram->path));
>               break;
>   
>           case VIR_DOMAIN_LOADER_TYPE_NONE:
> diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
> index 1ed60917ea..c8a25dbe91 100644
> --- a/src/qemu/qemu_process.c
> +++ b/src/qemu/qemu_process.c
> @@ -4475,7 +4475,8 @@ qemuPrepareNVRAM(virQEMUDriver *driver,
>       struct qemuPrepareNVRAMHelperData data;
>   
>       if (!loader || !loader->nvram ||
> -        (virFileExists(loader->nvram) && !reset_nvram))
> +        loader->nvram->type != VIR_STORAGE_TYPE_FILE ||
> +        (virFileExists(loader->nvram->path) && !reset_nvram))
>           return 0;
>   
>       master_nvram_path = loader->nvramTemplate;
> @@ -4507,7 +4508,7 @@ qemuPrepareNVRAM(virQEMUDriver *driver,
>       data.srcFD = srcFD;
>       data.srcPath = master_nvram_path;
>   
> -    if (virFileRewrite(loader->nvram,
> +    if (virFileRewrite(loader->nvram->path,
>                          S_IRUSR | S_IWUSR,
>                          cfg->user, cfg->group,
>                          qemuPrepareNVRAMHelper,
> diff --git a/src/security/security_dac.c b/src/security/security_dac.c
> index e9e316551e..66c36c57a3 100644
> --- a/src/security/security_dac.c
> +++ b/src/security/security_dac.c
> @@ -1971,7 +1971,8 @@ virSecurityDACRestoreAllLabel(virSecurityManager *mgr,
>       }
>   
>       if (def->os.loader && def->os.loader->nvram &&
> -        virSecurityDACRestoreFileLabel(mgr, def->os.loader->nvram) < 0)
> +        def->os.loader->nvram->type == VIR_STORAGE_TYPE_FILE &&
> +        virSecurityDACRestoreFileLabel(mgr, def->os.loader->nvram->path) < 0)
>           rc = -1;
>   
>       if (def->os.kernel &&
> @@ -2182,8 +2183,9 @@ virSecurityDACSetAllLabel(virSecurityManager *mgr,
>       }
>   
>       if (def->os.loader && def->os.loader->nvram &&
> +        def->os.loader->nvram->type == VIR_STORAGE_TYPE_FILE &&
>           virSecurityDACSetOwnership(mgr, NULL,
> -                                   def->os.loader->nvram,
> +                                   def->os.loader->nvram->path,
>                                      user, group, true) < 0)
>           return -1;
>   
> diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c
> index 6f02baf2ce..1b6b67e8c7 100644
> --- a/src/security/security_selinux.c
> +++ b/src/security/security_selinux.c
> @@ -2806,7 +2806,8 @@ virSecuritySELinuxRestoreAllLabel(virSecurityManager *mgr,
>       }
>   
>       if (def->os.loader && def->os.loader->nvram &&
> -        virSecuritySELinuxRestoreFileLabel(mgr, def->os.loader->nvram, true) < 0)
> +        def->os.loader->nvram->type == VIR_STORAGE_TYPE_FILE &&
> +        virSecuritySELinuxRestoreFileLabel(mgr, def->os.loader->nvram->path, true) < 0)
>           rc = -1;
>   
>       if (def->os.kernel &&
> @@ -3212,8 +3213,9 @@ virSecuritySELinuxSetAllLabel(virSecurityManager *mgr,
>       /* This is different than kernel or initrd. The nvram store
>        * is really a disk, qemu can read and write to it. */
>       if (def->os.loader && def->os.loader->nvram &&
> +        def->os.loader->nvram->type == VIR_STORAGE_TYPE_FILE &&
>           secdef && secdef->imagelabel &&
> -        virSecuritySELinuxSetFilecon(mgr, def->os.loader->nvram,
> +        virSecuritySELinuxSetFilecon(mgr, def->os.loader->nvram->path,
>                                        secdef->imagelabel, true) < 0)
>           return -1;
>   
> diff --git a/src/security/virt-aa-helper.c b/src/security/virt-aa-helper.c
> index 1f1cce8b3d..5803f9ff8d 100644
> --- a/src/security/virt-aa-helper.c
> +++ b/src/security/virt-aa-helper.c
> @@ -1006,8 +1006,9 @@ get_files(vahControl * ctl)
>           if (vah_add_file(&buf, ctl->def->os.loader->path, "rk") != 0)
>               goto cleanup;
>   
> -    if (ctl->def->os.loader && ctl->def->os.loader->nvram)
> -        if (vah_add_file(&buf, ctl->def->os.loader->nvram, "rwk") != 0)
> +    if (ctl->def->os.loader && ctl->def->os.loader->nvram &&
> +        ctl->def->os.loader->nvram->type == VIR_STORAGE_TYPE_FILE)
> +        if (vah_add_file(&buf, ctl->def->os.loader->nvram->path, "rwk") != 0)
>               goto cleanup;
>   
>       for (i = 0; i < ctl->def->ngraphics; i++) {
> diff --git a/src/vbox/vbox_common.c b/src/vbox/vbox_common.c
> index acd18494d3..d6a482d28b 100644
> --- a/src/vbox/vbox_common.c
> +++ b/src/vbox/vbox_common.c
> @@ -994,10 +994,10 @@ vboxSetBootDeviceOrder(virDomainDef *def, struct _vboxDriver *data,
>       VIR_DEBUG("def->os.cmdline          %s", def->os.cmdline);
>       VIR_DEBUG("def->os.root             %s", def->os.root);
>       if (def->os.loader) {
> -        VIR_DEBUG("def->os.loader->path     %s", def->os.loader->path);
> -        VIR_DEBUG("def->os.loader->readonly %d", def->os.loader->readonly);
> -        VIR_DEBUG("def->os.loader->type     %d", def->os.loader->type);
> -        VIR_DEBUG("def->os.loader->nvram    %s", def->os.loader->nvram);
> +        VIR_DEBUG("def->os.loader->path         %s", def->os.loader->path);
> +        VIR_DEBUG("def->os.loader->readonly     %d", def->os.loader->readonly);
> +        VIR_DEBUG("def->os.loader->type         %d", def->os.loader->type);
> +        VIR_DEBUG("def->os.loader->nvram->path  %s", def->os.loader->nvram->path);
>       }
>       VIR_DEBUG("def->os.bootloader       %s", def->os.bootloader);
>       VIR_DEBUG("def->os.bootloaderArgs   %s", def->os.bootloaderArgs);
> diff --git a/tests/qemuxml2argvdata/bios-nvram-network.args b/tests/qemuxml2argvdata/bios-nvram-network.args
> new file mode 100644
> index 0000000000..05075b45de
> --- /dev/null
> +++ b/tests/qemuxml2argvdata/bios-nvram-network.args
> @@ -0,0 +1,35 @@
> +LC_ALL=C \
> +PATH=/bin \
> +HOME=/tmp/lib/domain--1-test-bios \
> +USER=test \
> +LOGNAME=test \
> +XDG_DATA_HOME=/tmp/lib/domain--1-test-bios/.local/share \
> +XDG_CACHE_HOME=/tmp/lib/domain--1-test-bios/.cache \
> +XDG_CONFIG_HOME=/tmp/lib/domain--1-test-bios/.config \
> +QEMU_AUDIO_DRV=none \
> +/usr/bin/qemu-system-x86_64 \
> +-name guest=test-bios,debug-threads=on \
> +-S \
> +-object secret,id=masterKey0,format=raw,file=/tmp/lib/domain--1-test-bios/master-key.aes \
> +-machine pc,usb=off,dump-guest-core=off \
> +-accel tcg \
> +-drive file=/usr/share/OVMF/OVMF_CODE.fd,if=pflash,format=raw,unit=0,readonly=on \
> +-drive file=iscsi://example.org:6000/iqn.1992-01.com.example,if=pflash,format=raw,unit=1 \
> +-m 1024 \
> +-realtime mlock=off \
> +-smp 1,sockets=1,cores=1,threads=1 \
> +-uuid 362d1fc1-df7d-193e-5c18-49a71bd1da66 \
> +-display none \
> +-no-user-config \
> +-nodefaults \
> +-chardev socket,id=charmonitor,path=/tmp/lib/domain--1-test-bios/monitor.sock,server=on,wait=off \
> +-mon chardev=charmonitor,id=monitor,mode=control \
> +-rtc base=utc \
> +-no-shutdown \
> +-boot menu=on,strict=on \
> +-usb \
> +-drive file=/dev/HostVG/QEMUGuest1,format=raw,if=none,id=drive-ide0-0-0 \
> +-device ide-hd,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0,bootindex=1 \
> +-device usb-tablet,id=input0,bus=usb.0,port=1 \
> +-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x2 \
> +-msg timestamp=on
> diff --git a/tests/qemuxml2argvdata/bios-nvram-network.xml b/tests/qemuxml2argvdata/bios-nvram-network.xml
> new file mode 100644
> index 0000000000..0e1e23fd31
> --- /dev/null
> +++ b/tests/qemuxml2argvdata/bios-nvram-network.xml
> @@ -0,0 +1,40 @@
> +<domain type='qemu'>
> +  <name>test-bios</name>
> +  <uuid>362d1fc1-df7d-193e-5c18-49a71bd1da66</uuid>
> +  <memory unit='KiB'>1048576</memory>
> +  <currentMemory unit='KiB'>1048576</currentMemory>
> +  <vcpu placement='static'>1</vcpu>
> +  <os>
> +    <type arch='x86_64' machine='pc'>hvm</type>
> +    <loader readonly='yes' type='pflash'>/usr/share/OVMF/OVMF_CODE.fd</loader>
> +    <nvram>
> +      <source protocol='iscsi' name='iqn.1992-01.com.example'>
> +        <host name='example.org' port='6000'/>
> +      </source>
> +    </nvram>
> +    <boot dev='hd'/>
> +    <bootmenu enable='yes'/>
> +  </os>
> +  <features>
> +    <acpi/>
> +  </features>
> +  <clock offset='utc'/>
> +  <on_poweroff>destroy</on_poweroff>
> +  <on_reboot>restart</on_reboot>
> +  <on_crash>restart</on_crash>
> +  <devices>
> +    <emulator>/usr/bin/qemu-system-x86_64</emulator>
> +    <disk type='block' device='disk'>
> +      <source dev='/dev/HostVG/QEMUGuest1'/>
> +      <target dev='hda' bus='ide'/>
> +      <address type='drive' controller='0' bus='0' target='0' unit='0'/>
> +    </disk>
> +    <controller type='usb' index='0'/>
> +    <controller type='ide' index='0'/>
> +    <controller type='pci' index='0' model='pci-root'/>
> +    <input type='tablet' bus='usb'/>
> +    <input type='mouse' bus='ps2'/>
> +    <input type='keyboard' bus='ps2'/>
> +    <memballoon model='virtio'/>
> +  </devices>
> +</domain>
> diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
> index e7fecb24d3..7ec45ec74b 100644
> --- a/tests/qemuxml2argvtest.c
> +++ b/tests/qemuxml2argvtest.c
> @@ -1189,6 +1189,7 @@ mymain(void)
>               QEMU_CAPS_DEVICE_ISA_SERIAL);
>       DO_TEST_NOCAPS("bios-nvram");
>       DO_TEST_PARSE_ERROR_NOCAPS("bios-nvram-no-path");
> +    DO_TEST_NOCAPS("bios-nvram-network");
>       DO_TEST_CAPS_LATEST("bios-nvram-rw");
>       DO_TEST_CAPS_LATEST("bios-nvram-rw-implicit");
>       DO_TEST("bios-nvram-secure",



More information about the libvir-list mailing list