[PATCH] bhyve: implement reboot using agent

Roman Bogorodskiy posted 1 patch 1 week, 3 days ago
Failed in applying to current master (apply log)
src/bhyve/bhyve_driver.c | 38 +++++++++++++++++++++++++++++++++++---
1 file changed, 35 insertions(+), 3 deletions(-)
[PATCH] bhyve: implement reboot using agent
Posted by Roman Bogorodskiy 1 week, 3 days ago
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
Re: [PATCH] bhyve: implement reboot using agent
Posted by Roman Bogorodskiy 1 week, 3 days ago
  Roman Bogorodskiy wrote:

> 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(-)

Sorry, I messed up with my patch directories and shell globs while
sending this. This patch should be skipped. Patches 1/2 and 2/2 are
valid.

Roman
[PATCH 1/2] bhyve: implement shutdown using agent
Posted by Roman Bogorodskiy 1 week, 3 days ago
Implement shutdown using a guest agent.
Implementation and behaviour is very similar to the one
found in the qemu driver.

The bhyveDomainShutdownFlags() function now supports
the VIR_DOMAIN_SHUTDOWN_SIGNAL and VIR_DOMAIN_SHUTDOWN_GUEST_AGENT.
If flags were not specified, try the agent first, and if it does
not work, proceed with the signal.

As we do not expect a response from the agent shutdown command,
we do not check qemuAgentShutdown()'s return value. Assume that the
command failed if the agent did not receive EOF, thus "priv->agent"
is not NULL.

Signed-off-by: Roman Bogorodskiy <bogorodskiy@gmail.com>
---
 src/bhyve/bhyve_driver.c | 69 ++++++++++++++++++++++++++++++++++++++--
 1 file changed, 67 insertions(+), 2 deletions(-)

diff --git a/src/bhyve/bhyve_driver.c b/src/bhyve/bhyve_driver.c
index 35abf36877..4b28c698e7 100644
--- a/src/bhyve/bhyve_driver.c
+++ b/src/bhyve/bhyve_driver.c
@@ -1053,14 +1053,51 @@ bhyveDomainShutdownSignal(virDomainObj *vm,
     return virBhyveProcessShutdown(vm);
 }
 
+static int
+bhyveDomainShutdownFlagsAgent(virDomainObj *vm,
+                              bool isReboot,
+                              bool reportError)
+{
+    int ret = -1;
+    qemuAgent *agent;
+    int agentFlag = isReboot ? QEMU_AGENT_SHUTDOWN_REBOOT :
+        QEMU_AGENT_SHUTDOWN_POWERDOWN;
+
+    if (virDomainObjBeginAgentJob(vm, VIR_AGENT_JOB_MODIFY) < 0)
+        return -1;
+
+    if (virDomainObjGetState(vm, NULL) != VIR_DOMAIN_RUNNING) {
+        virReportError(VIR_ERR_OPERATION_INVALID,
+                       "%s", _("domain is not running"));
+        goto endjob;
+    }
+
+    if (bhyveDomainEnsureAgent(vm, reportError) < 0)
+        goto endjob;
+
+    agent = bhyveDomainObjEnterAgent(vm);
+    qemuAgentShutdown(agent, agentFlag);
+    bhyveDomainObjExitAgent(vm, agent);
+    ret = 0;
+
+ endjob:
+    virDomainObjEndAgentJob(vm);
+    return ret;
+}
+
 static int
 bhyveDomainShutdownFlags(virDomainPtr dom, unsigned int flags)
 {
     virDomainObj *vm;
+    bhyveDomainObjPrivate *priv;
     int ret = -1;
     bool isReboot = false;
+    bool useAgent = false;
+    bool agentRequested, signalRequested;
+    bool agentForced;
 
-    virCheckFlags(0, -1);
+    virCheckFlags(VIR_DOMAIN_SHUTDOWN_SIGNAL |
+                  VIR_DOMAIN_SHUTDOWN_GUEST_AGENT, -1);
 
     if (!(vm = bhyveDomObjFromDomain(dom)))
         goto cleanup;
@@ -1071,13 +1108,41 @@ bhyveDomainShutdownFlags(virDomainPtr dom, unsigned int flags)
         VIR_INFO("Domain on_poweroff setting overridden, attempting reboot");
     }
 
+    priv = vm->privateData;
+    agentRequested = flags & VIR_DOMAIN_SHUTDOWN_GUEST_AGENT;
+    signalRequested = flags & VIR_DOMAIN_SHUTDOWN_SIGNAL;
+
+    /* Prefer agent unless we were requested to not to. */
+    if (agentRequested || !flags)
+        useAgent = true;
+
     if (virDomainShutdownFlagsEnsureACL(dom->conn, vm->def, flags) < 0)
         goto cleanup;
 
     if (virDomainObjCheckActive(vm) < 0)
         goto cleanup;
 
-    ret = bhyveDomainShutdownSignal(vm, isReboot);
+    agentForced = agentRequested && !signalRequested;
+    if (useAgent) {
+        ret = bhyveDomainShutdownFlagsAgent(vm, isReboot, agentForced);
+        if (((ret < 0) || (priv->agent != NULL)) && agentForced)
+            goto cleanup;
+    }
+
+    /* If we are not enforced to use just an agent, try signal
+     * shutdown as well in case agent did not succeed.
+     */
+    if (!useAgent || (((ret < 0) ||
+        (priv->agent != NULL)) && (signalRequested || !flags))) {
+        /* Even if agent failed, we have to check if guest went away
+         * by itself while our locks were down.  */
+        if (useAgent && !virDomainObjIsActive(vm)) {
+            ret = 0;
+            goto cleanup;
+        }
+
+        ret = bhyveDomainShutdownSignal(vm, isReboot);
+    }
 
  cleanup:
     virDomainObjEndAPI(&vm);
-- 
2.52.0
Re: [PATCH 1/2] bhyve: implement shutdown using agent
Posted by Michal Prívozník via Devel 1 week, 1 day ago
On 6/14/26 08:56, Roman Bogorodskiy wrote:
> Implement shutdown using a guest agent.
> Implementation and behaviour is very similar to the one
> found in the qemu driver.
> 
> The bhyveDomainShutdownFlags() function now supports
> the VIR_DOMAIN_SHUTDOWN_SIGNAL and VIR_DOMAIN_SHUTDOWN_GUEST_AGENT.
> If flags were not specified, try the agent first, and if it does
> not work, proceed with the signal.
> 
> As we do not expect a response from the agent shutdown command,
> we do not check qemuAgentShutdown()'s return value. Assume that the
> command failed if the agent did not receive EOF, thus "priv->agent"
> is not NULL.
> 
> Signed-off-by: Roman Bogorodskiy <bogorodskiy@gmail.com>
> ---
>  src/bhyve/bhyve_driver.c | 69 ++++++++++++++++++++++++++++++++++++++--
>  1 file changed, 67 insertions(+), 2 deletions(-)

Reviewed-by: Michal Privoznik <mprivozn@redhat.com>

Michal
[PATCH 2/2] bhyve: implement reboot using agent
Posted by Roman Bogorodskiy 1 week, 3 days ago
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
Re: [PATCH 2/2] bhyve: implement reboot using agent
Posted by Michal Prívozník via Devel 1 week, 1 day ago
On 6/14/26 08:56, Roman Bogorodskiy wrote:
> 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(-)

Reviewed-by: Michal Privoznik <mprivozn@redhat.com>

Michal