[Ocfs2-tools-devel] [PATCH 6/9] ocfs2_controld: Registration function for lockspaces.

Joel Becker joel.becker at oracle.com
Wed Aug 13 17:15:36 PDT 2008


We want to register a filesystem uuid with dlm_controld so that the
lockspace waits on us before recovery.  We use libdlmcontrol's
registration functions.

Signed-off-by: Joel Becker <joel.becker at oracle.com>
---
 ocfs2_controld/dlmcontrol.c     |  149 ++++++++++++++++++++++++++++++++++++++-
 ocfs2_controld/ocfs2_controld.h |    4 +
 2 files changed, 151 insertions(+), 2 deletions(-)

diff --git a/ocfs2_controld/dlmcontrol.c b/ocfs2_controld/dlmcontrol.c
index f7e3047..7a4214d 100644
--- a/ocfs2_controld/dlmcontrol.c
+++ b/ocfs2_controld/dlmcontrol.c
@@ -22,10 +22,117 @@
 #include <libdlm.h>
 #include <libdlmcontrol.h>
 
+#include "ocfs2-kernel/kernel-list.h"
+
 #include "ocfs2_controld.h"
 
-static int dlmcontrol_ci;
-static int dlmcontrol_fd = -1;
+
+/*
+ * Structure to keep track of filesystems we've registered with
+ * dlm_controld.
+ */
+struct dlmcontrol_fs {
+	struct list_head	df_list;
+	char			df_name[DLM_LOCKSPACE_LEN+1];
+	void			(*df_result)(int status, void *user_data);
+	void			*df_user_data;
+};
+
+static int dlmcontrol_ci;	/* Client number in the main loop */
+static int dlmcontrol_fd = -1;	/* fd for dlm_controld connection */
+
+/* List of all filesystems we have registered */
+static LIST_HEAD(register_list);
+
+int dlmcontrol_register(const char *name,
+			void (*result_func)(int status, void *user_data),
+			void *user_data)
+{
+	int rc;
+	struct dlmcontrol_fs *df;
+
+	df = malloc(sizeof(struct dlmcontrol_fs));
+	if (!df) {
+		log_error("Unable to allocate memory to register \"%s\" "
+			  "with dlm_controld",
+			  name);
+		rc = -ENOMEM;
+		goto out;
+	}
+
+	snprintf(df->df_name, DLM_LOCKSPACE_LEN+1, "%s", name);
+	df->df_result = result_func;
+	df->df_user_data = user_data;
+
+	/*
+	 * We register *before* allowing the filesystem to mount.
+	 * Otherwise we have a window between mount(2) and registration
+	 * where notification is unordered.
+	 */
+	log_debug("Registering \"%s\" with dlm_controld", name);
+	rc = dlmc_fs_register(dlmcontrol_fd, df->df_name);
+	if (rc) {
+		rc = -errno;
+		log_error("Unable to register \"%s\" with dlm_controld: %s",
+			  df->df_name, strerror(-rc));
+		goto out;
+	}
+
+	list_add(&df->df_list, &register_list);
+
+out:
+	if (rc && df)
+		free(df);
+
+	return rc;
+}
+
+static struct dlmcontrol_fs *find_fs(const char *name)
+{
+	struct list_head *pos;
+	struct dlmcontrol_fs *df;
+
+	list_for_each(pos, &register_list) {
+		df = list_entry(pos, struct dlmcontrol_fs, df_list);
+		if (!strcmp(df->df_name, name))
+			return df;
+	}
+
+	return NULL;
+}
+
+int dlmcontrol_unregister(const char *name)
+{
+	int rc;
+	struct dlmcontrol_fs *df;
+
+	df = find_fs(name);
+	if (!df) {
+		log_error("Name \"%s\" is unknown", name);
+		rc = -ENOENT;
+		goto out;
+	}
+
+	list_del(&df->df_list);
+
+	/*
+	 * From here out, we're going to try to drop everything, even in
+	 * the face of errors.
+	 */
+	log_debug("Unregistering \"%s\" from dlm_controld", name);
+	rc = dlmc_fs_unregister(dlmcontrol_fd, df->df_name);
+	if (rc) {
+		rc = -errno;
+		log_error("Unable to unregister \"%s\" from dlm_controld: "
+			  "%s",
+			  name, strerror(-rc));
+	}
+
+	free(df);
+
+out:
+	return rc;
+}
 
 static void dead_dlmcontrol(int ci)
 {
@@ -41,12 +148,50 @@ static void dead_dlmcontrol(int ci)
 
 static void process_dlmcontrol(int ci)
 {
+	int rc, result_type, nodeid, status;
+	char name[DLM_LOCKSPACE_LEN + 1];
+	struct dlmcontrol_fs *df;
+
+	memset(name, 0, sizeof(name));
+
 	if (ci != dlmcontrol_ci) {
 		log_error("Unknown connection %d", ci);
 		return;
 	}
 
 	log_debug("message from dlmcontrol\n");
+
+	rc = dlmc_fs_result(dlmcontrol_fd, name, &result_type, &nodeid,
+			    &status);
+	if (rc) {
+		rc = -errno;
+		log_error("Error from dlmc_fs_result: %s", strerror(-rc));
+		return;
+	}
+
+	df = find_fs(name);
+	if (!df) {
+		log_error("Name \"%s\" is unknown", name);
+		return;
+	}
+
+	switch (result_type) {
+		case DLMC_RESULT_REGISTER:
+			log_debug("Registration of \"%s\" complete",
+				  name);
+			df->df_result(status, df->df_user_data);
+			break;
+
+		case DLMC_RESULT_NOTIFIED:
+			log_debug("Notified for \"%s\"", name);
+			/* XXX: handle */
+			break;
+
+		default:
+			log_error("Unknown message from dlm_controld: %d",
+				  result_type);
+			break;
+	}
 }
 
 int setup_dlmcontrol(void)
diff --git a/ocfs2_controld/ocfs2_controld.h b/ocfs2_controld/ocfs2_controld.h
index 61c4689..4296639 100644
--- a/ocfs2_controld/ocfs2_controld.h
+++ b/ocfs2_controld/ocfs2_controld.h
@@ -100,6 +100,10 @@ int group_leave(struct cgroup *cg);
 /* dlmcontrol.c */
 int setup_dlmcontrol(void);
 void exit_dlmcontrol(void);
+int dlmcontrol_register(const char *name,
+			void (*result_func)(int status, void *user_data),
+			void *user_data);
+int dlmcontrol_unregister(const char *name);
 
 /* mount.c */
 void init_mounts(void);
-- 
1.5.6.3




More information about the Ocfs2-tools-devel mailing list