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 #pragma ident   "%Z%%M% %I%     %E% SMI"
  27 
  28 #pragma D depends_on module unix
  29 #pragma D depends_on provider io
  30 
  31 inline int B_BUSY = @B_BUSY@;
  32 #pragma D binding "1.0" B_BUSY
  33 inline int B_DONE = @B_DONE@;
  34 #pragma D binding "1.0" B_DONE
  35 inline int B_ERROR = @B_ERROR@;
  36 #pragma D binding "1.0" B_ERROR
  37 inline int B_PAGEIO = @B_PAGEIO@;
  38 #pragma D binding "1.0" B_PAGEIO
  39 inline int B_PHYS = @B_PHYS@;
  40 #pragma D binding "1.0" B_PHYS
  41 inline int B_READ = @B_READ@;
  42 #pragma D binding "1.0" B_READ
  43 inline int B_WRITE = @B_WRITE@;
  44 #pragma D binding "1.0" B_WRITE
  45 inline int B_ASYNC = @B_ASYNC@;
  46 #pragma D binding "1.0" B_ASYNC
  47 
  48 typedef struct bufinfo {
  49         int b_flags;                    /* buffer status */
  50         size_t b_bcount;                /* number of bytes */
  51         caddr_t b_addr;                 /* buffer address */
  52         uint64_t b_lblkno;              /* block # on device */
  53         uint64_t b_blkno;               /* expanded block # on device */
  54         size_t b_resid;                 /* # of bytes not transferred */
  55         size_t b_bufsize;               /* size of allocated buffer */
  56         caddr_t b_iodone;               /* I/O completion routine */
  57         int b_error;                    /* expanded error field */
  58         dev_t b_edev;                   /* extended device */
  59 } bufinfo_t;
  60 
  61 #pragma D binding "1.0" translator
  62 translator bufinfo_t < struct buf *B > {
  63         b_flags = B->b_flags;
  64         b_addr = B->b_un.b_addr;
  65         b_bcount = B->b_bcount;
  66         b_lblkno = B->_b_blkno._f;
  67         b_blkno = sizeof (long) == 8 ? B->_b_blkno._f : B->_b_blkno._p._l;
  68         b_resid = B->b_resid;
  69         b_bufsize = B->b_bufsize;
  70         b_iodone = (caddr_t)B->b_iodone;
  71         b_error = B->b_error;
  72         b_edev = B->b_edev;
  73 }; 
  74 
  75 typedef struct devinfo {
  76         int dev_major;                  /* major number */
  77         int dev_minor;                  /* minor number */
  78         int dev_instance;               /* instance number */
  79         string dev_name;                /* name of device */
  80         string dev_statname;            /* name of device + instance/minor */
  81         string dev_pathname;            /* pathname of device */
  82 } devinfo_t;
  83 
  84 #pragma D binding "1.0" translator
  85 translator devinfo_t < struct buf *B > {
  86         dev_major = B->b_dip != NULL ? getmajor(B->b_edev) :
  87             getmajor(B->b_file->v_vfsp->vfs_dev);
  88         dev_minor = B->b_dip != NULL ? getminor(B->b_edev) :
  89             getminor(B->b_file->v_vfsp->vfs_dev);
  90         dev_instance = B->b_dip == NULL ? 
  91             getminor(B->b_file->v_vfsp->vfs_dev) :
  92             ((struct dev_info *)B->b_dip)->devi_instance;
  93         dev_name = B->b_dip == NULL ? "nfs" :
  94             stringof(`devnamesp[getmajor(B->b_edev)].dn_name);
  95         dev_statname = strjoin(B->b_dip == NULL ? "nfs" :
  96             stringof(`devnamesp[getmajor(B->b_edev)].dn_name),
  97             lltostr(B->b_dip == NULL ? getminor(B->b_file->v_vfsp->vfs_dev) :
  98             ((struct dev_info *)B->b_dip)->devi_instance == 0 &&
  99             ((struct dev_info *)B->b_dip)->devi_parent != NULL &&
 100             ((struct dev_info *)B->b_dip)->devi_parent->devi_node_name ==
 101             "pseudo" ? getminor(B->b_edev) :
 102             ((struct dev_info *)B->b_dip)->devi_instance));
 103         dev_pathname = B->b_dip == NULL ? "<nfs>" :
 104             ddi_pathname(B->b_dip, getminor(B->b_edev));
 105 };
 106 
 107 typedef struct fileinfo {
 108         string fi_name;                 /* name (basename of fi_pathname) */
 109         string fi_dirname;              /* directory (dirname of fi_pathname) */
 110         string fi_pathname;             /* full pathname */
 111         offset_t fi_offset;             /* offset within file */
 112         string fi_fs;                   /* filesystem */
 113         string fi_mount;                /* mount point of file system */
 114         int fi_oflags;                  /* open(2) flags for file descriptor */
 115 } fileinfo_t;
 116 
 117 #pragma D binding "1.0" translator
 118 translator fileinfo_t < struct buf *B > {
 119         fi_name = B->b_file == NULL ? "<none>" :
 120             B->b_file->v_path == NULL ? "<unknown>" :
 121             basename(cleanpath(B->b_file->v_path));
 122         fi_dirname = B->b_file == NULL ? "<none>" :
 123             B->b_file->v_path == NULL ? "<unknown>" :
 124             dirname(cleanpath(B->b_file->v_path));
 125         fi_pathname = B->b_file == NULL ? "<none>" :
 126             B->b_file->v_path == NULL ? "<unknown>" :
 127             cleanpath(B->b_file->v_path);
 128         fi_offset = B->b_offset;
 129         fi_fs = B->b_file == NULL ? "<none>" :
 130             stringof(B->b_file->v_op->vnop_name);
 131         fi_mount = B->b_file == NULL ? "<none>" :
 132             B->b_file->v_vfsp->vfs_vnodecovered == NULL ? "/" :
 133             B->b_file->v_vfsp->vfs_vnodecovered->v_path == NULL ? "<unknown>" :
 134             cleanpath(B->b_file->v_vfsp->vfs_vnodecovered->v_path);
 135         fi_oflags = 0;
 136 };
 137 
 138 /*
 139  * The following inline constants can be used to examine fi_oflags when using
 140  * the fds[] array or a translated fileinfo_t.  Note that the various open
 141  * flags behave as a bit-field *except* for O_RDONLY, O_WRONLY, and O_RDWR.
 142  * To test the open mode, you write code similar to that used with the fcntl(2)
 143  * F_GET[X]FL command, such as: if ((fi_oflags & O_ACCMODE) == O_WRONLY).
 144  */
 145 inline int O_ACCMODE = @O_ACCMODE@;
 146 #pragma D binding "1.1" O_ACCMODE
 147 
 148 inline int O_RDONLY = @O_RDONLY@;
 149 #pragma D binding "1.1" O_RDONLY
 150 inline int O_WRONLY = @O_WRONLY@;
 151 #pragma D binding "1.1" O_WRONLY
 152 inline int O_RDWR = @O_RDWR@;
 153 #pragma D binding "1.1" O_RDWR
 154 
 155 inline int O_APPEND = @O_APPEND@;
 156 #pragma D binding "1.1" O_APPEND
 157 inline int O_CREAT = @O_CREAT@;
 158 #pragma D binding "1.1" O_CREAT
 159 inline int O_DSYNC = @O_DSYNC@;
 160 #pragma D binding "1.1" O_DSYNC
 161 inline int O_EXCL = @O_EXCL@;
 162 #pragma D binding "1.1" O_EXCL
 163 inline int O_LARGEFILE = @O_LARGEFILE@;
 164 #pragma D binding "1.1" O_LARGEFILE
 165 inline int O_NOCTTY = @O_NOCTTY@;
 166 #pragma D binding "1.1" O_NOCTTY
 167 inline int O_NONBLOCK = @O_NONBLOCK@;
 168 #pragma D binding "1.1" O_NONBLOCK
 169 inline int O_NDELAY = @O_NDELAY@;
 170 #pragma D binding "1.1" O_NDELAY
 171 inline int O_RSYNC = @O_RSYNC@;
 172 #pragma D binding "1.1" O_RSYNC
 173 inline int O_SYNC = @O_SYNC@;
 174 #pragma D binding "1.1" O_SYNC
 175 inline int O_TRUNC = @O_TRUNC@;
 176 #pragma D binding "1.1" O_TRUNC
 177 inline int O_XATTR = @O_XATTR@;
 178 #pragma D binding "1.1" O_XATTR
 179 
 180 #pragma D binding "1.1" translator
 181 translator fileinfo_t < struct file *F > {
 182         fi_name = F == NULL ? "<none>" :
 183             F->f_vnode->v_path == NULL ? "<unknown>" :
 184             basename(cleanpath(F->f_vnode->v_path));
 185         fi_dirname = F == NULL ? "<none>" :
 186             F->f_vnode->v_path == NULL ? "<unknown>" :
 187             dirname(cleanpath(F->f_vnode->v_path));
 188         fi_pathname = F == NULL ? "<none>" :
 189             F->f_vnode->v_path == NULL ? "<unknown>" :
 190             cleanpath(F->f_vnode->v_path);
 191         fi_offset = F == NULL ? 0 : F->f_offset;
 192         fi_fs = F == NULL ? "<none>" : stringof(F->f_vnode->v_op->vnop_name);
 193         fi_mount = F == NULL ? "<none>" :
 194             F->f_vnode->v_vfsp->vfs_vnodecovered == NULL ? "/" :
 195             F->f_vnode->v_vfsp->vfs_vnodecovered->v_path == NULL ? "<unknown>" :
 196             cleanpath(F->f_vnode->v_vfsp->vfs_vnodecovered->v_path);
 197         fi_oflags = F == NULL ? 0 : F->f_flag + (int)@FOPEN@;
 198 };
 199 
 200 inline fileinfo_t fds[int fd] = xlate <fileinfo_t> (
 201     fd >= 0 && fd < curthread->t_procp->p_user.u_finfo.fi_nfiles ?
 202     curthread->t_procp->p_user.u_finfo.fi_list[fd].uf_file : NULL);
 203 
 204 #pragma D attributes Stable/Stable/Common fds
 205 #pragma D binding "1.1" fds
 206 
 207 #pragma D binding "1.2" translator
 208 translator 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 };