The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/kern/init_sysctl.c

Version: -  FREEBSD  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-2  -  FREEBSD-11-1  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-4  -  FREEBSD-10-3  -  FREEBSD-10-2  -  FREEBSD-10-1  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-3  -  FREEBSD-9-2  -  FREEBSD-9-1  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-4  -  FREEBSD-8-3  -  FREEBSD-8-2  -  FREEBSD-8-1  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-4  -  FREEBSD-7-3  -  FREEBSD-7-2  -  FREEBSD-7-1  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-4  -  FREEBSD-6-3  -  FREEBSD-6-2  -  FREEBSD-6-1  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-5  -  FREEBSD-5-4  -  FREEBSD-5-3  -  FREEBSD-5-2  -  FREEBSD-5-1  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  linux-2.6  -  linux-2.4.22  -  MK83  -  MK84  -  PLAN9  -  DFBSD  -  NETBSD  -  NETBSD5  -  NETBSD4  -  NETBSD3  -  NETBSD20  -  OPENBSD  -  xnu-517  -  xnu-792  -  xnu-792.6.70  -  xnu-1228  -  xnu-1456.1.26  -  xnu-1699.24.8  -  xnu-2050.18.24  -  OPENSOLARIS  -  minix-3-1-1 
SearchContext: -  none  -  3  -  10 

    1 /*      $NetBSD: init_sysctl.c,v 1.24.2.5 2004/07/28 11:03:51 tron Exp $ */
    2 
    3 /*-
    4  * Copyright (c) 2003 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.
    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  * 3. All advertising materials mentioning features or use of this software
   19  *    must display the following acknowledgement:
   20  *      This product includes software developed by the NetBSD
   21  *      Foundation, Inc. and its contributors.
   22  * 4. Neither the name of The NetBSD Foundation nor the names of its
   23  *    contributors may be used to endorse or promote products derived
   24  *    from this software without specific prior written permission.
   25  *
   26  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   27  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   28  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   29  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   30  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   31  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   32  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   33  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   34  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   35  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   36  * POSSIBILITY OF SUCH DAMAGE.
   37  */
   38 
   39 #include <sys/cdefs.h>
   40 __KERNEL_RCSID(0, "$NetBSD: init_sysctl.c,v 1.24.2.5 2004/07/28 11:03:51 tron Exp $");
   41 
   42 #include "opt_sysv.h"
   43 #include "opt_multiprocessor.h"
   44 #include "opt_posix.h"
   45 #include "pty.h"
   46 #include "rnd.h"
   47 
   48 #include <sys/types.h>
   49 #include <sys/param.h>
   50 #include <sys/sysctl.h>
   51 #include <sys/errno.h>
   52 #include <sys/systm.h>
   53 #include <sys/kernel.h>
   54 #include <sys/unistd.h>
   55 #include <sys/disklabel.h>
   56 #include <sys/rnd.h>
   57 #include <sys/vnode.h>
   58 #include <sys/mount.h>
   59 #include <sys/namei.h>
   60 #include <sys/msgbuf.h>
   61 #include <dev/cons.h>
   62 #include <sys/socketvar.h>
   63 #include <sys/file.h>
   64 #include <sys/tty.h>
   65 #include <sys/malloc.h>
   66 #include <sys/resource.h>
   67 #include <sys/resourcevar.h>
   68 #include <sys/exec.h>
   69 #include <sys/conf.h>
   70 #include <sys/device.h>
   71 
   72 #if defined(SYSVMSG) || defined(SYSVSEM) || defined(SYSVSHM)
   73 #include <sys/ipc.h>
   74 #endif
   75 #ifdef SYSVMSG
   76 #include <sys/msg.h>
   77 #endif
   78 #ifdef SYSVSEM
   79 #include <sys/sem.h>
   80 #endif
   81 #ifdef SYSVSHM
   82 #include <sys/shm.h>
   83 #endif
   84 
   85 #include <machine/cpu.h>
   86 
   87 /*
   88  * try over estimating by 5 procs/lwps
   89  */
   90 #define KERN_PROCSLOP   (5 * sizeof(struct kinfo_proc))
   91 #define KERN_LWPSLOP    (5 * sizeof(struct kinfo_lwp))
   92 
   93 #ifndef MULTIPROCESSOR
   94 #define sysctl_ncpus()  (1)
   95 #else /* MULTIPROCESSOR */
   96 #ifndef CPU_INFO_FOREACH
   97 #define CPU_INFO_ITERATOR int
   98 #define CPU_INFO_FOREACH(cii, ci) cii = 0, ci = curcpu(); ci != NULL; ci = NULL
   99 #endif
  100 static int
  101 sysctl_ncpus(void)
  102 {
  103         struct cpu_info *ci;
  104         CPU_INFO_ITERATOR cii;
  105 
  106         int ncpus = 0;
  107         for (CPU_INFO_FOREACH(cii, ci))
  108                 ncpus++;
  109         return (ncpus);
  110 }
  111 #endif /* MULTIPROCESSOR */
  112 
  113 static int sysctl_kern_maxvnodes(SYSCTLFN_PROTO);
  114 static int sysctl_kern_rtc_offset(SYSCTLFN_PROTO);
  115 static int sysctl_kern_maxproc(SYSCTLFN_PROTO);
  116 static int sysctl_kern_securelevel(SYSCTLFN_PROTO);
  117 static int sysctl_kern_hostid(SYSCTLFN_PROTO);
  118 static int sysctl_setlen(SYSCTLFN_PROTO);
  119 static int sysctl_kern_clockrate(SYSCTLFN_PROTO);
  120 static int sysctl_kern_file(SYSCTLFN_PROTO);
  121 static int sysctl_kern_autonice(SYSCTLFN_PROTO);
  122 static int sysctl_msgbuf(SYSCTLFN_PROTO);
  123 static int sysctl_kern_defcorename(SYSCTLFN_PROTO);
  124 static int sysctl_kern_cptime(SYSCTLFN_PROTO);
  125 #if defined(SYSVMSG) || defined(SYSVSEM) || defined(SYSVSHM)
  126 static int sysctl_kern_sysvipc(SYSCTLFN_PROTO);
  127 #endif /* defined(SYSVMSG) || defined(SYSVSEM) || defined(SYSVSHM) */
  128 #if NPTY > 0
  129 static int sysctl_kern_maxptys(SYSCTLFN_PROTO);
  130 #endif /* NPTY > 0 */
  131 static int sysctl_kern_sbmax(SYSCTLFN_PROTO);
  132 static int sysctl_kern_urnd(SYSCTLFN_PROTO);
  133 static int sysctl_kern_lwp(SYSCTLFN_PROTO);
  134 static int sysctl_kern_forkfsleep(SYSCTLFN_PROTO);
  135 static int sysctl_kern_root_partition(SYSCTLFN_PROTO);
  136 static int sysctl_kern_drivers(SYSCTLFN_PROTO);
  137 static int sysctl_doeproc(SYSCTLFN_PROTO);
  138 static int sysctl_kern_proc_args(SYSCTLFN_PROTO);
  139 static int sysctl_hw_usermem(SYSCTLFN_PROTO);
  140 static int sysctl_hw_cnmagic(SYSCTLFN_PROTO);
  141 static int sysctl_hw_ncpu(SYSCTLFN_PROTO);
  142 
  143 static void fill_kproc2(struct proc *, struct kinfo_proc2 *);
  144 static void fill_lwp(struct lwp *l, struct kinfo_lwp *kl);
  145 
  146 /*
  147  * ********************************************************************
  148  * section 1: setup routines
  149  * ********************************************************************
  150  * these functions are stuffed into a link set for sysctl setup
  151  * functions.  they're never called or referenced from anywhere else.
  152  * ********************************************************************
  153  */
  154 
  155 /*
  156  * sets up the base nodes...
  157  */
  158 SYSCTL_SETUP(sysctl_root_setup, "sysctl base setup")
  159 {
  160 
  161         sysctl_createv(clog, 0, NULL, NULL,
  162                        CTLFLAG_PERMANENT,
  163                        CTLTYPE_NODE, "kern",
  164                        SYSCTL_DESCR("High kernel"),
  165                        NULL, 0, NULL, 0,
  166                        CTL_KERN, CTL_EOL);
  167         sysctl_createv(clog, 0, NULL, NULL,
  168                        CTLFLAG_PERMANENT,
  169                        CTLTYPE_NODE, "vm",
  170                        SYSCTL_DESCR("Virtual memory"),
  171                        NULL, 0, NULL, 0,
  172                        CTL_VM, CTL_EOL);
  173         sysctl_createv(clog, 0, NULL, NULL,
  174                        CTLFLAG_PERMANENT,
  175                        CTLTYPE_NODE, "vfs",
  176                        SYSCTL_DESCR("Filesystem"),
  177                        NULL, 0, NULL, 0,
  178                        CTL_VFS, CTL_EOL);
  179         sysctl_createv(clog, 0, NULL, NULL,
  180                        CTLFLAG_PERMANENT,
  181                        CTLTYPE_NODE, "net",
  182                        SYSCTL_DESCR("Networking"),
  183                        NULL, 0, NULL, 0,
  184                        CTL_NET, CTL_EOL);
  185         sysctl_createv(clog, 0, NULL, NULL,
  186                        CTLFLAG_PERMANENT,
  187                        CTLTYPE_NODE, "debug",
  188                        SYSCTL_DESCR("Debugging"),
  189                        NULL, 0, NULL, 0,
  190                        CTL_DEBUG, CTL_EOL);
  191         sysctl_createv(clog, 0, NULL, NULL,
  192                        CTLFLAG_PERMANENT,
  193                        CTLTYPE_NODE, "hw",
  194                        SYSCTL_DESCR("Generic CPU, I/O"),
  195                        NULL, 0, NULL, 0,
  196                        CTL_HW, CTL_EOL);
  197         sysctl_createv(clog, 0, NULL, NULL,
  198                        CTLFLAG_PERMANENT,
  199                        CTLTYPE_NODE, "machdep",
  200                        SYSCTL_DESCR("Machine dependent"),
  201                        NULL, 0, NULL, 0,
  202                        CTL_MACHDEP, CTL_EOL);
  203         /*
  204          * this node is inserted so that the sysctl nodes in libc can
  205          * operate.
  206          */
  207         sysctl_createv(clog, 0, NULL, NULL,
  208                        CTLFLAG_PERMANENT,
  209                        CTLTYPE_NODE, "user",
  210                        SYSCTL_DESCR("User-level"),
  211                        NULL, 0, NULL, 0,
  212                        CTL_USER, CTL_EOL);
  213         sysctl_createv(clog, 0, NULL, NULL,
  214                        CTLFLAG_PERMANENT,
  215                        CTLTYPE_NODE, "ddb",
  216                        SYSCTL_DESCR("In-kernel debugger"),
  217                        NULL, 0, NULL, 0,
  218                        CTL_DDB, CTL_EOL);
  219         sysctl_createv(clog, 0, NULL, NULL,
  220                        CTLFLAG_PERMANENT,
  221                        CTLTYPE_NODE, "proc",
  222                        SYSCTL_DESCR("Per-process"),
  223                        NULL, 0, NULL, 0,
  224                        CTL_PROC, CTL_EOL);
  225         sysctl_createv(clog, 0, NULL, NULL,
  226                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
  227                        CTLTYPE_NODE, "vendor",
  228                        SYSCTL_DESCR("Vendor specific"),
  229                        NULL, 0, NULL, 0,
  230                        CTL_VENDOR, CTL_EOL);
  231         sysctl_createv(clog, 0, NULL, NULL,
  232                        CTLFLAG_PERMANENT,
  233                        CTLTYPE_NODE, "emul",
  234                        SYSCTL_DESCR("Emulation settings"),
  235                        NULL, 0, NULL, 0,
  236                        CTL_EMUL, CTL_EOL);
  237 }
  238 
  239 /*
  240  * this setup routine is a replacement for kern_sysctl()
  241  */
  242 SYSCTL_SETUP(sysctl_kern_setup, "sysctl kern subtree setup")
  243 {
  244         extern int kern_logsigexit;     /* defined in kern/kern_sig.c */
  245         extern fixpt_t ccpu;            /* defined in kern/kern_synch.c */
  246         extern int dumponpanic;         /* defined in kern/subr_prf.c */
  247 
  248         sysctl_createv(clog, 0, NULL, NULL,
  249                        CTLFLAG_PERMANENT,
  250                        CTLTYPE_NODE, "kern", NULL,
  251                        NULL, 0, NULL, 0,
  252                        CTL_KERN, CTL_EOL);
  253 
  254         sysctl_createv(clog, 0, NULL, NULL,
  255                        CTLFLAG_PERMANENT,
  256                        CTLTYPE_STRING, "ostype",
  257                        SYSCTL_DESCR("Operating system type"),
  258                        NULL, 0, &ostype, 0,
  259                        CTL_KERN, KERN_OSTYPE, CTL_EOL);
  260         sysctl_createv(clog, 0, NULL, NULL,
  261                        CTLFLAG_PERMANENT,
  262                        CTLTYPE_STRING, "osrelease",
  263                        SYSCTL_DESCR("Operating system release"),
  264                        NULL, 0, &osrelease, 0,
  265                        CTL_KERN, KERN_OSRELEASE, CTL_EOL);
  266         sysctl_createv(clog, 0, NULL, NULL,
  267                        CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
  268                        CTLTYPE_INT, "osrevision",
  269                        SYSCTL_DESCR("Operating system revision"),
  270                        NULL, __NetBSD_Version__, NULL, 0,
  271                        CTL_KERN, KERN_OSREV, CTL_EOL);
  272         sysctl_createv(clog, 0, NULL, NULL,
  273                        CTLFLAG_PERMANENT,
  274                        CTLTYPE_STRING, "version",
  275                        SYSCTL_DESCR("Kernel version"),
  276                        NULL, 0, &version, 0,
  277                        CTL_KERN, KERN_VERSION, CTL_EOL);
  278         sysctl_createv(clog, 0, NULL, NULL,
  279                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
  280                        CTLTYPE_INT, "maxvnodes",
  281                        SYSCTL_DESCR("Maximum number of vnodes"),
  282                        sysctl_kern_maxvnodes, 0, NULL, 0,
  283                        CTL_KERN, KERN_MAXVNODES, CTL_EOL);
  284         sysctl_createv(clog, 0, NULL, NULL,
  285                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
  286                        CTLTYPE_INT, "maxproc",
  287                        SYSCTL_DESCR("Maximum number of simultaneous processes"),
  288                        sysctl_kern_maxproc, 0, NULL, 0,
  289                        CTL_KERN, KERN_MAXPROC, CTL_EOL);
  290         sysctl_createv(clog, 0, NULL, NULL,
  291                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
  292                        CTLTYPE_INT, "maxfiles",
  293                        SYSCTL_DESCR("Maximum number of open files"),
  294                        NULL, 0, &maxfiles, 0,
  295                        CTL_KERN, KERN_MAXFILES, CTL_EOL);
  296         sysctl_createv(clog, 0, NULL, NULL,
  297                        CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
  298                        CTLTYPE_INT, "argmax",
  299                        SYSCTL_DESCR("Maximum number of bytes of arguments to "
  300                                     "execve(2)"),
  301                        NULL, ARG_MAX, NULL, 0,
  302                        CTL_KERN, KERN_ARGMAX, CTL_EOL);
  303         sysctl_createv(clog, 0, NULL, NULL,
  304                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
  305                        CTLTYPE_INT, "securelevel",
  306                        SYSCTL_DESCR("System security level"),
  307                        sysctl_kern_securelevel, 0, &securelevel, 0,
  308                        CTL_KERN, KERN_SECURELVL, CTL_EOL);
  309         sysctl_createv(clog, 0, NULL, NULL,
  310                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
  311                        CTLTYPE_STRING, "hostname",
  312                        SYSCTL_DESCR("System hostname"),
  313                        sysctl_setlen, 0, &hostname, MAXHOSTNAMELEN,
  314                        CTL_KERN, KERN_HOSTNAME, CTL_EOL);
  315         sysctl_createv(clog, 0, NULL, NULL,
  316                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE|CTLFLAG_HEX,
  317                        CTLTYPE_INT, "hostid",
  318                        SYSCTL_DESCR("System host ID number"),
  319                        sysctl_kern_hostid, 0, NULL, 0,
  320                        CTL_KERN, KERN_HOSTID, CTL_EOL);
  321         sysctl_createv(clog, 0, NULL, NULL,
  322                        CTLFLAG_PERMANENT,
  323                        CTLTYPE_STRUCT, "clockrate",
  324                        SYSCTL_DESCR("Kernel clock rates"),
  325                        sysctl_kern_clockrate, 0, NULL,
  326                        sizeof(struct clockinfo),
  327                        CTL_KERN, KERN_CLOCKRATE, CTL_EOL);
  328         sysctl_createv(clog, 0, NULL, NULL,
  329                        CTLFLAG_PERMANENT,
  330                        CTLTYPE_STRUCT, "vnode",
  331                        SYSCTL_DESCR("System vnode table"),
  332                        sysctl_kern_vnode, 0, NULL, 0,
  333                        CTL_KERN, KERN_VNODE, CTL_EOL);
  334         sysctl_createv(clog, 0, NULL, NULL,
  335                        CTLFLAG_PERMANENT,
  336                        CTLTYPE_STRUCT, "file",
  337                        SYSCTL_DESCR("System open file table"),
  338                        sysctl_kern_file, 0, NULL, 0,
  339                        CTL_KERN, KERN_FILE, CTL_EOL);
  340 #ifndef GPROF
  341         sysctl_createv(clog, 0, NULL, NULL,
  342                        CTLFLAG_PERMANENT,
  343                        CTLTYPE_NODE, "profiling",
  344                        SYSCTL_DESCR("Profiling information (not available)"),
  345                        sysctl_notavail, 0, NULL, 0,
  346                        CTL_KERN, KERN_PROF, CTL_EOL);
  347 #endif
  348         sysctl_createv(clog, 0, NULL, NULL,
  349                        CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
  350                        CTLTYPE_INT, "posix1version",
  351                        SYSCTL_DESCR("Version of ISO/IEC 9945 (POSIX 1003.1) "
  352                                     "with which the operating system attempts "
  353                                     "to comply"),
  354                        NULL, _POSIX_VERSION, NULL, 0,
  355                        CTL_KERN, KERN_POSIX1, CTL_EOL);
  356         sysctl_createv(clog, 0, NULL, NULL,
  357                        CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
  358                        CTLTYPE_INT, "ngroups",
  359                        SYSCTL_DESCR("Maximum number of supplemental groups"),
  360                        NULL, NGROUPS_MAX, NULL, 0,
  361                        CTL_KERN, KERN_NGROUPS, CTL_EOL);
  362         sysctl_createv(clog, 0, NULL, NULL,
  363                        CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
  364                        CTLTYPE_INT, "job_control",
  365                        SYSCTL_DESCR("Whether job control is available"),
  366                        NULL, 1, NULL, 0,
  367                        CTL_KERN, KERN_JOB_CONTROL, CTL_EOL);
  368         sysctl_createv(clog, 0, NULL, NULL,
  369                        CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
  370                        CTLTYPE_INT, "saved_ids",
  371                        SYSCTL_DESCR("Whether saved set-group/user ID is "
  372                                     "available"), NULL,
  373 #ifdef _POSIX_SAVED_IDS
  374                        1,
  375 #else /* _POSIX_SAVED_IDS */
  376                        0,
  377 #endif /* _POSIX_SAVED_IDS */
  378                        NULL, 0, CTL_KERN, KERN_SAVED_IDS, CTL_EOL);
  379         sysctl_createv(clog, 0, NULL, NULL,
  380                        CTLFLAG_PERMANENT,
  381                        CTLTYPE_STRUCT, "boottime",
  382                        SYSCTL_DESCR("System boot time"),
  383                        NULL, 0, &boottime, sizeof(boottime),
  384                        CTL_KERN, KERN_BOOTTIME, CTL_EOL);
  385         sysctl_createv(clog, 0, NULL, NULL,
  386                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
  387                        CTLTYPE_STRING, "domainname",
  388                        SYSCTL_DESCR("YP domain name"),
  389                        sysctl_setlen, 0, &domainname, MAXHOSTNAMELEN,
  390                        CTL_KERN, KERN_DOMAINNAME, CTL_EOL);
  391         sysctl_createv(clog, 0, NULL, NULL,
  392                        CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
  393                        CTLTYPE_INT, "maxpartitions",
  394                        SYSCTL_DESCR("Maximum number of partitions allowed per "
  395                                     "disk"),
  396                        NULL, MAXPARTITIONS, NULL, 0,
  397                        CTL_KERN, KERN_MAXPARTITIONS, CTL_EOL);
  398         sysctl_createv(clog, 0, NULL, NULL,
  399                        CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
  400                        CTLTYPE_INT, "rawpartition",
  401                        SYSCTL_DESCR("Raw partition of a disk"),
  402                        NULL, RAW_PART, NULL, 0,
  403                        CTL_KERN, KERN_RAWPARTITION, CTL_EOL);
  404         sysctl_createv(clog, 0, NULL, NULL,
  405                        CTLFLAG_PERMANENT,
  406                        CTLTYPE_STRUCT, "timex", NULL,
  407                        sysctl_notavail, 0, NULL, 0,
  408                        CTL_KERN, KERN_TIMEX, CTL_EOL);
  409         sysctl_createv(clog, 0, NULL, NULL,
  410                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
  411                        CTLTYPE_INT, "autonicetime",
  412                        SYSCTL_DESCR("CPU clock seconds before non-root "
  413                                     "process priority is lowered"),
  414                        sysctl_kern_autonice, 0, &autonicetime, 0,
  415                        CTL_KERN, KERN_AUTONICETIME, CTL_EOL);
  416         sysctl_createv(clog, 0, NULL, NULL,
  417                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
  418                        CTLTYPE_INT, "autoniceval",
  419                        SYSCTL_DESCR("Automatic reniced non-root process "
  420                                     "priority"),
  421                        sysctl_kern_autonice, 0, &autoniceval, 0,
  422                        CTL_KERN, KERN_AUTONICEVAL, CTL_EOL);
  423         sysctl_createv(clog, 0, NULL, NULL,
  424                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
  425                        CTLTYPE_INT, "rtc_offset",
  426                        SYSCTL_DESCR("Offset of real time clock from UTC in "
  427                                     "minutes"),
  428                        sysctl_kern_rtc_offset, 0, &rtc_offset, 0,
  429                        CTL_KERN, KERN_RTC_OFFSET, CTL_EOL);
  430         sysctl_createv(clog, 0, NULL, NULL,
  431                        CTLFLAG_PERMANENT,
  432                        CTLTYPE_STRING, "root_device",
  433                        SYSCTL_DESCR("Name of the root device"),
  434                        sysctl_root_device, 0, NULL, 0,
  435                        CTL_KERN, KERN_ROOT_DEVICE, CTL_EOL);
  436         sysctl_createv(clog, 0, NULL, NULL,
  437                        CTLFLAG_PERMANENT,
  438                        CTLTYPE_INT, "msgbufsize",
  439                        SYSCTL_DESCR("Size of the kernel message buffer"),
  440                        sysctl_msgbuf, 0, NULL, 0,
  441                        CTL_KERN, KERN_MSGBUFSIZE, CTL_EOL);
  442         sysctl_createv(clog, 0, NULL, NULL,
  443                        CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
  444                        CTLTYPE_INT, "fsync",
  445                        SYSCTL_DESCR("Whether the POSIX 1003.1b File "
  446                                     "Synchronization Option is available on "
  447                                     "this system"),
  448                        NULL, 1, NULL, 0,
  449                        CTL_KERN, KERN_FSYNC, CTL_EOL);
  450         sysctl_createv(clog, 0, NULL, NULL,
  451                        CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
  452                        CTLTYPE_INT, "sysvmsg",
  453                        SYSCTL_DESCR("System V style message support available"),
  454                        NULL,
  455 #ifdef SYSVMSG
  456                        1,
  457 #else /* SYSVMSG */
  458                        0,
  459 #endif /* SYSVMSG */
  460                        NULL, 0, CTL_KERN, KERN_SYSVMSG, CTL_EOL);
  461         sysctl_createv(clog, 0, NULL, NULL,
  462                        CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
  463                        CTLTYPE_INT, "sysvsem",
  464                        SYSCTL_DESCR("System V style semaphore support "
  465                                     "available"), NULL,
  466 #ifdef SYSVSEM
  467                        1,
  468 #else /* SYSVSEM */
  469                        0,
  470 #endif /* SYSVSEM */
  471                        NULL, 0, CTL_KERN, KERN_SYSVSEM, CTL_EOL);
  472         sysctl_createv(clog, 0, NULL, NULL,
  473                        CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
  474                        CTLTYPE_INT, "sysvshm",
  475                        SYSCTL_DESCR("System V style shared memory support "
  476                                     "available"), NULL,
  477 #ifdef SYSVSHM
  478                        1,
  479 #else /* SYSVSHM */
  480                        0,
  481 #endif /* SYSVSHM */
  482                        NULL, 0, CTL_KERN, KERN_SYSVSHM, CTL_EOL);
  483         sysctl_createv(clog, 0, NULL, NULL,
  484                        CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
  485                        CTLTYPE_INT, "synchronized_io",
  486                        SYSCTL_DESCR("Whether the POSIX 1003.1b Synchronized "
  487                                     "I/O Option is available on this system"),
  488                        NULL, 1, NULL, 0,
  489                        CTL_KERN, KERN_SYNCHRONIZED_IO, CTL_EOL);
  490         sysctl_createv(clog, 0, NULL, NULL,
  491                        CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
  492                        CTLTYPE_INT, "iov_max",
  493                        SYSCTL_DESCR("Maximum number of iovec structures per "
  494                                     "process"),
  495                        NULL, IOV_MAX, NULL, 0,
  496                        CTL_KERN, KERN_IOV_MAX, CTL_EOL);
  497         sysctl_createv(clog, 0, NULL, NULL,
  498                        CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
  499                        CTLTYPE_INT, "mapped_files",
  500                        SYSCTL_DESCR("Whether the POSIX 1003.1b Memory Mapped "
  501                                     "Files Option is available on this system"),
  502                        NULL, 1, NULL, 0,
  503                        CTL_KERN, KERN_MAPPED_FILES, CTL_EOL);
  504         sysctl_createv(clog, 0, NULL, NULL,
  505                        CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
  506                        CTLTYPE_INT, "memlock",
  507                        SYSCTL_DESCR("Whether the POSIX 1003.1b Process Memory "
  508                                     "Locking Option is available on this "
  509                                     "system"),
  510                        NULL, 1, NULL, 0,
  511                        CTL_KERN, KERN_MEMLOCK, CTL_EOL);
  512         sysctl_createv(clog, 0, NULL, NULL,
  513                        CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
  514                        CTLTYPE_INT, "memlock_range",
  515                        SYSCTL_DESCR("Whether the POSIX 1003.1b Range Memory "
  516                                     "Locking Option is available on this "
  517                                     "system"),
  518                        NULL, 1, NULL, 0,
  519                        CTL_KERN, KERN_MEMLOCK_RANGE, CTL_EOL);
  520         sysctl_createv(clog, 0, NULL, NULL,
  521                        CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
  522                        CTLTYPE_INT, "memory_protection",
  523                        SYSCTL_DESCR("Whether the POSIX 1003.1b Memory "
  524                                     "Protection Option is available on this "
  525                                     "system"),
  526                        NULL, 1, NULL, 0,
  527                        CTL_KERN, KERN_MEMORY_PROTECTION, CTL_EOL);
  528         sysctl_createv(clog, 0, NULL, NULL,
  529                        CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
  530                        CTLTYPE_INT, "login_name_max",
  531                        SYSCTL_DESCR("Maximum login name length"),
  532                        NULL, LOGIN_NAME_MAX, NULL, 0,
  533                        CTL_KERN, KERN_LOGIN_NAME_MAX, CTL_EOL);
  534         sysctl_createv(clog, 0, NULL, NULL,
  535                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
  536                        CTLTYPE_STRING, "defcorename",
  537                        SYSCTL_DESCR("Default core file name"),
  538                        sysctl_kern_defcorename, 0, defcorename, MAXPATHLEN,
  539                        CTL_KERN, KERN_DEFCORENAME, CTL_EOL);
  540         sysctl_createv(clog, 0, NULL, NULL,
  541                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
  542                        CTLTYPE_INT, "logsigexit",
  543                        SYSCTL_DESCR("Log process exit when caused by signals"),
  544                        NULL, 0, &kern_logsigexit, 0,
  545                        CTL_KERN, KERN_LOGSIGEXIT, CTL_EOL);
  546         sysctl_createv(clog, 0, NULL, NULL,
  547                        CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
  548                        CTLTYPE_INT, "fscale",
  549                        SYSCTL_DESCR("Kernel fixed-point scale factor"),
  550                        NULL, FSCALE, NULL, 0,
  551                        CTL_KERN, KERN_FSCALE, CTL_EOL);
  552         sysctl_createv(clog, 0, NULL, NULL,
  553                        CTLFLAG_PERMANENT,
  554                        CTLTYPE_INT, "ccpu",
  555                        SYSCTL_DESCR("Scheduler exponential decay value"),
  556                        NULL, 0, &ccpu, 0,
  557                        CTL_KERN, KERN_CCPU, CTL_EOL);
  558         sysctl_createv(clog, 0, NULL, NULL,
  559                        CTLFLAG_PERMANENT,
  560                        CTLTYPE_STRUCT, "cp_time",
  561                        SYSCTL_DESCR("Clock ticks spent in different CPU states"),
  562                        sysctl_kern_cptime, 0, NULL, 0,
  563                        CTL_KERN, KERN_CP_TIME, CTL_EOL);
  564 #if defined(SYSVMSG) || defined(SYSVSEM) || defined(SYSVSHM)
  565         sysctl_createv(clog, 0, NULL, NULL,
  566                        CTLFLAG_PERMANENT,
  567                        CTLTYPE_STRUCT, "sysvipc_info",
  568                        SYSCTL_DESCR("System V style IPC information"),
  569                        sysctl_kern_sysvipc, 0, NULL, 0,
  570                        CTL_KERN, KERN_SYSVIPC_INFO, CTL_EOL);
  571 #endif /* SYSVMSG || SYSVSEM || SYSVSHM */
  572         sysctl_createv(clog, 0, NULL, NULL,
  573                        CTLFLAG_PERMANENT,
  574                        CTLTYPE_INT, "msgbuf",
  575                        SYSCTL_DESCR("Kernel message buffer"),
  576                        sysctl_msgbuf, 0, NULL, 0,
  577                        CTL_KERN, KERN_MSGBUF, CTL_EOL);
  578         sysctl_createv(clog, 0, NULL, NULL,
  579                        CTLFLAG_PERMANENT,
  580                        CTLTYPE_STRUCT, "consdev",
  581                        SYSCTL_DESCR("Console device"),
  582                        sysctl_consdev, 0, NULL, sizeof(dev_t),
  583                        CTL_KERN, KERN_CONSDEV, CTL_EOL);
  584 #if NPTY > 0
  585         sysctl_createv(clog, 0, NULL, NULL,
  586                        CTLFLAG_PERMANENT,
  587                        CTLTYPE_INT, "maxptys",
  588                        SYSCTL_DESCR("Maximum number of pseudo-ttys"),
  589                        sysctl_kern_maxptys, 0, NULL, 0,
  590                        CTL_KERN, KERN_MAXPTYS, CTL_EOL);
  591 #endif /* NPTY > 0 */
  592         sysctl_createv(clog, 0, NULL, NULL,
  593                        CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
  594                        CTLTYPE_INT, "maxphys",
  595                        SYSCTL_DESCR("Maximum raw I/O transfer size"),
  596                        NULL, MAXPHYS, NULL, 0,
  597                        CTL_KERN, KERN_MAXPHYS, CTL_EOL);
  598         sysctl_createv(clog, 0, NULL, NULL,
  599                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
  600                        CTLTYPE_INT, "sbmax",
  601                        SYSCTL_DESCR("Maximum socket buffer size"),
  602                        sysctl_kern_sbmax, 0, NULL, 0,
  603                        CTL_KERN, KERN_SBMAX, CTL_EOL);
  604         sysctl_createv(clog, 0, NULL, NULL,
  605                        CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
  606                        CTLTYPE_INT, "monotonic_clock",
  607                        SYSCTL_DESCR("Implementation version of the POSIX "
  608                                     "1003.1b Monotonic Clock Option"),
  609                        /* XXX _POSIX_VERSION */
  610                        NULL, _POSIX_MONOTONIC_CLOCK, NULL, 0,
  611                        CTL_KERN, KERN_MONOTONIC_CLOCK, CTL_EOL);
  612         sysctl_createv(clog, 0, NULL, NULL,
  613                        CTLFLAG_PERMANENT,
  614                        CTLTYPE_INT, "urandom",
  615                        SYSCTL_DESCR("Random integer value"),
  616                        sysctl_kern_urnd, 0, NULL, 0,
  617                        CTL_KERN, KERN_URND, CTL_EOL);
  618         sysctl_createv(clog, 0, NULL, NULL,
  619                        CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
  620                        CTLTYPE_INT, "labelsector",
  621                        SYSCTL_DESCR("Sector number containing the disklabel"),
  622                        NULL, LABELSECTOR, NULL, 0,
  623                        CTL_KERN, KERN_LABELSECTOR, CTL_EOL);
  624         sysctl_createv(clog, 0, NULL, NULL,
  625                        CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
  626                        CTLTYPE_INT, "labeloffset",
  627                        SYSCTL_DESCR("Offset of the disklabel within the "
  628                                     "sector"),
  629                        NULL, LABELOFFSET, NULL, 0,
  630                        CTL_KERN, KERN_LABELOFFSET, CTL_EOL);
  631         sysctl_createv(clog, 0, NULL, NULL,
  632                        CTLFLAG_PERMANENT,
  633                        CTLTYPE_NODE, "lwp",
  634                        SYSCTL_DESCR("System-wide LWP information"),
  635                        sysctl_kern_lwp, 0, NULL, 0,
  636                        CTL_KERN, KERN_LWP, CTL_EOL);
  637         sysctl_createv(clog, 0, NULL, NULL,
  638                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
  639                        CTLTYPE_INT, "forkfsleep",
  640                        SYSCTL_DESCR("Milliseconds to sleep on fork failure due "
  641                                     "to process limits"),
  642                        sysctl_kern_forkfsleep, 0, NULL, 0,
  643                        CTL_KERN, KERN_FORKFSLEEP, CTL_EOL);
  644         sysctl_createv(clog, 0, NULL, NULL,
  645                        CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
  646                        CTLTYPE_INT, "posix_threads",
  647                        SYSCTL_DESCR("Version of IEEE Std 1003.1 and its "
  648                                     "Threads option to which the system "
  649                                     "attempts to conform"),
  650                        /* XXX _POSIX_VERSION */
  651                        NULL, _POSIX_THREADS, NULL, 0,
  652                        CTL_KERN, KERN_POSIX_THREADS, CTL_EOL);
  653         sysctl_createv(clog, 0, NULL, NULL,
  654                        CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
  655                        CTLTYPE_INT, "posix_semaphores",
  656                        SYSCTL_DESCR("Version of IEEE Std 1003.1 and its "
  657                                     "Semaphores option to which the system "
  658                                     "attempts to conform"), NULL,
  659 #ifdef P1003_1B_SEMAPHORE
  660                        200112,
  661 #else /* P1003_1B_SEMAPHORE */
  662                        0,
  663 #endif /* P1003_1B_SEMAPHORE */
  664                        NULL, 0, CTL_KERN, KERN_POSIX_SEMAPHORES, CTL_EOL);
  665         sysctl_createv(clog, 0, NULL, NULL,
  666                        CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
  667                        CTLTYPE_INT, "posix_barriers",
  668                        SYSCTL_DESCR("Version of IEEE Std 1003.1 and its "
  669                                     "Barriers option to which the system "
  670                                     "attempts to conform"),
  671                        /* XXX _POSIX_VERSION */
  672                        NULL, _POSIX_BARRIERS, NULL, 0,
  673                        CTL_KERN, KERN_POSIX_BARRIERS, CTL_EOL);
  674         sysctl_createv(clog, 0, NULL, NULL,
  675                        CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
  676                        CTLTYPE_INT, "posix_timers",
  677                        SYSCTL_DESCR("Version of IEEE Std 1003.1 and its "
  678                                     "Timers option to which the system "
  679                                     "attempts to conform"),
  680                        /* XXX _POSIX_VERSION */
  681                        NULL, _POSIX_TIMERS, NULL, 0,
  682                        CTL_KERN, KERN_POSIX_TIMERS, CTL_EOL);
  683         sysctl_createv(clog, 0, NULL, NULL,
  684                        CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
  685                        CTLTYPE_INT, "posix_spin_locks",
  686                        SYSCTL_DESCR("Version of IEEE Std 1003.1 and its Spin "
  687                                     "Locks option to which the system attempts "
  688                                     "to conform"),
  689                        /* XXX _POSIX_VERSION */
  690                        NULL, _POSIX_SPIN_LOCKS, NULL, 0,
  691                        CTL_KERN, KERN_POSIX_SPIN_LOCKS, CTL_EOL);
  692         sysctl_createv(clog, 0, NULL, NULL,
  693                        CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
  694                        CTLTYPE_INT, "posix_reader_writer_locks",
  695                        SYSCTL_DESCR("Version of IEEE Std 1003.1 and its "
  696                                     "Read-Write Locks option to which the "
  697                                     "system attempts to conform"),
  698                        /* XXX _POSIX_VERSION */
  699                        NULL, _POSIX_READER_WRITER_LOCKS, NULL, 0,
  700                        CTL_KERN, KERN_POSIX_READER_WRITER_LOCKS, CTL_EOL);
  701         sysctl_createv(clog, 0, NULL, NULL,
  702                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
  703                        CTLTYPE_INT, "dump_on_panic",
  704                        SYSCTL_DESCR("Perform a crash dump on system panic"),
  705                        NULL, 0, &dumponpanic, 0,
  706                        CTL_KERN, KERN_DUMP_ON_PANIC, CTL_EOL);
  707         sysctl_createv(clog, 0, NULL, NULL,
  708                        CTLFLAG_PERMANENT,
  709                        CTLTYPE_INT, "root_partition",
  710                        SYSCTL_DESCR("Root partition on the root device"),
  711                        sysctl_kern_root_partition, 0, NULL, 0,
  712                        CTL_KERN, KERN_ROOT_PARTITION, CTL_EOL);
  713         sysctl_createv(clog, 0, NULL, NULL,
  714                        CTLFLAG_PERMANENT,
  715                        CTLTYPE_STRUCT, "drivers",
  716                        SYSCTL_DESCR("List of all drivers with block and "
  717                                     "character device numbers"),
  718                        sysctl_kern_drivers, 0, NULL, 0,
  719                        CTL_KERN, KERN_DRIVERS, CTL_EOL);
  720 }
  721 
  722 SYSCTL_SETUP(sysctl_kern_proc_setup,
  723              "sysctl kern.proc/proc2/proc_args subtree setup")
  724 {
  725 
  726         sysctl_createv(clog, 0, NULL, NULL,
  727                        CTLFLAG_PERMANENT,
  728                        CTLTYPE_NODE, "kern", NULL,
  729                        NULL, 0, NULL, 0,
  730                        CTL_KERN, CTL_EOL);
  731 
  732         sysctl_createv(clog, 0, NULL, NULL,
  733                        CTLFLAG_PERMANENT,
  734                        CTLTYPE_NODE, "proc",
  735                        SYSCTL_DESCR("System-wide process information"),
  736                        sysctl_doeproc, 0, NULL, 0,
  737                        CTL_KERN, KERN_PROC, CTL_EOL);
  738         sysctl_createv(clog, 0, NULL, NULL,
  739                        CTLFLAG_PERMANENT,
  740                        CTLTYPE_NODE, "proc2",
  741                        SYSCTL_DESCR("Machine-independent process information"),
  742                        sysctl_doeproc, 0, NULL, 0,
  743                        CTL_KERN, KERN_PROC2, CTL_EOL);
  744         sysctl_createv(clog, 0, NULL, NULL,
  745                        CTLFLAG_PERMANENT,
  746                        CTLTYPE_NODE, "proc_args",
  747                        SYSCTL_DESCR("Process argument information"),
  748                        sysctl_kern_proc_args, 0, NULL, 0,
  749                        CTL_KERN, KERN_PROC_ARGS, CTL_EOL);
  750 
  751         /*
  752           "nodes" under these:
  753 
  754           KERN_PROC_ALL
  755           KERN_PROC_PID pid
  756           KERN_PROC_PGRP pgrp
  757           KERN_PROC_SESSION sess
  758           KERN_PROC_TTY tty
  759           KERN_PROC_UID uid
  760           KERN_PROC_RUID uid
  761           KERN_PROC_GID gid
  762           KERN_PROC_RGID gid
  763 
  764           all in all, probably not worth the effort...
  765         */
  766 }
  767 
  768 SYSCTL_SETUP(sysctl_hw_setup, "sysctl hw subtree setup")
  769 {
  770         u_int u;
  771         u_quad_t q;
  772 
  773         sysctl_createv(clog, 0, NULL, NULL,
  774                        CTLFLAG_PERMANENT,
  775                        CTLTYPE_NODE, "hw", NULL,
  776                        NULL, 0, NULL, 0,
  777                        CTL_HW, CTL_EOL);
  778 
  779         sysctl_createv(clog, 0, NULL, NULL,
  780                        CTLFLAG_PERMANENT,
  781                        CTLTYPE_STRING, "machine",
  782                        SYSCTL_DESCR("Machine class"),
  783                        NULL, 0, machine, 0,
  784                        CTL_HW, HW_MACHINE, CTL_EOL);
  785         sysctl_createv(clog, 0, NULL, NULL,
  786                        CTLFLAG_PERMANENT,
  787                        CTLTYPE_STRING, "model",
  788                        SYSCTL_DESCR("Machine model"),
  789                        NULL, 0, cpu_model, 0,
  790                        CTL_HW, HW_MODEL, CTL_EOL);
  791         sysctl_createv(clog, 0, NULL, NULL,
  792                        CTLFLAG_PERMANENT,
  793                        CTLTYPE_INT, "ncpu",
  794                        SYSCTL_DESCR("Number of active CPUs"),
  795                        sysctl_hw_ncpu, 0, NULL, 0,
  796                        CTL_HW, HW_NCPU, CTL_EOL);
  797         sysctl_createv(clog, 0, NULL, NULL,
  798                        CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
  799                        CTLTYPE_INT, "byteorder",
  800                        SYSCTL_DESCR("System byte order"),
  801                        NULL, BYTE_ORDER, NULL, 0,
  802                        CTL_HW, HW_BYTEORDER, CTL_EOL);
  803         u = ((u_int)physmem > (UINT_MAX / PAGE_SIZE)) ?
  804                 UINT_MAX : physmem * PAGE_SIZE;
  805         sysctl_createv(clog, 0, NULL, NULL,
  806                        CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
  807                        CTLTYPE_INT, "physmem",
  808                        SYSCTL_DESCR("Bytes of physical memory"),
  809                        NULL, u, NULL, 0,
  810                        CTL_HW, HW_PHYSMEM, CTL_EOL);
  811         sysctl_createv(clog, 0, NULL, NULL,
  812                        CTLFLAG_PERMANENT,
  813                        CTLTYPE_INT, "usermem",
  814                        SYSCTL_DESCR("Bytes of non-kernel memory"),
  815                        sysctl_hw_usermem, 0, NULL, 0,
  816                        CTL_HW, HW_USERMEM, CTL_EOL);
  817         sysctl_createv(clog, 0, NULL, NULL,
  818                        CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
  819                        CTLTYPE_INT, "pagesize",
  820                        SYSCTL_DESCR("Software page size"),
  821                        NULL, PAGE_SIZE, NULL, 0,
  822                        CTL_HW, HW_PAGESIZE, CTL_EOL);
  823         sysctl_createv(clog, 0, NULL, NULL,
  824                        CTLFLAG_PERMANENT,
  825                        CTLTYPE_STRING, "disknames",
  826                        SYSCTL_DESCR("List of disk devices present"),
  827                        sysctl_hw_disknames, 0, NULL, 0,
  828                        CTL_HW, HW_DISKNAMES, CTL_EOL);
  829         sysctl_createv(clog, 0, NULL, NULL,
  830                        CTLFLAG_PERMANENT,
  831                        CTLTYPE_STRUCT, "diskstats",
  832                        SYSCTL_DESCR("Statistics on disk operation"),
  833                        sysctl_hw_diskstats, 0, NULL, 0,
  834                        CTL_HW, HW_DISKSTATS, CTL_EOL);
  835         sysctl_createv(clog, 0, NULL, NULL,
  836                        CTLFLAG_PERMANENT,
  837                        CTLTYPE_STRING, "machine_arch",
  838                        SYSCTL_DESCR("Machine CPU class"),
  839                        NULL, 0, machine_arch, 0,
  840                        CTL_HW, HW_MACHINE_ARCH, CTL_EOL);
  841         sysctl_createv(clog, 0, NULL, NULL,
  842                        CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
  843                        CTLTYPE_INT, "alignbytes",
  844                        SYSCTL_DESCR("Alignment constraint for all possible "
  845                                     "data types"),
  846                        NULL, ALIGNBYTES, NULL, 0,
  847                        CTL_HW, HW_ALIGNBYTES, CTL_EOL);
  848         sysctl_createv(clog, 0, NULL, NULL,
  849                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE|CTLFLAG_HEX,
  850                        CTLTYPE_STRING, "cnmagic",
  851                        SYSCTL_DESCR("Console magic key sequence"),
  852                        sysctl_hw_cnmagic, 0, NULL, CNS_LEN,
  853                        CTL_HW, HW_CNMAGIC, CTL_EOL);
  854         q = (u_quad_t)physmem * PAGE_SIZE;
  855         sysctl_createv(clog, 0, NULL, NULL,
  856                        CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
  857                        CTLTYPE_QUAD, "physmem64",
  858                        SYSCTL_DESCR("Bytes of physical memory"),
  859                        NULL, q, NULL, 0,
  860                        CTL_HW, HW_PHYSMEM64, CTL_EOL);
  861         sysctl_createv(clog, 0, NULL, NULL,
  862                        CTLFLAG_PERMANENT,
  863                        CTLTYPE_QUAD, "usermem64",
  864                        SYSCTL_DESCR("Bytes of non-kernel memory"),
  865                        sysctl_hw_usermem, 0, NULL, 0,
  866                        CTL_HW, HW_USERMEM64, CTL_EOL);
  867 }
  868 
  869 #ifdef DEBUG
  870 /*
  871  * Debugging related system variables.
  872  */
  873 struct ctldebug /* debug0, */ /* debug1, */ debug2, debug3, debug4;
  874 struct ctldebug debug5, debug6, debug7, debug8, debug9;
  875 struct ctldebug debug10, debug11, debug12, debug13, debug14;
  876 struct ctldebug debug15, debug16, debug17, debug18, debug19;
  877 static struct ctldebug *debugvars[CTL_DEBUG_MAXID] = {
  878         &debug0, &debug1, &debug2, &debug3, &debug4,
  879         &debug5, &debug6, &debug7, &debug8, &debug9,
  880         &debug10, &debug11, &debug12, &debug13, &debug14,
  881         &debug15, &debug16, &debug17, &debug18, &debug19,
  882 };
  883 
  884 /*
  885  * this setup routine is a replacement for debug_sysctl()
  886  *
  887  * note that it creates several nodes per defined debug variable
  888  */
  889 SYSCTL_SETUP(sysctl_debug_setup, "sysctl debug subtree setup")
  890 {
  891         struct ctldebug *cdp;
  892         char nodename[20];
  893         int i;
  894 
  895         /*
  896          * two ways here:
  897          *
  898          * the "old" way (debug.name -> value) which was emulated by
  899          * the sysctl(8) binary
  900          *
  901          * the new way, which the sysctl(8) binary was actually using
  902 
  903          node   debug
  904          node   debug.0
  905          string debug.0.name
  906          int    debug.0.value
  907          int    debug.name
  908 
  909          */
  910 
  911         sysctl_createv(clog, 0, NULL, NULL,
  912                        CTLFLAG_PERMANENT,
  913                        CTLTYPE_NODE, "debug", NULL,
  914                        NULL, 0, NULL, 0,
  915                        CTL_DEBUG, CTL_EOL);
  916 
  917         for (i = 0; i < CTL_DEBUG_MAXID; i++) {
  918                 cdp = debugvars[i];
  919                 if (cdp->debugname == NULL || cdp->debugvar == NULL)
  920                         continue;
  921 
  922                 snprintf(nodename, sizeof(nodename), "debug%d", i);
  923                 sysctl_createv(clog, 0, NULL, NULL,
  924                                CTLFLAG_PERMANENT|CTLFLAG_HIDDEN,
  925                                CTLTYPE_NODE, nodename, NULL,
  926                                NULL, 0, NULL, 0,
  927                                CTL_DEBUG, i, CTL_EOL);
  928                 sysctl_createv(clog, 0, NULL, NULL,
  929                                CTLFLAG_PERMANENT|CTLFLAG_HIDDEN,
  930                                CTLTYPE_STRING, "name", NULL,
  931                                NULL, 0, cdp->debugname, 0,
  932                                CTL_DEBUG, i, CTL_DEBUG_NAME, CTL_EOL);
  933                 sysctl_createv(clog, 0, NULL, NULL,
  934                                CTLFLAG_PERMANENT|CTLFLAG_HIDDEN,
  935                                CTLTYPE_INT, "value", NULL,
  936                                NULL, 0, cdp->debugvar, 0,
  937                                CTL_DEBUG, i, CTL_DEBUG_VALUE, CTL_EOL);
  938                 sysctl_createv(clog, 0, NULL, NULL,
  939                                CTLFLAG_PERMANENT,
  940                                CTLTYPE_INT, cdp->debugname, NULL,
  941                                NULL, 0, cdp->debugvar, 0,
  942                                CTL_DEBUG, CTL_CREATE, CTL_EOL);
  943         }
  944 }
  945 #endif /* DEBUG */
  946 
  947 /*
  948  * ********************************************************************
  949  * section 2: private node-specific helper routines.
  950  * ********************************************************************
  951  */
  952 
  953 /*
  954  * sysctl helper routine for kern.maxvnodes.  drain vnodes if
  955  * new value is lower than desiredvnodes and then calls reinit
  956  * routines that needs to adjust to the new value.
  957  */
  958 static int
  959 sysctl_kern_maxvnodes(SYSCTLFN_ARGS)
  960 {
  961         int error, new_vnodes, old_vnodes;
  962         struct sysctlnode node;
  963 
  964         new_vnodes = desiredvnodes;
  965         node = *rnode;
  966         node.sysctl_data = &new_vnodes;
  967         error = sysctl_lookup(SYSCTLFN_CALL(&node));
  968         if (error || newp == NULL)
  969                 return (error);
  970 
  971         old_vnodes = desiredvnodes;
  972         desiredvnodes = new_vnodes;
  973         if (new_vnodes < old_vnodes) {
  974                 error = vfs_drainvnodes(new_vnodes, l->l_proc);
  975                 if (error) {
  976                         desiredvnodes = old_vnodes;
  977                         return (error);
  978                 }
  979         }
  980         vfs_reinit();
  981         nchreinit();
  982 
  983         return (0);
  984 }
  985 
  986 /*
  987  * sysctl helper routine for rtc_offset - set time after changes
  988  */
  989 static int
  990 sysctl_kern_rtc_offset(SYSCTLFN_ARGS)
  991 {
  992         struct timeval tv, delta;
  993         int s, error, new_rtc_offset;
  994         struct sysctlnode node;
  995 
  996         new_rtc_offset = rtc_offset;
  997         node = *rnode;
  998         node.sysctl_data = &new_rtc_offset;
  999         error = sysctl_lookup(SYSCTLFN_CALL(&node));
 1000         if (error || newp == NULL)
 1001                 return (error);
 1002 
 1003         if (securelevel > 0)
 1004                 return (EPERM);
 1005         if (rtc_offset == new_rtc_offset)
 1006                 return (0);
 1007 
 1008         /* if we change the offset, adjust the time */
 1009         s = splclock();
 1010         tv = time;
 1011         splx(s);
 1012         delta.tv_sec = 60*(new_rtc_offset - rtc_offset);
 1013         delta.tv_usec = 0;
 1014         timeradd(&tv, &delta, &tv);
 1015         rtc_offset = new_rtc_offset;
 1016         settime(&tv);
 1017 
 1018         return (0);
 1019 }
 1020 
 1021 /*
 1022  * sysctl helper routine for kern.maxvnodes.  ensures that the new
 1023  * values are not too low or too high.
 1024  */
 1025 static int
 1026 sysctl_kern_maxproc(SYSCTLFN_ARGS)
 1027 {
 1028         int error, nmaxproc;
 1029         struct sysctlnode node;
 1030 
 1031         nmaxproc = maxproc;
 1032         node = *rnode;
 1033         node.sysctl_data = &nmaxproc;
 1034         error = sysctl_lookup(SYSCTLFN_CALL(&node));
 1035         if (error || newp == NULL)
 1036                 return (error);
 1037 
 1038         if (nmaxproc < 0 || nmaxproc >= PID_MAX)
 1039                 return (EINVAL);
 1040 #ifdef __HAVE_CPU_MAXPROC
 1041         if (nmaxproc > cpu_maxproc())
 1042                 return (EINVAL);
 1043 #endif
 1044         maxproc = nmaxproc;
 1045 
 1046         return (0);
 1047 }
 1048 
 1049 /*
 1050  * sysctl helper routine for kern.securelevel.  ensures that the value
 1051  * only rises unless the caller has pid 1 (assumed to be init).
 1052  */
 1053 static int
 1054 sysctl_kern_securelevel(SYSCTLFN_ARGS)
 1055 {
 1056         int newsecurelevel, error;
 1057         struct sysctlnode node;
 1058 
 1059         newsecurelevel = securelevel;
 1060         node = *rnode;
 1061         node.sysctl_data = &newsecurelevel;
 1062         error = sysctl_lookup(SYSCTLFN_CALL(&node));
 1063         if (error || newp == NULL)
 1064                 return (error);
 1065 
 1066         if (newsecurelevel < securelevel && l && l->l_proc->p_pid != 1)
 1067                 return (EPERM);
 1068         securelevel = newsecurelevel;
 1069 
 1070         return (error);
 1071 }
 1072 
 1073 /*
 1074  * sysctl helper function for kern.hostid.  the hostid is a long, but
 1075  * we export it as an int, so we need to give it a little help.
 1076  */
 1077 static int
 1078 sysctl_kern_hostid(SYSCTLFN_ARGS)
 1079 {
 1080         int error, inthostid;
 1081         struct sysctlnode node;
 1082 
 1083         inthostid = hostid;  /* XXX assumes sizeof int <= sizeof long */
 1084         node = *rnode;
 1085         node.sysctl_data = &inthostid;
 1086         error = sysctl_lookup(SYSCTLFN_CALL(&node));
 1087         if (error || newp == NULL)
 1088                 return (error);
 1089 
 1090         hostid = (unsigned)inthostid;
 1091 
 1092         return (0);
 1093 }
 1094 
 1095 /*
 1096  * sysctl helper function for kern.hostname and kern.domainnname.
 1097  * resets the relevant recorded length when the underlying name is
 1098  * changed.
 1099  */
 1100 static int
 1101 sysctl_setlen(SYSCTLFN_ARGS)
 1102 {
 1103         int error;
 1104 
 1105         error = sysctl_lookup(SYSCTLFN_CALL(rnode));
 1106         if (error || newp == NULL)
 1107                 return (error);
 1108 
 1109         switch (rnode->sysctl_num) {
 1110         case KERN_HOSTNAME:
 1111                 hostnamelen = strlen((const char*)rnode->sysctl_data);
 1112                 break;
 1113         case KERN_DOMAINNAME:
 1114                 domainnamelen = strlen((const char*)rnode->sysctl_data);
 1115                 break;
 1116         }
 1117 
 1118         return (0);
 1119 }
 1120 
 1121 /*
 1122  * sysctl helper routine for kern.clockrate.  assembles a struct on
 1123  * the fly to be returned to the caller.
 1124  */
 1125 static int
 1126 sysctl_kern_clockrate(SYSCTLFN_ARGS)
 1127 {
 1128         struct clockinfo clkinfo;
 1129         struct sysctlnode node;
 1130 
 1131         clkinfo.tick = tick;
 1132         clkinfo.tickadj = tickadj;
 1133         clkinfo.hz = hz;
 1134         clkinfo.profhz = profhz;
 1135         clkinfo.stathz = stathz ? stathz : hz;
 1136 
 1137         node = *rnode;
 1138         node.sysctl_data = &clkinfo;
 1139         return (sysctl_lookup(SYSCTLFN_CALL(&node)));
 1140 }
 1141 
 1142 
 1143 /*
 1144  * sysctl helper routine for kern.file pseudo-subtree.
 1145  */
 1146 static int
 1147 sysctl_kern_file(SYSCTLFN_ARGS)
 1148 {
 1149         int error;
 1150         size_t buflen;
 1151         struct file *fp;
 1152         char *start, *where;
 1153 
 1154         start = where = oldp;
 1155         buflen = *oldlenp;
 1156         if (where == NULL) {
 1157                 /*
 1158                  * overestimate by 10 files
 1159                  */
 1160                 *oldlenp = sizeof(filehead) + (nfiles + 10) * sizeof(struct file);
 1161                 return (0);
 1162         }
 1163 
 1164         /*
 1165          * first copyout filehead
 1166          */
 1167         if (buflen < sizeof(filehead)) {
 1168                 *oldlenp = 0;
 1169                 return (0);
 1170         }
 1171         error = copyout(&filehead, where, sizeof(filehead));
 1172         if (error)
 1173                 return (error);
 1174         buflen -= sizeof(filehead);
 1175         where += sizeof(filehead);
 1176 
 1177         /*
 1178          * followed by an array of file structures
 1179          */
 1180         LIST_FOREACH(fp, &filehead, f_list) {
 1181                 if (buflen < sizeof(struct file)) {
 1182                         *oldlenp = where - start;
 1183                         return (ENOMEM);
 1184                 }
 1185                 error = copyout(fp, where, sizeof(struct file));
 1186                 if (error)
 1187                         return (error);
 1188                 buflen -= sizeof(struct file);
 1189                 where += sizeof(struct file);
 1190         }
 1191         *oldlenp = where - start;
 1192         return (0);
 1193 }
 1194 
 1195 /*
 1196  * sysctl helper routine for kern.autonicetime and kern.autoniceval.
 1197  * asserts that the assigned value is in the correct range.
 1198  */
 1199 static int
 1200 sysctl_kern_autonice(SYSCTLFN_ARGS)
 1201 {
 1202         int error, t = 0;
 1203         struct sysctlnode node;
 1204 
 1205         node = *rnode;
 1206         t = *(int*)node.sysctl_data;
 1207         node.sysctl_data = &t;
 1208         error = sysctl_lookup(SYSCTLFN_CALL(&node));
 1209         if (error || newp == NULL)
 1210                 return (error);
 1211 
 1212         switch (node.sysctl_num) {
 1213         case KERN_AUTONICETIME:
 1214                 if (t >= 0)
 1215                         autonicetime = t;
 1216                 break;
 1217         case KERN_AUTONICEVAL:
 1218                 if (t < PRIO_MIN)
 1219                         t = PRIO_MIN;
 1220                 else if (t > PRIO_MAX)
 1221                         t = PRIO_MAX;
 1222                 autoniceval = t;
 1223                 break;
 1224         }
 1225 
 1226         return (0);
 1227 }
 1228 
 1229 /*
 1230  * sysctl helper routine for kern.msgbufsize and kern.msgbuf.  for the
 1231  * former it merely checks the the message buffer is set up.  for the
 1232  * latter, it also copies out the data if necessary.
 1233  */
 1234 static int
 1235 sysctl_msgbuf(SYSCTLFN_ARGS)
 1236 {
 1237         char *where = oldp;
 1238         size_t len, maxlen;
 1239         long beg, end;
 1240         int error;
 1241 
 1242         if (!msgbufenabled || msgbufp->msg_magic != MSG_MAGIC) {
 1243                 msgbufenabled = 0;
 1244                 return (ENXIO);
 1245         }
 1246 
 1247         switch (rnode->sysctl_num) {
 1248         case KERN_MSGBUFSIZE: {
 1249                 struct sysctlnode node = *rnode;
 1250                 int msg_bufs = (int)msgbufp->msg_bufs;
 1251                 node.sysctl_data = &msg_bufs;
 1252                 return (sysctl_lookup(SYSCTLFN_CALL(&node)));
 1253         }
 1254         case KERN_MSGBUF:
 1255                 break;
 1256         default:
 1257                 return (EOPNOTSUPP);
 1258         }
 1259 
 1260         if (newp != NULL)
 1261                 return (EPERM);
 1262 
 1263         if (oldp == NULL) {
 1264                 /* always return full buffer size */
 1265                 *oldlenp = msgbufp->msg_bufs;
 1266                 return (0);
 1267         }
 1268 
 1269         error = 0;
 1270         maxlen = MIN(msgbufp->msg_bufs, *oldlenp);
 1271 
 1272         /*
 1273          * First, copy from the write pointer to the end of
 1274          * message buffer.
 1275          */
 1276         beg = msgbufp->msg_bufx;
 1277         end = msgbufp->msg_bufs;
 1278         while (maxlen > 0) {
 1279                 len = MIN(end - beg, maxlen);
 1280                 if (len == 0)
 1281                         break;
 1282                 error = copyout(&msgbufp->msg_bufc[beg], where, len);
 1283                 if (error)
 1284                         break;
 1285                 where += len;
 1286                 maxlen -= len;
 1287 
 1288                 /*
 1289                  * ... then, copy from the beginning of message buffer to
 1290                  * the write pointer.
 1291                  */
 1292                 beg = 0;
 1293                 end = msgbufp->msg_bufx;
 1294         }
 1295 
 1296         return (error);
 1297 }
 1298 
 1299 /*
 1300  * sysctl helper routine for kern.defcorename.  in the case of a new
 1301  * string being assigned, check that it's not a zero-length string.
 1302  * (XXX the check in -current doesn't work, but do we really care?)
 1303  */
 1304 static int
 1305 sysctl_kern_defcorename(SYSCTLFN_ARGS)
 1306 {
 1307         int error;
 1308         char newcorename[MAXPATHLEN];
 1309         struct sysctlnode node;
 1310 
 1311         node = *rnode;
 1312         node.sysctl_data = &newcorename[0];
 1313         memcpy(node.sysctl_data, rnode->sysctl_data, MAXPATHLEN);
 1314         error = sysctl_lookup(SYSCTLFN_CALL(&node));
 1315         if (error || newp == NULL)
 1316                 return (error);
 1317 
 1318         /*
 1319          * when sysctl_lookup() deals with a string, it's guaranteed
 1320          * to come back nul terminated.  so there.  :)
 1321          */
 1322         if (strlen(newcorename) == 0)
 1323                 return (EINVAL);
 1324 
 1325         memcpy(rnode->sysctl_data, node.sysctl_data, MAXPATHLEN);
 1326 
 1327         return (0);
 1328 }
 1329 
 1330 /*
 1331  * sysctl helper routine for kern.cp_time node.  adds up cpu time
 1332  * across all cpus.
 1333  */
 1334 static int
 1335 sysctl_kern_cptime(SYSCTLFN_ARGS)
 1336 {
 1337         struct sysctlnode node = *rnode;
 1338 
 1339 #ifndef MULTIPROCESSOR
 1340 
 1341         if (namelen == 1) {
 1342                 if (name[0] != 0)
 1343                         return (ENOENT);
 1344                 /*
 1345                  * you're allowed to ask for the zero'th processor
 1346                  */
 1347                 name++;
 1348                 namelen--;
 1349         }
 1350         node.sysctl_data = curcpu()->ci_schedstate.spc_cp_time;
 1351         node.sysctl_size = sizeof(curcpu()->ci_schedstate.spc_cp_time);
 1352         return (sysctl_lookup(SYSCTLFN_CALL(&node)));
 1353 
 1354 #else /* MULTIPROCESSOR */
 1355 
 1356         u_int64_t *cp_time = NULL;
 1357         int error, n = sysctl_ncpus(), i;
 1358         struct cpu_info *ci;
 1359         CPU_INFO_ITERATOR cii;
 1360 
 1361         /*
 1362          * if you specifically pass a buffer that is the size of the
 1363          * sum, or if you are probing for the size, you get the "sum"
 1364          * of cp_time (and the size thereof) across all processors.
 1365          *
 1366          * alternately, you can pass an additional mib number and get
 1367          * cp_time for that particular processor.
 1368          */
 1369         switch (namelen) {
 1370         case 0:
 1371                 if (*oldlenp == sizeof(u_int64_t) * CPUSTATES || oldp == NULL) {
 1372                         node.sysctl_size = sizeof(u_int64_t) * CPUSTATES;
 1373                         n = -1; /* SUM */
 1374                 }
 1375                 else {
 1376                         node.sysctl_size = n * sizeof(u_int64_t) * CPUSTATES;
 1377                         n = -2; /* ALL */
 1378                 }
 1379                 break;
 1380         case 1:
 1381                 if (name[0] < 0 || name[0] >= n)
 1382                         return (ENOENT); /* ENOSUCHPROCESSOR */
 1383                 node.sysctl_size = sizeof(u_int64_t) * CPUSTATES;
 1384                 n = name[0];
 1385                 /*
 1386                  * adjust these so that sysctl_lookup() will be happy
 1387                  */
 1388                 name++;
 1389                 namelen--;
 1390                 break;
 1391         default:
 1392                 return (EINVAL);
 1393         }
 1394 
 1395         cp_time = malloc(node.sysctl_size, M_TEMP, M_WAITOK|M_CANFAIL);
 1396         if (cp_time == NULL)
 1397                 return (ENOMEM);
 1398         node.sysctl_data = cp_time;
 1399         memset(cp_time, 0, node.sysctl_size);
 1400 
 1401         for (CPU_INFO_FOREACH(cii, ci)) {
 1402                 if (n <= 0)
 1403                         for (i = 0; i < CPUSTATES; i++)
 1404                                 cp_time[i] += ci->ci_schedstate.spc_cp_time[i];
 1405                 /*
 1406                  * if a specific processor was requested and we just
 1407                  * did it, we're done here
 1408                  */
 1409                 if (n == 0)
 1410                         break;
 1411                 /*
 1412                  * if doing "all", skip to next cp_time set for next processor
 1413                  */
 1414                 if (n == -2)
 1415                         cp_time += CPUSTATES;
 1416                 /*
 1417                  * if we're doing a specific processor, we're one
 1418                  * processor closer
 1419                  */
 1420                 if (n > 0)
 1421                         n--;
 1422         }
 1423 
 1424         error = sysctl_lookup(SYSCTLFN_CALL(&node));
 1425         free(node.sysctl_data, M_TEMP);
 1426         return (error);
 1427 
 1428 #endif /* MULTIPROCESSOR */
 1429 }
 1430 
 1431 #if defined(SYSVMSG) || defined(SYSVSEM) || defined(SYSVSHM)
 1432 /*
 1433  * sysctl helper routine for kern.sysvipc_info subtree.
 1434  */
 1435 
 1436 #define FILL_PERM(src, dst) do { \
 1437         (dst)._key = (src)._key; \
 1438         (dst).uid = (src).uid; \
 1439         (dst).gid = (src).gid; \
 1440         (dst).cuid = (src).cuid; \
 1441         (dst).cgid = (src).cgid; \
 1442         (dst).mode = (src).mode; \
 1443         (dst)._seq = (src)._seq; \
 1444 } while (/*CONSTCOND*/ 0);
 1445 #define FILL_MSG(src, dst) do { \
 1446         FILL_PERM((src).msg_perm, (dst).msg_perm); \
 1447         (dst).msg_qnum = (src).msg_qnum; \
 1448         (dst).msg_qbytes = (src).msg_qbytes; \
 1449         (dst)._msg_cbytes = (src)._msg_cbytes; \
 1450         (dst).msg_lspid = (src).msg_lspid; \
 1451         (dst).msg_lrpid = (src).msg_lrpid; \
 1452         (dst).msg_stime = (src).msg_stime; \
 1453         (dst).msg_rtime = (src).msg_rtime; \
 1454         (dst).msg_ctime = (src).msg_ctime; \
 1455 } while (/*CONSTCOND*/ 0)
 1456 #define FILL_SEM(src, dst) do { \
 1457         FILL_PERM((src).sem_perm, (dst).sem_perm); \
 1458         (dst).sem_nsems = (src).sem_nsems; \
 1459         (dst).sem_otime = (src).sem_otime; \
 1460         (dst).sem_ctime = (src).sem_ctime; \
 1461 } while (/*CONSTCOND*/ 0)
 1462 #define FILL_SHM(src, dst) do { \
 1463         FILL_PERM((src).shm_perm, (dst).shm_perm); \
 1464         (dst).shm_segsz = (src).shm_segsz; \
 1465         (dst).shm_lpid = (src).shm_lpid; \
 1466         (dst).shm_cpid = (src).shm_cpid; \
 1467         (dst).shm_atime = (src).shm_atime; \
 1468         (dst).shm_dtime = (src).shm_dtime; \
 1469         (dst).shm_ctime = (src).shm_ctime; \
 1470         (dst).shm_nattch = (src).shm_nattch; \
 1471 } while (/*CONSTCOND*/ 0)
 1472 
 1473 static int
 1474 sysctl_kern_sysvipc(SYSCTLFN_ARGS)
 1475 {
 1476         void *where = oldp;
 1477         size_t *sizep = oldlenp;
 1478 #ifdef SYSVMSG
 1479         struct msg_sysctl_info *msgsi = NULL;
 1480 #endif
 1481 #ifdef SYSVSEM
 1482         struct sem_sysctl_info *semsi = NULL;
 1483 #endif
 1484 #ifdef SYSVSHM
 1485         struct shm_sysctl_info *shmsi = NULL;
 1486 #endif
 1487         size_t infosize, dssize, tsize, buflen;
 1488         void *buf = NULL;
 1489         char *start;
 1490         int32_t nds;
 1491         int i, error, ret;
 1492 
 1493         if (namelen != 1)
 1494                 return (EINVAL);
 1495 
 1496         start = where;
 1497         buflen = *sizep;
 1498 
 1499         switch (*name) {
 1500         case KERN_SYSVIPC_MSG_INFO:
 1501 #ifdef SYSVMSG
 1502                 infosize = sizeof(msgsi->msginfo);
 1503                 nds = msginfo.msgmni;
 1504                 dssize = sizeof(msgsi->msgids[0]);
 1505                 break;
 1506 #else
 1507                 return (EINVAL);
 1508 #endif
 1509         case KERN_SYSVIPC_SEM_INFO:
 1510 #ifdef SYSVSEM
 1511                 infosize = sizeof(semsi->seminfo);
 1512                 nds = seminfo.semmni;
 1513                 dssize = sizeof(semsi->semids[0]);
 1514                 break;
 1515 #else
 1516                 return (EINVAL);
 1517 #endif
 1518         case KERN_SYSVIPC_SHM_INFO:
 1519 #ifdef SYSVSHM
 1520                 infosize = sizeof(shmsi->shminfo);
 1521                 nds = shminfo.shmmni;
 1522                 dssize = sizeof(shmsi->shmids[0]);
 1523                 break;
 1524 #else
 1525                 return (EINVAL);
 1526 #endif
 1527         default:
 1528                 return (EINVAL);
 1529         }
 1530         /*
 1531          * Round infosize to 64 bit boundary if requesting more than just
 1532          * the info structure or getting the total data size.
 1533          */
 1534         if (where == NULL || *sizep > infosize)
 1535                 infosize = ((infosize + 7) / 8) * 8;
 1536         tsize = infosize + nds * dssize;
 1537 
 1538         /* Return just the total size required. */
 1539         if (where == NULL) {
 1540                 *sizep = tsize;
 1541                 return (0);
 1542         }
 1543 
 1544         /* Not enough room for even the info struct. */
 1545         if (buflen < infosize) {
 1546                 *sizep = 0;
 1547                 return (ENOMEM);
 1548         }
 1549         buf = malloc(min(tsize, buflen), M_TEMP, M_WAITOK);
 1550         memset(buf, 0, min(tsize, buflen));
 1551 
 1552         switch (*name) {
 1553 #ifdef SYSVMSG
 1554         case KERN_SYSVIPC_MSG_INFO:
 1555                 msgsi = (struct msg_sysctl_info *)buf;
 1556                 msgsi->msginfo = msginfo;
 1557                 break;
 1558 #endif
 1559 #ifdef SYSVSEM
 1560         case KERN_SYSVIPC_SEM_INFO:
 1561                 semsi = (struct sem_sysctl_info *)buf;
 1562                 semsi->seminfo = seminfo;
 1563                 break;
 1564 #endif
 1565 #ifdef SYSVSHM
 1566         case KERN_SYSVIPC_SHM_INFO:
 1567                 shmsi = (struct shm_sysctl_info *)buf;
 1568                 shmsi->shminfo = shminfo;
 1569                 break;
 1570 #endif
 1571         }
 1572         buflen -= infosize;
 1573 
 1574         ret = 0;
 1575         if (buflen > 0) {
 1576                 /* Fill in the IPC data structures.  */
 1577                 for (i = 0; i < nds; i++) {
 1578                         if (buflen < dssize) {
 1579                                 ret = ENOMEM;
 1580                                 break;
 1581                         }
 1582                         switch (*name) {
 1583 #ifdef SYSVMSG
 1584                         case KERN_SYSVIPC_MSG_INFO:
 1585                                 FILL_MSG(msqids[i], msgsi->msgids[i]);
 1586                                 break;
 1587 #endif
 1588 #ifdef SYSVSEM
 1589                         case KERN_SYSVIPC_SEM_INFO:
 1590                                 FILL_SEM(sema[i], semsi->semids[i]);
 1591                                 break;
 1592 #endif
 1593 #ifdef SYSVSHM
 1594                         case KERN_SYSVIPC_SHM_INFO:
 1595                                 FILL_SHM(shmsegs[i], shmsi->shmids[i]);
 1596                                 break;
 1597 #endif
 1598                         }
 1599                         buflen -= dssize;
 1600                 }
 1601         }
 1602         *sizep -= buflen;
 1603         error = copyout(buf, start, *sizep);
 1604         /* If copyout succeeded, use return code set earlier. */
 1605         if (error == 0)
 1606                 error = ret;
 1607         if (buf)
 1608                 free(buf, M_TEMP);
 1609         return (error);
 1610 }
 1611 
 1612 #undef FILL_PERM
 1613 #undef FILL_MSG
 1614 #undef FILL_SEM
 1615 #undef FILL_SHM
 1616 
 1617 #endif /* defined(SYSVMSG) || defined(SYSVSEM) || defined(SYSVSHM) */
 1618 
 1619 #if NPTY > 0
 1620 /*
 1621  * sysctl helper routine for kern.maxptys.  ensures that any new value
 1622  * is acceptable to the pty subsystem.
 1623  */
 1624 static int
 1625 sysctl_kern_maxptys(SYSCTLFN_ARGS)
 1626 {
 1627         int pty_maxptys(int, int);              /* defined in kern/tty_pty.c */
 1628         int error, max;
 1629         struct sysctlnode node;
 1630 
 1631         /* get current value of maxptys */
 1632         max = pty_maxptys(0, 0);
 1633 
 1634         node = *rnode;
 1635         node.sysctl_data = &max;
 1636         error = sysctl_lookup(SYSCTLFN_CALL(&node));
 1637         if (error || newp == NULL)
 1638                 return (error);
 1639         
 1640         if (max != pty_maxptys(max, 1))
 1641                 return (EINVAL);
 1642 
 1643         return (0);
 1644 }
 1645 #endif /* NPTY > 0 */
 1646 
 1647 /*
 1648  * sysctl helper routine for kern.sbmax.  basically just ensures that
 1649  * any new value is not too small.
 1650  */
 1651 static int
 1652 sysctl_kern_sbmax(SYSCTLFN_ARGS)
 1653 {
 1654         int error, new_sbmax;
 1655         struct sysctlnode node;
 1656 
 1657         new_sbmax = sb_max;
 1658         node = *rnode;
 1659         node.sysctl_data = &new_sbmax;
 1660         error = sysctl_lookup(SYSCTLFN_CALL(&node));
 1661         if (error || newp == NULL)
 1662                 return (error);
 1663 
 1664         error = sb_max_set(new_sbmax);
 1665 
 1666         return (error);
 1667 }
 1668 
 1669 /*
 1670  * sysctl helper routine for kern.urandom node.  picks a random number
 1671  * for you.
 1672  */
 1673 static int
 1674 sysctl_kern_urnd(SYSCTLFN_ARGS)
 1675 {
 1676 #if NRND > 0
 1677         int v;
 1678 
 1679         if (rnd_extract_data(&v, sizeof(v), RND_EXTRACT_ANY) == sizeof(v)) {
 1680                 struct sysctlnode node = *rnode;
 1681                 node.sysctl_data = &v;
 1682                 return (sysctl_lookup(SYSCTLFN_CALL(&node)));
 1683         }
 1684         else
 1685                 return (EIO);   /*XXX*/
 1686 #else
 1687         return (EOPNOTSUPP);
 1688 #endif
 1689 }
 1690 
 1691 /*
 1692  * sysctl helper routine to do kern.lwp.* work.
 1693  */
 1694 static int
 1695 sysctl_kern_lwp(SYSCTLFN_ARGS)
 1696 {
 1697         struct kinfo_lwp klwp;
 1698         struct proc *p;
 1699         struct lwp *l2;
 1700         char *where, *dp;
 1701         int pid, elem_size, elem_count;
 1702         int buflen, needed, error;
 1703 
 1704         if (namelen == 1 && name[0] == CTL_QUERY)
 1705                 return (sysctl_query(SYSCTLFN_CALL(rnode)));
 1706 
 1707         dp = where = oldp;
 1708         buflen = where != NULL ? *oldlenp : 0;
 1709         error = needed = 0;
 1710 
 1711         if (newp != NULL || namelen != 3)
 1712                 return (EINVAL);
 1713         pid = name[0];
 1714         elem_size = name[1];
 1715         elem_count = name[2];
 1716 
 1717         p = pfind(pid);
 1718         if (p == NULL)
 1719                 return (ESRCH);
 1720         LIST_FOREACH(l2, &p->p_lwps, l_sibling) {
 1721                 if (buflen >= elem_size && elem_count > 0) {
 1722                         fill_lwp(l2, &klwp);
 1723                         /*
 1724                          * Copy out elem_size, but not larger than
 1725                          * the size of a struct kinfo_proc2.
 1726                          */
 1727                         error = copyout(&klwp, dp,
 1728                             min(sizeof(klwp), elem_size));
 1729                         if (error)
 1730                                 goto cleanup;
 1731                         dp += elem_size;
 1732                         buflen -= elem_size;
 1733                         elem_count--;
 1734                 }
 1735                 needed += elem_size;
 1736         }
 1737 
 1738         if (where != NULL) {
 1739                 *oldlenp = dp - where;
 1740                 if (needed > *oldlenp)
 1741                         return (ENOMEM);
 1742         } else {
 1743                 needed += KERN_LWPSLOP;
 1744                 *oldlenp = needed;
 1745         }
 1746         return (0);
 1747  cleanup:
 1748         return (error);
 1749 }
 1750 
 1751 /*
 1752  * sysctl helper routine for kern.forkfsleep node.  ensures that the
 1753  * given value is not too large or two small, and is at least one
 1754  * timer tick if not zero.
 1755  */
 1756 static int
 1757 sysctl_kern_forkfsleep(SYSCTLFN_ARGS)
 1758 {
 1759         /* userland sees value in ms, internally is in ticks */
 1760         extern int forkfsleep;          /* defined in kern/kern_fork.c */
 1761         int error, timo, lsleep;
 1762         struct sysctlnode node;
 1763 
 1764         lsleep = forkfsleep * 1000 / hz;
 1765         node = *rnode;
 1766         node.sysctl_data = &lsleep;
 1767         error = sysctl_lookup(SYSCTLFN_CALL(&node));
 1768         if (error || newp == NULL)
 1769                 return (error);
 1770 
 1771         /* refuse negative values, and overly 'long time' */
 1772         if (lsleep < 0 || lsleep > MAXSLP * 1000)
 1773                 return (EINVAL);
 1774 
 1775         timo = mstohz(lsleep);
 1776 
 1777         /* if the interval is >0 ms && <1 tick, use 1 tick */
 1778         if (lsleep != 0 && timo == 0)
 1779                 forkfsleep = 1;
 1780         else
 1781                 forkfsleep = timo;
 1782 
 1783         return (0);
 1784 }
 1785 
 1786 /*
 1787  * sysctl helper routine for kern.root_partition
 1788  */
 1789 static int
 1790 sysctl_kern_root_partition(SYSCTLFN_ARGS)
 1791 {
 1792         int rootpart = DISKPART(rootdev);
 1793         struct sysctlnode node = *rnode;
 1794 
 1795         node.sysctl_data = &rootpart;
 1796         return (sysctl_lookup(SYSCTLFN_CALL(&node)));
 1797 }
 1798 
 1799 /*
 1800  * sysctl helper function for kern.drivers
 1801  */
 1802 static int
 1803 sysctl_kern_drivers(SYSCTLFN_ARGS)
 1804 {
 1805         int error;
 1806         size_t buflen;
 1807         struct kinfo_drivers kd;
 1808         char *start, *where;
 1809         const char *dname;
 1810         int i;
 1811         extern struct devsw_conv *devsw_conv;
 1812         extern int max_devsw_convs;
 1813 
 1814         if (newp != NULL || namelen != 0)
 1815                 return (EINVAL);
 1816 
 1817         start = where = oldp;
 1818         buflen = *oldlenp;
 1819         if (where == NULL) {
 1820                 *oldlenp = max_devsw_convs * sizeof kd;
 1821                 return 0;
 1822         }
 1823 
 1824         /*
 1825          * An array of kinfo_drivers structures
 1826          */
 1827         error = 0;
 1828         for (i = 0; i < max_devsw_convs; i++) {
 1829                 dname = devsw_conv[i].d_name;
 1830                 if (dname == NULL)
 1831                         continue;
 1832                 if (buflen < sizeof kd) {
 1833                         error = ENOMEM;
 1834                         break;
 1835                 }
 1836                 memset(&kd, 0, sizeof(kd));
 1837                 kd.d_bmajor = devsw_conv[i].d_bmajor;
 1838                 kd.d_cmajor = devsw_conv[i].d_cmajor;
 1839                 strlcpy(kd.d_name, dname, sizeof kd.d_name);
 1840                 error = copyout(&kd, where, sizeof kd);
 1841                 if (error != 0)
 1842                         break;
 1843                 buflen -= sizeof kd;
 1844                 where += sizeof kd;
 1845         }
 1846         *oldlenp = where - start;
 1847         return error;
 1848 }
 1849 
 1850 static int
 1851 sysctl_doeproc(SYSCTLFN_ARGS)
 1852 {
 1853         struct eproc eproc;
 1854         struct kinfo_proc2 kproc2;
 1855         struct kinfo_proc *dp;
 1856         struct proc *p;
 1857         const struct proclist_desc *pd;
 1858         char *where, *dp2;
 1859         int type, op, arg;
 1860         u_int elem_size, elem_count;
 1861         size_t buflen, needed;
 1862         int error;
 1863 
 1864         if (namelen == 1 && name[0] == CTL_QUERY)
 1865                 return (sysctl_query(SYSCTLFN_CALL(rnode)));
 1866 
 1867         dp = oldp;
 1868         dp2 = where = oldp;
 1869         buflen = where != NULL ? *oldlenp : 0;
 1870         error = 0;
 1871         needed = 0;
 1872         type = rnode->sysctl_num;
 1873 
 1874         if (type == KERN_PROC) {
 1875                 if (namelen != 2 && !(namelen == 1 && name[0] == KERN_PROC_ALL))
 1876                         return (EINVAL);
 1877                 op = name[0];
 1878                 if (op != KERN_PROC_ALL)
 1879                         arg = name[1];
 1880                 else
 1881                         arg = 0;                /* Quell compiler warning */
 1882                 elem_size = elem_count = 0;     /* Ditto */
 1883         } else {
 1884                 if (namelen != 4)
 1885                         return (EINVAL);
 1886                 op = name[0];
 1887                 arg = name[1];
 1888                 elem_size = name[2];
 1889                 elem_count = name[3];
 1890         }
 1891 
 1892         proclist_lock_read();
 1893 
 1894         pd = proclists;
 1895 again:
 1896         for (p = LIST_FIRST(pd->pd_list); p != NULL; p = LIST_NEXT(p, p_list)) {
 1897                 /*
 1898                  * Skip embryonic processes.
 1899                  */
 1900                 if (p->p_stat == SIDL)
 1901                         continue;
 1902                 /*
 1903                  * TODO - make more efficient (see notes below).
 1904                  * do by session.
 1905                  */
 1906                 switch (op) {
 1907 
 1908                 case KERN_PROC_PID:
 1909                         /* could do this with just a lookup */
 1910                         if (p->p_pid != (pid_t)arg)
 1911                                 continue;
 1912                         break;
 1913 
 1914                 case KERN_PROC_PGRP:
 1915                         /* could do this by traversing pgrp */
 1916                         if (p->p_pgrp->pg_id != (pid_t)arg)
 1917                                 continue;
 1918                         break;
 1919 
 1920                 case KERN_PROC_SESSION:
 1921                         if (p->p_session->s_sid != (pid_t)arg)
 1922                                 continue;
 1923                         break;
 1924 
 1925                 case KERN_PROC_TTY:
 1926                         if (arg == (int) KERN_PROC_TTY_REVOKE) {
 1927                                 if ((p->p_flag & P_CONTROLT) == 0 ||
 1928                                     p->p_session->s_ttyp == NULL ||
 1929                                     p->p_session->s_ttyvp != NULL)
 1930                                         continue;
 1931                         } else if ((p->p_flag & P_CONTROLT) == 0 ||
 1932                             p->p_session->s_ttyp == NULL) {
 1933                                 if ((dev_t)arg != KERN_PROC_TTY_NODEV)
 1934                                         continue;
 1935                         } else if (p->p_session->s_ttyp->t_dev != (dev_t)arg)
 1936                                 continue;
 1937                         break;
 1938 
 1939                 case KERN_PROC_UID:
 1940                         if (p->p_ucred->cr_uid != (uid_t)arg)
 1941                                 continue;
 1942                         break;
 1943 
 1944                 case KERN_PROC_RUID:
 1945                         if (p->p_cred->p_ruid != (uid_t)arg)
 1946                                 continue;
 1947                         break;
 1948 
 1949                 case KERN_PROC_GID:
 1950                         if (p->p_ucred->cr_gid != (uid_t)arg)
 1951                                 continue;
 1952                         break;
 1953 
 1954                 case KERN_PROC_RGID:
 1955                         if (p->p_cred->p_rgid != (uid_t)arg)
 1956                                 continue;
 1957                         break;
 1958 
 1959                 case KERN_PROC_ALL:
 1960                         /* allow everything */
 1961                         break;
 1962 
 1963                 default:
 1964                         error = EINVAL;
 1965                         goto cleanup;
 1966                 }
 1967                 if (type == KERN_PROC) {
 1968                         if (buflen >= sizeof(struct kinfo_proc)) {
 1969                                 fill_eproc(p, &eproc);
 1970                                 error = copyout(p, &dp->kp_proc,
 1971                                     sizeof(struct proc));
 1972                                 if (error)
 1973                                         goto cleanup;
 1974                                 error = copyout(&eproc, &dp->kp_eproc,
 1975                                     sizeof(eproc));
 1976                                 if (error)
 1977                                         goto cleanup;
 1978                                 dp++;
 1979                                 buflen -= sizeof(struct kinfo_proc);
 1980                         }
 1981                         needed += sizeof(struct kinfo_proc);
 1982                 } else { /* KERN_PROC2 */
 1983                         if (buflen >= elem_size && elem_count > 0) {
 1984                                 fill_kproc2(p, &kproc2);
 1985                                 /*
 1986                                  * Copy out elem_size, but not larger than
 1987                                  * the size of a struct kinfo_proc2.
 1988                                  */
 1989                                 error = copyout(&kproc2, dp2,
 1990                                     min(sizeof(kproc2), elem_size));
 1991                                 if (error)
 1992                                         goto cleanup;
 1993                                 dp2 += elem_size;
 1994                                 buflen -= elem_size;
 1995                                 elem_count--;
 1996                         }
 1997                         needed += elem_size;
 1998                 }
 1999         }
 2000         pd++;
 2001         if (pd->pd_list != NULL)
 2002                 goto again;
 2003         proclist_unlock_read();
 2004 
 2005         if (where != NULL) {
 2006                 if (type == KERN_PROC)
 2007                         *oldlenp = (char *)dp - where;
 2008                 else
 2009                         *oldlenp = dp2 - where;
 2010                 if (needed > *oldlenp)
 2011                         return (ENOMEM);
 2012         } else {
 2013                 needed += KERN_PROCSLOP;
 2014                 *oldlenp = needed;
 2015         }
 2016         return (0);
 2017  cleanup:
 2018         proclist_unlock_read();
 2019         return (error);
 2020 }
 2021 
 2022 /*
 2023  * sysctl helper routine for kern.proc_args pseudo-subtree.
 2024  */
 2025 static int
 2026 sysctl_kern_proc_args(SYSCTLFN_ARGS)
 2027 {
 2028         struct ps_strings pss;
 2029         struct proc *p, *up = l->l_proc;
 2030         size_t len, upper_bound, xlen, i;
 2031         struct uio auio;
 2032         struct iovec aiov;
 2033         vaddr_t argv;
 2034         pid_t pid;
 2035         int nargv, type, error;
 2036         char *arg;
 2037         char *tmp;
 2038 
 2039         if (namelen == 1 && name[0] == CTL_QUERY)
 2040                 return (sysctl_query(SYSCTLFN_CALL(rnode)));
 2041 
 2042         if (newp != NULL || namelen != 2)
 2043                 return (EINVAL);
 2044         pid = name[0];
 2045         type = name[1];
 2046 
 2047         switch (type) {
 2048         case KERN_PROC_ARGV:
 2049         case KERN_PROC_NARGV:
 2050         case KERN_PROC_ENV:
 2051         case KERN_PROC_NENV:
 2052                 /* ok */
 2053                 break;
 2054         default:
 2055                 return (EINVAL);
 2056         }
 2057 
 2058         /* check pid */
 2059         if ((p = pfind(pid)) == NULL)
 2060                 return (EINVAL);
 2061 
 2062         /* only root or same user change look at the environment */
 2063         if (type == KERN_PROC_ENV || type == KERN_PROC_NENV) {
 2064                 if (up->p_ucred->cr_uid != 0) {
 2065                         if (up->p_cred->p_ruid != p->p_cred->p_ruid ||
 2066                             up->p_cred->p_ruid != p->p_cred->p_svuid)
 2067                                 return (EPERM);
 2068                 }
 2069         }
 2070 
 2071         if (oldp == NULL) {
 2072                 if (type == KERN_PROC_NARGV || type == KERN_PROC_NENV)
 2073                         *oldlenp = sizeof (int);
 2074                 else
 2075                         *oldlenp = ARG_MAX;     /* XXX XXX XXX */
 2076                 return (0);
 2077         }
 2078 
 2079         /*
 2080          * Zombies don't have a stack, so we can't read their psstrings.
 2081          * System processes also don't have a user stack.
 2082          */
 2083         if (P_ZOMBIE(p) || (p->p_flag & P_SYSTEM) != 0)
 2084                 return (EINVAL);
 2085 
 2086         /*
 2087          * Lock the process down in memory.
 2088          */
 2089         /* XXXCDC: how should locking work here? */
 2090         if ((p->p_flag & P_WEXIT) || (p->p_vmspace->vm_refcnt < 1))
 2091                 return (EFAULT);
 2092 
 2093         p->p_vmspace->vm_refcnt++;      /* XXX */
 2094 
 2095         /*
 2096          * Allocate a temporary buffer to hold the arguments.
 2097          */
 2098         arg = malloc(PAGE_SIZE, M_TEMP, M_WAITOK);
 2099 
 2100         /*
 2101          * Read in the ps_strings structure.
 2102          */
 2103         aiov.iov_base = &pss;
 2104         aiov.iov_len = sizeof(pss);
 2105         auio.uio_iov = &aiov;
 2106         auio.uio_iovcnt = 1;
 2107         auio.uio_offset = (vaddr_t)p->p_psstr;
 2108         auio.uio_resid = sizeof(pss);
 2109         auio.uio_segflg = UIO_SYSSPACE;
 2110         auio.uio_rw = UIO_READ;
 2111         auio.uio_procp = NULL;
 2112         error = uvm_io(&p->p_vmspace->vm_map, &auio);
 2113         if (error)
 2114                 goto done;
 2115 
 2116         if (type == KERN_PROC_ARGV || type == KERN_PROC_NARGV)
 2117                 memcpy(&nargv, (char *)&pss + p->p_psnargv, sizeof(nargv));
 2118         else
 2119                 memcpy(&nargv, (char *)&pss + p->p_psnenv, sizeof(nargv));
 2120         if (type == KERN_PROC_NARGV || type == KERN_PROC_NENV) {
 2121                 error = copyout(&nargv, oldp, sizeof(nargv));
 2122                 *oldlenp = sizeof(nargv);
 2123                 goto done;
 2124         }
 2125         /*
 2126          * Now read the address of the argument vector.
 2127          */
 2128         switch (type) {
 2129         case KERN_PROC_ARGV:
 2130                 /* XXX compat32 stuff here */
 2131                 memcpy(&tmp, (char *)&pss + p->p_psargv, sizeof(tmp));
 2132                 break;
 2133         case KERN_PROC_ENV:
 2134                 memcpy(&tmp, (char *)&pss + p->p_psenv, sizeof(tmp));
 2135                 break;
 2136         default:
 2137                 return (EINVAL);
 2138         }
 2139         auio.uio_offset = (off_t)(long)tmp;
 2140         aiov.iov_base = &argv;
 2141         aiov.iov_len = sizeof(argv);
 2142         auio.uio_iov = &aiov;
 2143         auio.uio_iovcnt = 1;
 2144         auio.uio_resid = sizeof(argv);
 2145         auio.uio_segflg = UIO_SYSSPACE;
 2146         auio.uio_rw = UIO_READ;
 2147         auio.uio_procp = NULL;
 2148         error = uvm_io(&p->p_vmspace->vm_map, &auio);
 2149         if (error)
 2150                 goto done;
 2151 
 2152         /*
 2153          * Now copy in the actual argument vector, one page at a time,
 2154          * since we don't know how long the vector is (though, we do
 2155          * know how many NUL-terminated strings are in the vector).
 2156          */
 2157         len = 0;
 2158         upper_bound = *oldlenp;
 2159         for (; nargv != 0 && len < upper_bound; len += xlen) {
 2160                 aiov.iov_base = arg;
 2161                 aiov.iov_len = PAGE_SIZE;
 2162                 auio.uio_iov = &aiov;
 2163                 auio.uio_iovcnt = 1;
 2164                 auio.uio_offset = argv + len;
 2165                 xlen = PAGE_SIZE - ((argv + len) & PAGE_MASK);
 2166                 auio.uio_resid = xlen;
 2167                 auio.uio_segflg = UIO_SYSSPACE;
 2168                 auio.uio_rw = UIO_READ;
 2169                 auio.uio_procp = NULL;
 2170                 error = uvm_io(&p->p_vmspace->vm_map, &auio);
 2171                 if (error)
 2172                         goto done;
 2173 
 2174                 for (i = 0; i < xlen && nargv != 0; i++) {
 2175                         if (arg[i] == '\0')
 2176                                 nargv--;        /* one full string */
 2177                 }
 2178 
 2179                 /*
 2180                  * Make sure we don't copyout past the end of the user's
 2181                  * buffer.
 2182                  */
 2183                 if (len + i > upper_bound)
 2184                         i = upper_bound - len;
 2185 
 2186                 error = copyout(arg, (char *)oldp + len, i);
 2187                 if (error)
 2188                         break;
 2189 
 2190                 if (nargv == 0) {
 2191                         len += i;
 2192                         break;
 2193                 }
 2194         }
 2195         *oldlenp = len;
 2196 
 2197 done:
 2198         uvmspace_free(p->p_vmspace);
 2199 
 2200         free(arg, M_TEMP);
 2201         return (error);
 2202 }
 2203 
 2204 /*
 2205  * sysctl helper routine for hw.usermem and hw.usermem64.  values are
 2206  * calculate on the fly taking into account integer overflow and the
 2207  * current wired count.
 2208  */
 2209 static int
 2210 sysctl_hw_usermem(SYSCTLFN_ARGS)
 2211 {
 2212         u_int ui;
 2213         u_quad_t uq;
 2214         struct sysctlnode node;
 2215 
 2216         node = *rnode;
 2217         switch (rnode->sysctl_num) {
 2218             case HW_USERMEM:
 2219                 if ((ui = physmem - uvmexp.wired) > (UINT_MAX / PAGE_SIZE))
 2220                         ui = UINT_MAX;
 2221                 else
 2222                         ui *= PAGE_SIZE;
 2223                 node.sysctl_data = &ui;
 2224                 break;
 2225         case HW_USERMEM64:
 2226                 uq = (u_quad_t)(physmem - uvmexp.wired) * PAGE_SIZE;
 2227                 node.sysctl_data = &uq;
 2228                 break;
 2229         default:
 2230                 return (EINVAL);
 2231         }
 2232 
 2233         return (sysctl_lookup(SYSCTLFN_CALL(&node)));
 2234 }
 2235 
 2236 /*
 2237  * sysctl helper routine for kern.cnmagic node.  pulls the old value
 2238  * out, encoded, and stuffs the new value in for decoding.
 2239  */
 2240 static int
 2241 sysctl_hw_cnmagic(SYSCTLFN_ARGS)
 2242 {
 2243         char magic[CNS_LEN];
 2244         int error;
 2245         struct sysctlnode node;
 2246 
 2247         if (oldp)
 2248                 cn_get_magic(magic, CNS_LEN);
 2249         node = *rnode;
 2250         node.sysctl_data = &magic[0];
 2251         error = sysctl_lookup(SYSCTLFN_CALL(&node));
 2252         if (error || newp == NULL)
 2253                 return (error);
 2254         
 2255         return (cn_set_magic(magic));
 2256 }
 2257 
 2258 static int
 2259 sysctl_hw_ncpu(SYSCTLFN_ARGS)
 2260 {
 2261         int ncpu;
 2262         struct sysctlnode node;
 2263 
 2264         ncpu = sysctl_ncpus();
 2265         node = *rnode;
 2266         node.sysctl_data = &ncpu;
 2267         
 2268         return (sysctl_lookup(SYSCTLFN_CALL(&node)));
 2269 }
 2270 
 2271 
 2272 /*
 2273  * ********************************************************************
 2274  * section 3: public helper routines that are used for more than one
 2275  * node
 2276  * ********************************************************************
 2277  */
 2278 
 2279 /*
 2280  * sysctl helper routine for the kern.root_device node and some ports'
 2281  * machdep.root_device nodes.
 2282  */
 2283 int
 2284 sysctl_root_device(SYSCTLFN_ARGS)
 2285 {
 2286         struct sysctlnode node;
 2287 
 2288         node = *rnode;
 2289         node.sysctl_data = root_device->dv_xname;
 2290         node.sysctl_size = strlen(root_device->dv_xname) + 1;
 2291         return (sysctl_lookup(SYSCTLFN_CALL(&node)));
 2292 }
 2293 
 2294 /*
 2295  * sysctl helper routine for kern.consdev, dependent on the current
 2296  * state of the console.  also used for machdep.console_device on some
 2297  * ports.
 2298  */
 2299 int
 2300 sysctl_consdev(SYSCTLFN_ARGS)
 2301 {
 2302         dev_t consdev;
 2303         struct sysctlnode node;
 2304 
 2305         if (cn_tab != NULL)
 2306                 consdev = cn_tab->cn_dev;
 2307         else
 2308                 consdev = NODEV;
 2309         node = *rnode;
 2310         node.sysctl_data = &consdev;
 2311         node.sysctl_size = sizeof(consdev);
 2312         return (sysctl_lookup(SYSCTLFN_CALL(&node)));
 2313 }
 2314 
 2315 /*
 2316  * ********************************************************************
 2317  * section 4: support for some helpers
 2318  * ********************************************************************
 2319  */
 2320 
 2321 /*
 2322  * Fill in a kinfo_proc2 structure for the specified process.
 2323  */
 2324 static void
 2325 fill_kproc2(struct proc *p, struct kinfo_proc2 *ki)
 2326 {
 2327         struct tty *tp;
 2328         struct lwp *l;
 2329         struct timeval ut, st;
 2330 
 2331         memset(ki, 0, sizeof(*ki));
 2332 
 2333         ki->p_paddr = PTRTOUINT64(p);
 2334         ki->p_fd = PTRTOUINT64(p->p_fd);
 2335         ki->p_cwdi = PTRTOUINT64(p->p_cwdi);
 2336         ki->p_stats = PTRTOUINT64(p->p_stats);
 2337         ki->p_limit = PTRTOUINT64(p->p_limit);
 2338         ki->p_vmspace = PTRTOUINT64(p->p_vmspace);
 2339         ki->p_sigacts = PTRTOUINT64(p->p_sigacts);
 2340         ki->p_sess = PTRTOUINT64(p->p_session);
 2341         ki->p_tsess = 0;        /* may be changed if controlling tty below */
 2342         ki->p_ru = PTRTOUINT64(p->p_ru);
 2343 
 2344         ki->p_eflag = 0;
 2345         ki->p_exitsig = p->p_exitsig;
 2346         ki->p_flag = p->p_flag;
 2347 
 2348         ki->p_pid = p->p_pid;
 2349         if (p->p_pptr)
 2350                 ki->p_ppid = p->p_pptr->p_pid;
 2351         else
 2352                 ki->p_ppid = 0;
 2353         ki->p_sid = p->p_session->s_sid;
 2354         ki->p__pgid = p->p_pgrp->pg_id;
 2355 
 2356         ki->p_tpgid = NO_PGID;  /* may be changed if controlling tty below */
 2357 
 2358         ki->p_uid = p->p_ucred->cr_uid;
 2359         ki->p_ruid = p->p_cred->p_ruid;
 2360         ki->p_gid = p->p_ucred->cr_gid;
 2361         ki->p_rgid = p->p_cred->p_rgid;
 2362         ki->p_svuid = p->p_cred->p_svuid;
 2363         ki->p_svgid = p->p_cred->p_svgid;
 2364 
 2365         memcpy(ki->p_groups, p->p_cred->pc_ucred->cr_groups,
 2366             min(sizeof(ki->p_groups), sizeof(p->p_cred->pc_ucred->cr_groups)));
 2367         ki->p_ngroups = p->p_cred->pc_ucred->cr_ngroups;
 2368 
 2369         ki->p_jobc = p->p_pgrp->pg_jobc;
 2370         if ((p->p_flag & P_CONTROLT) && (tp = p->p_session->s_ttyp)) {
 2371                 ki->p_tdev = tp->t_dev;
 2372                 ki->p_tpgid = tp->t_pgrp ? tp->t_pgrp->pg_id : NO_PGID;
 2373                 ki->p_tsess = PTRTOUINT64(tp->t_session);
 2374         } else {
 2375                 ki->p_tdev = NODEV;
 2376         }
 2377 
 2378         ki->p_estcpu = p->p_estcpu;
 2379         ki->p_rtime_sec = p->p_rtime.tv_sec;
 2380         ki->p_rtime_usec = p->p_rtime.tv_usec;
 2381         ki->p_cpticks = p->p_cpticks;
 2382         ki->p_pctcpu = p->p_pctcpu;
 2383 
 2384         ki->p_uticks = p->p_uticks;
 2385         ki->p_sticks = p->p_sticks;
 2386         ki->p_iticks = p->p_iticks;
 2387 
 2388         ki->p_tracep = PTRTOUINT64(p->p_tracep);
 2389         ki->p_traceflag = p->p_traceflag;
 2390 
 2391 
 2392         memcpy(&ki->p_siglist, &p->p_sigctx.ps_siglist, sizeof(ki_sigset_t));
 2393         memcpy(&ki->p_sigmask, &p->p_sigctx.ps_sigmask, sizeof(ki_sigset_t));
 2394         memcpy(&ki->p_sigignore, &p->p_sigctx.ps_sigignore,sizeof(ki_sigset_t));
 2395         memcpy(&ki->p_sigcatch, &p->p_sigctx.ps_sigcatch, sizeof(ki_sigset_t));
 2396 
 2397         ki->p_stat = p->p_stat; /* Will likely be overridden by LWP status */
 2398         ki->p_realstat = p->p_stat;
 2399         ki->p_nice = p->p_nice;
 2400 
 2401         ki->p_xstat = p->p_xstat;
 2402         ki->p_acflag = p->p_acflag;
 2403 
 2404         strncpy(ki->p_comm, p->p_comm,
 2405             min(sizeof(ki->p_comm), sizeof(p->p_comm)));
 2406 
 2407         strncpy(ki->p_login, p->p_session->s_login,
 2408             min(sizeof ki->p_login - 1, sizeof p->p_session->s_login));
 2409 
 2410         ki->p_nlwps = p->p_nlwps;
 2411         ki->p_nrlwps = p->p_nrlwps;
 2412         ki->p_realflag = p->p_flag;
 2413 
 2414         if (p->p_stat == SIDL || P_ZOMBIE(p)) {
 2415                 ki->p_vm_rssize = 0;
 2416                 ki->p_vm_tsize = 0;
 2417                 ki->p_vm_dsize = 0;
 2418                 ki->p_vm_ssize = 0;
 2419                 l = NULL;
 2420         } else {
 2421                 struct vmspace *vm = p->p_vmspace;
 2422 
 2423                 ki->p_vm_rssize = vm_resident_count(vm);
 2424                 ki->p_vm_tsize = vm->vm_tsize;
 2425                 ki->p_vm_dsize = vm->vm_dsize;
 2426                 ki->p_vm_ssize = vm->vm_ssize;
 2427 
 2428                 /* Pick a "representative" LWP */
 2429                 l = proc_representative_lwp(p);
 2430                 ki->p_forw = PTRTOUINT64(l->l_forw);
 2431                 ki->p_back = PTRTOUINT64(l->l_back);
 2432                 ki->p_addr = PTRTOUINT64(l->l_addr);
 2433                 ki->p_stat = l->l_stat;
 2434                 ki->p_flag |= l->l_flag;
 2435                 ki->p_swtime = l->l_swtime;
 2436                 ki->p_slptime = l->l_slptime;
 2437                 if (l->l_stat == LSONPROC) {
 2438                         KDASSERT(l->l_cpu != NULL);
 2439                         ki->p_schedflags = l->l_cpu->ci_schedstate.spc_flags;
 2440                 } else
 2441                         ki->p_schedflags = 0;
 2442                 ki->p_holdcnt = l->l_holdcnt;
 2443                 ki->p_priority = l->l_priority;
 2444                 ki->p_usrpri = l->l_usrpri;
 2445                 if (l->l_wmesg)
 2446                         strncpy(ki->p_wmesg, l->l_wmesg, sizeof(ki->p_wmesg));
 2447                 ki->p_wchan = PTRTOUINT64(l->l_wchan);
 2448 
 2449         }
 2450 
 2451         if (p->p_session->s_ttyvp)
 2452                 ki->p_eflag |= EPROC_CTTY;
 2453         if (SESS_LEADER(p))
 2454                 ki->p_eflag |= EPROC_SLEADER;
 2455 
 2456         /* XXX Is this double check necessary? */
 2457         if (P_ZOMBIE(p)) {
 2458                 ki->p_uvalid = 0;
 2459         } else {
 2460                 ki->p_uvalid = 1;
 2461 
 2462                 ki->p_ustart_sec = p->p_stats->p_start.tv_sec;
 2463                 ki->p_ustart_usec = p->p_stats->p_start.tv_usec;
 2464 
 2465                 calcru(p, &ut, &st, 0);
 2466                 ki->p_uutime_sec = ut.tv_sec;
 2467                 ki->p_uutime_usec = ut.tv_usec;
 2468                 ki->p_ustime_sec = st.tv_sec;
 2469                 ki->p_ustime_usec = st.tv_usec;
 2470 
 2471                 ki->p_uru_maxrss = p->p_stats->p_ru.ru_maxrss;
 2472                 ki->p_uru_ixrss = p->p_stats->p_ru.ru_ixrss;
 2473                 ki->p_uru_idrss = p->p_stats->p_ru.ru_idrss;
 2474                 ki->p_uru_isrss = p->p_stats->p_ru.ru_isrss;
 2475                 ki->p_uru_minflt = p->p_stats->p_ru.ru_minflt;
 2476                 ki->p_uru_majflt = p->p_stats->p_ru.ru_majflt;
 2477                 ki->p_uru_nswap = p->p_stats->p_ru.ru_nswap;
 2478                 ki->p_uru_inblock = p->p_stats->p_ru.ru_inblock;
 2479                 ki->p_uru_oublock = p->p_stats->p_ru.ru_oublock;
 2480                 ki->p_uru_msgsnd = p->p_stats->p_ru.ru_msgsnd;
 2481                 ki->p_uru_msgrcv = p->p_stats->p_ru.ru_msgrcv;
 2482                 ki->p_uru_nsignals = p->p_stats->p_ru.ru_nsignals;
 2483                 ki->p_uru_nvcsw = p->p_stats->p_ru.ru_nvcsw;
 2484                 ki->p_uru_nivcsw = p->p_stats->p_ru.ru_nivcsw;
 2485 
 2486                 timeradd(&p->p_stats->p_cru.ru_utime,
 2487                          &p->p_stats->p_cru.ru_stime, &ut);
 2488                 ki->p_uctime_sec = ut.tv_sec;
 2489                 ki->p_uctime_usec = ut.tv_usec;
 2490         }
 2491 #ifdef MULTIPROCESSOR
 2492         if (l && l->l_cpu != NULL)
 2493                 ki->p_cpuid = l->l_cpu->ci_cpuid;
 2494         else
 2495 #endif
 2496                 ki->p_cpuid = KI_NOCPU;
 2497 }
 2498 
 2499 /*
 2500  * Fill in a kinfo_lwp structure for the specified lwp.
 2501  */
 2502 static void
 2503 fill_lwp(struct lwp *l, struct kinfo_lwp *kl)
 2504 {
 2505 
 2506         kl->l_forw = PTRTOUINT64(l->l_forw);
 2507         kl->l_back = PTRTOUINT64(l->l_back);
 2508         kl->l_laddr = PTRTOUINT64(l);
 2509         kl->l_addr = PTRTOUINT64(l->l_addr);
 2510         kl->l_stat = l->l_stat;
 2511         kl->l_lid = l->l_lid;
 2512         kl->l_flag = l->l_flag;
 2513 
 2514         kl->l_swtime = l->l_swtime;
 2515         kl->l_slptime = l->l_slptime;
 2516         if (l->l_stat == LSONPROC) {
 2517                 KDASSERT(l->l_cpu != NULL);
 2518                 kl->l_schedflags = l->l_cpu->ci_schedstate.spc_flags;
 2519         } else
 2520                 kl->l_schedflags = 0;
 2521         kl->l_holdcnt = l->l_holdcnt;
 2522         kl->l_priority = l->l_priority;
 2523         kl->l_usrpri = l->l_usrpri;
 2524         if (l->l_wmesg)
 2525                 strncpy(kl->l_wmesg, l->l_wmesg, sizeof(kl->l_wmesg));
 2526         kl->l_wchan = PTRTOUINT64(l->l_wchan);
 2527 #ifdef MULTIPROCESSOR
 2528         if (l->l_cpu != NULL)
 2529                 kl->l_cpuid = l->l_cpu->ci_cpuid;
 2530         else
 2531 #endif
 2532                 kl->l_cpuid = KI_NOCPU;
 2533 }
 2534 
 2535 /*
 2536  * Fill in an eproc structure for the specified process.
 2537  */
 2538 void
 2539 fill_eproc(struct proc *p, struct eproc *ep)
 2540 {
 2541         struct tty *tp;
 2542         struct lwp *l;
 2543 
 2544         ep->e_paddr = p;
 2545         ep->e_sess = p->p_session;
 2546         ep->e_pcred = *p->p_cred;
 2547         ep->e_ucred = *p->p_ucred;
 2548         if (p->p_stat == SIDL || P_ZOMBIE(p)) {
 2549                 ep->e_vm.vm_rssize = 0;
 2550                 ep->e_vm.vm_tsize = 0;
 2551                 ep->e_vm.vm_dsize = 0;
 2552                 ep->e_vm.vm_ssize = 0;
 2553                 /* ep->e_vm.vm_pmap = XXX; */
 2554         } else {
 2555                 struct vmspace *vm = p->p_vmspace;
 2556 
 2557                 ep->e_vm.vm_rssize = vm_resident_count(vm);
 2558                 ep->e_vm.vm_tsize = vm->vm_tsize;
 2559                 ep->e_vm.vm_dsize = vm->vm_dsize;
 2560                 ep->e_vm.vm_ssize = vm->vm_ssize;
 2561 
 2562                 /* Pick a "representative" LWP */
 2563                 l = proc_representative_lwp(p);
 2564 
 2565                 if (l->l_wmesg)
 2566                         strncpy(ep->e_wmesg, l->l_wmesg, WMESGLEN);
 2567         }
 2568         if (p->p_pptr)
 2569                 ep->e_ppid = p->p_pptr->p_pid;
 2570         else
 2571                 ep->e_ppid = 0;
 2572         ep->e_pgid = p->p_pgrp->pg_id;
 2573         ep->e_sid = ep->e_sess->s_sid;
 2574         ep->e_jobc = p->p_pgrp->pg_jobc;
 2575         if ((p->p_flag & P_CONTROLT) &&
 2576             (tp = ep->e_sess->s_ttyp)) {
 2577                 ep->e_tdev = tp->t_dev;
 2578                 ep->e_tpgid = tp->t_pgrp ? tp->t_pgrp->pg_id : NO_PGID;
 2579                 ep->e_tsess = tp->t_session;
 2580         } else
 2581                 ep->e_tdev = NODEV;
 2582 
 2583         ep->e_xsize = ep->e_xrssize = 0;
 2584         ep->e_xccount = ep->e_xswrss = 0;
 2585         ep->e_flag = ep->e_sess->s_ttyvp ? EPROC_CTTY : 0;
 2586         if (SESS_LEADER(p))
 2587                 ep->e_flag |= EPROC_SLEADER;
 2588         strncpy(ep->e_login, ep->e_sess->s_login, MAXLOGNAME);
 2589 }

Cache object: bb68a3aa7cb4d5fe86d3fbfef723df52


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.