osi_rwlock_t cm_serverLock;
osi_rwlock_t cm_syscfgLock;
-cm_server_t *cm_allServersp;
+cm_server_t *cm_serversAllFirstp = NULL;
+cm_server_t *cm_serversAllLastp = NULL;
+
afs_uint32 cm_numFileServers = 0;
afs_uint32 cm_numVldbServers = 0;
cm_server_t *tsp;
lock_ObtainRead(&cm_serverLock);
- for (tsp = cm_allServersp; tsp; tsp = tsp->allNextp) {
+ for (tsp = cm_serversAllFirstp;
+ tsp;
+ tsp = (cm_server_t *)osi_QNext(&tsp->allq)) {
cm_GetServerNoLock(tsp);
lock_ReleaseRead(&cm_serverLock);
cm_ForceNewConnections(tsp);
afs_uint16 port;
lock_ObtainRead(&cm_serverLock);
- for (tsp = cm_allServersp; tsp; tsp = tsp->allNextp) {
+ for (tsp = cm_serversAllFirstp;
+ tsp;
+ tsp = (cm_server_t *)osi_QNext(&tsp->allq)) {
switch (tsp->type) {
case CM_SERVER_VLDB:
port = htons(7003);
return code;
}
+static void
+cm_MarkServerDown(cm_server_t *tsp, afs_int32 code, int wasDown)
+{
+
+ /* mark server as down */
+ if (!(tsp->flags & CM_SERVERFLAG_DOWN)) {
+ _InterlockedOr(&tsp->flags, CM_SERVERFLAG_DOWN);
+ tsp->downTime = time(NULL);
+ }
+ if (code != VRESTARTING) {
+ lock_ReleaseMutex(&tsp->mx);
+ cm_ForceNewConnections(tsp);
+ lock_ObtainMutex(&tsp->mx);
+ }
+ /* Now update the volume status if necessary */
+ if (!wasDown) {
+ if (tsp->type == CM_SERVER_FILE) {
+ cm_server_vols_t * tsrvp;
+ cm_volume_t * volp;
+ int i;
+ cm_req_t req;
+
+ for (tsrvp = tsp->vols; tsrvp; tsrvp = tsrvp->nextp) {
+ for (i=0; i<NUM_SERVER_VOLS; i++) {
+ if (tsrvp->ids[i] != 0) {
+ cm_InitReq(&req);
+
+ lock_ReleaseMutex(&tsp->mx);
+ code = cm_FindVolumeByID(tsp->cellp, tsrvp->ids[i],
+ cm_rootUserp, &req,
+ CM_GETVOL_FLAG_NO_LRU_UPDATE,
+ &volp);
+ lock_ObtainMutex(&tsp->mx);
+ if (code == 0) {
+ cm_UpdateVolumeStatus(volp, tsrvp->ids[i]);
+ cm_PutVolume(volp);
+ }
+ }
+ }
+ }
+ }
+ cm_RankServer(tsp);
+ }
+}
+
void
cm_PingServer(cm_server_t *tsp)
{
afs_inet_ntoa_r(tsp->addr.sin_addr.S_un.S_addr, hoststr);
lock_ReleaseMutex(&tsp->mx);
- code = cm_ConnByServer(tsp, cm_rootUserp, FALSE, &connp);
+ if (cm_noIPAddr > 0)
+ code = cm_ConnByServer(tsp, cm_rootUserp, FALSE, &connp);
+ else
+ code = RX_CALL_DEAD; /* No network */
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
rxconnp = cm_GetRxConn(connp);
if (wasDown)
- rx_SetConnDeadTime(rxconnp, 10);
+ rx_SetConnHardDeadTime(rxconnp, 10);
if (tsp->type == CM_SERVER_VLDB) {
code = VL_ProbeServer(rxconnp);
}
code = RXAFS_GetCapabilities(rxconnp, &caps);
}
if (wasDown)
- rx_SetConnDeadTime(rxconnp, ConnDeadtimeout);
+ rx_SetConnHardDeadTime(rxconnp, HardDeadtimeout);
rx_PutConnection(rxconnp);
cm_PutConn(connp);
} /* got an unauthenticated connection to this server */
cm_RankServer(tsp);
}
} else {
- /* mark server as down */
- if (!(tsp->flags & CM_SERVERFLAG_DOWN)) {
- _InterlockedOr(&tsp->flags, CM_SERVERFLAG_DOWN);
- tsp->downTime = time(NULL);
- }
- if (code != VRESTARTING) {
- lock_ReleaseMutex(&tsp->mx);
- cm_ForceNewConnections(tsp);
- lock_ObtainMutex(&tsp->mx);
- }
+ cm_MarkServerDown(tsp, code, wasDown);
+
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);
-
- /* Now update the volume status if necessary */
- if (!wasDown) {
- cm_server_vols_t * tsrvp;
- cm_volume_t * volp;
- int i;
-
- for (tsrvp = tsp->vols; tsrvp; tsrvp = tsrvp->nextp) {
- for (i=0; i<NUM_SERVER_VOLS; i++) {
- if (tsrvp->ids[i] != 0) {
- cm_InitReq(&req);
-
- lock_ReleaseMutex(&tsp->mx);
- code = cm_FindVolumeByID(tsp->cellp, tsrvp->ids[i], cm_rootUserp,
- &req, CM_GETVOL_FLAG_NO_LRU_UPDATE, &volp);
- lock_ObtainMutex(&tsp->mx);
- if (code == 0) {
- cm_UpdateVolumeStatus(volp, tsrvp->ids[i]);
- cm_PutVolume(volp);
- }
- }
- }
- }
- cm_RankServer(tsp);
- }
}
if (tsp->waitCount == 0)
cm_server_t * tsp;
lock_ObtainRead(&cm_serverLock);
- for (tsp = cm_allServersp; tsp; tsp = tsp->allNextp) {
+ for (tsp = cm_serversAllFirstp;
+ tsp;
+ tsp = (cm_server_t *)osi_QNext(&tsp->allq)) {
cm_GetServerNoLock(tsp);
lock_ReleaseRead(&cm_serverLock);
int isVLDB;
lock_ObtainRead(&cm_serverLock);
- for (tsp = cm_allServersp; tsp; tsp = tsp->allNextp) {
+ for (tsp = cm_serversAllFirstp;
+ tsp;
+ tsp = (cm_server_t *)osi_QNext(&tsp->allq)) {
cm_GetServerNoLock(tsp);
lock_ReleaseRead(&cm_serverLock);
!(flags & (CM_FLAG_CHECKFILESERVERS|CM_FLAG_CHECKVLDBSERVERS)))
{
lock_ObtainRead(&cm_serverLock);
- for (nconns=0, tsp = cm_allServersp; tsp && nconns < maxconns; tsp = tsp->allNextp) {
+ for (nconns=0, tsp = cm_serversAllFirstp;
+ tsp != NULL && nconns < maxconns;
+ tsp = (cm_server_t *)osi_QNext(&tsp->allq)) {
if (tsp->type != CM_SERVER_FILE ||
tsp->cellp == NULL || /* SetPref only */
cellp && cellp != tsp->cellp)
lock_ReleaseMutex(&tsp->mx);
serversp[nconns] = tsp;
- code = cm_ConnByServer(tsp, cm_rootUserp, FALSE, &conns[nconns]);
+ if (cm_noIPAddr > 0)
+ code = cm_ConnByServer(tsp, cm_rootUserp, FALSE, &conns[nconns]);
+ else
+ code = RX_CALL_DEAD;
if (code) {
- lock_ObtainRead(&cm_serverLock);
- cm_PutServerNoLock(tsp);
+ if (code == RX_CALL_DEAD) {
+ lock_ObtainMutex(&tsp->mx);
+ cm_MarkServerDown(tsp, code, isDown);
+ lock_ReleaseMutex(&tsp->mx);
+ }
+ lock_ObtainRead(&cm_serverLock);
+ cm_PutServerNoLock(tsp);
continue;
}
lock_ObtainRead(&cm_serverLock);
rxconns[nconns] = cm_GetRxConn(conns[nconns]);
if (conntimer[nconns] = (isDown ? 1 : 0))
- rx_SetConnDeadTime(rxconns[nconns], 10);
+ rx_SetConnHardDeadTime(rxconns[nconns], 10);
nconns++;
}
/* Process results of servers that support RXAFS_GetCapabilities */
for (i=0; i<nconns; i++) {
if (conntimer[i])
- rx_SetConnDeadTime(rxconns[i], ConnDeadtimeout);
+ rx_SetConnHardDeadTime(rxconns[i], HardDeadtimeout);
rx_PutConnection(rxconns[i]);
cm_PutConn(conns[i]);
cm_RankServer(tsp);
}
} else {
- /* mark server as down */
- if (!(tsp->flags & CM_SERVERFLAG_DOWN)) {
- _InterlockedOr(&tsp->flags, CM_SERVERFLAG_DOWN);
- tsp->downTime = time(NULL);
- }
- if (code != VRESTARTING) {
- lock_ReleaseMutex(&tsp->mx);
- cm_ForceNewConnections(tsp);
- lock_ObtainMutex(&tsp->mx);
- }
- afs_inet_ntoa_r(tsp->addr.sin_addr.S_un.S_addr, hoststr);
+ cm_MarkServerDown(tsp, results[i], wasDown);
+
+ afs_inet_ntoa_r(tsp->addr.sin_addr.S_un.S_addr, hoststr);
osi_Log3(afsd_logp, "cm_MultiPingServer server %s (%s) is down with caps 0x%x",
osi_LogSaveString(afsd_logp, hoststr),
tsp->type == CM_SERVER_VLDB ? "vldb" : "file",
tsp->capabilities);
-
- /* Now update the volume status if necessary */
- if (!wasDown) {
- cm_server_vols_t * tsrvp;
- cm_volume_t * volp;
- int i;
-
- for (tsrvp = tsp->vols; tsrvp; tsrvp = tsrvp->nextp) {
- for (i=0; i<NUM_SERVER_VOLS; i++) {
- if (tsrvp->ids[i] != 0) {
- cm_InitReq(&req);
-
- lock_ReleaseMutex(&tsp->mx);
- code = cm_FindVolumeByID(tsp->cellp, tsrvp->ids[i], cm_rootUserp,
- &req, CM_GETVOL_FLAG_NO_LRU_UPDATE, &volp);
- lock_ObtainMutex(&tsp->mx);
- if (code == 0) {
- cm_UpdateVolumeStatus(volp, tsrvp->ids[i]);
- cm_PutVolume(volp);
- }
- }
- }
- }
- cm_RankServer(tsp);
- }
}
if (tsp->waitCount == 0)
!(flags & (CM_FLAG_CHECKFILESERVERS|CM_FLAG_CHECKVLDBSERVERS)))
{
lock_ObtainRead(&cm_serverLock);
- for (nconns=0, tsp = cm_allServersp; tsp && nconns < maxconns; tsp = tsp->allNextp) {
+ for (nconns=0, tsp = cm_serversAllFirstp;
+ tsp != NULL && nconns < maxconns;
+ tsp = (cm_server_t *)osi_QNext(&tsp->allq)) {
if (tsp->type != CM_SERVER_VLDB ||
tsp->cellp == NULL || /* SetPref only */
cellp && cellp != tsp->cellp)
lock_ReleaseMutex(&tsp->mx);
serversp[nconns] = tsp;
- code = cm_ConnByServer(tsp, cm_rootUserp, FALSE, &conns[nconns]);
+ if (cm_noIPAddr > 0)
+ code = cm_ConnByServer(tsp, cm_rootUserp, FALSE, &conns[nconns]);
+ else
+ code = RX_CALL_DEAD;
if (code) {
- lock_ObtainRead(&cm_serverLock);
+ if (code == RX_CALL_DEAD) {
+ lock_ObtainMutex(&tsp->mx);
+ cm_MarkServerDown(tsp, code, isDown);
+ lock_ReleaseMutex(&tsp->mx);
+ }
+ lock_ObtainRead(&cm_serverLock);
cm_PutServerNoLock(tsp);
continue;
}
rxconns[nconns] = cm_GetRxConn(conns[nconns]);
conntimer[nconns] = (isDown ? 1 : 0);
if (isDown)
- rx_SetConnDeadTime(rxconns[nconns], 10);
+ rx_SetConnHardDeadTime(rxconns[nconns], 10);
nconns++;
}
/* Process results of servers that support VL_ProbeServer */
for (i=0; i<nconns; i++) {
if (conntimer[i])
- rx_SetConnDeadTime(rxconns[i], ConnDeadtimeout);
+ rx_SetConnHardDeadTime(rxconns[i], HardDeadtimeout);
rx_PutConnection(rxconns[i]);
cm_PutConn(conns[i]);
if (wasDown)
cm_RankServer(tsp);
} else {
- /* mark server as down */
- if (!(tsp->flags & CM_SERVERFLAG_DOWN)) {
- _InterlockedOr(&tsp->flags, CM_SERVERFLAG_DOWN);
- tsp->downTime = time(NULL);
- }
- if (code != VRESTARTING) {
- lock_ReleaseMutex(&tsp->mx);
- cm_ForceNewConnections(tsp);
- lock_ObtainMutex(&tsp->mx);
- }
- afs_inet_ntoa_r(tsp->addr.sin_addr.S_un.S_addr, hoststr);
+ cm_MarkServerDown(tsp, results[i], wasDown);
+
+ afs_inet_ntoa_r(tsp->addr.sin_addr.S_un.S_addr, hoststr);
osi_Log3(afsd_logp, "cm_MultiPingServer server %s (%s) is down with caps 0x%x",
osi_LogSaveString(afsd_logp, hoststr),
tsp->type == CM_SERVER_VLDB ? "vldb" : "file",
tsp->capabilities);
- if (!wasDown)
- cm_RankServer(tsp);
}
if (tsp->waitCount == 0)
lock_ReleaseMutex(&serverp->mx);
}
+afs_int32 cm_UpdateIFInfo(void)
+{
+ afs_int32 code;
+ /* get network related info */
+ cm_noIPAddr = CM_MAXINTERFACE_ADDR;
+ code = syscfg_GetIFInfo(&cm_noIPAddr,
+ cm_IPAddr, cm_SubnetMask,
+ cm_NetMtu, cm_NetFlags);
+ cm_LanAdapterChangeDetected = 0;
+ return code;
+}
+
void cm_SetServerIPRank(cm_server_t * serverp)
{
unsigned long serverAddr; /* in host byte order */
unsigned long myAddr, myNet, mySubnet;/* in host byte order */
unsigned long netMask;
int i;
- long code;
+ afs_int32 code;
lock_ObtainRead(&cm_syscfgLock);
if (cm_LanAdapterChangeDetected) {
lock_ConvertRToW(&cm_syscfgLock);
if (cm_LanAdapterChangeDetected) {
- /* get network related info */
- cm_noIPAddr = CM_MAXINTERFACE_ADDR;
- code = syscfg_GetIFInfo(&cm_noIPAddr,
- cm_IPAddr, cm_SubnetMask,
- cm_NetMtu, cm_NetFlags);
- cm_LanAdapterChangeDetected = 0;
- }
+ code = cm_UpdateIFInfo();
+ }
lock_ConvertWToR(&cm_syscfgLock);
}
cm_server_t *cm_NewServer(struct sockaddr_in *socketp, int type, cm_cell_t *cellp, afsUUID *uuidp, afs_uint32 flags) {
cm_server_t *tsp;
+ char hoststr[16];
osi_assertx(socketp->sin_family == AF_INET, "unexpected socket family");
tsp->uuid = *uuidp;
_InterlockedOr(&tsp->flags, CM_SERVERFLAG_UUID);
}
- lock_ReleaseWrite(&cm_serverLock);
+
+ if (cellp != NULL && tsp->cellp == NULL) {
+ tsp->cellp = cellp;
+ afs_inet_ntoa_r(tsp->addr.sin_addr.s_addr, hoststr);
+ osi_Log3(afsd_logp, "cm_NewServer assigning server %s to cell (%u) %s",
+ osi_LogSaveString(afsd_logp,hoststr),
+ cellp->cellID,
+ osi_LogSaveString(afsd_logp,cellp->name));
+ }
+ else if (tsp->cellp != cellp) {
+ afs_inet_ntoa_r(tsp->addr.sin_addr.s_addr, hoststr);
+ osi_Log5(afsd_logp,
+ "cm_NewServer found a server %s associated with two cells (%u) %s and (%u) %s",
+ osi_LogSaveString(afsd_logp,hoststr),
+ tsp->cellp->cellID,
+ osi_LogSaveString(afsd_logp,tsp->cellp->name),
+ cellp->cellID,
+ osi_LogSaveString(afsd_logp,cellp->name));
+ }
+ lock_ReleaseWrite(&cm_serverLock);
return tsp;
}
if (tsp) {
memset(tsp, 0, sizeof(*tsp));
tsp->type = type;
- tsp->cellp = cellp;
if (uuidp && !afs_uuid_is_nil(uuidp)) {
tsp->uuid = *uuidp;
_InterlockedOr(&tsp->flags, CM_SERVERFLAG_UUID);
lock_InitializeMutex(&tsp->mx, "cm_server_t mutex", LOCK_HIERARCHY_SERVER);
tsp->addr = *socketp;
- tsp->allNextp = cm_allServersp;
- cm_allServersp = tsp;
+ osi_QAddH((osi_queue_t **)&cm_serversAllFirstp,
+ (osi_queue_t **)&cm_serversAllLastp, &tsp->allq);
switch (type) {
case CM_SERVER_VLDB:
cm_numFileServers++;
break;
}
+
+ if (cellp != NULL) {
+ tsp->cellp = cellp;
+ afs_inet_ntoa_r(tsp->addr.sin_addr.s_addr, hoststr);
+ osi_Log3(afsd_logp, "cm_NewServer new server %s in cell (%u) %s",
+ osi_LogSaveString(afsd_logp,hoststr),
+ cellp->cellID,
+ osi_LogSaveString(afsd_logp,cellp->name));
+ }
}
lock_ReleaseWrite(&cm_serverLock); /* release server lock */
if (!locked)
lock_ObtainRead(&cm_serverLock);
- for (tsp = cm_allServersp; tsp; tsp = tsp->allNextp) {
+ for (tsp = cm_serversAllFirstp;
+ tsp;
+ tsp = (cm_server_t *)osi_QNext(&tsp->allq)) {
if (tsp->type == type &&
tsp->addr.sin_addr.S_un.S_addr == ipaddr &&
(tsp->addr.sin_port == port || tsp->addr.sin_port == 0))
if (!locked)
lock_ObtainRead(&cm_serverLock);
- for (tsp = cm_allServersp; tsp; tsp = tsp->allNextp) {
- if (tsp->type == type && !afs_uuid_equal(&tsp->uuid, serverUuid))
+ for (tsp = cm_serversAllFirstp;
+ tsp;
+ tsp = (cm_server_t *)osi_QNext(&tsp->allq)) {
+ if (tsp->type == type && afs_uuid_equal(&tsp->uuid, serverUuid))
break;
}
cm_serverRef_t **currentp = list;
cm_serverRef_t **nextp = NULL;
cm_serverRef_t * next = NULL;
+ cm_server_t * serverp = NULL;
for (currentp = list; *currentp; currentp = nextp)
{
nextp = &(*currentp)->next;
+ /* obtain a refcnt on next in case cm_serverLock is dropped */
+ if (*nextp)
+ cm_GetServerRef(*nextp, TRUE);
if ((*currentp)->refCount == 0 &&
(*currentp)->status == srv_deleted) {
next = *nextp;
if ((*currentp)->volID)
cm_RemoveVolumeFromServer((*currentp)->server, (*currentp)->volID);
- cm_FreeServer((*currentp)->server);
+ serverp = (*currentp)->server;
free(*currentp);
nextp = &next;
+ /* cm_FreeServer will drop cm_serverLock if serverp->refCount == 0 */
+ cm_FreeServer(serverp);
}
+ /* drop the next refcnt obtained above. */
+ if (*nextp)
+ cm_PutServerRef(*nextp, TRUE);
}
}
*/
if (serverp->refCount == 0) {
if (!(serverp->flags & CM_SERVERFLAG_PREF_SET)) {
+ osi_QRemoveHT((osi_queue_t **)&cm_serversAllFirstp,
+ (osi_queue_t **)&cm_serversAllLastp,
+ &serverp->allq);
+
switch (serverp->type) {
case CM_SERVER_VLDB:
cm_numVldbServers--;
}
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 the volid list */
for ( tsrvp = serverp->vols; tsrvp; tsrvp = nextp) {
cm_serverRef_t **current;
cm_serverRef_t **nextp;
cm_serverRef_t * next;
+ cm_server_t * serverp;
afs_int32 refCount;
lock_ObtainWrite(&cm_serverLock);
while (*current)
{
nextp = &(*current)->next;
+ /* obtain a refcnt on next in case cm_serverLock is dropped */
+ if (*nextp)
+ cm_GetServerRef(*nextp, TRUE);
refCount = cm_PutServerRef(*current, TRUE);
if (refCount == 0) {
next = *nextp;
if ((*current)->volID)
cm_RemoveVolumeFromServer((*current)->server, (*current)->volID);
- cm_FreeServer((*current)->server);
+ serverp = (*current)->server;
free(*current);
*current = next;
+ /* cm_FreeServer will drop cm_serverLock if serverp->refCount == 0 */
+ cm_FreeServer(serverp);
} else {
if (flags & CM_FREESERVERLIST_DELETE) {
(*current)->status = srv_deleted;
}
current = nextp;
}
+ /* drop the next refcnt obtained above. */
+ if (*current)
+ cm_PutServerRef(*current, TRUE);
}
done:
cookie, cm_numFileServers, cm_numVldbServers);
WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
- for (tsp = cm_allServersp; tsp; tsp=tsp->allNextp)
+ for (tsp = cm_serversAllFirstp;
+ tsp;
+ tsp = (cm_server_t *)osi_QNext(&tsp->allq))
{
char * type;
char * down;
cookie, tsp, tsp->cellp ? tsp->cellp->name : "", hoststr,
ntohs(tsp->addr.sin_port), uuidstr, type,
tsp->capabilities, tsp->flags, tsp->waitCount, tsp->activeRank,
- (tsp->flags & CM_SERVERFLAG_DOWN) ? down : "up",
+ (tsp->flags & CM_SERVERFLAG_DOWN) ? "down" : "up",
tsp->refCount);
WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
}
if (UuidEqual((UUID *)&srv1->uuid, (UUID *)&srv2->uuid, &status))
return 1;
} else {
- if (srv1->flags & CM_SERVERFLAG_UUID)
+ if (srv2->flags & CM_SERVERFLAG_UUID)
return 0;
/* Neither support UUID so perform an addr/port comparison */