From: Hannes Laimer <h.laimer@proxmox.com>
To: pve-devel@lists.proxmox.com
Subject: [PATCH pve-cluster 04/10] pmxcfs: memdb: add change notification hook
Date: Fri, 18 Sep 2026 16:41:46 +0200 [thread overview]
Message-ID: <20260918144152.575163-5-h.laimer@proxmox.com> (raw)
In-Reply-To: <20260918144152.575163-1-h.laimer@proxmox.com>
Every mutation of the cluster file system, local or delivered from
another node, passes through memdb, which makes it the one place where
a change notification can be raised for all of them. Add a hook the
daemon installs at startup and call it as the last step of a mutation,
after the change is persisted and the guest list updated. An observer
is then told only about changes that survived, and whatever it reads
next, the guest list included, already reflects them. A node that
takes the whole state from the cluster during a synchronization raises
a resync in place of the mutations it never saw, since its state is
replaced as a whole then.
The hook stays a plain function pointer rather than a direct call
into the notifier, since memdb is part of the static C library the
database tools and the unit tests also link, which must not drag the
socket server along. The event types come straight from the notifier's
header, so the values cross the boundary without translation.
Signed-off-by: Hannes Laimer <h.laimer@proxmox.com>
---
src/pmxcfs/Makefile | 1 +
src/pmxcfs/database.c | 2 ++
src/pmxcfs/memdb.c | 24 ++++++++++++++++++++++++
src/pmxcfs/memdb.h | 11 +++++++++++
4 files changed, 38 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..486fe84 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, memdb->root->version, NULL, NULL);
+
result = TRUE;
ret:
diff --git a/src/pmxcfs/memdb.c b/src/pmxcfs/memdb.c
index 77d7652..a6a2a62 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, uint64_t seq, const char *path, const char *to) {
+ if (notify_hook) {
+ notify_hook(type, seq, 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, memdb->root->version, path, NULL);
+
ret = 0;
ret:
@@ -824,6 +838,10 @@ static int memdb_pwrite(
vmlist_register_vm(vmtype, vmid, nodename);
}
+ memdb_notify(
+ old ? PMXCFS_NOTIFY_WRITE : PMXCFS_NOTIFY_CREATE, memdb->root->version, path, NULL
+ );
+
ret = count;
ret:
@@ -929,6 +947,8 @@ int memdb_mtime(memdb_t *memdb, const char *path, guint32 writer, guint32 mtime)
}
}
+ memdb_notify(PMXCFS_NOTIFY_MTIME, memdb->root->version, path, NULL);
+
ret = 0;
ret:
@@ -1191,6 +1211,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, memdb->root->version, from, to);
+
ret = 0;
ret:
@@ -1264,6 +1286,8 @@ int memdb_delete(memdb_t *memdb, const char *path, guint32 writer, guint32 mtime
vmlist_delete_vm(vmid);
}
+ memdb_notify(PMXCFS_NOTIFY_DELETE, memdb->root->version, path, NULL);
+
ret = 0;
ret:
diff --git a/src/pmxcfs/memdb.h b/src/pmxcfs/memdb.h
index bca8967..f7dff5b 100644
--- a/src/pmxcfs/memdb.h
+++ b/src/pmxcfs/memdb.h
@@ -22,11 +22,14 @@
#define _PVE_MEMDB_H_
#include <stdio.h>
+#include <stdint.h>
#include <stdlib.h>
#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 +86,10 @@ typedef struct {
db_backend_t *bdb;
} memdb_t;
+typedef void (*memdb_notify_fn)(
+ enum pmxcfs_notify_type type, uint64_t seq, const char *path, const char *to
+);
+
memdb_t *memdb_open(const char *dbfilename);
void memdb_close(memdb_t *memdb);
@@ -138,6 +145,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, uint64_t seq, const char *path, const char *to);
+
void memdb_dump(memdb_t *memdb);
gboolean
--
2.47.3
next prev parent reply other threads:[~2026-09-18 14:42 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-18 14:41 [RFC cluster/manager 00/10] pmxcfs: add a change notification socket Hannes Laimer
2026-09-18 14:41 ` [PATCH pve-cluster 01/10] buildsys: add rust workspace under src/rust Hannes Laimer
2026-09-18 14:41 ` [PATCH pve-cluster 02/10] rust: notify: add change notification socket server Hannes Laimer
2026-09-18 14:41 ` [PATCH pve-cluster 03/10] rust: ffi: add C ABI staticlib for pmxcfs Hannes Laimer
2026-09-18 14:41 ` Hannes Laimer [this message]
2026-09-18 14:41 ` [PATCH pve-cluster 05/10] buildsys: link pmxcfs against the rust notify staticlib Hannes Laimer
2026-09-18 14:41 ` [PATCH pve-cluster 06/10] pmxcfs: notify: emit change events over the notification socket Hannes Laimer
2026-09-18 14:41 ` [PATCH pve-cluster 07/10] cfs: add perl client for the change " Hannes Laimer
2026-09-18 14:41 ` [PATCH pve-cluster 08/10] cfs: add hook registry for change notification consumers Hannes Laimer
2026-09-18 14:41 ` [PATCH pve-manager 09/10] hooks: add runner executing cluster change hooks in children Hannes Laimer
2026-09-18 14:41 ` [PATCH pve-manager 10/10] pvescheduler: run cluster change hooks from a listener child 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=20260918144152.575163-5-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