[Cluster-devel] cluster/rgmanager ChangeLog include/resgroup.h ...

lhh at sourceware.org lhh at sourceware.org
Fri Apr 27 18:10:12 UTC 2007


CVSROOT:	/cvs/cluster
Module name:	cluster
Changes by:	lhh at sourceware.org	2007-04-27 19:10:10

Modified files:
	rgmanager      : ChangeLog 
	rgmanager/include: resgroup.h 
	rgmanager/src/clulib: rg_strings.c 
	rgmanager/src/daemons: groups.c rg_state.c rg_thread.c 
	rgmanager/src/utils: clustat.c clusvcadm.c 
Added files:
	rgmanager/src/daemons: sbuf.c 

Log message:
	Add patch from Simone Gotti to implement service freeze/unfreeze.  Add simple buffer handling for later use.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/rgmanager/ChangeLog.diff?cvsroot=cluster&r1=1.39&r2=1.40
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/rgmanager/include/resgroup.h.diff?cvsroot=cluster&r1=1.19&r2=1.20
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/rgmanager/src/clulib/rg_strings.c.diff?cvsroot=cluster&r1=1.7&r2=1.8
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/rgmanager/src/daemons/sbuf.c.diff?cvsroot=cluster&r1=NONE&r2=1.1
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/rgmanager/src/daemons/groups.c.diff?cvsroot=cluster&r1=1.31&r2=1.32
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/rgmanager/src/daemons/rg_state.c.diff?cvsroot=cluster&r1=1.31&r2=1.32
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/rgmanager/src/daemons/rg_thread.c.diff?cvsroot=cluster&r1=1.19&r2=1.20
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/rgmanager/src/utils/clustat.c.diff?cvsroot=cluster&r1=1.31&r2=1.32
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/rgmanager/src/utils/clusvcadm.c.diff?cvsroot=cluster&r1=1.18&r2=1.19

--- cluster/rgmanager/ChangeLog	2007/04/27 04:23:05	1.39
+++ cluster/rgmanager/ChangeLog	2007/04/27 18:10:07	1.40
@@ -1,3 +1,10 @@
+2007-04-27 Lon Hohberger <lhh at redhat.com>
+	* include/resgroup.h, src/clulib/rg_strings.c src/daemons/groups.c,
+	rg_state.c, rg_thread.c, src/utils/clustat.c, clusvcadm.c: Apply
+	patch to implement service freeze/unfreeze from Simone Gotti
+	* src/daemons/sbuf.c: Add simple buffer handlers for future use
+	by svc_status_inquiry
+
 2007-04-27 Fabio M. Di Nitto <fabbione at ubuntu.com>
 	* src/clulib/vft.c: Change ifdef to fix build on parisc.
 
--- cluster/rgmanager/include/resgroup.h	2007/03/20 17:09:56	1.19
+++ cluster/rgmanager/include/resgroup.h	2007/04/27 18:10:07	1.20
@@ -35,6 +35,7 @@
 	uint32_t	rs_restarts;	/**< Number of cluster-induced 
 					     restarts */
 	uint64_t	rs_transition;	/**< Last service transition time */
+	uint32_t	rs_flags;	/**< User setted flags */
 } rg_state_t;
 
 #define swab_rg_state_t(ptr) \
@@ -46,6 +47,7 @@
 	swab32((ptr)->rs_state);\
 	swab32((ptr)->rs_restarts);\
 	swab64((ptr)->rs_transition);\
+	swab32((ptr)->rs_flags);\
 }
 
 
@@ -79,6 +81,8 @@
 #define RG_UNLOCK	  20
 #define RG_QUERY_LOCK	  21
 #define RG_MIGRATE	  22
+#define RG_FREEZE	  23
+#define RG_UNFREEZE	  24
 #define RG_NONE		  999
 
 const char *rg_req_str(int req);
@@ -105,7 +109,11 @@
 
 #define DEFAULT_CHECK_INTERVAL		10
 
+/* Resource group flags (for now) */
+#define RG_FLAG_FROZEN			(1<<0)	/** Resource frozen */
+
 const char *rg_state_str(int val);
+const char *rg_flags_str(char *flags_string, size_t size, int val, char *separator);
 const char *agent_op_str(int val);
 
 int eval_groups(int local, uint32_t nodeid, int nodeStatus);
@@ -121,6 +129,8 @@
 int svc_status(char *svcName);
 int svc_disable(char *svcName);
 int svc_fail(char *svcName);
