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.
160 if (tix
>= typeCount
)
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.
226 if (tix
>= typeCount
)
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
) {
664 continue; /* missing slot, nothing to worry about */
669 afs_syscall(AFSCALL_ICL
, ICL_OP_GETLOGINFO
, (long)tname
,
670 (long)&dummy
, (long)&dummy2
, 0, 0, 0);
674 if (dummy
> bufferSize
) /* find biggest log */
676 lip
= calloc(1, sizeof(struct logInfo
));
677 lip
->nextp
= allInfo
;
679 lip
->name
= strdup(tname
);
684 for (i
= 0; i
< 1000; i
++) {
686 afs_syscall(AFSCALL_ICL
, ICL_OP_ENUMLOGS
, i
, (long)tname
,
687 sizeof(tname
), (long)&dummy
, 0, 0);
690 if (dummy
> bufferSize
) /* find biggest log */
692 lip
= calloc(1, sizeof(struct logInfo
));
693 lip
->nextp
= allInfo
;
695 lip
->name
= strdup(tname
);
701 bufferp
= malloc(sizeof(afs_int32
) * bufferSize
);
705 fprintf(outFilep
, "Found %d logs.\n", i
);
707 /* now print out the contents of each log */
708 for (lip
= allInfo
; lip
; lip
= lip
->nextp
) {
709 fprintf(outFilep
, "\nContents of log %s:\n", lip
->name
);
710 /* read out everything first; gets a more consistent
713 nwords
= 0; /* total words copied out */
715 /* display all the entries in the log */
716 if (bufferSize
- nwords
<= 0)
717 break; /* filled whole buffer */
719 afs_syscall(AFSCALL_ICL
, ICL_OP_COPYOUT
, (long)lip
->name
,
720 (long)(bufferp
+ nwords
), bufferSize
- nwords
,
723 /* otherwise we've got an error */
724 fprintf(outFilep
, "Returned error %d dumping log.\n", errno
);
727 /* otherwise, we have flags in the high order byte, and
728 * a length (in words) in the remainder.
730 if ((code
>> 24) & ICL_COPYOUTF_MISSEDSOME
)
731 fprintf(outFilep
, "Log wrapped; data missing.\n");
739 } /* for loop over all cookies */
741 /* otherwise we should display all of the log entries here.
742 * Note that a record may end in the middle, in which case
743 * we should start over with the cookie value of the start
746 for (ix
= 0; ix
< nwords
;) {
747 /* start of a record */
748 rlength
= (bufferp
[ix
] >> 24) & 0xff;
750 fprintf(outFilep
, "Internal error: 0 length record\n");
754 /* ensure that entire record fits */
755 if (ix
+ rlength
> nwords
) {
756 /* doesn't fit, adjust cookie and break */
759 /* print the record */
760 DisplayRecord(outFilep
, &bufferp
[ix
], rlength
);
763 /* obsolete: read entire buffer first */
764 i
+= rlength
; /* update cookie value, too */
766 } /* for loop displaying buffer */
767 } /* for loop over all logs */
774 /* clear out log 'name' */
776 icl_ClearLog(char *name
)
780 code
= afs_syscall(AFSCALL_ICL
, ICL_OP_CLRLOG
, (long)name
, 0, 0, 0, 0, 0);
784 /* clear out set 'name' */
786 icl_ClearSet(char *name
)
790 code
= afs_syscall(AFSCALL_ICL
, ICL_OP_CLRSET
, (long)name
, 0, 0, 0, 0, 0);
794 /* clear out all logs */
800 code
= afs_syscall(AFSCALL_ICL
, ICL_OP_CLRALL
, 0, 0, 0, 0, 0, 0);
804 /* list out all available sets to outFileP */
806 icl_ListSets(FILE *outFileP
)
813 for (i
= 0; i
< 1000; i
++) {
815 afs_syscall(AFSCALL_ICL
, ICL_OP_ENUMSETS
, i
, (long)tname
,
816 sizeof(tname
), (long)&states
, 0, 0);
819 (void)fprintf(outFileP
, "%s %s%s%s\n", tname
,
820 (states
& ICL_SETF_ACTIVE
) ? "active" : "inactive",
821 (states
& ICL_SETF_FREED
) ? " (dormant)" : "",
822 (states
& ICL_SETF_PERSISTENT
) ? " persistent" : "");
828 /* list out all available logs to outFileP */
830 icl_ListLogs(FILE *outFileP
, int int32flg
)
838 for (i
= 0; i
< 1000; i
++) {
840 afs_syscall(AFSCALL_ICL
, ICL_OP_ENUMLOGS
, i
, (long)tname
,
841 sizeof(tname
), (long)&logSize
, 0, 0);
845 /* get more information on the log */
847 afs_syscall(AFSCALL_ICL
, ICL_OP_GETLOGINFO
, (long)tname
,
848 (long)&logSize
, (long)&allocated
, 0, 0, 0);
851 (void)fprintf(outFileP
, "%s : %d kbytes (%s)\n", tname
,
853 allocated
? "allocated" : "unallocated");
855 (void)fprintf(outFileP
, "%s\n", tname
);
861 /* list out all available logs to outFileP */
863 icl_ListLogsBySet(FILE *outFileP
, char *setname
, int int32flg
)
871 for (i
= 0; i
< ICL_LOGSPERSET
; i
++) {
873 afs_syscall(AFSCALL_ICL
, ICL_OP_ENUMLOGSBYSET
, (long)setname
, i
,
874 (long)tname
, sizeof(tname
), 0, 0);
876 if (errno
== EBADF
) {
878 continue; /* missing */
883 /* get more information on the log */
885 afs_syscall(AFSCALL_ICL
, ICL_OP_GETLOGINFO
, (long)tname
,
886 (long)&logSize
, (long)&allocated
, 0, 0, 0);
889 (void)fprintf(outFileP
, "%s : %d kbytes (%s)\n", tname
,
891 allocated
? "allocated" : "unallocated");
893 (void)fprintf(outFileP
, "%s\n", tname
);
899 /* activate/deactivate/free specified set */
901 icl_ChangeSetState(char *name
, afs_int32 op
)
905 code
= afs_syscall(AFSCALL_ICL
, ICL_OP_SETSTAT
, (long)name
, op
, 0, 0, 0, 0);
909 /* activate/deactivate/free all sets */
911 icl_ChangeAllSetState(afs_int32 op
)
915 code
= afs_syscall(AFSCALL_ICL
, ICL_OP_SETSTATALL
, op
, 0, 0, 0, 0, 0);
919 /* set size if log */
921 icl_ChangeLogSize(char *name
, afs_int32 logSize
)
926 afs_syscall(AFSCALL_ICL
, ICL_OP_SETLOGSIZE
, (long)name
, logSize
, 0,
931 /* get logsize of specified log */
933 icl_GetLogsize(char *logname
, afs_int32
*logSizeP
, int *allocatedP
)
937 afs_syscall(AFSCALL_ICL
, ICL_OP_GETLOGINFO
, (long)logname
,
938 (long)logSizeP
, (long)allocatedP
, 0, 0, 0);
942 /* get state of specified set */
944 icl_GetSetState(char *setname
, afs_int32
*stateP
)
948 afs_syscall(AFSCALL_ICL
, ICL_OP_GETSETINFO
, (long)setname
,
949 (long)stateP
, 0, 0, 0, 0);
954 icl_TailKernel(FILE *outFilep
, char *logname
, afs_int32 waitTime
)
956 afs_int32 bufferSize
= 0;
957 afs_int32 newBufferSize
;
960 afs_int32 code
, retVal
= 0;
966 /* get information about the specified log */
968 afs_syscall(AFSCALL_ICL
, ICL_OP_GETLOGINFO
, (long)logname
,
969 (long)&bufferSize
, (long)&allocated
, 0, 0, 0);
972 (void)fprintf(stderr
, "'%s' not found\n", logname
);
974 (void)fprintf(stderr
,
975 "cannot get information on log '%s' (errno = %d)\n",
981 (void)fprintf(stderr
, "'%s' not allocated\n", logname
);
987 bufferp
= malloc(sizeof(afs_int32
) * bufferSize
);
989 (void)fprintf(stderr
, "cannot allocate %d words for buffer\n",
994 /* start "infinite" loop */
996 /* read out all that's currently there */
997 nwords
= 0; /* total words copied out */
998 i
= 0; /* initialize cookie */
1000 /* display all the entries in the log */
1001 if (bufferSize
- nwords
<= 0)
1002 break; /* filled whole buffer, clear when done */
1004 afs_syscall(AFSCALL_ICL
, ICL_OP_COPYOUTCLR
, (long)logname
,
1005 (long)(bufferp
+ nwords
), bufferSize
- nwords
,
1008 /* otherwise we've got an error */
1009 fprintf(stderr
, "returned error %d dumping log.\n", errno
);
1013 /* otherwise, we have flags in the high order byte, and
1014 * a length (in words) in the remainder.
1023 } /* for loop over all cookies */
1025 /* otherwise we should display all of the log entries here.
1026 * Note that a record may end in the middle, in which case
1027 * we should start over with the cookie value of the start
1030 for (ix
= 0; ix
< nwords
;) {
1031 /* start of a record */
1032 rlength
= (bufferp
[ix
] >> 24) & 0xff;
1033 /* ensure that entire record fits */
1034 if (ix
+ rlength
> nwords
) {
1035 /* doesn't fit, adjust cookie and break */
1037 fprintf(stderr
, "BOGUS: 0 length record\n");
1043 /* print the record */
1044 DisplayRecord(outFilep
, &bufferp
[ix
], rlength
);
1046 } /* for loop displaying buffer */
1051 /* see if things have changed */
1053 afs_syscall(AFSCALL_ICL
, ICL_OP_GETLOGINFO
, (long)logname
,
1054 (long)&newBufferSize
, (long)&allocated
, 0, 0, 0);
1056 if (errno
== ENOENT
)
1057 (void)fprintf(stderr
, "'%s' not found\n", logname
);
1059 (void)fprintf(stderr
,
1060 "cannot get information on log '%s' (errno = %d)\n",
1067 (void)fprintf(stderr
, "'%s' no int32er allocated\n", logname
);
1072 if (bufferSize
== 0) {
1073 (void)fprintf(stderr
, "buffer size has become 0\n");
1077 if (bufferSize
!= newBufferSize
) {
1078 /* have to reallocate a buffer */
1079 bufferSize
= newBufferSize
;
1081 bufferp
= malloc(sizeof(afs_int32
) * bufferSize
);
1083 (void)fprintf(stderr
, "cannot allocate %d words for buffer\n",
1089 } /* infinite loop */
1096 #if !defined(AFS_SGI_ENV)
1098 afs_syscall(long call
, long parm0
, long parm1
, long parm2
, long parm3
,
1099 long parm4
, long parm5
, long parm6
)
1102 #if defined(AFS_DARWIN80_ENV) || defined(AFS_LINUX20_ENV)
1105 #ifdef AFS_LINUX20_ENV
1106 #if defined AFS_LINUX_64BIT_KERNEL
1108 /* don't want to sign extend it to 64bit, so using ulong */
1109 eparm
[0] = (unsigned long)parm3
;
1110 eparm
[1] = (unsigned long)parm4
;
1111 eparm
[2] = (unsigned long)parm5
;
1112 eparm
[3] = (unsigned long)parm6
;
1120 /* Linux can only handle 5 arguments in the actual syscall. */
1121 if (call
== AFSCALL_ICL
) {
1122 rval
= proc_afs_syscall(call
, parm0
, parm1
, parm2
, (long)eparm
, &code
);
1125 code
= syscall(AFS_SYSCALL
, call
, parm0
, parm1
, parm2
, eparm
);
1131 rval
= proc_afs_syscall(call
, parm0
, parm1
, parm2
, parm3
, &code
);
1134 code
= syscall(AFS_SYSCALL
, call
, parm0
, parm1
, parm2
, parm3
);
1140 #if defined(AFS_SPARC64_LINUX20_ENV) || defined(AFS_SPARC_LINUX20_ENV)
1141 /* on sparc this function returns none value, so do it myself */
1142 __asm__
__volatile__("mov %o0, %i0; ret; restore");
1145 #ifdef AFS_DARWIN80_ENV
1146 code
= ioctl_afs_syscall(call
, parm0
, parm1
, parm2
, parm3
, parm4
, parm5
, &rval
);
1147 if (!code
) code
= rval
;
1149 #if !defined(AFS_SGI_ENV) && !defined(AFS_AIX32_ENV)
1150 # if defined(AFS_SYSCALL)
1151 code
= syscall(AFS_SYSCALL
, call
, parm0
, parm1
, parm2
, parm3
, parm4
);
1156 #if defined(AFS_SGI_ENV)
1157 code
= syscall(AFS_ICL
, call
, parm0
, parm1
, parm2
, parm3
, parm4
); /* XXX */
1159 code
= syscall(AFSCALL_ICL
, parm0
, parm1
, parm2
, parm3
, parm4
);
1163 #endif /* AFS_LINUX20_ENV */
1171 /* init function, called once, under icl_lock */
1178 /* setup signal handler, in user space */
1185 icl_CreateSet(char *name
, struct afs_icl_log
*baseLogp
,
1186 struct afs_icl_log
*fatalLogp
, struct afs_icl_set
**outSetpp
)
1188 return icl_CreateSetWithFlags(name
, baseLogp
, fatalLogp
, /*flags */ 0,
1192 /* create a set, given pointers to base and fatal logs, if any.
1193 * Logs are unlocked, but referenced, and *outSetpp is returned
1194 * referenced. Function bumps reference count on logs, since it
1195 * addds references from the new icl_set. When the set is destroyed,
1196 * those references will be released.
1199 icl_CreateSetWithFlags(char *name
, struct afs_icl_log
*baseLogp
,
1200 struct afs_icl_log
*fatalLogp
, afs_uint32 flags
,
1201 struct afs_icl_set
**outSetpp
)
1203 struct afs_icl_set
*setp
;
1205 afs_int32 states
= ICL_DEFAULT_SET_STATES
;
1210 for (setp
= icl_allSets
; setp
; setp
= setp
->nextp
) {
1211 if (strcmp(setp
->name
, name
) == 0) {
1214 if (flags
& ICL_CRSET_FLAG_PERSISTENT
) {
1215 setp
->states
|= ICL_SETF_PERSISTENT
;
1221 /* determine initial state */
1222 if (flags
& ICL_CRSET_FLAG_DEFAULT_ON
)
1223 states
= ICL_SETF_ACTIVE
;
1224 else if (flags
& ICL_CRSET_FLAG_DEFAULT_OFF
)
1225 states
= ICL_SETF_FREED
;
1226 if (flags
& ICL_CRSET_FLAG_PERSISTENT
)
1227 states
|= ICL_SETF_PERSISTENT
;
1229 setp
= osi_Alloc(sizeof(struct afs_icl_set
));
1230 memset((caddr_t
) setp
, 0, sizeof(*setp
));
1232 if (states
& ICL_SETF_FREED
)
1233 states
&= ~ICL_SETF_ACTIVE
; /* if freed, can't be active */
1234 setp
->states
= states
;
1236 setp
->name
= osi_Alloc(strlen(name
) + 1);
1237 strcpy(setp
->name
, name
);
1238 setp
->nevents
= ICL_DEFAULTEVENTS
;
1239 setp
->eventFlags
= osi_Alloc(ICL_DEFAULTEVENTS
);
1240 for (i
= 0; i
< ICL_DEFAULTEVENTS
; i
++)
1241 setp
->eventFlags
[i
] = 0xff; /* default to enabled */
1243 /* update this global info under the icl_lock */
1244 setp
->nextp
= icl_allSets
;
1247 /* set's basic lock is still held, so we can finish init */
1249 setp
->logs
[0] = baseLogp
;
1250 icl_LogHold(baseLogp
);
1251 if (!(setp
->states
& ICL_SETF_FREED
))
1252 icl_LogUse(baseLogp
); /* log is actually being used */
1255 setp
->logs
[1] = fatalLogp
;
1256 icl_LogHold(fatalLogp
);
1257 if (!(setp
->states
& ICL_SETF_FREED
))
1258 icl_LogUse(fatalLogp
); /* log is actually being used */
1265 /* function to change event enabling information for a particular set */
1267 icl_SetEnable(struct afs_icl_set
*setp
, afs_int32 eventID
, int setValue
)
1271 if (!ICL_EVENTOK(setp
, eventID
)) {
1274 tp
= &setp
->eventFlags
[ICL_EVENTBYTE(eventID
)];
1276 *tp
|= ICL_EVENTMASK(eventID
);
1278 *tp
&= ~(ICL_EVENTMASK(eventID
));
1282 /* return indication of whether a particular event ID is enabled
1283 * for tracing. If *getValuep is set to 0, the event is disabled,
1284 * otherwise it is enabled. All events start out enabled by default.
1287 icl_GetEnable(struct afs_icl_set
*setp
, afs_int32 eventID
, int *getValuep
)
1289 if (!ICL_EVENTOK(setp
, eventID
)) {
1292 if (setp
->eventFlags
[ICL_EVENTBYTE(eventID
)] & ICL_EVENTMASK(eventID
))
1299 /* hold and release event sets */
1301 icl_SetHold(struct afs_icl_set
*setp
)
1307 /* free a set. Called with icl_lock locked */
1309 icl_ZapSet(struct afs_icl_set
*setp
)
1311 struct afs_icl_set
**lpp
, *tp
;
1313 struct afs_icl_log
*tlp
;
1315 for (lpp
= &icl_allSets
, tp
= *lpp
; tp
; lpp
= &tp
->nextp
, tp
= *lpp
) {
1317 /* found the dude we want to remove */
1319 osi_Free(setp
->name
, 1 + strlen(setp
->name
));
1320 osi_Free(setp
->eventFlags
, ICL_EVENTBYTES(setp
->nevents
));
1321 for (i
= 0; i
< ICL_LOGSPERSET
; i
++) {
1322 if ((tlp
= setp
->logs
[i
]))
1325 osi_Free(setp
, sizeof(struct afs_icl_set
));
1326 break; /* won't find it twice */
1332 /* do the release, watching for deleted entries */
1334 icl_SetRele(struct afs_icl_set
*setp
)
1336 if (--setp
->refCount
== 0 && (setp
->states
& ICL_SETF_DELETED
)) {
1337 icl_ZapSet(setp
); /* destroys setp's lock! */
1342 /* free a set entry, dropping its reference count */
1344 icl_SetFree(struct afs_icl_set
*setp
)
1346 setp
->states
|= ICL_SETF_DELETED
;
1351 /* find a set by name, returning it held */
1352 struct afs_icl_set
*
1353 icl_FindSet(char *name
)
1355 struct afs_icl_set
*tp
;
1357 for (tp
= icl_allSets
; tp
; tp
= tp
->nextp
) {
1358 if (strcmp(tp
->name
, name
) == 0) {
1359 /* this is the dude we want */
1367 /* zero out all the logs in the set */
1369 icl_ZeroSet(struct afs_icl_set
*setp
)
1374 struct afs_icl_log
*logp
;
1376 for (i
= 0; i
< ICL_LOGSPERSET
; i
++) {
1377 logp
= setp
->logs
[i
];
1380 tcode
= icl_ZeroLog(logp
);
1382 code
= tcode
; /* save the last bad one */
1390 icl_EnumerateSets(int (*aproc
) (char *, void *, struct afs_icl_set
*),
1393 struct afs_icl_set
*tp
, *np
;
1397 for (tp
= icl_allSets
; tp
; tp
= np
) {
1398 tp
->refCount
++; /* hold this guy */
1399 code
= (*aproc
) (tp
->name
, arock
, tp
);
1400 np
= tp
->nextp
; /* tp may disappear next, but not np */
1401 if (--tp
->refCount
== 0 && (tp
->states
& ICL_SETF_DELETED
))
1410 icl_AddLogToSet(struct afs_icl_set
*setp
, struct afs_icl_log
*newlogp
)
1415 for (i
= 0; i
< ICL_LOGSPERSET
; i
++) {
1416 if (!setp
->logs
[i
]) {
1417 setp
->logs
[i
] = newlogp
;
1419 icl_LogHold(newlogp
);
1420 if (!(setp
->states
& ICL_SETF_FREED
)) {
1421 /* bump up the number of sets using the log */
1422 icl_LogUse(newlogp
);
1431 icl_SetSetStat(struct afs_icl_set
*setp
, int op
)
1435 struct afs_icl_log
*logp
;
1438 case ICL_OP_SS_ACTIVATE
: /* activate a log */
1440 * If we are not already active, see if we have released
1441 * our demand that the log be allocated (FREED set). If
1442 * we have, reassert our desire.
1444 if (!(setp
->states
& ICL_SETF_ACTIVE
)) {
1445 if (setp
->states
& ICL_SETF_FREED
) {
1446 /* have to reassert desire for logs */
1447 for (i
= 0; i
< ICL_LOGSPERSET
; i
++) {
1448 logp
= setp
->logs
[i
];
1455 setp
->states
&= ~ICL_SETF_FREED
;
1457 setp
->states
|= ICL_SETF_ACTIVE
;
1462 case ICL_OP_SS_DEACTIVATE
: /* deactivate a log */
1463 /* this doesn't require anything beyond clearing the ACTIVE flag */
1464 setp
->states
&= ~ICL_SETF_ACTIVE
;
1468 case ICL_OP_SS_FREE
: /* deassert design for log */
1470 * if we are already in this state, do nothing; otherwise
1471 * deassert desire for log
1473 if (setp
->states
& ICL_SETF_ACTIVE
)
1476 if (!(setp
->states
& ICL_SETF_FREED
)) {
1477 for (i
= 0; i
< ICL_LOGSPERSET
; i
++) {
1478 logp
= setp
->logs
[i
];
1481 icl_LogFreeUse(logp
);
1485 setp
->states
|= ICL_SETF_FREED
;
1498 struct afs_icl_log
*afs_icl_allLogs
= 0;
1500 /* hold and release logs */
1502 icl_LogHold(struct afs_icl_log
*logp
)
1508 /* hold and release logs, called with lock already held */
1510 icl_LogHoldNL(struct afs_icl_log
*logp
)
1516 /* keep track of how many sets believe the log itself is allocated */
1518 icl_LogUse(struct afs_icl_log
*logp
)
1520 if (logp
->setCount
== 0) {
1521 /* this is the first set actually using the log -- allocate it */
1522 if (logp
->logSize
== 0) {
1523 /* we weren't passed in a hint and it wasn't set */
1524 logp
->logSize
= ICL_DEFAULT_LOGSIZE
;
1526 logp
->datap
= osi_Alloc(sizeof(afs_int32
) * logp
->logSize
);
1532 /* decrement the number of real users of the log, free if possible */
1534 icl_LogFreeUse(struct afs_icl_log
*logp
)
1536 if (--logp
->setCount
== 0) {
1537 /* no more users -- free it (but keep log structure around) */
1538 osi_Free(logp
->datap
, sizeof(afs_int32
) * logp
->logSize
);
1539 logp
->firstUsed
= logp
->firstFree
= 0;
1540 logp
->logElements
= 0;
1546 /* set the size of the log to 'logSize' */
1548 icl_LogSetSize(struct afs_icl_log
*logp
, afs_int32 logSize
)
1551 /* nothing to worry about since it's not allocated */
1552 logp
->logSize
= logSize
;
1555 logp
->firstUsed
= logp
->firstFree
= 0;
1556 logp
->logElements
= 0;
1558 /* free and allocate a new one */
1559 osi_Free(logp
->datap
, sizeof(afs_int32
) * logp
->logSize
);
1560 logp
->datap
= osi_Alloc(sizeof(afs_int32
) * logSize
);
1561 logp
->logSize
= logSize
;
1567 /* free a log. Called with icl_lock locked. */
1569 icl_ZapLog(struct afs_icl_log
*logp
)
1571 struct afs_icl_log
**lpp
, *tp
;
1573 for (lpp
= &afs_icl_allLogs
, tp
= *lpp
; tp
; lpp
= &tp
->nextp
, tp
= *lpp
) {
1575 /* found the dude we want to remove */
1577 osi_Free(logp
->name
, 1 + strlen(logp
->name
));
1578 osi_Free(logp
->datap
, logp
->logSize
* sizeof(afs_int32
));
1579 osi_Free(logp
, sizeof(struct icl_log
));
1580 break; /* won't find it twice */
1586 /* do the release, watching for deleted entries */
1588 icl_LogRele(struct afs_icl_log
*logp
)
1590 if (--logp
->refCount
== 0 && (logp
->states
& ICL_LOGF_DELETED
)) {
1591 icl_ZapLog(logp
); /* destroys logp's lock! */
1596 /* do the release, watching for deleted entries, log already held */
1598 icl_LogReleNL(struct afs_icl_log
*logp
)
1600 if (--logp
->refCount
== 0 && (logp
->states
& ICL_LOGF_DELETED
)) {
1601 icl_ZapLog(logp
); /* destroys logp's lock! */
1606 /* zero out the log */
1608 icl_ZeroLog(struct afs_icl_log
*logp
)
1610 logp
->firstUsed
= logp
->firstFree
= 0;
1611 logp
->logElements
= 0;
1615 /* free a log entry, and drop its reference count */
1617 icl_LogFree(struct afs_icl_log
*logp
)
1619 logp
->states
|= ICL_LOGF_DELETED
;
1626 icl_EnumerateLogs(int (*aproc
)
1627 (char *name
, void *arock
, struct afs_icl_log
* tp
),
1630 struct afs_icl_log
*tp
, *np
;
1634 for (tp
= afs_icl_allLogs
; tp
; tp
= np
) {
1635 tp
->refCount
++; /* hold this guy */
1637 code
= (*aproc
) (tp
->name
, arock
, tp
);
1638 if (--tp
->refCount
== 0)
1647 afs_icl_bulkSetinfo_t
*
1648 GetBulkSetInfo(void)
1650 unsigned int infoSize
;
1653 sizeof(afs_icl_bulkSetinfo_t
) + (ICL_RPC_MAX_SETS
-
1654 1) * sizeof(afs_icl_setinfo_t
);
1656 setInfo
= calloc(1, infoSize
);
1658 (void)fprintf(stderr
,
1659 "Could not allocate the memory for bulk set info structure\n");
1667 afs_icl_bulkLoginfo_t
*
1668 GetBulkLogInfo(void)
1670 unsigned int infoSize
;
1673 sizeof(afs_icl_bulkLoginfo_t
) + (ICL_RPC_MAX_LOGS
-
1674 1) * sizeof(afs_icl_loginfo_t
);
1676 logInfo
= calloc(1, infoSize
);
1678 (void)fprintf(stderr
,
1679 "Could not allocate the memory for bulk log info structure\n");
1689 DoDump(struct cmd_syndesc
*as
, void *arock
)
1693 afs_int32 waitTime
= 10 /* seconds */ ;
1695 FILE *outfp
= stdout
;
1697 struct cmd_item
*itemp
;
1699 if (geteuid() != 0) {
1700 printf("fstrace must be run as root\n");
1704 if (as
->parms
[3].items
) {
1705 if (!as
->parms
[1].items
) {
1706 (void)fprintf(stderr
, "-sleep can only be used with -follow\n");
1709 waitTime
= strtol(as
->parms
[3].items
->data
, NULL
, 0);
1712 if (as
->parms
[2].items
) {
1713 /* try to open the specified output file */
1714 if ((outfp
= fopen(as
->parms
[2].items
->data
, "w")) == NULL
) {
1715 (void)fprintf(stderr
, "Cannot open file '%s' for writing\n",
1716 as
->parms
[2].items
->data
);
1720 #ifdef AFS_SGI64_ENV
1721 startTime
= time((time_t *) 0);
1723 startTime
= time(0);
1725 (void)fprintf(outfp
, "AFS Trace Dump -\n\n Date: %s\n",
1728 if (as
->parms
[0].items
) {
1729 for (itemp
= as
->parms
[0].items
; itemp
; itemp
= itemp
->next
) {
1730 tcode
= icl_DumpKernel(outfp
, itemp
->data
);
1732 (void)fprintf(stderr
, "Unable to dump set %s (errno = %d)\n",
1733 itemp
->data
, errno
);
1737 } else if (as
->parms
[1].items
) {
1738 logname
= as
->parms
[1].items
->data
;
1739 code
= icl_TailKernel(outfp
, logname
, waitTime
);
1741 (void)fprintf(stderr
,
1742 "Error tailing kernel log '%s' (errno = %d)\n",
1746 code
= icl_DumpKernel(outfp
, NULL
);
1748 (void)fprintf(outfp
, "\nAFS Trace Dump - %s\n",
1749 code
? "FAILED" : "Completed");
1751 if (outfp
!= stdout
)
1752 (void)fclose(outfp
);
1760 struct cmd_syndesc
*dumpSyntax
;
1763 cmd_CreateSyntax("dump", DoDump
, NULL
, 0, "dump AFS trace logs");
1764 (void)cmd_AddParm(dumpSyntax
, "-set", CMD_LIST
, CMD_OPTIONAL
,
1766 (void)cmd_AddParm(dumpSyntax
, "-follow", CMD_SINGLE
, CMD_OPTIONAL
,
1768 (void)cmd_AddParm(dumpSyntax
, "-file", CMD_SINGLE
, CMD_OPTIONAL
,
1769 "path to trace log file for writing");
1770 (void)cmd_AddParm(dumpSyntax
, "-sleep", CMD_SINGLE
, CMD_OPTIONAL
,
1771 "interval (secs) for writes when using -follow");
1776 DoShowLog(struct cmd_syndesc
*as
, void *arock
)
1778 afs_int32 retVal
= 0;
1783 struct cmd_item
*itemp
;
1785 if (geteuid() != 0) {
1786 printf("fstrace must be run as root\n");
1789 if (as
->parms
[2].items
)
1792 if (as
->parms
[0].items
) {
1793 /* enumerate logs for the specified sets */
1794 for (itemp
= as
->parms
[0].items
; itemp
; itemp
= itemp
->next
) {
1795 (void)fprintf(stdout
, "Logs for set '%s':\n", itemp
->data
);
1796 code
= icl_ListLogsBySet(stdout
, itemp
->data
, int32flg
);
1798 (void)fprintf(stderr
,
1799 "Error in enumerating set %s (errno = %d)\n",
1800 itemp
->data
, errno
);
1804 } else if (as
->parms
[1].items
) {
1805 /* print out log information */
1806 for (itemp
= as
->parms
[1].items
; itemp
; itemp
= itemp
->next
) {
1807 code
= icl_GetLogsize(itemp
->data
, &logSize
, &allocated
);
1809 (void)fprintf(stdout
, "%s : %d kbytes (%s)\n", itemp
->data
,
1811 allocated
? "allocated" : "unallocated");
1813 (void)fprintf(stderr
,
1814 "Could not find log '%s' (errno = %d)\n",
1815 itemp
->data
, errno
);
1821 (void)fprintf(stdout
, "Available logs:\n");
1822 code
= icl_ListLogs(stdout
, int32flg
);
1824 (void)fprintf(stderr
, "Error in listing logs (errno = %d)\n",
1836 struct cmd_syndesc
*showSyntax
;
1839 cmd_CreateSyntax("lslog", DoShowLog
, NULL
, 0,
1840 "list available logs");
1841 (void)cmd_AddParm(showSyntax
, "-set", CMD_LIST
, CMD_OPTIONAL
,
1843 (void)cmd_AddParm(showSyntax
, "-log", CMD_LIST
, CMD_OPTIONAL
,
1845 (void)cmd_AddParm(showSyntax
, "-long", CMD_FLAG
, CMD_OPTIONAL
,
1846 "show defined log size in kbytes & if it is allocated in kernel mem");
1850 DoShowSet(struct cmd_syndesc
*as
, void *arock
)
1852 afs_int32 retVal
= 0;
1855 struct cmd_item
*itemp
;
1857 if (geteuid() != 0) {
1858 printf("fstrace must be run as root\n");
1861 if (as
->parms
[0].items
) {
1862 /* print information on the specified sets */
1863 for (itemp
= as
->parms
[0].items
; itemp
; itemp
= itemp
->next
) {
1864 code
= icl_GetSetState(itemp
->data
, &state
);
1866 (void)fprintf(stderr
,
1867 "Error getting status on set %s (errno = %d)\n",
1868 itemp
->data
, errno
);
1871 (void)fprintf(stdout
, "Set %s: %s%s%s\n", itemp
->data
,
1872 (state
& ICL_SETF_ACTIVE
) ? "active" :
1874 (state
& ICL_SETF_FREED
) ? " (dormant)" : "",
1875 (state
& ICL_SETF_PERSISTENT
) ? " persistent" :
1880 (void)fprintf(stdout
, "Available sets:\n");
1881 code
= icl_ListSets(stdout
);
1883 (void)fprintf(stderr
, "Error in listing sets (errno = %d)\n",
1895 struct cmd_syndesc
*showSyntax
;
1898 cmd_CreateSyntax("lsset", DoShowSet
, NULL
, 0,
1899 "list available event sets");
1900 (void)cmd_AddParm(showSyntax
, "-set", CMD_LIST
, CMD_OPTIONAL
,
1905 DoClear(struct cmd_syndesc
*as
, void *arock
)
1907 afs_int32 retVal
= 0;
1909 struct cmd_item
*itemp
;
1911 if (geteuid() != 0) {
1912 printf("fstrace must be run as root\n");
1915 if (as
->parms
[0].items
) {
1916 /* clear logs for the specified sets */
1917 for (itemp
= as
->parms
[0].items
; itemp
; itemp
= itemp
->next
) {
1918 code
= icl_ClearSet(itemp
->data
);
1920 (void)fprintf(stderr
,
1921 "Error in clearing set %s (errno = %d)\n",
1922 itemp
->data
, errno
);
1926 } else if (as
->parms
[1].items
) {
1927 /* clear specified log */
1928 for (itemp
= as
->parms
[0].items
; itemp
; itemp
= itemp
->next
) {
1929 code
= icl_ClearLog(itemp
->data
);
1931 (void)fprintf(stderr
,
1932 "Error in clearing log %s (errno = %d)\n",
1933 itemp
->data
, errno
);
1938 /* clear all logs */
1939 code
= icl_ClearAll();
1941 (void)fprintf(stderr
, "Error in clearing logs (errno = %d)\n",
1953 struct cmd_syndesc
*clearSyntax
;
1956 cmd_CreateSyntax("clear", DoClear
, NULL
, 0,
1957 "clear logs by logname or by event set");
1958 (void)cmd_AddParm(clearSyntax
, "-set", CMD_LIST
, CMD_OPTIONAL
,
1960 (void)cmd_AddParm(clearSyntax
, "-log", CMD_LIST
, CMD_OPTIONAL
,
1965 DoSet(struct cmd_syndesc
*as
, void *arock
)
1967 afs_int32 retVal
= 0;
1972 struct cmd_item
*itemp
;
1974 if (geteuid() != 0) {
1975 printf("fstrace must be run as root\n");
1978 if (as
->parms
[1].items
) {
1979 op
= ICL_OP_SS_ACTIVATE
;
1980 operation
= "active";
1981 } else if (as
->parms
[2].items
) {
1982 op
= ICL_OP_SS_DEACTIVATE
;
1983 operation
= "inactive";
1984 } else if (as
->parms
[3].items
) {
1985 op
= ICL_OP_SS_DEACTIVATE
;
1986 operation
= "inactive";
1989 /* assume active" */
1990 op
= ICL_OP_SS_ACTIVATE
;
1991 operation
= "active";
1994 if (as
->parms
[0].items
) {
1995 /* activate specified sets */
1996 for (itemp
= as
->parms
[0].items
; itemp
; itemp
= itemp
->next
) {
1997 code
= icl_ChangeSetState(itemp
->data
, op
);
1999 (void)fprintf(stderr
,
2000 "cannot set state of %s to %s (errno = %d)\n",
2001 itemp
->data
, operation
, errno
);
2003 } else if (doFree
) {
2004 /* try to make it dormant as well */
2005 code
= icl_ChangeSetState(itemp
->data
, ICL_OP_SS_FREE
);
2007 (void)fprintf(stderr
,
2008 "cannot set state of %s to dormant (errno = %d)\n",
2009 itemp
->data
, errno
);
2016 code
= icl_ChangeAllSetState(op
);
2018 (void)fprintf(stderr
,
2019 "cannot set the state of all sets to %s (errno = %d)\n",
2022 } else if (doFree
) {
2023 /* try to make it dormant as well */
2024 code
= icl_ChangeAllSetState(ICL_OP_SS_FREE
);
2026 (void)fprintf(stderr
,
2027 "cannot set the state of all sets to dormant (errno = %d)\n",
2040 struct cmd_syndesc
*setSyntax
;
2043 cmd_CreateSyntax("setset", DoSet
, NULL
, 0,
2044 "set state of event sets");
2045 (void)cmd_AddParm(setSyntax
, "-set", CMD_LIST
, CMD_OPTIONAL
,
2047 (void)cmd_AddParm(setSyntax
, "-active", CMD_FLAG
, CMD_OPTIONAL
,
2048 "enable tracing for event set & allocate kernel memory");
2049 (void)cmd_AddParm(setSyntax
, "-inactive", CMD_FLAG
, CMD_OPTIONAL
,
2050 "disables tracing for event set, keep kernel memory");
2051 (void)cmd_AddParm(setSyntax
, "-dormant", CMD_FLAG
, CMD_OPTIONAL
,
2052 "disable tracing for event set & free kernel memory");
2056 DoResize(struct cmd_syndesc
*as
, void *arock
)
2058 afs_int32 retVal
= 0;
2060 afs_int32 bufferSize
;
2061 struct cmd_item
*itemp
;
2063 if (geteuid() != 0) {
2064 printf("fstrace must be run as root\n");
2067 /* get buffer size */
2068 bufferSize
= atoi(as
->parms
[1].items
->data
);
2069 bufferSize
*= BUFFER_MULTIPLIER
;
2070 if (bufferSize
== 0)
2071 bufferSize
= ICL_DEFAULT_LOGSIZE
;
2073 /* set the size of the specified logs */
2074 if ((itemp
= as
->parms
[0].items
)) {
2075 for (; itemp
; itemp
= itemp
->next
) {
2076 code
= icl_ChangeLogSize(itemp
->data
, bufferSize
);
2078 (void)fprintf(stderr
,
2079 "Error in changing log %s buffer size (errno = %d)\n",
2080 itemp
->data
, errno
);
2085 /* Use the only current support log, "cmfx" */
2086 code
= icl_ChangeLogSize("cmfx", bufferSize
);
2088 (void)fprintf(stderr
,
2089 "Error in changing log cmfx buffer size (errno = %d)\n",
2101 struct cmd_syndesc
*setsizeSyntax
;
2104 cmd_CreateSyntax("setlog", DoResize
, NULL
, 0,
2105 "set the size of a log");
2106 (void)cmd_AddParm(setsizeSyntax
, "-log", CMD_LIST
, CMD_OPTIONAL
,
2108 (void)cmd_AddParm(setsizeSyntax
, "-buffersize", CMD_SINGLE
, CMD_REQUIRED
,
2109 "# of 1-kbyte blocks to allocate for log");
2112 #include "AFS_component_version_number.c"
2115 main(int argc
, char *argv
[])
2117 setlocale(LC_ALL
, "");
2118 #ifdef AFS_SGI62_ENV
2119 set_kernel_sizeof_long();
2122 /* set up user interface then dispatch */
2130 return (cmd_Dispatch(argc
, argv
));