Implement domain reboot using the guest agent. Implementation is very similar to the domain shutdown added earlier. Also, change the VIR_DOMAIN_REBOOT_ACPI_POWER_BTN flag to VIR_DOMAIN_REBOOT_SIGNAL. Even though bhyve emulates the ACPI button, it's triggered by sending a signal to the bhyve process, so VIR_DOMAIN_REBOOT_SIGNAL looks like a more accurate description of communication between libvirt and bhyve. Signed-off-by: Roman Bogorodskiy <bogorodskiy@gmail.com> --- src/bhyve/bhyve_driver.c | 38 +++++++++++++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/src/bhyve/bhyve_driver.c b/src/bhyve/bhyve_driver.c index 4b28c698e7..45e8aad5b5 100644 --- a/src/bhyve/bhyve_driver.c +++ b/src/bhyve/bhyve_driver.c @@ -1085,6 +1085,12 @@ bhyveDomainShutdownFlagsAgent(virDomainObj *vm, return ret; } +static int +bhyveDomainRebootAgent(virDomainObj *vm, bool isReboot, bool reportError) +{ + return bhyveDomainShutdownFlagsAgent(vm, isReboot, reportError); +} + static int bhyveDomainShutdownFlags(virDomainPtr dom, unsigned int flags) { @@ -1160,10 +1166,15 @@ bhyveDomainReboot(virDomainPtr dom, unsigned int flags) { virConnectPtr conn = dom->conn; virDomainObj *vm; - bool isReboot = true; + bhyveDomainObjPrivate *priv; int ret = -1; + bool isReboot = true; + bool useAgent = false; + bool agentRequested, signalRequested; + bool agentForced; - virCheckFlags(VIR_DOMAIN_REBOOT_ACPI_POWER_BTN, -1); + virCheckFlags(VIR_DOMAIN_REBOOT_SIGNAL | + VIR_DOMAIN_REBOOT_GUEST_AGENT, -1); if (!(vm = bhyveDomObjFromDomain(dom))) goto cleanup; @@ -1174,13 +1185,34 @@ bhyveDomainReboot(virDomainPtr dom, unsigned int flags) VIR_INFO("Domain on_reboot setting overridden, shutting down"); } + priv = vm->privateData; + agentRequested = flags & VIR_DOMAIN_REBOOT_GUEST_AGENT; + signalRequested = flags & VIR_DOMAIN_REBOOT_SIGNAL; + + /* Prefer agent unless we were requested to not to. */ + if (agentRequested || !flags) + useAgent = true; + if (virDomainRebootEnsureACL(conn, vm->def, flags) < 0) goto cleanup; if (virDomainObjCheckActive(vm) < 0) goto cleanup; - ret = bhyveDomainShutdownSignal(vm, isReboot); + agentForced = agentRequested && !signalRequested; + if (useAgent) { + ret = bhyveDomainRebootAgent(vm, isReboot, agentForced); + if (((ret < 0) || (priv->agent != NULL)) && agentForced) + goto cleanup; + } + + /* If we are not enforced to use just an agent, try signal + * reboot as well in case agent did not succeed. + */ + if (!useAgent || (((ret < 0) || + (priv->agent != NULL)) && (signalRequested || !flags))) { + ret = bhyveDomainShutdownSignal(vm, isReboot); + } cleanup: virDomainObjEndAPI(&vm); -- 2.52.0