]> git.saurik.com Git - apple/system_cmds.git/blob - fs_usage.tproj/fs_usage.c
465d0dcfc74c842eaa9b33d2330241d3aba96303
[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. -DKERNEL_PRIVATE -O -o fs_usage fs_usage.c
27 */
28
29 #define Default_DELAY 1 /* default delay interval */
30
31 #include <stdlib.h>
32 #include <stdio.h>
33 #include <signal.h>
34 #include <strings.h>
35 #include <nlist.h>
36 #include <fcntl.h>
37 #include <string.h>
38
39 #include <sys/types.h>
40 #include <sys/param.h>
41 #include <sys/time.h>
42
43 #include <libc.h>
44 #include <termios.h>
45 #include <bsd/curses.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 #include <err.h>
60
61 extern int errno;
62
63 /*
64 MAXCOLS controls when extra data kicks in.
65 MAX_WIDE_MODE_COLS controls -w mode to get even wider data in path.
66 If NUMPARMS changes to match the kernel, it will automatically
67 get reflected in the -w mode output.
68 */
69 #define NUMPARMS 23
70 #define PATHLENGTH (NUMPARMS*sizeof(long))
71 #define MAXCOLS 131
72 #define MAX_WIDE_MODE_COLS (PATHLENGTH + 80)
73
74 struct th_info {
75 int in_filemgr;
76 int thread;
77 int type;
78 int arg1;
79 int arg2;
80 int arg3;
81 int arg4;
82 int child_thread;
83 int waited;
84 double stime;
85 long *pathptr;
86 char pathname[PATHLENGTH + 1]; /* add room for null terminator */
87 };
88
89 #define MAX_THREADS 512
90 struct th_info th_state[MAX_THREADS];
91
92
93 int cur_max = 0;
94 int need_new_map = 1;
95 int bias_secs;
96 int wideflag = 0;
97 int select_pid_mode = 0; /* Flag set indicates that output is restricted
98 to selected pids or commands */
99
100 int one_good_pid = 0; /* Used to fail gracefully when bad pids given */
101
102
103 #define DBG_ZERO_FILL_FAULT 1
104 #define DBG_PAGEIN_FAULT 2
105 #define DBG_COW_FAULT 3
106 #define DBG_CACHE_HIT_FAULT 4
107
108 #define TRACE_DATA_NEWTHREAD 0x07000004
109 #define TRACE_STRING_NEWTHREAD 0x07010004
110 #define TRACE_STRING_EXEC 0x07010008
111
112 #define MACH_vmfault 0x01300000
113 #define MACH_sched 0x01400000
114 #define MACH_stkhandoff 0x01400008
115 #define VFS_LOOKUP 0x03010090
116 #define BSC_exit 0x040C0004
117
118 #define MSC_map_fd 0x010c00ac
119 #define BSC_recvmsg 0x040C006C
120 #define BSC_sendmsg 0x040C0070
121 #define BSC_recvfrom 0x040C0074
122 #define BSC_sendto 0x040C0214
123
124 #define BSC_read 0x040C000C
125 #define BSC_write 0x040C0010
126 #define BSC_open 0x040C0014
127 #define BSC_close 0x040C0018
128 #define BSC_link 0x040C0024
129 #define BSC_unlink 0x040C0028
130 #define BSC_mknod 0x040C0038
131 #define BSC_chmod 0x040C003C
132 #define BSC_chown 0x040C0040
133 #define BSC_access 0x040C0084
134 #define BSC_chflags 0x040C0088
135 #define BSC_fchflags 0x040C008C
136 #define BSC_sync 0x040C0090
137 #define BSC_symlink 0x040C00E4
138 #define BSC_readlink 0x040C00E8
139 #define BSC_fsync 0x040C017C
140 #define BSC_readv 0x040C01E0
141 #define BSC_writev 0x040C01E4
142 #define BSC_fchown 0x040C01EC
143 #define BSC_fchmod 0x040C01F0
144 #define BSC_rename 0x040C0200
145 #define BSC_mkdir 0x040C0220
146 #define BSC_rmdir 0x040C0224
147 #define BSC_statfs 0x040C0274
148 #define BSC_fstatfs 0x040C0278
149 #define BSC_stat 0x040C02F0
150 #define BSC_fstat 0x040C02F4
151 #define BSC_lstat 0x040C02F8
152 #define BSC_pathconf 0x040C02FC
153 #define BSC_fpathconf 0x040C0300
154 #define BSC_getdirentries 0x040C0310
155 #define BSC_mmap 0x040c0314
156 #define BSC_lseek 0x040c031c
157 #define BSC_truncate 0x040C0320
158 #define BSC_ftruncate 0x040C0324
159 #define BSC_statv 0x040C0364
160 #define BSC_lstatv 0x040C0368
161 #define BSC_fstatv 0x040C036C
162 #define BSC_mkcomplex 0x040C0360
163 #define BSC_getattrlist 0x040C0370
164 #define BSC_setattrlist 0x040C0374
165 #define BSC_getdirentriesattr 0x040C0378
166 #define BSC_exchangedata 0x040C037C
167 #define BSC_checkuseraccess 0x040C0380
168 #define BSC_searchfs 0x040C0384
169
170 // Carbon File Manager support
171 #define FILEMGR_PBGETCATALOGINFO 0x1e000020
172 #define FILEMGR_PBGETCATALOGINFOBULK 0x1e000024
173 #define FILEMGR_PBCREATEFILEUNICODE 0x1e000028
174 #define FILEMGR_PBCREATEDIRECTORYUNICODE 0x1e00002c
175 #define FILEMGR_PBCREATEFORK 0x1e000030
176 #define FILEMGR_PBDELETEFORK 0x1e000034
177 #define FILEMGR_PBITERATEFORK 0x1e000038
178 #define FILEMGR_PBOPENFORK 0x1e00003c
179 #define FILEMGR_PBREADFORK 0x1e000040
180 #define FILEMGR_PBWRITEFORK 0x1e000044
181 #define FILEMGR_PBALLOCATEFORK 0x1e000048
182 #define FILEMGR_PBDELETEOBJECT 0x1e00004c
183 #define FILEMGR_PBEXCHANGEOBJECT 0x1e000050
184 #define FILEMGR_PBGETFORKCBINFO 0x1e000054
185 #define FILEMGR_PBGETVOLUMEINFO 0x1e000058
186 #define FILEMGR_PBMAKEFSREF 0x1e00005c
187 #define FILEMGR_PBMAKEFSREFUNICODE 0x1e000060
188 #define FILEMGR_PBMOVEOBJECT 0x1e000064
189 #define FILEMGR_PBOPENITERATOR 0x1e000068
190 #define FILEMGR_PBRENAMEUNICODE 0x1e00006c
191 #define FILEMGR_PBSETCATALOGINFO 0x1e000070
192 #define FILEMGR_PBSETVOLUMEINFO 0x1e000074
193 #define FILEMGR_FSREFMAKEPATH 0x1e000078
194 #define FILEMGR_FSPATHMAKEREF 0x1e00007c
195
196 #define FILEMGR_PBGETCATINFO 0x1e010000
197 #define FILEMGR_PBGETCATINFOLITE 0x1e010004
198 #define FILEMGR_PBHGETFINFO 0x1e010008
199 #define FILEMGR_PBXGETVOLINFO 0x1e01000c
200 #define FILEMGR_PBHCREATE 0x1e010010
201 #define FILEMGR_PBHOPENDF 0x1e010014
202 #define FILEMGR_PBHOPENRF 0x1e010018
203 #define FILEMGR_PBHGETDIRACCESS 0x1e01001c
204 #define FILEMGR_PBHSETDIRACCESS 0x1e010020
205 #define FILEMGR_PBHMAPID 0x1e010024
206 #define FILEMGR_PBHMAPNAME 0x1e010028
207 #define FILEMGR_PBCLOSE 0x1e01002c
208 #define FILEMGR_PBFLUSHFILE 0x1e010030
209 #define FILEMGR_PBGETEOF 0x1e010034
210 #define FILEMGR_PBSETEOF 0x1e010038
211 #define FILEMGR_PBGETFPOS 0x1e01003c
212 #define FILEMGR_PBREAD 0x1e010040
213 #define FILEMGR_PBWRITE 0x1e010044
214 #define FILEMGR_PBGETFCBINFO 0x1e010048
215 #define FILEMGR_PBSETFINFO 0x1e01004c
216 #define FILEMGR_PBALLOCATE 0x1e010050
217 #define FILEMGR_PBALLOCCONTIG 0x1e010054
218 #define FILEMGR_PBSETFPOS 0x1e010058
219 #define FILEMGR_PBSETCATINFO 0x1e01005c
220 #define FILEMGR_PBGETVOLPARMS 0x1e010060
221 #define FILEMGR_PBSETVINFO 0x1e010064
222 #define FILEMGR_PBMAKEFSSPEC 0x1e010068
223 #define FILEMGR_PBHGETVINFO 0x1e01006c
224 #define FILEMGR_PBCREATEFILEIDREF 0x1e010070
225 #define FILEMGR_PBDELETEFILEIDREF 0x1e010074
226 #define FILEMGR_PBRESOLVEFILEIDREF 0x1e010078
227 #define FILEMGR_PBFLUSHVOL 0x1e01007c
228 #define FILEMGR_PBHRENAME 0x1e010080
229 #define FILEMGR_PBCATMOVE 0x1e010084
230 #define FILEMGR_PBEXCHANGEFILES 0x1e010088
231 #define FILEMGR_PBHDELETE 0x1e01008c
232 #define FILEMGR_PBDIRCREATE 0x1e010090
233 #define FILEMGR_PBCATSEARCH 0x1e010094
234 #define FILEMGR_PBHSETFLOCK 0x1e010098
235 #define FILEMGR_PBHRSTFLOCK 0x1e01009c
236 #define FILEMGR_PBLOCKRANGE 0x1e0100a0
237 #define FILEMGR_PBUNLOCKRANGE 0x1e0100a4
238
239
240 #define FILEMGR_CLASS 0x1e
241
242 #define MAX_PIDS 32
243 int pids[MAX_PIDS];
244
245 int num_of_pids = 0;
246 int exclude_pids = 0;
247 int exclude_default_pids = 1;
248
249 struct kinfo_proc *kp_buffer = 0;
250 int kp_nentries = 0;
251
252 #define SAMPLE_SIZE 60000
253
254 #define DBG_ZERO_FILL_FAULT 1
255 #define DBG_PAGEIN_FAULT 2
256 #define DBG_COW_FAULT 3
257 #define DBG_CACHE_HIT_FAULT 4
258
259 #define DBG_FUNC_ALL (DBG_FUNC_START | DBG_FUNC_END)
260 #define DBG_FUNC_MASK 0xfffffffc
261
262 /* Default divisor */
263 #define DIVISOR 16.6666 /* Trace divisor converts to microseconds */
264 double divisor = DIVISOR;
265
266 int mib[6];
267 size_t needed;
268 char *my_buffer;
269
270 kbufinfo_t bufinfo = {0, 0, 0, 0};
271
272 int total_threads = 0;
273 kd_threadmap *mapptr = 0;
274
275 int trace_enabled = 0;
276 int set_remove_flag = 1;
277
278 void set_numbufs();
279 void set_init();
280 void set_enable();
281 void sample_sc();
282 int quit();
283
284 /*
285 * signal handlers
286 */
287
288 void leave() /* exit under normal conditions -- INT handler */
289 {
290 int i;
291 void set_enable();
292 void set_pidcheck();
293 void set_pidexclude();
294 void set_remove();
295
296 set_enable(0);
297
298 if (exclude_pids == 0) {
299 for (i = 0; i < num_of_pids; i++)
300 set_pidcheck(pids[i], 0);
301 }
302 else {
303 for (i = 0; i < num_of_pids; i++)
304 set_pidexclude(pids[i], 0);
305 }
306 set_remove();
307 exit(0);
308 }
309
310
311 void sigwinch()
312 {
313 if (!wideflag)
314 initscr();
315 }
316
317 int
318 exit_usage(myname) {
319
320 fprintf(stderr, "Usage: %s [-e] [-w] [pid | cmd [pid | cmd]....]\n", myname);
321 fprintf(stderr, " -e exclude the specified list of pids from the sample\n");
322 fprintf(stderr, " and exclude fs_usage by default\n");
323 fprintf(stderr, " -w force wider, detailed, output\n");
324 fprintf(stderr, " pid selects process(s) to sample\n");
325 fprintf(stderr, " cmd selects process(s) matching command string to sample\n");
326 fprintf(stderr, "\n%s will handle a maximum list of %d pids.\n\n", myname, MAX_PIDS);
327 fprintf(stderr, "By default (no options) the following processes are excluded from the output:\n");
328 fprintf(stderr, "fs_usage, Terminal, telnetd, sshd, rlogind, tcsh, csh, sh\n\n");
329
330 exit(1);
331 }
332
333
334 main(argc, argv)
335 int argc;
336 char *argv[];
337 {
338 char *myname = "fs_usage";
339 int i;
340 char ch;
341 void getdivisor();
342 void argtopid();
343 void set_remove();
344 void set_pidcheck();
345 void set_pidexclude();
346 int quit();
347
348 if ( geteuid() != 0 ) {
349 printf("'fs_usage' must be run as root...\n");
350 exit(1);
351 }
352
353 initscr();
354
355 /* get our name */
356 if (argc > 0) {
357 if ((myname = rindex(argv[0], '/')) == 0) {
358 myname = argv[0];
359 }
360 else {
361 myname++;
362 }
363 }
364
365 while ((ch = getopt(argc, argv, "ew")) != EOF) {
366 switch(ch) {
367 case 'e':
368 exclude_pids = 1;
369 exclude_default_pids = 0;
370 break;
371 case 'w':
372 wideflag = 1;
373 if (COLS < MAX_WIDE_MODE_COLS)
374 COLS = MAX_WIDE_MODE_COLS;
375 break;
376 default:
377 exit_usage(myname);
378 }
379 }
380
381 argc -= optind;
382 argv += optind;
383
384 /* If we process any list of pids/cmds, then turn off the defaults */
385 if (argc > 0)
386 exclude_default_pids = 0;
387
388 while (argc > 0 && num_of_pids < (MAX_PIDS - 1)) {
389 select_pid_mode++;
390 argtopid(argv[0]);
391 argc--;
392 argv++;
393 }
394
395 /* Exclude a set of default pids */
396 if (exclude_default_pids)
397 {
398 argtopid("Terminal");
399 argtopid("telnetd");
400 argtopid("sshd");
401 argtopid("rlogind");
402 argtopid("tcsh");
403 argtopid("csh");
404 argtopid("sh");
405 exclude_pids = 1;
406 }
407
408 if (exclude_pids)
409 {
410 if (num_of_pids < (MAX_PIDS - 1))
411 pids[num_of_pids++] = getpid();
412 else
413 exit_usage(myname);
414 }
415
416 #if 0
417 for (i = 0; i < num_of_pids; i++)
418 {
419 if (exclude_pids)
420 printf("exclude pid %d\n", pids[i]);
421 else
422 printf("pid %d\n", pids[i]);
423 }
424 #endif
425
426 /* set up signal handlers */
427 signal(SIGINT, leave);
428 signal(SIGQUIT, leave);
429 signal(SIGTERM, leave);
430 signal(SIGWINCH, sigwinch);
431
432 if ((my_buffer = malloc(SAMPLE_SIZE * sizeof(kd_buf))) == (char *)0)
433 quit("can't allocate memory for tracing info\n");
434
435 set_remove();
436 set_numbufs(SAMPLE_SIZE);
437 set_init();
438
439 if (exclude_pids == 0) {
440 for (i = 0; i < num_of_pids; i++)
441 set_pidcheck(pids[i], 1);
442 } else {
443 for (i = 0; i < num_of_pids; i++)
444 set_pidexclude(pids[i], 1);
445 }
446
447 if (select_pid_mode && !one_good_pid)
448 {
449 /*
450 An attempt to restrict output to a given
451 pid or command has failed. Exit gracefully
452 */
453 set_remove();
454 exit_usage(myname);
455 }
456
457 set_enable(1);
458 getdivisor();
459
460
461 /* main loop */
462
463 while (1) {
464 usleep(1000 * 50);
465
466 sample_sc();
467 }
468 }
469
470 void
471 find_proc_names()
472 {
473 size_t bufSize = 0;
474 struct kinfo_proc *kp;
475 int quit();
476
477 mib[0] = CTL_KERN;
478 mib[1] = KERN_PROC;
479 mib[2] = KERN_PROC_ALL;
480 mib[3] = 0;
481
482 if (sysctl(mib, 4, NULL, &bufSize, NULL, 0) < 0)
483 quit("trace facility failure, KERN_PROC_ALL\n");
484
485 if((kp = (struct kinfo_proc *)malloc(bufSize)) == (struct kinfo_proc *)0)
486 quit("can't allocate memory for proc buffer\n");
487
488 if (sysctl(mib, 4, kp, &bufSize, NULL, 0) < 0)
489 quit("trace facility failure, KERN_PROC_ALL\n");
490
491 kp_nentries = bufSize/ sizeof(struct kinfo_proc);
492 kp_buffer = kp;
493 }
494
495
496 struct th_info *find_thread(int thread, int type) {
497 struct th_info *ti;
498
499 for (ti = th_state; ti < &th_state[cur_max]; ti++) {
500 if (ti->thread == thread) {
501 if (type == ti->type)
502 return(ti);
503 if (ti->in_filemgr) {
504 if (type == -1)
505 return(ti);
506 continue;
507 }
508 if (type == 0)
509 return(ti);
510 }
511 }
512 return ((struct th_info *)0);
513 }
514
515 void
516 set_enable(int val)
517 {
518 mib[0] = CTL_KERN;
519 mib[1] = KERN_KDEBUG;
520 mib[2] = KERN_KDENABLE; /* protocol */
521 mib[3] = val;
522 mib[4] = 0;
523 mib[5] = 0; /* no flags */
524 if (sysctl(mib, 4, NULL, &needed, NULL, 0) < 0)
525 quit("trace facility failure, KERN_KDENABLE\n");
526
527 if (val)
528 trace_enabled = 1;
529 else
530 trace_enabled = 0;
531 }
532
533 void
534 set_numbufs(int nbufs)
535 {
536 mib[0] = CTL_KERN;
537 mib[1] = KERN_KDEBUG;
538 mib[2] = KERN_KDSETBUF;
539 mib[3] = nbufs;
540 mib[4] = 0;
541 mib[5] = 0; /* no flags */
542 if (sysctl(mib, 4, NULL, &needed, NULL, 0) < 0)
543 quit("trace facility failure, KERN_KDSETBUF\n");
544
545 mib[0] = CTL_KERN;
546 mib[1] = KERN_KDEBUG;
547 mib[2] = KERN_KDSETUP;
548 mib[3] = 0;
549 mib[4] = 0;
550 mib[5] = 0; /* no flags */
551 if (sysctl(mib, 3, NULL, &needed, NULL, 0) < 0)
552 quit("trace facility failure, KERN_KDSETUP\n");
553 }
554
555 void
556 set_pidcheck(int pid, int on_off)
557 {
558 kd_regtype kr;
559
560 kr.type = KDBG_TYPENONE;
561 kr.value1 = pid;
562 kr.value2 = on_off;
563 needed = sizeof(kd_regtype);
564 mib[0] = CTL_KERN;
565 mib[1] = KERN_KDEBUG;
566 mib[2] = KERN_KDPIDTR;
567 mib[3] = 0;
568 mib[4] = 0;
569 mib[5] = 0;
570
571 if (sysctl(mib, 3, &kr, &needed, NULL, 0) < 0) {
572 if (on_off == 1)
573 printf("pid %d does not exist\n", pid);
574 }
575 else {
576 one_good_pid++;
577 }
578 }
579
580 /*
581 on_off == 0 turns off pid exclusion
582 on_off == 1 turns on pid exclusion
583 */
584 void
585 set_pidexclude(int pid, int on_off)
586 {
587 kd_regtype kr;
588
589 one_good_pid++;
590
591 kr.type = KDBG_TYPENONE;
592 kr.value1 = pid;
593 kr.value2 = on_off;
594 needed = sizeof(kd_regtype);
595 mib[0] = CTL_KERN;
596 mib[1] = KERN_KDEBUG;
597 mib[2] = KERN_KDPIDEX;
598 mib[3] = 0;
599 mib[4] = 0;
600 mib[5] = 0;
601
602 if (sysctl(mib, 3, &kr, &needed, NULL, 0) < 0) {
603 if (on_off == 1)
604 printf("pid %d does not exist\n", pid);
605 }
606 }
607
608 void
609 get_bufinfo(kbufinfo_t *val)
610 {
611 needed = sizeof (*val);
612 mib[0] = CTL_KERN;
613 mib[1] = KERN_KDEBUG;
614 mib[2] = KERN_KDGETBUF;
615 mib[3] = 0;
616 mib[4] = 0;
617 mib[5] = 0; /* no flags */
618
619 if (sysctl(mib, 3, val, &needed, 0, 0) < 0)
620 quit("trace facility failure, KERN_KDGETBUF\n");
621
622 }
623
624 void
625 set_remove()
626 {
627 extern int errno;
628
629 errno = 0;
630
631 mib[0] = CTL_KERN;
632 mib[1] = KERN_KDEBUG;
633 mib[2] = KERN_KDREMOVE; /* protocol */
634 mib[3] = 0;
635 mib[4] = 0;
636 mib[5] = 0; /* no flags */
637 if (sysctl(mib, 3, NULL, &needed, NULL, 0) < 0)
638 {
639 set_remove_flag = 0;
640
641 if (errno == EBUSY)
642 quit("the trace facility is currently in use...\n fs_usage, sc_usage, and latency use this feature.\n\n");
643 else
644 quit("trace facility failure, KERN_KDREMOVE\n");
645 }
646 }
647
648 void
649 set_init()
650 { kd_regtype kr;
651
652 kr.type = KDBG_RANGETYPE;
653 kr.value1 = 0;
654 kr.value2 = -1;
655 needed = sizeof(kd_regtype);
656 mib[0] = CTL_KERN;
657 mib[1] = KERN_KDEBUG;
658 mib[2] = KERN_KDSETREG;
659 mib[3] = 0;
660 mib[4] = 0;
661 mib[5] = 0; /* no flags */
662
663 if (sysctl(mib, 3, &kr, &needed, NULL, 0) < 0)
664 quit("trace facility failure, KERN_KDSETREG\n");
665
666 mib[0] = CTL_KERN;
667 mib[1] = KERN_KDEBUG;
668 mib[2] = KERN_KDSETUP;
669 mib[3] = 0;
670 mib[4] = 0;
671 mib[5] = 0; /* no flags */
672
673 if (sysctl(mib, 3, NULL, &needed, NULL, 0) < 0)
674 quit("trace facility failure, KERN_KDSETUP\n");
675 }
676
677 void
678 sample_sc()
679 {
680 kd_buf *kd;
681 int i, count;
682 size_t needed;
683 void read_command_map();
684 void create_map_entry();
685
686 /* Get kernel buffer information */
687 get_bufinfo(&bufinfo);
688
689 if (need_new_map) {
690 read_command_map();
691 need_new_map = 0;
692 }
693 needed = bufinfo.nkdbufs * sizeof(kd_buf);
694 mib[0] = CTL_KERN;
695 mib[1] = KERN_KDEBUG;
696 mib[2] = KERN_KDREADTR;
697 mib[3] = 0;
698 mib[4] = 0;
699 mib[5] = 0; /* no flags */
700
701 if (sysctl(mib, 3, my_buffer, &needed, NULL, 0) < 0)
702 quit("trace facility failure, KERN_KDREADTR\n");
703 count = needed;
704
705 if (bufinfo.flags & KDBG_WRAPPED) {
706 printf("buffer wrapped count = %d\n", count);
707
708 for (i = 0; i < cur_max; i++) {
709 th_state[i].thread = 0;
710 th_state[i].pathptr = (long *)0;
711 th_state[i].pathname[0] = 0;
712 }
713 cur_max = 0;
714 need_new_map = 1;
715
716 set_enable(0);
717 set_enable(1);
718 }
719 kd = (kd_buf *)my_buffer;
720 #if 0
721 printf("READTR returned %d items\n", count);
722 #endif
723 for (i = 0; i < count; i++) {
724 int debugid, thread;
725 int type, n;
726 long *sargptr;
727 unsigned long long now;
728 struct th_info *ti;
729 void enter_syscall();
730 void exit_syscall();
731 void kill_thread_map();
732
733 thread = kd[i].arg5 & KDBG_THREAD_MASK;
734 debugid = kd[i].debugid;
735 type = kd[i].debugid & DBG_FUNC_MASK;
736
737 switch (type) {
738
739 case TRACE_DATA_NEWTHREAD:
740
741 for (n = 0, ti = th_state; ti < &th_state[MAX_THREADS]; ti++, n++) {
742 if (ti->thread == 0)
743 break;
744 }
745 if (ti == &th_state[MAX_THREADS])
746 continue;
747 if (n >= cur_max)
748 cur_max = n + 1;
749
750 ti->thread = thread;
751 ti->child_thread = kd[i].arg1;
752 continue;
753
754 case TRACE_STRING_NEWTHREAD:
755 if ((ti = find_thread(thread, 0)) == (struct th_info *)0)
756 continue;
757 if (ti->child_thread == 0)
758 continue;
759 create_map_entry(ti->child_thread, (char *)&kd[i].arg1);
760
761 if (ti == &th_state[cur_max - 1])
762 cur_max--;
763 ti->child_thread = 0;
764 ti->thread = 0;
765 continue;
766
767 case TRACE_STRING_EXEC:
768 create_map_entry(thread, (char *)&kd[i].arg1);
769 continue;
770
771 case BSC_exit:
772 kill_thread_map(thread);
773 continue;
774
775 case MACH_sched:
776 case MACH_stkhandoff:
777 if (ti = find_thread(thread, 0))
778 ti->waited = 1;
779 continue;
780
781 case VFS_LOOKUP:
782 if ((ti = find_thread(thread, 0)) == (struct th_info *)0)
783 continue;
784
785 if (!ti->pathptr) {
786 sargptr = (long *)&ti->pathname[0];
787 memset(&ti->pathname[0], 0, (PATHLENGTH + 1));
788 *sargptr++ = kd[i].arg2;
789 *sargptr++ = kd[i].arg3;
790 *sargptr++ = kd[i].arg4;
791 ti->pathptr = sargptr;
792
793 } else {
794 sargptr = ti->pathptr;
795
796 /*
797 We don't want to overrun our pathname buffer if the
798 kernel sends us more VFS_LOOKUP entries than we can
799 handle.
800 */
801
802 if ((long *)sargptr >= (long *)&ti->pathname[PATHLENGTH])
803 continue;
804
805 *sargptr++ = kd[i].arg1;
806 *sargptr++ = kd[i].arg2;
807 *sargptr++ = kd[i].arg3;
808 *sargptr++ = kd[i].arg4;
809 ti->pathptr = sargptr;
810 }
811 continue;
812 }
813 now = (((unsigned long long)kd[i].timestamp.tv_sec) << 32) |
814 (unsigned long long)((unsigned int)(kd[i].timestamp.tv_nsec));
815
816 if (debugid & DBG_FUNC_START) {
817 char *p;
818
819 switch (type) {
820 case FILEMGR_PBGETCATALOGINFO:
821 p = "GetCatalogInfo";
822 break;
823 case FILEMGR_PBGETCATALOGINFOBULK:
824 p = "GetCatalogInfoBulk";
825 break;
826 case FILEMGR_PBCREATEFILEUNICODE:
827 p = "CreateFileUnicode";
828 break;
829 case FILEMGR_PBCREATEDIRECTORYUNICODE:
830 p = "CreateDirectoryUnicode";
831 break;
832 case FILEMGR_PBCREATEFORK:
833 p = "PBCreateFork";
834 break;
835 case FILEMGR_PBDELETEFORK:
836 p = "PBDeleteFork";
837 break;
838 case FILEMGR_PBITERATEFORK:
839 p = "PBIterateFork";
840 break;
841 case FILEMGR_PBOPENFORK:
842 p = "PBOpenFork";
843 break;
844 case FILEMGR_PBREADFORK:
845 p = "PBReadFork";
846 break;
847 case FILEMGR_PBWRITEFORK:
848 p = "PBWriteFork";
849 break;
850 case FILEMGR_PBALLOCATEFORK:
851 p = "PBAllocateFork";
852 break;
853 case FILEMGR_PBDELETEOBJECT:
854 p = "PBDeleteObject";
855 break;
856 case FILEMGR_PBEXCHANGEOBJECT:
857 p = "PBExchangeObject";
858 break;
859 case FILEMGR_PBGETFORKCBINFO:
860 p = "PBGetForkCBInfo";
861 break;
862 case FILEMGR_PBGETVOLUMEINFO:
863 p = "PBGetVolumeInfo";
864 break;
865 case FILEMGR_PBMAKEFSREF:
866 p = "PBMakeFSRef";
867 break;
868 case FILEMGR_PBMAKEFSREFUNICODE:
869 p = "PBMakeFSRefUnicode";
870 break;
871 case FILEMGR_PBMOVEOBJECT:
872 p = "PBMoveObject";
873 break;
874 case FILEMGR_PBOPENITERATOR:
875 p = "PBOpenIterator";
876 break;
877 case FILEMGR_PBRENAMEUNICODE:
878 p = "PBRenameUnicode";
879 break;
880 case FILEMGR_PBSETCATALOGINFO:
881 p = "SetCatalogInfo";
882 break;
883 case FILEMGR_PBSETVOLUMEINFO:
884 p = "SetVolumeInfo";
885 break;
886 case FILEMGR_FSREFMAKEPATH:
887 p = "FSRefMakePath";
888 break;
889 case FILEMGR_FSPATHMAKEREF:
890 p = "FSPathMakeRef";
891 break;
892 // SPEC based calls
893 case FILEMGR_PBGETCATINFO:
894 p = "GetCatInfo";
895 break;
896 case FILEMGR_PBGETCATINFOLITE:
897 p = "GetCatInfoLite";
898 break;
899 case FILEMGR_PBHGETFINFO:
900 p = "PBHGetFInfo";
901 break;
902 case FILEMGR_PBXGETVOLINFO:
903 p = "PBXGetVolInfo";
904 break;
905 case FILEMGR_PBHCREATE:
906 p = "PBHCreate";
907 break;
908 case FILEMGR_PBHOPENDF:
909 p = "PBHOpenDF";
910 break;
911 case FILEMGR_PBHOPENRF:
912 p = "PBHOpenRF";
913 break;
914 case FILEMGR_PBHGETDIRACCESS:
915 p = "PBHGetDirAccess";
916 break;
917 case FILEMGR_PBHSETDIRACCESS:
918 p = "PBHSetDirAccess";
919 break;
920 case FILEMGR_PBHMAPID:
921 p = "PBHMapID";
922 break;
923 case FILEMGR_PBHMAPNAME:
924 p = "PBHMapName";
925 break;
926 case FILEMGR_PBCLOSE:
927 p = "PBClose";
928 break;
929 case FILEMGR_PBFLUSHFILE:
930 p = "PBFlushFile";
931 break;
932 case FILEMGR_PBGETEOF:
933 p = "PBGetEOF";
934 break;
935 case FILEMGR_PBSETEOF:
936 p = "PBSetEOF";
937 break;
938 case FILEMGR_PBGETFPOS:
939 p = "PBGetFPos";
940 break;
941 case FILEMGR_PBREAD:
942 p = "PBRead";
943 break;
944 case FILEMGR_PBWRITE:
945 p = "PBWrite";
946 break;
947 case FILEMGR_PBGETFCBINFO:
948 p = "PBGetFCBInfo";
949 break;
950 case FILEMGR_PBSETFINFO:
951 p = "PBSetFInfo";
952 break;
953 case FILEMGR_PBALLOCATE:
954 p = "PBAllocate";
955 break;
956 case FILEMGR_PBALLOCCONTIG:
957 p = "PBAllocContig";
958 break;
959 case FILEMGR_PBSETFPOS:
960 p = "PBSetFPos";
961 break;
962 case FILEMGR_PBSETCATINFO:
963 p = "PBSetCatInfo";
964 break;
965 case FILEMGR_PBGETVOLPARMS:
966 p = "PBGetVolParms";
967 break;
968 case FILEMGR_PBSETVINFO:
969 p = "PBSetVInfo";
970 break;
971 case FILEMGR_PBMAKEFSSPEC:
972 p = "PBMakeFSSpec";
973 break;
974 case FILEMGR_PBHGETVINFO:
975 p = "PBHGetVInfo";
976 break;
977 case FILEMGR_PBCREATEFILEIDREF:
978 p = "PBCreateFileIDRef";
979 break;
980 case FILEMGR_PBDELETEFILEIDREF:
981 p = "PBDeleteFileIDRef";
982 break;
983 case FILEMGR_PBRESOLVEFILEIDREF:
984 p = "PBResolveFileIDRef";
985 break;
986 case FILEMGR_PBFLUSHVOL:
987 p = "PBFlushVol";
988 break;
989 case FILEMGR_PBHRENAME:
990 p = "PBHRename";
991 break;
992 case FILEMGR_PBCATMOVE:
993 p = "PBCatMove";
994 break;
995 case FILEMGR_PBEXCHANGEFILES:
996 p = "PBExchangeFiles";
997 break;
998 case FILEMGR_PBHDELETE:
999 p = "PBHDelete";
1000 break;
1001 case FILEMGR_PBDIRCREATE:
1002 p = "PBDirCreate";
1003 break;
1004 case FILEMGR_PBCATSEARCH:
1005 p = "PBCatSearch";
1006 break;
1007 case FILEMGR_PBHSETFLOCK:
1008 p = "PBHSetFlock";
1009 break;
1010 case FILEMGR_PBHRSTFLOCK:
1011 p = "PBHRstFLock";
1012 break;
1013 case FILEMGR_PBLOCKRANGE:
1014 p = "PBLockRange";
1015 break;
1016 case FILEMGR_PBUNLOCKRANGE:
1017 p = "PBUnlockRange";
1018 break;
1019 default:
1020 p = (char *)0;
1021 break;
1022 }
1023 enter_syscall(thread, type, &kd[i], p, (double)now);
1024 continue;
1025 }
1026 switch (type) {
1027
1028 case MACH_vmfault:
1029 if (kd[i].arg2 == DBG_PAGEIN_FAULT)
1030 exit_syscall("PAGE_IN", thread, type, 0, kd[i].arg1, 0, 2, (double)now);
1031 else {
1032 if (ti = find_thread(thread, type)) {
1033 if (ti == &th_state[cur_max - 1])
1034 cur_max--;
1035 ti->thread = 0;
1036 }
1037 }
1038 break;
1039
1040 case MSC_map_fd:
1041 exit_syscall("map_fd", thread, type, kd[i].arg1, kd[i].arg2, 1, 0, (double)now);
1042 break;
1043
1044 case BSC_mmap:
1045 exit_syscall("mmap", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1046 break;
1047
1048 case BSC_recvmsg:
1049 exit_syscall("recvmsg", thread, type, kd[i].arg1, kd[i].arg2, 1, 1, (double)now);
1050 break;
1051
1052 case BSC_sendmsg:
1053 exit_syscall("sendmsg", thread, type, kd[i].arg1, kd[i].arg2, 1, 1, (double)now);
1054 break;
1055
1056 case BSC_recvfrom:
1057 exit_syscall("recvfrom", thread, type, kd[i].arg1, kd[i].arg2, 1, 1, (double)now);
1058 break;
1059
1060 case BSC_sendto:
1061 exit_syscall("sendto", thread, type, kd[i].arg1, kd[i].arg2, 1, 1, (double)now);
1062 break;
1063
1064 case BSC_stat:
1065 exit_syscall("stat", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1066 break;
1067
1068 case BSC_open:
1069 exit_syscall("open", thread, type, kd[i].arg1, kd[i].arg2, 2, 0, (double)now);
1070 break;
1071
1072 case BSC_close:
1073 exit_syscall("close", thread, type, kd[i].arg1, kd[i].arg2, 1, 0, (double)now);
1074 break;
1075
1076 case BSC_read:
1077 exit_syscall("read", thread, type, kd[i].arg1, kd[i].arg2, 1, 1, (double)now);
1078 break;
1079
1080 case BSC_write:
1081 exit_syscall("write", thread, type, kd[i].arg1, kd[i].arg2, 1, 1, (double)now);
1082 break;
1083
1084 case BSC_fstat:
1085 exit_syscall("fstat", thread, type, kd[i].arg1, kd[i].arg2, 1, 0, (double)now);
1086 break;
1087
1088 case BSC_lstat:
1089 exit_syscall("lstat", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1090 break;
1091
1092 case BSC_link:
1093 exit_syscall("link", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1094 break;
1095
1096 case BSC_unlink:
1097 exit_syscall("unlink", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1098 break;
1099
1100 case BSC_mknod:
1101 exit_syscall("mknod", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1102 break;
1103
1104 case BSC_chmod:
1105 exit_syscall("chmod", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1106 break;
1107
1108 case BSC_chown:
1109 exit_syscall("chown", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1110 break;
1111
1112 case BSC_access:
1113 exit_syscall("access", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1114 break;
1115
1116 case BSC_chflags:
1117 exit_syscall("chflags", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1118 break;
1119
1120 case BSC_fchflags:
1121 exit_syscall("fchflags", thread, type, kd[i].arg1, kd[i].arg2, 1, 0, (double)now);
1122 break;
1123
1124 case BSC_sync:
1125 exit_syscall("sync", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1126 break;
1127
1128 case BSC_symlink:
1129 exit_syscall("symlink", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1130 break;
1131
1132 case BSC_readlink:
1133 exit_syscall("readlink", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1134 break;
1135
1136 case BSC_fsync:
1137 exit_syscall("fsync", thread, type, kd[i].arg1, kd[i].arg2, 1, 0, (double)now);
1138 break;
1139
1140 case BSC_readv:
1141 exit_syscall("readv", thread, type, kd[i].arg1, kd[i].arg2, 1, 1, (double)now);
1142 break;
1143
1144 case BSC_writev:
1145 exit_syscall("writev", thread, type, kd[i].arg1, kd[i].arg2, 1, 1, (double)now);
1146 break;
1147
1148 case BSC_fchown:
1149 exit_syscall("fchown", thread, type, kd[i].arg1, kd[i].arg2, 1, 0, (double)now);
1150 break;
1151
1152 case BSC_fchmod:
1153 exit_syscall("fchmod", thread, type, kd[i].arg1, kd[i].arg2, 1, 0, (double)now);
1154 break;
1155
1156 case BSC_rename:
1157 exit_syscall("rename", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1158 break;
1159
1160 case BSC_mkdir:
1161 exit_syscall("mkdir", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1162 break;
1163
1164 case BSC_rmdir:
1165 exit_syscall("rmdir", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1166 break;
1167
1168 case BSC_statfs:
1169 exit_syscall("statfs", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1170 break;
1171
1172 case BSC_fstatfs:
1173 exit_syscall("fstatfs", thread, type, kd[i].arg1, kd[i].arg2, 1, 0, (double)now);
1174 break;
1175
1176 case BSC_pathconf:
1177 exit_syscall("pathconf", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1178 break;
1179
1180 case BSC_fpathconf:
1181 exit_syscall("fpathconf", thread, type, kd[i].arg1, kd[i].arg2, 1, 0, (double)now);
1182 break;
1183
1184 case BSC_getdirentries:
1185 exit_syscall("getdirentries", thread, type, kd[i].arg1, kd[i].arg2, 1, 1, (double)now);
1186 break;
1187
1188 case BSC_lseek:
1189 exit_syscall("lseek", thread, type, kd[i].arg1, kd[i].arg3, 1, 5, (double)now);
1190 break;
1191
1192 case BSC_truncate:
1193 exit_syscall("truncate", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1194 break;
1195
1196 case BSC_ftruncate:
1197 exit_syscall("ftruncate", thread, type, kd[i].arg1, kd[i].arg2, 1, 3, (double)now);
1198 break;
1199
1200 case BSC_statv:
1201 exit_syscall("statv", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1202 break;
1203
1204 case BSC_lstatv:
1205 exit_syscall("lstatv", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1206 break;
1207
1208 case BSC_fstatv:
1209 exit_syscall("fstatv", thread, type, kd[i].arg1, kd[i].arg2, 1, 0, (double)now);
1210 break;
1211
1212 case BSC_mkcomplex:
1213 exit_syscall("mkcomplex", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1214 break;
1215
1216 case BSC_getattrlist:
1217 exit_syscall("getattrlist", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1218 break;
1219
1220 case BSC_setattrlist:
1221 exit_syscall("setattrlist", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1222 break;
1223
1224 case BSC_getdirentriesattr:
1225 exit_syscall("getdirentriesattr", thread, type, kd[i].arg1, kd[i].arg2, 0, 1, (double)now);
1226 break;
1227
1228 case BSC_exchangedata:
1229 exit_syscall("exchangedata", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1230 break;
1231
1232 case BSC_checkuseraccess:
1233 exit_syscall("checkuseraccess", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1234 break;
1235
1236 case BSC_searchfs:
1237 exit_syscall("searchfs", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1238 break;
1239
1240 case FILEMGR_PBGETCATALOGINFO:
1241 exit_syscall("GetCatalogInfo", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1242 break;
1243 case FILEMGR_PBGETCATALOGINFOBULK:
1244 exit_syscall("GetCatalogInfoBulk", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1245 break;
1246 case FILEMGR_PBCREATEFILEUNICODE:
1247 exit_syscall("CreateFileUnicode", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1248 break;
1249 case FILEMGR_PBCREATEDIRECTORYUNICODE:
1250 exit_syscall("CreateDirectoryUnicode", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1251 break;
1252 case FILEMGR_PBCREATEFORK:
1253 exit_syscall("PBCreateFork", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1254 break;
1255 case FILEMGR_PBDELETEFORK:
1256 exit_syscall("PBDeleteFork", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1257 break;
1258 case FILEMGR_PBITERATEFORK:
1259 exit_syscall("PBIterateFork", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1260 break;
1261 case FILEMGR_PBOPENFORK:
1262 exit_syscall("PBOpenFork", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1263 break;
1264 case FILEMGR_PBREADFORK:
1265 exit_syscall("PBReadFork", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1266 break;
1267 case FILEMGR_PBWRITEFORK:
1268 exit_syscall("PBWriteFork", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1269 break;
1270 case FILEMGR_PBALLOCATEFORK:
1271 exit_syscall("PBAllocateFork", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1272 break;
1273 case FILEMGR_PBDELETEOBJECT:
1274 exit_syscall("PBDeleteObject", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1275 break;
1276 case FILEMGR_PBEXCHANGEOBJECT:
1277 exit_syscall("PBExchangeObject", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1278 break;
1279 case FILEMGR_PBGETFORKCBINFO:
1280 exit_syscall("PBGetForkCBInfo", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1281 break;
1282 case FILEMGR_PBGETVOLUMEINFO:
1283 exit_syscall("PBGetVolumeInfo", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1284 break;
1285 case FILEMGR_PBMAKEFSREF:
1286 exit_syscall("PBMakeFSRef", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1287 break;
1288 case FILEMGR_PBMAKEFSREFUNICODE:
1289 exit_syscall("PBMakeFSRefUnicode", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1290 break;
1291 case FILEMGR_PBMOVEOBJECT:
1292 exit_syscall("PBMoveObject", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1293 break;
1294 case FILEMGR_PBOPENITERATOR:
1295 exit_syscall("PBOpenIterator", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1296 break;
1297 case FILEMGR_PBRENAMEUNICODE:
1298 exit_syscall("PBRenameUnicode", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1299 break;
1300 case FILEMGR_PBSETCATALOGINFO:
1301 exit_syscall("PBSetCatalogInfo", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1302 break;
1303 case FILEMGR_PBSETVOLUMEINFO:
1304 exit_syscall("PBSetVolumeInfo", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1305 break;
1306 case FILEMGR_FSREFMAKEPATH:
1307 exit_syscall("FSRefMakePath", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1308 break;
1309 case FILEMGR_FSPATHMAKEREF:
1310 exit_syscall("FSPathMakeRef", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1311 break;
1312 case FILEMGR_PBGETCATINFO:
1313 exit_syscall("GetCatInfo", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1314 break;
1315 case FILEMGR_PBGETCATINFOLITE:
1316 exit_syscall("GetCatInfoLite", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1317 break;
1318 case FILEMGR_PBHGETFINFO:
1319 exit_syscall("PBHGetFInfo", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1320 break;
1321 case FILEMGR_PBXGETVOLINFO:
1322 exit_syscall("PBXGetVolInfo", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1323 break;
1324 case FILEMGR_PBHCREATE:
1325 exit_syscall("PBHCreate", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1326 break;
1327 case FILEMGR_PBHOPENDF:
1328 exit_syscall("PBHOpenDF", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1329 break;
1330 case FILEMGR_PBHOPENRF:
1331 exit_syscall("PBHOpenRF", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1332 break;
1333 case FILEMGR_PBHGETDIRACCESS:
1334 exit_syscall("PBHGetDirAccess", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1335 break;
1336 case FILEMGR_PBHSETDIRACCESS:
1337 exit_syscall("PBHSetDirAccess", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1338 break;
1339 case FILEMGR_PBHMAPID:
1340 exit_syscall("PBHMapID", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1341 break;
1342 case FILEMGR_PBHMAPNAME:
1343 exit_syscall("PBHMapName", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1344 break;
1345 case FILEMGR_PBCLOSE:
1346 exit_syscall("PBClose", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1347 break;
1348 case FILEMGR_PBFLUSHFILE:
1349 exit_syscall("PBFlushFile", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1350 break;
1351 case FILEMGR_PBGETEOF:
1352 exit_syscall("PBGetEOF", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1353 break;
1354 case FILEMGR_PBSETEOF:
1355 exit_syscall("PBSetEOF", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1356 break;
1357 case FILEMGR_PBGETFPOS:
1358 exit_syscall("PBGetFPos", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1359 break;
1360 case FILEMGR_PBREAD:
1361 exit_syscall("PBRead", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1362 break;
1363 case FILEMGR_PBWRITE:
1364 exit_syscall("PBWrite", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1365 break;
1366 case FILEMGR_PBGETFCBINFO:
1367 exit_syscall("PBGetFCBInfo", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1368 break;
1369 case FILEMGR_PBSETFINFO:
1370 exit_syscall("PBSetFInfo", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1371 break;
1372 case FILEMGR_PBALLOCATE:
1373 exit_syscall("PBAllocate", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1374 break;
1375 case FILEMGR_PBALLOCCONTIG:
1376 exit_syscall("PBAllocContig", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1377 break;
1378 case FILEMGR_PBSETFPOS:
1379 exit_syscall("PBSetFPos", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1380 break;
1381 case FILEMGR_PBSETCATINFO:
1382 exit_syscall("PBSetCatInfo", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1383 break;
1384 case FILEMGR_PBGETVOLPARMS:
1385 exit_syscall("PBGetVolParms", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1386 break;
1387 case FILEMGR_PBSETVINFO:
1388 exit_syscall("PBSetVInfo", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1389 break;
1390 case FILEMGR_PBMAKEFSSPEC:
1391 exit_syscall("PBMakeFSSpec", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1392 break;
1393 case FILEMGR_PBHGETVINFO:
1394 exit_syscall("PBHGetVInfo", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1395 break;
1396 case FILEMGR_PBCREATEFILEIDREF:
1397 exit_syscall("PBCreateFileIDRef", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1398 break;
1399 case FILEMGR_PBDELETEFILEIDREF:
1400 exit_syscall("PBDeleteFileIDRef", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1401 break;
1402 case FILEMGR_PBRESOLVEFILEIDREF:
1403 exit_syscall("PBResolveFileIDRef", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1404 break;
1405 case FILEMGR_PBFLUSHVOL:
1406 exit_syscall("PBFlushVol", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1407 break;
1408 case FILEMGR_PBHRENAME:
1409 exit_syscall("PBHRename", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1410 break;
1411 case FILEMGR_PBCATMOVE:
1412 exit_syscall("PBCatMove", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1413 break;
1414 case FILEMGR_PBEXCHANGEFILES:
1415 exit_syscall("PBExchangeFiles", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1416 break;
1417 case FILEMGR_PBHDELETE:
1418 exit_syscall("PBHDelete", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1419 break;
1420 case FILEMGR_PBDIRCREATE:
1421 exit_syscall("PBDirCreate", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1422 break;
1423 case FILEMGR_PBCATSEARCH:
1424 exit_syscall("PBCatSearch", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1425 break;
1426 case FILEMGR_PBHSETFLOCK:
1427 exit_syscall("PBHSetFLock", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1428 break;
1429 case FILEMGR_PBHRSTFLOCK:
1430 exit_syscall("PBHRstFLock", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1431 break;
1432 case FILEMGR_PBLOCKRANGE:
1433 exit_syscall("PBLockRange", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1434 break;
1435 case FILEMGR_PBUNLOCKRANGE:
1436 exit_syscall("PBUnlockRange", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
1437 break;
1438 default:
1439 break;
1440 }
1441 }
1442 fflush(0);
1443 }
1444
1445 void
1446 enter_syscall(int thread, int type, kd_buf *kd, char *name, double now)
1447 {
1448 struct th_info *ti;
1449 int i;
1450 int secs;
1451 int usecs;
1452 long long l_usecs;
1453 long curr_time;
1454 kd_threadmap *map;
1455 kd_threadmap *find_thread_map();
1456 int clen = 0;
1457 int tsclen = 0;
1458 int nmclen = 0;
1459 int argsclen = 0;
1460 char buf[MAXCOLS];
1461
1462 switch (type) {
1463
1464 case MACH_vmfault:
1465 case MSC_map_fd:
1466 case BSC_mmap:
1467 case BSC_recvmsg:
1468 case BSC_sendmsg:
1469 case BSC_recvfrom:
1470 case BSC_sendto:
1471 case BSC_stat:
1472 case BSC_open:
1473 case BSC_close:
1474 case BSC_read:
1475 case BSC_write:
1476 case BSC_fstat:
1477 case BSC_lstat:
1478 case BSC_link:
1479 case BSC_unlink:
1480 case BSC_mknod:
1481 case BSC_chmod:
1482 case BSC_chown:
1483 case BSC_access:
1484 case BSC_chflags:
1485 case BSC_fchflags:
1486 case BSC_sync:
1487 case BSC_symlink:
1488 case BSC_readlink:
1489 case BSC_fsync:
1490 case BSC_readv:
1491 case BSC_writev:
1492 case BSC_fchown:
1493 case BSC_fchmod:
1494 case BSC_rename:
1495 case BSC_mkdir:
1496 case BSC_rmdir:
1497 case BSC_statfs:
1498 case BSC_fstatfs:
1499 case BSC_pathconf:
1500 case BSC_fpathconf:
1501 case BSC_getdirentries:
1502 case BSC_lseek:
1503 case BSC_truncate:
1504 case BSC_ftruncate:
1505 case BSC_statv:
1506 case BSC_lstatv:
1507 case BSC_fstatv:
1508 case BSC_mkcomplex:
1509 case BSC_getattrlist:
1510 case BSC_setattrlist:
1511 case BSC_getdirentriesattr:
1512 case BSC_exchangedata:
1513 case BSC_checkuseraccess:
1514 case BSC_searchfs:
1515 case FILEMGR_PBGETCATALOGINFO:
1516 case FILEMGR_PBGETCATALOGINFOBULK:
1517 case FILEMGR_PBCREATEFILEUNICODE:
1518 case FILEMGR_PBCREATEDIRECTORYUNICODE:
1519 case FILEMGR_PBCREATEFORK:
1520 case FILEMGR_PBDELETEFORK:
1521 case FILEMGR_PBITERATEFORK:
1522 case FILEMGR_PBOPENFORK:
1523 case FILEMGR_PBREADFORK:
1524 case FILEMGR_PBWRITEFORK:
1525 case FILEMGR_PBALLOCATEFORK:
1526 case FILEMGR_PBDELETEOBJECT:
1527 case FILEMGR_PBEXCHANGEOBJECT:
1528 case FILEMGR_PBGETFORKCBINFO:
1529 case FILEMGR_PBGETVOLUMEINFO:
1530 case FILEMGR_PBMAKEFSREF:
1531 case FILEMGR_PBMAKEFSREFUNICODE:
1532 case FILEMGR_PBMOVEOBJECT:
1533 case FILEMGR_PBOPENITERATOR:
1534 case FILEMGR_PBRENAMEUNICODE:
1535 case FILEMGR_PBSETCATALOGINFO:
1536 case FILEMGR_PBSETVOLUMEINFO:
1537 case FILEMGR_FSREFMAKEPATH:
1538 case FILEMGR_FSPATHMAKEREF:
1539
1540 case FILEMGR_PBGETCATINFO:
1541 case FILEMGR_PBGETCATINFOLITE:
1542 case FILEMGR_PBHGETFINFO:
1543 case FILEMGR_PBXGETVOLINFO:
1544 case FILEMGR_PBHCREATE:
1545 case FILEMGR_PBHOPENDF:
1546 case FILEMGR_PBHOPENRF:
1547 case FILEMGR_PBHGETDIRACCESS:
1548 case FILEMGR_PBHSETDIRACCESS:
1549 case FILEMGR_PBHMAPID:
1550 case FILEMGR_PBHMAPNAME:
1551 case FILEMGR_PBCLOSE:
1552 case FILEMGR_PBFLUSHFILE:
1553 case FILEMGR_PBGETEOF:
1554 case FILEMGR_PBSETEOF:
1555 case FILEMGR_PBGETFPOS:
1556 case FILEMGR_PBREAD:
1557 case FILEMGR_PBWRITE:
1558 case FILEMGR_PBGETFCBINFO:
1559 case FILEMGR_PBSETFINFO:
1560 case FILEMGR_PBALLOCATE:
1561 case FILEMGR_PBALLOCCONTIG:
1562 case FILEMGR_PBSETFPOS:
1563 case FILEMGR_PBSETCATINFO:
1564 case FILEMGR_PBGETVOLPARMS:
1565 case FILEMGR_PBSETVINFO:
1566 case FILEMGR_PBMAKEFSSPEC:
1567 case FILEMGR_PBHGETVINFO:
1568 case FILEMGR_PBCREATEFILEIDREF:
1569 case FILEMGR_PBDELETEFILEIDREF:
1570 case FILEMGR_PBRESOLVEFILEIDREF:
1571 case FILEMGR_PBFLUSHVOL:
1572 case FILEMGR_PBHRENAME:
1573 case FILEMGR_PBCATMOVE:
1574 case FILEMGR_PBEXCHANGEFILES:
1575 case FILEMGR_PBHDELETE:
1576 case FILEMGR_PBDIRCREATE:
1577 case FILEMGR_PBCATSEARCH:
1578 case FILEMGR_PBHSETFLOCK:
1579 case FILEMGR_PBHRSTFLOCK:
1580 case FILEMGR_PBLOCKRANGE:
1581 case FILEMGR_PBUNLOCKRANGE:
1582
1583
1584 for (i = 0, ti = th_state; ti < &th_state[MAX_THREADS]; ti++, i++) {
1585 if (ti->thread == 0)
1586 break;
1587 }
1588 if (ti == &th_state[MAX_THREADS])
1589 return;
1590 if (i >= cur_max)
1591 cur_max = i + 1;
1592
1593 if ((type >> 24) == FILEMGR_CLASS) {
1594 ti->in_filemgr = 1;
1595
1596 l_usecs = (long long)(now / divisor);
1597 secs = l_usecs / 1000000;
1598
1599 if (bias_secs == 0) {
1600 curr_time = time((long *)0);
1601 bias_secs = curr_time - secs;
1602 }
1603 curr_time = bias_secs + secs;
1604 sprintf(buf, "%-8.8s", &(ctime(&curr_time)[11]));
1605 tsclen = strlen(buf);
1606
1607 if (COLS > MAXCOLS || wideflag) {
1608 usecs = l_usecs - (long long)((long long)secs * 1000000);
1609 sprintf(&buf[tsclen], ".%03ld", (long)usecs / 1000);
1610 tsclen = strlen(buf);
1611 }
1612
1613 /* Print timestamp column */
1614 printf(buf);
1615
1616 map = find_thread_map(thread);
1617 if (map) {
1618 sprintf(buf, " %-25.25s ", name);
1619 nmclen = strlen(buf);
1620 printf(buf);
1621
1622 sprintf(buf, "(%d, 0x%x, 0x%x, 0x%x)", (short)kd->arg1, kd->arg2, kd->arg3, kd->arg4);
1623 argsclen = strlen(buf);
1624
1625 /*
1626 Calculate white space out to command
1627 */
1628 if (COLS > MAXCOLS || wideflag)
1629 {
1630 clen = COLS - (tsclen + nmclen + argsclen + 20);
1631 }
1632 else
1633 clen = COLS - (tsclen + nmclen + argsclen + 12);
1634
1635 if(clen > 0)
1636 {
1637 printf(buf); /* print the kdargs */
1638 memset(buf, ' ', clen);
1639 buf[clen] = '\0';
1640 printf(buf);
1641 }
1642 else if ((argsclen + clen) > 0)
1643 {
1644 /* no room so wipe out the kdargs */
1645 memset(buf, ' ', (argsclen + clen));
1646 buf[argsclen + clen] = '\0';
1647 printf(buf);
1648 }
1649
1650 if (COLS > MAXCOLS || wideflag)
1651 printf("%-20.20s\n", map->command);
1652 else
1653 printf("%-12.12s\n", map->command);
1654 } else
1655 printf(" %-24.24s (%5d, %#x, 0x%x, 0x%x)\n", name, (short)kd->arg1, kd->arg2, kd->arg3, kd->arg4);
1656 } else {
1657 ti->in_filemgr = 0;
1658 }
1659 ti->thread = thread;
1660 ti->waited = 0;
1661 ti->type = type;
1662 ti->stime = now;
1663 ti->arg1 = kd->arg1;
1664 ti->arg2 = kd->arg2;
1665 ti->arg3 = kd->arg3;
1666 ti->arg4 = kd->arg4;
1667 ti->pathptr = (long *)0;
1668 ti->pathname[0] = 0;
1669
1670 break;
1671
1672 default:
1673 break;
1674 }
1675 fflush (0);
1676 }
1677
1678
1679 void
1680 exit_syscall(char *sc_name, int thread, int type, int error, int retval,
1681 int has_fd, int has_ret, double now)
1682 {
1683 struct th_info *ti;
1684 int secs;
1685 int usecs;
1686 int nopadding;
1687 long long l_usecs;
1688 long curr_time;
1689 kd_threadmap *map;
1690 kd_threadmap *find_thread_map();
1691 int len = 0;
1692 int clen = 0;
1693 char buf[MAXCOLS];
1694
1695 if ((ti = find_thread(thread, type)) == (struct th_info *)0)
1696 return;
1697 map = find_thread_map(thread);
1698 l_usecs = (long long)(now / divisor);
1699 secs = l_usecs / 1000000;
1700
1701 if (bias_secs == 0) {
1702 curr_time = time((long *)0);
1703 bias_secs = curr_time - secs;
1704 }
1705 curr_time = bias_secs + secs;
1706 sprintf(buf, "%-8.8s", &(ctime(&curr_time)[11]));
1707 clen = strlen(buf);
1708
1709 if (COLS > MAXCOLS || wideflag) {
1710 nopadding = 0;
1711 usecs = l_usecs - (long long)((long long)secs * 1000000);
1712 sprintf(&buf[clen], ".%03ld", (long)usecs / 1000);
1713 clen = strlen(buf);
1714 if ((type >> 24) != FILEMGR_CLASS) {
1715 if (find_thread(thread, -1)) {
1716 sprintf(&buf[clen], " ");
1717 clen = strlen(buf);
1718 nopadding = 1;
1719 }
1720 }
1721 } else
1722 nopadding = 1;
1723
1724 if (((type >> 24) == FILEMGR_CLASS) && (COLS > MAXCOLS || wideflag))
1725 sprintf(&buf[clen], " %-18.18s", sc_name);
1726 else
1727 sprintf(&buf[clen], " %-15.15s", sc_name);
1728
1729 clen = strlen(buf);
1730
1731 if (COLS > MAXCOLS || wideflag) {
1732 if (has_fd == 2 && error == 0)
1733 sprintf(&buf[clen], " F=%-3d", retval);
1734 else if (has_fd == 1)
1735 sprintf(&buf[clen], " F=%-3d", ti->arg1);
1736 else if (has_ret != 2)
1737 sprintf(&buf[clen], " ");
1738
1739 clen = strlen(buf);
1740
1741 if (error)
1742 sprintf(&buf[clen], "[%3d] ", error);
1743 else if (has_ret == 3)
1744 sprintf(&buf[clen], "O=0x%8.8x", ti->arg3);
1745 else if (has_ret == 5)
1746 sprintf(&buf[clen], "O=0x%8.8x", retval);
1747 else if (has_ret == 2)
1748 sprintf(&buf[clen], " A=0x%8.8x ", retval);
1749 else if (has_ret == 1)
1750 sprintf(&buf[clen], " B=0x%-6x", retval);
1751 else if (has_ret == 4)
1752 sprintf(&buf[clen], "R=0x%-8x", retval);
1753 else
1754 sprintf(&buf[clen], " ");
1755 clen = strlen(buf);
1756 }
1757 printf(buf);
1758
1759 /*
1760 Calculate space available to print pathname
1761 */
1762 if (COLS > MAXCOLS || wideflag)
1763 clen = COLS - (clen + 13 + 20);
1764 else
1765 clen = COLS - (clen + 13 + 12);
1766
1767 if ((type >> 24) != FILEMGR_CLASS && !nopadding)
1768 clen -= 3;
1769
1770 sprintf(&buf[0], " %s ", ti->pathname);
1771 len = strlen(buf);
1772
1773 if (clen > len)
1774 {
1775 /*
1776 Add null padding if column length
1777 is wider than the pathname length.
1778 */
1779 memset(&buf[len], ' ', clen - len);
1780 buf[clen] = '\0';
1781 printf(buf);
1782 }
1783 else if (clen == len)
1784 {
1785 printf(buf);
1786 }
1787 else if ((clen > 0) && (clen < len))
1788 {
1789 /* This prints the tail end of the pathname */
1790 buf[len-clen] = ' ';
1791 printf(&buf[len - clen]);
1792 }
1793
1794 usecs = (unsigned long)(((double)now - ti->stime) / divisor);
1795 secs = usecs / 1000000;
1796 usecs -= secs * 1000000;
1797
1798 if ((type >> 24) != FILEMGR_CLASS && !nopadding)
1799 printf(" ");
1800
1801 printf(" %2ld.%06ld", (long)secs, (long)usecs);
1802 if (ti->waited)
1803 printf(" W");
1804 else
1805 printf(" ");
1806
1807 if (map) {
1808 if (COLS > MAXCOLS || wideflag)
1809 printf(" %-20.20s", map->command);
1810 else
1811 printf(" %-12.12s", map->command);
1812 }
1813 printf("\n");
1814
1815 if (ti == &th_state[cur_max - 1])
1816 cur_max--;
1817 ti->thread = 0;
1818 fflush (0);
1819 }
1820
1821 int
1822 quit(s)
1823 char *s;
1824 {
1825 if (trace_enabled)
1826 set_enable(0);
1827
1828 /*
1829 This flag is turned off when calling
1830 quit() due to a set_remove() failure.
1831 */
1832 if (set_remove_flag)
1833 set_remove();
1834
1835 printf("fs_usage: ");
1836 if (s)
1837 printf("%s", s);
1838
1839 exit(1);
1840 }
1841
1842
1843 void getdivisor()
1844 {
1845
1846 unsigned int delta;
1847 unsigned int abs_to_ns_num;
1848 unsigned int abs_to_ns_denom;
1849 unsigned int proc_to_abs_num;
1850 unsigned int proc_to_abs_denom;
1851
1852 extern void MKGetTimeBaseInfo(unsigned int *, unsigned int *, unsigned int *, unsigned int *, unsigned int *);
1853
1854 MKGetTimeBaseInfo (&delta, &abs_to_ns_num, &abs_to_ns_denom,
1855 &proc_to_abs_num, &proc_to_abs_denom);
1856
1857 divisor = ((double)abs_to_ns_denom / (double)abs_to_ns_num) * 1000;
1858 }
1859
1860
1861 void read_command_map()
1862 {
1863 size_t size;
1864 int mib[6];
1865
1866 if (mapptr) {
1867 free(mapptr);
1868 mapptr = 0;
1869 }
1870 total_threads = bufinfo.nkdthreads;
1871 size = bufinfo.nkdthreads * sizeof(kd_threadmap);
1872
1873 if (size)
1874 {
1875 if (mapptr = (kd_threadmap *) malloc(size))
1876 bzero (mapptr, size);
1877 else
1878 {
1879 printf("Thread map is not initialized -- this is not fatal\n");
1880 return;
1881 }
1882 }
1883
1884 /* Now read the threadmap */
1885 mib[0] = CTL_KERN;
1886 mib[1] = KERN_KDEBUG;
1887 mib[2] = KERN_KDTHRMAP;
1888 mib[3] = 0;
1889 mib[4] = 0;
1890 mib[5] = 0; /* no flags */
1891 if (sysctl(mib, 3, mapptr, &size, NULL, 0) < 0)
1892 {
1893 /* This is not fatal -- just means I cant map command strings */
1894
1895 printf("Can't read the thread map -- this is not fatal\n");
1896 free(mapptr);
1897 mapptr = 0;
1898 return;
1899 }
1900 return;
1901 }
1902
1903
1904 void create_map_entry(int thread, char *command)
1905 {
1906 int i, n;
1907 kd_threadmap *map;
1908
1909 if (!mapptr)
1910 return;
1911
1912 for (i = 0, map = 0; !map && i < total_threads; i++)
1913 {
1914 if (mapptr[i].thread == thread )
1915 map = &mapptr[i]; /* Reuse this entry, the thread has been reassigned */
1916 }
1917
1918 if (!map) /* look for invalid entries that I can reuse*/
1919 {
1920 for (i = 0, map = 0; !map && i < total_threads; i++)
1921 {
1922 if (mapptr[i].valid == 0 )
1923 map = &mapptr[i]; /* Reuse this invalid entry */
1924 }
1925 }
1926
1927 if (!map)
1928 {
1929 /* If reach here, then this is a new thread and
1930 * there are no invalid entries to reuse
1931 * Double the size of the thread map table.
1932 */
1933
1934 n = total_threads * 2;
1935 mapptr = (kd_threadmap *) realloc(mapptr, n * sizeof(kd_threadmap));
1936 bzero(&mapptr[total_threads], total_threads*sizeof(kd_threadmap));
1937 map = &mapptr[total_threads];
1938 total_threads = n;
1939 }
1940
1941 map->valid = 1;
1942 map->thread = thread;
1943 /*
1944 The trace entry that returns the command name will hold
1945 at most, MAXCOMLEN chars, and in that case, is not
1946 guaranteed to be null terminated.
1947 */
1948 (void)strncpy (map->command, command, MAXCOMLEN);
1949 map->command[MAXCOMLEN] = '\0';
1950 }
1951
1952
1953 kd_threadmap *find_thread_map(int thread)
1954 {
1955 int i;
1956 kd_threadmap *map;
1957
1958 if (!mapptr)
1959 return((kd_threadmap *)0);
1960
1961 for (i = 0; i < total_threads; i++)
1962 {
1963 map = &mapptr[i];
1964 if (map->valid && (map->thread == thread))
1965 {
1966 return(map);
1967 }
1968 }
1969 return ((kd_threadmap *)0);
1970 }
1971
1972
1973 void
1974 kill_thread_map(int thread)
1975 {
1976 kd_threadmap *map;
1977
1978 if (map = find_thread_map(thread)) {
1979 map->valid = 0;
1980 map->thread = 0;
1981 map->command[0] = '\0';
1982 }
1983 }
1984
1985 void
1986 argtopid(str)
1987 char *str;
1988 {
1989 char *cp;
1990 int ret;
1991 int i;
1992
1993 ret = (int)strtol(str, &cp, 10);
1994 if (cp == str || *cp) {
1995 /* Assume this is a command string and find matching pids */
1996 if (!kp_buffer)
1997 find_proc_names();
1998
1999 for (i=0; i < kp_nentries && num_of_pids < (MAX_PIDS - 1); i++) {
2000 if(kp_buffer[i].kp_proc.p_stat == 0)
2001 continue;
2002 else {
2003 if(!strcmp(str, kp_buffer[i].kp_proc.p_comm))
2004 pids[num_of_pids++] = kp_buffer[i].kp_proc.p_pid;
2005 }
2006 }
2007 }
2008 else if (num_of_pids < (MAX_PIDS - 1))
2009 pids[num_of_pids++] = ret;
2010
2011 return;
2012 }
2013
2014