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

Cache object: 0acf27c1eb2fc29c35ddf07fc7b4afbe


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