xref: /freebsd-src/sys/compat/linprocfs/linprocfs.c (revision 58c7db14cd71c41f59d80d26d921782c0c27d523)
1898b0535SWarner Losh /*-
2df57947fSPedro F. Giffuni  * SPDX-License-Identifier: BSD-4-Clause
3df57947fSPedro F. Giffuni  *
4e738085bSDag-Erling Smørgrav  * Copyright (c) 2000 Dag-Erling Smørgrav
581dc16f6SDag-Erling Smørgrav  * Copyright (c) 1999 Pierre Beyssac
606ab4b95SMike Smith  * Copyright (c) 1993 Jan-Simon Pendry
706ab4b95SMike Smith  * Copyright (c) 1993
806ab4b95SMike Smith  *	The Regents of the University of California.  All rights reserved.
906ab4b95SMike Smith  *
1006ab4b95SMike Smith  * This code is derived from software contributed to Berkeley by
1106ab4b95SMike Smith  * Jan-Simon Pendry.
1206ab4b95SMike Smith  *
1306ab4b95SMike Smith  * Redistribution and use in source and binary forms, with or without
1406ab4b95SMike Smith  * modification, are permitted provided that the following conditions
1506ab4b95SMike Smith  * are met:
1606ab4b95SMike Smith  * 1. Redistributions of source code must retain the above copyright
1706ab4b95SMike Smith  *    notice, this list of conditions and the following disclaimer.
1806ab4b95SMike Smith  * 2. Redistributions in binary form must reproduce the above copyright
1906ab4b95SMike Smith  *    notice, this list of conditions and the following disclaimer in the
2006ab4b95SMike Smith  *    documentation and/or other materials provided with the distribution.
2106ab4b95SMike Smith  * 3. All advertising materials mentioning features or use of this software
2206ab4b95SMike Smith  *    must display the following acknowledgement:
2306ab4b95SMike Smith  *	This product includes software developed by the University of
2406ab4b95SMike Smith  *	California, Berkeley and its contributors.
2506ab4b95SMike Smith  * 4. Neither the name of the University nor the names of its contributors
2606ab4b95SMike Smith  *    may be used to endorse or promote products derived from this software
2706ab4b95SMike Smith  *    without specific prior written permission.
2806ab4b95SMike Smith  *
2906ab4b95SMike Smith  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
3006ab4b95SMike Smith  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
3106ab4b95SMike Smith  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
3206ab4b95SMike Smith  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
3306ab4b95SMike Smith  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
3406ab4b95SMike Smith  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
3506ab4b95SMike Smith  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
3606ab4b95SMike Smith  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
3706ab4b95SMike Smith  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3806ab4b95SMike Smith  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3906ab4b95SMike Smith  * SUCH DAMAGE.
4006ab4b95SMike Smith  */
4106ab4b95SMike Smith 
424c9db956SJohn Grafton #include "opt_inet.h"
434c9db956SJohn Grafton 
4406ab4b95SMike Smith #include <sys/param.h>
457bbdcdc9SDmitry Chagin #include <sys/systm.h>
4606ab4b95SMike Smith #include <sys/blist.h>
47fb919e4dSMark Murray #include <sys/conf.h>
4868936485SDag-Erling Smørgrav #include <sys/exec.h>
4957b4252eSKonstantin Belousov #include <sys/fcntl.h>
500dd872f5SDag-Erling Smørgrav #include <sys/filedesc.h>
51fb919e4dSMark Murray #include <sys/jail.h>
52ddc0b992SDag-Erling Smørgrav #include <sys/kernel.h>
531c73bcabSEdward Tomasz Napierala #include <sys/limits.h>
5468936485SDag-Erling Smørgrav #include <sys/linker.h>
55fb919e4dSMark Murray #include <sys/lock.h>
56b47ed6cbSJonathan Lemon #include <sys/malloc.h>
573dd8390fSJung-uk Kim #include <sys/msg.h>
5823955314SAlfred Perlstein #include <sys/mutex.h>
597936569bSDag-Erling Smørgrav #include <sys/namei.h>
60ddc0b992SDag-Erling Smørgrav #include <sys/proc.h>
616c82a991SKonstantin Belousov #include <sys/ptrace.h>
627bbdcdc9SDmitry Chagin #include <sys/queue.h>
6306ab4b95SMike Smith #include <sys/resourcevar.h>
64f4d6a773SDag-Erling Smørgrav #include <sys/resource.h>
656e66bfacSDag-Erling Smørgrav #include <sys/sbuf.h>
663dd8390fSJung-uk Kim #include <sys/sem.h>
67978ffef2SEdward Tomasz Napierala #include <sys/shm.h>
683f907e34SDag-Erling Smørgrav #include <sys/smp.h>
6968936485SDag-Erling Smørgrav #include <sys/socket.h>
701c73bcabSEdward Tomasz Napierala #include <sys/syscallsubr.h>
71d9b610a0SJonathan Lemon #include <sys/sysctl.h>
7267d39748SDmitry Chagin #include <sys/sysent.h>
73550be19eSAlexander Leidinger #include <sys/time.h>
74ddc0b992SDag-Erling Smørgrav #include <sys/tty.h>
7568936485SDag-Erling Smørgrav #include <sys/user.h>
769ace8010SEitan Adler #include <sys/uuid.h>
7768936485SDag-Erling Smørgrav #include <sys/vmmeter.h>
78ddc0b992SDag-Erling Smørgrav #include <sys/vnode.h>
79d2b2128aSDoug Ambrisko #include <sys/bus.h>
80b7df7b98SDmitry Chagin #include <sys/uio.h>
8106ab4b95SMike Smith 
8268936485SDag-Erling Smørgrav #include <net/if.h>
8376039bc8SGleb Smirnoff #include <net/if_var.h>
8467d39748SDmitry Chagin #include <net/if_types.h>
8568936485SDag-Erling Smørgrav 
864c9db956SJohn Grafton #include <net/route.h>
874c9db956SJohn Grafton #include <net/route/nhop.h>
884c9db956SJohn Grafton #include <net/route/route_ctl.h>
894c9db956SJohn Grafton 
9006ab4b95SMike Smith #include <vm/vm.h>
91c7462f43SKonstantin Belousov #include <vm/vm_extern.h>
9206ab4b95SMike Smith #include <vm/pmap.h>
93886a6f6fSDag-Erling Smørgrav #include <vm/vm_map.h>
9406ab4b95SMike Smith #include <vm/vm_param.h>
95ce4e34c8SDag-Erling Smørgrav #include <vm/vm_object.h>
9606ab4b95SMike Smith #include <vm/swap_pager.h>
97f786d43aSDag-Erling Smørgrav 
98f8c05e50SDag-Erling Smørgrav #include <machine/clock.h>
994c178576SDag-Erling Smørgrav 
100d2b2128aSDoug Ambrisko #include <geom/geom.h>
101d2b2128aSDoug Ambrisko #include <geom/geom_int.h>
102d2b2128aSDoug Ambrisko 
10384880f87STim J. Robbins #if defined(__i386__) || defined(__amd64__)
10406ab4b95SMike Smith #include <machine/cputypes.h>
105f8c05e50SDag-Erling Smørgrav #include <machine/md_var.h>
10684880f87STim J. Robbins #endif /* __i386__ || __amd64__ */
10706ab4b95SMike Smith 
10894c0ee30SDmitry Chagin #include <compat/linux/linux.h>
1093ab3c9c2SDmitry Chagin #include <compat/linux/linux_common.h>
110b7df7b98SDmitry Chagin #include <compat/linux/linux_emul.h>
1116e66bfacSDag-Erling Smørgrav #include <compat/linux/linux_mib.h>
112d825ce0aSJohn Baldwin #include <compat/linux/linux_misc.h>
1137936569bSDag-Erling Smørgrav #include <compat/linux/linux_util.h>
114f08adc10SDag-Erling Smørgrav #include <fs/pseudofs/pseudofs.h>
115e4fea9d1SDag-Erling Smørgrav #include <fs/procfs/procfs.h>
116ddc0b992SDag-Erling Smørgrav 
117886a6f6fSDag-Erling Smørgrav /*
118886a6f6fSDag-Erling Smørgrav  * Various conversion macros
119886a6f6fSDag-Erling Smørgrav  */
120fc825cc3SAlexander Leidinger #define T2J(x) ((long)(((x) * 100ULL) / (stathz ? stathz : hz)))	/* ticks to jiffies */
121fc825cc3SAlexander Leidinger #define T2CS(x) ((unsigned long)(((x) * 100ULL) / (stathz ? stathz : hz)))	/* ticks to centiseconds */
122886a6f6fSDag-Erling Smørgrav #define T2S(x) ((x) / (stathz ? stathz : hz))		/* ticks to seconds */
123886a6f6fSDag-Erling Smørgrav #define B2K(x) ((x) >> 10)				/* bytes to kbytes */
124f786d43aSDag-Erling Smørgrav #define B2P(x) ((x) >> PAGE_SHIFT)			/* bytes to pages */
125886a6f6fSDag-Erling Smørgrav #define P2B(x) ((x) << PAGE_SHIFT)			/* pages to bytes */
126886a6f6fSDag-Erling Smørgrav #define P2K(x) ((x) << (PAGE_SHIFT - 10))		/* pages to kbytes */
127fc825cc3SAlexander Leidinger #define TV2J(x)	((x)->tv_sec * 100UL + (x)->tv_usec / 10000)
12806ab4b95SMike Smith 
129550be19eSAlexander Leidinger /**
130550be19eSAlexander Leidinger  * @brief Mapping of ki_stat in struct kinfo_proc to the linux state
131550be19eSAlexander Leidinger  *
132550be19eSAlexander Leidinger  * The linux procfs state field displays one of the characters RSDZTW to
133550be19eSAlexander Leidinger  * denote running, sleeping in an interruptible wait, waiting in an
134976b0106SKevin Lo  * uninterruptible disk sleep, a zombie process, process is being traced
135550be19eSAlexander Leidinger  * or stopped, or process is paging respectively.
136550be19eSAlexander Leidinger  *
137550be19eSAlexander Leidinger  * Our struct kinfo_proc contains the variable ki_stat which contains a
138550be19eSAlexander Leidinger  * value out of SIDL, SRUN, SSLEEP, SSTOP, SZOMB, SWAIT and SLOCK.
139550be19eSAlexander Leidinger  *
140550be19eSAlexander Leidinger  * This character array is used with ki_stati-1 as an index and tries to
141550be19eSAlexander Leidinger  * map our states to suitable linux states.
142550be19eSAlexander Leidinger  */
143456ede39SAlexander Leidinger static char linux_state[] = "RRSTZDD";
144550be19eSAlexander Leidinger 
1454c178576SDag-Erling Smørgrav /*
1464c178576SDag-Erling Smørgrav  * Filler function for proc/meminfo
1474c178576SDag-Erling Smørgrav  */
148f08adc10SDag-Erling Smørgrav static int
149f08adc10SDag-Erling Smørgrav linprocfs_domeminfo(PFS_FILL_ARGS)
15006ab4b95SMike Smith {
15106ab4b95SMike Smith 	unsigned long memtotal;		/* total memory in bytes */
15206ab4b95SMike Smith 	unsigned long memfree;		/* free memory in bytes */
1539eb0cd08SMark Johnston 	unsigned long cached;		/* page cache */
1549eb0cd08SMark Johnston 	unsigned long buffers;		/* buffer cache */
1554bedc361SJohn Baldwin 	unsigned long long swaptotal;	/* total swap space in bytes */
1564bedc361SJohn Baldwin 	unsigned long long swapused;	/* used swap space in bytes */
1574bedc361SJohn Baldwin 	unsigned long long swapfree;	/* free swap space in bytes */
1589eb0cd08SMark Johnston 	size_t sz;
1599eb0cd08SMark Johnston 	int error, i, j;
16006ab4b95SMike Smith 
16106ab4b95SMike Smith 	memtotal = physmem * PAGE_SIZE;
1629eb0cd08SMark Johnston 	memfree = (unsigned long)vm_free_count() * PAGE_SIZE;
163567104a1SPoul-Henning Kamp 	swap_pager_status(&i, &j);
16426940197SMax Laier 	swaptotal = (unsigned long long)i * PAGE_SIZE;
16526940197SMax Laier 	swapused = (unsigned long long)j * PAGE_SIZE;
166567104a1SPoul-Henning Kamp 	swapfree = swaptotal - swapused;
1679eb0cd08SMark Johnston 
16806ab4b95SMike Smith 	/*
1699eb0cd08SMark Johnston 	 * This value may exclude wired pages, but we have no good way of
1709eb0cd08SMark Johnston 	 * accounting for that.
17106ab4b95SMike Smith 	 */
1729eb0cd08SMark Johnston 	cached =
1739eb0cd08SMark Johnston 	    (vm_active_count() + vm_inactive_count() + vm_laundry_count()) *
1749eb0cd08SMark Johnston 	    PAGE_SIZE;
1759eb0cd08SMark Johnston 
1769eb0cd08SMark Johnston 	sz = sizeof(buffers);
1779eb0cd08SMark Johnston 	error = kernel_sysctlbyname(curthread, "vfs.bufspace", &buffers, &sz,
1789eb0cd08SMark Johnston 	    NULL, 0, 0, 0);
1799eb0cd08SMark Johnston 	if (error != 0)
18006ab4b95SMike Smith 		buffers = 0;
18106ab4b95SMike Smith 
182f08adc10SDag-Erling Smørgrav 	sbuf_printf(sb,
18306ab4b95SMike Smith 	    "MemTotal: %9lu kB\n"
18406ab4b95SMike Smith 	    "MemFree:  %9lu kB\n"
18506ab4b95SMike Smith 	    "Buffers:  %9lu kB\n"
18606ab4b95SMike Smith 	    "Cached:   %9lu kB\n"
187d9b610a0SJonathan Lemon 	    "SwapTotal:%9llu kB\n"
188d9b610a0SJonathan Lemon 	    "SwapFree: %9llu kB\n",
189dbfe4b26SMateusz Guzik 	    B2K(memtotal), B2K(memfree), B2K(buffers),
190dbfe4b26SMateusz Guzik 	    B2K(cached), B2K(swaptotal), B2K(swapfree));
19106ab4b95SMike Smith 
192f08adc10SDag-Erling Smørgrav 	return (0);
19306ab4b95SMike Smith }
19406ab4b95SMike Smith 
19584880f87STim J. Robbins #if defined(__i386__) || defined(__amd64__)
1964c178576SDag-Erling Smørgrav /*
19784880f87STim J. Robbins  * Filler function for proc/cpuinfo (i386 & amd64 version)
1984c178576SDag-Erling Smørgrav  */
199f08adc10SDag-Erling Smørgrav static int
200f08adc10SDag-Erling Smørgrav linprocfs_docpuinfo(PFS_FILL_ARGS)
20106ab4b95SMike Smith {
2023453537fSJung-uk Kim 	uint64_t freq;
203906ba872SMahdi Mokhtari 	u_int cache_size[4];
2047ab03740SDmitry Chagin 	u_int regs[4] = { 0 };
20538605d73SJohn Baldwin 	int fqmhz, fqkhz;
206906ba872SMahdi Mokhtari 	int i, j;
207bccbc20fSDag-Erling Smørgrav 
208f786d43aSDag-Erling Smørgrav 	/*
209f786d43aSDag-Erling Smørgrav 	 * We default the flags to include all non-conflicting flags,
210f786d43aSDag-Erling Smørgrav 	 * and the Intel versions of conflicting flags.
211f786d43aSDag-Erling Smørgrav 	 */
212967cbe64SEdward Tomasz Napierala 	static char *cpu_feature_names[] = {
213967cbe64SEdward Tomasz Napierala 		/*  0 */ "fpu", "vme", "de", "pse",
214967cbe64SEdward Tomasz Napierala 		/*  4 */ "tsc", "msr", "pae", "mce",
215967cbe64SEdward Tomasz Napierala 		/*  8 */ "cx8", "apic", "", "sep",
216967cbe64SEdward Tomasz Napierala 		/* 12 */ "mtrr", "pge", "mca", "cmov",
217967cbe64SEdward Tomasz Napierala 		/* 16 */ "pat", "pse36", "pn", "clflush",
218967cbe64SEdward Tomasz Napierala 		/* 20 */ "", "dts", "acpi", "mmx",
219967cbe64SEdward Tomasz Napierala 		/* 24 */ "fxsr", "sse", "sse2", "ss",
220967cbe64SEdward Tomasz Napierala 		/* 28 */ "ht", "tm", "ia64", "pbe"
221967cbe64SEdward Tomasz Napierala 	};
222967cbe64SEdward Tomasz Napierala 
223967cbe64SEdward Tomasz Napierala 	static char *amd_feature_names[] = {
224967cbe64SEdward Tomasz Napierala 		/*  0 */ "", "", "", "",
225967cbe64SEdward Tomasz Napierala 		/*  4 */ "", "", "", "",
226967cbe64SEdward Tomasz Napierala 		/*  8 */ "", "", "", "syscall",
227967cbe64SEdward Tomasz Napierala 		/* 12 */ "", "", "", "",
228967cbe64SEdward Tomasz Napierala 		/* 16 */ "", "", "", "mp",
229967cbe64SEdward Tomasz Napierala 		/* 20 */ "nx", "", "mmxext", "",
230967cbe64SEdward Tomasz Napierala 		/* 24 */ "", "fxsr_opt", "pdpe1gb", "rdtscp",
231967cbe64SEdward Tomasz Napierala 		/* 28 */ "", "lm", "3dnowext", "3dnow"
232967cbe64SEdward Tomasz Napierala 	};
233967cbe64SEdward Tomasz Napierala 
234967cbe64SEdward Tomasz Napierala 	static char *cpu_feature2_names[] = {
2358ba7ddddSEdward Tomasz Napierala 		/*  0 */ "pni", "pclmulqdq", "dtes64", "monitor",
236967cbe64SEdward Tomasz Napierala 		/*  4 */ "ds_cpl", "vmx", "smx", "est",
237967cbe64SEdward Tomasz Napierala 		/*  8 */ "tm2", "ssse3", "cid", "sdbg",
2388ba7ddddSEdward Tomasz Napierala 		/* 12 */ "fma", "cx16", "xtpr", "pdcm",
239967cbe64SEdward Tomasz Napierala 		/* 16 */ "", "pcid", "dca", "sse4_1",
240967cbe64SEdward Tomasz Napierala 		/* 20 */ "sse4_2", "x2apic", "movbe", "popcnt",
241967cbe64SEdward Tomasz Napierala 		/* 24 */ "tsc_deadline_timer", "aes", "xsave", "",
242967cbe64SEdward Tomasz Napierala 		/* 28 */ "avx", "f16c", "rdrand", "hypervisor"
243967cbe64SEdward Tomasz Napierala 	};
244967cbe64SEdward Tomasz Napierala 
245967cbe64SEdward Tomasz Napierala 	static char *amd_feature2_names[] = {
246967cbe64SEdward Tomasz Napierala 		/*  0 */ "lahf_lm", "cmp_legacy", "svm", "extapic",
247967cbe64SEdward Tomasz Napierala 		/*  4 */ "cr8_legacy", "abm", "sse4a", "misalignsse",
248967cbe64SEdward Tomasz Napierala 		/*  8 */ "3dnowprefetch", "osvw", "ibs", "xop",
249967cbe64SEdward Tomasz Napierala 		/* 12 */ "skinit", "wdt", "", "lwp",
250967cbe64SEdward Tomasz Napierala 		/* 16 */ "fma4", "tce", "", "nodeid_msr",
251967cbe64SEdward Tomasz Napierala 		/* 20 */ "", "tbm", "topoext", "perfctr_core",
252967cbe64SEdward Tomasz Napierala 		/* 24 */ "perfctr_nb", "", "bpext", "ptsc",
253967cbe64SEdward Tomasz Napierala 		/* 28 */ "perfctr_llc", "mwaitx", "", ""
254967cbe64SEdward Tomasz Napierala 	};
255967cbe64SEdward Tomasz Napierala 
256967cbe64SEdward Tomasz Napierala 	static char *cpu_stdext_feature_names[] = {
257c8e7070cSDmitry Chagin 		/*  0 */ "fsgsbase", "tsc_adjust", "sgx", "bmi1",
258967cbe64SEdward Tomasz Napierala 		/*  4 */ "hle", "avx2", "", "smep",
259967cbe64SEdward Tomasz Napierala 		/*  8 */ "bmi2", "erms", "invpcid", "rtm",
260967cbe64SEdward Tomasz Napierala 		/* 12 */ "cqm", "", "mpx", "rdt_a",
261967cbe64SEdward Tomasz Napierala 		/* 16 */ "avx512f", "avx512dq", "rdseed", "adx",
262967cbe64SEdward Tomasz Napierala 		/* 20 */ "smap", "avx512ifma", "", "clflushopt",
263967cbe64SEdward Tomasz Napierala 		/* 24 */ "clwb", "intel_pt", "avx512pf", "avx512er",
264967cbe64SEdward Tomasz Napierala 		/* 28 */ "avx512cd", "sha_ni", "avx512bw", "avx512vl"
265f8c05e50SDag-Erling Smørgrav 	};
26606ab4b95SMike Smith 
2677ab03740SDmitry Chagin 	static char *cpu_stdext_feature2_names[] = {
2687ab03740SDmitry Chagin 		/*  0 */ "prefetchwt1", "avx512vbmi", "umip", "pku",
2697ab03740SDmitry Chagin 		/*  4 */ "ospke", "waitpkg", "avx512_vbmi2", "",
2707ab03740SDmitry Chagin 		/*  8 */ "gfni", "vaes", "vpclmulqdq", "avx512_vnni",
2717ab03740SDmitry Chagin 		/* 12 */ "avx512_bitalg", "", "avx512_vpopcntdq", "",
2727ab03740SDmitry Chagin 		/* 16 */ "", "", "", "",
2737ab03740SDmitry Chagin 		/* 20 */ "", "", "rdpid", "",
2747ab03740SDmitry Chagin 		/* 24 */ "", "cldemote", "", "movdiri",
2757ab03740SDmitry Chagin 		/* 28 */ "movdir64b", "enqcmd", "sgx_lc", ""
2767ab03740SDmitry Chagin 	};
2777ab03740SDmitry Chagin 
2787ab03740SDmitry Chagin 	static char *cpu_stdext_feature3_names[] = {
2797ab03740SDmitry Chagin 		/*  0 */ "", "", "avx512_4vnniw", "avx512_4fmaps",
2807ab03740SDmitry Chagin 		/*  4 */ "fsrm", "", "", "",
2817ab03740SDmitry Chagin 		/*  8 */ "avx512_vp2intersect", "", "md_clear", "",
2827ab03740SDmitry Chagin 		/* 12 */ "", "", "", "",
2837ab03740SDmitry Chagin 		/* 16 */ "", "", "pconfig", "",
2847ab03740SDmitry Chagin 		/* 20 */ "", "", "", "",
2857ab03740SDmitry Chagin 		/* 24 */ "", "", "ibrs", "stibp",
2867ab03740SDmitry Chagin 		/* 28 */ "flush_l1d", "arch_capabilities", "core_capabilities", "ssbd"
2877ab03740SDmitry Chagin 	};
2887ab03740SDmitry Chagin 
2897ab03740SDmitry Chagin 	static char *cpu_stdext_feature_l1_names[] = {
2907ab03740SDmitry Chagin 		/*  0 */ "xsaveopt", "xsavec", "xgetbv1", "xsaves",
2917ab03740SDmitry Chagin 		/*  4 */ "xfd"
2927ab03740SDmitry Chagin 	};
2937ab03740SDmitry Chagin 
294906ba872SMahdi Mokhtari 	static char *power_flags[] = {
295906ba872SMahdi Mokhtari 		"ts",           "fid",          "vid",
296906ba872SMahdi Mokhtari 		"ttp",          "tm",           "stc",
297906ba872SMahdi Mokhtari 		"100mhzsteps",  "hwpstate",     "",
298906ba872SMahdi Mokhtari 		"cpb",          "eff_freq_ro",  "proc_feedback",
299906ba872SMahdi Mokhtari 		"acc_power",
300906ba872SMahdi Mokhtari 	};
301906ba872SMahdi Mokhtari 
30234fe8947SJung-uk Kim #ifdef __i386__
30334fe8947SJung-uk Kim 	switch (cpu_vendor_id) {
30434fe8947SJung-uk Kim 	case CPU_VENDOR_AMD:
30538605d73SJohn Baldwin 		if (cpu_class < CPUCLASS_686)
306967cbe64SEdward Tomasz Napierala 			cpu_feature_names[16] = "fcmov";
30734fe8947SJung-uk Kim 		break;
30834fe8947SJung-uk Kim 	case CPU_VENDOR_CYRIX:
309967cbe64SEdward Tomasz Napierala 		cpu_feature_names[24] = "cxmmx";
31034fe8947SJung-uk Kim 		break;
311f8c05e50SDag-Erling Smørgrav 	}
31234fe8947SJung-uk Kim #endif
3134b360806SMahdi Mokhtari 	if (cpu_exthigh >= 0x80000006)
314906ba872SMahdi Mokhtari 		do_cpuid(0x80000006, cache_size);
3154b360806SMahdi Mokhtari 	else
3164b360806SMahdi Mokhtari 		memset(cache_size, 0, sizeof(cache_size));
317906ba872SMahdi Mokhtari 	for (i = 0; i < mp_ncpus; ++i) {
318906ba872SMahdi Mokhtari 		fqmhz = 0;
319906ba872SMahdi Mokhtari 		fqkhz = 0;
3203453537fSJung-uk Kim 		freq = atomic_load_acq_64(&tsc_freq);
3213453537fSJung-uk Kim 		if (freq != 0) {
3223453537fSJung-uk Kim 			fqmhz = (freq + 4999) / 1000000;
3233453537fSJung-uk Kim 			fqkhz = ((freq + 4999) / 10000) % 100;
324f8c05e50SDag-Erling Smørgrav 		}
325906ba872SMahdi Mokhtari 		sbuf_printf(sb,
326906ba872SMahdi Mokhtari 		    "processor\t: %d\n"
327906ba872SMahdi Mokhtari 		    "vendor_id\t: %.20s\n"
328906ba872SMahdi Mokhtari 		    "cpu family\t: %u\n"
329906ba872SMahdi Mokhtari 		    "model\t\t: %u\n"
330906ba872SMahdi Mokhtari 		    "model name\t: %s\n"
331906ba872SMahdi Mokhtari 		    "stepping\t: %u\n"
332906ba872SMahdi Mokhtari 		    "cpu MHz\t\t: %d.%02d\n"
333906ba872SMahdi Mokhtari 		    "cache size\t: %d KB\n"
334906ba872SMahdi Mokhtari 		    "physical id\t: %d\n"
335906ba872SMahdi Mokhtari 		    "siblings\t: %d\n"
336906ba872SMahdi Mokhtari 		    "core id\t\t: %d\n"
337906ba872SMahdi Mokhtari 		    "cpu cores\t: %d\n"
338906ba872SMahdi Mokhtari 		    "apicid\t\t: %d\n"
339906ba872SMahdi Mokhtari 		    "initial apicid\t: %d\n"
340906ba872SMahdi Mokhtari 		    "fpu\t\t: %s\n"
341906ba872SMahdi Mokhtari 		    "fpu_exception\t: %s\n"
342906ba872SMahdi Mokhtari 		    "cpuid level\t: %d\n"
343906ba872SMahdi Mokhtari 		    "wp\t\t: %s\n",
344906ba872SMahdi Mokhtari 		    i, cpu_vendor, CPUID_TO_FAMILY(cpu_id),
345d74a7427SMark Johnston 		    CPUID_TO_MODEL(cpu_id), cpu_model, cpu_id & CPUID_STEPPING,
346906ba872SMahdi Mokhtari 		    fqmhz, fqkhz,
347906ba872SMahdi Mokhtari 		    (cache_size[2] >> 16), 0, mp_ncpus, i, mp_ncpus,
348906ba872SMahdi Mokhtari 		    i, i, /*cpu_id & CPUID_LOCAL_APIC_ID ??*/
349906ba872SMahdi Mokhtari 		    (cpu_feature & CPUID_FPU) ? "yes" : "no", "yes",
350906ba872SMahdi Mokhtari 		    CPUID_TO_FAMILY(cpu_id), "yes");
351906ba872SMahdi Mokhtari 		sbuf_cat(sb, "flags\t\t:");
352967cbe64SEdward Tomasz Napierala 		for (j = 0; j < nitems(cpu_feature_names); j++)
353967cbe64SEdward Tomasz Napierala 			if (cpu_feature & (1 << j) &&
354967cbe64SEdward Tomasz Napierala 			    cpu_feature_names[j][0] != '\0')
355967cbe64SEdward Tomasz Napierala 				sbuf_printf(sb, " %s", cpu_feature_names[j]);
356967cbe64SEdward Tomasz Napierala 		for (j = 0; j < nitems(amd_feature_names); j++)
357967cbe64SEdward Tomasz Napierala 			if (amd_feature & (1 << j) &&
358967cbe64SEdward Tomasz Napierala 			    amd_feature_names[j][0] != '\0')
359967cbe64SEdward Tomasz Napierala 				sbuf_printf(sb, " %s", amd_feature_names[j]);
360967cbe64SEdward Tomasz Napierala 		for (j = 0; j < nitems(cpu_feature2_names); j++)
361967cbe64SEdward Tomasz Napierala 			if (cpu_feature2 & (1 << j) &&
362967cbe64SEdward Tomasz Napierala 			    cpu_feature2_names[j][0] != '\0')
363967cbe64SEdward Tomasz Napierala 				sbuf_printf(sb, " %s", cpu_feature2_names[j]);
364967cbe64SEdward Tomasz Napierala 		for (j = 0; j < nitems(amd_feature2_names); j++)
365967cbe64SEdward Tomasz Napierala 			if (amd_feature2 & (1 << j) &&
366967cbe64SEdward Tomasz Napierala 			    amd_feature2_names[j][0] != '\0')
367967cbe64SEdward Tomasz Napierala 				sbuf_printf(sb, " %s", amd_feature2_names[j]);
368967cbe64SEdward Tomasz Napierala 		for (j = 0; j < nitems(cpu_stdext_feature_names); j++)
369967cbe64SEdward Tomasz Napierala 			if (cpu_stdext_feature & (1 << j) &&
370967cbe64SEdward Tomasz Napierala 			    cpu_stdext_feature_names[j][0] != '\0')
371967cbe64SEdward Tomasz Napierala 				sbuf_printf(sb, " %s",
372967cbe64SEdward Tomasz Napierala 				    cpu_stdext_feature_names[j]);
3738da00a51SDmitry Chagin 		if (tsc_is_invariant)
3748da00a51SDmitry Chagin 			sbuf_cat(sb, " constant_tsc");
3757ab03740SDmitry Chagin 		for (j = 0; j < nitems(cpu_stdext_feature2_names); j++)
3767ab03740SDmitry Chagin 			if (cpu_stdext_feature2 & (1 << j) &&
3777ab03740SDmitry Chagin 			    cpu_stdext_feature2_names[j][0] != '\0')
3787ab03740SDmitry Chagin 				sbuf_printf(sb, " %s",
3797ab03740SDmitry Chagin 				    cpu_stdext_feature2_names[j]);
3807ab03740SDmitry Chagin 		for (j = 0; j < nitems(cpu_stdext_feature3_names); j++)
3817ab03740SDmitry Chagin 			if (cpu_stdext_feature3 & (1 << j) &&
3827ab03740SDmitry Chagin 			    cpu_stdext_feature3_names[j][0] != '\0')
3837ab03740SDmitry Chagin 				sbuf_printf(sb, " %s",
3847ab03740SDmitry Chagin 				    cpu_stdext_feature3_names[j]);
3857ab03740SDmitry Chagin 		if ((cpu_feature2 & CPUID2_XSAVE) != 0) {
3867ab03740SDmitry Chagin 			cpuid_count(0xd, 0x1, regs);
3877ab03740SDmitry Chagin 			for (j = 0; j < nitems(cpu_stdext_feature_l1_names); j++)
3887ab03740SDmitry Chagin 				if (regs[0] & (1 << j) &&
3897ab03740SDmitry Chagin 				    cpu_stdext_feature_l1_names[j][0] != '\0')
3907ab03740SDmitry Chagin 					sbuf_printf(sb, " %s",
3917ab03740SDmitry Chagin 					    cpu_stdext_feature_l1_names[j]);
3927ab03740SDmitry Chagin 		}
393906ba872SMahdi Mokhtari 		sbuf_cat(sb, "\n");
394906ba872SMahdi Mokhtari 		sbuf_printf(sb,
395906ba872SMahdi Mokhtari 		    "bugs\t\t: %s\n"
396906ba872SMahdi Mokhtari 		    "bogomips\t: %d.%02d\n"
397906ba872SMahdi Mokhtari 		    "clflush size\t: %d\n"
398906ba872SMahdi Mokhtari 		    "cache_alignment\t: %d\n"
399906ba872SMahdi Mokhtari 		    "address sizes\t: %d bits physical, %d bits virtual\n",
400906ba872SMahdi Mokhtari #if defined(I586_CPU) && !defined(NO_F00F_HACK)
401906ba872SMahdi Mokhtari 		    (has_f00f_bug) ? "Intel F00F" : "",
402906ba872SMahdi Mokhtari #else
403906ba872SMahdi Mokhtari 		    "",
404906ba872SMahdi Mokhtari #endif
4057ce051e7SEdward Tomasz Napierala 		    fqmhz * 2, fqkhz,
406906ba872SMahdi Mokhtari 		    cpu_clflush_line_size, cpu_clflush_line_size,
407906ba872SMahdi Mokhtari 		    cpu_maxphyaddr,
408906ba872SMahdi Mokhtari 		    (cpu_maxphyaddr > 32) ? 48 : 0);
409906ba872SMahdi Mokhtari 		sbuf_cat(sb, "power management: ");
410906ba872SMahdi Mokhtari 		for (j = 0; j < nitems(power_flags); j++)
411906ba872SMahdi Mokhtari 			if (amd_pminfo & (1 << j))
412906ba872SMahdi Mokhtari 				sbuf_printf(sb, " %s", power_flags[j]);
413906ba872SMahdi Mokhtari 		sbuf_cat(sb, "\n\n");
414906ba872SMahdi Mokhtari 
415906ba872SMahdi Mokhtari 		/* XXX per-cpu vendor / class / model / id? */
416906ba872SMahdi Mokhtari 	}
417906ba872SMahdi Mokhtari 	sbuf_cat(sb, "\n");
41806ab4b95SMike Smith 
419f08adc10SDag-Erling Smørgrav 	return (0);
42006ab4b95SMike Smith }
4216a1d1e0cSEd Maste #else
4226a1d1e0cSEd Maste /* ARM64TODO: implement non-stubbed linprocfs_docpuinfo */
4236a1d1e0cSEd Maste static int
4246a1d1e0cSEd Maste linprocfs_docpuinfo(PFS_FILL_ARGS)
4256a1d1e0cSEd Maste {
4266a1d1e0cSEd Maste 	int i;
4276a1d1e0cSEd Maste 
4286a1d1e0cSEd Maste 	for (i = 0; i < mp_ncpus; ++i) {
4296a1d1e0cSEd Maste 		sbuf_printf(sb,
4306a1d1e0cSEd Maste 		    "processor\t: %d\n"
4316a1d1e0cSEd Maste 		    "BogoMIPS\t: %d.%02d\n",
4326a1d1e0cSEd Maste 		    i, 0, 0);
4336a1d1e0cSEd Maste 		sbuf_cat(sb, "Features\t: ");
4346a1d1e0cSEd Maste 		sbuf_cat(sb, "\n");
4356a1d1e0cSEd Maste 		sbuf_printf(sb,
4366a1d1e0cSEd Maste 		    "CPU implementer\t: \n"
4376a1d1e0cSEd Maste 		    "CPU architecture: \n"
4386a1d1e0cSEd Maste 		    "CPU variant\t: 0x%x\n"
4396a1d1e0cSEd Maste 		    "CPU part\t: 0x%x\n"
4406a1d1e0cSEd Maste 		    "CPU revision\t: %d\n",
4416a1d1e0cSEd Maste 		    0, 0, 0);
4426a1d1e0cSEd Maste 		sbuf_cat(sb, "\n");
4436a1d1e0cSEd Maste 	}
4446a1d1e0cSEd Maste 
4456a1d1e0cSEd Maste 	return (0);
4466a1d1e0cSEd Maste }
44784880f87STim J. Robbins #endif /* __i386__ || __amd64__ */
448ddc0b992SDag-Erling Smørgrav 
449b1976ea1SConrad Meyer static const char *path_slash_sys = "/sys";
450b1976ea1SConrad Meyer static const char *fstype_sysfs = "sysfs";
451b1976ea1SConrad Meyer 
452b1976ea1SConrad Meyer static int
453b1976ea1SConrad Meyer _mtab_helper(const struct pfs_node *pn, const struct statfs *sp,
454b1976ea1SConrad Meyer     const char **mntfrom, const char **mntto, const char **fstype)
455b1976ea1SConrad Meyer {
456b1976ea1SConrad Meyer 	/* determine device name */
457b1976ea1SConrad Meyer 	*mntfrom = sp->f_mntfromname;
458b1976ea1SConrad Meyer 
459b1976ea1SConrad Meyer 	/* determine mount point */
460b1976ea1SConrad Meyer 	*mntto = sp->f_mntonname;
461b1976ea1SConrad Meyer 
462b1976ea1SConrad Meyer 	/* determine fs type */
463b1976ea1SConrad Meyer 	*fstype = sp->f_fstypename;
464b1976ea1SConrad Meyer 	if (strcmp(*fstype, pn->pn_info->pi_name) == 0)
465b1976ea1SConrad Meyer 		*mntfrom = *fstype = "proc";
466b1976ea1SConrad Meyer 	else if (strcmp(*fstype, "procfs") == 0)
467b1976ea1SConrad Meyer 		return (ECANCELED);
468b1976ea1SConrad Meyer 
469b1976ea1SConrad Meyer 	if (strcmp(*fstype, "autofs") == 0) {
4704c178576SDag-Erling Smørgrav 		/*
471b1976ea1SConrad Meyer 		 * FreeBSD uses eg "map -hosts", whereas Linux
472b1976ea1SConrad Meyer 		 * expects just "-hosts".
473b1976ea1SConrad Meyer 		 */
474b1976ea1SConrad Meyer 		if (strncmp(*mntfrom, "map ", 4) == 0)
475b1976ea1SConrad Meyer 			*mntfrom += 4;
476b1976ea1SConrad Meyer 	}
477b1976ea1SConrad Meyer 
478b1976ea1SConrad Meyer 	if (strcmp(*fstype, "linsysfs") == 0) {
479b1976ea1SConrad Meyer 		*mntfrom = path_slash_sys;
480b1976ea1SConrad Meyer 		*fstype = fstype_sysfs;
481b1976ea1SConrad Meyer 	} else {
482b1976ea1SConrad Meyer 		/* For Linux msdosfs is called vfat */
483b1976ea1SConrad Meyer 		if (strcmp(*fstype, "msdosfs") == 0)
484b1976ea1SConrad Meyer 			*fstype = "vfat";
485b1976ea1SConrad Meyer 	}
486b1976ea1SConrad Meyer 	return (0);
487b1976ea1SConrad Meyer }
488b1976ea1SConrad Meyer 
489b1976ea1SConrad Meyer static void
490b1976ea1SConrad Meyer _sbuf_mntoptions_helper(struct sbuf *sb, uint64_t f_flags)
491b1976ea1SConrad Meyer {
492b1976ea1SConrad Meyer 	sbuf_cat(sb, (f_flags & MNT_RDONLY) ? "ro" : "rw");
493b1976ea1SConrad Meyer #define ADD_OPTION(opt, name) \
494b1976ea1SConrad Meyer 	if (f_flags & (opt)) sbuf_cat(sb, "," name);
495b1976ea1SConrad Meyer 	ADD_OPTION(MNT_SYNCHRONOUS,	"sync");
496b1976ea1SConrad Meyer 	ADD_OPTION(MNT_NOEXEC,		"noexec");
497b1976ea1SConrad Meyer 	ADD_OPTION(MNT_NOSUID,		"nosuid");
498b1976ea1SConrad Meyer 	ADD_OPTION(MNT_UNION,		"union");
499b1976ea1SConrad Meyer 	ADD_OPTION(MNT_ASYNC,		"async");
500b1976ea1SConrad Meyer 	ADD_OPTION(MNT_SUIDDIR,		"suiddir");
501b1976ea1SConrad Meyer 	ADD_OPTION(MNT_NOSYMFOLLOW,	"nosymfollow");
502b1976ea1SConrad Meyer 	ADD_OPTION(MNT_NOATIME,		"noatime");
503b1976ea1SConrad Meyer #undef ADD_OPTION
504b1976ea1SConrad Meyer }
505b1976ea1SConrad Meyer 
506b1976ea1SConrad Meyer /*
507b1976ea1SConrad Meyer  * Filler function for proc/mtab and proc/<pid>/mounts.
5087936569bSDag-Erling Smørgrav  *
509b1976ea1SConrad Meyer  * /proc/mtab doesn't exist in Linux' procfs, but is included here so
5107936569bSDag-Erling Smørgrav  * users can symlink /compat/linux/etc/mtab to /proc/mtab
5117936569bSDag-Erling Smørgrav  */
5127936569bSDag-Erling Smørgrav static int
5137936569bSDag-Erling Smørgrav linprocfs_domtab(PFS_FILL_ARGS)
5147936569bSDag-Erling Smørgrav {
515a482fffcSDmitry Chagin 	const char *mntto, *mntfrom, *fstype;
516b1976ea1SConrad Meyer 	char *dlep, *flep;
517a482fffcSDmitry Chagin 	struct vnode *vp;
518a482fffcSDmitry Chagin 	struct pwd *pwd;
5197936569bSDag-Erling Smørgrav 	size_t lep_len;
5207936569bSDag-Erling Smørgrav 	int error;
5211c73bcabSEdward Tomasz Napierala 	struct statfs *buf, *sp;
5221c73bcabSEdward Tomasz Napierala 	size_t count;
5237936569bSDag-Erling Smørgrav 
524b1976ea1SConrad Meyer 	/*
525a482fffcSDmitry Chagin 	 * Resolve emulation tree prefix
526b1976ea1SConrad Meyer 	 */
5277936569bSDag-Erling Smørgrav 	flep = NULL;
528a482fffcSDmitry Chagin 	pwd = pwd_hold(td);
529a482fffcSDmitry Chagin 	vp = pwd->pwd_adir;
530a482fffcSDmitry Chagin 	error = vn_fullpath_global(vp, &dlep, &flep);
531a482fffcSDmitry Chagin 	pwd_drop(pwd);
532a482fffcSDmitry Chagin 	if (error != 0)
533a482fffcSDmitry Chagin 		return (error);
534a482fffcSDmitry Chagin 	lep_len = strlen(dlep);
5357936569bSDag-Erling Smørgrav 
5361c73bcabSEdward Tomasz Napierala 	buf = NULL;
5371c73bcabSEdward Tomasz Napierala 	error = kern_getfsstat(td, &buf, SIZE_T_MAX, &count,
5381c73bcabSEdward Tomasz Napierala 	    UIO_SYSSPACE, MNT_WAIT);
5391c73bcabSEdward Tomasz Napierala 	if (error != 0) {
540*58c7db14SMichael Osipov 		goto out;
5411c73bcabSEdward Tomasz Napierala 	}
5421c73bcabSEdward Tomasz Napierala 
5431c73bcabSEdward Tomasz Napierala 	for (sp = buf; count > 0; sp++, count--) {
544b1976ea1SConrad Meyer 		error = _mtab_helper(pn, sp, &mntfrom, &mntto, &fstype);
545b1976ea1SConrad Meyer 		if (error != 0) {
546b1976ea1SConrad Meyer 			MPASS(error == ECANCELED);
547b1976ea1SConrad Meyer 			continue;
548b1976ea1SConrad Meyer 		}
5497936569bSDag-Erling Smørgrav 
5507936569bSDag-Erling Smørgrav 		/* determine mount point */
551a482fffcSDmitry Chagin 		if (strncmp(mntto, dlep, lep_len) == 0 && mntto[lep_len] == '/')
5527936569bSDag-Erling Smørgrav 			mntto += lep_len;
5537936569bSDag-Erling Smørgrav 
554b1976ea1SConrad Meyer 		sbuf_printf(sb, "%s %s %s ", mntfrom, mntto, fstype);
555b1976ea1SConrad Meyer 		_sbuf_mntoptions_helper(sb, sp->f_flags);
5567936569bSDag-Erling Smørgrav 		/* a real Linux mtab will also show NFS options */
5577936569bSDag-Erling Smørgrav 		sbuf_printf(sb, " 0 0\n");
5587936569bSDag-Erling Smørgrav 	}
5591c73bcabSEdward Tomasz Napierala 
560*58c7db14SMichael Osipov 	error = 0;
561*58c7db14SMichael Osipov out:
5621c73bcabSEdward Tomasz Napierala 	free(buf, M_TEMP);
5637936569bSDag-Erling Smørgrav 	free(flep, M_TEMP);
5647936569bSDag-Erling Smørgrav 	return (error);
5657936569bSDag-Erling Smørgrav }
5667936569bSDag-Erling Smørgrav 
567b1976ea1SConrad Meyer static int
568b1976ea1SConrad Meyer linprocfs_doprocmountinfo(PFS_FILL_ARGS)
569b1976ea1SConrad Meyer {
570b1976ea1SConrad Meyer 	const char *mntfrom, *mntto, *fstype;
571b1976ea1SConrad Meyer 	char *dlep, *flep;
572b1976ea1SConrad Meyer 	struct statfs *buf, *sp;
573b1976ea1SConrad Meyer 	size_t count, lep_len;
574a482fffcSDmitry Chagin 	struct vnode *vp;
575a482fffcSDmitry Chagin 	struct pwd *pwd;
576b1976ea1SConrad Meyer 	int error;
577b1976ea1SConrad Meyer 
578b1976ea1SConrad Meyer 	/*
579a482fffcSDmitry Chagin 	 * Resolve emulation tree prefix
580b1976ea1SConrad Meyer 	 */
581b1976ea1SConrad Meyer 	flep = NULL;
582a482fffcSDmitry Chagin 	pwd = pwd_hold(td);
583a482fffcSDmitry Chagin 	vp = pwd->pwd_adir;
584a482fffcSDmitry Chagin 	error = vn_fullpath_global(vp, &dlep, &flep);
585a482fffcSDmitry Chagin 	pwd_drop(pwd);
586a482fffcSDmitry Chagin 	if (error != 0)
587a482fffcSDmitry Chagin 		return (error);
588a482fffcSDmitry Chagin 	lep_len = strlen(dlep);
589b1976ea1SConrad Meyer 
590b1976ea1SConrad Meyer 	buf = NULL;
591b1976ea1SConrad Meyer 	error = kern_getfsstat(td, &buf, SIZE_T_MAX, &count,
592b1976ea1SConrad Meyer 	    UIO_SYSSPACE, MNT_WAIT);
593b1976ea1SConrad Meyer 	if (error != 0)
594b1976ea1SConrad Meyer 		goto out;
595b1976ea1SConrad Meyer 
596b1976ea1SConrad Meyer 	for (sp = buf; count > 0; sp++, count--) {
597b1976ea1SConrad Meyer 		error = _mtab_helper(pn, sp, &mntfrom, &mntto, &fstype);
598b1976ea1SConrad Meyer 		if (error != 0) {
599b1976ea1SConrad Meyer 			MPASS(error == ECANCELED);
600b1976ea1SConrad Meyer 			continue;
601b1976ea1SConrad Meyer 		}
602b1976ea1SConrad Meyer 
603a482fffcSDmitry Chagin 		if (strncmp(mntto, dlep, lep_len) == 0 && mntto[lep_len] == '/')
604b1976ea1SConrad Meyer 			mntto += lep_len;
605b1976ea1SConrad Meyer #if 0
606b1976ea1SConrad Meyer 		/*
607b1976ea1SConrad Meyer 		 * If the prefix is a chroot, and this mountpoint is not under
608b1976ea1SConrad Meyer 		 * the prefix, we should skip it.  Leave it for now for
609b1976ea1SConrad Meyer 		 * consistency with procmtab above.
610b1976ea1SConrad Meyer 		 */
611b1976ea1SConrad Meyer 		else
612b1976ea1SConrad Meyer 			continue;
613b1976ea1SConrad Meyer #endif
614b1976ea1SConrad Meyer 
615b1976ea1SConrad Meyer 		/*
616b1976ea1SConrad Meyer 		 * (1) mount id
617b1976ea1SConrad Meyer 		 *
618b1976ea1SConrad Meyer 		 * (2) parent mount id -- we don't have this cheaply, so
619b1976ea1SConrad Meyer 		 * provide a dummy value
620b1976ea1SConrad Meyer 		 *
621b1976ea1SConrad Meyer 		 * (3) major:minor -- ditto
622b1976ea1SConrad Meyer 		 *
623b1976ea1SConrad Meyer 		 * (4) root filesystem mount -- probably a namespaces thing
624b1976ea1SConrad Meyer 		 *
625b1976ea1SConrad Meyer 		 * (5) mountto path
626b1976ea1SConrad Meyer 		 */
627b1976ea1SConrad Meyer 		sbuf_printf(sb, "%u 0 0:0 / %s ",
628b1976ea1SConrad Meyer 		    sp->f_fsid.val[0] ^ sp->f_fsid.val[1], mntto);
629b1976ea1SConrad Meyer 		/* (6) mount options */
630b1976ea1SConrad Meyer 		_sbuf_mntoptions_helper(sb, sp->f_flags);
631b1976ea1SConrad Meyer 		/*
632b1976ea1SConrad Meyer 		 * (7) zero or more optional fields -- again, namespace related
633b1976ea1SConrad Meyer 		 *
634b1976ea1SConrad Meyer 		 * (8) End of variable length fields separator ("-")
635b1976ea1SConrad Meyer 		 *
636b1976ea1SConrad Meyer 		 * (9) fstype
637b1976ea1SConrad Meyer 		 *
638b1976ea1SConrad Meyer 		 * (10) mount from
639b1976ea1SConrad Meyer 		 *
640b1976ea1SConrad Meyer 		 * (11) "superblock" options -- like (6), but different
641b1976ea1SConrad Meyer 		 * semantics in Linux
642b1976ea1SConrad Meyer 		 */
643b1976ea1SConrad Meyer 		sbuf_printf(sb, " - %s %s %s\n", fstype, mntfrom,
644b1976ea1SConrad Meyer 		    (sp->f_flags & MNT_RDONLY) ? "ro" : "rw");
645b1976ea1SConrad Meyer 	}
646b1976ea1SConrad Meyer 
647b1976ea1SConrad Meyer 	error = 0;
648b1976ea1SConrad Meyer out:
649b1976ea1SConrad Meyer 	free(buf, M_TEMP);
650b1976ea1SConrad Meyer 	free(flep, M_TEMP);
651b1976ea1SConrad Meyer 	return (error);
652b1976ea1SConrad Meyer }
653b1976ea1SConrad Meyer 
6547936569bSDag-Erling Smørgrav /*
655d2b2128aSDoug Ambrisko  * Filler function for proc/partitions
656d2b2128aSDoug Ambrisko  */
657d2b2128aSDoug Ambrisko static int
658d2b2128aSDoug Ambrisko linprocfs_dopartitions(PFS_FILL_ARGS)
659d2b2128aSDoug Ambrisko {
660d2b2128aSDoug Ambrisko 	struct g_class *cp;
661d2b2128aSDoug Ambrisko 	struct g_geom *gp;
662d2b2128aSDoug Ambrisko 	struct g_provider *pp;
663d2b2128aSDoug Ambrisko 	int major, minor;
664d2b2128aSDoug Ambrisko 
665d2b2128aSDoug Ambrisko 	g_topology_lock();
666d2b2128aSDoug Ambrisko 	sbuf_printf(sb, "major minor  #blocks  name rio rmerge rsect "
667d2b2128aSDoug Ambrisko 	    "ruse wio wmerge wsect wuse running use aveq\n");
668d2b2128aSDoug Ambrisko 
669d2b2128aSDoug Ambrisko 	LIST_FOREACH(cp, &g_classes, class) {
670d2b2128aSDoug Ambrisko 		if (strcmp(cp->name, "DISK") == 0 ||
671d2b2128aSDoug Ambrisko 		    strcmp(cp->name, "PART") == 0)
672d2b2128aSDoug Ambrisko 			LIST_FOREACH(gp, &cp->geom, geom) {
673d2b2128aSDoug Ambrisko 				LIST_FOREACH(pp, &gp->provider, provider) {
674d2b2128aSDoug Ambrisko 					if (linux_driver_get_major_minor(
675d2b2128aSDoug Ambrisko 					    pp->name, &major, &minor) != 0) {
676d2b2128aSDoug Ambrisko 						major = 0;
677d2b2128aSDoug Ambrisko 						minor = 0;
678d2b2128aSDoug Ambrisko 					}
679d2b2128aSDoug Ambrisko 					sbuf_printf(sb, "%d %d %lld %s "
680d2b2128aSDoug Ambrisko 					    "%d %d %d %d %d "
681d2b2128aSDoug Ambrisko 					     "%d %d %d %d %d %d\n",
682d2b2128aSDoug Ambrisko 					     major, minor,
683d2b2128aSDoug Ambrisko 					     (long long)pp->mediasize, pp->name,
684d2b2128aSDoug Ambrisko 					     0, 0, 0, 0, 0,
685d2b2128aSDoug Ambrisko 					     0, 0, 0, 0, 0, 0);
686d2b2128aSDoug Ambrisko 				}
687d2b2128aSDoug Ambrisko 			}
688d2b2128aSDoug Ambrisko 	}
689d2b2128aSDoug Ambrisko 	g_topology_unlock();
690d2b2128aSDoug Ambrisko 
69167caead1SEdward Tomasz Napierala 	return (0);
692d2b2128aSDoug Ambrisko }
693d2b2128aSDoug Ambrisko 
694d2b2128aSDoug Ambrisko /*
6954c178576SDag-Erling Smørgrav  * Filler function for proc/stat
6964c431719SChuck Tuffli  *
6974c431719SChuck Tuffli  * Output depends on kernel version:
6984c431719SChuck Tuffli  *
6994c431719SChuck Tuffli  * v2.5.40 <=
7004c431719SChuck Tuffli  *   user nice system idle
7014c431719SChuck Tuffli  * v2.5.41
7024c431719SChuck Tuffli  *   user nice system idle iowait
7034c431719SChuck Tuffli  * v2.6.11
7044c431719SChuck Tuffli  *   user nice system idle iowait irq softirq steal
7054c431719SChuck Tuffli  * v2.6.24
7064c431719SChuck Tuffli  *   user nice system idle iowait irq softirq steal guest
7074c431719SChuck Tuffli  * v2.6.33 >=
7084c431719SChuck Tuffli  *   user nice system idle iowait irq softirq steal guest guest_nice
7094c178576SDag-Erling Smørgrav  */
710f08adc10SDag-Erling Smørgrav static int
711f08adc10SDag-Erling Smørgrav linprocfs_dostat(PFS_FILL_ARGS)
712ddc0b992SDag-Erling Smørgrav {
7137628402bSPeter Wemm 	struct pcpu *pcpu;
7147628402bSPeter Wemm 	long cp_time[CPUSTATES];
7157628402bSPeter Wemm 	long *cp;
716584b675eSKonstantin Belousov 	struct timeval boottime;
7173f907e34SDag-Erling Smørgrav 	int i;
7184c431719SChuck Tuffli 	char *zero_pad;
7194c431719SChuck Tuffli 	bool has_intr = true;
7204c431719SChuck Tuffli 
7214c431719SChuck Tuffli 	if (linux_kernver(td) >= LINUX_KERNVER(2,6,33)) {
7224c431719SChuck Tuffli 		zero_pad = " 0 0 0 0\n";
7234c431719SChuck Tuffli 	} else if (linux_kernver(td) >= LINUX_KERNVER(2,6,24)) {
7244c431719SChuck Tuffli 		zero_pad = " 0 0 0\n";
7254c431719SChuck Tuffli 	} else if (linux_kernver(td) >= LINUX_KERNVER(2,6,11)) {
7264c431719SChuck Tuffli 		zero_pad = " 0 0\n";
7274c431719SChuck Tuffli 	} else if (linux_kernver(td) >= LINUX_KERNVER(2,5,41)) {
7284c431719SChuck Tuffli 		has_intr = false;
7294c431719SChuck Tuffli 		zero_pad = " 0\n";
7304c431719SChuck Tuffli 	} else {
7314c431719SChuck Tuffli 		has_intr = false;
7324c431719SChuck Tuffli 		zero_pad = "\n";
7334c431719SChuck Tuffli 	}
734e54c4ad8SDag-Erling Smørgrav 
7357628402bSPeter Wemm 	read_cpu_time(cp_time);
736584b675eSKonstantin Belousov 	getboottime(&boottime);
7374c431719SChuck Tuffli 	/* Parameters common to all versions */
7384c431719SChuck Tuffli 	sbuf_printf(sb, "cpu %lu %lu %lu %lu",
739e54c4ad8SDag-Erling Smørgrav 	    T2J(cp_time[CP_USER]),
740e54c4ad8SDag-Erling Smørgrav 	    T2J(cp_time[CP_NICE]),
7414c431719SChuck Tuffli 	    T2J(cp_time[CP_SYS]),
742e54c4ad8SDag-Erling Smørgrav 	    T2J(cp_time[CP_IDLE]));
7434c431719SChuck Tuffli 
7444c431719SChuck Tuffli 	/* Print interrupt stats if available */
7454c431719SChuck Tuffli 	if (has_intr) {
7464c431719SChuck Tuffli 		sbuf_printf(sb, " 0 %lu", T2J(cp_time[CP_INTR]));
7474c431719SChuck Tuffli 	}
7484c431719SChuck Tuffli 
7494c431719SChuck Tuffli 	/* Pad out remaining fields depending on version */
7504c431719SChuck Tuffli 	sbuf_printf(sb, "%s", zero_pad);
7514c431719SChuck Tuffli 
7523aa6d94eSJohn Baldwin 	CPU_FOREACH(i) {
7537628402bSPeter Wemm 		pcpu = pcpu_find(i);
7547628402bSPeter Wemm 		cp = pcpu->pc_cp_time;
7554c431719SChuck Tuffli 		sbuf_printf(sb, "cpu%d %lu %lu %lu %lu", i,
7567628402bSPeter Wemm 		    T2J(cp[CP_USER]),
7577628402bSPeter Wemm 		    T2J(cp[CP_NICE]),
7584c431719SChuck Tuffli 		    T2J(cp[CP_SYS]),
7597628402bSPeter Wemm 		    T2J(cp[CP_IDLE]));
7604c431719SChuck Tuffli 
7614c431719SChuck Tuffli 		if (has_intr) {
7624c431719SChuck Tuffli 			sbuf_printf(sb, " 0 %lu", T2J(cp[CP_INTR]));
7634c431719SChuck Tuffli 		}
7644c431719SChuck Tuffli 
7654c431719SChuck Tuffli 		sbuf_printf(sb, "%s", zero_pad);
7667628402bSPeter Wemm 	}
767f08adc10SDag-Erling Smørgrav 	sbuf_printf(sb,
768ddc0b992SDag-Erling Smørgrav 	    "disk 0 0 0 0\n"
76983c9dea1SGleb Smirnoff 	    "page %ju %ju\n"
77083c9dea1SGleb Smirnoff 	    "swap %ju %ju\n"
77183c9dea1SGleb Smirnoff 	    "intr %ju\n"
77283c9dea1SGleb Smirnoff 	    "ctxt %ju\n"
77359ea8469SMatthew Dillon 	    "btime %lld\n",
77483c9dea1SGleb Smirnoff 	    (uintmax_t)VM_CNT_FETCH(v_vnodepgsin),
77583c9dea1SGleb Smirnoff 	    (uintmax_t)VM_CNT_FETCH(v_vnodepgsout),
77683c9dea1SGleb Smirnoff 	    (uintmax_t)VM_CNT_FETCH(v_swappgsin),
77783c9dea1SGleb Smirnoff 	    (uintmax_t)VM_CNT_FETCH(v_swappgsout),
77883c9dea1SGleb Smirnoff 	    (uintmax_t)VM_CNT_FETCH(v_intr),
77983c9dea1SGleb Smirnoff 	    (uintmax_t)VM_CNT_FETCH(v_swtch),
7804bedc361SJohn Baldwin 	    (long long)boottime.tv_sec);
781f08adc10SDag-Erling Smørgrav 	return (0);
782ddc0b992SDag-Erling Smørgrav }
783ddc0b992SDag-Erling Smørgrav 
784dda4f960SKonstantin Belousov static int
785dda4f960SKonstantin Belousov linprocfs_doswaps(PFS_FILL_ARGS)
786dda4f960SKonstantin Belousov {
787dda4f960SKonstantin Belousov 	struct xswdev xsw;
788dda4f960SKonstantin Belousov 	uintmax_t total, used;
789dda4f960SKonstantin Belousov 	int n;
790dda4f960SKonstantin Belousov 	char devname[SPECNAMELEN + 1];
791dda4f960SKonstantin Belousov 
792dda4f960SKonstantin Belousov 	sbuf_printf(sb, "Filename\t\t\t\tType\t\tSize\tUsed\tPriority\n");
793dda4f960SKonstantin Belousov 	for (n = 0; ; n++) {
794dda4f960SKonstantin Belousov 		if (swap_dev_info(n, &xsw, devname, sizeof(devname)) != 0)
795dda4f960SKonstantin Belousov 			break;
796dda4f960SKonstantin Belousov 		total = (uintmax_t)xsw.xsw_nblks * PAGE_SIZE / 1024;
797dda4f960SKonstantin Belousov 		used  = (uintmax_t)xsw.xsw_used * PAGE_SIZE / 1024;
798dda4f960SKonstantin Belousov 
799dda4f960SKonstantin Belousov 		/*
800dda4f960SKonstantin Belousov 		 * The space and not tab after the device name is on
801dda4f960SKonstantin Belousov 		 * purpose.  Linux does so.
802dda4f960SKonstantin Belousov 		 */
803dda4f960SKonstantin Belousov 		sbuf_printf(sb, "/dev/%-34s unknown\t\t%jd\t%jd\t-1\n",
804dda4f960SKonstantin Belousov 		    devname, total, used);
805dda4f960SKonstantin Belousov 	}
806dda4f960SKonstantin Belousov 	return (0);
807dda4f960SKonstantin Belousov }
808dda4f960SKonstantin Belousov 
8094c178576SDag-Erling Smørgrav /*
8104c178576SDag-Erling Smørgrav  * Filler function for proc/uptime
8114c178576SDag-Erling Smørgrav  */
812f08adc10SDag-Erling Smørgrav static int
813f08adc10SDag-Erling Smørgrav linprocfs_douptime(PFS_FILL_ARGS)
814ddc0b992SDag-Erling Smørgrav {
8157628402bSPeter Wemm 	long cp_time[CPUSTATES];
816ddc0b992SDag-Erling Smørgrav 	struct timeval tv;
817ddc0b992SDag-Erling Smørgrav 
818ddc0b992SDag-Erling Smørgrav 	getmicrouptime(&tv);
8197628402bSPeter Wemm 	read_cpu_time(cp_time);
820fc825cc3SAlexander Leidinger 	sbuf_printf(sb, "%lld.%02ld %ld.%02lu\n",
8214bedc361SJohn Baldwin 	    (long long)tv.tv_sec, tv.tv_usec / 10000,
822fc825cc3SAlexander Leidinger 	    T2S(cp_time[CP_IDLE] / mp_ncpus),
823fc825cc3SAlexander Leidinger 	    T2CS(cp_time[CP_IDLE] / mp_ncpus) % 100);
824f08adc10SDag-Erling Smørgrav 	return (0);
825ddc0b992SDag-Erling Smørgrav }
826ddc0b992SDag-Erling Smørgrav 
8274c178576SDag-Erling Smørgrav /*
8285017af60SJung-uk Kim  * Get OS build date
8295017af60SJung-uk Kim  */
8305017af60SJung-uk Kim static void
8315017af60SJung-uk Kim linprocfs_osbuild(struct thread *td, struct sbuf *sb)
8325017af60SJung-uk Kim {
8335017af60SJung-uk Kim #if 0
8345017af60SJung-uk Kim 	char osbuild[256];
8355017af60SJung-uk Kim 	char *cp1, *cp2;
8365017af60SJung-uk Kim 
8375017af60SJung-uk Kim 	strncpy(osbuild, version, 256);
8385017af60SJung-uk Kim 	osbuild[255] = '\0';
8395017af60SJung-uk Kim 	cp1 = strstr(osbuild, "\n");
8405017af60SJung-uk Kim 	cp2 = strstr(osbuild, ":");
8415017af60SJung-uk Kim 	if (cp1 && cp2) {
8425017af60SJung-uk Kim 		*cp1 = *cp2 = '\0';
8435017af60SJung-uk Kim 		cp1 = strstr(osbuild, "#");
8445017af60SJung-uk Kim 	} else
8455017af60SJung-uk Kim 		cp1 = NULL;
8465017af60SJung-uk Kim 	if (cp1)
8475017af60SJung-uk Kim 		sbuf_printf(sb, "%s%s", cp1, cp2 + 1);
8485017af60SJung-uk Kim 	else
8495017af60SJung-uk Kim #endif
8505017af60SJung-uk Kim 		sbuf_cat(sb, "#4 Sun Dec 18 04:30:00 CET 1977");
8515017af60SJung-uk Kim }
8525017af60SJung-uk Kim 
8535017af60SJung-uk Kim /*
8545017af60SJung-uk Kim  * Get OS builder
8555017af60SJung-uk Kim  */
8565017af60SJung-uk Kim static void
8575017af60SJung-uk Kim linprocfs_osbuilder(struct thread *td, struct sbuf *sb)
8585017af60SJung-uk Kim {
85978c3440eSDag-Erling Smørgrav #if 0
8605017af60SJung-uk Kim 	char builder[256];
8615017af60SJung-uk Kim 	char *cp;
8625017af60SJung-uk Kim 
8635017af60SJung-uk Kim 	cp = strstr(version, "\n    ");
8645017af60SJung-uk Kim 	if (cp) {
8655017af60SJung-uk Kim 		strncpy(builder, cp + 5, 256);
8665017af60SJung-uk Kim 		builder[255] = '\0';
8675017af60SJung-uk Kim 		cp = strstr(builder, ":");
8685017af60SJung-uk Kim 		if (cp)
8695017af60SJung-uk Kim 			*cp = '\0';
8705017af60SJung-uk Kim 	}
8715017af60SJung-uk Kim 	if (cp)
8725017af60SJung-uk Kim 		sbuf_cat(sb, builder);
8735017af60SJung-uk Kim 	else
87478c3440eSDag-Erling Smørgrav #endif
8755017af60SJung-uk Kim 		sbuf_cat(sb, "des@freebsd.org");
8765017af60SJung-uk Kim }
8775017af60SJung-uk Kim 
8785017af60SJung-uk Kim /*
8794c178576SDag-Erling Smørgrav  * Filler function for proc/version
8804c178576SDag-Erling Smørgrav  */
881f08adc10SDag-Erling Smørgrav static int
882f08adc10SDag-Erling Smørgrav linprocfs_doversion(PFS_FILL_ARGS)
883ddc0b992SDag-Erling Smørgrav {
88401137630SRobert Watson 	char osname[LINUX_MAX_UTSNAME];
88501137630SRobert Watson 	char osrelease[LINUX_MAX_UTSNAME];
88601137630SRobert Watson 
887b62f75cfSJohn Baldwin 	linux_get_osname(td, osname);
888b62f75cfSJohn Baldwin 	linux_get_osrelease(td, osrelease);
8895017af60SJung-uk Kim 	sbuf_printf(sb, "%s version %s (", osname, osrelease);
8905017af60SJung-uk Kim 	linprocfs_osbuilder(td, sb);
8915017af60SJung-uk Kim 	sbuf_cat(sb, ") (gcc version " __VERSION__ ") ");
8925017af60SJung-uk Kim 	linprocfs_osbuild(td, sb);
8935017af60SJung-uk Kim 	sbuf_cat(sb, "\n");
89401137630SRobert Watson 
895f08adc10SDag-Erling Smørgrav 	return (0);
896ddc0b992SDag-Erling Smørgrav }
897ddc0b992SDag-Erling Smørgrav 
8984c178576SDag-Erling Smørgrav /*
8994c178576SDag-Erling Smørgrav  * Filler function for proc/loadavg
9004c178576SDag-Erling Smørgrav  */
901f08adc10SDag-Erling Smørgrav static int
902f08adc10SDag-Erling Smørgrav linprocfs_doloadavg(PFS_FILL_ARGS)
903d9b610a0SJonathan Lemon {
90478c3440eSDag-Erling Smørgrav 
905f08adc10SDag-Erling Smørgrav 	sbuf_printf(sb,
906d9b610a0SJonathan Lemon 	    "%d.%02d %d.%02d %d.%02d %d/%d %d\n",
907d9b610a0SJonathan Lemon 	    (int)(averunnable.ldavg[0] / averunnable.fscale),
908d9b610a0SJonathan Lemon 	    (int)(averunnable.ldavg[0] * 100 / averunnable.fscale % 100),
909d9b610a0SJonathan Lemon 	    (int)(averunnable.ldavg[1] / averunnable.fscale),
910d9b610a0SJonathan Lemon 	    (int)(averunnable.ldavg[1] * 100 / averunnable.fscale % 100),
911d9b610a0SJonathan Lemon 	    (int)(averunnable.ldavg[2] / averunnable.fscale),
912d9b610a0SJonathan Lemon 	    (int)(averunnable.ldavg[2] * 100 / averunnable.fscale % 100),
913d9b610a0SJonathan Lemon 	    1,				/* number of running tasks */
914d9b610a0SJonathan Lemon 	    nprocs,			/* number of tasks */
915336d3d2aSDag-Erling Smørgrav 	    lastpid			/* the last pid */
916d9b610a0SJonathan Lemon 	);
917f08adc10SDag-Erling Smørgrav 	return (0);
918d9b610a0SJonathan Lemon }
919d9b610a0SJonathan Lemon 
920ce28fd95SEdward Tomasz Napierala static int
921ce28fd95SEdward Tomasz Napierala linprocfs_get_tty_nr(struct proc *p)
922ce28fd95SEdward Tomasz Napierala {
923ce28fd95SEdward Tomasz Napierala 	struct session *sp;
924ce28fd95SEdward Tomasz Napierala 	const char *ttyname;
925ce28fd95SEdward Tomasz Napierala 	int error, major, minor, nr;
926ce28fd95SEdward Tomasz Napierala 
927ce28fd95SEdward Tomasz Napierala 	PROC_LOCK_ASSERT(p, MA_OWNED);
928ce28fd95SEdward Tomasz Napierala 	sx_assert(&proctree_lock, SX_LOCKED);
929ce28fd95SEdward Tomasz Napierala 
930ce28fd95SEdward Tomasz Napierala 	if ((p->p_flag & P_CONTROLT) == 0)
931ce28fd95SEdward Tomasz Napierala 		return (-1);
932ce28fd95SEdward Tomasz Napierala 
933ce28fd95SEdward Tomasz Napierala 	sp = p->p_pgrp->pg_session;
934ce28fd95SEdward Tomasz Napierala 	if (sp == NULL)
935ce28fd95SEdward Tomasz Napierala 		return (-1);
936ce28fd95SEdward Tomasz Napierala 
937ce28fd95SEdward Tomasz Napierala 	ttyname = devtoname(sp->s_ttyp->t_dev);
938ce28fd95SEdward Tomasz Napierala 	error = linux_driver_get_major_minor(ttyname, &major, &minor);
939ce28fd95SEdward Tomasz Napierala 	if (error != 0)
940ce28fd95SEdward Tomasz Napierala 		return (-1);
941ce28fd95SEdward Tomasz Napierala 
942ce28fd95SEdward Tomasz Napierala 	nr = makedev(major, minor);
943ce28fd95SEdward Tomasz Napierala 	return (nr);
944ce28fd95SEdward Tomasz Napierala }
945ce28fd95SEdward Tomasz Napierala 
9464c178576SDag-Erling Smørgrav /*
9474c178576SDag-Erling Smørgrav  * Filler function for proc/pid/stat
9484c178576SDag-Erling Smørgrav  */
949f08adc10SDag-Erling Smørgrav static int
950f08adc10SDag-Erling Smørgrav linprocfs_doprocstat(PFS_FILL_ARGS)
951886a6f6fSDag-Erling Smørgrav {
9526e66bfacSDag-Erling Smørgrav 	struct kinfo_proc kp;
953584b675eSKonstantin Belousov 	struct timeval boottime;
954456ede39SAlexander Leidinger 	char state;
955456ede39SAlexander Leidinger 	static int ratelimit = 0;
956ce28fd95SEdward Tomasz Napierala 	int tty_nr;
957fc825cc3SAlexander Leidinger 	vm_offset_t startcode, startdata;
958886a6f6fSDag-Erling Smørgrav 
959584b675eSKonstantin Belousov 	getboottime(&boottime);
9606662ce5aSMateusz Guzik 	sx_slock(&proctree_lock);
96165c9b430SJohn Baldwin 	PROC_LOCK(p);
9626e66bfacSDag-Erling Smørgrav 	fill_kinfo_proc(p, &kp);
963ce28fd95SEdward Tomasz Napierala 	tty_nr = linprocfs_get_tty_nr(p);
9646662ce5aSMateusz Guzik 	sx_sunlock(&proctree_lock);
965fc825cc3SAlexander Leidinger 	if (p->p_vmspace) {
966fc825cc3SAlexander Leidinger 	   startcode = (vm_offset_t)p->p_vmspace->vm_taddr;
967fc825cc3SAlexander Leidinger 	   startdata = (vm_offset_t)p->p_vmspace->vm_daddr;
968fc825cc3SAlexander Leidinger 	} else {
969fc825cc3SAlexander Leidinger 	   startcode = 0;
970fc825cc3SAlexander Leidinger 	   startdata = 0;
97174b8d63dSPedro F. Giffuni 	}
972f08adc10SDag-Erling Smørgrav 	sbuf_printf(sb, "%d", p->p_pid);
973f08adc10SDag-Erling Smørgrav #define PS_ADD(name, fmt, arg) sbuf_printf(sb, " " fmt, arg)
974886a6f6fSDag-Erling Smørgrav 	PS_ADD("comm",		"(%s)",	p->p_comm);
975456ede39SAlexander Leidinger 	if (kp.ki_stat > sizeof(linux_state)) {
976456ede39SAlexander Leidinger 		state = 'R';
977456ede39SAlexander Leidinger 
978f0cad96dSAlexander Leidinger 		if (ratelimit == 0) {
979eff9c72bSAlexander Leidinger 			printf("linprocfs: don't know how to handle unknown FreeBSD state %d/%zd, mapping to R\n",
980eff9c72bSAlexander Leidinger 			    kp.ki_stat, sizeof(linux_state));
981f0cad96dSAlexander Leidinger 			++ratelimit;
982f0cad96dSAlexander Leidinger 		}
983456ede39SAlexander Leidinger 	} else
984456ede39SAlexander Leidinger 		state = linux_state[kp.ki_stat - 1];
985456ede39SAlexander Leidinger 	PS_ADD("state",		"%c",	state);
986f553c179SJohn Baldwin 	PS_ADD("ppid",		"%d",	p->p_pptr ? p->p_pptr->p_pid : 0);
987886a6f6fSDag-Erling Smørgrav 	PS_ADD("pgrp",		"%d",	p->p_pgid);
988886a6f6fSDag-Erling Smørgrav 	PS_ADD("session",	"%d",	p->p_session->s_sid);
989f591779bSSeigo Tanimura 	PROC_UNLOCK(p);
990ce28fd95SEdward Tomasz Napierala 	PS_ADD("tty",		"%d",	tty_nr);
991550be19eSAlexander Leidinger 	PS_ADD("tpgid",		"%d",	kp.ki_tpgid);
992886a6f6fSDag-Erling Smørgrav 	PS_ADD("flags",		"%u",	0); /* XXX */
993550be19eSAlexander Leidinger 	PS_ADD("minflt",	"%lu",	kp.ki_rusage.ru_minflt);
994550be19eSAlexander Leidinger 	PS_ADD("cminflt",	"%lu",	kp.ki_rusage_ch.ru_minflt);
995550be19eSAlexander Leidinger 	PS_ADD("majflt",	"%lu",	kp.ki_rusage.ru_majflt);
996550be19eSAlexander Leidinger 	PS_ADD("cmajflt",	"%lu",	kp.ki_rusage_ch.ru_majflt);
997fc825cc3SAlexander Leidinger 	PS_ADD("utime",		"%ld",	TV2J(&kp.ki_rusage.ru_utime));
998fc825cc3SAlexander Leidinger 	PS_ADD("stime",		"%ld",	TV2J(&kp.ki_rusage.ru_stime));
999fc825cc3SAlexander Leidinger 	PS_ADD("cutime",	"%ld",	TV2J(&kp.ki_rusage_ch.ru_utime));
1000fc825cc3SAlexander Leidinger 	PS_ADD("cstime",	"%ld",	TV2J(&kp.ki_rusage_ch.ru_stime));
1001550be19eSAlexander Leidinger 	PS_ADD("priority",	"%d",	kp.ki_pri.pri_user);
1002550be19eSAlexander Leidinger 	PS_ADD("nice",		"%d",	kp.ki_nice); /* 19 (nicest) to -19 */
1003550be19eSAlexander Leidinger 	PS_ADD("0",		"%d",	0); /* removed field */
1004550be19eSAlexander Leidinger 	PS_ADD("itrealvalue",	"%d",	0); /* XXX */
1005fc825cc3SAlexander Leidinger 	PS_ADD("starttime",	"%lu",	TV2J(&kp.ki_start) - TV2J(&boottime));
1006a55b5a9aSDmitry Chagin 	PS_ADD("vsize",		"%ju",	(uintmax_t)kp.ki_size);
1007550be19eSAlexander Leidinger 	PS_ADD("rss",		"%ju",	(uintmax_t)kp.ki_rssize);
1008550be19eSAlexander Leidinger 	PS_ADD("rlim",		"%lu",	kp.ki_rusage.ru_maxrss);
1009fc825cc3SAlexander Leidinger 	PS_ADD("startcode",	"%ju",	(uintmax_t)startcode);
1010fc825cc3SAlexander Leidinger 	PS_ADD("endcode",	"%ju",	(uintmax_t)startdata);
1011886a6f6fSDag-Erling Smørgrav 	PS_ADD("startstack",	"%u",	0); /* XXX */
1012550be19eSAlexander Leidinger 	PS_ADD("kstkesp",	"%u",	0); /* XXX */
1013550be19eSAlexander Leidinger 	PS_ADD("kstkeip",	"%u",	0); /* XXX */
1014550be19eSAlexander Leidinger 	PS_ADD("signal",	"%u",	0); /* XXX */
1015550be19eSAlexander Leidinger 	PS_ADD("blocked",	"%u",	0); /* XXX */
1016550be19eSAlexander Leidinger 	PS_ADD("sigignore",	"%u",	0); /* XXX */
1017550be19eSAlexander Leidinger 	PS_ADD("sigcatch",	"%u",	0); /* XXX */
1018886a6f6fSDag-Erling Smørgrav 	PS_ADD("wchan",		"%u",	0); /* XXX */
1019550be19eSAlexander Leidinger 	PS_ADD("nswap",		"%lu",	kp.ki_rusage.ru_nswap);
1020550be19eSAlexander Leidinger 	PS_ADD("cnswap",	"%lu",	kp.ki_rusage_ch.ru_nswap);
1021f786d43aSDag-Erling Smørgrav 	PS_ADD("exitsignal",	"%d",	0); /* XXX */
1022550be19eSAlexander Leidinger 	PS_ADD("processor",	"%u",	kp.ki_lastcpu);
1023550be19eSAlexander Leidinger 	PS_ADD("rt_priority",	"%u",	0); /* XXX */ /* >= 2.5.19 */
1024550be19eSAlexander Leidinger 	PS_ADD("policy",	"%u",	kp.ki_pri.pri_class); /* >= 2.5.19 */
1025886a6f6fSDag-Erling Smørgrav #undef PS_ADD
1026f08adc10SDag-Erling Smørgrav 	sbuf_putc(sb, '\n');
1027886a6f6fSDag-Erling Smørgrav 
1028f08adc10SDag-Erling Smørgrav 	return (0);
1029886a6f6fSDag-Erling Smørgrav }
1030886a6f6fSDag-Erling Smørgrav 
1031886a6f6fSDag-Erling Smørgrav /*
10320dd872f5SDag-Erling Smørgrav  * Filler function for proc/pid/statm
10330dd872f5SDag-Erling Smørgrav  */
10340dd872f5SDag-Erling Smørgrav static int
10350dd872f5SDag-Erling Smørgrav linprocfs_doprocstatm(PFS_FILL_ARGS)
10360dd872f5SDag-Erling Smørgrav {
10370dd872f5SDag-Erling Smørgrav 	struct kinfo_proc kp;
10380dd872f5SDag-Erling Smørgrav 	segsz_t lsize;
10390dd872f5SDag-Erling Smørgrav 
10406662ce5aSMateusz Guzik 	sx_slock(&proctree_lock);
10410dd872f5SDag-Erling Smørgrav 	PROC_LOCK(p);
10420dd872f5SDag-Erling Smørgrav 	fill_kinfo_proc(p, &kp);
10430dd872f5SDag-Erling Smørgrav 	PROC_UNLOCK(p);
10446662ce5aSMateusz Guzik 	sx_sunlock(&proctree_lock);
10450dd872f5SDag-Erling Smørgrav 
10460dd872f5SDag-Erling Smørgrav 	/*
10470dd872f5SDag-Erling Smørgrav 	 * See comments in linprocfs_doprocstatus() regarding the
10480dd872f5SDag-Erling Smørgrav 	 * computation of lsize.
10490dd872f5SDag-Erling Smørgrav 	 */
10500dd872f5SDag-Erling Smørgrav 	/* size resident share trs drs lrs dt */
10510dd872f5SDag-Erling Smørgrav 	sbuf_printf(sb, "%ju ", B2P((uintmax_t)kp.ki_size));
10520dd872f5SDag-Erling Smørgrav 	sbuf_printf(sb, "%ju ", (uintmax_t)kp.ki_rssize);
10530dd872f5SDag-Erling Smørgrav 	sbuf_printf(sb, "%ju ", (uintmax_t)0); /* XXX */
10540dd872f5SDag-Erling Smørgrav 	sbuf_printf(sb, "%ju ",	(uintmax_t)kp.ki_tsize);
10550dd872f5SDag-Erling Smørgrav 	sbuf_printf(sb, "%ju ", (uintmax_t)(kp.ki_dsize + kp.ki_ssize));
10560dd872f5SDag-Erling Smørgrav 	lsize = B2P(kp.ki_size) - kp.ki_dsize -
10570dd872f5SDag-Erling Smørgrav 	    kp.ki_ssize - kp.ki_tsize - 1;
10580dd872f5SDag-Erling Smørgrav 	sbuf_printf(sb, "%ju ", (uintmax_t)lsize);
10590dd872f5SDag-Erling Smørgrav 	sbuf_printf(sb, "%ju\n", (uintmax_t)0); /* XXX */
10600dd872f5SDag-Erling Smørgrav 
10610dd872f5SDag-Erling Smørgrav 	return (0);
10620dd872f5SDag-Erling Smørgrav }
10630dd872f5SDag-Erling Smørgrav 
10640dd872f5SDag-Erling Smørgrav /*
10654c178576SDag-Erling Smørgrav  * Filler function for proc/pid/status
10664c178576SDag-Erling Smørgrav  */
1067f08adc10SDag-Erling Smørgrav static int
1068f08adc10SDag-Erling Smørgrav linprocfs_doprocstatus(PFS_FILL_ARGS)
1069886a6f6fSDag-Erling Smørgrav {
10706e66bfacSDag-Erling Smørgrav 	struct kinfo_proc kp;
1071886a6f6fSDag-Erling Smørgrav 	char *state;
1072f786d43aSDag-Erling Smørgrav 	segsz_t lsize;
1073e602ba25SJulian Elischer 	struct thread *td2;
107490af4afaSJohn Baldwin 	struct sigacts *ps;
107594c0ee30SDmitry Chagin 	l_sigset_t siglist, sigignore, sigcatch;
1076b47ed6cbSJonathan Lemon 	int i;
1077886a6f6fSDag-Erling Smørgrav 
10786662ce5aSMateusz Guzik 	sx_slock(&proctree_lock);
1079418e9d1bSJohn Baldwin 	PROC_LOCK(p);
1080aae8ae5eSDmitry Chagin 	td2 = FIRST_THREAD_IN_PROC(p);
1081e602ba25SJulian Elischer 
1082e602ba25SJulian Elischer 	if (P_SHOULDSTOP(p)) {
1083e602ba25SJulian Elischer 		state = "T (stopped)";
1084e602ba25SJulian Elischer 	} else {
1085e602ba25SJulian Elischer 		switch(p->p_state) {
1086e602ba25SJulian Elischer 		case PRS_NEW:
1087e602ba25SJulian Elischer 			state = "I (idle)";
1088e602ba25SJulian Elischer 			break;
1089e602ba25SJulian Elischer 		case PRS_NORMAL:
1090e602ba25SJulian Elischer 			if (p->p_flag & P_WEXIT) {
1091e602ba25SJulian Elischer 				state = "X (exiting)";
1092e602ba25SJulian Elischer 				break;
1093e602ba25SJulian Elischer 			}
1094fa2528acSAlex Richardson 			switch(TD_GET_STATE(td2)) {
109571fad9fdSJulian Elischer 			case TDS_INHIBITED:
1096e602ba25SJulian Elischer 				state = "S (sleeping)";
1097e602ba25SJulian Elischer 				break;
1098e602ba25SJulian Elischer 			case TDS_RUNQ:
1099e602ba25SJulian Elischer 			case TDS_RUNNING:
1100e602ba25SJulian Elischer 				state = "R (running)";
1101e602ba25SJulian Elischer 				break;
1102e602ba25SJulian Elischer 			default:
1103e602ba25SJulian Elischer 				state = "? (unknown)";
1104e602ba25SJulian Elischer 				break;
1105e602ba25SJulian Elischer 			}
1106e602ba25SJulian Elischer 			break;
1107e602ba25SJulian Elischer 		case PRS_ZOMBIE:
1108e602ba25SJulian Elischer 			state = "Z (zombie)";
1109e602ba25SJulian Elischer 			break;
1110e602ba25SJulian Elischer 		default:
1111e602ba25SJulian Elischer 			state = "? (unknown)";
1112e602ba25SJulian Elischer 			break;
1113e602ba25SJulian Elischer 		}
1114418e9d1bSJohn Baldwin 	}
1115886a6f6fSDag-Erling Smørgrav 
11166e66bfacSDag-Erling Smørgrav 	fill_kinfo_proc(p, &kp);
11176662ce5aSMateusz Guzik 	sx_sunlock(&proctree_lock);
11186662ce5aSMateusz Guzik 
1119f08adc10SDag-Erling Smørgrav 	sbuf_printf(sb, "Name:\t%s\n",		p->p_comm); /* XXX escape */
1120f08adc10SDag-Erling Smørgrav 	sbuf_printf(sb, "State:\t%s\n",		state);
1121886a6f6fSDag-Erling Smørgrav 
1122886a6f6fSDag-Erling Smørgrav 	/*
1123886a6f6fSDag-Erling Smørgrav 	 * Credentials
1124886a6f6fSDag-Erling Smørgrav 	 */
1125bb3c7a54SEdward Tomasz Napierala 	sbuf_printf(sb, "Tgid:\t%d\n",		p->p_pid);
1126f08adc10SDag-Erling Smørgrav 	sbuf_printf(sb, "Pid:\t%d\n",		p->p_pid);
11271f3bc157SKonstantin Belousov 	sbuf_printf(sb, "PPid:\t%d\n",		kp.ki_ppid );
11281f3bc157SKonstantin Belousov 	sbuf_printf(sb, "TracerPid:\t%d\n",	kp.ki_tracer );
112991be6286SEdward Tomasz Napierala 	sbuf_printf(sb, "Uid:\t%d\t%d\t%d\t%d\n", p->p_ucred->cr_ruid,
1130886a6f6fSDag-Erling Smørgrav 						p->p_ucred->cr_uid,
1131b1fc0ec1SRobert Watson 						p->p_ucred->cr_svuid,
1132886a6f6fSDag-Erling Smørgrav 						/* FreeBSD doesn't have fsuid */
1133886a6f6fSDag-Erling Smørgrav 						p->p_ucred->cr_uid);
113491be6286SEdward Tomasz Napierala 	sbuf_printf(sb, "Gid:\t%d\t%d\t%d\t%d\n", p->p_ucred->cr_rgid,
1135886a6f6fSDag-Erling Smørgrav 						p->p_ucred->cr_gid,
1136b1fc0ec1SRobert Watson 						p->p_ucred->cr_svgid,
1137886a6f6fSDag-Erling Smørgrav 						/* FreeBSD doesn't have fsgid */
1138886a6f6fSDag-Erling Smørgrav 						p->p_ucred->cr_gid);
1139f08adc10SDag-Erling Smørgrav 	sbuf_cat(sb, "Groups:\t");
1140886a6f6fSDag-Erling Smørgrav 	for (i = 0; i < p->p_ucred->cr_ngroups; i++)
1141f08adc10SDag-Erling Smørgrav 		sbuf_printf(sb, "%d ",		p->p_ucred->cr_groups[i]);
1142ec447af1SJohn Baldwin 	PROC_UNLOCK(p);
1143f08adc10SDag-Erling Smørgrav 	sbuf_putc(sb, '\n');
1144886a6f6fSDag-Erling Smørgrav 
1145886a6f6fSDag-Erling Smørgrav 	/*
1146886a6f6fSDag-Erling Smørgrav 	 * Memory
1147f786d43aSDag-Erling Smørgrav 	 *
1148f786d43aSDag-Erling Smørgrav 	 * While our approximation of VmLib may not be accurate (I
1149f786d43aSDag-Erling Smørgrav 	 * don't know of a simple way to verify it, and I'm not sure
1150f786d43aSDag-Erling Smørgrav 	 * it has much meaning anyway), I believe it's good enough.
1151f786d43aSDag-Erling Smørgrav 	 *
1152f786d43aSDag-Erling Smørgrav 	 * The same code that could (I think) accurately compute VmLib
1153f786d43aSDag-Erling Smørgrav 	 * could also compute VmLck, but I don't really care enough to
1154f786d43aSDag-Erling Smørgrav 	 * implement it. Submissions are welcome.
1155886a6f6fSDag-Erling Smørgrav 	 */
11564bedc361SJohn Baldwin 	sbuf_printf(sb, "VmSize:\t%8ju kB\n",	B2K((uintmax_t)kp.ki_size));
1157f08adc10SDag-Erling Smørgrav 	sbuf_printf(sb, "VmLck:\t%8u kB\n",	P2K(0)); /* XXX */
1158fc825cc3SAlexander Leidinger 	sbuf_printf(sb, "VmRSS:\t%8ju kB\n",	P2K((uintmax_t)kp.ki_rssize));
11594bedc361SJohn Baldwin 	sbuf_printf(sb, "VmData:\t%8ju kB\n",	P2K((uintmax_t)kp.ki_dsize));
11604bedc361SJohn Baldwin 	sbuf_printf(sb, "VmStk:\t%8ju kB\n",	P2K((uintmax_t)kp.ki_ssize));
11614bedc361SJohn Baldwin 	sbuf_printf(sb, "VmExe:\t%8ju kB\n",	P2K((uintmax_t)kp.ki_tsize));
11626e66bfacSDag-Erling Smørgrav 	lsize = B2P(kp.ki_size) - kp.ki_dsize -
11636e66bfacSDag-Erling Smørgrav 	    kp.ki_ssize - kp.ki_tsize - 1;
11644bedc361SJohn Baldwin 	sbuf_printf(sb, "VmLib:\t%8ju kB\n",	P2K((uintmax_t)lsize));
1165886a6f6fSDag-Erling Smørgrav 
1166886a6f6fSDag-Erling Smørgrav 	/*
1167886a6f6fSDag-Erling Smørgrav 	 * Signal masks
1168886a6f6fSDag-Erling Smørgrav 	 */
1169ec447af1SJohn Baldwin 	PROC_LOCK(p);
117094c0ee30SDmitry Chagin 	bsd_to_linux_sigset(&p->p_siglist, &siglist);
117190af4afaSJohn Baldwin 	ps = p->p_sigacts;
117290af4afaSJohn Baldwin 	mtx_lock(&ps->ps_mtx);
117394c0ee30SDmitry Chagin 	bsd_to_linux_sigset(&ps->ps_sigignore, &sigignore);
117494c0ee30SDmitry Chagin 	bsd_to_linux_sigset(&ps->ps_sigcatch, &sigcatch);
117590af4afaSJohn Baldwin 	mtx_unlock(&ps->ps_mtx);
1176ec447af1SJohn Baldwin 	PROC_UNLOCK(p);
1177886a6f6fSDag-Erling Smørgrav 
117894c0ee30SDmitry Chagin 	sbuf_printf(sb, "SigPnd:\t%016jx\n",	siglist.__mask);
117994c0ee30SDmitry Chagin 	/*
118094c0ee30SDmitry Chagin 	 * XXX. SigBlk - target thread's signal mask, td_sigmask.
118194c0ee30SDmitry Chagin 	 * To implement SigBlk pseudofs should support proc/tid dir entries.
118294c0ee30SDmitry Chagin 	 */
118394c0ee30SDmitry Chagin 	sbuf_printf(sb, "SigBlk:\t%016x\n",	0);
118494c0ee30SDmitry Chagin 	sbuf_printf(sb, "SigIgn:\t%016jx\n",	sigignore.__mask);
118594c0ee30SDmitry Chagin 	sbuf_printf(sb, "SigCgt:\t%016jx\n",	sigcatch.__mask);
118694c0ee30SDmitry Chagin 
1187886a6f6fSDag-Erling Smørgrav 	/*
1188886a6f6fSDag-Erling Smørgrav 	 * Linux also prints the capability masks, but we don't have
1189886a6f6fSDag-Erling Smørgrav 	 * capabilities yet, and when we do get them they're likely to
1190886a6f6fSDag-Erling Smørgrav 	 * be meaningless to Linux programs, so we lie. XXX
1191886a6f6fSDag-Erling Smørgrav 	 */
1192f08adc10SDag-Erling Smørgrav 	sbuf_printf(sb, "CapInh:\t%016x\n",	0);
1193f08adc10SDag-Erling Smørgrav 	sbuf_printf(sb, "CapPrm:\t%016x\n",	0);
1194f08adc10SDag-Erling Smørgrav 	sbuf_printf(sb, "CapEff:\t%016x\n",	0);
1195886a6f6fSDag-Erling Smørgrav 
1196f08adc10SDag-Erling Smørgrav 	return (0);
1197b47ed6cbSJonathan Lemon }
1198b47ed6cbSJonathan Lemon 
11990dd872f5SDag-Erling Smørgrav /*
12000dd872f5SDag-Erling Smørgrav  * Filler function for proc/pid/cwd
12010dd872f5SDag-Erling Smørgrav  */
12020dd872f5SDag-Erling Smørgrav static int
12030dd872f5SDag-Erling Smørgrav linprocfs_doproccwd(PFS_FILL_ARGS)
12040dd872f5SDag-Erling Smørgrav {
12058d03b99bSMateusz Guzik 	struct pwd *pwd;
12060dd872f5SDag-Erling Smørgrav 	char *fullpath = "unknown";
12070dd872f5SDag-Erling Smørgrav 	char *freepath = NULL;
12080dd872f5SDag-Erling Smørgrav 
120969ab5283SMateusz Guzik 	pwd = pwd_hold_proc(p);
1210feabaaf9SMateusz Guzik 	vn_fullpath(pwd->pwd_cdir, &fullpath, &freepath);
12110dd872f5SDag-Erling Smørgrav 	sbuf_printf(sb, "%s", fullpath);
12120dd872f5SDag-Erling Smørgrav 	if (freepath)
12130dd872f5SDag-Erling Smørgrav 		free(freepath, M_TEMP);
12148d03b99bSMateusz Guzik 	pwd_drop(pwd);
12150dd872f5SDag-Erling Smørgrav 	return (0);
12160dd872f5SDag-Erling Smørgrav }
12170dd872f5SDag-Erling Smørgrav 
12180dd872f5SDag-Erling Smørgrav /*
12190dd872f5SDag-Erling Smørgrav  * Filler function for proc/pid/root
12200dd872f5SDag-Erling Smørgrav  */
12210dd872f5SDag-Erling Smørgrav static int
12220dd872f5SDag-Erling Smørgrav linprocfs_doprocroot(PFS_FILL_ARGS)
12230dd872f5SDag-Erling Smørgrav {
12248d03b99bSMateusz Guzik 	struct pwd *pwd;
1225b34be824SMateusz Guzik 	struct vnode *vp;
12260dd872f5SDag-Erling Smørgrav 	char *fullpath = "unknown";
12270dd872f5SDag-Erling Smørgrav 	char *freepath = NULL;
12280dd872f5SDag-Erling Smørgrav 
122969ab5283SMateusz Guzik 	pwd = pwd_hold_proc(p);
12308d03b99bSMateusz Guzik 	vp = jailed(p->p_ucred) ? pwd->pwd_jdir : pwd->pwd_rdir;
1231feabaaf9SMateusz Guzik 	vn_fullpath(vp, &fullpath, &freepath);
12320dd872f5SDag-Erling Smørgrav 	sbuf_printf(sb, "%s", fullpath);
12330dd872f5SDag-Erling Smørgrav 	if (freepath)
12340dd872f5SDag-Erling Smørgrav 		free(freepath, M_TEMP);
12358d03b99bSMateusz Guzik 	pwd_drop(pwd);
12360dd872f5SDag-Erling Smørgrav 	return (0);
12370dd872f5SDag-Erling Smørgrav }
12380dd872f5SDag-Erling Smørgrav 
12394c178576SDag-Erling Smørgrav /*
12406c82a991SKonstantin Belousov  * Filler function for proc/pid/cmdline
12416c82a991SKonstantin Belousov  */
12426c82a991SKonstantin Belousov static int
12436c82a991SKonstantin Belousov linprocfs_doproccmdline(PFS_FILL_ARGS)
12446c82a991SKonstantin Belousov {
12456c82a991SKonstantin Belousov 	int ret;
12466c82a991SKonstantin Belousov 
12476c82a991SKonstantin Belousov 	PROC_LOCK(p);
12486c82a991SKonstantin Belousov 	if ((ret = p_cansee(td, p)) != 0) {
12496c82a991SKonstantin Belousov 		PROC_UNLOCK(p);
12506c82a991SKonstantin Belousov 		return (ret);
12516c82a991SKonstantin Belousov 	}
1252e0607decSSergey Kandaurov 
1253e0607decSSergey Kandaurov 	/*
1254e0607decSSergey Kandaurov 	 * Mimic linux behavior and pass only processes with usermode
1255e0607decSSergey Kandaurov 	 * address space as valid.  Return zero silently otherwize.
1256e0607decSSergey Kandaurov 	 */
1257e0607decSSergey Kandaurov 	if (p->p_vmspace == &vmspace0) {
1258e0607decSSergey Kandaurov 		PROC_UNLOCK(p);
1259e0607decSSergey Kandaurov 		return (0);
1260e0607decSSergey Kandaurov 	}
12616c82a991SKonstantin Belousov 	if (p->p_args != NULL) {
12626c82a991SKonstantin Belousov 		sbuf_bcpy(sb, p->p_args->ar_args, p->p_args->ar_length);
12636c82a991SKonstantin Belousov 		PROC_UNLOCK(p);
12646c82a991SKonstantin Belousov 		return (0);
12656c82a991SKonstantin Belousov 	}
12667a837e17SMikolaj Golub 
12677a837e17SMikolaj Golub 	if ((p->p_flag & P_SYSTEM) != 0) {
12687a837e17SMikolaj Golub 		PROC_UNLOCK(p);
12697a837e17SMikolaj Golub 		return (0);
12707a837e17SMikolaj Golub 	}
12717a837e17SMikolaj Golub 
12726c82a991SKonstantin Belousov 	PROC_UNLOCK(p);
12736c82a991SKonstantin Belousov 
1274fe7f89b7SMikolaj Golub 	ret = proc_getargv(td, p, sb);
12756c82a991SKonstantin Belousov 	return (ret);
12766c82a991SKonstantin Belousov }
12776c82a991SKonstantin Belousov 
12786c82a991SKonstantin Belousov /*
127916dbc7f2SDavid E. O'Brien  * Filler function for proc/pid/environ
128016dbc7f2SDavid E. O'Brien  */
128116dbc7f2SDavid E. O'Brien static int
128216dbc7f2SDavid E. O'Brien linprocfs_doprocenviron(PFS_FILL_ARGS)
128316dbc7f2SDavid E. O'Brien {
1284e0607decSSergey Kandaurov 
1285e0607decSSergey Kandaurov 	/*
1286e0607decSSergey Kandaurov 	 * Mimic linux behavior and pass only processes with usermode
1287e0607decSSergey Kandaurov 	 * address space as valid.  Return zero silently otherwize.
1288e0607decSSergey Kandaurov 	 */
1289dcc0e6c4SDmitry Chagin 	if (p->p_vmspace == &vmspace0)
1290e0607decSSergey Kandaurov 		return (0);
12917a837e17SMikolaj Golub 
1292dcc0e6c4SDmitry Chagin 	return (proc_getenvv(td, p, sb));
129316dbc7f2SDavid E. O'Brien }
129416dbc7f2SDavid E. O'Brien 
12950ed687faSDmitry Chagin static char l32_map_str[] = "%08lx-%08lx %s%s%s%s %08lx %02x:%02x %lu%s%s\n";
12960ed687faSDmitry Chagin static char l64_map_str[] = "%016lx-%016lx %s%s%s%s %08lx %02x:%02x %lu%s%s\n";
1297ffefd570SDmitry Chagin static char vdso_str[] = "      [vdso]";
1298ffefd570SDmitry Chagin static char stack_str[] = "      [stack]";
12990ed687faSDmitry Chagin 
130016dbc7f2SDavid E. O'Brien /*
130116dbc7f2SDavid E. O'Brien  * Filler function for proc/pid/maps
130216dbc7f2SDavid E. O'Brien  */
130316dbc7f2SDavid E. O'Brien static int
130416dbc7f2SDavid E. O'Brien linprocfs_doprocmaps(PFS_FILL_ARGS)
130516dbc7f2SDavid E. O'Brien {
1306c7462f43SKonstantin Belousov 	struct vmspace *vm;
1307c7462f43SKonstantin Belousov 	vm_map_t map;
13085a66e025SKonstantin Belousov 	vm_map_entry_t entry, tmp_entry;
1309c92dcdd9SOlivier Houchard 	vm_object_t obj, tobj, lobj;
13105a66e025SKonstantin Belousov 	vm_offset_t e_start, e_end;
1311f8091e2cSMark Johnston 	vm_ooffset_t off;
13125a66e025SKonstantin Belousov 	vm_prot_t e_prot;
13135a66e025SKonstantin Belousov 	unsigned int last_timestamp;
1314c92dcdd9SOlivier Houchard 	char *name = "", *freename = NULL;
13150ed687faSDmitry Chagin 	const char *l_map_str;
1316c92dcdd9SOlivier Houchard 	ino_t ino;
1317c92dcdd9SOlivier Houchard 	int error;
13187689860fSPoul-Henning Kamp 	struct vnode *vp;
13197689860fSPoul-Henning Kamp 	struct vattr vat;
1320f8091e2cSMark Johnston 	bool private;
1321faf1e147SOlivier Houchard 
1322faf1e147SOlivier Houchard 	PROC_LOCK(p);
1323faf1e147SOlivier Houchard 	error = p_candebug(td, p);
1324faf1e147SOlivier Houchard 	PROC_UNLOCK(p);
1325faf1e147SOlivier Houchard 	if (error)
1326faf1e147SOlivier Houchard 		return (error);
1327faf1e147SOlivier Houchard 
1328faf1e147SOlivier Houchard 	if (uio->uio_rw != UIO_READ)
1329faf1e147SOlivier Houchard 		return (EOPNOTSUPP);
1330faf1e147SOlivier Houchard 
1331faf1e147SOlivier Houchard 	error = 0;
1332c7462f43SKonstantin Belousov 	vm = vmspace_acquire_ref(p);
1333c7462f43SKonstantin Belousov 	if (vm == NULL)
1334c7462f43SKonstantin Belousov 		return (ESRCH);
1335ffefd570SDmitry Chagin 
1336ffefd570SDmitry Chagin 	if (SV_CURPROC_FLAG(SV_LP64))
1337ffefd570SDmitry Chagin 		l_map_str = l64_map_str;
1338ffefd570SDmitry Chagin 	else
1339ffefd570SDmitry Chagin 		l_map_str = l32_map_str;
1340c7462f43SKonstantin Belousov 	map = &vm->vm_map;
1341faf1e147SOlivier Houchard 	vm_map_lock_read(map);
13422288078cSDoug Moore 	VM_MAP_ENTRY_FOREACH(entry, map) {
1343c92dcdd9SOlivier Houchard 		name = "";
1344c92dcdd9SOlivier Houchard 		freename = NULL;
1345ef1976ccSDmitry Chagin 		/*
1346ef1976ccSDmitry Chagin 		 * Skip printing of the guard page of the stack region, as
1347ef1976ccSDmitry Chagin 		 * it confuses glibc pthread_getattr_np() method, where both
1348ef1976ccSDmitry Chagin 		 * the base address and size of the stack of the initial thread
1349ef1976ccSDmitry Chagin 		 * are calculated.
1350ef1976ccSDmitry Chagin 		 */
1351ef1976ccSDmitry Chagin 		if ((entry->eflags & (MAP_ENTRY_IS_SUB_MAP | MAP_ENTRY_GUARD)) != 0)
1352faf1e147SOlivier Houchard 			continue;
13535a66e025SKonstantin Belousov 		e_prot = entry->protection;
13545a66e025SKonstantin Belousov 		e_start = entry->start;
13555a66e025SKonstantin Belousov 		e_end = entry->end;
1356faf1e147SOlivier Houchard 		obj = entry->object.vm_object;
1357f8091e2cSMark Johnston 		off = entry->offset;
1358f8091e2cSMark Johnston 		for (lobj = tobj = obj; tobj != NULL;
1359f8091e2cSMark Johnston 		    lobj = tobj, tobj = tobj->backing_object) {
136066c392dfSAlan Cox 			VM_OBJECT_RLOCK(tobj);
1361f8091e2cSMark Johnston 			off += lobj->backing_object_offset;
13624bd4f5a2SAlan Cox 			if (lobj != obj)
136366c392dfSAlan Cox 				VM_OBJECT_RUNLOCK(lobj);
13644bd4f5a2SAlan Cox 		}
1365f8091e2cSMark Johnston 		private = (entry->eflags & MAP_ENTRY_COW) != 0 || obj == NULL ||
1366f8091e2cSMark Johnston 		    (obj->flags & OBJ_ANON) != 0;
13675a66e025SKonstantin Belousov 		last_timestamp = map->timestamp;
13685a66e025SKonstantin Belousov 		vm_map_unlock_read(map);
1369faf1e147SOlivier Houchard 		ino = 0;
1370faf1e147SOlivier Houchard 		if (lobj) {
137163e4c6cdSEric van Gyzen 			vp = vm_object_vnode(lobj);
137263e4c6cdSEric van Gyzen 			if (vp != NULL)
13731565bf54SKonstantin Belousov 				vref(vp);
13744bd4f5a2SAlan Cox 			if (lobj != obj)
137566c392dfSAlan Cox 				VM_OBJECT_RUNLOCK(lobj);
137666c392dfSAlan Cox 			VM_OBJECT_RUNLOCK(obj);
137763e4c6cdSEric van Gyzen 			if (vp != NULL) {
1378feabaaf9SMateusz Guzik 				vn_fullpath(vp, &name, &freename);
1379cb05b60aSAttilio Rao 				vn_lock(vp, LK_SHARED | LK_RETRY);
13800359a12eSAttilio Rao 				VOP_GETATTR(vp, &vat, td->td_ucred);
13811565bf54SKonstantin Belousov 				ino = vat.va_fileid;
13821565bf54SKonstantin Belousov 				vput(vp);
1383ffefd570SDmitry Chagin 			} else if (SV_PROC_ABI(p) == SV_ABI_LINUX) {
1384fe740953SDmitry Chagin 				/*
1385fe740953SDmitry Chagin 				 * sv_shared_page_base pointed out to the
1386fe740953SDmitry Chagin 				 * FreeBSD sharedpage, PAGE_SIZE is a size
1387fe740953SDmitry Chagin 				 * of it. The vDSO page is above.
1388fe740953SDmitry Chagin 				 */
1389fe740953SDmitry Chagin 				if (e_start == p->p_sysent->sv_shared_page_base +
1390fe740953SDmitry Chagin 				    PAGE_SIZE)
1391ffefd570SDmitry Chagin 					name = vdso_str;
1392ffefd570SDmitry Chagin 				if (e_end == p->p_sysent->sv_usrstack)
1393ffefd570SDmitry Chagin 					name = stack_str;
13941565bf54SKonstantin Belousov 			}
1395faf1e147SOlivier Houchard 		}
1396faf1e147SOlivier Houchard 
1397faf1e147SOlivier Houchard 		/*
1398faf1e147SOlivier Houchard 		 * format:
1399faf1e147SOlivier Houchard 		 *  start, end, access, offset, major, minor, inode, name.
1400faf1e147SOlivier Houchard 		 */
14010ed687faSDmitry Chagin 		error = sbuf_printf(sb, l_map_str,
14025a66e025SKonstantin Belousov 		    (u_long)e_start, (u_long)e_end,
14035a66e025SKonstantin Belousov 		    (e_prot & VM_PROT_READ)?"r":"-",
14045a66e025SKonstantin Belousov 		    (e_prot & VM_PROT_WRITE)?"w":"-",
14055a66e025SKonstantin Belousov 		    (e_prot & VM_PROT_EXECUTE)?"x":"-",
1406f8091e2cSMark Johnston 		    private ? "p" : "s",
1407faf1e147SOlivier Houchard 		    (u_long)off,
1408faf1e147SOlivier Houchard 		    0,
1409faf1e147SOlivier Houchard 		    0,
1410faf1e147SOlivier Houchard 		    (u_long)ino,
1411faf1e147SOlivier Houchard 		    *name ? "     " : " ",
1412faf1e147SOlivier Houchard 		    name
1413faf1e147SOlivier Houchard 		    );
1414faf1e147SOlivier Houchard 		if (freename)
1415faf1e147SOlivier Houchard 			free(freename, M_TEMP);
1416c96f3741SKonstantin Belousov 		vm_map_lock_read(map);
14179a1e630dSKonstantin Belousov 		if (error == -1) {
14189a1e630dSKonstantin Belousov 			error = 0;
1419faf1e147SOlivier Houchard 			break;
1420faf1e147SOlivier Houchard 		}
142122a448c4SKonstantin Belousov 		if (last_timestamp != map->timestamp) {
14225a66e025SKonstantin Belousov 			/*
14235a66e025SKonstantin Belousov 			 * Look again for the entry because the map was
14245a66e025SKonstantin Belousov 			 * modified while it was unlocked.  Specifically,
14255a66e025SKonstantin Belousov 			 * the entry may have been clipped, merged, or deleted.
14265a66e025SKonstantin Belousov 			 */
14275a66e025SKonstantin Belousov 			vm_map_lookup_entry(map, e_end - 1, &tmp_entry);
14285a66e025SKonstantin Belousov 			entry = tmp_entry;
14295a66e025SKonstantin Belousov 		}
14304bd4f5a2SAlan Cox 	}
1431faf1e147SOlivier Houchard 	vm_map_unlock_read(map);
1432c7462f43SKonstantin Belousov 	vmspace_free(vm);
1433faf1e147SOlivier Houchard 
1434faf1e147SOlivier Houchard 	return (error);
143516dbc7f2SDavid E. O'Brien }
143616dbc7f2SDavid E. O'Brien 
143716dbc7f2SDavid E. O'Brien /*
143891bc7361SEdward Tomasz Napierala  * Filler function for proc/pid/mem
143991bc7361SEdward Tomasz Napierala  */
144091bc7361SEdward Tomasz Napierala static int
144191bc7361SEdward Tomasz Napierala linprocfs_doprocmem(PFS_FILL_ARGS)
144291bc7361SEdward Tomasz Napierala {
144391bc7361SEdward Tomasz Napierala 	ssize_t resid;
144491bc7361SEdward Tomasz Napierala 	int error;
144591bc7361SEdward Tomasz Napierala 
144691bc7361SEdward Tomasz Napierala 	resid = uio->uio_resid;
144791bc7361SEdward Tomasz Napierala 	error = procfs_doprocmem(PFS_FILL_ARGNAMES);
144891bc7361SEdward Tomasz Napierala 
144991bc7361SEdward Tomasz Napierala 	if (uio->uio_rw == UIO_READ && resid != uio->uio_resid)
145091bc7361SEdward Tomasz Napierala 		return (0);
145191bc7361SEdward Tomasz Napierala 
145291bc7361SEdward Tomasz Napierala 	if (error == EFAULT)
145391bc7361SEdward Tomasz Napierala 		error = EIO;
145491bc7361SEdward Tomasz Napierala 
145591bc7361SEdward Tomasz Napierala 	return (error);
145691bc7361SEdward Tomasz Napierala }
145791bc7361SEdward Tomasz Napierala 
145867d39748SDmitry Chagin /*
14594c178576SDag-Erling Smørgrav  * Filler function for proc/net/dev
14604c178576SDag-Erling Smørgrav  */
1461f08adc10SDag-Erling Smørgrav static int
14626c5786fdSDmitry Chagin linprocfs_donetdev_cb(if_t ifp, void *arg)
14636c5786fdSDmitry Chagin {
14646c5786fdSDmitry Chagin 	char ifname[LINUX_IFNAMSIZ];
14656c5786fdSDmitry Chagin 	struct sbuf *sb = arg;
14666c5786fdSDmitry Chagin 
14676c5786fdSDmitry Chagin 	if (ifname_bsd_to_linux_ifp(ifp, ifname, sizeof(ifname)) <= 0)
14686c5786fdSDmitry Chagin 		return (ENODEV);
14696c5786fdSDmitry Chagin 
14706c5786fdSDmitry Chagin 	sbuf_printf(sb, "%6.6s: ", ifname);
14716c5786fdSDmitry Chagin 	sbuf_printf(sb, "%7ju %7ju %4ju %4ju %4lu %5lu %10lu %9ju ",
14726c5786fdSDmitry Chagin 	    (uintmax_t)if_getcounter(ifp, IFCOUNTER_IBYTES),
14736c5786fdSDmitry Chagin 	    (uintmax_t)if_getcounter(ifp, IFCOUNTER_IPACKETS),
14746c5786fdSDmitry Chagin 	    (uintmax_t)if_getcounter(ifp, IFCOUNTER_IERRORS),
14756c5786fdSDmitry Chagin 	    (uintmax_t)if_getcounter(ifp, IFCOUNTER_IQDROPS),
14766c5786fdSDmitry Chagin 						/* rx_missed_errors */
14776c5786fdSDmitry Chagin 	    0UL,				/* rx_fifo_errors */
14786c5786fdSDmitry Chagin 	    0UL,				/* rx_length_errors +
14796c5786fdSDmitry Chagin 						 * rx_over_errors +
14806c5786fdSDmitry Chagin 						 * rx_crc_errors +
14816c5786fdSDmitry Chagin 						 * rx_frame_errors */
14826c5786fdSDmitry Chagin 	    0UL,				/* rx_compressed */
14836c5786fdSDmitry Chagin 	    (uintmax_t)if_getcounter(ifp, IFCOUNTER_IMCASTS));
14846c5786fdSDmitry Chagin 						/* XXX-BZ rx only? */
14856c5786fdSDmitry Chagin 	sbuf_printf(sb, "%8ju %7ju %4ju %4ju %4lu %5ju %7lu %10lu\n",
14866c5786fdSDmitry Chagin 	    (uintmax_t)if_getcounter(ifp, IFCOUNTER_OBYTES),
14876c5786fdSDmitry Chagin 	    (uintmax_t)if_getcounter(ifp, IFCOUNTER_OPACKETS),
14886c5786fdSDmitry Chagin 	    (uintmax_t)if_getcounter(ifp, IFCOUNTER_OERRORS),
14896c5786fdSDmitry Chagin 	    (uintmax_t)if_getcounter(ifp, IFCOUNTER_OQDROPS),
14906c5786fdSDmitry Chagin 	    0UL,				/* tx_fifo_errors */
14916c5786fdSDmitry Chagin 	    (uintmax_t)if_getcounter(ifp, IFCOUNTER_COLLISIONS),
14926c5786fdSDmitry Chagin 	    0UL,				/* tx_carrier_errors +
14936c5786fdSDmitry Chagin 						 * tx_aborted_errors +
14946c5786fdSDmitry Chagin 						 * tx_window_errors +
14956c5786fdSDmitry Chagin 						 * tx_heartbeat_errors*/
14966c5786fdSDmitry Chagin 	    0UL);				/* tx_compressed */
14976c5786fdSDmitry Chagin 	return (0);
14986c5786fdSDmitry Chagin }
14996c5786fdSDmitry Chagin 
15006c5786fdSDmitry Chagin static int
1501f08adc10SDag-Erling Smørgrav linprocfs_donetdev(PFS_FILL_ARGS)
1502b47ed6cbSJonathan Lemon {
15033ab3c9c2SDmitry Chagin 	struct epoch_tracker et;
150419850ee0SJustin Hibbits 
150563827f25SBjoern A. Zeeb 	sbuf_printf(sb, "%6s|%58s|%s\n"
150663827f25SBjoern A. Zeeb 	    "%6s|%58s|%58s\n",
150763827f25SBjoern A. Zeeb 	    "Inter-", "   Receive", "  Transmit",
150863827f25SBjoern A. Zeeb 	    " face",
150963827f25SBjoern A. Zeeb 	    "bytes    packets errs drop fifo frame compressed multicast",
151063827f25SBjoern A. Zeeb 	    "bytes    packets errs drop fifo colls carrier compressed");
1511b47ed6cbSJonathan Lemon 
1512a26f987fSMarko Zec 	CURVNET_SET(TD_TO_VNET(curthread));
15133ab3c9c2SDmitry Chagin 	NET_EPOCH_ENTER(et);
15146c5786fdSDmitry Chagin 	if_foreach(linprocfs_donetdev_cb, sb);
15153ab3c9c2SDmitry Chagin 	NET_EPOCH_EXIT(et);
1516a26f987fSMarko Zec 	CURVNET_RESTORE();
1517b47ed6cbSJonathan Lemon 
1518f08adc10SDag-Erling Smørgrav 	return (0);
1519b47ed6cbSJonathan Lemon }
1520b47ed6cbSJonathan Lemon 
15214c9db956SJohn Grafton struct walkarg {
15224c9db956SJohn Grafton 	struct sbuf *sb;
15234c9db956SJohn Grafton };
15244c9db956SJohn Grafton 
15254c9db956SJohn Grafton static int
15264c9db956SJohn Grafton linux_route_print(struct rtentry *rt, void *vw)
15274c9db956SJohn Grafton {
15284c9db956SJohn Grafton #ifdef INET
15294c9db956SJohn Grafton 	struct walkarg *w = vw;
15304c9db956SJohn Grafton 	struct route_nhop_data rnd;
15314c9db956SJohn Grafton 	struct in_addr dst, mask;
15324c9db956SJohn Grafton 	struct nhop_object *nh;
15334c9db956SJohn Grafton 	char ifname[16];
15344c9db956SJohn Grafton 	uint32_t scopeid = 0;
15354c9db956SJohn Grafton 	uint32_t gw = 0;
15364c9db956SJohn Grafton 	uint32_t linux_flags = 0;
15374c9db956SJohn Grafton 
15384c9db956SJohn Grafton 	rt_get_inet_prefix_pmask(rt, &dst, &mask, &scopeid);
15394c9db956SJohn Grafton 
15404c9db956SJohn Grafton 	rt_get_rnd(rt, &rnd);
15414c9db956SJohn Grafton 
15424c9db956SJohn Grafton 	/* select only first route in case of multipath */
15434c9db956SJohn Grafton 	nh = nhop_select_func(rnd.rnd_nhop, 0);
15444c9db956SJohn Grafton 
15453ab3c9c2SDmitry Chagin 	if (ifname_bsd_to_linux_ifp(nh->nh_ifp, ifname, sizeof(ifname)) <= 0)
15463ab3c9c2SDmitry Chagin 		return (ENODEV);
15474c9db956SJohn Grafton 
15484c9db956SJohn Grafton 	gw = (nh->nh_flags & NHF_GATEWAY)
15494c9db956SJohn Grafton 		? nh->gw4_sa.sin_addr.s_addr : 0;
15504c9db956SJohn Grafton 
15514c9db956SJohn Grafton 	linux_flags = RTF_UP |
15524c9db956SJohn Grafton 		(nhop_get_rtflags(nh) & (RTF_GATEWAY | RTF_HOST));
15534c9db956SJohn Grafton 
15544c9db956SJohn Grafton 	sbuf_printf(w->sb,
15554c9db956SJohn Grafton 		"%s\t"
15564c9db956SJohn Grafton 		"%08X\t%08X\t%04X\t"
15574c9db956SJohn Grafton 		"%d\t%u\t%d\t"
15584c9db956SJohn Grafton 		"%08X\t%d\t%u\t%u",
15594c9db956SJohn Grafton 		ifname,
15604c9db956SJohn Grafton 		dst.s_addr, gw, linux_flags,
15614c9db956SJohn Grafton 		0, 0, rnd.rnd_weight,
15624c9db956SJohn Grafton 		mask.s_addr, nh->nh_mtu, 0, 0);
15634c9db956SJohn Grafton 
15644c9db956SJohn Grafton 	sbuf_printf(w->sb, "\n\n");
15654c9db956SJohn Grafton #endif
15664c9db956SJohn Grafton 	return (0);
15674c9db956SJohn Grafton }
15684c9db956SJohn Grafton 
15694c9db956SJohn Grafton /*
15704c9db956SJohn Grafton  * Filler function for proc/net/route
15714c9db956SJohn Grafton  */
15724c9db956SJohn Grafton static int
15734c9db956SJohn Grafton linprocfs_donetroute(PFS_FILL_ARGS)
15744c9db956SJohn Grafton {
15753ab3c9c2SDmitry Chagin 	struct epoch_tracker et;
15764c9db956SJohn Grafton 	struct walkarg w = {
15774c9db956SJohn Grafton 		.sb = sb
15784c9db956SJohn Grafton 	};
15794c9db956SJohn Grafton 	uint32_t fibnum = curthread->td_proc->p_fibnum;
15804c9db956SJohn Grafton 
15814c9db956SJohn Grafton 	sbuf_printf(w.sb, "%-127s\n", "Iface\tDestination\tGateway "
15824c9db956SJohn Grafton                "\tFlags\tRefCnt\tUse\tMetric\tMask\t\tMTU"
15834c9db956SJohn Grafton                "\tWindow\tIRTT");
15844c9db956SJohn Grafton 
15854c9db956SJohn Grafton 	CURVNET_SET(TD_TO_VNET(curthread));
15863ab3c9c2SDmitry Chagin 	NET_EPOCH_ENTER(et);
15874c9db956SJohn Grafton 	rib_walk(fibnum, AF_INET, false, linux_route_print, &w);
15883ab3c9c2SDmitry Chagin 	NET_EPOCH_EXIT(et);
15894c9db956SJohn Grafton 	CURVNET_RESTORE();
15904c9db956SJohn Grafton 
15914c9db956SJohn Grafton 	return (0);
15924c9db956SJohn Grafton }
15934c9db956SJohn Grafton 
1594060e4882SDoug Ambrisko /*
15955017af60SJung-uk Kim  * Filler function for proc/sys/kernel/osrelease
15965017af60SJung-uk Kim  */
15975017af60SJung-uk Kim static int
15985017af60SJung-uk Kim linprocfs_doosrelease(PFS_FILL_ARGS)
15995017af60SJung-uk Kim {
16005017af60SJung-uk Kim 	char osrelease[LINUX_MAX_UTSNAME];
16015017af60SJung-uk Kim 
16025017af60SJung-uk Kim 	linux_get_osrelease(td, osrelease);
16035017af60SJung-uk Kim 	sbuf_printf(sb, "%s\n", osrelease);
16045017af60SJung-uk Kim 
16055017af60SJung-uk Kim 	return (0);
16065017af60SJung-uk Kim }
16075017af60SJung-uk Kim 
16085017af60SJung-uk Kim /*
16095017af60SJung-uk Kim  * Filler function for proc/sys/kernel/ostype
16105017af60SJung-uk Kim  */
16115017af60SJung-uk Kim static int
16125017af60SJung-uk Kim linprocfs_doostype(PFS_FILL_ARGS)
16135017af60SJung-uk Kim {
16145017af60SJung-uk Kim 	char osname[LINUX_MAX_UTSNAME];
16155017af60SJung-uk Kim 
16165017af60SJung-uk Kim 	linux_get_osname(td, osname);
16175017af60SJung-uk Kim 	sbuf_printf(sb, "%s\n", osname);
16185017af60SJung-uk Kim 
16195017af60SJung-uk Kim 	return (0);
16205017af60SJung-uk Kim }
16215017af60SJung-uk Kim 
16225017af60SJung-uk Kim /*
16235017af60SJung-uk Kim  * Filler function for proc/sys/kernel/version
16245017af60SJung-uk Kim  */
16255017af60SJung-uk Kim static int
16265017af60SJung-uk Kim linprocfs_doosbuild(PFS_FILL_ARGS)
16275017af60SJung-uk Kim {
162878c3440eSDag-Erling Smørgrav 
16295017af60SJung-uk Kim 	linprocfs_osbuild(td, sb);
16305017af60SJung-uk Kim 	sbuf_cat(sb, "\n");
16315017af60SJung-uk Kim 	return (0);
16325017af60SJung-uk Kim }
16335017af60SJung-uk Kim 
16345017af60SJung-uk Kim /*
1635978ffef2SEdward Tomasz Napierala  * Filler function for proc/sys/kernel/msgmax
1636978ffef2SEdward Tomasz Napierala  */
1637978ffef2SEdward Tomasz Napierala static int
1638978ffef2SEdward Tomasz Napierala linprocfs_domsgmax(PFS_FILL_ARGS)
1639978ffef2SEdward Tomasz Napierala {
1640978ffef2SEdward Tomasz Napierala 
1641978ffef2SEdward Tomasz Napierala 	sbuf_printf(sb, "%d\n", msginfo.msgmax);
1642978ffef2SEdward Tomasz Napierala 	return (0);
1643978ffef2SEdward Tomasz Napierala }
1644978ffef2SEdward Tomasz Napierala 
1645978ffef2SEdward Tomasz Napierala /*
1646e40fc50bSJung-uk Kim  * Filler function for proc/sys/kernel/msgmni
1647e40fc50bSJung-uk Kim  */
1648e40fc50bSJung-uk Kim static int
1649e40fc50bSJung-uk Kim linprocfs_domsgmni(PFS_FILL_ARGS)
1650e40fc50bSJung-uk Kim {
1651e40fc50bSJung-uk Kim 
16523dd8390fSJung-uk Kim 	sbuf_printf(sb, "%d\n", msginfo.msgmni);
1653e40fc50bSJung-uk Kim 	return (0);
1654e40fc50bSJung-uk Kim }
1655e40fc50bSJung-uk Kim 
1656e40fc50bSJung-uk Kim /*
1657978ffef2SEdward Tomasz Napierala  * Filler function for proc/sys/kernel/msgmnb
1658978ffef2SEdward Tomasz Napierala  */
1659978ffef2SEdward Tomasz Napierala static int
1660978ffef2SEdward Tomasz Napierala linprocfs_domsgmnb(PFS_FILL_ARGS)
1661978ffef2SEdward Tomasz Napierala {
1662978ffef2SEdward Tomasz Napierala 
1663978ffef2SEdward Tomasz Napierala 	sbuf_printf(sb, "%d\n", msginfo.msgmnb);
1664978ffef2SEdward Tomasz Napierala 	return (0);
1665978ffef2SEdward Tomasz Napierala }
1666978ffef2SEdward Tomasz Napierala 
1667978ffef2SEdward Tomasz Napierala /*
16687135ca98SEdward Tomasz Napierala  * Filler function for proc/sys/kernel/ngroups_max
16697135ca98SEdward Tomasz Napierala  *
16707135ca98SEdward Tomasz Napierala  * Note that in Linux it defaults to 65536, not 1023.
16717135ca98SEdward Tomasz Napierala  */
16727135ca98SEdward Tomasz Napierala static int
16737135ca98SEdward Tomasz Napierala linprocfs_dongroups_max(PFS_FILL_ARGS)
16747135ca98SEdward Tomasz Napierala {
16757135ca98SEdward Tomasz Napierala 
16767135ca98SEdward Tomasz Napierala 	sbuf_printf(sb, "%d\n", ngroups_max);
16777135ca98SEdward Tomasz Napierala 	return (0);
16787135ca98SEdward Tomasz Napierala }
16797135ca98SEdward Tomasz Napierala 
16807135ca98SEdward Tomasz Napierala /*
1681050f8bb6SGiorgos Keramidas  * Filler function for proc/sys/kernel/pid_max
1682236e97b2SAlexander Leidinger  */
1683236e97b2SAlexander Leidinger static int
1684236e97b2SAlexander Leidinger linprocfs_dopid_max(PFS_FILL_ARGS)
1685236e97b2SAlexander Leidinger {
1686e3e64492SAlexander Leidinger 
1687236e97b2SAlexander Leidinger 	sbuf_printf(sb, "%i\n", PID_MAX);
1688236e97b2SAlexander Leidinger 	return (0);
1689236e97b2SAlexander Leidinger }
1690236e97b2SAlexander Leidinger 
1691236e97b2SAlexander Leidinger /*
1692e40fc50bSJung-uk Kim  * Filler function for proc/sys/kernel/sem
1693e40fc50bSJung-uk Kim  */
1694e40fc50bSJung-uk Kim static int
1695e40fc50bSJung-uk Kim linprocfs_dosem(PFS_FILL_ARGS)
1696e40fc50bSJung-uk Kim {
1697e40fc50bSJung-uk Kim 
16983dd8390fSJung-uk Kim 	sbuf_printf(sb, "%d %d %d %d\n", seminfo.semmsl, seminfo.semmns,
16993dd8390fSJung-uk Kim 	    seminfo.semopm, seminfo.semmni);
1700e40fc50bSJung-uk Kim 	return (0);
1701e40fc50bSJung-uk Kim }
1702e40fc50bSJung-uk Kim 
1703e40fc50bSJung-uk Kim /*
1704978ffef2SEdward Tomasz Napierala  * Filler function for proc/sys/kernel/shmall
1705978ffef2SEdward Tomasz Napierala  */
1706978ffef2SEdward Tomasz Napierala static int
1707978ffef2SEdward Tomasz Napierala linprocfs_doshmall(PFS_FILL_ARGS)
1708978ffef2SEdward Tomasz Napierala {
1709978ffef2SEdward Tomasz Napierala 
1710978ffef2SEdward Tomasz Napierala 	sbuf_printf(sb, "%lu\n", shminfo.shmall);
1711978ffef2SEdward Tomasz Napierala 	return (0);
1712978ffef2SEdward Tomasz Napierala }
1713978ffef2SEdward Tomasz Napierala 
1714978ffef2SEdward Tomasz Napierala /*
1715978ffef2SEdward Tomasz Napierala  * Filler function for proc/sys/kernel/shmmax
1716978ffef2SEdward Tomasz Napierala  */
1717978ffef2SEdward Tomasz Napierala static int
1718978ffef2SEdward Tomasz Napierala linprocfs_doshmmax(PFS_FILL_ARGS)
1719978ffef2SEdward Tomasz Napierala {
1720978ffef2SEdward Tomasz Napierala 
1721978ffef2SEdward Tomasz Napierala 	sbuf_printf(sb, "%lu\n", shminfo.shmmax);
1722978ffef2SEdward Tomasz Napierala 	return (0);
1723978ffef2SEdward Tomasz Napierala }
1724978ffef2SEdward Tomasz Napierala 
1725978ffef2SEdward Tomasz Napierala /*
1726978ffef2SEdward Tomasz Napierala  * Filler function for proc/sys/kernel/shmmni
1727978ffef2SEdward Tomasz Napierala  */
1728978ffef2SEdward Tomasz Napierala static int
1729978ffef2SEdward Tomasz Napierala linprocfs_doshmmni(PFS_FILL_ARGS)
1730978ffef2SEdward Tomasz Napierala {
1731978ffef2SEdward Tomasz Napierala 
1732978ffef2SEdward Tomasz Napierala 	sbuf_printf(sb, "%lu\n", shminfo.shmmni);
1733978ffef2SEdward Tomasz Napierala 	return (0);
1734978ffef2SEdward Tomasz Napierala }
1735978ffef2SEdward Tomasz Napierala 
1736978ffef2SEdward Tomasz Napierala /*
17377fcc9f7eSEdward Tomasz Napierala  * Filler function for proc/sys/kernel/tainted
17387fcc9f7eSEdward Tomasz Napierala  */
17397fcc9f7eSEdward Tomasz Napierala static int
17407fcc9f7eSEdward Tomasz Napierala linprocfs_dotainted(PFS_FILL_ARGS)
17417fcc9f7eSEdward Tomasz Napierala {
17427fcc9f7eSEdward Tomasz Napierala 
17437fcc9f7eSEdward Tomasz Napierala 	sbuf_printf(sb, "0\n");
17447fcc9f7eSEdward Tomasz Napierala 	return (0);
17457fcc9f7eSEdward Tomasz Napierala }
17467fcc9f7eSEdward Tomasz Napierala 
17477fcc9f7eSEdward Tomasz Napierala /*
1748d1fa346fSChuck Tuffli  * Filler function for proc/sys/vm/min_free_kbytes
1749d1fa346fSChuck Tuffli  *
1750d1fa346fSChuck Tuffli  * This mirrors the approach in illumos to return zero for reads. Effectively,
1751d1fa346fSChuck Tuffli  * it says, no memory is kept in reserve for "atomic allocations". This class
1752d1fa346fSChuck Tuffli  * of allocation can be used at times when a thread cannot be suspended.
1753d1fa346fSChuck Tuffli  */
1754d1fa346fSChuck Tuffli static int
1755d1fa346fSChuck Tuffli linprocfs_dominfree(PFS_FILL_ARGS)
1756d1fa346fSChuck Tuffli {
1757d1fa346fSChuck Tuffli 
1758d1fa346fSChuck Tuffli 	sbuf_printf(sb, "%d\n", 0);
1759d1fa346fSChuck Tuffli 	return (0);
1760d1fa346fSChuck Tuffli }
1761d1fa346fSChuck Tuffli 
1762d1fa346fSChuck Tuffli /*
1763060e4882SDoug Ambrisko  * Filler function for proc/scsi/device_info
1764060e4882SDoug Ambrisko  */
1765060e4882SDoug Ambrisko static int
1766060e4882SDoug Ambrisko linprocfs_doscsidevinfo(PFS_FILL_ARGS)
1767060e4882SDoug Ambrisko {
176878c3440eSDag-Erling Smørgrav 
1769060e4882SDoug Ambrisko 	return (0);
1770060e4882SDoug Ambrisko }
1771060e4882SDoug Ambrisko 
1772060e4882SDoug Ambrisko /*
1773060e4882SDoug Ambrisko  * Filler function for proc/scsi/scsi
1774060e4882SDoug Ambrisko  */
1775060e4882SDoug Ambrisko static int
1776060e4882SDoug Ambrisko linprocfs_doscsiscsi(PFS_FILL_ARGS)
1777060e4882SDoug Ambrisko {
177878c3440eSDag-Erling Smørgrav 
1779060e4882SDoug Ambrisko 	return (0);
1780060e4882SDoug Ambrisko }
1781060e4882SDoug Ambrisko 
17824c178576SDag-Erling Smørgrav /*
17834c178576SDag-Erling Smørgrav  * Filler function for proc/devices
17844c178576SDag-Erling Smørgrav  */
1785f08adc10SDag-Erling Smørgrav static int
1786f08adc10SDag-Erling Smørgrav linprocfs_dodevices(PFS_FILL_ARGS)
1787b47ed6cbSJonathan Lemon {
1788060e4882SDoug Ambrisko 	char *char_devices;
1789f08adc10SDag-Erling Smørgrav 	sbuf_printf(sb, "Character devices:\n");
1790b47ed6cbSJonathan Lemon 
1791060e4882SDoug Ambrisko 	char_devices = linux_get_char_devices();
1792060e4882SDoug Ambrisko 	sbuf_printf(sb, "%s", char_devices);
1793060e4882SDoug Ambrisko 	linux_free_get_char_devices(char_devices);
1794f08adc10SDag-Erling Smørgrav 
1795f08adc10SDag-Erling Smørgrav 	sbuf_printf(sb, "\nBlock devices:\n");
1796f08adc10SDag-Erling Smørgrav 
1797f08adc10SDag-Erling Smørgrav 	return (0);
1798b47ed6cbSJonathan Lemon }
1799b47ed6cbSJonathan Lemon 
18004c178576SDag-Erling Smørgrav /*
18014c178576SDag-Erling Smørgrav  * Filler function for proc/cmdline
18024c178576SDag-Erling Smørgrav  */
1803f08adc10SDag-Erling Smørgrav static int
1804f08adc10SDag-Erling Smørgrav linprocfs_docmdline(PFS_FILL_ARGS)
1805b47ed6cbSJonathan Lemon {
180678c3440eSDag-Erling Smørgrav 
1807f08adc10SDag-Erling Smørgrav 	sbuf_printf(sb, "BOOT_IMAGE=%s", kernelname);
1808f08adc10SDag-Erling Smørgrav 	sbuf_printf(sb, " ro root=302\n");
1809f08adc10SDag-Erling Smørgrav 	return (0);
1810886a6f6fSDag-Erling Smørgrav }
1811f08adc10SDag-Erling Smørgrav 
1812663072c6SJohn Baldwin /*
1813663072c6SJohn Baldwin  * Filler function for proc/filesystems
1814663072c6SJohn Baldwin  */
1815663072c6SJohn Baldwin static int
1816663072c6SJohn Baldwin linprocfs_dofilesystems(PFS_FILL_ARGS)
1817663072c6SJohn Baldwin {
1818663072c6SJohn Baldwin 	struct vfsconf *vfsp;
1819663072c6SJohn Baldwin 
1820eb00e5b7SKonstantin Belousov 	vfsconf_slock();
1821663072c6SJohn Baldwin 	TAILQ_FOREACH(vfsp, &vfsconf, vfc_list) {
1822663072c6SJohn Baldwin 		if (vfsp->vfc_flags & VFCF_SYNTHETIC)
1823663072c6SJohn Baldwin 			sbuf_printf(sb, "nodev");
1824663072c6SJohn Baldwin 		sbuf_printf(sb, "\t%s\n", vfsp->vfc_name);
1825663072c6SJohn Baldwin 	}
1826eb00e5b7SKonstantin Belousov 	vfsconf_sunlock();
1827663072c6SJohn Baldwin 	return(0);
1828663072c6SJohn Baldwin }
1829663072c6SJohn Baldwin 
183068936485SDag-Erling Smørgrav /*
183168936485SDag-Erling Smørgrav  * Filler function for proc/modules
183268936485SDag-Erling Smørgrav  */
183368936485SDag-Erling Smørgrav static int
183468936485SDag-Erling Smørgrav linprocfs_domodules(PFS_FILL_ARGS)
183568936485SDag-Erling Smørgrav {
1836ad382bd8SEdward Tomasz Napierala #if 0
183768936485SDag-Erling Smørgrav 	struct linker_file *lf;
183868936485SDag-Erling Smørgrav 
183968936485SDag-Erling Smørgrav 	TAILQ_FOREACH(lf, &linker_files, link) {
184068936485SDag-Erling Smørgrav 		sbuf_printf(sb, "%-20s%8lu%4d\n", lf->filename,
184168936485SDag-Erling Smørgrav 		    (unsigned long)lf->size, lf->refs);
184268936485SDag-Erling Smørgrav 	}
1843ad382bd8SEdward Tomasz Napierala #endif
184468936485SDag-Erling Smørgrav 	return (0);
184568936485SDag-Erling Smørgrav }
184668936485SDag-Erling Smørgrav 
1847f08adc10SDag-Erling Smørgrav /*
1848ec492b49SEd Schouten  * Filler function for proc/pid/fd
1849ec492b49SEd Schouten  */
1850ec492b49SEd Schouten static int
1851ec492b49SEd Schouten linprocfs_dofdescfs(PFS_FILL_ARGS)
1852ec492b49SEd Schouten {
1853ec492b49SEd Schouten 
1854ec492b49SEd Schouten 	if (p == curproc)
1855ec492b49SEd Schouten 		sbuf_printf(sb, "/dev/fd");
1856ec492b49SEd Schouten 	else
1857ec492b49SEd Schouten 		sbuf_printf(sb, "unknown");
1858ec492b49SEd Schouten 	return (0);
1859ec492b49SEd Schouten }
1860ec492b49SEd Schouten 
1861f4d6a773SDag-Erling Smørgrav /*
1862f4d6a773SDag-Erling Smørgrav  * Filler function for proc/pid/limits
1863f4d6a773SDag-Erling Smørgrav  */
18645743aa47SDmitry Chagin static const struct linux_rlimit_ident {
1865f4d6a773SDag-Erling Smørgrav 	const char	*desc;
1866f4d6a773SDag-Erling Smørgrav 	const char	*unit;
18675743aa47SDmitry Chagin 	unsigned int	rlim_id;
18685743aa47SDmitry Chagin } linux_rlimits_ident[] = {
1869f4d6a773SDag-Erling Smørgrav 	{ "Max cpu time",	"seconds",	RLIMIT_CPU },
1870f4d6a773SDag-Erling Smørgrav 	{ "Max file size", 	"bytes",	RLIMIT_FSIZE },
1871f4d6a773SDag-Erling Smørgrav 	{ "Max data size",	"bytes", 	RLIMIT_DATA },
1872f4d6a773SDag-Erling Smørgrav 	{ "Max stack size",	"bytes", 	RLIMIT_STACK },
1873f4d6a773SDag-Erling Smørgrav 	{ "Max core file size",  "bytes",	RLIMIT_CORE },
1874f4d6a773SDag-Erling Smørgrav 	{ "Max resident set",	"bytes",	RLIMIT_RSS },
1875f4d6a773SDag-Erling Smørgrav 	{ "Max processes",	"processes",	RLIMIT_NPROC },
1876f4d6a773SDag-Erling Smørgrav 	{ "Max open files",	"files",	RLIMIT_NOFILE },
1877f4d6a773SDag-Erling Smørgrav 	{ "Max locked memory",	"bytes",	RLIMIT_MEMLOCK },
1878f4d6a773SDag-Erling Smørgrav 	{ "Max address space",	"bytes",	RLIMIT_AS },
18795743aa47SDmitry Chagin 	{ "Max file locks",	"locks",	LINUX_RLIMIT_LOCKS },
18805743aa47SDmitry Chagin 	{ "Max pending signals", "signals",	LINUX_RLIMIT_SIGPENDING },
18815743aa47SDmitry Chagin 	{ "Max msgqueue size",	"bytes",	LINUX_RLIMIT_MSGQUEUE },
18825743aa47SDmitry Chagin 	{ "Max nice priority", 		"",	LINUX_RLIMIT_NICE },
18835743aa47SDmitry Chagin 	{ "Max realtime priority",	"",	LINUX_RLIMIT_RTPRIO },
18845743aa47SDmitry Chagin 	{ "Max realtime timeout",	"us",	LINUX_RLIMIT_RTTIME },
1885f4d6a773SDag-Erling Smørgrav 	{ 0, 0, 0 }
1886f4d6a773SDag-Erling Smørgrav };
1887f4d6a773SDag-Erling Smørgrav 
1888f4d6a773SDag-Erling Smørgrav static int
1889f4d6a773SDag-Erling Smørgrav linprocfs_doproclimits(PFS_FILL_ARGS)
1890f4d6a773SDag-Erling Smørgrav {
18915743aa47SDmitry Chagin 	const struct linux_rlimit_ident *li;
18925743aa47SDmitry Chagin 	struct plimit *limp;
18935743aa47SDmitry Chagin 	struct rlimit rl;
18945743aa47SDmitry Chagin 	ssize_t size;
18955743aa47SDmitry Chagin 	int res, error;
1896f4d6a773SDag-Erling Smørgrav 
18978d340432SConrad Meyer 	error = 0;
18988d340432SConrad Meyer 
18995743aa47SDmitry Chagin 	PROC_LOCK(p);
19005743aa47SDmitry Chagin 	limp = lim_hold(p->p_limit);
19015743aa47SDmitry Chagin 	PROC_UNLOCK(p);
19025743aa47SDmitry Chagin 	size = sizeof(res);
19035743aa47SDmitry Chagin 	sbuf_printf(sb, "%-26s%-21s%-21s%-21s\n", "Limit", "Soft Limit",
1904f4d6a773SDag-Erling Smørgrav 			"Hard Limit", "Units");
19055743aa47SDmitry Chagin 	for (li = linux_rlimits_ident; li->desc != NULL; ++li) {
19065743aa47SDmitry Chagin 		switch (li->rlim_id)
19075743aa47SDmitry Chagin 		{
19085743aa47SDmitry Chagin 		case LINUX_RLIMIT_LOCKS:
19095743aa47SDmitry Chagin 			/* FALLTHROUGH */
19105743aa47SDmitry Chagin 		case LINUX_RLIMIT_RTTIME:
19115743aa47SDmitry Chagin 			rl.rlim_cur = RLIM_INFINITY;
19125743aa47SDmitry Chagin 			break;
19135743aa47SDmitry Chagin 		case LINUX_RLIMIT_SIGPENDING:
19145743aa47SDmitry Chagin 			error = kernel_sysctlbyname(td,
19155743aa47SDmitry Chagin 			    "kern.sigqueue.max_pending_per_proc",
19165743aa47SDmitry Chagin 			    &res, &size, 0, 0, 0, 0);
19175743aa47SDmitry Chagin 			if (error != 0)
1918e78adba3SConrad Meyer 				goto out;
19195743aa47SDmitry Chagin 			rl.rlim_cur = res;
19205743aa47SDmitry Chagin 			rl.rlim_max = res;
19215743aa47SDmitry Chagin 			break;
19225743aa47SDmitry Chagin 		case LINUX_RLIMIT_MSGQUEUE:
19235743aa47SDmitry Chagin 			error = kernel_sysctlbyname(td,
19245743aa47SDmitry Chagin 			    "kern.ipc.msgmnb", &res, &size, 0, 0, 0, 0);
19255743aa47SDmitry Chagin 			if (error != 0)
1926e78adba3SConrad Meyer 				goto out;
19275743aa47SDmitry Chagin 			rl.rlim_cur = res;
19285743aa47SDmitry Chagin 			rl.rlim_max = res;
19295743aa47SDmitry Chagin 			break;
19305743aa47SDmitry Chagin 		case LINUX_RLIMIT_NICE:
19315743aa47SDmitry Chagin 			/* FALLTHROUGH */
19325743aa47SDmitry Chagin 		case LINUX_RLIMIT_RTPRIO:
19335743aa47SDmitry Chagin 			rl.rlim_cur = 0;
19345743aa47SDmitry Chagin 			rl.rlim_max = 0;
19355743aa47SDmitry Chagin 			break;
19365743aa47SDmitry Chagin 		default:
19375743aa47SDmitry Chagin 			rl = limp->pl_rlimit[li->rlim_id];
19385743aa47SDmitry Chagin 			break;
1939f4d6a773SDag-Erling Smørgrav 		}
19405743aa47SDmitry Chagin 		if (rl.rlim_cur == RLIM_INFINITY)
1941f4d6a773SDag-Erling Smørgrav 			sbuf_printf(sb, "%-26s%-21s%-21s%-10s\n",
1942f4d6a773SDag-Erling Smørgrav 			    li->desc, "unlimited", "unlimited", li->unit);
1943f4d6a773SDag-Erling Smørgrav 		else
19445743aa47SDmitry Chagin 			sbuf_printf(sb, "%-26s%-21llu%-21llu%-10s\n",
19455743aa47SDmitry Chagin 			    li->desc, (unsigned long long)rl.rlim_cur,
19465743aa47SDmitry Chagin 			    (unsigned long long)rl.rlim_max, li->unit);
1947f4d6a773SDag-Erling Smørgrav 	}
1948e78adba3SConrad Meyer out:
19495743aa47SDmitry Chagin 	lim_free(limp);
19505743aa47SDmitry Chagin 	return (error);
1951f4d6a773SDag-Erling Smørgrav }
1952f4d6a773SDag-Erling Smørgrav 
19539ace8010SEitan Adler /*
1954c2da36feSEdward Tomasz Napierala  * The point of the following two functions is to work around
1955c2da36feSEdward Tomasz Napierala  * an assertion in Chromium; see kern/240991 for details.
1956c2da36feSEdward Tomasz Napierala  */
1957c2da36feSEdward Tomasz Napierala static int
1958c2da36feSEdward Tomasz Napierala linprocfs_dotaskattr(PFS_ATTR_ARGS)
1959c2da36feSEdward Tomasz Napierala {
1960c2da36feSEdward Tomasz Napierala 
1961c2da36feSEdward Tomasz Napierala 	vap->va_nlink = 3;
1962c2da36feSEdward Tomasz Napierala 	return (0);
1963c2da36feSEdward Tomasz Napierala }
1964c2da36feSEdward Tomasz Napierala 
1965c2da36feSEdward Tomasz Napierala /*
1966c2da36feSEdward Tomasz Napierala  * Filler function for proc/<pid>/task/.dummy
1967c2da36feSEdward Tomasz Napierala  */
1968c2da36feSEdward Tomasz Napierala static int
1969c2da36feSEdward Tomasz Napierala linprocfs_dotaskdummy(PFS_FILL_ARGS)
1970c2da36feSEdward Tomasz Napierala {
1971c2da36feSEdward Tomasz Napierala 
1972c2da36feSEdward Tomasz Napierala 	return (0);
1973c2da36feSEdward Tomasz Napierala }
1974c2da36feSEdward Tomasz Napierala 
1975c2da36feSEdward Tomasz Napierala /*
19769ace8010SEitan Adler  * Filler function for proc/sys/kernel/random/uuid
19779ace8010SEitan Adler  */
19789ace8010SEitan Adler static int
19799ace8010SEitan Adler linprocfs_douuid(PFS_FILL_ARGS)
19809ace8010SEitan Adler {
19819ace8010SEitan Adler 	struct uuid uuid;
19829ace8010SEitan Adler 
19839ace8010SEitan Adler 	kern_uuidgen(&uuid, 1);
19849ace8010SEitan Adler 	sbuf_printf_uuid(sb, &uuid);
19859ace8010SEitan Adler 	sbuf_printf(sb, "\n");
19869ace8010SEitan Adler 	return(0);
19879ace8010SEitan Adler }
19889ace8010SEitan Adler 
1989a6fd8bb2SDmitry Chagin /*
19900f2041a5SFernando Apesteguía  * Filler function for proc/sys/kernel/random/boot_id
19910f2041a5SFernando Apesteguía  */
19920f2041a5SFernando Apesteguía static int
19930f2041a5SFernando Apesteguía linprocfs_doboot_id(PFS_FILL_ARGS)
19940f2041a5SFernando Apesteguía {
19950f2041a5SFernando Apesteguía        static bool firstboot = 1;
19960f2041a5SFernando Apesteguía        static struct uuid uuid;
19970f2041a5SFernando Apesteguía 
19980f2041a5SFernando Apesteguía        if (firstboot) {
19990f2041a5SFernando Apesteguía                kern_uuidgen(&uuid, 1);
20000f2041a5SFernando Apesteguía                firstboot = 0;
20010f2041a5SFernando Apesteguía        }
20020f2041a5SFernando Apesteguía        sbuf_printf_uuid(sb, &uuid);
20030f2041a5SFernando Apesteguía        sbuf_printf(sb, "\n");
20040f2041a5SFernando Apesteguía        return(0);
20050f2041a5SFernando Apesteguía }
20060f2041a5SFernando Apesteguía 
20070f2041a5SFernando Apesteguía /*
2008a6fd8bb2SDmitry Chagin  * Filler function for proc/pid/auxv
2009a6fd8bb2SDmitry Chagin  */
2010a6fd8bb2SDmitry Chagin static int
2011a6fd8bb2SDmitry Chagin linprocfs_doauxv(PFS_FILL_ARGS)
2012a6fd8bb2SDmitry Chagin {
2013a6fd8bb2SDmitry Chagin 	struct sbuf *asb;
2014a6fd8bb2SDmitry Chagin 	off_t buflen, resid;
2015a6fd8bb2SDmitry Chagin 	int error;
2016a6fd8bb2SDmitry Chagin 
2017a6fd8bb2SDmitry Chagin 	/*
2018a6fd8bb2SDmitry Chagin 	 * Mimic linux behavior and pass only processes with usermode
2019a6fd8bb2SDmitry Chagin 	 * address space as valid. Return zero silently otherwise.
2020a6fd8bb2SDmitry Chagin 	 */
2021a6fd8bb2SDmitry Chagin 	if (p->p_vmspace == &vmspace0)
2022a6fd8bb2SDmitry Chagin 		return (0);
2023a6fd8bb2SDmitry Chagin 
2024a6fd8bb2SDmitry Chagin 	if (uio->uio_resid == 0)
2025a6fd8bb2SDmitry Chagin 		return (0);
2026a6fd8bb2SDmitry Chagin 	if (uio->uio_offset < 0 || uio->uio_resid < 0)
2027a6fd8bb2SDmitry Chagin 		return (EINVAL);
2028a6fd8bb2SDmitry Chagin 
2029a6fd8bb2SDmitry Chagin 	asb = sbuf_new_auto();
2030a6fd8bb2SDmitry Chagin 	if (asb == NULL)
2031a6fd8bb2SDmitry Chagin 		return (ENOMEM);
2032a6fd8bb2SDmitry Chagin 	error = proc_getauxv(td, p, asb);
2033a6fd8bb2SDmitry Chagin 	if (error == 0)
2034a6fd8bb2SDmitry Chagin 		error = sbuf_finish(asb);
2035a6fd8bb2SDmitry Chagin 
2036a6fd8bb2SDmitry Chagin 	resid = sbuf_len(asb) - uio->uio_offset;
2037a6fd8bb2SDmitry Chagin 	if (resid > uio->uio_resid)
2038a6fd8bb2SDmitry Chagin 		buflen = uio->uio_resid;
2039a6fd8bb2SDmitry Chagin 	else
2040a6fd8bb2SDmitry Chagin 		buflen = resid;
2041a6fd8bb2SDmitry Chagin 	if (buflen > IOSIZE_MAX)
2042a6fd8bb2SDmitry Chagin 		return (EINVAL);
2043cd853791SKonstantin Belousov 	if (buflen > maxphys)
2044cd853791SKonstantin Belousov 		buflen = maxphys;
2045a6fd8bb2SDmitry Chagin 	if (resid <= 0)
2046a6fd8bb2SDmitry Chagin 		return (0);
2047a6fd8bb2SDmitry Chagin 
2048a6fd8bb2SDmitry Chagin 	if (error == 0)
2049a6fd8bb2SDmitry Chagin 		error = uiomove(sbuf_data(asb) + uio->uio_offset, buflen, uio);
2050a6fd8bb2SDmitry Chagin 	sbuf_delete(asb);
2051a6fd8bb2SDmitry Chagin 	return (error);
2052a6fd8bb2SDmitry Chagin }
20539ace8010SEitan Adler 
2054ec492b49SEd Schouten /*
2055b7df7b98SDmitry Chagin  * Filler function for proc/self/oom_score_adj
2056b7df7b98SDmitry Chagin  */
2057b7df7b98SDmitry Chagin static int
2058b7df7b98SDmitry Chagin linprocfs_do_oom_score_adj(PFS_FILL_ARGS)
2059b7df7b98SDmitry Chagin {
2060b7df7b98SDmitry Chagin 	struct linux_pemuldata *pem;
2061b7df7b98SDmitry Chagin 	long oom;
2062b7df7b98SDmitry Chagin 
2063b7df7b98SDmitry Chagin 	pem = pem_find(p);
2064b7df7b98SDmitry Chagin 	if (pem == NULL || uio == NULL)
2065b7df7b98SDmitry Chagin 		return (EOPNOTSUPP);
2066b7df7b98SDmitry Chagin 	if (uio->uio_rw == UIO_READ) {
2067b7df7b98SDmitry Chagin 		sbuf_printf(sb, "%d\n", pem->oom_score_adj);
2068b7df7b98SDmitry Chagin 	} else {
2069b7df7b98SDmitry Chagin 		sbuf_trim(sb);
2070b7df7b98SDmitry Chagin 		sbuf_finish(sb);
2071b7df7b98SDmitry Chagin 		oom = strtol(sbuf_data(sb), NULL, 10);
2072b7df7b98SDmitry Chagin 		if (oom < LINUX_OOM_SCORE_ADJ_MIN ||
2073b7df7b98SDmitry Chagin 		    oom > LINUX_OOM_SCORE_ADJ_MAX)
2074b7df7b98SDmitry Chagin 			return (EINVAL);
2075b7df7b98SDmitry Chagin 		pem->oom_score_adj = oom;
2076b7df7b98SDmitry Chagin 	}
2077b7df7b98SDmitry Chagin 	return (0);
2078b7df7b98SDmitry Chagin }
2079b7df7b98SDmitry Chagin 
2080b7df7b98SDmitry Chagin /*
20817e2a4511SDmitry Chagin  * Filler function for proc/sys/vm/max_map_count
20827e2a4511SDmitry Chagin  *
20837e2a4511SDmitry Chagin  * Maximum number of active map areas, on Linux this limits the number
20847e2a4511SDmitry Chagin  * of vmaps per mm struct. We don't limit mappings, return a suitable
20857e2a4511SDmitry Chagin  * large value.
20867e2a4511SDmitry Chagin  */
20877e2a4511SDmitry Chagin static int
20887e2a4511SDmitry Chagin linprocfs_domax_map_cnt(PFS_FILL_ARGS)
20897e2a4511SDmitry Chagin {
20907e2a4511SDmitry Chagin 
20917e2a4511SDmitry Chagin 	sbuf_printf(sb, "%d\n", INT32_MAX);
20927e2a4511SDmitry Chagin 	return (0);
20937e2a4511SDmitry Chagin }
20947e2a4511SDmitry Chagin 
20957e2a4511SDmitry Chagin /*
209625a04527SRicardo Branco  * Filler function for proc/sysvipc/msg
209725a04527SRicardo Branco  */
209825a04527SRicardo Branco static int
209925a04527SRicardo Branco linprocfs_dosysvipc_msg(PFS_FILL_ARGS)
210025a04527SRicardo Branco {
210125a04527SRicardo Branco 	struct msqid_kernel *msqids;
210225a04527SRicardo Branco 	size_t id, size;
210325a04527SRicardo Branco 	int error;
210425a04527SRicardo Branco 
210525a04527SRicardo Branco 	sbuf_printf(sb,
210625a04527SRicardo Branco 	    "%10s %10s %4s  %10s %10s %5s %5s %5s %5s %5s %5s %10s %10s %10s\n",
210725a04527SRicardo Branco 	    "key", "msqid", "perms", "cbytes", "qnum", "lspid", "lrpid",
210825a04527SRicardo Branco 	    "uid", "gid", "cuid", "cgid", "stime", "rtime", "ctime");
210925a04527SRicardo Branco 
211025a04527SRicardo Branco 	error = kern_get_msqids(curthread, &msqids, &size);
211125a04527SRicardo Branco 	if (error != 0)
211225a04527SRicardo Branco 		return (error);
211325a04527SRicardo Branco 
211425a04527SRicardo Branco 	for (id = 0; id < size; id++) {
211525a04527SRicardo Branco 		if (msqids[id].u.msg_qbytes == 0)
211625a04527SRicardo Branco 			continue;
211725a04527SRicardo Branco 		sbuf_printf(sb,
2118208f11e8SWarner Losh 		    "%10d %10zu  %4o  %10lu %10lu %5u %5u %5u %5u %5u %5u %jd %jd %jd\n",
211925a04527SRicardo Branco 		    (int)msqids[id].u.msg_perm.key,
212025a04527SRicardo Branco 		    IXSEQ_TO_IPCID(id, msqids[id].u.msg_perm),
212125a04527SRicardo Branco 		    msqids[id].u.msg_perm.mode,
212225a04527SRicardo Branco 		    msqids[id].u.msg_cbytes,
212325a04527SRicardo Branco 		    msqids[id].u.msg_qnum,
212425a04527SRicardo Branco 		    msqids[id].u.msg_lspid,
212525a04527SRicardo Branco 		    msqids[id].u.msg_lrpid,
212625a04527SRicardo Branco 		    msqids[id].u.msg_perm.uid,
212725a04527SRicardo Branco 		    msqids[id].u.msg_perm.gid,
212825a04527SRicardo Branco 		    msqids[id].u.msg_perm.cuid,
212925a04527SRicardo Branco 		    msqids[id].u.msg_perm.cgid,
213025a04527SRicardo Branco 		    (intmax_t)msqids[id].u.msg_stime,
213125a04527SRicardo Branco 		    (intmax_t)msqids[id].u.msg_rtime,
213225a04527SRicardo Branco 		    (intmax_t)msqids[id].u.msg_ctime);
213325a04527SRicardo Branco 	}
213425a04527SRicardo Branco 
213525a04527SRicardo Branco 	free(msqids, M_TEMP);
213625a04527SRicardo Branco 	return (0);
213725a04527SRicardo Branco }
213825a04527SRicardo Branco 
213925a04527SRicardo Branco /*
214025a04527SRicardo Branco  * Filler function for proc/sysvipc/sem
214125a04527SRicardo Branco  */
214225a04527SRicardo Branco static int
214325a04527SRicardo Branco linprocfs_dosysvipc_sem(PFS_FILL_ARGS)
214425a04527SRicardo Branco {
214525a04527SRicardo Branco 	struct semid_kernel *semids;
214625a04527SRicardo Branco 	size_t id, size;
214725a04527SRicardo Branco 	int error;
214825a04527SRicardo Branco 
214925a04527SRicardo Branco 	sbuf_printf(sb, "%10s %10s %4s %10s %5s %5s %5s %5s %10s %10s\n",
215025a04527SRicardo Branco 	    "key", "semid", "perms", "nsems", "uid", "gid", "cuid", "cgid",
215125a04527SRicardo Branco 	    "otime", "ctime");
215225a04527SRicardo Branco 
215325a04527SRicardo Branco 	error = kern_get_sema(curthread, &semids, &size);
215425a04527SRicardo Branco 	if (error != 0)
215525a04527SRicardo Branco 		return (error);
215625a04527SRicardo Branco 
215725a04527SRicardo Branco 	for (id = 0; id < size; id++) {
215825a04527SRicardo Branco 		if ((semids[id].u.sem_perm.mode & SEM_ALLOC) == 0)
215925a04527SRicardo Branco 			continue;
216025a04527SRicardo Branco 		sbuf_printf(sb,
2161208f11e8SWarner Losh 		    "%10d %10zu  %4o %10u %5u %5u %5u %5u %jd %jd\n",
216225a04527SRicardo Branco 		    (int)semids[id].u.sem_perm.key,
216325a04527SRicardo Branco 		    IXSEQ_TO_IPCID(id, semids[id].u.sem_perm),
216425a04527SRicardo Branco 		    semids[id].u.sem_perm.mode,
216525a04527SRicardo Branco 		    semids[id].u.sem_nsems,
216625a04527SRicardo Branco 		    semids[id].u.sem_perm.uid,
216725a04527SRicardo Branco 		    semids[id].u.sem_perm.gid,
216825a04527SRicardo Branco 		    semids[id].u.sem_perm.cuid,
216925a04527SRicardo Branco 		    semids[id].u.sem_perm.cgid,
217025a04527SRicardo Branco 		    (intmax_t)semids[id].u.sem_otime,
217125a04527SRicardo Branco 		    (intmax_t)semids[id].u.sem_ctime);
217225a04527SRicardo Branco 	}
217325a04527SRicardo Branco 
217425a04527SRicardo Branco 	free(semids, M_TEMP);
217525a04527SRicardo Branco 	return (0);
217625a04527SRicardo Branco }
217725a04527SRicardo Branco 
217825a04527SRicardo Branco /*
217925a04527SRicardo Branco  * Filler function for proc/sysvipc/shm
218025a04527SRicardo Branco  */
218125a04527SRicardo Branco static int
218225a04527SRicardo Branco linprocfs_dosysvipc_shm(PFS_FILL_ARGS)
218325a04527SRicardo Branco {
218425a04527SRicardo Branco 	struct shmid_kernel *shmids;
218525a04527SRicardo Branco 	size_t id, size;
218625a04527SRicardo Branco 	int error;
218725a04527SRicardo Branco 
218825a04527SRicardo Branco 	sbuf_printf(sb,
218925a04527SRicardo Branco 	    "%10s %10s %s %21s %5s %5s %5s %5s %5s %5s %5s %10s %10s %10s %21s %21s\n",
219025a04527SRicardo Branco 	    "key", "shmid", "perms", "size", "cpid", "lpid", "nattch", "uid",
219125a04527SRicardo Branco 	    "gid", "cuid", "cgid", "atime", "dtime", "ctime", "rss", "swap");
219225a04527SRicardo Branco 
219325a04527SRicardo Branco 	error = kern_get_shmsegs(curthread, &shmids, &size);
219425a04527SRicardo Branco 	if (error != 0)
219525a04527SRicardo Branco 		return (error);
219625a04527SRicardo Branco 
219725a04527SRicardo Branco 	for (id = 0; id < size; id++) {
219825a04527SRicardo Branco 		if ((shmids[id].u.shm_perm.mode & SHMSEG_ALLOCATED) == 0)
219925a04527SRicardo Branco 			continue;
220025a04527SRicardo Branco 		sbuf_printf(sb,
2201208f11e8SWarner Losh 		    "%10d %10zu  %4o %21zu %5u %5u  %5u %5u %5u %5u %5u %jd %jd %jd %21d %21d\n",
220225a04527SRicardo Branco 		    (int)shmids[id].u.shm_perm.key,
220325a04527SRicardo Branco 		    IXSEQ_TO_IPCID(id, shmids[id].u.shm_perm),
220425a04527SRicardo Branco 		    shmids[id].u.shm_perm.mode,
220525a04527SRicardo Branco 		    shmids[id].u.shm_segsz,
220625a04527SRicardo Branco 		    shmids[id].u.shm_cpid,
220725a04527SRicardo Branco 		    shmids[id].u.shm_lpid,
220825a04527SRicardo Branco 		    shmids[id].u.shm_nattch,
220925a04527SRicardo Branco 		    shmids[id].u.shm_perm.uid,
221025a04527SRicardo Branco 		    shmids[id].u.shm_perm.gid,
221125a04527SRicardo Branco 		    shmids[id].u.shm_perm.cuid,
221225a04527SRicardo Branco 		    shmids[id].u.shm_perm.cgid,
221325a04527SRicardo Branco 		    (intmax_t)shmids[id].u.shm_atime,
221425a04527SRicardo Branco 		    (intmax_t)shmids[id].u.shm_dtime,
221525a04527SRicardo Branco 		    (intmax_t)shmids[id].u.shm_ctime,
221625a04527SRicardo Branco 		    0, 0);	/* XXX rss & swp are not supported */
221725a04527SRicardo Branco 	}
221825a04527SRicardo Branco 
221925a04527SRicardo Branco 	free(shmids, M_TEMP);
222025a04527SRicardo Branco 	return (0);
222125a04527SRicardo Branco }
222225a04527SRicardo Branco 
222325a04527SRicardo Branco /*
222404d3f8e5SRicardo Branco  * Filler function for proc/sys/fs/mqueue/msg_default
222504d3f8e5SRicardo Branco  */
222604d3f8e5SRicardo Branco static int
222704d3f8e5SRicardo Branco linprocfs_domqueue_msg_default(PFS_FILL_ARGS)
222804d3f8e5SRicardo Branco {
222904d3f8e5SRicardo Branco 	int res, error;
223004d3f8e5SRicardo Branco 	size_t size = sizeof(res);
223104d3f8e5SRicardo Branco 
223204d3f8e5SRicardo Branco 	error = kernel_sysctlbyname(curthread, "kern.mqueue.default_maxmsg",
223304d3f8e5SRicardo Branco 	    &res, &size, NULL, 0, 0, 0);
223404d3f8e5SRicardo Branco 	if (error != 0)
223504d3f8e5SRicardo Branco 		return (error);
223604d3f8e5SRicardo Branco 
223704d3f8e5SRicardo Branco 	sbuf_printf(sb, "%d\n", res);
223804d3f8e5SRicardo Branco 	return (0);
223904d3f8e5SRicardo Branco }
224004d3f8e5SRicardo Branco 
224104d3f8e5SRicardo Branco /*
224204d3f8e5SRicardo Branco  * Filler function for proc/sys/fs/mqueue/msgsize_default
224304d3f8e5SRicardo Branco  */
224404d3f8e5SRicardo Branco static int
224504d3f8e5SRicardo Branco linprocfs_domqueue_msgsize_default(PFS_FILL_ARGS)
224604d3f8e5SRicardo Branco {
224704d3f8e5SRicardo Branco 	int res, error;
224804d3f8e5SRicardo Branco 	size_t size = sizeof(res);
224904d3f8e5SRicardo Branco 
225004d3f8e5SRicardo Branco 	error = kernel_sysctlbyname(curthread, "kern.mqueue.default_msgsize",
225104d3f8e5SRicardo Branco 	    &res, &size, NULL, 0, 0, 0);
225204d3f8e5SRicardo Branco 	if (error != 0)
225304d3f8e5SRicardo Branco 		return (error);
225404d3f8e5SRicardo Branco 
225504d3f8e5SRicardo Branco 	sbuf_printf(sb, "%d\n", res);
225604d3f8e5SRicardo Branco 	return (0);
225704d3f8e5SRicardo Branco 
225804d3f8e5SRicardo Branco }
225904d3f8e5SRicardo Branco 
226004d3f8e5SRicardo Branco /*
226104d3f8e5SRicardo Branco  * Filler function for proc/sys/fs/mqueue/msg_max
226204d3f8e5SRicardo Branco  */
226304d3f8e5SRicardo Branco static int
226404d3f8e5SRicardo Branco linprocfs_domqueue_msg_max(PFS_FILL_ARGS)
226504d3f8e5SRicardo Branco {
226604d3f8e5SRicardo Branco 	int res, error;
226704d3f8e5SRicardo Branco 	size_t size = sizeof(res);
226804d3f8e5SRicardo Branco 
226904d3f8e5SRicardo Branco 	error = kernel_sysctlbyname(curthread, "kern.mqueue.maxmsg",
227004d3f8e5SRicardo Branco 	    &res, &size, NULL, 0, 0, 0);
227104d3f8e5SRicardo Branco 	if (error != 0)
227204d3f8e5SRicardo Branco 		return (error);
227304d3f8e5SRicardo Branco 
227404d3f8e5SRicardo Branco 	sbuf_printf(sb, "%d\n", res);
227504d3f8e5SRicardo Branco 	return (0);
227604d3f8e5SRicardo Branco }
227704d3f8e5SRicardo Branco 
227804d3f8e5SRicardo Branco /*
227904d3f8e5SRicardo Branco  * Filler function for proc/sys/fs/mqueue/msgsize_max
228004d3f8e5SRicardo Branco  */
228104d3f8e5SRicardo Branco static int
228204d3f8e5SRicardo Branco linprocfs_domqueue_msgsize_max(PFS_FILL_ARGS)
228304d3f8e5SRicardo Branco {
228404d3f8e5SRicardo Branco 	int res, error;
228504d3f8e5SRicardo Branco 	size_t size = sizeof(res);
228604d3f8e5SRicardo Branco 
228704d3f8e5SRicardo Branco 	error = kernel_sysctlbyname(curthread, "kern.mqueue.maxmsgsize",
228804d3f8e5SRicardo Branco 	    &res, &size, NULL, 0, 0, 0);
228904d3f8e5SRicardo Branco 	if (error != 0)
229004d3f8e5SRicardo Branco 		return (error);
229104d3f8e5SRicardo Branco 
229204d3f8e5SRicardo Branco 	sbuf_printf(sb, "%d\n", res);
229304d3f8e5SRicardo Branco 	return (0);
229404d3f8e5SRicardo Branco }
229504d3f8e5SRicardo Branco 
229604d3f8e5SRicardo Branco /*
229704d3f8e5SRicardo Branco  * Filler function for proc/sys/fs/mqueue/queues_max
229804d3f8e5SRicardo Branco  */
229904d3f8e5SRicardo Branco static int
230004d3f8e5SRicardo Branco linprocfs_domqueue_queues_max(PFS_FILL_ARGS)
230104d3f8e5SRicardo Branco {
230204d3f8e5SRicardo Branco 	int res, error;
230304d3f8e5SRicardo Branco 	size_t size = sizeof(res);
230404d3f8e5SRicardo Branco 
230504d3f8e5SRicardo Branco 	error = kernel_sysctlbyname(curthread, "kern.mqueue.maxmq",
230604d3f8e5SRicardo Branco 	    &res, &size, NULL, 0, 0, 0);
230704d3f8e5SRicardo Branco 	if (error != 0)
230804d3f8e5SRicardo Branco 		return (error);
230904d3f8e5SRicardo Branco 
231004d3f8e5SRicardo Branco 	sbuf_printf(sb, "%d\n", res);
231104d3f8e5SRicardo Branco 	return (0);
231204d3f8e5SRicardo Branco }
231304d3f8e5SRicardo Branco 
231404d3f8e5SRicardo Branco /*
23151c0bfd6eSDag-Erling Smørgrav  * Constructor
2316f08adc10SDag-Erling Smørgrav  */
23171c0bfd6eSDag-Erling Smørgrav static int
23181c0bfd6eSDag-Erling Smørgrav linprocfs_init(PFS_INIT_ARGS)
23191c0bfd6eSDag-Erling Smørgrav {
23201c0bfd6eSDag-Erling Smørgrav 	struct pfs_node *root;
23211c0bfd6eSDag-Erling Smørgrav 	struct pfs_node *dir;
2322d1fa346fSChuck Tuffli 	struct pfs_node *sys;
2323f08adc10SDag-Erling Smørgrav 
23241c0bfd6eSDag-Erling Smørgrav 	root = pi->pi_root;
2325f08adc10SDag-Erling Smørgrav 
23267d10d055SDag-Erling Smørgrav 	/* /proc/... */
23270dd872f5SDag-Erling Smørgrav 	pfs_create_file(root, "cmdline", &linprocfs_docmdline,
2328771709ebSDag-Erling Smørgrav 	    NULL, NULL, NULL, PFS_RD);
23290dd872f5SDag-Erling Smørgrav 	pfs_create_file(root, "cpuinfo", &linprocfs_docpuinfo,
2330771709ebSDag-Erling Smørgrav 	    NULL, NULL, NULL, PFS_RD);
23310dd872f5SDag-Erling Smørgrav 	pfs_create_file(root, "devices", &linprocfs_dodevices,
2332771709ebSDag-Erling Smørgrav 	    NULL, NULL, NULL, PFS_RD);
2333663072c6SJohn Baldwin 	pfs_create_file(root, "filesystems", &linprocfs_dofilesystems,
2334663072c6SJohn Baldwin 	    NULL, NULL, NULL, PFS_RD);
23350dd872f5SDag-Erling Smørgrav 	pfs_create_file(root, "loadavg", &linprocfs_doloadavg,
2336771709ebSDag-Erling Smørgrav 	    NULL, NULL, NULL, PFS_RD);
23370dd872f5SDag-Erling Smørgrav 	pfs_create_file(root, "meminfo", &linprocfs_domeminfo,
2338771709ebSDag-Erling Smørgrav 	    NULL, NULL, NULL, PFS_RD);
23390dd872f5SDag-Erling Smørgrav 	pfs_create_file(root, "modules", &linprocfs_domodules,
2340771709ebSDag-Erling Smørgrav 	    NULL, NULL, NULL, PFS_RD);
2341060e4882SDoug Ambrisko 	pfs_create_file(root, "mounts", &linprocfs_domtab,
2342771709ebSDag-Erling Smørgrav 	    NULL, NULL, NULL, PFS_RD);
23430dd872f5SDag-Erling Smørgrav 	pfs_create_file(root, "mtab", &linprocfs_domtab,
2344771709ebSDag-Erling Smørgrav 	    NULL, NULL, NULL, PFS_RD);
2345d2b2128aSDoug Ambrisko 	pfs_create_file(root, "partitions", &linprocfs_dopartitions,
2346d2b2128aSDoug Ambrisko 	    NULL, NULL, NULL, PFS_RD);
2347157b65aeSDag-Erling Smørgrav 	pfs_create_link(root, "self", &procfs_docurproc,
2348771709ebSDag-Erling Smørgrav 	    NULL, NULL, NULL, 0);
23490dd872f5SDag-Erling Smørgrav 	pfs_create_file(root, "stat", &linprocfs_dostat,
2350771709ebSDag-Erling Smørgrav 	    NULL, NULL, NULL, PFS_RD);
2351dda4f960SKonstantin Belousov 	pfs_create_file(root, "swaps", &linprocfs_doswaps,
2352dda4f960SKonstantin Belousov 	    NULL, NULL, NULL, PFS_RD);
23530dd872f5SDag-Erling Smørgrav 	pfs_create_file(root, "uptime", &linprocfs_douptime,
2354771709ebSDag-Erling Smørgrav 	    NULL, NULL, NULL, PFS_RD);
23550dd872f5SDag-Erling Smørgrav 	pfs_create_file(root, "version", &linprocfs_doversion,
2356771709ebSDag-Erling Smørgrav 	    NULL, NULL, NULL, PFS_RD);
2357f08adc10SDag-Erling Smørgrav 
23588b99a63fSEdward Tomasz Napierala 	/* /proc/bus/... */
23598b99a63fSEdward Tomasz Napierala 	dir = pfs_create_dir(root, "bus", NULL, NULL, NULL, 0);
23608b99a63fSEdward Tomasz Napierala 	dir = pfs_create_dir(dir, "pci", NULL, NULL, NULL, 0);
23618b99a63fSEdward Tomasz Napierala 	dir = pfs_create_dir(dir, "devices", NULL, NULL, NULL, 0);
23628b99a63fSEdward Tomasz Napierala 
23637d10d055SDag-Erling Smørgrav 	/* /proc/net/... */
2364771709ebSDag-Erling Smørgrav 	dir = pfs_create_dir(root, "net", NULL, NULL, NULL, 0);
23651c0bfd6eSDag-Erling Smørgrav 	pfs_create_file(dir, "dev", &linprocfs_donetdev,
2366771709ebSDag-Erling Smørgrav 	    NULL, NULL, NULL, PFS_RD);
23674c9db956SJohn Grafton 	pfs_create_file(dir, "route", &linprocfs_donetroute,
23684c9db956SJohn Grafton 	    NULL, NULL, NULL, PFS_RD);
2369f08adc10SDag-Erling Smørgrav 
23707d10d055SDag-Erling Smørgrav 	/* /proc/<pid>/... */
2371771709ebSDag-Erling Smørgrav 	dir = pfs_create_dir(root, "pid", NULL, NULL, NULL, PFS_PROCDEP);
23721c0bfd6eSDag-Erling Smørgrav 	pfs_create_file(dir, "cmdline", &linprocfs_doproccmdline,
2373771709ebSDag-Erling Smørgrav 	    NULL, NULL, NULL, PFS_RD);
23740dd872f5SDag-Erling Smørgrav 	pfs_create_link(dir, "cwd", &linprocfs_doproccwd,
2375771709ebSDag-Erling Smørgrav 	    NULL, NULL, NULL, 0);
237616dbc7f2SDavid E. O'Brien 	pfs_create_file(dir, "environ", &linprocfs_doprocenviron,
2377dcc0e6c4SDmitry Chagin 	    NULL, &procfs_candebug, NULL, PFS_RD);
2378157b65aeSDag-Erling Smørgrav 	pfs_create_link(dir, "exe", &procfs_doprocfile,
2379771709ebSDag-Erling Smørgrav 	    NULL, &procfs_notsystem, NULL, 0);
238016dbc7f2SDavid E. O'Brien 	pfs_create_file(dir, "maps", &linprocfs_doprocmaps,
238120172854SConrad Meyer 	    NULL, NULL, NULL, PFS_RD | PFS_AUTODRAIN);
238291bc7361SEdward Tomasz Napierala 	pfs_create_file(dir, "mem", &linprocfs_doprocmem,
2383e07db022SEitan Adler 	    procfs_attr_rw, &procfs_candebug, NULL, PFS_RDWR | PFS_RAW);
2384b1976ea1SConrad Meyer 	pfs_create_file(dir, "mountinfo", &linprocfs_doprocmountinfo,
2385b1976ea1SConrad Meyer 	    NULL, NULL, NULL, PFS_RD);
238615cbcf4bSEdward Tomasz Napierala 	pfs_create_file(dir, "mounts", &linprocfs_domtab,
238715cbcf4bSEdward Tomasz Napierala 	    NULL, NULL, NULL, PFS_RD);
23880dd872f5SDag-Erling Smørgrav 	pfs_create_link(dir, "root", &linprocfs_doprocroot,
2389771709ebSDag-Erling Smørgrav 	    NULL, NULL, NULL, 0);
23901c0bfd6eSDag-Erling Smørgrav 	pfs_create_file(dir, "stat", &linprocfs_doprocstat,
2391771709ebSDag-Erling Smørgrav 	    NULL, NULL, NULL, PFS_RD);
23920dd872f5SDag-Erling Smørgrav 	pfs_create_file(dir, "statm", &linprocfs_doprocstatm,
2393771709ebSDag-Erling Smørgrav 	    NULL, NULL, NULL, PFS_RD);
23941c0bfd6eSDag-Erling Smørgrav 	pfs_create_file(dir, "status", &linprocfs_doprocstatus,
2395771709ebSDag-Erling Smørgrav 	    NULL, NULL, NULL, PFS_RD);
2396ec492b49SEd Schouten 	pfs_create_link(dir, "fd", &linprocfs_dofdescfs,
2397ec492b49SEd Schouten 	    NULL, NULL, NULL, 0);
2398a6fd8bb2SDmitry Chagin 	pfs_create_file(dir, "auxv", &linprocfs_doauxv,
2399a6fd8bb2SDmitry Chagin 	    NULL, &procfs_candebug, NULL, PFS_RD|PFS_RAWRD);
2400f4d6a773SDag-Erling Smørgrav 	pfs_create_file(dir, "limits", &linprocfs_doproclimits,
2401f4d6a773SDag-Erling Smørgrav 	    NULL, NULL, NULL, PFS_RD);
2402b7df7b98SDmitry Chagin 	pfs_create_file(dir, "oom_score_adj", &linprocfs_do_oom_score_adj,
2403b7df7b98SDmitry Chagin 	    procfs_attr_rw, &procfs_candebug, NULL, PFS_RDWR);
24041c0bfd6eSDag-Erling Smørgrav 
2405c2da36feSEdward Tomasz Napierala 	/* /proc/<pid>/task/... */
2406c2da36feSEdward Tomasz Napierala 	dir = pfs_create_dir(dir, "task", linprocfs_dotaskattr, NULL, NULL, 0);
2407c2da36feSEdward Tomasz Napierala 	pfs_create_file(dir, ".dummy", &linprocfs_dotaskdummy,
2408c2da36feSEdward Tomasz Napierala 	    NULL, NULL, NULL, PFS_RD);
2409c2da36feSEdward Tomasz Napierala 
2410060e4882SDoug Ambrisko 	/* /proc/scsi/... */
2411771709ebSDag-Erling Smørgrav 	dir = pfs_create_dir(root, "scsi", NULL, NULL, NULL, 0);
2412060e4882SDoug Ambrisko 	pfs_create_file(dir, "device_info", &linprocfs_doscsidevinfo,
2413771709ebSDag-Erling Smørgrav 	    NULL, NULL, NULL, PFS_RD);
2414060e4882SDoug Ambrisko 	pfs_create_file(dir, "scsi", &linprocfs_doscsiscsi,
2415771709ebSDag-Erling Smørgrav 	    NULL, NULL, NULL, PFS_RD);
2416236e97b2SAlexander Leidinger 
2417236e97b2SAlexander Leidinger 	/* /proc/sys/... */
2418d1fa346fSChuck Tuffli 	sys = pfs_create_dir(root, "sys", NULL, NULL, NULL, 0);
2419978ffef2SEdward Tomasz Napierala 
2420236e97b2SAlexander Leidinger 	/* /proc/sys/kernel/... */
2421d1fa346fSChuck Tuffli 	dir = pfs_create_dir(sys, "kernel", NULL, NULL, NULL, 0);
24225017af60SJung-uk Kim 	pfs_create_file(dir, "osrelease", &linprocfs_doosrelease,
2423771709ebSDag-Erling Smørgrav 	    NULL, NULL, NULL, PFS_RD);
24245017af60SJung-uk Kim 	pfs_create_file(dir, "ostype", &linprocfs_doostype,
2425771709ebSDag-Erling Smørgrav 	    NULL, NULL, NULL, PFS_RD);
24265017af60SJung-uk Kim 	pfs_create_file(dir, "version", &linprocfs_doosbuild,
2427771709ebSDag-Erling Smørgrav 	    NULL, NULL, NULL, PFS_RD);
2428978ffef2SEdward Tomasz Napierala 	pfs_create_file(dir, "msgmax", &linprocfs_domsgmax,
2429978ffef2SEdward Tomasz Napierala 	    NULL, NULL, NULL, PFS_RD);
2430e40fc50bSJung-uk Kim 	pfs_create_file(dir, "msgmni", &linprocfs_domsgmni,
2431771709ebSDag-Erling Smørgrav 	    NULL, NULL, NULL, PFS_RD);
2432978ffef2SEdward Tomasz Napierala 	pfs_create_file(dir, "msgmnb", &linprocfs_domsgmnb,
2433978ffef2SEdward Tomasz Napierala 	    NULL, NULL, NULL, PFS_RD);
24347135ca98SEdward Tomasz Napierala 	pfs_create_file(dir, "ngroups_max", &linprocfs_dongroups_max,
24357135ca98SEdward Tomasz Napierala 	    NULL, NULL, NULL, PFS_RD);
2436236e97b2SAlexander Leidinger 	pfs_create_file(dir, "pid_max", &linprocfs_dopid_max,
2437771709ebSDag-Erling Smørgrav 	    NULL, NULL, NULL, PFS_RD);
2438e40fc50bSJung-uk Kim 	pfs_create_file(dir, "sem", &linprocfs_dosem,
2439771709ebSDag-Erling Smørgrav 	    NULL, NULL, NULL, PFS_RD);
2440978ffef2SEdward Tomasz Napierala 	pfs_create_file(dir, "shmall", &linprocfs_doshmall,
2441978ffef2SEdward Tomasz Napierala 	    NULL, NULL, NULL, PFS_RD);
2442978ffef2SEdward Tomasz Napierala 	pfs_create_file(dir, "shmmax", &linprocfs_doshmmax,
2443978ffef2SEdward Tomasz Napierala 	    NULL, NULL, NULL, PFS_RD);
2444978ffef2SEdward Tomasz Napierala 	pfs_create_file(dir, "shmmni", &linprocfs_doshmmni,
2445978ffef2SEdward Tomasz Napierala 	    NULL, NULL, NULL, PFS_RD);
24467fcc9f7eSEdward Tomasz Napierala 	pfs_create_file(dir, "tainted", &linprocfs_dotainted,
24477fcc9f7eSEdward Tomasz Napierala 	    NULL, NULL, NULL, PFS_RD);
2448236e97b2SAlexander Leidinger 
24499ace8010SEitan Adler 	/* /proc/sys/kernel/random/... */
24509ace8010SEitan Adler 	dir = pfs_create_dir(dir, "random", NULL, NULL, NULL, 0);
24519ace8010SEitan Adler 	pfs_create_file(dir, "uuid", &linprocfs_douuid,
24529ace8010SEitan Adler 	    NULL, NULL, NULL, PFS_RD);
24530f2041a5SFernando Apesteguía 	pfs_create_file(dir, "boot_id", &linprocfs_doboot_id,
24540f2041a5SFernando Apesteguía 	    NULL, NULL, NULL, PFS_RD);
24559ace8010SEitan Adler 
2456d1fa346fSChuck Tuffli 	/* /proc/sys/vm/.... */
2457d1fa346fSChuck Tuffli 	dir = pfs_create_dir(sys, "vm", NULL, NULL, NULL, 0);
2458d1fa346fSChuck Tuffli 	pfs_create_file(dir, "min_free_kbytes", &linprocfs_dominfree,
2459d1fa346fSChuck Tuffli 	    NULL, NULL, NULL, PFS_RD);
24607e2a4511SDmitry Chagin 	pfs_create_file(dir, "max_map_count", &linprocfs_domax_map_cnt,
24617e2a4511SDmitry Chagin 	    NULL, NULL, NULL, PFS_RD);
2462d1fa346fSChuck Tuffli 
246325a04527SRicardo Branco 	/* /proc/sysvipc/... */
246425a04527SRicardo Branco 	dir = pfs_create_dir(root, "sysvipc", NULL, NULL, NULL, 0);
246525a04527SRicardo Branco 	pfs_create_file(dir, "msg", &linprocfs_dosysvipc_msg,
246625a04527SRicardo Branco 	    NULL, NULL, NULL, PFS_RD);
246725a04527SRicardo Branco 	pfs_create_file(dir, "sem", &linprocfs_dosysvipc_sem,
246825a04527SRicardo Branco 	    NULL, NULL, NULL, PFS_RD);
246925a04527SRicardo Branco 	pfs_create_file(dir, "shm", &linprocfs_dosysvipc_shm,
247025a04527SRicardo Branco 	    NULL, NULL, NULL, PFS_RD);
247125a04527SRicardo Branco 
247204d3f8e5SRicardo Branco 	/* /proc/sys/fs/... */
247304d3f8e5SRicardo Branco 	dir = pfs_create_dir(sys, "fs", NULL, NULL, NULL, 0);
247404d3f8e5SRicardo Branco 
247504d3f8e5SRicardo Branco 	/* /proc/sys/fs/mqueue/... */
247604d3f8e5SRicardo Branco 	dir = pfs_create_dir(dir, "mqueue", NULL, NULL, NULL, 0);
247704d3f8e5SRicardo Branco 	pfs_create_file(dir, "msg_default", &linprocfs_domqueue_msg_default,
247804d3f8e5SRicardo Branco 	    NULL, NULL, NULL, PFS_RD);
247904d3f8e5SRicardo Branco 	pfs_create_file(dir, "msgsize_default", &linprocfs_domqueue_msgsize_default,
248004d3f8e5SRicardo Branco 	    NULL, NULL, NULL, PFS_RD);
248104d3f8e5SRicardo Branco 	pfs_create_file(dir, "msg_max", &linprocfs_domqueue_msg_max,
248204d3f8e5SRicardo Branco 	    NULL, NULL, NULL, PFS_RD);
248304d3f8e5SRicardo Branco 	pfs_create_file(dir, "msgsize_max", &linprocfs_domqueue_msgsize_max,
248404d3f8e5SRicardo Branco 	    NULL, NULL, NULL, PFS_RD);
248504d3f8e5SRicardo Branco 	pfs_create_file(dir, "queues_max", &linprocfs_domqueue_queues_max,
248604d3f8e5SRicardo Branco 	    NULL, NULL, NULL, PFS_RD);
248704d3f8e5SRicardo Branco 
24881c0bfd6eSDag-Erling Smørgrav 	return (0);
24891c0bfd6eSDag-Erling Smørgrav }
24901c0bfd6eSDag-Erling Smørgrav 
24911c0bfd6eSDag-Erling Smørgrav /*
24921c0bfd6eSDag-Erling Smørgrav  * Destructor
24931c0bfd6eSDag-Erling Smørgrav  */
24941c0bfd6eSDag-Erling Smørgrav static int
24951c0bfd6eSDag-Erling Smørgrav linprocfs_uninit(PFS_INIT_ARGS)
24961c0bfd6eSDag-Erling Smørgrav {
24971c0bfd6eSDag-Erling Smørgrav 
24981c0bfd6eSDag-Erling Smørgrav 	/* nothing to do, pseudofs will GC */
24991c0bfd6eSDag-Erling Smørgrav 	return (0);
25001c0bfd6eSDag-Erling Smørgrav }
25011c0bfd6eSDag-Erling Smørgrav 
25020e5c6bd4SJamie Gritton PSEUDOFS(linprocfs, 1, VFCF_JAIL);
25036a1d1e0cSEd Maste #if defined(__aarch64__) || defined(__amd64__)
250467d39748SDmitry Chagin MODULE_DEPEND(linprocfs, linux_common, 1, 1, 1);
250567d39748SDmitry Chagin #else
2506f08adc10SDag-Erling Smørgrav MODULE_DEPEND(linprocfs, linux, 1, 1, 1);
250767d39748SDmitry Chagin #endif
2508f08adc10SDag-Erling Smørgrav MODULE_DEPEND(linprocfs, procfs, 1, 1, 1);
25096e612ecaSJung-uk Kim MODULE_DEPEND(linprocfs, sysvmsg, 1, 1, 1);
25106e612ecaSJung-uk Kim MODULE_DEPEND(linprocfs, sysvsem, 1, 1, 1);
2511978ffef2SEdward Tomasz Napierala MODULE_DEPEND(linprocfs, sysvshm, 1, 1, 1);
2512