procfs.c revision 166548
1139776Simp/*- 287321Sdes * Copyright (c) 2001 Dag-Erling Sm�rgrav 387321Sdes * Copyright (c) 1993 Jan-Simon Pendry 487321Sdes * Copyright (c) 1993 587321Sdes * The Regents of the University of California. All rights reserved. 687321Sdes * 787321Sdes * This code is derived from software contributed to Berkeley by 887321Sdes * Jan-Simon Pendry. 987321Sdes * 1087321Sdes * Redistribution and use in source and binary forms, with or without 1187321Sdes * modification, are permitted provided that the following conditions 1287321Sdes * are met: 1387321Sdes * 1. Redistributions of source code must retain the above copyright 1487321Sdes * notice, this list of conditions and the following disclaimer. 1587321Sdes * 2. Redistributions in binary form must reproduce the above copyright 1687321Sdes * notice, this list of conditions and the following disclaimer in the 1787321Sdes * documentation and/or other materials provided with the distribution. 1887321Sdes * 3. All advertising materials mentioning features or use of this software 1987321Sdes * must display the following acknowledgement: 2087321Sdes * This product includes software developed by the University of 2187321Sdes * California, Berkeley and its contributors. 2287321Sdes * 4. Neither the name of the University nor the names of its contributors 2387321Sdes * may be used to endorse or promote products derived from this software 2487321Sdes * without specific prior written permission. 2587321Sdes * 2687321Sdes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2787321Sdes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2887321Sdes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2987321Sdes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 3087321Sdes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 3187321Sdes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 3287321Sdes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3387321Sdes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 3487321Sdes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3587321Sdes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3687321Sdes * SUCH DAMAGE. 3787321Sdes * 3887321Sdes * @(#)procfs_vfsops.c 8.7 (Berkeley) 5/10/95 3987321Sdes * 4087321Sdes * $FreeBSD: head/sys/fs/procfs/procfs.c 166548 2007-02-07 10:30:49Z kib $ 4187321Sdes */ 4287321Sdes 4387321Sdes#include <sys/param.h> 4487321Sdes#include <sys/queue.h> 4587321Sdes#include <sys/exec.h> 4687321Sdes#include <sys/lock.h> 4787321Sdes#include <sys/kernel.h> 4887321Sdes#include <sys/malloc.h> 4987321Sdes#include <sys/mount.h> 5087321Sdes#include <sys/mutex.h> 5187321Sdes#include <sys/proc.h> 5287321Sdes#include <sys/sbuf.h> 5387321Sdes#include <sys/sysproto.h> 5487321Sdes#include <sys/systm.h> 5587321Sdes#include <sys/vnode.h> 5687321Sdes 5787321Sdes#include <vm/vm.h> 5887321Sdes#include <vm/pmap.h> 5987321Sdes#include <vm/vm_param.h> 6087321Sdes 6187321Sdes#include <fs/pseudofs/pseudofs.h> 6287321Sdes#include <fs/procfs/procfs.h> 6387321Sdes 6487321Sdes/* 6587321Sdes * Filler function for proc/pid/self 6687321Sdes */ 6787538Sdesint 6887321Sdesprocfs_doprocfile(PFS_FILL_ARGS) 6987321Sdes{ 7087321Sdes char *fullpath = "unknown"; 7187321Sdes char *freepath = NULL; 72166548Skib struct vnode *textvp; 73166548Skib int err; 7487321Sdes 75166548Skib textvp = p->p_textvp; 76166548Skib VI_LOCK(textvp); 77166548Skib vholdl(textvp); 78166548Skib err = vn_lock(textvp, LK_EXCLUSIVE | LK_INTERLOCK, td); 79166548Skib vdrop(textvp); 80166548Skib if (err) 81166548Skib return (err); 82166548Skib vn_fullpath(td, textvp, &fullpath, &freepath); 83166548Skib VOP_UNLOCK(textvp, 0, td); 8487321Sdes sbuf_printf(sb, "%s", fullpath); 8587321Sdes if (freepath) 8687321Sdes free(freepath, M_TEMP); 8787321Sdes return (0); 8887321Sdes} 8987321Sdes 9087321Sdes/* 9187321Sdes * Filler function for proc/curproc 9287321Sdes */ 9387538Sdesint 9487321Sdesprocfs_docurproc(PFS_FILL_ARGS) 9587321Sdes{ 9687321Sdes sbuf_printf(sb, "%ld", (long)td->td_proc->p_pid); 9787321Sdes return (0); 9887321Sdes} 9987321Sdes 10087321Sdes/* 10187321Sdes * Adjust mode for some nodes that need it 10287321Sdes */ 10387321Sdesint 10487321Sdesprocfs_attr(PFS_ATTR_ARGS) 10587321Sdes{ 106113617Sjhb PROC_LOCK_ASSERT(p, MA_OWNED); 107113617Sjhb 10887321Sdes /* XXX inefficient, split into separate functions */ 109159283Sghelmer if (strcmp(pn->pn_name, "ctl") == 0 || 11087321Sdes strcmp(pn->pn_name, "note") == 0 || 11187321Sdes strcmp(pn->pn_name, "notepg") == 0) 11287321Sdes vap->va_mode = 0200; 11387321Sdes else if (strcmp(pn->pn_name, "mem") == 0 || 11487321Sdes strcmp(pn->pn_name, "regs") == 0 || 11587321Sdes strcmp(pn->pn_name, "dbregs") == 0 || 11687321Sdes strcmp(pn->pn_name, "fpregs") == 0) 11787321Sdes vap->va_mode = 0600; 11887321Sdes 119159283Sghelmer if ((p->p_flag & P_SUGID) && pn->pn_type != pfstype_procdir) 120159283Sghelmer vap->va_mode = 0; 121159283Sghelmer 12287321Sdes vap->va_uid = p->p_ucred->cr_uid; 12387321Sdes vap->va_gid = p->p_ucred->cr_gid; 124123247Sdes 12587321Sdes return (0); 12687321Sdes} 12787321Sdes 12887321Sdes/* 12987321Sdes * Visibility: some files only exist for non-system processes 13087321Sdes * Non-static because linprocfs uses it. 13187321Sdes */ 13287321Sdesint 13387321Sdesprocfs_notsystem(PFS_VIS_ARGS) 13487321Sdes{ 135113617Sjhb PROC_LOCK_ASSERT(p, MA_OWNED); 13687321Sdes return ((p->p_flag & P_SYSTEM) == 0); 13787321Sdes} 13887321Sdes 13987321Sdes/* 14087321Sdes * Visibility: some files are only visible to process that can debug 14187321Sdes * the target process. 14287321Sdes */ 14387321Sdesint 14487321Sdesprocfs_candebug(PFS_VIS_ARGS) 14587321Sdes{ 14696886Sjhb PROC_LOCK_ASSERT(p, MA_OWNED); 147123247Sdes return ((p->p_flag & P_SYSTEM) == 0 && p_candebug(td, p) == 0); 14887321Sdes} 14987321Sdes 15087321Sdes/* 15187321Sdes * Constructor 15287321Sdes */ 15387321Sdesstatic int 15487321Sdesprocfs_init(PFS_INIT_ARGS) 15587321Sdes{ 15687321Sdes struct pfs_node *root; 15787321Sdes struct pfs_node *dir; 15887321Sdes struct pfs_node *node; 15987321Sdes 16087321Sdes root = pi->pi_root; 16187321Sdes 162105560Sphk pfs_create_link(root, "curproc", procfs_docurproc, 16387321Sdes NULL, NULL, 0); 164123247Sdes 16587321Sdes dir = pfs_create_dir(root, "pid", 166105560Sphk procfs_attr, NULL, PFS_PROCDEP); 167105560Sphk pfs_create_file(dir, "cmdline", procfs_doproccmdline, 16887321Sdes NULL, NULL, PFS_RD); 169105560Sphk pfs_create_file(dir, "ctl", procfs_doprocctl, 170105560Sphk procfs_attr, NULL, PFS_WR); 171105560Sphk pfs_create_file(dir, "dbregs", procfs_doprocdbregs, 172105560Sphk procfs_attr, procfs_candebug, PFS_RDWR|PFS_RAW); 173105560Sphk pfs_create_file(dir, "etype", procfs_doproctype, 17487321Sdes NULL, NULL, PFS_RD); 175105560Sphk pfs_create_file(dir, "fpregs", procfs_doprocfpregs, 176105560Sphk procfs_attr, procfs_candebug, PFS_RDWR|PFS_RAW); 177105560Sphk pfs_create_file(dir, "map", procfs_doprocmap, 178105560Sphk NULL, procfs_notsystem, PFS_RD); 179105560Sphk node = pfs_create_file(dir, "mem", procfs_doprocmem, 180105560Sphk procfs_attr, procfs_candebug, PFS_RDWR|PFS_RAW); 181105560Sphk node->pn_ioctl = procfs_ioctl; 182105560Sphk node->pn_close = procfs_close; 183105560Sphk pfs_create_file(dir, "note", procfs_doprocnote, 184105560Sphk procfs_attr, procfs_candebug, PFS_WR); 185105560Sphk pfs_create_file(dir, "notepg", procfs_doprocnote, 186105560Sphk procfs_attr, procfs_candebug, PFS_WR); 187105560Sphk pfs_create_file(dir, "regs", procfs_doprocregs, 188105560Sphk procfs_attr, procfs_candebug, PFS_RDWR|PFS_RAW); 189105560Sphk pfs_create_file(dir, "rlimit", procfs_doprocrlimit, 19087321Sdes NULL, NULL, PFS_RD); 191105560Sphk pfs_create_file(dir, "status", procfs_doprocstatus, 19287321Sdes NULL, NULL, PFS_RD); 193123247Sdes 194105560Sphk pfs_create_link(dir, "file", procfs_doprocfile, 19587321Sdes NULL, procfs_notsystem, 0); 196123247Sdes 19787321Sdes return (0); 19887321Sdes} 19987321Sdes 20087321Sdes/* 20187321Sdes * Destructor 20287321Sdes */ 20387321Sdesstatic int 20487321Sdesprocfs_uninit(PFS_INIT_ARGS) 20587321Sdes{ 20687321Sdes /* nothing to do, pseudofs will GC */ 20787321Sdes return (0); 20887321Sdes} 20987321Sdes 21087321SdesPSEUDOFS(procfs, 1); 211