325 lines
6.5 KiB
C
325 lines
6.5 KiB
C
#include "cms_base.h"
|
|
#include "cms_message.h"
|
|
#include "cms_info.h"
|
|
#include "cms_cell_status.h"
|
|
#include "cms_trace.h"
|
|
#include "sys/mman.h"
|
|
#include "cms_membership.h"
|
|
|
|
static void cms_init_cell_status(void);
|
|
static void cms_map_cell_status_file(void);
|
|
static void cms_memb_test(void);
|
|
static void cms_start_cell(int cell);
|
|
|
|
extern void cms_monitor(int);
|
|
|
|
|
|
cell_t local_cell;
|
|
cms_cell_status_t *cms_cell_status;
|
|
int cms_num_cells;
|
|
extern int num_test_funcs;
|
|
|
|
char *cell_tty[MAX_CELLS];
|
|
|
|
void
|
|
main(int argc, char **argv)
|
|
{
|
|
int test_num = 0;
|
|
int i;
|
|
int pflag = 0;
|
|
int tflag = 0;
|
|
int c;
|
|
int ttyno;
|
|
|
|
|
|
if (argc == 1) {
|
|
fprintf(stderr, "%s -n <num cells> "
|
|
"[-t<test_num>] [-p ttynos]\n", argv[0]);
|
|
exit(1);
|
|
}
|
|
|
|
while ((c = getopt(argc, argv, "n:p:t:")) != EOF) {
|
|
switch (c) {
|
|
case 'n' :
|
|
cms_num_cells = atoi(optarg);
|
|
break;
|
|
|
|
case 't' :
|
|
tflag++;
|
|
test_num = atoi(optarg);
|
|
break;
|
|
|
|
case 'p' :
|
|
pflag = 1;
|
|
for (ttyno = 0; optind <= argc; ttyno++) {
|
|
if ( ttyno >= cms_num_cells)
|
|
break;
|
|
cell_tty[ttyno] = argv[optind -1 ];
|
|
optind++;
|
|
}
|
|
printf("ttyno. %d cms_num_cells %d optind %d \n",
|
|
ttyno, cms_num_cells, optind);
|
|
if (ttyno < cms_num_cells) {
|
|
fprintf(stderr,
|
|
"Not enough ttys to be useful\n");
|
|
pflag = 0;
|
|
}
|
|
break;
|
|
|
|
default :
|
|
fprintf(stderr, "%s -n <num cells> "
|
|
"[-t<test_num>] [-p ttynos]\n", argv[0]);
|
|
exit(1);
|
|
}
|
|
}
|
|
|
|
cms_map_cell_status_file();
|
|
|
|
/*
|
|
* Start the membership daemons.
|
|
*/
|
|
for (i = 0; i < cms_num_cells; i++) {
|
|
if (fork() == 0) {
|
|
char dev_tty[20];
|
|
/*
|
|
* Open the given per cell ttys.
|
|
*/
|
|
if (pflag) {
|
|
close(1);
|
|
strcpy(dev_tty, "/dev/");
|
|
strcat(dev_tty, cell_tty[i]);
|
|
if (open(dev_tty, O_RDWR) < 0) {
|
|
perror(cell_tty[i]);
|
|
exit(1);
|
|
}
|
|
close(2);
|
|
dup(1);
|
|
}
|
|
|
|
printf("Starting cell %d\n", i);
|
|
cms_start_cell(i);
|
|
exit(1);
|
|
}
|
|
}
|
|
|
|
if (tflag) {
|
|
if ((test_num < 0) || (test_num > num_test_funcs)) {
|
|
printf("Invalid test number should between 1 and %d\n",
|
|
num_test_funcs);
|
|
exit(1);
|
|
}
|
|
cms_monitor(test_num - 1 );
|
|
} else {
|
|
printf("Running all tests\n");
|
|
cms_monitor(-1);
|
|
}
|
|
}
|
|
|
|
|
|
static void
|
|
cms_start_cell(int cell)
|
|
{
|
|
local_cell = cell;
|
|
|
|
|
|
cms_map_cell_status_file();
|
|
cip = &cms_cell_status->cms_info[cellid()];
|
|
cms_get_config_info();
|
|
cms_init();
|
|
ep_mesg_init();
|
|
cms_init_cell_status();
|
|
/* cms_memb_test(); */
|
|
cms_print_cell_status();
|
|
cms();
|
|
}
|
|
|
|
/* REFERENCED */
|
|
void
|
|
cms_memb_test(void)
|
|
{
|
|
cell_set_t membership;
|
|
int i, j;
|
|
|
|
for (i = 0; i < cip->cms_num_cells; i++) {
|
|
cms_set_cell_status(i, B_TRUE);
|
|
for (j = 0; j < cip->cms_num_cells; j++)
|
|
cms_set_link_status(i, j, B_TRUE);
|
|
}
|
|
|
|
cms_set_link_status(3,2, B_FALSE);
|
|
for (i = 0; i < cip->cms_num_cells; i++) {
|
|
local_cell = i;
|
|
hb_get_recv_set(&cip->cms_recv_set[i]);
|
|
cms_trace(CMS_TR_MEMB_RECV_SET, i, cip->cms_recv_set[i], 0);
|
|
}
|
|
|
|
cms_membership_compute(&membership, B_FALSE);
|
|
printf("Membership printed is %x\n", membership);
|
|
exit(1);
|
|
}
|
|
|
|
void
|
|
cms_get_config_info(void)
|
|
{
|
|
FILE *fp;
|
|
char config_file[20];
|
|
char config_str[80];
|
|
|
|
sprintf(config_file, "ms_config");
|
|
|
|
fp = fopen(config_file, "r");
|
|
|
|
if (fp == NULL) {
|
|
perror("fopen");
|
|
fprintf(stderr,"Cannot open config file %s using defaults\n",
|
|
config_file);
|
|
cip->cms_num_cells = cms_num_cells;
|
|
cip->cms_follower_timeout = 20;
|
|
cip->cms_leader_timeout = 6;
|
|
cip->cms_nascent_timeout = 5;
|
|
cip->cms_tie_timeout = 5;
|
|
} else {
|
|
while (fgets(config_str, sizeof(config_str), fp) != NULL) {
|
|
if (config_str[0] == '#') {
|
|
continue;
|
|
}
|
|
sscanf(config_str,"%3d %3d %3d %3d %3d",
|
|
&cip->cms_num_cells,
|
|
&cip->cms_follower_timeout,
|
|
&cip->cms_leader_timeout,
|
|
&cip->cms_nascent_timeout,
|
|
&cip->cms_tie_timeout);
|
|
}
|
|
fclose(fp);
|
|
}
|
|
|
|
printf("Config data for cell %d\n", cellid());
|
|
printf("Nascent timeout: %3d\n", cip->cms_nascent_timeout);
|
|
printf("Leader timeout: %3d\n", cip->cms_leader_timeout);
|
|
printf("Follower timeout: %3d\n", cip->cms_follower_timeout);
|
|
printf("Tie timeout: %3d\n", cip->cms_tie_timeout);
|
|
printf("Num cells: %3d\n", cip->cms_num_cells);
|
|
}
|
|
|
|
void
|
|
hb_get_connectivity_set(cell_set_t *send_set, cell_set_t *recv_set)
|
|
{
|
|
hb_get_send_set(send_set);
|
|
hb_get_recv_set(recv_set);
|
|
}
|
|
|
|
|
|
void
|
|
hb_get_send_set(cell_set_t *send_set)
|
|
{
|
|
cell_t cell;
|
|
|
|
set_init(send_set);
|
|
for (cell = 0; cell < cip->cms_num_cells; cell++) {
|
|
if (cms_get_cell_status(cell) &&
|
|
cms_get_link_status(cellid(), cell))
|
|
set_add_member(send_set, cell);
|
|
}
|
|
for (cell = 0; cell < cip->cms_num_cells; cell++) {
|
|
if (set_is_member(send_set, cell))
|
|
if (!cms_get_link_status(cellid(), cell))
|
|
abort();
|
|
}
|
|
}
|
|
|
|
void
|
|
hb_get_recv_set(cell_set_t *recv_set)
|
|
{
|
|
cell_t cell;
|
|
|
|
set_init(recv_set);
|
|
for (cell = 0; cell < cip->cms_num_cells; cell++) {
|
|
if (cms_get_cell_status(cell) &&
|
|
cms_get_link_status(cell, cellid()))
|
|
set_add_member(recv_set, cell);
|
|
}
|
|
}
|
|
|
|
void
|
|
cms_reset_cell(cell_t cell)
|
|
{
|
|
cms_set_cell_status(cell, B_FALSE);
|
|
}
|
|
|
|
static void
|
|
cms_map_cell_status_file(void)
|
|
{
|
|
int fd;
|
|
|
|
fd = open(CELL_STATUS_FILE,O_RDWR|O_CREAT, 0644);
|
|
|
|
if (fd == -1) {
|
|
perror("open");
|
|
fprintf(stderr,"Cannot open %s\n", CELL_STATUS_FILE);
|
|
exit(1);
|
|
}
|
|
|
|
cms_cell_status = (cms_cell_status_t *)
|
|
mmap(0, sizeof(cms_cell_status_t),
|
|
PROT_READ|PROT_WRITE, MAP_SHARED|MAP_AUTOGROW, fd, 0);
|
|
|
|
if ((void * )cms_cell_status == MAP_FAILED) {
|
|
perror("mmap");
|
|
exit(1);
|
|
}
|
|
}
|
|
|
|
void
|
|
cms_init_cell_status(void)
|
|
{
|
|
int j;
|
|
/*
|
|
* Initialize the cells
|
|
*/
|
|
cms_cell_status->cms_cell_alive[cellid()] = TRUE;
|
|
for (j = 0; j < cip->cms_num_cells; j++)
|
|
cms_cell_status->cms_link_status[cellid()][j] = TRUE;
|
|
|
|
}
|
|
|
|
void
|
|
cms_print_cell_status(void)
|
|
{
|
|
int i, j;
|
|
|
|
for (i = 0; i < cip->cms_num_cells; i++) {
|
|
printf("Cell %d is %s\n", i,
|
|
cms_get_cell_status(i) ? "alive" : "dead");
|
|
printf("Cell %d is connected to ");
|
|
for (j = 0; j < cip->cms_num_cells; j++)
|
|
if (cms_get_link_status(i,j)) printf("%d ",j);
|
|
printf("\n");
|
|
}
|
|
}
|
|
|
|
/*
|
|
* cms_dead:
|
|
* Dead state. This is used only for testing.
|
|
*/
|
|
void
|
|
cms_dead(void)
|
|
{
|
|
printf("%d died\n",cellid());
|
|
ep_mesg_close();
|
|
|
|
cms_set_cell_status(cellid(), B_FALSE);
|
|
for (;;) {
|
|
delay(DEAD_TIME);
|
|
if (cms_get_cell_status(cellid()))
|
|
break;
|
|
}
|
|
|
|
printf("%d rebooting\n",cellid());
|
|
bzero(cip, sizeof(cms_info_t));
|
|
cip->cms_leader = CELL_NONE; /* No leader yet */
|
|
cms_get_config_info();
|
|
ep_mesg_init();
|
|
cms_set_state(CMS_NASCENT);
|
|
return;
|
|
}
|