public inbox for cluster-cvs@sourceware.org
help / color / mirror / Atom feed
* master - dlm_controld: open dlm-monitor misc device
@ 2008-08-19 21:02 David Teigland
  0 siblings, 0 replies; only message in thread
From: David Teigland @ 2008-08-19 21:02 UTC (permalink / raw)
  To: cluster-cvs-relay

Gitweb:        http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=3c6d20abb8feac1d3756a13bf98e062a385b5f10
Commit:        3c6d20abb8feac1d3756a13bf98e062a385b5f10
Parent:        485525632d2763d69eb87bd137e798468cbfc9a3
Author:        David Teigland <teigland@redhat.com>
AuthorDate:    Tue Aug 19 14:39:59 2008 -0500
Committer:     David Teigland <teigland@redhat.com>
CommitterDate: Tue Aug 19 14:43:58 2008 -0500

dlm_controld: open dlm-monitor misc device

if it exists, as it will in future kernels.  This allows dlm-kernel
to detect if dlm_controld fails, and stop lockspaces in response.

Also rework/simplify handling of all misc devices; depend on udev
to create the device nodes.

Adds /dev/misc/dlm-monitor to the dlm's udev config file.

Signed-off-by: David Teigland <teigland@redhat.com>
---
 dlm/libdlm/51-dlm.rules         |    1 +
 group/dlm_controld/action.c     |  100 +++++++++++++++++++++
 group/dlm_controld/dlm_daemon.h |    5 +
 group/dlm_controld/main.c       |   25 +++++
 group/dlm_controld/plock.c      |  189 ++++-----------------------------------
 5 files changed, 148 insertions(+), 172 deletions(-)

diff --git a/dlm/libdlm/51-dlm.rules b/dlm/libdlm/51-dlm.rules
index 70d26dc..f71e79d 100644
--- a/dlm/libdlm/51-dlm.rules
+++ b/dlm/libdlm/51-dlm.rules
@@ -1,4 +1,5 @@
 KERNEL=="dlm-control", NAME="misc/dlm-control", MODE="0666"
+KERNEL=="dlm-monitor", NAME="misc/dlm-monitor", MODE="0666"
 KERNEL=="dlm_default", NAME="misc/dlm_default", MODE="0666"
 KERNEL=="dlm_*", NAME="misc/%k", MODE="0660"
 
diff --git a/group/dlm_controld/action.c b/group/dlm_controld/action.c
index aaf183a..18d0b09 100644
--- a/group/dlm_controld/action.c
+++ b/group/dlm_controld/action.c
@@ -829,3 +829,103 @@ int setup_configfs(void)
 	return 0;
 }
 
+static void find_minors(void)
+{
+	FILE *fl;
+	char name[256];
+	uint32_t number;
+	int found = 0;
+	int c;
+
+	if (!(fl = fopen("/proc/misc", "r"))) {
+		log_error("/proc/misc fopen failed: %s", strerror(errno));
+		return;
+	}
+
+	while (!feof(fl)) {
+		if (fscanf(fl, "%d %255s\n", &number, &name[0]) == 2) {
+
+			if (!strcmp(name, "dlm-control")) {
+				control_minor = number;
+				found++;
+			} else if (!strcmp(name, "dlm-monitor")) {
+				monitor_minor = number;
+				found++;
+			} else if (!strcmp(name, "dlm_plock")) {
+				plock_minor = number;
+				found++;
+			} else if (!strcmp(name, "lock_dlm_plock")) {
+				old_plock_minor = number;
+				found++;
+			}
+
+		} else do {
+			c = fgetc(fl);
+		} while (c != EOF && c != '\n');
+
+		if (found == 3)
+			break;
+	}
+	fclose(fl);
+
+	if (!found)
+		log_error("Is dlm missing from kernel? No misc devices found.");
+}
+
+static int find_udev_device(char *path, uint32_t minor)
+{
+	struct stat st;
+	int i;
+
+	for (i = 0; i < 10; i++) {
+		if (stat(path, &st) == 0 && minor(st.st_rdev) == minor)
+			return 0;
+		sleep(1);
+	}
+
+	log_error("cannot find device %s with minor %d", path, minor);
+	return -1;
+}
+
+int setup_misc_devices(void)
+{
+	int rv;
+
+	find_minors();
+
+	if (control_minor) {
+		rv = find_udev_device("/dev/misc/dlm-control", control_minor);
+		if (rv < 0)
+			return rv;
+		log_debug("found /dev/misc/dlm-control minor %u",
+			  control_minor);
+	}
+
+	if (monitor_minor) {
+		rv = find_udev_device("/dev/misc/dlm-monitor", monitor_minor);
+		if (rv < 0)
+			return rv;
+		log_debug("found /dev/misc/dlm-monitor minor %u",
+			  monitor_minor);
+	}
+
+	if (plock_minor) {
+		rv = find_udev_device("/dev/misc/dlm_plock", plock_minor);
+		if (rv < 0)
+			return rv;
+		log_debug("found /dev/misc/dlm_plock minor %u",
+			  plock_minor);
+	}
+
+	if (old_plock_minor) {
+		rv = find_udev_device("/dev/misc/lock_dlm_plock",
+				      old_plock_minor);
+		if (rv < 0)
+			return rv;
+		log_debug("found /dev/misc/lock_dlm_plock minor %u",
+			  old_plock_minor);
+	}
+
+	return 0;
+}
+
diff --git a/group/dlm_controld/dlm_daemon.h b/group/dlm_controld/dlm_daemon.h
index 0b3feb9..3a4b31c 100644
--- a/group/dlm_controld/dlm_daemon.h
+++ b/group/dlm_controld/dlm_daemon.h
@@ -83,6 +83,10 @@ extern int dump_wrap;
 extern char plock_dump_buf[DLMC_DUMP_SIZE];
 extern int plock_dump_len;
 extern int group_mode;
