1 /* 2 * Copyright (c) 2000 Dag-Erling Co�dan Sm�rgrav 3 * Copyright (c) 1999 Pierre Beyssac 4 * Copyright (c) 1993 Jan-Simon Pendry 5 * Copyright (c) 1993 6 * The Regents of the University of California. All rights reserved. 7 * 8 * This code is derived from software contributed to Berkeley by 9 * Jan-Simon Pendry. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 3. All advertising materials mentioning features or use of this software 20 * must display the following acknowledgement: 21 * This product includes software developed by the University of 22 * California, Berkeley and its contributors. 23 * 4. Neither the name of the University nor the names of its contributors 24 * may be used to endorse or promote products derived from this software 25 * without specific prior written permission. 26 * 27 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 28 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 30 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 31 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 37 * SUCH DAMAGE. 38 * 39 * @(#)procfs_status.c 8.4 (Berkeley) 6/15/94 40 * 41 * $FreeBSD$ 42 */ 43 44 #include <sys/param.h> 45 #include <sys/blist.h> 46 #include <sys/dkstat.h> 47 #include <sys/jail.h> 48 #include <sys/kernel.h> 49 #include <sys/proc.h> 50 #include <sys/resourcevar.h> 51 #include <sys/systm.h> 52 #include <sys/tty.h> 53 #include <sys/vnode.h> 54 55 #include <vm/vm.h> 56 #include <vm/pmap.h> 57 #include <vm/vm_param.h> 58 #include <vm/vm_object.h> 59 #include <vm/swap_pager.h> 60 #include <sys/vmmeter.h> 61 #include <sys/exec.h> 62 63 #include <machine/md_var.h> 64 #include <machine/cputypes.h> 65 66 #include <i386/linux/linprocfs/linprocfs.h> 67 68 #define T2J(x) (((x) * 100) / stathz) 69 #define T2S(x) ((x) / stathz) 70 71 int 72 linprocfs_domeminfo(curp, p, pfs, uio) 73 struct proc *curp; 74 struct proc *p; 75 struct pfsnode *pfs; 76 struct uio *uio; 77 { 78 char *ps; 79 int xlen; 80 char psbuf[512]; /* XXX - conservative */ 81 unsigned long memtotal; /* total memory in bytes */ 82 unsigned long memused; /* used memory in bytes */ 83 unsigned long memfree; /* free memory in bytes */ 84 unsigned long memshared; /* shared memory ??? */ 85 unsigned long buffers, cached; /* buffer / cache memory ??? */ 86 unsigned long swaptotal; /* total swap space in bytes */ 87 unsigned long swapused; /* used swap space in bytes */ 88 unsigned long swapfree; /* free swap space in bytes */ 89 vm_object_t object; 90 91 if (uio->uio_rw != UIO_READ) 92 return (EOPNOTSUPP); 93 94 memtotal = physmem * PAGE_SIZE; 95 /* 96 * The correct thing here would be: 97 * 98 memfree = cnt.v_free_count * PAGE_SIZE; 99 memused = memtotal - memfree; 100 * 101 * but it might mislead linux binaries into thinking there 102 * is very little memory left, so we cheat and tell them that 103 * all memory that isn't wired down is free. 104 */ 105 memused = cnt.v_wire_count * PAGE_SIZE; 106 memfree = memtotal - memused; 107 if (swapblist == NULL) { 108 swaptotal = 0; 109 swapfree = 0; 110 } else { 111 swaptotal = swapblist->bl_blocks * 1024; /* XXX why 1024? */ 112 swapfree = swapblist->bl_root->u.bmu_avail * PAGE_SIZE; 113 } 114 swapused = swaptotal - swapfree; 115 memshared = 0; 116 for (object = TAILQ_FIRST(&vm_object_list); object != NULL; 117 object = TAILQ_NEXT(object, object_list)) 118 if (object->shadow_count > 1) 119 memshared += object->resident_page_count; 120 memshared *= PAGE_SIZE; 121 /* 122 * We'd love to be able to write: 123 * 124 buffers = bufspace; 125 * 126 * but bufspace is internal to vfs_bio.c and we don't feel 127 * like unstaticizing it just for linprocfs's sake. 128 */ 129 buffers = 0; 130 cached = cnt.v_cache_count * PAGE_SIZE; 131 132 ps = psbuf; 133 ps += sprintf(ps, 134 " total: used: free: shared: buffers: cached:\n" 135 "Mem: %lu %lu %lu %lu %lu %lu\n" 136 "Swap: %lu %lu %lu\n" 137 "MemTotal: %9lu kB\n" 138 "MemFree: %9lu kB\n" 139 "MemShared:%9lu kB\n" 140 "Buffers: %9lu kB\n" 141 "Cached: %9lu kB\n" 142 "SwapTotal:%9lu kB\n" 143 "SwapFree: %9lu kB\n", 144 memtotal, memused, memfree, memshared, buffers, cached, 145 swaptotal, swapused, swapfree, 146 memtotal >> 10, memfree >> 10, 147 memshared >> 10, buffers >> 10, cached >> 10, 148 swaptotal >> 10, swapfree >> 10); 149 150 xlen = ps - psbuf; 151 xlen -= uio->uio_offset; 152 ps = psbuf + uio->uio_offset; 153 xlen = imin(xlen, uio->uio_resid); 154 return (xlen <= 0 ? 0 : uiomove(ps, xlen, uio)); 155 } 156 157 int 158 linprocfs_docpuinfo(curp, p, pfs, uio) 159 struct proc *curp; 160 struct proc *p; 161 struct pfsnode *pfs; 162 struct uio *uio; 163 { 164 char *ps; 165 int xlen; 166 char psbuf[512]; /* XXX - conservative */ 167 char *class; 168 #if 0 169 extern char *cpu_model; /* Yuck */ 170 #endif 171 172 if (uio->uio_rw != UIO_READ) 173 return (EOPNOTSUPP); 174 175 switch (cpu_class) { 176 case CPUCLASS_286: 177 class = "286"; 178 break; 179 case CPUCLASS_386: 180 class = "386"; 181 break; 182 case CPUCLASS_486: 183 class = "486"; 184 break; 185 case CPUCLASS_586: 186 class = "586"; 187 break; 188 case CPUCLASS_686: 189 class = "686"; 190 break; 191 default: 192 class = "unknown"; 193 break; 194 } 195 196 ps = psbuf; 197 ps += sprintf(ps, 198 "processor : %d\n" 199 "cpu : %.3s\n" 200 "model : %.20s\n" 201 "vendor_id : %.20s\n" 202 "stepping : %d\n", 203 0, class, "unknown", cpu_vendor, cpu_id); 204 205 xlen = ps - psbuf; 206 xlen -= uio->uio_offset; 207 ps = psbuf + uio->uio_offset; 208 xlen = imin(xlen, uio->uio_resid); 209 return (xlen <= 0 ? 0 : uiomove(ps, xlen, uio)); 210 } 211 212 int 213 linprocfs_dostat(curp, p, pfs, uio) 214 struct proc *curp; 215 struct proc *p; 216 struct pfsnode *pfs; 217 struct uio *uio; 218 { 219 char *ps; 220 char psbuf[512]; 221 int xlen; 222 223 ps = psbuf; 224 ps += sprintf(ps, 225 "cpu %ld %ld %ld %ld\n" 226 "disk 0 0 0 0\n" 227 "page %u %u\n" 228 "swap %u %u\n" 229 "intr %u\n" 230 "ctxt %u\n" 231 "btime %ld\n", 232 T2J(cp_time[CP_USER]), 233 T2J(cp_time[CP_NICE]), 234 T2J(cp_time[CP_SYS] /*+ cp_time[CP_INTR]*/), 235 T2J(cp_time[CP_IDLE]), 236 cnt.v_vnodepgsin, 237 cnt.v_vnodepgsout, 238 cnt.v_swappgsin, 239 cnt.v_swappgsout, 240 cnt.v_intr, 241 cnt.v_swtch, 242 boottime.tv_sec); 243 xlen = ps - psbuf; 244 xlen -= uio->uio_offset; 245 ps = psbuf + uio->uio_offset; 246 xlen = imin(xlen, uio->uio_resid); 247 return (xlen <= 0 ? 0 : uiomove(ps, xlen, uio)); 248 } 249 250 int 251 linprocfs_douptime(curp, p, pfs, uio) 252 struct proc *curp; 253 struct proc *p; 254 struct pfsnode *pfs; 255 struct uio *uio; 256 { 257 char *ps; 258 int xlen; 259 char psbuf[64]; 260 struct timeval tv; 261 long ip, fp; 262 263 getmicrouptime(&tv); 264 ps = psbuf; 265 ps += sprintf(ps, "%ld.%02ld %ld.%02ld\n", 266 tv.tv_sec, tv.tv_usec / 10000, 267 T2S(cp_time[CP_IDLE]), T2J(cp_time[CP_IDLE]) % 100); 268 xlen = ps - psbuf; 269 xlen -= uio->uio_offset; 270 ps = psbuf + uio->uio_offset; 271 xlen = imin(xlen, uio->uio_resid); 272 return (xlen <= 0 ? 0 : uiomove(ps, xlen, uio)); 273 } 274 275 int 276 linprocfs_doversion(curp, p, pfs, uio) 277 struct proc *curp; 278 struct proc *p; 279 struct pfsnode *pfs; 280 struct uio *uio; 281 { 282 char *ps; 283 int xlen; 284 285 ps = version; /* XXX not entirely correct */ 286 for (xlen = 0; ps[xlen] != '\n'; ++xlen) 287 /* nothing */ ; 288 ++xlen; 289 xlen -= uio->uio_offset; 290 ps += uio->uio_offset; 291 xlen = imin(xlen, uio->uio_resid); 292 return (xlen <= 0 ? 0 : uiomove(ps, xlen, uio)); 293 } 294 295