X-Git-Url: https://git.saurik.com/apple/system_cmds.git/blobdiff_plain/83f6dbe8135dc38ce4ac497ebea7f0ebc87d9199..d1ccfde8e7580e81fbe4bd45dc2621b45a9f2e6f:/fs_usage.tproj/fs_usage.c diff --git a/fs_usage.tproj/fs_usage.c b/fs_usage.tproj/fs_usage.c index e0ffcbf..6f8b2f2 100644 --- a/fs_usage.tproj/fs_usage.c +++ b/fs_usage.tproj/fs_usage.c @@ -3,28 +3,27 @@ * * @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. -DPRIVATE -D__APPLE_PRIVATE -O -o fs_usage fs_usage.c */ #define Default_DELAY 1 /* default delay interval */ @@ -57,6 +56,7 @@ cc -I. -DKERNEL_PRIVATE -O -o fs_usage fs_usage.c #include #include #import +#import #include extern int errno; @@ -126,11 +126,13 @@ int argmax = 0; * Network only or filesystem only output filter * Default of zero means report all activity - no filtering */ -#define FILESYS_FILTER 1 -#define NETWORK_FILTER 2 -#define CACHEHIT_FILTER 4 -#define DEFAULT_DO_NOT_FILTER 0 -int filter_mode = DEFAULT_DO_NOT_FILTER; +#define FILESYS_FILTER 0x01 +#define NETWORK_FILTER 0x02 +#define CACHEHIT_FILTER 0x04 +#define EXEC_FILTER 0x08 +#define DEFAULT_DO_NOT_FILTER 0x00 + +int filter_mode = CACHEHIT_FILTER; #define NFS_DEV -1 @@ -177,6 +179,11 @@ void init_arguments_buffer(); int get_real_command_name(int, char *, int); void create_map_entry(int, int, char *); +void enter_syscall(); +void exit_syscall(); +void extend_syscall(); +void kill_thread_map(); + #define TRACE_DATA_NEWTHREAD 0x07000004 #define TRACE_DATA_EXEC 0x07000008 #define TRACE_STRING_NEWTHREAD 0x07010004 @@ -250,6 +257,7 @@ void create_map_entry(int, int, char *); #define BSC_revoke 0x040C00E0 #define BSC_symlink 0x040C00E4 #define BSC_readlink 0x040C00E8 +#define BSC_execve 0x040C00EC #define BSC_chroot 0x040C00F4 #define BSC_dup2 0x040C0168 #define BSC_fsync 0x040C017C @@ -292,8 +300,26 @@ void create_map_entry(int, int, char *); #define BSC_searchfs 0x040C0384 #define BSC_delete 0x040C0388 #define BSC_copyfile 0x040C038C +#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_open_extended 0x040C0454 +#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_load_shared_file 0x040C04A0 +#define BSC_lchown 0x040C05B0 // Carbon File Manager support #define FILEMGR_PBGETCATALOGINFO 0x1e000020 @@ -476,9 +502,11 @@ exit_usage(char *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, " -f Output is 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, " mode = \"filesys\" Show only file system related output\n"); + fprintf(stderr, " mode = \"exec\" Show only execs\n"); + fprintf(stderr, " mode = \"cachehit\" In addition, show cachehits\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); @@ -537,7 +565,9 @@ main(argc, argv) else if (!strcmp(optarg, "filesys")) filter_mode |= FILESYS_FILTER; else if (!strcmp(optarg, "cachehit")) - filter_mode |= CACHEHIT_FILTER; /* turns off CACHE_HIT */ + filter_mode &= ~CACHEHIT_FILTER; /* turns on CACHE_HIT */ + else if (!strcmp(optarg, "exec")) + filter_mode |= EXEC_FILTER; break; default: @@ -634,7 +664,7 @@ main(argc, argv) /* main loop */ while (1) { - usleep(1000 * 25); + usleep(1000 * 20); sample_sc(); } @@ -887,7 +917,7 @@ sample_sc() count = needed; if (bufinfo.flags & KDBG_WRAPPED) { - fprintf(stderr, "buffer wrapped count = %d\n", count); + fprintf(stderr, "fs_usage: buffer overrun, events generated too quickly\n"); for (i = 0; i < cur_max; i++) { th_state[i].thread = 0; @@ -915,15 +945,12 @@ sample_sc() long curr_time; struct th_info *ti; struct diskio *dio; - void enter_syscall(); - void exit_syscall(); - void extend_syscall(); - void kill_thread_map(); + thread = kd[i].arg5; debugid = kd[i].debugid; type = kd[i].debugid & DBG_FUNC_MASK; - + now = kd[i].timestamp & KDBG_TIMESTAMP_MASK; if (i == 0) @@ -1030,6 +1057,7 @@ sample_sc() else { create_map_entry(thread, ti->pid, (char *)&kd[i].arg1); + if (ti == &th_state[cur_max - 1]) cur_max--; ti->thread = 0; @@ -1066,9 +1094,9 @@ sample_sc() handle. */ - if ((long *)sargptr >= (long *)&ti->pathname[PATHLENGTH]) - continue; - + 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, @@ -1076,11 +1104,10 @@ sample_sc() vfslookup entries. */ - if (debugid & DBG_FUNC_START) - { + if (debugid & DBG_FUNC_START) { (long *)ti->pathptr = (long *)&ti->pathname[PATHLENGTH]; continue; - } + } *sargptr++ = kd[i].arg1; *sargptr++ = kd[i].arg2; @@ -1381,10 +1408,34 @@ sample_sc() exit_syscall("socketpair", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); break; + case BSC_getxattr: + exit_syscall("getxattr", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); + break; + + case BSC_setxattr: + exit_syscall("setxattr", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); + break; + + case BSC_removexattr: + exit_syscall("removexattr", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); + break; + + case BSC_listxattr: + exit_syscall("listxattr", 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_stat_extended: + exit_syscall("stat_extended", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); + break; + + case BSC_execve: + exit_syscall("execve", 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; @@ -1393,6 +1444,10 @@ sample_sc() exit_syscall("open", thread, type, kd[i].arg1, kd[i].arg2, 2, 0, (double)now); break; + case BSC_open_extended: + exit_syscall("open_extended", thread, type, kd[i].arg1, kd[i].arg2, 2, 0, (double)now); + break; + case BSC_dup: exit_syscall("dup", thread, type, kd[i].arg1, kd[i].arg2, 2, 0, (double)now); break; @@ -1413,14 +1468,38 @@ sample_sc() exit_syscall("write", thread, type, kd[i].arg1, kd[i].arg2, 1, 1, (double)now); break; + case BSC_fgetxattr: + exit_syscall("fgetxattr", thread, type, kd[i].arg1, kd[i].arg2, 1, 0, (double)now); + break; + + case BSC_fsetxattr: + exit_syscall("fsetxattr", thread, type, kd[i].arg1, kd[i].arg2, 1, 0, (double)now); + break; + + case BSC_fremovexattr: + exit_syscall("fremovexattr", thread, type, kd[i].arg1, kd[i].arg2, 1, 0, (double)now); + break; + + case BSC_flistxattr: + exit_syscall("flistxattr", thread, type, kd[i].arg1, kd[i].arg2, 1, 0, (double)now); + break; + case BSC_fstat: exit_syscall("fstat", thread, type, kd[i].arg1, kd[i].arg2, 1, 0, (double)now); break; + case BSC_fstat_extended: + exit_syscall("fstat_extended", thread, type, kd[i].arg1, kd[i].arg2, 1, 0, (double)now); + break; + case BSC_lstat: exit_syscall("lstat", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); break; + case BSC_lstat_extended: + exit_syscall("lstat_extended", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); + break; + case BSC_link: exit_syscall("link", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); break; @@ -1437,14 +1516,26 @@ sample_sc() exit_syscall("chmod", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); break; + case BSC_chmod_extended: + exit_syscall("chmod_extended", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); + break; + case BSC_chown: exit_syscall("chown", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); break; + case BSC_lchown: + exit_syscall("lchown", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); + break; + case BSC_access: exit_syscall("access", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); break; + case BSC_access_extended: + exit_syscall("access_extended", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); + break; + case BSC_chdir: exit_syscall("chdir", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); break; @@ -1529,14 +1620,26 @@ sample_sc() exit_syscall("fchmod", thread, type, kd[i].arg1, kd[i].arg2, 1, 0, (double)now); break; + case BSC_fchmod_extended: + exit_syscall("fchmod_extended", 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_mkdir_extended: + exit_syscall("mkdir_extended", 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; + case BSC_mkfifo_extended: + exit_syscall("mkfifo_extended", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); + break; + case BSC_rmdir: exit_syscall("rmdir", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); break; @@ -1862,6 +1965,24 @@ enter_syscall(int thread, int type, kd_buf *kd, char *name, double now) case BSC_listen: case BSC_sendto: case BSC_socketpair: + case BSC_execve: + case BSC_getxattr: + case BSC_fgetxattr: + case BSC_setxattr: + case BSC_fsetxattr: + case BSC_removexattr: + case BSC_fremovexattr: + case BSC_listxattr: + case BSC_flistxattr: + case BSC_open_extended: + case BSC_stat_extended: + case BSC_lstat_extended: + case BSC_fstat_extended: + case BSC_chmod_extended: + case BSC_fchmod_extended: + case BSC_access_extended: + case BSC_mkfifo_extended: + case BSC_mkdir_extended: case BSC_stat: case BSC_load_shared_file: case BSC_open: @@ -1877,6 +1998,7 @@ enter_syscall(int thread, int type, kd_buf *kd, char *name, double now) case BSC_mknod: case BSC_chmod: case BSC_chown: + case BSC_lchown: case BSC_access: case BSC_chflags: case BSC_fchflags: @@ -1990,7 +2112,11 @@ enter_syscall(int thread, int type, kd_buf *kd, char *name, double now) case FILEMGR_PBLOCKRANGE: case FILEMGR_PBUNLOCKRANGE: - + if ((ti = find_thread(thread, BSC_execve))) { + if (ti->pathptr) { + exit_syscall("execve", thread, BSC_execve, 0, 0, 0, 0, (double)now); + } + } for (i = 0, ti = th_state; ti < &th_state[MAX_THREADS]; ti++, i++) { if (ti->thread == 0) break; @@ -2000,7 +2126,6 @@ enter_syscall(int thread, int type, kd_buf *kd, char *name, double now) if (i >= cur_max) cur_max = i + 1; - if ((type >> 24) == FILEMGR_CLASS) { ti->in_filemgr = 1; @@ -2336,19 +2461,11 @@ char *s; void getdivisor() { + struct mach_timebase_info mti; - 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; + mach_timebase_info(&mti); - extern void MKGetTimeBaseInfo(unsigned int *, unsigned int *, unsigned int *, unsigned int *, unsigned int *); - - MKGetTimeBaseInfo (&delta, &abs_to_ns_num, &abs_to_ns_denom, - &proc_to_abs_num, &proc_to_abs_denom); - - divisor = ((double)abs_to_ns_denom / (double)abs_to_ns_num) * 1000; + divisor = ((double)mti.denom / (double)mti.numer) * 1000; } @@ -2390,7 +2507,7 @@ void read_command_map() } } - if (mapptr && (filter_mode != DEFAULT_DO_NOT_FILTER)) + if (mapptr && (filter_mode & (NETWORK_FILTER | FILESYS_FILTER))) { if (fdmapptr) { @@ -2455,7 +2572,7 @@ void create_map_entry(int thread, int pid, char *command) { map = &mapptr[i]; /* Reuse this entry, the thread has been * reassigned */ - if(filter_mode && fdmapptr) + if ((filter_mode & (NETWORK_FILTER | FILESYS_FILTER)) && fdmapptr) { fdmap = &fdmapptr[i]; if (fdmap->fd_thread != thread) /* This shouldn't happen */ @@ -2470,7 +2587,7 @@ void create_map_entry(int thread, int pid, char *command) { if (mapptr[i].valid == 0 ) map = &mapptr[i]; /* Reuse this invalid entry */ - if (filter_mode && fdmapptr) + if ((filter_mode & (NETWORK_FILTER | FILESYS_FILTER)) && fdmapptr) { fdmap = &fdmapptr[i]; } @@ -2489,7 +2606,7 @@ void create_map_entry(int thread, int pid, char *command) bzero(&mapptr[total_threads], total_threads*sizeof(kd_threadmap)); map = &mapptr[total_threads]; - if (filter_mode && fdmapptr) + if ((filter_mode & (NETWORK_FILTER | FILESYS_FILTER)) && fdmapptr) { fdmapptr = (fd_threadmap *)realloc(fdmapptr, n * sizeof(fd_threadmap)); bzero(&fdmapptr[total_threads], total_threads*sizeof(fd_threadmap)); @@ -2579,7 +2696,7 @@ kill_thread_map(int thread) map->command[0] = '\0'; } - if (filter_mode) + if ((filter_mode & (NETWORK_FILTER | FILESYS_FILTER))) { if ((fdmap = find_fd_thread_map(thread))) { @@ -3105,12 +3222,22 @@ check_filter_mode(struct th_info * ti, int type, int error, int retval, char *sc if (filter_mode == DEFAULT_DO_NOT_FILTER) return(1); - if (filter_mode & CACHEHIT_FILTER) + if (!strcmp (sc_name, "CACHE_HIT")) { + if (filter_mode & CACHEHIT_FILTER) + /* Do not print if cachehit filter is set */ + return(0); + return (1); + } + + if (filter_mode & EXEC_FILTER) { - /* Do not print if cachehit filter is set */ - if (!strcmp (sc_name, "CACHE_HIT")) - return(0); + if (!strcmp (sc_name, "execve")) + return(1); + return(0); } + if ( !(filter_mode & (FILESYS_FILTER | NETWORK_FILTER))) + return(1); + if (ti == (struct th_info *)0) {