From e8d8a2240a57f9f4a11ee45b60c229d3f8447b86 Mon Sep 17 00:00:00 2001 From: Derrick Brashear Date: Wed, 1 Dec 2010 15:22:30 -0500 Subject: [PATCH] refactor afs_CheckServers basically, we need the ability to reuse this function, so, let's make it work differently so we can. Change-Id: I41a7e1dc62feeb137f1a7f5c939f54cb59cc6c13 Reviewed-on: http://gerrit.openafs.org/3403 Reviewed-by: Derrick Brashear Tested-by: Derrick Brashear --- src/afs/afs.h | 5 + src/afs/afs_prototypes.h | 9 + src/afs/afs_server.c | 414 +++++++++++++++++++++++---------------- 3 files changed, 256 insertions(+), 172 deletions(-) diff --git a/src/afs/afs.h b/src/afs/afs.h index 13c68ca93..6969831b3 100644 --- a/src/afs/afs.h +++ b/src/afs/afs.h @@ -1330,6 +1330,11 @@ extern struct brequest afs_brs[NBRS]; /* request structures */ #define IS_WLOCK 8 #define FIND_CDEAD 16 +/* values for adown value of afs_LoopServers */ +#define AFS_LS_UP 0 +#define AFS_LS_DOWN 1 +#define AFS_LS_ALL 2 + /* values for flag param of afs_CheckVolumeNames */ #define AFS_VOLCHECK_EXPIRED 0x1 /* volumes whose callbacks have expired */ #define AFS_VOLCHECK_BUSY 0x2 /* volumes which were marked busy */ diff --git a/src/afs/afs_prototypes.h b/src/afs/afs_prototypes.h index 1327298cf..acf1d3233 100644 --- a/src/afs/afs_prototypes.h +++ b/src/afs/afs_prototypes.h @@ -844,6 +844,15 @@ extern void afs_MarkServerUpOrDown(struct srvAddr *sa, int a_isDown); extern afs_int32 afs_ServerDown(struct srvAddr *sa); extern void afs_CountServers(void); extern void afs_CheckServers(int adown, struct cell *acellp); +extern void afs_LoopServers(int adown, struct cell *acellp, int vlalso, + void (*func1) (struct rx_connection **rxconns, + int nconns, int nservers, + struct afs_conn **conns, + struct srvAddr **addrs), + void (*func2) (struct rx_connection **rxconns, + int nconns, int nservers, + struct afs_conn **conns, + struct srvAddr **addrs)); extern unsigned int afs_random(void); extern int afs_randomMod15(void); extern int afs_randomMod127(void); diff --git a/src/afs/afs_server.c b/src/afs/afs_server.c index 49dc24e87..39925f9c3 100644 --- a/src/afs/afs_server.c +++ b/src/afs/afs_server.c @@ -523,27 +523,254 @@ ForceAllNewConnections(void) } } +static void +CkSrv_MarkUpDown(struct afs_conn **conns, int nconns, afs_int32 *results) +{ + struct srvAddr *sa; + struct afs_conn *tc; + afs_int32 i; + + for(i = 0; i < nconns; i++){ + tc = conns[i]; + sa = tc->parent->srvr; + + if (( results[i] >= 0 ) && (sa->sa_flags & SRVADDR_ISDOWN) && + (tc->parent->srvr == sa)) { + /* server back up */ + print_internet_address("afs: file server ", sa, " is back up", 2); + + ObtainWriteLock(&afs_xserver, 244); + ObtainWriteLock(&afs_xsrvAddr, 245); + afs_MarkServerUpOrDown(sa, 0); + ReleaseWriteLock(&afs_xsrvAddr); + ReleaseWriteLock(&afs_xserver); + + if (afs_waitForeverCount) { + afs_osi_Wakeup(&afs_waitForever); + } + } else { + if (results[i] < 0) { + /* server crashed */ + afs_ServerDown(sa); + ForceNewConnections(sa); /* multi homed clients */ + } + } + } +} + +void +CkSrv_SetTime(struct rx_connection **rxconns, int nconns, int nservers, + struct afs_conn **conns, struct srvAddr **addrs) +{ + struct afs_conn *tc; + afs_int32 start, end = 0, delta; + osi_timeval_t tv; + struct srvAddr *sa; + afs_int32 *conntimer, *results, *deltas; + afs_int32 i = 0; + char tbuffer[CVBS]; + + conntimer = afs_osi_Alloc(nservers * sizeof (afs_int32)); + osi_Assert(conntimer != NULL); + results = afs_osi_Alloc(nservers * sizeof (afs_int32)); + osi_Assert(results != NULL); + deltas = afs_osi_Alloc(nservers * sizeof (afs_int32)); + osi_Assert(deltas != NULL); + + /* make sure we're starting from zero */ + memset(&deltas, 0, sizeof(deltas)); + + start = osi_Time(); /* time the gettimeofday call */ + AFS_GUNLOCK(); + if ( afs_setTimeHost == NULL ) { + multi_Rx(rxconns,nconns) + { + tv.tv_sec = tv.tv_usec = 0; + multi_RXAFS_GetTime( + (afs_uint32 *)&tv.tv_sec, (afs_uint32 *)&tv.tv_usec); + tc = conns[multi_i]; + sa = tc->parent->srvr; + if (conntimer[multi_i] == 1) + rx_SetConnDeadTime(tc->id, afs_rx_deadtime); + end = osi_Time(); + results[multi_i]=multi_error; + if ((start == end) && !multi_error) + deltas[multi_i] = end - tv.tv_sec; + } multi_End; + } else { /* find and query setTimeHost only */ + for ( i = 0 ; i < nservers ; i++ ) { + if ( conns[i] == NULL || conns[i]->parent->srvr == NULL ) + continue; + if ( conns[i]->parent->srvr->server == afs_setTimeHost ) { + tv.tv_sec = tv.tv_usec = 0; + results[i] = RXAFS_GetTime(rxconns[i], + (afs_uint32 *)&tv.tv_sec, + (afs_uint32 *)&tv.tv_usec); + end = osi_Time(); + if ((start == end) && !results[i]) + deltas[i] = end - tv.tv_sec; + break; + } + } + } + AFS_GLOCK(); + + if ( afs_setTimeHost == NULL ) + CkSrv_MarkUpDown(conns, nconns, results); + else /* We lack info for other than this host */ + CkSrv_MarkUpDown(&conns[i], 1, &results[i]); + + /* + * If we're supposed to set the time, and the call worked + * quickly (same second response) and this is the host we + * use for the time and the time is really different, then + * really set the time + */ + if (afs_setTime != 0) { + for (i=0; iparent->srvr; + + if ((tc->parent->srvr->server == afs_setTimeHost || + /* Sync only to a server in the local cell */ + (afs_setTimeHost == (struct server *)0 && + afs_IsPrimaryCell(sa->server->cell)))) { + /* set the time */ + char msgbuf[90]; /* strlen("afs: setting clock...") + slop */ + delta = end - tv.tv_sec; /* how many secs fast we are */ + + afs_setTimeHost = tc->parent->srvr->server; + /* see if clock has changed enough to make it worthwhile */ + if (delta >= AFS_MINCHANGE || delta <= -AFS_MINCHANGE) { + end = osi_Time(); + if (delta > AFS_MAXCHANGEBACK) { + /* setting clock too far back, just do it a little */ + tv.tv_sec = end - AFS_MAXCHANGEBACK; + } else { + tv.tv_sec = end - delta; + } + afs_osi_SetTime(&tv); + if (delta > 0) { + strcpy(msgbuf, "afs: setting clock back "); + if (delta > AFS_MAXCHANGEBACK) { + afs_strcat(msgbuf, + afs_cv2string(&tbuffer[CVBS], + AFS_MAXCHANGEBACK)); + afs_strcat(msgbuf, " seconds (of "); + afs_strcat(msgbuf, + afs_cv2string(&tbuffer[CVBS], + delta - + AFS_MAXCHANGEBACK)); + afs_strcat(msgbuf, ", via "); + print_internet_address(msgbuf, sa, + "); clock is still fast.", + 0); + } else { + afs_strcat(msgbuf, + afs_cv2string(&tbuffer[CVBS], delta)); + afs_strcat(msgbuf, " seconds (via "); + print_internet_address(msgbuf, sa, ").", 0); + } + } else { + strcpy(msgbuf, "afs: setting clock ahead "); + afs_strcat(msgbuf, + afs_cv2string(&tbuffer[CVBS], -delta)); + afs_strcat(msgbuf, " seconds (via "); + print_internet_address(msgbuf, sa, ").", 0); + } + /* We're only going to set it once; why bother looping? */ + break; + } + } + } + } + afs_osi_Free(conntimer, nservers * sizeof(afs_int32)); + afs_osi_Free(deltas, nservers * sizeof(afs_int32)); + afs_osi_Free(results, nservers * sizeof(afs_int32)); +} + +void +CkSrv_GetCaps(struct rx_connection **rxconns, int nconns, int nservers, + struct afs_conn **conns, struct srvAddr **addrs) +{ + Capabilities *caps; + afs_int32 *results; + afs_int32 i; + struct server *ts; + + caps = afs_osi_Alloc(nservers * sizeof (Capabilities)); + osi_Assert(caps != NULL); + memset(caps, 0, nservers * sizeof(Capabilities)); + + results = afs_osi_Alloc(nservers * sizeof (afs_int32)); + osi_Assert(results != NULL); + + AFS_GUNLOCK(); + multi_Rx(rxconns,nconns) + { + multi_RXAFS_GetCapabilities(&caps[multi_i]); + results[multi_i] = multi_error; + } multi_End; + AFS_GLOCK(); + + for ( i = 0 ; i < nconns ; i++ ) { + ts = addrs[i]->server; + if ( !ts ) + continue; + ts->capabilities = 0; + ts->flags |= SCAPS_KNOWN; + if ( results[i] == RXGEN_OPCODE ) { + /* Mark server as up - it responded */ + results[i] = 0; + continue; + } + if ( results[i] >= 0 ) + /* we currently handle 32-bits of capabilities */ + if (caps[i].Capabilities_len > 0) { + ts->capabilities = caps[i].Capabilities_val[0]; + xdr_free((xdrproc_t)xdr_Capabilities, &caps[i]); + caps[i].Capabilities_val = NULL; + caps[i].Capabilities_len = 0; + } + } + CkSrv_MarkUpDown(conns, nconns, results); + + afs_osi_Free(caps, nservers * sizeof(Capabilities)); + afs_osi_Free(results, nservers * sizeof(afs_int32)); +} + /* check down servers (if adown), or running servers (if !adown) */ void afs_CheckServers(int adown, struct cell *acellp) +{ + afs_LoopServers(adown?AFS_LS_DOWN:AFS_LS_UP, acellp, 1, CkSrv_GetCaps, + afs_setTime?CkSrv_SetTime:NULL); +} + +/* adown: 0 - check only down. 1 - check only up. 2 - check all */ +void +afs_LoopServers(int adown, struct cell *acellp, int vlalso, + void (*func1) (struct rx_connection **rxconns, int nconns, + int nservers, struct afs_conn **conns, + struct srvAddr **addrs), + void (*func2) (struct rx_connection **rxconns, int nconns, + int nservers, struct afs_conn **conns, + struct srvAddr **addrs)) { struct vrequest treq; struct server *ts; struct srvAddr *sa; - struct afs_conn *tc; + struct afs_conn *tc = NULL; afs_int32 i, j; afs_int32 code; - afs_int32 start, end = 0, delta; - osi_timeval_t tv; struct unixuser *tu; - char tbuffer[CVBS]; int srvAddrCount; struct srvAddr **addrs; struct afs_conn **conns; int nconns; struct rx_connection **rxconns; - afs_int32 *conntimer, *deltas, *results; - Capabilities *caps = NULL; + afs_int32 *conntimer, *results; AFS_STATCNT(afs_CheckServers); @@ -591,17 +818,10 @@ afs_CheckServers(int adown, struct cell *acellp) osi_Assert(rxconns != NULL); conntimer = afs_osi_Alloc(j * sizeof (afs_int32)); osi_Assert(conntimer != NULL); - deltas = afs_osi_Alloc(j * sizeof (afs_int32)); - osi_Assert(deltas != NULL); results = afs_osi_Alloc(j * sizeof (afs_int32)); osi_Assert(results != NULL); - caps = afs_osi_Alloc(j * sizeof (Capabilities)); - osi_Assert(caps != NULL); - memset(caps, 0, j * sizeof(Capabilities)); - for (i = 0; i < j; i++) { - deltas[i] = 0; sa = addrs[i]; ts = sa->server; if (!ts) @@ -613,13 +833,14 @@ afs_CheckServers(int adown, struct cell *acellp) if (acellp && acellp != ts->cell) continue; - if ((!adown && (sa->sa_flags & SRVADDR_ISDOWN)) - || (adown && !(sa->sa_flags & SRVADDR_ISDOWN))) + if (((adown==AFS_LS_DOWN) && (sa->sa_flags & SRVADDR_ISDOWN)) + || ((adown==AFS_LS_UP) && !(sa->sa_flags & SRVADDR_ISDOWN))) continue; /* check vlserver with special code */ if (sa->sa_portal == AFS_VLPORT) { - CheckVLServer(sa, &treq); + if (vlalso) + CheckVLServer(sa, &treq); continue; } @@ -648,164 +869,15 @@ afs_CheckServers(int adown, struct cell *acellp) } } /* Outer loop over addrs */ - AFS_GUNLOCK(); - multi_Rx(rxconns,nconns) - { - multi_RXAFS_GetCapabilities(&caps[multi_i]); - results[multi_i] = multi_error; - } multi_End; - AFS_GLOCK(); + (*func1)(rxconns, nconns, j, conns, addrs); - for ( i = 0 ; i < nconns ; i++ ) { - ts = addrs[i]->server; - if ( !ts ) - continue; - ts->capabilities = 0; - ts->flags |= SCAPS_KNOWN; - if ( results[i] == RXGEN_OPCODE ) { - /* Mark server as up - it responded */ - results[i] = 0; - continue; - } - if ( results[i] >= 0 ) - /* we currently handle 32-bits of capabilities */ - if (caps[i].Capabilities_len > 0) { - ts->capabilities = caps[i].Capabilities_val[0]; - xdr_free((xdrproc_t)xdr_Capabilities, &caps[i]); - caps[i].Capabilities_val = NULL; - caps[i].Capabilities_len = 0; - } - } - - if ( afs_setTime != 0 ) { - start = osi_Time(); /* time the gettimeofday call */ - AFS_GUNLOCK(); - if ( afs_setTimeHost == NULL ) { - multi_Rx(rxconns,nconns) - { - tv.tv_sec = tv.tv_usec = 0; - multi_RXAFS_GetTime( - (afs_uint32 *)&tv.tv_sec, (afs_uint32 *)&tv.tv_usec); - tc = conns[multi_i]; - sa = tc->parent->srvr; - if (conntimer[multi_i] == 1) - rx_SetConnDeadTime(tc->id, afs_rx_deadtime); - end = osi_Time(); - results[multi_i]=multi_error; - if ((start == end) && !multi_error) - deltas[multi_i] = end - tv.tv_sec; - } multi_End; - } - else { /* find and query setTimeHost only */ - for ( i = 0 ; i < j ; i++ ) { - if ( conns[i] == NULL || conns[i]->parent->srvr == NULL ) - continue; - if ( conns[i]->parent->srvr->server == afs_setTimeHost ) { - tv.tv_sec = tv.tv_usec = 0; - results[i] = RXAFS_GetTime(rxconns[i], - (afs_uint32 *)&tv.tv_sec, (afs_uint32 *)&tv.tv_usec); - end = osi_Time(); - if ((start == end) && !results[i]) - deltas[i] = end - tv.tv_sec; - break; - } - } - } - AFS_GLOCK(); - } - - for(i=0;iparent->srvr; - - if (( results[i] >= 0 ) && (sa->sa_flags & SRVADDR_ISDOWN) && (tc->parent->srvr == sa)) { - /* server back up */ - print_internet_address("afs: file server ", sa, " is back up", 2); - - ObtainWriteLock(&afs_xserver, 244); - ObtainWriteLock(&afs_xsrvAddr, 245); - afs_MarkServerUpOrDown(sa, 0); - ReleaseWriteLock(&afs_xsrvAddr); - ReleaseWriteLock(&afs_xserver); - - if (afs_waitForeverCount) { - afs_osi_Wakeup(&afs_waitForever); - } - } else { - if ((results[i] < 0) && (results[i] != RXGEN_OPCODE)) { - /* server crashed */ - afs_ServerDown(sa); - ForceNewConnections(sa); /* multi homed clients */ - } - } + if (func2) { + (*func2)(rxconns, nconns, j, conns, addrs); } - /* - * If we're supposed to set the time, and the call worked - * quickly (same second response) and this is the host we - * use for the time and the time is really different, then - * really set the time - */ - if (afs_setTime != 0) { - for (i=0; iparent->srvr; - - if ((tc->parent->srvr->server == afs_setTimeHost || - /* Sync only to a server in the local cell */ - (afs_setTimeHost == (struct server *)0 && - afs_IsPrimaryCell(sa->server->cell)))) { - /* set the time */ - char msgbuf[90]; /* strlen("afs: setting clock...") + slop */ - delta = end - tv.tv_sec; /* how many secs fast we are */ - - afs_setTimeHost = tc->parent->srvr->server; - /* see if clock has changed enough to make it worthwhile */ - if (delta >= AFS_MINCHANGE || delta <= -AFS_MINCHANGE) { - end = osi_Time(); - if (delta > AFS_MAXCHANGEBACK) { - /* setting clock too far back, just do it a little */ - tv.tv_sec = end - AFS_MAXCHANGEBACK; - } else { - tv.tv_sec = end - delta; - } - afs_osi_SetTime(&tv); - if (delta > 0) { - strcpy(msgbuf, "afs: setting clock back "); - if (delta > AFS_MAXCHANGEBACK) { - afs_strcat(msgbuf, - afs_cv2string(&tbuffer[CVBS], - AFS_MAXCHANGEBACK)); - afs_strcat(msgbuf, " seconds (of "); - afs_strcat(msgbuf, - afs_cv2string(&tbuffer[CVBS], - delta - - AFS_MAXCHANGEBACK)); - afs_strcat(msgbuf, ", via "); - print_internet_address(msgbuf, sa, - "); clock is still fast.", - 0); - } else { - afs_strcat(msgbuf, - afs_cv2string(&tbuffer[CVBS], delta)); - afs_strcat(msgbuf, " seconds (via "); - print_internet_address(msgbuf, sa, ").", 0); - } - } else { - strcpy(msgbuf, "afs: setting clock ahead "); - afs_strcat(msgbuf, - afs_cv2string(&tbuffer[CVBS], -delta)); - afs_strcat(msgbuf, " seconds (via "); - print_internet_address(msgbuf, sa, ").", 0); - } - /* We're only going to set it once; why bother looping? */ - break; - } - } - } - } for (i = 0; i < nconns; i++) { + if (conntimer[i] == 1) + rx_SetConnDeadTime(tc->id, afs_rx_deadtime); afs_PutConn(conns[i], SHARED_LOCK); /* done with it now */ } @@ -813,9 +885,7 @@ afs_CheckServers(int adown, struct cell *acellp) afs_osi_Free(conns, j * sizeof(struct afs_conn *)); afs_osi_Free(rxconns, j * sizeof(struct rx_connection *)); afs_osi_Free(conntimer, j * sizeof(afs_int32)); - afs_osi_Free(deltas, j * sizeof(afs_int32)); afs_osi_Free(results, j * sizeof(afs_int32)); - afs_osi_Free(caps, j * sizeof(Capabilities)); } /*afs_CheckServers*/ -- 2.39.5