]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/kern/kern_sysctl.c
vfs: use vnlru_read_freevnodes for the freevnodes sysctl
[FreeBSD/FreeBSD.git] / sys / kern / kern_sysctl.c
1 /*-
2  * SPDX-License-Identifier: BSD-3-Clause
3  *
4  * Copyright (c) 1982, 1986, 1989, 1993
5  *      The Regents of the University of California.  All rights reserved.
6  *
7  * This code is derived from software contributed to Berkeley by
8  * Mike Karels at Berkeley Software Design, Inc.
9  *
10  * Quite extensively rewritten by Poul-Henning Kamp of the FreeBSD
11  * project, to make these variables more userfriendly.
12  *
13  * Redistribution and use in source and binary forms, with or without
14  * modification, are permitted provided that the following conditions
15  * are met:
16  * 1. Redistributions of source code must retain the above copyright
17  *    notice, this list of conditions and the following disclaimer.
18  * 2. Redistributions in binary form must reproduce the above copyright
19  *    notice, this list of conditions and the following disclaimer in the
20  *    documentation and/or other materials provided with the distribution.
21  * 3. Neither the name of the University nor the names of its contributors
22  *    may be used to endorse or promote products derived from this software
23  *    without specific prior written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35  * SUCH DAMAGE.
36  *
37  *      @(#)kern_sysctl.c       8.4 (Berkeley) 4/14/94
38  */
39
40 #include <sys/cdefs.h>
41 #include "opt_capsicum.h"
42 #include "opt_ddb.h"
43 #include "opt_ktrace.h"
44 #include "opt_sysctl.h"
45
46 #include <sys/param.h>
47 #include <sys/fail.h>
48 #include <sys/systm.h>
49 #include <sys/capsicum.h>
50 #include <sys/kernel.h>
51 #include <sys/limits.h>
52 #include <sys/sysctl.h>
53 #include <sys/malloc.h>
54 #include <sys/priv.h>
55 #include <sys/proc.h>
56 #include <sys/jail.h>
57 #include <sys/kdb.h>
58 #include <sys/lock.h>
59 #include <sys/mutex.h>
60 #include <sys/rmlock.h>
61 #include <sys/sbuf.h>
62 #include <sys/sx.h>
63 #include <sys/sysproto.h>
64 #include <sys/uio.h>
65 #ifdef KTRACE
66 #include <sys/ktrace.h>
67 #endif
68
69 #ifdef DDB
70 #include <ddb/ddb.h>
71 #include <ddb/db_lex.h>
72 #endif
73
74 #include <net/vnet.h>
75
76 #include <security/mac/mac_framework.h>
77
78 #include <vm/vm.h>
79 #include <vm/vm_extern.h>
80
81 static MALLOC_DEFINE(M_SYSCTL, "sysctl", "sysctl internal magic");
82 static MALLOC_DEFINE(M_SYSCTLOID, "sysctloid", "sysctl dynamic oids");
83 static MALLOC_DEFINE(M_SYSCTLTMP, "sysctltmp", "sysctl temp output buffer");
84
85 /*
86  * The sysctllock protects the MIB tree.  It also protects sysctl
87  * contexts used with dynamic sysctls.  The sysctl_register_oid() and
88  * sysctl_unregister_oid() routines require the sysctllock to already
89  * be held, so the sysctl_wlock() and sysctl_wunlock() routines are
90  * provided for the few places in the kernel which need to use that
91  * API rather than using the dynamic API.  Use of the dynamic API is
92  * strongly encouraged for most code.
93  *
94  * The sysctlmemlock is used to limit the amount of user memory wired for
95  * sysctl requests.  This is implemented by serializing any userland
96  * sysctl requests larger than a single page via an exclusive lock.
97  *
98  * The sysctlstringlock is used to protect concurrent access to writable
99  * string nodes in sysctl_handle_string().
100  */
101 static struct rmlock sysctllock;
102 static struct sx __exclusive_cache_line sysctlmemlock;
103 static struct sx sysctlstringlock;
104
105 #define SYSCTL_WLOCK()          rm_wlock(&sysctllock)
106 #define SYSCTL_WUNLOCK()        rm_wunlock(&sysctllock)
107 #define SYSCTL_RLOCK(tracker)   rm_rlock(&sysctllock, (tracker))
108 #define SYSCTL_RUNLOCK(tracker) rm_runlock(&sysctllock, (tracker))
109 #define SYSCTL_WLOCKED()        rm_wowned(&sysctllock)
110 #define SYSCTL_ASSERT_LOCKED()  rm_assert(&sysctllock, RA_LOCKED)
111 #define SYSCTL_ASSERT_WLOCKED() rm_assert(&sysctllock, RA_WLOCKED)
112 #define SYSCTL_ASSERT_RLOCKED() rm_assert(&sysctllock, RA_RLOCKED)
113 #define SYSCTL_INIT()           rm_init_flags(&sysctllock, "sysctl lock", \
114                                     RM_SLEEPABLE)
115 #define SYSCTL_SLEEP(ch, wmesg, timo)                                   \
116                                 rm_sleep(ch, &sysctllock, 0, wmesg, timo)
117
118 static int sysctl_root(SYSCTL_HANDLER_ARGS);
119
120 /* Root list */
121 struct sysctl_oid_list sysctl__children = SLIST_HEAD_INITIALIZER(&sysctl__children);
122
123 static char*    sysctl_escape_name(const char*);
124 static int      sysctl_remove_oid_locked(struct sysctl_oid *oidp, int del,
125                     int recurse);
126 static int      sysctl_old_kernel(struct sysctl_req *, const void *, size_t);
127 static int      sysctl_new_kernel(struct sysctl_req *, void *, size_t);
128
129 static struct sysctl_oid *
130 sysctl_find_oidname(const char *name, struct sysctl_oid_list *list)
131 {
132         struct sysctl_oid *oidp;
133
134         SYSCTL_ASSERT_LOCKED();
135         SYSCTL_FOREACH(oidp, list) {
136                 if (strcmp(oidp->oid_name, name) == 0) {
137                         return (oidp);
138                 }
139         }
140         return (NULL);
141 }
142
143 /*
144  * Initialization of the MIB tree.
145  *
146  * Order by number in each list.
147  */
148 void
149 sysctl_wlock(void)
150 {
151
152         SYSCTL_WLOCK();
153 }
154
155 void
156 sysctl_wunlock(void)
157 {
158
159         SYSCTL_WUNLOCK();
160 }
161
162 static int
163 sysctl_root_handler_locked(struct sysctl_oid *oid, void *arg1, intmax_t arg2,
164     struct sysctl_req *req, struct rm_priotracker *tracker)
165 {
166         int error;
167
168         if (oid->oid_kind & CTLFLAG_DYN)
169                 atomic_add_int(&oid->oid_running, 1);
170
171         if (tracker != NULL)
172                 SYSCTL_RUNLOCK(tracker);
173         else
174                 SYSCTL_WUNLOCK();
175
176         /*
177          * Treat set CTLFLAG_NEEDGIANT and unset CTLFLAG_MPSAFE flags the same,
178          * untill we're ready to remove all traces of Giant from sysctl(9).
179          */
180         if ((oid->oid_kind & CTLFLAG_NEEDGIANT) ||
181             (!(oid->oid_kind & CTLFLAG_MPSAFE)))
182                 mtx_lock(&Giant);
183         error = oid->oid_handler(oid, arg1, arg2, req);
184         if ((oid->oid_kind & CTLFLAG_NEEDGIANT) ||
185             (!(oid->oid_kind & CTLFLAG_MPSAFE)))
186                 mtx_unlock(&Giant);
187
188         KFAIL_POINT_ERROR(_debug_fail_point, sysctl_running, error);
189
190         if (tracker != NULL)
191                 SYSCTL_RLOCK(tracker);
192         else
193                 SYSCTL_WLOCK();
194
195         if (oid->oid_kind & CTLFLAG_DYN) {
196                 if (atomic_fetchadd_int(&oid->oid_running, -1) == 1 &&
197                     (oid->oid_kind & CTLFLAG_DYING) != 0)
198                         wakeup(&oid->oid_running);
199         }
200
201         return (error);
202 }
203
204 static void
205 sysctl_load_tunable_by_oid_locked(struct sysctl_oid *oidp)
206 {
207         struct sysctl_req req;
208         struct sysctl_oid *curr;
209         char *penv = NULL;
210         char path[96];
211         ssize_t rem = sizeof(path);
212         ssize_t len;
213         uint8_t data[512] __aligned(sizeof(uint64_t));
214         int size;
215         int error;
216
217         path[--rem] = 0;
218
219         for (curr = oidp; curr != NULL; curr = SYSCTL_PARENT(curr)) {
220                 len = strlen(curr->oid_name);
221                 rem -= len;
222                 if (curr != oidp)
223                         rem -= 1;
224                 if (rem < 0) {
225                         printf("OID path exceeds %d bytes\n", (int)sizeof(path));
226                         return;
227                 }
228                 memcpy(path + rem, curr->oid_name, len);
229                 if (curr != oidp)
230                         path[rem + len] = '.';
231         }
232
233         memset(&req, 0, sizeof(req));
234
235         req.td = curthread;
236         req.oldfunc = sysctl_old_kernel;
237         req.newfunc = sysctl_new_kernel;
238         req.lock = REQ_UNWIRED;
239
240         switch (oidp->oid_kind & CTLTYPE) {
241         case CTLTYPE_INT:
242                 if (getenv_array(path + rem, data, sizeof(data), &size,
243                     sizeof(int), GETENV_SIGNED) == 0)
244                         return;
245                 req.newlen = size;
246                 req.newptr = data;
247                 break;
248         case CTLTYPE_UINT:
249                 if (getenv_array(path + rem, data, sizeof(data), &size,
250                     sizeof(int), GETENV_UNSIGNED) == 0)
251                         return;
252                 req.newlen = size;
253                 req.newptr = data;
254                 break;
255         case CTLTYPE_LONG:
256                 if (getenv_array(path + rem, data, sizeof(data), &size,
257                     sizeof(long), GETENV_SIGNED) == 0)
258                         return;
259                 req.newlen = size;
260                 req.newptr = data;
261                 break;
262         case CTLTYPE_ULONG:
263                 if (getenv_array(path + rem, data, sizeof(data), &size,
264                     sizeof(long), GETENV_UNSIGNED) == 0)
265                         return;
266                 req.newlen = size;
267                 req.newptr = data;
268                 break;
269         case CTLTYPE_S8:
270                 if (getenv_array(path + rem, data, sizeof(data), &size,
271                     sizeof(int8_t), GETENV_SIGNED) == 0)
272                         return;
273                 req.newlen = size;
274                 req.newptr = data;
275                 break;
276         case CTLTYPE_S16:
277                 if (getenv_array(path + rem, data, sizeof(data), &size,
278                     sizeof(int16_t), GETENV_SIGNED) == 0)
279                         return;
280                 req.newlen = size;
281                 req.newptr = data;
282                 break;
283         case CTLTYPE_S32:
284                 if (getenv_array(path + rem, data, sizeof(data), &size,
285                     sizeof(int32_t), GETENV_SIGNED) == 0)
286                         return;
287                 req.newlen = size;
288                 req.newptr = data;
289                 break;
290         case CTLTYPE_S64:
291                 if (getenv_array(path + rem, data, sizeof(data), &size,
292                     sizeof(int64_t), GETENV_SIGNED) == 0)
293                         return;
294                 req.newlen = size;
295                 req.newptr = data;
296                 break;
297         case CTLTYPE_U8:
298                 if (getenv_array(path + rem, data, sizeof(data), &size,
299                     sizeof(uint8_t), GETENV_UNSIGNED) == 0)
300                         return;
301                 req.newlen = size;
302                 req.newptr = data;
303                 break;
304         case CTLTYPE_U16:
305                 if (getenv_array(path + rem, data, sizeof(data), &size,
306                     sizeof(uint16_t), GETENV_UNSIGNED) == 0)
307                         return;
308                 req.newlen = size;
309                 req.newptr = data;
310                 break;
311         case CTLTYPE_U32:
312                 if (getenv_array(path + rem, data, sizeof(data), &size,
313                     sizeof(uint32_t), GETENV_UNSIGNED) == 0)
314                         return;
315                 req.newlen = size;
316                 req.newptr = data;
317                 break;
318         case CTLTYPE_U64:
319                 if (getenv_array(path + rem, data, sizeof(data), &size,
320                     sizeof(uint64_t), GETENV_UNSIGNED) == 0)
321                         return;
322                 req.newlen = size;
323                 req.newptr = data;
324                 break;
325         case CTLTYPE_STRING:
326                 penv = kern_getenv(path + rem);
327                 if (penv == NULL)
328                         return;
329                 req.newlen = strlen(penv);
330                 req.newptr = penv;
331                 break;
332         default:
333                 return;
334         }
335         error = sysctl_root_handler_locked(oidp, oidp->oid_arg1,
336             oidp->oid_arg2, &req, NULL);
337         if (error != 0)
338                 printf("Setting sysctl %s failed: %d\n", path + rem, error);
339         if (penv != NULL)
340                 freeenv(penv);
341 }
342
343 /*
344  * Locate the path to a given oid.  Returns the length of the resulting path,
345  * or -1 if the oid was not found.  nodes must have room for CTL_MAXNAME
346  * elements and be NULL initialized.
347  */
348 static int
349 sysctl_search_oid(struct sysctl_oid **nodes, struct sysctl_oid *needle)
350 {
351         int indx;
352
353         SYSCTL_ASSERT_LOCKED();
354         indx = 0;
355         while (indx < CTL_MAXNAME && indx >= 0) {
356                 if (nodes[indx] == NULL && indx == 0)
357                         nodes[indx] = SLIST_FIRST(&sysctl__children);
358                 else if (nodes[indx] == NULL)
359                         nodes[indx] = SLIST_FIRST(&nodes[indx - 1]->oid_children);
360                 else
361                         nodes[indx] = SLIST_NEXT(nodes[indx], oid_link);
362
363                 if (nodes[indx] == needle)
364                         return (indx + 1);
365
366                 if (nodes[indx] == NULL) {
367                         indx--;
368                         continue;
369                 }
370
371                 if ((nodes[indx]->oid_kind & CTLTYPE) == CTLTYPE_NODE) {
372                         indx++;
373                         continue;
374                 }
375         }
376         return (-1);
377 }
378
379 static void
380 sysctl_warn_reuse(const char *func, struct sysctl_oid *leaf)
381 {
382         struct sysctl_oid *nodes[CTL_MAXNAME];
383         char buf[128];
384         struct sbuf sb;
385         int rc, i;
386
387         (void)sbuf_new(&sb, buf, sizeof(buf), SBUF_FIXEDLEN | SBUF_INCLUDENUL);
388         sbuf_set_drain(&sb, sbuf_printf_drain, NULL);
389
390         sbuf_printf(&sb, "%s: can't re-use a leaf (", __func__);
391
392         memset(nodes, 0, sizeof(nodes));
393         rc = sysctl_search_oid(nodes, leaf);
394         if (rc > 0) {
395                 for (i = 0; i < rc; i++)
396                         sbuf_printf(&sb, "%s%.*s", nodes[i]->oid_name,
397                             i != (rc - 1), ".");
398         } else {
399                 sbuf_printf(&sb, "%s", leaf->oid_name);
400         }
401         sbuf_printf(&sb, ")!\n");
402
403         (void)sbuf_finish(&sb);
404 }
405
406 #ifdef SYSCTL_DEBUG
407 static int
408 sysctl_reuse_test(SYSCTL_HANDLER_ARGS)
409 {
410         struct rm_priotracker tracker;
411
412         SYSCTL_RLOCK(&tracker);
413         sysctl_warn_reuse(__func__, oidp);
414         SYSCTL_RUNLOCK(&tracker);
415         return (0);
416 }
417 SYSCTL_PROC(_sysctl, OID_AUTO, reuse_test,
418     CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, 0, 0, sysctl_reuse_test, "-",
419     "");
420 #endif
421
422 void
423 sysctl_register_oid(struct sysctl_oid *oidp)
424 {
425         struct sysctl_oid_list *parent = oidp->oid_parent;
426         struct sysctl_oid *p;
427         struct sysctl_oid *q;
428         int oid_number;
429         int timeout = 2;
430
431         /*
432          * First check if another oid with the same name already
433          * exists in the parent's list.
434          */
435         SYSCTL_ASSERT_WLOCKED();
436         p = sysctl_find_oidname(oidp->oid_name, parent);
437         if (p != NULL) {
438                 if ((p->oid_kind & CTLTYPE) == CTLTYPE_NODE) {
439                         p->oid_refcnt++;
440                         return;
441                 } else {
442                         sysctl_warn_reuse(__func__, p);
443                         return;
444                 }
445         }
446         /* get current OID number */
447         oid_number = oidp->oid_number;
448
449 #if (OID_AUTO >= 0)
450 #error "OID_AUTO is expected to be a negative value"
451 #endif  
452         /*
453          * Any negative OID number qualifies as OID_AUTO. Valid OID
454          * numbers should always be positive.
455          *
456          * NOTE: DO NOT change the starting value here, change it in
457          * <sys/sysctl.h>, and make sure it is at least 256 to
458          * accommodate e.g. net.inet.raw as a static sysctl node.
459          */
460         if (oid_number < 0) {
461                 static int newoid;
462
463                 /*
464                  * By decrementing the next OID number we spend less
465                  * time inserting the OIDs into a sorted list.
466                  */
467                 if (--newoid < CTL_AUTO_START)
468                         newoid = 0x7fffffff;
469
470                 oid_number = newoid;
471         }
472
473         /*
474          * Insert the OID into the parent's list sorted by OID number.
475          */
476 retry:
477         q = NULL;
478         SLIST_FOREACH(p, parent, oid_link) {
479                 /* check if the current OID number is in use */
480                 if (oid_number == p->oid_number) {
481                         /* get the next valid OID number */
482                         if (oid_number < CTL_AUTO_START ||
483                             oid_number == 0x7fffffff) {
484                                 /* wraparound - restart */
485                                 oid_number = CTL_AUTO_START;
486                                 /* don't loop forever */
487                                 if (!timeout--)
488                                         panic("sysctl: Out of OID numbers\n");
489                                 goto retry;
490                         } else {
491                                 oid_number++;
492                         }
493                 } else if (oid_number < p->oid_number)
494                         break;
495                 q = p;
496         }
497         /* check for non-auto OID number collision */
498         if (oidp->oid_number >= 0 && oidp->oid_number < CTL_AUTO_START &&
499             oid_number >= CTL_AUTO_START) {
500                 printf("sysctl: OID number(%d) is already in use for '%s'\n",
501                     oidp->oid_number, oidp->oid_name);
502         }
503         /* update the OID number, if any */
504         oidp->oid_number = oid_number;
505         if (q != NULL)
506                 SLIST_INSERT_AFTER(q, oidp, oid_link);
507         else
508                 SLIST_INSERT_HEAD(parent, oidp, oid_link);
509
510         if ((oidp->oid_kind & CTLTYPE) != CTLTYPE_NODE &&
511 #ifdef VIMAGE
512             (oidp->oid_kind & CTLFLAG_VNET) == 0 &&
513 #endif
514             (oidp->oid_kind & CTLFLAG_TUN) != 0 &&
515             (oidp->oid_kind & CTLFLAG_NOFETCH) == 0) {
516                 /* only fetch value once */
517                 oidp->oid_kind |= CTLFLAG_NOFETCH;
518                 /* try to fetch value from kernel environment */
519                 sysctl_load_tunable_by_oid_locked(oidp);
520         }
521 }
522
523 void
524 sysctl_register_disabled_oid(struct sysctl_oid *oidp)
525 {
526
527         /*
528          * Mark the leaf as dormant if it's not to be immediately enabled.
529          * We do not disable nodes as they can be shared between modules
530          * and it is always safe to access a node.
531          */
532         KASSERT((oidp->oid_kind & CTLFLAG_DORMANT) == 0,
533             ("internal flag is set in oid_kind"));
534         if ((oidp->oid_kind & CTLTYPE) != CTLTYPE_NODE)
535                 oidp->oid_kind |= CTLFLAG_DORMANT;
536         sysctl_register_oid(oidp);
537 }
538
539 void
540 sysctl_enable_oid(struct sysctl_oid *oidp)
541 {
542
543         SYSCTL_ASSERT_WLOCKED();
544         if ((oidp->oid_kind & CTLTYPE) == CTLTYPE_NODE) {
545                 KASSERT((oidp->oid_kind & CTLFLAG_DORMANT) == 0,
546                     ("sysctl node is marked as dormant"));
547                 return;
548         }
549         KASSERT((oidp->oid_kind & CTLFLAG_DORMANT) != 0,
550             ("enabling already enabled sysctl oid"));
551         oidp->oid_kind &= ~CTLFLAG_DORMANT;
552 }
553
554 void
555 sysctl_unregister_oid(struct sysctl_oid *oidp)
556 {
557         struct sysctl_oid *p;
558         int error;
559
560         SYSCTL_ASSERT_WLOCKED();
561         if (oidp->oid_number == OID_AUTO) {
562                 error = EINVAL;
563         } else {
564                 error = ENOENT;
565                 SLIST_FOREACH(p, oidp->oid_parent, oid_link) {
566                         if (p == oidp) {
567                                 SLIST_REMOVE(oidp->oid_parent, oidp,
568                                     sysctl_oid, oid_link);
569                                 error = 0;
570                                 break;
571                         }
572                 }
573         }
574
575         /* 
576          * This can happen when a module fails to register and is
577          * being unloaded afterwards.  It should not be a panic()
578          * for normal use.
579          */
580         if (error) {
581                 printf("%s: failed(%d) to unregister sysctl(%s)\n",
582                     __func__, error, oidp->oid_name);
583         }
584 }
585
586 /* Initialize a new context to keep track of dynamically added sysctls. */
587 int
588 sysctl_ctx_init(struct sysctl_ctx_list *c)
589 {
590
591         if (c == NULL) {
592                 return (EINVAL);
593         }
594
595         /*
596          * No locking here, the caller is responsible for not adding
597          * new nodes to a context until after this function has
598          * returned.
599          */
600         TAILQ_INIT(c);
601         return (0);
602 }
603
604 /* Free the context, and destroy all dynamic oids registered in this context */
605 int
606 sysctl_ctx_free(struct sysctl_ctx_list *clist)
607 {
608         struct sysctl_ctx_entry *e, *e1;
609         int error;
610
611         error = 0;
612         /*
613          * First perform a "dry run" to check if it's ok to remove oids.
614          * XXX FIXME
615          * XXX This algorithm is a hack. But I don't know any
616          * XXX better solution for now...
617          */
618         SYSCTL_WLOCK();
619         TAILQ_FOREACH(e, clist, link) {
620                 error = sysctl_remove_oid_locked(e->entry, 0, 0);
621                 if (error)
622                         break;
623         }
624         /*
625          * Restore deregistered entries, either from the end,
626          * or from the place where error occurred.
627          * e contains the entry that was not unregistered
628          */
629         if (error)
630                 e1 = TAILQ_PREV(e, sysctl_ctx_list, link);
631         else
632                 e1 = TAILQ_LAST(clist, sysctl_ctx_list);
633         while (e1 != NULL) {
634                 sysctl_register_oid(e1->entry);
635                 e1 = TAILQ_PREV(e1, sysctl_ctx_list, link);
636         }
637         if (error) {
638                 SYSCTL_WUNLOCK();
639                 return(EBUSY);
640         }
641         /* Now really delete the entries */
642         e = TAILQ_FIRST(clist);
643         while (e != NULL) {
644                 e1 = TAILQ_NEXT(e, link);
645                 error = sysctl_remove_oid_locked(e->entry, 1, 0);
646                 if (error)
647                         panic("sysctl_remove_oid: corrupt tree, entry: %s",
648                             e->entry->oid_name);
649                 free(e, M_SYSCTLOID);
650                 e = e1;
651         }
652         SYSCTL_WUNLOCK();
653         return (error);
654 }
655
656 /* Add an entry to the context */
657 struct sysctl_ctx_entry *
658 sysctl_ctx_entry_add(struct sysctl_ctx_list *clist, struct sysctl_oid *oidp)
659 {
660         struct sysctl_ctx_entry *e;
661
662         SYSCTL_ASSERT_WLOCKED();
663         if (clist == NULL || oidp == NULL)
664                 return(NULL);
665         e = malloc(sizeof(struct sysctl_ctx_entry), M_SYSCTLOID, M_WAITOK);
666         e->entry = oidp;
667         TAILQ_INSERT_HEAD(clist, e, link);
668         return (e);
669 }
670
671 /* Find an entry in the context */
672 struct sysctl_ctx_entry *
673 sysctl_ctx_entry_find(struct sysctl_ctx_list *clist, struct sysctl_oid *oidp)
674 {
675         struct sysctl_ctx_entry *e;
676
677         SYSCTL_ASSERT_WLOCKED();
678         if (clist == NULL || oidp == NULL)
679                 return(NULL);
680         TAILQ_FOREACH(e, clist, link) {
681                 if(e->entry == oidp)
682                         return(e);
683         }
684         return (e);
685 }
686
687 /*
688  * Delete an entry from the context.
689  * NOTE: this function doesn't free oidp! You have to remove it
690  * with sysctl_remove_oid().
691  */
692 int
693 sysctl_ctx_entry_del(struct sysctl_ctx_list *clist, struct sysctl_oid *oidp)
694 {
695         struct sysctl_ctx_entry *e;
696
697         if (clist == NULL || oidp == NULL)
698                 return (EINVAL);
699         SYSCTL_WLOCK();
700         e = sysctl_ctx_entry_find(clist, oidp);
701         if (e != NULL) {
702                 TAILQ_REMOVE(clist, e, link);
703                 SYSCTL_WUNLOCK();
704                 free(e, M_SYSCTLOID);
705                 return (0);
706         } else {
707                 SYSCTL_WUNLOCK();
708                 return (ENOENT);
709         }
710 }
711
712 /*
713  * Remove dynamically created sysctl trees.
714  * oidp - top of the tree to be removed
715  * del - if 0 - just deregister, otherwise free up entries as well
716  * recurse - if != 0 traverse the subtree to be deleted
717  */
718 int
719 sysctl_remove_oid(struct sysctl_oid *oidp, int del, int recurse)
720 {
721         int error;
722
723         SYSCTL_WLOCK();
724         error = sysctl_remove_oid_locked(oidp, del, recurse);
725         SYSCTL_WUNLOCK();
726         return (error);
727 }
728
729 int
730 sysctl_remove_name(struct sysctl_oid *parent, const char *name,
731     int del, int recurse)
732 {
733         struct sysctl_oid *p, *tmp;
734         int error;
735
736         error = ENOENT;
737         SYSCTL_WLOCK();
738         SLIST_FOREACH_SAFE(p, SYSCTL_CHILDREN(parent), oid_link, tmp) {
739                 if (strcmp(p->oid_name, name) == 0) {
740                         error = sysctl_remove_oid_locked(p, del, recurse);
741                         break;
742                 }
743         }
744         SYSCTL_WUNLOCK();
745
746         return (error);
747 }
748
749 /*
750  * Duplicate the provided string, escaping any illegal characters.  The result
751  * must be freed when no longer in use.
752  *
753  * The list of illegal characters is ".".
754  */
755 static char*
756 sysctl_escape_name(const char* orig)
757 {
758         int i, s = 0, d = 0, nillegals = 0;
759         char *new;
760
761         /* First count the number of illegal characters */
762         for (i = 0; orig[i] != '\0'; i++) {
763                 if (orig[i] == '.')
764                         nillegals++;
765         }
766
767         /* Allocate storage for new string */
768         new = malloc(i + 2 * nillegals + 1, M_SYSCTLOID, M_WAITOK);
769
770         /* Copy the name, escaping characters as we go */
771         while (orig[s] != '\0') {
772                 if (orig[s] == '.') {
773                         /* %25 is the hexadecimal representation of '.' */
774                         new[d++] = '%';
775                         new[d++] = '2';
776                         new[d++] = '5';
777                         s++;
778                 } else {
779                         new[d++] = orig[s++];
780                 }
781         }
782
783         /* Finally, nul-terminate */
784         new[d] = '\0';
785
786         return (new);
787 }
788
789 static int
790 sysctl_remove_oid_locked(struct sysctl_oid *oidp, int del, int recurse)
791 {
792         struct sysctl_oid *p, *tmp;
793         int error;
794
795         SYSCTL_ASSERT_WLOCKED();
796         if (oidp == NULL)
797                 return(EINVAL);
798         if ((oidp->oid_kind & CTLFLAG_DYN) == 0) {
799                 printf("Warning: can't remove non-dynamic nodes (%s)!\n",
800                     oidp->oid_name);
801                 return (EINVAL);
802         }
803         /*
804          * WARNING: normal method to do this should be through
805          * sysctl_ctx_free(). Use recursing as the last resort
806          * method to purge your sysctl tree of leftovers...
807          * However, if some other code still references these nodes,
808          * it will panic.
809          */
810         if ((oidp->oid_kind & CTLTYPE) == CTLTYPE_NODE) {
811                 if (oidp->oid_refcnt == 1) {
812                         SLIST_FOREACH_SAFE(p,
813                             SYSCTL_CHILDREN(oidp), oid_link, tmp) {
814                                 if (!recurse) {
815                                         printf("Warning: failed attempt to "
816                                             "remove oid %s with child %s\n",
817                                             oidp->oid_name, p->oid_name);
818                                         return (ENOTEMPTY);
819                                 }
820                                 error = sysctl_remove_oid_locked(p, del,
821                                     recurse);
822                                 if (error)
823                                         return (error);
824                         }
825                 }
826         }
827         if (oidp->oid_refcnt > 1 ) {
828                 oidp->oid_refcnt--;
829         } else {
830                 if (oidp->oid_refcnt == 0) {
831                         printf("Warning: bad oid_refcnt=%u (%s)!\n",
832                                 oidp->oid_refcnt, oidp->oid_name);
833                         return (EINVAL);
834                 }
835                 sysctl_unregister_oid(oidp);
836                 if (del) {
837                         /*
838                          * Wait for all threads running the handler to drain.
839                          * This preserves the previous behavior when the
840                          * sysctl lock was held across a handler invocation,
841                          * and is necessary for module unload correctness.
842                          */
843                         while (oidp->oid_running > 0) {
844                                 oidp->oid_kind |= CTLFLAG_DYING;
845                                 SYSCTL_SLEEP(&oidp->oid_running, "oidrm", 0);
846                         }
847                         if (oidp->oid_descr)
848                                 free(__DECONST(char *, oidp->oid_descr),
849                                     M_SYSCTLOID);
850                         if (oidp->oid_label)
851                                 free(__DECONST(char *, oidp->oid_label),
852                                     M_SYSCTLOID);
853                         free(__DECONST(char *, oidp->oid_name), M_SYSCTLOID);
854                         free(oidp, M_SYSCTLOID);
855                 }
856         }
857         return (0);
858 }
859 /*
860  * Create new sysctls at run time.
861  * clist may point to a valid context initialized with sysctl_ctx_init().
862  */
863 struct sysctl_oid *
864 sysctl_add_oid(struct sysctl_ctx_list *clist, struct sysctl_oid_list *parent,
865         int number, const char *name, int kind, void *arg1, intmax_t arg2,
866         int (*handler)(SYSCTL_HANDLER_ARGS), const char *fmt, const char *descr,
867         const char *label)
868 {
869         struct sysctl_oid *oidp;
870         char *escaped;
871
872         /* You have to hook up somewhere.. */
873         if (parent == NULL)
874                 return(NULL);
875         escaped = sysctl_escape_name(name);
876         /* Check if the node already exists, otherwise create it */
877         SYSCTL_WLOCK();
878         oidp = sysctl_find_oidname(escaped, parent);
879         if (oidp != NULL) {
880                 free(escaped, M_SYSCTLOID);
881                 if ((oidp->oid_kind & CTLTYPE) == CTLTYPE_NODE) {
882                         oidp->oid_refcnt++;
883                         /* Update the context */
884                         if (clist != NULL)
885                                 sysctl_ctx_entry_add(clist, oidp);
886                         SYSCTL_WUNLOCK();
887                         return (oidp);
888                 } else {
889                         sysctl_warn_reuse(__func__, oidp);
890                         SYSCTL_WUNLOCK();
891                         return (NULL);
892                 }
893         }
894         oidp = malloc(sizeof(struct sysctl_oid), M_SYSCTLOID, M_WAITOK|M_ZERO);
895         oidp->oid_parent = parent;
896         SLIST_INIT(&oidp->oid_children);
897         oidp->oid_number = number;
898         oidp->oid_refcnt = 1;
899         oidp->oid_name = escaped;
900         oidp->oid_handler = handler;
901         oidp->oid_kind = CTLFLAG_DYN | kind;
902         oidp->oid_arg1 = arg1;
903         oidp->oid_arg2 = arg2;
904         oidp->oid_fmt = fmt;
905         if (descr != NULL)
906                 oidp->oid_descr = strdup(descr, M_SYSCTLOID);
907         if (label != NULL)
908                 oidp->oid_label = strdup(label, M_SYSCTLOID);
909         /* Update the context, if used */
910         if (clist != NULL)
911                 sysctl_ctx_entry_add(clist, oidp);
912         /* Register this oid */
913         sysctl_register_oid(oidp);
914         SYSCTL_WUNLOCK();
915         return (oidp);
916 }
917
918 /*
919  * Rename an existing oid.
920  */
921 void
922 sysctl_rename_oid(struct sysctl_oid *oidp, const char *name)
923 {
924         char *newname;
925         char *oldname;
926
927         newname = strdup(name, M_SYSCTLOID);
928         SYSCTL_WLOCK();
929         oldname = __DECONST(char *, oidp->oid_name);
930         oidp->oid_name = newname;
931         SYSCTL_WUNLOCK();
932         free(oldname, M_SYSCTLOID);
933 }
934
935 /*
936  * Reparent an existing oid.
937  */
938 int
939 sysctl_move_oid(struct sysctl_oid *oid, struct sysctl_oid_list *parent)
940 {
941         struct sysctl_oid *oidp;
942
943         SYSCTL_WLOCK();
944         if (oid->oid_parent == parent) {
945                 SYSCTL_WUNLOCK();
946                 return (0);
947         }
948         oidp = sysctl_find_oidname(oid->oid_name, parent);
949         if (oidp != NULL) {
950                 SYSCTL_WUNLOCK();
951                 return (EEXIST);
952         }
953         sysctl_unregister_oid(oid);
954         oid->oid_parent = parent;
955         oid->oid_number = OID_AUTO;
956         sysctl_register_oid(oid);
957         SYSCTL_WUNLOCK();
958         return (0);
959 }
960
961 /*
962  * Register the kernel's oids on startup.
963  */
964 SET_DECLARE(sysctl_set, struct sysctl_oid);
965
966 static void
967 sysctl_register_all(void *arg)
968 {
969         struct sysctl_oid **oidp;
970
971         sx_init(&sysctlmemlock, "sysctl mem");
972         sx_init(&sysctlstringlock, "sysctl string handler");
973         SYSCTL_INIT();
974         SYSCTL_WLOCK();
975         SET_FOREACH(oidp, sysctl_set)
976                 sysctl_register_oid(*oidp);
977         SYSCTL_WUNLOCK();
978 }
979 SYSINIT(sysctl, SI_SUB_KMEM, SI_ORDER_FIRST, sysctl_register_all, NULL);
980
981 /*
982  * "Staff-functions"
983  *
984  * These functions implement a presently undocumented interface 
985  * used by the sysctl program to walk the tree, and get the type
986  * so it can print the value.
987  * This interface is under work and consideration, and should probably
988  * be killed with a big axe by the first person who can find the time.
989  * (be aware though, that the proper interface isn't as obvious as it
990  * may seem, there are various conflicting requirements.
991  *
992  * {CTL_SYSCTL, CTL_SYSCTL_DEBUG}               printf the entire MIB-tree.
993  * {CTL_SYSCTL, CTL_SYSCTL_NAME, ...}           return the name of the "..."
994  *                                              OID.
995  * {CTL_SYSCTL, CTL_SYSCTL_NEXT, ...}           return the next OID, honoring
996  *                                              CTLFLAG_SKIP.
997  * {CTL_SYSCTL, CTL_SYSCTL_NAME2OID}            return the OID of the name in
998  *                                              "new"
999  * {CTL_SYSCTL, CTL_SYSCTL_OIDFMT, ...}         return the kind & format info
1000  *                                              for the "..." OID.
1001  * {CTL_SYSCTL, CTL_SYSCTL_OIDDESCR, ...}       return the description of the
1002  *                                              "..." OID.
1003  * {CTL_SYSCTL, CTL_SYSCTL_OIDLABEL, ...}       return the aggregation label of
1004  *                                              the "..." OID.
1005  * {CTL_SYSCTL, CTL_SYSCTL_NEXTNOSKIP, ...}     return the next OID, ignoring
1006  *                                              CTLFLAG_SKIP.
1007  */
1008
1009 #ifdef SYSCTL_DEBUG
1010 static void
1011 sysctl_sysctl_debug_dump_node(struct sysctl_oid_list *l, int i)
1012 {
1013         int k;
1014         struct sysctl_oid *oidp;
1015
1016         SYSCTL_ASSERT_LOCKED();
1017         SYSCTL_FOREACH(oidp, l) {
1018                 for (k=0; k<i; k++)
1019                         printf(" ");
1020
1021                 printf("%d %s ", oidp->oid_number, oidp->oid_name);
1022
1023                 printf("%c%c",
1024                         oidp->oid_kind & CTLFLAG_RD ? 'R':' ',
1025                         oidp->oid_kind & CTLFLAG_WR ? 'W':' ');
1026
1027                 if (oidp->oid_handler)
1028                         printf(" *Handler");
1029
1030                 switch (oidp->oid_kind & CTLTYPE) {
1031                         case CTLTYPE_NODE:
1032                                 printf(" Node\n");
1033                                 if (!oidp->oid_handler) {
1034                                         sysctl_sysctl_debug_dump_node(
1035                                             SYSCTL_CHILDREN(oidp), i + 2);
1036                                 }
1037                                 break;
1038                         case CTLTYPE_INT:    printf(" Int\n"); break;
1039                         case CTLTYPE_UINT:   printf(" u_int\n"); break;
1040                         case CTLTYPE_LONG:   printf(" Long\n"); break;
1041                         case CTLTYPE_ULONG:  printf(" u_long\n"); break;
1042                         case CTLTYPE_STRING: printf(" String\n"); break;
1043                         case CTLTYPE_S8:     printf(" int8_t\n"); break;
1044                         case CTLTYPE_S16:    printf(" int16_t\n"); break;
1045                         case CTLTYPE_S32:    printf(" int32_t\n"); break;
1046                         case CTLTYPE_S64:    printf(" int64_t\n"); break;
1047                         case CTLTYPE_U8:     printf(" uint8_t\n"); break;
1048                         case CTLTYPE_U16:    printf(" uint16_t\n"); break;
1049                         case CTLTYPE_U32:    printf(" uint32_t\n"); break;
1050                         case CTLTYPE_U64:    printf(" uint64_t\n"); break;
1051                         case CTLTYPE_OPAQUE: printf(" Opaque/struct\n"); break;
1052                         default:             printf("\n");
1053                 }
1054         }
1055 }
1056
1057 static int
1058 sysctl_sysctl_debug(SYSCTL_HANDLER_ARGS)
1059 {
1060         struct rm_priotracker tracker;
1061         int error;
1062
1063         error = priv_check(req->td, PRIV_SYSCTL_DEBUG);
1064         if (error)
1065                 return (error);
1066         SYSCTL_RLOCK(&tracker);
1067         sysctl_sysctl_debug_dump_node(&sysctl__children, 0);
1068         SYSCTL_RUNLOCK(&tracker);
1069         return (ENOENT);
1070 }
1071
1072 SYSCTL_PROC(_sysctl, CTL_SYSCTL_DEBUG, debug, CTLTYPE_STRING | CTLFLAG_RD |
1073     CTLFLAG_MPSAFE, 0, 0, sysctl_sysctl_debug, "-", "");
1074 #endif
1075
1076 static int
1077 sysctl_sysctl_name(SYSCTL_HANDLER_ARGS)
1078 {
1079         int *name = (int *) arg1;
1080         u_int namelen = arg2;
1081         int error;
1082         struct sysctl_oid *oid;
1083         struct sysctl_oid_list *lsp = &sysctl__children, *lsp2;
1084         struct rm_priotracker tracker;
1085         char buf[10];
1086
1087         error = sysctl_wire_old_buffer(req, 0);
1088         if (error)
1089                 return (error);
1090
1091         SYSCTL_RLOCK(&tracker);
1092         while (namelen) {
1093                 if (!lsp) {
1094                         snprintf(buf,sizeof(buf),"%d",*name);
1095                         if (req->oldidx)
1096                                 error = SYSCTL_OUT(req, ".", 1);
1097                         if (!error)
1098                                 error = SYSCTL_OUT(req, buf, strlen(buf));
1099                         if (error)
1100                                 goto out;
1101                         namelen--;
1102                         name++;
1103                         continue;
1104                 }
1105                 lsp2 = NULL;
1106                 SLIST_FOREACH(oid, lsp, oid_link) {
1107                         if (oid->oid_number != *name)
1108                                 continue;
1109
1110                         if (req->oldidx)
1111                                 error = SYSCTL_OUT(req, ".", 1);
1112                         if (!error)
1113                                 error = SYSCTL_OUT(req, oid->oid_name,
1114                                         strlen(oid->oid_name));
1115                         if (error)
1116                                 goto out;
1117
1118                         namelen--;
1119                         name++;
1120
1121                         if ((oid->oid_kind & CTLTYPE) != CTLTYPE_NODE) 
1122                                 break;
1123
1124                         if (oid->oid_handler)
1125                                 break;
1126
1127                         lsp2 = SYSCTL_CHILDREN(oid);
1128                         break;
1129                 }
1130                 lsp = lsp2;
1131         }
1132         error = SYSCTL_OUT(req, "", 1);
1133  out:
1134         SYSCTL_RUNLOCK(&tracker);
1135         return (error);
1136 }
1137
1138 /*
1139  * XXXRW/JA: Shouldn't return name data for nodes that we don't permit in
1140  * capability mode.
1141  */
1142 static SYSCTL_NODE(_sysctl, CTL_SYSCTL_NAME, name, CTLFLAG_RD |
1143     CTLFLAG_MPSAFE | CTLFLAG_CAPRD, sysctl_sysctl_name, "");
1144
1145 enum sysctl_iter_action {
1146         ITER_SIBLINGS,  /* Not matched, continue iterating siblings */
1147         ITER_CHILDREN,  /* Node has children we need to iterate over them */
1148         ITER_FOUND,     /* Matching node was found */
1149 };
1150
1151 /*
1152  * Tries to find the next node for @name and @namelen.
1153  *
1154  * Returns next action to take. 
1155  */
1156 static enum sysctl_iter_action
1157 sysctl_sysctl_next_node(struct sysctl_oid *oidp, int *name, unsigned int namelen,
1158     bool honor_skip)
1159 {
1160
1161         if ((oidp->oid_kind & CTLFLAG_DORMANT) != 0)
1162                 return (ITER_SIBLINGS);
1163
1164         if (honor_skip && (oidp->oid_kind & CTLFLAG_SKIP) != 0)
1165                 return (ITER_SIBLINGS);
1166
1167         if (namelen == 0) {
1168                 /*
1169                  * We have reached a node with a full name match and are
1170                  * looking for the next oid in its children.
1171                  *
1172                  * For CTL_SYSCTL_NEXTNOSKIP we are done.
1173                  *
1174                  * For CTL_SYSCTL_NEXT we skip CTLTYPE_NODE (unless it
1175                  * has a handler) and move on to the children.
1176                  */
1177                 if (!honor_skip)
1178                         return (ITER_FOUND);
1179                 if ((oidp->oid_kind & CTLTYPE) != CTLTYPE_NODE) 
1180                         return (ITER_FOUND);
1181                 /* If node does not have an iterator, treat it as leaf */
1182                 if (oidp->oid_handler) 
1183                         return (ITER_FOUND);
1184
1185                 /* Report oid as a node to iterate */
1186                 return (ITER_CHILDREN);
1187         }
1188
1189         /*
1190          * No match yet. Continue seeking the given name.
1191          *
1192          * We are iterating in order by oid_number, so skip oids lower
1193          * than the one we are looking for.
1194          *
1195          * When the current oid_number is higher than the one we seek,
1196          * that means we have reached the next oid in the sequence and
1197          * should return it.
1198          *
1199          * If the oid_number matches the name at this level then we
1200          * have to find a node to continue searching at the next level.
1201          */
1202         if (oidp->oid_number < *name)
1203                 return (ITER_SIBLINGS);
1204         if (oidp->oid_number > *name) {
1205                 /*
1206                  * We have reached the next oid.
1207                  *
1208                  * For CTL_SYSCTL_NEXTNOSKIP we are done.
1209                  *
1210                  * For CTL_SYSCTL_NEXT we skip CTLTYPE_NODE (unless it
1211                  * has a handler) and move on to the children.
1212                  */
1213                 if (!honor_skip)
1214                         return (ITER_FOUND);
1215                 if ((oidp->oid_kind & CTLTYPE) != CTLTYPE_NODE)
1216                         return (ITER_FOUND);
1217                 /* If node does not have an iterator, treat it as leaf */
1218                 if (oidp->oid_handler)
1219                         return (ITER_FOUND);
1220                 return (ITER_CHILDREN);
1221         }
1222
1223         /* match at a current level */
1224         if ((oidp->oid_kind & CTLTYPE) != CTLTYPE_NODE)
1225                 return (ITER_SIBLINGS);
1226         if (oidp->oid_handler)
1227                 return (ITER_SIBLINGS);
1228
1229         return (ITER_CHILDREN);
1230 }
1231
1232 /*
1233  * Recursively walk the sysctl subtree at lsp until we find the given name.
1234  * Returns true and fills in next oid data in @next and @len if oid is found.
1235  */
1236 static bool
1237 sysctl_sysctl_next_action(struct sysctl_oid_list *lsp, int *name, u_int namelen, 
1238     int *next, int *len, int level, bool honor_skip)
1239 {
1240         struct sysctl_oid *oidp;
1241         bool success = false;
1242         enum sysctl_iter_action action;
1243
1244         SYSCTL_ASSERT_LOCKED();
1245         SLIST_FOREACH(oidp, lsp, oid_link) {
1246                 action = sysctl_sysctl_next_node(oidp, name, namelen, honor_skip);
1247                 if (action == ITER_SIBLINGS)
1248                         continue;
1249                 if (action == ITER_FOUND) {
1250                         success = true;
1251                         break;
1252                 }
1253                 KASSERT((action== ITER_CHILDREN), ("ret(%d)!=ITER_CHILDREN", action));
1254
1255                 lsp = SYSCTL_CHILDREN(oidp);
1256                 if (namelen == 0) {
1257                         success = sysctl_sysctl_next_action(lsp, NULL, 0,
1258                             next + 1, len, level + 1, honor_skip);
1259                 } else {
1260                         success = sysctl_sysctl_next_action(lsp, name + 1, namelen - 1,
1261                             next + 1, len, level + 1, honor_skip);
1262                         if (!success) {
1263
1264                                 /*
1265                                  * We maintain the invariant that current node oid
1266                                  * is >= the oid provided in @name.
1267                                  * As there are no usable children at this node,
1268                                  *  current node oid is strictly > than the requested
1269                                  *  oid.
1270                                  * Hence, reduce namelen to 0 to allow for picking first
1271                                  *  nodes/leafs in the next node in list.
1272                                  */
1273                                 namelen = 0;
1274                         }
1275                 }
1276                 if (success)
1277                         break;
1278         }
1279
1280         if (success) {
1281                 *next = oidp->oid_number;
1282                 if (level > *len)
1283                         *len = level;
1284         }
1285
1286         return (success);
1287 }
1288
1289 static int
1290 sysctl_sysctl_next(SYSCTL_HANDLER_ARGS)
1291 {
1292         int *name = (int *) arg1;
1293         u_int namelen = arg2;
1294         int len, error;
1295         bool success;
1296         struct sysctl_oid_list *lsp = &sysctl__children;
1297         struct rm_priotracker tracker;
1298         int next[CTL_MAXNAME];
1299
1300         len = 0;
1301         SYSCTL_RLOCK(&tracker);
1302         success = sysctl_sysctl_next_action(lsp, name, namelen, next, &len, 1,
1303             oidp->oid_number == CTL_SYSCTL_NEXT);
1304         SYSCTL_RUNLOCK(&tracker);
1305         if (!success)
1306                 return (ENOENT);
1307         error = SYSCTL_OUT(req, next, len * sizeof (int));
1308         return (error);
1309 }
1310
1311 /*
1312  * XXXRW/JA: Shouldn't return next data for nodes that we don't permit in
1313  * capability mode.
1314  */
1315 static SYSCTL_NODE(_sysctl, CTL_SYSCTL_NEXT, next, CTLFLAG_RD |
1316     CTLFLAG_MPSAFE | CTLFLAG_CAPRD, sysctl_sysctl_next, "");
1317
1318 static SYSCTL_NODE(_sysctl, CTL_SYSCTL_NEXTNOSKIP, nextnoskip, CTLFLAG_RD |
1319     CTLFLAG_MPSAFE | CTLFLAG_CAPRD, sysctl_sysctl_next, "");
1320
1321 static int
1322 name2oid(char *name, int *oid, int *len, struct sysctl_oid **oidpp)
1323 {
1324         struct sysctl_oid *oidp;
1325         struct sysctl_oid_list *lsp = &sysctl__children;
1326         char *p;
1327
1328         SYSCTL_ASSERT_LOCKED();
1329
1330         for (*len = 0; *len < CTL_MAXNAME;) {
1331                 p = strsep(&name, ".");
1332
1333                 SYSCTL_FOREACH(oidp, lsp) {
1334                         if (strcmp(p, oidp->oid_name) == 0)
1335                                 break;
1336                 }
1337                 if (oidp == NULL)
1338                         return (ENOENT);
1339                 *oid++ = oidp->oid_number;
1340                 (*len)++;
1341
1342                 if (name == NULL || *name == '\0') {
1343                         if (oidpp)
1344                                 *oidpp = oidp;
1345                         return (0);
1346                 }
1347
1348                 if ((oidp->oid_kind & CTLTYPE) != CTLTYPE_NODE)
1349                         break;
1350
1351                 if (oidp->oid_handler)
1352                         break;
1353
1354                 lsp = SYSCTL_CHILDREN(oidp);
1355         }
1356         return (ENOENT);
1357 }
1358
1359 static int
1360 sysctl_sysctl_name2oid(SYSCTL_HANDLER_ARGS)
1361 {
1362         char *p;
1363         int error, oid[CTL_MAXNAME], len = 0;
1364         struct sysctl_oid *op = NULL;
1365         struct rm_priotracker tracker;
1366         char buf[32];
1367
1368         if (!req->newlen) 
1369                 return (ENOENT);
1370         if (req->newlen >= MAXPATHLEN)  /* XXX arbitrary, undocumented */
1371                 return (ENAMETOOLONG);
1372
1373         p = buf;
1374         if (req->newlen >= sizeof(buf))
1375                 p = malloc(req->newlen+1, M_SYSCTL, M_WAITOK);
1376
1377         error = SYSCTL_IN(req, p, req->newlen);
1378         if (error) {
1379                 if (p != buf)
1380                         free(p, M_SYSCTL);
1381                 return (error);
1382         }
1383
1384         p [req->newlen] = '\0';
1385
1386         SYSCTL_RLOCK(&tracker);
1387         error = name2oid(p, oid, &len, &op);
1388         SYSCTL_RUNLOCK(&tracker);
1389
1390         if (p != buf)
1391                 free(p, M_SYSCTL);
1392
1393         if (error)
1394                 return (error);
1395
1396         error = SYSCTL_OUT(req, oid, len * sizeof *oid);
1397         return (error);
1398 }
1399
1400 /*
1401  * XXXRW/JA: Shouldn't return name2oid data for nodes that we don't permit in
1402  * capability mode.
1403  */
1404 SYSCTL_PROC(_sysctl, CTL_SYSCTL_NAME2OID, name2oid, CTLTYPE_INT | CTLFLAG_RW |
1405     CTLFLAG_ANYBODY | CTLFLAG_MPSAFE | CTLFLAG_CAPRW, 0, 0,
1406     sysctl_sysctl_name2oid, "I", "");
1407
1408 static int
1409 sysctl_sysctl_oidfmt(SYSCTL_HANDLER_ARGS)
1410 {
1411         struct sysctl_oid *oid;
1412         struct rm_priotracker tracker;
1413         int error;
1414
1415         error = sysctl_wire_old_buffer(req, 0);
1416         if (error)
1417                 return (error);
1418
1419         SYSCTL_RLOCK(&tracker);
1420         error = sysctl_find_oid(arg1, arg2, &oid, NULL, req);
1421         if (error)
1422                 goto out;
1423
1424         if (oid->oid_fmt == NULL) {
1425                 error = ENOENT;
1426                 goto out;
1427         }
1428         error = SYSCTL_OUT(req, &oid->oid_kind, sizeof(oid->oid_kind));
1429         if (error)
1430                 goto out;
1431         error = SYSCTL_OUT(req, oid->oid_fmt, strlen(oid->oid_fmt) + 1);
1432  out:
1433         SYSCTL_RUNLOCK(&tracker);
1434         return (error);
1435 }
1436
1437 static SYSCTL_NODE(_sysctl, CTL_SYSCTL_OIDFMT, oidfmt, CTLFLAG_RD |
1438     CTLFLAG_MPSAFE | CTLFLAG_CAPRD, sysctl_sysctl_oidfmt, "");
1439
1440 static int
1441 sysctl_sysctl_oiddescr(SYSCTL_HANDLER_ARGS)
1442 {
1443         struct sysctl_oid *oid;
1444         struct rm_priotracker tracker;
1445         int error;
1446
1447         error = sysctl_wire_old_buffer(req, 0);
1448         if (error)
1449                 return (error);
1450
1451         SYSCTL_RLOCK(&tracker);
1452         error = sysctl_find_oid(arg1, arg2, &oid, NULL, req);
1453         if (error)
1454                 goto out;
1455
1456         if (oid->oid_descr == NULL) {
1457                 error = ENOENT;
1458                 goto out;
1459         }
1460         error = SYSCTL_OUT(req, oid->oid_descr, strlen(oid->oid_descr) + 1);
1461  out:
1462         SYSCTL_RUNLOCK(&tracker);
1463         return (error);
1464 }
1465
1466 static SYSCTL_NODE(_sysctl, CTL_SYSCTL_OIDDESCR, oiddescr, CTLFLAG_RD |
1467     CTLFLAG_MPSAFE|CTLFLAG_CAPRD, sysctl_sysctl_oiddescr, "");
1468
1469 static int
1470 sysctl_sysctl_oidlabel(SYSCTL_HANDLER_ARGS)
1471 {
1472         struct sysctl_oid *oid;
1473         struct rm_priotracker tracker;
1474         int error;
1475
1476         error = sysctl_wire_old_buffer(req, 0);
1477         if (error)
1478                 return (error);
1479
1480         SYSCTL_RLOCK(&tracker);
1481         error = sysctl_find_oid(arg1, arg2, &oid, NULL, req);
1482         if (error)
1483                 goto out;
1484
1485         if (oid->oid_label == NULL) {
1486                 error = ENOENT;
1487                 goto out;
1488         }
1489         error = SYSCTL_OUT(req, oid->oid_label, strlen(oid->oid_label) + 1);
1490  out:
1491         SYSCTL_RUNLOCK(&tracker);
1492         return (error);
1493 }
1494
1495 static SYSCTL_NODE(_sysctl, CTL_SYSCTL_OIDLABEL, oidlabel, CTLFLAG_RD |
1496     CTLFLAG_MPSAFE | CTLFLAG_CAPRD, sysctl_sysctl_oidlabel, "");
1497
1498 /*
1499  * Default "handler" functions.
1500  */
1501
1502 /*
1503  * Handle a bool.
1504  * Two cases:
1505  *     a variable:  point arg1 at it.
1506  *     a constant:  pass it in arg2.
1507  */
1508
1509 int
1510 sysctl_handle_bool(SYSCTL_HANDLER_ARGS)
1511 {
1512         uint8_t temp;
1513         int error;
1514
1515         /*
1516          * Attempt to get a coherent snapshot by making a copy of the data.
1517          */
1518         if (arg1)
1519                 temp = *(bool *)arg1 ? 1 : 0;
1520         else
1521                 temp = arg2 ? 1 : 0;
1522
1523         error = SYSCTL_OUT(req, &temp, sizeof(temp));
1524         if (error || !req->newptr)
1525                 return (error);
1526
1527         if (!arg1)
1528                 error = EPERM;
1529         else {
1530                 error = SYSCTL_IN(req, &temp, sizeof(temp));
1531                 if (!error)
1532                         *(bool *)arg1 = temp ? 1 : 0;
1533         }
1534         return (error);
1535 }
1536
1537 /*
1538  * Handle an int8_t, signed or unsigned.
1539  * Two cases:
1540  *     a variable:  point arg1 at it.
1541  *     a constant:  pass it in arg2.
1542  */
1543
1544 int
1545 sysctl_handle_8(SYSCTL_HANDLER_ARGS)
1546 {
1547         int8_t tmpout;
1548         int error = 0;
1549
1550         /*
1551          * Attempt to get a coherent snapshot by making a copy of the data.
1552          */
1553         if (arg1)
1554                 tmpout = *(int8_t *)arg1;
1555         else
1556                 tmpout = arg2;
1557         error = SYSCTL_OUT(req, &tmpout, sizeof(tmpout));
1558
1559         if (error || !req->newptr)
1560                 return (error);
1561
1562         if (!arg1)
1563                 error = EPERM;
1564         else
1565                 error = SYSCTL_IN(req, arg1, sizeof(tmpout));
1566         return (error);
1567 }
1568
1569 /*
1570  * Handle an int16_t, signed or unsigned.
1571  * Two cases:
1572  *     a variable:  point arg1 at it.
1573  *     a constant:  pass it in arg2.
1574  */
1575
1576 int
1577 sysctl_handle_16(SYSCTL_HANDLER_ARGS)
1578 {
1579         int16_t tmpout;
1580         int error = 0;
1581
1582         /*
1583          * Attempt to get a coherent snapshot by making a copy of the data.
1584          */
1585         if (arg1)
1586                 tmpout = *(int16_t *)arg1;
1587         else
1588                 tmpout = arg2;
1589         error = SYSCTL_OUT(req, &tmpout, sizeof(tmpout));
1590
1591         if (error || !req->newptr)
1592                 return (error);
1593
1594         if (!arg1)
1595                 error = EPERM;
1596         else
1597                 error = SYSCTL_IN(req, arg1, sizeof(tmpout));
1598         return (error);
1599 }
1600
1601 /*
1602  * Handle an int32_t, signed or unsigned.
1603  * Two cases:
1604  *     a variable:  point arg1 at it.
1605  *     a constant:  pass it in arg2.
1606  */
1607
1608 int
1609 sysctl_handle_32(SYSCTL_HANDLER_ARGS)
1610 {
1611         int32_t tmpout;
1612         int error = 0;
1613
1614         /*
1615          * Attempt to get a coherent snapshot by making a copy of the data.
1616          */
1617         if (arg1)
1618                 tmpout = *(int32_t *)arg1;
1619         else
1620                 tmpout = arg2;
1621         error = SYSCTL_OUT(req, &tmpout, sizeof(tmpout));
1622
1623         if (error || !req->newptr)
1624                 return (error);
1625
1626         if (!arg1)
1627                 error = EPERM;
1628         else
1629                 error = SYSCTL_IN(req, arg1, sizeof(tmpout));
1630         return (error);
1631 }
1632
1633 /*
1634  * Handle an int, signed or unsigned.
1635  * Two cases:
1636  *     a variable:  point arg1 at it.
1637  *     a constant:  pass it in arg2.
1638  */
1639
1640 int
1641 sysctl_handle_int(SYSCTL_HANDLER_ARGS)
1642 {
1643         int tmpout, error = 0;
1644
1645         /*
1646          * Attempt to get a coherent snapshot by making a copy of the data.
1647          */
1648         if (arg1)
1649                 tmpout = *(int *)arg1;
1650         else
1651                 tmpout = arg2;
1652         error = SYSCTL_OUT(req, &tmpout, sizeof(int));
1653
1654         if (error || !req->newptr)
1655                 return (error);
1656
1657         if (!arg1)
1658                 error = EPERM;
1659         else
1660                 error = SYSCTL_IN(req, arg1, sizeof(int));
1661         return (error);
1662 }
1663
1664 /*
1665  * Based on on sysctl_handle_int() convert milliseconds into ticks.
1666  * Note: this is used by TCP.
1667  */
1668
1669 int
1670 sysctl_msec_to_ticks(SYSCTL_HANDLER_ARGS)
1671 {
1672         int error, s, tt;
1673
1674         tt = *(int *)arg1;
1675         s = (int)((int64_t)tt * 1000 / hz);
1676
1677         error = sysctl_handle_int(oidp, &s, 0, req);
1678         if (error || !req->newptr)
1679                 return (error);
1680
1681         tt = (int)((int64_t)s * hz / 1000);
1682         if (tt < 1)
1683                 return (EINVAL);
1684
1685         *(int *)arg1 = tt;
1686         return (0);
1687 }
1688
1689 /*
1690  * Handle a long, signed or unsigned.
1691  * Two cases:
1692  *     a variable:  point arg1 at it.
1693  *     a constant:  pass it in arg2.
1694  */
1695
1696 int
1697 sysctl_handle_long(SYSCTL_HANDLER_ARGS)
1698 {
1699         int error = 0;
1700         long tmplong;
1701 #ifdef SCTL_MASK32
1702         int tmpint;
1703 #endif
1704
1705         /*
1706          * Attempt to get a coherent snapshot by making a copy of the data.
1707          */
1708         if (arg1)
1709                 tmplong = *(long *)arg1;
1710         else
1711                 tmplong = arg2;
1712 #ifdef SCTL_MASK32
1713         if (req->flags & SCTL_MASK32) {
1714                 tmpint = tmplong;
1715                 error = SYSCTL_OUT(req, &tmpint, sizeof(int));
1716         } else
1717 #endif
1718                 error = SYSCTL_OUT(req, &tmplong, sizeof(long));
1719
1720         if (error || !req->newptr)
1721                 return (error);
1722
1723         if (!arg1)
1724                 error = EPERM;
1725 #ifdef SCTL_MASK32
1726         else if (req->flags & SCTL_MASK32) {
1727                 error = SYSCTL_IN(req, &tmpint, sizeof(int));
1728                 *(long *)arg1 = (long)tmpint;
1729         }
1730 #endif
1731         else
1732                 error = SYSCTL_IN(req, arg1, sizeof(long));
1733         return (error);
1734 }
1735
1736 /*
1737  * Handle a 64 bit int, signed or unsigned.
1738  * Two cases:
1739  *     a variable:  point arg1 at it.
1740  *     a constant:  pass it in arg2.
1741  */
1742 int
1743 sysctl_handle_64(SYSCTL_HANDLER_ARGS)
1744 {
1745         int error = 0;
1746         uint64_t tmpout;
1747
1748         /*
1749          * Attempt to get a coherent snapshot by making a copy of the data.
1750          */
1751         if (arg1)
1752                 tmpout = *(uint64_t *)arg1;
1753         else
1754                 tmpout = arg2;
1755         error = SYSCTL_OUT(req, &tmpout, sizeof(uint64_t));
1756
1757         if (error || !req->newptr)
1758                 return (error);
1759
1760         if (!arg1)
1761                 error = EPERM;
1762         else
1763                 error = SYSCTL_IN(req, arg1, sizeof(uint64_t));
1764         return (error);
1765 }
1766
1767 /*
1768  * Handle our generic '\0' terminated 'C' string.
1769  * Two cases:
1770  *      a variable string:  point arg1 at it, arg2 is max length.
1771  *      a constant string:  point arg1 at it, arg2 is zero.
1772  */
1773
1774 int
1775 sysctl_handle_string(SYSCTL_HANDLER_ARGS)
1776 {
1777         char *tmparg;
1778         size_t outlen;
1779         int error = 0, ro_string = 0;
1780
1781         /*
1782          * If the sysctl isn't writable and isn't a preallocated tunable that
1783          * can be modified by kenv(2), microoptimise and treat it as a
1784          * read-only string.
1785          * A zero-length buffer indicates a fixed size read-only
1786          * string.  In ddb, don't worry about trying to make a malloced
1787          * snapshot.
1788          */
1789         if ((oidp->oid_kind & (CTLFLAG_WR | CTLFLAG_TUN)) == 0 ||
1790             arg2 == 0 || kdb_active) {
1791                 arg2 = strlen((char *)arg1) + 1;
1792                 ro_string = 1;
1793         }
1794
1795         if (req->oldptr != NULL) {
1796                 if (ro_string) {
1797                         tmparg = arg1;
1798                         outlen = strlen(tmparg) + 1;
1799                 } else {
1800                         tmparg = malloc(arg2, M_SYSCTLTMP, M_WAITOK);
1801                         sx_slock(&sysctlstringlock);
1802                         memcpy(tmparg, arg1, arg2);
1803                         sx_sunlock(&sysctlstringlock);
1804                         outlen = strlen(tmparg) + 1;
1805                 }
1806
1807                 error = SYSCTL_OUT(req, tmparg, outlen);
1808
1809                 if (!ro_string)
1810                         free(tmparg, M_SYSCTLTMP);
1811         } else {
1812                 if (!ro_string)
1813                         sx_slock(&sysctlstringlock);
1814                 outlen = strlen((char *)arg1) + 1;
1815                 if (!ro_string)
1816                         sx_sunlock(&sysctlstringlock);
1817                 error = SYSCTL_OUT(req, NULL, outlen);
1818         }
1819         if (error || !req->newptr)
1820                 return (error);
1821
1822         if (req->newlen - req->newidx >= arg2 ||
1823             req->newlen - req->newidx < 0) {
1824                 error = EINVAL;
1825         } else if (req->newlen - req->newidx == 0) {
1826                 sx_xlock(&sysctlstringlock);
1827                 ((char *)arg1)[0] = '\0';
1828                 sx_xunlock(&sysctlstringlock);
1829         } else if (req->newfunc == sysctl_new_kernel) {
1830                 arg2 = req->newlen - req->newidx;
1831                 sx_xlock(&sysctlstringlock);
1832                 error = SYSCTL_IN(req, arg1, arg2);
1833                 if (error == 0) {
1834                         ((char *)arg1)[arg2] = '\0';
1835                         req->newidx += arg2;
1836                 }
1837                 sx_xunlock(&sysctlstringlock);
1838         } else {
1839                 arg2 = req->newlen - req->newidx;
1840                 tmparg = malloc(arg2, M_SYSCTLTMP, M_WAITOK);
1841
1842                 error = SYSCTL_IN(req, tmparg, arg2);
1843                 if (error) {
1844                         free(tmparg, M_SYSCTLTMP);
1845                         return (error);
1846                 }
1847
1848                 sx_xlock(&sysctlstringlock);
1849                 memcpy(arg1, tmparg, arg2);
1850                 ((char *)arg1)[arg2] = '\0';
1851                 sx_xunlock(&sysctlstringlock);
1852                 free(tmparg, M_SYSCTLTMP);
1853                 req->newidx += arg2;
1854         }
1855         return (error);
1856 }
1857
1858 /*
1859  * Handle any kind of opaque data.
1860  * arg1 points to it, arg2 is the size.
1861  */
1862
1863 int
1864 sysctl_handle_opaque(SYSCTL_HANDLER_ARGS)
1865 {
1866         int error, tries;
1867         u_int generation;
1868         struct sysctl_req req2;
1869
1870         /*
1871          * Attempt to get a coherent snapshot, by using the thread
1872          * pre-emption counter updated from within mi_switch() to
1873          * determine if we were pre-empted during a bcopy() or
1874          * copyout(). Make 3 attempts at doing this before giving up.
1875          * If we encounter an error, stop immediately.
1876          */
1877         tries = 0;
1878         req2 = *req;
1879 retry:
1880         generation = curthread->td_generation;
1881         error = SYSCTL_OUT(req, arg1, arg2);
1882         if (error)
1883                 return (error);
1884         tries++;
1885         if (generation != curthread->td_generation && tries < 3) {
1886                 *req = req2;
1887                 goto retry;
1888         }
1889
1890         error = SYSCTL_IN(req, arg1, arg2);
1891
1892         return (error);
1893 }
1894
1895 /*
1896  * Based on on sysctl_handle_int() convert microseconds to a sbintime.
1897  */
1898 int
1899 sysctl_usec_to_sbintime(SYSCTL_HANDLER_ARGS)
1900 {
1901         int error;
1902         int64_t tt;
1903         sbintime_t sb;
1904
1905         tt = *(int64_t *)arg1;
1906         sb = sbttous(tt);
1907
1908         error = sysctl_handle_64(oidp, &sb, 0, req);
1909         if (error || !req->newptr)
1910                 return (error);
1911
1912         tt = ustosbt(sb);
1913         *(int64_t *)arg1 = tt;
1914
1915         return (0);
1916 }
1917
1918 /*
1919  * Based on on sysctl_handle_int() convert milliseconds to a sbintime.
1920  */
1921 int
1922 sysctl_msec_to_sbintime(SYSCTL_HANDLER_ARGS)
1923 {
1924         int error;
1925         int64_t tt;
1926         sbintime_t sb;
1927
1928         tt = *(int64_t *)arg1;
1929         sb = sbttoms(tt);
1930
1931         error = sysctl_handle_64(oidp, &sb, 0, req);
1932         if (error || !req->newptr)
1933                 return (error);
1934
1935         tt = mstosbt(sb);
1936         *(int64_t *)arg1 = tt;
1937
1938         return (0);
1939 }
1940
1941 /*
1942  * Convert seconds to a struct timeval.  Intended for use with
1943  * intervals and thus does not permit negative seconds.
1944  */
1945 int
1946 sysctl_sec_to_timeval(SYSCTL_HANDLER_ARGS)
1947 {
1948         struct timeval *tv;
1949         int error, secs;
1950
1951         tv = arg1;
1952         secs = tv->tv_sec;
1953
1954         error = sysctl_handle_int(oidp, &secs, 0, req);
1955         if (error || req->newptr == NULL)
1956                 return (error);
1957
1958         if (secs < 0)
1959                 return (EINVAL);
1960         tv->tv_sec = secs;
1961
1962         return (0);
1963 }
1964
1965 /*
1966  * Transfer functions to/from kernel space.
1967  * XXX: rather untested at this point
1968  */
1969 static int
1970 sysctl_old_kernel(struct sysctl_req *req, const void *p, size_t l)
1971 {
1972         size_t i = 0;
1973
1974         if (req->oldptr) {
1975                 i = l;
1976                 if (req->oldlen <= req->oldidx)
1977                         i = 0;
1978                 else
1979                         if (i > req->oldlen - req->oldidx)
1980                                 i = req->oldlen - req->oldidx;
1981                 if (i > 0)
1982                         bcopy(p, (char *)req->oldptr + req->oldidx, i);
1983         }
1984         req->oldidx += l;
1985         if (req->oldptr && i != l)
1986                 return (ENOMEM);
1987         return (0);
1988 }
1989
1990 static int
1991 sysctl_new_kernel(struct sysctl_req *req, void *p, size_t l)
1992 {
1993         if (!req->newptr)
1994                 return (0);
1995         if (req->newlen - req->newidx < l)
1996                 return (EINVAL);
1997         bcopy((const char *)req->newptr + req->newidx, p, l);
1998         req->newidx += l;
1999         return (0);
2000 }
2001
2002 int
2003 kernel_sysctl(struct thread *td, int *name, u_int namelen, void *old,
2004     size_t *oldlenp, void *new, size_t newlen, size_t *retval, int flags)
2005 {
2006         int error = 0;
2007         struct sysctl_req req;
2008
2009         bzero(&req, sizeof req);
2010
2011         req.td = td;
2012         req.flags = flags;
2013
2014         if (oldlenp) {
2015                 req.oldlen = *oldlenp;
2016         }
2017         req.validlen = req.oldlen;
2018
2019         if (old) {
2020                 req.oldptr= old;
2021         }
2022
2023         if (new != NULL) {
2024                 req.newlen = newlen;
2025                 req.newptr = new;
2026         }
2027
2028         req.oldfunc = sysctl_old_kernel;
2029         req.newfunc = sysctl_new_kernel;
2030         req.lock = REQ_UNWIRED;
2031
2032         error = sysctl_root(0, name, namelen, &req);
2033
2034         if (req.lock == REQ_WIRED && req.validlen > 0)
2035                 vsunlock(req.oldptr, req.validlen);
2036
2037         if (error && error != ENOMEM)
2038                 return (error);
2039
2040         if (retval) {
2041                 if (req.oldptr && req.oldidx > req.validlen)
2042                         *retval = req.validlen;
2043                 else
2044                         *retval = req.oldidx;
2045         }
2046         return (error);
2047 }
2048
2049 int
2050 kernel_sysctlbyname(struct thread *td, char *name, void *old, size_t *oldlenp,
2051     void *new, size_t newlen, size_t *retval, int flags)
2052 {
2053         int oid[CTL_MAXNAME];
2054         size_t oidlen, plen;
2055         int error;
2056
2057         oid[0] = CTL_SYSCTL;
2058         oid[1] = CTL_SYSCTL_NAME2OID;
2059         oidlen = sizeof(oid);
2060
2061         error = kernel_sysctl(td, oid, 2, oid, &oidlen,
2062             (void *)name, strlen(name), &plen, flags);
2063         if (error)
2064                 return (error);
2065
2066         error = kernel_sysctl(td, oid, plen / sizeof(int), old, oldlenp,
2067             new, newlen, retval, flags);
2068         return (error);
2069 }
2070
2071 /*
2072  * Transfer function to/from user space.
2073  */
2074 static int
2075 sysctl_old_user(struct sysctl_req *req, const void *p, size_t l)
2076 {
2077         size_t i, len, origidx;
2078         int error;
2079
2080         origidx = req->oldidx;
2081         req->oldidx += l;
2082         if (req->oldptr == NULL)
2083                 return (0);
2084         /*
2085          * If we have not wired the user supplied buffer and we are currently
2086          * holding locks, drop a witness warning, as it's possible that
2087          * write operations to the user page can sleep.
2088          */
2089         if (req->lock != REQ_WIRED)
2090                 WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL,
2091                     "sysctl_old_user()");
2092         i = l;
2093         len = req->validlen;
2094         if (len <= origidx)
2095                 i = 0;
2096         else {
2097                 if (i > len - origidx)
2098                         i = len - origidx;
2099                 if (req->lock == REQ_WIRED) {
2100                         error = copyout_nofault(p, (char *)req->oldptr +
2101                             origidx, i);
2102                 } else
2103                         error = copyout(p, (char *)req->oldptr + origidx, i);
2104                 if (error != 0)
2105                         return (error);
2106         }
2107         if (i < l)
2108                 return (ENOMEM);
2109         return (0);
2110 }
2111
2112 static int
2113 sysctl_new_user(struct sysctl_req *req, void *p, size_t l)
2114 {
2115         int error;
2116
2117         if (!req->newptr)
2118                 return (0);
2119         if (req->newlen - req->newidx < l)
2120                 return (EINVAL);
2121         WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL,
2122             "sysctl_new_user()");
2123         error = copyin((const char *)req->newptr + req->newidx, p, l);
2124         req->newidx += l;
2125         return (error);
2126 }
2127
2128 /*
2129  * Wire the user space destination buffer.  If set to a value greater than
2130  * zero, the len parameter limits the maximum amount of wired memory.
2131  */
2132 int
2133 sysctl_wire_old_buffer(struct sysctl_req *req, size_t len)
2134 {
2135         int ret;
2136         size_t wiredlen;
2137
2138         wiredlen = (len > 0 && len < req->oldlen) ? len : req->oldlen;
2139         ret = 0;
2140         if (req->lock != REQ_WIRED && req->oldptr &&
2141             req->oldfunc == sysctl_old_user) {
2142                 if (wiredlen != 0) {
2143                         ret = vslock(req->oldptr, wiredlen);
2144                         if (ret != 0) {
2145                                 if (ret != ENOMEM)
2146                                         return (ret);
2147                                 wiredlen = 0;
2148                         }
2149                 }
2150                 req->lock = REQ_WIRED;
2151                 req->validlen = wiredlen;
2152         }
2153         return (0);
2154 }
2155
2156 int
2157 sysctl_find_oid(int *name, u_int namelen, struct sysctl_oid **noid,
2158     int *nindx, struct sysctl_req *req)
2159 {
2160         struct sysctl_oid_list *lsp;
2161         struct sysctl_oid *oid;
2162         int indx;
2163
2164         SYSCTL_ASSERT_LOCKED();
2165         lsp = &sysctl__children;
2166         indx = 0;
2167         while (indx < CTL_MAXNAME) {
2168                 SLIST_FOREACH(oid, lsp, oid_link) {
2169                         if (oid->oid_number == name[indx])
2170                                 break;
2171                 }
2172                 if (oid == NULL)
2173                         return (ENOENT);
2174
2175                 indx++;
2176                 if ((oid->oid_kind & CTLTYPE) == CTLTYPE_NODE) {
2177                         if (oid->oid_handler != NULL || indx == namelen) {
2178                                 *noid = oid;
2179                                 if (nindx != NULL)
2180                                         *nindx = indx;
2181                                 KASSERT((oid->oid_kind & CTLFLAG_DYING) == 0,
2182                                     ("%s found DYING node %p", __func__, oid));
2183                                 return (0);
2184                         }
2185                         lsp = SYSCTL_CHILDREN(oid);
2186                 } else if (indx == namelen) {
2187                         if ((oid->oid_kind & CTLFLAG_DORMANT) != 0)
2188                                 return (ENOENT);
2189                         *noid = oid;
2190                         if (nindx != NULL)
2191                                 *nindx = indx;
2192                         KASSERT((oid->oid_kind & CTLFLAG_DYING) == 0,
2193                             ("%s found DYING node %p", __func__, oid));
2194                         return (0);
2195                 } else {
2196                         return (ENOTDIR);
2197                 }
2198         }
2199         return (ENOENT);
2200 }
2201
2202 /*
2203  * Traverse our tree, and find the right node, execute whatever it points
2204  * to, and return the resulting error code.
2205  */
2206
2207 static int
2208 sysctl_root(SYSCTL_HANDLER_ARGS)
2209 {
2210         struct sysctl_oid *oid;
2211         struct rm_priotracker tracker;
2212         int error, indx, lvl;
2213
2214         SYSCTL_RLOCK(&tracker);
2215
2216         error = sysctl_find_oid(arg1, arg2, &oid, &indx, req);
2217         if (error)
2218                 goto out;
2219
2220         if ((oid->oid_kind & CTLTYPE) == CTLTYPE_NODE) {
2221                 /*
2222                  * You can't call a sysctl when it's a node, but has
2223                  * no handler.  Inform the user that it's a node.
2224                  * The indx may or may not be the same as namelen.
2225                  */
2226                 if (oid->oid_handler == NULL) {
2227                         error = EISDIR;
2228                         goto out;
2229                 }
2230         }
2231
2232         /* Is this sysctl writable? */
2233         if (req->newptr && !(oid->oid_kind & CTLFLAG_WR)) {
2234                 error = EPERM;
2235                 goto out;
2236         }
2237
2238         KASSERT(req->td != NULL, ("sysctl_root(): req->td == NULL"));
2239
2240 #ifdef CAPABILITY_MODE
2241         /*
2242          * If the process is in capability mode, then don't permit reading or
2243          * writing unless specifically granted for the node.
2244          */
2245         if (IN_CAPABILITY_MODE(req->td)) {
2246                 if ((req->oldptr && !(oid->oid_kind & CTLFLAG_CAPRD)) ||
2247                     (req->newptr && !(oid->oid_kind & CTLFLAG_CAPWR))) {
2248                         error = EPERM;
2249                         goto out;
2250                 }
2251         }
2252 #endif
2253
2254         /* Is this sysctl sensitive to securelevels? */
2255         if (req->newptr && (oid->oid_kind & CTLFLAG_SECURE)) {
2256                 lvl = (oid->oid_kind & CTLMASK_SECURE) >> CTLSHIFT_SECURE;
2257                 error = securelevel_gt(req->td->td_ucred, lvl);
2258                 if (error)
2259                         goto out;
2260         }
2261
2262         /* Is this sysctl writable by only privileged users? */
2263         if (req->newptr && !(oid->oid_kind & CTLFLAG_ANYBODY)) {
2264                 int priv;
2265
2266                 if (oid->oid_kind & CTLFLAG_PRISON)
2267                         priv = PRIV_SYSCTL_WRITEJAIL;
2268 #ifdef VIMAGE
2269                 else if ((oid->oid_kind & CTLFLAG_VNET) &&
2270                      prison_owns_vnet(req->td->td_ucred))
2271                         priv = PRIV_SYSCTL_WRITEJAIL;
2272 #endif
2273                 else
2274                         priv = PRIV_SYSCTL_WRITE;
2275                 error = priv_check(req->td, priv);
2276                 if (error)
2277                         goto out;
2278         }
2279
2280         if (!oid->oid_handler) {
2281                 error = EINVAL;
2282                 goto out;
2283         }
2284
2285         if ((oid->oid_kind & CTLTYPE) == CTLTYPE_NODE) {
2286                 arg1 = (int *)arg1 + indx;
2287                 arg2 -= indx;
2288         } else {
2289                 arg1 = oid->oid_arg1;
2290                 arg2 = oid->oid_arg2;
2291         }
2292 #ifdef MAC
2293         error = mac_system_check_sysctl(req->td->td_ucred, oid, arg1, arg2,
2294             req);
2295         if (error != 0)
2296                 goto out;
2297 #endif
2298 #ifdef VIMAGE
2299         if ((oid->oid_kind & CTLFLAG_VNET) && arg1 != NULL)
2300                 arg1 = (void *)(curvnet->vnet_data_base + (uintptr_t)arg1);
2301 #endif
2302         error = sysctl_root_handler_locked(oid, arg1, arg2, req, &tracker);
2303
2304 out:
2305         SYSCTL_RUNLOCK(&tracker);
2306         return (error);
2307 }
2308
2309 #ifndef _SYS_SYSPROTO_H_
2310 struct sysctl_args {
2311         int     *name;
2312         u_int   namelen;
2313         void    *old;
2314         size_t  *oldlenp;
2315         void    *new;
2316         size_t  newlen;
2317 };
2318 #endif
2319 int
2320 sys___sysctl(struct thread *td, struct sysctl_args *uap)
2321 {
2322         int error, i, name[CTL_MAXNAME];
2323         size_t j;
2324
2325         if (uap->namelen > CTL_MAXNAME || uap->namelen < 2)
2326                 return (EINVAL);
2327
2328         error = copyin(uap->name, &name, uap->namelen * sizeof(int));
2329         if (error)
2330                 return (error);
2331
2332         error = userland_sysctl(td, name, uap->namelen,
2333                 uap->old, uap->oldlenp, 0,
2334                 uap->new, uap->newlen, &j, 0);
2335         if (error && error != ENOMEM)
2336                 return (error);
2337         if (uap->oldlenp) {
2338                 i = copyout(&j, uap->oldlenp, sizeof(j));
2339                 if (i)
2340                         return (i);
2341         }
2342         return (error);
2343 }
2344
2345 int
2346 kern___sysctlbyname(struct thread *td, const char *oname, size_t namelen,
2347     void *old, size_t *oldlenp, void *new, size_t newlen, size_t *retval,
2348     int flags, bool inkernel)
2349 {
2350         int oid[CTL_MAXNAME];
2351         char namebuf[16];
2352         char *name;
2353         size_t oidlen;
2354         int error;
2355
2356         if (namelen > MAXPATHLEN || namelen == 0)
2357                 return (EINVAL);
2358         name = namebuf;
2359         if (namelen > sizeof(namebuf))
2360                 name = malloc(namelen, M_SYSCTL, M_WAITOK);
2361         error = copyin(oname, name, namelen);
2362         if (error != 0)
2363                 goto out;
2364
2365         oid[0] = CTL_SYSCTL;
2366         oid[1] = CTL_SYSCTL_NAME2OID;
2367         oidlen = sizeof(oid);
2368         error = kernel_sysctl(td, oid, 2, oid, &oidlen, (void *)name, namelen,
2369             retval, flags);
2370         if (error != 0)
2371                 goto out;
2372         error = userland_sysctl(td, oid, *retval / sizeof(int), old, oldlenp,
2373             inkernel, new, newlen, retval, flags);
2374
2375 out:
2376         if (namelen > sizeof(namebuf))
2377                 free(name, M_SYSCTL);
2378         return (error);
2379 }
2380
2381 #ifndef _SYS_SYSPROTO_H_
2382 struct __sysctlbyname_args {
2383         const char      *name;
2384         size_t  namelen;
2385         void    *old;
2386         size_t  *oldlenp;
2387         void    *new;
2388         size_t  newlen;
2389 };
2390 #endif
2391 int
2392 sys___sysctlbyname(struct thread *td, struct __sysctlbyname_args *uap)
2393 {
2394         size_t rv;
2395         int error;
2396
2397         error = kern___sysctlbyname(td, uap->name, uap->namelen, uap->old,
2398             uap->oldlenp, uap->new, uap->newlen, &rv, 0, 0);
2399         if (error != 0)
2400                 return (error);
2401         if (uap->oldlenp != NULL)
2402                 error = copyout(&rv, uap->oldlenp, sizeof(rv));
2403
2404         return (error);
2405 }
2406
2407 /*
2408  * This is used from various compatibility syscalls too.  That's why name
2409  * must be in kernel space.
2410  */
2411 int
2412 userland_sysctl(struct thread *td, int *name, u_int namelen, void *old,
2413     size_t *oldlenp, int inkernel, const void *new, size_t newlen,
2414     size_t *retval, int flags)
2415 {
2416         int error = 0, memlocked;
2417         struct sysctl_req req;
2418
2419         bzero(&req, sizeof req);
2420
2421         req.td = td;
2422         req.flags = flags;
2423
2424         if (oldlenp) {
2425                 if (inkernel) {
2426                         req.oldlen = *oldlenp;
2427                 } else {
2428                         error = copyin(oldlenp, &req.oldlen, sizeof(*oldlenp));
2429                         if (error)
2430                                 return (error);
2431                 }
2432         }
2433         req.validlen = req.oldlen;
2434         req.oldptr = old;
2435
2436         if (new != NULL) {
2437                 req.newlen = newlen;
2438                 req.newptr = new;
2439         }
2440
2441         req.oldfunc = sysctl_old_user;
2442         req.newfunc = sysctl_new_user;
2443         req.lock = REQ_UNWIRED;
2444
2445 #ifdef KTRACE
2446         if (KTRPOINT(curthread, KTR_SYSCTL))
2447                 ktrsysctl(name, namelen);
2448 #endif
2449         memlocked = 0;
2450         if (req.oldptr && req.oldlen > 4 * PAGE_SIZE) {
2451                 memlocked = 1;
2452                 sx_xlock(&sysctlmemlock);
2453         }
2454         CURVNET_SET(TD_TO_VNET(td));
2455
2456         for (;;) {
2457                 req.oldidx = 0;
2458                 req.newidx = 0;
2459                 error = sysctl_root(0, name, namelen, &req);
2460                 if (error != EAGAIN)
2461                         break;
2462                 kern_yield(PRI_USER);
2463         }
2464
2465         CURVNET_RESTORE();
2466
2467         if (req.lock == REQ_WIRED && req.validlen > 0)
2468                 vsunlock(req.oldptr, req.validlen);
2469         if (memlocked)
2470                 sx_xunlock(&sysctlmemlock);
2471
2472         if (error && error != ENOMEM)
2473                 return (error);
2474
2475         if (retval) {
2476                 if (req.oldptr && req.oldidx > req.validlen)
2477                         *retval = req.validlen;
2478                 else
2479                         *retval = req.oldidx;
2480         }
2481         return (error);
2482 }
2483
2484 /*
2485  * Drain into a sysctl struct.  The user buffer should be wired if a page
2486  * fault would cause issue.
2487  */
2488 static int
2489 sbuf_sysctl_drain(void *arg, const char *data, int len)
2490 {
2491         struct sysctl_req *req = arg;
2492         int error;
2493
2494         error = SYSCTL_OUT(req, data, len);
2495         KASSERT(error >= 0, ("Got unexpected negative value %d", error));
2496         return (error == 0 ? len : -error);
2497 }
2498
2499 struct sbuf *
2500 sbuf_new_for_sysctl(struct sbuf *s, char *buf, int length,
2501     struct sysctl_req *req)
2502 {
2503
2504         /* Supply a default buffer size if none given. */
2505         if (buf == NULL && length == 0)
2506                 length = 64;
2507         s = sbuf_new(s, buf, length, SBUF_FIXEDLEN | SBUF_INCLUDENUL);
2508         sbuf_set_drain(s, sbuf_sysctl_drain, req);
2509         return (s);
2510 }
2511
2512 #ifdef DDB
2513
2514 /* The current OID the debugger is working with */
2515 static struct sysctl_oid *g_ddb_oid;
2516
2517 /* The current flags specified by the user */
2518 static int g_ddb_sysctl_flags;
2519
2520 /* Check to see if the last sysctl printed */
2521 static int g_ddb_sysctl_printed;
2522
2523 static const int ctl_sign[CTLTYPE+1] = {
2524         [CTLTYPE_INT] = 1,
2525         [CTLTYPE_LONG] = 1,
2526         [CTLTYPE_S8] = 1,
2527         [CTLTYPE_S16] = 1,
2528         [CTLTYPE_S32] = 1,
2529         [CTLTYPE_S64] = 1,
2530 };
2531
2532 static const int ctl_size[CTLTYPE+1] = {
2533         [CTLTYPE_INT] = sizeof(int),
2534         [CTLTYPE_UINT] = sizeof(u_int),
2535         [CTLTYPE_LONG] = sizeof(long),
2536         [CTLTYPE_ULONG] = sizeof(u_long),
2537         [CTLTYPE_S8] = sizeof(int8_t),
2538         [CTLTYPE_S16] = sizeof(int16_t),
2539         [CTLTYPE_S32] = sizeof(int32_t),
2540         [CTLTYPE_S64] = sizeof(int64_t),
2541         [CTLTYPE_U8] = sizeof(uint8_t),
2542         [CTLTYPE_U16] = sizeof(uint16_t),
2543         [CTLTYPE_U32] = sizeof(uint32_t),
2544         [CTLTYPE_U64] = sizeof(uint64_t),
2545 };
2546
2547 #define DB_SYSCTL_NAME_ONLY     0x001   /* Compare with -N */
2548 #define DB_SYSCTL_VALUE_ONLY    0x002   /* Compare with -n */
2549 #define DB_SYSCTL_OPAQUE        0x004   /* Compare with -o */
2550 #define DB_SYSCTL_HEX           0x008   /* Compare with -x */
2551
2552 #define DB_SYSCTL_SAFE_ONLY     0x100   /* Only simple types */
2553
2554 static const char db_sysctl_modifs[] = {
2555         'N', 'n', 'o', 'x',
2556 };
2557
2558 static const int db_sysctl_modif_values[] = {
2559         DB_SYSCTL_NAME_ONLY, DB_SYSCTL_VALUE_ONLY,
2560         DB_SYSCTL_OPAQUE, DB_SYSCTL_HEX,
2561 };
2562
2563 /* Handlers considered safe to print while recursing */
2564 static int (* const db_safe_handlers[])(SYSCTL_HANDLER_ARGS) = {
2565         sysctl_handle_bool,
2566         sysctl_handle_8,
2567         sysctl_handle_16,
2568         sysctl_handle_32,
2569         sysctl_handle_64,
2570         sysctl_handle_int,
2571         sysctl_handle_long,
2572         sysctl_handle_string,
2573         sysctl_handle_opaque,
2574 };
2575
2576 /*
2577  * Use in place of sysctl_old_kernel to print sysctl values.
2578  *
2579  * Compare to the output handling in show_var from sbin/sysctl/sysctl.c
2580  */
2581 static int
2582 sysctl_old_ddb(struct sysctl_req *req, const void *ptr, size_t len)
2583 {
2584         const u_char *val, *p;
2585         const char *sep1;
2586         size_t intlen, slen;
2587         uintmax_t umv;
2588         intmax_t mv;
2589         int sign, ctltype, hexlen, xflag, error;
2590
2591         /* Suppress false-positive GCC uninitialized variable warnings */
2592         mv = 0;
2593         umv = 0;
2594
2595         slen = len;
2596         val = p = ptr;
2597
2598         if (ptr == NULL) {
2599                 error = 0;
2600                 goto out;
2601         }
2602
2603         /* We are going to print */
2604         g_ddb_sysctl_printed = 1;
2605
2606         xflag = g_ddb_sysctl_flags & DB_SYSCTL_HEX;
2607
2608         ctltype = (g_ddb_oid->oid_kind & CTLTYPE);
2609         sign = ctl_sign[ctltype];
2610         intlen = ctl_size[ctltype];
2611
2612         switch (ctltype) {
2613         case CTLTYPE_NODE:
2614         case CTLTYPE_STRING:
2615                 db_printf("%.*s", (int) len, (const char *) p);
2616                 error = 0;
2617                 goto out;
2618
2619         case CTLTYPE_INT:
2620         case CTLTYPE_UINT:
2621         case CTLTYPE_LONG:
2622         case CTLTYPE_ULONG:
2623         case CTLTYPE_S8:
2624         case CTLTYPE_S16:
2625         case CTLTYPE_S32:
2626         case CTLTYPE_S64:
2627         case CTLTYPE_U8:
2628         case CTLTYPE_U16:
2629         case CTLTYPE_U32:
2630         case CTLTYPE_U64:
2631                 hexlen = 2 + (intlen * CHAR_BIT + 3) / 4;
2632                 sep1 = "";
2633                 while (len >= intlen) {
2634                         switch (ctltype) {
2635                         case CTLTYPE_INT:
2636                         case CTLTYPE_UINT:
2637                                 umv = *(const u_int *)p;
2638                                 mv = *(const int *)p;
2639                                 break;
2640                         case CTLTYPE_LONG:
2641                         case CTLTYPE_ULONG:
2642                                 umv = *(const u_long *)p;
2643                                 mv = *(const long *)p;
2644                                 break;
2645                         case CTLTYPE_S8:
2646                         case CTLTYPE_U8:
2647                                 umv = *(const uint8_t *)p;
2648                                 mv = *(const int8_t *)p;
2649                                 break;
2650                         case CTLTYPE_S16:
2651                         case CTLTYPE_U16:
2652                                 umv = *(const uint16_t *)p;
2653                                 mv = *(const int16_t *)p;
2654                                 break;
2655                         case CTLTYPE_S32:
2656                         case CTLTYPE_U32:
2657                                 umv = *(const uint32_t *)p;
2658                                 mv = *(const int32_t *)p;
2659                                 break;
2660                         case CTLTYPE_S64:
2661                         case CTLTYPE_U64:
2662                                 umv = *(const uint64_t *)p;
2663                                 mv = *(const int64_t *)p;
2664                                 break;
2665                         }
2666
2667                         db_printf("%s", sep1);
2668                         if (xflag)
2669                                 db_printf("%#0*jx", hexlen, umv);
2670                         else if (!sign)
2671                                 db_printf("%ju", umv);
2672                         else if (g_ddb_oid->oid_fmt[1] == 'K') {
2673                                 /* Kelvins are currently unsupported. */
2674                                 error = EOPNOTSUPP;
2675                                 goto out;
2676                         } else
2677                                 db_printf("%jd", mv);
2678
2679                         sep1 = " ";
2680                         len -= intlen;
2681                         p += intlen;
2682                 }
2683                 error = 0;
2684                 goto out;
2685
2686         case CTLTYPE_OPAQUE:
2687                 /* TODO: Support struct functions. */
2688
2689                 /* FALLTHROUGH */
2690         default:
2691                 db_printf("Format:%s Length:%zu Dump:0x",
2692                     g_ddb_oid->oid_fmt, len);
2693                 while (len-- && (xflag || p < val + 16))
2694                         db_printf("%02x", *p++);
2695                 if (!xflag && len > 16)
2696                         db_printf("...");
2697                 error = 0;
2698                 goto out;
2699         }
2700
2701 out:
2702         req->oldidx += slen;
2703         return (error);
2704 }
2705
2706 /*
2707  * Avoid setting new sysctl values from the debugger
2708  */
2709 static int
2710 sysctl_new_ddb(struct sysctl_req *req, void *p, size_t l)
2711 {
2712
2713         if (!req->newptr)
2714                 return (0);
2715
2716         /* Changing sysctls from the debugger is currently unsupported */
2717         return (EPERM);
2718 }
2719
2720 /*
2721  * Run a sysctl handler with the DDB oldfunc and newfunc attached.
2722  * Instead of copying any output to a buffer we'll dump it right to
2723  * the console.
2724  */
2725 static int
2726 db_sysctl(struct sysctl_oid *oidp, int *name, u_int namelen,
2727     void *old, size_t *oldlenp, size_t *retval, int flags)
2728 {
2729         struct sysctl_req req;
2730         int error;
2731
2732         /* Setup the request */
2733         bzero(&req, sizeof req);
2734         req.td = kdb_thread;
2735         req.oldfunc = sysctl_old_ddb;
2736         req.newfunc = sysctl_new_ddb;
2737         req.lock = REQ_UNWIRED;
2738         if (oldlenp) {
2739                 req.oldlen = *oldlenp;
2740         }
2741         req.validlen = req.oldlen;
2742         if (old) {
2743                 req.oldptr = old;
2744         }
2745
2746         /* Setup our globals for sysctl_old_ddb */
2747         g_ddb_oid = oidp;
2748         g_ddb_sysctl_flags = flags;
2749         g_ddb_sysctl_printed = 0;
2750
2751         error = sysctl_root(0, name, namelen, &req);
2752
2753         /* Reset globals */
2754         g_ddb_oid = NULL;
2755         g_ddb_sysctl_flags = 0;
2756
2757         if (retval) {
2758                 if (req.oldptr && req.oldidx > req.validlen)
2759                         *retval = req.validlen;
2760                 else
2761                         *retval = req.oldidx;
2762         }
2763         return (error);
2764 }
2765
2766 /*
2767  * Show a sysctl's name
2768  */
2769 static void
2770 db_show_oid_name(int *oid, size_t nlen)
2771 {
2772         struct sysctl_oid *oidp;
2773         int qoid[CTL_MAXNAME+2];
2774         int error;
2775
2776         qoid[0] = 0;
2777         memcpy(qoid + 2, oid, nlen * sizeof(int));
2778         qoid[1] = 1;
2779
2780         error = sysctl_find_oid(qoid, nlen + 2, &oidp, NULL, NULL);
2781         if (error)
2782                 db_error("sysctl name oid");
2783
2784         error = db_sysctl(oidp, qoid, nlen + 2, NULL, NULL, NULL, 0);
2785         if (error)
2786                 db_error("sysctl name");
2787 }
2788
2789 /*
2790  * Check to see if an OID is safe to print from ddb.
2791  */
2792 static bool
2793 db_oid_safe(const struct sysctl_oid *oidp)
2794 {
2795         for (unsigned int i = 0; i < nitems(db_safe_handlers); ++i) {
2796                 if (oidp->oid_handler == db_safe_handlers[i])
2797                         return (true);
2798         }
2799
2800         return (false);
2801 }
2802
2803 /*
2804  * Show a sysctl at a specific OID
2805  * Compare to the input handling in show_var from sbin/sysctl/sysctl.c
2806  */
2807 static int
2808 db_show_oid(struct sysctl_oid *oidp, int *oid, size_t nlen, int flags)
2809 {
2810         int error, xflag, oflag, Nflag, nflag;
2811         size_t len;
2812
2813         xflag = flags & DB_SYSCTL_HEX;
2814         oflag = flags & DB_SYSCTL_OPAQUE;
2815         nflag = flags & DB_SYSCTL_VALUE_ONLY;
2816         Nflag = flags & DB_SYSCTL_NAME_ONLY;
2817
2818         if ((oidp->oid_kind & CTLTYPE) == CTLTYPE_OPAQUE &&
2819             (!xflag && !oflag))
2820                 return (0);
2821
2822         if (Nflag) {
2823                 db_show_oid_name(oid, nlen);
2824                 error = 0;
2825                 goto out;
2826         }
2827
2828         if (!nflag) {
2829                 db_show_oid_name(oid, nlen);
2830                 db_printf(": ");
2831         }
2832
2833         if ((flags & DB_SYSCTL_SAFE_ONLY) && !db_oid_safe(oidp)) {
2834                 db_printf("Skipping, unsafe to print while recursing.");
2835                 error = 0;
2836                 goto out;
2837         }
2838
2839         /* Try once, and ask about the size */
2840         len = 0;
2841         error = db_sysctl(oidp, oid, nlen,
2842             NULL, NULL, &len, flags);
2843         if (error)
2844                 goto out;
2845
2846         if (!g_ddb_sysctl_printed)
2847                 /* Lie about the size */
2848                 error = db_sysctl(oidp, oid, nlen,
2849                     (void *) 1, &len, NULL, flags);
2850
2851 out:
2852         db_printf("\n");
2853         return (error);
2854 }
2855
2856 /*
2857  * Show all sysctls under a specific OID
2858  * Compare to sysctl_all from sbin/sysctl/sysctl.c
2859  */
2860 static int
2861 db_show_sysctl_all(int *oid, size_t len, int flags)
2862 {
2863         struct sysctl_oid *oidp;
2864         int name1[CTL_MAXNAME + 2], name2[CTL_MAXNAME + 2];
2865         size_t l1, l2;
2866
2867         name1[0] = CTL_SYSCTL;
2868         name1[1] = CTL_SYSCTL_NEXT;
2869         l1 = 2;
2870         if (len) {
2871                 memcpy(name1 + 2, oid, len * sizeof(int));
2872                 l1 += len;
2873         } else {
2874                 name1[2] = CTL_KERN;
2875                 l1++;
2876         }
2877         for (;;) {
2878                 int i, error;
2879
2880                 l2 = sizeof(name2);
2881                 error = kernel_sysctl(kdb_thread, name1, l1,
2882                     name2, &l2, NULL, 0, &l2, 0);
2883                 if (error != 0) {
2884                         if (error == ENOENT)
2885                                 return (0);
2886                         else
2887                                 db_error("sysctl(next)");
2888                 }
2889
2890                 l2 /= sizeof(int);
2891
2892                 if (l2 < (unsigned int)len)
2893                         return (0);
2894
2895                 for (i = 0; i < len; i++)
2896                         if (name2[i] != oid[i])
2897                                 return (0);
2898
2899                 /* Find the OID in question */
2900                 error = sysctl_find_oid(name2, l2, &oidp, NULL, NULL);
2901                 if (error)
2902                         return (error);
2903
2904                 i = db_show_oid(oidp, name2, l2, flags | DB_SYSCTL_SAFE_ONLY);
2905
2906                 if (db_pager_quit)
2907                         return (0);
2908
2909                 memcpy(name1+2, name2, l2 * sizeof(int));
2910                 l1 = 2 + l2;
2911         }
2912 }
2913
2914 /*
2915  * Show a sysctl by its user facing string
2916  */
2917 static int
2918 db_sysctlbyname(char *name, int flags)
2919 {
2920         struct sysctl_oid *oidp;
2921         int oid[CTL_MAXNAME];
2922         int error, nlen;
2923
2924         error = name2oid(name, oid, &nlen, &oidp);
2925         if (error) {
2926                 return (error);
2927         }
2928
2929         if ((oidp->oid_kind & CTLTYPE) == CTLTYPE_NODE) {
2930                 db_show_sysctl_all(oid, nlen, flags);
2931         } else {
2932                 error = db_show_oid(oidp, oid, nlen, flags);
2933         }
2934
2935         return (error);
2936 }
2937
2938 static void
2939 db_sysctl_cmd_usage(void)
2940 {
2941         db_printf(
2942             " sysctl [/Nnox] <sysctl>                                       \n"
2943             "                                                               \n"
2944             " <sysctl> The name of the sysctl to show.                      \n"
2945             "                                                               \n"
2946             " Show a sysctl by hooking into SYSCTL_IN and SYSCTL_OUT.       \n"
2947             " This will work for most sysctls, but should not be used       \n"
2948             " with sysctls that are known to malloc.                        \n"
2949             "                                                               \n"
2950             " While recursing any \"unsafe\" sysctls will be skipped.       \n"
2951             " Call sysctl directly on the sysctl to try printing the        \n"
2952             " skipped sysctl. This is unsafe and may make the ddb           \n"
2953             " session unusable.                                             \n"
2954             "                                                               \n"
2955             " Arguments:                                                    \n"
2956             "   /N      Display only the name of the sysctl.                \n"
2957             "   /n      Display only the value of the sysctl.               \n"
2958             "   /o      Display opaque values.                              \n"
2959             "   /x      Display the sysctl in hex.                          \n"
2960             "                                                               \n"
2961             "For example:                                                   \n"
2962             "sysctl vm.v_free_min                                           \n"
2963             "vn.v_free_min: 12669                                           \n"
2964             );
2965 }
2966
2967 /*
2968  * Show a specific sysctl similar to sysctl (8).
2969  */
2970 DB_COMMAND_FLAGS(sysctl, db_sysctl_cmd, CS_OWN)
2971 {
2972         char name[TOK_STRING_SIZE];
2973         int error, i, t, flags;
2974
2975         /* Parse the modifiers */
2976         t = db_read_token();
2977         if (t == tSLASH || t == tMINUS) {
2978                 t = db_read_token();
2979                 if (t != tIDENT) {
2980                         db_printf("Bad modifier\n");
2981                         error = EINVAL;
2982                         goto out;
2983                 }
2984                 db_strcpy(modif, db_tok_string);
2985         }
2986         else {
2987                 db_unread_token(t);
2988                 modif[0] = '\0';
2989         }
2990
2991         flags = 0;
2992         for (i = 0; i < nitems(db_sysctl_modifs); i++) {
2993                 if (strchr(modif, db_sysctl_modifs[i])) {
2994                         flags |= db_sysctl_modif_values[i];
2995                 }
2996         }
2997
2998         /* Parse the sysctl names */
2999         t = db_read_token();
3000         if (t != tIDENT) {
3001                 db_printf("Need sysctl name\n");
3002                 error = EINVAL;
3003                 goto out;
3004         }
3005
3006         /* Copy the name into a temporary buffer */
3007         db_strcpy(name, db_tok_string);
3008
3009         /* Ensure there is no trailing cruft */
3010         t = db_read_token();
3011         if (t != tEOL) {
3012                 db_printf("Unexpected sysctl argument\n");
3013                 error = EINVAL;
3014                 goto out;
3015         }
3016
3017         error = db_sysctlbyname(name, flags);
3018         if (error == ENOENT) {
3019                 db_printf("unknown oid: '%s'\n", db_tok_string);
3020                 goto out;
3021         } else if (error) {
3022                 db_printf("%s: error: %d\n", db_tok_string, error);
3023                 goto out;
3024         }
3025
3026 out:
3027         /* Ensure we eat all of our text */
3028         db_flush_lex();
3029
3030         if (error == EINVAL) {
3031                 db_sysctl_cmd_usage();
3032         }
3033 }
3034
3035 #endif /* DDB */