|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1983 Regents of the University of California. ! 3: * All rights reserved. The Berkeley software License Agreement ! 4: * specifies the terms and conditions for redistribution. ! 5: */ ! 6: ! 7: #ifndef lint ! 8: static char sccsid[] = "@(#)candidate.c 2.3 (Berkeley) 4/21/86"; ! 9: #endif not lint ! 10: ! 11: #include "globals.h" ! 12: #include <protocols/timed.h> ! 13: ! 14: #define ELECTIONWAIT 3 /* seconds */ ! 15: ! 16: /* ! 17: * `election' candidates a host as master: it is called by a slave ! 18: * which runs with the -M option set when its election timeout expires. ! 19: * Note the conservative approach: if a new timed comes up, or another ! 20: * candidate sends an election request, the candidature is withdrawn. ! 21: */ ! 22: ! 23: election(net) ! 24: struct netinfo *net; ! 25: { ! 26: int ret; ! 27: struct tsp *resp, msg, *readmsg(); ! 28: struct timeval wait; ! 29: struct tsp *answer, *acksend(); ! 30: long casual(); ! 31: struct sockaddr_in server; ! 32: ! 33: syslog(LOG_INFO, "THIS MACHINE IS A CANDIDATE"); ! 34: if (trace) { ! 35: fprintf(fd, "THIS MACHINE IS A CANDIDATE\n"); ! 36: } ! 37: ! 38: ret = MASTER; ! 39: slvcount = 1; ! 40: ! 41: msg.tsp_type = TSP_ELECTION; ! 42: msg.tsp_vers = TSPVERSION; ! 43: (void)strcpy(msg.tsp_name, hostname); ! 44: bytenetorder(&msg); ! 45: if (sendto(sock, (char *)&msg, sizeof(struct tsp), 0, &net->dest_addr, ! 46: sizeof(struct sockaddr_in)) < 0) { ! 47: syslog(LOG_ERR, "sendto: %m"); ! 48: exit(1); ! 49: } ! 50: ! 51: do { ! 52: wait.tv_sec = ELECTIONWAIT; ! 53: wait.tv_usec = 0; ! 54: resp = readmsg(TSP_ANY, (char *)ANYADDR, &wait, net); ! 55: if (resp != NULL) { ! 56: switch (resp->tsp_type) { ! 57: ! 58: case TSP_ACCEPT: ! 59: (void) addmach(resp->tsp_name, &from); ! 60: break; ! 61: ! 62: case TSP_MASTERUP: ! 63: case TSP_MASTERREQ: ! 64: /* ! 65: * If a timedaemon is coming up at the same time, ! 66: * give up the candidature: it will be the master. ! 67: */ ! 68: ret = SLAVE; ! 69: break; ! 70: ! 71: case TSP_QUIT: ! 72: case TSP_REFUSE: ! 73: /* ! 74: * Collision: change value of election timer ! 75: * using exponential backoff. ! 76: * The value of timer will be recomputed (in slave.c) ! 77: * using the original interval when election will ! 78: * be successfully completed. ! 79: */ ! 80: backoff *= 2; ! 81: delay2 = casual((long)MINTOUT, ! 82: (long)(MAXTOUT * backoff)); ! 83: ret = SLAVE; ! 84: break; ! 85: ! 86: case TSP_ELECTION: ! 87: /* no master for another round */ ! 88: msg.tsp_type = TSP_REFUSE; ! 89: (void)strcpy(msg.tsp_name, hostname); ! 90: server = from; ! 91: answer = acksend(&msg, &server, resp->tsp_name, ! 92: TSP_ACK, (struct netinfo *)NULL); ! 93: if (answer == NULL) { ! 94: syslog(LOG_ERR, "error in election"); ! 95: } else { ! 96: (void) addmach(resp->tsp_name, &from); ! 97: } ! 98: break; ! 99: ! 100: case TSP_SLAVEUP: ! 101: (void) addmach(resp->tsp_name, &from); ! 102: break; ! 103: ! 104: case TSP_SETDATE: ! 105: case TSP_SETDATEREQ: ! 106: break; ! 107: ! 108: default: ! 109: if (trace) { ! 110: fprintf(fd, "candidate: "); ! 111: print(resp, &from); ! 112: } ! 113: break; ! 114: } ! 115: } else { ! 116: break; ! 117: } ! 118: } while (ret == MASTER); ! 119: return(ret); ! 120: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.