+int svc_freeze(char *svcName);
+int svc_unfreeze(char *svcName);
 int svc_migrate(char *svcName, int target);
 int rt_enqueue_request(const char *resgroupname, int request,
 		       msgctx_t *resp_ctx,
@@ -162,6 +172,7 @@
 int my_id(void);
 
 /* Return codes */
+#define RG_EFROZEN	-11		/* Service is frozen */
 #define RG_ERUN		-10		/* Service is already running */
 #define RG_EQUORUM	-9		/* Operation requires quorum */
 #define RG_EINVAL	-8		/* Invalid operation for resource */
--- cluster/rgmanager/src/clulib/rg_strings.c	2007/03/10 00:20:54	1.7
+++ cluster/rgmanager/src/clulib/rg_strings.c	2007/04/27 18:10:10	1.8
@@ -35,6 +35,7 @@
 	{ RG_ENOSERVICE,"Service does not exist" },
 	{ RG_EFORWARD,	"Service not mastered locally" },
 	{ RG_EABORT,	"Aborted; service failed" },
+	{ RG_EFROZEN,	"Failure: Service is frozen"},
 	{ RG_EFAIL,	"Failure" },
 	{ RG_ESUCCESS,	"Success" },
 	{ RG_YES,	"Yes" },
@@ -88,6 +89,12 @@
 };
 
 
+const struct string_val rg_flags_strings[] = {
+	{RG_FLAG_FROZEN, "frozen"},
+	{0, NULL}
+};
+
+
 const struct string_val agent_ops[] = {
 	{RS_START, "start"},
 	{RS_STOP, "stop"},
@@ -122,6 +129,20 @@
 }
 
 
+static inline const char *
+rg_flag_search_table(const struct string_val *table, int val)
+{
+	int x;
+
+	for (x = 0; table[x].str != NULL; x++) {
+		if (table[x].val == val) {
+			return table[x].str;
+		}
+	}
+
+	return "Unknown";
+}
+
 const char *
 rg_strerror(int val)
 {
@@ -134,6 +155,22 @@
 	return rg_search_table(rg_state_strings, val);
 }
 
+const char *
+rg_flags_str(char *flags_string, size_t size, int val, char *separator)
+{
+	int i;
+	const char *string;
+
+	for (i = 0; i < sizeof(uint32_t); i++) {
+		if ( val & (1 << i)) {
+			if (strlen(flags_string))
+				strncat(flags_string, separator, size - (strlen(flags_string) + strlen(separator) + 1));
+			string = rg_search_table(rg_flags_strings, (1 << i));
+			strncat(flags_string, string, size - (strlen(flags_string) + strlen(string) + 1));
+		}
+	}
+	return flags_string;
+}
 
 const char *
 rg_req_str(int val)
/cvs/cluster/cluster/rgmanager/src/daemons/sbuf.c,v  -->  standard output
revision 1.1
--- cluster/rgmanager/src/daemons/sbuf.c
+++ -	2007-04-27 19:10:12.507518000 +0100
@@ -0,0 +1,85 @@
+#include <string.h>
+#include <sys/types.h>
+#include <stdio.h>
+#include <errno.h>
+
+struct _retbuf {
+	char *data;
+	ssize_t maxsize;
+	ssize_t cursize;
+	char magic[8];
+};
+
+static char _x_buf_magic[]="m461kz31";
+
+void *
+buf_init(void *buf, size_t len)
+{
+	struct _retbuf *b = (struct _retbuf *)buf;
+
+	errno = EINVAL;
+	if (!len || !buf)
+		return NULL;
+	if (len < sizeof(*b) + 16)
+		return NULL;
+
+	memset(b, 0, len);
+	b->data = buf + sizeof(*b);
+	b->maxsize = len - sizeof (*b);
+	b->cursize = 0;
+	memcpy(b->magic, _x_buf_magic, sizeof(b->magic));
+
+	return buf;
+}
+
+ssize_t
+buf_append(void *buf, char *info)
+{
+	struct _retbuf *b = (struct _retbuf *)buf;
+	ssize_t len;
+
+	errno = EINVAL;
+	if (!buf)
+		return -1;
+	if (memcmp(b->magic, _x_buf_magic, sizeof(b->magic)))
+		return -1;
+	if (!info)
+		return 0;
+       	len = strlen(info);
+	if (!len)
+		return 0;
+
+	errno = ENOSPC;
+	if (b->maxsize - b->cursize < len)
+		return -1;
+
+	memcpy(&(b->data[b->cursize]), info, len);
+	b->cursize += len;
+	return len;
+}
+
+char *
+buf_data(void *buf)
+{
+	struct _retbuf *b = (struct _retbuf *)buf;
+	errno = EINVAL;
+	if (!buf)
+		return NULL;
+	if (memcmp(b->magic, _x_buf_magic, sizeof(b->magic)))
+		return NULL;
+	return ((struct _retbuf *)buf)->data;
+}
+
+
+int
+buf_finished(void *buf)
+{
+	struct _retbuf *b = (struct _retbuf *)buf;
+	errno = EINVAL;
+	if (!buf)
+		return -1;
+	if (memcmp(b->magic, _x_buf_magic, sizeof(b->magic)))
+		return -1;
+	memset(b->magic, 0, sizeof(b->magic));
+	return 0;
+}
--- cluster/rgmanager/src/daemons/groups.c	2007/04/19 17:59:36	1.31
+++ cluster/rgmanager/src/daemons/groups.c	2007/04/27 18:10:10	1.32
@@ -376,6 +376,9 @@
 	mp = memb_id_to_p(membership, my_id());
 	assert(mp);
 
