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

Re: [Linux-cluster] cluster service development - question



On Tue, 2005-10-04 at 12:40 -0400, Lon Hohberger wrote:
> On Tue, 2005-10-04 at 17:50 +0200, Christian Niessner wrote:
> > hi,
> > 
> > i'm currently developing a cluster service for the cluster release 
> > 1.00.00. It's using libmagma for messaging and node membership 
> > maintainance, and these parts work really well.. But i also have to
> > maintain a list of all configured nodes.
> > 
> > What is the 'best practice' to get this list? (Node id and name would be
> > fine...) It doesn't seem do be possible with libmagma...

Ugh, I read this wrong.

Here you go.  It's part of a rewrite of clustat which has "how to get
this stuff from ccsd" built right in.  I haven't committed this yet, but
will soon as part of a larger clustat rewrite.

ccs_member_list() returns cluster_member_list_t *.

build_member_list does that, but compares it against who is in the
configuration (and in this case, who is running rgmanager).  It's kind
of hackish the way I'm overloading the cm_state field with a bunch of
bitflags, but it works.

-- Lon
#include <magma.h>
#include <ccs.h>

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#define FLAG_LOCAL 0x1
#define FLAG_UP    0x2
#define FLAG_RGMGR 0x4
#define FLAG_NOCFG 0x8	/* Shouldn't happen */


cluster_member_list_t *ccs_member_list(void)
{
	int desc;
	int x;
	char buf[128];
	char *name;
	cluster_member_list_t *ret = NULL;

	desc = ccs_connect();
	if (desc < 0) {
		return NULL;
	}

	x = 1;
	
	snprintf(buf, sizeof(buf),
		 "/cluster/clusternodes/clusternode[%d]/@name", x);
	while (ccs_get(desc, buf, &name) == 0) {
		if (!ret) {
			ret = malloc(cml_size(x));
			memset(ret, 0, cml_size(x));
			if (!ret) {
				perror("malloc");
				ccs_disconnect(desc);
				exit(1);
			}
		} else {
			ret = realloc(ret, cml_size(x));
			if (!ret) {
				perror("realloc");
				ccs_disconnect(desc);
				exit(1);
			}
		}

		memset(&ret->cml_members[x-1], 0, sizeof(cluster_member_t));
		strncpy(ret->cml_members[x-1].cm_name, name,
			sizeof(ret->cml_members[x-1].cm_name));
		free(name);

		ret->cml_count = x;
		++x;
		snprintf(buf, sizeof(buf),
			 "/cluster/clusternodes/clusternode[%d]/@name", x);
	}

	ccs_disconnect(desc);
	return ret;
}


void
flag_nodes(cluster_member_list_t *all, cluster_member_list_t *these,
	   uint8_t flag)
{
	int x;
	cluster_member_t *m;

	for (x=0; x<all->cml_count; x++) {

		m = memb_name_to_p(these, all->cml_members[x].cm_name);

		if (m) {
			all->cml_members[x].cm_id = m->cm_id;
			all->cml_members[x].cm_state |= flag;
		}
	}
}


cluster_member_list_t *
add_missing(cluster_member_list_t *all, cluster_member_list_t *these)
{
	int x, y;
	cluster_member_t *m, *new;

	for (x=0; x<these->cml_count; x++) {

		m = NULL;
        	for (y = 0; y < all->cml_count; y++) {
			if (!strcmp(all->cml_members[y].cm_name,
				    these->cml_members[x].cm_name))
                        	m = &all->cml_members[y];
		}

		if (!m) {
			printf("%s not found\n", these->cml_members[x].cm_name);
			/* WTF? It's not in our config */
			printf("realloc %d\n", (int)cml_size((all->cml_count+1)));
			all = realloc(all, cml_size((all->cml_count+1)));
			if (!all) {
				perror("realloc");
				exit(1);
			}
			
			new = &all->cml_members[all->cml_count];

			memcpy(new, &these->cml_members[x],
			       sizeof(cluster_member_t));

			if (new->cm_state == STATE_UP) {
				new->cm_state = FLAG_UP | FLAG_NOCFG;
			} else {
				new->cm_state = FLAG_NOCFG;
			}
			++all->cml_count;

		}
	}

	return all;
}


cluster_member_list_t *
build_member_list(uint64_t *lid)
{
	cluster_member_list_t *all, *part;
	cluster_member_t *m;
	int x;

	/* Get all members from ccs, and all members reported by the cluster
	   infrastructure */
	all = ccs_member_list();
	part = clu_member_list(NULL);
	msg_update(part); /* XXX magmamsg is awful. */

	/* Flag online nodes */
	flag_nodes(all, part, FLAG_UP);

	/* See if our config has anyone missed.  If so, flag them as missing 
	   from the config file */
	all = add_missing(all, part);

	/* Grab the local node ID and flag it from the list of reported
	   online nodes */
	clu_local_nodeid(NULL, lid);
	for (x=0; x<all->cml_count; x++) {
		if (all->cml_members[x].cm_id == *lid) {
			m = &all->cml_members[x];
			m->cm_state |= FLAG_LOCAL;
			break;
		}
	}
			
	cml_free(part);

	/* Flag rgmanager nodes, if any */
	part = clu_member_list(RG_SERVICE_GROUP);
	flag_nodes(all, part, FLAG_RGMGR);
	cml_free(part);

	return all;
}


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