nrelease - fix/improve livecd
[dragonfly.git] / sys / kern / subr_param.c
1 /*
2  * Copyright (c) 1980, 1986, 1989, 1993
3  *      The Regents of the University of California.  All rights reserved.
4  * (c) UNIX System Laboratories, Inc.
5  * All or some portions of this file are derived from material licensed
6  * to the University of California by American Telephone and Telegraph
7  * Co. or Unix System Laboratories, Inc. and are reproduced herein with
8  * the permission of UNIX System Laboratories, Inc.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  * 3. Neither the name of the University nor the names of its contributors
19  *    may be used to endorse or promote products derived from this software
20  *    without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  *
34  *      @(#)param.c     8.3 (Berkeley) 8/20/94
35  * $FreeBSD: src/sys/kern/subr_param.c,v 1.42.2.10 2002/03/09 21:05:47 silby Exp $
36  */
37
38 #include "opt_param.h"
39 #include "opt_maxusers.h"
40
41 #include <sys/param.h>
42 #include <sys/systm.h>
43 #include <sys/kernel.h>
44 #include <sys/malloc.h>
45 #include <sys/sysctl.h>
46 #include <vm/pmap.h>
47 #include <machine/vmparam.h>
48
49 /*
50  * System parameter formulae.
51  */
52
53 #ifndef HZ_DEFAULT
54 #define HZ_DEFAULT      100
55 #endif
56 #define NPROC           (20 + 16 * maxusers)
57 #ifndef NBUF
58 #define NBUF            0
59 #endif
60 #ifndef MAXFILES
61 #define MAXFILES        (maxproc * 16)
62 #endif
63 #ifndef MAXPOSIXLOCKSPERUID
64 #define MAXPOSIXLOCKSPERUID (maxproc * 4)
65 #endif
66
67 static int sysctl_kern_vmm_guest(SYSCTL_HANDLER_ARGS);
68
69 int     hz;
70 int     stathz;
71 int     profhz;
72 int     ustick;                         /* tick interval in microseconds */
73 int     nstick;                         /* tick interval in nanoseconds */
74 int     maxusers;                       /* base tunable */
75 int     maxproc;                        /* maximum # of processes */
76 int     maxprocperuid;                  /* max # of procs per user */
77 int     maxfiles;                       /* system wide open files limit */
78 int     maxfilesrootres;                /* descriptors reserved for root use */
79 int     minfilesperproc;                /* per-proc min open files (safety) */
80 int     maxfilesperproc;                /* per-proc open files limit */
81 int     maxfilesperuser;                /* per-user open files limit */
82 int     maxposixlocksperuid;            /* max # POSIX locks per uid */
83 int     ncallout;                       /* maximum # of timer events */
84 long    nbuf;
85 long    nswbuf_mem;
86 long    nswbuf_kva;
87 long    nswbuf_raw;
88 long    maxswzone;                      /* max swmeta KVA storage */
89 long    maxbcache;                      /* max buffer cache KVA storage */
90 enum vmm_guest_type vmm_guest = VMM_GUEST_NONE; /* Running as VM guest? */
91 u_quad_t        maxtsiz;                        /* max text size */
92 u_quad_t        dfldsiz;                        /* initial data size limit */
93 u_quad_t        maxdsiz;                        /* max data size */
94 u_quad_t        dflssiz;                        /* initial stack size limit */
95 u_quad_t        maxssiz;                        /* max stack size */
96 u_quad_t        sgrowsiz;                       /* amount to grow stack */
97 u_quad_t        maxthrssiz;                     /* thread stack area */
98
99 SYSCTL_PROC(_kern, OID_AUTO, vmm_guest, CTLFLAG_RD | CTLTYPE_STRING,
100             NULL, 0, sysctl_kern_vmm_guest, "A",
101             "Virtual machine guest type");
102 SYSCTL_QUAD(_kern, OID_AUTO, maxssiz, CTLFLAG_RD, &maxssiz, 0,
103             "Maximum user stack size");
104 SYSCTL_QUAD(_kern, OID_AUTO, maxthrssiz, CTLFLAG_RD, &maxthrssiz, 0,
105             "Nominal threading stack area");
106
107 /*
108  * These have to be allocated somewhere; allocating
109  * them here forces loader errors if this file is omitted
110  * (if they've been externed everywhere else; hah!).
111  */
112 struct  buf *swbuf_mem;
113 struct  buf *swbuf_kva;
114 struct  buf *swbuf_raw;
115
116 struct vmm_bname {
117         const char *str;
118         enum vmm_guest_type type;
119 };
120
121 static struct vmm_bname vmm_bnames[] = {
122         { "QEMU",       VMM_GUEST_QEMU },       /* QEMU */
123         { "Plex86",     VMM_GUEST_PLEX86 },     /* Plex86 */
124         { "Bochs",      VMM_GUEST_BOCHS },      /* Bochs */
125         { "Xen",        VMM_GUEST_XEN },        /* Xen */
126         { "BHYVE",      VMM_GUEST_BHYVE },      /* bhyve */
127         { "Seabios",    VMM_GUEST_KVM},         /* KVM */
128         { NULL, 0 }
129 };
130
131 static struct vmm_bname vmm_pnames[] = {
132         { "VMware Virtual Platform",    VMM_GUEST_VMWARE },     /* VMWare VM */
133         { "Virtual Machine",            VMM_GUEST_HYPERV },     /* MS Hyper-V */
134         { "VirtualBox",                 VMM_GUEST_VBOX },       /* Sun VirtualBox */
135         { "Parallels Virtual Platform", VMM_GUEST_PARALLELS },  /* Parallels VM */
136         { "KVM",                        VMM_GUEST_KVM },        /* KVM */
137         { NULL, 0 }
138 };
139
140 static const char *const vmm_guest_sysctl_names[] = {
141         "none",
142         "qemu",
143         "plex86",
144         "bochs",
145         "xen",
146         "bhyve",
147         "kvm",
148         "vmware",
149         "hyperv",
150         "vbox",
151         "parallels",
152         "vkernel",
153         "nvmm",
154         "unknown",
155         NULL
156 };
157 CTASSERT(NELEM(vmm_guest_sysctl_names) - 1 == VMM_GUEST_LAST);
158
159 char            vmm_vendor[16];
160 SYSCTL_STRING(_kern, OID_AUTO, vmm_vendor, CTLFLAG_RD, vmm_vendor, 0,
161     "Virtual machine vendor");
162
163 /*
164  * Detect known Virtual Machine hosts by inspecting the emulated BIOS.
165  */
166 enum vmm_guest_type
167 detect_virtual(void)
168 {
169         char *sysenv;
170         int i;
171
172         sysenv = kgetenv("smbios.bios.vendor");
173         if (sysenv != NULL) {
174                 for (i = 0; vmm_bnames[i].str != NULL; i++)
175                         if (strcmp(sysenv, vmm_bnames[i].str) == 0) {
176                                 kfreeenv(sysenv);
177                                 return (vmm_bnames[i].type);
178                         }
179                 kfreeenv(sysenv);
180         }
181         sysenv = kgetenv("smbios.system.product");
182         if (sysenv != NULL) {
183                 for (i = 0; vmm_pnames[i].str != NULL; i++)
184                         if (strcmp(sysenv, vmm_pnames[i].str) == 0) {
185                                 kfreeenv(sysenv);
186                                 return (vmm_pnames[i].type);
187                         }
188                 kfreeenv(sysenv);
189         }
190         return (VMM_GUEST_NONE);
191 }
192
193 /*
194  * Boot time overrides that are not scaled against main memory
195  */
196 void
197 init_param1(void)
198 {
199         hz = HZ_DEFAULT;
200         TUNABLE_INT_FETCH("kern.hz", &hz);
201         stathz = hz + 1;
202         TUNABLE_INT_FETCH("kern.stathz", &stathz);
203         profhz = stathz;
204         ustick = 1000000 / hz;
205         nstick = 1000000000 / hz;
206         /* can adjust 30ms in 60s */
207         ntp_default_tick_delta = howmany(30000000, 60 * hz);
208
209 #ifdef VM_SWZONE_SIZE_MAX
210         maxswzone = VM_SWZONE_SIZE_MAX;
211 #endif
212         TUNABLE_LONG_FETCH("kern.maxswzone", &maxswzone);
213 #ifdef VM_BCACHE_SIZE_MAX
214         maxbcache = VM_BCACHE_SIZE_MAX;
215 #endif
216         TUNABLE_LONG_FETCH("kern.maxbcache", &maxbcache);
217         maxtsiz = MAXTSIZ;
218         TUNABLE_QUAD_FETCH("kern.maxtsiz", &maxtsiz);
219         dfldsiz = DFLDSIZ;
220         TUNABLE_QUAD_FETCH("kern.dfldsiz", &dfldsiz);
221         maxdsiz = MAXDSIZ;
222         TUNABLE_QUAD_FETCH("kern.maxdsiz", &maxdsiz);
223         dflssiz = DFLSSIZ;
224         TUNABLE_QUAD_FETCH("kern.dflssiz", &dflssiz);
225         maxssiz = MAXSSIZ;
226         TUNABLE_QUAD_FETCH("kern.maxssiz", &maxssiz);
227         sgrowsiz = SGROWSIZ;
228         TUNABLE_QUAD_FETCH("kern.sgrowsiz", &sgrowsiz);
229         maxthrssiz = MAXTHRSSIZ;
230         TUNABLE_QUAD_FETCH("kern.maxthrssiz", &maxthrssiz);
231 }
232
233 /*
234  * Boot time overrides that are scaled against main memory
235  */
236 void
237 init_param2(int physpages)
238 {
239         size_t limsize;
240
241         /*
242          * Calculate manually becaus the VM page queues / system is not set
243          * up yet.
244          */
245         limsize = (size_t)physpages * PAGE_SIZE;
246         if (limsize > KvaSize)
247                 limsize = KvaSize;
248         if (maxswzone > limsize / 2)    /* maxswzone size (1/2 of phys mem) */
249                 maxswzone = limsize / 2;
250
251         limsize /= 1024 * 1024;         /* smaller of KVM or physmem in MB */
252
253         /* Base parameters */
254         maxusers = MAXUSERS;
255         TUNABLE_INT_FETCH("kern.maxusers", &maxusers);
256         if (maxusers == 0) {
257                 maxusers = limsize / 8;         /* ~384 per 3G */
258                 if (maxusers < 32)
259                         maxusers = 32;
260                 /* no upper limit */
261         }
262
263         /*
264          * The following can be overridden after boot via sysctl.  Note:
265          * unless overridden, these macros are ultimately based on maxusers.
266          *
267          * Limit maxproc so that kmap entries cannot be exhausted by
268          * processes.  This limitation can be a bit problematic because
269          * processes can have a wide range of complexity.
270          */
271         maxproc = NPROC;
272         TUNABLE_INT_FETCH("kern.maxproc", &maxproc);
273         if (maxproc < 32)
274                 maxproc = 32;
275         if (maxproc > limsize * 40)
276                 maxproc = limsize * 40;
277
278         /*
279          * Maximum number of open files
280          */
281         maxfiles = MAXFILES;
282         TUNABLE_INT_FETCH("kern.maxfiles", &maxfiles);
283         if (maxfiles < 128)
284                 maxfiles = 128;
285
286         /*
287          * Limit file descriptors so no single user can exhaust the
288          * system.
289          *
290          * WARNING: Do not set minfilesperproc too high or the user
291          *          can exhaust the system with a combination of fork()
292          *          and open().  Actual worst case is:
293          *
294          *          (minfilesperproc * maxprocperuid) + maxfilesperuser
295          */
296         maxprocperuid = maxproc / 4;
297         if (maxprocperuid < 128)
298                 maxprocperuid = maxproc / 2;
299         minfilesperproc = 8;
300         maxfilesperproc = maxfiles / 4;
301         maxfilesperuser = maxfilesperproc * 2;
302         maxfilesrootres = maxfiles / 20;
303
304         /*
305          * Severe hack to try to prevent pipe() descriptors from
306          * blowing away kernel memory.
307          */
308         if (KvaSize <= (vm_offset_t)(1536LL * 1024 * 1024) &&
309             maxfilesperuser > 20000) {
310                 maxfilesperuser = 20000;
311         }
312
313         maxposixlocksperuid = MAXPOSIXLOCKSPERUID;
314         TUNABLE_INT_FETCH("kern.maxposixlocksperuid", &maxposixlocksperuid);
315
316         /*
317          * Unless overridden, NBUF is typically 0 (auto-sized later).
318          */
319         nbuf = NBUF;
320         TUNABLE_LONG_FETCH("kern.nbuf", &nbuf);
321
322         /*
323          * Calculate the size of the callout wheel.  Limit to approximately
324          * 5 minutes worth of table (maxproc would have to be pretty huge),
325          * as more is not likely to gain us anything.
326          */
327         ncallout = 16 + maxproc + maxfiles;
328         if (ncallout > 5*60*hz)
329                 ncallout = 5*60*hz;
330         TUNABLE_INT_FETCH("kern.ncallout", &ncallout);
331 }
332
333 /*
334  * Sysctl stringifying handler for kern.vmm_guest.
335  */
336 static int
337 sysctl_kern_vmm_guest(SYSCTL_HANDLER_ARGS)
338 {
339         return (SYSCTL_OUT(req, vmm_guest_sysctl_names[vmm_guest],
340             strlen(vmm_guest_sysctl_names[vmm_guest])));
341 }