[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[Cluster-devel] RFC: cman_wait_init rework



Hi guys,

I just spotted one major issue with the basic implementation of
cman_wait_init. Basically we don't provide the user any kind
of information about the status and this is bad IMHO.

So I have been thinking a bit about it and I see 2 solutions to
the problem:

One is to just revert the original patch and let the clients use
the actual code for cman_init and cman_admin_init.

Two is to complete cman_wait_init with something similar to the patch
in attachment. As an example I have converted qdisk to use it (patch is untested
and qdisk is kind of a special case because it retains backwards compatibility
with older versions of cman, so look at it in the full context of the code).
You can see that the code is generally simplified and the client can retain as
much control as they want.

The basic idea is to provide the option to hook two (optionals) callbacks that
are invoked in each loop (waiting for cman or quorum).

If we will go this route, i want to extend this patch to allow the callbacks to
either modify/reset the loops or return some values to break the loops.

Cheers
Fabio
Index: cman/lib/libcman.c
===================================================================
RCS file: /cvs/cluster/cluster/cman/lib/libcman.c,v
retrieving revision 1.38
diff -u -r1.38 libcman.c
--- cman/lib/libcman.c	5 Nov 2007 16:43:50 -0000	1.38
+++ cman/lib/libcman.c	8 Nov 2007 21:53:33 -0000
@@ -359,12 +359,19 @@
  * @admin: set to 0 for standard socket, != 0 for admin socket
  * @ctimeout: connection timeout in second to attempt to connect to cman.
  *            0 = wait forever, -1 = do not wait.
+ * @ccallback: register a notification call back while waiting for cman to
+ * 	      appear and called with number of seconds/loops that have been
+ * 	      done so far.
  * @qtimeout: cluster quorum timeout in second.
  *            0 = wait forever, -1 = do not wait.
+ * @qcallback: equivalent to ccallback but applies while waiting for quorum.
  * @privdata: see cman_admin_init and cman_init.
  */
 
-cman_handle_t cman_wait_init(int admin, int ctimeout, int qtimeout, void *privdata)
+cman_handle_t cman_wait_init(int admin,
+				int ctimeout, void (*ccallback)(int loops),
+				int qtimeout, void (*qcallback)(int loops),
+				void *privdata)
 {
 	cman_handle_t ch;
 	int i = 0;
@@ -385,6 +392,9 @@
 		} else {
 			sleep(1);
 			i++;
+
+			if (ccallback)
+				ccallback(i);
 		}
 	}
 
@@ -403,6 +413,9 @@
 		} else {
 			sleep(1);
 			i++;
+
+			if (qcallback)
+				qcallback(i);
 		}
 	}
 
Index: cman/lib/libcman.h
===================================================================
RCS file: /cvs/cluster/cluster/cman/lib/libcman.h,v
retrieving revision 1.36
diff -u -r1.36 libcman.h
--- cman/lib/libcman.h	5 Nov 2007 16:43:50 -0000	1.36
+++ cman/lib/libcman.h	8 Nov 2007 21:53:33 -0000
@@ -203,7 +203,7 @@
  */
 cman_handle_t cman_init(void *privdata);
 cman_handle_t cman_admin_init(void *privdata);
-cman_handle_t cman_wait_init(int admin, int ctimeout, int qtimeout, void *privdata);
+cman_handle_t cman_wait_init(int admin, int ctimeout, void (*ccallback)(int loops), int qtimeout, void (*qcallback)(int loops), void *privdata);
 int cman_finish(cman_handle_t handle);
 
 /* Update/retrieve the private data */
Index: cman/qdisk/main.c
===================================================================
RCS file: /cvs/cluster/cluster/cman/qdisk/main.c,v
retrieving revision 1.11
diff -u -r1.11 main.c
--- cman/qdisk/main.c	1 Nov 2007 00:25:28 -0000	1.11
+++ cman/qdisk/main.c	8 Nov 2007 21:53:34 -0000
@@ -1394,6 +1394,10 @@
 	}
 }
 
+void wait_for_cman(int i)
+{
+	printf("Waiting for cman\n");
+}
 
 int
 main(int argc, char **argv)
@@ -1437,12 +1441,31 @@
 			break;
 		}
 	}
-	
+
 #if (defined(LIBCMAN_VERSION) && LIBCMAN_VERSION >= 2)
-	ch = cman_admin_init(NULL);
+	/* use new cman_wait_init.
+	 * use admin socket
+	 * wait 10 seconds
+	 * don't wait for quorum
+	 * no priv data
+	 */
+	ch = cman_wait_init(1, 10, &wait_for_cman, 0, NULL, NULL);
+
+	if (!foreground && !forked) {
+		if (daemon_init(argv[0]) < 0)
+			return -1;
+		else
+			forked = 1;
+	}
+
+	/* we wait forever if we don't get a handler */
+	if (!ch)
+		ch =  cman_wait_init(1, 0, &wait_for_cman, 0, NULL, NULL);
+
+	memset(&me, 0, sizeof(me));
+	cman_get_node(ch, CMAN_NODEID_US, &me);
 #else
 	ch = cman_init(NULL);
-#endif
 	if (!ch) {
 		if (!foreground && !forked) {
 			if (daemon_init(argv[0]) < 0)
@@ -1450,16 +1473,12 @@
 			else
 				forked = 1;
 		}
-		
+
 		clulog(LOG_INFO, "Waiting for CMAN to start\n");
-		
+
 		do {
 			sleep(5);
-#if (defined(LIBCMAN_VERSION) && LIBCMAN_VERSION >= 2)
-			ch = cman_admin_init(NULL);
-#else
 			ch = cman_init(NULL);
-#endif
 		} while (!ch);
 	}
 
@@ -1473,7 +1492,7 @@
 		}
 		sleep(5);
 	}
-
+#endif
 	qd_init(&ctx, ch, me.cn_nodeid);
 
 	signal(SIGINT, int_handler);

[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]