Blame SOURCES/nfs-utils-2.3.3-nfsrahead.patch

981ed7
diff --git a/.gitignore b/.gitignore
981ed7
index e97b31f5..e504d492 100644
981ed7
--- a/.gitignore
981ed7
+++ b/.gitignore
981ed7
@@ -60,6 +60,8 @@ utils/statd/statd
981ed7
 tools/locktest/testlk
981ed7
 tools/getiversion/getiversion
981ed7
 tools/nfsconf/nfsconf
981ed7
+tools/nfsrahead/nfsrahead
981ed7
+tools/nfsrahead/99-nfs_bdi.rules
981ed7
 support/export/mount.h
981ed7
 support/export/mount_clnt.c
981ed7
 support/export/mount_xdr.c
981ed7
diff --git a/configure.ac b/configure.ac
981ed7
index 6d464ac5..f462a645 100644
981ed7
--- a/configure.ac
981ed7
+++ b/configure.ac
981ed7
@@ -639,6 +639,7 @@ AC_CONFIG_FILES([
981ed7
 	tools/rpcgen/Makefile
981ed7
 	tools/mountstats/Makefile
981ed7
 	tools/nfs-iostat/Makefile
981ed7
+	tools/nfsrahead/Makefile
981ed7
 	tools/rpcctl/Makefile
981ed7
 	tools/nfsdclnts/Makefile
981ed7
 	tools/nfsconf/Makefile
981ed7
diff --git a/nfs.conf b/nfs.conf
981ed7
index 86ed7d53..30f9e109 100644
981ed7
--- a/nfs.conf
981ed7
+++ b/nfs.conf
981ed7
@@ -5,6 +5,10 @@
981ed7
 [general]
981ed7
 # pipefs-directory=/var/lib/nfs/rpc_pipefs
981ed7
 #
981ed7
+[nfsrahead]
981ed7
+# nfs=15000
981ed7
+# nfs4=16000
981ed7
+#
981ed7
 [exportfs]
981ed7
 # debug=0
981ed7
 #
981ed7
diff --git a/systemd/nfs.conf.man b/systemd/nfs.conf.man
981ed7
index f32c690b..ebbf28d0 100644
981ed7
--- a/systemd/nfs.conf.man
981ed7
+++ b/systemd/nfs.conf.man
981ed7
@@ -245,6 +245,17 @@ Only
981ed7
 .B debug=
981ed7
 is recognized.
981ed7
 
981ed7
+.TP
981ed7
+.B nfsrahead
981ed7
+Recognized values:
981ed7
+.BR nfs ,
981ed7
+.BR nfsv4 ,
981ed7
+.BR default .
981ed7
+
981ed7
+See
981ed7
+.BR nfsrahead (5)
981ed7
+for deatils.
981ed7
+
981ed7
 .SH FILES
981ed7
 .I /etc/nfs.conf
981ed7
 .SH SEE ALSO
981ed7
diff --git a/tools/Makefile.am b/tools/Makefile.am
981ed7
index c3feabbe..40c17c37 100644
981ed7
--- a/tools/Makefile.am
981ed7
+++ b/tools/Makefile.am
981ed7
@@ -12,6 +12,6 @@ if CONFIG_NFSDCLD
981ed7
 OPTDIRS += nfsdclddb
981ed7
 endif
981ed7
 
981ed7
-SUBDIRS = locktest rpcdebug nlmtest mountstats nfs-iostat rpcctl nfsdclnts $(OPTDIRS)
981ed7
+SUBDIRS = locktest rpcdebug nlmtest mountstats nfs-iostat rpcctl nfsdclnts nfsrahead $(OPTDIRS)
981ed7
 
981ed7
 MAINTAINERCLEANFILES = Makefile.in
981ed7
diff --git a/tools/nfsrahead/99-nfs.rules b/tools/nfsrahead/99-nfs.rules
981ed7
new file mode 100644
981ed7
index 00000000..c74914b2
981ed7
--- /dev/null
981ed7
+++ b/tools/nfsrahead/99-nfs.rules
981ed7
@@ -0,0 +1 @@
981ed7
+SUBSYSTEM=="bdi", ACTION=="add", PROGRAM="/usr/libexec/nfsrahead %k", ATTR{read_ahead_kb}="%c"
981ed7
diff --git a/tools/nfsrahead/99-nfs.rules.in b/tools/nfsrahead/99-nfs.rules.in
981ed7
new file mode 100644
981ed7
index 00000000..648813c5
981ed7
--- /dev/null
981ed7
+++ b/tools/nfsrahead/99-nfs.rules.in
981ed7
@@ -0,0 +1 @@
981ed7
+SUBSYSTEM=="bdi", ACTION=="add", PROGRAM="_libexecdir_/nfsrahead %k", ATTR{read_ahead_kb}="%c"
981ed7
diff --git a/tools/nfsrahead/Makefile.am b/tools/nfsrahead/Makefile.am
981ed7
new file mode 100644
981ed7
index 00000000..845ea0d5
981ed7
--- /dev/null
981ed7
+++ b/tools/nfsrahead/Makefile.am
981ed7
@@ -0,0 +1,16 @@
981ed7
+libexec_PROGRAMS = nfsrahead
981ed7
+nfsrahead_SOURCES = main.c
981ed7
+nfsrahead_LDFLAGS= -lmount
981ed7
+nfsrahead_LDADD = ../../support/nfs/libnfsconf.la
981ed7
+
981ed7
+man5_MANS = nfsrahead.man
981ed7
+EXTRA_DIST = $(man5_MANS)
981ed7
+
981ed7
+udev_rulesdir = /usr/lib/udev/rules.d/
981ed7
+udev_rules_DATA = 99-nfs.rules
981ed7
+
981ed7
+99-nfs.rules: 99-nfs.rules.in $(builddefs)
981ed7
+	$(SED) "s|_libexecdir_|@libexecdir@|g" 99-nfs.rules.in > $@
981ed7
+
981ed7
+clean-local:
981ed7
+	$(RM) 99-nfs.rules
981ed7
diff --git a/tools/nfsrahead/main.c b/tools/nfsrahead/main.c
981ed7
new file mode 100644
981ed7
index 00000000..c83c6f71
981ed7
--- /dev/null
981ed7
+++ b/tools/nfsrahead/main.c
981ed7
@@ -0,0 +1,192 @@
981ed7
+#include <stdio.h>
981ed7
+#include <string.h>
981ed7
+#include <stdlib.h>
981ed7
+#include <errno.h>
981ed7
+#include <unistd.h>
981ed7
+
981ed7
+#include <libmount/libmount.h>
981ed7
+#include <sys/sysmacros.h>
981ed7
+
981ed7
+#include "xlog.h"
981ed7
+#include "conffile.h"
981ed7
+
981ed7
+#ifndef MOUNTINFO_PATH
981ed7
+#define MOUNTINFO_PATH "/proc/self/mountinfo"
981ed7
+#endif
981ed7
+
981ed7
+#define CONF_NAME "nfsrahead"
981ed7
+#define NFS_DEFAULT_READAHEAD 128
981ed7
+
981ed7
+/* Device information from the system */
981ed7
+struct device_info {
981ed7
+	char *device_number;
981ed7
+	dev_t dev;
981ed7
+	char *mountpoint;
981ed7
+	char *fstype;
981ed7
+};
981ed7
+
981ed7
+/* Convert a string in the format n:m to a device number */
981ed7
+static int fill_device_number(struct device_info *info)
981ed7
+{
981ed7
+	char *s = strdup(info->device_number), *p;
981ed7
+	char *maj_s, *min_s;
981ed7
+	unsigned int maj, min;
981ed7
+	int err = -EINVAL;
981ed7
+
981ed7
+	maj_s = p = s;
981ed7
+	for ( ; *p != ':' && *p != '\0'; p++)
981ed7
+		;
981ed7
+
981ed7
+	if (*p == '\0')
981ed7
+		goto out_free;
981ed7
+
981ed7
+	err = 0;
981ed7
+	*p = '\0';
981ed7
+	min_s = p + 1;
981ed7
+
981ed7
+	maj = strtol(maj_s, NULL, 10);
981ed7
+	min = strtol(min_s, NULL, 10);
981ed7
+
981ed7
+	info->dev = makedev(maj, min);
981ed7
+out_free:
981ed7
+	free(s);
981ed7
+	return err;
981ed7
+}
981ed7
+
981ed7
+#define sfree(ptr) if (ptr) free(ptr)
981ed7
+
981ed7
+/* device_info maintenance */
981ed7
+static void init_device_info(struct device_info *di, const char *device_number)
981ed7
+{
981ed7
+	di->device_number = strdup(device_number);
981ed7
+	di->dev = 0;
981ed7
+	di->mountpoint = NULL;
981ed7
+	di->fstype = NULL;
981ed7
+}
981ed7
+
981ed7
+
981ed7
+static void free_device_info(struct device_info *di)
981ed7
+{
981ed7
+	sfree(di->mountpoint);
981ed7
+	sfree(di->fstype);
981ed7
+	sfree(di->device_number);
981ed7
+}
981ed7
+
981ed7
+static int get_mountinfo(const char *device_number, struct device_info *device_info, const char *mountinfo_path)
981ed7
+{
981ed7
+	int ret = 0;
981ed7
+	struct libmnt_table *mnttbl;
981ed7
+	struct libmnt_fs *fs;
981ed7
+	char *target;
981ed7
+
981ed7
+	init_device_info(device_info, device_number);
981ed7
+	if ((ret = fill_device_number(device_info)) < 0)
981ed7
+		goto out_free_device_info;
981ed7
+
981ed7
+	mnttbl = mnt_new_table();
981ed7
+
981ed7
+	if ((ret = mnt_table_parse_file(mnttbl, mountinfo_path)) < 0) {
981ed7
+		xlog(D_GENERAL, "Failed to parse %s\n", mountinfo_path);
981ed7
+		goto out_free_tbl;
981ed7
+	}
981ed7
+
981ed7
+	if ((fs = mnt_table_find_devno(mnttbl, device_info->dev, MNT_ITER_FORWARD)) == NULL) {
981ed7
+		ret = ENOENT;
981ed7
+		goto out_free_tbl;
981ed7
+	}
981ed7
+
981ed7
+	if ((target = (char *)mnt_fs_get_target(fs)) == NULL) {
981ed7
+		ret = ENOENT;
981ed7
+		goto out_free_fs;
981ed7
+	}
981ed7
+
981ed7
+	device_info->mountpoint = strdup(target);
981ed7
+	target = (char *)mnt_fs_get_fstype(fs);
981ed7
+	if (target)
981ed7
+		device_info->fstype = strdup(target);
981ed7
+
981ed7
+out_free_fs:
981ed7
+	mnt_free_fs(fs);
981ed7
+out_free_tbl:
981ed7
+	mnt_free_table(mnttbl);
981ed7
+out_free_device_info:
981ed7
+	free(device_info->device_number);
981ed7
+	device_info->device_number = NULL;
981ed7
+	return ret;
981ed7
+}
981ed7
+
981ed7
+static int get_device_info(const char *device_number, struct device_info *device_info)
981ed7
+{
981ed7
+	int ret = ENOENT;
981ed7
+	for (int retry_count = 0; retry_count < 10 && ret != 0; retry_count++)
981ed7
+		ret = get_mountinfo(device_number, device_info, MOUNTINFO_PATH);
981ed7
+
981ed7
+	return ret;
981ed7
+}
981ed7
+
981ed7
+static int conf_get_readahead(const char *kind) {
981ed7
+	int readahead = 0;
981ed7
+
981ed7
+	if((readahead = conf_get_num(CONF_NAME, kind, -1)) == -1)
981ed7
+		readahead = conf_get_num(CONF_NAME, "default", NFS_DEFAULT_READAHEAD);
981ed7
+	
981ed7
+	return readahead;
981ed7
+}
981ed7
+
981ed7
+int main(int argc, char **argv)
981ed7
+{
981ed7
+	int ret = 0, retry, opt;
981ed7
+	struct device_info device;
981ed7
+	unsigned int readahead = 128, log_level, log_stderr = 0;
981ed7
+
981ed7
+
981ed7
+	log_level = D_ALL & ~D_GENERAL;
981ed7
+	while((opt = getopt(argc, argv, "dF")) != -1) {
981ed7
+		switch (opt) {
981ed7
+		case 'd':
981ed7
+			log_level = D_ALL;
981ed7
+			break;
981ed7
+		case 'F':
981ed7
+			log_stderr = 1;
981ed7
+			break;
981ed7
+		}
981ed7
+	}
981ed7
+
981ed7
+	conf_init_file(NFS_CONFFILE);
981ed7
+
981ed7
+	xlog_stderr(log_stderr);
981ed7
+	xlog_syslog(~log_stderr);
981ed7
+	xlog_config(log_level, 1);
981ed7
+	xlog_open(CONF_NAME);
981ed7
+
981ed7
+	// xlog_err causes the system to exit
981ed7
+	if ((argc - optind) != 1)
981ed7
+		xlog_err("expected the device number of a BDI; is udev ok?");
981ed7
+
981ed7
+	for (retry = 0; retry <= 10; retry++ )
981ed7
+		if ((ret = get_device_info(argv[optind], &device)) == 0)
981ed7
+			break;
981ed7
+
981ed7
+	if (ret != 0) {
981ed7
+		xlog(D_GENERAL, "unable to find device %s\n", argv[optind]);
981ed7
+		goto out;
981ed7
+	}
981ed7
+
981ed7
+	if (strncmp("nfs", device.fstype, 3) != 0) {
981ed7
+		xlog(D_GENERAL,
981ed7
+			"not setting readahead for non supported fstype %s on device %s\n",
981ed7
+			device.fstype, argv[optind]);
981ed7
+		ret = -EINVAL;
981ed7
+		goto out;
981ed7
+	}
981ed7
+
981ed7
+	readahead = conf_get_readahead(device.fstype);
981ed7
+
981ed7
+	xlog(D_FAC7, "setting %s readahead to %d\n", device.mountpoint, readahead);
981ed7
+
981ed7
+	printf("%d\n", readahead);
981ed7
+
981ed7
+out:
981ed7
+	free_device_info(&device);
981ed7
+	return ret;
981ed7
+}
981ed7
diff --git a/tools/nfsrahead/nfsrahead.man b/tools/nfsrahead/nfsrahead.man
981ed7
new file mode 100644
981ed7
index 00000000..5488f633
981ed7
--- /dev/null
981ed7
+++ b/tools/nfsrahead/nfsrahead.man
981ed7
@@ -0,0 +1,72 @@
981ed7
+.\" Manpage for nfsrahead.
981ed7
+.nh
981ed7
+.ad l
981ed7
+.TH man 5 "08 Mar 2022" "1.0" "nfsrahead man page"
981ed7
+.SH NAME
981ed7
+
981ed7
+nfsrahead \- Configure the readahead for NFS mounts
981ed7
+
981ed7
+.SH SYNOPSIS
981ed7
+
981ed7
+nfsrahead [-F] [-d] <device>
981ed7
+
981ed7
+.SH DESCRIPTION
981ed7
+
981ed7
+\fInfsrahead\fR is a tool intended to be used with udev to set the \fIread_ahead_kb\fR parameter of NFS mounts, according to the configuration file (see \fICONFIGURATION\fR). \fIdevice\fR is the device number for the NFS backing device as provided by the kernel.
981ed7
+
981ed7
+.SH OPTIONS
981ed7
+.TP
981ed7
+.B -F
981ed7
+Send messages to 
981ed7
+.I stderr 
981ed7
+instead of
981ed7
+.I syslog
981ed7
+
981ed7
+.TP
981ed7
+.B -d
981ed7
+Increase the debugging level.
981ed7
+
981ed7
+.SH CONFIGURATION
981ed7
+.I nfsrahead
981ed7
+is configured in
981ed7
+.IR /etc/nfs.conf ,
981ed7
+in the section titled
981ed7
+.IR nfsrahead .
981ed7
+It accepts the following configurations.
981ed7
+
981ed7
+.TP
981ed7
+.B nfs=<value>
981ed7
+The readahead value applied to NFSv3 mounts.
981ed7
+
981ed7
+.TP
981ed7
+.B nfs4=<value>
981ed7
+The readahead value applied to NFSv4 mounts.
981ed7
+
981ed7
+.TP
981ed7
+.B default=<value>
981ed7
+The default configuration when none of the configurations above is set.
981ed7
+
981ed7
+.SH EXAMPLE CONFIGURATION
981ed7
+[nfsrahead]
981ed7
+.br
981ed7
+nfs=15000              # readahead of 15000 for NFSv3 mounts
981ed7
+.br
981ed7
+nfs4=16000             # readahead of 16000 for NFSv4 mounts
981ed7
+.br
981ed7
+default=128            # default is 128
981ed7
+
981ed7
+.SH SEE ALSO
981ed7
+
981ed7
+.BR mount.nfs (8),
981ed7
+.BR nfs (5),
981ed7
+.BR nfs.conf (5),
981ed7
+.BR udev (7),
981ed7
+.BR bcc-readahead (8)
981ed7
+
981ed7
+.SH BUGS
981ed7
+
981ed7
+No known bugs.
981ed7
+
981ed7
+.SH AUTHOR
981ed7
+
981ed7
+Thiago Rafael Becker <trbecker@gmail.com>
981ed7
diff --git a/utils/nfsidmap/nfsidmap.man b/utils/nfsidmap/nfsidmap.man
981ed7
index 2af16f31..1911c41b 100644
981ed7
--- a/utils/nfsidmap/nfsidmap.man
981ed7
+++ b/utils/nfsidmap/nfsidmap.man
981ed7
@@ -2,7 +2,7 @@
981ed7
 .\"@(#)nfsidmap(8) - The NFS idmapper upcall program
981ed7
 .\"
981ed7
 .\" Copyright (C) 2010 Bryan Schumaker <bjschuma@netapp.com>
981ed7
-.TH nfsidmap 5 "1 October 2010"
981ed7
+.TH nfsidmap 8 "1 October 2010"
981ed7
 .SH NAME
981ed7
 nfsidmap \- The NFS idmapper upcall program
981ed7
 .SH SYNOPSIS