Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 14 Jan 2011 23:30:35 +0000 (UTC)
From:      Rick Macklem <rmacklem@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r217432 - in head/sys: fs/nfs fs/nfsserver nfs
Message-ID:  <201101142330.p0ENUZh6005706@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: rmacklem
Date: Fri Jan 14 23:30:35 2011
New Revision: 217432
URL: http://svn.freebsd.org/changeset/base/217432

Log:
  Modify the experimental NFSv4 server so that it posts a SIGUSR2
  signal to the master nfsd daemon whenever the stable restart
  file has been modified. This will allow the master nfsd daemon
  to maintain an up to date backup copy of the file. This is
  enabled via the nfssvc() syscall, so that older nfsd daemons
  will not be signaled.
  
  Reviewed by:	jhb
  MFC after:	1 week

Modified:
  head/sys/fs/nfs/nfs_var.h
  head/sys/fs/nfsserver/nfs_nfsdkrpc.c
  head/sys/fs/nfsserver/nfs_nfsdport.c
  head/sys/fs/nfsserver/nfs_nfsdstate.c
  head/sys/nfs/nfs_nfssvc.c
  head/sys/nfs/nfssvc.h

Modified: head/sys/fs/nfs/nfs_var.h
==============================================================================
--- head/sys/fs/nfs/nfs_var.h	Fri Jan 14 22:58:41 2011	(r217431)
+++ head/sys/fs/nfs/nfs_var.h	Fri Jan 14 23:30:35 2011	(r217432)
@@ -573,6 +573,7 @@ int nfsvno_advlock(vnode_t, int, u_int64
 int nfsrv_v4rootexport(void *, struct ucred *, NFSPROC_T *);
 int nfsvno_testexp(struct nfsrv_descript *, struct nfsexstuff *);
 uint32_t nfsrv_hashfh(fhandle_t *);
+void nfsrv_backupstable(void);
 
 /* nfs_commonkrpc.c */
 int newnfs_nmcancelreqs(struct nfsmount *);

Modified: head/sys/fs/nfsserver/nfs_nfsdkrpc.c
==============================================================================
--- head/sys/fs/nfsserver/nfs_nfsdkrpc.c	Fri Jan 14 22:58:41 2011	(r217431)
+++ head/sys/fs/nfsserver/nfs_nfsdkrpc.c	Fri Jan 14 23:30:35 2011	(r217432)
@@ -97,6 +97,7 @@ static int nfs_proc(struct nfsrv_descrip
 
 extern u_long sb_max_adj;
 extern int newnfs_numnfsd;
+extern struct proc *nfsd_master_proc;
 
 /*
  * NFS server system calls
@@ -465,6 +466,7 @@ nfsrvd_init(int terminating)
 	NFSD_LOCK_ASSERT();
 
 	if (terminating) {
+		nfsd_master_proc = NULL;
 		NFSD_UNLOCK();
 		svcpool_destroy(nfsrvd_pool);
 		nfsrvd_pool = NULL;

Modified: head/sys/fs/nfsserver/nfs_nfsdport.c
==============================================================================
--- head/sys/fs/nfsserver/nfs_nfsdport.c	Fri Jan 14 22:58:41 2011	(r217431)
+++ head/sys/fs/nfsserver/nfs_nfsdport.c	Fri Jan 14 23:30:35 2011	(r217432)
@@ -58,6 +58,10 @@ struct mtx nfs_cache_mutex;
 struct mtx nfs_v4root_mutex;
 struct nfsrvfh nfs_rootfh, nfs_pubfh;
 int nfs_pubfhset = 0, nfs_rootfhset = 0;
+struct proc *nfsd_master_proc = NULL;
+static pid_t nfsd_master_pid = (pid_t)-1;
+static char nfsd_master_comm[MAXCOMLEN + 1];
+static struct timeval nfsd_master_start;
 static uint32_t nfsv4_sysid = 0;
 
 static int nfssvc_srvcall(struct thread *, struct nfssvc_args *,
@@ -2905,6 +2909,7 @@ nfssvc_srvcall(struct thread *p, struct 
 	struct nameidata nd;
 	vnode_t vp;
 	int error = EINVAL;
+	struct proc *procp;
 
 	if (uap->flag & NFSSVC_PUBLICFH) {
 		NFSBZERO((caddr_t)&nfs_pubfh.nfsrvfh_data,
@@ -2975,6 +2980,14 @@ nfssvc_srvcall(struct thread *p, struct 
 			    CAST_USER_ADDR_T(dumplocklist.ndllck_list), len);
 			free((caddr_t)dumplocks, M_TEMP);
 		}
+	} else if (uap->flag & NFSSVC_BACKUPSTABLE) {
+		procp = p->td_proc;
+		PROC_LOCK(procp);
+		nfsd_master_pid = procp->p_pid;
+		bcopy(procp->p_comm, nfsd_master_comm, MAXCOMLEN + 1);
+		nfsd_master_start = procp->p_stats->p_start;
+		nfsd_master_proc = procp;
+		PROC_UNLOCK(procp);
 	}
 	return (error);
 }
@@ -3030,6 +3043,32 @@ nfsrv_hashfh(fhandle_t *fhp)
 	return (hashval);
 }
 
+/*
+ * Signal the userland master nfsd to backup the stable restart file.
+ */
+void
+nfsrv_backupstable(void)
+{
+	struct proc *procp;
+
+	if (nfsd_master_proc != NULL) {
+		procp = pfind(nfsd_master_pid);
+		/* Try to make sure it is the correct process. */
+		if (procp == nfsd_master_proc &&
+		    procp->p_stats->p_start.tv_sec ==
+		    nfsd_master_start.tv_sec &&
+		    procp->p_stats->p_start.tv_usec ==
+		    nfsd_master_start.tv_usec &&
+		    strcmp(procp->p_comm, nfsd_master_comm) == 0)
+			psignal(procp, SIGUSR2);
+		else
+			nfsd_master_proc = NULL;
+
+		if (procp != NULL)
+			PROC_UNLOCK(procp);
+	}
+}
+
 extern int (*nfsd_call_nfsd)(struct thread *, struct nfssvc_args *);
 
 /*

Modified: head/sys/fs/nfsserver/nfs_nfsdstate.c
==============================================================================
--- head/sys/fs/nfsserver/nfs_nfsdstate.c	Fri Jan 14 22:58:41 2011	(r217431)
+++ head/sys/fs/nfsserver/nfs_nfsdstate.c	Fri Jan 14 23:30:35 2011	(r217432)
@@ -577,6 +577,7 @@ nfsrv_adminrevoke(struct nfsd_clid *revo
 	 * Now, write out the revocation record
 	 */
 	nfsrv_writestable(clp->lc_id, clp->lc_idlen, NFSNST_REVOKE, p);
+	nfsrv_backupstable();
 
 	/*
 	 * and clear out the state, marking the clientid revoked.
@@ -2988,8 +2989,10 @@ nfsrv_openupdate(vnode_t vp, struct nfss
 	 * If the client just confirmed its first open, write a timestamp
 	 * to the stable storage file.
 	 */
-	if (gotstate)
+	if (gotstate != 0) {
 		nfsrv_writestable(client, len, NFSNST_NEWSTATE, p);
+		nfsrv_backupstable();
+	}
 	return (error);
 }
 
@@ -4132,6 +4135,7 @@ nfsrv_updatestable(NFSPROC_T *p)
 		LIST_REMOVE(sp, nst_list);
 		free((caddr_t)sp, M_TEMP);
 	}
