linprocfs.c revision 78025
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 78025 2001-06-10 23:23:59Z des $ 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> 5378025Sdes#include <sys/mount.h> 5476827Salfred#include <sys/mutex.h> 5565633Sdes#include <sys/proc.h> 5665633Sdes#include <sys/resourcevar.h> 5769995Sdes#include <sys/sbuf.h> 5876839Sjlemon#include <sys/sysctl.h> 5965633Sdes#include <sys/tty.h> 6059412Smsmith#include <sys/vnode.h> 6159412Smsmith 6259412Smsmith#include <vm/vm.h> 6359412Smsmith#include <vm/pmap.h> 6467588Sdes#include <vm/vm_map.h> 6559412Smsmith#include <vm/vm_param.h> 6660860Sdes#include <vm/vm_object.h> 6769995Sdes#include <vm/vm_zone.h> 6859412Smsmith#include <vm/swap_pager.h> 6969799Sdes 7069799Sdes#include <sys/exec.h> 7169799Sdes#include <sys/user.h> 7259412Smsmith#include <sys/vmmeter.h> 7359412Smsmith 7467589Sdes#include <machine/clock.h> 7567589Sdes#include <machine/cputypes.h> 7659412Smsmith#include <machine/md_var.h> 7759412Smsmith 7874135Sjlemon#include <sys/socket.h> 7974135Sjlemon#include <net/if.h> 8074135Sjlemon 8169995Sdes#include <compat/linux/linux_mib.h> 8278025Sdes#include <fs/pseudofs/pseudofs.h> 8359412Smsmith 8474135Sjlemonextern struct cdevsw *cdevsw[]; 8574135Sjlemon 8667588Sdes/* 8767588Sdes * Various conversion macros 8867588Sdes */ 8976405Sdes#define T2J(x) (((x) * 100UL) / (stathz ? stathz : hz)) /* ticks to jiffies */ 9067588Sdes#define T2S(x) ((x) / (stathz ? stathz : hz)) /* ticks to seconds */ 9167588Sdes#define B2K(x) ((x) >> 10) /* bytes to kbytes */ 9269799Sdes#define B2P(x) ((x) >> PAGE_SHIFT) /* bytes to pages */ 9367588Sdes#define P2B(x) ((x) << PAGE_SHIFT) /* pages to bytes */ 9467588Sdes#define P2K(x) ((x) << (PAGE_SHIFT - 10)) /* pages to kbytes */ 9574135Sjlemon 9678025Sdesstatic int 9778025Sdeslinprocfs_domeminfo(PFS_FILL_ARGS) 9859412Smsmith{ 9959412Smsmith unsigned long memtotal; /* total memory in bytes */ 10059412Smsmith unsigned long memused; /* used memory in bytes */ 10159412Smsmith unsigned long memfree; /* free memory in bytes */ 10259412Smsmith unsigned long memshared; /* shared memory ??? */ 10359412Smsmith unsigned long buffers, cached; /* buffer / cache memory ??? */ 10476839Sjlemon u_quad_t swaptotal; /* total swap space in bytes */ 10576839Sjlemon u_quad_t swapused; /* used swap space in bytes */ 10676839Sjlemon u_quad_t swapfree; /* free swap space in bytes */ 10760860Sdes vm_object_t object; 10859412Smsmith 10959412Smsmith memtotal = physmem * PAGE_SIZE; 11059412Smsmith /* 11159412Smsmith * The correct thing here would be: 11259412Smsmith * 11359412Smsmith memfree = cnt.v_free_count * PAGE_SIZE; 11459412Smsmith memused = memtotal - memfree; 11559412Smsmith * 11659412Smsmith * but it might mislead linux binaries into thinking there 11759412Smsmith * is very little memory left, so we cheat and tell them that 11859412Smsmith * all memory that isn't wired down is free. 11959412Smsmith */ 12059412Smsmith memused = cnt.v_wire_count * PAGE_SIZE; 12159412Smsmith memfree = memtotal - memused; 12264560Sbde if (swapblist == NULL) { 12364560Sbde swaptotal = 0; 12464560Sbde swapfree = 0; 12564560Sbde } else { 12676839Sjlemon swaptotal = (u_quad_t)swapblist->bl_blocks * 1024; /* XXX why 1024? */ 12776839Sjlemon swapfree = (u_quad_t)swapblist->bl_root->u.bmu_avail * PAGE_SIZE; 12864560Sbde } 12959412Smsmith swapused = swaptotal - swapfree; 13060860Sdes memshared = 0; 13171471Sjhb TAILQ_FOREACH(object, &vm_object_list, object_list) 13260860Sdes if (object->shadow_count > 1) 13360860Sdes memshared += object->resident_page_count; 13460860Sdes memshared *= PAGE_SIZE; 13559412Smsmith /* 13659412Smsmith * We'd love to be able to write: 13759412Smsmith * 13859412Smsmith buffers = bufspace; 13959412Smsmith * 14059412Smsmith * but bufspace is internal to vfs_bio.c and we don't feel 14159412Smsmith * like unstaticizing it just for linprocfs's sake. 14259412Smsmith */ 14359412Smsmith buffers = 0; 14459412Smsmith cached = cnt.v_cache_count * PAGE_SIZE; 14559412Smsmith 14678025Sdes sbuf_printf(sb, 14769799Sdes " total: used: free: shared: buffers: cached:\n" 14869799Sdes "Mem: %lu %lu %lu %lu %lu %lu\n" 14976839Sjlemon "Swap: %llu %llu %llu\n" 15069799Sdes "MemTotal: %9lu kB\n" 15169799Sdes "MemFree: %9lu kB\n" 15269799Sdes "MemShared:%9lu kB\n" 15369799Sdes "Buffers: %9lu kB\n" 15469799Sdes "Cached: %9lu kB\n" 15576839Sjlemon "SwapTotal:%9llu kB\n" 15676839Sjlemon "SwapFree: %9llu kB\n", 15769799Sdes memtotal, memused, memfree, memshared, buffers, cached, 15869799Sdes swaptotal, swapused, swapfree, 15969799Sdes B2K(memtotal), B2K(memfree), 16069799Sdes B2K(memshared), B2K(buffers), B2K(cached), 16169799Sdes B2K(swaptotal), B2K(swapfree)); 16259412Smsmith 16378025Sdes return (0); 16459412Smsmith} 16559412Smsmith 16678025Sdesstatic int 16778025Sdeslinprocfs_docpuinfo(PFS_FILL_ARGS) 16859412Smsmith{ 16969799Sdes int class, i, fqmhz, fqkhz; 17059412Smsmith 17169799Sdes /* 17269799Sdes * We default the flags to include all non-conflicting flags, 17369799Sdes * and the Intel versions of conflicting flags. 17469799Sdes */ 17567589Sdes static char *flags[] = { 17667589Sdes "fpu", "vme", "de", "pse", "tsc", 17767589Sdes "msr", "pae", "mce", "cx8", "apic", 17867589Sdes "sep", "sep", "mtrr", "pge", "mca", 17967589Sdes "cmov", "pat", "pse36", "pn", "b19", 18067589Sdes "b20", "b21", "mmxext", "mmx", "fxsr", 18167589Sdes "xmm", "b26", "b27", "b28", "b29", 18267589Sdes "3dnowext", "3dnow" 18367589Sdes }; 18467589Sdes 18559412Smsmith switch (cpu_class) { 18659412Smsmith case CPUCLASS_286: 18767589Sdes class = 2; 18859412Smsmith break; 18959412Smsmith case CPUCLASS_386: 19067589Sdes class = 3; 19159412Smsmith break; 19259412Smsmith case CPUCLASS_486: 19367589Sdes class = 4; 19459412Smsmith break; 19559412Smsmith case CPUCLASS_586: 19667589Sdes class = 5; 19759412Smsmith break; 19859412Smsmith case CPUCLASS_686: 19967589Sdes class = 6; 20059412Smsmith break; 20159412Smsmith default: 20267589Sdes class = 0; 20359412Smsmith break; 20459412Smsmith } 20559412Smsmith 20678025Sdes sbuf_printf(sb, 20769799Sdes "processor\t: %d\n" 20869799Sdes "vendor_id\t: %.20s\n" 20969799Sdes "cpu family\t: %d\n" 21069799Sdes "model\t\t: %d\n" 21169799Sdes "stepping\t: %d\n", 21269799Sdes 0, cpu_vendor, class, cpu, cpu_id & 0xf); 21359412Smsmith 21478025Sdes sbuf_cat(sb, 21569799Sdes "flags\t\t:"); 21667589Sdes 21767589Sdes if (!strcmp(cpu_vendor, "AuthenticAMD") && (class < 6)) { 21867589Sdes flags[16] = "fcmov"; 21967589Sdes } else if (!strcmp(cpu_vendor, "CyrixInstead")) { 22067589Sdes flags[24] = "cxmmx"; 22167589Sdes } 22267589Sdes 22367589Sdes for (i = 0; i < 32; i++) 22467589Sdes if (cpu_feature & (1 << i)) 22578025Sdes sbuf_printf(sb, " %s", flags[i]); 22678025Sdes sbuf_cat(sb, "\n"); 22767589Sdes if (class >= 5) { 22869799Sdes fqmhz = (tsc_freq + 4999) / 1000000; 22969799Sdes fqkhz = ((tsc_freq + 4999) / 10000) % 100; 23078025Sdes sbuf_printf(sb, 23169799Sdes "cpu MHz\t\t: %d.%02d\n" 23269799Sdes "bogomips\t: %d.%02d\n", 23369799Sdes fqmhz, fqkhz, fqmhz, fqkhz); 23467589Sdes } 23569995Sdes 23678025Sdes return (0); 23759412Smsmith} 23865633Sdes 23978025Sdesstatic int 24078025Sdeslinprocfs_dostat(PFS_FILL_ARGS) 24165633Sdes{ 24278025Sdes sbuf_printf(sb, 24369799Sdes "cpu %ld %ld %ld %ld\n" 24469799Sdes "disk 0 0 0 0\n" 24569799Sdes "page %u %u\n" 24669799Sdes "swap %u %u\n" 24769799Sdes "intr %u\n" 24869799Sdes "ctxt %u\n" 24969799Sdes "btime %ld\n", 25069799Sdes T2J(cp_time[CP_USER]), 25169799Sdes T2J(cp_time[CP_NICE]), 25269799Sdes T2J(cp_time[CP_SYS] /*+ cp_time[CP_INTR]*/), 25369799Sdes T2J(cp_time[CP_IDLE]), 25469799Sdes cnt.v_vnodepgsin, 25569799Sdes cnt.v_vnodepgsout, 25669799Sdes cnt.v_swappgsin, 25769799Sdes cnt.v_swappgsout, 25869799Sdes cnt.v_intr, 25969799Sdes cnt.v_swtch, 26069799Sdes boottime.tv_sec); 26178025Sdes return (0); 26265633Sdes} 26365633Sdes 26478025Sdesstatic int 26578025Sdeslinprocfs_douptime(PFS_FILL_ARGS) 26665633Sdes{ 26765633Sdes struct timeval tv; 26865633Sdes 26965633Sdes getmicrouptime(&tv); 27078025Sdes sbuf_printf(sb, "%ld.%02ld %ld.%02ld\n", 27169799Sdes tv.tv_sec, tv.tv_usec / 10000, 27269799Sdes T2S(cp_time[CP_IDLE]), T2J(cp_time[CP_IDLE]) % 100); 27378025Sdes return (0); 27465633Sdes} 27565633Sdes 27678025Sdesstatic int 27778025Sdeslinprocfs_doversion(PFS_FILL_ARGS) 27865633Sdes{ 27978025Sdes sbuf_printf(sb, 28069995Sdes "%s version %s (des@freebsd.org) (gcc version " __VERSION__ ")" 28169995Sdes " #4 Sun Dec 18 04:30:00 CET 1977\n", 28269995Sdes linux_get_osname(curp), 28369995Sdes linux_get_osrelease(curp)); 28478025Sdes return (0); 28565633Sdes} 28665633Sdes 28778025Sdesstatic int 28878025Sdeslinprocfs_doloadavg(PFS_FILL_ARGS) 28976839Sjlemon{ 29076839Sjlemon int lastpid, ilen; 29176839Sjlemon 29276839Sjlemon ilen = sizeof(lastpid); 29376839Sjlemon if (kernel_sysctlbyname(p, "kern.lastpid", 29476839Sjlemon &lastpid, &ilen, NULL, 0, NULL) != 0) 29576839Sjlemon lastpid = -1; /* fake it */ 29676839Sjlemon 29778025Sdes sbuf_printf(sb, 29876839Sjlemon "%d.%02d %d.%02d %d.%02d %d/%d %d\n", 29976839Sjlemon (int)(averunnable.ldavg[0] / averunnable.fscale), 30076839Sjlemon (int)(averunnable.ldavg[0] * 100 / averunnable.fscale % 100), 30176839Sjlemon (int)(averunnable.ldavg[1] / averunnable.fscale), 30276839Sjlemon (int)(averunnable.ldavg[1] * 100 / averunnable.fscale % 100), 30376839Sjlemon (int)(averunnable.ldavg[2] / averunnable.fscale), 30476839Sjlemon (int)(averunnable.ldavg[2] * 100 / averunnable.fscale % 100), 30576839Sjlemon 1, /* number of running tasks */ 30676839Sjlemon nprocs, /* number of tasks */ 30776839Sjlemon lastpid /* the last pid */ 30876839Sjlemon ); 30978025Sdes 31078025Sdes return (0); 31176839Sjlemon} 31276839Sjlemon 31378025Sdesstatic int 31478025Sdeslinprocfs_doprocstat(PFS_FILL_ARGS) 31567588Sdes{ 31669995Sdes struct kinfo_proc kp; 31767588Sdes 31869995Sdes fill_kinfo_proc(p, &kp); 31978025Sdes sbuf_printf(sb, "%d", p->p_pid); 32078025Sdes#define PS_ADD(name, fmt, arg) sbuf_printf(sb, " " fmt, arg) 32167588Sdes PS_ADD("comm", "(%s)", p->p_comm); 32267588Sdes PS_ADD("statr", "%c", '0'); /* XXX */ 32373923Sjhb PROC_LOCK(p); 32473923Sjhb PS_ADD("ppid", "%d", p->p_pptr ? p->p_pptr->p_pid : 0); 32573923Sjhb PROC_UNLOCK(p); 32667588Sdes PS_ADD("pgrp", "%d", p->p_pgid); 32767588Sdes PS_ADD("session", "%d", p->p_session->s_sid); 32867588Sdes PS_ADD("tty", "%d", 0); /* XXX */ 32967588Sdes PS_ADD("tpgid", "%d", 0); /* XXX */ 33067588Sdes PS_ADD("flags", "%u", 0); /* XXX */ 33167588Sdes PS_ADD("minflt", "%u", 0); /* XXX */ 33267588Sdes PS_ADD("cminflt", "%u", 0); /* XXX */ 33367588Sdes PS_ADD("majflt", "%u", 0); /* XXX */ 33467588Sdes PS_ADD("cminflt", "%u", 0); /* XXX */ 33567588Sdes PS_ADD("utime", "%d", 0); /* XXX */ 33667588Sdes PS_ADD("stime", "%d", 0); /* XXX */ 33767588Sdes PS_ADD("cutime", "%d", 0); /* XXX */ 33867588Sdes PS_ADD("cstime", "%d", 0); /* XXX */ 33967588Sdes PS_ADD("counter", "%d", 0); /* XXX */ 34067588Sdes PS_ADD("priority", "%d", 0); /* XXX */ 34167588Sdes PS_ADD("timeout", "%u", 0); /* XXX */ 34267588Sdes PS_ADD("itrealvalue", "%u", 0); /* XXX */ 34367588Sdes PS_ADD("starttime", "%d", 0); /* XXX */ 34469995Sdes PS_ADD("vsize", "%u", kp.ki_size); 34569995Sdes PS_ADD("rss", "%u", P2K(kp.ki_rssize)); 34667588Sdes PS_ADD("rlim", "%u", 0); /* XXX */ 34769995Sdes PS_ADD("startcode", "%u", (unsigned)0); 34867588Sdes PS_ADD("endcode", "%u", 0); /* XXX */ 34967588Sdes PS_ADD("startstack", "%u", 0); /* XXX */ 35069799Sdes PS_ADD("esp", "%u", 0); /* XXX */ 35169799Sdes PS_ADD("eip", "%u", 0); /* XXX */ 35267588Sdes PS_ADD("signal", "%d", 0); /* XXX */ 35367588Sdes PS_ADD("blocked", "%d", 0); /* XXX */ 35467588Sdes PS_ADD("sigignore", "%d", 0); /* XXX */ 35567588Sdes PS_ADD("sigcatch", "%d", 0); /* XXX */ 35667588Sdes PS_ADD("wchan", "%u", 0); /* XXX */ 35769799Sdes PS_ADD("nswap", "%lu", (long unsigned)0); /* XXX */ 35869799Sdes PS_ADD("cnswap", "%lu", (long unsigned)0); /* XXX */ 35969799Sdes PS_ADD("exitsignal", "%d", 0); /* XXX */ 36069799Sdes PS_ADD("processor", "%d", 0); /* XXX */ 36167588Sdes#undef PS_ADD 36278025Sdes sbuf_putc(sb, '\n'); 36367588Sdes 36478025Sdes return (0); 36567588Sdes} 36667588Sdes 36767588Sdes/* 36867588Sdes * Map process state to descriptive letter. Note that this does not 36967588Sdes * quite correspond to what Linux outputs, but it's close enough. 37067588Sdes */ 37167588Sdesstatic char *state_str[] = { 37267588Sdes "? (unknown)", 37367588Sdes "I (idle)", 37467588Sdes "R (running)", 37567588Sdes "S (sleeping)", 37667588Sdes "T (stopped)", 37767588Sdes "Z (zombie)", 37867588Sdes "W (waiting)", 37967588Sdes "M (mutex)" 38067588Sdes}; 38167588Sdes 38278025Sdesstatic int 38378025Sdeslinprocfs_doprocstatus(PFS_FILL_ARGS) 38467588Sdes{ 38569995Sdes struct kinfo_proc kp; 38667588Sdes char *state; 38769799Sdes segsz_t lsize; 38874135Sjlemon int i; 38967588Sdes 39072200Sbmilekic mtx_lock_spin(&sched_lock); 39167588Sdes if (p->p_stat > sizeof state_str / sizeof *state_str) 39267588Sdes state = state_str[0]; 39367588Sdes else 39467588Sdes state = state_str[(int)p->p_stat]; 39572200Sbmilekic mtx_unlock_spin(&sched_lock); 39667588Sdes 39769995Sdes fill_kinfo_proc(p, &kp); 39878025Sdes sbuf_printf(sb, "Name:\t%s\n", p->p_comm); /* XXX escape */ 39978025Sdes sbuf_printf(sb, "State:\t%s\n", state); 40067588Sdes 40167588Sdes /* 40267588Sdes * Credentials 40367588Sdes */ 40478025Sdes sbuf_printf(sb, "Pid:\t%d\n", p->p_pid); 40571471Sjhb PROC_LOCK(p); 40678025Sdes sbuf_printf(sb, "PPid:\t%d\n", p->p_pptr ? 40773923Sjhb p->p_pptr->p_pid : 0); 40878025Sdes sbuf_printf(sb, "Uid:\t%d %d %d %d\n", p->p_ucred->cr_ruid, 40969995Sdes p->p_ucred->cr_uid, 41077183Srwatson p->p_ucred->cr_svuid, 41169995Sdes /* FreeBSD doesn't have fsuid */ 41269995Sdes p->p_ucred->cr_uid); 41378025Sdes sbuf_printf(sb, "Gid:\t%d %d %d %d\n", p->p_ucred->cr_rgid, 41469995Sdes p->p_ucred->cr_gid, 41577183Srwatson p->p_ucred->cr_svgid, 41669995Sdes /* FreeBSD doesn't have fsgid */ 41769995Sdes p->p_ucred->cr_gid); 41878025Sdes sbuf_cat(sb, "Groups:\t"); 41967588Sdes for (i = 0; i < p->p_ucred->cr_ngroups; i++) 42078025Sdes sbuf_printf(sb, "%d ", p->p_ucred->cr_groups[i]); 42171471Sjhb PROC_UNLOCK(p); 42278025Sdes sbuf_putc(sb, '\n'); 42367588Sdes 42467588Sdes /* 42567588Sdes * Memory 42669799Sdes * 42769799Sdes * While our approximation of VmLib may not be accurate (I 42869799Sdes * don't know of a simple way to verify it, and I'm not sure 42969799Sdes * it has much meaning anyway), I believe it's good enough. 43069799Sdes * 43169799Sdes * The same code that could (I think) accurately compute VmLib 43269799Sdes * could also compute VmLck, but I don't really care enough to 43369799Sdes * implement it. Submissions are welcome. 43467588Sdes */ 43578025Sdes sbuf_printf(sb, "VmSize:\t%8u kB\n", B2K(kp.ki_size)); 43678025Sdes sbuf_printf(sb, "VmLck:\t%8u kB\n", P2K(0)); /* XXX */ 43778025Sdes sbuf_printf(sb, "VmRss:\t%8u kB\n", P2K(kp.ki_rssize)); 43878025Sdes sbuf_printf(sb, "VmData:\t%8u kB\n", P2K(kp.ki_dsize)); 43978025Sdes sbuf_printf(sb, "VmStk:\t%8u kB\n", P2K(kp.ki_ssize)); 44078025Sdes sbuf_printf(sb, "VmExe:\t%8u kB\n", P2K(kp.ki_tsize)); 44169995Sdes lsize = B2P(kp.ki_size) - kp.ki_dsize - 44269995Sdes kp.ki_ssize - kp.ki_tsize - 1; 44378025Sdes sbuf_printf(sb, "VmLib:\t%8u kB\n", P2K(lsize)); 44467588Sdes 44567588Sdes /* 44667588Sdes * Signal masks 44767588Sdes * 44867588Sdes * We support up to 128 signals, while Linux supports 32, 44967588Sdes * but we only define 32 (the same 32 as Linux, to boot), so 45067588Sdes * just show the lower 32 bits of each mask. XXX hack. 45167588Sdes * 45267588Sdes * NB: on certain platforms (Sparc at least) Linux actually 45367588Sdes * supports 64 signals, but this code is a long way from 45467588Sdes * running on anything but i386, so ignore that for now. 45567588Sdes */ 45671471Sjhb PROC_LOCK(p); 45778025Sdes sbuf_printf(sb, "SigPnd:\t%08x\n", p->p_siglist.__bits[0]); 45869799Sdes /* 45969799Sdes * I can't seem to find out where the signal mask is in 46069799Sdes * relation to struct proc, so SigBlk is left unimplemented. 46169799Sdes */ 46278025Sdes sbuf_printf(sb, "SigBlk:\t%08x\n", 0); /* XXX */ 46378025Sdes sbuf_printf(sb, "SigIgn:\t%08x\n", p->p_sigignore.__bits[0]); 46478025Sdes sbuf_printf(sb, "SigCgt:\t%08x\n", p->p_sigcatch.__bits[0]); 46571471Sjhb PROC_UNLOCK(p); 46667588Sdes 46767588Sdes /* 46867588Sdes * Linux also prints the capability masks, but we don't have 46967588Sdes * capabilities yet, and when we do get them they're likely to 47067588Sdes * be meaningless to Linux programs, so we lie. XXX 47167588Sdes */ 47278025Sdes sbuf_printf(sb, "CapInh:\t%016x\n", 0); 47378025Sdes sbuf_printf(sb, "CapPrm:\t%016x\n", 0); 47478025Sdes sbuf_printf(sb, "CapEff:\t%016x\n", 0); 47578025Sdes 47678025Sdes return (0); 47767588Sdes} 47874135Sjlemon 47978025Sdesstatic int 48078025Sdeslinprocfs_doselflink(PFS_FILL_ARGS) 48174135Sjlemon{ 48278025Sdes sbuf_printf(sb, "%ld", (long)curp->p_pid); 48378025Sdes return (0); 48474135Sjlemon} 48574135Sjlemon 48678025Sdesstatic int 48778025Sdeslinprocfs_doexelink(PFS_FILL_ARGS) 48874135Sjlemon{ 48974135Sjlemon char *fullpath = "unknown"; 49074135Sjlemon char *freepath = NULL; 49174135Sjlemon 49278025Sdes textvp_fullpath(p, &fullpath, &freepath); 49378025Sdes sbuf_printf(sb, "%s", fullpath); 49474135Sjlemon if (freepath) 49574135Sjlemon free(freepath, M_TEMP); 49678025Sdes return (0); 49774135Sjlemon} 49874135Sjlemon 49978025Sdesstatic int 50078025Sdeslinprocfs_donetdev(PFS_FILL_ARGS) 50174135Sjlemon{ 50274135Sjlemon struct ifnet *ifp; 50374135Sjlemon int eth_index = 0; 50474135Sjlemon 50578025Sdes sbuf_printf(sb, 50674135Sjlemon "Inter-| Receive " 50774135Sjlemon " | Transmit\n" 50874135Sjlemon " face |bytes packets errs drop fifo frame compressed " 50974135Sjlemon "multicast|bytes packets errs drop fifo colls carrier " 51074135Sjlemon "compressed\n"); 51174135Sjlemon 51274135Sjlemon TAILQ_FOREACH(ifp, &ifnet, if_link) { 51374135Sjlemon if (strcmp(ifp->if_name, "lo") == 0) { 51478025Sdes sbuf_printf(sb, "%6.6s:", ifp->if_name); 51574135Sjlemon } else { 51678025Sdes sbuf_printf(sb, "%5.5s%d:", "eth", eth_index); 51774135Sjlemon eth_index++; 51874135Sjlemon } 51978025Sdes sbuf_printf(sb, 52074135Sjlemon "%8lu %7lu %4lu %4lu %4lu %5lu %10lu %9lu " 52174135Sjlemon "%8lu %7lu %4lu %4lu %4lu %5lu %7lu %10lu\n", 52274135Sjlemon 0, 0, 0, 0, 0, 0, 0, 0, 52374135Sjlemon 0, 0, 0, 0, 0, 0, 0, 0); 52474135Sjlemon } 52578025Sdes 52678025Sdes return (0); 52774135Sjlemon} 52874135Sjlemon 52978025Sdesstatic int 53078025Sdeslinprocfs_dodevices(PFS_FILL_ARGS) 53174135Sjlemon{ 53274135Sjlemon int i; 53374135Sjlemon 53478025Sdes sbuf_printf(sb, "Character devices:\n"); 53574135Sjlemon 53678025Sdes for (i = 0; i < NUMCDEVSW; i++) 53774135Sjlemon if (cdevsw[i] != NULL) 53878025Sdes sbuf_printf(sb, "%3d %s\n", i, cdevsw[i]->d_name); 53974135Sjlemon 54078025Sdes sbuf_printf(sb, "\nBlock devices:\n"); 54178025Sdes 54278025Sdes return (0); 54374135Sjlemon} 54474135Sjlemon 54578025Sdesstatic int 54678025Sdeslinprocfs_docmdline(PFS_FILL_ARGS) 54774135Sjlemon{ 54878025Sdes sbuf_printf(sb, "BOOT_IMAGE=%s", kernelname); 54978025Sdes sbuf_printf(sb, " ro root=302\n"); 55078025Sdes return (0); 55178025Sdes} 55274135Sjlemon 55378025Sdes/* 55478025Sdes * Directory structure 55578025Sdes */ 55674135Sjlemon 55778025Sdesstatic struct pfs_node linprocfs_proc_nodes[] = { 55878025Sdes PFS_THIS, 55978025Sdes PFS_PARENT, 56078025Sdes /* name flags uid gid mode data */ 56178025Sdes /* PFS_FILE( "cmdline", 0, 0, 0, 0444, procfs_doproccmdline), */ 56278025Sdes PFS_SYMLINK("exe", 0, 0, 0, 0444, linprocfs_doexelink), 56378025Sdes /* PFS_FILE( "mem", 0, 0, 0, 0444, procfs_domem), */ 56478025Sdes PFS_FILE( "stat", 0, 0, 0, 0444, linprocfs_doprocstat), 56578025Sdes PFS_FILE( "status", 0, 0, 0, 0444, linprocfs_doprocstatus), 56678025Sdes PFS_LASTNODE 56778025Sdes}; 56878025Sdes 56978025Sdesstatic struct pfs_node linprocfs_net_nodes[] = { 57078025Sdes PFS_THIS, 57178025Sdes PFS_PARENT, 57278025Sdes /* name flags uid gid mode data */ 57378025Sdes PFS_FILE( "dev", 0, 0, 0, 0444, linprocfs_donetdev), 57478025Sdes PFS_LASTNODE 57578025Sdes}; 57678025Sdes 57778025Sdesstatic struct pfs_node linprocfs_root_nodes[] = { 57878025Sdes PFS_THIS, 57978025Sdes PFS_PARENT, 58078025Sdes /* name flags uid gid mode data */ 58178025Sdes PFS_FILE( "cmdline", 0, 0, 0, 0444, linprocfs_docmdline), 58278025Sdes PFS_FILE( "cpuinfo", 0, 0, 0, 0444, linprocfs_docpuinfo), 58378025Sdes PFS_FILE( "devices", 0, 0, 0, 0444, linprocfs_dodevices), 58478025Sdes PFS_FILE( "loadavg", 0, 0, 0, 0444, linprocfs_doloadavg), 58578025Sdes PFS_FILE( "meminfo", 0, 0, 0, 0444, linprocfs_domeminfo), 58678025Sdes PFS_FILE( "stat", 0, 0, 0, 0444, linprocfs_dostat), 58778025Sdes PFS_FILE( "uptime", 0, 0, 0, 0444, linprocfs_douptime), 58878025Sdes PFS_FILE( "version", 0, 0, 0, 0444, linprocfs_doversion), 58978025Sdes PFS_DIR( "net", 0, 0, 0, 0555, linprocfs_net_nodes), 59078025Sdes PFS_PROCDIR( 0, 0, 0, 0555, linprocfs_proc_nodes), 59178025Sdes PFS_SYMLINK("self", 0, 0, 0, 0555, linprocfs_doselflink), 59278025Sdes PFS_LASTNODE 59378025Sdes}; 59478025Sdes 59578025Sdesstatic struct pfs_node linprocfs_root = 59678025Sdes PFS_ROOT(linprocfs_root_nodes); 59778025Sdes 59878025SdesPSEUDOFS(linprocfs, linprocfs_root); 59978025SdesMODULE_DEPEND(linprocfs, linux, 1, 1, 1); 60078025SdesMODULE_DEPEND(linprocfs, procfs, 1, 1, 1); 601