]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
ch: virCHMonitorNew() run new CH monitor daemonized
authorKirill Shchetiniuk via Devel <devel@lists.libvirt.org>
Tue, 25 Mar 2025 14:11:57 +0000 (15:11 +0100)
committerMichal Privoznik <mprivozn@redhat.com>
Wed, 2 Apr 2025 15:35:28 +0000 (17:35 +0200)
When the new CH monitor was started, it ran as a non-daemonized
process and was a child of the CH driver process. This led to a
situation where if the CH driver died, the monitor process were
killed too, terminating the running VM under the monitor. This
led to termination of all VM started under the libvirt.

Make new monitor running daemonized to avoid VMs shutdown when
driver dies. Also added a pidfile its preparetion to be able
to aquire daemon's PID.

Signed-off-by: Kirill Shchetiniuk <kshcheti@redhat.com>
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
src/ch/ch_domain.c
src/ch/ch_domain.h
src/ch/ch_monitor.c
src/ch/ch_process.c

index a08b18c5b906df921d2053455784149482e8c352..c0c9acd85bdf394bd9b660a1d723a3891779b1f8 100644 (file)
@@ -68,6 +68,7 @@ virCHDomainObjPrivateFree(void *data)
     virBitmapFree(priv->autoCpuset);
     virBitmapFree(priv->autoNodeset);
     virCgroupFree(priv->cgroup);
+    g_free(priv->pidfile);
     g_free(priv);
 }
 
index 8dea2b21236e0888e16091900a5f19a51d62ddcb..69a657f6af6f9476b12ba866ea0afb0b3d082695 100644 (file)
@@ -36,6 +36,7 @@ struct _virCHDomainObjPrivate {
     virBitmap *autoCpuset;
     virBitmap *autoNodeset;
     virCgroup *cgroup;
+    char *pidfile;
 };
 
 #define CH_DOMAIN_PRIVATE(vm) \
index 0ba927a194115aa021f856ea2e89ae4ebc321c5a..91899e873b295cc4689ac00e573b8863d77a694c 100644 (file)
@@ -27,6 +27,7 @@
 
 #include "datatypes.h"
 #include "ch_conf.h"
+#include "ch_domain.h"
 #include "ch_events.h"
 #include "ch_interface.h"
 #include "ch_monitor.h"
@@ -37,6 +38,7 @@
 #include "virfile.h"
 #include "virjson.h"
 #include "virlog.h"
+#include "virpidfile.h"
 #include "virstring.h"
 
 #define VIR_FROM_THIS VIR_FROM_CH
@@ -582,10 +584,12 @@ chMonitorCreateSocket(const char *socket_path)
 virCHMonitor *
 virCHMonitorNew(virDomainObj *vm, virCHDriverConfig *cfg, int logfile)
 {
+    virCHDomainObjPrivate *priv = vm->privateData;
     g_autoptr(virCHMonitor) mon = NULL;
     g_autoptr(virCommand) cmd = NULL;
     int socket_fd = 0;
     int event_monitor_fd;
+    int rv;
 
     if (virCHMonitorInitialize() < 0)
         return NULL;
@@ -644,6 +648,7 @@ virCHMonitorNew(virDomainObj *vm, virCHDriverConfig *cfg, int logfile)
     virCommandSetErrorFD(cmd, &logfile);
     virCommandNonblockingFDs(cmd);
     virCommandSetUmask(cmd, 0x002);
+
     socket_fd = chMonitorCreateSocket(mon->socketpath);
     if (socket_fd < 0) {
         virReportSystemError(errno,
@@ -655,13 +660,26 @@ virCHMonitorNew(virDomainObj *vm, virCHDriverConfig *cfg, int logfile)
     virCommandAddArg(cmd, "--api-socket");
     virCommandAddArgFormat(cmd, "fd=%d", socket_fd);
     virCommandPassFD(cmd, socket_fd, VIR_COMMAND_PASS_FD_CLOSE_PARENT);
-
     virCommandAddArg(cmd, "--event-monitor");
     virCommandAddArgFormat(cmd, "path=%s", mon->eventmonitorpath);
+    virCommandSetPidFile(cmd, priv->pidfile);
+    virCommandDaemonize(cmd);
 
     /* launch Cloud-Hypervisor socket */
-    if (virCommandRunAsync(cmd, &mon->pid) < 0)
+    if (virCommandRun(cmd, NULL) < 0) {
+        VIR_DEBUG("CH vm=%p name=%s failed to spawn",
+                  vm, vm->def->name);
+        return NULL;
+    }
+
+    if ((rv = virPidFileReadPath(priv->pidfile, &mon->pid)) < 0) {
+        virReportSystemError(-rv,
+                             _("Domain  %1$s didn't show up"),
+                             vm->def->name);
         return NULL;
+    }
+    VIR_DEBUG("CH vm=%p name=%s running with pid=%lld",
+              vm, vm->def->name, (long long)mon->pid);
 
     /* open the reader end of fifo before start Event Handler */
     while ((event_monitor_fd = open(mon->eventmonitorpath, O_RDONLY)) < 0) {
index b3eddd61e86fc77b7dabebd552260446621d169e..ad44e8031a87e2ba6def1befbf3aef9f70f9bdf1 100644 (file)
@@ -36,6 +36,7 @@
 #include "virjson.h"
 #include "virlog.h"
 #include "virnuma.h"
+#include "virpidfile.h"
 #include "virstring.h"
 #include "ch_interface.h"
 #include "ch_hostdev.h"
@@ -850,6 +851,21 @@ virCHProcessPrepareHost(virCHDriver *driver, virDomainObj *vm)
     if (virCHHostdevPrepareDomainDevices(driver, vm->def, hostdev_flags) < 0)
         return -1;
 
+    VIR_FREE(priv->pidfile);
+    if (!(priv->pidfile = virPidFileBuildPath(cfg->stateDir, vm->def->name))) {
+        virReportSystemError(errno, "%s",
+                             _("Failed to build pidfile path."));
+        return -1;
+    }
+
+    if (unlink(priv->pidfile) < 0 &&
+        errno != ENOENT) {
+        virReportSystemError(errno,
+                             _("Cannot remove stale PID file %1$s"),
+                             priv->pidfile);
+        return -1;
+    }
+
     /* Ensure no historical cgroup for this VM is lying around */
     VIR_DEBUG("Ensuring no historical cgroup is lying around");
     virDomainCgroupRemoveCgroup(vm, priv->cgroup, priv->machineName);
@@ -1035,6 +1051,15 @@ virCHProcessStop(virCHDriver *driver,
     vm->def->id = -1;
     g_clear_pointer(&priv->machineName, g_free);
 
+    if (priv->pidfile) {
+        if (unlink(priv->pidfile) < 0 &&
+            errno != ENOENT)
+            VIR_WARN("Failed to remove PID file for %s: %s",
+                     vm->def->name, g_strerror(errno));
+
+        g_clear_pointer(&priv->pidfile, g_free);
+    }
+
     virDomainObjSetState(vm, VIR_DOMAIN_SHUTOFF, reason);
 
     virHostdevReAttachDomainDevices(driver->hostdevMgr, CH_DRIVER_NAME, def,