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