svn commit: r319838 - projects/pnfs-planb-server-stable11/usr.sbin/nfsd
Rick Macklem
rmacklem at FreeBSD.org
Sun Jun 11 22:05:33 UTC 2017
Author: rmacklem
Date: Sun Jun 11 22:05:32 2017
New Revision: 319838
URL: https://svnweb.freebsd.org/changeset/base/319838
Log:
Update nfsd to support the pNFS server.
Modified:
projects/pnfs-planb-server-stable11/usr.sbin/nfsd/nfsd.8
projects/pnfs-planb-server-stable11/usr.sbin/nfsd/nfsd.c
Modified: projects/pnfs-planb-server-stable11/usr.sbin/nfsd/nfsd.8
==============================================================================
--- projects/pnfs-planb-server-stable11/usr.sbin/nfsd/nfsd.8 Sun Jun 11 21:49:59 2017 (r319837)
+++ projects/pnfs-planb-server-stable11/usr.sbin/nfsd/nfsd.8 Sun Jun 11 22:05:32 2017 (r319838)
@@ -41,6 +41,7 @@ server
.Op Fl ardute
.Op Fl n Ar num_servers
.Op Fl h Ar bindip
+.Op Fl p Ar pnfs_setup
.Op Fl Fl maxthreads Ar max_threads
.Op Fl Fl minthreads Ar min_threads
.Sh DESCRIPTION
@@ -103,6 +104,35 @@ It may also be specified in addition to any
options given.
Note that NFS/UDP does not operate properly when
bound to the wildcard IP address whether you use -a or do not use -h.
+.It Fl p Ar pnfs_setup
+Enables pNFS support in the server and specifies the information that the
+daemon needs to start it.
+This option can only be used on one server and specifies that this server
+will be the MetaData Server (MDS) for the pNFS service.
+This can only be done if there is at least one FreeBSD system configured
+as a Data Server (DS) for it to use.
+.Pp
+The
+.Ar pnfs_setup
+string is a set of ',' separated fields:
+.Bl -tag -width Ds
+.It
+Each of these fields specifies one Data Server.
+It consists of a server hostname, followed by a ':'
+and the directory path where the DS's data storage file system is mounted on
+this MDS server.
+The DS storage file systems must be mounted on this system before the
+.Nm
+is started with this option specified.
+For example:
+.sp
+nfsv4-ds0:/DS0,nfsv4-ds1:/DS1
+.sp
+Would specify two DS servers called nfsv4-ds0 and nfsv4-ds1 that comprise the
+data storage component of the pNFS service.
+The directories "/DS0" and "/DS1" are where the DS storage servers exported
+storage directories are mounted on this system (which will act as the MDS).
+.El
.It Fl t
Serve
.Tn TCP NFS
Modified: projects/pnfs-planb-server-stable11/usr.sbin/nfsd/nfsd.c
==============================================================================
--- projects/pnfs-planb-server-stable11/usr.sbin/nfsd/nfsd.c Sun Jun 11 21:49:59 2017 (r319837)
+++ projects/pnfs-planb-server-stable11/usr.sbin/nfsd/nfsd.c Sun Jun 11 22:05:32 2017 (r319838)
@@ -62,9 +62,12 @@ static const char rcsid[] =
#include <netdb.h>
#include <arpa/inet.h>
-#include <nfsserver/nfs.h>
#include <nfs/nfssvc.h>
+#include <fs/nfs/nfsproto.h>
+#include <fs/nfs/nfskpiport.h>
+#include <fs/nfs/nfs.h>
+
#include <err.h>
#include <errno.h>
#include <signal.h>
@@ -95,6 +98,8 @@ static int stablefd = -1; /* Fd for the stable restart
static int backupfd; /* Fd for the backup stable restart file */
static const char *getopt_shortopts;
static const char *getopt_usage;
+static char *dshost = NULL;
+static int dshostc = 0;
static int minthreads_set;
static int maxthreads_set;
@@ -103,9 +108,18 @@ static struct option longopts[] = {
{ "debug", no_argument, &debug, 1 },
{ "minthreads", required_argument, &minthreads_set, 1 },
{ "maxthreads", required_argument, &maxthreads_set, 1 },
+ { "pnfs", required_argument, NULL, 'p' },
{ NULL, 0, NULL, 0}
};
+struct nfhret {
+ u_long stat;
+ long vers;
+ long auth;
+ long fhsize;
+ u_char nfh[NFS3_FHSIZE];
+};
+
static void cleanup(int);
static void child_cleanup(int);
static void killchildren(void);
@@ -114,13 +128,14 @@ static void nonfs(int);
static void reapchild(int);
static int setbindhost(struct addrinfo **ia, const char *bindhost,
struct addrinfo hints);
-static void start_server(int);
+static void start_server(int, struct nfsd_nfsd_args *);
static void unregistration(void);
static void usage(void);
static void open_stable(int *, int *);
static void copy_stable(int, int);
static void backup_stable(int);
static void set_nfsdcnt(int);
+static void parse_dsserver(const char *, struct nfsd_nfsd_args *);
/*
* Nfs server daemon mostly just a user context for nfssvc()
@@ -166,15 +181,18 @@ main(int argc, char **argv)
const char *lopt;
char **bindhost = NULL;
pid_t pid;
+ struct nfsd_nfsd_args nfsdargs;
nfsdcnt = DEFNFSDCNT;
unregister = reregister = tcpflag = maxsock = 0;
bindanyflag = udpflag = connect_type_cnt = bindhostc = 0;
- getopt_shortopts = "ah:n:rdtue";
+ getopt_shortopts = "ah:n:rdtuep:";
getopt_usage =
"usage:\n"
" nfsd [-ardtue] [-h bindip]\n"
- " [-n numservers] [--minthreads #] [--maxthreads #]\n";
+ " [-n numservers] [--minthreads #] [--maxthreads #]\n"
+ " [-p/--pnfs dsserver0:/dsserver0-mounted-on-dir,...,"
+ "dsserverN:/dsserverN-mounted-on-dir\n";
while ((ch = getopt_long(argc, argv, getopt_shortopts, longopts,
&longindex)) != -1)
switch (ch) {
@@ -208,6 +226,10 @@ main(int argc, char **argv)
case 'e':
/* now a no-op, since this is the default */
break;
+ case 'p':
+ /* Parse out the DS server host names and mount pts. */
+ parse_dsserver(optarg, &nfsdargs);
+ break;
case 0:
lopt = longopts[longindex].name;
if (!strcmp(lopt, "minthreads")) {
@@ -427,7 +449,7 @@ main(int argc, char **argv)
exit(1);
}
nfssvc_addsock = NFSSVC_NFSDADDSOCK;
- nfssvc_nfsd = NFSSVC_NFSDNFSD;
+ nfssvc_nfsd = NFSSVC_NFSDNFSD | NFSSVC_NEWSTRUCT;
if (tcpflag) {
/*
@@ -445,7 +467,7 @@ main(int argc, char **argv)
} else {
(void)signal(SIGUSR1, child_cleanup);
setproctitle("server");
- start_server(0);
+ start_server(0, &nfsdargs);
}
}
@@ -766,7 +788,7 @@ main(int argc, char **argv)
* a "server" too. start_server will not return.
*/
if (!tcpflag)
- start_server(1);
+ start_server(1, &nfsdargs);
/*
* Loop forever accepting connections and passing the sockets
@@ -990,10 +1012,9 @@ get_tuned_nfsdcount(void)
}
static void
-start_server(int master)
+start_server(int master, struct nfsd_nfsd_args *nfsdargp)
{
char principal[MAXHOSTNAMELEN + 5];
- struct nfsd_nfsd_args nfsdargs;
int status, error;
char hostname[MAXHOSTNAMELEN + 1], *cp;
struct addrinfo *aip, hints;
@@ -1016,17 +1037,17 @@ start_server(int master)
freeaddrinfo(aip);
}
}
- nfsdargs.principal = principal;
+ nfsdargp->principal = principal;
if (nfsdcnt_set)
- nfsdargs.minthreads = nfsdargs.maxthreads = nfsdcnt;
+ nfsdargp->minthreads = nfsdargp->maxthreads = nfsdcnt;
else {
- nfsdargs.minthreads = minthreads_set ? minthreads : get_tuned_nfsdcount();
- nfsdargs.maxthreads = maxthreads_set ? maxthreads : nfsdargs.minthreads;
- if (nfsdargs.maxthreads < nfsdargs.minthreads)
- nfsdargs.maxthreads = nfsdargs.minthreads;
+ nfsdargp->minthreads = minthreads_set ? minthreads : get_tuned_nfsdcount();
+ nfsdargp->maxthreads = maxthreads_set ? maxthreads : nfsdargp->minthreads;
+ if (nfsdargp->maxthreads < nfsdargp->minthreads)
+ nfsdargp->maxthreads = nfsdargp->minthreads;
}
- error = nfssvc(nfssvc_nfsd, &nfsdargs);
+ error = nfssvc(nfssvc_nfsd, nfsdargp);
if (error < 0 && errno == EAUTH) {
/*
* This indicates that it could not register the
@@ -1036,7 +1057,7 @@ start_server(int master)
*/
syslog(LOG_ERR, "No gssd, using AUTH_SYS only");
principal[0] = '\0';
- error = nfssvc(nfssvc_nfsd, &nfsdargs);
+ error = nfssvc(nfssvc_nfsd, nfsdargp);
}
if (error < 0) {
syslog(LOG_ERR, "nfssvc: %m");
@@ -1138,4 +1159,127 @@ backup_stable(__unused int signo)
if (stablefd >= 0)
copy_stable(stablefd, backupfd);
}
+
+/*
+ * Parse the pNFS string and extract the DS servers and ports numbers.
+ */
+static void
+parse_dsserver(const char *optarg, struct nfsd_nfsd_args *nfsdargp)
+{
+ char *ad, *cp, *cp2, *dsaddr, *dshost, *dspath, *dsvol, nfsprt[9];
+ int adsiz, dsaddrcnt, dshostcnt, dspathcnt, ecode, hostsiz, pathsiz;
+ size_t dsaddrsiz, dshostsiz, dspathsiz, nfsprtsiz;
+ struct addrinfo hints, *ai_tcp;
+ struct sockaddr_in *sin;
+
+ cp = strdup(optarg);
+ if (cp == NULL)
+ errx(1, "Out of memory");
+
+ /* Now, do the host names. */
+ dspathsiz = 1024;
+ dspathcnt = 0;
+ dspath = malloc(dspathsiz);
+ if (dspath == NULL)
+ errx(1, "Out of memory");
+ dshostsiz = 1024;
+ dshostcnt = 0;
+ dshost = malloc(dshostsiz);
+ if (dshost == NULL)
+ errx(1, "Out of memory");
+ dsaddrsiz = 1024;
+ dsaddrcnt = 0;
+ dsaddr = malloc(dsaddrsiz);
+ if (dsaddr == 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;
+ /* Loop around for each DS server name. */
+ do {
+ cp2 = strchr(cp, ',');
+ if (cp2 != NULL) {
+ *cp2++ = '\0';
+ if (*cp2 == '\0')
+ usage();
+ }
+ dsvol = strchr(cp, ':');
+ if (dsvol == NULL || *(dsvol + 1) == '\0')
+ usage();
+ *dsvol++ = '\0';
+
+printf("pnfs path=%s\n", dsvol);
+ /* Append this pathname to dspath. */
+ pathsiz = strlen(dsvol);
+ if (dspathcnt + pathsiz + 1 > dspathsiz) {
+ dspathsiz *= 2;
+ dspath = realloc(dspath, dspathsiz);
+ if (dspath == NULL)
+ errx(1, "Out of memory");
+ }
+ strcpy(&dspath[dspathcnt], dsvol);
+ dspathcnt += pathsiz + 1;
+
+ if (ai_tcp != NULL)
+ freeaddrinfo(ai_tcp);
+
+ /* Get the fully qualified domain name and IP address. */
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_flags = AI_CANONNAME;
+ hints.ai_family = AF_INET;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_protocol = IPPROTO_TCP;
+ ecode = getaddrinfo(cp, NULL, &hints, &ai_tcp);
+ if (ecode != 0)
+ err(1, "getaddrinfo pnfs: %s %s", cp,
+ gai_strerror(ecode));
+ sin = (struct sockaddr_in *)ai_tcp->ai_addr;
+ if (sin->sin_family != AF_INET)
+ err(1, "getaddrinfo() returned non-INET address");
+
+ /* Append this address to dsaddr. */
+ ad = inet_ntoa(sin->sin_addr);
+ adsiz = strlen(ad);
+ if (dsaddrcnt + adsiz + nfsprtsiz + 1 > dsaddrsiz) {
+ dsaddrsiz *= 2;
+ dsaddr = realloc(dsaddr, dsaddrsiz);
+ if (dsaddr == NULL)
+ errx(1, "Out of memory");
+ }
+ strcpy(&dsaddr[dsaddrcnt], ad);
+ strcat(&dsaddr[dsaddrcnt], nfsprt);
+ dsaddrcnt += adsiz + nfsprtsiz + 1;
+
+ /* Append this hostname to dshost. */
+ hostsiz = strlen(ai_tcp->ai_canonname);
+ if (dshostcnt + hostsiz + 1 > dshostsiz) {
+ dshostsiz *= 2;
+ dshost = realloc(dshost, dshostsiz);
+ if (dshost == NULL)
+ errx(1, "Out of memory");
+ }
+ strcpy(&dshost[dshostcnt], ai_tcp->ai_canonname);
+ dshostcnt += hostsiz + 1;
+
+ cp = cp2;
+ } while (cp != NULL);
+
+ /*
+ * At the point, ai_tcp refers to the last DS server host and
+ * sin is set to point to the sockaddr structure in it.
+ * Set the port# for the DS Mount protocol and get the DS root FH.
+ */
+ sin->sin_port = htons(2049);
+ nfsdargp->addr = dsaddr;
+ nfsdargp->addrlen = dsaddrcnt;
+ nfsdargp->dnshost = dshost;
+ nfsdargp->dnshostlen = dshostcnt;
+ nfsdargp->dspath = dspath;
+ nfsdargp->dspathlen = dspathcnt;
+ freeaddrinfo(ai_tcp);
+}
+
More information about the svn-src-projects
mailing list