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>
new function nfs41_recover_sequence_flags() in recovery.c takes care of checking status flags, entering recovery mode, and reclaiming state
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
if any of (SEQ4_STATUS_EXPIRED_ALL_STATE_REVOKED | SEQ4_STATUS_EXPIRED_SOME_STATE_REVOKED | SEQ4_STATUS_ADMIN_STATE_REVOKED) are set in the session flags returned by SEQUENCE:
* enter client recovery mode
* determine which state was lost with TEST_STATEID (consider all delegations, opens, locks, and layouts)
* send FREE_STATEID for each stateid revoked
* recall all layouts and forget devices (required by 12.7.2: Dealing with Lease Expiration on the Client)
* call recover_delegation(), recover_open() or recover_locks() to reclaim each lock
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
added 2011 year to the copyright line
added authors info to the license
added UofM license to libtirpc files that we modified
(but i probably missed some)
recovery.h exposes the following functions for nfs41_compound.c:
nfs41_recovery_start_or_wait()
nfs41_recovery_finish()
nfs41_recover_client_state()
nfs41_recover_stateid()
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
combined nfs41_open() and nfs41_open_reclaim() into nfs41_rpc_open() by factoring out the open_claim4 argument. new function nfs41_open() in open.c deals with the nfs41_open_state, adding it to the client's list, and handles any delegations granted
added xdr for OPEN CLAIM types CLAIM_DELEGATE_CUR, CLAIM_DELEG_CUR_FH, CLAIM_DELEGATE_PREV, CLAIM_DELEG_PREV_FH (the _FH types are new to 4.1, and not supported by linux server)
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
handling receiving WRONGSEC error in compound_encode_decode function by
sending either SECINFO or SECINFO_NONAME op to find out available
security flavors from the server. then try to establish new security
context given the ordered list returned by the server.
Not handling if parent directory doesn't permit a security flavor of
its child directory. Example "/" exported with only auth_sys and
"/sec" exported with only "gss".
if we are doing CREATE_NEW file creation, then based on whether or not
we have a persistent session, we'll send either GUARDED4 create for
persistent session and EXCLUSIVE4_1 create otherwise.
send CREATE_SESSION with compound_encode_send_decode() instead of nfs41_send_compound() for its NFS4ERR_DELAY and NFS4ERR_STALE_CLIENTID handling
added 'try_recovery' argument to nfs41_create_session(), which is passed on to compound_encode_send_decode(). nfs41_session_renew() uses try_recovery=FALSE, because it handles the NFS4ERR_STALE_CLIENTID error on its own. nfs41_session_create() uses try_recovery=TRUE to make use of the NFS4ERR_STALE_CLIENTID error handling. modified the NFS4ERR_STALE_CLIENTID block to call nfs41_client_renew() and retry the operation (i.e. CREATE_SESSION), instead of falling through to session recovery
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
12.7.4. Recovery from Metadata Server Restart
"The client MUST stop using layouts and delete the device ID to device address mappings it previously received from the metadata server."
during client state recovery, call pnfs_file_layout_recall() to revoke all layouts and devices held by the client
LAYOUTGET, LAYOUTRETURN, and GETDEVICEINFO are all sent under their respective locks, and pnfs_file_layout_recall() requires a lock on each layout and device it operates on, so this would cause a deadlock if one of those operations triggered the recovery. to avoid this, LAYOUTGET, LAYOUTRETURN, and GETDEVICEINFO are all sent with try_recovery=FALSE. this behavior is preferable for recovery, because errors in the pnfs path cause us to fall back to the metadata server
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
if we're recovering a lock stateid for a LOCK operation, and the file has no outstanding locks, we won't be able to recover a lock stateid. resend the LOCK with an open stateid instead
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
if we see NFS4ERR_NO_GRACE from recovery operations, it means we lost our state due to a lease expiration rather than a server reboot. in this case, it's possible that conflicting locks were granted to other clients, so we have to try normal OPEN/LOCK operations to recover our state. because they're sent during recovery, nfs41_open() and nfs41_lock() take a new 'bool_t try_recovery' argument so we can avoid recursion
if these operations fail due to conflicting locks, we have no choice but to return errors to the application. using a stateid that was revoked due to lease expiration results in NFS4ERR_EXPIRED, and we map this error to ERROR_FILE_INVALID: The volume for a file has been externally altered so that the opened file is no longer valid.
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
nfs41_open_state maintains a list of outstanding byte-range locks by calling open_lock_add() and open_lock_remove() in lock.c
during client state recovery, after reclaiming each OPEN stateid, send LOCK requests with reclaim=TRUE for each lock it owns, and update the open's lock stateid with the result
added 'bool_t reclaim' argument to nfs41_lock(); when set, compound_encode_send_decode() is called with try_recovery=FALSE to avoid recursive recovery
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
avoid the recursive case where state recovery operations (OPEN for reclaim and RECLAIM_COMPLETE) return BADSESSION, which kicks off another round of recovery
added a 'bool_t try_recovery' argument to compound_encode_send_decode() in place of its unused 'bufsize_in' and 'bufsize_out'. when try_recovery=FALSE, return BADSESSION/STALE_CLIENTID errors instead of attempting recovery. nfs41_open_reclaim(), nfs41_reclaim_complete(), and nfs41_destroy_session() now pass try_recovery=FALSE
during state recovery, we can now check the return values of nfs41_open_reclaim() and nfs41_reclaim_complete() for BADSESSION, and use a goto to restart session recovery
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
moved recovery-related fields into struct nfs41_client.recovery. now uses a com
bination of CRITICAL_SECTION and CONDITION_VARIABLE for use with SleepConditionV
ariableCS()
renamed check_renew_in_progress() to recovery_start_or_wait(), and fixed the loc
king so that we atomically check/set in_recovery
when recovery is finished (including error conditions), call recovery_finish() t
o reset the recovery status and wake any waiting threads
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
consider an operation that takes a stateid, and results in a BADSESSION error due to server reboot. we'll recover the client and session, and send OPENs to reclaim all of the client's state. but after recovery, we'll resend the original operation with the original stateid, and this will result in a STALE_STATEID error
we handle this by making use of the information in stateid_arg. if we determine that stateid_arg.stateid is different from the nfs41_open_state's stateid, we copy the new stateid into stateid_arg.stateid and retry
note that if another thread is in recovery, it hasn't finished reclaiming its open state yet; so we wait on recovery to finish before comparing the stateids
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
after the client and session have been recovered, loop through the client's list of open state, calling nfs41_open_reclaim() and updating the stateid on success
nfs41_open_state saves the share_access and share_deny fields from the initial open, for use with nfs41_open_reclaim()
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>