cm_server_t *cm_allServersp;
-int cm_noIPAddr; /* number of client network interfaces */
-int cm_IPAddr[CM_MAXINTERFACE_ADDR]; /* client's IP address in host order */
-int cm_SubnetMask[CM_MAXINTERFACE_ADDR];/* client's subnet mask in host order*/
-int cm_NetMtu[CM_MAXINTERFACE_ADDR]; /* client's MTU sizes */
-int cm_NetFlags[CM_MAXINTERFACE_ADDR]; /* network flags */
+void
+cm_ForceNewConnectionsAllServers(void)
+{
+ cm_server_t *tsp;
+
+ lock_ObtainRead(&cm_serverLock);
+ for (tsp = cm_allServersp; tsp; tsp = tsp->allNextp) {
+ cm_GetServerNoLock(tsp);
+ cm_ForceNewConnections(tsp);
+ cm_PutServerNoLock(tsp);
+ }
+ lock_ReleaseRead(&cm_serverLock);
+}
+
+void
+cm_PingServer(cm_server_t *tsp)
+{
+ long code;
+ int wasDown = 0;
+ cm_conn_t *connp;
+ struct rx_connection * callp;
+ long secs;
+ long usecs;
+ Capabilities caps = {0, 0};
+ char hoststr[16];
+
+ lock_ObtainMutex(&tsp->mx);
+ if (tsp->flags & CM_SERVERFLAG_PINGING) {
+ tsp->waitCount++;
+ osi_SleepM((LONG_PTR)tsp, &tsp->mx);
+ lock_ObtainMutex(&tsp->mx);
+ tsp->waitCount--;
+ if (tsp->waitCount == 0)
+ tsp->flags &= ~CM_SERVERFLAG_PINGING;
+ else
+ osi_Wakeup((LONG_PTR)tsp);
+ lock_ReleaseMutex(&tsp->mx);
+ return;
+ }
+ tsp->flags |= CM_SERVERFLAG_PINGING;
+ wasDown = tsp->flags & CM_SERVERFLAG_DOWN;
+ afs_inet_ntoa_r(tsp->addr.sin_addr.S_un.S_addr, hoststr);
+ lock_ReleaseMutex(&tsp->mx);
+
+ code = cm_ConnByServer(tsp, cm_rootUserp, &connp);
+ if (code == 0) {
+ /* now call the appropriate ping call. Drop the timeout if
+ * the server is known to be down, so that we don't waste a
+ * lot of time retiming out down servers.
+ */
+
+ osi_Log4(afsd_logp, "cm_PingServer server %s (%s) was %s with caps 0x%x",
+ osi_LogSaveString(afsd_logp, hoststr),
+ tsp->type == CM_SERVER_VLDB ? "vldb" : "file",
+ wasDown ? "down" : "up",
+ tsp->capabilities);
+
+ if (wasDown)
+ rx_SetConnDeadTime(connp->callp, 10);
+ if (tsp->type == CM_SERVER_VLDB) {
+ code = VL_ProbeServer(connp->callp);
+ }
+ else {
+ /* file server */
+ callp = cm_GetRxConn(connp);
+ code = RXAFS_GetCapabilities(callp, &caps);
+ if (code == RXGEN_OPCODE)
+ code = RXAFS_GetTime(callp, &secs, &usecs);
+ rx_PutConnection(callp);
+ }
+ if (wasDown)
+ rx_SetConnDeadTime(connp->callp, ConnDeadtimeout);
+ cm_PutConn(connp);
+ } /* got an unauthenticated connection to this server */
+
+ lock_ObtainMutex(&tsp->mx);
+ if (code >= 0) {
+ /* mark server as up */
+ tsp->flags &= ~CM_SERVERFLAG_DOWN;
+
+ /* we currently handle 32-bits of capabilities */
+ if (caps.Capabilities_len > 0) {
+ tsp->capabilities = caps.Capabilities_val[0];
+ free(caps.Capabilities_val);
+ caps.Capabilities_len = 0;
+ caps.Capabilities_val = 0;
+ } else {
+ tsp->capabilities = 0;
+ }
+
+ osi_Log3(afsd_logp, "cm_PingServer server %s (%s) is up with caps 0x%x",
+ osi_LogSaveString(afsd_logp, hoststr),
+ tsp->type == CM_SERVER_VLDB ? "vldb" : "file",
+ tsp->capabilities);
+ } else {
+ /* mark server as down */
+ tsp->flags |= CM_SERVERFLAG_DOWN;
+ if (code != VRESTARTING)
+ cm_ForceNewConnections(tsp);
+
+ osi_Log3(afsd_logp, "cm_PingServer server %s (%s) is down with caps 0x%x",
+ osi_LogSaveString(afsd_logp, hoststr),
+ tsp->type == CM_SERVER_VLDB ? "vldb" : "file",
+ tsp->capabilities);
+ }
+
+ if (tsp->waitCount == 0)
+ tsp->flags &= ~CM_SERVERFLAG_PINGING;
+ else
+ osi_Wakeup((LONG_PTR)tsp);
+ lock_ReleaseMutex(&tsp->mx);
+}
+
void cm_CheckServers(long flags, cm_cell_t *cellp)
{
* Also, ping down VLDBs.
*/
cm_server_t *tsp;
- long code;
- long secs;
- long usecs;
int doPing;
- int serverType;
- long now;
- int wasDown;
- cm_conn_t *connp;
+ int isDown;
lock_ObtainWrite(&cm_serverLock);
for (tsp = cm_allServersp; tsp; tsp = tsp->allNextp) {
/* now process the server */
lock_ObtainMutex(&tsp->mx);
- /* what time is it? */
- now = osi_Time();
-
- serverType = tsp->type;
doPing = 0;
- wasDown = tsp->flags & CM_SERVERFLAG_DOWN;
+ isDown = tsp->flags & CM_SERVERFLAG_DOWN;
/* only do the ping if the cell matches the requested cell, or we're
* matching all cells (cellp == NULL), and if we've requested to ping
* this type of {up, down} servers.
*/
if ((cellp == NULL || cellp == tsp->cellp) &&
- ((wasDown && (flags & CM_FLAG_CHECKDOWNSERVERS)) ||
- (!wasDown && (flags & CM_FLAG_CHECKUPSERVERS)))) {
-
+ ((isDown && (flags & CM_FLAG_CHECKDOWNSERVERS)) ||
+ (!isDown && (flags & CM_FLAG_CHECKUPSERVERS)))) {
doPing = 1;
} /* we're supposed to check this up/down server */
lock_ReleaseMutex(&tsp->mx);
/* at this point, we've adjusted the server state, so do the ping and
* adjust things.
*/
- if (doPing) {
- code = cm_ConnByServer(tsp, cm_rootUserp, &connp);
- if (code == 0) {
- /* now call the appropriate ping call. Drop the timeout if
- * the server is known to be down, so that we don't waste a
- * lot of time retiming out down servers.
- */
- if (wasDown)
- rx_SetConnDeadTime(connp->callp, 10);
- if (serverType == CM_SERVER_VLDB) {
- code = VL_ProbeServer(connp->callp);
- }
- else {
- /* file server */
- lock_ObtainMutex(&connp->mx);
- code = RXAFS_GetTime(connp->callp, &secs, &usecs);
- lock_ReleaseMutex(&connp->mx);
- }
- if (wasDown)
- rx_SetConnDeadTime(connp->callp, ConnDeadtimeout);
- cm_PutConn(connp);
- } /* got an unauthenticated connection to this server */
-
- lock_ObtainMutex(&tsp->mx);
- if (code == 0) {
- /* mark server as up */
- tsp->flags &= ~CM_SERVERFLAG_DOWN;
- }
- else {
- /* mark server as down */
- tsp->flags |= CM_SERVERFLAG_DOWN;
- }
- lock_ReleaseMutex(&tsp->mx);
- }
+ if (doPing)
+ cm_PingServer(tsp);
/* also, run the GC function for connections on all of the
* server's connections.
unsigned long netMask;
int i;
- /* implement server prefs for fileservers only */
- if ( serverp->type == CM_SERVER_FILE )
- {
- serverAddr = ntohl(serverp->addr.sin_addr.s_addr);
- serverp->ipRank = CM_IPRANK_LOW; /* default setings */
+ int cm_noIPAddr; /* number of client network interfaces */
+ int cm_IPAddr[CM_MAXINTERFACE_ADDR]; /* client's IP address in host order */
+ int cm_SubnetMask[CM_MAXINTERFACE_ADDR];/* client's subnet mask in host order*/
+ int cm_NetMtu[CM_MAXINTERFACE_ADDR]; /* client's MTU sizes */
+ int cm_NetFlags[CM_MAXINTERFACE_ADDR]; /* network flags */
+ long code;
- for ( i=0; i < cm_noIPAddr; i++)
- {
- /* loop through all the client's IP address and compare
- ** each of them against the server's IP address */
-
- myAddr = cm_IPAddr[i];
- if ( IN_CLASSA(myAddr) )
- netMask = IN_CLASSA_NET;
- else if ( IN_CLASSB(myAddr) )
- netMask = IN_CLASSB_NET;
- else if ( IN_CLASSC(myAddr) )
- netMask = IN_CLASSC_NET;
- else
- netMask = 0;
-
- myNet = myAddr & netMask;
- mySubnet = myAddr & cm_SubnetMask[i];
-
- if ( (serverAddr & netMask) == myNet )
- {
- if ( (serverAddr & cm_SubnetMask[i]) == mySubnet)
- {
- if ( serverAddr == myAddr )
- serverp->ipRank = min(serverp->ipRank,
- CM_IPRANK_TOP);/* same machine */
- else serverp->ipRank = min(serverp->ipRank,
- CM_IPRANK_HI); /* same subnet */
- }
- else serverp->ipRank = min(serverp->ipRank,CM_IPRANK_MED);
- /* same net */
- }
- /* random between 0..15*/
- serverp->ipRank += min(serverp->ipRank, rand() % 0x000f);
- } /* and of for loop */
- }
- else
- serverp->ipRank = 10000 + (rand() % 0x00ff); /* VL server */
+ /* get network related info */
+ cm_noIPAddr = CM_MAXINTERFACE_ADDR;
+ code = syscfg_GetIFInfo(&cm_noIPAddr,
+ cm_IPAddr, cm_SubnetMask,
+ cm_NetMtu, cm_NetFlags);
+
+ serverAddr = ntohl(serverp->addr.sin_addr.s_addr);
+ serverp->ipRank = CM_IPRANK_LOW; /* default setings */
+
+ for ( i=0; i < cm_noIPAddr; i++)
+ {
+ /* loop through all the client's IP address and compare
+ ** each of them against the server's IP address */
+
+ myAddr = cm_IPAddr[i];
+ if ( IN_CLASSA(myAddr) )
+ netMask = IN_CLASSA_NET;
+ else if ( IN_CLASSB(myAddr) )
+ netMask = IN_CLASSB_NET;
+ else if ( IN_CLASSC(myAddr) )
+ netMask = IN_CLASSC_NET;
+ else
+ netMask = 0;
+
+ myNet = myAddr & netMask;
+ mySubnet = myAddr & cm_SubnetMask[i];
+
+ if ( (serverAddr & netMask) == myNet )
+ {
+ if ( (serverAddr & cm_SubnetMask[i]) == mySubnet)
+ {
+ if ( serverAddr == myAddr )
+ serverp->ipRank = min(serverp->ipRank,
+ CM_IPRANK_TOP);/* same machine */
+ else serverp->ipRank = min(serverp->ipRank,
+ CM_IPRANK_HI); /* same subnet */
+ }
+ else serverp->ipRank = min(serverp->ipRank,CM_IPRANK_MED);
+ /* same net */
+ }
+ /* random between 0..15*/
+ serverp->ipRank += min(serverp->ipRank, rand() % 0x000f);
+ } /* and of for loop */
}
cm_server_t *cm_NewServer(struct sockaddr_in *socketp, int type, cm_cell_t *cellp) {
tsp->refCount = 1;
lock_InitializeMutex(&tsp->mx, "cm_server_t mutex");
tsp->addr = *socketp;
+ tsp->flags = CM_SERVERFLAG_DOWN; /* assume down; ping will mark up if available */
cm_SetServerPrefs(tsp);
- lock_ObtainWrite(&cm_serverLock); /* get server lock */
+ lock_ObtainWrite(&cm_serverLock); /* get server lock */
tsp->allNextp = cm_allServersp;
cm_allServersp = tsp;
- lock_ReleaseWrite(&cm_serverLock); /* release server lock */
+ lock_ReleaseWrite(&cm_serverLock); /* release server lock */
+ cm_PingServer(tsp); /* Obtain Capabilities and check up/down state */
return tsp;
}
lock_ObtainWrite(&cm_serverLock);
for (tsp = cm_allServersp; tsp; tsp=tsp->allNextp) {
if (tsp->type == type &&
- tsp->addr.sin_addr.s_addr == addrp->sin_addr.s_addr) break;
+ tsp->addr.sin_addr.s_addr == addrp->sin_addr.s_addr)
+ break;
}
/* bump ref count if we found the server */
return tsrp;
}
-long cm_ChecksumServerList(cm_serverRef_t *serversp)
+LONG_PTR cm_ChecksumServerList(cm_serverRef_t *serversp)
{
- long sum = 0;
+ LONG_PTR sum = 0;
int first = 1;
cm_serverRef_t *tsrp;
first = 0;
else
sum <<= 1;
- sum ^= (long) tsrp->server;
+ sum ^= (LONG_PTR) tsrp->server;
}
lock_ReleaseWrite(&cm_serverLock);
*/
cm_GCConnections(serverp); /* connsp */
- lock_FinalizeMutex(&serverp->mx);
- if ( cm_allServersp == serverp )
- cm_allServersp = serverp->allNextp;
- else {
- cm_server_t *tsp;
-
- for(tsp = cm_allServersp; tsp->allNextp; tsp=tsp->allNextp) {
- if ( tsp->allNextp == serverp ) {
- tsp->allNextp = serverp->allNextp;
- break;
- }
+ if (!(serverp->flags & CM_SERVERFLAG_PREF_SET)) {
+ lock_FinalizeMutex(&serverp->mx);
+ if ( cm_allServersp == serverp )
+ cm_allServersp = serverp->allNextp;
+ else {
+ cm_server_t *tsp;
+
+ for(tsp = cm_allServersp; tsp->allNextp; tsp=tsp->allNextp) {
+ if ( tsp->allNextp == serverp ) {
+ tsp->allNextp = serverp->allNextp;
+ break;
+ }
+ }
}
+ free(serverp);
}
}
- }
+}
void cm_FreeServerList(cm_serverRef_t** list)
{