[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, ®ister_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, ®ister_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