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