linprocfs.c revision 76827
159412Smsmith/* 265577Sdes * Copyright (c) 2000 Dag-Erling Co�dan Sm�rgrav 365577Sdes * Copyright (c) 1999 Pierre Beyssac 459412Smsmith * Copyright (c) 1993 Jan-Simon Pendry 559412Smsmith * Copyright (c) 1993 659412Smsmith * The Regents of the University of California. All rights reserved. 759412Smsmith * 859412Smsmith * This code is derived from software contributed to Berkeley by 959412Smsmith * Jan-Simon Pendry. 1059412Smsmith * 1159412Smsmith * Redistribution and use in source and binary forms, with or without 1259412Smsmith * modification, are permitted provided that the following conditions 1359412Smsmith * are met: 1459412Smsmith * 1. Redistributions of source code must retain the above copyright 1559412Smsmith * notice, this list of conditions and the following disclaimer. 1659412Smsmith * 2. Redistributions in binary form must reproduce the above copyright 1759412Smsmith * notice, this list of conditions and the following disclaimer in the 1859412Smsmith * documentation and/or other materials provided with the distribution. 1959412Smsmith * 3. All advertising materials mentioning features or use of this software 2059412Smsmith * must display the following acknowledgement: 2159412Smsmith * This product includes software developed by the University of 2259412Smsmith * California, Berkeley and its contributors. 2359412Smsmith * 4. Neither the name of the University nor the names of its contributors 2459412Smsmith * may be used to endorse or promote products derived from this software 2559412Smsmith * without specific prior written permission. 2659412Smsmith * 2759412Smsmith * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2859412Smsmith * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2959412Smsmith * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 3059412Smsmith * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 3159412Smsmith * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 3259412Smsmith * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 3359412Smsmith * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3459412Smsmith * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 3559412Smsmith * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3659412Smsmith * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3759412Smsmith * SUCH DAMAGE. 3859412Smsmith * 3959412Smsmith * @(#)procfs_status.c 8.4 (Berkeley) 6/15/94 4059412Smsmith * 4159412Smsmith * $FreeBSD: head/sys/compat/linprocfs/linprocfs.c 76827 2001-05-19 01:28:09Z alfred $ 4259412Smsmith */ 4359412Smsmith 4459412Smsmith#include <sys/param.h> 4576166Smarkm#include <sys/systm.h> 4676166Smarkm#include <sys/blist.h> 4774135Sjlemon#include <sys/conf.h> 4865633Sdes#include <sys/dkstat.h> 4976166Smarkm#include <sys/jail.h> 5065633Sdes#include <sys/kernel.h> 5176166Smarkm#include <sys/lock.h> 5274135Sjlemon#include <sys/malloc.h> 5376827Salfred#include <sys/mutex.h> 5465633Sdes#include <sys/proc.h> 5565633Sdes#include <sys/resourcevar.h> 5669995Sdes#include <sys/sbuf.h> 5765633Sdes#include <sys/tty.h> 5859412Smsmith#include <sys/vnode.h> 5959412Smsmith 6059412Smsmith#include <vm/vm.h> 6159412Smsmith#include <vm/pmap.h> 6267588Sdes#include <vm/vm_map.h> 6359412Smsmith#include <vm/vm_param.h> 6460860Sdes#include <vm/vm_object.h> 6569995Sdes#include <vm/vm_zone.h> 6659412Smsmith#include <vm/swap_pager.h> 6769799Sdes 6869799Sdes#include <sys/exec.h> 6969799Sdes#include <sys/user.h> 7059412Smsmith#include <sys/vmmeter.h> 7159412Smsmith 7267589Sdes#include <machine/clock.h> 7367589Sdes#include <machine/cputypes.h> 7459412Smsmith#include <machine/md_var.h> 7559412Smsmith 7674135Sjlemon#include <sys/socket.h> 7774135Sjlemon#include <net/if.h> 7874135Sjlemon 7969995Sdes#include <compat/linux/linux_mib.h> 8069933Sdes#include <compat/linprocfs/linprocfs.h> 8159412Smsmith 8274135Sjlemonextern struct cdevsw *cdevsw[]; 8374135Sjlemon 8467588Sdes/* 8567588Sdes * Various conversion macros 8667588Sdes */ 8776405Sdes#define T2J(x) (((x) * 100UL) / (stathz ? stathz : hz)) /* ticks to jiffies */ 8867588Sdes#define T2S(x) ((x) / (stathz ? stathz : hz)) /* ticks to seconds */ 8967588Sdes#define B2K(x) ((x) >> 10) /* bytes to kbytes */ 9069799Sdes#define B2P(x) ((x) >> PAGE_SHIFT) /* bytes to pages */ 9167588Sdes#define P2B(x) ((x) << PAGE_SHIFT) /* pages to bytes */ 9267588Sdes#define P2K(x) ((x) << (PAGE_SHIFT - 10)) /* pages to kbytes */ 9374135Sjlemon 9474135Sjlemon#define COMMON_START \ 9574135Sjlemon struct sbuf sb; \ 9674135Sjlemon char *ps; \ 9774135Sjlemon int error, xlen 9874135Sjlemon 9974135Sjlemon#define COMMON_END \ 10074135Sjlemon sbuf_finish(&sb); \ 10174135Sjlemon ps = sbuf_data(&sb) + uio->uio_offset; \ 10274135Sjlemon xlen = sbuf_len(&sb) - uio->uio_offset; \ 10374135Sjlemon xlen = imin(xlen, uio->uio_resid); \ 10474135Sjlemon error = (xlen <= 0 ? 0 : uiomove(ps, xlen, uio)); \ 10574135Sjlemon sbuf_delete(&sb); \ 10674135Sjlemon return (error) 10769799Sdes 10859412Smsmithint 10959412Smsmithlinprocfs_domeminfo(curp, p, pfs, uio) 11059412Smsmith struct proc *curp; 11159412Smsmith struct proc *p; 11259412Smsmith struct pfsnode *pfs; 11359412Smsmith struct uio *uio; 11459412Smsmith{ 11574135Sjlemon COMMON_START; 11659412Smsmith unsigned long memtotal; /* total memory in bytes */ 11759412Smsmith unsigned long memused; /* used memory in bytes */ 11859412Smsmith unsigned long memfree; /* free memory in bytes */ 11959412Smsmith unsigned long memshared; /* shared memory ??? */ 12059412Smsmith unsigned long buffers, cached; /* buffer / cache memory ??? */ 12159412Smsmith unsigned long swaptotal; /* total swap space in bytes */ 12259412Smsmith unsigned long swapused; /* used swap space in bytes */ 12359412Smsmith unsigned long swapfree; /* free swap space in bytes */ 12460860Sdes vm_object_t object; 12559412Smsmith 12659412Smsmith if (uio->uio_rw != UIO_READ) 12759412Smsmith return (EOPNOTSUPP); 12859412Smsmith 12959412Smsmith memtotal = physmem * PAGE_SIZE; 13059412Smsmith /* 13159412Smsmith * The correct thing here would be: 13259412Smsmith * 13359412Smsmith memfree = cnt.v_free_count * PAGE_SIZE; 13459412Smsmith memused = memtotal - memfree; 13559412Smsmith * 13659412Smsmith * but it might mislead linux binaries into thinking there 13759412Smsmith * is very little memory left, so we cheat and tell them that 13859412Smsmith * all memory that isn't wired down is free. 13959412Smsmith */ 14059412Smsmith memused = cnt.v_wire_count * PAGE_SIZE; 14159412Smsmith memfree = memtotal - memused; 14264560Sbde if (swapblist == NULL) { 14364560Sbde swaptotal = 0; 14464560Sbde swapfree = 0; 14564560Sbde } else { 14664560Sbde swaptotal = swapblist->bl_blocks * 1024; /* XXX why 1024? */ 14764560Sbde swapfree = swapblist->bl_root->u.bmu_avail * PAGE_SIZE; 14864560Sbde } 14959412Smsmith swapused = swaptotal - swapfree; 15060860Sdes memshared = 0; 15171471Sjhb TAILQ_FOREACH(object, &vm_object_list, object_list) 15260860Sdes if (object->shadow_count > 1) 15360860Sdes memshared += object->resident_page_count; 15460860Sdes memshared *= PAGE_SIZE; 15559412Smsmith /* 15659412Smsmith * We'd love to be able to write: 15759412Smsmith * 15859412Smsmith buffers = bufspace; 15959412Smsmith * 16059412Smsmith * but bufspace is internal to vfs_bio.c and we don't feel 16159412Smsmith * like unstaticizing it just for linprocfs's sake. 16259412Smsmith */ 16359412Smsmith buffers = 0; 16459412Smsmith cached = cnt.v_cache_count * PAGE_SIZE; 16559412Smsmith 16669995Sdes sbuf_new(&sb, NULL, 512, 0); 16769995Sdes sbuf_printf(&sb, 16869799Sdes " total: used: free: shared: buffers: cached:\n" 16969799Sdes "Mem: %lu %lu %lu %lu %lu %lu\n" 17069799Sdes "Swap: %lu %lu %lu\n" 17169799Sdes "MemTotal: %9lu kB\n" 17269799Sdes "MemFree: %9lu kB\n" 17369799Sdes "MemShared:%9lu kB\n" 17469799Sdes "Buffers: %9lu kB\n" 17569799Sdes "Cached: %9lu kB\n" 17669799Sdes "SwapTotal:%9lu kB\n" 17769799Sdes "SwapFree: %9lu kB\n", 17869799Sdes memtotal, memused, memfree, memshared, buffers, cached, 17969799Sdes swaptotal, swapused, swapfree, 18069799Sdes B2K(memtotal), B2K(memfree), 18169799Sdes B2K(memshared), B2K(buffers), B2K(cached), 18269799Sdes B2K(swaptotal), B2K(swapfree)); 18359412Smsmith 18474135Sjlemon COMMON_END; 18559412Smsmith} 18659412Smsmith 18759412Smsmithint 18859412Smsmithlinprocfs_docpuinfo(curp, p, pfs, uio) 18959412Smsmith struct proc *curp; 19059412Smsmith struct proc *p; 19159412Smsmith struct pfsnode *pfs; 19259412Smsmith struct uio *uio; 19359412Smsmith{ 19474135Sjlemon COMMON_START; 19569799Sdes int class, i, fqmhz, fqkhz; 19659412Smsmith 19769799Sdes /* 19869799Sdes * We default the flags to include all non-conflicting flags, 19969799Sdes * and the Intel versions of conflicting flags. 20069799Sdes */ 20167589Sdes static char *flags[] = { 20267589Sdes "fpu", "vme", "de", "pse", "tsc", 20367589Sdes "msr", "pae", "mce", "cx8", "apic", 20467589Sdes "sep", "sep", "mtrr", "pge", "mca", 20567589Sdes "cmov", "pat", "pse36", "pn", "b19", 20667589Sdes "b20", "b21", "mmxext", "mmx", "fxsr", 20767589Sdes "xmm", "b26", "b27", "b28", "b29", 20867589Sdes "3dnowext", "3dnow" 20967589Sdes }; 21067589Sdes 21159412Smsmith if (uio->uio_rw != UIO_READ) 21259412Smsmith return (EOPNOTSUPP); 21359412Smsmith 21459412Smsmith switch (cpu_class) { 21559412Smsmith case CPUCLASS_286: 21667589Sdes class = 2; 21759412Smsmith break; 21859412Smsmith case CPUCLASS_386: 21967589Sdes class = 3; 22059412Smsmith break; 22159412Smsmith case CPUCLASS_486: 22267589Sdes class = 4; 22359412Smsmith break; 22459412Smsmith case CPUCLASS_586: 22567589Sdes class = 5; 22659412Smsmith break; 22759412Smsmith case CPUCLASS_686: 22867589Sdes class = 6; 22959412Smsmith break; 23059412Smsmith default: 23167589Sdes class = 0; 23259412Smsmith break; 23359412Smsmith } 23459412Smsmith 23569995Sdes sbuf_new(&sb, NULL, 512, 0); 23669995Sdes sbuf_printf(&sb, 23769799Sdes "processor\t: %d\n" 23869799Sdes "vendor_id\t: %.20s\n" 23969799Sdes "cpu family\t: %d\n" 24069799Sdes "model\t\t: %d\n" 24169799Sdes "stepping\t: %d\n", 24269799Sdes 0, cpu_vendor, class, cpu, cpu_id & 0xf); 24359412Smsmith 24469995Sdes sbuf_cat(&sb, 24569799Sdes "flags\t\t:"); 24667589Sdes 24767589Sdes if (!strcmp(cpu_vendor, "AuthenticAMD") && (class < 6)) { 24867589Sdes flags[16] = "fcmov"; 24967589Sdes } else if (!strcmp(cpu_vendor, "CyrixInstead")) { 25067589Sdes flags[24] = "cxmmx"; 25167589Sdes } 25267589Sdes 25367589Sdes for (i = 0; i < 32; i++) 25467589Sdes if (cpu_feature & (1 << i)) 25569995Sdes sbuf_printf(&sb, " %s", flags[i]); 25669995Sdes sbuf_cat(&sb, "\n"); 25767589Sdes if (class >= 5) { 25869799Sdes fqmhz = (tsc_freq + 4999) / 1000000; 25969799Sdes fqkhz = ((tsc_freq + 4999) / 10000) % 100; 26069995Sdes sbuf_printf(&sb, 26169799Sdes "cpu MHz\t\t: %d.%02d\n" 26269799Sdes "bogomips\t: %d.%02d\n", 26369799Sdes fqmhz, fqkhz, fqmhz, fqkhz); 26467589Sdes } 26569995Sdes 26674135Sjlemon COMMON_END; 26759412Smsmith} 26865633Sdes 26965633Sdesint 27065633Sdeslinprocfs_dostat(curp, p, pfs, uio) 27165633Sdes struct proc *curp; 27265633Sdes struct proc *p; 27365633Sdes struct pfsnode *pfs; 27465633Sdes struct uio *uio; 27565633Sdes{ 27674135Sjlemon COMMON_START; 27765633Sdes 27869995Sdes sbuf_new(&sb, NULL, 512, 0); 27969995Sdes sbuf_printf(&sb, 28069799Sdes "cpu %ld %ld %ld %ld\n" 28169799Sdes "disk 0 0 0 0\n" 28269799Sdes "page %u %u\n" 28369799Sdes "swap %u %u\n" 28469799Sdes "intr %u\n" 28569799Sdes "ctxt %u\n" 28669799Sdes "btime %ld\n", 28769799Sdes T2J(cp_time[CP_USER]), 28869799Sdes T2J(cp_time[CP_NICE]), 28969799Sdes T2J(cp_time[CP_SYS] /*+ cp_time[CP_INTR]*/), 29069799Sdes T2J(cp_time[CP_IDLE]), 29169799Sdes cnt.v_vnodepgsin, 29269799Sdes cnt.v_vnodepgsout, 29369799Sdes cnt.v_swappgsin, 29469799Sdes cnt.v_swappgsout, 29569799Sdes cnt.v_intr, 29669799Sdes cnt.v_swtch, 29769799Sdes boottime.tv_sec); 29869995Sdes 29974135Sjlemon COMMON_END; 30065633Sdes} 30165633Sdes 30265633Sdesint 30365633Sdeslinprocfs_douptime(curp, p, pfs, uio) 30465633Sdes struct proc *curp; 30565633Sdes struct proc *p; 30665633Sdes struct pfsnode *pfs; 30765633Sdes struct uio *uio; 30865633Sdes{ 30974135Sjlemon COMMON_START; 31065633Sdes struct timeval tv; 31165633Sdes 31265633Sdes getmicrouptime(&tv); 31369995Sdes sbuf_new(&sb, NULL, 64, 0); 31469995Sdes sbuf_printf(&sb, "%ld.%02ld %ld.%02ld\n", 31569799Sdes tv.tv_sec, tv.tv_usec / 10000, 31669799Sdes T2S(cp_time[CP_IDLE]), T2J(cp_time[CP_IDLE]) % 100); 31774135Sjlemon 31874135Sjlemon COMMON_END; 31965633Sdes} 32065633Sdes 32165633Sdesint 32265633Sdeslinprocfs_doversion(curp, p, pfs, uio) 32365633Sdes struct proc *curp; 32465633Sdes struct proc *p; 32565633Sdes struct pfsnode *pfs; 32665633Sdes struct uio *uio; 32765633Sdes{ 32874135Sjlemon COMMON_START; 32965633Sdes 33069995Sdes sbuf_new(&sb, NULL, 128, 0); 33169995Sdes sbuf_printf(&sb, 33269995Sdes "%s version %s (des@freebsd.org) (gcc version " __VERSION__ ")" 33369995Sdes " #4 Sun Dec 18 04:30:00 CET 1977\n", 33469995Sdes linux_get_osname(curp), 33569995Sdes linux_get_osrelease(curp)); 33674135Sjlemon 33774135Sjlemon COMMON_END; 33865633Sdes} 33965633Sdes 34067588Sdesint 34167588Sdeslinprocfs_doprocstat(curp, p, pfs, uio) 34267588Sdes struct proc *curp; 34367588Sdes struct proc *p; 34467588Sdes struct pfsnode *pfs; 34567588Sdes struct uio *uio; 34667588Sdes{ 34774135Sjlemon COMMON_START; 34869995Sdes struct kinfo_proc kp; 34967588Sdes 35069995Sdes fill_kinfo_proc(p, &kp); 35169995Sdes sbuf_new(&sb, NULL, 1024, 0); 35269995Sdes sbuf_printf(&sb, "%d", p->p_pid); 35369995Sdes#define PS_ADD(name, fmt, arg) sbuf_printf(&sb, " " fmt, arg) 35467588Sdes PS_ADD("comm", "(%s)", p->p_comm); 35567588Sdes PS_ADD("statr", "%c", '0'); /* XXX */ 35673923Sjhb PROC_LOCK(p); 35773923Sjhb PS_ADD("ppid", "%d", p->p_pptr ? p->p_pptr->p_pid : 0); 35873923Sjhb PROC_UNLOCK(p); 35967588Sdes PS_ADD("pgrp", "%d", p->p_pgid); 36067588Sdes PS_ADD("session", "%d", p->p_session->s_sid); 36167588Sdes PS_ADD("tty", "%d", 0); /* XXX */ 36267588Sdes PS_ADD("tpgid", "%d", 0); /* XXX */ 36367588Sdes PS_ADD("flags", "%u", 0); /* XXX */ 36467588Sdes PS_ADD("minflt", "%u", 0); /* XXX */ 36567588Sdes PS_ADD("cminflt", "%u", 0); /* XXX */ 36667588Sdes PS_ADD("majflt", "%u", 0); /* XXX */ 36767588Sdes PS_ADD("cminflt", "%u", 0); /* XXX */ 36867588Sdes PS_ADD("utime", "%d", 0); /* XXX */ 36967588Sdes PS_ADD("stime", "%d", 0); /* XXX */ 37067588Sdes PS_ADD("cutime", "%d", 0); /* XXX */ 37167588Sdes PS_ADD("cstime", "%d", 0); /* XXX */ 37267588Sdes PS_ADD("counter", "%d", 0); /* XXX */ 37367588Sdes PS_ADD("priority", "%d", 0); /* XXX */ 37467588Sdes PS_ADD("timeout", "%u", 0); /* XXX */ 37567588Sdes PS_ADD("itrealvalue", "%u", 0); /* XXX */ 37667588Sdes PS_ADD("starttime", "%d", 0); /* XXX */ 37769995Sdes PS_ADD("vsize", "%u", kp.ki_size); 37869995Sdes PS_ADD("rss", "%u", P2K(kp.ki_rssize)); 37967588Sdes PS_ADD("rlim", "%u", 0); /* XXX */ 38069995Sdes PS_ADD("startcode", "%u", (unsigned)0); 38167588Sdes PS_ADD("endcode", "%u", 0); /* XXX */ 38267588Sdes PS_ADD("startstack", "%u", 0); /* XXX */ 38369799Sdes PS_ADD("esp", "%u", 0); /* XXX */ 38469799Sdes PS_ADD("eip", "%u", 0); /* XXX */ 38567588Sdes PS_ADD("signal", "%d", 0); /* XXX */ 38667588Sdes PS_ADD("blocked", "%d", 0); /* XXX */ 38767588Sdes PS_ADD("sigignore", "%d", 0); /* XXX */ 38867588Sdes PS_ADD("sigcatch", "%d", 0); /* XXX */ 38967588Sdes PS_ADD("wchan", "%u", 0); /* XXX */ 39069799Sdes PS_ADD("nswap", "%lu", (long unsigned)0); /* XXX */ 39169799Sdes PS_ADD("cnswap", "%lu", (long unsigned)0); /* XXX */ 39269799Sdes PS_ADD("exitsignal", "%d", 0); /* XXX */ 39369799Sdes PS_ADD("processor", "%d", 0); /* XXX */ 39467588Sdes#undef PS_ADD 39569995Sdes sbuf_putc(&sb, '\n'); 39667588Sdes 39774135Sjlemon COMMON_END; 39867588Sdes} 39967588Sdes 40067588Sdes/* 40167588Sdes * Map process state to descriptive letter. Note that this does not 40267588Sdes * quite correspond to what Linux outputs, but it's close enough. 40367588Sdes */ 40467588Sdesstatic char *state_str[] = { 40567588Sdes "? (unknown)", 40667588Sdes "I (idle)", 40767588Sdes "R (running)", 40867588Sdes "S (sleeping)", 40967588Sdes "T (stopped)", 41067588Sdes "Z (zombie)", 41167588Sdes "W (waiting)", 41267588Sdes "M (mutex)" 41367588Sdes}; 41467588Sdes 41567588Sdesint 41667588Sdeslinprocfs_doprocstatus(curp, p, pfs, uio) 41767588Sdes struct proc *curp; 41867588Sdes struct proc *p; 41967588Sdes struct pfsnode *pfs; 42067588Sdes struct uio *uio; 42167588Sdes{ 42274135Sjlemon COMMON_START; 42369995Sdes struct kinfo_proc kp; 42467588Sdes char *state; 42569799Sdes segsz_t lsize; 42674135Sjlemon int i; 42767588Sdes 42869995Sdes sbuf_new(&sb, NULL, 1024, 0); 42969995Sdes 43072200Sbmilekic mtx_lock_spin(&sched_lock); 43167588Sdes if (p->p_stat > sizeof state_str / sizeof *state_str) 43267588Sdes state = state_str[0]; 43367588Sdes else 43467588Sdes state = state_str[(int)p->p_stat]; 43572200Sbmilekic mtx_unlock_spin(&sched_lock); 43667588Sdes 43769995Sdes fill_kinfo_proc(p, &kp); 43869995Sdes sbuf_printf(&sb, "Name:\t%s\n", p->p_comm); /* XXX escape */ 43969995Sdes sbuf_printf(&sb, "State:\t%s\n", state); 44067588Sdes 44167588Sdes /* 44267588Sdes * Credentials 44367588Sdes */ 44469995Sdes sbuf_printf(&sb, "Pid:\t%d\n", p->p_pid); 44571471Sjhb PROC_LOCK(p); 44673923Sjhb sbuf_printf(&sb, "PPid:\t%d\n", p->p_pptr ? 44773923Sjhb p->p_pptr->p_pid : 0); 44869995Sdes sbuf_printf(&sb, "Uid:\t%d %d %d %d\n", p->p_cred->p_ruid, 44969995Sdes p->p_ucred->cr_uid, 45069995Sdes p->p_cred->p_svuid, 45169995Sdes /* FreeBSD doesn't have fsuid */ 45269995Sdes p->p_ucred->cr_uid); 45369995Sdes sbuf_printf(&sb, "Gid:\t%d %d %d %d\n", p->p_cred->p_rgid, 45469995Sdes p->p_ucred->cr_gid, 45569995Sdes p->p_cred->p_svgid, 45669995Sdes /* FreeBSD doesn't have fsgid */ 45769995Sdes p->p_ucred->cr_gid); 45869995Sdes sbuf_cat(&sb, "Groups:\t"); 45967588Sdes for (i = 0; i < p->p_ucred->cr_ngroups; i++) 46069995Sdes sbuf_printf(&sb, "%d ", p->p_ucred->cr_groups[i]); 46171471Sjhb PROC_UNLOCK(p); 46269995Sdes sbuf_putc(&sb, '\n'); 46367588Sdes 46467588Sdes /* 46567588Sdes * Memory 46669799Sdes * 46769799Sdes * While our approximation of VmLib may not be accurate (I 46869799Sdes * don't know of a simple way to verify it, and I'm not sure 46969799Sdes * it has much meaning anyway), I believe it's good enough. 47069799Sdes * 47169799Sdes * The same code that could (I think) accurately compute VmLib 47269799Sdes * could also compute VmLck, but I don't really care enough to 47369799Sdes * implement it. Submissions are welcome. 47467588Sdes */ 47569995Sdes sbuf_printf(&sb, "VmSize:\t%8u kB\n", B2K(kp.ki_size)); 47669995Sdes sbuf_printf(&sb, "VmLck:\t%8u kB\n", P2K(0)); /* XXX */ 47769995Sdes sbuf_printf(&sb, "VmRss:\t%8u kB\n", P2K(kp.ki_rssize)); 47869995Sdes sbuf_printf(&sb, "VmData:\t%8u kB\n", P2K(kp.ki_dsize)); 47969995Sdes sbuf_printf(&sb, "VmStk:\t%8u kB\n", P2K(kp.ki_ssize)); 48069995Sdes sbuf_printf(&sb, "VmExe:\t%8u kB\n", P2K(kp.ki_tsize)); 48169995Sdes lsize = B2P(kp.ki_size) - kp.ki_dsize - 48269995Sdes kp.ki_ssize - kp.ki_tsize - 1; 48369995Sdes sbuf_printf(&sb, "VmLib:\t%8u kB\n", P2K(lsize)); 48467588Sdes 48567588Sdes /* 48667588Sdes * Signal masks 48767588Sdes * 48867588Sdes * We support up to 128 signals, while Linux supports 32, 48967588Sdes * but we only define 32 (the same 32 as Linux, to boot), so 49067588Sdes * just show the lower 32 bits of each mask. XXX hack. 49167588Sdes * 49267588Sdes * NB: on certain platforms (Sparc at least) Linux actually 49367588Sdes * supports 64 signals, but this code is a long way from 49467588Sdes * running on anything but i386, so ignore that for now. 49567588Sdes */ 49671471Sjhb PROC_LOCK(p); 49769995Sdes sbuf_printf(&sb, "SigPnd:\t%08x\n", p->p_siglist.__bits[0]); 49869799Sdes /* 49969799Sdes * I can't seem to find out where the signal mask is in 50069799Sdes * relation to struct proc, so SigBlk is left unimplemented. 50169799Sdes */ 50269995Sdes sbuf_printf(&sb, "SigBlk:\t%08x\n", 0); /* XXX */ 50369995Sdes sbuf_printf(&sb, "SigIgn:\t%08x\n", p->p_sigignore.__bits[0]); 50469995Sdes sbuf_printf(&sb, "SigCgt:\t%08x\n", p->p_sigcatch.__bits[0]); 50571471Sjhb PROC_UNLOCK(p); 50667588Sdes 50767588Sdes /* 50867588Sdes * Linux also prints the capability masks, but we don't have 50967588Sdes * capabilities yet, and when we do get them they're likely to 51067588Sdes * be meaningless to Linux programs, so we lie. XXX 51167588Sdes */ 51269995Sdes sbuf_printf(&sb, "CapInh:\t%016x\n", 0); 51369995Sdes sbuf_printf(&sb, "CapPrm:\t%016x\n", 0); 51469995Sdes sbuf_printf(&sb, "CapEff:\t%016x\n", 0); 51569995Sdes 51674135Sjlemon COMMON_END; 51767588Sdes} 51874135Sjlemon 51974135Sjlemonint 52074135Sjlemonlinprocfs_doselflink(curp, p, pfs, uio) 52174135Sjlemon struct proc *curp; 52274135Sjlemon struct proc *p; 52374135Sjlemon struct pfsnode *pfs; 52474135Sjlemon struct uio *uio; 52574135Sjlemon{ 52674135Sjlemon char buf[16]; /* should be enough */ 52774135Sjlemon int len; 52874135Sjlemon 52974135Sjlemon /* XXX shouldn't this be uio->uio_procp->p_pid? */ 53074135Sjlemon len = snprintf(buf, sizeof(buf), "%ld", (long)curproc->p_pid); 53174135Sjlemon 53274135Sjlemon return (uiomove(buf, len, uio)); 53374135Sjlemon} 53474135Sjlemon 53574135Sjlemonint 53674135Sjlemonlinprocfs_doexelink(curp, p, pfs, uio) 53774135Sjlemon struct proc *curp; 53874135Sjlemon struct proc *p; 53974135Sjlemon struct pfsnode *pfs; 54074135Sjlemon struct uio *uio; 54174135Sjlemon{ 54274135Sjlemon int error = 0; 54374135Sjlemon char *fullpath = "unknown"; 54474135Sjlemon char *freepath = NULL; 54574135Sjlemon 54674135Sjlemon p = PFIND(pfs->pfs_pid); 54774135Sjlemon if (p == NULL || p->p_cred == NULL || p->p_ucred == NULL) { 54874135Sjlemon if (p != NULL) 54974135Sjlemon PROC_UNLOCK(p); 55074135Sjlemon printf("doexelink: pid %d disappeared\n", pfs->pfs_pid); 55174135Sjlemon } else { 55274135Sjlemon PROC_UNLOCK(p); 55374135Sjlemon /* fullpath/freepath are unchanged if textvp_fullpath fails */ 55474135Sjlemon error = textvp_fullpath(p, &fullpath, &freepath); 55574135Sjlemon } 55674135Sjlemon error = uiomove(fullpath, strlen(fullpath), uio); 55774135Sjlemon if (freepath) 55874135Sjlemon free(freepath, M_TEMP); 55974135Sjlemon return (error); 56074135Sjlemon} 56174135Sjlemon 56274135Sjlemonint 56374135Sjlemonlinprocfs_donetdev(curp, p, pfs, uio) 56474135Sjlemon struct proc *curp; 56574135Sjlemon struct proc *p; 56674135Sjlemon struct pfsnode *pfs; 56774135Sjlemon struct uio *uio; 56874135Sjlemon{ 56974135Sjlemon COMMON_START; 57074135Sjlemon struct ifnet *ifp; 57174135Sjlemon int eth_index = 0; 57274135Sjlemon 57374135Sjlemon sbuf_new(&sb, NULL, 1024, 0); 57474135Sjlemon sbuf_printf(&sb, 57574135Sjlemon "Inter-| Receive " 57674135Sjlemon " | Transmit\n" 57774135Sjlemon " face |bytes packets errs drop fifo frame compressed " 57874135Sjlemon "multicast|bytes packets errs drop fifo colls carrier " 57974135Sjlemon "compressed\n"); 58074135Sjlemon 58174135Sjlemon TAILQ_FOREACH(ifp, &ifnet, if_link) { 58274135Sjlemon if (strcmp(ifp->if_name, "lo") == 0) { 58374135Sjlemon sbuf_printf(&sb, "%6.6s:", ifp->if_name); 58474135Sjlemon } else { 58574135Sjlemon sbuf_printf(&sb, "%5.5s%d:", "eth", eth_index); 58674135Sjlemon eth_index++; 58774135Sjlemon } 58874135Sjlemon sbuf_printf(&sb, 58974135Sjlemon "%8lu %7lu %4lu %4lu %4lu %5lu %10lu %9lu " 59074135Sjlemon "%8lu %7lu %4lu %4lu %4lu %5lu %7lu %10lu\n", 59174135Sjlemon 0, 0, 0, 0, 0, 0, 0, 0, 59274135Sjlemon 0, 0, 0, 0, 0, 0, 0, 0); 59374135Sjlemon } 59474135Sjlemon 59574135Sjlemon COMMON_END; 59674135Sjlemon} 59774135Sjlemon 59874135Sjlemonint 59974135Sjlemonlinprocfs_dodevices(curp, p, pfs, uio) 60074135Sjlemon struct proc *curp; 60174135Sjlemon struct proc *p; 60274135Sjlemon struct pfsnode *pfs; 60374135Sjlemon struct uio *uio; 60474135Sjlemon{ 60574135Sjlemon COMMON_START; 60674135Sjlemon int i; 60774135Sjlemon 60874135Sjlemon sbuf_new(&sb, NULL, 1024, 0); 60974135Sjlemon sbuf_printf(&sb, "Character devices:\n"); 61074135Sjlemon 61174135Sjlemon for (i = 0; i < NUMCDEVSW; i++) { 61274135Sjlemon if (cdevsw[i] != NULL) 61374135Sjlemon sbuf_printf(&sb, "%3d %s\n", i, cdevsw[i]->d_name); 61474135Sjlemon } 61574135Sjlemon 61674135Sjlemon sbuf_printf(&sb, "\nBlock devices:\n"); 61774135Sjlemon 61874135Sjlemon COMMON_END; 61974135Sjlemon} 62074135Sjlemon 62174135Sjlemonint 62274135Sjlemonlinprocfs_docmdline(curp, p, pfs, uio) 62374135Sjlemon struct proc *curp; 62474135Sjlemon struct proc *p; 62574135Sjlemon struct pfsnode *pfs; 62674135Sjlemon struct uio *uio; 62774135Sjlemon{ 62874135Sjlemon COMMON_START; 62974135Sjlemon 63074135Sjlemon sbuf_new(&sb, NULL, 128, 0); 63174135Sjlemon sbuf_printf(&sb, "BOOT_IMAGE=%s", kernelname); 63274135Sjlemon sbuf_printf(&sb, " ro root=302\n"); 63374135Sjlemon 63474135Sjlemon COMMON_END; 63574135Sjlemon} 636