+extern uint32_t control_minor;
+extern uint32_t monitor_minor;
+extern uint32_t plock_minor;
+extern uint32_t old_plock_minor;
 
 void daemon_dump_save(void);
 
@@ -218,6 +222,7 @@ void del_configfs_node(int nodeid);
 void clear_configfs(void);
 int setup_configfs(void);
 int check_uncontrolled_lockspaces(void);
+int setup_misc_devices(void);
 
 /* config.c */
 int setup_ccs(void);
diff --git a/group/dlm_controld/main.c b/group/dlm_controld/main.c
index afa590d..d712b88 100644
--- a/group/dlm_controld/main.c
+++ b/group/dlm_controld/main.c
@@ -18,6 +18,7 @@ static struct pollfd *pollfd = NULL;
 static pthread_t query_thread;
 static pthread_mutex_t query_mutex;
 static struct list_head fs_register_list;
+static int kernel_monitor_fd;
 
 struct client {
 	int fd;
@@ -840,6 +841,20 @@ static int setup_queries(void)
 	return 0;
 }
 
+/* The dlm in kernels before 2.6.28 do not have the monitor device.  We
+   keep this fd open as long as we're running.  If we exit/terminate while
+   lockspaces exist in the kernel, the kernel will detect a close on this
+   fd and stop the lockspaces. */
+
+static void setup_monitor(void)
+{
+	if (!monitor_minor)
+		return;
+
+	kernel_monitor_fd = open("/dev/misc/dlm-monitor", O_RDONLY);
+	log_debug("/dev/misc/dlm-monitor fd %d", kernel_monitor_fd);
+}
+
 void cluster_dead(int ci)
 {
 	log_error("cluster is down, exiting");
@@ -877,6 +892,12 @@ static void loop(void)
 	if (rv < 0)
 		goto out;
 
+	rv = setup_misc_devices();
+	if (rv < 0)
+		goto out;
+
+	setup_monitor();
+
 	rv = setup_configfs();
 	if (rv < 0)
 		goto out;
@@ -1275,4 +1296,8 @@ int dump_wrap;
 char plock_dump_buf[DLMC_DUMP_SIZE];
 int plock_dump_len;
 int group_mode;
+uint32_t control_minor;
+uint32_t monitor_minor;
+uint32_t plock_minor;
+uint32_t old_plock_minor;
 
diff --git a/group/dlm_controld/plock.c b/group/dlm_controld/plock.c
index e9a47ce..3a95caf 100644
--- a/group/dlm_controld/plock.c
+++ b/group/dlm_controld/plock.c
@@ -3,12 +3,6 @@
 
 #include <linux/dlm_plock.h>
 
-#define PROC_MISC               "/proc/misc"
-#define PROC_DEVICES            "/proc/devices"
-#define MISC_NAME               "misc"
-#define CONTROL_DIR             "/dev/misc"
-#define CONTROL_NAME            "dlm_plock"
-
 static uint32_t plock_read_count;
 static uint32_t plock_recv_count;
 static uint32_t plock_rate_delays;
@@ -16,7 +10,7 @@ static struct timeval plock_read_time;
 static struct timeval plock_recv_time;
 static struct timeval plock_rate_last;
 
-static int control_fd = -1;
+static int plock_device_fd = -1;
 static SaCkptHandleT system_ckpt_handle;
 static SaCkptCallbacksT callbacks = { 0, 0 };
 static SaVersionT version = { 'B', 1, 1 };
@@ -144,133 +138,6 @@ static char *ex_str(int optype, int ex)
 		return "RD";
 }
 