+	/* Service cannot be started if Frozen */
+	if (svcStatus->rs_flags & RG_FLAG_FROZEN)
+		return;
 	/*
 	 * Service must be not be running elsewhere to consider for a
 	 * local start.
--- cluster/rgmanager/src/daemons/rg_state.c	2007/04/19 17:59:36	1.31
+++ cluster/rgmanager/src/daemons/rg_state.c	2007/04/27 18:10:10	1.32
@@ -282,6 +282,7 @@
 	svcblk->rs_owner = 0;
 	svcblk->rs_last_owner = 0;
 	svcblk->rs_state = RG_STATE_STOPPED;
+       	svcblk->rs_flags = 0;
        	svcblk->rs_restarts = 0;
 	svcblk->rs_transition = 0;	
 	strncpy(svcblk->rs_name, name, sizeof(svcblk->rs_name));
@@ -418,6 +419,7 @@
 		svcblk->rs_owner = 0;
 		svcblk->rs_last_owner = 0;
 		svcblk->rs_state = RG_STATE_UNINITIALIZED;
+       		svcblk->rs_flags = 0;
        		svcblk->rs_restarts = 0;
 		svcblk->rs_transition = 0;	
 		strncpy(svcblk->rs_name, name, sizeof(svcblk->rs_name));
@@ -446,6 +448,7 @@
  *			2 = DO NOT stop service, return 0 (success)
  *                      3 = DO NOT stop service, return RG_EFORWARD
  *			4 = DO NOT stop service, return RG_EAGAIN
+ *			5 = DO NOT stop service, return RG_EFROZEN
  */
 int
 svc_advise_stop(rg_state_t *svcStatus, char *svcName, int req)
@@ -453,6 +456,11 @@
 	cluster_member_list_t *membership = member_list();
 	int ret = 0;
 	
+	if (svcStatus->rs_flags & RG_FLAG_FROZEN) {
+		clulog(LOG_DEBUG, "Service %s frozen.\n", svcName);
+		return 5;
+	}
+
 	switch(svcStatus->rs_state) {
 	case RG_STATE_FAILED:
 		if (req == RG_DISABLE)
@@ -568,6 +576,7 @@
  *			2 = DO NOT start service, return 0
  *			3 = DO NOT start service, return RG_EAGAIN
  *			4 = DO NOT start service, return RG_ERUN
+ *			5 = DO NOT start service, return RG_EFROZEN
  */
 int
 svc_advise_start(rg_state_t *svcStatus, char *svcName, int req)
@@ -575,6 +584,11 @@
 	cluster_member_list_t *membership = member_list();
 	int ret = 0;
 	
+	if (svcStatus->rs_flags & RG_FLAG_FROZEN) {
+		clulog(LOG_DEBUG, "Service %s frozen.\n", svcName);
+		return 5;
+	}
+
 	switch(svcStatus->rs_state) {
 	case RG_STATE_FAILED:
 		clulog(LOG_ERR,
@@ -752,6 +766,9 @@
 	case 4:
 		rg_unlock(&lockp);
 		return RG_ERUN;
+	case 5:
+		rg_unlock(&lockp);
+		return RG_EFROZEN;
 	default:
 		break;
 	}
@@ -914,6 +931,10 @@
 	}
 	rg_unlock(&lockp);
 
+	if (svcStatus.rs_flags & RG_FLAG_FROZEN)
+		/* Don't check status if the service is frozen */
+		return 0;
+
 	if (svcStatus.rs_owner != my_id())
 		/* Don't check status for anything not owned */
 		return 0;
@@ -961,6 +982,17 @@
 int
 svc_status_inquiry(char *svcName)
 {
+	rg_state_t svcStatus;
+
+	if (get_rg_state_local(svcName, &svcStatus) != 0) {
+		clulog(LOG_ERR, "Failed getting local status for RG %s\n",
+		       svcName);
+		return RG_EFAIL;
+	}
+
+	if (svcStatus.rs_flags & RG_FLAG_FROZEN)
+		return 0;
+	
 	return group_op(svcName, RG_STATUS);
 }
 
@@ -1015,6 +1047,9 @@
 	case 4:
 		rg_unlock(&lockp);
 		return RG_EAGAIN;
+	case 5:
+		rg_unlock(&lockp);
+		return RG_EFROZEN;
 	default:
 		break;
 	}
