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
13 #include <afsconfig.h>
14 #include <afs/param.h>
18 #include <sys/types.h>
20 #if !defined(AFS_SUN3_ENV) && !defined(sys_vax_ul43)
22 /*#ifdef AFS_AIX_ENV*/
33 #include <afs/afs_args.h>
35 #include <afs/afsutil.h>
38 #include <afs/sys_prototypes.h>
40 #if defined(AFS_OSF_ENV) || defined(AFS_SGI61_ENV) || (defined(AFS_AIX51_ENV) && defined(AFS_64BIT_KERNEL))
41 /* For SGI 6.2, this is changed to 1 if it's a 32 bit kernel. */
42 int afs_icl_sizeofLong = 2;
44 int afs_icl_sizeofLong = 1;
47 #if defined(AFS_SGI61_ENV) || (defined(AFS_AIX51_ENV) && defined(AFS_64BIT_KERNEL))
48 int afs_64bit_kernel = 1; /* Default for 6.2+, and always for 6.1 */
49 extern int afs_icl_sizeofLong; /* Used in ICL_SIZEHACK() */
53 /* If _SC_KERN_POINTERS not in sysconf, then we can assume a 32 bit abi. */
55 set_kernel_sizeof_long(void)
60 retval = sysconf(_SC_KERN_POINTERS);
63 afs_icl_sizeofLong = 2;
66 afs_icl_sizeofLong = 1;
70 #endif /* AFS_SGI62_ENV */
71 #endif /* AFS_SGI61_ENV */
73 int afs_syscall(long call, long parm0, long parm1, long parm2, long parm3,
74 long parm4, long parm5, long parm6);
75 void dce1_error_inq_text(afs_uint32 status_to_convert,
76 char *error_text, int *status);
77 int icl_CreateSetWithFlags(char *name, struct afs_icl_log *baseLogp,
78 struct afs_icl_log *fatalLogp, afs_uint32 flags,
79 struct afs_icl_set **outSetpp);
80 int icl_LogHold(register struct afs_icl_log *logp);
81 int icl_LogUse(register struct afs_icl_log *logp);
82 int icl_LogReleNL(register struct afs_icl_log *logp);
83 int icl_LogRele(register struct afs_icl_log *logp);
84 int icl_ZeroLog(register struct afs_icl_log *logp);
85 int icl_LogFreeUse(register struct afs_icl_log *logp);
87 #define BUFFER_MULTIPLIER 1024
89 /* make it big enough to snapshot everything at once, since
90 * decoding takes so long.
92 #define IBSIZE 100000 /* default size */
95 struct logInfo *nextp;
99 char dumpFileName[256] = "";
101 RegisterIclDumpFileName(char *name)
103 (void)sprintf(dumpFileName, "icl.%.250s", name);
106 /* define globals to use for bulk info */
107 afs_icl_bulkSetinfo_t *setInfo = (afs_icl_bulkSetinfo_t *) 0;
108 afs_icl_bulkLoginfo_t *logInfo = (afs_icl_bulkLoginfo_t *) 0;
110 struct afs_icl_set *icl_allSets = 0;
114 /* given a type and an address, get the size of the thing
118 icl_GetSize(afs_int32 type, char *addr)
124 ICL_SIZEHACK(type, addr);
128 /* Check types in printf string "bufferp", making sure that each
129 * is compatible with the corresponding parameter type described
130 * by typesp. Also watch for prematurely running out of parameters
131 * before the string is gone.
133 #if defined(AFS_SGI61_ENV) || (defined(AFS_AIX51_ENV) && defined(AFS_64BIT_KERNEL))
135 CheckTypes(char *bufferp, int *typesp, int typeCount, char *outMsgBuffer)
143 for (tc = *bufferp;; outMsgBuffer++, tc = *(++bufferp)) {
146 /* hit end of string. We win as long as we aren't
155 inPercent = 1 - inPercent;
159 if (tc >= '0' && tc <= '9') {
160 /* skip digits in % string */
165 /* 'l' is a type modifier. */
169 /* otherwise, we've finally gotten to the type-describing
170 * character. Make sure there's a type descriptor, and then
171 * check the type descriptor.
175 return 0; /* no more type descriptors left */
177 if (typesp[tix] != 1) /* not a string descriptor */
180 *outMsgBuffer = (char)1;
182 if (tc == 'u' || tc == 'x' || tc == 'd' || tc == 'o') {
183 if (typesp[tix] != 0)
184 return 0; /* not an integer descriptor */
188 *outMsgBuffer = (char)2;
191 *outMsgBuffer = (char)3;
194 *outMsgBuffer = (char)4;
198 *outMsgBuffer = (char)5;
202 /* otherwise we're fine, so eat this descriptor */
208 #else /* AFS_SGI61_ENV */
210 CheckTypes(char *bufferp, int *typesp, int typeCount)
218 for (tc = *bufferp;; tc = *(++bufferp)) {
220 /* hit end of string. We win as long as we aren't
229 inPercent = 1 - inPercent;
233 if (tc >= '0' && tc <= '9')
234 continue; /* skip digits in % string */
235 /* otherwise, we've finally gotten to the type-describing
236 * character. Make sure there's a type descriptor, and then
237 * check the type descriptor.
241 return 0; /* no more type descriptors left */
242 if (tc == 's' && typesp[tix] != 1) /* not a string descriptor */
244 if ((tc == 'u' || tc == 'l' || tc == 'x' || tc == 'd')
245 && (typesp[tix] != 0))
246 return 0; /* not an integer descriptor */
247 /* otherwise we're fine, so eat this descriptor */
253 #endif /* AFS_SGI61_ENV */
255 /* display a single record.
256 * alp points at the first word in the array to be interpreted
257 * rsize gives the # of words in the array
259 #if defined(AFS_SGI61_ENV) && !defined(AFS_SGI62_ENV)
260 #define uint64_t long long
263 DisplayRecord(FILE *outFilep, register afs_int32 *alp, afs_int32 rsize)
265 char msgBuffer[1024];
266 #if defined(AFS_SGI61_ENV) || (defined(AFS_AIX51_ENV) && defined(AFS_64BIT_KERNEL))
267 char outMsgBuffer[1024];
269 uint64_t printfParms[ICL_MAXEXPANSION * /* max parms */ 4];
270 char *printfStrings[ICL_MAXEXPANSION * /* max parms */ 4];
271 #else /* AFS_SGI61_ENV */
272 long printfParms[ICL_MAXEXPANSION * /* max parms */ 4];
273 #endif /* AFS_SGI61_ENV */
274 int printfTypes[ICL_MAXEXPANSION * 4];
280 int pix; /* index in alp */
281 int pfpix; /* index in printfParms */
282 int pftix; /* index in printfTypes */
284 int printed; /* did we print the string yet? */
287 /* decode parameters */
288 temp = alp[0]; /* type encoded in low-order 24 bits, t0 high */
294 for (i = 0; i < 4 * ICL_MAXEXPANSION; i++)
296 /* decode each parameter, getting addrs for afs_hyper_t and strings */
297 for (i = 0; !done && i < 4; i++) {
298 type = (temp >> (18 - i * 6)) & 0x3f;
304 case ICL_TYPE_POINTER:
305 printfTypes[pftix++] = 0;
306 #if defined(AFS_SGI61_ENV) || (defined(AFS_AIX51_ENV) && defined(AFS_64BIT_KERNEL))
307 printfParms[pfpix] = alp[pix];
308 printfParms[pfpix] &= 0xffffffff;
309 if (afs_64bit_kernel) {
310 printfParms[pfpix] <<= 32;
311 printfParms[pfpix] |= alp[pix + 1];
313 #elif defined(AFS_OSF_ENV)
314 printfParms[pfpix] = alp[pix + 1];
315 printfParms[pfpix] |= (alp[pix] <<= 32);
316 #else /* !AFS_OSF_ENV && !AFS_SGI61_ENV */
317 printfParms[pfpix] = alp[pix];
322 printfTypes[pftix++] = 0;
323 printfParms[pfpix++] = alp[pix];
327 printfTypes[pftix++] = 0;
328 printfParms[pfpix++] = alp[pix];
329 printfTypes[pftix++] = 0;
330 printfParms[pfpix++] = alp[pix + 1];
333 printfTypes[pftix++] = 0;
334 printfParms[pfpix++] = alp[pix];
335 printfTypes[pftix++] = 0;
336 printfParms[pfpix++] = alp[pix + 1];
337 printfTypes[pftix++] = 0;
338 printfParms[pfpix++] = alp[pix + 2];
339 printfTypes[pftix++] = 0;
340 printfParms[pfpix++] = alp[pix + 3];
342 case ICL_TYPE_STRING:
343 printfTypes[pftix++] = 1;
345 printfStrings[pfpix++] = (char *)&alp[pix];
346 #else /* AFS_SGI64_ENV */
347 #if defined(AFS_SGI61_ENV) || (defined(AFS_AIX51_ENV) && defined(AFS_64BIT_KERNEL))
348 printfStrings[pfpix++] = (char *)&alp[pix];
349 #else /* AFS_SGI61_ENV */
350 printfParms[pfpix++] = (long)&alp[pix];
351 #endif /* AFS_SGI61_ENV */
352 #endif /* AFS_SGI64_ENV */
354 case ICL_TYPE_UNIXDATE:
356 printfParms[pfpix++] = (long)ctime(&tmv);
359 printf("DisplayRecord: Bad type %d in decode switch.\n", type);
366 pix += icl_GetSize(type, (char *)&alp[pix]);
369 /* next, try to decode the opcode into a printf string */
370 dce1_error_inq_text(alp[1], msgBuffer, &status);
372 /* if we got a string back, and it is compatible with the
373 * parms we've got, then print it.
377 #if defined(AFS_SGI61_ENV) || (defined(AFS_AIX51_ENV) && defined(AFS_64BIT_KERNEL))
378 if (CheckTypes(msgBuffer, printfTypes, pftix, outMsgBuffer)) {
379 /* we have a string to use, but it ends "(dfs / zcm)",
380 * so we remove the extra gunk.
382 j = strlen(outMsgBuffer);
384 outMsgBuffer[j - 11] = 0;
388 fprintf(outFilep, "time %d.%06d, pid %u: ", alp[3] / 1000000,
389 alp[3] % 1000000, alp[2]);
390 for (i = 0; i < j; i++) {
391 if ((int)outMsgBuffer[i] > 5)
392 fputc(outMsgBuffer[i], outFilep);
394 switch (outMsgBuffer[i]) {
398 fprintf(outFilep, "%s", printfStrings[pfpix++]);
400 case 2: /* signed integer */
401 fprintf(outFilep, "%" AFS_INT64_FMT, printfParms[pfpix++]);
403 case 3: /* unsigned integer */
404 fprintf(outFilep, "%llu", printfParms[pfpix++]);
406 case 4: /* octal integer */
407 fprintf(outFilep, "%llo", printfParms[pfpix++]);
409 case 5: /* hex integer */
410 fprintf(outFilep, "%llx", printfParms[pfpix++]);
414 "fstrace: Bad char %d in outMsgBuffer for parm %d\n",
415 outMsgBuffer[i], pfpix);
416 fprintf(outFilep, "fstrace: msgBuffer='%s'\n",
422 fprintf(outFilep, "\n");
425 #else /* AFS_SGI61_ENV */
426 if (CheckTypes(msgBuffer, printfTypes, pftix)) {
427 /* we have a string to use, but it ends "(dfs / zcm)",
428 * so we remove the extra gunk.
430 j = strlen(msgBuffer);
432 msgBuffer[j - 11] = 0;
433 fprintf(outFilep, "time %d.%06d, pid %u: ", alp[3] / 1000000,
434 alp[3] % 1000000, alp[2]);
435 fprintf(outFilep, msgBuffer, printfParms[0], printfParms[1],
436 printfParms[2], printfParms[3], printfParms[4],
437 printfParms[5], printfParms[6], printfParms[7],
438 printfParms[8], printfParms[9], printfParms[10],
439 printfParms[11], printfParms[12], printfParms[13],
440 printfParms[14], printfParms[15]);
441 fprintf(outFilep, "\n");
444 #endif /* AFS_SGI61_ENV */
446 fprintf(outFilep, "Type mismatch, using raw print.\n");
447 fprintf(outFilep, "%s", msgBuffer);
451 if (alp[1] == ICL_INFO_TIMESTAMP) {
453 fprintf(outFilep, "time %d.%06d, pid %u: %s\n", alp[3] / 1000000,
454 alp[3] % 1000000, alp[2], ctime(&tmv));
456 fprintf(outFilep, "raw op %d, time %d.%06d, pid %u\n", alp[1],
457 alp[3] / 1000000, alp[3] % 1000000, alp[2]);
458 /* now decode each parameter and print it */
461 for (i = 0; !done && i < 4; i++) {
462 type = (temp >> (18 - i * 6)) & 0x3f;
468 fprintf(outFilep, "p%d:%d ", i, alp[pix]);
472 tempParam = alp[pix];
474 tempParam |= alp[pix + 1];
475 fprintf(outFilep, "p%d:%" AFS_INT64_FMT " ", i, tempParam);
476 #else /* AFS_SGI61_ENV */
477 fprintf(outFilep, "p%d:%d ", i, alp[pix]);
478 #endif /* AFS_SGI61_ENV */
480 case ICL_TYPE_POINTER:
482 tempParam = alp[pix];
484 tempParam |= alp[pix + 1];
485 fprintf(outFilep, "p%d:0x%llx ", i, tempParam);
486 #else /* AFS_SGI61_ENV */
487 fprintf(outFilep, "p%d:0x%x ", i, alp[pix]);
488 #endif /* AFS_SGI61_ENV */
492 fprintf(outFilep, "p%d:%x.%x ", i, alp[pix],
496 fprintf(outFilep, "p%d:%d.%d.%d.%d ", i, alp[pix],
497 alp[pix + 1], alp[pix + 2], alp[pix + 3]);
499 case ICL_TYPE_STRING:
500 fprintf(outFilep, "p%d:%s ", i, (char *)&alp[pix]);
502 case ICL_TYPE_UNIXDATE:
504 fprintf(outFilep, "p%d:%s ", i,
509 ("DisplayRecord: Bad type %d in raw print switch.\n",
517 pix += icl_GetSize(type, (char *)&alp[pix]);
520 fprintf(outFilep, "\n"); /* done with line */
530 #include <nl_types.h>
532 #define FACILITY_CODE_MASK 0xF0000000
533 #define FACILITY_CODE_SHIFT 28
535 #define COMPONENT_CODE_MASK 0x0FFFF000
536 #define COMPONENT_CODE_SHIFT 12
538 #define STATUS_CODE_MASK 0x00000FFF
539 #define STATUS_CODE_SHIFT 0
541 #define NO_MESSAGE "THIS IS NOT A MESSAGE"
544 * The system-dependant location for the catalog files is defined in sysconf.h
545 * RPC_DEFAULT_NLSPATH should be defined in sysconf.h. Otherwise we use
546 * /usr/afs/etc/C/%s.cat
549 #ifndef RPC_NLS_FORMAT
550 #define RPC_NLS_FORMAT "%s.cat"
554 dce1_error_inq_text(afs_uint32 status_to_convert,
555 char *error_text, int *status)
557 unsigned short facility_code;
558 unsigned short component_code;
559 unsigned short status_code;
560 unsigned short i, failed = 0;
562 char component_name[4];
564 char filename_prefix[7];
565 char nls_filename[11];
566 char alt_filename[80];
568 #if defined(AFS_64BITPOINTER_ENV)
573 static char *facility_names[] = {
579 * set up output status for future error returns
581 if (status != NULL) {
585 * check for ok input status
587 if (status_to_convert == 0) {
588 if (status != NULL) {
591 strcpy((char *)error_text, "successful completion");
596 * extract the component, facility and status codes
599 (status_to_convert & FACILITY_CODE_MASK) >> FACILITY_CODE_SHIFT;
601 (status_to_convert & COMPONENT_CODE_MASK) >> COMPONENT_CODE_SHIFT;
602 status_code = (status_to_convert & STATUS_CODE_MASK) >> STATUS_CODE_SHIFT;
605 * see if this is a recognized facility
607 if (facility_code == 0
608 || facility_code > sizeof(facility_names) / sizeof(char *)) {
609 sprintf((char *)error_text, "status %08x (unknown facility)",
613 facility_name = facility_names[facility_code - 1];
615 * Convert component name from RAD-50 component code. (Mapping is:
616 * 0 => 'a', ..., 25 => 'z', 26 => '{', 27 => '0', ..., 36 => '9'.)
618 component_name[3] = 0;
619 component_name[2] = component_code % 40;
620 component_code /= 40;
621 component_name[1] = component_code % 40;
622 component_name[0] = component_code / 40;
623 for (i = 0; i < 3; i++) {
624 component_name[i] += (component_name[i] <= 26) ? 'a' : ('0' - 27);
626 sprintf(filename_prefix, "%3s%3s", facility_name, component_name);
627 sprintf(nls_filename, RPC_NLS_FORMAT, filename_prefix);
630 * Open the message file
632 #if defined(AFS_OSF20_ENV)
633 catd = (nl_catd) catopen(nls_filename, 0);
635 #if defined(AFS_64BITPOINTER_ENV)
636 J = (long)catopen(nls_filename, 0);
638 J = (int)catopen(nls_filename, 0);
642 if (catd == (nl_catd) - 1) {
644 * If we did not succeed in opening message file using NLSPATH,
645 * try to open the message file in a well-known default area
648 #ifndef RPC_DEFAULT_NLSPATH
649 sprintf(alt_filename, "%s/C/%s.cat", AFSDIR_CLIENT_ETC_DIRPATH,
652 sprintf(alt_filename, RPC_DEFAULT_NLSPATH, filename_prefix);
655 #if defined(AFS_OSF20_ENV)
656 catd = (nl_catd) catopen(alt_filename, 0);
658 #if defined(AFS_64BITPOINTER_ENV)
659 J = (long)catopen(alt_filename, 0);
661 J = (int)catopen(alt_filename, 0);
665 if (catd == (nl_catd) - 1) {
666 sprintf((char *)error_text, "status %08x (%s / %s)",
667 status_to_convert, facility_name, component_name);
672 * try to get the specified message from the file
674 message = (char *)catgets(catd, 1, status_code, NO_MESSAGE);
676 * if everything went well, return the resulting message
678 if (strcmp(message, NO_MESSAGE) != 0) {
679 sprintf((char *)error_text, "%s (%s / %s)", message, facility_name,
681 if (status != NULL) {
690 sprintf((char *)error_text, "status %08x (%s / %s)",
691 status_to_convert, facility_name, component_name);
697 icl_DumpKernel(FILE *outFilep, char *setname)
699 afs_int32 bufferSize = 0;
702 afs_int32 code, retVal = 0;
707 afs_int32 dummy, dummy2;
710 /* first, enumerate the logs we're interested in */
713 /* dump logs for a particular set */
714 for (i = 0; i < ICL_LOGSPERSET; i++) {
716 afs_syscall(AFSCALL_ICL, ICL_OP_ENUMLOGSBYSET, (long)setname,
717 i, (long)tname, sizeof(tname), 0, 0);
719 if (errno == EBADF) {
721 continue; /* missing slot, nothing to worry about */
726 afs_syscall(AFSCALL_ICL, ICL_OP_GETLOGINFO, (long)tname,
727 (long)&dummy, (long)&dummy2, 0, 0, 0);
731 if (dummy > bufferSize) /* find biggest log */
733 lip = (struct logInfo *)malloc(sizeof(struct logInfo));
734 memset((char *)lip, 0, sizeof(*lip));
735 lip->nextp = allInfo;
737 lip->name = (char *)malloc(strlen(tname) + 1);
738 strcpy(lip->name, tname);
743 for (i = 0; i < 1000; i++) {
745 afs_syscall(AFSCALL_ICL, ICL_OP_ENUMLOGS, i, (long)tname,
746 sizeof(tname), (long)&dummy, 0, 0);
749 if (dummy > bufferSize) /* find biggest log */
751 lip = (struct logInfo *)malloc(sizeof(struct logInfo));
752 memset((char *)lip, 0, sizeof(*lip));
753 lip->nextp = allInfo;
755 lip->name = (char *)malloc(strlen(tname) + 1);
756 strcpy(lip->name, tname);
762 bufferp = (afs_int32 *) malloc(sizeof(afs_int32) * bufferSize);
766 fprintf(outFilep, "Found %d logs.\n", i);
768 /* now print out the contents of each log */
769 for (lip = allInfo; lip; lip = lip->nextp) {
770 fprintf(outFilep, "\nContents of log %s:\n", lip->name);
771 /* read out everything first; gets a more consistent
774 nwords = 0; /* total words copied out */
776 /* display all the entries in the log */
777 if (bufferSize - nwords <= 0)
778 break; /* filled whole buffer */
780 afs_syscall(AFSCALL_ICL, ICL_OP_COPYOUT, (long)lip->name,
781 (long)(bufferp + nwords), bufferSize - nwords,
784 /* otherwise we've got an error */
785 fprintf(outFilep, "Returned error %d dumping log.\n", errno);
788 /* otherwise, we have flags in the high order byte, and
789 * a length (in words) in the remainder.
791 if ((code >> 24) & ICL_COPYOUTF_MISSEDSOME)
792 fprintf(outFilep, "Log wrapped; data missing.\n");
800 } /* for loop over all cookies */
802 /* otherwise we should display all of the log entries here.
803 * Note that a record may end in the middle, in which case
804 * we should start over with the cookie value of the start
807 for (ix = 0; ix < nwords;) {
808 /* start of a record */
809 rlength = (bufferp[ix] >> 24) & 0xff;
811 fprintf(outFilep, "Internal error: 0 length record\n");
815 /* ensure that entire record fits */
816 if (ix + rlength > nwords) {
817 /* doesn't fit, adjust cookie and break */
820 /* print the record */
821 DisplayRecord(outFilep, &bufferp[ix], rlength);
824 /* obsolete: read entire buffer first */
825 i += rlength; /* update cookie value, too */
827 } /* for loop displaying buffer */
828 } /* for loop over all logs */
835 /* clear out log 'name' */
837 icl_ClearLog(char *name)
841 code = afs_syscall(AFSCALL_ICL, ICL_OP_CLRLOG, (long)name, 0, 0, 0, 0, 0);
845 /* clear out set 'name' */
847 icl_ClearSet(char *name)
851 code = afs_syscall(AFSCALL_ICL, ICL_OP_CLRSET, (long)name, 0, 0, 0, 0, 0);
855 /* clear out all logs */
861 code = afs_syscall(AFSCALL_ICL, ICL_OP_CLRALL, 0, 0, 0, 0, 0, 0);
865 /* list out all available sets to outFileP */
867 icl_ListSets(FILE *outFileP)
874 for (i = 0; i < 1000; i++) {
876 afs_syscall(AFSCALL_ICL, ICL_OP_ENUMSETS, i, (long)tname,
877 sizeof(tname), (long)&states, 0, 0);
880 (void)fprintf(outFileP, "%s %s%s%s\n", tname,
881 (states & ICL_SETF_ACTIVE) ? "active" : "inactive",
882 (states & ICL_SETF_FREED) ? " (dormant)" : "",
883 (states & ICL_SETF_PERSISTENT) ? " persistent" : "");
889 /* list out all available logs to outFileP */
891 icl_ListLogs(FILE *outFileP, int int32flg)
899 for (i = 0; i < 1000; i++) {
901 afs_syscall(AFSCALL_ICL, ICL_OP_ENUMLOGS, i, (long)tname,
902 sizeof(tname), (long)&logSize, 0, 0);
906 /* get more information on the log */
908 afs_syscall(AFSCALL_ICL, ICL_OP_GETLOGINFO, (long)tname,
909 (long)&logSize, (long)&allocated, 0, 0, 0);
912 (void)fprintf(outFileP, "%s : %d kbytes (%s)\n", tname,
914 allocated ? "allocated" : "unallocated");
916 (void)fprintf(outFileP, "%s\n", tname);
922 /* list out all available logs to outFileP */
924 icl_ListLogsBySet(FILE *outFileP, char *setname, int int32flg)
932 for (i = 0; i < ICL_LOGSPERSET; i++) {
934 afs_syscall(AFSCALL_ICL, ICL_OP_ENUMLOGSBYSET, (long)setname, i,
935 (long)tname, sizeof(tname), 0, 0);
937 if (errno == EBADF) {
939 continue; /* missing */
944 /* get more information on the log */
946 afs_syscall(AFSCALL_ICL, ICL_OP_GETLOGINFO, (long)tname,
947 (long)&logSize, (long)&allocated, 0, 0, 0);
950 (void)fprintf(outFileP, "%s : %d kbytes (%s)\n", tname,
952 allocated ? "allocated" : "unallocated");
954 (void)fprintf(outFileP, "%s\n", tname);
960 /* activate/deactivate/free specified set */
962 icl_ChangeSetState(char *name, afs_int32 op)
966 code = afs_syscall(AFSCALL_ICL, ICL_OP_SETSTAT, (long)name, op, 0, 0, 0, 0);
970 /* activate/deactivate/free all sets */
972 icl_ChangeAllSetState(afs_int32 op)
976 code = afs_syscall(AFSCALL_ICL, ICL_OP_SETSTATALL, op, 0, 0, 0, 0, 0);
980 /* set size if log */
982 icl_ChangeLogSize(char *name, afs_int32 logSize)
987 afs_syscall(AFSCALL_ICL, ICL_OP_SETLOGSIZE, (long)name, logSize, 0,
992 /* get logsize of specified log */
994 icl_GetLogsize(char *logname, afs_int32 *logSizeP, int *allocatedP)
998 afs_syscall(AFSCALL_ICL, ICL_OP_GETLOGINFO, (long)logname,
999 (long)logSizeP, (long)allocatedP, 0, 0, 0);
1003 /* get state of specified set */
1005 icl_GetSetState(char *setname, afs_int32 *stateP)
1009 afs_syscall(AFSCALL_ICL, ICL_OP_GETSETINFO, (long)setname,
1010 (long)stateP, 0, 0, 0, 0);
1015 icl_TailKernel(FILE *outFilep, char *logname, afs_int32 waitTime)
1017 afs_int32 bufferSize = 0;
1018 afs_int32 newBufferSize;
1021 afs_int32 code, retVal = 0;
1027 /* get information about the specified log */
1029 afs_syscall(AFSCALL_ICL, ICL_OP_GETLOGINFO, (long)logname,
1030 (long)&bufferSize, (long)&allocated, 0, 0, 0);
1032 if (errno == ENOENT)
1033 (void)fprintf(stderr, "'%s' not found\n", logname);
1035 (void)fprintf(stderr,
1036 "cannot get information on log '%s' (errno = %d)\n",
1042 (void)fprintf(stderr, "'%s' not allocated\n", logname);
1046 if (bufferSize == 0)
1048 bufferp = (afs_int32 *) malloc(sizeof(afs_int32) * bufferSize);
1050 (void)fprintf(stderr, "cannot allocate %d words for buffer\n",
1055 /* start "infinite" loop */
1057 /* read out all that's currently there */
1058 nwords = 0; /* total words copied out */
1059 i = 0; /* initialize cookie */
1061 /* display all the entries in the log */
1062 if (bufferSize - nwords <= 0)
1063 break; /* filled whole buffer, clear when done */
1065 afs_syscall(AFSCALL_ICL, ICL_OP_COPYOUTCLR, (long)logname,
1066 (long)(bufferp + nwords), bufferSize - nwords,
1069 /* otherwise we've got an error */
1070 fprintf(stderr, "returned error %d dumping log.\n", errno);
1074 /* otherwise, we have flags in the high order byte, and
1075 * a length (in words) in the remainder.
1084 } /* for loop over all cookies */
1086 /* otherwise we should display all of the log entries here.
1087 * Note that a record may end in the middle, in which case
1088 * we should start over with the cookie value of the start
1091 for (ix = 0; ix < nwords;) {
1092 /* start of a record */
1093 rlength = (bufferp[ix] >> 24) & 0xff;
1094 /* ensure that entire record fits */
1095 if (ix + rlength > nwords) {
1096 /* doesn't fit, adjust cookie and break */
1098 fprintf(stderr, "BOGUS: 0 length record\n");
1104 /* print the record */
1105 DisplayRecord(outFilep, &bufferp[ix], rlength);
1107 } /* for loop displaying buffer */
1112 /* see if things have changed */
1114 afs_syscall(AFSCALL_ICL, ICL_OP_GETLOGINFO, (long)logname,
1115 (long)&newBufferSize, (long)&allocated, 0, 0, 0);
1117 if (errno == ENOENT)
1118 (void)fprintf(stderr, "'%s' not found\n", logname);
1120 (void)fprintf(stderr,
1121 "cannot get information on log '%s' (errno = %d)\n",
1128 (void)fprintf(stderr, "'%s' no int32er allocated\n", logname);
1133 if (bufferSize == 0) {
1134 (void)fprintf(stderr, "buffer size has become 0\n");
1138 if (bufferSize != newBufferSize) {
1139 /* have to reallocate a buffer */
1140 bufferSize = newBufferSize;
1142 bufferp = (afs_int32 *) malloc(sizeof(afs_int32) * bufferSize);
1144 (void)fprintf(stderr, "cannot allocate %d words for buffer\n",
1150 } /* infinite loop */
1157 #if !defined(AFS_SGI_ENV)
1159 afs_syscall(long call, long parm0, long parm1, long parm2, long parm3,
1160 long parm4, long parm5, long parm6)
1163 #ifdef AFS_LINUX20_ENV
1164 #if defined AFS_LINUX_64BIT_KERNEL
1166 /* don't want to sign extend it to 64bit, so using ulong */
1167 eparm[0] = (unsigned long)parm3;
1168 eparm[1] = (unsigned long)parm4;
1169 eparm[2] = (unsigned long)parm5;
1170 eparm[3] = (unsigned long)parm6;
1178 /* Linux can only handle 5 arguments in the actual syscall. */
1179 if (call == AFSCALL_ICL) {
1180 rval = proc_afs_syscall(call, parm0, parm1, parm2, eparm, &code);
1182 code = syscall(AFS_SYSCALL, call, parm0, parm1, parm2, eparm);
1184 rval = proc_afs_syscall(call, parm0, parm1, parm2, parm3, &code);
1186 code = syscall(AFS_SYSCALL, call, parm0, parm1, parm2, parm3);
1188 #if defined(AFS_SPARC64_LINUX20_ENV) || defined(AFS_SPARC_LINUX20_ENV)
1189 /* on sparc this function returns none value, so do it myself */
1190 __asm__ __volatile__("mov %o0, %i0; ret; restore");
1193 #ifdef AFS_DARWIN80_ENV
1194 code = ioctl_afs_syscall(call, parm0, parm1, parm2, parm3, parm4, parm5, &rval);
1195 if (!code) code = rval;
1197 #if !defined(AFS_SGI_ENV) && !defined(AFS_AIX32_ENV)
1198 code = syscall(AFS_SYSCALL, call, parm0, parm1, parm2, parm3, parm4);
1200 #if defined(AFS_SGI_ENV)
1201 code = syscall(AFS_ICL, call, parm0, parm1, parm2, parm3, parm4); /* XXX */
1203 code = syscall(AFSCALL_ICL, parm0, parm1, parm2, parm3, parm4);
1207 #endif /* AFS_LINUX20_ENV */
1215 /* init function, called once, under icl_lock */
1222 /* setup signal handler, in user space */
1229 icl_CreateSet(char *name, struct afs_icl_log *baseLogp,
1230 struct afs_icl_log *fatalLogp, struct afs_icl_set **outSetpp)
1232 return icl_CreateSetWithFlags(name, baseLogp, fatalLogp, /*flags */ 0,
1236 /* create a set, given pointers to base and fatal logs, if any.
1237 * Logs are unlocked, but referenced, and *outSetpp is returned
1238 * referenced. Function bumps reference count on logs, since it
1239 * addds references from the new icl_set. When the set is destroyed,
1240 * those references will be released.
1243 icl_CreateSetWithFlags(char *name, struct afs_icl_log *baseLogp,
1244 struct afs_icl_log *fatalLogp, afs_uint32 flags,
1245 struct afs_icl_set **outSetpp)
1247 register struct afs_icl_set *setp;
1249 afs_int32 states = ICL_DEFAULT_SET_STATES;
1254 for (setp = icl_allSets; setp; setp = setp->nextp) {
1255 if (strcmp(setp->name, name) == 0) {
1258 if (flags & ICL_CRSET_FLAG_PERSISTENT) {
1259 setp->states |= ICL_SETF_PERSISTENT;
1265 /* determine initial state */
1266 if (flags & ICL_CRSET_FLAG_DEFAULT_ON)
1267 states = ICL_SETF_ACTIVE;
1268 else if (flags & ICL_CRSET_FLAG_DEFAULT_OFF)
1269 states = ICL_SETF_FREED;
1270 if (flags & ICL_CRSET_FLAG_PERSISTENT)
1271 states |= ICL_SETF_PERSISTENT;
1273 setp = (struct afs_icl_set *)osi_Alloc(sizeof(struct afs_icl_set));
1274 memset((caddr_t) setp, 0, sizeof(*setp));
1276 if (states & ICL_SETF_FREED)
1277 states &= ~ICL_SETF_ACTIVE; /* if freed, can't be active */
1278 setp->states = states;
1280 setp->name = (char *)osi_Alloc(strlen(name) + 1);
1281 strcpy(setp->name, name);
1282 setp->nevents = ICL_DEFAULTEVENTS;
1283 setp->eventFlags = (char *)osi_Alloc(ICL_DEFAULTEVENTS);
1284 for (i = 0; i < ICL_DEFAULTEVENTS; i++)
1285 setp->eventFlags[i] = 0xff; /* default to enabled */
1287 /* update this global info under the icl_lock */
1288 setp->nextp = icl_allSets;
1291 /* set's basic lock is still held, so we can finish init */
1293 setp->logs[0] = baseLogp;
1294 icl_LogHold(baseLogp);
1295 if (!(setp->states & ICL_SETF_FREED))
1296 icl_LogUse(baseLogp); /* log is actually being used */
1299 setp->logs[1] = fatalLogp;
1300 icl_LogHold(fatalLogp);
1301 if (!(setp->states & ICL_SETF_FREED))
1302 icl_LogUse(fatalLogp); /* log is actually being used */
1309 /* function to change event enabling information for a particular set */
1311 icl_SetEnable(struct afs_icl_set *setp, afs_int32 eventID, int setValue)
1315 if (!ICL_EVENTOK(setp, eventID)) {
1318 tp = &setp->eventFlags[ICL_EVENTBYTE(eventID)];
1320 *tp |= ICL_EVENTMASK(eventID);
1322 *tp &= ~(ICL_EVENTMASK(eventID));
1326 /* return indication of whether a particular event ID is enabled
1327 * for tracing. If *getValuep is set to 0, the event is disabled,
1328 * otherwise it is enabled. All events start out enabled by default.
1331 icl_GetEnable(struct afs_icl_set *setp, afs_int32 eventID, int *getValuep)
1333 if (!ICL_EVENTOK(setp, eventID)) {
1336 if (setp->eventFlags[ICL_EVENTBYTE(eventID)] & ICL_EVENTMASK(eventID))
1343 /* hold and release event sets */
1345 icl_SetHold(register struct afs_icl_set *setp)
1351 /* free a set. Called with icl_lock locked */
1353 icl_ZapSet(register struct afs_icl_set *setp)
1355 register struct afs_icl_set **lpp, *tp;
1357 register struct afs_icl_log *tlp;
1359 for (lpp = &icl_allSets, tp = *lpp; tp; lpp = &tp->nextp, tp = *lpp) {
1361 /* found the dude we want to remove */
1363 osi_Free(setp->name, 1 + strlen(setp->name));
1364 osi_Free(setp->eventFlags, ICL_EVENTBYTES(setp->nevents));
1365 for (i = 0; i < ICL_LOGSPERSET; i++) {
1366 if ((tlp = setp->logs[i]))
1369 osi_Free(setp, sizeof(struct afs_icl_set));
1370 break; /* won't find it twice */
1376 /* do the release, watching for deleted entries */
1378 icl_SetRele(register struct afs_icl_set *setp)
1380 if (--setp->refCount == 0 && (setp->states & ICL_SETF_DELETED)) {
1381 icl_ZapSet(setp); /* destroys setp's lock! */
1386 /* free a set entry, dropping its reference count */
1388 icl_SetFree(register struct afs_icl_set *setp)
1390 setp->states |= ICL_SETF_DELETED;
1395 /* find a set by name, returning it held */
1396 struct afs_icl_set *
1397 icl_FindSet(char *name)
1399 register struct afs_icl_set *tp;
1401 for (tp = icl_allSets; tp; tp = tp->nextp) {
1402 if (strcmp(tp->name, name) == 0) {
1403 /* this is the dude we want */
1411 /* zero out all the logs in the set */
1413 icl_ZeroSet(struct afs_icl_set *setp)
1418 struct afs_icl_log *logp;
1420 for (i = 0; i < ICL_LOGSPERSET; i++) {
1421 logp = setp->logs[i];
1424 tcode = icl_ZeroLog(logp);
1426 code = tcode; /* save the last bad one */
1434 icl_EnumerateSets(int (*aproc) (char *, void *, struct afs_icl_set *),
1437 register struct afs_icl_set *tp, *np;
1438 register afs_int32 code;
1441 for (tp = icl_allSets; tp; tp = np) {
1442 tp->refCount++; /* hold this guy */
1443 code = (*aproc) (tp->name, arock, tp);
1444 np = tp->nextp; /* tp may disappear next, but not np */
1445 if (--tp->refCount == 0 && (tp->states & ICL_SETF_DELETED))
1454 icl_AddLogToSet(struct afs_icl_set *setp, struct afs_icl_log *newlogp)
1459 for (i = 0; i < ICL_LOGSPERSET; i++) {
1460 if (!setp->logs[i]) {
1461 setp->logs[i] = newlogp;
1463 icl_LogHold(newlogp);
1464 if (!(setp->states & ICL_SETF_FREED)) {
1465 /* bump up the number of sets using the log */
1466 icl_LogUse(newlogp);
1475 icl_SetSetStat(struct afs_icl_set *setp, int op)
1479 struct afs_icl_log *logp;
1482 case ICL_OP_SS_ACTIVATE: /* activate a log */
1484 * If we are not already active, see if we have released
1485 * our demand that the log be allocated (FREED set). If
1486 * we have, reassert our desire.
1488 if (!(setp->states & ICL_SETF_ACTIVE)) {
1489 if (setp->states & ICL_SETF_FREED) {
1490 /* have to reassert desire for logs */
1491 for (i = 0; i < ICL_LOGSPERSET; i++) {
1492 logp = setp->logs[i];
1499 setp->states &= ~ICL_SETF_FREED;
1501 setp->states |= ICL_SETF_ACTIVE;
1506 case ICL_OP_SS_DEACTIVATE: /* deactivate a log */
1507 /* this doesn't require anything beyond clearing the ACTIVE flag */
1508 setp->states &= ~ICL_SETF_ACTIVE;
1512 case ICL_OP_SS_FREE: /* deassert design for log */
1514 * if we are already in this state, do nothing; otherwise
1515 * deassert desire for log
1517 if (setp->states & ICL_SETF_ACTIVE)
1520 if (!(setp->states & ICL_SETF_FREED)) {
1521 for (i = 0; i < ICL_LOGSPERSET; i++) {
1522 logp = setp->logs[i];
1525 icl_LogFreeUse(logp);
1529 setp->states |= ICL_SETF_FREED;
1542 struct afs_icl_log *afs_icl_allLogs = 0;
1544 /* hold and release logs */
1546 icl_LogHold(register struct afs_icl_log *logp)
1552 /* hold and release logs, called with lock already held */
1554 icl_LogHoldNL(register struct afs_icl_log *logp)
1560 /* keep track of how many sets believe the log itself is allocated */
1562 icl_LogUse(register struct afs_icl_log *logp)
1564 if (logp->setCount == 0) {
1565 /* this is the first set actually using the log -- allocate it */
1566 if (logp->logSize == 0) {
1567 /* we weren't passed in a hint and it wasn't set */
1568 logp->logSize = ICL_DEFAULT_LOGSIZE;
1571 (afs_int32 *) osi_Alloc(sizeof(afs_int32) * logp->logSize);
1577 /* decrement the number of real users of the log, free if possible */
1579 icl_LogFreeUse(register struct afs_icl_log *logp)
1581 if (--logp->setCount == 0) {
1582 /* no more users -- free it (but keep log structure around) */
1583 osi_Free(logp->datap, sizeof(afs_int32) * logp->logSize);
1584 logp->firstUsed = logp->firstFree = 0;
1585 logp->logElements = 0;
1591 /* set the size of the log to 'logSize' */
1593 icl_LogSetSize(register struct afs_icl_log *logp, afs_int32 logSize)
1596 /* nothing to worry about since it's not allocated */
1597 logp->logSize = logSize;
1600 logp->firstUsed = logp->firstFree = 0;
1601 logp->logElements = 0;
1603 /* free and allocate a new one */
1604 osi_Free(logp->datap, sizeof(afs_int32) * logp->logSize);
1605 logp->datap = (afs_int32 *) osi_Alloc(sizeof(afs_int32) * logSize);
1606 logp->logSize = logSize;
1612 /* free a log. Called with icl_lock locked. */
1614 icl_ZapLog(register struct afs_icl_log *logp)
1616 register struct afs_icl_log **lpp, *tp;
1618 for (lpp = &afs_icl_allLogs, tp = *lpp; tp; lpp = &tp->nextp, tp = *lpp) {
1620 /* found the dude we want to remove */
1622 osi_Free(logp->name, 1 + strlen(logp->name));
1623 osi_Free(logp->datap, logp->logSize * sizeof(afs_int32));
1624 osi_Free(logp, sizeof(struct icl_log));
1625 break; /* won't find it twice */
1631 /* do the release, watching for deleted entries */
1633 icl_LogRele(register struct afs_icl_log *logp)
1635 if (--logp->refCount == 0 && (logp->states & ICL_LOGF_DELETED)) {
1636 icl_ZapLog(logp); /* destroys logp's lock! */
1641 /* do the release, watching for deleted entries, log already held */
1643 icl_LogReleNL(register struct afs_icl_log *logp)
1645 if (--logp->refCount == 0 && (logp->states & ICL_LOGF_DELETED)) {
1646 icl_ZapLog(logp); /* destroys logp's lock! */
1651 /* zero out the log */
1653 icl_ZeroLog(register struct afs_icl_log *logp)
1655 logp->firstUsed = logp->firstFree = 0;
1656 logp->logElements = 0;
1660 /* free a log entry, and drop its reference count */
1662 icl_LogFree(register struct afs_icl_log *logp)
1664 logp->states |= ICL_LOGF_DELETED;
1671 icl_EnumerateLogs(int (*aproc)
1672 (char *name, void *arock, struct afs_icl_log * tp),
1675 register struct afs_icl_log *tp;
1676 register afs_int32 code;
1679 for (tp = afs_icl_allLogs; tp; tp = tp->nextp) {
1680 tp->refCount++; /* hold this guy */
1681 code = (*aproc) (tp->name, arock, tp);
1682 if (--tp->refCount == 0)
1691 afs_icl_bulkSetinfo_t *
1692 GetBulkSetInfo(void)
1694 unsigned int infoSize;
1697 sizeof(afs_icl_bulkSetinfo_t) + (ICL_RPC_MAX_SETS -
1698 1) * sizeof(afs_icl_setinfo_t);
1700 setInfo = (afs_icl_bulkSetinfo_t *) malloc(infoSize);
1702 (void)fprintf(stderr,
1703 "Could not allocate the memory for bulk set info structure\n");
1707 memset((char *)setInfo, 0, infoSize);
1712 afs_icl_bulkLoginfo_t *
1713 GetBulkLogInfo(void)
1715 unsigned int infoSize;
1718 sizeof(afs_icl_bulkLoginfo_t) + (ICL_RPC_MAX_LOGS -
1719 1) * sizeof(afs_icl_loginfo_t);
1721 logInfo = (afs_icl_bulkLoginfo_t *) malloc(infoSize);
1723 (void)fprintf(stderr,
1724 "Could not allocate the memory for bulk log info structure\n");
1729 memset((char *)logInfo, 0, infoSize);
1735 DoDump(struct cmd_syndesc *as, void *arock)
1739 afs_int32 waitTime = 10 /* seconds */ ;
1741 FILE *outfp = stdout;
1743 struct cmd_item *itemp;
1745 if (geteuid() != 0) {
1746 printf("fstrace must be run as root\n");
1750 if (as->parms[3].items) {
1751 if (!as->parms[1].items) {
1752 (void)fprintf(stderr, "-sleep can only be used with -follow\n");
1755 waitTime = strtol(as->parms[3].items->data, NULL, 0);
1758 if (as->parms[2].items) {
1759 /* try to open the specified output file */
1760 if ((outfp = fopen(as->parms[2].items->data, "w")) == NULL) {
1761 (void)fprintf(stderr, "Cannot open file '%s' for writing\n",
1762 as->parms[2].items->data);
1766 #ifdef AFS_SGI64_ENV
1767 startTime = time((time_t *) 0);
1769 startTime = time(0);
1771 (void)fprintf(outfp, "AFS Trace Dump -\n\n Date: %s\n",
1774 if (as->parms[0].items) {
1775 for (itemp = as->parms[0].items; itemp; itemp = itemp->next) {
1776 tcode = icl_DumpKernel(outfp, itemp->data);
1778 (void)fprintf(stderr, "Unable to dump set %s (errno = %d)\n",
1779 itemp->data, errno);
1783 } else if (as->parms[1].items) {
1784 logname = as->parms[1].items->data;
1785 code = icl_TailKernel(outfp, logname, waitTime);
1787 (void)fprintf(stderr,
1788 "Error tailing kernel log '%s' (errno = %d)\n",
1792 code = icl_DumpKernel(outfp, NULL);
1794 (void)fprintf(outfp, "\nAFS Trace Dump - %s\n",
1795 code ? "FAILED" : "Completed");
1797 if (outfp != stdout)
1798 (void)fclose(outfp);
1806 struct cmd_syndesc *dumpSyntax;
1809 cmd_CreateSyntax("dump", DoDump, NULL, "dump AFS trace logs");
1810 (void)cmd_AddParm(dumpSyntax, "-set", CMD_LIST, CMD_OPTIONAL, "set_name");
1811 (void)cmd_AddParm(dumpSyntax, "-follow", CMD_SINGLE, CMD_OPTIONAL,
1813 (void)cmd_AddParm(dumpSyntax, "-file", CMD_SINGLE, CMD_OPTIONAL,
1815 (void)cmd_AddParm(dumpSyntax, "-sleep", CMD_SINGLE, CMD_OPTIONAL,
1816 "seconds_between_reads");
1820 DoShowLog(register struct cmd_syndesc *as, void *arock)
1822 afs_int32 retVal = 0;
1827 struct cmd_item *itemp;
1829 if (geteuid() != 0) {
1830 printf("fstrace must be run as root\n");
1833 if (as->parms[2].items)
1836 if (as->parms[0].items) {
1837 /* enumerate logs for the specified sets */
1838 for (itemp = as->parms[0].items; itemp; itemp = itemp->next) {
1839 (void)fprintf(stdout, "Logs for set '%s':\n", itemp->data);
1840 code = icl_ListLogsBySet(stdout, itemp->data, int32flg);
1842 (void)fprintf(stderr,
1843 "Error in enumerating set %s (errno = %d)\n",
1844 itemp->data, errno);
1848 } else if (as->parms[1].items) {
1849 /* print out log information */
1850 for (itemp = as->parms[1].items; itemp; itemp = itemp->next) {
1851 code = icl_GetLogsize(itemp->data, &logSize, &allocated);
1853 (void)fprintf(stdout, "%s : %d kbytes (%s)\n", itemp->data,
1855 allocated ? "allocated" : "unallocated");
1857 (void)fprintf(stderr,
1858 "Could not find log '%s' (errno = %d)\n",
1859 itemp->data, errno);
1865 (void)fprintf(stdout, "Available logs:\n");
1866 code = icl_ListLogs(stdout, int32flg);
1868 (void)fprintf(stderr, "Error in listing logs (errno = %d)\n",
1880 struct cmd_syndesc *showSyntax;
1883 cmd_CreateSyntax("lslog", DoShowLog, NULL,
1884 "list available logs");
1885 (void)cmd_AddParm(showSyntax, "-set", CMD_LIST, CMD_OPTIONAL, "set_name");
1886 (void)cmd_AddParm(showSyntax, "-log", CMD_LIST, CMD_OPTIONAL, "log_name");
1887 (void)cmd_AddParm(showSyntax, "-long", CMD_FLAG, CMD_OPTIONAL, "");
1891 DoShowSet(register struct cmd_syndesc *as, void *arock)
1893 afs_int32 retVal = 0;
1896 struct cmd_item *itemp;
1898 if (geteuid() != 0) {
1899 printf("fstrace must be run as root\n");
1902 if (as->parms[0].items) {
1903 /* print information on the specified sets */
1904 for (itemp = as->parms[0].items; itemp; itemp = itemp->next) {
1905 code = icl_GetSetState(itemp->data, &state);
1907 (void)fprintf(stderr,
1908 "Error getting status on set %s (errno = %d)\n",
1909 itemp->data, errno);
1912 (void)fprintf(stdout, "Set %s: %s%s%s\n", itemp->data,
1913 (state & ICL_SETF_ACTIVE) ? "active" :
1915 (state & ICL_SETF_FREED) ? " (dormant)" : "",
1916 (state & ICL_SETF_PERSISTENT) ? " persistent" :
1921 (void)fprintf(stdout, "Available sets:\n");
1922 code = icl_ListSets(stdout);
1924 (void)fprintf(stderr, "Error in listing sets (errno = %d)\n",
1936 struct cmd_syndesc *showSyntax;
1939 cmd_CreateSyntax("lsset", DoShowSet, NULL,
1940 "list available event sets");
1941 (void)cmd_AddParm(showSyntax, "-set", CMD_LIST, CMD_OPTIONAL, "set_name");
1945 DoClear(register struct cmd_syndesc *as, void *arock)
1947 afs_int32 retVal = 0;
1949 struct cmd_item *itemp;
1951 if (geteuid() != 0) {
1952 printf("fstrace must be run as root\n");
1955 if (as->parms[0].items) {
1956 /* clear logs for the specified sets */
1957 for (itemp = as->parms[0].items; itemp; itemp = itemp->next) {
1958 code = icl_ClearSet(itemp->data);
1960 (void)fprintf(stderr,
1961 "Error in clearing set %s (errno = %d)\n",
1962 itemp->data, errno);
1966 } else if (as->parms[1].items) {
1967 /* clear specified log */
1968 for (itemp = as->parms[0].items; itemp; itemp = itemp->next) {
1969 code = icl_ClearLog(itemp->data);
1971 (void)fprintf(stderr,
1972 "Error in clearing log %s (errno = %d)\n",
1973 itemp->data, errno);
1978 /* clear all logs */
1979 code = icl_ClearAll();
1981 (void)fprintf(stderr, "Error in clearing logs (errno = %d)\n",
1993 struct cmd_syndesc *clearSyntax;
1996 cmd_CreateSyntax("clear", DoClear, NULL,
1997 "clear logs by logname or by event set");
1998 (void)cmd_AddParm(clearSyntax, "-set", CMD_LIST, CMD_OPTIONAL,
2000 (void)cmd_AddParm(clearSyntax, "-log", CMD_LIST, CMD_OPTIONAL,
2005 DoSet(register struct cmd_syndesc *as, void *arock)
2007 afs_int32 retVal = 0;
2012 struct cmd_item *itemp;
2014 if (geteuid() != 0) {
2015 printf("fstrace must be run as root\n");
2018 if (as->parms[1].items) {
2019 op = ICL_OP_SS_ACTIVATE;
2020 operation = "active";
2021 } else if (as->parms[2].items) {
2022 op = ICL_OP_SS_DEACTIVATE;
2023 operation = "inactive";
2024 } else if (as->parms[3].items) {
2025 op = ICL_OP_SS_DEACTIVATE;
2026 operation = "inactive";
2029 /* assume active" */
2030 op = ICL_OP_SS_ACTIVATE;
2031 operation = "active";
2034 if (as->parms[0].items) {
2035 /* activate specified sets */
2036 for (itemp = as->parms[0].items; itemp; itemp = itemp->next) {
2037 code = icl_ChangeSetState(itemp->data, op);
2039 (void)fprintf(stderr,
2040 "cannot set state of %s to %s (errno = %d)\n",
2041 itemp->data, operation, errno);
2043 } else if (doFree) {
2044 /* try to make it dormant as well */
2045 code = icl_ChangeSetState(itemp->data, ICL_OP_SS_FREE);
2047 (void)fprintf(stderr,
2048 "cannot set state of %s to dormant (errno = %d)\n",
2049 itemp->data, errno);
2056 code = icl_ChangeAllSetState(op);
2058 (void)fprintf(stderr,
2059 "cannot set the state of all sets to %s (errno = %d)\n",
2062 } else if (doFree) {
2063 /* try to make it dormant as well */
2064 code = icl_ChangeAllSetState(ICL_OP_SS_FREE);
2066 (void)fprintf(stderr,
2067 "cannot set the state of all sets to dormant (errno = %d)\n",
2080 struct cmd_syndesc *setSyntax;
2083 cmd_CreateSyntax("setset", DoSet, NULL,
2084 "set state of event sets");
2085 (void)cmd_AddParm(setSyntax, "-set", CMD_LIST, CMD_OPTIONAL, "set_name");
2086 (void)cmd_AddParm(setSyntax, "-active", CMD_FLAG, CMD_OPTIONAL, "");
2087 (void)cmd_AddParm(setSyntax, "-inactive", CMD_FLAG, CMD_OPTIONAL, "");
2088 (void)cmd_AddParm(setSyntax, "-dormant", CMD_FLAG, CMD_OPTIONAL, "");
2092 DoResize(register struct cmd_syndesc *as, void *arock)
2094 afs_int32 retVal = 0;
2096 afs_int32 bufferSize;
2097 struct cmd_item *itemp;
2099 if (geteuid() != 0) {
2100 printf("fstrace must be run as root\n");
2103 /* get buffer size */
2104 bufferSize = atoi(as->parms[1].items->data);
2105 bufferSize *= BUFFER_MULTIPLIER;
2106 if (bufferSize == 0)
2107 bufferSize = ICL_DEFAULT_LOGSIZE;
2109 /* set the size of the specified logs */
2110 if ((itemp = as->parms[0].items)) {
2111 for (; itemp; itemp = itemp->next) {
2112 code = icl_ChangeLogSize(itemp->data, bufferSize);
2114 (void)fprintf(stderr,
2115 "Error in changing log %s buffer size (errno = %d)\n",
2116 itemp->data, errno);
2121 /* Use the only current support log, "cmfx" */
2122 code = icl_ChangeLogSize("cmfx", bufferSize);
2124 (void)fprintf(stderr,
2125 "Error in changing log cmfx buffer size (errno = %d)\n",
2137 struct cmd_syndesc *setsizeSyntax;
2140 cmd_CreateSyntax("setlog", DoResize, NULL,
2141 "set the size of a log");
2142 (void)cmd_AddParm(setsizeSyntax, "-log", CMD_LIST, CMD_OPTIONAL,
2144 (void)cmd_AddParm(setsizeSyntax, "-buffersize", CMD_SINGLE, CMD_REQUIRED,
2145 "1-kilobyte_units");
2148 #include "AFS_component_version_number.c"
2151 main(int argc, char *argv[])
2153 setlocale(LC_ALL, "");
2154 #ifdef AFS_SGI62_ENV
2155 set_kernel_sizeof_long();
2158 /* set up user interface then dispatch */
2166 return (cmd_Dispatch(argc, argv));
2169 #include "AFS_component_version_number.c"
2172 main(int argc, char *argv[])
2174 printf("fstrace is NOT supported for this OS\n");