1 | /* |
---|
2 | * $Source: /afs/dev.mit.edu/source/repository/athena/bin/attach/nfs.c,v $ |
---|
3 | * $Author: probe $ |
---|
4 | * |
---|
5 | * Copyright (c) 1988 by the Massachusetts Institute of Technology. |
---|
6 | */ |
---|
7 | |
---|
8 | static char *rcsid_nfs_c = "$Header: /afs/dev.mit.edu/source/repository/athena/bin/attach/nfs.c,v 1.6 1991-07-01 09:47:19 probe Exp $"; |
---|
9 | |
---|
10 | #include "attach.h" |
---|
11 | #ifdef NFS |
---|
12 | |
---|
13 | /* If the timeout is not explicitly specified by the attach command, |
---|
14 | * it is set to 20 tenths of a second (i.e. 2 seconds). This should |
---|
15 | * really be set in the kernel, but due to release shakedown timing, |
---|
16 | * it's kludged in here. |
---|
17 | * Similarly with retransmissions. |
---|
18 | * |
---|
19 | * The kernel will double the timeout on each retry until it reaches a |
---|
20 | * max of 60 seconds, at which point it uses 60 seconds for the timeout. |
---|
21 | * |
---|
22 | * current kernel defaults: 4 retrans, 7 tenths sec timeout. |
---|
23 | * -JTK, 24 Oct 88 |
---|
24 | * |
---|
25 | * The new values are: 6 retrans, 8 tenths sec timeout. |
---|
26 | * The total timeout period is approximately 100 seconds, thus |
---|
27 | * compensating for a gateway rebooting (~40 seconds). |
---|
28 | * -RPB, 9 Feb 88 |
---|
29 | * |
---|
30 | * Calculations: |
---|
31 | * total time = timeout * (2^(retrans) - 1) |
---|
32 | * [derived from sum of geometric series = a(r^n-1)/(r-1)] |
---|
33 | * a = initial timeout |
---|
34 | * r = 2 |
---|
35 | * n = retrans |
---|
36 | * |
---|
37 | * This holds true while timeout * 2^retrans <= 60 seconds |
---|
38 | */ |
---|
39 | |
---|
40 | #define TIMEO_DEFAULT 8 |
---|
41 | #define RETRANS_DEFAULT 7 |
---|
42 | |
---|
43 | nfs_attach(at, mopt, errorout) |
---|
44 | struct _attachtab *at; |
---|
45 | struct mntopts *mopt; |
---|
46 | int errorout; |
---|
47 | { |
---|
48 | char fsname[BUFSIZ]; |
---|
49 | static char myhostname[BUFSIZ] = ""; |
---|
50 | |
---|
51 | /* |
---|
52 | * Handle the 'n' mode. |
---|
53 | */ |
---|
54 | if (at->mode == 'n') { |
---|
55 | add_options(mopt, "ro"); |
---|
56 | } |
---|
57 | |
---|
58 | /* |
---|
59 | * Try to figure out information about myself. Use fsname |
---|
60 | * as a temporary buffer. |
---|
61 | */ |
---|
62 | if (!myhostname[0]) { |
---|
63 | if (gethostname(myhostname, sizeof(myhostname))) { |
---|
64 | if (debug_flag) |
---|
65 | perror("gethostname"); |
---|
66 | } |
---|
67 | } |
---|
68 | |
---|
69 | if (myhostname[0]) { |
---|
70 | if (host_compare(myhostname, at->host)) { |
---|
71 | if (!override) { |
---|
72 | fprintf(stderr, |
---|
73 | "%s: (filesystem %s) NFS self mount not allowed.\n", |
---|
74 | progname, at->hesiodname); |
---|
75 | error_status = ERR_ATTACHNOTALLOWED; |
---|
76 | return(FAILURE); |
---|
77 | } |
---|
78 | fprintf(stderr, "%s: (filesystem %s) warning: NFS self mount\n", |
---|
79 | progname, at->hesiodname); |
---|
80 | } |
---|
81 | } |
---|
82 | |
---|
83 | if ((at->mode != 'n') && do_nfsid) |
---|
84 | if (nfsid(at->host, at->hostaddr[0], MOUNTPROC_KUIDMAP, |
---|
85 | errorout, at->hesiodname, 1, owner_uid) == FAILURE) { |
---|
86 | if (mopt->flags & M_RDONLY) { |
---|
87 | printf("%s: Warning, mapping failed for filesystem %s,\n\tcontinuing with read-only mount.\n", |
---|
88 | progname, at->hesiodname); |
---|
89 | /* So the mount rpc wins */ |
---|
90 | clear_errored(at->hostaddr[0]); |
---|
91 | } else if(at->mode == 'm') { |
---|
92 | printf("%s: Warning, mapping failed for filesystem %s.\n", |
---|
93 | progname, at->hesiodname); |
---|
94 | error_status = 0; |
---|
95 | clear_errored(at->hostaddr[0]); |
---|
96 | } else |
---|
97 | return (FAILURE); |
---|
98 | } |
---|
99 | |
---|
100 | if (!(mopt->tsa.nfs.flags & NFSMNT_RETRANS)) { |
---|
101 | mopt->tsa.nfs.flags |= NFSMNT_RETRANS; |
---|
102 | mopt->tsa.nfs.retrans = RETRANS_DEFAULT; |
---|
103 | } |
---|
104 | |
---|
105 | if (!(mopt->tsa.nfs.flags & NFSMNT_TIMEO)) { |
---|
106 | mopt->tsa.nfs.flags |= NFSMNT_TIMEO; |
---|
107 | mopt->tsa.nfs.timeo = TIMEO_DEFAULT; |
---|
108 | } |
---|
109 | |
---|
110 | /* XXX This is kind of bogus, because if a filesystem has a number |
---|
111 | * of hesiod entries, and the mount point is busy, each one will |
---|
112 | * be tried until the last one fails, then an error printed. |
---|
113 | * C'est la vie. |
---|
114 | */ |
---|
115 | |
---|
116 | sprintf(fsname, "%s:%s", at->host, at->hostdir); |
---|
117 | |
---|
118 | if (mountfs(at, fsname, mopt, errorout) == FAILURE) { |
---|
119 | if ((at->mode != 'n') && do_nfsid) |
---|
120 | nfsid(at->host, at->hostaddr[0], MOUNTPROC_KUIDUMAP, |
---|
121 | errorout, at->hesiodname, 1, owner_uid); |
---|
122 | return (FAILURE); |
---|
123 | } |
---|
124 | |
---|
125 | return (SUCCESS); |
---|
126 | } |
---|
127 | |
---|
128 | /* |
---|
129 | * Detach an NFS filesystem. |
---|
130 | */ |
---|
131 | nfs_detach(at) |
---|
132 | struct _attachtab *at; |
---|
133 | { |
---|
134 | if ((at->mode != 'n') && do_nfsid && |
---|
135 | nfsid(at->host, at->hostaddr[0], MOUNTPROC_KUIDUMAP, 1, |
---|
136 | at->hesiodname,0, owner_uid) == FAILURE) |
---|
137 | printf("%s: Warning: couldn't unmap filesystem %s/host %s\n", |
---|
138 | progname, at->hesiodname, at->host); |
---|
139 | |
---|
140 | if (at->flags & FLAG_PERMANENT) { |
---|
141 | if (debug_flag) |
---|
142 | printf("Permanent flag on, skipping umount.\n"); |
---|
143 | return(SUCCESS); |
---|
144 | } |
---|
145 | |
---|
146 | if (nfs_unmount(at->hesiodname, at->host, at->hostaddr[0], |
---|
147 | at->mntpt, at->hostdir) == FAILURE) |
---|
148 | return (FAILURE); |
---|
149 | |
---|
150 | return (SUCCESS); |
---|
151 | } |
---|
152 | |
---|
153 | /* |
---|
154 | * Parsing of explicit NFS file types |
---|
155 | */ |
---|
156 | char **nfs_explicit(name) |
---|
157 | char *name; |
---|
158 | { |
---|
159 | char temp[BUFSIZ], host[BUFSIZ]; |
---|
160 | char *dir, *cp; |
---|
161 | char newmntpt[BUFSIZ]; |
---|
162 | extern char *exp_hesptr[2]; |
---|
163 | |
---|
164 | strcpy(host, name); |
---|
165 | dir = index(host, ':'); |
---|
166 | if (!dir) { |
---|
167 | fprintf(stderr, "%s: Illegal explicit definition \"%s\" for type %s\n", |
---|
168 | progname, name, filsys_type); |
---|
169 | return (0); |
---|
170 | } |
---|
171 | *dir = '\0'; |
---|
172 | dir++; |
---|
173 | if (*dir != '/') { |
---|
174 | fprintf(stderr, "%s: Illegal explicit definition \"%s\" for type %s\n", |
---|
175 | progname, name, filsys_type); |
---|
176 | return (0); |
---|
177 | } |
---|
178 | if (!nfs_mount_dir) |
---|
179 | nfs_mount_dir = strdup(""); |
---|
180 | if (!mntpt) { |
---|
181 | strcpy(temp, host); |
---|
182 | /* |
---|
183 | * Zero out any domain names, since they're ugly as mount |
---|
184 | * points. |
---|
185 | */ |
---|
186 | if (cp = index(temp, '.')) |
---|
187 | *cp = '\0'; |
---|
188 | if (!strcmp(dir, "/")) { |
---|
189 | if (nfs_root_hack) |
---|
190 | sprintf(newmntpt, "%s/%s/root", |
---|
191 | nfs_mount_dir, temp); |
---|
192 | else |
---|
193 | sprintf(newmntpt, "%s/%s", nfs_mount_dir, temp); |
---|
194 | } else |
---|
195 | sprintf(newmntpt, "%s/%s%s", nfs_mount_dir, temp, dir); |
---|
196 | } |
---|
197 | |
---|
198 | sprintf(exp_hesline, "NFS %s %s %c %s", dir, host, override_mode ? |
---|
199 | override_mode : 'w',mntpt ? mntpt : newmntpt); |
---|
200 | exp_hesptr[0] = exp_hesline; |
---|
201 | exp_hesptr[1] = 0; |
---|
202 | return (exp_hesptr); |
---|
203 | } |
---|
204 | #endif |
---|