recovery: trigger recovery on RESTART_RECLAIM_NEEDED
adds a check for sequence flag SEQ4_STATUS_RESTART_RECLAIM_NEEDED in nfs41_recover_sequence_flags(). if other _STATE_REVOKED flags are set, call nfs41_client_state_revoked() as normal but follow it up with a RECLAIM_COMPLETE. otherwise, reclaim all locks with nfs41_recover_client_state(). like other callers of nfs41_recover_client_state(), we need to handle BADSESSION errors because the recovery operations are sent with try_recovery=FALSE. because this logic is similar to our default NFS4ERR_BADSESSION handling, i moved the common code into a new nfs41_recover_session() function in recovery.c Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
This commit is contained in:
parent
ab51beeb98
commit
6c1c300a3b
3 changed files with 62 additions and 30 deletions
|
|
@ -150,7 +150,6 @@ int compound_encode_send_decode(
|
||||||
int status, retry_count = 0, delayby = 0, secinfo_status;
|
int status, retry_count = 0, delayby = 0, secinfo_status;
|
||||||
nfs41_sequence_args *args = (nfs41_sequence_args *)
|
nfs41_sequence_args *args = (nfs41_sequence_args *)
|
||||||
compound->args.argarray[0].arg;
|
compound->args.argarray[0].arg;
|
||||||
bool_t client_state_lost = FALSE;
|
|
||||||
uint32_t saved_sec_flavor;
|
uint32_t saved_sec_flavor;
|
||||||
AUTH *saved_auth;
|
AUTH *saved_auth;
|
||||||
int op1 = compound->args.argarray[0].op;
|
int op1 = compound->args.argarray[0].op;
|
||||||
|
|
@ -218,14 +217,13 @@ retry:
|
||||||
goto out;
|
goto out;
|
||||||
if (!nfs41_recovery_start_or_wait(session->client))
|
if (!nfs41_recovery_start_or_wait(session->client))
|
||||||
goto do_retry;
|
goto do_retry;
|
||||||
//try to create a new client
|
// try to create a new client
|
||||||
status = nfs41_client_renew(session->client);
|
status = nfs41_client_renew(session->client);
|
||||||
|
|
||||||
nfs41_recovery_finish(session->client);
|
nfs41_recovery_finish(session->client);
|
||||||
if (status) {
|
if (status) {
|
||||||
eprintf("nfs41_exchange_id() failed with %d\n", status);
|
eprintf("nfs41_client_renew() failed with %d\n", status);
|
||||||
status = ERROR_BAD_NET_RESP;
|
status = ERROR_BAD_NET_RESP;
|
||||||
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
if (op1 == OP_CREATE_SESSION) {
|
if (op1 == OP_CREATE_SESSION) {
|
||||||
|
|
@ -243,31 +241,15 @@ retry:
|
||||||
goto out;
|
goto out;
|
||||||
if (!nfs41_recovery_start_or_wait(session->client))
|
if (!nfs41_recovery_start_or_wait(session->client))
|
||||||
goto do_retry;
|
goto do_retry;
|
||||||
restart_recovery:
|
// try to create a new session
|
||||||
//try to create a new session
|
status = nfs41_recover_session(session, FALSE);
|
||||||
status = nfs41_session_renew(session);
|
|
||||||
if (status == NFS4ERR_STALE_CLIENTID) {
|
nfs41_recovery_finish(session->client);
|
||||||
client_state_lost = TRUE;
|
|
||||||
status = nfs41_client_renew(session->client);
|
|
||||||
if (status) {
|
if (status) {
|
||||||
eprintf("nfs41_exchange_id() failed with %d\n", status);
|
eprintf("nfs41_recover_session() failed with %d\n", status);
|
||||||
status = ERROR_BAD_NET_RESP;
|
status = ERROR_BAD_NET_RESP;
|
||||||
nfs41_recovery_finish(session->client);
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
goto restart_recovery;
|
|
||||||
} else if (status) {
|
|
||||||
eprintf("nfs41_session_renew: failed with %d\n", status);
|
|
||||||
nfs41_recovery_finish(session->client);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
if (client_state_lost) {
|
|
||||||
/* do client state recovery */
|
|
||||||
status = nfs41_recover_client_state(session, session->client);
|
|
||||||
if (status == NFS4ERR_BADSESSION)
|
|
||||||
goto restart_recovery;
|
|
||||||
}
|
|
||||||
nfs41_recovery_finish(session->client);
|
|
||||||
goto do_retry;
|
goto do_retry;
|
||||||
|
|
||||||
case NFS4ERR_EXPIRED: /* revoked by lease expiration */
|
case NFS4ERR_EXPIRED: /* revoked by lease expiration */
|
||||||
|
|
|
||||||
|
|
@ -70,6 +70,36 @@ void nfs41_recovery_finish(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* session/client/state recovery */
|
||||||
|
int nfs41_recover_session(
|
||||||
|
IN nfs41_session *session,
|
||||||
|
IN bool_t client_state_lost)
|
||||||
|
{
|
||||||
|
enum nfsstat4 status = NFS4_OK;
|
||||||
|
|
||||||
|
restart_recovery:
|
||||||
|
/* recover the session */
|
||||||
|
status = nfs41_session_renew(session);
|
||||||
|
|
||||||
|
if (status == NFS4ERR_STALE_CLIENTID) {
|
||||||
|
/* recover the client */
|
||||||
|
client_state_lost = TRUE;
|
||||||
|
status = nfs41_client_renew(session->client);
|
||||||
|
if (status == NFS4_OK)
|
||||||
|
goto restart_recovery; /* resume session recovery */
|
||||||
|
|
||||||
|
eprintf("nfs41_client_renew() failed with %d\n", status);
|
||||||
|
} else if (status) {
|
||||||
|
eprintf("nfs41_session_renew() failed with %d\n", status);
|
||||||
|
} else if (client_state_lost) {
|
||||||
|
/* recover the client's state */
|
||||||
|
status = nfs41_recover_client_state(session, session->client);
|
||||||
|
if (status == NFS4ERR_BADSESSION)
|
||||||
|
goto restart_recovery;
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
void nfs41_recover_sequence_flags(
|
void nfs41_recover_sequence_flags(
|
||||||
IN nfs41_session *session,
|
IN nfs41_session *session,
|
||||||
IN uint32_t flags)
|
IN uint32_t flags)
|
||||||
|
|
@ -78,16 +108,32 @@ void nfs41_recover_sequence_flags(
|
||||||
(SEQ4_STATUS_EXPIRED_ALL_STATE_REVOKED
|
(SEQ4_STATUS_EXPIRED_ALL_STATE_REVOKED
|
||||||
| SEQ4_STATUS_EXPIRED_SOME_STATE_REVOKED
|
| SEQ4_STATUS_EXPIRED_SOME_STATE_REVOKED
|
||||||
| SEQ4_STATUS_ADMIN_STATE_REVOKED);
|
| SEQ4_STATUS_ADMIN_STATE_REVOKED);
|
||||||
|
const uint32_t restarted = flags &
|
||||||
|
SEQ4_STATUS_RESTART_RECLAIM_NEEDED;
|
||||||
|
|
||||||
/* no state recovery needed */
|
/* no state recovery needed */
|
||||||
if (revoked == 0)
|
if (revoked == 0 && restarted == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!nfs41_recovery_start_or_wait(session->client))
|
if (!nfs41_recovery_start_or_wait(session->client))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (revoked) {
|
||||||
/* free stateids and attempt to recover them */
|
/* free stateids and attempt to recover them */
|
||||||
nfs41_client_state_revoked(session, session->client, revoked);
|
nfs41_client_state_revoked(session, session->client, revoked);
|
||||||
|
|
||||||
|
/* if RESTART_RECLAIM_NEEDED is also set, just do RECLAIM_COMPLETE */
|
||||||
|
if (restarted) nfs41_reclaim_complete(session);
|
||||||
|
|
||||||
|
} else if (restarted) {
|
||||||
|
/* do server reboot state recovery */
|
||||||
|
uint32_t status = nfs41_recover_client_state(session, session->client);
|
||||||
|
if (status == NFS4ERR_BADSESSION) {
|
||||||
|
/* recover the session and finish state recovery */
|
||||||
|
nfs41_recover_session(session, TRUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
nfs41_recovery_finish(session->client);
|
nfs41_recovery_finish(session->client);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,10 @@ void nfs41_recovery_finish(
|
||||||
IN nfs41_client *client);
|
IN nfs41_client *client);
|
||||||
|
|
||||||
|
|
||||||
|
int nfs41_recover_session(
|
||||||
|
IN nfs41_session *session,
|
||||||
|
IN bool_t client_state_lost);
|
||||||
|
|
||||||
void nfs41_recover_sequence_flags(
|
void nfs41_recover_sequence_flags(
|
||||||
IN nfs41_session *session,
|
IN nfs41_session *session,
|
||||||
IN uint32_t flags);
|
IN uint32_t flags);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue