diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2018-08-09 14:02:09 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2018-09-21 10:29:38 +0200 |
commit | bb80d9df8bac71eedee1a6787ca63aef972a7e48 (patch) | |
tree | 1b5cb9443c5ead5706c35afb618abbbd1592315e /freebsd/sys/kern/kern_sysctl.c | |
parent | Update to FreeBSD head 2017-10-01 (diff) | |
download | rtems-libbsd-bb80d9df8bac71eedee1a6787ca63aef972a7e48.tar.bz2 |
Update to FreeBSD head 2017-12-01
Git mirror commit e724f51f811a4b2bd29447f8b85ab5c2f9b88266.
Update #3472.
Diffstat (limited to 'freebsd/sys/kern/kern_sysctl.c')
-rw-r--r-- | freebsd/sys/kern/kern_sysctl.c | 55 |
1 files changed, 47 insertions, 8 deletions
diff --git a/freebsd/sys/kern/kern_sysctl.c b/freebsd/sys/kern/kern_sysctl.c index e99a8bd6..02078a32 100644 --- a/freebsd/sys/kern/kern_sysctl.c +++ b/freebsd/sys/kern/kern_sysctl.c @@ -1,6 +1,8 @@ #include <machine/rtems-bsd-kernel-space.h> /*- + * SPDX-License-Identifier: BSD-3-Clause + * * Copyright (c) 1982, 1986, 1989, 1993 * The Regents of the University of California. All rights reserved. * @@ -516,6 +518,37 @@ retry: } void +sysctl_register_disabled_oid(struct sysctl_oid *oidp) +{ + + /* + * Mark the leaf as dormant if it's not to be immediately enabled. + * We do not disable nodes as they can be shared between modules + * and it is always safe to access a node. + */ + KASSERT((oidp->oid_kind & CTLFLAG_DORMANT) == 0, + ("internal flag is set in oid_kind")); + if ((oidp->oid_kind & CTLTYPE) != CTLTYPE_NODE) + oidp->oid_kind |= CTLFLAG_DORMANT; + sysctl_register_oid(oidp); +} + +void +sysctl_enable_oid(struct sysctl_oid *oidp) +{ + + SYSCTL_ASSERT_WLOCKED(); + if ((oidp->oid_kind & CTLTYPE) == CTLTYPE_NODE) { + KASSERT((oidp->oid_kind & CTLFLAG_DORMANT) == 0, + ("sysctl node is marked as dormant")); + return; + } + KASSERT((oidp->oid_kind & CTLFLAG_DORMANT) != 0, + ("enabling already enabled sysctl oid")); + oidp->oid_kind &= ~CTLFLAG_DORMANT; +} + +void sysctl_unregister_oid(struct sysctl_oid *oidp) { struct sysctl_oid *p; @@ -1063,7 +1096,7 @@ sysctl_sysctl_next_ls(struct sysctl_oid_list *lsp, int *name, u_int namelen, *next = oidp->oid_number; *oidpp = oidp; - if (oidp->oid_kind & CTLFLAG_SKIP) + if ((oidp->oid_kind & (CTLFLAG_SKIP | CTLFLAG_DORMANT)) != 0) continue; if (!namelen) { @@ -1184,17 +1217,21 @@ sysctl_sysctl_name2oid(SYSCTL_HANDLER_ARGS) int error, oid[CTL_MAXNAME], len = 0; struct sysctl_oid *op = NULL; struct rm_priotracker tracker; + char buf[32]; if (!req->newlen) return (ENOENT); if (req->newlen >= MAXPATHLEN) /* XXX arbitrary, undocumented */ return (ENAMETOOLONG); - p = malloc(req->newlen+1, M_SYSCTL, M_WAITOK); + p = buf; + if (req->newlen >= sizeof(buf)) + p = malloc(req->newlen+1, M_SYSCTL, M_WAITOK); error = SYSCTL_IN(req, p, req->newlen); if (error) { - free(p, M_SYSCTL); + if (p != buf) + free(p, M_SYSCTL); return (error); } @@ -1204,7 +1241,8 @@ sysctl_sysctl_name2oid(SYSCTL_HANDLER_ARGS) error = name2oid(p, oid, &len, &op); SYSCTL_RUNLOCK(&tracker); - free(p, M_SYSCTL); + if (p != buf) + free(p, M_SYSCTL); if (error) return (error); @@ -1902,6 +1940,8 @@ sysctl_find_oid(int *name, u_int namelen, struct sysctl_oid **noid, } lsp = SYSCTL_CHILDREN(oid); } else if (indx == namelen) { + if ((oid->oid_kind & CTLFLAG_DORMANT) != 0) + return (ENOENT); *noid = oid; if (nindx != NULL) *nindx = indx; @@ -2105,12 +2145,11 @@ userland_sysctl(struct thread *td, int *name, u_int namelen, void *old, if (KTRPOINT(curthread, KTR_SYSCTL)) ktrsysctl(name, namelen); #endif - - if (req.oldptr && req.oldlen > PAGE_SIZE) { + memlocked = 0; + if (req.oldptr && req.oldlen > 4 * PAGE_SIZE) { memlocked = 1; sx_xlock(&sysctlmemlock); - } else - memlocked = 0; + } CURVNET_SET(TD_TO_VNET(td)); for (;;) { |