c288c9
diff -uprN sysstat-10.1.5.orig/configure sysstat-10.1.5/configure
c288c9
--- sysstat-10.1.5.orig/configure	2013-03-13 15:28:25.000000000 +0100
c288c9
+++ sysstat-10.1.5/configure	2016-05-24 18:25:16.209668309 +0200
c288c9
@@ -5388,7 +5388,7 @@ ac_config_files="$ac_config_files man/io
c288c9
 	# File must be renamed
c288c9
 ac_config_files="$ac_config_files man/cifsiostat.1:man/cifsiostat.in"
c288c9
 	# File must be renamed
c288c9
-ac_config_files="$ac_config_files man/nfsiostat.1:man/nfsiostat.in"
c288c9
+ac_config_files="$ac_config_files man/nfsiostat-sysstat.1:man/nfsiostat-sysstat.in"
c288c9
 	# File must be renamed
c288c9
 ac_config_files="$ac_config_files contrib/isag/isag"
c288c9
  # Permissions must be changed
c288c9
@@ -6120,7 +6120,7 @@ do
c288c9
     "man/sysstat.5") CONFIG_FILES="$CONFIG_FILES man/sysstat.5:man/sysstat.in" ;;
c288c9
     "man/iostat.1") CONFIG_FILES="$CONFIG_FILES man/iostat.1:man/iostat.in" ;;
c288c9
     "man/cifsiostat.1") CONFIG_FILES="$CONFIG_FILES man/cifsiostat.1:man/cifsiostat.in" ;;
c288c9
-    "man/nfsiostat.1") CONFIG_FILES="$CONFIG_FILES man/nfsiostat.1:man/nfsiostat.in" ;;
c288c9
+    "man/nfsiostat-sysstat.1") CONFIG_FILES="$CONFIG_FILES man/nfsiostat-sysstat.1:man/nfsiostat-sysstat.in" ;;
c288c9
     "contrib/isag/isag") CONFIG_FILES="$CONFIG_FILES contrib/isag/isag" ;;
c288c9
     "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
c288c9
 
c288c9
diff -uprN sysstat-10.1.5.orig/configure.in sysstat-10.1.5/configure.in
c288c9
--- sysstat-10.1.5.orig/configure.in	2013-03-13 15:28:17.000000000 +0100
c288c9
+++ sysstat-10.1.5/configure.in	2016-05-24 18:25:16.209668309 +0200
c288c9
@@ -580,7 +580,7 @@ AC_CONFIG_FILES([man/sar.1:man/sar.in])
c288c9
 AC_CONFIG_FILES([man/sysstat.5:man/sysstat.in])	# File must be renamed
c288c9
 AC_CONFIG_FILES([man/iostat.1:man/iostat.in])	# File must be renamed
c288c9
 AC_CONFIG_FILES([man/cifsiostat.1:man/cifsiostat.in])	# File must be renamed
c288c9
-AC_CONFIG_FILES([man/nfsiostat.1:man/nfsiostat.in])	# File must be renamed
c288c9
+AC_CONFIG_FILES([man/nfsiostat-sysstat.1:man/nfsiostat-sysstat.in])	# File must be renamed
c288c9
 AC_CONFIG_FILES([contrib/isag/isag], [chmod +x contrib/isag/isag]) # Permissions must be changed
c288c9
 
c288c9
 AC_OUTPUT(Makefile)
c288c9
diff -uprN sysstat-10.1.5.orig/Makefile.in sysstat-10.1.5/Makefile.in
c288c9
--- sysstat-10.1.5.orig/Makefile.in	2016-05-24 18:33:48.438839524 +0200
c288c9
+++ sysstat-10.1.5/Makefile.in	2016-05-24 18:25:16.209668309 +0200
c288c9
@@ -160,7 +160,7 @@ NLSPOT= $(NLSPO:.po=.pot)
c288c9
 % : %.o
c288c9
 	$(CC) -o $@ $(CFLAGS) $^ $(LFLAGS)
c288c9
 
c288c9
-all: sadc sar sadf iostat mpstat pidstat nfsiostat cifsiostat locales
c288c9
+all: sadc sar sadf iostat mpstat pidstat nfsiostat-sysstat cifsiostat locales
c288c9
 
c288c9
 common.o: common.c version.h common.h ioconf.h sysconfig.h
c288c9
 
c288c9
@@ -229,9 +229,9 @@ mpstat.o: mpstat.c mpstat.h version.h co
c288c9
 
c288c9
 mpstat: mpstat.o librdstats.a libsyscom.a
c288c9
 
c288c9
-nfsiostat.o: nfsiostat.c nfsiostat.h version.h common.h
c288c9
+nfsiostat-sysstat.o: nfsiostat-sysstat.c nfsiostat-sysstat.h version.h common.h
c288c9
 
c288c9
-nfsiostat: nfsiostat.o librdstats.a libsyscom.a
c288c9
+nfsiostat-sysstat: nfsiostat-sysstat.o librdstats.a libsyscom.a
c288c9
 
c288c9
 cifsiostat.o: cifsiostat.c cifsiostat.h version.h common.h
c288c9
 
c288c9
@@ -273,8 +273,8 @@ ifeq ($(INSTALL_DOC),y)
c288c9
 	$(INSTALL_DATA) $(MANGRPARG) man/mpstat.1 $(DESTDIR)$(MAN1_DIR)
c288c9
 	rm -f $(DESTDIR)$(MAN1_DIR)/pidstat.1*
c288c9
 	$(INSTALL_DATA) $(MANGRPARG) man/pidstat.1 $(DESTDIR)$(MAN1_DIR)
c288c9
-	rm -f $(DESTDIR)$(MAN1_DIR)/nfsiostat.1*
c288c9
-	$(INSTALL_DATA) $(MANGRPARG) man/nfsiostat.1 $(DESTDIR)$(MAN1_DIR)
c288c9
+	rm -f $(DESTDIR)$(MAN1_DIR)/nfsiostat-sysstat.1*
c288c9
+	$(INSTALL_DATA) $(MANGRPARG) man/nfsiostat-sysstat.1 $(DESTDIR)$(MAN1_DIR)
c288c9
 	rm -f $(DESTDIR)$(MAN1_DIR)/cifsiostat.1*
c288c9
 	$(INSTALL_DATA) $(MANGRPARG) man/cifsiostat.1 $(DESTDIR)$(MAN1_DIR)
c288c9
 ifeq ($(INSTALL_ISAG),y)
c288c9
@@ -290,7 +290,7 @@ ifeq ($(COMPRESS_MANPG),y)
c288c9
 	$(ZIP) $(DESTDIR)$(MAN1_DIR)/iostat.1
c288c9
 	$(ZIP) $(DESTDIR)$(MAN1_DIR)/mpstat.1
c288c9
 	$(ZIP) $(DESTDIR)$(MAN1_DIR)/pidstat.1
c288c9
-	$(ZIP) $(DESTDIR)$(MAN1_DIR)/nfsiostat.1
c288c9
+	$(ZIP) $(DESTDIR)$(MAN1_DIR)/nfsiostat-sysstat.1
c288c9
 	$(ZIP) $(DESTDIR)$(MAN1_DIR)/cifsiostat.1
c288c9
 ifeq ($(INSTALL_ISAG),y)
c288c9
 	$(ZIP) $(DESTDIR)$(MAN1_DIR)/isag.1
c288c9
@@ -330,7 +330,7 @@ endif
c288c9
 	$(INSTALL_BIN) iostat $(DESTDIR)$(BIN_DIR)
c288c9
 	$(INSTALL_BIN) mpstat $(DESTDIR)$(BIN_DIR)
c288c9
 	$(INSTALL_BIN) pidstat $(DESTDIR)$(BIN_DIR)
c288c9
-	$(INSTALL_BIN) nfsiostat $(DESTDIR)$(BIN_DIR)
c288c9
+	$(INSTALL_BIN) nfsiostat-sysstat $(DESTDIR)$(BIN_DIR)
c288c9
 	$(INSTALL_BIN) cifsiostat $(DESTDIR)$(BIN_DIR)
c288c9
 ifeq ($(INSTALL_ISAG),y)
c288c9
 	$(INSTALL_BIN) contrib/isag/isag $(DESTDIR)$(BIN_DIR)
c288c9
@@ -397,7 +397,7 @@ ifeq ($(INSTALL_DOC),y)
c288c9
 	rm -f $(DESTDIR)$(MAN1_DIR)/iostat.1*
c288c9
 	rm -f $(DESTDIR)$(MAN1_DIR)/mpstat.1*
c288c9
 	rm -f $(DESTDIR)$(MAN1_DIR)/pidstat.1*
c288c9
-	rm -f $(DESTDIR)$(MAN1_DIR)/nfsiostat.1*
c288c9
+	rm -f $(DESTDIR)$(MAN1_DIR)/nfsiostat-sysstat.1*
c288c9
 	rm -f $(DESTDIR)$(MAN1_DIR)/cifsiostat.1*
c288c9
 ifeq ($(INSTALL_ISAG),y)
c288c9
 	rm -f $(DESTDIR)$(MAN1_DIR)/isag.1
c288c9
@@ -425,7 +425,7 @@ uninstall_base: uninstall_man uninstall_
c288c9
 	rm -f $(DESTDIR)$(BIN_DIR)/iostat
c288c9
 	rm -f $(DESTDIR)$(BIN_DIR)/mpstat
c288c9
 	rm -f $(DESTDIR)$(BIN_DIR)/pidstat
c288c9
-	rm -f $(DESTDIR)$(BIN_DIR)/nfsiostat
c288c9
+	rm -f $(DESTDIR)$(BIN_DIR)/nfsiostat-sysstat
c288c9
 	rm -f $(DESTDIR)$(BIN_DIR)/cifsiostat
c288c9
 ifeq ($(INSTALL_ISAG),y)
c288c9
 	rm -f $(DESTDIR)$(BIN_DIR)/isag
c288c9
@@ -487,7 +487,7 @@ po-files:
c288c9
 endif
c288c9
 
c288c9
 clean:
c288c9
-	rm -f sadc sar sadf iostat mpstat pidstat nfsiostat cifsiostat *.o *.a core TAGS
c288c9
+	rm -f sadc sar sadf iostat mpstat pidstat nfsiostat-sysstat cifsiostat *.o *.a core TAGS
c288c9
 	find nls -name "*.gmo" -exec rm -f {} \;
c288c9
 
c288c9
 almost-distclean: clean nls/sysstat.pot
c288c9
@@ -496,7 +496,7 @@ almost-distclean: clean nls/sysstat.pot
c288c9
 	rm -f cron/sysstat.cron.hourly cron/sysstat.crond.sample cron/sysstat.crond.sample.in
c288c9
 	rm -f contrib/isag/isag
c288c9
 	rm -f man/sa1.8 man/sa2.8 man/sadc.8 man/sadf.1 man/sar.1 man/iostat.1 man/sysstat.5
c288c9
-	rm -f man/cifsiostat.1 man/nfsiostat.1
c288c9
+	rm -f man/cifsiostat.1 man/nfsiostat-sysstat.1
c288c9
 	rm -f *.log config.status
c288c9
 	rm -rf autom4te.cache
c288c9
 	rm -f *.save *.old .*.swp data
