Because NFS is a stateless service, it cannot provide inherently
The NLM is a service that provides advisory X/Open CAE file and record locking, and DOS compatible file sharing and locking in an XNFS environment. Its use is strongly encouraged but not mandatory. XNFS clients must be prepared to interoperate with servers which do not support this service. It is also recommended, but not required, that locks created by DOS processes are honoured by processes running on an X/Open host and vice versa.
The NLM provides two types of locks, monitored and non-monitored.
Monitored locks are reliable. A client process which establishes monitored locks can be assured that if the server host, on which the locks are established, crashes and recovers, the locks will be reinstated without any action on the client process' part. Likewise, locks that are held by a client process will be discarded by the NLM on the server host if the client host crashes before the locks are released.
Monitored locks require both the client and server hosts to implement the NSM protocol.
Monitored locks are preferred over the non-monitored locks.
Non-monitored locks provide the same functionality as monitored locks except if the server host, on which the locks are established, crashes and recovers, the locks will not be re-established. The personal computer client is responsible for detecting a server host failure and re-establishing the locks. Additionally, the personal computer client must inform the server NLM when it has been rebooted so it can discard all locks and file shares held for the client.
The NSM is a service that provides applications with information on the status of network hosts. It is included in this document as it is heavily used by the NLM to track hosts that have established locks and the hosts that are holding those locks. Although the NSM is a general service, this document will only describe the NSM as it is used by the NLM.
Each NSM keeps track of its own "state" and notifies
any interested party of a change in this state.
The state is merely a number which increases monotonically each time
The NSM does not
actively "probe" hosts it has been asked to monitor; instead it waits
When it receives an SM_MON request an NSM adds the information in the SM_MON parameter to a notify list. If the host has a status change (crashes and recovers), the NSM will notify each host on the notify list via the SM_NOTIFY call. If the NSM receives notification of a status change from another host it will search the notify list for that host and call the RPC supplied in the SM_MON call.
For obvious reasons, the NSM maintains copies of its current state and of the notify list on stable storage.
For correct operation of the NLM, the client and server hosts are required to monitor each other. When a lock request is issued by a process running on the client host, the NLM on the client host requests the NSM on the client host to monitor the server host. The client NLM then transmits the lock request to the NLM on the server. On reception of the lock request the NLM on the server host will request the NSM on the server host to monitor the client host. In this way each host is monitored by the NSM on the other host.
It is assumed that the user process requests locks and file shares via
a user-level API or system call such as the XSI
This section will describe the interaction between the NLM and the
NSM for the synchronous procedures.
NLM_LOCK requests may be blocking or non-blocking. When the server NLM receives the NLM_LOCK request, it must make a call to the SM_MON procedure on its local NSM to monitor the calling host. The SM_MON call includes the name of the host to be monitored and an RPC to be called if the NSM is notified of a state change for the monitored host. The RPC information includes a transport end-point, program number, program version, procedure number and an opaque argument. The RPC information is of significance only to an NLM implementation, and is not defined by this specification.
If the lock can be granted immediately, or the call was non-blocking, the RPC returns immediately with the appropriate status (granted or denied).
If the lock cannot be granted immediately (it conflicts with an existing lock) and the call was a blocking call, the RPC will return with a blocked status, thus allowing the client NLM to continue processing. At this point the client NLM can choose to cancel the outstanding lock request by calling the NLM_CANCEL procedure. Upon reception of an NLM_CANCEL request, the server NLM will then delete the outstanding lock request and may request its local NSM to stop monitoring the calling host by calling the SM_UNMON procedure.
When the blocked lock request can be processed, the server NLM makes an NLM_GRANTED call-back to the client NLM indicating success or failure.
Once the lock has been granted, the client NLM instructs the local NSM to monitor the server via the SM_MON RPC, as described above; once again, the RPC used for notification is not defined by this specification. At this point the NSMs on both the client and server hosts are monitoring each other.
The grace period is an implementation-dependent time during which the
NLM implementation will only accept requests to
If the client host crashes, upon reboot, the NSM will go through the same process notifying the NSMs on hosts in the notify list via the SM_NOTIFY procedure call that there was a change in state. The server NSM will receive this notification call and in turn notify the server NLM, via the provided RPC, that the client host had crashed. The server NLM can then dispose of all locks and shares held by the crashed host.
A client host establishes a non-monitored lock by calling the NLM_NM_LOCK procedure on the server NLM. The server NLM will process the lock and return status to the client host indicating whether the lock was granted or denied. The NLM_NM_LOCK procedure call cannot block and so cannot result in a call-back.
NLM and NSM implementations are required to support both UDP and TCP transports. Personal computer NFS clients will always use UDP when issuing locking and sharing requests to an NLM. Most implementations of the NSM use TCP when interacting with the local NLM and any remote NSMs, but both NLM and NSM must accept any request over either transport.
The server NSM is started. (Note that NSM and NLM initialisation proceed in parallel.) The server NSM retrieves a copy of the last server state from stable storage, increments it to the next odd value, and saves it on stable storage. It then processes the notify list on stable storage, which is initially empty.
The server NLM is started. It issues an SM_UNMON_ALL to the server NSM, from which it obtains a copy of the server state. It then enters grace period recovery state, waits for the grace period, and then enters normal service state.
The client NSM is started. (Note that NSM and NLM initialisation proceed in parallel.) The client NSM retrieves a copy of the last client state from stable storage, increments it to the next odd value, and saves it on stable storage. It then processes the notify list, which is initially empty.
The client NLM is started. It issues an SM_UNMON_ALL to the client NSM, from which it obtains a copy of the client state. It then enters grace period recovery state, waits for the grace period, and then enters normal service state.
A process on the client system requests a byte range lock on a file stored on the server. The client NFS passes this request, including the file handle, to the local NLM using a private protocol.
The client NLM issues an NLM_LOCK RPC to the server NLM. This request includes a copy of the client state.
The server NLM determines that the lock can be granted. It verifies that this is the first lock held for the client, and issues an SM_MON call to the server NSM instructing it to monitor the client.
The server NSM saves the client name and RPC information in the notify list, committing the client name to stable storage, and reports success to the server NLM.
The server NLM records the fact that it is holding a lock for the named client which is in client state. It then sends a success response to the client NLM.
The client NLM verifies that this is the first lock which it is holding on the server system, and issues an SM_MON call to the client NSM instructing it to monitor the server.
The client NSM saves the server name and RPC information in the notify list, committing the server name to stable storage, and reports success to the client NLM.
The client NLM records the fact that the server NLM is holding a lock for it, and returns to the local application.
The server system fails and is restarted.
The server NSM is restarted. (Note that NSM and NLM initialisation proceed in parallel.) The server NSM retrieves a copy of the last server state from stable storage, increments it to the next odd value, and saves it on stable storage. It then processes the notify list on stable storage, adding each name to a recovery list.
For each name in the recovery list, the server NSM issues an SM_NOTIFY RPC to the NSM on the named host. In this example it will issue an SM_NOTIFY to the client NSM, including the server name and the new server state.
The client NSM receives the SM_NOTIFY RPC and compares the hostname against each entry in the notify list. When it encounters a match, it calls back the client NLM using the RPC information provided with the original SM_MON RPC.
The callback procedure in the client NLM notes that the server state has changed and schedules lock recovery (see below). It then acknowledges the RPC callback from the client NSM.
After comparing the name against all entries in the notify list, the client NSM acknowledges the SM_NOTIFY RPC from the server NSM.
After processing all entries in the recovery list, the server NSM enters normal service state with an empty notify list.
The server NLM is started.
It issues an SM_UNMON_ALL to the server
The client NLM now attempts to recover all locks which it was holding
on the server.
For each lock, it issues an NLM_LOCK request with
reclaim set to true.
This NLM_LOCK is processed as described
At the conclusion of the grace period, the server NLM enters normal service mode.
Eventually the client application releases the lock on the file. The client NLM issues an NLM_UNLOCK RPC to the server NLM.
The server NLM releases the lock, and notices that this is the last lock which was being held on behalf of the client. It issues an SM_UNMON RPC to the server NSM.
The server NSM removes the client from the notify list, and returns to the server NLM, which completes the NLM_UNLOCK request.
The client NLM deletes the lock record, and notices that this is the last lock which it was holding on the server. It issues an SM_UNMON RPC to the client NSM.
The client NSM removes the server from the notify list, and returns to the client NLM, which completes the application's unlock request.
The server and client NSM and NLM are initialised as described in the previous example.
The client lock request is processed as described in the previous example.
The client system fails and is restarted.
The client NSM is restarted. (Note that NSM and NLM initialisation proceed in parallel.) The client NSM retrieves a copy of the last client state from stable storage, increments it to the next odd value, and saves it on stable storage. It then processes the notify list on stable storage, adding each name to a recovery list.
For each name in the recovery list, the client NSM issues an SM_NOTIFY RPC to the NSM on the named host. In this example it will issue an SM_NOTIFY to the server NSM, including the client name and the new client state.
The server NSM receives the SM_NOTIFY RPC and compares the hostname against each entry in the notify list. When it encounters a match, it calls back the server NLM using the RPC information provided with the original SM_MON RPC.
The callback procedure in the server NLM notes that the client state has changed and releases all locks held on behalf of the client. It then acknowledges the RPC callback from the server NSM.
After comparing the name against all entries in the notify list, the server NSM acknowledges the SM_NOTIFY RPC from the client NSM.
After processing all entries in the recovery list, the client NSM enters normal service state with an empty notify list.
The client NLM is now restarted as normal.
Contents | Next section | Index |