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