In unprivileged mode, libvirt tracks the bhyve monitor process while
'bhyvectl --get-vm-pid' reports the child process executing the VM.

Keep the existing process title validation for privileged mode. In
unprivileged mode, query the VM PID and require the VM process to be a
child of the tracked monitor process.

Signed-off-by: Roman Bogorodskiy <[email protected]>
---
 src/bhyve/bhyve_process.c | 44 +++++++++++++++++++++++----------------
 1 file changed, 26 insertions(+), 18 deletions(-)

diff --git a/src/bhyve/bhyve_process.c b/src/bhyve/bhyve_process.c
index 0dc7d18289..811ed4204d 100644
--- a/src/bhyve/bhyve_process.c
+++ b/src/bhyve/bhyve_process.c
@@ -933,7 +933,8 @@ virBhyveProcessReconnect(virDomainObj *vm,
     struct kinfo_proc *kp;
     int nprocs;
     char **proc_argv;
-    char *expected_proctitle = NULL;
+    g_autofree char *expected_proctitle = NULL;
+    pid_t bhyvePid;
     bhyveDomainObjPrivate *priv = vm->privateData;
     g_autoptr(virConnect) conn = NULL;
     size_t i;
@@ -951,22 +952,30 @@ virBhyveProcessReconnect(virDomainObj *vm,
     if (kp == NULL || nprocs != 1)
         goto cleanup;
 
-    expected_proctitle = g_strdup_printf("bhyve: %s", vm->def->name);
-
-    proc_argv = kvm_getargv(data->kd, kp, 0);
-    if (proc_argv && proc_argv[0]) {
-         if (STREQ(expected_proctitle, proc_argv[0])) {
-             ret = 0;
-             priv->mon = bhyveMonitorOpen(vm, data->driver);
-             if (vm->def->ngraphics == 1 &&
-                 vm->def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC) {
-                 int vnc_port = vm->def->graphics[0]->data.vnc.port;
-                 if (virPortAllocatorSetUsed(vnc_port) < 0) {
-                     VIR_WARN("Failed to mark VNC port '%d' as used by '%s'",
-                              vnc_port, vm->def->name);
-                 }
-             }
-         }
+    if (data->driver->privileged) {
+        expected_proctitle = g_strdup_printf("bhyve: %s", vm->def->name);
+        proc_argv = kvm_getargv(data->kd, kp, 0);
+        if (!proc_argv || !proc_argv[0] ||
+            STRNEQ(expected_proctitle, proc_argv[0]))
+            goto cleanup;
+    } else {
+        if ((bhyvePid = bhyveProcessQueryVMPid(vm)) < 0)
+            goto cleanup;
+
+        kp = kvm_getprocs(data->kd, KERN_PROC_PID, bhyvePid, &nprocs);
+        if (kp == NULL || nprocs != 1 || (pid_t)kp->ki_ppid != vm->pid)
+            goto cleanup;
+    }
+
+    ret = 0;
+    priv->mon = bhyveMonitorOpen(vm, data->driver);
+    if (vm->def->ngraphics == 1 &&
+        vm->def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC) {
+        int vnc_port = vm->def->graphics[0]->data.vnc.port;
+        if (virPortAllocatorSetUsed(vnc_port) < 0) {
+            VIR_WARN("Failed to mark VNC port '%d' as used by '%s'",
+                     vnc_port, vm->def->name);
+        }
     }
 
     for (i = 0; i < vm->def->nnets; i++) {
@@ -995,7 +1004,6 @@ virBhyveProcessReconnect(virDomainObj *vm,
     }
 
     virObjectUnlock(vm);
-    VIR_FREE(expected_proctitle);
 
     return ret;
 }
-- 
2.55.0

Reply via email to