Blame SOURCES/nfs-utils-1.3.0-blkmapd-pnfs.patch

d2edb4
diff --git a/Makefile.am b/Makefile.am
d2edb4
index ae7cd16..c9e9f87 100644
d2edb4
--- a/Makefile.am
d2edb4
+++ b/Makefile.am
d2edb4
@@ -2,7 +2,7 @@
d2edb4
 
d2edb4
 AUTOMAKE_OPTIONS = foreign
d2edb4
 
d2edb4
-SUBDIRS = tools support utils linux-nfs tests
d2edb4
+SUBDIRS = tools support utils linux-nfs tests systemd
d2edb4
 
d2edb4
 MAINTAINERCLEANFILES = Makefile.in
d2edb4
 
d2edb4
diff --git a/configure.ac b/configure.ac
d2edb4
index 7b93de6..4ee4db5 100644
d2edb4
--- a/configure.ac
d2edb4
+++ b/configure.ac
d2edb4
@@ -54,6 +54,16 @@ AC_ARG_WITH(start-statd,
d2edb4
 	)
d2edb4
 	AC_SUBST(startstatd)
d2edb4
 	AC_DEFINE_UNQUOTED(START_STATD, "$startstatd", [Define this to a script which can start statd on mount])
d2edb4
+unitdir=/usr/lib/systemd/system
d2edb4
+AC_ARG_WITH(systemd,
d2edb4
+	[AC_HELP_STRING([--with-systemd@<:@=unit-dir-path@:>@],
d2edb4
+			[install systemd unit files @<:@Default: no, and path defaults to /usr/lib/systemd/system if not given@:>@])],
d2edb4
+	test "$withval" = "no" && use_systemd=0 || unitdir=$withval use_systemd=1
d2edb4
+	use_systemd=0
d2edb4
+	)
d2edb4
+	AM_CONDITIONAL(INSTALL_SYSTEMD, [test "$use_systemd" = 1])
d2edb4
+	AC_SUBST(unitdir)
d2edb4
+
d2edb4
 AC_ARG_ENABLE(nfsv4,
d2edb4
 	[AC_HELP_STRING([--enable-nfsv4],
d2edb4
                         [enable support for NFSv4 @<:@default=yes@:>@])],
d2edb4
@@ -506,6 +516,7 @@ AC_CONFIG_FILES([
d2edb4
 	utils/showmount/Makefile
d2edb4
 	utils/statd/Makefile
d2edb4
 	utils/osd_login/Makefile
d2edb4
+	systemd/Makefile
d2edb4
 	tests/Makefile
d2edb4
 	tests/nsm_client/Makefile])
d2edb4
 AC_OUTPUT
d2edb4
diff --git a/support/include/nfs/export.h b/support/include/nfs/export.h
d2edb4
index 2f59e6a..1194255 100644
d2edb4
--- a/support/include/nfs/export.h
d2edb4
+++ b/support/include/nfs/export.h
d2edb4
@@ -26,6 +26,7 @@
d2edb4
 #define	NFSEXP_CROSSMOUNT	0x4000
d2edb4
 #define NFSEXP_NOACL		0x8000 /* reserved for possible ACL related use */
d2edb4
 #define NFSEXP_V4ROOT		0x10000
d2edb4
+#define NFSEXP_PNFS            0x20000
d2edb4
 /*
d2edb4
  * All flags supported by the kernel before addition of the
d2edb4
  * export_features interface:
d2edb4
diff --git a/support/nfs/exports.c b/support/nfs/exports.c
d2edb4
index 5451ed7..9399a12 100644
d2edb4
--- a/support/nfs/exports.c
d2edb4
+++ b/support/nfs/exports.c
d2edb4
@@ -275,6 +275,7 @@ putexportent(struct exportent *ep)
d2edb4
 		"no_" : "");
d2edb4
 	if (ep->e_flags & NFSEXP_NOREADDIRPLUS)
d2edb4
 		fprintf(fp, "nordirplus,");
d2edb4
+	fprintf(fp, "%spnfs,", (ep->e_flags & NFSEXP_PNFS)? "" : "no_");
d2edb4
 	if (ep->e_flags & NFSEXP_FSID) {
d2edb4
 		fprintf(fp, "fsid=%d,", ep->e_fsid);
d2edb4
 	}
d2edb4
@@ -581,6 +582,10 @@ parseopts(char *cp, struct exportent *ep, int warn, int *had_subtree_opt_ptr)
d2edb4
 			clearflags(NFSEXP_NOACL, active, ep);
d2edb4
 		else if (strcmp(opt, "no_acl") == 0)
d2edb4
 			setflags(NFSEXP_NOACL, active, ep);
d2edb4
+		else if (!strcmp(opt, "pnfs"))
d2edb4
+			setflags(NFSEXP_PNFS, active, ep);
d2edb4
+		else if (!strcmp(opt, "no_pnfs"))
d2edb4
+			clearflags(NFSEXP_PNFS, active, ep);
d2edb4
 		else if (strncmp(opt, "anonuid=", 8) == 0) {
d2edb4
 			char *oe;
d2edb4
 			ep->e_anonuid = strtol(opt+8, &oe, 10);
d2edb4
diff --git a/systemd/Makefile.am b/systemd/Makefile.am
d2edb4
new file mode 100644
d2edb4
index 0000000..fbcabb1
d2edb4
--- /dev/null
d2edb4
+++ b/systemd/Makefile.am
d2edb4
@@ -0,0 +1,31 @@
d2edb4
+## Process this file with automake to produce Makefile.in
d2edb4
+
d2edb4
+MAINTAINERCLEANFILES = Makefile.in
d2edb4
+
d2edb4
+unit_files =  \
d2edb4
+    nfs-client.target \
d2edb4
+    \
d2edb4
+    auth-rpcgss-module.service \
d2edb4
+    nfs-blkmap.service \
d2edb4
+    nfs-config.service \
d2edb4
+    nfs-idmapd.service \
d2edb4
+    nfs-mountd.service \
d2edb4
+    nfs-server.service \
d2edb4
+    nfs-utils.service \
d2edb4
+    rpc-gssd.service \
d2edb4
+    rpc-statd-notify.service \
d2edb4
+    rpc-statd.service \
d2edb4
+    rpc-svcgssd.service \
d2edb4
+    \
d2edb4
+    proc-fs-nfsd.mount \
d2edb4
+    var-lib-nfs-rpc_pipefs.mount
d2edb4
+
d2edb4
+EXTRA_DIST = $(unit_files)
d2edb4
+
d2edb4
+unit_dir = /usr/lib/systemd/system
d2edb4
+
d2edb4
+if INSTALL_SYSTEMD
d2edb4
+install-data-hook: $(unit_files)
d2edb4
+	mkdir -p $(DESTDIR)/$(unitdir)
d2edb4
+	cp $(unit_files) $(DESTDIR)/$(unitdir)
d2edb4
+endif
d2edb4
diff --git a/systemd/README b/systemd/README
d2edb4
index a2a5f06..bbd7790 100644
d2edb4
--- a/systemd/README
d2edb4
+++ b/systemd/README
d2edb4
@@ -24,7 +24,7 @@ by a suitable 'preset' setting:
d2edb4
     is started by /usr/sbin/start-statd which mount.nfs will run
d2edb4
     if statd is needed.
d2edb4
 
d2edb4
- nfs-blkmap.target
d2edb4
+ nfs-blkmap.service
d2edb4
     If enabled, then blkmapd will be run when nfs-client.target is
d2edb4
     started.
d2edb4
 
d2edb4
diff --git a/systemd/nfs-blkmap.service b/systemd/nfs-blkmap.service
d2edb4
index f470e3d..ddbf4e9 100644
d2edb4
--- a/systemd/nfs-blkmap.service
d2edb4
+++ b/systemd/nfs-blkmap.service
d2edb4
@@ -5,12 +5,13 @@ Conflicts=umount.target
d2edb4
 After=var-lib-nfs-rpc_pipefs.mount
d2edb4
 Requires=var-lib-nfs-rpc_pipefs.mount
d2edb4
 
d2edb4
-Requisite=nfs-blkmap.target
d2edb4
-After=nfs-blkmap.target
d2edb4
-
d2edb4
 PartOf=nfs-utils.service
d2edb4
 
d2edb4
 [Service]
d2edb4
 Type=forking
d2edb4
 PIDFile=/var/run/blkmapd.pid
d2edb4
+EnvironmentFile=-/run/sysconfig/nfs-utils
d2edb4
 ExecStart=/usr/sbin/blkmapd $BLKMAPDARGS
d2edb4
+
d2edb4
+[Install]
d2edb4
+WantedBy=nfs-client.target
d2edb4
diff --git a/systemd/nfs-blkmap.target b/systemd/nfs-blkmap.target
d2edb4
deleted file mode 100644
d2edb4
index fbcc111..0000000
d2edb4
--- a/systemd/nfs-blkmap.target
d2edb4
+++ /dev/null
d2edb4
@@ -1,8 +0,0 @@
d2edb4
-[Unit]
d2edb4
-Description= PNFS blkmaping enablement.
d2edb4
-# If this target is enabled, then blkmapd will be started
d2edb4
-# as required.  If it is not enabled it won't.
d2edb4
-
d2edb4
-[Install]
d2edb4
-WantedBy=remote-fs.target
d2edb4
-WantedBy=multi-user.target
d2edb4
\ No newline at end of file
d2edb4
diff --git a/systemd/nfs-client.target b/systemd/nfs-client.target
d2edb4
index 9b792a3..8a8300a 100644
d2edb4
--- a/systemd/nfs-client.target
d2edb4
+++ b/systemd/nfs-client.target
d2edb4
@@ -5,8 +5,7 @@ Wants=remote-fs-pre.target
d2edb4
 
d2edb4
 # Note: we don't "Wants=rpc-statd.service" as "mount.nfs" will arrange to
d2edb4
 # start that on demand if needed.
d2edb4
-Wants=nfs-blkmap.service rpc-statd-notify.service
d2edb4
-After=nfs-blkmap.service
d2edb4
+Wants=rpc-statd-notify.service
d2edb4
 
d2edb4
 # GSS services dependencies and ordering
d2edb4
 Wants=auth-rpcgss-module.service
d2edb4
diff --git a/utils/blkmapd/device-discovery.c b/utils/blkmapd/device-discovery.c
d2edb4
index df4627e..b52afe2 100644
d2edb4
--- a/utils/blkmapd/device-discovery.c
d2edb4
+++ b/utils/blkmapd/device-discovery.c
d2edb4
@@ -77,16 +77,6 @@ struct bl_disk_path *bl_get_path(const char *filepath,
d2edb4
 	return tmp;
d2edb4
 }
d2edb4
 
d2edb4
-/* Check whether valid_path is a substring(partition) of path */
d2edb4
-int bl_is_partition(struct bl_disk_path *valid_path, struct bl_disk_path *path)
d2edb4
-{
d2edb4
-	if (!strncmp(valid_path->full_path, path->full_path,
d2edb4
-		     strlen(valid_path->full_path)))
d2edb4
-		return 1;
d2edb4
-
d2edb4
-	return 0;
d2edb4
-}
d2edb4
-
d2edb4
 /*
d2edb4
  * For multipath devices, devices state could be PASSIVE/ACTIVE/PSEUDO,
d2edb4
  * where PSEUDO > ACTIVE > PASSIVE. Device with highest state is used to
d2edb4
@@ -95,19 +85,13 @@ int bl_is_partition(struct bl_disk_path *valid_path, struct bl_disk_path *path)
d2edb4
  * If device-mapper multipath support is a must, pseudo devices should
d2edb4
  * exist for each multipath device. If not, active device path will be
d2edb4
  * chosen for device creation.
d2edb4
- * Treat partition as invalid path.
d2edb4
  */
d2edb4
-int bl_update_path(struct bl_disk_path *path, enum bl_path_state_e state,
d2edb4
-		   struct bl_disk *disk)
d2edb4
+int bl_update_path(enum bl_path_state_e state, struct bl_disk *disk)
d2edb4
 {
d2edb4
 	struct bl_disk_path *valid_path = disk->valid_path;
d2edb4
 
d2edb4
-	if (valid_path) {
d2edb4
-		if (valid_path->state >= state) {
d2edb4
-			if (bl_is_partition(valid_path, path))
d2edb4
-				return 0;
d2edb4
-		}
d2edb4
-	}
d2edb4
+	if (valid_path && valid_path->state >= state)
d2edb4
+		return 0;
d2edb4
 	return 1;
d2edb4
 }
d2edb4
 
d2edb4
@@ -164,15 +148,16 @@ void bl_add_disk(char *filepath)
d2edb4
 
d2edb4
 	dev = sb.st_rdev;
d2edb4
 	serial = bldev_read_serial(fd, filepath);
d2edb4
-	if (dm_is_dm_major(major(dev)))
d2edb4
+	if (!serial) {
d2edb4
+		BL_LOG_ERR("%s: no serial found for %s\n",
d2edb4
+				 __func__, filepath);
d2edb4
+		ap_state = BL_PATH_STATE_PASSIVE;
d2edb4
+	} else if (dm_is_dm_major(major(dev)))
d2edb4
 		ap_state = BL_PATH_STATE_PSEUDO;
d2edb4
 	else
d2edb4
 		ap_state = bldev_read_ap_state(fd);
d2edb4
 	close(fd);
d2edb4
 
d2edb4
-	if (ap_state != BL_PATH_STATE_ACTIVE)
d2edb4
-		return;
d2edb4
-
d2edb4
 	for (disk = visible_disk_list; disk != NULL; disk = disk->next) {
d2edb4
 		/* Already scanned or a partition?
d2edb4
 		 * XXX: if released each time, maybe not need to compare
d2edb4
@@ -216,7 +201,7 @@ void bl_add_disk(char *filepath)
d2edb4
 		path->next = disk->paths;
d2edb4
 		disk->paths = path;
d2edb4
 		/* check whether we need to update disk info */
d2edb4
-		if (bl_update_path(path, path->state, disk)) {
d2edb4
+		if (bl_update_path(path->state, disk)) {
d2edb4
 			disk->dev = dev;
d2edb4
 			disk->size = size;
d2edb4
 			disk->valid_path = path;
d2edb4
diff --git a/utils/blkmapd/device-inq.c b/utils/blkmapd/device-inq.c
d2edb4
index eabc70c..c5bf71f 100644
d2edb4
--- a/utils/blkmapd/device-inq.c
d2edb4
+++ b/utils/blkmapd/device-inq.c
d2edb4
@@ -179,6 +179,7 @@ struct bl_serial *bldev_read_serial(int fd, const char *filename)
d2edb4
 	char *buffer;
d2edb4
 	struct bl_dev_id *dev_root, *dev_id;
d2edb4
 	unsigned int pos, len, current_id = 0;
d2edb4
+	size_t devid_len = sizeof(struct bl_dev_id) - sizeof(unsigned char);
d2edb4
 
d2edb4
 	status = bldev_inquire_pages(fd, 0x83, &buffer);
d2edb4
 	if (status)
d2edb4
@@ -189,7 +190,11 @@ struct bl_serial *bldev_read_serial(int fd, const char *filename)
d2edb4
 	pos = 0;
d2edb4
 	current_id = 0;
d2edb4
 	len = dev_root->len;
d2edb4
-	while (pos < (len - sizeof(struct bl_dev_id) + sizeof(unsigned char))) {
d2edb4
+
d2edb4
+	if (len < devid_len)
d2edb4
+		goto out;
d2edb4
+
d2edb4
+	while (pos < (len - devid_len)) {
d2edb4
 		dev_id = (struct bl_dev_id *)&(dev_root->data[pos]);
d2edb4
 		if ((dev_id->ids & 0xf) < current_id)
d2edb4
 			continue;
d2edb4
@@ -221,8 +226,7 @@ struct bl_serial *bldev_read_serial(int fd, const char *filename)
d2edb4
 		}
d2edb4
 		if (current_id == 3)
d2edb4
 			break;
d2edb4
-		pos += (dev_id->len + sizeof(struct bl_dev_id) -
d2edb4
-			sizeof(unsigned char));
d2edb4
+		pos += (dev_id->len + devid_len);
d2edb4
 	}
d2edb4
  out:
d2edb4
 	if (!serial_out)
d2edb4
diff --git a/utils/blkmapd/device-process.c b/utils/blkmapd/device-process.c
d2edb4
index 5fe3dff..f53a616 100644
d2edb4
--- a/utils/blkmapd/device-process.c
d2edb4
+++ b/utils/blkmapd/device-process.c
d2edb4
@@ -181,6 +181,8 @@ static int map_sig_to_device(struct bl_sig *sig, struct bl_volume *vol)
d2edb4
 		/* FIXME: should we use better algorithm for disk scan? */
d2edb4
 		mapped = verify_sig(disk, sig);
d2edb4
 		if (mapped) {
d2edb4
+			BL_LOG_INFO("%s: using device %s\n",
d2edb4
+					__func__, disk->valid_path->full_path);
d2edb4
 			vol->param.bv_dev = disk->dev;
d2edb4
 			vol->bv_size = disk->size;
d2edb4
 			break;
d2edb4
diff --git a/utils/blkmapd/dm-device.c b/utils/blkmapd/dm-device.c
d2edb4
index 0f4f148..24ffcbf 100644
d2edb4
--- a/utils/blkmapd/dm-device.c
d2edb4
+++ b/utils/blkmapd/dm-device.c
d2edb4
@@ -400,6 +400,8 @@ uint64_t dm_device_create(struct bl_volume *vols, int num_vols)
d2edb4
 			}
d2edb4
 			dev = node->bv_vols[0]->param.bv_dev;
d2edb4
 			tmp = table->params;
d2edb4
+			BL_LOG_INFO("%s: major %lu minor %lu", __func__,
d2edb4
+					MAJOR(dev), MINOR(dev));
d2edb4
 			if (!dm_format_dev(tmp, DM_PARAMS_LEN,
d2edb4
 					   MAJOR(dev), MINOR(dev))) {
d2edb4
 				free(table);
d2edb4
@@ -459,6 +461,8 @@ uint64_t dm_device_create(struct bl_volume *vols, int num_vols)
d2edb4
 				strcpy(table->target_type, "linear");
d2edb4
 				tmp = table->params;
d2edb4
 				dev = node->bv_vols[i]->param.bv_dev;
d2edb4
+				BL_LOG_INFO("%s: major %lu minor %lu", __func__,
d2edb4
+					MAJOR(dev), MINOR(dev));
d2edb4
 				if (!dm_format_dev(tmp, DM_PARAMS_LEN,
d2edb4
 						   MAJOR(dev), MINOR(dev))) {
d2edb4
 					free(table);
d2edb4
diff --git a/utils/exportfs/exportfs.c b/utils/exportfs/exportfs.c
d2edb4
index 8391615..53e86ec 100644
d2edb4
--- a/utils/exportfs/exportfs.c
d2edb4
+++ b/utils/exportfs/exportfs.c
d2edb4
@@ -815,6 +815,8 @@ dump(int verbose, int export_format)
d2edb4
 				c = dumpopt(c, "insecure_locks");
d2edb4
 			if (ep->e_flags & NFSEXP_NOACL)
d2edb4
 				c = dumpopt(c, "no_acl");
d2edb4
+			if (ep->e_flags & NFSEXP_PNFS)
d2edb4
+				c = dumpopt(c, "pnfs");
d2edb4
 			if (ep->e_flags & NFSEXP_FSID)
d2edb4
 				c = dumpopt(c, "fsid=%d", ep->e_fsid);
d2edb4
 			if (ep->e_uuid)
d2edb4
diff --git a/utils/exportfs/exports.man b/utils/exportfs/exports.man
d2edb4
index 3d974d9..59358e6 100644
d2edb4
--- a/utils/exportfs/exports.man
d2edb4
+++ b/utils/exportfs/exports.man
d2edb4
@@ -378,6 +378,15 @@ If the client asks for alternative locations for the export point, it
d2edb4
 will be given this list of alternatives. (Note that actual replication
d2edb4
 of the filesystem must be handled elsewhere.)
d2edb4
 
d2edb4
+.TP
d2edb4
+.IR pnfs
d2edb4
+This option allows enables the use of pNFS extension if protocol level
d2edb4
+is NFSv4.1 or higher, and the filesystem supports pNFS exports.  With
d2edb4
+pNFS clients can bypass the server and perform I/O directly to storage
d2edb4
+devices. The default can be explicitly requested with the
d2edb4
+.I no_pnfs
d2edb4
+option.
d2edb4
+
d2edb4
 .SS User ID Mapping
d2edb4
 .PP
d2edb4
 .B nfsd