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-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: cf607e24aa69d2e9e9202a08b384dec9


[ 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.