1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  * Copyright 2012 Joyent, Inc.  All rights reserved.
  26  */
  27 
  28 /*      Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T     */
  29 /*        All Rights Reserved   */
  30 
  31 #include <sys/param.h>
  32 #include <sys/types.h>
  33 #include <sys/sysmacros.h>
  34 #include <sys/systm.h>
  35 #include <sys/tuneable.h>
  36 #include <sys/errno.h>
  37 #include <sys/var.h>
  38 #include <sys/signal.h>
  39 #include <sys/time.h>
  40 #include <sys/sysconfig.h>
  41 #include <sys/resource.h>
  42 #include <sys/ulimit.h>
  43 #include <sys/unistd.h>
  44 #include <sys/debug.h>
  45 #include <sys/cpuvar.h>
  46 #include <sys/mman.h>
  47 #include <sys/timer.h>
  48 #include <sys/zone.h>
  49 #include <sys/vm_usage.h>
  50 
  51 extern rctl_hndl_t rc_process_sigqueue;
  52 
  53 long
  54 sysconfig(int which)
  55 {
  56         switch (which) {
  57 
  58         /*
  59          * if it is not handled in mach_sysconfig either
  60          * it must be EINVAL.
  61          */
  62         default:
  63                 return (mach_sysconfig(which)); /* `uname -i`/os */
  64 
  65         case _CONFIG_CLK_TCK:
  66                 return ((long)hz);      /* clock frequency per second */
  67 
  68         case _CONFIG_PROF_TCK:
  69                 return ((long)hz);      /* profiling clock freq per sec */
  70 
  71         case _CONFIG_NGROUPS:
  72                 /*
  73                  * Maximum number of supplementary groups.
  74                  */
  75                 return (ngroups_max);
  76 
  77         case _CONFIG_OPEN_FILES:
  78                 /*
  79                  * Maximum number of open files (soft limit).
  80                  */
  81                 {
  82                         rlim64_t fd_ctl;
  83                         mutex_enter(&curproc->p_lock);
  84                         fd_ctl = rctl_enforced_value(
  85                             rctlproc_legacy[RLIMIT_NOFILE], curproc->p_rctls,
  86                             curproc);
  87                         mutex_exit(&curproc->p_lock);
  88                         return ((ulong_t)fd_ctl);
  89                 }
  90 
  91         case _CONFIG_CHILD_MAX:
  92                 /*
  93                  * Maximum number of processes.
  94                  */
  95                 return (v.v_maxup);
  96 
  97         case _CONFIG_POSIX_VER:
  98                 return (_POSIX_VERSION); /* current POSIX version */
  99 
 100         case _CONFIG_PAGESIZE:
 101                 return (PAGESIZE);
 102 
 103         case _CONFIG_XOPEN_VER:
 104                 return (_XOPEN_VERSION); /* current XOPEN version */
 105 
 106         case _CONFIG_NPROC_CONF:
 107                 return (zone_ncpus_get(curproc->p_zone));
 108 
 109         case _CONFIG_NPROC_ONLN:
 110                 return (zone_ncpus_online_get(curproc->p_zone));
 111 
 112         case _CONFIG_NPROC_MAX:
 113                 return (max_ncpus);
 114 
 115         case _CONFIG_STACK_PROT:
 116                 return (curproc->p_stkprot & ~PROT_USER);
 117 
 118         case _CONFIG_AIO_LISTIO_MAX:
 119                 return (_AIO_LISTIO_MAX);
 120 
 121         case _CONFIG_AIO_MAX:
 122                 return (_AIO_MAX);
 123 
 124         case _CONFIG_AIO_PRIO_DELTA_MAX:
 125                 return (0);
 126 
 127         case _CONFIG_DELAYTIMER_MAX:
 128                 return (INT_MAX);
 129 
 130         case _CONFIG_MQ_OPEN_MAX:
 131                 return (_MQ_OPEN_MAX);
 132 
 133         case _CONFIG_MQ_PRIO_MAX:
 134                 return (_MQ_PRIO_MAX);
 135 
 136         case _CONFIG_RTSIG_MAX:
 137                 return (_SIGRTMAX - _SIGRTMIN + 1);
 138 
 139         case _CONFIG_SEM_NSEMS_MAX:
 140                 return (_SEM_NSEMS_MAX);
 141 
 142         case _CONFIG_SEM_VALUE_MAX:
 143                 return (_SEM_VALUE_MAX);
 144 
 145         case _CONFIG_SIGQUEUE_MAX:
 146                 /*
 147                  * Maximum number of outstanding queued signals.
 148                  */
 149                 {
 150                         rlim64_t sigqsz_max;
 151                         mutex_enter(&curproc->p_lock);
 152                         sigqsz_max = rctl_enforced_value(rc_process_sigqueue,
 153                             curproc->p_rctls, curproc);
 154                         mutex_exit(&curproc->p_lock);
 155                         return ((uint_t)sigqsz_max);
 156                 }
 157 
 158         case _CONFIG_SIGRT_MIN:
 159                 return (_SIGRTMIN);
 160 
 161         case _CONFIG_SIGRT_MAX:
 162                 return (_SIGRTMAX);
 163 
 164         case _CONFIG_TIMER_MAX:
 165                 return (timer_max);
 166 
 167         case _CONFIG_PHYS_PAGES:
 168                 /*
 169                  * If the non-global zone has a phys. memory cap, use that.
 170                  * We always report the system-wide value for the global zone,
 171                  * even though rcapd can be used on the global zone too.
 172                  */
 173                 if (!INGLOBALZONE(curproc) &&
 174                     curproc->p_zone->zone_phys_mem_ctl != UINT64_MAX)
 175                         return (MIN(btop(curproc->p_zone->zone_phys_mem_ctl),
 176                             physinstalled));
 177 
 178                 return (physinstalled);
 179 
 180         case _CONFIG_AVPHYS_PAGES:
 181                 /*
 182                  * If the non-global zone has a phys. memory cap, use
 183                  * the phys. memory cap - zone's rss.  We always
 184                  * report the system-wide value for the global zone, even
 185                  * though memory capping can be used on the global zone too.
 186                  * We use the cached value for the RSS since vm_getusage()
 187                  * is so expensive and we don't need this value to be exact.
 188                  */
 189                 if (!INGLOBALZONE(curproc) &&
 190                     curproc->p_zone->zone_phys_mem_ctl != UINT64_MAX) {
 191                         pgcnt_t cap, rss, free;
 192 
 193                         cap = btop(curproc->p_zone->zone_phys_mem_ctl);
 194                         if (cap > physinstalled)
 195                                 return (freemem);
 196 
 197                         rss = btop(curproc->p_zone->zone_phys_mem);
 198                         /*
 199                          * Because this is a soft cap, it is possible
 200                          * for rss to be temporarily over the cap.
 201                          */
 202                         if (cap > rss)
 203                                 free = cap - rss;
 204                         else
 205                                 free = 0;
 206                         return (MIN(free, freemem));
 207                 }
 208 
 209                 return (freemem);
 210 
 211         case _CONFIG_MAXPID:
 212                 return (maxpid);
 213 
 214         case _CONFIG_CPUID_MAX:
 215                 return (max_cpuid);
 216 
 217         case _CONFIG_EPHID_MAX:
 218                 return (MAXEPHUID);
 219 
 220         case _CONFIG_SYMLOOP_MAX:
 221                 return (MAXSYMLINKS);
 222         }
 223 }