--- sys/conf/majors.orig	2005-06-10 17:28:49.000000000 +0200
+++ sys/conf/majors	2006-07-14 14:10:08.000000000 +0200
@@ -1,4 +1,4 @@
-# $NetBSD: majors,v 1.13.8.1 2005/06/10 15:28:49 tron Exp $
+# $NetBSD: majors
 #
 # Device majors for Machine-Independent drivers.
 #
@@ -20,3 +20,4 @@
 device-major	dk		char 168 block 168
 device-major	tap		char 169		tap
 device-major	veriexec	char 170		veriexec
+device-major	nfslock		char 239		nfslock
--- sys/nfs/Makefile.orig	2002-11-27 00:30:34.000000000 +0100
+++ sys/nfs/Makefile	2006-07-19 16:27:56.000000000 +0200
@@ -1,8 +1,8 @@
-#	$NetBSD: Makefile,v 1.2 2002/11/26 23:30:34 lukem Exp $
+#	$NetBSD: Makefile $
 
 INCSDIR= /usr/include/nfs
 
 INCS=	krpc.h nfs.h nfs_var.h nfsdiskless.h nfsm_subs.h nfsmount.h nfsnode.h \
-	nfsproto.h nfsrtt.h nfsrvcache.h nqnfs.h rpcv2.h xdr_subs.h
+	nfsproto.h nfsrtt.h nfsrvcache.h nfs_lock.h nqnfs.h rpcv2.h xdr_subs.h
 
 .include <bsd.kinc.mk>
--- sys/nfs/nfs_vnops.c.orig	2005-09-27 12:31:29.000000000 +0200
+++ sys/nfs/nfs_vnops.c	2006-07-14 11:54:11.000000000 +0200
@@ -1,4 +1,4 @@
-/*	$NetBSD: nfs_vnops.c,v 1.220.2.1 2005/09/27 10:31:29 tron Exp $	*/
+/*	$NetBSD: nfs_vnops.c	*/
 
 /*
  * Copyright (c) 1989, 1993
@@ -3453,6 +3453,7 @@
 /*
  * NFS advisory byte-level locks.
  */
+#ifndef NFS_LOCKING /* otherwise this is in nfs_lock.c */
 int
 nfs_advlock(v)
 	void *v;
@@ -3468,6 +3469,7 @@
 
 	return lf_advlock(ap, &np->n_lockf, np->n_size);
 }
+#endif /* NFS_LOCKING */
 
 /*
  * Print out the contents of an nfsnode.
--- sys/nfs/files.nfs.orig	2005-02-26 23:39:50.000000000 +0100
+++ sys/nfs/files.nfs	2006-07-22 15:16:58.000000000 +0200
@@ -1,4 +1,4 @@
-#	$NetBSD: files.nfs,v 1.5 2005/02/26 22:39:50 perry Exp $
+#	$NetBSD: files.nfs
 
 deffs	fs_nfs.h		NFS
 
@@ -12,7 +12,7 @@
 				NFS_BOOTSTATIC_MASK NFS_BOOTSTATIC_SERVADDR
 				NFS_BOOTSTATIC_SERVER
 
-defflag opt_nfs.h		NFS_V2_ONLY
+defflag opt_nfs.h		NFS_V2_ONLY NFS_LOCKING
 
 defflag				NFSSERVER
 
@@ -32,3 +32,5 @@
 file	nfs/nfs_syscalls.c	nfsserver | nfs
 file	nfs/nfs_vfsops.c	nfs
 file	nfs/nfs_vnops.c		nfs
+defpseudo	nfslock
+file	nfs/nfs_lock.c		nfs & nfs_locking
--- usr.sbin/rpc.lockd/Makefile.orig	2003-01-05 20:24:07.000000000 +0100
+++ usr.sbin/rpc.lockd/Makefile	2006-07-24 15:14:14.000000000 +0200
@@ -1,14 +1,14 @@
-#	$NetBSD: Makefile,v 1.13 2003/01/05 19:24:07 sommerfeld Exp $
+#	$NetBSD: Makefile $
 
 PROG=		rpc.lockd
-SRCS=		nlm_prot_svc.c lockd.c lock_proc.c lockd_lock.c
+SRCS=		nlm_prot_svc.c lockd.c lock_proc.c lock_common.c lock_server.c lock_client.c
 MAN=		rpc.lockd.8
 MLINKS=		rpc.lockd.8 lockd.8
 
 CPPFLAGS+=	-I. -I${DESTDIR}/usr/include/rpcsvc
 
 DPADD=		${LIBRPCSVC} ${LIBUTIL}
-LDADD=		-lrpcsvc -lutil
+LDADD=		-lrpcsvc -lutil -lpthread
 
 RPC_SVCFLAGS=	-L -m
 RPC_SVCFILES=	nlm_prot_svc.c
--- usr.sbin/rpc.lockd/lockd.h.orig	2000-06-07 16:34:40.000000000 +0200
+++ usr.sbin/rpc.lockd/lockd.h	2006-07-25 14:09:51.000000000 +0200
@@ -1,4 +1,4 @@
-/*	$NetBSD: lockd.h,v 1.2 2000/06/07 14:34:40 bouyer Exp $	*/
+/*	$NetBSD: lockd.h $	*/
 
 /*
  * Copyright (c) 1995
@@ -33,6 +33,12 @@
  *
  */
 
