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.
+2005-10-07 Erez Zadok <ezk@cs.sunysb.edu>
+
+ * 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 <ezk@cs.sunysb.edu>
* ltmain.sh, m4/macros/libtool.m4: update to libtool-1.5.20.
2005-10-05 Erez Zadok <ezk@cs.sunysb.edu>
- * 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
* 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
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.
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);
}
+/* 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.
*/
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;
}
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;
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 */
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);
}
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);
}
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);
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);
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);
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);
}
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);
}
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);
}
#include <amq.h>
/* 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 *
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))
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;
#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