static long cm_GetServerList(struct cm_fid *fidp, struct cm_user *userp,
struct cm_req *reqp, cm_serverRef_t ***serversppp)
{
- long code;
+ long code;
cm_volume_t *volp = NULL;
cm_cell_t *cellp = NULL;
if (!fidp) {
- *serversppp = NULL;
- return 0;
- }
+ *serversppp = NULL;
+ return 0;
+ }
- cellp = cm_FindCellByID(fidp->cell);
+ cellp = cm_FindCellByID(fidp->cell);
if (!cellp) return CM_ERROR_NOSUCHCELL;
code = cm_GetVolumeByID(cellp, fidp->volume, userp, reqp, &volp);
*serversppp = cm_GetVolServers(volp, fidp->volume);
cm_PutVolume(volp);
- return 0;
+ return 0;
}
/*
cm_serverRef_t * serversp,
cm_callbackRequest_t *cbrp, long errorCode)
{
- cm_server_t *serverp = 0;
- cm_serverRef_t **serverspp = 0;
+ cm_server_t *serverp = NULL;
+ cm_serverRef_t **serverspp = NULL;
cm_serverRef_t *tsrp;
+ cm_cell_t *cellp = NULL;
cm_ucell_t *ucellp;
int retry = 0;
int free_svr_list = 0;
int dead_session;
long timeUsed, timeLeft;
+ long code;
osi_Log2(afsd_logp, "cm_Analyze connp 0x%x, code 0x%x",
(long) connp, errorCode);
if (errorCode == CM_ERROR_TIMEDOUT) {
if (timeLeft > 5 ) {
thrd_Sleep(3000);
- cm_CheckServers(CM_FLAG_CHECKDOWNSERVERS, NULL);
+ if (cellp == NULL && serverp)
+ cellp = serverp->cellp;
+ if (cellp == NULL && serversp) {
+ struct cm_serverRef * refp;
+ for ( refp=serversp ; cellp == NULL && refp != NULL; refp=refp->next) {
+ if ( refp->server )
+ cellp = refp->server->cellp;
+ }
+ }
+ cm_CheckServers(CM_FLAG_CHECKDOWNSERVERS, cellp);
retry = 1;
}
}
- /* if all servers are offline, mark them non-busy and start over */
+ /* if there is nosuchvolume, then we have a situation in which a
+ * previously known volume no longer has a set of servers
+ * associated with it. Either the volume has moved or
+ * the volume has been deleted. Try to find a new server list
+ * until the timeout period expires.
+ */
+ else if (errorCode == CM_ERROR_NOSUCHVOLUME) {
+ if (timeLeft > 7) {
+ osi_Log0(afsd_logp, "cm_Analyze passed CM_ERROR_NOSUCHVOLUME.");
+ thrd_Sleep(5000);
+
+ retry = 1;
+
+ if (fidp != NULL) /* Not a VLDB call */
+ cm_ForceUpdateVolume(fidp, userp, reqp);
+ }
+ }
+
else if (errorCode == CM_ERROR_ALLOFFLINE) {
if (timeLeft > 7) {
osi_Log0(afsd_logp, "cm_Analyze passed CM_ERROR_ALLOFFLINE.");
thrd_Sleep(5000);
+
/* cm_ForceUpdateVolume marks all servers as non_busy */
/* No it doesn't and it won't do anything if all of the
* the servers are marked as DOWN. So clear the DOWN
* flag and reset the busy state as well.
*/
if (!serversp) {
- cm_GetServerList(fidp, userp, reqp, &serverspp);
- serversp = *serverspp;
- free_svr_list = 1;
+ code = cm_GetServerList(fidp, userp, reqp, &serverspp);
+ if (code == 0) {
+ serversp = *serverspp;
+ free_svr_list = 1;
+ }
}
if (serversp) {
lock_ObtainWrite(&cm_serverLock);
if (fidp != NULL) /* Not a VLDB call */
cm_ForceUpdateVolume(fidp, userp, reqp);
+ else
+ retry = 0;
}
}
if (timeLeft > 7) {
thrd_Sleep(5000);
if (!serversp) {
- cm_GetServerList(fidp, userp, reqp, &serverspp);
- serversp = *serverspp;
- free_svr_list = 1;
+ code = cm_GetServerList(fidp, userp, reqp, &serverspp);
+ if (code == 0) {
+ serversp = *serverspp;
+ free_svr_list = 1;
+ }
}
lock_ObtainWrite(&cm_serverLock);
for (tsrp = serversp; tsrp; tsrp=tsrp->next) {
/* special codes: VBUSY and VRESTARTING */
else if (errorCode == VBUSY || errorCode == VRESTARTING) {
if (!serversp) {
- cm_GetServerList(fidp, userp, reqp, &serverspp);
- serversp = *serverspp;
- free_svr_list = 1;
+ code = cm_GetServerList(fidp, userp, reqp, &serverspp);
+ if (code == 0) {
+ serversp = *serverspp;
+ free_svr_list = 1;
+ }
}
lock_ObtainWrite(&cm_serverLock);
for (tsrp = serversp; tsrp; tsrp=tsrp->next) {
}
/* special codes: missing volumes */
- else if (errorCode == VNOVOL || errorCode == VMOVED || errorCode == VOFFLINE
- || errorCode == VSALVAGE || errorCode == VNOSERVICE)
+ else if (errorCode == VNOVOL || errorCode == VMOVED || errorCode == VOFFLINE ||
+ errorCode == VSALVAGE || errorCode == VNOSERVICE || errorCode == VIO)
{
/* Log server being offline for this volume */
osi_Log4(afsd_logp, "cm_Analyze found server %d.%d.%d.%d marked offline for a volume",
/* Mark server offline for this volume */
if (!serversp) {
- cm_GetServerList(fidp, userp, reqp, &serverspp);
- serversp = *serverspp;
- free_svr_list = 1;
+ code = cm_GetServerList(fidp, userp, reqp, &serverspp);
+ if (code == 0) {
+ serversp = *serverspp;
+ free_svr_list = 1;
+ }
}
for (tsrp = serversp; tsrp; tsrp=tsrp->next) {
if (tsrp->server == serverp)
if ( timeLeft > 2 )
retry = 1;
}
- else if (errorCode == RXKADEXPIRED) {
+ else if (errorCode == RXKADEXPIRED ||
+ errorCode == RXKADBADTICKET) {
if (!dead_session) {
lock_ObtainMutex(&userp->mx);
ucellp = cm_GetUCell(userp, serverp->cellp);
retry = 1;
}
} else {
- if (errorCode)
- osi_Log1(afsd_logp, "cm_Analyze: ignoring error code 0x%x", errorCode);
+ if (errorCode) {
+ char * s = "unknown error";
+ switch ( errorCode ) {
+ case RXKADINCONSISTENCY: s = "RXKADINCONSISTENCY"; break;
+ case RXKADPACKETSHORT : s = "RXKADPACKETSHORT"; break;
+ case RXKADLEVELFAIL : s = "RXKADLEVELFAIL"; break;
+ case RXKADTICKETLEN : s = "RXKADTICKETLEN"; break;
+ case RXKADOUTOFSEQUENCE: s = "RXKADOUTOFSEQUENCE"; break;
+ case RXKADNOAUTH : s = "RXKADNOAUTH"; break;
+ case RXKADBADKEY : s = "RXKADBADKEY"; break;
+ case RXKADBADTICKET : s = "RXKADBADTICKET"; break;
+ case RXKADUNKNOWNKEY : s = "RXKADUNKNOWNKEY"; break;
+ case RXKADEXPIRED : s = "RXKADEXPIRED"; break;
+ case RXKADSEALEDINCON : s = "RXKADSEALEDINCON"; break;
+ case RXKADDATALEN : s = "RXKADDATALEN"; break;
+ case RXKADILLEGALLEVEL : s = "RXKADILLEGALLEVEL"; break;
+ case VSALVAGE : s = "VSALVAGE"; break;
+ case VNOVNODE : s = "VNOVNODE"; break;
+ case VNOVOL : s = "VNOVOL"; break;
+ case VVOLEXISTS : s = "VVOLEXISTS"; break;
+ case VNOSERVICE : s = "VNOSERVICE"; break;
+ case VOFFLINE : s = "VOFFLINE"; break;
+ case VONLINE : s = "VONLINE"; break;
+ case VDISKFULL : s = "VDISKFULL"; break;
+ case VOVERQUOTA : s = "VOVERQUOTA"; break;
+ case VBUSY : s = "VBUSY"; break;
+ case VMOVED : s = "VMOVED"; break;
+ case VIO : s = "VIO"; break;
+ case VRESTRICTED : s = "VRESTRICTED"; break;
+ case VRESTARTING : s = "VRESTARTING"; break;
+ case VREADONLY : s = "VREADONLY"; break;
+ }
+ osi_Log2(afsd_logp, "cm_Analyze: ignoring error code 0x%x (%s)",
+ errorCode, s);
+ retry = 0;
+ }
}
if (retry && dead_session)