2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
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
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.
23 * @APPLE_LICENSE_HEADER_END@
27 cc -I. -DKERNEL_PRIVATE -O -o fs_usage fs_usage.c
30 #define Default_DELAY 1 /* default delay interval */
41 #include <sys/types.h>
42 #include <sys/param.h>
47 #include <sys/ioctl.h>
49 #ifndef KERNEL_PRIVATE
50 #define KERNEL_PRIVATE
51 #include <sys/kdebug.h>
54 #include <sys/kdebug.h>
55 #endif /*KERNEL_PRIVATE*/
57 #include <sys/sysctl.h>
59 #import <mach/clock_types.h>
68 typedef struct LibraryInfo
{
69 unsigned long address
;
73 LibraryInfo frameworkInfo
[MAXINDEX
];
74 int numFrameworks
= 0;
76 char seg_addr_table
[256]="/AppleInternal/Developer/seg_addr_table";
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.
88 #define PATHLENGTH (NUMPARMS*sizeof(long))
90 #define MAX_WIDE_MODE_COLS (PATHLENGTH + 80)
104 char pathname
[PATHLENGTH
+ 1]; /* add room for null terminator */
107 #define MAX_THREADS 512
108 struct th_info th_state
[MAX_THREADS
];
112 int need_new_map
= 1;
116 int select_pid_mode
= 0; /* Flag set indicates that output is restricted
117 to selected pids or commands */
119 int one_good_pid
= 0; /* Used to fail gracefully when bad pids given */
125 struct diskrec
*next
;
140 int completion_thread
;
141 char issuing_command
[MAXCOMLEN
];
143 double completed_time
;
146 struct diskrec
*disk_list
= NULL
;
147 struct diskio
*free_diskios
= NULL
;
148 struct diskio
*busy_diskios
= NULL
;
150 struct diskio
*insert_diskio();
151 struct diskio
*complete_diskio();
155 char *find_disk_name();
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
163 #define TRACE_DATA_NEWTHREAD 0x07000004
164 #define TRACE_STRING_NEWTHREAD 0x07010004
165 #define TRACE_STRING_EXEC 0x07010008
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
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
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
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
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
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
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
335 #define FILEMGR_CLASS 0x1e
341 int exclude_pids
= 0;
342 int exclude_default_pids
= 1;
344 struct kinfo_proc
*kp_buffer
= 0;
347 #define SAMPLE_SIZE 60000
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
354 #define DBG_FUNC_ALL (DBG_FUNC_START | DBG_FUNC_END)
355 #define DBG_FUNC_MASK 0xfffffffc
357 double divisor
= 0.0; /* Trace divisor converts to microseconds */
363 kbufinfo_t bufinfo
= {0, 0, 0, 0};
365 int total_threads
= 0;
366 kd_threadmap
*mapptr
= 0;
368 int trace_enabled
= 0;
369 int set_remove_flag
= 1;
381 void leave() /* exit under normal conditions -- INT handler */
386 void set_pidexclude();
391 if (exclude_pids
== 0) {
392 for (i
= 0; i
< num_of_pids
; i
++)
393 set_pidcheck(pids
[i
], 0);
396 for (i
= 0; i
< num_of_pids
; i
++)
397 set_pidexclude(pids
[i
], 0);
404 void get_screenwidth()
411 if (ioctl(1, TIOCGWINSZ
, &size
) != -1)
412 columns
= size
.ws_col
;
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");
444 char *myname
= "fs_usage";
451 void set_pidexclude();
454 if ( geteuid() != 0 ) {
455 printf("'fs_usage' must be run as root...\n");
462 if ((myname
= rindex(argv
[0], '/')) == 0) {
470 while ((ch
= getopt(argc
, argv
, "ew")) != EOF
) {
474 exclude_default_pids
= 0;
478 if (columns
< MAX_WIDE_MODE_COLS
)
479 columns
= MAX_WIDE_MODE_COLS
;
489 /* If we process any list of pids/cmds, then turn off the defaults */
491 exclude_default_pids
= 0;
493 while (argc
> 0 && num_of_pids
< (MAX_PIDS
- 1)) {
500 /* Exclude a set of default pids */
501 if (exclude_default_pids
)
503 argtopid("Terminal");
516 if (num_of_pids
< (MAX_PIDS
- 1))
517 pids
[num_of_pids
++] = getpid();
523 for (i
= 0; i
< num_of_pids
; i
++)
526 printf("exclude pid %d\n", pids
[i
]);
528 printf("pid %d\n", pids
[i
]);
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
);
539 if ((my_buffer
= malloc(SAMPLE_SIZE
* sizeof(kd_buf
))) == (char *)0)
540 quit("can't allocate memory for tracing info\n");
546 set_numbufs(SAMPLE_SIZE
);
549 if (exclude_pids
== 0) {
550 for (i
= 0; i
< num_of_pids
; i
++)
551 set_pidcheck(pids
[i
], 1);
553 for (i
= 0; i
< num_of_pids
; i
++)
554 set_pidexclude(pids
[i
], 1);
557 if (select_pid_mode
&& !one_good_pid
)
560 An attempt to restrict output to a given
561 pid or command has failed. Exit gracefully
584 struct kinfo_proc
*kp
;
589 mib
[2] = KERN_PROC_ALL
;
592 if (sysctl(mib
, 4, NULL
, &bufSize
, NULL
, 0) < 0)
593 quit("trace facility failure, KERN_PROC_ALL\n");
595 if((kp
= (struct kinfo_proc
*)malloc(bufSize
)) == (struct kinfo_proc
*)0)
596 quit("can't allocate memory for proc buffer\n");
598 if (sysctl(mib
, 4, kp
, &bufSize
, NULL
, 0) < 0)
599 quit("trace facility failure, KERN_PROC_ALL\n");
601 kp_nentries
= bufSize
/ sizeof(struct kinfo_proc
);
606 struct th_info
*find_thread(int thread
, int type
) {
609 for (ti
= th_state
; ti
< &th_state
[cur_max
]; ti
++) {
610 if (ti
->thread
== thread
) {
611 if (type
== ti
->type
)
613 if (ti
->in_filemgr
) {
622 return ((struct th_info
*)0);
626 mark_thread_waited(int thread
) {
629 for (ti
= th_state
; ti
< &th_state
[cur_max
]; ti
++) {
630 if (ti
->thread
== thread
) {
641 mib
[1] = KERN_KDEBUG
;
642 mib
[2] = KERN_KDENABLE
; /* protocol */
645 mib
[5] = 0; /* no flags */
646 if (sysctl(mib
, 4, NULL
, &needed
, NULL
, 0) < 0)
647 quit("trace facility failure, KERN_KDENABLE\n");
656 set_numbufs(int nbufs
)
659 mib
[1] = KERN_KDEBUG
;
660 mib
[2] = KERN_KDSETBUF
;
663 mib
[5] = 0; /* no flags */
664 if (sysctl(mib
, 4, NULL
, &needed
, NULL
, 0) < 0)
665 quit("trace facility failure, KERN_KDSETBUF\n");
668 mib
[1] = KERN_KDEBUG
;
669 mib
[2] = KERN_KDSETUP
;
672 mib
[5] = 0; /* no flags */
673 if (sysctl(mib
, 3, NULL
, &needed
, NULL
, 0) < 0)
674 quit("trace facility failure, KERN_KDSETUP\n");
678 set_pidcheck(int pid
, int on_off
)
682 kr
.type
= KDBG_TYPENONE
;
685 needed
= sizeof(kd_regtype
);
687 mib
[1] = KERN_KDEBUG
;
688 mib
[2] = KERN_KDPIDTR
;
693 if (sysctl(mib
, 3, &kr
, &needed
, NULL
, 0) < 0) {
695 printf("pid %d does not exist\n", pid
);
703 on_off == 0 turns off pid exclusion
704 on_off == 1 turns on pid exclusion
707 set_pidexclude(int pid
, int on_off
)
713 kr
.type
= KDBG_TYPENONE
;
716 needed
= sizeof(kd_regtype
);
718 mib
[1] = KERN_KDEBUG
;
719 mib
[2] = KERN_KDPIDEX
;
724 if (sysctl(mib
, 3, &kr
, &needed
, NULL
, 0) < 0) {
726 printf("pid %d does not exist\n", pid
);
731 get_bufinfo(kbufinfo_t
*val
)
733 needed
= sizeof (*val
);
735 mib
[1] = KERN_KDEBUG
;
736 mib
[2] = KERN_KDGETBUF
;
739 mib
[5] = 0; /* no flags */
741 if (sysctl(mib
, 3, val
, &needed
, 0, 0) < 0)
742 quit("trace facility failure, KERN_KDGETBUF\n");
752 mib
[1] = KERN_KDEBUG
;
753 mib
[2] = KERN_KDREMOVE
; /* protocol */
756 mib
[5] = 0; /* no flags */
757 if (sysctl(mib
, 3, NULL
, &needed
, NULL
, 0) < 0)
762 quit("the trace facility is currently in use...\n fs_usage, sc_usage, and latency use this feature.\n\n");
764 quit("trace facility failure, KERN_KDREMOVE\n");
772 kr
.type
= KDBG_RANGETYPE
;
775 needed
= sizeof(kd_regtype
);
777 mib
[1] = KERN_KDEBUG
;
778 mib
[2] = KERN_KDSETREG
;
781 mib
[5] = 0; /* no flags */
783 if (sysctl(mib
, 3, &kr
, &needed
, NULL
, 0) < 0)
784 quit("trace facility failure, KERN_KDSETREG\n");
787 mib
[1] = KERN_KDEBUG
;
788 mib
[2] = KERN_KDSETUP
;
791 mib
[5] = 0; /* no flags */
793 if (sysctl(mib
, 3, NULL
, &needed
, NULL
, 0) < 0)
794 quit("trace facility failure, KERN_KDSETUP\n");
803 void read_command_map();
804 void create_map_entry();
806 /* Get kernel buffer information */
807 get_bufinfo(&bufinfo
);
813 needed
= bufinfo
.nkdbufs
* sizeof(kd_buf
);
815 mib
[1] = KERN_KDEBUG
;
816 mib
[2] = KERN_KDREADTR
;
819 mib
[5] = 0; /* no flags */
821 if (sysctl(mib
, 3, my_buffer
, &needed
, NULL
, 0) < 0)
822 quit("trace facility failure, KERN_KDREADTR\n");
825 if (bufinfo
.flags
& KDBG_WRAPPED
) {
826 printf("buffer wrapped count = %d\n", count
);
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;
839 kd
= (kd_buf
*)my_buffer
;
841 printf("READTR returned %d items\n", count
);
843 for (i
= 0; i
< count
; i
++) {
847 unsigned long long now
;
850 void enter_syscall();
852 void kill_thread_map();
854 thread
= kd
[i
].arg5
& KDBG_THREAD_MASK
;
855 debugid
= kd
[i
].debugid
;
856 type
= kd
[i
].debugid
& DBG_FUNC_MASK
;
858 now
= (((unsigned long long)kd
[i
].timestamp
.tv_sec
) << 32) |
859 (unsigned long long)((unsigned int)(kd
[i
].timestamp
.tv_nsec
));
876 insert_diskio(type
, kd
[i
].arg1
, kd
[i
].arg2
, kd
[i
].arg3
, kd
[i
].arg4
, thread
, (double)now
);
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
)) {
898 case TRACE_DATA_NEWTHREAD
:
900 for (n
= 0, ti
= th_state
; ti
< &th_state
[MAX_THREADS
]; ti
++, n
++) {
904 if (ti
== &th_state
[MAX_THREADS
])
910 ti
->child_thread
= kd
[i
].arg1
;
913 case TRACE_STRING_NEWTHREAD
:
914 if ((ti
= find_thread(thread
, 0)) == (struct th_info
*)0)
916 if (ti
->child_thread
== 0)
918 create_map_entry(ti
->child_thread
, (char *)&kd
[i
].arg1
);
920 if (ti
== &th_state
[cur_max
- 1])
922 ti
->child_thread
= 0;
926 case TRACE_STRING_EXEC
:
927 create_map_entry(thread
, (char *)&kd
[i
].arg1
);
931 kill_thread_map(thread
);
935 case MACH_stkhandoff
:
936 mark_thread_waited(thread
);
940 if ((ti
= find_thread(thread
, 0)) == (struct th_info
*)0)
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
;
951 sargptr
= ti
->pathptr
;
954 We don't want to overrun our pathname buffer if the
955 kernel sends us more VFS_LOOKUP entries than we can
959 if ((long *)sargptr
>= (long *)&ti
->pathname
[PATHLENGTH
])
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
969 if (debugid
& DBG_FUNC_START
)
971 (long *)ti
->pathptr
= (long *)&ti
->pathname
[PATHLENGTH
];
975 *sargptr
++ = kd
[i
].arg1
;
976 *sargptr
++ = kd
[i
].arg2
;
977 *sargptr
++ = kd
[i
].arg3
;
978 *sargptr
++ = kd
[i
].arg4
;
979 ti
->pathptr
= sargptr
;
984 if (debugid
& DBG_FUNC_START
) {
988 case FILEMGR_PBGETCATALOGINFO
:
989 p
= "GetCatalogInfo";
991 case FILEMGR_PBGETCATALOGINFOBULK
:
992 p
= "GetCatalogInfoBulk";
994 case FILEMGR_PBCREATEFILEUNICODE
:
995 p
= "CreateFileUnicode";
997 case FILEMGR_PBCREATEDIRECTORYUNICODE
:
998 p
= "CreateDirectoryUnicode";
1000 case FILEMGR_PBCREATEFORK
:
1003 case FILEMGR_PBDELETEFORK
:
1006 case FILEMGR_PBITERATEFORK
:
1007 p
= "PBIterateFork";
1009 case FILEMGR_PBOPENFORK
:
1012 case FILEMGR_PBREADFORK
:
1015 case FILEMGR_PBWRITEFORK
:
1018 case FILEMGR_PBALLOCATEFORK
:
1019 p
= "PBAllocateFork";
1021 case FILEMGR_PBDELETEOBJECT
:
1022 p
= "PBDeleteObject";
1024 case FILEMGR_PBEXCHANGEOBJECT
:
1025 p
= "PBExchangeObject";
1027 case FILEMGR_PBGETFORKCBINFO
:
1028 p
= "PBGetForkCBInfo";
1030 case FILEMGR_PBGETVOLUMEINFO
:
1031 p
= "PBGetVolumeInfo";
1033 case FILEMGR_PBMAKEFSREF
:
1036 case FILEMGR_PBMAKEFSREFUNICODE
:
1037 p
= "PBMakeFSRefUnicode";
1039 case FILEMGR_PBMOVEOBJECT
:
1042 case FILEMGR_PBOPENITERATOR
:
1043 p
= "PBOpenIterator";
1045 case FILEMGR_PBRENAMEUNICODE
:
1046 p
= "PBRenameUnicode";
1048 case FILEMGR_PBSETCATALOGINFO
:
1049 p
= "SetCatalogInfo";
1051 case FILEMGR_PBSETVOLUMEINFO
:
1052 p
= "SetVolumeInfo";
1054 case FILEMGR_FSREFMAKEPATH
:
1055 p
= "FSRefMakePath";
1057 case FILEMGR_FSPATHMAKEREF
:
1058 p
= "FSPathMakeRef";
1061 case FILEMGR_PBGETCATINFO
:
1064 case FILEMGR_PBGETCATINFOLITE
:
1065 p
= "GetCatInfoLite";
1067 case FILEMGR_PBHGETFINFO
:
1070 case FILEMGR_PBXGETVOLINFO
:
1071 p
= "PBXGetVolInfo";
1073 case FILEMGR_PBHCREATE
:
1076 case FILEMGR_PBHOPENDF
:
1079 case FILEMGR_PBHOPENRF
:
1082 case FILEMGR_PBHGETDIRACCESS
:
1083 p
= "PBHGetDirAccess";
1085 case FILEMGR_PBHSETDIRACCESS
:
1086 p
= "PBHSetDirAccess";
1088 case FILEMGR_PBHMAPID
:
1091 case FILEMGR_PBHMAPNAME
:
1094 case FILEMGR_PBCLOSE
:
1097 case FILEMGR_PBFLUSHFILE
:
1100 case FILEMGR_PBGETEOF
:
1103 case FILEMGR_PBSETEOF
:
1106 case FILEMGR_PBGETFPOS
:
1109 case FILEMGR_PBREAD
:
1112 case FILEMGR_PBWRITE
:
1115 case FILEMGR_PBGETFCBINFO
:
1118 case FILEMGR_PBSETFINFO
:
1121 case FILEMGR_PBALLOCATE
:
1124 case FILEMGR_PBALLOCCONTIG
:
1125 p
= "PBAllocContig";
1127 case FILEMGR_PBSETFPOS
:
1130 case FILEMGR_PBSETCATINFO
:
1133 case FILEMGR_PBGETVOLPARMS
:
1134 p
= "PBGetVolParms";
1136 case FILEMGR_PBSETVINFO
:
1139 case FILEMGR_PBMAKEFSSPEC
:
1142 case FILEMGR_PBHGETVINFO
:
1145 case FILEMGR_PBCREATEFILEIDREF
:
1146 p
= "PBCreateFileIDRef";
1148 case FILEMGR_PBDELETEFILEIDREF
:
1149 p
= "PBDeleteFileIDRef";
1151 case FILEMGR_PBRESOLVEFILEIDREF
:
1152 p
= "PBResolveFileIDRef";
1154 case FILEMGR_PBFLUSHVOL
:
1157 case FILEMGR_PBHRENAME
:
1160 case FILEMGR_PBCATMOVE
:
1163 case FILEMGR_PBEXCHANGEFILES
:
1164 p
= "PBExchangeFiles";
1166 case FILEMGR_PBHDELETE
:
1169 case FILEMGR_PBDIRCREATE
:
1172 case FILEMGR_PBCATSEARCH
:
1175 case FILEMGR_PBHSETFLOCK
:
1178 case FILEMGR_PBHRSTFLOCK
:
1181 case FILEMGR_PBLOCKRANGE
:
1184 case FILEMGR_PBUNLOCKRANGE
:
1185 p
= "PBUnlockRange";
1191 enter_syscall(thread
, type
, &kd
[i
], p
, (double)now
);
1198 exit_syscall("PAGE_OUT_D", thread
, type
, 0, kd
[i
].arg1
, 0, 4, (double)now
);
1200 exit_syscall("PAGE_OUT_V", thread
, type
, 0, kd
[i
].arg1
, 0, 4, (double)now
);
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
);
1209 if (ti
= find_thread(thread
, type
)) {
1210 if (ti
== &th_state
[cur_max
- 1])
1218 exit_syscall("map_fd", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 0, (double)now
);
1222 exit_syscall("mmap", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1226 exit_syscall("recvmsg", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 1, (double)now
);
1230 exit_syscall("sendmsg", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 1, (double)now
);
1234 exit_syscall("recvfrom", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 1, (double)now
);
1238 exit_syscall("sendto", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 1, (double)now
);
1242 exit_syscall("stat", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1245 case BSC_load_shared_file
:
1246 exit_syscall("load_sf", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1250 exit_syscall("open", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 2, 0, (double)now
);
1254 exit_syscall("close", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 0, (double)now
);
1258 exit_syscall("read", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 1, (double)now
);
1262 exit_syscall("write", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 1, (double)now
);
1266 exit_syscall("fstat", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 0, (double)now
);
1270 exit_syscall("lstat", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1274 exit_syscall("link", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1278 exit_syscall("unlink", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1282 exit_syscall("mknod", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1286 exit_syscall("chmod", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1290 exit_syscall("chown", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1294 exit_syscall("access", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1298 exit_syscall("chdir", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1302 exit_syscall("chroot", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1306 exit_syscall("utimes", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1310 exit_syscall("delete", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1314 exit_syscall("undelete", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1318 exit_syscall("revoke", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1322 exit_syscall("fsctl", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1326 exit_syscall("chflags", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1330 exit_syscall("fchflags", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 0, (double)now
);
1334 exit_syscall("fchdir", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 0, (double)now
);
1338 exit_syscall("futimes", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 0, (double)now
);
1342 exit_syscall("sync", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1346 exit_syscall("symlink", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1350 exit_syscall("readlink", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1354 exit_syscall("fsync", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 0, (double)now
);
1358 exit_syscall("readv", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 1, (double)now
);
1362 exit_syscall("writev", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 1, (double)now
);
1366 exit_syscall("fchown", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 0, (double)now
);
1370 exit_syscall("fchmod", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 0, (double)now
);
1374 exit_syscall("mkdir", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1378 exit_syscall("mkfifo", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1382 exit_syscall("rmdir", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1386 exit_syscall("statfs", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1390 exit_syscall("fstatfs", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 0, (double)now
);
1394 exit_syscall("pathconf", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1398 exit_syscall("fpathconf", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 0, (double)now
);
1401 case BSC_getdirentries
:
1402 exit_syscall("getdirentries", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 1, (double)now
);
1406 exit_syscall("lseek", thread
, type
, kd
[i
].arg1
, kd
[i
].arg3
, 1, 5, (double)now
);
1410 exit_syscall("truncate", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1414 exit_syscall("ftruncate", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 3, (double)now
);
1418 exit_syscall("statv", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1422 exit_syscall("lstatv", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1426 exit_syscall("fstatv", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 0, (double)now
);
1430 exit_syscall("mkcomplex", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1433 case BSC_getattrlist
:
1434 exit_syscall("getattrlist", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1437 case BSC_setattrlist
:
1438 exit_syscall("setattrlist", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1441 case BSC_getdirentriesattr
:
1442 exit_syscall("getdirentriesattr", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 1, (double)now
);
1446 case BSC_exchangedata
:
1447 exit_syscall("exchangedata", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1451 exit_syscall("rename", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1455 exit_syscall("copyfile", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1459 case BSC_checkuseraccess
:
1460 exit_syscall("checkuseraccess", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1464 exit_syscall("searchfs", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1467 case FILEMGR_PBGETCATALOGINFO
:
1468 exit_syscall("GetCatalogInfo", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1470 case FILEMGR_PBGETCATALOGINFOBULK
:
1471 exit_syscall("GetCatalogInfoBulk", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1473 case FILEMGR_PBCREATEFILEUNICODE
:
1474 exit_syscall("CreateFileUnicode", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1476 case FILEMGR_PBCREATEDIRECTORYUNICODE
:
1477 exit_syscall("CreateDirectoryUnicode", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1479 case FILEMGR_PBCREATEFORK
:
1480 exit_syscall("PBCreateFork", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1482 case FILEMGR_PBDELETEFORK
:
1483 exit_syscall("PBDeleteFork", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1485 case FILEMGR_PBITERATEFORK
:
1486 exit_syscall("PBIterateFork", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1488 case FILEMGR_PBOPENFORK
:
1489 exit_syscall("PBOpenFork", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1491 case FILEMGR_PBREADFORK
:
1492 exit_syscall("PBReadFork", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1494 case FILEMGR_PBWRITEFORK
:
1495 exit_syscall("PBWriteFork", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1497 case FILEMGR_PBALLOCATEFORK
:
1498 exit_syscall("PBAllocateFork", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1500 case FILEMGR_PBDELETEOBJECT
:
1501 exit_syscall("PBDeleteObject", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1503 case FILEMGR_PBEXCHANGEOBJECT
:
1504 exit_syscall("PBExchangeObject", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1506 case FILEMGR_PBGETFORKCBINFO
:
1507 exit_syscall("PBGetForkCBInfo", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1509 case FILEMGR_PBGETVOLUMEINFO
:
1510 exit_syscall("PBGetVolumeInfo", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1512 case FILEMGR_PBMAKEFSREF
:
1513 exit_syscall("PBMakeFSRef", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1515 case FILEMGR_PBMAKEFSREFUNICODE
:
1516 exit_syscall("PBMakeFSRefUnicode", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1518 case FILEMGR_PBMOVEOBJECT
:
1519 exit_syscall("PBMoveObject", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1521 case FILEMGR_PBOPENITERATOR
:
1522 exit_syscall("PBOpenIterator", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1524 case FILEMGR_PBRENAMEUNICODE
:
1525 exit_syscall("PBRenameUnicode", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1527 case FILEMGR_PBSETCATALOGINFO
:
1528 exit_syscall("PBSetCatalogInfo", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1530 case FILEMGR_PBSETVOLUMEINFO
:
1531 exit_syscall("PBSetVolumeInfo", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1533 case FILEMGR_FSREFMAKEPATH
:
1534 exit_syscall("FSRefMakePath", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1536 case FILEMGR_FSPATHMAKEREF
:
1537 exit_syscall("FSPathMakeRef", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1539 case FILEMGR_PBGETCATINFO
:
1540 exit_syscall("GetCatInfo", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1542 case FILEMGR_PBGETCATINFOLITE
:
1543 exit_syscall("GetCatInfoLite", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1545 case FILEMGR_PBHGETFINFO
:
1546 exit_syscall("PBHGetFInfo", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1548 case FILEMGR_PBXGETVOLINFO
:
1549 exit_syscall("PBXGetVolInfo", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1551 case FILEMGR_PBHCREATE
:
1552 exit_syscall("PBHCreate", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1554 case FILEMGR_PBHOPENDF
:
1555 exit_syscall("PBHOpenDF", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1557 case FILEMGR_PBHOPENRF
:
1558 exit_syscall("PBHOpenRF", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1560 case FILEMGR_PBHGETDIRACCESS
:
1561 exit_syscall("PBHGetDirAccess", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1563 case FILEMGR_PBHSETDIRACCESS
:
1564 exit_syscall("PBHSetDirAccess", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1566 case FILEMGR_PBHMAPID
:
1567 exit_syscall("PBHMapID", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1569 case FILEMGR_PBHMAPNAME
:
1570 exit_syscall("PBHMapName", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1572 case FILEMGR_PBCLOSE
:
1573 exit_syscall("PBClose", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1575 case FILEMGR_PBFLUSHFILE
:
1576 exit_syscall("PBFlushFile", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1578 case FILEMGR_PBGETEOF
:
1579 exit_syscall("PBGetEOF", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1581 case FILEMGR_PBSETEOF
:
1582 exit_syscall("PBSetEOF", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1584 case FILEMGR_PBGETFPOS
:
1585 exit_syscall("PBGetFPos", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1587 case FILEMGR_PBREAD
:
1588 exit_syscall("PBRead", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1590 case FILEMGR_PBWRITE
:
1591 exit_syscall("PBWrite", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1593 case FILEMGR_PBGETFCBINFO
:
1594 exit_syscall("PBGetFCBInfo", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1596 case FILEMGR_PBSETFINFO
:
1597 exit_syscall("PBSetFInfo", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1599 case FILEMGR_PBALLOCATE
:
1600 exit_syscall("PBAllocate", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1602 case FILEMGR_PBALLOCCONTIG
:
1603 exit_syscall("PBAllocContig", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1605 case FILEMGR_PBSETFPOS
:
1606 exit_syscall("PBSetFPos", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1608 case FILEMGR_PBSETCATINFO
:
1609 exit_syscall("PBSetCatInfo", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1611 case FILEMGR_PBGETVOLPARMS
:
1612 exit_syscall("PBGetVolParms", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1614 case FILEMGR_PBSETVINFO
:
1615 exit_syscall("PBSetVInfo", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1617 case FILEMGR_PBMAKEFSSPEC
:
1618 exit_syscall("PBMakeFSSpec", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1620 case FILEMGR_PBHGETVINFO
:
1621 exit_syscall("PBHGetVInfo", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1623 case FILEMGR_PBCREATEFILEIDREF
:
1624 exit_syscall("PBCreateFileIDRef", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1626 case FILEMGR_PBDELETEFILEIDREF
:
1627 exit_syscall("PBDeleteFileIDRef", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1629 case FILEMGR_PBRESOLVEFILEIDREF
:
1630 exit_syscall("PBResolveFileIDRef", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1632 case FILEMGR_PBFLUSHVOL
:
1633 exit_syscall("PBFlushVol", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1635 case FILEMGR_PBHRENAME
:
1636 exit_syscall("PBHRename", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1638 case FILEMGR_PBCATMOVE
:
1639 exit_syscall("PBCatMove", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1641 case FILEMGR_PBEXCHANGEFILES
:
1642 exit_syscall("PBExchangeFiles", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1644 case FILEMGR_PBHDELETE
:
1645 exit_syscall("PBHDelete", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1647 case FILEMGR_PBDIRCREATE
:
1648 exit_syscall("PBDirCreate", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1650 case FILEMGR_PBCATSEARCH
:
1651 exit_syscall("PBCatSearch", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1653 case FILEMGR_PBHSETFLOCK
:
1654 exit_syscall("PBHSetFLock", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1656 case FILEMGR_PBHRSTFLOCK
:
1657 exit_syscall("PBHRstFLock", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1659 case FILEMGR_PBLOCKRANGE
:
1660 exit_syscall("PBLockRange", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1662 case FILEMGR_PBUNLOCKRANGE
:
1663 exit_syscall("PBUnlockRange", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1673 enter_syscall(int thread
, int type
, kd_buf
*kd
, char *name
, double now
)
1682 kd_threadmap
*find_thread_map();
1700 case BSC_load_shared_file
:
1741 case BSC_getdirentries
:
1749 case BSC_getattrlist
:
1750 case BSC_setattrlist
:
1751 case BSC_getdirentriesattr
:
1752 case BSC_exchangedata
:
1753 case BSC_checkuseraccess
:
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
:
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
:
1824 for (i
= 0, ti
= th_state
; ti
< &th_state
[MAX_THREADS
]; ti
++, i
++) {
1825 if (ti
->thread
== 0)
1828 if (ti
== &th_state
[MAX_THREADS
])
1834 if ((type
>> 24) == FILEMGR_CLASS
) {
1837 l_usecs
= (long long)(now
/ divisor
);
1838 secs
= l_usecs
/ 1000000;
1840 if (bias_secs
== 0) {
1841 curr_time
= time((long *)0);
1842 bias_secs
= curr_time
- secs
;
1844 curr_time
= bias_secs
+ secs
;
1845 sprintf(buf
, "%-8.8s", &(ctime(&curr_time
)[11]));
1846 tsclen
= strlen(buf
);
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
);
1854 /* Print timestamp column */
1857 map
= find_thread_map(thread
);
1859 sprintf(buf
, " %-25.25s ", name
);
1860 nmclen
= strlen(buf
);
1863 sprintf(buf
, "(%d, 0x%x, 0x%x, 0x%x)", (short)kd
->arg1
, kd
->arg2
, kd
->arg3
, kd
->arg4
);
1864 argsclen
= strlen(buf
);
1867 Calculate white space out to command
1869 if (columns
> MAXCOLS
|| wideflag
)
1871 clen
= columns
- (tsclen
+ nmclen
+ argsclen
+ 20);
1874 clen
= columns
- (tsclen
+ nmclen
+ argsclen
+ 12);
1878 printf(buf
); /* print the kdargs */
1879 memset(buf
, ' ', clen
);
1883 else if ((argsclen
+ clen
) > 0)
1885 /* no room so wipe out the kdargs */
1886 memset(buf
, ' ', (argsclen
+ clen
));
1887 buf
[argsclen
+ clen
] = '\0';
1891 if (columns
> MAXCOLS
|| wideflag
)
1892 printf("%-20.20s\n", map
->command
);
1894 printf("%-12.12s\n", map
->command
);
1896 printf(" %-24.24s (%5d, %#x, 0x%x, 0x%x)\n", name
, (short)kd
->arg1
, kd
->arg2
, kd
->arg3
, kd
->arg4
);
1900 ti
->thread
= thread
;
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;
1920 exit_syscall(char *sc_name
, int thread
, int type
, int error
, int retval
,
1921 int has_fd
, int has_ret
, double now
)
1925 if ((ti
= find_thread(thread
, type
)) == (struct th_info
*)0)
1928 format_print(ti
, sc_name
, thread
, type
, error
, retval
, has_fd
, has_ret
, now
, ti
->stime
, ti
->waited
, ti
->pathname
, NULL
);
1930 if (ti
== &th_state
[cur_max
- 1])
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
)
1948 kd_threadmap
*find_thread_map();
1951 char *framework_name
;
1957 command_name
= dio
->issuing_command
;
1959 if (map
= find_thread_map(thread
))
1960 command_name
= map
->command
;
1962 l_usecs
= (long long)(now
/ divisor
);
1963 secs
= l_usecs
/ 1000000;
1965 if (bias_secs
== 0) {
1966 curr_time
= time((long *)0);
1967 bias_secs
= curr_time
- secs
;
1969 curr_time
= bias_secs
+ secs
;
1970 sprintf(buf
, "%-8.8s", &(ctime(&curr_time
)[11]));
1973 if (columns
> MAXCOLS
|| wideflag
) {
1975 usecs
= l_usecs
- (long long)((long long)secs
* 1000000);
1976 sprintf(&buf
[clen
], ".%03ld", (long)usecs
/ 1000);
1979 if ((type
>> 24) != FILEMGR_CLASS
) {
1980 if (find_thread(thread
, -1)) {
1981 sprintf(&buf
[clen
], " ");
1989 if (((type
>> 24) == FILEMGR_CLASS
) && (columns
> MAXCOLS
|| wideflag
))
1990 sprintf(&buf
[clen
], " %-18.18s", sc_name
);
1992 sprintf(&buf
[clen
], " %-15.15s", sc_name
);
1996 framework_name
= (char *)0;
1998 if (columns
> MAXCOLS
|| wideflag
) {
2000 sprintf(&buf
[clen
], " D=0x%8.8x", dio
->blkno
);
2005 sprintf(&buf
[clen
], " [%3d] ", dio
->io_errno
);
2007 sprintf(&buf
[clen
], " B=0x%-6x /dev/%s", dio
->iosize
, find_disk_name(dio
->dev
));
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
], " ");
2019 if (has_ret
== 2 || has_ret
== 6)
2020 framework_name
= lookup_name(retval
);
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
);
2037 sprintf(&buf
[clen
], " ");
2044 Calculate space available to print pathname
2046 if (columns
> MAXCOLS
|| wideflag
)
2047 clen
= columns
- (clen
+ 13 + 20);
2049 clen
= columns
- (clen
+ 13 + 12);
2051 if ((type
>> 24) != FILEMGR_CLASS
&& !nopadding
)
2055 sprintf(&buf
[0], " %s ", framework_name
);
2057 sprintf(&buf
[0], " %s ", pathname
);
2063 Add null padding if column length
2064 is wider than the pathname length.
2066 memset(&buf
[len
], ' ', clen
- len
);
2070 else if (clen
== len
)
2074 else if ((clen
> 0) && (clen
< len
))
2076 /* This prints the tail end of the pathname */
2077 buf
[len
-clen
] = ' ';
2078 printf(&buf
[len
- clen
]);
2081 usecs
= (unsigned long)((now
- stime
) / divisor
);
2082 secs
= usecs
/ 1000000;
2083 usecs
-= secs
* 1000000;
2085 if ((type
>> 24) != FILEMGR_CLASS
&& !nopadding
)
2088 printf(" %2ld.%06ld", (unsigned long)secs
, (unsigned long)usecs
);
2095 if (columns
> MAXCOLS
|| wideflag
)
2096 printf(" %-20.20s", command_name
);
2098 printf(" %-12.12s", command_name
);
2112 This flag is turned off when calling
2113 quit() due to a set_remove() failure.
2115 if (set_remove_flag
)
2118 printf("fs_usage: ");
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
;
2135 extern void MKGetTimeBaseInfo(unsigned int *, unsigned int *, unsigned int *, unsigned int *, unsigned int *);
2137 MKGetTimeBaseInfo (&delta
, &abs_to_ns_num
, &abs_to_ns_denom
,
2138 &proc_to_abs_num
, &proc_to_abs_denom
);
2140 divisor
= ((double)abs_to_ns_denom
/ (double)abs_to_ns_num
) * 1000;
2144 void read_command_map()
2153 total_threads
= bufinfo
.nkdthreads
;
2154 size
= bufinfo
.nkdthreads
* sizeof(kd_threadmap
);
2158 if (mapptr
= (kd_threadmap
*) malloc(size
))
2159 bzero (mapptr
, size
);
2164 /* Now read the threadmap */
2166 mib
[1] = KERN_KDEBUG
;
2167 mib
[2] = KERN_KDTHRMAP
;
2170 mib
[5] = 0; /* no flags */
2171 if (sysctl(mib
, 3, mapptr
, &size
, NULL
, 0) < 0)
2173 /* This is not fatal -- just means I cant map command strings */
2180 void create_map_entry(int thread
, char *command
)
2188 for (i
= 0, map
= 0; !map
&& i
< total_threads
; i
++)
2190 if (mapptr
[i
].thread
== thread
)
2191 map
= &mapptr
[i
]; /* Reuse this entry, the thread has been reassigned */
2194 if (!map
) /* look for invalid entries that I can reuse*/
2196 for (i
= 0, map
= 0; !map
&& i
< total_threads
; i
++)
2198 if (mapptr
[i
].valid
== 0 )
2199 map
= &mapptr
[i
]; /* Reuse this invalid entry */
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.
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
];
2218 map
->thread
= thread
;
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.
2224 (void)strncpy (map
->command
, command
, MAXCOMLEN
);
2225 map
->command
[MAXCOMLEN
] = '\0';
2229 kd_threadmap
*find_thread_map(int thread
)
2235 return((kd_threadmap
*)0);
2237 for (i
= 0; i
< total_threads
; i
++)
2240 if (map
->valid
&& (map
->thread
== thread
))
2245 return ((kd_threadmap
*)0);
2250 kill_thread_map(int thread
)
2254 if (map
= find_thread_map(thread
)) {
2257 map
->command
[0] = '\0';
2269 ret
= (int)strtol(str
, &cp
, 10);
2270 if (cp
== str
|| *cp
) {
2271 /* Assume this is a command string and find matching pids */
2275 for (i
=0; i
< kp_nentries
&& num_of_pids
< (MAX_PIDS
- 1); i
++) {
2276 if(kp_buffer
[i
].kp_proc
.p_stat
== 0)
2279 if(!strcmp(str
, kp_buffer
[i
].kp_proc
.p_comm
))
2280 pids
[num_of_pids
++] = kp_buffer
[i
].kp_proc
.p_pid
;
2284 else if (num_of_pids
< (MAX_PIDS
- 1))
2285 pids
[num_of_pids
++] = ret
;
2292 char *lookup_name(unsigned long addr
)
2295 register int start
, last
;
2298 if (numFrameworks
== 0 || addr
< frameworkInfo
[0].address
|| addr
> frameworkInfo
[numFrameworks
].address
)
2302 last
= numFrameworks
;
2304 for (i
= numFrameworks
/ 2; i
>= 0 && i
< numFrameworks
; ) {
2306 if (addr
>= frameworkInfo
[i
].address
&& addr
< frameworkInfo
[i
+1].address
)
2307 return(frameworkInfo
[i
].name
);
2309 if (addr
>= frameworkInfo
[i
].address
) {
2311 i
= start
+ ((last
- i
) / 2);
2314 i
= start
+ ((i
- start
) / 2);
2322 * Comparison routines for sorting
2324 static int compareFrameworkAddress(const void *aa
, const void *bb
)
2326 LibraryInfo
*a
= (LibraryInfo
*)aa
;
2327 LibraryInfo
*b
= (LibraryInfo
*)bb
;
2329 if (a
->address
< b
->address
) return -1;
2330 if (a
->address
== b
->address
) return 0;
2335 int scanline(char *inputstring
,char **argv
)
2338 char **ap
= argv
, *p
, *val
;
2340 for (p
= inputstring
; p
!= NULL
; )
2342 while ((val
= strsep(&p
, " \t")) != NULL
&& *val
== '\0');
2351 int ReadSegAddrTable()
2356 unsigned long frameworkAddress
, frameworkDataAddress
, previousFrameworkAddress
;
2357 char frameworkName
[256];
2360 char *substring
,*ptr
;
2365 bzero(buf
, sizeof(buf
));
2366 bzero(tokens
, sizeof(tokens
));
2370 if ((fd
= fopen(seg_addr_table
, "r")) == 0)
2374 fgets(buf
, 1023, fd
);
2379 frameworkName
[0] = 0;
2380 previousFrameworkAddress
= 0;
2382 while (fgets(buf
, 1023, fd
) && numFrameworks
< (MAXINDEX
- 2))
2387 buf
[strlen(buf
)-1] = 0;
2389 if (strncmp(buf
, "# dyld:", 7) == 0) {
2391 * the next line in the file will contain info about dyld
2397 * This is a split library line: parse it into 3 tokens
2399 ntokens
= scanline(buf
, tokens
);
2404 frameworkAddress
= strtoul(tokens
[0], 0, 16);
2405 frameworkDataAddress
= strtoul(tokens
[1], 0, 16);
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
2413 frameworkInfo
[numFrameworks
].address
= frameworkAddress
;
2414 frameworkInfo
[numFrameworks
+1].address
= frameworkAddress
+ frameworkDataAddress
;
2416 frameworkInfo
[numFrameworks
].name
= (char *)"dylib";
2417 frameworkInfo
[numFrameworks
+1].name
= (char *)0;
2426 * Make sure that we have 2 addresses and a path
2428 if (!frameworkAddress
)
2430 if (!frameworkDataAddress
)
2432 if (*tokens
[2] != '/')
2434 if (frameworkAddress
== previousFrameworkAddress
)
2436 previousFrameworkAddress
= frameworkAddress
;
2439 * Extract lib name from path name
2441 if (substring
= strrchr(tokens
[2], '.'))
2444 * There is a ".": name is whatever is between the "/" around the "."
2446 while ( *substring
!= '/') { /* find "/" before "." */
2450 strcpy(frameworkName
, substring
); /* copy path from "/" */
2451 substring
= frameworkName
;
2453 while ( *substring
!= '/' && *substring
) /* find "/" after "." and stop string there */
2460 * No ".": take segment after last "/"
2468 substring
= ptr
+ 1;
2471 strcpy(frameworkName
, substring
);
2473 frameworkInfo
[numFrameworks
].address
= frameworkAddress
;
2474 frameworkInfo
[numFrameworks
+1].address
= frameworkDataAddress
;
2476 frameworkInfo
[numFrameworks
].name
= (char *)malloc(strlen(frameworkName
) + 1);
2477 strcpy(frameworkInfo
[numFrameworks
].name
, frameworkName
);
2478 frameworkInfo
[numFrameworks
+1].name
= frameworkInfo
[numFrameworks
].name
;
2483 frameworkInfo
[numFrameworks
].address
= frameworkInfo
[numFrameworks
- 1].address
+ 0x800000;
2484 frameworkInfo
[numFrameworks
].name
= (char *)0;
2488 qsort(frameworkInfo
, numFrameworks
, sizeof(LibraryInfo
), compareFrameworkAddress
);
2494 struct diskio
*insert_diskio(int type
, int bp
, int dev
, int blkno
, int io_size
, int thread
, double curtime
)
2496 register struct diskio
*dio
;
2497 register kd_threadmap
*map
;
2499 if (dio
= free_diskios
)
2500 free_diskios
= dio
->next
;
2502 if ((dio
= (struct diskio
*)malloc(sizeof(struct diskio
))) == NULL
)
2511 dio
->iosize
= io_size
;
2512 dio
->issued_time
= curtime
;
2513 dio
->issuing_thread
= thread
;
2515 if (map
= find_thread_map(thread
))
2516 strcpy(dio
->issuing_command
, map
->command
);
2518 strcpy(dio
->issuing_command
, "");
2520 dio
->next
= busy_diskios
;
2522 dio
->next
->prev
= dio
;
2529 struct diskio
*complete_diskio(int bp
, int io_errno
, int resid
, int thread
, double curtime
)
2531 register struct diskio
*dio
;
2533 for (dio
= busy_diskios
; dio
; dio
= dio
->next
) {
2534 if (dio
->bp
== bp
) {
2536 if (dio
== busy_diskios
) {
2537 if (busy_diskios
= dio
->next
)
2538 dio
->next
->prev
= NULL
;
2541 dio
->next
->prev
= dio
->prev
;
2542 dio
->prev
->next
= dio
->next
;
2544 dio
->iosize
-= resid
;
2545 dio
->io_errno
= io_errno
;
2546 dio
->completed_time
= curtime
;
2547 dio
->completion_thread
= thread
;
2552 return ((struct diskio
*)0);
2556 void free_diskio(struct diskio
*dio
)
2558 dio
->next
= free_diskios
;
2563 void print_diskio(struct diskio
*dio
)
2568 switch (dio
->type
) {
2589 p
= " RdMeta[async]";
2592 p
= " WrMeta[async]";
2595 p
= " RdData[async]";
2598 p
= " WrData[async]";
2604 p
= " PgOut[async]";
2608 format_print(NULL
, p
, dio
->issuing_thread
, dio
->type
, 0, 0, 0, 7, dio
->completed_time
, dio
->issued_time
, 1, "", dio
);
2617 struct diskrec
*dnp
;
2620 if ((dirp
= opendir("/dev")) == NULL
)
2623 while ((dir
= readdir(dirp
)) != NULL
) {
2624 char nbuf
[MAXPATHLEN
];
2626 if (dir
->d_namlen
< 5 || strncmp("disk", dir
->d_name
, 4))
2628 sprintf(nbuf
, "%s/%s", "/dev", dir
->d_name
);
2630 if (stat(nbuf
, &st
) < 0)
2633 if ((dnp
= (struct diskrec
*)malloc(sizeof(struct diskrec
))) == NULL
)
2636 if ((dnp
->diskname
= (char *)malloc(dir
->d_namlen
+ 1)) == NULL
) {
2640 strncpy(dnp
->diskname
, dir
->d_name
, dir
->d_namlen
);
2641 dnp
->diskname
[dir
->d_namlen
] = 0;
2642 dnp
->dev
= st
.st_rdev
;
2644 dnp
->next
= disk_list
;
2647 (void) closedir(dirp
);
2651 char *find_disk_name(int dev
)
2653 struct diskrec
*dnp
;
2658 for (dnp
= disk_list
; dnp
; dnp
= dnp
->next
) {
2659 if (dnp
->dev
== dev
)
2660 return (dnp
->diskname
);
2662 return ("NOTFOUND");