Skip to contentSkip to conversation

nfs4 client loops printing "Error: state manager encountered RPCSEC_GSS session expired" if kerberos ticket expires

BUG John Hughes 1 participant 3 messages Nov 10, 2011 – Nov 16, 2011

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

We mount user home directories (using automount) from an nfs4 server with sec=krb5.

Using older kernels (2.6.32 for example) when the user ticket expires attempts to access the mount get EPERM. This is no big deal, the workstation is probably in the screensaver so the user enters her password, a new ticket is granted and everything carries on.

At some point (before or after 2.6.39) this behaviour changed.

Now attempts to access the mount point hang and an endless stream of:

Error: state manager encountered RPCSEC_GSS session expired against NFSv4 server xxxx

messages is printed to the kernel log. The user doesn't get prompted for a password and can only get a new ticket by moving to a text console and logging in again (which unblocks things).

(This is Debian bug http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=648155 and Ubuntu bug https://bugs.launchpad.net/ubuntu/+bug/794112 ).

The client is Debian Sid, with kernel 3.1.0-rc10 on a Dell core i5 based Optiplex 390. (The same problem occurs in the standard Debian 3.0 kernel).

Linux cretic 3.1.0-rc10 #1 SMP Thu Nov 10 11:45:46 CET 2011 x86_64 GNU/Linux

The server is Debian Squeeze, kernel 2.6.32.

What should I be trying to do to debug this?

#1 lore raw

Here is a ridiculously stupid patch that fixes the behaviour to be closer to what I want.

Now, if the krb5 ticket has expired processes get a EKEYEXPIRED error and the kernel doesn't waste its time printing "ticket expired" errors.

From the point of view of someone who has their home directory nfs mounted they go home after work, when they get back in the morning they give their password to the screensaver, pam_krb5 gets a new ticket and everything works.

(Without this hack the screensaver hangs before presenting the password prompt, presumably accessing something in the home directory).

Anyone care to comment?

fs/nfs/nfs4proc.c +4 -0
index 4700fae..3101f84 100644
@@ -302,7 +302,9 @@ static int nfs4_handle_exception(struct nfs_server *server, int errorcode, struc
 			}
 		case -NFS4ERR_GRACE:
 		case -NFS4ERR_DELAY:
+#if 0			/* JH hack - don't handle KRB5 ticket expiry */
 		case -EKEYEXPIRED:
+#endif
 			ret = nfs4_delay(server->client, &exception->timeout);
 			if (ret != 0)
 				break;
@@ -3732,7 +3734,9 @@ nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server,
 		case -NFS4ERR_DELAY:
 			nfs_inc_server_stats(server, NFSIOS_DELAY);
 		case -NFS4ERR_GRACE:
+#if 0			/* JH hack - don't handle KRB5 ticket expiry */
 		case -EKEYEXPIRED:
+#endif
 			rpc_delay(task, NFS4_POLL_RETRY_MAX);
 			task->tk_status = 0;
 			return -EAGAIN;
fs/nfs/nfs4state.c +2 -0
index 39914be..0137ec9 100644
@@ -1376,10 +1376,12 @@ static int nfs4_recovery_handle_error(struct nfs_client *clp, int error)
 			set_bit(NFS4CLNT_SESSION_RESET, &clp->cl_state);
 			/* Zero session reset errors */
 			return 0;
+#if 0			/* JH hack: If there is nothing to do, do nothing */
 		case -EKEYEXPIRED:
 			/* Nothing we can do */
 			nfs4_warn_keyexpired(clp->cl_hostname);
 			return 0;
+#endif
 	}
 	return error;
 }
#2 lore raw
Quoted 3 lines · John Hughes

Here is a ridiculously stupid patch that fixes the behaviour to be closer to what I want.

Now, if the krb5 ticket has expired processes get a EKEYEXPIRED error and the kernel doesn't waste its time printing "ticket expired" errors.

A slight modification of the patch is needed to avoid scads of "state manager failed" errors, if we get EKEYEXPIRED in nfs4_recovery_handle_error we *should* return zero, but we don't want to call nfs4_warn_keyexpired (there is no reason to log this, it's not a kernel problem).

Here's a cleaner version of the patch.

Does anybody care about this? Will anybody read this message?

fs/nfs/nfs4proc.c +0 -2
index 4700fae..dc28a78 100644
@@ -302,7 +302,6 @@ static int nfs4_handle_exception(struct nfs_server *server, int errorcode, struc
 			}
 		case -NFS4ERR_GRACE:
 		case -NFS4ERR_DELAY:
-		case -EKEYEXPIRED:
 			ret = nfs4_delay(server->client, &exception->timeout);
 			if (ret != 0)
 				break;
@@ -3732,7 +3731,6 @@ nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server,
 		case -NFS4ERR_DELAY:
 			nfs_inc_server_stats(server, NFSIOS_DELAY);
 		case -NFS4ERR_GRACE:
-		case -EKEYEXPIRED:
 			rpc_delay(task, NFS4_POLL_RETRY_MAX);
 			task->tk_status = 0;
 			return -EAGAIN;
fs/nfs/nfs4state.c +3 -2
index 39914be..2bee41e 100644
@@ -1377,8 +1377,9 @@ static int nfs4_recovery_handle_error(struct nfs_client *clp, int error)
 			/* Zero session reset errors */
 			return 0;
 		case -EKEYEXPIRED:
-			/* Nothing we can do */
-			nfs4_warn_keyexpired(clp->cl_hostname);
+			/* Nothing we can do, so do nothing.  Don't even
+			   print a warning message, this is not a kernel
+			   problem */
 			return 0;
 	}
 	return error;