Drop main() prototype. Syncs with NetBSD-8
[minix.git] / minix / servers / mib / kern.c
blob465a7ab395f26526d19bf69365a3ea1b387e4f95
1 /* MIB service - kern.c - implementation of the CTL_KERN subtree */
3 #include "mib.h"
5 #include <sys/svrctl.h>
6 #include <minix/sysinfo.h>
7 #include <machine/partition.h>
9 #include "servers/vfs/const.h"
10 #include "servers/vfs/dmap.h"
12 static char hostname[MAXHOSTNAMELEN], domainname[MAXHOSTNAMELEN];
15 * Verification for CTL_KERN KERN_SECURELVL.
17 static int
18 mib_kern_securelvl(struct mib_call * call __unused, struct mib_node * node,
19 void * ptr, size_t size __unused)
21 int v;
23 memcpy(&v, ptr, sizeof(v));
26 * Only ever allow the security level to be increased. This is a mock
27 * implementation. TODO: implement actual support for security levels.
29 return (v >= node->node_int);
33 * Implementation of CTL_KERN KERN_CLOCKRATE.
35 static ssize_t
36 mib_kern_clockrate(struct mib_call * call __unused,
37 struct mib_node * node __unused, struct mib_oldp * oldp,
38 struct mib_newp * newp __unused)
40 struct clockinfo clockinfo;
42 memset(&clockinfo, 0, sizeof(clockinfo));
44 clockinfo.hz = sys_hz();
45 clockinfo.tick = 1000000 / clockinfo.hz;
46 clockinfo.profhz = clockinfo.hz;
47 clockinfo.stathz = clockinfo.hz;
50 * Number of microseconds that can be corrected per clock tick through
51 * adjtime(2). The kernel allows correction of one clock tick per
52 * clock tick, which means it should be the same as .tick.. I think.
53 * TODO: get this from the kernel itself.
55 clockinfo.tickadj = clockinfo.tick;
57 return mib_copyout(oldp, 0, &clockinfo, sizeof(clockinfo));
61 * Implementation of CTL_KERN KERN_PROFILING.
63 static ssize_t
64 mib_kern_profiling(struct mib_call * call __unused,
65 struct mib_node * node __unused, struct mib_oldp * oldp __unused,
66 struct mib_newp * newp __unused)
69 /* As per sysctl(7). We have a different profiling API. */
70 return EOPNOTSUPP;
74 * Implementation of CTL_KERN KERN_HARDCLOCK_TICKS.
76 static ssize_t
77 mib_kern_hardclock_ticks(struct mib_call * call __unused,
78 struct mib_node * node __unused, struct mib_oldp * oldp,
79 struct mib_newp * newp __unused)
81 int uptime;
84 * The number of hardclock (hardware clock driver) ticks is what we
85 * call the number of monotonic clock ticks AKA the uptime clock ticks.
87 uptime = (int)getticks();
89 return mib_copyout(oldp, 0, &uptime, sizeof(uptime));
93 * Implementation of CTL_KERN KERN_ROOT_DEVICE.
95 static ssize_t
96 mib_kern_root_device(struct mib_call * call __unused,
97 struct mib_node * node __unused, struct mib_oldp * oldp,
98 struct mib_newp * newp __unused)
100 char name[PATH_MAX];
101 struct sysgetenv sysgetenv;
103 sysgetenv.key = __UNCONST("rootdevname");
104 sysgetenv.keylen = strlen(sysgetenv.key) + 1;
105 sysgetenv.val = name;
106 sysgetenv.vallen = sizeof(name);
108 if (svrctl(PMGETPARAM, &sysgetenv) != 0)
109 return EINVAL;
111 name[MIN(sysgetenv.vallen, sizeof(name) - 1)] = '\0';
113 return mib_copyout(oldp, 0, name, strlen(name) + 1);
117 * Implementation of CTL_KERN KERN_CCPU.
119 static ssize_t
120 mib_kern_ccpu(struct mib_call * call __unused,
121 struct mib_node * node __unused, struct mib_oldp * oldp,
122 struct mib_newp * newp __unused)
124 int ccpu;
126 ccpu = (int)cpuavg_getccpu();
128 return mib_copyout(oldp, 0, &ccpu, sizeof(ccpu));
132 * Implementation of CTL_KERN KERN_CP_TIME.
134 static ssize_t
135 mib_kern_cp_time(struct mib_call * call, struct mib_node * node __unused,
136 struct mib_oldp * oldp, struct mib_newp * newp __unused)
138 uint64_t ticks[MINIX_CPUSTATES], sum[MINIX_CPUSTATES];
139 unsigned int cpu;
140 int i, r, do_sum;
143 * If a subnode is provided, it identifies the CPU number for which to
144 * return information. If no subnode is provided, but a size is given
145 * that allows returning information for all CPUs, return information
146 * for all of them in an array. If no such size is given either,
147 * return a summation of all CPU statistics. Both we and the kernel
148 * are considering the number of configured CPUs (hw.ncpu).
150 if (call->call_namelen > 1)
151 return EINVAL;
153 if (call->call_namelen == 1) {
154 /* Do not bother saving on this call if oldp is NULL. */
155 if ((r = sys_getcputicks(ticks, call->call_name[0])) != OK)
156 return r;
158 return mib_copyout(oldp, 0, ticks, sizeof(ticks));
161 if (oldp == NULL)
162 return sizeof(ticks); /* implying a summation request */
164 do_sum = (mib_getoldlen(oldp) == sizeof(ticks));
166 if (do_sum)
167 memset(&sum, 0, sizeof(sum));
169 for (cpu = 0; cpu < CONFIG_MAX_CPUS; cpu++) {
170 if ((r = sys_getcputicks(ticks, cpu)) != OK)
171 return r;
173 if (do_sum) {
174 for (i = 0; i < MINIX_CPUSTATES; i++)
175 sum[i] += ticks[i];
176 } else {
177 if ((r = mib_copyout(oldp, cpu * sizeof(ticks), ticks,
178 sizeof(ticks))) < 0)
179 return r;
183 if (do_sum)
184 return mib_copyout(oldp, 0, sum, sizeof(sum));
185 else
186 return cpu * sizeof(ticks);
190 * Implementation of CTL_KERN KERN_CONSDEV.
192 static ssize_t
193 mib_kern_consdev(struct mib_call * call __unused,
194 struct mib_node * node __unused, struct mib_oldp * oldp,
195 struct mib_newp * newp __unused)
197 dev_t dev;
199 dev = makedev(TTY_MAJOR, CONS_MINOR);
201 /* No support for legacy 32-bit requests. */
202 return mib_copyout(oldp, 0, &dev, sizeof(dev));
206 * Verification for CTL_KERN KERN_FORKFSLEEP.
208 static int
209 mib_kern_forkfsleep(struct mib_call * call __unused,
210 struct mib_node * node __unused, void * ptr, size_t size __unused)
212 int v;
214 memcpy(&v, ptr, sizeof(v));
216 return (v >= 0 && v <= MAXSLP * 1000); /* rules from NetBSD */
220 * Implementation of CTL_KERN KERN_DRIVERS.
222 static ssize_t
223 mib_kern_drivers(struct mib_call * call __unused,
224 struct mib_node * node __unused, struct mib_oldp * oldp,
225 struct mib_newp * newp __unused)
227 struct dmap dmap_tab[NR_DEVICES];
228 struct kinfo_drivers drivers[NR_DEVICES + 1];
229 unsigned int count;
230 devmajor_t maj;
233 * On MINIX3, we list only drivers that are actually running.
236 if (getsysinfo(VFS_PROC_NR, SI_DMAP_TAB, dmap_tab,
237 sizeof(dmap_tab)) != OK)
238 return EINVAL;
240 count = 0;
243 * Compatibility hack. NetBSD userland expects that the name of the
244 * PTY driver is "pts". Add an extra entry for this purpose if needed.
246 if (dmap_tab[PTY_MAJOR].dmap_driver != NONE &&
247 strcmp(dmap_tab[PTY_MAJOR].dmap_label, "pts")) {
248 if (mib_inrange(oldp, 0)) {
249 memset(&drivers[0], 0, sizeof(drivers[0]));
250 strlcpy(drivers[count].d_name, "pts",
251 sizeof(drivers[0].d_name));
252 drivers[count].d_bmajor = -1;
253 drivers[count].d_cmajor = PTY_MAJOR;
255 count++;
258 for (maj = 0; maj < NR_DEVICES; maj++) {
259 if (dmap_tab[maj].dmap_driver == NONE)
260 continue;
262 if (mib_inrange(oldp, sizeof(drivers[0]) * count)) {
263 memset(&drivers[count], 0, sizeof(drivers[0]));
265 strlcpy(drivers[count].d_name,
266 dmap_tab[maj].dmap_label,
267 sizeof(drivers[0].d_name));
270 * We do not know whether the device is a block device,
271 * character device, or both. In any case, a driver
272 * has only one major number.
274 drivers[count].d_bmajor = maj;
275 drivers[count].d_cmajor = maj;
277 count++;
280 return mib_copyout(oldp, 0, drivers, count * sizeof(drivers[0]));
284 * Implementation of CTL_KERN KERN_BOOTTIME.
286 static ssize_t
287 mib_kern_boottime(struct mib_call * call __unused,
288 struct mib_node * node __unused, struct mib_oldp * oldp,
289 struct mib_newp * newp __unused)
291 struct timeval tv;
293 memset(&tv, 0, sizeof(tv));
295 if (getuptime(NULL, NULL, &tv.tv_sec) != OK)
296 return EINVAL;
298 return mib_copyout(oldp, 0, &tv, sizeof(tv));
302 * Mock implementation of CTL_KERN KERN_SYSVIPC KERN_SYSVIPC_INFO. Normally,
303 * the IPC service overrides the entire "kern.ipc" subtree. Therefore, this
304 * function will only ever be called when the IPC service is *not* running.
306 static ssize_t
307 mib_kern_ipc_info(struct mib_call * call, struct mib_node * node __unused,
308 struct mib_oldp * oldp __unused, struct mib_newp * newp __unused)
311 /* The caller must always specify the resouce type (sem/shm/msg). */
312 if (call->call_namelen != 1)
313 return EINVAL;
315 return EOPNOTSUPP;
318 /* The CTL_KERN KERN_SYSVIPC nodes, when not overridden by the IPC service. */
319 static struct mib_node mib_kern_ipc_table[] = {
320 /* 1*/ [KERN_SYSVIPC_INFO] = MIB_FUNC(_P | _RO | CTLTYPE_NODE, 0,
321 mib_kern_ipc_info, "sysvipc_info",
322 "System V style IPC information"),
323 /* 2*/ [KERN_SYSVIPC_MSG] = MIB_INT(_P | _RO, 0, "sysvmsg", "System V "
324 "style message support available"),
325 /* 3*/ [KERN_SYSVIPC_SEM] = MIB_INT(_P | _RO, 0, "sysvsem", "System V "
326 "style semaphore support available"),
327 /* 4*/ [KERN_SYSVIPC_SHM] = MIB_INT(_P | _RO, 0, "sysvshm", "System V "
328 "style shared memory support available"),
331 /* The CTL_KERN nodes. */
332 static struct mib_node mib_kern_table[] = {
333 /* 1*/ [KERN_OSTYPE] = MIB_STRING(_P | _RO, OS_NAME, "ostype",
334 "Operating system type"),
335 /* 2*/ [KERN_OSRELEASE] = MIB_STRING(_P | _RO, OS_RELEASE, "osrelease",
336 "Operating system release"),
337 /* 3*/ [KERN_OSREV] = MIB_INT(_P | _RO , OS_REV, "osrevision",
338 "Operating system revision"),
339 /* 4*/ [KERN_VERSION] = MIB_STRING(_P | _RO, OS_VERSION, "version",
340 "Kernel version"),
341 /* 5*/ [KERN_MAXVNODES] = MIB_INT(_P | _RO, NR_VNODES, "maxvnodes",
342 "Maximum number of vnodes"),
343 /* 6*/ [KERN_MAXPROC] = MIB_INT(_P | _RO, NR_PROCS, "maxproc",
344 "Maximum number of simultaneous "
345 "processes"),
346 /* 7*/ [KERN_MAXFILES] = MIB_INT(_P | _RO, NR_VNODES, "maxfiles",
347 "Maximum number of open files"),
348 /* 8*/ [KERN_ARGMAX] = MIB_INT(_P | _RO, ARG_MAX, "argmax",
349 "Maximum number of bytes of arguments to "
350 "execve(2)"),
351 /* 9*/ [KERN_SECURELVL] = MIB_INTV(_P | _RW, -1, mib_kern_securelvl,
352 "securelevel", "System security level"),
353 /*10*/ [KERN_HOSTNAME] = MIB_STRING(_P | _RW, hostname, "hostname",
354 "System hostname"),
355 /*11*/ [KERN_HOSTID] = MIB_INT(_P | _RW | CTLFLAG_HEX, 0, "hostid",
356 "System host ID number"),
357 /*12*/ [KERN_CLOCKRATE] = MIB_FUNC(_P | _RO | CTLTYPE_STRUCT,
358 sizeof(struct clockinfo),
359 mib_kern_clockrate, "clockrate",
360 "Kernel clock rates"),
361 /*13*/ /* KERN_VNODE: not yet implemented */
362 /*14*/ /* KERN_PROC: not yet implemented */
363 /*15*/ /* KERN_FILE: not yet implemented */
364 /*16*/ [KERN_PROF] = MIB_FUNC(_P | _RO | CTLTYPE_NODE, 0,
365 mib_kern_profiling, "profiling",
366 "Profiling information (not available)"),
367 /*17*/ [KERN_POSIX1] = MIB_INT(_P | _RO, _POSIX_VERSION,
368 "posix1version", "Version of ISO/IEC 9945 "
369 "(POSIX 1003.1) with which the operating "
370 "system attempts to comply"),
371 /*18*/ [KERN_NGROUPS] = MIB_INT(_P | _RO, NGROUPS_MAX, "ngroups",
372 "Maximum number of supplemental groups"),
373 /*19*/ [KERN_JOB_CONTROL] = MIB_INT(_P | _RO, 0, "job_control",
374 "Whether job control is available"),
375 /*20*/ [KERN_SAVED_IDS] = MIB_INT(_P | _RO, 0, "saved_ids",
376 "Whether POSIX saved set-group/user ID is "
377 "available"),
378 /*21*/ /* KERN_OBOOTTIME: obsolete */
379 /*22*/ [KERN_DOMAINNAME] = MIB_STRING(_P | _RW, domainname,
380 "domainname", "YP domain name"),
381 /*23*/ [KERN_MAXPARTITIONS] = MIB_INT(_P | _RO, NR_PARTITIONS,
382 "maxpartitions", "Maximum number of "
383 "partitions allowed per disk"),
384 /*24*/ /* KERN_RAWPARTITION: incompatible with our device node scheme */
385 /*25*/ /* KERN_NTPTIME: not yet supported */
386 /*26*/ /* KERN_TIMEX: not yet supported */
387 /*27*/ /* KERN_AUTONICETIME: not yet supported */
388 /*28*/ /* KERN_AUTONICEVAL: not yet supported */
389 /*29*/ [KERN_RTC_OFFSET] = MIB_INT(_P | _RW, 0, "rtc_offset", "Offset "
390 "of real time clock from UTC in minutes"),
391 /*30*/ [KERN_ROOT_DEVICE] = MIB_FUNC(_P | _RO | CTLTYPE_STRING, 0,
392 mib_kern_root_device, "root_device",
393 "Name of the root device"),
394 /*31*/ [KERN_MSGBUFSIZE] = MIB_INT(_P | _RO, DIAG_BUFSIZE, "msgbufsize",
395 "Size of the kernel message buffer"),
396 /*32*/ [KERN_FSYNC] = MIB_INT(_P | _RO, 1, "fsync", "Whether the "
397 "POSIX 1003.1b File Synchronization Option"
398 " is available on this system"),
399 /*33*/ /* KERN_OLDSYSVMSG: obsolete */
400 /*34*/ /* KERN_OLDSYSVSEM: obsolete */
401 /*35*/ /* KERN_OLDSYSVSHM: obsolete */
402 /*36*/ /* KERN_OLDSHORTCORENAME: obsolete */
403 /*37*/ [KERN_SYNCHRONIZED_IO] = MIB_INT(_P | _RO, 0, "synchronized_io",
404 "Whether the POSIX 1003.1b Synchronized "
405 "I/O Option is available on this system"),
406 /*38*/ [KERN_IOV_MAX] = MIB_INT(_P | _RO, IOV_MAX, "iov_max",
407 "Maximum number of iovec structures per "
408 "process"),
409 /*39*/ /* KERN_MBUF: not yet supported */
410 /*40*/ [KERN_MAPPED_FILES] = MIB_INT(_P | _RO, 1, "mapped_files",
411 "Whether the POSIX 1003.1b Memory Mapped "
412 "Files Option is available on this "
413 "system"),
414 /*41*/ [KERN_MEMLOCK] = MIB_INT(_P | _RO, 0, "memlock", "Whether "
415 "the POSIX 1003.1b Process Memory Locking "
416 "Option is available on this system"),
417 /*42*/ [KERN_MEMLOCK_RANGE] = MIB_INT(_P | _RO, 0, "memlock_range",
418 "Whether the POSIX 1003.1b Range Memory "
419 "Locking Option is available on this "
420 "system"),
421 /*43*/ [KERN_MEMORY_PROTECTION]= MIB_INT(_P | _RO, 0, "memory_protection",
422 "Whether the POSIX 1003.1b Memory "
423 "Protection Option is available on this "
424 "system"),
425 /*44*/ /* KERN_LOGIN_NAME_MAX: not yet supported */
426 /*45*/ /* KERN_DEFCORENAME: obsolete */
427 /*46*/ /* KERN_LOGSIGEXIT: not yet supported */
428 /*47*/ [KERN_PROC2] = MIB_FUNC(_P | _RO | CTLTYPE_NODE, 0,
429 mib_kern_proc2, "proc2",
430 "Machine-independent process information"),
431 /*48*/ [KERN_PROC_ARGS] = MIB_FUNC(_P | _RO | CTLTYPE_NODE, 0,
432 mib_kern_proc_args, "proc_args",
433 "Process argument information"),
434 /*49*/ [KERN_FSCALE] = MIB_INT(_P | _RO, FSCALE, "fscale",
435 "Kernel fixed-point scale factor"),
436 /*50*/ [KERN_CCPU] = MIB_FUNC(_P | _RO | CTLTYPE_INT, sizeof(int),
437 mib_kern_ccpu, "ccpu",
438 "Scheduler exponential decay value"),
439 /*51*/ [KERN_CP_TIME] = MIB_FUNC(_P | _RO | CTLTYPE_NODE, 0,
440 mib_kern_cp_time, "cp_time", "Clock ticks "
441 "spent in different CPU states"),
442 /*52*/ /* KERN_OLDSYSVIPC_INFO: obsolete */
443 /*53*/ /* KERN_MSGBUF: not yet supported */
444 /*54*/ [KERN_CONSDEV] = MIB_FUNC(_P | _RO | CTLTYPE_STRUCT,
445 sizeof(dev_t), mib_kern_consdev, "consdev",
446 "Console device"),
447 /*55*/ [KERN_MAXPTYS] = MIB_INT(_P | _RO, NR_PTYS, "maxptys",
448 "Maximum number of pseudo-ttys"),
449 /*56*/ /* KERN_PIPE: not yet supported */
450 /*57*/ [KERN_MAXPHYS] = MIB_INT(_P | _RO, 4*1024*1024, "maxphys",
451 "Maximum raw I/O transfer size"),
452 /* 4MB is the upper limit for AHCI */
453 /*58*/ /* KERN_SBMAX: not yet supported */
454 /*59*/ /* KERN_TKSTAT: not yet supported */
455 /*60*/ [KERN_MONOTONIC_CLOCK] = MIB_INT(_P | _RO, _POSIX_MONOTONIC_CLOCK,
456 "monotonic_clock",
457 "Implementation version of the POSIX "
458 "1003.1b Monotonic Clock Option"),
459 /*61*/ /* KERN_URND: not yet supported */
460 /*62*/ /* KERN_LABELSECTOR: not yet supported */
461 /*63*/ /* KERN_LABELOFFSET: not yet supported */
462 /*64*/ [KERN_LWP] = MIB_FUNC(_P | _RO | CTLTYPE_NODE, 0,
463 mib_kern_lwp, "lwp",
464 "System-wide LWP information"),
465 /*65*/ [KERN_FORKFSLEEP] = MIB_INTV(_P | _RW, 0, mib_kern_forkfsleep,
466 "forkfsleep", "Milliseconds to sleep on "
467 "fork failure due to process limits"),
468 /*66*/ /* KERN_POSIX_THREADS: not yet supported */
469 /*67*/ /* KERN_POSIX_SEMAPHORES: not yet supported */
470 /*68*/ /* KERN_POSIX_BARRIERS: not yet supported */
471 /*69*/ /* KERN_POSIX_TIMERS: not yet supported */
472 /*70*/ /* KERN_POSIX_SPIN_LOCKS: not yet supported */
473 /*71*/ /* KERN_POSIX_READER_WRITER_LOCKS: not yet supported */
474 /*72*/ [KERN_DUMP_ON_PANIC] = MIB_INT(_P | _RO, 0, "dump_on_panic",
475 "Perform a crash dump on system panic"),
476 /*73*/ /* KERN_SOMAXKVA: not yet supported */
477 /*74*/ /* KERN_ROOT_PARTITION: incompatible with our device node scheme */
478 /*75*/ [KERN_DRIVERS] = MIB_FUNC(_P | _RO | CTLTYPE_STRUCT, 0,
479 mib_kern_drivers, "drivers",
480 "List of all drivers with block and "
481 "character device numbers"),
482 /*76*/ /* KERN_BUF: not yet supported */
483 /*77*/ /* KERN_FILE2: not yet supported */
484 /*78*/ /* KERN_VERIEXEC: not yet supported */
485 /*79*/ /* KERN_CP_ID: not yet supported */
486 /*80*/ [KERN_HARDCLOCK_TICKS] = MIB_FUNC(_P | _RO | CTLFLAG_UNSIGNED |
487 CTLTYPE_INT, sizeof(int),
488 mib_kern_hardclock_ticks,
489 "hardclock_ticks",
490 "Number of hardclock ticks"),
491 /*81*/ /* KERN_ARND: not yet supported */
492 /*82*/ [KERN_SYSVIPC] = MIB_NODE(_P | _RO, mib_kern_ipc_table, "ipc",
493 "SysV IPC options"),
494 /*83*/ [KERN_BOOTTIME] = MIB_FUNC(_P | _RO | CTLTYPE_STRUCT,
495 sizeof(struct timeval), mib_kern_boottime,
496 "boottime", "System boot time"),
497 /*84*/ /* KERN_EVCNT: not yet supported */
501 * Initialize the CTL_KERN subtree.
503 void
504 mib_kern_init(struct mib_node * node)
507 MIB_INIT_ENODE(node, mib_kern_table);