All pastes #1770531 Raw Edit

xtreemos

public text v1 · immutable
#1770531 ·published 2010-01-29 09:43 UTC
rendered paste body
 /* *  Copyright (C) 2006-2007, Pascal Gallard, Kerlabs. *  Copyright (c) 2008 Jean Parpaillon <jean.parpaillon@kerlabs.com> */#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <errno.h>#include <getopt.h>#include <kerrighed.h>enum {	NONE,	STATUS,	START,	WAIT_START,	POWEROFF,	REBOOT,};#define NODE_SEP ','#define NODE_RANGE_SEP '-'#define POLL_NODES 1#define NODES_OPTION "nodes", required_argument, NULL, 'n'#define AUTO_OPTION "auto", required_argument,NULL, 'a'static struct option start_options[] = {  {NODES_OPTION},  {AUTO_OPTION},  {NULL, 0, NULL, 0}};void help(char * program_name){	printf("\Usage: %s -h,--help\n\  or:  %s cluster {status|wait_start|poweroff|reboot}\n\  or:  %s cluster start  [-n|--nodes] [-a|--auto]\n\  or:  %s nodes\n",	       program_name, program_name, program_name, program_name);	printf("\n\Mode:\n\  cluster           clusters management\n\  nodes             print nodes status\n\\n\Cluster start options:\n\  -n, --nodes       list of nodes to wait for before starting\n\                    ie: 2,3,6-10,42-45\n\  -a, --auto        number of nodes to wait for before starting\n\\n\Node Status:\n\  present           available for integrating the cluster\n\  online            participating in the cluster\n\\n");}int parse_node(char *ch, struct krg_node_set *node_set){	int node;	char* endptr;	int r = 1;	node = strtol(ch, &endptr, 10);	if (endptr == ch || *endptr) {		r = -1;		errno = EINVAL;		perror("node");	} else		krg_node_set_add(node_set, node);	return r;}int parse_nodes_interval(char *ch, struct krg_node_set *node_set){	int node1, node2, node;	char* index;	char* endptr;	int r = 1;	index = strchr(ch, NODE_RANGE_SEP);	node1 = strtol(ch, &endptr, 10);	if (endptr == ch || NODE_RANGE_SEP != *endptr) {		r = -1;		errno = EINVAL;		perror("first node range");		goto exit;	}	node2 = strtol(index+1, &endptr, 10);	if (endptr == index+1 || *endptr) {		r = -1;		errno = EINVAL;		perror("end node range");		goto exit;	}	for(node=node1; node<=node2; node++)		krg_node_set_add(node_set, node); exit:	return r;}int parse_nodes(char *ch, struct krg_node_set *node_set){	char *ch_item;	int r = 1;	ch_item = strrchr(ch, NODE_SEP);	if(ch_item){		*ch_item = 0;		if ((r=parse_nodes(ch, node_set)) == -1)			goto exit;		if ((r=parse_nodes(ch_item+1, node_set)) == -1)			goto exit;		goto exit;	}	ch_item = strrchr(ch, NODE_RANGE_SEP);	if(ch_item) {		if ((r=parse_nodes_interval(ch, node_set)) == -1)			goto exit;	} else		if ((r=parse_node(ch, node_set)) == -1)			goto exit; exit:	return r;}/* * Return number of nodes in the cluster if up, 0 if not, -1 on failure */int cluster_status(){	struct krg_clusters* cluster_status;	int i = 0;	cluster_status = krg_cluster_status();	if(!cluster_status){		i = -1;		goto exit;	}	if (krg_clusters_is_up(cluster_status, 0)){		i = krg_nodes_num_online(krg_nodes_status());	} exit:	krg_clusters_destroy(cluster_status);	return i;}/* * When returning on success, node_set contains nodes to start. * * Return 1 when i nodes are present, -1 on failure. */int wait_for_nodes_count(int i, struct krg_node_set* node_set){	struct krg_nodes* status;	int cur, r = 1;	int nodes_count;	printf("Waiting for %d nodes to join... ", i);	fflush(stdout);	if (cluster_status() > 0) {		r = -1;		errno = EALREADY;		goto exit;	}	if (i < 1 || i > krg_get_max_nodes()) {		r = -1;		errno = ERANGE;		goto exit;	}	do {		status = krg_nodes_status();		if (!status) {			r = -1;			goto exit;		}		nodes_count = krg_nodes_num_present(status);		printf("%4d/%-4d", nodes_count, i);		fflush(stdout);		if (nodes_count < i) {			sleep(POLL_NODES);			printf("\b\b\b\b\b\b\b\b\b");			krg_nodes_destroy(status);		}		fflush(stdout);	} while (nodes_count < i);	nodes_count = 0;	cur = -1;	do {		cur = krg_nodes_next_present(status, cur);		krg_node_set_add(node_set, cur);		nodes_count++;	} while (nodes_count < i);	krg_nodes_destroy(status); exit:	if (r==1)		printf(" done\n");	else		printf(" fail (%s)\n", strerror(errno));	return r;}/* * Return 1 when nodes in node_set are present, -1 on failure. */int wait_for_nodes(struct krg_node_set* node_set){	struct krg_nodes* status;	int bcl, r = 1, done, node_count;	printf("Waiting for nodes to join... ");	fflush(stdout);	if (cluster_status() > 0) {		r = -1;		errno = EALREADY;		goto exit;	}	node_count = krg_node_set_weight(node_set);	do {		done = 1;		status = krg_nodes_status();		if (!status) {			r = -1;			goto exit;		}		for (bcl = 0; bcl < krg_get_max_nodes(); bcl++) {			if (krg_node_set_contains(node_set, bcl)) {				printf("%4d:", bcl);				if (krg_nodes_is_present(status, bcl))					printf("1");				else {					done = 0;					printf("0");				}			}			fflush(stdout);		}		krg_nodes_destroy(status);		if (!done) {			sleep(POLL_NODES);			for (bcl = 0; bcl < node_count; bcl++)				printf("\b\b\b\b\b\b");			fflush(stdout);		}	} while (!done); exit:	if (r==1)		printf(" done\n");	else		printf(" fail (%s)\n", strerror(errno));	return r;}/* * Return 0 on success, -1 on failure */int cluster_start(int argc, char* argv[], char* program_name){	struct krg_node_set* node_set;	int c, option_index;	int r = 0;	int wait = -1;	char* nodes;	char* endptr;	node_set = krg_node_set_init();	while ((c=getopt_long(argc, argv, "n:a:",												start_options, &option_index)) != -1) {		switch (c) {		case 'n':			wait = 0;			nodes = malloc(sizeof(char)*(strlen(optarg)+1));			nodes = strncpy(nodes, optarg, strlen(optarg)+1);			if ((r=parse_nodes(optarg, node_set)) == -1)				goto exit;			break;		case 'a':			wait = strtol(optarg, &endptr, 10);			if (endptr == optarg || *endptr) {				r = -1;				errno = EINVAL;				perror("nodes number");				goto exit;			}			break;		default:			help(program_name);			goto exit;		}	}	switch (wait) {	case -1:		{			struct krg_nodes* status;			status = krg_nodes_status();			node_set = krg_nodes_get_present(status);			krg_nodes_destroy(status);		}		break;	case 0:		r = wait_for_nodes(node_set);		if (r == -1)			goto exit;		break;	default:		r = wait_for_nodes_count(wait, node_set);		if (r == -1) {			goto exit;		}	}	printf("Starting cluster... ");	fflush(stdout);	r = krg_cluster_start(node_set);	if (r == -1)		printf("fail (%s)\n", strerror(errno));	else		printf("done\n"); exit:	return r;}/* * Return EXIT_SUCCESS on success, EXIT_FAILURE on failure. */int cluster(int argc, char* argv[], char* program_name){	int action = NONE;	int ret = EXIT_SUCCESS;	int r;	if(argc==0 || !strcmp(*argv, "status"))		action = STATUS;	else if(!strcmp(*argv, "start"))		action = START;	else if(!strcmp(*argv, "wait_start"))		action = WAIT_START;	else if(!strcmp(*argv, "poweroff"))		action = POWEROFF;	else if(!strcmp(*argv, "reboot"))		action = REBOOT;	switch (action) {	case STATUS:		printf("status: ");		r = cluster_status();			switch(r){			case -1:				printf("error\n");				ret = EXIT_FAILURE;				break;			case 0:				printf("down\n");				break;			default:				printf("up on %d nodes\n", r);			}			break;	case START:		r = cluster_start(argc, argv, program_name);		if (r == -1)			ret = EXIT_FAILURE;		break;	case WAIT_START:		printf("Waiting for cluster to start... ");		fflush(stdout);		r = krg_cluster_wait_for_start();		if (r == -1) {			printf("fail (%s)\n", strerror(errno));			ret = EXIT_FAILURE;		} else			printf("done\n");		break;	case POWEROFF:		printf("Shutting down cluster... ");		fflush(stdout);		if (cluster_status()==0) {			printf("fail (cluster not running)\n");			ret = EXIT_FAILURE;		} else {			r = krg_cluster_shutdown(0);			if (r == -1) {				printf("fail (%s)\n", strerror(errno));				ret = EXIT_FAILURE;			} else				printf("done\n");		}		break;	case REBOOT:		printf("Rebooting cluster... ");		fflush(stdout);		if (cluster_status() == 0) {			printf("fail (cluster not running)\n");			ret = EXIT_FAILURE;		} else {			r = krg_cluster_reboot(0);			if (r == -1) {				printf("fail (%s)\n", strerror(errno));				ret = EXIT_FAILURE;			} else				printf("done\n");		}	break;	default:		help(program_name);	}	return ret;}/* * Return EXIT_SUCCESS on success, EXIT_FAILURE on error */int nodes(int argc, char* argv[], char* program_name){	int ret = EXIT_SUCCESS;	if(argc==0 || !strcmp(*argv, "status")){		struct krg_nodes* status;		int bcl;		status = krg_nodes_status();		if(status){			for(bcl=0;bcl<krg_get_max_nodes();bcl++)				if(status->nodes[bcl]!=INVALID)					printf("%d:%s\n", bcl, krg_status_str(status->nodes[bcl]));		}else{			printf("Are you sure to run Kerrighed ?\n");			ret = EXIT_FAILURE;		}	}else		help(program_name);	return ret;}int main(int argc, char* argv[]){	char **arg;	char* program_name;	int count;	int ret = EXIT_SUCCESS;	arg = argv;	count = argc;	program_name = argv[0];	if(argc==1){		help(program_name);		exit(EXIT_SUCCESS);	}	opterr = 0;	count--;	arg++;	if (!strcmp(argv[1], "cluster"))		ret = cluster(count-1, arg+1, program_name);	else if (!strcmp(argv[1], "nodes"))		ret = nodes(count-1, arg+1, program_name);	else		help(program_name);	return ret;}