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  */
  26 
  27 /*      Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T     */
  28 /*        All Rights Reserved   */
  29 
  30 #include <sys/param.h>
  31 #include <sys/types.h>
  32 #include <sys/sysmacros.h>
  33 #include <sys/systm.h>
  34 #include <sys/tuneable.h>
  35 #include <sys/errno.h>
  36 #include <sys/var.h>
  37 #include <sys/signal.h>
  38 #include <sys/time.h>
  39 #include <sys/sysconfig.h>
  40 #include <sys/resource.h>
  41 #include <sys/ulimit.h>
  42 #include <sys/unistd.h>
  43 #include <sys/debug.h>
  44 #include <sys/cpuvar.h>
  45 #include <sys/mman.h>
  46 #include <sys/timer.h>
  47 #include <sys/zone.h>
  48 #include <sys/vm_usage.h>
  49 
  50 extern rctl_hndl_t rc_process_sigqueue;
  51 
  52 long
  53 sysconfig(int which)
  54 {
  55         switch (which) {
  56 
  57         /*
  58          * if it is not handled in mach_sysconfig either
  59          * it must be EINVAL.
  60          */
  61         default:
  62                 return (mach_sysconfig(which)); /* `uname -i`/os */
  63 
  64         case _CONFIG_CLK_TCK:
  65                 return ((long)hz);      /* clock frequency per second */
  66 
  67         case _CONFIG_PROF_TCK:
  68                 return ((long)hz);      /* profiling clock freq per sec */
  69 
  70         case _CONFIG_NGROUPS:
  71                 /*
  72                  * Maximum number of supplementary groups.
  73                  */
  74                 return (ngroups_max);
  75 
  76         case _CONFIG_OPEN_FILES:
  77                 /*
  78                  * Maximum number of open files (soft limit).
  79                  */
  80                 {
  81                         rlim64_t fd_ctl;
  82                         mutex_enter(&curproc->p_lock);
  83                         fd_ctl = rctl_enforced_value(
  84                             rctlproc_legacy[RLIMIT_NOFILE], curproc->p_rctls,
  85                             curproc);
  86                         mutex_exit(&curproc->p_lock);
  87                         return ((ulong_t)fd_ctl);
  88                 }
  89 
  90         case _CONFIG_CHILD_MAX:
  91                 /*
  92                  * Maximum number of processes.
  93                  */
  94                 return (v.v_maxup);
  95 
  96         case _CONFIG_POSIX_VER:
  97                 return (_POSIX_VERSION); /* current POSIX version */
  98 
  99         case _CONFIG_PAGESIZE:
 100                 return (PAGESIZE);
 101 
 102         case _CONFIG_XOPEN_VER:
 103                 return (_XOPEN_VERSION); /* current XOPEN version */
 104 
 105         case _CONFIG_NPROC_CONF:
 106                 return (zone_ncpus_get(curproc->p_zone));
 107 
 108         case _CONFIG_NPROC_ONLN:
 109                 return (zone_ncpus_online_get(curproc->p_zone));
 110 
 111         case _CONFIG_NPROC_MAX:
 112                 return (max_ncpus);
 113 
 114         case _CONFIG_STACK_PROT:
 115                 return (curproc->p_stkprot & ~PROT_USER);
 116 
 117         case _CONFIG_AIO_LISTIO_MAX:
 118                 return (_AIO_LISTIO_MAX);
 119 
 120         case _CONFIG_AIO_MAX:
 121                 return (_AIO_MAX);
 122 
 123         case _CONFIG_AIO_PRIO_DELTA_MAX:
 124                 return (0);
 125 
 126         case _CONFIG_DELAYTIMER_MAX:
 127                 return (INT_MAX);
 128 
 129         case _CONFIG_MQ_OPEN_MAX:
 130                 return (_MQ_OPEN_MAX);
 131 
 132         case _CONFIG_MQ_PRIO_MAX:
 133                 return (_MQ_PRIO_MAX);
 134 
 135         case _CONFIG_RTSIG_MAX:
 136                 return (_SIGRTMAX - _SIGRTMIN + 1);
 137 
 138         case _CONFIG_SEM_NSEMS_MAX:
 139                 return (_SEM_NSEMS_MAX);
 140 
 141         case _CONFIG_SEM_VALUE_MAX:
 142                 return (_SEM_VALUE_MAX);
 143 
 144         case _CONFIG_SIGQUEUE_MAX:
 145                 /*
 146                  * Maximum number of outstanding queued signals.
 147                  */
 148                 {
 149                         rlim64_t sigqsz_max;
 150                         mutex_enter(&curproc->p_lock);
 151                         sigqsz_max = rctl_enforced_value(rc_process_sigqueue,
 152                             curproc->p_rctls, curproc);
 153                         mutex_exit(&curproc->p_lock);
 154                         return ((uint_t)sigqsz_max);
 155                 }
 156 
 157         case _CONFIG_SIGRT_MIN:
 158                 return (_SIGRTMIN);
 159 
 160         case _CONFIG_SIGRT_MAX:
 161                 return (_SIGRTMAX);
 162 
 163         case _CONFIG_TIMER_MAX:
 164                 return (timer_max);
 165 
 166         case _CONFIG_PHYS_PAGES:
 167                 /*
 168                  * If the non-global zone has a phys. memory cap, use that.
 169                  * We always report the system-wide value for the global zone,
 170                  * even though rcapd can be used on the global zone too.
 171                  */
 172                 if (!INGLOBALZONE(curproc) &&
 173                     curproc->p_zone->zone_phys_mcap != 0)
 174                         return (MIN(btop(curproc->p_zone->zone_phys_mcap),
 175                             physinstalled));
 176 
 177                 return (physinstalled);
 178 
 179         case _CONFIG_AVPHYS_PAGES:
 180                 /*
 181                  * If the non-global zone has a phys. memory cap, use
 182                  * the phys. memory cap - zone's current rss.  We always
 183                  * report the system-wide value for the global zone, even
 184                  * though rcapd can be used on the global zone too.
 185                  */
 186                 if (!INGLOBALZONE(curproc) &&
 187                     curproc->p_zone->zone_phys_mcap != 0) {
 188                         pgcnt_t cap, rss, free;
 189                         vmusage_t in_use;
 190                         size_t cnt = 1;
 191 
 192                         cap = btop(curproc->p_zone->zone_phys_mcap);
 193                         if (cap > physinstalled)
 194                                 return (freemem);
 195 
 196                         if (vm_getusage(VMUSAGE_ZONE, 1, &in_use, &cnt,
 197                             FKIOCTL) != 0)
 198                                 in_use.vmu_rss_all = 0;
 199                         rss = btop(in_use.vmu_rss_all);
 200                         /*
 201                          * Because rcapd implements a soft cap, it is possible
 202                          * for rss to be temporarily over the cap.
 203                          */
 204                         if (cap > rss)
 205                                 free = cap - rss;
 206                         else
 207                                 free = 0;
 208                         return (MIN(free, freemem));
 209                 }
 210 
 211                 return (freemem);
 212 
 213         case _CONFIG_MAXPID:
 214                 return (maxpid);
 215 
 216         case _CONFIG_CPUID_MAX:
 217                 return (max_cpuid);
 218 
 219         case _CONFIG_EPHID_MAX:
 220                 return (MAXEPHUID);
 221 
 222         case _CONFIG_SYMLOOP_MAX:
 223                 return (MAXSYMLINKS);
 224         }
 225 }