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
This commit is contained in:
Rick Macklem 2011-01-14 23:30:35 +00:00
parent 45b3c17647
commit 5f73287a6e
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=217432
6 changed files with 51 additions and 2 deletions

View File

@ -573,6 +573,7 @@ int nfsvno_advlock(vnode_t, int, u_int64_t, u_int64_t, NFSPROC_T *);
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 *);

View File

@ -97,6 +97,7 @@ static int nfs_proc(struct nfsrv_descript *, u_int32_t, struct socket *,
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;

View File

@ -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 nfssvc_args *uap, struct ucred *cred)
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 nfssvc_args *uap, struct ucred *cred)
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 *);
/*

View File

@ -577,6 +577,7 @@ nfsrv_adminrevoke(struct nfsd_clid *revokep, NFSPROC_T *p)
* 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 nfsstate *new_stp, nfsquad_t clientid,
* 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 *clp, int *haslockp, vnode_t vp,
* 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, int *haslockp, NFSPROC_T *p,
* 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);

View File

@ -99,7 +99,7 @@ nfssvc(struct thread *td, struct nfssvc_args *uap)
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)

View File

@ -63,5 +63,6 @@
#define NFSSVC_NFSCBD 0x00100000
#define NFSSVC_CBADDSOCK 0x00200000
#define NFSSVC_GETSTATS 0x00400000
#define NFSSVC_BACKUPSTABLE 0x00800000
#endif /* _NFS_NFSSVC_H */