-static int get_proc_number(const char *file, const char *name, uint32_t *number)
-{
-	FILE *fl;
-	char nm[256];
-	int c;
-
-	if (!(fl = fopen(file, "r"))) {
-		log_error("%s: fopen failed: %s", file, strerror(errno));
-		return 0;
-	}
-
-	while (!feof(fl)) {
-		if (fscanf(fl, "%d %255s\n", number, &nm[0]) == 2) {
-			if (!strcmp(name, nm)) {
-				fclose(fl);
-				return 1;
-			}
-		} else do {
-			c = fgetc(fl);
-		} while (c != EOF && c != '\n');
-	}
-	fclose(fl);
-
-	log_error("%s: No entry for %s found", file, name);
-	return 0;
-}
-
-static int control_device_number(const char *plock_misc_name,
-				 uint32_t *major, uint32_t *minor)
-{
-	if (!get_proc_number(PROC_DEVICES, MISC_NAME, major) ||
-	    !get_proc_number(PROC_MISC, plock_misc_name, minor)) {
-		*major = 0;
-		return 0;
-	}
-
-	return 1;
-}
-
-/*
- * Returns 1 if exists; 0 if it doesn't; -1 if it's wrong
- */
-static int control_exists(const char *control, uint32_t major, uint32_t minor)
-{
-	struct stat buf;
-
-	if (stat(control, &buf) < 0) {
-		if (errno != ENOENT)
-			log_error("%s: stat failed: %s", control,
-				  strerror(errno));
-		return 0;
-	}
-
-	if (!S_ISCHR(buf.st_mode)) {
-		log_error("%s: Wrong inode type", control);
-		if (!unlink(control))
-			return 0;
-		log_error("%s: unlink failed: %s", control, strerror(errno));
-		return -1;
-	}
-
-	if (major && buf.st_rdev != makedev(major, minor)) {
-		log_error("%s: Wrong device number: (%u, %u) instead of "
-			  "(%u, %u)", control, major(buf.st_mode),
-			  minor(buf.st_mode), major, minor);
-		if (!unlink(control))
-			return 0;
-		log_error("%s: unlink failed: %s", control, strerror(errno));
-		return -1;
-	}
-
-	return 1;
-}
-
-static int create_control(const char *control, uint32_t major, uint32_t minor)
-{
-	int ret;
-	mode_t old_umask;
-
-	if (!major)
-		return 0;
-
-	old_umask = umask(0022);
-	ret = mkdir(CONTROL_DIR, 0777);
-	umask(old_umask);
-	if (ret < 0 && errno != EEXIST) {
-		log_error("%s: mkdir failed: %s", CONTROL_DIR, strerror(errno));
-		return 0;
-	}
-
-	if (mknod(control, S_IFCHR | S_IRUSR | S_IWUSR, makedev(major, minor)) < 0) {
-		log_error("%s: mknod failed: %s", control, strerror(errno));
-		return 0;
-	}
-
-	return 1;
-}
-
-static int open_control(const char *control_name, const char *plock_misc_name)
-{
-	char control[PATH_MAX];
-	uint32_t major = 0, minor = 0;
-
-	if (control_fd != -1)
-		return 0;
-
-	snprintf(control, sizeof(control), "%s/%s", CONTROL_DIR, control_name);
-
-	if (!control_device_number(plock_misc_name, &major, &minor))
-		return -1;
-
-	if (!control_exists(control, major, minor) &&
-	    !create_control(control, major, minor)) {
-		log_error("Failure to create device file %s", control);
-		return -1;
-	}
-
-	control_fd = open(control, O_RDWR);
-	if (control_fd < 0) {
-		log_error("Failure to open device %s: %s", control,
-			  strerror(errno));
-		return -1;
-	}
-
-	return 0;
-}
-
 /*
  * In kernels before 2.6.26, plocks came from gfs2's lock_dlm module.
  * Reading plocks from there as well should allow us to use cluster3
@@ -278,13 +145,9 @@ static int open_control(const char *control_name, const char *plock_misc_name)
  * structs is the mountgroup id, which we need to translate to the ls id.
  */
 
