1/*	$NetBSD: init_sysctl_base.c,v 1.9 2023/12/20 20:35:37 andvar Exp $ */
2
3/*-
4 * Copyright (c) 2003, 2007, 2008, 2009 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Andrew Brown, and by Andrew Doran.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 *    notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 *    notice, this list of conditions and the following disclaimer in the
17 *    documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32#include <sys/cdefs.h>
33__KERNEL_RCSID(0, "$NetBSD: init_sysctl_base.c,v 1.9 2023/12/20 20:35:37 andvar Exp $");
34
35#include <sys/types.h>
36#include <sys/param.h>
37#include <sys/sysctl.h>
38#include <sys/proc.h>
39#include <sys/cpu.h>
40#include <sys/kernel.h>
41#include <sys/disklabel.h>
42
43static int sysctl_setlen(SYSCTLFN_PROTO);
44
45/*
46 * sets up the base nodes...
47 */
48void
49sysctl_basenode_init(void)
50{
51
52	sysctl_createv(NULL, 0, NULL, NULL,
53		       CTLFLAG_PERMANENT,
54		       CTLTYPE_NODE, "kern",
55		       SYSCTL_DESCR("High kernel"),
56		       NULL, 0, NULL, 0,
57		       CTL_KERN, CTL_EOL);
58	sysctl_createv(NULL, 0, NULL, NULL,
59		       CTLFLAG_PERMANENT,
60		       CTLTYPE_NODE, "vm",
61		       SYSCTL_DESCR("Virtual memory"),
62		       NULL, 0, NULL, 0,
63		       CTL_VM, CTL_EOL);
64	sysctl_createv(NULL, 0, NULL, NULL,
65		       CTLFLAG_PERMANENT,
66		       CTLTYPE_NODE, "vfs",
67		       SYSCTL_DESCR("Filesystem"),
68		       NULL, 0, NULL, 0,
69		       CTL_VFS, CTL_EOL);
70	sysctl_createv(NULL, 0, NULL, NULL,
71		       CTLFLAG_PERMANENT,
72		       CTLTYPE_NODE, "net",
73		       SYSCTL_DESCR("Networking"),
74		       NULL, 0, NULL, 0,
75		       CTL_NET, CTL_EOL);
76	sysctl_createv(NULL, 0, NULL, NULL,
77		       CTLFLAG_PERMANENT,
78		       CTLTYPE_NODE, "debug",
79		       SYSCTL_DESCR("Debugging"),
80		       NULL, 0, NULL, 0,
81		       CTL_DEBUG, CTL_EOL);
82	sysctl_createv(NULL, 0, NULL, NULL,
83		       CTLFLAG_PERMANENT,
84		       CTLTYPE_NODE, "hw",
85		       SYSCTL_DESCR("Generic CPU, I/O"),
86		       NULL, 0, NULL, 0,
87		       CTL_HW, CTL_EOL);
88	sysctl_createv(NULL, 0, NULL, NULL,
89		       CTLFLAG_PERMANENT,
90		       CTLTYPE_NODE, "machdep",
91		       SYSCTL_DESCR("Machine dependent"),
92		       NULL, 0, NULL, 0,
93		       CTL_MACHDEP, CTL_EOL);
94	/*
95	 * this node is inserted so that the sysctl nodes in libc can
96	 * operate.
97	 */
98	sysctl_createv(NULL, 0, NULL, NULL,
99		       CTLFLAG_PERMANENT,
100		       CTLTYPE_NODE, "user",
101		       SYSCTL_DESCR("User-level"),
102		       NULL, 0, NULL, 0,
103		       CTL_USER, CTL_EOL);
104	sysctl_createv(NULL, 0, NULL, NULL,
105		       CTLFLAG_PERMANENT,
106		       CTLTYPE_NODE, "ddb",
107		       SYSCTL_DESCR("In-kernel debugger"),
108		       NULL, 0, NULL, 0,
109		       CTL_DDB, CTL_EOL);
110	sysctl_createv(NULL, 0, NULL, NULL,
111		       CTLFLAG_PERMANENT,
112		       CTLTYPE_NODE, "proc",
113		       SYSCTL_DESCR("Per-process"),
114		       NULL, 0, NULL, 0,
115		       CTL_PROC, CTL_EOL);
116	sysctl_createv(NULL, 0, NULL, NULL,
117		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
118		       CTLTYPE_NODE, "vendor",
119		       SYSCTL_DESCR("Vendor specific"),
120		       NULL, 0, NULL, 0,
121		       CTL_VENDOR, CTL_EOL);
122	sysctl_createv(NULL, 0, NULL, NULL,
123		       CTLFLAG_PERMANENT,
124		       CTLTYPE_NODE, "emul",
125		       SYSCTL_DESCR("Emulation settings"),
126		       NULL, 0, NULL, 0,
127		       CTL_EMUL, CTL_EOL);
128	sysctl_createv(NULL, 0, NULL, NULL,
129		       CTLFLAG_PERMANENT,
130		       CTLTYPE_NODE, "security",
131		       SYSCTL_DESCR("Security"),
132		       NULL, 0, NULL, 0,
133		       CTL_SECURITY, CTL_EOL);
134}
135
136/*
137 * now add some nodes which both rump kernel and standard
138 * NetBSD both need, as rump cannot use sys/kern/init_sysctl.c
139 */
140SYSCTL_SETUP(sysctl_kernbase_setup, "sysctl kern subtree base setup")
141{
142
143	sysctl_createv(clog, 0, NULL, NULL,
144		       CTLFLAG_PERMANENT,
145		       CTLTYPE_STRING, "ostype",
146		       SYSCTL_DESCR("Operating system type"),
147		       NULL, 0, __UNCONST(&ostype), 0,
148		       CTL_KERN, KERN_OSTYPE, CTL_EOL);
149	sysctl_createv(clog, 0, NULL, NULL,
150		       CTLFLAG_PERMANENT,
151		       CTLTYPE_STRING, "osrelease",
152		       SYSCTL_DESCR("Operating system release"),
153		       NULL, 0, __UNCONST(&osrelease), 0,
154		       CTL_KERN, KERN_OSRELEASE, CTL_EOL);
155	sysctl_createv(clog, 0, NULL, NULL,
156		       CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
157		       CTLTYPE_INT, "osrevision",
158		       SYSCTL_DESCR("Operating system revision"),
159		       NULL, __NetBSD_Version__, NULL, 0,
160		       CTL_KERN, KERN_OSREV, CTL_EOL);
161	sysctl_createv(clog, 0, NULL, NULL,
162		       CTLFLAG_PERMANENT,
163		       CTLTYPE_STRING, "version",
164		       SYSCTL_DESCR("Kernel version"),
165		       NULL, 0, __UNCONST(&version), 0,
166		       CTL_KERN, KERN_VERSION, CTL_EOL);
167	sysctl_createv(clog, 0, NULL, NULL,
168		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
169		       CTLTYPE_STRING, "hostname",
170		       SYSCTL_DESCR("System hostname"),
171		       sysctl_setlen, 0, hostname, MAXHOSTNAMELEN,
172		       CTL_KERN, KERN_HOSTNAME, CTL_EOL);
173	sysctl_createv(clog, 0, NULL, NULL,
174		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
175		       CTLTYPE_STRING, "domainname",
176		       SYSCTL_DESCR("YP domain name"),
177		       sysctl_setlen, 0, domainname, MAXHOSTNAMELEN,
178		       CTL_KERN, KERN_DOMAINNAME, CTL_EOL);
179	sysctl_createv(clog, 0, NULL, NULL,
180		       CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
181		       CTLTYPE_INT, "rawpartition",
182		       SYSCTL_DESCR("Raw partition of a disk"),
183		       NULL, RAW_PART, NULL, 0,
184		       CTL_KERN, KERN_RAWPARTITION, CTL_EOL);
185}
186
187static int
188sysctl_hw_machine_arch(SYSCTLFN_ARGS)
189{
190	struct sysctlnode node = *rnode;
191#ifndef PROC_MACHINE_ARCH
192#define PROC_MACHINE_ARCH(P)	machine_arch
193#endif
194
195	node.sysctl_data = PROC_MACHINE_ARCH(l->l_proc);
196	node.sysctl_size = strlen(node.sysctl_data) + 1;
197	return sysctl_lookup(SYSCTLFN_CALL(&node));
198}
199
200SYSCTL_SETUP(sysctl_hwbase_setup, "sysctl hw subtree base setup")
201{
202	u_int u;
203	u_quad_t q;
204	const char *model = cpu_getmodel();
205
206	sysctl_createv(clog, 0, NULL, NULL,
207		       CTLFLAG_PERMANENT,
208		       CTLTYPE_STRING, "model",
209		       SYSCTL_DESCR("Machine model"),
210		       NULL, 0, __UNCONST(model), 0,
211		       CTL_HW, HW_MODEL, CTL_EOL);
212	sysctl_createv(clog, 0, NULL, NULL,
213		       CTLFLAG_PERMANENT,
214		       CTLTYPE_STRING, "machine",
215		       SYSCTL_DESCR("Machine class"),
216		       NULL, 0, machine, 0,
217		       CTL_HW, HW_MACHINE, CTL_EOL);
218	sysctl_createv(clog, 0, NULL, NULL,
219		       CTLFLAG_PERMANENT|CTLFLAG_READONLY,
220		       CTLTYPE_STRING, "machine_arch",
221		       SYSCTL_DESCR("Machine CPU class"),
222		       sysctl_hw_machine_arch, 0, NULL, 0,
223		       CTL_HW, HW_MACHINE_ARCH, CTL_EOL);
224	sysctl_createv(clog, 0, NULL, NULL,
225		       CTLFLAG_PERMANENT,
226		       CTLTYPE_INT, "ncpu",
227		       SYSCTL_DESCR("Number of CPUs configured"),
228		       NULL, 0, &ncpu, 0,
229		       CTL_HW, HW_NCPU, CTL_EOL);
230	sysctl_createv(clog, 0, NULL, NULL,
231		       CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
232		       CTLTYPE_INT, "byteorder",
233		       SYSCTL_DESCR("System byte order"),
234		       NULL, BYTE_ORDER, NULL, 0,
235		       CTL_HW, HW_BYTEORDER, CTL_EOL);
236	u = ((u_int)physmem > (UINT_MAX / PAGE_SIZE)) ?
237		UINT_MAX : physmem * PAGE_SIZE;
238	sysctl_createv(clog, 0, NULL, NULL,
239		       CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
240		       CTLTYPE_INT, "physmem",
241		       SYSCTL_DESCR("Bytes of physical memory"),
242		       NULL, u, NULL, 0,
243		       CTL_HW, HW_PHYSMEM, CTL_EOL);
244	sysctl_createv(clog, 0, NULL, NULL,
245		       CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
246		       CTLTYPE_INT, "pagesize",
247		       SYSCTL_DESCR("Software page size"),
248		       NULL, PAGE_SIZE, NULL, 0,
249		       CTL_HW, HW_PAGESIZE, CTL_EOL);
250	sysctl_createv(clog, 0, NULL, NULL,
251		       CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
252		       CTLTYPE_INT, "alignbytes",
253		       SYSCTL_DESCR("Alignment constraint for all possible "
254				    "data types"),
255		       NULL, ALIGNBYTES, NULL, 0,
256		       CTL_HW, HW_ALIGNBYTES, CTL_EOL);
257	q = (u_quad_t)physmem * PAGE_SIZE;
258	sysctl_createv(clog, 0, NULL, NULL,
259		       CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
260		       CTLTYPE_QUAD, "physmem64",
261		       SYSCTL_DESCR("Bytes of physical memory"),
262		       NULL, q, NULL, 0,
263		       CTL_HW, HW_PHYSMEM64, CTL_EOL);
264	sysctl_createv(clog, 0, NULL, NULL,
265		       CTLFLAG_PERMANENT,
266		       CTLTYPE_INT, "ncpuonline",
267		       SYSCTL_DESCR("Number of CPUs online"),
268		       NULL, 0, &ncpuonline, 0,
269		       CTL_HW, HW_NCPUONLINE, CTL_EOL);
270}
271
272/*
273 * sysctl helper function for kern.hostname and kern.domainname.
274 * resets the relevant recorded length when the underlying name is
275 * changed.
276 */
277static int
278sysctl_setlen(SYSCTLFN_ARGS)
279{
280	int error;
281
282	error = sysctl_lookup(SYSCTLFN_CALL(rnode));
283	if (error || newp == NULL)
284		return (error);
285
286	switch (rnode->sysctl_num) {
287	case KERN_HOSTNAME:
288		hostnamelen = strlen((const char*)rnode->sysctl_data);
289		break;
290	case KERN_DOMAINNAME:
291		domainnamelen = strlen((const char*)rnode->sysctl_data);
292		break;
293	}
294
295	return (0);
296}
297