Updated to latest upstream release: 1.2.0
This commit is contained in:
parent
5b1bacb347
commit
c1ec542e87
@ -1,3 +1,4 @@
|
|||||||
nfs.doc.tar.gz
|
nfs.doc.tar.gz
|
||||||
nfs-utils-1.1.6.tar.bz2
|
nfs-utils-1.1.6.tar.bz2
|
||||||
nfs-utils-1.2.0.tar.bz2
|
nfs-utils-1.2.0.tar.bz2
|
||||||
|
nfs-utils-1.2.1.tar.bz2
|
||||||
|
@ -1,694 +0,0 @@
|
|||||||
diff -up nfs-utils-1.2.0/support/export/xtab.c.orig nfs-utils-1.2.0/support/export/xtab.c
|
|
||||||
--- nfs-utils-1.2.0/support/export/xtab.c.orig 2009-06-02 10:43:05.000000000 -0400
|
|
||||||
+++ nfs-utils-1.2.0/support/export/xtab.c 2009-08-17 07:33:13.000000000 -0400
|
|
||||||
@@ -19,7 +19,9 @@
|
|
||||||
#include "exportfs.h"
|
|
||||||
#include "xio.h"
|
|
||||||
#include "xlog.h"
|
|
||||||
+#include "v4root.h"
|
|
||||||
|
|
||||||
+int v4root_needed;
|
|
||||||
static void cond_rename(char *newfile, char *oldfile);
|
|
||||||
|
|
||||||
static int
|
|
||||||
@@ -36,6 +38,8 @@ xtab_read(char *xtab, char *lockfn, int
|
|
||||||
if ((lockid = xflock(lockfn, "r")) < 0)
|
|
||||||
return 0;
|
|
||||||
setexportent(xtab, "r");
|
|
||||||
+ if (is_export == 1)
|
|
||||||
+ v4root_needed = 1;
|
|
||||||
while ((xp = getexportent(is_export==0, 0)) != NULL) {
|
|
||||||
if (!(exp = export_lookup(xp->e_hostname, xp->e_path, is_export != 1)) &&
|
|
||||||
!(exp = export_create(xp, is_export!=1))) {
|
|
||||||
@@ -48,6 +52,8 @@ xtab_read(char *xtab, char *lockfn, int
|
|
||||||
case 1:
|
|
||||||
exp->m_xtabent = 1;
|
|
||||||
exp->m_mayexport = 1;
|
|
||||||
+ if ((xp->e_flags & NFSEXP_FSID) && xp->e_fsid == 0)
|
|
||||||
+ v4root_needed = 0;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
exp->m_exported = -1;/* may be exported */
|
|
||||||
diff -up nfs-utils-1.2.0/support/include/exportfs.h.orig nfs-utils-1.2.0/support/include/exportfs.h
|
|
||||||
--- nfs-utils-1.2.0/support/include/exportfs.h.orig 2009-06-02 10:43:05.000000000 -0400
|
|
||||||
+++ nfs-utils-1.2.0/support/include/exportfs.h 2009-08-17 07:33:13.000000000 -0400
|
|
||||||
@@ -12,6 +12,17 @@
|
|
||||||
#include <netdb.h>
|
|
||||||
#include "nfslib.h"
|
|
||||||
|
|
||||||
+enum nfsd_fsid {
|
|
||||||
+ FSID_DEV = 0,
|
|
||||||
+ FSID_NUM,
|
|
||||||
+ FSID_MAJOR_MINOR,
|
|
||||||
+ FSID_ENCODE_DEV,
|
|
||||||
+ FSID_UUID4_INUM,
|
|
||||||
+ FSID_UUID8,
|
|
||||||
+ FSID_UUID16,
|
|
||||||
+ FSID_UUID16_INUM,
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
enum {
|
|
||||||
MCL_FQDN = 0,
|
|
||||||
MCL_SUBNETWORK,
|
|
||||||
diff -up nfs-utils-1.2.0/support/include/nfs/export.h.orig nfs-utils-1.2.0/support/include/nfs/export.h
|
|
||||||
--- nfs-utils-1.2.0/support/include/nfs/export.h.orig 2009-06-02 10:43:05.000000000 -0400
|
|
||||||
+++ nfs-utils-1.2.0/support/include/nfs/export.h 2009-08-17 07:33:13.000000000 -0400
|
|
||||||
@@ -24,6 +24,7 @@
|
|
||||||
#define NFSEXP_FSID 0x2000
|
|
||||||
#define NFSEXP_CROSSMOUNT 0x4000
|
|
||||||
#define NFSEXP_NOACL 0x8000 /* reserved for possible ACL related use */
|
|
||||||
-#define NFSEXP_ALLFLAGS 0xFFFF
|
|
||||||
+#define NFSEXP_V4ROOT 0x10000
|
|
||||||
+#define NFSEXP_ALLFLAGS 0x1FFFF
|
|
||||||
|
|
||||||
#endif /* _NSF_EXPORT_H */
|
|
||||||
diff -up nfs-utils-1.2.0/support/include/nfslib.h.orig nfs-utils-1.2.0/support/include/nfslib.h
|
|
||||||
--- nfs-utils-1.2.0/support/include/nfslib.h.orig 2009-08-17 07:31:52.000000000 -0400
|
|
||||||
+++ nfs-utils-1.2.0/support/include/nfslib.h 2009-08-17 07:33:13.000000000 -0400
|
|
||||||
@@ -88,6 +88,7 @@ struct exportent {
|
|
||||||
int e_fslocmethod;
|
|
||||||
char * e_fslocdata;
|
|
||||||
char * e_uuid;
|
|
||||||
+ void * e_v4root;
|
|
||||||
struct sec_entry e_secinfo[SECFLAVOR_COUNT+1];
|
|
||||||
};
|
|
||||||
|
|
||||||
diff -up /dev/null nfs-utils-1.2.0/support/include/v4root.h
|
|
||||||
--- /dev/null 2009-08-13 17:25:29.612003011 -0400
|
|
||||||
+++ nfs-utils-1.2.0/support/include/v4root.h 2009-08-17 07:33:13.000000000 -0400
|
|
||||||
@@ -0,0 +1,20 @@
|
|
||||||
+/*
|
|
||||||
+ * Copyright (C) 2009 Red Hat <nfs@redhat.com>
|
|
||||||
+ * support/include/v4root.h
|
|
||||||
+ *
|
|
||||||
+ * Support routines for dynamic pseudo roots.
|
|
||||||
+ *
|
|
||||||
+ */
|
|
||||||
+
|
|
||||||
+#ifndef V4ROOT_H
|
|
||||||
+#define V4ROOT_H
|
|
||||||
+
|
|
||||||
+extern int v4root_needed;
|
|
||||||
+
|
|
||||||
+extern struct exportent *v4root_chkroot(int , unsigned int , char *);
|
|
||||||
+extern struct exportent *v4root_export(char *, int);
|
|
||||||
+extern struct exportent *v4root_create(char *, nfs_export *, int);
|
|
||||||
+extern void v4root_free(struct exportent *);
|
|
||||||
+extern void v4root_unset(void), v4root_set(void);
|
|
||||||
+
|
|
||||||
+#endif /* V4ROOT_H */
|
|
||||||
diff -up nfs-utils-1.2.0/utils/mountd/auth.c.orig nfs-utils-1.2.0/utils/mountd/auth.c
|
|
||||||
--- nfs-utils-1.2.0/utils/mountd/auth.c.orig 2009-06-02 10:43:05.000000000 -0400
|
|
||||||
+++ nfs-utils-1.2.0/utils/mountd/auth.c 2009-08-17 07:33:13.000000000 -0400
|
|
||||||
@@ -20,6 +20,7 @@
|
|
||||||
#include "exportfs.h"
|
|
||||||
#include "mountd.h"
|
|
||||||
#include "xmalloc.h"
|
|
||||||
+#include "v4root.h"
|
|
||||||
|
|
||||||
enum auth_error
|
|
||||||
{
|
|
||||||
@@ -98,10 +99,13 @@ auth_reload()
|
|
||||||
last_inode = stb.st_ino;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ v4root_unset();
|
|
||||||
export_freeall();
|
|
||||||
memset(&my_client, 0, sizeof(my_client));
|
|
||||||
xtab_export_read();
|
|
||||||
check_useipaddr();
|
|
||||||
+ v4root_set();
|
|
||||||
+
|
|
||||||
++counter;
|
|
||||||
|
|
||||||
return counter;
|
|
||||||
diff -up nfs-utils-1.2.0/utils/mountd/cache.c.orig nfs-utils-1.2.0/utils/mountd/cache.c
|
|
||||||
--- nfs-utils-1.2.0/utils/mountd/cache.c.orig 2009-08-17 07:31:52.000000000 -0400
|
|
||||||
+++ nfs-utils-1.2.0/utils/mountd/cache.c 2009-08-17 07:33:13.000000000 -0400
|
|
||||||
@@ -32,23 +32,12 @@
|
|
||||||
#include "xmalloc.h"
|
|
||||||
#include "fsloc.h"
|
|
||||||
#include "pseudoflavors.h"
|
|
||||||
+#include "v4root.h"
|
|
||||||
|
|
||||||
#ifdef USE_BLKID
|
|
||||||
#include "blkid/blkid.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
-
|
|
||||||
-enum nfsd_fsid {
|
|
||||||
- FSID_DEV = 0,
|
|
||||||
- FSID_NUM,
|
|
||||||
- FSID_MAJOR_MINOR,
|
|
||||||
- FSID_ENCODE_DEV,
|
|
||||||
- FSID_UUID4_INUM,
|
|
||||||
- FSID_UUID8,
|
|
||||||
- FSID_UUID16,
|
|
||||||
- FSID_UUID16_INUM,
|
|
||||||
-};
|
|
||||||
-
|
|
||||||
/*
|
|
||||||
* Support routines for text-based upcalls.
|
|
||||||
* Fields are separated by spaces.
|
|
||||||
@@ -135,6 +124,8 @@ void auth_unix_gid(FILE *f)
|
|
||||||
if (readline(fileno(f), &lbuf, &lbuflen) != 1)
|
|
||||||
return;
|
|
||||||
|
|
||||||
+ xlog(D_CALL, "auth_unix_gid: '%s'", lbuf);
|
|
||||||
+
|
|
||||||
cp = lbuf;
|
|
||||||
if (qword_get_int(&cp, &uid) != 0)
|
|
||||||
return;
|
|
||||||
@@ -391,6 +382,12 @@ void nfsd_fh(FILE *f)
|
|
||||||
|
|
||||||
auth_reload();
|
|
||||||
|
|
||||||
+ /* Check to see if the kenel is looking for the pseudo root */
|
|
||||||
+ if ((found = v4root_chkroot(fsidtype, fsidnum, fhuuid))) {
|
|
||||||
+ found_path = strdup(found->e_path);
|
|
||||||
+ goto found;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
/* Now determine export point for this fsid/domain */
|
|
||||||
for (i=0 ; i < MCL_MAXTYPES; i++) {
|
|
||||||
nfs_export *next_exp;
|
|
||||||
@@ -511,7 +508,23 @@ void nfsd_fh(FILE *f)
|
|
||||||
*/
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
+ if (!found) {
|
|
||||||
+ /*
|
|
||||||
+ * See if this is a pesudo export
|
|
||||||
+ */
|
|
||||||
+ switch(fsidtype) {
|
|
||||||
+ case FSID_UUID4_INUM:
|
|
||||||
+ case FSID_UUID8:
|
|
||||||
+ case FSID_UUID16:
|
|
||||||
+ case FSID_UUID16_INUM:
|
|
||||||
+ found = v4root_export(fhuuid, uuidlen);
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
+ if (found)
|
|
||||||
+ found_path = strdup(found->e_path);
|
|
||||||
+ }
|
|
||||||
|
|
||||||
+found:
|
|
||||||
if (found)
|
|
||||||
if (cache_export_ent(dom, found, found_path) < 0)
|
|
||||||
found = 0;
|
|
||||||
@@ -629,6 +642,7 @@ void nfsd_export(FILE *f)
|
|
||||||
int found_type = 0;
|
|
||||||
struct in_addr addr;
|
|
||||||
struct hostent *he = NULL;
|
|
||||||
+ struct exportent *v4root = NULL;
|
|
||||||
|
|
||||||
|
|
||||||
if (readline(fileno(f), &lbuf, &lbuflen) != 1)
|
|
||||||
@@ -663,10 +677,18 @@ void nfsd_export(FILE *f)
|
|
||||||
path[l] == '/' &&
|
|
||||||
is_mountpoint(path)))
|
|
||||||
/* ok */;
|
|
||||||
- else
|
|
||||||
+ else {
|
|
||||||
+ /* See if the path is part of the psuedo root */
|
|
||||||
+ if (v4root_needed && !v4root)
|
|
||||||
+ v4root = v4root_create(path, exp, TRUE);
|
|
||||||
continue;
|
|
||||||
- } else if (strcmp(path, exp->m_export.e_path) != 0)
|
|
||||||
+ }
|
|
||||||
+ } else if (strcmp(path, exp->m_export.e_path) != 0) {
|
|
||||||
+ /* See if the path is part of the psuedo root */
|
|
||||||
+ if (v4root_needed && !v4root)
|
|
||||||
+ v4root = v4root_create(path, exp, TRUE);
|
|
||||||
continue;
|
|
||||||
+ }
|
|
||||||
if (use_ipaddr) {
|
|
||||||
if (he == NULL) {
|
|
||||||
if (!inet_aton(dom, &addr))
|
|
||||||
@@ -705,17 +727,28 @@ void nfsd_export(FILE *f)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (found) {
|
|
||||||
+ xlog(D_CALL, "nfsd_export: found: path %s", path);
|
|
||||||
if (dump_to_cache(f, dom, path, &found->m_export) < 0) {
|
|
||||||
xlog(L_WARNING,
|
|
||||||
"Cannot export %s, possibly unsupported filesystem"
|
|
||||||
" or fsid= required", path);
|
|
||||||
dump_to_cache(f, dom, path, NULL);
|
|
||||||
}
|
|
||||||
- } else {
|
|
||||||
+ } else if (v4root) {
|
|
||||||
+ xlog(D_CALL, "nfsd_export: vroot: path %s", path);
|
|
||||||
+ dump_to_cache(f, dom, path, v4root);
|
|
||||||
+ found = (nfs_export *)v4root;
|
|
||||||
+ } else {
|
|
||||||
dump_to_cache(f, dom, path, NULL);
|
|
||||||
}
|
|
||||||
out:
|
|
||||||
- xlog(D_CALL, "nfsd_export: found %p path %s", found, path ? path : NULL);
|
|
||||||
+ /*
|
|
||||||
+ * If a psuedo export was create and its not needed
|
|
||||||
+ * free it up.
|
|
||||||
+ */
|
|
||||||
+ if (v4root && found != (nfs_export *)v4root)
|
|
||||||
+ v4root_free(v4root);
|
|
||||||
+
|
|
||||||
if (dom) free(dom);
|
|
||||||
if (path) free(path);
|
|
||||||
if (he) free(he);
|
|
||||||
@@ -743,7 +776,9 @@ void cache_open(void)
|
|
||||||
if (!manage_gids && cachelist[i].cache_handle == auth_unix_gid)
|
|
||||||
continue;
|
|
||||||
sprintf(path, "/proc/net/rpc/%s/channel", cachelist[i].cache_name);
|
|
||||||
- cachelist[i].f = fopen(path, "r+");
|
|
||||||
+ if ((cachelist[i].f = fopen(path, "r+")) == NULL)
|
|
||||||
+ xlog(L_ERROR, "cache_open: Unable to open '%s': errno %d (%s)",
|
|
||||||
+ path, errno, strerror(errno));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
diff -up nfs-utils-1.2.0/utils/mountd/Makefile.am.orig nfs-utils-1.2.0/utils/mountd/Makefile.am
|
|
||||||
--- nfs-utils-1.2.0/utils/mountd/Makefile.am.orig 2009-06-02 10:43:05.000000000 -0400
|
|
||||||
+++ nfs-utils-1.2.0/utils/mountd/Makefile.am 2009-08-17 07:33:13.000000000 -0400
|
|
||||||
@@ -8,7 +8,7 @@ KPREFIX = @kprefix@
|
|
||||||
sbin_PROGRAMS = mountd
|
|
||||||
|
|
||||||
mountd_SOURCES = mountd.c mount_dispatch.c auth.c rmtab.c cache.c \
|
|
||||||
- svc_run.c fsloc.c mountd.h
|
|
||||||
+ svc_run.c fsloc.c v4root.c mountd.h
|
|
||||||
mountd_LDADD = ../../support/export/libexport.a \
|
|
||||||
../../support/nfs/libnfs.a \
|
|
||||||
../../support/misc/libmisc.a \
|
|
||||||
diff -up /dev/null nfs-utils-1.2.0/utils/mountd/v4root.c
|
|
||||||
--- /dev/null 2009-08-13 17:25:29.612003011 -0400
|
|
||||||
+++ nfs-utils-1.2.0/utils/mountd/v4root.c 2009-08-17 07:33:13.000000000 -0400
|
|
||||||
@@ -0,0 +1,409 @@
|
|
||||||
+/*
|
|
||||||
+ * Copyright (C) 2009 Red Hat <nfs@redhat.com>
|
|
||||||
+ *
|
|
||||||
+ * support/export/v4root.c
|
|
||||||
+ *
|
|
||||||
+ * Routines used to support NFSv4 pseudo roots
|
|
||||||
+ *
|
|
||||||
+ */
|
|
||||||
+
|
|
||||||
+#ifdef HAVE_CONFIG_H
|
|
||||||
+#include <config.h>
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
+#include <sys/types.h>
|
|
||||||
+#include <sys/stat.h>
|
|
||||||
+#include <sys/queue.h>
|
|
||||||
+#include <stdio.h>
|
|
||||||
+#include <stdlib.h>
|
|
||||||
+
|
|
||||||
+#include <uuid/uuid.h>
|
|
||||||
+#include <unistd.h>
|
|
||||||
+#include <errno.h>
|
|
||||||
+
|
|
||||||
+#include "xlog.h"
|
|
||||||
+#include "exportfs.h"
|
|
||||||
+#include "nfslib.h"
|
|
||||||
+#include "misc.h"
|
|
||||||
+#include "v4root.h"
|
|
||||||
+
|
|
||||||
+#ifndef _PATH_PSEUDO_ROOT
|
|
||||||
+#define _PATH_PSEUDO_ROOT "/"
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
+#ifndef _PSEUDO_ROOT_FSID
|
|
||||||
+#define _PSEUDO_ROOT_FSID 0
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
+extern int get_uuid(char *path, char *uuid, int uuidlen, char *u);
|
|
||||||
+
|
|
||||||
+typedef struct _exports_t {
|
|
||||||
+ TAILQ_ENTRY(_exports_t) list;
|
|
||||||
+ char *path;
|
|
||||||
+ void *head;
|
|
||||||
+ char uuid_len;
|
|
||||||
+ char uuid[sizeof(uuid_t)];
|
|
||||||
+ struct exportent p_export;
|
|
||||||
+} exports_t;
|
|
||||||
+
|
|
||||||
+#define HASH_TABLE_SIZE 1021
|
|
||||||
+typedef struct _hash_head {
|
|
||||||
+ TAILQ_HEAD(export_list, _exports_t) h_head;
|
|
||||||
+} hash_head;
|
|
||||||
+hash_head exports_tbl[HASH_TABLE_SIZE];
|
|
||||||
+
|
|
||||||
+
|
|
||||||
+static exports_t *hash_export_lookup(char *, unsigned int);
|
|
||||||
+static void hash_export_add(struct _exports_t *, int);
|
|
||||||
+static void hash_mount_free(void);
|
|
||||||
+
|
|
||||||
+static inline unsigned int strtoint(char *str, int len)
|
|
||||||
+{
|
|
||||||
+ unsigned int n = 0;
|
|
||||||
+ int i;
|
|
||||||
+
|
|
||||||
+ for (i=0; i < len; i++)
|
|
||||||
+ n+=((int)str[i])*i;
|
|
||||||
+ return n;
|
|
||||||
+}
|
|
||||||
+static inline int hashint(unsigned int num)
|
|
||||||
+{
|
|
||||||
+ return num % HASH_TABLE_SIZE;
|
|
||||||
+}
|
|
||||||
+#define HASH(_s, _l) hashint(strtoint((_s), (_l)))
|
|
||||||
+void v4root_set(void);
|
|
||||||
+void v4root_unset(void);
|
|
||||||
+
|
|
||||||
+int v4root_needed;
|
|
||||||
+
|
|
||||||
+static nfs_export pr_export = {
|
|
||||||
+ .m_next = NULL,
|
|
||||||
+ .m_client = NULL,
|
|
||||||
+ .m_export = {
|
|
||||||
+ .e_hostname = "*",
|
|
||||||
+ .e_path = _PATH_PSEUDO_ROOT,
|
|
||||||
+ .e_flags = NFSEXP_READONLY | NFSEXP_ROOTSQUASH
|
|
||||||
+ | NFSEXP_NOSUBTREECHECK | NFSEXP_FSID
|
|
||||||
+ | NFSEXP_CROSSMOUNT | NFSEXP_V4ROOT,
|
|
||||||
+ .e_anonuid = 65534,
|
|
||||||
+ .e_anongid = 65534,
|
|
||||||
+ .e_squids = NULL,
|
|
||||||
+ .e_nsquids = 0,
|
|
||||||
+ .e_sqgids = NULL,
|
|
||||||
+ .e_nsqgids = 0,
|
|
||||||
+ .e_fsid = 0,
|
|
||||||
+ .e_mountpoint = NULL,
|
|
||||||
+ },
|
|
||||||
+ .m_exported = 0,
|
|
||||||
+ .m_xtabent = 1,
|
|
||||||
+ .m_mayexport = 1,
|
|
||||||
+ .m_changed = 0,
|
|
||||||
+ .m_warned = 0,
|
|
||||||
+};
|
|
||||||
+static nfs_export *pseudo_root;
|
|
||||||
+
|
|
||||||
+/*
|
|
||||||
+ * Return the number '/' in the path
|
|
||||||
+ */
|
|
||||||
+inline static int slash_count(char *path)
|
|
||||||
+{
|
|
||||||
+ int i, slashs=0;
|
|
||||||
+
|
|
||||||
+ for (i=0; i < strlen(path); i++) {
|
|
||||||
+ if (path[i] == '/')
|
|
||||||
+ slashs++;
|
|
||||||
+ }
|
|
||||||
+ return slashs;
|
|
||||||
+}
|
|
||||||
+/*
|
|
||||||
+ * Make sure the kernel has pseudo root support.
|
|
||||||
+ */
|
|
||||||
+static int
|
|
||||||
+v4root_support()
|
|
||||||
+{
|
|
||||||
+ static int kernel_support = -1;
|
|
||||||
+ char *ptr, version[64];
|
|
||||||
+ int major, minor;
|
|
||||||
+ FILE *fp;
|
|
||||||
+
|
|
||||||
+ if (kernel_support != -1)
|
|
||||||
+ return kernel_support;
|
|
||||||
+
|
|
||||||
+ kernel_support = 0;
|
|
||||||
+ fp = fopen("/proc/fs/nfsd/exports", "r");
|
|
||||||
+ if (fp == NULL)
|
|
||||||
+ goto out;
|
|
||||||
+
|
|
||||||
+ ptr = fgets(version, 64, fp);
|
|
||||||
+ fclose(fp);
|
|
||||||
+ if (ptr == NULL)
|
|
||||||
+ goto out;
|
|
||||||
+
|
|
||||||
+ while(*ptr && isdigit(*ptr) == 0)
|
|
||||||
+ ptr++;
|
|
||||||
+ if (*ptr == '\0')
|
|
||||||
+ goto out;
|
|
||||||
+
|
|
||||||
+ major = minor = 0;
|
|
||||||
+ sscanf(ptr, " %d.%d",&major, &minor);
|
|
||||||
+ if (major >= 1 && minor >= 2)
|
|
||||||
+ kernel_support = 1;
|
|
||||||
+out:
|
|
||||||
+ if (!kernel_support) {
|
|
||||||
+ xlog(L_WARNING, "Kernel does not have psuedo root support.");
|
|
||||||
+ xlog(L_WARNING, "NFS v4 mounts will be disabled unless fsid=0");
|
|
||||||
+ xlog(L_WARNING, "is specfied in /etc/exports file.");
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return kernel_support;
|
|
||||||
+}
|
|
||||||
+/*
|
|
||||||
+ * Build a table of pseudo exports by running through
|
|
||||||
+ * the real export looking at the components of the path
|
|
||||||
+ * that make up the export. Those path components, if not
|
|
||||||
+ * not exported, will be come pseudo exports allow them
|
|
||||||
+ * to be found when the kernel does an upcall looking for
|
|
||||||
+ * components of the v4 mount.
|
|
||||||
+ */
|
|
||||||
+void
|
|
||||||
+v4root_set()
|
|
||||||
+{
|
|
||||||
+ nfs_export *exp, *nxt;
|
|
||||||
+ int i, slcnt;
|
|
||||||
+ char *e_path, *path, *ptr, *comp;
|
|
||||||
+ char *hostname;
|
|
||||||
+
|
|
||||||
+ if (!v4root_needed)
|
|
||||||
+ return;
|
|
||||||
+
|
|
||||||
+ if (!v4root_support())
|
|
||||||
+ return;
|
|
||||||
+
|
|
||||||
+ pseudo_root = &pr_export;
|
|
||||||
+
|
|
||||||
+ for (i = 0; i < MCL_MAXTYPES; i++) {
|
|
||||||
+ for (exp = exportlist[i].p_head; exp; exp = nxt) {
|
|
||||||
+ nxt = exp->m_next;
|
|
||||||
+ e_path = exp->m_export.e_path;
|
|
||||||
+ hostname = exp->m_export.e_hostname;
|
|
||||||
+
|
|
||||||
+ if ((slcnt = slash_count(e_path)) < 2)
|
|
||||||
+ continue;
|
|
||||||
+ slcnt--; /* knock off the leanding '/' */
|
|
||||||
+
|
|
||||||
+ path = strdup(e_path);
|
|
||||||
+ if ((ptr = strrchr(path, '/')) != NULL)
|
|
||||||
+ *ptr = '\0';
|
|
||||||
+
|
|
||||||
+ /*
|
|
||||||
+ * Run through each component of the path to
|
|
||||||
+ * see if a pseudo export should be create.
|
|
||||||
+ */
|
|
||||||
+ comp = path+1;
|
|
||||||
+ do {
|
|
||||||
+ if ((ptr = strchr(comp, '/')) != NULL)
|
|
||||||
+ *ptr = '\0';
|
|
||||||
+
|
|
||||||
+ if (export_lookup(hostname, path, 0) == NULL)
|
|
||||||
+ v4root_create(path, exp, FALSE);
|
|
||||||
+
|
|
||||||
+ if (ptr) {
|
|
||||||
+ *ptr = '/';
|
|
||||||
+ comp = ptr+1;
|
|
||||||
+ }
|
|
||||||
+ } while (--slcnt > 0);
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+/*
|
|
||||||
+ * Unset the pseudo root export
|
|
||||||
+ */
|
|
||||||
+void
|
|
||||||
+v4root_unset()
|
|
||||||
+{
|
|
||||||
+ pseudo_root = NULL;
|
|
||||||
+ hash_mount_free();
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+/*
|
|
||||||
+ * The kernel will do an upcall looking for the pseudo
|
|
||||||
+ * root via its fsid. When the wanted fsid equals
|
|
||||||
+ * PSEUDO_ROOT_FSID return the pseudo root export.
|
|
||||||
+ */
|
|
||||||
+struct exportent *
|
|
||||||
+v4root_chkroot(int fsidtype, unsigned int fsidnum, char *fhuuid)
|
|
||||||
+{
|
|
||||||
+ struct exportent *p_export = NULL;
|
|
||||||
+
|
|
||||||
+ if (pseudo_root == NULL)
|
|
||||||
+ return NULL;
|
|
||||||
+
|
|
||||||
+ switch(fsidtype) {
|
|
||||||
+ case FSID_NUM:
|
|
||||||
+ if (fsidnum == _PSEUDO_ROOT_FSID) {
|
|
||||||
+ p_export = &pseudo_root->m_export;
|
|
||||||
+ strncpy(p_export->e_path, _PATH_PSEUDO_ROOT,
|
|
||||||
+ NFS_MAXPATHLEN);
|
|
||||||
+ }
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return p_export;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+/*
|
|
||||||
+ * Create a psuedo export, if one does not
|
|
||||||
+ * already exist.
|
|
||||||
+ */
|
|
||||||
+struct exportent *
|
|
||||||
+v4root_create(char *path, nfs_export *exp, int docheck)
|
|
||||||
+{
|
|
||||||
+ static struct exportent *p_export = NULL;
|
|
||||||
+ exports_t *pexp;
|
|
||||||
+ char *epath = exp->m_export.e_path;
|
|
||||||
+ char *hostname = exp->m_export.e_hostname;
|
|
||||||
+ int elen, plen, i;
|
|
||||||
+ char uuid_len = sizeof(uuid_t);
|
|
||||||
+ char uuid[sizeof(uuid_t)];
|
|
||||||
+
|
|
||||||
+ if (pseudo_root == NULL)
|
|
||||||
+ return NULL;
|
|
||||||
+
|
|
||||||
+ if (docheck) {
|
|
||||||
+
|
|
||||||
+ /* Path needs to be an subset of e_path */
|
|
||||||
+ elen = strlen(epath);
|
|
||||||
+ plen = strlen(path);
|
|
||||||
+ if (plen >= elen)
|
|
||||||
+ return NULL;
|
|
||||||
+
|
|
||||||
+ for (i=0; i < plen; i++) {
|
|
||||||
+ if (path[i] != epath[i])
|
|
||||||
+ return NULL;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ /* Check to see if the export already exists */
|
|
||||||
+ get_uuid(path, NULL, uuid_len, uuid);
|
|
||||||
+ if ((p_export = v4root_export(uuid, uuid_len)) != NULL)
|
|
||||||
+ return p_export;
|
|
||||||
+
|
|
||||||
+ pexp = (exports_t *)malloc(sizeof(exports_t));
|
|
||||||
+ if (pexp == NULL) {
|
|
||||||
+ xlog(L_WARNING, "v4root_create: No memory for psuedo export");
|
|
||||||
+ return NULL;
|
|
||||||
+ }
|
|
||||||
+ p_export = &pexp->p_export;
|
|
||||||
+ pexp->path = strdup(path);
|
|
||||||
+
|
|
||||||
+ pexp->uuid_len = uuid_len;
|
|
||||||
+ memcpy(pexp->uuid, uuid, uuid_len);
|
|
||||||
+
|
|
||||||
+ memcpy(&pexp->p_export, &pr_export.m_export,
|
|
||||||
+ sizeof(struct exportent));
|
|
||||||
+ strcpy(p_export->e_path, path);
|
|
||||||
+ p_export->e_flags &= ~NFSEXP_FSID;
|
|
||||||
+ p_export->e_v4root = (void *)pexp;
|
|
||||||
+
|
|
||||||
+ hash_export_add(pexp, HASH(pexp->uuid, sizeof(uuid_t)));
|
|
||||||
+
|
|
||||||
+ xlog(D_CALL, "v4root_create: path '%s'", p_export->e_path);
|
|
||||||
+
|
|
||||||
+ return p_export;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+/*
|
|
||||||
+ * Free a psuedo export
|
|
||||||
+ */
|
|
||||||
+void
|
|
||||||
+v4root_free(struct exportent *p_export)
|
|
||||||
+{
|
|
||||||
+ exports_t *pexp = (exports_t *)p_export->e_v4root;
|
|
||||||
+ hash_head *head = (hash_head *)pexp->head;
|
|
||||||
+
|
|
||||||
+ free(pexp->path);
|
|
||||||
+ TAILQ_REMOVE(&head->h_head, pexp, list);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+/*
|
|
||||||
+ * Return a psuedo export that match the given uuid
|
|
||||||
+ */
|
|
||||||
+struct exportent *
|
|
||||||
+v4root_export(char *fhuuid, int uuidlen)
|
|
||||||
+{
|
|
||||||
+ struct exportent *p_export = NULL;
|
|
||||||
+ exports_t *pexp;
|
|
||||||
+ int len = MIN(uuidlen, sizeof(uuid_t));
|
|
||||||
+
|
|
||||||
+ if (pseudo_root == NULL)
|
|
||||||
+ return NULL;
|
|
||||||
+
|
|
||||||
+ pexp = hash_export_lookup(fhuuid, len);
|
|
||||||
+ if (pexp) {
|
|
||||||
+ p_export = &pexp->p_export;
|
|
||||||
+ xlog(D_CALL, "v4root_export: path %s", p_export->e_path);
|
|
||||||
+ }
|
|
||||||
+ return p_export;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+/*
|
|
||||||
+ * Add psuedo export to export table
|
|
||||||
+ */
|
|
||||||
+static void hash_export_add(struct _exports_t *exp, int hash)
|
|
||||||
+{
|
|
||||||
+ hash_head *head;
|
|
||||||
+
|
|
||||||
+ head = &(exports_tbl[hash]);
|
|
||||||
+ exp->head = head;
|
|
||||||
+
|
|
||||||
+ if (TAILQ_EMPTY(&head->h_head))
|
|
||||||
+ TAILQ_INSERT_HEAD(&head->h_head, exp, list);
|
|
||||||
+ else
|
|
||||||
+ TAILQ_INSERT_TAIL(&head->h_head, exp, list);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+/*
|
|
||||||
+ * Lookup a psuedo export using the uuid and inode number
|
|
||||||
+ */
|
|
||||||
+static exports_t *
|
|
||||||
+hash_export_lookup(char *uuid, unsigned int uuidlen)
|
|
||||||
+{
|
|
||||||
+ exports_t *pexp;
|
|
||||||
+ hash_head *head;
|
|
||||||
+ int hash = HASH(uuid, uuidlen);
|
|
||||||
+
|
|
||||||
+ head = &(exports_tbl[hash]);
|
|
||||||
+
|
|
||||||
+ TAILQ_FOREACH(pexp, &head->h_head, list) {
|
|
||||||
+ if (memcmp(pexp->uuid, uuid, uuidlen) == 0)
|
|
||||||
+ return pexp;
|
|
||||||
+ }
|
|
||||||
+ return NULL;
|
|
||||||
+
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+/*
|
|
||||||
+ * Free up psuedo export table
|
|
||||||
+ */
|
|
||||||
+static void hash_mount_free()
|
|
||||||
+{
|
|
||||||
+ hash_head *head;
|
|
||||||
+ exports_t *e1, *e2;
|
|
||||||
+ int hash;
|
|
||||||
+
|
|
||||||
+ for (hash=0; hash < HASH_TABLE_SIZE; hash++) {
|
|
||||||
+ head = &(exports_tbl[hash]);
|
|
||||||
+ if (head == NULL)
|
|
||||||
+ continue;
|
|
||||||
+ e1 = TAILQ_FIRST(&head->h_head);
|
|
||||||
+ while (e1 != NULL) {
|
|
||||||
+ free(e1->path);
|
|
||||||
+ e2 = TAILQ_NEXT(e1, list);
|
|
||||||
+ TAILQ_REMOVE(&head->h_head, e1, list);
|
|
||||||
+ free(e1);
|
|
||||||
+ e1 = e2;
|
|
||||||
+ }
|
|
||||||
+ TAILQ_INIT(&head->h_head);
|
|
||||||
+ }
|
|
||||||
+}
|
|
@ -1,32 +0,0 @@
|
|||||||
Author: Steve Dickson <steved@redhat.com>
|
|
||||||
Date: Tue Oct 20 10:25:34 EDT 2009
|
|
||||||
|
|
||||||
Retry v4 mounts with a v3 mount when the version
|
|
||||||
is not explicitly specified and the mount fails
|
|
||||||
with ENOENT. The will help deal with Linux servers
|
|
||||||
that do not automatically export a pseudo root
|
|
||||||
|
|
||||||
Signed-off-by: Steve Dickson <steved@redhat.com>
|
|
||||||
|
|
||||||
diff -up nfs-utils-1.2.0/utils/mount/stropts.c.orig nfs-utils-1.2.0/utils/mount/stropts.c
|
|
||||||
--- nfs-utils-1.2.0/utils/mount/stropts.c.orig 2009-10-20 10:11:03.000000000 -0400
|
|
||||||
+++ nfs-utils-1.2.0/utils/mount/stropts.c 2009-10-20 10:24:41.000000000 -0400
|
|
||||||
@@ -613,8 +613,15 @@ static int nfs_try_mount(struct nfsmount
|
|
||||||
if (linux_version_code() > MAKE_VERSION(2, 6, 31)) {
|
|
||||||
errno = 0;
|
|
||||||
result = nfs_try_mount_v4(mi);
|
|
||||||
- if (errno != EPROTONOSUPPORT)
|
|
||||||
- break;
|
|
||||||
+ if (errno != EPROTONOSUPPORT) {
|
|
||||||
+ /*
|
|
||||||
+ * To deal with legacy Linux servers that don't
|
|
||||||
+ * automatically export a pseudo root, retry
|
|
||||||
+ * ENOENT errors using version 3
|
|
||||||
+ */
|
|
||||||
+ if (errno != ENOENT)
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
case 2:
|
|
||||||
case 3:
|
|
||||||
|
|
@ -1,64 +0,0 @@
|
|||||||
commit 1aa4121ba599de836702d7b2d38cad63e6a09044
|
|
||||||
Author: Steve Dickson <steved@redhat.com>
|
|
||||||
Date: Mon Jun 29 10:44:20 2009 -0400
|
|
||||||
|
|
||||||
mydaemon: remove closeall() calls from mydaemon()
|
|
||||||
|
|
||||||
idmapd and svcgssd have a mydaemon() routine that uses closeall() to
|
|
||||||
close file descriptors. Unfortunately, they aren't using it correctly
|
|
||||||
and it ends up closing the pipe that the child process uses to talk to
|
|
||||||
its parent.
|
|
||||||
|
|
||||||
Fix this by not using closeall() in this routine and instead, just close
|
|
||||||
the file descriptors that we know need to be closed. If /dev/null can't
|
|
||||||
be opened for some reason, then just have the child exit with a non-zero
|
|
||||||
error.
|
|
||||||
|
|
||||||
Signed-off-by: Jeff Layton <jlayton@redhat.com>
|
|
||||||
Signed-off-by: Steve Dickson <steved@redhat.com>
|
|
||||||
|
|
||||||
diff --git a/utils/gssd/svcgssd.c b/utils/gssd/svcgssd.c
|
|
||||||
index 69d2a69..729b6a6 100644
|
|
||||||
--- a/utils/gssd/svcgssd.c
|
|
||||||
+++ b/utils/gssd/svcgssd.c
|
|
||||||
@@ -117,10 +117,16 @@ mydaemon(int nochdir, int noclose)
|
|
||||||
|
|
||||||
if (noclose == 0) {
|
|
||||||
tempfd = open("/dev/null", O_RDWR);
|
|
||||||
- dup2(tempfd, 0);
|
|
||||||
- dup2(tempfd, 1);
|
|
||||||
- dup2(tempfd, 2);
|
|
||||||
- closeall(3);
|
|
||||||
+ if (tempfd >= 0) {
|
|
||||||
+ dup2(tempfd, 0);
|
|
||||||
+ dup2(tempfd, 1);
|
|
||||||
+ dup2(tempfd, 2);
|
|
||||||
+ close(tempfd);
|
|
||||||
+ } else {
|
|
||||||
+ printerr(1, "mydaemon: can't open /dev/null: errno %d "
|
|
||||||
+ "(%s)\n", errno, strerror(errno));
|
|
||||||
+ exit(1);
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
diff --git a/utils/idmapd/idmapd.c b/utils/idmapd/idmapd.c
|
|
||||||
index b690e21..9cbe96c 100644
|
|
||||||
--- a/utils/idmapd/idmapd.c
|
|
||||||
+++ b/utils/idmapd/idmapd.c
|
|
||||||
@@ -978,9 +978,12 @@ mydaemon(int nochdir, int noclose)
|
|
||||||
dup2(tempfd, 0);
|
|
||||||
dup2(tempfd, 1);
|
|
||||||
dup2(tempfd, 2);
|
|
||||||
- closeall(3);
|
|
||||||
- } else
|
|
||||||
- closeall(0);
|
|
||||||
+ close(tempfd);
|
|
||||||
+ } else {
|
|
||||||
+ err(1, "mydaemon: can't open /dev/null: errno %d",
|
|
||||||
+ errno);
|
|
||||||
+ exit(1);
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
@ -1,173 +0,0 @@
|
|||||||
diff --git a/aclocal/ipv6.m4 b/aclocal/ipv6.m4
|
|
||||||
index ba9dcc2..2490f3d 100644
|
|
||||||
--- a/aclocal/ipv6.m4
|
|
||||||
+++ b/aclocal/ipv6.m4
|
|
||||||
@@ -11,7 +11,7 @@ AC_DEFUN([AC_IPV6], [
|
|
||||||
|
|
||||||
dnl TI-RPC required for IPv6
|
|
||||||
if test "$enable_tirpc" = no; then
|
|
||||||
- AC_MSG_ERROR(['--enable-ipv6' requires '--enable-tirpc'.])
|
|
||||||
+ AC_MSG_ERROR(['--enable-ipv6' requires TIRPC support.])
|
|
||||||
fi
|
|
||||||
|
|
||||||
dnl IPv6-enabled networking functions required for IPv6
|
|
||||||
diff --git a/aclocal/libtirpc.m4 b/aclocal/libtirpc.m4
|
|
||||||
index af4c7d3..9f0fde0 100644
|
|
||||||
--- a/aclocal/libtirpc.m4
|
|
||||||
+++ b/aclocal/libtirpc.m4
|
|
||||||
@@ -11,17 +11,29 @@ AC_DEFUN([AC_LIBTIRPC], [
|
|
||||||
dnl if --enable-tirpc was specifed, the following components
|
|
||||||
dnl must be present, and we set up HAVE_ macros for them.
|
|
||||||
|
|
||||||
- if test "$enable_tirpc" = yes; then
|
|
||||||
+ if test "$enable_tirpc" != "no"; then
|
|
||||||
|
|
||||||
dnl look for the library; add to LIBS if found
|
|
||||||
AC_CHECK_LIB([tirpc], [clnt_tli_create], ,
|
|
||||||
- [AC_MSG_ERROR([libtirpc not found.])])
|
|
||||||
+ [if test "$enable_tirpc" = "yes"; then
|
|
||||||
+ AC_MSG_ERROR([libtirpc not found.])
|
|
||||||
+ else
|
|
||||||
+ AC_MSG_WARN([libtirpc not found. TIRPC disabled!])
|
|
||||||
+ enable_tirpc="no"
|
|
||||||
+ fi])
|
|
||||||
+ fi
|
|
||||||
|
|
||||||
+ if test "$enable_tirpc" != "no"; then
|
|
||||||
dnl also must have the headers installed where we expect
|
|
||||||
dnl look for headers; add -I compiler option if found
|
|
||||||
- AC_CHECK_HEADERS([${tirpc_header_dir}/netconfig.h], ,
|
|
||||||
- [AC_MSG_ERROR([libtirpc headers not found.])])
|
|
||||||
- AC_SUBST([AM_CPPFLAGS], ["-I${tirpc_header_dir}"])
|
|
||||||
+ AC_CHECK_HEADERS([${tirpc_header_dir}/netconfig.h],
|
|
||||||
+ AC_SUBST([AM_CPPFLAGS], ["-I${tirpc_header_dir}"]),
|
|
||||||
+ [if test "$enable_tirpc" = "yes"; then
|
|
||||||
+ AC_MSG_ERROR([libtirpc headers not found.])
|
|
||||||
+ else
|
|
||||||
+ AC_MSG_WARN([libtirpc headers not found. TIRPC disabled!])
|
|
||||||
+ enable_tirpc="no"
|
|
||||||
+ fi])
|
|
||||||
|
|
||||||
fi
|
|
||||||
|
|
||||||
diff --git a/configure.ac b/configure.ac
|
|
||||||
index e09e1d9..e0ca70e 100644
|
|
||||||
--- a/configure.ac
|
|
||||||
+++ b/configure.ac
|
|
||||||
@@ -1,6 +1,6 @@
|
|
||||||
dnl Process this file with autoconf to produce a configure script.
|
|
||||||
dnl
|
|
||||||
-AC_INIT([linux nfs-utils],[1.1.6],[linux-nfs@vger.kernel.org],[nfs-utils])
|
|
||||||
+AC_INIT([linux nfs-utils],[1.2.0],[linux-nfs@vger.kernel.org],[nfs-utils])
|
|
||||||
AC_CANONICAL_BUILD([])
|
|
||||||
AC_CANONICAL_HOST([])
|
|
||||||
AC_CONFIG_MACRO_DIR(aclocal)
|
|
||||||
@@ -120,9 +120,9 @@ AC_ARG_ENABLE(mount,
|
|
||||||
AM_CONDITIONAL(CONFIG_MOUNT, [test "$enable_mount" = "yes"])
|
|
||||||
AC_ARG_ENABLE(tirpc,
|
|
||||||
[AC_HELP_STRING([--enable-tirpc],
|
|
||||||
- [enable use of TI-RPC @<:@default=no@:>@])],
|
|
||||||
+ [enable use of TI-RPC @<:@default=yes@:>@])],
|
|
||||||
enable_tirpc=$enableval,
|
|
||||||
- enable_tirpc=no)
|
|
||||||
+ enable_tirpc='yes')
|
|
||||||
AC_ARG_ENABLE(ipv6,
|
|
||||||
[AC_HELP_STRING([--enable-ipv6],
|
|
||||||
[enable support for IPv6 @<:@default=no@:>@])],
|
|
||||||
diff --git a/support/nfs/closeall.c b/support/nfs/closeall.c
|
|
||||||
index cc7fb3b..38fb162 100644
|
|
||||||
--- a/support/nfs/closeall.c
|
|
||||||
+++ b/support/nfs/closeall.c
|
|
||||||
@@ -7,19 +7,24 @@
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <dirent.h>
|
|
||||||
+#include <errno.h>
|
|
||||||
|
|
||||||
void
|
|
||||||
closeall(int min)
|
|
||||||
{
|
|
||||||
+ char *endp;
|
|
||||||
+ long n;
|
|
||||||
DIR *dir = opendir("/proc/self/fd");
|
|
||||||
+
|
|
||||||
if (dir != NULL) {
|
|
||||||
int dfd = dirfd(dir);
|
|
||||||
struct dirent *d;
|
|
||||||
|
|
||||||
while ((d = readdir(dir)) != NULL) {
|
|
||||||
- char *endp;
|
|
||||||
- long n = strtol(d->d_name, &endp, 10);
|
|
||||||
- if (*endp != '\0' && n >= min && n != dfd)
|
|
||||||
+ errno = 0;
|
|
||||||
+ n = strtol(d->d_name, &endp, 10);
|
|
||||||
+ if (!errno && *endp == '\0' && endp != d->d_name &&
|
|
||||||
+ n >= min && n != dfd)
|
|
||||||
(void) close(n);
|
|
||||||
}
|
|
||||||
closedir(dir);
|
|
||||||
diff --git a/utils/gssd/gssd.c b/utils/gssd/gssd.c
|
|
||||||
index f6949db..40a2b4d 100644
|
|
||||||
--- a/utils/gssd/gssd.c
|
|
||||||
+++ b/utils/gssd/gssd.c
|
|
||||||
@@ -171,6 +171,8 @@ main(int argc, char *argv[])
|
|
||||||
|
|
||||||
initerr(progname, verbosity, fg);
|
|
||||||
#ifdef HAVE_AUTHGSS_SET_DEBUG_LEVEL
|
|
||||||
+ if (verbosity && rpc_verbosity == 0)
|
|
||||||
+ rpc_verbosity = verbosity;
|
|
||||||
authgss_set_debug_level(rpc_verbosity);
|
|
||||||
#else
|
|
||||||
if (rpc_verbosity > 0)
|
|
||||||
diff --git a/utils/gssd/svcgssd.c b/utils/gssd/svcgssd.c
|
|
||||||
index 6ca0e8d..69d2a69 100644
|
|
||||||
--- a/utils/gssd/svcgssd.c
|
|
||||||
+++ b/utils/gssd/svcgssd.c
|
|
||||||
@@ -208,6 +208,8 @@ main(int argc, char *argv[])
|
|
||||||
|
|
||||||
initerr(progname, verbosity, fg);
|
|
||||||
#ifdef HAVE_AUTHGSS_SET_DEBUG_LEVEL
|
|
||||||
+ if (verbosity && rpc_verbosity == 0)
|
|
||||||
+ rpc_verbosity = verbosity;
|
|
||||||
authgss_set_debug_level(rpc_verbosity);
|
|
||||||
#else
|
|
||||||
if (rpc_verbosity > 0)
|
|
||||||
@@ -215,6 +217,8 @@ main(int argc, char *argv[])
|
|
||||||
"support setting debug level\n");
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_NFS4_SET_DEBUG
|
|
||||||
+ if (verbosity && idmap_verbosity == 0)
|
|
||||||
+ idmap_verbosity = verbosity;
|
|
||||||
nfs4_set_debug(idmap_verbosity, NULL);
|
|
||||||
#else
|
|
||||||
if (idmap_verbosity > 0)
|
|
||||||
diff --git a/utils/mountd/mountd.c b/utils/mountd/mountd.c
|
|
||||||
index 25d292b..b59f939 100644
|
|
||||||
--- a/utils/mountd/mountd.c
|
|
||||||
+++ b/utils/mountd/mountd.c
|
|
||||||
@@ -467,8 +467,12 @@ get_rootfh(struct svc_req *rqstp, dirpath *path, nfs_export **expret,
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
- if (exp->m_exported<1)
|
|
||||||
+ int did_export = 0;
|
|
||||||
+ retry:
|
|
||||||
+ if (exp->m_exported<1) {
|
|
||||||
export_export(exp);
|
|
||||||
+ did_export = 1;
|
|
||||||
+ }
|
|
||||||
if (!exp->m_xtabent)
|
|
||||||
xtab_append(exp);
|
|
||||||
|
|
||||||
@@ -482,6 +486,11 @@ get_rootfh(struct svc_req *rqstp, dirpath *path, nfs_export **expret,
|
|
||||||
fh = getfh_old ((struct sockaddr *) sin,
|
|
||||||
stb.st_dev, stb.st_ino);
|
|
||||||
}
|
|
||||||
+ if (fh == NULL && !did_export) {
|
|
||||||
+ exp->m_exported = 0;
|
|
||||||
+ goto retry;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
if (fh == NULL) {
|
|
||||||
xlog(L_WARNING, "getfh failed: %s", strerror(errno));
|
|
||||||
*error = NFSERR_ACCES;
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,744 +0,0 @@
|
|||||||
diff --git a/support/include/conffile.h b/support/include/conffile.h
|
|
||||||
index 132a149..672020a 100644
|
|
||||||
--- a/support/include/conffile.h
|
|
||||||
+++ b/support/include/conffile.h
|
|
||||||
@@ -34,6 +34,7 @@
|
|
||||||
#define _CONFFILE_H_
|
|
||||||
|
|
||||||
#include <sys/queue.h>
|
|
||||||
+#include <ctype.h>
|
|
||||||
|
|
||||||
struct conf_list_node {
|
|
||||||
TAILQ_ENTRY(conf_list_node) link;
|
|
||||||
diff --git a/tools/nfs-iostat/nfs-iostat.py b/tools/nfs-iostat/nfs-iostat.py
|
|
||||||
index 9626d42..2d0b143 100644
|
|
||||||
--- a/tools/nfs-iostat/nfs-iostat.py
|
|
||||||
+++ b/tools/nfs-iostat/nfs-iostat.py
|
|
||||||
@@ -1,4 +1,4 @@
|
|
||||||
-#!/usr/bin/env python
|
|
||||||
+#!/usr/bin/python
|
|
||||||
# -*- python-mode -*-
|
|
||||||
"""Emulate iostat for NFS mount points using /proc/self/mountstats
|
|
||||||
"""
|
|
||||||
@@ -21,6 +21,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
"""
|
|
||||||
|
|
||||||
import sys, os, time
|
|
||||||
+from optparse import OptionParser, OptionGroup
|
|
||||||
|
|
||||||
Iostats_version = '0.2'
|
|
||||||
|
|
||||||
@@ -353,6 +354,12 @@ class DeviceData:
|
|
||||||
print '\t%7.3f' % rtt_per_op,
|
|
||||||
print '\t%7.3f' % exe_per_op
|
|
||||||
|
|
||||||
+ def ops(self, sample_time):
|
|
||||||
+ sends = float(self.__rpc_data['rpcsends'])
|
|
||||||
+ if sample_time == 0:
|
|
||||||
+ sample_time = float(self.__nfs_data['age'])
|
|
||||||
+ return (sends / sample_time)
|
|
||||||
+
|
|
||||||
def display_iostats(self, sample_time, which):
|
|
||||||
"""Display NFS and RPC stats in an iostat-like way
|
|
||||||
"""
|
|
||||||
@@ -395,33 +402,6 @@ class DeviceData:
|
|
||||||
# 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
|
|
||||||
@@ -446,109 +426,198 @@ def parse_stats_file(filename):
|
|
||||||
|
|
||||||
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:
|
|
||||||
+def print_iostat_summary(old, new, devices, time, options):
|
|
||||||
+ stats = {}
|
|
||||||
+ diff_stats = {}
|
|
||||||
+
|
|
||||||
+ if old:
|
|
||||||
+ # Trim device list to only include intersection of old and new data,
|
|
||||||
+ # this addresses umounts due to autofs mountpoints
|
|
||||||
+ devicelist = filter(lambda x:x in devices,old)
|
|
||||||
+ else:
|
|
||||||
+ devicelist = devices
|
|
||||||
+
|
|
||||||
+ for device in devicelist:
|
|
||||||
+ stats[device] = DeviceData()
|
|
||||||
+ stats[device].parse_stats(new[device])
|
|
||||||
+ if old:
|
|
||||||
old_stats = DeviceData()
|
|
||||||
old_stats.parse_stats(old[device])
|
|
||||||
- diff_stats = stats.compare_iostats(old_stats)
|
|
||||||
- diff_stats.display_iostats(time, ac)
|
|
||||||
+ diff_stats[device] = stats[device].compare_iostats(old_stats)
|
|
||||||
+
|
|
||||||
+ if options.sort:
|
|
||||||
+ if old:
|
|
||||||
+ # We now have compared data and can print a comparison
|
|
||||||
+ # ordered by mountpoint ops per second
|
|
||||||
+ devicelist.sort(key=lambda x: diff_stats[x].ops(time), reverse=True)
|
|
||||||
+ else:
|
|
||||||
+ # First iteration, just sort by newly parsed ops/s
|
|
||||||
+ devicelist.sort(key=lambda x: stats[x].ops(time), reverse=True)
|
|
||||||
+
|
|
||||||
+ count = 1
|
|
||||||
+ for device in devicelist:
|
|
||||||
+ if old:
|
|
||||||
+ diff_stats[device].display_iostats(time, options.which)
|
|
||||||
+ else:
|
|
||||||
+ stats[device].display_iostats(time, options.which)
|
|
||||||
+
|
|
||||||
+ count += 1
|
|
||||||
+ if (count > options.list):
|
|
||||||
+ return
|
|
||||||
+
|
|
||||||
+
|
|
||||||
+def list_nfs_mounts(givenlist, mountstats):
|
|
||||||
+ """return a list of NFS mounts given a list to validate or
|
|
||||||
+ return a full list if the given list is empty -
|
|
||||||
+ may return an empty list if none found
|
|
||||||
+ """
|
|
||||||
+ list = []
|
|
||||||
+ if len(givenlist) > 0:
|
|
||||||
+ for device in givenlist:
|
|
||||||
+ stats = DeviceData()
|
|
||||||
+ stats.parse_stats(mountstats[device])
|
|
||||||
+ if stats.is_nfs_mountpoint():
|
|
||||||
+ list += [device]
|
|
||||||
+ else:
|
|
||||||
+ for device, descr in mountstats.iteritems():
|
|
||||||
+ stats = DeviceData()
|
|
||||||
+ stats.parse_stats(descr)
|
|
||||||
+ if stats.is_nfs_mountpoint():
|
|
||||||
+ list += [device]
|
|
||||||
+ return list
|
|
||||||
|
|
||||||
def iostat_command(name):
|
|
||||||
"""iostat-like command for NFS mount points
|
|
||||||
"""
|
|
||||||
mountstats = parse_stats_file('/proc/self/mountstats')
|
|
||||||
devices = []
|
|
||||||
- which = 0
|
|
||||||
+ origdevices = []
|
|
||||||
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
|
|
||||||
+ mydescription= """
|
|
||||||
+Sample iostat-like program to display NFS client per-mount'
|
|
||||||
+statistics. The <interval> parameter specifies the amount of time in seconds
|
|
||||||
+between each report. The first report contains statistics for the time since
|
|
||||||
+each file system was mounted. Each subsequent report contains statistics
|
|
||||||
+collected during the interval since the previous report. If the <count>
|
|
||||||
+parameter is specified, the value of <count> determines the number of reports
|
|
||||||
+generated at <interval> seconds apart. If the interval parameter is specified
|
|
||||||
+without the <count> parameter, the command generates reports continuously.
|
|
||||||
+If one or more <mount point> names are specified, statistics for only these
|
|
||||||
+mount points will be displayed. Otherwise, all NFS mount points on the
|
|
||||||
+client are listed.
|
|
||||||
+"""
|
|
||||||
+ parser = OptionParser(
|
|
||||||
+ usage="usage: %prog [ <interval> [ <count> ] ] [ <options> ] [ <mount point> ]",
|
|
||||||
+ description=mydescription,
|
|
||||||
+ version='version %s' % Iostats_version)
|
|
||||||
+ parser.set_defaults(which=0, sort=False, list=sys.maxint)
|
|
||||||
+
|
|
||||||
+ statgroup = OptionGroup(parser, "Statistics Options",
|
|
||||||
+ 'File I/O is displayed unless one of the following is specified:')
|
|
||||||
+ statgroup.add_option('-a', '--attr',
|
|
||||||
+ action="store_const",
|
|
||||||
+ dest="which",
|
|
||||||
+ const=1,
|
|
||||||
+ help='displays statistics related to the attribute cache')
|
|
||||||
+ statgroup.add_option('-d', '--dir',
|
|
||||||
+ action="store_const",
|
|
||||||
+ dest="which",
|
|
||||||
+ const=2,
|
|
||||||
+ help='displays statistics related to directory operations')
|
|
||||||
+ statgroup.add_option('-p', '--page',
|
|
||||||
+ action="store_const",
|
|
||||||
+ dest="which",
|
|
||||||
+ const=3,
|
|
||||||
+ help='displays statistics related to the page cache')
|
|
||||||
+ parser.add_option_group(statgroup)
|
|
||||||
+ displaygroup = OptionGroup(parser, "Display Options",
|
|
||||||
+ 'Options affecting display format:')
|
|
||||||
+ displaygroup.add_option('-s', '--sort',
|
|
||||||
+ action="store_true",
|
|
||||||
+ dest="sort",
|
|
||||||
+ help="Sort NFS mount points by ops/second")
|
|
||||||
+ displaygroup.add_option('-l','--list',
|
|
||||||
+ action="store",
|
|
||||||
+ type="int",
|
|
||||||
+ dest="list",
|
|
||||||
+ help="only print stats for first LIST mount points")
|
|
||||||
+ parser.add_option_group(displaygroup)
|
|
||||||
+
|
|
||||||
+ (options, args) = parser.parse_args(sys.argv)
|
|
||||||
+
|
|
||||||
+ for arg in args:
|
|
||||||
|
|
||||||
if arg == sys.argv[0]:
|
|
||||||
continue
|
|
||||||
|
|
||||||
if arg in mountstats:
|
|
||||||
- devices += [arg]
|
|
||||||
+ origdevices += [arg]
|
|
||||||
elif not interval_seen:
|
|
||||||
- interval = int(arg)
|
|
||||||
+ try:
|
|
||||||
+ interval = int(arg)
|
|
||||||
+ except:
|
|
||||||
+ print 'Illegal <interval> value %s' % arg
|
|
||||||
+ return
|
|
||||||
if interval > 0:
|
|
||||||
interval_seen = True
|
|
||||||
else:
|
|
||||||
- print 'Illegal <interval> value'
|
|
||||||
+ print 'Illegal <interval> value %s' % arg
|
|
||||||
return
|
|
||||||
elif not count_seen:
|
|
||||||
- count = int(arg)
|
|
||||||
+ try:
|
|
||||||
+ count = int(arg)
|
|
||||||
+ except:
|
|
||||||
+ print 'Ilegal <count> value %s' % arg
|
|
||||||
+ return
|
|
||||||
if count > 0:
|
|
||||||
count_seen = True
|
|
||||||
else:
|
|
||||||
- print 'Illegal <count> value'
|
|
||||||
+ print 'Illegal <count> value %s' % arg
|
|
||||||
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]
|
|
||||||
+ devices = list_nfs_mounts(origdevices, mountstats)
|
|
||||||
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)
|
|
||||||
+ print_iostat_summary(old_mountstats, mountstats, devices, sample_time, options)
|
|
||||||
return
|
|
||||||
|
|
||||||
if count_seen:
|
|
||||||
while count != 0:
|
|
||||||
- print_iostat_summary(old_mountstats, mountstats, devices, sample_time, which)
|
|
||||||
+ print_iostat_summary(old_mountstats, mountstats, devices, sample_time, options)
|
|
||||||
old_mountstats = mountstats
|
|
||||||
time.sleep(interval)
|
|
||||||
sample_time = interval
|
|
||||||
mountstats = parse_stats_file('/proc/self/mountstats')
|
|
||||||
+ # automount mountpoints add and drop, if automount is involved
|
|
||||||
+ # we need to recheck the devices list when reparsing
|
|
||||||
+ devices = list_nfs_mounts(origdevices,mountstats)
|
|
||||||
+ if len(devices) == 0:
|
|
||||||
+ print 'No NFS mount points were found'
|
|
||||||
+ return
|
|
||||||
count -= 1
|
|
||||||
else:
|
|
||||||
while True:
|
|
||||||
- print_iostat_summary(old_mountstats, mountstats, devices, sample_time, which)
|
|
||||||
+ print_iostat_summary(old_mountstats, mountstats, devices, sample_time, options)
|
|
||||||
old_mountstats = mountstats
|
|
||||||
time.sleep(interval)
|
|
||||||
sample_time = interval
|
|
||||||
mountstats = parse_stats_file('/proc/self/mountstats')
|
|
||||||
+ # automount mountpoints add and drop, if automount is involved
|
|
||||||
+ # we need to recheck the devices list when reparsing
|
|
||||||
+ devices = list_nfs_mounts(origdevices,mountstats)
|
|
||||||
+ if len(devices) == 0:
|
|
||||||
+ print 'No NFS mount points were found'
|
|
||||||
+ return
|
|
||||||
|
|
||||||
#
|
|
||||||
# Main
|
|
||||||
diff --git a/utils/gssd/gssd_proc.c b/utils/gssd/gssd_proc.c
|
|
||||||
index 02239d2..37e2aa5 100644
|
|
||||||
--- a/utils/gssd/gssd_proc.c
|
|
||||||
+++ b/utils/gssd/gssd_proc.c
|
|
||||||
@@ -840,42 +840,48 @@ handle_krb5_upcall(struct clnt_info *clp)
|
|
||||||
}
|
|
||||||
if (create_resp != 0) {
|
|
||||||
if (uid == 0 && root_uses_machine_creds == 1) {
|
|
||||||
+ int nocache = 0;
|
|
||||||
int success = 0;
|
|
||||||
-
|
|
||||||
- gssd_refresh_krb5_machine_credential(clp->servername,
|
|
||||||
- NULL);
|
|
||||||
- /*
|
|
||||||
- * Get a list of credential cache names and try each
|
|
||||||
- * of them until one works or we've tried them all
|
|
||||||
- */
|
|
||||||
- if (gssd_get_krb5_machine_cred_list(&credlist)) {
|
|
||||||
- printerr(0, "ERROR: No credentials found "
|
|
||||||
- "for connection to server %s\n",
|
|
||||||
- clp->servername);
|
|
||||||
- goto out_return_error;
|
|
||||||
- }
|
|
||||||
- for (ccname = credlist; ccname && *ccname; ccname++) {
|
|
||||||
- gssd_setup_krb5_machine_gss_ccache(*ccname);
|
|
||||||
- if ((create_auth_rpc_client(clp, &rpc_clnt,
|
|
||||||
- &auth, uid,
|
|
||||||
- AUTHTYPE_KRB5)) == 0) {
|
|
||||||
- /* Success! */
|
|
||||||
- success++;
|
|
||||||
- break;
|
|
||||||
+ do {
|
|
||||||
+ gssd_refresh_krb5_machine_credential(clp->servername,
|
|
||||||
+ NULL, nocache);
|
|
||||||
+ /*
|
|
||||||
+ * Get a list of credential cache names and try each
|
|
||||||
+ * of them until one works or we've tried them all
|
|
||||||
+ */
|
|
||||||
+ if (gssd_get_krb5_machine_cred_list(&credlist)) {
|
|
||||||
+ printerr(0, "ERROR: No credentials found "
|
|
||||||
+ "for connection to server %s\n",
|
|
||||||
+ clp->servername);
|
|
||||||
+ goto out_return_error;
|
|
||||||
}
|
|
||||||
- printerr(2, "WARNING: Failed to create krb5 context "
|
|
||||||
- "for user with uid %d with credentials "
|
|
||||||
- "cache %s for server %s\n",
|
|
||||||
- uid, *ccname, clp->servername);
|
|
||||||
- }
|
|
||||||
- gssd_free_krb5_machine_cred_list(credlist);
|
|
||||||
- if (!success) {
|
|
||||||
- printerr(1, "WARNING: Failed to create krb5 context "
|
|
||||||
- "for user with uid %d with any "
|
|
||||||
- "credentials cache for server %s\n",
|
|
||||||
- uid, clp->servername);
|
|
||||||
- goto out_return_error;
|
|
||||||
- }
|
|
||||||
+ for (ccname = credlist; ccname && *ccname; ccname++) {
|
|
||||||
+ gssd_setup_krb5_machine_gss_ccache(*ccname);
|
|
||||||
+ if ((create_auth_rpc_client(clp, &rpc_clnt,
|
|
||||||
+ &auth, uid,
|
|
||||||
+ AUTHTYPE_KRB5)) == 0) {
|
|
||||||
+ /* Success! */
|
|
||||||
+ success++;
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
+ printerr(2, "WARNING: Failed to create machine krb5 context "
|
|
||||||
+ "with credentials cache %s for server %s\n",
|
|
||||||
+ *ccname, clp->servername);
|
|
||||||
+ }
|
|
||||||
+ gssd_free_krb5_machine_cred_list(credlist);
|
|
||||||
+ if (!success) {
|
|
||||||
+ if(nocache == 0) {
|
|
||||||
+ nocache++;
|
|
||||||
+ printerr(2, "WARNING: Machine cache is prematurely expired or corrupted "
|
|
||||||
+ "trying to recreate cache for server %s\n", clp->servername);
|
|
||||||
+ } else {
|
|
||||||
+ printerr(1, "WARNING: Failed to create machine krb5 context "
|
|
||||||
+ "with any credentials cache for server %s\n",
|
|
||||||
+ clp->servername);
|
|
||||||
+ goto out_return_error;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ } while(!success);
|
|
||||||
} else {
|
|
||||||
printerr(1, "WARNING: Failed to create krb5 context "
|
|
||||||
"for user with uid %d for server %s\n",
|
|
||||||
diff --git a/utils/gssd/krb5_util.c b/utils/gssd/krb5_util.c
|
|
||||||
index 3009cc5..78e9775 100644
|
|
||||||
--- a/utils/gssd/krb5_util.c
|
|
||||||
+++ b/utils/gssd/krb5_util.c
|
|
||||||
@@ -137,7 +137,7 @@ static int select_krb5_ccache(const 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);
|
|
||||||
+ krb5_keytab kt, struct gssd_k5_kt_princ *ple, int nocache);
|
|
||||||
static int query_krb5_ccache(const char* cred_cache, char **ret_princname,
|
|
||||||
char **ret_realm);
|
|
||||||
|
|
||||||
@@ -359,7 +359,8 @@ limit_krb5_enctypes(struct rpc_gss_sec *sec, uid_t uid)
|
|
||||||
static int
|
|
||||||
gssd_get_single_krb5_cred(krb5_context context,
|
|
||||||
krb5_keytab kt,
|
|
||||||
- struct gssd_k5_kt_princ *ple)
|
|
||||||
+ struct gssd_k5_kt_princ *ple,
|
|
||||||
+ int nocache)
|
|
||||||
{
|
|
||||||
#if HAVE_KRB5_GET_INIT_CREDS_OPT_SET_ADDRESSLESS
|
|
||||||
krb5_get_init_creds_opt *init_opts = NULL;
|
|
||||||
@@ -379,7 +380,7 @@ gssd_get_single_krb5_cred(krb5_context context,
|
|
||||||
|
|
||||||
memset(&my_creds, 0, sizeof(my_creds));
|
|
||||||
|
|
||||||
- if (ple->ccname && ple->endtime > now) {
|
|
||||||
+ if (ple->ccname && ple->endtime > now && !nocache) {
|
|
||||||
printerr(2, "INFO: Credentials in CC '%s' are good until %d\n",
|
|
||||||
ple->ccname, ple->endtime);
|
|
||||||
code = 0;
|
|
||||||
@@ -1095,7 +1096,7 @@ gssd_get_krb5_machine_cred_list(char ***list)
|
|
||||||
for (ple = gssd_k5_kt_princ_list; ple; ple = ple->next) {
|
|
||||||
if (ple->ccname) {
|
|
||||||
/* Make sure cred is up-to-date before returning it */
|
|
||||||
- retval = gssd_refresh_krb5_machine_credential(NULL, ple);
|
|
||||||
+ retval = gssd_refresh_krb5_machine_credential(NULL, ple, 0);
|
|
||||||
if (retval)
|
|
||||||
continue;
|
|
||||||
if (i + 1 > listsize) {
|
|
||||||
@@ -1185,7 +1186,7 @@ gssd_destroy_krb5_machine_creds(void)
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
gssd_refresh_krb5_machine_credential(char *hostname,
|
|
||||||
- struct gssd_k5_kt_princ *ple)
|
|
||||||
+ struct gssd_k5_kt_princ *ple, int nocache)
|
|
||||||
{
|
|
||||||
krb5_error_code code = 0;
|
|
||||||
krb5_context context;
|
|
||||||
@@ -1240,7 +1241,7 @@ gssd_refresh_krb5_machine_credential(char *hostname,
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
- retval = gssd_get_single_krb5_cred(context, kt, ple);
|
|
||||||
+ retval = gssd_get_single_krb5_cred(context, kt, ple, nocache);
|
|
||||||
out:
|
|
||||||
if (kt)
|
|
||||||
krb5_kt_close(context, kt);
|
|
||||||
diff --git a/utils/gssd/krb5_util.h b/utils/gssd/krb5_util.h
|
|
||||||
index 3d39300..4b6b281 100644
|
|
||||||
--- a/utils/gssd/krb5_util.h
|
|
||||||
+++ b/utils/gssd/krb5_util.h
|
|
||||||
@@ -30,7 +30,7 @@ void gssd_free_krb5_machine_cred_list(char **list);
|
|
||||||
void gssd_setup_krb5_machine_gss_ccache(char *servername);
|
|
||||||
void gssd_destroy_krb5_machine_creds(void);
|
|
||||||
int gssd_refresh_krb5_machine_credential(char *hostname,
|
|
||||||
- struct gssd_k5_kt_princ *ple);
|
|
||||||
+ struct gssd_k5_kt_princ *ple, int nocache);
|
|
||||||
char *gssd_k5_err_msg(krb5_context context, krb5_error_code code);
|
|
||||||
void gssd_k5_get_default_realm(char **def_realm);
|
|
||||||
|
|
||||||
diff --git a/utils/idmapd/idmapd.c b/utils/idmapd/idmapd.c
|
|
||||||
index 65a6a2a..573abaa 100644
|
|
||||||
--- a/utils/idmapd/idmapd.c
|
|
||||||
+++ b/utils/idmapd/idmapd.c
|
|
||||||
@@ -139,6 +139,7 @@ static void nametoidres(struct idmap_msg *);
|
|
||||||
|
|
||||||
static int nfsdopen(void);
|
|
||||||
static int nfsdopenone(struct idmap_client *);
|
|
||||||
+static void nfsdreopen_one(struct idmap_client *);
|
|
||||||
static void nfsdreopen(void);
|
|
||||||
|
|
||||||
size_t strlcat(char *, const char *, size_t);
|
|
||||||
@@ -502,7 +503,8 @@ nfsdcb(int fd, short which, void *data)
|
|
||||||
xlog_warn("nfsdcb: read(%s) failed: errno %d (%s)",
|
|
||||||
ic->ic_path, len?errno:0,
|
|
||||||
len?strerror(errno):"End of File");
|
|
||||||
- goto out;
|
|
||||||
+ nfsdreopen_one(ic);
|
|
||||||
+ return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get rid of newline and terminate buffer*/
|
|
||||||
@@ -514,11 +516,11 @@ nfsdcb(int fd, short which, void *data)
|
|
||||||
/* Authentication name -- ignored for now*/
|
|
||||||
if (getfield(&bp, authbuf, sizeof(authbuf)) == -1) {
|
|
||||||
xlog_warn("nfsdcb: bad authentication name in upcall\n");
|
|
||||||
- return;
|
|
||||||
+ goto out;
|
|
||||||
}
|
|
||||||
if (getfield(&bp, typebuf, sizeof(typebuf)) == -1) {
|
|
||||||
xlog_warn("nfsdcb: bad type in upcall\n");
|
|
||||||
- return;
|
|
||||||
+ goto out;
|
|
||||||
}
|
|
||||||
if (verbose > 0)
|
|
||||||
xlog_warn("nfsdcb: authbuf=%s authtype=%s",
|
|
||||||
@@ -532,26 +534,26 @@ nfsdcb(int fd, short which, void *data)
|
|
||||||
im.im_conv = IDMAP_CONV_NAMETOID;
|
|
||||||
if (getfield(&bp, im.im_name, sizeof(im.im_name)) == -1) {
|
|
||||||
xlog_warn("nfsdcb: bad name in upcall\n");
|
|
||||||
- return;
|
|
||||||
+ goto out;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case IC_IDNAME:
|
|
||||||
im.im_conv = IDMAP_CONV_IDTONAME;
|
|
||||||
if (getfield(&bp, buf1, sizeof(buf1)) == -1) {
|
|
||||||
xlog_warn("nfsdcb: bad id in upcall\n");
|
|
||||||
- return;
|
|
||||||
+ goto out;
|
|
||||||
}
|
|
||||||
tmp = strtoul(buf1, (char **)NULL, 10);
|
|
||||||
im.im_id = (u_int32_t)tmp;
|
|
||||||
if ((tmp == ULONG_MAX && errno == ERANGE)
|
|
||||||
|| (unsigned long)im.im_id != tmp) {
|
|
||||||
xlog_warn("nfsdcb: id '%s' too big!\n", buf1);
|
|
||||||
- return;
|
|
||||||
+ goto out;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
xlog_warn("nfsdcb: Unknown which type %d", ic->ic_which);
|
|
||||||
- return;
|
|
||||||
+ goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
imconv(ic, &im);
|
|
||||||
@@ -612,7 +614,7 @@ nfsdcb(int fd, short which, void *data)
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
xlog_warn("nfsdcb: Unknown which type %d", ic->ic_which);
|
|
||||||
- return;
|
|
||||||
+ goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
bsiz = sizeof(buf) - bsiz;
|
|
||||||
diff --git a/utils/mount/mount_config.h b/utils/mount/mount_config.h
|
|
||||||
index 9a885a9..3023306 100644
|
|
||||||
--- a/utils/mount/mount_config.h
|
|
||||||
+++ b/utils/mount/mount_config.h
|
|
||||||
@@ -20,6 +20,8 @@ inline void mount_config_init(char *);
|
|
||||||
|
|
||||||
#ifdef MOUNT_CONFIG
|
|
||||||
#include "conffile.h"
|
|
||||||
+#include "xlog.h"
|
|
||||||
+
|
|
||||||
extern char *conf_get_mntopts(char *, char *, char *);
|
|
||||||
|
|
||||||
inline void mount_config_init(char *program)
|
|
||||||
diff --git a/utils/mount/network.c b/utils/mount/network.c
|
|
||||||
index f6fa5fd..bd621be 100644
|
|
||||||
--- a/utils/mount/network.c
|
|
||||||
+++ b/utils/mount/network.c
|
|
||||||
@@ -90,6 +90,7 @@ static const char *nfs_transport_opttbl[] = {
|
|
||||||
static const char *nfs_version_opttbl[] = {
|
|
||||||
"v2",
|
|
||||||
"v3",
|
|
||||||
+ "v4",
|
|
||||||
"vers",
|
|
||||||
"nfsvers",
|
|
||||||
NULL,
|
|
||||||
@@ -1203,7 +1204,7 @@ nfs_nfs_program(struct mount_options *options, unsigned long *program)
|
|
||||||
* Returns TRUE if @version contains a valid value for this option,
|
|
||||||
* or FALSE if the option was specified with an invalid value.
|
|
||||||
*/
|
|
||||||
-static int
|
|
||||||
+int
|
|
||||||
nfs_nfs_version(struct mount_options *options, unsigned long *version)
|
|
||||||
{
|
|
||||||
long tmp;
|
|
||||||
@@ -1215,10 +1216,13 @@ nfs_nfs_version(struct mount_options *options, unsigned long *version)
|
|
||||||
case 1: /* v3 */
|
|
||||||
*version = 3;
|
|
||||||
return 1;
|
|
||||||
- case 2: /* vers */
|
|
||||||
+ case 2: /* v4 */
|
|
||||||
+ *version = 4;
|
|
||||||
+ return 1;
|
|
||||||
+ case 3: /* vers */
|
|
||||||
switch (po_get_numeric(options, "vers", &tmp)) {
|
|
||||||
case PO_FOUND:
|
|
||||||
- if (tmp >= 2 && tmp <= 3) {
|
|
||||||
+ if (tmp >= 2 && tmp <= 4) {
|
|
||||||
*version = tmp;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
@@ -1229,10 +1233,10 @@ nfs_nfs_version(struct mount_options *options, unsigned long *version)
|
|
||||||
case PO_BAD_VALUE:
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
- case 3: /* nfsvers */
|
|
||||||
+ case 4: /* nfsvers */
|
|
||||||
switch (po_get_numeric(options, "nfsvers", &tmp)) {
|
|
||||||
case PO_FOUND:
|
|
||||||
- if (tmp >= 2 && tmp <= 3) {
|
|
||||||
+ if (tmp >= 2 && tmp <= 4) {
|
|
||||||
*version = tmp;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
diff --git a/utils/mount/network.h b/utils/mount/network.h
|
|
||||||
index db5134c..402e0a5 100644
|
|
||||||
--- a/utils/mount/network.h
|
|
||||||
+++ b/utils/mount/network.h
|
|
||||||
@@ -56,6 +56,7 @@ int clnt_ping(struct sockaddr_in *, const unsigned long,
|
|
||||||
|
|
||||||
struct mount_options;
|
|
||||||
|
|
||||||
+int nfs_nfs_version(struct mount_options *options, unsigned long *version);
|
|
||||||
int nfs_options2pmap(struct mount_options *,
|
|
||||||
struct pmap *, struct pmap *);
|
|
||||||
|
|
||||||
diff --git a/utils/mount/nfsumount.c b/utils/mount/nfsumount.c
|
|
||||||
index f81db14..c5505b1 100644
|
|
||||||
--- a/utils/mount/nfsumount.c
|
|
||||||
+++ b/utils/mount/nfsumount.c
|
|
||||||
@@ -179,6 +179,10 @@ static int nfs_umount_do_umnt(struct mount_options *options,
|
|
||||||
return EX_FAIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ /* Skip UMNT call for vers=4 mounts */
|
|
||||||
+ if (nfs_pmap.pm_vers == 4)
|
|
||||||
+ return EX_SUCCESS;
|
|
||||||
+
|
|
||||||
*hostname = nfs_umount_hostname(options, *hostname);
|
|
||||||
if (!*hostname) {
|
|
||||||
nfs_error(_("%s: out of memory"), progname);
|
|
||||||
diff --git a/utils/mount/stropts.c b/utils/mount/stropts.c
|
|
||||||
index a12ace7..3eb661e 100644
|
|
||||||
--- a/utils/mount/stropts.c
|
|
||||||
+++ b/utils/mount/stropts.c
|
|
||||||
@@ -84,6 +84,7 @@ struct nfsmount_info {
|
|
||||||
struct mount_options *options; /* parsed mount options */
|
|
||||||
char **extra_opts; /* string for /etc/mtab */
|
|
||||||
|
|
||||||
+ unsigned long version; /* NFS version */
|
|
||||||
int flags, /* MS_ flags */
|
|
||||||
fake, /* actually do the mount? */
|
|
||||||
child; /* forked bg child? */
|
|
||||||
@@ -272,7 +273,12 @@ static int nfs_validate_options(struct nfsmount_info *mi)
|
|
||||||
if (!nfs_name_to_address(mi->hostname, sap, &salen))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
- if (strncmp(mi->type, "nfs4", 4) == 0) {
|
|
||||||
+ if (!nfs_nfs_version(mi->options, &mi->version))
|
|
||||||
+ return 0;
|
|
||||||
+ if (strncmp(mi->type, "nfs4", 4) == 0)
|
|
||||||
+ mi->version = 4;
|
|
||||||
+
|
|
||||||
+ if (mi->version == 4) {
|
|
||||||
if (!nfs_append_clientaddr_option(sap, salen, mi->options))
|
|
||||||
return 0;
|
|
||||||
} else {
|
|
||||||
@@ -488,7 +494,7 @@ static int nfs_try_mount(struct nfsmount_info *mi)
|
|
||||||
char *options = NULL;
|
|
||||||
int result;
|
|
||||||
|
|
||||||
- if (strncmp(mi->type, "nfs4", 4) != 0) {
|
|
||||||
+ if (mi->version != 4) {
|
|
||||||
if (!nfs_rewrite_pmap_mount_options(mi->options))
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
diff --git a/utils/mountd/mountd.c b/utils/mountd/mountd.c
|
|
||||||
index b59f939..888fd8c 100644
|
|
||||||
--- a/utils/mountd/mountd.c
|
|
||||||
+++ b/utils/mountd/mountd.c
|
|
||||||
@@ -359,6 +359,11 @@ static void set_authflavors(struct mountres3_ok *ok, nfs_export *exp)
|
|
||||||
flavors[i] = s->flav->fnum;
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
+ if (i == 0) {
|
|
||||||
+ /* default when there is no sec= option: */
|
|
||||||
+ i = 1;
|
|
||||||
+ flavors[0] = AUTH_UNIX;
|
|
||||||
+ }
|
|
||||||
ok->auth_flavors.auth_flavors_val = flavors;
|
|
||||||
ok->auth_flavors.auth_flavors_len = i;
|
|
||||||
}
|
|
||||||
diff --git a/utils/nfsd/nfsd.c b/utils/nfsd/nfsd.c
|
|
||||||
index 650c593..1cda1e5 100644
|
|
||||||
--- a/utils/nfsd/nfsd.c
|
|
||||||
+++ b/utils/nfsd/nfsd.c
|
|
||||||
@@ -27,6 +27,15 @@
|
|
||||||
#include "nfssvc.h"
|
|
||||||
#include "xlog.h"
|
|
||||||
|
|
||||||
+/*
|
|
||||||
+ * IPv6 support for nfsd was finished before some of the other daemons (mountd
|
|
||||||
+ * and statd in particular). That could be a problem in the future if someone
|
|
||||||
+ * were to boot a kernel that supports IPv6 serving with an older nfs-utils. For
|
|
||||||
+ * now, hardcode the IPv6 switch into the off position until the other daemons
|
|
||||||
+ * are functional.
|
|
||||||
+ */
|
|
||||||
+#undef IPV6_SUPPORTED
|
|
||||||
+
|
|
||||||
static void usage(const char *);
|
|
||||||
|
|
||||||
static struct option longopts[] =
|
|
||||||
diff --git a/utils/nfsd/nfssvc.c b/utils/nfsd/nfssvc.c
|
|
||||||
index ee862b2..12d3253 100644
|
|
||||||
--- a/utils/nfsd/nfssvc.c
|
|
||||||
+++ b/utils/nfsd/nfssvc.c
|
|
||||||
@@ -22,6 +22,15 @@
|
|
||||||
#include "nfslib.h"
|
|
||||||
#include "xlog.h"
|
|
||||||
|
|
||||||
+/*
|
|
||||||
+ * IPv6 support for nfsd was finished before some of the other daemons (mountd
|
|
||||||
+ * and statd in particular). That could be a problem in the future if someone
|
|
||||||
+ * were to boot a kernel that supports IPv6 serving with an older nfs-utils. For
|
|
||||||
+ * now, hardcode the IPv6 switch into the off position until the other daemons
|
|
||||||
+ * are functional.
|
|
||||||
+ */
|
|
||||||
+#undef IPV6_SUPPORTED
|
|
||||||
+
|
|
||||||
#define NFSD_PORTS_FILE "/proc/fs/nfsd/portlist"
|
|
||||||
#define NFSD_VERS_FILE "/proc/fs/nfsd/versions"
|
|
||||||
#define NFSD_THREAD_FILE "/proc/fs/nfsd/threads"
|
|
@ -1,307 +0,0 @@
|
|||||||
diff --git a/utils/mount/parse_opt.c b/utils/mount/parse_opt.c
|
|
||||||
index 1dfee8a..f0918f7 100644
|
|
||||||
--- a/utils/mount/parse_opt.c
|
|
||||||
+++ b/utils/mount/parse_opt.c
|
|
||||||
@@ -101,6 +101,37 @@ fail:
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
+static struct mount_option *option_dup(const struct mount_option *option)
|
|
||||||
+{
|
|
||||||
+ struct mount_option *new;
|
|
||||||
+
|
|
||||||
+ new = malloc(sizeof(*new));
|
|
||||||
+ if (!new)
|
|
||||||
+ return NULL;
|
|
||||||
+
|
|
||||||
+ new->next = NULL;
|
|
||||||
+ new->prev = NULL;
|
|
||||||
+
|
|
||||||
+ new->keyword = strdup(option->keyword);
|
|
||||||
+ if (!new->keyword)
|
|
||||||
+ goto fail;
|
|
||||||
+
|
|
||||||
+ new->value = NULL;
|
|
||||||
+ if (option->value) {
|
|
||||||
+ new->value = strdup(option->value);
|
|
||||||
+ if (!new->value) {
|
|
||||||
+ free(new->keyword);
|
|
||||||
+ goto fail;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return new;
|
|
||||||
+
|
|
||||||
+fail:
|
|
||||||
+ free(new);
|
|
||||||
+ return NULL;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
static void option_destroy(struct mount_option *option)
|
|
||||||
{
|
|
||||||
free(option->keyword);
|
|
||||||
@@ -229,6 +260,40 @@ fail:
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
+ * po_dup - duplicate an existing list of options
|
|
||||||
+ * @options: pointer to mount options
|
|
||||||
+ *
|
|
||||||
+ */
|
|
||||||
+struct mount_options *po_dup(struct mount_options *source)
|
|
||||||
+{
|
|
||||||
+ struct mount_options *target;
|
|
||||||
+ struct mount_option *current;
|
|
||||||
+
|
|
||||||
+ if (!source)
|
|
||||||
+ return NULL;
|
|
||||||
+
|
|
||||||
+ target = options_create();
|
|
||||||
+ if (options_empty(source) || target == NULL)
|
|
||||||
+ return target;
|
|
||||||
+
|
|
||||||
+ current = source->head;
|
|
||||||
+ while (target->count < source->count) {
|
|
||||||
+ struct mount_option *option;
|
|
||||||
+
|
|
||||||
+ option = option_dup(current);
|
|
||||||
+ if (!option) {
|
|
||||||
+ po_destroy(target);
|
|
||||||
+ return NULL;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ options_tail_insert(target, option);
|
|
||||||
+ current = current->next;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return target;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+/**
|
|
||||||
* po_replace - replace mount options in one mount_options object with another
|
|
||||||
* @target: pointer to previously instantiated object to replace
|
|
||||||
* @source: pointer to object containing source mount options
|
|
||||||
diff --git a/utils/mount/parse_opt.h b/utils/mount/parse_opt.h
|
|
||||||
index f9243c3..2c0b5f4 100644
|
|
||||||
--- a/utils/mount/parse_opt.h
|
|
||||||
+++ b/utils/mount/parse_opt.h
|
|
||||||
@@ -38,6 +38,7 @@ typedef enum {
|
|
||||||
struct mount_options;
|
|
||||||
|
|
||||||
struct mount_options * po_split(char *);
|
|
||||||
+struct mount_options * po_dup(struct mount_options *);
|
|
||||||
void po_replace(struct mount_options *,
|
|
||||||
struct mount_options *);
|
|
||||||
po_return_t po_join(struct mount_options *, char **);
|
|
||||||
diff --git a/utils/mount/stropts.c b/utils/mount/stropts.c
|
|
||||||
index 3eb661e..069bdc1 100644
|
|
||||||
--- a/utils/mount/stropts.c
|
|
||||||
+++ b/utils/mount/stropts.c
|
|
||||||
@@ -80,6 +80,8 @@ struct nfsmount_info {
|
|
||||||
*node, /* mounted-on dir */
|
|
||||||
*type; /* "nfs" or "nfs4" */
|
|
||||||
char *hostname; /* server's hostname */
|
|
||||||
+ struct sockaddr_storage address; /* server's address */
|
|
||||||
+ socklen_t salen; /* size of server's address */
|
|
||||||
|
|
||||||
struct mount_options *options; /* parsed mount options */
|
|
||||||
char **extra_opts; /* string for /etc/mtab */
|
|
||||||
@@ -257,47 +259,35 @@ static int nfs_append_sloppy_option(struct mount_options *options)
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
- * Set up mandatory NFS mount options.
|
|
||||||
+ * Set up mandatory non-version specific NFS mount options.
|
|
||||||
*
|
|
||||||
* Returns 1 if successful; otherwise zero.
|
|
||||||
*/
|
|
||||||
static int nfs_validate_options(struct nfsmount_info *mi)
|
|
||||||
{
|
|
||||||
- struct sockaddr_storage dummy;
|
|
||||||
- struct sockaddr *sap = (struct sockaddr *)&dummy;
|
|
||||||
- socklen_t salen = sizeof(dummy);
|
|
||||||
+ struct sockaddr *sap = (struct sockaddr *)&mi->address;
|
|
||||||
|
|
||||||
if (!nfs_parse_devname(mi->spec, &mi->hostname, NULL))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
- if (!nfs_name_to_address(mi->hostname, sap, &salen))
|
|
||||||
+ mi->salen = sizeof(mi->address);
|
|
||||||
+ if (!nfs_name_to_address(mi->hostname, sap, &mi->salen))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (!nfs_nfs_version(mi->options, &mi->version))
|
|
||||||
return 0;
|
|
||||||
if (strncmp(mi->type, "nfs4", 4) == 0)
|
|
||||||
mi->version = 4;
|
|
||||||
-
|
|
||||||
- if (mi->version == 4) {
|
|
||||||
- if (!nfs_append_clientaddr_option(sap, salen, mi->options))
|
|
||||||
- return 0;
|
|
||||||
- } else {
|
|
||||||
- if (!nfs_fix_mounthost_option(mi->options))
|
|
||||||
- return 0;
|
|
||||||
- if (!mi->fake && !nfs_verify_lock_option(mi->options))
|
|
||||||
- return 0;
|
|
||||||
+ else {
|
|
||||||
+ char *option = po_get(mi->options, "proto");
|
|
||||||
+ if (option && strcmp(option, "rdma") == 0)
|
|
||||||
+ mi->version = 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!nfs_append_sloppy_option(mi->options))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
- if (!nfs_append_addr_option(sap, salen, mi->options))
|
|
||||||
- return 0;
|
|
||||||
-
|
|
||||||
- /*
|
|
||||||
- * Update option string to be recorded in /etc/mnttab
|
|
||||||
- */
|
|
||||||
- if (po_join(mi->options, mi->extra_opts) == PO_FAILED)
|
|
||||||
+ if (!nfs_append_addr_option(sap, mi->salen, mi->options))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
@@ -489,17 +479,12 @@ out:
|
|
||||||
* Returns TRUE if successful, otherwise FALSE.
|
|
||||||
* "errno" is set to reflect the individual error.
|
|
||||||
*/
|
|
||||||
-static int nfs_try_mount(struct nfsmount_info *mi)
|
|
||||||
+static int nfs_sys_mount(struct nfsmount_info *mi, struct mount_options *opts)
|
|
||||||
{
|
|
||||||
char *options = NULL;
|
|
||||||
int result;
|
|
||||||
|
|
||||||
- if (mi->version != 4) {
|
|
||||||
- if (!nfs_rewrite_pmap_mount_options(mi->options))
|
|
||||||
- return 0;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- if (po_join(mi->options, &options) == PO_FAILED) {
|
|
||||||
+ if (po_join(opts, &options) == PO_FAILED) {
|
|
||||||
errno = EIO;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -522,6 +507,121 @@ static int nfs_try_mount(struct nfsmount_info *mi)
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
+ * For "-t nfs vers=2" or "-t nfs vers=3" mounts.
|
|
||||||
+ */
|
|
||||||
+static int nfs_try_mount_v3v2(struct nfsmount_info *mi)
|
|
||||||
+{
|
|
||||||
+ struct mount_options *options = po_dup(mi->options);
|
|
||||||
+ int result = 0;
|
|
||||||
+
|
|
||||||
+ if (!options) {
|
|
||||||
+ errno = ENOMEM;
|
|
||||||
+ return result;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (!nfs_fix_mounthost_option(options)) {
|
|
||||||
+ errno = EINVAL;
|
|
||||||
+ goto out_fail;
|
|
||||||
+ }
|
|
||||||
+ if (!mi->fake && !nfs_verify_lock_option(options)) {
|
|
||||||
+ errno = EINVAL;
|
|
||||||
+ goto out_fail;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ /*
|
|
||||||
+ * Options we negotiate below may be stale by the time this
|
|
||||||
+ * file system is unmounted. In order to force umount.nfs
|
|
||||||
+ * to renegotiate with the server, only write the user-
|
|
||||||
+ * specified options, and not negotiated options, to /etc/mtab.
|
|
||||||
+ */
|
|
||||||
+ if (po_join(options, mi->extra_opts) == PO_FAILED) {
|
|
||||||
+ errno = ENOMEM;
|
|
||||||
+ goto out_fail;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (!nfs_rewrite_pmap_mount_options(options))
|
|
||||||
+ goto out_fail;
|
|
||||||
+
|
|
||||||
+ result = nfs_sys_mount(mi, options);
|
|
||||||
+
|
|
||||||
+out_fail:
|
|
||||||
+ po_destroy(options);
|
|
||||||
+ return result;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+/*
|
|
||||||
+ * For "-t nfs -o vers=4" or "-t nfs4" mounts.
|
|
||||||
+ */
|
|
||||||
+static int nfs_try_mount_v4(struct nfsmount_info *mi)
|
|
||||||
+{
|
|
||||||
+ struct sockaddr *sap = (struct sockaddr *)&mi->address;
|
|
||||||
+ struct mount_options *options = po_dup(mi->options);
|
|
||||||
+ int result = 0;
|
|
||||||
+
|
|
||||||
+ if (!options) {
|
|
||||||
+ errno = ENOMEM;
|
|
||||||
+ return result;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (mi->version == 0) {
|
|
||||||
+ if (po_append(options, "vers=4") == PO_FAILED) {
|
|
||||||
+ errno = EINVAL;
|
|
||||||
+ goto out_fail;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (!nfs_append_clientaddr_option(sap, mi->salen, options)) {
|
|
||||||
+ errno = EINVAL;
|
|
||||||
+ goto out_fail;
|
|
||||||
+ }
|
|
||||||
+ /*
|
|
||||||
+ * Update option string to be recorded in /etc/mtab.
|
|
||||||
+ */
|
|
||||||
+ if (po_join(options, mi->extra_opts) == PO_FAILED) {
|
|
||||||
+ errno = ENOMEM;
|
|
||||||
+ return 0;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ result = nfs_sys_mount(mi, options);
|
|
||||||
+
|
|
||||||
+out_fail:
|
|
||||||
+ po_destroy(options);
|
|
||||||
+ return result;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+/*
|
|
||||||
+ * This is a single pass through the fg/bg loop.
|
|
||||||
+ *
|
|
||||||
+ * Returns TRUE if successful, otherwise FALSE.
|
|
||||||
+ * "errno" is set to reflect the individual error.
|
|
||||||
+ */
|
|
||||||
+static int nfs_try_mount(struct nfsmount_info *mi)
|
|
||||||
+{
|
|
||||||
+ int result = 0;
|
|
||||||
+
|
|
||||||
+ switch (mi->version) {
|
|
||||||
+ case 0:
|
|
||||||
+ if (linux_version_code() > MAKE_VERSION(2, 6, 31)) {
|
|
||||||
+ errno = 0;
|
|
||||||
+ result = nfs_try_mount_v4(mi);
|
|
||||||
+ if (errno != EPROTONOSUPPORT)
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
+ case 2:
|
|
||||||
+ case 3:
|
|
||||||
+ result = nfs_try_mount_v3v2(mi);
|
|
||||||
+ break;
|
|
||||||
+ case 4:
|
|
||||||
+ result = nfs_try_mount_v4(mi);
|
|
||||||
+ break;
|
|
||||||
+ default:
|
|
||||||
+ errno = EIO;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return result;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+/*
|
|
||||||
* Distinguish between permanent and temporary errors.
|
|
||||||
*
|
|
||||||
* Basically, we retry if communication with the server has
|
|
@ -1,261 +0,0 @@
|
|||||||
diff --git a/support/include/conffile.h b/support/include/conffile.h
|
|
||||||
index 672020a..fe23ec2 100644
|
|
||||||
--- a/support/include/conffile.h
|
|
||||||
+++ b/support/include/conffile.h
|
|
||||||
@@ -75,4 +75,11 @@ static inline void upper2lower(char *str)
|
|
||||||
while ((c = tolower(*str)))
|
|
||||||
*str++ = c;
|
|
||||||
}
|
|
||||||
+
|
|
||||||
+/*
|
|
||||||
+ * Default Mount options
|
|
||||||
+ */
|
|
||||||
+extern unsigned long config_default_vers;
|
|
||||||
+extern unsigned long config_default_proto;
|
|
||||||
+
|
|
||||||
#endif /* _CONFFILE_H_ */
|
|
||||||
diff --git a/utils/mount/configfile.c b/utils/mount/configfile.c
|
|
||||||
index e347b0e..28b722c 100644
|
|
||||||
--- a/utils/mount/configfile.c
|
|
||||||
+++ b/utils/mount/configfile.c
|
|
||||||
@@ -20,13 +20,19 @@
|
|
||||||
#include <config.h>
|
|
||||||
#endif
|
|
||||||
#include <sys/types.h>
|
|
||||||
+#include <sys/socket.h>
|
|
||||||
+#include <netinet/in.h>
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
+#include <errno.h>
|
|
||||||
|
|
||||||
#include "xlog.h"
|
|
||||||
+#include "mount.h"
|
|
||||||
+#include "parse_opt.h"
|
|
||||||
+#include "network.h"
|
|
||||||
#include "conffile.h"
|
|
||||||
|
|
||||||
#define KBYTES(x) ((x) * (1024))
|
|
||||||
@@ -185,6 +191,63 @@ void free_all(void)
|
|
||||||
free(entry);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+static char *versions[] = {"v2", "v3", "v4", "vers", "nfsvers", NULL};
|
|
||||||
+int inline check_vers(char *mopt, char *field)
|
|
||||||
+{
|
|
||||||
+ int i;
|
|
||||||
+
|
|
||||||
+ if (strncmp("mountvers", field, strlen("mountvers")) != 0) {
|
|
||||||
+ for (i=0; versions[i]; i++)
|
|
||||||
+ if (strcasestr(mopt, versions[i]) != NULL)
|
|
||||||
+ return 1;
|
|
||||||
+ }
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+unsigned long config_default_vers;
|
|
||||||
+unsigned long config_default_proto;
|
|
||||||
+/*
|
|
||||||
+ * Check to see if a default value is being set.
|
|
||||||
+ * If so, set the appropriate global value which will
|
|
||||||
+ * be used as the initial value in the server negation.
|
|
||||||
+ */
|
|
||||||
+int inline default_value(char *mopt)
|
|
||||||
+{
|
|
||||||
+ struct mount_options *options = NULL;
|
|
||||||
+ int dftlen = strlen("default");
|
|
||||||
+ char *field;
|
|
||||||
+
|
|
||||||
+ if (strncasecmp(mopt, "default", dftlen) != 0)
|
|
||||||
+ return 0;
|
|
||||||
+
|
|
||||||
+ field = mopt + dftlen;
|
|
||||||
+ if (strncasecmp(field, "proto", strlen("proto")) == 0) {
|
|
||||||
+ if ((options = po_split(field)) != NULL) {
|
|
||||||
+ if (!nfs_nfs_protocol(options, &config_default_proto)) {
|
|
||||||
+ xlog_warn("Unable to set default protocol : %s",
|
|
||||||
+ strerror(errno));
|
|
||||||
+ }
|
|
||||||
+ } else {
|
|
||||||
+ xlog_warn("Unable to alloc memory for default protocol");
|
|
||||||
+ }
|
|
||||||
+ } else if (strncasecmp(field, "vers", strlen("vers")) == 0) {
|
|
||||||
+ if ((options = po_split(field)) != NULL) {
|
|
||||||
+ if (!nfs_nfs_version(options, &config_default_vers)) {
|
|
||||||
+ xlog_warn("Unable to set default version: %s",
|
|
||||||
+ strerror(errno));
|
|
||||||
+
|
|
||||||
+ }
|
|
||||||
+ } else {
|
|
||||||
+ xlog_warn("Unable to alloc memory for default version");
|
|
||||||
+ }
|
|
||||||
+ } else
|
|
||||||
+ xlog_warn("Invalid default setting: '%s'", mopt);
|
|
||||||
+
|
|
||||||
+ if (options)
|
|
||||||
+ po_destroy(options);
|
|
||||||
+
|
|
||||||
+ return 1;
|
|
||||||
+}
|
|
||||||
/*
|
|
||||||
* Parse the given section of the configuration
|
|
||||||
* file to if there are any mount options set.
|
|
||||||
@@ -207,6 +270,12 @@ conf_parse_mntopts(char *section, char *arg, char *opts)
|
|
||||||
snprintf(buf, BUFSIZ, "%s=", node->field);
|
|
||||||
if (opts && strcasestr(opts, buf) != NULL)
|
|
||||||
continue;
|
|
||||||
+ /*
|
|
||||||
+ * Protocol verions can be set in a number of ways
|
|
||||||
+ */
|
|
||||||
+ if (opts && check_vers(opts, node->field))
|
|
||||||
+ continue;
|
|
||||||
+
|
|
||||||
if (lookup_entry(node->field) != NULL)
|
|
||||||
continue;
|
|
||||||
buf[0] = '\0';
|
|
||||||
@@ -302,15 +371,19 @@ char *conf_get_mntopts(char *spec, char *mount_point,
|
|
||||||
free_all();
|
|
||||||
return mount_opts;
|
|
||||||
}
|
|
||||||
+
|
|
||||||
if (mount_opts) {
|
|
||||||
strcpy(config_opts, mount_opts);
|
|
||||||
strcat(config_opts, ",");
|
|
||||||
}
|
|
||||||
SLIST_FOREACH(entry, &head, entries) {
|
|
||||||
+ if (default_value(entry->opt))
|
|
||||||
+ continue;
|
|
||||||
strcat(config_opts, entry->opt);
|
|
||||||
strcat(config_opts, ",");
|
|
||||||
}
|
|
||||||
- *(strrchr(config_opts, ',')) = '\0';
|
|
||||||
+ if ((ptr = strrchr(config_opts, ',')) != NULL)
|
|
||||||
+ *ptr = '\0';
|
|
||||||
|
|
||||||
free_all();
|
|
||||||
if (mount_opts)
|
|
||||||
diff --git a/utils/mount/network.c b/utils/mount/network.c
|
|
||||||
index bd621be..e651167 100644
|
|
||||||
--- a/utils/mount/network.c
|
|
||||||
+++ b/utils/mount/network.c
|
|
||||||
@@ -50,6 +50,7 @@
|
|
||||||
#include "nfsrpc.h"
|
|
||||||
#include "parse_opt.h"
|
|
||||||
#include "network.h"
|
|
||||||
+#include "conffile.h"
|
|
||||||
|
|
||||||
#define PMAP_TIMEOUT (10)
|
|
||||||
#define CONNECT_TIMEOUT (20)
|
|
||||||
@@ -609,10 +610,19 @@ static int nfs_probe_nfsport(const struct sockaddr *sap, const socklen_t salen,
|
|
||||||
if (pmap->pm_vers && pmap->pm_prot && pmap->pm_port)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
- if (nfs_mount_data_version >= 4)
|
|
||||||
+ if (nfs_mount_data_version >= 4) {
|
|
||||||
+ const unsigned int *probe_proto = probe_tcp_first;
|
|
||||||
+
|
|
||||||
+ /*
|
|
||||||
+ * If the default proto has been set and
|
|
||||||
+ * its not TCP, start with UDP
|
|
||||||
+ */
|
|
||||||
+ if (config_default_proto && config_default_proto != IPPROTO_TCP)
|
|
||||||
+ probe_proto = probe_udp_first;
|
|
||||||
+
|
|
||||||
return nfs_probe_port(sap, salen, pmap,
|
|
||||||
- probe_nfs3_first, probe_tcp_first);
|
|
||||||
- else
|
|
||||||
+ probe_nfs3_first, probe_proto);
|
|
||||||
+ } else
|
|
||||||
return nfs_probe_port(sap, salen, pmap,
|
|
||||||
probe_nfs2_only, probe_udp_only);
|
|
||||||
}
|
|
||||||
@@ -1261,7 +1271,7 @@ nfs_nfs_version(struct mount_options *options, unsigned long *version)
|
|
||||||
* Returns TRUE if @protocol contains a valid value for this option,
|
|
||||||
* or FALSE if the option was specified with an invalid value.
|
|
||||||
*/
|
|
||||||
-static int
|
|
||||||
+int
|
|
||||||
nfs_nfs_protocol(struct mount_options *options, unsigned long *protocol)
|
|
||||||
{
|
|
||||||
char *option;
|
|
||||||
diff --git a/utils/mount/network.h b/utils/mount/network.h
|
|
||||||
index 402e0a5..7eb89b0 100644
|
|
||||||
--- a/utils/mount/network.h
|
|
||||||
+++ b/utils/mount/network.h
|
|
||||||
@@ -57,6 +57,8 @@ int clnt_ping(struct sockaddr_in *, const unsigned long,
|
|
||||||
struct mount_options;
|
|
||||||
|
|
||||||
int nfs_nfs_version(struct mount_options *options, unsigned long *version);
|
|
||||||
+int nfs_nfs_protocol(struct mount_options *options, unsigned long *protocol);
|
|
||||||
+
|
|
||||||
int nfs_options2pmap(struct mount_options *,
|
|
||||||
struct pmap *, struct pmap *);
|
|
||||||
|
|
||||||
diff --git a/utils/mount/nfsmount.conf b/utils/mount/nfsmount.conf
|
|
||||||
index f9fcfcb..9b8ff4a 100644
|
|
||||||
--- a/utils/mount/nfsmount.conf
|
|
||||||
+++ b/utils/mount/nfsmount.conf
|
|
||||||
@@ -24,14 +24,29 @@
|
|
||||||
# All reads and writes to the 'nfsserver.foo.com' server
|
|
||||||
# will be done with 32k (32768 bytes) block sizes.
|
|
||||||
#
|
|
||||||
-#[ NFSMount_Global_Options ]
|
|
||||||
+[ NFSMount_Global_Options ]
|
|
||||||
# This statically named section defines global mount
|
|
||||||
# options that can be applied on all NFS mount.
|
|
||||||
#
|
|
||||||
-# Protocol Version [2,3]
|
|
||||||
-# Nfsvers=3
|
|
||||||
-# Network Transport [Udp,Tcp,Rdma]
|
|
||||||
-# Proto=Tcp
|
|
||||||
+# Protocol Version [2,3,4]
|
|
||||||
+# This defines the default protocol version which will
|
|
||||||
+# be used to start the negotiation with the server.
|
|
||||||
+# Defaultvers=4
|
|
||||||
+#
|
|
||||||
+# Setting this option makes it mandatory the server supports the
|
|
||||||
+# given version. The mount will fail if the given version is
|
|
||||||
+# not support by the server.
|
|
||||||
+# Nfsvers=4
|
|
||||||
+#
|
|
||||||
+# Network Protocol [udp,tcp,rdma] (Note: values are case sensitive)
|
|
||||||
+# This defines the default network protocol which will
|
|
||||||
+# be used to start the negotiation with the server.
|
|
||||||
+# Defaultproto=tcp
|
|
||||||
+#
|
|
||||||
+# Setting this option makes it mandatory the server supports the
|
|
||||||
+# given network protocol. The mount will fail if the given network
|
|
||||||
+# protocol is not supported by the server.
|
|
||||||
+# Proto=tcp
|
|
||||||
#
|
|
||||||
# The number of times a request will be retired before
|
|
||||||
# generating a timeout
|
|
||||||
diff --git a/utils/mount/stropts.c b/utils/mount/stropts.c
|
|
||||||
index 069bdc1..ceefdb0 100644
|
|
||||||
--- a/utils/mount/stropts.c
|
|
||||||
+++ b/utils/mount/stropts.c
|
|
||||||
@@ -45,6 +45,7 @@
|
|
||||||
#include "parse_opt.h"
|
|
||||||
#include "version.h"
|
|
||||||
#include "parse_dev.h"
|
|
||||||
+#include "conffile.h"
|
|
||||||
|
|
||||||
#ifndef NFS_PROGRAM
|
|
||||||
#define NFS_PROGRAM (100003)
|
|
||||||
@@ -283,6 +284,14 @@ static int nfs_validate_options(struct nfsmount_info *mi)
|
|
||||||
if (option && strcmp(option, "rdma") == 0)
|
|
||||||
mi->version = 3;
|
|
||||||
}
|
|
||||||
+ /*
|
|
||||||
+ * Use the default value set in the config file when
|
|
||||||
+ * the version has not been explicitly set.
|
|
||||||
+ */
|
|
||||||
+ if (mi->version == 0 && config_default_vers) {
|
|
||||||
+ if (config_default_vers < 4)
|
|
||||||
+ mi->version = config_default_vers;
|
|
||||||
+ }
|
|
||||||
|
|
||||||
if (!nfs_append_sloppy_option(mi->options))
|
|
||||||
return 0;
|
|
@ -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.2.0
|
Version: 1.2.1
|
||||||
Release: 18%{?dist}
|
Release: 1%{?dist}
|
||||||
Epoch: 1
|
Epoch: 1
|
||||||
|
|
||||||
# group all 32bit related archs
|
# group all 32bit related archs
|
||||||
@ -22,16 +22,7 @@ Patch00: nfs-utils-1.0.5-statdpath.patch
|
|||||||
Patch01: nfs-utils-1.1.0-smnotify-path.patch
|
Patch01: nfs-utils-1.1.0-smnotify-path.patch
|
||||||
Patch02: nfs-utils-1.1.0-exp-subtree-warn-off.patch
|
Patch02: nfs-utils-1.1.0-exp-subtree-warn-off.patch
|
||||||
|
|
||||||
Patch100: nfs-utils-1.2.1-rc1.patch
|
|
||||||
Patch101: nfs-utils-1.2.1-rc2.patch
|
|
||||||
Patch102: nfs-utils-1.2.1-rc3.patch
|
|
||||||
Patch103: nfs-utils-1.2.1-rc4.patch
|
|
||||||
Patch104: nfs-utils-1.2.1-rc5.patch
|
|
||||||
Patch105: nfs-utils-1.2.1-rc6.patch
|
|
||||||
Patch106: nfs-utils-1.2.1-rc7.patch
|
|
||||||
|
|
||||||
Patch200: nfs-utils-1.2.0-v4root-rel7.patch
|
Patch200: nfs-utils-1.2.0-v4root-rel7.patch
|
||||||
Patch201: nfs-utils-1.2.0-v4-enoent.patch
|
|
||||||
|
|
||||||
Group: System Environment/Daemons
|
Group: System Environment/Daemons
|
||||||
Provides: exportfs = %{epoch}:%{version}-%{release}
|
Provides: exportfs = %{epoch}:%{version}-%{release}
|
||||||
@ -83,16 +74,7 @@ This package also contains the mount.nfs and umount.nfs program.
|
|||||||
%patch01 -p1
|
%patch01 -p1
|
||||||
%patch02 -p1
|
%patch02 -p1
|
||||||
|
|
||||||
%patch100 -p1
|
|
||||||
%patch101 -p1
|
|
||||||
%patch102 -p1
|
|
||||||
%patch103 -p1
|
|
||||||
%patch104 -p1
|
|
||||||
%patch105 -p1
|
|
||||||
%patch106 -p1
|
|
||||||
|
|
||||||
%patch200 -p1
|
%patch200 -p1
|
||||||
%patch201 -p1
|
|
||||||
|
|
||||||
# Remove .orig files
|
# Remove .orig files
|
||||||
find . -name "*.orig" | xargs rm -f
|
find . -name "*.orig" | xargs rm -f
|
||||||
@ -264,6 +246,9 @@ fi
|
|||||||
%attr(4755,root,root) /sbin/umount.nfs4
|
%attr(4755,root,root) /sbin/umount.nfs4
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Wed Nov 4 2009 Steve Dickson <steved@redhat.com> 1.2.1-1
|
||||||
|
- Updated to latest upstream release: 1.2.0
|
||||||
|
|
||||||
* Tue Nov 3 2009 Steve Dickson <steved@redhat.com> 1.2.0-18
|
* Tue Nov 3 2009 Steve Dickson <steved@redhat.com> 1.2.0-18
|
||||||
- Reworked and remove some of the Default-Start/Stop stanzas
|
- Reworked and remove some of the Default-Start/Stop stanzas
|
||||||
in the init scripts (bz 531425)
|
in the init scripts (bz 531425)
|
||||||
|
Loading…
Reference in New Issue
Block a user