@@ -1191,6 +1226,76 @@
 	return 0;
 }
 
+/**
+ * Flag/Unflag a cluster service as frozen.
+ *
+ * @param svcName	Service ID to flag/unflag as frozen.
+ * @return		FAIL, 0
+ */
+int
+_svc_freeze(char *svcName, int enabled)
+{
+	struct dlm_lksb lockp;
+	rg_state_t svcStatus;
+
+	if (rg_lock(svcName, &lockp) == RG_EFAIL) {
+		clulog(LOG_ERR, "#55: Unable to obtain cluster lock: %s\n",
+		       strerror(errno));
+		return RG_EFAIL;
+	}
+
+	clulog(LOG_DEBUG, "Handling %s request for RG %s\n", svcName, enabled?"freeze":"unfreeze");
+
+	if (get_rg_state(svcName, &svcStatus) != 0) {
+		rg_unlock(&lockp);
+		clulog(LOG_ERR, "#56: Failed getting status for RG %s\n",
+		       svcName);
+		return RG_EFAIL;
+	}
+
+	switch(svcStatus.rs_state) {
+	case RG_STATE_STOPPED:
+	case RG_STATE_STARTED:
+	case RG_STATE_DISABLED:
+
+		if (enabled == 1) {
+			clulog(LOG_DEBUG, "Freezing RG %s\n", svcName);
+			svcStatus.rs_flags |= RG_FLAG_FROZEN;
+		} else {
+			clulog(LOG_DEBUG, "Unfreezing RG %s\n", svcName);
+			svcStatus.rs_flags &= ~RG_FLAG_FROZEN;
+		}
+
+		if (set_rg_state(svcName, &svcStatus) != 0) {
+			rg_unlock(&lockp);
+			clulog(LOG_ERR, "#57: Failed changing RG status\n");
+			return RG_EFAIL;
+		}
+		break;
+
+	default:
+		rg_unlock(&lockp);
+		return RG_EFAIL;
+		break;
+	}
+
+	rg_unlock(&lockp);
+
+	return 0;
+}
+
+int
+svc_freeze(char *svcName)
+{
+	return _svc_freeze(svcName, 1);
+}
+
+int
+svc_unfreeze(char *svcName)
+{
+	return _svc_freeze(svcName, 0);
+}
+
 
 /*
  * Send a message to the target node to start the service.
@@ -1324,6 +1429,9 @@
 			svc_fail(svcName);
 			return RG_EFAIL;
 		}
+		if (ret == RG_EFROZEN) {
+			return RG_EFROZEN;
+		}
 		if (ret == RG_EFORWARD)
 			return RG_EFORWARD;
 	}
@@ -1531,7 +1639,7 @@
 	/* 
 	   If services are locked, return the error 
 	  */
