xref: /freebsd/sys/compat/linprocfs/linprocfs.c (revision c6e4d7c5bad68558e05ba776fac741e713a558d0)
1 /*
2  * Copyright (c) 1993 Jan-Simon Pendry
3  * Copyright (c) 1993
4  *	The Regents of the University of California.  All rights reserved.
5  *
6  * This code is derived from software contributed to Berkeley by
7  * Jan-Simon Pendry.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  * 3. All advertising materials mentioning features or use of this software
18  *    must display the following acknowledgement:
19  *	This product includes software developed by the University of
20  *	California, Berkeley and its contributors.
21  * 4. Neither the name of the University nor the names of its contributors
22  *    may be used to endorse or promote products derived from this software
23  *    without specific prior written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35  * SUCH DAMAGE.
36  *
37  *	@(#)procfs_status.c	8.4 (Berkeley) 6/15/94
38  *
39  * $FreeBSD$
40  */
41 
42 #include <sys/param.h>
43 #include <sys/systm.h>
44 #include <sys/proc.h>
45 #include <sys/jail.h>
46 #include <sys/vnode.h>
47 #include <sys/blist.h>
48 #include <sys/tty.h>
49 #include <sys/resourcevar.h>
50 #include <i386/linux/linprocfs/linprocfs.h>
51 
52 #include <vm/vm.h>
53 #include <vm/pmap.h>
54 #include <vm/vm_param.h>
55 #include <vm/vm_object.h>
56 #include <vm/swap_pager.h>
57 #include <sys/vmmeter.h>
58 #include <sys/exec.h>
59 
60 #include <machine/md_var.h>
61 #include <machine/cputypes.h>
62 
63 struct proc;
64 
65 int
66 linprocfs_domeminfo(curp, p, pfs, uio)
67 	struct proc *curp;
68 	struct proc *p;
69 	struct pfsnode *pfs;
70 	struct uio *uio;
71 {
72 	char *ps;
73 	int xlen;
74 	int error;
75 	char psbuf[512];		/* XXX - conservative */
76 	unsigned long memtotal;		/* total memory in bytes */
77 	unsigned long memused;		/* used memory in bytes */
78 	unsigned long memfree;		/* free memory in bytes */
79 	unsigned long memshared;	/* shared memory ??? */
80 	unsigned long buffers, cached;	/* buffer / cache memory ??? */
81 	unsigned long swaptotal;	/* total swap space in bytes */
82 	unsigned long swapused;		/* used swap space in bytes */
83 	unsigned long swapfree;		/* free swap space in bytes */
84 	vm_object_t object;
85 
86 	if (uio->uio_rw != UIO_READ)
87 		return (EOPNOTSUPP);
88 
89 	memtotal = physmem * PAGE_SIZE;
90 	/*
91 	 * The correct thing here would be:
92 	 *
93 	memfree = cnt.v_free_count * PAGE_SIZE;
94 	memused = memtotal - memfree;
95 	 *
96 	 * but it might mislead linux binaries into thinking there
97 	 * is very little memory left, so we cheat and tell them that
98 	 * all memory that isn't wired down is free.
99 	 */
100 	memused = cnt.v_wire_count * PAGE_SIZE;
101 	memfree = memtotal - memused;
102 	if (swapblist == NULL) {
103 		swaptotal = 0;
104 		swapfree = 0;
105 	} else {
106 		swaptotal = swapblist->bl_blocks * 1024; /* XXX why 1024? */
107 		swapfree = swapblist->bl_root->u.bmu_avail * PAGE_SIZE;
108 	}
109 	swapused = swaptotal - swapfree;
110 	memshared = 0;
111 	for (object = TAILQ_FIRST(&vm_object_list); object != NULL;
112 	    object = TAILQ_NEXT(object, object_list))
113 		if (object->shadow_count > 1)
114 			memshared += object->resident_page_count;
115 	memshared *= PAGE_SIZE;
116 	/*
117 	 * We'd love to be able to write:
118 	 *
119 	buffers = bufspace;
120 	 *
121 	 * but bufspace is internal to vfs_bio.c and we don't feel
122 	 * like unstaticizing it just for linprocfs's sake.
123 	 */
124 	buffers = 0;
125 	cached = cnt.v_cache_count * PAGE_SIZE;
126 
127 	ps = psbuf;
128 	ps += sprintf(ps,
129 		"        total:    used:    free:  shared: buffers:  cached:\n"
130 		"Mem:  %lu %lu %lu %lu %lu %lu\n"
131 		"Swap: %lu %lu %lu\n"
132 		"MemTotal: %9lu kB\n"
133 		"MemFree:  %9lu kB\n"
134 		"MemShared:%9lu kB\n"
135 		"Buffers:  %9lu kB\n"
136 		"Cached:   %9lu kB\n"
137 		"SwapTotal:%9lu kB\n"
138 		"SwapFree: %9lu kB\n",
139 		memtotal, memused, memfree, memshared, buffers, cached,
140 		swaptotal, swapused, swapfree,
141 		memtotal >> 10, memfree >> 10,
142 		memshared >> 10, buffers >> 10, cached >> 10,
143 		swaptotal >> 10, swapfree >> 10);
144 
145 	xlen = ps - psbuf;
146 	xlen -= uio->uio_offset;
147 	ps = psbuf + uio->uio_offset;
148 	xlen = imin(xlen, uio->uio_resid);
149 	if (xlen <= 0)
150 		error = 0;
151 	else
152 		error = uiomove(ps, xlen, uio);
153 	return (error);
154 }
155 
156 int
157 linprocfs_docpuinfo(curp, p, pfs, uio)
158 	struct proc *curp;
159 	struct proc *p;
160 	struct pfsnode *pfs;
161 	struct uio *uio;
162 {
163 	char *ps;
164 	int xlen;
165 	int error;
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 	if (xlen <= 0)
210 		error = 0;
211 	else
212 		error = uiomove(ps, xlen, uio);
213 	return (error);
214 }
215