2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
10 #include <afsconfig.h>
11 #include <afs/param.h>
16 #include <sys/types.h>
18 #include <sys/resource.h>
20 #include <netinet/in.h>
26 #include <afs/cellconfig.h>
28 #include <afs/com_err.h>
34 char *whoami = "test_rxkad_free";
36 static void PrintRxkadStats()
38 printf ("New Objects client %d, server %d. Destroyed objects %d.\n",
39 rxkad_stats_clientObjects, rxkad_stats_serverObjects,
40 rxkad_stats.destroyObject);
41 printf ("client conns: %d %d %d, destroyed client %d.\n",
42 rxkad_stats.connections[0], rxkad_stats.connections[1],
43 rxkad_stats.connections[2], rxkad_stats.destroyClient);
44 printf ("server challenges %d, responses %d %d %d\n",
45 rxkad_stats.challengesSent, rxkad_stats.responses[0],
46 rxkad_stats.responses[1], rxkad_stats.responses[2]);
47 printf ("server conns %d %d %d unused %d, unauth %d\n",
48 rxkad_stats.destroyConn[0], rxkad_stats.destroyConn[1],
49 rxkad_stats.destroyConn[2],
50 rxkad_stats.destroyUnused, rxkad_stats.destroyUnauth);
53 static long Main (as, arock)
54 IN struct cmd_syndesc *as;
58 char name[MAXKTCNAMELEN];
59 char instance[MAXKTCNAMELEN];
60 char newCell[MAXKTCREALMLEN];
63 long serverList[MAXSERVERS];
64 extern struct passwd *getpwuid();
67 struct ktc_encryptionKey key;
73 int verbose = (as->parms[1].items != 0);
74 int hostUsage = (as->parms[2].items != 0);
75 int waitReap = (as->parms[4].items != 0);
76 int doAuth = (as->parms[5].items != 0);
77 int number; /* number of iterations */
78 int callsPerSecond; /* to allow conn GC to run */
80 unsigned long lo, hi; /* mem usage */
81 unsigned long highWater; /* mem usage after reap period */
82 unsigned long lastWater; /* mem usage after last msg */
83 int serversUse[MAXSERVERS]; /* usage of each server */
84 long serversHost[MAXSERVERS]; /* host addr */
85 unsigned long startTime;
92 if (as->parms[0].items)
93 number = atoi (as->parms[0].items->data);
95 if (as->parms[3].items)
96 callsPerSecond = atoi (as->parms[3].items->data);
97 else callsPerSecond = 1;
98 if (doAuth && hostUsage) {
100 "Can't report host usage when calling UserAuthenticate\n");
104 if (as->parms[12].items) { /* if username specified */
105 code = ka_ParseLoginName (as->parms[12].items->data,
106 name, instance, newCell);
108 com_err (whoami, code, "parsing user's name '%s'",
109 as->parms[12].items->data);
112 if (strlen(newCell) > 0) cellSpecified = 1;
115 /* No explicit name provided: use Unix uid. */
116 pw = getpwuid(getuid());
118 printf ("Can't figure out your name from your user id.\n");
121 strncpy (name, pw->pw_name, sizeof(name));
122 strcpy (instance, "");
123 strcpy (newCell, "");
125 if (strcmp(as->parms[14].name, "-cell") == 0) {
126 if (as->parms[14].items) { /* if cell specified */
128 printf ("Duplicate cell specification not allowed\n");
129 else strncpy (newCell, as->parms[14].items->data,
134 code = ka_ExpandCell (newCell, newCell, 0/*local*/);
136 com_err (whoami, code, "Can't expand cell name");
141 if (as->parms[13].items) { /* if password specified */
142 strncpy (passwd, as->parms[13].items->data, sizeof(passwd));
143 memset(as->parms[13].items->data, 0, strlen (as->parms[13].items->data));
145 char msg[sizeof(name)+15];
146 if (as->parms[12].items) strcpy (msg, "Admin Password: ");
147 else sprintf (msg, "Password for %s: ", name);
148 code = read_pw_string (passwd, sizeof(passwd), msg, 0);
149 if (code) code = KAREADPW;
150 else if (strlen(passwd) == 0) code = KANULLPASSWORD;
152 com_err (whoami, code, "reading password");
156 if (as->parms[15].items) {
158 char *ap[MAXSERVERS+2];
160 for (ip = as->parms[15].items, i=2; ip; ip=ip->next, i++)
164 code = ubik_ParseClientList(i, ap, serverList);
166 com_err (whoami, code, "could not parse server list");
169 ka_ExplicitCell (cell, serverList);
173 ka_StringToKey (passwd, cell, &key);
174 memset(passwd, 0, sizeof(passwd));
177 memset(serversUse, 0, sizeof(serversUse));
178 memset(serversHost, 0, sizeof(serversHost));
182 for (i=0; i<number; i++) {
185 code = ka_UserAuthenticateLife (0, name, instance, cell,
188 fprintf (stderr, "Unable to authenticate to AFS because %s.\n",
193 struct ktc_token token;
194 struct ktc_token *pToken;
195 struct ubik_client *ubikConn;
196 struct kaentryinfo tentry;
199 code = ka_GetAdminToken (name, instance, cell, &key, 3600,
202 com_err (whoami, code, "getting admin token");
206 if (token.ticketLen == 0) {
207 fprintf ("Can't get admin token\n");
211 code = ka_AuthServerConn (cell, KA_MAINTENANCE_SERVICE, pToken,
214 com_err (whoami, code, "Getting AuthServer ubik conn");
218 if (verbose) for (c=0; c<MAXSERVERS; c++) {
219 struct rx_connection *rxConn = ubik_GetRPCConn(ubikConn,c);
220 struct rx_peer *peer;
222 if (rxConn == 0) break;
223 peer = rx_PeerOf (rxConn);
224 printf ("conn to %s:%d secObj:%x\n",
225 inet_ntoa(rx_HostOf(peer)), ntohs(rx_PortOf(peer)),
226 rxConn->securityObject);
229 code = ubik_Call (KAM_GetEntry, ubikConn, 0, name, instance,
230 KAMAJORVERSION, &tentry);
232 com_err (whoami, code,
233 "getting information for %s.%s", name, instance);
237 for (c=0; c<MAXSERVERS; c++) {
238 struct rx_connection *rxConn = ubik_GetRPCConn(ubikConn,c);
240 if (rxConn == 0) break;
241 if (rxConn->serial > 0) {
242 long host = rx_HostOf(rx_PeerOf(rxConn));
243 for (d=0;d<MAXSERVERS;d++) {
244 if (serversHost[d] == 0) serversHost[d] = host;
245 if (host == serversHost[d]) {
251 if (verbose) printf ("serial is %d\n", rxConn->serial);
253 ubik_ClientDestroy (ubikConn);
257 if (!lo) lo = sbrk(0);
258 if (i && ((i & 0x3f) == 0)) {
259 unsigned long this = sbrk(0);
260 printf (" mem after %d: lo=%x, cur=%x => %d (@ %d)\n",
261 i, lo, this, this-lo, (this-lo)/i);
262 if (highWater && (lastWater != this)) {
264 printf (" core leaking (after %d) should be %x, is %x\n",
268 if ((highWater == 0) && ((now-startTime) > 61)) {
270 lastWater = highWater;
271 printf (" mem highWater mark (after %d) should be %x\n",
274 if (callsPerSecond) {
276 if (callsPerSecond > 0)
277 target = i/callsPerSecond;
278 else /* if negative interpret as seconds per call */
279 target = i*(-callsPerSecond);
280 target = (startTime + target) - now;
281 if (target > 0) IOMGR_Sleep (target);
284 printf ("calling finalize\n");
289 for (i=0; i<MAXSERVERS; i++) {
290 total += serversUse[i];
291 if (serversHost[i] == 0) break;
292 printf ("host %s used %d times (%2g%%)\n",
293 inet_ntoa(serversHost[i]),
294 serversUse[i], 100.0 * serversUse[i] / (double) number);
297 printf (" %2g%% retries\n", 100.0*(total-number)/(double)number);
300 printf ("mem usage: lo=%x, hi=%x => %d (@ %d)\n",
301 lo, hi, hi-lo, (hi-lo)/number);
303 unsigned long mediumHi;
304 printf ("Waiting 61 seconds for all connections to be reaped\n");
310 printf ("mem usage: lo=%x, hi=%x => %d (@ %d)\n",
311 lo, hi, hi-lo, (hi-lo)/number);
313 /* most of these checks are sure to fail w/o waiting for reap */
315 ((rxkad_stats_clientObjects != rxkad_stats.destroyObject) ||
316 (rxkad_stats.connections[0]+rxkad_stats.connections[1]+
317 rxkad_stats.connections[2] != rxkad_stats.destroyClient) ||
318 (rxkad_stats.responses[0] != rxkad_stats.destroyConn[0]) ||
319 (rxkad_stats.responses[1] != rxkad_stats.destroyConn[1]) ||
320 (rxkad_stats.responses[2] != rxkad_stats.destroyConn[2])
321 /* values of destroyUnused and destroyUnauth should be very small */
323 fprintf (stderr, "Some rxkad security storage not freed\n");
326 if ((highWater != 0) && (highWater < hi)){
327 /* We should reach steady state memory usage after 60 seconds (the Rx
328 * connection reap period). If we are still using memory, there must
330 fprintf (stderr, "Core leak\n");
340 register struct cmd_syndesc *ts;
343 initialize_u_error_table();
344 initialize_cmd_error_table();
345 initialize_rxk_error_table();
346 initialize_ktc_error_table();
347 initialize_acfg_error_table();
348 initialize_ka_error_table();
350 ts = cmd_CreateSyntax (0, Main, 0, "Main program");
351 /* 0 */ cmd_AddParm (ts, "-number", CMD_SINGLE, CMD_OPTIONAL,
352 "number of iterations");
353 /* 1 */ cmd_AddParm (ts, "-long", CMD_FLAG, CMD_OPTIONAL,
354 "long form of output");
355 /* 2 */ cmd_AddParm (ts, "-hostusage", CMD_FLAG, CMD_OPTIONAL,
356 "report distribution of host usage");
357 /* 3 */ cmd_AddParm (ts, "-rate", CMD_SINGLE, CMD_OPTIONAL,
359 /* 4 */ cmd_AddParm (ts, "-waitforreap", CMD_FLAG, CMD_OPTIONAL,
360 "wait one reap time before exit");
361 /* 5 */ cmd_AddParm (ts, "-doauth", CMD_FLAG, CMD_OPTIONAL,
362 "call UserAuthenticate instead of GetEntry");
364 /* 12 */ cmd_AddParm (ts, "-admin_username", CMD_SINGLE, CMD_OPTIONAL,
365 "admin principal to use for authentication");
366 /* 13 */ cmd_AddParm (ts, "-password_for_admin", CMD_SINGLE, CMD_OPTIONAL,
368 /* 14 */ cmd_AddParm (ts, "-cell", CMD_SINGLE, CMD_OPTIONAL, "cell name");
369 /* 15 */ cmd_AddParm (ts, "-servers", CMD_LIST, CMD_OPTIONAL,
370 "explicit list of authentication servers");
371 code = cmd_Dispatch(argc, argv);