Changeset View
Changeset View
Standalone View
Standalone View
head/sys/kern/kern_sysctl.c
Show First 20 Lines • Show All 929 Lines • ▼ Show 20 Lines | |||||
* These functions implement a presently undocumented interface | * These functions implement a presently undocumented interface | ||||
* used by the sysctl program to walk the tree, and get the type | * used by the sysctl program to walk the tree, and get the type | ||||
* so it can print the value. | * so it can print the value. | ||||
* This interface is under work and consideration, and should probably | * This interface is under work and consideration, and should probably | ||||
* be killed with a big axe by the first person who can find the time. | * be killed with a big axe by the first person who can find the time. | ||||
* (be aware though, that the proper interface isn't as obvious as it | * (be aware though, that the proper interface isn't as obvious as it | ||||
* may seem, there are various conflicting requirements. | * may seem, there are various conflicting requirements. | ||||
* | * | ||||
* {0,0} printf the entire MIB-tree. | * {CTL_SYSCTL, CTL_SYSCTL_DEBUG} printf the entire MIB-tree. | ||||
* {0,1,...} return the name of the "..." OID. | * {CTL_SYSCTL, CTL_SYSCTL_NAME, ...} return the name of the "..." | ||||
* {0,2,...} return the next OID. | * OID. | ||||
* {0,3} return the OID of the name in "new" | * {CTL_SYSCTL, CTL_SYSCTL_NEXT, ...} return the next OID. | ||||
* {0,4,...} return the kind & format info for the "..." OID. | * {CTL_SYSCTL, CTL_SYSCTL_NAME2OID} return the OID of the name in | ||||
* {0,5,...} return the description of the "..." OID. | * "new" | ||||
* {0,6,...} return the aggregation label of the "..." OID. | * {CTL_SYSCTL, CTL_SYSCTL_OIDFMT, ...} return the kind & format info | ||||
* for the "..." OID. | |||||
* {CTL_SYSCTL, CTL_SYSCTL_OIDDESCR, ...} return the description of the | |||||
* "..." OID. | |||||
* {CTL_SYSCTL, CTL_SYSCTL_OIDLABEL, ...} return the aggregation label of | |||||
* the "..." OID. | |||||
*/ | */ | ||||
#ifdef SYSCTL_DEBUG | #ifdef SYSCTL_DEBUG | ||||
static void | static void | ||||
sysctl_sysctl_debug_dump_node(struct sysctl_oid_list *l, int i) | sysctl_sysctl_debug_dump_node(struct sysctl_oid_list *l, int i) | ||||
{ | { | ||||
int k; | int k; | ||||
struct sysctl_oid *oidp; | struct sysctl_oid *oidp; | ||||
▲ Show 20 Lines • Show All 51 Lines • ▼ Show 20 Lines | sysctl_sysctl_debug(SYSCTL_HANDLER_ARGS) | ||||
if (error) | if (error) | ||||
return (error); | return (error); | ||||
SYSCTL_RLOCK(&tracker); | SYSCTL_RLOCK(&tracker); | ||||
sysctl_sysctl_debug_dump_node(&sysctl__children, 0); | sysctl_sysctl_debug_dump_node(&sysctl__children, 0); | ||||
SYSCTL_RUNLOCK(&tracker); | SYSCTL_RUNLOCK(&tracker); | ||||
return (ENOENT); | return (ENOENT); | ||||
} | } | ||||
SYSCTL_PROC(_sysctl, 0, debug, CTLTYPE_STRING|CTLFLAG_RD|CTLFLAG_MPSAFE, | SYSCTL_PROC(_sysctl, CTL_SYSCTL_DEBUG, debug, CTLTYPE_STRING | CTLFLAG_RD | | ||||
0, 0, sysctl_sysctl_debug, "-", ""); | CTLFLAG_MPSAFE, 0, 0, sysctl_sysctl_debug, "-", ""); | ||||
#endif | #endif | ||||
static int | static int | ||||
sysctl_sysctl_name(SYSCTL_HANDLER_ARGS) | sysctl_sysctl_name(SYSCTL_HANDLER_ARGS) | ||||
{ | { | ||||
int *name = (int *) arg1; | int *name = (int *) arg1; | ||||
u_int namelen = arg2; | u_int namelen = arg2; | ||||
int error = 0; | int error = 0; | ||||
▲ Show 20 Lines • Show All 48 Lines • ▼ Show 20 Lines | out: | ||||
SYSCTL_RUNLOCK(&tracker); | SYSCTL_RUNLOCK(&tracker); | ||||
return (error); | return (error); | ||||
} | } | ||||
/* | /* | ||||
* XXXRW/JA: Shouldn't return name data for nodes that we don't permit in | * XXXRW/JA: Shouldn't return name data for nodes that we don't permit in | ||||
* capability mode. | * capability mode. | ||||
*/ | */ | ||||
static SYSCTL_NODE(_sysctl, 1, name, CTLFLAG_RD | CTLFLAG_MPSAFE | CTLFLAG_CAPRD, | static SYSCTL_NODE(_sysctl, CTL_SYSCTL_NAME, name, CTLFLAG_RD | | ||||
sysctl_sysctl_name, ""); | CTLFLAG_MPSAFE | CTLFLAG_CAPRD, sysctl_sysctl_name, ""); | ||||
static int | static int | ||||
sysctl_sysctl_next_ls(struct sysctl_oid_list *lsp, int *name, u_int namelen, | sysctl_sysctl_next_ls(struct sysctl_oid_list *lsp, int *name, u_int namelen, | ||||
int *next, int *len, int level, struct sysctl_oid **oidpp) | int *next, int *len, int level, struct sysctl_oid **oidpp) | ||||
{ | { | ||||
struct sysctl_oid *oidp; | struct sysctl_oid *oidp; | ||||
SYSCTL_ASSERT_LOCKED(); | SYSCTL_ASSERT_LOCKED(); | ||||
▲ Show 20 Lines • Show All 69 Lines • ▼ Show 20 Lines | sysctl_sysctl_next(SYSCTL_HANDLER_ARGS) | ||||
error = SYSCTL_OUT(req, newoid, j * sizeof (int)); | error = SYSCTL_OUT(req, newoid, j * sizeof (int)); | ||||
return (error); | return (error); | ||||
} | } | ||||
/* | /* | ||||
* XXXRW/JA: Shouldn't return next data for nodes that we don't permit in | * XXXRW/JA: Shouldn't return next data for nodes that we don't permit in | ||||
* capability mode. | * capability mode. | ||||
*/ | */ | ||||
static SYSCTL_NODE(_sysctl, 2, next, CTLFLAG_RD | CTLFLAG_MPSAFE | CTLFLAG_CAPRD, | static SYSCTL_NODE(_sysctl, CTL_SYSCTL_NEXT, next, CTLFLAG_RD | | ||||
sysctl_sysctl_next, ""); | CTLFLAG_MPSAFE | CTLFLAG_CAPRD, sysctl_sysctl_next, ""); | ||||
static int | static int | ||||
name2oid(char *name, int *oid, int *len, struct sysctl_oid **oidpp) | name2oid(char *name, int *oid, int *len, struct sysctl_oid **oidpp) | ||||
{ | { | ||||
struct sysctl_oid *oidp; | struct sysctl_oid *oidp; | ||||
struct sysctl_oid_list *lsp = &sysctl__children; | struct sysctl_oid_list *lsp = &sysctl__children; | ||||
char *p; | char *p; | ||||
▲ Show 20 Lines • Show All 69 Lines • ▼ Show 20 Lines | sysctl_sysctl_name2oid(SYSCTL_HANDLER_ARGS) | ||||
error = SYSCTL_OUT(req, oid, len * sizeof *oid); | error = SYSCTL_OUT(req, oid, len * sizeof *oid); | ||||
return (error); | return (error); | ||||
} | } | ||||
/* | /* | ||||
* XXXRW/JA: Shouldn't return name2oid data for nodes that we don't permit in | * XXXRW/JA: Shouldn't return name2oid data for nodes that we don't permit in | ||||
* capability mode. | * capability mode. | ||||
*/ | */ | ||||
SYSCTL_PROC(_sysctl, 3, name2oid, | SYSCTL_PROC(_sysctl, CTL_SYSCTL_NAME2OID, name2oid, CTLTYPE_INT | CTLFLAG_RW | | ||||
CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_ANYBODY | CTLFLAG_MPSAFE | CTLFLAG_ANYBODY | CTLFLAG_MPSAFE | CTLFLAG_CAPRW, 0, 0, | ||||
| CTLFLAG_CAPRW, 0, 0, sysctl_sysctl_name2oid, "I", ""); | sysctl_sysctl_name2oid, "I", ""); | ||||
static int | static int | ||||
sysctl_sysctl_oidfmt(SYSCTL_HANDLER_ARGS) | sysctl_sysctl_oidfmt(SYSCTL_HANDLER_ARGS) | ||||
{ | { | ||||
struct sysctl_oid *oid; | struct sysctl_oid *oid; | ||||
struct rm_priotracker tracker; | struct rm_priotracker tracker; | ||||
int error; | int error; | ||||
Show All 11 Lines | if (error) | ||||
goto out; | goto out; | ||||
error = SYSCTL_OUT(req, oid->oid_fmt, strlen(oid->oid_fmt) + 1); | error = SYSCTL_OUT(req, oid->oid_fmt, strlen(oid->oid_fmt) + 1); | ||||
out: | out: | ||||
SYSCTL_RUNLOCK(&tracker); | SYSCTL_RUNLOCK(&tracker); | ||||
return (error); | return (error); | ||||
} | } | ||||
static SYSCTL_NODE(_sysctl, 4, oidfmt, CTLFLAG_RD|CTLFLAG_MPSAFE|CTLFLAG_CAPRD, | static SYSCTL_NODE(_sysctl, CTL_SYSCTL_OIDFMT, oidfmt, CTLFLAG_RD | | ||||
sysctl_sysctl_oidfmt, ""); | CTLFLAG_MPSAFE | CTLFLAG_CAPRD, sysctl_sysctl_oidfmt, ""); | ||||
static int | static int | ||||
sysctl_sysctl_oiddescr(SYSCTL_HANDLER_ARGS) | sysctl_sysctl_oiddescr(SYSCTL_HANDLER_ARGS) | ||||
{ | { | ||||
struct sysctl_oid *oid; | struct sysctl_oid *oid; | ||||
struct rm_priotracker tracker; | struct rm_priotracker tracker; | ||||
int error; | int error; | ||||
SYSCTL_RLOCK(&tracker); | SYSCTL_RLOCK(&tracker); | ||||
error = sysctl_find_oid(arg1, arg2, &oid, NULL, req); | error = sysctl_find_oid(arg1, arg2, &oid, NULL, req); | ||||
if (error) | if (error) | ||||
goto out; | goto out; | ||||
if (oid->oid_descr == NULL) { | if (oid->oid_descr == NULL) { | ||||
error = ENOENT; | error = ENOENT; | ||||
goto out; | goto out; | ||||
} | } | ||||
error = SYSCTL_OUT(req, oid->oid_descr, strlen(oid->oid_descr) + 1); | error = SYSCTL_OUT(req, oid->oid_descr, strlen(oid->oid_descr) + 1); | ||||
out: | out: | ||||
SYSCTL_RUNLOCK(&tracker); | SYSCTL_RUNLOCK(&tracker); | ||||
return (error); | return (error); | ||||
} | } | ||||
static SYSCTL_NODE(_sysctl, 5, oiddescr, CTLFLAG_RD|CTLFLAG_MPSAFE|CTLFLAG_CAPRD, | static SYSCTL_NODE(_sysctl, CTL_SYSCTL_OIDDESCR, oiddescr, CTLFLAG_RD | | ||||
sysctl_sysctl_oiddescr, ""); | CTLFLAG_MPSAFE|CTLFLAG_CAPRD, sysctl_sysctl_oiddescr, ""); | ||||
static int | static int | ||||
sysctl_sysctl_oidlabel(SYSCTL_HANDLER_ARGS) | sysctl_sysctl_oidlabel(SYSCTL_HANDLER_ARGS) | ||||
{ | { | ||||
struct sysctl_oid *oid; | struct sysctl_oid *oid; | ||||
struct rm_priotracker tracker; | struct rm_priotracker tracker; | ||||
int error; | int error; | ||||
SYSCTL_RLOCK(&tracker); | SYSCTL_RLOCK(&tracker); | ||||
error = sysctl_find_oid(arg1, arg2, &oid, NULL, req); | error = sysctl_find_oid(arg1, arg2, &oid, NULL, req); | ||||
if (error) | if (error) | ||||
goto out; | goto out; | ||||
if (oid->oid_label == NULL) { | if (oid->oid_label == NULL) { | ||||
error = ENOENT; | error = ENOENT; | ||||
goto out; | goto out; | ||||
} | } | ||||
error = SYSCTL_OUT(req, oid->oid_label, strlen(oid->oid_label) + 1); | error = SYSCTL_OUT(req, oid->oid_label, strlen(oid->oid_label) + 1); | ||||
out: | out: | ||||
SYSCTL_RUNLOCK(&tracker); | SYSCTL_RUNLOCK(&tracker); | ||||
return (error); | return (error); | ||||
} | } | ||||
static SYSCTL_NODE(_sysctl, 6, oidlabel, | static SYSCTL_NODE(_sysctl, CTL_SYSCTL_OIDLABEL, oidlabel, CTLFLAG_RD | | ||||
CTLFLAG_RD | CTLFLAG_MPSAFE | CTLFLAG_CAPRD, sysctl_sysctl_oidlabel, ""); | CTLFLAG_MPSAFE | CTLFLAG_CAPRD, sysctl_sysctl_oidlabel, ""); | ||||
/* | /* | ||||
* Default "handler" functions. | * Default "handler" functions. | ||||
*/ | */ | ||||
/* | /* | ||||
* Handle a bool. | * Handle a bool. | ||||
* Two cases: | * Two cases: | ||||
▲ Show 20 Lines • Show All 510 Lines • ▼ Show 20 Lines | |||||
int | int | ||||
kernel_sysctlbyname(struct thread *td, char *name, void *old, size_t *oldlenp, | kernel_sysctlbyname(struct thread *td, char *name, void *old, size_t *oldlenp, | ||||
void *new, size_t newlen, size_t *retval, int flags) | void *new, size_t newlen, size_t *retval, int flags) | ||||
{ | { | ||||
int oid[CTL_MAXNAME]; | int oid[CTL_MAXNAME]; | ||||
size_t oidlen, plen; | size_t oidlen, plen; | ||||
int error; | int error; | ||||
oid[0] = 0; /* sysctl internal magic */ | oid[0] = CTL_SYSCTL; | ||||
oid[1] = 3; /* name2oid */ | oid[1] = CTL_SYSCTL_NAME2OID; | ||||
oidlen = sizeof(oid); | oidlen = sizeof(oid); | ||||
error = kernel_sysctl(td, oid, 2, oid, &oidlen, | error = kernel_sysctl(td, oid, 2, oid, &oidlen, | ||||
(void *)name, strlen(name), &plen, flags); | (void *)name, strlen(name), &plen, flags); | ||||
if (error) | if (error) | ||||
return (error); | return (error); | ||||
error = kernel_sysctl(td, oid, plen / sizeof(int), old, oldlenp, | error = kernel_sysctl(td, oid, plen / sizeof(int), old, oldlenp, | ||||
▲ Show 20 Lines • Show All 290 Lines • ▼ Show 20 Lines | if (namelen > MAXPATHLEN || namelen == 0) | ||||
return (EINVAL); | return (EINVAL); | ||||
name = namebuf; | name = namebuf; | ||||
if (namelen > sizeof(namebuf)) | if (namelen > sizeof(namebuf)) | ||||
name = malloc(namelen, M_SYSCTL, M_WAITOK); | name = malloc(namelen, M_SYSCTL, M_WAITOK); | ||||
error = copyin(oname, name, namelen); | error = copyin(oname, name, namelen); | ||||
if (error != 0) | if (error != 0) | ||||
goto out; | goto out; | ||||
oid[0] = 0; | oid[0] = CTL_SYSCTL; | ||||
oid[1] = 3; | oid[1] = CTL_SYSCTL_NAME2OID; | ||||
oidlen = sizeof(oid); | oidlen = sizeof(oid); | ||||
error = kernel_sysctl(td, oid, 2, oid, &oidlen, (void *)name, namelen, | error = kernel_sysctl(td, oid, 2, oid, &oidlen, (void *)name, namelen, | ||||
retval, flags); | retval, flags); | ||||
if (error != 0) | if (error != 0) | ||||
goto out; | goto out; | ||||
error = userland_sysctl(td, oid, *retval / sizeof(int), old, oldlenp, | error = userland_sysctl(td, oid, *retval / sizeof(int), old, oldlenp, | ||||
inkernel, new, newlen, retval, flags); | inkernel, new, newlen, retval, flags); | ||||
▲ Show 20 Lines • Show All 484 Lines • ▼ Show 20 Lines | |||||
*/ | */ | ||||
static int | static int | ||||
db_show_sysctl_all(int *oid, size_t len, int flags) | db_show_sysctl_all(int *oid, size_t len, int flags) | ||||
{ | { | ||||
struct sysctl_oid *oidp; | struct sysctl_oid *oidp; | ||||
int name1[CTL_MAXNAME + 2], name2[CTL_MAXNAME + 2]; | int name1[CTL_MAXNAME + 2], name2[CTL_MAXNAME + 2]; | ||||
size_t l1, l2; | size_t l1, l2; | ||||
name1[0] = 0; | name1[0] = CTL_SYSCTL; | ||||
name1[1] = 2; | name1[1] = CTL_SYSCTL_NEXT; | ||||
l1 = 2; | l1 = 2; | ||||
if (len) { | if (len) { | ||||
memcpy(name1+2, oid, len * sizeof(int)); | memcpy(name1+2, oid, len * sizeof(int)); | ||||
l1 +=len; | l1 +=len; | ||||
} else { | } else { | ||||
name1[2] = 1; | name1[2] = 1; | ||||
l1++; | l1++; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 159 Lines • Show Last 20 Lines |