[-]
[+]
|
Changed |
_service:tar_git:nfs-utils.spec
|
|
|
Changed |
_service
^
|
[-]
[+]
|
Deleted |
_service:tar_git:nfs-utils-2.6.2+git3.tar.bz2/upstream/systemd/50-nfs.conf
^
|
@@ -1,16 +0,0 @@
-# Ensure all NFS systctl settings get applied when modules load
-
-# sunrpc module supports "sunrpc.*" sysctls
-install sunrpc /sbin/modprobe --ignore-install sunrpc $CMDLINE_OPTS && { /sbin/sysctl -q --pattern sunrpc --system; exit 0; }
-
-# rpcrdma module supports sunrpc.svc_rdma.*
-install rpcrdma /sbin/modprobe --ignore-install rpcrdma $CMDLINE_OPTS && { /sbin/sysctl -q --pattern sunrpc.svc_rdma --system; exit 0; }
-
-# lockd module supports "fs.nfs.nlm*" and "fs.nfs.nsm*" sysctls
-install lockd /sbin/modprobe --ignore-install lockd $CMDLINE_OPTS && { /sbin/sysctl -q --pattern fs.nfs.n[sl]m --system; exit 0; }
-
-# nfsv4 module supports "fs.nfs.*" sysctls (nfs_callback_tcpport and idmap_cache_timeout)
-install nfsv4 /sbin/modprobe --ignore-install nfsv4 $CMDLINE_OPTS && { /sbin/sysctl -q --pattern 'fs.nfs.(nfs_callback_tcpport|idmap_cache_timeout)' --system; exit 0; }
-
-# nfs module supports "fs.nfs.*" sysctls
-install nfs /sbin/modprobe --ignore-install nfs $CMDLINE_OPTS && { /sbin/sysctl -q --pattern fs.nfs --system; exit 0; }
|
[-]
[+]
|
Changed |
_service:tar_git:nfs-utils-2.6.3+git2.tar.bz2/upstream/.gitignore
^
|
@@ -72,6 +72,7 @@
support/nsm/sm_inter_svc.c
support/nsm/sm_inter_xdr.c
support/include/sm_inter.h
+support/reexport/fsidd
tests/nsm_client/nlm_sm_inter.h
tests/nsm_client/nlm_sm_inter_clnt.c
tests/nsm_client/nlm_sm_inter_svc.c
@@ -86,3 +87,5 @@
cscope.*
# generic editor backup et al
*~
+# file generated by ctags
+tags
|
[-]
[+]
|
Changed |
_service:tar_git:nfs-utils-2.6.3+git2.tar.bz2/upstream/NEWS
^
|
@@ -1,32 +1,32 @@
Significant changes for nfs-utils 1.1.0 - March/April 2007
- - rpc.lockd is gone. One 3 old kernel releases need it.
- - rpc.rquotad is gone. Use the one from the 'quota' package.
- Everone else does.
+ - rpc.lockd is gone. One 3 old kernel releases need it.
+ - rpc.rquotad is gone. Use the one from the 'quota' package.
+ Everyone else does.
- /sbin/{u,}mount.nfs{,4} are now installed so 'mount' will
use these to mount nfs filesystems instead of internal code.
+ mount.nfs will check for 'statd' to be running when mounting
- a filesystem which requires it. If it is not running it will
+ a filesystem which requires it. If it is not running it will
run "/usr/sbin/start-statd" to try to start it.
If statd is not running and cannot be started, mount.nfs will
refuse to mount the filesystem and will suggest the 'nolock'
option.
- Substantial changes to statd
+ The 'notify' process that must happen at boot has been split
- into a separate program "sm-notify". It ensures that it
- only runs once even if you restart statd. This is correct
+ into a separate program "sm-notify". It ensures that it
+ only runs once even if you restart statd. This is correct
behaviour.
+ statd stores state in the files in /var/lib/nfs/sm/ so that
if you kill and restart it, it will restore that state and
continue working correctly.
+ statd makes more use of DNS lookup and should handle
- multi-homed peers better. In particular, files in
+ multi-homed peers better. In particular, files in
/var/lib/nfs/sm/ are named with the Full Qualified Domain Name
if available.
- If you export a directory as 'crossmnt', all filesystems
mounted beneath are automatically exported with the same
options (unless explicitly exported with different options).
- - subtree_check is no-longer the default. The default is now
+ - subtree_check is no-longer the default. The default is now
no_subtree_check.
- By default the system 'rpcgen' is used while building
nfs-utils rather than the internal one.
@@ -43,14 +43,14 @@
- A new option, -n, was added to rpc.gssd which specifies that
accesses by root should not use 'machine credentials' when
- accessing NFS file systems mounted with Kerberos. Using this
+ accessing NFS file systems mounted with Kerberos. Using this
option allows the root user to access the NFS space using any
Kerberos principal, rather than always using the machine
- credentials. However, its use also requires that root manually
+ credentials. However, its use also requires that root manually
authenticate before attempting a mount with Kerberos.
When rpc.gssd uses machine credentials, the selection algorithm has
- been changed. Instead of simply using the first "nfs/*" key in the
+ been changed. Instead of simply using the first "nfs/*" key in the
keytab, the keytab is now searched for keys in the following
defined order:
|
[-]
[+]
|
Changed |
_service:tar_git:nfs-utils-2.6.3+git2.tar.bz2/upstream/README
^
|
@@ -25,7 +25,7 @@
# ./configure
# make
-To install binaries and documenation, run this command:
+To install binaries and documentation, run this command:
# make install
@@ -40,7 +40,7 @@
git pull
-Building requires that autotools be installed. To invoke them
+Building requires that autotools be installed. To invoke them
simply
sh autogen.sh
@@ -70,7 +70,7 @@
3.1. SERVER STARTUP
- A/ mount -t nfsd /proc/fs/nfsd
+ A/ mount -t nfsd nfsd /proc/fs/nfsd
This filesystem needs to be mount before most daemons,
particularly exportfs, mountd, svcgssd, idmapd.
It could be mounted once, or the script that starts each daemon
@@ -95,27 +95,27 @@
D/ rpc.statd --no-notify
It is best if statd is started before nfsd though this isn't
- critical. Certainly it should be at most a few seconds after
+ critical. Certainly, it should be at most a few seconds after
nfsd.
When nfsd starts it will start lockd. If lockd then receives a
- lock request it will communicate with statd. If statd is not
+ lock request, it will communicate with statd. If statd is not
running lockd will retry, but it won't wait forever for a
reply.
Note that if statd is started before nfsd, the --no-notify
- option must be used. If notify requests are sent out before
+ option must be used. If notify requests are sent out before
nfsd start, clients may try to reclaim locks and, on finding
that lockd isn't running, they will give up and never reclaim
the lock.
rpc.statd is only needed for NFSv2 and NFSv3 support.
E/ rpc.nfsd
- Starting nfsd will automatically start lockd. The nfs server
+ Starting nfsd will automatically start lockd. The nfs server
will now be fully active and respond to any requests from
clients.
F/ sm-notify
This will notify any client which might have locks from before
- a reboot to try to reclaim their locks. This should start
+ a reboot to try to reclaim their locks. This should start
immediately after rpc.nfsd is started so that clients have a
chance to reclaim locks within the 90 second grace period.
sm-notify is only needed for NFSv2 and NFSv3 support.
|
[-]
[+]
|
Changed |
_service:tar_git:nfs-utils-2.6.3+git2.tar.bz2/upstream/configure.ac
^
|
@@ -1,6 +1,6 @@
dnl Process this file with autoconf to produce a configure script.
dnl
-AC_INIT([linux nfs-utils],[2.6.2],[linux-nfs@vger.kernel.org],[nfs-utils])
+AC_INIT([linux nfs-utils],[2.6.3],[linux-nfs@vger.kernel.org],[nfs-utils])
AC_CANONICAL_BUILD([])
AC_CANONICAL_HOST([])
AC_CONFIG_MACRO_DIR(aclocal)
@@ -71,18 +71,6 @@
AM_CONDITIONAL(INSTALL_SYSTEMD, [test "$use_systemd" = 1])
AC_SUBST(unitdir)
-modprobedir=/usr/lib/modprobe.d
-AC_ARG_WITH(modprobedir,
- [AS_HELP_STRING([--with-modprobedir@<:@=modprobe-dir-path@:>@],[install modprobe config files @<:@Default: /usr/lib/modprobe.d@:>@])],
- if test "$withval" != "no" ; then
- modprobedir=$withval
- else
- modprobedir=
- fi
- )
- AM_CONDITIONAL(INSTALL_MODPROBEDIR, [test -n "$modprobedir"])
- AC_SUBST(modprobedir)
-
AC_ARG_ENABLE(nfsv4,
[AS_HELP_STRING([--disable-nfsv4],[disable support for NFSv4 @<:@default=no@:>@])],
enable_nfsv4=$enableval,
@@ -249,6 +237,16 @@
enable_nfsdcld=$enableval,
enable_nfsdcld="yes")
+AC_ARG_ENABLE(nfsrahead,
+ [AS_HELP_STRING([--disable-nfsrahead],[disable nfsrahead command @<:@default=no@:>@])],
+ enable_nfsrahead=$enableval,
+ enable_nfsrahead="yes")
+ AM_CONDITIONAL(CONFIG_NFSRAHEAD, [test "$enable_nfsrahead" = "yes" ])
+ if test "$enable_nfsrahead" = yes; then
+ dnl Check for -lmount
+ PKG_CHECK_MODULES([LIBMOUNT], [mount])
+ fi
+
AC_ARG_ENABLE(nfsdcltrack,
[AS_HELP_STRING([--disable-nfsdcltrack],[disable NFSv4 clientid tracking programs @<:@default=no@:>@])],
enable_nfsdcltrack=$enableval,
@@ -678,12 +676,12 @@
# Make sure that $ACLOCAL_FLAGS are used during a rebuild
AC_SUBST([ACLOCAL_AMFLAGS], ["-I $ac_macro_dir \$(ACLOCAL_FLAGS)"])
-# make _sysconfdir available for substituion in config files
+# make _sysconfdir available for substitution in config files
# 2 "evals" needed late to expand variable names.
AC_SUBST([_sysconfdir])
AC_CONFIG_COMMANDS_PRE([eval eval _sysconfdir=$sysconfdir])
-# make _statedir available for substituion in config files
+# make _statedir available for substitution in config files
# 2 "evals" needed late to expand variable names.
AC_SUBST([_statedir])
AC_CONFIG_COMMANDS_PRE([eval eval _statedir=$statedir])
@@ -695,7 +693,7 @@
fi
AC_SUBST(rpc_pipefsmount)
-# make _rpc_pipefsmount available for substituion in config files
+# make _rpc_pipefsmount available for substitution in config files
# 2 "evals" needed late to expand variable names.
AC_SUBST([_rpc_pipefsmount])
AC_CONFIG_COMMANDS_PRE([eval eval _rpc_pipefsmount=$rpc_pipefsmount])
@@ -719,6 +717,7 @@
support/nsm/Makefile
support/nfsidmap/Makefile
support/nfsidmap/libnfsidmap.pc
+ support/reexport/Makefile
tools/Makefile
tools/locktest/Makefile
tools/nlmtest/Makefile
|
[-]
[+]
|
Changed |
_service:tar_git:nfs-utils-2.6.3+git2.tar.bz2/upstream/support/Makefile.am
^
|
@@ -10,7 +10,7 @@
OPTDIRS += junction
endif
-SUBDIRS = export include misc nfs nsm $(OPTDIRS)
+SUBDIRS = export include misc nfs nsm reexport $(OPTDIRS)
MAINTAINERCLEANFILES = Makefile.in
|
[-]
[+]
|
Changed |
_service:tar_git:nfs-utils-2.6.3+git2.tar.bz2/upstream/support/export/Makefile.am
^
|
@@ -14,6 +14,8 @@
xtab.c mount_clnt.c mount_xdr.c \
cache.c auth.c v4root.c fsloc.c \
v4clients.c
+libexport_a_CPPFLAGS = $(AM_CPPFLAGS) $(CPPFLAGS) -I$(top_srcdir)/support/reexport
+
BUILT_SOURCES = $(GENFILES)
noinst_HEADERS = mount.h
|
[-]
[+]
|
Changed |
_service:tar_git:nfs-utils-2.6.3+git2.tar.bz2/upstream/support/export/auth.c
^
|
@@ -82,7 +82,7 @@
}
unsigned int
-auth_reload()
+auth_reload(void)
{
struct stat stb;
static ino_t last_inode;
|
[-]
[+]
|
Changed |
_service:tar_git:nfs-utils-2.6.3+git2.tar.bz2/upstream/support/export/cache.c
^
|
@@ -33,6 +33,7 @@
#include "export.h"
#include "pseudoflavors.h"
#include "xcommon.h"
+#include "reexport.h"
#ifdef HAVE_JUNCTION_SUPPORT
#include "fsloc.h"
@@ -235,6 +236,16 @@
xlog(L_ERROR, "auth_unix_gid: error writing reply");
}
+static int match_crossmnt_fsidnum(uint32_t parsed_fsidnum, char *path)
+{
+ uint32_t fsidnum;
+
+ if (reexpdb_fsidnum_by_path(path, &fsidnum, 0) == 0)
+ return 0;
+
+ return fsidnum == parsed_fsidnum;
+}
+
#ifdef USE_BLKID
static const char *get_uuid_blkdev(char *path)
{
@@ -346,27 +357,27 @@
/* Possible sources of uuid are
* - blkid uuid
- * - statfs64 uuid
+ * - statfs uuid
*
- * On some filesystems (e.g. vfat) the statfs64 uuid is simply an
+ * On some filesystems (e.g. vfat) the statfs uuid is simply an
* encoding of the device that the filesystem is mounted from, so
* it we be very bad to use that (as device numbers change). blkid
* must be preferred.
- * On other filesystems (e.g. btrfs) the statfs64 uuid contains
+ * On other filesystems (e.g. btrfs) the statfs uuid contains
* important info that the blkid uuid cannot contain: This happens
* when multiple subvolumes are exported (they have the same
- * blkid uuid but different statfs64 uuids).
+ * blkid uuid but different statfs uuids).
* We rely on get_uuid_blkdev *knowing* which is which and not returning
- * a uuid for filesystems where the statfs64 uuid is better.
+ * a uuid for filesystems where the statfs uuid is better.
*
*/
- struct statfs64 st;
+ struct statfs st;
char fsid_val[17];
const char *blkid_val = NULL;
const char *val;
int rc;
- rc = nfsd_path_statfs64(path, &st);
+ rc = nfsd_path_statfs(path, &st);
if (type == 0 && rc == 0) {
const unsigned long *bad;
@@ -410,12 +421,16 @@
*v = f;
} else
f = *v;
- while ((me = getmntent(f)) != NULL && l > 1) {
+ while ((me = getmntent(f)) != NULL && l >= 1) {
char *mnt_dir = nfsd_path_strip_root(me->mnt_dir);
if (!mnt_dir)
continue;
+ /* Everything below "/" is a proper sub-mount */
+ if (strcmp(p, "/") == 0)
+ return mnt_dir;
+
if (strncmp(mnt_dir, p, l) == 0 && mnt_dir[l] == '/')
return mnt_dir;
}
@@ -684,8 +699,13 @@
goto match;
case FSID_NUM:
if (((exp->m_export.e_flags & NFSEXP_FSID) == 0 ||
- exp->m_export.e_fsid != parsed->fsidnum))
+ exp->m_export.e_fsid != parsed->fsidnum)) {
+ if ((exp->m_export.e_flags & NFSEXP_CROSSMOUNT) && exp->m_export.e_reexport != REEXP_NONE &&
+ match_crossmnt_fsidnum(parsed->fsidnum, path))
+ goto match;
+
goto nomatch;
+ }
goto match;
case FSID_UUID4_INUM:
case FSID_UUID16_INUM:
@@ -758,6 +778,7 @@
int dev_missing = 0;
char buf[RPC_CHAN_BUF_SIZE], *bp;
int blen;
+ int did_uncover = 0;
blen = cache_read(f, buf, sizeof(buf));
if (blen <= 0 || buf[blen-1] != '\n') return;
@@ -795,6 +816,11 @@
for (exp = exportlist[i].p_head; exp; exp = next_exp) {
char *path;
+ if (!did_uncover && parsed.fsidnum && parsed.fsidtype == FSID_NUM && exp->m_export.e_reexport != REEXP_NONE) {
+ reexpdb_uncover_subvolume(parsed.fsidnum);
+ did_uncover = 1;
+ }
+
if (exp->m_export.e_flags & NFSEXP_CROSSMOUNT) {
static nfs_export *prev = NULL;
static void *mnt = NULL;
@@ -932,7 +958,8 @@
release_replicas(servers);
}
#endif
-static void write_secinfo(char **bp, int *blen, struct exportent *ep, int flag_mask)
+
+static void write_secinfo(char **bp, int *blen, struct exportent *ep, int flag_mask, int extra_flag)
{
struct sec_entry *p;
@@ -947,9 +974,31 @@
qword_addint(bp, blen, p - ep->e_secinfo);
for (p = ep->e_secinfo; p->flav; p++) {
qword_addint(bp, blen, p->flav->fnum);
- qword_addint(bp, blen, p->flags & flag_mask);
+ qword_addint(bp, blen, (p->flags | extra_flag) & flag_mask);
}
+}
+
+static void write_xprtsec(char **bp, int *blen, struct exportent *ep)
+{
+ struct xprtsec_entry *p;
+ for (p = ep->e_xprtsec; p->info; p++);
+ if (p == ep->e_xprtsec)
+ return;
+
+ qword_add(bp, blen, "xprtsec");
+ qword_addint(bp, blen, p - ep->e_xprtsec);
+ for (p = ep->e_xprtsec; p->info; p++)
+ qword_addint(bp, blen, p->info->number);
+}
+
+static int can_reexport_via_fsidnum(struct exportent *exp, struct statfs *st)
+{
+ if (st->f_type != 0x6969 /* NFS_SUPER_MAGIC */)
+ return 0;
+
+ return exp->e_reexport == REEXP_PREDEFINED_FSIDNUM ||
+ exp->e_reexport == REEXP_AUTO_FSIDNUM;
}
static int dump_to_cache(int f, char *buf, int blen, char *domain,
@@ -968,17 +1017,48 @@
if (exp) {
int different_fs = strcmp(path, exp->e_path) != 0;
int flag_mask = different_fs ? ~NFSEXP_FSID : ~0;
+ int rc, do_fsidnum = 0;
+ uint32_t fsidnum = exp->e_fsid;
+
+ if (different_fs) {
+ struct statfs st;
+
+ rc = nfsd_path_statfs(path, &st);
+ if (rc) {
+ xlog(L_WARNING, "unable to statfs %s", path);
+ errno = EINVAL;
+ return -1;
+ }
+
+ if (can_reexport_via_fsidnum(exp, &st)) {
+ do_fsidnum = 1;
+ flag_mask = ~0;
+ }
+ }
qword_adduint(&bp, &blen, now + exp->e_ttl);
- qword_addint(&bp, &blen, exp->e_flags & flag_mask);
+
+ if (do_fsidnum) {
+ uint32_t search_fsidnum = 0;
+ if (exp->e_reexport != REEXP_NONE && reexpdb_fsidnum_by_path(path, &search_fsidnum,
+ exp->e_reexport == REEXP_AUTO_FSIDNUM) == 0) {
+ errno = EINVAL;
+ return -1;
+ }
+ fsidnum = search_fsidnum;
+ qword_addint(&bp, &blen, exp->e_flags | NFSEXP_FSID);
+ } else {
+ qword_addint(&bp, &blen, exp->e_flags & flag_mask);
+ }
+
qword_addint(&bp, &blen, exp->e_anonuid);
qword_addint(&bp, &blen, exp->e_anongid);
- qword_addint(&bp, &blen, exp->e_fsid);
+ qword_addint(&bp, &blen, fsidnum);
|
[-]
[+]
|
Changed |
_service:tar_git:nfs-utils-2.6.3+git2.tar.bz2/upstream/support/export/client.c
^
|
@@ -699,6 +699,9 @@
/* check whether the IP itself is in the netgroup */
ip = calloc(INET6_ADDRSTRLEN, 1);
+ if (ip == NULL)
+ goto out;
+
if (inet_ntop(ai->ai_family, &(((struct sockaddr_in *)ai->ai_addr)->sin_addr), ip, INET6_ADDRSTRLEN) == ip) {
if (innetgr(netgroup, ip, NULL, NULL)) {
free(hname);
|
[-]
[+]
|
Changed |
_service:tar_git:nfs-utils-2.6.3+git2.tar.bz2/upstream/support/export/export.c
^
|
@@ -25,6 +25,7 @@
#include "exportfs.h"
#include "nfsd_path.h"
#include "xlog.h"
+#include "reexport.h"
exp_hash_table exportlist[MCL_MAXTYPES] = {{NULL, {{NULL,NULL}, }}, };
static int export_hash(char *);
@@ -115,6 +116,7 @@
nfs_export *exp;
int volumes = 0;
+ int reexport_found = 0;
setexportent(fname, "r");
while ((eep = getexportent(0,1)) != NULL) {
@@ -126,7 +128,25 @@
}
else
warn_duplicated_exports(exp, eep);
+
+ if (eep->e_reexport)
+ reexport_found = 1;
}
+
+ if (reexport_found) {
+ for (int i = 0; i < MCL_MAXTYPES; i++) {
+ for (exp = exportlist[i].p_head; exp; exp = exp->m_next) {
+ if (exp->m_export.e_reexport)
+ continue;
+
+ if (exp->m_export.e_flags & NFSEXP_FSID) {
+ xlog(L_ERROR, "When a reexport= option is present no manully assigned numerical fsid= options are allowed");
+ return -1;
+ }
+ }
+ }
+ }
+
endexportent();
return volumes;
|
[-]
[+]
|
Changed |
_service:tar_git:nfs-utils-2.6.3+git2.tar.bz2/upstream/support/export/v4clients.c
^
|
@@ -26,7 +26,7 @@
{
struct stat sb;
- if (!stat("/proc/fs/nfsd/clients", &sb) == 0 ||
+ if (stat("/proc/fs/nfsd/clients", &sb) != 0 ||
!S_ISDIR(sb.st_mode))
return;
if (clients_fd >= 0)
|
[-]
[+]
|
Changed |
_service:tar_git:nfs-utils-2.6.3+git2.tar.bz2/upstream/support/export/v4root.c
^
|
@@ -66,6 +66,8 @@
if (!flav->fnum)
continue;
+ if (flav->need_krb5 && access("/etc/krb5.keytab", F_OK) != 0)
+ continue;
i = secinfo_addflavor(flav, pseudo);
new = &pseudo->e_secinfo[i];
@@ -198,7 +200,7 @@
* looking for components of the v4 mount.
*/
void
-v4root_set()
+v4root_set(void)
{
nfs_export *exp;
int i;
|
[-]
[+]
|
Changed |
_service:tar_git:nfs-utils-2.6.3+git2.tar.bz2/upstream/support/export/xtab.c
^
|
@@ -135,7 +135,7 @@
}
int
-xtab_export_write()
+xtab_export_write(void)
{
return xtab_write(etab.statefn, etab.tmpfn, etab.lockfn, 1);
}
|
[-]
[+]
|
Changed |
_service:tar_git:nfs-utils-2.6.3+git2.tar.bz2/upstream/support/include/nfs/export.h
^
|
@@ -40,4 +40,18 @@
#define NFSEXP_OLD_SECINFO_FLAGS (NFSEXP_READONLY | NFSEXP_ROOTSQUASH \
| NFSEXP_ALLSQUASH)
+/*
+ * Transport layer security policies that are permitted to access
+ * an export
+ */
+#define NFSEXP_XPRTSEC_NONE 0x0001
+#define NFSEXP_XPRTSEC_TLS 0x0002
+#define NFSEXP_XPRTSEC_MTLS 0x0004
+
+#define NFSEXP_XPRTSEC_NUM (3)
+
+#define NFSEXP_XPRTSEC_ALL (NFSEXP_XPRTSEC_NONE | \
+ NFSEXP_XPRTSEC_TLS | \
+ NFSEXP_XPRTSEC_MTLS)
+
#endif /* _NSF_EXPORT_H */
|
[-]
[+]
|
Changed |
_service:tar_git:nfs-utils-2.6.3+git2.tar.bz2/upstream/support/include/nfsd_path.h
^
|
@@ -7,7 +7,7 @@
#include <sys/stat.h>
struct file_handle;
-struct statfs64;
+struct statfs;
void nfsd_path_init(void);
@@ -18,8 +18,8 @@
int nfsd_path_stat(const char *pathname, struct stat *statbuf);
int nfsd_path_lstat(const char *pathname, struct stat *statbuf);
-int nfsd_path_statfs64(const char *pathname,
- struct statfs64 *statbuf);
+int nfsd_path_statfs(const char *pathname,
+ struct statfs *statbuf);
char * nfsd_realpath(const char *path, char *resolved_path);
|
[-]
[+]
|
Changed |
_service:tar_git:nfs-utils-2.6.3+git2.tar.bz2/upstream/support/include/nfslib.h
^
|
@@ -62,6 +62,18 @@
int flags;
};
+#define XPRTSECMODE_COUNT 3
+
+struct xprtsec_info {
+ const char *name;
+ int number;
+};
+
+struct xprtsec_entry {
+ const struct xprtsec_info *info;
+ int flags;
+};
+
/*
* Data related to a single exports entry as returned by getexportent.
* FIXME: export options should probably be parsed at a later time to
@@ -83,8 +95,10 @@
char * e_fslocdata;
char * e_uuid;
struct sec_entry e_secinfo[SECFLAVOR_COUNT+1];
+ struct xprtsec_entry e_xprtsec[XPRTSECMODE_COUNT + 1];
unsigned int e_ttl;
char * e_realpath;
+ int e_reexport;
};
struct rmtabent {
@@ -99,6 +113,7 @@
void setexportent(char *fname, char *type);
struct exportent * getexportent(int,int);
void secinfo_show(FILE *fp, struct exportent *ep);
+void xprtsecinfo_show(FILE *fp, struct exportent *ep);
void putexportent(struct exportent *xep);
void endexportent(void);
struct exportent * mkexportent(char *hname, char *path, char *opts);
|
[-]
[+]
|
Changed |
_service:tar_git:nfs-utils-2.6.3+git2.tar.bz2/upstream/support/include/pseudoflavors.h
^
|
@@ -8,6 +8,7 @@
struct flav_info {
char *flavour;
int fnum;
+ int need_krb5;
};
extern struct flav_info flav_map[];
|
[-]
[+]
|
Changed |
_service:tar_git:nfs-utils-2.6.3+git2.tar.bz2/upstream/support/junction/junction.c
^
|
@@ -63,7 +63,7 @@
if (pathname == NULL || fd == NULL)
return FEDFS_ERR_INVAL;
- tmp = open(pathname, O_DIRECTORY);
+ tmp = open(pathname, O_PATH|O_DIRECTORY);
if (tmp == -1) {
switch (errno) {
case EPERM:
@@ -93,7 +93,7 @@
{
struct stat stb;
- if (fstat(fd, &stb) == -1) {
+ if (fstatat(fd, "", &stb, AT_NO_AUTOMOUNT|AT_EMPTY_PATH) == -1) {
xlog(D_GENERAL, "%s: failed to stat %s: %m",
__func__, path);
return FEDFS_ERR_ACCESS;
@@ -121,7 +121,7 @@
{
struct stat stb;
- if (fstat(fd, &stb) == -1) {
+ if (fstatat(fd, "", &stb, AT_NO_AUTOMOUNT|AT_EMPTY_PATH) == -1) {
xlog(D_GENERAL, "%s: failed to stat %s: %m",
__func__, path);
return FEDFS_ERR_ACCESS;
@@ -155,7 +155,7 @@
{
struct stat stb;
- if (fstat(fd, &stb) == -1) {
+ if (fstatat(fd, "", &stb, AT_NO_AUTOMOUNT|AT_EMPTY_PATH) == -1) {
xlog(D_GENERAL, "%s: failed to stat %s: %m",
__func__, path);
return FEDFS_ERR_ACCESS;
@@ -393,7 +393,7 @@
if (retval != FEDFS_OK)
return retval;
- if (fstat(fd, &stb) == -1) {
+ if (fstatat(fd, "", &stb, AT_NO_AUTOMOUNT|AT_EMPTY_PATH) == -1) {
xlog(D_GENERAL, "%s: failed to stat %s: %m",
__func__, pathname);
(void)close(fd);
|
[-]
[+]
|
Changed |
_service:tar_git:nfs-utils-2.6.3+git2.tar.bz2/upstream/support/misc/nfsd_path.c
^
|
@@ -184,46 +184,46 @@
return nfsd_run_stat(nfsd_wq, nfsd_lstatfunc, pathname, statbuf);
}
-struct nfsd_statfs64_data {
+struct nfsd_statfs_data {
const char *pathname;
- struct statfs64 *statbuf;
+ struct statfs *statbuf;
int ret;
int err;
};
static void
-nfsd_statfs64func(void *data)
+nfsd_statfsfunc(void *data)
{
- struct nfsd_statfs64_data *d = data;
+ struct nfsd_statfs_data *d = data;
- d->ret = statfs64(d->pathname, d->statbuf);
+ d->ret = statfs(d->pathname, d->statbuf);
if (d->ret < 0)
d->err = errno;
}
static int
-nfsd_run_statfs64(struct xthread_workqueue *wq,
+nfsd_run_statfs(struct xthread_workqueue *wq,
const char *pathname,
- struct statfs64 *statbuf)
+ struct statfs *statbuf)
{
- struct nfsd_statfs64_data data = {
+ struct nfsd_statfs_data data = {
pathname,
statbuf,
0,
0
};
- xthread_work_run_sync(wq, nfsd_statfs64func, &data);
+ xthread_work_run_sync(wq, nfsd_statfsfunc, &data);
if (data.ret < 0)
errno = data.err;
return data.ret;
}
int
-nfsd_path_statfs64(const char *pathname, struct statfs64 *statbuf)
+nfsd_path_statfs(const char *pathname, struct statfs *statbuf)
{
if (!nfsd_wq)
- return statfs64(pathname, statbuf);
- return nfsd_run_statfs64(nfsd_wq, pathname, statbuf);
+ return statfs(pathname, statbuf);
+ return nfsd_run_statfs(nfsd_wq, pathname, statbuf);
}
struct nfsd_realpath_data {
|
[-]
[+]
|
Changed |
_service:tar_git:nfs-utils-2.6.3+git2.tar.bz2/upstream/support/nfs/Makefile.am
^
|
@@ -9,6 +9,7 @@
svc_socket.c cacheio.c closeall.c nfs_mntent.c \
svc_create.c atomicio.c strlcat.c strlcpy.c
libnfs_la_LIBADD = libnfsconf.la
+libnfs_la_CPPFLAGS = $(AM_CPPFLAGS) $(CPPFLAGS) -I$(top_srcdir)/support/reexport
libnfsconf_la_SOURCES = conffile.c xlog.c
|
[-]
[+]
|
Changed |
_service:tar_git:nfs-utils-2.6.3+git2.tar.bz2/upstream/support/nfs/exports.c
^
|
@@ -31,18 +31,19 @@
#include "xlog.h"
#include "xio.h"
#include "pseudoflavors.h"
+#include "reexport.h"
#define EXPORT_DEFAULT_FLAGS \
(NFSEXP_READONLY|NFSEXP_ROOTSQUASH|NFSEXP_GATHERED_WRITES|NFSEXP_NOSUBTREECHECK)
struct flav_info flav_map[] = {
- { "krb5", RPC_AUTH_GSS_KRB5 },
- { "krb5i", RPC_AUTH_GSS_KRB5I },
- { "krb5p", RPC_AUTH_GSS_KRB5P },
- { "unix", AUTH_UNIX },
- { "sys", AUTH_SYS },
- { "null", AUTH_NULL },
- { "none", AUTH_NONE },
+ { "krb5", RPC_AUTH_GSS_KRB5, 1},
+ { "krb5i", RPC_AUTH_GSS_KRB5I, 1},
+ { "krb5p", RPC_AUTH_GSS_KRB5P, 1},
+ { "unix", AUTH_UNIX, 0},
+ { "sys", AUTH_SYS, 0},
+ { "null", AUTH_NULL, 0},
+ { "none", AUTH_NONE, 0},
};
const int flav_map_size = sizeof(flav_map)/sizeof(flav_map[0]);
@@ -99,10 +100,12 @@
ee->e_fslocmethod = FSLOC_NONE;
ee->e_fslocdata = NULL;
ee->e_secinfo[0].flav = NULL;
+ ee->e_xprtsec[0].info = NULL;
ee->e_nsquids = 0;
ee->e_nsqgids = 0;
ee->e_uuid = NULL;
ee->e_ttl = default_ttl;
+ ee->e_reexport = REEXP_NONE;
}
struct exportent *
@@ -122,7 +125,7 @@
if (first || (ok = getexport(exp, sizeof(exp))) == 0) {
has_default_opts = 0;
has_default_subtree_opts = 0;
-
+
init_exportent(&def_ee, fromkernel);
ok = getpath(def_ee.e_path, sizeof(def_ee.e_path));
@@ -146,7 +149,7 @@
if (exp[0] == '-' && !fromkernel) {
if (parseopts(exp + 1, &def_ee, 0, &has_default_subtree_opts) < 0)
return NULL;
-
+
has_default_opts = 1;
ok = getexport(exp, sizeof(exp));
@@ -239,7 +242,6 @@
if (ep->e_secinfo[0].flav == NULL)
secinfo_addflavor(find_flavor("sys"), ep);
for (p1=ep->e_secinfo; p1->flav; p1=p2) {
-
fprintf(fp, ",sec=%s", p1->flav->flavour);
for (p2=p1+1; (p2->flav != NULL) && (p1->flags == p2->flags);
p2++) {
@@ -249,6 +251,17 @@
}
}
+void xprtsecinfo_show(FILE *fp, struct exportent *ep)
+{
+ struct xprtsec_entry *p1, *p2;
+
+ for (p1 = ep->e_xprtsec; p1->info; p1 = p2) {
+ fprintf(fp, ",xprtsec=%s", p1->info->name);
+ for (p2 = p1 + 1; p2->info && (p1->flags == p2->flags); p2++)
+ fprintf(fp, ":%s", p2->info->name);
+ }
+}
+
static void
fprintpath(FILE *fp, const char *path)
{
@@ -302,6 +315,23 @@
}
if (ep->e_uuid)
fprintf(fp, "fsid=%s,", ep->e_uuid);
+
+ if (ep->e_reexport) {
+ fprintf(fp, "reexport=");
+ switch (ep->e_reexport) {
+ case REEXP_AUTO_FSIDNUM:
+ fprintf(fp, "auto-fsidnum");
+ break;
+ case REEXP_PREDEFINED_FSIDNUM:
+ fprintf(fp, "predefined-fsidnum");
+ break;
+ default:
+ xlog(L_ERROR, "unknown reexport method %i", ep->e_reexport);
+ fprintf(fp, "none");
+ }
+ fprintf(fp, ",");
+ }
+
if (ep->e_mountpoint)
fprintf(fp, "mountpoint%s%s,",
ep->e_mountpoint[0]?"=":"", ep->e_mountpoint);
@@ -345,6 +375,7 @@
}
fprintf(fp, "anonuid=%d,anongid=%d", ep->e_anonuid, ep->e_anongid);
secinfo_show(fp, ep);
+ xprtsecinfo_show(fp, ep);
fprintf(fp, ")\n");
}
@@ -483,6 +514,75 @@
return out;
}
+static const struct xprtsec_info xprtsec_name2info[] = {
+ { "none", NFSEXP_XPRTSEC_NONE },
+ { "tls", NFSEXP_XPRTSEC_TLS },
+ { "mtls", NFSEXP_XPRTSEC_MTLS },
+ { NULL, 0 }
+};
+
+static const struct xprtsec_info *find_xprtsec_info(const char *name)
+{
+ const struct xprtsec_info *info;
+
+ for (info = xprtsec_name2info; info->name; info++)
+ if (strcmp(info->name, name) == 0)
+ return info;
+ return NULL;
+}
+
+/*
+ * Append the given xprtsec mode to the exportent's e_xprtsec array,
+ * or do nothing if it's already there. Returns the index of flavor in
+ * the resulting array in any case.
+ */
+static int xprtsec_addmode(const struct xprtsec_info *info, struct exportent *ep)
+{
+ struct xprtsec_entry *p;
+
+ for (p = ep->e_xprtsec; p->info; p++)
+ if (p->info == info || p->info->number == info->number)
+ return p - ep->e_xprtsec;
+
+ if (p - ep->e_xprtsec >= XPRTSECMODE_COUNT) {
+ xlog(L_ERROR, "more than %d xprtsec modes on an export\n",
+ XPRTSECMODE_COUNT);
+ return -1;
+ }
+ p->info = info;
+ p->flags = ep->e_flags;
+ (p + 1)->info = NULL;
+ return p - ep->e_xprtsec;
+}
+
+/*
+ * @str is a colon seperated list of transport layer security modes.
+ * Their order is recorded in @ep, and a bitmap corresponding to the
+ * list is returned.
+ *
+ * A zero return indicates an error.
+ */
+static unsigned int parse_xprtsec(char *str, struct exportent *ep)
+{
+ unsigned int out = 0;
+ char *name;
+
+ while ((name = strsep(&str, ":"))) {
+ const struct xprtsec_info *info = find_xprtsec_info(name);
+ int bit;
+
+ if (!info) {
+ xlog(L_ERROR, "unknown xprtsec mode %s\n", name);
+ return 0;
+ }
+ bit = xprtsec_addmode(info, ep);
+ if (bit < 0)
+ return 0;
+ out |= 1 << bit;
+ }
+ return out;
+}
+
/* Sets the bits in @mask for the appropriate security flavor flags. */
static void setflags(int mask, unsigned int active, struct exportent *ep)
{
@@ -538,6 +638,7 @@
char *flname = efname?efname:"command line";
int flline = efp?efp->x_line:0;
unsigned int active = 0;
+ int saw_reexport = 0;
squids = ep->e_squids; nsquids = ep->e_nsquids;
sqgids = ep->e_sqgids; nsqgids = ep->e_nsqgids;
|
[-]
[+]
|
Changed |
_service:tar_git:nfs-utils-2.6.3+git2.tar.bz2/upstream/support/nfs/xlog.c
^
|
@@ -46,11 +46,13 @@
static void xlog_toggle(int sig);
static struct xlog_debugfac debugnames[] = {
+ { "0", 0, },
{ "general", D_GENERAL, },
{ "call", D_CALL, },
{ "auth", D_AUTH, },
{ "parse", D_PARSE, },
{ "all", D_ALL, },
+ { "1", D_ALL, },
{ NULL, 0, },
};
@@ -119,13 +121,14 @@
{
struct xlog_debugfac *tbl = debugnames;
- while (tbl->df_name != NULL && strcasecmp(tbl->df_name, kind))
+ while (tbl->df_name != NULL && strcasecmp(tbl->df_name, kind))
tbl++;
if (!tbl->df_name) {
xlog (L_WARNING, "Invalid debug facility: %s\n", kind);
return;
}
- xlog_config(tbl->df_fac, on);
+ if (tbl->df_fac)
+ xlog_config(tbl->df_fac, on);
}
void
|
[-]
[+]
|
Changed |
_service:tar_git:nfs-utils-2.6.3+git2.tar.bz2/upstream/support/nfsidmap/regex.c
^
|
@@ -542,7 +542,7 @@
.gss_princ_to_grouplist = regex_gss_princ_to_grouplist,
};
-struct trans_func *libnfsidmap_plugin_init()
+struct trans_func *libnfsidmap_plugin_init(void)
{
return (®ex_trans);
}
|
[-]
[+]
|
Added |
_service:tar_git:nfs-utils-2.6.3+git2.tar.bz2/upstream/support/reexport/Makefile.am
^
|
@@ -0,0 +1,18 @@
+## Process this file with automake to produce Makefile.in
+
+noinst_LIBRARIES = libreexport.a
+libreexport_a_SOURCES = reexport.c
+
+sbin_PROGRAMS = fsidd
+
+fsidd_SOURCES = fsidd.c backend_sqlite.c
+
+fsidd_LDADD = ../../support/misc/libmisc.a \
+ ../../support/nfs/libnfs.la \
+ $(LIBPTHREAD) $(LIBEVENT) $(LIBSQLITE) \
+ $(OPTLIBS)
+
+fsidd_CPPFLAGS = $(AM_CPPFLAGS) $(CPPFLAGS) \
+ -I$(top_builddir)/support/include
+
+MAINTAINERCLEANFILES = Makefile.in
|
[-]
[+]
|
Added |
_service:tar_git:nfs-utils-2.6.3+git2.tar.bz2/upstream/support/reexport/backend_sqlite.c
^
|
@@ -0,0 +1,267 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <sqlite3.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/random.h>
+#include <unistd.h>
+
+#include "conffile.h"
+#include "reexport_backend.h"
+#include "xlog.h"
+
+#define REEXPDB_DBFILE NFS_STATEDIR "/reexpdb.sqlite3"
+#define REEXPDB_DBFILE_WAIT_USEC (5000)
+
+static sqlite3 *db;
+static int init_done;
+
+static int prng_init(void)
+{
+ int seed;
+
+ if (getrandom(&seed, sizeof(seed), 0) != sizeof(seed)) {
+ xlog(L_ERROR, "Unable to obtain seed for PRNG via getrandom()");
+ return -1;
+ }
+
+ srand(seed);
+ return 0;
+}
+
+static void wait_for_dbaccess(void)
+{
+ usleep(REEXPDB_DBFILE_WAIT_USEC + (rand() % REEXPDB_DBFILE_WAIT_USEC));
+}
+
+static bool sqlite_plug_init(void)
+{
+ char *sqlerr;
+ int ret;
+
+ if (init_done)
+ return true;
+
+ if (prng_init() != 0)
+ return false;
+
+ ret = sqlite3_open_v2(conf_get_str_with_def("reexport", "sqlitedb", REEXPDB_DBFILE),
+ &db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_FULLMUTEX,
+ NULL);
+ if (ret != SQLITE_OK) {
+ xlog(L_ERROR, "Unable to open reexport database: %s", sqlite3_errstr(ret));
+ return false;
+ }
+
+again:
+ ret = sqlite3_exec(db, "CREATE TABLE IF NOT EXISTS fsidnums (num INTEGER PRIMARY KEY CHECK (num > 0 AND num < 4294967296), path TEXT UNIQUE); CREATE INDEX IF NOT EXISTS idx_ids_path ON fsidnums (path);", NULL, NULL, &sqlerr);
+ switch (ret) {
+ case SQLITE_OK:
+ init_done = 1;
+ ret = 0;
+ break;
+ case SQLITE_BUSY:
+ case SQLITE_LOCKED:
+ wait_for_dbaccess();
+ goto again;
+ default:
+ xlog(L_ERROR, "Unable to init reexport database: %s", sqlite3_errstr(ret));
+ sqlite3_free(sqlerr);
+ sqlite3_close_v2(db);
+ ret = -1;
+ }
+
+ return ret == 0 ? true : false;
+}
+
+static void sqlite_plug_destroy(void)
+{
+ if (!init_done)
+ return;
+
+ sqlite3_close_v2(db);
+}
+
+static bool get_fsidnum_by_path(char *path, uint32_t *fsidnum, bool *found)
+{
+ static const char fsidnum_by_path_sql[] = "SELECT num FROM fsidnums WHERE path = ?1;";
+ sqlite3_stmt *stmt = NULL;
+ bool success = false;
+ int ret;
+
+ *found = false;
+
+ ret = sqlite3_prepare_v2(db, fsidnum_by_path_sql, sizeof(fsidnum_by_path_sql), &stmt, NULL);
+ if (ret != SQLITE_OK) {
+ xlog(L_WARNING, "Unable to prepare SQL query '%s': %s", fsidnum_by_path_sql, sqlite3_errstr(ret));
+ goto out;
+ }
+
+ ret = sqlite3_bind_text(stmt, 1, path, -1, NULL);
+ if (ret != SQLITE_OK) {
+ xlog(L_WARNING, "Unable to bind SQL query '%s': %s", fsidnum_by_path_sql, sqlite3_errstr(ret));
+ goto out;
+ }
+
+again:
+ ret = sqlite3_step(stmt);
+ switch (ret) {
+ case SQLITE_ROW:
+ *fsidnum = sqlite3_column_int(stmt, 0);
+ success = true;
+ *found = true;
+ break;
+ case SQLITE_DONE:
+ /* No hit */
+ success = true;
+ *found = false;
+ break;
+ case SQLITE_BUSY:
+ case SQLITE_LOCKED:
+ wait_for_dbaccess();
+ goto again;
+ default:
+ xlog(L_WARNING, "Error while looking up '%s' in database: %s", path, sqlite3_errstr(ret));
+ }
+
+out:
+ sqlite3_finalize(stmt);
+ return success;
+}
+
+static bool sqlite_plug_path_by_fsidnum(uint32_t fsidnum, char **path, bool *found)
+{
+ static const char path_by_fsidnum_sql[] = "SELECT path FROM fsidnums WHERE num = ?1;";
+ sqlite3_stmt *stmt = NULL;
+ bool success = false;
+ int ret;
+
+ *found = false;
+
+ ret = sqlite3_prepare_v2(db, path_by_fsidnum_sql, sizeof(path_by_fsidnum_sql), &stmt, NULL);
+ if (ret != SQLITE_OK) {
+ xlog(L_WARNING, "Unable to prepare SQL query '%s': %s", path_by_fsidnum_sql, sqlite3_errstr(ret));
+ goto out;
+ }
+
+ ret = sqlite3_bind_int(stmt, 1, fsidnum);
+ if (ret != SQLITE_OK) {
+ xlog(L_WARNING, "Unable to bind SQL query '%s': %s", path_by_fsidnum_sql, sqlite3_errstr(ret));
+ goto out;
+ }
+
+again:
+ ret = sqlite3_step(stmt);
+ switch (ret) {
+ case SQLITE_ROW:
+ *path = strdup((char *)sqlite3_column_text(stmt, 0));
+ if (*path) {
+ *found = true;
+ success = true;
+ } else {
+ xlog(L_WARNING, "Out of memory");
+ }
+ break;
+ case SQLITE_DONE:
+ /* No hit */
+ *found = false;
+ success = true;
+ break;
+ case SQLITE_BUSY:
+ case SQLITE_LOCKED:
+ wait_for_dbaccess();
+ goto again;
+ default:
+ xlog(L_WARNING, "Error while looking up '%i' in database: %s", fsidnum, sqlite3_errstr(ret));
+ }
+
+out:
+ sqlite3_finalize(stmt);
+ return success;
+}
+
+static bool new_fsidnum_by_path(char *path, uint32_t *fsidnum)
+{
+ /*
+ * This query is a little tricky. We use SQL to find and claim the smallest free fsid number.
+ * To find a free fsid the fsidnums is left joined to itself but with an offset of 1.
+ * Everything after the UNION statement is to handle the corner case where fsidnums
+ * is empty. In this case we want 1 as first fsid number.
+ */
+ static const char new_fsidnum_by_path_sql[] = "INSERT INTO fsidnums VALUES ((SELECT ids1.num + 1 FROM fsidnums AS ids1 LEFT JOIN fsidnums AS ids2 ON ids2.num = ids1.num + 1 WHERE ids2.num IS NULL UNION SELECT 1 WHERE NOT EXISTS (SELECT NULL FROM fsidnums WHERE num = 1) LIMIT 1), ?1) RETURNING num;";
+
+ sqlite3_stmt *stmt = NULL;
+ int ret, check = 0;
+ bool success = false;
|
[-]
[+]
|
Added |
_service:tar_git:nfs-utils-2.6.3+git2.tar.bz2/upstream/support/reexport/fsidd.c
^
|
@@ -0,0 +1,198 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <assert.h>
+#include <dlfcn.h>
+#include <event2/event.h>
+#include <limits.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <sys/random.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/un.h>
+#include <sys/vfs.h>
+#include <unistd.h>
+
+#include "conffile.h"
+#include "reexport_backend.h"
+#include "xcommon.h"
+#include "xlog.h"
+
+#define FSID_SOCKET_NAME "fsid.sock"
+
+static struct event_base *evbase;
+static struct reexpdb_backend_plugin *dbbackend = &sqlite_plug_ops;
+
+static void client_cb(evutil_socket_t cl, short ev, void *d)
+{
+ struct event *me = d;
+ char buf[PATH_MAX * 2];
+ int n;
+
+ (void)ev;
+
+ n = recv(cl, buf, sizeof(buf) - 1, 0);
+ if (n <= 0) {
+ event_del(me);
+ event_free(me);
+ close(cl);
+ return;
+ }
+
+ buf[n] = '\0';
+
+ if (strncmp(buf, "get_fsidnum ", strlen("get_fsidnum ")) == 0) {
+ char *req_path = buf + strlen("get_fsidnum ");
+ uint32_t fsidnum;
+ char *answer = NULL;
+ bool found;
+
+ assert(req_path < buf + n );
+
+ printf("client asks for %s\n", req_path);
+
+ if (dbbackend->fsidnum_by_path(req_path, &fsidnum, false, &found)) {
+ if (found)
+ assert(asprintf(&answer, "+ %u", fsidnum) != -1);
+ else
+ assert(asprintf(&answer, "+ ") != -1);
+
+ } else {
+ assert(asprintf(&answer, "- %s", "Command failed") != -1);
+ }
+
+ (void)send(cl, answer, strlen(answer), 0);
+
+ free(answer);
+ } else if (strncmp(buf, "get_or_create_fsidnum ", strlen("get_or_create_fsidnum ")) == 0) {
+ char *req_path = buf + strlen("get_or_create_fsidnum ");
+ uint32_t fsidnum;
+ char *answer = NULL;
+ bool found;
+
+ assert(req_path < buf + n );
+
+
+ if (dbbackend->fsidnum_by_path(req_path, &fsidnum, true, &found)) {
+ if (found) {
+ assert(asprintf(&answer, "+ %u", fsidnum) != -1);
+ } else {
+ assert(asprintf(&answer, "+ ") != -1);
+ }
+
+ } else {
+ assert(asprintf(&answer, "- %s", "Command failed") != -1);
+ }
+
+ (void)send(cl, answer, strlen(answer), 0);
+
+ free(answer);
+ } else if (strncmp(buf, "get_path ", strlen("get_path ")) == 0) {
+ char *req_fsidnum = buf + strlen("get_path ");
+ char *path = NULL, *answer = NULL, *endp;
+ bool bad_input = true;
+ uint32_t fsidnum;
+ bool found;
+
+ assert(req_fsidnum < buf + n );
+
+ errno = 0;
+ fsidnum = strtoul(req_fsidnum, &endp, 10);
+ if (errno == 0 && *endp == '\0') {
+ bad_input = false;
+ }
+
+ if (bad_input) {
+ assert(asprintf(&answer, "- %s", "Command failed: Bad input") != -1);
+ } else {
+ if (dbbackend->path_by_fsidnum(fsidnum, &path, &found)) {
+ if (found)
+ assert(asprintf(&answer, "+ %s", path) != -1);
+ else
+ assert(asprintf(&answer, "+ ") != -1);
+ } else {
+ assert(asprintf(&answer, "+ ") != -1);
+ }
+ }
+
+ (void)send(cl, answer, strlen(answer), 0);
+
+ free(path);
+ free(answer);
+ } else if (strcmp(buf, "version") == 0) {
+ char answer[] = "+ 1";
+
+ (void)send(cl, answer, strlen(answer), 0);
+ } else {
+ char *answer = NULL;
+
+ assert(asprintf(&answer, "- bad command") != -1);
+ (void)send(cl, answer, strlen(answer), 0);
+
+ free(answer);
+ }
+}
+
+static void srv_cb(evutil_socket_t fd, short ev, void *d)
+{
+ int cl = accept4(fd, NULL, NULL, SOCK_NONBLOCK);
+ struct event *client_ev;
+
+ (void)ev;
+ (void)d;
+
+ client_ev = event_new(evbase, cl, EV_READ | EV_PERSIST | EV_CLOSED, client_cb, event_self_cbarg());
+ event_add(client_ev, NULL);
+}
+
+int main(void)
+{
+ struct event *srv_ev;
+ struct sockaddr_un addr;
+ char *sock_file;
+ int srv;
+
+ conf_init_file(NFS_CONFFILE);
+
+ if (!dbbackend->initdb()) {
+ return 1;
+ }
+
+ sock_file = conf_get_str_with_def("reexport", "fsidd_socket", FSID_SOCKET_NAME);
+
+ unlink(sock_file);
+
+ memset(&addr, 0, sizeof(struct sockaddr_un));
+ addr.sun_family = AF_UNIX;
+ strncpy(addr.sun_path, sock_file, sizeof(addr.sun_path) - 1);
+
+ srv = socket(AF_UNIX, SOCK_SEQPACKET | SOCK_NONBLOCK, 0);
+ if (srv == -1) {
+ xlog(L_WARNING, "Unable to create AF_UNIX socket for %s: %m\n", sock_file);
+ return 1;
+ }
+
+ if (bind(srv, (const struct sockaddr *)&addr, sizeof(struct sockaddr_un)) == -1) {
+ xlog(L_WARNING, "Unable to bind %s: %m\n", sock_file);
+ return 1;
+ }
+
+ if (listen(srv, 5) == -1) {
+ xlog(L_WARNING, "Unable to listen on %s: %m\n", sock_file);
+ return 1;
+ }
+
+ evbase = event_base_new();
+
+ srv_ev = event_new(evbase, srv, EV_READ | EV_PERSIST, srv_cb, NULL);
+ event_add(srv_ev, NULL);
+
+ event_base_dispatch(evbase);
+
+ dbbackend->destroydb();
+
+ return 0;
+}
|
[-]
[+]
|
Added |
_service:tar_git:nfs-utils-2.6.3+git2.tar.bz2/upstream/support/reexport/reexport.c
^
|
@@ -0,0 +1,326 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <dlfcn.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <sys/random.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/vfs.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+
+#include "nfsd_path.h"
+#include "conffile.h"
+#include "nfslib.h"
+#include "reexport.h"
+#include "xcommon.h"
+#include "xlog.h"
+
+static int fsidd_srv = -1;
+
+static bool connect_fsid_service(void)
+{
+ struct sockaddr_un addr;
+ char *sock_file;
+ int ret;
+ int s;
+
+ if (fsidd_srv != -1)
+ return true;
+
+ sock_file = conf_get_str_with_def("reexport", "fsidd_socket", FSID_SOCKET_NAME);
+
+ memset(&addr, 0, sizeof(struct sockaddr_un));
+ addr.sun_family = AF_UNIX;
+ strncpy(addr.sun_path, sock_file, sizeof(addr.sun_path) - 1);
+
+ s = socket(AF_UNIX, SOCK_SEQPACKET, 0);
+ if (s == -1) {
+ xlog(L_WARNING, "Unable to create AF_UNIX socket for %s: %m\n", sock_file);
+ return false;
+ }
+
+ ret = connect(s, (const struct sockaddr *)&addr, sizeof(struct sockaddr_un));
+ if (ret == -1) {
+ xlog(L_WARNING, "Unable to connect %s: %m, is fsidd running?\n", sock_file);
+ return false;
+ }
+
+ fsidd_srv = s;
+
+ return true;
+}
+
+int reexpdb_init(void)
+{
+ int try_count = 3;
+
+ while (try_count > 0 && !connect_fsid_service()) {
+ sleep(1);
+ try_count--;
+ }
+
+ return try_count > 0;
+}
+
+void reexpdb_destroy(void)
+{
+ close(fsidd_srv);
+ fsidd_srv = -1;
+}
+
+static bool parse_fsidd_reply(const char *cmd_info, char *buf, size_t len, char **result)
+{
+ if (len == 0) {
+ xlog(L_WARNING, "Unable to read %s result: server closed the connection", cmd_info);
+ return false;
+ } else if (len < 2) {
+ xlog(L_WARNING, "Unable to read %s result: server sent too few bytes", cmd_info);
+ return false;
+ }
+
+ if (buf[0] == '-') {
+ if (len > 2) {
+ char *reason = buf + 2;
+ xlog(L_WARNING, "Command %s failed, server said: %s", cmd_info, reason);
+ } else {
+ xlog(L_WARNING, "Command %s failed at server side", cmd_info);
+ }
+
+ return false;
+ }
+
+ if (buf[0] != '+') {
+ xlog(L_WARNING, "Unable to read %s result: server sent malformed answer", cmd_info);
+ return false;
+ }
+
+ if (len > 2) {
+ *result = strdup(buf + 2);
+ } else {
+ *result = NULL;
+ }
+
+ return true;
+}
+
+static bool do_fsidd_cmd(const char *cmd_info, char *msg, size_t len, char **result)
+{
+ char recvbuf[1024];
+ int n;
+
+ if (fsidd_srv == -1) {
+ xlog(L_NOTICE, "Reconnecting to fsid services");
+ if (reexpdb_init() == false)
+ return false;
+ }
+
+ xlog(D_GENERAL, "Request to fsidd: msg=\"%s\" len=%zd", msg, len);
+
+ if (write(fsidd_srv, msg, len) == -1) {
+ xlog(L_WARNING, "Unable to send %s command: %m", cmd_info);
+ goto out_close;
+ }
+
+ n = read(fsidd_srv, recvbuf, sizeof(recvbuf) - 1);
+ if (n <= -1) {
+ xlog(L_WARNING, "Unable to recv %s answer: %m", cmd_info);
+ goto out_close;
+ } else if (n == sizeof(recvbuf) - 1) {
+ //TODO: use better way to detect truncation
+ xlog(L_WARNING, "Unable to recv %s answer: answer truncated", cmd_info);
+ goto out_close;
+ }
+ recvbuf[n] = '\0';
+
+ xlog(D_GENERAL, "Answer from fsidd: msg=\"%s\" len=%i", recvbuf, n);
+
+ if (parse_fsidd_reply(cmd_info, recvbuf, n, result) == false) {
+ goto out_close;
+ }
+
+ return true;
+
+out_close:
+ close(fsidd_srv);
+ fsidd_srv = -1;
+ return false;
+}
+
+static bool fsidnum_get_by_path(char *path, uint32_t *fsidnum, bool may_create)
+{
+ char *msg, *result;
+ bool ret = false;
+ int len;
+
+ char *cmd = may_create ? "get_or_create_fsidnum" : "get_fsidnum";
+
+ len = asprintf(&msg, "%s %s", cmd, path);
+ if (len == -1) {
+ xlog(L_WARNING, "Unable to build %s command: %m", cmd);
+ goto out;
+ }
+
+ if (do_fsidd_cmd(cmd, msg, len, &result) == false) {
+ goto out;
+ }
+
+ if (result) {
+ bool bad_input = true;
+ char *endp;
+
+ errno = 0;
+ *fsidnum = strtoul(result, &endp, 10);
+ if (errno == 0 && *endp == '\0') {
+ bad_input = false;
+ }
+
+ free(result);
+
+ if (!bad_input) {
+ ret = true;
+ } else {
+ xlog(L_NOTICE, "Got malformed fsid for path %s", path);
+ }
+ } else {
+ xlog(L_NOTICE, "No fsid found for path %s", path);
+ }
+
+out:
+ free(msg);
+ return ret;
+}
+
+static bool path_by_fsidnum(uint32_t fsidnum, char **path)
|
[-]
[+]
|
Added |
_service:tar_git:nfs-utils-2.6.3+git2.tar.bz2/upstream/support/reexport/reexport.h
^
|
@@ -0,0 +1,18 @@
+#ifndef REEXPORT_H
+#define REEXPORT_H
+
+enum {
+ REEXP_NONE = 0,
+ REEXP_AUTO_FSIDNUM,
+ REEXP_PREDEFINED_FSIDNUM,
+};
+
+int reexpdb_init(void);
+void reexpdb_destroy(void);
+int reexpdb_fsidnum_by_path(char *path, uint32_t *fsidnum, int may_create);
+int reexpdb_apply_reexport_settings(struct exportent *ep, char *flname, int flline);
+void reexpdb_uncover_subvolume(uint32_t fsidnum);
+
+#define FSID_SOCKET_NAME "fsid.sock"
+
+#endif /* REEXPORT_H */
|
[-]
[+]
|
Added |
_service:tar_git:nfs-utils-2.6.3+git2.tar.bz2/upstream/support/reexport/reexport_backend.h
^
|
@@ -0,0 +1,47 @@
+#ifndef REEXPORT_BACKEND_H
+#define REEXPORT_BACKEND_H
+
+extern struct reexpdb_backend_plugin sqlite_plug_ops;
+
+struct reexpdb_backend_plugin {
+ /*
+ * Find or allocate a fsidnum for a given path.
+ *
+ * @path: Path to look for
+ * @fsidnum: Pointer to an uint32_t variable
+ * @may_create: If non-zero, a fsidnum will be allocated if none was found
+ *
+ * Returns true if either an fsidnum was found or successfully allocated,
+ * false otherwise.
+ * On success, the fsidnum will be stored into @fsidnum.
+ * Upon errors, false is returned and errors are logged.
+ */
+ bool (*fsidnum_by_path)(char *path, uint32_t *fsidnum, int may_create, bool *found);
+
+ /*
+ * Lookup path by a given fsidnum
+ *
+ * @fsidnum: fsidnum to look for
+ * @path: address of a char pointer
+ *
+ * Returns true if a path was found, false otherwise.
+ * Upon errors, false is returned and errors are logged.
+ * In case of success, the function returns the found path
+ * via @path, @path will point to a freshly allocated buffer
+ * which is free()'able.
+ */
+ bool (*path_by_fsidnum)(uint32_t fsidnum, char **path, bool *found);
+
+ /*
+ * Init database connection, can get called multiple times.
+ * Returns true on success, false otherwise.
+ */
+ bool (*initdb)(void);
+
+ /*
+ * Undoes initdb().
+ */
+ void (*destroydb)(void);
+};
+
+#endif /* REEXPORT_BACKEND_H */
|
[-]
[+]
|
Added |
_service:tar_git:nfs-utils-2.6.3+git2.tar.bz2/upstream/systemd/60-nfs.rules
^
|
@@ -0,0 +1,21 @@
+# Ensure all NFS systctl settings get applied when modules load
+
+# sunrpc module supports "sunrpc.*" sysctls
+ACTION=="add", SUBSYSTEM=="module", KERNEL=="sunrpc", \
+ RUN+="/sbin/sysctl -q --pattern ^sunrpc --system"
+
+# rpcrdma module supports sunrpc.svc_rdma.*
+ACTION=="add", SUBSYSTEM=="module", KERNEL=="rpcrdma", \
+ RUN+="/sbin/sysctl -q --pattern ^sunrpc.svc_rdma --system"
+
+# lockd module supports "fs.nfs.nlm*" and "fs.nfs.nsm*" sysctls
+ACTION=="add", SUBSYSTEM=="module", KERNEL=="lockd", \
+ RUN+="/sbin/sysctl -q --pattern ^fs.nfs.n[sl]m --system"
+
+# nfsv4 module supports "fs.nfs.*" sysctls (nfs_callback_tcpport and idmap_cache_timeout)
+ACTION=="add", SUBSYSTEM=="module", KERNEL=="nfsv4", \
+ RUN+="/sbin/sysctl -q --pattern ^fs.nfs.(nfs_callback_tcpport|idmap_cache_timeout) --system"
+
+# nfs module supports "fs.nfs.*" sysctls
+ACTION=="add", SUBSYSTEM=="module", KERNEL=="nfs", \
+ RUN+="/sbin/sysctl -q --pattern ^fs.nfs --system"
|
[-]
[+]
|
Changed |
_service:tar_git:nfs-utils-2.6.3+git2.tar.bz2/upstream/systemd/Makefile.am
^
|
@@ -2,7 +2,8 @@
MAINTAINERCLEANFILES = Makefile.in
-modprobe_files = 50-nfs.conf
+udev_rulesdir = /usr/lib/udev/rules.d/
+udev_files = 60-nfs.rules
unit_files = \
nfs-client.target \
@@ -14,7 +15,8 @@
rpc-statd-notify.service \
rpc-statd.service \
\
- proc-fs-nfsd.mount
+ proc-fs-nfsd.mount \
+ fsidd.service
rpc_pipefs_mount_file = \
var-lib-nfs-rpc_pipefs.mount
@@ -53,7 +55,7 @@
man5_MANS = nfs.conf.man
man7_MANS = nfs.systemd.man
-EXTRA_DIST = $(unit_files) $(modprobe_files) $(man5_MANS) $(man7_MANS)
+EXTRA_DIST = $(unit_files) $(udev_files) $(man5_MANS) $(man7_MANS)
generator_dir = $(unitdir)/../system-generators
@@ -69,20 +71,18 @@
nfs_server_generator_LDADD = ../support/export/libexport.a \
../support/nfs/libnfs.la \
../support/misc/libmisc.a \
+ ../support/reexport/libreexport.a \
$(LIBPTHREAD)
+
rpc_pipefs_generator_LDADD = ../support/nfs/libnfs.la
if INSTALL_SYSTEMD
genexec_PROGRAMS = nfs-server-generator rpc-pipefs-generator
-install-data-hook: $(unit_files) $(modprobe_files)
+install-data-hook: $(unit_files) $(udev_files)
mkdir -p $(DESTDIR)/$(unitdir)
cp $(unit_files) $(DESTDIR)/$(unitdir)
cp $(rpc_pipefs_mount_file) $(DESTDIR)/$(unitdir)/$(rpc_pipefsmount)
-else
-install-data-hook: $(modprobe_files)
-endif
-if INSTALL_MODPROBEDIR
- mkdir -p $(DESTDIR)$(modprobedir)
- cp $(modprobe_files) $(DESTDIR)$(modprobedir)
+ mkdir -p $(DESTDIR)/$(udev_rulesdir)
+ cp $(udev_files) $(DESTDIR)/$(udev_rulesdir)
endif
|
[-]
[+]
|
Changed |
_service:tar_git:nfs-utils-2.6.3+git2.tar.bz2/upstream/systemd/auth-rpcgss-module.service
^
|
@@ -8,8 +8,9 @@
Description=Kernel Module supporting RPCSEC_GSS
DefaultDependencies=no
Before=gssproxy.service rpc-svcgssd.service rpc-gssd.service
-Wants=gssproxy.service rpc-svcgssd.service rpc-gssd.service
+Wants=gssproxy.service rpc-gssd.service
ConditionPathExists=/etc/krb5.keytab
+ConditionVirtualization=!container
[Service]
Type=oneshot
|
[-]
[+]
|
Added |
_service:tar_git:nfs-utils-2.6.3+git2.tar.bz2/upstream/systemd/fsidd.service
^
|
@@ -0,0 +1,10 @@
+[Unit]
+Description=NFS FSID Daemon
+After=local-fs.target
+Before=nfs-mountd.service nfs-server.service
+
+[Service]
+ExecStart=/usr/sbin/fsidd
+
+[Install]
+RequiredBy=nfs-mountd.service nfs-server.service
|
[-]
[+]
|
Changed |
_service:tar_git:nfs-utils-2.6.3+git2.tar.bz2/upstream/systemd/nfs-server.service
^
|
@@ -15,7 +15,7 @@
Before=rpc-statd-notify.service
# GSS services dependencies and ordering
-Wants=auth-rpcgss-module.service
+Wants=auth-rpcgss-module.service rpc-svcgssd.service
After=rpc-gssd.service gssproxy.service rpc-svcgssd.service
[Service]
|
[-]
[+]
|
Changed |
_service:tar_git:nfs-utils-2.6.3+git2.tar.bz2/upstream/systemd/nfs.conf.man
^
|
@@ -98,6 +98,12 @@
.BR parse ,
.BR all .
When a list is given, the members should be comma-separated.
+The values
+.BR 0
+and
+.BR 1
+are also accepted, with '0' making no changes to the debug level, and '1' equivalent to specifying 'all'.
+
.TP
.B general
Recognized values:
@@ -166,6 +172,7 @@
Recognized values:
.BR threads ,
.BR host ,
+.BR scope ,
.BR port ,
.BR grace-time ,
.BR lease-time ,
|
[-]
[+]
|
Changed |
_service:tar_git:nfs-utils-2.6.3+git2.tar.bz2/upstream/tools/Makefile.am
^
|
@@ -12,6 +12,10 @@
OPTDIRS += nfsdclddb
endif
-SUBDIRS = locktest rpcdebug nlmtest mountstats nfs-iostat rpcctl nfsdclnts nfsrahead $(OPTDIRS)
+if CONFIG_NFSRAHEAD
+OPTDIRS += nfsrahead
+endif
+
+SUBDIRS = locktest rpcdebug nlmtest mountstats nfs-iostat rpcctl nfsdclnts $(OPTDIRS)
MAINTAINERCLEANFILES = Makefile.in
|
[-]
[+]
|
Changed |
_service:tar_git:nfs-utils-2.6.3+git2.tar.bz2/upstream/tools/nfs-iostat/nfs-iostat.py
^
|
@@ -43,7 +43,7 @@
'vfspermission',
'vfsupdatepage',
'vfsreadpage',
- 'vfsreadpages',
+ 'vfsreadpages', # or vfsreadahead in statvers=1.2 or above
'vfswritepage',
'vfswritepages',
'vfsreaddir',
@@ -86,14 +86,14 @@
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]
+ if words[7] == 'nfs' or words[7] == 'nfs4':
+ self.__nfs_data['statvers'] = float(words[8].split('=',1)[1])
elif 'nfs' in words or 'nfs4' in words:
self.__nfs_data['export'] = words[0]
self.__nfs_data['mountpoint'] = words[3]
self.__nfs_data['fstype'] = words[6]
if words[6] == 'nfs':
- self.__nfs_data['statvers'] = words[7]
+ self.__nfs_data['statvers'] = float(words[7].split('=',1)[1])
elif words[0] == 'age:':
self.__nfs_data['age'] = int(words[1])
elif words[0] == 'opts:':
@@ -294,8 +294,11 @@
print()
print('%d nfs_readpage() calls read %d pages' % \
(vfsreadpage, vfsreadpage))
- print('%d nfs_readpages() calls read %d pages' % \
- (vfsreadpages, pages_read - vfsreadpage))
+ multipageread = "readpages"
+ if self.__nfs_data['statvers'] >= 1.2:
+ multipageread = "readahead"
+ print('%d nfs_%s() calls read %d pages' % \
+ (vfsreadpages, multipageread, pages_read - vfsreadpage))
if vfsreadpages != 0:
print('(%.1f pages per call)' % \
(float(pages_read - vfsreadpage) / vfsreadpages))
|
[-]
[+]
|
Changed |
_service:tar_git:nfs-utils-2.6.3+git2.tar.bz2/upstream/tools/nfsrahead/Makefile.am
^
|
@@ -1,6 +1,6 @@
libexec_PROGRAMS = nfsrahead
nfsrahead_SOURCES = main.c
-nfsrahead_LDFLAGS= -lmount
+nfsrahead_LDFLAGS= $(LIBMOUNT_LIBS)
nfsrahead_LDADD = ../../support/nfs/libnfsconf.la
man5_MANS = nfsrahead.man
|
[-]
[+]
|
Changed |
_service:tar_git:nfs-utils-2.6.3+git2.tar.bz2/upstream/tools/nfsrahead/main.c
^
|
@@ -167,7 +167,7 @@
if ((ret = get_device_info(argv[optind], &device)) == 0)
break;
- if (ret != 0) {
+ if (ret != 0 || device.fstype == NULL) {
xlog(D_GENERAL, "unable to find device %s\n", argv[optind]);
goto out;
}
|
[-]
[+]
|
Changed |
_service:tar_git:nfs-utils-2.6.3+git2.tar.bz2/upstream/tools/rpcdebug/rpcdebug.c
^
|
@@ -257,7 +257,7 @@
perror(filename);
exit(1);
}
- if ((len = read(sysfd, buffer, sizeof(buffer))) < 0) {
+ if ((len = read(sysfd, buffer, sizeof(buffer))) <= 0) {
perror("read");
exit(1);
}
|
[-]
[+]
|
Changed |
_service:tar_git:nfs-utils-2.6.3+git2.tar.bz2/upstream/utils/blkmapd/device-discovery.c
^
|
@@ -187,10 +187,7 @@
}
if (disk && diskpath) {
- if (serial) {
- free(serial->data);
- free(serial);
- }
+ bl_free_scsi_string(serial);
return;
}
@@ -228,10 +225,7 @@
disk->size = size;
disk->valid_path = path;
}
- if (serial) {
- free(serial->data);
- free(serial);
- }
+ bl_free_scsi_string(serial);
}
return;
@@ -241,10 +235,7 @@
free(path->full_path);
free(path);
}
- if (serial) {
- free(serial->data);
- free(serial);
- }
+ bl_free_scsi_string(serial);
return;
}
@@ -462,7 +453,7 @@
unlink(PID_FILE);
}
BL_LOG_ERR("exit on signal(%d)\n", signal);
- exit(1);
+ exit(0);
}
static void usage(void)
{
@@ -507,28 +498,44 @@
if (fg) {
openlog("blkmapd", LOG_PERROR, 0);
} else {
- if (daemon(0, 0) != 0) {
- fprintf(stderr, "Daemonize failed\n");
+ pid_t pid = fork();
+ if (pid < 0) {
+ BL_LOG_ERR("fork error\n");
exit(1);
- }
+ } else if (pid != 0) {
+ pidfd = open(PID_FILE, O_WRONLY | O_CREAT, 0644);
+ if (pidfd < 0) {
+ BL_LOG_ERR("Create pid file %s failed\n", PID_FILE);
+ exit(1);
+ }
- openlog("blkmapd", LOG_PID, 0);
- pidfd = open(PID_FILE, O_WRONLY | O_CREAT, 0644);
- if (pidfd < 0) {
- BL_LOG_ERR("Create pid file %s failed\n", PID_FILE);
- exit(1);
+ if (lockf(pidfd, F_TLOCK, 0) < 0) {
+ BL_LOG_ERR("Already running; Exiting!");
+ close(pidfd);
+ exit(1);
+ }
+ if (ftruncate(pidfd, 0) < 0)
+ BL_LOG_ERR("ftruncate on %s failed: m\n", PID_FILE);
+ sprintf(pidbuf, "%d\n", pid);
+ if (write(pidfd, pidbuf, strlen(pidbuf)) != (ssize_t)strlen(pidbuf))
+ BL_LOG_ERR("write on %s failed: m\n", PID_FILE);
+ exit(0);
}
- if (lockf(pidfd, F_TLOCK, 0) < 0) {
- BL_LOG_ERR("Already running; Exiting!");
- close(pidfd);
- exit(1);
+ (void)setsid();
+ if (chdir("/")) {
+ BL_LOG_ERR("chdir error\n");
+ }
+ int fd = open("/dev/null", O_RDWR, 0);
+ if (fd >= 0) {
+ (void)dup2(fd, STDIN_FILENO);
+ (void)dup2(fd, STDOUT_FILENO);
+ (void)dup2(fd, STDERR_FILENO);
+
+ (void)close(fd);
}
- if (ftruncate(pidfd, 0) < 0)
- BL_LOG_WARNING("ftruncate on %s failed: m\n", PID_FILE);
- sprintf(pidbuf, "%d\n", getpid());
- if (write(pidfd, pidbuf, strlen(pidbuf)) != (ssize_t)strlen(pidbuf))
- BL_LOG_WARNING("write on %s failed: m\n", PID_FILE);
+
+ openlog("blkmapd", LOG_PID, 0);
}
signal(SIGINT, sig_die);
|
[-]
[+]
|
Changed |
_service:tar_git:nfs-utils-2.6.3+git2.tar.bz2/upstream/utils/blkmapd/device-discovery.h
^
|
@@ -151,6 +151,8 @@
extern ssize_t atomicio(ssize_t(*f) (int, void *, size_t),
int fd, void *_s, size_t n);
+extern struct bl_serial *bl_create_scsi_string(int len, const char *bytes);
+extern void bl_free_scsi_string(struct bl_serial *str);
extern struct bl_serial *bldev_read_serial(int fd, const char *filename);
extern enum bl_path_state_e bldev_read_ap_state(int fd);
extern int bl_discover_devices(void);
|
[-]
[+]
|
Changed |
_service:tar_git:nfs-utils-2.6.3+git2.tar.bz2/upstream/utils/blkmapd/device-inq.c
^
|
@@ -53,7 +53,7 @@
#define DEF_ALLOC_LEN 255
#define MX_ALLOC_LEN (0xc000 + 0x80)
-static struct bl_serial *bl_create_scsi_string(int len, const char *bytes)
+struct bl_serial *bl_create_scsi_string(int len, const char *bytes)
{
struct bl_serial *s;
@@ -66,7 +66,7 @@
return s;
}
-static void bl_free_scsi_string(struct bl_serial *str)
+void bl_free_scsi_string(struct bl_serial *str)
{
if (str)
free(str);
|
[-]
[+]
|
Changed |
_service:tar_git:nfs-utils-2.6.3+git2.tar.bz2/upstream/utils/exportd/Makefile.am
^
|
@@ -16,7 +16,9 @@
exportd_LDADD = ../../support/export/libexport.a \
../../support/nfs/libnfs.la \
../../support/misc/libmisc.a \
- $(OPTLIBS) $(LIBBLKID) $(LIBPTHREAD) -luuid
+ ../../support/reexport/libreexport.a \
+ $(OPTLIBS) $(LIBBLKID) $(LIBPTHREAD) \
+ -luuid
exportd_CPPFLAGS = $(AM_CPPFLAGS) $(CPPFLAGS) \
-I$(top_srcdir)/support/export
|
[-]
[+]
|
Changed |
_service:tar_git:nfs-utils-2.6.3+git2.tar.bz2/upstream/utils/exportfs/Makefile.am
^
|
@@ -10,6 +10,9 @@
exportfs_LDADD = ../../support/export/libexport.a \
../../support/nfs/libnfs.la \
../../support/misc/libmisc.a \
+ ../../support/reexport/libreexport.a \
$(LIBWRAP) $(LIBNSL) $(LIBPTHREAD)
+exportfs_CPPFLAGS = $(AM_CPPFLAGS) $(CPPFLAGS) -I$(top_srcdir)/support/reexport
+
MAINTAINERCLEANFILES = Makefile.in
|
[-]
[+]
|
Changed |
_service:tar_git:nfs-utils-2.6.3+git2.tar.bz2/upstream/utils/exportfs/exportfs.c
^
|
@@ -38,6 +38,7 @@
#include "exportfs.h"
#include "xlog.h"
#include "conffile.h"
+#include "reexport.h"
static void export_all(int verbose);
static void exportfs(char *arg, char *options, int verbose);
@@ -69,14 +70,14 @@
* need these additional lockfile() routines.
*/
static void
-grab_lockfile()
+grab_lockfile(void)
{
_lockfd = open(lockfile, O_CREAT|O_RDWR, 0666);
if (_lockfd != -1)
lockf(_lockfd, F_LOCK, 0);
}
static void
-release_lockfile()
+release_lockfile(void)
{
if (_lockfd != -1) {
lockf(_lockfd, F_ULOCK, 0);
@@ -513,7 +514,7 @@
*/
struct stat stb;
char *path = exportent_realpath(&exp->m_export);
- struct statfs64 stf;
+ struct statfs stf;
int fs_has_fsid = 0;
if (stat(path, &stb) < 0) {
@@ -528,7 +529,7 @@
if (!can_test())
return;
- if (!statfs64(path, &stf) &&
+ if (!statfs(path, &stf) &&
(stf.f_fsid.__val[0] || stf.f_fsid.__val[1]))
fs_has_fsid = 1;
@@ -719,6 +720,16 @@
c = dumpopt(c, "fsid=%d", ep->e_fsid);
if (ep->e_uuid)
c = dumpopt(c, "fsid=%s", ep->e_uuid);
+ if (ep->e_reexport) {
+ switch (ep->e_reexport) {
+ case REEXP_AUTO_FSIDNUM:
+ c = dumpopt(c, "reexport=%s", "auto-fsidnum");
+ break;
+ case REEXP_PREDEFINED_FSIDNUM:
+ c = dumpopt(c, "reexport=%s", "predefined-fsidnum");
+ break;
+ }
+ }
if (ep->e_mountpoint)
c = dumpopt(c, "mountpoint%s%s",
ep->e_mountpoint[0]?"=":"",
@@ -743,6 +754,7 @@
#endif
}
secinfo_show(stdout, ep);
+ xprtsecinfo_show(stdout, ep);
printf("%c\n", (c != '(')? ')' : ' ');
}
}
|
[-]
[+]
|
Changed |
_service:tar_git:nfs-utils-2.6.3+git2.tar.bz2/upstream/utils/exportfs/exports.man
^
|
@@ -125,7 +125,55 @@
will be enforced only for access using flavors listed in the immediately
preceding sec= option. The only options that are permitted to vary in
this way are ro, rw, no_root_squash, root_squash, and all_squash.
+.SS Transport layer security
+The Linux NFS server allows the use of RPC-with-TLS (RFC 9289) to
+protect RPC traffic between itself and its clients.
+Alternately, administrators can secure NFS traffic using a VPN,
+or an ssh tunnel or similar mechanism, in a way that is transparent
+to the server.
.PP
+To enable the use of RPC-with-TLS, the server's administrator must
+install and configure
+.BR tlshd
+to handle transport layer security handshake requests from the local
+kernel.
+Clients can then choose to use RPC-with-TLS or they may continue
+operating without it.
+.PP
+Administrators may require the use of RPC-with-TLS to protect access
+to individual exports.
+This is particularly useful when using non-cryptographic security
+flavors such as
+.IR sec=sys .
+The
+.I xprtsec=
+option, followed by an unordered colon-delimited list of security policies,
+can restrict access to the export to only clients that have negotiated
+transport-layer security.
+Currently supported transport layer security policies include:
+.TP
+.IR none
+The server permits clients to access the export
+without the use of transport layer security.
+.TP
+.IR tls
+The server permits clients that have negotiated an RPC-with-TLS session
+without peer authentication (confidentiality only) to access the export.
+Clients are not required to offer an x.509 certificate
+when establishing a transport layer security session.
+.TP
+.IR mtls
+The server permits clients that have negotiated an RPC-with-TLS session
+with peer authentication to access the export.
+The server requires clients to offer an x.509 certificate
+when establishing a transport layer security session.
+.PP
+If RPC-with-TLS is configured and enabled and the
+.I xprtsec=
+option is not specified, the default setting for an export is
+.IR xprtsec=none:tls:mtls .
+With this setting, the server permits clients to use any transport
+layer security mechanism or none at all to access the export.
.SS General Options
.BR exportfs
understands the following export options:
@@ -420,6 +468,37 @@
that early kernels did not support this export option, and instead
enabled security labels by default.
+.TP
+.IR reexport= auto-fsidnum|predefined-fsidnum
+This option helps when a NFS share is re-exported. Since the NFS server
+needs a unique identifier for each exported filesystem and a NFS share
+cannot provide such, usually a manual fsid is needed.
+As soon
+.IR crossmnt
+is used manually assigning fsid won't work anymore. This is where this
+option becomes handy. It will automatically assign a numerical fsid
+to exported NFS shares. The fsid and path relations are stored in a SQLite
+database. If
+.IR auto-fsidnum
+is selected, the fsid is also autmatically allocated.
+.IR predefined-fsidnum
+assumes pre-allocated fsid numbers and will just look them up.
+This option depends also on the kernel, you will need at least kernel version
+5.19.
+Since
+.IR reexport=
+can automatically allocate and assign numerical fsids, it is no longer possible
+to have numerical fsids in other exports as soon this option is used in at least
+one export entry.
+
+The association between fsid numbers and paths is stored in a SQLite database.
+Don't edit or remove the database unless you know exactly what you're doing.
+.IR predefined-fsidnum
+is useful when you have used
+.IR auto-fsidnum
+before and don't want further entries stored.
+
+
.SS User ID Mapping
.PP
.B nfsd
@@ -581,7 +660,8 @@
.BR netgroup (5),
.BR mountd (8),
.BR nfsd (8),
-.BR showmount (8).
+.BR showmount (8),
+.BR tlshd (8).
.\".SH DIAGNOSTICS
.\"An error parsing the file is reported using syslogd(8) as level NOTICE from
.\"a DAEMON whenever
|
[-]
[+]
|
Changed |
_service:tar_git:nfs-utils-2.6.3+git2.tar.bz2/upstream/utils/idmapd/idmapd.c
^
|
@@ -867,7 +867,7 @@
}
static void
-nfsdreopen()
+nfsdreopen(void)
{
nfsdreopen_one(&nfsd_ic[IC_NAMEID]);
nfsdreopen_one(&nfsd_ic[IC_IDNAME]);
|
[-]
[+]
|
Changed |
_service:tar_git:nfs-utils-2.6.3+git2.tar.bz2/upstream/utils/mount/Makefile.am
^
|
@@ -29,8 +29,9 @@
mount_nfs_LDADD = ../../support/nfs/libnfs.la \
../../support/export/libexport.a \
+ ../../support/reexport/libreexport.a \
../../support/misc/libmisc.a \
- $(LIBTIRPC)
+ $(LIBTIRPC) $(LIBPTHREAD)
mount_nfs_SOURCES = $(mount_common)
|
[-]
[+]
|
Changed |
_service:tar_git:nfs-utils-2.6.3+git2.tar.bz2/upstream/utils/mount/error.c
^
|
@@ -207,16 +207,17 @@
progname, spec);
break;
case EINVAL:
- nfs_error(_("%s: an incorrect mount option was specified"), progname);
+ nfs_error(_("%s: an incorrect mount option was specified for %s"),
+ progname, mount_point);
break;
case EOPNOTSUPP:
- nfs_error(_("%s: requested NFS version or transport protocol is not supported"),
- progname);
+ nfs_error(_("%s: requested NFS version or transport protocol is not supported for %s"),
+ progname, mount_point);
break;
case ENOTDIR:
if (spec)
- nfs_error(_("%s: mount spec %s or point %s is not a "
- "directory"), progname, spec, mount_point);
+ nfs_error(_("%s: mount spec %s or point %s is not a directory"),
+ progname, spec, mount_point);
else
nfs_error(_("%s: mount point %s is not a directory"),
progname, mount_point);
@@ -227,31 +228,31 @@
break;
case ENOENT:
if (spec)
- nfs_error(_("%s: mounting %s failed, "
- "reason given by server: %s"),
- progname, spec, strerror(error));
+ nfs_error(_("%s: mounting %s failed, reason given by server: %s"),
+ progname, spec, strerror(error));
else
nfs_error(_("%s: mount point %s does not exist"),
- progname, mount_point);
+ progname, mount_point);
break;
case ESPIPE:
rpc_mount_errors((char *)spec, 0, 0);
break;
case EIO:
- nfs_error(_("%s: mount system call failed"), progname);
+ nfs_error(_("%s: mount system call failed for %s"),
+ progname, mount_point);
break;
case EFAULT:
- nfs_error(_("%s: encountered unexpected error condition."),
- progname);
+ nfs_error(_("%s: encountered unexpected error condition for %s."),
+ progname, mount_point);
nfs_error(_("%s: please report the error to" PACKAGE_BUGREPORT),
- progname);
+ progname);
break;
case EALREADY:
/* Error message has already been provided */
break;
default:
- nfs_error(_("%s: %s"),
- progname, strerror(error));
+ nfs_error(_("%s: %s for %s on %s"),
+ progname, strerror(error), spec, mount_point);
}
}
|
[-]
[+]
|
Changed |
_service:tar_git:nfs-utils-2.6.3+git2.tar.bz2/upstream/utils/mount/network.c
^
|
@@ -179,7 +179,7 @@
static const unsigned int *nfs_default_proto(void);
#ifdef MOUNT_CONFIG
-static const unsigned int *nfs_default_proto()
+static const unsigned int *nfs_default_proto(void)
{
extern unsigned long config_default_proto;
/*
|
[-]
[+]
|
Changed |
_service:tar_git:nfs-utils-2.6.3+git2.tar.bz2/upstream/utils/mount/nfs.man
^
|
@@ -574,7 +574,39 @@
.B sloppy
option is an alternative to specifying
.BR mount.nfs " -s " option.
-
+.TP 1.5i
+.BI xprtsec= policy
+Specifies the use of transport layer security to protect NFS network
+traffic on behalf of this mount point.
+.I policy
+can be one of
+.BR none ,
+.BR tls ,
+or
+.BR mtls .
+.IP
+If
+.B none
+is specified,
+transport layer security is forced off, even if the NFS server supports
+transport layer security.
+If
+.B tls
+is specified, the client uses RPC-with-TLS to provide in-transit
+confidentiality.
+If
+.B mtls
+is specified, the client uses RPC-with-TLS to authenticate itself and
+to provide in-transit confidentiality.
+If the server does not support RPC-with-TLS or peer authentication
+fails, the mount attempt fails.
+.IP
+If the
+.B xprtsec=
+option is not specified,
+the default behavior depends on the kernel,
+but is usually equivalent to
+.BR "xprtsec=none" .
.SS "Options for NFS versions 2 and 3 only"
Use these options, along with the options in the above subsection,
for NFS versions 2 and 3 only.
|
[-]
[+]
|
Changed |
_service:tar_git:nfs-utils-2.6.3+git2.tar.bz2/upstream/utils/mount/nfsmount.conf
^
|
@@ -59,13 +59,13 @@
# acregmin=30
#
# The Maximum time (in seconds) file attributes are cached
-# acregmin=60
+# acregmax=60
#
# The minimum time (in seconds) directory attributes are cached
-# acregmin=30
+# acdirmin=30
#
# The Maximum time (in seconds) directory attributes are cached
-# acregmin=60
+# acdirmax=60
#
# Enable Access Control Lists
# Acl=False
|
[-]
[+]
|
Changed |
_service:tar_git:nfs-utils-2.6.3+git2.tar.bz2/upstream/utils/mount/parse_dev.c
^
|
@@ -170,7 +170,8 @@
if (pathname) {
*pathname = strndup(cbrace, path_len);
if (*pathname == NULL) {
- free(*hostname);
+ if (hostname)
+ free(*hostname);
return nfs_pdn_nomem_err();
}
}
|
[-]
[+]
|
Changed |
_service:tar_git:nfs-utils-2.6.3+git2.tar.bz2/upstream/utils/mountd/Makefile.am
^
|
@@ -17,9 +17,11 @@
mountd_LDADD = ../../support/export/libexport.a \
../../support/nfs/libnfs.la \
../../support/misc/libmisc.a \
+ ../../support/reexport/libreexport.a \
$(OPTLIBS) \
$(LIBBSD) $(LIBWRAP) $(LIBNSL) $(LIBBLKID) -luuid $(LIBTIRPC) \
$(LIBPTHREAD)
+
mountd_CPPFLAGS = $(AM_CPPFLAGS) $(CPPFLAGS) \
-I$(top_builddir)/support/include \
-I$(top_srcdir)/support/export
|
[-]
[+]
|
Changed |
_service:tar_git:nfs-utils-2.6.3+git2.tar.bz2/upstream/utils/nfsd/nfsd.c
^
|
@@ -23,6 +23,7 @@
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
+#include <sched.h>
#include "conffile.h"
#include "nfslib.h"
@@ -39,6 +40,7 @@
static struct option longopts[] =
{
{ "host", 1, 0, 'H' },
+ { "scope", 1, 0, 'S'},
{ "help", 0, 0, 'h' },
{ "no-nfs-version", 1, 0, 'N' },
{ "nfs-version", 1, 0, 'V' },
@@ -69,6 +71,7 @@
int count = NFSD_NPROC, c, i, error = 0, portnum, fd, found_one;
char *p, *progname, *port, *rdma_port = NULL;
char **haddr = NULL;
+ char *scope = NULL;
int hcounter = 0;
struct conf_list *hosts;
int socket_up = 0;
@@ -168,8 +171,9 @@
hcounter++;
}
}
+ scope = conf_get_str("nfsd", "scope");
- while ((c = getopt_long(argc, argv, "dH:hN:V:p:P:stTuUrG:L:", longopts, NULL)) != EOF) {
+ while ((c = getopt_long(argc, argv, "dH:S:hN:V:p:P:stTuUrG:L:", longopts, NULL)) != EOF) {
switch(c) {
case 'd':
xlog_config(D_ALL, 1);
@@ -190,6 +194,9 @@
haddr[hcounter] = optarg;
hcounter++;
break;
+ case 'S':
+ scope = optarg;
+ break;
case 'P': /* XXX for nfs-server compatibility */
case 'p':
/* only the last -p option has any effect */
@@ -367,6 +374,14 @@
if (lease > 0)
nfssvc_set_time("lease", lease);
+ if (scope) {
+ if (unshare(CLONE_NEWUTS) < 0 ||
+ sethostname(scope, strlen(scope)) < 0) {
+ xlog(L_ERROR, "Unable to set server scope: %m");
+ error = -1;
+ goto out;
+ }
+ }
i = 0;
do {
error = nfssvc_set_sockets(protobits, haddr[i], port);
|
[-]
[+]
|
Changed |
_service:tar_git:nfs-utils-2.6.3+git2.tar.bz2/upstream/utils/nfsd/nfsd.man
^
|
@@ -35,9 +35,17 @@
.B lockd
(which performs file locking services for NFS) may still accept
request on all known network addresses. This may change in future
-releases of the Linux Kernel. This option can be used multiple time
+releases of the Linux Kernel. This option can be used multiple times
to listen to more than one interface.
.TP
+.B \-S " or " \-\-scope scope
+NFSv4.1 and later require the server to report a "scope" which is used
+by the clients to detect if two connections are to the same server.
+By default Linux NFSD uses the host name as the scope.
+.sp
+It is particularly important for high-availablity configurations to ensure
+that all potential server nodes report the same server scope.
+.TP
.B \-p " or " \-\-port port
specify a different port to listen on for NFS requests. By default,
.B rpc.nfsd
@@ -134,6 +142,9 @@
.B --host
option replaces all host names listed here.
.TP
+.B scope
+Set the server scope.
+.TP
.B grace-time
The grace time, for both NFSv4 and NLM, in seconds.
.TP
@@ -159,7 +170,9 @@
.B vers3
.TP
.B vers4
-Enable or disable a major NFS version. 3 and 4 are normally enabled
+Enable or disable
+.B all
+NFSv4 versions. All versions are normally enabled
by default.
.TP
.B vers4.1
|
[-]
[+]
|
Changed |
_service:tar_git:nfs-utils.yaml
^
|
@@ -1,6 +1,6 @@
Name: nfs-utils
Summary: NFS client and server daemons
-Version: 2.6.2
+Version: 2.6.3
Release: 0
Group: System
License: GPLv2
@@ -15,14 +15,14 @@
Note that in order to use NFS, you need a kernel that supports it.
Some SailfishOS devices do, some do not. The Gemini for example does, the XPeria 10III does not.
- PackageName: NFS Utils
- PackagerName: nephros
+ Title: NFS Utils
+ PackagedBy: nephros
Categories:
- Network
- Filesystem
Custom:
PackagingRepo: https://github.com/sailfishos-chum/nfs-utils
- Url:
+ Links:
Help: https://wiki.linux-nfs.org/wiki/index.php/Nfsv4_configuration
Bugtracker: https://bugzilla.linux-nfs.org
%endif
@@ -55,6 +55,7 @@
- uuid
- mount
- systemd
+ - sqlite3
Files:
- '%{_sbindir}/*'
@@ -65,8 +66,8 @@
- '%{_unitdir}/*'
- '%{_systemdgeneratordir}/*'
- '%{_sharedstatedir}/nfs'
+ - '%{_prefix}/%{_udevrulesdir}/60-nfs.rules'
- '%{_udevrulesdir}/99-nfs.rules'
- - '%{_prefix}/lib/modprobe.d/50-nfs.conf'
- '%{_libexecdir}/nfsrahead'
SubPackages:
- Name: doc
|