From: Fabian Freyer <fabian.freyer@xxxxxxxxxxxxxxxxxxx> Allow to boot using UEFI rather than using an external boot loader such as bhyveload or grub-bhyve. Also, make LPC PCI-ISA bridge handling more flexible as now it's needed not only for serial ports, but for bootrom as well. Signed-off-by: Roman Bogorodskiy <bogorodskiy@xxxxxxxxx> --- src/bhyve/bhyve_command.c | 30 +++++++++++++++++++++++++- src/bhyve/bhyve_driver.c | 27 +++++++++++++++++++---- src/bhyve/bhyve_process.c | 55 +++++++++++++++++++++++++---------------------- 3 files changed, 81 insertions(+), 31 deletions(-) diff --git a/src/bhyve/bhyve_command.c b/src/bhyve/bhyve_command.c index e7131625c..450800920 100644 --- a/src/bhyve/bhyve_command.c +++ b/src/bhyve/bhyve_command.c @@ -163,7 +163,6 @@ bhyveBuildConsoleArgStr(const virDomainDef *def, virCommandPtr cmd) return -1; } - virCommandAddArgList(cmd, "-s", "1,lpc", NULL); virCommandAddArg(cmd, "-l"); virCommandAddArgFormat(cmd, "com%d,%s", chr->target.port + 1, chr->source->data.file.path); @@ -283,6 +282,14 @@ bhyveBuildVirtIODiskArgStr(const virDomainDef *def ATTRIBUTE_UNUSED, return 0; } +static int +bhyveBuildLPCArgStr(const virDomainDef *def ATTRIBUTE_UNUSED, + virCommandPtr cmd) +{ + virCommandAddArgList(cmd, "-s", "1,lpc", NULL); + return 0; +} + virCommandPtr virBhyveProcessBuildBhyveCmd(virConnectPtr conn, virDomainDefPtr def, bool dryRun) @@ -296,6 +303,7 @@ virBhyveProcessBuildBhyveCmd(virConnectPtr conn, * vm0 */ size_t i; + bool add_lpc = false; virCommandPtr cmd = virCommandNew(BHYVE); @@ -350,6 +358,21 @@ virBhyveProcessBuildBhyveCmd(virConnectPtr conn, virCommandAddArg(cmd, "-P"); /* vmexit from guest on pause */ virCommandAddArgList(cmd, "-s", "0:0,hostbridge", NULL); + + if (def->os.bootloader == NULL && + def->os.loader) { + if ((bhyveDriverGetCaps(conn) & BHYVE_CAP_LPC_BOOTROM)) { + virCommandAddArg(cmd, "-l"); + virCommandAddArgFormat(cmd, "bootrom,%s", def->os.loader->path); + add_lpc = true; + } else { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("Installed bhyve binary does not support " + "UEFI loader")); + goto error; + } + } + /* Devices */ for (i = 0; i < def->ncontrollers; i++) { virDomainControllerDefPtr controller = def->controllers[i]; @@ -389,8 +412,13 @@ virBhyveProcessBuildBhyveCmd(virConnectPtr conn, goto error; } } + + if (add_lpc || def->nserials) + bhyveBuildLPCArgStr(def, cmd); + if (bhyveBuildConsoleArgStr(def, cmd) < 0) goto error; + virCommandAddArg(cmd, def->name); return cmd; diff --git a/src/bhyve/bhyve_driver.c b/src/bhyve/bhyve_driver.c index f4ccef32b..0f9961ae0 100644 --- a/src/bhyve/bhyve_driver.c +++ b/src/bhyve/bhyve_driver.c @@ -734,15 +734,34 @@ bhyveConnectDomainXMLToNative(virConnectPtr conn, if (bhyveDomainAssignAddresses(def, NULL) < 0) goto cleanup; - if (!(loadcmd = virBhyveProcessBuildLoadCmd(conn, def, "<device.map>", + if (def->os.bootloader == NULL && + def->os.loader) { + + if ((def->os.loader->readonly != VIR_TRISTATE_BOOL_YES) + || (def->os.loader->type != VIR_DOMAIN_LOADER_TYPE_PFLASH)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("Only read-only pflash is supported.")); + goto cleanup; + } + + if ((bhyveDriverGetCaps(conn) & BHYVE_CAP_LPC_BOOTROM) == 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("Installed bhyve binary does not support " + "bootrom")); + goto cleanup; + } + } else { + if (!(loadcmd = virBhyveProcessBuildLoadCmd(conn, def, "<device.map>", NULL))) - goto cleanup; + goto cleanup; + + virBufferAdd(&buf, virCommandToString(loadcmd), -1); + virBufferAddChar(&buf, '\n'); + } if (!(cmd = virBhyveProcessBuildBhyveCmd(conn, def, true))) goto cleanup; - virBufferAdd(&buf, virCommandToString(loadcmd), -1); - virBufferAddChar(&buf, '\n'); virBufferAdd(&buf, virCommandToString(cmd), -1); if (virBufferCheckError(&buf) < 0) diff --git a/src/bhyve/bhyve_process.c b/src/bhyve/bhyve_process.c index 9d8097676..a97e300ff 100644 --- a/src/bhyve/bhyve_process.c +++ b/src/bhyve/bhyve_process.c @@ -165,38 +165,41 @@ virBhyveProcessStart(virConnectPtr conn, virCommandSetPidFile(cmd, privconn->pidfile); virCommandDaemonize(cmd); - /* Now bhyve command is constructed, meaning the - * domain is ready to be started, so we can build - * and execute bhyveload command */ - rc = virBhyveFormatDevMapFile(vm->def->name, &devmap_file); - if (rc < 0) - goto cleanup; + if (vm->def->os.loader == NULL) { + /* Now bhyve command is constructed, meaning the + * domain is ready to be started, so we can build + * and execute bhyveload command */ - if (!(load_cmd = virBhyveProcessBuildLoadCmd(conn, vm->def, devmap_file, - &devicemap))) - goto cleanup; - virCommandSetOutputFD(load_cmd, &logfd); - virCommandSetErrorFD(load_cmd, &logfd); + rc = virBhyveFormatDevMapFile(vm->def->name, &devmap_file); + if (rc < 0) + goto cleanup; - if (devicemap != NULL) { - rc = virFileWriteStr(devmap_file, devicemap, 0644); - if (rc) { - virReportSystemError(errno, - _("Cannot write device.map '%s'"), - devmap_file); + if (!(load_cmd = virBhyveProcessBuildLoadCmd(conn, vm->def, devmap_file, + &devicemap))) goto cleanup; + virCommandSetOutputFD(load_cmd, &logfd); + virCommandSetErrorFD(load_cmd, &logfd); + + if (devicemap != NULL) { + rc = virFileWriteStr(devmap_file, devicemap, 0644); + if (rc) { + virReportSystemError(errno, + _("Cannot write device.map '%s'"), + devmap_file); + goto cleanup; + } } - } - /* Log generated command line */ - virCommandWriteArgLog(load_cmd, logfd); - if ((pos = lseek(logfd, 0, SEEK_END)) < 0) - VIR_WARN("Unable to seek to end of logfile: %s", - virStrerror(errno, ebuf, sizeof(ebuf))); + /* Log generated command line */ + virCommandWriteArgLog(load_cmd, logfd); + if ((pos = lseek(logfd, 0, SEEK_END)) < 0) + VIR_WARN("Unable to seek to end of logfile: %s", + virStrerror(errno, ebuf, sizeof(ebuf))); - VIR_DEBUG("Loading domain '%s'", vm->def->name); - if (virCommandRun(load_cmd, NULL) < 0) - goto cleanup; + VIR_DEBUG("Loading domain '%s'", vm->def->name); + if (virCommandRun(load_cmd, NULL) < 0) + goto cleanup; + } /* Now we can start the domain */ VIR_DEBUG("Starting domain '%s'", vm->def->name); -- 2.11.0 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list