From nobody Fri Dec 19 20:17:27 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) client-ip=8.43.85.245; envelope-from=devel-bounces@lists.libvirt.org; helo=lists.libvirt.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) smtp.mailfrom=devel-bounces@lists.libvirt.org; dmarc=fail(p=none dis=none) header.from=gmail.com Return-Path: Received: from lists.libvirt.org (lists.libvirt.org [8.43.85.245]) by mx.zohomail.com with SMTPS id 1746810858083376.0686956220799; Fri, 9 May 2025 10:14:18 -0700 (PDT) Received: by lists.libvirt.org (Postfix, from userid 996) id 6612A171C; Fri, 9 May 2025 13:14:17 -0400 (EDT) Received: from lists.libvirt.org (localhost [IPv6:::1]) by lists.libvirt.org (Postfix) with ESMTP id A82E61763; Fri, 9 May 2025 13:13:15 -0400 (EDT) Received: by lists.libvirt.org (Postfix, from userid 996) id 178C5179E; Fri, 9 May 2025 13:13:11 -0400 (EDT) Received: from mail-ed1-f48.google.com (mail-ed1-f48.google.com [209.85.208.48]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by lists.libvirt.org (Postfix) with ESMTPS id 860DD179E for ; Fri, 9 May 2025 13:13:01 -0400 (EDT) Received: by mail-ed1-f48.google.com with SMTP id 4fb4d7f45d1cf-5f5bef591d6so4774151a12.1 for ; Fri, 09 May 2025 10:13:01 -0700 (PDT) Received: from tulp.my.domain (80-115-115-199.cable.dynamic.v4.ziggo.nl. [80.115.115.199]) by smtp.gmail.com with ESMTPSA id 4fb4d7f45d1cf-5fcb3773b04sm581106a12.10.2025.05.09.10.12.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 09 May 2025 10:12:58 -0700 (PDT) X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on lists.libvirt.org X-Spam-Level: X-Spam-Status: No, score=-0.8 required=5.0 tests=DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2,RCVD_IN_VALIDITY_RPBL_BLOCKED, RCVD_IN_VALIDITY_SAFE_BLOCKED,SPF_HELO_NONE autolearn=unavailable autolearn_force=no version=3.4.4 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1746810780; x=1747415580; darn=lists.libvirt.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=MJlF7D0xpfPjbCPKdrWI6JVGYxuoLTDn/2fP7GBU1es=; b=F/TIN+wPm72egJjP+L006I3eGDGpWYk3GyESSW+p6vHtJDI/oO2ux3xM1uwbaCUWww mAuM9VJGtWtkRHwoLpp6C5JBotuQWh7ELCJxKf/9GQ4DGaJ5Ik5VHPcqLr9RKri1vQ5Q t+aKuOaX1+JbEDG55/Cg+DDsYST3/gzXSjCo9IS47dXhahZw0QJvBi9+miesmBUQXb4H IOOJOk/NP3BZhbxURkv8aa4b6jWXxP6JCqIuYTaLOcfmiOVDaTVLaOBbEiSteK2KJX6G eTW4gvo3V+OzavO7HuyxBFyO9I9Qh3z9FlIzxR1iUwmDCdV2Mli/Yy4uHsjirzZA7Iag J6KA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1746810780; x=1747415580; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=MJlF7D0xpfPjbCPKdrWI6JVGYxuoLTDn/2fP7GBU1es=; b=lkQqDNPdRtSFHlUhL0K3GgzSBV6sxP9AU4dl63FKnzpqWTQ/Q/xG5MmVh8Oi1EJv8S CAOeSFKMiv+fTXdR4ukL0/zR0vFDi9Deb4lRKhCBbdEuLCIxRK+bgd0x06o4tnMzepNv bzks03N47rs68zPRVopI6kPoMPZZvNYy9T9XYyIPKVHpPOExr5Bv4pWgd3pP4nF3slGx wGzrGVzPFAdeyaSkTEjbaUYDTJo5Z7NXOHkwDl+z5hwdqRE2FYIG/Kc98EyKo6MT/+lW rMa6W+Pta73PZDd61b6sxsvNrzTyCAFPefU3d88VcjF6fh4eAMP5uYP3YCMz9tOxpMO4 8Mfw== X-Gm-Message-State: AOJu0YxWdtniVtqpmPC40k/Nb+VfWLzc4JfnF9d6QHIFyDOnfobPpj+9 iqjBlbLk/hDZjURAsPL6CQ0xbOKs/xiEJugj8tNFkWSRierPkxjIZKwkdXkgA1jcCA== X-Gm-Gg: ASbGncvqu88HXoX0eNij3b5UMxuZFO1f8MJTa815sbFmmZUu9JKkuAlBIvLcTtkvgIM 4y2bKG3fumtbuW0j1/tBAf/3Oa68/4rzF1xfgBBG+RfUp5Qu6gEiCCFkibrZ7vh32ErE0r86NGd +tp64jtDD9XIp1ffCyh/zDC5yXsdkofGciLyyEDm2vX2tDSuoMc/as7Xs8RSjeVJt5+E27/T/sE QTP7yqgKk9zg7AVVOrXShL5PUbaM/6iQ0/e+IObmxVWmH4gN3OmvqkDJqv6yzj6pEq0b1SZr97V QzOpuxVm1YrlW5cANhooXxZtVFhQjDCQHoh1EHhFTwqIASaZAzsS4jtFcjLOOldzmq6fkMfcaGC 4Zbrgufqa9t43OA== X-Google-Smtp-Source: AGHT+IEScecgO/eEtwmbTIv1x+zPfEh2Tt7GB32rZFyBDI5mDDf4tmRJWm6gq6p9fPZGHfe42a3BnQ== X-Received: by 2002:a05:6402:5241:b0:5fb:3ca1:fb3c with SMTP id 4fb4d7f45d1cf-5fca07ed5e9mr3968826a12.27.1746810779425; Fri, 09 May 2025 10:12:59 -0700 (PDT) From: Roman Bogorodskiy To: devel@lists.libvirt.org Subject: [PATCH 2/5] bhyve: generate NVRAM bhyve arguments Date: Fri, 9 May 2025 19:11:48 +0200 Message-ID: <20250509171151.31305-3-bogorodskiy@gmail.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250509171151.31305-1-bogorodskiy@gmail.com> References: <20250509171151.31305-1-bogorodskiy@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Message-ID-Hash: L3JHA2IXZZ4JBTS5ENTDMJAJX42XV5PE X-Message-ID-Hash: L3JHA2IXZZ4JBTS5ENTDMJAJX42XV5PE X-MailFrom: bogorodskiy@gmail.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-config-1; header-match-config-2; header-match-config-3; header-match-devel.lists.libvirt.org-0; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; suspicious-header CC: Roman Bogorodskiy X-Mailman-Version: 3.2.2 Precedence: list List-Id: Development discussions about the libvirt library & tools Archived-At: List-Archive: List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1746810860176019000 Content-Type: text/plain; charset="utf-8" Currently, bhyve bootrom specification looks like this: bhyve ... -l bootrom,/path/to/firmware.fd In addition to that, it supports specifying the VARS files using: -l bootrom,/path/to/firmware.fd,/path/to/my_domain_VARS.fd Update virBhyveProcessBuildBhyveCmd() to include the VARS file if NVRAM is specified in the domain XML. Additionally, support copying this file from the specified template. To do that, introduce the bhyveProcessPrepareHost() and related helpers. They are currently not doing anything but NVRAM preparations, but should be useful for other host-side related tasks in the future. Signed-off-by: Roman Bogorodskiy --- src/bhyve/bhyve_command.c | 8 ++- src/bhyve/bhyve_process.c | 132 ++++++++++++++++++++++++++++++++++++++ src/bhyve/bhyve_process.h | 8 +++ 3 files changed, 146 insertions(+), 2 deletions(-) diff --git a/src/bhyve/bhyve_command.c b/src/bhyve/bhyve_command.c index 44c66ea147..cd1ccf61f3 100644 --- a/src/bhyve/bhyve_command.c +++ b/src/bhyve/bhyve_command.c @@ -808,8 +808,12 @@ virBhyveProcessBuildBhyveCmd(struct _bhyveConn *driver= , virDomainDef *def, if (def->os.bootloader =3D=3D NULL && def->os.loader) { if ((bhyveDriverGetBhyveCaps(driver) & BHYVE_CAP_LPC_BOOTROM)) { - virCommandAddArg(cmd, "-l"); - virCommandAddArgFormat(cmd, "bootrom,%s", def->os.loader->path= ); + g_auto(virBuffer) buf =3D VIR_BUFFER_INITIALIZER; + virBufferAsprintf(&buf, "bootrom,%s", def->os.loader->path); + if (def->os.loader->nvram && def->os.loader->nvram->path) + virBufferAsprintf(&buf, ",%s", def->os.loader->nvram->path= ); + + virCommandAddArgList(cmd, "-l", virBufferContentAndReset(&buf)= , NULL); } else { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("Installed bhyve binary does not support UEFI= loader")); diff --git a/src/bhyve/bhyve_process.c b/src/bhyve/bhyve_process.c index a17994e2a0..5e77a9c4d6 100644 --- a/src/bhyve/bhyve_process.c +++ b/src/bhyve/bhyve_process.c @@ -1,6 +1,7 @@ /* * bhyve_process.c: bhyve process management * + * Copyright (C) 2006-2016 Red Hat, Inc. * Copyright (C) 2014 Roman Bogorodskiy * Copyright (C) 2025 The FreeBSD Foundation * @@ -275,6 +276,134 @@ bhyveProcessPrepareDomain(bhyveConn *driver, return 0; } =20 + +struct bhyvePrepareNVRAMHelperData { + int srcFD; + const char *srcPath; +}; + + +static int +bhyvePrepareNVRAMHelper(int dstFD, + const char *dstPath, + const void *opaque) +{ + const struct bhyvePrepareNVRAMHelperData *data =3D opaque; + ssize_t r; + + do { + char buf[1024]; + + if ((r =3D saferead(data->srcFD, buf, sizeof(buf))) < 0) { + virReportSystemError(errno, + _("Unable to read from file '%1$s'"), + data->srcPath); + return -2; + } + + if (safewrite(dstFD, buf, r) < 0) { + virReportSystemError(errno, + _("Unable to write to file '%1$s'"), + dstPath); + return -1; + } + } while (r); + + return 0; +} + + +static int +bhyvePrepareNVRAMFile(bhyveConn *driver G_GNUC_UNUSED, + virDomainLoaderDef *loader) +{ + VIR_AUTOCLOSE srcFD =3D -1; + struct bhyvePrepareNVRAMHelperData data; + + if (virFileExists(loader->nvram->path)) + return 0; + + if (!loader->nvramTemplate) { + virReportError(VIR_ERR_OPERATION_FAILED, + _("unable to find any master var store for loader: = %1$s"), + loader->path); + return -1; + } + + /* If 'nvramTemplateFormat' is empty it means that it's a user-provided + * template which we couldn't verify. Assume the user knows what they'= re doing */ + if (loader->nvramTemplateFormat !=3D VIR_STORAGE_FILE_NONE && + loader->nvram->format !=3D loader->nvramTemplateFormat) { + virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s", + _("conversion of the nvram template to another targ= et format is not supported")); + return -1; + } + + if ((srcFD =3D virFileOpenAs(loader->nvramTemplate, O_RDONLY, + 0, -1, -1, 0)) < 0) { + virReportSystemError(-srcFD, + _("Failed to open file '%1$s'"), + loader->nvramTemplate); + return -1; + } + + data.srcFD =3D srcFD; + data.srcPath =3D loader->nvramTemplate; + + if (virFileRewrite(loader->nvram->path, + S_IRUSR | S_IWUSR, + 0, 0, + bhyvePrepareNVRAMHelper, + &data) < 0) { + return -1; + } + + return 0; +} + + +int +bhyvePrepareNVRAM(bhyveConn *driver, + virDomainDef *def) +{ + virDomainLoaderDef *loader =3D def->os.loader; + + if (!loader || !loader->nvram) + return 0; + + VIR_DEBUG("nvram=3D'%s'", NULLSTR(loader->nvram->path)); + + switch (virStorageSourceGetActualType(loader->nvram)) { + case VIR_STORAGE_TYPE_FILE: + return bhyvePrepareNVRAMFile(driver, loader); + case VIR_STORAGE_TYPE_BLOCK: + case VIR_STORAGE_TYPE_DIR: + case VIR_STORAGE_TYPE_NETWORK: + case VIR_STORAGE_TYPE_VOLUME: + case VIR_STORAGE_TYPE_NVME: + case VIR_STORAGE_TYPE_VHOST_USER: + case VIR_STORAGE_TYPE_VHOST_VDPA: + case VIR_STORAGE_TYPE_LAST: + case VIR_STORAGE_TYPE_NONE: + break; + } + + return 0; +} + +int +bhyveProcessPrepareHost(bhyveConn *driver, + virDomainDef *def, + unsigned int flags) +{ + virCheckFlags(0, -1); + + if (bhyvePrepareNVRAM(driver, def) < 0) + return -1; + + return 0; +} + int virBhyveProcessStart(bhyveConn *driver, virConnectPtr conn, @@ -292,6 +421,9 @@ virBhyveProcessStart(bhyveConn *driver, if (bhyveProcessPrepareDomain(driver, vm, flags) < 0) return -1; =20 + if (bhyveProcessPrepareHost(driver, vm->def, flags) < 0) + return -1; + return virBhyveProcessStartImpl(driver, vm, reason); } =20 diff --git a/src/bhyve/bhyve_process.h b/src/bhyve/bhyve_process.h index e69db41fc2..5e0acc810c 100644 --- a/src/bhyve/bhyve_process.h +++ b/src/bhyve/bhyve_process.h @@ -23,10 +23,18 @@ =20 #include "bhyve_utils.h" =20 +int +bhyvePrepareNVRAM(bhyveConn *driver, + virDomainDef *def); + int bhyveProcessPrepareDomain(bhyveConn *driver, virDomainObj *vm, unsigned int flags); +int +bhyveProcessPrepareHost(bhyveConn *driver, + virDomainDef *def, + unsigned int flags); =20 int virBhyveProcessStart(bhyveConn *driver, virConnectPtr conn, --=20 2.49.0