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>
20 #include <afs/afs_args.h>
22 #include <afs/afsutil.h>
25 #include <afs/sys_prototypes.h>
27 #if defined(AFS_OSF_ENV) || defined(AFS_SGI61_ENV) || (defined(AFS_AIX51_ENV) && defined(AFS_64BIT_KERNEL))
28 /* For SGI 6.2, this is changed to 1 if it's a 32 bit kernel. */
29 int afs_icl_sizeofLong = 2;
31 int afs_icl_sizeofLong = 1;
34 #if defined(AFS_SGI61_ENV) || (defined(AFS_AIX51_ENV) && defined(AFS_64BIT_KERNEL))
35 int afs_64bit_kernel = 1; /* Default for 6.2+, and always for 6.1 */
36 extern int afs_icl_sizeofLong; /* Used in ICL_SIZEHACK() */
39 /* If _SC_KERN_POINTERS not in sysconf, then we can assume a 32 bit abi. */
41 set_kernel_sizeof_long(void)
46 retval = sysconf(_SC_KERN_POINTERS);
49 afs_icl_sizeofLong = 2;
52 afs_icl_sizeofLong = 1;
56 #endif /* AFS_SGI62_ENV */
57 #endif /* AFS_SGI61_ENV */
59 int afs_syscall(long call, long parm0, long parm1, long parm2, long parm3,
60 long parm4, long parm5, long parm6);
61 void dce1_error_inq_text(afs_uint32 status_to_convert,
62 char *error_text, int *status);
63 int icl_CreateSetWithFlags(char *name, struct afs_icl_log *baseLogp,
64 struct afs_icl_log *fatalLogp, afs_uint32 flags,
65 struct afs_icl_set **outSetpp);
66 int icl_LogHold(struct afs_icl_log *logp);
67 int icl_LogUse(struct afs_icl_log *logp);
68 int icl_LogReleNL(struct afs_icl_log *logp);
69 int icl_LogRele(struct afs_icl_log *logp);
70 int icl_ZeroLog(struct afs_icl_log *logp);
71 int icl_LogFreeUse(struct afs_icl_log *logp);
73 #define BUFFER_MULTIPLIER 1024
75 /* make it big enough to snapshot everything at once, since
76 * decoding takes so long.
78 #define IBSIZE 100000 /* default size */
81 struct logInfo *nextp;
85 char dumpFileName[256] = "";
87 RegisterIclDumpFileName(char *name)
89 (void)sprintf(dumpFileName, "icl.%.250s", name);
92 /* define globals to use for bulk info */
93 afs_icl_bulkSetinfo_t *setInfo = (afs_icl_bulkSetinfo_t *) 0;
94 afs_icl_bulkLoginfo_t *logInfo = (afs_icl_bulkLoginfo_t *) 0;
96 struct afs_icl_set *icl_allSets = 0;
100 /* given a type and an address, get the size of the thing
104 icl_GetSize(afs_int32 type, char *addr)
110 ICL_SIZEHACK(type, addr, tsize, rsize);
114 /* Check types in printf string "bufferp", making sure that each
115 * is compatible with the corresponding parameter type described
116 * by typesp. Also watch for prematurely running out of parameters
117 * before the string is gone.
119 #if defined(AFS_SGI61_ENV) || (defined(AFS_AIX51_ENV) && defined(AFS_64BIT_KERNEL))
121 CheckTypes(char *bufferp, int *typesp, int typeCount, char *outMsgBuffer)
129 for (tc = *bufferp;; outMsgBuffer++, tc = *(++bufferp)) {
132 /* hit end of string. We win as long as we aren't
141 inPercent = 1 - inPercent;
145 if (tc >= '0' && tc <= '9') {
146 /* skip digits in % string */
151 /* 'l' is a type modifier. */
155 /* otherwise, we've finally gotten to the type-describing
156 * character. Make sure there's a type descriptor, and then
157 * check the type descriptor.
161 return 0; /* no more type descriptors left */
163 if (typesp[tix] != 1) /* not a string descriptor */
166 *outMsgBuffer = (char)1;
168 if (tc == 'u' || tc == 'x' || tc == 'd' || tc == 'o') {
169 if (typesp[tix] != 0)
170 return 0; /* not an integer descriptor */
174 *outMsgBuffer = (char)2;
177 *outMsgBuffer = (char)3;
180 *outMsgBuffer = (char)4;
184 *outMsgBuffer = (char)5;
188 /* otherwise we're fine, so eat this descriptor */
194 #else /* AFS_SGI61_ENV */
196 CheckTypes(char *bufferp, int *typesp, int typeCount)
204 for (tc = *bufferp;; tc = *(++bufferp)) {
206 /* hit end of string. We win as long as we aren't
215 inPercent = 1 - inPercent;
219 if (tc >= '0' && tc <= '9')
220 continue; /* skip digits in % string */
221 /* otherwise, we've finally gotten to the type-describing
222 * character. Make sure there's a type descriptor, and then
223 * check the type descriptor.
227 return 0; /* no more type descriptors left */
228 if (tc == 's' && typesp[tix] != 1) /* not a string descriptor */
230 if ((tc == 'u' || tc == 'l' || tc == 'x' || tc == 'd')
231 && (typesp[tix] != 0))
232 return 0; /* not an integer descriptor */
233 /* otherwise we're fine, so eat this descriptor */
239 #endif /* AFS_SGI61_ENV */
241 /* display a single record.
242 * alp points at the first word in the array to be interpreted
243 * rsize gives the # of words in the array
245 #if defined(AFS_SGI61_ENV) && !defined(AFS_SGI62_ENV)
246 #define uint64_t long long
249 DisplayRecord(FILE *outFilep, afs_int32 *alp, afs_int32 rsize)
251 char msgBuffer[1024];
252 #if defined(AFS_SGI61_ENV) || (defined(AFS_AIX51_ENV) && defined(AFS_64BIT_KERNEL))
253 char outMsgBuffer[1024];
255 uint64_t printfParms[ICL_MAXEXPANSION * /* max parms */ 4];
256 char *printfStrings[ICL_MAXEXPANSION * /* max parms */ 4];
257 #else /* AFS_SGI61_ENV */
258 long printfParms[ICL_MAXEXPANSION * /* max parms */ 4];
259 #endif /* AFS_SGI61_ENV */
260 int printfTypes[ICL_MAXEXPANSION * 4];
266 int pix; /* index in alp */
267 int pfpix; /* index in printfParms */
268 int pftix; /* index in printfTypes */
270 int printed; /* did we print the string yet? */
273 /* decode parameters */
274 temp = alp[0]; /* type encoded in low-order 24 bits, t0 high */
280 for (i = 0; i < 4 * ICL_MAXEXPANSION; i++)
282 /* decode each parameter, getting addrs for afs_hyper_t and strings */
283 for (i = 0; !done && i < 4; i++) {
284 type = (temp >> (18 - i * 6)) & 0x3f;
290 case ICL_TYPE_POINTER:
291 printfTypes[pftix++] = 0;
292 #if defined(AFS_SGI61_ENV) || (defined(AFS_AIX51_ENV) && defined(AFS_64BIT_KERNEL))
293 printfParms[pfpix] = alp[pix];
294 printfParms[pfpix] &= 0xffffffff;
295 if (afs_64bit_kernel) {
296 printfParms[pfpix] <<= 32;
297 printfParms[pfpix] |= alp[pix + 1];
299 #elif defined(AFS_OSF_ENV)
300 printfParms[pfpix] = alp[pix + 1];
301 printfParms[pfpix] |= (alp[pix] <<= 32);
302 #else /* !AFS_OSF_ENV && !AFS_SGI61_ENV */
303 printfParms[pfpix] = alp[pix];
308 printfTypes[pftix++] = 0;
309 printfParms[pfpix++] = alp[pix];
313 printfTypes[pftix++] = 0;
314 printfParms[pfpix++] = alp[pix];
315 printfTypes[pftix++] = 0;
316 printfParms[pfpix++] = alp[pix + 1];
319 printfTypes[pftix++] = 0;
320 printfParms[pfpix++] = alp[pix];
321 printfTypes[pftix++] = 0;
322 printfParms[pfpix++] = alp[pix + 1];
323 printfTypes[pftix++] = 0;
324 printfParms[pfpix++] = alp[pix + 2];
325 printfTypes[pftix++] = 0;
326 printfParms[pfpix++] = alp[pix + 3];
328 case ICL_TYPE_STRING:
329 printfTypes[pftix++] = 1;
331 printfStrings[pfpix++] = (char *)&alp[pix];
332 #else /* AFS_SGI64_ENV */
333 #if defined(AFS_SGI61_ENV) || (defined(AFS_AIX51_ENV) && defined(AFS_64BIT_KERNEL))
334 printfStrings[pfpix++] = (char *)&alp[pix];
335 #else /* AFS_SGI61_ENV */
336 printfParms[pfpix++] = (long)&alp[pix];
337 #endif /* AFS_SGI61_ENV */
338 #endif /* AFS_SGI64_ENV */
340 case ICL_TYPE_UNIXDATE:
342 printfParms[pfpix++] = (long)ctime(&tmv);
345 printf("DisplayRecord: Bad type %d in decode switch.\n", type);
352 pix += icl_GetSize(type, (char *)&alp[pix]);
355 /* next, try to decode the opcode into a printf string */
356 dce1_error_inq_text(alp[1], msgBuffer, &status);
358 /* if we got a string back, and it is compatible with the
359 * parms we've got, then print it.
363 #if defined(AFS_SGI61_ENV) || (defined(AFS_AIX51_ENV) && defined(AFS_64BIT_KERNEL))
364 if (CheckTypes(msgBuffer, printfTypes, pftix, outMsgBuffer)) {
365 /* we have a string to use, but it ends "(dfs / zcm)",
366 * so we remove the extra gunk.
368 j = strlen(outMsgBuffer);
370 outMsgBuffer[j - 11] = 0;
374 fprintf(outFilep, "time %d.%06d, pid %u: ", alp[3] / 1000000,
375 alp[3] % 1000000, alp[2]);
376 for (i = 0; i < j; i++) {
377 if ((int)outMsgBuffer[i] > 5)
378 fputc(outMsgBuffer[i], outFilep);
380 switch (outMsgBuffer[i]) {
384 fprintf(outFilep, "%s", printfStrings[pfpix++]);
386 case 2: /* signed integer */
387 fprintf(outFilep, "%" AFS_INT64_FMT, printfParms[pfpix++]);
389 case 3: /* unsigned integer */
390 fprintf(outFilep, "%llu", printfParms[pfpix++]);
392 case 4: /* octal integer */
393 fprintf(outFilep, "%llo", printfParms[pfpix++]);
395 case 5: /* hex integer */
396 fprintf(outFilep, "%llx", printfParms[pfpix++]);
400 "fstrace: Bad char %d in outMsgBuffer for parm %d\n",
401 outMsgBuffer[i], pfpix);
402 fprintf(outFilep, "fstrace: msgBuffer='%s'\n",
408 fprintf(outFilep, "\n");
411 #else /* AFS_SGI61_ENV */
412 if (CheckTypes(msgBuffer, printfTypes, pftix)) {
413 /* we have a string to use, but it ends "(dfs / zcm)",
414 * so we remove the extra gunk.
416 j = strlen(msgBuffer);
418 msgBuffer[j - 11] = 0;
419 fprintf(outFilep, "time %d.%06d, pid %u: ", alp[3] / 1000000,
420 alp[3] % 1000000, alp[2]);
421 fprintf(outFilep, msgBuffer, printfParms[0], printfParms[1],
422 printfParms[2], printfParms[3], printfParms[4],
423 printfParms[5], printfParms[6], printfParms[7],
424 printfParms[8], printfParms[9], printfParms[10],
425 printfParms[11], printfParms[12], printfParms[13],
426 printfParms[14], printfParms[15]);
427 fprintf(outFilep, "\n");
430 #endif /* AFS_SGI61_ENV */
432 fprintf(outFilep, "Type mismatch, using raw print.\n");
433 fprintf(outFilep, "%s", msgBuffer);
437 if (alp[1] == ICL_INFO_TIMESTAMP) {
439 fprintf(outFilep, "time %d.%06d, pid %u: %s\n", alp[3] / 1000000,
440 alp[3] % 1000000, alp[2], ctime(&tmv));
442 fprintf(outFilep, "raw op %d, time %d.%06d, pid %u\n", alp[1],
443 alp[3] / 1000000, alp[3] % 1000000, alp[2]);
444 /* now decode each parameter and print it */
447 for (i = 0; !done && i < 4; i++) {
448 type = (temp >> (18 - i * 6)) & 0x3f;
454 fprintf(outFilep, "p%d:%d ", i, alp[pix]);
458 tempParam = alp[pix];
460 tempParam |= alp[pix + 1];
461 fprintf(outFilep, "p%d:%" AFS_INT64_FMT " ", i, tempParam);
462 #else /* AFS_SGI61_ENV */
463 fprintf(outFilep, "p%d:%d ", i, alp[pix]);
464 #endif /* AFS_SGI61_ENV */
466 case ICL_TYPE_POINTER:
468 tempParam = alp[pix];
470 tempParam |= alp[pix + 1];
471 fprintf(outFilep, "p%d:0x%llx ", i, tempParam);
472 #else /* AFS_SGI61_ENV */
473 fprintf(outFilep, "p%d:0x%x ", i, alp[pix]);
474 #endif /* AFS_SGI61_ENV */
478 fprintf(outFilep, "p%d:%x.%x ", i, alp[pix],
482 fprintf(outFilep, "p%d:%d.%d.%d.%d ", i, alp[pix],
483 alp[pix + 1], alp[pix + 2], alp[pix + 3]);
485 case ICL_TYPE_STRING:
486 fprintf(outFilep, "p%d:%s ", i, (char *)&alp[pix]);
488 case ICL_TYPE_UNIXDATE:
490 fprintf(outFilep, "p%d:%s ", i,
495 ("DisplayRecord: Bad type %d in raw print switch.\n",
503 pix += icl_GetSize(type, (char *)&alp[pix]);
506 fprintf(outFilep, "\n"); /* done with line */
516 #include <nl_types.h>
518 #define FACILITY_CODE_MASK 0xF0000000
519 #define FACILITY_CODE_SHIFT 28
521 #define COMPONENT_CODE_MASK 0x0FFFF000
522 #define COMPONENT_CODE_SHIFT 12
524 #define STATUS_CODE_MASK 0x00000FFF
525 #define STATUS_CODE_SHIFT 0
527 #define NO_MESSAGE "THIS IS NOT A MESSAGE"
530 * We use NLS message catalog functions to convert numbers to human-readable
531 * strings. The message catalog will be in AFSDIR_DATA_DIR, which is
532 * ${datadir}/openafs with normal paths and /usr/vice/etc (for historical
533 * compatibility) for Transarc paths.
537 dce1_error_inq_text(afs_uint32 status_to_convert,
538 char *error_text, int *status)
540 unsigned short facility_code;
541 unsigned short component_code;
542 unsigned short status_code;
545 char component_name[4];
547 char filename_prefix[7];
548 char nls_filename[80];
550 static char *facility_names[] = {
556 * set up output status for future error returns
558 if (status != NULL) {
562 * check for ok input status
564 if (status_to_convert == 0) {
565 if (status != NULL) {
568 strcpy((char *)error_text, "successful completion");
573 * extract the component, facility and status codes
576 (status_to_convert & FACILITY_CODE_MASK) >> FACILITY_CODE_SHIFT;
578 (status_to_convert & COMPONENT_CODE_MASK) >> COMPONENT_CODE_SHIFT;
579 status_code = (status_to_convert & STATUS_CODE_MASK) >> STATUS_CODE_SHIFT;
582 * see if this is a recognized facility
584 if (facility_code == 0
585 || facility_code > sizeof(facility_names) / sizeof(char *)) {
586 sprintf((char *)error_text, "status %08x (unknown facility)",
590 facility_name = facility_names[facility_code - 1];
592 * Convert component name from RAD-50 component code. (Mapping is:
593 * 0 => 'a', ..., 25 => 'z', 26 => '{', 27 => '0', ..., 36 => '9'.)
595 component_name[3] = 0;
596 component_name[2] = component_code % 40;
597 component_code /= 40;
598 component_name[1] = component_code % 40;
599 component_name[0] = component_code / 40;
600 for (i = 0; i < 3; i++) {
601 component_name[i] += (component_name[i] <= 26) ? 'a' : ('0' - 27);
603 sprintf(filename_prefix, "%3s%3s", facility_name, component_name);
606 * We do not use the normal NLS message catalog search path since our use
607 * message catalogs isn't a typical use. It wouldn't make sense to
608 * install this special message catalog in with internationalization
611 snprintf(nls_filename, sizeof(nls_filename), "%s/C/%s.cat",
612 AFSDIR_CLIENT_DATA_DIRPATH, filename_prefix);
614 catd = catopen(nls_filename, 0);
615 if (catd == (nl_catd) -1) {
616 sprintf((char *)error_text, "status %08x (%s / %s)",
617 status_to_convert, facility_name, component_name);
621 * try to get the specified message from the file
623 message = (char *)catgets(catd, 1, status_code, NO_MESSAGE);
625 * if everything went well, return the resulting message
627 if (strcmp(message, NO_MESSAGE) != 0) {
628 sprintf((char *)error_text, "%s (%s / %s)", message, facility_name,
630 if (status != NULL) {
634 sprintf((char *)error_text, "status %08x (%s / %s)",
635 status_to_convert, facility_name, component_name);
641 icl_DumpKernel(FILE *outFilep, char *setname)
643 afs_int32 bufferSize = 0;
646 afs_int32 code, retVal = 0;
651 afs_int32 dummy, dummy2;
654 /* first, enumerate the logs we're interested in */
657 /* dump logs for a particular set */
658 for (i = 0; i < ICL_LOGSPERSET; i++) {
660 afs_syscall(AFSCALL_ICL, ICL_OP_ENUMLOGSBYSET, (long)setname,
661 i, (long)tname, sizeof(tname), 0, 0);
663 if (errno == EBADF) {
665 continue; /* missing slot, nothing to worry about */
670 afs_syscall(AFSCALL_ICL, ICL_OP_GETLOGINFO, (long)tname,
671 (long)&dummy, (long)&dummy2, 0, 0, 0);
675 if (dummy > bufferSize) /* find biggest log */
677 lip = (struct logInfo *)malloc(sizeof(struct logInfo));
678 memset(lip, 0, sizeof(*lip));
679 lip->nextp = allInfo;
681 lip->name = (char *)malloc(strlen(tname) + 1);
682 strcpy(lip->name, tname);
687 for (i = 0; i < 1000; i++) {
689 afs_syscall(AFSCALL_ICL, ICL_OP_ENUMLOGS, i, (long)tname,
690 sizeof(tname), (long)&dummy, 0, 0);
693 if (dummy > bufferSize) /* find biggest log */
695 lip = (struct logInfo *)malloc(sizeof(struct logInfo));
696 memset(lip, 0, sizeof(*lip));
697 lip->nextp = allInfo;
699 lip->name = (char *)malloc(strlen(tname) + 1);
700 strcpy(lip->name, tname);
706 bufferp = (afs_int32 *) malloc(sizeof(afs_int32) * bufferSize);
710 fprintf(outFilep, "Found %d logs.\n", i);
712 /* now print out the contents of each log */
713 for (lip = allInfo; lip; lip = lip->nextp) {
714 fprintf(outFilep, "\nContents of log %s:\n", lip->name);
715 /* read out everything first; gets a more consistent
718 nwords = 0; /* total words copied out */
720 /* display all the entries in the log */
721 if (bufferSize - nwords <= 0)
722 break; /* filled whole buffer */
724 afs_syscall(AFSCALL_ICL, ICL_OP_COPYOUT, (long)lip->name,
725 (long)(bufferp + nwords), bufferSize - nwords,
728 /* otherwise we've got an error */
729 fprintf(outFilep, "Returned error %d dumping log.\n", errno);
732 /* otherwise, we have flags in the high order byte, and
733 * a length (in words) in the remainder.
735 if ((code >> 24) & ICL_COPYOUTF_MISSEDSOME)
736 fprintf(outFilep, "Log wrapped; data missing.\n");
744 } /* for loop over all cookies */
746 /* otherwise we should display all of the log entries here.
747 * Note that a record may end in the middle, in which case
748 * we should start over with the cookie value of the start
751 for (ix = 0; ix < nwords;) {
752 /* start of a record */
753 rlength = (bufferp[ix] >> 24) & 0xff;
755 fprintf(outFilep, "Internal error: 0 length record\n");
759 /* ensure that entire record fits */
760 if (ix + rlength > nwords) {
761 /* doesn't fit, adjust cookie and break */
764 /* print the record */
765 DisplayRecord(outFilep, &bufferp[ix], rlength);
768 /* obsolete: read entire buffer first */
769 i += rlength; /* update cookie value, too */
771 } /* for loop displaying buffer */
772 } /* for loop over all logs */
779 /* clear out log 'name' */
781 icl_ClearLog(char *name)
785 code = afs_syscall(AFSCALL_ICL, ICL_OP_CLRLOG, (long)name, 0, 0, 0, 0, 0);
789 /* clear out set 'name' */
791 icl_ClearSet(char *name)
795 code = afs_syscall(AFSCALL_ICL, ICL_OP_CLRSET, (long)name, 0, 0, 0, 0, 0);
799 /* clear out all logs */
805 code = afs_syscall(AFSCALL_ICL, ICL_OP_CLRALL, 0, 0, 0, 0, 0, 0);
809 /* list out all available sets to outFileP */
811 icl_ListSets(FILE *outFileP)
818 for (i = 0; i < 1000; i++) {
820 afs_syscall(AFSCALL_ICL, ICL_OP_ENUMSETS, i, (long)tname,
821 sizeof(tname), (long)&states, 0, 0);
824 (void)fprintf(outFileP, "%s %s%s%s\n", tname,
825 (states & ICL_SETF_ACTIVE) ? "active" : "inactive",
826 (states & ICL_SETF_FREED) ? " (dormant)" : "",
827 (states & ICL_SETF_PERSISTENT) ? " persistent" : "");
833 /* list out all available logs to outFileP */
835 icl_ListLogs(FILE *outFileP, int int32flg)
843 for (i = 0; i < 1000; i++) {
845 afs_syscall(AFSCALL_ICL, ICL_OP_ENUMLOGS, i, (long)tname,
846 sizeof(tname), (long)&logSize, 0, 0);
850 /* get more information on the log */
852 afs_syscall(AFSCALL_ICL, ICL_OP_GETLOGINFO, (long)tname,
853 (long)&logSize, (long)&allocated, 0, 0, 0);
856 (void)fprintf(outFileP, "%s : %d kbytes (%s)\n", tname,
858 allocated ? "allocated" : "unallocated");
860 (void)fprintf(outFileP, "%s\n", tname);
866 /* list out all available logs to outFileP */
868 icl_ListLogsBySet(FILE *outFileP, char *setname, int int32flg)
876 for (i = 0; i < ICL_LOGSPERSET; i++) {
878 afs_syscall(AFSCALL_ICL, ICL_OP_ENUMLOGSBYSET, (long)setname, i,
879 (long)tname, sizeof(tname), 0, 0);
881 if (errno == EBADF) {
883 continue; /* missing */
888 /* get more information on the log */
890 afs_syscall(AFSCALL_ICL, ICL_OP_GETLOGINFO, (long)tname,
891 (long)&logSize, (long)&allocated, 0, 0, 0);
894 (void)fprintf(outFileP, "%s : %d kbytes (%s)\n", tname,
896 allocated ? "allocated" : "unallocated");
898 (void)fprintf(outFileP, "%s\n", tname);
904 /* activate/deactivate/free specified set */
906 icl_ChangeSetState(char *name, afs_int32 op)
910 code = afs_syscall(AFSCALL_ICL, ICL_OP_SETSTAT, (long)name, op, 0, 0, 0, 0);
914 /* activate/deactivate/free all sets */
916 icl_ChangeAllSetState(afs_int32 op)
920 code = afs_syscall(AFSCALL_ICL, ICL_OP_SETSTATALL, op, 0, 0, 0, 0, 0);
924 /* set size if log */
926 icl_ChangeLogSize(char *name, afs_int32 logSize)
931 afs_syscall(AFSCALL_ICL, ICL_OP_SETLOGSIZE, (long)name, logSize, 0,
936 /* get logsize of specified log */
938 icl_GetLogsize(char *logname, afs_int32 *logSizeP, int *allocatedP)
942 afs_syscall(AFSCALL_ICL, ICL_OP_GETLOGINFO, (long)logname,
943 (long)logSizeP, (long)allocatedP, 0, 0, 0);
947 /* get state of specified set */
949 icl_GetSetState(char *setname, afs_int32 *stateP)
953 afs_syscall(AFSCALL_ICL, ICL_OP_GETSETINFO, (long)setname,
954 (long)stateP, 0, 0, 0, 0);
959 icl_TailKernel(FILE *outFilep, char *logname, afs_int32 waitTime)
961 afs_int32 bufferSize = 0;
962 afs_int32 newBufferSize;
965 afs_int32 code, retVal = 0;
971 /* get information about the specified log */
973 afs_syscall(AFSCALL_ICL, ICL_OP_GETLOGINFO, (long)logname,
974 (long)&bufferSize, (long)&allocated, 0, 0, 0);
977 (void)fprintf(stderr, "'%s' not found\n", logname);
979 (void)fprintf(stderr,
980 "cannot get information on log '%s' (errno = %d)\n",
986 (void)fprintf(stderr, "'%s' not allocated\n", logname);
992 bufferp = (afs_int32 *) malloc(sizeof(afs_int32) * bufferSize);
994 (void)fprintf(stderr, "cannot allocate %d words for buffer\n",
999 /* start "infinite" loop */
1001 /* read out all that's currently there */
1002 nwords = 0; /* total words copied out */
1003 i = 0; /* initialize cookie */
1005 /* display all the entries in the log */
1006 if (bufferSize - nwords <= 0)
1007 break; /* filled whole buffer, clear when done */
1009 afs_syscall(AFSCALL_ICL, ICL_OP_COPYOUTCLR, (long)logname,
1010 (long)(bufferp + nwords), bufferSize - nwords,
1013 /* otherwise we've got an error */
1014 fprintf(stderr, "returned error %d dumping log.\n", errno);
1018 /* otherwise, we have flags in the high order byte, and
1019 * a length (in words) in the remainder.
1028 } /* for loop over all cookies */
1030 /* otherwise we should display all of the log entries here.
1031 * Note that a record may end in the middle, in which case
1032 * we should start over with the cookie value of the start
1035 for (ix = 0; ix < nwords;) {
1036 /* start of a record */
1037 rlength = (bufferp[ix] >> 24) & 0xff;
1038 /* ensure that entire record fits */
1039 if (ix + rlength > nwords) {
1040 /* doesn't fit, adjust cookie and break */
1042 fprintf(stderr, "BOGUS: 0 length record\n");
1048 /* print the record */
1049 DisplayRecord(outFilep, &bufferp[ix], rlength);
1051 } /* for loop displaying buffer */
1056 /* see if things have changed */
1058 afs_syscall(AFSCALL_ICL, ICL_OP_GETLOGINFO, (long)logname,
1059 (long)&newBufferSize, (long)&allocated, 0, 0, 0);
1061 if (errno == ENOENT)
1062 (void)fprintf(stderr, "'%s' not found\n", logname);
1064 (void)fprintf(stderr,
1065 "cannot get information on log '%s' (errno = %d)\n",
1072 (void)fprintf(stderr, "'%s' no int32er allocated\n", logname);
1077 if (bufferSize == 0) {
1078 (void)fprintf(stderr, "buffer size has become 0\n");
1082 if (bufferSize != newBufferSize) {
1083 /* have to reallocate a buffer */
1084 bufferSize = newBufferSize;
1086 bufferp = (afs_int32 *) malloc(sizeof(afs_int32) * bufferSize);
1088 (void)fprintf(stderr, "cannot allocate %d words for buffer\n",
1094 } /* infinite loop */
1101 #if !defined(AFS_SGI_ENV)
1103 afs_syscall(long call, long parm0, long parm1, long parm2, long parm3,
1104 long parm4, long parm5, long parm6)
1107 #ifdef AFS_LINUX20_ENV
1108 #if defined AFS_LINUX_64BIT_KERNEL
1110 /* don't want to sign extend it to 64bit, so using ulong */
1111 eparm[0] = (unsigned long)parm3;
1112 eparm[1] = (unsigned long)parm4;
1113 eparm[2] = (unsigned long)parm5;
1114 eparm[3] = (unsigned long)parm6;
1122 /* Linux can only handle 5 arguments in the actual syscall. */
1123 if (call == AFSCALL_ICL) {
1124 rval = proc_afs_syscall(call, parm0, parm1, parm2, (long)eparm, &code);
1126 code = syscall(AFS_SYSCALL, call, parm0, parm1, parm2, eparm);
1128 rval = proc_afs_syscall(call, parm0, parm1, parm2, parm3, &code);
1130 code = syscall(AFS_SYSCALL, call, parm0, parm1, parm2, parm3);
1132 #if defined(AFS_SPARC64_LINUX20_ENV) || defined(AFS_SPARC_LINUX20_ENV)
1133 /* on sparc this function returns none value, so do it myself */
1134 __asm__ __volatile__("mov %o0, %i0; ret; restore");
1137 #ifdef AFS_DARWIN80_ENV
1138 code = ioctl_afs_syscall(call, parm0, parm1, parm2, parm3, parm4, parm5, &rval);
1139 if (!code) code = rval;
1141 #if !defined(AFS_SGI_ENV) && !defined(AFS_AIX32_ENV)
1142 code = syscall(AFS_SYSCALL, call, parm0, parm1, parm2, parm3, parm4);
1144 #if defined(AFS_SGI_ENV)
1145 code = syscall(AFS_ICL, call, parm0, parm1, parm2, parm3, parm4); /* XXX */
1147 code = syscall(AFSCALL_ICL, parm0, parm1, parm2, parm3, parm4);
1151 #endif /* AFS_LINUX20_ENV */
1159 /* init function, called once, under icl_lock */
1166 /* setup signal handler, in user space */
1173 icl_CreateSet(char *name, struct afs_icl_log *baseLogp,
1174 struct afs_icl_log *fatalLogp, struct afs_icl_set **outSetpp)
1176 return icl_CreateSetWithFlags(name, baseLogp, fatalLogp, /*flags */ 0,
1180 /* create a set, given pointers to base and fatal logs, if any.
1181 * Logs are unlocked, but referenced, and *outSetpp is returned
1182 * referenced. Function bumps reference count on logs, since it
1183 * addds references from the new icl_set. When the set is destroyed,
1184 * those references will be released.
1187 icl_CreateSetWithFlags(char *name, struct afs_icl_log *baseLogp,
1188 struct afs_icl_log *fatalLogp, afs_uint32 flags,
1189 struct afs_icl_set **outSetpp)
1191 struct afs_icl_set *setp;
1193 afs_int32 states = ICL_DEFAULT_SET_STATES;
1198 for (setp = icl_allSets; setp; setp = setp->nextp) {
1199 if (strcmp(setp->name, name) == 0) {
1202 if (flags & ICL_CRSET_FLAG_PERSISTENT) {
1203 setp->states |= ICL_SETF_PERSISTENT;
1209 /* determine initial state */
1210 if (flags & ICL_CRSET_FLAG_DEFAULT_ON)
1211 states = ICL_SETF_ACTIVE;
1212 else if (flags & ICL_CRSET_FLAG_DEFAULT_OFF)
1213 states = ICL_SETF_FREED;
1214 if (flags & ICL_CRSET_FLAG_PERSISTENT)
1215 states |= ICL_SETF_PERSISTENT;
1217 setp = (struct afs_icl_set *)osi_Alloc(sizeof(struct afs_icl_set));
1218 memset((caddr_t) setp, 0, sizeof(*setp));
1220 if (states & ICL_SETF_FREED)
1221 states &= ~ICL_SETF_ACTIVE; /* if freed, can't be active */
1222 setp->states = states;
1224 setp->name = (char *)osi_Alloc(strlen(name) + 1);
1225 strcpy(setp->name, name);
1226 setp->nevents = ICL_DEFAULTEVENTS;
1227 setp->eventFlags = (char *)osi_Alloc(ICL_DEFAULTEVENTS);
1228 for (i = 0; i < ICL_DEFAULTEVENTS; i++)
1229 setp->eventFlags[i] = 0xff; /* default to enabled */
1231 /* update this global info under the icl_lock */
1232 setp->nextp = icl_allSets;
1235 /* set's basic lock is still held, so we can finish init */
1237 setp->logs[0] = baseLogp;
1238 icl_LogHold(baseLogp);
1239 if (!(setp->states & ICL_SETF_FREED))
1240 icl_LogUse(baseLogp); /* log is actually being used */
1243 setp->logs[1] = fatalLogp;
1244 icl_LogHold(fatalLogp);
1245 if (!(setp->states & ICL_SETF_FREED))
1246 icl_LogUse(fatalLogp); /* log is actually being used */
1253 /* function to change event enabling information for a particular set */
1255 icl_SetEnable(struct afs_icl_set *setp, afs_int32 eventID, int setValue)
1259 if (!ICL_EVENTOK(setp, eventID)) {
1262 tp = &setp->eventFlags[ICL_EVENTBYTE(eventID)];
1264 *tp |= ICL_EVENTMASK(eventID);
1266 *tp &= ~(ICL_EVENTMASK(eventID));
1270 /* return indication of whether a particular event ID is enabled
1271 * for tracing. If *getValuep is set to 0, the event is disabled,
1272 * otherwise it is enabled. All events start out enabled by default.
1275 icl_GetEnable(struct afs_icl_set *setp, afs_int32 eventID, int *getValuep)
1277 if (!ICL_EVENTOK(setp, eventID)) {
1280 if (setp->eventFlags[ICL_EVENTBYTE(eventID)] & ICL_EVENTMASK(eventID))
1287 /* hold and release event sets */
1289 icl_SetHold(struct afs_icl_set *setp)
1295 /* free a set. Called with icl_lock locked */
1297 icl_ZapSet(struct afs_icl_set *setp)
1299 struct afs_icl_set **lpp, *tp;
1301 struct afs_icl_log *tlp;
1303 for (lpp = &icl_allSets, tp = *lpp; tp; lpp = &tp->nextp, tp = *lpp) {
1305 /* found the dude we want to remove */
1307 osi_Free(setp->name, 1 + strlen(setp->name));
1308 osi_Free(setp->eventFlags, ICL_EVENTBYTES(setp->nevents));
1309 for (i = 0; i < ICL_LOGSPERSET; i++) {
1310 if ((tlp = setp->logs[i]))
1313 osi_Free(setp, sizeof(struct afs_icl_set));
1314 break; /* won't find it twice */
1320 /* do the release, watching for deleted entries */
1322 icl_SetRele(struct afs_icl_set *setp)
1324 if (--setp->refCount == 0 && (setp->states & ICL_SETF_DELETED)) {
1325 icl_ZapSet(setp); /* destroys setp's lock! */
1330 /* free a set entry, dropping its reference count */
1332 icl_SetFree(struct afs_icl_set *setp)
1334 setp->states |= ICL_SETF_DELETED;
1339 /* find a set by name, returning it held */
1340 struct afs_icl_set *
1341 icl_FindSet(char *name)
1343 struct afs_icl_set *tp;
1345 for (tp = icl_allSets; tp; tp = tp->nextp) {
1346 if (strcmp(tp->name, name) == 0) {
1347 /* this is the dude we want */
1355 /* zero out all the logs in the set */
1357 icl_ZeroSet(struct afs_icl_set *setp)
1362 struct afs_icl_log *logp;
1364 for (i = 0; i < ICL_LOGSPERSET; i++) {
1365 logp = setp->logs[i];
1368 tcode = icl_ZeroLog(logp);
1370 code = tcode; /* save the last bad one */
1378 icl_EnumerateSets(int (*aproc) (char *, void *, struct afs_icl_set *),
1381 struct afs_icl_set *tp, *np;
1385 for (tp = icl_allSets; tp; tp = np) {
1386 tp->refCount++; /* hold this guy */
1387 code = (*aproc) (tp->name, arock, tp);
1388 np = tp->nextp; /* tp may disappear next, but not np */
1389 if (--tp->refCount == 0 && (tp->states & ICL_SETF_DELETED))
1398 icl_AddLogToSet(struct afs_icl_set *setp, struct afs_icl_log *newlogp)
1403 for (i = 0; i < ICL_LOGSPERSET; i++) {
1404 if (!setp->logs[i]) {
1405 setp->logs[i] = newlogp;
1407 icl_LogHold(newlogp);
1408 if (!(setp->states & ICL_SETF_FREED)) {
1409 /* bump up the number of sets using the log */
1410 icl_LogUse(newlogp);
1419 icl_SetSetStat(struct afs_icl_set *setp, int op)
1423 struct afs_icl_log *logp;
1426 case ICL_OP_SS_ACTIVATE: /* activate a log */
1428 * If we are not already active, see if we have released
1429 * our demand that the log be allocated (FREED set). If
1430 * we have, reassert our desire.
1432 if (!(setp->states & ICL_SETF_ACTIVE)) {
1433 if (setp->states & ICL_SETF_FREED) {
1434 /* have to reassert desire for logs */
1435 for (i = 0; i < ICL_LOGSPERSET; i++) {
1436 logp = setp->logs[i];
1443 setp->states &= ~ICL_SETF_FREED;
1445 setp->states |= ICL_SETF_ACTIVE;
1450 case ICL_OP_SS_DEACTIVATE: /* deactivate a log */
1451 /* this doesn't require anything beyond clearing the ACTIVE flag */
1452 setp->states &= ~ICL_SETF_ACTIVE;
1456 case ICL_OP_SS_FREE: /* deassert design for log */
1458 * if we are already in this state, do nothing; otherwise
1459 * deassert desire for log
1461 if (setp->states & ICL_SETF_ACTIVE)
1464 if (!(setp->states & ICL_SETF_FREED)) {
1465 for (i = 0; i < ICL_LOGSPERSET; i++) {
1466 logp = setp->logs[i];
1469 icl_LogFreeUse(logp);
1473 setp->states |= ICL_SETF_FREED;
1486 struct afs_icl_log *afs_icl_allLogs = 0;
1488 /* hold and release logs */
1490 icl_LogHold(struct afs_icl_log *logp)
1496 /* hold and release logs, called with lock already held */
1498 icl_LogHoldNL(struct afs_icl_log *logp)
1504 /* keep track of how many sets believe the log itself is allocated */
1506 icl_LogUse(struct afs_icl_log *logp)
1508 if (logp->setCount == 0) {
1509 /* this is the first set actually using the log -- allocate it */
1510 if (logp->logSize == 0) {
1511 /* we weren't passed in a hint and it wasn't set */
1512 logp->logSize = ICL_DEFAULT_LOGSIZE;
1515 (afs_int32 *) osi_Alloc(sizeof(afs_int32) * logp->logSize);
1521 /* decrement the number of real users of the log, free if possible */
1523 icl_LogFreeUse(struct afs_icl_log *logp)
1525 if (--logp->setCount == 0) {
1526 /* no more users -- free it (but keep log structure around) */
1527 osi_Free(logp->datap, sizeof(afs_int32) * logp->logSize);
1528 logp->firstUsed = logp->firstFree = 0;
1529 logp->logElements = 0;
1535 /* set the size of the log to 'logSize' */
1537 icl_LogSetSize(struct afs_icl_log *logp, afs_int32 logSize)
1540 /* nothing to worry about since it's not allocated */
1541 logp->logSize = logSize;
1544 logp->firstUsed = logp->firstFree = 0;
1545 logp->logElements = 0;
1547 /* free and allocate a new one */
1548 osi_Free(logp->datap, sizeof(afs_int32) * logp->logSize);
1549 logp->datap = (afs_int32 *) osi_Alloc(sizeof(afs_int32) * logSize);
1550 logp->logSize = logSize;
1556 /* free a log. Called with icl_lock locked. */
1558 icl_ZapLog(struct afs_icl_log *logp)
1560 struct afs_icl_log **lpp, *tp;
1562 for (lpp = &afs_icl_allLogs, tp = *lpp; tp; lpp = &tp->nextp, tp = *lpp) {
1564 /* found the dude we want to remove */
1566 osi_Free(logp->name, 1 + strlen(logp->name));
1567 osi_Free(logp->datap, logp->logSize * sizeof(afs_int32));
1568 osi_Free(logp, sizeof(struct icl_log));
1569 break; /* won't find it twice */
1575 /* do the release, watching for deleted entries */
1577 icl_LogRele(struct afs_icl_log *logp)
1579 if (--logp->refCount == 0 && (logp->states & ICL_LOGF_DELETED)) {
1580 icl_ZapLog(logp); /* destroys logp's lock! */
1585 /* do the release, watching for deleted entries, log already held */
1587 icl_LogReleNL(struct afs_icl_log *logp)
1589 if (--logp->refCount == 0 && (logp->states & ICL_LOGF_DELETED)) {
1590 icl_ZapLog(logp); /* destroys logp's lock! */
1595 /* zero out the log */
1597 icl_ZeroLog(struct afs_icl_log *logp)
1599 logp->firstUsed = logp->firstFree = 0;
1600 logp->logElements = 0;
1604 /* free a log entry, and drop its reference count */
1606 icl_LogFree(struct afs_icl_log *logp)
1608 logp->states |= ICL_LOGF_DELETED;
1615 icl_EnumerateLogs(int (*aproc)
1616 (char *name, void *arock, struct afs_icl_log * tp),
1619 struct afs_icl_log *tp;
1623 for (tp = afs_icl_allLogs; tp; tp = tp->nextp) {
1624 tp->refCount++; /* hold this guy */
1625 code = (*aproc) (tp->name, arock, tp);
1626 if (--tp->refCount == 0)
1635 afs_icl_bulkSetinfo_t *
1636 GetBulkSetInfo(void)
1638 unsigned int infoSize;
1641 sizeof(afs_icl_bulkSetinfo_t) + (ICL_RPC_MAX_SETS -
1642 1) * sizeof(afs_icl_setinfo_t);
1644 setInfo = (afs_icl_bulkSetinfo_t *) malloc(infoSize);
1646 (void)fprintf(stderr,
1647 "Could not allocate the memory for bulk set info structure\n");
1651 memset(setInfo, 0, infoSize);
1656 afs_icl_bulkLoginfo_t *
1657 GetBulkLogInfo(void)
1659 unsigned int infoSize;
1662 sizeof(afs_icl_bulkLoginfo_t) + (ICL_RPC_MAX_LOGS -
1663 1) * sizeof(afs_icl_loginfo_t);
1665 logInfo = (afs_icl_bulkLoginfo_t *) malloc(infoSize);
1667 (void)fprintf(stderr,
1668 "Could not allocate the memory for bulk log info structure\n");
1673 memset(logInfo, 0, infoSize);
1679 DoDump(struct cmd_syndesc *as, void *arock)
1683 afs_int32 waitTime = 10 /* seconds */ ;
1685 FILE *outfp = stdout;
1687 struct cmd_item *itemp;
1689 if (geteuid() != 0) {
1690 printf("fstrace must be run as root\n");
1694 if (as->parms[3].items) {
1695 if (!as->parms[1].items) {
1696 (void)fprintf(stderr, "-sleep can only be used with -follow\n");
1699 waitTime = strtol(as->parms[3].items->data, NULL, 0);
1702 if (as->parms[2].items) {
1703 /* try to open the specified output file */
1704 if ((outfp = fopen(as->parms[2].items->data, "w")) == NULL) {
1705 (void)fprintf(stderr, "Cannot open file '%s' for writing\n",
1706 as->parms[2].items->data);
1710 #ifdef AFS_SGI64_ENV
1711 startTime = time((time_t *) 0);
1713 startTime = time(0);
1715 (void)fprintf(outfp, "AFS Trace Dump -\n\n Date: %s\n",
1718 if (as->parms[0].items) {
1719 for (itemp = as->parms[0].items; itemp; itemp = itemp->next) {
1720 tcode = icl_DumpKernel(outfp, itemp->data);
1722 (void)fprintf(stderr, "Unable to dump set %s (errno = %d)\n",
1723 itemp->data, errno);
1727 } else if (as->parms[1].items) {
1728 logname = as->parms[1].items->data;
1729 code = icl_TailKernel(outfp, logname, waitTime);
1731 (void)fprintf(stderr,
1732 "Error tailing kernel log '%s' (errno = %d)\n",
1736 code = icl_DumpKernel(outfp, NULL);
1738 (void)fprintf(outfp, "\nAFS Trace Dump - %s\n",
1739 code ? "FAILED" : "Completed");
1741 if (outfp != stdout)
1742 (void)fclose(outfp);
1750 struct cmd_syndesc *dumpSyntax;
1753 cmd_CreateSyntax("dump", DoDump, NULL, "dump AFS trace logs");
1754 (void)cmd_AddParm(dumpSyntax, "-set", CMD_LIST, CMD_OPTIONAL,
1756 (void)cmd_AddParm(dumpSyntax, "-follow", CMD_SINGLE, CMD_OPTIONAL,
1758 (void)cmd_AddParm(dumpSyntax, "-file", CMD_SINGLE, CMD_OPTIONAL,
1759 "path to trace log file for writing");
1760 (void)cmd_AddParm(dumpSyntax, "-sleep", CMD_SINGLE, CMD_OPTIONAL,
1761 "interval (secs) for writes when using -follow");
1766 DoShowLog(struct cmd_syndesc *as, void *arock)
1768 afs_int32 retVal = 0;
1773 struct cmd_item *itemp;
1775 if (geteuid() != 0) {
1776 printf("fstrace must be run as root\n");
1779 if (as->parms[2].items)
1782 if (as->parms[0].items) {
1783 /* enumerate logs for the specified sets */
1784 for (itemp = as->parms[0].items; itemp; itemp = itemp->next) {
1785 (void)fprintf(stdout, "Logs for set '%s':\n", itemp->data);
1786 code = icl_ListLogsBySet(stdout, itemp->data, int32flg);
1788 (void)fprintf(stderr,
1789 "Error in enumerating set %s (errno = %d)\n",
1790 itemp->data, errno);
1794 } else if (as->parms[1].items) {
1795 /* print out log information */
1796 for (itemp = as->parms[1].items; itemp; itemp = itemp->next) {
1797 code = icl_GetLogsize(itemp->data, &logSize, &allocated);
1799 (void)fprintf(stdout, "%s : %d kbytes (%s)\n", itemp->data,
1801 allocated ? "allocated" : "unallocated");
1803 (void)fprintf(stderr,
1804 "Could not find log '%s' (errno = %d)\n",
1805 itemp->data, errno);
1811 (void)fprintf(stdout, "Available logs:\n");
1812 code = icl_ListLogs(stdout, int32flg);
1814 (void)fprintf(stderr, "Error in listing logs (errno = %d)\n",
1826 struct cmd_syndesc *showSyntax;
1829 cmd_CreateSyntax("lslog", DoShowLog, NULL,
1830 "list available logs");
1831 (void)cmd_AddParm(showSyntax, "-set", CMD_LIST, CMD_OPTIONAL,
1833 (void)cmd_AddParm(showSyntax, "-log", CMD_LIST, CMD_OPTIONAL,
1835 (void)cmd_AddParm(showSyntax, "-long", CMD_FLAG, CMD_OPTIONAL,
1836 "show defined log size in kbytes & if it is allocated in kernel mem");
1840 DoShowSet(struct cmd_syndesc *as, void *arock)
1842 afs_int32 retVal = 0;
1845 struct cmd_item *itemp;
1847 if (geteuid() != 0) {
1848 printf("fstrace must be run as root\n");
1851 if (as->parms[0].items) {
1852 /* print information on the specified sets */
1853 for (itemp = as->parms[0].items; itemp; itemp = itemp->next) {
1854 code = icl_GetSetState(itemp->data, &state);
1856 (void)fprintf(stderr,
1857 "Error getting status on set %s (errno = %d)\n",
1858 itemp->data, errno);
1861 (void)fprintf(stdout, "Set %s: %s%s%s\n", itemp->data,
1862 (state & ICL_SETF_ACTIVE) ? "active" :
1864 (state & ICL_SETF_FREED) ? " (dormant)" : "",
1865 (state & ICL_SETF_PERSISTENT) ? " persistent" :
1870 (void)fprintf(stdout, "Available sets:\n");
1871 code = icl_ListSets(stdout);
1873 (void)fprintf(stderr, "Error in listing sets (errno = %d)\n",
1885 struct cmd_syndesc *showSyntax;
1888 cmd_CreateSyntax("lsset", DoShowSet, NULL,
1889 "list available event sets");
1890 (void)cmd_AddParm(showSyntax, "-set", CMD_LIST, CMD_OPTIONAL,
1895 DoClear(struct cmd_syndesc *as, void *arock)
1897 afs_int32 retVal = 0;
1899 struct cmd_item *itemp;
1901 if (geteuid() != 0) {
1902 printf("fstrace must be run as root\n");
1905 if (as->parms[0].items) {
1906 /* clear logs for the specified sets */
1907 for (itemp = as->parms[0].items; itemp; itemp = itemp->next) {
1908 code = icl_ClearSet(itemp->data);
1910 (void)fprintf(stderr,
1911 "Error in clearing set %s (errno = %d)\n",
1912 itemp->data, errno);
1916 } else if (as->parms[1].items) {
1917 /* clear specified log */
1918 for (itemp = as->parms[0].items; itemp; itemp = itemp->next) {
1919 code = icl_ClearLog(itemp->data);
1921 (void)fprintf(stderr,
1922 "Error in clearing log %s (errno = %d)\n",
1923 itemp->data, errno);
1928 /* clear all logs */
1929 code = icl_ClearAll();
1931 (void)fprintf(stderr, "Error in clearing logs (errno = %d)\n",
1943 struct cmd_syndesc *clearSyntax;
1946 cmd_CreateSyntax("clear", DoClear, NULL,
1947 "clear logs by logname or by event set");
1948 (void)cmd_AddParm(clearSyntax, "-set", CMD_LIST, CMD_OPTIONAL,
1950 (void)cmd_AddParm(clearSyntax, "-log", CMD_LIST, CMD_OPTIONAL,
1955 DoSet(struct cmd_syndesc *as, void *arock)
1957 afs_int32 retVal = 0;
1962 struct cmd_item *itemp;
1964 if (geteuid() != 0) {
1965 printf("fstrace must be run as root\n");
1968 if (as->parms[1].items) {
1969 op = ICL_OP_SS_ACTIVATE;
1970 operation = "active";
1971 } else if (as->parms[2].items) {
1972 op = ICL_OP_SS_DEACTIVATE;
1973 operation = "inactive";
1974 } else if (as->parms[3].items) {
1975 op = ICL_OP_SS_DEACTIVATE;
1976 operation = "inactive";
1979 /* assume active" */
1980 op = ICL_OP_SS_ACTIVATE;
1981 operation = "active";
1984 if (as->parms[0].items) {
1985 /* activate specified sets */
1986 for (itemp = as->parms[0].items; itemp; itemp = itemp->next) {
1987 code = icl_ChangeSetState(itemp->data, op);
1989 (void)fprintf(stderr,
1990 "cannot set state of %s to %s (errno = %d)\n",
1991 itemp->data, operation, errno);
1993 } else if (doFree) {
1994 /* try to make it dormant as well */
1995 code = icl_ChangeSetState(itemp->data, ICL_OP_SS_FREE);
1997 (void)fprintf(stderr,
1998 "cannot set state of %s to dormant (errno = %d)\n",
1999 itemp->data, errno);
2006 code = icl_ChangeAllSetState(op);
2008 (void)fprintf(stderr,
2009 "cannot set the state of all sets to %s (errno = %d)\n",
2012 } else if (doFree) {
2013 /* try to make it dormant as well */
2014 code = icl_ChangeAllSetState(ICL_OP_SS_FREE);
2016 (void)fprintf(stderr,
2017 "cannot set the state of all sets to dormant (errno = %d)\n",
2030 struct cmd_syndesc *setSyntax;
2033 cmd_CreateSyntax("setset", DoSet, NULL,
2034 "set state of event sets");
2035 (void)cmd_AddParm(setSyntax, "-set", CMD_LIST, CMD_OPTIONAL,
2037 (void)cmd_AddParm(setSyntax, "-active", CMD_FLAG, CMD_OPTIONAL,
2038 "enable tracing for event set & allocate kernel memory");
2039 (void)cmd_AddParm(setSyntax, "-inactive", CMD_FLAG, CMD_OPTIONAL,
2040 "disables tracing for event set, keep kernel memory");
2041 (void)cmd_AddParm(setSyntax, "-dormant", CMD_FLAG, CMD_OPTIONAL,
2042 "disable tracing for event set & free kernel memory");
2046 DoResize(struct cmd_syndesc *as, void *arock)
2048 afs_int32 retVal = 0;
2050 afs_int32 bufferSize;
2051 struct cmd_item *itemp;
2053 if (geteuid() != 0) {
2054 printf("fstrace must be run as root\n");
2057 /* get buffer size */
2058 bufferSize = atoi(as->parms[1].items->data);
2059 bufferSize *= BUFFER_MULTIPLIER;
2060 if (bufferSize == 0)
2061 bufferSize = ICL_DEFAULT_LOGSIZE;
2063 /* set the size of the specified logs */
2064 if ((itemp = as->parms[0].items)) {
2065 for (; itemp; itemp = itemp->next) {
2066 code = icl_ChangeLogSize(itemp->data, bufferSize);
2068 (void)fprintf(stderr,
2069 "Error in changing log %s buffer size (errno = %d)\n",
2070 itemp->data, errno);
2075 /* Use the only current support log, "cmfx" */
2076 code = icl_ChangeLogSize("cmfx", bufferSize);
2078 (void)fprintf(stderr,
2079 "Error in changing log cmfx buffer size (errno = %d)\n",
2091 struct cmd_syndesc *setsizeSyntax;
2094 cmd_CreateSyntax("setlog", DoResize, NULL,
2095 "set the size of a log");
2096 (void)cmd_AddParm(setsizeSyntax, "-log", CMD_LIST, CMD_OPTIONAL,
2098 (void)cmd_AddParm(setsizeSyntax, "-buffersize", CMD_SINGLE, CMD_REQUIRED,
2099 "# of 1-kbyte blocks to allocate for log");
2102 #include "AFS_component_version_number.c"
2105 main(int argc, char *argv[])
2107 setlocale(LC_ALL, "");
2108 #ifdef AFS_SGI62_ENV
2109 set_kernel_sizeof_long();
2112 /* set up user interface then dispatch */
2120 return (cmd_Dispatch(argc, argv));