1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21/*
22 * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
23 * Use is subject to license terms.
24 */
25
26/*
27 * Copyright (c) 2012, Joyent, Inc. All rights reserved.
28 */
29
30#pragma D depends_on module unix
31#pragma D depends_on provider io
32
33inline int B_BUSY = @B_BUSY@;
34#pragma D binding "1.0" B_BUSY
35inline int B_DONE = @B_DONE@;
36#pragma D binding "1.0" B_DONE
37inline int B_ERROR = @B_ERROR@;
38#pragma D binding "1.0" B_ERROR
39inline int B_PAGEIO = @B_PAGEIO@;
40#pragma D binding "1.0" B_PAGEIO
41inline int B_PHYS = @B_PHYS@;
42#pragma D binding "1.0" B_PHYS
43inline int B_READ = @B_READ@;
44#pragma D binding "1.0" B_READ
45inline int B_WRITE = @B_WRITE@;
46#pragma D binding "1.0" B_WRITE
47inline int B_ASYNC = @B_ASYNC@;
48#pragma D binding "1.0" B_ASYNC
49
50typedef struct bufinfo {
51	int b_flags;			/* buffer status */
52	size_t b_bcount;		/* number of bytes */
53	caddr_t b_addr;			/* buffer address */
54	uint64_t b_lblkno;		/* block # on device */
55	uint64_t b_blkno;		/* expanded block # on device */
56	size_t b_resid;			/* # of bytes not transferred */
57	size_t b_bufsize;		/* size of allocated buffer */
58	caddr_t b_iodone;		/* I/O completion routine */
59	int b_error;			/* expanded error field */
60	dev_t b_edev;			/* extended device */
61} bufinfo_t;
62
63#pragma D binding "1.0" translator
64translator bufinfo_t < struct buf *B > {
65	b_flags = B->b_flags;
66	b_addr = B->b_un.b_addr;
67	b_bcount = B->b_bcount;
68	b_lblkno = B->_b_blkno._f;
69	b_blkno = sizeof (long) == 8 ? B->_b_blkno._f : B->_b_blkno._p._l;
70	b_resid = B->b_resid;
71	b_bufsize = B->b_bufsize;
72	b_iodone = (caddr_t)B->b_iodone;
73	b_error = B->b_error;
74	b_edev = B->b_edev;
75};
76
77typedef struct devinfo {
78	int dev_major;			/* major number */
79	int dev_minor;			/* minor number */
80	int dev_instance;		/* instance number */
81	string dev_name;		/* name of device */
82	string dev_statname;		/* name of device + instance/minor */
83	string dev_pathname;		/* pathname of device */
84} devinfo_t;
85
86#pragma D binding "1.0" translator
87translator devinfo_t < struct buf *B > {
88	dev_major = B->b_dip != NULL ? getmajor(B->b_edev) :
89	    getmajor(B->b_file->v_vfsp->vfs_dev);
90	dev_minor = B->b_dip != NULL ? getminor(B->b_edev) :
91	    getminor(B->b_file->v_vfsp->vfs_dev);
92	dev_instance = B->b_dip == NULL ?
93	    getminor(B->b_file->v_vfsp->vfs_dev) :
94	    ((struct dev_info *)B->b_dip)->devi_instance;
95	dev_name = B->b_dip == NULL ? "nfs" :
96	    stringof(`devnamesp[getmajor(B->b_edev)].dn_name);
97	dev_statname = strjoin(B->b_dip == NULL ? "nfs" :
98	    stringof(`devnamesp[getmajor(B->b_edev)].dn_name),
99	    lltostr(B->b_dip == NULL ? getminor(B->b_file->v_vfsp->vfs_dev) :
100	    ((struct dev_info *)B->b_dip)->devi_instance == 0 &&
101	    ((struct dev_info *)B->b_dip)->devi_parent != NULL &&
102	    ((struct dev_info *)B->b_dip)->devi_parent->devi_node_name ==
103	    "pseudo" ? getminor(B->b_edev) :
104	    ((struct dev_info *)B->b_dip)->devi_instance));
105	dev_pathname = B->b_dip == NULL ? "<nfs>" :
106	    ddi_pathname(B->b_dip, getminor(B->b_edev));
107};
108
109typedef struct fileinfo {
110	string fi_name;			/* name (basename of fi_pathname) */
111	string fi_dirname;		/* directory (dirname of fi_pathname) */
112	string fi_pathname;		/* full pathname */
113	offset_t fi_offset;		/* offset within file */
114	string fi_fs;			/* filesystem */
115	string fi_mount;		/* mount point of file system */
116	int fi_oflags;			/* open(2) flags for file descriptor */
117} fileinfo_t;
118
119#pragma D binding "1.0" translator
120translator fileinfo_t < struct buf *B > {
121	fi_name = B->b_file == NULL ? "<none>" :
122	    B->b_file->v_path == NULL ? "<unknown>" :
123	    basename(cleanpath(B->b_file->v_path));
124	fi_dirname = B->b_file == NULL ? "<none>" :
125	    B->b_file->v_path == NULL ? "<unknown>" :
126	    dirname(cleanpath(B->b_file->v_path));
127	fi_pathname = B->b_file == NULL ? "<none>" :
128	    B->b_file->v_path == NULL ? "<unknown>" :
129	    cleanpath(B->b_file->v_path);
130	fi_offset = B->b_offset;
131	fi_fs = B->b_file == NULL ? "<none>" :
132	    stringof(B->b_file->v_op->vnop_name);
133	fi_mount = B->b_file == NULL ? "<none>" :
134	    B->b_file->v_vfsp->vfs_vnodecovered == NULL ? "/" :
135	    B->b_file->v_vfsp->vfs_vnodecovered->v_path == NULL ? "<unknown>" :
136	    cleanpath(B->b_file->v_vfsp->vfs_vnodecovered->v_path);
137	fi_oflags = 0;
138};
139
140/*
141 * The following inline constants can be used to examine fi_oflags when using
142 * the fds[] array or a translated fileinfo_t.  Note that the various open
143 * flags behave as a bit-field *except* for O_RDONLY, O_WRONLY, and O_RDWR.
144 * To test the open mode, you write code similar to that used with the fcntl(2)
145 * F_GET[X]FL command, such as: if ((fi_oflags & O_ACCMODE) == O_WRONLY).
146 */
147inline int O_ACCMODE = @O_ACCMODE@;
148#pragma D binding "1.1" O_ACCMODE
149
150inline int O_RDONLY = @O_RDONLY@;
151#pragma D binding "1.1" O_RDONLY
152inline int O_WRONLY = @O_WRONLY@;
153#pragma D binding "1.1" O_WRONLY
154inline int O_RDWR = @O_RDWR@;
155#pragma D binding "1.1" O_RDWR
156
157inline int O_APPEND = @O_APPEND@;
158#pragma D binding "1.1" O_APPEND
159inline int O_CREAT = @O_CREAT@;
160#pragma D binding "1.1" O_CREAT
161inline int O_DSYNC = @O_DSYNC@;
162#pragma D binding "1.1" O_DSYNC
163inline int O_EXCL = @O_EXCL@;
164#pragma D binding "1.1" O_EXCL
165inline int O_LARGEFILE = @O_LARGEFILE@;
166#pragma D binding "1.1" O_LARGEFILE
167inline int O_NOCTTY = @O_NOCTTY@;
168#pragma D binding "1.1" O_NOCTTY
169inline int O_NONBLOCK = @O_NONBLOCK@;
170#pragma D binding "1.1" O_NONBLOCK
171inline int O_NDELAY = @O_NDELAY@;
172#pragma D binding "1.1" O_NDELAY
173inline int O_RSYNC = @O_RSYNC@;
174#pragma D binding "1.1" O_RSYNC
175inline int O_SYNC = @O_SYNC@;
176#pragma D binding "1.1" O_SYNC
177inline int O_TRUNC = @O_TRUNC@;
178#pragma D binding "1.1" O_TRUNC
179inline int O_XATTR = @O_XATTR@;
180#pragma D binding "1.1" O_XATTR
181
182#pragma D binding "1.1" translator
183translator fileinfo_t < struct file *F > {
184	fi_name = F == NULL ? "<none>" :
185	    F->f_vnode->v_path == NULL ? "<unknown>" :
186	    basename(cleanpath(F->f_vnode->v_path));
187	fi_dirname = F == NULL ? "<none>" :
188	    F->f_vnode->v_path == NULL ? "<unknown>" :
189	    dirname(cleanpath(F->f_vnode->v_path));
190	fi_pathname = F == NULL ? "<none>" :
191	    F->f_vnode->v_path == NULL ? "<unknown>" :
192	    cleanpath(F->f_vnode->v_path);
193	fi_offset = F == NULL ? 0 : F->f_offset;
194	fi_fs = F == NULL ? "<none>" : stringof(F->f_vnode->v_op->vnop_name);
195	fi_mount = F == NULL ? "<none>" :
196	    F->f_vnode->v_vfsp->vfs_vnodecovered == NULL ? "/" :
197	    F->f_vnode->v_vfsp->vfs_vnodecovered->v_path == NULL ? "<unknown>" :
198	    cleanpath(F->f_vnode->v_vfsp->vfs_vnodecovered->v_path);
199	fi_oflags = F == NULL ? 0 : F->f_flag + (int)@FOPEN@;
200};
201
202inline fileinfo_t fds[int fd] = xlate <fileinfo_t> (getf(fd));
203
204#pragma D attributes Stable/Stable/Common fds
205#pragma D binding "1.1" fds
206
207#pragma D binding "1.2" translator
208translator fileinfo_t < struct vnode *V > {
209	fi_name = V->v_path == NULL ? "<unknown>" :
210	    basename(cleanpath(V->v_path));
211	fi_dirname = V->v_path == NULL ? "<unknown>" :
212	    dirname(cleanpath(V->v_path));
213	fi_pathname = V->v_path == NULL ? "<unknown>" : cleanpath(V->v_path);
214	fi_fs = stringof(V->v_op->vnop_name);
215	fi_mount = V->v_vfsp->vfs_vnodecovered == NULL ? "/" :
216	    V->v_vfsp->vfs_vnodecovered->v_path == NULL ? "<unknown>" :
217	    cleanpath(V->v_vfsp->vfs_vnodecovered->v_path);
218};
219