1 | /* Created by: Robert French |
---|
2 | * |
---|
3 | * $Source: /afs/dev.mit.edu/source/repository/athena/bin/attach/detach.c,v $ |
---|
4 | * $Author: probe $ |
---|
5 | * |
---|
6 | * Copyright (c) 1988 by the Massachusetts Institute of Technology. |
---|
7 | */ |
---|
8 | |
---|
9 | static char *rcsid_detach_c = "$Header: /afs/dev.mit.edu/source/repository/athena/bin/attach/detach.c,v 1.11 1992-01-27 03:09:15 probe Exp $"; |
---|
10 | |
---|
11 | #include "attach.h" |
---|
12 | #include <string.h> |
---|
13 | |
---|
14 | /* |
---|
15 | * Detach the filesystem called name. |
---|
16 | */ |
---|
17 | |
---|
18 | detach(name) |
---|
19 | const char *name; |
---|
20 | { |
---|
21 | struct _attachtab *atp, at; |
---|
22 | int status, bymntpt; |
---|
23 | #ifdef ZEPHYR |
---|
24 | char instbfr[BUFSIZ]; |
---|
25 | #endif |
---|
26 | |
---|
27 | lock_attachtab(); |
---|
28 | get_attachtab(); |
---|
29 | bymntpt = 0; |
---|
30 | if (!(atp = attachtab_lookup(name))) { |
---|
31 | if (!(atp = attachtab_lookup_mntpt(name))) { |
---|
32 | unlock_attachtab(); |
---|
33 | free_attachtab(); |
---|
34 | fprintf(stderr, "%s: Filesystem \"%s\" is not attached\n", progname, name); |
---|
35 | error_status = ERR_DETACHNOTATTACHED; |
---|
36 | return (FAILURE); |
---|
37 | } else |
---|
38 | bymntpt = 1; |
---|
39 | } |
---|
40 | |
---|
41 | switch (atp->status) { |
---|
42 | case STATUS_ATTACHING: |
---|
43 | if (!force && really_in_use(name)) { |
---|
44 | fprintf(stderr, "%s: Filesystem \"%s\" is being attached by another process\n", |
---|
45 | progname, name); |
---|
46 | error_status = ERR_DETACHINUSE; |
---|
47 | unlock_attachtab(); |
---|
48 | free_attachtab(); |
---|
49 | return (FAILURE); |
---|
50 | } |
---|
51 | /* |
---|
52 | * Derelict entry...here might be a good place for attachtab/mtab |
---|
53 | * reconciliation. |
---|
54 | */ |
---|
55 | break; |
---|
56 | case STATUS_DETACHING: |
---|
57 | if (!force && really_in_use(name)) { |
---|
58 | fprintf(stderr, "%s: Filesystem \"%s\" already being detached by another process\n", |
---|
59 | progname, name); |
---|
60 | error_status = ERR_DETACHINUSE; |
---|
61 | unlock_attachtab(); |
---|
62 | free_attachtab(); |
---|
63 | return (FAILURE); |
---|
64 | } |
---|
65 | break; |
---|
66 | } |
---|
67 | |
---|
68 | /* Note: attachtab still locked at this point */ |
---|
69 | |
---|
70 | start_critical_code(); |
---|
71 | if (clean_detach) { |
---|
72 | if (clean_attachtab(atp)) { |
---|
73 | put_attachtab(); |
---|
74 | unlock_attachtab(); |
---|
75 | free_attachtab(); |
---|
76 | end_critical_code(); |
---|
77 | return(SUCCESS); |
---|
78 | } |
---|
79 | /* |
---|
80 | * If we fall through, it means we should detach the filesystem |
---|
81 | */ |
---|
82 | } |
---|
83 | if (atp->status == STATUS_ATTACHED) { |
---|
84 | if (override) { /* Override _all_ owners and detach */ |
---|
85 | atp->nowners = 0; |
---|
86 | atp->flags &= ~FLAG_LOCKED; |
---|
87 | status = SUCCESS; |
---|
88 | } else if (owner_check && !clean_detach) { |
---|
89 | if (del_an_owner(atp, owner_uid)) { |
---|
90 | int ret = SUCCESS; |
---|
91 | fprintf(stderr, "%s: Filesystem \"%s\" wanted by others, not unmounted.\n", |
---|
92 | progname, name); |
---|
93 | error_status = ERR_ATTACHINUSE; |
---|
94 | put_attachtab(); |
---|
95 | unlock_attachtab(); |
---|
96 | if (atp->fs->type == TYPE_NFS && do_nfsid) |
---|
97 | ret = nfsid(atp->host, atp->hostaddr[0], |
---|
98 | MOUNTPROC_KUIDUMAP, 1, |
---|
99 | atp->hesiodname, 0, real_uid); |
---|
100 | free_attachtab(); |
---|
101 | end_critical_code(); |
---|
102 | return(ret); |
---|
103 | } |
---|
104 | status = SUCCESS; |
---|
105 | } |
---|
106 | if (!override && atp->flags & FLAG_LOCKED) { |
---|
107 | error_status = ERR_DETACHNOTALLOWED; |
---|
108 | if (trusted_user(real_uid)) |
---|
109 | fprintf(stderr, |
---|
110 | "%s: Filesystem \"%s\" locked, use -override to detach it.\n", |
---|
111 | progname, name); |
---|
112 | else |
---|
113 | fprintf(stderr, "%s: Filesystem \"%s\" locked, can't detach\n", |
---|
114 | progname, name); |
---|
115 | put_attachtab(); |
---|
116 | unlock_attachtab(); |
---|
117 | free_attachtab(); |
---|
118 | end_critical_code(); |
---|
119 | return(FAILURE); |
---|
120 | } |
---|
121 | |
---|
122 | } |
---|
123 | atp->status = STATUS_DETACHING; |
---|
124 | put_attachtab(); |
---|
125 | mark_in_use(name); |
---|
126 | at = *atp; |
---|
127 | unlock_attachtab(); |
---|
128 | free_attachtab(); |
---|
129 | |
---|
130 | if (at.fs->detach) |
---|
131 | status = (at.fs->detach)(&at); |
---|
132 | else { |
---|
133 | fprintf(stderr, "%s: Can't detach filesystem type \"%s\"\n", |
---|
134 | progname, at.fs->name); |
---|
135 | status = ERR_FATAL; |
---|
136 | return(FAILURE); |
---|
137 | } |
---|
138 | |
---|
139 | if (status == SUCCESS) { |
---|
140 | if (verbose) |
---|
141 | printf("%s: %s detached\n", progname, at.hesiodname); |
---|
142 | if (at.fs->flags & AT_FS_MNTPT) |
---|
143 | rm_mntpt(&at); |
---|
144 | lock_attachtab(); |
---|
145 | get_attachtab(); |
---|
146 | if (bymntpt) |
---|
147 | attachtab_delete(attachtab_lookup_mntpt(at.mntpt)); |
---|
148 | else |
---|
149 | attachtab_delete(attachtab_lookup(at.hesiodname)); |
---|
150 | put_attachtab(); |
---|
151 | mark_in_use(NULL); |
---|
152 | unlock_attachtab(); |
---|
153 | /* |
---|
154 | * Do Zephyr stuff as necessary |
---|
155 | */ |
---|
156 | #ifdef ZEPHYR |
---|
157 | if (use_zephyr && at.fs->flags & AT_FS_REMOTE) { |
---|
158 | sprintf(instbfr, "%s:%s", at.host, at.hostdir); |
---|
159 | zephyr_addsub(instbfr); |
---|
160 | if (!host_occurs(at.host)) |
---|
161 | zephyr_addsub(at.host); |
---|
162 | } |
---|
163 | #endif |
---|
164 | free_attachtab(); |
---|
165 | } else { |
---|
166 | lock_attachtab(); |
---|
167 | get_attachtab(); |
---|
168 | at.status = STATUS_ATTACHED; |
---|
169 | attachtab_replace(&at); |
---|
170 | put_attachtab(); |
---|
171 | mark_in_use(NULL); |
---|
172 | unlock_attachtab(); |
---|
173 | free_attachtab(); |
---|
174 | } |
---|
175 | end_critical_code(); |
---|
176 | return (status); |
---|
177 | } |
---|
178 | |
---|
179 | /* |
---|
180 | * Detach all filesystems. Read through the attachtab and call detach |
---|
181 | * on each one. |
---|
182 | */ |
---|
183 | |
---|
184 | void detach_all() |
---|
185 | { |
---|
186 | struct _attachtab *atp, *next; |
---|
187 | int tempexp; |
---|
188 | extern struct _attachtab *attachtab_last, *attachtab_first; |
---|
189 | struct _fstypes *fs_type = NULL; |
---|
190 | |
---|
191 | lock_attachtab(); |
---|
192 | get_attachtab(); |
---|
193 | unlock_attachtab(); |
---|
194 | |
---|
195 | if (filsys_type) |
---|
196 | fs_type = get_fs(filsys_type); |
---|
197 | tempexp = explicit; |
---|
198 | atp = attachtab_last; |
---|
199 | attachtab_last = attachtab_first = NULL; |
---|
200 | while (atp) { |
---|
201 | next = atp->prev; |
---|
202 | explicit = atp->explicit; |
---|
203 | if ((override || !owner_check || clean_detach |
---|
204 | || is_an_owner(atp,owner_uid)) && |
---|
205 | (!filsys_type || fs_type == atp->fs)) { |
---|
206 | if (atp->flags & FLAG_LOCKED) { |
---|
207 | del_an_owner(atp, owner_uid); |
---|
208 | lock_attachtab(); |
---|
209 | get_attachtab(); |
---|
210 | attachtab_replace(atp); |
---|
211 | put_attachtab(); |
---|
212 | unlock_attachtab(); |
---|
213 | fprintf(stderr, |
---|
214 | "%s: Filesystem \"%s\" locked, not unmounted.\n", |
---|
215 | progname, atp->hesiodname); |
---|
216 | } else |
---|
217 | detach(atp->hesiodname); |
---|
218 | } |
---|
219 | free(atp); |
---|
220 | atp = next; |
---|
221 | } |
---|
222 | free_attachtab(); |
---|
223 | explicit = tempexp; |
---|
224 | } |
---|
225 | |
---|
226 | /* |
---|
227 | * Detach routine for the NULL filesystem. This is for cleanup |
---|
228 | * purposes only. |
---|
229 | */ |
---|
230 | |
---|
231 | null_detach(at, mopt, errorout) |
---|
232 | struct _attachtab *at; |
---|
233 | struct mntopts *mopt; |
---|
234 | int errorout; |
---|
235 | { |
---|
236 | if (debug_flag) |
---|
237 | printf("Detaching null filesystem %s...\n", at->hesiodname); |
---|
238 | |
---|
239 | return(SUCCESS); |
---|
240 | } |
---|
241 | |
---|
242 | |
---|
243 | /* |
---|
244 | * Detach all filesystems from a specified host. Read through the |
---|
245 | * attachtab and call detach on each one. |
---|
246 | */ |
---|
247 | |
---|
248 | void detach_host(host) |
---|
249 | const char *host; |
---|
250 | { |
---|
251 | struct _attachtab *atp, *next; |
---|
252 | int tempexp; |
---|
253 | extern struct _attachtab *attachtab_last, *attachtab_first; |
---|
254 | struct _fstypes *fs_type = NULL; |
---|
255 | register int i; |
---|
256 | |
---|
257 | lock_attachtab(); |
---|
258 | get_attachtab(); |
---|
259 | unlock_attachtab(); |
---|
260 | |
---|
261 | if (filsys_type) |
---|
262 | fs_type = get_fs(filsys_type); |
---|
263 | tempexp = explicit; |
---|
264 | atp = attachtab_last; |
---|
265 | attachtab_last = attachtab_first = NULL; |
---|
266 | while (atp) { |
---|
267 | next = atp->prev; |
---|
268 | explicit = atp->explicit; |
---|
269 | if ((override || !owner_check || clean_detach |
---|
270 | || is_an_owner(atp,owner_uid)) && |
---|
271 | (!filsys_type || fs_type == atp->fs)) { |
---|
272 | for (i=0; i<MAXHOSTS && atp->hostaddr[i].s_addr; i++) |
---|
273 | if (host_compare(host, inet_ntoa(atp->hostaddr[i]))) { |
---|
274 | if (atp->flags & FLAG_LOCKED) { |
---|
275 | del_an_owner(atp, owner_uid); |
---|
276 | lock_attachtab(); |
---|
277 | get_attachtab(); |
---|
278 | attachtab_replace(atp); |
---|
279 | put_attachtab(); |
---|
280 | unlock_attachtab(); |
---|
281 | fprintf(stderr, |
---|
282 | "%s: Filesystem \"%s\" locked, not unmounted.\n", |
---|
283 | progname, atp->hesiodname); |
---|
284 | } else |
---|
285 | detach(atp->hesiodname); |
---|
286 | break; |
---|
287 | } |
---|
288 | } |
---|
289 | free(atp); |
---|
290 | atp = next; |
---|
291 | } |
---|
292 | free_attachtab(); |
---|
293 | explicit = tempexp; |
---|
294 | } |
---|