From nobody Wed May 15 11:34:27 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of redhat.com designates 170.10.133.124 as permitted sender) client-ip=170.10.133.124; envelope-from=libvir-list-bounces@redhat.com; helo=us-smtp-delivery-124.mimecast.com; Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of redhat.com designates 170.10.133.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=fail(p=none dis=none) header.from=nutanix.com Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by mx.zohomail.com with SMTPS id 1647836943840779.6118674960102; Sun, 20 Mar 2022 21:29:03 -0700 (PDT) Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-660-MapyYO7EPRm1-HvCDDcYGA-1; Mon, 21 Mar 2022 00:28:50 -0400 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.rdu2.redhat.com [10.11.54.5]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 88B20804192; Mon, 21 Mar 2022 04:28:48 +0000 (UTC) Received: from mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com [10.30.29.100]) by smtp.corp.redhat.com (Postfix) with ESMTP id 46F2253D8; Mon, 21 Mar 2022 04:28:46 +0000 (UTC) Received: from mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (localhost [IPv6:::1]) by mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (Postfix) with ESMTP id 1B49019451EF; Mon, 21 Mar 2022 04:28:44 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx09.intmail.prod.int.rdu2.redhat.com [10.11.54.9]) by mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (Postfix) with ESMTP id A43AF19452D2 for ; Mon, 21 Mar 2022 04:28:42 +0000 (UTC) Received: by smtp.corp.redhat.com (Postfix) id 66593428EE1; Mon, 21 Mar 2022 04:28:42 +0000 (UTC) Received: from mimecast-mx02.redhat.com (mimecast03.extmail.prod.ext.rdu2.redhat.com [10.11.55.19]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 60D71428EE0 for ; Mon, 21 Mar 2022 04:28:42 +0000 (UTC) Received: from us-smtp-1.mimecast.com (us-smtp-delivery-1.mimecast.com [205.139.110.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 40826811E76 for ; Mon, 21 Mar 2022 04:28:42 +0000 (UTC) Received: from mx0b-002c1b01.pphosted.com (mx0b-002c1b01.pphosted.com [148.163.155.12]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-402-YojF4fE9O5anOhUZbC4XlQ-1; Mon, 21 Mar 2022 00:28:40 -0400 Received: from pps.filterd (m0127841.ppops.net [127.0.0.1]) by mx0b-002c1b01.pphosted.com (8.16.1.2/8.16.1.2) with ESMTP id 22KEH1Rt027831 for ; Sun, 20 Mar 2022 21:28:39 -0700 Received: from nam11-co1-obe.outbound.protection.outlook.com (mail-co1nam11lp2168.outbound.protection.outlook.com [104.47.56.168]) by mx0b-002c1b01.pphosted.com (PPS) with ESMTPS id 3ewcq7tmhq-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT) for ; Sun, 20 Mar 2022 21:28:39 -0700 Received: from SJ0PR02MB8564.namprd02.prod.outlook.com (2603:10b6:a03:3f6::16) by DM6PR02MB6106.namprd02.prod.outlook.com (2603:10b6:5:1d3::19) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5081.18; Mon, 21 Mar 2022 04:28:35 +0000 Received: from SJ0PR02MB8564.namprd02.prod.outlook.com ([fe80::b167:3939:c2e0:64e8]) by SJ0PR02MB8564.namprd02.prod.outlook.com ([fe80::b167:3939:c2e0:64e8%5]) with mapi id 15.20.5081.022; Mon, 21 Mar 2022 04:28:34 +0000 X-MC-Unique: MapyYO7EPRm1-HvCDDcYGA-1 X-Original-To: libvir-list@listman.corp.redhat.com X-MC-Unique: YojF4fE9O5anOhUZbC4XlQ-1 From: Rohit Kumar To: libvir-list@redhat.com Subject: [PATCH] Introduce network-backed NVRAM Date: Sun, 20 Mar 2022 21:28:13 -0700 Message-Id: <20220321042813.437626-1-rohit.kumar3@nutanix.com> X-ClientProxiedBy: SJ0PR03CA0155.namprd03.prod.outlook.com (2603:10b6:a03:338::10) To SJ0PR02MB8564.namprd02.prod.outlook.com (2603:10b6:a03:3f6::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 925202be-3875-410e-a142-08da0af34313 X-MS-TrafficTypeDiagnostic: DM6PR02MB6106:EE_ X-Microsoft-Antispam-PRVS: x-proofpoint-crosstenant: true X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0 X-Microsoft-Antispam-Message-Info: 8I/bZk1fKEQOxkhQz7zt5VLVgPjaVkxKkN/UMPoN7r6s2w37Unp/PPZkZ3l6+lj+SXau5EJ8N55ugiIXhrHvSE0BUZwAB9Je5YO5LR7uQs5R+9L2RqdI8o083nJTWE1xU36i7JO+QyNO17VVxoe1/TxCWeQxV8NgkHIXARC3kIQasHIhHRwSGhZZo8XjpRdwzoOr/IHzVUAqzkUPoMoFKSaJtWtFIjST9N0xWLQd+ywo4ZXky5VWMPedH0cANJf55LPXQPV6l+vSVMlZXAszv6U98KMgonarxWjc3c9+bApr5PAyc03dh2NnchZ2hCWWFMUeZtbzENHBOhLsqlhOUT73uMuvJcwXRzG2ZwvCJS1CDB5qx4kxDgn0w9E69oiQc163Ec7GRQTg4a91UAg9wap2xK7T/nfXL9AsIglNvEkSwMsTWzZD9H62rbzuG04UQP2jP072SA/voYEmn99TN3+D3jP4Tf3/abKz0ZDuB+ChGRW00oe3xFMubSaSqnNSipcpwMOuuU5Jf9AwfHg1wexsDU1UKqY1HKgmlOTxkN1oIueVfZhpyZlfymkYYP9XmuiV4Urif2LweQgmaw0RrRqZPGez7oL4cn2csxwnL4AFrwQ66hhF+ekM6//ZXXA4Xizn9alSzNd+/sHiv4ykGd+ywpqHJa95t8uFIumObmzf421DgUBt+BnBm3/oj4HRKX61nItDEn3rq4MPhutcZg== X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:SJ0PR02MB8564.namprd02.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230001)(366004)(2906002)(316002)(38100700002)(6512007)(86362001)(6916009)(1076003)(30864003)(26005)(52116002)(186003)(6506007)(36756003)(5660300002)(54906003)(107886003)(8936002)(6486002)(66946007)(6666004)(66476007)(508600001)(83380400001)(66556008)(2616005)(38350700002)(4326008)(8676002); DIR:OUT; SFP:1102 X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?4GmtkrhLm6hs6XfXVZJmENHcanfjUX90OeL6GE/oLMYDo5AG/f4ykNCNAGAh?= =?us-ascii?Q?95OivZK+u2I+NhkUzeJGsBbQ3qDWw8Pl/Y/fU9pQeu4qlTpw4kf7iVn/N8KF?= =?us-ascii?Q?DRbGr/27ITLeGxcjjCw9mFvXtOkccL5ufY/Z+zViENePGpqQbMTxnUMjhjqP?= =?us-ascii?Q?ZDIbTGumtlcGgVgjwV0EFghxbBls1M/xIWyVZ0+T9S3teYfFl3ecpzOvmlE2?= =?us-ascii?Q?5jkYTB6XghmP7CTIIZgrDudqXLJHLOEsjwD0GnToFQHjgfSL0lZs0bdkum3R?= =?us-ascii?Q?ODpyleqeQBt958PtLAclHk4dD7wNPIgArjLoP5hygHiVccCstV6AwtFyKktx?= =?us-ascii?Q?j5xUcedDYlURtXh46/p26YZO1E4WBzZ6qmToKhp3lGxpRSmHmWhjHCgA3NYu?= =?us-ascii?Q?+0IUXj4FLfC24Yu6p/Z7gKkjSG341CUnkZ1jB07bAi4IEv8Zjt8kkAgcNtTh?= =?us-ascii?Q?klJnsUyMYYw5CxoQtl8EDy0iw9OEPabaHqLQiQ+x6glOGfugATqgn+GikYWL?= =?us-ascii?Q?e/sMkEo/4SZ/dAOMrnuG0ZvbnAgYC6vuWO3Vhmv/bo7Lt4WoGQcLNNXGKtwT?= =?us-ascii?Q?L7pk5oHADj3wmOP5VNnbGZnppcV9+NouDzyhEs4vuaHvT9BimVYJ6AKweF4R?= =?us-ascii?Q?IFXNpp1aAWHniTvRbPiZn7haUEV+ynyRgf+72dti49g2879SFtSrhMoAiWOU?= =?us-ascii?Q?fIG29q8Tjxy7GNzSvKUK2ZFvs8PxVbAlY4RPZyTQZ17PEBrKKei0JEiOeKlD?= =?us-ascii?Q?MywFJve4xOsyD8KNDmLafEMV2Wsq4NSQcRHzCuXQOzeX8hnHiIXi3ObfwzT3?= =?us-ascii?Q?wx7oPAfWWx8cibYg2jN66Edot6OlAsmBVX5t9LOQL94GFhPlE9Zw6HyK1+Q7?= =?us-ascii?Q?APfgZwcQsm3bfTM6wY6O/Iu9CVi/1PoiqP/+y1aJGZrpMwh1PPjQhM2AkDLF?= =?us-ascii?Q?lKG0FDDeaGPdwhgRaNNAGQ9bkt6ETvi90BfP48IqKzOngZWMuXPZW1vTNKU6?= =?us-ascii?Q?iI04vuNYtOsq9ZeURYb9LAqkQiq1/jrzY1JWpDoJdKba/WS+3shWnLYKA9T8?= =?us-ascii?Q?SDRtBDumJLfcTcq9mhi3KaSiQkN9Mk499aJznxueGasFo0rbnxsI5OP5Un7N?= =?us-ascii?Q?JWocI4OTm/okiI5bj4o63y+IcMbGkB+eb660GtqYqMMtRH+KVTLPf/fSNvdC?= =?us-ascii?Q?rkcU/v50Vk8+mZuB5BP0J0T8fdRRVAL4wo1rJea5mPcAcbeFXxkbmAjYIb83?= =?us-ascii?Q?p++dWOCJ7kQE99Pn2EJ4ks2RChsZFyiTcL8/hBhyzd0UIH7QsTzIai7MHOrI?= =?us-ascii?Q?25q920qU7XixYv+5NxjWU0jj6hA0qa/0Weg1odszIB8LTrozZ01HH8sBhsuf?= =?us-ascii?Q?mv4UMcukqKNgBiPQ0zrKiIDaqV2OlilUsW+DoOVLSnz6ZPJZ3tW3vr6Pksai?= =?us-ascii?Q?vRGbLlUHAuaijIU/9hMF7YIKtIpoOzsnC2Y6aNf4e8jxa18P7VT8AQ=3D=3D?= X-OriginatorOrg: nutanix.com X-MS-Exchange-CrossTenant-Network-Message-Id: 925202be-3875-410e-a142-08da0af34313 X-MS-Exchange-CrossTenant-AuthSource: SJ0PR02MB8564.namprd02.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 21 Mar 2022 04:28:34.6911 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: bb047546-786f-4de1-bd75-24e5b6f79043 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: KRukq3VeYZxS0FXf/By80sssSkm2/ZNxKermYC0edWUqyLtpDq+xqNYcsOjZ4UQ9PzVr16XDtSiEdcBc97ZcDg/9F0HGoJmjTXdbx7Q/h2I= X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM6PR02MB6106 X-Proofpoint-ORIG-GUID: lT9Da4-Z52JyoVVB10Ram6Vtra4HdWli X-Proofpoint-GUID: lT9Da4-Z52JyoVVB10Ram6Vtra4HdWli X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.850,Hydra:6.0.425,FMLib:17.11.64.514 definitions=2022-03-21_01,2022-03-15_01,2022-02-23_01 X-Proofpoint-Spam-Reason: safe X-Mimecast-Impersonation-Protect: Policy=CLT - Impersonation Protection Definition; Similar Internal Domain=false; Similar Monitored External Domain=false; Custom External Domain=false; Mimecast External Domain=false; Newly Observed Domain=false; Internal User Name=false; Custom Display Name List=false; Reply-to Address Mismatch=false; Targeted Threat Dictionary=false; Mimecast Threat Dictionary=false; Custom Threat Dictionary=false X-Scanned-By: MIMEDefang 2.85 on 10.11.54.9 X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: prachatos.mitra@nutanix.com, Prerna Saxena , Florian Schmidt , Rohit Kumar Errors-To: libvir-list-bounces@redhat.com Sender: "libvir-list" X-Scanned-By: MIMEDefang 2.79 on 10.11.54.5 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=libvir-list-bounces@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable X-ZM-MESSAGEID: 1647836944690100001 Content-Type: text/plain; charset="utf-8" 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: or Signed-off-by: Prerna Saxena Signed-off-by: Florian Schmidt Signed-off-by: Rohit Kumar --- 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 @@ - + + + + + + + + + + + @@ -1714,6 +1724,31 @@ =20 + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1721,28 +1756,7 @@ - - - - - - - - - - - - - - - - - - - - - - + =20 @@ -2137,10 +2151,7 @@ =20 - - - network - + @@ -2155,6 +2166,13 @@ =20 + + + network + + + + volume 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; =20 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, } =20 =20 +static int +virDomainNvramDefParseXML(virStorageSource *nvram, + xmlXPathContextPtr ctxt, + virDomainXMLOption *opt, + unsigned int flags) +{ + g_autofree char *srcTypeFile =3D NULL; + g_autofree char *srcTypeNetwork =3D NULL; + xmlNodePtr source; + + srcTypeFile =3D virXPathString("string(./os/nvram/source/@file)", ctx= t); + srcTypeNetwork =3D virXPathString("string(./os/nvram/source/@protocol= )", ctxt); + + if (!srcTypeFile && !srcTypeNetwork) { + nvram->type =3D VIR_STORAGE_TYPE_FILE; + nvram->path =3D virXPathString("string(./os/nvram[1])", ctxt); + return 0; + } else { + if (srcTypeFile) { + nvram->type =3D VIR_STORAGE_TYPE_FILE; + } else { + nvram->type =3D VIR_STORAGE_TYPE_NETWORK; + } + source =3D 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, =20 static int virDomainDefParseBootLoaderOptions(virDomainDef *def, - xmlXPathContextPtr ctxt) + xmlXPathContextPtr ctxt, + virDomainXMLOption *xmlopt, + unsigned int flags) { xmlNodePtr loader_node =3D virXPathNode("./os/loader[1]", ctxt); const bool fwAutoSelect =3D def->os.firmware !=3D VIR_DOMAIN_OS_DEF_FI= RMWARE_NONE; @@ -18234,7 +18267,14 @@ virDomainDefParseBootLoaderOptions(virDomainDef *d= ef, fwAutoSelect) < 0) return -1; =20 - def->os.loader->nvram =3D virXPathString("string(./os/nvram[1])", ctxt= ); + if (virXPathNode("./os/nvram[1]", ctxt)) { + def->os.loader->nvram =3D g_new0(virStorageSource, 1); + + if (virDomainNvramDefParseXML(def->os.loader->nvram, + ctxt, xmlopt, flags) < 0) + return -1; + } + if (!fwAutoSelect) def->os.loader->nvramTemplate =3D virXPathString("string(./os/nvra= m[1]/@template)", ctxt); =20 @@ -18288,7 +18328,9 @@ virDomainDefParseBootAcpiOptions(virDomainDef *def, =20 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; =20 - if (virDomainDefParseBootLoaderOptions(def, ctxt) < 0) + if (virDomainDefParseBootLoaderOptions(def, ctxt, xmlopt, flags) <= 0) return -1; =20 if (virDomainDefParseBootAcpiOptions(def, ctxt) < 0) @@ -18322,7 +18364,7 @@ virDomainDefParseBootOptions(virDomainDef *def, case VIR_DOMAIN_OSTYPE_UML: virDomainDefParseBootKernelOptions(def, ctxt); =20 - if (virDomainDefParseBootLoaderOptions(def, ctxt) < 0) + if (virDomainDefParseBootLoaderOptions(def, ctxt, xmlopt, flags) <= 0) return -1; =20 break; @@ -19606,7 +19648,7 @@ virDomainDefParseXML(xmlXPathContextPtr ctxt, if (virDomainDefClockParse(def, ctxt) < 0) return NULL; =20 - if (virDomainDefParseBootOptions(def, ctxt) < 0) + if (virDomainDefParseBootOptions(def, ctxt, xmlopt, flags) < 0) return NULL; =20 /* analysis of the disk devices */ @@ -26899,7 +26941,9 @@ virDomainHugepagesFormat(virBuffer *buf, =20 static void virDomainLoaderDefFormat(virBuffer *buf, - virDomainLoaderDef *loader) + virDomainLoaderDef *loader, + virDomainXMLOption *xmlopt, + unsigned int flags) { const char *readonly =3D virTristateBoolTypeToString(loader->readonly); const char *secure =3D virTristateBoolTypeToString(loader->secure); @@ -26921,13 +26965,27 @@ virDomainLoaderDefFormat(virBuffer *buf, else virBufferAddLit(buf, "/>\n"); =20 - if (loader->nvram || loader->nvramTemplate) { - virBufferAddLit(buf, "nvramTempla= te); - if (loader->nvram) - virBufferEscapeString(buf, ">%s\n", loader->nvram); - else - virBufferAddLit(buf, "/>\n"); + if (loader->nvram) { + if (loader->nvram->type =3D=3D VIR_STORAGE_TYPE_FILE) { + virBufferAddLit(buf, "nvramTe= mplate); + if (loader->nvram->path) + virBufferEscapeString(buf, ">%s\n", loader->nvram-= >path); + else + virBufferAddLit(buf, "/>\n"); + } else { + virBufferAddLit(buf, "nvramTe= mplate); + 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, "\n"); + } } } =20 @@ -28122,7 +28180,7 @@ virDomainDefFormatInternalSetRootName(virDomainDef = *def, virBufferAsprintf(buf, "%s\n", def->os.init= group); =20 if (def->os.loader) - virDomainLoaderDefFormat(buf, def->os.loader); + virDomainLoaderDefFormat(buf, def->os.loader, xmlopt, 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 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 */ }; =20 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; =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 c836799888..649a6f5b55 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -9583,6 +9583,7 @@ qemuBuildDomainLoaderPflashCommandLine(virCommand *cm= d, virQEMUCaps *qemuCaps) { g_auto(virBuffer) buf =3D VIR_BUFFER_INITIALIZER; + g_autofree char *nvramPath =3D NULL; int unit =3D 0; =20 if (loader->secure =3D=3D VIR_TRISTATE_BOOL_YES) { @@ -9610,8 +9611,10 @@ qemuBuildDomainLoaderPflashCommandLine(virCommand *c= md, virCommandAddArgBuffer(cmd, &buf); =20 if (loader->nvram) { + if (qemuGetDriveSourceString(loader->nvram, NULL, &nvramPath) < 0) + return; virBufferAddLit(&buf, "file=3D"); - virQEMUBuildBufferEscapeComma(&buf, loader->nvram); + virQEMUBuildBufferEscapeComma(&buf, nvramPath); virBufferAsprintf(&buf, ",if=3Dpflash,format=3Draw,unit=3D%d", uni= t); =20 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, } =20 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 =3D g_new0(virStorageSource, 1); + def->os.loader->nvram->type =3D VIR_STORAGE_TYPE_FILE; + qemuDomainNVRAMPathFormat(cfg, def, &def->os.loader->nvram->path); + } =20 if (qemuDomainDefAddDefaultDevices(driver, def, qemuCaps) < 0) return -1; @@ -11133,15 +11138,23 @@ qemuDomainInitializePflashStorageSource(virDomain= Obj *vm) pflash0->nodeformat =3D g_strdup("libvirt-pflash0-format"); pflash0->nodestorage =3D g_strdup("libvirt-pflash0-storage"); =20 - if (def->os.loader->nvram) { pflash1 =3D virStorageSourceNew(); - pflash1->type =3D VIR_STORAGE_TYPE_FILE; pflash1->format =3D VIR_STORAGE_FILE_RAW; - pflash1->path =3D g_strdup(def->os.loader->nvram); + pflash1->path =3D g_strdup(def->os.loader->nvram->path); pflash1->readonly =3D false; pflash1->nodeformat =3D g_strdup("libvirt-pflash1-format"); pflash1->nodestorage =3D g_strdup("libvirt-pflash1-storage"); + + if (def->os.loader->nvram->type =3D=3D VIR_STORAGE_TYPE_FILE) { + pflash1->type =3D VIR_STORAGE_TYPE_FILE; + } else if (def->os.loader->nvram->type =3D=3D VIR_STORAGE_TYPE_NET= WORK) { + pflash1->protocol =3D def->os.loader->nvram->protocol; + pflash1->hosts =3D g_new0(virStorageNetHostDef, 1); + pflash1->nhosts =3D 1; + pflash1->hosts[0].name =3D def->os.loader->nvram->hosts[0].nam= e; + pflash1->hosts[0].port =3D def->os.loader->nvram->hosts[0].por= t; + } } =20 priv->pflash0 =3D 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, } } =20 - if (vm->def->os.loader && vm->def->os.loader->nvram) { - nvram_path =3D g_strdup(vm->def->os.loader->nvram); + if (vm->def->os.loader && vm->def->os.loader->nvram && + vm->def->os.loader->nvram->type =3D=3D VIR_STORAGE_TYPE_FILE) { + nvram_path =3D g_strdup(vm->def->os.loader->nvram->path); } else if (vm->def->os.firmware =3D=3D 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 =3D g_strdup(flash->nvram_template.f= ilename); =20 - if (!def->os.loader->nvram) - qemuDomainNVRAMPathFormat(cfg, def, &def->os.loader->nvram); + if (!def->os.loader->nvram) { + def->os.loader->nvram =3D g_new0(virStorageSource, 1); + def->os.loader->nvram->type =3D VIR_STORAGE_TYPE_FILE; + qemuDomainNVRAMPathFormat(cfg, def, &def->os.loader->nvram->pa= th); + } =20 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; =20 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 =3D=3D VIR_STOR= AGE_TYPE_FILE + && virFileExists(def->os.loader->nvram->path)) || + (def->os.loader->nvram->type =3D=3D VIR_STORAGE_TYPE_NETWORK = && + def->os.loader->nvram->path)))) return 0; =20 /* ... 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 =3D g_slist_prepend(*paths, g_strdup(loader->path)); =20 - if (loader->nvram) - *paths =3D g_slist_prepend(*paths, g_strdup(loader->nvram)= ); + if (loader->nvram && + loader->nvram->type =3D=3D VIR_STORAGE_TYPE_FILE) + *paths =3D g_slist_prepend(*paths, g_strdup(loader->nvram-= >path)); break; =20 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; =20 if (!loader || !loader->nvram || - (virFileExists(loader->nvram) && !reset_nvram)) + loader->nvram->type !=3D VIR_STORAGE_TYPE_FILE || + (virFileExists(loader->nvram->path) && !reset_nvram)) return 0; =20 master_nvram_path =3D loader->nvramTemplate; @@ -4507,7 +4508,7 @@ qemuPrepareNVRAM(virQEMUDriver *driver, data.srcFD =3D srcFD; data.srcPath =3D master_nvram_path; =20 - 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, } =20 if (def->os.loader && def->os.loader->nvram && - virSecurityDACRestoreFileLabel(mgr, def->os.loader->nvram) < 0) + def->os.loader->nvram->type =3D=3D VIR_STORAGE_TYPE_FILE && + virSecurityDACRestoreFileLabel(mgr, def->os.loader->nvram->path) <= 0) rc =3D -1; =20 if (def->os.kernel && @@ -2182,8 +2183,9 @@ virSecurityDACSetAllLabel(virSecurityManager *mgr, } =20 if (def->os.loader && def->os.loader->nvram && + def->os.loader->nvram->type =3D=3D VIR_STORAGE_TYPE_FILE && virSecurityDACSetOwnership(mgr, NULL, - def->os.loader->nvram, + def->os.loader->nvram->path, user, group, true) < 0) return -1; =20 diff --git a/src/security/security_selinux.c b/src/security/security_selinu= x.c index 6f02baf2ce..1b6b67e8c7 100644 --- a/src/security/security_selinux.c +++ b/src/security/security_selinux.c @@ -2806,7 +2806,8 @@ virSecuritySELinuxRestoreAllLabel(virSecurityManager = *mgr, } =20 if (def->os.loader && def->os.loader->nvram && - virSecuritySELinuxRestoreFileLabel(mgr, def->os.loader->nvram, tru= e) < 0) + def->os.loader->nvram->type =3D=3D VIR_STORAGE_TYPE_FILE && + virSecuritySELinuxRestoreFileLabel(mgr, def->os.loader->nvram->pat= h, true) < 0) rc =3D -1; =20 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 =3D=3D 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; =20 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") !=3D 0) goto cleanup; =20 - if (ctl->def->os.loader && ctl->def->os.loader->nvram) - if (vah_add_file(&buf, ctl->def->os.loader->nvram, "rwk") !=3D 0) + if (ctl->def->os.loader && ctl->def->os.loader->nvram && + ctl->def->os.loader->nvram->type =3D=3D VIR_STORAGE_TYPE_FILE) + if (vah_add_file(&buf, ctl->def->os.loader->nvram->path, "rwk") != =3D 0) goto cleanup; =20 for (i =3D 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 _vbo= xDriver *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->reado= nly); + 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/qemuxml= 2argvdata/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=3DC \ +PATH=3D/bin \ +HOME=3D/tmp/lib/domain--1-test-bios \ +USER=3Dtest \ +LOGNAME=3Dtest \ +XDG_DATA_HOME=3D/tmp/lib/domain--1-test-bios/.local/share \ +XDG_CACHE_HOME=3D/tmp/lib/domain--1-test-bios/.cache \ +XDG_CONFIG_HOME=3D/tmp/lib/domain--1-test-bios/.config \ +QEMU_AUDIO_DRV=3Dnone \ +/usr/bin/qemu-system-x86_64 \ +-name guest=3Dtest-bios,debug-threads=3Don \ +-S \ +-object secret,id=3DmasterKey0,format=3Draw,file=3D/tmp/lib/domain--1-test= -bios/master-key.aes \ +-machine pc,usb=3Doff,dump-guest-core=3Doff \ +-accel tcg \ +-drive file=3D/usr/share/OVMF/OVMF_CODE.fd,if=3Dpflash,format=3Draw,unit= =3D0,readonly=3Don \ +-drive file=3Discsi://example.org:6000/iqn.1992-01.com.example,if=3Dpflash= ,format=3Draw,unit=3D1 \ +-m 1024 \ +-realtime mlock=3Doff \ +-smp 1,sockets=3D1,cores=3D1,threads=3D1 \ +-uuid 362d1fc1-df7d-193e-5c18-49a71bd1da66 \ +-display none \ +-no-user-config \ +-nodefaults \ +-chardev socket,id=3Dcharmonitor,path=3D/tmp/lib/domain--1-test-bios/monit= or.sock,server=3Don,wait=3Doff \ +-mon chardev=3Dcharmonitor,id=3Dmonitor,mode=3Dcontrol \ +-rtc base=3Dutc \ +-no-shutdown \ +-boot menu=3Don,strict=3Don \ +-usb \ +-drive file=3D/dev/HostVG/QEMUGuest1,format=3Draw,if=3Dnone,id=3Ddrive-ide= 0-0-0 \ +-device ide-hd,bus=3Dide.0,unit=3D0,drive=3Ddrive-ide0-0-0,id=3Dide0-0-0,b= ootindex=3D1 \ +-device usb-tablet,id=3Dinput0,bus=3Dusb.0,port=3D1 \ +-device virtio-balloon-pci,id=3Dballoon0,bus=3Dpci.0,addr=3D0x2 \ +-msg timestamp=3Don diff --git a/tests/qemuxml2argvdata/bios-nvram-network.xml b/tests/qemuxml2= argvdata/bios-nvram-network.xml new file mode 100644 index 0000000000..0e1e23fd31 --- /dev/null +++ b/tests/qemuxml2argvdata/bios-nvram-network.xml @@ -0,0 +1,40 @@ + + test-bios + 362d1fc1-df7d-193e-5c18-49a71bd1da66 + 1048576 + 1048576 + 1 + + hvm + /usr/share/OVMF/OVMF_CODE.fd<= /loader> + + + + + + + + + + + + + destroy + restart + restart + + /usr/bin/qemu-system-x86_64 + + + +
+ + + + + + + + + + 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", --=20 2.25.1