/* Exported variables */
afs_rwlock_t afs_xserver; /* allocation lock for servers */
-struct server *afs_setTimeHost = 0; /* last host we used for time */
struct server *afs_servers[NSERVERS]; /* Hashed by server`s uuid & 1st ip */
afs_rwlock_t afs_xsrvAddr; /* allocation lock for srvAddrs */
struct srvAddr *afs_srvAddrs[NSERVERS]; /* Hashed by server's ip */
* All ips are down we treat the whole server down
*/
a_serverP->flags |= SRVR_ISDOWN;
- /*
- * If this was our time server, search for another time server
- */
- if (a_serverP == afs_setTimeHost)
- afs_setTimeHost = 0;
} else {
sa->sa_flags &= ~SRVADDR_ISDOWN;
/* If any ips are up, the server is also marked up */
}
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(rxconns[multi_i], 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; i<nconns; i++) {
- delta = deltas[i];
- tc = conns[i];
- sa = tc->parent->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)
+CkSrv_GetCaps(int nconns, struct rx_connection **rxconns,
+ struct afs_conn **conns)
{
Capabilities *caps;
afs_int32 *results;
afs_int32 i;
struct server *ts;
- caps = afs_osi_Alloc(nservers * sizeof (Capabilities));
+ caps = afs_osi_Alloc(nconns * sizeof (Capabilities));
osi_Assert(caps != NULL);
- memset(caps, 0, nservers * sizeof(Capabilities));
+ memset(caps, 0, nconns * sizeof(Capabilities));
- results = afs_osi_Alloc(nservers * sizeof (afs_int32));
+ results = afs_osi_Alloc(nconns * sizeof (afs_int32));
osi_Assert(results != NULL);
AFS_GUNLOCK();
AFS_GLOCK();
for ( i = 0 ; i < nconns ; i++ ) {
- ts = addrs[i]->server;
+ ts = conns[i]->parent->srvr->server;
if ( !ts )
continue;
ts->capabilities = 0;
}
CkSrv_MarkUpDown(conns, nconns, results);
- afs_osi_Free(caps, nservers * sizeof(Capabilities));
- afs_osi_Free(results, nservers * sizeof(afs_int32));
+ afs_osi_Free(caps, nconns * sizeof(Capabilities));
+ afs_osi_Free(results, nconns * 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);
+ afs_LoopServers(adown?AFS_LS_DOWN:AFS_LS_UP, acellp, 1, CkSrv_GetCaps, NULL);
}
/* adown: AFS_LS_UP - check only up
* AFS_LS_ALL - 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))
+ void (*func1) (int nservers, struct rx_connection **rxconns,
+ struct afs_conn **conns),
+ void (*func2) (int nservers, struct rx_connection **rxconns,
+ struct afs_conn **conns))
{
struct vrequest treq;
struct server *ts;
struct afs_conn **conns;
int nconns;
struct rx_connection **rxconns;
- afs_int32 *conntimer, *results;
+ afs_int32 *conntimer;
AFS_STATCNT(afs_CheckServers);
osi_Assert(rxconns != NULL);
conntimer = afs_osi_Alloc(j * sizeof (afs_int32));
osi_Assert(conntimer != NULL);
- results = afs_osi_Alloc(j * sizeof (afs_int32));
- osi_Assert(results != NULL);
for (i = 0; i < j; i++) {
struct rx_connection *rxconn;
if (!tc)
continue;
- if ((sa->sa_flags & SRVADDR_ISDOWN) || afs_HaveCallBacksFrom(sa->server)
- || (tc->parent->srvr->server == afs_setTimeHost)) {
+ if ((sa->sa_flags & SRVADDR_ISDOWN) || afs_HaveCallBacksFrom(sa->server)) {
conns[nconns]=tc;
rxconns[nconns]=rxconn;
if (sa->sa_flags & SRVADDR_ISDOWN) {
}
} /* Outer loop over addrs */
- (*func1)(rxconns, nconns, j, conns, addrs);
+ afs_osi_Free(addrs, srvAddrCount * sizeof(*addrs));
+ addrs = NULL;
+
+ (*func1)(nconns, rxconns, conns);
if (func2) {
- (*func2)(rxconns, nconns, j, conns, addrs);
+ (*func2)(nconns, rxconns, conns);
}
for (i = 0; i < nconns; i++) {
afs_PutConn(conns[i], rxconns[i], SHARED_LOCK); /* done with it now */
}
- afs_osi_Free(addrs, srvAddrCount * sizeof(*addrs));
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(results, j * sizeof(afs_int32));
} /*afs_CheckServers*/
return;
}
#else /* AFS_USERSPACE_IP_ADDR */
-#if (! defined(AFS_SUN5_ENV)) && (! defined(AFS_DARWIN_ENV)) && (! defined(AFS_OBSD47_ENV)) && defined(USEIFADDR)
+#if (! defined(AFS_SUN5_ENV)) && (! defined(AFS_DARWIN_ENV)) && (! defined(AFS_OBSD47_ENV)) && (! defined(AFS_FBSD_ENV)) && defined(USEIFADDR)
void
afsi_SetServerIPRank(struct srvAddr *sa, struct in_ifaddr *ifa)
{
#endif /* IFF_POINTTOPOINT */
}
#endif /*(!defined(AFS_SUN5_ENV)) && defined(USEIFADDR) */
-#if (defined(AFS_DARWIN_ENV) || defined(AFS_OBSD47_ENV)) && defined(USEIFADDR)
+#if (defined(AFS_DARWIN_ENV) || defined(AFS_OBSD47_ENV) || defined(AFS_FBSD_ENV)) && defined(USEIFADDR)
#ifndef afs_min
#define afs_min(A,B) ((A)<(B)) ? (A) : (B)
#endif
{
struct sockaddr sout;
struct sockaddr_in *sin;
+#if defined(AFS_DARWIN80_ENV) && !defined(UKERNEL)
int t;
+#else
+ void *t;
+#endif
afs_uint32 subnetmask, myAddr, myNet, myDstaddr, mySubnet, netMask;
afs_uint32 serverAddr;
#else
TAILQ_FOREACH(ifa, &in_ifaddrhead, ia_link) {
#endif
- afsi_SetServerIPRank(sa, ifa);
+ afsi_SetServerIPRank(sa, &ifa->ia_ifa);
}}
#elif defined(AFS_OBSD_ENV)
{
* The afs_xserver, afs_xvcb and afs_xsrvAddr locks are assumed taken.
*/
static void
-afs_FlushServer(struct server *srvp)
+afs_FlushServer(struct server *srvp, struct volume *tv)
{
afs_int32 i;
struct server *ts, **pts;
/* Find any volumes residing on this server and flush their state */
- afs_ResetVolumes(srvp);
+ afs_ResetVolumes(srvp, tv);
/* Flush all callbacks in the all vcaches for this specific server */
- afs_FlushServerCBs(srvp);
+ afs_FlushServerCBs(srvp);
/* Remove all the callbacks structs */
if (srvp->cbrs) {
* remains connected to a server struct.
* The afs_xserver and afs_xsrvAddr locks are assumed taken.
* It is not removed from the afs_srvAddrs hash chain.
+ * If resetting volumes, do not reset volume tv
*/
-void
-afs_RemoveSrvAddr(struct srvAddr *sap)
+static void
+afs_RemoveSrvAddr(struct srvAddr *sap, struct volume *tv)
{
struct srvAddr **psa, *sa;
struct server *srv;
sa->server = 0;
/* Flush the server struct since it's IP address has changed */
- afs_FlushServer(srv);
+ afs_FlushServer(srv, tv);
}
}
return NULL;
}
-/* afs_GetServer()
- * Return an updated and properly initialized server structure
- * corresponding to the server ID, cell, and port specified.
- * If one does not exist, then one will be created.
- * aserver and aport must be in NET byte order.
+/*!
+ * Return an updated and properly initialized server structure.
+ *
+ * Takes a server ID, cell, and port.
+ * If server does not exist, then one will be created.
+ * @param[in] aserverp
+ * The server address in network byte order
+ * @param[in] nservers
+ * The number of IP addresses claimed by the server
+ * @param[in] acell
+ * The cell the server is in
+ * @param[in] aport
+ * The port for the server (fileserver or vlserver) in network byte order
+ * @param[in] locktype
+ * The type of lock to hold when iterating server hash (unused).
+ * @param[in] uuidp
+ * The uuid for servers supporting one.
+ * @param[in] addr_uniquifier
+ * The vldb-provider per-instantiated-server uniquifer counter.
+ * @param[in] tv
+ * A volume not to reset information for if the server addresses
+ * changed.
+ *
+ * @return
+ * A server structure matching the request.
*/
struct server *
-afs_GetServer(afs_uint32 * aserverp, afs_int32 nservers, afs_int32 acell,
+afs_GetServer(afs_uint32 *aserverp, afs_int32 nservers, afs_int32 acell,
u_short aport, afs_int32 locktype, afsUUID * uuidp,
- afs_int32 addr_uniquifier)
+ afs_int32 addr_uniquifier, struct volume *tv)
{
struct server *oldts = 0, *ts, *newts, *orphts = 0;
struct srvAddr *oldsa, *newsa, *nextsa, *orphsa;
/* Check if the server struct exists and is up to date */
if (!uuidp) {
if (nservers != 1)
- panic("afs_GetServer: incorect count of servers");
+ panic("afs_GetServer: incorrect count of servers");
ObtainReadLock(&afs_xsrvAddr);
ts = afs_FindServer(aserverp[0], aport, NULL, locktype);
ReleaseReadLock(&afs_xsrvAddr);
break;
}
if (oldsa && (oldsa->server != newts)) {
- afs_RemoveSrvAddr(oldsa); /* Remove from its server struct */
+ afs_RemoveSrvAddr(oldsa, tv); /* Remove from its server struct */
oldsa->next_sa = newts->addr; /* Add to the new server struct */
newts->addr = oldsa;
}
/* Hang the srvAddr struct off of the server structure. The server
* may have multiple srvAddrs, but it won't be marked multihomed.
*/
- afs_RemoveSrvAddr(orphsa); /* remove */
+ afs_RemoveSrvAddr(orphsa, tv); /* remove */
orphsa->next_sa = orphts->addr; /* hang off server struct */
orphts->addr = orphsa;
orphsa->server = orphts;
if (afs_stats_cmperf.srvRecords > afs_stats_cmperf.srvRecordsHWM)
afs_stats_cmperf.srvRecordsHWM = afs_stats_cmperf.srvRecords;
}
+ /* We can't need this below, and won't reacquire */
+ ReleaseWriteLock(&afs_xvcb);
ReleaseWriteLock(&afs_xsrvAddr);