root/kern/kern_sysctl.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. sys___sysctl
  2. kern_sysctl
  3. hw_sysctl
  4. debug_sysctl
  5. sysctl_int_lower
  6. sysctl_int
  7. sysctl_rdint
  8. sysctl_int_arr
  9. sysctl_quad
  10. sysctl_rdquad
  11. sysctl_string
  12. sysctl_tstring
  13. sysctl__string
  14. sysctl_rdstring
  15. sysctl_struct
  16. sysctl_rdstruct
  17. sysctl_file
  18. sysctl_doproc
  19. fill_eproc
  20. fill_kproc2
  21. sysctl_proc_args
  22. sysctl_diskinit
  23. sysctl_sysvipc
  24. sysctl_intrcnt
  25. sysctl_sensors
  26. sysctl_emul
  27. sysctl_cptime2

    1 /*      $OpenBSD: kern_sysctl.c,v 1.155 2007/08/09 04:12:12 cnst Exp $  */
    2 /*      $NetBSD: kern_sysctl.c,v 1.17 1996/05/20 17:49:05 mrg Exp $     */
    3 
    4 /*-
    5  * Copyright (c) 1982, 1986, 1989, 1993
    6  *      The Regents of the University of California.  All rights reserved.
    7  *
    8  * This code is derived from software contributed to Berkeley by
    9  * Mike Karels at Berkeley Software Design, Inc.
   10  *
   11  * Redistribution and use in source and binary forms, with or without
   12  * modification, are permitted provided that the following conditions
   13  * are met:
   14  * 1. Redistributions of source code must retain the above copyright
   15  *    notice, this list of conditions and the following disclaimer.
   16  * 2. Redistributions in binary form must reproduce the above copyright
   17  *    notice, this list of conditions and the following disclaimer in the
   18  *    documentation and/or other materials provided with the distribution.
   19  * 3. Neither the name of the University nor the names of its contributors
   20  *    may be used to endorse or promote products derived from this software
   21  *    without specific prior written permission.
   22  *
   23  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   26  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   27  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   29  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   32  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   33  * SUCH DAMAGE.
   34  *
   35  *      @(#)kern_sysctl.c       8.4 (Berkeley) 4/14/94
   36  */
   37 
   38 /*
   39  * sysctl system call.
   40  */
   41 
   42 #include <sys/param.h>
   43 #include <sys/systm.h>
   44 #include <sys/kernel.h>
   45 #include <sys/malloc.h>
   46 #include <sys/proc.h>
   47 #include <sys/resourcevar.h>
   48 #include <sys/file.h>
   49 #include <sys/vnode.h>
   50 #include <sys/unistd.h>
   51 #include <sys/buf.h>
   52 #include <sys/ioctl.h>
   53 #include <sys/tty.h>
   54 #include <sys/disklabel.h>
   55 #include <sys/disk.h>
   56 #include <uvm/uvm_extern.h>
   57 #include <sys/sysctl.h>
   58 #include <sys/msgbuf.h>
   59 #include <sys/dkstat.h>
   60 #include <sys/vmmeter.h>
   61 #include <sys/namei.h>
   62 #include <sys/exec.h>
   63 #include <sys/mbuf.h>
   64 #include <sys/sensors.h>
   65 #ifdef __HAVE_TIMECOUNTER
   66 #include <sys/timetc.h>
   67 #endif
   68 #include <sys/evcount.h>
   69 
   70 #include <sys/mount.h>
   71 #include <sys/syscallargs.h>
   72 #include <dev/rndvar.h>
   73 
   74 #ifdef DDB
   75 #include <ddb/db_var.h>
   76 #endif
   77 
   78 #ifdef SYSVMSG
   79 #include <sys/msg.h>
   80 #endif
   81 #ifdef SYSVSEM
   82 #include <sys/sem.h>
   83 #endif
   84 #ifdef SYSVSHM
   85 #include <sys/shm.h>
   86 #endif
   87 
   88 #define PTRTOINT64(_x)  ((u_int64_t)(u_long)(_x))
   89 
   90 extern struct forkstat forkstat;
   91 extern struct nchstats nchstats;
   92 extern int nselcoll, fscale;
   93 extern struct disklist_head disklist;
   94 extern fixpt_t ccpu;
   95 extern  long numvnodes;
   96 
   97 extern void nmbclust_update(void);
   98 
   99 int sysctl_diskinit(int, struct proc *);
  100 int sysctl_proc_args(int *, u_int, void *, size_t *, struct proc *);
  101 int sysctl_intrcnt(int *, u_int, void *, size_t *);
  102 int sysctl_sensors(int *, u_int, void *, size_t *, void *, size_t);
  103 int sysctl_emul(int *, u_int, void *, size_t *, void *, size_t);
  104 int sysctl_cptime2(int *, u_int, void *, size_t *, void *, size_t);
  105 
  106 int (*cpu_cpuspeed)(int *);
  107 void (*cpu_setperf)(int);
  108 int perflevel = 100;
  109 
  110 /*
  111  * Lock to avoid too many processes vslocking a large amount of memory
  112  * at the same time.
  113  */
  114 struct rwlock sysctl_lock = RWLOCK_INITIALIZER("sysctllk");
  115 struct rwlock sysctl_disklock = RWLOCK_INITIALIZER("sysctldlk");
  116 
  117 int
  118 sys___sysctl(struct proc *p, void *v, register_t *retval)
  119 {
  120         struct sys___sysctl_args /* {
  121                 syscallarg(int *) name;
  122                 syscallarg(u_int) namelen;
  123                 syscallarg(void *) old;
  124                 syscallarg(size_t *) oldlenp;
  125                 syscallarg(void *) new;
  126                 syscallarg(size_t) newlen;
  127         } */ *uap = v;
  128         int error, dolock = 1;
  129         size_t savelen = 0, oldlen = 0;
  130         sysctlfn *fn;
  131         int name[CTL_MAXNAME];
  132 
  133         if (SCARG(uap, new) != NULL &&
  134             (error = suser(p, 0)))
  135                 return (error);
  136         /*
  137          * all top-level sysctl names are non-terminal
  138          */
  139         if (SCARG(uap, namelen) > CTL_MAXNAME || SCARG(uap, namelen) < 2)
  140                 return (EINVAL);
  141         error = copyin(SCARG(uap, name), name,
  142                        SCARG(uap, namelen) * sizeof(int));
  143         if (error)
  144                 return (error);
  145 
  146         switch (name[0]) {
  147         case CTL_KERN:
  148                 fn = kern_sysctl;
  149                 if (name[1] == KERN_VNODE)      /* XXX */
  150                         dolock = 0;
  151                 break;
  152         case CTL_HW:
  153                 fn = hw_sysctl;
  154                 break;
  155         case CTL_VM:
  156                 fn = uvm_sysctl;
  157                 break;
  158         case CTL_NET:
  159                 fn = net_sysctl;
  160                 break;
  161         case CTL_FS:
  162                 fn = fs_sysctl;
  163                 break;
  164         case CTL_VFS:
  165                 fn = vfs_sysctl;
  166                 break;
  167         case CTL_MACHDEP:
  168                 fn = cpu_sysctl;
  169                 break;
  170 #ifdef DEBUG
  171         case CTL_DEBUG:
  172                 fn = debug_sysctl;
  173                 break;
  174 #endif
  175 #ifdef DDB
  176         case CTL_DDB:
  177                 fn = ddb_sysctl;
  178                 break;
  179 #endif
  180         default:
  181                 return (EOPNOTSUPP);
  182         }
  183 
  184         if (SCARG(uap, oldlenp) &&
  185             (error = copyin(SCARG(uap, oldlenp), &oldlen, sizeof(oldlen))))
  186                 return (error);
  187         if (SCARG(uap, old) != NULL) {
  188                 if ((error = rw_enter(&sysctl_lock, RW_WRITE|RW_INTR)) != 0)
  189                         return (error);
  190                 if (dolock) {
  191                         if (atop(oldlen) > uvmexp.wiredmax - uvmexp.wired) {
  192                                 rw_exit_write(&sysctl_lock);
  193                                 return (ENOMEM);
  194                         }
  195                         error = uvm_vslock(p, SCARG(uap, old), oldlen,
  196                             VM_PROT_READ|VM_PROT_WRITE);
  197                         if (error) {
  198                                 rw_exit_write(&sysctl_lock);
  199                                 return (error);
  200                         }
  201                 }
  202                 savelen = oldlen;
  203         }
  204         error = (*fn)(&name[1], SCARG(uap, namelen) - 1, SCARG(uap, old),
  205             &oldlen, SCARG(uap, new), SCARG(uap, newlen), p);
  206         if (SCARG(uap, old) != NULL) {
  207                 if (dolock)
  208                         uvm_vsunlock(p, SCARG(uap, old), savelen);
  209                 rw_exit_write(&sysctl_lock);
  210         }
  211         if (error)
  212                 return (error);
  213         if (SCARG(uap, oldlenp))
  214                 error = copyout(&oldlen, SCARG(uap, oldlenp), sizeof(oldlen));
  215         return (error);
  216 }
  217 
  218 /*
  219  * Attributes stored in the kernel.
  220  */
  221 char hostname[MAXHOSTNAMELEN];
  222 int hostnamelen;
  223 char domainname[MAXHOSTNAMELEN];
  224 int domainnamelen;
  225 long hostid;
  226 char *disknames = NULL;
  227 struct diskstats *diskstats = NULL;
  228 #ifdef INSECURE
  229 int securelevel = -1;
  230 #else
  231 int securelevel;
  232 #endif
  233 
  234 /*
  235  * kernel related system variables.
  236  */
  237 int
  238 kern_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
  239     size_t newlen, struct proc *p)
  240 {
  241         int error, level, inthostid, stackgap;
  242         extern int somaxconn, sominconn;
  243         extern int usermount, nosuidcoredump;
  244         extern long cp_time[CPUSTATES];
  245         extern int stackgap_random;
  246 #ifdef CRYPTO
  247         extern int usercrypto;
  248         extern int userasymcrypto;
  249         extern int cryptodevallowsoft;
  250 #endif
  251         extern int maxlocksperuid;
  252 
  253         /* all sysctl names at this level are terminal except a ton of them */
  254         if (namelen != 1) {
  255                 switch (name[0]) {
  256                 case KERN_PROC:
  257                 case KERN_PROC2:
  258                 case KERN_PROF:
  259                 case KERN_MALLOCSTATS:
  260                 case KERN_TTY:
  261                 case KERN_POOL:
  262                 case KERN_PROC_ARGS:
  263                 case KERN_SYSVIPC_INFO:
  264                 case KERN_SEMINFO:
  265                 case KERN_SHMINFO:
  266                 case KERN_INTRCNT:
  267                 case KERN_WATCHDOG:
  268                 case KERN_EMUL:
  269                 case KERN_EVCOUNT:
  270 #ifdef __HAVE_TIMECOUNTER
  271                 case KERN_TIMECOUNTER:
  272 #endif
  273                 case KERN_CPTIME2:
  274                         break;
  275                 default:
  276                         return (ENOTDIR);       /* overloaded */
  277                 }
  278         }
  279 
  280         switch (name[0]) {
  281         case KERN_OSTYPE:
  282                 return (sysctl_rdstring(oldp, oldlenp, newp, ostype));
  283         case KERN_OSRELEASE:
  284                 return (sysctl_rdstring(oldp, oldlenp, newp, osrelease));
  285         case KERN_OSREV:
  286                 return (sysctl_rdint(oldp, oldlenp, newp, OpenBSD));
  287         case KERN_OSVERSION:
  288                 return (sysctl_rdstring(oldp, oldlenp, newp, osversion));
  289         case KERN_VERSION:
  290                 return (sysctl_rdstring(oldp, oldlenp, newp, version));
  291         case KERN_MAXVNODES:
  292                 return(sysctl_int(oldp, oldlenp, newp, newlen, &maxvnodes));
  293         case KERN_MAXPROC:
  294                 return (sysctl_int(oldp, oldlenp, newp, newlen, &maxproc));
  295         case KERN_MAXFILES:
  296                 return (sysctl_int(oldp, oldlenp, newp, newlen, &maxfiles));
  297         case KERN_NFILES:
  298                 return (sysctl_rdint(oldp, oldlenp, newp, nfiles));
  299         case KERN_TTYCOUNT:
  300                 return (sysctl_rdint(oldp, oldlenp, newp, tty_count));
  301         case KERN_NUMVNODES:
  302                 return (sysctl_rdint(oldp, oldlenp, newp, numvnodes));
  303         case KERN_ARGMAX:
  304                 return (sysctl_rdint(oldp, oldlenp, newp, ARG_MAX));
  305         case KERN_NSELCOLL:
  306                 return (sysctl_rdint(oldp, oldlenp, newp, nselcoll));
  307         case KERN_SECURELVL:
  308                 level = securelevel;
  309                 if ((error = sysctl_int(oldp, oldlenp, newp, newlen, &level)) ||
  310                     newp == NULL)
  311                         return (error);
  312                 if ((securelevel > 0 || level < -1) &&
  313                     level < securelevel && p->p_pid != 1)
  314                         return (EPERM);
  315                 securelevel = level;
  316                 return (0);
  317         case KERN_HOSTNAME:
  318                 error = sysctl_tstring(oldp, oldlenp, newp, newlen,
  319                     hostname, sizeof(hostname));
  320                 if (newp && !error)
  321                         hostnamelen = newlen;
  322                 return (error);
  323         case KERN_DOMAINNAME:
  324                 error = sysctl_tstring(oldp, oldlenp, newp, newlen,
  325                     domainname, sizeof(domainname));
  326                 if (newp && !error)
  327                         domainnamelen = newlen;
  328                 return (error);
  329         case KERN_HOSTID:
  330                 inthostid = hostid;  /* XXX assumes sizeof long <= sizeof int */
  331                 error =  sysctl_int(oldp, oldlenp, newp, newlen, &inthostid);
  332                 hostid = inthostid;
  333                 return (error);
  334         case KERN_CLOCKRATE:
  335                 return (sysctl_clockrate(oldp, oldlenp));
  336         case KERN_BOOTTIME:
  337                 return (sysctl_rdstruct(oldp, oldlenp, newp, &boottime,
  338                     sizeof(struct timeval)));
  339         case KERN_VNODE:
  340                 return (sysctl_vnode(oldp, oldlenp, p));
  341 #ifndef SMALL_KERNEL
  342         case KERN_PROC:
  343         case KERN_PROC2:
  344                 return (sysctl_doproc(name, namelen, oldp, oldlenp));
  345         case KERN_PROC_ARGS:
  346                 return (sysctl_proc_args(name + 1, namelen - 1, oldp, oldlenp,
  347                      p));
  348 #endif
  349         case KERN_FILE:
  350                 return (sysctl_file(oldp, oldlenp));
  351         case KERN_MBSTAT:
  352                 return (sysctl_rdstruct(oldp, oldlenp, newp, &mbstat,
  353                     sizeof(mbstat)));
  354 #ifdef GPROF
  355         case KERN_PROF:
  356                 return (sysctl_doprof(name + 1, namelen - 1, oldp, oldlenp,
  357                     newp, newlen));
  358 #endif
  359         case KERN_POSIX1:
  360                 return (sysctl_rdint(oldp, oldlenp, newp, _POSIX_VERSION));
  361         case KERN_NGROUPS:
  362                 return (sysctl_rdint(oldp, oldlenp, newp, NGROUPS_MAX));
  363         case KERN_JOB_CONTROL:
  364                 return (sysctl_rdint(oldp, oldlenp, newp, 1));
  365         case KERN_SAVED_IDS:
  366 #ifdef _POSIX_SAVED_IDS
  367                 return (sysctl_rdint(oldp, oldlenp, newp, 1));
  368 #else
  369                 return (sysctl_rdint(oldp, oldlenp, newp, 0));
  370 #endif
  371         case KERN_MAXPARTITIONS:
  372                 return (sysctl_rdint(oldp, oldlenp, newp, MAXPARTITIONS));
  373         case KERN_RAWPARTITION:
  374                 return (sysctl_rdint(oldp, oldlenp, newp, RAW_PART));
  375         case KERN_SOMAXCONN:
  376                 return (sysctl_int(oldp, oldlenp, newp, newlen, &somaxconn));
  377         case KERN_SOMINCONN:
  378                 return (sysctl_int(oldp, oldlenp, newp, newlen, &sominconn));
  379         case KERN_USERMOUNT:
  380                 return (sysctl_int(oldp, oldlenp, newp, newlen, &usermount));
  381         case KERN_RND:
  382                 return (sysctl_rdstruct(oldp, oldlenp, newp, &rndstats,
  383                     sizeof(rndstats)));
  384         case KERN_ARND: {
  385                 char buf[256];
  386 
  387                 if (*oldlenp > sizeof(buf))
  388                         *oldlenp = sizeof(buf);
  389                 if (oldp) {
  390                         arc4random_bytes(buf, *oldlenp);
  391                         if ((error = copyout(buf, oldp, *oldlenp)))
  392                                 return (error);
  393                 }
  394                 return (0);
  395         }
  396         case KERN_NOSUIDCOREDUMP:
  397                 return (sysctl_int(oldp, oldlenp, newp, newlen, &nosuidcoredump));
  398         case KERN_FSYNC:
  399                 return (sysctl_rdint(oldp, oldlenp, newp, 1));
  400         case KERN_SYSVMSG:
  401 #ifdef SYSVMSG
  402                 return (sysctl_rdint(oldp, oldlenp, newp, 1));
  403 #else
  404                 return (sysctl_rdint(oldp, oldlenp, newp, 0));
  405 #endif
  406         case KERN_SYSVSEM:
  407 #ifdef SYSVSEM
  408                 return (sysctl_rdint(oldp, oldlenp, newp, 1));
  409 #else
  410                 return (sysctl_rdint(oldp, oldlenp, newp, 0));
  411 #endif
  412         case KERN_SYSVSHM:
  413 #ifdef SYSVSHM
  414                 return (sysctl_rdint(oldp, oldlenp, newp, 1));
  415 #else
  416                 return (sysctl_rdint(oldp, oldlenp, newp, 0));
  417 #endif
  418         case KERN_MSGBUFSIZE:
  419                 /*
  420                  * deal with cases where the message buffer has
  421                  * become corrupted.
  422                  */
  423                 if (!msgbufp || msgbufp->msg_magic != MSG_MAGIC)
  424                         return (ENXIO);
  425                 return (sysctl_rdint(oldp, oldlenp, newp, msgbufp->msg_bufs));
  426         case KERN_MSGBUF:
  427                 /* see note above */
  428                 if (!msgbufp || msgbufp->msg_magic != MSG_MAGIC)
  429                         return (ENXIO);
  430                 return (sysctl_rdstruct(oldp, oldlenp, newp, msgbufp,
  431                     msgbufp->msg_bufs + offsetof(struct msgbuf, msg_bufc)));
  432         case KERN_MALLOCSTATS:
  433                 return (sysctl_malloc(name + 1, namelen - 1, oldp, oldlenp,
  434                     newp, newlen, p));
  435         case KERN_CPTIME:
  436         {
  437                 CPU_INFO_ITERATOR cii;
  438                 struct cpu_info *ci;
  439                 int i;
  440 
  441                 bzero(cp_time, sizeof(cp_time));
  442 
  443                 CPU_INFO_FOREACH(cii, ci) {
  444                         for (i = 0; i < CPUSTATES; i++)
  445                                 cp_time[i] += ci->ci_schedstate.spc_cp_time[i];
  446                 }
  447 
  448                 return (sysctl_rdstruct(oldp, oldlenp, newp, &cp_time,
  449                     sizeof(cp_time)));
  450         }
  451         case KERN_NCHSTATS:
  452                 return (sysctl_rdstruct(oldp, oldlenp, newp, &nchstats,
  453                     sizeof(struct nchstats)));
  454         case KERN_FORKSTAT:
  455                 return (sysctl_rdstruct(oldp, oldlenp, newp, &forkstat,
  456                     sizeof(struct forkstat)));
  457         case KERN_TTY:
  458                 return (sysctl_tty(name + 1, namelen - 1, oldp, oldlenp,
  459                     newp, newlen));
  460         case KERN_FSCALE:
  461                 return (sysctl_rdint(oldp, oldlenp, newp, fscale));
  462         case KERN_CCPU:
  463                 return (sysctl_rdint(oldp, oldlenp, newp, ccpu));
  464         case KERN_NPROCS:
  465                 return (sysctl_rdint(oldp, oldlenp, newp, nprocs));
  466         case KERN_POOL:
  467                 return (sysctl_dopool(name + 1, namelen - 1, oldp, oldlenp));
  468         case KERN_STACKGAPRANDOM:
  469                 stackgap = stackgap_random;
  470                 error = sysctl_int(oldp, oldlenp, newp, newlen, &stackgap);
  471                 if (error)
  472                         return (error);
  473                 /*
  474                  * Safety harness.
  475                  */
  476                 if ((stackgap < ALIGNBYTES && stackgap != 0) ||
  477                     !powerof2(stackgap) || stackgap >= MAXSSIZ)
  478                         return (EINVAL);
  479                 stackgap_random = stackgap;
  480                 return (0);
  481 #if defined(SYSVMSG) || defined(SYSVSEM) || defined(SYSVSHM)
  482         case KERN_SYSVIPC_INFO:
  483                 return (sysctl_sysvipc(name + 1, namelen - 1, oldp, oldlenp));
  484 #endif
  485 #ifdef CRYPTO
  486         case KERN_USERCRYPTO:
  487                 return (sysctl_int(oldp, oldlenp, newp, newlen, &usercrypto));
  488         case KERN_USERASYMCRYPTO:
  489                 return (sysctl_int(oldp, oldlenp, newp, newlen,
  490                             &userasymcrypto));
  491         case KERN_CRYPTODEVALLOWSOFT:
  492                 return (sysctl_int(oldp, oldlenp, newp, newlen,
  493                             &cryptodevallowsoft));
  494 #endif
  495         case KERN_SPLASSERT:
  496                 return (sysctl_int(oldp, oldlenp, newp, newlen,
  497                     &splassert_ctl));
  498 #ifdef SYSVSEM
  499         case KERN_SEMINFO:
  500                 return (sysctl_sysvsem(name + 1, namelen - 1, oldp, oldlenp,
  501                     newp, newlen));
  502 #endif
  503 #ifdef SYSVSHM
  504         case KERN_SHMINFO:
  505                 return (sysctl_sysvshm(name + 1, namelen - 1, oldp, oldlenp,
  506                     newp, newlen));
  507 #endif
  508 #ifndef SMALL_KERNEL
  509         case KERN_INTRCNT:
  510                 return (sysctl_intrcnt(name + 1, namelen - 1, oldp, oldlenp));
  511         case KERN_WATCHDOG:
  512                 return (sysctl_wdog(name + 1, namelen - 1, oldp, oldlenp,
  513                     newp, newlen));
  514         case KERN_EMUL:
  515                 return (sysctl_emul(name + 1, namelen - 1, oldp, oldlenp,
  516                     newp, newlen));
  517 #endif
  518         case KERN_MAXCLUSTERS:
  519                 error = sysctl_int(oldp, oldlenp, newp, newlen, &nmbclust);
  520                 if (!error)
  521                         nmbclust_update();
  522                 return (error);
  523 #ifndef SMALL_KERNEL
  524         case KERN_EVCOUNT:
  525                 return (evcount_sysctl(name + 1, namelen - 1, oldp, oldlenp,
  526                     newp, newlen));
  527 #endif
  528 #ifdef __HAVE_TIMECOUNTER
  529         case KERN_TIMECOUNTER:
  530                 return (sysctl_tc(name + 1, namelen - 1, oldp, oldlenp,
  531                     newp, newlen));
  532 #endif
  533         case KERN_MAXLOCKSPERUID:
  534                 return (sysctl_int(oldp, oldlenp, newp, newlen, &maxlocksperuid));
  535         case KERN_CPTIME2:
  536                 return (sysctl_cptime2(name + 1, namelen -1, oldp, oldlenp,
  537                     newp, newlen));
  538         default:
  539                 return (EOPNOTSUPP);
  540         }
  541         /* NOTREACHED */
  542 }
  543 
  544 /*
  545  * hardware related system variables.
  546  */
  547 char *hw_vendor, *hw_prod, *hw_uuid, *hw_serial, *hw_ver;
  548 
  549 int
  550 hw_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
  551     size_t newlen, struct proc *p)
  552 {
  553         extern char machine[], cpu_model[];
  554         int err, cpuspeed;
  555 
  556         /* all sysctl names at this level except sensors are terminal */
  557         if (name[0] != HW_SENSORS && namelen != 1)
  558                 return (ENOTDIR);               /* overloaded */
  559 
  560         switch (name[0]) {
  561         case HW_MACHINE:
  562                 return (sysctl_rdstring(oldp, oldlenp, newp, machine));
  563         case HW_MODEL:
  564                 return (sysctl_rdstring(oldp, oldlenp, newp, cpu_model));
  565         case HW_NCPU:
  566                 return (sysctl_rdint(oldp, oldlenp, newp, ncpus));
  567         case HW_BYTEORDER:
  568                 return (sysctl_rdint(oldp, oldlenp, newp, BYTE_ORDER));
  569         case HW_PHYSMEM:
  570                 return (sysctl_rdint(oldp, oldlenp, newp, ctob(physmem)));
  571         case HW_USERMEM:
  572                 return (sysctl_rdint(oldp, oldlenp, newp,
  573                     ctob(physmem - uvmexp.wired)));
  574         case HW_PAGESIZE:
  575                 return (sysctl_rdint(oldp, oldlenp, newp, PAGE_SIZE));
  576         case HW_DISKNAMES:
  577                 err = sysctl_diskinit(0, p);
  578                 if (err)
  579                         return err;
  580                 if (disknames)
  581                         return (sysctl_rdstring(oldp, oldlenp, newp,
  582                             disknames));
  583                 else
  584                         return (sysctl_rdstring(oldp, oldlenp, newp, ""));
  585         case HW_DISKSTATS:
  586                 err = sysctl_diskinit(1, p);
  587                 if (err)
  588                         return err;
  589                 return (sysctl_rdstruct(oldp, oldlenp, newp, diskstats,
  590                     disk_count * sizeof(struct diskstats)));
  591         case HW_DISKCOUNT:
  592                 return (sysctl_rdint(oldp, oldlenp, newp, disk_count));
  593 #ifndef SMALL_KERNEL
  594         case HW_SENSORS:
  595                 return (sysctl_sensors(name + 1, namelen - 1, oldp, oldlenp,
  596                     newp, newlen));
  597 #endif
  598         case HW_CPUSPEED:
  599                 if (!cpu_cpuspeed)
  600                         return (EOPNOTSUPP);
  601                 err = cpu_cpuspeed(&cpuspeed);
  602                 if (err)
  603                         return err;
  604                 return (sysctl_rdint(oldp, oldlenp, newp, cpuspeed));
  605         case HW_SETPERF:
  606                 if (!cpu_setperf)
  607                         return (EOPNOTSUPP);
  608                 err = sysctl_int(oldp, oldlenp, newp, newlen, &perflevel);
  609                 if (err)
  610                         return err;
  611                 if (perflevel > 100)
  612                         perflevel = 100;
  613                 if (perflevel < 0)
  614                         perflevel = 0;
  615                 if (newp)
  616                         cpu_setperf(perflevel);
  617                 return (0);
  618         case HW_VENDOR:
  619                 if (hw_vendor)
  620                         return (sysctl_rdstring(oldp, oldlenp, newp,
  621                             hw_vendor));
  622                 else
  623                         return (EOPNOTSUPP);
  624         case HW_PRODUCT:
  625                 if (hw_prod)
  626                         return (sysctl_rdstring(oldp, oldlenp, newp, hw_prod));
  627                 else
  628                         return (EOPNOTSUPP);
  629         case HW_VERSION:
  630                 if (hw_ver)
  631                         return (sysctl_rdstring(oldp, oldlenp, newp, hw_ver));
  632                 else
  633                         return (EOPNOTSUPP);
  634         case HW_SERIALNO:
  635                 if (hw_serial)
  636                         return (sysctl_rdstring(oldp, oldlenp, newp,
  637                             hw_serial));
  638                 else
  639                         return (EOPNOTSUPP);
  640         case HW_UUID:
  641                 if (hw_uuid)
  642                         return (sysctl_rdstring(oldp, oldlenp, newp, hw_uuid));
  643                 else
  644                         return (EOPNOTSUPP);
  645         default:
  646                 return (EOPNOTSUPP);
  647         }
  648         /* NOTREACHED */
  649 }
  650 
  651 #ifdef DEBUG
  652 /*
  653  * Debugging related system variables.
  654  */
  655 extern struct ctldebug debug0, debug1;
  656 struct ctldebug debug2, debug3, debug4;
  657 struct ctldebug debug5, debug6, debug7, debug8, debug9;
  658 struct ctldebug debug10, debug11, debug12, debug13, debug14;
  659 struct ctldebug debug15, debug16, debug17, debug18, debug19;
  660 static struct ctldebug *debugvars[CTL_DEBUG_MAXID] = {
  661         &debug0, &debug1, &debug2, &debug3, &debug4,
  662         &debug5, &debug6, &debug7, &debug8, &debug9,
  663         &debug10, &debug11, &debug12, &debug13, &debug14,
  664         &debug15, &debug16, &debug17, &debug18, &debug19,
  665 };
  666 int
  667 debug_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
  668     size_t newlen, struct proc *p)
  669 {
  670         struct ctldebug *cdp;
  671 
  672         /* all sysctl names at this level are name and field */
  673         if (namelen != 2)
  674                 return (ENOTDIR);               /* overloaded */
  675         cdp = debugvars[name[0]];
  676         if (cdp->debugname == 0)
  677                 return (EOPNOTSUPP);
  678         switch (name[1]) {
  679         case CTL_DEBUG_NAME:
  680                 return (sysctl_rdstring(oldp, oldlenp, newp, cdp->debugname));
  681         case CTL_DEBUG_VALUE:
  682                 return (sysctl_int(oldp, oldlenp, newp, newlen, cdp->debugvar));
  683         default:
  684                 return (EOPNOTSUPP);
  685         }
  686         /* NOTREACHED */
  687 }
  688 #endif /* DEBUG */
  689 
  690 /*
  691  * Reads, or writes that lower the value
  692  */
  693 int
  694 sysctl_int_lower(void *oldp, size_t *oldlenp, void *newp, size_t newlen, int *valp)
  695 {
  696         unsigned int oval = *valp, val = *valp;
  697         int error;
  698 
  699         if (newp == NULL)
  700                 return (sysctl_rdint(oldp, oldlenp, newp, *valp));
  701 
  702         if ((error = sysctl_int(oldp, oldlenp, newp, newlen, &val)))
  703                 return (error);
  704         if (val > oval)
  705                 return (EPERM);         /* do not allow raising */
  706         *(unsigned int *)valp = val;
  707         return (0);
  708 }
  709 
  710 /*
  711  * Validate parameters and get old / set new parameters
  712  * for an integer-valued sysctl function.
  713  */
  714 int
  715 sysctl_int(void *oldp, size_t *oldlenp, void *newp, size_t newlen, int *valp)
  716 {
  717         int error = 0;
  718 
  719         if (oldp && *oldlenp < sizeof(int))
  720                 return (ENOMEM);
  721         if (newp && newlen != sizeof(int))
  722                 return (EINVAL);
  723         *oldlenp = sizeof(int);
  724         if (oldp)
  725                 error = copyout(valp, oldp, sizeof(int));
  726         if (error == 0 && newp)
  727                 error = copyin(newp, valp, sizeof(int));
  728         return (error);
  729 }
  730 
  731 /*
  732  * As above, but read-only.
  733  */
  734 int
  735 sysctl_rdint(void *oldp, size_t *oldlenp, void *newp, int val)
  736 {
  737         int error = 0;
  738 
  739         if (oldp && *oldlenp < sizeof(int))
  740                 return (ENOMEM);
  741         if (newp)
  742                 return (EPERM);
  743         *oldlenp = sizeof(int);
  744         if (oldp)
  745                 error = copyout((caddr_t)&val, oldp, sizeof(int));
  746         return (error);
  747 }
  748 
  749 /*
  750  * Array of integer values.
  751  */
  752 int
  753 sysctl_int_arr(int **valpp, int *name, u_int namelen, void *oldp,
  754     size_t *oldlenp, void *newp, size_t newlen)
  755 {
  756         if (namelen > 1)
  757                 return (ENOTDIR);
  758         if (name[0] < 0 || valpp[name[0]] == NULL)
  759                 return (EOPNOTSUPP);
  760         return (sysctl_int(oldp, oldlenp, newp, newlen, valpp[name[0]]));
  761 }
  762 
  763 /*
  764  * Validate parameters and get old / set new parameters
  765  * for an integer-valued sysctl function.
  766  */
  767 int
  768 sysctl_quad(void *oldp, size_t *oldlenp, void *newp, size_t newlen,
  769     int64_t *valp)
  770 {
  771         int error = 0;
  772 
  773         if (oldp && *oldlenp < sizeof(int64_t))
  774                 return (ENOMEM);
  775         if (newp && newlen != sizeof(int64_t))
  776                 return (EINVAL);
  777         *oldlenp = sizeof(int64_t);
  778         if (oldp)
  779                 error = copyout(valp, oldp, sizeof(int64_t));
  780         if (error == 0 && newp)
  781                 error = copyin(newp, valp, sizeof(int64_t));
  782         return (error);
  783 }
  784 
  785 /*
  786  * As above, but read-only.
  787  */
  788 int
  789 sysctl_rdquad(void *oldp, size_t *oldlenp, void *newp, int64_t val)
  790 {
  791         int error = 0;
  792 
  793         if (oldp && *oldlenp < sizeof(int64_t))
  794                 return (ENOMEM);
  795         if (newp)
  796                 return (EPERM);
  797         *oldlenp = sizeof(int64_t);
  798         if (oldp)
  799                 error = copyout((caddr_t)&val, oldp, sizeof(int64_t));
  800         return (error);
  801 }
  802 
  803 /*
  804  * Validate parameters and get old / set new parameters
  805  * for a string-valued sysctl function.
  806  */
  807 int
  808 sysctl_string(void *oldp, size_t *oldlenp, void *newp, size_t newlen, char *str,
  809     int maxlen)
  810 {
  811         return sysctl__string(oldp, oldlenp, newp, newlen, str, maxlen, 0);
  812 }
  813 
  814 int
  815 sysctl_tstring(void *oldp, size_t *oldlenp, void *newp, size_t newlen,
  816     char *str, int maxlen)
  817 {
  818         return sysctl__string(oldp, oldlenp, newp, newlen, str, maxlen, 1);
  819 }
  820 
  821 int
  822 sysctl__string(void *oldp, size_t *oldlenp, void *newp, size_t newlen,
  823     char *str, int maxlen, int trunc)
  824 {
  825         int len, error = 0;
  826         char c;
  827 
  828         len = strlen(str) + 1;
  829         if (oldp && *oldlenp < len) {
  830                 if (trunc == 0 || *oldlenp == 0)
  831                         return (ENOMEM);
  832         }
  833         if (newp && newlen >= maxlen)
  834                 return (EINVAL);
  835         if (oldp) {
  836                 if (trunc && *oldlenp < len) {
  837                         /* save & zap NUL terminator while copying */
  838                         c = str[*oldlenp-1];
  839                         str[*oldlenp-1] = '\0';
  840                         error = copyout(str, oldp, *oldlenp);
  841                         str[*oldlenp-1] = c;
  842                 } else {
  843                         *oldlenp = len;
  844                         error = copyout(str, oldp, len);
  845                 }
  846         }
  847         if (error == 0 && newp) {
  848                 error = copyin(newp, str, newlen);
  849                 str[newlen] = 0;
  850         }
  851         return (error);
  852 }
  853 
  854 /*
  855  * As above, but read-only.
  856  */
  857 int
  858 sysctl_rdstring(void *oldp, size_t *oldlenp, void *newp, const char *str)
  859 {
  860         int len, error = 0;
  861 
  862         len = strlen(str) + 1;
  863         if (oldp && *oldlenp < len)
  864                 return (ENOMEM);
  865         if (newp)
  866                 return (EPERM);
  867         *oldlenp = len;
  868         if (oldp)
  869                 error = copyout(str, oldp, len);
  870         return (error);
  871 }
  872 
  873 /*
  874  * Validate parameters and get old / set new parameters
  875  * for a structure oriented sysctl function.
  876  */
  877 int
  878 sysctl_struct(void *oldp, size_t *oldlenp, void *newp, size_t newlen, void *sp,
  879     int len)
  880 {
  881         int error = 0;
  882 
  883         if (oldp && *oldlenp < len)
  884                 return (ENOMEM);
  885         if (newp && newlen > len)
  886                 return (EINVAL);
  887         if (oldp) {
  888                 *oldlenp = len;
  889                 error = copyout(sp, oldp, len);
  890         }
  891         if (error == 0 && newp)
  892                 error = copyin(newp, sp, len);
  893         return (error);
  894 }
  895 
  896 /*
  897  * Validate parameters and get old parameters
  898  * for a structure oriented sysctl function.
  899  */
  900 int
  901 sysctl_rdstruct(void *oldp, size_t *oldlenp, void *newp, const void *sp,
  902     int len)
  903 {
  904         int error = 0;
  905 
  906         if (oldp && *oldlenp < len)
  907                 return (ENOMEM);
  908         if (newp)
  909                 return (EPERM);
  910         *oldlenp = len;
  911         if (oldp)
  912                 error = copyout(sp, oldp, len);
  913         return (error);
  914 }
  915 
  916 /*
  917  * Get file structures.
  918  */
  919 int
  920 sysctl_file(char *where, size_t *sizep)
  921 {
  922         int buflen, error;
  923         struct file *fp;
  924         char *start = where;
  925 
  926         buflen = *sizep;
  927         if (where == NULL) {
  928                 /*
  929                  * overestimate by 10 files
  930                  */
  931                 *sizep = sizeof(filehead) + (nfiles + 10) * sizeof(struct file);
  932                 return (0);
  933         }
  934 
  935         /*
  936          * first copyout filehead
  937          */
  938         if (buflen < sizeof(filehead)) {
  939                 *sizep = 0;
  940                 return (0);
  941         }
  942         error = copyout((caddr_t)&filehead, where, sizeof(filehead));
  943         if (error)
  944                 return (error);
  945         buflen -= sizeof(filehead);
  946         where += sizeof(filehead);
  947 
  948         /*
  949          * followed by an array of file structures
  950          */
  951         LIST_FOREACH(fp, &filehead, f_list) {
  952                 if (buflen < sizeof(struct file)) {
  953                         *sizep = where - start;
  954                         return (ENOMEM);
  955                 }
  956                 error = copyout((caddr_t)fp, where, sizeof (struct file));
  957                 if (error)
  958                         return (error);
  959                 buflen -= sizeof(struct file);
  960                 where += sizeof(struct file);
  961         }
  962         *sizep = where - start;
  963         return (0);
  964 }
  965 
  966 #ifndef SMALL_KERNEL
  967 
  968 /*
  969  * try over estimating by 5 procs
  970  */
  971 #define KERN_PROCSLOP   (5 * sizeof (struct kinfo_proc))
  972 
  973 int
  974 sysctl_doproc(int *name, u_int namelen, char *where, size_t *sizep)
  975 {
  976         struct kinfo_proc2 *kproc2 = NULL;
  977         struct eproc *eproc = NULL;
  978         struct proc *p;
  979         char *dp;
  980         int arg, buflen, doingzomb, elem_size, elem_count;
  981         int error, needed, type, op;
  982 
  983         dp = where;
  984         buflen = where != NULL ? *sizep : 0;
  985         needed = error = 0;
  986         type = name[0];
  987 
  988         if (type == KERN_PROC) {
  989                 if (namelen != 3 && !(namelen == 2 &&
  990                     (name[1] == KERN_PROC_ALL || name[1] == KERN_PROC_KTHREAD)))
  991                         return (EINVAL);
  992                 op = name[1];
  993                 arg = op == KERN_PROC_ALL ? 0 : name[2];
  994                 elem_size = elem_count = 0;
  995                 eproc = malloc(sizeof(struct eproc), M_TEMP, M_WAITOK);
  996         } else /* if (type == KERN_PROC2) */ {
  997                 if (namelen != 5 || name[3] < 0 || name[4] < 0)
  998                         return (EINVAL);
  999                 op = name[1];
 1000                 arg = name[2];
 1001                 elem_size = name[3];
 1002                 elem_count = name[4];
 1003                 kproc2 = malloc(sizeof(struct kinfo_proc2), M_TEMP, M_WAITOK);
 1004         }
 1005         p = LIST_FIRST(&allproc);
 1006         doingzomb = 0;
 1007 again:
 1008         for (; p != 0; p = LIST_NEXT(p, p_list)) {
 1009                 /*
 1010                  * Skip embryonic processes.
 1011                  */
 1012                 if (p->p_stat == SIDL)
 1013                         continue;
 1014                 /*
 1015                  * TODO - make more efficient (see notes below).
 1016                  */
 1017                 switch (op) {
 1018 
 1019                 case KERN_PROC_PID:
 1020                         /* could do this with just a lookup */
 1021                         if (p->p_pid != (pid_t)arg)
 1022                                 continue;
 1023                         break;
 1024 
 1025                 case KERN_PROC_PGRP:
 1026                         /* could do this by traversing pgrp */
 1027                         if (p->p_pgrp->pg_id != (pid_t)arg)
 1028                                 continue;
 1029                         break;
 1030 
 1031                 case KERN_PROC_SESSION:
 1032                         if (p->p_session->s_leader == NULL ||
 1033                             p->p_session->s_leader->p_pid != (pid_t)arg)
 1034                                 continue;
 1035                         break;
 1036 
 1037                 case KERN_PROC_TTY:
 1038                         if ((p->p_flag & P_CONTROLT) == 0 ||
 1039                             p->p_session->s_ttyp == NULL ||
 1040                             p->p_session->s_ttyp->t_dev != (dev_t)arg)
 1041                                 continue;
 1042                         break;
 1043 
 1044                 case KERN_PROC_UID:
 1045                         if (p->p_ucred->cr_uid != (uid_t)arg)
 1046                                 continue;
 1047                         break;
 1048 
 1049                 case KERN_PROC_RUID:
 1050                         if (p->p_cred->p_ruid != (uid_t)arg)
 1051                                 continue;
 1052                         break;
 1053 
 1054                 case KERN_PROC_ALL:
 1055                         if (p->p_flag & P_SYSTEM)
 1056                                 continue;
 1057                         break;
 1058                 case KERN_PROC_KTHREAD:
 1059                         /* no filtering */
 1060                         break;
 1061                 default:
 1062                         error = EINVAL;
 1063                         goto err;
 1064                 }
 1065                 if (type == KERN_PROC) {
 1066                         if (buflen >= sizeof(struct kinfo_proc)) {
 1067                                 fill_eproc(p, eproc);
 1068                                 error = copyout((caddr_t)p,
 1069                                     &((struct kinfo_proc *)dp)->kp_proc,
 1070                                     sizeof(struct proc));
 1071                                 if (error)
 1072                                         goto err;
 1073                                 error = copyout((caddr_t)eproc,
 1074                                     &((struct kinfo_proc *)dp)->kp_eproc,
 1075                                     sizeof(*eproc));
 1076                                 if (error)
 1077                                         goto err;
 1078                                 dp += sizeof(struct kinfo_proc);
 1079                                 buflen -= sizeof(struct kinfo_proc);
 1080                         }
 1081                         needed += sizeof(struct kinfo_proc);
 1082                 } else /* if (type == KERN_PROC2) */ {
 1083                         if (buflen >= elem_size && elem_count > 0) {
 1084                                 fill_kproc2(p, kproc2);
 1085                                 /*
 1086                                  * Copy out elem_size, but not larger than
 1087                                  * the size of a struct kinfo_proc2.
 1088                                  */
 1089                                 error = copyout(kproc2, dp,
 1090                                     min(sizeof(*kproc2), elem_size));
 1091                                 if (error)
 1092                                         goto err;
 1093                                 dp += elem_size;
 1094                                 buflen -= elem_size;
 1095                                 elem_count--;
 1096                         }
 1097                         needed += elem_size;
 1098                 }
 1099         }
 1100         if (doingzomb == 0) {
 1101                 p = LIST_FIRST(&zombproc);
 1102                 doingzomb++;
 1103                 goto again;
 1104         }
 1105         if (where != NULL) {
 1106                 *sizep = dp - where;
 1107                 if (needed > *sizep) {
 1108                         error = ENOMEM;
 1109                         goto err;
 1110                 }
 1111         } else {
 1112                 needed += KERN_PROCSLOP;
 1113                 *sizep = needed;
 1114         }
 1115 err:
 1116         if (eproc)
 1117                 free(eproc, M_TEMP);
 1118         if (kproc2)
 1119                 free(kproc2, M_TEMP);
 1120         return (error);
 1121 }
 1122 
 1123 #endif  /* SMALL_KERNEL */
 1124 
 1125 /*
 1126  * Fill in an eproc structure for the specified process.
 1127  */
 1128 void
 1129 fill_eproc(struct proc *p, struct eproc *ep)
 1130 {
 1131         struct tty *tp;
 1132 
 1133         ep->e_paddr = p;
 1134         ep->e_sess = p->p_pgrp->pg_session;
 1135         ep->e_pcred = *p->p_cred;
 1136         ep->e_ucred = *p->p_ucred;
 1137         if (p->p_stat == SIDL || P_ZOMBIE(p)) {
 1138                 ep->e_vm.vm_rssize = 0;
 1139                 ep->e_vm.vm_tsize = 0;
 1140                 ep->e_vm.vm_dsize = 0;
 1141                 ep->e_vm.vm_ssize = 0;
 1142                 bzero(&ep->e_pstats, sizeof(ep->e_pstats));
 1143                 ep->e_pstats_valid = 0;
 1144         } else {
 1145                 struct vmspace *vm = p->p_vmspace;
 1146 
 1147                 ep->e_vm.vm_rssize = vm_resident_count(vm);
 1148                 ep->e_vm.vm_tsize = vm->vm_tsize;
 1149                 ep->e_vm.vm_dsize = vm->vm_dused;
 1150                 ep->e_vm.vm_ssize = vm->vm_ssize;
 1151                 ep->e_pstats = *p->p_stats;
 1152                 ep->e_pstats_valid = 1;
 1153         }
 1154         if (p->p_pptr)
 1155                 ep->e_ppid = p->p_pptr->p_pid;
 1156         else
 1157                 ep->e_ppid = 0;
 1158         ep->e_pgid = p->p_pgrp->pg_id;
 1159         ep->e_jobc = p->p_pgrp->pg_jobc;
 1160         if ((p->p_flag & P_CONTROLT) &&
 1161              (tp = ep->e_sess->s_ttyp)) {
 1162                 ep->e_tdev = tp->t_dev;
 1163                 ep->e_tpgid = tp->t_pgrp ? tp->t_pgrp->pg_id : NO_PID;
 1164                 ep->e_tsess = tp->t_session;
 1165         } else
 1166                 ep->e_tdev = NODEV;
 1167         ep->e_flag = ep->e_sess->s_ttyvp ? EPROC_CTTY : 0;
 1168         if (SESS_LEADER(p))
 1169                 ep->e_flag |= EPROC_SLEADER;
 1170         strncpy(ep->e_wmesg, p->p_wmesg ? p->p_wmesg : "", WMESGLEN);
 1171         ep->e_wmesg[WMESGLEN] = '\0';
 1172         ep->e_xsize = ep->e_xrssize = 0;
 1173         ep->e_xccount = ep->e_xswrss = 0;
 1174         strncpy(ep->e_login, ep->e_sess->s_login, MAXLOGNAME-1);
 1175         ep->e_login[MAXLOGNAME-1] = '\0';
 1176         strncpy(ep->e_emul, p->p_emul->e_name, EMULNAMELEN);
 1177         ep->e_emul[EMULNAMELEN] = '\0';
 1178         ep->e_maxrss = p->p_rlimit ? p->p_rlimit[RLIMIT_RSS].rlim_cur : 0;
 1179         ep->e_limit = p->p_p->ps_limit;
 1180 }
 1181 
 1182 #ifndef SMALL_KERNEL
 1183 
 1184 /*
 1185  * Fill in a kproc2 structure for the specified process.
 1186  */
 1187 void
 1188 fill_kproc2(struct proc *p, struct kinfo_proc2 *ki)
 1189 {
 1190         struct tty *tp;
 1191         struct timeval ut, st;
 1192 
 1193         bzero(ki, sizeof(*ki));
 1194 
 1195         ki->p_paddr = PTRTOINT64(p);
 1196         ki->p_fd = PTRTOINT64(p->p_fd);
 1197         ki->p_stats = PTRTOINT64(p->p_stats);
 1198         ki->p_limit = PTRTOINT64(p->p_p->ps_limit);
 1199         ki->p_vmspace = PTRTOINT64(p->p_vmspace);
 1200         ki->p_sigacts = PTRTOINT64(p->p_sigacts);
 1201         ki->p_sess = PTRTOINT64(p->p_session);
 1202         ki->p_tsess = 0;        /* may be changed if controlling tty below */
 1203         ki->p_ru = PTRTOINT64(p->p_ru);
 1204 
 1205         ki->p_eflag = 0;
 1206         ki->p_exitsig = p->p_exitsig;
 1207         ki->p_flag = p->p_flag | P_INMEM;
 1208 
 1209         ki->p_pid = p->p_pid;
 1210         if (p->p_pptr)
 1211                 ki->p_ppid = p->p_pptr->p_pid;
 1212         else
 1213                 ki->p_ppid = 0;
 1214         if (p->p_session->s_leader)
 1215                 ki->p_sid = p->p_session->s_leader->p_pid;
 1216         else
 1217                 ki->p_sid = 0;
 1218         ki->p__pgid = p->p_pgrp->pg_id;
 1219 
 1220         ki->p_tpgid = -1;       /* may be changed if controlling tty below */
 1221 
 1222         ki->p_uid = p->p_ucred->cr_uid;
 1223         ki->p_ruid = p->p_cred->p_ruid;
 1224         ki->p_gid = p->p_ucred->cr_gid;
 1225         ki->p_rgid = p->p_cred->p_rgid;
 1226         ki->p_svuid = p->p_cred->p_svuid;
 1227         ki->p_svgid = p->p_cred->p_svgid;
 1228 
 1229         memcpy(ki->p_groups, p->p_cred->pc_ucred->cr_groups,
 1230             min(sizeof(ki->p_groups), sizeof(p->p_cred->pc_ucred->cr_groups)));
 1231         ki->p_ngroups = p->p_cred->pc_ucred->cr_ngroups;
 1232 
 1233         ki->p_jobc = p->p_pgrp->pg_jobc;
 1234         if ((p->p_flag & P_CONTROLT) && (tp = p->p_session->s_ttyp)) {
 1235                 ki->p_tdev = tp->t_dev;
 1236                 ki->p_tpgid = tp->t_pgrp ? tp->t_pgrp->pg_id : -1;
 1237                 ki->p_tsess = PTRTOINT64(tp->t_session);
 1238         } else {
 1239                 ki->p_tdev = NODEV;
 1240         }
 1241 
 1242         ki->p_estcpu = p->p_estcpu;
 1243         ki->p_rtime_sec = p->p_rtime.tv_sec;
 1244         ki->p_rtime_usec = p->p_rtime.tv_usec;
 1245         ki->p_cpticks = p->p_cpticks;
 1246         ki->p_pctcpu = p->p_pctcpu;
 1247 
 1248         ki->p_uticks = p->p_uticks;
 1249         ki->p_sticks = p->p_sticks;
 1250         ki->p_iticks = p->p_iticks;
 1251 
 1252         ki->p_tracep = PTRTOINT64(p->p_tracep);
 1253         ki->p_traceflag = p->p_traceflag;
 1254 
 1255         ki->p_siglist = p->p_siglist;
 1256         ki->p_sigmask = p->p_sigmask;
 1257         ki->p_sigignore = p->p_sigignore;
 1258         ki->p_sigcatch = p->p_sigcatch;
 1259 
 1260         ki->p_stat = p->p_stat;
 1261         ki->p_nice = p->p_nice;
 1262 
 1263         ki->p_xstat = p->p_xstat;
 1264         ki->p_acflag = p->p_acflag;
 1265 
 1266         strlcpy(ki->p_emul, p->p_emul->e_name, sizeof(ki->p_emul));
 1267         strlcpy(ki->p_comm, p->p_comm, sizeof(ki->p_comm));
 1268         strncpy(ki->p_login, p->p_session->s_login,
 1269             min(sizeof(ki->p_login) - 1, sizeof(p->p_session->s_login)));
 1270 
 1271         if (p->p_stat == SIDL || P_ZOMBIE(p)) {
 1272                 ki->p_vm_rssize = 0;
 1273                 ki->p_vm_tsize = 0;
 1274                 ki->p_vm_dsize = 0;
 1275                 ki->p_vm_ssize = 0;
 1276         } else {
 1277                 struct vmspace *vm = p->p_vmspace;
 1278 
 1279                 ki->p_vm_rssize = vm_resident_count(vm);
 1280                 ki->p_vm_tsize = vm->vm_tsize;
 1281                 ki->p_vm_dsize = vm->vm_dused;
 1282                 ki->p_vm_ssize = vm->vm_ssize;
 1283 
 1284                 ki->p_forw = PTRTOINT64(p->p_forw);
 1285                 ki->p_back = PTRTOINT64(p->p_back);
 1286                 ki->p_addr = PTRTOINT64(p->p_addr);
 1287                 ki->p_stat = p->p_stat;
 1288                 ki->p_swtime = p->p_swtime;
 1289                 ki->p_slptime = p->p_slptime;
 1290                 ki->p_schedflags = 0;
 1291                 ki->p_holdcnt = 1;
 1292                 ki->p_priority = p->p_priority;
 1293                 ki->p_usrpri = p->p_usrpri;
 1294                 if (p->p_wmesg)
 1295                         strlcpy(ki->p_wmesg, p->p_wmesg, sizeof(ki->p_wmesg));
 1296                 ki->p_wchan = PTRTOINT64(p->p_wchan);
 1297 
 1298         }
 1299 
 1300         if (p->p_session->s_ttyvp)
 1301                 ki->p_eflag |= EPROC_CTTY;
 1302         if (SESS_LEADER(p))
 1303                 ki->p_eflag |= EPROC_SLEADER;
 1304         if (p->p_rlimit)
 1305                 ki->p_rlim_rss_cur = p->p_rlimit[RLIMIT_RSS].rlim_cur;
 1306 
 1307         /* XXX Is this double check necessary? */
 1308         if (P_ZOMBIE(p)) {
 1309                 ki->p_uvalid = 0;
 1310         } else {
 1311                 ki->p_uvalid = 1;
 1312 
 1313                 ki->p_ustart_sec = p->p_stats->p_start.tv_sec;
 1314                 ki->p_ustart_usec = p->p_stats->p_start.tv_usec;
 1315 
 1316                 calcru(p, &ut, &st, 0);
 1317                 ki->p_uutime_sec = ut.tv_sec;
 1318                 ki->p_uutime_usec = ut.tv_usec;
 1319                 ki->p_ustime_sec = st.tv_sec;
 1320                 ki->p_ustime_usec = st.tv_usec;
 1321 
 1322                 ki->p_uru_maxrss = p->p_stats->p_ru.ru_maxrss;
 1323                 ki->p_uru_ixrss = p->p_stats->p_ru.ru_ixrss;
 1324                 ki->p_uru_idrss = p->p_stats->p_ru.ru_idrss;
 1325                 ki->p_uru_isrss = p->p_stats->p_ru.ru_isrss;
 1326                 ki->p_uru_minflt = p->p_stats->p_ru.ru_minflt;
 1327                 ki->p_uru_majflt = p->p_stats->p_ru.ru_majflt;
 1328                 ki->p_uru_nswap = p->p_stats->p_ru.ru_nswap;
 1329                 ki->p_uru_inblock = p->p_stats->p_ru.ru_inblock;
 1330                 ki->p_uru_oublock = p->p_stats->p_ru.ru_oublock;
 1331                 ki->p_uru_msgsnd = p->p_stats->p_ru.ru_msgsnd;
 1332                 ki->p_uru_msgrcv = p->p_stats->p_ru.ru_msgrcv;
 1333                 ki->p_uru_nsignals = p->p_stats->p_ru.ru_nsignals;
 1334                 ki->p_uru_nvcsw = p->p_stats->p_ru.ru_nvcsw;
 1335                 ki->p_uru_nivcsw = p->p_stats->p_ru.ru_nivcsw;
 1336 
 1337                 timeradd(&p->p_stats->p_cru.ru_utime,
 1338                          &p->p_stats->p_cru.ru_stime, &ut);
 1339                 ki->p_uctime_sec = ut.tv_sec;
 1340                 ki->p_uctime_usec = ut.tv_usec;
 1341                 ki->p_cpuid = KI_NOCPU;
 1342 #ifdef MULTIPROCESSOR
 1343                 if (p->p_cpu != NULL)
 1344                         ki->p_cpuid = CPU_INFO_UNIT(p->p_cpu);
 1345 #endif
 1346         }
 1347 }
 1348 
 1349 int
 1350 sysctl_proc_args(int *name, u_int namelen, void *oldp, size_t *oldlenp,
 1351     struct proc *cp)
 1352 {
 1353         struct proc *vp;
 1354         pid_t pid;
 1355         int op;
 1356         struct ps_strings pss;
 1357         struct iovec iov;
 1358         struct uio uio;
 1359         int error;
 1360         size_t limit;
 1361         int cnt;
 1362         char **rargv, **vargv;          /* reader vs. victim */
 1363         char *rarg, *varg;
 1364         char *buf;
 1365 
 1366         if (namelen > 2)
 1367                 return (ENOTDIR);
 1368         if (namelen < 2)
 1369                 return (EINVAL);
 1370 
 1371         pid = name[0];
 1372         op = name[1];
 1373 
 1374         switch (op) {
 1375         case KERN_PROC_ARGV:
 1376         case KERN_PROC_NARGV:
 1377         case KERN_PROC_ENV:
 1378         case KERN_PROC_NENV:
 1379                 break;
 1380         default:
 1381                 return (EOPNOTSUPP);
 1382         }
 1383 
 1384         if ((vp = pfind(pid)) == NULL)
 1385                 return (ESRCH);
 1386 
 1387         if (oldp == NULL) {
 1388                 if (op == KERN_PROC_NARGV || op == KERN_PROC_NENV)
 1389                         *oldlenp = sizeof(int);
 1390                 else
 1391                         *oldlenp = ARG_MAX;     /* XXX XXX XXX */
 1392                 return (0);
 1393         }
 1394 
 1395         if (P_ZOMBIE(vp) || (vp->p_flag & P_SYSTEM))
 1396                 return (EINVAL);
 1397 
 1398         /* Exiting - don't bother, it will be gone soon anyway */
 1399         if ((vp->p_flag & P_WEXIT))
 1400                 return (ESRCH);
 1401 
 1402         /* Execing - danger. */
 1403         if ((vp->p_flag & P_INEXEC))
 1404                 return (EBUSY);
 1405 
 1406         vp->p_vmspace->vm_refcnt++;     /* XXX */
 1407         buf = malloc(PAGE_SIZE, M_TEMP, M_WAITOK);
 1408 
 1409         iov.iov_base = &pss;
 1410         iov.iov_len = sizeof(pss);
 1411         uio.uio_iov = &iov;
 1412         uio.uio_iovcnt = 1;     
 1413         uio.uio_offset = (off_t)PS_STRINGS;
 1414         uio.uio_resid = sizeof(pss);
 1415         uio.uio_segflg = UIO_SYSSPACE;
 1416         uio.uio_rw = UIO_READ;
 1417         uio.uio_procp = cp;
 1418 
 1419         if ((error = uvm_io(&vp->p_vmspace->vm_map, &uio, 0)) != 0)
 1420                 goto out;
 1421 
 1422         if (op == KERN_PROC_NARGV) {
 1423                 error = sysctl_rdint(oldp, oldlenp, NULL, pss.ps_nargvstr);
 1424                 goto out;
 1425         }
 1426         if (op == KERN_PROC_NENV) {
 1427                 error = sysctl_rdint(oldp, oldlenp, NULL, pss.ps_nenvstr);
 1428                 goto out;
 1429         }
 1430 
 1431         if (op == KERN_PROC_ARGV) {
 1432                 cnt = pss.ps_nargvstr;
 1433                 vargv = pss.ps_argvstr;
 1434         } else {
 1435                 cnt = pss.ps_nenvstr;
 1436                 vargv = pss.ps_envstr;
 1437         }
 1438 
 1439         /* -1 to have space for a terminating NUL */
 1440         limit = *oldlenp - 1;
 1441         *oldlenp = 0;
 1442 
 1443         rargv = oldp;
 1444 
 1445         /*
 1446          * *oldlenp - number of bytes copied out into readers buffer.
 1447          * limit - maximal number of bytes allowed into readers buffer.
 1448          * rarg - pointer into readers buffer where next arg will be stored.
 1449          * rargv - pointer into readers buffer where the next rarg pointer
 1450          *  will be stored.
 1451          * vargv - pointer into victim address space where the next argument
 1452          *  will be read.
 1453          */
 1454 
 1455         /* space for cnt pointers and a NULL */
 1456         rarg = (char *)(rargv + cnt + 1);
 1457         *oldlenp += (cnt + 1) * sizeof(char **);
 1458 
 1459         while (cnt > 0 && *oldlenp < limit) {
 1460                 size_t len, vstrlen;
 1461 
 1462                 /* Write to readers argv */
 1463                 if ((error = copyout(&rarg, rargv, sizeof(rarg))) != 0)
 1464                         goto out;
 1465 
 1466                 /* read the victim argv */
 1467                 iov.iov_base = &varg;
 1468                 iov.iov_len = sizeof(varg);
 1469                 uio.uio_iov = &iov;
 1470                 uio.uio_iovcnt = 1;
 1471                 uio.uio_offset = (off_t)(vaddr_t)vargv;
 1472                 uio.uio_resid = sizeof(varg);
 1473                 uio.uio_segflg = UIO_SYSSPACE;
 1474                 uio.uio_rw = UIO_READ;
 1475                 uio.uio_procp = cp;
 1476                 if ((error = uvm_io(&vp->p_vmspace->vm_map, &uio, 0)) != 0)
 1477                         goto out;
 1478 
 1479                 if (varg == NULL)
 1480                         break;
 1481 
 1482                 /*
 1483                  * read the victim arg. We must jump through hoops to avoid
 1484                  * crossing a page boundary too much and returning an error.
 1485                  */
 1486 more:
 1487                 len = PAGE_SIZE - (((vaddr_t)varg) & PAGE_MASK);
 1488                 /* leave space for the terminating NUL */
 1489                 iov.iov_base = buf;
 1490                 iov.iov_len = len;
 1491                 uio.uio_iov = &iov;
 1492                 uio.uio_iovcnt = 1;
 1493                 uio.uio_offset = (off_t)(vaddr_t)varg;
 1494                 uio.uio_resid = len;
 1495                 uio.uio_segflg = UIO_SYSSPACE;
 1496                 uio.uio_rw = UIO_READ;
 1497                 uio.uio_procp = cp;
 1498                 if ((error = uvm_io(&vp->p_vmspace->vm_map, &uio, 0)) != 0)
 1499                         goto out;
 1500 
 1501                 for (vstrlen = 0; vstrlen < len; vstrlen++) {
 1502                         if (buf[vstrlen] == '\0')
 1503                                 break;
 1504                 }
 1505 
 1506                 /* Don't overflow readers buffer. */
 1507                 if (*oldlenp + vstrlen + 1 >= limit) {
 1508                         error = ENOMEM;
 1509                         goto out;
 1510                 }
 1511 
 1512                 if ((error = copyout(buf, rarg, vstrlen)) != 0)
 1513                         goto out;
 1514 
 1515                 *oldlenp += vstrlen;
 1516                 rarg += vstrlen;
 1517 
 1518                 /* The string didn't end in this page? */
 1519                 if (vstrlen == len) {
 1520                         varg += vstrlen;
 1521                         goto more;
 1522                 }
 1523 
 1524                 /* End of string. Terminate it with a NUL */
 1525                 buf[0] = '\0';
 1526                 if ((error = copyout(buf, rarg, 1)) != 0)
 1527                         goto out;
 1528                 *oldlenp += 1;
 1529                 rarg += 1;
 1530 
 1531                 vargv++;
 1532                 rargv++;
 1533                 cnt--;
 1534         }
 1535 
 1536         if (*oldlenp >= limit) {
 1537                 error = ENOMEM;
 1538                 goto out;
 1539         }
 1540 
 1541         /* Write the terminating null */
 1542         rarg = NULL;
 1543         error = copyout(&rarg, rargv, sizeof(rarg));
 1544 
 1545 out:
 1546         uvmspace_free(vp->p_vmspace);
 1547         free(buf, M_TEMP);
 1548         return (error);
 1549 }
 1550 
 1551 #endif
 1552 
 1553 /*
 1554  * Initialize disknames/diskstats for export by sysctl. If update is set,
 1555  * then we simply update the disk statistics information.
 1556  */
 1557 int
 1558 sysctl_diskinit(int update, struct proc *p)
 1559 {
 1560         struct diskstats *sdk;
 1561         struct disk *dk;
 1562         int i, tlen, l;
 1563 
 1564         if ((i = rw_enter(&sysctl_disklock, RW_WRITE|RW_INTR)) != 0)
 1565                 return i;
 1566 
 1567         if (disk_change) {
 1568                 for (dk = TAILQ_FIRST(&disklist), tlen = 0; dk;
 1569                     dk = TAILQ_NEXT(dk, dk_link))
 1570                         tlen += strlen(dk->dk_name) + 1;
 1571                 tlen++;
 1572 
 1573                 if (disknames)
 1574                         free(disknames, M_SYSCTL);
 1575                 if (diskstats)
 1576                         free(diskstats, M_SYSCTL);
 1577                 diskstats = NULL;
 1578                 disknames = NULL;
 1579                 diskstats = malloc(disk_count * sizeof(struct diskstats),
 1580                     M_SYSCTL, M_WAITOK);
 1581                 disknames = malloc(tlen, M_SYSCTL, M_WAITOK);
 1582                 disknames[0] = '\0';
 1583 
 1584                 for (dk = TAILQ_FIRST(&disklist), i = 0, l = 0; dk;
 1585                     dk = TAILQ_NEXT(dk, dk_link), i++) {
 1586                         snprintf(disknames + l, tlen - l, "%s,",
 1587                             dk->dk_name ? dk->dk_name : "");
 1588                         l += strlen(disknames + l);
 1589                         sdk = diskstats + i;
 1590                         strlcpy(sdk->ds_name, dk->dk_name,
 1591                             sizeof(sdk->ds_name));
 1592                         sdk->ds_busy = dk->dk_busy;
 1593                         sdk->ds_rxfer = dk->dk_rxfer;
 1594                         sdk->ds_wxfer = dk->dk_wxfer;
 1595                         sdk->ds_seek = dk->dk_seek;
 1596                         sdk->ds_rbytes = dk->dk_rbytes;
 1597                         sdk->ds_wbytes = dk->dk_wbytes;
 1598                         sdk->ds_attachtime = dk->dk_attachtime;
 1599                         sdk->ds_timestamp = dk->dk_timestamp;
 1600                         sdk->ds_time = dk->dk_time;
 1601                 }
 1602 
 1603                 /* Eliminate trailing comma */
 1604                 if (l != 0)
 1605                         disknames[l - 1] = '\0';
 1606                 disk_change = 0;
 1607         } else if (update) {
 1608                 /* Just update, number of drives hasn't changed */
 1609                 for (dk = TAILQ_FIRST(&disklist), i = 0; dk;
 1610                     dk = TAILQ_NEXT(dk, dk_link), i++) {
 1611                         sdk = diskstats + i;
 1612                         strlcpy(sdk->ds_name, dk->dk_name,
 1613                             sizeof(sdk->ds_name));
 1614                         sdk->ds_busy = dk->dk_busy;
 1615                         sdk->ds_rxfer = dk->dk_rxfer;
 1616                         sdk->ds_wxfer = dk->dk_wxfer;
 1617                         sdk->ds_seek = dk->dk_seek;
 1618                         sdk->ds_rbytes = dk->dk_rbytes;
 1619                         sdk->ds_wbytes = dk->dk_wbytes;
 1620                         sdk->ds_attachtime = dk->dk_attachtime;
 1621                         sdk->ds_timestamp = dk->dk_timestamp;
 1622                         sdk->ds_time = dk->dk_time;
 1623                 }
 1624         }
 1625         rw_exit_write(&sysctl_disklock);
 1626         return 0;
 1627 }
 1628 
 1629 #if defined(SYSVMSG) || defined(SYSVSEM) || defined(SYSVSHM)
 1630 int
 1631 sysctl_sysvipc(int *name, u_int namelen, void *where, size_t *sizep)
 1632 {
 1633 #ifdef SYSVMSG
 1634         struct msg_sysctl_info *msgsi;
 1635 #endif
 1636 #ifdef SYSVSEM
 1637         struct sem_sysctl_info *semsi;
 1638 #endif
 1639 #ifdef SYSVSHM
 1640         struct shm_sysctl_info *shmsi;
 1641 #endif
 1642         size_t infosize, dssize, tsize, buflen;
 1643         int i, nds, error, ret;
 1644         void *buf;
 1645 
 1646         if (namelen != 1)
 1647                 return (EINVAL);
 1648 
 1649         buflen = *sizep;
 1650 
 1651         switch (*name) {
 1652         case KERN_SYSVIPC_MSG_INFO:
 1653 #ifdef SYSVMSG
 1654                 infosize = sizeof(msgsi->msginfo);
 1655                 nds = msginfo.msgmni;
 1656                 dssize = sizeof(msgsi->msgids[0]);
 1657                 break;
 1658 #else
 1659                 return (EOPNOTSUPP);
 1660 #endif
 1661         case KERN_SYSVIPC_SEM_INFO:
 1662 #ifdef SYSVSEM
 1663                 infosize = sizeof(semsi->seminfo);
 1664                 nds = seminfo.semmni;
 1665                 dssize = sizeof(semsi->semids[0]);
 1666                 break;
 1667 #else
 1668                 return (EOPNOTSUPP);
 1669 #endif
 1670         case KERN_SYSVIPC_SHM_INFO:
 1671 #ifdef SYSVSHM
 1672                 infosize = sizeof(shmsi->shminfo);
 1673                 nds = shminfo.shmmni;
 1674                 dssize = sizeof(shmsi->shmids[0]);
 1675                 break;
 1676 #else
 1677                 return (EOPNOTSUPP);
 1678 #endif
 1679         default:
 1680                 return (EINVAL);
 1681         }
 1682         tsize = infosize + (nds * dssize);
 1683 
 1684         /* Return just the total size required. */
 1685         if (where == NULL) {
 1686                 *sizep = tsize;
 1687                 return (0);
 1688         }
 1689 
 1690         /* Not enough room for even the info struct. */
 1691         if (buflen < infosize) {
 1692                 *sizep = 0;
 1693                 return (ENOMEM);
 1694         }
 1695         buf = malloc(min(tsize, buflen), M_TEMP, M_WAITOK);
 1696         bzero(buf, min(tsize, buflen));
 1697 
 1698         switch (*name) {
 1699 #ifdef SYSVMSG
 1700         case KERN_SYSVIPC_MSG_INFO:
 1701                 msgsi = (struct msg_sysctl_info *)buf;
 1702                 msgsi->msginfo = msginfo;
 1703                 break;
 1704 #endif
 1705 #ifdef SYSVSEM
 1706         case KERN_SYSVIPC_SEM_INFO:
 1707                 semsi = (struct sem_sysctl_info *)buf;
 1708                 semsi->seminfo = seminfo;
 1709                 break;
 1710 #endif
 1711 #ifdef SYSVSHM
 1712         case KERN_SYSVIPC_SHM_INFO:
 1713                 shmsi = (struct shm_sysctl_info *)buf;
 1714                 shmsi->shminfo = shminfo;
 1715                 break;
 1716 #endif
 1717         }
 1718         buflen -= infosize;
 1719 
 1720         ret = 0;
 1721         if (buflen > 0) {
 1722                 /* Fill in the IPC data structures.  */
 1723                 for (i = 0; i < nds; i++) {
 1724                         if (buflen < dssize) {
 1725                                 ret = ENOMEM;
 1726                                 break;
 1727                         }
 1728                         switch (*name) {
 1729 #ifdef SYSVMSG
 1730                         case KERN_SYSVIPC_MSG_INFO:
 1731                                 bcopy(&msqids[i], &msgsi->msgids[i], dssize);
 1732                                 break;
 1733 #endif
 1734 #ifdef SYSVSEM
 1735                         case KERN_SYSVIPC_SEM_INFO:
 1736                                 if (sema[i] != NULL)
 1737                                         bcopy(sema[i], &semsi->semids[i],
 1738                                             dssize);
 1739                                 else
 1740                                         bzero(&semsi->semids[i], dssize);
 1741                                 break;
 1742 #endif
 1743 #ifdef SYSVSHM
 1744                         case KERN_SYSVIPC_SHM_INFO:
 1745                                 if (shmsegs[i] != NULL)
 1746                                         bcopy(shmsegs[i], &shmsi->shmids[i],
 1747                                             dssize);
 1748                                 else
 1749                                         bzero(&shmsi->shmids[i], dssize);
 1750                                 break;
 1751 #endif
 1752                         }
 1753                         buflen -= dssize;
 1754                 }
 1755         }
 1756         *sizep -= buflen;
 1757         error = copyout(buf, where, *sizep);
 1758         free(buf, M_TEMP);
 1759         /* If copyout succeeded, use return code set earlier. */
 1760         return (error ? error : ret);
 1761 }
 1762 #endif /* SYSVMSG || SYSVSEM || SYSVSHM */
 1763 
 1764 #ifndef SMALL_KERNEL
 1765 
 1766 int
 1767 sysctl_intrcnt(int *name, u_int namelen, void *oldp, size_t *oldlenp)
 1768 {
 1769         return (evcount_sysctl(name, namelen, oldp, oldlenp, NULL, 0));
 1770 }
 1771 
 1772 
 1773 int
 1774 sysctl_sensors(int *name, u_int namelen, void *oldp, size_t *oldlenp,
 1775     void *newp, size_t newlen)
 1776 {
 1777         struct ksensor *ks;
 1778         struct sensor *us;
 1779         struct ksensordev *ksd;
 1780         struct sensordev *usd;
 1781         int dev, numt, ret;
 1782         enum sensor_type type;
 1783 
 1784         if (namelen != 1 && namelen != 3)
 1785                 return (ENOTDIR);
 1786 
 1787         dev = name[0];
 1788         if (namelen == 1) {
 1789                 ksd = sensordev_get(dev);
 1790                 if (ksd == NULL)
 1791                         return (ENOENT);
 1792 
 1793                 /* Grab a copy, to clear the kernel pointers */
 1794                 usd = malloc(sizeof(*usd), M_TEMP, M_WAITOK);
 1795                 bzero(usd, sizeof(*usd));
 1796                 usd->num = ksd->num;
 1797                 strlcpy(usd->xname, ksd->xname, sizeof(usd->xname));
 1798                 memcpy(usd->maxnumt, ksd->maxnumt, sizeof(usd->maxnumt));
 1799                 usd->sensors_count = ksd->sensors_count;
 1800 
 1801                 ret = sysctl_rdstruct(oldp, oldlenp, newp, usd,
 1802                     sizeof(struct sensordev));
 1803 
 1804                 free(usd, M_TEMP);
 1805                 return (ret);
 1806         }
 1807 
 1808         type = name[1];
 1809         numt = name[2];
 1810 
 1811         ks = sensor_find(dev, type, numt);
 1812         if (ks == NULL)
 1813                 return (ENOENT);
 1814 
 1815         /* Grab a copy, to clear the kernel pointers */
 1816         us = malloc(sizeof(*us), M_TEMP, M_WAITOK);
 1817         bzero(us, sizeof(*us));
 1818         memcpy(us->desc, ks->desc, sizeof(us->desc));
 1819         us->tv = ks->tv;
 1820         us->value = ks->value;
 1821         us->type = ks->type;
 1822         us->status = ks->status;
 1823         us->numt = ks->numt;
 1824         us->flags = ks->flags;
 1825 
 1826         ret = sysctl_rdstruct(oldp, oldlenp, newp, us,
 1827             sizeof(struct sensor));
 1828         free(us, M_TEMP);
 1829         return (ret);
 1830 }
 1831 
 1832 int
 1833 sysctl_emul(int *name, u_int namelen, void *oldp, size_t *oldlenp,
 1834     void *newp, size_t newlen)
 1835 {
 1836         int enabled, error;
 1837         struct emul *e;
 1838 
 1839         if (name[0] == KERN_EMUL_NUM) {
 1840                 if (namelen != 1)
 1841                         return (ENOTDIR);
 1842                 return (sysctl_rdint(oldp, oldlenp, newp, nexecs));
 1843         }
 1844 
 1845         if (namelen != 2)
 1846                 return (ENOTDIR);
 1847         if (name[0] > nexecs || name[0] < 0)
 1848                 return (EINVAL);
 1849         e = execsw[name[0] - 1].es_emul;
 1850         if (e == NULL)
 1851                 return (EINVAL);
 1852 
 1853         switch (name[1]) {
 1854         case KERN_EMUL_NAME:
 1855                 return (sysctl_rdstring(oldp, oldlenp, newp, e->e_name));
 1856         case KERN_EMUL_ENABLED:
 1857                 enabled = (e->e_flags & EMUL_ENABLED);
 1858                 error = sysctl_int(oldp, oldlenp, newp, newlen,
 1859                     &enabled);
 1860                 e->e_flags = (enabled & EMUL_ENABLED);
 1861                 return (error);
 1862         default:
 1863                 return (EINVAL);
 1864         }
 1865 }
 1866 
 1867 #endif  /* SMALL_KERNEL */
 1868 
 1869 int
 1870 sysctl_cptime2(int *name, u_int namelen, void *oldp, size_t *oldlenp,
 1871     void *newp, size_t newlen)
 1872 {
 1873         CPU_INFO_ITERATOR cii;
 1874         struct cpu_info *ci;
 1875         int i;
 1876 
 1877         if (namelen != 1)
 1878                 return (ENOTDIR);
 1879 
 1880         i = name[0];
 1881 
 1882         CPU_INFO_FOREACH(cii, ci) {
 1883                 if (i-- == 0)
 1884                         break;
 1885         }
 1886         if (i > 0)
 1887                 return (ENOENT);
 1888 
 1889         return (sysctl_rdstruct(oldp, oldlenp, newp,
 1890             &ci->ci_schedstate.spc_cp_time,
 1891             sizeof(ci->ci_schedstate.spc_cp_time)));
 1892 }

/* [<][>][^][v][top][bottom][index][help] */