2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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
22 * @APPLE_LICENSE_HEADER_END@
26 cc -I. -DKERNEL_PRIVATE -O -o fs_usage fs_usage.c
29 #define Default_DELAY 1 /* default delay interval */
40 #include <sys/types.h>
41 #include <sys/param.h>
46 #include <sys/ioctl.h>
48 #ifndef KERNEL_PRIVATE
49 #define KERNEL_PRIVATE
50 #include <sys/kdebug.h>
53 #include <sys/kdebug.h>
54 #endif /*KERNEL_PRIVATE*/
56 #include <sys/sysctl.h>
58 #import <mach/clock_types.h>
67 typedef struct LibraryInfo
{
68 unsigned long address
;
72 LibraryInfo frameworkInfo
[MAXINDEX
];
73 int numFrameworks
= 0;
75 char seg_addr_table
[256]="/AppleInternal/Developer/seg_addr_table";
81 MAXCOLS controls when extra data kicks in.
82 MAX_WIDE_MODE_COLS controls -w mode to get even wider data in path.
83 If NUMPARMS changes to match the kernel, it will automatically
84 get reflected in the -w mode output.
87 #define PATHLENGTH (NUMPARMS*sizeof(long))
89 #define MAX_WIDE_MODE_COLS (PATHLENGTH + 80)
103 char pathname
[PATHLENGTH
+ 1]; /* add room for null terminator */
106 #define MAX_THREADS 512
107 struct th_info th_state
[MAX_THREADS
];
111 int need_new_map
= 1;
115 int select_pid_mode
= 0; /* Flag set indicates that output is restricted
116 to selected pids or commands */
118 int one_good_pid
= 0; /* Used to fail gracefully when bad pids given */
124 struct diskrec
*next
;
139 int completion_thread
;
140 char issuing_command
[MAXCOMLEN
];
142 double completed_time
;
145 struct diskrec
*disk_list
= NULL
;
146 struct diskio
*free_diskios
= NULL
;
147 struct diskio
*busy_diskios
= NULL
;
149 struct diskio
*insert_diskio();
150 struct diskio
*complete_diskio();
154 char *find_disk_name();
157 #define DBG_ZERO_FILL_FAULT 1
158 #define DBG_PAGEIN_FAULT 2
159 #define DBG_COW_FAULT 3
160 #define DBG_CACHE_HIT_FAULT 4
162 #define TRACE_DATA_NEWTHREAD 0x07000004
163 #define TRACE_STRING_NEWTHREAD 0x07010004
164 #define TRACE_STRING_EXEC 0x07010008
166 #define MACH_vmfault 0x01300000
167 #define MACH_pageout 0x01300004
168 #define MACH_sched 0x01400000
169 #define MACH_stkhandoff 0x01400008
170 #define VFS_LOOKUP 0x03010090
171 #define BSC_exit 0x040C0004
173 #define P_WrData 0x03020000
174 #define P_RdData 0x03020008
175 #define P_WrMeta 0x03020020
176 #define P_RdMeta 0x03020028
177 #define P_PgOut 0x03020040
178 #define P_PgIn 0x03020048
179 #define P_WrDataAsync 0x03020010
180 #define P_RdDataAsync 0x03020018
181 #define P_WrMetaAsync 0x03020030
182 #define P_RdMetaAsync 0x03020038
183 #define P_PgOutAsync 0x03020050
184 #define P_PgInAsync 0x03020058
186 #define P_WrDataDone 0x03020004
187 #define P_RdDataDone 0x0302000C
188 #define P_WrMetaDone 0x03020024
189 #define P_RdMetaDone 0x0302002C
190 #define P_PgOutDone 0x03020044
191 #define P_PgInDone 0x0302004C
192 #define P_WrDataAsyncDone 0x03020014
193 #define P_RdDataAsyncDone 0x0302001C
194 #define P_WrMetaAsyncDone 0x03020034
195 #define P_RdMetaAsyncDone 0x0302003C
196 #define P_PgOutAsyncDone 0x03020054
197 #define P_PgInAsyncDone 0x0302005C
200 #define MSC_map_fd 0x010c00ac
201 #define BSC_recvmsg 0x040C006C
202 #define BSC_sendmsg 0x040C0070
203 #define BSC_recvfrom 0x040C0074
204 #define BSC_sendto 0x040C0214
206 #define BSC_read 0x040C000C
207 #define BSC_write 0x040C0010
208 #define BSC_open 0x040C0014
209 #define BSC_close 0x040C0018
210 #define BSC_link 0x040C0024
211 #define BSC_unlink 0x040C0028
212 #define BSC_chdir 0x040c0030
213 #define BSC_fchdir 0x040c0034
214 #define BSC_mknod 0x040C0038
215 #define BSC_chmod 0x040C003C
216 #define BSC_chown 0x040C0040
217 #define BSC_access 0x040C0084
218 #define BSC_chflags 0x040C0088
219 #define BSC_fchflags 0x040C008C
220 #define BSC_sync 0x040C0090
221 #define BSC_revoke 0x040C00E0
222 #define BSC_symlink 0x040C00E4
223 #define BSC_readlink 0x040C00E8
224 #define BSC_chroot 0x040C00F4
225 #define BSC_fsync 0x040C017C
226 #define BSC_readv 0x040C01E0
227 #define BSC_writev 0x040C01E4
228 #define BSC_fchown 0x040C01EC
229 #define BSC_fchmod 0x040C01F0
230 #define BSC_rename 0x040C0200
231 #define BSC_mkfifo 0x040c0210
232 #define BSC_mkdir 0x040C0220
233 #define BSC_rmdir 0x040C0224
234 #define BSC_utimes 0x040C0228
235 #define BSC_futimes 0x040C022C
236 #define BSC_statfs 0x040C0274
237 #define BSC_fstatfs 0x040C0278
238 #define BSC_stat 0x040C02F0
239 #define BSC_fstat 0x040C02F4
240 #define BSC_lstat 0x040C02F8
241 #define BSC_pathconf 0x040C02FC
242 #define BSC_fpathconf 0x040C0300
243 #define BSC_getdirentries 0x040C0310
244 #define BSC_mmap 0x040c0314
245 #define BSC_lseek 0x040c031c
246 #define BSC_truncate 0x040C0320
247 #define BSC_ftruncate 0x040C0324
248 #define BSC_undelete 0x040C0334
249 #define BSC_statv 0x040C0364
250 #define BSC_lstatv 0x040C0368
251 #define BSC_fstatv 0x040C036C
252 #define BSC_mkcomplex 0x040C0360
253 #define BSC_getattrlist 0x040C0370
254 #define BSC_setattrlist 0x040C0374
255 #define BSC_getdirentriesattr 0x040C0378
256 #define BSC_exchangedata 0x040C037C
257 #define BSC_checkuseraccess 0x040C0380
258 #define BSC_searchfs 0x040C0384
259 #define BSC_delete 0x040C0388
260 #define BSC_copyfile 0x040C038C
261 #define BSC_fsctl 0x040C03C8
262 #define BSC_load_shared_file 0x040C04A0
264 // Carbon File Manager support
265 #define FILEMGR_PBGETCATALOGINFO 0x1e000020
266 #define FILEMGR_PBGETCATALOGINFOBULK 0x1e000024
267 #define FILEMGR_PBCREATEFILEUNICODE 0x1e000028
268 #define FILEMGR_PBCREATEDIRECTORYUNICODE 0x1e00002c
269 #define FILEMGR_PBCREATEFORK 0x1e000030
270 #define FILEMGR_PBDELETEFORK 0x1e000034
271 #define FILEMGR_PBITERATEFORK 0x1e000038
272 #define FILEMGR_PBOPENFORK 0x1e00003c
273 #define FILEMGR_PBREADFORK 0x1e000040
274 #define FILEMGR_PBWRITEFORK 0x1e000044
275 #define FILEMGR_PBALLOCATEFORK 0x1e000048
276 #define FILEMGR_PBDELETEOBJECT 0x1e00004c
277 #define FILEMGR_PBEXCHANGEOBJECT 0x1e000050
278 #define FILEMGR_PBGETFORKCBINFO 0x1e000054
279 #define FILEMGR_PBGETVOLUMEINFO 0x1e000058
280 #define FILEMGR_PBMAKEFSREF 0x1e00005c
281 #define FILEMGR_PBMAKEFSREFUNICODE 0x1e000060
282 #define FILEMGR_PBMOVEOBJECT 0x1e000064
283 #define FILEMGR_PBOPENITERATOR 0x1e000068
284 #define FILEMGR_PBRENAMEUNICODE 0x1e00006c
285 #define FILEMGR_PBSETCATALOGINFO 0x1e000070
286 #define FILEMGR_PBSETVOLUMEINFO 0x1e000074
287 #define FILEMGR_FSREFMAKEPATH 0x1e000078
288 #define FILEMGR_FSPATHMAKEREF 0x1e00007c
290 #define FILEMGR_PBGETCATINFO 0x1e010000
291 #define FILEMGR_PBGETCATINFOLITE 0x1e010004
292 #define FILEMGR_PBHGETFINFO 0x1e010008
293 #define FILEMGR_PBXGETVOLINFO 0x1e01000c
294 #define FILEMGR_PBHCREATE 0x1e010010
295 #define FILEMGR_PBHOPENDF 0x1e010014
296 #define FILEMGR_PBHOPENRF 0x1e010018
297 #define FILEMGR_PBHGETDIRACCESS 0x1e01001c
298 #define FILEMGR_PBHSETDIRACCESS 0x1e010020
299 #define FILEMGR_PBHMAPID 0x1e010024
300 #define FILEMGR_PBHMAPNAME 0x1e010028
301 #define FILEMGR_PBCLOSE 0x1e01002c
302 #define FILEMGR_PBFLUSHFILE 0x1e010030
303 #define FILEMGR_PBGETEOF 0x1e010034
304 #define FILEMGR_PBSETEOF 0x1e010038
305 #define FILEMGR_PBGETFPOS 0x1e01003c
306 #define FILEMGR_PBREAD 0x1e010040
307 #define FILEMGR_PBWRITE 0x1e010044
308 #define FILEMGR_PBGETFCBINFO 0x1e010048
309 #define FILEMGR_PBSETFINFO 0x1e01004c
310 #define FILEMGR_PBALLOCATE 0x1e010050
311 #define FILEMGR_PBALLOCCONTIG 0x1e010054
312 #define FILEMGR_PBSETFPOS 0x1e010058
313 #define FILEMGR_PBSETCATINFO 0x1e01005c
314 #define FILEMGR_PBGETVOLPARMS 0x1e010060
315 #define FILEMGR_PBSETVINFO 0x1e010064
316 #define FILEMGR_PBMAKEFSSPEC 0x1e010068
317 #define FILEMGR_PBHGETVINFO 0x1e01006c
318 #define FILEMGR_PBCREATEFILEIDREF 0x1e010070
319 #define FILEMGR_PBDELETEFILEIDREF 0x1e010074
320 #define FILEMGR_PBRESOLVEFILEIDREF 0x1e010078
321 #define FILEMGR_PBFLUSHVOL 0x1e01007c
322 #define FILEMGR_PBHRENAME 0x1e010080
323 #define FILEMGR_PBCATMOVE 0x1e010084
324 #define FILEMGR_PBEXCHANGEFILES 0x1e010088
325 #define FILEMGR_PBHDELETE 0x1e01008c
326 #define FILEMGR_PBDIRCREATE 0x1e010090
327 #define FILEMGR_PBCATSEARCH 0x1e010094
328 #define FILEMGR_PBHSETFLOCK 0x1e010098
329 #define FILEMGR_PBHRSTFLOCK 0x1e01009c
330 #define FILEMGR_PBLOCKRANGE 0x1e0100a0
331 #define FILEMGR_PBUNLOCKRANGE 0x1e0100a4
334 #define FILEMGR_CLASS 0x1e
340 int exclude_pids
= 0;
341 int exclude_default_pids
= 1;
343 struct kinfo_proc
*kp_buffer
= 0;
346 #define SAMPLE_SIZE 60000
348 #define DBG_ZERO_FILL_FAULT 1
349 #define DBG_PAGEIN_FAULT 2
350 #define DBG_COW_FAULT 3
351 #define DBG_CACHE_HIT_FAULT 4
353 #define DBG_FUNC_ALL (DBG_FUNC_START | DBG_FUNC_END)
354 #define DBG_FUNC_MASK 0xfffffffc
356 double divisor
= 0.0; /* Trace divisor converts to microseconds */
362 kbufinfo_t bufinfo
= {0, 0, 0, 0};
364 int total_threads
= 0;
365 kd_threadmap
*mapptr
= 0;
367 int trace_enabled
= 0;
368 int set_remove_flag
= 1;
380 void leave() /* exit under normal conditions -- INT handler */
385 void set_pidexclude();
390 if (exclude_pids
== 0) {
391 for (i
= 0; i
< num_of_pids
; i
++)
392 set_pidcheck(pids
[i
], 0);
395 for (i
= 0; i
< num_of_pids
; i
++)
396 set_pidexclude(pids
[i
], 0);
403 void get_screenwidth()
410 if (ioctl(1, TIOCGWINSZ
, &size
) != -1)
411 columns
= size
.ws_col
;
425 fprintf(stderr
, "Usage: %s [-e] [-w] [pid | cmd [pid | cmd]....]\n", myname
);
426 fprintf(stderr
, " -e exclude the specified list of pids from the sample\n");
427 fprintf(stderr
, " and exclude fs_usage by default\n");
428 fprintf(stderr
, " -w force wider, detailed, output\n");
429 fprintf(stderr
, " pid selects process(s) to sample\n");
430 fprintf(stderr
, " cmd selects process(s) matching command string to sample\n");
431 fprintf(stderr
, "\n%s will handle a maximum list of %d pids.\n\n", myname
, MAX_PIDS
);
432 fprintf(stderr
, "By default (no options) the following processes are excluded from the output:\n");
433 fprintf(stderr
, "fs_usage, Terminal, telnetd, sshd, rlogind, tcsh, csh, sh\n\n");
443 char *myname
= "fs_usage";
450 void set_pidexclude();
453 if ( geteuid() != 0 ) {
454 printf("'fs_usage' must be run as root...\n");
461 if ((myname
= rindex(argv
[0], '/')) == 0) {
469 while ((ch
= getopt(argc
, argv
, "ew")) != EOF
) {
473 exclude_default_pids
= 0;
477 if (columns
< MAX_WIDE_MODE_COLS
)
478 columns
= MAX_WIDE_MODE_COLS
;
488 /* If we process any list of pids/cmds, then turn off the defaults */
490 exclude_default_pids
= 0;
492 while (argc
> 0 && num_of_pids
< (MAX_PIDS
- 1)) {
499 /* Exclude a set of default pids */
500 if (exclude_default_pids
)
502 argtopid("Terminal");
515 if (num_of_pids
< (MAX_PIDS
- 1))
516 pids
[num_of_pids
++] = getpid();
522 for (i
= 0; i
< num_of_pids
; i
++)
525 printf("exclude pid %d\n", pids
[i
]);
527 printf("pid %d\n", pids
[i
]);
531 /* set up signal handlers */
532 signal(SIGINT
, leave
);
533 signal(SIGQUIT
, leave
);
534 signal(SIGHUP
, leave
);
535 signal(SIGTERM
, leave
);
536 signal(SIGWINCH
, sigwinch
);
538 if ((my_buffer
= malloc(SAMPLE_SIZE
* sizeof(kd_buf
))) == (char *)0)
539 quit("can't allocate memory for tracing info\n");
545 set_numbufs(SAMPLE_SIZE
);
548 if (exclude_pids
== 0) {
549 for (i
= 0; i
< num_of_pids
; i
++)
550 set_pidcheck(pids
[i
], 1);
552 for (i
= 0; i
< num_of_pids
; i
++)
553 set_pidexclude(pids
[i
], 1);
556 if (select_pid_mode
&& !one_good_pid
)
559 An attempt to restrict output to a given
560 pid or command has failed. Exit gracefully
583 struct kinfo_proc
*kp
;
588 mib
[2] = KERN_PROC_ALL
;
591 if (sysctl(mib
, 4, NULL
, &bufSize
, NULL
, 0) < 0)
592 quit("trace facility failure, KERN_PROC_ALL\n");
594 if((kp
= (struct kinfo_proc
*)malloc(bufSize
)) == (struct kinfo_proc
*)0)
595 quit("can't allocate memory for proc buffer\n");
597 if (sysctl(mib
, 4, kp
, &bufSize
, NULL
, 0) < 0)
598 quit("trace facility failure, KERN_PROC_ALL\n");
600 kp_nentries
= bufSize
/ sizeof(struct kinfo_proc
);
605 struct th_info
*find_thread(int thread
, int type
) {
608 for (ti
= th_state
; ti
< &th_state
[cur_max
]; ti
++) {
609 if (ti
->thread
== thread
) {
610 if (type
== ti
->type
)
612 if (ti
->in_filemgr
) {
621 return ((struct th_info
*)0);
625 mark_thread_waited(int thread
) {
628 for (ti
= th_state
; ti
< &th_state
[cur_max
]; ti
++) {
629 if (ti
->thread
== thread
) {
640 mib
[1] = KERN_KDEBUG
;
641 mib
[2] = KERN_KDENABLE
; /* protocol */
644 mib
[5] = 0; /* no flags */
645 if (sysctl(mib
, 4, NULL
, &needed
, NULL
, 0) < 0)
646 quit("trace facility failure, KERN_KDENABLE\n");
655 set_numbufs(int nbufs
)
658 mib
[1] = KERN_KDEBUG
;
659 mib
[2] = KERN_KDSETBUF
;
662 mib
[5] = 0; /* no flags */
663 if (sysctl(mib
, 4, NULL
, &needed
, NULL
, 0) < 0)
664 quit("trace facility failure, KERN_KDSETBUF\n");
667 mib
[1] = KERN_KDEBUG
;
668 mib
[2] = KERN_KDSETUP
;
671 mib
[5] = 0; /* no flags */
672 if (sysctl(mib
, 3, NULL
, &needed
, NULL
, 0) < 0)
673 quit("trace facility failure, KERN_KDSETUP\n");
677 set_pidcheck(int pid
, int on_off
)
681 kr
.type
= KDBG_TYPENONE
;
684 needed
= sizeof(kd_regtype
);
686 mib
[1] = KERN_KDEBUG
;
687 mib
[2] = KERN_KDPIDTR
;
692 if (sysctl(mib
, 3, &kr
, &needed
, NULL
, 0) < 0) {
694 printf("pid %d does not exist\n", pid
);
702 on_off == 0 turns off pid exclusion
703 on_off == 1 turns on pid exclusion
706 set_pidexclude(int pid
, int on_off
)
712 kr
.type
= KDBG_TYPENONE
;
715 needed
= sizeof(kd_regtype
);
717 mib
[1] = KERN_KDEBUG
;
718 mib
[2] = KERN_KDPIDEX
;
723 if (sysctl(mib
, 3, &kr
, &needed
, NULL
, 0) < 0) {
725 printf("pid %d does not exist\n", pid
);
730 get_bufinfo(kbufinfo_t
*val
)
732 needed
= sizeof (*val
);
734 mib
[1] = KERN_KDEBUG
;
735 mib
[2] = KERN_KDGETBUF
;
738 mib
[5] = 0; /* no flags */
740 if (sysctl(mib
, 3, val
, &needed
, 0, 0) < 0)
741 quit("trace facility failure, KERN_KDGETBUF\n");
751 mib
[1] = KERN_KDEBUG
;
752 mib
[2] = KERN_KDREMOVE
; /* protocol */
755 mib
[5] = 0; /* no flags */
756 if (sysctl(mib
, 3, NULL
, &needed
, NULL
, 0) < 0)
761 quit("the trace facility is currently in use...\n fs_usage, sc_usage, and latency use this feature.\n\n");
763 quit("trace facility failure, KERN_KDREMOVE\n");
771 kr
.type
= KDBG_RANGETYPE
;
774 needed
= sizeof(kd_regtype
);
776 mib
[1] = KERN_KDEBUG
;
777 mib
[2] = KERN_KDSETREG
;
780 mib
[5] = 0; /* no flags */
782 if (sysctl(mib
, 3, &kr
, &needed
, NULL
, 0) < 0)
783 quit("trace facility failure, KERN_KDSETREG\n");
786 mib
[1] = KERN_KDEBUG
;
787 mib
[2] = KERN_KDSETUP
;
790 mib
[5] = 0; /* no flags */
792 if (sysctl(mib
, 3, NULL
, &needed
, NULL
, 0) < 0)
793 quit("trace facility failure, KERN_KDSETUP\n");
802 void read_command_map();
803 void create_map_entry();
805 /* Get kernel buffer information */
806 get_bufinfo(&bufinfo
);
812 needed
= bufinfo
.nkdbufs
* sizeof(kd_buf
);
814 mib
[1] = KERN_KDEBUG
;
815 mib
[2] = KERN_KDREADTR
;
818 mib
[5] = 0; /* no flags */
820 if (sysctl(mib
, 3, my_buffer
, &needed
, NULL
, 0) < 0)
821 quit("trace facility failure, KERN_KDREADTR\n");
824 if (bufinfo
.flags
& KDBG_WRAPPED
) {
825 printf("buffer wrapped count = %d\n", count
);
827 for (i
= 0; i
< cur_max
; i
++) {
828 th_state
[i
].thread
= 0;
829 th_state
[i
].pathptr
= (long *)0;
830 th_state
[i
].pathname
[0] = 0;
838 kd
= (kd_buf
*)my_buffer
;
840 printf("READTR returned %d items\n", count
);
842 for (i
= 0; i
< count
; i
++) {
846 unsigned long long now
;
849 void enter_syscall();
851 void kill_thread_map();
853 thread
= kd
[i
].arg5
& KDBG_THREAD_MASK
;
854 debugid
= kd
[i
].debugid
;
855 type
= kd
[i
].debugid
& DBG_FUNC_MASK
;
857 now
= (((unsigned long long)kd
[i
].timestamp
.tv_sec
) << 32) |
858 (unsigned long long)((unsigned int)(kd
[i
].timestamp
.tv_nsec
));
875 insert_diskio(type
, kd
[i
].arg1
, kd
[i
].arg2
, kd
[i
].arg3
, kd
[i
].arg4
, thread
, (double)now
);
884 case P_RdMetaAsyncDone
:
885 case P_WrMetaAsyncDone
:
886 case P_RdDataAsyncDone
:
887 case P_WrDataAsyncDone
:
888 case P_PgInAsyncDone
:
889 case P_PgOutAsyncDone
:
890 if (dio
= complete_diskio(kd
[i
].arg1
, kd
[i
].arg4
, kd
[i
].arg3
, thread
, (double)now
)) {
897 case TRACE_DATA_NEWTHREAD
:
899 for (n
= 0, ti
= th_state
; ti
< &th_state
[MAX_THREADS
]; ti
++, n
++) {
903 if (ti
== &th_state
[MAX_THREADS
])
909 ti
->child_thread
= kd
[i
].arg1
;
912 case TRACE_STRING_NEWTHREAD
:
913 if ((ti
= find_thread(thread
, 0)) == (struct th_info
*)0)
915 if (ti
->child_thread
== 0)
917 create_map_entry(ti
->child_thread
, (char *)&kd
[i
].arg1
);
919 if (ti
== &th_state
[cur_max
- 1])
921 ti
->child_thread
= 0;
925 case TRACE_STRING_EXEC
:
926 create_map_entry(thread
, (char *)&kd
[i
].arg1
);
930 kill_thread_map(thread
);
934 case MACH_stkhandoff
:
935 mark_thread_waited(thread
);
939 if ((ti
= find_thread(thread
, 0)) == (struct th_info
*)0)
943 sargptr
= (long *)&ti
->pathname
[0];
944 memset(&ti
->pathname
[0], 0, (PATHLENGTH
+ 1));
945 *sargptr
++ = kd
[i
].arg2
;
946 *sargptr
++ = kd
[i
].arg3
;
947 *sargptr
++ = kd
[i
].arg4
;
948 ti
->pathptr
= sargptr
;
950 sargptr
= ti
->pathptr
;
953 We don't want to overrun our pathname buffer if the
954 kernel sends us more VFS_LOOKUP entries than we can
958 if ((long *)sargptr
>= (long *)&ti
->pathname
[PATHLENGTH
])
962 We need to detect consecutive vfslookup entries.
963 So, if we get here and find a START entry,
964 fake the pathptr so we can bypass all further
968 if (debugid
& DBG_FUNC_START
)
970 (long *)ti
->pathptr
= (long *)&ti
->pathname
[PATHLENGTH
];
974 *sargptr
++ = kd
[i
].arg1
;
975 *sargptr
++ = kd
[i
].arg2
;
976 *sargptr
++ = kd
[i
].arg3
;
977 *sargptr
++ = kd
[i
].arg4
;
978 ti
->pathptr
= sargptr
;
983 if (debugid
& DBG_FUNC_START
) {
987 case FILEMGR_PBGETCATALOGINFO
:
988 p
= "GetCatalogInfo";
990 case FILEMGR_PBGETCATALOGINFOBULK
:
991 p
= "GetCatalogInfoBulk";
993 case FILEMGR_PBCREATEFILEUNICODE
:
994 p
= "CreateFileUnicode";
996 case FILEMGR_PBCREATEDIRECTORYUNICODE
:
997 p
= "CreateDirectoryUnicode";
999 case FILEMGR_PBCREATEFORK
:
1002 case FILEMGR_PBDELETEFORK
:
1005 case FILEMGR_PBITERATEFORK
:
1006 p
= "PBIterateFork";
1008 case FILEMGR_PBOPENFORK
:
1011 case FILEMGR_PBREADFORK
:
1014 case FILEMGR_PBWRITEFORK
:
1017 case FILEMGR_PBALLOCATEFORK
:
1018 p
= "PBAllocateFork";
1020 case FILEMGR_PBDELETEOBJECT
:
1021 p
= "PBDeleteObject";
1023 case FILEMGR_PBEXCHANGEOBJECT
:
1024 p
= "PBExchangeObject";
1026 case FILEMGR_PBGETFORKCBINFO
:
1027 p
= "PBGetForkCBInfo";
1029 case FILEMGR_PBGETVOLUMEINFO
:
1030 p
= "PBGetVolumeInfo";
1032 case FILEMGR_PBMAKEFSREF
:
1035 case FILEMGR_PBMAKEFSREFUNICODE
:
1036 p
= "PBMakeFSRefUnicode";
1038 case FILEMGR_PBMOVEOBJECT
:
1041 case FILEMGR_PBOPENITERATOR
:
1042 p
= "PBOpenIterator";
1044 case FILEMGR_PBRENAMEUNICODE
:
1045 p
= "PBRenameUnicode";
1047 case FILEMGR_PBSETCATALOGINFO
:
1048 p
= "SetCatalogInfo";
1050 case FILEMGR_PBSETVOLUMEINFO
:
1051 p
= "SetVolumeInfo";
1053 case FILEMGR_FSREFMAKEPATH
:
1054 p
= "FSRefMakePath";
1056 case FILEMGR_FSPATHMAKEREF
:
1057 p
= "FSPathMakeRef";
1060 case FILEMGR_PBGETCATINFO
:
1063 case FILEMGR_PBGETCATINFOLITE
:
1064 p
= "GetCatInfoLite";
1066 case FILEMGR_PBHGETFINFO
:
1069 case FILEMGR_PBXGETVOLINFO
:
1070 p
= "PBXGetVolInfo";
1072 case FILEMGR_PBHCREATE
:
1075 case FILEMGR_PBHOPENDF
:
1078 case FILEMGR_PBHOPENRF
:
1081 case FILEMGR_PBHGETDIRACCESS
:
1082 p
= "PBHGetDirAccess";
1084 case FILEMGR_PBHSETDIRACCESS
:
1085 p
= "PBHSetDirAccess";
1087 case FILEMGR_PBHMAPID
:
1090 case FILEMGR_PBHMAPNAME
:
1093 case FILEMGR_PBCLOSE
:
1096 case FILEMGR_PBFLUSHFILE
:
1099 case FILEMGR_PBGETEOF
:
1102 case FILEMGR_PBSETEOF
:
1105 case FILEMGR_PBGETFPOS
:
1108 case FILEMGR_PBREAD
:
1111 case FILEMGR_PBWRITE
:
1114 case FILEMGR_PBGETFCBINFO
:
1117 case FILEMGR_PBSETFINFO
:
1120 case FILEMGR_PBALLOCATE
:
1123 case FILEMGR_PBALLOCCONTIG
:
1124 p
= "PBAllocContig";
1126 case FILEMGR_PBSETFPOS
:
1129 case FILEMGR_PBSETCATINFO
:
1132 case FILEMGR_PBGETVOLPARMS
:
1133 p
= "PBGetVolParms";
1135 case FILEMGR_PBSETVINFO
:
1138 case FILEMGR_PBMAKEFSSPEC
:
1141 case FILEMGR_PBHGETVINFO
:
1144 case FILEMGR_PBCREATEFILEIDREF
:
1145 p
= "PBCreateFileIDRef";
1147 case FILEMGR_PBDELETEFILEIDREF
:
1148 p
= "PBDeleteFileIDRef";
1150 case FILEMGR_PBRESOLVEFILEIDREF
:
1151 p
= "PBResolveFileIDRef";
1153 case FILEMGR_PBFLUSHVOL
:
1156 case FILEMGR_PBHRENAME
:
1159 case FILEMGR_PBCATMOVE
:
1162 case FILEMGR_PBEXCHANGEFILES
:
1163 p
= "PBExchangeFiles";
1165 case FILEMGR_PBHDELETE
:
1168 case FILEMGR_PBDIRCREATE
:
1171 case FILEMGR_PBCATSEARCH
:
1174 case FILEMGR_PBHSETFLOCK
:
1177 case FILEMGR_PBHRSTFLOCK
:
1180 case FILEMGR_PBLOCKRANGE
:
1183 case FILEMGR_PBUNLOCKRANGE
:
1184 p
= "PBUnlockRange";
1190 enter_syscall(thread
, type
, &kd
[i
], p
, (double)now
);
1197 exit_syscall("PAGE_OUT_D", thread
, type
, 0, kd
[i
].arg1
, 0, 4, (double)now
);
1199 exit_syscall("PAGE_OUT_V", thread
, type
, 0, kd
[i
].arg1
, 0, 4, (double)now
);
1203 if (kd
[i
].arg2
== DBG_PAGEIN_FAULT
)
1204 exit_syscall("PAGE_IN", thread
, type
, kd
[i
].arg4
, kd
[i
].arg1
, 0, 6, (double)now
);
1205 else if (kd
[i
].arg2
== DBG_CACHE_HIT_FAULT
)
1206 exit_syscall("CACHE_HIT", thread
, type
, 0, kd
[i
].arg1
, 0, 2, (double)now
);
1208 if (ti
= find_thread(thread
, type
)) {
1209 if (ti
== &th_state
[cur_max
- 1])
1217 exit_syscall("map_fd", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 0, (double)now
);
1221 exit_syscall("mmap", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1225 exit_syscall("recvmsg", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 1, (double)now
);
1229 exit_syscall("sendmsg", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 1, (double)now
);
1233 exit_syscall("recvfrom", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 1, (double)now
);
1237 exit_syscall("sendto", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 1, (double)now
);
1241 exit_syscall("stat", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1244 case BSC_load_shared_file
:
1245 exit_syscall("load_sf", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1249 exit_syscall("open", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 2, 0, (double)now
);
1253 exit_syscall("close", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 0, (double)now
);
1257 exit_syscall("read", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 1, (double)now
);
1261 exit_syscall("write", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 1, (double)now
);
1265 exit_syscall("fstat", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 0, (double)now
);
1269 exit_syscall("lstat", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1273 exit_syscall("link", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1277 exit_syscall("unlink", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1281 exit_syscall("mknod", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1285 exit_syscall("chmod", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1289 exit_syscall("chown", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1293 exit_syscall("access", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1297 exit_syscall("chdir", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1301 exit_syscall("chroot", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1305 exit_syscall("utimes", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1309 exit_syscall("delete", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1313 exit_syscall("undelete", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1317 exit_syscall("revoke", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1321 exit_syscall("fsctl", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1325 exit_syscall("chflags", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1329 exit_syscall("fchflags", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 0, (double)now
);
1333 exit_syscall("fchdir", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 0, (double)now
);
1337 exit_syscall("futimes", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 0, (double)now
);
1341 exit_syscall("sync", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1345 exit_syscall("symlink", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1349 exit_syscall("readlink", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1353 exit_syscall("fsync", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 0, (double)now
);
1357 exit_syscall("readv", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 1, (double)now
);
1361 exit_syscall("writev", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 1, (double)now
);
1365 exit_syscall("fchown", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 0, (double)now
);
1369 exit_syscall("fchmod", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 0, (double)now
);
1373 exit_syscall("mkdir", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1377 exit_syscall("mkfifo", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1381 exit_syscall("rmdir", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1385 exit_syscall("statfs", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1389 exit_syscall("fstatfs", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 0, (double)now
);
1393 exit_syscall("pathconf", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1397 exit_syscall("fpathconf", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 0, (double)now
);
1400 case BSC_getdirentries
:
1401 exit_syscall("getdirentries", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 1, (double)now
);
1405 exit_syscall("lseek", thread
, type
, kd
[i
].arg1
, kd
[i
].arg3
, 1, 5, (double)now
);
1409 exit_syscall("truncate", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1413 exit_syscall("ftruncate", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 3, (double)now
);
1417 exit_syscall("statv", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1421 exit_syscall("lstatv", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1425 exit_syscall("fstatv", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 0, (double)now
);
1429 exit_syscall("mkcomplex", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1432 case BSC_getattrlist
:
1433 exit_syscall("getattrlist", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1436 case BSC_setattrlist
:
1437 exit_syscall("setattrlist", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1440 case BSC_getdirentriesattr
:
1441 exit_syscall("getdirentriesattr", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 1, (double)now
);
1445 case BSC_exchangedata
:
1446 exit_syscall("exchangedata", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1450 exit_syscall("rename", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1454 exit_syscall("copyfile", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1458 case BSC_checkuseraccess
:
1459 exit_syscall("checkuseraccess", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1463 exit_syscall("searchfs", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1466 case FILEMGR_PBGETCATALOGINFO
:
1467 exit_syscall("GetCatalogInfo", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1469 case FILEMGR_PBGETCATALOGINFOBULK
:
1470 exit_syscall("GetCatalogInfoBulk", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1472 case FILEMGR_PBCREATEFILEUNICODE
:
1473 exit_syscall("CreateFileUnicode", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1475 case FILEMGR_PBCREATEDIRECTORYUNICODE
:
1476 exit_syscall("CreateDirectoryUnicode", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1478 case FILEMGR_PBCREATEFORK
:
1479 exit_syscall("PBCreateFork", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1481 case FILEMGR_PBDELETEFORK
:
1482 exit_syscall("PBDeleteFork", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1484 case FILEMGR_PBITERATEFORK
:
1485 exit_syscall("PBIterateFork", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1487 case FILEMGR_PBOPENFORK
:
1488 exit_syscall("PBOpenFork", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1490 case FILEMGR_PBREADFORK
:
1491 exit_syscall("PBReadFork", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1493 case FILEMGR_PBWRITEFORK
:
1494 exit_syscall("PBWriteFork", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1496 case FILEMGR_PBALLOCATEFORK
:
1497 exit_syscall("PBAllocateFork", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1499 case FILEMGR_PBDELETEOBJECT
:
1500 exit_syscall("PBDeleteObject", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1502 case FILEMGR_PBEXCHANGEOBJECT
:
1503 exit_syscall("PBExchangeObject", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1505 case FILEMGR_PBGETFORKCBINFO
:
1506 exit_syscall("PBGetForkCBInfo", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1508 case FILEMGR_PBGETVOLUMEINFO
:
1509 exit_syscall("PBGetVolumeInfo", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1511 case FILEMGR_PBMAKEFSREF
:
1512 exit_syscall("PBMakeFSRef", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1514 case FILEMGR_PBMAKEFSREFUNICODE
:
1515 exit_syscall("PBMakeFSRefUnicode", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1517 case FILEMGR_PBMOVEOBJECT
:
1518 exit_syscall("PBMoveObject", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1520 case FILEMGR_PBOPENITERATOR
:
1521 exit_syscall("PBOpenIterator", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1523 case FILEMGR_PBRENAMEUNICODE
:
1524 exit_syscall("PBRenameUnicode", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1526 case FILEMGR_PBSETCATALOGINFO
:
1527 exit_syscall("PBSetCatalogInfo", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1529 case FILEMGR_PBSETVOLUMEINFO
:
1530 exit_syscall("PBSetVolumeInfo", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1532 case FILEMGR_FSREFMAKEPATH
:
1533 exit_syscall("FSRefMakePath", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1535 case FILEMGR_FSPATHMAKEREF
:
1536 exit_syscall("FSPathMakeRef", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1538 case FILEMGR_PBGETCATINFO
:
1539 exit_syscall("GetCatInfo", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1541 case FILEMGR_PBGETCATINFOLITE
:
1542 exit_syscall("GetCatInfoLite", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1544 case FILEMGR_PBHGETFINFO
:
1545 exit_syscall("PBHGetFInfo", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1547 case FILEMGR_PBXGETVOLINFO
:
1548 exit_syscall("PBXGetVolInfo", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1550 case FILEMGR_PBHCREATE
:
1551 exit_syscall("PBHCreate", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1553 case FILEMGR_PBHOPENDF
:
1554 exit_syscall("PBHOpenDF", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1556 case FILEMGR_PBHOPENRF
:
1557 exit_syscall("PBHOpenRF", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1559 case FILEMGR_PBHGETDIRACCESS
:
1560 exit_syscall("PBHGetDirAccess", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1562 case FILEMGR_PBHSETDIRACCESS
:
1563 exit_syscall("PBHSetDirAccess", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1565 case FILEMGR_PBHMAPID
:
1566 exit_syscall("PBHMapID", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1568 case FILEMGR_PBHMAPNAME
:
1569 exit_syscall("PBHMapName", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1571 case FILEMGR_PBCLOSE
:
1572 exit_syscall("PBClose", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1574 case FILEMGR_PBFLUSHFILE
:
1575 exit_syscall("PBFlushFile", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1577 case FILEMGR_PBGETEOF
:
1578 exit_syscall("PBGetEOF", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1580 case FILEMGR_PBSETEOF
:
1581 exit_syscall("PBSetEOF", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1583 case FILEMGR_PBGETFPOS
:
1584 exit_syscall("PBGetFPos", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1586 case FILEMGR_PBREAD
:
1587 exit_syscall("PBRead", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1589 case FILEMGR_PBWRITE
:
1590 exit_syscall("PBWrite", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1592 case FILEMGR_PBGETFCBINFO
:
1593 exit_syscall("PBGetFCBInfo", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1595 case FILEMGR_PBSETFINFO
:
1596 exit_syscall("PBSetFInfo", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1598 case FILEMGR_PBALLOCATE
:
1599 exit_syscall("PBAllocate", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1601 case FILEMGR_PBALLOCCONTIG
:
1602 exit_syscall("PBAllocContig", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1604 case FILEMGR_PBSETFPOS
:
1605 exit_syscall("PBSetFPos", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1607 case FILEMGR_PBSETCATINFO
:
1608 exit_syscall("PBSetCatInfo", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1610 case FILEMGR_PBGETVOLPARMS
:
1611 exit_syscall("PBGetVolParms", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1613 case FILEMGR_PBSETVINFO
:
1614 exit_syscall("PBSetVInfo", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1616 case FILEMGR_PBMAKEFSSPEC
:
1617 exit_syscall("PBMakeFSSpec", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1619 case FILEMGR_PBHGETVINFO
:
1620 exit_syscall("PBHGetVInfo", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1622 case FILEMGR_PBCREATEFILEIDREF
:
1623 exit_syscall("PBCreateFileIDRef", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1625 case FILEMGR_PBDELETEFILEIDREF
:
1626 exit_syscall("PBDeleteFileIDRef", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1628 case FILEMGR_PBRESOLVEFILEIDREF
:
1629 exit_syscall("PBResolveFileIDRef", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1631 case FILEMGR_PBFLUSHVOL
:
1632 exit_syscall("PBFlushVol", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1634 case FILEMGR_PBHRENAME
:
1635 exit_syscall("PBHRename", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1637 case FILEMGR_PBCATMOVE
:
1638 exit_syscall("PBCatMove", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1640 case FILEMGR_PBEXCHANGEFILES
:
1641 exit_syscall("PBExchangeFiles", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1643 case FILEMGR_PBHDELETE
:
1644 exit_syscall("PBHDelete", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1646 case FILEMGR_PBDIRCREATE
:
1647 exit_syscall("PBDirCreate", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1649 case FILEMGR_PBCATSEARCH
:
1650 exit_syscall("PBCatSearch", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1652 case FILEMGR_PBHSETFLOCK
:
1653 exit_syscall("PBHSetFLock", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1655 case FILEMGR_PBHRSTFLOCK
:
1656 exit_syscall("PBHRstFLock", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1658 case FILEMGR_PBLOCKRANGE
:
1659 exit_syscall("PBLockRange", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1661 case FILEMGR_PBUNLOCKRANGE
:
1662 exit_syscall("PBUnlockRange", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1672 enter_syscall(int thread
, int type
, kd_buf
*kd
, char *name
, double now
)
1681 kd_threadmap
*find_thread_map();
1699 case BSC_load_shared_file
:
1740 case BSC_getdirentries
:
1748 case BSC_getattrlist
:
1749 case BSC_setattrlist
:
1750 case BSC_getdirentriesattr
:
1751 case BSC_exchangedata
:
1752 case BSC_checkuseraccess
:
1754 case FILEMGR_PBGETCATALOGINFO
:
1755 case FILEMGR_PBGETCATALOGINFOBULK
:
1756 case FILEMGR_PBCREATEFILEUNICODE
:
1757 case FILEMGR_PBCREATEDIRECTORYUNICODE
:
1758 case FILEMGR_PBCREATEFORK
:
1759 case FILEMGR_PBDELETEFORK
:
1760 case FILEMGR_PBITERATEFORK
:
1761 case FILEMGR_PBOPENFORK
:
1762 case FILEMGR_PBREADFORK
:
1763 case FILEMGR_PBWRITEFORK
:
1764 case FILEMGR_PBALLOCATEFORK
:
1765 case FILEMGR_PBDELETEOBJECT
:
1766 case FILEMGR_PBEXCHANGEOBJECT
:
1767 case FILEMGR_PBGETFORKCBINFO
:
1768 case FILEMGR_PBGETVOLUMEINFO
:
1769 case FILEMGR_PBMAKEFSREF
:
1770 case FILEMGR_PBMAKEFSREFUNICODE
:
1771 case FILEMGR_PBMOVEOBJECT
:
1772 case FILEMGR_PBOPENITERATOR
:
1773 case FILEMGR_PBRENAMEUNICODE
:
1774 case FILEMGR_PBSETCATALOGINFO
:
1775 case FILEMGR_PBSETVOLUMEINFO
:
1776 case FILEMGR_FSREFMAKEPATH
:
1777 case FILEMGR_FSPATHMAKEREF
:
1779 case FILEMGR_PBGETCATINFO
:
1780 case FILEMGR_PBGETCATINFOLITE
:
1781 case FILEMGR_PBHGETFINFO
:
1782 case FILEMGR_PBXGETVOLINFO
:
1783 case FILEMGR_PBHCREATE
:
1784 case FILEMGR_PBHOPENDF
:
1785 case FILEMGR_PBHOPENRF
:
1786 case FILEMGR_PBHGETDIRACCESS
:
1787 case FILEMGR_PBHSETDIRACCESS
:
1788 case FILEMGR_PBHMAPID
:
1789 case FILEMGR_PBHMAPNAME
:
1790 case FILEMGR_PBCLOSE
:
1791 case FILEMGR_PBFLUSHFILE
:
1792 case FILEMGR_PBGETEOF
:
1793 case FILEMGR_PBSETEOF
:
1794 case FILEMGR_PBGETFPOS
:
1795 case FILEMGR_PBREAD
:
1796 case FILEMGR_PBWRITE
:
1797 case FILEMGR_PBGETFCBINFO
:
1798 case FILEMGR_PBSETFINFO
:
1799 case FILEMGR_PBALLOCATE
:
1800 case FILEMGR_PBALLOCCONTIG
:
1801 case FILEMGR_PBSETFPOS
:
1802 case FILEMGR_PBSETCATINFO
:
1803 case FILEMGR_PBGETVOLPARMS
:
1804 case FILEMGR_PBSETVINFO
:
1805 case FILEMGR_PBMAKEFSSPEC
:
1806 case FILEMGR_PBHGETVINFO
:
1807 case FILEMGR_PBCREATEFILEIDREF
:
1808 case FILEMGR_PBDELETEFILEIDREF
:
1809 case FILEMGR_PBRESOLVEFILEIDREF
:
1810 case FILEMGR_PBFLUSHVOL
:
1811 case FILEMGR_PBHRENAME
:
1812 case FILEMGR_PBCATMOVE
:
1813 case FILEMGR_PBEXCHANGEFILES
:
1814 case FILEMGR_PBHDELETE
:
1815 case FILEMGR_PBDIRCREATE
:
1816 case FILEMGR_PBCATSEARCH
:
1817 case FILEMGR_PBHSETFLOCK
:
1818 case FILEMGR_PBHRSTFLOCK
:
1819 case FILEMGR_PBLOCKRANGE
:
1820 case FILEMGR_PBUNLOCKRANGE
:
1823 for (i
= 0, ti
= th_state
; ti
< &th_state
[MAX_THREADS
]; ti
++, i
++) {
1824 if (ti
->thread
== 0)
1827 if (ti
== &th_state
[MAX_THREADS
])
1833 if ((type
>> 24) == FILEMGR_CLASS
) {
1836 l_usecs
= (long long)(now
/ divisor
);
1837 secs
= l_usecs
/ 1000000;
1839 if (bias_secs
== 0) {
1840 curr_time
= time((long *)0);
1841 bias_secs
= curr_time
- secs
;
1843 curr_time
= bias_secs
+ secs
;
1844 sprintf(buf
, "%-8.8s", &(ctime(&curr_time
)[11]));
1845 tsclen
= strlen(buf
);
1847 if (columns
> MAXCOLS
|| wideflag
) {
1848 usecs
= l_usecs
- (long long)((long long)secs
* 1000000);
1849 sprintf(&buf
[tsclen
], ".%03ld", (long)usecs
/ 1000);
1850 tsclen
= strlen(buf
);
1853 /* Print timestamp column */
1856 map
= find_thread_map(thread
);
1858 sprintf(buf
, " %-25.25s ", name
);
1859 nmclen
= strlen(buf
);
1862 sprintf(buf
, "(%d, 0x%x, 0x%x, 0x%x)", (short)kd
->arg1
, kd
->arg2
, kd
->arg3
, kd
->arg4
);
1863 argsclen
= strlen(buf
);
1866 Calculate white space out to command
1868 if (columns
> MAXCOLS
|| wideflag
)
1870 clen
= columns
- (tsclen
+ nmclen
+ argsclen
+ 20);
1873 clen
= columns
- (tsclen
+ nmclen
+ argsclen
+ 12);
1877 printf(buf
); /* print the kdargs */
1878 memset(buf
, ' ', clen
);
1882 else if ((argsclen
+ clen
) > 0)
1884 /* no room so wipe out the kdargs */
1885 memset(buf
, ' ', (argsclen
+ clen
));
1886 buf
[argsclen
+ clen
] = '\0';
1890 if (columns
> MAXCOLS
|| wideflag
)
1891 printf("%-20.20s\n", map
->command
);
1893 printf("%-12.12s\n", map
->command
);
1895 printf(" %-24.24s (%5d, %#x, 0x%x, 0x%x)\n", name
, (short)kd
->arg1
, kd
->arg2
, kd
->arg3
, kd
->arg4
);
1899 ti
->thread
= thread
;
1903 ti
->arg1
= kd
->arg1
;
1904 ti
->arg2
= kd
->arg2
;
1905 ti
->arg3
= kd
->arg3
;
1906 ti
->arg4
= kd
->arg4
;
1907 ti
->pathptr
= (long *)0;
1908 ti
->pathname
[0] = 0;
1919 exit_syscall(char *sc_name
, int thread
, int type
, int error
, int retval
,
1920 int has_fd
, int has_ret
, double now
)
1924 if ((ti
= find_thread(thread
, type
)) == (struct th_info
*)0)
1927 format_print(ti
, sc_name
, thread
, type
, error
, retval
, has_fd
, has_ret
, now
, ti
->stime
, ti
->waited
, ti
->pathname
, NULL
);
1929 if (ti
== &th_state
[cur_max
- 1])
1937 format_print(struct th_info
*ti
, char *sc_name
, int thread
, int type
, int error
, int retval
,
1938 int has_fd
, int has_ret
, double now
, double stime
, int waited
, char *pathname
, struct diskio
*dio
)
1947 kd_threadmap
*find_thread_map();
1950 char *framework_name
;
1956 command_name
= dio
->issuing_command
;
1958 if (map
= find_thread_map(thread
))
1959 command_name
= map
->command
;
1961 l_usecs
= (long long)(now
/ divisor
);
1962 secs
= l_usecs
/ 1000000;
1964 if (bias_secs
== 0) {
1965 curr_time
= time((long *)0);
1966 bias_secs
= curr_time
- secs
;
1968 curr_time
= bias_secs
+ secs
;
1969 sprintf(buf
, "%-8.8s", &(ctime(&curr_time
)[11]));
1972 if (columns
> MAXCOLS
|| wideflag
) {
1974 usecs
= l_usecs
- (long long)((long long)secs
* 1000000);
1975 sprintf(&buf
[clen
], ".%03ld", (long)usecs
/ 1000);
1978 if ((type
>> 24) != FILEMGR_CLASS
) {
1979 if (find_thread(thread
, -1)) {
1980 sprintf(&buf
[clen
], " ");
1988 if (((type
>> 24) == FILEMGR_CLASS
) && (columns
> MAXCOLS
|| wideflag
))
1989 sprintf(&buf
[clen
], " %-18.18s", sc_name
);
1991 sprintf(&buf
[clen
], " %-15.15s", sc_name
);
1995 framework_name
= (char *)0;
1997 if (columns
> MAXCOLS
|| wideflag
) {
1999 sprintf(&buf
[clen
], " D=0x%8.8x", dio
->blkno
);
2004 sprintf(&buf
[clen
], " [%3d] ", dio
->io_errno
);
2006 sprintf(&buf
[clen
], " B=0x%-6x /dev/%s", dio
->iosize
, find_disk_name(dio
->dev
));
2009 if (has_fd
== 2 && error
== 0)
2010 sprintf(&buf
[clen
], " F=%-3d", retval
);
2011 else if (has_fd
== 1)
2012 sprintf(&buf
[clen
], " F=%-3d", ti
->arg1
);
2013 else if (has_ret
!= 2 && has_ret
!= 6)
2014 sprintf(&buf
[clen
], " ");
2018 if (has_ret
== 2 || has_ret
== 6)
2019 framework_name
= lookup_name(retval
);
2021 if (error
&& has_ret
!= 6)
2022 sprintf(&buf
[clen
], "[%3d] ", error
);
2023 else if (has_ret
== 3)
2024 sprintf(&buf
[clen
], "O=0x%8.8x", ti
->arg3
);
2025 else if (has_ret
== 5)
2026 sprintf(&buf
[clen
], "O=0x%8.8x", retval
);
2027 else if (has_ret
== 2)
2028 sprintf(&buf
[clen
], " A=0x%8.8x ", retval
);
2029 else if (has_ret
== 6)
2030 sprintf(&buf
[clen
], " A=0x%8.8x B=0x%-8x", retval
, error
);
2031 else if (has_ret
== 1)
2032 sprintf(&buf
[clen
], " B=0x%-6x", retval
);
2033 else if (has_ret
== 4)
2034 sprintf(&buf
[clen
], "B=0x%-8x", retval
);
2036 sprintf(&buf
[clen
], " ");
2043 Calculate space available to print pathname
2045 if (columns
> MAXCOLS
|| wideflag
)
2046 clen
= columns
- (clen
+ 13 + 20);
2048 clen
= columns
- (clen
+ 13 + 12);
2050 if ((type
>> 24) != FILEMGR_CLASS
&& !nopadding
)
2054 sprintf(&buf
[0], " %s ", framework_name
);
2056 sprintf(&buf
[0], " %s ", pathname
);
2062 Add null padding if column length
2063 is wider than the pathname length.
2065 memset(&buf
[len
], ' ', clen
- len
);
2069 else if (clen
== len
)
2073 else if ((clen
> 0) && (clen
< len
))
2075 /* This prints the tail end of the pathname */
2076 buf
[len
-clen
] = ' ';
2077 printf(&buf
[len
- clen
]);
2080 usecs
= (unsigned long)((now
- stime
) / divisor
);
2081 secs
= usecs
/ 1000000;
2082 usecs
-= secs
* 1000000;
2084 if ((type
>> 24) != FILEMGR_CLASS
&& !nopadding
)
2087 printf(" %2ld.%06ld", (unsigned long)secs
, (unsigned long)usecs
);
2094 if (columns
> MAXCOLS
|| wideflag
)
2095 printf(" %-20.20s", command_name
);
2097 printf(" %-12.12s", command_name
);
2111 This flag is turned off when calling
2112 quit() due to a set_remove() failure.
2114 if (set_remove_flag
)
2117 printf("fs_usage: ");
2129 unsigned int abs_to_ns_num
;
2130 unsigned int abs_to_ns_denom
;
2131 unsigned int proc_to_abs_num
;
2132 unsigned int proc_to_abs_denom
;
2134 extern void MKGetTimeBaseInfo(unsigned int *, unsigned int *, unsigned int *, unsigned int *, unsigned int *);
2136 MKGetTimeBaseInfo (&delta
, &abs_to_ns_num
, &abs_to_ns_denom
,
2137 &proc_to_abs_num
, &proc_to_abs_denom
);
2139 divisor
= ((double)abs_to_ns_denom
/ (double)abs_to_ns_num
) * 1000;
2143 void read_command_map()
2152 total_threads
= bufinfo
.nkdthreads
;
2153 size
= bufinfo
.nkdthreads
* sizeof(kd_threadmap
);
2157 if (mapptr
= (kd_threadmap
*) malloc(size
))
2158 bzero (mapptr
, size
);
2163 /* Now read the threadmap */
2165 mib
[1] = KERN_KDEBUG
;
2166 mib
[2] = KERN_KDTHRMAP
;
2169 mib
[5] = 0; /* no flags */
2170 if (sysctl(mib
, 3, mapptr
, &size
, NULL
, 0) < 0)
2172 /* This is not fatal -- just means I cant map command strings */
2179 void create_map_entry(int thread
, char *command
)
2187 for (i
= 0, map
= 0; !map
&& i
< total_threads
; i
++)
2189 if (mapptr
[i
].thread
== thread
)
2190 map
= &mapptr
[i
]; /* Reuse this entry, the thread has been reassigned */
2193 if (!map
) /* look for invalid entries that I can reuse*/
2195 for (i
= 0, map
= 0; !map
&& i
< total_threads
; i
++)
2197 if (mapptr
[i
].valid
== 0 )
2198 map
= &mapptr
[i
]; /* Reuse this invalid entry */
2204 /* If reach here, then this is a new thread and
2205 * there are no invalid entries to reuse
2206 * Double the size of the thread map table.
2209 n
= total_threads
* 2;
2210 mapptr
= (kd_threadmap
*) realloc(mapptr
, n
* sizeof(kd_threadmap
));
2211 bzero(&mapptr
[total_threads
], total_threads
*sizeof(kd_threadmap
));
2212 map
= &mapptr
[total_threads
];
2217 map
->thread
= thread
;
2219 The trace entry that returns the command name will hold
2220 at most, MAXCOMLEN chars, and in that case, is not
2221 guaranteed to be null terminated.
2223 (void)strncpy (map
->command
, command
, MAXCOMLEN
);
2224 map
->command
[MAXCOMLEN
] = '\0';
2228 kd_threadmap
*find_thread_map(int thread
)
2234 return((kd_threadmap
*)0);
2236 for (i
= 0; i
< total_threads
; i
++)
2239 if (map
->valid
&& (map
->thread
== thread
))
2244 return ((kd_threadmap
*)0);
2249 kill_thread_map(int thread
)
2253 if (map
= find_thread_map(thread
)) {
2256 map
->command
[0] = '\0';
2268 ret
= (int)strtol(str
, &cp
, 10);
2269 if (cp
== str
|| *cp
) {
2270 /* Assume this is a command string and find matching pids */
2274 for (i
=0; i
< kp_nentries
&& num_of_pids
< (MAX_PIDS
- 1); i
++) {
2275 if(kp_buffer
[i
].kp_proc
.p_stat
== 0)
2278 if(!strcmp(str
, kp_buffer
[i
].kp_proc
.p_comm
))
2279 pids
[num_of_pids
++] = kp_buffer
[i
].kp_proc
.p_pid
;
2283 else if (num_of_pids
< (MAX_PIDS
- 1))
2284 pids
[num_of_pids
++] = ret
;
2291 char *lookup_name(unsigned long addr
)
2294 register int start
, last
;
2297 if (numFrameworks
== 0 || addr
< frameworkInfo
[0].address
|| addr
> frameworkInfo
[numFrameworks
].address
)
2301 last
= numFrameworks
;
2303 for (i
= numFrameworks
/ 2; i
>= 0 && i
< numFrameworks
; ) {
2305 if (addr
>= frameworkInfo
[i
].address
&& addr
< frameworkInfo
[i
+1].address
)
2306 return(frameworkInfo
[i
].name
);
2308 if (addr
>= frameworkInfo
[i
].address
) {
2310 i
= start
+ ((last
- i
) / 2);
2313 i
= start
+ ((i
- start
) / 2);
2321 * Comparison routines for sorting
2323 static int compareFrameworkAddress(const void *aa
, const void *bb
)
2325 LibraryInfo
*a
= (LibraryInfo
*)aa
;
2326 LibraryInfo
*b
= (LibraryInfo
*)bb
;
2328 if (a
->address
< b
->address
) return -1;
2329 if (a
->address
== b
->address
) return 0;
2334 int scanline(char *inputstring
,char **argv
)
2337 char **ap
= argv
, *p
, *val
;
2339 for (p
= inputstring
; p
!= NULL
; )
2341 while ((val
= strsep(&p
, " \t")) != NULL
&& *val
== '\0');
2350 int ReadSegAddrTable()
2355 unsigned long frameworkAddress
, frameworkDataAddress
, previousFrameworkAddress
;
2356 char frameworkName
[256];
2359 char *substring
,*ptr
;
2364 bzero(buf
, sizeof(buf
));
2365 bzero(tokens
, sizeof(tokens
));
2369 if ((fd
= fopen(seg_addr_table
, "r")) == 0)
2373 fgets(buf
, 1023, fd
);
2378 frameworkName
[0] = 0;
2379 previousFrameworkAddress
= 0;
2381 while (fgets(buf
, 1023, fd
) && numFrameworks
< (MAXINDEX
- 2))
2386 buf
[strlen(buf
)-1] = 0;
2388 if (strncmp(buf
, "# dyld:", 7) == 0) {
2390 * the next line in the file will contain info about dyld
2396 * This is a split library line: parse it into 3 tokens
2398 ntokens
= scanline(buf
, tokens
);
2403 frameworkAddress
= strtoul(tokens
[0], 0, 16);
2404 frameworkDataAddress
= strtoul(tokens
[1], 0, 16);
2408 * dyld entry is of a different form from the std split library
2409 * it consists of a base address and a size instead of a code
2410 * and data base address
2412 frameworkInfo
[numFrameworks
].address
= frameworkAddress
;
2413 frameworkInfo
[numFrameworks
+1].address
= frameworkAddress
+ frameworkDataAddress
;
2415 frameworkInfo
[numFrameworks
].name
= (char *)"dylib";
2416 frameworkInfo
[numFrameworks
+1].name
= (char *)0;
2425 * Make sure that we have 2 addresses and a path
2427 if (!frameworkAddress
)
2429 if (!frameworkDataAddress
)
2431 if (*tokens
[2] != '/')
2433 if (frameworkAddress
== previousFrameworkAddress
)
2435 previousFrameworkAddress
= frameworkAddress
;
2438 * Extract lib name from path name
2440 if (substring
= strrchr(tokens
[2], '.'))
2443 * There is a ".": name is whatever is between the "/" around the "."
2445 while ( *substring
!= '/') { /* find "/" before "." */
2449 strcpy(frameworkName
, substring
); /* copy path from "/" */
2450 substring
= frameworkName
;
2452 while ( *substring
!= '/' && *substring
) /* find "/" after "." and stop string there */
2459 * No ".": take segment after last "/"
2467 substring
= ptr
+ 1;
2470 strcpy(frameworkName
, substring
);
2472 frameworkInfo
[numFrameworks
].address
= frameworkAddress
;
2473 frameworkInfo
[numFrameworks
+1].address
= frameworkDataAddress
;
2475 frameworkInfo
[numFrameworks
].name
= (char *)malloc(strlen(frameworkName
) + 1);
2476 strcpy(frameworkInfo
[numFrameworks
].name
, frameworkName
);
2477 frameworkInfo
[numFrameworks
+1].name
= frameworkInfo
[numFrameworks
].name
;
2482 frameworkInfo
[numFrameworks
].address
= frameworkInfo
[numFrameworks
- 1].address
+ 0x800000;
2483 frameworkInfo
[numFrameworks
].name
= (char *)0;
2487 qsort(frameworkInfo
, numFrameworks
, sizeof(LibraryInfo
), compareFrameworkAddress
);
2493 struct diskio
*insert_diskio(int type
, int bp
, int dev
, int blkno
, int io_size
, int thread
, double curtime
)
2495 register struct diskio
*dio
;
2496 register kd_threadmap
*map
;
2498 if (dio
= free_diskios
)
2499 free_diskios
= dio
->next
;
2501 if ((dio
= (struct diskio
*)malloc(sizeof(struct diskio
))) == NULL
)
2510 dio
->iosize
= io_size
;
2511 dio
->issued_time
= curtime
;
2512 dio
->issuing_thread
= thread
;
2514 if (map
= find_thread_map(thread
))
2515 strcpy(dio
->issuing_command
, map
->command
);
2517 strcpy(dio
->issuing_command
, "");
2519 dio
->next
= busy_diskios
;
2521 dio
->next
->prev
= dio
;
2528 struct diskio
*complete_diskio(int bp
, int io_errno
, int resid
, int thread
, double curtime
)
2530 register struct diskio
*dio
;
2532 for (dio
= busy_diskios
; dio
; dio
= dio
->next
) {
2533 if (dio
->bp
== bp
) {
2535 if (dio
== busy_diskios
) {
2536 if (busy_diskios
= dio
->next
)
2537 dio
->next
->prev
= NULL
;
2540 dio
->next
->prev
= dio
->prev
;
2541 dio
->prev
->next
= dio
->next
;
2543 dio
->iosize
-= resid
;
2544 dio
->io_errno
= io_errno
;
2545 dio
->completed_time
= curtime
;
2546 dio
->completion_thread
= thread
;
2551 return ((struct diskio
*)0);
2555 void free_diskio(struct diskio
*dio
)
2557 dio
->next
= free_diskios
;
2562 void print_diskio(struct diskio
*dio
)
2567 switch (dio
->type
) {
2588 p
= " RdMeta[async]";
2591 p
= " WrMeta[async]";
2594 p
= " RdData[async]";
2597 p
= " WrData[async]";
2603 p
= " PgOut[async]";
2607 format_print(NULL
, p
, dio
->issuing_thread
, dio
->type
, 0, 0, 0, 7, dio
->completed_time
, dio
->issued_time
, 1, "", dio
);
2616 struct diskrec
*dnp
;
2619 if ((dirp
= opendir("/dev")) == NULL
)
2622 while ((dir
= readdir(dirp
)) != NULL
) {
2623 char nbuf
[MAXPATHLEN
];
2625 if (dir
->d_namlen
< 5 || strncmp("disk", dir
->d_name
, 4))
2627 sprintf(nbuf
, "%s/%s", "/dev", dir
->d_name
);
2629 if (stat(nbuf
, &st
) < 0)
2632 if ((dnp
= (struct diskrec
*)malloc(sizeof(struct diskrec
))) == NULL
)
2635 if ((dnp
->diskname
= (char *)malloc(dir
->d_namlen
+ 1)) == NULL
) {
2639 strncpy(dnp
->diskname
, dir
->d_name
, dir
->d_namlen
);
2640 dnp
->diskname
[dir
->d_namlen
] = 0;
2641 dnp
->dev
= st
.st_rdev
;
2643 dnp
->next
= disk_list
;
2646 (void) closedir(dirp
);
2650 char *find_disk_name(int dev
)
2652 struct diskrec
*dnp
;
2657 for (dnp
= disk_list
; dnp
; dnp
= dnp
->next
) {
2658 if (dnp
->dev
== dev
)
2659 return (dnp
->diskname
);
2661 return ("NOTFOUND");