+	nfsrv_backupstable();
 }
 
 /*
@@ -4266,6 +4270,7 @@ nfsrv_clientconflict(struct nfsclient *c
 	 * Ok, we can expire the conflicting client.
 	 */
 	nfsrv_writestable(clp->lc_id, clp->lc_idlen, NFSNST_REVOKE, p);
+	nfsrv_backupstable();
 	nfsrv_cleanclient(clp, p);
 	nfsrv_freedeleglist(&clp->lc_deleg);
 	nfsrv_freedeleglist(&clp->lc_olddeleg);
@@ -4441,6 +4446,7 @@ nfsrv_delegconflict(struct nfsstate *stp
 	 * sleep without the state changing.
 	 */
 	nfsrv_writestable(clp->lc_id, clp->lc_idlen, NFSNST_REVOKE, p);
+	nfsrv_backupstable();
 	if (clp->lc_expiry < NFSD_MONOSEC) {
 		nfsrv_cleanclient(clp, p);
 		nfsrv_freedeleglist(&clp->lc_deleg);

Modified: head/sys/nfs/nfs_nfssvc.c
==============================================================================
--- head/sys/nfs/nfs_nfssvc.c	Fri Jan 14 22:58:41 2011	(r217431)
+++ head/sys/nfs/nfs_nfssvc.c	Fri Jan 14 23:30:35 2011	(r217432)
@@ -99,7 +99,7 @@ nfssvc(struct thread *td, struct nfssvc_
 	else if ((uap->flag & (NFSSVC_NFSDNFSD | NFSSVC_NFSDADDSOCK |
 	    NFSSVC_PUBLICFH | NFSSVC_V4ROOTEXPORT | NFSSVC_NOPUBLICFH |
 	    NFSSVC_STABLERESTART | NFSSVC_ADMINREVOKE |
-	    NFSSVC_DUMPCLIENTS | NFSSVC_DUMPLOCKS)) &&
+	    NFSSVC_DUMPCLIENTS | NFSSVC_DUMPLOCKS | NFSSVC_BACKUPSTABLE)) &&
 	    nfsd_call_nfsd != NULL)
 		error = (*nfsd_call_nfsd)(td, uap);
 	if (error == EINTR || error == ERESTART)

Modified: head/sys/nfs/nfssvc.h
==============================================================================
--- head/sys/nfs/nfssvc.h	Fri Jan 14 22:58:41 2011	(r217431)
+++ head/sys/nfs/nfssvc.h	Fri Jan 14 23:30:35 2011	(r217432)
@@ -63,5 +63,6 @@
 #define	NFSSVC_NFSCBD		0x00100000
 #define	NFSSVC_CBADDSOCK	0x00200000
 #define	NFSSVC_GETSTATS		0x00400000
+#define	NFSSVC_BACKUPSTABLE	0x00800000
 
 #endif /* _NFS_NFSSVC_H */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201101142330.p0ENUZh6005706>