avg@ reported a crash where the nr_client (krpc client structure ptr) was NULL during an
upcall to the nfsuserd daemon. nr_client is only NULL when the nfsuserd is shut down or
shutting down.
Upon inspection, two races were identified. The first is seems likely to be the cause of the crash.
- At the beginning of nfsrv_getuser(), the nfsrv_nfsuserd variable was checked to see if the daemon was running, but then the upcall RPC was done sometime later via newnfs_request(), leaving a window during which nfsuserd shutdown could have occurred. --> This patch adds code to acquire a reference count on the structure pointed at by nr_client and holds that reference until after newnfs_request(), so that the structure will not be prematurely destroyed.
The second race was between a startup and shutdown of the daemon, since the variable nfsrv_nfsuserd was only
a binary running/not_running value that did not handle the periods of time during startup and shutdown.
--> This patch makes nfsrv_nfsuserd a tri-state variable (an enum), so that it can hold an intermediate state
during startup/shutdown, to prevent a race between a nfsuserd daemon shutdown and the startup of another one.