amq_subr.c revision 82798
1/* 2 * Copyright (c) 1997-2001 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 * %W% (Berkeley) %G% 40 * 41 * $Id: amq_subr.c,v 1.6.2.2 2001/01/12 22:43:42 ro Exp $ 42 * $FreeBSD: head/contrib/amd/amd/amq_subr.c 82798 2001-09-02 18:15:24Z obrien $ 43 * 44 */ 45/* 46 * Auxiliary routines for amq tool 47 */ 48 49#ifdef HAVE_CONFIG_H 50# include <config.h> 51#endif /* HAVE_CONFIG_H */ 52#include <am_defs.h> 53#include <amd.h> 54 55/* forward definitions */ 56bool_t xdr_amq_mount_tree_node(XDR *xdrs, amq_mount_tree *objp); 57bool_t xdr_amq_mount_subtree(XDR *xdrs, amq_mount_tree *objp); 58 59 60voidp 61amqproc_null_1_svc(voidp argp, struct svc_req *rqstp) 62{ 63 static char res; 64 65 return (voidp) &res; 66} 67 68 69/* 70 * Return a sub-tree of mounts 71 */ 72amq_mount_tree_p * 73amqproc_mnttree_1_svc(voidp argp, struct svc_req *rqstp) 74{ 75 static am_node *mp; 76 77 mp = find_ap(*(char **) argp); 78 return (amq_mount_tree_p *) ∓ 79} 80 81 82/* 83 * Unmount a single node 84 */ 85voidp 86amqproc_umnt_1_svc(voidp argp, struct svc_req *rqstp) 87{ 88 static char res; 89 am_node *mp = find_ap(*(char **) argp); 90 91 if (mp) 92 forcibly_timeout_mp(mp); 93 94 return (voidp) &res; 95} 96 97 98/* 99 * Return global statistics 100 */ 101amq_mount_stats * 102amqproc_stats_1_svc(voidp argp, struct svc_req *rqstp) 103{ 104 return (amq_mount_stats *) &amd_stats; 105} 106 107 108/* 109 * Return the entire tree of mount nodes 110 */ 111amq_mount_tree_list * 112amqproc_export_1_svc(voidp argp, struct svc_req *rqstp) 113{ 114 static amq_mount_tree_list aml; 115 116 aml.amq_mount_tree_list_val = (amq_mount_tree_p *) &exported_ap[0]; 117 aml.amq_mount_tree_list_len = 1; /* XXX */ 118 119 return &aml; 120} 121 122 123int * 124amqproc_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#ifdef DEBUG 135 if (debug_option(opt->as_str)) 136#endif /* DEBUG */ 137 rc = EINVAL; 138 break; 139 140 case AMOPT_LOGFILE: 141 if (gopt.logfile && opt->as_str 142 && STREQ(gopt.logfile, opt->as_str)) { 143 if (switch_to_logfile(opt->as_str, orig_umask)) 144 rc = EINVAL; 145 } else { 146 rc = EACCES; 147 } 148 break; 149 150 case AMOPT_XLOG: 151 if (switch_option(opt->as_str)) 152 rc = EINVAL; 153 break; 154 155 case AMOPT_FLUSHMAPC: 156 if (amd_state == Run) { 157 plog(XLOG_INFO, "amq says flush cache"); 158 do_mapc_reload = 0; 159 flush_nfs_fhandle_cache((fserver *) 0); 160 flush_srvr_nfs_cache(); 161 } 162 break; 163 } 164 165 return &rc; 166} 167 168 169amq_mount_info_list * 170amqproc_getmntfs_1_svc(voidp argp, struct svc_req *rqstp) 171{ 172 return (amq_mount_info_list *) &mfhead; /* XXX */ 173} 174 175 176amq_string * 177amqproc_getvers_1_svc(voidp argp, struct svc_req *rqstp) 178{ 179 static amq_string res; 180 181 res = get_version_string(); 182 return &res; 183} 184 185 186/* get PID of remote amd */ 187int * 188amqproc_getpid_1_svc(voidp argp, struct svc_req *rqstp) 189{ 190 static int res; 191 192 res = getpid(); 193 return &res; 194} 195 196 197/* 198 * XDR routines. 199 */ 200 201 202bool_t 203xdr_amq_setopt(XDR *xdrs, amq_setopt *objp) 204{ 205 if (!xdr_enum(xdrs, (enum_t *) & objp->as_opt)) { 206 return (FALSE); 207 } 208 if (!xdr_string(xdrs, &objp->as_str, AMQ_STRLEN)) { 209 return (FALSE); 210 } 211 return (TRUE); 212} 213 214 215/* 216 * More XDR routines - Should be used for OUTPUT ONLY. 217 */ 218bool_t 219xdr_amq_mount_tree_node(XDR *xdrs, amq_mount_tree *objp) 220{ 221 am_node *mp = (am_node *) objp; 222 long mtime; 223 224 if (!xdr_amq_string(xdrs, &mp->am_mnt->mf_info)) { 225 return (FALSE); 226 } 227 if (!xdr_amq_string(xdrs, &mp->am_path)) { 228 return (FALSE); 229 } 230 if (!xdr_amq_string(xdrs, mp->am_link ? &mp->am_link : &mp->am_mnt->mf_mount)) { 231 return (FALSE); 232 } 233 if (!xdr_amq_string(xdrs, &mp->am_mnt->mf_ops->fs_type)) { 234 return (FALSE); 235 } 236 mtime = mp->am_stats.s_mtime; 237 if (!xdr_long(xdrs, &mtime)) { 238 return (FALSE); 239 } 240 if (!xdr_u_short(xdrs, &mp->am_stats.s_uid)) { 241 return (FALSE); 242 } 243 if (!xdr_int(xdrs, &mp->am_stats.s_getattr)) { 244 return (FALSE); 245 } 246 if (!xdr_int(xdrs, &mp->am_stats.s_lookup)) { 247 return (FALSE); 248 } 249 if (!xdr_int(xdrs, &mp->am_stats.s_readdir)) { 250 return (FALSE); 251 } 252 if (!xdr_int(xdrs, &mp->am_stats.s_readlink)) { 253 return (FALSE); 254 } 255 if (!xdr_int(xdrs, &mp->am_stats.s_statfs)) { 256 return (FALSE); 257 } 258 return (TRUE); 259} 260 261 262bool_t 263xdr_amq_mount_subtree(XDR *xdrs, amq_mount_tree *objp) 264{ 265 am_node *mp = (am_node *) objp; 266 267 if (!xdr_amq_mount_tree_node(xdrs, objp)) { 268 return (FALSE); 269 } 270 if (!xdr_pointer(xdrs, (char **) &mp->am_osib, sizeof(amq_mount_tree), (XDRPROC_T_TYPE) xdr_amq_mount_subtree)) { 271 return (FALSE); 272 } 273 if (!xdr_pointer(xdrs, (char **) &mp->am_child, sizeof(amq_mount_tree), (XDRPROC_T_TYPE) xdr_amq_mount_subtree)) { 274 return (FALSE); 275 } 276 return (TRUE); 277} 278 279 280bool_t 281xdr_amq_mount_tree(XDR *xdrs, amq_mount_tree *objp) 282{ 283 am_node *mp = (am_node *) objp; 284 am_node *mnil = 0; 285 286 if (!xdr_amq_mount_tree_node(xdrs, objp)) { 287 return (FALSE); 288 } 289 if (!xdr_pointer(xdrs, (char **) &mnil, sizeof(amq_mount_tree), (XDRPROC_T_TYPE) xdr_amq_mount_subtree)) { 290 return (FALSE); 291 } 292 if (!xdr_pointer(xdrs, (char **) &mp->am_child, sizeof(amq_mount_tree), (XDRPROC_T_TYPE) xdr_amq_mount_subtree)) { 293 return (FALSE); 294 } 295 return (TRUE); 296} 297 298 299bool_t 300xdr_amq_mount_tree_p(XDR *xdrs, amq_mount_tree_p *objp) 301{ 302 if (!xdr_pointer(xdrs, (char **) objp, sizeof(amq_mount_tree), (XDRPROC_T_TYPE) xdr_amq_mount_tree)) { 303 return (FALSE); 304 } 305 return (TRUE); 306} 307 308 309bool_t 310xdr_amq_mount_stats(XDR *xdrs, amq_mount_stats *objp) 311{ 312 if (!xdr_int(xdrs, &objp->as_drops)) { 313 return (FALSE); 314 } 315 if (!xdr_int(xdrs, &objp->as_stale)) { 316 return (FALSE); 317 } 318 if (!xdr_int(xdrs, &objp->as_mok)) { 319 return (FALSE); 320 } 321 if (!xdr_int(xdrs, &objp->as_merr)) { 322 return (FALSE); 323 } 324 if (!xdr_int(xdrs, &objp->as_uerr)) { 325 return (FALSE); 326 } 327 return (TRUE); 328} 329 330 331 332bool_t 333xdr_amq_mount_tree_list(XDR *xdrs, amq_mount_tree_list *objp) 334{ 335 if (!xdr_array(xdrs, 336 (char **) &objp->amq_mount_tree_list_val, 337 (u_int *) &objp->amq_mount_tree_list_len, 338 ~0, 339 sizeof(amq_mount_tree_p), 340 (XDRPROC_T_TYPE) xdr_amq_mount_tree_p)) { 341 return (FALSE); 342 } 343 return (TRUE); 344} 345 346 347 348/* 349 * Compute length of list 350 */ 351bool_t 352xdr_amq_mount_info_qelem(XDR *xdrs, qelem *qhead) 353{ 354 mntfs *mf; 355 u_int len = 0; 356 357 for (mf = AM_LAST(mntfs, qhead); mf != HEAD(mntfs, qhead); mf = PREV(mntfs, mf)) { 358 if (!(mf->mf_ops->fs_flags & FS_AMQINFO)) 359 continue; 360 len++; 361 } 362 xdr_u_int(xdrs, &len); 363 364 /* 365 * Send individual data items 366 */ 367 for (mf = AM_LAST(mntfs, qhead); mf != HEAD(mntfs, qhead); mf = PREV(mntfs, mf)) { 368 int up; 369 if (!(mf->mf_ops->fs_flags & FS_AMQINFO)) 370 continue; 371 372 if (!xdr_amq_string(xdrs, &mf->mf_ops->fs_type)) { 373 return (FALSE); 374 } 375 if (!xdr_amq_string(xdrs, &mf->mf_mount)) { 376 return (FALSE); 377 } 378 if (!xdr_amq_string(xdrs, &mf->mf_info)) { 379 return (FALSE); 380 } 381 if (!xdr_amq_string(xdrs, &mf->mf_server->fs_host)) { 382 return (FALSE); 383 } 384 if (!xdr_int(xdrs, &mf->mf_error)) { 385 return (FALSE); 386 } 387 if (!xdr_int(xdrs, &mf->mf_refc)) { 388 return (FALSE); 389 } 390 if (mf->mf_server->fs_flags & FSF_ERROR) 391 up = 0; 392 else 393 switch (mf->mf_server->fs_flags & (FSF_DOWN | FSF_VALID)) { 394 case FSF_DOWN | FSF_VALID: 395 up = 0; 396 break; 397 case FSF_VALID: 398 up = 1; 399 break; 400 default: 401 up = -1; 402 break; 403 } 404 if (!xdr_int(xdrs, &up)) { 405 return (FALSE); 406 } 407 } 408 return (TRUE); 409} 410 411 412bool_t 413xdr_pri_free(XDRPROC_T_TYPE xdr_args, caddr_t args_ptr) 414{ 415 XDR xdr; 416 417 xdr.x_op = XDR_FREE; 418 return ((*xdr_args) (&xdr, (caddr_t *) args_ptr)); 419} 420