]> git.saurik.com Git - apple/system_cmds.git/blame_incremental - fs_usage.tproj/fs_usage.c
system_cmds-643.1.1.tar.gz
[apple/system_cmds.git] / fs_usage.tproj / fs_usage.c
... / ...
CommitLineData
1/*
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7 * Reserved. This file contains Original Code and/or Modifications of
8 * Original Code as defined in and that are subject to the Apple Public
9 * Source License Version 1.0 (the 'License'). You may not use this file
10 * except in compliance with the License. Please obtain a copy of the
11 * License at http://www.apple.com/publicsource and read it before using
12 * this file.
13 *
14 * The Original Code and all software distributed under the License are
15 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
19 * License for the specific language governing rights and limitations
20 * under the License."
21 *
22 * @APPLE_LICENSE_HEADER_END@
23 */
24
25/*
26cc -I/System/Library/Frameworks/System.framework/Versions/B/PrivateHeaders -DPRIVATE -D__APPLE_PRIVATE -arch x86_64 -arch i386 -O -lutil -o fs_usage fs_usage.c
27*/
28
29#include <stdlib.h>
30#include <stdio.h>
31#include <signal.h>
32#include <strings.h>
33#include <nlist.h>
34#include <fcntl.h>
35#include <aio.h>
36#include <string.h>
37#include <dirent.h>
38#include <libc.h>
39#include <termios.h>
40#include <errno.h>
41#include <err.h>
42#include <libutil.h>
43
44#include <sys/types.h>
45#include <sys/param.h>
46#include <sys/time.h>
47#include <sys/ioctl.h>
48#include <sys/socket.h>
49#include <sys/mman.h>
50#include <sys/sysctl.h>
51#include <sys/disk.h>
52#include <sys/file.h>
53
54#ifndef KERNEL_PRIVATE
55#define KERNEL_PRIVATE
56#include <sys/kdebug.h>
57#undef KERNEL_PRIVATE
58#else
59#include <sys/kdebug.h>
60#endif /*KERNEL_PRIVATE*/
61
62#import <mach/clock_types.h>
63#import <mach/mach_time.h>
64
65
66
67#define F_OPENFROM 56 /* SPI: open a file relative to fd (must be a dir) */
68#define F_UNLINKFROM 57 /* SPI: open a file relative to fd (must be a dir) */
69#define F_CHECK_OPENEVT 58 /* SPI: if a process is marked OPENEVT, or in O_EVTONLY on opens of this vnode */
70
71
72#ifndef RAW_VERSION1
73typedef struct {
74 int version_no;
75 int thread_count;
76 uint64_t TOD_secs;
77 uint32_t TOD_usecs;
78} RAW_header;
79
80#define RAW_VERSION0 0x55aa0000
81#define RAW_VERSION1 0x55aa0101
82#endif
83
84
85#define MAXINDEX 2048
86
87typedef struct LibraryRange {
88 uint64_t b_address;
89 uint64_t e_address;
90} LibraryRange;
91
92LibraryRange framework32;
93LibraryRange framework64;
94
95
96#define TEXT_R 0
97#define DATA_R 1
98#define OBJC_R 2
99#define IMPORT_R 3
100#define UNICODE_R 4
101#define IMAGE_R 5
102#define LINKEDIT_R 6
103
104
105char *frameworkType[] = {
106 "<TEXT> ",
107 "<DATA> ",
108 "<OBJC> ",
109 "<IMPORT> ",
110 "<UNICODE> ",
111 "<IMAGE> ",
112 "<LINKEDIT>",
113};
114
115
116typedef struct LibraryInfo {
117 uint64_t b_address;
118 uint64_t e_address;
119 int r_type;
120 char *name;
121} LibraryInfo;
122
123LibraryInfo frameworkInfo[MAXINDEX];
124int numFrameworks = 0;
125
126
127/*
128 * MAXCOLS controls when extra data kicks in.
129 * MAX_WIDE_MODE_COLS controls -w mode to get even wider data in path.
130 * If NUMPARMS changes to match the kernel, it will automatically
131 * get reflected in the -w mode output.
132 */
133#define NUMPARMS 23
134#define PATHLENGTH (NUMPARMS*sizeof(uintptr_t))
135
136#define MAXCOLS 132
137#define MAX_WIDE_MODE_COLS (PATHLENGTH + 80)
138#define MAXWIDTH MAX_WIDE_MODE_COLS + 64
139
140#define MAX_PATHNAMES 3
141#define MAX_SCALL_PATHNAMES 2
142
143typedef struct th_info *th_info_t;
144
145struct lookup {
146 uintptr_t pathname[NUMPARMS + 1]; /* add room for null terminator */
147};
148
149struct th_info {
150 th_info_t next;
151 uintptr_t thread;
152 uintptr_t child_thread;
153
154 int in_filemgr;
155 int in_hfs_update;
156 int pid;
157 int type;
158 int arg1;
159 int arg2;
160 int arg3;
161 int arg4;
162 int arg5;
163 int arg6;
164 int arg7;
165 int arg8;
166 int waited;
167 double stime;
168 uint64_t vnodeid;
169 char *nameptr;
170 uintptr_t *pathptr;
171 int pn_scall_index;
172 int pn_work_index;
173 struct lookup lookups[MAX_PATHNAMES];
174};
175
176
177typedef struct threadmap * threadmap_t;
178
179struct threadmap {
180 threadmap_t tm_next;
181
182 uintptr_t tm_thread;
183 unsigned int tm_setsize; /* this is a bit count */
184 unsigned long *tm_setptr; /* file descripter bitmap */
185 char tm_command[MAXCOMLEN + 1];
186};
187
188
189typedef struct vnode_info * vnode_info_t;
190
191struct vnode_info {
192 vnode_info_t vn_next;
193 uint64_t vn_id;
194 uintptr_t vn_pathname[NUMPARMS + 1];
195};
196
197typedef struct meta_info * meta_info_t;
198
199struct meta_info {
200 meta_info_t m_next;
201 uint64_t m_blkno;
202 char *m_nameptr;
203};
204
205#define HASH_SIZE 1024
206#define HASH_MASK (HASH_SIZE - 1)
207
208th_info_t th_info_hash[HASH_SIZE];
209th_info_t th_info_freelist;
210
211threadmap_t threadmap_hash[HASH_SIZE];
212threadmap_t threadmap_freelist;
213
214
215#define VN_HASH_SHIFT 3
216#define VN_HASH_SIZE 16384
217#define VN_HASH_MASK (VN_HASH_SIZE - 1)
218
219vnode_info_t vn_info_hash[VN_HASH_SIZE];
220meta_info_t m_info_hash[VN_HASH_SIZE];
221
222
223int filemgr_in_progress = 0;
224int need_new_map = 1;
225int bias_secs = 0;
226long last_time;
227int wideflag = 0;
228int columns = 0;
229
230int one_good_pid = 0; /* Used to fail gracefully when bad pids given */
231int select_pid_mode = 0; /* Flag set indicates that output is restricted
232 to selected pids or commands */
233
234char *arguments = 0;
235int argmax = 0;
236
237
238#define USLEEP_MIN 1
239#define USLEEP_BEHIND 2
240#define USLEEP_MAX 32
241int usleep_ms = USLEEP_MIN;
242
243/*
244 * Network only or filesystem only output filter
245 * Default of zero means report all activity - no filtering
246 */
247#define FILESYS_FILTER 0x01
248#define NETWORK_FILTER 0x02
249#define EXEC_FILTER 0x08
250#define PATHNAME_FILTER 0x10
251#define DISKIO_FILTER 0x20
252#define DEFAULT_DO_NOT_FILTER 0x00
253
254int filter_mode = DEFAULT_DO_NOT_FILTER;
255
256boolean_t show_cachehits = FALSE;
257
258#define NFS_DEV -1
259#define CS_DEV -2
260
261struct diskrec {
262 struct diskrec *next;
263 char *diskname;
264 int dev;
265};
266
267struct diskio {
268 struct diskio *next;
269 struct diskio *prev;
270 int type;
271 int bp;
272 int dev;
273 int blkno;
274 int iosize;
275 int io_errno;
276 int is_meta;
277 uint64_t vnodeid;
278 uintptr_t issuing_thread;
279 uintptr_t completion_thread;
280 char issuing_command[MAXCOMLEN + 1];
281 double issued_time;
282 double completed_time;
283 uint32_t bc_info;
284};
285
286struct diskrec *disk_list = NULL;
287struct diskio *free_diskios = NULL;
288struct diskio *busy_diskios = NULL;
289
290
291struct diskio *insert_diskio();
292struct diskio *find_diskio(int);
293struct diskio *complete_diskio();
294void free_diskio();
295void print_diskio();
296
297int check_filter_mode(struct th_info *, int, int, int, char *);
298void format_print(struct th_info *, char *, uintptr_t, int, uintptr_t, uintptr_t, uintptr_t, uintptr_t, int, double, double, int, char *, struct diskio *);
299void enter_event_now(uintptr_t, int, kd_buf *, char *, double);
300void enter_event(uintptr_t, int, kd_buf *, char *, double);
301void exit_event(char *, uintptr_t, int, uintptr_t, uintptr_t, uintptr_t, uintptr_t, int, double);
302void extend_syscall(uintptr_t, int, kd_buf *);
303
304char *generate_cs_disk_name(int, char *s);
305char *find_disk_name(int);
306void cache_disk_names();
307void recache_disk_names();
308
309void lookup_name(uint64_t user_addr, char **type, char **name);
310int ReadSharedCacheMap(const char *, LibraryRange *, char *);
311void SortFrameworkAddresses();
312
313void fs_usage_fd_set(uintptr_t, unsigned int);
314int fs_usage_fd_isset(uintptr_t, unsigned int);
315void fs_usage_fd_clear(uintptr_t, unsigned int);
316
317void init_arguments_buffer();
318int get_real_command_name(int, char *, int);
319
320void delete_all_events();
321void delete_event(th_info_t);
322th_info_t add_event(uintptr_t, int);
323th_info_t find_event(uintptr_t, int);
324void mark_thread_waited(uintptr_t);
325
326void read_command_map();
327void delete_all_map_entries();
328void create_map_entry(uintptr_t, int, char *);
329void delete_map_entry(uintptr_t);
330threadmap_t find_map_entry(uintptr_t);
331
332char *add_vnode_name(uint64_t, char *);
333char *find_vnode_name(uint64_t);
334char *find_meta_name(uint64_t);
335void add_meta_name(uint64_t, char *);
336
337void getdivisor();
338void argtopid();
339void set_remove();
340void set_pidcheck();
341void set_pidexclude();
342int quit();
343
344
345#define CLASS_MASK 0xff000000
346#define CSC_MASK 0xffff0000
347#define BSC_INDEX(type) ((type >> 2) & 0x3fff)
348
349
350#define TRACE_DATA_NEWTHREAD 0x07000004
351#define TRACE_DATA_EXEC 0x07000008
352#define TRACE_STRING_NEWTHREAD 0x07010004
353#define TRACE_STRING_EXEC 0x07010008
354
355#define MACH_vmfault 0x01300008
356#define MACH_pageout 0x01300004
357#define MACH_sched 0x01400000
358#define MACH_stkhandoff 0x01400008
359#define MACH_idle 0x01400024
360#define VFS_LOOKUP 0x03010090
361#define VFS_ALIAS_VP 0x03010094
362
363#define BSC_thread_terminate 0x040c05a4
364
365#define HFS_update 0x3018000
366#define HFS_modify_block_end 0x3018004
367
368#define Throttled 0x3010184
369#define SPEC_ioctl 0x3060000
370#define SPEC_unmap_info 0x3060004
371#define proc_exit 0x4010004
372
373#define BC_IO_HIT 0x03070010
374#define BC_IO_HIT_STALLED 0x03070020
375#define BC_IO_MISS 0x03070040
376#define BC_IO_MISS_CUT_THROUGH 0x03070080
377#define BC_PLAYBACK_IO 0x03070100
378#define BC_STR(s) ( \
379 (s == BC_IO_HIT) ? "HIT" : \
380 (s == BC_IO_HIT_STALLED) ? "STALL" : \
381 (s == BC_IO_MISS) ? "MISS" : \
382 (s == BC_IO_MISS_CUT_THROUGH) ? "CUT" : \
383 (s == BC_PLAYBACK_IO) ? "PLBK" : \
384 (s == 0x0) ? "NONE" : "UNKN" )
385
386#ifndef DKIO_NOCACHE
387#define DKIO_NOCACHE 0x80
388#endif
389
390#define P_DISKIO_READ (DKIO_READ << 2)
391#define P_DISKIO_ASYNC (DKIO_ASYNC << 2)
392#define P_DISKIO_META (DKIO_META << 2)
393#define P_DISKIO_PAGING (DKIO_PAGING << 2)
394#define P_DISKIO_THROTTLE (DKIO_THROTTLE << 2)
395#define P_DISKIO_PASSIVE (DKIO_PASSIVE << 2)
396#define P_DISKIO_NOCACHE (DKIO_NOCACHE << 2)
397#define P_DISKIO_TIER_MASK (DKIO_TIER_MASK << 2)
398#define P_DISKIO_TIER_SHIFT (DKIO_TIER_SHIFT + 2)
399
400#define P_DISKIO (FSDBG_CODE(DBG_DKRW, 0))
401#define P_DISKIO_DONE (P_DISKIO | (DKIO_DONE << 2))
402#define P_DISKIO_TYPE (P_DISKIO | P_DISKIO_READ | P_DISKIO_META | P_DISKIO_PAGING)
403#define P_DISKIO_MASK (CSC_MASK | 0x4)
404
405#define P_WrData (P_DISKIO)
406#define P_RdData (P_DISKIO | P_DISKIO_READ)
407#define P_WrMeta (P_DISKIO | P_DISKIO_META)
408#define P_RdMeta (P_DISKIO | P_DISKIO_META | P_DISKIO_READ)
409#define P_PgOut (P_DISKIO | P_DISKIO_PAGING)
410#define P_PgIn (P_DISKIO | P_DISKIO_PAGING | P_DISKIO_READ)
411
412#define P_CS_Class 0x0a000000 // DBG_CORESTORAGE
413#define P_CS_Type_Mask 0xfffffff0
414#define P_CS_IO_Done 0x00000004
415
416#define P_CS_ReadChunk 0x0a000200 // chopped up request
417#define P_CS_WriteChunk 0x0a000210
418#define P_CS_MetaRead 0x0a000300 // meta data
419#define P_CS_MetaWrite 0x0a000310
420#define P_CS_TransformRead 0x0a000500 // background transform
421#define P_CS_TransformWrite 0x0a000510
422#define P_CS_MigrationRead 0x0a000600 // composite disk block migration
423#define P_CS_MigrationWrite 0x0a000610
424#define P_CS_SYNC_DISK 0x0a010000
425
426#define MSC_map_fd 0x010c00ac
427
428#define BSC_BASE 0x040C0000
429#define MSC_BASE 0x010C0000
430
431// Network related codes
432#define BSC_recvmsg 0x040C006C
433#define BSC_sendmsg 0x040C0070
434#define BSC_recvfrom 0x040C0074
435#define BSC_accept 0x040C0078
436#define BSC_select 0x040C0174
437#define BSC_socket 0x040C0184
438#define BSC_connect 0x040C0188
439#define BSC_bind 0x040C01A0
440#define BSC_listen 0x040C01A8
441#define BSC_sendto 0x040C0214
442#define BSC_socketpair 0x040C021C
443#define BSC_recvmsg_nocancel 0x040c0644
444#define BSC_sendmsg_nocancel 0x040c0648
445#define BSC_recvfrom_nocancel 0x040c064c
446#define BSC_accept_nocancel 0x040c0650
447#define BSC_connect_nocancel 0x040c0664
448#define BSC_sendto_nocancel 0x040c0674
449
450#define BSC_exit 0x040C0004
451#define BSC_read 0x040C000C
452#define BSC_write 0x040C0010
453#define BSC_open 0x040C0014
454#define BSC_close 0x040C0018
455#define BSC_link 0x040C0024
456#define BSC_unlink 0x040C0028
457#define BSC_chdir 0x040c0030
458#define BSC_fchdir 0x040c0034
459#define BSC_mknod 0x040C0038
460#define BSC_chmod 0x040C003C
461#define BSC_chown 0x040C0040
462#define BSC_getfsstat 0x040C0048
463#define BSC_access 0x040C0084
464#define BSC_chflags 0x040C0088
465#define BSC_fchflags 0x040C008C
466#define BSC_sync 0x040C0090
467#define BSC_dup 0x040C00A4
468#define BSC_ioctl 0x040C00D8
469#define BSC_revoke 0x040C00E0
470#define BSC_symlink 0x040C00E4
471#define BSC_readlink 0x040C00E8
472#define BSC_execve 0x040C00EC
473#define BSC_umask 0x040C00F0
474#define BSC_chroot 0x040C00F4
475#define BSC_msync 0x040C0104
476#define BSC_dup2 0x040C0168
477#define BSC_fcntl 0x040C0170
478#define BSC_fsync 0x040C017C
479#define BSC_readv 0x040C01E0
480#define BSC_writev 0x040C01E4
481#define BSC_fchown 0x040C01EC
482#define BSC_fchmod 0x040C01F0
483#define BSC_rename 0x040C0200
484#define BSC_flock 0x040C020C
485#define BSC_mkfifo 0x040C0210
486#define BSC_mkdir 0x040C0220
487#define BSC_rmdir 0x040C0224
488#define BSC_utimes 0x040C0228
489#define BSC_futimes 0x040C022C
490#define BSC_pread 0x040C0264
491#define BSC_pwrite 0x040C0268
492#define BSC_statfs 0x040C0274
493#define BSC_fstatfs 0x040C0278
494#define BSC_unmount 0x040C027C
495#define BSC_mount 0x040C029C
496#define BSC_fdatasync 0x040C02EC
497#define BSC_stat 0x040C02F0
498#define BSC_fstat 0x040C02F4
499#define BSC_lstat 0x040C02F8
500#define BSC_pathconf 0x040C02FC
501#define BSC_fpathconf 0x040C0300
502#define BSC_getdirentries 0x040C0310
503#define BSC_mmap 0x040c0314
504#define BSC_lseek 0x040c031c
505#define BSC_truncate 0x040C0320
506#define BSC_ftruncate 0x040C0324
507#define BSC_undelete 0x040C0334
508#define BSC_open_dprotected_np 0x040C0360
509#define BSC_getattrlist 0x040C0370
510#define BSC_setattrlist 0x040C0374
511#define BSC_getdirentriesattr 0x040C0378
512#define BSC_exchangedata 0x040C037C
513#define BSC_checkuseraccess 0x040C0380
514#define BSC_searchfs 0x040C0384
515#define BSC_delete 0x040C0388
516#define BSC_copyfile 0x040C038C
517#define BSC_fgetattrlist 0x040C0390
518#define BSC_fsetattrlist 0x040C0394
519#define BSC_getxattr 0x040C03A8
520#define BSC_fgetxattr 0x040C03AC
521#define BSC_setxattr 0x040C03B0
522#define BSC_fsetxattr 0x040C03B4
523#define BSC_removexattr 0x040C03B8
524#define BSC_fremovexattr 0x040C03BC
525#define BSC_listxattr 0x040C03C0
526#define BSC_flistxattr 0x040C03C4
527#define BSC_fsctl 0x040C03C8
528#define BSC_posix_spawn 0x040C03D0
529#define BSC_ffsctl 0x040C03D4
530#define BSC_open_extended 0x040C0454
531#define BSC_umask_extended 0x040C0458
532#define BSC_stat_extended 0x040C045C
533#define BSC_lstat_extended 0x040C0460
534#define BSC_fstat_extended 0x040C0464
535#define BSC_chmod_extended 0x040C0468
536#define BSC_fchmod_extended 0x040C046C
537#define BSC_access_extended 0x040C0470
538#define BSC_mkfifo_extended 0x040C048C
539#define BSC_mkdir_extended 0x040C0490
540#define BSC_aio_fsync 0x040C04E4
541#define BSC_aio_return 0x040C04E8
542#define BSC_aio_suspend 0x040C04EC
543#define BSC_aio_cancel 0x040C04F0
544#define BSC_aio_error 0x040C04F4
545#define BSC_aio_read 0x040C04F8
546#define BSC_aio_write 0x040C04FC
547#define BSC_lio_listio 0x040C0500
548#define BSC_sendfile 0x040C0544
549#define BSC_stat64 0x040C0548
550#define BSC_fstat64 0x040C054C
551#define BSC_lstat64 0x040C0550
552#define BSC_stat64_extended 0x040C0554
553#define BSC_lstat64_extended 0x040C0558
554#define BSC_fstat64_extended 0x040C055C
555#define BSC_getdirentries64 0x040C0560
556#define BSC_statfs64 0x040C0564
557#define BSC_fstatfs64 0x040C0568
558#define BSC_getfsstat64 0x040C056C
559#define BSC_pthread_chdir 0x040C0570
560#define BSC_pthread_fchdir 0x040C0574
561#define BSC_lchown 0x040C05B0
562
563#define BSC_read_nocancel 0x040c0630
564#define BSC_write_nocancel 0x040c0634
565#define BSC_open_nocancel 0x040c0638
566#define BSC_close_nocancel 0x040c063c
567#define BSC_msync_nocancel 0x040c0654
568#define BSC_fcntl_nocancel 0x040c0658
569#define BSC_select_nocancel 0x040c065c
570#define BSC_fsync_nocancel 0x040c0660
571#define BSC_readv_nocancel 0x040c066c
572#define BSC_writev_nocancel 0x040c0670
573#define BSC_pread_nocancel 0x040c0678
574#define BSC_pwrite_nocancel 0x040c067c
575#define BSC_aio_suspend_nocancel 0x40c0694
576#define BSC_guarded_open_np 0x040c06e4
577#define BSC_guarded_close_np 0x040c06e8
578
579#define BSC_fsgetpath 0x040c06ac
580
581#define BSC_getattrlistbulk 0x040c0734
582
583#define BSC_openat 0x040c073c
584#define BSC_openat_nocancel 0x040c0740
585#define BSC_renameat 0x040c0744
586#define BSC_chmodat 0x040c074c
587#define BSC_chownat 0x040c0750
588#define BSC_fstatat 0x040c0754
589#define BSC_fstatat64 0x040c0758
590#define BSC_linkat 0x040c075c
591#define BSC_unlinkat 0x040c0760
592#define BSC_readlinkat 0x040c0764
593#define BSC_symlinkat 0x040c0768
594#define BSC_mkdirat 0x040c076c
595#define BSC_getattrlistat 0x040c0770
596
597#define BSC_msync_extended 0x040e0104
598#define BSC_pread_extended 0x040e0264
599#define BSC_pwrite_extended 0x040e0268
600#define BSC_mmap_extended 0x040e0314
601#define BSC_mmap_extended2 0x040f0314
602
603// Carbon File Manager support
604#define FILEMGR_PBGETCATALOGINFO 0x1e000020
605#define FILEMGR_PBGETCATALOGINFOBULK 0x1e000024
606#define FILEMGR_PBCREATEFILEUNICODE 0x1e000028
607#define FILEMGR_PBCREATEDIRECTORYUNICODE 0x1e00002c
608#define FILEMGR_PBCREATEFORK 0x1e000030
609#define FILEMGR_PBDELETEFORK 0x1e000034
610#define FILEMGR_PBITERATEFORK 0x1e000038
611#define FILEMGR_PBOPENFORK 0x1e00003c
612#define FILEMGR_PBREADFORK 0x1e000040
613#define FILEMGR_PBWRITEFORK 0x1e000044
614#define FILEMGR_PBALLOCATEFORK 0x1e000048
615#define FILEMGR_PBDELETEOBJECT 0x1e00004c
616#define FILEMGR_PBEXCHANGEOBJECT 0x1e000050
617#define FILEMGR_PBGETFORKCBINFO 0x1e000054
618#define FILEMGR_PBGETVOLUMEINFO 0x1e000058
619#define FILEMGR_PBMAKEFSREF 0x1e00005c
620#define FILEMGR_PBMAKEFSREFUNICODE 0x1e000060
621#define FILEMGR_PBMOVEOBJECT 0x1e000064
622#define FILEMGR_PBOPENITERATOR 0x1e000068
623#define FILEMGR_PBRENAMEUNICODE 0x1e00006c
624#define FILEMGR_PBSETCATALOGINFO 0x1e000070
625#define FILEMGR_PBSETVOLUMEINFO 0x1e000074
626#define FILEMGR_FSREFMAKEPATH 0x1e000078
627#define FILEMGR_FSPATHMAKEREF 0x1e00007c
628
629#define FILEMGR_PBGETCATINFO 0x1e010000
630#define FILEMGR_PBGETCATINFOLITE 0x1e010004
631#define FILEMGR_PBHGETFINFO 0x1e010008
632#define FILEMGR_PBXGETVOLINFO 0x1e01000c
633#define FILEMGR_PBHCREATE 0x1e010010
634#define FILEMGR_PBHOPENDF 0x1e010014
635#define FILEMGR_PBHOPENRF 0x1e010018
636#define FILEMGR_PBHGETDIRACCESS 0x1e01001c
637#define FILEMGR_PBHSETDIRACCESS 0x1e010020
638#define FILEMGR_PBHMAPID 0x1e010024
639#define FILEMGR_PBHMAPNAME 0x1e010028
640#define FILEMGR_PBCLOSE 0x1e01002c
641#define FILEMGR_PBFLUSHFILE 0x1e010030
642#define FILEMGR_PBGETEOF 0x1e010034
643#define FILEMGR_PBSETEOF 0x1e010038
644#define FILEMGR_PBGETFPOS 0x1e01003c
645#define FILEMGR_PBREAD 0x1e010040
646#define FILEMGR_PBWRITE 0x1e010044
647#define FILEMGR_PBGETFCBINFO 0x1e010048
648#define FILEMGR_PBSETFINFO 0x1e01004c
649#define FILEMGR_PBALLOCATE 0x1e010050
650#define FILEMGR_PBALLOCCONTIG 0x1e010054
651#define FILEMGR_PBSETFPOS 0x1e010058
652#define FILEMGR_PBSETCATINFO 0x1e01005c
653#define FILEMGR_PBGETVOLPARMS 0x1e010060
654#define FILEMGR_PBSETVINFO 0x1e010064
655#define FILEMGR_PBMAKEFSSPEC 0x1e010068
656#define FILEMGR_PBHGETVINFO 0x1e01006c
657#define FILEMGR_PBCREATEFILEIDREF 0x1e010070
658#define FILEMGR_PBDELETEFILEIDREF 0x1e010074
659#define FILEMGR_PBRESOLVEFILEIDREF 0x1e010078
660#define FILEMGR_PBFLUSHVOL 0x1e01007c
661#define FILEMGR_PBHRENAME 0x1e010080
662#define FILEMGR_PBCATMOVE 0x1e010084
663#define FILEMGR_PBEXCHANGEFILES 0x1e010088
664#define FILEMGR_PBHDELETE 0x1e01008c
665#define FILEMGR_PBDIRCREATE 0x1e010090
666#define FILEMGR_PBCATSEARCH 0x1e010094
667#define FILEMGR_PBHSETFLOCK 0x1e010098
668#define FILEMGR_PBHRSTFLOCK 0x1e01009c
669#define FILEMGR_PBLOCKRANGE 0x1e0100a0
670#define FILEMGR_PBUNLOCKRANGE 0x1e0100a4
671
672
673#define FILEMGR_CLASS 0x1e
674#define FILEMGR_BASE 0x1e000000
675
676#define FMT_DEFAULT 0
677#define FMT_FD 1
678#define FMT_FD_IO 2
679#define FMT_FD_2 3
680#define FMT_SOCKET 4
681#define FMT_PGIN 5
682#define FMT_PGOUT 6
683#define FMT_CACHEHIT 7
684#define FMT_DISKIO 8
685#define FMT_LSEEK 9
686#define FMT_PREAD 10
687#define FMT_FTRUNC 11
688#define FMT_TRUNC 12
689#define FMT_SELECT 13
690#define FMT_OPEN 14
691#define FMT_AIO_FSYNC 15
692#define FMT_AIO_RETURN 16
693#define FMT_AIO_SUSPEND 17
694#define FMT_AIO_CANCEL 18
695#define FMT_AIO 19
696#define FMT_LIO_LISTIO 20
697#define FMT_MSYNC 21
698#define FMT_FCNTL 22
699#define FMT_ACCESS 23
700#define FMT_CHMOD 24
701#define FMT_FCHMOD 25
702#define FMT_CHMOD_EXT 26
703#define FMT_FCHMOD_EXT 27
704#define FMT_CHFLAGS 28
705#define FMT_FCHFLAGS 29
706#define FMT_IOCTL 30
707#define FMT_MMAP 31
708#define FMT_UMASK 32
709#define FMT_SENDFILE 33
710#define FMT_IOCTL_SYNC 34
711#define FMT_MOUNT 35
712#define FMT_UNMOUNT 36
713#define FMT_DISKIO_CS 37
714#define FMT_SYNC_DISK_CS 38
715#define FMT_IOCTL_UNMAP 39
716#define FMT_UNMAP_INFO 40
717#define FMT_HFS_update 41
718#define FMT_FLOCK 42
719#define FMT_AT 43
720#define FMT_CHMODAT 44
721#define FMT_OPENAT 45
722#define FMT_RENAMEAT 46
723
724#define MAX_BSD_SYSCALL 526
725
726struct bsd_syscall {
727 char *sc_name;
728 int sc_format;
729} bsd_syscalls[MAX_BSD_SYSCALL];
730
731
732int bsd_syscall_types[] = {
733 BSC_recvmsg,
734 BSC_recvmsg_nocancel,
735 BSC_sendmsg,
736 BSC_sendmsg_nocancel,
737 BSC_recvfrom,
738 BSC_recvfrom_nocancel,
739 BSC_accept,
740 BSC_accept_nocancel,
741 BSC_select,
742 BSC_select_nocancel,
743 BSC_socket,
744 BSC_connect,
745 BSC_connect_nocancel,
746 BSC_bind,
747 BSC_listen,
748 BSC_sendto,
749 BSC_sendto_nocancel,
750 BSC_socketpair,
751 BSC_read,
752 BSC_read_nocancel,
753 BSC_write,
754 BSC_write_nocancel,
755 BSC_open,
756 BSC_open_nocancel,
757 BSC_close,
758 BSC_close_nocancel,
759 BSC_link,
760 BSC_unlink,
761 BSC_chdir,
762 BSC_fchdir,
763 BSC_mknod,
764 BSC_chmod,
765 BSC_chown,
766 BSC_access,
767 BSC_chflags,
768 BSC_fchflags,
769 BSC_sync,
770 BSC_dup,
771 BSC_revoke,
772 BSC_symlink,
773 BSC_readlink,
774 BSC_exit,
775 BSC_execve,
776 BSC_posix_spawn,
777 BSC_umask,
778 BSC_chroot,
779 BSC_dup2,
780 BSC_fsync,
781 BSC_fsync_nocancel,
782 BSC_readv,
783 BSC_readv_nocancel,
784 BSC_writev,
785 BSC_writev_nocancel,
786 BSC_fchown,
787 BSC_fchmod,
788 BSC_rename,
789 BSC_mkfifo,
790 BSC_mkdir,
791 BSC_rmdir,
792 BSC_utimes,
793 BSC_futimes,
794 BSC_pread,
795 BSC_pread_nocancel,
796 BSC_pwrite,
797 BSC_pwrite_nocancel,
798 BSC_statfs,
799 BSC_fstatfs,
800 BSC_fdatasync,
801 BSC_stat,
802 BSC_fstat,
803 BSC_lstat,
804 BSC_mount,
805 BSC_unmount,
806 BSC_pathconf,
807 BSC_fpathconf,
808 BSC_getdirentries,
809 BSC_mmap,
810 BSC_lseek,
811 BSC_truncate,
812 BSC_ftruncate,
813 BSC_flock,
814 BSC_undelete,
815 BSC_open_dprotected_np,
816 BSC_getattrlist,
817 BSC_setattrlist,
818 BSC_fgetattrlist,
819 BSC_fsetattrlist,
820 BSC_getdirentriesattr,
821 BSC_exchangedata,
822 BSC_checkuseraccess,
823 BSC_searchfs,
824 BSC_delete,
825 BSC_copyfile,
826 BSC_getxattr,
827 BSC_fgetxattr,
828 BSC_setxattr,
829 BSC_fsetxattr,
830 BSC_removexattr,
831 BSC_fremovexattr,
832 BSC_listxattr,
833 BSC_flistxattr,
834 BSC_fsctl,
835 BSC_ffsctl,
836 BSC_open_extended,
837 BSC_umask_extended,
838 BSC_stat_extended,
839 BSC_lstat_extended,
840 BSC_fstat_extended,
841 BSC_chmod_extended,
842 BSC_fchmod_extended,
843 BSC_access_extended,
844 BSC_mkfifo_extended,
845 BSC_mkdir_extended,
846 BSC_aio_fsync,
847 BSC_aio_return,
848 BSC_aio_suspend,
849 BSC_aio_suspend_nocancel,
850 BSC_aio_cancel,
851 BSC_aio_error,
852 BSC_aio_read,
853 BSC_aio_write,
854 BSC_lio_listio,
855 BSC_lchown,
856 BSC_sendfile,
857 BSC_msync,
858 BSC_msync_nocancel,
859 BSC_fcntl,
860 BSC_fcntl_nocancel,
861 BSC_ioctl,
862 BSC_stat64,
863 BSC_fstat64,
864 BSC_lstat64,
865 BSC_stat64_extended,
866 BSC_lstat64_extended,
867 BSC_fstat64_extended,
868 BSC_getdirentries64,
869 BSC_statfs64,
870 BSC_fstatfs64,
871 BSC_pthread_chdir,
872 BSC_pthread_fchdir,
873 BSC_getfsstat,
874 BSC_getfsstat64,
875 BSC_guarded_open_np,
876 BSC_guarded_close_np,
877 BSC_fsgetpath,
878 BSC_getattrlistbulk,
879 BSC_openat,
880 BSC_openat_nocancel,
881 BSC_renameat,
882 BSC_chmodat,
883 BSC_chownat,
884 BSC_fstatat,
885 BSC_fstatat64,
886 BSC_linkat,
887 BSC_unlinkat,
888 BSC_readlinkat,
889 BSC_symlinkat,
890 BSC_mkdirat,
891 BSC_getattrlistat,
892 0
893};
894
895
896#define MAX_FILEMGR 512
897
898struct filemgr_call {
899 char *fm_name;
900} filemgr_calls[MAX_FILEMGR];
901
902
903int filemgr_call_types[] = {
904 FILEMGR_PBGETCATALOGINFO,
905 FILEMGR_PBGETCATALOGINFOBULK,
906 FILEMGR_PBCREATEFILEUNICODE,
907 FILEMGR_PBCREATEDIRECTORYUNICODE,
908 FILEMGR_PBCREATEFORK,
909 FILEMGR_PBDELETEFORK,
910 FILEMGR_PBITERATEFORK,
911 FILEMGR_PBOPENFORK,
912 FILEMGR_PBREADFORK,
913 FILEMGR_PBWRITEFORK,
914 FILEMGR_PBALLOCATEFORK,
915 FILEMGR_PBDELETEOBJECT,
916 FILEMGR_PBEXCHANGEOBJECT,
917 FILEMGR_PBGETFORKCBINFO,
918 FILEMGR_PBGETVOLUMEINFO,
919 FILEMGR_PBMAKEFSREF,
920 FILEMGR_PBMAKEFSREFUNICODE,
921 FILEMGR_PBMOVEOBJECT,
922 FILEMGR_PBOPENITERATOR,
923 FILEMGR_PBRENAMEUNICODE,
924 FILEMGR_PBSETCATALOGINFO,
925 FILEMGR_PBSETVOLUMEINFO,
926 FILEMGR_FSREFMAKEPATH,
927 FILEMGR_FSPATHMAKEREF,
928
929 FILEMGR_PBGETCATINFO,
930 FILEMGR_PBGETCATINFOLITE,
931 FILEMGR_PBHGETFINFO,
932 FILEMGR_PBXGETVOLINFO,
933 FILEMGR_PBHCREATE,
934 FILEMGR_PBHOPENDF,
935 FILEMGR_PBHOPENRF,
936 FILEMGR_PBHGETDIRACCESS,
937 FILEMGR_PBHSETDIRACCESS,
938 FILEMGR_PBHMAPID,
939 FILEMGR_PBHMAPNAME,
940 FILEMGR_PBCLOSE,
941 FILEMGR_PBFLUSHFILE,
942 FILEMGR_PBGETEOF,
943 FILEMGR_PBSETEOF,
944 FILEMGR_PBGETFPOS,
945 FILEMGR_PBREAD,
946 FILEMGR_PBWRITE,
947 FILEMGR_PBGETFCBINFO,
948 FILEMGR_PBSETFINFO,
949 FILEMGR_PBALLOCATE,
950 FILEMGR_PBALLOCCONTIG,
951 FILEMGR_PBSETFPOS,
952 FILEMGR_PBSETCATINFO,
953 FILEMGR_PBGETVOLPARMS,
954 FILEMGR_PBSETVINFO,
955 FILEMGR_PBMAKEFSSPEC,
956 FILEMGR_PBHGETVINFO,
957 FILEMGR_PBCREATEFILEIDREF,
958 FILEMGR_PBDELETEFILEIDREF,
959 FILEMGR_PBRESOLVEFILEIDREF,
960 FILEMGR_PBFLUSHVOL,
961 FILEMGR_PBHRENAME,
962 FILEMGR_PBCATMOVE,
963 FILEMGR_PBEXCHANGEFILES,
964 FILEMGR_PBHDELETE,
965 FILEMGR_PBDIRCREATE,
966 FILEMGR_PBCATSEARCH,
967 FILEMGR_PBHSETFLOCK,
968 FILEMGR_PBHRSTFLOCK,
969 FILEMGR_PBLOCKRANGE,
970 FILEMGR_PBUNLOCKRANGE,
971 0
972};
973
974
975
976#define MAX_PIDS 256
977int pids[MAX_PIDS];
978
979int num_of_pids = 0;
980int exclude_pids = 0;
981int exclude_default_pids = 1;
982
983
984struct kinfo_proc *kp_buffer = 0;
985int kp_nentries = 0;
986
987#define EVENT_BASE 60000
988
989int num_events = EVENT_BASE;
990
991
992#define DBG_FUNC_ALL (DBG_FUNC_START | DBG_FUNC_END)
993#define DBG_FUNC_MASK 0xfffffffc
994
995double divisor = 0.0; /* Trace divisor converts to microseconds */
996
997int mib[6];
998size_t needed;
999char *my_buffer;
1000
1001kbufinfo_t bufinfo = {0, 0, 0, 0, 0};
1002
1003
1004/* defines for tracking file descriptor state */
1005#define FS_USAGE_FD_SETSIZE 256 /* Initial number of file descriptors per
1006 thread that we will track */
1007
1008#define FS_USAGE_NFDBITS (sizeof (unsigned long) * 8)
1009#define FS_USAGE_NFDBYTES(n) (((n) / FS_USAGE_NFDBITS) * sizeof (unsigned long))
1010
1011int trace_enabled = 0;
1012int set_remove_flag = 1;
1013
1014int BC_flag = 0;
1015
1016char *RAW_file = (char *)0;
1017int RAW_flag = 0;
1018int RAW_fd = 0;
1019
1020uint64_t sample_TOD_secs;
1021uint32_t sample_TOD_usecs;
1022
1023double bias_now = 0.0;
1024double start_time = 0.0;
1025double end_time = 999999999999.9;
1026
1027
1028void set_numbufs();
1029void set_filter();
1030void set_init();
1031void set_enable();
1032void sample_sc();
1033int quit();
1034
1035/*
1036 * signal handlers
1037 */
1038
1039void leave() /* exit under normal conditions -- INT handler */
1040{
1041 int i;
1042 void set_enable();
1043 void set_pidcheck();
1044 void set_pidexclude();
1045 void set_remove();
1046
1047 fflush(0);
1048
1049 set_enable(0);
1050
1051 if (exclude_pids == 0) {
1052 for (i = 0; i < num_of_pids; i++)
1053 set_pidcheck(pids[i], 0);
1054 }
1055 else {
1056 for (i = 0; i < num_of_pids; i++)
1057 set_pidexclude(pids[i], 0);
1058 }
1059 set_remove();
1060
1061 exit(0);
1062}
1063
1064
1065int
1066quit(s)
1067char *s;
1068{
1069 if (trace_enabled)
1070 set_enable(0);
1071
1072 /*
1073 * This flag is turned off when calling
1074 * quit() due to a set_remove() failure.
1075 */
1076 if (set_remove_flag)
1077 set_remove();
1078
1079 fprintf(stderr, "fs_usage: ");
1080 if (s)
1081 fprintf(stderr, "%s", s);
1082
1083 exit(1);
1084}
1085
1086
1087void get_screenwidth()
1088{
1089 struct winsize size;
1090
1091 columns = MAXCOLS;
1092
1093 if (isatty(1)) {
1094 if (ioctl(1, TIOCGWINSZ, &size) != -1) {
1095 columns = size.ws_col;
1096
1097 if (columns > MAXWIDTH)
1098 columns = MAXWIDTH;
1099 }
1100 }
1101}
1102
1103
1104void sigwinch()
1105{
1106 if (!wideflag)
1107 get_screenwidth();
1108}
1109
1110
1111void getdivisor()
1112{
1113 struct mach_timebase_info mti;
1114
1115 mach_timebase_info(&mti);
1116
1117 divisor = ((double)mti.denom / (double)mti.numer) * 1000;
1118}
1119
1120
1121int
1122exit_usage(char *myname) {
1123
1124 fprintf(stderr, "Usage: %s [-e] [-w] [-f mode] [-b] [-t seconds] [-R rawfile [-S start_time] [-E end_time]] [pid | cmd [pid | cmd] ...]\n", myname);
1125 fprintf(stderr, " -e exclude the specified list of pids from the sample\n");
1126 fprintf(stderr, " and exclude fs_usage by default\n");
1127 fprintf(stderr, " -w force wider, detailed, output\n");
1128 fprintf(stderr, " -f output is based on the mode provided\n");
1129 fprintf(stderr, " mode = \"network\" Show network-related events\n");
1130 fprintf(stderr, " mode = \"filesys\" Show filesystem-related events\n");
1131 fprintf(stderr, " mode = \"pathname\" Show only pathname-related events\n");
1132 fprintf(stderr, " mode = \"exec\" Show only exec and spawn events\n");
1133 fprintf(stderr, " mode = \"diskio\" Show only disk I/O events\n");
1134 fprintf(stderr, " mode = \"cachehit\" In addition, show cache hits\n");
1135 fprintf(stderr, " -b annotate disk I/O events with BootCache info (if available)\n");
1136 fprintf(stderr, " -t specifies timeout in seconds (for use in automated tools)\n");
1137 fprintf(stderr, " -R specifies a raw trace file to process\n");
1138 fprintf(stderr, " -S if -R is specified, selects a start point in microseconds\n");
1139 fprintf(stderr, " -E if -R is specified, selects an end point in microseconds\n");
1140 fprintf(stderr, " pid selects process(s) to sample\n");
1141 fprintf(stderr, " cmd selects process(s) matching command string to sample\n");
1142 fprintf(stderr, "\n%s will handle a maximum list of %d pids.\n\n", myname, MAX_PIDS);
1143 fprintf(stderr, "By default (no options) the following processes are excluded from the output:\n");
1144 fprintf(stderr, "fs_usage, Terminal, telnetd, sshd, rlogind, tcsh, csh, sh\n\n");
1145
1146 exit(1);
1147}
1148
1149
1150int filemgr_index(type) {
1151
1152 if (type & 0x10000)
1153 return (((type >> 2) & 0x3fff) + 256);
1154
1155 return (((type >> 2) & 0x3fff));
1156}
1157
1158
1159void init_tables(void)
1160{ int i;
1161 int type;
1162 int code;
1163
1164
1165 for (i = 0; i < MAX_BSD_SYSCALL; i++) {
1166 bsd_syscalls[i].sc_name = NULL;
1167 bsd_syscalls[i].sc_format = FMT_DEFAULT;
1168 }
1169
1170 for (i = 0; i < MAX_FILEMGR; i++) {
1171 filemgr_calls[i].fm_name = NULL;
1172 }
1173
1174 for (i = 0; (type = bsd_syscall_types[i]); i++) {
1175
1176 code = BSC_INDEX(type);
1177
1178 if (code >= MAX_BSD_SYSCALL) {
1179 printf("BSD syscall init (%x): type exceeds table size\n", type);
1180 continue;
1181 }
1182 switch (type) {
1183
1184 case BSC_sendfile:
1185 bsd_syscalls[code].sc_name = "sendfile";
1186 bsd_syscalls[code].sc_format = FMT_FD; /* this should be changed to FMT_SENDFILE */
1187 break; /* once we add an extended info trace event */
1188
1189 case BSC_recvmsg:
1190 case BSC_recvmsg_nocancel:
1191 bsd_syscalls[code].sc_name = "recvmsg";
1192 bsd_syscalls[code].sc_format = FMT_FD_IO;
1193 break;
1194
1195 case BSC_sendmsg:
1196 case BSC_sendmsg_nocancel:
1197 bsd_syscalls[code].sc_name = "sendmsg";
1198 bsd_syscalls[code].sc_format = FMT_FD_IO;
1199 break;
1200
1201 case BSC_recvfrom:
1202 case BSC_recvfrom_nocancel:
1203 bsd_syscalls[code].sc_name = "recvfrom";
1204 bsd_syscalls[code].sc_format = FMT_FD_IO;
1205 break;
1206
1207 case BSC_sendto:
1208 case BSC_sendto_nocancel:
1209 bsd_syscalls[code].sc_name = "sendto";
1210 bsd_syscalls[code].sc_format = FMT_FD_IO;
1211 break;
1212
1213 case BSC_select:
1214 case BSC_select_nocancel:
1215 bsd_syscalls[code].sc_name = "select";
1216 bsd_syscalls[code].sc_format = FMT_SELECT;
1217 break;
1218
1219 case BSC_accept:
1220 case BSC_accept_nocancel:
1221 bsd_syscalls[code].sc_name = "accept";
1222 bsd_syscalls[code].sc_format = FMT_FD_2;
1223 break;
1224
1225 case BSC_socket:
1226 bsd_syscalls[code].sc_name = "socket";
1227 bsd_syscalls[code].sc_format = FMT_SOCKET;
1228 break;
1229
1230 case BSC_connect:
1231 case BSC_connect_nocancel:
1232 bsd_syscalls[code].sc_name = "connect";
1233 bsd_syscalls[code].sc_format = FMT_FD;
1234 break;
1235
1236 case BSC_bind:
1237 bsd_syscalls[code].sc_name = "bind";
1238 bsd_syscalls[code].sc_format = FMT_FD;
1239 break;
1240
1241 case BSC_listen:
1242 bsd_syscalls[code].sc_name = "listen";
1243 bsd_syscalls[code].sc_format = FMT_FD;
1244 break;
1245
1246 case BSC_mmap:
1247 bsd_syscalls[code].sc_name = "mmap";
1248 bsd_syscalls[code].sc_format = FMT_MMAP;
1249 break;
1250
1251 case BSC_socketpair:
1252 bsd_syscalls[code].sc_name = "socketpair";
1253 break;
1254
1255 case BSC_getxattr:
1256 bsd_syscalls[code].sc_name = "getxattr";
1257 break;
1258
1259 case BSC_setxattr:
1260 bsd_syscalls[code].sc_name = "setxattr";
1261 break;
1262
1263 case BSC_removexattr:
1264 bsd_syscalls[code].sc_name = "removexattr";
1265 break;
1266
1267 case BSC_listxattr:
1268 bsd_syscalls[code].sc_name = "listxattr";
1269 break;
1270
1271 case BSC_stat:
1272 bsd_syscalls[code].sc_name = "stat";
1273 break;
1274
1275 case BSC_stat64:
1276 bsd_syscalls[code].sc_name = "stat64";
1277 break;
1278
1279 case BSC_stat_extended:
1280 bsd_syscalls[code].sc_name = "stat_extended";
1281 break;
1282
1283 case BSC_stat64_extended:
1284 bsd_syscalls[code].sc_name = "stat_extended64";
1285 break;
1286
1287 case BSC_mount:
1288 bsd_syscalls[code].sc_name = "mount";
1289 bsd_syscalls[code].sc_format = FMT_MOUNT;
1290 break;
1291
1292 case BSC_unmount:
1293 bsd_syscalls[code].sc_name = "unmount";
1294 bsd_syscalls[code].sc_format = FMT_UNMOUNT;
1295 break;
1296
1297 case BSC_exit:
1298 bsd_syscalls[code].sc_name = "exit";
1299 break;
1300
1301 case BSC_execve:
1302 bsd_syscalls[code].sc_name = "execve";
1303 break;
1304
1305 case BSC_posix_spawn:
1306 bsd_syscalls[code].sc_name = "posix_spawn";
1307 break;
1308
1309 case BSC_open:
1310 case BSC_open_nocancel:
1311 bsd_syscalls[code].sc_name = "open";
1312 bsd_syscalls[code].sc_format = FMT_OPEN;
1313 break;
1314
1315 case BSC_open_extended:
1316 bsd_syscalls[code].sc_name = "open_extended";
1317 bsd_syscalls[code].sc_format = FMT_OPEN;
1318 break;
1319
1320 case BSC_guarded_open_np:
1321 bsd_syscalls[code].sc_name = "guarded_open_np";
1322 bsd_syscalls[code].sc_format = FMT_OPEN;
1323 break;
1324
1325 case BSC_open_dprotected_np:
1326 bsd_syscalls[code].sc_name = "open_dprotected";
1327 bsd_syscalls[code].sc_format = FMT_OPEN;
1328 break;
1329
1330 case BSC_dup:
1331 bsd_syscalls[code].sc_name = "dup";
1332 bsd_syscalls[code].sc_format = FMT_FD_2;
1333 break;
1334
1335 case BSC_dup2:
1336 bsd_syscalls[code].sc_name = "dup2";
1337 bsd_syscalls[code].sc_format = FMT_FD_2;
1338 break;
1339
1340 case BSC_close:
1341 case BSC_close_nocancel:
1342 bsd_syscalls[code].sc_name = "close";
1343 bsd_syscalls[code].sc_format = FMT_FD;
1344 break;
1345
1346 case BSC_guarded_close_np:
1347 bsd_syscalls[code].sc_name = "guarded_close_np";
1348 bsd_syscalls[code].sc_format = FMT_FD;
1349 break;
1350
1351 case BSC_read:
1352 case BSC_read_nocancel:
1353 bsd_syscalls[code].sc_name = "read";
1354 bsd_syscalls[code].sc_format = FMT_FD_IO;
1355 break;
1356
1357 case BSC_write:
1358 case BSC_write_nocancel:
1359 bsd_syscalls[code].sc_name = "write";
1360 bsd_syscalls[code].sc_format = FMT_FD_IO;
1361 break;
1362
1363 case BSC_fgetxattr:
1364 bsd_syscalls[code].sc_name = "fgetxattr";
1365 bsd_syscalls[code].sc_format = FMT_FD;
1366 break;
1367
1368 case BSC_fsetxattr:
1369 bsd_syscalls[code].sc_name = "fsetxattr";
1370 bsd_syscalls[code].sc_format = FMT_FD;
1371 break;
1372
1373 case BSC_fremovexattr:
1374 bsd_syscalls[code].sc_name = "fremovexattr";
1375 bsd_syscalls[code].sc_format = FMT_FD;
1376 break;
1377
1378 case BSC_flistxattr:
1379 bsd_syscalls[code].sc_name = "flistxattr";
1380 bsd_syscalls[code].sc_format = FMT_FD;
1381 break;
1382
1383 case BSC_fstat:
1384 bsd_syscalls[code].sc_name = "fstat";
1385 bsd_syscalls[code].sc_format = FMT_FD;
1386 break;
1387
1388 case BSC_fstat64:
1389 bsd_syscalls[code].sc_name = "fstat64";
1390 bsd_syscalls[code].sc_format = FMT_FD;
1391 break;
1392
1393 case BSC_fstat_extended:
1394 bsd_syscalls[code].sc_name = "fstat_extended";
1395 bsd_syscalls[code].sc_format = FMT_FD;
1396 break;
1397
1398 case BSC_fstat64_extended:
1399 bsd_syscalls[code].sc_name = "fstat64_extended";
1400 bsd_syscalls[code].sc_format = FMT_FD;
1401 break;
1402
1403 case BSC_lstat:
1404 bsd_syscalls[code].sc_name = "lstat";
1405 break;
1406
1407 case BSC_lstat64:
1408 bsd_syscalls[code].sc_name = "lstat64";
1409 break;
1410
1411 case BSC_lstat_extended:
1412 bsd_syscalls[code].sc_name = "lstat_extended";
1413 break;
1414
1415 case BSC_lstat64_extended:
1416 bsd_syscalls[code].sc_name = "lstat_extended64";
1417 break;
1418
1419 case BSC_link:
1420 bsd_syscalls[code].sc_name = "link";
1421 break;
1422
1423 case BSC_unlink:
1424 bsd_syscalls[code].sc_name = "unlink";
1425 break;
1426
1427 case BSC_mknod:
1428 bsd_syscalls[code].sc_name = "mknod";
1429 break;
1430
1431 case BSC_umask:
1432 bsd_syscalls[code].sc_name = "umask";
1433 bsd_syscalls[code].sc_format = FMT_UMASK;
1434 break;
1435
1436 case BSC_umask_extended:
1437 bsd_syscalls[code].sc_name = "umask_extended";
1438 bsd_syscalls[code].sc_format = FMT_UMASK;
1439 break;
1440
1441 case BSC_chmod:
1442 bsd_syscalls[code].sc_name = "chmod";
1443 bsd_syscalls[code].sc_format = FMT_CHMOD;
1444 break;
1445
1446 case BSC_chmod_extended:
1447 bsd_syscalls[code].sc_name = "chmod_extended";
1448 bsd_syscalls[code].sc_format = FMT_CHMOD_EXT;
1449 break;
1450
1451 case BSC_fchmod:
1452 bsd_syscalls[code].sc_name = "fchmod";
1453 bsd_syscalls[code].sc_format = FMT_FCHMOD;
1454 break;
1455
1456 case BSC_fchmod_extended:
1457 bsd_syscalls[code].sc_name = "fchmod_extended";
1458 bsd_syscalls[code].sc_format = FMT_FCHMOD_EXT;
1459 break;
1460
1461 case BSC_chown:
1462 bsd_syscalls[code].sc_name = "chown";
1463 break;
1464
1465 case BSC_lchown:
1466 bsd_syscalls[code].sc_name = "lchown";
1467 break;
1468
1469 case BSC_fchown:
1470 bsd_syscalls[code].sc_name = "fchown";
1471 bsd_syscalls[code].sc_format = FMT_FD;
1472 break;
1473
1474 case BSC_access:
1475 bsd_syscalls[code].sc_name = "access";
1476 bsd_syscalls[code].sc_format = FMT_ACCESS;
1477 break;
1478
1479 case BSC_access_extended:
1480 bsd_syscalls[code].sc_name = "access_extended";
1481 break;
1482
1483 case BSC_chdir:
1484 bsd_syscalls[code].sc_name = "chdir";
1485 break;
1486
1487 case BSC_pthread_chdir:
1488 bsd_syscalls[code].sc_name = "pthread_chdir";
1489 break;
1490
1491 case BSC_chroot:
1492 bsd_syscalls[code].sc_name = "chroot";
1493 break;
1494
1495 case BSC_utimes:
1496 bsd_syscalls[code].sc_name = "utimes";
1497 break;
1498
1499 case BSC_delete:
1500 bsd_syscalls[code].sc_name = "delete-Carbon";
1501 break;
1502
1503 case BSC_undelete:
1504 bsd_syscalls[code].sc_name = "undelete";
1505 break;
1506
1507 case BSC_revoke:
1508 bsd_syscalls[code].sc_name = "revoke";
1509 break;
1510
1511 case BSC_fsctl:
1512 bsd_syscalls[code].sc_name = "fsctl";
1513 break;
1514
1515 case BSC_ffsctl:
1516 bsd_syscalls[code].sc_name = "ffsctl";
1517 bsd_syscalls[code].sc_format = FMT_FD;
1518 break;
1519
1520 case BSC_chflags:
1521 bsd_syscalls[code].sc_name = "chflags";
1522 bsd_syscalls[code].sc_format = FMT_CHFLAGS;
1523 break;
1524
1525 case BSC_fchflags:
1526 bsd_syscalls[code].sc_name = "fchflags";
1527 bsd_syscalls[code].sc_format = FMT_FCHFLAGS;
1528 break;
1529
1530 case BSC_fchdir:
1531 bsd_syscalls[code].sc_name = "fchdir";
1532 bsd_syscalls[code].sc_format = FMT_FD;
1533 break;
1534
1535 case BSC_pthread_fchdir:
1536 bsd_syscalls[code].sc_name = "pthread_fchdir";
1537 bsd_syscalls[code].sc_format = FMT_FD;
1538 break;
1539
1540 case BSC_futimes:
1541 bsd_syscalls[code].sc_name = "futimes";
1542 bsd_syscalls[code].sc_format = FMT_FD;
1543 break;
1544
1545 case BSC_sync:
1546 bsd_syscalls[code].sc_name = "sync";
1547 break;
1548
1549 case BSC_symlink:
1550 bsd_syscalls[code].sc_name = "symlink";
1551 break;
1552
1553 case BSC_readlink:
1554 bsd_syscalls[code].sc_name = "readlink";
1555 break;
1556
1557 case BSC_fsync:
1558 case BSC_fsync_nocancel:
1559 bsd_syscalls[code].sc_name = "fsync";
1560 bsd_syscalls[code].sc_format = FMT_FD;
1561 break;
1562
1563 case BSC_fdatasync:
1564 bsd_syscalls[code].sc_name = "fdatasync";
1565 bsd_syscalls[code].sc_format = FMT_FD;
1566 break;
1567
1568 case BSC_readv:
1569 case BSC_readv_nocancel:
1570 bsd_syscalls[code].sc_name = "readv";
1571 bsd_syscalls[code].sc_format = FMT_FD_IO;
1572 break;
1573
1574 case BSC_writev:
1575 case BSC_writev_nocancel:
1576 bsd_syscalls[code].sc_name = "writev";
1577 bsd_syscalls[code].sc_format = FMT_FD_IO;
1578 break;
1579
1580 case BSC_pread:
1581 case BSC_pread_nocancel:
1582 bsd_syscalls[code].sc_name = "pread";
1583 bsd_syscalls[code].sc_format = FMT_PREAD;
1584 break;
1585
1586 case BSC_pwrite:
1587 case BSC_pwrite_nocancel:
1588 bsd_syscalls[code].sc_name = "pwrite";
1589 bsd_syscalls[code].sc_format = FMT_PREAD;
1590 break;
1591
1592 case BSC_mkdir:
1593 bsd_syscalls[code].sc_name = "mkdir";
1594 break;
1595
1596 case BSC_mkdir_extended:
1597 bsd_syscalls[code].sc_name = "mkdir_extended";
1598 break;
1599
1600 case BSC_mkfifo:
1601 bsd_syscalls[code].sc_name = "mkfifo";
1602 break;
1603
1604 case BSC_mkfifo_extended:
1605 bsd_syscalls[code].sc_name = "mkfifo_extended";
1606 break;
1607
1608 case BSC_rmdir:
1609 bsd_syscalls[code].sc_name = "rmdir";
1610 break;
1611
1612 case BSC_statfs:
1613 bsd_syscalls[code].sc_name = "statfs";
1614 break;
1615
1616 case BSC_statfs64:
1617 bsd_syscalls[code].sc_name = "statfs64";
1618 break;
1619
1620 case BSC_getfsstat:
1621 bsd_syscalls[code].sc_name = "getfsstat";
1622 break;
1623
1624 case BSC_getfsstat64:
1625 bsd_syscalls[code].sc_name = "getfsstat64";
1626 break;
1627
1628 case BSC_fstatfs:
1629 bsd_syscalls[code].sc_name = "fstatfs";
1630 bsd_syscalls[code].sc_format = FMT_FD;
1631 break;
1632
1633 case BSC_fstatfs64:
1634 bsd_syscalls[code].sc_name = "fstatfs64";
1635 bsd_syscalls[code].sc_format = FMT_FD;
1636 break;
1637
1638 case BSC_pathconf:
1639 bsd_syscalls[code].sc_name = "pathconf";
1640 break;
1641
1642 case BSC_fpathconf:
1643 bsd_syscalls[code].sc_name = "fpathconf";
1644 bsd_syscalls[code].sc_format = FMT_FD;
1645 break;
1646
1647 case BSC_getdirentries:
1648 bsd_syscalls[code].sc_name = "getdirentries";
1649 bsd_syscalls[code].sc_format = FMT_FD_IO;
1650 break;
1651
1652 case BSC_getdirentries64:
1653 bsd_syscalls[code].sc_name = "getdirentries64";
1654 bsd_syscalls[code].sc_format = FMT_FD_IO;
1655 break;
1656
1657 case BSC_lseek:
1658 bsd_syscalls[code].sc_name = "lseek";
1659 bsd_syscalls[code].sc_format = FMT_LSEEK;
1660 break;
1661
1662 case BSC_truncate:
1663 bsd_syscalls[code].sc_name = "truncate";
1664 bsd_syscalls[code].sc_format = FMT_TRUNC;
1665 break;
1666
1667 case BSC_ftruncate:
1668 bsd_syscalls[code].sc_name = "ftruncate";
1669 bsd_syscalls[code].sc_format = FMT_FTRUNC;
1670 break;
1671
1672 case BSC_flock:
1673 bsd_syscalls[code].sc_name = "flock";
1674 bsd_syscalls[code].sc_format = FMT_FLOCK;
1675 break;
1676
1677 case BSC_getattrlist:
1678 bsd_syscalls[code].sc_name = "getattrlist";
1679 break;
1680
1681 case BSC_setattrlist:
1682 bsd_syscalls[code].sc_name = "setattrlist";
1683 break;
1684
1685 case BSC_fgetattrlist:
1686 bsd_syscalls[code].sc_name = "fgetattrlist";
1687 bsd_syscalls[code].sc_format = FMT_FD;
1688 break;
1689
1690 case BSC_fsetattrlist:
1691 bsd_syscalls[code].sc_name = "fsetattrlist";
1692 bsd_syscalls[code].sc_format = FMT_FD;
1693 break;
1694
1695 case BSC_getdirentriesattr:
1696 bsd_syscalls[code].sc_name = "getdirentriesattr";
1697 bsd_syscalls[code].sc_format = FMT_FD;
1698 break;
1699
1700 case BSC_exchangedata:
1701 bsd_syscalls[code].sc_name = "exchangedata";
1702 break;
1703
1704 case BSC_rename:
1705 bsd_syscalls[code].sc_name = "rename";
1706 break;
1707
1708 case BSC_copyfile:
1709 bsd_syscalls[code].sc_name = "copyfile";
1710 break;
1711
1712 case BSC_checkuseraccess:
1713 bsd_syscalls[code].sc_name = "checkuseraccess";
1714 break;
1715
1716 case BSC_searchfs:
1717 bsd_syscalls[code].sc_name = "searchfs";
1718 break;
1719
1720 case BSC_aio_fsync:
1721 bsd_syscalls[code].sc_name = "aio_fsync";
1722 bsd_syscalls[code].sc_format = FMT_AIO_FSYNC;
1723 break;
1724
1725 case BSC_aio_return:
1726 bsd_syscalls[code].sc_name = "aio_return";
1727 bsd_syscalls[code].sc_format = FMT_AIO_RETURN;
1728 break;
1729
1730 case BSC_aio_suspend:
1731 case BSC_aio_suspend_nocancel:
1732 bsd_syscalls[code].sc_name = "aio_suspend";
1733 bsd_syscalls[code].sc_format = FMT_AIO_SUSPEND;
1734 break;
1735
1736 case BSC_aio_cancel:
1737 bsd_syscalls[code].sc_name = "aio_cancel";
1738 bsd_syscalls[code].sc_format = FMT_AIO_CANCEL;
1739 break;
1740
1741 case BSC_aio_error:
1742 bsd_syscalls[code].sc_name = "aio_error";
1743 bsd_syscalls[code].sc_format = FMT_AIO;
1744 break;
1745
1746 case BSC_aio_read:
1747 bsd_syscalls[code].sc_name = "aio_read";
1748 bsd_syscalls[code].sc_format = FMT_AIO;
1749 break;
1750
1751 case BSC_aio_write:
1752 bsd_syscalls[code].sc_name = "aio_write";
1753 bsd_syscalls[code].sc_format = FMT_AIO;
1754 break;
1755
1756 case BSC_lio_listio:
1757 bsd_syscalls[code].sc_name = "lio_listio";
1758 bsd_syscalls[code].sc_format = FMT_LIO_LISTIO;
1759 break;
1760
1761 case BSC_msync:
1762 case BSC_msync_nocancel:
1763 bsd_syscalls[code].sc_name = "msync";
1764 bsd_syscalls[code].sc_format = FMT_MSYNC;
1765 break;
1766
1767 case BSC_fcntl:
1768 case BSC_fcntl_nocancel:
1769 bsd_syscalls[code].sc_name = "fcntl";
1770 bsd_syscalls[code].sc_format = FMT_FCNTL;
1771 break;
1772
1773 case BSC_ioctl:
1774 bsd_syscalls[code].sc_name = "ioctl";
1775 bsd_syscalls[code].sc_format = FMT_IOCTL;
1776 break;
1777
1778 case BSC_fsgetpath:
1779 bsd_syscalls[code].sc_name = "fsgetpath";
1780 break;
1781
1782 case BSC_getattrlistbulk:
1783 bsd_syscalls[code].sc_name = "getattrlistbulk";
1784 break;
1785
1786 case BSC_openat:
1787 bsd_syscalls[code].sc_name = "openat";
1788 bsd_syscalls[code].sc_format = FMT_OPENAT;
1789 break;
1790
1791 case BSC_openat_nocancel:
1792 bsd_syscalls[code].sc_name = "openat_nocanel";
1793 bsd_syscalls[code].sc_format = FMT_OPENAT;
1794 break;
1795
1796 case BSC_renameat:
1797 bsd_syscalls[code].sc_name = "renameat";
1798 bsd_syscalls[code].sc_format = FMT_RENAMEAT;
1799 break;
1800
1801 case BSC_chmodat:
1802 bsd_syscalls[code].sc_name = "chmodat";
1803 bsd_syscalls[code].sc_format = FMT_CHMODAT;
1804 break;
1805
1806 case BSC_chownat:
1807 bsd_syscalls[code].sc_name = "chownat";
1808 bsd_syscalls[code].sc_format = FMT_AT;
1809 break;
1810
1811 case BSC_fstatat:
1812 bsd_syscalls[code].sc_name = "fstatat";
1813 bsd_syscalls[code].sc_format = FMT_AT;
1814 break;
1815
1816 case BSC_fstatat64:
1817 bsd_syscalls[code].sc_name = "fstatat64";
1818 bsd_syscalls[code].sc_format = FMT_AT;
1819 break;
1820
1821 case BSC_linkat:
1822 bsd_syscalls[code].sc_name = "linkat";
1823 bsd_syscalls[code].sc_format = FMT_AT;
1824 break;
1825
1826 case BSC_unlinkat:
1827 bsd_syscalls[code].sc_name = "unlinkat";
1828 bsd_syscalls[code].sc_format = FMT_AT;
1829 break;
1830
1831 case BSC_readlinkat:
1832 bsd_syscalls[code].sc_name = "readlinkat";
1833 bsd_syscalls[code].sc_format = FMT_AT;
1834 break;
1835
1836 case BSC_symlinkat:
1837 bsd_syscalls[code].sc_name = "symlinkat";
1838 bsd_syscalls[code].sc_format = FMT_AT;
1839 break;
1840
1841 case BSC_mkdirat:
1842 bsd_syscalls[code].sc_name = "mkdirat";
1843 bsd_syscalls[code].sc_format = FMT_AT;
1844 break;
1845
1846 case BSC_getattrlistat:
1847 bsd_syscalls[code].sc_name = "getattrlistat";
1848 bsd_syscalls[code].sc_format = FMT_AT;
1849 break;
1850 }
1851 }
1852
1853 for (i = 0; (type = filemgr_call_types[i]); i++) {
1854 char * p;
1855
1856 code = filemgr_index(type);
1857
1858 if (code >= MAX_FILEMGR) {
1859 printf("FILEMGR call init (%x): type exceeds table size\n", type);
1860 continue;
1861 }
1862 switch (type) {
1863
1864 case FILEMGR_PBGETCATALOGINFO:
1865 p = "GetCatalogInfo";
1866 break;
1867
1868 case FILEMGR_PBGETCATALOGINFOBULK:
1869 p = "GetCatalogInfoBulk";
1870 break;
1871
1872 case FILEMGR_PBCREATEFILEUNICODE:
1873 p = "CreateFileUnicode";
1874 break;
1875
1876 case FILEMGR_PBCREATEDIRECTORYUNICODE:
1877 p = "CreateDirectoryUnicode";
1878 break;
1879
1880 case FILEMGR_PBCREATEFORK:
1881 p = "PBCreateFork";
1882 break;
1883
1884 case FILEMGR_PBDELETEFORK:
1885 p = "PBDeleteFork";
1886 break;
1887
1888 case FILEMGR_PBITERATEFORK:
1889 p = "PBIterateFork";
1890 break;
1891
1892 case FILEMGR_PBOPENFORK:
1893 p = "PBOpenFork";
1894 break;
1895
1896 case FILEMGR_PBREADFORK:
1897 p = "PBReadFork";
1898 break;
1899
1900 case FILEMGR_PBWRITEFORK:
1901 p = "PBWriteFork";
1902 break;
1903
1904 case FILEMGR_PBALLOCATEFORK:
1905 p = "PBAllocateFork";
1906 break;
1907
1908 case FILEMGR_PBDELETEOBJECT:
1909 p = "PBDeleteObject";
1910 break;
1911
1912 case FILEMGR_PBEXCHANGEOBJECT:
1913 p = "PBExchangeObject";
1914 break;
1915
1916 case FILEMGR_PBGETFORKCBINFO:
1917 p = "PBGetForkCBInfo";
1918 break;
1919
1920 case FILEMGR_PBGETVOLUMEINFO:
1921 p = "PBGetVolumeInfo";
1922 break;
1923
1924 case FILEMGR_PBMAKEFSREF:
1925 p = "PBMakeFSRef";
1926 break;
1927
1928 case FILEMGR_PBMAKEFSREFUNICODE:
1929 p = "PBMakeFSRefUnicode";
1930 break;
1931
1932 case FILEMGR_PBMOVEOBJECT:
1933 p = "PBMoveObject";
1934 break;
1935
1936 case FILEMGR_PBOPENITERATOR:
1937 p = "PBOpenIterator";
1938 break;
1939
1940 case FILEMGR_PBRENAMEUNICODE:
1941 p = "PBRenameUnicode";
1942 break;
1943
1944 case FILEMGR_PBSETCATALOGINFO:
1945 p = "SetCatalogInfo";
1946 break;
1947
1948 case FILEMGR_PBSETVOLUMEINFO:
1949 p = "SetVolumeInfo";
1950 break;
1951
1952 case FILEMGR_FSREFMAKEPATH:
1953 p = "FSRefMakePath";
1954 break;
1955
1956 case FILEMGR_FSPATHMAKEREF:
1957 p = "FSPathMakeRef";
1958 break;
1959
1960 case FILEMGR_PBGETCATINFO:
1961 p = "GetCatInfo";
1962 break;
1963
1964 case FILEMGR_PBGETCATINFOLITE:
1965 p = "GetCatInfoLite";
1966 break;
1967
1968 case FILEMGR_PBHGETFINFO:
1969 p = "PBHGetFInfo";
1970 break;
1971
1972 case FILEMGR_PBXGETVOLINFO:
1973 p = "PBXGetVolInfo";
1974 break;
1975
1976 case FILEMGR_PBHCREATE:
1977 p = "PBHCreate";
1978 break;
1979
1980 case FILEMGR_PBHOPENDF:
1981 p = "PBHOpenDF";
1982 break;
1983
1984 case FILEMGR_PBHOPENRF:
1985 p = "PBHOpenRF";
1986 break;
1987
1988 case FILEMGR_PBHGETDIRACCESS:
1989 p = "PBHGetDirAccess";
1990 break;
1991
1992 case FILEMGR_PBHSETDIRACCESS:
1993 p = "PBHSetDirAccess";
1994 break;
1995
1996 case FILEMGR_PBHMAPID:
1997 p = "PBHMapID";
1998 break;
1999
2000 case FILEMGR_PBHMAPNAME:
2001 p = "PBHMapName";
2002 break;
2003
2004 case FILEMGR_PBCLOSE:
2005 p = "PBClose";
2006 break;
2007
2008 case FILEMGR_PBFLUSHFILE:
2009 p = "PBFlushFile";
2010 break;
2011
2012 case FILEMGR_PBGETEOF:
2013 p = "PBGetEOF";
2014 break;
2015
2016 case FILEMGR_PBSETEOF:
2017 p = "PBSetEOF";
2018 break;
2019
2020 case FILEMGR_PBGETFPOS:
2021 p = "PBGetFPos";
2022 break;
2023
2024 case FILEMGR_PBREAD:
2025 p = "PBRead";
2026 break;
2027
2028 case FILEMGR_PBWRITE:
2029 p = "PBWrite";
2030 break;
2031
2032 case FILEMGR_PBGETFCBINFO:
2033 p = "PBGetFCBInfo";
2034 break;
2035
2036 case FILEMGR_PBSETFINFO:
2037 p = "PBSetFInfo";
2038 break;
2039
2040 case FILEMGR_PBALLOCATE:
2041 p = "PBAllocate";
2042 break;
2043
2044 case FILEMGR_PBALLOCCONTIG:
2045 p = "PBAllocContig";
2046 break;
2047
2048 case FILEMGR_PBSETFPOS:
2049 p = "PBSetFPos";
2050 break;
2051
2052 case FILEMGR_PBSETCATINFO:
2053 p = "PBSetCatInfo";
2054 break;
2055
2056 case FILEMGR_PBGETVOLPARMS:
2057 p = "PBGetVolParms";
2058 break;
2059
2060 case FILEMGR_PBSETVINFO:
2061 p = "PBSetVInfo";
2062 break;
2063
2064 case FILEMGR_PBMAKEFSSPEC:
2065 p = "PBMakeFSSpec";
2066 break;
2067
2068 case FILEMGR_PBHGETVINFO:
2069 p = "PBHGetVInfo";
2070 break;
2071
2072 case FILEMGR_PBCREATEFILEIDREF:
2073 p = "PBCreateFileIDRef";
2074 break;
2075
2076 case FILEMGR_PBDELETEFILEIDREF:
2077 p = "PBDeleteFileIDRef";
2078 break;
2079
2080 case FILEMGR_PBRESOLVEFILEIDREF:
2081 p = "PBResolveFileIDRef";
2082 break;
2083
2084 case FILEMGR_PBFLUSHVOL:
2085 p = "PBFlushVol";
2086 break;
2087
2088 case FILEMGR_PBHRENAME:
2089 p = "PBHRename";
2090 break;
2091
2092 case FILEMGR_PBCATMOVE:
2093 p = "PBCatMove";
2094 break;
2095
2096 case FILEMGR_PBEXCHANGEFILES:
2097 p = "PBExchangeFiles";
2098 break;
2099
2100 case FILEMGR_PBHDELETE:
2101 p = "PBHDelete";
2102 break;
2103
2104 case FILEMGR_PBDIRCREATE:
2105 p = "PBDirCreate";
2106 break;
2107
2108 case FILEMGR_PBCATSEARCH:
2109 p = "PBCatSearch";
2110 break;
2111
2112 case FILEMGR_PBHSETFLOCK:
2113 p = "PBHSetFlock";
2114 break;
2115
2116 case FILEMGR_PBHRSTFLOCK:
2117 p = "PBHRstFLock";
2118 break;
2119
2120 case FILEMGR_PBLOCKRANGE:
2121 p = "PBLockRange";
2122 break;
2123
2124 case FILEMGR_PBUNLOCKRANGE:
2125 p = "PBUnlockRange";
2126 break;
2127
2128 default:
2129 p = NULL;
2130 break;
2131 }
2132 filemgr_calls[code].fm_name = p;
2133 }
2134}
2135
2136
2137
2138int
2139main(argc, argv)
2140 int argc;
2141 char *argv[];
2142{
2143 char *myname = "fs_usage";
2144 int i;
2145 char ch;
2146
2147 time_t stop_at_time = 0;
2148
2149 if (0 != reexec_to_match_kernel()) {
2150 fprintf(stderr, "Could not re-execute: %d\n", errno);
2151 exit(1);
2152 }
2153 get_screenwidth();
2154
2155 /*
2156 * get our name
2157 */
2158 if (argc > 0) {
2159 if ((myname = rindex(argv[0], '/')) == 0)
2160 myname = argv[0];
2161 else
2162 myname++;
2163 }
2164
2165 while ((ch = getopt(argc, argv, "bewf:R:S:E:t:")) != EOF) {
2166
2167 switch(ch) {
2168
2169 case 'e':
2170 exclude_pids = 1;
2171 exclude_default_pids = 0;
2172 break;
2173
2174 case 'w':
2175 wideflag = 1;
2176 if ((uint)columns < MAX_WIDE_MODE_COLS)
2177 columns = MAX_WIDE_MODE_COLS;
2178 break;
2179
2180 case 'f':
2181 if (!strcmp(optarg, "network"))
2182 filter_mode |= NETWORK_FILTER;
2183 else if (!strcmp(optarg, "filesys"))
2184 filter_mode |= FILESYS_FILTER;
2185 else if (!strcmp(optarg, "cachehit"))
2186 show_cachehits = TRUE;
2187 else if (!strcmp(optarg, "exec"))
2188 filter_mode |= EXEC_FILTER;
2189 else if (!strcmp(optarg, "pathname"))
2190 filter_mode |= PATHNAME_FILTER;
2191 else if (!strcmp(optarg, "diskio"))
2192 filter_mode |= DISKIO_FILTER;
2193 break;
2194
2195 case 'b':
2196 BC_flag = 1;
2197 break;
2198
2199 case 't':
2200 stop_at_time = time(NULL) + strtoul(optarg, NULL, 10);
2201 break;
2202
2203 case 'R':
2204 RAW_flag = 1;
2205 RAW_file = optarg;
2206 break;
2207
2208 case 'S':
2209 start_time = atof(optarg);
2210 break;
2211
2212 case 'E':
2213 end_time = atof(optarg);
2214 break;
2215
2216 default:
2217 exit_usage(myname);
2218 }
2219 }
2220 if (!RAW_flag) {
2221 if ( geteuid() != 0 ) {
2222 fprintf(stderr, "'fs_usage' must be run as root...\n");
2223 exit(1);
2224 }
2225 }
2226 argc -= optind;
2227 argv += optind;
2228
2229 /*
2230 * when excluding, fs_usage should be the first in line for pids[]
2231 *
2232 * the !exclude_pids && argc == 0 catches the exclude_default_pids
2233 * case below where exclude_pids is later set and the fs_usage PID
2234 * needs to make it into pids[]
2235 */
2236 if (exclude_pids || (!exclude_pids && argc == 0)) {
2237 if (num_of_pids < (MAX_PIDS - 1))
2238 pids[num_of_pids++] = getpid();
2239 }
2240
2241 /*
2242 * If we process any list of pids/cmds, then turn off the defaults
2243 */
2244 if (argc > 0)
2245 exclude_default_pids = 0;
2246
2247 while (argc > 0 && num_of_pids < (MAX_PIDS - 1)) {
2248 select_pid_mode++;
2249 argtopid(argv[0]);
2250 argc--;
2251 argv++;
2252 }
2253 /*
2254 * Exclude a set of default pids
2255 */
2256 if (exclude_default_pids) {
2257 argtopid("Terminal");
2258 argtopid("telnetd");
2259 argtopid("telnet");
2260 argtopid("sshd");
2261 argtopid("rlogind");
2262 argtopid("tcsh");
2263 argtopid("csh");
2264 argtopid("sh");
2265 exclude_pids = 1;
2266 }
2267#if 0
2268 for (i = 0; i < num_of_pids; i++) {
2269 if (exclude_pids)
2270 fprintf(stderr, "exclude pid %d\n", pids[i]);
2271 else
2272 fprintf(stderr, "pid %d\n", pids[i]);
2273 }
2274#endif
2275 if (!RAW_flag) {
2276 struct sigaction osa;
2277 int num_cpus;
2278 size_t len;
2279
2280 /* set up signal handlers */
2281 signal(SIGINT, leave);
2282 signal(SIGQUIT, leave);
2283
2284 sigaction(SIGHUP, (struct sigaction *)NULL, &osa);
2285
2286 if (osa.sa_handler == SIG_DFL)
2287 signal(SIGHUP, leave);
2288 signal(SIGTERM, leave);
2289 /*
2290 * grab the number of cpus
2291 */
2292 mib[0] = CTL_HW;
2293 mib[1] = HW_NCPU;
2294 mib[2] = 0;
2295 len = sizeof(num_cpus);
2296
2297 sysctl(mib, 2, &num_cpus, &len, NULL, 0);
2298 num_events = EVENT_BASE * num_cpus;
2299 }
2300 signal(SIGWINCH, sigwinch);
2301
2302 if ((my_buffer = malloc(num_events * sizeof(kd_buf))) == (char *)0)
2303 quit("can't allocate memory for tracing info\n");
2304
2305 if (ReadSharedCacheMap("/var/db/dyld/dyld_shared_cache_i386.map", &framework32, "/var/db/dyld/dyld_shared_cache_i386")) {
2306 ReadSharedCacheMap("/var/db/dyld/dyld_shared_cache_x86_64.map", &framework64, "/var/db/dyld/dyld_shared_cache_x86_64");
2307 } else {
2308 ReadSharedCacheMap("/var/db/dyld/dyld_shared_cache_ppc.map", &framework32, "/var/db/dyld/dyld_shared_cache_ppc");
2309 ReadSharedCacheMap("/var/db/dyld/dyld_shared_cache_ppc64.map", &framework64, "/var/db/dyld/dyld_shared_cache_ppc64");
2310 }
2311 SortFrameworkAddresses();
2312
2313 cache_disk_names();
2314
2315 if (!RAW_flag) {
2316
2317 set_remove();
2318 set_numbufs(num_events);
2319 set_init();
2320
2321 if (exclude_pids == 0) {
2322 for (i = 0; i < num_of_pids; i++)
2323 set_pidcheck(pids[i], 1);
2324 } else {
2325 for (i = 0; i < num_of_pids; i++)
2326 set_pidexclude(pids[i], 1);
2327 }
2328 if (select_pid_mode && !one_good_pid) {
2329 /*
2330 * An attempt to restrict output to a given
2331 * pid or command has failed. Exit gracefully
2332 */
2333 set_remove();
2334 exit_usage(myname);
2335 }
2336
2337 set_filter();
2338
2339 set_enable(1);
2340
2341 init_arguments_buffer();
2342 }
2343 getdivisor();
2344
2345 init_tables();
2346
2347 /*
2348 * main loop
2349 */
2350 while (stop_at_time == 0 || last_time < stop_at_time) {
2351 if (!RAW_flag)
2352 usleep(1000 * usleep_ms);
2353
2354 sample_sc();
2355
2356 last_time = time((long *)0);
2357 }
2358}
2359
2360
2361void
2362find_proc_names()
2363{
2364 size_t bufSize = 0;
2365 struct kinfo_proc *kp;
2366
2367 mib[0] = CTL_KERN;
2368 mib[1] = KERN_PROC;
2369 mib[2] = KERN_PROC_ALL;
2370 mib[3] = 0;
2371
2372 if (sysctl(mib, 4, NULL, &bufSize, NULL, 0) < 0)
2373 quit("trace facility failure, KERN_PROC_ALL\n");
2374
2375 if ((kp = (struct kinfo_proc *)malloc(bufSize)) == (struct kinfo_proc *)0)
2376 quit("can't allocate memory for proc buffer\n");
2377
2378 if (sysctl(mib, 4, kp, &bufSize, NULL, 0) < 0)
2379 quit("trace facility failure, KERN_PROC_ALL\n");
2380
2381 kp_nentries = bufSize/ sizeof(struct kinfo_proc);
2382 kp_buffer = kp;
2383}
2384
2385
2386void
2387set_enable(int val)
2388{
2389 mib[0] = CTL_KERN;
2390 mib[1] = KERN_KDEBUG;
2391 mib[2] = KERN_KDENABLE; /* protocol */
2392 mib[3] = val;
2393 mib[4] = 0;
2394 mib[5] = 0; /* no flags */
2395
2396 if (sysctl(mib, 4, NULL, &needed, NULL, 0) < 0)
2397 quit("trace facility failure, KERN_KDENABLE\n");
2398
2399 if (val)
2400 trace_enabled = 1;
2401 else
2402 trace_enabled = 0;
2403}
2404
2405void
2406set_numbufs(int nbufs)
2407{
2408 mib[0] = CTL_KERN;
2409 mib[1] = KERN_KDEBUG;
2410 mib[2] = KERN_KDSETBUF;
2411 mib[3] = nbufs;
2412 mib[4] = 0;
2413 mib[5] = 0; /* no flags */
2414
2415 if (sysctl(mib, 4, NULL, &needed, NULL, 0) < 0)
2416 quit("trace facility failure, KERN_KDSETBUF\n");
2417
2418 mib[0] = CTL_KERN;
2419 mib[1] = KERN_KDEBUG;
2420 mib[2] = KERN_KDSETUP;
2421 mib[3] = 0;
2422 mib[4] = 0;
2423 mib[5] = 0; /* no flags */
2424
2425 if (sysctl(mib, 3, NULL, &needed, NULL, 0) < 0)
2426 quit("trace facility failure, KERN_KDSETUP\n");
2427}
2428
2429#define ENCODE_CSC_LOW(class, subclass) \
2430 ( (uint16_t) ( ((class) & 0xff) << 8 ) | ((subclass) & 0xff) )
2431
2432void
2433set_filter(void)
2434{
2435 uint8_t type_filter_bitmap[KDBG_TYPEFILTER_BITMAP_SIZE];
2436 bzero(type_filter_bitmap, sizeof(type_filter_bitmap));
2437
2438 setbit(type_filter_bitmap, ENCODE_CSC_LOW(DBG_TRACE,DBG_TRACE_DATA));
2439 setbit(type_filter_bitmap, ENCODE_CSC_LOW(DBG_TRACE,DBG_TRACE_STRING));
2440
2441 setbit(type_filter_bitmap, ENCODE_CSC_LOW(DBG_MACH,DBG_MACH_EXCP_SC)); //0x010c
2442 setbit(type_filter_bitmap, ENCODE_CSC_LOW(DBG_MACH,DBG_MACH_VM)); //0x0130
2443 setbit(type_filter_bitmap, ENCODE_CSC_LOW(DBG_MACH,DBG_MACH_SCHED)); //0x0140
2444
2445 setbit(type_filter_bitmap, ENCODE_CSC_LOW(DBG_FSYSTEM,DBG_FSRW)); //0x0301
2446 setbit(type_filter_bitmap, ENCODE_CSC_LOW(DBG_FSYSTEM,DBG_DKRW)); //0x0302
2447 setbit(type_filter_bitmap, ENCODE_CSC_LOW(DBG_FSYSTEM,DBG_IOCTL)); //0x0306
2448 setbit(type_filter_bitmap, ENCODE_CSC_LOW(DBG_FSYSTEM,DBG_BOOTCACHE)); //0x0307
2449
2450 setbit(type_filter_bitmap, ENCODE_CSC_LOW(DBG_BSD,DBG_BSD_EXCP_SC)); //0x040c
2451 setbit(type_filter_bitmap, ENCODE_CSC_LOW(DBG_BSD,DBG_BSD_PROC)); //0x0401
2452 setbit(type_filter_bitmap, ENCODE_CSC_LOW(DBG_BSD,DBG_BSD_SC_EXTENDED_INFO)); //0x040e
2453 setbit(type_filter_bitmap, ENCODE_CSC_LOW(DBG_BSD,DBG_BSD_SC_EXTENDED_INFO2)); //0x040f
2454
2455 setbit(type_filter_bitmap, ENCODE_CSC_LOW(DBG_CORESTORAGE,DBG_CS_IO)); //0x0a00
2456 setbit(type_filter_bitmap, ENCODE_CSC_LOW(DBG_CORESTORAGE, 1)); //0x0a01 for P_SCCS_SYNC_DIS
2457
2458 setbit(type_filter_bitmap, ENCODE_CSC_LOW(FILEMGR_CLASS, 0)); //Carbon File Manager
2459 setbit(type_filter_bitmap, ENCODE_CSC_LOW(FILEMGR_CLASS, 1)); //Carbon File Manager
2460
2461 errno = 0;
2462 int mib[] = { CTL_KERN, KERN_KDEBUG, KERN_KDSET_TYPEFILTER };
2463 size_t needed = KDBG_TYPEFILTER_BITMAP_SIZE;
2464 if(sysctl(mib, 3, type_filter_bitmap, &needed, NULL, 0)) {
2465 quit("trace facility failure, KERN_KDSET_TYPEFILTER\n");
2466 }
2467}
2468
2469void
2470set_pidcheck(int pid, int on_off)
2471{
2472 kd_regtype kr;
2473
2474 kr.type = KDBG_TYPENONE;
2475 kr.value1 = pid;
2476 kr.value2 = on_off;
2477 needed = sizeof(kd_regtype);
2478 mib[0] = CTL_KERN;
2479 mib[1] = KERN_KDEBUG;
2480 mib[2] = KERN_KDPIDTR;
2481 mib[3] = 0;
2482 mib[4] = 0;
2483 mib[5] = 0;
2484
2485 if (sysctl(mib, 3, &kr, &needed, NULL, 0) < 0) {
2486 if (on_off == 1)
2487 fprintf(stderr, "pid %d does not exist\n", pid);
2488 } else
2489 one_good_pid++;
2490}
2491
2492/*
2493 * on_off == 0 turns off pid exclusion
2494 * on_off == 1 turns on pid exclusion
2495 */
2496void
2497set_pidexclude(int pid, int on_off)
2498{
2499 kd_regtype kr;
2500
2501 one_good_pid++;
2502
2503 kr.type = KDBG_TYPENONE;
2504 kr.value1 = pid;
2505 kr.value2 = on_off;
2506 needed = sizeof(kd_regtype);
2507 mib[0] = CTL_KERN;
2508 mib[1] = KERN_KDEBUG;
2509 mib[2] = KERN_KDPIDEX;
2510 mib[3] = 0;
2511 mib[4] = 0;
2512 mib[5] = 0;
2513
2514 if (sysctl(mib, 3, &kr, &needed, NULL, 0) < 0) {
2515 if (on_off == 1)
2516 fprintf(stderr, "pid %d does not exist\n", pid);
2517 }
2518}
2519
2520void
2521get_bufinfo(kbufinfo_t *val)
2522{
2523 needed = sizeof (*val);
2524 mib[0] = CTL_KERN;
2525 mib[1] = KERN_KDEBUG;
2526 mib[2] = KERN_KDGETBUF;
2527 mib[3] = 0;
2528 mib[4] = 0;
2529 mib[5] = 0; /* no flags */
2530
2531 if (sysctl(mib, 3, val, &needed, 0, 0) < 0)
2532 quit("trace facility failure, KERN_KDGETBUF\n");
2533
2534}
2535
2536void
2537set_remove()
2538{
2539 errno = 0;
2540
2541 mib[0] = CTL_KERN;
2542 mib[1] = KERN_KDEBUG;
2543 mib[2] = KERN_KDREMOVE; /* protocol */
2544 mib[3] = 0;
2545 mib[4] = 0;
2546 mib[5] = 0; /* no flags */
2547
2548 if (sysctl(mib, 3, NULL, &needed, NULL, 0) < 0) {
2549 set_remove_flag = 0;
2550
2551 if (errno == EBUSY)
2552 quit("the trace facility is currently in use...\n fs_usage, sc_usage, and latency use this feature.\n\n");
2553 else
2554 quit("trace facility failure, KERN_KDREMOVE\n");
2555 }
2556}
2557
2558void
2559set_init()
2560{ kd_regtype kr;
2561
2562 kr.type = KDBG_RANGETYPE;
2563 kr.value1 = 0;
2564 kr.value2 = -1;
2565 needed = sizeof(kd_regtype);
2566
2567 mib[0] = CTL_KERN;
2568 mib[1] = KERN_KDEBUG;
2569 mib[2] = KERN_KDSETREG;
2570 mib[3] = 0;
2571 mib[4] = 0;
2572 mib[5] = 0; /* no flags */
2573
2574 if (sysctl(mib, 3, &kr, &needed, NULL, 0) < 0)
2575 quit("trace facility failure, KERN_KDSETREG\n");
2576
2577 mib[0] = CTL_KERN;
2578 mib[1] = KERN_KDEBUG;
2579 mib[2] = KERN_KDSETUP;
2580 mib[3] = 0;
2581 mib[4] = 0;
2582 mib[5] = 0; /* no flags */
2583
2584 if (sysctl(mib, 3, NULL, &needed, NULL, 0) < 0)
2585 quit("trace facility failure, KERN_KDSETUP\n");
2586}
2587
2588
2589void
2590sample_sc()
2591{
2592 kd_buf *kd;
2593 int i, count;
2594 size_t needed;
2595 uint32_t my_buffer_size = 0;
2596
2597 if (!RAW_flag)
2598 get_bufinfo(&bufinfo);
2599 else
2600 my_buffer_size = num_events * sizeof(kd_buf);
2601
2602 if (need_new_map) {
2603 read_command_map();
2604 need_new_map = 0;
2605 }
2606 if (!RAW_flag) {
2607 needed = bufinfo.nkdbufs * sizeof(kd_buf);
2608
2609 mib[0] = CTL_KERN;
2610 mib[1] = KERN_KDEBUG;
2611 mib[2] = KERN_KDREADTR;
2612 mib[3] = 0;
2613 mib[4] = 0;
2614 mib[5] = 0; /* no flags */
2615
2616 if (sysctl(mib, 3, my_buffer, &needed, NULL, 0) < 0)
2617 quit("trace facility failure, KERN_KDREADTR\n");
2618 count = needed;
2619
2620 if (count > (num_events / 8)) {
2621 if (usleep_ms > USLEEP_BEHIND)
2622 usleep_ms = USLEEP_BEHIND;
2623 else if (usleep_ms > USLEEP_MIN)
2624 usleep_ms /= 2;
2625
2626 } else if (count < (num_events / 16)) {
2627 if (usleep_ms < USLEEP_MAX)
2628 usleep_ms *= 2;
2629 }
2630
2631 if (bufinfo.flags & KDBG_WRAPPED) {
2632 fprintf(stderr, "fs_usage: buffer overrun, events generated too quickly: %d\n", count);
2633
2634 delete_all_events();
2635
2636 need_new_map = 1;
2637
2638 set_enable(0);
2639 set_enable(1);
2640 }
2641 } else {
2642 int bytes_read;
2643
2644 if ((bytes_read = read(RAW_fd, my_buffer, my_buffer_size)) < sizeof(kd_buf))
2645 exit(0);
2646 count = bytes_read / sizeof(kd_buf);
2647 }
2648 kd = (kd_buf *)my_buffer;
2649#if 0
2650 fprintf(stderr, "READTR returned %d items\n", count);
2651#endif
2652 for (i = 0; i < count; i++) {
2653 uint32_t debugid;
2654 uintptr_t thread;
2655 int type;
2656 int index;
2657 uintptr_t *sargptr;
2658 uint64_t now;
2659 long long l_usecs;
2660 int secs;
2661 long curr_time;
2662 th_info_t ti;
2663 struct diskio *dio;
2664
2665
2666 thread = kd[i].arg5;
2667 debugid = kd[i].debugid;
2668 type = kd[i].debugid & DBG_FUNC_MASK;
2669
2670 now = kdbg_get_timestamp(&kd[i]);
2671
2672 if (i == 0 && !RAW_flag) {
2673
2674 curr_time = time((long *)0);
2675 /*
2676 * Compute bias seconds after each trace buffer read.
2677 * This helps resync timestamps with the system clock
2678 * in the event of a system sleep.
2679 */
2680 if (bias_secs == 0 || curr_time < last_time || curr_time > (last_time + 2)) {
2681 l_usecs = (long long)(now / divisor);
2682 secs = l_usecs / 1000000;
2683 bias_secs = curr_time - secs;
2684 }
2685 }
2686 if (RAW_flag && bias_now == 0.0)
2687 bias_now = now;
2688
2689 if ((type & P_DISKIO_MASK) == P_DISKIO) {
2690 insert_diskio(type, kd[i].arg1, kd[i].arg2, kd[i].arg3, kd[i].arg4, thread, (double)now);
2691 continue;
2692 }
2693 if ((type & P_DISKIO_MASK) == P_DISKIO_DONE) {
2694 if ((dio = complete_diskio(kd[i].arg1, kd[i].arg4, kd[i].arg3, thread, (double)now))) {
2695 dio->vnodeid = kd[i].arg2;
2696 print_diskio(dio);
2697 free_diskio(dio);
2698 }
2699 continue;
2700 }
2701
2702 if ((type & CLASS_MASK) == P_CS_Class) {
2703
2704 // the usual DBG_FUNC_START/END does not work for i/o since it will
2705 // return on a different thread, this code uses the P_CS_IO_Done (0x4) bit
2706 // instead. the trace command doesn't know how handle either method
2707 // (unmatched start/end or 0x4) but works a little better this way.
2708
2709 int cs_type = type & P_CS_Type_Mask; // strip out the done bit
2710 bool start = (type & P_CS_IO_Done) != P_CS_IO_Done;
2711
2712 switch (cs_type) {
2713
2714 case P_CS_ReadChunk:
2715 case P_CS_WriteChunk:
2716 case P_CS_MetaRead:
2717 case P_CS_MetaWrite:
2718 if (start) {
2719 insert_diskio(cs_type, kd[i].arg2, kd[i].arg1, kd[i].arg3, kd[i].arg4, thread, (double)now);
2720 } else {
2721 if ((dio = complete_diskio(kd[i].arg2, kd[i].arg4, kd[i].arg3, thread, (double)now))) {
2722 print_diskio(dio);
2723 free_diskio(dio);
2724 }
2725 }
2726 continue;
2727
2728 case P_CS_TransformRead:
2729 case P_CS_TransformWrite:
2730 case P_CS_MigrationRead:
2731 case P_CS_MigrationWrite:
2732 if (start) {
2733 insert_diskio(cs_type, kd[i].arg2, CS_DEV, kd[i].arg3, kd[i].arg4, thread, (double)now);
2734 } else {
2735 if ((dio = complete_diskio(kd[i].arg2, kd[i].arg4, kd[i].arg3, thread, (double)now))) {
2736 print_diskio(dio);
2737 free_diskio(dio);
2738 }
2739 }
2740 continue;
2741
2742 case P_CS_SYNC_DISK:
2743 if (start) {
2744 enter_event(thread, cs_type, &kd[i], NULL, (double)now);
2745 } else {
2746 exit_event(" SyncCacheCS", thread, cs_type, kd[i].arg1, 0, 0, 0, FMT_SYNC_DISK_CS, (double)now);
2747 }
2748 continue;
2749 }
2750
2751 continue; // ignore other cs timestamps
2752 }
2753
2754 switch (type) {
2755
2756 case TRACE_DATA_NEWTHREAD:
2757 if (kd[i].arg1) {
2758 if ((ti = add_event(thread, TRACE_DATA_NEWTHREAD)) == NULL)
2759 continue;
2760 ti->child_thread = kd[i].arg1;
2761 ti->pid = kd[i].arg2;
2762 }
2763 continue;
2764
2765 case TRACE_STRING_NEWTHREAD:
2766 if ((ti = find_event(thread, TRACE_DATA_NEWTHREAD)) == (struct th_info *)0)
2767 continue;
2768
2769 create_map_entry(ti->child_thread, ti->pid, (char *)&kd[i].arg1);
2770
2771 delete_event(ti);
2772 continue;
2773
2774 case TRACE_DATA_EXEC:
2775 if ((ti = add_event(thread, TRACE_DATA_EXEC)) == NULL)
2776 continue;
2777
2778 ti->pid = kd[i].arg1;
2779 continue;
2780
2781 case TRACE_STRING_EXEC:
2782 if ((ti = find_event(thread, BSC_execve))) {
2783 if (ti->lookups[0].pathname[0])
2784 exit_event("execve", thread, BSC_execve, 0, 0, 0, 0, FMT_DEFAULT, (double)now);
2785
2786 } else if ((ti = find_event(thread, BSC_posix_spawn))) {
2787 if (ti->lookups[0].pathname[0])
2788 exit_event("posix_spawn", thread, BSC_posix_spawn, 0, 0, 0, 0, FMT_DEFAULT, (double)now);
2789 }
2790 if ((ti = find_event(thread, TRACE_DATA_EXEC)) == (struct th_info *)0)
2791 continue;
2792
2793 create_map_entry(thread, ti->pid, (char *)&kd[i].arg1);
2794
2795 delete_event(ti);
2796 continue;
2797
2798 case BSC_thread_terminate:
2799 delete_map_entry(thread);
2800 continue;
2801
2802 case BSC_exit:
2803 continue;
2804
2805 case proc_exit:
2806 kd[i].arg1 = kd[i].arg2 >> 8;
2807 type = BSC_exit;
2808 break;
2809
2810 case BSC_mmap:
2811 if (kd[i].arg4 & MAP_ANON)
2812 continue;
2813 break;
2814
2815 case MACH_idle:
2816 case MACH_sched:
2817 case MACH_stkhandoff:
2818 mark_thread_waited(thread);
2819 continue;
2820
2821 case BC_IO_HIT:
2822 case BC_IO_HIT_STALLED:
2823 case BC_IO_MISS:
2824 case BC_IO_MISS_CUT_THROUGH:
2825 case BC_PLAYBACK_IO:
2826 if ((dio = find_diskio(kd[i].arg1)) != NULL)
2827 dio->bc_info = type;
2828 continue;
2829
2830 case HFS_modify_block_end:
2831 if ((ti = find_event(thread, 0))) {
2832 if (ti->nameptr)
2833 add_meta_name(kd[i].arg2, ti->nameptr);
2834 }
2835 continue;
2836
2837 case VFS_ALIAS_VP:
2838 add_vnode_name(kd[i].arg2, find_vnode_name(kd[i].arg1));
2839 continue;
2840
2841 case VFS_LOOKUP:
2842 if ((ti = find_event(thread, 0)) == (struct th_info *)0)
2843 continue;
2844
2845 if (debugid & DBG_FUNC_START) {
2846
2847 if (ti->in_hfs_update) {
2848 ti->pn_work_index = (MAX_PATHNAMES - 1);
2849 } else {
2850 if (ti->pn_scall_index < MAX_SCALL_PATHNAMES)
2851 ti->pn_work_index = ti->pn_scall_index;
2852 else
2853 continue;
2854 }
2855 sargptr = &ti->lookups[ti->pn_work_index].pathname[0];
2856
2857 ti->vnodeid = kd[i].arg1;
2858
2859 *sargptr++ = kd[i].arg2;
2860 *sargptr++ = kd[i].arg3;
2861 *sargptr++ = kd[i].arg4;
2862 /*
2863 * NULL terminate the 'string'
2864 */
2865 *sargptr = 0;
2866
2867 ti->pathptr = sargptr;
2868 } else {
2869 sargptr = ti->pathptr;
2870
2871 /*
2872 * We don't want to overrun our pathname buffer if the
2873 * kernel sends us more VFS_LOOKUP entries than we can
2874 * handle and we only handle 2 pathname lookups for
2875 * a given system call
2876 */
2877 if (sargptr == 0)
2878 continue;
2879
2880 if ((uintptr_t)sargptr < (uintptr_t)&ti->lookups[ti->pn_work_index].pathname[NUMPARMS]) {
2881
2882 *sargptr++ = kd[i].arg1;
2883 *sargptr++ = kd[i].arg2;
2884 *sargptr++ = kd[i].arg3;
2885 *sargptr++ = kd[i].arg4;
2886 /*
2887 * NULL terminate the 'string'
2888 */
2889 *sargptr = 0;
2890 }
2891 }
2892 if (debugid & DBG_FUNC_END) {
2893
2894 ti->nameptr = add_vnode_name(ti->vnodeid, &ti->lookups[ti->pn_work_index].pathname[0]);
2895
2896 if (ti->pn_work_index == ti->pn_scall_index) {
2897
2898 ti->pn_scall_index++;
2899
2900 if (ti->pn_scall_index < MAX_SCALL_PATHNAMES)
2901 ti->pathptr = &ti->lookups[ti->pn_scall_index].pathname[0];
2902 else
2903 ti->pathptr = 0;
2904 }
2905 } else
2906 ti->pathptr = sargptr;
2907
2908 continue;
2909 }
2910
2911 if (debugid & DBG_FUNC_START) {
2912 char * p;
2913
2914 if ((type & CLASS_MASK) == FILEMGR_BASE) {
2915
2916 index = filemgr_index(type);
2917
2918 if (index >= MAX_FILEMGR)
2919 continue;
2920
2921 if ((p = filemgr_calls[index].fm_name) == NULL)
2922 continue;
2923 } else
2924 p = NULL;
2925
2926 enter_event(thread, type, &kd[i], p, (double)now);
2927 continue;
2928 }
2929
2930 switch (type) {
2931
2932 case Throttled:
2933 exit_event(" THROTTLED", thread, type, 0, 0, 0, 0, FMT_DEFAULT, (double)now);
2934 continue;
2935
2936 case HFS_update:
2937 exit_event(" HFS_update", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, FMT_HFS_update, (double)now);
2938 continue;
2939
2940 case SPEC_unmap_info:
2941 if (check_filter_mode(NULL, SPEC_unmap_info, 0, 0, "SPEC_unmap_info"))
2942 format_print(NULL, " TrimExtent", thread, type, kd[i].arg1, kd[i].arg2, kd[i].arg3, 0, FMT_UNMAP_INFO, now, now, 0, "", NULL);
2943 continue;
2944
2945 case SPEC_ioctl:
2946 if (kd[i].arg2 == DKIOCSYNCHRONIZECACHE)
2947 exit_event("IOCTL", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, FMT_IOCTL_SYNC, (double)now);
2948 else if (kd[i].arg2 == DKIOCUNMAP)
2949 exit_event("IOCTL", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, FMT_IOCTL_UNMAP, (double)now);
2950 else {
2951 if ((ti = find_event(thread, type)))
2952 delete_event(ti);
2953 }
2954 continue;
2955
2956 case MACH_pageout:
2957 if (kd[i].arg2)
2958 exit_event("PAGE_OUT_ANON", thread, type, 0, kd[i].arg1, 0, 0, FMT_PGOUT, (double)now);
2959 else
2960 exit_event("PAGE_OUT_FILE", thread, type, 0, kd[i].arg1, 0, 0, FMT_PGOUT, (double)now);
2961 continue;
2962
2963 case MACH_vmfault:
2964 if (kd[i].arg4 == DBG_PAGEIN_FAULT)
2965 exit_event("PAGE_IN", thread, type, 0, kd[i].arg1, kd[i].arg2, 0, FMT_PGIN, (double)now);
2966 else if (kd[i].arg4 == DBG_PAGEINV_FAULT)
2967 exit_event("PAGE_IN_FILE", thread, type, 0, kd[i].arg1, kd[i].arg2, 0, FMT_PGIN, (double)now);
2968 else if (kd[i].arg4 == DBG_PAGEIND_FAULT)
2969 exit_event("PAGE_IN_ANON", thread, type, 0, kd[i].arg1, kd[i].arg2, 0, FMT_PGIN, (double)now);
2970 else if (kd[i].arg4 == DBG_CACHE_HIT_FAULT)
2971 exit_event("CACHE_HIT", thread, type, 0, kd[i].arg1, kd[i].arg2, 0, FMT_CACHEHIT, (double)now);
2972 else {
2973 if ((ti = find_event(thread, type)))
2974 delete_event(ti);
2975 }
2976 continue;
2977
2978 case MSC_map_fd:
2979 exit_event("map_fd", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, FMT_FD, (double)now);
2980 continue;
2981
2982 case BSC_mmap_extended:
2983 case BSC_mmap_extended2:
2984 case BSC_msync_extended:
2985 case BSC_pread_extended:
2986 case BSC_pwrite_extended:
2987 extend_syscall(thread, type, &kd[i]);
2988 continue;
2989 }
2990
2991 if ((type & CSC_MASK) == BSC_BASE) {
2992
2993 if ((index = BSC_INDEX(type)) >= MAX_BSD_SYSCALL)
2994 continue;
2995
2996 if (bsd_syscalls[index].sc_name) {
2997 exit_event(bsd_syscalls[index].sc_name, thread, type, kd[i].arg1, kd[i].arg2, kd[i].arg3, kd[i].arg4,
2998 bsd_syscalls[index].sc_format, (double)now);
2999
3000 if (type == BSC_exit)
3001 delete_map_entry(thread);
3002 }
3003 } else if ((type & CLASS_MASK) == FILEMGR_BASE) {
3004
3005 if ((index = filemgr_index(type)) >= MAX_FILEMGR)
3006 continue;
3007
3008 if (filemgr_calls[index].fm_name) {
3009 exit_event(filemgr_calls[index].fm_name, thread, type, kd[i].arg1, kd[i].arg2, kd[i].arg3, kd[i].arg4,
3010 FMT_DEFAULT, (double)now);
3011 }
3012 }
3013 }
3014 fflush(0);
3015}
3016
3017
3018void
3019enter_event_now(uintptr_t thread, int type, kd_buf *kd, char *name, double now)
3020{
3021 th_info_t ti;
3022 threadmap_t tme;
3023 int secs;
3024 int usecs;
3025 long long l_usecs;
3026 long curr_time;
3027 int clen = 0;
3028 int tsclen = 0;
3029 int nmclen = 0;
3030 int argsclen = 0;
3031 char buf[MAXWIDTH];
3032
3033 if ((ti = add_event(thread, type)) == NULL)
3034 return;
3035
3036 ti->stime = now;
3037 ti->arg1 = kd->arg1;
3038 ti->arg2 = kd->arg2;
3039 ti->arg3 = kd->arg3;
3040 ti->arg4 = kd->arg4;
3041
3042 switch (type) {
3043
3044 case HFS_update:
3045 ti->in_hfs_update = 1;
3046 break;
3047 }
3048
3049 if ((type & CLASS_MASK) == FILEMGR_BASE &&
3050 (!RAW_flag || (now >= start_time && now <= end_time))) {
3051
3052 filemgr_in_progress++;
3053 ti->in_filemgr = 1;
3054
3055 if (RAW_flag) {
3056 l_usecs = (long long)((now - bias_now) / divisor);
3057 l_usecs += (sample_TOD_secs * 1000000) + sample_TOD_usecs;
3058 } else
3059 l_usecs = (long long)(now / divisor);
3060 secs = l_usecs / 1000000;
3061 curr_time = bias_secs + secs;
3062
3063 sprintf(buf, "%-8.8s", &(ctime(&curr_time)[11]));
3064 tsclen = strlen(buf);
3065
3066 if (columns > MAXCOLS || wideflag) {
3067 usecs = l_usecs - (long long)((long long)secs * 1000000);
3068 sprintf(&buf[tsclen], ".%06ld", (long)usecs);
3069 tsclen = strlen(buf);
3070 }
3071
3072 /*
3073 * Print timestamp column
3074 */
3075 printf("%s", buf);
3076
3077 tme = find_map_entry(thread);
3078 if (tme) {
3079 sprintf(buf, " %-25.25s ", name);
3080 nmclen = strlen(buf);
3081 printf("%s", buf);
3082
3083 sprintf(buf, "(%d, 0x%lx, 0x%lx, 0x%lx)", (short)kd->arg1, kd->arg2, kd->arg3, kd->arg4);
3084 argsclen = strlen(buf);
3085
3086 /*
3087 * Calculate white space out to command
3088 */
3089 if (columns > MAXCOLS || wideflag) {
3090 clen = columns - (tsclen + nmclen + argsclen + 20 + 11);
3091 } else
3092 clen = columns - (tsclen + nmclen + argsclen + 12);
3093
3094 if (clen > 0) {
3095 printf("%s", buf); /* print the kdargs */
3096 memset(buf, ' ', clen);
3097 buf[clen] = '\0';
3098 printf("%s", buf);
3099 }
3100 else if ((argsclen + clen) > 0) {
3101 /*
3102 * no room so wipe out the kdargs
3103 */
3104 memset(buf, ' ', (argsclen + clen));
3105 buf[argsclen + clen] = '\0';
3106 printf("%s", buf);
3107 }
3108 if (columns > MAXCOLS || wideflag)
3109 printf("%s.%d\n", tme->tm_command, (int)thread);
3110 else
3111 printf("%-12.12s\n", tme->tm_command);
3112 } else
3113 printf(" %-24.24s (%5d, %#lx, 0x%lx, 0x%lx)\n", name, (short)kd->arg1, kd->arg2, kd->arg3, kd->arg4);
3114 }
3115}
3116
3117
3118void
3119enter_event(uintptr_t thread, int type, kd_buf *kd, char *name, double now)
3120{
3121 int index;
3122
3123 switch (type) {
3124
3125 case P_CS_SYNC_DISK:
3126 case MACH_pageout:
3127 case MACH_vmfault:
3128 case MSC_map_fd:
3129 case SPEC_ioctl:
3130 case Throttled:
3131 case HFS_update:
3132 enter_event_now(thread, type, kd, name, now);
3133 return;
3134
3135 }
3136 if ((type & CSC_MASK) == BSC_BASE) {
3137
3138 if ((index = BSC_INDEX(type)) >= MAX_BSD_SYSCALL)
3139 return;
3140
3141 if (bsd_syscalls[index].sc_name)
3142 enter_event_now(thread, type, kd, name, now);
3143 return;
3144 }
3145 if ((type & CLASS_MASK) == FILEMGR_BASE) {
3146
3147 if ((index = filemgr_index(type)) >= MAX_FILEMGR)
3148 return;
3149
3150 if (filemgr_calls[index].fm_name)
3151 enter_event_now(thread, type, kd, name, now);
3152 return;
3153 }
3154}
3155
3156/*
3157 * Handle system call extended trace data.
3158 * pread and pwrite:
3159 * Wipe out the kd args that were collected upon syscall_entry
3160 * because it is the extended info that we really want, and it
3161 * is all we really need.
3162*/
3163
3164void
3165extend_syscall(uintptr_t thread, int type, kd_buf *kd)
3166{
3167 th_info_t ti;
3168
3169 switch (type) {
3170 case BSC_mmap_extended:
3171 if ((ti = find_event(thread, BSC_mmap)) == (struct th_info *)0)
3172 return;
3173 ti->arg8 = ti->arg3; /* save protection */
3174 ti->arg1 = kd->arg1; /* the fd */
3175 ti->arg3 = kd->arg2; /* bottom half address */
3176 ti->arg5 = kd->arg3; /* bottom half size */
3177 break;
3178 case BSC_mmap_extended2:
3179 if ((ti = find_event(thread, BSC_mmap)) == (struct th_info *)0)
3180 return;
3181 ti->arg2 = kd->arg1; /* top half address */
3182 ti->arg4 = kd->arg2; /* top half size */
3183 ti->arg6 = kd->arg3; /* top half file offset */
3184 ti->arg7 = kd->arg4; /* bottom half file offset */
3185 break;
3186 case BSC_msync_extended:
3187 if ((ti = find_event(thread, BSC_msync)) == (struct th_info *)0) {
3188 if ((ti = find_event(thread, BSC_msync_nocancel)) == (struct th_info *)0)
3189 return;
3190 }
3191 ti->arg4 = kd->arg1; /* top half address */
3192 ti->arg5 = kd->arg2; /* top half size */
3193 break;
3194 case BSC_pread_extended:
3195 if ((ti = find_event(thread, BSC_pread)) == (struct th_info *)0) {
3196 if ((ti = find_event(thread, BSC_pread_nocancel)) == (struct th_info *)0)
3197 return;
3198 }
3199 ti->arg1 = kd->arg1; /* the fd */
3200 ti->arg2 = kd->arg2; /* nbytes */
3201 ti->arg3 = kd->arg3; /* top half offset */
3202 ti->arg4 = kd->arg4; /* bottom half offset */
3203 break;
3204 case BSC_pwrite_extended:
3205 if ((ti = find_event(thread, BSC_pwrite)) == (struct th_info *)0) {
3206 if ((ti = find_event(thread, BSC_pwrite_nocancel)) == (struct th_info *)0)
3207 return;
3208 }
3209 ti->arg1 = kd->arg1; /* the fd */
3210 ti->arg2 = kd->arg2; /* nbytes */
3211 ti->arg3 = kd->arg3; /* top half offset */
3212 ti->arg4 = kd->arg4; /* bottom half offset */
3213 break;
3214 default:
3215 return;
3216 }
3217}
3218
3219
3220void
3221exit_event(char *sc_name, uintptr_t thread, int type, uintptr_t arg1, uintptr_t arg2, uintptr_t arg3, uintptr_t arg4,
3222 int format, double now)
3223{
3224 th_info_t ti;
3225
3226 if ((ti = find_event(thread, type)) == (struct th_info *)0)
3227 return;
3228
3229 ti->nameptr = 0;
3230
3231 if (check_filter_mode(ti, type, arg1, arg2, sc_name))
3232 format_print(ti, sc_name, thread, type, arg1, arg2, arg3, arg4, format, now, ti->stime, ti->waited, (char *)&ti->lookups[0].pathname[0], NULL);
3233
3234 switch (type) {
3235
3236 case HFS_update:
3237 ti->in_hfs_update = 0;
3238 break;
3239 }
3240 if ((type & CLASS_MASK) == FILEMGR_BASE) {
3241 ti->in_filemgr = 0;
3242
3243 if (filemgr_in_progress > 0)
3244 filemgr_in_progress--;
3245 }
3246 delete_event(ti);
3247}
3248
3249
3250void
3251get_mode_nibble(char * buf, int smode, int special, char x_on, char x_off)
3252{
3253 if (smode & 04)
3254 buf[0] = 'r';
3255 if (smode & 02)
3256 buf[1] = 'w';
3257 if (smode & 01) {
3258 if (special)
3259 buf[2] = x_on;
3260 else
3261 buf[2] = 'x';
3262 } else {
3263 if (special)
3264 buf[2] = x_off;
3265 }
3266}
3267
3268
3269void
3270get_mode_string(int mode, char *buf)
3271{
3272 memset(buf, '-', 9);
3273 buf[9] = '\0';
3274
3275 get_mode_nibble(&buf[6], mode, (mode & 01000), 't', 'T');
3276 get_mode_nibble(&buf[3], (mode>>3), (mode & 02000), 's', 'S');
3277 get_mode_nibble(&buf[0], (mode>>6), (mode & 04000), 's', 'S');
3278}
3279
3280
3281int clip_64bit(char *s, uint64_t value)
3282{
3283 int clen = 0;
3284
3285 if ( (value & 0xff00000000000000LL) )
3286 clen = printf("%s0x%16.16qx", s, value);
3287 else if ( (value & 0x00ff000000000000LL) )
3288 clen = printf("%s0x%14.14qx ", s, value);
3289 else if ( (value & 0x0000ff0000000000LL) )
3290 clen = printf("%s0x%12.12qx ", s, value);
3291 else if ( (value & 0x000000ff00000000LL) )
3292 clen = printf("%s0x%10.10qx ", s, value);
3293 else
3294 clen = printf("%s0x%8.8qx ", s, value);
3295
3296 return (clen);
3297}
3298
3299
3300void
3301format_print(struct th_info *ti, char *sc_name, uintptr_t thread, int type, uintptr_t arg1, uintptr_t arg2, uintptr_t arg3, uintptr_t arg4,
3302 int format, double now, double stime, int waited, char *pathname, struct diskio *dio)
3303{
3304 int secs;
3305 int usecs;
3306 int nopadding = 0;
3307 long long l_usecs;
3308 long curr_time;
3309 char *command_name;
3310 int in_filemgr = 0;
3311 int len = 0;
3312 int clen = 0;
3313 int tlen = 0;
3314 int class;
3315 uint64_t user_addr;
3316 uint64_t user_size;
3317 char *framework_name;
3318 char *framework_type;
3319 char *p1;
3320 char *p2;
3321 char buf[MAXWIDTH];
3322 char cs_diskname[32];
3323
3324 static char timestamp[32];
3325 static int last_timestamp = -1;
3326 static int timestamp_len = 0;
3327
3328 command_name = "";
3329
3330 if (RAW_flag) {
3331 l_usecs = (long long)((now - bias_now) / divisor);
3332
3333 if ((double)l_usecs < start_time || (double)l_usecs > end_time)
3334 return;
3335
3336 l_usecs += (sample_TOD_secs * 1000000) + sample_TOD_usecs;
3337 }
3338 else
3339 l_usecs = (long long)(now / divisor);
3340 secs = l_usecs / 1000000;
3341 curr_time = bias_secs + secs;
3342
3343 class = type >> 24;
3344
3345 if (dio)
3346 command_name = dio->issuing_command;
3347 else {
3348 threadmap_t tme;
3349
3350 if ((tme = find_map_entry(thread)))
3351 command_name = tme->tm_command;
3352 }
3353 if (last_timestamp != curr_time) {
3354 timestamp_len = sprintf(timestamp, "%-8.8s", &(ctime(&curr_time)[11]));
3355 last_timestamp = curr_time;
3356 }
3357 if (columns > MAXCOLS || wideflag) {
3358 int usec;
3359
3360 tlen = timestamp_len;
3361 nopadding = 0;
3362 usec = (l_usecs - (long long)((long long)secs * 1000000));
3363
3364 sprintf(&timestamp[tlen], ".%06ld", (long)usec);
3365 tlen += 7;
3366
3367 timestamp[tlen] = '\0';
3368
3369 if (filemgr_in_progress) {
3370 if (class != FILEMGR_CLASS) {
3371 if (find_event(thread, -1))
3372 in_filemgr = 1;
3373 }
3374 }
3375 } else
3376 nopadding = 1;
3377
3378 if ((class == FILEMGR_CLASS) && (columns > MAXCOLS || wideflag))
3379 clen = printf("%s %-20.20s", timestamp, sc_name);
3380 else if (in_filemgr)
3381 clen = printf("%s %-15.15s", timestamp, sc_name);
3382 else
3383 clen = printf("%s %-17.17s", timestamp, sc_name);
3384
3385
3386 framework_name = NULL;
3387
3388 if (columns > MAXCOLS || wideflag) {
3389
3390 off_t offset_reassembled = 0LL;
3391
3392 switch (format) {
3393
3394 case FMT_AT:
3395 case FMT_RENAMEAT:
3396 case FMT_DEFAULT:
3397 /*
3398 * pathname based system calls or
3399 * calls with no fd or pathname (i.e. sync)
3400 */
3401 if (arg1)
3402 clen += printf(" [%3d] ", arg1);
3403 else
3404 clen += printf(" ");
3405 break;
3406
3407 case FMT_FD:
3408 /*
3409 * fd based system call... no I/O
3410 */
3411 if (arg1)
3412 clen += printf(" F=%-3d[%3d]", ti->arg1, arg1);
3413 else
3414 clen += printf(" F=%-3d", ti->arg1);
3415 break;
3416
3417 case FMT_FD_2:
3418 /*
3419 * accept, dup, dup2
3420 */
3421 if (arg1)
3422 clen += printf(" F=%-3d[%3d]", ti->arg1, arg1);
3423 else
3424 clen += printf(" F=%-3d F=%-3d", ti->arg1, arg2);
3425 break;
3426
3427 case FMT_FD_IO:
3428 /*
3429 * system calls with fd's that return an I/O completion count
3430 */
3431 if (arg1)
3432 clen += printf(" F=%-3d[%3d]", ti->arg1, arg1);
3433 else
3434 clen += printf(" F=%-3d B=0x%-6x", ti->arg1, arg2);
3435 break;
3436
3437 case FMT_PGIN:
3438 /*
3439 * pagein
3440 */
3441 user_addr = ((uint64_t)arg2 << 32) | (uint32_t)arg3;
3442
3443 lookup_name(user_addr, &framework_type, &framework_name);
3444 clen += clip_64bit(" A=", user_addr);
3445 break;
3446
3447 case FMT_CACHEHIT:
3448 /*
3449 * cache hit
3450 */
3451 user_addr = ((uint64_t)arg2 << 32) | (uint32_t)arg3;
3452
3453 lookup_name(user_addr, &framework_type, &framework_name);
3454 clen += clip_64bit(" A=", user_addr);
3455 break;
3456
3457 case FMT_PGOUT:
3458 /*
3459 * pageout
3460 */
3461 clen += printf(" B=0x%-8x", arg2);
3462 break;
3463
3464 case FMT_HFS_update:
3465 {
3466 char sbuf[7];
3467 int sflag = (int)arg2;
3468
3469 memset(sbuf, '_', 6);
3470 sbuf[6] = '\0';
3471
3472
3473 if (sflag & 0x10)
3474 sbuf[0] = 'F';
3475 if (sflag & 0x08)
3476 sbuf[1] = 'M';
3477 if (sflag & 0x20)
3478 sbuf[2] = 'D';
3479 if (sflag & 0x04)
3480 sbuf[3] = 'c';
3481 if (sflag & 0x01)
3482 sbuf[4] = 'a';
3483 if (sflag & 0x02)
3484 sbuf[5] = 'm';
3485
3486 clen += printf(" (%s) ", sbuf);
3487
3488 pathname = find_vnode_name(arg1);
3489 nopadding = 1;
3490
3491 break;
3492 }
3493
3494 case FMT_DISKIO:
3495 /*
3496 * physical disk I/O
3497 */
3498 if (dio->io_errno)
3499 clen += printf(" D=0x%8.8x [%3d]", dio->blkno, dio->io_errno);
3500 else {
3501 if (BC_flag)
3502 clen += printf(" D=0x%8.8x B=0x%-6x BC:%s /dev/%s ", dio->blkno, dio->iosize, BC_STR(dio->bc_info), find_disk_name(dio->dev));
3503 else
3504 clen += printf(" D=0x%8.8x B=0x%-6x /dev/%s ", dio->blkno, dio->iosize, find_disk_name(dio->dev));
3505
3506 if (dio->is_meta) {
3507 if (!(type & P_DISKIO_READ))
3508 pathname = find_meta_name(dio->blkno);
3509 } else
3510 pathname = find_vnode_name(dio->vnodeid);
3511 nopadding = 1;
3512 }
3513 break;
3514
3515 case FMT_DISKIO_CS:
3516 /*
3517 * physical disk I/O
3518 */
3519 if (dio->io_errno)
3520 clen += printf(" D=0x%8.8x [%3d]", dio->blkno, dio->io_errno);
3521 else
3522 clen += printf(" D=0x%8.8x B=0x%-6x /dev/%s", dio->blkno, dio->iosize, generate_cs_disk_name(dio->dev, &cs_diskname[0]));
3523 break;
3524
3525 case FMT_SYNC_DISK_CS:
3526 /*
3527 * physical disk sync cache
3528 */
3529 clen += printf(" /dev/%s", generate_cs_disk_name(arg1, &cs_diskname[0]));
3530
3531 break;
3532
3533 case FMT_MSYNC:
3534 {
3535 /*
3536 * msync
3537 */
3538 int mlen = 0;
3539
3540 buf[0] = '\0';
3541
3542 if (ti->arg3 & MS_ASYNC)
3543 mlen += sprintf(&buf[mlen], "MS_ASYNC | ");
3544 else
3545 mlen += sprintf(&buf[mlen], "MS_SYNC | ");
3546
3547 if (ti->arg3 & MS_INVALIDATE)
3548 mlen += sprintf(&buf[mlen], "MS_INVALIDATE | ");
3549 if (ti->arg3 & MS_KILLPAGES)
3550 mlen += sprintf(&buf[mlen], "MS_KILLPAGES | ");
3551 if (ti->arg3 & MS_DEACTIVATE)
3552 mlen += sprintf(&buf[mlen], "MS_DEACTIVATE | ");
3553
3554 if (ti->arg3 & ~(MS_ASYNC | MS_SYNC | MS_INVALIDATE | MS_KILLPAGES | MS_DEACTIVATE))
3555 mlen += sprintf(&buf[mlen], "UNKNOWN | ");
3556
3557 if (mlen)
3558 buf[mlen - 3] = '\0';
3559
3560 if (arg1)
3561 clen += printf(" [%3d]", arg1);
3562
3563 user_addr = (((off_t)(unsigned int)(ti->arg4)) << 32) | (unsigned int)(ti->arg1);
3564 clen += clip_64bit(" A=", user_addr);
3565
3566 user_size = (((off_t)(unsigned int)(ti->arg5)) << 32) | (unsigned int)(ti->arg2);
3567
3568 clen += printf(" B=0x%-16qx <%s>", user_size, buf);
3569
3570 break;
3571 }
3572
3573 case FMT_FLOCK:
3574 {
3575 /*
3576 * flock
3577 */
3578 int mlen = 0;
3579
3580 buf[0] = '\0';
3581
3582 if (ti->arg2 & LOCK_SH)
3583 mlen += sprintf(&buf[mlen], "LOCK_SH | ");
3584 if (ti->arg2 & LOCK_EX)
3585 mlen += sprintf(&buf[mlen], "LOCK_EX | ");
3586 if (ti->arg2 & LOCK_NB)
3587 mlen += sprintf(&buf[mlen], "LOCK_NB | ");
3588 if (ti->arg2 & LOCK_UN)
3589 mlen += sprintf(&buf[mlen], "LOCK_UN | ");
3590
3591 if (ti->arg2 & ~(LOCK_SH | LOCK_EX | LOCK_NB | LOCK_UN))
3592 mlen += sprintf(&buf[mlen], "UNKNOWN | ");
3593
3594 if (mlen)
3595 buf[mlen - 3] = '\0';
3596
3597 if (arg1)
3598 clen += printf(" F=%-3d[%3d] <%s>", ti->arg1, arg1, buf);
3599 else
3600 clen += printf(" F=%-3d <%s>", ti->arg1, buf);
3601
3602 break;
3603 }
3604
3605 case FMT_FCNTL:
3606 {
3607 /*
3608 * fcntl
3609 */
3610 char *p = NULL;
3611 int fd = -1;
3612
3613 if (arg1)
3614 clen += printf(" F=%-3d[%3d]", ti->arg1, arg1);
3615 else
3616 clen += printf(" F=%-3d", ti->arg1);
3617
3618 switch(ti->arg2) {
3619
3620 case F_DUPFD:
3621 p = "DUPFD";
3622 break;
3623
3624 case F_GETFD:
3625 p = "GETFD";
3626 break;
3627
3628 case F_SETFD:
3629 p = "SETFD";
3630 break;
3631
3632 case F_GETFL:
3633 p = "GETFL";
3634 break;
3635
3636 case F_SETFL:
3637 p = "SETFL";
3638 break;
3639
3640 case F_GETOWN:
3641 p = "GETOWN";
3642 break;
3643
3644 case F_SETOWN:
3645 p = "SETOWN";
3646 break;
3647
3648 case F_GETLK:
3649 p = "GETLK";
3650 break;
3651
3652 case F_SETLK:
3653 p = "SETLK";
3654 break;
3655
3656 case F_SETLKW:
3657 p = "SETLKW";
3658 break;
3659
3660 case F_PREALLOCATE:
3661 p = "PREALLOCATE";
3662 break;
3663
3664 case F_SETSIZE:
3665 p = "SETSIZE";
3666 break;
3667
3668 case F_RDADVISE:
3669 p = "RDADVISE";
3670 break;
3671
3672 case F_GETPATH:
3673 p = "GETPATH";
3674 break;
3675
3676 case F_FULLFSYNC:
3677 p = "FULLFSYNC";
3678 break;
3679
3680 case F_PATHPKG_CHECK:
3681 p = "PATHPKG_CHECK";
3682 break;
3683
3684 case F_OPENFROM:
3685 p = "OPENFROM";
3686
3687 if (arg1 == 0)
3688 fd = arg2;
3689 break;
3690
3691 case F_UNLINKFROM:
3692 p = "UNLINKFROM";
3693 break;
3694
3695 case F_CHECK_OPENEVT:
3696 p = "CHECK_OPENEVT";
3697 break;
3698
3699 case F_NOCACHE:
3700 if (ti->arg3)
3701 p = "CACHING OFF";
3702 else
3703 p = "CACHING ON";
3704 break;
3705
3706 case F_GLOBAL_NOCACHE:
3707 if (ti->arg3)
3708 p = "CACHING OFF (GLOBAL)";
3709 else
3710 p = "CACHING ON (GLOBAL)";
3711 break;
3712
3713 }
3714 if (p) {
3715 if (fd == -1)
3716 clen += printf(" <%s>", p);
3717 else
3718 clen += printf(" <%s> F=%d", p, fd);
3719 } else
3720 clen += printf(" <CMD=%d>", ti->arg2);
3721
3722 break;
3723 }
3724
3725 case FMT_IOCTL:
3726 {
3727 /*
3728 * ioctl
3729 */
3730 if (arg1)
3731 clen += printf(" F=%-3d[%3d]", ti->arg1, arg1);
3732 else
3733 clen += printf(" F=%-3d", ti->arg1);
3734
3735 clen += printf(" <CMD=0x%x>", ti->arg2);
3736
3737 break;
3738 }
3739
3740 case FMT_IOCTL_SYNC:
3741 {
3742 /*
3743 * ioctl
3744 */
3745 clen += printf(" <DKIOCSYNCHRONIZECACHE> /dev/%s", find_disk_name(arg1));
3746
3747 break;
3748 }
3749
3750 case FMT_IOCTL_UNMAP:
3751 {
3752 /*
3753 * ioctl
3754 */
3755 clen += printf(" <DKIOCUNMAP> /dev/%s", find_disk_name(arg1));
3756
3757 break;
3758 }
3759
3760 case FMT_UNMAP_INFO:
3761 {
3762 clen += printf(" D=0x%8.8x B=0x%-6x /dev/%s", arg2, arg3, find_disk_name(arg1));
3763
3764 break;
3765 }
3766
3767 case FMT_SELECT:
3768 /*
3769 * select
3770 */
3771 if (arg1)
3772 clen += printf(" [%3d]", arg1);
3773 else
3774 clen += printf(" S=%-3d", arg2);
3775
3776 break;
3777
3778 case FMT_LSEEK:
3779 case FMT_PREAD:
3780 /*
3781 * pread, pwrite, lseek
3782 */
3783 clen += printf(" F=%-3d", ti->arg1);
3784
3785 if (arg1)
3786 clen += printf("[%3d] ", arg1);
3787 else {
3788 if (format == FMT_PREAD)
3789 clen += printf(" B=0x%-8x ", arg2);
3790 else
3791 clen += printf(" ");
3792 }
3793 if (format == FMT_PREAD)
3794 offset_reassembled = (((off_t)(unsigned int)(ti->arg3)) << 32) | (unsigned int)(ti->arg4);
3795 else
3796#ifdef __ppc__
3797 offset_reassembled = (((off_t)(unsigned int)(arg2)) << 32) | (unsigned int)(arg3);
3798#else
3799 offset_reassembled = (((off_t)(unsigned int)(arg3)) << 32) | (unsigned int)(arg2);
3800#endif
3801 clen += clip_64bit("O=", offset_reassembled);
3802
3803 if (format == FMT_LSEEK) {
3804 char *mode;
3805
3806 if (ti->arg4 == SEEK_SET)
3807 mode = "SEEK_SET";
3808 else if (ti->arg4 == SEEK_CUR)
3809 mode = "SEEK_CUR";
3810 else if (ti->arg4 == SEEK_END)
3811 mode = "SEEK_END";
3812 else
3813 mode = "UNKNOWN";
3814
3815 clen += printf(" <%s>", mode);
3816 }
3817 break;
3818
3819 case FMT_MMAP:
3820 /*
3821 * mmap
3822 */
3823 clen += printf(" F=%-3d ", ti->arg1);
3824
3825 if (arg1)
3826 clen += printf("[%3d] ", arg1);
3827 else {
3828
3829 user_addr = (((off_t)(unsigned int)(ti->arg2)) << 32) | (unsigned int)(ti->arg3);
3830
3831 clen += clip_64bit("A=", user_addr);
3832
3833 offset_reassembled = (((off_t)(unsigned int)(ti->arg6)) << 32) | (unsigned int)(ti->arg7);
3834
3835 clen += clip_64bit("O=", offset_reassembled);
3836
3837 user_size = (((off_t)(unsigned int)(ti->arg4)) << 32) | (unsigned int)(ti->arg5);
3838
3839 clen += printf("B=0x%-16qx", user_size);
3840
3841 clen += printf(" <");
3842
3843 if (ti->arg8 & PROT_READ)
3844 clen += printf("READ");
3845
3846 if (ti->arg8 & PROT_WRITE)
3847 clen += printf("|WRITE");
3848
3849 if (ti->arg8 & PROT_EXEC)
3850 clen += printf("|EXEC");
3851
3852 clen += printf(">");
3853 }
3854 break;
3855
3856 case FMT_TRUNC:
3857 case FMT_FTRUNC:
3858 /*
3859 * ftruncate, truncate
3860 */
3861 if (format == FMT_FTRUNC)
3862 clen += printf(" F=%-3d", ti->arg1);
3863 else
3864 clen += printf(" ");
3865
3866 if (arg1)
3867 clen += printf("[%3d]", arg1);
3868
3869#ifdef __ppc__
3870 offset_reassembled = (((off_t)(unsigned int)(ti->arg2)) << 32) | (unsigned int)(ti->arg3);
3871#else
3872 offset_reassembled = (((off_t)(unsigned int)(ti->arg3)) << 32) | (unsigned int)(ti->arg2);
3873#endif
3874 clen += clip_64bit(" O=", offset_reassembled);
3875
3876 nopadding = 1;
3877 break;
3878
3879 case FMT_FCHFLAGS:
3880 case FMT_CHFLAGS:
3881 {
3882 /*
3883 * fchflags, chflags
3884 */
3885 int mlen = 0;
3886
3887 if (format == FMT_FCHFLAGS) {
3888 if (arg1)
3889 clen += printf(" F=%-3d[%3d]", ti->arg1, arg1);
3890 else
3891 clen += printf(" F=%-3d", ti->arg1);
3892 } else {
3893 if (arg1)
3894 clen += printf(" [%3d] ", arg1);
3895 }
3896 buf[mlen++] = ' ';
3897 buf[mlen++] = '<';
3898
3899 if (ti->arg2 & UF_NODUMP)
3900 mlen += sprintf(&buf[mlen], "UF_NODUMP | ");
3901 if (ti->arg2 & UF_IMMUTABLE)
3902 mlen += sprintf(&buf[mlen], "UF_IMMUTABLE | ");
3903 if (ti->arg2 & UF_APPEND)
3904 mlen += sprintf(&buf[mlen], "UF_APPEND | ");
3905 if (ti->arg2 & UF_OPAQUE)
3906 mlen += sprintf(&buf[mlen], "UF_OPAQUE | ");
3907 if (ti->arg2 & SF_ARCHIVED)
3908 mlen += sprintf(&buf[mlen], "SF_ARCHIVED | ");
3909 if (ti->arg2 & SF_IMMUTABLE)
3910 mlen += sprintf(&buf[mlen], "SF_IMMUTABLE | ");
3911 if (ti->arg2 & SF_APPEND)
3912 mlen += sprintf(&buf[mlen], "SF_APPEND | ");
3913
3914 if (ti->arg2 == 0)
3915 mlen += sprintf(&buf[mlen], "CLEAR_ALL_FLAGS | ");
3916 else if (ti->arg2 & ~(UF_NODUMP | UF_IMMUTABLE | UF_APPEND | SF_ARCHIVED | SF_IMMUTABLE | SF_APPEND))
3917 mlen += sprintf(&buf[mlen], "UNKNOWN | ");
3918
3919 if (mlen >= 3)
3920 mlen -= 3;
3921
3922 buf[mlen++] = '>';
3923 buf[mlen] = '\0';
3924
3925 if (mlen < 19) {
3926 memset(&buf[mlen], ' ', 19 - mlen);
3927 mlen = 19;
3928 }
3929 clen += printf("%s", buf);
3930
3931 nopadding = 1;
3932 break;
3933 }
3934
3935 case FMT_UMASK:
3936 case FMT_FCHMOD:
3937 case FMT_FCHMOD_EXT:
3938 case FMT_CHMOD:
3939 case FMT_CHMOD_EXT:
3940 case FMT_CHMODAT:
3941 {
3942 /*
3943 * fchmod, fchmod_extended, chmod, chmod_extended
3944 */
3945 int mode;
3946
3947 if (format == FMT_FCHMOD || format == FMT_FCHMOD_EXT) {
3948 if (arg1)
3949 clen += printf(" F=%-3d[%3d] ", ti->arg1, arg1);
3950 else
3951 clen += printf(" F=%-3d ", ti->arg1);
3952 } else {
3953 if (arg1)
3954 clen += printf(" [%3d] ", arg1);
3955 else
3956 clen += printf(" ");
3957 }
3958 if (format == FMT_UMASK)
3959 mode = ti->arg1;
3960 else if (format == FMT_FCHMOD || format == FMT_CHMOD || format == FMT_CHMODAT)
3961 mode = ti->arg2;
3962 else
3963 mode = ti->arg4;
3964
3965 get_mode_string(mode, &buf[0]);
3966
3967 if (arg1 == 0)
3968 clen += printf("<%s> ", buf);
3969 else
3970 clen += printf("<%s>", buf);
3971 break;
3972 }
3973
3974 case FMT_ACCESS:
3975 {
3976 /*
3977 * access
3978 */
3979 char mode[5];
3980
3981 memset(mode, '_', 4);
3982 mode[4] = '\0';
3983
3984 if (ti->arg2 & R_OK)
3985 mode[0] = 'R';
3986 if (ti->arg2 & W_OK)
3987 mode[1] = 'W';
3988 if (ti->arg2 & X_OK)
3989 mode[2] = 'X';
3990 if (ti->arg2 == F_OK)
3991 mode[3] = 'F';
3992
3993 if (arg1)
3994 clen += printf(" [%3d] (%s) ", arg1, mode);
3995 else
3996 clen += printf(" (%s) ", mode);
3997
3998 nopadding = 1;
3999 break;
4000 }
4001
4002 case FMT_MOUNT:
4003 {
4004 if (arg1)
4005 clen += printf(" [%3d] <FLGS=0x%x> ", arg1, ti->arg3);
4006 else
4007 clen += printf(" <FLGS=0x%x> ", ti->arg3);
4008
4009 nopadding = 1;
4010 break;
4011 }
4012
4013 case FMT_UNMOUNT:
4014 {
4015 char *mountflag;
4016
4017 if (ti->arg2 & MNT_FORCE)
4018 mountflag = "<FORCE>";
4019 else
4020 mountflag = "";
4021
4022 if (arg1)
4023 clen += printf(" [%3d] %s ", arg1, mountflag);
4024 else
4025 clen += printf(" %s ", mountflag);
4026
4027 nopadding = 1;
4028 break;
4029 }
4030
4031 case FMT_OPENAT:
4032 case FMT_OPEN:
4033 {
4034 /*
4035 * open
4036 */
4037 char mode[7];
4038
4039 memset(mode, '_', 6);
4040 mode[6] = '\0';
4041
4042 if (ti->arg2 & O_RDWR) {
4043 mode[0] = 'R';
4044 mode[1] = 'W';
4045 } else if (ti->arg2 & O_WRONLY)
4046 mode[1] = 'W';
4047 else
4048 mode[0] = 'R';
4049
4050 if (ti->arg2 & O_CREAT)
4051 mode[2] = 'C';
4052
4053 if (ti->arg2 & O_APPEND)
4054 mode[3] = 'A';
4055
4056 if (ti->arg2 & O_TRUNC)
4057 mode[4] = 'T';
4058
4059 if (ti->arg2 & O_EXCL)
4060 mode[5] = 'E';
4061
4062 if (arg1)
4063 clen += printf(" [%3d] (%s) ", arg1, mode);
4064 else
4065 clen += printf(" F=%-3d (%s) ", arg2, mode);
4066
4067 nopadding = 1;
4068 break;
4069 }
4070
4071 case FMT_SOCKET:
4072 {
4073 /*
4074 * socket
4075 *
4076 */
4077 char *domain;
4078 char *type;
4079
4080 switch (ti->arg1) {
4081
4082 case AF_UNIX:
4083 domain = "AF_UNIX";
4084 break;
4085
4086 case AF_INET:
4087 domain = "AF_INET";
4088 break;
4089
4090 case AF_ISO:
4091 domain = "AF_ISO";
4092 break;
4093
4094 case AF_NS:
4095 domain = "AF_NS";
4096 break;
4097
4098 case AF_IMPLINK:
4099 domain = "AF_IMPLINK";
4100 break;
4101
4102 default:
4103 domain = "UNKNOWN";
4104 break;
4105 }
4106
4107 switch (ti->arg2) {
4108
4109 case SOCK_STREAM:
4110 type = "SOCK_STREAM";
4111 break;
4112
4113 case SOCK_DGRAM:
4114 type = "SOCK_DGRAM";
4115 break;
4116
4117 case SOCK_RAW:
4118 type = "SOCK_RAW";
4119 break;
4120
4121 case SOCK_SEQPACKET:
4122 type = "SOCK_SEQPACKET";
4123 break;
4124
4125 case SOCK_RDM:
4126 type = "SOCK_RDM";
4127 break;
4128
4129 default:
4130 type = "UNKNOWN";
4131 break;
4132 }
4133
4134 if (arg1)
4135 clen += printf(" [%3d] <%s, %s, 0x%x>", arg1, domain, type, ti->arg3);
4136 else
4137 clen += printf(" F=%-3d <%s, %s, 0x%x>", arg2, domain, type, ti->arg3);
4138 break;
4139 }
4140
4141 case FMT_AIO_FSYNC:
4142 {
4143 /*
4144 * aio_fsync [errno] AIOCBP OP
4145 */
4146 char *op;
4147
4148 if (ti->arg1 == O_SYNC || ti->arg1 == 0)
4149 op = "AIO_FSYNC";
4150#if O_DSYNC
4151 else if (ti->arg1 == O_DSYNC)
4152 op = "AIO_DSYNC";
4153#endif
4154 else
4155 op = "UNKNOWN";
4156
4157 if (arg1)
4158 clen += printf(" [%3d] P=0x%8.8x <%s>", arg1, ti->arg2, op);
4159 else
4160 clen += printf(" P=0x%8.8x <%s>", ti->arg2, op);
4161 break;
4162 }
4163
4164 case FMT_AIO_RETURN:
4165 /*
4166 * aio_return [errno] AIOCBP IOSIZE
4167 */
4168 if (arg1)
4169 clen += printf(" [%3d] P=0x%8.8x", arg1, ti->arg1);
4170 else
4171 clen += printf(" P=0x%8.8x B=0x%-8x", ti->arg1, arg2);
4172 break;
4173
4174 case FMT_AIO_SUSPEND:
4175 /*
4176 * aio_suspend [errno] NENTS
4177 */
4178 if (arg1)
4179 clen += printf(" [%3d] N=%d", arg1, ti->arg2);
4180 else
4181 clen += printf(" N=%d", ti->arg2);
4182 break;
4183
4184 case FMT_AIO_CANCEL:
4185 /*
4186 * aio_cancel [errno] FD or AIOCBP (if non-null)
4187 */
4188 if (ti->arg2) {
4189 if (arg1)
4190 clen += printf(" [%3d] P=0x%8.8x", arg1, ti->arg2);
4191 else
4192 clen += printf(" P=0x%8.8x", ti->arg2);
4193 } else {
4194 if (arg1)
4195 clen += printf(" F=%-3d[%3d]", ti->arg1, arg1);
4196 else
4197 clen += printf(" F=%-3d", ti->arg1);
4198 }
4199 break;
4200
4201 case FMT_AIO:
4202 /*
4203 * aio_error, aio_read, aio_write [errno] AIOCBP
4204 */
4205 if (arg1)
4206 clen += printf(" [%3d] P=0x%8.8x", arg1, ti->arg1);
4207 else
4208 clen += printf(" P=0x%8.8x", ti->arg1);
4209 break;
4210
4211 case FMT_LIO_LISTIO:
4212 {
4213 /*
4214 * lio_listio [errno] NENTS MODE
4215 */
4216 char *op;
4217
4218 if (ti->arg1 == LIO_NOWAIT)
4219 op = "LIO_NOWAIT";
4220 else if (ti->arg1 == LIO_WAIT)
4221 op = "LIO_WAIT";
4222 else
4223 op = "UNKNOWN";
4224
4225 if (arg1)
4226 clen += printf(" [%3d] N=%d <%s>", arg1, ti->arg3, op);
4227 else
4228 clen += printf(" N=%d <%s>", ti->arg3, op);
4229 break;
4230 }
4231
4232 }
4233 }
4234
4235 /*
4236 * Calculate space available to print pathname
4237 */
4238 if (columns > MAXCOLS || wideflag)
4239 clen = columns - (clen + 14 + 20 + 11);
4240 else
4241 clen = columns - (clen + 14 + 12);
4242
4243 if (class != FILEMGR_CLASS && !nopadding)
4244 clen -= 3;
4245
4246 if (framework_name)
4247 len = sprintf(&buf[0], " %s %s ", framework_type, framework_name);
4248 else if (*pathname != '\0') {
4249 switch(format) {
4250 case FMT_AT:
4251 case FMT_OPENAT:
4252 case FMT_CHMODAT:
4253 len = sprintf(&buf[0], " [%d]/%s ", ti->arg1, pathname);
4254 break;
4255 case FMT_RENAMEAT:
4256 len = sprintf(&buf[0], " [%d]/%s ", ti->arg3, pathname);
4257 break;
4258 default:
4259 len = sprintf(&buf[0], " %s ", pathname);
4260 }
4261
4262 if (format == FMT_MOUNT && ti->lookups[1].pathname[0]) {
4263 int len2;
4264
4265 memset(&buf[len], ' ', 2);
4266
4267 len2 = sprintf(&buf[len+2], " %s ", (char *)&ti->lookups[1].pathname[0]);
4268 len = len + 2 + len2;
4269 }
4270 } else
4271 len = 0;
4272
4273 if (clen > len) {
4274 /*
4275 * Add null padding if column length
4276 * is wider than the pathname length.
4277 */
4278 memset(&buf[len], ' ', clen - len);
4279 buf[clen] = '\0';
4280
4281 pathname = buf;
4282
4283 } else if (clen == len) {
4284 pathname = buf;
4285
4286 } else if ((clen > 0) && (clen < len)) {
4287 /*
4288 * This prints the tail end of the pathname
4289 */
4290 buf[len-clen] = ' ';
4291
4292 pathname = &buf[len - clen];
4293
4294 } else {
4295 pathname = "";
4296 }
4297
4298 /*
4299 * fudge some additional system call overhead
4300 * that currently isn't tracked... this also
4301 * insures that we see a minimum of 1 us for
4302 * an elapsed time
4303 */
4304 usecs = (unsigned long)(((now - stime) + (divisor-1)) / divisor);
4305 secs = usecs / 1000000;
4306 usecs -= secs * 1000000;
4307
4308 if (class != FILEMGR_CLASS && !nopadding)
4309 p1 = " ";
4310 else
4311 p1 = "";
4312
4313 if (waited)
4314 p2 = " W";
4315 else
4316 p2 = " ";
4317
4318 if (columns > MAXCOLS || wideflag)
4319 printf("%s%s %3ld.%06ld%s %s.%d\n", p1, pathname, (unsigned long)secs, (unsigned long)usecs, p2, command_name, (int)thread);
4320 else
4321 printf("%s%s %3ld.%06ld%s %-12.12s\n", p1, pathname, (unsigned long)secs, (unsigned long)usecs, p2, command_name);
4322}
4323
4324
4325void
4326add_meta_name(uint64_t blockno, char *pathname) {
4327 meta_info_t mi;
4328 int hashid;
4329
4330 hashid = blockno & VN_HASH_MASK;
4331
4332 for (mi = m_info_hash[hashid]; mi; mi = mi->m_next) {
4333 if (mi->m_blkno == blockno)
4334 break;
4335 }
4336 if (mi == NULL) {
4337 mi = (meta_info_t)malloc(sizeof(struct meta_info));
4338
4339 mi->m_next = m_info_hash[hashid];
4340 m_info_hash[hashid] = mi;
4341 mi->m_blkno = blockno;
4342 }
4343 mi->m_nameptr = pathname;
4344}
4345
4346char *
4347find_meta_name(uint64_t blockno) {
4348 meta_info_t mi;
4349 int hashid;
4350
4351 hashid = blockno & VN_HASH_MASK;
4352
4353 for (mi = m_info_hash[hashid]; mi; mi = mi->m_next) {
4354 if (mi->m_blkno == blockno)
4355 return (mi->m_nameptr);
4356 }
4357 return ("");
4358}
4359
4360
4361char *
4362add_vnode_name(uint64_t vn_id, char *pathname) {
4363 vnode_info_t vn;
4364 int hashid;
4365
4366 hashid = (vn_id >> VN_HASH_SHIFT) & VN_HASH_MASK;
4367
4368 for (vn = vn_info_hash[hashid]; vn; vn = vn->vn_next) {
4369 if (vn->vn_id == vn_id)
4370 break;
4371 }
4372 if (vn == NULL) {
4373 vn = (vnode_info_t)malloc(sizeof(struct vnode_info));
4374
4375 vn->vn_next = vn_info_hash[hashid];
4376 vn_info_hash[hashid] = vn;
4377 vn->vn_id = vn_id;
4378 }
4379 strcpy(vn->vn_pathname, pathname);
4380
4381 return (&vn->vn_pathname);
4382}
4383
4384
4385char *
4386find_vnode_name(uint64_t vn_id) {
4387 vnode_info_t vn;
4388 int hashid;
4389
4390 hashid = (vn_id >> VN_HASH_SHIFT) & VN_HASH_MASK;
4391
4392 for (vn = vn_info_hash[hashid]; vn; vn = vn->vn_next) {
4393 if (vn->vn_id == vn_id)
4394 return (vn->vn_pathname);
4395 }
4396 return ("");
4397}
4398
4399
4400void
4401delete_event(th_info_t ti_to_delete) {
4402 th_info_t ti;
4403 th_info_t ti_prev;
4404 int hashid;
4405
4406 hashid = ti_to_delete->thread & HASH_MASK;
4407
4408 if ((ti = th_info_hash[hashid])) {
4409 if (ti == ti_to_delete)
4410 th_info_hash[hashid] = ti->next;
4411 else {
4412 ti_prev = ti;
4413
4414 for (ti = ti->next; ti; ti = ti->next) {
4415 if (ti == ti_to_delete) {
4416 ti_prev->next = ti->next;
4417 break;
4418 }
4419 ti_prev = ti;
4420 }
4421 }
4422 if (ti) {
4423 ti->next = th_info_freelist;
4424 th_info_freelist = ti;
4425 }
4426 }
4427}
4428
4429th_info_t
4430add_event(uintptr_t thread, int type) {
4431 th_info_t ti;
4432 int i;
4433 int hashid;
4434
4435 if ((ti = th_info_freelist))
4436 th_info_freelist = ti->next;
4437 else
4438 ti = (th_info_t)malloc(sizeof(struct th_info));
4439
4440 hashid = thread & HASH_MASK;
4441
4442 ti->next = th_info_hash[hashid];
4443 th_info_hash[hashid] = ti;
4444
4445 ti->thread = thread;
4446 ti->type = type;
4447
4448 ti->waited = 0;
4449 ti->in_filemgr = 0;
4450 ti->in_hfs_update = 0;
4451
4452 ti->pathptr = &ti->lookups[0].pathname[0];
4453 ti->pn_scall_index = 0;
4454 ti->pn_work_index = 0;
4455
4456 for (i = 0; i < MAX_PATHNAMES; i++)
4457 ti->lookups[i].pathname[0] = 0;
4458
4459 return (ti);
4460}
4461
4462th_info_t
4463find_event(uintptr_t thread, int type) {
4464 th_info_t ti;
4465 int hashid;
4466
4467 hashid = thread & HASH_MASK;
4468
4469 for (ti = th_info_hash[hashid]; ti; ti = ti->next) {
4470 if (ti->thread == thread) {
4471 if (type == ti->type)
4472 return (ti);
4473 if (ti->in_filemgr) {
4474 if (type == -1)
4475 return (ti);
4476 continue;
4477 }
4478 if (type == 0)
4479 return (ti);
4480 }
4481 }
4482 return ((th_info_t) 0);
4483}
4484
4485void
4486delete_all_events() {
4487 th_info_t ti = 0;
4488 th_info_t ti_next = 0;
4489 int i;
4490
4491 for (i = 0; i < HASH_SIZE; i++) {
4492
4493 for (ti = th_info_hash[i]; ti; ti = ti_next) {
4494 ti_next = ti->next;
4495 ti->next = th_info_freelist;
4496 th_info_freelist = ti;
4497 }
4498 th_info_hash[i] = 0;
4499 }
4500}
4501
4502
4503void
4504mark_thread_waited(uintptr_t thread) {
4505 th_info_t ti;
4506 int hashid;
4507
4508 hashid = thread & HASH_MASK;
4509
4510 for (ti = th_info_hash[hashid]; ti; ti = ti->next) {
4511 if (ti->thread == thread)
4512 ti->waited = 1;
4513 }
4514}
4515
4516
4517void read_command_map()
4518{
4519 size_t size;
4520 int i;
4521 int total_threads = 0;
4522 kd_threadmap *mapptr = 0;
4523
4524 delete_all_map_entries();
4525
4526 if (!RAW_flag) {
4527
4528 total_threads = bufinfo.nkdthreads;
4529 size = bufinfo.nkdthreads * sizeof(kd_threadmap);
4530
4531 if (size) {
4532 if ((mapptr = (kd_threadmap *) malloc(size))) {
4533 int mib[6];
4534
4535 bzero (mapptr, size);
4536 /*
4537 * Now read the threadmap
4538 */
4539 mib[0] = CTL_KERN;
4540 mib[1] = KERN_KDEBUG;
4541 mib[2] = KERN_KDTHRMAP;
4542 mib[3] = 0;
4543 mib[4] = 0;
4544 mib[5] = 0; /* no flags */
4545
4546 if (sysctl(mib, 3, mapptr, &size, NULL, 0) < 0) {
4547 /*
4548 * This is not fatal -- just means I cant map command strings
4549 */
4550 free(mapptr);
4551 return;
4552 }
4553 }
4554 }
4555 } else {
4556 RAW_header header;
4557 off_t offset;
4558
4559 RAW_fd = open(RAW_file, O_RDONLY);
4560
4561 if (RAW_fd < 0) {
4562 perror("Can't open RAW file");
4563 exit(1);
4564 }
4565 if (read(RAW_fd, &header, sizeof(RAW_header)) != sizeof(RAW_header)) {
4566 perror("read failed");
4567 exit(2);
4568 }
4569 if (header.version_no != RAW_VERSION1) {
4570 header.version_no = RAW_VERSION0;
4571 header.TOD_secs = time((long *)0);
4572 header.TOD_usecs = 0;
4573
4574 lseek(RAW_fd, (off_t)0, SEEK_SET);
4575
4576 if (read(RAW_fd, &header.thread_count, sizeof(int)) != sizeof(int)) {
4577 perror("read failed");
4578 exit(2);
4579 }
4580 }
4581 sample_TOD_secs = header.TOD_secs;
4582 sample_TOD_usecs = header.TOD_usecs;
4583
4584 total_threads = header.thread_count;
4585 size = total_threads * sizeof(kd_threadmap);
4586
4587 if (size) {
4588 if ((mapptr = (kd_threadmap *) malloc(size))) {
4589 bzero (mapptr, size);
4590
4591 if (read(RAW_fd, mapptr, size) != size) {
4592 free(mapptr);
4593 return;
4594 }
4595 }
4596 }
4597 if (header.version_no != RAW_VERSION0) {
4598 offset = lseek(RAW_fd, (off_t)0, SEEK_CUR);
4599 offset = (offset + (4095)) & ~4095;
4600
4601 lseek(RAW_fd, offset, SEEK_SET);
4602 }
4603 }
4604 for (i = 0; i < total_threads; i++)
4605 create_map_entry(mapptr[i].thread, mapptr[i].valid, &mapptr[i].command[0]);
4606
4607 free(mapptr);
4608}
4609
4610
4611void delete_all_map_entries()
4612{
4613 threadmap_t tme = 0;
4614 threadmap_t tme_next = 0;
4615 int i;
4616
4617 for (i = 0; i < HASH_SIZE; i++) {
4618
4619 for (tme = threadmap_hash[i]; tme; tme = tme_next) {
4620 if (tme->tm_setptr)
4621 free(tme->tm_setptr);
4622 tme_next = tme->tm_next;
4623 tme->tm_next = threadmap_freelist;
4624 threadmap_freelist = tme;
4625 }
4626 threadmap_hash[i] = 0;
4627 }
4628}
4629
4630
4631void create_map_entry(uintptr_t thread, int pid, char *command)
4632{
4633 threadmap_t tme;
4634 int hashid;
4635
4636 if ((tme = threadmap_freelist))
4637 threadmap_freelist = tme->tm_next;
4638 else
4639 tme = (threadmap_t)malloc(sizeof(struct threadmap));
4640
4641 tme->tm_thread = thread;
4642 tme->tm_setsize = 0;
4643 tme->tm_setptr = 0;
4644
4645 (void)strncpy (tme->tm_command, command, MAXCOMLEN);
4646 tme->tm_command[MAXCOMLEN] = '\0';
4647
4648 hashid = thread & HASH_MASK;
4649
4650 tme->tm_next = threadmap_hash[hashid];
4651 threadmap_hash[hashid] = tme;
4652
4653 if (pid != 0 && pid != 1) {
4654 if (!strncmp(command, "LaunchCFMA", 10))
4655 (void)get_real_command_name(pid, tme->tm_command, MAXCOMLEN);
4656 }
4657}
4658
4659
4660threadmap_t
4661find_map_entry(uintptr_t thread)
4662{
4663 threadmap_t tme;
4664 int hashid;
4665
4666 hashid = thread & HASH_MASK;
4667
4668 for (tme = threadmap_hash[hashid]; tme; tme = tme->tm_next) {
4669 if (tme->tm_thread == thread)
4670 return (tme);
4671 }
4672 return (0);
4673}
4674
4675
4676void
4677delete_map_entry(uintptr_t thread)
4678{
4679 threadmap_t tme = 0;
4680 threadmap_t tme_prev;
4681 int hashid;
4682
4683 hashid = thread & HASH_MASK;
4684
4685 if ((tme = threadmap_hash[hashid])) {
4686 if (tme->tm_thread == thread)
4687 threadmap_hash[hashid] = tme->tm_next;
4688 else {
4689 tme_prev = tme;
4690
4691 for (tme = tme->tm_next; tme; tme = tme->tm_next) {
4692 if (tme->tm_thread == thread) {
4693 tme_prev->tm_next = tme->tm_next;
4694 break;
4695 }
4696 tme_prev = tme;
4697 }
4698 }
4699 if (tme) {
4700 if (tme->tm_setptr)
4701 free(tme->tm_setptr);
4702
4703 tme->tm_next = threadmap_freelist;
4704 threadmap_freelist = tme;
4705 }
4706 }
4707}
4708
4709
4710void
4711fs_usage_fd_set(uintptr_t thread, unsigned int fd)
4712{
4713 threadmap_t tme;
4714
4715 if ((tme = find_map_entry(thread)) == 0)
4716 return;
4717 /*
4718 * If the map is not allocated, then now is the time
4719 */
4720 if (tme->tm_setptr == (unsigned long *)0) {
4721 if ((tme->tm_setptr = (unsigned long *)malloc(FS_USAGE_NFDBYTES(FS_USAGE_FD_SETSIZE))) == 0)
4722 return;
4723
4724 tme->tm_setsize = FS_USAGE_FD_SETSIZE;
4725 bzero(tme->tm_setptr, (FS_USAGE_NFDBYTES(FS_USAGE_FD_SETSIZE)));
4726 }
4727 /*
4728 * If the map is not big enough, then reallocate it
4729 */
4730 while (tme->tm_setsize <= fd) {
4731 int n;
4732
4733 n = tme->tm_setsize * 2;
4734 tme->tm_setptr = (unsigned long *)realloc(tme->tm_setptr, (FS_USAGE_NFDBYTES(n)));
4735
4736 bzero(&tme->tm_setptr[(tme->tm_setsize/FS_USAGE_NFDBITS)], (FS_USAGE_NFDBYTES(tme->tm_setsize)));
4737 tme->tm_setsize = n;
4738 }
4739 /*
4740 * set the bit
4741 */
4742 tme->tm_setptr[fd/FS_USAGE_NFDBITS] |= (1 << ((fd) % FS_USAGE_NFDBITS));
4743}
4744
4745
4746/*
4747 * Return values:
4748 * 0 : File Descriptor bit is not set
4749 * 1 : File Descriptor bit is set
4750 */
4751int
4752fs_usage_fd_isset(uintptr_t thread, unsigned int fd)
4753{
4754 threadmap_t tme;
4755 int ret = 0;
4756
4757 if ((tme = find_map_entry(thread))) {
4758 if (tme->tm_setptr && fd < tme->tm_setsize)
4759 ret = tme->tm_setptr[fd/FS_USAGE_NFDBITS] & (1 << (fd % FS_USAGE_NFDBITS));
4760 }
4761 return (ret);
4762}
4763
4764
4765void
4766fs_usage_fd_clear(uintptr_t thread, unsigned int fd)
4767{
4768 threadmap_t tme;
4769
4770 if ((tme = find_map_entry(thread))) {
4771 if (tme->tm_setptr && fd < tme->tm_setsize)
4772 tme->tm_setptr[fd/FS_USAGE_NFDBITS] &= ~(1 << (fd % FS_USAGE_NFDBITS));
4773 }
4774}
4775
4776
4777
4778void
4779argtopid(char *str)
4780{
4781 char *cp;
4782 int ret;
4783 int i;
4784
4785 ret = (int)strtol(str, &cp, 10);
4786
4787 if (cp == str || *cp) {
4788 /*
4789 * Assume this is a command string and find matching pids
4790 */
4791 if (!kp_buffer)
4792 find_proc_names();
4793
4794 for (i = 0; i < kp_nentries && num_of_pids < (MAX_PIDS - 1); i++) {
4795 if (kp_buffer[i].kp_proc.p_stat == 0)
4796 continue;
4797 else {
4798 if (!strncmp(str, kp_buffer[i].kp_proc.p_comm,
4799 sizeof(kp_buffer[i].kp_proc.p_comm) -1))
4800 pids[num_of_pids++] = kp_buffer[i].kp_proc.p_pid;
4801 }
4802 }
4803 }
4804 else if (num_of_pids < (MAX_PIDS - 1))
4805 pids[num_of_pids++] = ret;
4806}
4807
4808
4809
4810void
4811lookup_name(uint64_t user_addr, char **type, char **name)
4812{
4813 int i;
4814 int start, last;
4815
4816 *name = NULL;
4817 *type = NULL;
4818
4819 if (numFrameworks) {
4820
4821 if ((user_addr >= framework32.b_address && user_addr < framework32.e_address) ||
4822 (user_addr >= framework64.b_address && user_addr < framework64.e_address)) {
4823
4824 start = 0;
4825 last = numFrameworks;
4826
4827 for (i = numFrameworks / 2; start < last; i = start + ((last - start) / 2)) {
4828 if (user_addr > frameworkInfo[i].e_address)
4829 start = i+1;
4830 else
4831 last = i;
4832 }
4833 if (start < numFrameworks &&
4834 user_addr >= frameworkInfo[start].b_address && user_addr < frameworkInfo[start].e_address) {
4835 *type = frameworkType[frameworkInfo[start].r_type];
4836 *name = frameworkInfo[start].name;
4837 }
4838 }
4839 }
4840}
4841
4842
4843/*
4844 * Comparison routines for sorting
4845 */
4846static int compareFrameworkAddress(const void *aa, const void *bb)
4847{
4848 LibraryInfo *a = (LibraryInfo *)aa;
4849 LibraryInfo *b = (LibraryInfo *)bb;
4850
4851 if (a->b_address < b->b_address) return -1;
4852 if (a->b_address == b->b_address) return 0;
4853 return 1;
4854}
4855
4856
4857int scanline(char *inputstring, char **argv, int maxtokens)
4858{
4859 int n = 0;
4860 char **ap = argv, *p, *val;
4861
4862 for (p = inputstring; n < maxtokens && p != NULL; ) {
4863
4864 while ((val = strsep(&p, " \t")) != NULL && *val == '\0');
4865
4866 *ap++ = val;
4867 n++;
4868 }
4869 *ap = 0;
4870
4871 return n;
4872}
4873
4874
4875int ReadSharedCacheMap(const char *path, LibraryRange *lr, char *linkedit_name)
4876{
4877 uint64_t b_address, e_address;
4878 char buf[1024];
4879 char *fnp;
4880 FILE *fd;
4881 char frameworkName[256];
4882 char *tokens[64];
4883 int ntokens;
4884 int type;
4885 int linkedit_found = 0;
4886 char *substring, *ptr;
4887
4888 bzero(buf, sizeof(buf));
4889 bzero(tokens, sizeof(tokens));
4890
4891 lr->b_address = 0;
4892 lr->e_address = 0;
4893
4894 if ((fd = fopen(path, "r")) == 0)
4895 return 0;
4896
4897 while (fgets(buf, 1023, fd)) {
4898 if (strncmp(buf, "mapping", 7))
4899 break;
4900 }
4901 buf[strlen(buf)-1] = 0;
4902
4903 frameworkName[0] = 0;
4904
4905 for (;;) {
4906 /*
4907 * Extract lib name from path name
4908 */
4909 if ((substring = strrchr(buf, '.')))
4910 {
4911 /*
4912 * There is a ".": name is whatever is between the "/" around the "."
4913 */
4914 while ( *substring != '/') /* find "/" before "." */
4915 substring--;
4916 substring++;
4917
4918 strncpy(frameworkName, substring, 256); /* copy path from "/" */
4919 frameworkName[255] = 0;
4920 substring = frameworkName;
4921
4922 while ( *substring != '/' && *substring) /* find "/" after "." and stop string there */
4923 substring++;
4924 *substring = 0;
4925 }
4926 else
4927 {
4928 /*
4929 * No ".": take segment after last "/"
4930 */
4931 ptr = buf;
4932 substring = ptr;
4933
4934 while (*ptr) {
4935 if (*ptr == '/')
4936 substring = ptr + 1;
4937 ptr++;
4938 }
4939 strncpy(frameworkName, substring, 256);
4940 frameworkName[255] = 0;
4941 }
4942 fnp = (char *)malloc(strlen(frameworkName) + 1);
4943 strcpy(fnp, frameworkName);
4944
4945 while (fgets(buf, 1023, fd) && numFrameworks < (MAXINDEX - 2)) {
4946 /*
4947 * Get rid of EOL
4948 */
4949 buf[strlen(buf)-1] = 0;
4950
4951 ntokens = scanline(buf, tokens, 64);
4952
4953 if (ntokens < 4)
4954 continue;
4955
4956 if (strncmp(tokens[0], "__TEXT", 6) == 0)
4957 type = TEXT_R;
4958 else if (strncmp(tokens[0], "__DATA", 6) == 0)
4959 type = DATA_R;
4960 else if (strncmp(tokens[0], "__OBJC", 6) == 0)
4961 type = OBJC_R;
4962 else if (strncmp(tokens[0], "__IMPORT", 8) == 0)
4963 type = IMPORT_R;
4964 else if (strncmp(tokens[0], "__UNICODE", 9) == 0)
4965 type = UNICODE_R;
4966 else if (strncmp(tokens[0], "__IMAGE", 7) == 0)
4967 type = IMAGE_R;
4968 else if (strncmp(tokens[0], "__LINKEDIT", 10) == 0)
4969 type = LINKEDIT_R;
4970 else
4971 type = -1;
4972
4973 if (type == LINKEDIT_R && linkedit_found)
4974 break;
4975
4976 if (type != -1) {
4977 b_address = strtoull(tokens[1], 0, 16);
4978 e_address = strtoull(tokens[3], 0, 16);
4979
4980 frameworkInfo[numFrameworks].b_address = b_address;
4981 frameworkInfo[numFrameworks].e_address = e_address;
4982 frameworkInfo[numFrameworks].r_type = type;
4983
4984 if (type == LINKEDIT_R) {
4985 frameworkInfo[numFrameworks].name = linkedit_name;
4986 linkedit_found = 1;
4987 } else
4988 frameworkInfo[numFrameworks].name = fnp;
4989#if 0
4990 printf("%s(%d): %qx-%qx\n", frameworkInfo[numFrameworks].name, type, b_address, e_address);
4991#endif
4992 if (lr->b_address == 0 || b_address < lr->b_address)
4993 lr->b_address = b_address;
4994
4995 if (lr->e_address == 0 || e_address > lr->e_address)
4996 lr->e_address = e_address;
4997
4998 numFrameworks++;
4999 }
5000 if (type == LINKEDIT_R)
5001 break;
5002 }
5003 if (fgets(buf, 1023, fd) == 0)
5004 break;
5005
5006 buf[strlen(buf)-1] = 0;
5007 }
5008 fclose(fd);
5009
5010#if 0
5011 printf("%s range, %qx-%qx\n", path, lr->b_address, lr->e_address);
5012#endif
5013 return 1;
5014}
5015
5016
5017void
5018SortFrameworkAddresses()
5019{
5020
5021 frameworkInfo[numFrameworks].b_address = frameworkInfo[numFrameworks - 1].b_address + 0x800000;
5022 frameworkInfo[numFrameworks].e_address = frameworkInfo[numFrameworks].b_address;
5023 frameworkInfo[numFrameworks].name = (char *)0;
5024
5025 qsort(frameworkInfo, numFrameworks, sizeof(LibraryInfo), compareFrameworkAddress);
5026}
5027
5028
5029struct diskio *insert_diskio(int type, int bp, int dev, int blkno, int io_size, uintptr_t thread, double curtime)
5030{
5031 struct diskio *dio;
5032 threadmap_t tme;
5033
5034 if ((dio = free_diskios))
5035 free_diskios = dio->next;
5036 else {
5037 if ((dio = (struct diskio *)malloc(sizeof(struct diskio))) == NULL)
5038 return (NULL);
5039 }
5040 dio->prev = NULL;
5041
5042 dio->type = type;
5043 dio->bp = bp;
5044 dio->dev = dev;
5045 dio->blkno = blkno;
5046 dio->iosize = io_size;
5047 dio->issued_time = curtime;
5048 dio->issuing_thread = thread;
5049
5050 dio->bc_info = 0x0;
5051
5052 if ((tme = find_map_entry(thread))) {
5053 strncpy(dio->issuing_command, tme->tm_command, MAXCOMLEN);
5054 dio->issuing_command[MAXCOMLEN] = '\0';
5055 } else
5056 strcpy(dio->issuing_command, "");
5057
5058 dio->next = busy_diskios;
5059 if (dio->next)
5060 dio->next->prev = dio;
5061 busy_diskios = dio;
5062
5063 return (dio);
5064}
5065
5066struct diskio *find_diskio(int bp) {
5067 struct diskio *dio;
5068
5069 for (dio = busy_diskios; dio; dio = dio->next) {
5070 if (dio->bp == bp)
5071 return (dio);
5072 }
5073
5074 return NULL;
5075}
5076
5077
5078struct diskio *complete_diskio(int bp, int io_errno, int resid, uintptr_t thread, double curtime)
5079{
5080 struct diskio *dio;
5081
5082 if ((dio = find_diskio(bp)) == NULL) return NULL;
5083
5084 if (dio == busy_diskios) {
5085 if ((busy_diskios = dio->next))
5086 dio->next->prev = NULL;
5087 } else {
5088 if (dio->next)
5089 dio->next->prev = dio->prev;
5090 dio->prev->next = dio->next;
5091 }
5092
5093 dio->iosize -= resid;
5094 dio->io_errno = io_errno;
5095 dio->completed_time = curtime;
5096 dio->completion_thread = thread;
5097
5098 return dio;
5099}
5100
5101
5102void free_diskio(struct diskio *dio)
5103{
5104 dio->next = free_diskios;
5105 free_diskios = dio;
5106}
5107
5108
5109void print_diskio(struct diskio *dio)
5110{
5111 char *p = NULL;
5112 int len = 0;
5113 int type;
5114 int format = FMT_DISKIO;
5115 char buf[64];
5116
5117 type = dio->type;
5118 dio->is_meta = 0;
5119
5120 if ((type & P_CS_Class) == P_CS_Class) {
5121
5122 switch (type) {
5123
5124 case P_CS_ReadChunk:
5125 p = " RdChunkCS";
5126 len = 13;
5127 format = FMT_DISKIO_CS;
5128 break;
5129 case P_CS_WriteChunk:
5130 p = " WrChunkCS";
5131 len = 13;
5132 format = FMT_DISKIO_CS;
5133 break;
5134 case P_CS_MetaRead:
5135 p = " RdMetaCS";
5136 len = 10;
5137 format = FMT_DISKIO_CS;
5138 break;
5139 case P_CS_MetaWrite:
5140 p = " WrMetaCS";
5141 len = 10;
5142 format = FMT_DISKIO_CS;
5143 break;
5144 case P_CS_TransformRead:
5145 p = " RdBgTfCS";
5146 len = 10;
5147 break;
5148 case P_CS_TransformWrite:
5149 p = " WrBgTfCS";
5150 len = 10;
5151 break;
5152 case P_CS_MigrationRead:
5153 p = " RdBgMigrCS";
5154 len = 12;
5155 break;
5156 case P_CS_MigrationWrite:
5157 p = " WrBgMigrCS";
5158 len = 12;
5159 break;
5160 }
5161 strncpy(buf, p, len);
5162 } else {
5163
5164 switch (type & P_DISKIO_TYPE) {
5165
5166 case P_RdMeta:
5167 dio->is_meta = 1;
5168 p = " RdMeta";
5169 len = 8;
5170 break;
5171 case P_WrMeta:
5172 dio->is_meta = 1;
5173 p = " WrMeta";
5174 len = 8;
5175 break;
5176 case P_RdData:
5177 p = " RdData";
5178 len = 8;
5179 break;
5180 case P_WrData:
5181 p = " WrData";
5182 len = 8;
5183 break;
5184 case P_PgIn:
5185 p = " PgIn";
5186 len = 6;
5187 break;
5188 case P_PgOut:
5189 p = " PgOut";
5190 len = 7;
5191 break;
5192 default:
5193 p = " ";
5194 len = 2;
5195 break;
5196 }
5197 strncpy(buf, p, len);
5198
5199 buf[len++] = '[';
5200
5201 if (type & P_DISKIO_ASYNC)
5202 buf[len++] = 'A';
5203 else
5204 buf[len++] = 'S';
5205
5206 if (type & P_DISKIO_NOCACHE)
5207 buf[len++] = 'N';
5208
5209 int tier = (type & P_DISKIO_TIER_MASK) >> P_DISKIO_TIER_SHIFT;
5210 if (tier > 0) {
5211 buf[len++] = 'T';
5212 if (tier > 0 && tier < 10)
5213 buf[len++] = '0' + tier;
5214 }
5215
5216 if (type & P_DISKIO_PASSIVE)
5217 buf[len++] = 'P';
5218
5219
5220 buf[len++] = ']';
5221 }
5222 buf[len] = 0;
5223
5224 if (check_filter_mode(NULL, type, 0, 0, buf))
5225 format_print(NULL, buf, dio->issuing_thread, type, 0, 0, 0, 0, format, dio->completed_time, dio->issued_time, 1, "", dio);
5226}
5227
5228
5229void cache_disk_names()
5230{
5231 struct stat st;
5232 DIR *dirp = NULL;
5233 struct dirent *dir;
5234 struct diskrec *dnp;
5235
5236
5237 if ((dirp = opendir("/dev")) == NULL)
5238 return;
5239
5240 while ((dir = readdir(dirp)) != NULL) {
5241 char nbuf[MAXPATHLEN];
5242
5243 if (dir->d_namlen < 5 || strncmp("disk", dir->d_name, 4))
5244 continue;
5245
5246 snprintf(nbuf, MAXPATHLEN, "%s/%s", "/dev", dir->d_name);
5247
5248 if (stat(nbuf, &st) < 0)
5249 continue;
5250
5251 if ((dnp = (struct diskrec *)malloc(sizeof(struct diskrec))) == NULL)
5252 continue;
5253
5254 if ((dnp->diskname = (char *)malloc(dir->d_namlen + 1)) == NULL) {
5255 free(dnp);
5256 continue;
5257 }
5258 strncpy(dnp->diskname, dir->d_name, dir->d_namlen);
5259 dnp->diskname[dir->d_namlen] = 0;
5260 dnp->dev = st.st_rdev;
5261
5262 dnp->next = disk_list;
5263 disk_list = dnp;
5264 }
5265 (void) closedir(dirp);
5266}
5267
5268
5269void recache_disk_names()
5270{
5271 struct diskrec *dnp, *next_dnp;
5272
5273 for (dnp = disk_list; dnp; dnp = next_dnp) {
5274 next_dnp = dnp->next;
5275
5276 free(dnp->diskname);
5277 free(dnp);
5278 }
5279 disk_list = NULL;
5280
5281 cache_disk_names();
5282}
5283
5284
5285char *find_disk_name(int dev)
5286{
5287 struct diskrec *dnp;
5288 int i;
5289
5290 if (dev == NFS_DEV)
5291 return ("NFS");
5292
5293 if (dev == CS_DEV)
5294 return ("CS");
5295
5296 for (i = 0; i < 2; i++) {
5297 for (dnp = disk_list; dnp; dnp = dnp->next) {
5298 if (dnp->dev == dev)
5299 return (dnp->diskname);
5300 }
5301 recache_disk_names();
5302 }
5303 return ("NOTFOUND");
5304}
5305
5306
5307char *generate_cs_disk_name(int dev, char *s)
5308{
5309 if (dev == -1)
5310 return ("UNKNOWN");
5311
5312 sprintf(s, "disk%ds%d", (dev >> 16) & 0xffff, dev & 0xffff);
5313
5314 return (s);
5315}
5316
5317
5318
5319/*
5320 * ret = 1 means print the entry
5321 * ret = 0 means don't print the entry
5322 */
5323
5324/*
5325 * meaning of filter flags:
5326 * cachehit turn on display of CACHE_HIT events (which are filtered out by default)
5327 *
5328 * exec show exec/posix_spawn
5329 * pathname show events with a pathname and close()
5330 * diskio show disk I/Os
5331 * filesys show filesystem events
5332 * network show network events
5333 *
5334 * filters may be combined; default is all filters on (except cachehit)
5335 */
5336int
5337check_filter_mode(struct th_info *ti, int type, int error, int retval, char *sc_name)
5338{
5339 int ret = 0;
5340 int network_fd_isset = 0;
5341 unsigned int fd;
5342
5343 /* cachehit is special -- it's not on by default */
5344 if (sc_name[0] == 'C' && !strcmp(sc_name, "CACHE_HIT")) {
5345 if (show_cachehits) return 1;
5346 else return 0;
5347 }
5348
5349 if (filter_mode == DEFAULT_DO_NOT_FILTER)
5350 return(1);
5351
5352 if (filter_mode & DISKIO_FILTER) {
5353 if ((type & P_DISKIO_MASK) == P_DISKIO)
5354 return 1;
5355 }
5356
5357 if (filter_mode & EXEC_FILTER) {
5358 if (type == BSC_execve || type == BSC_posix_spawn)
5359 return(1);
5360 }
5361
5362 if (filter_mode & PATHNAME_FILTER) {
5363 if (ti && ti->lookups[0].pathname[0])
5364 return(1);
5365 if (type == BSC_close || type == BSC_close_nocancel ||
5366 type == BSC_guarded_close_np)
5367 return(1);
5368 }
5369
5370 if (ti == (struct th_info *)0) {
5371 if (filter_mode & FILESYS_FILTER)
5372 return(1);
5373 return(0);
5374 }
5375
5376 switch (type) {
5377
5378 case BSC_close:
5379 case BSC_close_nocancel:
5380 case BSC_guarded_close_np:
5381 fd = ti->arg1;
5382 network_fd_isset = fs_usage_fd_isset(ti->thread, fd);
5383
5384 if (error == 0)
5385 fs_usage_fd_clear(ti->thread,fd);
5386
5387 if (network_fd_isset) {
5388 if (filter_mode & NETWORK_FILTER)
5389 ret = 1;
5390 } else
5391 if (filter_mode & FILESYS_FILTER)
5392 ret = 1;
5393 break;
5394
5395 case BSC_read:
5396 case BSC_write:
5397 case BSC_read_nocancel:
5398 case BSC_write_nocancel:
5399 /*
5400 * we don't care about error in these cases
5401 */
5402 fd = ti->arg1;
5403 network_fd_isset = fs_usage_fd_isset(ti->thread, fd);
5404
5405 if (network_fd_isset) {
5406 if (filter_mode & NETWORK_FILTER)
5407 ret = 1;
5408 } else
5409 if (filter_mode & FILESYS_FILTER)
5410 ret = 1;
5411 break;
5412
5413 case BSC_accept:
5414 case BSC_accept_nocancel:
5415 case BSC_socket:
5416 fd = retval;
5417
5418 if (error == 0)
5419 fs_usage_fd_set(ti->thread, fd);
5420 if (filter_mode & NETWORK_FILTER)
5421 ret = 1;
5422 break;
5423
5424 case BSC_recvfrom:
5425 case BSC_sendto:
5426 case BSC_recvmsg:
5427 case BSC_sendmsg:
5428 case BSC_connect:
5429 case BSC_bind:
5430 case BSC_listen:
5431 case BSC_sendto_nocancel:
5432 case BSC_recvfrom_nocancel:
5433 case BSC_recvmsg_nocancel:
5434 case BSC_sendmsg_nocancel:
5435 case BSC_connect_nocancel:
5436 fd = ti->arg1;
5437
5438 if (error == 0)
5439 fs_usage_fd_set(ti->thread, fd);
5440 if (filter_mode & NETWORK_FILTER)
5441 ret = 1;
5442 break;
5443
5444 case BSC_select:
5445 case BSC_select_nocancel:
5446 case BSC_socketpair:
5447 /*
5448 * Cannot determine info about file descriptors
5449 */
5450 if (filter_mode & NETWORK_FILTER)
5451 ret = 1;
5452 break;
5453
5454 case BSC_dup:
5455 case BSC_dup2:
5456 /*
5457 * We track these cases for fd state only
5458 */
5459 fd = ti->arg1;
5460 network_fd_isset = fs_usage_fd_isset(ti->thread, fd);
5461
5462 if (error == 0 && network_fd_isset) {
5463 /*
5464 * then we are duping a socket descriptor
5465 */
5466 fd = retval; /* the new fd */
5467 fs_usage_fd_set(ti->thread, fd);
5468 }
5469 break;
5470
5471 default:
5472 if (filter_mode & FILESYS_FILTER)
5473 ret = 1;
5474 break;
5475 }
5476
5477 return(ret);
5478}
5479
5480/*
5481 * Allocate a buffer that is large enough to hold the maximum arguments
5482 * to execve(). This is used when getting the arguments to programs
5483 * when we see LaunchCFMApps. If this fails, it is not fatal, we will
5484 * simply not resolve the command name.
5485 */
5486
5487void
5488init_arguments_buffer()
5489{
5490 int mib[2];
5491 size_t size;
5492
5493 mib[0] = CTL_KERN;
5494 mib[1] = KERN_ARGMAX;
5495 size = sizeof(argmax);
5496
5497 if (sysctl(mib, 2, &argmax, &size, NULL, 0) == -1)
5498 return;
5499#if 1
5500 /* Hack to avoid kernel bug. */
5501 if (argmax > 8192) {
5502 argmax = 8192;
5503 }
5504#endif
5505 arguments = (char *)malloc(argmax);
5506}
5507
5508
5509int
5510get_real_command_name(int pid, char *cbuf, int csize)
5511{
5512 /*
5513 * Get command and arguments.
5514 */
5515 char *cp;
5516 int mib[4];
5517 char *command_beg, *command, *command_end;
5518
5519 if (cbuf == NULL)
5520 return(0);
5521
5522 if (arguments)
5523 bzero(arguments, argmax);
5524 else
5525 return(0);
5526
5527 /*
5528 * A sysctl() is made to find out the full path that the command
5529 * was called with.
5530 */
5531 mib[0] = CTL_KERN;
5532 mib[1] = KERN_PROCARGS2;
5533 mib[2] = pid;
5534 mib[3] = 0;
5535
5536 if (sysctl(mib, 3, arguments, (size_t *)&argmax, NULL, 0) < 0)
5537 return(0);
5538
5539 /*
5540 * Skip the saved exec_path
5541 */
5542 for (cp = arguments; cp < &arguments[argmax]; cp++) {
5543 if (*cp == '\0') {
5544 /*
5545 * End of exec_path reached
5546 */
5547 break;
5548 }
5549 }
5550 if (cp == &arguments[argmax])
5551 return(0);
5552
5553 /*
5554 * Skip trailing '\0' characters
5555 */
5556 for (; cp < &arguments[argmax]; cp++) {
5557 if (*cp != '\0') {
5558 /*
5559 * Beginning of first argument reached
5560 */
5561 break;
5562 }
5563 }
5564 if (cp == &arguments[argmax])
5565 return(0);
5566
5567 command_beg = cp;
5568 /*
5569 * Make sure that the command is '\0'-terminated. This protects
5570 * against malicious programs; under normal operation this never
5571 * ends up being a problem..
5572 */
5573 for (; cp < &arguments[argmax]; cp++) {
5574 if (*cp == '\0') {
5575 /*
5576 * End of first argument reached
5577 */
5578 break;
5579 }
5580 }
5581 if (cp == &arguments[argmax])
5582 return(0);
5583
5584 command_end = command = cp;
5585
5586 /*
5587 * Get the basename of command
5588 */
5589 for (command--; command >= command_beg; command--) {
5590 if (*command == '/') {
5591 command++;
5592 break;
5593 }
5594 }
5595 (void) strncpy(cbuf, (char *)command, csize);
5596 cbuf[csize-1] = '\0';
5597
5598 return(1);
5599}