Author: rmacklem
Date: Mon Jul  9 19:58:01 2018
New Revision: 336141
URL: https://svnweb.freebsd.org/changeset/base/336141

Log:
  Add support for a "forced" pnfsdskill to the pNFS server kernel code.
  
  The pnfsdskill(8) command will normally fail if there is no valid mirror
  for the DS to be disabled. However, a system administrator may need to
  disable a DS which does not have a valid mirror so that the nfsd threads
  can be terminated. This patch adds the kernel code needed by pnfsdskill(8)
  to implement this "forced" case of disabling a DS.
  This patch only affects the pNFS server.

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

Modified: head/sys/fs/nfs/nfs.h
==============================================================================
--- head/sys/fs/nfs/nfs.h       Mon Jul  9 19:03:30 2018        (r336140)
+++ head/sys/fs/nfs/nfs.h       Mon Jul  9 19:58:01 2018        (r336141)
@@ -207,6 +207,7 @@ struct nfsd_pnfsd_args {
 
 #define        PNFSDOP_DELDSSERVER     1
 #define        PNFSDOP_COPYMR          2
+#define        PNFSDOP_FORCEDELDS      3
 
 /* Old version. */
 struct nfsd_nfsd_oargs {

Modified: head/sys/fs/nfs/nfs_var.h
==============================================================================
--- head/sys/fs/nfs/nfs_var.h   Mon Jul  9 19:03:30 2018        (r336140)
+++ head/sys/fs/nfs/nfs_var.h   Mon Jul  9 19:58:01 2018        (r336141)
@@ -159,8 +159,8 @@ int nfsrv_getdevinfo(char *, int, uint32_t *, uint32_t
 void nfsrv_freeonedevid(struct nfsdevice *);
 void nfsrv_freealllayoutsanddevids(void);
 void nfsrv_freefilelayouts(fhandle_t *);
-int nfsrv_deldsserver(char *, NFSPROC_T *);
-struct nfsdevice *nfsrv_deldsnmp(struct nfsmount *, NFSPROC_T *);
+int nfsrv_deldsserver(int, char *, NFSPROC_T *);
+struct nfsdevice *nfsrv_deldsnmp(int, struct nfsmount *, NFSPROC_T *);
 int nfsrv_createdevids(struct nfsd_nfsd_args *, NFSPROC_T *);
 int nfsrv_checkdsattr(struct nfsrv_descript *, vnode_t, NFSPROC_T *);
 int nfsrv_copymr(vnode_t, vnode_t, vnode_t, struct nfsdevice *,

Modified: head/sys/fs/nfsserver/nfs_nfsdport.c
==============================================================================
--- head/sys/fs/nfsserver/nfs_nfsdport.c        Mon Jul  9 19:03:30 2018        
(r336140)
+++ head/sys/fs/nfsserver/nfs_nfsdport.c        Mon Jul  9 19:58:01 2018        
(r336141)
@@ -3433,12 +3433,13 @@ nfssvc_nfsd(struct thread *td, struct nfssvc_args *uap
                free(nfsdarg.mdspath, M_TEMP);
        } else if (uap->flag & NFSSVC_PNFSDS) {
                error = copyin(uap->argp, &pnfsdarg, sizeof(pnfsdarg));
-               if (error == 0 && pnfsdarg.op == PNFSDOP_DELDSSERVER) {
+               if (error == 0 && (pnfsdarg.op == PNFSDOP_DELDSSERVER ||
+                   pnfsdarg.op == PNFSDOP_FORCEDELDS)) {
                        cp = malloc(PATH_MAX + 1, M_TEMP, M_WAITOK);
                        error = copyinstr(pnfsdarg.dspath, cp, PATH_MAX + 1,
                            NULL);
                        if (error == 0)
-                               error = nfsrv_deldsserver(cp, td);
+                               error = nfsrv_deldsserver(pnfsdarg.op, cp, td);
                        free(cp, M_TEMP);
                } else if (error == 0 && pnfsdarg.op == PNFSDOP_COPYMR) {
                        cp = malloc(PATH_MAX + 1, M_TEMP, M_WAITOK);
@@ -4014,7 +4015,7 @@ nfsrv_pnfscreate(struct vnode *vp, struct vattr *vap, 
                     NFSMNTP_CANCELRPCS)) == 0) {
                        nmp->nm_privflag |= NFSMNTP_CANCELRPCS;
                        NFSUNLOCKMNT(nmp);
-                       ds = nfsrv_deldsnmp(nmp, p);
+                       ds = nfsrv_deldsnmp(PNFSDOP_DELDSSERVER, nmp, p);
                        NFSD_DEBUG(4, "dscreatfail fail=%d ds=%p\n", failpos,
                            ds);
                        if (ds != NULL)
@@ -4248,7 +4249,7 @@ nfsrv_pnfsremove(struct vnode **dvp, int mirrorcnt, ch
                     NFSMNTP_CANCELRPCS)) == 0) {
                        nmp->nm_privflag |= NFSMNTP_CANCELRPCS;
                        NFSUNLOCKMNT(nmp);
-                       ds = nfsrv_deldsnmp(nmp, p);
+                       ds = nfsrv_deldsnmp(PNFSDOP_DELDSSERVER, nmp, p);
                        NFSD_DEBUG(4, "dsremovefail fail=%d ds=%p\n", failpos,
                            ds);
                        if (ds != NULL)
@@ -4463,7 +4464,8 @@ tryagain:
                             NFSMNTP_CANCELRPCS)) == 0) {
                                failnmp->nm_privflag |= NFSMNTP_CANCELRPCS;
                                NFSUNLOCKMNT(failnmp);
-                               ds = nfsrv_deldsnmp(failnmp, p);
+                               ds = nfsrv_deldsnmp(PNFSDOP_DELDSSERVER,
+                                   failnmp, p);
                                NFSD_DEBUG(4, "dsldsnmp fail=%d ds=%p\n",
                                    failpos, ds);
                                if (ds != NULL)

Modified: head/sys/fs/nfsserver/nfs_nfsdstate.c
==============================================================================
--- head/sys/fs/nfsserver/nfs_nfsdstate.c       Mon Jul  9 19:03:30 2018        
(r336140)
+++ head/sys/fs/nfsserver/nfs_nfsdstate.c       Mon Jul  9 19:58:01 2018        
(r336141)
@@ -7482,7 +7482,7 @@ out:
  * Look up the mount path for the DS server and delete it.
  */
 int
-nfsrv_deldsserver(char *dspathp, NFSPROC_T *p)
+nfsrv_deldsserver(int op, char *dspathp, NFSPROC_T *p)
 {
        struct mount *mp;
        struct nfsmount *nmp;
@@ -7524,7 +7524,7 @@ nfsrv_deldsserver(char *dspathp, NFSPROC_T *p)
        mtx_unlock(&mountlist_mtx);
 
        if (nmp != NULL) {
-               ds = nfsrv_deldsnmp(nmp, p);
+               ds = nfsrv_deldsnmp(op, nmp, p);
                NFSD_DEBUG(4, "deldsnmp=%p\n", ds);
                if (ds != NULL) {
                        nfsrv_killrpcs(nmp);
@@ -7544,20 +7544,26 @@ nfsrv_deldsserver(char *dspathp, NFSPROC_T *p)
  * Search for and remove a DS entry which matches the "nmp" argument.
  * The nfsdevice structure pointer is returned so that the caller can
  * free it via nfsrv_freeonedevid().
+ * For the forced case, do not try to do LayoutRecalls, since the server
+ * must be shut down now anyhow.
  */
 struct nfsdevice *
-nfsrv_deldsnmp(struct nfsmount *nmp, NFSPROC_T *p)
+nfsrv_deldsnmp(int op, struct nfsmount *nmp, NFSPROC_T *p)
 {
        struct nfsdevice *fndds;
 
        NFSD_DEBUG(4, "deldsdvp\n");
        NFSDDSLOCK();
-       fndds = nfsrv_findmirroredds(nmp);
+       if (op == PNFSDOP_FORCEDELDS)
+               fndds = nfsv4_findmirror(nmp);
+       else
+               fndds = nfsrv_findmirroredds(nmp);
        if (fndds != NULL)
                nfsrv_deleteds(fndds);
        NFSDDSUNLOCK();
        if (fndds != NULL) {
-               nfsrv_flexmirrordel(fndds->nfsdev_deviceid, p);
+               if (op != PNFSDOP_FORCEDELDS)
+                       nfsrv_flexmirrordel(fndds->nfsdev_deviceid, p);
                printf("pNFS server: mirror %s failed\n", fndds->nfsdev_host);
        }
        return (fndds);
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to