diff options
Diffstat (limited to 'plpnfsd/mp_mount.c')
-rw-r--r-- | plpnfsd/mp_mount.c | 630 |
1 files changed, 0 insertions, 630 deletions
diff --git a/plpnfsd/mp_mount.c b/plpnfsd/mp_mount.c deleted file mode 100644 index 8b8a515..0000000 --- a/plpnfsd/mp_mount.c +++ /dev/null @@ -1,630 +0,0 @@ -/* $Id$ - * - * Original version of this file from p3nfsd-5.4 by - * Rudolf Koenig (rfkoenig@immd4.informatik.uni-erlangen.de) - * - * Modifications for plputils by Fritz Elfert <felfert@to.com> - * - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#if defined(__SVR4) || defined(__sgi) || defined(linux) -#include <stdlib.h> -#include <unistd.h> -#include <string.h> /* strdup */ -#ifndef linux -extern int inet_addr(char *); -#endif -#define PORTMAP /* I need svcudp_create in rpc/svc_soc.h, sol 2.4 */ -#endif - -#include "OSdefs.h" -#include <stdio.h> -#include <signal.h> -#include <sys/stat.h> -#include <sys/wait.h> - -#ifdef __sgi -#include <bstring.h> -#endif - -#if defined(__NetBSD__) || defined(__FreeBSD__) -#include <sys/param.h> /* Needs NGROUPS for mount.h */ -#define umount(dir) unmount(dir, 1) -#endif - -#if defined(__NeXT__) -#include <libc.h> -#include <unistd.h> -#include <nfs/nfs_mount.h> -#define umount(dir) unmount(dir) -#endif - - -static char nfshost[128]; - -#define NFSCLIENT -#ifdef __FreeBSD__ -#define NFS -#endif /* __FreeBSD__ */ -#include <sys/mount.h> - -#ifdef __FreeBSD__ -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <rpc/rpc.h> -#include <nfs/rpcv2.h> -#if __FreeBSD_version >= 300001 -#include <nfs/nfs.h> -#endif -#endif /* __FreeBSD__ */ - -#ifdef __NetBSD__ -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <sys/types.h> -#include <stdlib.h> -#include <unistd.h> -#include <strings.h> -#include <nfs/nfsmount.h> -#endif /* __NetBSD__ */ - -#include <rpc/rpc.h> -#include "nfs_prot.h" - -#ifdef linux -#ifndef __GLIBC__ -#include <linux/fs.h> /* struct nfs_mount_data */ -#endif -#include "linux-misc.h" /* struct nfs_mount_data */ -#include <arpa/inet.h> /* inet_addr() */ -#endif -#ifdef _IBMR2 -#include "os-aix3.h" -#include "misc-aix3.h" -#include <sys/vmount.h> -#endif - -#ifndef DONT_UPDATE_MTAB -#if defined(sun) && defined(__SVR4) -#include <sys/mnttab.h> -#else -#include <mntent.h> -#endif -#endif - -#if defined(sun) && defined(__SVR4) /*gec */ -#include <nfs/mount.h> -#include <sys/fstyp.h> -#include <sys/fsid.h> -#include <sys/types.h> -#include <sys/stat.h> -#define PORTMAP -#endif - -#if defined(sun) && !defined(__SVR4) -extern int _rpc_dtablesize(); -#define umount unmount -#endif - -#include <sys/socket.h> -#include <netdb.h> - -#include "rfsv_api.h" - -#ifdef __sgi -#define vfork fork -#define NFSMNT_NOCTO 0 -#endif - -#if defined(sun) && defined(__SVR4) -#define setmntent fopen -#define endmntent fclose -#define addmntent putmntent -#define mntent mnttab -#endif - -static char *mntdir; /* where we mounted the psion */ - -#ifdef __STDC__ -static void doexit(void); -#endif - -static RETSIGTYPE -usr1_handler SIGARG -{ - debug = (debug + 1) & 3; - infolog("Set debug level to %d\n", debug); -}; - -static RETSIGTYPE -hup_handler SIGARG -{ - if (debug > 1) - debuglog("Got HUP signal\n"); - exiting = 5; -}; - -static RETSIGTYPE -term_handler SIGARG -{ - if (debug > 1) - debuglog("Got TERM signal\n"); - exiting = 5; -}; - -static void doexit() { -#ifndef DONT_UPDATE_MTAB - FILE *fpin, *fpout; -#if defined(sun) && defined(__SVR4) - struct mntent entr; -#else - struct mntent *ent; -#endif -#endif -#if !defined(__FreeBSD__) && !defined(__NetBSD__) - struct stat statb; -#endif - - exiting--; - debuglog("Doing exit\n"); - -#ifdef _IBMR2 - if (stat(mntdir, &statb)) { - errorlog("stat %s: %m\n", mntdir); - return; - } - debuglog("Next call: uvmount(%d, 0)\n", statb.st_vfs); - if (uvmount(statb.st_vfs, 0)) { - errorlog("uvmount: %m\n"); - return; - } -#else - if (umount(mntdir)) { - errorlog("umount %s: %m\n", mntdir); - return; - } -#endif - -#ifndef DONT_UPDATE_MTAB - debuglog("unmount succeeded, trying to fix mtab.\n"); - - if (!(fpout = setmntent(MTAB_TMP, "w"))) { - errorlog("%s: %m\n", MTAB_TMP); - return; - } - if (!(fpin = setmntent(MTAB_PATH, "r"))) { - endmntent(fpout); - unlink(MTAB_TMP); - errorlog("%s: %m\n", MTAB_PATH); - exit(0); - } - if (fstat(fileno(fpin), &statb)) - errorlog("fstat: %m\n"); - else - fchmod(fileno(fpout), statb.st_mode); - -#if defined(sun) && defined(__SVR4) - while (!getmntent(fpin, &entr)) - if (strcmp(entr.mnt_special, nfshost) || strcmp(entr.mnt_mountp, mntdir)) - putmntent(fpout, &entr); -#else - while ((ent = getmntent(fpin))) - if (strcmp(ent->mnt_fsname, nfshost) || strcmp(ent->mnt_dir, mntdir)) - addmntent(fpout, ent); -#endif - endmntent(fpin); - endmntent(fpout); - - if (rename(MTAB_TMP, MTAB_PATH)) { - errorlog("%s: %m\n", MTAB_PATH); - unlink(MTAB_TMP); - } -#else - debuglog("no mtab fixing needed\n"); -#endif - infolog("plpnfsd: terminating.\n"); - - exit(0); -} - -void cache_flush() { - struct cache *cp; - struct dcache *dcp; - - /* - * Solaris sends blocks in a way which is not very pleasent - * for us. It sends blocks 0,1,2,3,4,5,6, then 9,10,11 and - * do on. A little bit later block 7 and 8 arrives. This "bit" - * is more that 2 seconds, it is about 6 seconds. It occurs - * if we're rewriting a file. We set MAXWRITE to 15, meaning - * that we are waiting for 30 seconds to receive the missing - * blocks. - */ - -#define MAXWRITE 15 - - int doclean = 1; - for (cp = attrcache; cp; cp = cp->next) - for (dcp = cp->dcache; dcp; dcp = dcp->next) - if (dcp->towrite) { - debuglog("waiting for block %d in %s to write (%d)\n", - dcp->offset, get_num(cp->inode)->name, dcp->towrite); - if (++dcp->towrite <= MAXWRITE) - doclean = 0; /* Wait with cleaning */ - } - if (doclean || force_cache_clean) { - for (cp = attrcache; cp; cp = cp->next) - for (dcp = cp->dcache; dcp; dcp = dcp->next) - if (dcp->towrite) - errorlog("PLPNFSD WARNING: file %s block at %d not written\n", - get_num(cp->inode)->name, dcp->offset); - clean_cache(&attrcache); - if (force_cache_clean || ((time(0) - devcache_stamp) > devcache_keep)) - query_cache = 0; /* clear the GETDENTS "cache". */ - rfsv_closecached(); - force_cache_clean = 0; - } -} - -void -mount_and_run(char *dir, void (*proc)(), nfs_fh *root_fh) -{ - int sock, port, pid, doclean; - struct sockaddr_in sain; - int isalive = 0, ret, dtbsize; - SVCXPRT *nfsxprt; - int bufsiz = 0xc000; /* room for a few biods */ -#ifdef linux - struct nfs_mount_data nfs_mount_data; - int mount_flags; - int ksock, kport; - struct sockaddr_in kaddr; -#else - struct nfs_args nfs_args; -#endif -#if defined(__FreeBSD__) || defined(__NetBSD__) - int mount_flags; -#endif - - sprintf(nfshost, "localhost:/psion"); - bzero((char *) &sain, sizeof(struct sockaddr_in)); -#ifdef linux - bzero(&nfs_mount_data, sizeof(struct nfs_mount_data)); -#else - bzero((char *) &nfs_args, sizeof(struct nfs_args)); -#endif - -/*** First part: set up the rpc service */ - /* Create udp socket */ - sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); - if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (char *) &bufsiz, sizeof(bufsiz))) - errorlog("setsockopt: %m\n"); - - /* Bind it to a reserved port */ - sain.sin_family = AF_INET; - sain.sin_addr.s_addr = inet_addr("127.0.0.1"); - for (port = IPPORT_RESERVED - 1; port > IPPORT_RESERVED / 2; port--) { - sain.sin_port = htons(port); - if (bind(sock, (struct sockaddr *) &sain, sizeof(sain)) >= 0) - break; - } - if (port <= IPPORT_RESERVED / 2) { - errorlog("bind to reserved port: %m\n"); - exit(1); - } - if ((nfsxprt = svcudp_create(sock)) == 0) { - errorlog("svcudp_create: %m\n"); - exit(1); - } - if (!svc_register(nfsxprt, NFS_PROGRAM, NFS_VERSION, proc, 0)) { - errorlog("svc_register: %m\n"); - exit(1); - } - debuglog("created svc PROG=%d, VER=%d port=%d\n", - NFS_PROGRAM, NFS_VERSION, port); - - -/*** Second part: mount the directory */ -#ifdef linux - /* - * Hold your hat! Another odd internet socket coming up. The linux - * kernel needs the socket to talk to the nfs daemon. - */ - ksock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); - if (ksock < 0) { - errorlog("Cannot create kernel socket: %m\n"); - exit(1); - } - kaddr.sin_family = AF_INET; - kaddr.sin_addr.s_addr = inet_addr("127.0.0.1"); - for (kport = IPPORT_RESERVED - 1; kport > IPPORT_RESERVED / 2; kport--) { - kaddr.sin_port = htons(kport); - if (bind(ksock, (struct sockaddr *) &kaddr, sizeof(kaddr)) >= 0) - break; - } - if (kport <= IPPORT_RESERVED / 2) { - errorlog("bind to reserved port: %m\n"); - exit(1); - } - nfs_mount_data.version = NFS_MOUNT_VERSION; - nfs_mount_data.fd = ksock; - nfs_mount_data.root = *root_fh; /* structure copy */ - nfs_mount_data.flags = NFS_MOUNT_INTR | NFS_MOUNT_NOCTO; - /* NFS_MOUNT_SECURE | NFS_MOUNT_POSIX | NFS_MOUNT_SOFT | NFS_MOUNT_NOAC */ - nfs_mount_data.rsize = PBUFSIZE; - nfs_mount_data.wsize = PBUFSIZE; - nfs_mount_data.timeo = 600; - nfs_mount_data.retrans = 10; /* default 3 */ - nfs_mount_data.acregmin = 3; /* default 3 seconds */ - nfs_mount_data.acregmax = 60; /* default 60 seconds */ - nfs_mount_data.acdirmin = 30; /* default 30 seconds */ - nfs_mount_data.acdirmax = 60; /* default 60 seconds */ - nfs_mount_data.addr = sain; /* structure copy */ - strcpy(nfs_mount_data.hostname, PSIONHOSTNAME); - - if (connect(ksock, (struct sockaddr *) &nfs_mount_data.addr, sizeof(nfs_mount_data.addr)) < 0) { - errorlog("Cannot connect to plpnfsd: %m\n"); - exit(1); - } - mount_flags = MS_MGC_VAL; /* | MS_SYNCHRONOUS | MS_RDONLY | MS_NOEXEC | MS_NODEV | MS_NOSUID */ - -#endif - -#if defined(sun) && defined (__SVR4) - { /*gec */ - struct netbuf myaddr; - struct stat stb; - struct knetconfig knc; - struct netconfig *nc = getnetconfigent("udp"); - if (!nc) { - extern int errno; - errorlog("getnetconfigent \"udp\": (errno %d) %m\n", errno); - exit(1); - } - knc.knc_semantics = nc->nc_semantics; - knc.knc_protofmly = strdup(nc->nc_protofmly); - knc.knc_proto = strdup(nc->nc_proto); - - if (stat(nc->nc_device, &stb)) { - extern int errno; - errorlog("stat \"%s\": (errno %d) %m\n", nc->nc_device, errno); - exit(1); - } - knc.knc_rdev = stb.st_rdev; - - /*freenetconfigent(nc) has the struct been allocated, or is it static ?!? */ - - debuglog("%d,%s,%s,%lx (1,inet,udp,0x002c0029)\n", (int) knc.knc_semantics, - knc.knc_protofmly, knc.knc_proto, knc.knc_rdev); - - myaddr.maxlen = myaddr.len = sizeof(sain); - myaddr.buf = (char *) &sain; - - nfs_args.knconf = &knc; - nfs_args.wsize = PBUFSIZE; - nfs_args.rsize = PBUFSIZE; - nfs_args.addr = &myaddr; - nfs_args.fh = (char *) root_fh; - nfs_args.retrans = 10; - /* 1 minute timeout - see below */ - nfs_args.timeo = 600; - nfs_args.hostname = PSIONHOSTNAME; - nfs_args.flags = NFSMNT_INT | NFSMNT_HOSTNAME | NFSMNT_NOCTO | - NFSMNT_RETRANS | NFSMNT_TIMEO | NFSMNT_WSIZE | - NFSMNT_RSIZE | NFSMNT_KNCONF /* | NFSMNT_NOAC */ ; - /* eventually drop knc-strings now (memory-leak) */ - } -#endif /* solaris */ - -/* BSD Derived systems */ -#if (defined(sun) && !defined(__SVR4)) || defined(hpux) || defined(__sgi) || defined(__NeXT__) - nfs_args.addr = &sain; - nfs_args.fh = (void *) root_fh; - nfs_args.wsize = PBUFSIZE; - nfs_args.rsize = PBUFSIZE; - nfs_args.retrans = 10; - /* 1 minute timeout - means that we receive double requests in worst case, - if the file is longer than 100k. So long for the theory. Since SunOS uses - dynamic retransmission (hardwired), nfs_args.timeo is only a hint. :-( */ - nfs_args.timeo = 600; - nfs_args.hostname = PSIONHOSTNAME; - nfs_args.flags = NFSMNT_INT | NFSMNT_HOSTNAME | NFSMNT_NOCTO | - NFSMNT_RETRANS | NFSMNT_TIMEO | NFSMNT_WSIZE | NFSMNT_RSIZE; -#endif - -#ifdef __FreeBSD__ -#if __FreeBSD_version >= 300001 - nfs_args.version = NFS_ARGSVERSION; -#endif - nfs_args.addr = (struct sockaddr *) &sain; - nfs_args.addrlen = sizeof(sain); - nfs_args.sotype = SOCK_DGRAM; - nfs_args.fh = (void *) root_fh; - nfs_args.fhsize = sizeof(*root_fh); - nfs_args.wsize = PBUFSIZE; - nfs_args.rsize = PBUFSIZE; - nfs_args.retrans = 10; - /* 1 minute timeout - see below */ - nfs_args.timeo = 600; - nfs_args.hostname = PSIONHOSTNAME; - nfs_args.flags = - NFSMNT_INT | - NFSMNT_SOFT | - NFSMNT_RETRANS | - NFSMNT_TIMEO | - NFSMNT_WSIZE | - NFSMNT_RSIZE; - mount_flags = MNT_NOSUID | MNT_NODEV | MNT_NOEXEC | MNT_NOATIME; -#endif - -#ifdef __NetBSD__ - nfs_args.version = NFS_ARGSVERSION; - nfs_args.addrlen = sizeof(sain); - nfs_args.sotype = SOCK_DGRAM; - nfs_args.maxgrouplist = NGROUPS; - nfs_args.readahead = 1; - nfs_args.addr = (struct sockaddr *) &sain; - nfs_args.fh = (void *) root_fh; - nfs_args.fhsize = sizeof(*root_fh); - nfs_args.wsize = PBUFSIZE; - nfs_args.rsize = PBUFSIZE; - nfs_args.retrans = 10; - nfs_args.timeo = 600; - nfs_args.hostname = PSIONHOSTNAME; - nfs_args.flags = NFSMNT_INT | NFSMNT_RETRANS | NFSMNT_TIMEO - | NFSMNT_NOCONN | NFSMNT_DUMBTIMR - | NFSMNT_WSIZE | NFSMNT_RSIZE; - mount_flags = MNT_NOSUID | MNT_NODEV | MNT_NOEXEC | MNT_NOATIME; -#endif - -#if defined(_IBMR2) - nfs_args.addr = sain; - nfs_args.fh = *(fhandle_t *) root_fh; - nfs_args.wsize = PBUFSIZE; - nfs_args.rsize = PBUFSIZE; - nfs_args.retrans = 0; /* Shouldn't need bigger retrans since there is - only one biod. Somebody prove it ? Nice feature. */ - nfs_args.biods = 1; - nfs_args.timeo = 150; - nfs_args.hostname = PSIONHOSTNAME; - nfs_args.flags = NFSMNT_INT | NFSMNT_HOSTNAME | NFSMNT_BIODS | - NFSMNT_RETRANS | NFSMNT_TIMEO | NFSMNT_WSIZE | NFSMNT_RSIZE; -#endif - - mntdir = dir; - switch (pid = fork()) { - case 0: - break; - case -1: - errorlog("fork: %m\n"); - exit(1); - default: - debuglog("Going to mount...\n"); - -#if defined(__sgi) || (defined(sun) && defined(__SVR4)) - if (mount("", dir, MS_DATA, "nfs", &nfs_args, sizeof(nfs_args))) -#endif -#if defined(__NeXT__) - if (mount(MOUNT_NFS, dir, 0, (caddr_t) & nfs_args)) -#endif -#ifdef hpux - if (vfsmount(MOUNT_NFS, dir, 0, &nfs_args)) -#endif -#if defined(sun) && !defined(__SVR4) - if (mount("nfs", dir, M_NEWTYPE, (caddr_t) & nfs_args)) -#endif -#ifdef linux - if (mount("nfs", dir, "nfs", mount_flags, &nfs_mount_data)) -#endif -#ifdef _IBMR2 - if (aix3_mount("psion:loc", dir, 0, MOUNT_TYPE_NFS, &nfs_args, "plpnfsd")) -#endif - -#if defined(__NetBSD__) || defined(__FreeBSD__) -#if __FreeBSD_version >= 300001 - if (mount("nfs", dir, mount_flags, &nfs_args)) -#else - if (mount(MOUNT_NFS, dir, mount_flags, &nfs_args)) -#endif -#endif - - { - errorlog("nfs mount %s: %m\n", dir); - kill(pid, SIGTERM); - exit(0); - } else { -#ifndef DONT_UPDATE_MTAB - FILE *mfp; - struct mntent mnt; -#if defined(sun) && defined(__SVR4) /*gec */ - char tim[32]; -#endif - - debuglog("Mount succeeded, making mtab entry.\n"); - -#if defined(sun) && defined(__SVR4) /*gec */ - mnt.mnt_special = nfshost; - mnt.mnt_mountp = mntdir; - mnt.mnt_fstype = "nfs"; - mnt.mnt_mntopts = "hard,intr"; /* dev=??? */ - sprintf(tim, "%ld", time(NULL)); /* umount crashes! without this */ - mnt.mnt_time = tim; -#else - mnt.mnt_fsname = nfshost; - mnt.mnt_dir = mntdir; - mnt.mnt_type = "nfs"; - mnt.mnt_opts = "hard,intr"; - mnt.mnt_freq = mnt.mnt_passno = 0; -#endif - - if ((mfp = setmntent(MTAB_PATH, "a"))) - addmntent(mfp, &mnt); - else - errorlog("%s: %m\n", MTAB_PATH); - endmntent(mfp); -#endif /* !DONT_UPDATE_MTAB */ - } - exit(0); - } - -/*** Third part: let's go */ - infolog("to stop the server do \"echo stop > %s/proc/exit\".\n", mntdir); - -#if defined(sun) && !defined(__SVR4) - dtbsize = _rpc_dtablesize(); -#else - dtbsize = FD_SETSIZE; -#endif - - /* - * Signal handling, etc. should only happen in one process, so let's - * make it this one (the other one might well go away). We really - * ought to block off the other signals, but that's OK... - */ - signal(SIGUSR1, usr1_handler); - signal(SIGHUP, hup_handler); - signal(SIGTERM, term_handler); - - for (;;) { - fd_set readfd; - struct timeval tv; - - readfd = svc_fdset; - tv.tv_sec = 2; - tv.tv_usec = 0; - - ret = select(dtbsize, &readfd, 0, 0, &tv); - if (ret > 0) - svc_getreqset(&readfd); - if (ret != 0) - continue; - - /* Do some housekeeping */ - - if (exiting) - doexit(); - - cache_flush(); - - ret = rfsv_isalive(); - if (isalive) { - if (!ret) { - debuglog("Disconnected...\n"); - doclean = 1; - root_fattr.mtime.seconds = time(0); - } - } else { - if (ret) { - debuglog("Connected...\n"); - root_fattr.mtime.seconds = time(0); - } - } - isalive = ret; - } -} |