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:
parent
76772b9dc3
commit
2af903ca13
@ -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 {
|
||||
|
@ -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 *,
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user