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