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 E4E8F1FF0C2 for ; Thu, 22 Oct 2026 16:23:00 +0200 (CEST) Received: from gate001.proxmox.com (localhost.localdomain [127.0.0.1]) by gate001.proxmox.com (Proxmox) with ESMTP id 95EE621663; Thu, 22 Oct 2026 16:22:59 +0200 (CEST) From: Hannes Laimer To: pve-devel@lists.proxmox.com Subject: [PATCH pve-cluster 07/12] pmxcfs: memdb: add change notification hook Date: Thu, 22 Oct 2026 16:22:00 +0200 Message-ID: <20261022142205.930536-8-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: 1792678935216 X-SPAM-LEVEL: Spam detection results: 0 AWL 0.346 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: 4IBGX4RJDLRTKXZS3TYI2WZPS5XXKTUM X-Message-ID-Hash: 4IBGX4RJDLRTKXZS3TYI2WZPS5XXKTUM 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: Every change to the cluster file system, local or delivered from another node, goes through a memdb mutation. Add a hook to memdb and call it as the last step of each mutation, after the change is stored and the guest list updated. An observer is then told only about stored changes, and whatever it reads next already shows them. During a synchronization a node can take the whole state from the cluster. It never saw the mutations behind that state, so the hook gets a resync instead. The hook is a function pointer instead of a direct call into the notifier, since the database tool and the tests link the same static C library as the daemon. They should not pull in the socket server. The event types come from the notifier's header, so memdb needs no mapping of its own. Signed-off-by: Hannes Laimer --- src/pmxcfs/Makefile | 1 + src/pmxcfs/database.c | 2 ++ src/pmxcfs/memdb.c | 22 ++++++++++++++++++++++ src/pmxcfs/memdb.h | 8 ++++++++ 4 files changed, 33 insertions(+) diff --git a/src/pmxcfs/Makefile b/src/pmxcfs/Makefile index 547f258..90bc6a5 100644 --- a/src/pmxcfs/Makefile +++ b/src/pmxcfs/Makefile @@ -8,6 +8,7 @@ CFLAGS += -Wpedantic CFLAGS += -g -O2 CFLAGS += -I. CFLAGS += $(shell pkg-config --cflags $(DEPENDENCIES)) +CFLAGS += -I../rust/pmxcfs-ffi/include LDFLAGS += -Wl,-z,relro $(shell pkg-config --libs $(DEPENDENCIES)) diff --git a/src/pmxcfs/database.c b/src/pmxcfs/database.c index 4ee2389..36fc1d7 100644 --- a/src/pmxcfs/database.c +++ b/src/pmxcfs/database.c @@ -611,6 +611,8 @@ gboolean bdb_backend_commit_update( memdb_update_locks(memdb); + memdb_notify(PMXCFS_NOTIFY_RESYNC, NULL, NULL); + result = TRUE; ret: diff --git a/src/pmxcfs/memdb.c b/src/pmxcfs/memdb.c index 77d7652..3f60593 100644 --- a/src/pmxcfs/memdb.c +++ b/src/pmxcfs/memdb.c @@ -41,6 +41,18 @@ #define CFS_LOCK_TIMEOUT (60 * 2) +// Set once before any other thread runs, so no locking is needed here. +// The hook runs under memdb->mutex and must not call back into memdb. +static memdb_notify_fn notify_hook; + +void memdb_set_notify_hook(memdb_notify_fn hook) { notify_hook = hook; } + +void memdb_notify(enum pmxcfs_notify_type type, const char *path, const char *to) { + if (notify_hook) { + notify_hook(type, path, to); + } +} + memdb_tree_entry_t *memdb_tree_entry_new(const char *name) { g_return_val_if_fail(name != NULL, NULL); @@ -621,6 +633,8 @@ int memdb_mkdir(memdb_t *memdb, const char *path, guint32 writer, guint32 mtime) } } + memdb_notify(PMXCFS_NOTIFY_MKDIR, path, NULL); + ret = 0; ret: @@ -824,6 +838,8 @@ static int memdb_pwrite( vmlist_register_vm(vmtype, vmid, nodename); } + memdb_notify(old ? PMXCFS_NOTIFY_WRITE : PMXCFS_NOTIFY_CREATE, path, NULL); + ret = count; ret: @@ -929,6 +945,8 @@ int memdb_mtime(memdb_t *memdb, const char *path, guint32 writer, guint32 mtime) } } + memdb_notify(PMXCFS_NOTIFY_MTIME, path, NULL); + ret = 0; ret: @@ -1191,6 +1209,8 @@ int memdb_rename(memdb_t *memdb, const char *from, const char *to, guint32 write /* directories are alwayse empty (see unlink_tree_entry) */ } + memdb_notify(PMXCFS_NOTIFY_RENAME, from, to); + ret = 0; ret: @@ -1264,6 +1284,8 @@ int memdb_delete(memdb_t *memdb, const char *path, guint32 writer, guint32 mtime vmlist_delete_vm(vmid); } + memdb_notify(PMXCFS_NOTIFY_DELETE, path, NULL); + ret = 0; ret: diff --git a/src/pmxcfs/memdb.h b/src/pmxcfs/memdb.h index bca8967..28e7c28 100644 --- a/src/pmxcfs/memdb.h +++ b/src/pmxcfs/memdb.h @@ -27,6 +27,8 @@ #include #include +#include "pmxcfs-notify.h" + #define MEMDB_MAX_FILE_SIZE (1024 * 1024) // 1 MiB #define MEMDB_MAX_FSSIZE (128 * 1024 * 1024) // 128 MiB #define MEMDB_MAX_INODES (256 * 1024) // 256k @@ -83,6 +85,8 @@ typedef struct { db_backend_t *bdb; } memdb_t; +typedef void (*memdb_notify_fn)(enum pmxcfs_notify_type type, const char *path, const char *to); + memdb_t *memdb_open(const char *dbfilename); void memdb_close(memdb_t *memdb); @@ -138,6 +142,10 @@ memdb_tree_entry_t *memdb_getattr(memdb_t *memdb, const char *path); int memdb_rename(memdb_t *memdb, const char *from, const char *to, guint32 writer, guint32 mtime); +void memdb_set_notify_hook(memdb_notify_fn hook); + +void memdb_notify(enum pmxcfs_notify_type type, const char *path, const char *to); + void memdb_dump(memdb_t *memdb); gboolean -- 2.47.3