summaryrefslogtreecommitdiffstats
path: root/contrib/netbsd-tests/fs
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/netbsd-tests/fs')
-rw-r--r--contrib/netbsd-tests/fs/common/fstest_lfs.c4
-rw-r--r--contrib/netbsd-tests/fs/common/h_fsmacros.h12
-rwxr-xr-xcontrib/netbsd-tests/fs/ffs/ffs_common.sh4
-rw-r--r--contrib/netbsd-tests/fs/fifofs/t_fifo.c3
-rw-r--r--contrib/netbsd-tests/fs/h_funcs.subr12
-rw-r--r--contrib/netbsd-tests/fs/nfs/nfsservice/mountd.c2575
-rw-r--r--contrib/netbsd-tests/fs/nfs/nfsservice/nfsd.c571
-rw-r--r--contrib/netbsd-tests/fs/nfs/nfsservice/rumpnfsd.c5
-rwxr-xr-xcontrib/netbsd-tests/fs/nfs/t_rquotad.sh4
-rwxr-xr-xcontrib/netbsd-tests/fs/psshfs/t_psshfs.sh23
-rw-r--r--contrib/netbsd-tests/fs/puffs/t_basic.c6
-rw-r--r--contrib/netbsd-tests/fs/tmpfs/h_funcs.subr19
-rw-r--r--contrib/netbsd-tests/fs/tmpfs/h_tools.c24
-rwxr-xr-xcontrib/netbsd-tests/fs/tmpfs/t_link.sh15
-rwxr-xr-xcontrib/netbsd-tests/fs/tmpfs/t_mknod.sh16
-rwxr-xr-xcontrib/netbsd-tests/fs/tmpfs/t_mount.sh16
-rwxr-xr-xcontrib/netbsd-tests/fs/tmpfs/t_readdir.sh8
-rwxr-xr-xcontrib/netbsd-tests/fs/tmpfs/t_remove.sh15
-rwxr-xr-xcontrib/netbsd-tests/fs/tmpfs/t_sizes.sh8
-rwxr-xr-xcontrib/netbsd-tests/fs/tmpfs/t_statvfs.sh8
-rwxr-xr-xcontrib/netbsd-tests/fs/tmpfs/t_vnd.sh33
-rwxr-xr-xcontrib/netbsd-tests/fs/tmpfs/t_vnode_leak.sh8
-rw-r--r--contrib/netbsd-tests/fs/vfs/t_io.c20
-rw-r--r--contrib/netbsd-tests/fs/vfs/t_renamerace.c4
-rw-r--r--contrib/netbsd-tests/fs/vfs/t_unpriv.c4
-rw-r--r--contrib/netbsd-tests/fs/vfs/t_vnops.c191
26 files changed, 371 insertions, 3237 deletions
diff --git a/contrib/netbsd-tests/fs/common/fstest_lfs.c b/contrib/netbsd-tests/fs/common/fstest_lfs.c
index fd131cf..597ca23 100644
--- a/contrib/netbsd-tests/fs/common/fstest_lfs.c
+++ b/contrib/netbsd-tests/fs/common/fstest_lfs.c
@@ -1,4 +1,4 @@
-/* $NetBSD: fstest_lfs.c,v 1.4 2010/07/30 16:15:05 pooka Exp $ */
+/* $NetBSD: fstest_lfs.c,v 1.5 2015/08/30 18:27:26 dholland Exp $ */
/*-
* Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -48,8 +48,6 @@
#include "h_fsmacros.h"
#include "mount_lfs.h"
-sem_t lfs_clearnerloop;
-
struct lfstestargs {
struct ufs_args ta_uargs;
pthread_t ta_cleanerthread;
diff --git a/contrib/netbsd-tests/fs/common/h_fsmacros.h b/contrib/netbsd-tests/fs/common/h_fsmacros.h
index b47a708..b295cf2 100644
--- a/contrib/netbsd-tests/fs/common/h_fsmacros.h
+++ b/contrib/netbsd-tests/fs/common/h_fsmacros.h
@@ -1,4 +1,4 @@
-/* $NetBSD: h_fsmacros.h,v 1.38 2013/06/26 19:29:24 reinoud Exp $ */
+/* $NetBSD: h_fsmacros.h,v 1.40 2015/08/29 19:19:43 dholland Exp $ */
/*-
* Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -110,10 +110,6 @@ do { \
atf_tc_set_md_var(tc, "descr", type " test for " desc); \
atf_tc_set_md_var(tc, "X-fs.type", #fs); \
atf_tc_set_md_var(tc, "X-fs.mntname", type); \
- if (strcmp(#fs, "zfs") == 0) { \
- /* This should not be necessary. */ \
- atf_tc_set_md_var(tc, "require.user", "root"); \
- } \
} \
void *fs##func##tmp; \
\
@@ -136,10 +132,6 @@ do { \
atf_tc_set_md_var(tc, "descr",_type_" test for "_desc_);\
atf_tc_set_md_var(tc, "X-fs.type", #_fs_); \
atf_tc_set_md_var(tc, "X-fs.mntname", _type_); \
- if (strcmp(#_fs_, "zfs") == 0) { \
- /* This should not be necessary. */ \
- atf_tc_set_md_var(tc, "require.user", "root"); \
- } \
} \
void *_fs_##_func_##tmp; \
\
@@ -153,7 +145,7 @@ do { \
atf_tc_fail_errno("unmount r/w failed"); \
if (_fs_##_fstest_mount(tc, _fs_##_func_##tmp, \
FSTEST_MNTNAME, MNT_RDONLY) != 0) \
- atf_tc_fail_errno("mount ro failed"); \
+ atf_tc_fail_errno("mount ro failed"); \
_func_(tc,FSTEST_MNTNAME); \
if (_fs_##_fstest_unmount(tc, FSTEST_MNTNAME, 0) != 0) {\
rump_pub_vfs_mount_print(FSTEST_MNTNAME, 1); \
diff --git a/contrib/netbsd-tests/fs/ffs/ffs_common.sh b/contrib/netbsd-tests/fs/ffs/ffs_common.sh
index eaf7142..ee94a15 100755
--- a/contrib/netbsd-tests/fs/ffs/ffs_common.sh
+++ b/contrib/netbsd-tests/fs/ffs/ffs_common.sh
@@ -1,4 +1,4 @@
-# $NetBSD: ffs_common.sh,v 1.2 2013/07/29 13:15:24 skrll Exp $
+# $NetBSD: ffs_common.sh,v 1.3 2016/10/08 13:23:53 gson Exp $
create_ffs()
{
@@ -45,7 +45,7 @@ test_case()
eval "${name}_head() { \
atf_set "descr" "${descr}"
- atf_set "timeout" "60"
+ atf_set "timeout" "120"
}"
eval "${name}_body() { \
RUMP_SOCKETS_LIST=\${RUMP_SOCKET}; \
diff --git a/contrib/netbsd-tests/fs/fifofs/t_fifo.c b/contrib/netbsd-tests/fs/fifofs/t_fifo.c
index c4a2060..4b37bb8 100644
--- a/contrib/netbsd-tests/fs/fifofs/t_fifo.c
+++ b/contrib/netbsd-tests/fs/fifofs/t_fifo.c
@@ -1,9 +1,10 @@
/* Test case written by Bharat Joshi */
#include <sys/cdefs.h>
-__RCSID("$NetBSD: t_fifo.c,v 1.1 2011/12/21 00:17:07 christos Exp $");
+__RCSID("$NetBSD: t_fifo.c,v 1.2 2017/01/10 22:36:29 christos Exp $");
#include <sys/types.h>
#include <sys/wait.h>
+#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
diff --git a/contrib/netbsd-tests/fs/h_funcs.subr b/contrib/netbsd-tests/fs/h_funcs.subr
index 1216aaf..21bdd97 100644
--- a/contrib/netbsd-tests/fs/h_funcs.subr
+++ b/contrib/netbsd-tests/fs/h_funcs.subr
@@ -45,6 +45,15 @@ require_fs() {
# if we have autoloadable modules, just assume the file system
atf_require_prog sysctl
+ # Begin FreeBSD
+ if true; then
+ if kldstat -m ${name}; then
+ found=yes
+ else
+ found=no
+ fi
+ else
+ # End FreeBSD
autoload=$(sysctl -n kern.module.autoload)
[ "${autoload}" = "1" ] && return 0
@@ -57,6 +66,9 @@ require_fs() {
fi
shift
done
+ # Begin FreeBSD
+ fi
+ # End FreeBSD
[ ${found} = yes ] || \
atf_skip "The kernel does not include support the " \
"\`${name}' file system"
diff --git a/contrib/netbsd-tests/fs/nfs/nfsservice/mountd.c b/contrib/netbsd-tests/fs/nfs/nfsservice/mountd.c
deleted file mode 100644
index b3625f6..0000000
--- a/contrib/netbsd-tests/fs/nfs/nfsservice/mountd.c
+++ /dev/null
@@ -1,2575 +0,0 @@
-/* $NetBSD: mountd.c,v 1.8 2013/10/19 17:45:00 christos Exp $ */
-
-/*
- * Copyright (c) 1989, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Herb Hasler and Rick Macklem at The University of Guelph.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <sys/cdefs.h>
-#ifndef lint
-__COPYRIGHT("@(#) Copyright (c) 1989, 1993\
- The Regents of the University of California. All rights reserved.");
-#endif /* not lint */
-
-#ifndef lint
-#if 0
-static char sccsid[] = "@(#)mountd.c 8.15 (Berkeley) 5/1/95";
-#else
-__RCSID("$NetBSD: mountd.c,v 1.8 2013/10/19 17:45:00 christos Exp $");
-#endif
-#endif /* not lint */
-
-#include <sys/param.h>
-#include <sys/file.h>
-#include <sys/ioctl.h>
-#include <sys/mount.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <syslog.h>
-#include <sys/ucred.h>
-
-#include <rpc/rpc.h>
-#include <rpc/pmap_clnt.h>
-#include <rpc/pmap_prot.h>
-#include <rpcsvc/mount.h>
-#include <nfs/rpcv2.h>
-#include <nfs/nfsproto.h>
-#include <nfs/nfs.h>
-#include <nfs/nfsmount.h>
-
-#include <arpa/inet.h>
-
-#include <rump/rump.h>
-#include <rump/rump_syscalls.h>
-
-#include <ctype.h>
-#include <errno.h>
-#include <grp.h>
-#include <netdb.h>
-#include <pwd.h>
-#include <netgroup.h>
-#include <pthread.h>
-#include <semaphore.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <err.h>
-#include <util.h>
-#include "pathnames.h"
-
-#ifdef IPSEC
-#include <netinet6/ipsec.h>
-#ifndef IPSEC_POLICY_IPSEC /* no ipsec support on old ipsec */
-#undef IPSEC
-#endif
-#include "ipsec.h"
-#endif
-
-#include "svc_fdset.h"
-
-#include <stdarg.h>
-
-/*
- * Structures for keeping the mount list and export list
- */
-struct mountlist {
- struct mountlist *ml_next;
- char ml_host[RPCMNT_NAMELEN + 1];
- char ml_dirp[RPCMNT_PATHLEN + 1];
- int ml_flag;/* XXX more flags (same as dp_flag) */
-};
-
-struct dirlist {
- struct dirlist *dp_left;
- struct dirlist *dp_right;
- int dp_flag;
- struct hostlist *dp_hosts; /* List of hosts this dir exported to */
- char dp_dirp[1]; /* Actually malloc'd to size of dir */
-};
-/* dp_flag bits */
-#define DP_DEFSET 0x1
-#define DP_HOSTSET 0x2
-#define DP_KERB 0x4
-#define DP_NORESMNT 0x8
-
-struct exportlist {
- struct exportlist *ex_next;
- struct dirlist *ex_dirl;
- struct dirlist *ex_defdir;
- int ex_flag;
- fsid_t ex_fs;
- char *ex_fsdir;
- char *ex_indexfile;
-};
-/* ex_flag bits */
-#define EX_LINKED 0x1
-
-struct netmsk {
- struct sockaddr_storage nt_net;
- int nt_len;
- char *nt_name;
-};
-
-union grouptypes {
- struct addrinfo *gt_addrinfo;
- struct netmsk gt_net;
-};
-
-struct grouplist {
- int gr_type;
- union grouptypes gr_ptr;
- struct grouplist *gr_next;
-};
-/* Group types */
-#define GT_NULL 0x0
-#define GT_HOST 0x1
-#define GT_NET 0x2
-
-struct hostlist {
- int ht_flag;/* Uses DP_xx bits */
- struct grouplist *ht_grp;
- struct hostlist *ht_next;
-};
-
-struct fhreturn {
- int fhr_flag;
- int fhr_vers;
- size_t fhr_fhsize;
- union {
- uint8_t v2[NFSX_V2FH];
- uint8_t v3[NFSX_V3FHMAX];
- } fhr_fh;
-};
-
-/* Global defs */
-static char *add_expdir __P((struct dirlist **, char *, int));
-static void add_dlist __P((struct dirlist **, struct dirlist *,
- struct grouplist *, int));
-static void add_mlist __P((char *, char *, int));
-static int check_dirpath __P((const char *, size_t, char *));
-static int check_options __P((const char *, size_t, struct dirlist *));
-static int chk_host __P((struct dirlist *, struct sockaddr *, int *, int *));
-static int del_mlist __P((char *, char *, struct sockaddr *));
-static struct dirlist *dirp_search __P((struct dirlist *, char *));
-static int do_nfssvc __P((const char *, size_t, struct exportlist *,
- struct grouplist *, int, struct uucred *, char *, int, struct statvfs *));
-static int do_opt __P((const char *, size_t, char **, char **,
- struct exportlist *, struct grouplist *, int *, int *, struct uucred *));
-static struct exportlist *ex_search __P((fsid_t *));
-static int parse_directory __P((const char *, size_t, struct grouplist *,
- int, char *, struct exportlist **, struct statvfs *));
-static int parse_host_netgroup __P((const char *, size_t, struct exportlist *,
- struct grouplist *, char *, int *, struct grouplist **));
-static struct exportlist *get_exp __P((void));
-static void free_dir __P((struct dirlist *));
-static void free_exp __P((struct exportlist *));
-static void free_grp __P((struct grouplist *));
-static void free_host __P((struct hostlist *));
-void get_exportlist __P((int));
-static int get_host __P((const char *, size_t, const char *,
- struct grouplist *));
-static struct hostlist *get_ht __P((void));
-static void get_mountlist __P((void));
-static int get_net __P((char *, struct netmsk *, int));
-static void free_exp_grp __P((struct exportlist *, struct grouplist *));
-static struct grouplist *get_grp __P((void));
-static void hang_dirp __P((struct dirlist *, struct grouplist *,
- struct exportlist *, int));
-static void mntsrv __P((struct svc_req *, SVCXPRT *));
-static void nextfield __P((char **, char **));
-static void parsecred __P((char *, struct uucred *));
-static int put_exlist __P((struct dirlist *, XDR *, struct dirlist *, int *));
-static int scan_tree __P((struct dirlist *, struct sockaddr *));
-static void send_umntall __P((int));
-#if 0
-static int umntall_each __P((caddr_t, struct sockaddr_in *));
-#endif
-static int xdr_dir __P((XDR *, char *));
-static int xdr_explist __P((XDR *, caddr_t));
-static int xdr_fhs __P((XDR *, caddr_t));
-static int xdr_mlist __P((XDR *, caddr_t));
-static int bitcmp __P((void *, void *, int));
-static int netpartcmp __P((struct sockaddr *, struct sockaddr *, int));
-static int sacmp __P((struct sockaddr *, struct sockaddr *));
-static int allones __P((struct sockaddr_storage *, int));
-static int countones __P((struct sockaddr *));
-static void bind_resv_port __P((int, sa_family_t, in_port_t));
-static void no_nfs(int);
-static struct exportlist *exphead;
-static struct mountlist *mlhead;
-static struct grouplist *grphead;
-static char *exname;
-static struct uucred def_anon = {
- 1,
- (uid_t) -2,
- (gid_t) -2,
- 0,
- { 0 }
-};
-
-static int opt_flags;
-static int have_v6 = 1;
-static const int ninumeric = NI_NUMERICHOST;
-
-/* Bits for above */
-#define OP_MAPROOT 0x001
-#define OP_MAPALL 0x002
-#define OP_KERB 0x004
-#define OP_MASK 0x008
-#define OP_NET 0x010
-#define OP_ALLDIRS 0x040
-#define OP_NORESPORT 0x080
-#define OP_NORESMNT 0x100
-#define OP_MASKLEN 0x200
-
-static int debug = 1;
-#if 0
-static void SYSLOG __P((int, const char *,...));
-#endif
-int main __P((int, char *[]));
-
-/*
- * If this is non-zero, -noresvport and -noresvmnt are implied for
- * each export.
- */
-static int noprivports;
-
-#define C2FD(_c_) ((int)(uintptr_t)(_c_))
-static int
-rumpread(void *cookie, char *buf, int count)
-{
-
- return rump_sys_read(C2FD(cookie), buf, count);
-}
-
-static int
-rumpwrite(void *cookie, const char *buf, int count)
-{
-
- return rump_sys_write(C2FD(cookie), buf, count);
-}
-
-static off_t
-rumpseek(void *cookie, off_t off, int whence)
-{
-
- return rump_sys_lseek(C2FD(cookie), off, whence);
-}
-
-static int
-rumpclose(void *cookie)
-{
-
- return rump_sys_close(C2FD(cookie));
-}
-
-int __sflags(const char *, int *); /* XXX */
-static FILE *
-rumpfopen(const char *path, const char *opts)
-{
- int fd, oflags;
-
- __sflags(opts, &oflags);
- fd = rump_sys_open(path, oflags, 0777);
- if (fd == -1)
- return NULL;
-
- return funopen((void *)(uintptr_t)fd,
- rumpread, rumpwrite, rumpseek, rumpclose);
-}
-
-/*
- * Make sure mountd signal handler is executed from a thread context
- * instead of the signal handler. This avoids the signal handler
- * ruining our kernel context.
- */
-static sem_t exportsem;
-static void
-signal_get_exportlist(int sig)
-{
-
- sem_post(&exportsem);
-}
-
-static void *
-exportlist_thread(void *arg)
-{
-
- for (;;) {
- sem_wait(&exportsem);
- get_exportlist(0);
- }
-
- return NULL;
-}
-
-/*
- * Mountd server for NFS mount protocol as described in:
- * NFS: Network File System Protocol Specification, RFC1094, Appendix A
- * The optional arguments are the exports file name
- * default: _PATH_EXPORTS
- * "-d" to enable debugging
- * and "-n" to allow nonroot mount.
- */
-void *mountd_main(void *);
-void *
-mountd_main(void *arg)
-{
- SVCXPRT *udptransp, *tcptransp;
- struct netconfig *udpconf, *tcpconf;
- int udpsock, tcpsock;
- int xcreated = 0;
- int maxrec = RPC_MAXDATASIZE;
- in_port_t forcedport = 0;
- extern sem_t gensem;
- pthread_t ptdummy;
-
- alloc_fdset();
-
-#if 0
- while ((c = getopt(argc, argv, "dNnrp:" ADDOPTS)) != -1)
- switch (c) {
-#ifdef IPSEC
- case 'P':
- if (ipsecsetup_test(policy = optarg))
- errx(1, "Invalid ipsec policy `%s'", policy);
- break;
-#endif
- case 'p':
- /* A forced port "0" will dynamically allocate a port */
- forcedport = atoi(optarg);
- break;
- case 'd':
- debug = 1;
- break;
- case 'N':
- noprivports = 1;
- break;
- /* Compatibility */
- case 'n':
- case 'r':
- break;
- default:
- fprintf(stderr, "usage: %s [-dNn]"
-#ifdef IPSEC
- " [-P policy]"
-#endif
- " [-p port] [exportsfile]\n", getprogname());
- exit(1);
- };
- argc -= optind;
- argv += optind;
-#endif
-
- sem_init(&exportsem, 0, 0);
- pthread_create(&ptdummy, NULL, exportlist_thread, NULL);
-
- grphead = NULL;
- exphead = NULL;
- mlhead = NULL;
- exname = _PATH_EXPORTS;
- openlog("mountd", LOG_PID | (debug ? LOG_PERROR : 0), LOG_DAEMON);
- (void)signal(SIGSYS, no_nfs);
-
- if (debug)
- (void)fprintf(stderr, "Getting export list.\n");
- get_exportlist(0);
- if (debug)
- (void)fprintf(stderr, "Getting mount list.\n");
- get_mountlist();
- if (debug)
- (void)fprintf(stderr, "Here we go.\n");
- if (debug == 0) {
- daemon(0, 0);
- (void)signal(SIGINT, SIG_IGN);
- (void)signal(SIGQUIT, SIG_IGN);
- }
- (void)signal(SIGHUP, signal_get_exportlist);
- (void)signal(SIGTERM, send_umntall);
- pidfile(NULL);
-
- rpcb_unset(RPCPROG_MNT, RPCMNT_VER1, NULL);
- rpcb_unset(RPCPROG_MNT, RPCMNT_VER3, NULL);
-
- udpsock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
- tcpsock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
-
- udpconf = getnetconfigent("udp");
- tcpconf = getnetconfigent("tcp");
-
- rpc_control(RPC_SVC_CONNMAXREC_SET, &maxrec);
-
- if (udpsock != -1 && udpconf != NULL) {
- bind_resv_port(udpsock, AF_INET, forcedport);
-#ifdef IPSEC
- if (policy)
- ipsecsetup(AF_INET, udpsock, policy);
-#endif
- udptransp = svc_dg_create(udpsock, 0, 0);
- if (udptransp != NULL) {
- if (!svc_reg(udptransp, RPCPROG_MNT, RPCMNT_VER1,
- mntsrv, udpconf) ||
- !svc_reg(udptransp, RPCPROG_MNT, RPCMNT_VER3,
- mntsrv, udpconf)) {
- syslog(LOG_WARNING, "can't register UDP service");
- }
- else {
- xcreated++;
- }
- } else {
- syslog(LOG_WARNING, "can't create UDP service");
- }
-
- }
-
- if (tcpsock != -1 && tcpconf != NULL) {
- bind_resv_port(tcpsock, AF_INET, forcedport);
-#ifdef IPSEC
- if (policy)
- ipsecsetup(AF_INET, tcpsock, policy);
-#endif
- listen(tcpsock, SOMAXCONN);
- tcptransp = svc_vc_create(tcpsock, RPC_MAXDATASIZE,
- RPC_MAXDATASIZE);
- if (tcptransp != NULL) {
- if (!svc_reg(tcptransp, RPCPROG_MNT, RPCMNT_VER1,
- mntsrv, tcpconf) ||
- !svc_reg(tcptransp, RPCPROG_MNT, RPCMNT_VER3,
- mntsrv, tcpconf))
- syslog(LOG_WARNING, "can't register TCP service");
- else
- xcreated++;
- } else
- syslog(LOG_WARNING, "can't create TCP service");
-
- }
-
- if (xcreated == 0) {
- syslog(LOG_ERR, "could not create any services");
- exit(1);
- }
-
- sem_post(&gensem);
- svc_run();
- syslog(LOG_ERR, "Mountd died");
- exit(1);
-}
-
-/*
- * The mount rpc service
- */
-void
-mntsrv(rqstp, transp)
- struct svc_req *rqstp;
- SVCXPRT *transp;
-{
- struct exportlist *ep;
- struct dirlist *dp;
- struct fhreturn fhr;
- struct stat stb;
- struct statvfs fsb;
- char host[NI_MAXHOST], numerichost[NI_MAXHOST];
- int lookup_failed = 1;
- struct sockaddr *saddr;
- u_short sport;
- char rpcpath[RPCMNT_PATHLEN + 1], dpath[MAXPATHLEN];
- long bad = EACCES;
- int defset, hostset, ret;
- sigset_t sighup_mask;
- struct sockaddr_in6 *sin6;
- struct sockaddr_in *sin;
- size_t fh_size;
- int error = 0;
-
- (void)sigemptyset(&sighup_mask);
- (void)sigaddset(&sighup_mask, SIGHUP);
- saddr = svc_getrpccaller(transp)->buf;
- switch (saddr->sa_family) {
- case AF_INET6:
- sin6 = (struct sockaddr_in6 *)saddr;
- sport = ntohs(sin6->sin6_port);
- break;
- case AF_INET:
- sin = (struct sockaddr_in *)saddr;
- sport = ntohs(sin->sin_port);
- break;
- default:
- syslog(LOG_ERR, "request from unknown address family");
- return;
- }
- lookup_failed = getnameinfo(saddr, saddr->sa_len, host, sizeof host,
- NULL, 0, 0);
- if (getnameinfo(saddr, saddr->sa_len, numerichost,
- sizeof numerichost, NULL, 0, ninumeric) != 0)
- strlcpy(numerichost, "?", sizeof(numerichost));
- ret = 0;
- switch (rqstp->rq_proc) {
- case NULLPROC:
- if (!svc_sendreply(transp, (xdrproc_t)xdr_void, NULL))
- syslog(LOG_ERR, "Can't send reply");
- return;
- case MOUNTPROC_MNT:
- if (debug)
- fprintf(stderr,
- "got mount request from %s\n", numerichost);
- if (!svc_getargs(transp, xdr_dir, rpcpath)) {
- if (debug)
- fprintf(stderr, "-> garbage args\n");
- svcerr_decode(transp);
- return;
- }
- if (debug)
- fprintf(stderr,
- "-> rpcpath: %s\n", rpcpath);
- /*
- * Get the real pathname and make sure it is a file or
- * directory that exists.
- */
-#if 0
- if (realpath(rpcpath, dpath) == 0 ||
-#endif
- strcpy(dpath, rpcpath);
- if (rump_sys_stat(dpath, &stb) < 0 ||
- (!S_ISDIR(stb.st_mode) && !S_ISREG(stb.st_mode)) ||
- rump_sys_statvfs1(dpath, &fsb, ST_WAIT) < 0) {
- (void)chdir("/"); /* Just in case realpath doesn't */
- if (debug)
- (void)fprintf(stderr, "-> stat failed on %s\n",
- dpath);
- if (!svc_sendreply(transp, (xdrproc_t)xdr_long, (caddr_t) &bad))
- syslog(LOG_ERR, "Can't send reply");
- return;
- }
- if (debug)
- fprintf(stderr,
- "-> dpath: %s\n", dpath);
- /* Check in the exports list */
- (void)sigprocmask(SIG_BLOCK, &sighup_mask, NULL);
- ep = ex_search(&fsb.f_fsidx);
- hostset = defset = 0;
- if (ep && (chk_host(ep->ex_defdir, saddr, &defset,
- &hostset) || ((dp = dirp_search(ep->ex_dirl, dpath)) &&
- chk_host(dp, saddr, &defset, &hostset)) ||
- (defset && scan_tree(ep->ex_defdir, saddr) == 0 &&
- scan_tree(ep->ex_dirl, saddr) == 0))) {
- if ((hostset & DP_HOSTSET) == 0) {
- hostset = defset;
- }
- if (sport >= IPPORT_RESERVED &&
- !(hostset & DP_NORESMNT)) {
- syslog(LOG_NOTICE,
- "Refused mount RPC from host %s port %d",
- numerichost, sport);
- svcerr_weakauth(transp);
- goto out;
- }
- fhr.fhr_flag = hostset;
- fhr.fhr_vers = rqstp->rq_vers;
- /* Get the file handle */
- memset(&fhr.fhr_fh, 0, sizeof(fhr.fhr_fh)); /* for v2 */
- fh_size = sizeof(fhr.fhr_fh);
- error = 0;
- if (rump_sys_getfh(dpath, &fhr.fhr_fh, &fh_size) < 0) {
- bad = error;
- //syslog(LOG_ERR, "Can't get fh for %s %d %d", dpath, error, fh_size);
- if (!svc_sendreply(transp, (xdrproc_t)xdr_long,
- (char *)&bad))
- syslog(LOG_ERR, "Can't send reply");
- goto out;
- }
- if ((fhr.fhr_vers == 1 && fh_size > NFSX_V2FH) ||
- fh_size > NFSX_V3FHMAX) {
- bad = EINVAL; /* XXX */
- if (!svc_sendreply(transp, (xdrproc_t)xdr_long,
- (char *)&bad))
- syslog(LOG_ERR, "Can't send reply");
- goto out;
- }
- fhr.fhr_fhsize = fh_size;
- if (!svc_sendreply(transp, (xdrproc_t)xdr_fhs, (char *) &fhr))
- syslog(LOG_ERR, "Can't send reply");
- if (!lookup_failed)
- add_mlist(host, dpath, hostset);
- else
- add_mlist(numerichost, dpath, hostset);
- if (debug)
- (void)fprintf(stderr, "Mount successful.\n");
- } else {
- if (!svc_sendreply(transp, (xdrproc_t)xdr_long, (caddr_t) &bad))
- syslog(LOG_ERR, "Can't send reply");
- }
-out:
- (void)sigprocmask(SIG_UNBLOCK, &sighup_mask, NULL);
- return;
- case MOUNTPROC_DUMP:
- if (!svc_sendreply(transp, (xdrproc_t)xdr_mlist, NULL))
- syslog(LOG_ERR, "Can't send reply");
- return;
- case MOUNTPROC_UMNT:
- if (!svc_getargs(transp, xdr_dir, dpath)) {
- svcerr_decode(transp);
- return;
- }
- if (!lookup_failed)
- ret = del_mlist(host, dpath, saddr);
- ret |= del_mlist(numerichost, dpath, saddr);
- if (ret) {
- svcerr_weakauth(transp);
- return;
- }
- if (!svc_sendreply(transp, (xdrproc_t)xdr_void, NULL))
- syslog(LOG_ERR, "Can't send reply");
- return;
- case MOUNTPROC_UMNTALL:
- if (!lookup_failed)
- ret = del_mlist(host, NULL, saddr);
- ret |= del_mlist(numerichost, NULL, saddr);
- if (ret) {
- svcerr_weakauth(transp);
- return;
- }
- if (!svc_sendreply(transp, (xdrproc_t)xdr_void, NULL))
- syslog(LOG_ERR, "Can't send reply");
- return;
- case MOUNTPROC_EXPORT:
- case MOUNTPROC_EXPORTALL:
- if (!svc_sendreply(transp, (xdrproc_t)xdr_explist, NULL))
- syslog(LOG_ERR, "Can't send reply");
- return;
-
-
- default:
- svcerr_noproc(transp);
- return;
- }
-}
-
-/*
- * Xdr conversion for a dpath string
- */
-static int
-xdr_dir(xdrsp, dirp)
- XDR *xdrsp;
- char *dirp;
-{
-
- return (xdr_string(xdrsp, &dirp, RPCMNT_PATHLEN));
-}
-
-/*
- * Xdr routine to generate file handle reply
- */
-static int
-xdr_fhs(xdrsp, cp)
- XDR *xdrsp;
- caddr_t cp;
-{
- struct fhreturn *fhrp = (struct fhreturn *) cp;
- long ok = 0, len, auth;
-
- if (!xdr_long(xdrsp, &ok))
- return (0);
- switch (fhrp->fhr_vers) {
- case 1:
- return (xdr_opaque(xdrsp, (caddr_t)&fhrp->fhr_fh, NFSX_V2FH));
- case 3:
- len = fhrp->fhr_fhsize;
- if (!xdr_long(xdrsp, &len))
- return (0);
- if (!xdr_opaque(xdrsp, (caddr_t)&fhrp->fhr_fh, len))
- return (0);
- if (fhrp->fhr_flag & DP_KERB)
- auth = RPCAUTH_KERB4;
- else
- auth = RPCAUTH_UNIX;
- len = 1;
- if (!xdr_long(xdrsp, &len))
- return (0);
- return (xdr_long(xdrsp, &auth));
- };
- return (0);
-}
-
-int
-xdr_mlist(xdrsp, cp)
- XDR *xdrsp;
- caddr_t cp;
-{
- struct mountlist *mlp;
- int trueval = 1;
- int falseval = 0;
- char *strp;
-
- mlp = mlhead;
- while (mlp) {
- if (!xdr_bool(xdrsp, &trueval))
- return (0);
- strp = &mlp->ml_host[0];
- if (!xdr_string(xdrsp, &strp, RPCMNT_NAMELEN))
- return (0);
- strp = &mlp->ml_dirp[0];
- if (!xdr_string(xdrsp, &strp, RPCMNT_PATHLEN))
- return (0);
- mlp = mlp->ml_next;
- }
- if (!xdr_bool(xdrsp, &falseval))
- return (0);
- return (1);
-}
-
-/*
- * Xdr conversion for export list
- */
-int
-xdr_explist(xdrsp, cp)
- XDR *xdrsp;
- caddr_t cp;
-{
- struct exportlist *ep;
- int falseval = 0;
- int putdef;
- sigset_t sighup_mask;
-
- (void)sigemptyset(&sighup_mask);
- (void)sigaddset(&sighup_mask, SIGHUP);
- (void)sigprocmask(SIG_BLOCK, &sighup_mask, NULL);
- ep = exphead;
- while (ep) {
- putdef = 0;
- if (put_exlist(ep->ex_dirl, xdrsp, ep->ex_defdir, &putdef))
- goto errout;
- if (ep->ex_defdir && putdef == 0 &&
- put_exlist(ep->ex_defdir, xdrsp, NULL, &putdef))
- goto errout;
- ep = ep->ex_next;
- }
- (void)sigprocmask(SIG_UNBLOCK, &sighup_mask, NULL);
- if (!xdr_bool(xdrsp, &falseval))
- return (0);
- return (1);
-errout:
- (void)sigprocmask(SIG_UNBLOCK, &sighup_mask, NULL);
- return (0);
-}
-
-/*
- * Called from xdr_explist() to traverse the tree and export the
- * directory paths. Assumes SIGHUP has already been masked.
- */
-int
-put_exlist(dp, xdrsp, adp, putdefp)
- struct dirlist *dp;
- XDR *xdrsp;
- struct dirlist *adp;
- int *putdefp;
-{
- struct grouplist *grp;
- struct hostlist *hp;
- int trueval = 1;
- int falseval = 0;
- int gotalldir = 0;
- char *strp;
-
- if (dp) {
- if (put_exlist(dp->dp_left, xdrsp, adp, putdefp))
- return (1);
- if (!xdr_bool(xdrsp, &trueval))
- return (1);
- strp = dp->dp_dirp;
- if (!xdr_string(xdrsp, &strp, RPCMNT_PATHLEN))
- return (1);
- if (adp && !strcmp(dp->dp_dirp, adp->dp_dirp)) {
- gotalldir = 1;
- *putdefp = 1;
- }
- if ((dp->dp_flag & DP_DEFSET) == 0 &&
- (gotalldir == 0 || (adp->dp_flag & DP_DEFSET) == 0)) {
- hp = dp->dp_hosts;
- while (hp) {
- grp = hp->ht_grp;
- if (grp->gr_type == GT_HOST) {
- if (!xdr_bool(xdrsp, &trueval))
- return (1);
- strp =
- grp->gr_ptr.gt_addrinfo->ai_canonname;
- if (!xdr_string(xdrsp, &strp,
- RPCMNT_NAMELEN))
- return (1);
- } else if (grp->gr_type == GT_NET) {
- if (!xdr_bool(xdrsp, &trueval))
- return (1);
- strp = grp->gr_ptr.gt_net.nt_name;
- if (!xdr_string(xdrsp, &strp,
- RPCMNT_NAMELEN))
- return (1);
- }
- hp = hp->ht_next;
- if (gotalldir && hp == NULL) {
- hp = adp->dp_hosts;
- gotalldir = 0;
- }
- }
- }
- if (!xdr_bool(xdrsp, &falseval))
- return (1);
- if (put_exlist(dp->dp_right, xdrsp, adp, putdefp))
- return (1);
- }
- return (0);
-}
-
-static int
-parse_host_netgroup(line, lineno, ep, tgrp, cp, has_host, grp)
- const char *line;
- size_t lineno;
- struct exportlist *ep;
- struct grouplist *tgrp;
- char *cp;
- int *has_host;
- struct grouplist **grp;
-{
- const char *hst, *usr, *dom;
- int netgrp;
-
- if (ep == NULL) {
- syslog(LOG_ERR, "\"%s\", line %ld: No current export",
- line, (unsigned long)lineno);
- return 0;
- }
- setnetgrent(cp);
- netgrp = getnetgrent(&hst, &usr, &dom);
- do {
- if (*has_host) {
- (*grp)->gr_next = get_grp();
- *grp = (*grp)->gr_next;
- }
- if (netgrp) {
- if (hst == NULL) {
- syslog(LOG_ERR,
- "\"%s\", line %ld: No host in netgroup %s",
- line, (unsigned long)lineno, cp);
- goto bad;
- }
- if (get_host(line, lineno, hst, *grp))
- goto bad;
- } else if (get_host(line, lineno, cp, *grp))
- goto bad;
- *has_host = TRUE;
- } while (netgrp && getnetgrent(&hst, &usr, &dom));
-
- endnetgrent();
- return 1;
-bad:
- endnetgrent();
- return 0;
-
-}
-
-static int
-parse_directory(line, lineno, tgrp, got_nondir, cp, ep, fsp)
- const char *line;
- size_t lineno;
- struct grouplist *tgrp;
- int got_nondir;
- char *cp;
- struct exportlist **ep;
- struct statvfs *fsp;
-{
- int error = 0;
-
- if (!check_dirpath(line, lineno, cp))
- return 0;
-
- if (rump_sys_statvfs1(cp, fsp, ST_WAIT) == -1) {
- syslog(LOG_ERR, "\"%s\", line %ld: statvfs for `%s' failed: %m %d",
- line, (unsigned long)lineno, cp, error);
- return 0;
- }
-
- if (got_nondir) {
- syslog(LOG_ERR,
- "\"%s\", line %ld: Directories must precede files",
- line, (unsigned long)lineno);
- return 0;
- }
- if (*ep) {
- if ((*ep)->ex_fs.__fsid_val[0] != fsp->f_fsidx.__fsid_val[0] ||
- (*ep)->ex_fs.__fsid_val[1] != fsp->f_fsidx.__fsid_val[1]) {
- syslog(LOG_ERR,
- "\"%s\", line %ld: filesystem ids disagree",
- line, (unsigned long)lineno);
- return 0;
- }
- } else {
- /*
- * See if this directory is already
- * in the list.
- */
- *ep = ex_search(&fsp->f_fsidx);
- if (*ep == NULL) {
- *ep = get_exp();
- (*ep)->ex_fs = fsp->f_fsidx;
- (*ep)->ex_fsdir = estrdup(fsp->f_mntonname);
- if (debug)
- (void)fprintf(stderr,
- "Making new ep fs=0x%x,0x%x\n",
- fsp->f_fsidx.__fsid_val[0], fsp->f_fsidx.__fsid_val[1]);
- } else {
- if (debug)
- (void)fprintf(stderr,
- "Found ep fs=0x%x,0x%x\n",
- fsp->f_fsidx.__fsid_val[0], fsp->f_fsidx.__fsid_val[1]);
- }
- }
-
- return 1;
-}
-
-
-/*
- * Get the export list
- */
-/* ARGSUSED */
-void
-get_exportlist(n)
- int n;
-{
- struct exportlist *ep, *ep2;
- struct grouplist *grp, *tgrp;
- struct exportlist **epp;
- struct dirlist *dirhead;
- struct statvfs fsb, *fsp;
- struct addrinfo *ai;
- struct uucred anon;
- char *cp, *endcp, *dirp, savedc;
- int has_host, exflags, got_nondir, dirplen, num, i;
- FILE *exp_file;
- char *line;
- size_t lineno = 0, len;
-
-
- /*
- * First, get rid of the old list
- */
- ep = exphead;
- while (ep) {
- ep2 = ep;
- ep = ep->ex_next;
- free_exp(ep2);
- }
- exphead = NULL;
-
- dirp = NULL;
- dirplen = 0;
- grp = grphead;
- while (grp) {
- tgrp = grp;
- grp = grp->gr_next;
- free_grp(tgrp);
- }
- grphead = NULL;
-
- /*
- * And delete exports that are in the kernel for all local
- * file systems.
- */
- num = getmntinfo(&fsp, MNT_NOWAIT);
- for (i = 0; i < num; i++) {
- struct mountd_exports_list mel;
-
- /* Delete all entries from the export list. */
- mel.mel_path = fsp->f_mntonname;
- mel.mel_nexports = 0;
- if (rump_sys_nfssvc(NFSSVC_SETEXPORTSLIST, &mel) == -1 &&
- errno != EOPNOTSUPP)
- syslog(LOG_ERR, "Can't delete exports for %s (%m)",
- fsp->f_mntonname);
-
- fsp++;
- }
-
- /*
- * Read in the exports file and build the list, calling
- * mount() as we go along to push the export rules into the kernel.
- */
- exname = _PATH_EXPORTS;
- if ((exp_file = rumpfopen(exname, "r")) == NULL) {
- /*
- * Don't exit here; we can still reload the config
- * after a SIGHUP.
- */
- if (debug)
- (void)fprintf(stderr, "Can't open %s: %s\n", exname,
- strerror(errno));
- return;
- }
- dirhead = NULL;
- while ((line = fparseln(exp_file, &len, &lineno, NULL, 0)) != NULL) {
- if (debug)
- (void)fprintf(stderr, "Got line %s\n", line);
- cp = line;
- nextfield(&cp, &endcp);
- if (cp == endcp)
- goto nextline; /* skip empty line */
- /*
- * Set defaults.
- */
- has_host = FALSE;
- anon = def_anon;
- exflags = MNT_EXPORTED;
- got_nondir = 0;
- opt_flags = 0;
- ep = NULL;
-
- if (noprivports) {
- opt_flags |= OP_NORESMNT | OP_NORESPORT;
- exflags |= MNT_EXNORESPORT;
- }
-
- /*
- * Create new exports list entry
- */
- len = endcp - cp;
- tgrp = grp = get_grp();
- while (len > 0) {
- if (len > RPCMNT_NAMELEN) {
- *endcp = '\0';
- syslog(LOG_ERR,
- "\"%s\", line %ld: name `%s' is too long",
- line, (unsigned long)lineno, cp);
- goto badline;
- }
- switch (*cp) {
- case '-':
- /*
- * Option
- */
- if (ep == NULL) {
- syslog(LOG_ERR,
- "\"%s\", line %ld: No current export list",
- line, (unsigned long)lineno);
- goto badline;
- }
- if (debug)
- (void)fprintf(stderr, "doing opt %s\n",
- cp);
- got_nondir = 1;
- if (do_opt(line, lineno, &cp, &endcp, ep, grp,
- &has_host, &exflags, &anon))
- goto badline;
- break;
-
- case '/':
- /*
- * Directory
- */
- savedc = *endcp;
- *endcp = '\0';
-
- if (!parse_directory(line, lineno, tgrp,
- got_nondir, cp, &ep, &fsb))
- goto badline;
- /*
- * Add dirpath to export mount point.
- */
- dirp = add_expdir(&dirhead, cp, len);
- dirplen = len;
-
- *endcp = savedc;
- break;
-
- default:
- /*
- * Host or netgroup.
- */
- savedc = *endcp;
- *endcp = '\0';
-
- if (!parse_host_netgroup(line, lineno, ep,
- tgrp, cp, &has_host, &grp))
- goto badline;
-
- got_nondir = 1;
-
- *endcp = savedc;
- break;
- }
-
- cp = endcp;
- nextfield(&cp, &endcp);
- len = endcp - cp;
- }
- if (check_options(line, lineno, dirhead))
- goto badline;
-
- if (!has_host) {
- grp->gr_type = GT_HOST;
- if (debug)
- (void)fprintf(stderr,
- "Adding a default entry\n");
- /* add a default group and make the grp list NULL */
- ai = emalloc(sizeof(struct addrinfo));
- ai->ai_flags = 0;
- ai->ai_family = AF_INET; /* XXXX */
- ai->ai_socktype = SOCK_DGRAM;
- /* setting the length to 0 will match anything */
- ai->ai_addrlen = 0;
- ai->ai_flags = AI_CANONNAME;
- ai->ai_canonname = estrdup("Default");
- ai->ai_addr = NULL;
- ai->ai_next = NULL;
- grp->gr_ptr.gt_addrinfo = ai;
-
- } else if ((opt_flags & OP_NET) && tgrp->gr_next) {
- /*
- * Don't allow a network export coincide with a list of
- * host(s) on the same line.
- */
- syslog(LOG_ERR,
- "\"%s\", line %ld: Mixed exporting of networks and hosts is disallowed",
- line, (unsigned long)lineno);
- goto badline;
- }
- /*
- * Loop through hosts, pushing the exports into the kernel.
- * After loop, tgrp points to the start of the list and
- * grp points to the last entry in the list.
- */
- grp = tgrp;
- do {
- if (do_nfssvc(line, lineno, ep, grp, exflags, &anon,
- dirp, dirplen, &fsb))
- goto badline;
- } while (grp->gr_next && (grp = grp->gr_next));
-
- /*
- * Success. Update the data structures.
- */
- if (has_host) {
- hang_dirp(dirhead, tgrp, ep, opt_flags);
- grp->gr_next = grphead;
- grphead = tgrp;
- } else {
- hang_dirp(dirhead, NULL, ep, opt_flags);
- free_grp(tgrp);
- }
- tgrp = NULL;
- dirhead = NULL;
- if ((ep->ex_flag & EX_LINKED) == 0) {
- ep2 = exphead;
- epp = &exphead;
-
- /*
- * Insert in the list in alphabetical order.
- */
- while (ep2 && strcmp(ep2->ex_fsdir, ep->ex_fsdir) < 0) {
- epp = &ep2->ex_next;
- ep2 = ep2->ex_next;
- }
- if (ep2)
- ep->ex_next = ep2;
- *epp = ep;
- ep->ex_flag |= EX_LINKED;
- }
- goto nextline;
-badline:
- free_exp_grp(ep, grp);
-nextline:
- if (dirhead) {
- free_dir(dirhead);
- dirhead = NULL;
- }
- free(line);
- }
- (void)fclose(exp_file);
-}
-
-/*
- * Allocate an export list element
- */
-static struct exportlist *
-get_exp()
-{
- struct exportlist *ep;
-
- ep = emalloc(sizeof(struct exportlist));
- (void)memset(ep, 0, sizeof(struct exportlist));
- return (ep);
-}
-
-/*
- * Allocate a group list element
- */
-static struct grouplist *
-get_grp()
-{
- struct grouplist *gp;
-
- gp = emalloc(sizeof(struct grouplist));
- (void)memset(gp, 0, sizeof(struct grouplist));
- return (gp);
-}
-
-/*
- * Clean up upon an error in get_exportlist().
- */
-static void
-free_exp_grp(ep, grp)
- struct exportlist *ep;
- struct grouplist *grp;
-{
- struct grouplist *tgrp;
-
- if (ep && (ep->ex_flag & EX_LINKED) == 0)
- free_exp(ep);
- while (grp) {
- tgrp = grp;
- grp = grp->gr_next;
- free_grp(tgrp);
- }
-}
-
-/*
- * Search the export list for a matching fs.
- */
-static struct exportlist *
-ex_search(fsid)
- fsid_t *fsid;
-{
- struct exportlist *ep;
-
- ep = exphead;
- return ep;
- while (ep) {
- if (ep->ex_fs.__fsid_val[0] == fsid->__fsid_val[0] &&
- ep->ex_fs.__fsid_val[1] == fsid->__fsid_val[1])
- return (ep);
- ep = ep->ex_next;
- }
- return (ep);
-}
-
-/*
- * Add a directory path to the list.
- */
-static char *
-add_expdir(dpp, cp, len)
- struct dirlist **dpp;
- char *cp;
- int len;
-{
- struct dirlist *dp;
-
- dp = emalloc(sizeof(struct dirlist) + len);
- dp->dp_left = *dpp;
- dp->dp_right = NULL;
- dp->dp_flag = 0;
- dp->dp_hosts = NULL;
- (void)strcpy(dp->dp_dirp, cp);
- *dpp = dp;
- return (dp->dp_dirp);
-}
-
-/*
- * Hang the dir list element off the dirpath binary tree as required
- * and update the entry for host.
- */
-void
-hang_dirp(dp, grp, ep, flags)
- struct dirlist *dp;
- struct grouplist *grp;
- struct exportlist *ep;
- int flags;
-{
- struct hostlist *hp;
- struct dirlist *dp2;
-
- if (flags & OP_ALLDIRS) {
- if (ep->ex_defdir)
- free(dp);
- else
- ep->ex_defdir = dp;
- if (grp == NULL) {
- ep->ex_defdir->dp_flag |= DP_DEFSET;
- if (flags & OP_KERB)
- ep->ex_defdir->dp_flag |= DP_KERB;
- if (flags & OP_NORESMNT)
- ep->ex_defdir->dp_flag |= DP_NORESMNT;
- } else
- while (grp) {
- hp = get_ht();
- if (flags & OP_KERB)
- hp->ht_flag |= DP_KERB;
- if (flags & OP_NORESMNT)
- hp->ht_flag |= DP_NORESMNT;
- hp->ht_grp = grp;
- hp->ht_next = ep->ex_defdir->dp_hosts;
- ep->ex_defdir->dp_hosts = hp;
- grp = grp->gr_next;
- }
- } else {
-
- /*
- * Loop through the directories adding them to the tree.
- */
- while (dp) {
- dp2 = dp->dp_left;
- add_dlist(&ep->ex_dirl, dp, grp, flags);
- dp = dp2;
- }
- }
-}
-
-/*
- * Traverse the binary tree either updating a node that is already there
- * for the new directory or adding the new node.
- */
-static void
-add_dlist(dpp, newdp, grp, flags)
- struct dirlist **dpp;
- struct dirlist *newdp;
- struct grouplist *grp;
- int flags;
-{
- struct dirlist *dp;
- struct hostlist *hp;
- int cmp;
-
- dp = *dpp;
- if (dp) {
- cmp = strcmp(dp->dp_dirp, newdp->dp_dirp);
- if (cmp > 0) {
- add_dlist(&dp->dp_left, newdp, grp, flags);
- return;
- } else if (cmp < 0) {
- add_dlist(&dp->dp_right, newdp, grp, flags);
- return;
- } else
- free(newdp);
- } else {
- dp = newdp;
- dp->dp_left = NULL;
- *dpp = dp;
- }
- if (grp) {
-
- /*
- * Hang all of the host(s) off of the directory point.
- */
- do {
- hp = get_ht();
- if (flags & OP_KERB)
- hp->ht_flag |= DP_KERB;
- if (flags & OP_NORESMNT)
- hp->ht_flag |= DP_NORESMNT;
- hp->ht_grp = grp;
- hp->ht_next = dp->dp_hosts;
- dp->dp_hosts = hp;
- grp = grp->gr_next;
- } while (grp);
- } else {
- dp->dp_flag |= DP_DEFSET;
- if (flags & OP_KERB)
- dp->dp_flag |= DP_KERB;
- if (flags & OP_NORESMNT)
- dp->dp_flag |= DP_NORESMNT;
- }
-}
-
-/*
- * Search for a dirpath on the export point.
- */
-static struct dirlist *
-dirp_search(dp, dirp)
- struct dirlist *dp;
- char *dirp;
-{
- int cmp;
-
- if (dp) {
- cmp = strcmp(dp->dp_dirp, dirp);
- if (cmp > 0)
- return (dirp_search(dp->dp_left, dirp));
- else if (cmp < 0)
- return (dirp_search(dp->dp_right, dirp));
- else
- return (dp);
- }
- return (dp);
-}
-
-/*
- * Some helper functions for netmasks. They all assume masks in network
- * order (big endian).
- */
-static int
-bitcmp(void *dst, void *src, int bitlen)
-{
- int i;
- u_int8_t *p1 = dst, *p2 = src;
- u_int8_t bitmask;
- int bytelen, bitsleft;
-
- bytelen = bitlen / 8;
- bitsleft = bitlen % 8;
-
- if (debug) {
- printf("comparing:\n");
- for (i = 0; i < (bitsleft ? bytelen + 1 : bytelen); i++)
- printf("%02x", p1[i]);
- printf("\n");
- for (i = 0; i < (bitsleft ? bytelen + 1 : bytelen); i++)
- printf("%02x", p2[i]);
- printf("\n");
- }
-
- for (i = 0; i < bytelen; i++) {
- if (*p1 != *p2)
- return 1;
- p1++;
- p2++;
- }
-
- for (i = 0; i < bitsleft; i++) {
- bitmask = 1 << (7 - i);
- if ((*p1 & bitmask) != (*p2 & bitmask))
- return 1;
- }
-
- return 0;
-}
-
-static int
-netpartcmp(struct sockaddr *s1, struct sockaddr *s2, int bitlen)
-{
- void *src, *dst;
-
- if (s1->sa_family != s2->sa_family)
- return 1;
-
- switch (s1->sa_family) {
- case AF_INET:
- src = &((struct sockaddr_in *)s1)->sin_addr;
- dst = &((struct sockaddr_in *)s2)->sin_addr;
- if (bitlen > sizeof(((struct sockaddr_in *)s1)->sin_addr) * 8)
- return 1;
- break;
- case AF_INET6:
- src = &((struct sockaddr_in6 *)s1)->sin6_addr;
- dst = &((struct sockaddr_in6 *)s2)->sin6_addr;
- if (((struct sockaddr_in6 *)s1)->sin6_scope_id !=
- ((struct sockaddr_in6 *)s2)->sin6_scope_id)
- return 1;
- if (bitlen > sizeof(((struct sockaddr_in6 *)s1)->sin6_addr) * 8)
- return 1;
- break;
- default:
- return 1;
- }
-
- return bitcmp(src, dst, bitlen);
-}
-
-static int
-allones(struct sockaddr_storage *ssp, int bitlen)
-{
- u_int8_t *p;
- int bytelen, bitsleft, i;
- int zerolen;
-
- switch (ssp->ss_family) {
- case AF_INET:
- p = (u_int8_t *)&((struct sockaddr_in *)ssp)->sin_addr;
- zerolen = sizeof (((struct sockaddr_in *)ssp)->sin_addr);
- break;
- case AF_INET6:
- p = (u_int8_t *)&((struct sockaddr_in6 *)ssp)->sin6_addr;
- zerolen = sizeof (((struct sockaddr_in6 *)ssp)->sin6_addr);
- break;
- default:
- return -1;
- }
-
- memset(p, 0, zerolen);
-
- bytelen = bitlen / 8;
- bitsleft = bitlen % 8;
-
- if (bytelen > zerolen)
- return -1;
-
- for (i = 0; i < bytelen; i++)
- *p++ = 0xff;
-
- for (i = 0; i < bitsleft; i++)
- *p |= 1 << (7 - i);
-
- return 0;
-}
-
-static int
-countones(struct sockaddr *sa)
-{
- void *mask;
- int i, bits = 0, bytelen;
- u_int8_t *p;
-
- switch (sa->sa_family) {
- case AF_INET:
- mask = (u_int8_t *)&((struct sockaddr_in *)sa)->sin_addr;
- bytelen = 4;
- break;
- case AF_INET6:
- mask = (u_int8_t *)&((struct sockaddr_in6 *)sa)->sin6_addr;
- bytelen = 16;
- break;
- default:
- return 0;
- }
-
- p = mask;
-
- for (i = 0; i < bytelen; i++, p++) {
- if (*p != 0xff) {
- for (bits = 0; bits < 8; bits++) {
- if (!(*p & (1 << (7 - bits))))
- break;
- }
- break;
- }
- }
-
- return (i * 8 + bits);
-}
-
-static int
-sacmp(struct sockaddr *sa1, struct sockaddr *sa2)
-{
- void *p1, *p2;
- int len;
-
- if (sa1->sa_family != sa2->sa_family)
- return 1;
-
- switch (sa1->sa_family) {
- case AF_INET:
- p1 = &((struct sockaddr_in *)sa1)->sin_addr;
- p2 = &((struct sockaddr_in *)sa2)->sin_addr;
- len = 4;
- break;
- case AF_INET6:
- p1 = &((struct sockaddr_in6 *)sa1)->sin6_addr;
- p2 = &((struct sockaddr_in6 *)sa2)->sin6_addr;
- len = 16;
- if (((struct sockaddr_in6 *)sa1)->sin6_scope_id !=
- ((struct sockaddr_in6 *)sa2)->sin6_scope_id)
- return 1;
- break;
- default:
- return 1;
- }
-
- return memcmp(p1, p2, len);
-}
-
-/*
- * Scan for a host match in a directory tree.
- */
-static int
-chk_host(dp, saddr, defsetp, hostsetp)
- struct dirlist *dp;
- struct sockaddr *saddr;
- int *defsetp;
- int *hostsetp;
-{
- struct hostlist *hp;
- struct grouplist *grp;
- struct addrinfo *ai;
-
- if (dp) {
- if (dp->dp_flag & DP_DEFSET)
- *defsetp = dp->dp_flag;
- hp = dp->dp_hosts;
- while (hp) {
- grp = hp->ht_grp;
- switch (grp->gr_type) {
- case GT_HOST:
- ai = grp->gr_ptr.gt_addrinfo;
- for (; ai; ai = ai->ai_next) {
- if (!sacmp(ai->ai_addr, saddr)) {
- *hostsetp =
- (hp->ht_flag | DP_HOSTSET);
- return (1);
- }
- }
- break;
- case GT_NET:
- if (!netpartcmp(saddr,
- (struct sockaddr *)
- &grp->gr_ptr.gt_net.nt_net,
- grp->gr_ptr.gt_net.nt_len)) {
- *hostsetp = (hp->ht_flag | DP_HOSTSET);
- return (1);
- }
- break;
- };
- hp = hp->ht_next;
- }
- }
- return (0);
-}
-
-/*
- * Scan tree for a host that matches the address.
- */
-static int
-scan_tree(dp, saddr)
- struct dirlist *dp;
- struct sockaddr *saddr;
-{
- int defset, hostset;
-
- if (dp) {
- if (scan_tree(dp->dp_left, saddr))
- return (1);
- if (chk_host(dp, saddr, &defset, &hostset))
- return (1);
- if (scan_tree(dp->dp_right, saddr))
- return (1);
- }
- return (0);
-}
-
-/*
- * Traverse the dirlist tree and free it up.
- */
-static void
-free_dir(dp)
- struct dirlist *dp;
-{
-
- if (dp) {
- free_dir(dp->dp_left);
- free_dir(dp->dp_right);
- free_host(dp->dp_hosts);
- free(dp);
- }
-}
-
-/*
- * Parse the option string and update fields.
- * Option arguments may either be -<option>=<value> or
- * -<option> <value>
- */
-static int
-do_opt(line, lineno, cpp, endcpp, ep, grp, has_hostp, exflagsp, cr)
- const char *line;
- size_t lineno;
- char **cpp, **endcpp;
- struct exportlist *ep;
- struct grouplist *grp;
- int *has_hostp;
- int *exflagsp;
- struct uucred *cr;
-{
- char *cpoptarg, *cpoptend;
- char *cp, *cpopt, savedc, savedc2;
- char *endcp = NULL; /* XXX: GCC */
- int allflag, usedarg;
-
- cpopt = *cpp;
- cpopt++;
- cp = *endcpp;
- savedc = *cp;
- *cp = '\0';
- while (cpopt && *cpopt) {
- allflag = 1;
- usedarg = -2;
- savedc2 = '\0';
- if ((cpoptend = strchr(cpopt, ',')) != NULL) {
- *cpoptend++ = '\0';
- if ((cpoptarg = strchr(cpopt, '=')) != NULL)
- *cpoptarg++ = '\0';
- } else {
- if ((cpoptarg = strchr(cpopt, '=')) != NULL)
- *cpoptarg++ = '\0';
- else {
- *cp = savedc;
- nextfield(&cp, &endcp);
- **endcpp = '\0';
- if (endcp > cp && *cp != '-') {
- cpoptarg = cp;
- savedc2 = *endcp;
- *endcp = '\0';
- usedarg = 0;
- }
- }
- }
- if (!strcmp(cpopt, "ro") || !strcmp(cpopt, "o")) {
- *exflagsp |= MNT_EXRDONLY;
- } else if (cpoptarg && (!strcmp(cpopt, "maproot") ||
- !(allflag = strcmp(cpopt, "mapall")) ||
- !strcmp(cpopt, "root") || !strcmp(cpopt, "r"))) {
- usedarg++;
- parsecred(cpoptarg, cr);
- if (allflag == 0) {
- *exflagsp |= MNT_EXPORTANON;
- opt_flags |= OP_MAPALL;
- } else
- opt_flags |= OP_MAPROOT;
- } else if (!strcmp(cpopt, "kerb") || !strcmp(cpopt, "k")) {
- *exflagsp |= MNT_EXKERB;
- opt_flags |= OP_KERB;
- } else if (cpoptarg && (!strcmp(cpopt, "mask") ||
- !strcmp(cpopt, "m"))) {
- if (get_net(cpoptarg, &grp->gr_ptr.gt_net, 1)) {
- syslog(LOG_ERR,
- "\"%s\", line %ld: Bad mask: %s",
- line, (unsigned long)lineno, cpoptarg);
- return (1);
- }
- usedarg++;
- opt_flags |= OP_MASK;
- } else if (cpoptarg && (!strcmp(cpopt, "network") ||
- !strcmp(cpopt, "n"))) {
- if (strchr(cpoptarg, '/') != NULL) {
- if (debug)
- fprintf(stderr, "setting OP_MASKLEN\n");
- opt_flags |= OP_MASKLEN;
- }
- if (grp->gr_type != GT_NULL) {
- syslog(LOG_ERR,
- "\"%s\", line %ld: Network/host conflict",
- line, (unsigned long)lineno);
- return (1);
- } else if (get_net(cpoptarg, &grp->gr_ptr.gt_net, 0)) {
- syslog(LOG_ERR,
- "\"%s\", line %ld: Bad net: %s",
- line, (unsigned long)lineno, cpoptarg);
- return (1);
- }
- grp->gr_type = GT_NET;
- *has_hostp = 1;
- usedarg++;
- opt_flags |= OP_NET;
- } else if (!strcmp(cpopt, "alldirs")) {
- opt_flags |= OP_ALLDIRS;
- } else if (!strcmp(cpopt, "noresvmnt")) {
- opt_flags |= OP_NORESMNT;
- } else if (!strcmp(cpopt, "noresvport")) {
- opt_flags |= OP_NORESPORT;
- *exflagsp |= MNT_EXNORESPORT;
- } else if (!strcmp(cpopt, "public")) {
- *exflagsp |= (MNT_EXNORESPORT | MNT_EXPUBLIC);
- opt_flags |= OP_NORESPORT;
- } else if (!strcmp(cpopt, "webnfs")) {
- *exflagsp |= (MNT_EXNORESPORT | MNT_EXPUBLIC |
- MNT_EXRDONLY | MNT_EXPORTANON);
- opt_flags |= (OP_MAPALL | OP_NORESPORT);
- } else if (cpoptarg && !strcmp(cpopt, "index")) {
- ep->ex_indexfile = strdup(cpoptarg);
- } else {
- syslog(LOG_ERR,
- "\"%s\", line %ld: Bad opt %s",
- line, (unsigned long)lineno, cpopt);
- return (1);
- }
- if (usedarg >= 0) {
- *endcp = savedc2;
- **endcpp = savedc;
- if (usedarg > 0) {
- *cpp = cp;
- *endcpp = endcp;
- }
- return (0);
- }
- cpopt = cpoptend;
- }
- **endcpp = savedc;
- return (0);
-}
-
-/*
- * Translate a character string to the corresponding list of network
- * addresses for a hostname.
- */
-static int
-get_host(line, lineno, cp, grp)
- const char *line;
- size_t lineno;
- const char *cp;
- struct grouplist *grp;
-{
- struct addrinfo *ai, hints;
- int ecode;
- char host[NI_MAXHOST];
-
- if (grp->gr_type != GT_NULL) {
- syslog(LOG_ERR,
- "\"%s\", line %ld: Bad netgroup type for ip host %s",
- line, (unsigned long)lineno, cp);
- return (1);
- }
- memset(&hints, 0, sizeof hints);
- hints.ai_flags = AI_CANONNAME;
- hints.ai_protocol = IPPROTO_UDP;
- ecode = getaddrinfo(cp, NULL, &hints, &ai);
- if (ecode != 0) {
- syslog(LOG_ERR, "\"%s\", line %ld: can't get address info for "
- "host %s",
- line, (long)lineno, cp);
- return 1;
- }
- grp->gr_type = GT_HOST;
- grp->gr_ptr.gt_addrinfo = ai;
- while (ai != NULL) {
- if (ai->ai_canonname == NULL) {
- if (getnameinfo(ai->ai_addr, ai->ai_addrlen, host,
- sizeof host, NULL, 0, ninumeric) != 0)
- strlcpy(host, "?", sizeof(host));
- ai->ai_canonname = estrdup(host);
- ai->ai_flags |= AI_CANONNAME;
- } else
- ai->ai_flags &= ~AI_CANONNAME;
- if (debug)
- (void)fprintf(stderr, "got host %s\n", ai->ai_canonname);
- ai = ai->ai_next;
- }
- return (0);
-}
-
-/*
- * Free up an exports list component
- */
-static void
-free_exp(ep)
- struct exportlist *ep;
-{
-
- if (ep->ex_defdir) {
- free_host(ep->ex_defdir->dp_hosts);
- free(ep->ex_defdir);
- }
- if (ep->ex_fsdir)
- free(ep->ex_fsdir);
- if (ep->ex_indexfile)
- free(ep->ex_indexfile);
- free_dir(ep->ex_dirl);
- free(ep);
-}
-
-/*
- * Free hosts.
- */
-static void
-free_host(hp)
- struct hostlist *hp;
-{
- struct hostlist *hp2;
-
- while (hp) {
- hp2 = hp;
- hp = hp->ht_next;
- free(hp2);
- }
-}
-
-static struct hostlist *
-get_ht()
-{
- struct hostlist *hp;
-
- hp = emalloc(sizeof(struct hostlist));
- hp->ht_next = NULL;
- hp->ht_flag = 0;
- return (hp);
-}
-
-/*
- * Do the nfssvc syscall to push the export info into the kernel.
- */
-static int
-do_nfssvc(line, lineno, ep, grp, exflags, anoncrp, dirp, dirplen, fsb)
- const char *line;
- size_t lineno;
- struct exportlist *ep;
- struct grouplist *grp;
- int exflags;
- struct uucred *anoncrp;
- char *dirp;
- int dirplen;
- struct statvfs *fsb;
-{
- struct sockaddr *addrp;
- struct sockaddr_storage ss;
- struct addrinfo *ai;
- int addrlen;
- int done;
- struct export_args export;
-
- export.ex_flags = exflags;
- export.ex_anon = *anoncrp;
- export.ex_indexfile = ep->ex_indexfile;
- if (grp->gr_type == GT_HOST) {
- ai = grp->gr_ptr.gt_addrinfo;
- addrp = ai->ai_addr;
- addrlen = ai->ai_addrlen;
- } else {
- addrp = NULL;
- ai = NULL; /* XXXGCC -Wuninitialized */
- addrlen = 0; /* XXXGCC -Wuninitialized */
- }
- done = FALSE;
- while (!done) {
- struct mountd_exports_list mel;
-
- switch (grp->gr_type) {
- case GT_HOST:
- if (addrp != NULL && addrp->sa_family == AF_INET6 &&
- have_v6 == 0)
- goto skip;
- export.ex_addr = addrp;
- export.ex_addrlen = addrlen;
- export.ex_masklen = 0;
- break;
- case GT_NET:
- export.ex_addr = (struct sockaddr *)
- &grp->gr_ptr.gt_net.nt_net;
- if (export.ex_addr->sa_family == AF_INET6 &&
- have_v6 == 0)
- goto skip;
- export.ex_addrlen = export.ex_addr->sa_len;
- memset(&ss, 0, sizeof ss);
- ss.ss_family = export.ex_addr->sa_family;
- ss.ss_len = export.ex_addr->sa_len;
- if (allones(&ss, grp->gr_ptr.gt_net.nt_len) != 0) {
- syslog(LOG_ERR,
- "\"%s\", line %ld: Bad network flag",
- line, (unsigned long)lineno);
- return (1);
- }
- export.ex_mask = (struct sockaddr *)&ss;
- export.ex_masklen = ss.ss_len;
- break;
- default:
- syslog(LOG_ERR, "\"%s\", line %ld: Bad netgroup type",
- line, (unsigned long)lineno);
- return (1);
- };
-
- /*
- * XXX:
- * Maybe I should just use the fsb->f_mntonname path?
- */
-
- mel.mel_path = dirp;
- mel.mel_nexports = 1;
- mel.mel_exports = &export;
-
- if (rump_sys_nfssvc(NFSSVC_SETEXPORTSLIST, &mel) != 0) {
- syslog(LOG_ERR,
- "\"%s\", line %ld: Can't change attributes for %s to %s: %m %d",
- line, (unsigned long)lineno,
- dirp, (grp->gr_type == GT_HOST) ?
- grp->gr_ptr.gt_addrinfo->ai_canonname :
- (grp->gr_type == GT_NET) ?
- grp->gr_ptr.gt_net.nt_name :
- "Unknown", errno);
- return (1);
- }
-skip:
- if (addrp) {
- ai = ai->ai_next;
- if (ai == NULL)
- done = TRUE;
- else {
- addrp = ai->ai_addr;
- addrlen = ai->ai_addrlen;
- }
- } else
- done = TRUE;
- }
- return (0);
-}
-
-/*
- * Translate a net address.
- */
-static int
-get_net(cp, net, maskflg)
- char *cp;
- struct netmsk *net;
- int maskflg;
-{
- struct netent *np;
- char *thename, *p, *prefp;
- struct sockaddr_in sin, *sinp;
- struct sockaddr *sa;
- struct addrinfo hints, *ai = NULL;
- char netname[NI_MAXHOST];
- long preflen;
- int ecode;
-
- (void)memset(&sin, 0, sizeof(sin));
- if ((opt_flags & OP_MASKLEN) && !maskflg) {
- p = strchr(cp, '/');
- *p = '\0';
- prefp = p + 1;
- } else {
- p = NULL; /* XXXGCC -Wuninitialized */
- prefp = NULL; /* XXXGCC -Wuninitialized */
- }
-
- if ((np = getnetbyname(cp)) != NULL) {
- sin.sin_family = AF_INET;
- sin.sin_len = sizeof sin;
- sin.sin_addr = inet_makeaddr(np->n_net, 0);
- sa = (struct sockaddr *)&sin;
- } else if (isdigit((unsigned char)*cp)) {
- memset(&hints, 0, sizeof hints);
- hints.ai_family = AF_UNSPEC;
- hints.ai_flags = AI_NUMERICHOST;
- if (getaddrinfo(cp, NULL, &hints, &ai) != 0) {
- /*
- * If getaddrinfo() failed, try the inet4 network
- * notation with less than 3 dots.
- */
- sin.sin_family = AF_INET;
- sin.sin_len = sizeof sin;
- sin.sin_addr = inet_makeaddr(inet_network(cp),0);
- if (debug)
- fprintf(stderr, "get_net: v4 addr %x\n",
- sin.sin_addr.s_addr);
- sa = (struct sockaddr *)&sin;
- } else
- sa = ai->ai_addr;
- } else if (isxdigit((unsigned char)*cp) || *cp == ':') {
- memset(&hints, 0, sizeof hints);
- hints.ai_family = AF_UNSPEC;
- hints.ai_flags = AI_NUMERICHOST;
- if (getaddrinfo(cp, NULL, &hints, &ai) == 0)
- sa = ai->ai_addr;
- else
- goto fail;
- } else
- goto fail;
-
- /*
- * Only allow /pref notation for v6 addresses.
- */
- if (sa->sa_family == AF_INET6 && (!(opt_flags & OP_MASKLEN) || maskflg))
- return 1;
-
- ecode = getnameinfo(sa, sa->sa_len, netname, sizeof netname,
- NULL, 0, ninumeric);
- if (ecode != 0)
- goto fail;
-
- if (maskflg)
- net->nt_len = countones(sa);
- else {
- if (opt_flags & OP_MASKLEN) {
- errno = 0;
- preflen = strtol(prefp, NULL, 10);
- if (preflen == LONG_MIN && errno == ERANGE)
- goto fail;
- net->nt_len = (int)preflen;
- *p = '/';
- }
-
- if (np)
- thename = np->n_name;
- else {
- if (getnameinfo(sa, sa->sa_len, netname, sizeof netname,
- NULL, 0, ninumeric) != 0)
- strlcpy(netname, "?", sizeof(netname));
- thename = netname;
- }
- net->nt_name = estrdup(thename);
- memcpy(&net->nt_net, sa, sa->sa_len);
- }
-
- if (!maskflg && sa->sa_family == AF_INET &&
- !(opt_flags & (OP_MASK|OP_MASKLEN))) {
- sinp = (struct sockaddr_in *)sa;
- if (IN_CLASSA(sinp->sin_addr.s_addr))
- net->nt_len = 8;
- else if (IN_CLASSB(sinp->sin_addr.s_addr))
- net->nt_len = 16;
- else if (IN_CLASSC(sinp->sin_addr.s_addr))
- net->nt_len = 24;
- else if (IN_CLASSD(sinp->sin_addr.s_addr))
- net->nt_len = 28;
- else
- net->nt_len = 32; /* XXX */
- }
-
- if (ai)
- freeaddrinfo(ai);
- return 0;
-
-fail:
- if (ai)
- freeaddrinfo(ai);
- return 1;
-}
-
-/*
- * Parse out the next white space separated field
- */
-static void
-nextfield(cp, endcp)
- char **cp;
- char **endcp;
-{
- char *p;
-
- p = *cp;
- while (*p == ' ' || *p == '\t')
- p++;
- if (*p == '\n' || *p == '\0')
- *cp = *endcp = p;
- else {
- *cp = p++;
- while (*p != ' ' && *p != '\t' && *p != '\n' && *p != '\0')
- p++;
- *endcp = p;
- }
-}
-
-/*
- * Parse a description of a credential.
- */
-static void
-parsecred(namelist, cr)
- char *namelist;
- struct uucred *cr;
-{
- char *thename;
- int cnt;
- char *names;
- struct passwd *pw;
- struct group *gr;
- int ngroups;
- gid_t grps[NGROUPS + 1];
-
- /*
- * Set up the unprivileged user.
- */
- *cr = def_anon;
- /*
- * Get the user's password table entry.
- */
- names = strsep(&namelist, " \t\n");
- thename = strsep(&names, ":");
- if (isdigit((unsigned char)*thename) || *thename == '-')
- pw = getpwuid(atoi(thename));
- else
- pw = getpwnam(thename);
- /*
- * Credentials specified as those of a user.
- */
- if (names == NULL) {
- if (pw == NULL) {
- syslog(LOG_ERR, "Unknown user: %s", thename);
- return;
- }
- cr->cr_uid = pw->pw_uid;
- ngroups = NGROUPS + 1;
- if (getgrouplist(pw->pw_name, pw->pw_gid, grps, &ngroups))
- syslog(LOG_ERR, "Too many groups for user %s", thename);
- /*
- * Convert from int's to gid_t's and compress out duplicate
- */
- cr->cr_ngroups = ngroups - 1;
- cr->cr_gid = grps[0];
- for (cnt = 1; cnt < ngroups; cnt++)
- cr->cr_groups[cnt - 1] = grps[cnt];
- return;
- }
- /*
- * Explicit credential specified as a colon separated list:
- * uid:gid:gid:...
- */
- if (pw != NULL)
- cr->cr_uid = pw->pw_uid;
- else if (isdigit((unsigned char)*thename) || *thename == '-')
- cr->cr_uid = atoi(thename);
- else {
- syslog(LOG_ERR, "Unknown user: %s", thename);
- return;
- }
- cr->cr_ngroups = 0;
- while (names != NULL && *names != '\0' && cr->cr_ngroups < NGROUPS) {
- thename = strsep(&names, ":");
- if (isdigit((unsigned char)*thename) || *thename == '-') {
- cr->cr_groups[cr->cr_ngroups++] = atoi(thename);
- } else {
- if ((gr = getgrnam(thename)) == NULL) {
- syslog(LOG_ERR, "Unknown group: %s", thename);
- continue;
- }
- cr->cr_groups[cr->cr_ngroups++] = gr->gr_gid;
- }
- }
- if (names != NULL && *names != '\0' && cr->cr_ngroups == NGROUPS)
- syslog(LOG_ERR, "Too many groups");
-}
-
-#define STRSIZ (RPCMNT_NAMELEN+RPCMNT_PATHLEN+50)
-/*
- * Routines that maintain the remote mounttab
- */
-static void
-get_mountlist()
-{
- struct mountlist *mlp, **mlpp;
- char *host, *dirp, *cp;
- char str[STRSIZ];
- FILE *mlfile;
-
- if ((mlfile = rumpfopen(_PATH_RMOUNTLIST, "r")) == NULL) {
- syslog(LOG_ERR, "Can't open %s: %m", _PATH_RMOUNTLIST);
- return;
- }
- mlpp = &mlhead;
- while (fgets(str, STRSIZ, mlfile) != NULL) {
- cp = str;
- host = strsep(&cp, " \t\n");
- dirp = strsep(&cp, " \t\n");
- if (host == NULL || dirp == NULL)
- continue;
- mlp = emalloc(sizeof(*mlp));
- (void)strncpy(mlp->ml_host, host, RPCMNT_NAMELEN);
- mlp->ml_host[RPCMNT_NAMELEN] = '\0';
- (void)strncpy(mlp->ml_dirp, dirp, RPCMNT_PATHLEN);
- mlp->ml_dirp[RPCMNT_PATHLEN] = '\0';
- mlp->ml_next = NULL;
- *mlpp = mlp;
- mlpp = &mlp->ml_next;
- }
- (void)fclose(mlfile);
-}
-
-static int
-del_mlist(hostp, dirp, saddr)
- char *hostp, *dirp;
- struct sockaddr *saddr;
-{
- struct mountlist *mlp, **mlpp;
- struct mountlist *mlp2;
- u_short sport;
- FILE *mlfile;
- int fnd = 0, ret = 0;
- char host[NI_MAXHOST];
-
- switch (saddr->sa_family) {
- case AF_INET6:
- sport = ntohs(((struct sockaddr_in6 *)saddr)->sin6_port);
- break;
- case AF_INET:
- sport = ntohs(((struct sockaddr_in *)saddr)->sin_port);
- break;
- default:
- return -1;
- }
- mlpp = &mlhead;
- mlp = mlhead;
- while (mlp) {
- if (!strcmp(mlp->ml_host, hostp) &&
- (!dirp || !strcmp(mlp->ml_dirp, dirp))) {
- if (!(mlp->ml_flag & DP_NORESMNT) &&
- sport >= IPPORT_RESERVED) {
- if (getnameinfo(saddr, saddr->sa_len, host,
- sizeof host, NULL, 0, ninumeric) != 0)
- strlcpy(host, "?", sizeof(host));
- syslog(LOG_NOTICE,
- "Umount request for %s:%s from %s refused\n",
- mlp->ml_host, mlp->ml_dirp, host);
- ret = -1;
- goto cont;
- }
- fnd = 1;
- mlp2 = mlp;
- *mlpp = mlp = mlp->ml_next;
- free(mlp2);
- } else {
-cont:
- mlpp = &mlp->ml_next;
- mlp = mlp->ml_next;
- }
- }
- if (fnd) {
- if ((mlfile = rumpfopen(_PATH_RMOUNTLIST, "w")) == NULL) {
- syslog(LOG_ERR, "Can't update %s: %m",
- _PATH_RMOUNTLIST);
- return ret;
- }
- mlp = mlhead;
- while (mlp) {
- (void)fprintf(mlfile, "%s %s\n", mlp->ml_host,
- mlp->ml_dirp);
- mlp = mlp->ml_next;
- }
- (void)fclose(mlfile);
- }
- return ret;
-}
-
-static void
-add_mlist(hostp, dirp, flags)
- char *hostp, *dirp;
- int flags;
-{
- struct mountlist *mlp, **mlpp;
- FILE *mlfile;
-
- mlpp = &mlhead;
- mlp = mlhead;
- while (mlp) {
- if (!strcmp(mlp->ml_host, hostp) && !strcmp(mlp->ml_dirp, dirp))
- return;
- mlpp = &mlp->ml_next;
- mlp = mlp->ml_next;
- }
- mlp = emalloc(sizeof(*mlp));
- strncpy(mlp->ml_host, hostp, RPCMNT_NAMELEN);
- mlp->ml_host[RPCMNT_NAMELEN] = '\0';
- strncpy(mlp->ml_dirp, dirp, RPCMNT_PATHLEN);
- mlp->ml_dirp[RPCMNT_PATHLEN] = '\0';
- mlp->ml_flag = flags;
- mlp->ml_next = NULL;
- *mlpp = mlp;
- if ((mlfile = rumpfopen(_PATH_RMOUNTLIST, "a")) == NULL) {
- syslog(LOG_ERR, "Can't update %s: %m", _PATH_RMOUNTLIST);
- return;
- }
- (void)fprintf(mlfile, "%s %s\n", mlp->ml_host, mlp->ml_dirp);
- (void)fclose(mlfile);
-}
-
-/*
- * This function is called via. SIGTERM when the system is going down.
- * It sends a broadcast RPCMNT_UMNTALL.
- */
-/* ARGSUSED */
-static void
-send_umntall(n)
- int n;
-{
-#if 0
- (void)clnt_broadcast(RPCPROG_MNT, RPCMNT_VER1, RPCMNT_UMNTALL,
- xdr_void, NULL, xdr_void, NULL, (resultproc_t)umntall_each);
-#endif
- exit(0);
-}
-
-#if 0
-static int
-umntall_each(resultsp, raddr)
- caddr_t resultsp;
- struct sockaddr_in *raddr;
-{
- return (1);
-}
-#endif
-
-/*
- * Free up a group list.
- */
-static void
-free_grp(grp)
- struct grouplist *grp;
-{
-
- if (grp->gr_type == GT_HOST) {
- if (grp->gr_ptr.gt_addrinfo != NULL)
- freeaddrinfo(grp->gr_ptr.gt_addrinfo);
- } else if (grp->gr_type == GT_NET) {
- if (grp->gr_ptr.gt_net.nt_name)
- free(grp->gr_ptr.gt_net.nt_name);
- }
- free(grp);
-}
-
-#if 0
-static void
-SYSLOG(int pri, const char *fmt,...)
-{
- va_list ap;
-
- va_start(ap, fmt);
-
- if (debug)
- vfprintf(stderr, fmt, ap);
- else
- vsyslog(pri, fmt, ap);
-
- va_end(ap);
-}
-#endif
-
-/*
- * Check options for consistency.
- */
-static int
-check_options(line, lineno, dp)
- const char *line;
- size_t lineno;
- struct dirlist *dp;
-{
-
- if (dp == NULL) {
- syslog(LOG_ERR,
- "\"%s\", line %ld: missing directory list",
- line, (unsigned long)lineno);
- return (1);
- }
- if ((opt_flags & (OP_MAPROOT|OP_MAPALL)) == (OP_MAPROOT|OP_MAPALL) ||
- (opt_flags & (OP_MAPROOT|OP_KERB)) == (OP_MAPROOT|OP_KERB) ||
- (opt_flags & (OP_MAPALL|OP_KERB)) == (OP_MAPALL|OP_KERB)) {
- syslog(LOG_ERR,
- "\"%s\", line %ld: -mapall, -maproot and -kerb mutually exclusive",
- line, (unsigned long)lineno);
- return (1);
- }
- if ((opt_flags & OP_MASK) && (opt_flags & OP_NET) == 0) {
- syslog(LOG_ERR, "\"%s\", line %ld: -mask requires -net",
- line, (unsigned long)lineno);
- return (1);
- }
- if ((opt_flags & OP_MASK) && (opt_flags & OP_MASKLEN) != 0) {
- syslog(LOG_ERR, "\"%s\", line %ld: /pref and -mask mutually"
- " exclusive",
- line, (unsigned long)lineno);
- return (1);
- }
- if ((opt_flags & OP_ALLDIRS) && dp->dp_left) {
- syslog(LOG_ERR,
- "\"%s\", line %ld: -alldirs has multiple directories",
- line, (unsigned long)lineno);
- return (1);
- }
- return (0);
-}
-
-/*
- * Check an absolute directory path for any symbolic links. Return true
- * if no symbolic links are found.
- */
-static int
-check_dirpath(line, lineno, dirp)
- const char *line;
- size_t lineno;
- char *dirp;
-{
- char *cp;
- struct stat sb;
- char *file = "";
-
- for (cp = dirp + 1; *cp; cp++) {
- if (*cp == '/') {
- *cp = '\0';
- if (rump_sys_lstat(dirp, &sb) == -1)
- goto bad;
- if (!S_ISDIR(sb.st_mode))
- goto bad1;
- *cp = '/';
- }
- }
-
- cp = NULL;
- if (rump_sys_lstat(dirp, &sb) == -1)
- goto bad;
-
- if (!S_ISDIR(sb.st_mode) && !S_ISREG(sb.st_mode)) {
- file = " file or a";
- goto bad1;
- }
-
- return 1;
-
-bad:
- syslog(LOG_ERR,
- "\"%s\", line %ld: lstat for `%s' failed: %m",
- line, (unsigned long)lineno, dirp);
- if (cp)
- *cp = '/';
- return 0;
-
-bad1:
- syslog(LOG_ERR,
- "\"%s\", line %ld: `%s' is not a%s directory",
- line, (unsigned long)lineno, dirp, file);
- abort();
- if (cp)
- *cp = '/';
- return 0;
-}
-
-static void
-bind_resv_port(int sock, sa_family_t family, in_port_t port)
-{
- struct sockaddr *sa;
- struct sockaddr_in sasin;
- struct sockaddr_in6 sasin6;
-
- switch (family) {
- case AF_INET:
- (void)memset(&sasin, 0, sizeof(sasin));
- sasin.sin_len = sizeof(sasin);
- sasin.sin_family = family;
- sasin.sin_port = htons(port);
- sa = (struct sockaddr *)(void *)&sasin;
- break;
- case AF_INET6:
- (void)memset(&sasin6, 0, sizeof(sasin6));
- sasin6.sin6_len = sizeof(sasin6);
- sasin6.sin6_family = family;
- sasin6.sin6_port = htons(port);
- sa = (struct sockaddr *)(void *)&sasin6;
- break;
- default:
- syslog(LOG_ERR, "Unsupported address family %d", family);
- return;
- }
- if (bindresvport_sa(sock, sa) == -1)
- syslog(LOG_ERR, "Cannot bind to reserved port %d (%m)", port);
-}
-
-/* ARGSUSED */
-static void
-no_nfs(int sig)
-{
- syslog(LOG_ERR, "kernel NFS support not present; exiting");
- exit(1);
-}
diff --git a/contrib/netbsd-tests/fs/nfs/nfsservice/nfsd.c b/contrib/netbsd-tests/fs/nfs/nfsservice/nfsd.c
deleted file mode 100644
index b062501..0000000
--- a/contrib/netbsd-tests/fs/nfs/nfsservice/nfsd.c
+++ /dev/null
@@ -1,571 +0,0 @@
-/* $NetBSD: nfsd.c,v 1.4 2013/10/19 17:45:00 christos Exp $ */
-
-/*
- * Copyright (c) 1989, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Rick Macklem at The University of Guelph.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <sys/cdefs.h>
-#ifndef lint
-__COPYRIGHT("@(#) Copyright (c) 1989, 1993, 1994\
- The Regents of the University of California. All rights reserved.");
-#endif /* not lint */
-
-#ifndef lint
-#if 0
-static char sccsid[] = "@(#)nfsd.c 8.9 (Berkeley) 3/29/95";
-#else
-__RCSID("$NetBSD: nfsd.c,v 1.4 2013/10/19 17:45:00 christos Exp $");
-#endif
-#endif /* not lint */
-
-#include <sys/param.h>
-#include <sys/ioctl.h>
-#include <sys/stat.h>
-#include <sys/wait.h>
-#include <sys/uio.h>
-#include <sys/ucred.h>
-#include <sys/mount.h>
-#include <sys/socket.h>
-#include <sys/socketvar.h>
-#include <poll.h>
-
-#include <rpc/rpc.h>
-#include <rpc/pmap_clnt.h>
-#include <rpc/pmap_prot.h>
-
-#include <nfs/rpcv2.h>
-#include <nfs/nfsproto.h>
-#include <nfs/nfs.h>
-
-#include <err.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <grp.h>
-#include <pwd.h>
-#include <pthread.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <syslog.h>
-#include <unistd.h>
-#include <netdb.h>
-
-#include <rump/rump.h>
-#include <rump/rump_syscalls.h>
-
-/* Global defs */
-#ifdef DEBUG
-#define syslog(e, s, args...) \
-do { \
- fprintf(stderr,(s), ## args); \
- fprintf(stderr, "\n"); \
-} while (/*CONSTCOND*/0)
-int debug = 1;
-#else
-int debug = 0;
-#endif
-
-int main __P((int, char **));
-void nonfs __P((int));
-void usage __P((void));
-
-static void *
-child(void *arg)
-{
- struct nfsd_srvargs nsd;
- int nfssvc_flag;
-
- nfssvc_flag = NFSSVC_NFSD;
- memset(&nsd, 0, sizeof(nsd));
- while (rump_sys_nfssvc(nfssvc_flag, &nsd) < 0) {
- if (errno != ENEEDAUTH) {
- syslog(LOG_ERR, "nfssvc: %m %d", errno);
- exit(1);
- }
- nfssvc_flag = NFSSVC_NFSD | NFSSVC_AUTHINFAIL;
- }
-
- return NULL;
-}
-
-/*
- * Nfs server daemon mostly just a user context for nfssvc()
- *
- * 1 - do file descriptor and signal cleanup
- * 2 - create the nfsd thread(s)
- * 3 - create server socket(s)
- * 4 - register socket with portmap
- *
- * For connectionless protocols, just pass the socket into the kernel via
- * nfssvc().
- * For connection based sockets, loop doing accepts. When you get a new
- * socket from accept, pass the msgsock into the kernel via nfssvc().
- * The arguments are:
- * -c - support iso cltp clients
- * -r - reregister with portmapper
- * -t - support tcp nfs clients
- * -u - support udp nfs clients
- * followed by "n" which is the number of nfsd threads to create
- */
-int nfsd_main(int, char**);
-int
-nfsd_main(argc, argv)
- int argc;
- char *argv[];
-{
- struct nfsd_args nfsdargs;
- struct addrinfo *ai_udp, *ai_tcp, *ai_udp6, *ai_tcp6, hints;
- struct netconfig *nconf_udp, *nconf_tcp, *nconf_udp6, *nconf_tcp6;
- struct netbuf nb_udp, nb_tcp, nb_udp6, nb_tcp6;
- struct sockaddr_in inetpeer;
- struct pollfd set[4];
- socklen_t len;
- int ch, connect_type_cnt, i, msgsock;
- int nfsdcnt, on = 1, reregister, sock, tcpflag, tcpsock;
- int tcp6sock, ip6flag;
- int tp4cnt, tp4flag, tpipcnt, udpflag, ecode, s;
- int error = 0;
-
-#define DEFNFSDCNT 4
- nfsdcnt = DEFNFSDCNT;
- reregister = tcpflag = tp4cnt = tp4flag = tpipcnt = 0;
- udpflag = ip6flag = 0;
- nconf_udp = nconf_tcp = nconf_udp6 = nconf_tcp6 = NULL;
- tcpsock = tcp6sock = -1;
-#define GETOPT "6n:rtu"
-#define USAGE "[-rtu] [-n num_servers]"
- while ((ch = getopt(argc, argv, GETOPT)) != -1) {
- switch (ch) {
- case '6':
- ip6flag = 1;
- s = socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP);
- if (s < 0 && (errno == EPROTONOSUPPORT ||
- errno == EPFNOSUPPORT || errno == EAFNOSUPPORT))
- ip6flag = 0;
- else
- close(s);
- break;
- case 'n':
- nfsdcnt = atoi(optarg);
- if (nfsdcnt < 1) {
- warnx("nfsd count %d; reset to %d", nfsdcnt, DEFNFSDCNT);
- nfsdcnt = DEFNFSDCNT;
- }
- break;
- case 'r':
- reregister = 1;
- break;
- case 't':
- tcpflag = 1;
- break;
- case 'u':
- udpflag = 1;
- break;
- default:
- case '?':
- usage();
- };
- }
- argv += optind;
- argc -= optind;
-
- /*
- * XXX
- * Backward compatibility, trailing number is the count of daemons.
- */
- if (argc > 1)
- usage();
- if (argc == 1) {
- nfsdcnt = atoi(argv[0]);
- if (nfsdcnt < 1) {
- warnx("nfsd count %d; reset to %d", nfsdcnt, DEFNFSDCNT);
- nfsdcnt = DEFNFSDCNT;
- }
- }
-
- /*
- * If none of TCP or UDP are specified, default to UDP only.
- */
- if (tcpflag == 0 && udpflag == 0)
- udpflag = 1;
-
- if (debug == 0) {
- fprintf(stderr, "non-debug not supported here\n");
- exit(1);
-
-#ifdef not_the_debug_man
- daemon(0, 0);
- (void)signal(SIGHUP, SIG_IGN);
- (void)signal(SIGINT, SIG_IGN);
- (void)signal(SIGQUIT, SIG_IGN);
- (void)signal(SIGSYS, nonfs);
-#endif
- }
-
- if (udpflag) {
- memset(&hints, 0, sizeof hints);
- hints.ai_flags = AI_PASSIVE;
- hints.ai_family = PF_INET;
- hints.ai_socktype = SOCK_DGRAM;
- hints.ai_protocol = IPPROTO_UDP;
-
- ecode = getaddrinfo(NULL, "nfs", &hints, &ai_udp);
- if (ecode != 0) {
- syslog(LOG_ERR, "getaddrinfo udp: %s",
- gai_strerror(ecode));
- exit(1);
- }
-
- nconf_udp = getnetconfigent("udp");
-
- if (nconf_udp == NULL)
- err(1, "getnetconfigent udp failed");
-
- nb_udp.buf = ai_udp->ai_addr;
- nb_udp.len = nb_udp.maxlen = ai_udp->ai_addrlen;
- if (reregister)
- if (!rpcb_set(RPCPROG_NFS, 2, nconf_udp, &nb_udp))
- err(1, "rpcb_set udp failed");
- }
-
- if (tcpflag) {
- memset(&hints, 0, sizeof hints);
- hints.ai_flags = AI_PASSIVE;
- hints.ai_family = PF_INET;
- hints.ai_socktype = SOCK_STREAM;
- hints.ai_protocol = IPPROTO_TCP;
-
- ecode = getaddrinfo(NULL, "nfs", &hints, &ai_tcp);
- if (ecode != 0) {
- syslog(LOG_ERR, "getaddrinfo tcp: %s",
- gai_strerror(ecode));
- exit(1);
- }
-
- nconf_tcp = getnetconfigent("tcp");
-
- if (nconf_tcp == NULL)
- err(1, "getnetconfigent tcp failed");
-
- nb_tcp.buf = ai_tcp->ai_addr;
- nb_tcp.len = nb_tcp.maxlen = ai_tcp->ai_addrlen;
- if (reregister)
- if (!rpcb_set(RPCPROG_NFS, 2, nconf_tcp, &nb_tcp))
- err(1, "rpcb_set tcp failed");
- }
-
- if (udpflag && ip6flag) {
- memset(&hints, 0, sizeof hints);
- hints.ai_flags = AI_PASSIVE;
- hints.ai_family = PF_INET6;
- hints.ai_socktype = SOCK_DGRAM;
- hints.ai_protocol = IPPROTO_UDP;
-
- ecode = getaddrinfo(NULL, "nfs", &hints, &ai_udp6);
- if (ecode != 0) {
- syslog(LOG_ERR, "getaddrinfo udp: %s",
- gai_strerror(ecode));
- exit(1);
- }
-
- nconf_udp6 = getnetconfigent("udp6");
-
- if (nconf_udp6 == NULL)
- err(1, "getnetconfigent udp6 failed");
-
- nb_udp6.buf = ai_udp6->ai_addr;
- nb_udp6.len = nb_udp6.maxlen = ai_udp6->ai_addrlen;
- if (reregister)
- if (!rpcb_set(RPCPROG_NFS, 2, nconf_udp6, &nb_udp6))
- err(1, "rpcb_set udp6 failed");
- }
-
- if (tcpflag && ip6flag) {
- memset(&hints, 0, sizeof hints);
- hints.ai_flags = AI_PASSIVE;
- hints.ai_family = PF_INET6;
- hints.ai_socktype = SOCK_STREAM;
- hints.ai_protocol = IPPROTO_TCP;
-
- ecode = getaddrinfo(NULL, "nfs", &hints, &ai_tcp6);
- if (ecode != 0) {
- syslog(LOG_ERR, "getaddrinfo tcp: %s",
- gai_strerror(ecode));
- exit(1);
- }
-
- nconf_tcp6 = getnetconfigent("tcp6");
-
- if (nconf_tcp6 == NULL)
- err(1, "getnetconfigent tcp6 failed");
-
- nb_tcp6.buf = ai_tcp6->ai_addr;
- nb_tcp6.len = nb_tcp6.maxlen = ai_tcp6->ai_addrlen;
- if (reregister)
- if (!rpcb_set(RPCPROG_NFS, 2, nconf_tcp6, &nb_tcp6))
- err(1, "rpcb_set tcp6 failed");
- }
-
- openlog("nfsd", LOG_PID, LOG_DAEMON);
-
- for (i = 0; i < nfsdcnt; i++) {
- pthread_t t;
- pthread_create(&t, NULL, child, NULL);
- }
-
- /* If we are serving udp, set up the socket. */
- if (udpflag) {
- if ((sock = rump_sys_socket(ai_udp->ai_family, ai_udp->ai_socktype,
- ai_udp->ai_protocol)) < 0) {
- syslog(LOG_ERR, "can't create udp socket");
- exit(1);
- }
- if (bind(sock, ai_udp->ai_addr, ai_udp->ai_addrlen) < 0) {
- syslog(LOG_ERR, "can't bind udp addr");
- exit(1);
- }
- if (!rpcb_set(RPCPROG_NFS, 2, nconf_udp, &nb_udp) ||
- !rpcb_set(RPCPROG_NFS, 3, nconf_udp, &nb_udp)) {
- syslog(LOG_ERR, "can't register with udp portmap");
- exit(1);
- }
- nfsdargs.sock = sock;
- nfsdargs.name = NULL;
- nfsdargs.namelen = 0;
- if (rump_sys_nfssvc(NFSSVC_ADDSOCK, &nfsdargs) < 0) {
- syslog(LOG_ERR, "can't add UDP socket");
- exit(1);
- }
- (void)rump_sys_close(sock);
- }
-
- if (udpflag &&ip6flag) {
- if ((sock = rump_sys_socket(ai_udp6->ai_family, ai_udp6->ai_socktype,
- ai_udp6->ai_protocol)) < 0) {
- syslog(LOG_ERR, "can't create udp socket");
- exit(1);
- }
- if (rump_sys_setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY,
- &on, sizeof on) < 0) {
- syslog(LOG_ERR, "can't set v6-only binding for udp6 "
- "socket: %m");
- exit(1);
- }
- if (rump_sys_bind(sock, ai_udp6->ai_addr, ai_udp6->ai_addrlen) < 0) {
- syslog(LOG_ERR, "can't bind udp addr");
- exit(1);
- }
- if (!rpcb_set(RPCPROG_NFS, 2, nconf_udp6, &nb_udp6) ||
- !rpcb_set(RPCPROG_NFS, 3, nconf_udp6, &nb_udp6)) {
- syslog(LOG_ERR, "can't register with udp portmap");
- exit(1);
- }
- nfsdargs.sock = sock;
- nfsdargs.name = NULL;
- nfsdargs.namelen = 0;
- if (rump_sys_nfssvc(NFSSVC_ADDSOCK, &nfsdargs) < 0) {
- syslog(LOG_ERR, "can't add UDP6 socket");
- exit(1);
- }
- (void)rump_sys_close(sock);
- }
-
- /* Now set up the master server socket waiting for tcp connections. */
- on = 1;
- connect_type_cnt = 0;
- if (tcpflag) {
- if ((tcpsock = rump_sys_socket(ai_tcp->ai_family, ai_tcp->ai_socktype,
- ai_tcp->ai_protocol)) < 0) {
- syslog(LOG_ERR, "can't create tcp socket");
- exit(1);
- }
- if (setsockopt(tcpsock,
- SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) < 0)
- syslog(LOG_ERR, "setsockopt SO_REUSEADDR: %m");
- if (bind(tcpsock, ai_tcp->ai_addr, ai_tcp->ai_addrlen) < 0) {
- syslog(LOG_ERR, "can't bind tcp addr");
- exit(1);
- }
- if (rump_sys_listen(tcpsock, 5) < 0) {
- syslog(LOG_ERR, "listen failed");
- exit(1);
- }
- if (!rpcb_set(RPCPROG_NFS, 2, nconf_tcp, &nb_tcp) ||
- !rpcb_set(RPCPROG_NFS, 3, nconf_tcp, &nb_tcp)) {
- syslog(LOG_ERR, "can't register tcp with rpcbind");
- exit(1);
- }
- set[0].fd = tcpsock;
- set[0].events = POLLIN;
- connect_type_cnt++;
- } else
- set[0].fd = -1;
-
- if (tcpflag && ip6flag) {
- if ((tcp6sock = socket(ai_tcp6->ai_family, ai_tcp6->ai_socktype,
- ai_tcp6->ai_protocol)) < 0) {
- syslog(LOG_ERR, "can't create tcp socket");
- exit(1);
- }
- if (setsockopt(tcp6sock,
- SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) < 0)
- syslog(LOG_ERR, "setsockopt SO_REUSEADDR: %m");
- if (setsockopt(tcp6sock, IPPROTO_IPV6, IPV6_V6ONLY,
- &on, sizeof on) < 0) {
- syslog(LOG_ERR, "can't set v6-only binding for tcp6 "
- "socket: %m");
- exit(1);
- }
- if (bind(tcp6sock, ai_tcp6->ai_addr, ai_tcp6->ai_addrlen) < 0) {
- syslog(LOG_ERR, "can't bind tcp6 addr");
- exit(1);
- }
- if (listen(tcp6sock, 5) < 0) {
- syslog(LOG_ERR, "listen failed");
- exit(1);
- }
- if (!rpcb_set(RPCPROG_NFS, 2, nconf_tcp6, &nb_tcp6) ||
- !rpcb_set(RPCPROG_NFS, 3, nconf_tcp6, &nb_tcp6)) {
- syslog(LOG_ERR, "can't register tcp6 with rpcbind");
- exit(1);
- }
- set[1].fd = tcp6sock;
- set[1].events = POLLIN;
- connect_type_cnt++;
- } else
- set[1].fd = -1;
-
- set[2].fd = -1;
- set[3].fd = -1;
-
- if (connect_type_cnt == 0) {
- pause();
- exit(0);
- }
-
- /*
- * Loop forever accepting connections and passing the sockets
- * into the kernel for the mounts.
- */
- for (;;) {
- if (rump_sys_poll(set, 4, INFTIM) < 1) {
- syslog(LOG_ERR, "poll failed: %m");
- exit(1);
- }
-
- len = sizeof(inetpeer);
- if ((msgsock = accept(tcpsock,
- (struct sockaddr *)&inetpeer, &len)) < 0) {
- syslog(LOG_ERR, "accept failed: %d", error);
- exit(1);
- }
- memset(inetpeer.sin_zero, 0, sizeof(inetpeer.sin_zero));
- if (setsockopt(msgsock, SOL_SOCKET,
- SO_KEEPALIVE, (char *)&on, sizeof(on)) < 0)
- syslog(LOG_ERR,
- "setsockopt SO_KEEPALIVE: %m");
- nfsdargs.sock = msgsock;
- nfsdargs.name = (caddr_t)&inetpeer;
- nfsdargs.namelen = sizeof(inetpeer);
- rump_sys_nfssvc(NFSSVC_ADDSOCK, &nfsdargs);
- (void)rump_sys_close(msgsock);
-
-#ifdef notyet
- if (set[1].revents & POLLIN) {
- len = sizeof(inet6peer);
- if ((msgsock = rump_sys_accept(tcp6sock,
- (struct sockaddr *)&inet6peer, &len, &error)) < 0) {
- syslog(LOG_ERR, "accept failed: %m");
- exit(1);
- }
- if (rump_sys_setsockopt(msgsock, SOL_SOCKET,
- SO_KEEPALIVE, (char *)&on, sizeof(on), &error) < 0)
- syslog(LOG_ERR,
- "setsockopt SO_KEEPALIVE: %m");
- nfsdargs.sock = msgsock;
- nfsdargs.name = (caddr_t)&inet6peer;
- nfsdargs.namelen = sizeof(inet6peer);
- rump_sys_nfssvc(NFSSVC_ADDSOCK, &nfsdargs, &error);
- (void)rump_sys_close(msgsock, &error);
- }
-
- if (set[2].revents & POLLIN) {
- len = sizeof(isopeer);
- if ((msgsock = rump_sys_accept(tp4sock,
- (struct sockaddr *)&isopeer, &len, &error)) < 0) {
- syslog(LOG_ERR, "accept failed: %m");
- exit(1);
- }
- if (rump_sys_setsockopt(msgsock, SOL_SOCKET,
- SO_KEEPALIVE, (char *)&on, sizeof(on), &error) < 0)
- syslog(LOG_ERR,
- "setsockopt SO_KEEPALIVE: %m");
- nfsdargs.sock = msgsock;
- nfsdargs.name = (caddr_t)&isopeer;
- nfsdargs.namelen = len;
- rump_sys_nfssvc(NFSSVC_ADDSOCK, &nfsdargs, &error);
- (void)rump_sys_close(msgsock, &error);
- }
-
- if (set[3].revents & POLLIN) {
- len = sizeof(inetpeer);
- if ((msgsock = rump_sys_accept(tpipsock,
- (struct sockaddr *)&inetpeer, &len)) < 0) {
- syslog(LOG_ERR, "accept failed: %m");
- exit(1);
- }
- if (setsockopt(msgsock, SOL_SOCKET,
- SO_KEEPALIVE, (char *)&on, sizeof(on)) < 0)
- syslog(LOG_ERR, "setsockopt SO_KEEPALIVE: %m");
- nfsdargs.sock = msgsock;
- nfsdargs.name = (caddr_t)&inetpeer;
- nfsdargs.namelen = len;
- rump_sys_nfssvc(NFSSVC_ADDSOCK, &nfsdargs);
- (void)rump_sys_close(msgsock);
- }
-#endif /* notyet */
- }
-}
-
-void
-usage()
-{
- (void)fprintf(stderr, "usage: nfsd %s\n", USAGE);
- exit(1);
-}
-
-void
-nonfs(signo)
- int signo;
-{
- syslog(LOG_ERR, "missing system call: NFS not available.");
-}
diff --git a/contrib/netbsd-tests/fs/nfs/nfsservice/rumpnfsd.c b/contrib/netbsd-tests/fs/nfs/nfsservice/rumpnfsd.c
index 337a06e..5f8e152 100644
--- a/contrib/netbsd-tests/fs/nfs/nfsservice/rumpnfsd.c
+++ b/contrib/netbsd-tests/fs/nfs/nfsservice/rumpnfsd.c
@@ -1,4 +1,4 @@
-/* $NetBSD: rumpnfsd.c,v 1.8 2014/05/12 15:31:07 christos Exp $ */
+/* $NetBSD: rumpnfsd.c,v 1.9 2015/11/08 02:45:16 christos Exp $ */
/*-
* Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -37,6 +37,7 @@
#include <string.h>
#include <syslog.h>
#include <unistd.h>
+#include <rpc/rpc.h>
void *mountd_main(void *);
void *rpcbind_main(void *);
@@ -87,7 +88,7 @@ main(int argc, char *argv[])
}
rump_init();
- init_fdsets();
+ svc_fdset_init(SVC_FDSET_MT);
rv = rump_pub_etfs_register("/etc/exports", "./exports", RUMP_ETFS_REG);
if (rv) {
diff --git a/contrib/netbsd-tests/fs/nfs/t_rquotad.sh b/contrib/netbsd-tests/fs/nfs/t_rquotad.sh
index 05d34fb..dc9226c 100755
--- a/contrib/netbsd-tests/fs/nfs/t_rquotad.sh
+++ b/contrib/netbsd-tests/fs/nfs/t_rquotad.sh
@@ -1,4 +1,4 @@
-# $NetBSD: t_rquotad.sh,v 1.4 2014/03/13 12:45:14 gson Exp $
+# $NetBSD: t_rquotad.sh,v 1.5 2016/08/10 23:25:39 kre Exp $
#
# Copyright (c) 2011 Manuel Bouyer
# All rights reserved.
@@ -114,7 +114,7 @@ get_nfs_quota()
unset RUMPHIJACK
unset LD_PRELOAD
- atf_check -s exit:0 rump_server -lrumpvfs -lrumpnet \
+ atf_check -s exit:0 rump_server -lrumpvfs -lrumpnet -lrumpdev \
-lrumpnet_net -lrumpnet_netinet -lrumpnet_shmif -lrumpfs_nfs\
${RUMP_SERVER}
diff --git a/contrib/netbsd-tests/fs/psshfs/t_psshfs.sh b/contrib/netbsd-tests/fs/psshfs/t_psshfs.sh
index 241d46d..4d8fede 100755
--- a/contrib/netbsd-tests/fs/psshfs/t_psshfs.sh
+++ b/contrib/netbsd-tests/fs/psshfs/t_psshfs.sh
@@ -1,4 +1,4 @@
-# $NetBSD: t_psshfs.sh,v 1.7 2013/03/16 07:54:04 jmmv Exp $
+# $NetBSD: t_psshfs.sh,v 1.8 2016/09/05 08:53:57 christos Exp $
#
# Copyright (c) 2007, 2008 The NetBSD Foundation, Inc.
# All rights reserved.
@@ -262,6 +262,26 @@ setattr_cache_cleanup() {
stop_ssh
}
+atf_test_case read_empty_file cleanup
+read_empty_file_head() {
+ atf_set "descr" "Checks whether an empty file can be read"
+ # This test is supposed to make sure psshfs does not hang
+ # when reading from an empty file, hence the timeout.
+ atf_set "timeout" 8
+}
+read_empty_file_body() {
+ require_puffs
+ start_ssh
+ atf_check mkdir root mnt
+ atf_check -x ': > root/empty'
+ mount_psshfs root mnt
+ atf_check cat mnt/empty
+}
+read_empty_file_cleanup() {
+ umount mnt
+ stop_ssh
+}
+
# -------------------------------------------------------------------------
# Initialization.
# -------------------------------------------------------------------------
@@ -271,4 +291,5 @@ atf_init_test_cases() {
atf_add_test_case pwd
atf_add_test_case ls
#atf_add_test_case setattr_cache
+ atf_add_test_case read_empty_file
}
diff --git a/contrib/netbsd-tests/fs/puffs/t_basic.c b/contrib/netbsd-tests/fs/puffs/t_basic.c
index ce5e4ea..735108d 100644
--- a/contrib/netbsd-tests/fs/puffs/t_basic.c
+++ b/contrib/netbsd-tests/fs/puffs/t_basic.c
@@ -1,4 +1,4 @@
-/* $NetBSD: t_basic.c,v 1.12 2013/10/19 17:45:00 christos Exp $ */
+/* $NetBSD: t_basic.c,v 1.13 2016/12/01 14:49:04 hannken Exp $ */
#include <sys/types.h>
#include <sys/mount.h>
@@ -286,7 +286,7 @@ ATF_TC_BODY(inactive_reclaim, tc)
rump_sys_close(fd);
syncbar(FSTEST_MNTNAME);
- ATF_REQUIRE_EQ(pargs->pta_vn_toserv_ops[PUFFS_VN_INACTIVE], 1);
+ ATF_REQUIRE(pargs->pta_vn_toserv_ops[PUFFS_VN_INACTIVE] > 0);
ATF_REQUIRE_EQ(pargs->pta_vn_toserv_ops[PUFFS_VN_RECLAIM], 1);
FSTEST_EXIT();
@@ -383,7 +383,7 @@ ATF_TC_BODY(unlink_accessible, tc)
syncbar(FSTEST_MNTNAME);
ATF_REQUIRE_EQ(pargs->pta_vn_toserv_ops[PUFFS_VN_RECLAIM], 1);
- ATF_REQUIRE_EQ(pargs->pta_vn_toserv_ops[PUFFS_VN_INACTIVE], ianow+1);
+ ATF_REQUIRE(pargs->pta_vn_toserv_ops[PUFFS_VN_INACTIVE] > ianow);
ATF_REQUIRE_STREQ(buf, MAGICSTR);
diff --git a/contrib/netbsd-tests/fs/tmpfs/h_funcs.subr b/contrib/netbsd-tests/fs/tmpfs/h_funcs.subr
index 07c1644..edab789 100644
--- a/contrib/netbsd-tests/fs/tmpfs/h_funcs.subr
+++ b/contrib/netbsd-tests/fs/tmpfs/h_funcs.subr
@@ -59,12 +59,31 @@ test_mount() {
# Unmounts the file system mounted by test_mount.
#
test_unmount() {
+ # Begin FreeBSD
+ _test_unmount
+ exit_code=$?
+ atf_check_equal "$exit_code" "0"
+ return $exit_code
+ # End FreeBSD
cd - >/dev/null
atf_check -s eq:0 -o empty -e empty umount ${Mount_Point}
atf_check -s eq:0 -o empty -e empty rmdir ${Mount_Point}
Mount_Point=
}
+# Begin FreeBSD
+_test_unmount() {
+ if [ -z "${Mount_Point}" -o ! -d "${Mount_Point}" ]; then
+ return 0
+ fi
+
+ cd - >/dev/null
+ umount ${Mount_Point}
+ rmdir ${Mount_Point}
+ Mount_Point=
+}
+# End FreeBSD
+
#
# kqueue_monitor expected_nevents file1 [.. fileN]
#
diff --git a/contrib/netbsd-tests/fs/tmpfs/h_tools.c b/contrib/netbsd-tests/fs/tmpfs/h_tools.c
index 6a7b8fd..492e084 100644
--- a/contrib/netbsd-tests/fs/tmpfs/h_tools.c
+++ b/contrib/netbsd-tests/fs/tmpfs/h_tools.c
@@ -50,6 +50,10 @@
#include <string.h>
#include <unistd.h>
+#ifdef __FreeBSD__
+#include <inttypes.h>
+#endif
+
/* --------------------------------------------------------------------- */
static int getfh_main(int, char **);
@@ -70,7 +74,12 @@ getfh_main(int argc, char **argv)
if (argc < 2)
return EXIT_FAILURE;
+#ifdef __FreeBSD__
+ fh_size = sizeof(fhandle_t);
+#else
fh_size = 0;
+#endif
+
fh = NULL;
for (;;) {
if (fh_size) {
@@ -85,7 +94,11 @@ getfh_main(int argc, char **argv)
* but it may change if someone moves things around,
* so retry untill we have enough memory.
*/
+#ifdef __FreeBSD__
+ error = getfh(argv[1], fh);
+#else
error = getfh(argv[1], fh, &fh_size);
+#endif
if (error == 0) {
break;
} else {
@@ -230,12 +243,21 @@ sockets_main(int argc, char **argv)
return EXIT_FAILURE;
}
+#ifdef __FreeBSD__
+ memset(&addr, 0, sizeof(addr));
+#endif
(void)strlcpy(addr.sun_path, argv[1], sizeof(addr.sun_path));
addr.sun_family = PF_UNIX;
-
+#ifdef __FreeBSD__
+ error = bind(fd, (struct sockaddr *)&addr, SUN_LEN(&addr));
+#else
error = bind(fd, (struct sockaddr *)&addr, sizeof(addr));
+#endif
if (error == -1) {
warn("connect");
+#ifdef __FreeBSD__
+ (void)close(fd);
+#endif
return EXIT_FAILURE;
}
diff --git a/contrib/netbsd-tests/fs/tmpfs/t_link.sh b/contrib/netbsd-tests/fs/tmpfs/t_link.sh
index 660f3f2..612c1e2 100755
--- a/contrib/netbsd-tests/fs/tmpfs/t_link.sh
+++ b/contrib/netbsd-tests/fs/tmpfs/t_link.sh
@@ -93,7 +93,18 @@ subdirs_body() {
test_unmount
}
+# Begin FreeBSD
+if true; then
+atf_test_case kqueue cleanup
+kqueue_cleanup() {
+ Mount_Point=$(pwd)/mntpt _test_unmount || :
+}
+else
+# End FreeBSD
atf_test_case kqueue
+# Begin FreeBSD
+fi
+# End FreeBSD
kqueue_head() {
atf_set "descr" "Verifies that creating a link raises the correct" \
"kqueue events"
@@ -102,6 +113,10 @@ kqueue_head() {
kqueue_body() {
test_mount
+ # Begin FreeBSD
+ atf_expect_fail "fails with: dir/b did not receive NOTE_LINK - bug 213662"
+ # End FreeBSD
+
atf_check -s eq:0 -o empty -e empty mkdir dir
atf_check -s eq:0 -o empty -e empty touch dir/a
echo 'ln dir/a dir/b' | kqueue_monitor 2 dir dir/a
diff --git a/contrib/netbsd-tests/fs/tmpfs/t_mknod.sh b/contrib/netbsd-tests/fs/tmpfs/t_mknod.sh
index 62c7cce..037dc16 100755
--- a/contrib/netbsd-tests/fs/tmpfs/t_mknod.sh
+++ b/contrib/netbsd-tests/fs/tmpfs/t_mknod.sh
@@ -106,7 +106,15 @@ pipe_body() {
test_mount
umask 022
+ # Begin FreeBSD
+ if true; then
+ atf_check -s eq:0 -o empty -e empty mkfifo pipe
+ else
+ # End FreeBSD
atf_check -s eq:0 -o empty -e empty mknod pipe p
+ # Begin FreeBSD
+ fi
+ # End FreeBSD
eval $(stat -s pipe)
[ ${st_mode} = 010644 ] || atf_fail "Invalid mode"
@@ -124,7 +132,15 @@ pipe_kqueue_body() {
umask 022
atf_check -s eq:0 -o empty -e empty mkdir dir
+ # Begin FreeBSD
+ if true; then
+ echo 'mkfifo dir/pipe' | kqueue_monitor 1 dir
+ else
+ # End FreeBSD
echo 'mknod dir/pipe p' | kqueue_monitor 1 dir
+ # Begin FreeBSD
+ fi
+ # End FreeBSD
kqueue_check dir NOTE_WRITE
test_unmount
diff --git a/contrib/netbsd-tests/fs/tmpfs/t_mount.sh b/contrib/netbsd-tests/fs/tmpfs/t_mount.sh
index 11a77d4..9ec5e31 100755
--- a/contrib/netbsd-tests/fs/tmpfs/t_mount.sh
+++ b/contrib/netbsd-tests/fs/tmpfs/t_mount.sh
@@ -93,7 +93,19 @@ negative_body() {
test_unmount
}
+# Begin FreeBSD
+if true; then
+atf_test_case large cleanup
+large_cleanup() {
+ umount -f tmp 2>/dev/null || :
+ Mount_Point=$(pwd)/mnt _test_unmount || :
+}
+else
+# End FreeBSD
atf_test_case large
+# Begin FreeBSD
+fi
+# End FreeBSD
large_head() {
atf_set "descr" "Tests that extremely long values passed to -s" \
"are handled correctly"
@@ -103,6 +115,10 @@ large_body() {
test_mount -o -s9223372036854775807
test_unmount
+ # Begin FreeBSD
+ atf_expect_fail "-o -s<large-size> succeeds unexpectedly on FreeBSD - bug 212862"
+ # End FreeBSD
+
mkdir tmp
atf_check -s eq:1 -o empty -e ignore \
mount -t tmpfs -o -s9223372036854775808 tmpfs tmp
diff --git a/contrib/netbsd-tests/fs/tmpfs/t_readdir.sh b/contrib/netbsd-tests/fs/tmpfs/t_readdir.sh
index 6f5dc3e..272c749 100755
--- a/contrib/netbsd-tests/fs/tmpfs/t_readdir.sh
+++ b/contrib/netbsd-tests/fs/tmpfs/t_readdir.sh
@@ -59,7 +59,15 @@ types_body() {
atf_check -s eq:0 -o empty -e empty ln -s reg lnk
atf_check -s eq:0 -o empty -e empty mknod blk b 0 0
atf_check -s eq:0 -o empty -e empty mknod chr c 0 0
+ # Begin FreeBSD
+ if true; then
+ atf_check -s eq:0 -o empty -e empty mkfifo fifo
+ else
+ # End FreeBSD
atf_check -s eq:0 -o empty -e empty mknod fifo p
+ # Begin FreeBSD
+ fi
+ # End FreeBSD
atf_check -s eq:0 -o empty -e empty \
$(atf_get_srcdir)/h_tools sockets sock
diff --git a/contrib/netbsd-tests/fs/tmpfs/t_remove.sh b/contrib/netbsd-tests/fs/tmpfs/t_remove.sh
index df868f9..f75032c 100755
--- a/contrib/netbsd-tests/fs/tmpfs/t_remove.sh
+++ b/contrib/netbsd-tests/fs/tmpfs/t_remove.sh
@@ -46,13 +46,28 @@ single_body() {
test_unmount
}
+# Begin FreeBSD
+if true; then
+atf_test_case uchg cleanup
+uchg_cleanup() {
+ Mount_Point=$(pwd)/mntpt _test_unmount
+}
+else
+# End FreeBSD
atf_test_case uchg
+# Begin FreeBSD
+fi
+# End FreeBSD
uchg_head() {
atf_set "descr" "Checks that files with the uchg flag set cannot" \
"be removed"
atf_set "require.user" "root"
}
uchg_body() {
+ # Begin FreeBSD
+ atf_expect_fail "this fails on FreeBSD with root - bug 212861"
+ # End FreeBSD
+
test_mount
atf_check -s eq:0 -o empty -e empty touch a
diff --git a/contrib/netbsd-tests/fs/tmpfs/t_sizes.sh b/contrib/netbsd-tests/fs/tmpfs/t_sizes.sh
index 9673b91..35abe8a 100755
--- a/contrib/netbsd-tests/fs/tmpfs/t_sizes.sh
+++ b/contrib/netbsd-tests/fs/tmpfs/t_sizes.sh
@@ -54,7 +54,15 @@ big_head() {
big_body() {
test_mount -o -s10M
+ # Begin FreeBSD
+ if true; then
+ pagesize=$(sysctl -n hw.pagesize)
+ else
+ # End FreeBSD
pagesize=$(sysctl hw.pagesize | cut -d ' ' -f 3)
+ # Begin FreeBSD
+ fi
+ # End FreeBSD
eval $($(atf_get_srcdir)/h_tools statvfs . | sed -e 's|^f_|cf_|')
cf_bused=$((${cf_blocks} - ${cf_bfree}))
diff --git a/contrib/netbsd-tests/fs/tmpfs/t_statvfs.sh b/contrib/netbsd-tests/fs/tmpfs/t_statvfs.sh
index 21290b6..d0e7ac2 100755
--- a/contrib/netbsd-tests/fs/tmpfs/t_statvfs.sh
+++ b/contrib/netbsd-tests/fs/tmpfs/t_statvfs.sh
@@ -38,7 +38,15 @@ values_head() {
values_body() {
test_mount -o -s10M
+ # Begin FreeBSD
+ if true; then
+ pagesize=$(sysctl -n hw.pagesize)
+ else
+ # End FreeBSD
pagesize=$(sysctl hw.pagesize | cut -d ' ' -f 3)
+ # Begin FreeBSD
+ fi
+ # End FreeBSD
eval $($(atf_get_srcdir)/h_tools statvfs .)
[ ${pagesize} -eq ${f_bsize} ] || \
atf_fail "Invalid bsize"
diff --git a/contrib/netbsd-tests/fs/tmpfs/t_vnd.sh b/contrib/netbsd-tests/fs/tmpfs/t_vnd.sh
index 2c97fa9..1f42f62 100755
--- a/contrib/netbsd-tests/fs/tmpfs/t_vnd.sh
+++ b/contrib/netbsd-tests/fs/tmpfs/t_vnd.sh
@@ -1,4 +1,4 @@
-# $NetBSD: t_vnd.sh,v 1.8 2011/04/21 22:26:46 haad Exp $
+# $NetBSD: t_vnd.sh,v 1.9 2016/07/29 05:23:24 pgoyette Exp $
#
# Copyright (c) 2006, 2007, 2008 The NetBSD Foundation, Inc.
# All rights reserved.
@@ -38,12 +38,21 @@ basic_body() {
atf_check -s eq:0 -o ignore -e ignore \
dd if=/dev/zero of=disk.img bs=1m count=10
- atf_check -s eq:0 -o empty -e empty vnconfig /dev/vnd3 disk.img
+ # Begin FreeBSD
+ if true; then
+ atf_check -s eq:0 -o empty -e empty mkdir mnt
+ atf_check -s eq:0 -o empty -e empty mdmfs -F disk.img md3 mnt
+ else
+ # End FreeBSD
+ atf_check -s eq:0 -o empty -e empty vndconfig /dev/vnd3 disk.img
atf_check -s eq:0 -o ignore -e ignore newfs /dev/rvnd3a
atf_check -s eq:0 -o empty -e empty mkdir mnt
atf_check -s eq:0 -o empty -e empty mount /dev/vnd3a mnt
+ # Begin FreeBSD
+ fi
+ # End FreeBSD
echo "Creating test files"
for f in $(jot -w %u 100 | uniq); do
@@ -58,7 +67,15 @@ basic_body() {
done
atf_check -s eq:0 -o empty -e empty umount mnt
- atf_check -s eq:0 -o empty -e empty vnconfig -u /dev/vnd3
+ # Begin FreeBSD
+ if true; then
+ atf_check -s eq:0 -o empty -e empty mdconfig -d -u 3
+ else
+ # End FreeBSD
+ atf_check -s eq:0 -o empty -e empty vndconfig -u /dev/vnd3
+ # Begin FreeBSD
+ fi
+ # End FreeBSD
test_unmount
touch done
@@ -66,7 +83,15 @@ basic_body() {
basic_cleanup() {
if [ ! -f done ]; then
umount mnt 2>/dev/null 1>&2
- vnconfig -u /dev/vnd3 2>/dev/null 1>&2
+ # Begin FreeBSD
+ if true; then
+ [ ! -c /dev/md3 ] || mdconfig -d -u 3
+ else
+ # End FreeBSD
+ vndconfig -u /dev/vnd3 2>/dev/null 1>&2
+ # Begin FreeBSD
+ fi
+ # End FreeBSD
fi
}
diff --git a/contrib/netbsd-tests/fs/tmpfs/t_vnode_leak.sh b/contrib/netbsd-tests/fs/tmpfs/t_vnode_leak.sh
index c505ffd..4630a7c 100755
--- a/contrib/netbsd-tests/fs/tmpfs/t_vnode_leak.sh
+++ b/contrib/netbsd-tests/fs/tmpfs/t_vnode_leak.sh
@@ -36,7 +36,15 @@ main_head() {
}
main_body() {
echo "Lowering kern.maxvnodes to 2000"
+ # Begin FreeBSD
+ if true; then
+ sysctl -n kern.maxvnodes > oldvnodes
+ else
+ # End FreeBSD
sysctl kern.maxvnodes | awk '{ print $3; }' >oldvnodes
+ # Begin FreeBSD
+ fi
+ # End FreeBSD
atf_check -s eq:0 -o ignore -e empty sysctl -w kern.maxvnodes=2000
test_mount -o -s$(((4000 + 2) * 4096))
diff --git a/contrib/netbsd-tests/fs/vfs/t_io.c b/contrib/netbsd-tests/fs/vfs/t_io.c
index 67d8657..23c3a15 100644
--- a/contrib/netbsd-tests/fs/vfs/t_io.c
+++ b/contrib/netbsd-tests/fs/vfs/t_io.c
@@ -1,4 +1,4 @@
-/* $NetBSD: t_io.c,v 1.12 2013/08/04 11:02:02 pooka Exp $ */
+/* $NetBSD: t_io.c,v 1.16 2015/04/04 12:34:44 riastradh Exp $ */
/*-
* Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -222,6 +222,22 @@ wrrd_after_unlink(const atf_tc_t *tc, const char *mp)
FSTEST_EXIT();
}
+static void
+read_fault(const atf_tc_t *tc, const char *mp)
+{
+ char ch = 123;
+ int fd;
+
+ FSTEST_ENTER();
+ RL(fd = rump_sys_open("file", O_CREAT | O_RDWR, 0777));
+ ATF_REQUIRE_EQ(rump_sys_write(fd, &ch, 1), 1);
+ RL(rump_sys_close(fd));
+ RL(fd = rump_sys_open("file", O_RDONLY | O_SYNC | O_RSYNC));
+ ATF_REQUIRE_ERRNO(EFAULT, rump_sys_read(fd, NULL, 1) == -1);
+ RL(rump_sys_close(fd));
+ FSTEST_EXIT();
+}
+
ATF_TC_FSAPPLY(holywrite, "create a sparse file and fill hole");
ATF_TC_FSAPPLY(extendfile, "check that extending a file works");
ATF_TC_FSAPPLY(extendfile_append, "check that extending a file works "
@@ -232,6 +248,7 @@ ATF_TC_FSAPPLY(overwrite_trunc, "write 64k + truncate + rewrite");
ATF_TC_FSAPPLY(shrinkfile, "shrink file");
ATF_TC_FSAPPLY(read_after_unlink, "contents can be read off disk after unlink");
ATF_TC_FSAPPLY(wrrd_after_unlink, "file can be written and read after unlink");
+ATF_TC_FSAPPLY(read_fault, "read at bad address must return EFAULT");
ATF_TP_ADD_TCS(tp)
{
@@ -245,6 +262,7 @@ ATF_TP_ADD_TCS(tp)
ATF_TP_FSAPPLY(shrinkfile);
ATF_TP_FSAPPLY(read_after_unlink);
ATF_TP_FSAPPLY(wrrd_after_unlink);
+ ATF_TP_FSAPPLY(read_fault);
return atf_no_error();
}
diff --git a/contrib/netbsd-tests/fs/vfs/t_renamerace.c b/contrib/netbsd-tests/fs/vfs/t_renamerace.c
index 70e02f3..809c380 100644
--- a/contrib/netbsd-tests/fs/vfs/t_renamerace.c
+++ b/contrib/netbsd-tests/fs/vfs/t_renamerace.c
@@ -1,4 +1,4 @@
-/* $NetBSD: t_renamerace.c,v 1.32 2014/07/29 09:15:48 gson Exp $ */
+/* $NetBSD: t_renamerace.c,v 1.33 2016/05/04 08:30:22 dholland Exp $ */
/*
* Modified for rump and atf from a program supplied
@@ -127,7 +127,7 @@ renamerace(const atf_tc_t *tc, const char *mp)
atf_tc_fail("race did not trigger this time");
if (FSTYPE_MSDOS(tc)) {
- atf_tc_expect_fail("PR kern/44661");
+ atf_tc_expect_fail("PR kern/43626");
/*
* XXX: race does not trigger every time at least
* on amd64/qemu.
diff --git a/contrib/netbsd-tests/fs/vfs/t_unpriv.c b/contrib/netbsd-tests/fs/vfs/t_unpriv.c
index fffffe4..6da771b4 100644
--- a/contrib/netbsd-tests/fs/vfs/t_unpriv.c
+++ b/contrib/netbsd-tests/fs/vfs/t_unpriv.c
@@ -1,4 +1,4 @@
-/* $NetBSD: t_unpriv.c,v 1.11 2014/08/29 17:39:18 gson Exp $ */
+/* $NetBSD: t_unpriv.c,v 1.12 2015/04/09 19:51:13 riastradh Exp $ */
/*-
* Copyright (c) 2011 The NetBSD Foundation, Inc.
@@ -55,8 +55,6 @@ owner(const atf_tc_t *tc, const char *mp)
rump_pub_lwproc_rfork(RUMP_RFCFDG);
if (rump_sys_setuid(1) == -1)
atf_tc_fail_errno("setuid");
- if (FSTYPE_ZFS(tc))
- atf_tc_expect_fail("PR kern/47656: Test known to be broken");
if (rump_sys_chown(".", 1, -1) != -1 || errno != EPERM)
atf_tc_fail_errno("chown");
if (rump_sys_chmod(".", 0000) != -1 || errno != EPERM)
diff --git a/contrib/netbsd-tests/fs/vfs/t_vnops.c b/contrib/netbsd-tests/fs/vfs/t_vnops.c
index 66b5505..978fadb 100644
--- a/contrib/netbsd-tests/fs/vfs/t_vnops.c
+++ b/contrib/netbsd-tests/fs/vfs/t_vnops.c
@@ -1,4 +1,4 @@
-/* $NetBSD: t_vnops.c,v 1.43 2014/09/09 06:51:00 gson Exp $ */
+/* $NetBSD: t_vnops.c,v 1.58 2016/08/29 02:31:46 kre Exp $ */
/*-
* Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -28,9 +28,11 @@
#include <sys/stat.h>
#include <sys/statvfs.h>
+#include <sys/time.h>
#include <assert.h>
#include <atf-c.h>
+#include <ctype.h>
#include <fcntl.h>
#include <libgen.h>
#include <stdlib.h>
@@ -54,10 +56,10 @@
atf_tc_skip("symlinks not supported by file system")
static char *
-md(char *buf, const char *base, const char *tail)
+md(char *buf, size_t buflen, const char *base, const char *tail)
{
- sprintf(buf, "%s/%s", base, tail);
+ snprintf(buf, buflen, "%s/%s", base, tail);
return buf;
}
@@ -68,11 +70,11 @@ lookup_simple(const atf_tc_t *tc, const char *mountpath)
struct stat sb1, sb2;
strcpy(final, mountpath);
- sprintf(pb, "%s/../%s", mountpath, basename(final));
+ snprintf(pb, sizeof(pb), "%s/../%s", mountpath, basename(final));
if (rump_sys_stat(pb, &sb1) == -1)
atf_tc_fail_errno("stat 1");
- sprintf(pb, "%s/./../%s", mountpath, basename(final));
+ snprintf(pb, sizeof(pb), "%s/./../%s", mountpath, basename(final));
if (rump_sys_stat(pb, &sb2) == -1)
atf_tc_fail_errno("stat 2");
@@ -84,22 +86,38 @@ lookup_complex(const atf_tc_t *tc, const char *mountpath)
{
char pb[MAXPATHLEN];
struct stat sb1, sb2;
+ struct timespec atplus1, onesec;
USES_DIRS;
- if (FSTYPE_UDF(tc))
- atf_tc_expect_fail("PR kern/49033");
-
- sprintf(pb, "%s/dir", mountpath);
+ snprintf(pb, sizeof(pb), "%s/dir", mountpath);
if (rump_sys_mkdir(pb, 0777) == -1)
atf_tc_fail_errno("mkdir");
if (rump_sys_stat(pb, &sb1) == -1)
atf_tc_fail_errno("stat 1");
- sprintf(pb, "%s/./dir/../././dir/.", mountpath);
+ snprintf(pb, sizeof(pb), "%s/./dir/../././dir/.", mountpath);
if (rump_sys_stat(pb, &sb2) == -1)
atf_tc_fail_errno("stat 2");
+ /*
+ * The lookup is permitted to modify the access time of
+ * any directories searched - such a directory is the
+ * subject of this test. Any difference should cause
+ * the 2nd lookup atime tp be >= the first, if it is ==, all is
+ * OK (atime is not required to be modified by the search, or
+ * both references may happen within the came clock tick), if the
+ * 2nd lookup atime is > the first, but not "too much" greater,
+ * just set it back, so the memcmp just below succeeds
+ * (assuming all else is OK).
+ */
+ onesec.tv_sec = 1;
+ onesec.tv_nsec = 0;
+ timespecadd(&sb1.st_atimespec, &onesec, &atplus1);
+ if (timespeccmp(&sb2.st_atimespec, &sb1.st_atimespec, >) &&
+ timespeccmp(&sb2.st_atimespec, &atplus1, <))
+ sb2.st_atimespec = sb1.st_atimespec;
+
if (memcmp(&sb1, &sb2, sizeof(sb1)) != 0) {
printf("what\tsb1\t\tsb2\n");
@@ -118,10 +136,10 @@ lookup_complex(const atf_tc_t *tc, const char *mountpath)
FIELD(st_uid);
FIELD(st_gid);
FIELD(st_rdev);
- TIME(st_atim);
- TIME(st_mtim);
- TIME(st_ctim);
- TIME(st_birthtim);
+ TIME(st_atimespec);
+ TIME(st_mtimespec);
+ TIME(st_ctimespec);
+ TIME(st_birthtimespec);
FIELD(st_size);
FIELD(st_blocks);
FIELD(st_flags);
@@ -132,9 +150,6 @@ lookup_complex(const atf_tc_t *tc, const char *mountpath)
atf_tc_fail("stat results differ, see ouput for more details");
}
- if (FSTYPE_UDF(tc))
- atf_tc_fail("random failure of PR kern/49033 "
- "did not happen this time");
}
static void
@@ -146,7 +161,7 @@ dir_simple(const atf_tc_t *tc, const char *mountpath)
USES_DIRS;
/* check we can create directories */
- sprintf(pb, "%s/dir", mountpath);
+ snprintf(pb, sizeof(pb), "%s/dir", mountpath);
if (rump_sys_mkdir(pb, 0777) == -1)
atf_tc_fail_errno("mkdir");
if (rump_sys_stat(pb, &sb) == -1)
@@ -168,19 +183,17 @@ dir_notempty(const atf_tc_t *tc, const char *mountpath)
USES_DIRS;
/* check we can create directories */
- sprintf(pb, "%s/dir", mountpath);
+ snprintf(pb, sizeof(pb), "%s/dir", mountpath);
if (rump_sys_mkdir(pb, 0777) == -1)
atf_tc_fail_errno("mkdir");
- sprintf(pb2, "%s/dir/file", mountpath);
+ snprintf(pb2, sizeof(pb2), "%s/dir/file", mountpath);
fd = rump_sys_open(pb2, O_RDWR | O_CREAT, 0777);
if (fd == -1)
atf_tc_fail_errno("create file");
rump_sys_close(fd);
rv = rump_sys_rmdir(pb);
- if (FSTYPE_ZFS(tc))
- atf_tc_expect_fail("PR kern/47656: Test known to be broken");
if (rv != -1 || errno != ENOTEMPTY)
atf_tc_fail("non-empty directory removed succesfully");
@@ -206,9 +219,9 @@ dir_rmdirdotdot(const atf_tc_t *tc, const char *mp)
RL(rump_sys_mkdir("subtest", 0777));
RL(rump_sys_chdir("subtest"));
- md(pb, mp, "test/subtest");
+ md(pb, sizeof(pb), mp, "test/subtest");
RL(rump_sys_rmdir(pb));
- md(pb, mp, "test");
+ md(pb, sizeof(pb), mp, "test");
RL(rump_sys_rmdir(pb));
if (FSTYPE_NFS(tc))
@@ -226,7 +239,7 @@ checkfile(const char *path, struct stat *refp)
struct stat sb;
static int n = 1;
- md(buf, path, "file");
+ md(buf, sizeof(buf), path, "file");
if (rump_sys_stat(buf, &sb) == -1)
atf_tc_fail_errno("cannot stat file %d (%s)", n, buf);
if (memcmp(&sb, refp, sizeof(sb)) != 0)
@@ -245,18 +258,18 @@ rename_dir(const atf_tc_t *tc, const char *mp)
USES_DIRS;
- md(pb1, mp, "dir1");
+ md(pb1, sizeof(pb1), mp, "dir1");
if (rump_sys_mkdir(pb1, 0777) == -1)
atf_tc_fail_errno("mkdir 1");
- md(pb2, mp, "dir2");
+ md(pb2, sizeof(pb2), mp, "dir2");
if (rump_sys_mkdir(pb2, 0777) == -1)
atf_tc_fail_errno("mkdir 2");
- md(pb2, mp, "dir2/subdir");
+ md(pb2, sizeof(pb2), mp, "dir2/subdir");
if (rump_sys_mkdir(pb2, 0777) == -1)
atf_tc_fail_errno("mkdir 3");
- md(pb3, mp, "dir1/file");
+ md(pb3, sizeof(pb3), mp, "dir1/file");
if (rump_sys_mknod(pb3, S_IFREG | 0777, -1) == -1)
atf_tc_fail_errno("create file");
if (rump_sys_stat(pb3, &ref) == -1)
@@ -267,30 +280,28 @@ rename_dir(const atf_tc_t *tc, const char *mp)
*/
/* rename within directory */
- md(pb3, mp, "dir3");
+ md(pb3, sizeof(pb3), mp, "dir3");
if (rump_sys_rename(pb1, pb3) == -1)
atf_tc_fail_errno("rename 1");
checkfile(pb3, &ref);
/* rename directory onto itself (two ways, should fail) */
- md(pb1, mp, "dir3/.");
+ md(pb1, sizeof(pb1), mp, "dir3/.");
if (rump_sys_rename(pb1, pb3) != -1 || errno != EINVAL)
atf_tc_fail_errno("rename 2");
- if (FSTYPE_ZFS(tc))
- atf_tc_expect_fail("PR kern/47656: Test known to be broken");
if (rump_sys_rename(pb3, pb1) != -1 || errno != EISDIR)
atf_tc_fail_errno("rename 3");
checkfile(pb3, &ref);
/* rename father of directory into directory */
- md(pb1, mp, "dir2/dir");
- md(pb2, mp, "dir2");
+ md(pb1, sizeof(pb1), mp, "dir2/dir");
+ md(pb2, sizeof(pb2), mp, "dir2");
if (rump_sys_rename(pb2, pb1) != -1 || errno != EINVAL)
atf_tc_fail_errno("rename 4");
/* same for grandfather */
- md(pb1, mp, "dir2/subdir/dir2");
+ md(pb1, sizeof(pb1), mp, "dir2/subdir/dir2");
if (rump_sys_rename(pb2, pb1) != -1 || errno != EINVAL)
atf_tc_fail("rename 5");
@@ -301,29 +312,29 @@ rename_dir(const atf_tc_t *tc, const char *mp)
atf_tc_fail("rename 6");
/* cross-directory rename */
- md(pb1, mp, "dir3");
- md(pb2, mp, "dir2/somedir");
+ md(pb1, sizeof(pb1), mp, "dir3");
+ md(pb2, sizeof(pb2), mp, "dir2/somedir");
if (rump_sys_rename(pb1, pb2) == -1)
atf_tc_fail_errno("rename 7");
checkfile(pb2, &ref);
/* move to parent directory */
- md(pb1, mp, "dir2/somedir/../../dir3");
+ md(pb1, sizeof(pb1), mp, "dir2/somedir/../../dir3");
if (rump_sys_rename(pb2, pb1) == -1)
atf_tc_fail_errno("rename 8");
- md(pb1, mp, "dir2/../dir3");
+ md(pb1, sizeof(pb1), mp, "dir2/../dir3");
checkfile(pb1, &ref);
/* atomic cross-directory rename */
- md(pb3, mp, "dir2/subdir");
+ md(pb3, sizeof(pb3), mp, "dir2/subdir");
if (rump_sys_rename(pb1, pb3) == -1)
atf_tc_fail_errno("rename 9");
checkfile(pb3, &ref);
/* rename directory over an empty directory */
- md(pb1, mp, "parent");
- md(pb2, mp, "parent/dir1");
- md(pb3, mp, "parent/dir2");
+ md(pb1, sizeof(pb1), mp, "parent");
+ md(pb2, sizeof(pb2), mp, "parent/dir1");
+ md(pb3, sizeof(pb3), mp, "parent/dir2");
RL(rump_sys_mkdir(pb1, 0777));
RL(rump_sys_mkdir(pb2, 0777));
RL(rump_sys_mkdir(pb3, 0777));
@@ -442,6 +453,78 @@ rename_reg_nodir(const atf_tc_t *tc, const char *mp)
rump_sys_chdir("/");
}
+/* PR kern/50607 */
+static void
+create_many(const atf_tc_t *tc, const char *mp)
+{
+ char buf[64];
+ int nfiles = 2324; /* #Nancy */
+ int i;
+
+ /* takes forever with many files */
+ if (FSTYPE_MSDOS(tc))
+ nfiles /= 4;
+
+ RL(rump_sys_chdir(mp));
+
+ if (FSTYPE_SYSVBFS(tc)) {
+ /* fs doesn't support many files or subdirectories */
+ nfiles = 5;
+ } else {
+ /* msdosfs doesn't like many entries in the root directory */
+ RL(rump_sys_mkdir("subdir", 0777));
+ RL(rump_sys_chdir("subdir"));
+ }
+
+ /* create them */
+#define TESTFN "testfile"
+ for (i = 0; i < nfiles; i++) {
+ int fd;
+
+ snprintf(buf, sizeof(buf), TESTFN "%d", i);
+ RL(fd = rump_sys_open(buf, O_RDWR|O_CREAT|O_EXCL, 0666));
+ RL(rump_sys_close(fd));
+ }
+
+ /* wipe them out */
+ for (i = 0; i < nfiles; i++) {
+ snprintf(buf, sizeof(buf), TESTFN "%d", i);
+ RLF(rump_sys_unlink(buf), "%s", buf);
+ }
+#undef TESTFN
+
+ rump_sys_chdir("/");
+}
+
+/*
+ * Test creating files with one-character names using all possible
+ * character values. Failures to create the file are ignored as the
+ * characters allowed in file names vary by file system, but at least
+ * we can check that the fs does not crash, and if the file is
+ * successfully created, unlinking it should also succeed.
+ */
+static void
+create_nonalphanum(const atf_tc_t *tc, const char *mp)
+{
+ char buf[64];
+ int i;
+
+ RL(rump_sys_chdir(mp));
+
+ for (i = 0; i < 256; i++) {
+ int fd;
+ snprintf(buf, sizeof(buf), "%c", i);
+ fd = rump_sys_open(buf, O_RDWR|O_CREAT|O_EXCL, 0666);
+ if (fd == -1)
+ continue;
+ RLF(rump_sys_close(fd), "%d", fd);
+ RLF(rump_sys_unlink(buf), "%s", buf);
+ }
+ printf("\n");
+
+ rump_sys_chdir("/");
+}
+
static void
create_nametoolong(const atf_tc_t *tc, const char *mp)
{
@@ -563,7 +646,7 @@ symlink_len(const atf_tc_t *tc, const char *mp, size_t len)
USES_SYMLINKS;
- RL(rump_sys_chdir(mp));
+ RLF(rump_sys_chdir(mp), "%s", mp);
buf = malloc(len + 1);
ATF_REQUIRE(buf);
@@ -645,8 +728,6 @@ attrs(const atf_tc_t *tc, const char *mp)
RL(rump_sys_stat(TESTFILE, &sb2));
#define CHECK(a) ATF_REQUIRE_EQ(sb.a, sb2.a)
- if (FSTYPE_ZFS(tc))
- atf_tc_expect_fail("PR kern/47656: Test known to be broken");
if (!(FSTYPE_MSDOS(tc) || FSTYPE_SYSVBFS(tc))) {
CHECK(st_uid);
CHECK(st_gid);
@@ -684,9 +765,6 @@ fcntl_lock(const atf_tc_t *tc, const char *mp)
RL(fd = rump_sys_open(TESTFILE, O_RDWR | O_CREAT, 0755));
RL(rump_sys_ftruncate(fd, 8192));
- /* PR kern/43321 */
- if (FSTYPE_ZFS(tc))
- atf_tc_expect_fail("PR kern/47656: Test known to be broken");
RL(rump_sys_fcntl(fd, F_SETLK, &l));
/* Next, we fork and try to lock the same area */
@@ -820,9 +898,6 @@ fcntl_getlock_pids(const atf_tc_t *tc, const char *mp)
RL(rump_sys_ftruncate(fd[i], sz));
- if (FSTYPE_ZFS(tc))
- atf_tc_expect_fail("PR kern/47656: Test known to be "
- "broken");
if (i < __arraycount(lock)) {
RL(rump_sys_fcntl(fd[i], F_SETLK, &lock[i]));
expect[i].l_pid = pid[i];
@@ -932,9 +1007,6 @@ lstat_symlink(const atf_tc_t *tc, const char *mp)
USES_SYMLINKS;
- if (FSTYPE_V7FS(tc))
- atf_tc_expect_fail("PR kern/48864");
-
FSTEST_ENTER();
src = "source";
@@ -973,6 +1045,11 @@ ATF_TC_FSAPPLY(access_simple, "access(2)");
ATF_TC_FSAPPLY(read_directory, "read(2) on directories");
ATF_TC_FSAPPLY(lstat_symlink, "lstat(2) values for symbolic links");
+#undef FSTEST_IMGSIZE
+#define FSTEST_IMGSIZE (1024*1024*64)
+ATF_TC_FSAPPLY(create_many, "create many directory entries");
+ATF_TC_FSAPPLY(create_nonalphanum, "non-alphanumeric filenames");
+
ATF_TP_ADD_TCS(tp)
{
@@ -984,6 +1061,8 @@ ATF_TP_ADD_TCS(tp)
ATF_TP_FSAPPLY(rename_dir);
ATF_TP_FSAPPLY(rename_dotdot);
ATF_TP_FSAPPLY(rename_reg_nodir);
+ ATF_TP_FSAPPLY(create_many);
+ ATF_TP_FSAPPLY(create_nonalphanum);
ATF_TP_FSAPPLY(create_nametoolong);
ATF_TP_FSAPPLY(create_exist);
ATF_TP_FSAPPLY(rename_nametoolong);
OpenPOWER on IntegriCloud