]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/kern/kern_sysctl.c
Upgrade our copy of llvm/clang to r130700, from upstream's trunk.
[FreeBSD/FreeBSD.git] / sys / kern / kern_sysctl.c
1 /*-
2  * Copyright (c) 1982, 1986, 1989, 1993
3  *      The Regents of the University of California.  All rights reserved.
4  *
5  * This code is derived from software contributed to Berkeley by
6  * Mike Karels at Berkeley Software Design, Inc.
7  *
8  * Quite extensively rewritten by Poul-Henning Kamp of the FreeBSD
9  * project, to make these variables more userfriendly.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  * 4. Neither the name of the University nor the names of its contributors
20  *    may be used to endorse or promote products derived from this software
21  *    without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33  * SUCH DAMAGE.
34  *
35  *      @(#)kern_sysctl.c       8.4 (Berkeley) 4/14/94
36  */
37
38 #include <sys/cdefs.h>
39 __FBSDID("$FreeBSD$");
40
41 #include "opt_compat.h"
42 #include "opt_ktrace.h"
43
44 #include <sys/param.h>
45 #include <sys/fail.h>
46 #include <sys/systm.h>
47 #include <sys/kernel.h>
48 #include <sys/sysctl.h>
49 #include <sys/malloc.h>
50 #include <sys/priv.h>
51 #include <sys/proc.h>
52 #include <sys/jail.h>
53 #include <sys/lock.h>
54 #include <sys/mutex.h>
55 #include <sys/sbuf.h>
56 #include <sys/sx.h>
57 #include <sys/sysproto.h>
58 #include <sys/uio.h>
59 #ifdef KTRACE
60 #include <sys/ktrace.h>
61 #endif
62
63 #include <net/vnet.h>
64
65 #include <security/mac/mac_framework.h>
66
67 #include <vm/vm.h>
68 #include <vm/vm_extern.h>
69
70 static MALLOC_DEFINE(M_SYSCTL, "sysctl", "sysctl internal magic");
71 static MALLOC_DEFINE(M_SYSCTLOID, "sysctloid", "sysctl dynamic oids");
72 static MALLOC_DEFINE(M_SYSCTLTMP, "sysctltmp", "sysctl temp output buffer");
73
74 /*
75  * The sysctllock protects the MIB tree.  It also protects sysctl
76  * contexts used with dynamic sysctls.  The sysctl_register_oid() and
77  * sysctl_unregister_oid() routines require the sysctllock to already
78  * be held, so the sysctl_lock() and sysctl_unlock() routines are
79  * provided for the few places in the kernel which need to use that
80  * API rather than using the dynamic API.  Use of the dynamic API is
81  * strongly encouraged for most code.
82  *
83  * The sysctlmemlock is used to limit the amount of user memory wired for
84  * sysctl requests.  This is implemented by serializing any userland
85  * sysctl requests larger than a single page via an exclusive lock.
86  */
87 static struct sx sysctllock;
88 static struct sx sysctlmemlock;
89
90 #define SYSCTL_XLOCK()          sx_xlock(&sysctllock)
91 #define SYSCTL_XUNLOCK()        sx_xunlock(&sysctllock)
92 #define SYSCTL_ASSERT_XLOCKED() sx_assert(&sysctllock, SA_XLOCKED)
93 #define SYSCTL_INIT()           sx_init(&sysctllock, "sysctl lock")
94 #define SYSCTL_SLEEP(ch, wmesg, timo)                                   \
95                                 sx_sleep(ch, &sysctllock, 0, wmesg, timo)
96
97 static int sysctl_root(SYSCTL_HANDLER_ARGS);
98
99 struct sysctl_oid_list sysctl__children; /* root list */
100
101 static int      sysctl_remove_oid_locked(struct sysctl_oid *oidp, int del,
102                     int recurse);
103
104 static struct sysctl_oid *
105 sysctl_find_oidname(const char *name, struct sysctl_oid_list *list)
106 {
107         struct sysctl_oid *oidp;
108
109         SYSCTL_ASSERT_XLOCKED();
110         SLIST_FOREACH(oidp, list, oid_link) {
111                 if (strcmp(oidp->oid_name, name) == 0) {
112                         return (oidp);
113                 }
114         }
115         return (NULL);
116 }
117
118 /*
119  * Initialization of the MIB tree.
120  *
121  * Order by number in each list.
122  */
123 void
124 sysctl_lock(void)
125 {
126
127         SYSCTL_XLOCK();
128 }
129
130 void
131 sysctl_unlock(void)
132 {
133
134         SYSCTL_XUNLOCK();
135 }
136
137 void
138 sysctl_register_oid(struct sysctl_oid *oidp)
139 {
140         struct sysctl_oid_list *parent = oidp->oid_parent;
141         struct sysctl_oid *p;
142         struct sysctl_oid *q;
143
144         /*
145          * First check if another oid with the same name already
146          * exists in the parent's list.
147          */
148         SYSCTL_ASSERT_XLOCKED();
149         p = sysctl_find_oidname(oidp->oid_name, parent);
150         if (p != NULL) {
151                 if ((p->oid_kind & CTLTYPE) == CTLTYPE_NODE) {
152                         p->oid_refcnt++;
153                         return;
154                 } else {
155                         printf("can't re-use a leaf (%s)!\n", p->oid_name);
156                         return;
157                 }
158         }
159         /*
160          * If this oid has a number OID_AUTO, give it a number which
161          * is greater than any current oid.
162          * NOTE: DO NOT change the starting value here, change it in
163          * <sys/sysctl.h>, and make sure it is at least 256 to
164          * accomodate e.g. net.inet.raw as a static sysctl node.
165          */
166         if (oidp->oid_number == OID_AUTO) {
167                 static int newoid = CTL_AUTO_START;
168
169                 oidp->oid_number = newoid++;
170                 if (newoid == 0x7fffffff)
171                         panic("out of oids");
172         }
173 #if 0
174         else if (oidp->oid_number >= CTL_AUTO_START) {
175                 /* do not panic; this happens when unregistering sysctl sets */
176                 printf("static sysctl oid too high: %d", oidp->oid_number);
177         }
178 #endif
179
180         /*
181          * Insert the oid into the parent's list in order.
182          */
183         q = NULL;
184         SLIST_FOREACH(p, parent, oid_link) {
185                 if (oidp->oid_number < p->oid_number)
186                         break;
187                 q = p;
188         }
189         if (q)
190                 SLIST_INSERT_AFTER(q, oidp, oid_link);
191         else
192                 SLIST_INSERT_HEAD(parent, oidp, oid_link);
193 }
194
195 void
196 sysctl_unregister_oid(struct sysctl_oid *oidp)
197 {
198         struct sysctl_oid *p;
199         int error;
200
201         SYSCTL_ASSERT_XLOCKED();
202         error = ENOENT;
203         if (oidp->oid_number == OID_AUTO) {
204                 error = EINVAL;
205         } else {
206                 SLIST_FOREACH(p, oidp->oid_parent, oid_link) {
207                         if (p == oidp) {
208                                 SLIST_REMOVE(oidp->oid_parent, oidp,
209                                     sysctl_oid, oid_link);
210                                 error = 0;
211                                 break;
212                         }
213                 }
214         }
215
216         /* 
217          * This can happen when a module fails to register and is
218          * being unloaded afterwards.  It should not be a panic()
219          * for normal use.
220          */
221         if (error)
222                 printf("%s: failed to unregister sysctl\n", __func__);
223 }
224
225 /* Initialize a new context to keep track of dynamically added sysctls. */
226 int
227 sysctl_ctx_init(struct sysctl_ctx_list *c)
228 {
229
230         if (c == NULL) {
231                 return (EINVAL);
232         }
233
234         /*
235          * No locking here, the caller is responsible for not adding
236          * new nodes to a context until after this function has
237          * returned.
238          */
239         TAILQ_INIT(c);
240         return (0);
241 }
242
243 /* Free the context, and destroy all dynamic oids registered in this context */
244 int
245 sysctl_ctx_free(struct sysctl_ctx_list *clist)
246 {
247         struct sysctl_ctx_entry *e, *e1;
248         int error;
249
250         error = 0;
251         /*
252          * First perform a "dry run" to check if it's ok to remove oids.
253          * XXX FIXME
254          * XXX This algorithm is a hack. But I don't know any
255          * XXX better solution for now...
256          */
257         SYSCTL_XLOCK();
258         TAILQ_FOREACH(e, clist, link) {
259                 error = sysctl_remove_oid_locked(e->entry, 0, 0);
260                 if (error)
261                         break;
262         }
263         /*
264          * Restore deregistered entries, either from the end,
265          * or from the place where error occured.
266          * e contains the entry that was not unregistered
267          */
268         if (error)
269                 e1 = TAILQ_PREV(e, sysctl_ctx_list, link);
270         else
271                 e1 = TAILQ_LAST(clist, sysctl_ctx_list);
272         while (e1 != NULL) {
273                 sysctl_register_oid(e1->entry);
274                 e1 = TAILQ_PREV(e1, sysctl_ctx_list, link);
275         }
276         if (error) {
277                 SYSCTL_XUNLOCK();
278                 return(EBUSY);
279         }
280         /* Now really delete the entries */
281         e = TAILQ_FIRST(clist);
282         while (e != NULL) {
283                 e1 = TAILQ_NEXT(e, link);
284                 error = sysctl_remove_oid_locked(e->entry, 1, 0);
285                 if (error)
286                         panic("sysctl_remove_oid: corrupt tree, entry: %s",
287                             e->entry->oid_name);
288                 free(e, M_SYSCTLOID);
289                 e = e1;
290         }
291         SYSCTL_XUNLOCK();
292         return (error);
293 }
294
295 /* Add an entry to the context */
296 struct sysctl_ctx_entry *
297 sysctl_ctx_entry_add(struct sysctl_ctx_list *clist, struct sysctl_oid *oidp)
298 {
299         struct sysctl_ctx_entry *e;
300
301         SYSCTL_ASSERT_XLOCKED();
302         if (clist == NULL || oidp == NULL)
303                 return(NULL);
304         e = malloc(sizeof(struct sysctl_ctx_entry), M_SYSCTLOID, M_WAITOK);
305         e->entry = oidp;
306         TAILQ_INSERT_HEAD(clist, e, link);
307         return (e);
308 }
309
310 /* Find an entry in the context */
311 struct sysctl_ctx_entry *
312 sysctl_ctx_entry_find(struct sysctl_ctx_list *clist, struct sysctl_oid *oidp)
313 {
314         struct sysctl_ctx_entry *e;
315
316         SYSCTL_ASSERT_XLOCKED();
317         if (clist == NULL || oidp == NULL)
318                 return(NULL);
319         TAILQ_FOREACH(e, clist, link) {
320                 if(e->entry == oidp)
321                         return(e);
322         }
323         return (e);
324 }
325
326 /*
327  * Delete an entry from the context.
328  * NOTE: this function doesn't free oidp! You have to remove it
329  * with sysctl_remove_oid().
330  */
331 int
332 sysctl_ctx_entry_del(struct sysctl_ctx_list *clist, struct sysctl_oid *oidp)
333 {
334         struct sysctl_ctx_entry *e;
335
336         if (clist == NULL || oidp == NULL)
337                 return (EINVAL);
338         SYSCTL_XLOCK();
339         e = sysctl_ctx_entry_find(clist, oidp);
340         if (e != NULL) {
341                 TAILQ_REMOVE(clist, e, link);
342                 SYSCTL_XUNLOCK();
343                 free(e, M_SYSCTLOID);
344                 return (0);
345         } else {
346                 SYSCTL_XUNLOCK();
347                 return (ENOENT);
348         }
349 }
350
351 /*
352  * Remove dynamically created sysctl trees.
353  * oidp - top of the tree to be removed
354  * del - if 0 - just deregister, otherwise free up entries as well
355  * recurse - if != 0 traverse the subtree to be deleted
356  */
357 int
358 sysctl_remove_oid(struct sysctl_oid *oidp, int del, int recurse)
359 {
360         int error;
361
362         SYSCTL_XLOCK();
363         error = sysctl_remove_oid_locked(oidp, del, recurse);
364         SYSCTL_XUNLOCK();
365         return (error);
366 }
367
368 int
369 sysctl_remove_name(struct sysctl_oid *parent, const char *name,
370     int del, int recurse)
371 {
372         struct sysctl_oid *p, *tmp;
373         int error;
374
375         error = ENOENT;
376         SYSCTL_XLOCK();
377         SLIST_FOREACH_SAFE(p, SYSCTL_CHILDREN(parent), oid_link, tmp) {
378                 if (strcmp(p->oid_name, name) == 0) {
379                         error = sysctl_remove_oid_locked(p, del, recurse);
380                         break;
381                 }
382         }
383         SYSCTL_XUNLOCK();
384
385         return (error);
386 }
387
388
389 static int
390 sysctl_remove_oid_locked(struct sysctl_oid *oidp, int del, int recurse)
391 {
392         struct sysctl_oid *p, *tmp;
393         int error;
394
395         SYSCTL_ASSERT_XLOCKED();
396         if (oidp == NULL)
397                 return(EINVAL);
398         if ((oidp->oid_kind & CTLFLAG_DYN) == 0) {
399                 printf("can't remove non-dynamic nodes!\n");
400                 return (EINVAL);
401         }
402         /*
403          * WARNING: normal method to do this should be through
404          * sysctl_ctx_free(). Use recursing as the last resort
405          * method to purge your sysctl tree of leftovers...
406          * However, if some other code still references these nodes,
407          * it will panic.
408          */
409         if ((oidp->oid_kind & CTLTYPE) == CTLTYPE_NODE) {
410                 if (oidp->oid_refcnt == 1) {
411                         SLIST_FOREACH_SAFE(p,
412                             SYSCTL_CHILDREN(oidp), oid_link, tmp) {
413                                 if (!recurse)
414                                         return (ENOTEMPTY);
415                                 error = sysctl_remove_oid_locked(p, del,
416                                     recurse);
417                                 if (error)
418                                         return (error);
419                         }
420                         if (del)
421                                 free(SYSCTL_CHILDREN(oidp), M_SYSCTLOID);
422                 }
423         }
424         if (oidp->oid_refcnt > 1 ) {
425                 oidp->oid_refcnt--;
426         } else {
427                 if (oidp->oid_refcnt == 0) {
428                         printf("Warning: bad oid_refcnt=%u (%s)!\n",
429                                 oidp->oid_refcnt, oidp->oid_name);
430                         return (EINVAL);
431                 }
432                 sysctl_unregister_oid(oidp);
433                 if (del) {
434                         /*
435                          * Wait for all threads running the handler to drain.
436                          * This preserves the previous behavior when the
437                          * sysctl lock was held across a handler invocation,
438                          * and is necessary for module unload correctness.
439                          */
440                         while (oidp->oid_running > 0) {
441                                 oidp->oid_kind |= CTLFLAG_DYING;
442                                 SYSCTL_SLEEP(&oidp->oid_running, "oidrm", 0);
443                         }
444                         if (oidp->oid_descr)
445                                 free((void *)(uintptr_t)(const void *)oidp->oid_descr, M_SYSCTLOID);
446                         free((void *)(uintptr_t)(const void *)oidp->oid_name,
447                              M_SYSCTLOID);
448                         free(oidp, M_SYSCTLOID);
449                 }
450         }
451         return (0);
452 }
453 /*
454  * Create new sysctls at run time.
455  * clist may point to a valid context initialized with sysctl_ctx_init().
456  */
457 struct sysctl_oid *
458 sysctl_add_oid(struct sysctl_ctx_list *clist, struct sysctl_oid_list *parent,
459         int number, const char *name, int kind, void *arg1, intptr_t arg2,
460         int (*handler)(SYSCTL_HANDLER_ARGS), const char *fmt, const char *descr)
461 {
462         struct sysctl_oid *oidp;
463         ssize_t len;
464         char *newname;
465
466         /* You have to hook up somewhere.. */
467         if (parent == NULL)
468                 return(NULL);
469         /* Check if the node already exists, otherwise create it */
470         SYSCTL_XLOCK();
471         oidp = sysctl_find_oidname(name, parent);
472         if (oidp != NULL) {
473                 if ((oidp->oid_kind & CTLTYPE) == CTLTYPE_NODE) {
474                         oidp->oid_refcnt++;
475                         /* Update the context */
476                         if (clist != NULL)
477                                 sysctl_ctx_entry_add(clist, oidp);
478                         SYSCTL_XUNLOCK();
479                         return (oidp);
480                 } else {
481                         SYSCTL_XUNLOCK();
482                         printf("can't re-use a leaf (%s)!\n", name);
483                         return (NULL);
484                 }
485         }
486         oidp = malloc(sizeof(struct sysctl_oid), M_SYSCTLOID, M_WAITOK|M_ZERO);
487         oidp->oid_parent = parent;
488         SLIST_NEXT(oidp, oid_link) = NULL;
489         oidp->oid_number = number;
490         oidp->oid_refcnt = 1;
491         len = strlen(name);
492         newname = malloc(len + 1, M_SYSCTLOID, M_WAITOK);
493         bcopy(name, newname, len + 1);
494         newname[len] = '\0';
495         oidp->oid_name = newname;
496         oidp->oid_handler = handler;
497         oidp->oid_kind = CTLFLAG_DYN | kind;
498         if ((kind & CTLTYPE) == CTLTYPE_NODE) {
499                 /* Allocate space for children */
500                 SYSCTL_CHILDREN_SET(oidp, malloc(sizeof(struct sysctl_oid_list),
501                     M_SYSCTLOID, M_WAITOK));
502                 SLIST_INIT(SYSCTL_CHILDREN(oidp));
503                 oidp->oid_arg2 = arg2;
504         } else {
505                 oidp->oid_arg1 = arg1;
506                 oidp->oid_arg2 = arg2;
507         }
508         oidp->oid_fmt = fmt;
509         if (descr) {
510                 int len = strlen(descr) + 1;
511                 oidp->oid_descr = malloc(len, M_SYSCTLOID, M_WAITOK);
512                 if (oidp->oid_descr)
513                         strcpy((char *)(uintptr_t)(const void *)oidp->oid_descr, descr);
514         }
515         /* Update the context, if used */
516         if (clist != NULL)
517                 sysctl_ctx_entry_add(clist, oidp);
518         /* Register this oid */
519         sysctl_register_oid(oidp);
520         SYSCTL_XUNLOCK();
521         return (oidp);
522 }
523
524 /*
525  * Rename an existing oid.
526  */
527 void
528 sysctl_rename_oid(struct sysctl_oid *oidp, const char *name)
529 {
530         ssize_t len;
531         char *newname;
532         void *oldname;
533
534         len = strlen(name);
535         newname = malloc(len + 1, M_SYSCTLOID, M_WAITOK);
536         bcopy(name, newname, len + 1);
537         newname[len] = '\0';
538         SYSCTL_XLOCK();
539         oldname = (void *)(uintptr_t)(const void *)oidp->oid_name;
540         oidp->oid_name = newname;
541         SYSCTL_XUNLOCK();
542         free(oldname, M_SYSCTLOID);
543 }
544
545 /*
546  * Reparent an existing oid.
547  */
548 int
549 sysctl_move_oid(struct sysctl_oid *oid, struct sysctl_oid_list *parent)
550 {
551         struct sysctl_oid *oidp;
552
553         SYSCTL_XLOCK();
554         if (oid->oid_parent == parent) {
555                 SYSCTL_XUNLOCK();
556                 return (0);
557         }
558         oidp = sysctl_find_oidname(oid->oid_name, parent);
559         if (oidp != NULL) {
560                 SYSCTL_XUNLOCK();
561                 return (EEXIST);
562         }
563         sysctl_unregister_oid(oid);
564         oid->oid_parent = parent;
565         oid->oid_number = OID_AUTO;
566         sysctl_register_oid(oid);
567         SYSCTL_XUNLOCK();
568         return (0);
569 }
570
571 /*
572  * Register the kernel's oids on startup.
573  */
574 SET_DECLARE(sysctl_set, struct sysctl_oid);
575
576 static void
577 sysctl_register_all(void *arg)
578 {
579         struct sysctl_oid **oidp;
580
581         sx_init(&sysctlmemlock, "sysctl mem");
582         SYSCTL_INIT();
583         SYSCTL_XLOCK();
584         SET_FOREACH(oidp, sysctl_set)
585                 sysctl_register_oid(*oidp);
586         SYSCTL_XUNLOCK();
587 }
588 SYSINIT(sysctl, SI_SUB_KMEM, SI_ORDER_ANY, sysctl_register_all, 0);
589
590 /*
591  * "Staff-functions"
592  *
593  * These functions implement a presently undocumented interface 
594  * used by the sysctl program to walk the tree, and get the type
595  * so it can print the value.
596  * This interface is under work and consideration, and should probably
597  * be killed with a big axe by the first person who can find the time.
598  * (be aware though, that the proper interface isn't as obvious as it
599  * may seem, there are various conflicting requirements.
600  *
601  * {0,0}        printf the entire MIB-tree.
602  * {0,1,...}    return the name of the "..." OID.
603  * {0,2,...}    return the next OID.
604  * {0,3}        return the OID of the name in "new"
605  * {0,4,...}    return the kind & format info for the "..." OID.
606  * {0,5,...}    return the description the "..." OID.
607  */
608
609 #ifdef SYSCTL_DEBUG
610 static void
611 sysctl_sysctl_debug_dump_node(struct sysctl_oid_list *l, int i)
612 {
613         int k;
614         struct sysctl_oid *oidp;
615
616         SYSCTL_ASSERT_XLOCKED();
617         SLIST_FOREACH(oidp, l, oid_link) {
618
619                 for (k=0; k<i; k++)
620                         printf(" ");
621
622                 printf("%d %s ", oidp->oid_number, oidp->oid_name);
623
624                 printf("%c%c",
625                         oidp->oid_kind & CTLFLAG_RD ? 'R':' ',
626                         oidp->oid_kind & CTLFLAG_WR ? 'W':' ');
627
628                 if (oidp->oid_handler)
629                         printf(" *Handler");
630
631                 switch (oidp->oid_kind & CTLTYPE) {
632                         case CTLTYPE_NODE:
633                                 printf(" Node\n");
634                                 if (!oidp->oid_handler) {
635                                         sysctl_sysctl_debug_dump_node(
636                                                 oidp->oid_arg1, i+2);
637                                 }
638                                 break;
639                         case CTLTYPE_INT:    printf(" Int\n"); break;
640                         case CTLTYPE_UINT:   printf(" u_int\n"); break;
641                         case CTLTYPE_LONG:   printf(" Long\n"); break;
642                         case CTLTYPE_ULONG:  printf(" u_long\n"); break;
643                         case CTLTYPE_STRING: printf(" String\n"); break;
644                         case CTLTYPE_U64:    printf(" uint64_t\n"); break;
645                         case CTLTYPE_S64:    printf(" int64_t\n"); break;
646                         case CTLTYPE_OPAQUE: printf(" Opaque/struct\n"); break;
647                         default:             printf("\n");
648                 }
649
650         }
651 }
652
653 static int
654 sysctl_sysctl_debug(SYSCTL_HANDLER_ARGS)
655 {
656         int error;
657
658         error = priv_check(req->td, PRIV_SYSCTL_DEBUG);
659         if (error)
660                 return (error);
661         SYSCTL_XLOCK();
662         sysctl_sysctl_debug_dump_node(&sysctl__children, 0);
663         SYSCTL_XUNLOCK();
664         return (ENOENT);
665 }
666
667 SYSCTL_PROC(_sysctl, 0, debug, CTLTYPE_STRING|CTLFLAG_RD,
668         0, 0, sysctl_sysctl_debug, "-", "");
669 #endif
670
671 static int
672 sysctl_sysctl_name(SYSCTL_HANDLER_ARGS)
673 {
674         int *name = (int *) arg1;
675         u_int namelen = arg2;
676         int error = 0;
677         struct sysctl_oid *oid;
678         struct sysctl_oid_list *lsp = &sysctl__children, *lsp2;
679         char buf[10];
680
681         SYSCTL_XLOCK();
682         while (namelen) {
683                 if (!lsp) {
684                         snprintf(buf,sizeof(buf),"%d",*name);
685                         if (req->oldidx)
686                                 error = SYSCTL_OUT(req, ".", 1);
687                         if (!error)
688                                 error = SYSCTL_OUT(req, buf, strlen(buf));
689                         if (error)
690                                 goto out;
691                         namelen--;
692                         name++;
693                         continue;
694                 }
695                 lsp2 = 0;
696                 SLIST_FOREACH(oid, lsp, oid_link) {
697                         if (oid->oid_number != *name)
698                                 continue;
699
700                         if (req->oldidx)
701                                 error = SYSCTL_OUT(req, ".", 1);
702                         if (!error)
703                                 error = SYSCTL_OUT(req, oid->oid_name,
704                                         strlen(oid->oid_name));
705                         if (error)
706                                 goto out;
707
708                         namelen--;
709                         name++;
710
711                         if ((oid->oid_kind & CTLTYPE) != CTLTYPE_NODE) 
712                                 break;
713
714                         if (oid->oid_handler)
715                                 break;
716
717                         lsp2 = SYSCTL_CHILDREN(oid);
718                         break;
719                 }
720                 lsp = lsp2;
721         }
722         error = SYSCTL_OUT(req, "", 1);
723  out:
724         SYSCTL_XUNLOCK();
725         return (error);
726 }
727
728 static SYSCTL_NODE(_sysctl, 1, name, CTLFLAG_RD, sysctl_sysctl_name, "");
729
730 static int
731 sysctl_sysctl_next_ls(struct sysctl_oid_list *lsp, int *name, u_int namelen, 
732         int *next, int *len, int level, struct sysctl_oid **oidpp)
733 {
734         struct sysctl_oid *oidp;
735
736         SYSCTL_ASSERT_XLOCKED();
737         *len = level;
738         SLIST_FOREACH(oidp, lsp, oid_link) {
739                 *next = oidp->oid_number;
740                 *oidpp = oidp;
741
742                 if (oidp->oid_kind & CTLFLAG_SKIP)
743                         continue;
744
745                 if (!namelen) {
746                         if ((oidp->oid_kind & CTLTYPE) != CTLTYPE_NODE) 
747                                 return (0);
748                         if (oidp->oid_handler) 
749                                 /* We really should call the handler here...*/
750                                 return (0);
751                         lsp = SYSCTL_CHILDREN(oidp);
752                         if (!sysctl_sysctl_next_ls(lsp, 0, 0, next+1, 
753                                 len, level+1, oidpp))
754                                 return (0);
755                         goto emptynode;
756                 }
757
758                 if (oidp->oid_number < *name)
759                         continue;
760
761                 if (oidp->oid_number > *name) {
762                         if ((oidp->oid_kind & CTLTYPE) != CTLTYPE_NODE)
763                                 return (0);
764                         if (oidp->oid_handler)
765                                 return (0);
766                         lsp = SYSCTL_CHILDREN(oidp);
767                         if (!sysctl_sysctl_next_ls(lsp, name+1, namelen-1, 
768                                 next+1, len, level+1, oidpp))
769                                 return (0);
770                         goto next;
771                 }
772                 if ((oidp->oid_kind & CTLTYPE) != CTLTYPE_NODE)
773                         continue;
774
775                 if (oidp->oid_handler)
776                         continue;
777
778                 lsp = SYSCTL_CHILDREN(oidp);
779                 if (!sysctl_sysctl_next_ls(lsp, name+1, namelen-1, next+1, 
780                         len, level+1, oidpp))
781                         return (0);
782         next:
783                 namelen = 1;
784         emptynode:
785                 *len = level;
786         }
787         return (1);
788 }
789
790 static int
791 sysctl_sysctl_next(SYSCTL_HANDLER_ARGS)
792 {
793         int *name = (int *) arg1;
794         u_int namelen = arg2;
795         int i, j, error;
796         struct sysctl_oid *oid;
797         struct sysctl_oid_list *lsp = &sysctl__children;
798         int newoid[CTL_MAXNAME];
799
800         SYSCTL_XLOCK();
801         i = sysctl_sysctl_next_ls(lsp, name, namelen, newoid, &j, 1, &oid);
802         SYSCTL_XUNLOCK();
803         if (i)
804                 return (ENOENT);
805         error = SYSCTL_OUT(req, newoid, j * sizeof (int));
806         return (error);
807 }
808
809 static SYSCTL_NODE(_sysctl, 2, next, CTLFLAG_RD, sysctl_sysctl_next, "");
810
811 static int
812 name2oid(char *name, int *oid, int *len, struct sysctl_oid **oidpp)
813 {
814         int i;
815         struct sysctl_oid *oidp;
816         struct sysctl_oid_list *lsp = &sysctl__children;
817         char *p;
818
819         SYSCTL_ASSERT_XLOCKED();
820
821         if (!*name)
822                 return (ENOENT);
823
824         p = name + strlen(name) - 1 ;
825         if (*p == '.')
826                 *p = '\0';
827
828         *len = 0;
829
830         for (p = name; *p && *p != '.'; p++) 
831                 ;
832         i = *p;
833         if (i == '.')
834                 *p = '\0';
835
836         oidp = SLIST_FIRST(lsp);
837
838         while (oidp && *len < CTL_MAXNAME) {
839                 if (strcmp(name, oidp->oid_name)) {
840                         oidp = SLIST_NEXT(oidp, oid_link);
841                         continue;
842                 }
843                 *oid++ = oidp->oid_number;
844                 (*len)++;
845
846                 if (!i) {
847                         if (oidpp)
848                                 *oidpp = oidp;
849                         return (0);
850                 }
851
852                 if ((oidp->oid_kind & CTLTYPE) != CTLTYPE_NODE)
853                         break;
854
855                 if (oidp->oid_handler)
856                         break;
857
858                 lsp = SYSCTL_CHILDREN(oidp);
859                 oidp = SLIST_FIRST(lsp);
860                 name = p+1;
861                 for (p = name; *p && *p != '.'; p++) 
862                                 ;
863                 i = *p;
864                 if (i == '.')
865                         *p = '\0';
866         }
867         return (ENOENT);
868 }
869
870 static int
871 sysctl_sysctl_name2oid(SYSCTL_HANDLER_ARGS)
872 {
873         char *p;
874         int error, oid[CTL_MAXNAME], len = 0;
875         struct sysctl_oid *op = 0;
876
877         if (!req->newlen) 
878                 return (ENOENT);
879         if (req->newlen >= MAXPATHLEN)  /* XXX arbitrary, undocumented */
880                 return (ENAMETOOLONG);
881
882         p = malloc(req->newlen+1, M_SYSCTL, M_WAITOK);
883
884         error = SYSCTL_IN(req, p, req->newlen);
885         if (error) {
886                 free(p, M_SYSCTL);
887                 return (error);
888         }
889
890         p [req->newlen] = '\0';
891
892         SYSCTL_XLOCK();
893         error = name2oid(p, oid, &len, &op);
894         SYSCTL_XUNLOCK();
895
896         free(p, M_SYSCTL);
897
898         if (error)
899                 return (error);
900
901         error = SYSCTL_OUT(req, oid, len * sizeof *oid);
902         return (error);
903 }
904
905 SYSCTL_PROC(_sysctl, 3, name2oid,
906     CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_ANYBODY | CTLFLAG_MPSAFE,
907     0, 0, sysctl_sysctl_name2oid, "I", "");
908
909 static int
910 sysctl_sysctl_oidfmt(SYSCTL_HANDLER_ARGS)
911 {
912         struct sysctl_oid *oid;
913         int error;
914
915         SYSCTL_XLOCK();
916         error = sysctl_find_oid(arg1, arg2, &oid, NULL, req);
917         if (error)
918                 goto out;
919
920         if (oid->oid_fmt == NULL) {
921                 error = ENOENT;
922                 goto out;
923         }
924         error = SYSCTL_OUT(req, &oid->oid_kind, sizeof(oid->oid_kind));
925         if (error)
926                 goto out;
927         error = SYSCTL_OUT(req, oid->oid_fmt, strlen(oid->oid_fmt) + 1);
928  out:
929         SYSCTL_XUNLOCK();
930         return (error);
931 }
932
933
934 static SYSCTL_NODE(_sysctl, 4, oidfmt, CTLFLAG_RD|CTLFLAG_MPSAFE,
935     sysctl_sysctl_oidfmt, "");
936
937 static int
938 sysctl_sysctl_oiddescr(SYSCTL_HANDLER_ARGS)
939 {
940         struct sysctl_oid *oid;
941         int error;
942
943         SYSCTL_XLOCK();
944         error = sysctl_find_oid(arg1, arg2, &oid, NULL, req);
945         if (error)
946                 goto out;
947
948         if (oid->oid_descr == NULL) {
949                 error = ENOENT;
950                 goto out;
951         }
952         error = SYSCTL_OUT(req, oid->oid_descr, strlen(oid->oid_descr) + 1);
953  out:
954         SYSCTL_XUNLOCK();
955         return (error);
956 }
957
958 static SYSCTL_NODE(_sysctl, 5, oiddescr, CTLFLAG_RD, sysctl_sysctl_oiddescr, "");
959
960 /*
961  * Default "handler" functions.
962  */
963
964 /*
965  * Handle an int, signed or unsigned.
966  * Two cases:
967  *     a variable:  point arg1 at it.
968  *     a constant:  pass it in arg2.
969  */
970
971 int
972 sysctl_handle_int(SYSCTL_HANDLER_ARGS)
973 {
974         int tmpout, error = 0;
975
976         /*
977          * Attempt to get a coherent snapshot by making a copy of the data.
978          */
979         if (arg1)
980                 tmpout = *(int *)arg1;
981         else
982                 tmpout = arg2;
983         error = SYSCTL_OUT(req, &tmpout, sizeof(int));
984
985         if (error || !req->newptr)
986                 return (error);
987
988         if (!arg1)
989                 error = EPERM;
990         else
991                 error = SYSCTL_IN(req, arg1, sizeof(int));
992         return (error);
993 }
994
995 /*
996  * Based on on sysctl_handle_int() convert milliseconds into ticks.
997  * Note: this is used by TCP.
998  */
999
1000 int
1001 sysctl_msec_to_ticks(SYSCTL_HANDLER_ARGS)
1002 {
1003         int error, s, tt;
1004
1005         tt = *(int *)arg1;
1006         s = (int)((int64_t)tt * 1000 / hz);
1007
1008         error = sysctl_handle_int(oidp, &s, 0, req);
1009         if (error || !req->newptr)
1010                 return (error);
1011
1012         tt = (int)((int64_t)s * hz / 1000);
1013         if (tt < 1)
1014                 return (EINVAL);
1015
1016         *(int *)arg1 = tt;
1017         return (0);
1018 }
1019
1020
1021 /*
1022  * Handle a long, signed or unsigned.  arg1 points to it.
1023  */
1024
1025 int
1026 sysctl_handle_long(SYSCTL_HANDLER_ARGS)
1027 {
1028         int error = 0;
1029         long tmplong;
1030 #ifdef SCTL_MASK32
1031         int tmpint;
1032 #endif
1033
1034         /*
1035          * Attempt to get a coherent snapshot by making a copy of the data.
1036          */
1037         if (!arg1)
1038                 return (EINVAL);
1039         tmplong = *(long *)arg1;
1040 #ifdef SCTL_MASK32
1041         if (req->flags & SCTL_MASK32) {
1042                 tmpint = tmplong;
1043                 error = SYSCTL_OUT(req, &tmpint, sizeof(int));
1044         } else
1045 #endif
1046                 error = SYSCTL_OUT(req, &tmplong, sizeof(long));
1047
1048         if (error || !req->newptr)
1049                 return (error);
1050
1051 #ifdef SCTL_MASK32
1052         if (req->flags & SCTL_MASK32) {
1053                 error = SYSCTL_IN(req, &tmpint, sizeof(int));
1054                 *(long *)arg1 = (long)tmpint;
1055         } else
1056 #endif
1057                 error = SYSCTL_IN(req, arg1, sizeof(long));
1058         return (error);
1059 }
1060
1061 /*
1062  * Handle a 64 bit int, signed or unsigned.  arg1 points to it.
1063  */
1064 int
1065 sysctl_handle_64(SYSCTL_HANDLER_ARGS)
1066 {
1067         int error = 0;
1068         uint64_t tmpout;
1069
1070         /*
1071          * Attempt to get a coherent snapshot by making a copy of the data.
1072          */
1073         if (!arg1)
1074                 return (EINVAL);
1075         tmpout = *(uint64_t *)arg1;
1076         error = SYSCTL_OUT(req, &tmpout, sizeof(uint64_t));
1077
1078         if (error || !req->newptr)
1079                 return (error);
1080
1081         error = SYSCTL_IN(req, arg1, sizeof(uint64_t));
1082         return (error);
1083 }
1084
1085 /*
1086  * Handle our generic '\0' terminated 'C' string.
1087  * Two cases:
1088  *      a variable string:  point arg1 at it, arg2 is max length.
1089  *      a constant string:  point arg1 at it, arg2 is zero.
1090  */
1091
1092 int
1093 sysctl_handle_string(SYSCTL_HANDLER_ARGS)
1094 {
1095         int error=0;
1096         char *tmparg;
1097         size_t outlen;
1098
1099         /*
1100          * Attempt to get a coherent snapshot by copying to a
1101          * temporary kernel buffer.
1102          */
1103 retry:
1104         outlen = strlen((char *)arg1)+1;
1105         tmparg = malloc(outlen, M_SYSCTLTMP, M_WAITOK);
1106
1107         if (strlcpy(tmparg, (char *)arg1, outlen) >= outlen) {
1108                 free(tmparg, M_SYSCTLTMP);
1109                 goto retry;
1110         }
1111
1112         error = SYSCTL_OUT(req, tmparg, outlen);
1113         free(tmparg, M_SYSCTLTMP);
1114
1115         if (error || !req->newptr)
1116                 return (error);
1117
1118         if ((req->newlen - req->newidx) >= arg2) {
1119                 error = EINVAL;
1120         } else {
1121                 arg2 = (req->newlen - req->newidx);
1122                 error = SYSCTL_IN(req, arg1, arg2);
1123                 ((char *)arg1)[arg2] = '\0';
1124         }
1125
1126         return (error);
1127 }
1128
1129 /*
1130  * Handle any kind of opaque data.
1131  * arg1 points to it, arg2 is the size.
1132  */
1133
1134 int
1135 sysctl_handle_opaque(SYSCTL_HANDLER_ARGS)
1136 {
1137         int error, tries;
1138         u_int generation;
1139         struct sysctl_req req2;
1140
1141         /*
1142          * Attempt to get a coherent snapshot, by using the thread
1143          * pre-emption counter updated from within mi_switch() to
1144          * determine if we were pre-empted during a bcopy() or
1145          * copyout(). Make 3 attempts at doing this before giving up.
1146          * If we encounter an error, stop immediately.
1147          */
1148         tries = 0;
1149         req2 = *req;
1150 retry:
1151         generation = curthread->td_generation;
1152         error = SYSCTL_OUT(req, arg1, arg2);
1153         if (error)
1154                 return (error);
1155         tries++;
1156         if (generation != curthread->td_generation && tries < 3) {
1157                 *req = req2;
1158                 goto retry;
1159         }
1160
1161         error = SYSCTL_IN(req, arg1, arg2);
1162
1163         return (error);
1164 }
1165
1166 /*
1167  * Transfer functions to/from kernel space.
1168  * XXX: rather untested at this point
1169  */
1170 static int
1171 sysctl_old_kernel(struct sysctl_req *req, const void *p, size_t l)
1172 {
1173         size_t i = 0;
1174
1175         if (req->oldptr) {
1176                 i = l;
1177                 if (req->oldlen <= req->oldidx)
1178                         i = 0;
1179                 else
1180                         if (i > req->oldlen - req->oldidx)
1181                                 i = req->oldlen - req->oldidx;
1182                 if (i > 0)
1183                         bcopy(p, (char *)req->oldptr + req->oldidx, i);
1184         }
1185         req->oldidx += l;
1186         if (req->oldptr && i != l)
1187                 return (ENOMEM);
1188         return (0);
1189 }
1190
1191 static int
1192 sysctl_new_kernel(struct sysctl_req *req, void *p, size_t l)
1193 {
1194         if (!req->newptr)
1195                 return (0);
1196         if (req->newlen - req->newidx < l)
1197                 return (EINVAL);
1198         bcopy((char *)req->newptr + req->newidx, p, l);
1199         req->newidx += l;
1200         return (0);
1201 }
1202
1203 int
1204 kernel_sysctl(struct thread *td, int *name, u_int namelen, void *old,
1205     size_t *oldlenp, void *new, size_t newlen, size_t *retval, int flags)
1206 {
1207         int error = 0;
1208         struct sysctl_req req;
1209
1210         bzero(&req, sizeof req);
1211
1212         req.td = td;
1213         req.flags = flags;
1214
1215         if (oldlenp) {
1216                 req.oldlen = *oldlenp;
1217         }
1218         req.validlen = req.oldlen;
1219
1220         if (old) {
1221                 req.oldptr= old;
1222         }
1223
1224         if (new != NULL) {
1225                 req.newlen = newlen;
1226                 req.newptr = new;
1227         }
1228
1229         req.oldfunc = sysctl_old_kernel;
1230         req.newfunc = sysctl_new_kernel;
1231         req.lock = REQ_UNWIRED;
1232
1233         SYSCTL_XLOCK();
1234         error = sysctl_root(0, name, namelen, &req);
1235         SYSCTL_XUNLOCK();
1236
1237         if (req.lock == REQ_WIRED && req.validlen > 0)
1238                 vsunlock(req.oldptr, req.validlen);
1239
1240         if (error && error != ENOMEM)
1241                 return (error);
1242
1243         if (retval) {
1244                 if (req.oldptr && req.oldidx > req.validlen)
1245                         *retval = req.validlen;
1246                 else
1247                         *retval = req.oldidx;
1248         }
1249         return (error);
1250 }
1251
1252 int
1253 kernel_sysctlbyname(struct thread *td, char *name, void *old, size_t *oldlenp,
1254     void *new, size_t newlen, size_t *retval, int flags)
1255 {
1256         int oid[CTL_MAXNAME];
1257         size_t oidlen, plen;
1258         int error;
1259
1260         oid[0] = 0;             /* sysctl internal magic */
1261         oid[1] = 3;             /* name2oid */
1262         oidlen = sizeof(oid);
1263
1264         error = kernel_sysctl(td, oid, 2, oid, &oidlen,
1265             (void *)name, strlen(name), &plen, flags);
1266         if (error)
1267                 return (error);
1268
1269         error = kernel_sysctl(td, oid, plen / sizeof(int), old, oldlenp,
1270             new, newlen, retval, flags);
1271         return (error);
1272 }
1273
1274 /*
1275  * Transfer function to/from user space.
1276  */
1277 static int
1278 sysctl_old_user(struct sysctl_req *req, const void *p, size_t l)
1279 {
1280         int error = 0;
1281         size_t i, len, origidx;
1282
1283         origidx = req->oldidx;
1284         req->oldidx += l;
1285         if (req->oldptr == NULL)
1286                 return (0);
1287         /*
1288          * If we have not wired the user supplied buffer and we are currently
1289          * holding locks, drop a witness warning, as it's possible that
1290          * write operations to the user page can sleep.
1291          */
1292         if (req->lock != REQ_WIRED)
1293                 WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL,
1294                     "sysctl_old_user()");
1295         i = l;
1296         len = req->validlen;
1297         if (len <= origidx)
1298                 i = 0;
1299         else {
1300                 if (i > len - origidx)
1301                         i = len - origidx;
1302                 error = copyout(p, (char *)req->oldptr + origidx, i);
1303         }
1304         if (error)
1305                 return (error);
1306         if (i < l)
1307                 return (ENOMEM);
1308         return (0);
1309 }
1310
1311 static int
1312 sysctl_new_user(struct sysctl_req *req, void *p, size_t l)
1313 {
1314         int error;
1315
1316         if (!req->newptr)
1317                 return (0);
1318         if (req->newlen - req->newidx < l)
1319                 return (EINVAL);
1320         WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL,
1321             "sysctl_new_user()");
1322         error = copyin((char *)req->newptr + req->newidx, p, l);
1323         req->newidx += l;
1324         return (error);
1325 }
1326
1327 /*
1328  * Wire the user space destination buffer.  If set to a value greater than
1329  * zero, the len parameter limits the maximum amount of wired memory.
1330  */
1331 int
1332 sysctl_wire_old_buffer(struct sysctl_req *req, size_t len)
1333 {
1334         int ret;
1335         size_t wiredlen;
1336
1337         wiredlen = (len > 0 && len < req->oldlen) ? len : req->oldlen;
1338         ret = 0;
1339         if (req->lock != REQ_WIRED && req->oldptr &&
1340             req->oldfunc == sysctl_old_user) {
1341                 if (wiredlen != 0) {
1342                         ret = vslock(req->oldptr, wiredlen);
1343                         if (ret != 0) {
1344                                 if (ret != ENOMEM)
1345                                         return (ret);
1346                                 wiredlen = 0;
1347                         }
1348                 }
1349                 req->lock = REQ_WIRED;
1350                 req->validlen = wiredlen;
1351         }
1352         return (0);
1353 }
1354
1355 int
1356 sysctl_find_oid(int *name, u_int namelen, struct sysctl_oid **noid,
1357     int *nindx, struct sysctl_req *req)
1358 {
1359         struct sysctl_oid_list *lsp;
1360         struct sysctl_oid *oid;
1361         int indx;
1362
1363         SYSCTL_ASSERT_XLOCKED();
1364         lsp = &sysctl__children;
1365         indx = 0;
1366         while (indx < CTL_MAXNAME) {
1367                 SLIST_FOREACH(oid, lsp, oid_link) {
1368                         if (oid->oid_number == name[indx])
1369                                 break;
1370                 }
1371                 if (oid == NULL)
1372                         return (ENOENT);
1373
1374                 indx++;
1375                 if ((oid->oid_kind & CTLTYPE) == CTLTYPE_NODE) {
1376                         if (oid->oid_handler != NULL || indx == namelen) {
1377                                 *noid = oid;
1378                                 if (nindx != NULL)
1379                                         *nindx = indx;
1380                                 KASSERT((oid->oid_kind & CTLFLAG_DYING) == 0,
1381                                     ("%s found DYING node %p", __func__, oid));
1382                                 return (0);
1383                         }
1384                         lsp = SYSCTL_CHILDREN(oid);
1385                 } else if (indx == namelen) {
1386                         *noid = oid;
1387                         if (nindx != NULL)
1388                                 *nindx = indx;
1389                         KASSERT((oid->oid_kind & CTLFLAG_DYING) == 0,
1390                             ("%s found DYING node %p", __func__, oid));
1391                         return (0);
1392                 } else {
1393                         return (ENOTDIR);
1394                 }
1395         }
1396         return (ENOENT);
1397 }
1398
1399 /*
1400  * Traverse our tree, and find the right node, execute whatever it points
1401  * to, and return the resulting error code.
1402  */
1403
1404 static int
1405 sysctl_root(SYSCTL_HANDLER_ARGS)
1406 {
1407         struct sysctl_oid *oid;
1408         int error, indx, lvl;
1409
1410         SYSCTL_ASSERT_XLOCKED();
1411
1412         error = sysctl_find_oid(arg1, arg2, &oid, &indx, req);
1413         if (error)
1414                 return (error);
1415
1416         if ((oid->oid_kind & CTLTYPE) == CTLTYPE_NODE) {
1417                 /*
1418                  * You can't call a sysctl when it's a node, but has
1419                  * no handler.  Inform the user that it's a node.
1420                  * The indx may or may not be the same as namelen.
1421                  */
1422                 if (oid->oid_handler == NULL)
1423                         return (EISDIR);
1424         }
1425
1426         /* Is this sysctl writable? */
1427         if (req->newptr && !(oid->oid_kind & CTLFLAG_WR))
1428                 return (EPERM);
1429
1430         KASSERT(req->td != NULL, ("sysctl_root(): req->td == NULL"));
1431
1432         /* Is this sysctl sensitive to securelevels? */
1433         if (req->newptr && (oid->oid_kind & CTLFLAG_SECURE)) {
1434                 lvl = (oid->oid_kind & CTLMASK_SECURE) >> CTLSHIFT_SECURE;
1435                 error = securelevel_gt(req->td->td_ucred, lvl);
1436                 if (error)
1437                         return (error);
1438         }
1439
1440         /* Is this sysctl writable by only privileged users? */
1441         if (req->newptr && !(oid->oid_kind & CTLFLAG_ANYBODY)) {
1442                 int priv;
1443
1444                 if (oid->oid_kind & CTLFLAG_PRISON)
1445                         priv = PRIV_SYSCTL_WRITEJAIL;
1446 #ifdef VIMAGE
1447                 else if ((oid->oid_kind & CTLFLAG_VNET) &&
1448                      prison_owns_vnet(req->td->td_ucred))
1449                         priv = PRIV_SYSCTL_WRITEJAIL;
1450 #endif
1451                 else
1452                         priv = PRIV_SYSCTL_WRITE;
1453                 error = priv_check(req->td, priv);
1454                 if (error)
1455                         return (error);
1456         }
1457
1458         if (!oid->oid_handler)
1459                 return (EINVAL);
1460
1461         if ((oid->oid_kind & CTLTYPE) == CTLTYPE_NODE) {
1462                 arg1 = (int *)arg1 + indx;
1463                 arg2 -= indx;
1464         } else {
1465                 arg1 = oid->oid_arg1;
1466                 arg2 = oid->oid_arg2;
1467         }
1468 #ifdef MAC
1469         error = mac_system_check_sysctl(req->td->td_ucred, oid, arg1, arg2,
1470             req);
1471         if (error != 0)
1472                 return (error);
1473 #endif
1474         oid->oid_running++;
1475         SYSCTL_XUNLOCK();
1476
1477         if (!(oid->oid_kind & CTLFLAG_MPSAFE))
1478                 mtx_lock(&Giant);
1479         error = oid->oid_handler(oid, arg1, arg2, req);
1480         if (!(oid->oid_kind & CTLFLAG_MPSAFE))
1481                 mtx_unlock(&Giant);
1482
1483         KFAIL_POINT_ERROR(_debug_fail_point, sysctl_running, error);
1484
1485         SYSCTL_XLOCK();
1486         oid->oid_running--;
1487         if (oid->oid_running == 0 && (oid->oid_kind & CTLFLAG_DYING) != 0)
1488                 wakeup(&oid->oid_running);
1489         return (error);
1490 }
1491
1492 #ifndef _SYS_SYSPROTO_H_
1493 struct sysctl_args {
1494         int     *name;
1495         u_int   namelen;
1496         void    *old;
1497         size_t  *oldlenp;
1498         void    *new;
1499         size_t  newlen;
1500 };
1501 #endif
1502 int
1503 __sysctl(struct thread *td, struct sysctl_args *uap)
1504 {
1505         int error, i, name[CTL_MAXNAME];
1506         size_t j;
1507
1508         if (uap->namelen > CTL_MAXNAME || uap->namelen < 2)
1509                 return (EINVAL);
1510
1511         error = copyin(uap->name, &name, uap->namelen * sizeof(int));
1512         if (error)
1513                 return (error);
1514
1515         error = userland_sysctl(td, name, uap->namelen,
1516                 uap->old, uap->oldlenp, 0,
1517                 uap->new, uap->newlen, &j, 0);
1518         if (error && error != ENOMEM)
1519                 return (error);
1520         if (uap->oldlenp) {
1521                 i = copyout(&j, uap->oldlenp, sizeof(j));
1522                 if (i)
1523                         return (i);
1524         }
1525         return (error);
1526 }
1527
1528 /*
1529  * This is used from various compatibility syscalls too.  That's why name
1530  * must be in kernel space.
1531  */
1532 int
1533 userland_sysctl(struct thread *td, int *name, u_int namelen, void *old,
1534     size_t *oldlenp, int inkernel, void *new, size_t newlen, size_t *retval,
1535     int flags)
1536 {
1537         int error = 0, memlocked;
1538         struct sysctl_req req;
1539
1540         bzero(&req, sizeof req);
1541
1542         req.td = td;
1543         req.flags = flags;
1544
1545         if (oldlenp) {
1546                 if (inkernel) {
1547                         req.oldlen = *oldlenp;
1548                 } else {
1549                         error = copyin(oldlenp, &req.oldlen, sizeof(*oldlenp));
1550                         if (error)
1551                                 return (error);
1552                 }
1553         }
1554         req.validlen = req.oldlen;
1555
1556         if (old) {
1557                 if (!useracc(old, req.oldlen, VM_PROT_WRITE))
1558                         return (EFAULT);
1559                 req.oldptr= old;
1560         }
1561
1562         if (new != NULL) {
1563                 if (!useracc(new, newlen, VM_PROT_READ))
1564                         return (EFAULT);
1565                 req.newlen = newlen;
1566                 req.newptr = new;
1567         }
1568
1569         req.oldfunc = sysctl_old_user;
1570         req.newfunc = sysctl_new_user;
1571         req.lock = REQ_UNWIRED;
1572
1573 #ifdef KTRACE
1574         if (KTRPOINT(curthread, KTR_SYSCTL))
1575                 ktrsysctl(name, namelen);
1576 #endif
1577
1578         if (req.oldlen > PAGE_SIZE) {
1579                 memlocked = 1;
1580                 sx_xlock(&sysctlmemlock);
1581         } else
1582                 memlocked = 0;
1583         CURVNET_SET(TD_TO_VNET(td));
1584
1585         for (;;) {
1586                 req.oldidx = 0;
1587                 req.newidx = 0;
1588                 SYSCTL_XLOCK();
1589                 error = sysctl_root(0, name, namelen, &req);
1590                 SYSCTL_XUNLOCK();
1591                 if (error != EAGAIN)
1592                         break;
1593                 kern_yield(curthread->td_user_pri);
1594         }
1595
1596         CURVNET_RESTORE();
1597
1598         if (req.lock == REQ_WIRED && req.validlen > 0)
1599                 vsunlock(req.oldptr, req.validlen);
1600         if (memlocked)
1601                 sx_xunlock(&sysctlmemlock);
1602
1603         if (error && error != ENOMEM)
1604                 return (error);
1605
1606         if (retval) {
1607                 if (req.oldptr && req.oldidx > req.validlen)
1608                         *retval = req.validlen;
1609                 else
1610                         *retval = req.oldidx;
1611         }
1612         return (error);
1613 }
1614
1615 /*
1616  * Drain into a sysctl struct.  The user buffer should be wired if a page
1617  * fault would cause issue.
1618  */
1619 static int
1620 sbuf_sysctl_drain(void *arg, const char *data, int len)
1621 {
1622         struct sysctl_req *req = arg;
1623         int error;
1624
1625         error = SYSCTL_OUT(req, data, len);
1626         KASSERT(error >= 0, ("Got unexpected negative value %d", error));
1627         return (error == 0 ? len : -error);
1628 }
1629
1630 struct sbuf *
1631 sbuf_new_for_sysctl(struct sbuf *s, char *buf, int length,
1632     struct sysctl_req *req)
1633 {
1634
1635         s = sbuf_new(s, buf, length, SBUF_FIXEDLEN);
1636         sbuf_set_drain(s, sbuf_sysctl_drain, req);
1637         return (s);
1638 }