public inbox for pve-devel@lists.proxmox.com
 help / color / mirror / Atom feed
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





  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
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal