*
* @APPLE_LICENSE_HEADER_START@
*
- * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
+ * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
+ * Reserved. This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License'). You may not use this file
+ * except in compliance with the License. Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
-cc -I. -DKERNEL_PRIVATE -O -o fs_usage fs_usage.c
+cc -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
*/
-#define Default_DELAY 1 /* default delay interval */
-
#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
#include <strings.h>
#include <nlist.h>
#include <fcntl.h>
+#include <aio.h>
#include <string.h>
#include <dirent.h>
+#include <libc.h>
+#include <termios.h>
+#include <errno.h>
+#include <err.h>
+#include <libutil.h>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/time.h>
-
-#include <libc.h>
-#include <termios.h>
#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <sys/mman.h>
+#include <sys/sysctl.h>
+#include <sys/disk.h>
+#include <sys/file.h>
#ifndef KERNEL_PRIVATE
#define KERNEL_PRIVATE
#include <sys/kdebug.h>
#endif /*KERNEL_PRIVATE*/
-#include <sys/sysctl.h>
-#include <errno.h>
#import <mach/clock_types.h>
-#include <err.h>
+#import <mach/mach_time.h>
+
+
+
+#define F_OPENFROM 56 /* SPI: open a file relative to fd (must be a dir) */
+#define F_UNLINKFROM 57 /* SPI: open a file relative to fd (must be a dir) */
+#define F_CHECK_OPENEVT 58 /* SPI: if a process is marked OPENEVT, or in O_EVTONLY on opens of this vnode */
-extern int errno;
+#ifndef RAW_VERSION1
+typedef struct {
+ int version_no;
+ int thread_count;
+ uint64_t TOD_secs;
+ uint32_t TOD_usecs;
+} RAW_header;
+
+#define RAW_VERSION0 0x55aa0000
+#define RAW_VERSION1 0x55aa0101
+#endif
#define MAXINDEX 2048
+typedef struct LibraryRange {
+ uint64_t b_address;
+ uint64_t e_address;
+} LibraryRange;
+
+LibraryRange framework32;
+LibraryRange framework64;
+
+
+#define TEXT_R 0
+#define DATA_R 1
+#define OBJC_R 2
+#define IMPORT_R 3
+#define UNICODE_R 4
+#define IMAGE_R 5
+#define LINKEDIT_R 6
+
+
+char *frameworkType[] = {
+ "<TEXT> ",
+ "<DATA> ",
+ "<OBJC> ",
+ "<IMPORT> ",
+ "<UNICODE> ",
+ "<IMAGE> ",
+ "<LINKEDIT>",
+};
+
+
typedef struct LibraryInfo {
- unsigned long address;
- char *name;
+ uint64_t b_address;
+ uint64_t e_address;
+ int r_type;
+ char *name;
} LibraryInfo;
LibraryInfo frameworkInfo[MAXINDEX];
int numFrameworks = 0;
-char seg_addr_table[256]="/AppleInternal/Developer/seg_addr_table";
-
-char *lookup_name();
-
/*
- MAXCOLS controls when extra data kicks in.
- MAX_WIDE_MODE_COLS controls -w mode to get even wider data in path.
- If NUMPARMS changes to match the kernel, it will automatically
- get reflected in the -w mode output.
-*/
+ * MAXCOLS controls when extra data kicks in.
+ * MAX_WIDE_MODE_COLS controls -w mode to get even wider data in path.
+ * If NUMPARMS changes to match the kernel, it will automatically
+ * get reflected in the -w mode output.
+ */
#define NUMPARMS 23
-#define PATHLENGTH (NUMPARMS*sizeof(long))
-#define MAXCOLS 131
+#define PATHLENGTH (NUMPARMS*sizeof(uintptr_t))
+
+#define MAXCOLS 132
#define MAX_WIDE_MODE_COLS (PATHLENGTH + 80)
+#define MAXWIDTH MAX_WIDE_MODE_COLS + 64
+
+#define MAX_PATHNAMES 3
+#define MAX_SCALL_PATHNAMES 2
+
+typedef struct th_info *th_info_t;
+
+struct lookup {
+ uintptr_t pathname[NUMPARMS + 1]; /* add room for null terminator */
+};
struct th_info {
+ th_info_t next;
+ uintptr_t thread;
+ uintptr_t child_thread;
+
int in_filemgr;
- int thread;
+ int in_hfs_update;
int pid;
int type;
int arg1;
int arg2;
int arg3;
int arg4;
- int child_thread;
+ int arg5;
+ int arg6;
+ int arg7;
+ int arg8;
int waited;
double stime;
- long *pathptr;
- char pathname[PATHLENGTH + 1]; /* add room for null terminator */
+ uint64_t vnodeid;
+ char *nameptr;
+ uintptr_t *pathptr;
+ int pn_scall_index;
+ int pn_work_index;
+ struct lookup lookups[MAX_PATHNAMES];
+};
+
+
+typedef struct threadmap * threadmap_t;
+
+struct threadmap {
+ threadmap_t tm_next;
+
+ uintptr_t tm_thread;
+ unsigned int tm_setsize; /* this is a bit count */
+ unsigned long *tm_setptr; /* file descripter bitmap */
+ char tm_command[MAXCOMLEN + 1];
+};
+
+
+typedef struct vnode_info * vnode_info_t;
+
+struct vnode_info {
+ vnode_info_t vn_next;
+ uint64_t vn_id;
+ uintptr_t vn_pathname[NUMPARMS + 1];
+};
+
+typedef struct meta_info * meta_info_t;
+
+struct meta_info {
+ meta_info_t m_next;
+ uint64_t m_blkno;
+ char *m_nameptr;
};
-#define MAX_THREADS 512
-struct th_info th_state[MAX_THREADS];
+#define HASH_SIZE 1024
+#define HASH_MASK (HASH_SIZE - 1)
+th_info_t th_info_hash[HASH_SIZE];
+th_info_t th_info_freelist;
-int cur_max = 0;
+threadmap_t threadmap_hash[HASH_SIZE];
+threadmap_t threadmap_freelist;
+
+
+#define VN_HASH_SHIFT 3
+#define VN_HASH_SIZE 16384
+#define VN_HASH_MASK (VN_HASH_SIZE - 1)
+
+vnode_info_t vn_info_hash[VN_HASH_SIZE];
+meta_info_t m_info_hash[VN_HASH_SIZE];
+
+
+int filemgr_in_progress = 0;
int need_new_map = 1;
-int bias_secs;
+int bias_secs = 0;
+long last_time;
int wideflag = 0;
int columns = 0;
-int select_pid_mode = 0; /* Flag set indicates that output is restricted
- to selected pids or commands */
int one_good_pid = 0; /* Used to fail gracefully when bad pids given */
+int select_pid_mode = 0; /* Flag set indicates that output is restricted
+ to selected pids or commands */
char *arguments = 0;
int argmax = 0;
+
+#define USLEEP_MIN 1
+#define USLEEP_BEHIND 2
+#define USLEEP_MAX 32
+int usleep_ms = USLEEP_MIN;
+
/*
* Network only or filesystem only output filter
* Default of zero means report all activity - no filtering
*/
-#define FILESYS_FILTER 0x01
-#define NETWORK_FILTER 0x02
-#define DEFAULT_DO_NOT_FILTER 0x0
+#define FILESYS_FILTER 0x01
+#define NETWORK_FILTER 0x02
+#define EXEC_FILTER 0x08
+#define PATHNAME_FILTER 0x10
+#define DISKIO_FILTER 0x20
+#define DEFAULT_DO_NOT_FILTER 0x00
+
int filter_mode = DEFAULT_DO_NOT_FILTER;
+boolean_t show_cachehits = FALSE;
+
#define NFS_DEV -1
+#define CS_DEV -2
struct diskrec {
struct diskrec *next;
int blkno;
int iosize;
int io_errno;
- int issuing_thread;
- int completion_thread;
+ int is_meta;
+ uint64_t vnodeid;
+ uintptr_t issuing_thread;
+ uintptr_t completion_thread;
char issuing_command[MAXCOMLEN];
double issued_time;
double completed_time;
+ uint32_t bc_info;
};
struct diskrec *disk_list = NULL;
struct diskio *free_diskios = NULL;
struct diskio *busy_diskios = NULL;
+
struct diskio *insert_diskio();
+struct diskio *find_diskio(int);
struct diskio *complete_diskio();
void free_diskio();
void print_diskio();
-void format_print();
-char *find_disk_name();
+
+int check_filter_mode(struct th_info *, int, int, int, char *);
+void format_print(struct th_info *, char *, uintptr_t, int, uintptr_t, uintptr_t, uintptr_t, uintptr_t, int, double, double, int, char *, struct diskio *);
+void enter_event_now(uintptr_t, int, kd_buf *, char *, double);
+void enter_event(uintptr_t, int, kd_buf *, char *, double);
+void exit_event(char *, uintptr_t, int, uintptr_t, uintptr_t, uintptr_t, uintptr_t, int, double);
+void extend_syscall(uintptr_t, int, kd_buf *);
+
+char *generate_cs_disk_name(int, char *s);
+char *find_disk_name(int);
void cache_disk_names();
-int ReadSegAddrTable();
-void mark_thread_waited(int);
-int check_filter_mode(struct th_info *, int, int, int);
-void fs_usage_fd_set(unsigned int, unsigned int);
-int fs_usage_fd_isset(unsigned int, unsigned int);
-void fs_usage_fd_clear(unsigned int, unsigned int);
+void recache_disk_names();
+
+void lookup_name(uint64_t user_addr, char **type, char **name);
+int ReadSharedCacheMap(const char *, LibraryRange *, char *);
+void SortFrameworkAddresses();
+
+void fs_usage_fd_set(uintptr_t, unsigned int);
+int fs_usage_fd_isset(uintptr_t, unsigned int);
+void fs_usage_fd_clear(uintptr_t, unsigned int);
+
void init_arguments_buffer();
int get_real_command_name(int, char *, int);
-void create_map_entry(int, int, char *);
-#define DBG_ZERO_FILL_FAULT 1
-#define DBG_PAGEIN_FAULT 2
-#define DBG_COW_FAULT 3
-#define DBG_CACHE_HIT_FAULT 4
+void delete_all_events();
+void delete_event(th_info_t);
+th_info_t add_event(uintptr_t, int);
+th_info_t find_event(uintptr_t, int);
+void mark_thread_waited(uintptr_t);
+
+void read_command_map();
+void delete_all_map_entries();
+void create_map_entry(uintptr_t, int, char *);
+void delete_map_entry(uintptr_t);
+threadmap_t find_map_entry(uintptr_t);
+
+char *add_vnode_name(uint64_t, char *);
+char *find_vnode_name(uint64_t);
+char *find_meta_name(uint64_t);
+void add_meta_name(uint64_t, char *);
+
+void getdivisor();
+void argtopid();
+void set_remove();
+void set_pidcheck();
+void set_pidexclude();
+int quit();
+
+
+#define CLASS_MASK 0xff000000
+#define CSC_MASK 0xffff0000
+#define BSC_INDEX(type) ((type >> 2) & 0x3fff)
+
#define TRACE_DATA_NEWTHREAD 0x07000004
#define TRACE_DATA_EXEC 0x07000008
#define TRACE_STRING_NEWTHREAD 0x07010004
#define TRACE_STRING_EXEC 0x07010008
-#define MACH_vmfault 0x01300000
+#define MACH_vmfault 0x01300008
#define MACH_pageout 0x01300004
#define MACH_sched 0x01400000
#define MACH_stkhandoff 0x01400008
+#define MACH_idle 0x01400024
#define VFS_LOOKUP 0x03010090
-#define BSC_exit 0x040C0004
-
-#define P_WrData 0x03020000
-#define P_RdData 0x03020008
-#define P_WrMeta 0x03020020
-#define P_RdMeta 0x03020028
-#define P_PgOut 0x03020040
-#define P_PgIn 0x03020048
-#define P_WrDataAsync 0x03020010
-#define P_RdDataAsync 0x03020018
-#define P_WrMetaAsync 0x03020030
-#define P_RdMetaAsync 0x03020038
-#define P_PgOutAsync 0x03020050
-#define P_PgInAsync 0x03020058
-
-#define P_WrDataDone 0x03020004
-#define P_RdDataDone 0x0302000C
-#define P_WrMetaDone 0x03020024
-#define P_RdMetaDone 0x0302002C
-#define P_PgOutDone 0x03020044
-#define P_PgInDone 0x0302004C
-#define P_WrDataAsyncDone 0x03020014
-#define P_RdDataAsyncDone 0x0302001C
-#define P_WrMetaAsyncDone 0x03020034
-#define P_RdMetaAsyncDone 0x0302003C
-#define P_PgOutAsyncDone 0x03020054
-#define P_PgInAsyncDone 0x0302005C
+#define VFS_ALIAS_VP 0x03010094
+
+#define BSC_thread_terminate 0x040c05a4
+
+#define HFS_update 0x3018000
+#define HFS_modify_block_end 0x3018004
+
+#define Throttled 0x3010184
+#define SPEC_ioctl 0x3060000
+#define SPEC_unmap_info 0x3060004
+#define proc_exit 0x4010004
+
+#define BC_IO_HIT 0x03070010
+#define BC_IO_HIT_STALLED 0x03070020
+#define BC_IO_MISS 0x03070040
+#define BC_IO_MISS_CUT_THROUGH 0x03070080
+#define BC_PLAYBACK_IO 0x03070100
+#define BC_STR(s) ( \
+ (s == BC_IO_HIT) ? "HIT" : \
+ (s == BC_IO_HIT_STALLED) ? "STALL" : \
+ (s == BC_IO_MISS) ? "MISS" : \
+ (s == BC_IO_MISS_CUT_THROUGH) ? "CUT" : \
+ (s == BC_PLAYBACK_IO) ? "PLBK" : \
+ (s == 0x0) ? "NONE" : "UNKN" )
+
+#ifndef DKIO_NOCACHE
+#define DKIO_NOCACHE 0x80
+#endif
+#define P_DISKIO_READ (DKIO_READ << 2)
+#define P_DISKIO_ASYNC (DKIO_ASYNC << 2)
+#define P_DISKIO_META (DKIO_META << 2)
+#define P_DISKIO_PAGING (DKIO_PAGING << 2)
+#define P_DISKIO_THROTTLE (DKIO_THROTTLE << 2)
+#define P_DISKIO_PASSIVE (DKIO_PASSIVE << 2)
+#define P_DISKIO_NOCACHE (DKIO_NOCACHE << 2)
+#define P_DISKIO_TIER_MASK (DKIO_TIER_MASK << 2)
+#define P_DISKIO_TIER_SHIFT (DKIO_TIER_SHIFT + 2)
+
+#define P_DISKIO (FSDBG_CODE(DBG_DKRW, 0))
+#define P_DISKIO_DONE (P_DISKIO | (DKIO_DONE << 2))
+#define P_DISKIO_TYPE (P_DISKIO | P_DISKIO_READ | P_DISKIO_META | P_DISKIO_PAGING)
+#define P_DISKIO_MASK (CSC_MASK | 0x4)
+
+#define P_WrData (P_DISKIO)
+#define P_RdData (P_DISKIO | P_DISKIO_READ)
+#define P_WrMeta (P_DISKIO | P_DISKIO_META)
+#define P_RdMeta (P_DISKIO | P_DISKIO_META | P_DISKIO_READ)
+#define P_PgOut (P_DISKIO | P_DISKIO_PAGING)
+#define P_PgIn (P_DISKIO | P_DISKIO_PAGING | P_DISKIO_READ)
+
+#define P_CS_Class 0x0a000000 // DBG_CORESTORAGE
+#define P_CS_Type_Mask 0xfffffff0
+#define P_CS_IO_Done 0x00000004
+
+#define P_CS_ReadChunk 0x0a000200 // chopped up request
+#define P_CS_WriteChunk 0x0a000210
+#define P_CS_MetaRead 0x0a000300 // meta data
+#define P_CS_MetaWrite 0x0a000310
+#define P_CS_TransformRead 0x0a000500 // background transform
+#define P_CS_TransformWrite 0x0a000510
+#define P_CS_MigrationRead 0x0a000600 // composite disk block migration
+#define P_CS_MigrationWrite 0x0a000610
+#define P_CS_SYNC_DISK 0x0a010000
#define MSC_map_fd 0x010c00ac
+#define BSC_BASE 0x040C0000
+#define MSC_BASE 0x010C0000
+
// Network related codes
-#define BSC_recvmsg 0x040C006C
-#define BSC_sendmsg 0x040C0070
-#define BSC_recvfrom 0x040C0074
-#define BSC_accept 0x040C0078
-#define BSC_select 0x040C0174
-#define BSC_socket 0x040C0184
-#define BSC_connect 0x040C0188
-#define BSC_bind 0x040C01A0
-#define BSC_listen 0x040C01A8
-#define BSC_sendto 0x040C0214
-#define BSC_socketpair 0x040C021C
-
-#define BSC_read 0x040C000C
-#define BSC_write 0x040C0010
-#define BSC_open 0x040C0014
-#define BSC_close 0x040C0018
-#define BSC_link 0x040C0024
-#define BSC_unlink 0x040C0028
-#define BSC_chdir 0x040c0030
-#define BSC_fchdir 0x040c0034
-#define BSC_mknod 0x040C0038
-#define BSC_chmod 0x040C003C
-#define BSC_chown 0x040C0040
-#define BSC_access 0x040C0084
-#define BSC_chflags 0x040C0088
-#define BSC_fchflags 0x040C008C
-#define BSC_sync 0x040C0090
-#define BSC_dup 0x040C00A4
-#define BSC_revoke 0x040C00E0
-#define BSC_symlink 0x040C00E4
-#define BSC_readlink 0x040C00E8
-#define BSC_chroot 0x040C00F4
-#define BSC_dup2 0x040C0168
-#define BSC_fsync 0x040C017C
-#define BSC_readv 0x040C01E0
-#define BSC_writev 0x040C01E4
-#define BSC_fchown 0x040C01EC
-#define BSC_fchmod 0x040C01F0
-#define BSC_rename 0x040C0200
-#define BSC_mkfifo 0x040c0210
-#define BSC_mkdir 0x040C0220
-#define BSC_rmdir 0x040C0224
-#define BSC_utimes 0x040C0228
-#define BSC_futimes 0x040C022C
-#define BSC_pread 0x040C0264
-#define BSC_pread_extended 0x040E0264
-#define BSC_pwrite 0x040C0268
-#define BSC_pwrite_extended 0x040E0268
-#define BSC_statfs 0x040C0274
-#define BSC_fstatfs 0x040C0278
-#define BSC_stat 0x040C02F0
-#define BSC_fstat 0x040C02F4
-#define BSC_lstat 0x040C02F8
-#define BSC_pathconf 0x040C02FC
-#define BSC_fpathconf 0x040C0300
-#define BSC_getdirentries 0x040C0310
-#define BSC_mmap 0x040c0314
-#define BSC_lseek 0x040c031c
-#define BSC_truncate 0x040C0320
-#define BSC_ftruncate 0x040C0324
-#define BSC_undelete 0x040C0334
-#define BSC_statv 0x040C0364
-#define BSC_lstatv 0x040C0368
-#define BSC_fstatv 0x040C036C
-#define BSC_mkcomplex 0x040C0360
-#define BSC_getattrlist 0x040C0370
-#define BSC_setattrlist 0x040C0374
-#define BSC_getdirentriesattr 0x040C0378
-#define BSC_exchangedata 0x040C037C
-#define BSC_checkuseraccess 0x040C0380
-#define BSC_searchfs 0x040C0384
-#define BSC_delete 0x040C0388
-#define BSC_copyfile 0x040C038C
-#define BSC_fsctl 0x040C03C8
-#define BSC_load_shared_file 0x040C04A0
+#define BSC_recvmsg 0x040C006C
+#define BSC_sendmsg 0x040C0070
+#define BSC_recvfrom 0x040C0074
+#define BSC_accept 0x040C0078
+#define BSC_select 0x040C0174
+#define BSC_socket 0x040C0184
+#define BSC_connect 0x040C0188
+#define BSC_bind 0x040C01A0
+#define BSC_listen 0x040C01A8
+#define BSC_sendto 0x040C0214
+#define BSC_socketpair 0x040C021C
+#define BSC_recvmsg_nocancel 0x040c0644
+#define BSC_sendmsg_nocancel 0x040c0648
+#define BSC_recvfrom_nocancel 0x040c064c
+#define BSC_accept_nocancel 0x040c0650
+#define BSC_connect_nocancel 0x040c0664
+#define BSC_sendto_nocancel 0x040c0674
+
+#define BSC_exit 0x040C0004
+#define BSC_read 0x040C000C
+#define BSC_write 0x040C0010
+#define BSC_open 0x040C0014
+#define BSC_close 0x040C0018
+#define BSC_link 0x040C0024
+#define BSC_unlink 0x040C0028
+#define BSC_chdir 0x040c0030
+#define BSC_fchdir 0x040c0034
+#define BSC_mknod 0x040C0038
+#define BSC_chmod 0x040C003C
+#define BSC_chown 0x040C0040
+#define BSC_getfsstat 0x040C0048
+#define BSC_access 0x040C0084
+#define BSC_chflags 0x040C0088
+#define BSC_fchflags 0x040C008C
+#define BSC_sync 0x040C0090
+#define BSC_dup 0x040C00A4
+#define BSC_ioctl 0x040C00D8
+#define BSC_revoke 0x040C00E0
+#define BSC_symlink 0x040C00E4
+#define BSC_readlink 0x040C00E8
+#define BSC_execve 0x040C00EC
+#define BSC_umask 0x040C00F0
+#define BSC_chroot 0x040C00F4
+#define BSC_msync 0x040C0104
+#define BSC_dup2 0x040C0168
+#define BSC_fcntl 0x040C0170
+#define BSC_fsync 0x040C017C
+#define BSC_readv 0x040C01E0
+#define BSC_writev 0x040C01E4
+#define BSC_fchown 0x040C01EC
+#define BSC_fchmod 0x040C01F0
+#define BSC_rename 0x040C0200
+#define BSC_flock 0x040C020C
+#define BSC_mkfifo 0x040C0210
+#define BSC_mkdir 0x040C0220
+#define BSC_rmdir 0x040C0224
+#define BSC_utimes 0x040C0228
+#define BSC_futimes 0x040C022C
+#define BSC_pread 0x040C0264
+#define BSC_pwrite 0x040C0268
+#define BSC_statfs 0x040C0274
+#define BSC_fstatfs 0x040C0278
+#define BSC_unmount 0x040C027C
+#define BSC_mount 0x040C029C
+#define BSC_fdatasync 0x040C02EC
+#define BSC_stat 0x040C02F0
+#define BSC_fstat 0x040C02F4
+#define BSC_lstat 0x040C02F8
+#define BSC_pathconf 0x040C02FC
+#define BSC_fpathconf 0x040C0300
+#define BSC_getdirentries 0x040C0310
+#define BSC_mmap 0x040c0314
+#define BSC_lseek 0x040c031c
+#define BSC_truncate 0x040C0320
+#define BSC_ftruncate 0x040C0324
+#define BSC_undelete 0x040C0334
+#define BSC_open_dprotected_np 0x040C0360
+#define BSC_getattrlist 0x040C0370
+#define BSC_setattrlist 0x040C0374
+#define BSC_getdirentriesattr 0x040C0378
+#define BSC_exchangedata 0x040C037C
+#define BSC_checkuseraccess 0x040C0380
+#define BSC_searchfs 0x040C0384
+#define BSC_delete 0x040C0388
+#define BSC_copyfile 0x040C038C
+#define BSC_fgetattrlist 0x040C0390
+#define BSC_fsetattrlist 0x040C0394
+#define BSC_getxattr 0x040C03A8
+#define BSC_fgetxattr 0x040C03AC
+#define BSC_setxattr 0x040C03B0
+#define BSC_fsetxattr 0x040C03B4
+#define BSC_removexattr 0x040C03B8
+#define BSC_fremovexattr 0x040C03BC
+#define BSC_listxattr 0x040C03C0
+#define BSC_flistxattr 0x040C03C4
+#define BSC_fsctl 0x040C03C8
+#define BSC_posix_spawn 0x040C03D0
+#define BSC_ffsctl 0x040C03D4
+#define BSC_open_extended 0x040C0454
+#define BSC_umask_extended 0x040C0458
+#define BSC_stat_extended 0x040C045C
+#define BSC_lstat_extended 0x040C0460
+#define BSC_fstat_extended 0x040C0464
+#define BSC_chmod_extended 0x040C0468
+#define BSC_fchmod_extended 0x040C046C
+#define BSC_access_extended 0x040C0470
+#define BSC_mkfifo_extended 0x040C048C
+#define BSC_mkdir_extended 0x040C0490
+#define BSC_aio_fsync 0x040C04E4
+#define BSC_aio_return 0x040C04E8
+#define BSC_aio_suspend 0x040C04EC
+#define BSC_aio_cancel 0x040C04F0
+#define BSC_aio_error 0x040C04F4
+#define BSC_aio_read 0x040C04F8
+#define BSC_aio_write 0x040C04FC
+#define BSC_lio_listio 0x040C0500
+#define BSC_sendfile 0x040C0544
+#define BSC_stat64 0x040C0548
+#define BSC_fstat64 0x040C054C
+#define BSC_lstat64 0x040C0550
+#define BSC_stat64_extended 0x040C0554
+#define BSC_lstat64_extended 0x040C0558
+#define BSC_fstat64_extended 0x040C055C
+#define BSC_getdirentries64 0x040C0560
+#define BSC_statfs64 0x040C0564
+#define BSC_fstatfs64 0x040C0568
+#define BSC_getfsstat64 0x040C056C
+#define BSC_pthread_chdir 0x040C0570
+#define BSC_pthread_fchdir 0x040C0574
+#define BSC_lchown 0x040C05B0
+
+#define BSC_read_nocancel 0x040c0630
+#define BSC_write_nocancel 0x040c0634
+#define BSC_open_nocancel 0x040c0638
+#define BSC_close_nocancel 0x040c063c
+#define BSC_msync_nocancel 0x040c0654
+#define BSC_fcntl_nocancel 0x040c0658
+#define BSC_select_nocancel 0x040c065c
+#define BSC_fsync_nocancel 0x040c0660
+#define BSC_readv_nocancel 0x040c066c
+#define BSC_writev_nocancel 0x040c0670
+#define BSC_pread_nocancel 0x040c0678
+#define BSC_pwrite_nocancel 0x040c067c
+#define BSC_aio_suspend_nocancel 0x40c0694
+#define BSC_guarded_open_np 0x040c06e4
+#define BSC_guarded_close_np 0x040c06e8
+
+#define BSC_fsgetpath 0x040c06ac
+
+#define BSC_msync_extended 0x040e0104
+#define BSC_pread_extended 0x040e0264
+#define BSC_pwrite_extended 0x040e0268
+#define BSC_mmap_extended 0x040e0314
+#define BSC_mmap_extended2 0x040f0314
// Carbon File Manager support
-#define FILEMGR_PBGETCATALOGINFO 0x1e000020
-#define FILEMGR_PBGETCATALOGINFOBULK 0x1e000024
-#define FILEMGR_PBCREATEFILEUNICODE 0x1e000028
-#define FILEMGR_PBCREATEDIRECTORYUNICODE 0x1e00002c
-#define FILEMGR_PBCREATEFORK 0x1e000030
-#define FILEMGR_PBDELETEFORK 0x1e000034
-#define FILEMGR_PBITERATEFORK 0x1e000038
-#define FILEMGR_PBOPENFORK 0x1e00003c
-#define FILEMGR_PBREADFORK 0x1e000040
-#define FILEMGR_PBWRITEFORK 0x1e000044
-#define FILEMGR_PBALLOCATEFORK 0x1e000048
-#define FILEMGR_PBDELETEOBJECT 0x1e00004c
-#define FILEMGR_PBEXCHANGEOBJECT 0x1e000050
-#define FILEMGR_PBGETFORKCBINFO 0x1e000054
-#define FILEMGR_PBGETVOLUMEINFO 0x1e000058
-#define FILEMGR_PBMAKEFSREF 0x1e00005c
-#define FILEMGR_PBMAKEFSREFUNICODE 0x1e000060
-#define FILEMGR_PBMOVEOBJECT 0x1e000064
-#define FILEMGR_PBOPENITERATOR 0x1e000068
-#define FILEMGR_PBRENAMEUNICODE 0x1e00006c
-#define FILEMGR_PBSETCATALOGINFO 0x1e000070
-#define FILEMGR_PBSETVOLUMEINFO 0x1e000074
-#define FILEMGR_FSREFMAKEPATH 0x1e000078
-#define FILEMGR_FSPATHMAKEREF 0x1e00007c
-
-#define FILEMGR_PBGETCATINFO 0x1e010000
-#define FILEMGR_PBGETCATINFOLITE 0x1e010004
-#define FILEMGR_PBHGETFINFO 0x1e010008
-#define FILEMGR_PBXGETVOLINFO 0x1e01000c
-#define FILEMGR_PBHCREATE 0x1e010010
-#define FILEMGR_PBHOPENDF 0x1e010014
-#define FILEMGR_PBHOPENRF 0x1e010018
-#define FILEMGR_PBHGETDIRACCESS 0x1e01001c
-#define FILEMGR_PBHSETDIRACCESS 0x1e010020
-#define FILEMGR_PBHMAPID 0x1e010024
-#define FILEMGR_PBHMAPNAME 0x1e010028
-#define FILEMGR_PBCLOSE 0x1e01002c
-#define FILEMGR_PBFLUSHFILE 0x1e010030
-#define FILEMGR_PBGETEOF 0x1e010034
-#define FILEMGR_PBSETEOF 0x1e010038
-#define FILEMGR_PBGETFPOS 0x1e01003c
-#define FILEMGR_PBREAD 0x1e010040
-#define FILEMGR_PBWRITE 0x1e010044
-#define FILEMGR_PBGETFCBINFO 0x1e010048
-#define FILEMGR_PBSETFINFO 0x1e01004c
-#define FILEMGR_PBALLOCATE 0x1e010050
-#define FILEMGR_PBALLOCCONTIG 0x1e010054
-#define FILEMGR_PBSETFPOS 0x1e010058
-#define FILEMGR_PBSETCATINFO 0x1e01005c
-#define FILEMGR_PBGETVOLPARMS 0x1e010060
-#define FILEMGR_PBSETVINFO 0x1e010064
-#define FILEMGR_PBMAKEFSSPEC 0x1e010068
-#define FILEMGR_PBHGETVINFO 0x1e01006c
-#define FILEMGR_PBCREATEFILEIDREF 0x1e010070
-#define FILEMGR_PBDELETEFILEIDREF 0x1e010074
-#define FILEMGR_PBRESOLVEFILEIDREF 0x1e010078
-#define FILEMGR_PBFLUSHVOL 0x1e01007c
-#define FILEMGR_PBHRENAME 0x1e010080
-#define FILEMGR_PBCATMOVE 0x1e010084
-#define FILEMGR_PBEXCHANGEFILES 0x1e010088
-#define FILEMGR_PBHDELETE 0x1e01008c
-#define FILEMGR_PBDIRCREATE 0x1e010090
-#define FILEMGR_PBCATSEARCH 0x1e010094
-#define FILEMGR_PBHSETFLOCK 0x1e010098
-#define FILEMGR_PBHRSTFLOCK 0x1e01009c
-#define FILEMGR_PBLOCKRANGE 0x1e0100a0
-#define FILEMGR_PBUNLOCKRANGE 0x1e0100a4
+#define FILEMGR_PBGETCATALOGINFO 0x1e000020
+#define FILEMGR_PBGETCATALOGINFOBULK 0x1e000024
+#define FILEMGR_PBCREATEFILEUNICODE 0x1e000028
+#define FILEMGR_PBCREATEDIRECTORYUNICODE 0x1e00002c
+#define FILEMGR_PBCREATEFORK 0x1e000030
+#define FILEMGR_PBDELETEFORK 0x1e000034
+#define FILEMGR_PBITERATEFORK 0x1e000038
+#define FILEMGR_PBOPENFORK 0x1e00003c
+#define FILEMGR_PBREADFORK 0x1e000040
+#define FILEMGR_PBWRITEFORK 0x1e000044
+#define FILEMGR_PBALLOCATEFORK 0x1e000048
+#define FILEMGR_PBDELETEOBJECT 0x1e00004c
+#define FILEMGR_PBEXCHANGEOBJECT 0x1e000050
+#define FILEMGR_PBGETFORKCBINFO 0x1e000054
+#define FILEMGR_PBGETVOLUMEINFO 0x1e000058
+#define FILEMGR_PBMAKEFSREF 0x1e00005c
+#define FILEMGR_PBMAKEFSREFUNICODE 0x1e000060
+#define FILEMGR_PBMOVEOBJECT 0x1e000064
+#define FILEMGR_PBOPENITERATOR 0x1e000068
+#define FILEMGR_PBRENAMEUNICODE 0x1e00006c
+#define FILEMGR_PBSETCATALOGINFO 0x1e000070
+#define FILEMGR_PBSETVOLUMEINFO 0x1e000074
+#define FILEMGR_FSREFMAKEPATH 0x1e000078
+#define FILEMGR_FSPATHMAKEREF 0x1e00007c
+
+#define FILEMGR_PBGETCATINFO 0x1e010000
+#define FILEMGR_PBGETCATINFOLITE 0x1e010004
+#define FILEMGR_PBHGETFINFO 0x1e010008
+#define FILEMGR_PBXGETVOLINFO 0x1e01000c
+#define FILEMGR_PBHCREATE 0x1e010010
+#define FILEMGR_PBHOPENDF 0x1e010014
+#define FILEMGR_PBHOPENRF 0x1e010018
+#define FILEMGR_PBHGETDIRACCESS 0x1e01001c
+#define FILEMGR_PBHSETDIRACCESS 0x1e010020
+#define FILEMGR_PBHMAPID 0x1e010024
+#define FILEMGR_PBHMAPNAME 0x1e010028
+#define FILEMGR_PBCLOSE 0x1e01002c
+#define FILEMGR_PBFLUSHFILE 0x1e010030
+#define FILEMGR_PBGETEOF 0x1e010034
+#define FILEMGR_PBSETEOF 0x1e010038
+#define FILEMGR_PBGETFPOS 0x1e01003c
+#define FILEMGR_PBREAD 0x1e010040
+#define FILEMGR_PBWRITE 0x1e010044
+#define FILEMGR_PBGETFCBINFO 0x1e010048
+#define FILEMGR_PBSETFINFO 0x1e01004c
+#define FILEMGR_PBALLOCATE 0x1e010050
+#define FILEMGR_PBALLOCCONTIG 0x1e010054
+#define FILEMGR_PBSETFPOS 0x1e010058
+#define FILEMGR_PBSETCATINFO 0x1e01005c
+#define FILEMGR_PBGETVOLPARMS 0x1e010060
+#define FILEMGR_PBSETVINFO 0x1e010064
+#define FILEMGR_PBMAKEFSSPEC 0x1e010068
+#define FILEMGR_PBHGETVINFO 0x1e01006c
+#define FILEMGR_PBCREATEFILEIDREF 0x1e010070
+#define FILEMGR_PBDELETEFILEIDREF 0x1e010074
+#define FILEMGR_PBRESOLVEFILEIDREF 0x1e010078
+#define FILEMGR_PBFLUSHVOL 0x1e01007c
+#define FILEMGR_PBHRENAME 0x1e010080
+#define FILEMGR_PBCATMOVE 0x1e010084
+#define FILEMGR_PBEXCHANGEFILES 0x1e010088
+#define FILEMGR_PBHDELETE 0x1e01008c
+#define FILEMGR_PBDIRCREATE 0x1e010090
+#define FILEMGR_PBCATSEARCH 0x1e010094
+#define FILEMGR_PBHSETFLOCK 0x1e010098
+#define FILEMGR_PBHRSTFLOCK 0x1e01009c
+#define FILEMGR_PBLOCKRANGE 0x1e0100a0
+#define FILEMGR_PBUNLOCKRANGE 0x1e0100a4
#define FILEMGR_CLASS 0x1e
+#define FILEMGR_BASE 0x1e000000
+
+#define FMT_DEFAULT 0
+#define FMT_FD 1
+#define FMT_FD_IO 2
+#define FMT_FD_2 3
+#define FMT_SOCKET 4
+#define FMT_PGIN 5
+#define FMT_PGOUT 6
+#define FMT_CACHEHIT 7
+#define FMT_DISKIO 8
+#define FMT_LSEEK 9
+#define FMT_PREAD 10
+#define FMT_FTRUNC 11
+#define FMT_TRUNC 12
+#define FMT_SELECT 13
+#define FMT_OPEN 14
+#define FMT_AIO_FSYNC 15
+#define FMT_AIO_RETURN 16
+#define FMT_AIO_SUSPEND 17
+#define FMT_AIO_CANCEL 18
+#define FMT_AIO 19
+#define FMT_LIO_LISTIO 20
+#define FMT_MSYNC 21
+#define FMT_FCNTL 22
+#define FMT_ACCESS 23
+#define FMT_CHMOD 24
+#define FMT_FCHMOD 25
+#define FMT_CHMOD_EXT 26
+#define FMT_FCHMOD_EXT 27
+#define FMT_CHFLAGS 28
+#define FMT_FCHFLAGS 29
+#define FMT_IOCTL 30
+#define FMT_MMAP 31
+#define FMT_UMASK 32
+#define FMT_SENDFILE 33
+#define FMT_IOCTL_SYNC 34
+#define FMT_MOUNT 35
+#define FMT_UNMOUNT 36
+#define FMT_DISKIO_CS 37
+#define FMT_SYNC_DISK_CS 38
+#define FMT_IOCTL_UNMAP 39
+#define FMT_UNMAP_INFO 40
+#define FMT_HFS_update 41
+#define FMT_FLOCK 42
+
+#define MAX_BSD_SYSCALL 512
+
+struct bsd_syscall {
+ char *sc_name;
+ int sc_format;
+} bsd_syscalls[MAX_BSD_SYSCALL];
+
+
+int bsd_syscall_types[] = {
+ BSC_recvmsg,
+ BSC_recvmsg_nocancel,
+ BSC_sendmsg,
+ BSC_sendmsg_nocancel,
+ BSC_recvfrom,
+ BSC_recvfrom_nocancel,
+ BSC_accept,
+ BSC_accept_nocancel,
+ BSC_select,
+ BSC_select_nocancel,
+ BSC_socket,
+ BSC_connect,
+ BSC_connect_nocancel,
+ BSC_bind,
+ BSC_listen,
+ BSC_sendto,
+ BSC_sendto_nocancel,
+ BSC_socketpair,
+ BSC_read,
+ BSC_read_nocancel,
+ BSC_write,
+ BSC_write_nocancel,
+ BSC_open,
+ BSC_open_nocancel,
+ BSC_close,
+ BSC_close_nocancel,
+ BSC_link,
+ BSC_unlink,
+ BSC_chdir,
+ BSC_fchdir,
+ BSC_mknod,
+ BSC_chmod,
+ BSC_chown,
+ BSC_access,
+ BSC_chflags,
+ BSC_fchflags,
+ BSC_sync,
+ BSC_dup,
+ BSC_revoke,
+ BSC_symlink,
+ BSC_readlink,
+ BSC_exit,
+ BSC_execve,
+ BSC_posix_spawn,
+ BSC_umask,
+ BSC_chroot,
+ BSC_dup2,
+ BSC_fsync,
+ BSC_fsync_nocancel,
+ BSC_readv,
+ BSC_readv_nocancel,
+ BSC_writev,
+ BSC_writev_nocancel,
+ BSC_fchown,
+ BSC_fchmod,
+ BSC_rename,
+ BSC_mkfifo,
+ BSC_mkdir,
+ BSC_rmdir,
+ BSC_utimes,
+ BSC_futimes,
+ BSC_pread,
+ BSC_pread_nocancel,
+ BSC_pwrite,
+ BSC_pwrite_nocancel,
+ BSC_statfs,
+ BSC_fstatfs,
+ BSC_fdatasync,
+ BSC_stat,
+ BSC_fstat,
+ BSC_lstat,
+ BSC_mount,
+ BSC_unmount,
+ BSC_pathconf,
+ BSC_fpathconf,
+ BSC_getdirentries,
+ BSC_mmap,
+ BSC_lseek,
+ BSC_truncate,
+ BSC_ftruncate,
+ BSC_flock,
+ BSC_undelete,
+ BSC_open_dprotected_np,
+ BSC_getattrlist,
+ BSC_setattrlist,
+ BSC_fgetattrlist,
+ BSC_fsetattrlist,
+ BSC_getdirentriesattr,
+ BSC_exchangedata,
+ BSC_checkuseraccess,
+ BSC_searchfs,
+ BSC_delete,
+ BSC_copyfile,
+ BSC_getxattr,
+ BSC_fgetxattr,
+ BSC_setxattr,
+ BSC_fsetxattr,
+ BSC_removexattr,
+ BSC_fremovexattr,
+ BSC_listxattr,
+ BSC_flistxattr,
+ BSC_fsctl,
+ BSC_ffsctl,
+ BSC_open_extended,
+ BSC_umask_extended,
+ BSC_stat_extended,
+ BSC_lstat_extended,
+ BSC_fstat_extended,
+ BSC_chmod_extended,
+ BSC_fchmod_extended,
+ BSC_access_extended,
+ BSC_mkfifo_extended,
+ BSC_mkdir_extended,
+ BSC_aio_fsync,
+ BSC_aio_return,
+ BSC_aio_suspend,
+ BSC_aio_suspend_nocancel,
+ BSC_aio_cancel,
+ BSC_aio_error,
+ BSC_aio_read,
+ BSC_aio_write,
+ BSC_lio_listio,
+ BSC_lchown,
+ BSC_sendfile,
+ BSC_msync,
+ BSC_msync_nocancel,
+ BSC_fcntl,
+ BSC_fcntl_nocancel,
+ BSC_ioctl,
+ BSC_stat64,
+ BSC_fstat64,
+ BSC_lstat64,
+ BSC_stat64_extended,
+ BSC_lstat64_extended,
+ BSC_fstat64_extended,
+ BSC_getdirentries64,
+ BSC_statfs64,
+ BSC_fstatfs64,
+ BSC_pthread_chdir,
+ BSC_pthread_fchdir,
+ BSC_getfsstat,
+ BSC_getfsstat64,
+ BSC_guarded_open_np,
+ BSC_guarded_close_np,
+ BSC_fsgetpath,
+ 0
+};
+
+
+#define MAX_FILEMGR 512
+
+struct filemgr_call {
+ char *fm_name;
+} filemgr_calls[MAX_FILEMGR];
+
+
+int filemgr_call_types[] = {
+ FILEMGR_PBGETCATALOGINFO,
+ FILEMGR_PBGETCATALOGINFOBULK,
+ FILEMGR_PBCREATEFILEUNICODE,
+ FILEMGR_PBCREATEDIRECTORYUNICODE,
+ FILEMGR_PBCREATEFORK,
+ FILEMGR_PBDELETEFORK,
+ FILEMGR_PBITERATEFORK,
+ FILEMGR_PBOPENFORK,
+ FILEMGR_PBREADFORK,
+ FILEMGR_PBWRITEFORK,
+ FILEMGR_PBALLOCATEFORK,
+ FILEMGR_PBDELETEOBJECT,
+ FILEMGR_PBEXCHANGEOBJECT,
+ FILEMGR_PBGETFORKCBINFO,
+ FILEMGR_PBGETVOLUMEINFO,
+ FILEMGR_PBMAKEFSREF,
+ FILEMGR_PBMAKEFSREFUNICODE,
+ FILEMGR_PBMOVEOBJECT,
+ FILEMGR_PBOPENITERATOR,
+ FILEMGR_PBRENAMEUNICODE,
+ FILEMGR_PBSETCATALOGINFO,
+ FILEMGR_PBSETVOLUMEINFO,
+ FILEMGR_FSREFMAKEPATH,
+ FILEMGR_FSPATHMAKEREF,
+
+ FILEMGR_PBGETCATINFO,
+ FILEMGR_PBGETCATINFOLITE,
+ FILEMGR_PBHGETFINFO,
+ FILEMGR_PBXGETVOLINFO,
+ FILEMGR_PBHCREATE,
+ FILEMGR_PBHOPENDF,
+ FILEMGR_PBHOPENRF,
+ FILEMGR_PBHGETDIRACCESS,
+ FILEMGR_PBHSETDIRACCESS,
+ FILEMGR_PBHMAPID,
+ FILEMGR_PBHMAPNAME,
+ FILEMGR_PBCLOSE,
+ FILEMGR_PBFLUSHFILE,
+ FILEMGR_PBGETEOF,
+ FILEMGR_PBSETEOF,
+ FILEMGR_PBGETFPOS,
+ FILEMGR_PBREAD,
+ FILEMGR_PBWRITE,
+ FILEMGR_PBGETFCBINFO,
+ FILEMGR_PBSETFINFO,
+ FILEMGR_PBALLOCATE,
+ FILEMGR_PBALLOCCONTIG,
+ FILEMGR_PBSETFPOS,
+ FILEMGR_PBSETCATINFO,
+ FILEMGR_PBGETVOLPARMS,
+ FILEMGR_PBSETVINFO,
+ FILEMGR_PBMAKEFSSPEC,
+ FILEMGR_PBHGETVINFO,
+ FILEMGR_PBCREATEFILEIDREF,
+ FILEMGR_PBDELETEFILEIDREF,
+ FILEMGR_PBRESOLVEFILEIDREF,
+ FILEMGR_PBFLUSHVOL,
+ FILEMGR_PBHRENAME,
+ FILEMGR_PBCATMOVE,
+ FILEMGR_PBEXCHANGEFILES,
+ FILEMGR_PBHDELETE,
+ FILEMGR_PBDIRCREATE,
+ FILEMGR_PBCATSEARCH,
+ FILEMGR_PBHSETFLOCK,
+ FILEMGR_PBHRSTFLOCK,
+ FILEMGR_PBLOCKRANGE,
+ FILEMGR_PBUNLOCKRANGE,
+ 0
+};
+
-#define MAX_PIDS 32
+
+#define MAX_PIDS 256
int pids[MAX_PIDS];
int num_of_pids = 0;
int exclude_pids = 0;
int exclude_default_pids = 1;
+
struct kinfo_proc *kp_buffer = 0;
int kp_nentries = 0;
-#define SAMPLE_SIZE 60000
+#define EVENT_BASE 60000
+
+int num_events = EVENT_BASE;
-#define DBG_ZERO_FILL_FAULT 1
-#define DBG_PAGEIN_FAULT 2
-#define DBG_COW_FAULT 3
-#define DBG_CACHE_HIT_FAULT 4
#define DBG_FUNC_ALL (DBG_FUNC_START | DBG_FUNC_END)
#define DBG_FUNC_MASK 0xfffffffc
kbufinfo_t bufinfo = {0, 0, 0, 0, 0};
-int total_threads = 0;
-kd_threadmap *mapptr = 0; /* pointer to list of threads */
/* defines for tracking file descriptor state */
#define FS_USAGE_FD_SETSIZE 256 /* Initial number of file descriptors per
#define FS_USAGE_NFDBITS (sizeof (unsigned long) * 8)
#define FS_USAGE_NFDBYTES(n) (((n) / FS_USAGE_NFDBITS) * sizeof (unsigned long))
-typedef struct {
- unsigned int fd_valid; /* set if this is a valid entry */
- unsigned int fd_thread;
- unsigned int fd_setsize; /* this is a bit count */
- unsigned long *fd_setptr; /* file descripter bitmap */
-} fd_threadmap;
-
-fd_threadmap *fdmapptr = 0; /* pointer to list of threads for fd tracking */
-
int trace_enabled = 0;
int set_remove_flag = 1;
+int BC_flag = 0;
+
+char *RAW_file = (char *)0;
+int RAW_flag = 0;
+int RAW_fd = 0;
+
+uint64_t sample_TOD_secs;
+uint32_t sample_TOD_usecs;
+
+double bias_now = 0.0;
+double start_time = 0.0;
+double end_time = 999999999999.9;
+
+
void set_numbufs();
+void set_filter();
void set_init();
void set_enable();
void sample_sc();
void set_pidexclude();
void set_remove();
+ fflush(0);
+
set_enable(0);
if (exclude_pids == 0) {
set_pidexclude(pids[i], 0);
}
set_remove();
+
exit(0);
}
+int
+quit(s)
+char *s;
+{
+ if (trace_enabled)
+ set_enable(0);
+
+ /*
+ * This flag is turned off when calling
+ * quit() due to a set_remove() failure.
+ */
+ if (set_remove_flag)
+ set_remove();
+
+ fprintf(stderr, "fs_usage: ");
+ if (s)
+ fprintf(stderr, "%s", s);
+
+ exit(1);
+}
+
+
void get_screenwidth()
{
struct winsize size;
columns = MAXCOLS;
if (isatty(1)) {
- if (ioctl(1, TIOCGWINSZ, &size) != -1)
+ if (ioctl(1, TIOCGWINSZ, &size) != -1) {
columns = size.ws_col;
+
+ if (columns > MAXWIDTH)
+ columns = MAXWIDTH;
+ }
}
}
get_screenwidth();
}
+
+void getdivisor()
+{
+ struct mach_timebase_info mti;
+
+ mach_timebase_info(&mti);
+
+ divisor = ((double)mti.denom / (double)mti.numer) * 1000;
+}
+
+
int
exit_usage(char *myname) {
- fprintf(stderr, "Usage: %s [-e] [-w] [-f mode] [pid | cmd [pid | cmd]....]\n", myname);
+ 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);
fprintf(stderr, " -e exclude the specified list of pids from the sample\n");
fprintf(stderr, " and exclude fs_usage by default\n");
fprintf(stderr, " -w force wider, detailed, output\n");
- fprintf(stderr, " -f Output is filtered based on the mode provided\n");
- fprintf(stderr, " mode = \"network\" Show only network related output\n");
- fprintf(stderr, " mode = \"filesys\" Show only file system related output\n");
+ fprintf(stderr, " -f output is based on the mode provided\n");
+ fprintf(stderr, " mode = \"network\" Show network-related events\n");
+ fprintf(stderr, " mode = \"filesys\" Show filesystem-related events\n");
+ fprintf(stderr, " mode = \"pathname\" Show only pathname-related events\n");
+ fprintf(stderr, " mode = \"exec\" Show only exec and spawn events\n");
+ fprintf(stderr, " mode = \"diskio\" Show only disk I/O events\n");
+ fprintf(stderr, " mode = \"cachehit\" In addition, show cache hits\n");
+ fprintf(stderr, " -b annotate disk I/O events with BootCache info (if available)\n");
+ fprintf(stderr, " -t specifies timeout in seconds (for use in automated tools)\n");
+ fprintf(stderr, " -R specifies a raw trace file to process\n");
+ fprintf(stderr, " -S if -R is specified, selects a start point in microseconds\n");
+ fprintf(stderr, " -E if -R is specified, selects an end point in microseconds\n");
fprintf(stderr, " pid selects process(s) to sample\n");
fprintf(stderr, " cmd selects process(s) matching command string to sample\n");
fprintf(stderr, "\n%s will handle a maximum list of %d pids.\n\n", myname, MAX_PIDS);
exit(1);
}
-int
-main(argc, argv)
- int argc;
- char *argv[];
-{
- char *myname = "fs_usage";
- int i;
- char ch;
- void getdivisor();
- void argtopid();
- void set_remove();
- void set_pidcheck();
- void set_pidexclude();
- int quit();
- if ( geteuid() != 0 ) {
- printf("'fs_usage' must be run as root...\n");
- exit(1);
- }
- get_screenwidth();
+int filemgr_index(type) {
- /* get our name */
- if (argc > 0) {
- if ((myname = rindex(argv[0], '/')) == 0) {
- myname = argv[0];
- }
- else {
- myname++;
- }
- }
+ if (type & 0x10000)
+ return (((type >> 2) & 0x3fff) + 256);
-
- while ((ch = getopt(argc, argv, "ewf:")) != EOF) {
- switch(ch) {
- case 'e':
- exclude_pids = 1;
- exclude_default_pids = 0;
- break;
- case 'w':
- wideflag = 1;
- if ((uint)columns < MAX_WIDE_MODE_COLS)
- columns = MAX_WIDE_MODE_COLS;
- break;
- case 'f':
- if (!strcmp(optarg, "network"))
- filter_mode |= NETWORK_FILTER;
- else if (!strcmp(optarg, "filesys"))
- filter_mode |= FILESYS_FILTER;
- break;
-
- default:
- exit_usage(myname);
- }
- }
+ return (((type >> 2) & 0x3fff));
+}
- argc -= optind;
- argv += optind;
- /* If we process any list of pids/cmds, then turn off the defaults */
- if (argc > 0)
- exclude_default_pids = 0;
+void init_tables(void)
+{ int i;
+ int type;
+ int code;
- while (argc > 0 && num_of_pids < (MAX_PIDS - 1)) {
- select_pid_mode++;
- argtopid(argv[0]);
- argc--;
- argv++;
- }
-
- /* Exclude a set of default pids */
- if (exclude_default_pids)
- {
- argtopid("Terminal");
- argtopid("telnetd");
- argtopid("telnet");
- argtopid("sshd");
- argtopid("rlogind");
- argtopid("tcsh");
- argtopid("csh");
- argtopid("sh");
- exclude_pids = 1;
- }
-
- if (exclude_pids)
- {
- if (num_of_pids < (MAX_PIDS - 1))
- pids[num_of_pids++] = getpid();
- else
- exit_usage(myname);
- }
-#if 0
- for (i = 0; i < num_of_pids; i++)
- {
- if (exclude_pids)
- printf("exclude pid %d\n", pids[i]);
- else
- printf("pid %d\n", pids[i]);
- }
-#endif
+ for (i = 0; i < MAX_BSD_SYSCALL; i++) {
+ bsd_syscalls[i].sc_name = NULL;
+ bsd_syscalls[i].sc_format = FMT_DEFAULT;
+ }
- /* set up signal handlers */
- signal(SIGINT, leave);
- signal(SIGQUIT, leave);
- signal(SIGHUP, leave);
- signal(SIGTERM, leave);
- signal(SIGWINCH, sigwinch);
+ for (i = 0; i < MAX_FILEMGR; i++) {
+ filemgr_calls[i].fm_name = NULL;
+ }
- if ((my_buffer = malloc(SAMPLE_SIZE * sizeof(kd_buf))) == (char *)0)
- quit("can't allocate memory for tracing info\n");
+ for (i = 0; (type = bsd_syscall_types[i]); i++) {
- ReadSegAddrTable();
- cache_disk_names();
+ code = BSC_INDEX(type);
- set_remove();
- set_numbufs(SAMPLE_SIZE);
- set_init();
+ if (code >= MAX_BSD_SYSCALL) {
+ printf("BSD syscall init (%x): type exceeds table size\n", type);
+ continue;
+ }
+ switch (type) {
- if (exclude_pids == 0) {
- for (i = 0; i < num_of_pids; i++)
- set_pidcheck(pids[i], 1);
- } else {
- for (i = 0; i < num_of_pids; i++)
- set_pidexclude(pids[i], 1);
+ case BSC_sendfile:
+ bsd_syscalls[code].sc_name = "sendfile";
+ bsd_syscalls[code].sc_format = FMT_FD; /* this should be changed to FMT_SENDFILE */
+ break; /* once we add an extended info trace event */
+
+ case BSC_recvmsg:
+ case BSC_recvmsg_nocancel:
+ bsd_syscalls[code].sc_name = "recvmsg";
+ bsd_syscalls[code].sc_format = FMT_FD_IO;
+ break;
+
+ case BSC_sendmsg:
+ case BSC_sendmsg_nocancel:
+ bsd_syscalls[code].sc_name = "sendmsg";
+ bsd_syscalls[code].sc_format = FMT_FD_IO;
+ break;
+
+ case BSC_recvfrom:
+ case BSC_recvfrom_nocancel:
+ bsd_syscalls[code].sc_name = "recvfrom";
+ bsd_syscalls[code].sc_format = FMT_FD_IO;
+ break;
+
+ case BSC_sendto:
+ case BSC_sendto_nocancel:
+ bsd_syscalls[code].sc_name = "sendto";
+ bsd_syscalls[code].sc_format = FMT_FD_IO;
+ break;
+
+ case BSC_select:
+ case BSC_select_nocancel:
+ bsd_syscalls[code].sc_name = "select";
+ bsd_syscalls[code].sc_format = FMT_SELECT;
+ break;
+
+ case BSC_accept:
+ case BSC_accept_nocancel:
+ bsd_syscalls[code].sc_name = "accept";
+ bsd_syscalls[code].sc_format = FMT_FD_2;
+ break;
+
+ case BSC_socket:
+ bsd_syscalls[code].sc_name = "socket";
+ bsd_syscalls[code].sc_format = FMT_SOCKET;
+ break;
+
+ case BSC_connect:
+ case BSC_connect_nocancel:
+ bsd_syscalls[code].sc_name = "connect";
+ bsd_syscalls[code].sc_format = FMT_FD;
+ break;
+
+ case BSC_bind:
+ bsd_syscalls[code].sc_name = "bind";
+ bsd_syscalls[code].sc_format = FMT_FD;
+ break;
+
+ case BSC_listen:
+ bsd_syscalls[code].sc_name = "listen";
+ bsd_syscalls[code].sc_format = FMT_FD;
+ break;
+
+ case BSC_mmap:
+ bsd_syscalls[code].sc_name = "mmap";
+ bsd_syscalls[code].sc_format = FMT_MMAP;
+ break;
+
+ case BSC_socketpair:
+ bsd_syscalls[code].sc_name = "socketpair";
+ break;
+
+ case BSC_getxattr:
+ bsd_syscalls[code].sc_name = "getxattr";
+ break;
+
+ case BSC_setxattr:
+ bsd_syscalls[code].sc_name = "setxattr";
+ break;
+
+ case BSC_removexattr:
+ bsd_syscalls[code].sc_name = "removexattr";
+ break;
+
+ case BSC_listxattr:
+ bsd_syscalls[code].sc_name = "listxattr";
+ break;
+
+ case BSC_stat:
+ bsd_syscalls[code].sc_name = "stat";
+ break;
+
+ case BSC_stat64:
+ bsd_syscalls[code].sc_name = "stat64";
+ break;
+
+ case BSC_stat_extended:
+ bsd_syscalls[code].sc_name = "stat_extended";
+ break;
+
+ case BSC_stat64_extended:
+ bsd_syscalls[code].sc_name = "stat_extended64";
+ break;
+
+ case BSC_mount:
+ bsd_syscalls[code].sc_name = "mount";
+ bsd_syscalls[code].sc_format = FMT_MOUNT;
+ break;
+
+ case BSC_unmount:
+ bsd_syscalls[code].sc_name = "unmount";
+ bsd_syscalls[code].sc_format = FMT_UNMOUNT;
+ break;
+
+ case BSC_exit:
+ bsd_syscalls[code].sc_name = "exit";
+ break;
+
+ case BSC_execve:
+ bsd_syscalls[code].sc_name = "execve";
+ break;
+
+ case BSC_posix_spawn:
+ bsd_syscalls[code].sc_name = "posix_spawn";
+ break;
+
+ case BSC_open:
+ case BSC_open_nocancel:
+ bsd_syscalls[code].sc_name = "open";
+ bsd_syscalls[code].sc_format = FMT_OPEN;
+ break;
+
+ case BSC_open_extended:
+ bsd_syscalls[code].sc_name = "open_extended";
+ bsd_syscalls[code].sc_format = FMT_OPEN;
+ break;
+
+ case BSC_guarded_open_np:
+ bsd_syscalls[code].sc_name = "guarded_open_np";
+ bsd_syscalls[code].sc_format = FMT_OPEN;
+ break;
+
+ case BSC_open_dprotected_np:
+ bsd_syscalls[code].sc_name = "open_dprotected";
+ bsd_syscalls[code].sc_format = FMT_OPEN;
+ break;
+
+ case BSC_dup:
+ bsd_syscalls[code].sc_name = "dup";
+ bsd_syscalls[code].sc_format = FMT_FD_2;
+ break;
+
+ case BSC_dup2:
+ bsd_syscalls[code].sc_name = "dup2";
+ bsd_syscalls[code].sc_format = FMT_FD_2;
+ break;
+
+ case BSC_close:
+ case BSC_close_nocancel:
+ bsd_syscalls[code].sc_name = "close";
+ bsd_syscalls[code].sc_format = FMT_FD;
+ break;
+
+ case BSC_guarded_close_np:
+ bsd_syscalls[code].sc_name = "guarded_close_np";
+ bsd_syscalls[code].sc_format = FMT_FD;
+ break;
+
+ case BSC_read:
+ case BSC_read_nocancel:
+ bsd_syscalls[code].sc_name = "read";
+ bsd_syscalls[code].sc_format = FMT_FD_IO;
+ break;
+
+ case BSC_write:
+ case BSC_write_nocancel:
+ bsd_syscalls[code].sc_name = "write";
+ bsd_syscalls[code].sc_format = FMT_FD_IO;
+ break;
+
+ case BSC_fgetxattr:
+ bsd_syscalls[code].sc_name = "fgetxattr";
+ bsd_syscalls[code].sc_format = FMT_FD;
+ break;
+
+ case BSC_fsetxattr:
+ bsd_syscalls[code].sc_name = "fsetxattr";
+ bsd_syscalls[code].sc_format = FMT_FD;
+ break;
+
+ case BSC_fremovexattr:
+ bsd_syscalls[code].sc_name = "fremovexattr";
+ bsd_syscalls[code].sc_format = FMT_FD;
+ break;
+
+ case BSC_flistxattr:
+ bsd_syscalls[code].sc_name = "flistxattr";
+ bsd_syscalls[code].sc_format = FMT_FD;
+ break;
+
+ case BSC_fstat:
+ bsd_syscalls[code].sc_name = "fstat";
+ bsd_syscalls[code].sc_format = FMT_FD;
+ break;
+
+ case BSC_fstat64:
+ bsd_syscalls[code].sc_name = "fstat64";
+ bsd_syscalls[code].sc_format = FMT_FD;
+ break;
+
+ case BSC_fstat_extended:
+ bsd_syscalls[code].sc_name = "fstat_extended";
+ bsd_syscalls[code].sc_format = FMT_FD;
+ break;
+
+ case BSC_fstat64_extended:
+ bsd_syscalls[code].sc_name = "fstat64_extended";
+ bsd_syscalls[code].sc_format = FMT_FD;
+ break;
+
+ case BSC_lstat:
+ bsd_syscalls[code].sc_name = "lstat";
+ break;
+
+ case BSC_lstat64:
+ bsd_syscalls[code].sc_name = "lstat64";
+ break;
+
+ case BSC_lstat_extended:
+ bsd_syscalls[code].sc_name = "lstat_extended";
+ break;
+
+ case BSC_lstat64_extended:
+ bsd_syscalls[code].sc_name = "lstat_extended64";
+ break;
+
+ case BSC_link:
+ bsd_syscalls[code].sc_name = "link";
+ break;
+
+ case BSC_unlink:
+ bsd_syscalls[code].sc_name = "unlink";
+ break;
+
+ case BSC_mknod:
+ bsd_syscalls[code].sc_name = "mknod";
+ break;
+
+ case BSC_umask:
+ bsd_syscalls[code].sc_name = "umask";
+ bsd_syscalls[code].sc_format = FMT_UMASK;
+ break;
+
+ case BSC_umask_extended:
+ bsd_syscalls[code].sc_name = "umask_extended";
+ bsd_syscalls[code].sc_format = FMT_UMASK;
+ break;
+
+ case BSC_chmod:
+ bsd_syscalls[code].sc_name = "chmod";
+ bsd_syscalls[code].sc_format = FMT_CHMOD;
+ break;
+
+ case BSC_chmod_extended:
+ bsd_syscalls[code].sc_name = "chmod_extended";
+ bsd_syscalls[code].sc_format = FMT_CHMOD_EXT;
+ break;
+
+ case BSC_fchmod:
+ bsd_syscalls[code].sc_name = "fchmod";
+ bsd_syscalls[code].sc_format = FMT_FCHMOD;
+ break;
+
+ case BSC_fchmod_extended:
+ bsd_syscalls[code].sc_name = "fchmod_extended";
+ bsd_syscalls[code].sc_format = FMT_FCHMOD_EXT;
+ break;
+
+ case BSC_chown:
+ bsd_syscalls[code].sc_name = "chown";
+ break;
+
+ case BSC_lchown:
+ bsd_syscalls[code].sc_name = "lchown";
+ break;
+
+ case BSC_fchown:
+ bsd_syscalls[code].sc_name = "fchown";
+ bsd_syscalls[code].sc_format = FMT_FD;
+ break;
+
+ case BSC_access:
+ bsd_syscalls[code].sc_name = "access";
+ bsd_syscalls[code].sc_format = FMT_ACCESS;
+ break;
+
+ case BSC_access_extended:
+ bsd_syscalls[code].sc_name = "access_extended";
+ break;
+
+ case BSC_chdir:
+ bsd_syscalls[code].sc_name = "chdir";
+ break;
+
+ case BSC_pthread_chdir:
+ bsd_syscalls[code].sc_name = "pthread_chdir";
+ break;
+
+ case BSC_chroot:
+ bsd_syscalls[code].sc_name = "chroot";
+ break;
+
+ case BSC_utimes:
+ bsd_syscalls[code].sc_name = "utimes";
+ break;
+
+ case BSC_delete:
+ bsd_syscalls[code].sc_name = "delete-Carbon";
+ break;
+
+ case BSC_undelete:
+ bsd_syscalls[code].sc_name = "undelete";
+ break;
+
+ case BSC_revoke:
+ bsd_syscalls[code].sc_name = "revoke";
+ break;
+
+ case BSC_fsctl:
+ bsd_syscalls[code].sc_name = "fsctl";
+ break;
+
+ case BSC_ffsctl:
+ bsd_syscalls[code].sc_name = "ffsctl";
+ bsd_syscalls[code].sc_format = FMT_FD;
+ break;
+
+ case BSC_chflags:
+ bsd_syscalls[code].sc_name = "chflags";
+ bsd_syscalls[code].sc_format = FMT_CHFLAGS;
+ break;
+
+ case BSC_fchflags:
+ bsd_syscalls[code].sc_name = "fchflags";
+ bsd_syscalls[code].sc_format = FMT_FCHFLAGS;
+ break;
+
+ case BSC_fchdir:
+ bsd_syscalls[code].sc_name = "fchdir";
+ bsd_syscalls[code].sc_format = FMT_FD;
+ break;
+
+ case BSC_pthread_fchdir:
+ bsd_syscalls[code].sc_name = "pthread_fchdir";
+ bsd_syscalls[code].sc_format = FMT_FD;
+ break;
+
+ case BSC_futimes:
+ bsd_syscalls[code].sc_name = "futimes";
+ bsd_syscalls[code].sc_format = FMT_FD;
+ break;
+
+ case BSC_sync:
+ bsd_syscalls[code].sc_name = "sync";
+ break;
+
+ case BSC_symlink:
+ bsd_syscalls[code].sc_name = "symlink";
+ break;
+
+ case BSC_readlink:
+ bsd_syscalls[code].sc_name = "readlink";
+ break;
+
+ case BSC_fsync:
+ case BSC_fsync_nocancel:
+ bsd_syscalls[code].sc_name = "fsync";
+ bsd_syscalls[code].sc_format = FMT_FD;
+ break;
+
+ case BSC_fdatasync:
+ bsd_syscalls[code].sc_name = "fdatasync";
+ bsd_syscalls[code].sc_format = FMT_FD;
+ break;
+
+ case BSC_readv:
+ case BSC_readv_nocancel:
+ bsd_syscalls[code].sc_name = "readv";
+ bsd_syscalls[code].sc_format = FMT_FD_IO;
+ break;
+
+ case BSC_writev:
+ case BSC_writev_nocancel:
+ bsd_syscalls[code].sc_name = "writev";
+ bsd_syscalls[code].sc_format = FMT_FD_IO;
+ break;
+
+ case BSC_pread:
+ case BSC_pread_nocancel:
+ bsd_syscalls[code].sc_name = "pread";
+ bsd_syscalls[code].sc_format = FMT_PREAD;
+ break;
+
+ case BSC_pwrite:
+ case BSC_pwrite_nocancel:
+ bsd_syscalls[code].sc_name = "pwrite";
+ bsd_syscalls[code].sc_format = FMT_PREAD;
+ break;
+
+ case BSC_mkdir:
+ bsd_syscalls[code].sc_name = "mkdir";
+ break;
+
+ case BSC_mkdir_extended:
+ bsd_syscalls[code].sc_name = "mkdir_extended";
+ break;
+
+ case BSC_mkfifo:
+ bsd_syscalls[code].sc_name = "mkfifo";
+ break;
+
+ case BSC_mkfifo_extended:
+ bsd_syscalls[code].sc_name = "mkfifo_extended";
+ break;
+
+ case BSC_rmdir:
+ bsd_syscalls[code].sc_name = "rmdir";
+ break;
+
+ case BSC_statfs:
+ bsd_syscalls[code].sc_name = "statfs";
+ break;
+
+ case BSC_statfs64:
+ bsd_syscalls[code].sc_name = "statfs64";
+ break;
+
+ case BSC_getfsstat:
+ bsd_syscalls[code].sc_name = "getfsstat";
+ break;
+
+ case BSC_getfsstat64:
+ bsd_syscalls[code].sc_name = "getfsstat64";
+ break;
+
+ case BSC_fstatfs:
+ bsd_syscalls[code].sc_name = "fstatfs";
+ bsd_syscalls[code].sc_format = FMT_FD;
+ break;
+
+ case BSC_fstatfs64:
+ bsd_syscalls[code].sc_name = "fstatfs64";
+ bsd_syscalls[code].sc_format = FMT_FD;
+ break;
+
+ case BSC_pathconf:
+ bsd_syscalls[code].sc_name = "pathconf";
+ break;
+
+ case BSC_fpathconf:
+ bsd_syscalls[code].sc_name = "fpathconf";
+ bsd_syscalls[code].sc_format = FMT_FD;
+ break;
+
+ case BSC_getdirentries:
+ bsd_syscalls[code].sc_name = "getdirentries";
+ bsd_syscalls[code].sc_format = FMT_FD_IO;
+ break;
+
+ case BSC_getdirentries64:
+ bsd_syscalls[code].sc_name = "getdirentries64";
+ bsd_syscalls[code].sc_format = FMT_FD_IO;
+ break;
+
+ case BSC_lseek:
+ bsd_syscalls[code].sc_name = "lseek";
+ bsd_syscalls[code].sc_format = FMT_LSEEK;
+ break;
+
+ case BSC_truncate:
+ bsd_syscalls[code].sc_name = "truncate";
+ bsd_syscalls[code].sc_format = FMT_TRUNC;
+ break;
+
+ case BSC_ftruncate:
+ bsd_syscalls[code].sc_name = "ftruncate";
+ bsd_syscalls[code].sc_format = FMT_FTRUNC;
+ break;
+
+ case BSC_flock:
+ bsd_syscalls[code].sc_name = "flock";
+ bsd_syscalls[code].sc_format = FMT_FLOCK;
+ break;
+
+ case BSC_getattrlist:
+ bsd_syscalls[code].sc_name = "getattrlist";
+ break;
+
+ case BSC_setattrlist:
+ bsd_syscalls[code].sc_name = "setattrlist";
+ break;
+
+ case BSC_fgetattrlist:
+ bsd_syscalls[code].sc_name = "fgetattrlist";
+ bsd_syscalls[code].sc_format = FMT_FD;
+ break;
+
+ case BSC_fsetattrlist:
+ bsd_syscalls[code].sc_name = "fsetattrlist";
+ bsd_syscalls[code].sc_format = FMT_FD;
+ break;
+
+ case BSC_getdirentriesattr:
+ bsd_syscalls[code].sc_name = "getdirentriesattr";
+ bsd_syscalls[code].sc_format = FMT_FD;
+ break;
+
+ case BSC_exchangedata:
+ bsd_syscalls[code].sc_name = "exchangedata";
+ break;
+
+ case BSC_rename:
+ bsd_syscalls[code].sc_name = "rename";
+ break;
+
+ case BSC_copyfile:
+ bsd_syscalls[code].sc_name = "copyfile";
+ break;
+
+ case BSC_checkuseraccess:
+ bsd_syscalls[code].sc_name = "checkuseraccess";
+ break;
+
+ case BSC_searchfs:
+ bsd_syscalls[code].sc_name = "searchfs";
+ break;
+
+ case BSC_aio_fsync:
+ bsd_syscalls[code].sc_name = "aio_fsync";
+ bsd_syscalls[code].sc_format = FMT_AIO_FSYNC;
+ break;
+
+ case BSC_aio_return:
+ bsd_syscalls[code].sc_name = "aio_return";
+ bsd_syscalls[code].sc_format = FMT_AIO_RETURN;
+ break;
+
+ case BSC_aio_suspend:
+ case BSC_aio_suspend_nocancel:
+ bsd_syscalls[code].sc_name = "aio_suspend";
+ bsd_syscalls[code].sc_format = FMT_AIO_SUSPEND;
+ break;
+
+ case BSC_aio_cancel:
+ bsd_syscalls[code].sc_name = "aio_cancel";
+ bsd_syscalls[code].sc_format = FMT_AIO_CANCEL;
+ break;
+
+ case BSC_aio_error:
+ bsd_syscalls[code].sc_name = "aio_error";
+ bsd_syscalls[code].sc_format = FMT_AIO;
+ break;
+
+ case BSC_aio_read:
+ bsd_syscalls[code].sc_name = "aio_read";
+ bsd_syscalls[code].sc_format = FMT_AIO;
+ break;
+
+ case BSC_aio_write:
+ bsd_syscalls[code].sc_name = "aio_write";
+ bsd_syscalls[code].sc_format = FMT_AIO;
+ break;
+
+ case BSC_lio_listio:
+ bsd_syscalls[code].sc_name = "lio_listio";
+ bsd_syscalls[code].sc_format = FMT_LIO_LISTIO;
+ break;
+
+ case BSC_msync:
+ case BSC_msync_nocancel:
+ bsd_syscalls[code].sc_name = "msync";
+ bsd_syscalls[code].sc_format = FMT_MSYNC;
+ break;
+
+ case BSC_fcntl:
+ case BSC_fcntl_nocancel:
+ bsd_syscalls[code].sc_name = "fcntl";
+ bsd_syscalls[code].sc_format = FMT_FCNTL;
+ break;
+
+ case BSC_ioctl:
+ bsd_syscalls[code].sc_name = "ioctl";
+ bsd_syscalls[code].sc_format = FMT_IOCTL;
+ break;
+
+ case BSC_fsgetpath:
+ bsd_syscalls[code].sc_name = "fsgetpath";
+ break;
+ }
}
- if (select_pid_mode && !one_good_pid)
- {
- /*
- An attempt to restrict output to a given
- pid or command has failed. Exit gracefully
- */
- set_remove();
- exit_usage(myname);
- }
+ for (i = 0; (type = filemgr_call_types[i]); i++) {
+ char * p;
- set_enable(1);
- getdivisor();
- init_arguments_buffer();
+ code = filemgr_index(type);
+ if (code >= MAX_FILEMGR) {
+ printf("FILEMGR call init (%x): type exceeds table size\n", type);
+ continue;
+ }
+ switch (type) {
- /* main loop */
+ case FILEMGR_PBGETCATALOGINFO:
+ p = "GetCatalogInfo";
+ break;
- while (1) {
- usleep(1000 * 25);
+ case FILEMGR_PBGETCATALOGINFOBULK:
+ p = "GetCatalogInfoBulk";
+ break;
- sample_sc();
- }
-}
+ case FILEMGR_PBCREATEFILEUNICODE:
+ p = "CreateFileUnicode";
+ break;
-void
-find_proc_names()
-{
- size_t bufSize = 0;
- struct kinfo_proc *kp;
- int quit();
+ case FILEMGR_PBCREATEDIRECTORYUNICODE:
+ p = "CreateDirectoryUnicode";
+ break;
- mib[0] = CTL_KERN;
- mib[1] = KERN_PROC;
- mib[2] = KERN_PROC_ALL;
- mib[3] = 0;
+ case FILEMGR_PBCREATEFORK:
+ p = "PBCreateFork";
+ break;
- if (sysctl(mib, 4, NULL, &bufSize, NULL, 0) < 0)
- quit("trace facility failure, KERN_PROC_ALL\n");
+ case FILEMGR_PBDELETEFORK:
+ p = "PBDeleteFork";
+ break;
- if((kp = (struct kinfo_proc *)malloc(bufSize)) == (struct kinfo_proc *)0)
- quit("can't allocate memory for proc buffer\n");
-
- if (sysctl(mib, 4, kp, &bufSize, NULL, 0) < 0)
- quit("trace facility failure, KERN_PROC_ALL\n");
+ case FILEMGR_PBITERATEFORK:
+ p = "PBIterateFork";
+ break;
- kp_nentries = bufSize/ sizeof(struct kinfo_proc);
- kp_buffer = kp;
-}
+ case FILEMGR_PBOPENFORK:
+ p = "PBOpenFork";
+ break;
+ case FILEMGR_PBREADFORK:
+ p = "PBReadFork";
+ break;
-struct th_info *find_thread(int thread, int type) {
- struct th_info *ti;
-
- for (ti = th_state; ti < &th_state[cur_max]; ti++) {
- if (ti->thread == thread) {
- if (type == ti->type)
- return(ti);
- if (ti->in_filemgr) {
- if (type == -1)
- return(ti);
- continue;
- }
- if (type == 0)
- return(ti);
- }
- }
- return ((struct th_info *)0);
-}
+ case FILEMGR_PBWRITEFORK:
+ p = "PBWriteFork";
+ break;
+ case FILEMGR_PBALLOCATEFORK:
+ p = "PBAllocateFork";
+ break;
-void
-mark_thread_waited(int thread) {
- struct th_info *ti;
+ case FILEMGR_PBDELETEOBJECT:
+ p = "PBDeleteObject";
+ break;
- for (ti = th_state; ti < &th_state[cur_max]; ti++) {
- if (ti->thread == thread) {
- ti->waited = 1;
- }
- }
-}
+ case FILEMGR_PBEXCHANGEOBJECT:
+ p = "PBExchangeObject";
+ break;
+ case FILEMGR_PBGETFORKCBINFO:
+ p = "PBGetForkCBInfo";
+ break;
-void
-set_enable(int val)
-{
- mib[0] = CTL_KERN;
- mib[1] = KERN_KDEBUG;
- mib[2] = KERN_KDENABLE; /* protocol */
- mib[3] = val;
- mib[4] = 0;
- mib[5] = 0; /* no flags */
- if (sysctl(mib, 4, NULL, &needed, NULL, 0) < 0)
- quit("trace facility failure, KERN_KDENABLE\n");
+ case FILEMGR_PBGETVOLUMEINFO:
+ p = "PBGetVolumeInfo";
+ break;
+
+ case FILEMGR_PBMAKEFSREF:
+ p = "PBMakeFSRef";
+ break;
- if (val)
- trace_enabled = 1;
- else
- trace_enabled = 0;
-}
+ case FILEMGR_PBMAKEFSREFUNICODE:
+ p = "PBMakeFSRefUnicode";
+ break;
-void
+ case FILEMGR_PBMOVEOBJECT:
+ p = "PBMoveObject";
+ break;
+
+ case FILEMGR_PBOPENITERATOR:
+ p = "PBOpenIterator";
+ break;
+
+ case FILEMGR_PBRENAMEUNICODE:
+ p = "PBRenameUnicode";
+ break;
+
+ case FILEMGR_PBSETCATALOGINFO:
+ p = "SetCatalogInfo";
+ break;
+
+ case FILEMGR_PBSETVOLUMEINFO:
+ p = "SetVolumeInfo";
+ break;
+
+ case FILEMGR_FSREFMAKEPATH:
+ p = "FSRefMakePath";
+ break;
+
+ case FILEMGR_FSPATHMAKEREF:
+ p = "FSPathMakeRef";
+ break;
+
+ case FILEMGR_PBGETCATINFO:
+ p = "GetCatInfo";
+ break;
+
+ case FILEMGR_PBGETCATINFOLITE:
+ p = "GetCatInfoLite";
+ break;
+
+ case FILEMGR_PBHGETFINFO:
+ p = "PBHGetFInfo";
+ break;
+
+ case FILEMGR_PBXGETVOLINFO:
+ p = "PBXGetVolInfo";
+ break;
+
+ case FILEMGR_PBHCREATE:
+ p = "PBHCreate";
+ break;
+
+ case FILEMGR_PBHOPENDF:
+ p = "PBHOpenDF";
+ break;
+
+ case FILEMGR_PBHOPENRF:
+ p = "PBHOpenRF";
+ break;
+
+ case FILEMGR_PBHGETDIRACCESS:
+ p = "PBHGetDirAccess";
+ break;
+
+ case FILEMGR_PBHSETDIRACCESS:
+ p = "PBHSetDirAccess";
+ break;
+
+ case FILEMGR_PBHMAPID:
+ p = "PBHMapID";
+ break;
+
+ case FILEMGR_PBHMAPNAME:
+ p = "PBHMapName";
+ break;
+
+ case FILEMGR_PBCLOSE:
+ p = "PBClose";
+ break;
+
+ case FILEMGR_PBFLUSHFILE:
+ p = "PBFlushFile";
+ break;
+
+ case FILEMGR_PBGETEOF:
+ p = "PBGetEOF";
+ break;
+
+ case FILEMGR_PBSETEOF:
+ p = "PBSetEOF";
+ break;
+
+ case FILEMGR_PBGETFPOS:
+ p = "PBGetFPos";
+ break;
+
+ case FILEMGR_PBREAD:
+ p = "PBRead";
+ break;
+
+ case FILEMGR_PBWRITE:
+ p = "PBWrite";
+ break;
+
+ case FILEMGR_PBGETFCBINFO:
+ p = "PBGetFCBInfo";
+ break;
+
+ case FILEMGR_PBSETFINFO:
+ p = "PBSetFInfo";
+ break;
+
+ case FILEMGR_PBALLOCATE:
+ p = "PBAllocate";
+ break;
+
+ case FILEMGR_PBALLOCCONTIG:
+ p = "PBAllocContig";
+ break;
+
+ case FILEMGR_PBSETFPOS:
+ p = "PBSetFPos";
+ break;
+
+ case FILEMGR_PBSETCATINFO:
+ p = "PBSetCatInfo";
+ break;
+
+ case FILEMGR_PBGETVOLPARMS:
+ p = "PBGetVolParms";
+ break;
+
+ case FILEMGR_PBSETVINFO:
+ p = "PBSetVInfo";
+ break;
+
+ case FILEMGR_PBMAKEFSSPEC:
+ p = "PBMakeFSSpec";
+ break;
+
+ case FILEMGR_PBHGETVINFO:
+ p = "PBHGetVInfo";
+ break;
+
+ case FILEMGR_PBCREATEFILEIDREF:
+ p = "PBCreateFileIDRef";
+ break;
+
+ case FILEMGR_PBDELETEFILEIDREF:
+ p = "PBDeleteFileIDRef";
+ break;
+
+ case FILEMGR_PBRESOLVEFILEIDREF:
+ p = "PBResolveFileIDRef";
+ break;
+
+ case FILEMGR_PBFLUSHVOL:
+ p = "PBFlushVol";
+ break;
+
+ case FILEMGR_PBHRENAME:
+ p = "PBHRename";
+ break;
+
+ case FILEMGR_PBCATMOVE:
+ p = "PBCatMove";
+ break;
+
+ case FILEMGR_PBEXCHANGEFILES:
+ p = "PBExchangeFiles";
+ break;
+
+ case FILEMGR_PBHDELETE:
+ p = "PBHDelete";
+ break;
+
+ case FILEMGR_PBDIRCREATE:
+ p = "PBDirCreate";
+ break;
+
+ case FILEMGR_PBCATSEARCH:
+ p = "PBCatSearch";
+ break;
+
+ case FILEMGR_PBHSETFLOCK:
+ p = "PBHSetFlock";
+ break;
+
+ case FILEMGR_PBHRSTFLOCK:
+ p = "PBHRstFLock";
+ break;
+
+ case FILEMGR_PBLOCKRANGE:
+ p = "PBLockRange";
+ break;
+
+ case FILEMGR_PBUNLOCKRANGE:
+ p = "PBUnlockRange";
+ break;
+
+ default:
+ p = NULL;
+ break;
+ }
+ filemgr_calls[code].fm_name = p;
+ }
+}
+
+
+
+int
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+ char *myname = "fs_usage";
+ int i;
+ char ch;
+
+ time_t stop_at_time = 0;
+
+ if (0 != reexec_to_match_kernel()) {
+ fprintf(stderr, "Could not re-execute: %d\n", errno);
+ exit(1);
+ }
+ get_screenwidth();
+
+ /*
+ * get our name
+ */
+ if (argc > 0) {
+ if ((myname = rindex(argv[0], '/')) == 0)
+ myname = argv[0];
+ else
+ myname++;
+ }
+
+ while ((ch = getopt(argc, argv, "bewf:R:S:E:t:")) != EOF) {
+
+ switch(ch) {
+
+ case 'e':
+ exclude_pids = 1;
+ exclude_default_pids = 0;
+ break;
+
+ case 'w':
+ wideflag = 1;
+ if ((uint)columns < MAX_WIDE_MODE_COLS)
+ columns = MAX_WIDE_MODE_COLS;
+ break;
+
+ case 'f':
+ if (!strcmp(optarg, "network"))
+ filter_mode |= NETWORK_FILTER;
+ else if (!strcmp(optarg, "filesys"))
+ filter_mode |= FILESYS_FILTER;
+ else if (!strcmp(optarg, "cachehit"))
+ show_cachehits = TRUE;
+ else if (!strcmp(optarg, "exec"))
+ filter_mode |= EXEC_FILTER;
+ else if (!strcmp(optarg, "pathname"))
+ filter_mode |= PATHNAME_FILTER;
+ else if (!strcmp(optarg, "diskio"))
+ filter_mode |= DISKIO_FILTER;
+ break;
+
+ case 'b':
+ BC_flag = 1;
+ break;
+
+ case 't':
+ stop_at_time = time(NULL) + strtoul(optarg, NULL, 10);
+ break;
+
+ case 'R':
+ RAW_flag = 1;
+ RAW_file = optarg;
+ break;
+
+ case 'S':
+ start_time = atof(optarg);
+ break;
+
+ case 'E':
+ end_time = atof(optarg);
+ break;
+
+ default:
+ exit_usage(myname);
+ }
+ }
+ if (!RAW_flag) {
+ if ( geteuid() != 0 ) {
+ fprintf(stderr, "'fs_usage' must be run as root...\n");
+ exit(1);
+ }
+ }
+ argc -= optind;
+ argv += optind;
+
+ /*
+ * when excluding, fs_usage should be the first in line for pids[]
+ *
+ * the !exclude_pids && argc == 0 catches the exclude_default_pids
+ * case below where exclude_pids is later set and the fs_usage PID
+ * needs to make it into pids[]
+ */
+ if (exclude_pids || (!exclude_pids && argc == 0)) {
+ if (num_of_pids < (MAX_PIDS - 1))
+ pids[num_of_pids++] = getpid();
+ }
+
+ /*
+ * If we process any list of pids/cmds, then turn off the defaults
+ */
+ if (argc > 0)
+ exclude_default_pids = 0;
+
+ while (argc > 0 && num_of_pids < (MAX_PIDS - 1)) {
+ select_pid_mode++;
+ argtopid(argv[0]);
+ argc--;
+ argv++;
+ }
+ /*
+ * Exclude a set of default pids
+ */
+ if (exclude_default_pids) {
+ argtopid("Terminal");
+ argtopid("telnetd");
+ argtopid("telnet");
+ argtopid("sshd");
+ argtopid("rlogind");
+ argtopid("tcsh");
+ argtopid("csh");
+ argtopid("sh");
+ exclude_pids = 1;
+ }
+#if 0
+ for (i = 0; i < num_of_pids; i++) {
+ if (exclude_pids)
+ fprintf(stderr, "exclude pid %d\n", pids[i]);
+ else
+ fprintf(stderr, "pid %d\n", pids[i]);
+ }
+#endif
+ if (!RAW_flag) {
+ struct sigaction osa;
+ int num_cpus;
+ size_t len;
+
+ /* set up signal handlers */
+ signal(SIGINT, leave);
+ signal(SIGQUIT, leave);
+
+ sigaction(SIGHUP, (struct sigaction *)NULL, &osa);
+
+ if (osa.sa_handler == SIG_DFL)
+ signal(SIGHUP, leave);
+ signal(SIGTERM, leave);
+ /*
+ * grab the number of cpus
+ */
+ mib[0] = CTL_HW;
+ mib[1] = HW_NCPU;
+ mib[2] = 0;
+ len = sizeof(num_cpus);
+
+ sysctl(mib, 2, &num_cpus, &len, NULL, 0);
+ num_events = EVENT_BASE * num_cpus;
+ }
+ signal(SIGWINCH, sigwinch);
+
+ if ((my_buffer = malloc(num_events * sizeof(kd_buf))) == (char *)0)
+ quit("can't allocate memory for tracing info\n");
+
+ if (ReadSharedCacheMap("/var/db/dyld/dyld_shared_cache_i386.map", &framework32, "/var/db/dyld/dyld_shared_cache_i386")) {
+ ReadSharedCacheMap("/var/db/dyld/dyld_shared_cache_x86_64.map", &framework64, "/var/db/dyld/dyld_shared_cache_x86_64");
+ } else {
+ ReadSharedCacheMap("/var/db/dyld/dyld_shared_cache_ppc.map", &framework32, "/var/db/dyld/dyld_shared_cache_ppc");
+ ReadSharedCacheMap("/var/db/dyld/dyld_shared_cache_ppc64.map", &framework64, "/var/db/dyld/dyld_shared_cache_ppc64");
+ }
+ SortFrameworkAddresses();
+
+ cache_disk_names();
+
+ if (!RAW_flag) {
+
+ set_remove();
+ set_numbufs(num_events);
+ set_init();
+
+ if (exclude_pids == 0) {
+ for (i = 0; i < num_of_pids; i++)
+ set_pidcheck(pids[i], 1);
+ } else {
+ for (i = 0; i < num_of_pids; i++)
+ set_pidexclude(pids[i], 1);
+ }
+ if (select_pid_mode && !one_good_pid) {
+ /*
+ * An attempt to restrict output to a given
+ * pid or command has failed. Exit gracefully
+ */
+ set_remove();
+ exit_usage(myname);
+ }
+
+ set_filter();
+
+ set_enable(1);
+
+ init_arguments_buffer();
+ }
+ getdivisor();
+
+ init_tables();
+
+ /*
+ * main loop
+ */
+ while (stop_at_time == 0 || last_time < stop_at_time) {
+ if (!RAW_flag)
+ usleep(1000 * usleep_ms);
+
+ sample_sc();
+
+ last_time = time((long *)0);
+ }
+}
+
+
+void
+find_proc_names()
+{
+ size_t bufSize = 0;
+ struct kinfo_proc *kp;
+
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_PROC;
+ mib[2] = KERN_PROC_ALL;
+ mib[3] = 0;
+
+ if (sysctl(mib, 4, NULL, &bufSize, NULL, 0) < 0)
+ quit("trace facility failure, KERN_PROC_ALL\n");
+
+ if ((kp = (struct kinfo_proc *)malloc(bufSize)) == (struct kinfo_proc *)0)
+ quit("can't allocate memory for proc buffer\n");
+
+ if (sysctl(mib, 4, kp, &bufSize, NULL, 0) < 0)
+ quit("trace facility failure, KERN_PROC_ALL\n");
+
+ kp_nentries = bufSize/ sizeof(struct kinfo_proc);
+ kp_buffer = kp;
+}
+
+
+void
+set_enable(int val)
+{
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_KDEBUG;
+ mib[2] = KERN_KDENABLE; /* protocol */
+ mib[3] = val;
+ mib[4] = 0;
+ mib[5] = 0; /* no flags */
+
+ if (sysctl(mib, 4, NULL, &needed, NULL, 0) < 0)
+ quit("trace facility failure, KERN_KDENABLE\n");
+
+ if (val)
+ trace_enabled = 1;
+ else
+ trace_enabled = 0;
+}
+
+void
set_numbufs(int nbufs)
{
mib[0] = CTL_KERN;
mib[3] = nbufs;
mib[4] = 0;
mib[5] = 0; /* no flags */
+
if (sysctl(mib, 4, NULL, &needed, NULL, 0) < 0)
quit("trace facility failure, KERN_KDSETBUF\n");
mib[3] = 0;
mib[4] = 0;
mib[5] = 0; /* no flags */
+
if (sysctl(mib, 3, NULL, &needed, NULL, 0) < 0)
quit("trace facility failure, KERN_KDSETUP\n");
}
+#define ENCODE_CSC_LOW(class, subclass) \
+ ( (uint16_t) ( ((class) & 0xff) << 8 ) | ((subclass) & 0xff) )
+
+void
+set_filter(void)
+{
+ uint8_t type_filter_bitmap[KDBG_TYPEFILTER_BITMAP_SIZE];
+ bzero(type_filter_bitmap, sizeof(type_filter_bitmap));
+
+ setbit(type_filter_bitmap, ENCODE_CSC_LOW(DBG_TRACE,DBG_TRACE_DATA));
+ setbit(type_filter_bitmap, ENCODE_CSC_LOW(DBG_TRACE,DBG_TRACE_STRING));
+
+ setbit(type_filter_bitmap, ENCODE_CSC_LOW(DBG_MACH,DBG_MACH_EXCP_SC)); //0x010c
+ setbit(type_filter_bitmap, ENCODE_CSC_LOW(DBG_MACH,DBG_MACH_VM)); //0x0130
+ setbit(type_filter_bitmap, ENCODE_CSC_LOW(DBG_MACH,DBG_MACH_SCHED)); //0x0140
+
+ setbit(type_filter_bitmap, ENCODE_CSC_LOW(DBG_FSYSTEM,DBG_FSRW)); //0x0301
+ setbit(type_filter_bitmap, ENCODE_CSC_LOW(DBG_FSYSTEM,DBG_DKRW)); //0x0302
+ setbit(type_filter_bitmap, ENCODE_CSC_LOW(DBG_FSYSTEM,DBG_IOCTL)); //0x0306
+ setbit(type_filter_bitmap, ENCODE_CSC_LOW(DBG_FSYSTEM,DBG_BOOTCACHE)); //0x0307
+
+ setbit(type_filter_bitmap, ENCODE_CSC_LOW(DBG_BSD,DBG_BSD_EXCP_SC)); //0x040c
+ setbit(type_filter_bitmap, ENCODE_CSC_LOW(DBG_BSD,DBG_BSD_PROC)); //0x0401
+ setbit(type_filter_bitmap, ENCODE_CSC_LOW(DBG_BSD,DBG_BSD_SC_EXTENDED_INFO)); //0x040e
+ setbit(type_filter_bitmap, ENCODE_CSC_LOW(DBG_BSD,DBG_BSD_SC_EXTENDED_INFO2)); //0x040f
+
+ setbit(type_filter_bitmap, ENCODE_CSC_LOW(DBG_CORESTORAGE,DBG_CS_IO)); //0x0a00
+ setbit(type_filter_bitmap, ENCODE_CSC_LOW(DBG_CORESTORAGE, 1)); //0x0a01 for P_SCCS_SYNC_DIS
+
+ setbit(type_filter_bitmap, ENCODE_CSC_LOW(FILEMGR_CLASS, 0)); //Carbon File Manager
+ setbit(type_filter_bitmap, ENCODE_CSC_LOW(FILEMGR_CLASS, 1)); //Carbon File Manager
+
+ errno = 0;
+ int mib[] = { CTL_KERN, KERN_KDEBUG, KERN_KDSET_TYPEFILTER };
+ size_t needed = KDBG_TYPEFILTER_BITMAP_SIZE;
+ if(sysctl(mib, 3, type_filter_bitmap, &needed, NULL, 0)) {
+ quit("trace facility failure, KERN_KDSET_TYPEFILTER\n");
+ }
+}
+
void
set_pidcheck(int pid, int on_off)
{
if (sysctl(mib, 3, &kr, &needed, NULL, 0) < 0) {
if (on_off == 1)
- printf("pid %d does not exist\n", pid);
- }
- else {
- one_good_pid++;
- }
+ fprintf(stderr, "pid %d does not exist\n", pid);
+ } else
+ one_good_pid++;
}
/*
- on_off == 0 turns off pid exclusion
- on_off == 1 turns on pid exclusion
-*/
+ * on_off == 0 turns off pid exclusion
+ * on_off == 1 turns on pid exclusion
+ */
void
set_pidexclude(int pid, int on_off)
{
if (sysctl(mib, 3, &kr, &needed, NULL, 0) < 0) {
if (on_off == 1)
- printf("pid %d does not exist\n", pid);
+ fprintf(stderr, "pid %d does not exist\n", pid);
}
}
mib[3] = 0;
mib[4] = 0;
mib[5] = 0; /* no flags */
- if (sysctl(mib, 3, NULL, &needed, NULL, 0) < 0)
- {
- set_remove_flag = 0;
-
- if (errno == EBUSY)
- quit("the trace facility is currently in use...\n fs_usage, sc_usage, and latency use this feature.\n\n");
- else
- quit("trace facility failure, KERN_KDREMOVE\n");
- }
+
+ if (sysctl(mib, 3, NULL, &needed, NULL, 0) < 0) {
+ set_remove_flag = 0;
+
+ if (errno == EBUSY)
+ quit("the trace facility is currently in use...\n fs_usage, sc_usage, and latency use this feature.\n\n");
+ else
+ quit("trace facility failure, KERN_KDREMOVE\n");
+ }
}
void
kr.value1 = 0;
kr.value2 = -1;
needed = sizeof(kd_regtype);
+
mib[0] = CTL_KERN;
mib[1] = KERN_KDEBUG;
mib[2] = KERN_KDSETREG;
quit("trace facility failure, KERN_KDSETUP\n");
}
+
void
sample_sc()
{
kd_buf *kd;
int i, count;
size_t needed;
- void read_command_map();
- void create_map_entry();
+ uint32_t my_buffer_size = 0;
- /* Get kernel buffer information */
- get_bufinfo(&bufinfo);
+ if (!RAW_flag)
+ get_bufinfo(&bufinfo);
+ else
+ my_buffer_size = num_events * sizeof(kd_buf);
if (need_new_map) {
read_command_map();
need_new_map = 0;
}
- needed = bufinfo.nkdbufs * sizeof(kd_buf);
- mib[0] = CTL_KERN;
- mib[1] = KERN_KDEBUG;
- mib[2] = KERN_KDREADTR;
- mib[3] = 0;
- mib[4] = 0;
- mib[5] = 0; /* no flags */
+ if (!RAW_flag) {
+ needed = bufinfo.nkdbufs * sizeof(kd_buf);
+
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_KDEBUG;
+ mib[2] = KERN_KDREADTR;
+ mib[3] = 0;
+ mib[4] = 0;
+ mib[5] = 0; /* no flags */
+
+ if (sysctl(mib, 3, my_buffer, &needed, NULL, 0) < 0)
+ quit("trace facility failure, KERN_KDREADTR\n");
+ count = needed;
+
+ if (count > (num_events / 8)) {
+ if (usleep_ms > USLEEP_BEHIND)
+ usleep_ms = USLEEP_BEHIND;
+ else if (usleep_ms > USLEEP_MIN)
+ usleep_ms /= 2;
+
+ } else if (count < (num_events / 16)) {
+ if (usleep_ms < USLEEP_MAX)
+ usleep_ms *= 2;
+ }
- if (sysctl(mib, 3, my_buffer, &needed, NULL, 0) < 0)
- quit("trace facility failure, KERN_KDREADTR\n");
- count = needed;
+ if (bufinfo.flags & KDBG_WRAPPED) {
+ fprintf(stderr, "fs_usage: buffer overrun, events generated too quickly: %d\n", count);
- if (bufinfo.flags & KDBG_WRAPPED) {
- printf("buffer wrapped count = %d\n", count);
+ delete_all_events();
- for (i = 0; i < cur_max; i++) {
- th_state[i].thread = 0;
- th_state[i].pid = 0;
- th_state[i].pathptr = (long *)0;
- th_state[i].pathname[0] = 0;
- }
- cur_max = 0;
- need_new_map = 1;
+ need_new_map = 1;
- set_enable(0);
- set_enable(1);
+ set_enable(0);
+ set_enable(1);
+ }
+ } else {
+ int bytes_read;
+
+ if ((bytes_read = read(RAW_fd, my_buffer, my_buffer_size)) < sizeof(kd_buf))
+ exit(0);
+ count = bytes_read / sizeof(kd_buf);
}
kd = (kd_buf *)my_buffer;
#if 0
- printf("READTR returned %d items\n", count);
+ fprintf(stderr, "READTR returned %d items\n", count);
#endif
for (i = 0; i < count; i++) {
- int debugid, thread;
- int type, n;
- long *sargptr;
+ uint32_t debugid;
+ uintptr_t thread;
+ int type;
+ int index;
+ uintptr_t *sargptr;
uint64_t now;
long long l_usecs;
int secs;
long curr_time;
- struct th_info *ti;
+ th_info_t ti;
struct diskio *dio;
- void enter_syscall();
- void exit_syscall();
- void extend_syscall();
- void kill_thread_map();
- thread = kd[i].arg5 & KDBG_THREAD_MASK;
+
+ thread = kd[i].arg5;
debugid = kd[i].debugid;
type = kd[i].debugid & DBG_FUNC_MASK;
-
- now = kd[i].timestamp;
- if (i == 0)
- {
- /*
- * Compute bias seconds after each trace buffer read.
- * This helps resync timestamps with the system clock
- * in the event of a system sleep.
- */
- l_usecs = (long long)(now / divisor);
- secs = l_usecs / 1000000;
- curr_time = time((long *)0);
- bias_secs = curr_time - secs;
- }
+ now = kdbg_get_timestamp(&kd[i]);
+ if (i == 0 && !RAW_flag) {
- switch (type) {
+ curr_time = time((long *)0);
+ /*
+ * Compute bias seconds after each trace buffer read.
+ * This helps resync timestamps with the system clock
+ * in the event of a system sleep.
+ */
+ if (bias_secs == 0 || curr_time < last_time || curr_time > (last_time + 2)) {
+ l_usecs = (long long)(now / divisor);
+ secs = l_usecs / 1000000;
+ bias_secs = curr_time - secs;
+ }
+ }
+ if (RAW_flag && bias_now == 0.0)
+ bias_now = now;
+
+ if ((type & P_DISKIO_MASK) == P_DISKIO) {
+ insert_diskio(type, kd[i].arg1, kd[i].arg2, kd[i].arg3, kd[i].arg4, thread, (double)now);
+ continue;
+ }
+ if ((type & P_DISKIO_MASK) == P_DISKIO_DONE) {
+ if ((dio = complete_diskio(kd[i].arg1, kd[i].arg4, kd[i].arg3, thread, (double)now))) {
+ dio->vnodeid = kd[i].arg2;
+ print_diskio(dio);
+ free_diskio(dio);
+ }
+ continue;
+ }
- case P_RdMeta:
- case P_WrMeta:
- case P_RdData:
- case P_WrData:
- case P_PgIn:
- case P_PgOut:
- case P_RdMetaAsync:
- case P_WrMetaAsync:
- case P_RdDataAsync:
- case P_WrDataAsync:
- case P_PgInAsync:
- case P_PgOutAsync:
- insert_diskio(type, kd[i].arg1, kd[i].arg2, kd[i].arg3, kd[i].arg4, thread, (double)now);
- continue;
-
- case P_RdMetaDone:
- case P_WrMetaDone:
- case P_RdDataDone:
- case P_WrDataDone:
- case P_PgInDone:
- case P_PgOutDone:
- case P_RdMetaAsyncDone:
- case P_WrMetaAsyncDone:
- case P_RdDataAsyncDone:
- case P_WrDataAsyncDone:
- case P_PgInAsyncDone:
- case P_PgOutAsyncDone:
- if ((dio = complete_diskio(kd[i].arg1, kd[i].arg4, kd[i].arg3, thread, (double)now))) {
- print_diskio(dio);
- free_diskio(dio);
- }
- continue;
+ if ((type & CLASS_MASK) == P_CS_Class) {
+ // the usual DBG_FUNC_START/END does not work for i/o since it will
+ // return on a different thread, this code uses the P_CS_IO_Done (0x4) bit
+ // instead. the trace command doesn't know how handle either method
+ // (unmatched start/end or 0x4) but works a little better this way.
- case TRACE_DATA_NEWTHREAD:
-
- for (n = 0, ti = th_state; ti < &th_state[MAX_THREADS]; ti++, n++) {
- if (ti->thread == 0)
- break;
- }
- if (ti == &th_state[MAX_THREADS])
- continue;
- if (n >= cur_max)
- cur_max = n + 1;
+ int cs_type = type & P_CS_Type_Mask; // strip out the done bit
+ bool start = (type & P_CS_IO_Done) != P_CS_IO_Done;
- ti->thread = thread;
- ti->child_thread = kd[i].arg1;
- ti->pid = kd[i].arg2;
- continue;
+ switch (cs_type) {
+
+ case P_CS_ReadChunk:
+ case P_CS_WriteChunk:
+ case P_CS_MetaRead:
+ case P_CS_MetaWrite:
+ if (start) {
+ insert_diskio(cs_type, kd[i].arg2, kd[i].arg1, kd[i].arg3, kd[i].arg4, thread, (double)now);
+ } else {
+ if ((dio = complete_diskio(kd[i].arg2, kd[i].arg4, kd[i].arg3, thread, (double)now))) {
+ print_diskio(dio);
+ free_diskio(dio);
+ }
+ }
+ continue;
- case TRACE_STRING_NEWTHREAD:
- if ((ti = find_thread(thread, 0)) == (struct th_info *)0)
- continue;
- if (ti->child_thread == 0)
- continue;
- create_map_entry(ti->child_thread, ti->pid, (char *)&kd[i].arg1);
+ case P_CS_TransformRead:
+ case P_CS_TransformWrite:
+ case P_CS_MigrationRead:
+ case P_CS_MigrationWrite:
+ if (start) {
+ insert_diskio(cs_type, kd[i].arg2, CS_DEV, kd[i].arg3, kd[i].arg4, thread, (double)now);
+ } else {
+ if ((dio = complete_diskio(kd[i].arg2, kd[i].arg4, kd[i].arg3, thread, (double)now))) {
+ print_diskio(dio);
+ free_diskio(dio);
+ }
+ }
+ continue;
+
+ case P_CS_SYNC_DISK:
+ if (start) {
+ enter_event(thread, cs_type, &kd[i], NULL, (double)now);
+ } else {
+ exit_event(" SyncCacheCS", thread, cs_type, kd[i].arg1, 0, 0, 0, FMT_SYNC_DISK_CS, (double)now);
+ }
+ continue;
+ }
+
+ continue; // ignore other cs timestamps
+ }
+
+ switch (type) {
+
+ case TRACE_DATA_NEWTHREAD:
+ if (kd[i].arg1) {
+ if ((ti = add_event(thread, TRACE_DATA_NEWTHREAD)) == NULL)
+ continue;
+ ti->child_thread = kd[i].arg1;
+ ti->pid = kd[i].arg2;
+ }
+ continue;
+
+ case TRACE_STRING_NEWTHREAD:
+ if ((ti = find_event(thread, TRACE_DATA_NEWTHREAD)) == (struct th_info *)0)
+ continue;
+
+ create_map_entry(ti->child_thread, ti->pid, (char *)&kd[i].arg1);
- if (ti == &th_state[cur_max - 1])
- cur_max--;
- ti->child_thread = 0;
- ti->thread = 0;
- ti->pid = 0;
+ delete_event(ti);
continue;
case TRACE_DATA_EXEC:
+ if ((ti = add_event(thread, TRACE_DATA_EXEC)) == NULL)
+ continue;
- for (n = 0, ti = th_state; ti < &th_state[MAX_THREADS]; ti++, n++) {
- if (ti->thread == 0)
- break;
- }
- if (ti == &th_state[MAX_THREADS])
- continue;
- if (n >= cur_max)
- cur_max = n + 1;
-
- ti->thread = thread;
ti->pid = kd[i].arg1;
continue;
case TRACE_STRING_EXEC:
- if ((ti = find_thread(thread, 0)) == (struct th_info *)0)
- {
- /* this is for backwards compatibility */
- create_map_entry(thread, 0, (char *)&kd[i].arg1);
- }
- else
- {
- create_map_entry(thread, ti->pid, (char *)&kd[i].arg1);
- if (ti == &th_state[cur_max - 1])
- cur_max--;
- ti->thread = 0;
- ti->pid = 0;
+ if ((ti = find_event(thread, BSC_execve))) {
+ if (ti->lookups[0].pathname[0])
+ exit_event("execve", thread, BSC_execve, 0, 0, 0, 0, FMT_DEFAULT, (double)now);
+
+ } else if ((ti = find_event(thread, BSC_posix_spawn))) {
+ if (ti->lookups[0].pathname[0])
+ exit_event("posix_spawn", thread, BSC_posix_spawn, 0, 0, 0, 0, FMT_DEFAULT, (double)now);
}
+ if ((ti = find_event(thread, TRACE_DATA_EXEC)) == (struct th_info *)0)
+ continue;
+
+ create_map_entry(thread, ti->pid, (char *)&kd[i].arg1);
+
+ delete_event(ti);
+ continue;
+
+ case BSC_thread_terminate:
+ delete_map_entry(thread);
continue;
case BSC_exit:
- kill_thread_map(thread);
continue;
+ case proc_exit:
+ kd[i].arg1 = kd[i].arg2 >> 8;
+ type = BSC_exit;
+ break;
+
+ case BSC_mmap:
+ if (kd[i].arg4 & MAP_ANON)
+ continue;
+ break;
+
+ case MACH_idle:
case MACH_sched:
case MACH_stkhandoff:
mark_thread_waited(thread);
continue;
+
+ case BC_IO_HIT:
+ case BC_IO_HIT_STALLED:
+ case BC_IO_MISS:
+ case BC_IO_MISS_CUT_THROUGH:
+ case BC_PLAYBACK_IO:
+ if ((dio = find_diskio(kd[i].arg1)) != NULL)
+ dio->bc_info = type;
+ continue;
+
+ case HFS_modify_block_end:
+ if ((ti = find_event(thread, 0))) {
+ if (ti->nameptr)
+ add_meta_name(kd[i].arg2, ti->nameptr);
+ }
+ continue;
+
+ case VFS_ALIAS_VP:
+ add_vnode_name(kd[i].arg2, find_vnode_name(kd[i].arg1));
+ continue;
case VFS_LOOKUP:
- if ((ti = find_thread(thread, 0)) == (struct th_info *)0)
+ if ((ti = find_event(thread, 0)) == (struct th_info *)0)
continue;
- if (!ti->pathptr) {
- sargptr = (long *)&ti->pathname[0];
- memset(&ti->pathname[0], 0, (PATHLENGTH + 1));
+ if (debugid & DBG_FUNC_START) {
+
+ if (ti->in_hfs_update) {
+ ti->pn_work_index = (MAX_PATHNAMES - 1);
+ } else {
+ if (ti->pn_scall_index < MAX_SCALL_PATHNAMES)
+ ti->pn_work_index = ti->pn_scall_index;
+ else
+ continue;
+ }
+ sargptr = &ti->lookups[ti->pn_work_index].pathname[0];
+
+ ti->vnodeid = kd[i].arg1;
+
*sargptr++ = kd[i].arg2;
*sargptr++ = kd[i].arg3;
*sargptr++ = kd[i].arg4;
+ /*
+ * NULL terminate the 'string'
+ */
+ *sargptr = 0;
+
ti->pathptr = sargptr;
} else {
sargptr = ti->pathptr;
- /*
- We don't want to overrun our pathname buffer if the
- kernel sends us more VFS_LOOKUP entries than we can
- handle.
- */
-
- if ((long *)sargptr >= (long *)&ti->pathname[PATHLENGTH])
- continue;
-
- /*
- We need to detect consecutive vfslookup entries.
- So, if we get here and find a START entry,
- fake the pathptr so we can bypass all further
- vfslookup entries.
- */
-
- if (debugid & DBG_FUNC_START)
- {
- (long *)ti->pathptr = (long *)&ti->pathname[PATHLENGTH];
- continue;
- }
+ /*
+ * We don't want to overrun our pathname buffer if the
+ * kernel sends us more VFS_LOOKUP entries than we can
+ * handle and we only handle 2 pathname lookups for
+ * a given system call
+ */
+ if (sargptr == 0)
+ continue;
+
+ if ((uintptr_t)sargptr < (uintptr_t)&ti->lookups[ti->pn_work_index].pathname[NUMPARMS]) {
+
+ *sargptr++ = kd[i].arg1;
+ *sargptr++ = kd[i].arg2;
+ *sargptr++ = kd[i].arg3;
+ *sargptr++ = kd[i].arg4;
+ /*
+ * NULL terminate the 'string'
+ */
+ *sargptr = 0;
+ }
+ }
+ if (debugid & DBG_FUNC_END) {
- *sargptr++ = kd[i].arg1;
- *sargptr++ = kd[i].arg2;
- *sargptr++ = kd[i].arg3;
- *sargptr++ = kd[i].arg4;
+ ti->nameptr = add_vnode_name(ti->vnodeid, &ti->lookups[ti->pn_work_index].pathname[0]);
+
+ if (ti->pn_work_index == ti->pn_scall_index) {
+
+ ti->pn_scall_index++;
+
+ if (ti->pn_scall_index < MAX_SCALL_PATHNAMES)
+ ti->pathptr = &ti->lookups[ti->pn_scall_index].pathname[0];
+ else
+ ti->pathptr = 0;
+ }
+ } else
ti->pathptr = sargptr;
- }
+
continue;
}
if (debugid & DBG_FUNC_START) {
- char *p;
-
- switch (type) {
- case FILEMGR_PBGETCATALOGINFO:
- p = "GetCatalogInfo";
- break;
- case FILEMGR_PBGETCATALOGINFOBULK:
- p = "GetCatalogInfoBulk";
- break;
- case FILEMGR_PBCREATEFILEUNICODE:
- p = "CreateFileUnicode";
- break;
- case FILEMGR_PBCREATEDIRECTORYUNICODE:
- p = "CreateDirectoryUnicode";
- break;
- case FILEMGR_PBCREATEFORK:
- p = "PBCreateFork";
- break;
- case FILEMGR_PBDELETEFORK:
- p = "PBDeleteFork";
- break;
- case FILEMGR_PBITERATEFORK:
- p = "PBIterateFork";
- break;
- case FILEMGR_PBOPENFORK:
- p = "PBOpenFork";
- break;
- case FILEMGR_PBREADFORK:
- p = "PBReadFork";
- break;
- case FILEMGR_PBWRITEFORK:
- p = "PBWriteFork";
- break;
- case FILEMGR_PBALLOCATEFORK:
- p = "PBAllocateFork";
- break;
- case FILEMGR_PBDELETEOBJECT:
- p = "PBDeleteObject";
- break;
- case FILEMGR_PBEXCHANGEOBJECT:
- p = "PBExchangeObject";
- break;
- case FILEMGR_PBGETFORKCBINFO:
- p = "PBGetForkCBInfo";
- break;
- case FILEMGR_PBGETVOLUMEINFO:
- p = "PBGetVolumeInfo";
- break;
- case FILEMGR_PBMAKEFSREF:
- p = "PBMakeFSRef";
- break;
- case FILEMGR_PBMAKEFSREFUNICODE:
- p = "PBMakeFSRefUnicode";
- break;
- case FILEMGR_PBMOVEOBJECT:
- p = "PBMoveObject";
- break;
- case FILEMGR_PBOPENITERATOR:
- p = "PBOpenIterator";
- break;
- case FILEMGR_PBRENAMEUNICODE:
- p = "PBRenameUnicode";
- break;
- case FILEMGR_PBSETCATALOGINFO:
- p = "SetCatalogInfo";
- break;
- case FILEMGR_PBSETVOLUMEINFO:
- p = "SetVolumeInfo";
- break;
- case FILEMGR_FSREFMAKEPATH:
- p = "FSRefMakePath";
- break;
- case FILEMGR_FSPATHMAKEREF:
- p = "FSPathMakeRef";
- break;
- // SPEC based calls
- case FILEMGR_PBGETCATINFO:
- p = "GetCatInfo";
- break;
- case FILEMGR_PBGETCATINFOLITE:
- p = "GetCatInfoLite";
- break;
- case FILEMGR_PBHGETFINFO:
- p = "PBHGetFInfo";
- break;
- case FILEMGR_PBXGETVOLINFO:
- p = "PBXGetVolInfo";
- break;
- case FILEMGR_PBHCREATE:
- p = "PBHCreate";
- break;
- case FILEMGR_PBHOPENDF:
- p = "PBHOpenDF";
- break;
- case FILEMGR_PBHOPENRF:
- p = "PBHOpenRF";
- break;
- case FILEMGR_PBHGETDIRACCESS:
- p = "PBHGetDirAccess";
- break;
- case FILEMGR_PBHSETDIRACCESS:
- p = "PBHSetDirAccess";
- break;
- case FILEMGR_PBHMAPID:
- p = "PBHMapID";
- break;
- case FILEMGR_PBHMAPNAME:
- p = "PBHMapName";
- break;
- case FILEMGR_PBCLOSE:
- p = "PBClose";
- break;
- case FILEMGR_PBFLUSHFILE:
- p = "PBFlushFile";
- break;
- case FILEMGR_PBGETEOF:
- p = "PBGetEOF";
- break;
- case FILEMGR_PBSETEOF:
- p = "PBSetEOF";
- break;
- case FILEMGR_PBGETFPOS:
- p = "PBGetFPos";
- break;
- case FILEMGR_PBREAD:
- p = "PBRead";
- break;
- case FILEMGR_PBWRITE:
- p = "PBWrite";
- break;
- case FILEMGR_PBGETFCBINFO:
- p = "PBGetFCBInfo";
- break;
- case FILEMGR_PBSETFINFO:
- p = "PBSetFInfo";
- break;
- case FILEMGR_PBALLOCATE:
- p = "PBAllocate";
- break;
- case FILEMGR_PBALLOCCONTIG:
- p = "PBAllocContig";
- break;
- case FILEMGR_PBSETFPOS:
- p = "PBSetFPos";
- break;
- case FILEMGR_PBSETCATINFO:
- p = "PBSetCatInfo";
- break;
- case FILEMGR_PBGETVOLPARMS:
- p = "PBGetVolParms";
- break;
- case FILEMGR_PBSETVINFO:
- p = "PBSetVInfo";
- break;
- case FILEMGR_PBMAKEFSSPEC:
- p = "PBMakeFSSpec";
- break;
- case FILEMGR_PBHGETVINFO:
- p = "PBHGetVInfo";
- break;
- case FILEMGR_PBCREATEFILEIDREF:
- p = "PBCreateFileIDRef";
- break;
- case FILEMGR_PBDELETEFILEIDREF:
- p = "PBDeleteFileIDRef";
- break;
- case FILEMGR_PBRESOLVEFILEIDREF:
- p = "PBResolveFileIDRef";
- break;
- case FILEMGR_PBFLUSHVOL:
- p = "PBFlushVol";
- break;
- case FILEMGR_PBHRENAME:
- p = "PBHRename";
- break;
- case FILEMGR_PBCATMOVE:
- p = "PBCatMove";
- break;
- case FILEMGR_PBEXCHANGEFILES:
- p = "PBExchangeFiles";
- break;
- case FILEMGR_PBHDELETE:
- p = "PBHDelete";
- break;
- case FILEMGR_PBDIRCREATE:
- p = "PBDirCreate";
- break;
- case FILEMGR_PBCATSEARCH:
- p = "PBCatSearch";
- break;
- case FILEMGR_PBHSETFLOCK:
- p = "PBHSetFlock";
- break;
- case FILEMGR_PBHRSTFLOCK:
- p = "PBHRstFLock";
- break;
- case FILEMGR_PBLOCKRANGE:
- p = "PBLockRange";
- break;
- case FILEMGR_PBUNLOCKRANGE:
- p = "PBUnlockRange";
- break;
- default:
- p = (char *)0;
- break;
- }
- enter_syscall(thread, type, &kd[i], p, (double)now);
+ char * p;
+
+ if ((type & CLASS_MASK) == FILEMGR_BASE) {
+
+ index = filemgr_index(type);
+
+ if (index >= MAX_FILEMGR)
+ continue;
+
+ if ((p = filemgr_calls[index].fm_name) == NULL)
+ continue;
+ } else
+ p = NULL;
+
+ enter_event(thread, type, &kd[i], p, (double)now);
continue;
}
-
+
switch (type) {
-
- case BSC_pread_extended:
- case BSC_pwrite_extended:
- extend_syscall(thread, type, &kd[i], (double)now);
+
+ case Throttled:
+ exit_event(" THROTTLED", thread, type, 0, 0, 0, 0, FMT_DEFAULT, (double)now);
+ continue;
+
+ case HFS_update:
+ exit_event(" HFS_update", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, FMT_HFS_update, (double)now);
+ continue;
+
+ case SPEC_unmap_info:
+ if (check_filter_mode(NULL, SPEC_unmap_info, 0, 0, "SPEC_unmap_info"))
+ format_print(NULL, " TrimExtent", thread, type, kd[i].arg1, kd[i].arg2, kd[i].arg3, 0, FMT_UNMAP_INFO, now, now, 0, "", NULL);
+ continue;
+
+ case SPEC_ioctl:
+ if (kd[i].arg2 == DKIOCSYNCHRONIZECACHE)
+ exit_event("IOCTL", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, FMT_IOCTL_SYNC, (double)now);
+ else if (kd[i].arg2 == DKIOCUNMAP)
+ exit_event("IOCTL", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, FMT_IOCTL_UNMAP, (double)now);
+ else {
+ if ((ti = find_event(thread, type)))
+ delete_event(ti);
+ }
+ continue;
case MACH_pageout:
- if (kd[i].arg2)
- exit_syscall("PAGE_OUT_D", thread, type, 0, kd[i].arg1, 0, 4, (double)now);
- else
- exit_syscall("PAGE_OUT_V", thread, type, 0, kd[i].arg1, 0, 4, (double)now);
- break;
+ if (kd[i].arg2)
+ exit_event("PAGE_OUT_ANON", thread, type, 0, kd[i].arg1, 0, 0, FMT_PGOUT, (double)now);
+ else
+ exit_event("PAGE_OUT_FILE", thread, type, 0, kd[i].arg1, 0, 0, FMT_PGOUT, (double)now);
+ continue;
case MACH_vmfault:
- if (kd[i].arg2 == DBG_PAGEIN_FAULT)
- exit_syscall("PAGE_IN", thread, type, kd[i].arg4, kd[i].arg1, 0, 6, (double)now);
- else if (kd[i].arg2 == DBG_CACHE_HIT_FAULT)
- exit_syscall("CACHE_HIT", thread, type, 0, kd[i].arg1, 0, 2, (double)now);
- else {
- if ((ti = find_thread(thread, type))) {
- if (ti == &th_state[cur_max - 1])
- cur_max--;
- ti->thread = 0;
- }
- }
- break;
+ if (kd[i].arg4 == DBG_PAGEIN_FAULT)
+ exit_event("PAGE_IN", thread, type, 0, kd[i].arg1, kd[i].arg2, 0, FMT_PGIN, (double)now);
+ else if (kd[i].arg4 == DBG_PAGEINV_FAULT)
+ exit_event("PAGE_IN_FILE", thread, type, 0, kd[i].arg1, kd[i].arg2, 0, FMT_PGIN, (double)now);
+ else if (kd[i].arg4 == DBG_PAGEIND_FAULT)
+ exit_event("PAGE_IN_ANON", thread, type, 0, kd[i].arg1, kd[i].arg2, 0, FMT_PGIN, (double)now);
+ else if (kd[i].arg4 == DBG_CACHE_HIT_FAULT)
+ exit_event("CACHE_HIT", thread, type, 0, kd[i].arg1, kd[i].arg2, 0, FMT_CACHEHIT, (double)now);
+ else {
+ if ((ti = find_event(thread, type)))
+ delete_event(ti);
+ }
+ continue;
case MSC_map_fd:
- exit_syscall("map_fd", thread, type, kd[i].arg1, kd[i].arg2, 1, 0, (double)now);
- break;
+ exit_event("map_fd", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, FMT_FD, (double)now);
+ continue;
+
+ case BSC_mmap_extended:
+ case BSC_mmap_extended2:
+ case BSC_msync_extended:
+ case BSC_pread_extended:
+ case BSC_pwrite_extended:
+ extend_syscall(thread, type, &kd[i]);
+ continue;
+ }
- case BSC_mmap:
- exit_syscall("mmap", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
-
- case BSC_recvmsg:
- exit_syscall("recvmsg", thread, type, kd[i].arg1, kd[i].arg2, 1, 1, (double)now);
- break;
+ if ((type & CSC_MASK) == BSC_BASE) {
- case BSC_sendmsg:
- exit_syscall("sendmsg", thread, type, kd[i].arg1, kd[i].arg2, 1, 1, (double)now);
- break;
+ if ((index = BSC_INDEX(type)) >= MAX_BSD_SYSCALL)
+ continue;
- case BSC_recvfrom:
- exit_syscall("recvfrom", thread, type, kd[i].arg1, kd[i].arg2, 1, 1, (double)now);
- break;
+ if (bsd_syscalls[index].sc_name) {
+ exit_event(bsd_syscalls[index].sc_name, thread, type, kd[i].arg1, kd[i].arg2, kd[i].arg3, kd[i].arg4,
+ bsd_syscalls[index].sc_format, (double)now);
- case BSC_accept:
- exit_syscall("accept", thread, type, kd[i].arg1, kd[i].arg2, 2, 0, (double)now);
- break;
-
- case BSC_select:
- exit_syscall("select", thread, type, kd[i].arg1, kd[i].arg2, 0, 8, (double)now);
- break;
-
- case BSC_socket:
- exit_syscall("socket", thread, type, kd[i].arg1, kd[i].arg2, 2, 0, (double)now);
- break;
+ if (type == BSC_exit)
+ delete_map_entry(thread);
+ }
+ } else if ((type & CLASS_MASK) == FILEMGR_BASE) {
+
+ if ((index = filemgr_index(type)) >= MAX_FILEMGR)
+ continue;
- case BSC_connect:
- exit_syscall("connect", thread, type, kd[i].arg1, kd[i].arg2, 1, 0, (double)now);
- break;
+ if (filemgr_calls[index].fm_name) {
+ exit_event(filemgr_calls[index].fm_name, thread, type, kd[i].arg1, kd[i].arg2, kd[i].arg3, kd[i].arg4,
+ FMT_DEFAULT, (double)now);
+ }
+ }
+ }
+ fflush(0);
+}
- case BSC_bind:
- exit_syscall("bind", thread, type, kd[i].arg1, kd[i].arg2, 1, 0, (double)now);
- break;
- case BSC_listen:
- exit_syscall("listen", thread, type, kd[i].arg1, kd[i].arg2, 1, 0, (double)now);
- break;
+void
+enter_event_now(uintptr_t thread, int type, kd_buf *kd, char *name, double now)
+{
+ th_info_t ti;
+ threadmap_t tme;
+ int secs;
+ int usecs;
+ long long l_usecs;
+ long curr_time;
+ int clen = 0;
+ int tsclen = 0;
+ int nmclen = 0;
+ int argsclen = 0;
+ char buf[MAXWIDTH];
+
+ if ((ti = add_event(thread, type)) == NULL)
+ return;
+
+ ti->stime = now;
+ ti->arg1 = kd->arg1;
+ ti->arg2 = kd->arg2;
+ ti->arg3 = kd->arg3;
+ ti->arg4 = kd->arg4;
+
+ switch (type) {
+
+ case HFS_update:
+ ti->in_hfs_update = 1;
+ break;
+ }
- case BSC_sendto:
- exit_syscall("sendto", thread, type, kd[i].arg1, kd[i].arg2, 1, 1, (double)now);
- break;
+ if ((type & CLASS_MASK) == FILEMGR_BASE &&
+ (!RAW_flag || (now >= start_time && now <= end_time))) {
- case BSC_socketpair:
- exit_syscall("socketpair", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
-
- case BSC_stat:
- exit_syscall("stat", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
-
- case BSC_load_shared_file:
- exit_syscall("load_sf", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
+ filemgr_in_progress++;
+ ti->in_filemgr = 1;
- case BSC_open:
- exit_syscall("open", thread, type, kd[i].arg1, kd[i].arg2, 2, 0, (double)now);
- break;
+ if (RAW_flag) {
+ l_usecs = (long long)((now - bias_now) / divisor);
+ l_usecs += (sample_TOD_secs * 1000000) + sample_TOD_usecs;
+ } else
+ l_usecs = (long long)(now / divisor);
+ secs = l_usecs / 1000000;
+ curr_time = bias_secs + secs;
+
+ sprintf(buf, "%-8.8s", &(ctime(&curr_time)[11]));
+ tsclen = strlen(buf);
- case BSC_dup:
- exit_syscall("dup", thread, type, kd[i].arg1, kd[i].arg2, 2, 0, (double)now);
- break;
+ if (columns > MAXCOLS || wideflag) {
+ usecs = l_usecs - (long long)((long long)secs * 1000000);
+ sprintf(&buf[tsclen], ".%06ld", (long)usecs);
+ tsclen = strlen(buf);
+ }
- case BSC_dup2:
- exit_syscall("dup2", thread, type, kd[i].arg1, kd[i].arg2, 2, 0, (double)now);
- break;
+ /*
+ * Print timestamp column
+ */
+ printf("%s", buf);
- case BSC_close:
- exit_syscall("close", thread, type, kd[i].arg1, kd[i].arg2, 1, 0, (double)now);
- break;
+ tme = find_map_entry(thread);
+ if (tme) {
+ sprintf(buf, " %-25.25s ", name);
+ nmclen = strlen(buf);
+ printf("%s", buf);
- case BSC_read:
- exit_syscall("read", thread, type, kd[i].arg1, kd[i].arg2, 1, 1, (double)now);
- break;
+ sprintf(buf, "(%d, 0x%lx, 0x%lx, 0x%lx)", (short)kd->arg1, kd->arg2, kd->arg3, kd->arg4);
+ argsclen = strlen(buf);
+
+ /*
+ * Calculate white space out to command
+ */
+ if (columns > MAXCOLS || wideflag) {
+ clen = columns - (tsclen + nmclen + argsclen + 20 + 11);
+ } else
+ clen = columns - (tsclen + nmclen + argsclen + 12);
+
+ if (clen > 0) {
+ printf("%s", buf); /* print the kdargs */
+ memset(buf, ' ', clen);
+ buf[clen] = '\0';
+ printf("%s", buf);
+ }
+ else if ((argsclen + clen) > 0) {
+ /*
+ * no room so wipe out the kdargs
+ */
+ memset(buf, ' ', (argsclen + clen));
+ buf[argsclen + clen] = '\0';
+ printf("%s", buf);
+ }
+ if (columns > MAXCOLS || wideflag)
+ printf("%s.%d\n", tme->tm_command, (int)thread);
+ else
+ printf("%-12.12s\n", tme->tm_command);
+ } else
+ printf(" %-24.24s (%5d, %#lx, 0x%lx, 0x%lx)\n", name, (short)kd->arg1, kd->arg2, kd->arg3, kd->arg4);
+ }
+}
- case BSC_write:
- exit_syscall("write", thread, type, kd[i].arg1, kd[i].arg2, 1, 1, (double)now);
- break;
- case BSC_fstat:
- exit_syscall("fstat", thread, type, kd[i].arg1, kd[i].arg2, 1, 0, (double)now);
- break;
+void
+enter_event(uintptr_t thread, int type, kd_buf *kd, char *name, double now)
+{
+ int index;
- case BSC_lstat:
- exit_syscall("lstat", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
+ switch (type) {
- case BSC_link:
- exit_syscall("link", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
+ case P_CS_SYNC_DISK:
+ case MACH_pageout:
+ case MACH_vmfault:
+ case MSC_map_fd:
+ case SPEC_ioctl:
+ case Throttled:
+ case HFS_update:
+ enter_event_now(thread, type, kd, name, now);
+ return;
- case BSC_unlink:
- exit_syscall("unlink", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
+ }
+ if ((type & CSC_MASK) == BSC_BASE) {
- case BSC_mknod:
- exit_syscall("mknod", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
+ if ((index = BSC_INDEX(type)) >= MAX_BSD_SYSCALL)
+ return;
- case BSC_chmod:
- exit_syscall("chmod", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
+ if (bsd_syscalls[index].sc_name)
+ enter_event_now(thread, type, kd, name, now);
+ return;
+ }
+ if ((type & CLASS_MASK) == FILEMGR_BASE) {
- case BSC_chown:
- exit_syscall("chown", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
+ if ((index = filemgr_index(type)) >= MAX_FILEMGR)
+ return;
+
+ if (filemgr_calls[index].fm_name)
+ enter_event_now(thread, type, kd, name, now);
+ return;
+ }
+}
- case BSC_access:
- exit_syscall("access", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
+/*
+ * Handle system call extended trace data.
+ * pread and pwrite:
+ * Wipe out the kd args that were collected upon syscall_entry
+ * because it is the extended info that we really want, and it
+ * is all we really need.
+*/
- case BSC_chdir:
- exit_syscall("chdir", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
-
- case BSC_chroot:
- exit_syscall("chroot", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
-
- case BSC_utimes:
- exit_syscall("utimes", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
-
- case BSC_delete:
- exit_syscall("delete", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
-
- case BSC_undelete:
- exit_syscall("undelete", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
-
- case BSC_revoke:
- exit_syscall("revoke", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
-
- case BSC_fsctl:
- exit_syscall("fsctl", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
-
- case BSC_chflags:
- exit_syscall("chflags", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
-
- case BSC_fchflags:
- exit_syscall("fchflags", thread, type, kd[i].arg1, kd[i].arg2, 1, 0, (double)now);
- break;
-
- case BSC_fchdir:
- exit_syscall("fchdir", thread, type, kd[i].arg1, kd[i].arg2, 1, 0, (double)now);
- break;
-
- case BSC_futimes:
- exit_syscall("futimes", thread, type, kd[i].arg1, kd[i].arg2, 1, 0, (double)now);
- break;
+void
+extend_syscall(uintptr_t thread, int type, kd_buf *kd)
+{
+ th_info_t ti;
+
+ switch (type) {
+ case BSC_mmap_extended:
+ if ((ti = find_event(thread, BSC_mmap)) == (struct th_info *)0)
+ return;
+ ti->arg8 = ti->arg3; /* save protection */
+ ti->arg1 = kd->arg1; /* the fd */
+ ti->arg3 = kd->arg2; /* bottom half address */
+ ti->arg5 = kd->arg3; /* bottom half size */
+ break;
+ case BSC_mmap_extended2:
+ if ((ti = find_event(thread, BSC_mmap)) == (struct th_info *)0)
+ return;
+ ti->arg2 = kd->arg1; /* top half address */
+ ti->arg4 = kd->arg2; /* top half size */
+ ti->arg6 = kd->arg3; /* top half file offset */
+ ti->arg7 = kd->arg4; /* bottom half file offset */
+ break;
+ case BSC_msync_extended:
+ if ((ti = find_event(thread, BSC_msync)) == (struct th_info *)0) {
+ if ((ti = find_event(thread, BSC_msync_nocancel)) == (struct th_info *)0)
+ return;
+ }
+ ti->arg4 = kd->arg1; /* top half address */
+ ti->arg5 = kd->arg2; /* top half size */
+ break;
+ case BSC_pread_extended:
+ if ((ti = find_event(thread, BSC_pread)) == (struct th_info *)0) {
+ if ((ti = find_event(thread, BSC_pread_nocancel)) == (struct th_info *)0)
+ return;
+ }
+ ti->arg1 = kd->arg1; /* the fd */
+ ti->arg2 = kd->arg2; /* nbytes */
+ ti->arg3 = kd->arg3; /* top half offset */
+ ti->arg4 = kd->arg4; /* bottom half offset */
+ break;
+ case BSC_pwrite_extended:
+ if ((ti = find_event(thread, BSC_pwrite)) == (struct th_info *)0) {
+ if ((ti = find_event(thread, BSC_pwrite_nocancel)) == (struct th_info *)0)
+ return;
+ }
+ ti->arg1 = kd->arg1; /* the fd */
+ ti->arg2 = kd->arg2; /* nbytes */
+ ti->arg3 = kd->arg3; /* top half offset */
+ ti->arg4 = kd->arg4; /* bottom half offset */
+ break;
+ default:
+ return;
+ }
+}
- case BSC_sync:
- exit_syscall("sync", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
- case BSC_symlink:
- exit_syscall("symlink", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
+void
+exit_event(char *sc_name, uintptr_t thread, int type, uintptr_t arg1, uintptr_t arg2, uintptr_t arg3, uintptr_t arg4,
+ int format, double now)
+{
+ th_info_t ti;
+
+ if ((ti = find_event(thread, type)) == (struct th_info *)0)
+ return;
- case BSC_readlink:
- exit_syscall("readlink", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
+ ti->nameptr = 0;
- case BSC_fsync:
- exit_syscall("fsync", thread, type, kd[i].arg1, kd[i].arg2, 1, 0, (double)now);
- break;
+ if (check_filter_mode(ti, type, arg1, arg2, sc_name))
+ format_print(ti, sc_name, thread, type, arg1, arg2, arg3, arg4, format, now, ti->stime, ti->waited, (char *)&ti->lookups[0].pathname[0], NULL);
- case BSC_readv:
- exit_syscall("readv", thread, type, kd[i].arg1, kd[i].arg2, 1, 1, (double)now);
- break;
+ switch (type) {
- case BSC_writev:
- exit_syscall("writev", thread, type, kd[i].arg1, kd[i].arg2, 1, 1, (double)now);
- break;
+ case HFS_update:
+ ti->in_hfs_update = 0;
+ break;
+ }
+ if ((type & CLASS_MASK) == FILEMGR_BASE) {
+ ti->in_filemgr = 0;
- case BSC_pread:
- exit_syscall("pread", thread, type, kd[i].arg1, kd[i].arg2, 1, 9, (double)now);
- break;
+ if (filemgr_in_progress > 0)
+ filemgr_in_progress--;
+ }
+ delete_event(ti);
+}
- case BSC_pwrite:
- exit_syscall("pwrite", thread, type, kd[i].arg1, kd[i].arg2, 1, 9, (double)now);
- break;
- case BSC_fchown:
- exit_syscall("fchown", thread, type, kd[i].arg1, kd[i].arg2, 1, 0, (double)now);
- break;
+void
+get_mode_nibble(char * buf, int smode, int special, char x_on, char x_off)
+{
+ if (smode & 04)
+ buf[0] = 'r';
+ if (smode & 02)
+ buf[1] = 'w';
+ if (smode & 01) {
+ if (special)
+ buf[2] = x_on;
+ else
+ buf[2] = 'x';
+ } else {
+ if (special)
+ buf[2] = x_off;
+ }
+}
- case BSC_fchmod:
- exit_syscall("fchmod", thread, type, kd[i].arg1, kd[i].arg2, 1, 0, (double)now);
- break;
- case BSC_mkdir:
- exit_syscall("mkdir", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
-
- case BSC_mkfifo:
- exit_syscall("mkfifo", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
+void
+get_mode_string(int mode, char *buf)
+{
+ memset(buf, '-', 9);
+ buf[9] = '\0';
- case BSC_rmdir:
- exit_syscall("rmdir", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
+ get_mode_nibble(&buf[6], mode, (mode & 01000), 't', 'T');
+ get_mode_nibble(&buf[3], (mode>>3), (mode & 02000), 's', 'S');
+ get_mode_nibble(&buf[0], (mode>>6), (mode & 04000), 's', 'S');
+}
- case BSC_statfs:
- exit_syscall("statfs", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
- case BSC_fstatfs:
- exit_syscall("fstatfs", thread, type, kd[i].arg1, kd[i].arg2, 1, 0, (double)now);
- break;
+int clip_64bit(char *s, uint64_t value)
+{
+ int clen = 0;
+
+ if ( (value & 0xff00000000000000LL) )
+ clen = printf("%s0x%16.16qx", s, value);
+ else if ( (value & 0x00ff000000000000LL) )
+ clen = printf("%s0x%14.14qx ", s, value);
+ else if ( (value & 0x0000ff0000000000LL) )
+ clen = printf("%s0x%12.12qx ", s, value);
+ else if ( (value & 0x000000ff00000000LL) )
+ clen = printf("%s0x%10.10qx ", s, value);
+ else
+ clen = printf("%s0x%8.8qx ", s, value);
+
+ return (clen);
+}
- case BSC_pathconf:
- exit_syscall("pathconf", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
- case BSC_fpathconf:
- exit_syscall("fpathconf", thread, type, kd[i].arg1, kd[i].arg2, 1, 0, (double)now);
- break;
+void
+format_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,
+ int format, double now, double stime, int waited, char *pathname, struct diskio *dio)
+{
+ int secs;
+ int usecs;
+ int nopadding = 0;
+ long long l_usecs;
+ long curr_time;
+ char *command_name;
+ int in_filemgr = 0;
+ int len = 0;
+ int clen = 0;
+ int tlen = 0;
+ int class;
+ uint64_t user_addr;
+ uint64_t user_size;
+ char *framework_name;
+ char *framework_type;
+ char *p1;
+ char *p2;
+ char buf[MAXWIDTH];
+ char cs_diskname[32];
+
+ static char timestamp[32];
+ static int last_timestamp = -1;
+ static int timestamp_len = 0;
+
+ command_name = "";
+
+ if (RAW_flag) {
+ l_usecs = (long long)((now - bias_now) / divisor);
+
+ if ((double)l_usecs < start_time || (double)l_usecs > end_time)
+ return;
+
+ l_usecs += (sample_TOD_secs * 1000000) + sample_TOD_usecs;
+ }
+ else
+ l_usecs = (long long)(now / divisor);
+ secs = l_usecs / 1000000;
+ curr_time = bias_secs + secs;
- case BSC_getdirentries:
- exit_syscall("getdirentries", thread, type, kd[i].arg1, kd[i].arg2, 1, 1, (double)now);
- break;
+ class = type >> 24;
- case BSC_lseek:
- exit_syscall("lseek", thread, type, kd[i].arg1, kd[i].arg3, 1, 5, (double)now);
- break;
+ if (dio)
+ command_name = dio->issuing_command;
+ else {
+ threadmap_t tme;
- case BSC_truncate:
- exit_syscall("truncate", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
+ if ((tme = find_map_entry(thread)))
+ command_name = tme->tm_command;
+ }
+ if (last_timestamp != curr_time) {
+ timestamp_len = sprintf(timestamp, "%-8.8s", &(ctime(&curr_time)[11]));
+ last_timestamp = curr_time;
+ }
+ if (columns > MAXCOLS || wideflag) {
+ int usec;
- case BSC_ftruncate:
- exit_syscall("ftruncate", thread, type, kd[i].arg1, kd[i].arg2, 1, 3, (double)now);
- break;
+ tlen = timestamp_len;
+ nopadding = 0;
+ usec = (l_usecs - (long long)((long long)secs * 1000000));
- case BSC_statv:
- exit_syscall("statv", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
+ sprintf(×tamp[tlen], ".%06ld", (long)usec);
+ tlen += 7;
- case BSC_lstatv:
- exit_syscall("lstatv", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
+ timestamp[tlen] = '\0';
- case BSC_fstatv:
- exit_syscall("fstatv", thread, type, kd[i].arg1, kd[i].arg2, 1, 0, (double)now);
- break;
+ if (filemgr_in_progress) {
+ if (class != FILEMGR_CLASS) {
+ if (find_event(thread, -1))
+ in_filemgr = 1;
+ }
+ }
+ } else
+ nopadding = 1;
- case BSC_mkcomplex:
- exit_syscall("mkcomplex", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
+ if ((class == FILEMGR_CLASS) && (columns > MAXCOLS || wideflag))
+ clen = printf("%s %-20.20s", timestamp, sc_name);
+ else if (in_filemgr)
+ clen = printf("%s %-15.15s", timestamp, sc_name);
+ else
+ clen = printf("%s %-17.17s", timestamp, sc_name);
+
- case BSC_getattrlist:
- exit_syscall("getattrlist", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
+ framework_name = NULL;
- case BSC_setattrlist:
- exit_syscall("setattrlist", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
+ if (columns > MAXCOLS || wideflag) {
- case BSC_getdirentriesattr:
- exit_syscall("getdirentriesattr", thread, type, kd[i].arg1, kd[i].arg2, 0, 1, (double)now);
- break;
+ off_t offset_reassembled = 0LL;
+
+ switch (format) {
+
+ case FMT_DEFAULT:
+ /*
+ * pathname based system calls or
+ * calls with no fd or pathname (i.e. sync)
+ */
+ if (arg1)
+ clen += printf(" [%3d] ", arg1);
+ else
+ clen += printf(" ");
+ break;
+
+ case FMT_FD:
+ /*
+ * fd based system call... no I/O
+ */
+ if (arg1)
+ clen += printf(" F=%-3d[%3d]", ti->arg1, arg1);
+ else
+ clen += printf(" F=%-3d", ti->arg1);
+ break;
+
+ case FMT_FD_2:
+ /*
+ * accept, dup, dup2
+ */
+ if (arg1)
+ clen += printf(" F=%-3d[%3d]", ti->arg1, arg1);
+ else
+ clen += printf(" F=%-3d F=%-3d", ti->arg1, arg2);
+ break;
+
+ case FMT_FD_IO:
+ /*
+ * system calls with fd's that return an I/O completion count
+ */
+ if (arg1)
+ clen += printf(" F=%-3d[%3d]", ti->arg1, arg1);
+ else
+ clen += printf(" F=%-3d B=0x%-6x", ti->arg1, arg2);
+ break;
+
+ case FMT_PGIN:
+ /*
+ * pagein
+ */
+ user_addr = ((uint64_t)arg2 << 32) | (uint32_t)arg3;
+
+ lookup_name(user_addr, &framework_type, &framework_name);
+ clen += clip_64bit(" A=", user_addr);
+ break;
+
+ case FMT_CACHEHIT:
+ /*
+ * cache hit
+ */
+ user_addr = ((uint64_t)arg2 << 32) | (uint32_t)arg3;
+
+ lookup_name(user_addr, &framework_type, &framework_name);
+ clen += clip_64bit(" A=", user_addr);
+ break;
+
+ case FMT_PGOUT:
+ /*
+ * pageout
+ */
+ clen += printf(" B=0x%-8x", arg2);
+ break;
+
+ case FMT_HFS_update:
+ {
+ char sbuf[7];
+ int sflag = (int)arg2;
+
+ memset(sbuf, '_', 6);
+ sbuf[6] = '\0';
+
+
+ if (sflag & 0x10)
+ sbuf[0] = 'F';
+ if (sflag & 0x08)
+ sbuf[1] = 'M';
+ if (sflag & 0x20)
+ sbuf[2] = 'D';
+ if (sflag & 0x04)
+ sbuf[3] = 'c';
+ if (sflag & 0x01)
+ sbuf[4] = 'a';
+ if (sflag & 0x02)
+ sbuf[5] = 'm';
+
+ clen += printf(" (%s) ", sbuf);
+
+ pathname = find_vnode_name(arg1);
+ nopadding = 1;
+
+ break;
+ }
+ case FMT_DISKIO:
+ /*
+ * physical disk I/O
+ */
+ if (dio->io_errno)
+ clen += printf(" D=0x%8.8x [%3d]", dio->blkno, dio->io_errno);
+ else {
+ if (BC_flag)
+ 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));
+ else
+ clen += printf(" D=0x%8.8x B=0x%-6x /dev/%s ", dio->blkno, dio->iosize, find_disk_name(dio->dev));
+
+ if (dio->is_meta)
+ pathname = find_meta_name(dio->blkno);
+ else
+ pathname = find_vnode_name(dio->vnodeid);
+ nopadding = 1;
+ }
+ break;
+
+ case FMT_DISKIO_CS:
+ /*
+ * physical disk I/O
+ */
+ if (dio->io_errno)
+ clen += printf(" D=0x%8.8x [%3d]", dio->blkno, dio->io_errno);
+ else
+ clen += printf(" D=0x%8.8x B=0x%-6x /dev/%s", dio->blkno, dio->iosize, generate_cs_disk_name(dio->dev, &cs_diskname[0]));
+ break;
+
+ case FMT_SYNC_DISK_CS:
+ /*
+ * physical disk sync cache
+ */
+ clen += printf(" /dev/%s", generate_cs_disk_name(arg1, &cs_diskname[0]));
+
+ break;
+
+ case FMT_MSYNC:
+ {
+ /*
+ * msync
+ */
+ int mlen = 0;
+
+ buf[0] = '\0';
+
+ if (ti->arg3 & MS_ASYNC)
+ mlen += sprintf(&buf[mlen], "MS_ASYNC | ");
+ else
+ mlen += sprintf(&buf[mlen], "MS_SYNC | ");
+
+ if (ti->arg3 & MS_INVALIDATE)
+ mlen += sprintf(&buf[mlen], "MS_INVALIDATE | ");
+ if (ti->arg3 & MS_KILLPAGES)
+ mlen += sprintf(&buf[mlen], "MS_KILLPAGES | ");
+ if (ti->arg3 & MS_DEACTIVATE)
+ mlen += sprintf(&buf[mlen], "MS_DEACTIVATE | ");
+
+ if (ti->arg3 & ~(MS_ASYNC | MS_SYNC | MS_INVALIDATE | MS_KILLPAGES | MS_DEACTIVATE))
+ mlen += sprintf(&buf[mlen], "UNKNOWN | ");
+
+ if (mlen)
+ buf[mlen - 3] = '\0';
+
+ if (arg1)
+ clen += printf(" [%3d]", arg1);
+
+ user_addr = (((off_t)(unsigned int)(ti->arg4)) << 32) | (unsigned int)(ti->arg1);
+ clen += clip_64bit(" A=", user_addr);
+
+ user_size = (((off_t)(unsigned int)(ti->arg5)) << 32) | (unsigned int)(ti->arg2);
+
+ clen += printf(" B=0x%-16qx <%s>", user_size, buf);
+
+ break;
+ }
- case BSC_exchangedata:
- exit_syscall("exchangedata", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
-
- case BSC_rename:
- exit_syscall("rename", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
+ case FMT_FLOCK:
+ {
+ /*
+ * flock
+ */
+ int mlen = 0;
+
+ buf[0] = '\0';
+
+ if (ti->arg2 & LOCK_SH)
+ mlen += sprintf(&buf[mlen], "LOCK_SH | ");
+ if (ti->arg2 & LOCK_EX)
+ mlen += sprintf(&buf[mlen], "LOCK_EX | ");
+ if (ti->arg2 & LOCK_NB)
+ mlen += sprintf(&buf[mlen], "LOCK_NB | ");
+ if (ti->arg2 & LOCK_UN)
+ mlen += sprintf(&buf[mlen], "LOCK_UN | ");
+
+ if (ti->arg2 & ~(LOCK_SH | LOCK_EX | LOCK_NB | LOCK_UN))
+ mlen += sprintf(&buf[mlen], "UNKNOWN | ");
+
+ if (mlen)
+ buf[mlen - 3] = '\0';
+
+ if (arg1)
+ clen += printf(" F=%-3d[%3d] <%s>", ti->arg1, arg1, buf);
+ else
+ clen += printf(" F=%-3d <%s>", ti->arg1, buf);
+
+ break;
+ }
- case BSC_copyfile:
- exit_syscall("copyfile", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
+ case FMT_FCNTL:
+ {
+ /*
+ * fcntl
+ */
+ char *p = NULL;
+ int fd = -1;
+
+ if (arg1)
+ clen += printf(" F=%-3d[%3d]", ti->arg1, arg1);
+ else
+ clen += printf(" F=%-3d", ti->arg1);
+
+ switch(ti->arg2) {
+
+ case F_DUPFD:
+ p = "DUPFD";
+ break;
+
+ case F_GETFD:
+ p = "GETFD";
+ break;
+
+ case F_SETFD:
+ p = "SETFD";
+ break;
+
+ case F_GETFL:
+ p = "GETFL";
+ break;
+
+ case F_SETFL:
+ p = "SETFL";
+ break;
+
+ case F_GETOWN:
+ p = "GETOWN";
+ break;
+
+ case F_SETOWN:
+ p = "SETOWN";
+ break;
+
+ case F_GETLK:
+ p = "GETLK";
+ break;
+
+ case F_SETLK:
+ p = "SETLK";
+ break;
+
+ case F_SETLKW:
+ p = "SETLKW";
+ break;
+
+ case F_PREALLOCATE:
+ p = "PREALLOCATE";
+ break;
+
+ case F_SETSIZE:
+ p = "SETSIZE";
+ break;
+
+ case F_RDADVISE:
+ p = "RDADVISE";
+ break;
+
+ case F_GETPATH:
+ p = "GETPATH";
+ break;
+
+ case F_FULLFSYNC:
+ p = "FULLFSYNC";
+ break;
+
+ case F_PATHPKG_CHECK:
+ p = "PATHPKG_CHECK";
+ break;
+
+ case F_OPENFROM:
+ p = "OPENFROM";
+
+ if (arg1 == 0)
+ fd = arg2;
+ break;
+
+ case F_UNLINKFROM:
+ p = "UNLINKFROM";
+ break;
+
+ case F_CHECK_OPENEVT:
+ p = "CHECK_OPENEVT";
+ break;
+
+ case F_NOCACHE:
+ if (ti->arg3)
+ p = "CACHING OFF";
+ else
+ p = "CACHING ON";
+ break;
+
+ case F_GLOBAL_NOCACHE:
+ if (ti->arg3)
+ p = "CACHING OFF (GLOBAL)";
+ else
+ p = "CACHING ON (GLOBAL)";
+ break;
+ }
+ if (p) {
+ if (fd == -1)
+ clen += printf(" <%s>", p);
+ else
+ clen += printf(" <%s> F=%d", p, fd);
+ } else
+ clen += printf(" <CMD=%d>", ti->arg2);
+
+ break;
+ }
- case BSC_checkuseraccess:
- exit_syscall("checkuseraccess", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
+ case FMT_IOCTL:
+ {
+ /*
+ * ioctl
+ */
+ if (arg1)
+ clen += printf(" F=%-3d[%3d]", ti->arg1, arg1);
+ else
+ clen += printf(" F=%-3d", ti->arg1);
- case BSC_searchfs:
- exit_syscall("searchfs", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
+ clen += printf(" <CMD=0x%x>", ti->arg2);
+
+ break;
+ }
+
+ case FMT_IOCTL_SYNC:
+ {
+ /*
+ * ioctl
+ */
+ clen += printf(" <DKIOCSYNCHRONIZECACHE> /dev/%s", find_disk_name(arg1));
+
+ break;
+ }
+
+ case FMT_IOCTL_UNMAP:
+ {
+ /*
+ * ioctl
+ */
+ clen += printf(" <DKIOCUNMAP> /dev/%s", find_disk_name(arg1));
+
+ break;
+ }
+
+ case FMT_UNMAP_INFO:
+ {
+ clen += printf(" D=0x%8.8x B=0x%-6x /dev/%s", arg2, arg3, find_disk_name(arg1));
+
+ break;
+ }
+
+ case FMT_SELECT:
+ /*
+ * select
+ */
+ if (arg1)
+ clen += printf(" [%3d]", arg1);
+ else
+ clen += printf(" S=%-3d", arg2);
+
+ break;
+
+ case FMT_LSEEK:
+ case FMT_PREAD:
+ /*
+ * pread, pwrite, lseek
+ */
+ clen += printf(" F=%-3d", ti->arg1);
+
+ if (arg1)
+ clen += printf("[%3d] ", arg1);
+ else {
+ if (format == FMT_PREAD)
+ clen += printf(" B=0x%-8x ", arg2);
+ else
+ clen += printf(" ");
+ }
+ if (format == FMT_PREAD)
+ offset_reassembled = (((off_t)(unsigned int)(ti->arg3)) << 32) | (unsigned int)(ti->arg4);
+ else
+#ifdef __ppc__
+ offset_reassembled = (((off_t)(unsigned int)(arg2)) << 32) | (unsigned int)(arg3);
+#else
+ offset_reassembled = (((off_t)(unsigned int)(arg3)) << 32) | (unsigned int)(arg2);
+#endif
+ clen += clip_64bit("O=", offset_reassembled);
+
+ if (format == FMT_LSEEK) {
+ char *mode;
+
+ if (ti->arg4 == SEEK_SET)
+ mode = "SEEK_SET";
+ else if (ti->arg4 == SEEK_CUR)
+ mode = "SEEK_CUR";
+ else if (ti->arg4 == SEEK_END)
+ mode = "SEEK_END";
+ else
+ mode = "UNKNOWN";
+
+ clen += printf(" <%s>", mode);
+ }
+ break;
+
+ case FMT_MMAP:
+ /*
+ * mmap
+ */
+ clen += printf(" F=%-3d ", ti->arg1);
+
+ if (arg1)
+ clen += printf("[%3d] ", arg1);
+ else {
+
+ user_addr = (((off_t)(unsigned int)(ti->arg2)) << 32) | (unsigned int)(ti->arg3);
+
+ clen += clip_64bit("A=", user_addr);
+
+ offset_reassembled = (((off_t)(unsigned int)(ti->arg6)) << 32) | (unsigned int)(ti->arg7);
+
+ clen += clip_64bit("O=", offset_reassembled);
+
+ user_size = (((off_t)(unsigned int)(ti->arg4)) << 32) | (unsigned int)(ti->arg5);
+
+ clen += printf("B=0x%-16qx", user_size);
+
+ clen += printf(" <");
+
+ if (ti->arg8 & PROT_READ)
+ clen += printf("READ");
+
+ if (ti->arg8 & PROT_WRITE)
+ clen += printf("|WRITE");
+
+ if (ti->arg8 & PROT_EXEC)
+ clen += printf("|EXEC");
+
+ clen += printf(">");
+ }
+ break;
+
+ case FMT_TRUNC:
+ case FMT_FTRUNC:
+ /*
+ * ftruncate, truncate
+ */
+ if (format == FMT_FTRUNC)
+ clen += printf(" F=%-3d", ti->arg1);
+ else
+ clen += printf(" ");
+
+ if (arg1)
+ clen += printf("[%3d]", arg1);
+
+#ifdef __ppc__
+ offset_reassembled = (((off_t)(unsigned int)(ti->arg2)) << 32) | (unsigned int)(ti->arg3);
+#else
+ offset_reassembled = (((off_t)(unsigned int)(ti->arg3)) << 32) | (unsigned int)(ti->arg2);
+#endif
+ clen += clip_64bit(" O=", offset_reassembled);
+
+ nopadding = 1;
+ break;
+
+ case FMT_FCHFLAGS:
+ case FMT_CHFLAGS:
+ {
+ /*
+ * fchflags, chflags
+ */
+ int mlen = 0;
+
+ if (format == FMT_FCHFLAGS) {
+ if (arg1)
+ clen += printf(" F=%-3d[%3d]", ti->arg1, arg1);
+ else
+ clen += printf(" F=%-3d", ti->arg1);
+ } else {
+ if (arg1)
+ clen += printf(" [%3d] ", arg1);
+ }
+ buf[mlen++] = ' ';
+ buf[mlen++] = '<';
+
+ if (ti->arg2 & UF_NODUMP)
+ mlen += sprintf(&buf[mlen], "UF_NODUMP | ");
+ if (ti->arg2 & UF_IMMUTABLE)
+ mlen += sprintf(&buf[mlen], "UF_IMMUTABLE | ");
+ if (ti->arg2 & UF_APPEND)
+ mlen += sprintf(&buf[mlen], "UF_APPEND | ");
+ if (ti->arg2 & UF_OPAQUE)
+ mlen += sprintf(&buf[mlen], "UF_OPAQUE | ");
+ if (ti->arg2 & SF_ARCHIVED)
+ mlen += sprintf(&buf[mlen], "SF_ARCHIVED | ");
+ if (ti->arg2 & SF_IMMUTABLE)
+ mlen += sprintf(&buf[mlen], "SF_IMMUTABLE | ");
+ if (ti->arg2 & SF_APPEND)
+ mlen += sprintf(&buf[mlen], "SF_APPEND | ");
+
+ if (ti->arg2 == 0)
+ mlen += sprintf(&buf[mlen], "CLEAR_ALL_FLAGS | ");
+ else if (ti->arg2 & ~(UF_NODUMP | UF_IMMUTABLE | UF_APPEND | SF_ARCHIVED | SF_IMMUTABLE | SF_APPEND))
+ mlen += sprintf(&buf[mlen], "UNKNOWN | ");
+
+ if (mlen >= 3)
+ mlen -= 3;
+
+ buf[mlen++] = '>';
+ buf[mlen] = '\0';
+
+ if (mlen < 19) {
+ memset(&buf[mlen], ' ', 19 - mlen);
+ mlen = 19;
+ }
+ clen += printf("%s", buf);
+
+ nopadding = 1;
+ break;
+ }
+
+ case FMT_UMASK:
+ case FMT_FCHMOD:
+ case FMT_FCHMOD_EXT:
+ case FMT_CHMOD:
+ case FMT_CHMOD_EXT:
+ {
+ /*
+ * fchmod, fchmod_extended, chmod, chmod_extended
+ */
+ int mode;
+
+ if (format == FMT_FCHMOD || format == FMT_FCHMOD_EXT) {
+ if (arg1)
+ clen += printf(" F=%-3d[%3d] ", ti->arg1, arg1);
+ else
+ clen += printf(" F=%-3d ", ti->arg1);
+ } else {
+ if (arg1)
+ clen += printf(" [%3d] ", arg1);
+ else
+ clen += printf(" ");
+ }
+ if (format == FMT_UMASK)
+ mode = ti->arg1;
+ else if (format == FMT_FCHMOD || format == FMT_CHMOD)
+ mode = ti->arg2;
+ else
+ mode = ti->arg4;
+
+ get_mode_string(mode, &buf[0]);
+
+ if (arg1 == 0)
+ clen += printf("<%s> ", buf);
+ else
+ clen += printf("<%s>", buf);
+ break;
+ }
+
+ case FMT_ACCESS:
+ {
+ /*
+ * access
+ */
+ char mode[5];
+
+ memset(mode, '_', 4);
+ mode[4] = '\0';
+
+ if (ti->arg2 & R_OK)
+ mode[0] = 'R';
+ if (ti->arg2 & W_OK)
+ mode[1] = 'W';
+ if (ti->arg2 & X_OK)
+ mode[2] = 'X';
+ if (ti->arg2 == F_OK)
+ mode[3] = 'F';
+
+ if (arg1)
+ clen += printf(" [%3d] (%s) ", arg1, mode);
+ else
+ clen += printf(" (%s) ", mode);
+
+ nopadding = 1;
+ break;
+ }
+
+ case FMT_MOUNT:
+ {
+ if (arg1)
+ clen += printf(" [%3d] <FLGS=0x%x> ", arg1, ti->arg3);
+ else
+ clen += printf(" <FLGS=0x%x> ", ti->arg3);
+
+ nopadding = 1;
+ break;
+ }
+
+ case FMT_UNMOUNT:
+ {
+ char *mountflag;
+
+ if (ti->arg2 & MNT_FORCE)
+ mountflag = "<FORCE>";
+ else
+ mountflag = "";
+
+ if (arg1)
+ clen += printf(" [%3d] %s ", arg1, mountflag);
+ else
+ clen += printf(" %s ", mountflag);
+
+ nopadding = 1;
+ break;
+ }
+
+ case FMT_OPEN:
+ {
+ /*
+ * open
+ */
+ char mode[7];
+
+ memset(mode, '_', 6);
+ mode[6] = '\0';
+
+ if (ti->arg2 & O_RDWR) {
+ mode[0] = 'R';
+ mode[1] = 'W';
+ } else if (ti->arg2 & O_WRONLY)
+ mode[1] = 'W';
+ else
+ mode[0] = 'R';
+
+ if (ti->arg2 & O_CREAT)
+ mode[2] = 'C';
+
+ if (ti->arg2 & O_APPEND)
+ mode[3] = 'A';
+
+ if (ti->arg2 & O_TRUNC)
+ mode[4] = 'T';
+
+ if (ti->arg2 & O_EXCL)
+ mode[5] = 'E';
+
+ if (arg1)
+ clen += printf(" [%3d] (%s) ", arg1, mode);
+ else
+ clen += printf(" F=%-3d (%s) ", arg2, mode);
+
+ nopadding = 1;
+ break;
+ }
+
+ case FMT_SOCKET:
+ {
+ /*
+ * socket
+ *
+ */
+ char *domain;
+ char *type;
+
+ switch (ti->arg1) {
+
+ case AF_UNIX:
+ domain = "AF_UNIX";
+ break;
+
+ case AF_INET:
+ domain = "AF_INET";
+ break;
+
+ case AF_ISO:
+ domain = "AF_ISO";
+ break;
+
+ case AF_NS:
+ domain = "AF_NS";
+ break;
+
+ case AF_IMPLINK:
+ domain = "AF_IMPLINK";
+ break;
+
+ default:
+ domain = "UNKNOWN";
+ break;
+ }
+
+ switch (ti->arg2) {
+
+ case SOCK_STREAM:
+ type = "SOCK_STREAM";
+ break;
+
+ case SOCK_DGRAM:
+ type = "SOCK_DGRAM";
+ break;
+
+ case SOCK_RAW:
+ type = "SOCK_RAW";
+ break;
+
+ case SOCK_SEQPACKET:
+ type = "SOCK_SEQPACKET";
+ break;
+
+ case SOCK_RDM:
+ type = "SOCK_RDM";
+ break;
+
+ default:
+ type = "UNKNOWN";
+ break;
+ }
+
+ if (arg1)
+ clen += printf(" [%3d] <%s, %s, 0x%x>", arg1, domain, type, ti->arg3);
+ else
+ clen += printf(" F=%-3d <%s, %s, 0x%x>", arg2, domain, type, ti->arg3);
+ break;
+ }
+
+ case FMT_AIO_FSYNC:
+ {
+ /*
+ * aio_fsync [errno] AIOCBP OP
+ */
+ char *op;
+
+ if (ti->arg1 == O_SYNC || ti->arg1 == 0)
+ op = "AIO_FSYNC";
+#if O_DSYNC
+ else if (ti->arg1 == O_DSYNC)
+ op = "AIO_DSYNC";
+#endif
+ else
+ op = "UNKNOWN";
+
+ if (arg1)
+ clen += printf(" [%3d] P=0x%8.8x <%s>", arg1, ti->arg2, op);
+ else
+ clen += printf(" P=0x%8.8x <%s>", ti->arg2, op);
+ break;
+ }
+
+ case FMT_AIO_RETURN:
+ /*
+ * aio_return [errno] AIOCBP IOSIZE
+ */
+ if (arg1)
+ clen += printf(" [%3d] P=0x%8.8x", arg1, ti->arg1);
+ else
+ clen += printf(" P=0x%8.8x B=0x%-8x", ti->arg1, arg2);
+ break;
+
+ case FMT_AIO_SUSPEND:
+ /*
+ * aio_suspend [errno] NENTS
+ */
+ if (arg1)
+ clen += printf(" [%3d] N=%d", arg1, ti->arg2);
+ else
+ clen += printf(" N=%d", ti->arg2);
+ break;
+
+ case FMT_AIO_CANCEL:
+ /*
+ * aio_cancel [errno] FD or AIOCBP (if non-null)
+ */
+ if (ti->arg2) {
+ if (arg1)
+ clen += printf(" [%3d] P=0x%8.8x", arg1, ti->arg2);
+ else
+ clen += printf(" P=0x%8.8x", ti->arg2);
+ } else {
+ if (arg1)
+ clen += printf(" F=%-3d[%3d]", ti->arg1, arg1);
+ else
+ clen += printf(" F=%-3d", ti->arg1);
+ }
+ break;
+
+ case FMT_AIO:
+ /*
+ * aio_error, aio_read, aio_write [errno] AIOCBP
+ */
+ if (arg1)
+ clen += printf(" [%3d] P=0x%8.8x", arg1, ti->arg1);
+ else
+ clen += printf(" P=0x%8.8x", ti->arg1);
+ break;
+
+ case FMT_LIO_LISTIO:
+ {
+ /*
+ * lio_listio [errno] NENTS MODE
+ */
+ char *op;
+
+ if (ti->arg1 == LIO_NOWAIT)
+ op = "LIO_NOWAIT";
+ else if (ti->arg1 == LIO_WAIT)
+ op = "LIO_WAIT";
+ else
+ op = "UNKNOWN";
+
+ if (arg1)
+ clen += printf(" [%3d] N=%d <%s>", arg1, ti->arg3, op);
+ else
+ clen += printf(" N=%d <%s>", ti->arg3, op);
+ break;
+ }
- case FILEMGR_PBGETCATALOGINFO:
- exit_syscall("GetCatalogInfo", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
- case FILEMGR_PBGETCATALOGINFOBULK:
- exit_syscall("GetCatalogInfoBulk", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
- case FILEMGR_PBCREATEFILEUNICODE:
- exit_syscall("CreateFileUnicode", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
- case FILEMGR_PBCREATEDIRECTORYUNICODE:
- exit_syscall("CreateDirectoryUnicode", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
- case FILEMGR_PBCREATEFORK:
- exit_syscall("PBCreateFork", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
- case FILEMGR_PBDELETEFORK:
- exit_syscall("PBDeleteFork", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
- case FILEMGR_PBITERATEFORK:
- exit_syscall("PBIterateFork", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
- case FILEMGR_PBOPENFORK:
- exit_syscall("PBOpenFork", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
- case FILEMGR_PBREADFORK:
- exit_syscall("PBReadFork", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
- case FILEMGR_PBWRITEFORK:
- exit_syscall("PBWriteFork", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
- case FILEMGR_PBALLOCATEFORK:
- exit_syscall("PBAllocateFork", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
- case FILEMGR_PBDELETEOBJECT:
- exit_syscall("PBDeleteObject", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
- case FILEMGR_PBEXCHANGEOBJECT:
- exit_syscall("PBExchangeObject", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
- case FILEMGR_PBGETFORKCBINFO:
- exit_syscall("PBGetForkCBInfo", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
- case FILEMGR_PBGETVOLUMEINFO:
- exit_syscall("PBGetVolumeInfo", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
- case FILEMGR_PBMAKEFSREF:
- exit_syscall("PBMakeFSRef", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
- case FILEMGR_PBMAKEFSREFUNICODE:
- exit_syscall("PBMakeFSRefUnicode", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
- case FILEMGR_PBMOVEOBJECT:
- exit_syscall("PBMoveObject", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
- case FILEMGR_PBOPENITERATOR:
- exit_syscall("PBOpenIterator", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
- case FILEMGR_PBRENAMEUNICODE:
- exit_syscall("PBRenameUnicode", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
- case FILEMGR_PBSETCATALOGINFO:
- exit_syscall("PBSetCatalogInfo", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
- case FILEMGR_PBSETVOLUMEINFO:
- exit_syscall("PBSetVolumeInfo", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
- case FILEMGR_FSREFMAKEPATH:
- exit_syscall("FSRefMakePath", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
- case FILEMGR_FSPATHMAKEREF:
- exit_syscall("FSPathMakeRef", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
- case FILEMGR_PBGETCATINFO:
- exit_syscall("GetCatInfo", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
- case FILEMGR_PBGETCATINFOLITE:
- exit_syscall("GetCatInfoLite", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
- case FILEMGR_PBHGETFINFO:
- exit_syscall("PBHGetFInfo", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
- case FILEMGR_PBXGETVOLINFO:
- exit_syscall("PBXGetVolInfo", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
- case FILEMGR_PBHCREATE:
- exit_syscall("PBHCreate", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
- case FILEMGR_PBHOPENDF:
- exit_syscall("PBHOpenDF", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
- case FILEMGR_PBHOPENRF:
- exit_syscall("PBHOpenRF", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
- case FILEMGR_PBHGETDIRACCESS:
- exit_syscall("PBHGetDirAccess", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
- case FILEMGR_PBHSETDIRACCESS:
- exit_syscall("PBHSetDirAccess", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
- case FILEMGR_PBHMAPID:
- exit_syscall("PBHMapID", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
- case FILEMGR_PBHMAPNAME:
- exit_syscall("PBHMapName", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
- case FILEMGR_PBCLOSE:
- exit_syscall("PBClose", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
- case FILEMGR_PBFLUSHFILE:
- exit_syscall("PBFlushFile", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
- case FILEMGR_PBGETEOF:
- exit_syscall("PBGetEOF", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
- case FILEMGR_PBSETEOF:
- exit_syscall("PBSetEOF", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
- case FILEMGR_PBGETFPOS:
- exit_syscall("PBGetFPos", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
- case FILEMGR_PBREAD:
- exit_syscall("PBRead", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
- case FILEMGR_PBWRITE:
- exit_syscall("PBWrite", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
- case FILEMGR_PBGETFCBINFO:
- exit_syscall("PBGetFCBInfo", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
- case FILEMGR_PBSETFINFO:
- exit_syscall("PBSetFInfo", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
- case FILEMGR_PBALLOCATE:
- exit_syscall("PBAllocate", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
- case FILEMGR_PBALLOCCONTIG:
- exit_syscall("PBAllocContig", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
- case FILEMGR_PBSETFPOS:
- exit_syscall("PBSetFPos", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
- case FILEMGR_PBSETCATINFO:
- exit_syscall("PBSetCatInfo", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
- case FILEMGR_PBGETVOLPARMS:
- exit_syscall("PBGetVolParms", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
- case FILEMGR_PBSETVINFO:
- exit_syscall("PBSetVInfo", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
- case FILEMGR_PBMAKEFSSPEC:
- exit_syscall("PBMakeFSSpec", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
- case FILEMGR_PBHGETVINFO:
- exit_syscall("PBHGetVInfo", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
- case FILEMGR_PBCREATEFILEIDREF:
- exit_syscall("PBCreateFileIDRef", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
- case FILEMGR_PBDELETEFILEIDREF:
- exit_syscall("PBDeleteFileIDRef", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
- case FILEMGR_PBRESOLVEFILEIDREF:
- exit_syscall("PBResolveFileIDRef", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
- case FILEMGR_PBFLUSHVOL:
- exit_syscall("PBFlushVol", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
- case FILEMGR_PBHRENAME:
- exit_syscall("PBHRename", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
- case FILEMGR_PBCATMOVE:
- exit_syscall("PBCatMove", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
- case FILEMGR_PBEXCHANGEFILES:
- exit_syscall("PBExchangeFiles", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
- case FILEMGR_PBHDELETE:
- exit_syscall("PBHDelete", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
- case FILEMGR_PBDIRCREATE:
- exit_syscall("PBDirCreate", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
- case FILEMGR_PBCATSEARCH:
- exit_syscall("PBCatSearch", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
- case FILEMGR_PBHSETFLOCK:
- exit_syscall("PBHSetFLock", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
- case FILEMGR_PBHRSTFLOCK:
- exit_syscall("PBHRstFLock", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
- case FILEMGR_PBLOCKRANGE:
- exit_syscall("PBLockRange", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
- case FILEMGR_PBUNLOCKRANGE:
- exit_syscall("PBUnlockRange", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
- break;
- default:
- break;
}
}
- fflush(0);
+
+ /*
+ * Calculate space available to print pathname
+ */
+ if (columns > MAXCOLS || wideflag)
+ clen = columns - (clen + 14 + 20 + 11);
+ else
+ clen = columns - (clen + 14 + 12);
+
+ if (class != FILEMGR_CLASS && !nopadding)
+ clen -= 3;
+
+ if (framework_name)
+ len = sprintf(&buf[0], " %s %s ", framework_type, framework_name);
+ else if (*pathname != '\0') {
+ len = sprintf(&buf[0], " %s ", pathname);
+
+ if (format == FMT_MOUNT && ti->lookups[1].pathname[0]) {
+ int len2;
+
+ memset(&buf[len], ' ', 2);
+
+ len2 = sprintf(&buf[len+2], " %s ", (char *)&ti->lookups[1].pathname[0]);
+ len = len + 2 + len2;
+ }
+ } else
+ len = 0;
+
+ if (clen > len) {
+ /*
+ * Add null padding if column length
+ * is wider than the pathname length.
+ */
+ memset(&buf[len], ' ', clen - len);
+ buf[clen] = '\0';
+
+ pathname = buf;
+
+ } else if (clen == len) {
+ pathname = buf;
+
+ } else if ((clen > 0) && (clen < len)) {
+ /*
+ * This prints the tail end of the pathname
+ */
+ buf[len-clen] = ' ';
+
+ pathname = &buf[len - clen];
+
+ } else {
+ pathname = "";
+ }
+
+ /*
+ * fudge some additional system call overhead
+ * that currently isn't tracked... this also
+ * insures that we see a minimum of 1 us for
+ * an elapsed time
+ */
+ usecs = (unsigned long)(((now - stime) + (divisor-1)) / divisor);
+ secs = usecs / 1000000;
+ usecs -= secs * 1000000;
+
+ if (class != FILEMGR_CLASS && !nopadding)
+ p1 = " ";
+ else
+ p1 = "";
+
+ if (waited)
+ p2 = " W";
+ else
+ p2 = " ";
+
+ if (columns > MAXCOLS || wideflag)
+ printf("%s%s %3ld.%06ld%s %s.%d\n", p1, pathname, (unsigned long)secs, (unsigned long)usecs, p2, command_name, (int)thread);
+ else
+ printf("%s%s %3ld.%06ld%s %-12.12s\n", p1, pathname, (unsigned long)secs, (unsigned long)usecs, p2, command_name);
}
+
void
-enter_syscall(int thread, int type, kd_buf *kd, char *name, double now)
-{
- struct th_info *ti;
- int i;
- int secs;
- int usecs;
- long long l_usecs;
- long curr_time;
- kd_threadmap *map;
- kd_threadmap *find_thread_map();
- int clen = 0;
- int tsclen = 0;
- int nmclen = 0;
- int argsclen = 0;
- char buf[MAXCOLS];
-
- switch (type) {
-
- case MACH_pageout:
- case MACH_vmfault:
- case MSC_map_fd:
- case BSC_mmap:
- case BSC_recvmsg:
- case BSC_sendmsg:
- case BSC_recvfrom:
- case BSC_accept:
- case BSC_select:
- case BSC_socket:
- case BSC_connect:
- case BSC_bind:
- case BSC_listen:
- case BSC_sendto:
- case BSC_socketpair:
- case BSC_stat:
- case BSC_load_shared_file:
- case BSC_open:
- case BSC_dup:
- case BSC_dup2:
- case BSC_close:
- case BSC_read:
- case BSC_write:
- case BSC_fstat:
- case BSC_lstat:
- case BSC_link:
- case BSC_unlink:
- case BSC_mknod:
- case BSC_chmod:
- case BSC_chown:
- case BSC_access:
- case BSC_chflags:
- case BSC_fchflags:
- case BSC_fchdir:
- case BSC_futimes:
- case BSC_chdir:
- case BSC_utimes:
- case BSC_chroot:
- case BSC_undelete:
- case BSC_delete:
- case BSC_revoke:
- case BSC_fsctl:
- case BSC_copyfile:
- case BSC_sync:
- case BSC_symlink:
- case BSC_readlink:
- case BSC_fsync:
- case BSC_readv:
- case BSC_writev:
- case BSC_pread:
- case BSC_pwrite:
- case BSC_fchown:
- case BSC_fchmod:
- case BSC_rename:
- case BSC_mkdir:
- case BSC_mkfifo:
- case BSC_rmdir:
- case BSC_statfs:
- case BSC_fstatfs:
- case BSC_pathconf:
- case BSC_fpathconf:
- case BSC_getdirentries:
- case BSC_lseek:
- case BSC_truncate:
- case BSC_ftruncate:
- case BSC_statv:
- case BSC_lstatv:
- case BSC_fstatv:
- case BSC_mkcomplex:
- case BSC_getattrlist:
- case BSC_setattrlist:
- case BSC_getdirentriesattr:
- case BSC_exchangedata:
- case BSC_checkuseraccess:
- case BSC_searchfs:
- case FILEMGR_PBGETCATALOGINFO:
- case FILEMGR_PBGETCATALOGINFOBULK:
- case FILEMGR_PBCREATEFILEUNICODE:
- case FILEMGR_PBCREATEDIRECTORYUNICODE:
- case FILEMGR_PBCREATEFORK:
- case FILEMGR_PBDELETEFORK:
- case FILEMGR_PBITERATEFORK:
- case FILEMGR_PBOPENFORK:
- case FILEMGR_PBREADFORK:
- case FILEMGR_PBWRITEFORK:
- case FILEMGR_PBALLOCATEFORK:
- case FILEMGR_PBDELETEOBJECT:
- case FILEMGR_PBEXCHANGEOBJECT:
- case FILEMGR_PBGETFORKCBINFO:
- case FILEMGR_PBGETVOLUMEINFO:
- case FILEMGR_PBMAKEFSREF:
- case FILEMGR_PBMAKEFSREFUNICODE:
- case FILEMGR_PBMOVEOBJECT:
- case FILEMGR_PBOPENITERATOR:
- case FILEMGR_PBRENAMEUNICODE:
- case FILEMGR_PBSETCATALOGINFO:
- case FILEMGR_PBSETVOLUMEINFO:
- case FILEMGR_FSREFMAKEPATH:
- case FILEMGR_FSPATHMAKEREF:
-
- case FILEMGR_PBGETCATINFO:
- case FILEMGR_PBGETCATINFOLITE:
- case FILEMGR_PBHGETFINFO:
- case FILEMGR_PBXGETVOLINFO:
- case FILEMGR_PBHCREATE:
- case FILEMGR_PBHOPENDF:
- case FILEMGR_PBHOPENRF:
- case FILEMGR_PBHGETDIRACCESS:
- case FILEMGR_PBHSETDIRACCESS:
- case FILEMGR_PBHMAPID:
- case FILEMGR_PBHMAPNAME:
- case FILEMGR_PBCLOSE:
- case FILEMGR_PBFLUSHFILE:
- case FILEMGR_PBGETEOF:
- case FILEMGR_PBSETEOF:
- case FILEMGR_PBGETFPOS:
- case FILEMGR_PBREAD:
- case FILEMGR_PBWRITE:
- case FILEMGR_PBGETFCBINFO:
- case FILEMGR_PBSETFINFO:
- case FILEMGR_PBALLOCATE:
- case FILEMGR_PBALLOCCONTIG:
- case FILEMGR_PBSETFPOS:
- case FILEMGR_PBSETCATINFO:
- case FILEMGR_PBGETVOLPARMS:
- case FILEMGR_PBSETVINFO:
- case FILEMGR_PBMAKEFSSPEC:
- case FILEMGR_PBHGETVINFO:
- case FILEMGR_PBCREATEFILEIDREF:
- case FILEMGR_PBDELETEFILEIDREF:
- case FILEMGR_PBRESOLVEFILEIDREF:
- case FILEMGR_PBFLUSHVOL:
- case FILEMGR_PBHRENAME:
- case FILEMGR_PBCATMOVE:
- case FILEMGR_PBEXCHANGEFILES:
- case FILEMGR_PBHDELETE:
- case FILEMGR_PBDIRCREATE:
- case FILEMGR_PBCATSEARCH:
- case FILEMGR_PBHSETFLOCK:
- case FILEMGR_PBHRSTFLOCK:
- case FILEMGR_PBLOCKRANGE:
- case FILEMGR_PBUNLOCKRANGE:
-
-
- for (i = 0, ti = th_state; ti < &th_state[MAX_THREADS]; ti++, i++) {
- if (ti->thread == 0)
- break;
- }
- if (ti == &th_state[MAX_THREADS])
- return;
- if (i >= cur_max)
- cur_max = i + 1;
-
-
- if ((type >> 24) == FILEMGR_CLASS) {
- ti->in_filemgr = 1;
-
- l_usecs = (long long)(now / divisor);
- secs = l_usecs / 1000000;
- curr_time = bias_secs + secs;
-
- sprintf(buf, "%-8.8s", &(ctime(&curr_time)[11]));
- tsclen = strlen(buf);
-
- if (columns > MAXCOLS || wideflag) {
- usecs = l_usecs - (long long)((long long)secs * 1000000);
- sprintf(&buf[tsclen], ".%03ld", (long)usecs / 1000);
- tsclen = strlen(buf);
- }
-
- /* Print timestamp column */
- printf(buf);
-
- map = find_thread_map(thread);
- if (map) {
- sprintf(buf, " %-25.25s ", name);
- nmclen = strlen(buf);
- printf(buf);
-
- sprintf(buf, "(%d, 0x%x, 0x%x, 0x%x)", (short)kd->arg1, kd->arg2, kd->arg3, kd->arg4);
- argsclen = strlen(buf);
-
- /*
- Calculate white space out to command
- */
- if (columns > MAXCOLS || wideflag)
- {
- clen = columns - (tsclen + nmclen + argsclen + 20);
- }
- else
- clen = columns - (tsclen + nmclen + argsclen + 12);
-
- if(clen > 0)
- {
- printf(buf); /* print the kdargs */
- memset(buf, ' ', clen);
- buf[clen] = '\0';
- printf(buf);
- }
- else if ((argsclen + clen) > 0)
- {
- /* no room so wipe out the kdargs */
- memset(buf, ' ', (argsclen + clen));
- buf[argsclen + clen] = '\0';
- printf(buf);
- }
-
- if (columns > MAXCOLS || wideflag)
- printf("%-20.20s\n", map->command);
- else
- printf("%-12.12s\n", map->command);
- } else
- printf(" %-24.24s (%5d, %#x, 0x%x, 0x%x)\n", name, (short)kd->arg1, kd->arg2, kd->arg3, kd->arg4);
- } else {
- ti->in_filemgr = 0;
- }
- ti->thread = thread;
- ti->waited = 0;
- ti->type = type;
- ti->stime = now;
- ti->arg1 = kd->arg1;
- ti->arg2 = kd->arg2;
- ti->arg3 = kd->arg3;
- ti->arg4 = kd->arg4;
- ti->pathptr = (long *)0;
- ti->pathname[0] = 0;
- break;
-
- default:
- break;
- }
- fflush (0);
+add_meta_name(uint64_t blockno, char *pathname) {
+ meta_info_t mi;
+ int hashid;
+
+ hashid = blockno & VN_HASH_MASK;
+
+ for (mi = m_info_hash[hashid]; mi; mi = mi->m_next) {
+ if (mi->m_blkno == blockno)
+ break;
+ }
+ if (mi == NULL) {
+ mi = (meta_info_t)malloc(sizeof(struct meta_info));
+
+ mi->m_next = m_info_hash[hashid];
+ m_info_hash[hashid] = mi;
+ mi->m_blkno = blockno;
+ }
+ mi->m_nameptr = pathname;
}
-/*
- * Handle system call extended trace data.
- * pread and pwrite:
- * Wipe out the kd args that were collected upon syscall_entry
- * because it is the extended info that we really want, and it
- * is all we really need.
-*/
+char *
+find_meta_name(uint64_t blockno) {
+ meta_info_t mi;
+ int hashid;
-void
-extend_syscall(int thread, int type, kd_buf *kd, char *name, double now)
-{
- struct th_info *ti;
-
- switch (type) {
- case BSC_pread_extended:
- if ((ti = find_thread(thread, BSC_pread)) == (struct th_info *)0)
- return;
- ti->arg1 = kd->arg1; /* the fd */
- ti->arg2 = kd->arg2; /* nbytes */
- ti->arg3 = kd->arg3; /* top half offset */
- ti->arg4 = kd->arg4; /* bottom half offset */
- break;
- case BSC_pwrite_extended:
- if ((ti = find_thread(thread, BSC_pwrite)) == (struct th_info *)0)
- return;
- ti->arg1 = kd->arg1; /* the fd */
- ti->arg2 = kd->arg2; /* nbytes */
- ti->arg3 = kd->arg3; /* top half offset */
- ti->arg4 = kd->arg4; /* bottom half offset */
- break;
- default:
- return;
- }
+ hashid = blockno & VN_HASH_MASK;
+
+ for (mi = m_info_hash[hashid]; mi; mi = mi->m_next) {
+ if (mi->m_blkno == blockno)
+ return (mi->m_nameptr);
+ }
+ return ("");
+}
+
+
+char *
+add_vnode_name(uint64_t vn_id, char *pathname) {
+ vnode_info_t vn;
+ int hashid;
+
+ hashid = (vn_id >> VN_HASH_SHIFT) & VN_HASH_MASK;
+
+ for (vn = vn_info_hash[hashid]; vn; vn = vn->vn_next) {
+ if (vn->vn_id == vn_id)
+ break;
+ }
+ if (vn == NULL) {
+ vn = (vnode_info_t)malloc(sizeof(struct vnode_info));
+
+ vn->vn_next = vn_info_hash[hashid];
+ vn_info_hash[hashid] = vn;
+ vn->vn_id = vn_id;
+ }
+ strcpy(vn->vn_pathname, pathname);
+
+ return (&vn->vn_pathname);
+}
+
+
+char *
+find_vnode_name(uint64_t vn_id) {
+ vnode_info_t vn;
+ int hashid;
+
+ hashid = (vn_id >> VN_HASH_SHIFT) & VN_HASH_MASK;
+
+ for (vn = vn_info_hash[hashid]; vn; vn = vn->vn_next) {
+ if (vn->vn_id == vn_id)
+ return (vn->vn_pathname);
+ }
+ return ("");
}
+
void
-exit_syscall(char *sc_name, int thread, int type, int error, int retval,
- int has_fd, int has_ret, double now)
-{
- struct th_info *ti;
-
- if ((ti = find_thread(thread, type)) == (struct th_info *)0)
- return;
+delete_event(th_info_t ti_to_delete) {
+ th_info_t ti;
+ th_info_t ti_prev;
+ int hashid;
+
+ hashid = ti_to_delete->thread & HASH_MASK;
+
+ if ((ti = th_info_hash[hashid])) {
+ if (ti == ti_to_delete)
+ th_info_hash[hashid] = ti->next;
+ else {
+ ti_prev = ti;
+
+ for (ti = ti->next; ti; ti = ti->next) {
+ if (ti == ti_to_delete) {
+ ti_prev->next = ti->next;
+ break;
+ }
+ ti_prev = ti;
+ }
+ }
+ if (ti) {
+ ti->next = th_info_freelist;
+ th_info_freelist = ti;
+ }
+ }
+}
+
+th_info_t
+add_event(uintptr_t thread, int type) {
+ th_info_t ti;
+ int i;
+ int hashid;
+
+ if ((ti = th_info_freelist))
+ th_info_freelist = ti->next;
+ else
+ ti = (th_info_t)malloc(sizeof(struct th_info));
+
+ hashid = thread & HASH_MASK;
+
+ ti->next = th_info_hash[hashid];
+ th_info_hash[hashid] = ti;
+
+ ti->thread = thread;
+ ti->type = type;
- if (check_filter_mode(ti, type, error, retval))
- format_print(ti, sc_name, thread, type, error, retval, has_fd, has_ret, now, ti->stime, ti->waited, ti->pathname, NULL);
+ ti->waited = 0;
+ ti->in_filemgr = 0;
+ ti->in_hfs_update = 0;
- if (ti == &th_state[cur_max - 1])
- cur_max--;
- ti->thread = 0;
+ ti->pathptr = &ti->lookups[0].pathname[0];
+ ti->pn_scall_index = 0;
+ ti->pn_work_index = 0;
+
+ for (i = 0; i < MAX_PATHNAMES; i++)
+ ti->lookups[i].pathname[0] = 0;
+
+ return (ti);
}
+th_info_t
+find_event(uintptr_t thread, int type) {
+ th_info_t ti;
+ int hashid;
+ hashid = thread & HASH_MASK;
+
+ for (ti = th_info_hash[hashid]; ti; ti = ti->next) {
+ if (ti->thread == thread) {
+ if (type == ti->type)
+ return (ti);
+ if (ti->in_filemgr) {
+ if (type == -1)
+ return (ti);
+ continue;
+ }
+ if (type == 0)
+ return (ti);
+ }
+ }
+ return ((th_info_t) 0);
+}
void
-format_print(struct th_info *ti, char *sc_name, int thread, int type, int error, int retval,
- int has_fd, int has_ret, double now, double stime, int waited, char *pathname, struct diskio *dio)
-{
- int secs;
- int usecs;
- int nopadding;
- long long l_usecs;
- long curr_time;
- char *command_name;
- kd_threadmap *map;
- kd_threadmap *find_thread_map();
- int len = 0;
- int clen = 0;
- char *framework_name;
- char buf[MAXCOLS];
-
- command_name = "";
-
- if (dio)
- command_name = dio->issuing_command;
- else {
- if ((map = find_thread_map(thread)))
- command_name = map->command;
- }
-
- l_usecs = (long long)(now / divisor);
- secs = l_usecs / 1000000;
- curr_time = bias_secs + secs;
- sprintf(buf, "%-8.8s", &(ctime(&curr_time)[11]));
- clen = strlen(buf);
-
- if (columns > MAXCOLS || wideflag) {
- nopadding = 0;
- usecs = l_usecs - (long long)((long long)secs * 1000000);
- sprintf(&buf[clen], ".%03ld", (long)usecs / 1000);
- clen = strlen(buf);
-
- if ((type >> 24) != FILEMGR_CLASS) {
- if (find_thread(thread, -1)) {
- sprintf(&buf[clen], " ");
- clen = strlen(buf);
- nopadding = 1;
- }
- }
- } else
- nopadding = 1;
+delete_all_events() {
+ th_info_t ti = 0;
+ th_info_t ti_next = 0;
+ int i;
+
+ for (i = 0; i < HASH_SIZE; i++) {
+
+ for (ti = th_info_hash[i]; ti; ti = ti_next) {
+ ti_next = ti->next;
+ ti->next = th_info_freelist;
+ th_info_freelist = ti;
+ }
+ th_info_hash[i] = 0;
+ }
+}
- if (((type >> 24) == FILEMGR_CLASS) && (columns > MAXCOLS || wideflag))
- sprintf(&buf[clen], " %-18.18s", sc_name);
- else
- sprintf(&buf[clen], " %-15.15s", sc_name);
- clen = strlen(buf);
-
- framework_name = (char *)0;
-
- if (columns > MAXCOLS || wideflag) {
- if (has_ret == 7) {
- sprintf(&buf[clen], " D=0x%8.8x", dio->blkno);
-
- clen = strlen(buf);
-
- if (dio->io_errno)
- sprintf(&buf[clen], " [%3d] ", dio->io_errno);
- else
- sprintf(&buf[clen], " B=0x%-6x /dev/%s", dio->iosize, find_disk_name(dio->dev));
- } else {
-
- off_t offset_reassembled = 0LL;
-
- if (has_fd == 2 && error == 0)
- sprintf(&buf[clen], " F=%-3d", retval);
- else if (has_fd == 1)
- sprintf(&buf[clen], " F=%-3d", ti->arg1);
- else if (has_ret != 2 && has_ret != 6)
- sprintf(&buf[clen], " ");
-
- clen = strlen(buf);
-
- if (has_ret == 2 || has_ret == 6)
- framework_name = lookup_name(retval);
-
- if (error && has_ret != 6)
- sprintf(&buf[clen], "[%3d] ", error);
- else if (has_ret == 3)
- sprintf(&buf[clen], "O=0x%8.8x", ti->arg3);
- else if (has_ret == 5)
- sprintf(&buf[clen], "O=0x%8.8x", retval);
- else if (has_ret == 2)
- sprintf(&buf[clen], " A=0x%8.8x ", retval);
- else if (has_ret == 6)
- sprintf(&buf[clen], " A=0x%8.8x B=0x%-8x", retval, error);
- else if (has_ret == 1)
- sprintf(&buf[clen], " B=0x%-6x", retval);
- else if (has_ret == 4)
- sprintf(&buf[clen], "B=0x%-8x", retval);
- else if (has_ret == 8) /* BSC_select */
- sprintf(&buf[clen], " S=%-3d ", retval);
- else if (has_ret == 9) /* BSC_pread, BSC_pwrite */
- {
- sprintf(&buf[clen], "B=0x%-8x", retval);
- clen = strlen(buf);
- offset_reassembled = (((off_t)(unsigned int)(ti->arg3)) << 32) | (unsigned int)(ti->arg4);
- if ((offset_reassembled >> 32) != 0)
- sprintf(&buf[clen], "O=0x%16.16qx", (off_t)offset_reassembled);
- else
- sprintf(&buf[clen], "O=0x%8.8qx", (off_t)offset_reassembled);
- }
- else
- sprintf(&buf[clen], " ");
- }
- clen = strlen(buf);
- }
- printf(buf);
-
- /*
- Calculate space available to print pathname
- */
- if (columns > MAXCOLS || wideflag)
- clen = columns - (clen + 13 + 20);
- else
- clen = columns - (clen + 13 + 12);
-
- if ((type >> 24) != FILEMGR_CLASS && !nopadding)
- clen -= 3;
-
- if (framework_name)
- sprintf(&buf[0], " %s ", framework_name);
- else
- sprintf(&buf[0], " %s ", pathname);
- len = strlen(buf);
-
- if (clen > len)
- {
- /*
- Add null padding if column length
- is wider than the pathname length.
- */
- memset(&buf[len], ' ', clen - len);
- buf[clen] = '\0';
- printf(buf);
- }
- else if (clen == len)
- {
- printf(buf);
- }
- else if ((clen > 0) && (clen < len))
- {
- /* This prints the tail end of the pathname */
- buf[len-clen] = ' ';
- printf(&buf[len - clen]);
- }
-
- usecs = (unsigned long)((now - stime) / divisor);
- secs = usecs / 1000000;
- usecs -= secs * 1000000;
-
- if ((type >> 24) != FILEMGR_CLASS && !nopadding)
- printf(" ");
-
- printf(" %2ld.%06ld", (unsigned long)secs, (unsigned long)usecs);
-
- if (waited)
- printf(" W");
- else
- printf(" ");
-
- if (columns > MAXCOLS || wideflag)
- printf(" %-20.20s", command_name);
- else
- printf(" %-12.12s", command_name);
-
- printf("\n");
- fflush (0);
+void
+mark_thread_waited(uintptr_t thread) {
+ th_info_t ti;
+ int hashid;
+
+ hashid = thread & HASH_MASK;
+
+ for (ti = th_info_hash[hashid]; ti; ti = ti->next) {
+ if (ti->thread == thread)
+ ti->waited = 1;
+ }
}
-int
-quit(s)
-char *s;
+
+void read_command_map()
{
- if (trace_enabled)
- set_enable(0);
+ size_t size;
+ int i;
+ int total_threads = 0;
+ kd_threadmap *mapptr = 0;
+
+ delete_all_map_entries();
+
+ if (!RAW_flag) {
+
+ total_threads = bufinfo.nkdthreads;
+ size = bufinfo.nkdthreads * sizeof(kd_threadmap);
+
+ if (size) {
+ if ((mapptr = (kd_threadmap *) malloc(size))) {
+ int mib[6];
+
+ bzero (mapptr, size);
+ /*
+ * Now read the threadmap
+ */
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_KDEBUG;
+ mib[2] = KERN_KDTHRMAP;
+ mib[3] = 0;
+ mib[4] = 0;
+ mib[5] = 0; /* no flags */
+
+ if (sysctl(mib, 3, mapptr, &size, NULL, 0) < 0) {
+ /*
+ * This is not fatal -- just means I cant map command strings
+ */
+ free(mapptr);
+ return;
+ }
+ }
+ }
+ } else {
+ RAW_header header;
+ off_t offset;
- /*
- This flag is turned off when calling
- quit() due to a set_remove() failure.
- */
- if (set_remove_flag)
- set_remove();
+ RAW_fd = open(RAW_file, O_RDONLY);
- printf("fs_usage: ");
- if (s)
- printf("%s", s);
+ if (RAW_fd < 0) {
+ perror("Can't open RAW file");
+ exit(1);
+ }
+ if (read(RAW_fd, &header, sizeof(RAW_header)) != sizeof(RAW_header)) {
+ perror("read failed");
+ exit(2);
+ }
+ if (header.version_no != RAW_VERSION1) {
+ header.version_no = RAW_VERSION0;
+ header.TOD_secs = time((long *)0);
+ header.TOD_usecs = 0;
- exit(1);
+ lseek(RAW_fd, (off_t)0, SEEK_SET);
+
+ if (read(RAW_fd, &header.thread_count, sizeof(int)) != sizeof(int)) {
+ perror("read failed");
+ exit(2);
+ }
+ }
+ sample_TOD_secs = header.TOD_secs;
+ sample_TOD_usecs = header.TOD_usecs;
+
+ total_threads = header.thread_count;
+ size = total_threads * sizeof(kd_threadmap);
+
+ if (size) {
+ if ((mapptr = (kd_threadmap *) malloc(size))) {
+ bzero (mapptr, size);
+
+ if (read(RAW_fd, mapptr, size) != size) {
+ free(mapptr);
+ return;
+ }
+ }
+ }
+ if (header.version_no != RAW_VERSION0) {
+ offset = lseek(RAW_fd, (off_t)0, SEEK_CUR);
+ offset = (offset + (4095)) & ~4095;
+
+ lseek(RAW_fd, offset, SEEK_SET);
+ }
+ }
+ for (i = 0; i < total_threads; i++)
+ create_map_entry(mapptr[i].thread, mapptr[i].valid, &mapptr[i].command[0]);
+
+ free(mapptr);
}
-void getdivisor()
+void delete_all_map_entries()
{
+ threadmap_t tme = 0;
+ threadmap_t tme_next = 0;
+ int i;
+
+ for (i = 0; i < HASH_SIZE; i++) {
+
+ for (tme = threadmap_hash[i]; tme; tme = tme_next) {
+ if (tme->tm_setptr)
+ free(tme->tm_setptr);
+ tme_next = tme->tm_next;
+ tme->tm_next = threadmap_freelist;
+ threadmap_freelist = tme;
+ }
+ threadmap_hash[i] = 0;
+ }
+}
+
+
+void create_map_entry(uintptr_t thread, int pid, char *command)
+{
+ threadmap_t tme;
+ int hashid;
+
+ if ((tme = threadmap_freelist))
+ threadmap_freelist = tme->tm_next;
+ else
+ tme = (threadmap_t)malloc(sizeof(struct threadmap));
- unsigned int delta;
- unsigned int abs_to_ns_num;
- unsigned int abs_to_ns_denom;
- unsigned int proc_to_abs_num;
- unsigned int proc_to_abs_denom;
+ tme->tm_thread = thread;
+ tme->tm_setsize = 0;
+ tme->tm_setptr = 0;
- extern void MKGetTimeBaseInfo(unsigned int *, unsigned int *, unsigned int *, unsigned int *, unsigned int *);
+ (void)strncpy (tme->tm_command, command, MAXCOMLEN);
+ tme->tm_command[MAXCOMLEN] = '\0';
- MKGetTimeBaseInfo (&delta, &abs_to_ns_num, &abs_to_ns_denom,
- &proc_to_abs_num, &proc_to_abs_denom);
+ hashid = thread & HASH_MASK;
- divisor = ((double)abs_to_ns_denom / (double)abs_to_ns_num) * 1000;
+ tme->tm_next = threadmap_hash[hashid];
+ threadmap_hash[hashid] = tme;
+
+ if (pid != 0 && pid != 1) {
+ if (!strncmp(command, "LaunchCFMA", 10))
+ (void)get_real_command_name(pid, tme->tm_command, MAXCOMLEN);
+ }
}
-void read_command_map()
+threadmap_t
+find_map_entry(uintptr_t thread)
{
- size_t size;
- int i;
- int prev_total_threads;
- int mib[6];
-
- if (mapptr) {
- free(mapptr);
- mapptr = 0;
- }
-
- prev_total_threads = total_threads;
- total_threads = bufinfo.nkdthreads;
- size = bufinfo.nkdthreads * sizeof(kd_threadmap);
-
- if (size)
- {
- if ((mapptr = (kd_threadmap *) malloc(size)))
- {
- bzero (mapptr, size);
-
- /* Now read the threadmap */
- mib[0] = CTL_KERN;
- mib[1] = KERN_KDEBUG;
- mib[2] = KERN_KDTHRMAP;
- mib[3] = 0;
- mib[4] = 0;
- mib[5] = 0; /* no flags */
- if (sysctl(mib, 3, mapptr, &size, NULL, 0) < 0)
- {
- /* This is not fatal -- just means I cant map command strings */
- free(mapptr);
- mapptr = 0;
- }
- }
- }
-
- if (mapptr && (filter_mode != DEFAULT_DO_NOT_FILTER))
- {
- if (fdmapptr)
- {
- /* We accept the fact that we lose file descriptor state if the
- kd_buffer wraps */
- for (i = 0; i < prev_total_threads; i++)
- {
- if (fdmapptr[i].fd_setptr)
- free (fdmapptr[i].fd_setptr);
- }
- free(fdmapptr);
- fdmapptr = 0;
- }
-
- size = total_threads * sizeof(fd_threadmap);
- if ((fdmapptr = (fd_threadmap *) malloc(size)))
- {
- bzero (fdmapptr, size);
- /* reinitialize file descriptor state map */
- for (i = 0; i < total_threads; i++)
- {
- fdmapptr[i].fd_thread = mapptr[i].thread;
- fdmapptr[i].fd_valid = mapptr[i].valid;
- fdmapptr[i].fd_setsize = 0;
- fdmapptr[i].fd_setptr = 0;
- }
- }
- }
+ threadmap_t tme;
+ int hashid;
- /* Resolve any LaunchCFMApp command names */
- if (mapptr && arguments)
- {
- for (i=0; i < total_threads; i++)
- {
- int pid;
+ hashid = thread & HASH_MASK;
- pid = mapptr[i].valid;
-
- if (pid == 0 || pid == 1)
- continue;
- else if (!strncmp(mapptr[i].command,"LaunchCFMA", 10))
- {
- (void)get_real_command_name(pid, mapptr[i].command, sizeof(mapptr[i].command));
- }
+ for (tme = threadmap_hash[hashid]; tme; tme = tme->tm_next) {
+ if (tme->tm_thread == thread)
+ return (tme);
}
- }
+ return (0);
}
-void create_map_entry(int thread, int pid, char *command)
+void
+delete_map_entry(uintptr_t thread)
{
- int i, n;
- kd_threadmap *map;
- fd_threadmap *fdmap = 0;
-
- if (!mapptr)
- return;
-
- for (i = 0, map = 0; !map && i < total_threads; i++)
- {
- if ((int)mapptr[i].thread == thread )
- {
- map = &mapptr[i]; /* Reuse this entry, the thread has been
- * reassigned */
- if(filter_mode && fdmapptr)
- {
- fdmap = &fdmapptr[i];
- if (fdmap->fd_thread != thread) /* This shouldn't happen */
- fdmap = (fd_threadmap *)0;
- }
+ threadmap_t tme = 0;
+ threadmap_t tme_prev;
+ int hashid;
+
+ hashid = thread & HASH_MASK;
+
+ if ((tme = threadmap_hash[hashid])) {
+ if (tme->tm_thread == thread)
+ threadmap_hash[hashid] = tme->tm_next;
+ else {
+ tme_prev = tme;
+
+ for (tme = tme->tm_next; tme; tme = tme->tm_next) {
+ if (tme->tm_thread == thread) {
+ tme_prev->tm_next = tme->tm_next;
+ break;
+ }
+ tme_prev = tme;
+ }
+ }
+ if (tme) {
+ if (tme->tm_setptr)
+ free(tme->tm_setptr);
+
+ tme->tm_next = threadmap_freelist;
+ threadmap_freelist = tme;
+ }
}
- }
-
- if (!map) /* look for invalid entries that I can reuse*/
- {
- for (i = 0, map = 0; !map && i < total_threads; i++)
- {
- if (mapptr[i].valid == 0 )
- map = &mapptr[i]; /* Reuse this invalid entry */
- if (filter_mode && fdmapptr)
- {
- fdmap = &fdmapptr[i];
- }
+}
+
+
+void
+fs_usage_fd_set(uintptr_t thread, unsigned int fd)
+{
+ threadmap_t tme;
+
+ if ((tme = find_map_entry(thread)) == 0)
+ return;
+ /*
+ * If the map is not allocated, then now is the time
+ */
+ if (tme->tm_setptr == (unsigned long *)0) {
+ if ((tme->tm_setptr = (unsigned long *)malloc(FS_USAGE_NFDBYTES(FS_USAGE_FD_SETSIZE))) == 0)
+ return;
+
+ tme->tm_setsize = FS_USAGE_FD_SETSIZE;
+ bzero(tme->tm_setptr, (FS_USAGE_NFDBYTES(FS_USAGE_FD_SETSIZE)));
}
- }
-
- if (!map)
- {
- /* If reach here, then this is a new thread and
- * there are no invalid entries to reuse
- * Double the size of the thread map table.
+ /*
+ * If the map is not big enough, then reallocate it
*/
+ while (tme->tm_setsize <= fd) {
+ int n;
- n = total_threads * 2;
- mapptr = (kd_threadmap *) realloc(mapptr, n * sizeof(kd_threadmap));
- bzero(&mapptr[total_threads], total_threads*sizeof(kd_threadmap));
- map = &mapptr[total_threads];
+ n = tme->tm_setsize * 2;
+ tme->tm_setptr = (unsigned long *)realloc(tme->tm_setptr, (FS_USAGE_NFDBYTES(n)));
- if (filter_mode && fdmapptr)
- {
- fdmapptr = (fd_threadmap *)realloc(fdmapptr, n * sizeof(fd_threadmap));
- bzero(&fdmapptr[total_threads], total_threads*sizeof(fd_threadmap));
- fdmap = &fdmapptr[total_threads];
+ bzero(&tme->tm_setptr[(tme->tm_setsize/FS_USAGE_NFDBITS)], (FS_USAGE_NFDBYTES(tme->tm_setsize)));
+ tme->tm_setsize = n;
}
-
- total_threads = n;
- }
-
- map->valid = 1;
- map->thread = thread;
- /*
- The trace entry that returns the command name will hold
- at most, MAXCOMLEN chars, and in that case, is not
- guaranteed to be null terminated.
- */
- (void)strncpy (map->command, command, MAXCOMLEN);
- map->command[MAXCOMLEN] = '\0';
-
- if (fdmap)
- {
- fdmap->fd_valid = 1;
- fdmap->fd_thread = thread;
- if (fdmap->fd_setptr)
- {
- free(fdmap->fd_setptr);
- fdmap->fd_setptr = (unsigned long *)0;
- }
- fdmap->fd_setsize = 0;
- }
-
- if (pid == 0 || pid == 1)
- return;
- else if (!strncmp(map->command, "LaunchCFMA", 10))
- (void)get_real_command_name(pid, map->command, sizeof(map->command));
+ /*
+ * set the bit
+ */
+ tme->tm_setptr[fd/FS_USAGE_NFDBITS] |= (1 << ((fd) % FS_USAGE_NFDBITS));
}
-kd_threadmap *find_thread_map(int thread)
+/*
+ * Return values:
+ * 0 : File Descriptor bit is not set
+ * 1 : File Descriptor bit is set
+ */
+int
+fs_usage_fd_isset(uintptr_t thread, unsigned int fd)
{
- int i;
- kd_threadmap *map;
+ threadmap_t tme;
+ int ret = 0;
- if (!mapptr)
- return((kd_threadmap *)0);
-
- for (i = 0; i < total_threads; i++)
- {
- map = &mapptr[i];
- if (map->valid && ((int)map->thread == thread))
- {
- return(map);
+ if ((tme = find_map_entry(thread))) {
+ if (tme->tm_setptr && fd < tme->tm_setsize)
+ ret = tme->tm_setptr[fd/FS_USAGE_NFDBITS] & (1 << (fd % FS_USAGE_NFDBITS));
}
- }
- return ((kd_threadmap *)0);
+ return (ret);
}
+
-fd_threadmap *find_fd_thread_map(int thread)
+void
+fs_usage_fd_clear(uintptr_t thread, unsigned int fd)
{
- int i;
- fd_threadmap *fdmap = 0;
+ threadmap_t tme;
- if (!fdmapptr)
- return((fd_threadmap *)0);
-
- for (i = 0; i < total_threads; i++)
- {
- fdmap = &fdmapptr[i];
- if (fdmap->fd_valid && ((int)fdmap->fd_thread == thread))
- {
- return(fdmap);
+ if ((tme = find_map_entry(thread))) {
+ if (tme->tm_setptr && fd < tme->tm_setsize)
+ tme->tm_setptr[fd/FS_USAGE_NFDBITS] &= ~(1 << (fd % FS_USAGE_NFDBITS));
}
- }
- return ((fd_threadmap *)0);
}
-void
-kill_thread_map(int thread)
-{
- kd_threadmap *map;
- fd_threadmap *fdmap;
-
- if ((map = find_thread_map(thread))) {
- map->valid = 0;
- map->thread = 0;
- map->command[0] = '\0';
- }
-
- if (filter_mode)
- {
- if ((fdmap = find_fd_thread_map(thread)))
- {
- fdmap->fd_valid = 0;
- fdmap->fd_thread = 0;
- if (fdmap->fd_setptr)
- {
- free (fdmap->fd_setptr);
- fdmap->fd_setptr = (unsigned long *)0;
- }
- fdmap->fd_setsize = 0;
- }
- }
-}
void
-argtopid(str)
- char *str;
+argtopid(char *str)
{
char *cp;
int ret;
int i;
ret = (int)strtol(str, &cp, 10);
+
if (cp == str || *cp) {
- /* Assume this is a command string and find matching pids */
+ /*
+ * Assume this is a command string and find matching pids
+ */
if (!kp_buffer)
find_proc_names();
- for (i=0; i < kp_nentries && num_of_pids < (MAX_PIDS - 1); i++) {
- if(kp_buffer[i].kp_proc.p_stat == 0)
- continue;
- else {
- if(!strcmp(str, kp_buffer[i].kp_proc.p_comm))
- pids[num_of_pids++] = kp_buffer[i].kp_proc.p_pid;
- }
+ for (i = 0; i < kp_nentries && num_of_pids < (MAX_PIDS - 1); i++) {
+ if (kp_buffer[i].kp_proc.p_stat == 0)
+ continue;
+ else {
+ if (!strncmp(str, kp_buffer[i].kp_proc.p_comm,
+ sizeof(kp_buffer[i].kp_proc.p_comm) -1))
+ pids[num_of_pids++] = kp_buffer[i].kp_proc.p_pid;
+ }
}
}
else if (num_of_pids < (MAX_PIDS - 1))
pids[num_of_pids++] = ret;
-
- return;
}
-char *lookup_name(unsigned long addr)
+void
+lookup_name(uint64_t user_addr, char **type, char **name)
{
- register int i;
- register int start, last;
-
-
- if (numFrameworks == 0 || addr < frameworkInfo[0].address || addr > frameworkInfo[numFrameworks].address)
- return (0);
-
- start = 0;
- last = numFrameworks;
-
- for (i = numFrameworks / 2; i >= 0 && i < numFrameworks; ) {
-
- if (addr >= frameworkInfo[i].address && addr < frameworkInfo[i+1].address)
- return(frameworkInfo[i].name);
-
- if (addr >= frameworkInfo[i].address) {
- start = i;
- i = start + ((last - i) / 2);
- } else {
- last = i;
- i = start + ((i - start) / 2);
+ int i;
+ int start, last;
+
+ *name = NULL;
+ *type = NULL;
+
+ if (numFrameworks) {
+
+ if ((user_addr >= framework32.b_address && user_addr < framework32.e_address) ||
+ (user_addr >= framework64.b_address && user_addr < framework64.e_address)) {
+
+ start = 0;
+ last = numFrameworks;
+
+ for (i = numFrameworks / 2; start < last; i = start + ((last - start) / 2)) {
+ if (user_addr > frameworkInfo[i].e_address)
+ start = i+1;
+ else
+ last = i;
+ }
+ if (start < numFrameworks &&
+ user_addr >= frameworkInfo[start].b_address && user_addr < frameworkInfo[start].e_address) {
+ *type = frameworkType[frameworkInfo[start].r_type];
+ *name = frameworkInfo[start].name;
+ }
}
}
- return (0);
}
*/
static int compareFrameworkAddress(const void *aa, const void *bb)
{
- LibraryInfo *a = (LibraryInfo *)aa;
- LibraryInfo *b = (LibraryInfo *)bb;
-
- if (a->address < b->address) return -1;
- if (a->address == b->address) return 0;
- return 1;
-}
-
+ LibraryInfo *a = (LibraryInfo *)aa;
+ LibraryInfo *b = (LibraryInfo *)bb;
-int scanline(char *inputstring,char **argv)
-{
- int n = 0;
- char **ap = argv, *p, *val;
-
- for (p = inputstring; p != NULL; )
- {
- while ((val = strsep(&p, " \t")) != NULL && *val == '\0');
- *ap++ = val;
- n++;
- }
- *ap = 0;
- return n;
+ if (a->b_address < b->b_address) return -1;
+ if (a->b_address == b->b_address) return 0;
+ return 1;
}
-int ReadSegAddrTable()
+int scanline(char *inputstring, char **argv, int maxtokens)
{
- char buf[1024];
+ int n = 0;
+ char **ap = argv, *p, *val;
- FILE *fd;
- unsigned long frameworkAddress, frameworkDataAddress, previousFrameworkAddress;
- char frameworkName[256];
- char *tokens[64];
- int ntokens;
- char *substring,*ptr;
- int founddylib = 0;
+ for (p = inputstring; n < maxtokens && p != NULL; ) {
+ while ((val = strsep(&p, " \t")) != NULL && *val == '\0');
- bzero(buf, sizeof(buf));
- bzero(tokens, sizeof(tokens));
-
- numFrameworks = 0;
-
- if ((fd = fopen(seg_addr_table, "r")) == 0)
- {
- return 0;
- }
- fgets(buf, 1023, fd);
-
- if (*buf == '#')
- {
- founddylib = 0;
- frameworkName[0] = 0;
- previousFrameworkAddress = 0;
-
- while (fgets(buf, 1023, fd) && numFrameworks < (MAXINDEX - 2))
- {
- /*
- * Get rid of EOL
- */
- buf[strlen(buf)-1] = 0;
+ *ap++ = val;
+ n++;
+ }
+ *ap = 0;
- if (strncmp(buf, "# dyld:", 7) == 0) {
- /*
- * the next line in the file will contain info about dyld
- */
- founddylib = 1;
- continue;
- }
- /*
- * This is a split library line: parse it into 3 tokens
- */
- ntokens = scanline(buf, tokens);
+ return n;
+}
- if (ntokens < 3)
- continue;
- frameworkAddress = strtoul(tokens[0], 0, 16);
- frameworkDataAddress = strtoul(tokens[1], 0, 16);
+int ReadSharedCacheMap(const char *path, LibraryRange *lr, char *linkedit_name)
+{
+ uint64_t b_address, e_address;
+ char buf[1024];
+ char *fnp;
+ FILE *fd;
+ char frameworkName[256];
+ char *tokens[64];
+ int ntokens;
+ int type;
+ int linkedit_found = 0;
+ char *substring, *ptr;
+
+ bzero(buf, sizeof(buf));
+ bzero(tokens, sizeof(tokens));
+
+ lr->b_address = 0;
+ lr->e_address = 0;
+
+ if ((fd = fopen(path, "r")) == 0)
+ return 0;
+
+ while (fgets(buf, 1023, fd)) {
+ if (strncmp(buf, "mapping", 7))
+ break;
+ }
+ buf[strlen(buf)-1] = 0;
+
+ frameworkName[0] = 0;
- if (founddylib) {
- /*
- * dyld entry is of a different form from the std split library
- * it consists of a base address and a size instead of a code
- * and data base address
+ for (;;) {
+ /*
+ * Extract lib name from path name
*/
- frameworkInfo[numFrameworks].address = frameworkAddress;
- frameworkInfo[numFrameworks+1].address = frameworkAddress + frameworkDataAddress;
+ if ((substring = strrchr(buf, '.')))
+ {
+ /*
+ * There is a ".": name is whatever is between the "/" around the "."
+ */
+ while ( *substring != '/') /* find "/" before "." */
+ substring--;
+ substring++;
+
+ strncpy(frameworkName, substring, 256); /* copy path from "/" */
+ frameworkName[255] = 0;
+ substring = frameworkName;
+
+ while ( *substring != '/' && *substring) /* find "/" after "." and stop string there */
+ substring++;
+ *substring = 0;
+ }
+ else
+ {
+ /*
+ * No ".": take segment after last "/"
+ */
+ ptr = buf;
+ substring = ptr;
+
+ while (*ptr) {
+ if (*ptr == '/')
+ substring = ptr + 1;
+ ptr++;
+ }
+ strncpy(frameworkName, substring, 256);
+ frameworkName[255] = 0;
+ }
+ fnp = (char *)malloc(strlen(frameworkName) + 1);
+ strcpy(fnp, frameworkName);
- frameworkInfo[numFrameworks].name = (char *)"dylib";
- frameworkInfo[numFrameworks+1].name = (char *)0;
+ while (fgets(buf, 1023, fd) && numFrameworks < (MAXINDEX - 2)) {
+ /*
+ * Get rid of EOL
+ */
+ buf[strlen(buf)-1] = 0;
- numFrameworks += 2;
- founddylib = 0;
+ ntokens = scanline(buf, tokens, 64);
- continue;
- }
+ if (ntokens < 4)
+ continue;
- /*
- * Make sure that we have 2 addresses and a path
- */
- if (!frameworkAddress)
- continue;
- if (!frameworkDataAddress)
- continue;
- if (*tokens[2] != '/')
- continue;
- if (frameworkAddress == previousFrameworkAddress)
- continue;
- previousFrameworkAddress = frameworkAddress;
-
- /*
- * Extract lib name from path name
- */
- if ((substring = strrchr(tokens[2], '.')))
- {
- /*
- * There is a ".": name is whatever is between the "/" around the "."
- */
- while ( *substring != '/') { /* find "/" before "." */
- substring--;
- }
- substring++;
- strcpy(frameworkName, substring); /* copy path from "/" */
- substring = frameworkName;
+ if (strncmp(tokens[0], "__TEXT", 6) == 0)
+ type = TEXT_R;
+ else if (strncmp(tokens[0], "__DATA", 6) == 0)
+ type = DATA_R;
+ else if (strncmp(tokens[0], "__OBJC", 6) == 0)
+ type = OBJC_R;
+ else if (strncmp(tokens[0], "__IMPORT", 8) == 0)
+ type = IMPORT_R;
+ else if (strncmp(tokens[0], "__UNICODE", 9) == 0)
+ type = UNICODE_R;
+ else if (strncmp(tokens[0], "__IMAGE", 7) == 0)
+ type = IMAGE_R;
+ else if (strncmp(tokens[0], "__LINKEDIT", 10) == 0)
+ type = LINKEDIT_R;
+ else
+ type = -1;
+
+ if (type == LINKEDIT_R && linkedit_found)
+ break;
+
+ if (type != -1) {
+ b_address = strtoull(tokens[1], 0, 16);
+ e_address = strtoull(tokens[3], 0, 16);
+
+ frameworkInfo[numFrameworks].b_address = b_address;
+ frameworkInfo[numFrameworks].e_address = e_address;
+ frameworkInfo[numFrameworks].r_type = type;
+
+ if (type == LINKEDIT_R) {
+ frameworkInfo[numFrameworks].name = linkedit_name;
+ linkedit_found = 1;
+ } else
+ frameworkInfo[numFrameworks].name = fnp;
+#if 0
+ printf("%s(%d): %qx-%qx\n", frameworkInfo[numFrameworks].name, type, b_address, e_address);
+#endif
+ if (lr->b_address == 0 || b_address < lr->b_address)
+ lr->b_address = b_address;
- while ( *substring != '/' && *substring) /* find "/" after "." and stop string there */
- substring++;
- *substring = 0;
- }
- else
- {
- /*
- * No ".": take segment after last "/"
- */
- ptr = tokens[2];
- substring = ptr;
+ if (lr->e_address == 0 || e_address > lr->e_address)
+ lr->e_address = e_address;
- while (*ptr)
- {
- if (*ptr == '/')
- substring = ptr + 1;
- ptr++;
+ numFrameworks++;
+ }
+ if (type == LINKEDIT_R)
+ break;
}
- strcpy(frameworkName, substring);
- }
- frameworkInfo[numFrameworks].address = frameworkAddress;
- frameworkInfo[numFrameworks+1].address = frameworkDataAddress;
+ if (fgets(buf, 1023, fd) == 0)
+ break;
- frameworkInfo[numFrameworks].name = (char *)malloc(strlen(frameworkName) + 1);
- strcpy(frameworkInfo[numFrameworks].name, frameworkName);
- frameworkInfo[numFrameworks+1].name = frameworkInfo[numFrameworks].name;
+ buf[strlen(buf)-1] = 0;
+ }
+ fclose(fd);
+
+#if 0
+ printf("%s range, %qx-%qx\n", path, lr->b_address, lr->e_address);
+#endif
+ return 1;
+}
- numFrameworks += 2;
- }
- }
- frameworkInfo[numFrameworks].address = frameworkInfo[numFrameworks - 1].address + 0x800000;
- frameworkInfo[numFrameworks].name = (char *)0;
- fclose(fd);
+void
+SortFrameworkAddresses()
+{
- qsort(frameworkInfo, numFrameworks, sizeof(LibraryInfo), compareFrameworkAddress);
+ frameworkInfo[numFrameworks].b_address = frameworkInfo[numFrameworks - 1].b_address + 0x800000;
+ frameworkInfo[numFrameworks].e_address = frameworkInfo[numFrameworks].b_address;
+ frameworkInfo[numFrameworks].name = (char *)0;
- return 1;
+ qsort(frameworkInfo, numFrameworks, sizeof(LibraryInfo), compareFrameworkAddress);
}
-struct diskio *insert_diskio(int type, int bp, int dev, int blkno, int io_size, int thread, double curtime)
+struct diskio *insert_diskio(int type, int bp, int dev, int blkno, int io_size, uintptr_t thread, double curtime)
{
- register struct diskio *dio;
- register kd_threadmap *map;
+ struct diskio *dio;
+ threadmap_t tme;
- if ((dio = free_diskios))
- free_diskios = dio->next;
- else {
- if ((dio = (struct diskio *)malloc(sizeof(struct diskio))) == NULL)
- return (NULL);
- }
- dio->prev = NULL;
-
- dio->type = type;
- dio->bp = bp;
- dio->dev = dev;
- dio->blkno = blkno;
- dio->iosize = io_size;
- dio->issued_time = curtime;
- dio->issuing_thread = thread;
+ if ((dio = free_diskios))
+ free_diskios = dio->next;
+ else {
+ if ((dio = (struct diskio *)malloc(sizeof(struct diskio))) == NULL)
+ return (NULL);
+ }
+ dio->prev = NULL;
- if ((map = find_thread_map(thread)))
- {
- strncpy(dio->issuing_command, map->command, MAXCOMLEN);
- dio->issuing_command[MAXCOMLEN-1] = '\0';
- }
- else
- strcpy(dio->issuing_command, "");
+ dio->type = type;
+ dio->bp = bp;
+ dio->dev = dev;
+ dio->blkno = blkno;
+ dio->iosize = io_size;
+ dio->issued_time = curtime;
+ dio->issuing_thread = thread;
+
+ dio->bc_info = 0x0;
+
+ if ((tme = find_map_entry(thread))) {
+ strncpy(dio->issuing_command, tme->tm_command, MAXCOMLEN);
+ dio->issuing_command[MAXCOMLEN-1] = '\0';
+ } else
+ strcpy(dio->issuing_command, "");
- dio->next = busy_diskios;
- if (dio->next)
- dio->next->prev = dio;
- busy_diskios = dio;
+ dio->next = busy_diskios;
+ if (dio->next)
+ dio->next->prev = dio;
+ busy_diskios = dio;
+
+ return (dio);
+}
- return (dio);
+struct diskio *find_diskio(int bp) {
+ struct diskio *dio;
+
+ for (dio = busy_diskios; dio; dio = dio->next) {
+ if (dio->bp == bp)
+ return (dio);
+ }
+
+ return NULL;
}
-struct diskio *complete_diskio(int bp, int io_errno, int resid, int thread, double curtime)
+struct diskio *complete_diskio(int bp, int io_errno, int resid, uintptr_t thread, double curtime)
{
- register struct diskio *dio;
-
- for (dio = busy_diskios; dio; dio = dio->next) {
- if (dio->bp == bp) {
-
- if (dio == busy_diskios) {
- if ((busy_diskios = dio->next))
- dio->next->prev = NULL;
- } else {
- if (dio->next)
- dio->next->prev = dio->prev;
- dio->prev->next = dio->next;
- }
- dio->iosize -= resid;
- dio->io_errno = io_errno;
- dio->completed_time = curtime;
- dio->completion_thread = thread;
-
- return (dio);
- }
- }
- return ((struct diskio *)0);
+ struct diskio *dio;
+
+ if ((dio = find_diskio(bp)) == NULL) return NULL;
+
+ if (dio == busy_diskios) {
+ if ((busy_diskios = dio->next))
+ dio->next->prev = NULL;
+ } else {
+ if (dio->next)
+ dio->next->prev = dio->prev;
+ dio->prev->next = dio->next;
+ }
+
+ dio->iosize -= resid;
+ dio->io_errno = io_errno;
+ dio->completed_time = curtime;
+ dio->completion_thread = thread;
+
+ return dio;
}
void free_diskio(struct diskio *dio)
{
- dio->next = free_diskios;
- free_diskios = dio;
+ dio->next = free_diskios;
+ free_diskios = dio;
}
void print_diskio(struct diskio *dio)
{
- register char *p;
-
- switch (dio->type) {
-
- case P_RdMeta:
- p = " RdMeta";
- break;
- case P_WrMeta:
- p = " WrMeta";
- break;
- case P_RdData:
- p = " RdData";
- break;
- case P_WrData:
- p = " WrData";
- break;
- case P_PgIn:
- p = " PgIn";
- break;
- case P_PgOut:
- p = " PgOut";
- break;
- case P_RdMetaAsync:
- p = " RdMeta[async]";
- break;
- case P_WrMetaAsync:
- p = " WrMeta[async]";
- break;
- case P_RdDataAsync:
- p = " RdData[async]";
- break;
- case P_WrDataAsync:
- p = " WrData[async]";
- break;
- case P_PgInAsync:
- p = " PgIn[async]";
- break;
- case P_PgOutAsync:
- p = " PgOut[async]";
- break;
- default:
- p = " ";
- break;
- }
- if (check_filter_mode(NULL, dio->type,0, 0))
- format_print(NULL, p, dio->issuing_thread, dio->type, 0, 0, 0, 7, dio->completed_time, dio->issued_time, 1, "", dio);
+ char *p = NULL;
+ int len = 0;
+ int type;
+ int format = FMT_DISKIO;
+ char buf[64];
+
+ type = dio->type;
+ dio->is_meta = 0;
+
+ if ((type & P_CS_Class) == P_CS_Class) {
+
+ switch (type) {
+
+ case P_CS_ReadChunk:
+ p = " RdChunkCS";
+ len = 13;
+ format = FMT_DISKIO_CS;
+ break;
+ case P_CS_WriteChunk:
+ p = " WrChunkCS";
+ len = 13;
+ format = FMT_DISKIO_CS;
+ break;
+ case P_CS_MetaRead:
+ p = " RdMetaCS";
+ len = 10;
+ format = FMT_DISKIO_CS;
+ break;
+ case P_CS_MetaWrite:
+ p = " WrMetaCS";
+ len = 10;
+ format = FMT_DISKIO_CS;
+ break;
+ case P_CS_TransformRead:
+ p = " RdBgTfCS";
+ len = 10;
+ break;
+ case P_CS_TransformWrite:
+ p = " WrBgTfCS";
+ len = 10;
+ break;
+ case P_CS_MigrationRead:
+ p = " RdBgMigrCS";
+ len = 12;
+ break;
+ case P_CS_MigrationWrite:
+ p = " WrBgMigrCS";
+ len = 12;
+ break;
+ }
+ strncpy(buf, p, len);
+ } else {
+
+ switch (type & P_DISKIO_TYPE) {
+
+ case P_RdMeta:
+ dio->is_meta = 1;
+ p = " RdMeta";
+ len = 8;
+ break;
+ case P_WrMeta:
+ dio->is_meta = 1;
+ p = " WrMeta";
+ len = 8;
+ break;
+ case P_RdData:
+ p = " RdData";
+ len = 8;
+ break;
+ case P_WrData:
+ p = " WrData";
+ len = 8;
+ break;
+ case P_PgIn:
+ p = " PgIn";
+ len = 6;
+ break;
+ case P_PgOut:
+ p = " PgOut";
+ len = 7;
+ break;
+ default:
+ p = " ";
+ len = 2;
+ break;
+ }
+ strncpy(buf, p, len);
+
+ buf[len++] = '[';
+
+ if (type & P_DISKIO_ASYNC)
+ buf[len++] = 'A';
+ else
+ buf[len++] = 'S';
+
+ if (type & P_DISKIO_NOCACHE)
+ buf[len++] = 'N';
+
+ int tier = (type & P_DISKIO_TIER_MASK) >> P_DISKIO_TIER_SHIFT;
+ if (tier > 0) {
+ buf[len++] = 'T';
+ if (tier > 0 && tier < 10)
+ buf[len++] = '0' + tier;
+ }
+
+ if (type & P_DISKIO_PASSIVE)
+ buf[len++] = 'P';
+
+
+ buf[len++] = ']';
+ }
+ buf[len] = 0;
+
+ if (check_filter_mode(NULL, type, 0, 0, buf))
+ format_print(NULL, buf, dio->issuing_thread, type, 0, 0, 0, 0, format, dio->completed_time, dio->issued_time, 1, "", dio);
}
void cache_disk_names()
{
- struct stat st;
- DIR *dirp = NULL;
- struct dirent *dir;
- struct diskrec *dnp;
+ struct stat st;
+ DIR *dirp = NULL;
+ struct dirent *dir;
+ struct diskrec *dnp;
- if ((dirp = opendir("/dev")) == NULL)
- return;
+ if ((dirp = opendir("/dev")) == NULL)
+ return;
- while ((dir = readdir(dirp)) != NULL) {
- char nbuf[MAXPATHLEN];
+ while ((dir = readdir(dirp)) != NULL) {
+ char nbuf[MAXPATHLEN];
- if (dir->d_namlen < 5 || strncmp("disk", dir->d_name, 4))
- continue;
- sprintf(nbuf, "%s/%s", "/dev", dir->d_name);
+ if (dir->d_namlen < 5 || strncmp("disk", dir->d_name, 4))
+ continue;
+
+ snprintf(nbuf, MAXPATHLEN, "%s/%s", "/dev", dir->d_name);
- if (stat(nbuf, &st) < 0)
- continue;
+ if (stat(nbuf, &st) < 0)
+ continue;
- if ((dnp = (struct diskrec *)malloc(sizeof(struct diskrec))) == NULL)
- continue;
+ if ((dnp = (struct diskrec *)malloc(sizeof(struct diskrec))) == NULL)
+ continue;
- if ((dnp->diskname = (char *)malloc(dir->d_namlen + 1)) == NULL) {
- free(dnp);
- continue;
- }
- strncpy(dnp->diskname, dir->d_name, dir->d_namlen);
- dnp->diskname[dir->d_namlen] = 0;
- dnp->dev = st.st_rdev;
+ if ((dnp->diskname = (char *)malloc(dir->d_namlen + 1)) == NULL) {
+ free(dnp);
+ continue;
+ }
+ strncpy(dnp->diskname, dir->d_name, dir->d_namlen);
+ dnp->diskname[dir->d_namlen] = 0;
+ dnp->dev = st.st_rdev;
- dnp->next = disk_list;
- disk_list = dnp;
- }
- (void) closedir(dirp);
+ dnp->next = disk_list;
+ disk_list = dnp;
+ }
+ (void) closedir(dirp);
}
-char *find_disk_name(int dev)
-{
- struct diskrec *dnp;
-
- if (dev == NFS_DEV)
- return ("NFS");
-
- for (dnp = disk_list; dnp; dnp = dnp->next) {
- if (dnp->dev == dev)
- return (dnp->diskname);
- }
- return ("NOTFOUND");
-}
-
-void
-fs_usage_fd_set(thread, fd)
- unsigned int thread;
- unsigned int fd;
+void recache_disk_names()
{
- int n;
- fd_threadmap *fdmap;
+ struct diskrec *dnp, *next_dnp;
- if(!(fdmap = find_fd_thread_map(thread)))
- return;
+ for (dnp = disk_list; dnp; dnp = next_dnp) {
+ next_dnp = dnp->next;
- /* If the map is not allocated, then now is the time */
- if (fdmap->fd_setptr == (unsigned long *)0)
- {
- fdmap->fd_setptr = (unsigned long *)malloc(FS_USAGE_NFDBYTES(FS_USAGE_FD_SETSIZE));
- if (fdmap->fd_setptr)
- {
- fdmap->fd_setsize = FS_USAGE_FD_SETSIZE;
- bzero(fdmap->fd_setptr,(FS_USAGE_NFDBYTES(FS_USAGE_FD_SETSIZE)));
+ free(dnp->diskname);
+ free(dnp);
}
- else
- return;
- }
-
- /* If the map is not big enough, then reallocate it */
- while (fdmap->fd_setsize < fd)
- {
- printf("reallocating bitmap for threadid %d, fd = %d, setsize = %d\n",
- thread, fd, fdmap->fd_setsize);
- n = fdmap->fd_setsize * 2;
- fdmap->fd_setptr = (unsigned long *)realloc(fdmap->fd_setptr, (FS_USAGE_NFDBYTES(n)));
- bzero(&fdmap->fd_setptr[(fdmap->fd_setsize/FS_USAGE_NFDBITS)], (FS_USAGE_NFDBYTES(fdmap->fd_setsize)));
- fdmap->fd_setsize = n;
- }
-
- /* set the bit */
- fdmap->fd_setptr[fd/FS_USAGE_NFDBITS] |= (1 << ((fd) % FS_USAGE_NFDBITS));
-
- return;
-}
-
-/*
- Return values:
- 0 : File Descriptor bit is not set
- 1 : File Descriptor bit is set
-*/
-
-int
-fs_usage_fd_isset(thread, fd)
- unsigned int thread;
- unsigned int fd;
-{
- int ret = 0;
- fd_threadmap *fdmap;
+ disk_list = NULL;
- if(!(fdmap = find_fd_thread_map(thread)))
- return(ret);
+ cache_disk_names();
+}
- if (fdmap->fd_setptr == (unsigned long *)0)
- return (ret);
- if (fd < fdmap->fd_setsize)
- ret = fdmap->fd_setptr[fd/FS_USAGE_NFDBITS] & (1 << (fd % FS_USAGE_NFDBITS));
+char *find_disk_name(int dev)
+{
+ struct diskrec *dnp;
+ int i;
- return (ret);
+ if (dev == NFS_DEV)
+ return ("NFS");
+
+ if (dev == CS_DEV)
+ return ("CS");
+
+ for (i = 0; i < 2; i++) {
+ for (dnp = disk_list; dnp; dnp = dnp->next) {
+ if (dnp->dev == dev)
+ return (dnp->diskname);
+ }
+ recache_disk_names();
+ }
+ return ("NOTFOUND");
}
-
-void
-fs_usage_fd_clear(thread, fd)
- unsigned int thread;
- unsigned int fd;
-{
- fd_threadmap *map;
- if (!(map = find_fd_thread_map(thread)))
- return;
- if (map->fd_setptr == (unsigned long *)0)
- return;
+char *generate_cs_disk_name(int dev, char *s)
+{
+ if (dev == -1)
+ return ("UNKNOWN");
+
+ sprintf(s, "disk%ds%d", (dev >> 16) & 0xffff, dev & 0xffff);
- /* clear the bit */
- if (fd < map->fd_setsize)
- map->fd_setptr[fd/FS_USAGE_NFDBITS] &= ~(1 << (fd % FS_USAGE_NFDBITS));
-
- return;
+ return (s);
}
+
/*
* ret = 1 means print the entry
* ret = 0 means don't print the entry
*/
+
+/*
+ * meaning of filter flags:
+ * cachehit turn on display of CACHE_HIT events (which are filtered out by default)
+ *
+ * exec show exec/posix_spawn
+ * pathname show events with a pathname and close()
+ * diskio show disk I/Os
+ * filesys show filesystem events
+ * network show network events
+ *
+ * filters may be combined; default is all filters on (except cachehit)
+ */
int
-check_filter_mode(struct th_info * ti, int type, int error, int retval)
+check_filter_mode(struct th_info *ti, int type, int error, int retval, char *sc_name)
{
- int ret = 0;
- int network_fd_isset = 0;
- unsigned int fd;
-
- if (filter_mode == DEFAULT_DO_NOT_FILTER)
- return(1);
+ int ret = 0;
+ int network_fd_isset = 0;
+ unsigned int fd;
+
+ /* cachehit is special -- it's not on by default */
+ if (sc_name[0] == 'C' && !strcmp(sc_name, "CACHE_HIT")) {
+ if (show_cachehits) return 1;
+ else return 0;
+ }
- if (ti == (struct th_info *)0)
- {
- if(filter_mode & FILESYS_FILTER)
- ret = 1;
- else
- ret = 0;
- return(ret);
- }
+ if (filter_mode == DEFAULT_DO_NOT_FILTER)
+ return(1);
-
- switch (type) {
- case BSC_close:
- fd = ti->arg1;
- network_fd_isset = fs_usage_fd_isset(ti->thread, fd);
- if (error == 0)
- {
- fs_usage_fd_clear(ti->thread,fd);
+ if (filter_mode & DISKIO_FILTER) {
+ if ((type & P_DISKIO_MASK) == P_DISKIO)
+ return 1;
}
- if (network_fd_isset)
- {
+ if (filter_mode & EXEC_FILTER) {
+ if (type == BSC_execve || type == BSC_posix_spawn)
+ return(1);
+ }
+
+ if (filter_mode & PATHNAME_FILTER) {
+ if (ti && ti->lookups[0].pathname[0])
+ return(1);
+ if (type == BSC_close || type == BSC_close_nocancel ||
+ type == BSC_guarded_close_np)
+ return(1);
+ }
+
+ if (ti == (struct th_info *)0) {
+ if (filter_mode & FILESYS_FILTER)
+ return(1);
+ return(0);
+ }
+
+ switch (type) {
+
+ case BSC_close:
+ case BSC_close_nocancel:
+ case BSC_guarded_close_np:
+ fd = ti->arg1;
+ network_fd_isset = fs_usage_fd_isset(ti->thread, fd);
+
+ if (error == 0)
+ fs_usage_fd_clear(ti->thread,fd);
+
+ if (network_fd_isset) {
+ if (filter_mode & NETWORK_FILTER)
+ ret = 1;
+ } else
+ if (filter_mode & FILESYS_FILTER)
+ ret = 1;
+ break;
+
+ case BSC_read:
+ case BSC_write:
+ case BSC_read_nocancel:
+ case BSC_write_nocancel:
+ /*
+ * we don't care about error in these cases
+ */
+ fd = ti->arg1;
+ network_fd_isset = fs_usage_fd_isset(ti->thread, fd);
+
+ if (network_fd_isset) {
+ if (filter_mode & NETWORK_FILTER)
+ ret = 1;
+ } else
+ if (filter_mode & FILESYS_FILTER)
+ ret = 1;
+ break;
+
+ case BSC_accept:
+ case BSC_accept_nocancel:
+ case BSC_socket:
+ fd = retval;
+
+ if (error == 0)
+ fs_usage_fd_set(ti->thread, fd);
+ if (filter_mode & NETWORK_FILTER)
+ ret = 1;
+ break;
+
+ case BSC_recvfrom:
+ case BSC_sendto:
+ case BSC_recvmsg:
+ case BSC_sendmsg:
+ case BSC_connect:
+ case BSC_bind:
+ case BSC_listen:
+ case BSC_sendto_nocancel:
+ case BSC_recvfrom_nocancel:
+ case BSC_recvmsg_nocancel:
+ case BSC_sendmsg_nocancel:
+ case BSC_connect_nocancel:
+ fd = ti->arg1;
+
+ if (error == 0)
+ fs_usage_fd_set(ti->thread, fd);
if (filter_mode & NETWORK_FILTER)
- ret = 1;
- }
- else if (filter_mode & FILESYS_FILTER)
- ret = 1;
- break;
- case BSC_read:
- case BSC_write:
- /* we don't care about error in this case */
- fd = ti->arg1;
- network_fd_isset = fs_usage_fd_isset(ti->thread, fd);
- if (network_fd_isset)
- {
+ ret = 1;
+ break;
+
+ case BSC_select:
+ case BSC_select_nocancel:
+ case BSC_socketpair:
+ /*
+ * Cannot determine info about file descriptors
+ */
if (filter_mode & NETWORK_FILTER)
- ret = 1;
- }
- else if (filter_mode & FILESYS_FILTER)
- ret = 1;
- break;
- case BSC_accept:
- case BSC_socket:
- fd = retval;
- if (error == 0)
- fs_usage_fd_set(ti->thread, fd);
- if (filter_mode & NETWORK_FILTER)
- ret = 1;
- break;
- case BSC_recvfrom:
- case BSC_sendto:
- case BSC_recvmsg:
- case BSC_sendmsg:
- case BSC_connect:
- case BSC_bind:
- case BSC_listen:
- fd = ti->arg1;
- if (error == 0)
- fs_usage_fd_set(ti->thread, fd);
- if (filter_mode & NETWORK_FILTER)
- ret = 1;
- break;
- case BSC_select:
- case BSC_socketpair:
- /* Cannot determine info about file descriptors */
- if (filter_mode & NETWORK_FILTER)
- ret = 1;
- break;
- case BSC_dup:
- case BSC_dup2:
- ret=0; /* We track these cases for fd state only */
- fd = ti->arg1; /* oldd */
- network_fd_isset = fs_usage_fd_isset(ti->thread, fd);
- if (error == 0 && network_fd_isset)
- {
- /* then we are duping a socket descriptor */
- fd = retval; /* the new fd */
- fs_usage_fd_set(ti->thread, fd);
- }
- break;
-
- default:
- if (filter_mode & FILESYS_FILTER)
- ret = 1;
- break;
- }
-
- return(ret);
+ ret = 1;
+ break;
+
+ case BSC_dup:
+ case BSC_dup2:
+ /*
+ * We track these cases for fd state only
+ */
+ fd = ti->arg1;
+ network_fd_isset = fs_usage_fd_isset(ti->thread, fd);
+
+ if (error == 0 && network_fd_isset) {
+ /*
+ * then we are duping a socket descriptor
+ */
+ fd = retval; /* the new fd */
+ fs_usage_fd_set(ti->thread, fd);
+ }
+ break;
+
+ default:
+ if (filter_mode & FILESYS_FILTER)
+ ret = 1;
+ break;
+ }
+
+ return(ret);
}
/*
void
init_arguments_buffer()
{
+ int mib[2];
+ size_t size;
- int mib[2];
- size_t size;
-
- mib[0] = CTL_KERN;
- mib[1] = KERN_ARGMAX;
- size = sizeof(argmax);
- if (sysctl(mib, 2, &argmax, &size, NULL, 0) == -1)
- return;
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_ARGMAX;
+ size = sizeof(argmax);
+ if (sysctl(mib, 2, &argmax, &size, NULL, 0) == -1)
+ return;
#if 1
- /* Hack to avoid kernel bug. */
- if (argmax > 8192) {
- argmax = 8192;
- }
+ /* Hack to avoid kernel bug. */
+ if (argmax > 8192) {
+ argmax = 8192;
+ }
#endif
-
- arguments = (char *)malloc(argmax);
-
- return;
+ arguments = (char *)malloc(argmax);
}
int
get_real_command_name(int pid, char *cbuf, int csize)
{
- /*
- * Get command and arguments.
- */
- char *cp;
- int mib[4];
- char *command_beg, *command, *command_end;
-
- if (cbuf == NULL) {
- return(0);
- }
-
- if (arguments)
- bzero(arguments, argmax);
- else
- return(0);
-
- /*
- * A sysctl() is made to find out the full path that the command
- * was called with.
- */
- mib[0] = CTL_KERN;
- mib[1] = KERN_PROCARGS;
- mib[2] = pid;
- mib[3] = 0;
-
- if (sysctl(mib, 3, arguments, (size_t *)&argmax, NULL, 0) < 0) {
- return(0);
- }
-
- /* Skip the saved exec_path. */
- for (cp = arguments; cp < &arguments[argmax]; cp++) {
- if (*cp == '\0') {
- /* End of exec_path reached. */
- break;
+ /*
+ * Get command and arguments.
+ */
+ char *cp;
+ int mib[4];
+ char *command_beg, *command, *command_end;
+
+ if (cbuf == NULL)
+ return(0);
+
+ if (arguments)
+ bzero(arguments, argmax);
+ else
+ return(0);
+
+ /*
+ * A sysctl() is made to find out the full path that the command
+ * was called with.
+ */
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_PROCARGS2;
+ mib[2] = pid;
+ mib[3] = 0;
+
+ if (sysctl(mib, 3, arguments, (size_t *)&argmax, NULL, 0) < 0)
+ return(0);
+
+ /*
+ * Skip the saved exec_path
+ */
+ for (cp = arguments; cp < &arguments[argmax]; cp++) {
+ if (*cp == '\0') {
+ /*
+ * End of exec_path reached
+ */
+ break;
+ }
}
- }
- if (cp == &arguments[argmax]) {
- return(0);
- }
+ if (cp == &arguments[argmax])
+ return(0);
- /* Skip trailing '\0' characters. */
- for (; cp < &arguments[argmax]; cp++) {
- if (*cp != '\0') {
- /* Beginning of first argument reached. */
- break;
+ /*
+ * Skip trailing '\0' characters
+ */
+ for (; cp < &arguments[argmax]; cp++) {
+ if (*cp != '\0') {
+ /*
+ * Beginning of first argument reached
+ */
+ break;
+ }
}
- }
- if (cp == &arguments[argmax]) {
- return(0);
- }
- command_beg = cp;
-
- /*
- * Make sure that the command is '\0'-terminated. This protects
- * against malicious programs; under normal operation this never
- * ends up being a problem..
- */
- for (; cp < &arguments[argmax]; cp++) {
- if (*cp == '\0') {
- /* End of first argument reached. */
- break;
+ if (cp == &arguments[argmax])
+ return(0);
+
+ command_beg = cp;
+ /*
+ * Make sure that the command is '\0'-terminated. This protects
+ * against malicious programs; under normal operation this never
+ * ends up being a problem..
+ */
+ for (; cp < &arguments[argmax]; cp++) {
+ if (*cp == '\0') {
+ /*
+ * End of first argument reached
+ */
+ break;
+ }
}
- }
- if (cp == &arguments[argmax]) {
- return(0);
- }
- command_end = command = cp;
+ if (cp == &arguments[argmax])
+ return(0);
- /* Get the basename of command. */
- for (command--; command >= command_beg; command--) {
- if (*command == '/') {
- command++;
- break;
- }
- }
+ command_end = command = cp;
- (void) strncpy(cbuf, (char *)command, csize);
- cbuf[csize-1] = '\0';
+ /*
+ * Get the basename of command
+ */
+ for (command--; command >= command_beg; command--) {
+ if (*command == '/') {
+ command++;
+ break;
+ }
+ }
+ (void) strncpy(cbuf, (char *)command, csize);
+ cbuf[csize-1] = '\0';
- return(1);
+ return(1);
}