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(×tamp[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} 5600