-	if (ret == RG_EAGAIN || ret == RG_ERUN)
+	if (ret == RG_EAGAIN || ret == RG_ERUN || ret == RG_EFROZEN)
 		return ret;
 
 	/*
--- cluster/rgmanager/src/daemons/rg_thread.c	2007/03/27 19:33:20	1.19
+++ cluster/rgmanager/src/daemons/rg_thread.c	2007/04/27 18:10:10	1.20
@@ -422,6 +422,18 @@
 
 			break;
 
+		case RG_FREEZE:
+			error = svc_freeze(myname);
+			if (error != 0)
+				ret = RG_EFAIL;
+			break;
+
+		case RG_UNFREEZE:
+			error = svc_unfreeze(myname);
+			if (error != 0)
+				ret = RG_EFAIL;
+			break;
+
 		default:
 			printf("Unhandled request %d\n", req->rr_request);
 			ret = RG_NONE;
--- cluster/rgmanager/src/utils/clustat.c	2007/02/06 20:21:17	1.31
+++ cluster/rgmanager/src/utils/clustat.c	2007/04/27 18:10:10	1.32
@@ -416,7 +416,7 @@
 _txt_rg_state(rg_state_t *rs, cluster_member_list_t *members, int flags)
 {
 	char owner[31];
-
+	char flags_string[255] = "";
 
 	if (rs->rs_state == RG_STATE_STOPPED ||
 	    rs->rs_state == RG_STATE_DISABLED ||
@@ -430,19 +430,34 @@
 		snprintf(owner, sizeof(owner), "%-.30s",
 			 my_memb_id_to_name(members, rs->rs_owner));
 	}
-	printf("  %-20.20s %-30.30s %-16.16s\n",
+	rg_flags_str(flags_string, sizeof(flags_string), rs->rs_flags, ", ");
+	printf("  %-20.20s %-30.30s %-16.16s ",
 	       rs->rs_name,
 	       owner,
 	       rg_state_str(rs->rs_state));
+	if(strlen(flags_string))
+		printf ("%-30.30s\n", flags_string);
+	else
+		printf("\n");
 }
 
 
 void
 _txt_rg_state_v(rg_state_t *rs, cluster_member_list_t *members, int flags)
 {
+	char flags_string[255] = "";
+
+	rg_flags_str(flags_string, sizeof(flags_string), rs->rs_flags, ", ");
+
 	printf("Service Name      : %s\n", rs->rs_name);
 	printf("  Current State   : %s (%d)\n",
 	       rg_state_str(rs->rs_state), rs->rs_state);
+	if (rs->rs_flags)
+		printf("  Flags           : %s (%d)\n",
+		       flags_string, rs->rs_flags);
+	else
+		printf("  Flags           : none (%d)\n",
+		       rs->rs_flags);
 	printf("  Owner           : %s\n",
 	       my_memb_id_to_name(members, rs->rs_owner));
 	printf("  Last Owner      : %s\n",
@@ -466,6 +481,7 @@
 xml_rg_state(rg_state_t *rs, cluster_member_list_t *members, int flags)
 {
 	char time_str[32];
+	char flags_string[255] = "";
 	int x;
 
 	/* Chop off newlines */
@@ -477,12 +493,15 @@
 		}
 	}
 
-	printf("    <group name=\"%s\" state=\"%d\" state_str=\"%s\" "
+	printf("    <group name=\"%s\" state=\"%d\" state_str=\"%s\""
+	       " flags=\"%d\" flags_str=\"%s\""
 	       " owner=\"%s\" last_owner=\"%s\" restarts=\"%d\""
 	       " last_transition=\"%llu\" last_transition_str=\"%s\"/>\n",
 	       rs->rs_name,
 	       rs->rs_state,
 	       rg_state_str(rs->rs_state),
+	       rs->rs_flags,
+	       rg_flags_str(flags_string, sizeof(flags_string), rs->rs_flags, " "),
 	       my_memb_id_to_name(members, rs->rs_owner),
 	       my_memb_id_to_name(members, rs->rs_last_owner),
 	       rs->rs_restarts,
@@ -504,10 +523,10 @@
 		ret = -1;
 
 	if (!(flags & RG_VERBOSE)) {
-		printf("  %-20.20s %-30.30s %-14.14s\n",
-		       "Service Name", "Owner (Last)", "State");
-		printf("  %-20.20s %-30.30s %-14.14s\n",
-		       "------- ----", "----- ------", "-----");
+		printf("  %-20.20s %-30.30s %-16.16s %-30.30s\n",
+		       "Service Name", "Owner (Last)", "State", "Flags");
+		printf("  %-20.20s %-30.30s %-16.16s %-30.30s\n",
+		       "------- ----", "----- ------", "-----", "-----");
 	} else {
 		printf("Service Information\n"
 		       "------- -----------\n\n");
--- cluster/rgmanager/src/utils/clusvcadm.c	2007/03/20 17:09:57	1.18
+++ cluster/rgmanager/src/utils/clusvcadm.c	2007/04/27 18:10:10	1.19
@@ -240,7 +240,7 @@
 		return 1;
 	}
 
-	while ((opt = getopt(argc, argv, "lSue:M:d:r:n:m:vR:s:qh?")) != EOF) {
+	while ((opt = getopt(argc, argv, "lSue:M:d:r:n:m:vR:s:F:U:qh?")) != EOF) {
 		switch (opt) {
 		case 'l':
 			return do_lock();
@@ -294,6 +294,16 @@
 		case 'v':
 			printf("%s\n",PACKAGE_VERSION);
 			return 0;
+		case 'F':
+			actionstr = "freezing";
+			action = RG_FREEZE;
+			svcname = optarg;
+			break;
+		case 'U':
+			actionstr = "unfreezing";
+			action = RG_UNFREEZE;
+			svcname = optarg;
+			break;
 		case 'q':
 			close(STDOUT_FILENO);
 			break;




More information about the Cluster-devel mailing list