From: Hannes Laimer <h.laimer@proxmox.com>
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 [thread overview]
Message-ID: <20261022142205.930536-8-h.laimer@proxmox.com> (raw)
In-Reply-To: <20261022142205.930536-1-h.laimer@proxmox.com>
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 <h.laimer@proxmox.com>
---
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 <glib.h>
#include <sys/statvfs.h>
+#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
next prev parent reply other threads:[~2026-10-22 14:23 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-22 14:21 [PATCH cluster 00/12] pmxcfs: add a change notification socket Hannes Laimer
2026-10-22 14:21 ` [PATCH pve-cluster 01/12] buildsys: add rust workspace under src/rust Hannes Laimer
2026-10-22 14:21 ` [PATCH pve-cluster 02/12] rust: notify: add path templates with placeholder capture Hannes Laimer
2026-10-22 14:21 ` [PATCH pve-cluster 03/12] rust: notify: add the wire protocol Hannes Laimer
2026-10-22 14:21 ` [PATCH pve-cluster 04/12] rust: notify: add subscription matching Hannes Laimer
2026-10-22 14:21 ` [PATCH pve-cluster 05/12] rust: notify: add the socket server Hannes Laimer
2026-10-22 14:21 ` [PATCH pve-cluster 06/12] rust: ffi: add C ABI staticlib for pmxcfs Hannes Laimer
2026-10-22 14:22 ` Hannes Laimer [this message]
2026-10-22 14:22 ` [PATCH pve-cluster 08/12] buildsys: link pmxcfs against the rust notify staticlib Hannes Laimer
2026-10-22 14:22 ` [PATCH pve-cluster 09/12] pmxcfs: notify: emit change events over the notification socket Hannes Laimer
2026-10-22 14:22 ` [PATCH pve-cluster 10/12] cfs: add perl client for the change " Hannes Laimer
2026-10-22 14:22 ` [PATCH pve-cluster 11/12] cfs: add hook registry for change notification consumers Hannes Laimer
2026-10-22 14:22 ` [PATCH pve-cluster 12/12] cfs: add runner executing cluster change hooks in children Hannes Laimer
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261022142205.930536-8-h.laimer@proxmox.com \
--to=h.laimer@proxmox.com \
--cc=pve-devel@lists.proxmox.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox