]> git.saurik.com Git - apple/xnu.git/blobdiff - bsd/dev/dtrace/scripts/io.d
xnu-2422.1.72.tar.gz
[apple/xnu.git] / bsd / dev / dtrace / scripts / io.d
diff --git a/bsd/dev/dtrace/scripts/io.d b/bsd/dev/dtrace/scripts/io.d
new file mode 100644 (file)
index 0000000..f295f10
--- /dev/null
@@ -0,0 +1,265 @@
+/*
+ * Copyright (c) 2007 Apple, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * The contents of this file constitute Original Code as defined in and
+ * are subject to the Apple Public Source License Version 1.1 (the
+ * "License").  You may not use this file except in compliance with the
+ * License.  Please obtain a copy of the License at
+ * http://www.apple.com/publicsource and read it before using this file.
+ * 
+ * This Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+#pragma D depends_on library darwin.d
+#pragma D depends_on module mach_kernel
+#pragma D depends_on provider io
+
+inline int B_WRITE = 0x0000;
+#pragma D binding "1.0" B_WRITE
+inline int B_READ = 0x0001;
+#pragma D binding "1.0" B_READ
+inline int B_ASYNC = 0x0002;
+#pragma D binding "1.0" B_ASYNC
+inline int B_NOCACHE = 0x0004;
+#pragma D binding "1.0" B_NOCACHE
+inline int B_DELWRI = 0x0008;
+#pragma D binding "1.0" B_DELWRI
+inline int B_LOCKED = 0x0010;
+#pragma D binding "1.0" B_LOCKED
+inline int B_PHYS = 0x0020;
+#pragma D binding "1.0" B_PHYS
+inline int B_CLUSTER = 0x0040;
+#pragma D binding "1.0" B_CLUSTER
+inline int B_PAGEIO = 0x0080;
+#pragma D binding "1.0" B_PAGEIO
+inline int B_META = 0x0100;
+#pragma D binding "1.0" B_META
+inline int B_RAW = 0x0200;
+#pragma D binding "1.0" B_RAW
+inline int B_FUA = 0x0400;
+#pragma D binding "1.0" B_FUA
+inline int B_PASSIVE = 0x0800;
+#pragma D binding "1.0" B_PASSIVE
+
+typedef struct bufinfo {
+       int b_flags;                    /* buffer status */
+       size_t b_bcount;                /* number of bytes */
+       caddr_t b_addr;                 /* buffer address */
+       uint64_t b_lblkno;              /* block # on device */
+       uint64_t b_blkno;               /* expanded block # on device */
+       size_t b_resid;                 /* # of bytes not transferred */
+       size_t b_bufsize;               /* size of allocated buffer */
+       caddr_t b_iodone;               /* I/O completion routine */
+       int b_error;                    /* expanded error field */
+       dev_t b_edev;                   /* extended device */
+} bufinfo_t;
+
+#pragma D binding "1.0" translator
+translator bufinfo_t < struct buf *B > {
+       b_flags = B->b_flags;
+       b_addr = (caddr_t)B->b_datap;
+       b_bcount = B->b_bcount;
+       b_lblkno = B->b_lblkno;
+       b_blkno = B->b_blkno;
+       b_resid = B->b_resid;
+       b_bufsize = B->b_bufsize;
+       b_iodone = (caddr_t)B->b_iodone;
+       b_error = B->b_error;
+       b_edev = B->b_dev;
+}; 
+
+typedef struct devinfo {
+       int dev_major;                  /* major number */
+       int dev_minor;                  /* minor number */
+       int dev_instance;               /* instance number */
+       string dev_name;                /* name of device */
+       string dev_statname;            /* name of device + instance/minor */
+       string dev_pathname;            /* pathname of device */
+} devinfo_t;
+
+#pragma D binding "1.0" translator
+translator devinfo_t < struct buf *B > {
+       dev_major = getmajor(B->b_dev);
+       dev_minor = getminor(B->b_dev);
+       dev_instance = getminor(B->b_dev);
+       dev_name = "??"; /* XXX */
+       dev_statname = "??"; /* XXX */
+       dev_pathname = "??"; /* XXX */
+};
+
+typedef off_t offset_t;
+
+typedef struct fileinfo {
+       string fi_name;                 /* name (basename of fi_pathname) */
+       string fi_dirname;              /* directory (dirname of fi_pathname) */
+       string fi_pathname;             /* full pathname */
+       offset_t fi_offset;             /* offset within file */
+       string fi_fs;                   /* filesystem */
+       string fi_mount;                /* mount point of file system */
+       int fi_oflags;          /* open(2) flags for file descriptor */
+} fileinfo_t;
+
+#pragma D binding "1.0" translator
+translator fileinfo_t < struct buf *B > {
+       fi_name = B->b_vp->v_name == NULL ? "<unknown (NULL v_name)>" : B->b_vp->v_name;
+
+       fi_dirname = B->b_vp->v_parent == NULL ? "<unknown (NULL v_parent)>" : 
+                       (B->b_vp->v_parent->v_name == NULL ? "<unknown (NULL v_name)>" : B->b_vp->v_parent->v_name);
+
+       fi_pathname = strjoin("??/", 
+                       strjoin(B->b_vp->v_parent == NULL ? "<unknown (NULL v_parent)>" :
+                               (B->b_vp->v_parent->v_name == NULL ? "<unknown (NULL v_name)>" : B->b_vp->v_parent->v_name),
+                               strjoin("/",
+                                       B->b_vp->v_name == NULL ? "<unknown (NULL v_name)>" : B->b_vp->v_name)));
+
+       fi_offset = B->b_upl == NULL ? -1 : ((upl_t)B->b_upl)->offset;
+
+       fi_fs = B->b_vp->v_mount->mnt_vtable->vfc_name;
+
+       fi_mount = B->b_vp->v_mount->mnt_vnodecovered == NULL ? "/" : B->b_vp->v_mount->mnt_vnodecovered->v_name;
+
+       fi_oflags = 0;
+};
+
+/*
+ * The following inline constants can be used to examine fi_oflags when using
+ * the fds[] array or a translated fileglob *.  Note that the various open
+ * flags behave as a bit-field *except* for O_RDONLY, O_WRONLY, and O_RDWR.
+ * To test the open mode, you write code similar to that used with the fcntl(2)
+ * F_GET[X]FL command, such as: if ((fi_oflags & O_ACCMODE) == O_WRONLY).
+ */     
+inline int O_ACCMODE = 0x0003;
+#pragma D binding "1.1" O_ACCMODE 
+        
+inline int O_RDONLY = 0x0000;
+#pragma D binding "1.1" O_RDONLY
+inline int O_WRONLY = 0x0001;
+#pragma D binding "1.1" O_WRONLY
+inline int O_RDWR = 0x0002;
+#pragma D binding "1.1" O_RDWR
+        
+inline int O_NONBLOCK = 0x0004;
+#pragma D binding "1.1" O_NONBLOCK
+inline int O_APPEND = 0x0008;
+#pragma D binding "1.1" O_APPEND
+inline int O_SHLOCK = 0x0010;
+#pragma D binding "1.1" O_SHLOCK
+inline int O_EXLOCK = 0x0020;
+#pragma D binding "1.1" O_EXLOCK
+inline int O_ASYNC = 0x0040;
+#pragma D binding "1.1" O_ASYNC
+inline int O_SYNC = 0x0080;
+#pragma D binding "1.1" O_SYNC
+inline int O_NOFOLLOW = 0x0100;
+#pragma D binding "1.1" O_NOFOLLOW
+inline int O_CREAT = 0x0200;
+#pragma D binding "1.1" O_CREAT
+inline int O_TRUNC = 0x0400;
+#pragma D binding "1.1" O_TRUNC
+inline int O_EXCL = 0x0800;
+#pragma D binding "1.1" O_EXCL
+inline int O_EVTONLY = 0x8000;
+#pragma D binding "1.1" O_EVTONLY
+inline int O_NOCTTY = 0x20000;
+#pragma D binding "1.1" O_NOCTTY
+inline int O_DIRECTORY = 0x100000;
+#pragma D binding "1.1" O_DIRECTORY
+inline int O_SYMLINK = 0x200000;
+#pragma D binding "1.1" O_SYMLINK
+
+/* From bsd/sys/file_internal.h */
+inline int DTYPE_VNODE = 1;
+#pragma D binding "1.1" DTYPE_VNODE
+inline int DTYPE_SOCKET = 2;
+#pragma D binding "1.1" DTYPE_SOCKET 
+inline int DTYPE_PSXSHM = 3;
+#pragma D binding "1.1" DTYPE_PSXSHM
+inline int DTYPE_PSXSEM = 4;
+#pragma D binding "1.1" DTYPE_PSXSEM
+inline int DTYPE_KQUEUE = 5;
+#pragma D binding "1.1" DTYPE_KQUEUE
+inline int DTYPE_PIPE = 6;
+#pragma D binding "1.1" DTYPE_PIPE
+inline int DTYPE_FSEVENTS = 7;
+#pragma D binding "1.1" DTYPE_FSEVENTS
+
+#pragma D binding "1.1" translator
+translator fileinfo_t < struct fileglob *F > {
+       fi_name = (F == NULL) ? "<none>" :
+               F->fg_ops->fo_type == DTYPE_VNODE ?
+                       ((struct vnode *)F->fg_data)->v_name == NULL ? "<unknown (NULL v_name)>" : ((struct vnode *)F->fg_data)->v_name :
+               F->fg_ops->fo_type == DTYPE_SOCKET ? "<socket>" :
+               F->fg_ops->fo_type == DTYPE_PSXSHM ? "<shared memory>" :
+               F->fg_ops->fo_type == DTYPE_PSXSEM ? "<semaphore>" :
+               F->fg_ops->fo_type == DTYPE_KQUEUE ? "<kqueue>" :
+               F->fg_ops->fo_type == DTYPE_PIPE ? "<pipe>" :
+               F->fg_ops->fo_type == DTYPE_FSEVENTS ? "<fsevents>" : "<unknown (BAD fo_type)>";
+
+       fi_dirname = (F == NULL) ? "<none>" :
+               F->fg_ops->fo_type != DTYPE_VNODE ? "<unknown (not a vnode)>" :
+                       ((struct vnode *)F->fg_data)->v_parent == NULL ? "<unknown (NULL v_parent)>" : 
+                       (((struct vnode *)F->fg_data)->v_parent->v_name == NULL ? "<unknown (NULL v_name)>" : 
+                        ((struct vnode *)F->fg_data)->v_parent->v_name);
+
+       fi_pathname = (F == NULL) ? "<none>" :
+               F->fg_ops->fo_type != DTYPE_VNODE ? "<unknown (not a vnode)>" :
+                       strjoin("??/", 
+                       strjoin(((struct vnode *)F->fg_data)->v_parent == NULL ? "<unknown (NULL v_parent)>" :
+                               (((struct vnode *)F->fg_data)->v_parent->v_name == NULL ? "<unknown (NULL v_name)>" : 
+                                ((struct vnode *)F->fg_data)->v_parent->v_name),
+                               strjoin("/",
+                                       ((struct vnode *)F->fg_data)->v_name == NULL ? "<unknown (NULL v_name)>" : 
+                                       ((struct vnode *)F->fg_data)->v_name)));
+
+       fi_offset = (F == NULL) ? 0 :
+                       F->fg_offset;
+
+       fi_fs = (F == NULL) ? "<none>" :
+               F->fg_ops->fo_type != DTYPE_VNODE ? "<unknown (not a vnode)>" :
+                       ((struct vnode *)F->fg_data)->v_mount->mnt_vtable->vfc_name;
+
+       fi_mount = (F == NULL) ? "<none>" :
+               F->fg_ops->fo_type != DTYPE_VNODE ? "<unknown (not a vnode)>" :
+                       ((struct vnode *)F->fg_data)->v_mount->mnt_vnodecovered == NULL ? "/" : 
+                       ((struct vnode *)F->fg_data)->v_mount->mnt_vnodecovered->v_name;
+
+       fi_oflags = (F == NULL) ? 0 : 
+                       F->fg_flag - 1; /* Subtract one to map FREAD/FWRITE bitfield to O_RD/WR open() flags. */
+};
+
+inline fileinfo_t fds[int fd] = xlate <fileinfo_t> (
+    (fd >= 0 && fd <= curproc->p_fd->fd_lastfile) ?
+       (struct fileglob *)(curproc->p_fd->fd_ofiles[fd]->f_fglob) : 
+               (struct fileglob *)NULL);
+
+#pragma D attributes Stable/Stable/Common fds
+#pragma D binding "1.1" fds
+
+#pragma D binding "1.2" translator
+translator fileinfo_t < struct vnode *V > {
+       fi_name = V->v_name == NULL ? "<unknown (NULL v_name)>" : V->v_name;
+
+       fi_dirname = V->v_parent == NULL ? "<unknown (NULL v_parent)>" : 
+                       (V->v_parent->v_name == NULL ? "<unknown (NULL v_name)>" : V->v_parent->v_name);
+
+       fi_pathname = strjoin("??/", 
+                       strjoin(V->v_parent == NULL ? "<unknown (NULL v_parent)>" :
+                               (V->v_parent->v_name == NULL ? "<unknown (NULL v_name)>" : V->v_parent->v_name),
+                               strjoin("/",
+                                       V->v_name == NULL ? "<unknown (NULL v_name)>" : V->v_name)));
+
+       fi_fs = V->v_mount->mnt_vtable->vfc_name;
+
+       fi_mount = V->v_mount->mnt_vnodecovered == NULL ? "/" : V->v_mount->mnt_vnodecovered->v_name;
+};
+