#include "rpcmisc.h"
#include "pseudoflavors.h"
-extern void cache_open(void);
-extern struct nfs_fh_len *cache_get_filehandle(nfs_export *exp, int len, char *p);
-extern int cache_export(nfs_export *exp, char *path);
-
extern void my_svc_run(void);
static void usage(const char *, int exitcode);
{ NULL, 0, 0, 0 }
};
-static int nfs_version = -1;
+#define NFSVERSBIT(vers) (0x1 << (vers - 1))
+#define NFSVERSBIT_ALL (NFSVERSBIT(2) | NFSVERSBIT(3) | NFSVERSBIT(4))
+
+static int nfs_version = NFSVERSBIT_ALL;
+
+static int version2(void)
+{
+ return nfs_version & NFSVERSBIT(2);
+}
+
+static int version3(void)
+{
+ return nfs_version & NFSVERSBIT(3);
+}
+
+static int version23(void)
+{
+ return nfs_version & (NFSVERSBIT(2) | NFSVERSBIT(3));
+}
+
+static int version_any(void)
+{
+ return nfs_version & NFSVERSBIT_ALL;
+}
static void
unregister_services (void)
{
- if (nfs_version & (0x1 << 1)) {
- pmap_unset (MOUNTPROG, MOUNTVERS);
- pmap_unset (MOUNTPROG, MOUNTVERS_POSIX);
- }
- if (nfs_version & (0x1 << 2))
- pmap_unset (MOUNTPROG, MOUNTVERS_NFSV3);
+ nfs_svc_unregister(MOUNTPROG, MOUNTVERS);
+ nfs_svc_unregister(MOUNTPROG, MOUNTVERS_POSIX);
+ nfs_svc_unregister(MOUNTPROG, MOUNTVERS_NFSV3);
}
static void
wait_for_workers();
}
cleanup_lockfiles();
- xlog (L_FATAL, "Caught signal %d, un-registering and exiting.", sig);
+ xlog (L_NOTICE, "Caught signal %d, un-registering and exiting.", sig);
+ exit(0);
}
static void
/* Reload /etc/xtab if necessary */
auth_reload();
- mountlist_del_all(nfs_getrpccaller_in(rqstp->rq_xprt));
+ mountlist_del_all(nfs_getrpccaller(rqstp->rq_xprt));
return 1;
}
/* Now authenticate the intruder... */
exp = auth_authenticate("mount", sap, p);
if (exp == NULL) {
- *error = NFSERR_ACCES;
+ *error = MNT3ERR_ACCES;
return NULL;
}
if (stat(p, &stb) < 0) {
xlog(L_WARNING, "can't stat exported dir %s: %s",
p, strerror(errno));
if (errno == ENOENT)
- *error = NFSERR_NOENT;
+ *error = MNT3ERR_NOENT;
else
- *error = NFSERR_ACCES;
+ *error = MNT3ERR_ACCES;
return NULL;
}
if (!S_ISDIR(stb.st_mode) && !S_ISREG(stb.st_mode)) {
xlog(L_WARNING, "%s is not a directory or regular file", p);
- *error = NFSERR_NOTDIR;
+ *error = MNT3ERR_NOTDIR;
return NULL;
}
if (stat(exp->m_export.e_path, &estb) < 0) {
xlog(L_WARNING, "can't stat export point %s: %s",
p, strerror(errno));
- *error = NFSERR_NOENT;
+ *error = MNT3ERR_NOENT;
return NULL;
}
if (estb.st_dev != stb.st_dev
|| !(exp->m_export.e_flags & NFSEXP_CROSSMOUNT))) {
xlog(L_WARNING, "request to export directory %s below nearest filesystem %s",
p, exp->m_export.e_path);
- *error = NFSERR_ACCES;
+ *error = MNT3ERR_ACCES;
return NULL;
}
if (exp->m_export.e_mountpoint &&
exp->m_export.e_path)) {
xlog(L_WARNING, "request to export an unmounted filesystem: %s",
p);
- *error = NFSERR_NOENT;
+ *error = MNT3ERR_NOENT;
return NULL;
}
*/
if (cache_export(exp, p)) {
- *error = NFSERR_ACCES;
+ *error = MNT3ERR_ACCES;
return NULL;
}
fh = cache_get_filehandle(exp, v3?64:32, p);
if (fh == NULL) {
- *error = NFSERR_ACCES;
+ *error = MNT3ERR_ACCES;
return NULL;
}
} else {
if (fh == NULL) {
xlog(L_WARNING, "getfh failed: %s", strerror(errno));
- *error = NFSERR_ACCES;
+ *error = MNT3ERR_ACCES;
return NULL;
}
}
- *error = NFS_OK;
+ *error = MNT_OK;
mountlist_add(host_ntop(sap, buf, sizeof(buf)), p);
if (expret)
*expret = exp;
struct groupnode *g;
for (g = e->ex_groups; g; g = g->gr_next)
- if (strcmp(g->gr_name, newname))
+ if (!strcmp(g->gr_name, newname))
return;
g = xmalloc(sizeof(*g));
{
char *export_file = _PATH_EXPORTS;
char *state_dir = NFS_STATEDIR;
+ char *progname;
+ unsigned int listeners = 0;
int foreground = 0;
int port = 0;
int descriptors = 0;
int c;
+ int vers;
struct sigaction sa;
struct rlimit rlim;
+ /* Set the basename */
+ if ((progname = strrchr(argv[0], '/')) != NULL)
+ progname++;
+ else
+ progname = argv[0];
+
/* Parse the command line options and arguments. */
opterr = 0;
while ((c = getopt_long(argc, argv, "o:nFd:f:p:P:hH:N:V:vrs:t:g", longopts, NULL)) != EOF)
descriptors = atoi(optarg);
if (descriptors <= 0) {
fprintf(stderr, "%s: bad descriptors: %s\n",
- argv [0], optarg);
- usage(argv [0], 1);
+ progname, optarg);
+ usage(progname, 1);
}
break;
case 'F':
ha_callout_prog = optarg;
break;
case 'h':
- usage(argv [0], 0);
+ usage(progname, 0);
break;
case 'P': /* XXX for nfs-server compatibility */
case 'p':
port = atoi(optarg);
if (port <= 0 || port > 65535) {
fprintf(stderr, "%s: bad port number: %s\n",
- argv [0], optarg);
- usage(argv [0], 1);
+ progname, optarg);
+ usage(progname, 1);
}
break;
case 'N':
- nfs_version &= ~(1 << (atoi (optarg) - 1));
+ vers = atoi(optarg);
+ if (vers < 2 || vers > 4) {
+ fprintf(stderr, "%s: bad version number: %s\n",
+ argv[0], optarg);
+ usage(argv[0], 1);
+ }
+ nfs_version &= ~NFSVERSBIT(vers);
break;
case 'n':
_rpcfdtype = SOCK_DGRAM;
case 's':
if ((state_dir = xstrdup(optarg)) == NULL) {
fprintf(stderr, "%s: xstrdup(%s) failed!\n",
- argv[0], optarg);
+ progname, optarg);
exit(1);
}
break;
num_threads = atoi (optarg);
break;
case 'V':
- nfs_version |= 1 << (atoi (optarg) - 1);
+ vers = atoi(optarg);
+ if (vers < 2 || vers > 4) {
+ fprintf(stderr, "%s: bad version number: %s\n",
+ argv[0], optarg);
+ usage(argv[0], 1);
+ }
+ nfs_version |= NFSVERSBIT(vers);
break;
case 'v':
- printf("kmountd %s\n", VERSION);
+ printf("%s version " VERSION "\n", progname);
exit(0);
case 0:
break;
case '?':
default:
- usage(argv [0], 1);
+ usage(progname, 1);
}
- /* No more arguments allowed.
- * Require at least one valid version (2, 3, or 4)
- */
- if (optind != argc || !(nfs_version & 0xE))
- usage(argv [0], 1);
+ /* No more arguments allowed. */
+ if (optind != argc || !version_any())
+ usage(progname, 1);
if (chdir(state_dir)) {
fprintf(stderr, "%s: chdir(%s) failed: %s\n",
- argv [0], state_dir, strerror(errno));
+ progname, state_dir, strerror(errno));
exit(1);
}
if (getrlimit (RLIMIT_NOFILE, &rlim) != 0)
fprintf(stderr, "%s: getrlimit (RLIMIT_NOFILE) failed: %s\n",
- argv [0], strerror(errno));
+ progname, strerror(errno));
else {
/* glibc sunrpc code dies if getdtablesize > FD_SETSIZE */
if ((descriptors == 0 && rlim.rlim_cur > FD_SETSIZE) ||
rlim.rlim_cur = descriptors;
if (setrlimit (RLIMIT_NOFILE, &rlim) != 0) {
fprintf(stderr, "%s: setrlimit (RLIMIT_NOFILE) failed: %s\n",
- argv [0], strerror(errno));
+ progname, strerror(errno));
exit(1);
}
}
}
/* Initialize logging. */
if (!foreground) xlog_stderr(0);
- xlog_open("mountd");
+ xlog_open(progname);
sa.sa_handler = SIG_IGN;
sa.sa_flags = 0;
if (new_cache)
cache_open();
- if (nfs_version & (0x1 << 1)) {
- rpc_init("mountd", MOUNTPROG, MOUNTVERS,
- mount_dispatch, port);
- rpc_init("mountd", MOUNTPROG, MOUNTVERS_POSIX,
- mount_dispatch, port);
+ unregister_services();
+ if (version2()) {
+ listeners += nfs_svc_create("mountd", MOUNTPROG,
+ MOUNTVERS, mount_dispatch, port);
+ listeners += nfs_svc_create("mountd", MOUNTPROG,
+ MOUNTVERS_POSIX, mount_dispatch, port);
}
- if (nfs_version & (0x1 << 2))
- rpc_init("mountd", MOUNTPROG, MOUNTVERS_NFSV3,
- mount_dispatch, port);
+ if (version3())
+ listeners += nfs_svc_create("mountd", MOUNTPROG,
+ MOUNTVERS_NFSV3, mount_dispatch, port);
+ if (version23() && listeners == 0)
+ xlog(L_FATAL, "mountd: could not create listeners\n");
sa.sa_handler = killer;
sigaction(SIGINT, &sa, NULL);
if (num_threads > 1)
fork_workers();
+ xlog(L_NOTICE, "Version " VERSION " starting");
my_svc_run();
- xlog(L_ERROR, "Ack! Gack! svc_run returned!\n");
+ xlog(L_ERROR, "RPC service loop terminated unexpectedly. Exiting...\n");
+ unregister_services();
exit(1);
}