From owner-svn-src-projects@freebsd.org Tue Aug 8 23:55:40 2017 Return-Path: Delivered-To: svn-src-projects@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 5DB9DDD8BDE for ; Tue, 8 Aug 2017 23:55:40 +0000 (UTC) (envelope-from rmacklem@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 382927D2F0; Tue, 8 Aug 2017 23:55:40 +0000 (UTC) (envelope-from rmacklem@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id v78Ntdge080535; Tue, 8 Aug 2017 23:55:39 GMT (envelope-from rmacklem@FreeBSD.org) Received: (from rmacklem@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id v78NtcUn080530; Tue, 8 Aug 2017 23:55:38 GMT (envelope-from rmacklem@FreeBSD.org) Message-Id: <201708082355.v78NtcUn080530@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: rmacklem set sender to rmacklem@FreeBSD.org using -f From: Rick Macklem Date: Tue, 8 Aug 2017 23:55:38 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r322284 - in projects/pnfs-planb-server: sys/fs/nfs sys/fs/nfsserver usr.sbin/nfsd X-SVN-Group: projects X-SVN-Commit-Author: rmacklem X-SVN-Commit-Paths: in projects/pnfs-planb-server: sys/fs/nfs sys/fs/nfsserver usr.sbin/nfsd X-SVN-Commit-Revision: 322284 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 08 Aug 2017 23:55:40 -0000 Author: rmacklem Date: Tue Aug 8 23:55:38 2017 New Revision: 322284 URL: https://svnweb.freebsd.org/changeset/base/322284 Log: Add support for mirrors to the private API that nfsd(8) uses to configure the pNFS server. Mirrors are nowhere near being supported, but by doing this now, it won't be necessary to rev. this private API later. Modified: projects/pnfs-planb-server/sys/fs/nfs/nfs.h projects/pnfs-planb-server/sys/fs/nfs/nfsrvstate.h projects/pnfs-planb-server/sys/fs/nfsserver/nfs_nfsdport.c projects/pnfs-planb-server/sys/fs/nfsserver/nfs_nfsdstate.c projects/pnfs-planb-server/usr.sbin/nfsd/nfsd.c Modified: projects/pnfs-planb-server/sys/fs/nfs/nfs.h ============================================================================== --- projects/pnfs-planb-server/sys/fs/nfs/nfs.h Tue Aug 8 23:44:47 2017 (r322283) +++ projects/pnfs-planb-server/sys/fs/nfs/nfs.h Tue Aug 8 23:55:38 2017 (r322284) @@ -183,7 +183,10 @@ struct nfsd_nfsd_args { int dnshostlen; /* Length of DNS names */ char *dspath; /* DS Mount path on MDS */ int dspathlen; /* Length of DS Mount path on MDS */ + char *mirror; /* DS with same mirrorindex are mirrors */ + int mirrorlen; /* Length of the mirrorindex array */ }; +#define NFSDEV_MIRRORSTR 3 /* Old version. */ struct nfsd_nfsd_oargs { Modified: projects/pnfs-planb-server/sys/fs/nfs/nfsrvstate.h ============================================================================== --- projects/pnfs-planb-server/sys/fs/nfs/nfsrvstate.h Tue Aug 8 23:44:47 2017 (r322283) +++ projects/pnfs-planb-server/sys/fs/nfs/nfsrvstate.h Tue Aug 8 23:55:38 2017 (r322284) @@ -47,6 +47,7 @@ LIST_HEAD(nfssessionhead, nfsdsession); LIST_HEAD(nfssessionhashhead, nfsdsession); LIST_HEAD(nfslayouthead, nfslayout); SLIST_HEAD(nfsdsdirhead, nfsdsdir); +TAILQ_HEAD(nfsdevicehead, nfsdevice); /* * List head for nfsusrgrp. @@ -331,9 +332,11 @@ void nfsrv_freedeleglist(struct nfsstatehead *); */ struct nfsdevice { TAILQ_ENTRY(nfsdevice) nfsdev_list; + struct nfsdevicehead nfsdev_mirrors; vnode_t nfsdev_dvp; struct nfsmount *nfsdev_nmp; char nfsdev_deviceid[NFSX_V4DEVICEID]; + char nfsdev_mirrorid[NFSDEV_MIRRORSTR + 1]; uint16_t nfsdev_hostnamelen; uint16_t nfsdev_fileaddrlen; uint16_t nfsdev_flexaddrlen; @@ -343,7 +346,6 @@ struct nfsdevice { uint32_t nfsdev_nextdir; vnode_t nfsdev_dsdir[0]; }; -TAILQ_HEAD(nfsdevicehead, nfsdevice); /* * This structure holds the va_size, va_filerev, va_atime and va_mtime for the Modified: projects/pnfs-planb-server/sys/fs/nfsserver/nfs_nfsdport.c ============================================================================== --- projects/pnfs-planb-server/sys/fs/nfsserver/nfs_nfsdport.c Tue Aug 8 23:44:47 2017 (r322283) +++ projects/pnfs-planb-server/sys/fs/nfsserver/nfs_nfsdport.c Tue Aug 8 23:55:38 2017 (r322284) @@ -3309,6 +3309,8 @@ nfssvc_nfsd(struct thread *td, struct nfssvc_args *uap nfsdarg.addrlen = 0; nfsdarg.dnshost = NULL; nfsdarg.dnshostlen = 0; + nfsdarg.mirror = NULL; + nfsdarg.mirrorlen = 0; } } else error = copyin(uap->argp, &nfsdarg, sizeof(nfsdarg)); @@ -3317,11 +3319,13 @@ nfssvc_nfsd(struct thread *td, struct nfssvc_args *uap if (nfsdarg.addrlen > 0 && nfsdarg.addrlen < 10000 && nfsdarg.dnshostlen > 0 && nfsdarg.dnshostlen < 10000 && nfsdarg.dspathlen > 0 && nfsdarg.dspathlen < 10000 && + nfsdarg.mirrorlen > 0 && nfsdarg.mirrorlen < 10000 && nfsdarg.addr != NULL && nfsdarg.dnshost != NULL && - nfsdarg.dspath != NULL) { - NFSD_DEBUG(1, "addrlen=%d dspathlen=%d dnslen=%d\n", - nfsdarg.addrlen, nfsdarg.dspathlen, - nfsdarg.dnshostlen); + nfsdarg.dspath != NULL && nfsdarg.mirror != NULL) { + NFSD_DEBUG(1, "addrlen=%d dspathlen=%d dnslen=%d" + " mirrorlen=%d\n", nfsdarg.addrlen, + nfsdarg.dspathlen, nfsdarg.dnshostlen, + nfsdarg.mirrorlen); cp = malloc(nfsdarg.addrlen + 1, M_TEMP, M_WAITOK); error = copyin(nfsdarg.addr, cp, nfsdarg.addrlen); if (error != 0) { @@ -3349,6 +3353,17 @@ nfssvc_nfsd(struct thread *td, struct nfssvc_args *uap } cp[nfsdarg.dspathlen] = '\0'; /* Ensure nul term. */ nfsdarg.dspath = cp; + cp = malloc(nfsdarg.mirrorlen + 1, M_TEMP, M_WAITOK); + error = copyin(nfsdarg.mirror, cp, nfsdarg.mirrorlen); + if (error != 0) { + free(nfsdarg.addr, M_TEMP); + free(nfsdarg.dnshost, M_TEMP); + free(nfsdarg.dspath, M_TEMP); + free(cp, M_TEMP); + goto out; + } + cp[nfsdarg.mirrorlen] = '\0'; /* Ensure nul term. */ + nfsdarg.mirror = cp; } else { nfsdarg.addr = NULL; nfsdarg.addrlen = 0; @@ -3356,11 +3371,14 @@ nfssvc_nfsd(struct thread *td, struct nfssvc_args *uap nfsdarg.dnshostlen = 0; nfsdarg.dspath = NULL; nfsdarg.dspathlen = 0; + nfsdarg.mirror = NULL; + nfsdarg.mirrorlen = 0; } error = nfsrvd_nfsd(td, &nfsdarg); free(nfsdarg.addr, M_TEMP); free(nfsdarg.dnshost, M_TEMP); free(nfsdarg.dspath, M_TEMP); + free(nfsdarg.mirror, M_TEMP); } else { error = nfssvc_srvcall(td, uap, td->td_ucred); } Modified: projects/pnfs-planb-server/sys/fs/nfsserver/nfs_nfsdstate.c ============================================================================== --- projects/pnfs-planb-server/sys/fs/nfsserver/nfs_nfsdstate.c Tue Aug 8 23:44:47 2017 (r322283) +++ projects/pnfs-planb-server/sys/fs/nfsserver/nfs_nfsdstate.c Tue Aug 8 23:55:38 2017 (r322284) @@ -188,7 +188,8 @@ static void nfsrv_freelayout(struct nfslayout *lyp); static void nfsrv_freelayoutlist(nfsquad_t clientid); static void nfsrv_freealllayouts(int *fndp); static void nfsrv_freedevid(struct nfsdevice *ds); -static int nfsrv_setdsserver(char *dspathp, NFSPROC_T *p, +static void nfsrv_freeonedevid(struct nfsdevice *ds); +static int nfsrv_setdsserver(char *dspathp, char *mirrorp, NFSPROC_T *p, struct nfsdevice **dsp); static void nfsrv_allocdevid(struct nfsdevice *ds, char *addr, char *dnshost); static void nfsrv_freealldevids(void); @@ -6685,11 +6686,10 @@ nfsrv_freelayout(struct nfslayout *lyp) * Free up a device id. */ static void -nfsrv_freedevid(struct nfsdevice *ds) +nfsrv_freeonedevid(struct nfsdevice *ds) { int i; - TAILQ_REMOVE(&nfsrv_devidhead, ds, nfsdev_list); vrele(ds->nfsdev_dvp); for (i = 0; i < nfsrv_dsdirsize; i++) if (ds->nfsdev_dsdir[i] != NULL) @@ -6701,6 +6701,20 @@ nfsrv_freedevid(struct nfsdevice *ds) } /* + * Free up a device id and its mirrors. + */ +static void +nfsrv_freedevid(struct nfsdevice *ds) +{ + struct nfsdevice *mds, *nds; + + TAILQ_REMOVE(&nfsrv_devidhead, ds, nfsdev_list); + TAILQ_FOREACH_SAFE(mds, &ds->nfsdev_mirrors, nfsdev_list, nds) + nfsrv_freeonedevid(mds); + nfsrv_freeonedevid(ds); +} + +/* * Free all layouts and device ids. * Done when the nfsd threads are shut down since there may be a new * modified device id list created when the nfsd is restarted. @@ -6744,10 +6758,11 @@ nfsrv_freealllayouts(int *fndp) * Look up the mount path for the DS server. */ static int -nfsrv_setdsserver(char *dspathp, NFSPROC_T *p, struct nfsdevice **dsp) +nfsrv_setdsserver(char *dspathp, char *mirrorp, NFSPROC_T *p, + struct nfsdevice **dsp) { struct nameidata nd; - struct nfsdevice *ds; + struct nfsdevice *ds, *mds, *tds; int error, i; char *dsdirpath; size_t dsdirsize; @@ -6778,6 +6793,8 @@ nfsrv_setdsserver(char *dspathp, NFSPROC_T *p, struct */ *dsp = ds = malloc(sizeof(*ds) + nfsrv_dsdirsize * sizeof(vnode_t), M_NFSDSTATE, M_WAITOK | M_ZERO); + TAILQ_INIT(&ds->nfsdev_mirrors); + strcpy(ds->nfsdev_mirrorid, mirrorp); ds->nfsdev_dvp = nd.ni_vp; NFSVOPUNLOCK(nd.ni_vp, 0); @@ -6812,8 +6829,23 @@ nfsrv_setdsserver(char *dspathp, NFSPROC_T *p, struct /* * Since this is done before the nfsd threads are running, locking * isn't required. + * First, look for a mirror. If none found, link into main list. */ - TAILQ_INSERT_TAIL(&nfsrv_devidhead, ds, nfsdev_list); + TAILQ_FOREACH(mds, &nfsrv_devidhead, nfsdev_list) { + if (strcmp(mds->nfsdev_mirrorid, mirrorp) == 0) { + TAILQ_INSERT_TAIL(&mds->nfsdev_mirrors, ds, + nfsdev_list); + ds = NULL; + i = 1; + TAILQ_FOREACH(tds, &mds->nfsdev_mirrors, nfsdev_list) + i++; + if (i > nfsrv_maxpnfsmirror) + nfsrv_maxpnfsmirror = i; + break; + } + } + if (ds != NULL) + TAILQ_INSERT_TAIL(&nfsrv_devidhead, ds, nfsdev_list); return (error); } @@ -6901,23 +6933,30 @@ int nfsrv_createdevids(struct nfsd_nfsd_args *args, NFSPROC_T *p) { struct nfsdevice *ds; - char *addrp, *dnshostp, *dspathp; + char *addrp, *dnshostp, *dspathp, *mirrorp; int error; addrp = args->addr; dnshostp = args->dnshost; dspathp = args->dspath; - if (addrp == NULL || dnshostp == NULL || dspathp == NULL) + mirrorp = args->mirror; + if (addrp == NULL || dnshostp == NULL || dspathp == NULL || + mirrorp == NULL) return (0); /* - * Loop around for each nul-terminated string in args->addr and - * args->dnshost. + * Loop around for each nul-terminated string in args->addr, + * args->dnshost, args->dnspath and args->mirror. */ while (addrp < (args->addr + args->addrlen) && dnshostp < (args->dnshost + args->dnshostlen) && - dspathp < (args->dspath + args->dspathlen)) { - error = nfsrv_setdsserver(dspathp, p, &ds); + dspathp < (args->dspath + args->dspathlen) && + mirrorp < (args->mirror + args->mirrorlen)) { + error = 0; + if (*mirrorp == '\0' || strlen(mirrorp) > NFSDEV_MIRRORSTR) + error = ENXIO; + if (error == 0) + error = nfsrv_setdsserver(dspathp, mirrorp, p, &ds); if (error != 0) { /* Free all DS servers. */ nfsrv_freealldevids(); @@ -6927,6 +6966,7 @@ nfsrv_createdevids(struct nfsd_nfsd_args *args, NFSPRO addrp += (strlen(addrp) + 1); dnshostp += (strlen(dnshostp) + 1); dspathp += (strlen(dspathp) + 1); + mirrorp += (strlen(mirrorp) + 1); } return (0); } Modified: projects/pnfs-planb-server/usr.sbin/nfsd/nfsd.c ============================================================================== --- projects/pnfs-planb-server/usr.sbin/nfsd/nfsd.c Tue Aug 8 23:44:47 2017 (r322283) +++ projects/pnfs-planb-server/usr.sbin/nfsd/nfsd.c Tue Aug 8 23:55:38 2017 (r322284) @@ -1175,8 +1175,10 @@ static void parse_dsserver(const char *optarg, struct nfsd_nfsd_args *nfsdargp) { char *ad, *cp, *cp2, *dsaddr, *dshost, *dspath, *dsvol, nfsprt[9]; + char *mirror, mirrorstr[NFSDEV_MIRRORSTR + 1]; int adsiz, dsaddrcnt, dshostcnt, dspathcnt, ecode, hostsiz, pathsiz; - size_t dsaddrsiz, dshostsiz, dspathsiz, nfsprtsiz; + int mirrorcnt, mirrorstrsiz, mirrorindex; + size_t dsaddrsiz, dshostsiz, dspathsiz, nfsprtsiz, mirrorsiz; struct addrinfo hints, *ai_tcp; struct sockaddr_in *sin; @@ -1200,12 +1202,18 @@ parse_dsserver(const char *optarg, struct nfsd_nfsd_ar dsaddr = malloc(dsaddrsiz); if (dsaddr == NULL) errx(1, "Out of memory"); + mirrorsiz = 1024; + mirrorcnt = 0; + mirror = malloc(mirrorsiz); + if (mirror == NULL) + errx(1, "Out of memory"); /* Put the NFS port# in "." form. */ snprintf(nfsprt, 9, ".%d.%d", 2049 >> 8, 2049 & 0xff); nfsprtsiz = strlen(nfsprt); ai_tcp = NULL; + mirrorindex = 0; /* Loop around for each DS server name. */ do { cp2 = strchr(cp, ','); @@ -1272,6 +1280,20 @@ printf("pnfs path=%s\n", dsvol); strcpy(&dshost[dshostcnt], ai_tcp->ai_canonname); dshostcnt += hostsiz + 1; + /* Append this mirrorindex to mirror. */ + if (snprintf(mirrorstr, NFSDEV_MIRRORSTR + 1, "%d", + mirrorindex++) > NFSDEV_MIRRORSTR) + errx(1, "Too many mirrors"); + mirrorstrsiz = strlen(mirrorstr); + if (mirrorcnt + mirrorstrsiz + 1 > mirrorsiz) { + mirrorsiz *= 2; + mirror = realloc(mirror, mirrorsiz); + if (mirror == NULL) + errx(1, "Out of memory"); + } + strcpy(&mirror[mirrorcnt], mirrorstr); + mirrorcnt += mirrorstrsiz + 1; + cp = cp2; } while (cp != NULL); @@ -1287,6 +1309,8 @@ printf("pnfs path=%s\n", dsvol); nfsdargp->dnshostlen = dshostcnt; nfsdargp->dspath = dspath; nfsdargp->dspathlen = dspathcnt; + nfsdargp->mirror = mirror; + nfsdargp->mirrorlen = mirrorcnt; freeaddrinfo(ai_tcp); }