-extern int	debug_level;
-extern int	grace_expired;
-void sigchild_handler __P((int));
+#include <nfs/nfs_lock.h>
+
+extern int debug_level;
+
+extern int poll_common;
+extern int poll_server;
+extern int poll_client;
+
+void sendrep(struct nfslock_rep *rep);
--- usr.sbin/rpc.lockd/lockd.c.orig	2002-11-08 01:16:39.000000000 +0100
+++ usr.sbin/rpc.lockd/lockd.c	2006-07-26 19:58:05.000000000 +0200
@@ -1,4 +1,4 @@
-/*	$NetBSD: lockd.c,v 1.8 2002/11/08 00:16:39 fvdl Exp $	*/
+/*	$NetBSD: lockd.c $	*/
 
 /*
  * Copyright (c) 1995
@@ -50,6 +50,7 @@
 
 #include <err.h>
 #include <stdio.h>
+#include <fcntl.h>
 #include <stdlib.h>
 #include <errno.h>
 #include <syslog.h>
@@ -65,10 +66,13 @@
 #include "lockd.h"
 #include <rpcsvc/nlm_prot.h>
 
-int		debug_level = 0;	/* 0 = no debugging syslog() calls */
-int		_rpcsvcdirty = 0;
+#include "lock_common.h"
+#include "lock_server.h"
+#include "lock_client.h"
 
-int grace_expired;
+int debug_level = 0;	/* 0 = no debugging syslog() calls */
+
+int poll_common = 0, poll_server = 0, poll_client = 0;
 
 int	main __P((int, char **));
 void	nlm_prog_0 __P((struct svc_req *, SVCXPRT *));
@@ -76,11 +80,17 @@
 void	nlm_prog_3 __P((struct svc_req *, SVCXPRT *));
 void	nlm_prog_4 __P((struct svc_req *, SVCXPRT *));
 void	usage __P((void));
+void	sigchild_handler(int);
 
 void sigalarm_handler __P((int));
 
+static void dumpreq(struct nfslock_req *req);
+static void dumprep(struct nfslock_rep *rep);
+
 char *transports[] = { "udp", "tcp", "udp6", "tcp6" };
 
+static int lockdev;
+
 int
 main(argc, argv)
 	int argc;
@@ -89,9 +99,13 @@
 	SVCXPRT *transp;
 	int ch, i, maxindex, s;
 	struct sigaction sigchild, sigalarm;
-	int grace_period = 30;
+	int grace_period = 45;
 	struct netconfig *nconf;
 	int maxrec = RPC_MAXDATASIZE;
