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