[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