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