提交 d3b9a611 编写于 作者: F Fabian Freyer 提交者: Roman Bogorodskiy

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: NRoman Bogorodskiy <bogorodskiy@gmail.com>
上级 b6ae1295
...@@ -163,7 +163,6 @@ bhyveBuildConsoleArgStr(const virDomainDef *def, virCommandPtr cmd) ...@@ -163,7 +163,6 @@ bhyveBuildConsoleArgStr(const virDomainDef *def, virCommandPtr cmd)
return -1; return -1;
} }
virCommandAddArgList(cmd, "-s", "1,lpc", NULL);
virCommandAddArg(cmd, "-l"); virCommandAddArg(cmd, "-l");
virCommandAddArgFormat(cmd, "com%d,%s", virCommandAddArgFormat(cmd, "com%d,%s",
chr->target.port + 1, chr->source->data.file.path); chr->target.port + 1, chr->source->data.file.path);
...@@ -283,6 +282,14 @@ bhyveBuildVirtIODiskArgStr(const virDomainDef *def ATTRIBUTE_UNUSED, ...@@ -283,6 +282,14 @@ bhyveBuildVirtIODiskArgStr(const virDomainDef *def ATTRIBUTE_UNUSED,
return 0; return 0;
} }
static int
bhyveBuildLPCArgStr(const virDomainDef *def ATTRIBUTE_UNUSED,
virCommandPtr cmd)
{
virCommandAddArgList(cmd, "-s", "1,lpc", NULL);
return 0;
}
virCommandPtr virCommandPtr
virBhyveProcessBuildBhyveCmd(virConnectPtr conn, virBhyveProcessBuildBhyveCmd(virConnectPtr conn,
virDomainDefPtr def, bool dryRun) virDomainDefPtr def, bool dryRun)
...@@ -296,6 +303,7 @@ virBhyveProcessBuildBhyveCmd(virConnectPtr conn, ...@@ -296,6 +303,7 @@ virBhyveProcessBuildBhyveCmd(virConnectPtr conn,
* vm0 * vm0
*/ */
size_t i; size_t i;
bool add_lpc = false;
virCommandPtr cmd = virCommandNew(BHYVE); virCommandPtr cmd = virCommandNew(BHYVE);
...@@ -350,6 +358,21 @@ virBhyveProcessBuildBhyveCmd(virConnectPtr conn, ...@@ -350,6 +358,21 @@ virBhyveProcessBuildBhyveCmd(virConnectPtr conn,
virCommandAddArg(cmd, "-P"); /* vmexit from guest on pause */ virCommandAddArg(cmd, "-P"); /* vmexit from guest on pause */
virCommandAddArgList(cmd, "-s", "0:0,hostbridge", NULL); 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 */ /* Devices */
for (i = 0; i < def->ncontrollers; i++) { for (i = 0; i < def->ncontrollers; i++) {
virDomainControllerDefPtr controller = def->controllers[i]; virDomainControllerDefPtr controller = def->controllers[i];
...@@ -389,8 +412,13 @@ virBhyveProcessBuildBhyveCmd(virConnectPtr conn, ...@@ -389,8 +412,13 @@ virBhyveProcessBuildBhyveCmd(virConnectPtr conn,
goto error; goto error;
} }
} }
if (add_lpc || def->nserials)
bhyveBuildLPCArgStr(def, cmd);
if (bhyveBuildConsoleArgStr(def, cmd) < 0) if (bhyveBuildConsoleArgStr(def, cmd) < 0)
goto error; goto error;
virCommandAddArg(cmd, def->name); virCommandAddArg(cmd, def->name);
return cmd; return cmd;
......
...@@ -734,15 +734,34 @@ bhyveConnectDomainXMLToNative(virConnectPtr conn, ...@@ -734,15 +734,34 @@ bhyveConnectDomainXMLToNative(virConnectPtr conn,
if (bhyveDomainAssignAddresses(def, NULL) < 0) if (bhyveDomainAssignAddresses(def, NULL) < 0)
goto cleanup; 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))) NULL)))
goto cleanup; goto cleanup;
virBufferAdd(&buf, virCommandToString(loadcmd), -1);
virBufferAddChar(&buf, '\n');
}
if (!(cmd = virBhyveProcessBuildBhyveCmd(conn, def, true))) if (!(cmd = virBhyveProcessBuildBhyveCmd(conn, def, true)))
goto cleanup; goto cleanup;
virBufferAdd(&buf, virCommandToString(loadcmd), -1);
virBufferAddChar(&buf, '\n');
virBufferAdd(&buf, virCommandToString(cmd), -1); virBufferAdd(&buf, virCommandToString(cmd), -1);
if (virBufferCheckError(&buf) < 0) if (virBufferCheckError(&buf) < 0)
......
...@@ -165,38 +165,41 @@ virBhyveProcessStart(virConnectPtr conn, ...@@ -165,38 +165,41 @@ virBhyveProcessStart(virConnectPtr conn,
virCommandSetPidFile(cmd, privconn->pidfile); virCommandSetPidFile(cmd, privconn->pidfile);
virCommandDaemonize(cmd); virCommandDaemonize(cmd);
/* Now bhyve command is constructed, meaning the if (vm->def->os.loader == NULL) {
* domain is ready to be started, so we can build /* Now bhyve command is constructed, meaning the
* and execute bhyveload command */ * domain is ready to be started, so we can build
rc = virBhyveFormatDevMapFile(vm->def->name, &devmap_file); * and execute bhyveload command */
if (rc < 0)
goto cleanup;
if (!(load_cmd = virBhyveProcessBuildLoadCmd(conn, vm->def, devmap_file, rc = virBhyveFormatDevMapFile(vm->def->name, &devmap_file);
&devicemap))) if (rc < 0)
goto cleanup; goto cleanup;
virCommandSetOutputFD(load_cmd, &logfd);
virCommandSetErrorFD(load_cmd, &logfd);
if (devicemap != NULL) { if (!(load_cmd = virBhyveProcessBuildLoadCmd(conn, vm->def, devmap_file,
rc = virFileWriteStr(devmap_file, devicemap, 0644); &devicemap)))
if (rc) {
virReportSystemError(errno,
_("Cannot write device.map '%s'"),
devmap_file);
goto cleanup; 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 */ /* Log generated command line */
virCommandWriteArgLog(load_cmd, logfd); virCommandWriteArgLog(load_cmd, logfd);
if ((pos = lseek(logfd, 0, SEEK_END)) < 0) if ((pos = lseek(logfd, 0, SEEK_END)) < 0)
VIR_WARN("Unable to seek to end of logfile: %s", VIR_WARN("Unable to seek to end of logfile: %s",
virStrerror(errno, ebuf, sizeof(ebuf))); virStrerror(errno, ebuf, sizeof(ebuf)));
VIR_DEBUG("Loading domain '%s'", vm->def->name); VIR_DEBUG("Loading domain '%s'", vm->def->name);
if (virCommandRun(load_cmd, NULL) < 0) if (virCommandRun(load_cmd, NULL) < 0)
goto cleanup; goto cleanup;
}
/* Now we can start the domain */ /* Now we can start the domain */
VIR_DEBUG("Starting domain '%s'", vm->def->name); VIR_DEBUG("Starting domain '%s'", vm->def->name);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册