 |
|
|
| |
1 /*
2 * Copyright (c) 1997-2005 Erez Zadok
3 * Copyright (c) 1990 Jan-Simon Pendry
4 * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
5 * Copyright (c) 1990 The Regents of the University of California.
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to Berkeley by
9 * Jan-Simon Pendry at Imperial College, London.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. All advertising materials mentioning features or use of this software
20 * must display the following acknowledgment:
21 * This product includes software developed by the University of
22 * California, Berkeley and its contributors.
23 * 4. Neither the name of the University nor the names of its contributors
24 * may be used to endorse or promote products derived from this software
25 * without specific prior written permission.
26 *
27 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
28 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
31 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 * SUCH DAMAGE.
38 *
39 *
40 * File: am-utils/amd/amq_subr.c
41 *
42 */
43 /*
44 * Auxiliary routines for amq tool
45 */
46
47 #ifdef HAVE_CONFIG_H
48 # include <config.h>
49 #endif /* HAVE_CONFIG_H */
50 #include <am_defs.h>
51 #include <amd.h>
52
53 /* forward definitions */
54 bool_t xdr_amq_mount_tree_node(XDR *xdrs, amq_mount_tree *objp);
55 bool_t xdr_amq_mount_subtree(XDR *xdrs, amq_mount_tree *objp);
56
57
58 voidp
59 amqproc_null_1_svc(voidp argp, struct svc_req *rqstp)
60 {
61 static char res;
62
63 return (voidp) &res;
64 }
65
66
67 /*
68 * Return a sub-tree of mounts
69 */
70 amq_mount_tree_p *
71 amqproc_mnttree_1_svc(voidp argp, struct svc_req *rqstp)
72 {
73 static am_node *mp;
74
75 mp = find_ap(*(char **) argp);
76 return (amq_mount_tree_p *) ((void *)&mp);
77 }
78
79
80 /*
81 * Unmount a single node
82 */
83 voidp
84 amqproc_umnt_1_svc(voidp argp, struct svc_req *rqstp)
85 {
86 static char res;
87 am_node *mp = find_ap(*(char **) argp);
88
89 if (mp)
90 forcibly_timeout_mp(mp);
91
92 return (voidp) &res;
93 }
94
95
96 /*
97 * Return global statistics
98 */
99 amq_mount_stats *
100 amqproc_stats_1_svc(voidp argp, struct svc_req *rqstp)
101 {
102 return (amq_mount_stats *) ((void *)&amd_stats);
103 }
104
105
106 /*
107 * Return the entire tree of mount nodes
108 */
109 amq_mount_tree_list *
110 amqproc_export_1_svc(voidp argp, struct svc_req *rqstp)
111 {
112 static amq_mount_tree_list aml;
113 static am_node *mp;
114
115 mp = get_exported_ap(0);
116 aml.amq_mount_tree_list_val = (amq_mount_tree_p *) ((void *) &mp);
117 aml.amq_mount_tree_list_len = 1; /* XXX */
118
119 return &aml;
120 }
121
122
123 int *
124 amqproc_setopt_1_svc(voidp argp, struct svc_req *rqstp)
125 {
126 static int rc;
127 amq_setopt *opt = (amq_setopt *) argp;
128
129 rc = 0;
130
131 switch (opt->as_opt) {
132
133 case AMOPT_DEBUG:
134 if (debug_option(opt->as_str))
135 rc = EINVAL;
136 break;
137
138 case AMOPT_LOGFILE:
139 if (gopt.logfile && opt->as_str
140 && STREQ(gopt.logfile, opt->as_str)) {
141 if (switch_to_logfile(opt->as_str, orig_umask, 0))
142 rc = EINVAL;
143 } else {
144 rc = EACCES;
145 }
146 break;
147
148 case AMOPT_XLOG:
149 if (switch_option(opt->as_str))
150 rc = EINVAL;
151 break;
152
153 case AMOPT_FLUSHMAPC:
154 if (amd_state == Run) {
155 plog(XLOG_INFO, "amq says flush cache");
156 do_mapc_reload = 0;
157 flush_nfs_fhandle_cache((fserver *) NULL);
158 flush_srvr_nfs_cache((fserver *) NULL);
159 }
160 break;
161 }
162
163 return &rc;
164 }
165
166
167 amq_mount_info_list *
168 amqproc_getmntfs_1_svc(voidp argp, struct svc_req *rqstp)
169 {
170 return (amq_mount_info_list *) ((void *)&mfhead); /* XXX */
171 }
172
173
174 amq_string *
175 amqproc_getvers_1_svc(voidp argp, struct svc_req *rqstp)
176 {
177 static amq_string res;
178
179 res = get_version_string();
180 return &res;
181 }
182
183
184 /* get PID of remote amd */
185 int *
186 amqproc_getpid_1_svc(voidp argp, struct svc_req *rqstp)
187 {
188 static int res;
189
190 res = getpid();
191 return &res;
192 }
193
194
195 /*
196 * XDR routines.
197 */
198
199
200 bool_t
201 xdr_amq_setopt(XDR *xdrs, amq_setopt *objp)
202 {
203 if (!xdr_enum(xdrs, (enum_t *) & objp->as_opt)) {
204 return (FALSE);
205 }
206 if (!xdr_string(xdrs, &objp->as_str, AMQ_STRLEN)) {
207 return (FALSE);
208 }
209 return (TRUE);
210 }
211
212
213 /*
214 * More XDR routines - Should be used for OUTPUT ONLY.
215 */
216 bool_t
217 xdr_amq_mount_tree_node(XDR *xdrs, amq_mount_tree *objp)
218 {
219 am_node *mp = (am_node *) objp;
220 long mtime;
221
222 if (!xdr_amq_string(xdrs, &mp->am_mnt->mf_info)) {
223 return (FALSE);
224 }
225 if (!xdr_amq_string(xdrs, &mp->am_path)) {
226 return (FALSE);
227 }
228 if (!xdr_amq_string(xdrs, mp->am_link ? &mp->am_link : &mp->am_mnt->mf_mount)) {
229 return (FALSE);
230 }
231 if (!xdr_amq_string(xdrs, &mp->am_mnt->mf_ops->fs_type)) {
232 return (FALSE);
233 }
234 mtime = mp->am_stats.s_mtime;
235 if (!xdr_long(xdrs, &mtime)) {
236 return (FALSE);
237 }
238 if (!xdr_u_short(xdrs, &mp->am_stats.s_uid)) {
239 return (FALSE);
240 }
241 if (!xdr_int(xdrs, &mp->am_stats.s_getattr)) {
242 return (FALSE);
243 }
244 if (!xdr_int(xdrs, &mp->am_stats.s_lookup)) {
245 return (FALSE);
246 }
247 if (!xdr_int(xdrs, &mp->am_stats.s_readdir)) {
248 return (FALSE);
249 }
250 if (!xdr_int(xdrs, &mp->am_stats.s_readlink)) {
251 return (FALSE);
252 }
253 if (!xdr_int(xdrs, &mp->am_stats.s_statfs)) {
254 return (FALSE);
255 }
256 return (TRUE);
257 }
258
259
260 bool_t
261 xdr_amq_mount_subtree(XDR *xdrs, amq_mount_tree *objp)
262 {
263 am_node *mp = (am_node *) objp;
264
265 if (!xdr_amq_mount_tree_node(xdrs, objp)) {
266 return (FALSE);
267 }
268 if (!xdr_pointer(xdrs, (char **) &mp->am_osib, sizeof(amq_mount_tree), (XDRPROC_T_TYPE) xdr_amq_mount_subtree)) {
269 return (FALSE);
270 }
271 if (!xdr_pointer(xdrs, (char **) &mp->am_child, sizeof(amq_mount_tree), (XDRPROC_T_TYPE) xdr_amq_mount_subtree)) {
272 return (FALSE);
273 }
274 return (TRUE);
275 }
276
277
278 bool_t
279 xdr_amq_mount_tree(XDR *xdrs, amq_mount_tree *objp)
280 {
281 am_node *mp = (am_node *) objp;
282 am_node *mnil = NULL;
283
284 if (!xdr_amq_mount_tree_node(xdrs, objp)) {
285 return (FALSE);
286 }
287 if (!xdr_pointer(xdrs, (char **) ((void *)&mnil), sizeof(amq_mount_tree), (XDRPROC_T_TYPE) xdr_amq_mount_subtree)) {
288 return (FALSE);
289 }
290 if (!xdr_pointer(xdrs, (char **) &mp->am_child, sizeof(amq_mount_tree), (XDRPROC_T_TYPE) xdr_amq_mount_subtree)) {
291 return (FALSE);
292 }
293 return (TRUE);
294 }
295
296
297 bool_t
298 xdr_amq_mount_tree_p(XDR *xdrs, amq_mount_tree_p *objp)
299 {
300 if (!xdr_pointer(xdrs, (char **) objp, sizeof(amq_mount_tree), (XDRPROC_T_TYPE) xdr_amq_mount_tree)) {
301 return (FALSE);
302 }
303 return (TRUE);
304 }
305
306
307 bool_t
308 xdr_amq_mount_stats(XDR *xdrs, amq_mount_stats *objp)
309 {
310 if (!xdr_int(xdrs, &objp->as_drops)) {
311 return (FALSE);
312 }
313 if (!xdr_int(xdrs, &objp->as_stale)) {
314 return (FALSE);
315 }
316 if (!xdr_int(xdrs, &objp->as_mok)) {
317 return (FALSE);
318 }
319 if (!xdr_int(xdrs, &objp->as_merr)) {
320 return (FALSE);
321 }
322 if (!xdr_int(xdrs, &objp->as_uerr)) {
323 return (FALSE);
324 }
325 return (TRUE);
326 }
327
328
329
330 bool_t
331 xdr_amq_mount_tree_list(XDR *xdrs, amq_mount_tree_list *objp)
332 {
333 if (!xdr_array(xdrs,
334 (char **) &objp->amq_mount_tree_list_val,
335 (u_int *) &objp->amq_mount_tree_list_len,
336 ~0,
337 sizeof(amq_mount_tree_p),
338 (XDRPROC_T_TYPE) xdr_amq_mount_tree_p)) {
339 return (FALSE);
340 }
341 return (TRUE);
342 }
343
344
345
346 /*
347 * Compute length of list
348 */
349 bool_t
350 xdr_amq_mount_info_qelem(XDR *xdrs, qelem *qhead)
351 {
352 mntfs *mf;
353 u_int len = 0;
354
355 for (mf = AM_LAST(mntfs, qhead); mf != HEAD(mntfs, qhead); mf = PREV(mntfs, mf)) {
356 if (!(mf->mf_fsflags & FS_AMQINFO))
357 continue;
358 len++;
359 }
360 xdr_u_int(xdrs, &len);
361
362 /*
363 * Send individual data items
364 */
365 for (mf = AM_LAST(mntfs, qhead); mf != HEAD(mntfs, qhead); mf = PREV(mntfs, mf)) {
366 int up;
367 if (!(mf->mf_fsflags & FS_AMQINFO))
368 continue;
369
370 if (!xdr_amq_string(xdrs, &mf->mf_ops->fs_type)) {
371 return (FALSE);
372 }
373 if (!xdr_amq_string(xdrs, &mf->mf_mount)) {
374 return (FALSE);
375 }
376 if (!xdr_amq_string(xdrs, &mf->mf_info)) {
377 return (FALSE);
378 }
379 if (!xdr_amq_string(xdrs, &mf->mf_server->fs_host)) {
380 return (FALSE);
381 }
382 if (!xdr_int(xdrs, &mf->mf_error)) {
383 return (FALSE);
384 }
385 if (!xdr_int(xdrs, &mf->mf_refc)) {
386 return (FALSE);
387 }
388 if (FSRV_ERROR(mf->mf_server) || FSRV_ISDOWN(mf->mf_server))
389 up = 0;
390 else if (FSRV_ISUP(mf->mf_server))
391 up = 1;
392 else
393 up = -1;
394 if (!xdr_int(xdrs, &up)) {
395 return (FALSE);
396 }
397 }
398 return (TRUE);
399 }
400
401
402 bool_t
403 xdr_pri_free(XDRPROC_T_TYPE xdr_args, caddr_t args_ptr)
404 {
405 XDR xdr;
406
407 xdr.x_op = XDR_FREE;
408 return ((*xdr_args) (&xdr, (caddr_t *) args_ptr));
409 }
410