From: Erez Zadok Date: Fri, 7 Oct 2005 16:39:12 +0000 (+0000) Subject: * amq/pawd.c (find_mt, find_mlp): remove obsolete, inefficient X-Git-Tag: am-utils-6_2a1~18 X-Git-Url: https://git.fsl.cs.stonybrook.edu/?a=commitdiff_plain;h=140f5995930f67ec5b3db7d6eeb9d62aef42791f;p=am-utils-6.1.git * amq/pawd.c (find_mt, find_mlp): remove obsolete, inefficient code. (transform_dir): call the new, efficient amqproc_pawd_1() routine. * amq/amq_clnt.c (amqproc_pawd_1): AMQPROC_PAWD wrapper routine. * amq/amq.h (amqproc_pawd_1): extern for amq's AMQPROC_PAWD wrapper routine. * amd/amq_svc.c (amq_program_1): dispatch point for amqproc_pawd_1_svc. * amd/amq_subr.c (amqproc_pawd_1_svc): moved pawd's path-matching functionality into Amd, where it can be done a lot more efficiently. We don't have to construct and ship a whole export tree from Amd to pawd. We just get a variable-length xdr_wrapstring for the user's path, iterate over the entire export list inside Amd, and return only a matched string if found (otherwise we return "" to indicate that there was no match, and let pawd printf the same string it sent over). * amd/amd.h: extern for amqproc_pawd_1_svc, amd's service routine the AMQPROC_PAWD RPC. * amq/pawd.c (transform_dir): was using UDP only. Now will also try TCP if UDP failed. Destroy client after use to avoid leftover TCP sockets in the kernel. --- diff --git a/ChangeLog b/ChangeLog index 67ab92b..f6ed181 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,29 @@ +2005-10-07 Erez Zadok + + * amq/pawd.c (find_mt, find_mlp): remove obsolete, inefficient + code. + (transform_dir): call the new, efficient amqproc_pawd_1() routine. + + * amq/amq_clnt.c (amqproc_pawd_1): AMQPROC_PAWD wrapper routine. + + * amq/amq.h (amqproc_pawd_1): extern for amq's AMQPROC_PAWD + wrapper routine. + + * amd/amq_svc.c (amq_program_1): dispatch point for + amqproc_pawd_1_svc. + + * amd/amq_subr.c (amqproc_pawd_1_svc): moved pawd's path-matching + functionality into Amd, where it can be done a lot more + efficiently. We don't have to construct and ship a whole export + tree from Amd to pawd. We just get a variable-length + xdr_wrapstring for the user's path, iterate over the entire export + list inside Amd, and return only a matched string if found + (otherwise we return "" to indicate that there was no match, and + let pawd printf the same string it sent over). + + * amd/amd.h: extern for amqproc_pawd_1_svc, amd's service routine + the AMQPROC_PAWD RPC. + 2005-10-06 Erez Zadok * ltmain.sh, m4/macros/libtool.m4: update to libtool-1.5.20. @@ -63,8 +89,9 @@ 2005-10-05 Erez Zadok - * amq/pawd.c (transform_dir): use TCP first, else UDP. Destroy - client after use to avoid leftover TCP sockets in the kernel. + * amq/pawd.c (transform_dir): was using UDP only. Now will also + try TCP if UDP failed. Destroy client after use to avoid leftover + TCP sockets in the kernel. * libamu/hasmntopt.c (amu_hasmntopt): increase size of MNTMAXSTR from 128 to to 256, because some users have really long option diff --git a/NEWS b/NEWS index 2f06d91..8c6b771 100644 --- a/NEWS +++ b/NEWS @@ -52,7 +52,8 @@ XXX: Dan, document sun_map_syntax flag in more detail in am-utils.texi and * convert all sprintf to safer xsnprintf * convert all strcat to safer xstrlcat * convert all strcpy to safer xstrlcpy - * pawd uses TCP first, then UDP + * fix three buffer overruns in expand_op (amd/opts.c) + * pawd was trying UDP only, now try TCP if UDP failed Amd now understands a new log_option called "defaults" which is synonymous with "fatal,error,user,warning,info" (and is also what logging happens by @@ -61,6 +62,12 @@ default). Amd now understands a new debug_option called "defaults" which is synonymous with "all,nohrtime,nomtab,noxdrtrace". +Moved pawd's path-matching functionality into Amd, where it can be done a +lot more efficiently (we no longer need to construct and send the whole +mounted tree, only to match small parts of it). This will lessen the CPU +and network load on systems that use pawd heavily, and also minimize the +chance that we exceed default or hard-coded UDP/TCP RPC packet sizes. + Changed slightly how Amd behaves when you try to change log_options after Amd started (options can be turned on/off via "amq -x ARG"). It used to be that Amd won't let you turn off options which were on when Amd started. diff --git a/amd/amd.h b/amd/amd.h index e0eaef5..1224a08 100644 --- a/amd/amd.h +++ b/amd/amd.h @@ -515,6 +515,7 @@ extern amq_mount_stats *amqproc_stats_1_svc(voidp argp, struct svc_req *rqstp); extern amq_mount_tree_list *amqproc_export_1_svc(voidp argp, struct svc_req *rqstp); extern amq_mount_tree_p *amqproc_mnttree_1_svc(voidp argp, struct svc_req *rqstp); extern amq_string *amqproc_getvers_1_svc(voidp argp, struct svc_req *rqstp); +extern amq_string *amqproc_pawd_1_svc(voidp argp, struct svc_req *rqstp); extern int *amqproc_getpid_1_svc(voidp argp, struct svc_req *rqstp); extern int *amqproc_mount_1_svc(voidp argp, struct svc_req *rqstp); extern int *amqproc_setopt_1_svc(voidp argp, struct svc_req *rqstp); diff --git a/amd/amq_subr.c b/amd/amq_subr.c index a6d245d..8615508 100644 --- a/amd/amq_subr.c +++ b/amd/amq_subr.c @@ -192,6 +192,43 @@ amqproc_getpid_1_svc(voidp argp, struct svc_req *rqstp) } +/* process PAWD string of remote pawd tool */ +amq_string * +amqproc_pawd_1_svc(voidp argp, struct svc_req *rqstp) +{ + static amq_string res; + int index, len; + am_node *mp; + char *mountpoint; + char *dir = *(char **) argp; + static char tmp_buf[MAXPATHLEN]; + + tmp_buf[0] = '\0'; /* default is empty string: no match */ + for (mp = get_first_exported_ap(&index); + mp; + mp = get_next_exported_ap(&index)) { + if (STREQ(mp->am_mnt->mf_ops->fs_type, "toplvl")) + continue; + if (STREQ(mp->am_mnt->mf_ops->fs_type, "auto")) + continue; + mountpoint = (mp->am_link ? mp->am_link : mp->am_mnt->mf_mount); + len = strlen(mountpoint); + if (len == 0) + continue; + if (!NSTREQ(mountpoint, dir, len)) + continue; + if (dir[len] != '\0' && dir[len] != '/') + continue; + xstrlcpy(tmp_buf, mp->am_path, sizeof(tmp_buf)); + xstrlcat(tmp_buf, &dir[len], sizeof(tmp_buf)); + break; + } + + res = tmp_buf; + return &res; +} + + /* * XDR routines. */ diff --git a/amd/amq_svc.c b/amd/amq_svc.c index cc8cc7f..b127be6 100644 --- a/amd/amq_svc.c +++ b/amd/amq_svc.c @@ -193,6 +193,12 @@ amq_program_1(struct svc_req *rqstp, SVCXPRT *transp) local = (amqsvcproc_t) amqproc_getpid_1_svc; break; + case AMQPROC_PAWD: + xdr_argument = (xdrproc_t) xdr_amq_string; + xdr_result = (xdrproc_t) xdr_amq_string; + local = (amqsvcproc_t) amqproc_pawd_1_svc; + break; + default: svcerr_noproc(transp); return; diff --git a/amd/nfs_start.c b/amd/nfs_start.c index 17303bc..76e794f 100644 --- a/amd/nfs_start.c +++ b/amd/nfs_start.c @@ -234,7 +234,7 @@ run_rpc(void) } tvv.tv_usec = 0; - if (amd_state == Finishing && get_exported_ap(0) == 0) { + if (amd_state == Finishing && get_exported_ap(0) == NULL) { flush_mntfs(); amd_state = Quit; break; diff --git a/amq/amq.h b/amq/amq.h index e2d6935..9d40e7e 100644 --- a/amq/amq.h +++ b/amq/amq.h @@ -58,5 +58,6 @@ extern amq_mount_info_list *amqproc_getmntfs_1(voidp argp, CLIENT *rqstp); extern int *amqproc_mount_1(voidp argp, CLIENT *rqstp); extern amq_string *amqproc_getvers_1(voidp argp, CLIENT *rqstp); extern int *amqproc_getpid_1(voidp argp, CLIENT *rqstp); +extern amq_string *amqproc_pawd_1(amq_string *argp, CLIENT *rqstp); #endif /* not _AMQ_H */ diff --git a/amq/amq_clnt.c b/amq/amq_clnt.c index fa4c503..2c377b7 100644 --- a/amq/amq_clnt.c +++ b/amq/amq_clnt.c @@ -75,7 +75,7 @@ amqproc_mnttree_1(amq_string *argp, CLIENT *clnt) memset((char *) &res, 0, sizeof(res)); if (clnt_call(clnt, AMQPROC_MNTTREE, (XDRPROC_T_TYPE) xdr_amq_string, (SVC_IN_ARG_TYPE) argp, - (XDRPROC_T_TYPE) xdr_amq_mount_tree_p, (SVC_IN_ARG_TYPE) & res, + (XDRPROC_T_TYPE) xdr_amq_mount_tree_p, (SVC_IN_ARG_TYPE) &res, TIMEOUT) != RPC_SUCCESS) { return (NULL); } @@ -108,7 +108,7 @@ amqproc_stats_1(voidp argp, CLIENT *clnt) if (clnt_call(clnt, AMQPROC_STATS, (XDRPROC_T_TYPE) xdr_void, argp, (XDRPROC_T_TYPE) xdr_amq_mount_stats, - (SVC_IN_ARG_TYPE) & res, + (SVC_IN_ARG_TYPE) &res, TIMEOUT) != RPC_SUCCESS) { return (NULL); } @@ -125,7 +125,7 @@ amqproc_export_1(voidp argp, CLIENT *clnt) if (clnt_call(clnt, AMQPROC_EXPORT, (XDRPROC_T_TYPE) xdr_void, argp, (XDRPROC_T_TYPE) xdr_amq_mount_tree_list, - (SVC_IN_ARG_TYPE) & res, TIMEOUT) != RPC_SUCCESS) { + (SVC_IN_ARG_TYPE) &res, TIMEOUT) != RPC_SUCCESS) { return (NULL); } return (&res); @@ -140,7 +140,7 @@ amqproc_setopt_1(amq_setopt *argp, CLIENT *clnt) memset((char *) &res, 0, sizeof(res)); if (clnt_call(clnt, AMQPROC_SETOPT, (XDRPROC_T_TYPE) xdr_amq_setopt, (SVC_IN_ARG_TYPE) argp, (XDRPROC_T_TYPE) xdr_int, - (SVC_IN_ARG_TYPE) & res, TIMEOUT) != RPC_SUCCESS) { + (SVC_IN_ARG_TYPE) &res, TIMEOUT) != RPC_SUCCESS) { return (NULL); } return (&res); @@ -155,7 +155,7 @@ amqproc_getmntfs_1(voidp argp, CLIENT *clnt) memset((char *) &res, 0, sizeof(res)); if (clnt_call(clnt, AMQPROC_GETMNTFS, (XDRPROC_T_TYPE) xdr_void, argp, (XDRPROC_T_TYPE) xdr_amq_mount_info_list, - (SVC_IN_ARG_TYPE) & res, TIMEOUT) != RPC_SUCCESS) { + (SVC_IN_ARG_TYPE) &res, TIMEOUT) != RPC_SUCCESS) { return (NULL); } return (&res); @@ -169,7 +169,7 @@ amqproc_mount_1(voidp argp, CLIENT *clnt) memset((char *) &res, 0, sizeof(res)); if (clnt_call(clnt, AMQPROC_MOUNT, (XDRPROC_T_TYPE) xdr_amq_string, argp, - (XDRPROC_T_TYPE) xdr_int, (SVC_IN_ARG_TYPE) & res, + (XDRPROC_T_TYPE) xdr_int, (SVC_IN_ARG_TYPE) &res, TIMEOUT) != RPC_SUCCESS) { return (NULL); } @@ -184,7 +184,7 @@ amqproc_getvers_1(voidp argp, CLIENT *clnt) memset((char *) &res, 0, sizeof(res)); if (clnt_call(clnt, AMQPROC_GETVERS, (XDRPROC_T_TYPE) xdr_void, argp, - (XDRPROC_T_TYPE) xdr_amq_string, (SVC_IN_ARG_TYPE) & res, + (XDRPROC_T_TYPE) xdr_amq_string, (SVC_IN_ARG_TYPE) &res, TIMEOUT) != RPC_SUCCESS) { return (NULL); } @@ -199,7 +199,23 @@ amqproc_getpid_1(voidp argp, CLIENT *clnt) memset((char *) &res, 0, sizeof(res)); if (clnt_call(clnt, AMQPROC_GETPID, (XDRPROC_T_TYPE) xdr_void, argp, - (XDRPROC_T_TYPE) xdr_int, (SVC_IN_ARG_TYPE) & res, + (XDRPROC_T_TYPE) xdr_int, (SVC_IN_ARG_TYPE) &res, + TIMEOUT) != RPC_SUCCESS) { + return (NULL); + } + return (&res); +} + + +amq_string * +amqproc_pawd_1(amq_string *argp, CLIENT *clnt) +{ + static amq_string res; + + memset((char *) &res, 0, sizeof(res)); + if (clnt_call(clnt, AMQPROC_PAWD, + (XDRPROC_T_TYPE) xdr_amq_string, (SVC_IN_ARG_TYPE) argp, + (XDRPROC_T_TYPE) xdr_amq_string, (SVC_IN_ARG_TYPE) &res, TIMEOUT) != RPC_SUCCESS) { return (NULL); } diff --git a/amq/pawd.c b/amq/pawd.c index 44aca1c..bf06cf6 100644 --- a/amq/pawd.c +++ b/amq/pawd.c @@ -58,45 +58,9 @@ #include /* statics */ -static char *localhost="localhost"; -static char newdir[MAXPATHLEN]; +static char *localhost = "localhost"; static char transform[MAXPATHLEN]; -static int -find_mt(amq_mount_tree *mt, char *dir) -{ - while (mt) { - if (!STREQ(mt->mt_type, "toplvl") && !STREQ(mt->mt_type, "auto")) { - int len = strlen(mt->mt_mountpoint); - if (len != 0 && NSTREQ(mt->mt_mountpoint, dir, len) && - ((dir[len] == '\0') || (dir[len] == '/'))) { - char tmp_buf[MAXPATHLEN]; - xstrlcpy(tmp_buf, mt->mt_directory, sizeof(tmp_buf)); - xstrlcat(tmp_buf, &dir[len], sizeof(tmp_buf)); - xstrlcpy(newdir, tmp_buf, sizeof(newdir)); - return 1; - } - } - if (find_mt(mt->mt_next,dir)) - return 1; - mt = mt->mt_child; - } - return 0; -} - - -static int -find_mlp(amq_mount_tree_list *mlp, char *dir) -{ - u_int i; - - for (i = 0; i < mlp->amq_mount_tree_list_len; i++) { - if (find_mt(mlp->amq_mount_tree_list_val[i], dir)) - return 1; - } - return 0; -} - #ifdef HAVE_CNODEID static char * @@ -215,8 +179,9 @@ transform_dir(char *dir) int s = RPC_ANYSOCK; CLIENT *clnt; struct hostent *hp; - amq_mount_tree_list *mlp; struct timeval tmo = {10, 0}; + char *dummystr; + amq_string *spp; #ifdef DISK_HOME_HACK if (ch = hack_name(dir)) @@ -235,16 +200,18 @@ transform_dir(char *dir) server_addr.sin_family = AF_INET; server_addr.sin_addr = *(struct in_addr *) hp->h_addr; - clnt = clnttcp_create(&server_addr, AMQ_PROGRAM, AMQ_VERSION, &s, 0, 0); + clnt = clntudp_create(&server_addr, AMQ_PROGRAM, AMQ_VERSION, tmo, &s); if (clnt == NULL) - clnt = clntudp_create(&server_addr, AMQ_PROGRAM, AMQ_VERSION, tmo, &s); + clnt = clnttcp_create(&server_addr, AMQ_PROGRAM, AMQ_VERSION, &s, 0, 0); if (clnt == NULL) return dir; xstrlcpy(transform, dir, sizeof(transform)); - while ( (mlp = amqproc_export_1((voidp)0, clnt)) && - find_mlp(mlp,transform) ) { - xstrlcpy(transform, newdir, sizeof(transform)); + dummystr = transform; + spp = amqproc_pawd_1((amq_string *) &dummystr, clnt); + if (spp && *spp && **spp) { + xstrlcpy(transform, *spp, sizeof(transform)); + XFREE(*spp); } clnt_destroy(clnt); return transform; diff --git a/include/amq_defs.h b/include/amq_defs.h index 90c4d9b..3c3e163 100644 --- a/include/amq_defs.h +++ b/include/amq_defs.h @@ -63,6 +63,7 @@ #define AMQPROC_MOUNT ((u_long)7) #define AMQPROC_GETVERS ((u_long)8) #define AMQPROC_GETPID ((u_long)9) +#define AMQPROC_PAWD ((u_long)10) /* * TYPEDEFS