diff options
author | John Kohl <jtkohl@mit.edu> | 1987-07-16 13:02:26 +0000 |
---|---|---|
committer | John Kohl <jtkohl@mit.edu> | 1987-07-16 13:02:26 +0000 |
commit | b211b3eba3b4e9b3a7ea43755e6239e82992a42d (patch) | |
tree | f4c52a572f11a40cecbe3d2f61265b4ca75e7f50 | |
parent | 322bd80b14103faa975952a2d418ba084391d65c (diff) |
add multiple server client flushing support
-rw-r--r-- | server/server.c | 202 |
1 files changed, 179 insertions, 23 deletions
diff --git a/server/server.c b/server/server.c index 4beb67f..ac4277c 100644 --- a/server/server.c +++ b/server/server.c @@ -55,12 +55,15 @@ static char rcsid_server_s_c[] = "$Header$"; * ZServerDesc_t *server_which_server(who) * struct sockaddr_in *who; * + * void server_kill_clt(client); + * ZClient_t *client; + * */ static void server_hello(), server_flush(), admin_dispatch(), setup_server(); static void hello_respond(), srv_responded(), send_msg(), send_msg_list(); static void srv_alive(), srv_nack_cancel(), srv_rexmit(), srv_nack_release(); -static void recover_clt(); +static void recover_clt(), kill_clt(), server_lost(); static Code_t server_register(); static struct in_addr *get_server_addrs(); @@ -212,7 +215,7 @@ ZServerDesc_t *which; which->zs_state = SERV_DEAD; which->zs_numsent = 0; which->zs_timeout = timo_dead; - server_flush(which); + server_lost(which); } auth = 0; break; @@ -370,30 +373,141 @@ ZClient_t *client; } /* - * Another server asked us to initiate recovery protocol with the hostmanager + * Tell the other servers that this client died. */ + +void +server_kill_clt(client) +ZClient_t *client; +{ + register int i; + ZServerDesc_t *server; + char buf[512], *lyst[2]; + ZNotice_t notice; + register ZNotAcked_t *nacked; + register ZNotice_t *pnotice; /* speed hack */ + caddr_t pack; + int packlen, auth; + Code_t retval; + + + zdbug((LOG_DEBUG, "server kill clt")); + lyst[0] = inet_ntoa(client->zct_sin.sin_addr), + (void) sprintf(buf, "%d", ntohs(client->zct_sin.sin_port)); + lyst[1] = buf; + + pnotice = ¬ice; + + pnotice->z_kind = ACKED; + + pnotice->z_port = sock_sin.sin_port; + pnotice->z_class = ZEPHYR_ADMIN_CLASS; + pnotice->z_class_inst = ""; + pnotice->z_opcode = ADMIN_KILL_CLT; + pnotice->z_sender = myname; /* myname is the hostname */ + pnotice->z_recipient = ""; + + + /* XXX */ + auth = 0; + + /* don't tell limbo to flush, start at 1*/ + for (i = 1; i < nservers; i++) { + if (i == me_server_idx) /* don't xmit to myself */ + continue; + if (otherservers[i].zs_state == SERV_DEAD) + continue; + + if (!(pack = (caddr_t) xmalloc(sizeof(ZPacket_t)))) { + syslog(LOG_ERR, "srv_forw malloc"); + continue; /* DON'T put on nack list */ + } + + packlen = sizeof(ZPacket_t); + if ((retval = ZFormatNoticeList(pnotice, lyst, 2, pack, packlen, &packlen, auth ? ZAUTH : ZNOAUTH)) != ZERR_NONE) { + syslog(LOG_WARNING, "kill_clt format: %s", + error_message(retval)); + return; + } + if ((retval = ZSetDestAddr(&otherservers[i].zs_addr)) + != ZERR_NONE) { + syslog(LOG_WARNING, "kill_clt set addr: %s", + error_message(retval)); + return; + } + if ((retval = ZSendPacket(pack, packlen)) != ZERR_NONE) { + syslog(LOG_WARNING, + "kill_clt xmit: %s", error_message(retval)); + return; + } + + /* now we've sent it, mark it as not ack'ed */ + + if (!(nacked = (ZNotAcked_t *)xmalloc(sizeof(ZNotAcked_t)))) { + /* no space: just punt */ + syslog(LOG_ERR, "srv_forw nack malloc"); + xfree(pack); + continue; + } + + nacked->na_rexmits = 0; + nacked->na_packet = pack; + nacked->na_srv_idx = i; + nacked->na_packsz = packlen; + nacked->na_uid = pnotice->z_uid; + nacked->q_forw = nacked->q_back = nacked; + nacked->na_abstimo = 0; + + /* set a timer to retransmit */ + nacked->na_timer = timer_set_rel(srv_rexmit_secs, + srv_rexmit, + (caddr_t) nacked); + /* chain in */ + xinsque(nacked, srv_nacklist); + } + +} + +/* + * A client has died. remove it + */ + static void -recover_clt(notice) -register ZNotice_t *notice; +kill_clt(notice) +ZNotice_t *notice; { struct sockaddr_in who; - register char *cp = notice->z_message; - ZClient_t *client; ZHostList_t *host; + ZClient_t *client; - if (!notice->z_message_len) { - syslog(LOG_WARNING, "bad recover_clt pkt"); + zdbug((LOG_DEBUG, "kill_clt")); + if (extract_addr(notice, &who) != ZERR_NONE) + return; + if (!(host = hostm_find_host(&who.sin_addr))) { + syslog(LOG_WARNING, "no host kill_clt"); return; } - who.sin_addr.s_addr = inet_addr(notice->z_message); - cp += strlen(cp); - if (cp >= notice->z_message + notice->z_message_len) { - syslog(LOG_WARNING, "short recover_clt pkt"); + if (!(client = client_which_client(&who, notice))) { + syslog(LOG_WARNING, "no clt kill_clt"); return; } - who.sin_port = notice->z_port = htons((u_short) atoi(cp)); - who.sin_family = AF_INET; + client_deregister(client, host); + return; +} +/* + * Another server asked us to initiate recovery protocol with the hostmanager + */ +static void +recover_clt(notice) +register ZNotice_t *notice; +{ + struct sockaddr_in who; + ZClient_t *client; + ZHostList_t *host; + + if (extract_addr(notice, &who) != ZERR_NONE) + return; if (!(host = hostm_find_host(&who.sin_addr))) { syslog(LOG_WARNING, "recover_clt h not found"); return; @@ -406,6 +520,34 @@ register ZNotice_t *notice; } /* + * extract a sockaddr_in from a message body + */ + +static Code_t +extract_addr(notice, who) +ZNotice_t *notice; +struct sockaddr_in *who; +{ + register char *cp = notice->z_message; + + if (!notice->z_message_len) { + syslog(LOG_WARNING, "bad addr pkt"); + return(ZSRV_PKSHORT); + } + who->sin_addr.s_addr = inet_addr(notice->z_message); + cp += strlen(cp) + 1; + if (cp >= notice->z_message + notice->z_message_len) { + syslog(LOG_WARNING, "short addr pkt"); + return(ZSRV_PKSHORT); + } + who->sin_port = notice->z_port = htons((u_short) atoi(cp)); + who->sin_family = AF_INET; + zdbug((LOG_DEBUG,"ext %s/%d", inet_ntoa(who->sin_addr), + ntohs(who->sin_port))); + return(ZERR_NONE); +} + +/* * Flush all data associated with the server which */ @@ -456,7 +598,6 @@ struct sockaddr_in *who; ZServerDesc_t *server; { register char *opcode = notice->z_opcode; - register ZHostList_t *host, *hishost; zdbug((LOG_DEBUG, "ADMIN received")); @@ -468,13 +609,7 @@ ZServerDesc_t *server; zdbug((LOG_DEBUG, "server shutdown")); /* we need to transfer all of its hosts to limbo */ if (server) { - hishost = server->zs_hosts; - for (host = hishost->q_forw; - host != hishost; - host = hishost->q_forw) - /* hostm transfer remque's the host and - attaches it to the new server */ - hostm_transfer(host, limbo_server); + server_lost(server); server->zs_state = SERV_DEAD; server->zs_timeout = timo_dead; /* don't worry about the timer, it will @@ -487,11 +622,32 @@ ZServerDesc_t *server; bdump_get(notice, auth, who, server); } else if (!strcmp(opcode, ADMIN_LOST_CLT)) { recover_clt(notice); + } else if (!strcmp(opcode, ADMIN_KILL_CLT)) { + kill_clt(notice); + ack(notice, who); } else syslog(LOG_WARNING, "ADMIN unknown opcode %s",opcode); return; } +/* + * Transfer all the hosts on server to limbo + */ + +static void +server_lost(server) +ZServerDesc_t *server; +{ + register ZHostList_t *host, *hishost; + + hishost = server->zs_hosts; + for (host = hishost->q_forw; + host != hishost; + host = hishost->q_forw) + /* hostm transfer remque's the host and + attaches it to the new server */ + hostm_transfer(host, limbo_server); +} /* * Handle an ADMIN message from some random client. |