Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 28 Apr 2017 13:15:41 +0000 (UTC)
From:      Rick Macklem <rmacklem@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r317553 - projects/pnfs-planb-server/usr.sbin/nfsd
Message-ID:  <201704281315.v3SDFgPV062998@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: rmacklem
Date: Fri Apr 28 13:15:41 2017
New Revision: 317553
URL: https://svnweb.freebsd.org/changeset/base/317553

Log:
  Update nfsd with the pNFS code.

Modified:
  projects/pnfs-planb-server/usr.sbin/nfsd/nfsd.8
  projects/pnfs-planb-server/usr.sbin/nfsd/nfsd.c

Modified: projects/pnfs-planb-server/usr.sbin/nfsd/nfsd.8
==============================================================================
--- projects/pnfs-planb-server/usr.sbin/nfsd/nfsd.8	Fri Apr 28 13:13:23 2017	(r317552)
+++ projects/pnfs-planb-server/usr.sbin/nfsd/nfsd.8	Fri Apr 28 13:15:41 2017	(r317553)
@@ -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 
 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/usr.sbin/nfsd/nfsd.c
==============================================================================
--- projects/pnfs-planb-server/usr.sbin/nfsd/nfsd.c	Fri Apr 28 13:13:23 2017	(r317552)
+++ projects/pnfs-planb-server/usr.sbin/nfsd/nfsd.c	Fri Apr 28 13:15:41 2017	(r317553)
@@ -59,12 +59,16 @@ static const char rcsid[] =
 #include <rpc/rpc.h>
 #include <rpc/pmap_clnt.h>
 #include <rpcsvc/nfs_prot.h>
+#include <rpcsvc/mount.h>
 
 #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 +99,8 @@ static int stablefd = -1;	/* Fd for the 
 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 +109,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 +129,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 +182,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 +227,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 the port#s. */
+			parse_dsserver(optarg, &nfsdargs);
+			break;
 		case 0:
 			lopt = longopts[longindex].name;
 			if (!strcmp(lopt, "minthreads")) {
@@ -427,7 +450,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 +468,7 @@ main(int argc, char **argv)
 		} else {
 			(void)signal(SIGUSR1, child_cleanup);
 			setproctitle("server");
-			start_server(0);
+			start_server(0, &nfsdargs);
 		}
 	}
 
@@ -766,7 +789,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 +1013,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 +1038,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 +1058,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");
@@ -1139,3 +1161,126 @@ backup_stable(__unused int signo)
 		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);
+}
+
+



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201704281315.v3SDFgPV062998>