+	fd_set readfds, zerofds;
+	int nfds;
+	struct timeval timeout;
+	struct nfslock_req *req;
 
 	while ((ch = getopt(argc, argv, "d:g:")) != (-1)) {
 		switch (ch) {
@@ -188,8 +202,7 @@
 	sigemptyset(&sigchild.sa_mask);
 	sigchild.sa_flags = SA_RESTART;
 	if (sigaction(SIGCHLD, &sigchild, NULL) != 0) {
-		syslog(LOG_WARNING, "sigaction(SIGCHLD) failed: %s",
-		    strerror(errno));
+		syslog(LOG_ERR, "sigaction(SIGCHLD) failed: %m");
 		exit(1);
 	}
 	sigalarm.sa_handler = sigalarm_handler;
@@ -197,30 +210,121 @@
 	sigalarm.sa_flags = SA_RESETHAND; /* should only happen once */
 	sigalarm.sa_flags |= SA_RESTART;
 	if (sigaction(SIGALRM, &sigalarm, NULL) != 0) {
-		syslog(LOG_WARNING, "sigaction(SIGALRM) failed: %s",
-		    strerror(errno));
+		syslog(LOG_ERR, "sigaction(SIGALRM) failed: %m");
 		exit(1);
 	}
-	grace_expired = 0;
-	if (alarm(10) < 0) {
-		syslog(LOG_WARNING, "alarm failed: %s",
-		    strerror(errno));
+	if ((lockdev = open(_PATH_NFS_LOCKDEV, O_RDWR | O_NONBLOCK, 0)) < 0) {
+		syslog(LOG_WARNING, "opening %s failed: %m", _PATH_NFS_LOCKDEV);
+	}
+
+	common_init();
+	server_init();
+	client_init();
+
+	if (alarm(grace_period) < 0) {
+		syslog(LOG_ERR, "alarm failed: %m");
 		exit(1);
 	}
 
-	svc_run();		/* Should never return */
-	exit(1);
+	timeout.tv_sec = 1;
+	timeout.tv_usec = 0;
+	FD_ZERO(&zerofds);
+
+	for (;;) {
+		FD_COPY(&svc_fdset, &readfds);
+		if (lockdev > 0) FD_SET(lockdev, &readfds);
+		nfds = svc_maxfd > lockdev ? svc_maxfd + 1 : lockdev + 1;
+#if 0
+		switch (select(nfds, &readfds, NULL, NULL, &timeout)) {
+#else
+		switch (select(nfds, &readfds, NULL, NULL, NULL)) {
+#endif
+		case -1:
+			if (errno != EINTR) {
+				syslog(LOG_ERR, "select failed: %m");
+				exit(1);
+			}
+			break;
+		case 0:
+			if (poll_common) common_poll();
+			if (poll_server) server_poll();
+			if (poll_client) client_poll();
+			break;
+		default:
+			if (lockdev > 0 && FD_ISSET(lockdev, &readfds)) {
+				if ((req = newreq()) == NULL) {
+					syslog(LOG_WARNING, "newreq() failed");
+				} else if (read(lockdev, req, sizeof(*req)) != sizeof(*req)) {
+					syslog(LOG_WARNING, "read(req) failed: %m");
+				} else if (req->magic != NFSLOCK_MAGIC) {
+					syslog(LOG_WARNING, "wrong magic (%d should be %d)", req->magic, NFSLOCK_MAGIC);
+				} else {
+#if 0
+					syslog(LOG_DEBUG, "handling request #%d", req->serial);
+#else
+					dumpreq(req);
+#endif
+					handlereq();
+				}
+				FD_CLR(lockdev, &readfds);
+			}
+			if (memcmp(&readfds, &zerofds, sizeof(fd_set))) {
+				syslog(LOG_DEBUG, "calling svc_getreqset");
+				svc_getreqset(&readfds);
+			}
+		}
+	}
+}
+
+void sendrep(struct nfslock_rep *rep) {
+	if (lockdev < 0) {
+		syslog(LOG_ERR, "sendrep: no device");
+		exit(1);
+	}
+	rep->magic = NFSLOCK_MAGIC + 1;
+#if 0
+	syslog(LOG_DEBUG, "sending reply #%d", rep->serial);
+#else
+	dumprep(rep);
+#endif
+	if (write(lockdev, rep, sizeof(*rep)) != sizeof (*rep)) {
+		syslog(LOG_WARNING, "write(rep) failed: %m");
+	}
+
 }
 
 void
 sigalarm_handler(s)
 	int s;
 {
-	grace_expired = 1;
+	graceover();
 }
 
+void sigchild_handler(int s)
+{
+	server_sigchild(s);
+	client_sigchild(s);
+	common_sigchild(s);
+}
+
+
 void
 usage()
 {
 	errx(1, "usage: rpc.lockd [-d <debuglevel>] [-g <grace period>]");
 }
+
+void dumpreq(struct nfslock_req *req)
+{
+	static char opname[5][7]={"null", "test", "lock", "cancel", "unlock"};
+
+	syslog(LOG_DEBUG, "req #%d: %s %s %s %s %ld+%ld:%d (%d) V%d %s %d*%d (%d)", req->serial, (req->op >= 0 && req->op <= sizeof(opname)) ? opname[req->op] : "?", req->exclusive ? "exclusive" : "shared", req->posix ? "posix" : "flock", req->wait ? "wait" : "nowait", (long)req->offset, (long)req->len, (int)req->owner, req->handle_len, req->mount_version, req->mount_soft ? "soft" : "hard", req->mount_timeo, req->mount_retry, req->mount_nam.ss_len);
+}
+
+void dumprep(struct nfslock_rep *rep)
+{
+	if (rep->conflict)
+		syslog(LOG_DEBUG, "rep #%d: %s %s %ld+%ld:%d", rep->serial, rep->errnum ? strerror(rep->errnum) : "OK", rep->conflict > 1 ? "ex" : "sh", (long)rep->offset, (long)rep->len, (int)rep->owner);
+	else
+		syslog(LOG_DEBUG, "rep #%d: %s", rep->serial, rep->errnum ? strerror(rep->errnum) : "OK");
+}
--- usr.sbin/rpc.lockd/lock_proc.c.orig	2000-10-11 22:23:56.000000000 +0200
+++ usr.sbin/rpc.lockd/lock_proc.c	2006-07-26 16:59:56.000000000 +0200
@@ -1,4 +1,4 @@
-/*	$NetBSD: lock_proc.c,v 1.7 2000/10/11 20:23:56 is Exp $	*/
+/*	$NetBSD: lock_proc.c $	*/
 
 /*
  * Copyright (c) 1995
@@ -55,7 +55,10 @@
 
 #include "lockd.h"
 #include <rpcsvc/nlm_prot.h>
-#include "lockd_lock.h"
+#include "lock_proc.h"
+#include "lock_common.h"
+#include "lock_client.h"
+#include "lock_server.h"
 
 
 #define	CLIENT_CACHE_SIZE	64	/* No. of client sockets cached */
@@ -525,11 +528,6 @@
 
 	/* copy cookie from arg to result.  See comment in nlm_test_1() */
 	res.cookie = arg->cookie;
-
-	/*
-	 * Since at present we never return 'nlm_blocked', there can never be
-	 * a lock to cancel, so this call always fails.
-	 */
 	res.stat.stat = unlock(&arg4, LOCK_CANCEL);
 	return (&res);
 }
@@ -548,10 +546,6 @@
 		log_from_addr("nlm_cancel_msg", rqstp);
 
 	res.cookie = arg->cookie;
-	/*
-	 * Since at present we never return 'nlm_blocked', there can never be
-	 * a lock to cancel, so this call always fails.
-	 */
 	res.stat.stat = unlock(&arg4, LOCK_CANCEL);
 	transmit_result(NLM_CANCEL_RES, &res,
 	    (struct sockaddr *)svc_getcaller(rqstp->rq_xprt));
@@ -630,14 +624,17 @@
 	struct svc_req *rqstp;
 {
 	static nlm_res res;
+	struct nlm4_lock lock4;
 
+	nlmtonlm4(&arg->alock, &lock4);
+	
 	if (debug_level)
 		log_from_addr("nlm_granted", rqstp);
 
+	res.stat.stat = granted(svc_getrpccaller(rqstp->rq_xprt), arg->exclusive, &lock4);
+
 	/* copy cookie from arg to result.  See comment in nlm_test_1() */
 	res.cookie = arg->cookie;
-
-	res.stat.stat = nlm_granted;
 	return (&res);
 }
 
@@ -647,12 +644,16 @@
 	struct svc_req *rqstp;
 {
 	static nlm_res res;
+	struct nlm4_lock lock4;
+
+	nlmtonlm4(&arg->alock, &lock4);
 
 	if (debug_level)
 		log_from_addr("nlm_granted_msg", rqstp);
 
+	res.stat.stat = granted(svc_getrpccaller(rqstp->rq_xprt), arg->exclusive, &lock4);
+
 	res.cookie = arg->cookie;
-	res.stat.stat = nlm_granted;
 	transmit_result(NLM_GRANTED_RES, &res,
 	    (struct sockaddr *)svc_getcaller(rqstp->rq_xprt));
 	return (NULL);
@@ -668,8 +669,18 @@
 	nlm_testres *arg;
 	struct svc_req *rqstp;
 {
+	struct nlm4_testrply arg4;
+
+	arg4.stat = arg->stat.stat;
+	arg4.nlm4_testrply_u.holder.exclusive = arg->stat.nlm_testrply_u.holder.exclusive;
+	arg4.nlm4_testrply_u.holder.svid = arg->stat.nlm_testrply_u.holder.svid;
+	arg4.nlm4_testrply_u.holder.oh = arg->stat.nlm_testrply_u.holder.oh;
+	arg4.nlm4_testrply_u.holder.l_offset = arg->stat.nlm_testrply_u.holder.l_offset;
+	arg4.nlm4_testrply_u.holder.l_len = arg->stat.nlm_testrply_u.holder.l_len;
+
 	if (debug_level)
 		log_from_addr("nlm_test_res", rqstp);
+	testres(arg->cookie, &arg4);
 	return (NULL);
 }
 
@@ -685,7 +696,7 @@
 {
 	if (debug_level)
 		log_from_addr("nlm_lock_res", rqstp);
-
+	lockres(arg->cookie, (nlm4_stats)(arg->stat.stat));
 	return (NULL);
 }
 
@@ -701,6 +712,7 @@
 {
 	if (debug_level)
 		log_from_addr("nlm_cancel_res", rqstp);
+	cancelres(arg->cookie, (nlm4_stats)(arg->stat.stat));
 	return (NULL);
 }
 
@@ -716,6 +728,7 @@
 {
 	if (debug_level)
 		log_from_addr("nlm_unlock_res", rqstp);
+	unlockres(arg->cookie, (nlm4_stats)(arg->stat.stat));
 	return (NULL);
 }
 
@@ -1079,8 +1092,7 @@
 
 	/* copy cookie from arg to result.  See comment in nlm_test_1() */
 	res.cookie = arg->cookie;
-
-	res.stat.stat = nlm4_granted;
+	res.stat.stat = (nlm4_stats)granted(svc_getrpccaller(rqstp->rq_xprt), arg->exclusive, &arg->alock);
 	return (&res);
 }
 
@@ -1095,7 +1107,7 @@
 		log_from_addr("nlm4_granted_msg", rqstp);
 
 	res.cookie = arg->cookie;
-	res.stat.stat = nlm4_granted;
+	res.stat.stat = (nlm4_stats)granted(svc_getrpccaller(rqstp->rq_xprt), arg->exclusive, &arg->alock);
 	transmit4_result(NLM4_GRANTED_RES, &res,
 	    (struct sockaddr *)svc_getrpccaller(rqstp->rq_xprt)->buf);
 	return (NULL);
@@ -1113,6 +1125,8 @@
 {
 	if (debug_level)
 		log_from_addr("nlm4_test_res", rqstp);
+
+	testres(arg->cookie, &arg->stat);
 	return (NULL);
 }
 
@@ -1128,7 +1142,7 @@
 {
 	if (debug_level)
 		log_from_addr("nlm4_lock_res", rqstp);
-
+	lockres(arg->cookie, arg->stat.stat);
 	return (NULL);
 }
 
@@ -1144,6 +1158,7 @@
 {
 	if (debug_level)
 		log_from_addr("nlm4_cancel_res", rqstp);
+	cancelres(arg->cookie, arg->stat.stat);
 	return (NULL);
 }
 
@@ -1159,6 +1174,7 @@
 {
 	if (debug_level)
 		log_from_addr("nlm4_unlock_res", rqstp);
+	unlockres(arg->cookie, arg->stat.stat);
 	return (NULL);
 }
 
@@ -1289,6 +1305,8 @@
 	struct svc_req *rqstp;
 {
 	static char dummy;
-	notify(arg->mon_name, arg->state);
+	common_notify(arg->mon_name, arg->state);
+	server_notify(arg->mon_name, arg->state);
+	client_notify(arg->mon_name, arg->state);
 	return (&dummy);
 }
--- usr.sbin/rpc.lockd/lockd_lock.h.orig	2000-06-09 16:00:54.000000000 +0200
+++ usr.sbin/rpc.lockd/lock_server.h	2006-07-25 14:07:47.000000000 +0200
@@ -1,20 +1,20 @@
-/*	$NetBSD: lockd_lock.h,v 1.2 2000/06/09 14:00:54 fvdl Exp $	*/
+/*	$NetBSD: lock_server.h $	*/
 
 /* Headers and function declarations for file-locking utilities */
 
-struct nlm4_holder * testlock __P((struct nlm4_lock *, int));
-
+struct nlm4_holder *testlock __P((struct nlm4_lock *, int));
 enum nlm_stats getlock __P((nlm4_lockargs *, struct svc_req *, int));
 enum nlm_stats unlock __P((nlm4_lock *, int));
-void notify __P((char *, int));
+
+void server_init(void);
+void server_poll(void);
+void server_notify(char *, int);
+void server_sigchild(int);
+
+void graceover(void);
 
 /* flags for testlock, getlock & unlock */
 #define LOCK_ASYNC	0x01 /* async version (getlock only) */
 #define LOCK_V4 	0x02 /* v4 version */
 #define LOCK_MON 	0x04 /* monitored lock (getlock only) */
 #define LOCK_CANCEL 0x08 /* cancel, not unlock request (unlock only) */
-
-/* callbacks from lock_proc.c */
-void	transmit_result __P((int, nlm_res *, struct sockaddr *));
-void	transmit4_result __P((int, nlm4_res *, struct sockaddr *));
-CLIENT  *get_client __P((struct sockaddr *, rpcvers_t));
--- usr.sbin/rpc.lockd/lockd_lock.c.orig	2005-06-15 07:52:28.000000000 +0200
+++ usr.sbin/rpc.lockd/lock_server.c	2006-07-25 14:07:14.000000000 +0200
@@ -1,4 +1,4 @@
-/*	$NetBSD: lockd_lock.c,v 1.20.6.1 2005/06/15 05:52:28 snj Exp $	*/
+/*	$NetBSD: lock_server.c $	*/
 
 /*
  * Copyright (c) 2000 Manuel Bouyer.
@@ -46,7 +46,9 @@
 #include <sys/wait.h>
 #include <rpcsvc/sm_inter.h>
 #include <rpcsvc/nlm_prot.h>
-#include "lockd_lock.h"
+#include "lock_proc.h"
+#include "lock_common.h"
+#include "lock_server.h"
 #include "lockd.h"
 
 /* A set of utilities for managing file locking */
@@ -78,21 +80,6 @@
 enum nlm_stats do_lock __P((struct file_lock *, int));
 enum nlm_stats do_unlock __P((struct file_lock *));
 void send_granted __P((struct file_lock *, int));
-void siglock __P((void));
-void sigunlock __P((void));
-
-/* list of hosts we monitor */
-LIST_HEAD(hostlst_head, host);
-struct hostlst_head hostlst_head = LIST_HEAD_INITIALIZER(hostlst_head);
-
-/* struct describing a lock */
-struct host {
-	LIST_ENTRY(host) hostlst;
-	char name[SM_MAXSTRLEN+1];
-	int refcnt;
-};
-
-void do_mon __P((char *));
 
 #define	LL_FH	0x01
 #define	LL_NAME	0x02
@@ -100,6 +87,8 @@
 
 static struct file_lock *lock_lookup __P((struct file_lock *, int));
 
+int grace_expired = 0;
+
 /*
  * lock_lookup: lookup a matching lock.
  * called with siglock held.
@@ -386,7 +375,7 @@
 }
 
 void
-sigchild_handler(sig)
+server_sigchild(sig)
 	int sig;
 {
 	int status;
@@ -695,89 +684,12 @@
 }
 
 void
-siglock()
-{
-	sigset_t block;
-	
-	sigemptyset(&block);
-	sigaddset(&block, SIGCHLD);
-
-	if (sigprocmask(SIG_BLOCK, &block, NULL) < 0) {
-		syslog(LOG_WARNING, "siglock failed: %s", strerror(errno));
-	}
-}
-
-void
-sigunlock()
-{
-	sigset_t block;
-	
-	sigemptyset(&block);
-	sigaddset(&block, SIGCHLD);
-
-	if (sigprocmask(SIG_UNBLOCK, &block, NULL) < 0) {
-		syslog(LOG_WARNING, "sigunlock failed: %s", strerror(errno));
-	}
-}
-
-/* monitor a host through rpc.statd, and keep a ref count */
-void
-do_mon(hostname)
-	char *hostname;
-{
-	struct host *hp;
-	struct mon my_mon;
-	struct sm_stat_res res;
-	int retval;
-
-	LIST_FOREACH(hp, &hostlst_head, hostlst) {
-		if (strcmp(hostname, hp->name) == 0) {
-			/* already monitored, just bump refcnt */
-			hp->refcnt++;
-			return;
-		}
-	}
-	/* not found, have to create an entry for it */
-	hp = malloc(sizeof(struct host));
- 	if (hp == NULL) {
- 		syslog(LOG_WARNING, "can't monitor host %s: malloc failed\n",
- 		    hostname);
- 		return;
-	}
-	strlcpy(hp->name, hostname, sizeof(hp->name));
-	hp->refcnt = 1;
-	syslog(LOG_DEBUG, "monitoring host %s",
-	    hostname);
-	memset(&my_mon, 0, sizeof(my_mon));
-	my_mon.mon_id.mon_name = hp->name;
-	my_mon.mon_id.my_id.my_name = "localhost";
-	my_mon.mon_id.my_id.my_prog = NLM_PROG;
-	my_mon.mon_id.my_id.my_vers = NLM_SM;
-	my_mon.mon_id.my_id.my_proc = NLM_SM_NOTIFY;
-	if ((retval =
-	    callrpc("localhost", SM_PROG, SM_VERS, SM_MON, xdr_mon,
-	    (char*)&my_mon, xdr_sm_stat_res, (char*)&res)) != 0) {
-		syslog(LOG_WARNING, "rpc to statd failed: %s",
-		    clnt_sperrno((enum clnt_stat)retval));
-		free(hp);
-		return;
-	}
-	if (res.res_stat == stat_fail) {
-		syslog(LOG_WARNING, "statd failed");
-		free(hp);
-		return;
-	}
-	LIST_INSERT_HEAD(&hostlst_head, hp, hostlst);
-}
-
-void
-notify(hostname, state)
+server_notify(hostname, state)
 	char *hostname;
 	int state;
 {
 	struct file_lock *fl, *next_fl;
 	int err;
-	syslog(LOG_DEBUG, "notify from %s, new state %d", hostname, state);
 	/* search all lock for this host; if status changed, release the lock */
 	siglock();
 	for (fl = LIST_FIRST(&lcklst_head); fl != NULL; fl = next_fl) {
@@ -811,3 +723,16 @@
 	}
 	sigunlock();
 }
+
+void graceover(void)
+{
+	grace_expired = 1;
+}
+
+void server_init(void)
+{
+}
+
+void server_poll(void)
+{
+}
--- usr.sbin/rpc.lockd/rpc.lockd.8.orig	2002-02-02 02:42:45.000000000 +0100
+++ usr.sbin/rpc.lockd/rpc.lockd.8	2006-07-20 17:47:06.000000000 +0200
@@ -101,13 +101,13 @@
 .Nm
 appeared in
 .Tn SunOS 4 .
+Server-side locking appeared in
+.Nx X.xx,
+client-side locking in
+.Nx Y.yy.
+.Sh AUTHORS
+A. R. Gordon (initial implementation),
+Manuel Bouyer (server routines),
+Edgar Fu (client routines).
 .Sh BUGS
-The current implementation provides only the server side of the protocol
-(i.e. clients running other OS types can establish locks on a
-.Nx
-fileserver,
-but there is currently no means for a
-.Nx
-client to establish locks).
-.Pp
 The current implementation serialises locks requests that could be shared.
