diff options
author | Philip Guenther <guenther@cvs.openbsd.org> | 2014-09-08 01:57:01 +0000 |
---|---|---|
committer | Philip Guenther <guenther@cvs.openbsd.org> | 2014-09-08 01:57:01 +0000 |
commit | 9279e2c961d9a4c29af849c66feb8087e377c1b7 (patch) | |
tree | 43e6497dfcacf47b9d7f0ed73a8ac77806d4228f /sys/miscfs | |
parent | 4c6be48bddde1bbe2127d982ef75c5a73d0e3d5b (diff) |
Actually remove the procfs files
Diffstat (limited to 'sys/miscfs')
-rw-r--r-- | sys/miscfs/procfs/procfs.h | 135 | ||||
-rw-r--r-- | sys/miscfs/procfs/procfs_cmdline.c | 186 | ||||
-rw-r--r-- | sys/miscfs/procfs/procfs_linux.c | 133 | ||||
-rw-r--r-- | sys/miscfs/procfs/procfs_status.c | 172 | ||||
-rw-r--r-- | sys/miscfs/procfs/procfs_subr.c | 284 | ||||
-rw-r--r-- | sys/miscfs/procfs/procfs_vfsops.c | 219 | ||||
-rw-r--r-- | sys/miscfs/procfs/procfs_vnops.c | 992 |
7 files changed, 0 insertions, 2121 deletions
diff --git a/sys/miscfs/procfs/procfs.h b/sys/miscfs/procfs/procfs.h deleted file mode 100644 index 9c091446323..00000000000 --- a/sys/miscfs/procfs/procfs.h +++ /dev/null @@ -1,135 +0,0 @@ -/* $OpenBSD: procfs.h,v 1.28 2011/12/24 04:34:20 guenther Exp $ */ -/* $NetBSD: procfs.h,v 1.17 1996/02/12 15:01:41 christos Exp $ */ - -/* - * Copyright (c) 1993 Jan-Simon Pendry - * Copyright (c) 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Jan-Simon Pendry. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)procfs.h 8.7 (Berkeley) 6/15/94 - */ - -/* - * The different types of node in a procfs filesystem - */ -typedef enum { - Proot, /* the filesystem root */ - Pcurproc, /* symbolic link for curproc */ - Pself, /* like curproc, but this is the Linux name */ - Pproc, /* a process-specific sub-directory */ - Pfile, /* the executable file */ - Pmem, /* the process's memory image */ - Pregs, /* the process's register set */ - Pfpregs, /* the process's FP register set */ - Pctl, /* process control */ - Pstatus, /* process status */ - Pnote, /* process notifier */ - Pnotepg, /* process group notifier */ - Pcmdline, /* process command line args */ - Pmeminfo, /* system memory info (if -o linux) */ - Pcpuinfo /* CPU info (if -o linux) */ -} pfstype; - -/* - * control data for the proc file system. - */ -struct pfsnode { - TAILQ_ENTRY(pfsnode) list; - struct vnode *pfs_vnode; /* vnode associated with this pfsnode */ - pfstype pfs_type; /* type of procfs node */ - pid_t pfs_pid; /* associated process */ - mode_t pfs_mode; /* mode bits for stat() */ - u_long pfs_flags; /* open flags */ - u_long pfs_fileno; /* unique file id */ -}; - -/* - * Kernel stuff follows - */ -#ifdef _KERNEL -#define CNEQ(cnp, s, len) \ - ((cnp)->cn_namelen == (len) && \ - (bcmp((s), (cnp)->cn_nameptr, (len)) == 0)) - -#define UIO_MX 32 - -#define PROCFS_FILENO(pid, type) \ - (((type) < Pproc) ? \ - ((type) + 4) : \ - ((((pid)+1) << 5) + ((int) (type)))) - -struct procfsmount { - void *pmnt_exechook; - int pmnt_flags; -}; - -#define VFSTOPROC(mp) ((struct procfsmount *)(mp)->mnt_data) - -/* - * Convert between pfsnode vnode - */ -#define VTOPFS(vp) ((struct pfsnode *)(vp)->v_data) -#define PFSTOV(pfs) ((pfs)->pfs_vnode) - -typedef struct vfs_namemap vfs_namemap_t; -struct vfs_namemap { - const char *nm_name; - int nm_val; -}; - -int vfs_getuserstr(struct uio *, char *, int *); -const vfs_namemap_t *vfs_findname(const vfs_namemap_t *, char *, int); - -int procfs_allocvp(struct mount *, struct vnode **, pid_t, pfstype); -int procfs_dostatus(struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio); -int procfs_docmdline(struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio); -int procfs_domeminfo(struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio); -int procfs_docpuinfo(struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio); -int procfs_freevp(struct vnode *); -int procfs_getcpuinfstr(char *, int *); -int procfs_poll(void *); - -/* functions to check whether or not files should be displayed */ -int procfs_validfile(struct proc *, struct mount *); - -int procfs_rw(void *); - -#define PROCFS_LOCKED 0x01 -#define PROCFS_WANT 0x02 - -extern struct vops procfs_vops; -extern const struct vfsops procfs_vfsops; - -struct vfsconf; - -int procfs_init(struct vfsconf *); -int procfs_root(struct mount *, struct vnode **); - -#endif /* _KERNEL */ diff --git a/sys/miscfs/procfs/procfs_cmdline.c b/sys/miscfs/procfs/procfs_cmdline.c deleted file mode 100644 index ccfed62ebc3..00000000000 --- a/sys/miscfs/procfs/procfs_cmdline.c +++ /dev/null @@ -1,186 +0,0 @@ -/* $OpenBSD: procfs_cmdline.c,v 1.13 2014/07/12 18:43:52 tedu Exp $ */ -/* $NetBSD: procfs_cmdline.c,v 1.3 1999/03/13 22:26:48 thorpej Exp $ */ - -/* - * Copyright (c) 1999 Jaromir Dolecek <dolecek@ics.muni.cz> - * Copyright (c) 1999 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Jaromir Dolecek. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include <sys/param.h> -#include <sys/types.h> -#include <sys/systm.h> -#include <sys/syslimits.h> -#include <sys/proc.h> -#include <sys/vnode.h> -#include <sys/exec.h> -#include <sys/malloc.h> -#include <miscfs/procfs/procfs.h> - -/* - * code for returning process's command line arguments - */ -int -procfs_docmdline(struct proc *curp, struct proc *p, struct pfsnode *pfs, struct uio *uio) -{ - struct process *pr = p->p_p; - struct ps_strings pss; - int count, error, i; - size_t len, xlen, upper_bound; - struct uio auio; - struct iovec aiov; - struct vmspace *vm; - vaddr_t argv; - char *arg; - - /* Don't allow writing. */ - if (uio->uio_rw != UIO_READ) - return (EOPNOTSUPP); - - /* - * Allocate a temporary buffer to hold the arguments. - */ - arg = malloc(PAGE_SIZE, M_TEMP, M_WAITOK); - - /* - * Zombies don't have a stack, so we can't read their psstrings. - * System processes also don't have a user stack. This is what - * ps(1) would display. - */ - if (pr->ps_flags & (PS_ZOMBIE | PS_SYSTEM)) { - len = snprintf(arg, PAGE_SIZE, "(%s)", p->p_comm); - if (uio->uio_offset >= (off_t)len) - error = 0; - else - error = uiomove(arg, len - uio->uio_offset, uio); - - free(arg, M_TEMP, 0); - return (error); - } - - /* - * NOTE: Don't bother doing a process_checkioperm() here - * because the psstrings info is available by using ps(1), - * so it's not like there's anything to protect here. - */ - - /* - * Lock the process down in memory. - */ - /* XXXCDC: how should locking work here? */ - if ((pr->ps_flags & PS_EXITING) || (pr->ps_vmspace->vm_refcnt < 1)) { - free(arg, M_TEMP, 0); - return (EFAULT); - } - vm = pr->ps_vmspace; - vm->vm_refcnt++; /* XXX */ - - /* - * Read in the ps_strings structure. - */ - aiov.iov_base = &pss; - aiov.iov_len = sizeof(pss); - auio.uio_iov = &aiov; - auio.uio_iovcnt = 1; - auio.uio_offset = (vaddr_t)PS_STRINGS; - auio.uio_resid = sizeof(pss); - auio.uio_segflg = UIO_SYSSPACE; - auio.uio_rw = UIO_READ; - auio.uio_procp = NULL; - error = uvm_io(&vm->vm_map, &auio, 0); - if (error) - goto bad; - - /* - * Now read the address of the argument vector. - */ - aiov.iov_base = &argv; - aiov.iov_len = sizeof(argv); - auio.uio_iov = &aiov; - auio.uio_iovcnt = 1; - auio.uio_offset = (vaddr_t)pss.ps_argvstr; - auio.uio_resid = sizeof(argv); - auio.uio_segflg = UIO_SYSSPACE; - auio.uio_rw = UIO_READ; - auio.uio_procp = NULL; - error = uvm_io(&vm->vm_map, &auio, 0); - if (error) - goto bad; - - /* - * Now copy in the actual argument vector, one byte at a time, - * since we don't know how long the vector is (though, we do - * know how many NUL-terminated strings are in the vector). - */ - len = 0; - count = pss.ps_nargvstr; - upper_bound = round_page(uio->uio_offset + uio->uio_resid); - for (; count && len < upper_bound; len += xlen) { - aiov.iov_base = arg; - aiov.iov_len = PAGE_SIZE; - auio.uio_iov = &aiov; - auio.uio_iovcnt = 1; - auio.uio_offset = argv + len; - xlen = PAGE_SIZE - ((argv + len) & PAGE_MASK); - auio.uio_resid = xlen; - auio.uio_segflg = UIO_SYSSPACE; - auio.uio_rw = UIO_READ; - auio.uio_procp = NULL; - error = uvm_io(&vm->vm_map, &auio, 0); - if (error) - goto bad; - - for (i = 0; i < xlen && count != 0; i++) { - if (arg[i] == '\0') - count--; /* one full string */ - } - - if (count == 0) - i--; /* exclude the final NUL */ - - if (len + i > uio->uio_offset) { - /* Have data in this page, copy it out */ - error = uiomove(arg + uio->uio_offset - len, - i + len - uio->uio_offset, uio); - if (error || uio->uio_resid <= 0) - break; - } - } - - - bad: - uvmspace_free(vm); - free(arg, M_TEMP, 0); - return (error); -} diff --git a/sys/miscfs/procfs/procfs_linux.c b/sys/miscfs/procfs/procfs_linux.c deleted file mode 100644 index 5480072e037..00000000000 --- a/sys/miscfs/procfs/procfs_linux.c +++ /dev/null @@ -1,133 +0,0 @@ -/* $OpenBSD: procfs_linux.c,v 1.9 2014/07/08 17:19:25 deraadt Exp $ */ -/* $NetBSD: procfs_linux.c,v 1.2.4.1 2001/03/30 21:48:11 he Exp $ */ - -/* - * Copyright (c) 2001 Wasabi Systems, Inc. - * All rights reserved. - * - * Written by Frank van der Linden for Wasabi Systems, Inc. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed for the NetBSD Project by - * Wasabi Systems, Inc. - * 4. The name of Wasabi Systems, Inc. may not be used to endorse - * or promote products derived from this software without specific prior - * written permission. - * - * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/time.h> -#include <sys/kernel.h> -#include <sys/proc.h> -#include <sys/vnode.h> - -#include <miscfs/procfs/procfs.h> - -#define PGTOB(p) ((unsigned long)(p) << PAGE_SHIFT) -#define PGTOKB(p) ((unsigned long)(p) << (PAGE_SHIFT - 10)) - -/* - * Linux compatible /proc/meminfo. Only active when the -o linux - * mountflag is used. - */ -int -procfs_domeminfo(struct proc *curp, struct proc *p, struct pfsnode *pfs, - struct uio *uio) -{ - char buf[512], *cp; - int len, error; - - len = snprintf(buf, sizeof buf, - " total: used: free: shared: buffers: cached:\n" - "Mem: %8lu %8lu %8lu %8lu %8lu %8lu\n" - "Swap: %8lu %8lu %8lu\n" - "MemTotal: %8lu kB\n" - "MemFree: %8lu kB\n" - "MemShared: %8lu kB\n" - "Buffers: %8lu kB\n" - "Cached: %8lu kB\n" - "SwapTotal: %8lu kB\n" - "SwapFree: %8lu kB\n", - PGTOB(uvmexp.npages), - PGTOB(uvmexp.npages - uvmexp.free), - PGTOB(uvmexp.free), - 0L, - 0L, - 0L, - PGTOB(uvmexp.swpages), - PGTOB(uvmexp.swpginuse), - PGTOB(uvmexp.swpages - uvmexp.swpginuse), - PGTOKB(uvmexp.npages), - PGTOKB(uvmexp.free), - 0L, - 0L, - 0L, - PGTOKB(uvmexp.swpages), - PGTOKB(uvmexp.swpages - uvmexp.swpginuse)); - - if (len <= 0 || len >= sizeof buf || - len < uio->uio_offset || uio->uio_resid == 0) - return EINVAL; - - len -= uio->uio_offset; - cp = buf + uio->uio_offset; - len = imin(len, uio->uio_resid); - error = uiomove(cp, len, uio); - return error; -} - -int -procfs_docpuinfo(struct proc *curp, struct proc *p, struct pfsnode *pfs, - struct uio *uio) -{ - char buf[512], *cp; - int len, error; - - len = sizeof buf; - if (procfs_getcpuinfstr(buf, &len) < 0) - return EIO; - - if (len == 0 || uio->uio_offset > sizeof(buf)) - return 0; - - len -= uio->uio_offset; - cp = buf + uio->uio_offset; - len = imin(len, uio->uio_resid); - if (len <= 0) - error = 0; - else - error = uiomove(cp, len, uio); - return error; -} - -#ifndef __i386__ -int -procfs_getcpuinfstr(char *buf, int *len) -{ - *len = 0; - - return 0; -} -#endif diff --git a/sys/miscfs/procfs/procfs_status.c b/sys/miscfs/procfs/procfs_status.c deleted file mode 100644 index 3596141ee8d..00000000000 --- a/sys/miscfs/procfs/procfs_status.c +++ /dev/null @@ -1,172 +0,0 @@ -/* $OpenBSD: procfs_status.c,v 1.16 2014/07/12 18:43:52 tedu Exp $ */ -/* $NetBSD: procfs_status.c,v 1.11 1996/03/16 23:52:50 christos Exp $ */ - -/* - * Copyright (c) 1993 Jan-Simon Pendry - * Copyright (c) 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Jan-Simon Pendry. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)procfs_status.c 8.4 (Berkeley) 6/15/94 - */ - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/time.h> -#include <sys/kernel.h> -#include <sys/malloc.h> -#include <sys/proc.h> -#include <sys/vnode.h> -#include <sys/ioctl.h> -#include <sys/tty.h> -#include <sys/resource.h> -#include <sys/resourcevar.h> -#include <miscfs/procfs/procfs.h> - -int procfs_stat_gen(struct proc *, char *s, int); - -#define COUNTORCAT(s, l, ps, n) do { \ - if (s) \ - strlcat(s, ps, l); \ - else \ - n += strlen(ps); \ - } while (0) - -/* Generates: - * comm pid ppid pgid sid maj,min ctty,sldr start ut st wmsg uid gid groups - */ -int -procfs_stat_gen(struct proc *p, char *s, int l) -{ - struct process *pr = p->p_p; - struct session *sess; - struct tty *tp; - struct ucred *cr; - int pid, ppid, pgid, sid; - struct timeval ut, st; - char ps[256], *sep; - int i, n; - - pid = pr->ps_pid; - ppid = pr->ps_pptr ? pr->ps_pptr->ps_pid : 0; - pgid = pr->ps_pgrp->pg_id; - sess = pr->ps_pgrp->pg_session; - sid = sess->s_leader ? sess->s_leader->ps_pid : 0; - - n = 0; - if (s) - bzero(s, l); - - bcopy(p->p_comm, ps, MAXCOMLEN-1); - ps[MAXCOMLEN] = '\0'; - COUNTORCAT(s, l, ps, n); - - (void) snprintf(ps, sizeof(ps), " %d %d %d %d ", - pid, ppid, pgid, sid); - COUNTORCAT(s, l, ps, n); - - if ((pr->ps_flags & PS_CONTROLT) && (tp = sess->s_ttyp)) - snprintf(ps, sizeof(ps), "%d,%d ", - major(tp->t_dev), minor(tp->t_dev)); - else - snprintf(ps, sizeof(ps), "%d,%d ", - -1, -1); - COUNTORCAT(s, l, ps, n); - - sep = ""; - if (sess->s_ttyvp) { - snprintf(ps, sizeof(ps), "%sctty", sep); - sep = ","; - COUNTORCAT(s, l, ps, n); - } - - if (SESS_LEADER(pr)) { - snprintf(ps, sizeof(ps), "%ssldr", sep); - sep = ","; - COUNTORCAT(s, l, ps, n); - } - - if (*sep != ',') { - snprintf(ps, sizeof(ps), "noflags"); - COUNTORCAT(s, l, ps, n); - } - - snprintf(ps, sizeof(ps), " %lld,%ld", - (long long)pr->ps_start.tv_sec, pr->ps_start.tv_nsec/1000); - COUNTORCAT(s, l, ps, n); - - calcru(&pr->ps_tu, &ut, &st, (void *) 0); - snprintf(ps, sizeof(ps), " %lld,%ld %lld,%ld", - (long long)ut.tv_sec, ut.tv_usec, - (long long)st.tv_sec, st.tv_usec); - COUNTORCAT(s, l, ps, n); - - snprintf(ps, sizeof(ps), " %s", - (p->p_wchan && p->p_wmesg) ? p->p_wmesg : "nochan"); - COUNTORCAT(s, l, ps, n); - - cr = p->p_ucred; - - snprintf(ps, sizeof(ps), " %u, %u", cr->cr_uid, cr->cr_gid); - COUNTORCAT(s, l, ps, n); - for (i = 0; i < cr->cr_ngroups; i++) { - snprintf(ps, sizeof(ps), ",%u", cr->cr_groups[i]); - COUNTORCAT(s, l, ps, n); - } - - snprintf(ps, sizeof(ps), "\n"); - COUNTORCAT(s, l, ps, n); - - return (s != NULL ? strlen(s) + 1 : n + 1); -} - -int -procfs_dostatus(struct proc *curp, struct proc *p, struct pfsnode *pfs, struct uio *uio) -{ - char *ps; - int error, len; - - if (uio->uio_rw != UIO_READ) - return (EOPNOTSUPP); - - len = procfs_stat_gen(p, NULL, 0); - ps = malloc(len, M_TEMP, M_WAITOK); - len = procfs_stat_gen(p, ps, len); - - if (len <= uio->uio_offset) - error = 0; - else { - len -= uio->uio_offset; - len = imin(len, uio->uio_resid); - error = uiomove(ps + uio->uio_offset, len, uio); - } - - free(ps, M_TEMP, 0); - return (error); -} diff --git a/sys/miscfs/procfs/procfs_subr.c b/sys/miscfs/procfs/procfs_subr.c deleted file mode 100644 index b6b616cf144..00000000000 --- a/sys/miscfs/procfs/procfs_subr.c +++ /dev/null @@ -1,284 +0,0 @@ -/* $OpenBSD: procfs_subr.c,v 1.36 2014/07/12 18:43:52 tedu Exp $ */ -/* $NetBSD: procfs_subr.c,v 1.15 1996/02/12 15:01:42 christos Exp $ */ - -/* - * Copyright (c) 1993 Jan-Simon Pendry - * Copyright (c) 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Jan-Simon Pendry. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)procfs_subr.c 8.5 (Berkeley) 6/15/94 - */ - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/time.h> -#include <sys/kernel.h> -#include <sys/proc.h> -#include <sys/vnode.h> -#include <sys/malloc.h> -#include <sys/rwlock.h> -#include <sys/stat.h> -#include <sys/ptrace.h> - -#include <miscfs/procfs/procfs.h> - -static TAILQ_HEAD(, pfsnode) pfshead; -struct rwlock pfs_vlock = RWLOCK_INITIALIZER("procfsl"); - -/*ARGSUSED*/ -int -procfs_init(struct vfsconf *vfsp) -{ - TAILQ_INIT(&pfshead); - return (0); -} - -/* - * allocate a pfsnode/vnode pair. the vnode is - * referenced, but not locked. - * - * the pid, pfs_type, and mount point uniquely - * identify a pfsnode. the mount point is needed - * because someone might mount this filesystem - * twice. - * - * all pfsnodes are maintained on a singly-linked - * list. new nodes are only allocated when they cannot - * be found on this list. entries on the list are - * removed when the vfs reclaim entry is called. - * - * a single lock is kept for the entire list. this is - * needed because the getnewvnode() function can block - * waiting for a vnode to become free, in which case there - * may be more than one process trying to get the same - * vnode. this lock is only taken if we are going to - * call getnewvnode, since the kernel itself is single-threaded. - * - * if an entry is found on the list, then call vget() to - * take a reference. this is done because there may be - * zero references to it and so it needs to removed from - * the vnode free list. - */ -int -procfs_allocvp(struct mount *mp, struct vnode **vpp, pid_t pid, pfstype pfs_type) -{ - struct proc *p = curproc; - struct pfsnode *pfs; - struct vnode *vp; - int error = 0; - - /* - * Lock the vp list, getnewvnode can sleep. - */ - rw_enter_write(&pfs_vlock); -loop: - TAILQ_FOREACH(pfs, &pfshead, list) { - vp = PFSTOV(pfs); - if (pfs->pfs_pid == pid && - pfs->pfs_type == pfs_type && - vp->v_mount == mp) { - if (vget(vp, 0, p)) - goto loop; - *vpp = vp; - goto out; - } - } - - if ((error = getnewvnode(VT_PROCFS, mp, &procfs_vops, vpp)) != 0) - goto out; - vp = *vpp; - - pfs = malloc(sizeof(*pfs), M_TEMP, M_WAITOK); - vp->v_data = pfs; - - pfs->pfs_pid = pid; - pfs->pfs_type = pfs_type; - pfs->pfs_vnode = vp; - pfs->pfs_flags = 0; - pfs->pfs_fileno = PROCFS_FILENO(pid, pfs_type); - - switch (pfs_type) { - case Proot: /* /proc = dr-xr-xr-x */ - pfs->pfs_mode = S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH; - vp->v_type = VDIR; - vp->v_flag = VROOT; - break; - - case Pcurproc: /* /proc/curproc = lr--r--r-- */ - case Pself: /* /proc/self = lr--r--r-- */ - pfs->pfs_mode = S_IRUSR|S_IRGRP|S_IROTH; - vp->v_type = VLNK; - break; - - case Pproc: /* /proc/N = dr-xr-xr-x */ - pfs->pfs_mode = S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH; - vp->v_type = VDIR; - break; - - case Pfile: /* /proc/N/file = -rw------- */ - case Pmem: /* /proc/N/mem = -rw------- */ - case Pregs: /* /proc/N/regs = -rw------- */ - case Pfpregs: /* /proc/N/fpregs = -rw------- */ - pfs->pfs_mode = S_IRUSR|S_IWUSR; - vp->v_type = VREG; - break; - - case Pctl: /* /proc/N/ctl = --w------ */ - case Pnote: /* /proc/N/note = --w------ */ - case Pnotepg: /* /proc/N/notepg = --w------ */ - pfs->pfs_mode = S_IWUSR; - vp->v_type = VREG; - break; - - case Pstatus: /* /proc/N/status = -r--r--r-- */ - case Pcmdline: /* /proc/N/cmdline = -r--r--r-- */ - case Pmeminfo: /* /proc/meminfo = -r--r--r-- */ - case Pcpuinfo: /* /proc/cpuinfo = -r--r--r-- */ - pfs->pfs_mode = S_IRUSR|S_IRGRP|S_IROTH; - vp->v_type = VREG; - break; - - default: - panic("procfs_allocvp"); - } - - /* add to procfs vnode list */ - TAILQ_INSERT_TAIL(&pfshead, pfs, list); - uvm_vnp_setsize(vp, 0); -out: - rw_exit_write(&pfs_vlock); - - return (error); -} - -int -procfs_freevp(struct vnode *vp) -{ - struct pfsnode *pfs = VTOPFS(vp); - - TAILQ_REMOVE(&pfshead, pfs, list); - free(vp->v_data, M_TEMP, 0); - vp->v_data = 0; - return (0); -} - -int -procfs_rw(void *v) -{ - struct vop_read_args *ap = v; - struct vnode *vp = ap->a_vp; - struct uio *uio = ap->a_uio; - struct proc *curp = uio->uio_procp; - struct pfsnode *pfs = VTOPFS(vp); - struct proc *p; - - p = pfind(pfs->pfs_pid); - if (p == 0 || (p->p_flag & P_THREAD)) - return (EINVAL); - /* Do not permit games to be played with init(8) */ - if (p->p_pid == 1 && securelevel > 0 && uio->uio_rw == UIO_WRITE) - return (EPERM); - if (uio->uio_offset < 0) - return (EINVAL); - - switch (pfs->pfs_type) { - case Pstatus: - return (procfs_dostatus(curp, p, pfs, uio)); - - case Pmem: - return (process_domem(curp, p, uio, PT_WRITE_I)); - - case Pcmdline: - return (procfs_docmdline(curp, p, pfs, uio)); - - case Pmeminfo: - return (procfs_domeminfo(curp, p, pfs, uio)); - - case Pcpuinfo: - return (procfs_docpuinfo(curp, p, pfs, uio)); - - default: - return (EOPNOTSUPP); - } -} - -/* - * Get a string from userland into (buf). Strip a trailing - * nl character (to allow easy access from the shell). - * The buffer should be *buflenp + 1 chars long. vfs_getuserstr - * will automatically add a nul char at the end. - * - * Returns 0 on success or the following errors - * - * EINVAL: file offset is non-zero. - * EMSGSIZE: message is longer than kernel buffer - * EFAULT: user i/o buffer is not addressable - */ -int -vfs_getuserstr(struct uio *uio, char *buf, int *buflenp) -{ - int xlen; - int error; - - if (uio->uio_offset != 0) - return (EINVAL); - - xlen = *buflenp; - - /* must be able to read the whole string in one go */ - if (xlen < uio->uio_resid) - return (EMSGSIZE); - xlen = uio->uio_resid; - - if ((error = uiomove(buf, xlen, uio)) != 0) - return (error); - - /* allow multiple writes without seeks */ - uio->uio_offset = 0; - - /* cleanup string and remove trailing newline */ - buf[xlen] = '\0'; - xlen = strlen(buf); - if (xlen > 0 && buf[xlen-1] == '\n') - buf[--xlen] = '\0'; - *buflenp = xlen; - - return (0); -} - -const vfs_namemap_t * -vfs_findname(const vfs_namemap_t *nm, char *buf, int buflen) -{ - for (; nm->nm_name; nm++) - if (bcmp(buf, nm->nm_name, buflen + 1) == 0) - return (nm); - - return (0); -} diff --git a/sys/miscfs/procfs/procfs_vfsops.c b/sys/miscfs/procfs/procfs_vfsops.c deleted file mode 100644 index adeb9b1edeb..00000000000 --- a/sys/miscfs/procfs/procfs_vfsops.c +++ /dev/null @@ -1,219 +0,0 @@ -/* $OpenBSD: procfs_vfsops.c,v 1.32 2014/07/12 18:43:52 tedu Exp $ */ -/* $NetBSD: procfs_vfsops.c,v 1.25 1996/02/09 22:40:53 christos Exp $ */ - -/* - * Copyright (c) 1993 Jan-Simon Pendry - * Copyright (c) 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Jan-Simon Pendry. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)procfs_vfsops.c 8.5 (Berkeley) 6/15/94 - */ - -/* - * procfs VFS interface - */ - -#include <sys/param.h> -#include <sys/time.h> -#include <sys/kernel.h> -#include <sys/systm.h> -#include <sys/proc.h> -#include <sys/buf.h> -#include <sys/syslog.h> -#include <sys/mount.h> -#include <sys/signalvar.h> -#include <sys/vnode.h> -#include <sys/malloc.h> - -#include <miscfs/procfs/procfs.h> - -int procfs_mount(struct mount *, const char *, void *, - struct nameidata *, struct proc *); -int procfs_start(struct mount *, int, struct proc *); -int procfs_unmount(struct mount *, int, struct proc *); -int procfs_statfs(struct mount *, struct statfs *, struct proc *); -/* - * VFS Operations. - * - * mount system call - */ -/* ARGSUSED */ -int -procfs_mount(struct mount *mp, const char *path, void *data, struct nameidata *ndp, - struct proc *p) -{ - struct procfsmount *pmnt; - struct procfs_args args; - int error; - - if (UIO_MX & (UIO_MX-1)) { - log(LOG_ERR, "procfs: invalid directory entry size"); - return (EINVAL); - } - - if (mp->mnt_flag & MNT_UPDATE) - return (EOPNOTSUPP); - - if (data != NULL) { - error = copyin(data, &args, sizeof(args)); - if (error != 0) - return (error); - - if (args.version != PROCFS_ARGSVERSION) - return (EINVAL); - } else - args.flags = 0; - - mp->mnt_flag |= MNT_LOCAL; - pmnt = (struct procfsmount *) malloc(sizeof(struct procfsmount), - M_MISCFSMNT, M_WAITOK); - - mp->mnt_data = pmnt; - vfs_getnewfsid(mp); - - bzero(mp->mnt_stat.f_mntonname, MNAMELEN); - strlcpy(mp->mnt_stat.f_mntonname, path, MNAMELEN); - bzero(mp->mnt_stat.f_mntfromname, MNAMELEN); - bcopy("procfs", mp->mnt_stat.f_mntfromname, sizeof("procfs")); - bzero(mp->mnt_stat.f_mntfromspec, MNAMELEN); - bcopy("procfs", mp->mnt_stat.f_mntfromspec, sizeof("procfs")); - bcopy(&args, &mp->mnt_stat.mount_info.procfs_args, sizeof(args)); - -#ifdef notyet - pmnt->pmnt_exechook = exechook_establish(procfs_revoke_vnodes, mp); -#endif - pmnt->pmnt_flags = args.flags; - - return (0); -} - -/* - * unmount system call - */ -int -procfs_unmount(struct mount *mp, int mntflags, struct proc *p) -{ - int error; - extern int doforce; - int flags = 0; - - if (mntflags & MNT_FORCE) { - /* procfs can never be rootfs so don't check for it */ - if (!doforce) - return (EINVAL); - flags |= FORCECLOSE; - } - - if ((error = vflush(mp, 0, flags)) != 0) - return (error); - - free(VFSTOPROC(mp), M_MISCFSMNT, 0); - mp->mnt_data = 0; - - return (0); -} - -int -procfs_root(struct mount *mp, struct vnode **vpp) -{ - int error; - - error = procfs_allocvp(mp, vpp, 0, Proot); - if (error) - return (error); - vn_lock(*vpp, LK_EXCLUSIVE | LK_RETRY, curproc); - - return (0); -} - -/* ARGSUSED */ -int -procfs_start(struct mount *mp, int flags, struct proc *p) -{ - - return (0); -} - -/* - * Get file system statistics. - */ -int -procfs_statfs(struct mount *mp, struct statfs *sbp, struct proc *p) -{ - sbp->f_bsize = PAGE_SIZE; - sbp->f_iosize = PAGE_SIZE; - sbp->f_blocks = uvmexp.npages - uvmexp.free + uvmexp.swpginuse; - sbp->f_bfree = uvmexp.npages - uvmexp.free - uvmexp.active; - sbp->f_bavail = 0; - sbp->f_files = maxprocess; /* approx */ - sbp->f_ffree = maxprocess - nprocesses; /* approx */ - if (sbp != &mp->mnt_stat) { - bcopy(&mp->mnt_stat.f_fsid, &sbp->f_fsid, sizeof(sbp->f_fsid)); - bcopy(mp->mnt_stat.f_mntonname, sbp->f_mntonname, MNAMELEN); - bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN); - bcopy(mp->mnt_stat.f_mntfromspec, sbp->f_mntfromspec, MNAMELEN); - bcopy(&mp->mnt_stat.mount_info.procfs_args, - &sbp->mount_info.procfs_args, sizeof(struct procfs_args)); - } - strncpy(sbp->f_fstypename, mp->mnt_vfc->vfc_name, MFSNAMELEN); - return (0); -} - - -#define procfs_sync ((int (*)(struct mount *, int, struct ucred *, \ - struct proc *))nullop) - -#define procfs_fhtovp ((int (*)(struct mount *, struct fid *, \ - struct vnode **))eopnotsupp) -#define procfs_quotactl ((int (*)(struct mount *, int, uid_t, caddr_t, \ - struct proc *))eopnotsupp) -#define procfs_sysctl ((int (*)(int *, u_int, void *, size_t *, void *, \ - size_t, struct proc *))eopnotsupp) -#define procfs_vget ((int (*)(struct mount *, ino_t, struct vnode **)) \ - eopnotsupp) -#define procfs_vptofh ((int (*)(struct vnode *, struct fid *))eopnotsupp) -#define procfs_checkexp ((int (*)(struct mount *, struct mbuf *, \ - int *, struct ucred **))eopnotsupp) - -const struct vfsops procfs_vfsops = { - procfs_mount, - procfs_start, - procfs_unmount, - procfs_root, - procfs_quotactl, - procfs_statfs, - procfs_sync, - procfs_vget, - procfs_fhtovp, - procfs_vptofh, - procfs_init, - procfs_sysctl, - procfs_checkexp -}; diff --git a/sys/miscfs/procfs/procfs_vnops.c b/sys/miscfs/procfs/procfs_vnops.c deleted file mode 100644 index 5804414e5d1..00000000000 --- a/sys/miscfs/procfs/procfs_vnops.c +++ /dev/null @@ -1,992 +0,0 @@ -/* $OpenBSD: procfs_vnops.c,v 1.60 2014/07/08 17:19:25 deraadt Exp $ */ -/* $NetBSD: procfs_vnops.c,v 1.40 1996/03/16 23:52:55 christos Exp $ */ - -/* - * Copyright (c) 1993 Jan-Simon Pendry - * Copyright (c) 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Jan-Simon Pendry. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)procfs_vnops.c 8.8 (Berkeley) 6/15/94 - */ - -/* - * procfs vnode interface - */ - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/time.h> -#include <sys/kernel.h> -#include <sys/file.h> -#include <sys/proc.h> -#include <sys/mount.h> -#include <sys/vnode.h> -#include <sys/namei.h> -#include <sys/malloc.h> -#include <sys/dirent.h> -#include <sys/resourcevar.h> -#include <sys/poll.h> -#include <sys/ptrace.h> -#include <sys/stat.h> - -#include <machine/reg.h> - -#include <miscfs/procfs/procfs.h> - -/* - * Vnode Operations. - * - */ -static int procfs_validfile_linux(struct proc *, struct mount *); - -/* - * This is a list of the valid names in the - * process-specific sub-directories. It is - * used in procfs_lookup and procfs_readdir - */ -struct proc_target { - u_char pt_type; - u_char pt_namlen; - char *pt_name; - pfstype pt_pfstype; - int (*pt_valid)(struct proc *p, struct mount *mp); -} proc_targets[] = { -#define N(s) sizeof(s)-1, s - /* name type validp */ - { DT_DIR, N("."), Pproc, NULL }, - { DT_DIR, N(".."), Proot, NULL }, - { DT_REG, N("file"), Pfile, procfs_validfile }, - { DT_REG, N("mem"), Pmem, NULL }, - { DT_REG, N("status"), Pstatus, NULL }, - { DT_REG, N("cmdline"), Pcmdline, NULL }, - { DT_REG, N("exe"), Pfile, procfs_validfile_linux }, -#undef N -}; -static int nproc_targets = sizeof(proc_targets) / sizeof(proc_targets[0]); - -/* - * List of files in the root directory. Note: the validate function - * will be called with p == NULL for these - */ -struct proc_target proc_root_targets[] = { -#define N(s) sizeof(s)-1, s - /* name type validp */ - { DT_REG, N("meminfo"), Pmeminfo, procfs_validfile_linux }, - { DT_REG, N("cpuinfo"), Pcpuinfo, procfs_validfile_linux }, -#undef N -}; -static int nproc_root_targets = - sizeof(proc_root_targets) / sizeof(proc_root_targets[0]); - -static pid_t atopid(const char *, u_int); - -/* - * Prototypes for procfs vnode ops - */ -int procfs_badop(void *); - -int procfs_lookup(void *); -int procfs_open(void *); -int procfs_close(void *); -int procfs_access(void *); -int procfs_getattr(void *); -int procfs_setattr(void *); -int procfs_ioctl(void *); -int procfs_link(void *); -int procfs_symlink(void *); -int procfs_readdir(void *); -int procfs_readlink(void *); -int procfs_inactive(void *); -int procfs_reclaim(void *); -int procfs_print(void *); -int procfs_pathconf(void *); - -static pid_t atopid(const char *, u_int); - -/* - * procfs vnode operations. - */ -struct vops procfs_vops = { - .vop_lookup = procfs_lookup, - .vop_create = procfs_badop, - .vop_mknod = procfs_badop, - .vop_open = procfs_open, - .vop_close = procfs_close, - .vop_access = procfs_access, - .vop_getattr = procfs_getattr, - .vop_setattr = procfs_setattr, - .vop_read = procfs_rw, - .vop_write = procfs_rw, - .vop_ioctl = procfs_ioctl, - .vop_poll = procfs_poll, - .vop_fsync = procfs_badop, - .vop_remove = procfs_badop, - .vop_link = procfs_link, - .vop_rename = procfs_badop, - .vop_mkdir = procfs_badop, - .vop_rmdir = procfs_badop, - .vop_symlink = procfs_symlink, - .vop_readdir = procfs_readdir, - .vop_readlink = procfs_readlink, - .vop_abortop = vop_generic_abortop, - .vop_inactive = procfs_inactive, - .vop_reclaim = procfs_reclaim, - .vop_lock = nullop, - .vop_unlock = nullop, - .vop_bmap = vop_generic_bmap, - .vop_strategy = procfs_badop, - .vop_print = procfs_print, - .vop_islocked = nullop, - .vop_pathconf = procfs_pathconf, - .vop_advlock = procfs_badop, -}; -/* - * set things up for doing i/o on - * the pfsnode (vp). (vp) is locked - * on entry, and should be left locked - * on exit. - * - * for procfs we don't need to do anything - * in particular for i/o. all that is done - * is to support exclusive open on process - * memory images. - */ -int -procfs_open(void *v) -{ - struct vop_open_args *ap = v; - struct pfsnode *pfs = VTOPFS(ap->a_vp); - struct proc *p1 = ap->a_p; /* tracer */ - struct proc *p2; /* traced */ - int error; - - if ((p2 = pfind(pfs->pfs_pid)) == 0 || (p2->p_flag & P_THREAD)) - return (ENOENT); /* was ESRCH, jsp */ - - switch (pfs->pfs_type) { - case Pmem: - if (((pfs->pfs_flags & FWRITE) && (ap->a_mode & O_EXCL)) || - ((pfs->pfs_flags & O_EXCL) && (ap->a_mode & FWRITE))) - return (EBUSY); - - if ((error = process_checkioperm(p1, p2->p_p)) != 0) - return (error); - - if (ap->a_mode & FWRITE) - pfs->pfs_flags = ap->a_mode & (FWRITE|O_EXCL); - - return (0); - - default: - break; - } - - return (0); -} - -/* - * close the pfsnode (vp) after doing i/o. - * (vp) is not locked on entry or exit. - * - * nothing to do for procfs other than undo - * any exclusive open flag (see _open above). - */ -int -procfs_close(void *v) -{ - struct vop_close_args *ap = v; - struct pfsnode *pfs = VTOPFS(ap->a_vp); - - switch (pfs->pfs_type) { - case Pmem: - if ((ap->a_fflag & FWRITE) && (pfs->pfs_flags & O_EXCL)) - pfs->pfs_flags &= ~(FWRITE|O_EXCL); - break; - case Pctl: - case Pstatus: - case Pnotepg: - case Pnote: - case Proot: - case Pcurproc: - case Pself: - case Pproc: - case Pfile: - case Pregs: - case Pfpregs: - case Pcmdline: - case Pmeminfo: - case Pcpuinfo: - break; - } - - return (0); -} - -/* - * do an ioctl operation on pfsnode (vp). - * (vp) is not locked on entry or exit. - */ -/*ARGSUSED*/ -int -procfs_ioctl(void *v) -{ - - return (ENOTTY); -} - -/* - * _inactive is called when the pfsnode - * is vrele'd and the reference count goes - * to zero. (vp) will be on the vnode free - * list, so to get it back vget() must be - * used. - * - * for procfs, check if the process is still - * alive and if it isn't then just throw away - * the vnode by calling vgone(). this may - * be overkill and a waste of time since the - * chances are that the process will still be - * there and pfind is not free. - * - * (vp) is not locked on entry or exit. - */ -int -procfs_inactive(void *v) -{ - struct vop_inactive_args *ap = v; - struct vnode *vp = ap->a_vp; - struct pfsnode *pfs = VTOPFS(vp); - - if (pfind(pfs->pfs_pid) == NULL && !(vp->v_flag & VXLOCK)) - vgone(vp); - - return (0); -} - -/* - * _reclaim is called when getnewvnode() - * wants to make use of an entry on the vnode - * free list. at this time the filesystem needs - * to free any private data and remove the node - * from any private lists. - */ -int -procfs_reclaim(void *v) -{ - struct vop_reclaim_args *ap = v; - - return (procfs_freevp(ap->a_vp)); -} - -/* - * Return POSIX pathconf information applicable to special devices. - */ -int -procfs_pathconf(void *v) -{ - struct vop_pathconf_args *ap = v; - int error = 0; - - switch (ap->a_name) { - case _PC_LINK_MAX: - *ap->a_retval = LINK_MAX; - break; - case _PC_CHOWN_RESTRICTED: - *ap->a_retval = 1; - break; - default: - error = EINVAL; - break; - } - - return (error); -} - -/* - * _print is used for debugging. - * just print a readable description - * of (vp). - */ -int -procfs_print(void *v) -{ - struct vop_print_args *ap = v; - struct pfsnode *pfs = VTOPFS(ap->a_vp); - - printf("tag VT_PROCFS, type %d, pid %d, mode %x, flags %lx\n", - pfs->pfs_type, pfs->pfs_pid, pfs->pfs_mode, pfs->pfs_flags); - return 0; -} - -int -procfs_link(void *v) -{ - struct vop_link_args *ap = v; - - VOP_ABORTOP(ap->a_dvp, ap->a_cnp); - vput(ap->a_dvp); - return (EROFS); -} - -int -procfs_symlink(void *v) -{ - struct vop_symlink_args *ap = v; - - VOP_ABORTOP(ap->a_dvp, ap->a_cnp); - vput(ap->a_dvp); - return (EROFS); -} - - -/* - * generic entry point for unsupported operations - */ -/*ARGSUSED*/ -int -procfs_badop(void *v) -{ - - return (EIO); -} - -/* - * Invent attributes for pfsnode (vp) and store - * them in (vap). - * Directories lengths are returned as zero since - * any real length would require the genuine size - * to be computed, and nothing cares anyway. - * - * this is relatively minimal for procfs. - */ -int -procfs_getattr(void *v) -{ - struct vop_getattr_args *ap = v; - struct pfsnode *pfs = VTOPFS(ap->a_vp); - struct vattr *vap = ap->a_vap; - struct proc *procp; - int error; - - /* first check the process still exists */ - switch (pfs->pfs_type) { - case Proot: - case Pcurproc: - case Pcpuinfo: - case Pmeminfo: - procp = 0; - break; - - default: - procp = pfind(pfs->pfs_pid); - if (procp == 0 || (procp->p_flag & P_THREAD)) - return (ENOENT); - } - - error = 0; - - /* start by zeroing out the attributes */ - VATTR_NULL(vap); - - /* next do all the common fields */ - vap->va_type = ap->a_vp->v_type; - vap->va_mode = pfs->pfs_mode; - vap->va_fileid = pfs->pfs_fileno; - vap->va_flags = 0; - vap->va_blocksize = PAGE_SIZE; - vap->va_bytes = vap->va_size = 0; - - /* - * Make all times be current TOD. - * It would be possible to get the process start - * time from the p_stat structure, but there's - * no "file creation" time stamp anyway, and the - * p_stat structure is not addressible if u. gets - * swapped out for that process. - */ - getnanotime(&vap->va_ctime); - vap->va_atime = vap->va_mtime = vap->va_ctime; - - switch (pfs->pfs_type) { - case Pregs: - case Pfpregs: -#ifndef PTRACE - break; -#endif - case Pmem: - /* - * If the process has exercised some setuid or setgid - * privilege, then rip away read/write permission so - * that only root can gain access. - */ - if (procp->p_p->ps_flags & PS_SUGID) - vap->va_mode &= ~(S_IRUSR|S_IWUSR); - /* FALLTHROUGH */ - case Pctl: - case Pstatus: - case Pnote: - case Pnotepg: - case Pcmdline: - vap->va_nlink = 1; - vap->va_uid = procp->p_ucred->cr_uid; - vap->va_gid = procp->p_ucred->cr_gid; - break; - case Pmeminfo: - case Pcpuinfo: - vap->va_nlink = 1; - vap->va_uid = vap->va_gid = 0; - break; - case Pproc: - case Pfile: - case Proot: - case Pcurproc: - case Pself: - break; - } - - /* - * now do the object specific fields - * - * The size could be set from struct reg, but it's hardly - * worth the trouble, and it puts some (potentially) machine - * dependent data into this machine-independent code. If it - * becomes important then this function should break out into - * a per-file stat function in the corresponding .c file. - */ - - switch (pfs->pfs_type) { - case Proot: - /* - * Set nlink to 1 to tell fts(3) we don't actually know. - */ - vap->va_nlink = 1; - vap->va_uid = 0; - vap->va_gid = 0; - vap->va_size = vap->va_bytes = DEV_BSIZE; - break; - - case Pcurproc: { - char buf[16]; /* should be enough */ - int len; - - len = snprintf(buf, sizeof buf, "%ld", (long)curproc->p_pid); - if (len == -1 || len >= sizeof buf) { - error = EINVAL; - break; - } - vap->va_nlink = 1; - vap->va_uid = 0; - vap->va_gid = 0; - vap->va_size = vap->va_bytes = len; - break; - } - - case Pself: - vap->va_nlink = 1; - vap->va_uid = 0; - vap->va_gid = 0; - vap->va_size = vap->va_bytes = sizeof("curproc"); - break; - - case Pproc: - vap->va_nlink = 2; - vap->va_uid = procp->p_ucred->cr_uid; - vap->va_gid = procp->p_ucred->cr_gid; - vap->va_size = vap->va_bytes = DEV_BSIZE; - break; - - case Pfile: - error = EOPNOTSUPP; - break; - - case Pmem: - vap->va_bytes = vap->va_size = - ptoa(procp->p_vmspace->vm_tsize + - procp->p_vmspace->vm_dsize + - procp->p_vmspace->vm_ssize); - break; - - case Pregs: -#ifdef PTRACE - vap->va_bytes = vap->va_size = sizeof(struct reg); -#endif - break; - - case Pfpregs: -#if defined(PT_GETFPREGS) || defined(PT_SETFPREGS) -#ifdef PTRACE - vap->va_bytes = vap->va_size = sizeof(struct fpreg); -#endif -#endif - break; - - case Pctl: - case Pstatus: - case Pnote: - case Pnotepg: - case Pcmdline: - case Pmeminfo: - case Pcpuinfo: - vap->va_bytes = vap->va_size = 0; - break; - -#ifdef DIAGNOSTIC - default: - panic("procfs_getattr"); -#endif - } - - return (error); -} - -/*ARGSUSED*/ -int -procfs_setattr(void *v) -{ - /* - * just fake out attribute setting - * it's not good to generate an error - * return, otherwise things like creat() - * will fail when they try to set the - * file length to 0. worse, this means - * that echo $note > /proc/$pid/note will fail. - */ - - return (0); -} - -/* - * implement access checking. - * - * actually, the check for super-user is slightly - * broken since it will allow read access to write-only - * objects. this doesn't cause any particular trouble - * but does mean that the i/o entry points need to check - * that the operation really does make sense. - */ -int -procfs_access(void *v) -{ - struct vop_access_args *ap = v; - struct vattr va; - int error; - - if ((error = VOP_GETATTR(ap->a_vp, &va, ap->a_cred, ap->a_p)) != 0) - return (error); - - return (vaccess(ap->a_vp->v_type, va.va_mode, va.va_uid, va.va_gid, - ap->a_mode, ap->a_cred)); -} - -/* - * lookup. this is incredibly complicated in the - * general case, however for most pseudo-filesystems - * very little needs to be done. - * - * unless you want to get a migraine, just make sure your - * filesystem doesn't do any locking of its own. otherwise - * read and inwardly digest ufs_lookup(). - */ -int -procfs_lookup(void *v) -{ - struct vop_lookup_args *ap = v; - struct componentname *cnp = ap->a_cnp; - struct vnode **vpp = ap->a_vpp; - struct vnode *dvp = ap->a_dvp; - char *pname = cnp->cn_nameptr; - struct proc *curp = curproc; - struct proc_target *pt; - struct vnode *fvp; - pid_t pid; - struct pfsnode *pfs; - struct proc *p = NULL; - int i, error, wantpunlock, iscurproc = 0, isself = 0; - - *vpp = NULL; - cnp->cn_flags &= ~PDIRUNLOCK; - - if (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME) - return (EROFS); - - if (cnp->cn_namelen == 1 && *pname == '.') { - *vpp = dvp; - vref(dvp); - return (0); - } - - wantpunlock = (~cnp->cn_flags & (LOCKPARENT | ISLASTCN)); - pfs = VTOPFS(dvp); - switch (pfs->pfs_type) { - case Proot: - if (cnp->cn_flags & ISDOTDOT) - return (EIO); - - iscurproc = CNEQ(cnp, "curproc", 7); - isself = CNEQ(cnp, "self", 4); - - if (iscurproc || isself) { - error = procfs_allocvp(dvp->v_mount, vpp, 0, - iscurproc ? Pcurproc : Pself); - if ((error == 0) && (wantpunlock)) { - VOP_UNLOCK(dvp, 0, curp); - cnp->cn_flags |= PDIRUNLOCK; - } - return (error); - } - - for (i = 0; i < nproc_root_targets; i++) { - pt = &proc_root_targets[i]; - if (cnp->cn_namelen == pt->pt_namlen && - memcmp(pt->pt_name, pname, cnp->cn_namelen) == 0 && - (pt->pt_valid == NULL || - (*pt->pt_valid)(p, dvp->v_mount))) - break; - } - - if (i != nproc_root_targets) { - error = procfs_allocvp(dvp->v_mount, vpp, 0, - pt->pt_pfstype); - if ((error == 0) && (wantpunlock)) { - VOP_UNLOCK(dvp, 0, curp); - cnp->cn_flags |= PDIRUNLOCK; - } - return (error); - } - - pid = atopid(pname, cnp->cn_namelen); - if (pid == NO_PID) - break; - - p = pfind(pid); - if (p == 0 || (p->p_flag & P_THREAD)) - break; - - error = procfs_allocvp(dvp->v_mount, vpp, pid, Pproc); - if ((error == 0) && wantpunlock) { - VOP_UNLOCK(dvp, 0, curp); - cnp->cn_flags |= PDIRUNLOCK; - } - return (error); - - case Pproc: - /* - * do the .. dance. We unlock the directory, and then - * get the root dir. That will automatically return .. - * locked. Then if the caller wanted dvp locked, we - * re-lock. - */ - if (cnp->cn_flags & ISDOTDOT) { - VOP_UNLOCK(dvp, 0, p); - cnp->cn_flags |= PDIRUNLOCK; - error = procfs_root(dvp->v_mount, vpp); - if ((error == 0) && (wantpunlock == 0) && - ((error = vn_lock(dvp, LK_EXCLUSIVE, curp)) == 0)) - cnp->cn_flags &= ~PDIRUNLOCK; - return (error); - } - - p = pfind(pfs->pfs_pid); - if (p == 0 || (p->p_flag & P_THREAD)) - break; - - for (pt = proc_targets, i = 0; i < nproc_targets; pt++, i++) { - if (cnp->cn_namelen == pt->pt_namlen && - bcmp(pt->pt_name, pname, cnp->cn_namelen) == 0 && - (pt->pt_valid == NULL || - (*pt->pt_valid)(p, dvp->v_mount))) - goto found; - } - break; - - found: - if (pt->pt_pfstype == Pfile) { - fvp = p->p_p->ps_textvp; - /* We already checked that it exists. */ - vref(fvp); - vn_lock(fvp, LK_EXCLUSIVE | LK_RETRY, curp); - if (wantpunlock) { - VOP_UNLOCK(dvp, 0, curp); - cnp->cn_flags |= PDIRUNLOCK; - } - *vpp = fvp; - return (0); - } - - error = procfs_allocvp(dvp->v_mount, vpp, pfs->pfs_pid, - pt->pt_pfstype); - if ((error == 0) && (wantpunlock)) { - VOP_UNLOCK(dvp, 0, curp); - cnp->cn_flags |= PDIRUNLOCK; - } - return (error); - - default: - return (ENOTDIR); - } - - return (cnp->cn_nameiop == LOOKUP ? ENOENT : EROFS); -} - -int -procfs_validfile(struct proc *p, struct mount *mp) -{ - - return (p->p_p->ps_textvp != NULLVP); -} - -int -procfs_validfile_linux(struct proc *p, struct mount *mp) -{ - int flags; - - flags = VFSTOPROC(mp)->pmnt_flags; - return ((flags & PROCFSMNT_LINUXCOMPAT) && - (p == NULL || procfs_validfile(p, mp))); -} - -/* - * readdir returns directory entries from pfsnode (vp). - * - * the strategy here with procfs is to generate a single - * directory entry at a time (struct dirent) and then - * copy that out to userland using uiomove. a more efficent - * though more complex implementation, would try to minimize - * the number of calls to uiomove(). for procfs, this is - * hardly worth the added code complexity. - * - * this should just be done through read() - */ -int -procfs_readdir(void *v) -{ - struct vop_readdir_args *ap = v; - struct uio *uio = ap->a_uio; - struct dirent d; - struct pfsnode *pfs; - struct vnode *vp; - int i; - int error; - - vp = ap->a_vp; - pfs = VTOPFS(vp); - - if (uio->uio_resid < UIO_MX) - return (EINVAL); - - error = 0; - i = uio->uio_offset; - if (i < 0) - return (EINVAL); - bzero(&d, UIO_MX); - d.d_reclen = UIO_MX; - - switch (pfs->pfs_type) { - /* - * this is for the process-specific sub-directories. - * all that is needed to is copy out all the entries - * from the procent[] table (top of this file). - */ - case Pproc: { - struct proc *p; - struct proc_target *pt; - - p = pfind(pfs->pfs_pid); - if (p == NULL || (p->p_flag & P_THREAD)) - break; - - for (pt = &proc_targets[i]; - uio->uio_resid >= UIO_MX && i < nproc_targets; pt++, i++) { - if (pt->pt_valid && - (*pt->pt_valid)(p, vp->v_mount) == 0) - continue; - - d.d_fileno = PROCFS_FILENO(pfs->pfs_pid, pt->pt_pfstype); - d.d_namlen = pt->pt_namlen; - bcopy(pt->pt_name, d.d_name, pt->pt_namlen + 1); - d.d_type = pt->pt_type; - - if ((error = uiomove(&d, UIO_MX, uio)) != 0) - break; - } - - break; - } - - /* - * this is for the root of the procfs filesystem - * what is needed is a special entry for "curproc" - * followed by an entry for each process on allprocess -#ifdef PROCFS_ZOMBIE - * and zombprocess. -#endif - */ - - case Proot: { -#ifdef PROCFS_ZOMBIE - int doingzomb = 0; -#endif - int pcnt = i; - volatile struct process *pr = LIST_FIRST(&allprocess); - - if (pcnt > 3) - pcnt = 3; -#ifdef PROCFS_ZOMBIE - again: -#endif - for (; pr && uio->uio_resid >= UIO_MX; i++, pcnt++) { - switch (i) { - case 0: /* `.' */ - case 1: /* `..' */ - d.d_fileno = PROCFS_FILENO(0, Proot); - d.d_namlen = i + 1; - bcopy("..", d.d_name, d.d_namlen); - d.d_name[i + 1] = '\0'; - d.d_type = DT_DIR; - break; - - case 2: - d.d_fileno = PROCFS_FILENO(0, Pcurproc); - d.d_namlen = 7; - bcopy("curproc", d.d_name, 8); - d.d_type = DT_LNK; - break; - - case 3: - d.d_fileno = PROCFS_FILENO(0, Pself); - d.d_namlen = 4; - bcopy("self", d.d_name, 5); - d.d_type = DT_LNK; - break; - - case 4: - if (VFSTOPROC(vp->v_mount)->pmnt_flags & - PROCFSMNT_LINUXCOMPAT) { - d.d_fileno = PROCFS_FILENO(0, Pcpuinfo); - d.d_namlen = 7; - bcopy("cpuinfo", d.d_name, 8); - d.d_type = DT_REG; - break; - } - /* fall through */ - - case 5: - if (VFSTOPROC(vp->v_mount)->pmnt_flags & - PROCFSMNT_LINUXCOMPAT) { - d.d_fileno = PROCFS_FILENO(0, Pmeminfo); - d.d_namlen = 7; - bcopy("meminfo", d.d_name, 8); - d.d_type = DT_REG; - break; - } - /* fall through */ - - default: - while (pcnt < i) - pcnt++; - d.d_fileno = PROCFS_FILENO(pr->ps_pid, Pproc); - d.d_namlen = snprintf(d.d_name, sizeof(d.d_name), - "%ld", (long)pr->ps_pid); - d.d_type = DT_REG; - break; - } - - if ((error = uiomove(&d, UIO_MX, uio)) != 0) - break; - } -#ifdef PROCFS_ZOMBIE - if (pr == NULL && doingzomb == 0) { - doingzomb = 1; - pr = LIST_FIRST(&zombprocess); - goto again; - } -#endif - - break; - - } - - default: - error = ENOTDIR; - break; - } - - uio->uio_offset = i; - return (error); -} - -/* - * readlink reads the link of `curproc' - */ -int -procfs_readlink(void *v) -{ - struct vop_readlink_args *ap = v; - char buf[16]; /* should be enough */ - int len; - - if (VTOPFS(ap->a_vp)->pfs_fileno == PROCFS_FILENO(0, Pcurproc)) - len = snprintf(buf, sizeof buf, "%ld", (long)curproc->p_pid); - else if (VTOPFS(ap->a_vp)->pfs_fileno == PROCFS_FILENO(0, Pself)) - len = strlcpy(buf, "curproc", sizeof buf); - else - return (EINVAL); - if (len == -1 || len >= sizeof buf) - return (EINVAL); - - return (uiomove(buf, len, ap->a_uio)); -} - -/* - * convert decimal ascii to pid_t - */ -static pid_t -atopid(const char *b, u_int len) -{ - pid_t p = 0; - - while (len--) { - char c = *b++; - if (c < '0' || c > '9') - return (NO_PID); - p = 10 * p + (c - '0'); - if (p > PID_MAX) - return (NO_PID); - } - - return (p); -} -int -procfs_poll(void *v) -{ - struct vop_poll_args *ap = v; - - return (ap->a_events & (POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM)); -} |