From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from gate001.proxmox.com (gate001.proxmox.com [IPv6:2a0f:8001:1:32::40]) by lore.proxmox.com (Postfix) with ESMTPS id 0A4BE1FF0C2 for ; Thu, 22 Oct 2026 16:23:16 +0200 (CEST) Received: from gate001.proxmox.com (localhost.localdomain [127.0.0.1]) by gate001.proxmox.com (Proxmox) with ESMTP id 34079216EB; Thu, 22 Oct 2026 16:23:01 +0200 (CEST) From: Hannes Laimer To: pve-devel@lists.proxmox.com Subject: [PATCH pve-cluster 09/12] pmxcfs: notify: emit change events over the notification socket Date: Thu, 22 Oct 2026 16:22:02 +0200 Message-ID: <20261022142205.930536-10-h.laimer@proxmox.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20261022142205.930536-1-h.laimer@proxmox.com> References: <20261022142205.930536-1-h.laimer@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Bm-Milter-Handled: 55990f41-d878-4baa-be0a-ee34c49e34d2 X-Bm-Transport-Timestamp: 1792678937428 X-SPAM-LEVEL: Spam detection results: 0 AWL 0.343 Adjusted score from AWL reputation of From: address DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment (newer systems) RCVD_IN_DNSWL_MED -2.3 Sender listed at https://www.dnswl.org/, medium trust SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record Message-ID-Hash: NM62G2B2PUJBEMUONYPM2PHFCNRS5RAI X-Message-ID-Hash: NM62G2B2PUJBEMUONYPM2PHFCNRS5RAI X-MailFrom: h.laimer@proxmox.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.10 Precedence: list List-Id: Proxmox VE development discussion List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: The daemon serves the socket at /run/pve-cluster/pmxcfs.sock to root and the www-data group. The filesystem works without the socket, so the daemon only logs a failure to start it. The notifier runs on a thread of its own, so it starts after the daemonize fork. The notifier's log messages go through the daemon's logging under their own domain, so they land in the same journal stream as the daemon's other messages. Signed-off-by: Hannes Laimer --- src/pmxcfs/cfs-utils.h | 4 ++++ src/pmxcfs/pmxcfs.c | 24 ++++++++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/src/pmxcfs/cfs-utils.h b/src/pmxcfs/cfs-utils.h index ed67264..29f844e 100644 --- a/src/pmxcfs/cfs-utils.h +++ b/src/pmxcfs/cfs-utils.h @@ -78,6 +78,10 @@ void ipc_log_fn(const char *file, int32_t line, int32_t severity, const char *ms cfs_log(G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, __FILE__, __LINE__, G_STRFUNC, __VA_ARGS__) #define cfs_dom_critical(domain, ...) \ cfs_log(domain, G_LOG_LEVEL_CRITICAL, __FILE__, __LINE__, G_STRFUNC, __VA_ARGS__) +#define cfs_warn(...) \ + cfs_log(G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, __FILE__, __LINE__, G_STRFUNC, __VA_ARGS__) +#define cfs_dom_warn(domain, ...) \ + cfs_log(domain, G_LOG_LEVEL_WARNING, __FILE__, __LINE__, G_STRFUNC, __VA_ARGS__) #define cfs_message(...) \ cfs_log(G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE, __FILE__, __LINE__, G_STRFUNC, __VA_ARGS__) #define cfs_dom_message(domain, ...) \ diff --git a/src/pmxcfs/pmxcfs.c b/src/pmxcfs/pmxcfs.c index 14f1168..34bd4be 100644 --- a/src/pmxcfs/pmxcfs.c +++ b/src/pmxcfs/pmxcfs.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include @@ -51,6 +52,7 @@ #include "confdb.h" #include "dcdb.h" #include "dfsm.h" +#include "pmxcfs-notify.h" #include "quorum.h" #include "server.h" #include "status.h" @@ -58,6 +60,7 @@ #define DBFILENAME VARLIBDIR "/config.db" #define LOCKFILE VARLIBDIR "/.pmxcfs.lockfile" #define RESTART_FLAG_FILE RUNDIR "/cfs-restart-flag" +#define NOTIFY_SOCKET RUNDIR "/pmxcfs.sock" #define CFSDIR "/etc/pve" @@ -78,6 +81,18 @@ static void glib_log_handler( cfs_log(log_domain, log_level, NULL, 0, NULL, "%s", message); } +static void notify_log_cb(int priority, const char *msg) { + if (priority <= LOG_ERR) { + cfs_dom_critical("notify", "%s", msg); + } else if (priority <= LOG_WARNING) { + cfs_dom_warn("notify", "%s", msg); + } else if (priority <= LOG_INFO) { + cfs_dom_message("notify", "%s", msg); + } else { + cfs_dom_debug("notify", "%s", msg); + } +} + static gboolean write_pidfile(pid_t pid) { char *strpid = g_strdup_printf("%d\n", pid); gboolean res = atomic_write_file(CFS_PID_FN, strpid, strlen(strpid), 0644, getgid()); @@ -1032,6 +1047,13 @@ int main(int argc, char *argv[]) { cfs_loop_add_service(corosync_loop, service_status, QB_LOOP_LOW); } + memdb_set_notify_hook(pmxcfs_notify_emit); + + // must run before any other thread starts, since the bind changes the process umask + if (pmxcfs_notify_init(NOTIFY_SOCKET, cfs.gid, notify_log_cb) != 0) { + cfs_critical("running without change notification socket"); + } + cfs_loop_start_worker(corosync_loop); server_start(memdb); @@ -1053,6 +1075,8 @@ int main(int argc, char *argv[]) { server_stop(); + pmxcfs_notify_shutdown(); + fuse_unmount(CFSDIR, fuse_chan); fuse_destroy(fuse); -- 2.47.3