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 <bogorodskiy@gmail.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
# 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
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;
&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;
g_free(cfg->firmwareDir);
g_free(cfg->libDir);
g_free(cfg->nvramDir);
+
+ g_free(cfg->ubootPath);
}
void
#include "bhyve_domain.h"
#include "bhyve_capabilities.h"
#include "viralloc.h"
+#include "virfile.h"
#include "virlog.h"
#include "virutil.h"
!(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;
}
char *libDir;
char *nvramDir;
+ char *ubootPath;
+
int bhyveloadTimeout;
int bhyveloadTimeoutKill;
};
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 ]
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" }
-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
-timeout \
---foreground \
---verbose \
--k 20s 300s bhyveload \
--m 214 \
--d /tmp/freebsd.img \
-bhyve
+dummy
-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 \
-timeout \
---foreground \
---verbose \
--k 20s 300s bhyveload \
--m 214 \
--d /tmp/freebsd.img \
-bhyve
+dummy
#include <dirent.h>
+#include "configmake.h"
#include "viralloc.h"
+#include "virfile.h"
#include "virstring.h"
#include "virnetdev.h"
#include "virnetdevtap.h"
#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"
{
return testUtilsHostCpusGetDefForArch(arch);
}
+
+bool
+virFileExists(const char *path)
+{
+ init_syms();
+
+ if (STREQ(path, "fakeubootpath/u-boot.bin"))
+ return true;
+
+ return real_virFileExists(path);
+}
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;
VIR_FREE(driver.config->firmwareDir);
VIR_FREE(driver.config->nvramDir);
+ VIR_FREE(driver.config->ubootPath);
driver.config->firmwareDir = g_steal_pointer(&fakefirmwaredir);
driver.config->nvramDir = g_steal_pointer(&fakenvramdir);
+ driver.config->ubootPath = g_steal_pointer(&fakeubootpath);
driver.config->bhyveloadTimeout = 0;
driver.config->bhyveloadTimeoutKill = 0;
<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'/>
<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'/>
#ifdef WITH_BHYVE
# include "bhyve/bhyve_capabilities.h"
+# include "bhyve/bhyve_conf.h"
# include "bhyve/bhyve_domain.h"
# include "bhyve/bhyve_utils.h"
static int
mymain(void)
{
+ g_autofree char *fakeubootpath = g_strdup("fakeubootpath/u-boot.bin");
int ret = 0;
if ((driver.caps = virBhyveCapsBuild()) == NULL)
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)}; \