Signed-off-by: Ryan Moeller <ryan@xxxxxxxxxxxxx> --- src/bhyve/bhyve_driver.c | 30 ++++++++++++++++++++++ src/bhyve/bhyve_monitor.c | 19 +++++++++----- src/bhyve/bhyve_monitor.h | 2 ++ src/bhyve/bhyve_process.c | 52 ++++++++++++++++++++++++++++----------- src/bhyve/bhyve_process.h | 3 +++ 5 files changed, 85 insertions(+), 21 deletions(-) diff --git a/src/bhyve/bhyve_driver.c b/src/bhyve/bhyve_driver.c index 625dc0ec22..05ffc2f050 100644 --- a/src/bhyve/bhyve_driver.c +++ b/src/bhyve/bhyve_driver.c @@ -1013,6 +1013,35 @@ bhyveDomainShutdown(virDomainPtr dom) return bhyveDomainShutdownFlags(dom, 0); } +static int +bhyveDomainReboot(virDomainPtr dom, unsigned int flags) +{ + virConnectPtr conn = dom->conn; + virDomainObjPtr vm; + bhyveDomainObjPrivatePtr priv; + int ret = -1; + + virCheckFlags(VIR_DOMAIN_REBOOT_ACPI_POWER_BTN, -1); + + if (!(vm = bhyveDomObjFromDomain(dom))) + goto cleanup; + + if (virDomainRebootEnsureACL(conn, vm->def, flags) < 0) + goto cleanup; + + if (virDomainObjCheckActive(vm) < 0) + goto cleanup; + + priv = vm->privateData; + bhyveMonitorSetReboot(priv->mon); + + ret = virBhyveProcessShutdown(vm); + + cleanup: + virDomainObjEndAPI(&vm); + return ret; +} + static int bhyveDomainOpenConsole(virDomainPtr dom, const char *dev_name G_GNUC_UNUSED, @@ -1657,6 +1686,7 @@ static virHypervisorDriver bhyveHypervisorDriver = { .domainDestroyFlags = bhyveDomainDestroyFlags, /* 5.6.0 */ .domainShutdown = bhyveDomainShutdown, /* 1.3.3 */ .domainShutdownFlags = bhyveDomainShutdownFlags, /* 5.6.0 */ + .domainReboot = bhyveDomainReboot, /* TBD */ .domainLookupByUUID = bhyveDomainLookupByUUID, /* 1.2.2 */ .domainLookupByName = bhyveDomainLookupByName, /* 1.2.2 */ .domainLookupByID = bhyveDomainLookupByID, /* 1.2.3 */ diff --git a/src/bhyve/bhyve_monitor.c b/src/bhyve/bhyve_monitor.c index a1b1a21a6f..e5cd39a086 100644 --- a/src/bhyve/bhyve_monitor.c +++ b/src/bhyve/bhyve_monitor.c @@ -41,10 +41,11 @@ VIR_LOG_INIT("bhyve.bhyve_monitor"); struct _bhyveMonitor { virObject parent; - int kq; - int watch; bhyveConnPtr driver; virDomainObjPtr vm; + int kq; + int watch; + bool reboot; }; static virClassPtr bhyveMonitorClass; @@ -100,6 +101,12 @@ bhyveMonitorUnregister(bhyveMonitorPtr mon) mon->watch = -1; } +void +bhyveMonitorSetReboot(bhyveMonitorPtr mon) +{ + mon->reboot = true; +} + static void bhyveMonitorIO(int watch, int kq, int events G_GNUC_UNUSED, void *opaque) { @@ -148,11 +155,10 @@ bhyveMonitorIO(int watch, int kq, int events G_GNUC_UNUSED, void *opaque) name, WTERMSIG(status)); virBhyveProcessStop(driver, vm, VIR_DOMAIN_SHUTOFF_CRASHED); } else if (WIFEXITED(status)) { - if (WEXITSTATUS(status) == 0) { + if (WEXITSTATUS(status) == 0 || mon->reboot) { /* 0 - reboot */ - /* TODO: Implementing reboot is a little more complicated. */ - VIR_INFO("Guest %s rebooted; destroying domain.", name); - virBhyveProcessStop(driver, vm, VIR_DOMAIN_SHUTOFF_SHUTDOWN); + VIR_INFO("Guest %s rebooted; restarting domain.", name); + virBhyveProcessRestart(driver, vm); } else if (WEXITSTATUS(status) < 3) { /* 1 - shutdown, 2 - halt, 3 - triple fault. others - error */ VIR_INFO("Guest %s shut itself down; destroying domain.", name); @@ -179,6 +185,7 @@ bhyveMonitorOpenImpl(virDomainObjPtr vm, bhyveConnPtr driver) return NULL; mon->driver = driver; + mon->reboot = false; virObjectRef(vm); mon->vm = vm; diff --git a/src/bhyve/bhyve_monitor.h b/src/bhyve/bhyve_monitor.h index 226866e6d9..175cc87192 100644 --- a/src/bhyve/bhyve_monitor.h +++ b/src/bhyve/bhyve_monitor.h @@ -29,3 +29,5 @@ typedef bhyveMonitor *bhyveMonitorPtr; bhyveMonitorPtr bhyveMonitorOpen(virDomainObjPtr vm, bhyveConnPtr driver); void bhyveMonitorClose(bhyveMonitorPtr mon); + +void bhyveMonitorSetReboot(bhyveMonitorPtr mon); diff --git a/src/bhyve/bhyve_process.c b/src/bhyve/bhyve_process.c index 45162503d4..060018bc70 100644 --- a/src/bhyve/bhyve_process.c +++ b/src/bhyve/bhyve_process.c @@ -110,11 +110,10 @@ bhyveProcessStopHook(virDomainObjPtr vm, virHookBhyveOpType op) VIR_HOOK_SUBOP_END, NULL, NULL, NULL); } -int -virBhyveProcessStart(virConnectPtr conn, - virDomainObjPtr vm, - virDomainRunningReason reason, - unsigned int flags) +static int +virBhyveProcessStartImpl(bhyveConnPtr driver, + virDomainObjPtr vm, + virDomainRunningReason reason) { char *devmap_file = NULL; char *devicemap = NULL; @@ -122,7 +121,6 @@ virBhyveProcessStart(virConnectPtr conn, int logfd = -1; virCommandPtr cmd = NULL; virCommandPtr load_cmd = NULL; - bhyveConnPtr driver = conn->privateData; bhyveDomainObjPrivatePtr priv = vm->privateData; int ret = -1, rc; @@ -154,10 +152,6 @@ virBhyveProcessStart(virConnectPtr conn, if (bhyveDomainAssignAddresses(vm->def, NULL) < 0) goto cleanup; - /* Run an early hook to setup missing devices. */ - if (bhyveProcessStartHook(vm, VIR_HOOK_BHYVE_OP_PREPARE) < 0) - goto cleanup; - /* Call bhyve to start the VM */ if (!(cmd = virBhyveProcessBuildBhyveCmd(driver, vm->def, false))) goto cleanup; @@ -213,11 +207,6 @@ virBhyveProcessStart(virConnectPtr conn, goto cleanup; } - if (flags & VIR_BHYVE_PROCESS_START_AUTODESTROY && - virCloseCallbacksSet(driver->closeCallbacks, vm, - conn, bhyveProcessAutoDestroy) < 0) - goto cleanup; - vm->def->id = vm->pid; virDomainObjSetState(vm, VIR_DOMAIN_RUNNING, reason); priv->mon = bhyveMonitorOpen(vm, driver); @@ -262,6 +251,26 @@ virBhyveProcessStart(virConnectPtr conn, return ret; } +int +virBhyveProcessStart(virConnectPtr conn, + virDomainObjPtr vm, + virDomainRunningReason reason, + unsigned int flags) +{ + bhyveConnPtr driver = conn->privateData; + + /* Run an early hook to setup missing devices. */ + if (bhyveProcessStartHook(vm, VIR_HOOK_BHYVE_OP_PREPARE) < 0) + return -1; + + if (flags & VIR_BHYVE_PROCESS_START_AUTODESTROY && + virCloseCallbacksSet(driver->closeCallbacks, vm, + conn, bhyveProcessAutoDestroy) < 0) + return -1; + + return virBhyveProcessStartImpl(driver, vm, reason); +} + int virBhyveProcessStop(bhyveConnPtr driver, virDomainObjPtr vm, @@ -349,6 +358,19 @@ virBhyveProcessShutdown(virDomainObjPtr vm) return 0; } +int +virBhyveProcessRestart(bhyveConnPtr driver, + virDomainObjPtr vm) +{ + if (virBhyveProcessStop(driver, vm, VIR_DOMAIN_SHUTOFF_SHUTDOWN) < 0) + return -1; + + if (virBhyveProcessStartImpl(driver, vm, VIR_DOMAIN_RUNNING_BOOTED) < 0) + return -1; + + return 0; +} + int virBhyveGetDomainTotalCpuStats(virDomainObjPtr vm, unsigned long long *cpustats) diff --git a/src/bhyve/bhyve_process.h b/src/bhyve/bhyve_process.h index 8419e44faa..d7b4e0bd4e 100644 --- a/src/bhyve/bhyve_process.h +++ b/src/bhyve/bhyve_process.h @@ -32,6 +32,9 @@ int virBhyveProcessStop(bhyveConnPtr driver, virDomainObjPtr vm, virDomainShutoffReason reason); +int virBhyveProcessRestart(bhyveConnPtr driver, + virDomainObjPtr vm); + int virBhyveProcessShutdown(virDomainObjPtr vm); int virBhyveGetDomainTotalCpuStats(virDomainObjPtr vm, -- 2.24.1