mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-30 16:35:24 +00:00
bhyve: add support for booting from UEFI
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@gmail.com>
This commit is contained in:
parent
b6ae129534
commit
d3b9a61172
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -165,39 +165,42 @@ 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);
|
||||
|
||||
if (devicemap != NULL) {
|
||||
rc = virFileWriteStr(devmap_file, devicemap, 0644);
|
||||
if (rc) {
|
||||
virReportSystemError(errno,
|
||||
_("Cannot write device.map '%s'"),
|
||||
devmap_file);
|
||||
rc = virBhyveFormatDevMapFile(vm->def->name, &devmap_file);
|
||||
if (rc < 0)
|
||||
goto cleanup;
|
||||
|
||||
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)));
|
||||
|
||||
VIR_DEBUG("Loading domain '%s'", vm->def->name);
|
||||
if (virCommandRun(load_cmd, NULL) < 0)
|
||||
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)));
|
||||
|
||||
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);
|
||||
if (virCommandRun(cmd, NULL) < 0)
|
||||
|
Loading…
x
Reference in New Issue
Block a user