#include <WINNT/afsreg.h>
#include <osi.h>
#include <rx/rx.h>
+#include <math.h>
osi_rwlock_t cm_serverLock;
osi_rwlock_t cm_syscfgLock;
lock_ReleaseRead(&cm_serverLock);
}
+/*
+ * lock_ObtainMutex must be held prior to calling
+ * this function.
+ */
+afs_int32
+cm_RankServer(cm_server_t * tsp)
+{
+ afs_int32 code = 0; /* start with "success" */
+ struct rx_debugPeer tpeer;
+ afs_uint16 port;
+ afs_uint16 newRank;
+
+ switch(tsp->type) {
+ case CM_SERVER_VLDB:
+ port = htons(7003);
+ break;
+ case CM_SERVER_FILE:
+ port = htons(7000);
+ break;
+ default:
+ return -1;
+ }
+
+ code = rx_GetLocalPeers(tsp->addr.sin_addr.s_addr, port, &tpeer);
+
+ /*check if rx_GetLocalPeers succeeded and if there is data for tsp */
+ if(code == 0 && (tpeer.rtt == 0 && tpeer.rtt_dev == 0))
+ code = -1;
+
+ if(code == 0) {
+ if((tsp->flags & CM_SERVERFLAG_PREF_SET))
+ newRank = tsp->adminRank +
+ ((int)(623 * log(tpeer.rtt) / 10) * 10 + 5);
+ else /* rank has not been set by admin, derive rank from rtt */
+ newRank = (int)(7200 * log(tpeer.rtt) / 5000) * 5000 + 5000;
+
+ newRank += (rand() & 0x000f); /* randomize */
+
+ if (abs(newRank - tsp->ipRank) > 0xf) {
+ tsp->ipRank = newRank;
+
+ lock_ReleaseMutex(&tsp->mx);
+ switch (tsp->type) {
+ case CM_SERVER_FILE:
+ /*
+ * find volumes which might have RO copy
+ * on server and change the ordering of
+ * their RO list
+ */
+ cm_ChangeRankVolume(tsp);
+ break;
+ case CM_SERVER_VLDB:
+ /* set preferences for an existing vlserver */
+ cm_ChangeRankCellVLServer(tsp);
+ break;
+ }
+ lock_ObtainMutex(&tsp->mx);
+ }
+ }
+
+ return code;
+}
+
void
cm_PingServer(cm_server_t *tsp)
{
/* we currently handle 32-bits of capabilities */
if (caps.Capabilities_len > 0) {
tsp->capabilities = caps.Capabilities_val[0];
- xdr_free(caps.Capabilities_val, caps.Capabilities_len);
+ xdr_free((xdrproc_t) xdr_Capabilities, &caps);
caps.Capabilities_len = 0;
caps.Capabilities_val = 0;
} else {
lock_ReleaseMutex(&tsp->mx);
}
+void
+cm_RankUpServers()
+{
+ cm_server_t * tsp;
+
+ lock_ObtainRead(&cm_serverLock);
+ for (tsp = cm_allServersp; tsp; tsp = tsp->allNextp) {
+ cm_GetServerNoLock(tsp);
+ lock_ReleaseRead(&cm_serverLock);
+
+ lock_ObtainMutex(&tsp->mx);
+
+ /* if the server is not down, rank the server */
+ if(!(tsp->flags & CM_SERVERFLAG_DOWN))
+ cm_RankServer(tsp);
+
+ lock_ReleaseMutex(&tsp->mx);
+
+ lock_ObtainRead(&cm_serverLock);
+ cm_PutServerNoLock(tsp);
+ }
+ lock_ReleaseRead(&cm_serverLock);
+}
+
static void cm_CheckServersSingular(afs_uint32 flags, cm_cell_t *cellp)
{
/* ping all file servers, up or down, with unauthenticated connection,
int doPing;
int isDown;
int isFS;
+ int isVLDB;
lock_ObtainRead(&cm_serverLock);
for (tsp = cm_allServersp; tsp; tsp = tsp->allNextp) {
doPing = 0;
isDown = tsp->flags & CM_SERVERFLAG_DOWN;
isFS = tsp->type == CM_SERVER_FILE;
+ isVLDB = tsp->type == CM_SERVER_VLDB;
/* 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
((isDown && (flags & CM_FLAG_CHECKDOWNSERVERS)) ||
(!isDown && (flags & CM_FLAG_CHECKUPSERVERS))) &&
((!(flags & CM_FLAG_CHECKVLDBSERVERS) ||
- !isFS && (flags & CM_FLAG_CHECKVLDBSERVERS)) &&
+ isVLDB && (flags & CM_FLAG_CHECKVLDBSERVERS)) &&
(!(flags & CM_FLAG_CHECKFILESERVERS) ||
isFS && (flags & CM_FLAG_CHECKFILESERVERS)))) {
doPing = 1;
/* we currently handle 32-bits of capabilities */
if (caps[i].Capabilities_len > 0) {
tsp->capabilities = caps[i].Capabilities_val[0];
- xdr_free(caps[i].Capabilities_val, caps[i].Capabilities_len);
+ xdr_free((xdrproc_t) xdr_Capabilities, &caps[i]);
caps[i].Capabilities_len = 0;
caps[i].Capabilities_val = 0;
} else {
}
serverAddr = ntohl(serverp->addr.sin_addr.s_addr);
- serverp->ipRank = CM_IPRANK_LOW; /* default setings */
+ serverp->ipRank = CM_IPRANK_LOW; /* default settings */
for ( i=0; i < cm_noIPAddr; i++)
{
}
cm_server_t *
-cm_FindServerByIP(afs_uint32 ipaddr, int type)
+cm_FindServerByIP(afs_uint32 ipaddr, unsigned short port, int type)
{
cm_server_t *tsp;
lock_ObtainRead(&cm_serverLock);
for (tsp = cm_allServersp; tsp; tsp = tsp->allNextp) {
if (tsp->type == type &&
- tsp->addr.sin_addr.S_un.S_addr == ipaddr)
+ tsp->addr.sin_addr.S_un.S_addr == ipaddr &&
+ (tsp->addr.sin_port == port || tsp->addr.sin_port == 0))
break;
}
cm_serverRef_t **nextp = 0;
cm_serverRef_t * next = 0;
- if (*list == NULL)
- return;
-
lock_ObtainWrite(&cm_serverLock);
+ if (*list == NULL)
+ goto done;
+
while (*current)
{
nextp = &(*current)->next;
}
}
+ done:
+
lock_ReleaseWrite(&cm_serverLock);
}
if (lock)
lock_ObtainRead(&cm_serverLock);
- sprintf(output, "%s - dumping servers - cm_numFileServers=%d, cm_numVldbServers=%d\r\n",
+ sprintf(output,
+ "%s - dumping servers - cm_numFileServers=%d, cm_numVldbServers=%d\r\n",
cookie, cm_numFileServers, cm_numVldbServers);
WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
down = ctime(&tsp->downTime);
down[strlen(down)-1] = '\0';
- sprintf(output, "%s - tsp=0x%p cell=%s addr=%-15s uuid=%s type=%s caps=0x%x flags=0x%x waitCount=%u rank=%u downTime=\"%s\" refCount=%u\r\n",
- cookie, tsp, tsp->cellp ? tsp->cellp->name : "", hoststr, uuidstr, type,
- tsp->capabilities, tsp->flags, tsp->waitCount, tsp->ipRank,
+ sprintf(output,
+ "%s - tsp=0x%p cell=%s addr=%-15s port=%u uuid=%s type=%s caps=0x%x "
+ "flags=0x%x waitCount=%u rank=%u downTime=\"%s\" refCount=%u\r\n",
+ cookie, tsp, tsp->cellp ? tsp->cellp->name : "", hoststr,
+ ntohs(tsp->addr.sin_port), uuidstr, type,
+ tsp->capabilities, tsp->flags, tsp->waitCount, tsp->ipRank,
(tsp->flags & CM_SERVERFLAG_DOWN) ? down : "up",
tsp->refCount);
WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);