auto_mount.c
来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 893 行 · 第 1/2 页
C
893 行
* mount of the same file system. */ for (mydir = 0, dir = HEAD(struct autodir, dir_q); dir; dir = NEXT(struct autodir, dir)) { if (strcmp(dir->dir_name, fs->fs_mntpnt) == 0) { mydir = 1; if (verbose) syslog(LOG_ERR, "%s:%s already mounted on %s", host, fsname, fs->fs_mntpnt); break; } } if (mydir) continue;/* lebel - should be comparing other opts too */ m2.mnt_opts = fs->fs_opts; has1 = hasmntopt(&m1, MNTOPT_RO) != NULL; has2 = hasmntopt(&m2, MNTOPT_RO) != NULL; if (has1 != has2) continue; has1 = hasmntopt(&m1, MNTOPT_NOSUID) != NULL; has2 = hasmntopt(&m2, MNTOPT_NOSUID) != NULL; if (has1 != has2) continue; has1 = hasmntopt(&m1, MNTOPT_SOFT) != NULL; has2 = hasmntopt(&m2, MNTOPT_SOFT) != NULL; if (has1 != has2) continue; has1 = hasmntopt(&m1, MNTOPT_INT) != NULL; has2 = hasmntopt(&m2, MNTOPT_INT) != NULL; if (has1 != has2) continue; return (fs); } return(0);}nfsunmount(fs) struct filsys *fs;{ struct sockaddr_in sin; struct timeval timeout; CLIENT *client; enum clnt_stat rpc_stat; int s; sin = fs->fs_addr; /* * Port number of "fs->fs_addr" is NFS port number; make port * number 0, so "clntudp_create" finds port number of mount * service. */ sin.sin_port = 0; s = RPC_ANYSOCK; timeout.tv_usec = 0; timeout.tv_sec = 10; if ((client = clntudp_create(&sin, MOUNTPROG, MOUNTVERS, timeout, &s)) == NULL) { syslog(LOG_WARNING, "%s:%s %s", fs->fs_host, fs->fs_dir, clnt_spcreateerror("server not responding")); return; }#ifdef OLDMOUNT if (bindresvport(s, NULL)) syslog(LOG_ERR, "Warning: cannot do local bind");#endif client->cl_auth = authunix_create_default(); timeout.tv_usec = 0; timeout.tv_sec = 25; rpc_stat = clnt_call(client, MOUNTPROC_UMNT, xdr_path, &fs->fs_dir, xdr_void, (char *)NULL, timeout); (void) close(s); AUTH_DESTROY(client->cl_auth); clnt_destroy(client); if (rpc_stat != RPC_SUCCESS) syslog(LOG_WARNING, "%s", clnt_sperror(client, "unmount"));}enum clnt_statpingmount(hostaddr) struct in_addr hostaddr;{ struct timeval tottime; struct sockaddr_in server_addr; enum clnt_stat clnt_stat; u_long port; static struct in_addr goodhost, deadhost; static time_t goodtime, deadtime; int cache_time = 60; /* sec */ if (goodtime > time_now && hostaddr.s_addr == goodhost.s_addr) return RPC_SUCCESS; if (deadtime > time_now && hostaddr.s_addr == deadhost.s_addr) return RPC_TIMEDOUT; if (trace > 1) fprintf(stderr, "ping %s ", inet_ntoa(hostaddr)); tottime.tv_sec = 10; tottime.tv_usec = 0; /* * We use the pmap_rmtcall interface because the normal * portmapper has a wired-in 60 second timeout */ server_addr.sin_family = AF_INET; server_addr.sin_addr = hostaddr; server_addr.sin_port = 0; clnt_stat = pmap_rmtcall(&server_addr, MOUNTPROG, MOUNTVERS, NULLPROC, xdr_void, 0, xdr_void, 0, tottime, &port); if (clnt_stat == RPC_SUCCESS) { goodhost = hostaddr; goodtime = time_now + cache_time; } else { deadhost = hostaddr; deadtime = time_now + cache_time; } if (trace > 1) fprintf(stderr, "%s\n", clnt_stat == RPC_SUCCESS ? "OK" : "NO RESPONSE"); return (clnt_stat);}struct in_addr gotaddr;/* ARGSUSED */catchfirst(ignore, raddr) struct sockaddr_in *raddr;{ gotaddr = raddr->sin_addr; return (1); /* first one ends search */}/* * ping a bunch of hosts at once and find out who * responds first */struct in_addrtrymany(addrs, timeout) struct in_addr *addrs; int timeout;{ enum clnt_stat many_cast(); enum clnt_stat clnt_stat; if (trace > 1) { register struct in_addr *a; fprintf(stderr, "many_cast: "); for (a = addrs ; a->s_addr ; a++) fprintf(stderr, "%s ", inet_ntoa(*a)); fprintf(stderr, "\n"); } gotaddr.s_addr = 0; clnt_stat = many_cast(addrs, MOUNTPROG, MOUNTVERS, NULLPROC, xdr_void, 0, xdr_void, 0, catchfirst, timeout); if (trace > 1) { fprintf(stderr, "many_cast: got %s\n", (int) clnt_stat ? "no response" : inet_ntoa(gotaddr)); } if (clnt_stat) syslog(LOG_ERR, "trymany: servers not responding: %s", clnt_sperrno(clnt_stat)); return (gotaddr);}nfsstatnfsmount(host, hostaddr, dir, mntpnt, opts, fsp) char *host, *dir, *mntpnt, *opts; struct in_addr hostaddr; struct filsys **fsp;{ struct filsys *fs; char remname[MAXPATHLEN]; struct mntent m; struct nfs_gfs_mount args; int flags; struct sockaddr_in sin; static struct fhstatus fhs; struct timeval timeout; CLIENT *client; enum clnt_stat rpc_stat; enum clnt_stat pingmount(); int s; u_short port; nfsstat status; struct stat stbuf; struct fs_data fsdata; if (lstat(mntpnt, &stbuf) < 0) { syslog(LOG_ERR, "Couldn't stat %s: %m", mntpnt); return (NFSERR_NOENT); } if ((stbuf.st_mode & S_IFMT) == S_IFLNK) { if (readlink(mntpnt, remname, sizeof remname) < 0) return (NFSERR_NOENT); if (remname[0] == '/') { syslog(LOG_ERR, "%s -> %s from %s: absolute symbolic link", mntpnt, remname, host); return (NFSERR_NOENT); } } /* * get fhandle of remote path from server's mountd */ (void) sprintf(remname, "%s:%s", host, dir); bzero((char *)&sin, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_addr.s_addr = hostaddr.s_addr; timeout.tv_usec = 0; timeout.tv_sec = mount_timeout; s = RPC_ANYSOCK; if ((client = clntudp_create(&sin, MOUNTPROG, MOUNTVERS, timeout, &s)) == NULL) { syslog(LOG_ERR, "%s %s", remname, clnt_spcreateerror("server not responding")); return (NFSERR_NOENT); }#ifdef OLDMOUNT if (bindresvport(s, NULL)) syslog(LOG_ERR, "Warning: cannot do local bind");#endif client->cl_auth = authunix_create_default(); timeout.tv_usec = 0; timeout.tv_sec = mount_timeout; rpc_stat = clnt_call(client, MOUNTPROC_MNT, xdr_path, &dir, xdr_fhstatus, &fhs, timeout); if (rpc_stat != RPC_SUCCESS) { /* * Given the way "clnt_sperror" works, the "%s" immediately * following the "not responding" is correct. */ syslog(LOG_ERR, "%s server not responding%s", remname, clnt_sperror(client, "")); (void) close(s); clnt_destroy(client); return (NFSERR_NOENT); } (void) close(s); AUTH_DESTROY(client->cl_auth); clnt_destroy(client); if (errno = fhs.fhs_status) { if (errno == EACCES) { status = NFSERR_ACCES; } else { syslog(LOG_ERR, "%s: %m", remname); status = NFSERR_IO; } return (status); } /* * set mount args */ args.fh = (fhandle_t *)&fhs.fhs_fh; args.hostname = host; args.flags = 0; args.flags |= (NFSMNT_HOSTNAME | NFSMNT_INT); args.gfs_flags = 0; args.addr = &sin; m.mnt_opts = opts; args.optstr = m.mnt_opts; args.pg_thresh = SIXTYFOUR; args.acregmin = NFSAC_REGMIN; args.acregmax = NFSAC_REGMAX; args.acdirmin = NFSAC_DIRMIN; args.acdirmax = NFSAC_DIRMAX; /* ignore sun secure mount option */ if (hasmntopt(&m, MNTOPT_SECURE) != NULL) { syslog(LOG_ERR, "Mount of %s on %s; secure option specified: %m", remname, mntpnt); return (NFSERR_IO); } if (hasmntopt(&m, MNTOPT_SOFT) != NULL) { args.flags |= NFSMNT_SOFT; } if (hasmntopt(&m, MNTOPT_INT) != NULL) { args.flags |= NFSMNT_INT; } if (hasmntopt(&m, MNTOPT_NOEXEC) != NULL) { args.gfs_flags |= M_NOEXEC; } if (hasmntopt(&m, MNTOPT_NOSUID) != NULL) { args.gfs_flags |= M_NOSUID; } if (hasmntopt(&m, MNTOPT_NODEV) != NULL) { args.gfs_flags |= M_NODEV; } if (hasmntopt(&m, MNTOPT_NOAC) != NULL) { args.flags |= NFSMNT_NOAC; } if (port = nopt(&m, "port")) { sin.sin_port = htons(port); } else { sin.sin_port = htons(NFS_PORT); /* XXX should use portmapper */ } if (args.rsize = nopt(&m, "rsize")) { args.flags |= NFSMNT_RSIZE; } if (args.wsize = nopt(&m, "wsize")) { args.flags |= NFSMNT_WSIZE; } if (args.timeo = nopt(&m, "timeo")) { args.flags |= NFSMNT_TIMEO; } if (args.retrans = nopt(&m, "retrans")) { args.flags |= NFSMNT_RETRANS; } flags = 0; flags |= (hasmntopt(&m, MNTOPT_RO) == NULL) ? 0 : M_RONLY; if (trace > 1) { fprintf(stderr, "mount %s %s (%s)\n", remname, mntpnt, opts); }#ifdef OLDMOUNT#define MOUNT_NFS 1 if (mount(remname, mntpnt, flags, 0x05, &args)) {#else if (mount(remname, mntpnt, flags, 0x05, &args)) {#endif syslog(LOG_ERR, "Mount of %s on %s: %m", remname, mntpnt); return (NFSERR_IO); } if (trace > 1) { fprintf(stderr, "mount %s OK\n", remname); } if (*fsp) fs = *fsp; else { fs = alloc_fs(host, dir, mntpnt, opts); if (fs == NULL) return (NFSERR_NOSPC); } if (getmnt(0, &fsdata, 0, NOSTAT_ONE, mntpnt) < 1) { /* Couldn't get dev number; we'll try later */ fs->fs_dev = -1; } else { /* Got it; save it away for the umount */ fs->fs_dev = fsdata.fd_req.dev; } fs->fs_type = MNTTYPE_NFS; fs->fs_mine = 1; fs->fs_nfsargs = args; fs->fs_mflags = flags; fs->fs_nfsargs.hostname = fs->fs_host; fs->fs_nfsargs.addr = &fs->fs_addr; fs->fs_nfsargs.fh = (fhandle_t *)&fs->fs_rootfh; fs->fs_addr = sin; bcopy(&fhs.fhs_fh, &fs->fs_rootfh, sizeof fs->fs_rootfh); *fsp = fs; return (NFS_OK);}nfsstatremount(fs) struct filsys *fs;{ char remname[1024]; if (fs->fs_nfsargs.fh == 0) return nfsmount(fs->fs_host, fs->fs_addr.sin_addr, fs->fs_dir, fs->fs_mntpnt, fs->fs_opts, &fs); (void) sprintf(remname, "%s:%s", fs->fs_host, fs->fs_dir); if (trace > 1) { fprintf(stderr, "remount %s %s (%s)\n", remname, fs->fs_mntpnt, fs->fs_opts); }#ifdef OLDMOUNT if (mount(remname, fs->fs_mntpnt, fs->fs_mflags, 0x05, &fs->fs_nfsargs)) {#else if (mount(remname, fs->fs_mntpnt, fs->fs_mflags, 0x05, &fs->fs_nfsargs)) {#endif syslog(LOG_ERR, "Remount of %s on %s: %m", remname, fs->fs_mntpnt); return (NFSERR_IO); } if (trace > 1) { fprintf(stderr, "remount %s OK\n", remname); } return (NFS_OK);}/* * Return the value of a numeric option of the form foo=x, if * option is not found or is malformed, return 0. */nopt(mnt, opt) struct mntent *mnt; char *opt;{ int val = 0; char *equal; char *str; if (str = (char *)hasmntopt(mnt, opt)) { if (equal = index(str, '=')) { val = atoi(&equal[1]); } else { syslog(LOG_ERR, "Bad numeric option '%s'", str); } } return (val);}same_opts(opts1, opts2) char *opts1, *opts2;{ int has1, has2; struct mntent m1, m2; m1.mnt_opts = opts1; m2.mnt_opts = opts2; has1 = hasmntopt(&m1, MNTOPT_RO) != NULL; has2 = hasmntopt(&m2, MNTOPT_RO) != NULL; if (has1 != has2) return(0); has1 = hasmntopt(&m1, MNTOPT_NOSUID) != NULL; has2 = hasmntopt(&m2, MNTOPT_NOSUID) != NULL; if (has1 != has2) return(0); has1 = hasmntopt(&m1, MNTOPT_SOFT) != NULL; has2 = hasmntopt(&m2, MNTOPT_SOFT) != NULL; if (has1 != has2) return(0); has1 = hasmntopt(&m1, MNTOPT_INT) != NULL; has2 = hasmntopt(&m2, MNTOPT_INT) != NULL; if (has1 != has2) return(0); return(1);}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?