1*0daf62d9SStanislav Sedov /*- 2*0daf62d9SStanislav Sedov * Copyright (c) 2009 Stanislav Sedov <stas@FreeBSD.org> 3*0daf62d9SStanislav Sedov * Copyright (c) 1988, 1993 4*0daf62d9SStanislav Sedov * The Regents of the University of California. All rights reserved. 5*0daf62d9SStanislav Sedov * 6*0daf62d9SStanislav Sedov * Redistribution and use in source and binary forms, with or without 7*0daf62d9SStanislav Sedov * modification, are permitted provided that the following conditions 8*0daf62d9SStanislav Sedov * are met: 9*0daf62d9SStanislav Sedov * 1. Redistributions of source code must retain the above copyright 10*0daf62d9SStanislav Sedov * notice, this list of conditions and the following disclaimer. 11*0daf62d9SStanislav Sedov * 2. Redistributions in binary form must reproduce the above copyright 12*0daf62d9SStanislav Sedov * notice, this list of conditions and the following disclaimer in the 13*0daf62d9SStanislav Sedov * documentation and/or other materials provided with the distribution. 14*0daf62d9SStanislav Sedov * 3. All advertising materials mentioning features or use of this software 15*0daf62d9SStanislav Sedov * must display the following acknowledgement: 16*0daf62d9SStanislav Sedov * This product includes software developed by the University of 17*0daf62d9SStanislav Sedov * California, Berkeley and its contributors. 18*0daf62d9SStanislav Sedov * 4. Neither the name of the University nor the names of its contributors 19*0daf62d9SStanislav Sedov * may be used to endorse or promote products derived from this software 20*0daf62d9SStanislav Sedov * without specific prior written permission. 21*0daf62d9SStanislav Sedov * 22*0daf62d9SStanislav Sedov * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23*0daf62d9SStanislav Sedov * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24*0daf62d9SStanislav Sedov * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25*0daf62d9SStanislav Sedov * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26*0daf62d9SStanislav Sedov * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27*0daf62d9SStanislav Sedov * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28*0daf62d9SStanislav Sedov * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29*0daf62d9SStanislav Sedov * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30*0daf62d9SStanislav Sedov * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31*0daf62d9SStanislav Sedov * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32*0daf62d9SStanislav Sedov * SUCH DAMAGE. 33*0daf62d9SStanislav Sedov */ 34*0daf62d9SStanislav Sedov 35*0daf62d9SStanislav Sedov #include <sys/cdefs.h> 36*0daf62d9SStanislav Sedov __FBSDID("$FreeBSD$"); 37*0daf62d9SStanislav Sedov 38*0daf62d9SStanislav Sedov #include <sys/param.h> 39*0daf62d9SStanislav Sedov #include <sys/user.h> 40*0daf62d9SStanislav Sedov #include <sys/stat.h> 41*0daf62d9SStanislav Sedov #include <sys/vnode.h> 42*0daf62d9SStanislav Sedov #include <sys/conf.h> 43*0daf62d9SStanislav Sedov #define _KERNEL 44*0daf62d9SStanislav Sedov #include <sys/pipe.h> 45*0daf62d9SStanislav Sedov #include <sys/mount.h> 46*0daf62d9SStanislav Sedov #include <ufs/ufs/quota.h> 47*0daf62d9SStanislav Sedov #include <ufs/ufs/inode.h> 48*0daf62d9SStanislav Sedov #include <fs/devfs/devfs.h> 49*0daf62d9SStanislav Sedov #include <fs/devfs/devfs_int.h> 50*0daf62d9SStanislav Sedov #undef _KERNEL 51*0daf62d9SStanislav Sedov #include <nfs/nfsproto.h> 52*0daf62d9SStanislav Sedov #include <nfsclient/nfs.h> 53*0daf62d9SStanislav Sedov #include <nfsclient/nfsnode.h> 54*0daf62d9SStanislav Sedov 55*0daf62d9SStanislav Sedov #include <assert.h> 56*0daf62d9SStanislav Sedov #include <err.h> 57*0daf62d9SStanislav Sedov #include <kvm.h> 58*0daf62d9SStanislav Sedov #include <stddef.h> 59*0daf62d9SStanislav Sedov #include <string.h> 60*0daf62d9SStanislav Sedov 61*0daf62d9SStanislav Sedov #include <libprocstat.h> 62*0daf62d9SStanislav Sedov #include "common_kvm.h" 63*0daf62d9SStanislav Sedov 64*0daf62d9SStanislav Sedov int 65*0daf62d9SStanislav Sedov kvm_read_all(kvm_t *kd, unsigned long addr, void *buf, size_t nbytes) 66*0daf62d9SStanislav Sedov { 67*0daf62d9SStanislav Sedov ssize_t error; 68*0daf62d9SStanislav Sedov 69*0daf62d9SStanislav Sedov if (nbytes >= SSIZE_MAX) 70*0daf62d9SStanislav Sedov return (0); 71*0daf62d9SStanislav Sedov error = kvm_read(kd, addr, buf, nbytes); 72*0daf62d9SStanislav Sedov return (error == (ssize_t)(nbytes)); 73*0daf62d9SStanislav Sedov } 74*0daf62d9SStanislav Sedov 75*0daf62d9SStanislav Sedov int 76*0daf62d9SStanislav Sedov kdevtoname(kvm_t *kd, struct cdev *dev, char *buf) 77*0daf62d9SStanislav Sedov { 78*0daf62d9SStanislav Sedov struct cdev si; 79*0daf62d9SStanislav Sedov 80*0daf62d9SStanislav Sedov assert(buf); 81*0daf62d9SStanislav Sedov if (!kvm_read_all(kd, (unsigned long)dev, &si, sizeof(si))) 82*0daf62d9SStanislav Sedov return (1); 83*0daf62d9SStanislav Sedov strlcpy(buf, si.__si_namebuf, SPECNAMELEN + 1); 84*0daf62d9SStanislav Sedov return (0); 85*0daf62d9SStanislav Sedov } 86*0daf62d9SStanislav Sedov 87*0daf62d9SStanislav Sedov int 88*0daf62d9SStanislav Sedov ufs_filestat(kvm_t *kd, struct vnode *vp, struct vnstat *vn) 89*0daf62d9SStanislav Sedov { 90*0daf62d9SStanislav Sedov struct inode inode; 91*0daf62d9SStanislav Sedov 92*0daf62d9SStanislav Sedov if (!kvm_read_all(kd, (unsigned long)VTOI(vp), &inode, sizeof(inode))) { 93*0daf62d9SStanislav Sedov warnx("can't read inode at %p", (void *)VTOI(vp)); 94*0daf62d9SStanislav Sedov return (1); 95*0daf62d9SStanislav Sedov } 96*0daf62d9SStanislav Sedov /* 97*0daf62d9SStanislav Sedov * The st_dev from stat(2) is a dev_t. These kernel structures 98*0daf62d9SStanislav Sedov * contain cdev pointers. We need to convert to dev_t to make 99*0daf62d9SStanislav Sedov * comparisons 100*0daf62d9SStanislav Sedov */ 101*0daf62d9SStanislav Sedov vn->vn_fsid = dev2udev(kd, inode.i_dev); 102*0daf62d9SStanislav Sedov vn->vn_fileid = (long)inode.i_number; 103*0daf62d9SStanislav Sedov vn->vn_mode = (mode_t)inode.i_mode; 104*0daf62d9SStanislav Sedov vn->vn_size = (u_long)inode.i_size; 105*0daf62d9SStanislav Sedov return (0); 106*0daf62d9SStanislav Sedov } 107*0daf62d9SStanislav Sedov 108*0daf62d9SStanislav Sedov int 109*0daf62d9SStanislav Sedov devfs_filestat(kvm_t *kd, struct vnode *vp, struct vnstat *vn) 110*0daf62d9SStanislav Sedov { 111*0daf62d9SStanislav Sedov struct devfs_dirent devfs_dirent; 112*0daf62d9SStanislav Sedov struct mount mount; 113*0daf62d9SStanislav Sedov 114*0daf62d9SStanislav Sedov if (!kvm_read_all(kd, (unsigned long)getvnodedata(vp), &devfs_dirent, 115*0daf62d9SStanislav Sedov sizeof(devfs_dirent))) { 116*0daf62d9SStanislav Sedov warnx("can't read devfs_dirent at %p", 117*0daf62d9SStanislav Sedov (void *)vp->v_data); 118*0daf62d9SStanislav Sedov return (1); 119*0daf62d9SStanislav Sedov } 120*0daf62d9SStanislav Sedov if (!kvm_read_all(kd, (unsigned long)getvnodemount(vp), &mount, 121*0daf62d9SStanislav Sedov sizeof(mount))) { 122*0daf62d9SStanislav Sedov warnx("can't read mount at %p", 123*0daf62d9SStanislav Sedov (void *)getvnodemount(vp)); 124*0daf62d9SStanislav Sedov return (1); 125*0daf62d9SStanislav Sedov } 126*0daf62d9SStanislav Sedov vn->vn_fsid = mount.mnt_stat.f_fsid.val[0]; 127*0daf62d9SStanislav Sedov vn->vn_fileid = devfs_dirent.de_inode; 128*0daf62d9SStanislav Sedov vn->vn_mode = (devfs_dirent.de_mode & ~S_IFMT) | S_IFCHR; 129*0daf62d9SStanislav Sedov vn->vn_size = 0; 130*0daf62d9SStanislav Sedov return (0); 131*0daf62d9SStanislav Sedov } 132*0daf62d9SStanislav Sedov 133*0daf62d9SStanislav Sedov int 134*0daf62d9SStanislav Sedov nfs_filestat(kvm_t *kd, struct vnode *vp, struct vnstat *vn) 135*0daf62d9SStanislav Sedov { 136*0daf62d9SStanislav Sedov struct nfsnode nfsnode; 137*0daf62d9SStanislav Sedov mode_t mode; 138*0daf62d9SStanislav Sedov 139*0daf62d9SStanislav Sedov if (!kvm_read_all(kd, (unsigned long)VTONFS(vp), &nfsnode, 140*0daf62d9SStanislav Sedov sizeof(nfsnode))) { 141*0daf62d9SStanislav Sedov warnx("can't read nfsnode at %p", 142*0daf62d9SStanislav Sedov (void *)VTONFS(vp)); 143*0daf62d9SStanislav Sedov return (1); 144*0daf62d9SStanislav Sedov } 145*0daf62d9SStanislav Sedov vn->vn_fsid = nfsnode.n_vattr.va_fsid; 146*0daf62d9SStanislav Sedov vn->vn_fileid = nfsnode.n_vattr.va_fileid; 147*0daf62d9SStanislav Sedov vn->vn_size = nfsnode.n_size; 148*0daf62d9SStanislav Sedov mode = (mode_t)nfsnode.n_vattr.va_mode; 149*0daf62d9SStanislav Sedov switch (vp->v_type) { 150*0daf62d9SStanislav Sedov case VREG: 151*0daf62d9SStanislav Sedov mode |= S_IFREG; 152*0daf62d9SStanislav Sedov break; 153*0daf62d9SStanislav Sedov case VDIR: 154*0daf62d9SStanislav Sedov mode |= S_IFDIR; 155*0daf62d9SStanislav Sedov break; 156*0daf62d9SStanislav Sedov case VBLK: 157*0daf62d9SStanislav Sedov mode |= S_IFBLK; 158*0daf62d9SStanislav Sedov break; 159*0daf62d9SStanislav Sedov case VCHR: 160*0daf62d9SStanislav Sedov mode |= S_IFCHR; 161*0daf62d9SStanislav Sedov break; 162*0daf62d9SStanislav Sedov case VLNK: 163*0daf62d9SStanislav Sedov mode |= S_IFLNK; 164*0daf62d9SStanislav Sedov break; 165*0daf62d9SStanislav Sedov case VSOCK: 166*0daf62d9SStanislav Sedov mode |= S_IFSOCK; 167*0daf62d9SStanislav Sedov break; 168*0daf62d9SStanislav Sedov case VFIFO: 169*0daf62d9SStanislav Sedov mode |= S_IFIFO; 170*0daf62d9SStanislav Sedov break; 171*0daf62d9SStanislav Sedov default: 172*0daf62d9SStanislav Sedov break; 173*0daf62d9SStanislav Sedov }; 174*0daf62d9SStanislav Sedov vn->vn_mode = mode; 175*0daf62d9SStanislav Sedov return (0); 176*0daf62d9SStanislav Sedov } 177*0daf62d9SStanislav Sedov 178*0daf62d9SStanislav Sedov /* 179*0daf62d9SStanislav Sedov * Read the cdev structure in the kernel in order to work out the 180*0daf62d9SStanislav Sedov * associated dev_t 181*0daf62d9SStanislav Sedov */ 182*0daf62d9SStanislav Sedov dev_t 183*0daf62d9SStanislav Sedov dev2udev(kvm_t *kd, struct cdev *dev) 184*0daf62d9SStanislav Sedov { 185*0daf62d9SStanislav Sedov struct cdev_priv priv; 186*0daf62d9SStanislav Sedov 187*0daf62d9SStanislav Sedov assert(kd); 188*0daf62d9SStanislav Sedov if (kvm_read_all(kd, (unsigned long)cdev2priv(dev), &priv, 189*0daf62d9SStanislav Sedov sizeof(priv))) { 190*0daf62d9SStanislav Sedov return ((dev_t)priv.cdp_inode); 191*0daf62d9SStanislav Sedov } else { 192*0daf62d9SStanislav Sedov warnx("can't convert cdev *%p to a dev_t\n", dev); 193*0daf62d9SStanislav Sedov return (-1); 194*0daf62d9SStanislav Sedov } 195*0daf62d9SStanislav Sedov } 196*0daf62d9SStanislav Sedov 197*0daf62d9SStanislav Sedov void * 198*0daf62d9SStanislav Sedov getvnodedata(struct vnode *vp) 199*0daf62d9SStanislav Sedov { 200*0daf62d9SStanislav Sedov return (vp->v_data); 201*0daf62d9SStanislav Sedov } 202*0daf62d9SStanislav Sedov 203*0daf62d9SStanislav Sedov struct mount * 204*0daf62d9SStanislav Sedov getvnodemount(struct vnode *vp) 205*0daf62d9SStanislav Sedov { 206*0daf62d9SStanislav Sedov return (vp->v_mount); 207*0daf62d9SStanislav Sedov } 208