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