All of lore.kernel.org
 help / color / mirror / Atom feed
From: lhh@sourceware.org <lhh@sourceware.org>
To: cluster-devel.redhat.com
Subject: [Cluster-devel] cluster/rgmanager ChangeLog include/resgroup.h ...
Date: 27 Apr 2007 18:10:12 -0000	[thread overview]
Message-ID: <20070427181012.1955.qmail@sourceware.org> (raw)

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@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@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;



             reply	other threads:[~2007-04-27 18:10 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-04-27 18:10 lhh [this message]
  -- strict thread matches above, loose matches on Subject: below --
2007-12-30  8:27 [Cluster-devel] cluster/rgmanager ChangeLog include/resgroup.h fabbione
2007-12-14 19:37 lhh
2007-11-30 20:36 lhh
2007-06-27 14:03 lhh
2007-06-26 21:55 lhh
2007-06-14 15:06 mgrac
2007-06-14 13:36 mgrac
2006-10-06 21:22 lhh
2006-09-01 19:02 lhh
2006-08-18 15:26 lhh

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20070427181012.1955.qmail@sourceware.org \
    --to=lhh@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.