Bhyve on arm64 does not have the bhyveload(8) tool. That means that it cannot be used as a default if the loader is not configured for the domain.
To prevent users from getting unusable configurations, handle loader configuration on arm64 like that: - if loader is specified in the domain XML, just use it - if not specified, try to check whether the default uboot loader is available on the system. In case it is, set is as the loader, otherwise fail with the error. Additionally, the loader could be configured in bhyve.conf. By default, it uses the loader installed by the sysutils/u-boot-bhyve-arm64 port or a corresponding package. Signed-off-by: Roman Bogorodskiy <[email protected]> Reviewed-by: Michal Privoznik <[email protected]> --- src/bhyve/bhyve.conf | 5 ++++ src/bhyve/bhyve_conf.c | 8 +++++++ src/bhyve/bhyve_domain.c | 23 +++++++++++++++++++ src/bhyve/bhyve_utils.h | 2 ++ src/bhyve/libvirtd_bhyve.aug | 3 ++- src/bhyve/test_libvirtd_bhyve.aug.in | 1 + .../aarch64/bhyvexml2argv-base.args | 1 + .../aarch64/bhyvexml2argv-base.ldargs | 8 +------ .../aarch64/bhyvexml2argv-console.args | 1 + .../aarch64/bhyvexml2argv-console.ldargs | 8 +------ tests/bhyvexml2argvmock.c | 20 +++++++++++++++- tests/bhyvexml2argvtest.c | 2 ++ .../aarch64/bhyvexml2xmlout-base.xml | 1 + .../aarch64/bhyvexml2xmlout-console.xml | 1 + tests/bhyvexml2xmltest.c | 7 ++++++ 15 files changed, 75 insertions(+), 16 deletions(-) diff --git a/src/bhyve/bhyve.conf b/src/bhyve/bhyve.conf index dc8d3d8fd8..a845937d87 100644 --- a/src/bhyve/bhyve.conf +++ b/src/bhyve/bhyve.conf @@ -6,6 +6,11 @@ # to the directory that sysutils/bhyve-firmware installs files into. #firmware_dir = "/usr/local/share/uefi-firmware" +# Path to the U-Boot loader for the arm64 guests. +# By default it's pointing to the loader installed +# by the sysutils/u-boot-bhyve-arm64 port +#uboot_path = "/usr/local/share/u-boot/u-boot-bhyve-arm64/u-boot.bin" + # Set timeout for the bhyveload(8) command. This might be necessary # because in case of errors bhyveload(8) drops to an interactive # loader and hangs indefinitely. These timeout values are passed diff --git a/src/bhyve/bhyve_conf.c b/src/bhyve/bhyve_conf.c index 182e00ee1d..f9a657f402 100644 --- a/src/bhyve/bhyve_conf.c +++ b/src/bhyve/bhyve_conf.c @@ -61,6 +61,8 @@ virBhyveDriverConfigNew(void) cfg->libDir = g_strdup_printf("%s/lib/libvirt/bhyve", LOCALSTATEDIR); cfg->nvramDir = g_strdup_printf("%s/nvram", cfg->libDir); + cfg->ubootPath = g_strdup(DATADIR "/u-boot/u-boot-bhyve-arm64/u-boot.bin"); + cfg->bhyveloadTimeout = 300; cfg->bhyveloadTimeoutKill = 15; @@ -85,6 +87,10 @@ virBhyveLoadDriverConfig(struct _virBhyveDriverConfig *cfg, &cfg->firmwareDir) < 0) return -1; + if (virConfGetValueString(conf, "uboot_path", + &cfg->ubootPath) < 0) + return -1; + if (virConfGetValueInt(conf, "bhyveload_timeout", &cfg->bhyveloadTimeout) < 0) return -1; @@ -111,6 +117,8 @@ virBhyveDriverConfigDispose(void *obj) g_free(cfg->firmwareDir); g_free(cfg->libDir); g_free(cfg->nvramDir); + + g_free(cfg->ubootPath); } void diff --git a/src/bhyve/bhyve_domain.c b/src/bhyve/bhyve_domain.c index df0a008ecd..8fc9733756 100644 --- a/src/bhyve/bhyve_domain.c +++ b/src/bhyve/bhyve_domain.c @@ -27,6 +27,7 @@ #include "bhyve_domain.h" #include "bhyve_capabilities.h" #include "viralloc.h" +#include "virfile.h" #include "virlog.h" #include "virutil.h" @@ -112,6 +113,28 @@ bhyveDomainDefPostParse(virDomainDef *def, !(bhyveDriverGetBhyveCaps(driver) & BHYVE_CAP_RTC_UTC)) def->clock.offset = VIR_DOMAIN_CLOCK_OFFSET_LOCALTIME; + /* bhyve/arm64 does not provide the bhyveload(8) tool, + * so if the loader is not specified and we cannot fall back to the + * default one, then this results in an unusable configuration. */ + if (ARCH_IS_ARM(def->os.arch)) { + if (def->os.loader == NULL) { + g_autoptr(virBhyveDriverConfig) cfg = virBhyveDriverGetConfig(driver); + char *uboot_path = cfg->ubootPath; + + if (virFileExists(uboot_path)) { + def->os.loader = virDomainLoaderDefNew(); + def->os.loader->path = g_strdup(uboot_path); + def->os.loader->readonly = true; + def->os.loader->type = VIR_DOMAIN_LOADER_TYPE_PFLASH; + } else { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("loader is not specified and the default loader (%1$s) not found"), + uboot_path); + return -1; + } + } + } + return 0; } diff --git a/src/bhyve/bhyve_utils.h b/src/bhyve/bhyve_utils.h index 8ed1fa5509..19369047fe 100644 --- a/src/bhyve/bhyve_utils.h +++ b/src/bhyve/bhyve_utils.h @@ -42,6 +42,8 @@ struct _virBhyveDriverConfig { char *libDir; char *nvramDir; + char *ubootPath; + int bhyveloadTimeout; int bhyveloadTimeoutKill; }; diff --git a/src/bhyve/libvirtd_bhyve.aug b/src/bhyve/libvirtd_bhyve.aug index 0fd74d4bb3..00e0db0285 100644 --- a/src/bhyve/libvirtd_bhyve.aug +++ b/src/bhyve/libvirtd_bhyve.aug @@ -25,9 +25,10 @@ module Libvirtd_bhyve = let log_entry = str_entry "firmware_dir" let bhyveload_timeout = int_entry "bhyveload_timeout" let bhyveload_timeout_kill = int_entry "bhyveload_timeout_kill" + let uboot_path = str_entry "uboot_path" (* Each entry in the config is one of the following three ... *) - let entry = log_entry | bhyveload_timeout | bhyveload_timeout_kill + let entry = log_entry | bhyveload_timeout | bhyveload_timeout_kill | uboot_path let comment = [ label "#comment" . del /#[ \t]*/ "# " . store /([^ \t\n][^\n]*)?/ . del /\n/ "\n" ] let empty = [ label "#empty" . eol ] diff --git a/src/bhyve/test_libvirtd_bhyve.aug.in b/src/bhyve/test_libvirtd_bhyve.aug.in index 391648e71f..371f11ef82 100644 --- a/src/bhyve/test_libvirtd_bhyve.aug.in +++ b/src/bhyve/test_libvirtd_bhyve.aug.in @@ -3,5 +3,6 @@ module Test_libvirtd_bhyve = test Libvirtd_bhyve.lns get conf = { "firmware_dir" = "/usr/local/share/uefi-firmware" } +{ "uboot_path" = "/usr/local/share/u-boot/u-boot-bhyve-arm64/u-boot.bin" } { "bhyveload_timeout" = "300" } { "bhyveload_timeout_kill" = "15" } diff --git a/tests/bhyvexml2argvdata/aarch64/bhyvexml2argv-base.args b/tests/bhyvexml2argvdata/aarch64/bhyvexml2argv-base.args index aef3ebd017..37292aa3fe 100644 --- a/tests/bhyvexml2argvdata/aarch64/bhyvexml2argv-base.args +++ b/tests/bhyvexml2argvdata/aarch64/bhyvexml2argv-base.args @@ -2,6 +2,7 @@ bhyve \ -c 1 \ -m 214 \ -s 0:0,hostbridge \ +-o bootrom=fakeubootpath/u-boot.bin \ -s 3:0,virtio-net,faketapdev,mac=52:54:00:b9:94:02 \ -s 2:0,virtio-blk,/tmp/freebsd.img \ bhyve diff --git a/tests/bhyvexml2argvdata/aarch64/bhyvexml2argv-base.ldargs b/tests/bhyvexml2argvdata/aarch64/bhyvexml2argv-base.ldargs index 264ae48441..421376db9e 100644 --- a/tests/bhyvexml2argvdata/aarch64/bhyvexml2argv-base.ldargs +++ b/tests/bhyvexml2argvdata/aarch64/bhyvexml2argv-base.ldargs @@ -1,7 +1 @@ -timeout \ ---foreground \ ---verbose \ --k 20s 300s bhyveload \ --m 214 \ --d /tmp/freebsd.img \ -bhyve +dummy diff --git a/tests/bhyvexml2argvdata/aarch64/bhyvexml2argv-console.args b/tests/bhyvexml2argvdata/aarch64/bhyvexml2argv-console.args index 4a031afb71..afd5f5d7b2 100644 --- a/tests/bhyvexml2argvdata/aarch64/bhyvexml2argv-console.args +++ b/tests/bhyvexml2argvdata/aarch64/bhyvexml2argv-console.args @@ -2,6 +2,7 @@ bhyve \ -c 1 \ -m 214 \ -s 0:0,hostbridge \ +-o bootrom=fakeubootpath/u-boot.bin \ -s 3:0,virtio-net,faketapdev,mac=52:54:00:b9:94:02 \ -s 2:0,virtio-blk,/tmp/freebsd.img \ -o console=/dev/nmdm0A \ diff --git a/tests/bhyvexml2argvdata/aarch64/bhyvexml2argv-console.ldargs b/tests/bhyvexml2argvdata/aarch64/bhyvexml2argv-console.ldargs index 264ae48441..421376db9e 100644 --- a/tests/bhyvexml2argvdata/aarch64/bhyvexml2argv-console.ldargs +++ b/tests/bhyvexml2argvdata/aarch64/bhyvexml2argv-console.ldargs @@ -1,7 +1 @@ -timeout \ ---foreground \ ---verbose \ --k 20s 300s bhyveload \ --m 214 \ --d /tmp/freebsd.img \ -bhyve +dummy diff --git a/tests/bhyvexml2argvmock.c b/tests/bhyvexml2argvmock.c index fe76564d51..191d6bdaf5 100644 --- a/tests/bhyvexml2argvmock.c +++ b/tests/bhyvexml2argvmock.c @@ -2,7 +2,9 @@ #include <dirent.h> +#include "configmake.h" #include "viralloc.h" +#include "virfile.h" #include "virstring.h" #include "virnetdev.h" #include "virnetdevtap.h" @@ -12,11 +14,16 @@ #define VIR_FROM_THIS VIR_FROM_BHYVE static DIR * (*real_opendir)(const char *name); +static bool (*real_virFileExists)(const char *path); static void init_syms(void) { - VIR_MOCK_REAL_INIT(opendir); + if (!real_opendir) + VIR_MOCK_REAL_INIT(opendir); + + if (!real_virFileExists) + VIR_MOCK_REAL_INIT(virFileExists); } #define FAKEFIRMWAREDIR abs_srcdir "/bhyvefirmwaredata/three_firmwares" @@ -89,3 +96,14 @@ int bind(int sockfd G_GNUC_UNUSED, { return 0; } + +bool +virFileExists(const char *path) +{ + init_syms(); + + if (STREQ(path, "fakeubootpath/u-boot.bin")) + return true; + + return real_virFileExists(path); +} diff --git a/tests/bhyvexml2argvtest.c b/tests/bhyvexml2argvtest.c index c7c18c3690..42c14b6ab3 100644 --- a/tests/bhyvexml2argvtest.c +++ b/tests/bhyvexml2argvtest.c @@ -151,6 +151,7 @@ mymain(void) g_autofree char *fakefirmwaredir = g_strdup("fakefirmwaredir"); g_autofree char *fakenvramdir = g_strdup("fakenvramdir"); g_autofree char *fakefirmwareemptydir = g_strdup("fakefirmwareemptydir"); + g_autofree char *fakeubootpath = g_strdup("fakeubootpath/u-boot.bin"); if ((driver.caps = virBhyveCapsBuild()) == NULL) return EXIT_FAILURE; @@ -166,6 +167,7 @@ mymain(void) driver.config->firmwareDir = fakefirmwaredir; driver.config->nvramDir = fakenvramdir; + driver.config->ubootPath = fakeubootpath; driver.config->bhyveloadTimeout = 0; driver.config->bhyveloadTimeoutKill = 0; diff --git a/tests/bhyvexml2xmloutdata/aarch64/bhyvexml2xmlout-base.xml b/tests/bhyvexml2xmloutdata/aarch64/bhyvexml2xmlout-base.xml index ee72370047..b2d88789c8 100644 --- a/tests/bhyvexml2xmloutdata/aarch64/bhyvexml2xmlout-base.xml +++ b/tests/bhyvexml2xmloutdata/aarch64/bhyvexml2xmlout-base.xml @@ -6,6 +6,7 @@ <vcpu placement='static'>1</vcpu> <os> <type arch='aarch64'>hvm</type> + <loader readonly='yes' type='pflash'>fakeubootpath/u-boot.bin</loader> <boot dev='hd'/> </os> <clock offset='localtime'/> diff --git a/tests/bhyvexml2xmloutdata/aarch64/bhyvexml2xmlout-console.xml b/tests/bhyvexml2xmloutdata/aarch64/bhyvexml2xmlout-console.xml index d43ce8fd6f..741570a5b5 100644 --- a/tests/bhyvexml2xmloutdata/aarch64/bhyvexml2xmlout-console.xml +++ b/tests/bhyvexml2xmloutdata/aarch64/bhyvexml2xmlout-console.xml @@ -6,6 +6,7 @@ <vcpu placement='static'>1</vcpu> <os> <type arch='aarch64'>hvm</type> + <loader readonly='yes' type='pflash'>fakeubootpath/u-boot.bin</loader> <boot dev='hd'/> </os> <clock offset='localtime'/> diff --git a/tests/bhyvexml2xmltest.c b/tests/bhyvexml2xmltest.c index 5df1f2b6ba..1e32f163d9 100644 --- a/tests/bhyvexml2xmltest.c +++ b/tests/bhyvexml2xmltest.c @@ -5,6 +5,7 @@ #ifdef WITH_BHYVE # include "bhyve/bhyve_capabilities.h" +# include "bhyve/bhyve_conf.h" # include "bhyve/bhyve_domain.h" # include "bhyve/bhyve_utils.h" @@ -55,6 +56,7 @@ testCompareXMLToXMLHelper(const void *data) static int mymain(void) { + g_autofree char *fakeubootpath = g_strdup("fakeubootpath/u-boot.bin"); int ret = 0; if ((driver.caps = virBhyveCapsBuild()) == NULL) @@ -63,6 +65,11 @@ mymain(void) if ((driver.xmlopt = virBhyveDriverCreateXMLConf(&driver)) == NULL) return EXIT_FAILURE; + if (!(driver.config = virBhyveDriverConfigNew())) + return EXIT_FAILURE; + + driver.config->ubootPath = fakeubootpath; + # define DO_TEST_FULL(name, flags) \ do { \ const struct testInfo info = {name, (flags)}; \ -- 2.52.0
