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.
This commit is contained in:
Rick Macklem 2018-07-09 19:58:01 +00:00
parent 1017327049
commit de9a1a70ab
4 changed files with 21 additions and 12 deletions

View File

@ -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 {

View File

@ -159,8 +159,8 @@ int nfsrv_getdevinfo(char *, int, uint32_t *, uint32_t *, int *, char **);
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 *,

View File

@ -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, struct ucred *cred,
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, char *fname, fhandle_t *fhp,
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 @@ nfsrv_proxyds(struct nfsrv_descript *nd, struct vnode *vp, off_t off, int cnt,
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)

View File

@ -7482,7 +7482,7 @@ nfsrv_setdsserver(char *dspathp, char *mdspathp, NFSPROC_T *p,
* 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);