From nobody Fri May 3 14:34:30 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=fail(p=none dis=none) header.from=gmail.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1524214988801611.5561389845446; Fri, 20 Apr 2018 02:03:08 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 3F3A93002A87; Fri, 20 Apr 2018 09:03:07 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id EAD125D6A8; Fri, 20 Apr 2018 09:03:06 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 934F665D32; Fri, 20 Apr 2018 09:03:06 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id w3K8xTMS003393 for ; Fri, 20 Apr 2018 04:59:29 -0400 Received: by smtp.corp.redhat.com (Postfix) id 110B85D72A; Fri, 20 Apr 2018 08:59:29 +0000 (UTC) Received: from mx1.redhat.com (ext-mx17.extmail.prod.ext.phx2.redhat.com [10.5.110.46]) by smtp.corp.redhat.com (Postfix) with ESMTPS id E38C55D726; Fri, 20 Apr 2018 08:59:26 +0000 (UTC) Received: from mail-pf0-f180.google.com (mail-pf0-f180.google.com [209.85.192.180]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 2D49C3133E83; Fri, 20 Apr 2018 08:59:15 +0000 (UTC) Received: by mail-pf0-f180.google.com with SMTP id l27so3979986pfk.12; Fri, 20 Apr 2018 01:59:15 -0700 (PDT) Received: from ps-f25-dev.eng.nutanix.com ([205.209.132.2]) by smtp.gmail.com with ESMTPSA id b3sm9832303pfi.54.2018.04.20.01.59.13 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 20 Apr 2018 01:59:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=qZCVaaOS+F+P/p4FqNZitAWMz9Ge0jGloDU8lLEpz00=; b=Hn5a9T2c4yhD9qCP9Fdli8Mv4q8WxSS+i70s3E8jZ+fxrVxqYpKVL4INnIi2VoSVYU Y5XTbGg3josai9pr7Dv3czagEFp2B0OgUinVNH+MJlZozuFK3Kh/6n7d9sZWimHwAv61 G/RwH4LO32SabnmDkR+ck1cSwuMf+cf0763j5BB5qoJxefpBvKDjlXP4SPqn2zK1Nc6D l3xqY2uD7g8DhIkRUlsKoHfNFZiOtdOv+aB/niaeDjQRbR+XlEeCIHz/qa8rqALkJtDz AYK395Ys8xSSUEYkzOAbZedF6+2kzgrDSnG/k+O80s9T2a1eZPzHlBUat0h4PK0xjm9a Og4A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=qZCVaaOS+F+P/p4FqNZitAWMz9Ge0jGloDU8lLEpz00=; b=UhlXxjePhgnCyl6WBD9g3c4suTeyAoGWKqvrmkgkslTxuzvXOeGn8sZlL/2vKXWhSc K/+s3/r+PwwaxMfi1Q2k352liLxPkA6I7WsZO7o9HKsOuC0IaoMMPYnTH/WbQcGJDYOb Q2xpW/rQsuXcvh4RIrWy1XZIxPP9SOjHkrXOjX+O43rxJHcpej4BfLXjiAw212X23Kbt 7wXAkbZjoPiFqsCJV2GsG2208QLiTbwRK6EnChngw2/HGXUqC8uyIERqP6app1vOr5Xr CTyQ74vlvAU5KqD6ujy3IAwAbXs2xgrFYlwMOv0qBRKQMwFL0R87KBtikimIJp1+ozFd lgtg== X-Gm-Message-State: ALQs6tB/y2mKFjdC0qxUINnASsUOU1cH0dRVuI4Yohrsb4xuT3O7zePA DRivtlWWFDZ/BYlqMo9cAa2nvA== X-Google-Smtp-Source: AIpwx48u/NTk2OTQDfyYGmLtMajHxw5tTELhKYvRTSJJsAYQVsHJiJ1aRKNRsv543nOKPPj6Osel9w== X-Received: by 10.99.62.201 with SMTP id l192mr7809165pga.318.1524214754030; Fri, 20 Apr 2018 01:59:14 -0700 (PDT) From: Prerna Saxena To: libvir-list@redhat.com Date: Fri, 20 Apr 2018 01:59:02 -0700 Message-Id: <20180420085902.17661-2-saxenap.ltc@gmail.com> In-Reply-To: <20180420085902.17661-1-saxenap.ltc@gmail.com> References: <20180420085902.17661-1-saxenap.ltc@gmail.com> X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.46]); Fri, 20 Apr 2018 08:59:15 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.46]); Fri, 20 Apr 2018 08:59:15 +0000 (UTC) for IP:'209.85.192.180' DOMAIN:'mail-pf0-f180.google.com' HELO:'mail-pf0-f180.google.com' FROM:'saxenap.ltc@gmail.com' RCPT:'' X-RedHat-Spam-Score: 1.301 * (DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, NML_ADSP_CUSTOM_MED, RCVD_IN_DNSWL_NONE, SPF_PASS, T_DKIM_INVALID) 209.85.192.180 mail-pf0-f180.google.com 209.85.192.180 mail-pf0-f180.google.com X-Scanned-By: MIMEDefang 2.84 on 10.5.110.46 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-loop: libvir-list@redhat.com Cc: mprivozn@redhat.com, pkrempa@redhat.com Subject: [libvirt] [PATCH] Qemu driver: Support network-backed pflash disks. X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.47]); Fri, 20 Apr 2018 09:03:07 +0000 (UTC) X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" So far libvirt domain XML only allows local filepaths that can be used to specify a loader element or its matching NVRAM disk. Given that Vms may themselves move across hypervisor hosts, it should be possible to allocate loaders/NVRAM disks on network storage for uninterrupted access. Signed-off-by: Prerna Saxena --- docs/schemas/domaincommon.rng | 108 +++++++++++++++++++---- src/conf/domain_conf.c | 188 ++++++++++++++++++++++++++++++++++++= ---- src/conf/domain_conf.h | 7 +- src/qemu/qemu_cgroup.c | 13 ++- src/qemu/qemu_command.c | 21 +++-- src/qemu/qemu_domain.c | 16 ++-- src/qemu/qemu_driver.c | 7 +- src/qemu/qemu_parse_command.c | 30 ++++++- src/qemu/qemu_process.c | 33 ++++--- src/security/security_dac.c | 6 +- src/security/security_selinux.c | 6 +- 11 files changed, 361 insertions(+), 74 deletions(-) diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 4cab55f..32db395 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -276,7 +276,42 @@ - + + + + file + network + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -287,7 +322,40 @@ - + + + file + network + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1494,25 +1562,29 @@ - - - - - - - - - - - - - - - - + =20 + + + + + + + + + + + + + + + + + + + block diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 35666c1..c80f9d9 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -2883,8 +2883,8 @@ virDomainLoaderDefFree(virDomainLoaderDefPtr loader) if (!loader) return; =20 - VIR_FREE(loader->path); - VIR_FREE(loader->nvram); + virStorageSourceFree(loader->loader_src); + virStorageSourceFree(loader->nvram); VIR_FREE(loader->templt); VIR_FREE(loader); } @@ -17961,17 +17961,59 @@ virDomainDefMaybeAddHostdevSCSIcontroller(virDoma= inDefPtr def) =20 static int virDomainLoaderDefParseXML(xmlNodePtr node, + xmlXPathContextPtr ctxt, virDomainLoaderDefPtr loader) { int ret =3D -1; char *readonly_str =3D NULL; char *secure_str =3D NULL; char *type_str =3D NULL; + char *tmp =3D NULL; + xmlNodePtr cur; + xmlXPathContextPtr cur_ctxt =3D ctxt; + + if (VIR_ALLOC(loader->loader_src)) { + goto cleanup; + } + loader->loader_src->type =3D VIR_STORAGE_TYPE_LAST; =20 readonly_str =3D virXMLPropString(node, "readonly"); secure_str =3D virXMLPropString(node, "secure"); type_str =3D virXMLPropString(node, "type"); - loader->path =3D (char *) xmlNodeGetContent(node); + + if ((tmp =3D virXMLPropString(node, "backing")) && + (loader->loader_src->type =3D virStorageTypeFromString(tmp)) <=3D = 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("unknown loader type '%s'"), tmp); + goto cleanup; + } + VIR_FREE(tmp); + + for (cur =3D node->children; cur !=3D NULL; cur =3D cur->next) { + if (cur->type !=3D XML_ELEMENT_NODE) { + continue; + } + + if (virXMLNodeNameEqual(cur, "source")) { + if (virDomainStorageSourceParse(cur, cur_ctxt, loader->loader_= src, 0) < 0) { + virReportError(VIR_ERR_XML_DETAIL, + _("Error parsing Loader source element")); + goto cleanup; + } + break; + } + } + + /* Old-style absolute path found ? */ + if (loader->loader_src->type =3D=3D VIR_STORAGE_TYPE_LAST) { + if (!(loader->loader_src->path =3D (char *) xmlNodeGetContent(node= ))) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("missing loader source")); + goto cleanup; + } else { + loader->loader_src->type =3D VIR_STORAGE_TYPE_FILE; + } + } =20 if (readonly_str && (loader->readonly =3D virTristateBoolTypeFromString(readonly_str))= <=3D 0) { @@ -17998,13 +18040,78 @@ virDomainLoaderDefParseXML(xmlNodePtr node, } =20 ret =3D 0; - cleanup: + goto exit; +cleanup: + if (loader->loader_src) + VIR_FREE(loader->loader_src); +exit: VIR_FREE(readonly_str); VIR_FREE(secure_str); VIR_FREE(type_str); + return ret; } =20 +static int +virDomainLoaderNvramDefParseXML(xmlNodePtr node, + xmlXPathContextPtr ctxt, + virDomainLoaderDefPtr loader) +{ + int ret =3D -1; + char *tmp =3D NULL; + xmlNodePtr cur; + + if (VIR_ALLOC(loader->nvram)) { + goto cleanup; + } + + loader->nvram->type =3D VIR_STORAGE_TYPE_LAST; + + if ((tmp =3D virXMLPropString(node, "backing")) && + (loader->nvram->type =3D virStorageTypeFromString(tmp)) <=3D 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("unknown nvram type '%s'"), tmp); + goto cleanup; + } + VIR_FREE(tmp); + + for (cur =3D node->children; cur !=3D NULL; cur =3D cur->next) { + if (cur->type !=3D XML_ELEMENT_NODE) { + continue; + } + + if (virXMLNodeNameEqual(cur, "template")) { + loader->templt =3D virXPathString("string(./os/nvram[1]/@templ= ate)", ctxt); + continue; + } + + if (virXMLNodeNameEqual(cur, "source")) { + if (virDomainStorageSourceParse(cur, ctxt, loader->nvram, 0) <= 0) { + virReportError(VIR_ERR_XML_DETAIL, + _("Error parsing nvram source element")); + goto cleanup; + } + ret =3D 0; + } + } + + if (loader->nvram->type =3D=3D VIR_STORAGE_TYPE_LAST) { + if (!(loader->nvram->path =3D (char *) xmlNodeGetContent(node))) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("missing nvram source")); + goto cleanup; + } else { + loader->nvram->type =3D VIR_STORAGE_TYPE_FILE; + ret =3D 0; + } + } + return ret; + +cleanup: + if (loader->nvram) + VIR_FREE(loader->nvram); + return ret; +} =20 static virBitmapPtr virDomainSchedulerParse(xmlNodePtr node, @@ -18397,11 +18504,15 @@ virDomainDefParseBootOptions(virDomainDefPtr def, if (VIR_ALLOC(def->os.loader) < 0) goto error; =20 - if (virDomainLoaderDefParseXML(loader_node, def->os.loader) < = 0) + def->os.loader->loader_src =3D NULL; + def->os.loader->nvram =3D NULL; + if (virDomainLoaderDefParseXML(loader_node, ctxt, def->os.load= er) < 0) goto error; =20 - def->os.loader->nvram =3D virXPathString("string(./os/nvram[1]= )", ctxt); - def->os.loader->templt =3D virXPathString("string(./os/nvram[1= ]/@template)", ctxt); + if ((loader_node =3D virXPathNode("./os/nvram[1]", ctxt)) && + (virDomainLoaderNvramDefParseXML(loader_node, ctxt, + def->os.loader) < 0)) + goto error; } } =20 @@ -26070,11 +26181,19 @@ virDomainHugepagesFormat(virBufferPtr buf, =20 static void virDomainLoaderDefFormat(virBufferPtr buf, - virDomainLoaderDefPtr loader) + virDomainLoaderDefPtr loader, + unsigned int flags) { const char *readonly =3D virTristateBoolTypeToString(loader->readonly); const char *secure =3D virTristateBoolTypeToString(loader->secure); const char *type =3D virDomainLoaderTypeToString(loader->type); + const char *backing =3D NULL; + + virBuffer attrBuf =3D VIR_BUFFER_INITIALIZER; + virBuffer childBuf =3D VIR_BUFFER_INITIALIZER; + + virBufferSetChildIndent(&childBuf, buf); + =20 virBufferAddLit(buf, "secure) virBufferAsprintf(buf, " secure=3D'%s'", secure); =20 - virBufferAsprintf(buf, " type=3D'%s'>", type); + virBufferAsprintf(buf, " type=3D'%s'", type); + if (loader->loader_src && + loader->loader_src->type !=3D VIR_STORAGE_TYPE_LAST) { + if (virDomainStorageSourceFormat(&attrBuf, &childBuf, loader->load= er_src, + flags, 0) < 0) + goto cleanup; + + backing =3D virStorageTypeToString(loader->loader_src->type); + virBufferAsprintf(buf, " backing=3D'%s'>", backing); + + if (virXMLFormatElement(buf, "source", &attrBuf, &childBuf) < 0) + goto cleanup; + } else { + virBufferAddLit(buf, ">\n"); + } + + virBufferAddLit(buf, "\n"); =20 - virBufferEscapeString(buf, "%s\n", loader->path); if (loader->nvram || loader->templt) { - virBufferAddLit(buf, "templt); + ignore_value(virBufferContentAndReset(&attrBuf)); + ignore_value(virBufferContentAndReset(&childBuf)); + virBufferSetChildIndent(&childBuf, buf); + if (loader->nvram) - virBufferEscapeString(buf, ">%s\n", loader->nvram); - else - virBufferAddLit(buf, "/>\n"); + backing =3D virStorageTypeToString(loader->nvram->type); + + virBufferAddLit(buf, "templt) { + virBufferEscapeString(buf, " template=3D'%s'", loader->templt); + } + if (loader->nvram && + (virDomainStorageSourceFormat(&attrBuf, &childBuf, + loader->nvram, flags, 0) < 0)) { + virBufferAddLit(buf, ">\n\n"); + goto cleanup; + } + + virBufferEscapeString(buf, " backing=3D'%s'>", backing); + if (virXMLFormatElement(buf, "source", &attrBuf, &childBuf) < 0) { + virBufferAddLit(buf, "\n"); + goto cleanup; + } + virBufferAddLit(buf, "\n"); } +cleanup: + virBufferFreeAndReset(&attrBuf); + virBufferFreeAndReset(&childBuf); + return; } =20 static void @@ -26757,7 +26913,7 @@ virDomainDefFormatInternal(virDomainDefPtr def, virBufferAsprintf(buf, "%s\n", def->os.init= group); =20 if (def->os.loader) - virDomainLoaderDefFormat(buf, def->os.loader); + virDomainLoaderDefFormat(buf, def->os.loader, flags); virBufferEscapeString(buf, "%s\n", def->os.kernel); virBufferEscapeString(buf, "%s\n", diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 3c7eccb..50d5ac3 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -1857,14 +1857,17 @@ typedef enum { =20 VIR_ENUM_DECL(virDomainLoader) =20 +struct _virStorageSource; +typedef struct _virStorageSource* virStorageSourcePtr; + typedef struct _virDomainLoaderDef virDomainLoaderDef; typedef virDomainLoaderDef *virDomainLoaderDefPtr; struct _virDomainLoaderDef { - char *path; + virStorageSourcePtr loader_src; int readonly; /* enum virTristateBool */ virDomainLoader type; int secure; /* enum virTristateBool */ - char *nvram; /* path to non-volatile RAM */ + virStorageSourcePtr nvram; /* path to non-voliatile RAM */ char *templt; /* user override of path to master nvram */ }; =20 diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c index d88eb78..aa5d071 100644 --- a/src/qemu/qemu_cgroup.c +++ b/src/qemu/qemu_cgroup.c @@ -580,16 +580,21 @@ qemuSetupMemoryCgroup(virDomainObjPtr vm) static int qemuSetupFirmwareCgroup(virDomainObjPtr vm) { + virStorageSourcePtr src =3D NULL; + if (!vm->def->os.loader) return 0; =20 - if (vm->def->os.loader->path && - qemuSetupImagePathCgroup(vm, vm->def->os.loader->path, - vm->def->os.loader->readonly =3D=3D VIR_T= RISTATE_BOOL_YES) < 0) + src =3D vm->def->os.loader->loader_src; + if (src->path && + src->type =3D=3D VIR_STORAGE_TYPE_FILE && + qemuSetupImagePathCgroup(vm, src->path, + src->readonly =3D=3D VIR_TRISTATE_BOOL_YE= S) < 0) return -1; =20 if (vm->def->os.loader->nvram && - qemuSetupImagePathCgroup(vm, vm->def->os.loader->nvram, false) < 0) + vm->def->os.loader->nvram->type =3D=3D VIR_STORAGE_TYPE_FILE && + qemuSetupImagePathCgroup(vm, vm->def->os.loader->nvram->path, fals= e) < 0) return -1; =20 return 0; diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 238c6ed..279a06c 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -9293,6 +9293,7 @@ qemuBuildDomainLoaderCommandLine(virCommandPtr cmd, virDomainLoaderDefPtr loader =3D def->os.loader; virBuffer buf =3D VIR_BUFFER_INITIALIZER; int unit =3D 0; + char *source =3D NULL; =20 if (!loader) return; @@ -9300,7 +9301,7 @@ qemuBuildDomainLoaderCommandLine(virCommandPtr cmd, switch ((virDomainLoader) loader->type) { case VIR_DOMAIN_LOADER_TYPE_ROM: virCommandAddArg(cmd, "-bios"); - virCommandAddArg(cmd, loader->path); + virCommandAddArg(cmd, loader->loader_src->path); break; =20 case VIR_DOMAIN_LOADER_TYPE_PFLASH: @@ -9312,9 +9313,14 @@ qemuBuildDomainLoaderCommandLine(virCommandPtr cmd, NULL); } =20 + if (qemuGetDriveSourceString(loader->loader_src, NULL, &source) < = 0) + break; + virBufferAddLit(&buf, "file=3D"); - virQEMUBuildBufferEscapeComma(&buf, loader->path); - virBufferAsprintf(&buf, ",if=3Dpflash,format=3Draw,unit=3D%d", uni= t); + virQEMUBuildBufferEscapeComma(&buf, source); + free(source); + virBufferAsprintf(&buf, ",if=3Dpflash,format=3Draw,unit=3D%d", + unit); unit++; =20 if (loader->readonly) { @@ -9327,9 +9333,14 @@ qemuBuildDomainLoaderCommandLine(virCommandPtr cmd, =20 if (loader->nvram) { virBufferFreeAndReset(&buf); + if (qemuGetDriveSourceString(loader->nvram, NULL, &source) < 0) + break; + virBufferAddLit(&buf, "file=3D"); - virQEMUBuildBufferEscapeComma(&buf, loader->nvram); - virBufferAsprintf(&buf, ",if=3Dpflash,format=3Draw,unit=3D%d",= unit); + virQEMUBuildBufferEscapeComma(&buf, source); + virBufferAsprintf(&buf, ",if=3Dpflash,format=3Draw,unit=3D%d", + unit); + unit++; =20 virCommandAddArg(cmd, "-drive"); virCommandAddArgBuffer(cmd, &buf); diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 21897cb..c1cb751 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -3312,8 +3312,10 @@ qemuDomainDefPostParse(virDomainDefPtr def, if (def->os.loader && def->os.loader->type =3D=3D VIR_DOMAIN_LOADER_TYPE_PFLASH && def->os.loader->readonly =3D=3D VIR_TRISTATE_SWITCH_ON && - !def->os.loader->nvram) { - if (virAsprintf(&def->os.loader->nvram, "%s/%s_VARS.fd", + def->os.loader->nvram && + def->os.loader->nvram->type =3D=3D VIR_STORAGE_TYPE_FILE && + !def->os.loader->nvram->path) { + if (virAsprintf(&def->os.loader->nvram->path, "%s/%s_VARS.fd", cfg->nvramDir, def->name) < 0) goto cleanup; } @@ -10477,19 +10479,21 @@ qemuDomainSetupLoader(virQEMUDriverConfigPtr cfg = ATTRIBUTE_UNUSED, =20 VIR_DEBUG("Setting up loader"); =20 - if (loader) { + if (loader && loader->loader_src && + loader->loader_src->type =3D=3D VIR_STORAGE_TYPE_FILE) { switch ((virDomainLoader) loader->type) { case VIR_DOMAIN_LOADER_TYPE_ROM: - if (qemuDomainCreateDevice(loader->path, data, false) < 0) + if (qemuDomainCreateDevice(loader->loader_src->path, data, fal= se) < 0) goto cleanup; break; =20 case VIR_DOMAIN_LOADER_TYPE_PFLASH: - if (qemuDomainCreateDevice(loader->path, data, false) < 0) + if (qemuDomainCreateDevice(loader->loader_src->path, data, fal= se) < 0) goto cleanup; =20 if (loader->nvram && - qemuDomainCreateDevice(loader->nvram, data, false) < 0) + loader->nvram->type =3D=3D VIR_STORAGE_TYPE_FILE && + qemuDomainCreateDevice(loader->nvram->path, data, false) <= 0) goto cleanup; break; =20 diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 5673d9f..ce6339d 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -7542,12 +7542,13 @@ qemuDomainUndefineFlags(virDomainPtr dom, =20 if (vm->def->os.loader && vm->def->os.loader->nvram && - virFileExists(vm->def->os.loader->nvram)) { + vm->def->os.loader->nvram->type =3D=3D VIR_STORAGE_TYPE_FILE && + virFileExists(vm->def->os.loader->nvram->path)) { if ((flags & VIR_DOMAIN_UNDEFINE_NVRAM)) { - if (unlink(vm->def->os.loader->nvram) < 0) { + if (unlink(vm->def->os.loader->nvram->path) < 0) { virReportSystemError(errno, _("failed to remove nvram: %s"), - vm->def->os.loader->nvram); + vm->def->os.loader->nvram->path); goto endjob; } } else if (!(flags & VIR_DOMAIN_UNDEFINE_KEEP_NVRAM)) { diff --git a/src/qemu/qemu_parse_command.c b/src/qemu/qemu_parse_command.c index 0ce9632..2a0b200 100644 --- a/src/qemu/qemu_parse_command.c +++ b/src/qemu/qemu_parse_command.c @@ -650,6 +650,7 @@ qemuParseCommandLineDisk(virDomainXMLOptionPtr xmlopt, int idx =3D -1; int busid =3D -1; int unitid =3D -1; + bool is_firmware =3D false; =20 if (qemuParseKeywords(val, &keywords, @@ -772,6 +773,9 @@ qemuParseCommandLineDisk(virDomainXMLOptionPtr xmlopt, def->bus =3D VIR_DOMAIN_DISK_BUS_VIRTIO; } else if (STREQ(values[i], "xen")) { def->bus =3D VIR_DOMAIN_DISK_BUS_XEN; + } else if (STREQ(values[i], "pflash")) { + def->bus =3D VIR_DOMAIN_DISK_BUS_LAST; + is_firmware =3D true; } else if (STREQ(values[i], "sd")) { def->bus =3D VIR_DOMAIN_DISK_BUS_SD; } @@ -943,8 +947,25 @@ qemuParseCommandLineDisk(virDomainXMLOptionPtr xmlopt, ignore_value(VIR_STRDUP(def->dst, "hda")); } =20 - if (!def->dst) - goto error; + if (!def->dst) { + if (is_firmware && def->bus =3D=3D VIR_DOMAIN_DISK_BUS_LAST) { + if (!dom->os.loader && (VIR_ALLOC(dom->os.loader) < 0)) + goto error; + if (def->src->readonly) { + /* Loader spec */ + dom->os.loader->loader_src =3D def->src; + dom->os.loader->type =3D VIR_DOMAIN_LOADER_TYPE_PFLASH; + } else { + /* NVRAM Spec */ + if (!dom->os.loader->nvram && (VIR_ALLOC(dom->os.loader->n= vram) < 0)) + goto error; + dom->os.loader->nvram =3D def->src; + } + } else { + goto error; + } + } + if (STREQ(def->dst, "xvda")) def->dst[3] =3D 'a' + idx; else @@ -2215,8 +2236,11 @@ qemuParseCommandLine(virCapsPtr caps, } else if (STREQ(arg, "-bios")) { WANT_VALUE(); if (VIR_ALLOC(def->os.loader) < 0 || - VIR_STRDUP(def->os.loader->path, val) < 0) + VIR_ALLOC(def->os.loader->loader_src) < 0 || + VIR_STRDUP(def->os.loader->loader_src->path, val) < 0) goto error; + def->os.loader->loader_src->type =3D VIR_STORAGE_TYPE_FILE; + def->os.loader->type =3D VIR_DOMAIN_LOADER_TYPE_ROM; } else if (STREQ(arg, "-initrd")) { WANT_VALUE(); if (VIR_STRDUP(def->os.initrd, val) < 0) diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 6a5262a..725dd6e 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -3994,25 +3994,32 @@ qemuPrepareNVRAM(virQEMUDriverConfigPtr cfg, const char *master_nvram_path; ssize_t r; =20 - if (!loader || !loader->nvram || virFileExists(loader->nvram)) + if (!loader || !loader->loader_src || !loader->nvram || + loader->nvram->type =3D=3D VIR_STORAGE_TYPE_NETWORK) return 0; =20 master_nvram_path =3D loader->templt; - if (!loader->templt) { + /* Even if a template is not specified, we associate "known" EFI firmw= are + * to their NVRAM templates. + * Ofcourse this only applies to local firmware paths, as it is diffcu= lt + * for libvirt to parse all network paths. + */ + if (!loader->templt && loader->loader_src->type =3D=3D VIR_STORAGE_TYP= E_FILE) { size_t i; for (i =3D 0; i < cfg->nfirmwares; i++) { - if (STREQ(cfg->firmwares[i]->name, loader->path)) { + if (STREQ(cfg->firmwares[i]->name, loader->loader_src->path)) { master_nvram_path =3D cfg->firmwares[i]->nvram; break; } } } =20 - if (!master_nvram_path) { - virReportError(VIR_ERR_OPERATION_FAILED, - _("unable to find any master var store for " - "loader: %s"), loader->path); - goto cleanup; + if (!master_nvram_path && loader->nvram) { + /* There is no template description, but an NVRAM spec + * has already been provided. + * Trust the client to have generated the right spec here + */ + return 0; } =20 if ((srcFD =3D virFileOpenAs(master_nvram_path, O_RDONLY, @@ -4022,13 +4029,13 @@ qemuPrepareNVRAM(virQEMUDriverConfigPtr cfg, master_nvram_path); goto cleanup; } - if ((dstFD =3D virFileOpenAs(loader->nvram, + if ((dstFD =3D virFileOpenAs(loader->nvram->path, O_WRONLY | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR, cfg->user, cfg->group, 0)) < 0) { virReportSystemError(-dstFD, _("Failed to create file '%s'"), - loader->nvram); + loader->nvram->path); goto cleanup; } created =3D true; @@ -4046,7 +4053,7 @@ qemuPrepareNVRAM(virQEMUDriverConfigPtr cfg, if (safewrite(dstFD, buf, r) < 0) { virReportSystemError(errno, _("Unable to write to file '%s'"), - loader->nvram); + loader->nvram->path); goto cleanup; } } while (r); @@ -4060,7 +4067,7 @@ qemuPrepareNVRAM(virQEMUDriverConfigPtr cfg, if (VIR_CLOSE(dstFD) < 0) { virReportSystemError(errno, _("Unable to close file '%s'"), - loader->nvram); + loader->nvram->path); goto cleanup; } =20 @@ -4070,7 +4077,7 @@ qemuPrepareNVRAM(virQEMUDriverConfigPtr cfg, * copy the file content. Roll back. */ if (ret < 0) { if (created) - unlink(loader->nvram); + unlink(loader->nvram->path); } =20 VIR_FORCE_CLOSE(srcFD); diff --git a/src/security/security_dac.c b/src/security/security_dac.c index 663c8c9..fce4204 100644 --- a/src/security/security_dac.c +++ b/src/security/security_dac.c @@ -1604,7 +1604,8 @@ virSecurityDACRestoreAllLabel(virSecurityManagerPtr m= gr, } =20 if (def->os.loader && def->os.loader->nvram && - virSecurityDACRestoreFileLabel(priv, def->os.loader->nvram) < 0) + def->os.loader->nvram->type =3D=3D VIR_STORAGE_TYPE_FILE && + virSecurityDACRestoreFileLabel(priv, def->os.loader->nvram->path) = < 0) rc =3D -1; =20 return rc; @@ -1732,8 +1733,9 @@ virSecurityDACSetAllLabel(virSecurityManagerPtr mgr, return -1; =20 if (def->os.loader && def->os.loader->nvram && + def->os.loader->nvram->type =3D=3D VIR_STORAGE_TYPE_FILE && virSecurityDACSetOwnership(priv, NULL, - def->os.loader->nvram, user, group) < 0) + def->os.loader->nvram->path, user, grou= p) < 0) return -1; =20 if (def->os.kernel && diff --git a/src/security/security_selinux.c b/src/security/security_selinu= x.c index c26cdac..396e7fc 100644 --- a/src/security/security_selinux.c +++ b/src/security/security_selinux.c @@ -2459,7 +2459,8 @@ virSecuritySELinuxRestoreAllLabel(virSecurityManagerP= tr mgr, rc =3D -1; =20 if (def->os.loader && def->os.loader->nvram && - virSecuritySELinuxRestoreFileLabel(mgr, def->os.loader->nvram) < 0) + def->os.loader->nvram->type =3D=3D VIR_STORAGE_TYPE_FILE && + virSecuritySELinuxRestoreFileLabel(mgr, def->os.loader->nvram->pat= h) < 0) rc =3D -1; =20 return rc; @@ -2851,8 +2852,9 @@ virSecuritySELinuxSetAllLabel(virSecurityManagerPtr m= gr, /* 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 =3D=3D VIR_STORAGE_TYPE_FILE && secdef && secdef->imagelabel && - virSecuritySELinuxSetFilecon(mgr, def->os.loader->nvram, + virSecuritySELinuxSetFilecon(mgr, def->os.loader->nvram->path, secdef->imagelabel) < 0) return -1; =20 --=20 1.8.1.2 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list