diff --git a/src/bhyve/bhyve_command.c b/src/bhyve/bhyve_command.c index e7131625c9bf2cfe9af99715c712b250583f4dd1..4508009209b634c07e7604a2bcceadca2b7f38d6 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 f4ccef32bfe26bba48721626ceed35cddfa652e0..759825c28b67d8f2b2c9f1ed3ac051ae323f8dff 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, "", + 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, "", 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 9d809767620ed3ac0eb6d0405df76f4f2839b500..a97e300ff74125aeb1ad59446ea70c3111c66c92 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);