Updated to latest upstream version: 1.1.3
This commit is contained in:
parent
433c940a7f
commit
8bea6d77d5
@ -12,3 +12,4 @@ nfs-utils-1.0.12.tar.bz2
|
|||||||
nfs-utils-1.1.0.tar.bz2
|
nfs-utils-1.1.0.tar.bz2
|
||||||
nfs-utils-1.1.1.tar.bz2
|
nfs-utils-1.1.1.tar.bz2
|
||||||
nfs-utils-1.1.2.tar.bz2
|
nfs-utils-1.1.2.tar.bz2
|
||||||
|
nfs-utils-1.1.3.tar.bz2
|
||||||
|
@ -1,31 +0,0 @@
|
|||||||
--- nfs-utils-1.0.6/utils/gssd/gssd_proc.c.gssd 2006-03-02 14:36:10.000000000 -0500
|
|
||||||
+++ nfs-utils-1.0.6/utils/gssd/gssd_proc.c 2006-03-02 14:38:47.000000000 -0500
|
|
||||||
@@ -53,6 +53,7 @@
|
|
||||||
#include <pwd.h>
|
|
||||||
#include <grp.h>
|
|
||||||
#include <string.h>
|
|
||||||
+#include <ctype.h>
|
|
||||||
#include <dirent.h>
|
|
||||||
#include <poll.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
@@ -115,6 +116,7 @@ read_service_info(char *info_file_name,
|
|
||||||
int fd = -1;
|
|
||||||
struct hostent *ent = NULL;
|
|
||||||
int numfields;
|
|
||||||
+ char *s;
|
|
||||||
|
|
||||||
*servicename = *servername = *protocol = NULL;
|
|
||||||
|
|
||||||
@@ -155,6 +157,12 @@ read_service_info(char *info_file_name,
|
|
||||||
printerr(0, "ERROR: can't resolve server %s name\n", address);
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
+
|
|
||||||
+ /* don't allow mixed-case names to rain on our parade */
|
|
||||||
+ for (s = ent->h_name; s && *s; s++) {
|
|
||||||
+ *s = tolower((int)*s);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
if (!(*servername = calloc(strlen(ent->h_name) + 1, 1)))
|
|
||||||
goto fail;
|
|
||||||
memcpy(*servername, ent->h_name, strlen(ent->h_name));
|
|
@ -1,31 +0,0 @@
|
|||||||
#
|
|
||||||
# Make sure check_new_cache() is looking in the right place
|
|
||||||
#
|
|
||||||
--- src/support/nfs/cacheio.c.org 2003-08-04 00:12:16.000000000 -0400
|
|
||||||
+++ src/support/nfs/cacheio.c 2004-03-22 18:12:55.163534208 -0500
|
|
||||||
@@ -223,12 +223,23 @@ int readline(int fd, char **buf, int *le
|
|
||||||
* This succeeds iff the "nfsd" filesystem is mounted on
|
|
||||||
* /proc/fs/nfs
|
|
||||||
*/
|
|
||||||
+static char *cachelist[] = {
|
|
||||||
+ { "auth.unix.ip" }, { "nfsd.export" }, { "nfsd.fh" },
|
|
||||||
+ { NULL, NULL }
|
|
||||||
+};
|
|
||||||
int
|
|
||||||
check_new_cache(void)
|
|
||||||
{
|
|
||||||
struct stat stb;
|
|
||||||
- return (stat("/proc/fs/nfs/filehandle", &stb) == 0) ||
|
|
||||||
- (stat("/proc/fs/nfsd/filehandle", &stb) == 0);
|
|
||||||
+ char path[64];
|
|
||||||
+ int i;
|
|
||||||
+
|
|
||||||
+ for (i=0; cachelist[i]; i++ ){
|
|
||||||
+ sprintf(path, "/proc/net/rpc/%s/channel", cachelist[i]);
|
|
||||||
+ if (stat(path, &stb) < 0)
|
|
||||||
+ return 0;
|
|
||||||
+ }
|
|
||||||
+ return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -1,94 +0,0 @@
|
|||||||
commit fa29d7a9a3d8a72b79924d28813eef7e55a25bc9
|
|
||||||
Author: Steve Dickson <steved@redhat.com>
|
|
||||||
Date: Tue Mar 18 09:33:44 2008 -0400
|
|
||||||
|
|
||||||
Updated exportfs man to talk about /var/lib/nfs/etab
|
|
||||||
instead of /var/lib/nfs/xtab
|
|
||||||
|
|
||||||
Signed-off-by: Steve Dickson <steved@redhat.com>
|
|
||||||
|
|
||||||
diff --git a/utils/exportfs/exportfs.man b/utils/exportfs/exportfs.man
|
|
||||||
index 59789cc..a8fdb05 100644
|
|
||||||
--- a/utils/exportfs/exportfs.man
|
|
||||||
+++ b/utils/exportfs/exportfs.man
|
|
||||||
@@ -22,14 +22,14 @@ The
|
|
||||||
.B exportfs
|
|
||||||
command is used to maintain the current table of exported file systems for
|
|
||||||
NFS. This list is kept in a separate file named
|
|
||||||
-.BR /var/lib/nfs/xtab
|
|
||||||
+.BR /var/lib/nfs/etab
|
|
||||||
which is read by
|
|
||||||
.B mountd
|
|
||||||
when a remote host requests access to mount a file tree, and parts of
|
|
||||||
the list which are active are kept in the kernel's export table.
|
|
||||||
.P
|
|
||||||
Normally this
|
|
||||||
-.B xtab
|
|
||||||
+.B etab
|
|
||||||
file is initialized with the list of all file systems named in
|
|
||||||
.B /etc/exports
|
|
||||||
by invoking
|
|
||||||
@@ -59,7 +59,7 @@ In the new mode,
|
|
||||||
does not give any information to the kernel but only provides it to
|
|
||||||
.B mountd
|
|
||||||
through the
|
|
||||||
-.B /var/lib/nfs/xtab
|
|
||||||
+.B /var/lib/nfs/etab
|
|
||||||
file.
|
|
||||||
.B mountd
|
|
||||||
will listen to requests from the kernel and will provide information
|
|
||||||
@@ -69,7 +69,7 @@ In the legacy mode,
|
|
||||||
any export requests which identify a specific host (rather than a
|
|
||||||
subnet or netgroup etc) are entered directly into the kernel's export
|
|
||||||
table as well as being written to
|
|
||||||
-.BR /var/lib/nfs/xtab .
|
|
||||||
+.BR /var/lib/nfs/etab .
|
|
||||||
Further, any mount points listed in
|
|
||||||
.B /var/lib/nfs/rmtab
|
|
||||||
which match a non host-specific export request will cause an
|
|
||||||
@@ -93,8 +93,8 @@ file, so that only default options and options given on the command
|
|
||||||
line are used.
|
|
||||||
.TP
|
|
||||||
.B -r
|
|
||||||
-Reexport all directories. It synchronizes /var/lib/nfs/xtab
|
|
||||||
-with /etc/exports. It removes entries in /var/lib/nfs/xtab
|
|
||||||
+Reexport all directories. It synchronizes /var/lib/nfs/etab
|
|
||||||
+with /etc/exports. It removes entries in /var/lib/nfs/etab
|
|
||||||
which are deleted from /etc/exports, and remove any entries from the
|
|
||||||
kernel export table which are no longer valid.
|
|
||||||
.TP
|
|
||||||
@@ -120,7 +120,7 @@ entries to the export table. When using
|
|
||||||
all directories in
|
|
||||||
.B exports(5)
|
|
||||||
are added to
|
|
||||||
-.B xtab
|
|
||||||
+.B etab
|
|
||||||
and the resulting list is pushed into the kernel.
|
|
||||||
.P
|
|
||||||
The
|
|
||||||
@@ -152,7 +152,7 @@ directory.
|
|
||||||
Modifications of the kernel export table used by
|
|
||||||
.B nfsd(8)
|
|
||||||
take place immediately after parsing the command line and updating the
|
|
||||||
-.B xtab
|
|
||||||
+.B etab
|
|
||||||
file.
|
|
||||||
.P
|
|
||||||
The default export options are
|
|
||||||
@@ -163,14 +163,14 @@ The third synopsis shows how to unexported a currently exported directory.
|
|
||||||
When using
|
|
||||||
.BR "exportfs -ua" ,
|
|
||||||
all entries listed in
|
|
||||||
-.B xtab
|
|
||||||
+.B etab
|
|
||||||
are removed from the kernel export tables, and the file is cleared. This
|
|
||||||
effectively shuts down all NFS activity.
|
|
||||||
.P
|
|
||||||
To remove an export to a host, specify a
|
|
||||||
.I host:/path
|
|
||||||
pair. This deletes the specified entry from
|
|
||||||
-.B xtab
|
|
||||||
+.B etab
|
|
||||||
and removes the corresponding kernel entry (if any).
|
|
||||||
To remove one or more exports to several hosts, use
|
|
||||||
.BR "exportfs -ua" .
|
|
@ -1,24 +0,0 @@
|
|||||||
diff -up nfs-utils-1.1.1/support/nfs/xio.c.save nfs-utils-1.1.1/support/nfs/xio.c
|
|
||||||
--- nfs-utils-1.1.1/support/nfs/xio.c.save 2007-10-18 23:07:28.000000000 -0400
|
|
||||||
+++ nfs-utils-1.1.1/support/nfs/xio.c 2008-01-05 08:27:35.000000000 -0500
|
|
||||||
@@ -54,13 +54,19 @@ xflock(char *fname, char *type)
|
|
||||||
{
|
|
||||||
struct sigaction sa, oldsa;
|
|
||||||
int readonly = !strcmp(type, "r");
|
|
||||||
+ mode_t mode = (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
|
|
||||||
struct flock fl = { readonly? F_RDLCK : F_WRLCK, SEEK_SET, 0, 0, 0 };
|
|
||||||
int fd;
|
|
||||||
|
|
||||||
- if ((fd = open(fname, readonly? O_RDONLY : (O_RDWR|O_CREAT), 0644)) < 0) {
|
|
||||||
+ if (readonly)
|
|
||||||
+ fd = open(fname, O_RDONLY);
|
|
||||||
+ else
|
|
||||||
+ fd = open(fname, (O_RDWR|O_CREAT), mode);
|
|
||||||
+ if (fd < 0) {
|
|
||||||
xlog(L_WARNING, "could not open %s for locking", fname);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
+
|
|
||||||
sa.sa_handler = doalarm;
|
|
||||||
sa.sa_flags = 0;
|
|
||||||
sigemptyset(&sa.sa_mask);
|
|
@ -1,20 +0,0 @@
|
|||||||
--- nfs-utils-1.1.0/utils/showmount/showmount.c.orig 2007-05-10 23:40:57.000000000 -0400
|
|
||||||
+++ nfs-utils-1.1.0/utils/showmount/showmount.c 2007-07-16 13:02:42.000000000 -0400
|
|
||||||
@@ -242,6 +242,8 @@ static unsigned short getport(struct soc
|
|
||||||
rpc_createerr.cf_stat = status;
|
|
||||||
clnt_destroy(client);
|
|
||||||
return 0;
|
|
||||||
+ } else if (port == 0) {
|
|
||||||
+ rpc_createerr.cf_stat = RPC_PROGNOTREGISTERED;
|
|
||||||
}
|
|
||||||
|
|
||||||
clnt_destroy(client);
|
|
||||||
@@ -368,7 +370,7 @@ char **argv;
|
|
||||||
server_addr.sin_port = getport(&server_addr,
|
|
||||||
MOUNTPROG, MOUNTVERS, IPPROTO_UDP);
|
|
||||||
if (!server_addr.sin_port) {
|
|
||||||
- clnt_pcreateerror("portmap getport");
|
|
||||||
+ clnt_pcreateerror("showmount");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
msock = RPC_ANYSOCK;
|
|
@ -1,21 +0,0 @@
|
|||||||
commit 7ef076fb98233783843d6019b2edbb48e2d18914
|
|
||||||
Author: Oren Held <oren@held.org.il>
|
|
||||||
Date: Thu May 8 05:23:10 2008 -0400
|
|
||||||
|
|
||||||
Fixed smail typo in exportfs man page
|
|
||||||
|
|
||||||
Signed-off-by: Steve Dickson <steved@redhat.com>
|
|
||||||
|
|
||||||
diff --git a/utils/exportfs/exportfs.man b/utils/exportfs/exportfs.man
|
|
||||||
index a8fdb05..c7b230a 100644
|
|
||||||
--- a/utils/exportfs/exportfs.man
|
|
||||||
+++ b/utils/exportfs/exportfs.man
|
|
||||||
@@ -198,7 +198,7 @@ and pushes the resulting export entries into the kernel:
|
|
||||||
To export the
|
|
||||||
.B /usr/tmp
|
|
||||||
directory to host
|
|
||||||
-.BR djando ,
|
|
||||||
+.BR django ,
|
|
||||||
allowing asynchronous writes, one would do this:
|
|
||||||
.P
|
|
||||||
.nf
|
|
@ -1,235 +0,0 @@
|
|||||||
commit 25cd5f9101b8969f9e1f9d7d486f11c215d0eeb4
|
|
||||||
Author: Vince Busam <vbusam@google.com>
|
|
||||||
Date: Wed May 7 15:24:53 2008 -0400
|
|
||||||
|
|
||||||
Kerberos credentials may be stored in multiple places. Make it
|
|
||||||
possible to search several directories for valid credentials when
|
|
||||||
making NFS requests.
|
|
||||||
|
|
||||||
Original patch from Vince Busam <vbusam@google.com>
|
|
||||||
|
|
||||||
Signed-off-by: Kevin Coffman <kwc@citi.umich.edu>.
|
|
||||||
Signed-off-by: Steve Dickson <steved@redhat.com>
|
|
||||||
|
|
||||||
diff --git a/utils/gssd/gssd.c b/utils/gssd/gssd.c
|
|
||||||
index bbcad20..e8612a5 100644
|
|
||||||
--- a/utils/gssd/gssd.c
|
|
||||||
+++ b/utils/gssd/gssd.c
|
|
||||||
@@ -57,6 +57,7 @@ char pipefs_dir[PATH_MAX] = GSSD_PIPEFS_DIR;
|
|
||||||
char pipefs_nfsdir[PATH_MAX] = GSSD_PIPEFS_DIR;
|
|
||||||
char keytabfile[PATH_MAX] = GSSD_DEFAULT_KEYTAB_FILE;
|
|
||||||
char ccachedir[PATH_MAX] = GSSD_DEFAULT_CRED_DIR;
|
|
||||||
+char *ccachesearch[GSSD_MAX_CCACHE_SEARCH + 1];
|
|
||||||
int use_memcache = 0;
|
|
||||||
int root_uses_machine_creds = 1;
|
|
||||||
|
|
||||||
@@ -93,9 +94,11 @@ main(int argc, char *argv[])
|
|
||||||
int verbosity = 0;
|
|
||||||
int rpc_verbosity = 0;
|
|
||||||
int opt;
|
|
||||||
+ int i;
|
|
||||||
extern char *optarg;
|
|
||||||
char *progname;
|
|
||||||
|
|
||||||
+ memset(ccachesearch, 0, sizeof(ccachesearch));
|
|
||||||
while ((opt = getopt(argc, argv, "fvrmnMp:k:d:")) != -1) {
|
|
||||||
switch (opt) {
|
|
||||||
case 'f':
|
|
||||||
@@ -136,6 +139,13 @@ main(int argc, char *argv[])
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+
|
|
||||||
+ i = 0;
|
|
||||||
+ ccachesearch[i++] = strtok(ccachedir, ":");
|
|
||||||
+ do {
|
|
||||||
+ ccachesearch[i++] = strtok(NULL, ":");
|
|
||||||
+ } while (ccachesearch[i-1] != NULL && i < GSSD_MAX_CCACHE_SEARCH);
|
|
||||||
+
|
|
||||||
snprintf(pipefs_nfsdir, sizeof(pipefs_nfsdir), "%s/%s",
|
|
||||||
pipefs_dir, GSSD_SERVICE_NAME);
|
|
||||||
if (pipefs_nfsdir[sizeof(pipefs_nfsdir)-1] != '\0')
|
|
||||||
diff --git a/utils/gssd/gssd.h b/utils/gssd/gssd.h
|
|
||||||
index 6f14c34..0f9f428 100644
|
|
||||||
--- a/utils/gssd/gssd.h
|
|
||||||
+++ b/utils/gssd/gssd.h
|
|
||||||
@@ -50,6 +50,7 @@
|
|
||||||
#define GSSD_DEFAULT_KEYTAB_FILE "/etc/krb5.keytab"
|
|
||||||
#define GSSD_SERVICE_NAME "nfs"
|
|
||||||
#define GSSD_SERVICE_NAME_LEN 3
|
|
||||||
+#define GSSD_MAX_CCACHE_SEARCH 16
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The gss mechanisms that we can handle
|
|
||||||
@@ -61,7 +62,7 @@ enum {AUTHTYPE_KRB5, AUTHTYPE_SPKM3, AUTHTYPE_LIPKEY};
|
|
||||||
extern char pipefs_dir[PATH_MAX];
|
|
||||||
extern char pipefs_nfsdir[PATH_MAX];
|
|
||||||
extern char keytabfile[PATH_MAX];
|
|
||||||
-extern char ccachedir[PATH_MAX];
|
|
||||||
+extern char *ccachesearch[];
|
|
||||||
extern int use_memcache;
|
|
||||||
extern int root_uses_machine_creds;
|
|
||||||
|
|
||||||
diff --git a/utils/gssd/gssd.man b/utils/gssd/gssd.man
|
|
||||||
index 2fa749e..8fa4f4a 100644
|
|
||||||
--- a/utils/gssd/gssd.man
|
|
||||||
+++ b/utils/gssd/gssd.man
|
|
||||||
@@ -74,7 +74,11 @@ where to look for the rpc_pipefs filesystem. The default value is
|
|
||||||
.B -d directory
|
|
||||||
Tells
|
|
||||||
.B rpc.gssd
|
|
||||||
-where to look for kerberos credential files. The default value is "/tmp".
|
|
||||||
+where to look for Kerberos credential files. The default value is "/tmp".
|
|
||||||
+This can also be a colon separated list of directories to be searched
|
|
||||||
+for Kerberos credential files. Note that if machine credentials are being
|
|
||||||
+stored in files, then the first directory on this list is where the
|
|
||||||
+machine credentials are stored.
|
|
||||||
.TP
|
|
||||||
.B -v
|
|
||||||
Increases the verbosity of the output (can be specified multiple times).
|
|
||||||
diff --git a/utils/gssd/gssd_proc.c b/utils/gssd/gssd_proc.c
|
|
||||||
index bac7295..be6f440 100644
|
|
||||||
--- a/utils/gssd/gssd_proc.c
|
|
||||||
+++ b/utils/gssd/gssd_proc.c
|
|
||||||
@@ -685,6 +685,7 @@ handle_krb5_upcall(struct clnt_info *clp)
|
|
||||||
gss_buffer_desc token;
|
|
||||||
char **credlist = NULL;
|
|
||||||
char **ccname;
|
|
||||||
+ char **dirname;
|
|
||||||
int create_resp = -1;
|
|
||||||
|
|
||||||
printerr(1, "handling krb5 upcall\n");
|
|
||||||
@@ -701,10 +702,14 @@ handle_krb5_upcall(struct clnt_info *clp)
|
|
||||||
|
|
||||||
if (uid != 0 || (uid == 0 && root_uses_machine_creds == 0)) {
|
|
||||||
/* Tell krb5 gss which credentials cache to use */
|
|
||||||
- gssd_setup_krb5_user_gss_ccache(uid, clp->servername);
|
|
||||||
+ for (dirname = ccachesearch; *dirname != NULL; dirname++) {
|
|
||||||
+ gssd_setup_krb5_user_gss_ccache(uid, clp->servername, *dirname);
|
|
||||||
|
|
||||||
- create_resp = create_auth_rpc_client(clp, &rpc_clnt, &auth, uid,
|
|
||||||
- AUTHTYPE_KRB5);
|
|
||||||
+ create_resp = create_auth_rpc_client(clp, &rpc_clnt, &auth, uid,
|
|
||||||
+ AUTHTYPE_KRB5);
|
|
||||||
+ if (create_resp == 0)
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
if (create_resp != 0) {
|
|
||||||
if (uid == 0 && root_uses_machine_creds == 1) {
|
|
||||||
diff --git a/utils/gssd/krb5_util.c b/utils/gssd/krb5_util.c
|
|
||||||
index 0589cd8..512c1cf 100644
|
|
||||||
--- a/utils/gssd/krb5_util.c
|
|
||||||
+++ b/utils/gssd/krb5_util.c
|
|
||||||
@@ -131,7 +131,8 @@ struct gssd_k5_kt_princ *gssd_k5_kt_princ_list = NULL;
|
|
||||||
/*==========================*/
|
|
||||||
|
|
||||||
static int select_krb5_ccache(const struct dirent *d);
|
|
||||||
-static int gssd_find_existing_krb5_ccache(uid_t uid, struct dirent **d);
|
|
||||||
+static int gssd_find_existing_krb5_ccache(uid_t uid, char *dirname,
|
|
||||||
+ struct dirent **d);
|
|
||||||
static int gssd_get_single_krb5_cred(krb5_context context,
|
|
||||||
krb5_keytab kt, struct gssd_k5_kt_princ *ple);
|
|
||||||
|
|
||||||
@@ -159,7 +160,7 @@ select_krb5_ccache(const struct dirent *d)
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
- * Look in the ccachedir for files that look like they
|
|
||||||
+ * Look in directory "dirname" for files that look like they
|
|
||||||
* are Kerberos Credential Cache files for a given UID. Return
|
|
||||||
* non-zero and the dirent pointer for the entry most likely to be
|
|
||||||
* what we want. Otherwise, return zero and no dirent pointer.
|
|
||||||
@@ -170,7 +171,7 @@ select_krb5_ccache(const struct dirent *d)
|
|
||||||
* 1 => found an existing entry
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
-gssd_find_existing_krb5_ccache(uid_t uid, struct dirent **d)
|
|
||||||
+gssd_find_existing_krb5_ccache(uid_t uid, char *dirname, struct dirent **d)
|
|
||||||
{
|
|
||||||
struct dirent **namelist;
|
|
||||||
int n;
|
|
||||||
@@ -181,9 +182,10 @@ gssd_find_existing_krb5_ccache(uid_t uid, struct dirent **d)
|
|
||||||
|
|
||||||
memset(&best_match_stat, 0, sizeof(best_match_stat));
|
|
||||||
*d = NULL;
|
|
||||||
- n = scandir(ccachedir, &namelist, select_krb5_ccache, 0);
|
|
||||||
+ n = scandir(dirname, &namelist, select_krb5_ccache, 0);
|
|
||||||
if (n < 0) {
|
|
||||||
- perror("scandir looking for krb5 credentials caches");
|
|
||||||
+ printerr(1, "Error doing scandir on directory '%s': %s\n",
|
|
||||||
+ dirname, strerror(errno));
|
|
||||||
}
|
|
||||||
else if (n > 0) {
|
|
||||||
char statname[1024];
|
|
||||||
@@ -191,7 +193,7 @@ gssd_find_existing_krb5_ccache(uid_t uid, struct dirent **d)
|
|
||||||
printerr(3, "CC file '%s' being considered\n",
|
|
||||||
namelist[i]->d_name);
|
|
||||||
snprintf(statname, sizeof(statname),
|
|
||||||
- "%s/%s", ccachedir, namelist[i]->d_name);
|
|
||||||
+ "%s/%s", dirname, namelist[i]->d_name);
|
|
||||||
if (lstat(statname, &tmp_stat)) {
|
|
||||||
printerr(0, "Error doing stat on file '%s'\n",
|
|
||||||
statname);
|
|
||||||
@@ -291,8 +293,9 @@ limit_krb5_enctypes(struct rpc_gss_sec *sec, uid_t uid)
|
|
||||||
&credh, NULL, NULL);
|
|
||||||
|
|
||||||
if (maj_stat != GSS_S_COMPLETE) {
|
|
||||||
- pgsserr("gss_acquire_cred",
|
|
||||||
- maj_stat, min_stat, &krb5oid);
|
|
||||||
+ if (get_verbosity() > 0)
|
|
||||||
+ pgsserr("gss_acquire_cred",
|
|
||||||
+ maj_stat, min_stat, &krb5oid);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -406,7 +409,7 @@ gssd_get_single_krb5_cred(krb5_context context,
|
|
||||||
cache_type = "FILE";
|
|
||||||
snprintf(cc_name, sizeof(cc_name), "%s:%s/%s%s_%s",
|
|
||||||
cache_type,
|
|
||||||
- ccachedir, GSSD_DEFAULT_CRED_PREFIX,
|
|
||||||
+ ccachesearch[0], GSSD_DEFAULT_CRED_PREFIX,
|
|
||||||
GSSD_DEFAULT_MACHINE_CRED_SUFFIX, ple->realm);
|
|
||||||
ple->endtime = my_creds.times.endtime;
|
|
||||||
if (ple->ccname != NULL)
|
|
||||||
@@ -894,7 +897,7 @@ out:
|
|
||||||
* void
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
-gssd_setup_krb5_user_gss_ccache(uid_t uid, char *servername)
|
|
||||||
+gssd_setup_krb5_user_gss_ccache(uid_t uid, char *servername, char *dirname)
|
|
||||||
{
|
|
||||||
char buf[MAX_NETOBJ_SZ];
|
|
||||||
struct dirent *d;
|
|
||||||
@@ -902,14 +905,13 @@ gssd_setup_krb5_user_gss_ccache(uid_t uid, char *servername)
|
|
||||||
printerr(2, "getting credentials for client with uid %u for "
|
|
||||||
"server %s\n", uid, servername);
|
|
||||||
memset(buf, 0, sizeof(buf));
|
|
||||||
- if (gssd_find_existing_krb5_ccache(uid, &d)) {
|
|
||||||
- snprintf(buf, sizeof(buf), "FILE:%s/%s",
|
|
||||||
- ccachedir, d->d_name);
|
|
||||||
+ if (gssd_find_existing_krb5_ccache(uid, dirname, &d)) {
|
|
||||||
+ snprintf(buf, sizeof(buf), "FILE:%s/%s", dirname, d->d_name);
|
|
||||||
free(d);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
snprintf(buf, sizeof(buf), "FILE:%s/%s%u",
|
|
||||||
- ccachedir, GSSD_DEFAULT_CRED_PREFIX, uid);
|
|
||||||
+ dirname, GSSD_DEFAULT_CRED_PREFIX, uid);
|
|
||||||
printerr(2, "using %s as credentials cache for client with "
|
|
||||||
"uid %u for server %s\n", buf, uid, servername);
|
|
||||||
gssd_set_krb5_ccache_name(buf);
|
|
||||||
diff --git a/utils/gssd/krb5_util.h b/utils/gssd/krb5_util.h
|
|
||||||
index 78ad45c..431fdaf 100644
|
|
||||||
--- a/utils/gssd/krb5_util.h
|
|
||||||
+++ b/utils/gssd/krb5_util.h
|
|
||||||
@@ -17,7 +17,8 @@ struct gssd_k5_kt_princ {
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
-void gssd_setup_krb5_user_gss_ccache(uid_t uid, char *servername);
|
|
||||||
+void gssd_setup_krb5_user_gss_ccache(uid_t uid, char *servername,
|
|
||||||
+ char *dirname);
|
|
||||||
int gssd_get_krb5_machine_cred_list(char ***list);
|
|
||||||
void gssd_free_krb5_machine_cred_list(char **list);
|
|
||||||
void gssd_setup_krb5_machine_gss_ccache(char *servername);
|
|
@ -1,25 +0,0 @@
|
|||||||
commit 313ab396c04afe160ee6764e28b5e61ce19c46d9
|
|
||||||
Author: Kevin Coffman <kwc@citi.umich.edu>
|
|
||||||
Date: Wed May 7 14:32:45 2008 -0400
|
|
||||||
|
|
||||||
Add the other two DES encryption types to the default list of
|
|
||||||
Kerberos encryption types that may be negotiated.
|
|
||||||
|
|
||||||
Signed-off-by: Kevin Coffman <kwc@citi.umich.edu>
|
|
||||||
Signed-off-by: Steve Dickson <steved@redhat.com>
|
|
||||||
|
|
||||||
diff --git a/utils/gssd/krb5_util.c b/utils/gssd/krb5_util.c
|
|
||||||
index 3cf27ca..0589cd8 100644
|
|
||||||
--- a/utils/gssd/krb5_util.c
|
|
||||||
+++ b/utils/gssd/krb5_util.c
|
|
||||||
@@ -277,7 +277,9 @@ limit_krb5_enctypes(struct rpc_gss_sec *sec, uid_t uid)
|
|
||||||
u_int maj_stat, min_stat;
|
|
||||||
gss_cred_id_t credh;
|
|
||||||
gss_OID_set_desc desired_mechs;
|
|
||||||
- krb5_enctype enctypes[] = { ENCTYPE_DES_CBC_CRC };
|
|
||||||
+ krb5_enctype enctypes[] = { ENCTYPE_DES_CBC_CRC,
|
|
||||||
+ ENCTYPE_DES_CBC_MD5,
|
|
||||||
+ ENCTYPE_DES_CBC_MD4 };
|
|
||||||
int num_enctypes = sizeof(enctypes) / sizeof(enctypes[0]);
|
|
||||||
|
|
||||||
/* We only care about getting a krb5 cred */
|
|
@ -1,84 +0,0 @@
|
|||||||
commit a04f8b5a3ea94b7a9d96d339b6ccde5f2e67a2d1
|
|
||||||
Author: Olga Kornievskaia <aglo@citi.umich.edu>
|
|
||||||
Date: Wed May 7 10:54:51 2008 -0400
|
|
||||||
|
|
||||||
Check the info file nfs/rpc_pipefs/nfs/clnt?/info to
|
|
||||||
see if a port number was supplied. If so, use it rather
|
|
||||||
than the default port number.
|
|
||||||
|
|
||||||
Signed-off-by: Olga Kornievskaia <aglo@citi.umich.edu>
|
|
||||||
Signed-off-by: Kevin Coffman <kwc@citi.umich.edu>
|
|
||||||
Signed-off-by: Steve Dickson <steved@redhat.com>
|
|
||||||
|
|
||||||
diff --git a/utils/gssd/gssd.h b/utils/gssd/gssd.h
|
|
||||||
index e17edde..6f14c34 100644
|
|
||||||
--- a/utils/gssd/gssd.h
|
|
||||||
+++ b/utils/gssd/gssd.h
|
|
||||||
@@ -80,6 +80,7 @@ struct clnt_info {
|
|
||||||
int krb5_poll_index;
|
|
||||||
int spkm3_fd;
|
|
||||||
int spkm3_poll_index;
|
|
||||||
+ int port;
|
|
||||||
};
|
|
||||||
|
|
||||||
void init_client_list(void);
|
|
||||||
diff --git a/utils/gssd/gssd_proc.c b/utils/gssd/gssd_proc.c
|
|
||||||
index 6860cc8..bac7295 100644
|
|
||||||
--- a/utils/gssd/gssd_proc.c
|
|
||||||
+++ b/utils/gssd/gssd_proc.c
|
|
||||||
@@ -102,7 +102,7 @@ int pollsize; /* the size of pollaray (in pollfd's) */
|
|
||||||
/* XXX buffer problems: */
|
|
||||||
static int
|
|
||||||
read_service_info(char *info_file_name, char **servicename, char **servername,
|
|
||||||
- int *prog, int *vers, char **protocol) {
|
|
||||||
+ int *prog, int *vers, char **protocol, int *port) {
|
|
||||||
#define INFOBUFLEN 256
|
|
||||||
char buf[INFOBUFLEN];
|
|
||||||
static char dummy[128];
|
|
||||||
@@ -112,6 +112,8 @@ read_service_info(char *info_file_name, char **servicename, char **servername,
|
|
||||||
char program[16];
|
|
||||||
char version[16];
|
|
||||||
char protoname[16];
|
|
||||||
+ char cb_port[128];
|
|
||||||
+ char *p;
|
|
||||||
in_addr_t inaddr;
|
|
||||||
int fd = -1;
|
|
||||||
struct hostent *ent = NULL;
|
|
||||||
@@ -143,6 +145,10 @@ read_service_info(char *info_file_name, char **servicename, char **servername,
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ cb_port[0] = '\0';
|
|
||||||
+ if ((p = strstr(buf, "port")) != NULL)
|
|
||||||
+ sscanf(p, "port: %127s\n", cb_port);
|
|
||||||
+
|
|
||||||
/* check service, program, and version */
|
|
||||||
if(memcmp(service, "nfs", 3)) return -1;
|
|
||||||
*prog = atoi(program + 1); /* skip open paren */
|
|
||||||
@@ -163,6 +169,8 @@ read_service_info(char *info_file_name, char **servicename, char **servername,
|
|
||||||
if (!(*servicename = calloc(strlen(buf) + 1, 1)))
|
|
||||||
goto fail;
|
|
||||||
memcpy(*servicename, buf, strlen(buf));
|
|
||||||
+ if (cb_port[0] != '\0')
|
|
||||||
+ *port = atoi(cb_port);
|
|
||||||
|
|
||||||
if (!(*protocol = strdup(protoname)))
|
|
||||||
goto fail;
|
|
||||||
@@ -238,7 +246,7 @@ process_clnt_dir_files(struct clnt_info * clp)
|
|
||||||
if ((clp->servicename == NULL) &&
|
|
||||||
read_service_info(info_file_name, &clp->servicename,
|
|
||||||
&clp->servername, &clp->prog, &clp->vers,
|
|
||||||
- &clp->protocol))
|
|
||||||
+ &clp->protocol, &clp->port))
|
|
||||||
return -1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -587,6 +595,8 @@ int create_auth_rpc_client(struct clnt_info *clp,
|
|
||||||
clp->servername, uid);
|
|
||||||
goto out_fail;
|
|
||||||
}
|
|
||||||
+ if (clp->port)
|
|
||||||
+ ((struct sockaddr_in *)a->ai_addr)->sin_port = htons(clp->port);
|
|
||||||
if (a->ai_protocol == IPPROTO_TCP) {
|
|
||||||
if ((rpc_clnt = clnttcp_create(
|
|
||||||
(struct sockaddr_in *) a->ai_addr,
|
|
@ -1,35 +0,0 @@
|
|||||||
commit 73f9b4402ec6625618967f947c99e6e417322d36
|
|
||||||
Author: Kevin Coffman <kwc@citi.umich.edu>
|
|
||||||
Date: Wed May 7 14:38:47 2008 -0400
|
|
||||||
|
|
||||||
Add a new function to retrieve the current verbosity level
|
|
||||||
so that some messages that would otherwise always print may
|
|
||||||
be silenced.
|
|
||||||
|
|
||||||
Signed-off-by: Kevin Coffman <kwc@citi.umich.edu>
|
|
||||||
Signed-off-by: Steve Dickson <steved@redhat.com>
|
|
||||||
|
|
||||||
diff --git a/utils/gssd/err_util.c b/utils/gssd/err_util.c
|
|
||||||
index 5644db6..2583e06 100644
|
|
||||||
--- a/utils/gssd/err_util.c
|
|
||||||
+++ b/utils/gssd/err_util.c
|
|
||||||
@@ -60,3 +60,8 @@ void printerr(int priority, char *format, ...)
|
|
||||||
xlog_backend(L_ERROR, format, args);
|
|
||||||
va_end(args);
|
|
||||||
}
|
|
||||||
+
|
|
||||||
+int get_verbosity(void)
|
|
||||||
+{
|
|
||||||
+ return verbosity;
|
|
||||||
+}
|
|
||||||
diff --git a/utils/gssd/err_util.h b/utils/gssd/err_util.h
|
|
||||||
index 5e5af48..c4df32d 100644
|
|
||||||
--- a/utils/gssd/err_util.h
|
|
||||||
+++ b/utils/gssd/err_util.h
|
|
||||||
@@ -33,5 +33,6 @@
|
|
||||||
|
|
||||||
void initerr(char *progname, int verbosity, int fg);
|
|
||||||
void printerr(int priority, char *format, ...);
|
|
||||||
+int get_verbosity(void);
|
|
||||||
|
|
||||||
#endif /* _ERR_UTIL_H_ */
|
|
@ -1,42 +0,0 @@
|
|||||||
commit 281ca299724f24e7b19c1eca04bba03410e2a306
|
|
||||||
Author: Jeff Layton <jlaton@redhat.com>
|
|
||||||
Date: Wed May 7 10:35:30 2008 -0400
|
|
||||||
|
|
||||||
The bg option is essentially ignored with nfs4 currently. nfs4mount()
|
|
||||||
will never exit with EX_BG, so the mount will never be backgrounded.
|
|
||||||
Fix it so that when bg is specified that we error out with EX_BG as
|
|
||||||
soon as possible after the first failed mount attempt.
|
|
||||||
|
|
||||||
Signed-off-by: Jeff Layton <jlayton@redhat.com>
|
|
||||||
Signed-off-by: Steve Dickson <steved@redhat.com>
|
|
||||||
|
|
||||||
diff --git a/utils/mount/nfs4mount.c b/utils/mount/nfs4mount.c
|
|
||||||
index af70551..2b0fe2e 100644
|
|
||||||
--- a/utils/mount/nfs4mount.c
|
|
||||||
+++ b/utils/mount/nfs4mount.c
|
|
||||||
@@ -188,10 +188,9 @@ int nfs4mount(const char *spec, const char *node, int flags,
|
|
||||||
int bg, soft, intr;
|
|
||||||
int nocto, noac, unshared;
|
|
||||||
int retry;
|
|
||||||
- int retval;
|
|
||||||
+ int retval = EX_FAIL;
|
|
||||||
time_t timeout, t;
|
|
||||||
|
|
||||||
- retval = EX_FAIL;
|
|
||||||
if (strlen(spec) >= sizeof(hostdir)) {
|
|
||||||
nfs_error(_("%s: excessively long host:dir argument\n"),
|
|
||||||
progname);
|
|
||||||
@@ -443,6 +442,13 @@ int nfs4mount(const char *spec, const char *node, int flags,
|
|
||||||
rpc_mount_errors(hostname, 0, bg);
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
+
|
|
||||||
+ if (bg && !running_bg) {
|
|
||||||
+ if (retry > 0)
|
|
||||||
+ retval = EX_BG;
|
|
||||||
+ goto fail;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
t = time(NULL);
|
|
||||||
if (t >= timeout) {
|
|
||||||
rpc_mount_errors(hostname, 0, bg);
|
|
@ -1,30 +0,0 @@
|
|||||||
commit 0930b25ee3a1eb28b957cdc70c9a1958812d895f
|
|
||||||
Author: NeilBrown <neilb@suse.de>
|
|
||||||
Date: Thu May 8 05:18:25 2008 -0400
|
|
||||||
|
|
||||||
If mount.nfs is not installed setuid, an attempt to perform a "user"
|
|
||||||
or "users" mount will fail with a fairly obscure error message,
|
|
||||||
typically about getting "permission denied" from the server.
|
|
||||||
|
|
||||||
This patch gives a more helpful message in that case.
|
|
||||||
|
|
||||||
Signed-off-by: NeilBrown <neilb@suse.de>
|
|
||||||
Signed-off-by: Steve Dickson <steved@redhat.com>
|
|
||||||
|
|
||||||
diff --git a/utils/mount/mount.c b/utils/mount/mount.c
|
|
||||||
index 5076468..d7271a1 100644
|
|
||||||
--- a/utils/mount/mount.c
|
|
||||||
+++ b/utils/mount/mount.c
|
|
||||||
@@ -539,6 +539,12 @@ int main(int argc, char *argv[])
|
|
||||||
mnt_err = EX_USAGE;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
+
|
|
||||||
+ if (geteuid() != 0) {
|
|
||||||
+ nfs_error(_("%s: not installed setuid - "
|
|
||||||
+ "\"user\" NFS mounts not supported."), progname);
|
|
||||||
+ exit(EX_FAIL);
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
|
|
||||||
if (chk_mountpoint(mount_point)) {
|
|
@ -1,458 +0,0 @@
|
|||||||
commit c641800eb0fcaa819199e58e5c4c8d1c2a9dab5d
|
|
||||||
Author: Chuck Lever <chuck.lever@oracle.com>
|
|
||||||
Date: Fri Jun 6 15:06:21 2008 -0400
|
|
||||||
|
|
||||||
Clean up: instead of passing so many arguments to all the helpers, have
|
|
||||||
nfsmount_string build a data structure that contains all the arguments, and
|
|
||||||
pass a pointer to that instead.
|
|
||||||
|
|
||||||
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
|
|
||||||
Signed-off-by: Steve Dickson <steved@redhat.com>
|
|
||||||
|
|
||||||
diff --git a/utils/mount/stropts.c b/utils/mount/stropts.c
|
|
||||||
index ad5bdee..3564f15 100644
|
|
||||||
--- a/utils/mount/stropts.c
|
|
||||||
+++ b/utils/mount/stropts.c
|
|
||||||
@@ -77,12 +77,26 @@ extern int nfs_mount_data_version;
|
|
||||||
extern char *progname;
|
|
||||||
extern int verbose;
|
|
||||||
|
|
||||||
-static int parse_devname(const char *spec, char **hostname)
|
|
||||||
+struct nfsmount_info {
|
|
||||||
+ const char *spec, /* server:/path */
|
|
||||||
+ *node, /* mounted-on dir */
|
|
||||||
+ *type; /* "nfs" or "nfs4" */
|
|
||||||
+ char *hostname; /* server's hostname */
|
|
||||||
+
|
|
||||||
+ struct mount_options *options; /* parsed mount options */
|
|
||||||
+ char **extra_opts; /* string for /etc/mtab */
|
|
||||||
+
|
|
||||||
+ int flags, /* MS_ flags */
|
|
||||||
+ fake, /* actually do the mount? */
|
|
||||||
+ child; /* forked bg child? */
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+static int nfs_parse_devname(struct nfsmount_info *mi)
|
|
||||||
{
|
|
||||||
int ret = 0;
|
|
||||||
char *dev, *pathname, *s;
|
|
||||||
|
|
||||||
- dev = xstrdup(spec);
|
|
||||||
+ dev = xstrdup(mi->spec);
|
|
||||||
|
|
||||||
if (!(pathname = strchr(dev, ':'))) {
|
|
||||||
nfs_error(_("%s: remote share not in 'host:dir' format"),
|
|
||||||
@@ -113,11 +127,12 @@ static int parse_devname(const char *spec, char **hostname)
|
|
||||||
nfs_error(_("%s: ignoring hostnames that follow the first one"),
|
|
||||||
progname);
|
|
||||||
}
|
|
||||||
- *hostname = xstrdup(dev);
|
|
||||||
- if (strlen(*hostname) > NFS_MAXHOSTNAME) {
|
|
||||||
+ mi->hostname = xstrdup(dev);
|
|
||||||
+ if (strlen(mi->hostname) > NFS_MAXHOSTNAME) {
|
|
||||||
nfs_error(_("%s: server hostname is too long"),
|
|
||||||
progname);
|
|
||||||
- free(*hostname);
|
|
||||||
+ free(mi->hostname);
|
|
||||||
+ mi->hostname = NULL;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -273,28 +288,30 @@ static int verify_lock_option(struct mount_options *options)
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
- * Set up mandatory mount options.
|
|
||||||
+ * Set up mandatory NFS mount options.
|
|
||||||
*
|
|
||||||
* Returns 1 if successful; otherwise zero.
|
|
||||||
*/
|
|
||||||
-static int validate_options(const char *type,
|
|
||||||
- struct sockaddr_in *saddr,
|
|
||||||
- struct mount_options *options,
|
|
||||||
- int fake)
|
|
||||||
+static int nfs_validate_options(struct nfsmount_info *mi)
|
|
||||||
{
|
|
||||||
- if (!append_addr_option(saddr, options))
|
|
||||||
+ struct sockaddr_in saddr;
|
|
||||||
+
|
|
||||||
+ if (!fill_ipv4_sockaddr(mi->hostname, &saddr))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
- if (strncmp(type, "nfs4", 4) == 0) {
|
|
||||||
- if (!append_clientaddr_option(saddr, options))
|
|
||||||
+ if (strncmp(mi->type, "nfs4", 4) == 0) {
|
|
||||||
+ if (!append_clientaddr_option(&saddr, mi->options))
|
|
||||||
return 0;
|
|
||||||
} else {
|
|
||||||
- if (!fix_mounthost_option(options))
|
|
||||||
+ if (!fix_mounthost_option(mi->options))
|
|
||||||
return 0;
|
|
||||||
- if (!fake && !verify_lock_option(options))
|
|
||||||
+ if (!mi->fake && !verify_lock_option(mi->options))
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ if (!append_addr_option(&saddr, mi->options))
|
|
||||||
+ return 0;
|
|
||||||
+
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -443,6 +460,27 @@ err:
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
+ * Do the mount(2) system call.
|
|
||||||
+ *
|
|
||||||
+ * Returns 1 if successful, otherwise zero.
|
|
||||||
+ * "errno" is set to reflect the individual error.
|
|
||||||
+ */
|
|
||||||
+static int nfs_sys_mount(const struct nfsmount_info *mi, const char *type,
|
|
||||||
+ const char *options)
|
|
||||||
+{
|
|
||||||
+ int result;
|
|
||||||
+
|
|
||||||
+ result = mount(mi->spec, mi->node, type,
|
|
||||||
+ mi->flags & ~(MS_USER|MS_USERS), options);
|
|
||||||
+ if (verbose && result) {
|
|
||||||
+ int save = errno;
|
|
||||||
+ nfs_error(_("%s: mount(2): %s"), progname, strerror(save));
|
|
||||||
+ errno = save;
|
|
||||||
+ }
|
|
||||||
+ return !result;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+/*
|
|
||||||
* Retry an NFS mount that failed because the requested service isn't
|
|
||||||
* available on the server.
|
|
||||||
*
|
|
||||||
@@ -453,12 +491,11 @@ err:
|
|
||||||
* 'extra_opts' are updated to reflect the mount options that worked.
|
|
||||||
* If the retry fails, 'options' and 'extra_opts' are left unchanged.
|
|
||||||
*/
|
|
||||||
-static int retry_nfsmount(const char *spec, const char *node,
|
|
||||||
- int flags, struct mount_options *options,
|
|
||||||
- int fake, char **extra_opts)
|
|
||||||
+static int nfs_retry_nfs23mount(struct nfsmount_info *mi)
|
|
||||||
{
|
|
||||||
struct mount_options *retry_options;
|
|
||||||
char *retry_str = NULL;
|
|
||||||
+ char **extra_opts = mi->extra_opts;
|
|
||||||
|
|
||||||
retry_options = rewrite_mount_options(*extra_opts);
|
|
||||||
if (!retry_options) {
|
|
||||||
@@ -476,17 +513,16 @@ static int retry_nfsmount(const char *spec, const char *node,
|
|
||||||
printf(_("%s: text-based options (retry): '%s'\n"),
|
|
||||||
progname, retry_str);
|
|
||||||
|
|
||||||
- if (!mount(spec, node, "nfs",
|
|
||||||
- flags & ~(MS_USER|MS_USERS), retry_str)) {
|
|
||||||
- free(*extra_opts);
|
|
||||||
- *extra_opts = retry_str;
|
|
||||||
- po_replace(options, retry_options);
|
|
||||||
- return 1;
|
|
||||||
+ if (!nfs_sys_mount(mi, "nfs", retry_str)) {
|
|
||||||
+ po_destroy(retry_options);
|
|
||||||
+ free(retry_str);
|
|
||||||
+ return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
- po_destroy(retry_options);
|
|
||||||
- free(retry_str);
|
|
||||||
- return 0;
|
|
||||||
+ free(*extra_opts);
|
|
||||||
+ *extra_opts = retry_str;
|
|
||||||
+ po_replace(mi->options, retry_options);
|
|
||||||
+ return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
@@ -502,11 +538,11 @@ static int retry_nfsmount(const char *spec, const char *node,
|
|
||||||
* 'extra_opts' are updated to reflect the mount options that worked.
|
|
||||||
* If the retry fails, 'options' and 'extra_opts' are left unchanged.
|
|
||||||
*/
|
|
||||||
-static int try_nfs23mount(const char *spec, const char *node,
|
|
||||||
- int flags, struct mount_options *options,
|
|
||||||
- int fake, char **extra_opts)
|
|
||||||
+static int nfs_try_nfs23mount(struct nfsmount_info *mi)
|
|
||||||
{
|
|
||||||
- if (po_join(options, extra_opts) == PO_FAILED) {
|
|
||||||
+ char **extra_opts = mi->extra_opts;
|
|
||||||
+
|
|
||||||
+ if (po_join(mi->options, extra_opts) == PO_FAILED) {
|
|
||||||
errno = EIO;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -515,11 +551,10 @@ static int try_nfs23mount(const char *spec, const char *node,
|
|
||||||
printf(_("%s: text-based options: '%s'\n"),
|
|
||||||
progname, *extra_opts);
|
|
||||||
|
|
||||||
- if (fake)
|
|
||||||
+ if (mi->fake)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
- if (!mount(spec, node, "nfs",
|
|
||||||
- flags & ~(MS_USER|MS_USERS), *extra_opts))
|
|
||||||
+ if (nfs_sys_mount(mi, "nfs", *extra_opts))
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
/*
|
|
||||||
@@ -529,7 +564,7 @@ static int try_nfs23mount(const char *spec, const char *node,
|
|
||||||
if (errno != EOPNOTSUPP && errno != EPROTONOSUPPORT)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
- return retry_nfsmount(spec, node, flags, options, fake, extra_opts);
|
|
||||||
+ return nfs_retry_nfs23mount(mi);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
@@ -538,11 +573,11 @@ static int try_nfs23mount(const char *spec, const char *node,
|
|
||||||
* Returns 1 if successful. Otherwise, returns zero.
|
|
||||||
* "errno" is set to reflect the individual error.
|
|
||||||
*/
|
|
||||||
-static int try_nfs4mount(const char *spec, const char *node,
|
|
||||||
- int flags, struct mount_options *options,
|
|
||||||
- int fake, char **extra_opts)
|
|
||||||
+static int nfs_try_nfs4mount(struct nfsmount_info *mi)
|
|
||||||
{
|
|
||||||
- if (po_join(options, extra_opts) == PO_FAILED) {
|
|
||||||
+ char **extra_opts = mi->extra_opts;
|
|
||||||
+
|
|
||||||
+ if (po_join(mi->options, extra_opts) == PO_FAILED) {
|
|
||||||
errno = EIO;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -551,31 +586,24 @@ static int try_nfs4mount(const char *spec, const char *node,
|
|
||||||
printf(_("%s: text-based options: '%s'\n"),
|
|
||||||
progname, *extra_opts);
|
|
||||||
|
|
||||||
- if (fake)
|
|
||||||
+ if (mi->fake)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
- if (!mount(spec, node, "nfs4",
|
|
||||||
- flags & ~(MS_USER|MS_USERS), *extra_opts))
|
|
||||||
- return 1;
|
|
||||||
- return 0;
|
|
||||||
+ return nfs_sys_mount(mi, "nfs4", *extra_opts);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
- * Try the mount(2) system call.
|
|
||||||
+ * Perform either an NFSv2/3 mount, or an NFSv4 mount system call.
|
|
||||||
*
|
|
||||||
* Returns 1 if successful. Otherwise, returns zero.
|
|
||||||
* "errno" is set to reflect the individual error.
|
|
||||||
*/
|
|
||||||
-static int try_mount(const char *spec, const char *node, const char *type,
|
|
||||||
- int flags, struct mount_options *options, int fake,
|
|
||||||
- char **extra_opts)
|
|
||||||
+static int nfs_try_mount(struct nfsmount_info *mi)
|
|
||||||
{
|
|
||||||
- if (strncmp(type, "nfs4", 4) == 0)
|
|
||||||
- return try_nfs4mount(spec, node, flags,
|
|
||||||
- options, fake, extra_opts);
|
|
||||||
+ if (strncmp(mi->type, "nfs4", 4) == 0)
|
|
||||||
+ return nfs_try_nfs4mount(mi);
|
|
||||||
else
|
|
||||||
- return try_nfs23mount(spec, node, flags,
|
|
||||||
- options, fake, extra_opts);
|
|
||||||
+ return nfs_try_nfs23mount(mi);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
@@ -585,22 +613,19 @@ static int try_mount(const char *spec, const char *node, const char *type,
|
|
||||||
*
|
|
||||||
* Returns a valid mount command exit code.
|
|
||||||
*/
|
|
||||||
-static int nfsmount_fg(const char *spec, const char *node,
|
|
||||||
- const char *type, int flags,
|
|
||||||
- struct mount_options *options, int fake,
|
|
||||||
- char **extra_opts)
|
|
||||||
+static int nfsmount_fg(struct nfsmount_info *mi)
|
|
||||||
{
|
|
||||||
unsigned int secs = 1;
|
|
||||||
time_t timeout;
|
|
||||||
|
|
||||||
- timeout = nfs_parse_retry_option(options, NFS_DEF_FG_TIMEOUT_MINUTES);
|
|
||||||
+ timeout = nfs_parse_retry_option(mi->options,
|
|
||||||
+ NFS_DEF_FG_TIMEOUT_MINUTES);
|
|
||||||
if (verbose)
|
|
||||||
printf(_("%s: timeout set for %s"),
|
|
||||||
progname, ctime(&timeout));
|
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
- if (try_mount(spec, node, type, flags,
|
|
||||||
- options, fake, extra_opts))
|
|
||||||
+ if (nfs_try_mount(mi))
|
|
||||||
return EX_SUCCESS;
|
|
||||||
|
|
||||||
if (is_permanent_error(errno))
|
|
||||||
@@ -620,7 +645,7 @@ static int nfsmount_fg(const char *spec, const char *node,
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
- mount_error(spec, node, errno);
|
|
||||||
+ mount_error(mi->spec, mi->node, errno);
|
|
||||||
return EX_FAIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -631,21 +656,17 @@ static int nfsmount_fg(const char *spec, const char *node,
|
|
||||||
*
|
|
||||||
* EX_BG should cause the caller to fork and invoke nfsmount_child.
|
|
||||||
*/
|
|
||||||
-static int nfsmount_parent(const char *spec, const char *node,
|
|
||||||
- const char *type, char *hostname, int flags,
|
|
||||||
- struct mount_options *options,
|
|
||||||
- int fake, char **extra_opts)
|
|
||||||
+static int nfsmount_parent(struct nfsmount_info *mi)
|
|
||||||
{
|
|
||||||
- if (try_mount(spec, node, type, flags, options,
|
|
||||||
- fake, extra_opts))
|
|
||||||
+ if (nfs_try_mount(mi))
|
|
||||||
return EX_SUCCESS;
|
|
||||||
|
|
||||||
if (is_permanent_error(errno)) {
|
|
||||||
- mount_error(spec, node, errno);
|
|
||||||
+ mount_error(mi->spec, mi->node, errno);
|
|
||||||
return EX_FAIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
- sys_mount_errors(hostname, errno, 1, 1);
|
|
||||||
+ sys_mount_errors(mi->hostname, errno, 1, 1);
|
|
||||||
return EX_BG;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -657,15 +678,13 @@ static int nfsmount_parent(const char *spec, const char *node,
|
|
||||||
* error return, though, so we use sys_mount_errors to log the
|
|
||||||
* failure.
|
|
||||||
*/
|
|
||||||
-static int nfsmount_child(const char *spec, const char *node,
|
|
||||||
- const char *type, char *hostname, int flags,
|
|
||||||
- struct mount_options *options,
|
|
||||||
- int fake, char **extra_opts)
|
|
||||||
+static int nfsmount_child(struct nfsmount_info *mi)
|
|
||||||
{
|
|
||||||
unsigned int secs = 1;
|
|
||||||
time_t timeout;
|
|
||||||
|
|
||||||
- timeout = nfs_parse_retry_option(options, NFS_DEF_BG_TIMEOUT_MINUTES);
|
|
||||||
+ timeout = nfs_parse_retry_option(mi->options,
|
|
||||||
+ NFS_DEF_BG_TIMEOUT_MINUTES);
|
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
if (sleep(secs))
|
|
||||||
@@ -674,8 +693,7 @@ static int nfsmount_child(const char *spec, const char *node,
|
|
||||||
if (secs > 120)
|
|
||||||
secs = 120;
|
|
||||||
|
|
||||||
- if (try_mount(spec, node, type, flags, options,
|
|
||||||
- fake, extra_opts))
|
|
||||||
+ if (nfs_try_mount(mi))
|
|
||||||
return EX_SUCCESS;
|
|
||||||
|
|
||||||
if (is_permanent_error(errno))
|
|
||||||
@@ -684,10 +702,10 @@ static int nfsmount_child(const char *spec, const char *node,
|
|
||||||
if (time(NULL) > timeout)
|
|
||||||
break;
|
|
||||||
|
|
||||||
- sys_mount_errors(hostname, errno, 1, 1);
|
|
||||||
+ sys_mount_errors(mi->hostname, errno, 1, 1);
|
|
||||||
};
|
|
||||||
|
|
||||||
- sys_mount_errors(hostname, errno, 1, 0);
|
|
||||||
+ sys_mount_errors(mi->hostname, errno, 1, 0);
|
|
||||||
return EX_FAIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -696,17 +714,28 @@ static int nfsmount_child(const char *spec, const char *node,
|
|
||||||
*
|
|
||||||
* Returns a valid mount command exit code.
|
|
||||||
*/
|
|
||||||
-static int nfsmount_bg(const char *spec, const char *node,
|
|
||||||
- const char *type, char *hostname, int flags,
|
|
||||||
- struct mount_options *options,
|
|
||||||
- int fake, int child, char **extra_opts)
|
|
||||||
+static int nfsmount_bg(struct nfsmount_info *mi)
|
|
||||||
{
|
|
||||||
- if (!child)
|
|
||||||
- return nfsmount_parent(spec, node, type, hostname, flags,
|
|
||||||
- options, fake, extra_opts);
|
|
||||||
+ if (!mi->child)
|
|
||||||
+ return nfsmount_parent(mi);
|
|
||||||
+ else
|
|
||||||
+ return nfsmount_child(mi);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+/*
|
|
||||||
+ * Process mount options and try a mount system call.
|
|
||||||
+ *
|
|
||||||
+ * Returns a valid mount command exit code.
|
|
||||||
+ */
|
|
||||||
+static int nfsmount_start(struct nfsmount_info *mi)
|
|
||||||
+{
|
|
||||||
+ if (!nfs_validate_options(mi))
|
|
||||||
+ return EX_FAIL;
|
|
||||||
+
|
|
||||||
+ if (po_rightmost(mi->options, "bg", "fg") == PO_KEY1_RIGHTMOST)
|
|
||||||
+ return nfsmount_bg(mi);
|
|
||||||
else
|
|
||||||
- return nfsmount_child(spec, node, type, hostname, flags,
|
|
||||||
- options, fake, extra_opts);
|
|
||||||
+ return nfsmount_fg(mi);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
@@ -723,35 +752,27 @@ static int nfsmount_bg(const char *spec, const char *node,
|
|
||||||
int nfsmount_string(const char *spec, const char *node, const char *type,
|
|
||||||
int flags, char **extra_opts, int fake, int child)
|
|
||||||
{
|
|
||||||
- struct mount_options *options = NULL;
|
|
||||||
- struct sockaddr_in saddr;
|
|
||||||
- char *hostname;
|
|
||||||
+ struct nfsmount_info mi = {
|
|
||||||
+ .spec = spec,
|
|
||||||
+ .node = node,
|
|
||||||
+ .type = type,
|
|
||||||
+ .extra_opts = extra_opts,
|
|
||||||
+ .flags = flags,
|
|
||||||
+ .fake = fake,
|
|
||||||
+ .child = child,
|
|
||||||
+ };
|
|
||||||
int retval = EX_FAIL;
|
|
||||||
|
|
||||||
- if (!parse_devname(spec, &hostname))
|
|
||||||
+ if (!nfs_parse_devname(&mi))
|
|
||||||
return retval;
|
|
||||||
- if (!fill_ipv4_sockaddr(hostname, &saddr))
|
|
||||||
- goto fail;
|
|
||||||
|
|
||||||
- options = po_split(*extra_opts);
|
|
||||||
- if (!options) {
|
|
||||||
+ mi.options = po_split(*extra_opts);
|
|
||||||
+ if (mi.options) {
|
|
||||||
+ retval = nfsmount_start(&mi);
|
|
||||||
+ po_destroy(mi.options);
|
|
||||||
+ } else
|
|
||||||
nfs_error(_("%s: internal option parsing error"), progname);
|
|
||||||
- goto fail;
|
|
||||||
- }
|
|
||||||
|
|
||||||
- if (!validate_options(type, &saddr, options, fake))
|
|
||||||
- goto out;
|
|
||||||
-
|
|
||||||
- if (po_rightmost(options, "bg", "fg") == PO_KEY1_RIGHTMOST)
|
|
||||||
- retval = nfsmount_bg(spec, node, type, hostname, flags,
|
|
||||||
- options, fake, child, extra_opts);
|
|
||||||
- else
|
|
||||||
- retval = nfsmount_fg(spec, node, type, flags, options,
|
|
||||||
- fake, extra_opts);
|
|
||||||
-
|
|
||||||
-out:
|
|
||||||
- po_destroy(options);
|
|
||||||
-fail:
|
|
||||||
- free(hostname);
|
|
||||||
+ free(mi.hostname);
|
|
||||||
return retval;
|
|
||||||
}
|
|
@ -1,26 +0,0 @@
|
|||||||
commit 697e28939b7d0a3e0ffe3b6bd516213a55f5a063
|
|
||||||
Author: Jeff Layton <jlaton@redhat.com>
|
|
||||||
Date: Mon Apr 14 09:03:13 2008 -0400
|
|
||||||
|
|
||||||
Change how mount.nfs handles EACCES errors. Currently,
|
|
||||||
EACCES is a non-fatal error which means the mount will be
|
|
||||||
retied. This caused mounts to hang for 2mins when the client
|
|
||||||
does not have permission to access the export. In a strict
|
|
||||||
interpretation, the error that should be returned is EPERM, but
|
|
||||||
this is not always the case. So due to the fuzzy interpretation,
|
|
||||||
of EPERM and EACCES, EACCESS is now a fatal error
|
|
||||||
|
|
||||||
Signed-off-by: Steve Dickson <steved@redhat.com>
|
|
||||||
|
|
||||||
diff --git a/utils/mount/stropts.c b/utils/mount/stropts.c
|
|
||||||
index cadb1f4..cdd610e 100644
|
|
||||||
--- a/utils/mount/stropts.c
|
|
||||||
+++ b/utils/mount/stropts.c
|
|
||||||
@@ -252,7 +252,6 @@ static int set_mandatory_options(const char *type,
|
|
||||||
static int is_permanent_error(int error)
|
|
||||||
{
|
|
||||||
switch (error) {
|
|
||||||
- case EACCES:
|
|
||||||
case ESTALE:
|
|
||||||
case ETIMEDOUT:
|
|
||||||
case ECONNREFUSED:
|
|
@ -1,66 +0,0 @@
|
|||||||
commit 52dff26c60c07cf1b4fbf8fbd3a1eab7ba90405f
|
|
||||||
Author: Chuck Lever <chuck.lever@oracle.com>
|
|
||||||
Date: Fri Jun 6 15:07:24 2008 -0400
|
|
||||||
|
|
||||||
Fix error reporting when probe_bothports() fails while rewriting mount
|
|
||||||
options.
|
|
||||||
|
|
||||||
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
|
|
||||||
Signed-off-by: Steve Dickson <steved@redhat.com>
|
|
||||||
|
|
||||||
diff --git a/utils/mount/error.c b/utils/mount/error.c
|
|
||||||
index 23a91ff..147e919 100644
|
|
||||||
--- a/utils/mount/error.c
|
|
||||||
+++ b/utils/mount/error.c
|
|
||||||
@@ -227,6 +227,9 @@ void mount_error(const char *spec, const char *mount_point, int error)
|
|
||||||
nfs_error(_("%s: mount point %s does not exist"),
|
|
||||||
progname, mount_point);
|
|
||||||
break;
|
|
||||||
+ case ESPIPE:
|
|
||||||
+ rpc_mount_errors((char *)spec, 0, 0);
|
|
||||||
+ break;
|
|
||||||
case EIO:
|
|
||||||
case EFAULT:
|
|
||||||
nfs_error(_("%s: internal error"), progname);
|
|
||||||
diff --git a/utils/mount/stropts.c b/utils/mount/stropts.c
|
|
||||||
index 3564f15..967fd69 100644
|
|
||||||
--- a/utils/mount/stropts.c
|
|
||||||
+++ b/utils/mount/stropts.c
|
|
||||||
@@ -356,6 +356,8 @@ static struct mount_options *rewrite_mount_options(char *str)
|
|
||||||
clnt_addr_t nfs_server = { };
|
|
||||||
int p;
|
|
||||||
|
|
||||||
+ errno = EIO;
|
|
||||||
+
|
|
||||||
options = po_split(str);
|
|
||||||
if (!options)
|
|
||||||
return NULL;
|
|
||||||
@@ -426,7 +428,7 @@ static struct mount_options *rewrite_mount_options(char *str)
|
|
||||||
po_remove_all(options, "udp");
|
|
||||||
|
|
||||||
if (!probe_bothports(&mnt_server, &nfs_server)) {
|
|
||||||
- rpc_mount_errors("rpcbind", 0, 0);
|
|
||||||
+ errno = ESPIPE;
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -452,6 +454,7 @@ static struct mount_options *rewrite_mount_options(char *str)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
+ errno = 0;
|
|
||||||
return options;
|
|
||||||
|
|
||||||
err:
|
|
||||||
@@ -498,10 +501,8 @@ static int nfs_retry_nfs23mount(struct nfsmount_info *mi)
|
|
||||||
char **extra_opts = mi->extra_opts;
|
|
||||||
|
|
||||||
retry_options = rewrite_mount_options(*extra_opts);
|
|
||||||
- if (!retry_options) {
|
|
||||||
- errno = EIO;
|
|
||||||
+ if (!retry_options)
|
|
||||||
return 0;
|
|
||||||
- }
|
|
||||||
|
|
||||||
if (po_join(retry_options, &retry_str) == PO_FAILED) {
|
|
||||||
po_destroy(retry_options);
|
|
@ -1,51 +0,0 @@
|
|||||||
commit 5fb4042ce4eb4fd5e50e3fb0f78bbd20b4d46e78
|
|
||||||
Author: Jeff Layton <jlaton@redhat.com>
|
|
||||||
Date: Wed May 7 10:37:40 2008 -0400
|
|
||||||
|
|
||||||
The prev_bg_host stuff made sense when NFS didn't have its own mount
|
|
||||||
handler. Now though, each mount.nfs invocation is really a one-shot
|
|
||||||
affair, and this check no longer works. It also leaked memory. Remove
|
|
||||||
it.
|
|
||||||
|
|
||||||
Signed-off-by: Jeff Layton <jlayton@redhat.com>
|
|
||||||
Signed-off-by: Steve Dickson <steved@redhat.com>
|
|
||||||
|
|
||||||
diff --git a/utils/mount/nfsmount.c b/utils/mount/nfsmount.c
|
|
||||||
index a9dd917..6a04518 100644
|
|
||||||
--- a/utils/mount/nfsmount.c
|
|
||||||
+++ b/utils/mount/nfsmount.c
|
|
||||||
@@ -494,7 +494,6 @@ int
|
|
||||||
nfsmount(const char *spec, const char *node, int flags,
|
|
||||||
char **extra_opts, int fake, int running_bg)
|
|
||||||
{
|
|
||||||
- static char *prev_bg_host;
|
|
||||||
char hostdir[1024];
|
|
||||||
char *hostname, *dirname, *old_opts, *mounthost = NULL;
|
|
||||||
char new_opts[1024], cbuf[1024];
|
|
||||||
@@ -628,18 +627,6 @@ nfsmount(const char *spec, const char *node, int flags,
|
|
||||||
if (flags & MS_REMOUNT)
|
|
||||||
goto out_ok;
|
|
||||||
|
|
||||||
- /*
|
|
||||||
- * If the previous mount operation on the same host was
|
|
||||||
- * backgrounded, and the "bg" for this mount is also set,
|
|
||||||
- * give up immediately, to avoid the initial timeout.
|
|
||||||
- */
|
|
||||||
- if (bg && !running_bg &&
|
|
||||||
- prev_bg_host && strcmp(hostname, prev_bg_host) == 0) {
|
|
||||||
- if (retry > 0)
|
|
||||||
- retval = EX_BG;
|
|
||||||
- return retval;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
/* create mount deamon client */
|
|
||||||
|
|
||||||
/*
|
|
||||||
@@ -708,7 +695,6 @@ nfsmount(const char *spec, const char *node, int flags,
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!running_bg) {
|
|
||||||
- prev_bg_host = xstrdup(hostname);
|
|
||||||
if (retry > 0)
|
|
||||||
retval = EX_BG;
|
|
||||||
goto fail;
|
|
@ -1,106 +0,0 @@
|
|||||||
commit d7a1070383bcf40d32c7f10e535ba443209dedef
|
|
||||||
Author: Chuck Lever <chuck.lever@oracle.com>
|
|
||||||
Date: Fri Jun 6 15:02:18 2008 -0400
|
|
||||||
|
|
||||||
Steinar Gunderson reports:
|
|
||||||
|
|
||||||
"It seems retry= is now additive with the text-based mount interface. In
|
|
||||||
particular, "mount -o retry=0" still gives a two-minute timeout."
|
|
||||||
|
|
||||||
Correct the bug and make retry= option parsing more robust. If parsing
|
|
||||||
the retry option fails, the option is ignored and a default timeout is
|
|
||||||
used.
|
|
||||||
|
|
||||||
Note that currently the kernel parser ignores the "retry=" option if the
|
|
||||||
value is a number. If the value contains other characters, the kernel will
|
|
||||||
choke. A subsequent patch to the kernel will allow any characters as the
|
|
||||||
value of the retry option (excepting of course ",").
|
|
||||||
|
|
||||||
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
|
|
||||||
Signed-off-by: Steve Dickson <steved@redhat.com>
|
|
||||||
|
|
||||||
diff --git a/utils/mount/stropts.c b/utils/mount/stropts.c
|
|
||||||
index b2b56be..ad5bdee 100644
|
|
||||||
--- a/utils/mount/stropts.c
|
|
||||||
+++ b/utils/mount/stropts.c
|
|
||||||
@@ -65,6 +65,14 @@
|
|
||||||
#define NFS_MAXPATHNAME (1024)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
+#ifndef NFS_DEF_FG_TIMEOUT_MINUTES
|
|
||||||
+#define NFS_DEF_FG_TIMEOUT_MINUTES (2u)
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
+#ifndef NFS_DEF_BG_TIMEOUT_MINUTES
|
|
||||||
+#define NFS_DEF_BG_TIMEOUT_MINUTES (10000u)
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
extern int nfs_mount_data_version;
|
|
||||||
extern char *progname;
|
|
||||||
extern int verbose;
|
|
||||||
@@ -141,6 +149,32 @@ static int fill_ipv4_sockaddr(const char *hostname, struct sockaddr_in *addr)
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
+ * Obtain a retry timeout value based on the value of the "retry=" option.
|
|
||||||
+ *
|
|
||||||
+ * Returns a time_t timeout timestamp, in seconds.
|
|
||||||
+ */
|
|
||||||
+static time_t nfs_parse_retry_option(struct mount_options *options,
|
|
||||||
+ unsigned int timeout_minutes)
|
|
||||||
+{
|
|
||||||
+ char *retry_option, *endptr;
|
|
||||||
+
|
|
||||||
+ retry_option = po_get(options, "retry");
|
|
||||||
+ if (retry_option) {
|
|
||||||
+ long tmp;
|
|
||||||
+
|
|
||||||
+ errno = 0;
|
|
||||||
+ tmp = strtol(retry_option, &endptr, 10);
|
|
||||||
+ if (errno == 0 && endptr != retry_option && tmp >= 0)
|
|
||||||
+ timeout_minutes = tmp;
|
|
||||||
+ else if (verbose)
|
|
||||||
+ nfs_error(_("%s: invalid retry timeout was specified; "
|
|
||||||
+ "using default timeout"), progname);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return time(NULL) + (time_t)(timeout_minutes * 60);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+/*
|
|
||||||
* Append the 'addr=' option to the options string to pass a resolved
|
|
||||||
* server address to the kernel. After a successful mount, this address
|
|
||||||
* is also added to /etc/mtab for use when unmounting.
|
|
||||||
@@ -557,14 +591,9 @@ static int nfsmount_fg(const char *spec, const char *node,
|
|
||||||
char **extra_opts)
|
|
||||||
{
|
|
||||||
unsigned int secs = 1;
|
|
||||||
- time_t timeout = time(NULL);
|
|
||||||
- char *retry;
|
|
||||||
-
|
|
||||||
- timeout += 60 * 2; /* default: 2 minutes */
|
|
||||||
- retry = po_get(options, "retry");
|
|
||||||
- if (retry)
|
|
||||||
- timeout += 60 * atoi(retry);
|
|
||||||
+ time_t timeout;
|
|
||||||
|
|
||||||
+ timeout = nfs_parse_retry_option(options, NFS_DEF_FG_TIMEOUT_MINUTES);
|
|
||||||
if (verbose)
|
|
||||||
printf(_("%s: timeout set for %s"),
|
|
||||||
progname, ctime(&timeout));
|
|
||||||
@@ -634,13 +663,9 @@ static int nfsmount_child(const char *spec, const char *node,
|
|
||||||
int fake, char **extra_opts)
|
|
||||||
{
|
|
||||||
unsigned int secs = 1;
|
|
||||||
- time_t timeout = time(NULL);
|
|
||||||
- char *retry;
|
|
||||||
+ time_t timeout;
|
|
||||||
|
|
||||||
- timeout += 60 * 10000; /* default: 10,000 minutes */
|
|
||||||
- retry = po_get(options, "retry");
|
|
||||||
- if (retry)
|
|
||||||
- timeout += 60 * atoi(retry);
|
|
||||||
+ timeout = nfs_parse_retry_option(options, NFS_DEF_BG_TIMEOUT_MINUTES);
|
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
if (sleep(secs))
|
|
@ -1,71 +0,0 @@
|
|||||||
commit 331c2ca949d5b4b4d18d0aca90afb8ae9475bcd6
|
|
||||||
Author: Neil Brown <neilb@suse.de>
|
|
||||||
Date: Fri Jun 6 14:59:21 2008 -0400
|
|
||||||
|
|
||||||
Make the text-based mount path check whether statd is running if the "lock"
|
|
||||||
option is in effect. This echoes similar logic in the legacy mount path.
|
|
||||||
|
|
||||||
Signed-off-by: Neil Brown <neilb@suse.de>
|
|
||||||
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
|
|
||||||
Signed-off-by: Steve Dickson <steved@redhat.com>
|
|
||||||
|
|
||||||
diff --git a/utils/mount/stropts.c b/utils/mount/stropts.c
|
|
||||||
index cdd610e..b2b56be 100644
|
|
||||||
--- a/utils/mount/stropts.c
|
|
||||||
+++ b/utils/mount/stropts.c
|
|
||||||
@@ -219,13 +219,34 @@ static int fix_mounthost_option(struct mount_options *options)
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
+ * Returns zero if the "lock" option is in effect, but statd
|
|
||||||
+ * can't be started. Otherwise, returns 1.
|
|
||||||
+ */
|
|
||||||
+static int verify_lock_option(struct mount_options *options)
|
|
||||||
+{
|
|
||||||
+ if (po_rightmost(options, "nolock", "lock") == PO_KEY1_RIGHTMOST)
|
|
||||||
+ return 1;
|
|
||||||
+
|
|
||||||
+ if (!start_statd()) {
|
|
||||||
+ nfs_error(_("%s: rpc.statd is not running but is "
|
|
||||||
+ "required for remote locking."), progname);
|
|
||||||
+ nfs_error(_("%s: Either use '-o nolock' to keep "
|
|
||||||
+ "locks local, or start statd."), progname);
|
|
||||||
+ return 0;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return 1;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+/*
|
|
||||||
* Set up mandatory mount options.
|
|
||||||
*
|
|
||||||
* Returns 1 if successful; otherwise zero.
|
|
||||||
*/
|
|
||||||
-static int set_mandatory_options(const char *type,
|
|
||||||
- struct sockaddr_in *saddr,
|
|
||||||
- struct mount_options *options)
|
|
||||||
+static int validate_options(const char *type,
|
|
||||||
+ struct sockaddr_in *saddr,
|
|
||||||
+ struct mount_options *options,
|
|
||||||
+ int fake)
|
|
||||||
{
|
|
||||||
if (!append_addr_option(saddr, options))
|
|
||||||
return 0;
|
|
||||||
@@ -236,6 +257,8 @@ static int set_mandatory_options(const char *type,
|
|
||||||
} else {
|
|
||||||
if (!fix_mounthost_option(options))
|
|
||||||
return 0;
|
|
||||||
+ if (!fake && !verify_lock_option(options))
|
|
||||||
+ return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
@@ -691,7 +714,7 @@ int nfsmount_string(const char *spec, const char *node, const char *type,
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
- if (!set_mandatory_options(type, &saddr, options))
|
|
||||||
+ if (!validate_options(type, &saddr, options, fake))
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
if (po_rightmost(options, "bg", "fg") == PO_KEY1_RIGHTMOST)
|
|
@ -1,42 +0,0 @@
|
|||||||
commit 589a913e42476a965b686c9f2656b786eaae399e
|
|
||||||
Author: Tom Talpey <tmt@netapp.com>
|
|
||||||
Date: Mon Jun 23 12:54:08 2008 -0400
|
|
||||||
|
|
||||||
Add RDMA as a supported transport for reporting the
|
|
||||||
mountstats statistics
|
|
||||||
|
|
||||||
Signed-off-by: Tom Talpey <tmt@netapp.com>
|
|
||||||
Acked-by: Chuck Lever <chuck.lever@oracle.com>
|
|
||||||
Signed-off-by: Steve Dickson <steved@redhat.com>
|
|
||||||
|
|
||||||
diff --git a/tools/mountstats/mountstats.py b/tools/mountstats/mountstats.py
|
|
||||||
index 5f20db6..f55595e 100644
|
|
||||||
--- a/tools/mountstats/mountstats.py
|
|
||||||
+++ b/tools/mountstats/mountstats.py
|
|
||||||
@@ -116,6 +116,26 @@ class DeviceData:
|
|
||||||
self.__rpc_data['badxids'] = int(words[9])
|
|
||||||
self.__rpc_data['inflightsends'] = long(words[10])
|
|
||||||
self.__rpc_data['backlogutil'] = int(words[11])
|
|
||||||
+ elif words[1] == 'rdma':
|
|
||||||
+ self.__rpc_data['port'] = words[2]
|
|
||||||
+ self.__rpc_data['bind_count'] = int(words[3])
|
|
||||||
+ self.__rpc_data['connect_count'] = int(words[4])
|
|
||||||
+ self.__rpc_data['connect_time'] = int(words[5])
|
|
||||||
+ self.__rpc_data['idle_time'] = int(words[6])
|
|
||||||
+ self.__rpc_data['rpcsends'] = int(words[7])
|
|
||||||
+ self.__rpc_data['rpcreceives'] = int(words[8])
|
|
||||||
+ self.__rpc_data['badxids'] = int(words[9])
|
|
||||||
+ self.__rpc_data['backlogutil'] = int(words[10])
|
|
||||||
+ self.__rpc_data['read_chunks'] = int(words[11])
|
|
||||||
+ self.__rpc_data['write_chunks'] = int(words[12])
|
|
||||||
+ self.__rpc_data['reply_chunks'] = int(words[13])
|
|
||||||
+ self.__rpc_data['total_rdma_req'] = int(words[14])
|
|
||||||
+ self.__rpc_data['total_rdma_rep'] = int(words[15])
|
|
||||||
+ self.__rpc_data['pullup'] = int(words[16])
|
|
||||||
+ self.__rpc_data['fixup'] = int(words[17])
|
|
||||||
+ self.__rpc_data['hardway'] = int(words[18])
|
|
||||||
+ self.__rpc_data['failed_marshal'] = int(words[19])
|
|
||||||
+ self.__rpc_data['bad_reply'] = int(words[20])
|
|
||||||
elif words[0] == 'per-op':
|
|
||||||
self.__rpc_data['per-op'] = words
|
|
||||||
else:
|
|
@ -1,605 +0,0 @@
|
|||||||
commit c761709ad3abb9c36a68c269f78118bf49d79639
|
|
||||||
Author: Chuck Lever <chuck.lever@oracle.com>
|
|
||||||
Date: Mon Jun 23 12:52:33 2008 -0400
|
|
||||||
|
|
||||||
The "mountstats" utility is a Python program that extracts and displays NFS
|
|
||||||
client performance information from /proc/self/mountstats.
|
|
||||||
|
|
||||||
Note that if mountstats is named 'ms-nfsstat' or 'ms-iostat' it offers
|
|
||||||
slightly different functionality. It needs two man pages and the install
|
|
||||||
script should provide both commands by installing the script and providing the
|
|
||||||
other command via a symlink.
|
|
||||||
|
|
||||||
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
|
|
||||||
Signed-off-by: Steve Dickson <steved@redhat.com>
|
|
||||||
|
|
||||||
diff --git a/tools/mountstats/mountstats.py b/tools/mountstats/mountstats.py
|
|
||||||
new file mode 100644
|
|
||||||
index 0000000..5f20db6
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/tools/mountstats/mountstats.py
|
|
||||||
@@ -0,0 +1,584 @@
|
|
||||||
+#!/usr/bin/env python
|
|
||||||
+# -*- python-mode -*-
|
|
||||||
+"""Parse /proc/self/mountstats and display it in human readable form
|
|
||||||
+"""
|
|
||||||
+
|
|
||||||
+__copyright__ = """
|
|
||||||
+Copyright (C) 2005, Chuck Lever <cel@netapp.com>
|
|
||||||
+
|
|
||||||
+This program is free software; you can redistribute it and/or modify
|
|
||||||
+it under the terms of the GNU General Public License version 2 as
|
|
||||||
+published by the Free Software Foundation.
|
|
||||||
+
|
|
||||||
+This program is distributed in the hope that it will be useful,
|
|
||||||
+but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
+GNU General Public License for more details.
|
|
||||||
+
|
|
||||||
+You should have received a copy of the GNU General Public License
|
|
||||||
+along with this program; if not, write to the Free Software
|
|
||||||
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
+"""
|
|
||||||
+
|
|
||||||
+import sys, os, time
|
|
||||||
+
|
|
||||||
+Mountstats_version = '0.2'
|
|
||||||
+
|
|
||||||
+def difference(x, y):
|
|
||||||
+ """Used for a map() function
|
|
||||||
+ """
|
|
||||||
+ return x - y
|
|
||||||
+
|
|
||||||
+class DeviceData:
|
|
||||||
+ """DeviceData objects provide methods for parsing and displaying
|
|
||||||
+ data for a single mount grabbed from /proc/self/mountstats
|
|
||||||
+ """
|
|
||||||
+ def __init__(self):
|
|
||||||
+ self.__nfs_data = dict()
|
|
||||||
+ self.__rpc_data = dict()
|
|
||||||
+ self.__rpc_data['ops'] = []
|
|
||||||
+
|
|
||||||
+ def __parse_nfs_line(self, words):
|
|
||||||
+ if words[0] == 'device':
|
|
||||||
+ self.__nfs_data['export'] = words[1]
|
|
||||||
+ self.__nfs_data['mountpoint'] = words[4]
|
|
||||||
+ self.__nfs_data['fstype'] = words[7]
|
|
||||||
+ if words[7].find('nfs') != -1:
|
|
||||||
+ self.__nfs_data['statvers'] = words[8]
|
|
||||||
+ elif words[0] == 'age:':
|
|
||||||
+ self.__nfs_data['age'] = long(words[1])
|
|
||||||
+ elif words[0] == 'opts:':
|
|
||||||
+ self.__nfs_data['mountoptions'] = ''.join(words[1:]).split(',')
|
|
||||||
+ elif words[0] == 'caps:':
|
|
||||||
+ self.__nfs_data['servercapabilities'] = ''.join(words[1:]).split(',')
|
|
||||||
+ elif words[0] == 'nfsv4:':
|
|
||||||
+ self.__nfs_data['nfsv4flags'] = ''.join(words[1:]).split(',')
|
|
||||||
+ elif words[0] == 'sec:':
|
|
||||||
+ keys = ''.join(words[1:]).split(',')
|
|
||||||
+ self.__nfs_data['flavor'] = int(keys[0].split('=')[1])
|
|
||||||
+ self.__nfs_data['pseudoflavor'] = 0
|
|
||||||
+ if self.__nfs_data['flavor'] == 6:
|
|
||||||
+ self.__nfs_data['pseudoflavor'] = int(keys[1].split('=')[1])
|
|
||||||
+ elif words[0] == 'events:':
|
|
||||||
+ self.__nfs_data['inoderevalidates'] = int(words[1])
|
|
||||||
+ self.__nfs_data['dentryrevalidates'] = int(words[2])
|
|
||||||
+ self.__nfs_data['datainvalidates'] = int(words[3])
|
|
||||||
+ self.__nfs_data['attrinvalidates'] = int(words[4])
|
|
||||||
+ self.__nfs_data['syncinodes'] = int(words[5])
|
|
||||||
+ self.__nfs_data['vfsopen'] = int(words[6])
|
|
||||||
+ self.__nfs_data['vfslookup'] = int(words[7])
|
|
||||||
+ self.__nfs_data['vfspermission'] = int(words[8])
|
|
||||||
+ self.__nfs_data['vfsreadpage'] = int(words[9])
|
|
||||||
+ self.__nfs_data['vfsreadpages'] = int(words[10])
|
|
||||||
+ self.__nfs_data['vfswritepage'] = int(words[11])
|
|
||||||
+ self.__nfs_data['vfswritepages'] = int(words[12])
|
|
||||||
+ self.__nfs_data['vfsreaddir'] = int(words[13])
|
|
||||||
+ self.__nfs_data['vfsflush'] = int(words[14])
|
|
||||||
+ self.__nfs_data['vfsfsync'] = int(words[15])
|
|
||||||
+ self.__nfs_data['vfslock'] = int(words[16])
|
|
||||||
+ self.__nfs_data['vfsrelease'] = int(words[17])
|
|
||||||
+ self.__nfs_data['setattrtrunc'] = int(words[18])
|
|
||||||
+ self.__nfs_data['extendwrite'] = int(words[19])
|
|
||||||
+ self.__nfs_data['sillyrenames'] = int(words[20])
|
|
||||||
+ self.__nfs_data['shortreads'] = int(words[21])
|
|
||||||
+ self.__nfs_data['shortwrites'] = int(words[22])
|
|
||||||
+ self.__nfs_data['delay'] = int(words[23])
|
|
||||||
+ elif words[0] == 'bytes:':
|
|
||||||
+ self.__nfs_data['normalreadbytes'] = long(words[1])
|
|
||||||
+ self.__nfs_data['normalwritebytes'] = long(words[2])
|
|
||||||
+ self.__nfs_data['directreadbytes'] = long(words[3])
|
|
||||||
+ self.__nfs_data['directwritebytes'] = long(words[4])
|
|
||||||
+ self.__nfs_data['serverreadbytes'] = long(words[5])
|
|
||||||
+ self.__nfs_data['serverwritebytes'] = long(words[6])
|
|
||||||
+
|
|
||||||
+ def __parse_rpc_line(self, words):
|
|
||||||
+ if words[0] == 'RPC':
|
|
||||||
+ self.__rpc_data['statsvers'] = float(words[3])
|
|
||||||
+ self.__rpc_data['programversion'] = words[5]
|
|
||||||
+ elif words[0] == 'xprt:':
|
|
||||||
+ self.__rpc_data['protocol'] = words[1]
|
|
||||||
+ if words[1] == 'udp':
|
|
||||||
+ self.__rpc_data['port'] = int(words[2])
|
|
||||||
+ self.__rpc_data['bind_count'] = int(words[3])
|
|
||||||
+ self.__rpc_data['rpcsends'] = int(words[4])
|
|
||||||
+ self.__rpc_data['rpcreceives'] = int(words[5])
|
|
||||||
+ self.__rpc_data['badxids'] = int(words[6])
|
|
||||||
+ self.__rpc_data['inflightsends'] = long(words[7])
|
|
||||||
+ self.__rpc_data['backlogutil'] = long(words[8])
|
|
||||||
+ elif words[1] == 'tcp':
|
|
||||||
+ self.__rpc_data['port'] = words[2]
|
|
||||||
+ self.__rpc_data['bind_count'] = int(words[3])
|
|
||||||
+ self.__rpc_data['connect_count'] = int(words[4])
|
|
||||||
+ self.__rpc_data['connect_time'] = int(words[5])
|
|
||||||
+ self.__rpc_data['idle_time'] = int(words[6])
|
|
||||||
+ self.__rpc_data['rpcsends'] = int(words[7])
|
|
||||||
+ self.__rpc_data['rpcreceives'] = int(words[8])
|
|
||||||
+ self.__rpc_data['badxids'] = int(words[9])
|
|
||||||
+ self.__rpc_data['inflightsends'] = long(words[10])
|
|
||||||
+ self.__rpc_data['backlogutil'] = int(words[11])
|
|
||||||
+ elif words[0] == 'per-op':
|
|
||||||
+ self.__rpc_data['per-op'] = words
|
|
||||||
+ else:
|
|
||||||
+ op = words[0][:-1]
|
|
||||||
+ self.__rpc_data['ops'] += [op]
|
|
||||||
+ self.__rpc_data[op] = [long(word) for word in words[1:]]
|
|
||||||
+
|
|
||||||
+ def parse_stats(self, lines):
|
|
||||||
+ """Turn a list of lines from a mount stat file into a
|
|
||||||
+ dictionary full of stats, keyed by name
|
|
||||||
+ """
|
|
||||||
+ found = False
|
|
||||||
+ for line in lines:
|
|
||||||
+ words = line.split()
|
|
||||||
+ if len(words) == 0:
|
|
||||||
+ continue
|
|
||||||
+ if (not found and words[0] != 'RPC'):
|
|
||||||
+ self.__parse_nfs_line(words)
|
|
||||||
+ continue
|
|
||||||
+
|
|
||||||
+ found = True
|
|
||||||
+ self.__parse_rpc_line(words)
|
|
||||||
+
|
|
||||||
+ def is_nfs_mountpoint(self):
|
|
||||||
+ """Return True if this is an NFS or NFSv4 mountpoint,
|
|
||||||
+ otherwise return False
|
|
||||||
+ """
|
|
||||||
+ if self.__nfs_data['fstype'] == 'nfs':
|
|
||||||
+ return True
|
|
||||||
+ elif self.__nfs_data['fstype'] == 'nfs4':
|
|
||||||
+ return True
|
|
||||||
+ return False
|
|
||||||
+
|
|
||||||
+ def display_nfs_options(self):
|
|
||||||
+ """Pretty-print the NFS options
|
|
||||||
+ """
|
|
||||||
+ print 'Stats for %s mounted on %s:' % \
|
|
||||||
+ (self.__nfs_data['export'], self.__nfs_data['mountpoint'])
|
|
||||||
+
|
|
||||||
+ print ' NFS mount options: %s' % ','.join(self.__nfs_data['mountoptions'])
|
|
||||||
+ print ' NFS server capabilities: %s' % ','.join(self.__nfs_data['servercapabilities'])
|
|
||||||
+ if self.__nfs_data.has_key('nfsv4flags'):
|
|
||||||
+ print ' NFSv4 capability flags: %s' % ','.join(self.__nfs_data['nfsv4flags'])
|
|
||||||
+ if self.__nfs_data.has_key('pseudoflavor'):
|
|
||||||
+ print ' NFS security flavor: %d pseudoflavor: %d' % \
|
|
||||||
+ (self.__nfs_data['flavor'], self.__nfs_data['pseudoflavor'])
|
|
||||||
+ else:
|
|
||||||
+ print ' NFS security flavor: %d' % self.__nfs_data['flavor']
|
|
||||||
+
|
|
||||||
+ def display_nfs_events(self):
|
|
||||||
+ """Pretty-print the NFS event counters
|
|
||||||
+ """
|
|
||||||
+ print
|
|
||||||
+ print 'Cache events:'
|
|
||||||
+ print ' data cache invalidated %d times' % self.__nfs_data['datainvalidates']
|
|
||||||
+ print ' attribute cache invalidated %d times' % self.__nfs_data['attrinvalidates']
|
|
||||||
+ print ' inodes synced %d times' % self.__nfs_data['syncinodes']
|
|
||||||
+ print
|
|
||||||
+ print 'VFS calls:'
|
|
||||||
+ print ' VFS requested %d inode revalidations' % self.__nfs_data['inoderevalidates']
|
|
||||||
+ print ' VFS requested %d dentry revalidations' % self.__nfs_data['dentryrevalidates']
|
|
||||||
+ print
|
|
||||||
+ print ' VFS called nfs_readdir() %d times' % self.__nfs_data['vfsreaddir']
|
|
||||||
+ print ' VFS called nfs_lookup() %d times' % self.__nfs_data['vfslookup']
|
|
||||||
+ print ' VFS called nfs_permission() %d times' % self.__nfs_data['vfspermission']
|
|
||||||
+ print ' VFS called nfs_file_open() %d times' % self.__nfs_data['vfsopen']
|
|
||||||
+ print ' VFS called nfs_file_flush() %d times' % self.__nfs_data['vfsflush']
|
|
||||||
+ print ' VFS called nfs_lock() %d times' % self.__nfs_data['vfslock']
|
|
||||||
+ print ' VFS called nfs_fsync() %d times' % self.__nfs_data['vfsfsync']
|
|
||||||
+ print ' VFS called nfs_file_release() %d times' % self.__nfs_data['vfsrelease']
|
|
||||||
+ print
|
|
||||||
+ print 'VM calls:'
|
|
||||||
+ print ' VFS called nfs_readpage() %d times' % self.__nfs_data['vfsreadpage']
|
|
||||||
+ print ' VFS called nfs_readpages() %d times' % self.__nfs_data['vfsreadpages']
|
|
||||||
+ print ' VFS called nfs_writepage() %d times' % self.__nfs_data['vfswritepage']
|
|
||||||
+ print ' VFS called nfs_writepages() %d times' % self.__nfs_data['vfswritepages']
|
|
||||||
+ print
|
|
||||||
+ print 'Generic NFS counters:'
|
|
||||||
+ print ' File size changing operations:'
|
|
||||||
+ print ' truncating SETATTRs: %d extending WRITEs: %d' % \
|
|
||||||
+ (self.__nfs_data['setattrtrunc'], self.__nfs_data['extendwrite'])
|
|
||||||
+ print ' %d silly renames' % self.__nfs_data['sillyrenames']
|
|
||||||
+ print ' short reads: %d short writes: %d' % \
|
|
||||||
+ (self.__nfs_data['shortreads'], self.__nfs_data['shortwrites'])
|
|
||||||
+ print ' NFSERR_DELAYs from server: %d' % self.__nfs_data['delay']
|
|
||||||
+
|
|
||||||
+ def display_nfs_bytes(self):
|
|
||||||
+ """Pretty-print the NFS event counters
|
|
||||||
+ """
|
|
||||||
+ print
|
|
||||||
+ print 'NFS byte counts:'
|
|
||||||
+ print ' applications read %d bytes via read(2)' % self.__nfs_data['normalreadbytes']
|
|
||||||
+ print ' applications wrote %d bytes via write(2)' % self.__nfs_data['normalwritebytes']
|
|
||||||
+ print ' applications read %d bytes via O_DIRECT read(2)' % self.__nfs_data['directreadbytes']
|
|
||||||
+ print ' applications wrote %d bytes via O_DIRECT write(2)' % self.__nfs_data['directwritebytes']
|
|
||||||
+ print ' client read %d bytes via NFS READ' % self.__nfs_data['serverreadbytes']
|
|
||||||
+ print ' client wrote %d bytes via NFS WRITE' % self.__nfs_data['serverwritebytes']
|
|
||||||
+
|
|
||||||
+ def display_rpc_generic_stats(self):
|
|
||||||
+ """Pretty-print the generic RPC stats
|
|
||||||
+ """
|
|
||||||
+ sends = self.__rpc_data['rpcsends']
|
|
||||||
+
|
|
||||||
+ print
|
|
||||||
+ print 'RPC statistics:'
|
|
||||||
+
|
|
||||||
+ print ' %d RPC requests sent, %d RPC replies received (%d XIDs not found)' % \
|
|
||||||
+ (sends, self.__rpc_data['rpcreceives'], self.__rpc_data['badxids'])
|
|
||||||
+ if sends != 0:
|
|
||||||
+ print ' average backlog queue length: %d' % \
|
|
||||||
+ (float(self.__rpc_data['backlogutil']) / sends)
|
|
||||||
+
|
|
||||||
+ def display_rpc_op_stats(self):
|
|
||||||
+ """Pretty-print the per-op stats
|
|
||||||
+ """
|
|
||||||
+ sends = self.__rpc_data['rpcsends']
|
|
||||||
+
|
|
||||||
+ # XXX: these should be sorted by 'count'
|
|
||||||
+ print
|
|
||||||
+ for op in self.__rpc_data['ops']:
|
|
||||||
+ stats = self.__rpc_data[op]
|
|
||||||
+ count = stats[0]
|
|
||||||
+ retrans = stats[1] - count
|
|
||||||
+ if count != 0:
|
|
||||||
+ print '%s:' % op
|
|
||||||
+ print '\t%d ops (%d%%)' % \
|
|
||||||
+ (count, ((count * 100) / sends)),
|
|
||||||
+ print '\t%d retrans (%d%%)' % (retrans, ((retrans * 100) / count)),
|
|
||||||
+ print '\t%d major timeouts' % stats[2]
|
|
||||||
+ print '\tavg bytes sent per op: %d\tavg bytes received per op: %d' % \
|
|
||||||
+ (stats[3] / count, stats[4] / count)
|
|
||||||
+ print '\tbacklog wait: %f' % (float(stats[5]) / count),
|
|
||||||
+ print '\tRTT: %f' % (float(stats[6]) / count),
|
|
||||||
+ print '\ttotal execute time: %f (milliseconds)' % \
|
|
||||||
+ (float(stats[7]) / count)
|
|
||||||
+
|
|
||||||
+ def compare_iostats(self, old_stats):
|
|
||||||
+ """Return the difference between two sets of stats
|
|
||||||
+ """
|
|
||||||
+ result = DeviceData()
|
|
||||||
+
|
|
||||||
+ # copy self into result
|
|
||||||
+ for key, value in self.__nfs_data.iteritems():
|
|
||||||
+ result.__nfs_data[key] = value
|
|
||||||
+ for key, value in self.__rpc_data.iteritems():
|
|
||||||
+ result.__rpc_data[key] = value
|
|
||||||
+
|
|
||||||
+ # compute the difference of each item in the list
|
|
||||||
+ # note the copy loop above does not copy the lists, just
|
|
||||||
+ # the reference to them. so we build new lists here
|
|
||||||
+ # for the result object.
|
|
||||||
+ for op in result.__rpc_data['ops']:
|
|
||||||
+ result.__rpc_data[op] = map(difference, self.__rpc_data[op], old_stats.__rpc_data[op])
|
|
||||||
+
|
|
||||||
+ # update the remaining keys we care about
|
|
||||||
+ result.__rpc_data['rpcsends'] -= old_stats.__rpc_data['rpcsends']
|
|
||||||
+ result.__rpc_data['backlogutil'] -= old_stats.__rpc_data['backlogutil']
|
|
||||||
+ result.__nfs_data['serverreadbytes'] -= old_stats.__nfs_data['serverreadbytes']
|
|
||||||
+ result.__nfs_data['serverwritebytes'] -= old_stats.__nfs_data['serverwritebytes']
|
|
||||||
+
|
|
||||||
+ return result
|
|
||||||
+
|
|
||||||
+ def display_iostats(self, sample_time):
|
|
||||||
+ """Display NFS and RPC stats in an iostat-like way
|
|
||||||
+ """
|
|
||||||
+ sends = float(self.__rpc_data['rpcsends'])
|
|
||||||
+ if sample_time == 0:
|
|
||||||
+ sample_time = float(self.__nfs_data['age'])
|
|
||||||
+
|
|
||||||
+ print
|
|
||||||
+ print '%s mounted on %s:' % \
|
|
||||||
+ (self.__nfs_data['export'], self.__nfs_data['mountpoint'])
|
|
||||||
+
|
|
||||||
+ print '\top/s\trpc bklog'
|
|
||||||
+ print '\t%.2f' % (sends / sample_time),
|
|
||||||
+ if sends != 0:
|
|
||||||
+ print '\t%.2f' % \
|
|
||||||
+ ((float(self.__rpc_data['backlogutil']) / sends) / sample_time)
|
|
||||||
+ else:
|
|
||||||
+ print '\t0.00'
|
|
||||||
+
|
|
||||||
+ # reads: ops/s, Kb/s, avg rtt, and avg exe
|
|
||||||
+ # XXX: include avg xfer size and retransmits?
|
|
||||||
+ read_rpc_stats = self.__rpc_data['READ']
|
|
||||||
+ ops = float(read_rpc_stats[0])
|
|
||||||
+ kilobytes = float(self.__nfs_data['serverreadbytes']) / 1024
|
|
||||||
+ rtt = float(read_rpc_stats[6])
|
|
||||||
+ exe = float(read_rpc_stats[7])
|
|
||||||
+
|
|
||||||
+ print '\treads:\tops/s\t\tKb/s\t\tavg RTT (ms)\tavg exe (ms)'
|
|
||||||
+ print '\t\t%.2f' % (ops / sample_time),
|
|
||||||
+ print '\t\t%.2f' % (kilobytes / sample_time),
|
|
||||||
+ if ops != 0:
|
|
||||||
+ print '\t\t%.2f' % (rtt / ops),
|
|
||||||
+ print '\t\t%.2f' % (exe / ops)
|
|
||||||
+ else:
|
|
||||||
+ print '\t\t0.00',
|
|
||||||
+ print '\t\t0.00'
|
|
||||||
+
|
|
||||||
+ # writes: ops/s, Kb/s, avg rtt, and avg exe
|
|
||||||
+ # XXX: include avg xfer size and retransmits?
|
|
||||||
+ write_rpc_stats = self.__rpc_data['WRITE']
|
|
||||||
+ ops = float(write_rpc_stats[0])
|
|
||||||
+ kilobytes = float(self.__nfs_data['serverwritebytes']) / 1024
|
|
||||||
+ rtt = float(write_rpc_stats[6])
|
|
||||||
+ exe = float(write_rpc_stats[7])
|
|
||||||
+
|
|
||||||
+ print '\twrites:\tops/s\t\tKb/s\t\tavg RTT (ms)\tavg exe (ms)'
|
|
||||||
+ print '\t\t%.2f' % (ops / sample_time),
|
|
||||||
+ print '\t\t%.2f' % (kilobytes / sample_time),
|
|
||||||
+ if ops != 0:
|
|
||||||
+ print '\t\t%.2f' % (rtt / ops),
|
|
||||||
+ print '\t\t%.2f' % (exe / ops)
|
|
||||||
+ else:
|
|
||||||
+ print '\t\t0.00',
|
|
||||||
+ print '\t\t0.00'
|
|
||||||
+
|
|
||||||
+def parse_stats_file(filename):
|
|
||||||
+ """pop the contents of a mountstats file into a dictionary,
|
|
||||||
+ keyed by mount point. each value object is a list of the
|
|
||||||
+ lines in the mountstats file corresponding to the mount
|
|
||||||
+ point named in the key.
|
|
||||||
+ """
|
|
||||||
+ ms_dict = dict()
|
|
||||||
+ key = ''
|
|
||||||
+
|
|
||||||
+ f = file(filename)
|
|
||||||
+ for line in f.readlines():
|
|
||||||
+ words = line.split()
|
|
||||||
+ if len(words) == 0:
|
|
||||||
+ continue
|
|
||||||
+ if words[0] == 'device':
|
|
||||||
+ key = words[4]
|
|
||||||
+ new = [ line.strip() ]
|
|
||||||
+ else:
|
|
||||||
+ new += [ line.strip() ]
|
|
||||||
+ ms_dict[key] = new
|
|
||||||
+ f.close
|
|
||||||
+
|
|
||||||
+ return ms_dict
|
|
||||||
+
|
|
||||||
+def print_mountstats_help(name):
|
|
||||||
+ print 'usage: %s [ options ] <mount point>' % name
|
|
||||||
+ print
|
|
||||||
+ print ' Version %s' % Mountstats_version
|
|
||||||
+ print
|
|
||||||
+ print ' Display NFS client per-mount statistics.'
|
|
||||||
+ print
|
|
||||||
+ print ' --version display the version of this command'
|
|
||||||
+ print ' --nfs display only the NFS statistics'
|
|
||||||
+ print ' --rpc display only the RPC statistics'
|
|
||||||
+ print ' --start sample and save statistics'
|
|
||||||
+ print ' --end resample statistics and compare them with saved'
|
|
||||||
+ print
|
|
||||||
+
|
|
||||||
+def mountstats_command():
|
|
||||||
+ """Mountstats command
|
|
||||||
+ """
|
|
||||||
+ mountpoints = []
|
|
||||||
+ nfs_only = False
|
|
||||||
+ rpc_only = False
|
|
||||||
+
|
|
||||||
+ for arg in sys.argv:
|
|
||||||
+ if arg in ['-h', '--help', 'help', 'usage']:
|
|
||||||
+ print_mountstats_help(prog)
|
|
||||||
+ return
|
|
||||||
+
|
|
||||||
+ if arg in ['-v', '--version', 'version']:
|
|
||||||
+ print '%s version %s' % (sys.argv[0], Mountstats_version)
|
|
||||||
+ sys.exit(0)
|
|
||||||
+
|
|
||||||
+ if arg in ['-n', '--nfs']:
|
|
||||||
+ nfs_only = True
|
|
||||||
+ continue
|
|
||||||
+
|
|
||||||
+ if arg in ['-r', '--rpc']:
|
|
||||||
+ rpc_only = True
|
|
||||||
+ continue
|
|
||||||
+
|
|
||||||
+ if arg in ['-s', '--start']:
|
|
||||||
+ raise Exception, 'Sampling is not yet implemented'
|
|
||||||
+
|
|
||||||
+ if arg in ['-e', '--end']:
|
|
||||||
+ raise Exception, 'Sampling is not yet implemented'
|
|
||||||
+
|
|
||||||
+ if arg == sys.argv[0]:
|
|
||||||
+ continue
|
|
||||||
+
|
|
||||||
+ mountpoints += [arg]
|
|
||||||
+
|
|
||||||
+ if mountpoints == []:
|
|
||||||
+ print_mountstats_help(prog)
|
|
||||||
+ return
|
|
||||||
+
|
|
||||||
+ if rpc_only == True and nfs_only == True:
|
|
||||||
+ print_mountstats_help(prog)
|
|
||||||
+ return
|
|
||||||
+
|
|
||||||
+ mountstats = parse_stats_file('/proc/self/mountstats')
|
|
||||||
+
|
|
||||||
+ for mp in mountpoints:
|
|
||||||
+ if mp not in mountstats:
|
|
||||||
+ print 'Statistics for mount point %s not found' % mp
|
|
||||||
+ continue
|
|
||||||
+
|
|
||||||
+ stats = DeviceData()
|
|
||||||
+ stats.parse_stats(mountstats[mp])
|
|
||||||
+
|
|
||||||
+ if not stats.is_nfs_mountpoint():
|
|
||||||
+ print 'Mount point %s exists but is not an NFS mount' % mp
|
|
||||||
+ continue
|
|
||||||
+
|
|
||||||
+ if nfs_only:
|
|
||||||
+ stats.display_nfs_options()
|
|
||||||
+ stats.display_nfs_events()
|
|
||||||
+ stats.display_nfs_bytes()
|
|
||||||
+ elif rpc_only:
|
|
||||||
+ stats.display_rpc_generic_stats()
|
|
||||||
+ stats.display_rpc_op_stats()
|
|
||||||
+ else:
|
|
||||||
+ stats.display_nfs_options()
|
|
||||||
+ stats.display_nfs_bytes()
|
|
||||||
+ stats.display_rpc_generic_stats()
|
|
||||||
+ stats.display_rpc_op_stats()
|
|
||||||
+
|
|
||||||
+def print_nfsstat_help(name):
|
|
||||||
+ print 'usage: %s [ options ]' % name
|
|
||||||
+ print
|
|
||||||
+ print ' Version %s' % Mountstats_version
|
|
||||||
+ print
|
|
||||||
+ print ' nfsstat-like program that uses NFS client per-mount statistics.'
|
|
||||||
+ print
|
|
||||||
+
|
|
||||||
+def nfsstat_command():
|
|
||||||
+ print_nfsstat_help(prog)
|
|
||||||
+
|
|
||||||
+def print_iostat_help(name):
|
|
||||||
+ print 'usage: %s [ <interval> [ <count> ] ] [ <mount point> ] ' % name
|
|
||||||
+ print
|
|
||||||
+ print ' Version %s' % Mountstats_version
|
|
||||||
+ print
|
|
||||||
+ print ' iostat-like program to display NFS client per-mount statistics.'
|
|
||||||
+ print
|
|
||||||
+ print ' The <interval> parameter specifies the amount of time in seconds between'
|
|
||||||
+ print ' each report. The first report contains statistics for the time since each'
|
|
||||||
+ print ' file system was mounted. Each subsequent report contains statistics'
|
|
||||||
+ print ' collected during the interval since the previous report.'
|
|
||||||
+ print
|
|
||||||
+ print ' If the <count> parameter is specified, the value of <count> determines the'
|
|
||||||
+ print ' number of reports generated at <interval> seconds apart. If the interval'
|
|
||||||
+ print ' parameter is specified without the <count> parameter, the command generates'
|
|
||||||
+ print ' reports continuously.'
|
|
||||||
+ print
|
|
||||||
+ print ' If one or more <mount point> names are specified, statistics for only these'
|
|
||||||
+ print ' mount points will be displayed. Otherwise, all NFS mount points on the'
|
|
||||||
+ print ' client are listed.'
|
|
||||||
+ print
|
|
||||||
+
|
|
||||||
+def print_iostat_summary(old, new, devices, time):
|
|
||||||
+ for device in devices:
|
|
||||||
+ stats = DeviceData()
|
|
||||||
+ stats.parse_stats(new[device])
|
|
||||||
+ if not old:
|
|
||||||
+ stats.display_iostats(time)
|
|
||||||
+ else:
|
|
||||||
+ old_stats = DeviceData()
|
|
||||||
+ old_stats.parse_stats(old[device])
|
|
||||||
+ diff_stats = stats.compare_iostats(old_stats)
|
|
||||||
+ diff_stats.display_iostats(time)
|
|
||||||
+
|
|
||||||
+def iostat_command():
|
|
||||||
+ """iostat-like command for NFS mount points
|
|
||||||
+ """
|
|
||||||
+ mountstats = parse_stats_file('/proc/self/mountstats')
|
|
||||||
+ devices = []
|
|
||||||
+ interval_seen = False
|
|
||||||
+ count_seen = False
|
|
||||||
+
|
|
||||||
+ for arg in sys.argv:
|
|
||||||
+ if arg in ['-h', '--help', 'help', 'usage']:
|
|
||||||
+ print_iostat_help(prog)
|
|
||||||
+ return
|
|
||||||
+
|
|
||||||
+ if arg in ['-v', '--version', 'version']:
|
|
||||||
+ print '%s version %s' % (sys.argv[0], Mountstats_version)
|
|
||||||
+ return
|
|
||||||
+
|
|
||||||
+ if arg == sys.argv[0]:
|
|
||||||
+ continue
|
|
||||||
+
|
|
||||||
+ if arg in mountstats:
|
|
||||||
+ devices += [arg]
|
|
||||||
+ elif not interval_seen:
|
|
||||||
+ interval = int(arg)
|
|
||||||
+ if interval > 0:
|
|
||||||
+ interval_seen = True
|
|
||||||
+ else:
|
|
||||||
+ print 'Illegal <interval> value'
|
|
||||||
+ return
|
|
||||||
+ elif not count_seen:
|
|
||||||
+ count = int(arg)
|
|
||||||
+ if count > 0:
|
|
||||||
+ count_seen = True
|
|
||||||
+ else:
|
|
||||||
+ print 'Illegal <count> value'
|
|
||||||
+ return
|
|
||||||
+
|
|
||||||
+ # make certain devices contains only NFS mount points
|
|
||||||
+ if len(devices) > 0:
|
|
||||||
+ check = []
|
|
||||||
+ for device in devices:
|
|
||||||
+ stats = DeviceData()
|
|
||||||
+ stats.parse_stats(mountstats[device])
|
|
||||||
+ if stats.is_nfs_mountpoint():
|
|
||||||
+ check += [device]
|
|
||||||
+ devices = check
|
|
||||||
+ else:
|
|
||||||
+ for device, descr in mountstats.iteritems():
|
|
||||||
+ stats = DeviceData()
|
|
||||||
+ stats.parse_stats(descr)
|
|
||||||
+ if stats.is_nfs_mountpoint():
|
|
||||||
+ devices += [device]
|
|
||||||
+ if len(devices) == 0:
|
|
||||||
+ print 'No NFS mount points were found'
|
|
||||||
+ return
|
|
||||||
+
|
|
||||||
+ old_mountstats = None
|
|
||||||
+ sample_time = 0
|
|
||||||
+
|
|
||||||
+ if not interval_seen:
|
|
||||||
+ print_iostat_summary(old_mountstats, mountstats, devices, sample_time)
|
|
||||||
+ return
|
|
||||||
+
|
|
||||||
+ if count_seen:
|
|
||||||
+ while count != 0:
|
|
||||||
+ print_iostat_summary(old_mountstats, mountstats, devices, sample_time)
|
|
||||||
+ old_mountstats = mountstats
|
|
||||||
+ time.sleep(interval)
|
|
||||||
+ sample_time = interval
|
|
||||||
+ mountstats = parse_stats_file('/proc/self/mountstats')
|
|
||||||
+ count -= 1
|
|
||||||
+ else:
|
|
||||||
+ while True:
|
|
||||||
+ print_iostat_summary(old_mountstats, mountstats, devices, sample_time)
|
|
||||||
+ old_mountstats = mountstats
|
|
||||||
+ time.sleep(interval)
|
|
||||||
+ sample_time = interval
|
|
||||||
+ mountstats = parse_stats_file('/proc/self/mountstats')
|
|
||||||
+
|
|
||||||
+#
|
|
||||||
+# Main
|
|
||||||
+#
|
|
||||||
+prog = os.path.basename(sys.argv[0])
|
|
||||||
+
|
|
||||||
+try:
|
|
||||||
+ if prog == 'mountstats':
|
|
||||||
+ mountstats_command()
|
|
||||||
+ elif prog == 'ms-nfsstat':
|
|
||||||
+ nfsstat_command()
|
|
||||||
+ elif prog == 'ms-iostat':
|
|
||||||
+ iostat_command()
|
|
||||||
+except KeyboardInterrupt:
|
|
||||||
+ print 'Caught ^C... exiting'
|
|
||||||
+ sys.exit(1)
|
|
||||||
+
|
|
||||||
+sys.exit(0)
|
|
@ -1,75 +0,0 @@
|
|||||||
commit 3c1bb23c0379864722e79d19f74c180edcf2c36e
|
|
||||||
Author: bc Wong <bcwong@cisco.com>
|
|
||||||
Date: Tue Mar 18 09:30:44 2008 -0400
|
|
||||||
|
|
||||||
There were 2 things wrong with auth flavour ordering:
|
|
||||||
- Mountd used to advertise AUTH_NULL as the first flavour on
|
|
||||||
the list, which means that it prefers AUTH_NULL to anything
|
|
||||||
else (as per RFC 2623 section 2.7).
|
|
||||||
- Mount.nfs used to scan the returned list in reverse order,
|
|
||||||
and stopping at the first AUTH_NULL or AUTH_SYS encountered.
|
|
||||||
If a server advertises (AUTH_SYS, AUTH_NULL), it will by
|
|
||||||
default choose AUTH_NULL and have degraded access.
|
|
||||||
|
|
||||||
I've fixed mount.nfs to scan from the beginning. For mountd,
|
|
||||||
it does not advertise AUTH_NULL anymore. This is necessary
|
|
||||||
to avoid backward compatibility issue. If AUTH_NULL appears
|
|
||||||
in the list, either the new or the old client will choose
|
|
||||||
that over AUTH_SYS.
|
|
||||||
|
|
||||||
Tested the server/client combination against the previous
|
|
||||||
versions, as well as Solaris and FreeBSD.
|
|
||||||
|
|
||||||
Signed-off-by: bc Wong <bcwong@cisco.com>
|
|
||||||
Signed-off-by: Steve Dickson <steved@redhat.com>
|
|
||||||
|
|
||||||
--- nfs-utils-1.1.2/utils/mount/nfsmount.c.orig 2008-03-14 11:46:29.000000000 -0400
|
|
||||||
+++ nfs-utils-1.1.2/utils/mount/nfsmount.c 2008-03-25 10:18:09.333839000 -0400
|
|
||||||
@@ -738,7 +738,7 @@ nfsmount(const char *spec, const char *n
|
|
||||||
#if NFS_MOUNT_VERSION >= 4
|
|
||||||
mountres3_ok *mountres;
|
|
||||||
fhandle3 *fhandle;
|
|
||||||
- int i, *flavor, yum = 0;
|
|
||||||
+ int i, n_flavors, *flavor, yum = 0;
|
|
||||||
if (mntres.nfsv3.fhs_status != 0) {
|
|
||||||
nfs_error(_("%s: %s:%s failed, reason given by server: %s"),
|
|
||||||
progname, hostname, dirname,
|
|
||||||
@@ -747,13 +747,16 @@ nfsmount(const char *spec, const char *n
|
|
||||||
}
|
|
||||||
#if NFS_MOUNT_VERSION >= 5
|
|
||||||
mountres = &mntres.nfsv3.mountres3_u.mountinfo;
|
|
||||||
- i = mountres->auth_flavors.auth_flavors_len;
|
|
||||||
- if (i <= 0)
|
|
||||||
+ n_flavors = mountres->auth_flavors.auth_flavors_len;
|
|
||||||
+ if (n_flavors <= 0)
|
|
||||||
goto noauth_flavors;
|
|
||||||
|
|
||||||
flavor = mountres->auth_flavors.auth_flavors_val;
|
|
||||||
- while (--i >= 0) {
|
|
||||||
- /* If no flavour requested, use first simple
|
|
||||||
+ for (i = 0; i < n_flavors; ++i) {
|
|
||||||
+ /*
|
|
||||||
+ * Per RFC2623, section 2.7, we should prefer the
|
|
||||||
+ * flavour listed first.
|
|
||||||
+ * If no flavour requested, use the first simple
|
|
||||||
* flavour that is offered.
|
|
||||||
*/
|
|
||||||
if (! (data.flags & NFS_MOUNT_SECFLAVOUR) &&
|
|
||||||
--- nfs-utils-1.1.2/utils/mountd/mountd.c.orig 2008-03-14 11:46:29.000000000 -0400
|
|
||||||
+++ nfs-utils-1.1.2/utils/mountd/mountd.c 2008-03-25 10:18:09.339833000 -0400
|
|
||||||
@@ -342,7 +342,14 @@ mount_mnt_3_svc(struct svc_req *rqstp, d
|
|
||||||
#define AUTH_GSS_KRB5 390003
|
|
||||||
#define AUTH_GSS_KRB5I 390004
|
|
||||||
#define AUTH_GSS_KRB5P 390005
|
|
||||||
- static int flavors[] = { AUTH_NULL, AUTH_UNIX, AUTH_GSS_KRB5, AUTH_GSS_KRB5I, AUTH_GSS_KRB5P};
|
|
||||||
+ static int flavors[] = { AUTH_UNIX, AUTH_GSS_KRB5, AUTH_GSS_KRB5I, AUTH_GSS_KRB5P};
|
|
||||||
+ /*
|
|
||||||
+ * We should advertise the preferred flavours first. (See RFC 2623
|
|
||||||
+ * section 2.7.) AUTH_UNIX is arbitrarily ranked over the GSS's.
|
|
||||||
+ * AUTH_NULL is dropped from the list to avoid backward compatibility
|
|
||||||
+ * issue with older Linux clients, who inspect the list in reversed
|
|
||||||
+ * order.
|
|
||||||
+ */
|
|
||||||
struct nfs_fh_len *fh;
|
|
||||||
|
|
||||||
xlog(D_CALL, "MNT3(%s) called", *path);
|
|
@ -1,42 +0,0 @@
|
|||||||
commit 2ef57222b10a91f4b96a06808d05a47e8f4c14f7
|
|
||||||
Author: Tom Talpey <tmt@netapp.com>
|
|
||||||
Date: Mon Jun 23 12:57:29 2008 -0400
|
|
||||||
|
|
||||||
Add RDMA as a supported transport for reporting
|
|
||||||
the mountstats statistics
|
|
||||||
|
|
||||||
Signed-off-by: Tom Talpey <tmt@netapp.com>
|
|
||||||
Acked-by: Chuck Lever <chuck.lever@oracle.com>
|
|
||||||
Signed-off-by: Steve Dickson <steved@redhat.com>
|
|
||||||
|
|
||||||
diff --git a/tools/nfs-iostat/nfs-iostat.py b/tools/nfs-iostat/nfs-iostat.py
|
|
||||||
index 794d4a8..649c1bd 100644
|
|
||||||
--- a/tools/nfs-iostat/nfs-iostat.py
|
|
||||||
+++ b/tools/nfs-iostat/nfs-iostat.py
|
|
||||||
@@ -134,6 +134,26 @@ class DeviceData:
|
|
||||||
self.__rpc_data['badxids'] = int(words[9])
|
|
||||||
self.__rpc_data['inflightsends'] = long(words[10])
|
|
||||||
self.__rpc_data['backlogutil'] = long(words[11])
|
|
||||||
+ elif words[1] == 'rdma':
|
|
||||||
+ self.__rpc_data['port'] = words[2]
|
|
||||||
+ self.__rpc_data['bind_count'] = int(words[3])
|
|
||||||
+ self.__rpc_data['connect_count'] = int(words[4])
|
|
||||||
+ self.__rpc_data['connect_time'] = int(words[5])
|
|
||||||
+ self.__rpc_data['idle_time'] = int(words[6])
|
|
||||||
+ self.__rpc_data['rpcsends'] = int(words[7])
|
|
||||||
+ self.__rpc_data['rpcreceives'] = int(words[8])
|
|
||||||
+ self.__rpc_data['badxids'] = int(words[9])
|
|
||||||
+ self.__rpc_data['backlogutil'] = int(words[10])
|
|
||||||
+ self.__rpc_data['read_chunks'] = int(words[11])
|
|
||||||
+ self.__rpc_data['write_chunks'] = int(words[12])
|
|
||||||
+ self.__rpc_data['reply_chunks'] = int(words[13])
|
|
||||||
+ self.__rpc_data['total_rdma_req'] = int(words[14])
|
|
||||||
+ self.__rpc_data['total_rdma_rep'] = int(words[15])
|
|
||||||
+ self.__rpc_data['pullup'] = int(words[16])
|
|
||||||
+ self.__rpc_data['fixup'] = int(words[17])
|
|
||||||
+ self.__rpc_data['hardway'] = int(words[18])
|
|
||||||
+ self.__rpc_data['failed_marshal'] = int(words[19])
|
|
||||||
+ self.__rpc_data['bad_reply'] = int(words[20])
|
|
||||||
elif words[0] == 'per-op':
|
|
||||||
self.__rpc_data['per-op'] = words
|
|
||||||
else:
|
|
@ -1,560 +0,0 @@
|
|||||||
commit ba18e469a8507befdf8969c5ce7a25564744ae01
|
|
||||||
Author: Chuck Lever <chuck.lever@oracle.com>
|
|
||||||
Date: Mon Jun 23 12:56:14 2008 -0400
|
|
||||||
|
|
||||||
The "nfs-iostat" utility is a Python program that extracts and displays NFS
|
|
||||||
client performance information from /proc/self/mountstats.
|
|
||||||
|
|
||||||
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
|
|
||||||
Signed-off-by: Steve Dickson <steved@redhat.com>
|
|
||||||
|
|
||||||
diff --git a/tools/nfs-iostat/nfs-iostat.py b/tools/nfs-iostat/nfs-iostat.py
|
|
||||||
new file mode 100644
|
|
||||||
index 0000000..794d4a8
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/tools/nfs-iostat/nfs-iostat.py
|
|
||||||
@@ -0,0 +1,544 @@
|
|
||||||
+#!/usr/bin/env python
|
|
||||||
+# -*- python-mode -*-
|
|
||||||
+"""Emulate iostat for NFS mount points using /proc/self/mountstats
|
|
||||||
+"""
|
|
||||||
+
|
|
||||||
+__copyright__ = """
|
|
||||||
+Copyright (C) 2005, Chuck Lever <cel@netapp.com>
|
|
||||||
+
|
|
||||||
+This program is free software; you can redistribute it and/or modify
|
|
||||||
+it under the terms of the GNU General Public License version 2 as
|
|
||||||
+published by the Free Software Foundation.
|
|
||||||
+
|
|
||||||
+This program is distributed in the hope that it will be useful,
|
|
||||||
+but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
+GNU General Public License for more details.
|
|
||||||
+
|
|
||||||
+You should have received a copy of the GNU General Public License
|
|
||||||
+along with this program; if not, write to the Free Software
|
|
||||||
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
+"""
|
|
||||||
+
|
|
||||||
+import sys, os, time
|
|
||||||
+
|
|
||||||
+Iostats_version = '0.2'
|
|
||||||
+
|
|
||||||
+def difference(x, y):
|
|
||||||
+ """Used for a map() function
|
|
||||||
+ """
|
|
||||||
+ return x - y
|
|
||||||
+
|
|
||||||
+NfsEventCounters = [
|
|
||||||
+ 'inoderevalidates',
|
|
||||||
+ 'dentryrevalidates',
|
|
||||||
+ 'datainvalidates',
|
|
||||||
+ 'attrinvalidates',
|
|
||||||
+ 'vfsopen',
|
|
||||||
+ 'vfslookup',
|
|
||||||
+ 'vfspermission',
|
|
||||||
+ 'vfsupdatepage',
|
|
||||||
+ 'vfsreadpage',
|
|
||||||
+ 'vfsreadpages',
|
|
||||||
+ 'vfswritepage',
|
|
||||||
+ 'vfswritepages',
|
|
||||||
+ 'vfsreaddir',
|
|
||||||
+ 'vfssetattr',
|
|
||||||
+ 'vfsflush',
|
|
||||||
+ 'vfsfsync',
|
|
||||||
+ 'vfslock',
|
|
||||||
+ 'vfsrelease',
|
|
||||||
+ 'congestionwait',
|
|
||||||
+ 'setattrtrunc',
|
|
||||||
+ 'extendwrite',
|
|
||||||
+ 'sillyrenames',
|
|
||||||
+ 'shortreads',
|
|
||||||
+ 'shortwrites',
|
|
||||||
+ 'delay'
|
|
||||||
+]
|
|
||||||
+
|
|
||||||
+NfsByteCounters = [
|
|
||||||
+ 'normalreadbytes',
|
|
||||||
+ 'normalwritebytes',
|
|
||||||
+ 'directreadbytes',
|
|
||||||
+ 'directwritebytes',
|
|
||||||
+ 'serverreadbytes',
|
|
||||||
+ 'serverwritebytes',
|
|
||||||
+ 'readpages',
|
|
||||||
+ 'writepages'
|
|
||||||
+]
|
|
||||||
+
|
|
||||||
+class DeviceData:
|
|
||||||
+ """DeviceData objects provide methods for parsing and displaying
|
|
||||||
+ data for a single mount grabbed from /proc/self/mountstats
|
|
||||||
+ """
|
|
||||||
+ def __init__(self):
|
|
||||||
+ self.__nfs_data = dict()
|
|
||||||
+ self.__rpc_data = dict()
|
|
||||||
+ self.__rpc_data['ops'] = []
|
|
||||||
+
|
|
||||||
+ def __parse_nfs_line(self, words):
|
|
||||||
+ if words[0] == 'device':
|
|
||||||
+ self.__nfs_data['export'] = words[1]
|
|
||||||
+ self.__nfs_data['mountpoint'] = words[4]
|
|
||||||
+ self.__nfs_data['fstype'] = words[7]
|
|
||||||
+ if words[7] == 'nfs':
|
|
||||||
+ self.__nfs_data['statvers'] = words[8]
|
|
||||||
+ elif words[0] == 'age:':
|
|
||||||
+ self.__nfs_data['age'] = long(words[1])
|
|
||||||
+ elif words[0] == 'opts:':
|
|
||||||
+ self.__nfs_data['mountoptions'] = ''.join(words[1:]).split(',')
|
|
||||||
+ elif words[0] == 'caps:':
|
|
||||||
+ self.__nfs_data['servercapabilities'] = ''.join(words[1:]).split(',')
|
|
||||||
+ elif words[0] == 'nfsv4:':
|
|
||||||
+ self.__nfs_data['nfsv4flags'] = ''.join(words[1:]).split(',')
|
|
||||||
+ elif words[0] == 'sec:':
|
|
||||||
+ keys = ''.join(words[1:]).split(',')
|
|
||||||
+ self.__nfs_data['flavor'] = int(keys[0].split('=')[1])
|
|
||||||
+ self.__nfs_data['pseudoflavor'] = 0
|
|
||||||
+ if self.__nfs_data['flavor'] == 6:
|
|
||||||
+ self.__nfs_data['pseudoflavor'] = int(keys[1].split('=')[1])
|
|
||||||
+ elif words[0] == 'events:':
|
|
||||||
+ i = 1
|
|
||||||
+ for key in NfsEventCounters:
|
|
||||||
+ self.__nfs_data[key] = int(words[i])
|
|
||||||
+ i += 1
|
|
||||||
+ elif words[0] == 'bytes:':
|
|
||||||
+ i = 1
|
|
||||||
+ for key in NfsByteCounters:
|
|
||||||
+ self.__nfs_data[key] = long(words[i])
|
|
||||||
+ i += 1
|
|
||||||
+
|
|
||||||
+ def __parse_rpc_line(self, words):
|
|
||||||
+ if words[0] == 'RPC':
|
|
||||||
+ self.__rpc_data['statsvers'] = float(words[3])
|
|
||||||
+ self.__rpc_data['programversion'] = words[5]
|
|
||||||
+ elif words[0] == 'xprt:':
|
|
||||||
+ self.__rpc_data['protocol'] = words[1]
|
|
||||||
+ if words[1] == 'udp':
|
|
||||||
+ self.__rpc_data['port'] = int(words[2])
|
|
||||||
+ self.__rpc_data['bind_count'] = int(words[3])
|
|
||||||
+ self.__rpc_data['rpcsends'] = int(words[4])
|
|
||||||
+ self.__rpc_data['rpcreceives'] = int(words[5])
|
|
||||||
+ self.__rpc_data['badxids'] = int(words[6])
|
|
||||||
+ self.__rpc_data['inflightsends'] = long(words[7])
|
|
||||||
+ self.__rpc_data['backlogutil'] = long(words[8])
|
|
||||||
+ elif words[1] == 'tcp':
|
|
||||||
+ self.__rpc_data['port'] = words[2]
|
|
||||||
+ self.__rpc_data['bind_count'] = int(words[3])
|
|
||||||
+ self.__rpc_data['connect_count'] = int(words[4])
|
|
||||||
+ self.__rpc_data['connect_time'] = int(words[5])
|
|
||||||
+ self.__rpc_data['idle_time'] = int(words[6])
|
|
||||||
+ self.__rpc_data['rpcsends'] = int(words[7])
|
|
||||||
+ self.__rpc_data['rpcreceives'] = int(words[8])
|
|
||||||
+ self.__rpc_data['badxids'] = int(words[9])
|
|
||||||
+ self.__rpc_data['inflightsends'] = long(words[10])
|
|
||||||
+ self.__rpc_data['backlogutil'] = long(words[11])
|
|
||||||
+ elif words[0] == 'per-op':
|
|
||||||
+ self.__rpc_data['per-op'] = words
|
|
||||||
+ else:
|
|
||||||
+ op = words[0][:-1]
|
|
||||||
+ self.__rpc_data['ops'] += [op]
|
|
||||||
+ self.__rpc_data[op] = [long(word) for word in words[1:]]
|
|
||||||
+
|
|
||||||
+ def parse_stats(self, lines):
|
|
||||||
+ """Turn a list of lines from a mount stat file into a
|
|
||||||
+ dictionary full of stats, keyed by name
|
|
||||||
+ """
|
|
||||||
+ found = False
|
|
||||||
+ for line in lines:
|
|
||||||
+ words = line.split()
|
|
||||||
+ if len(words) == 0:
|
|
||||||
+ continue
|
|
||||||
+ if (not found and words[0] != 'RPC'):
|
|
||||||
+ self.__parse_nfs_line(words)
|
|
||||||
+ continue
|
|
||||||
+
|
|
||||||
+ found = True
|
|
||||||
+ self.__parse_rpc_line(words)
|
|
||||||
+
|
|
||||||
+ def is_nfs_mountpoint(self):
|
|
||||||
+ """Return True if this is an NFS or NFSv4 mountpoint,
|
|
||||||
+ otherwise return False
|
|
||||||
+ """
|
|
||||||
+ if self.__nfs_data['fstype'] == 'nfs':
|
|
||||||
+ return True
|
|
||||||
+ elif self.__nfs_data['fstype'] == 'nfs4':
|
|
||||||
+ return True
|
|
||||||
+ return False
|
|
||||||
+
|
|
||||||
+ def compare_iostats(self, old_stats):
|
|
||||||
+ """Return the difference between two sets of stats
|
|
||||||
+ """
|
|
||||||
+ result = DeviceData()
|
|
||||||
+
|
|
||||||
+ # copy self into result
|
|
||||||
+ for key, value in self.__nfs_data.iteritems():
|
|
||||||
+ result.__nfs_data[key] = value
|
|
||||||
+ for key, value in self.__rpc_data.iteritems():
|
|
||||||
+ result.__rpc_data[key] = value
|
|
||||||
+
|
|
||||||
+ # compute the difference of each item in the list
|
|
||||||
+ # note the copy loop above does not copy the lists, just
|
|
||||||
+ # the reference to them. so we build new lists here
|
|
||||||
+ # for the result object.
|
|
||||||
+ for op in result.__rpc_data['ops']:
|
|
||||||
+ result.__rpc_data[op] = map(difference, self.__rpc_data[op], old_stats.__rpc_data[op])
|
|
||||||
+
|
|
||||||
+ # update the remaining keys we care about
|
|
||||||
+ result.__rpc_data['rpcsends'] -= old_stats.__rpc_data['rpcsends']
|
|
||||||
+ result.__rpc_data['backlogutil'] -= old_stats.__rpc_data['backlogutil']
|
|
||||||
+
|
|
||||||
+ for key in NfsEventCounters:
|
|
||||||
+ result.__nfs_data[key] -= old_stats.__nfs_data[key]
|
|
||||||
+ for key in NfsByteCounters:
|
|
||||||
+ result.__nfs_data[key] -= old_stats.__nfs_data[key]
|
|
||||||
+
|
|
||||||
+ return result
|
|
||||||
+
|
|
||||||
+ def __print_data_cache_stats(self):
|
|
||||||
+ """Print the data cache hit rate
|
|
||||||
+ """
|
|
||||||
+ nfs_stats = self.__nfs_data
|
|
||||||
+ app_bytes_read = float(nfs_stats['normalreadbytes'])
|
|
||||||
+ if app_bytes_read != 0:
|
|
||||||
+ client_bytes_read = float(nfs_stats['serverreadbytes'] - nfs_stats['directreadbytes'])
|
|
||||||
+ ratio = ((app_bytes_read - client_bytes_read) * 100) / app_bytes_read
|
|
||||||
+
|
|
||||||
+ print
|
|
||||||
+ print 'app bytes: %f client bytes %f' % (app_bytes_read, client_bytes_read)
|
|
||||||
+ print 'Data cache hit ratio: %4.2f%%' % ratio
|
|
||||||
+
|
|
||||||
+ def __print_attr_cache_stats(self, sample_time):
|
|
||||||
+ """Print attribute cache efficiency stats
|
|
||||||
+ """
|
|
||||||
+ nfs_stats = self.__nfs_data
|
|
||||||
+ getattr_stats = self.__rpc_data['GETATTR']
|
|
||||||
+
|
|
||||||
+ if nfs_stats['inoderevalidates'] != 0:
|
|
||||||
+ getattr_ops = float(getattr_stats[1])
|
|
||||||
+ opens = float(nfs_stats['vfsopen'])
|
|
||||||
+ revalidates = float(nfs_stats['inoderevalidates']) - opens
|
|
||||||
+ if revalidates != 0:
|
|
||||||
+ ratio = ((revalidates - getattr_ops) * 100) / revalidates
|
|
||||||
+ else:
|
|
||||||
+ ratio = 0.0
|
|
||||||
+
|
|
||||||
+ data_invalidates = float(nfs_stats['datainvalidates'])
|
|
||||||
+ attr_invalidates = float(nfs_stats['attrinvalidates'])
|
|
||||||
+
|
|
||||||
+ print
|
|
||||||
+ print '%d inode revalidations, hitting in cache %4.2f%% of the time' % \
|
|
||||||
+ (revalidates, ratio)
|
|
||||||
+ print '%d open operations (mandatory GETATTR requests)' % opens
|
|
||||||
+ if getattr_ops != 0:
|
|
||||||
+ print '%4.2f%% of GETATTRs resulted in data cache invalidations' % \
|
|
||||||
+ ((data_invalidates * 100) / getattr_ops)
|
|
||||||
+
|
|
||||||
+ def __print_dir_cache_stats(self, sample_time):
|
|
||||||
+ """Print directory stats
|
|
||||||
+ """
|
|
||||||
+ nfs_stats = self.__nfs_data
|
|
||||||
+ lookup_ops = self.__rpc_data['LOOKUP'][0]
|
|
||||||
+ readdir_ops = self.__rpc_data['READDIR'][0]
|
|
||||||
+ if self.__rpc_data.has_key('READDIRPLUS'):
|
|
||||||
+ readdir_ops += self.__rpc_data['READDIRPLUS'][0]
|
|
||||||
+
|
|
||||||
+ dentry_revals = nfs_stats['dentryrevalidates']
|
|
||||||
+ opens = nfs_stats['vfsopen']
|
|
||||||
+ lookups = nfs_stats['vfslookup']
|
|
||||||
+ getdents = nfs_stats['vfsreaddir']
|
|
||||||
+
|
|
||||||
+ print
|
|
||||||
+ print '%d open operations (pathname lookups)' % opens
|
|
||||||
+ print '%d dentry revalidates and %d vfs lookup requests' % \
|
|
||||||
+ (dentry_revals, lookups),
|
|
||||||
+ print 'resulted in %d LOOKUPs on the wire' % lookup_ops
|
|
||||||
+ print '%d vfs getdents calls resulted in %d READDIRs on the wire' % \
|
|
||||||
+ (getdents, readdir_ops)
|
|
||||||
+
|
|
||||||
+ def __print_page_stats(self, sample_time):
|
|
||||||
+ """Print page cache stats
|
|
||||||
+ """
|
|
||||||
+ nfs_stats = self.__nfs_data
|
|
||||||
+
|
|
||||||
+ vfsreadpage = nfs_stats['vfsreadpage']
|
|
||||||
+ vfsreadpages = nfs_stats['vfsreadpages']
|
|
||||||
+ pages_read = nfs_stats['readpages']
|
|
||||||
+ vfswritepage = nfs_stats['vfswritepage']
|
|
||||||
+ vfswritepages = nfs_stats['vfswritepages']
|
|
||||||
+ pages_written = nfs_stats['writepages']
|
|
||||||
+
|
|
||||||
+ print
|
|
||||||
+ print '%d nfs_readpage() calls read %d pages' % \
|
|
||||||
+ (vfsreadpage, vfsreadpage)
|
|
||||||
+ print '%d nfs_readpages() calls read %d pages' % \
|
|
||||||
+ (vfsreadpages, pages_read - vfsreadpage),
|
|
||||||
+ if vfsreadpages != 0:
|
|
||||||
+ print '(%.1f pages per call)' % \
|
|
||||||
+ (float(pages_read - vfsreadpage) / vfsreadpages)
|
|
||||||
+ else:
|
|
||||||
+ print
|
|
||||||
+
|
|
||||||
+ print
|
|
||||||
+ print '%d nfs_updatepage() calls' % nfs_stats['vfsupdatepage']
|
|
||||||
+ print '%d nfs_writepage() calls wrote %d pages' % \
|
|
||||||
+ (vfswritepage, vfswritepage)
|
|
||||||
+ print '%d nfs_writepages() calls wrote %d pages' % \
|
|
||||||
+ (vfswritepages, pages_written - vfswritepage),
|
|
||||||
+ if (vfswritepages) != 0:
|
|
||||||
+ print '(%.1f pages per call)' % \
|
|
||||||
+ (float(pages_written - vfswritepage) / vfswritepages)
|
|
||||||
+ else:
|
|
||||||
+ print
|
|
||||||
+
|
|
||||||
+ congestionwaits = nfs_stats['congestionwait']
|
|
||||||
+ if congestionwaits != 0:
|
|
||||||
+ print
|
|
||||||
+ print '%d congestion waits' % congestionwaits
|
|
||||||
+
|
|
||||||
+ def __print_rpc_op_stats(self, op, sample_time):
|
|
||||||
+ """Print generic stats for one RPC op
|
|
||||||
+ """
|
|
||||||
+ if not self.__rpc_data.has_key(op):
|
|
||||||
+ return
|
|
||||||
+
|
|
||||||
+ rpc_stats = self.__rpc_data[op]
|
|
||||||
+ ops = float(rpc_stats[0])
|
|
||||||
+ retrans = float(rpc_stats[1] - rpc_stats[0])
|
|
||||||
+ kilobytes = float(rpc_stats[3] + rpc_stats[4]) / 1024
|
|
||||||
+ rtt = float(rpc_stats[6])
|
|
||||||
+ exe = float(rpc_stats[7])
|
|
||||||
+
|
|
||||||
+ # prevent floating point exceptions
|
|
||||||
+ if ops != 0:
|
|
||||||
+ kb_per_op = kilobytes / ops
|
|
||||||
+ retrans_percent = (retrans * 100) / ops
|
|
||||||
+ rtt_per_op = rtt / ops
|
|
||||||
+ exe_per_op = exe / ops
|
|
||||||
+ else:
|
|
||||||
+ kb_per_op = 0.0
|
|
||||||
+ retrans_percent = 0.0
|
|
||||||
+ rtt_per_op = 0.0
|
|
||||||
+ exe_per_op = 0.0
|
|
||||||
+
|
|
||||||
+ op += ':'
|
|
||||||
+ print '%s' % op.lower().ljust(15),
|
|
||||||
+ print ' ops/s\t\t Kb/s\t\t Kb/op\t\tretrans\t\tavg RTT (ms)\tavg exe (ms)'
|
|
||||||
+
|
|
||||||
+ print '\t\t%7.3f' % (ops / sample_time),
|
|
||||||
+ print '\t%7.3f' % (kilobytes / sample_time),
|
|
||||||
+ print '\t%7.3f' % kb_per_op,
|
|
||||||
+ print ' %7d (%3.1f%%)' % (retrans, retrans_percent),
|
|
||||||
+ print '\t%7.3f' % rtt_per_op,
|
|
||||||
+ print '\t%7.3f' % exe_per_op
|
|
||||||
+
|
|
||||||
+ def display_iostats(self, sample_time, which):
|
|
||||||
+ """Display NFS and RPC stats in an iostat-like way
|
|
||||||
+ """
|
|
||||||
+ sends = float(self.__rpc_data['rpcsends'])
|
|
||||||
+ if sample_time == 0:
|
|
||||||
+ sample_time = float(self.__nfs_data['age'])
|
|
||||||
+ if sends != 0:
|
|
||||||
+ backlog = (float(self.__rpc_data['backlogutil']) / sends) / sample_time
|
|
||||||
+ else:
|
|
||||||
+ backlog = 0.0
|
|
||||||
+
|
|
||||||
+ print
|
|
||||||
+ print '%s mounted on %s:' % \
|
|
||||||
+ (self.__nfs_data['export'], self.__nfs_data['mountpoint'])
|
|
||||||
+ print
|
|
||||||
+
|
|
||||||
+ print ' op/s\t\trpc bklog'
|
|
||||||
+ print '%7.2f' % (sends / sample_time),
|
|
||||||
+ print '\t%7.2f' % backlog
|
|
||||||
+
|
|
||||||
+ if which == 0:
|
|
||||||
+ self.__print_rpc_op_stats('READ', sample_time)
|
|
||||||
+ self.__print_rpc_op_stats('WRITE', sample_time)
|
|
||||||
+ elif which == 1:
|
|
||||||
+ self.__print_rpc_op_stats('GETATTR', sample_time)
|
|
||||||
+ self.__print_rpc_op_stats('ACCESS', sample_time)
|
|
||||||
+ self.__print_attr_cache_stats(sample_time)
|
|
||||||
+ elif which == 2:
|
|
||||||
+ self.__print_rpc_op_stats('LOOKUP', sample_time)
|
|
||||||
+ self.__print_rpc_op_stats('READDIR', sample_time)
|
|
||||||
+ if self.__rpc_data.has_key('READDIRPLUS'):
|
|
||||||
+ self.__print_rpc_op_stats('READDIRPLUS', sample_time)
|
|
||||||
+ self.__print_dir_cache_stats(sample_time)
|
|
||||||
+ elif which == 3:
|
|
||||||
+ self.__print_rpc_op_stats('READ', sample_time)
|
|
||||||
+ self.__print_rpc_op_stats('WRITE', sample_time)
|
|
||||||
+ self.__print_page_stats(sample_time)
|
|
||||||
+
|
|
||||||
+#
|
|
||||||
+# Functions
|
|
||||||
+#
|
|
||||||
+
|
|
||||||
+def print_iostat_help(name):
|
|
||||||
+ print 'usage: %s [ <interval> [ <count> ] ] [ <options> ] [ <mount point> ] ' % name
|
|
||||||
+ print
|
|
||||||
+ print ' Version %s' % Iostats_version
|
|
||||||
+ print
|
|
||||||
+ print ' Sample iostat-like program to display NFS client per-mount statistics.'
|
|
||||||
+ print
|
|
||||||
+ print ' The <interval> parameter specifies the amount of time in seconds between'
|
|
||||||
+ print ' each report. The first report contains statistics for the time since each'
|
|
||||||
+ print ' file system was mounted. Each subsequent report contains statistics'
|
|
||||||
+ print ' collected during the interval since the previous report.'
|
|
||||||
+ print
|
|
||||||
+ print ' If the <count> parameter is specified, the value of <count> determines the'
|
|
||||||
+ print ' number of reports generated at <interval> seconds apart. If the interval'
|
|
||||||
+ print ' parameter is specified without the <count> parameter, the command generates'
|
|
||||||
+ print ' reports continuously.'
|
|
||||||
+ print
|
|
||||||
+ print ' Options include "--attr", which displays statistics related to the attribute'
|
|
||||||
+ print ' cache, "--dir", which displays statistics related to directory operations,'
|
|
||||||
+ print ' and "--page", which displays statistics related to the page cache.'
|
|
||||||
+ print ' By default, if no option is specified, statistics related to file I/O are'
|
|
||||||
+ print ' displayed.'
|
|
||||||
+ print
|
|
||||||
+ print ' If one or more <mount point> names are specified, statistics for only these'
|
|
||||||
+ print ' mount points will be displayed. Otherwise, all NFS mount points on the'
|
|
||||||
+ print ' client are listed.'
|
|
||||||
+
|
|
||||||
+def parse_stats_file(filename):
|
|
||||||
+ """pop the contents of a mountstats file into a dictionary,
|
|
||||||
+ keyed by mount point. each value object is a list of the
|
|
||||||
+ lines in the mountstats file corresponding to the mount
|
|
||||||
+ point named in the key.
|
|
||||||
+ """
|
|
||||||
+ ms_dict = dict()
|
|
||||||
+ key = ''
|
|
||||||
+
|
|
||||||
+ f = file(filename)
|
|
||||||
+ for line in f.readlines():
|
|
||||||
+ words = line.split()
|
|
||||||
+ if len(words) == 0:
|
|
||||||
+ continue
|
|
||||||
+ if words[0] == 'device':
|
|
||||||
+ key = words[4]
|
|
||||||
+ new = [ line.strip() ]
|
|
||||||
+ else:
|
|
||||||
+ new += [ line.strip() ]
|
|
||||||
+ ms_dict[key] = new
|
|
||||||
+ f.close
|
|
||||||
+
|
|
||||||
+ return ms_dict
|
|
||||||
+
|
|
||||||
+def print_iostat_summary(old, new, devices, time, ac):
|
|
||||||
+ for device in devices:
|
|
||||||
+ stats = DeviceData()
|
|
||||||
+ stats.parse_stats(new[device])
|
|
||||||
+ if not old:
|
|
||||||
+ stats.display_iostats(time, ac)
|
|
||||||
+ else:
|
|
||||||
+ old_stats = DeviceData()
|
|
||||||
+ old_stats.parse_stats(old[device])
|
|
||||||
+ diff_stats = stats.compare_iostats(old_stats)
|
|
||||||
+ diff_stats.display_iostats(time, ac)
|
|
||||||
+
|
|
||||||
+def iostat_command(name):
|
|
||||||
+ """iostat-like command for NFS mount points
|
|
||||||
+ """
|
|
||||||
+ mountstats = parse_stats_file('/proc/self/mountstats')
|
|
||||||
+ devices = []
|
|
||||||
+ which = 0
|
|
||||||
+ interval_seen = False
|
|
||||||
+ count_seen = False
|
|
||||||
+
|
|
||||||
+ for arg in sys.argv:
|
|
||||||
+ if arg in ['-h', '--help', 'help', 'usage']:
|
|
||||||
+ print_iostat_help(name)
|
|
||||||
+ return
|
|
||||||
+
|
|
||||||
+ if arg in ['-v', '--version', 'version']:
|
|
||||||
+ print '%s version %s' % (name, Iostats_version)
|
|
||||||
+ return
|
|
||||||
+
|
|
||||||
+ if arg in ['-a', '--attr']:
|
|
||||||
+ which = 1
|
|
||||||
+ continue
|
|
||||||
+
|
|
||||||
+ if arg in ['-d', '--dir']:
|
|
||||||
+ which = 2
|
|
||||||
+ continue
|
|
||||||
+
|
|
||||||
+ if arg in ['-p', '--page']:
|
|
||||||
+ which = 3
|
|
||||||
+ continue
|
|
||||||
+
|
|
||||||
+ if arg == sys.argv[0]:
|
|
||||||
+ continue
|
|
||||||
+
|
|
||||||
+ if arg in mountstats:
|
|
||||||
+ devices += [arg]
|
|
||||||
+ elif not interval_seen:
|
|
||||||
+ interval = int(arg)
|
|
||||||
+ if interval > 0:
|
|
||||||
+ interval_seen = True
|
|
||||||
+ else:
|
|
||||||
+ print 'Illegal <interval> value'
|
|
||||||
+ return
|
|
||||||
+ elif not count_seen:
|
|
||||||
+ count = int(arg)
|
|
||||||
+ if count > 0:
|
|
||||||
+ count_seen = True
|
|
||||||
+ else:
|
|
||||||
+ print 'Illegal <count> value'
|
|
||||||
+ return
|
|
||||||
+
|
|
||||||
+ # make certain devices contains only NFS mount points
|
|
||||||
+ if len(devices) > 0:
|
|
||||||
+ check = []
|
|
||||||
+ for device in devices:
|
|
||||||
+ stats = DeviceData()
|
|
||||||
+ stats.parse_stats(mountstats[device])
|
|
||||||
+ if stats.is_nfs_mountpoint():
|
|
||||||
+ check += [device]
|
|
||||||
+ devices = check
|
|
||||||
+ else:
|
|
||||||
+ for device, descr in mountstats.iteritems():
|
|
||||||
+ stats = DeviceData()
|
|
||||||
+ stats.parse_stats(descr)
|
|
||||||
+ if stats.is_nfs_mountpoint():
|
|
||||||
+ devices += [device]
|
|
||||||
+ if len(devices) == 0:
|
|
||||||
+ print 'No NFS mount points were found'
|
|
||||||
+ return
|
|
||||||
+
|
|
||||||
+ old_mountstats = None
|
|
||||||
+ sample_time = 0.0
|
|
||||||
+
|
|
||||||
+ if not interval_seen:
|
|
||||||
+ print_iostat_summary(old_mountstats, mountstats, devices, sample_time, which)
|
|
||||||
+ return
|
|
||||||
+
|
|
||||||
+ if count_seen:
|
|
||||||
+ while count != 0:
|
|
||||||
+ print_iostat_summary(old_mountstats, mountstats, devices, sample_time, which)
|
|
||||||
+ old_mountstats = mountstats
|
|
||||||
+ time.sleep(interval)
|
|
||||||
+ sample_time = interval
|
|
||||||
+ mountstats = parse_stats_file('/proc/self/mountstats')
|
|
||||||
+ count -= 1
|
|
||||||
+ else:
|
|
||||||
+ while True:
|
|
||||||
+ print_iostat_summary(old_mountstats, mountstats, devices, sample_time, which)
|
|
||||||
+ old_mountstats = mountstats
|
|
||||||
+ time.sleep(interval)
|
|
||||||
+ sample_time = interval
|
|
||||||
+ mountstats = parse_stats_file('/proc/self/mountstats')
|
|
||||||
+
|
|
||||||
+#
|
|
||||||
+# Main
|
|
||||||
+#
|
|
||||||
+prog = os.path.basename(sys.argv[0])
|
|
||||||
+
|
|
||||||
+try:
|
|
||||||
+ iostat_command(prog)
|
|
||||||
+except KeyboardInterrupt:
|
|
||||||
+ print 'Caught ^C... exiting'
|
|
||||||
+ sys.exit(1)
|
|
||||||
+
|
|
||||||
+sys.exit(0)
|
|
@ -1,60 +0,0 @@
|
|||||||
commit 5be04020788598cb811e51c4b1342cf0796cbb65
|
|
||||||
Author: Jeff Layton <jlayton@redhat.com>
|
|
||||||
Date: Mon Jun 23 07:21:52 2008 -0400
|
|
||||||
|
|
||||||
The nfsstat program reads /proc/net/rpc/* files to gets info about
|
|
||||||
calls. This info is output as unsigned numbers (at least on any
|
|
||||||
relatively recent kernel). When nfsstat prints these numbers, they are
|
|
||||||
printed as signed integers. When the call counters reach 2^31, things
|
|
||||||
start being printed as negative numbers.
|
|
||||||
|
|
||||||
This patch changes nfsstat to read and print all counters as unsigned
|
|
||||||
integers. Tested by hacking up a kernel to initialize call counters to
|
|
||||||
2^31+1.
|
|
||||||
|
|
||||||
Thanks to Takafumi Miki for the initial version of this patch.
|
|
||||||
|
|
||||||
Signed-off-by: Jeff Layton <jlayton@redhat.com>
|
|
||||||
Signed-off-by: Steve Dickson <steved@redhat.com>
|
|
||||||
|
|
||||||
diff --git a/utils/nfsstat/nfsstat.c b/utils/nfsstat/nfsstat.c
|
|
||||||
index d2cca8d..1517414 100644
|
|
||||||
--- a/utils/nfsstat/nfsstat.c
|
|
||||||
+++ b/utils/nfsstat/nfsstat.c
|
|
||||||
@@ -539,7 +539,7 @@ print_numbers(const char *hdr, unsigned int *info, unsigned int nr)
|
|
||||||
|
|
||||||
fputs(hdr, stdout);
|
|
||||||
for (i = 0; i < nr; i++)
|
|
||||||
- printf("%s%-8d", i? " " : "", info[i]);
|
|
||||||
+ printf("%s%-8u", i? " " : "", info[i]);
|
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -562,7 +562,7 @@ print_callstats(const char *hdr, const char **names,
|
|
||||||
printf("\n");
|
|
||||||
for (j = 0; j < 6 && i + j < nr; j++) {
|
|
||||||
pct = ((unsigned long long) info[i+j]*100)/total;
|
|
||||||
- printf("%-8d%3llu%% ", info[i+j], pct);
|
|
||||||
+ printf("%-8u%3llu%% ", info[i+j], pct);
|
|
||||||
}
|
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
@@ -604,7 +604,7 @@ parse_raw_statfile(const char *name, struct statinfo *statp)
|
|
||||||
for (i = 0; i < cnt; i++) {
|
|
||||||
if (!(sp = strtok(NULL, " \t")))
|
|
||||||
break;
|
|
||||||
- ip->valptr[i] = atoi(sp);
|
|
||||||
+ ip->valptr[i] = (unsigned int) strtoul(sp, NULL, 0);
|
|
||||||
total += ip->valptr[i];
|
|
||||||
}
|
|
||||||
ip->valptr[cnt - 1] = total;
|
|
||||||
@@ -618,7 +618,8 @@ parse_raw_statfile(const char *name, struct statinfo *statp)
|
|
||||||
static int
|
|
||||||
parse_pretty_statfile(const char *filename, struct statinfo *info)
|
|
||||||
{
|
|
||||||
- int numvals, curindex, numconsumed, n, sum, err = 1;
|
|
||||||
+ int numvals, curindex, numconsumed, n, err = 1;
|
|
||||||
+ unsigned int sum;
|
|
||||||
char buf[4096], *bufp, *fmt, is_proc;
|
|
||||||
FILE *fp = NULL;
|
|
||||||
struct statinfo *ip;
|
|
@ -1,26 +0,0 @@
|
|||||||
commit d03090be4f440d70328988e9f792f3bd0ebd956b
|
|
||||||
Author: Neil Brown <neilb@suse.de>
|
|
||||||
Date: Fri Jun 6 15:17:55 2008 -0400
|
|
||||||
|
|
||||||
nfsstat -m lists all current nfs mounts, with the mount options.
|
|
||||||
It does this by reading /proc/mounts and looking for mounts of type
|
|
||||||
"nfs". It really should check for "nfs4" as well.
|
|
||||||
|
|
||||||
For simplicity, just check the first 3 characters of the type.
|
|
||||||
|
|
||||||
Signed-off-by: NeilBrown <neilb@suse.de>
|
|
||||||
Signed-off-by: Steve Dickson <steved@redhat.com>
|
|
||||||
|
|
||||||
diff --git a/utils/nfsstat/nfsstat.c b/utils/nfsstat/nfsstat.c
|
|
||||||
index aa6c961..d2cca8d 100644
|
|
||||||
--- a/utils/nfsstat/nfsstat.c
|
|
||||||
+++ b/utils/nfsstat/nfsstat.c
|
|
||||||
@@ -716,7 +716,7 @@ mounts(const char *name)
|
|
||||||
if (!(type = strtok(NULL, " \t")))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
- if (strcmp(type, "nfs")) {
|
|
||||||
+ if (strcmp(type, "nfs") && strcmp(type,"nfs4")) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
@ -1,28 +0,0 @@
|
|||||||
commit 710765a87d599d95de51b79202ba3d82fd03ed95
|
|
||||||
Author: Steve Dickson <steved@redhat.com>
|
|
||||||
Date: Wed Jun 25 09:23:45 2008 -0400
|
|
||||||
|
|
||||||
When a FQDN exists in /var/lib/nfs/rmtab it causes
|
|
||||||
the exportfs command to seg fault due to the nfs_export pointer
|
|
||||||
not being allocated. Reworking the parentheses in rmtab_read()
|
|
||||||
so the htype variable is evaluated correctly fix the problem.
|
|
||||||
|
|
||||||
Signed-off-by: Steve Dickson <steved@redhat.com>
|
|
||||||
|
|
||||||
diff --git a/support/export/rmtab.c b/support/export/rmtab.c
|
|
||||||
index 0ce3682..e11a22a 100644
|
|
||||||
--- a/support/export/rmtab.c
|
|
||||||
+++ b/support/export/rmtab.c
|
|
||||||
@@ -31,10 +31,10 @@ rmtab_read(void)
|
|
||||||
int htype;
|
|
||||||
|
|
||||||
htype = client_gettype(rep->r_client);
|
|
||||||
- if (htype == MCL_FQDN || (htype == MCL_SUBNETWORK
|
|
||||||
+ if ((htype == MCL_FQDN || htype == MCL_SUBNETWORK)
|
|
||||||
&& (hp = gethostbyname (rep->r_client))
|
|
||||||
&& (hp = hostent_dup (hp),
|
|
||||||
- (exp = export_allowed (hp, rep->r_path))))) {
|
|
||||||
+ exp = export_allowed (hp, rep->r_path))) {
|
|
||||||
/* see if the entry already exists, otherwise this was an instantiated
|
|
||||||
* wild card, and we must add it
|
|
||||||
*/
|
|
@ -1,28 +0,0 @@
|
|||||||
commit ad1fc3feae447685a8ec8c7db0ad913fe3c4de5c
|
|
||||||
Author: Sten Spans <sten@blinkenlights.nl>
|
|
||||||
Date: Mon May 5 14:04:58 2008 -0400
|
|
||||||
|
|
||||||
Fixed arguments to the hosts_ctl() call in the good_client() routine
|
|
||||||
used in the tcpwrapper support.
|
|
||||||
|
|
||||||
Signe-off-by: Steve Dickson <steved@redhat.com>
|
|
||||||
|
|
||||||
diff --git a/support/misc/tcpwrapper.c b/support/misc/tcpwrapper.c
|
|
||||||
index 0cc9335..e4f453b 100644
|
|
||||||
--- a/support/misc/tcpwrapper.c
|
|
||||||
+++ b/support/misc/tcpwrapper.c
|
|
||||||
@@ -125,12 +125,12 @@ struct sockaddr_in *addr;
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* Check the official name first. */
|
|
||||||
- if (hosts_ctl(daemon, "", hp->h_name, ""))
|
|
||||||
+ if (hosts_ctl(daemon, hp->h_name, "", ""))
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
/* Check aliases. */
|
|
||||||
for (sp = hp->h_aliases; *sp ; sp++) {
|
|
||||||
- if (hosts_ctl(daemon, "", *sp, ""))
|
|
||||||
+ if (hosts_ctl(daemon, *sp, "", ""))
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
@ -1,34 +0,0 @@
|
|||||||
commit fd54675db0806e81c17ee7e7eec0abfcd33f1f23
|
|
||||||
Author: Steve Dickson <steved@redhat.com>
|
|
||||||
Date: Fri Jun 6 14:44:48 2008 -0400
|
|
||||||
|
|
||||||
Cleaned up warnings in rmtab.c and xlog.c
|
|
||||||
|
|
||||||
Signed-off-by: Steve Dickson <steved@redhat.com>
|
|
||||||
|
|
||||||
diff --git a/support/export/rmtab.c b/support/export/rmtab.c
|
|
||||||
index 8f392a7..0ce3682 100644
|
|
||||||
--- a/support/export/rmtab.c
|
|
||||||
+++ b/support/export/rmtab.c
|
|
||||||
@@ -23,7 +23,7 @@ int
|
|
||||||
rmtab_read(void)
|
|
||||||
{
|
|
||||||
struct rmtabent *rep;
|
|
||||||
- nfs_export *exp;
|
|
||||||
+ nfs_export *exp = NULL;
|
|
||||||
|
|
||||||
setrmtabent("r");
|
|
||||||
while ((rep = getrmtabent(1, NULL)) != NULL) {
|
|
||||||
@@ -31,10 +31,10 @@ rmtab_read(void)
|
|
||||||
int htype;
|
|
||||||
|
|
||||||
htype = client_gettype(rep->r_client);
|
|
||||||
- if (htype == MCL_FQDN || htype == MCL_SUBNETWORK
|
|
||||||
+ if (htype == MCL_FQDN || (htype == MCL_SUBNETWORK
|
|
||||||
&& (hp = gethostbyname (rep->r_client))
|
|
||||||
&& (hp = hostent_dup (hp),
|
|
||||||
- exp = export_allowed (hp, rep->r_path))) {
|
|
||||||
+ (exp = export_allowed (hp, rep->r_path))))) {
|
|
||||||
/* see if the entry already exists, otherwise this was an instantiated
|
|
||||||
* wild card, and we must add it
|
|
||||||
*/
|
|
@ -1,8 +1,8 @@
|
|||||||
Summary: NFS utilities and supporting clients and daemons for the kernel NFS server
|
Summary: NFS utilities and supporting clients and daemons for the kernel NFS server
|
||||||
Name: nfs-utils
|
Name: nfs-utils
|
||||||
URL: http://sourceforge.net/projects/nfs
|
URL: http://sourceforge.net/projects/nfs
|
||||||
Version: 1.1.2
|
Version: 1.1.3
|
||||||
Release: 12%{?dist}
|
Release: 1%{?dist}
|
||||||
Epoch: 1
|
Epoch: 1
|
||||||
|
|
||||||
# group all 32bit related archs
|
# group all 32bit related archs
|
||||||
@ -23,37 +23,8 @@ Source14: rpcsvcgssd.init
|
|||||||
Source15: nfs.sysconfig
|
Source15: nfs.sysconfig
|
||||||
|
|
||||||
Patch00: nfs-utils-1.0.5-statdpath.patch
|
Patch00: nfs-utils-1.0.5-statdpath.patch
|
||||||
Patch01: nfs-utils-1.0.6-mountd.patch
|
Patch01: nfs-utils-1.1.2-smnotifypath.patch
|
||||||
Patch02: nfs-utils-1.0.6-gssd_mixed_case.patch
|
Patch02: nfs-utils-1.1.0-exp-subtree-warn-off.patch
|
||||||
Patch03: nfs-utils-1.1.0-showmount-rpcerror.patch
|
|
||||||
Patch04: nfs-utils-1.1.0-exp-subtree-warn-off.patch
|
|
||||||
Patch05: nfs-utils-1.1.0-exportfs-open.patch
|
|
||||||
Patch06: nfs-utils-1.1.0-exportfs-man-update.patch
|
|
||||||
Patch07: nfs-utils-1.1.2-multi-auth-flavours.patch
|
|
||||||
Patch08: nfs-utils-1.1.2-mount-eacces.patch
|
|
||||||
Patch09: nfs-utils-1.1.0-smnotify-path.patch
|
|
||||||
|
|
||||||
Patch101: nfs-utils-1.1.2-tcpwrapper-fix.patch
|
|
||||||
Patch102: nfs-utils-1.1.2-mount-retry.patch
|
|
||||||
Patch103: nfs-utils-1.1.2-mount-bg-fix.patch
|
|
||||||
Patch104: nfs-utils-1.1.2-mount-remove-bg-host.patch
|
|
||||||
Patch105: nfs-utils-1.1.2-gssd-getport.patch
|
|
||||||
Patch106: nfs-utils-1.1.2-gssd-des-types.patch
|
|
||||||
Patch107: nfs-utils-1.1.2-gssd-getverbose.patch
|
|
||||||
Patch108: nfs-utils-1.1.2-gssd-creds.patch
|
|
||||||
Patch109: nfs-utils-1.1.2-mount-chk-setuid.patch
|
|
||||||
Patch110: nfs-utils-1.1.2-exportfs-man-typo.patch
|
|
||||||
Patch111: nfs-utils-1.1.2-warnings.patch
|
|
||||||
Patch112: nfs-utils-1.1.2-mount-statd-chk.patch
|
|
||||||
Patch113: nfs-utils-1.1.2-mount-cleanup.patch
|
|
||||||
Patch114: nfs-utils-1.1.2-mount-error-reporting.patch
|
|
||||||
Patch115: nfs-utils-1.1.2-nfsstat-m-arg.patch
|
|
||||||
Patch116: nfs-utils-1.1.2-nfsstat-counters.patch
|
|
||||||
Patch117: nfs-utils-1.1.2-mountstats.patch
|
|
||||||
Patch118: nfs-utils-1.1.2-mountstats-rdma.patch
|
|
||||||
Patch119: nfs-utils-1.1.2-nfs-iostat.patch
|
|
||||||
Patch120: nfs-utils-1.1.2-nfs-iostat-rdma.patch
|
|
||||||
Patch121: nfs-utils-1.1.2-rmtab-fqdn.patch
|
|
||||||
|
|
||||||
%if %{enablefscache}
|
%if %{enablefscache}
|
||||||
Patch90: nfs-utils-1.1.0-mount-fsc.patch
|
Patch90: nfs-utils-1.1.0-mount-fsc.patch
|
||||||
@ -107,35 +78,6 @@ This package also contains the mount.nfs and umount.nfs program.
|
|||||||
%patch00 -p1
|
%patch00 -p1
|
||||||
%patch01 -p1
|
%patch01 -p1
|
||||||
%patch02 -p1
|
%patch02 -p1
|
||||||
%patch03 -p1
|
|
||||||
%patch04 -p1
|
|
||||||
%patch05 -p1
|
|
||||||
%patch06 -p1
|
|
||||||
%patch07 -p1
|
|
||||||
%patch08 -p1
|
|
||||||
%patch09 -p1
|
|
||||||
|
|
||||||
%patch101 -p1
|
|
||||||
%patch102 -p1
|
|
||||||
%patch103 -p1
|
|
||||||
%patch104 -p1
|
|
||||||
%patch105 -p1
|
|
||||||
%patch106 -p1
|
|
||||||
%patch107 -p1
|
|
||||||
%patch108 -p1
|
|
||||||
%patch109 -p1
|
|
||||||
%patch110 -p1
|
|
||||||
%patch111 -p1
|
|
||||||
%patch112 -p1
|
|
||||||
%patch113 -p1
|
|
||||||
%patch114 -p1
|
|
||||||
%patch115 -p1
|
|
||||||
%patch116 -p1
|
|
||||||
%patch117 -p1
|
|
||||||
%patch118 -p1
|
|
||||||
%patch119 -p1
|
|
||||||
%patch120 -p1
|
|
||||||
%patch121 -p1
|
|
||||||
|
|
||||||
%if %{enablefscache}
|
%if %{enablefscache}
|
||||||
%patch90 -p1
|
%patch90 -p1
|
||||||
@ -299,6 +241,9 @@ fi
|
|||||||
%attr(4755,root,root) /sbin/umount.nfs4
|
%attr(4755,root,root) /sbin/umount.nfs4
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Mon Jul 28 2008 Steve Dickson <steved@redhat.com> 1.1.3-1
|
||||||
|
- Updated to latest upstream version: 1.1.3
|
||||||
|
|
||||||
* Wed Jul 2 2008 Steve Dickson <steved@redhat.com> 1.1.2-12
|
* Wed Jul 2 2008 Steve Dickson <steved@redhat.com> 1.1.2-12
|
||||||
- Changed the default directories for sm-notify (bz 435480)
|
- Changed the default directories for sm-notify (bz 435480)
|
||||||
- Added 'condstop' to init scripts so service are not
|
- Added 'condstop' to init scripts so service are not
|
||||||
|
Loading…
Reference in New Issue
Block a user