-#define OLD_CONTROL_NAME "lock_dlm_plock"
-#define OLD_PLOCK_MISC_NAME "lock_dlm_plock"
-
 int setup_plocks(void)
 {
 	SaAisErrorT err;
-	int rv;
 
 	plock_read_count = 0;
 	plock_recv_count = 0;
@@ -302,24 +165,25 @@ int setup_plocks(void)
 		   send ENOSYS back to the kernel if it tries to do a plock */
 	}
 
-
-	rv = open_control(CONTROL_NAME, DLM_PLOCK_MISC_NAME);
-	if (rv) {
-		log_debug("setup_plocks trying old lock_dlm interface");
-		rv = open_control(OLD_CONTROL_NAME, OLD_PLOCK_MISC_NAME);
-		if (rv) {
-			log_error("Is dlm missing from kernel?  No control device.");
-			return rv;
-		}
+	if (plock_minor) {
+		plock_device_fd = open("/dev/misc/dlm_plock", O_RDWR);
+	} else if (old_plock_minor) {
+		log_debug("setup_plocks using old lock_dlm interface");
 		need_fsid_translation = 1;
+		plock_device_fd = open("/dev/misc/lock_dlm_plock", O_RDWR);
 	}
 
-	log_debug("plocks %d", control_fd);
+	if (plock_device_fd < 0) {
+		log_error("Failure to open plock device: %s", strerror(errno));
+		return -1;
+	}
+
+	log_debug("plocks %d", plock_device_fd);
 	log_debug("plock cpg message size: %u bytes",
 		  (unsigned int) (sizeof(struct dlm_header) +
 		                  sizeof(struct dlm_plock_info)));
 
-	return control_fd;
+	return plock_device_fd;
 }
 
 static uint32_t mg_to_ls_id(uint32_t fsid)
@@ -775,7 +639,7 @@ static void write_result(struct lockspace *ls, struct dlm_plock_info *in,
 		in->fsid = ls->associated_mg_id;
 
 	in->rv = rv;
-	write(control_fd, in, sizeof(struct dlm_plock_info));
+	write(plock_device_fd, in, sizeof(struct dlm_plock_info));
 }
 
 static void do_waiters(struct lockspace *ls, struct resource *r)
@@ -1557,10 +1421,10 @@ void process_plocks(int ci)
 
 	memset(&info, 0, sizeof(info));
 
-	rv = do_read(control_fd, &info, sizeof(info));
+	rv = do_read(plock_device_fd, &info, sizeof(info));
 	if (rv < 0) {
 		log_debug("process_plocks: read error %d fd %d\n",
-			  errno, control_fd);
+			  errno, plock_device_fd);
 		return;
 	}
 
@@ -1631,7 +1495,7 @@ void process_plocks(int ci)
 
  fail:
 	info.rv = rv;
-	rv = write(control_fd, &info, sizeof(info));
+	rv = write(plock_device_fd, &info, sizeof(info));
 }
 
 void process_saved_plocks(struct lockspace *ls)
@@ -2283,22 +2147,3 @@ int fill_plock_dump_buf(struct lockspace *ls)
 	return rv;
 }
 
-#if 0
-/* replace all of the above with this to build on 2.6.25 kernels */
-
-int setup_plocks(void) { return 0; };
-void process_plocks(int ci) { };
-int limit_plocks(void) { return 0; };
-void receive_plock(struct lockspace *ls, struct dlm_header *hd, int len) { };
-void receive_own(struct lockspace *ls, struct dlm_header *hd, int len) { };
-void receive_sync(struct lockspace *ls, struct dlm_header *hd, int len) { };
-void receive_drop(struct lockspace *ls, struct dlm_header *hd, int len) { };
-void process_saved_plocks(struct lockspace *ls) { };
-void close_plock_checkpoint(struct lockspace *ls) { };
-void store_plocks(struct lockspace *ls) { };
-void retrieve_plocks(struct lockspace *ls) { };
-void purge_plocks(struct lockspace *ls, int nodeid, int unmount) { };
-int dump_plocks(char *name, int fd) { return 0; };
-
-#endif
-


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2008-08-19 19:53 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-08-19 21:02 master - dlm_controld: open dlm-monitor misc device David Teigland

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).