From: Kirill Shchetiniuk via Devel Date: Tue, 25 Mar 2025 14:11:57 +0000 (+0100) Subject: ch: virCHMonitorNew() run new CH monitor daemonized X-Git-Tag: v11.3.0-rc1~84 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=9d6e2d127e673642b0fb135b6d58539a8e332e08;p=thirdparty%2Flibvirt.git ch: virCHMonitorNew() run new CH monitor daemonized 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 Signed-off-by: Michal Privoznik Reviewed-by: Michal Privoznik --- diff --git a/src/ch/ch_domain.c b/src/ch/ch_domain.c index a08b18c5b9..c0c9acd85b 100644 --- a/src/ch/ch_domain.c +++ b/src/ch/ch_domain.c @@ -68,6 +68,7 @@ virCHDomainObjPrivateFree(void *data) virBitmapFree(priv->autoCpuset); virBitmapFree(priv->autoNodeset); virCgroupFree(priv->cgroup); + g_free(priv->pidfile); g_free(priv); } diff --git a/src/ch/ch_domain.h b/src/ch/ch_domain.h index 8dea2b2123..69a657f6af 100644 --- a/src/ch/ch_domain.h +++ b/src/ch/ch_domain.h @@ -36,6 +36,7 @@ struct _virCHDomainObjPrivate { virBitmap *autoCpuset; virBitmap *autoNodeset; virCgroup *cgroup; + char *pidfile; }; #define CH_DOMAIN_PRIVATE(vm) \ diff --git a/src/ch/ch_monitor.c b/src/ch/ch_monitor.c index 0ba927a194..91899e873b 100644 --- a/src/ch/ch_monitor.c +++ b/src/ch/ch_monitor.c @@ -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) { diff --git a/src/ch/ch_process.c b/src/ch/ch_process.c index b3eddd61e8..ad44e8031a 100644 --- a/src/ch/ch_process.c +++ b/src/ch/ch_process.c @@ -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,