]> git.saurik.com Git - apple/system_cmds.git/blame - fs_usage.tproj/fs_usage.c
system_cmds-279.6.1.tar.gz
[apple/system_cmds.git] / fs_usage.tproj / fs_usage.c
CommitLineData
1815bff5
A
1/*
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
d904471c
A
6 * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7 * Reserved. This file contains Original Code and/or Modifications of
8 * Original Code as defined in and that are subject to the Apple Public
9 * Source License Version 1.0 (the 'License'). You may not use this file
10 * except in compliance with the License. Please obtain a copy of the
11 * License at http://www.apple.com/publicsource and read it before using
12 * this file.
1815bff5
A
13 *
14 * The Original Code and all software distributed under the License are
15 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
d904471c
A
18 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
19 * License for the specific language governing rights and limitations
20 * under the License."
1815bff5
A
21 *
22 * @APPLE_LICENSE_HEADER_END@
23 */
24
25/*
26cc -I. -DKERNEL_PRIVATE -O -o fs_usage fs_usage.c
27*/
28
29#define Default_DELAY 1 /* default delay interval */
30
31#include <stdlib.h>
32#include <stdio.h>
33#include <signal.h>
34#include <strings.h>
35#include <nlist.h>
36#include <fcntl.h>
37#include <string.h>
b51d5b5f 38#include <dirent.h>
1815bff5
A
39
40#include <sys/types.h>
41#include <sys/param.h>
42#include <sys/time.h>
43
44#include <libc.h>
45#include <termios.h>
1815bff5
A
46#include <sys/ioctl.h>
47
48#ifndef KERNEL_PRIVATE
49#define KERNEL_PRIVATE
50#include <sys/kdebug.h>
51#undef KERNEL_PRIVATE
52#else
53#include <sys/kdebug.h>
54#endif /*KERNEL_PRIVATE*/
55
56#include <sys/sysctl.h>
57#include <errno.h>
58#import <mach/clock_types.h>
59#include <err.h>
60
61extern int errno;
62
b51d5b5f
A
63
64
65#define MAXINDEX 2048
66
67typedef struct LibraryInfo {
68 unsigned long address;
69 char *name;
70} LibraryInfo;
71
72LibraryInfo frameworkInfo[MAXINDEX];
73int numFrameworks = 0;
74
75char seg_addr_table[256]="/AppleInternal/Developer/seg_addr_table";
76
77char *lookup_name();
78
79
1c51fdde
A
80/*
81 MAXCOLS controls when extra data kicks in.
82 MAX_WIDE_MODE_COLS controls -w mode to get even wider data in path.
83 If NUMPARMS changes to match the kernel, it will automatically
84 get reflected in the -w mode output.
85*/
86#define NUMPARMS 23
87#define PATHLENGTH (NUMPARMS*sizeof(long))
88#define MAXCOLS 131
89#define MAX_WIDE_MODE_COLS (PATHLENGTH + 80)
1815bff5
A
90
91struct th_info {
92 int in_filemgr;
93 int thread;
20e66415 94 int pid;
1815bff5
A
95 int type;
96 int arg1;
97 int arg2;
98 int arg3;
99 int arg4;
1815bff5
A
100 int child_thread;
101 int waited;
102 double stime;
1c51fdde
A
103 long *pathptr;
104 char pathname[PATHLENGTH + 1]; /* add room for null terminator */
1815bff5
A
105};
106
107#define MAX_THREADS 512
108struct th_info th_state[MAX_THREADS];
109
110
111int cur_max = 0;
112int need_new_map = 1;
113int bias_secs;
114int wideflag = 0;
b51d5b5f 115int columns = 0;
1815bff5
A
116int select_pid_mode = 0; /* Flag set indicates that output is restricted
117 to selected pids or commands */
118
119int one_good_pid = 0; /* Used to fail gracefully when bad pids given */
120
20e66415
A
121char *arguments = 0;
122int argmax = 0;
123
124/*
125 * Network only or filesystem only output filter
126 * Default of zero means report all activity - no filtering
127 */
128#define FILESYS_FILTER 0x01
129#define NETWORK_FILTER 0x02
130#define DEFAULT_DO_NOT_FILTER 0x0
131int filter_mode = DEFAULT_DO_NOT_FILTER;
1815bff5 132
b51d5b5f
A
133#define NFS_DEV -1
134
135struct diskrec {
136 struct diskrec *next;
137 char *diskname;
138 int dev;
139};
140
141struct diskio {
142 struct diskio *next;
143 struct diskio *prev;
144 int type;
145 int bp;
146 int dev;
147 int blkno;
148 int iosize;
149 int io_errno;
150 int issuing_thread;
151 int completion_thread;
152 char issuing_command[MAXCOMLEN];
153 double issued_time;
154 double completed_time;
155};
156
157struct diskrec *disk_list = NULL;
158struct diskio *free_diskios = NULL;
159struct diskio *busy_diskios = NULL;
160
161struct diskio *insert_diskio();
162struct diskio *complete_diskio();
163void free_diskio();
164void print_diskio();
165void format_print();
166char *find_disk_name();
20e66415
A
167void cache_disk_names();
168int ReadSegAddrTable();
169void mark_thread_waited(int);
170int check_filter_mode(struct th_info *, int, int, int);
171void fs_usage_fd_set(unsigned int, unsigned int);
172int fs_usage_fd_isset(unsigned int, unsigned int);
173void fs_usage_fd_clear(unsigned int, unsigned int);
174void init_arguments_buffer();
175int get_real_command_name(int, char *, int);
176void create_map_entry(int, int, char *);
b51d5b5f 177
1815bff5
A
178#define DBG_ZERO_FILL_FAULT 1
179#define DBG_PAGEIN_FAULT 2
180#define DBG_COW_FAULT 3
181#define DBG_CACHE_HIT_FAULT 4
182
183#define TRACE_DATA_NEWTHREAD 0x07000004
20e66415 184#define TRACE_DATA_EXEC 0x07000008
1815bff5
A
185#define TRACE_STRING_NEWTHREAD 0x07010004
186#define TRACE_STRING_EXEC 0x07010008
187
188#define MACH_vmfault 0x01300000
b51d5b5f 189#define MACH_pageout 0x01300004
1815bff5
A
190#define MACH_sched 0x01400000
191#define MACH_stkhandoff 0x01400008
192#define VFS_LOOKUP 0x03010090
193#define BSC_exit 0x040C0004
194
b51d5b5f
A
195#define P_WrData 0x03020000
196#define P_RdData 0x03020008
197#define P_WrMeta 0x03020020
198#define P_RdMeta 0x03020028
199#define P_PgOut 0x03020040
200#define P_PgIn 0x03020048
201#define P_WrDataAsync 0x03020010
202#define P_RdDataAsync 0x03020018
203#define P_WrMetaAsync 0x03020030
204#define P_RdMetaAsync 0x03020038
205#define P_PgOutAsync 0x03020050
206#define P_PgInAsync 0x03020058
207
208#define P_WrDataDone 0x03020004
209#define P_RdDataDone 0x0302000C
210#define P_WrMetaDone 0x03020024
211#define P_RdMetaDone 0x0302002C
212#define P_PgOutDone 0x03020044
213#define P_PgInDone 0x0302004C
214#define P_WrDataAsyncDone 0x03020014
215#define P_RdDataAsyncDone 0x0302001C
216#define P_WrMetaAsyncDone 0x03020034
217#define P_RdMetaAsyncDone 0x0302003C
218#define P_PgOutAsyncDone 0x03020054
219#define P_PgInAsyncDone 0x0302005C
220
221
1815bff5 222#define MSC_map_fd 0x010c00ac
20e66415
A
223
224// Network related codes
1815bff5
A
225#define BSC_recvmsg 0x040C006C
226#define BSC_sendmsg 0x040C0070
227#define BSC_recvfrom 0x040C0074
20e66415
A
228#define BSC_accept 0x040C0078
229#define BSC_select 0x040C0174
230#define BSC_socket 0x040C0184
231#define BSC_connect 0x040C0188
232#define BSC_bind 0x040C01A0
233#define BSC_listen 0x040C01A8
1815bff5 234#define BSC_sendto 0x040C0214
20e66415 235#define BSC_socketpair 0x040C021C
1815bff5
A
236
237#define BSC_read 0x040C000C
238#define BSC_write 0x040C0010
239#define BSC_open 0x040C0014
240#define BSC_close 0x040C0018
241#define BSC_link 0x040C0024
242#define BSC_unlink 0x040C0028
b51d5b5f
A
243#define BSC_chdir 0x040c0030
244#define BSC_fchdir 0x040c0034
1815bff5
A
245#define BSC_mknod 0x040C0038
246#define BSC_chmod 0x040C003C
247#define BSC_chown 0x040C0040
248#define BSC_access 0x040C0084
249#define BSC_chflags 0x040C0088
250#define BSC_fchflags 0x040C008C
b51d5b5f 251#define BSC_sync 0x040C0090
20e66415 252#define BSC_dup 0x040C00A4
b51d5b5f 253#define BSC_revoke 0x040C00E0
1815bff5 254#define BSC_symlink 0x040C00E4
b51d5b5f 255#define BSC_readlink 0x040C00E8
20e66415
A
256#define BSC_chroot 0x040C00F4
257#define BSC_dup2 0x040C0168
1815bff5
A
258#define BSC_fsync 0x040C017C
259#define BSC_readv 0x040C01E0
260#define BSC_writev 0x040C01E4
261#define BSC_fchown 0x040C01EC
262#define BSC_fchmod 0x040C01F0
b51d5b5f
A
263#define BSC_rename 0x040C0200
264#define BSC_mkfifo 0x040c0210
1815bff5 265#define BSC_mkdir 0x040C0220
b51d5b5f
A
266#define BSC_rmdir 0x040C0224
267#define BSC_utimes 0x040C0228
268#define BSC_futimes 0x040C022C
c3a08f59
A
269#define BSC_pread 0x040C0264
270#define BSC_pread_extended 0x040E0264
271#define BSC_pwrite 0x040C0268
272#define BSC_pwrite_extended 0x040E0268
1815bff5
A
273#define BSC_statfs 0x040C0274
274#define BSC_fstatfs 0x040C0278
275#define BSC_stat 0x040C02F0
276#define BSC_fstat 0x040C02F4
277#define BSC_lstat 0x040C02F8
278#define BSC_pathconf 0x040C02FC
279#define BSC_fpathconf 0x040C0300
280#define BSC_getdirentries 0x040C0310
281#define BSC_mmap 0x040c0314
282#define BSC_lseek 0x040c031c
283#define BSC_truncate 0x040C0320
b51d5b5f
A
284#define BSC_ftruncate 0x040C0324
285#define BSC_undelete 0x040C0334
1815bff5
A
286#define BSC_statv 0x040C0364
287#define BSC_lstatv 0x040C0368
288#define BSC_fstatv 0x040C036C
b51d5b5f 289#define BSC_mkcomplex 0x040C0360
1815bff5
A
290#define BSC_getattrlist 0x040C0370
291#define BSC_setattrlist 0x040C0374
292#define BSC_getdirentriesattr 0x040C0378
293#define BSC_exchangedata 0x040C037C
294#define BSC_checkuseraccess 0x040C0380
b51d5b5f
A
295#define BSC_searchfs 0x040C0384
296#define BSC_delete 0x040C0388
297#define BSC_copyfile 0x040C038C
298#define BSC_fsctl 0x040C03C8
299#define BSC_load_shared_file 0x040C04A0
1815bff5
A
300
301// Carbon File Manager support
302#define FILEMGR_PBGETCATALOGINFO 0x1e000020
303#define FILEMGR_PBGETCATALOGINFOBULK 0x1e000024
304#define FILEMGR_PBCREATEFILEUNICODE 0x1e000028
305#define FILEMGR_PBCREATEDIRECTORYUNICODE 0x1e00002c
306#define FILEMGR_PBCREATEFORK 0x1e000030
307#define FILEMGR_PBDELETEFORK 0x1e000034
308#define FILEMGR_PBITERATEFORK 0x1e000038
309#define FILEMGR_PBOPENFORK 0x1e00003c
310#define FILEMGR_PBREADFORK 0x1e000040
311#define FILEMGR_PBWRITEFORK 0x1e000044
312#define FILEMGR_PBALLOCATEFORK 0x1e000048
313#define FILEMGR_PBDELETEOBJECT 0x1e00004c
314#define FILEMGR_PBEXCHANGEOBJECT 0x1e000050
315#define FILEMGR_PBGETFORKCBINFO 0x1e000054
316#define FILEMGR_PBGETVOLUMEINFO 0x1e000058
317#define FILEMGR_PBMAKEFSREF 0x1e00005c
318#define FILEMGR_PBMAKEFSREFUNICODE 0x1e000060
319#define FILEMGR_PBMOVEOBJECT 0x1e000064
320#define FILEMGR_PBOPENITERATOR 0x1e000068
321#define FILEMGR_PBRENAMEUNICODE 0x1e00006c
322#define FILEMGR_PBSETCATALOGINFO 0x1e000070
323#define FILEMGR_PBSETVOLUMEINFO 0x1e000074
324#define FILEMGR_FSREFMAKEPATH 0x1e000078
325#define FILEMGR_FSPATHMAKEREF 0x1e00007c
326
327#define FILEMGR_PBGETCATINFO 0x1e010000
328#define FILEMGR_PBGETCATINFOLITE 0x1e010004
329#define FILEMGR_PBHGETFINFO 0x1e010008
330#define FILEMGR_PBXGETVOLINFO 0x1e01000c
331#define FILEMGR_PBHCREATE 0x1e010010
332#define FILEMGR_PBHOPENDF 0x1e010014
333#define FILEMGR_PBHOPENRF 0x1e010018
334#define FILEMGR_PBHGETDIRACCESS 0x1e01001c
335#define FILEMGR_PBHSETDIRACCESS 0x1e010020
336#define FILEMGR_PBHMAPID 0x1e010024
337#define FILEMGR_PBHMAPNAME 0x1e010028
338#define FILEMGR_PBCLOSE 0x1e01002c
339#define FILEMGR_PBFLUSHFILE 0x1e010030
340#define FILEMGR_PBGETEOF 0x1e010034
341#define FILEMGR_PBSETEOF 0x1e010038
342#define FILEMGR_PBGETFPOS 0x1e01003c
343#define FILEMGR_PBREAD 0x1e010040
344#define FILEMGR_PBWRITE 0x1e010044
345#define FILEMGR_PBGETFCBINFO 0x1e010048
346#define FILEMGR_PBSETFINFO 0x1e01004c
347#define FILEMGR_PBALLOCATE 0x1e010050
348#define FILEMGR_PBALLOCCONTIG 0x1e010054
349#define FILEMGR_PBSETFPOS 0x1e010058
350#define FILEMGR_PBSETCATINFO 0x1e01005c
351#define FILEMGR_PBGETVOLPARMS 0x1e010060
352#define FILEMGR_PBSETVINFO 0x1e010064
353#define FILEMGR_PBMAKEFSSPEC 0x1e010068
354#define FILEMGR_PBHGETVINFO 0x1e01006c
355#define FILEMGR_PBCREATEFILEIDREF 0x1e010070
356#define FILEMGR_PBDELETEFILEIDREF 0x1e010074
357#define FILEMGR_PBRESOLVEFILEIDREF 0x1e010078
358#define FILEMGR_PBFLUSHVOL 0x1e01007c
359#define FILEMGR_PBHRENAME 0x1e010080
360#define FILEMGR_PBCATMOVE 0x1e010084
361#define FILEMGR_PBEXCHANGEFILES 0x1e010088
362#define FILEMGR_PBHDELETE 0x1e01008c
363#define FILEMGR_PBDIRCREATE 0x1e010090
364#define FILEMGR_PBCATSEARCH 0x1e010094
365#define FILEMGR_PBHSETFLOCK 0x1e010098
366#define FILEMGR_PBHRSTFLOCK 0x1e01009c
367#define FILEMGR_PBLOCKRANGE 0x1e0100a0
368#define FILEMGR_PBUNLOCKRANGE 0x1e0100a4
369
370
371#define FILEMGR_CLASS 0x1e
372
373#define MAX_PIDS 32
374int pids[MAX_PIDS];
375
376int num_of_pids = 0;
377int exclude_pids = 0;
1c51fdde 378int exclude_default_pids = 1;
1815bff5
A
379
380struct kinfo_proc *kp_buffer = 0;
381int kp_nentries = 0;
382
383#define SAMPLE_SIZE 60000
384
385#define DBG_ZERO_FILL_FAULT 1
386#define DBG_PAGEIN_FAULT 2
387#define DBG_COW_FAULT 3
388#define DBG_CACHE_HIT_FAULT 4
389
390#define DBG_FUNC_ALL (DBG_FUNC_START | DBG_FUNC_END)
391#define DBG_FUNC_MASK 0xfffffffc
392
b51d5b5f 393double divisor = 0.0; /* Trace divisor converts to microseconds */
1815bff5
A
394
395int mib[6];
396size_t needed;
397char *my_buffer;
398
20e66415 399kbufinfo_t bufinfo = {0, 0, 0, 0, 0};
1815bff5
A
400
401int total_threads = 0;
20e66415
A
402kd_threadmap *mapptr = 0; /* pointer to list of threads */
403
404/* defines for tracking file descriptor state */
405#define FS_USAGE_FD_SETSIZE 256 /* Initial number of file descriptors per
406 thread that we will track */
407
408#define FS_USAGE_NFDBITS (sizeof (unsigned long) * 8)
409#define FS_USAGE_NFDBYTES(n) (((n) / FS_USAGE_NFDBITS) * sizeof (unsigned long))
410
411typedef struct {
412 unsigned int fd_valid; /* set if this is a valid entry */
413 unsigned int fd_thread;
414 unsigned int fd_setsize; /* this is a bit count */
415 unsigned long *fd_setptr; /* file descripter bitmap */
416} fd_threadmap;
417
418fd_threadmap *fdmapptr = 0; /* pointer to list of threads for fd tracking */
1815bff5
A
419
420int trace_enabled = 0;
421int set_remove_flag = 1;
422
423void set_numbufs();
424void set_init();
425void set_enable();
426void sample_sc();
427int quit();
428
429/*
430 * signal handlers
431 */
432
433void leave() /* exit under normal conditions -- INT handler */
434{
435 int i;
436 void set_enable();
437 void set_pidcheck();
438 void set_pidexclude();
439 void set_remove();
440
441 set_enable(0);
442
443 if (exclude_pids == 0) {
444 for (i = 0; i < num_of_pids; i++)
445 set_pidcheck(pids[i], 0);
446 }
447 else {
448 for (i = 0; i < num_of_pids; i++)
449 set_pidexclude(pids[i], 0);
450 }
451 set_remove();
452 exit(0);
453}
454
455
b51d5b5f
A
456void get_screenwidth()
457{
458 struct winsize size;
459
460 columns = MAXCOLS;
461
462 if (isatty(1)) {
463 if (ioctl(1, TIOCGWINSZ, &size) != -1)
464 columns = size.ws_col;
465 }
466}
467
468
1815bff5
A
469void sigwinch()
470{
b51d5b5f
A
471 if (!wideflag)
472 get_screenwidth();
1815bff5
A
473}
474
475int
20e66415 476exit_usage(char *myname) {
1815bff5 477
20e66415 478 fprintf(stderr, "Usage: %s [-e] [-w] [-f mode] [pid | cmd [pid | cmd]....]\n", myname);
1c51fdde
A
479 fprintf(stderr, " -e exclude the specified list of pids from the sample\n");
480 fprintf(stderr, " and exclude fs_usage by default\n");
1815bff5 481 fprintf(stderr, " -w force wider, detailed, output\n");
20e66415
A
482 fprintf(stderr, " -f Output is filtered based on the mode provided\n");
483 fprintf(stderr, " mode = \"network\" Show only network related output\n");
484 fprintf(stderr, " mode = \"filesys\" Show only file system related output\n");
1815bff5
A
485 fprintf(stderr, " pid selects process(s) to sample\n");
486 fprintf(stderr, " cmd selects process(s) matching command string to sample\n");
1c51fdde
A
487 fprintf(stderr, "\n%s will handle a maximum list of %d pids.\n\n", myname, MAX_PIDS);
488 fprintf(stderr, "By default (no options) the following processes are excluded from the output:\n");
489 fprintf(stderr, "fs_usage, Terminal, telnetd, sshd, rlogind, tcsh, csh, sh\n\n");
1815bff5
A
490
491 exit(1);
492}
493
20e66415 494int
1815bff5
A
495main(argc, argv)
496 int argc;
497 char *argv[];
498{
499 char *myname = "fs_usage";
500 int i;
501 char ch;
502 void getdivisor();
503 void argtopid();
504 void set_remove();
505 void set_pidcheck();
506 void set_pidexclude();
507 int quit();
508
509 if ( geteuid() != 0 ) {
510 printf("'fs_usage' must be run as root...\n");
511 exit(1);
512 }
b51d5b5f 513 get_screenwidth();
1815bff5
A
514
515 /* get our name */
516 if (argc > 0) {
517 if ((myname = rindex(argv[0], '/')) == 0) {
518 myname = argv[0];
519 }
520 else {
521 myname++;
522 }
523 }
20e66415 524
1815bff5 525
20e66415 526 while ((ch = getopt(argc, argv, "ewf:")) != EOF) {
1815bff5
A
527 switch(ch) {
528 case 'e':
529 exclude_pids = 1;
1c51fdde 530 exclude_default_pids = 0;
1815bff5
A
531 break;
532 case 'w':
533 wideflag = 1;
20e66415 534 if ((uint)columns < MAX_WIDE_MODE_COLS)
b51d5b5f 535 columns = MAX_WIDE_MODE_COLS;
1815bff5 536 break;
20e66415
A
537 case 'f':
538 if (!strcmp(optarg, "network"))
539 filter_mode |= NETWORK_FILTER;
540 else if (!strcmp(optarg, "filesys"))
541 filter_mode |= FILESYS_FILTER;
542 break;
543
1815bff5
A
544 default:
545 exit_usage(myname);
546 }
547 }
548
549 argc -= optind;
550 argv += optind;
551
1c51fdde
A
552 /* If we process any list of pids/cmds, then turn off the defaults */
553 if (argc > 0)
554 exclude_default_pids = 0;
555
1815bff5
A
556 while (argc > 0 && num_of_pids < (MAX_PIDS - 1)) {
557 select_pid_mode++;
558 argtopid(argv[0]);
559 argc--;
560 argv++;
561 }
562
1c51fdde
A
563 /* Exclude a set of default pids */
564 if (exclude_default_pids)
565 {
566 argtopid("Terminal");
567 argtopid("telnetd");
b51d5b5f 568 argtopid("telnet");
1c51fdde
A
569 argtopid("sshd");
570 argtopid("rlogind");
571 argtopid("tcsh");
572 argtopid("csh");
573 argtopid("sh");
574 exclude_pids = 1;
575 }
576
1815bff5 577 if (exclude_pids)
1c51fdde
A
578 {
579 if (num_of_pids < (MAX_PIDS - 1))
1815bff5 580 pids[num_of_pids++] = getpid();
1c51fdde
A
581 else
582 exit_usage(myname);
583 }
1815bff5
A
584
585#if 0
586 for (i = 0; i < num_of_pids; i++)
587 {
588 if (exclude_pids)
589 printf("exclude pid %d\n", pids[i]);
590 else
591 printf("pid %d\n", pids[i]);
592 }
593#endif
594
595 /* set up signal handlers */
596 signal(SIGINT, leave);
597 signal(SIGQUIT, leave);
b51d5b5f 598 signal(SIGHUP, leave);
1815bff5
A
599 signal(SIGTERM, leave);
600 signal(SIGWINCH, sigwinch);
601
602 if ((my_buffer = malloc(SAMPLE_SIZE * sizeof(kd_buf))) == (char *)0)
603 quit("can't allocate memory for tracing info\n");
604
b51d5b5f
A
605 ReadSegAddrTable();
606 cache_disk_names();
607
1815bff5
A
608 set_remove();
609 set_numbufs(SAMPLE_SIZE);
610 set_init();
611
612 if (exclude_pids == 0) {
613 for (i = 0; i < num_of_pids; i++)
614 set_pidcheck(pids[i], 1);
615 } else {
616 for (i = 0; i < num_of_pids; i++)
617 set_pidexclude(pids[i], 1);
618 }
619
620 if (select_pid_mode && !one_good_pid)
621 {
622 /*
623 An attempt to restrict output to a given
624 pid or command has failed. Exit gracefully
625 */
626 set_remove();
627 exit_usage(myname);
628 }
629
630 set_enable(1);
631 getdivisor();
20e66415 632 init_arguments_buffer();
1815bff5
A
633
634
635 /* main loop */
636
637 while (1) {
b51d5b5f 638 usleep(1000 * 25);
1815bff5
A
639
640 sample_sc();
641 }
642}
643
644void
645find_proc_names()
646{
b51d5b5f 647 size_t bufSize = 0;
1815bff5
A
648 struct kinfo_proc *kp;
649 int quit();
650
651 mib[0] = CTL_KERN;
652 mib[1] = KERN_PROC;
653 mib[2] = KERN_PROC_ALL;
654 mib[3] = 0;
655
656 if (sysctl(mib, 4, NULL, &bufSize, NULL, 0) < 0)
657 quit("trace facility failure, KERN_PROC_ALL\n");
658
659 if((kp = (struct kinfo_proc *)malloc(bufSize)) == (struct kinfo_proc *)0)
660 quit("can't allocate memory for proc buffer\n");
661
662 if (sysctl(mib, 4, kp, &bufSize, NULL, 0) < 0)
663 quit("trace facility failure, KERN_PROC_ALL\n");
664
665 kp_nentries = bufSize/ sizeof(struct kinfo_proc);
666 kp_buffer = kp;
667}
668
669
670struct th_info *find_thread(int thread, int type) {
671 struct th_info *ti;
672
673 for (ti = th_state; ti < &th_state[cur_max]; ti++) {
674 if (ti->thread == thread) {
675 if (type == ti->type)
676 return(ti);
677 if (ti->in_filemgr) {
678 if (type == -1)
679 return(ti);
680 continue;
681 }
682 if (type == 0)
683 return(ti);
684 }
685 }
686 return ((struct th_info *)0);
687}
688
b51d5b5f 689
20e66415 690void
b51d5b5f
A
691mark_thread_waited(int thread) {
692 struct th_info *ti;
693
694 for (ti = th_state; ti < &th_state[cur_max]; ti++) {
695 if (ti->thread == thread) {
696 ti->waited = 1;
697 }
698 }
699}
700
701
1815bff5
A
702void
703set_enable(int val)
704{
705 mib[0] = CTL_KERN;
706 mib[1] = KERN_KDEBUG;
707 mib[2] = KERN_KDENABLE; /* protocol */
708 mib[3] = val;
709 mib[4] = 0;
710 mib[5] = 0; /* no flags */
711 if (sysctl(mib, 4, NULL, &needed, NULL, 0) < 0)
712 quit("trace facility failure, KERN_KDENABLE\n");
713
714 if (val)
715 trace_enabled = 1;
716 else
717 trace_enabled = 0;
718}
719
720void
721set_numbufs(int nbufs)
722{
723 mib[0] = CTL_KERN;
724 mib[1] = KERN_KDEBUG;
725 mib[2] = KERN_KDSETBUF;
726 mib[3] = nbufs;
727 mib[4] = 0;
728 mib[5] = 0; /* no flags */
729 if (sysctl(mib, 4, NULL, &needed, NULL, 0) < 0)
730 quit("trace facility failure, KERN_KDSETBUF\n");
731
732 mib[0] = CTL_KERN;
733 mib[1] = KERN_KDEBUG;
734 mib[2] = KERN_KDSETUP;
735 mib[3] = 0;
736 mib[4] = 0;
737 mib[5] = 0; /* no flags */
738 if (sysctl(mib, 3, NULL, &needed, NULL, 0) < 0)
739 quit("trace facility failure, KERN_KDSETUP\n");
740}
741
742void
743set_pidcheck(int pid, int on_off)
744{
745 kd_regtype kr;
746
747 kr.type = KDBG_TYPENONE;
748 kr.value1 = pid;
749 kr.value2 = on_off;
750 needed = sizeof(kd_regtype);
751 mib[0] = CTL_KERN;
752 mib[1] = KERN_KDEBUG;
753 mib[2] = KERN_KDPIDTR;
754 mib[3] = 0;
755 mib[4] = 0;
756 mib[5] = 0;
757
758 if (sysctl(mib, 3, &kr, &needed, NULL, 0) < 0) {
759 if (on_off == 1)
760 printf("pid %d does not exist\n", pid);
761 }
762 else {
763 one_good_pid++;
764 }
765}
766
767/*
768 on_off == 0 turns off pid exclusion
769 on_off == 1 turns on pid exclusion
770*/
771void
772set_pidexclude(int pid, int on_off)
773{
774 kd_regtype kr;
775
776 one_good_pid++;
777
778 kr.type = KDBG_TYPENONE;
779 kr.value1 = pid;
780 kr.value2 = on_off;
781 needed = sizeof(kd_regtype);
782 mib[0] = CTL_KERN;
783 mib[1] = KERN_KDEBUG;
784 mib[2] = KERN_KDPIDEX;
785 mib[3] = 0;
786 mib[4] = 0;
787 mib[5] = 0;
788
789 if (sysctl(mib, 3, &kr, &needed, NULL, 0) < 0) {
790 if (on_off == 1)
791 printf("pid %d does not exist\n", pid);
792 }
793}
794
795void
796get_bufinfo(kbufinfo_t *val)
797{
798 needed = sizeof (*val);
799 mib[0] = CTL_KERN;
800 mib[1] = KERN_KDEBUG;
801 mib[2] = KERN_KDGETBUF;
802 mib[3] = 0;
803 mib[4] = 0;
804 mib[5] = 0; /* no flags */
805
806 if (sysctl(mib, 3, val, &needed, 0, 0) < 0)
807 quit("trace facility failure, KERN_KDGETBUF\n");
808
809}
810
811void
812set_remove()
813{
1815bff5
A
814 errno = 0;
815
816 mib[0] = CTL_KERN;
817 mib[1] = KERN_KDEBUG;
818 mib[2] = KERN_KDREMOVE; /* protocol */
819 mib[3] = 0;
820 mib[4] = 0;
821 mib[5] = 0; /* no flags */
822 if (sysctl(mib, 3, NULL, &needed, NULL, 0) < 0)
823 {
824 set_remove_flag = 0;
825
826 if (errno == EBUSY)
827 quit("the trace facility is currently in use...\n fs_usage, sc_usage, and latency use this feature.\n\n");
828 else
829 quit("trace facility failure, KERN_KDREMOVE\n");
830 }
831}
832
833void
834set_init()
835{ kd_regtype kr;
836
837 kr.type = KDBG_RANGETYPE;
838 kr.value1 = 0;
839 kr.value2 = -1;
840 needed = sizeof(kd_regtype);
841 mib[0] = CTL_KERN;
842 mib[1] = KERN_KDEBUG;
843 mib[2] = KERN_KDSETREG;
844 mib[3] = 0;
845 mib[4] = 0;
846 mib[5] = 0; /* no flags */
847
848 if (sysctl(mib, 3, &kr, &needed, NULL, 0) < 0)
849 quit("trace facility failure, KERN_KDSETREG\n");
850
851 mib[0] = CTL_KERN;
852 mib[1] = KERN_KDEBUG;
853 mib[2] = KERN_KDSETUP;
854 mib[3] = 0;
855 mib[4] = 0;
856 mib[5] = 0; /* no flags */
857
858 if (sysctl(mib, 3, NULL, &needed, NULL, 0) < 0)
859 quit("trace facility failure, KERN_KDSETUP\n");
860}
861
862void
863sample_sc()
864{
865 kd_buf *kd;
866 int i, count;
1c51fdde 867 size_t needed;
1815bff5
A
868 void read_command_map();
869 void create_map_entry();
870
871 /* Get kernel buffer information */
872 get_bufinfo(&bufinfo);
873
874 if (need_new_map) {
875 read_command_map();
876 need_new_map = 0;
877 }
878 needed = bufinfo.nkdbufs * sizeof(kd_buf);
879 mib[0] = CTL_KERN;
880 mib[1] = KERN_KDEBUG;
881 mib[2] = KERN_KDREADTR;
882 mib[3] = 0;
883 mib[4] = 0;
884 mib[5] = 0; /* no flags */
885
886 if (sysctl(mib, 3, my_buffer, &needed, NULL, 0) < 0)
887 quit("trace facility failure, KERN_KDREADTR\n");
888 count = needed;
889
890 if (bufinfo.flags & KDBG_WRAPPED) {
891 printf("buffer wrapped count = %d\n", count);
892
893 for (i = 0; i < cur_max; i++) {
894 th_state[i].thread = 0;
20e66415 895 th_state[i].pid = 0;
1c51fdde 896 th_state[i].pathptr = (long *)0;
1815bff5
A
897 th_state[i].pathname[0] = 0;
898 }
899 cur_max = 0;
900 need_new_map = 1;
901
902 set_enable(0);
903 set_enable(1);
904 }
905 kd = (kd_buf *)my_buffer;
906#if 0
907 printf("READTR returned %d items\n", count);
908#endif
909 for (i = 0; i < count; i++) {
910 int debugid, thread;
911 int type, n;
912 long *sargptr;
20e66415
A
913 uint64_t now;
914 long long l_usecs;
915 int secs;
916 long curr_time;
1815bff5 917 struct th_info *ti;
b51d5b5f 918 struct diskio *dio;
1815bff5
A
919 void enter_syscall();
920 void exit_syscall();
c3a08f59 921 void extend_syscall();
1815bff5
A
922 void kill_thread_map();
923
924 thread = kd[i].arg5 & KDBG_THREAD_MASK;
925 debugid = kd[i].debugid;
926 type = kd[i].debugid & DBG_FUNC_MASK;
b51d5b5f 927
20e66415
A
928 now = kd[i].timestamp;
929
930 if (i == 0)
931 {
932 /*
933 * Compute bias seconds after each trace buffer read.
934 * This helps resync timestamps with the system clock
935 * in the event of a system sleep.
936 */
937 l_usecs = (long long)(now / divisor);
938 secs = l_usecs / 1000000;
939 curr_time = time((long *)0);
940 bias_secs = curr_time - secs;
941 }
b51d5b5f 942
1815bff5
A
943
944 switch (type) {
945
b51d5b5f
A
946 case P_RdMeta:
947 case P_WrMeta:
948 case P_RdData:
949 case P_WrData:
950 case P_PgIn:
951 case P_PgOut:
952 case P_RdMetaAsync:
953 case P_WrMetaAsync:
954 case P_RdDataAsync:
955 case P_WrDataAsync:
956 case P_PgInAsync:
957 case P_PgOutAsync:
958 insert_diskio(type, kd[i].arg1, kd[i].arg2, kd[i].arg3, kd[i].arg4, thread, (double)now);
959 continue;
960
961 case P_RdMetaDone:
962 case P_WrMetaDone:
963 case P_RdDataDone:
964 case P_WrDataDone:
965 case P_PgInDone:
966 case P_PgOutDone:
967 case P_RdMetaAsyncDone:
968 case P_WrMetaAsyncDone:
969 case P_RdDataAsyncDone:
970 case P_WrDataAsyncDone:
971 case P_PgInAsyncDone:
972 case P_PgOutAsyncDone:
20e66415 973 if ((dio = complete_diskio(kd[i].arg1, kd[i].arg4, kd[i].arg3, thread, (double)now))) {
b51d5b5f
A
974 print_diskio(dio);
975 free_diskio(dio);
976 }
977 continue;
978
979
1815bff5 980 case TRACE_DATA_NEWTHREAD:
20e66415 981
1815bff5
A
982 for (n = 0, ti = th_state; ti < &th_state[MAX_THREADS]; ti++, n++) {
983 if (ti->thread == 0)
984 break;
985 }
986 if (ti == &th_state[MAX_THREADS])
987 continue;
988 if (n >= cur_max)
989 cur_max = n + 1;
990
991 ti->thread = thread;
992 ti->child_thread = kd[i].arg1;
20e66415 993 ti->pid = kd[i].arg2;
1815bff5
A
994 continue;
995
996 case TRACE_STRING_NEWTHREAD:
997 if ((ti = find_thread(thread, 0)) == (struct th_info *)0)
998 continue;
999 if (ti->child_thread == 0)
1000 continue;
20e66415 1001 create_map_entry(ti->child_thread, ti->pid, (char *)&kd[i].arg1);
1815bff5
A
1002
1003 if (ti == &th_state[cur_max - 1])
1004 cur_max--;
1005 ti->child_thread = 0;
1006 ti->thread = 0;
20e66415 1007 ti->pid = 0;
1815bff5 1008 continue;
20e66415
A
1009
1010 case TRACE_DATA_EXEC:
1011
1012 for (n = 0, ti = th_state; ti < &th_state[MAX_THREADS]; ti++, n++) {
1013 if (ti->thread == 0)
1014 break;
1015 }
1016 if (ti == &th_state[MAX_THREADS])
1017 continue;
1018 if (n >= cur_max)
1019 cur_max = n + 1;
1020
1021 ti->thread = thread;
1022 ti->pid = kd[i].arg1;
1023 continue;
1815bff5
A
1024
1025 case TRACE_STRING_EXEC:
20e66415
A
1026 if ((ti = find_thread(thread, 0)) == (struct th_info *)0)
1027 {
1028 /* this is for backwards compatibility */
1029 create_map_entry(thread, 0, (char *)&kd[i].arg1);
1030 }
1031 else
1032 {
1033 create_map_entry(thread, ti->pid, (char *)&kd[i].arg1);
1034 if (ti == &th_state[cur_max - 1])
1035 cur_max--;
1036 ti->thread = 0;
1037 ti->pid = 0;
1038 }
1815bff5
A
1039 continue;
1040
1041 case BSC_exit:
1042 kill_thread_map(thread);
1043 continue;
1044
1045 case MACH_sched:
1046 case MACH_stkhandoff:
b51d5b5f 1047 mark_thread_waited(thread);
1815bff5
A
1048 continue;
1049
1050 case VFS_LOOKUP:
1051 if ((ti = find_thread(thread, 0)) == (struct th_info *)0)
1052 continue;
1053
1c51fdde 1054 if (!ti->pathptr) {
1815bff5 1055 sargptr = (long *)&ti->pathname[0];
1c51fdde 1056 memset(&ti->pathname[0], 0, (PATHLENGTH + 1));
1815bff5
A
1057 *sargptr++ = kd[i].arg2;
1058 *sargptr++ = kd[i].arg3;
1059 *sargptr++ = kd[i].arg4;
1c51fdde 1060 ti->pathptr = sargptr;
1c51fdde
A
1061 } else {
1062 sargptr = ti->pathptr;
1063
1064 /*
1065 We don't want to overrun our pathname buffer if the
1066 kernel sends us more VFS_LOOKUP entries than we can
1067 handle.
1068 */
1069
1070 if ((long *)sargptr >= (long *)&ti->pathname[PATHLENGTH])
1071 continue;
1815bff5 1072
b51d5b5f
A
1073 /*
1074 We need to detect consecutive vfslookup entries.
1075 So, if we get here and find a START entry,
1076 fake the pathptr so we can bypass all further
1077 vfslookup entries.
1078 */
1079
1080 if (debugid & DBG_FUNC_START)
1081 {
1082 (long *)ti->pathptr = (long *)&ti->pathname[PATHLENGTH];
1083 continue;
1084 }
1085
1815bff5
A
1086 *sargptr++ = kd[i].arg1;
1087 *sargptr++ = kd[i].arg2;
1088 *sargptr++ = kd[i].arg3;
1089 *sargptr++ = kd[i].arg4;
1c51fdde 1090 ti->pathptr = sargptr;
1815bff5
A
1091 }
1092 continue;
1093 }
1815bff5
A
1094
1095 if (debugid & DBG_FUNC_START) {
1096 char *p;
1097
1098 switch (type) {
1099 case FILEMGR_PBGETCATALOGINFO:
1100 p = "GetCatalogInfo";
1101 break;
1102 case FILEMGR_PBGETCATALOGINFOBULK:
1103 p = "GetCatalogInfoBulk";
1104 break;
1105 case FILEMGR_PBCREATEFILEUNICODE:
1106 p = "CreateFileUnicode";
1107 break;
1108 case FILEMGR_PBCREATEDIRECTORYUNICODE:
1109 p = "CreateDirectoryUnicode";
1110 break;
1111 case FILEMGR_PBCREATEFORK:
1112 p = "PBCreateFork";
1113 break;
1114 case FILEMGR_PBDELETEFORK:
1115 p = "PBDeleteFork";
1116 break;
1117 case FILEMGR_PBITERATEFORK:
1118 p = "PBIterateFork";
1119 break;
1120 case FILEMGR_PBOPENFORK:
1121 p = "PBOpenFork";
1122 break;
1123 case FILEMGR_PBREADFORK:
1124 p = "PBReadFork";
1125 break;
1126 case FILEMGR_PBWRITEFORK:
1127 p = "PBWriteFork";
1128 break;
1129 case FILEMGR_PBALLOCATEFORK:
1130 p = "PBAllocateFork";
1131 break;
1132 case FILEMGR_PBDELETEOBJECT:
1133 p = "PBDeleteObject";
1134 break;
1135 case FILEMGR_PBEXCHANGEOBJECT:
1136 p = "PBExchangeObject";
1137 break;
1138 case FILEMGR_PBGETFORKCBINFO:
1139 p = "PBGetForkCBInfo";
1140 break;
1141 case FILEMGR_PBGETVOLUMEINFO:
1142 p = "PBGetVolumeInfo";
1143 break;
1144 case FILEMGR_PBMAKEFSREF:
1145 p = "PBMakeFSRef";
1146 break;
1147 case FILEMGR_PBMAKEFSREFUNICODE:
1148 p = "PBMakeFSRefUnicode";
1149 break;
1150 case FILEMGR_PBMOVEOBJECT:
1151 p = "PBMoveObject";
1152 break;
1153 case FILEMGR_PBOPENITERATOR:
1154 p = "PBOpenIterator";
1155 break;
1156 case FILEMGR_PBRENAMEUNICODE:
1157 p = "PBRenameUnicode";
1158 break;
1159 case FILEMGR_PBSETCATALOGINFO:
1160 p = "SetCatalogInfo";
1161 break;
1162 case FILEMGR_PBSETVOLUMEINFO:
1163 p = "SetVolumeInfo";
1164 break;
1165 case FILEMGR_FSREFMAKEPATH:
1166 p = "FSRefMakePath";
1167 break;
1168 case FILEMGR_FSPATHMAKEREF:
1169 p = "FSPathMakeRef";
1170 break;
1171 // SPEC based calls
1172 case FILEMGR_PBGETCATINFO:
1173 p = "GetCatInfo";
1174 break;
1175 case FILEMGR_PBGETCATINFOLITE:
1176 p = "GetCatInfoLite";
1177 break;
1178 case FILEMGR_PBHGETFINFO:
1179 p = "PBHGetFInfo";
1180 break;
1181 case FILEMGR_PBXGETVOLINFO:
1182 p = "PBXGetVolInfo";
1183 break;
1184 case FILEMGR_PBHCREATE:
1185 p = "PBHCreate";
1186 break;
1187 case FILEMGR_PBHOPENDF:
1188 p = "PBHOpenDF";
1189 break;
1190 case FILEMGR_PBHOPENRF:
1191 p = "PBHOpenRF";
1192 break;
1193 case FILEMGR_PBHGETDIRACCESS:
1194 p = "PBHGetDirAccess";
1195 break;
1196 case FILEMGR_PBHSETDIRACCESS:
1197 p = "PBHSetDirAccess";
1198 break;
1199 case FILEMGR_PBHMAPID:
1200 p = "PBHMapID";
1201 break;
1202 case FILEMGR_PBHMAPNAME:
1203 p = "PBHMapName";
1204 break;
1205 case FILEMGR_PBCLOSE:
1206 p = "PBClose";
1207 break;
1208 case FILEMGR_PBFLUSHFILE:
1209 p = "PBFlushFile";
1210 break;
1211 case FILEMGR_PBGETEOF:
1212 p = "PBGetEOF";
1213 break;
1214 case FILEMGR_PBSETEOF:
1215 p = "PBSetEOF";
1216 break;
1217 case FILEMGR_PBGETFPOS:
1218 p = "PBGetFPos";
1219 break;
1220 case FILEMGR_PBREAD:
1221 p = "PBRead";
1222 break;
1223 case FILEMGR_PBWRITE:
1224 p = "PBWrite";
1225 break;
1226 case FILEMGR_PBGETFCBINFO:
1227 p = "PBGetFCBInfo";
1228 break;
1229 case FILEMGR_PBSETFINFO:
1230 p = "PBSetFInfo";
1231 break;
1232 case FILEMGR_PBALLOCATE:
1233 p = "PBAllocate";
1234 break;
1235 case FILEMGR_PBALLOCCONTIG:
1236 p = "PBAllocContig";
1237 break;
1238 case FILEMGR_PBSETFPOS:
1239 p = "PBSetFPos";
1240 break;
1241 case FILEMGR_PBSETCATINFO:
1242 p = "PBSetCatInfo";
1243 break;
1244 case FILEMGR_PBGETVOLPARMS:
1245 p = "PBGetVolParms";
1246 break;
1247 case FILEMGR_PBSETVINFO:
1248 p = "PBSetVInfo";
1249 break;
1250 case FILEMGR_PBMAKEFSSPEC:
1251 p = "PBMakeFSSpec";
1252 break;
1253 case FILEMGR_PBHGETVINFO:
1254 p = "PBHGetVInfo";
1255 break;
1256 case FILEMGR_PBCREATEFILEIDREF:
1257 p = "PBCreateFileIDRef";
1258 break;
1259 case FILEMGR_PBDELETEFILEIDREF:
1260 p = "PBDeleteFileIDRef";
1261 break;
1262 case FILEMGR_PBRESOLVEFILEIDREF:
1263 p = "PBResolveFileIDRef";
1264 break;
1265 case FILEMGR_PBFLUSHVOL:
1266 p = "PBFlushVol";
1267 break;
1268 case FILEMGR_PBHRENAME:
1269 p = "PBHRename";
1270 break;
1271 case FILEMGR_PBCATMOVE:
1272 p = "PBCatMove";
1273 break;
1274 case FILEMGR_PBEXCHANGEFILES:
1275 p = "PBExchangeFiles";
1276 break;
1277 case FILEMGR_PBHDELETE:
1278 p = "PBHDelete";
1279 break;
1280 case FILEMGR_PBDIRCREATE:
1281 p = "PBDirCreate";
1282 break;
1283 case FILEMGR_PBCATSEARCH:
1284 p = "PBCatSearch";
1285 break;
1286 case FILEMGR_PBHSETFLOCK:
1287 p = "PBHSetFlock";
1288 break;
1289 case FILEMGR_PBHRSTFLOCK:
1290 p = "PBHRstFLock";
1291 break;
1292 case FILEMGR_PBLOCKRANGE:
1293 p = "PBLockRange";
1294 break;
1295 case FILEMGR_PBUNLOCKRANGE:
1296 p = "PBUnlockRange";
1297 break;
1298 default:
1299 p = (char *)0;
1300 break;
1301 }
1302 enter_syscall(thread, type, &kd[i], p, (double)now);
1303 continue;
1304 }
c3a08f59 1305
1815bff5 1306 switch (type) {
c3a08f59
A
1307
1308 case BSC_pread_extended:
1309 case BSC_pwrite_extended:
1310 extend_syscall(thread, type, &kd[i], (double)now);
1815bff5 1311
b51d5b5f
A
1312 case MACH_pageout:
1313 if (kd[i].arg2)
1314 exit_syscall("PAGE_OUT_D", thread, type, 0, kd[i].arg1, 0, 4, (double)now);
1315 else
1316 exit_syscall("PAGE_OUT_V", thread, type, 0, kd[i].arg1, 0, 4, (double)now);
1317 break;
1318
1815bff5
A
1319 case MACH_vmfault:
1320 if (kd[i].arg2 == DBG_PAGEIN_FAULT)
b51d5b5f
A
1321 exit_syscall("PAGE_IN", thread, type, kd[i].arg4, kd[i].arg1, 0, 6, (double)now);
1322 else if (kd[i].arg2 == DBG_CACHE_HIT_FAULT)
1323 exit_syscall("CACHE_HIT", thread, type, 0, kd[i].arg1, 0, 2, (double)now);
1815bff5 1324 else {
20e66415 1325 if ((ti = find_thread(thread, type))) {
1815bff5
A
1326 if (ti == &th_state[cur_max - 1])
1327 cur_max--;
1328 ti->thread = 0;
1329 }
1330 }
1331 break;
1332
1333 case MSC_map_fd:
1334 exit_syscall("map_fd", thread, type, kd[i].arg1, kd[i].arg2, 1, 0, (double)now);
1335 break;
1336
1337 case BSC_mmap:
1338 exit_syscall("mmap", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1339 break;
20e66415 1340
1815bff5
A
1341 case BSC_recvmsg:
1342 exit_syscall("recvmsg", thread, type, kd[i].arg1, kd[i].arg2, 1, 1, (double)now);
1343 break;
1344
1345 case BSC_sendmsg:
1346 exit_syscall("sendmsg", thread, type, kd[i].arg1, kd[i].arg2, 1, 1, (double)now);
1347 break;
1348
1349 case BSC_recvfrom:
1350 exit_syscall("recvfrom", thread, type, kd[i].arg1, kd[i].arg2, 1, 1, (double)now);
1351 break;
1352
20e66415
A
1353 case BSC_accept:
1354 exit_syscall("accept", thread, type, kd[i].arg1, kd[i].arg2, 2, 0, (double)now);
1355 break;
1356
1357 case BSC_select:
1358 exit_syscall("select", thread, type, kd[i].arg1, kd[i].arg2, 0, 8, (double)now);
1359 break;
1360
1361 case BSC_socket:
1362 exit_syscall("socket", thread, type, kd[i].arg1, kd[i].arg2, 2, 0, (double)now);
1363 break;
1364
1365 case BSC_connect:
1366 exit_syscall("connect", thread, type, kd[i].arg1, kd[i].arg2, 1, 0, (double)now);
1367 break;
1368
1369 case BSC_bind:
1370 exit_syscall("bind", thread, type, kd[i].arg1, kd[i].arg2, 1, 0, (double)now);
1371 break;
1372
1373 case BSC_listen:
1374 exit_syscall("listen", thread, type, kd[i].arg1, kd[i].arg2, 1, 0, (double)now);
1375 break;
1376
1815bff5
A
1377 case BSC_sendto:
1378 exit_syscall("sendto", thread, type, kd[i].arg1, kd[i].arg2, 1, 1, (double)now);
1379 break;
1380
20e66415
A
1381 case BSC_socketpair:
1382 exit_syscall("socketpair", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1383 break;
1384
1815bff5
A
1385 case BSC_stat:
1386 exit_syscall("stat", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1387 break;
b51d5b5f
A
1388
1389 case BSC_load_shared_file:
1390 exit_syscall("load_sf", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1391 break;
1815bff5
A
1392
1393 case BSC_open:
1394 exit_syscall("open", thread, type, kd[i].arg1, kd[i].arg2, 2, 0, (double)now);
1395 break;
1396
20e66415
A
1397 case BSC_dup:
1398 exit_syscall("dup", thread, type, kd[i].arg1, kd[i].arg2, 2, 0, (double)now);
1399 break;
1400
1401 case BSC_dup2:
1402 exit_syscall("dup2", thread, type, kd[i].arg1, kd[i].arg2, 2, 0, (double)now);
1403 break;
1404
1815bff5
A
1405 case BSC_close:
1406 exit_syscall("close", thread, type, kd[i].arg1, kd[i].arg2, 1, 0, (double)now);
1407 break;
1408
1409 case BSC_read:
1410 exit_syscall("read", thread, type, kd[i].arg1, kd[i].arg2, 1, 1, (double)now);
1411 break;
1412
1413 case BSC_write:
1414 exit_syscall("write", thread, type, kd[i].arg1, kd[i].arg2, 1, 1, (double)now);
1415 break;
1416
1417 case BSC_fstat:
1418 exit_syscall("fstat", thread, type, kd[i].arg1, kd[i].arg2, 1, 0, (double)now);
1419 break;
1420
1421 case BSC_lstat:
1422 exit_syscall("lstat", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1423 break;
1424
1425 case BSC_link:
1426 exit_syscall("link", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1427 break;
1428
1429 case BSC_unlink:
1430 exit_syscall("unlink", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1431 break;
1432
1433 case BSC_mknod:
1434 exit_syscall("mknod", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1435 break;
1436
1437 case BSC_chmod:
1438 exit_syscall("chmod", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1439 break;
1440
1441 case BSC_chown:
1442 exit_syscall("chown", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1443 break;
1444
1445 case BSC_access:
1446 exit_syscall("access", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1447 break;
1448
b51d5b5f
A
1449 case BSC_chdir:
1450 exit_syscall("chdir", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1451 break;
1452
1453 case BSC_chroot:
1454 exit_syscall("chroot", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1455 break;
1456
1457 case BSC_utimes:
1458 exit_syscall("utimes", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1459 break;
1460
1461 case BSC_delete:
1462 exit_syscall("delete", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1463 break;
1464
1465 case BSC_undelete:
1466 exit_syscall("undelete", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1467 break;
1468
1469 case BSC_revoke:
1470 exit_syscall("revoke", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1471 break;
1472
1473 case BSC_fsctl:
1474 exit_syscall("fsctl", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1475 break;
1476
1815bff5
A
1477 case BSC_chflags:
1478 exit_syscall("chflags", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1479 break;
b51d5b5f 1480
1815bff5
A
1481 case BSC_fchflags:
1482 exit_syscall("fchflags", thread, type, kd[i].arg1, kd[i].arg2, 1, 0, (double)now);
1483 break;
b51d5b5f
A
1484
1485 case BSC_fchdir:
1486 exit_syscall("fchdir", thread, type, kd[i].arg1, kd[i].arg2, 1, 0, (double)now);
1487 break;
1488
1489 case BSC_futimes:
1490 exit_syscall("futimes", thread, type, kd[i].arg1, kd[i].arg2, 1, 0, (double)now);
1491 break;
1815bff5
A
1492
1493 case BSC_sync:
1494 exit_syscall("sync", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1495 break;
1496
1497 case BSC_symlink:
1498 exit_syscall("symlink", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1499 break;
1500
1501 case BSC_readlink:
1502 exit_syscall("readlink", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1503 break;
1504
1505 case BSC_fsync:
1506 exit_syscall("fsync", thread, type, kd[i].arg1, kd[i].arg2, 1, 0, (double)now);
1507 break;
1508
1509 case BSC_readv:
1510 exit_syscall("readv", thread, type, kd[i].arg1, kd[i].arg2, 1, 1, (double)now);
1511 break;
1512
1513 case BSC_writev:
1514 exit_syscall("writev", thread, type, kd[i].arg1, kd[i].arg2, 1, 1, (double)now);
1515 break;
1516
c3a08f59
A
1517 case BSC_pread:
1518 exit_syscall("pread", thread, type, kd[i].arg1, kd[i].arg2, 1, 9, (double)now);
1519 break;
1520
1521 case BSC_pwrite:
1522 exit_syscall("pwrite", thread, type, kd[i].arg1, kd[i].arg2, 1, 9, (double)now);
1523 break;
1524
1815bff5
A
1525 case BSC_fchown:
1526 exit_syscall("fchown", thread, type, kd[i].arg1, kd[i].arg2, 1, 0, (double)now);
1527 break;
1528
1529 case BSC_fchmod:
1530 exit_syscall("fchmod", thread, type, kd[i].arg1, kd[i].arg2, 1, 0, (double)now);
1531 break;
1532
1815bff5
A
1533 case BSC_mkdir:
1534 exit_syscall("mkdir", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1535 break;
b51d5b5f
A
1536
1537 case BSC_mkfifo:
1538 exit_syscall("mkfifo", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1539 break;
1815bff5
A
1540
1541 case BSC_rmdir:
1542 exit_syscall("rmdir", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1543 break;
1544
1545 case BSC_statfs:
1546 exit_syscall("statfs", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1547 break;
1548
1549 case BSC_fstatfs:
1550 exit_syscall("fstatfs", thread, type, kd[i].arg1, kd[i].arg2, 1, 0, (double)now);
1551 break;
1552
1553 case BSC_pathconf:
1554 exit_syscall("pathconf", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1555 break;
1556
1557 case BSC_fpathconf:
1558 exit_syscall("fpathconf", thread, type, kd[i].arg1, kd[i].arg2, 1, 0, (double)now);
1559 break;
1560
1561 case BSC_getdirentries:
1562 exit_syscall("getdirentries", thread, type, kd[i].arg1, kd[i].arg2, 1, 1, (double)now);
1563 break;
1564
1565 case BSC_lseek:
1566 exit_syscall("lseek", thread, type, kd[i].arg1, kd[i].arg3, 1, 5, (double)now);
1567 break;
1568
1569 case BSC_truncate:
1570 exit_syscall("truncate", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1571 break;
1572
1573 case BSC_ftruncate:
1574 exit_syscall("ftruncate", thread, type, kd[i].arg1, kd[i].arg2, 1, 3, (double)now);
1575 break;
1576
1577 case BSC_statv:
1578 exit_syscall("statv", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1579 break;
1580
1581 case BSC_lstatv:
1582 exit_syscall("lstatv", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1583 break;
1584
1585 case BSC_fstatv:
1586 exit_syscall("fstatv", thread, type, kd[i].arg1, kd[i].arg2, 1, 0, (double)now);
1587 break;
1588
1589 case BSC_mkcomplex:
1590 exit_syscall("mkcomplex", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1591 break;
1592
1593 case BSC_getattrlist:
1594 exit_syscall("getattrlist", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1595 break;
1596
1597 case BSC_setattrlist:
1598 exit_syscall("setattrlist", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1599 break;
1600
1601 case BSC_getdirentriesattr:
1602 exit_syscall("getdirentriesattr", thread, type, kd[i].arg1, kd[i].arg2, 0, 1, (double)now);
1603 break;
1604
b51d5b5f 1605
1815bff5
A
1606 case BSC_exchangedata:
1607 exit_syscall("exchangedata", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1608 break;
b51d5b5f
A
1609
1610 case BSC_rename:
1611 exit_syscall("rename", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1612 break;
1613
1614 case BSC_copyfile:
1615 exit_syscall("copyfile", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1616 break;
1617
1815bff5
A
1618
1619 case BSC_checkuseraccess:
1620 exit_syscall("checkuseraccess", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1621 break;
1622
1623 case BSC_searchfs:
1624 exit_syscall("searchfs", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1625 break;
1626
1627 case FILEMGR_PBGETCATALOGINFO:
1628 exit_syscall("GetCatalogInfo", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1629 break;
1630 case FILEMGR_PBGETCATALOGINFOBULK:
1631 exit_syscall("GetCatalogInfoBulk", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1632 break;
1633 case FILEMGR_PBCREATEFILEUNICODE:
1634 exit_syscall("CreateFileUnicode", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1635 break;
1636 case FILEMGR_PBCREATEDIRECTORYUNICODE:
1637 exit_syscall("CreateDirectoryUnicode", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1638 break;
1639 case FILEMGR_PBCREATEFORK:
1640 exit_syscall("PBCreateFork", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1641 break;
1642 case FILEMGR_PBDELETEFORK:
1643 exit_syscall("PBDeleteFork", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1644 break;
1645 case FILEMGR_PBITERATEFORK:
1646 exit_syscall("PBIterateFork", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1647 break;
1648 case FILEMGR_PBOPENFORK:
1649 exit_syscall("PBOpenFork", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1650 break;
1651 case FILEMGR_PBREADFORK:
1652 exit_syscall("PBReadFork", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1653 break;
1654 case FILEMGR_PBWRITEFORK:
1655 exit_syscall("PBWriteFork", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1656 break;
1657 case FILEMGR_PBALLOCATEFORK:
1658 exit_syscall("PBAllocateFork", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1659 break;
1660 case FILEMGR_PBDELETEOBJECT:
1661 exit_syscall("PBDeleteObject", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1662 break;
1663 case FILEMGR_PBEXCHANGEOBJECT:
1664 exit_syscall("PBExchangeObject", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1665 break;
1666 case FILEMGR_PBGETFORKCBINFO:
1667 exit_syscall("PBGetForkCBInfo", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1668 break;
1669 case FILEMGR_PBGETVOLUMEINFO:
1670 exit_syscall("PBGetVolumeInfo", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1671 break;
1672 case FILEMGR_PBMAKEFSREF:
1673 exit_syscall("PBMakeFSRef", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1674 break;
1675 case FILEMGR_PBMAKEFSREFUNICODE:
1676 exit_syscall("PBMakeFSRefUnicode", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1677 break;
1678 case FILEMGR_PBMOVEOBJECT:
1679 exit_syscall("PBMoveObject", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1680 break;
1681 case FILEMGR_PBOPENITERATOR:
1682 exit_syscall("PBOpenIterator", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1683 break;
1684 case FILEMGR_PBRENAMEUNICODE:
1685 exit_syscall("PBRenameUnicode", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1686 break;
1687 case FILEMGR_PBSETCATALOGINFO:
1688 exit_syscall("PBSetCatalogInfo", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1689 break;
1690 case FILEMGR_PBSETVOLUMEINFO:
1691 exit_syscall("PBSetVolumeInfo", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1692 break;
1693 case FILEMGR_FSREFMAKEPATH:
1694 exit_syscall("FSRefMakePath", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1695 break;
1696 case FILEMGR_FSPATHMAKEREF:
1697 exit_syscall("FSPathMakeRef", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1698 break;
1699 case FILEMGR_PBGETCATINFO:
1700 exit_syscall("GetCatInfo", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1701 break;
1702 case FILEMGR_PBGETCATINFOLITE:
1703 exit_syscall("GetCatInfoLite", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1704 break;
1705 case FILEMGR_PBHGETFINFO:
1706 exit_syscall("PBHGetFInfo", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1707 break;
1708 case FILEMGR_PBXGETVOLINFO:
1709 exit_syscall("PBXGetVolInfo", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1710 break;
1711 case FILEMGR_PBHCREATE:
1712 exit_syscall("PBHCreate", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1713 break;
1714 case FILEMGR_PBHOPENDF:
1715 exit_syscall("PBHOpenDF", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1716 break;
1717 case FILEMGR_PBHOPENRF:
1718 exit_syscall("PBHOpenRF", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1719 break;
1720 case FILEMGR_PBHGETDIRACCESS:
1721 exit_syscall("PBHGetDirAccess", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1722 break;
1723 case FILEMGR_PBHSETDIRACCESS:
1724 exit_syscall("PBHSetDirAccess", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1725 break;
1726 case FILEMGR_PBHMAPID:
1727 exit_syscall("PBHMapID", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1728 break;
1729 case FILEMGR_PBHMAPNAME:
1730 exit_syscall("PBHMapName", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1731 break;
1732 case FILEMGR_PBCLOSE:
1733 exit_syscall("PBClose", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1734 break;
1735 case FILEMGR_PBFLUSHFILE:
1736 exit_syscall("PBFlushFile", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1737 break;
1738 case FILEMGR_PBGETEOF:
1739 exit_syscall("PBGetEOF", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1740 break;
1741 case FILEMGR_PBSETEOF:
1742 exit_syscall("PBSetEOF", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1743 break;
1744 case FILEMGR_PBGETFPOS:
1745 exit_syscall("PBGetFPos", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1746 break;
1747 case FILEMGR_PBREAD:
1748 exit_syscall("PBRead", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1749 break;
1750 case FILEMGR_PBWRITE:
1751 exit_syscall("PBWrite", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1752 break;
1753 case FILEMGR_PBGETFCBINFO:
1754 exit_syscall("PBGetFCBInfo", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1755 break;
1756 case FILEMGR_PBSETFINFO:
1757 exit_syscall("PBSetFInfo", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1758 break;
1759 case FILEMGR_PBALLOCATE:
1760 exit_syscall("PBAllocate", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1761 break;
1762 case FILEMGR_PBALLOCCONTIG:
1763 exit_syscall("PBAllocContig", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1764 break;
1765 case FILEMGR_PBSETFPOS:
1766 exit_syscall("PBSetFPos", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1767 break;
1768 case FILEMGR_PBSETCATINFO:
1769 exit_syscall("PBSetCatInfo", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1770 break;
1771 case FILEMGR_PBGETVOLPARMS:
1772 exit_syscall("PBGetVolParms", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1773 break;
1774 case FILEMGR_PBSETVINFO:
1775 exit_syscall("PBSetVInfo", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1776 break;
1777 case FILEMGR_PBMAKEFSSPEC:
1778 exit_syscall("PBMakeFSSpec", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1779 break;
1780 case FILEMGR_PBHGETVINFO:
1781 exit_syscall("PBHGetVInfo", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1782 break;
1783 case FILEMGR_PBCREATEFILEIDREF:
1784 exit_syscall("PBCreateFileIDRef", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1785 break;
1786 case FILEMGR_PBDELETEFILEIDREF:
1787 exit_syscall("PBDeleteFileIDRef", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1788 break;
1789 case FILEMGR_PBRESOLVEFILEIDREF:
1790 exit_syscall("PBResolveFileIDRef", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1791 break;
1792 case FILEMGR_PBFLUSHVOL:
1793 exit_syscall("PBFlushVol", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1794 break;
1795 case FILEMGR_PBHRENAME:
1796 exit_syscall("PBHRename", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1797 break;
1798 case FILEMGR_PBCATMOVE:
1799 exit_syscall("PBCatMove", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1800 break;
1801 case FILEMGR_PBEXCHANGEFILES:
1802 exit_syscall("PBExchangeFiles", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1803 break;
1804 case FILEMGR_PBHDELETE:
1805 exit_syscall("PBHDelete", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1806 break;
1807 case FILEMGR_PBDIRCREATE:
1808 exit_syscall("PBDirCreate", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1809 break;
1810 case FILEMGR_PBCATSEARCH:
1811 exit_syscall("PBCatSearch", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1812 break;
1813 case FILEMGR_PBHSETFLOCK:
1814 exit_syscall("PBHSetFLock", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1815 break;
1816 case FILEMGR_PBHRSTFLOCK:
1817 exit_syscall("PBHRstFLock", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1818 break;
1819 case FILEMGR_PBLOCKRANGE:
1820 exit_syscall("PBLockRange", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1821 break;
1822 case FILEMGR_PBUNLOCKRANGE:
1823 exit_syscall("PBUnlockRange", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1824 break;
1825 default:
1826 break;
1827 }
1828 }
1829 fflush(0);
1830}
1831
1832void
1833enter_syscall(int thread, int type, kd_buf *kd, char *name, double now)
1834{
1835 struct th_info *ti;
1836 int i;
1837 int secs;
1838 int usecs;
1839 long long l_usecs;
1840 long curr_time;
1c51fdde
A
1841 kd_threadmap *map;
1842 kd_threadmap *find_thread_map();
1843 int clen = 0;
1844 int tsclen = 0;
1845 int nmclen = 0;
1846 int argsclen = 0;
1847 char buf[MAXCOLS];
1815bff5
A
1848
1849 switch (type) {
1850
b51d5b5f 1851 case MACH_pageout:
1815bff5
A
1852 case MACH_vmfault:
1853 case MSC_map_fd:
1854 case BSC_mmap:
1855 case BSC_recvmsg:
1856 case BSC_sendmsg:
1857 case BSC_recvfrom:
20e66415
A
1858 case BSC_accept:
1859 case BSC_select:
1860 case BSC_socket:
1861 case BSC_connect:
1862 case BSC_bind:
1863 case BSC_listen:
1815bff5 1864 case BSC_sendto:
20e66415 1865 case BSC_socketpair:
1815bff5 1866 case BSC_stat:
b51d5b5f 1867 case BSC_load_shared_file:
1815bff5 1868 case BSC_open:
20e66415
A
1869 case BSC_dup:
1870 case BSC_dup2:
1815bff5
A
1871 case BSC_close:
1872 case BSC_read:
1873 case BSC_write:
1874 case BSC_fstat:
1875 case BSC_lstat:
1876 case BSC_link:
1877 case BSC_unlink:
1878 case BSC_mknod:
1879 case BSC_chmod:
1880 case BSC_chown:
1881 case BSC_access:
1882 case BSC_chflags:
1883 case BSC_fchflags:
b51d5b5f
A
1884 case BSC_fchdir:
1885 case BSC_futimes:
1886 case BSC_chdir:
1887 case BSC_utimes:
1888 case BSC_chroot:
1889 case BSC_undelete:
1890 case BSC_delete:
1891 case BSC_revoke:
1892 case BSC_fsctl:
1893 case BSC_copyfile:
1815bff5
A
1894 case BSC_sync:
1895 case BSC_symlink:
1896 case BSC_readlink:
1897 case BSC_fsync:
1898 case BSC_readv:
1899 case BSC_writev:
c3a08f59
A
1900 case BSC_pread:
1901 case BSC_pwrite:
1815bff5
A
1902 case BSC_fchown:
1903 case BSC_fchmod:
1904 case BSC_rename:
1905 case BSC_mkdir:
b51d5b5f 1906 case BSC_mkfifo:
1815bff5
A
1907 case BSC_rmdir:
1908 case BSC_statfs:
1909 case BSC_fstatfs:
1910 case BSC_pathconf:
1911 case BSC_fpathconf:
1912 case BSC_getdirentries:
1913 case BSC_lseek:
1914 case BSC_truncate:
1915 case BSC_ftruncate:
1916 case BSC_statv:
1917 case BSC_lstatv:
1918 case BSC_fstatv:
1919 case BSC_mkcomplex:
1920 case BSC_getattrlist:
1921 case BSC_setattrlist:
1922 case BSC_getdirentriesattr:
1923 case BSC_exchangedata:
1924 case BSC_checkuseraccess:
1925 case BSC_searchfs:
1926 case FILEMGR_PBGETCATALOGINFO:
1927 case FILEMGR_PBGETCATALOGINFOBULK:
1928 case FILEMGR_PBCREATEFILEUNICODE:
1929 case FILEMGR_PBCREATEDIRECTORYUNICODE:
1930 case FILEMGR_PBCREATEFORK:
1931 case FILEMGR_PBDELETEFORK:
1932 case FILEMGR_PBITERATEFORK:
1933 case FILEMGR_PBOPENFORK:
1934 case FILEMGR_PBREADFORK:
1935 case FILEMGR_PBWRITEFORK:
1936 case FILEMGR_PBALLOCATEFORK:
1937 case FILEMGR_PBDELETEOBJECT:
1938 case FILEMGR_PBEXCHANGEOBJECT:
1939 case FILEMGR_PBGETFORKCBINFO:
1940 case FILEMGR_PBGETVOLUMEINFO:
1941 case FILEMGR_PBMAKEFSREF:
1942 case FILEMGR_PBMAKEFSREFUNICODE:
1943 case FILEMGR_PBMOVEOBJECT:
1944 case FILEMGR_PBOPENITERATOR:
1945 case FILEMGR_PBRENAMEUNICODE:
1946 case FILEMGR_PBSETCATALOGINFO:
1947 case FILEMGR_PBSETVOLUMEINFO:
1948 case FILEMGR_FSREFMAKEPATH:
1949 case FILEMGR_FSPATHMAKEREF:
1950
1951 case FILEMGR_PBGETCATINFO:
1952 case FILEMGR_PBGETCATINFOLITE:
1953 case FILEMGR_PBHGETFINFO:
1954 case FILEMGR_PBXGETVOLINFO:
1955 case FILEMGR_PBHCREATE:
1956 case FILEMGR_PBHOPENDF:
1957 case FILEMGR_PBHOPENRF:
1958 case FILEMGR_PBHGETDIRACCESS:
1959 case FILEMGR_PBHSETDIRACCESS:
1960 case FILEMGR_PBHMAPID:
1961 case FILEMGR_PBHMAPNAME:
1962 case FILEMGR_PBCLOSE:
1963 case FILEMGR_PBFLUSHFILE:
1964 case FILEMGR_PBGETEOF:
1965 case FILEMGR_PBSETEOF:
1966 case FILEMGR_PBGETFPOS:
1967 case FILEMGR_PBREAD:
1968 case FILEMGR_PBWRITE:
1969 case FILEMGR_PBGETFCBINFO:
1970 case FILEMGR_PBSETFINFO:
1971 case FILEMGR_PBALLOCATE:
1972 case FILEMGR_PBALLOCCONTIG:
1973 case FILEMGR_PBSETFPOS:
1974 case FILEMGR_PBSETCATINFO:
1975 case FILEMGR_PBGETVOLPARMS:
1976 case FILEMGR_PBSETVINFO:
1977 case FILEMGR_PBMAKEFSSPEC:
1978 case FILEMGR_PBHGETVINFO:
1979 case FILEMGR_PBCREATEFILEIDREF:
1980 case FILEMGR_PBDELETEFILEIDREF:
1981 case FILEMGR_PBRESOLVEFILEIDREF:
1982 case FILEMGR_PBFLUSHVOL:
1983 case FILEMGR_PBHRENAME:
1984 case FILEMGR_PBCATMOVE:
1985 case FILEMGR_PBEXCHANGEFILES:
1986 case FILEMGR_PBHDELETE:
1987 case FILEMGR_PBDIRCREATE:
1988 case FILEMGR_PBCATSEARCH:
1989 case FILEMGR_PBHSETFLOCK:
1990 case FILEMGR_PBHRSTFLOCK:
1991 case FILEMGR_PBLOCKRANGE:
1992 case FILEMGR_PBUNLOCKRANGE:
1993
1994
1995 for (i = 0, ti = th_state; ti < &th_state[MAX_THREADS]; ti++, i++) {
1996 if (ti->thread == 0)
1997 break;
1998 }
1999 if (ti == &th_state[MAX_THREADS])
2000 return;
2001 if (i >= cur_max)
2002 cur_max = i + 1;
b51d5b5f 2003
1815bff5
A
2004
2005 if ((type >> 24) == FILEMGR_CLASS) {
2006 ti->in_filemgr = 1;
2007
2008 l_usecs = (long long)(now / divisor);
2009 secs = l_usecs / 1000000;
1815bff5 2010 curr_time = bias_secs + secs;
20e66415 2011
1c51fdde
A
2012 sprintf(buf, "%-8.8s", &(ctime(&curr_time)[11]));
2013 tsclen = strlen(buf);
1815bff5 2014
b51d5b5f 2015 if (columns > MAXCOLS || wideflag) {
1815bff5 2016 usecs = l_usecs - (long long)((long long)secs * 1000000);
1c51fdde
A
2017 sprintf(&buf[tsclen], ".%03ld", (long)usecs / 1000);
2018 tsclen = strlen(buf);
1815bff5 2019 }
1815bff5 2020
1c51fdde 2021 /* Print timestamp column */
d904471c 2022 printf("%s", buf);
1815bff5 2023
1c51fdde
A
2024 map = find_thread_map(thread);
2025 if (map) {
2026 sprintf(buf, " %-25.25s ", name);
2027 nmclen = strlen(buf);
d904471c 2028 printf("%s", buf);
1815bff5 2029
1c51fdde
A
2030 sprintf(buf, "(%d, 0x%x, 0x%x, 0x%x)", (short)kd->arg1, kd->arg2, kd->arg3, kd->arg4);
2031 argsclen = strlen(buf);
2032
2033 /*
2034 Calculate white space out to command
2035 */
b51d5b5f 2036 if (columns > MAXCOLS || wideflag)
1c51fdde 2037 {
b51d5b5f 2038 clen = columns - (tsclen + nmclen + argsclen + 20);
1c51fdde
A
2039 }
2040 else
b51d5b5f 2041 clen = columns - (tsclen + nmclen + argsclen + 12);
1c51fdde
A
2042
2043 if(clen > 0)
2044 {
d904471c 2045 printf("%s", buf); /* print the kdargs */
1c51fdde
A
2046 memset(buf, ' ', clen);
2047 buf[clen] = '\0';
d904471c 2048 printf("%s", buf);
1c51fdde
A
2049 }
2050 else if ((argsclen + clen) > 0)
2051 {
2052 /* no room so wipe out the kdargs */
2053 memset(buf, ' ', (argsclen + clen));
2054 buf[argsclen + clen] = '\0';
d904471c 2055 printf("%s", buf);
1c51fdde
A
2056 }
2057
b51d5b5f 2058 if (columns > MAXCOLS || wideflag)
1c51fdde
A
2059 printf("%-20.20s\n", map->command);
2060 else
2061 printf("%-12.12s\n", map->command);
1815bff5
A
2062 } else
2063 printf(" %-24.24s (%5d, %#x, 0x%x, 0x%x)\n", name, (short)kd->arg1, kd->arg2, kd->arg3, kd->arg4);
1815bff5
A
2064 } else {
2065 ti->in_filemgr = 0;
2066 }
2067 ti->thread = thread;
1815bff5
A
2068 ti->waited = 0;
2069 ti->type = type;
2070 ti->stime = now;
2071 ti->arg1 = kd->arg1;
2072 ti->arg2 = kd->arg2;
2073 ti->arg3 = kd->arg3;
2074 ti->arg4 = kd->arg4;
1c51fdde 2075 ti->pathptr = (long *)0;
1815bff5 2076 ti->pathname[0] = 0;
1815bff5
A
2077 break;
2078
2079 default:
2080 break;
2081 }
1c51fdde 2082 fflush (0);
1815bff5
A
2083}
2084
c3a08f59
A
2085/*
2086 * Handle system call extended trace data.
2087 * pread and pwrite:
2088 * Wipe out the kd args that were collected upon syscall_entry
2089 * because it is the extended info that we really want, and it
2090 * is all we really need.
2091*/
2092
2093void
2094extend_syscall(int thread, int type, kd_buf *kd, char *name, double now)
2095{
2096 struct th_info *ti;
2097
2098 switch (type) {
2099 case BSC_pread_extended:
2100 if ((ti = find_thread(thread, BSC_pread)) == (struct th_info *)0)
2101 return;
2102 ti->arg1 = kd->arg1; /* the fd */
2103 ti->arg2 = kd->arg2; /* nbytes */
2104 ti->arg3 = kd->arg3; /* top half offset */
2105 ti->arg4 = kd->arg4; /* bottom half offset */
2106 break;
2107 case BSC_pwrite_extended:
2108 if ((ti = find_thread(thread, BSC_pwrite)) == (struct th_info *)0)
2109 return;
2110 ti->arg1 = kd->arg1; /* the fd */
2111 ti->arg2 = kd->arg2; /* nbytes */
2112 ti->arg3 = kd->arg3; /* top half offset */
2113 ti->arg4 = kd->arg4; /* bottom half offset */
2114 break;
2115 default:
2116 return;
2117 }
2118}
1815bff5
A
2119
2120void
2121exit_syscall(char *sc_name, int thread, int type, int error, int retval,
2122 int has_fd, int has_ret, double now)
2123{
b51d5b5f
A
2124 struct th_info *ti;
2125
2126 if ((ti = find_thread(thread, type)) == (struct th_info *)0)
2127 return;
20e66415
A
2128
2129 if (check_filter_mode(ti, type, error, retval))
2130 format_print(ti, sc_name, thread, type, error, retval, has_fd, has_ret, now, ti->stime, ti->waited, ti->pathname, NULL);
b51d5b5f
A
2131
2132 if (ti == &th_state[cur_max - 1])
2133 cur_max--;
2134 ti->thread = 0;
2135}
2136
2137
2138
2139void
2140format_print(struct th_info *ti, char *sc_name, int thread, int type, int error, int retval,
2141 int has_fd, int has_ret, double now, double stime, int waited, char *pathname, struct diskio *dio)
2142{
1815bff5
A
2143 int secs;
2144 int usecs;
2145 int nopadding;
2146 long long l_usecs;
2147 long curr_time;
b51d5b5f 2148 char *command_name;
1815bff5
A
2149 kd_threadmap *map;
2150 kd_threadmap *find_thread_map();
1c51fdde
A
2151 int len = 0;
2152 int clen = 0;
b51d5b5f 2153 char *framework_name;
1c51fdde 2154 char buf[MAXCOLS];
1815bff5 2155
b51d5b5f
A
2156 command_name = "";
2157
2158 if (dio)
2159 command_name = dio->issuing_command;
2160 else {
20e66415 2161 if ((map = find_thread_map(thread)))
b51d5b5f
A
2162 command_name = map->command;
2163 }
20e66415 2164
1815bff5
A
2165 l_usecs = (long long)(now / divisor);
2166 secs = l_usecs / 1000000;
1815bff5 2167 curr_time = bias_secs + secs;
1c51fdde
A
2168 sprintf(buf, "%-8.8s", &(ctime(&curr_time)[11]));
2169 clen = strlen(buf);
1815bff5 2170
b51d5b5f 2171 if (columns > MAXCOLS || wideflag) {
1815bff5
A
2172 nopadding = 0;
2173 usecs = l_usecs - (long long)((long long)secs * 1000000);
1c51fdde
A
2174 sprintf(&buf[clen], ".%03ld", (long)usecs / 1000);
2175 clen = strlen(buf);
b51d5b5f 2176
1815bff5
A
2177 if ((type >> 24) != FILEMGR_CLASS) {
2178 if (find_thread(thread, -1)) {
1c51fdde
A
2179 sprintf(&buf[clen], " ");
2180 clen = strlen(buf);
1815bff5
A
2181 nopadding = 1;
2182 }
2183 }
2184 } else
2185 nopadding = 1;
2186
b51d5b5f 2187 if (((type >> 24) == FILEMGR_CLASS) && (columns > MAXCOLS || wideflag))
1c51fdde 2188 sprintf(&buf[clen], " %-18.18s", sc_name);
1815bff5 2189 else
1c51fdde 2190 sprintf(&buf[clen], " %-15.15s", sc_name);
1815bff5 2191
1c51fdde 2192 clen = strlen(buf);
b51d5b5f
A
2193
2194 framework_name = (char *)0;
2195
2196 if (columns > MAXCOLS || wideflag) {
2197 if (has_ret == 7) {
2198 sprintf(&buf[clen], " D=0x%8.8x", dio->blkno);
2199
2200 clen = strlen(buf);
2201
2202 if (dio->io_errno)
2203 sprintf(&buf[clen], " [%3d] ", dio->io_errno);
2204 else
2205 sprintf(&buf[clen], " B=0x%-6x /dev/%s", dio->iosize, find_disk_name(dio->dev));
2206 } else {
c3a08f59
A
2207
2208 off_t offset_reassembled = 0LL;
2209
1815bff5 2210 if (has_fd == 2 && error == 0)
1c51fdde 2211 sprintf(&buf[clen], " F=%-3d", retval);
1815bff5 2212 else if (has_fd == 1)
1c51fdde 2213 sprintf(&buf[clen], " F=%-3d", ti->arg1);
b51d5b5f 2214 else if (has_ret != 2 && has_ret != 6)
1c51fdde
A
2215 sprintf(&buf[clen], " ");
2216
2217 clen = strlen(buf);
1815bff5 2218
b51d5b5f
A
2219 if (has_ret == 2 || has_ret == 6)
2220 framework_name = lookup_name(retval);
2221
2222 if (error && has_ret != 6)
1c51fdde 2223 sprintf(&buf[clen], "[%3d] ", error);
1815bff5 2224 else if (has_ret == 3)
1c51fdde 2225 sprintf(&buf[clen], "O=0x%8.8x", ti->arg3);
1815bff5 2226 else if (has_ret == 5)
1c51fdde 2227 sprintf(&buf[clen], "O=0x%8.8x", retval);
1815bff5 2228 else if (has_ret == 2)
b51d5b5f
A
2229 sprintf(&buf[clen], " A=0x%8.8x ", retval);
2230 else if (has_ret == 6)
2231 sprintf(&buf[clen], " A=0x%8.8x B=0x%-8x", retval, error);
1815bff5 2232 else if (has_ret == 1)
1c51fdde 2233 sprintf(&buf[clen], " B=0x%-6x", retval);
1815bff5 2234 else if (has_ret == 4)
b51d5b5f 2235 sprintf(&buf[clen], "B=0x%-8x", retval);
20e66415
A
2236 else if (has_ret == 8) /* BSC_select */
2237 sprintf(&buf[clen], " S=%-3d ", retval);
c3a08f59
A
2238 else if (has_ret == 9) /* BSC_pread, BSC_pwrite */
2239 {
2240 sprintf(&buf[clen], "B=0x%-8x", retval);
2241 clen = strlen(buf);
2242 offset_reassembled = (((off_t)(unsigned int)(ti->arg3)) << 32) | (unsigned int)(ti->arg4);
2243 if ((offset_reassembled >> 32) != 0)
2244 sprintf(&buf[clen], "O=0x%16.16qx", (off_t)offset_reassembled);
2245 else
2246 sprintf(&buf[clen], "O=0x%8.8qx", (off_t)offset_reassembled);
2247 }
1815bff5 2248 else
1c51fdde 2249 sprintf(&buf[clen], " ");
b51d5b5f
A
2250 }
2251 clen = strlen(buf);
1815bff5 2252 }
d904471c 2253 printf("%s", buf);
1c51fdde
A
2254
2255 /*
2256 Calculate space available to print pathname
2257 */
b51d5b5f
A
2258 if (columns > MAXCOLS || wideflag)
2259 clen = columns - (clen + 13 + 20);
1c51fdde 2260 else
b51d5b5f 2261 clen = columns - (clen + 13 + 12);
1c51fdde
A
2262
2263 if ((type >> 24) != FILEMGR_CLASS && !nopadding)
2264 clen -= 3;
2265
b51d5b5f
A
2266 if (framework_name)
2267 sprintf(&buf[0], " %s ", framework_name);
2268 else
2269 sprintf(&buf[0], " %s ", pathname);
1c51fdde
A
2270 len = strlen(buf);
2271
2272 if (clen > len)
2273 {
2274 /*
2275 Add null padding if column length
2276 is wider than the pathname length.
2277 */
2278 memset(&buf[len], ' ', clen - len);
2279 buf[clen] = '\0';
d904471c 2280 printf("%s", buf);
1c51fdde
A
2281 }
2282 else if (clen == len)
2283 {
d904471c 2284 printf("%s", buf);
1c51fdde
A
2285 }
2286 else if ((clen > 0) && (clen < len))
2287 {
2288 /* This prints the tail end of the pathname */
2289 buf[len-clen] = ' ';
d904471c 2290 printf("%s", &buf[len - clen]);
1c51fdde 2291 }
1815bff5 2292
b51d5b5f 2293 usecs = (unsigned long)((now - stime) / divisor);
1815bff5
A
2294 secs = usecs / 1000000;
2295 usecs -= secs * 1000000;
2296
2297 if ((type >> 24) != FILEMGR_CLASS && !nopadding)
2298 printf(" ");
2299
b51d5b5f
A
2300 printf(" %2ld.%06ld", (unsigned long)secs, (unsigned long)usecs);
2301
2302 if (waited)
1815bff5
A
2303 printf(" W");
2304 else
2305 printf(" ");
2306
b51d5b5f
A
2307 if (columns > MAXCOLS || wideflag)
2308 printf(" %-20.20s", command_name);
2309 else
2310 printf(" %-12.12s", command_name);
1815bff5 2311
b51d5b5f 2312 printf("\n");
1c51fdde 2313 fflush (0);
1815bff5
A
2314}
2315
2316int
2317quit(s)
2318char *s;
2319{
2320 if (trace_enabled)
2321 set_enable(0);
2322
2323 /*
2324 This flag is turned off when calling
2325 quit() due to a set_remove() failure.
2326 */
2327 if (set_remove_flag)
2328 set_remove();
2329
2330 printf("fs_usage: ");
2331 if (s)
2332 printf("%s", s);
2333
2334 exit(1);
2335}
2336
2337
2338void getdivisor()
2339{
2340
2341 unsigned int delta;
2342 unsigned int abs_to_ns_num;
2343 unsigned int abs_to_ns_denom;
2344 unsigned int proc_to_abs_num;
2345 unsigned int proc_to_abs_denom;
2346
b51d5b5f 2347 extern void MKGetTimeBaseInfo(unsigned int *, unsigned int *, unsigned int *, unsigned int *, unsigned int *);
1815bff5
A
2348
2349 MKGetTimeBaseInfo (&delta, &abs_to_ns_num, &abs_to_ns_denom,
2350 &proc_to_abs_num, &proc_to_abs_denom);
2351
2352 divisor = ((double)abs_to_ns_denom / (double)abs_to_ns_num) * 1000;
2353}
2354
2355
2356void read_command_map()
2357{
2358 size_t size;
20e66415
A
2359 int i;
2360 int prev_total_threads;
1815bff5
A
2361 int mib[6];
2362
2363 if (mapptr) {
2364 free(mapptr);
2365 mapptr = 0;
2366 }
20e66415
A
2367
2368 prev_total_threads = total_threads;
1815bff5
A
2369 total_threads = bufinfo.nkdthreads;
2370 size = bufinfo.nkdthreads * sizeof(kd_threadmap);
2371
2372 if (size)
2373 {
20e66415
A
2374 if ((mapptr = (kd_threadmap *) malloc(size)))
2375 {
1815bff5 2376 bzero (mapptr, size);
1815bff5 2377
20e66415
A
2378 /* Now read the threadmap */
2379 mib[0] = CTL_KERN;
2380 mib[1] = KERN_KDEBUG;
2381 mib[2] = KERN_KDTHRMAP;
2382 mib[3] = 0;
2383 mib[4] = 0;
2384 mib[5] = 0; /* no flags */
2385 if (sysctl(mib, 3, mapptr, &size, NULL, 0) < 0)
2386 {
2387 /* This is not fatal -- just means I cant map command strings */
2388 free(mapptr);
2389 mapptr = 0;
2390 }
2391 }
2392 }
2393
2394 if (mapptr && (filter_mode != DEFAULT_DO_NOT_FILTER))
1815bff5 2395 {
20e66415
A
2396 if (fdmapptr)
2397 {
2398 /* We accept the fact that we lose file descriptor state if the
2399 kd_buffer wraps */
2400 for (i = 0; i < prev_total_threads; i++)
2401 {
2402 if (fdmapptr[i].fd_setptr)
2403 free (fdmapptr[i].fd_setptr);
2404 }
2405 free(fdmapptr);
2406 fdmapptr = 0;
2407 }
2408
2409 size = total_threads * sizeof(fd_threadmap);
2410 if ((fdmapptr = (fd_threadmap *) malloc(size)))
2411 {
2412 bzero (fdmapptr, size);
2413 /* reinitialize file descriptor state map */
2414 for (i = 0; i < total_threads; i++)
2415 {
2416 fdmapptr[i].fd_thread = mapptr[i].thread;
2417 fdmapptr[i].fd_valid = mapptr[i].valid;
2418 fdmapptr[i].fd_setsize = 0;
2419 fdmapptr[i].fd_setptr = 0;
2420 }
2421 }
2422 }
2423
2424 /* Resolve any LaunchCFMApp command names */
2425 if (mapptr && arguments)
2426 {
2427 for (i=0; i < total_threads; i++)
2428 {
2429 int pid;
2430
2431 pid = mapptr[i].valid;
2432
2433 if (pid == 0 || pid == 1)
2434 continue;
2435 else if (!strncmp(mapptr[i].command,"LaunchCFMA", 10))
2436 {
2437 (void)get_real_command_name(pid, mapptr[i].command, sizeof(mapptr[i].command));
2438 }
2439 }
1815bff5 2440 }
1815bff5
A
2441}
2442
2443
20e66415 2444void create_map_entry(int thread, int pid, char *command)
1815bff5
A
2445{
2446 int i, n;
2447 kd_threadmap *map;
20e66415 2448 fd_threadmap *fdmap = 0;
1815bff5
A
2449
2450 if (!mapptr)
2451 return;
2452
2453 for (i = 0, map = 0; !map && i < total_threads; i++)
2454 {
20e66415
A
2455 if ((int)mapptr[i].thread == thread )
2456 {
2457 map = &mapptr[i]; /* Reuse this entry, the thread has been
2458 * reassigned */
2459 if(filter_mode && fdmapptr)
2460 {
2461 fdmap = &fdmapptr[i];
2462 if (fdmap->fd_thread != thread) /* This shouldn't happen */
2463 fdmap = (fd_threadmap *)0;
2464 }
2465 }
1815bff5
A
2466 }
2467
2468 if (!map) /* look for invalid entries that I can reuse*/
2469 {
2470 for (i = 0, map = 0; !map && i < total_threads; i++)
2471 {
2472 if (mapptr[i].valid == 0 )
2473 map = &mapptr[i]; /* Reuse this invalid entry */
20e66415
A
2474 if (filter_mode && fdmapptr)
2475 {
2476 fdmap = &fdmapptr[i];
2477 }
1815bff5
A
2478 }
2479 }
2480
2481 if (!map)
2482 {
2483 /* If reach here, then this is a new thread and
2484 * there are no invalid entries to reuse
2485 * Double the size of the thread map table.
2486 */
2487
2488 n = total_threads * 2;
2489 mapptr = (kd_threadmap *) realloc(mapptr, n * sizeof(kd_threadmap));
2490 bzero(&mapptr[total_threads], total_threads*sizeof(kd_threadmap));
2491 map = &mapptr[total_threads];
20e66415
A
2492
2493 if (filter_mode && fdmapptr)
2494 {
2495 fdmapptr = (fd_threadmap *)realloc(fdmapptr, n * sizeof(fd_threadmap));
2496 bzero(&fdmapptr[total_threads], total_threads*sizeof(fd_threadmap));
2497 fdmap = &fdmapptr[total_threads];
2498 }
2499
1815bff5
A
2500 total_threads = n;
2501 }
2502
2503 map->valid = 1;
2504 map->thread = thread;
1c51fdde
A
2505 /*
2506 The trace entry that returns the command name will hold
2507 at most, MAXCOMLEN chars, and in that case, is not
2508 guaranteed to be null terminated.
2509 */
2510 (void)strncpy (map->command, command, MAXCOMLEN);
2511 map->command[MAXCOMLEN] = '\0';
20e66415
A
2512
2513 if (fdmap)
2514 {
2515 fdmap->fd_valid = 1;
2516 fdmap->fd_thread = thread;
2517 if (fdmap->fd_setptr)
2518 {
2519 free(fdmap->fd_setptr);
2520 fdmap->fd_setptr = (unsigned long *)0;
2521 }
2522 fdmap->fd_setsize = 0;
2523 }
2524
2525 if (pid == 0 || pid == 1)
2526 return;
2527 else if (!strncmp(map->command, "LaunchCFMA", 10))
2528 (void)get_real_command_name(pid, map->command, sizeof(map->command));
1815bff5
A
2529}
2530
2531
2532kd_threadmap *find_thread_map(int thread)
2533{
2534 int i;
2535 kd_threadmap *map;
2536
2537 if (!mapptr)
2538 return((kd_threadmap *)0);
2539
2540 for (i = 0; i < total_threads; i++)
2541 {
2542 map = &mapptr[i];
20e66415 2543 if (map->valid && ((int)map->thread == thread))
1815bff5
A
2544 {
2545 return(map);
2546 }
2547 }
2548 return ((kd_threadmap *)0);
2549}
2550
20e66415
A
2551fd_threadmap *find_fd_thread_map(int thread)
2552{
2553 int i;
2554 fd_threadmap *fdmap = 0;
2555
2556 if (!fdmapptr)
2557 return((fd_threadmap *)0);
2558
2559 for (i = 0; i < total_threads; i++)
2560 {
2561 fdmap = &fdmapptr[i];
2562 if (fdmap->fd_valid && ((int)fdmap->fd_thread == thread))
2563 {
2564 return(fdmap);
2565 }
2566 }
2567 return ((fd_threadmap *)0);
2568}
2569
1815bff5
A
2570
2571void
2572kill_thread_map(int thread)
2573{
2574 kd_threadmap *map;
20e66415 2575 fd_threadmap *fdmap;
1815bff5 2576
20e66415 2577 if ((map = find_thread_map(thread))) {
1815bff5
A
2578 map->valid = 0;
2579 map->thread = 0;
2580 map->command[0] = '\0';
2581 }
20e66415
A
2582
2583 if (filter_mode)
2584 {
2585 if ((fdmap = find_fd_thread_map(thread)))
2586 {
2587 fdmap->fd_valid = 0;
2588 fdmap->fd_thread = 0;
2589 if (fdmap->fd_setptr)
2590 {
2591 free (fdmap->fd_setptr);
2592 fdmap->fd_setptr = (unsigned long *)0;
2593 }
2594 fdmap->fd_setsize = 0;
2595 }
2596 }
1815bff5
A
2597}
2598
2599void
2600argtopid(str)
2601 char *str;
2602{
2603 char *cp;
2604 int ret;
2605 int i;
2606
2607 ret = (int)strtol(str, &cp, 10);
2608 if (cp == str || *cp) {
2609 /* Assume this is a command string and find matching pids */
2610 if (!kp_buffer)
2611 find_proc_names();
2612
2613 for (i=0; i < kp_nentries && num_of_pids < (MAX_PIDS - 1); i++) {
2614 if(kp_buffer[i].kp_proc.p_stat == 0)
2615 continue;
2616 else {
2617 if(!strcmp(str, kp_buffer[i].kp_proc.p_comm))
2618 pids[num_of_pids++] = kp_buffer[i].kp_proc.p_pid;
2619 }
2620 }
2621 }
2622 else if (num_of_pids < (MAX_PIDS - 1))
2623 pids[num_of_pids++] = ret;
2624
2625 return;
2626}
2627
2628
b51d5b5f
A
2629
2630char *lookup_name(unsigned long addr)
2631{
2632 register int i;
2633 register int start, last;
2634
2635
2636 if (numFrameworks == 0 || addr < frameworkInfo[0].address || addr > frameworkInfo[numFrameworks].address)
2637 return (0);
2638
2639 start = 0;
2640 last = numFrameworks;
2641
2642 for (i = numFrameworks / 2; i >= 0 && i < numFrameworks; ) {
2643
2644 if (addr >= frameworkInfo[i].address && addr < frameworkInfo[i+1].address)
2645 return(frameworkInfo[i].name);
2646
2647 if (addr >= frameworkInfo[i].address) {
2648 start = i;
2649 i = start + ((last - i) / 2);
2650 } else {
2651 last = i;
2652 i = start + ((i - start) / 2);
2653 }
2654 }
2655 return (0);
2656}
2657
2658
2659/*
2660 * Comparison routines for sorting
2661 */
2662static int compareFrameworkAddress(const void *aa, const void *bb)
2663{
2664 LibraryInfo *a = (LibraryInfo *)aa;
2665 LibraryInfo *b = (LibraryInfo *)bb;
2666
2667 if (a->address < b->address) return -1;
2668 if (a->address == b->address) return 0;
2669 return 1;
2670}
2671
2672
2673int scanline(char *inputstring,char **argv)
2674{
2675 int n = 0;
2676 char **ap = argv, *p, *val;
2677
2678 for (p = inputstring; p != NULL; )
2679 {
2680 while ((val = strsep(&p, " \t")) != NULL && *val == '\0');
2681 *ap++ = val;
2682 n++;
2683 }
2684 *ap = 0;
2685 return n;
2686}
2687
2688
2689int ReadSegAddrTable()
2690{
2691 char buf[1024];
2692
2693 FILE *fd;
2694 unsigned long frameworkAddress, frameworkDataAddress, previousFrameworkAddress;
2695 char frameworkName[256];
2696 char *tokens[64];
2697 int ntokens;
2698 char *substring,*ptr;
2699 int founddylib = 0;
b51d5b5f
A
2700
2701
2702 bzero(buf, sizeof(buf));
2703 bzero(tokens, sizeof(tokens));
2704
2705 numFrameworks = 0;
2706
2707 if ((fd = fopen(seg_addr_table, "r")) == 0)
2708 {
2709 return 0;
2710 }
2711 fgets(buf, 1023, fd);
2712
2713 if (*buf == '#')
2714 {
2715 founddylib = 0;
2716 frameworkName[0] = 0;
2717 previousFrameworkAddress = 0;
2718
2719 while (fgets(buf, 1023, fd) && numFrameworks < (MAXINDEX - 2))
2720 {
2721 /*
2722 * Get rid of EOL
2723 */
2724 buf[strlen(buf)-1] = 0;
2725
2726 if (strncmp(buf, "# dyld:", 7) == 0) {
2727 /*
2728 * the next line in the file will contain info about dyld
2729 */
2730 founddylib = 1;
2731 continue;
2732 }
2733 /*
2734 * This is a split library line: parse it into 3 tokens
2735 */
2736 ntokens = scanline(buf, tokens);
2737
2738 if (ntokens < 3)
2739 continue;
2740
2741 frameworkAddress = strtoul(tokens[0], 0, 16);
2742 frameworkDataAddress = strtoul(tokens[1], 0, 16);
2743
2744 if (founddylib) {
2745 /*
2746 * dyld entry is of a different form from the std split library
2747 * it consists of a base address and a size instead of a code
2748 * and data base address
2749 */
2750 frameworkInfo[numFrameworks].address = frameworkAddress;
2751 frameworkInfo[numFrameworks+1].address = frameworkAddress + frameworkDataAddress;
2752
2753 frameworkInfo[numFrameworks].name = (char *)"dylib";
2754 frameworkInfo[numFrameworks+1].name = (char *)0;
2755
2756 numFrameworks += 2;
2757 founddylib = 0;
2758
2759 continue;
2760 }
2761
2762 /*
2763 * Make sure that we have 2 addresses and a path
2764 */
2765 if (!frameworkAddress)
2766 continue;
2767 if (!frameworkDataAddress)
2768 continue;
2769 if (*tokens[2] != '/')
2770 continue;
2771 if (frameworkAddress == previousFrameworkAddress)
2772 continue;
2773 previousFrameworkAddress = frameworkAddress;
2774
2775 /*
2776 * Extract lib name from path name
2777 */
20e66415 2778 if ((substring = strrchr(tokens[2], '.')))
b51d5b5f
A
2779 {
2780 /*
2781 * There is a ".": name is whatever is between the "/" around the "."
2782 */
2783 while ( *substring != '/') { /* find "/" before "." */
2784 substring--;
2785 }
2786 substring++;
2787 strcpy(frameworkName, substring); /* copy path from "/" */
2788 substring = frameworkName;
2789
2790 while ( *substring != '/' && *substring) /* find "/" after "." and stop string there */
2791 substring++;
2792 *substring = 0;
2793 }
2794 else
2795 {
2796 /*
2797 * No ".": take segment after last "/"
2798 */
2799 ptr = tokens[2];
2800 substring = ptr;
2801
2802 while (*ptr)
2803 {
2804 if (*ptr == '/')
2805 substring = ptr + 1;
2806 ptr++;
2807 }
2808 strcpy(frameworkName, substring);
2809 }
2810 frameworkInfo[numFrameworks].address = frameworkAddress;
2811 frameworkInfo[numFrameworks+1].address = frameworkDataAddress;
2812
2813 frameworkInfo[numFrameworks].name = (char *)malloc(strlen(frameworkName) + 1);
2814 strcpy(frameworkInfo[numFrameworks].name, frameworkName);
2815 frameworkInfo[numFrameworks+1].name = frameworkInfo[numFrameworks].name;
2816
2817 numFrameworks += 2;
2818 }
2819 }
2820 frameworkInfo[numFrameworks].address = frameworkInfo[numFrameworks - 1].address + 0x800000;
2821 frameworkInfo[numFrameworks].name = (char *)0;
2822
2823 fclose(fd);
2824
2825 qsort(frameworkInfo, numFrameworks, sizeof(LibraryInfo), compareFrameworkAddress);
2826
2827 return 1;
2828}
2829
2830
2831struct diskio *insert_diskio(int type, int bp, int dev, int blkno, int io_size, int thread, double curtime)
2832{
2833 register struct diskio *dio;
2834 register kd_threadmap *map;
2835
20e66415 2836 if ((dio = free_diskios))
b51d5b5f
A
2837 free_diskios = dio->next;
2838 else {
2839 if ((dio = (struct diskio *)malloc(sizeof(struct diskio))) == NULL)
2840 return (NULL);
2841 }
2842 dio->prev = NULL;
2843
2844 dio->type = type;
2845 dio->bp = bp;
2846 dio->dev = dev;
2847 dio->blkno = blkno;
2848 dio->iosize = io_size;
2849 dio->issued_time = curtime;
2850 dio->issuing_thread = thread;
2851
20e66415
A
2852 if ((map = find_thread_map(thread)))
2853 {
2854 strncpy(dio->issuing_command, map->command, MAXCOMLEN);
2855 dio->issuing_command[MAXCOMLEN-1] = '\0';
2856 }
b51d5b5f
A
2857 else
2858 strcpy(dio->issuing_command, "");
2859
2860 dio->next = busy_diskios;
2861 if (dio->next)
2862 dio->next->prev = dio;
2863 busy_diskios = dio;
2864
2865 return (dio);
2866}
2867
2868
2869struct diskio *complete_diskio(int bp, int io_errno, int resid, int thread, double curtime)
2870{
2871 register struct diskio *dio;
2872
2873 for (dio = busy_diskios; dio; dio = dio->next) {
2874 if (dio->bp == bp) {
2875
2876 if (dio == busy_diskios) {
20e66415 2877 if ((busy_diskios = dio->next))
b51d5b5f
A
2878 dio->next->prev = NULL;
2879 } else {
2880 if (dio->next)
2881 dio->next->prev = dio->prev;
2882 dio->prev->next = dio->next;
2883 }
2884 dio->iosize -= resid;
2885 dio->io_errno = io_errno;
2886 dio->completed_time = curtime;
2887 dio->completion_thread = thread;
2888
2889 return (dio);
2890 }
2891 }
2892 return ((struct diskio *)0);
2893}
2894
2895
2896void free_diskio(struct diskio *dio)
2897{
2898 dio->next = free_diskios;
2899 free_diskios = dio;
2900}
2901
2902
2903void print_diskio(struct diskio *dio)
2904{
2905 register char *p;
b51d5b5f
A
2906
2907 switch (dio->type) {
2908
2909 case P_RdMeta:
2910 p = " RdMeta";
2911 break;
2912 case P_WrMeta:
2913 p = " WrMeta";
2914 break;
2915 case P_RdData:
2916 p = " RdData";
2917 break;
2918 case P_WrData:
2919 p = " WrData";
2920 break;
2921 case P_PgIn:
2922 p = " PgIn";
2923 break;
2924 case P_PgOut:
2925 p = " PgOut";
2926 break;
2927 case P_RdMetaAsync:
2928 p = " RdMeta[async]";
2929 break;
2930 case P_WrMetaAsync:
2931 p = " WrMeta[async]";
2932 break;
2933 case P_RdDataAsync:
2934 p = " RdData[async]";
2935 break;
2936 case P_WrDataAsync:
2937 p = " WrData[async]";
2938 break;
2939 case P_PgInAsync:
2940 p = " PgIn[async]";
2941 break;
2942 case P_PgOutAsync:
2943 p = " PgOut[async]";
2944 break;
20e66415
A
2945 default:
2946 p = " ";
2947 break;
b51d5b5f 2948 }
20e66415
A
2949 if (check_filter_mode(NULL, dio->type,0, 0))
2950 format_print(NULL, p, dio->issuing_thread, dio->type, 0, 0, 0, 7, dio->completed_time, dio->issued_time, 1, "", dio);
b51d5b5f
A
2951}
2952
2953
20e66415 2954void cache_disk_names()
b51d5b5f
A
2955{
2956 struct stat st;
2957 DIR *dirp = NULL;
2958 struct dirent *dir;
2959 struct diskrec *dnp;
2960
2961
2962 if ((dirp = opendir("/dev")) == NULL)
2963 return;
2964
2965 while ((dir = readdir(dirp)) != NULL) {
2966 char nbuf[MAXPATHLEN];
2967
2968 if (dir->d_namlen < 5 || strncmp("disk", dir->d_name, 4))
2969 continue;
2970 sprintf(nbuf, "%s/%s", "/dev", dir->d_name);
2971
2972 if (stat(nbuf, &st) < 0)
2973 continue;
2974
2975 if ((dnp = (struct diskrec *)malloc(sizeof(struct diskrec))) == NULL)
2976 continue;
2977
2978 if ((dnp->diskname = (char *)malloc(dir->d_namlen + 1)) == NULL) {
2979 free(dnp);
2980 continue;
2981 }
2982 strncpy(dnp->diskname, dir->d_name, dir->d_namlen);
2983 dnp->diskname[dir->d_namlen] = 0;
2984 dnp->dev = st.st_rdev;
2985
2986 dnp->next = disk_list;
2987 disk_list = dnp;
2988 }
2989 (void) closedir(dirp);
2990}
2991
2992
2993char *find_disk_name(int dev)
2994{
2995 struct diskrec *dnp;
2996
2997 if (dev == NFS_DEV)
2998 return ("NFS");
2999
3000 for (dnp = disk_list; dnp; dnp = dnp->next) {
3001 if (dnp->dev == dev)
3002 return (dnp->diskname);
3003 }
3004 return ("NOTFOUND");
3005}
20e66415
A
3006
3007void
3008fs_usage_fd_set(thread, fd)
3009 unsigned int thread;
3010 unsigned int fd;
3011{
3012 int n;
3013 fd_threadmap *fdmap;
3014
3015 if(!(fdmap = find_fd_thread_map(thread)))
3016 return;
3017
3018 /* If the map is not allocated, then now is the time */
3019 if (fdmap->fd_setptr == (unsigned long *)0)
3020 {
3021 fdmap->fd_setptr = (unsigned long *)malloc(FS_USAGE_NFDBYTES(FS_USAGE_FD_SETSIZE));
3022 if (fdmap->fd_setptr)
3023 {
3024 fdmap->fd_setsize = FS_USAGE_FD_SETSIZE;
3025 bzero(fdmap->fd_setptr,(FS_USAGE_NFDBYTES(FS_USAGE_FD_SETSIZE)));
3026 }
3027 else
3028 return;
3029 }
3030
3031 /* If the map is not big enough, then reallocate it */
3032 while (fdmap->fd_setsize < fd)
3033 {
3034 printf("reallocating bitmap for threadid %d, fd = %d, setsize = %d\n",
3035 thread, fd, fdmap->fd_setsize);
3036 n = fdmap->fd_setsize * 2;
3037 fdmap->fd_setptr = (unsigned long *)realloc(fdmap->fd_setptr, (FS_USAGE_NFDBYTES(n)));
3038 bzero(&fdmap->fd_setptr[(fdmap->fd_setsize/FS_USAGE_NFDBITS)], (FS_USAGE_NFDBYTES(fdmap->fd_setsize)));
3039 fdmap->fd_setsize = n;
3040 }
3041
3042 /* set the bit */
3043 fdmap->fd_setptr[fd/FS_USAGE_NFDBITS] |= (1 << ((fd) % FS_USAGE_NFDBITS));
3044
3045 return;
3046}
3047
3048/*
3049 Return values:
3050 0 : File Descriptor bit is not set
3051 1 : File Descriptor bit is set
3052*/
3053
3054int
3055fs_usage_fd_isset(thread, fd)
3056 unsigned int thread;
3057 unsigned int fd;
3058{
3059 int ret = 0;
3060 fd_threadmap *fdmap;
3061
3062 if(!(fdmap = find_fd_thread_map(thread)))
3063 return(ret);
3064
3065 if (fdmap->fd_setptr == (unsigned long *)0)
3066 return (ret);
3067
3068 if (fd < fdmap->fd_setsize)
3069 ret = fdmap->fd_setptr[fd/FS_USAGE_NFDBITS] & (1 << (fd % FS_USAGE_NFDBITS));
3070
3071 return (ret);
3072}
3073
3074void
3075fs_usage_fd_clear(thread, fd)
3076 unsigned int thread;
3077 unsigned int fd;
3078{
3079 fd_threadmap *map;
3080
3081 if (!(map = find_fd_thread_map(thread)))
3082 return;
3083
3084 if (map->fd_setptr == (unsigned long *)0)
3085 return;
3086
3087 /* clear the bit */
3088 if (fd < map->fd_setsize)
3089 map->fd_setptr[fd/FS_USAGE_NFDBITS] &= ~(1 << (fd % FS_USAGE_NFDBITS));
3090
3091 return;
3092}
3093
3094
3095/*
3096 * ret = 1 means print the entry
3097 * ret = 0 means don't print the entry
3098 */
3099int
3100check_filter_mode(struct th_info * ti, int type, int error, int retval)
3101{
3102 int ret = 0;
3103 int network_fd_isset = 0;
3104 unsigned int fd;
3105
3106 if (filter_mode == DEFAULT_DO_NOT_FILTER)
3107 return(1);
3108
3109 if (ti == (struct th_info *)0)
3110 {
3111 if(filter_mode & FILESYS_FILTER)
3112 ret = 1;
3113 else
3114 ret = 0;
3115 return(ret);
3116 }
3117
3118
3119 switch (type) {
3120 case BSC_close:
3121 fd = ti->arg1;
3122 network_fd_isset = fs_usage_fd_isset(ti->thread, fd);
3123 if (error == 0)
3124 {
3125 fs_usage_fd_clear(ti->thread,fd);
3126 }
3127
3128 if (network_fd_isset)
3129 {
3130 if (filter_mode & NETWORK_FILTER)
3131 ret = 1;
3132 }
3133 else if (filter_mode & FILESYS_FILTER)
3134 ret = 1;
3135 break;
3136 case BSC_read:
3137 case BSC_write:
3138 /* we don't care about error in this case */
3139 fd = ti->arg1;
3140 network_fd_isset = fs_usage_fd_isset(ti->thread, fd);
3141 if (network_fd_isset)
3142 {
3143 if (filter_mode & NETWORK_FILTER)
3144 ret = 1;
3145 }
3146 else if (filter_mode & FILESYS_FILTER)
3147 ret = 1;
3148 break;
3149 case BSC_accept:
3150 case BSC_socket:
3151 fd = retval;
3152 if (error == 0)
3153 fs_usage_fd_set(ti->thread, fd);
3154 if (filter_mode & NETWORK_FILTER)
3155 ret = 1;
3156 break;
3157 case BSC_recvfrom:
3158 case BSC_sendto:
3159 case BSC_recvmsg:
3160 case BSC_sendmsg:
3161 case BSC_connect:
3162 case BSC_bind:
3163 case BSC_listen:
3164 fd = ti->arg1;
3165 if (error == 0)
3166 fs_usage_fd_set(ti->thread, fd);
3167 if (filter_mode & NETWORK_FILTER)
3168 ret = 1;
3169 break;
3170 case BSC_select:
3171 case BSC_socketpair:
3172 /* Cannot determine info about file descriptors */
3173 if (filter_mode & NETWORK_FILTER)
3174 ret = 1;
3175 break;
3176 case BSC_dup:
3177 case BSC_dup2:
3178 ret=0; /* We track these cases for fd state only */
3179 fd = ti->arg1; /* oldd */
3180 network_fd_isset = fs_usage_fd_isset(ti->thread, fd);
3181 if (error == 0 && network_fd_isset)
3182 {
3183 /* then we are duping a socket descriptor */
3184 fd = retval; /* the new fd */
3185 fs_usage_fd_set(ti->thread, fd);
3186 }
3187 break;
3188
3189 default:
3190 if (filter_mode & FILESYS_FILTER)
3191 ret = 1;
3192 break;
3193 }
3194
3195 return(ret);
3196}
3197
3198/*
3199 * Allocate a buffer that is large enough to hold the maximum arguments
3200 * to execve(). This is used when getting the arguments to programs
3201 * when we see LaunchCFMApps. If this fails, it is not fatal, we will
3202 * simply not resolve the command name.
3203 */
3204
3205void
3206init_arguments_buffer()
3207{
3208
3209 int mib[2];
3210 size_t size;
3211
3212 mib[0] = CTL_KERN;
3213 mib[1] = KERN_ARGMAX;
3214 size = sizeof(argmax);
3215 if (sysctl(mib, 2, &argmax, &size, NULL, 0) == -1)
3216 return;
3217
3218#if 1
3219 /* Hack to avoid kernel bug. */
3220 if (argmax > 8192) {
3221 argmax = 8192;
3222 }
3223#endif
3224
3225 arguments = (char *)malloc(argmax);
3226
3227 return;
3228}
3229
3230
3231int
3232get_real_command_name(int pid, char *cbuf, int csize)
3233{
3234 /*
3235 * Get command and arguments.
3236 */
3237 char *cp;
3238 int mib[4];
3239 char *command_beg, *command, *command_end;
3240
3241 if (cbuf == NULL) {
3242 return(0);
3243 }
3244
3245 if (arguments)
3246 bzero(arguments, argmax);
3247 else
3248 return(0);
3249
3250 /*
3251 * A sysctl() is made to find out the full path that the command
3252 * was called with.
3253 */
3254 mib[0] = CTL_KERN;
3255 mib[1] = KERN_PROCARGS;
3256 mib[2] = pid;
3257 mib[3] = 0;
3258
3259 if (sysctl(mib, 3, arguments, (size_t *)&argmax, NULL, 0) < 0) {
3260 return(0);
3261 }
3262
3263 /* Skip the saved exec_path. */
3264 for (cp = arguments; cp < &arguments[argmax]; cp++) {
3265 if (*cp == '\0') {
3266 /* End of exec_path reached. */
3267 break;
3268 }
3269 }
3270 if (cp == &arguments[argmax]) {
3271 return(0);
3272 }
3273
3274 /* Skip trailing '\0' characters. */
3275 for (; cp < &arguments[argmax]; cp++) {
3276 if (*cp != '\0') {
3277 /* Beginning of first argument reached. */
3278 break;
3279 }
3280 }
3281 if (cp == &arguments[argmax]) {
3282 return(0);
3283 }
3284 command_beg = cp;
3285
3286 /*
3287 * Make sure that the command is '\0'-terminated. This protects
3288 * against malicious programs; under normal operation this never
3289 * ends up being a problem..
3290 */
3291 for (; cp < &arguments[argmax]; cp++) {
3292 if (*cp == '\0') {
3293 /* End of first argument reached. */
3294 break;
3295 }
3296 }
3297 if (cp == &arguments[argmax]) {
3298 return(0);
3299 }
3300 command_end = command = cp;
3301
3302 /* Get the basename of command. */
3303 for (command--; command >= command_beg; command--) {
3304 if (*command == '/') {
3305 command++;
3306 break;
3307 }
3308 }
3309
3310 (void) strncpy(cbuf, (char *)command, csize);
3311 cbuf[csize-1] = '\0';
3312
3313 return(1);
3314}