c288c9
diff -uprN sysstat-10.1.5.orig/man/nfsiostat.in sysstat-10.1.5/man/nfsiostat.in
c288c9
--- sysstat-10.1.5.orig/man/nfsiostat.in	2012-07-13 08:48:55.000000000 +0200
c288c9
+++ sysstat-10.1.5/man/nfsiostat.in	1970-01-01 01:00:00.000000000 +0100
c288c9
@@ -1,175 +0,0 @@
c288c9
-.TH NFSIOSTAT 1 "JULY 2012" Linux "Linux User's Manual" -*- nroff -*-
c288c9
-.SH NAME
c288c9
-nfsiostat \- Report input/output statistics for network filesystems (NFS).
c288c9
-.SH SYNOPSIS
c288c9
-.ie 'yes'@WITH_DEBUG@' \{
c288c9
-.B nfsiostat [ -h ] [ -k | -m ] [ -t ] [ -V ] [ --debuginfo ] [
c288c9
-.I interval
c288c9
-.B [
c288c9
-.I count
c288c9
-.B ] ]
c288c9
-.\}
c288c9
-.el \{
c288c9
-.B nfsiostat [ -h ] [ -k | -m ] [ -t ] [ -V ] [
c288c9
-.I interval
c288c9
-.B [
c288c9
-.I count
c288c9
-.B ] ]
c288c9
-.\}
c288c9
-.SH DESCRIPTION
c288c9
-The
c288c9
-.B nfsiostat
c288c9
-command displays statistics about read and write operations
c288c9
-on NFS filesystems.
c288c9
-
c288c9
-The
c288c9
-.I interval
c288c9
-parameter specifies the amount of time in seconds between
c288c9
-each report. The first report contains statistics for the time since
c288c9
-system startup (boot). Each subsequent report contains statistics
c288c9
-collected during the interval since the previous report.
c288c9
-A report consists of an NFS header row followed by
c288c9
-a line of statistics for each network filesystem that is mounted.
c288c9
-The
c288c9
-.I count
c288c9
-parameter can be specified in conjunction with the
c288c9
-.I interval
c288c9
-parameter. If the
c288c9
-.I count
c288c9
-parameter is specified, the value of
c288c9
-.I count
c288c9
-determines the number of reports generated at
c288c9
-.I interval
c288c9
-seconds apart. If the
c288c9
-.I interval
c288c9
-parameter is specified without the
c288c9
-.I count
c288c9
-parameter, the
c288c9
-.B nfsiostat
c288c9
-command generates reports continuously.
c288c9
-
c288c9
-.SH REPORT
c288c9
-The Network Filesystem (NFS) report provides statistics for each mounted network filesystem.
c288c9
-Transfer rates are shown in 1K blocks by default, unless the environment
c288c9
-variable POSIXLY_CORRECT is set, in which case 512-byte blocks are used.
c288c9
-The report shows the following fields:
c288c9
-
c288c9
-.B Filesystem:
c288c9
-.RS
c288c9
-This columns shows the hostname of the NFS server followed by a colon and
c288c9
-by the directory name where the network filesystem is mounted.
c288c9
-
c288c9
-.RE
c288c9
-.B rBlk_nor/s (rkB_nor/s, rMB_nor)
c288c9
-.RS
c288c9
-Indicate the number of blocks (kilobytes, megabytes) read by applications
c288c9
-via the read(2) system
c288c9
-call interface. A block has a size of 512 bytes.
c288c9
-
c288c9
-.RE
c288c9
-.B wBlk_nor/s (wkB_nor/s, wMB_nor/s)
c288c9
-.RS
c288c9
-Indicate the number of blocks (kilobytes, megabytes) written by applications
c288c9
-via the write(2) system
c288c9
-call interface.
c288c9
-
c288c9
-.RE
c288c9
-.B rBlk_dir/s (rkB_dir/s, rMB_dir/s)
c288c9
-.RS
c288c9
-Indicate the number of blocks (kilobytes, megabytes) read from files
c288c9
-opened with the O_DIRECT flag.
c288c9
-
c288c9
-.RE
c288c9
-.B wBlk_dir/s (wkB_dir/s, wMB_dir/s)
c288c9
-.RS
c288c9
-Indicate the number of blocks (kilobytes, megabytes) written to files
c288c9
-opened with the O_DIRECT flag.
c288c9
-
c288c9
-.RE
c288c9
-.B rBlk_svr/s (rkB_svr/s, rMB_svr/s)
c288c9
-.RS
c288c9
-Indicate the number of blocks (kilobytes, megabytes) read from the server
c288c9
-by the NFS client via an NFS READ request.
c288c9
-
c288c9
-.RE
c288c9
-.B wBlk_svr/s (wkB_svr/s, wMB_svr/s)
c288c9
-.RS
c288c9
-Indicate the number of blocks (kilobytes, megabytes) written to the server
c288c9
-by the NFS client via an NFS WRITE request.
c288c9
-
c288c9
-.RE
c288c9
-.B ops/s
c288c9
-.RS
c288c9
-Indicate the number of operations that were issued to the filesystem per second.
c288c9
-
c288c9
-.RE
c288c9
-.B rops/s
c288c9
-.RS
c288c9
-Indicate the number of 'read' operations that were issued to the filesystem 
c288c9
-per second.
c288c9
-
c288c9
-.RE
c288c9
-.B wops/s
c288c9
-.RS
c288c9
-Indicate the number of 'write' operations that were issued to the filesystem
c288c9
-per second.
c288c9
-.RE
c288c9
-.RE
c288c9
-.SH OPTIONS
c288c9
-.if 'yes'@WITH_DEBUG@' \{
c288c9
-.IP --debuginfo
c288c9
-Print debug output to stderr.
c288c9
-.\}
c288c9
-.IP -h
c288c9
-Make the NFS report easier to read by a human.
c288c9
-.IP -k
c288c9
-Display statistics in kilobytes per second.
c288c9
-.IP -m
c288c9
-Display statistics in megabytes per second.
c288c9
-.IP -t
c288c9
-Print the time for each report displayed. The timestamp format may depend
c288c9
-on the value of the S_TIME_FORMAT environment variable (see below).
c288c9
-.IP -V
c288c9
-Print version number then exit.
c288c9
-
c288c9
-.SH ENVIRONMENT
c288c9
-The
c288c9
-.B nfsiostat
c288c9
-command takes into account the following environment variables:
c288c9
-
c288c9
-.IP S_TIME_FORMAT
c288c9
-If this variable exists and its value is
c288c9
-.BR ISO
c288c9
-then the current locale will be ignored when printing the date in the report
c288c9
-header. The
c288c9
-.B nfsiostat
c288c9
-command will use the ISO 8601 format (YYYY-MM-DD) instead.
c288c9
-The timestamp displayed with option -t will also be compliant with ISO 8601
c288c9
-format.
c288c9
-
c288c9
-.IP POSIXLY_CORRECT
c288c9
-When this variable is set, transfer rates are shown in 512-byte blocks instead
c288c9
-of the default 1K blocks.
c288c9
-
c288c9
-.SH BUG
c288c9
-.I /proc
c288c9
-filesystem must be mounted for
c288c9
-.B nfsiostat
c288c9
-to work.
c288c9
-
c288c9
-.SH FILE
c288c9
-.I /proc/self/mountstats
c288c9
-contains statistics for network filesystems.
c288c9
-.SH AUTHORS
c288c9
-Written by Ivana Varekova (varekova <at> redhat.com)
c288c9
-
c288c9
-Maintained by Sebastien Godard (sysstat <at> orange.fr)
c288c9
-.SH SEE ALSO
c288c9
-.BR sar (1),
c288c9
-.BR pidstat (1),
c288c9
-.BR mpstat (1),
c288c9
-.BR vmstat (8),
c288c9
-.BR iostat (1),
c288c9
-.BR cifsiostat (1)
c288c9
-
c288c9
-.I http://pagesperso-orange.fr/sebastien.godard/
c288c9
diff -uprN sysstat-10.1.5.orig/man/nfsiostat-sysstat.in sysstat-10.1.5/man/nfsiostat-sysstat.in
c288c9
--- sysstat-10.1.5.orig/man/nfsiostat-sysstat.in	1970-01-01 01:00:00.000000000 +0100
c288c9
+++ sysstat-10.1.5/man/nfsiostat-sysstat.in	2016-05-24 18:25:16.209668309 +0200
c288c9
@@ -0,0 +1,187 @@
c288c9
+.TH NFSIOSTAT-SYSSTAT 1 "JANUARY 2014" Linux "Linux User's Manual" -*- nroff -*-
c288c9
+.SH NAME
c288c9
+nfsiostat-sysstat (the nfsiostat command from the sysstat package) \- Report input/output statistics for network filesystems (NFS).
c288c9
+.SH SYNOPSIS
c288c9
+.ie 'yes'@WITH_DEBUG@' \{
c288c9
+.B nfsiostat-sysstat [ -h ] [ -k | -m ] [ -t ] [ -V ] [ --debuginfo ] [
c288c9
+.I interval
c288c9
+.B [
c288c9
+.I count
c288c9
+.B ] ]
c288c9
+.\}
c288c9
+.el \{
c288c9
+.B nfsiostat-sysstat [ -h ] [ -k | -m ] [ -t ] [ -V ] [
c288c9
+.I interval
c288c9
+.B [
c288c9
+.I count
c288c9
+.B ] ]
c288c9
+.\}
c288c9
+.SH DESCRIPTION
c288c9
+The
c288c9
+.B nfsiostat-sysstat
c288c9
+command displays statistics about read and write operations
c288c9
+on NFS filesystems.
c288c9
+
c288c9
+The
c288c9
+.I interval
c288c9
+parameter specifies the amount of time in seconds between
c288c9
+each report. The first report contains statistics for the time since
c288c9
+system startup (boot). Each subsequent report contains statistics
c288c9
+collected during the interval since the previous report.
c288c9
+A report consists of an NFS header row followed by
c288c9
+a line of statistics for each network filesystem that is mounted.
c288c9
+The
c288c9
+.I count
c288c9
+parameter can be specified in conjunction with the
c288c9
+.I interval
c288c9
+parameter. If the
c288c9
+.I count
c288c9
+parameter is specified, the value of
c288c9
+.I count
c288c9
+determines the number of reports generated at
c288c9
+.I interval
c288c9
+seconds apart. If the
c288c9
+.I interval
c288c9
+parameter is specified without the
c288c9
+.I count
c288c9
+parameter, the
c288c9
+.B nfsiostat-sysstat
c288c9
+command generates reports continuously.
c288c9
+
c288c9
+.SH REPORT
c288c9
+The Network Filesystem (NFS) report provides statistics for each mounted network filesystem.
c288c9
+Transfer rates are shown in 1K blocks by default, unless the environment
c288c9
+variable POSIXLY_CORRECT is set, in which case 512-byte blocks are used.
c288c9
+The report shows the following fields:
c288c9
+
c288c9
+.B Filesystem:
c288c9
+.RS
c288c9
+This columns shows the hostname of the NFS server followed by a colon and
c288c9
+by the directory name where the network filesystem is mounted.
c288c9
+
c288c9
+.RE
c288c9
+.B rBlk_nor/s (rkB_nor/s, rMB_nor)
c288c9
+.RS
c288c9
+Indicate the number of blocks (kilobytes, megabytes) read by applications
c288c9
+via the read(2) system
c288c9
+call interface. A block has a size of 512 bytes.
c288c9
+
c288c9
+.RE
c288c9
+.B wBlk_nor/s (wkB_nor/s, wMB_nor/s)
c288c9
+.RS
c288c9
+Indicate the number of blocks (kilobytes, megabytes) written by applications
c288c9
+via the write(2) system
c288c9
+call interface.
c288c9
+
c288c9
+.RE
c288c9
+.B rBlk_dir/s (rkB_dir/s, rMB_dir/s)
c288c9
+.RS
c288c9
+Indicate the number of blocks (kilobytes, megabytes) read from files
c288c9
+opened with the O_DIRECT flag.
c288c9
+
c288c9
+.RE
c288c9
+.B wBlk_dir/s (wkB_dir/s, wMB_dir/s)
c288c9
+.RS
c288c9
+Indicate the number of blocks (kilobytes, megabytes) written to files
c288c9
+opened with the O_DIRECT flag.
c288c9
+
c288c9
+.RE
c288c9
+.B rBlk_svr/s (rkB_svr/s, rMB_svr/s)
c288c9
+.RS
c288c9
+Indicate the number of blocks (kilobytes, megabytes) read from the server
c288c9
+by the NFS client via an NFS READ request.
c288c9
+
c288c9
+.RE
c288c9
+.B wBlk_svr/s (wkB_svr/s, wMB_svr/s)
c288c9
+.RS
c288c9
+Indicate the number of blocks (kilobytes, megabytes) written to the server
c288c9
+by the NFS client via an NFS WRITE request.
c288c9
+
c288c9
+.RE
c288c9
+.B ops/s
c288c9
+.RS
c288c9
+Indicate the number of operations that were issued to the filesystem per second.
c288c9
+
c288c9
+.RE
c288c9
+.B rops/s
c288c9
+.RS
c288c9
+Indicate the number of 'read' operations that were issued to the filesystem 
c288c9
+per second.
c288c9
+
c288c9
+.RE
c288c9
+.B wops/s
c288c9
+.RS
c288c9
+Indicate the number of 'write' operations that were issued to the filesystem
c288c9
+per second.
c288c9
+.RE
c288c9
+.RE
c288c9
+.SH OPTIONS
c288c9
+.if 'yes'@WITH_DEBUG@' \{
c288c9
+.IP --debuginfo
c288c9
+Print debug output to stderr.
c288c9
+.\}
c288c9
+.IP -h
c288c9
+Make the NFS report easier to read by a human.
c288c9
+.IP -k
c288c9
+Display statistics in kilobytes per second.
c288c9
+.IP -m
c288c9
+Display statistics in megabytes per second.
c288c9
+.IP -t
c288c9
+Print the time for each report displayed. The timestamp format may depend
c288c9
+on the value of the S_TIME_FORMAT environment variable (see below).
c288c9
+.IP -V
c288c9
+Print version number then exit.
c288c9
+
c288c9
+.SH ENVIRONMENT
c288c9
+The
c288c9
+.B nfsiostat-sysstat
c288c9
+command takes into account the following environment variables:
c288c9
+
c288c9
+.IP S_TIME_FORMAT
c288c9
+If this variable exists and its value is
c288c9
+.BR ISO
c288c9
+then the current locale will be ignored when printing the date in the report
c288c9
+header. The
c288c9
+.B nfsiostat-sysstat
c288c9
+command will use the ISO 8601 format (YYYY-MM-DD) instead.
c288c9
+The timestamp displayed with option -t will also be compliant with ISO 8601
c288c9
+format.
c288c9
+
c288c9
+.IP POSIXLY_CORRECT
c288c9
+When this variable is set, transfer rates are shown in 512-byte blocks instead
c288c9
+of the default 1K blocks.
c288c9
+
c288c9
+.SH BUG
c288c9
+.I /proc
c288c9
+filesystem must be mounted for
c288c9
+.B nfsiostat-sysstat
c288c9
+to work.
c288c9
+
c288c9
+.SH FILE
c288c9
+.I /proc/self/mountstats
c288c9
+contains statistics for network filesystems.
c288c9
+
c288c9
+.SH WARNING
c288c9
+The nfsiostat
c288c9
+command from the sysstat package (nfsiostat-sysstat) is now obsolete and is no longer maintained.
c288c9
+It will be removed in a future sysstat version.
c288c9
+Please use now the
c288c9
+.B nfsiostat
c288c9
+command from the
c288c9
+.I nfs-utils
c288c9
+package.
c288c9
+
c288c9
+.SH AUTHORS
c288c9
+Written by Ivana Varekova (varekova <at> redhat.com)
c288c9
+
c288c9
+Maintained by Sebastien Godard (sysstat <at> orange.fr)
c288c9
+.SH SEE ALSO
c288c9
+.BR nfsiostat (8),
c288c9
+.BR sar (1),
c288c9
+.BR pidstat (1),
c288c9
+.BR mpstat (1),
c288c9
+.BR vmstat (8),
c288c9
+.BR iostat (1),
c288c9
+.BR cifsiostat (1)
c288c9
+
c288c9
+.I http://pagesperso-orange.fr/sebastien.godard/
c288c9
diff -uprN sysstat-10.1.5.orig/nfsiostat.c sysstat-10.1.5/nfsiostat.c
c288c9
--- sysstat-10.1.5.orig/nfsiostat.c	2016-05-24 18:33:48.444839516 +0200
c288c9
+++ sysstat-10.1.5/nfsiostat.c	1970-01-01 01:00:00.000000000 +0100
c288c9
@@ -1,747 +0,0 @@
c288c9
-/*
c288c9
- * nfsiostat: Report NFS I/O statistics
c288c9
- * Copyright (C) 2010 Red Hat, Inc. All Rights Reserved
c288c9
- * Written by Ivana Varekova <varekova@redhat.com>
c288c9
- *
c288c9
- ***************************************************************************
c288c9
- * This program is free software; you can redistribute it and/or modify it *
c288c9
- * under the terms of the GNU General Public License as published  by  the *
c288c9
- * Free Software Foundation; either version 2 of the License, or (at  your *
c288c9
- * option) any later version.                                              *
c288c9
- *                                                                         *
c288c9
- * This program is distributed in the hope that it  will  be  useful,  but *
c288c9
- * WITHOUT ANY WARRANTY; without the implied warranty  of  MERCHANTABILITY *
c288c9
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License *
c288c9
- * for more details.                                                       *
c288c9
- *                                                                         *
c288c9
- * You should have received a copy of the GNU General Public License along *
c288c9
- * with this program; if not, write to the Free Software Foundation, Inc., *
c288c9
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA                   *
c288c9
- ***************************************************************************
c288c9
- */
c288c9
-
c288c9
-#include <stdio.h>
c288c9
-#include <string.h>
c288c9
-#include <stdlib.h>
c288c9
-#include <unistd.h>
c288c9
-#include <signal.h>
c288c9
-#include <sys/utsname.h>
c288c9
-
c288c9
-#include "version.h"
c288c9
-#include "nfsiostat.h"
c288c9
-#include "common.h"
c288c9
-
c288c9
-#ifdef USE_NLS
c288c9
-#include <locale.h>
c288c9
-#include <libintl.h>
c288c9
-#define _(string) gettext(string)
c288c9
-#else
c288c9
-#define _(string) (string)
c288c9
-#endif
c288c9
-
c288c9
-#define SCCSID "@(#)sysstat-" VERSION ": " __FILE__ " compiled " __DATE__ " " __TIME__
c288c9
-char *sccsid(void) { return (SCCSID); }
c288c9
-
c288c9
-unsigned long long uptime0[2] = {0, 0};
c288c9
-struct io_nfs_stats *st_ionfs[2];
c288c9
-struct io_hdr_stats *st_hdr_ionfs;
c288c9
-
c288c9
-int ionfs_nr = 0;	/* Nb of NFS mounted directories found */
c288c9
-int cpu_nr = 0;		/* Nb of processors on the machine */
c288c9
-int flags = 0;		/* Flag for common options and system state */
c288c9
-
c288c9
-long interval = 0;
c288c9
-char timestamp[64];
c288c9
-
c288c9
-struct sigaction alrm_act;
c288c9
-
c288c9
-/*
c288c9
- ***************************************************************************
c288c9
- * Print usage and exit.
c288c9
- *
c288c9
- * IN:
c288c9
- * @progname	Name of sysstat command.
c288c9
- ***************************************************************************
c288c9
- */
c288c9
-void usage(char *progname)
c288c9
-{
c288c9
-	fprintf(stderr, _("Usage: %s [ options ] [ <interval> [ <count> ] ]\n"),
c288c9
-		progname);
c288c9
-
c288c9
-#ifdef DEBUG
c288c9
-	fprintf(stderr, _("Options are:\n"
c288c9
-			  "[ -h ] [ -k | -m ] [ -t ] [ -V ] [ --debuginfo ]\n"));
c288c9
-#else
c288c9
-	fprintf(stderr, _("Options are:\n"
c288c9
-			  "[ -h ] [ -k | -m ] [ -t ] [ -V ]\n"));
c288c9
-#endif
c288c9
-	exit(1);
c288c9
-}
c288c9
-
c288c9
-/*
c288c9
- ***************************************************************************
c288c9
- * Set output unit. Unit will be kB/s unless POSIXLY_CORRECT
c288c9
- * environment variable has been set, in which case the output will be
c288c9
- * expressed in blocks/s.
c288c9
- ***************************************************************************
c288c9
- */
c288c9
-void set_output_unit(void)
c288c9
-{
c288c9
-	char *e;
c288c9
-
c288c9
-	if (DISPLAY_KILOBYTES(flags) || DISPLAY_MEGABYTES(flags))
c288c9
-		return;
c288c9
-
c288c9
-	/* Check POSIXLY_CORRECT environment variable */
c288c9
-	if ((e = getenv(ENV_POSIXLY_CORRECT)) == NULL) {
c288c9
-		/* Variable not set: Unit is kB/s and not blocks/s */
c288c9
-		flags |= I_D_KILOBYTES;
c288c9
-	}
c288c9
-}
c288c9
-
c288c9
-/*
c288c9
- ***************************************************************************
c288c9
- * SIGALRM signal handler.
c288c9
- *
c288c9
- * IN:
c288c9
- * @sig	Signal number.
c288c9
- ***************************************************************************
c288c9
- */
c288c9
-void alarm_handler(int sig)
c288c9
-{
c288c9
-	alarm(interval);
c288c9
-}
c288c9
-
c288c9
-/*
c288c9
- ***************************************************************************
c288c9
- * Find number of NFS-mounted points that are registered in
c288c9
- * /proc/self/mountstats.
c288c9
- *
c288c9
- * RETURNS:
c288c9
- * Number of NFS-mounted points.
c288c9
- ***************************************************************************
c288c9
- */
c288c9
-int get_nfs_mount_nr(void)
c288c9
-{
c288c9
-	FILE *fp;
c288c9
-	char line[8192];
c288c9
-	char type_name[10];
c288c9
-	unsigned int nfs = 0;
c288c9
-
c288c9
-	if ((fp = fopen(NFSMOUNTSTATS, "r")) == NULL)
c288c9
-		/* File non-existent */
c288c9
-		return 0;
c288c9
-
c288c9
-	while (fgets(line, 8192, fp) != NULL) {
c288c9
-
c288c9
-		if ((strstr(line, "mounted")) && (strstr(line, "on")) &&
c288c9
-		    (strstr(line, "with")) && (strstr(line, "fstype"))) {
c288c9
-
c288c9
-			sscanf(strstr(line, "fstype") + 6, "%9s", type_name);
c288c9
-			if ((!strncmp(type_name, "nfs", 3)) && (strncmp(type_name, "nfsd", 4))) {
c288c9
-				nfs ++;
c288c9
-			}
c288c9
-		}
c288c9
-	}
c288c9
-
c288c9
-	fclose(fp);
c288c9
-
c288c9
-	return nfs;
c288c9
-}
c288c9
-
c288c9
-/*
c288c9
- ***************************************************************************
c288c9
- * Set every nfs_io entry to inactive state (unregistered).
c288c9
- ***************************************************************************
c288c9
- */
c288c9
-void set_entries_inactive(void)
c288c9
-{
c288c9
-	int i;
c288c9
-	struct io_hdr_stats *shi = st_hdr_ionfs;
c288c9
-
c288c9
-	for (i = 0; i < ionfs_nr; i++, shi++) {
c288c9
-		shi->active = FALSE;
c288c9
-	}
c288c9
-}
c288c9
-
c288c9
-/*
c288c9
- ***************************************************************************
c288c9
- * Free inactive entries (mark them as unused).
c288c9
- ***************************************************************************
c288c9
- */
c288c9
-void free_inactive_entries(void)
c288c9
-{
c288c9
-	int i;
c288c9
-	struct io_hdr_stats *shi = st_hdr_ionfs;
c288c9
-
c288c9
-	for (i = 0; i < ionfs_nr; i++, shi++) {
c288c9
-		if (!shi->active) {
c288c9
-			shi->used = FALSE;
c288c9
-		}
c288c9
-	}
c288c9
-}
c288c9
-
c288c9
-/*
c288c9
- ***************************************************************************
c288c9
- * Allocate and init structures, according to system state.
c288c9
- ***************************************************************************
c288c9
- */
c288c9
-void io_sys_init(void)
c288c9
-{
c288c9
-	int i;
c288c9
-	
c288c9
-	/* How many processors on this machine? */
c288c9
-	cpu_nr = get_cpu_nr(~0);
c288c9
-
c288c9
-	/* Get number of NFS directories in /proc/self/mountstats */
c288c9
-	if ((ionfs_nr = get_nfs_mount_nr()) > 0) {
c288c9
-		ionfs_nr += NR_NFS_PREALLOC;
c288c9
-	}
c288c9
-	if ((st_hdr_ionfs = (struct io_hdr_stats *) calloc(ionfs_nr, IO_HDR_STATS_SIZE)) == NULL) {
c288c9
-		perror("malloc");
c288c9
-		exit(4);
c288c9
-	}
c288c9
-	
c288c9
-	/* Allocate structures for number of NFS directories found */
c288c9
-	for (i = 0; i < 2; i++) {
c288c9
-		if ((st_ionfs[i] =
c288c9
-		    (struct io_nfs_stats *) calloc(ionfs_nr, IO_NFS_STATS_SIZE)) == NULL) {
c288c9
-			perror("malloc");
c288c9
-			exit(4);
c288c9
-		}
c288c9
-	}
c288c9
-}
c288c9
-
c288c9
-/*
c288c9
- ***************************************************************************
c288c9
- * Free various structures.
c288c9
- ***************************************************************************
c288c9
-*/
c288c9
-void io_sys_free(void)
c288c9
-{
c288c9
-	int i;
c288c9
-
c288c9
-	/* Free I/O NFS directories structures */
c288c9
-	for (i = 0; i < 2; i++) {
c288c9
-
c288c9
-		if (st_ionfs[i]) {
c288c9
-			free(st_ionfs[i]);
c288c9
-		}
c288c9
-	}
c288c9
-	
c288c9
-	if (st_hdr_ionfs) {
c288c9
-		free(st_hdr_ionfs);
c288c9
-	}
c288c9
-}
c288c9
-
c288c9
-/*
c288c9
- ***************************************************************************
c288c9
- * Save stats for current NFS filesystem.
c288c9
- *
c288c9
- * IN:
c288c9
- * @name		Name of NFS filesystem.
c288c9
- * @curr		Index in array for current sample statistics.
c288c9
- * @st_io		Structure with NFS statistics to save.
c288c9
- * @ionfs_nr		Number of NFS filesystems.
c288c9
- * @st_hdr_ionfs	Pointer on structures describing an NFS filesystem.
c288c9
- *
c288c9
- * OUT:
c288c9
- * @st_hdr_ionfs	Pointer on structures describing an NFS filesystem.
c288c9
- ***************************************************************************
c288c9
- */
c288c9
-void save_stats(char *name, int curr, void *st_io)
c288c9
-{
c288c9
-	int i, j;
c288c9
-	struct io_hdr_stats *st_hdr_ionfs_i;
c288c9
-	struct io_nfs_stats *st_ionfs_i;
c288c9
-
c288c9
-	/* Look for NFS directory in data table */
c288c9
-	for (i = 0; i < ionfs_nr; i++) {
c288c9
-		st_hdr_ionfs_i = st_hdr_ionfs + i;
c288c9
-		if ((st_hdr_ionfs_i->used) &&
c288c9
-		    (!strcmp(st_hdr_ionfs_i->name, name))) {
c288c9
-			break;
c288c9
-		}
c288c9
-	}
c288c9
-
c288c9
-	if (i == ionfs_nr) {
c288c9
-		/*
c288c9
-		 * This is a new filesystem: Look for an unused entry to store it.
c288c9
-		 */
c288c9
-		for (i = 0; i < ionfs_nr; i++) {
c288c9
-			st_hdr_ionfs_i = st_hdr_ionfs + i;
c288c9
-			if (!st_hdr_ionfs_i->used) {
c288c9
-				/* Unused entry found... */
c288c9
-				st_hdr_ionfs_i->used = TRUE; /* Indicate it is now used */
c288c9
-				st_hdr_ionfs_i->active = TRUE;
c288c9
-
c288c9
-				strcpy(st_hdr_ionfs_i->name, name);
c288c9
-				st_ionfs_i = st_ionfs[curr] + i;
c288c9
-				memset(st_ionfs_i, 0, IO_NFS_STATS_SIZE);
c288c9
-				*st_ionfs_i = *((struct io_nfs_stats *) st_io);
c288c9
-				break;
c288c9
-			}
c288c9
-		}
c288c9
-		if (i == ionfs_nr) {
c288c9
-			/* All entries are used: The number has to be increased */
c288c9
-			ionfs_nr = ionfs_nr + 5;
c288c9
-
c288c9
-			/* Increase the size of st_hdr_ionfs buffer */
c288c9
-			if ((st_hdr_ionfs = (struct io_hdr_stats *)
c288c9
-				realloc(st_hdr_ionfs, ionfs_nr * IO_HDR_STATS_SIZE)) == NULL) {
c288c9
-				perror("malloc");
c288c9
-				exit(4);
c288c9
-			}
c288c9
-
c288c9
-			/* Set the new entries inactive */
c288c9
-			for (j = 0; j < 5; j++) {
c288c9
-				st_hdr_ionfs_i = st_hdr_ionfs + i + j;
c288c9
-				st_hdr_ionfs_i->used = FALSE;
c288c9
-				st_hdr_ionfs_i->active = FALSE;
c288c9
-			}
c288c9
-
c288c9
-			/* Increase the size of st_hdr_ionfs buffer */
c288c9
-			for (j = 0; j < 2; j++) {
c288c9
-				if ((st_ionfs[j] = (struct io_nfs_stats *)
c288c9
-					realloc(st_ionfs[j], ionfs_nr * IO_NFS_STATS_SIZE)) == NULL) {
c288c9
-					perror("malloc");
c288c9
-					exit(4);
c288c9
-				}
c288c9
-				memset(st_ionfs[j] + i, 0, 5 * IO_NFS_STATS_SIZE);
c288c9
-			}
c288c9
-
c288c9
-			/* Now i shows the first unused entry of the new block */
c288c9
-			st_hdr_ionfs_i = st_hdr_ionfs + i;
c288c9
-			st_hdr_ionfs_i->used = TRUE; /* Indicate it is now used */
c288c9
-			strcpy(st_hdr_ionfs_i->name, name);
c288c9
-			st_ionfs_i = st_ionfs[curr] + i;
c288c9
-			memset(st_ionfs_i, 0, IO_NFS_STATS_SIZE);
c288c9
-		}
c288c9
-	} else  {
c288c9
-		st_hdr_ionfs_i = st_hdr_ionfs + i;
c288c9
-		st_hdr_ionfs_i->used = TRUE;
c288c9
-		st_hdr_ionfs_i->active = TRUE;
c288c9
-		st_ionfs_i = st_ionfs[curr] + i;
c288c9
-		*st_ionfs_i = *((struct io_nfs_stats *) st_io);
c288c9
-	}
c288c9
-	/*
c288c9
-	 * else it was a new NFS directory
c288c9
-	 * but there was no free structure to store it.
c288c9
-	 */
c288c9
-}
c288c9
-
c288c9
-/*
c288c9
- ***************************************************************************
c288c9
- * Read NFS-mount directories stats from /proc/self/mountstats.
c288c9
- *
c288c9
- * IN:
c288c9
- * @curr	Index in array for current sample statistics.
c288c9
- ***************************************************************************
c288c9
- */
c288c9
-void read_nfs_stat(int curr)
c288c9
-{
c288c9
-	FILE *fp;
c288c9
-	int sw = 0;
c288c9
-	char line[256];
c288c9
-	char *xprt_line;
c288c9
-	char *mount_part;
c288c9
-	char nfs_name[MAX_NAME_LEN];
c288c9
-	char mount[10], on[10], prefix[10], aux[32];
c288c9
-	char operation[16];
c288c9
-	struct io_nfs_stats snfs;
c288c9
-	long int v1;
c288c9
-
c288c9
-	/* Every I/O NFS entry is potentially unregistered */
c288c9
-	set_entries_inactive();
c288c9
-
c288c9
-	if ((fp = fopen(NFSMOUNTSTATS, "r")) == NULL)
c288c9
-		return;
c288c9
-
c288c9
-	sprintf(aux, "%%%ds",
c288c9
-		MAX_NAME_LEN < 200 ? MAX_NAME_LEN-1 : 200);
c288c9
-
c288c9
-	while (fgets(line, 256, fp) != NULL) {
c288c9
-		/* Read NFS directory name */
c288c9
-		if (!strncmp(line, "device", 6)) {
c288c9
-			sw = 0;
c288c9
-			sscanf(line + 6, aux, nfs_name);
c288c9
-			mount_part = strchr(line + 7, ' ');
c288c9
-			if (mount_part != NULL) {
c288c9
-				sscanf(mount_part, "%9s %9s", mount, on);
c288c9
-				if ((!strncmp(mount, "mounted", 7)) && (!strncmp(on, "on", 2))) {
c288c9
-					sw = 1;
c288c9
-				}
c288c9
-			}
c288c9
-		}
c288c9
-
c288c9
-		sscanf(line, "%9s", prefix);
c288c9
-		if (sw && (!strncmp(prefix, "bytes:", 6))) {
c288c9
-			/* Read the stats for the last NFS-mounted directory */
c288c9
-			sscanf(strstr(line, "bytes:") + 6, "%llu %llu %llu %llu %llu %llu",
c288c9
-			       &snfs.rd_normal_bytes, &snfs.wr_normal_bytes,
c288c9
-			       &snfs.rd_direct_bytes, &snfs.wr_direct_bytes,
c288c9
-			       &snfs.rd_server_bytes, &snfs.wr_server_bytes);
c288c9
-			sw = 2;
c288c9
-		}
c288c9
-
c288c9
-		if ((sw == 2) && (!strncmp(prefix, "xprt:", 5))) {
c288c9
-			/*
c288c9
-			 * Read extended statistic for the last NFS-mounted directory
c288c9
-			 * - number of sent rpc requests.
c288c9
-			 */
c288c9
-			xprt_line = (strstr(line, "xprt:") + 6);
c288c9
-			/* udp, tcp or rdma data */
c288c9
-			if (!strncmp(xprt_line, "udp", 3)) {
c288c9
-				/* port bind_count sends recvs (bad_xids req_u bklog_u) */
c288c9
-				sscanf(strstr(xprt_line, "udp") + 4, "%*u %*u %lu",
c288c9
-				       &snfs.rpc_sends);
c288c9
-			}
c288c9
-			if (!strncmp(xprt_line, "tcp", 3)) {
c288c9
-				/*
c288c9
-				 * port bind_counter connect_count connect_time idle_time
c288c9
-				 * sends recvs (bad_xids req_u bklog_u)
c288c9
-				 */
c288c9
-				sscanf(strstr(xprt_line, "tcp") + 4,
c288c9
-				       "%*u %*u %*u %*u %*d %lu",
c288c9
-				       &snfs.rpc_sends);
c288c9
-			}
c288c9
-			if (!strncmp(xprt_line,"rdma", 4)) {
c288c9
-				/*
c288c9
-				 * 0(port) bind_count connect_count connect_time idle_time
c288c9
-				 * sends recvs (bad_xids req_u bklog_u...)
c288c9
-				 */
c288c9
-				sscanf(strstr(xprt_line, "rdma") + 5,
c288c9
-				       "%*u %*u %*u %*u %*d %lu",
c288c9
-				       &snfs.rpc_sends);
c288c9
-			}
c288c9
-			sw = 3;
c288c9
-		}
c288c9
-
c288c9
-		if ((sw == 3) && (!strncmp(prefix, "per-op", 6))) {
c288c9
-			sw = 4;
c288c9
-			while (sw == 4) {
c288c9
-				fgets(line, 256, fp);
c288c9
-				sscanf(line, "%15s %lu", operation, &v1;;
c288c9
-				if (!strncmp(operation, "READ:", 5)) {
c288c9
-					snfs.nfs_rops = v1;
c288c9
-				}
c288c9
-				else if (!strncmp(operation, "WRITE:", 6)) {
c288c9
-					snfs.nfs_wops = v1;
c288c9
-
c288c9
-					save_stats(nfs_name, curr, &snfs);
c288c9
-					sw = 0;
c288c9
-				}
c288c9
-			}
c288c9
-		}
c288c9
-	}
c288c9
-
c288c9
-	fclose(fp);
c288c9
-
c288c9
-	/* Free structures corresponding to unregistered filesystems */
c288c9
-	free_inactive_entries();
c288c9
-}
c288c9
-
c288c9
-/*
c288c9
- ***************************************************************************
c288c9
- * Display NFS stats header.
c288c9
- *
c288c9
- * OUT:
c288c9
- * @fctr	Conversion factor.
c288c9
- ***************************************************************************
c288c9
- */
c288c9
-void write_nfs_stat_header(int *fctr)
c288c9
-{
c288c9
-	printf("Filesystem:           ");
c288c9
-	if (DISPLAY_KILOBYTES(flags)) {
c288c9
-		printf("    rkB_nor/s    wkB_nor/s    rkB_dir/s    wkB_dir/s"
c288c9
-		       "    rkB_svr/s    wkB_svr/s");
c288c9
-		*fctr = 1024;
c288c9
-	}
c288c9
-	else if (DISPLAY_MEGABYTES(flags)) {
c288c9
-		printf("    rMB_nor/s    wMB_nor/s    rMB_dir/s    wMB_dir/s"
c288c9
-		       "    rMB_svr/s    wMB_svr/s");
c288c9
-		*fctr = 1024 * 1024;
c288c9
-	}
c288c9
-	else {
c288c9
-		printf("   rBlk_nor/s   wBlk_nor/s   rBlk_dir/s   wBlk_dir/s"
c288c9
-		       "   rBlk_svr/s   wBlk_svr/s");
c288c9
-		*fctr = 512;
c288c9
-	}
c288c9
-	printf("     ops/s    rops/s    wops/s\n");
c288c9
-}
c288c9
-
c288c9
-/*
c288c9
- ***************************************************************************
c288c9
- * Write NFS stats read from /proc/self/mountstats.
c288c9
- *
c288c9
- * IN:
c288c9
- * @curr	Index in array for current sample statistics.
c288c9
- * @itv		Interval of time.
c288c9
- * @fctr	Conversion factor.
c288c9
- * @shi		Structures describing the NFS filesystems.
c288c9
- * @ioi		Current sample statistics.
c288c9
- * @ioj		Previous sample statistics.
c288c9
- ***************************************************************************
c288c9
- */
c288c9
-void write_nfs_stat(int curr, unsigned long long itv, int fctr,
c288c9
-		    struct io_hdr_stats *shi, struct io_nfs_stats *ioni,
c288c9
-		    struct io_nfs_stats *ionj)
c288c9
-{
c288c9
-	if (DISPLAY_HUMAN_READ(flags)) {
c288c9
-		printf("%-22s\n%23s", shi->name, "");
c288c9
-	}
c288c9
-	else {
c288c9
-		printf("%-22s ", shi->name);
c288c9
-	}
c288c9
-	printf("%12.2f %12.2f %12.2f %12.2f %12.2f %12.2f %9.2f %9.2f %9.2f\n",
c288c9
-	       S_VALUE(ionj->rd_normal_bytes, ioni->rd_normal_bytes, itv) / fctr,
c288c9
-	       S_VALUE(ionj->wr_normal_bytes, ioni->wr_normal_bytes, itv) / fctr,
c288c9
-	       S_VALUE(ionj->rd_direct_bytes, ioni->rd_direct_bytes, itv) / fctr,
c288c9
-	       S_VALUE(ionj->wr_direct_bytes, ioni->wr_direct_bytes, itv) / fctr,
c288c9
-	       S_VALUE(ionj->rd_server_bytes, ioni->rd_server_bytes, itv) / fctr,
c288c9
-	       S_VALUE(ionj->wr_server_bytes, ioni->wr_server_bytes, itv) / fctr,
c288c9
-	       S_VALUE(ionj->rpc_sends, ioni->rpc_sends, itv),
c288c9
-	       S_VALUE(ionj->nfs_rops,  ioni->nfs_rops,  itv),
c288c9
-	       S_VALUE(ionj->nfs_wops,  ioni->nfs_wops,  itv));
c288c9
-}
c288c9
-
c288c9
-/*
c288c9
- ***************************************************************************
c288c9
- * Print everything now (stats and uptime).
c288c9
- *
c288c9
- * IN:
c288c9
- * @curr	Index in array for current sample statistics.
c288c9
- * @rectime	Current date and time.
c288c9
- ***************************************************************************
c288c9
- */
c288c9
-void write_stats(int curr, struct tm *rectime)
c288c9
-{
c288c9
-	int i, fctr = 1;
c288c9
-	unsigned long long itv;
c288c9
-	struct io_hdr_stats *shi;
c288c9
-	struct io_nfs_stats *ioni, *ionj;
c288c9
-
c288c9
-	/* Test stdout */
c288c9
-	TEST_STDOUT(STDOUT_FILENO);
c288c9
-
c288c9
-	/* Print time stamp */
c288c9
-	if (DISPLAY_TIMESTAMP(flags)) {
c288c9
-		if (DISPLAY_ISO(flags)) {
c288c9
-			strftime(timestamp, sizeof(timestamp), "%FT%T%z", rectime);
c288c9
-		}
c288c9
-		else {
c288c9
-			strftime(timestamp, sizeof(timestamp), "%x %X", rectime);
c288c9
-		}
c288c9
-		printf("%s\n", timestamp);
c288c9
-#ifdef DEBUG
c288c9
-		if (DISPLAY_DEBUG(flags)) {
c288c9
-			fprintf(stderr, "%s\n", timestamp);
c288c9
-		}
c288c9
-#endif
c288c9
-	}
c288c9
-
c288c9
-	/* Interval of time, reduced to one processor */
c288c9
-	itv = get_interval(uptime0[!curr], uptime0[curr]);
c288c9
-
c288c9
-	shi = st_hdr_ionfs;
c288c9
-
c288c9
-	/* Display NFS stats header */
c288c9
-	write_nfs_stat_header(&fctr);
c288c9
-
c288c9
-	for (i = 0; i < ionfs_nr; i++, shi++) {
c288c9
-		if (shi->used) {
c288c9
-			ioni = st_ionfs[curr]  + i;
c288c9
-			ionj = st_ionfs[!curr] + i;
c288c9
-#ifdef DEBUG
c288c9
-			if (DISPLAY_DEBUG(flags)) {
c288c9
-				/* Debug output */
c288c9
-				fprintf(stderr, "name=%s itv=%llu fctr=%d ioni{ rd_normal_bytes=%llu "
c288c9
-						"wr_normal_bytes=%llu rd_direct_bytes=%llu wr_direct_bytes=%llu rd_server_bytes=%llu "
c288c9
-						"wr_server_bytes=%llu rpc_sends=%lu nfs_rops=%lu nfs_wops=%lu }\n",
c288c9
-					shi->name, itv, fctr,
c288c9
-					ioni->rd_normal_bytes, ioni->wr_normal_bytes,
c288c9
-					ioni->rd_direct_bytes, ioni->wr_direct_bytes,
c288c9
-					ioni->rd_server_bytes, ioni->wr_server_bytes,
c288c9
-					ioni->rpc_sends,
c288c9
-					ioni->nfs_rops,        ioni->nfs_wops);
c288c9
-			}
c288c9
-#endif
c288c9
-			write_nfs_stat(curr, itv, fctr, shi, ioni, ionj);
c288c9
-		}
c288c9
-	}
c288c9
-	printf("\n");
c288c9
-}
c288c9
-
c288c9
-/*
c288c9
- ***************************************************************************
c288c9
- * Main loop: Read stats from the relevant sources and display them.
c288c9
- *
c288c9
- * IN:
c288c9
- * @count	Number of lines of stats to print.
c288c9
- * @rectime	Current date and time.
c288c9
- ***************************************************************************
c288c9
- */
c288c9
-void rw_io_stat_loop(long int count, struct tm *rectime)
c288c9
-{
c288c9
-	int curr = 1;
c288c9
-
c288c9
-	/* Don't buffer data if redirected to a pipe */
c288c9
-	setbuf(stdout, NULL);
c288c9
-	
c288c9
-	do {
c288c9
-		/* Read system uptime (reduced to one processor) */
c288c9
-		uptime0[curr] = 0;
c288c9
-		read_uptime(&(uptime0[curr]));
c288c9
-		if (!uptime0[curr])
c288c9
-			/* Cannot read system uptime (/proc/uptime doesn't exist) */
c288c9
-			exit(2);
c288c9
-
c288c9
-		/* Read NFS directories stats */
c288c9
-		read_nfs_stat(curr);
c288c9
-
c288c9
-		/* Get time */
c288c9
-		get_localtime(rectime, 0);
c288c9
-
c288c9
-		/* Print results */
c288c9
-		write_stats(curr, rectime);
c288c9
-
c288c9
-		if (count > 0) {
c288c9
-			count--;
c288c9
-		}
c288c9
-		if (count) {
c288c9
-			curr ^= 1;
c288c9
-			pause();
c288c9
-		}
c288c9
-	}
c288c9
-	while (count);
c288c9
-}
c288c9
-
c288c9
-/*
c288c9
- ***************************************************************************
c288c9
- * Main entry to the nfsiostat program.
c288c9
- ***************************************************************************
c288c9
- */
c288c9
-int main(int argc, char **argv)
c288c9
-{
c288c9
-	int it = 0;
c288c9
-	int opt = 1;
c288c9
-	int i;
c288c9
-	long count = 1;
c288c9
-	struct utsname header;
c288c9
-	struct tm rectime;
c288c9
-
c288c9
-#ifdef USE_NLS
c288c9
-	/* Init National Language Support */
c288c9
-	init_nls();
c288c9
-#endif
c288c9
-
c288c9
-	/* Get HZ */
c288c9
-	get_HZ();
c288c9
-
c288c9
-	/* Process args... */
c288c9
-	while (opt < argc) {
c288c9
-
c288c9
-#ifdef DEBUG
c288c9
-		if (!strcmp(argv[opt], "--debuginfo")) {
c288c9
-			flags |= I_D_DEBUG;
c288c9
-			opt++;
c288c9
-		} else
c288c9
-#endif
c288c9
-		if (!strncmp(argv[opt], "-", 1)) {
c288c9
-			for (i = 1; *(argv[opt] + i); i++) {
c288c9
-
c288c9
-				switch (*(argv[opt] + i)) {
c288c9
-
c288c9
-				case 'h':
c288c9
-					/* Display an easy-to-read NFS report */
c288c9
-					flags |= I_D_HUMAN_READ;
c288c9
-					break;
c288c9
-	
c288c9
-				case 'k':
c288c9
-					if (DISPLAY_MEGABYTES(flags)) {
c288c9
-						usage(argv[0]);
c288c9
-					}
c288c9
-					/* Display stats in kB/s */
c288c9
-					flags |= I_D_KILOBYTES;
c288c9
-					break;
c288c9
-
c288c9
-				case 'm':
c288c9
-					if (DISPLAY_KILOBYTES(flags)) {
c288c9
-						usage(argv[0]);
c288c9
-					}
c288c9
-					/* Display stats in MB/s */
c288c9
-					flags |= I_D_MEGABYTES;
c288c9
-					break;
c288c9
-
c288c9
-				case 't':
c288c9
-					/* Display timestamp */
c288c9
-					flags |= I_D_TIMESTAMP;
c288c9
-					break;
c288c9
-
c288c9
-				case 'V':
c288c9
-					/* Print version number and exit */
c288c9
-					print_version();
c288c9
-					break;
c288c9
-	
c288c9
-				default:
c288c9
-					usage(argv[0]);
c288c9
-				}
c288c9
-			}
c288c9
-			opt++;
c288c9
-		}
c288c9
-
c288c9
-		else if (!it) {
c288c9
-			interval = atol(argv[opt++]);
c288c9
-			if (interval < 0) {
c288c9
-				usage(argv[0]);
c288c9
-			}
c288c9
-			count = -1;
c288c9
-			it = 1;
c288c9
-		}
c288c9
-
c288c9
-		else if (it > 0) {
c288c9
-			count = atol(argv[opt++]);
c288c9
-			if ((count < 1) || !interval) {
c288c9
-				usage(argv[0]);
c288c9
-			}
c288c9
-			it = -1;
c288c9
-		}
c288c9
-		else {
c288c9
-			usage(argv[0]);
c288c9
-		}
c288c9
-	}
c288c9
-
c288c9
-	if (!interval) {
c288c9
-		count = 1;
c288c9
-	}
c288c9
-
c288c9
-	/* Select output unit (kB/s or blocks/s) */
c288c9
-	set_output_unit();
c288c9
-
c288c9
-	/* Init structures according to machine architecture */
c288c9
-	io_sys_init();
c288c9
-
c288c9
-	get_localtime(&rectime, 0);
c288c9
-
c288c9
-	/* Get system name, release number and hostname */
c288c9
-	uname(&header);
c288c9
-	if (print_gal_header(&rectime, header.sysname, header.release,
c288c9
-			     header.nodename, header.machine, cpu_nr)) {
c288c9
-		flags |= I_D_ISO;
c288c9
-	}
c288c9
-	printf("\n");
c288c9
-
c288c9
-	/* Set a handler for SIGALRM */
c288c9
-	memset(&alrm_act, 0, sizeof(alrm_act));
c288c9
-	alrm_act.sa_handler = (void *) alarm_handler;
c288c9
-	sigaction(SIGALRM, &alrm_act, NULL);
c288c9
-	alarm(interval);
c288c9
-
c288c9
-	/* Main loop */
c288c9
-	rw_io_stat_loop(count, &rectime);
c288c9
-
c288c9
-	/* Free structures */
c288c9
-	io_sys_free();
c288c9
-
c288c9
-	return 0;
c288c9
-}
c288c9
diff -uprN sysstat-10.1.5.orig/nfsiostat.h sysstat-10.1.5/nfsiostat.h
c288c9
--- sysstat-10.1.5.orig/nfsiostat.h	2013-03-23 17:31:46.000000000 +0100
c288c9
+++ sysstat-10.1.5/nfsiostat.h	1970-01-01 01:00:00.000000000 +0100
c288c9
@@ -1,57 +0,0 @@
c288c9
-/*
c288c9
- * nfsiostat: Report NFS I/O statistics
c288c9
- * Copyright (C) 2010 Red Hat, Inc. All Rights Reserved
c288c9
- * Written by Ivana Varekova <varekova@redhat.com>
c288c9
- */
c288c9
-
c288c9
-#ifndef _NFSIOSTAT_H
c288c9
-#define _NFSIOSTAT_H
c288c9
-
c288c9
-#include "common.h"
c288c9
-
c288c9
-#define NFSMOUNTSTATS  "/proc/self/mountstats"
c288c9
-
c288c9
-/* I_: iostat - D_: Display - F_: Flag */
c288c9
-#define I_D_TIMESTAMP		0x001
c288c9
-#define I_D_KILOBYTES		0x002
c288c9
-#define I_D_MEGABYTES		0x004
c288c9
-#define I_D_ISO			0x008
c288c9
-#define I_D_HUMAN_READ		0x010
c288c9
-#define I_D_DEBUG		0x020
c288c9
-
c288c9
-#define DISPLAY_TIMESTAMP(m)	(((m) & I_D_TIMESTAMP)     == I_D_TIMESTAMP)
c288c9
-#define DISPLAY_KILOBYTES(m)	(((m) & I_D_KILOBYTES)     == I_D_KILOBYTES)
c288c9
-#define DISPLAY_MEGABYTES(m)	(((m) & I_D_MEGABYTES)     == I_D_MEGABYTES)
c288c9
-#define DISPLAY_ISO(m)		(((m) & I_D_ISO)           == I_D_ISO)
c288c9
-#define DISPLAY_HUMAN_READ(m)	(((m) & I_D_HUMAN_READ)    == I_D_HUMAN_READ)
c288c9
-#define DISPLAY_DEBUG(m)	(((m) & I_D_DEBUG)         == I_D_DEBUG)
c288c9
-
c288c9
-/* Environment variable */
c288c9
-#define ENV_POSIXLY_CORRECT	"POSIXLY_CORRECT"
c288c9
-
c288c9
-/* Preallocation constats */
c288c9
-#define NR_NFS_PREALLOC	2
c288c9
-
c288c9
-struct io_nfs_stats {
c288c9
-	unsigned long long rd_normal_bytes	__attribute__ ((aligned (8)));
c288c9
-	unsigned long long wr_normal_bytes	__attribute__ ((packed));
c288c9
-	unsigned long long rd_direct_bytes	__attribute__ ((packed));
c288c9
-	unsigned long long wr_direct_bytes	__attribute__ ((packed));
c288c9
-	unsigned long long rd_server_bytes	__attribute__ ((packed));
c288c9
-	unsigned long long wr_server_bytes	__attribute__ ((packed));
c288c9
-	unsigned long rpc_sends			__attribute__ ((packed));
c288c9
-	unsigned long nfs_rops			__attribute__ ((packed));
c288c9
-	unsigned long nfs_wops			__attribute__ ((packed));
c288c9
-};
c288c9
-
c288c9
-#define IO_NFS_STATS_SIZE	(sizeof(struct io_nfs_stats))
c288c9
-
c288c9
-struct io_hdr_stats {
c288c9
-	unsigned int active		__attribute__ ((aligned (4)));
c288c9
-	unsigned int used		__attribute__ ((packed));
c288c9
-	char name[MAX_NAME_LEN];
c288c9
-};
c288c9
-
c288c9
-#define IO_HDR_STATS_SIZE	(sizeof(struct io_hdr_stats))
c288c9
-
c288c9
-#endif  /* _NFSIOSTAT_H */
c288c9
diff -uprN sysstat-10.1.5.orig/nfsiostat-sysstat.c sysstat-10.1.5/nfsiostat-sysstat.c
c288c9
--- sysstat-10.1.5.orig/nfsiostat-sysstat.c	1970-01-01 01:00:00.000000000 +0100
c288c9
+++ sysstat-10.1.5/nfsiostat-sysstat.c	2016-05-24 18:30:06.285162523 +0200
c288c9
@@ -0,0 +1,750 @@
c288c9
+/*
c288c9
+ * nfsiostat-sysstat: Report NFS I/O statistics
c288c9
+ * Copyright (C) 2010 Red Hat, Inc. All Rights Reserved
c288c9
+ * Written by Ivana Varekova <varekova@redhat.com>
c288c9
+ *
c288c9
+ ***************************************************************************
c288c9
+ * This program is free software; you can redistribute it and/or modify it *
c288c9
+ * under the terms of the GNU General Public License as published  by  the *
c288c9
+ * Free Software Foundation; either version 2 of the License, or (at  your *
c288c9
+ * option) any later version.                                              *
c288c9
+ *                                                                         *
c288c9
+ * This program is distributed in the hope that it  will  be  useful,  but *
c288c9
+ * WITHOUT ANY WARRANTY; without the implied warranty  of  MERCHANTABILITY *
c288c9
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License *
c288c9
+ * for more details.                                                       *
c288c9
+ *                                                                         *
c288c9
+ * You should have received a copy of the GNU General Public License along *
c288c9
+ * with this program; if not, write to the Free Software Foundation, Inc., *
c288c9
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA                   *
c288c9
+ ***************************************************************************
c288c9
+ */
c288c9
+
c288c9
+#include <stdio.h>
c288c9
+#include <string.h>
c288c9
+#include <stdlib.h>
c288c9
+#include <unistd.h>
c288c9
+#include <signal.h>
c288c9
+#include <sys/utsname.h>
c288c9
+
c288c9
+#include "version.h"
c288c9
+#include "nfsiostat-sysstat.h"
c288c9
+#include "common.h"
c288c9
+
c288c9
+#ifdef USE_NLS
c288c9
+#include <locale.h>
c288c9
+#include <libintl.h>
c288c9
+#define _(string) gettext(string)
c288c9
+#else
c288c9
+#define _(string) (string)
c288c9
+#endif
c288c9
+
c288c9
+#define SCCSID "@(#)sysstat-" VERSION ": " __FILE__ " compiled " __DATE__ " " __TIME__
c288c9
+char *sccsid(void) { return (SCCSID); }
c288c9
+
c288c9
+unsigned long long uptime0[2] = {0, 0};
c288c9
+struct io_nfs_stats *st_ionfs[2];
c288c9
+struct io_hdr_stats *st_hdr_ionfs;
c288c9
+
c288c9
+int ionfs_nr = 0;	/* Nb of NFS mounted directories found */
c288c9
+int cpu_nr = 0;		/* Nb of processors on the machine */
c288c9
+int flags = 0;		/* Flag for common options and system state */
c288c9
+
c288c9
+long interval = 0;
c288c9
+char timestamp[64];
c288c9
+
c288c9
+struct sigaction alrm_act;
c288c9
+
c288c9
+/*
c288c9
+ ***************************************************************************
c288c9
+ * Print usage and exit.
c288c9
+ *
c288c9
+ * IN:
c288c9
+ * @progname	Name of sysstat command.
c288c9
+ ***************************************************************************
c288c9
+ */
c288c9
+void usage(char *progname)
c288c9
+{
c288c9
+	fprintf(stderr, _("Usage: %s [ options ] [ <interval> [ <count> ] ]\n"),
c288c9
+		progname);
c288c9
+
c288c9
+#ifdef DEBUG
c288c9
+	fprintf(stderr, _("Options are:\n"
c288c9
+			  "[ -h ] [ -k | -m ] [ -t ] [ -V ] [ --debuginfo ]\n"));
c288c9
+#else
c288c9
+	fprintf(stderr, _("Options are:\n"
c288c9
+			  "[ -h ] [ -k | -m ] [ -t ] [ -V ]\n"));
c288c9
+#endif
c288c9
+	exit(1);
c288c9
+}
c288c9
+
c288c9
+/*
c288c9
+ ***************************************************************************
c288c9
+ * Set output unit. Unit will be kB/s unless POSIXLY_CORRECT
c288c9
+ * environment variable has been set, in which case the output will be
c288c9
+ * expressed in blocks/s.
c288c9
+ ***************************************************************************
c288c9
+ */
c288c9
+void set_output_unit(void)
c288c9
+{
c288c9
+	char *e;
c288c9
+
c288c9
+	if (DISPLAY_KILOBYTES(flags) || DISPLAY_MEGABYTES(flags))
c288c9
+		return;
c288c9
+
c288c9
+	/* Check POSIXLY_CORRECT environment variable */
c288c9
+	if ((e = getenv(ENV_POSIXLY_CORRECT)) == NULL) {
c288c9
+		/* Variable not set: Unit is kB/s and not blocks/s */
c288c9
+		flags |= I_D_KILOBYTES;
c288c9
+	}
c288c9
+}
c288c9
+
c288c9
+/*
c288c9
+ ***************************************************************************
c288c9
+ * SIGALRM signal handler.
c288c9
+ *
c288c9
+ * IN:
c288c9
+ * @sig	Signal number.
c288c9
+ ***************************************************************************
c288c9
+ */
c288c9
+void alarm_handler(int sig)
c288c9
+{
c288c9
+	alarm(interval);
c288c9
+}
c288c9
+
c288c9
+/*
c288c9
+ ***************************************************************************
c288c9
+ * Find number of NFS-mounted points that are registered in
c288c9
+ * /proc/self/mountstats.
c288c9
+ *
c288c9
+ * RETURNS:
c288c9
+ * Number of NFS-mounted points.
c288c9
+ ***************************************************************************
c288c9
+ */
c288c9
+int get_nfs_mount_nr(void)
c288c9
+{
c288c9
+	FILE *fp;
c288c9
+	char line[8192];
c288c9
+	char type_name[10];
c288c9
+	unsigned int nfs = 0;
c288c9
+
c288c9
+	if ((fp = fopen(NFSMOUNTSTATS, "r")) == NULL)
c288c9
+		/* File non-existent */
c288c9
+		return 0;
c288c9
+
c288c9
+	while (fgets(line, 8192, fp) != NULL) {
c288c9
+
c288c9
+		if ((strstr(line, "mounted")) && (strstr(line, "on")) &&
c288c9
+		    (strstr(line, "with")) && (strstr(line, "fstype"))) {
c288c9
+
c288c9
+			sscanf(strstr(line, "fstype") + 6, "%9s", type_name);
c288c9
+			if ((!strncmp(type_name, "nfs", 3)) && (strncmp(type_name, "nfsd", 4))) {
c288c9
+				nfs ++;
c288c9
+			}
c288c9
+		}
c288c9
+	}
c288c9
+
c288c9
+	fclose(fp);
c288c9
+
c288c9
+	return nfs;
c288c9
+}
c288c9
+
c288c9
+/*
c288c9
+ ***************************************************************************
c288c9
+ * Set every nfs_io entry to inactive state (unregistered).
c288c9
+ ***************************************************************************
c288c9
+ */
c288c9
+void set_entries_inactive(void)
c288c9
+{
c288c9
+	int i;
c288c9
+	struct io_hdr_stats *shi = st_hdr_ionfs;
c288c9
+
c288c9
+	for (i = 0; i < ionfs_nr; i++, shi++) {
c288c9
+		shi->active = FALSE;
c288c9
+	}
c288c9
+}
c288c9
+
c288c9
+/*
c288c9
+ ***************************************************************************
c288c9
+ * Free inactive entries (mark them as unused).
c288c9
+ ***************************************************************************
c288c9
+ */
c288c9
+void free_inactive_entries(void)
c288c9
+{
c288c9
+	int i;
c288c9
+	struct io_hdr_stats *shi = st_hdr_ionfs;
c288c9
+
c288c9
+	for (i = 0; i < ionfs_nr; i++, shi++) {
c288c9
+		if (!shi->active) {
c288c9
+			shi->used = FALSE;
c288c9
+		}
c288c9
+	}
c288c9
+}
c288c9
+
c288c9
+/*
c288c9
+ ***************************************************************************
c288c9
+ * Allocate and init structures, according to system state.
c288c9
+ ***************************************************************************
c288c9
+ */
c288c9
+void io_sys_init(void)
c288c9
+{
c288c9
+	int i;
c288c9
+	
c288c9
+	/* How many processors on this machine? */
c288c9
+	cpu_nr = get_cpu_nr(~0);
c288c9
+
c288c9
+	/* Get number of NFS directories in /proc/self/mountstats */
c288c9
+	if ((ionfs_nr = get_nfs_mount_nr()) > 0) {
c288c9
+		ionfs_nr += NR_NFS_PREALLOC;
c288c9
+	}
c288c9
+	if ((st_hdr_ionfs = (struct io_hdr_stats *) calloc(ionfs_nr, IO_HDR_STATS_SIZE)) == NULL) {
c288c9
+		perror("malloc");
c288c9
+		exit(4);
c288c9
+	}
c288c9
+	
c288c9
+	/* Allocate structures for number of NFS directories found */
c288c9
+	for (i = 0; i < 2; i++) {
c288c9
+		if ((st_ionfs[i] =
c288c9
+		    (struct io_nfs_stats *) calloc(ionfs_nr, IO_NFS_STATS_SIZE)) == NULL) {
c288c9
+			perror("malloc");
c288c9
+			exit(4);
c288c9
+		}
c288c9
+	}
c288c9
+}
c288c9
+
c288c9
+/*
c288c9
+ ***************************************************************************
c288c9
+ * Free various structures.
c288c9
+ ***************************************************************************
c288c9
+*/
c288c9
+void io_sys_free(void)
c288c9
+{
c288c9
+	int i;
c288c9
+
c288c9
+	/* Free I/O NFS directories structures */
c288c9
+	for (i = 0; i < 2; i++) {
c288c9
+
c288c9
+		if (st_ionfs[i]) {
c288c9
+			free(st_ionfs[i]);
c288c9
+		}
c288c9
+	}
c288c9
+	
c288c9
+	if (st_hdr_ionfs) {
c288c9
+		free(st_hdr_ionfs);
c288c9
+	}
c288c9
+}
c288c9
+
c288c9
+/*
c288c9
+ ***************************************************************************
c288c9
+ * Save stats for current NFS filesystem.
c288c9
+ *
c288c9
+ * IN:
c288c9
+ * @name		Name of NFS filesystem.
c288c9
+ * @curr		Index in array for current sample statistics.
c288c9
+ * @st_io		Structure with NFS statistics to save.
c288c9
+ * @ionfs_nr		Number of NFS filesystems.
c288c9
+ * @st_hdr_ionfs	Pointer on structures describing an NFS filesystem.
c288c9
+ *
c288c9
+ * OUT:
c288c9
+ * @st_hdr_ionfs	Pointer on structures describing an NFS filesystem.
c288c9
+ ***************************************************************************
c288c9
+ */
c288c9
+void save_stats(char *name, int curr, void *st_io)
c288c9
+{
c288c9
+	int i, j;
c288c9
+	struct io_hdr_stats *st_hdr_ionfs_i;
c288c9
+	struct io_nfs_stats *st_ionfs_i;
c288c9
+
c288c9
+	/* Look for NFS directory in data table */
c288c9
+	for (i = 0; i < ionfs_nr; i++) {
c288c9
+		st_hdr_ionfs_i = st_hdr_ionfs + i;
c288c9
+		if ((st_hdr_ionfs_i->used) &&
c288c9
+		    (!strcmp(st_hdr_ionfs_i->name, name))) {
c288c9
+			break;
c288c9
+		}
c288c9
+	}
c288c9
+
c288c9
+	if (i == ionfs_nr) {
c288c9
+		/*
c288c9
+		 * This is a new filesystem: Look for an unused entry to store it.
c288c9
+		 */
c288c9
+		for (i = 0; i < ionfs_nr; i++) {
c288c9
+			st_hdr_ionfs_i = st_hdr_ionfs + i;
c288c9
+			if (!st_hdr_ionfs_i->used) {
c288c9
+				/* Unused entry found... */
c288c9
+				st_hdr_ionfs_i->used = TRUE; /* Indicate it is now used */
c288c9
+				st_hdr_ionfs_i->active = TRUE;
c288c9
+
c288c9
+				strncpy(st_hdr_ionfs_i->name, name, MAX_NAME_LEN - 1);
c288c9
+				st_hdr_ionfs_i->name[MAX_NAME_LEN - 1] = '\0';
c288c9
+				st_ionfs_i = st_ionfs[curr] + i;
c288c9
+				memset(st_ionfs_i, 0, IO_NFS_STATS_SIZE);
c288c9
+				*st_ionfs_i = *((struct io_nfs_stats *) st_io);
c288c9
+				break;
c288c9
+			}
c288c9
+		}
c288c9
+		if (i == ionfs_nr) {
c288c9
+			/* All entries are used: The number has to be increased */
c288c9
+			ionfs_nr = ionfs_nr + 5;
c288c9
+
c288c9
+			/* Increase the size of st_hdr_ionfs buffer */
c288c9
+			if ((st_hdr_ionfs = (struct io_hdr_stats *)
c288c9
+				realloc(st_hdr_ionfs, ionfs_nr * IO_HDR_STATS_SIZE)) == NULL) {
c288c9
+				perror("malloc");
c288c9
+				exit(4);
c288c9
+			}
c288c9
+
c288c9
+			/* Set the new entries inactive */
c288c9
+			for (j = 0; j < 5; j++) {
c288c9
+				st_hdr_ionfs_i = st_hdr_ionfs + i + j;
c288c9
+				st_hdr_ionfs_i->used = FALSE;
c288c9
+				st_hdr_ionfs_i->active = FALSE;
c288c9
+			}
c288c9
+
c288c9
+			/* Increase the size of st_hdr_ionfs buffer */
c288c9
+			for (j = 0; j < 2; j++) {
c288c9
+				if ((st_ionfs[j] = (struct io_nfs_stats *)
c288c9
+					realloc(st_ionfs[j], ionfs_nr * IO_NFS_STATS_SIZE)) == NULL) {
c288c9
+					perror("malloc");
c288c9
+					exit(4);
c288c9
+				}
c288c9
+				memset(st_ionfs[j] + i, 0, 5 * IO_NFS_STATS_SIZE);
c288c9
+			}
c288c9
+
c288c9
+			/* Now i shows the first unused entry of the new block */
c288c9
+			st_hdr_ionfs_i = st_hdr_ionfs + i;
c288c9
+			st_hdr_ionfs_i->used = TRUE; /* Indicate it is now used */
c288c9
+			strncpy(st_hdr_ionfs_i->name, name, MAX_NAME_LEN - 1);
c288c9
+			st_hdr_ionfs_i->name[MAX_NAME_LEN - 1] = '\0';
c288c9
+			st_ionfs_i = st_ionfs[curr] + i;
c288c9
+			memset(st_ionfs_i, 0, IO_NFS_STATS_SIZE);
c288c9
+		}
c288c9
+	} else  {
c288c9
+		st_hdr_ionfs_i = st_hdr_ionfs + i;
c288c9
+		st_hdr_ionfs_i->used = TRUE;
c288c9
+		st_hdr_ionfs_i->active = TRUE;
c288c9
+		st_ionfs_i = st_ionfs[curr] + i;
c288c9
+		*st_ionfs_i = *((struct io_nfs_stats *) st_io);
c288c9
+	}
c288c9
+	/*
c288c9
+	 * else it was a new NFS directory
c288c9
+	 * but there was no free structure to store it.
c288c9
+	 */
c288c9
+}
c288c9
+
c288c9
+/*
c288c9
+ ***************************************************************************
c288c9
+ * Read NFS-mount directories stats from /proc/self/mountstats.
c288c9
+ *
c288c9
+ * IN:
c288c9
+ * @curr	Index in array for current sample statistics.
c288c9
+ ***************************************************************************
c288c9
+ */
c288c9
+void read_nfs_stat(int curr)
c288c9
+{
c288c9
+	FILE *fp;
c288c9
+	int sw = 0;
c288c9
+	char line[256];
c288c9
+	char *xprt_line;
c288c9
+	char *mount_part;
c288c9
+	char nfs_name[MAX_NAME_LEN];
c288c9
+	char mount[10], on[10], prefix[10], aux[32];
c288c9
+	char operation[16];
c288c9
+	struct io_nfs_stats snfs;
c288c9
+	long int v1;
c288c9
+
c288c9
+	/* Every I/O NFS entry is potentially unregistered */
c288c9
+	set_entries_inactive();
c288c9
+
c288c9
+	if ((fp = fopen(NFSMOUNTSTATS, "r")) == NULL)
c288c9
+		return;
c288c9
+
c288c9
+	sprintf(aux, "%%%ds",
c288c9
+		MAX_NAME_LEN < 200 ? MAX_NAME_LEN-1 : 200);
c288c9
+
c288c9
+	while (fgets(line, 256, fp) != NULL) {
c288c9
+		/* Read NFS directory name */
c288c9
+		if (!strncmp(line, "device", 6)) {
c288c9
+			sw = 0;
c288c9
+			sscanf(line + 6, aux, nfs_name);
c288c9
+			mount_part = strchr(line + 7, ' ');
c288c9
+			if (mount_part != NULL) {
c288c9
+				sscanf(mount_part, "%9s %9s", mount, on);
c288c9
+				if ((!strncmp(mount, "mounted", 7)) && (!strncmp(on, "on", 2))) {
c288c9
+					sw = 1;
c288c9
+				}
c288c9
+			}
c288c9
+		}
c288c9
+
c288c9
+		sscanf(line, "%9s", prefix);
c288c9
+		if (sw && (!strncmp(prefix, "bytes:", 6))) {
c288c9
+			/* Read the stats for the last NFS-mounted directory */
c288c9
+			sscanf(strstr(line, "bytes:") + 6, "%llu %llu %llu %llu %llu %llu",
c288c9
+			       &snfs.rd_normal_bytes, &snfs.wr_normal_bytes,
c288c9
+			       &snfs.rd_direct_bytes, &snfs.wr_direct_bytes,
c288c9
+			       &snfs.rd_server_bytes, &snfs.wr_server_bytes);
c288c9
+			sw = 2;
c288c9
+		}
c288c9
+
c288c9
+		if ((sw == 2) && (!strncmp(prefix, "xprt:", 5))) {
c288c9
+			/*
c288c9
+			 * Read extended statistic for the last NFS-mounted directory
c288c9
+			 * - number of sent rpc requests.
c288c9
+			 */
c288c9
+			xprt_line = (strstr(line, "xprt:") + 6);
c288c9
+			/* udp, tcp or rdma data */
c288c9
+			if (!strncmp(xprt_line, "udp", 3)) {
c288c9
+				/* port bind_count sends recvs (bad_xids req_u bklog_u) */
c288c9
+				sscanf(strstr(xprt_line, "udp") + 4, "%*u %*u %lu",
c288c9
+				       &snfs.rpc_sends);
c288c9
+			}
c288c9
+			if (!strncmp(xprt_line, "tcp", 3)) {
c288c9
+				/*
c288c9
+				 * port bind_counter connect_count connect_time idle_time
c288c9
+				 * sends recvs (bad_xids req_u bklog_u)
c288c9
+				 */
c288c9
+				sscanf(strstr(xprt_line, "tcp") + 4,
c288c9
+				       "%*u %*u %*u %*u %*d %lu",
c288c9
+				       &snfs.rpc_sends);
c288c9
+			}
c288c9
+			if (!strncmp(xprt_line,"rdma", 4)) {
c288c9
+				/*
c288c9
+				 * 0(port) bind_count connect_count connect_time idle_time
c288c9
+				 * sends recvs (bad_xids req_u bklog_u...)
c288c9
+				 */
c288c9
+				sscanf(strstr(xprt_line, "rdma") + 5,
c288c9
+				       "%*u %*u %*u %*u %*d %lu",
c288c9
+				       &snfs.rpc_sends);
c288c9
+			}
c288c9
+			sw = 3;
c288c9
+		}
c288c9
+
c288c9
+		if ((sw == 3) && (!strncmp(prefix, "per-op", 6))) {
c288c9
+			sw = 4;
c288c9
+			while (sw == 4) {
c288c9
+				if (fgets(line, sizeof(line), fp) == NULL)
c288c9
+					break;
c288c9
+				sscanf(line, "%15s %lu", operation, &v1;;
c288c9
+				if (!strncmp(operation, "READ:", 5)) {
c288c9
+					snfs.nfs_rops = v1;
c288c9
+				}
c288c9
+				else if (!strncmp(operation, "WRITE:", 6)) {
c288c9
+					snfs.nfs_wops = v1;
c288c9
+
c288c9
+					save_stats(nfs_name, curr, &snfs);
c288c9
+					sw = 0;
c288c9
+				}
c288c9
+			}
c288c9
+		}
c288c9
+	}
c288c9
+
c288c9
+	fclose(fp);
c288c9
+
c288c9
+	/* Free structures corresponding to unregistered filesystems */
c288c9
+	free_inactive_entries();
c288c9
+}
c288c9
+
c288c9
+/*
c288c9
+ ***************************************************************************
c288c9
+ * Display NFS stats header.
c288c9
+ *
c288c9
+ * OUT:
c288c9
+ * @fctr	Conversion factor.
c288c9
+ ***************************************************************************
c288c9
+ */
c288c9
+void write_nfs_stat_header(int *fctr)
c288c9
+{
c288c9
+	printf("Filesystem:           ");
c288c9
+	if (DISPLAY_KILOBYTES(flags)) {
c288c9
+		printf("    rkB_nor/s    wkB_nor/s    rkB_dir/s    wkB_dir/s"
c288c9
+		       "    rkB_svr/s    wkB_svr/s");
c288c9
+		*fctr = 1024;
c288c9
+	}
c288c9
+	else if (DISPLAY_MEGABYTES(flags)) {
c288c9
+		printf("    rMB_nor/s    wMB_nor/s    rMB_dir/s    wMB_dir/s"
c288c9
+		       "    rMB_svr/s    wMB_svr/s");
c288c9
+		*fctr = 1024 * 1024;
c288c9
+	}
c288c9
+	else {
c288c9
+		printf("   rBlk_nor/s   wBlk_nor/s   rBlk_dir/s   wBlk_dir/s"
c288c9
+		       "   rBlk_svr/s   wBlk_svr/s");
c288c9
+		*fctr = 512;
c288c9
+	}
c288c9
+	printf("     ops/s    rops/s    wops/s\n");
c288c9
+}
c288c9
+
c288c9
+/*
c288c9
+ ***************************************************************************
c288c9
+ * Write NFS stats read from /proc/self/mountstats.
c288c9
+ *
c288c9
+ * IN:
c288c9
+ * @curr	Index in array for current sample statistics.
c288c9
+ * @itv		Interval of time.
c288c9
+ * @fctr	Conversion factor.
c288c9
+ * @shi		Structures describing the NFS filesystems.
c288c9
+ * @ioi		Current sample statistics.
c288c9
+ * @ioj		Previous sample statistics.
c288c9
+ ***************************************************************************
c288c9
+ */
c288c9
+void write_nfs_stat(int curr, unsigned long long itv, int fctr,
c288c9
+		    struct io_hdr_stats *shi, struct io_nfs_stats *ioni,
c288c9
+		    struct io_nfs_stats *ionj)
c288c9
+{
c288c9
+	if (DISPLAY_HUMAN_READ(flags)) {
c288c9
+		printf("%-22s\n%23s", shi->name, "");
c288c9
+	}
c288c9
+	else {
c288c9
+		printf("%-22s ", shi->name);
c288c9
+	}
c288c9
+	printf("%12.2f %12.2f %12.2f %12.2f %12.2f %12.2f %9.2f %9.2f %9.2f\n",
c288c9
+	       S_VALUE(ionj->rd_normal_bytes, ioni->rd_normal_bytes, itv) / fctr,
c288c9
+	       S_VALUE(ionj->wr_normal_bytes, ioni->wr_normal_bytes, itv) / fctr,
c288c9
+	       S_VALUE(ionj->rd_direct_bytes, ioni->rd_direct_bytes, itv) / fctr,
c288c9
+	       S_VALUE(ionj->wr_direct_bytes, ioni->wr_direct_bytes, itv) / fctr,
c288c9
+	       S_VALUE(ionj->rd_server_bytes, ioni->rd_server_bytes, itv) / fctr,
c288c9
+	       S_VALUE(ionj->wr_server_bytes, ioni->wr_server_bytes, itv) / fctr,
c288c9
+	       S_VALUE(ionj->rpc_sends, ioni->rpc_sends, itv),
c288c9
+	       S_VALUE(ionj->nfs_rops,  ioni->nfs_rops,  itv),
c288c9
+	       S_VALUE(ionj->nfs_wops,  ioni->nfs_wops,  itv));
c288c9
+}
c288c9
+
c288c9
+/*
c288c9
+ ***************************************************************************
c288c9
+ * Print everything now (stats and uptime).
c288c9
+ *
c288c9
+ * IN:
c288c9
+ * @curr	Index in array for current sample statistics.
c288c9
+ * @rectime	Current date and time.
c288c9
+ ***************************************************************************
c288c9
+ */
c288c9
+void write_stats(int curr, struct tm *rectime)
c288c9
+{
c288c9
+	int i, fctr = 1;
c288c9
+	unsigned long long itv;
c288c9
+	struct io_hdr_stats *shi;
c288c9
+	struct io_nfs_stats *ioni, *ionj;
c288c9
+
c288c9
+	/* Test stdout */
c288c9
+	TEST_STDOUT(STDOUT_FILENO);
c288c9
+
c288c9
+	/* Print time stamp */
c288c9
+	if (DISPLAY_TIMESTAMP(flags)) {
c288c9
+		if (DISPLAY_ISO(flags)) {
c288c9
+			strftime(timestamp, sizeof(timestamp), "%FT%T%z", rectime);
c288c9
+		}
c288c9
+		else {
c288c9
+			strftime(timestamp, sizeof(timestamp), "%x %X", rectime);
c288c9
+		}
c288c9
+		printf("%s\n", timestamp);
c288c9
+#ifdef DEBUG
c288c9
+		if (DISPLAY_DEBUG(flags)) {
c288c9
+			fprintf(stderr, "%s\n", timestamp);
c288c9
+		}
c288c9
+#endif
c288c9
+	}
c288c9
+
c288c9
+	/* Interval of time, reduced to one processor */
c288c9
+	itv = get_interval(uptime0[!curr], uptime0[curr]);
c288c9
+
c288c9
+	shi = st_hdr_ionfs;
c288c9
+
c288c9
+	/* Display NFS stats header */
c288c9
+	write_nfs_stat_header(&fctr);
c288c9
+
c288c9
+	for (i = 0; i < ionfs_nr; i++, shi++) {
c288c9
+		if (shi->used) {
c288c9
+			ioni = st_ionfs[curr]  + i;
c288c9
+			ionj = st_ionfs[!curr] + i;
c288c9
+#ifdef DEBUG
c288c9
+			if (DISPLAY_DEBUG(flags)) {
c288c9
+				/* Debug output */
c288c9
+				fprintf(stderr, "name=%s itv=%llu fctr=%d ioni{ rd_normal_bytes=%llu "
c288c9
+						"wr_normal_bytes=%llu rd_direct_bytes=%llu wr_direct_bytes=%llu rd_server_bytes=%llu "
c288c9
+						"wr_server_bytes=%llu rpc_sends=%lu nfs_rops=%lu nfs_wops=%lu }\n",
c288c9
+					shi->name, itv, fctr,
c288c9
+					ioni->rd_normal_bytes, ioni->wr_normal_bytes,
c288c9
+					ioni->rd_direct_bytes, ioni->wr_direct_bytes,
c288c9
+					ioni->rd_server_bytes, ioni->wr_server_bytes,
c288c9
+					ioni->rpc_sends,
c288c9
+					ioni->nfs_rops,        ioni->nfs_wops);
c288c9
+			}
c288c9
+#endif
c288c9
+			write_nfs_stat(curr, itv, fctr, shi, ioni, ionj);
c288c9
+		}
c288c9
+	}
c288c9
+	printf("\n");
c288c9
+}
c288c9
+
c288c9
+/*
c288c9
+ ***************************************************************************
c288c9
+ * Main loop: Read stats from the relevant sources and display them.
c288c9
+ *
c288c9
+ * IN:
c288c9
+ * @count	Number of lines of stats to print.
c288c9
+ * @rectime	Current date and time.
c288c9
+ ***************************************************************************
c288c9
+ */
c288c9
+void rw_io_stat_loop(long int count, struct tm *rectime)
c288c9
+{
c288c9
+	int curr = 1;
c288c9
+
c288c9
+	/* Don't buffer data if redirected to a pipe */
c288c9
+	setbuf(stdout, NULL);
c288c9
+	
c288c9
+	do {
c288c9
+		/* Read system uptime (reduced to one processor) */
c288c9
+		uptime0[curr] = 0;
c288c9
+		read_uptime(&(uptime0[curr]));
c288c9
+		if (!uptime0[curr])
c288c9
+			/* Cannot read system uptime (/proc/uptime doesn't exist) */
c288c9
+			exit(2);
c288c9
+
c288c9
+		/* Read NFS directories stats */
c288c9
+		read_nfs_stat(curr);
c288c9
+
c288c9
+		/* Get time */
c288c9
+		get_localtime(rectime, 0);
c288c9
+
c288c9
+		/* Print results */
c288c9
+		write_stats(curr, rectime);
c288c9
+
c288c9
+		if (count > 0) {
c288c9
+			count--;
c288c9
+		}
c288c9
+		if (count) {
c288c9
+			curr ^= 1;
c288c9
+			pause();
c288c9
+		}
c288c9
+	}
c288c9
+	while (count);
c288c9
+}
c288c9
+
c288c9
+/*
c288c9
+ ***************************************************************************
c288c9
+ * Main entry to the nfsiostat-sysstat program.
c288c9
+ ***************************************************************************
c288c9
+ */
c288c9
+int main(int argc, char **argv)
c288c9
+{
c288c9
+	int it = 0;
c288c9
+	int opt = 1;
c288c9
+	int i;
c288c9
+	long count = 1;
c288c9
+	struct utsname header;
c288c9
+	struct tm rectime;
c288c9
+
c288c9
+#ifdef USE_NLS
c288c9
+	/* Init National Language Support */
c288c9
+	init_nls();
c288c9
+#endif
c288c9
+
c288c9
+	/* Get HZ */
c288c9
+	get_HZ();
c288c9
+
c288c9
+	/* Process args... */
c288c9
+	while (opt < argc) {
c288c9
+
c288c9
+#ifdef DEBUG
c288c9
+		if (!strcmp(argv[opt], "--debuginfo")) {
c288c9
+			flags |= I_D_DEBUG;
c288c9
+			opt++;
c288c9
+		} else
c288c9
+#endif
c288c9
+		if (!strncmp(argv[opt], "-", 1)) {
c288c9
+			for (i = 1; *(argv[opt] + i); i++) {
c288c9
+
c288c9
+				switch (*(argv[opt] + i)) {
c288c9
+
c288c9
+				case 'h':
c288c9
+					/* Display an easy-to-read NFS report */
c288c9
+					flags |= I_D_HUMAN_READ;
c288c9
+					break;
c288c9
+	
c288c9
+				case 'k':
c288c9
+					if (DISPLAY_MEGABYTES(flags)) {
c288c9
+						usage(argv[0]);
c288c9
+					}
c288c9
+					/* Display stats in kB/s */
c288c9
+					flags |= I_D_KILOBYTES;
c288c9
+					break;
c288c9
+
c288c9
+				case 'm':
c288c9
+					if (DISPLAY_KILOBYTES(flags)) {
c288c9
+						usage(argv[0]);
c288c9
+					}
c288c9
+					/* Display stats in MB/s */
c288c9
+					flags |= I_D_MEGABYTES;
c288c9
+					break;
c288c9
+
c288c9
+				case 't':
c288c9
+					/* Display timestamp */
c288c9
+					flags |= I_D_TIMESTAMP;
c288c9
+					break;
c288c9
+
c288c9
+				case 'V':
c288c9
+					/* Print version number and exit */
c288c9
+					print_version();
c288c9
+					break;
c288c9
+	
c288c9
+				default:
c288c9
+					usage(argv[0]);
c288c9
+				}
c288c9
+			}
c288c9
+			opt++;
c288c9
+		}
c288c9
+
c288c9
+		else if (!it) {
c288c9
+			interval = atol(argv[opt++]);
c288c9
+			if (interval < 0) {
c288c9
+				usage(argv[0]);
c288c9
+			}
c288c9
+			count = -1;
c288c9
+			it = 1;
c288c9
+		}
c288c9
+
c288c9
+		else if (it > 0) {
c288c9
+			count = atol(argv[opt++]);
c288c9
+			if ((count < 1) || !interval) {
c288c9
+				usage(argv[0]);
c288c9
+			}
c288c9
+			it = -1;
c288c9
+		}
c288c9
+		else {
c288c9
+			usage(argv[0]);
c288c9
+		}
c288c9
+	}
c288c9
+
c288c9
+	if (!interval) {
c288c9
+		count = 1;
c288c9
+	}
c288c9
+
c288c9
+	/* Select output unit (kB/s or blocks/s) */
c288c9
+	set_output_unit();
c288c9
+
c288c9
+	/* Init structures according to machine architecture */
c288c9
+	io_sys_init();
c288c9
+
c288c9
+	get_localtime(&rectime, 0);
c288c9
+
c288c9
+	/* Get system name, release number and hostname */
c288c9
+	uname(&header);
c288c9
+	if (print_gal_header(&rectime, header.sysname, header.release,
c288c9
+			     header.nodename, header.machine, cpu_nr)) {
c288c9
+		flags |= I_D_ISO;
c288c9
+	}
c288c9
+	printf("\n");
c288c9
+
c288c9
+	/* Set a handler for SIGALRM */
c288c9
+	memset(&alrm_act, 0, sizeof(alrm_act));
c288c9
+	alrm_act.sa_handler = (void *) alarm_handler;
c288c9
+	sigaction(SIGALRM, &alrm_act, NULL);
c288c9
+	alarm(interval);
c288c9
+
c288c9
+	/* Main loop */
c288c9
+	rw_io_stat_loop(count, &rectime);
c288c9
+
c288c9
+	/* Free structures */
c288c9
+	io_sys_free();
c288c9
+
c288c9
+	return 0;
c288c9
+}
c288c9
diff -uprN sysstat-10.1.5.orig/nfsiostat-sysstat.h sysstat-10.1.5/nfsiostat-sysstat.h
c288c9
--- sysstat-10.1.5.orig/nfsiostat-sysstat.h	1970-01-01 01:00:00.000000000 +0100
c288c9
+++ sysstat-10.1.5/nfsiostat-sysstat.h	2016-05-24 18:25:16.210668308 +0200
c288c9
@@ -0,0 +1,57 @@
c288c9
+/*
c288c9
+ * nfsiostat-sysstat: Report NFS I/O statistics
c288c9
+ * Copyright (C) 2010 Red Hat, Inc. All Rights Reserved
c288c9
+ * Written by Ivana Varekova <varekova@redhat.com>
c288c9
+ */
c288c9
+
c288c9
+#ifndef _NFSIOSTAT_SYSSTAT_H
c288c9
+#define _NFSIOSTAT_SYSSTAT_H
c288c9
+
c288c9
+#include "common.h"
c288c9
+
c288c9
+#define NFSMOUNTSTATS  "/proc/self/mountstats"
c288c9
+
c288c9
+/* I_: iostat - D_: Display - F_: Flag */
c288c9
+#define I_D_TIMESTAMP		0x001
c288c9
+#define I_D_KILOBYTES		0x002
c288c9
+#define I_D_MEGABYTES		0x004
c288c9
+#define I_D_ISO			0x008
c288c9
+#define I_D_HUMAN_READ		0x010
c288c9
+#define I_D_DEBUG		0x020
c288c9
+
c288c9
+#define DISPLAY_TIMESTAMP(m)	(((m) & I_D_TIMESTAMP)     == I_D_TIMESTAMP)
c288c9
+#define DISPLAY_KILOBYTES(m)	(((m) & I_D_KILOBYTES)     == I_D_KILOBYTES)
c288c9
+#define DISPLAY_MEGABYTES(m)	(((m) & I_D_MEGABYTES)     == I_D_MEGABYTES)
c288c9
+#define DISPLAY_ISO(m)		(((m) & I_D_ISO)           == I_D_ISO)
c288c9
+#define DISPLAY_HUMAN_READ(m)	(((m) & I_D_HUMAN_READ)    == I_D_HUMAN_READ)
c288c9
+#define DISPLAY_DEBUG(m)	(((m) & I_D_DEBUG)         == I_D_DEBUG)
c288c9
+
c288c9
+/* Environment variable */
c288c9
+#define ENV_POSIXLY_CORRECT	"POSIXLY_CORRECT"
c288c9
+
c288c9
+/* Preallocation constats */
c288c9
+#define NR_NFS_PREALLOC	2
c288c9
+
c288c9
+struct io_nfs_stats {
c288c9
+	unsigned long long rd_normal_bytes	__attribute__ ((aligned (8)));
c288c9
+	unsigned long long wr_normal_bytes	__attribute__ ((packed));
c288c9
+	unsigned long long rd_direct_bytes	__attribute__ ((packed));
c288c9
+	unsigned long long wr_direct_bytes	__attribute__ ((packed));
c288c9
+	unsigned long long rd_server_bytes	__attribute__ ((packed));
c288c9
+	unsigned long long wr_server_bytes	__attribute__ ((packed));
c288c9
+	unsigned long rpc_sends			__attribute__ ((packed));
c288c9
+	unsigned long nfs_rops			__attribute__ ((packed));
c288c9
+	unsigned long nfs_wops			__attribute__ ((packed));
c288c9
+};
c288c9
+
c288c9
+#define IO_NFS_STATS_SIZE	(sizeof(struct io_nfs_stats))
c288c9
+
c288c9
+struct io_hdr_stats {
c288c9
+	unsigned int active		__attribute__ ((aligned (4)));
c288c9
+	unsigned int used		__attribute__ ((packed));
c288c9
+	char name[MAX_NAME_LEN];
c288c9
+};
c288c9
+
c288c9
+#define IO_HDR_STATS_SIZE	(sizeof(struct io_hdr_stats))
c288c9
+
c288c9
+#endif  /* _NFSIOSTAT_SYSSTAT_H */