(c) 2003 Pawel Jakub Dawidek For now variables used by sysctls cannot be protected with mutexes. Some variables in source are marked that they should be (for example security.jail.*). This patch adds code that will handle protecting sysctl variable with given mutexes. Patch against FreeBSD 5.1-CURRENT, kern.osreldate: 501102. diff -upr /usr/src/sys/kern/kern_jail.c src/sys/kern/kern_jail.c --- /usr/src/sys/kern/kern_jail.c Tue Jul 1 11:29:30 2003 +++ src/sys/kern/kern_jail.c Sun Jul 13 15:24:05 2003 @@ -32,32 +32,33 @@ __FBSDID("$FreeBSD: src/sys/kern/kern_ja MALLOC_DEFINE(M_PRISON, "prison", "Prison structures"); + +/* allprison, lastprid, and prisoncount are protected by allprison_mtx. */ +struct prisonlist allprison; +struct mtx allprison_mtx; +int lastprid = 0; +int prisoncount = 0; + + SYSCTL_DECL(_security); SYSCTL_NODE(_security, OID_AUTO, jail, CTLFLAG_RW, 0, "Jail rules"); -mp_fixme("these variables need a lock") - +/* Those variables are protected by allprison_mtx mutex. */ int jail_set_hostname_allowed = 1; -SYSCTL_INT(_security_jail, OID_AUTO, set_hostname_allowed, CTLFLAG_RW, - &jail_set_hostname_allowed, 0, +SYSCTL_INT_MTX(_security_jail, OID_AUTO, set_hostname_allowed, CTLFLAG_RW, + &jail_set_hostname_allowed, 0, &allprison_mtx, "Processes in jail can set their hostnames"); int jail_socket_unixiproute_only = 1; -SYSCTL_INT(_security_jail, OID_AUTO, socket_unixiproute_only, CTLFLAG_RW, - &jail_socket_unixiproute_only, 0, +SYSCTL_INT_MTX(_security_jail, OID_AUTO, socket_unixiproute_only, CTLFLAG_RW, + &jail_socket_unixiproute_only, 0, &allprison_mtx, "Processes in jail are limited to creating UNIX/IPv4/route sockets only"); int jail_sysvipc_allowed = 0; -SYSCTL_INT(_security_jail, OID_AUTO, sysvipc_allowed, CTLFLAG_RW, - &jail_sysvipc_allowed, 0, +SYSCTL_INT_MTX(_security_jail, OID_AUTO, sysvipc_allowed, CTLFLAG_RW, + &jail_sysvipc_allowed, 0, &allprison_mtx, "Processes in jail can use System V IPC primitives"); - -/* allprison, lastprid, and prisoncount are protected by allprison_mtx. */ -struct prisonlist allprison; -struct mtx allprison_mtx; -int lastprid = 0; -int prisoncount = 0; static void init_prison(void *); static struct prison *prison_find(int); diff -upr /usr/src/sys/kern/kern_sysctl.c src/sys/kern/kern_sysctl.c --- /usr/src/sys/kern/kern_sysctl.c Tue Jul 1 11:29:30 2003 +++ src/sys/kern/kern_sysctl.c Sun Jul 13 16:30:02 2003 @@ -356,7 +356,8 @@ sysctl_remove_oid(struct sysctl_oid *oid struct sysctl_oid * sysctl_add_oid(struct sysctl_ctx_list *clist, struct sysctl_oid_list *parent, int number, const char *name, int kind, void *arg1, int arg2, - int (*handler)(SYSCTL_HANDLER_ARGS), const char *fmt, const char *descr) + int (*handler)(SYSCTL_HANDLER_ARGS), const char *fmt, struct mtx *mtx, + const char *descr) { struct sysctl_oid *oidp; ssize_t len; @@ -391,6 +392,7 @@ sysctl_add_oid(struct sysctl_ctx_list *c oidp->oid_name = newname; oidp->oid_handler = handler; oidp->oid_kind = CTLFLAG_DYN | kind; + oidp->oid_mtx = mtx; if ((kind & CTLTYPE) == CTLTYPE_NODE) { /* Allocate space for children */ SYSCTL_CHILDREN(oidp) = malloc(sizeof(struct sysctl_oid_list), @@ -788,19 +790,24 @@ sysctl_handle_int(SYSCTL_HANDLER_ARGS) /* * Attempt to get a coherent snapshot by making a copy of the data. */ + OID_LOCK(oidp); if (arg1) tmpout = *(int *)arg1; else tmpout = arg2; - error = SYSCTL_OUT(req, &tmpout, sizeof(int)); + error = SYSCTL_OUT_MTX(req, &tmpout, sizeof(int), + oidp->oid_mtx != NULL); - if (error || !req->newptr) + if (error || !req->newptr) { + OID_UNLOCK(oidp); return (error); + } if (!arg1) error = EPERM; else error = SYSCTL_IN(req, arg1, sizeof(int)); + OID_UNLOCK(oidp); return (error); } @@ -817,15 +824,22 @@ sysctl_handle_long(SYSCTL_HANDLER_ARGS) /* * Attempt to get a coherent snapshot by making a copy of the data. */ - if (!arg1) + OID_LOCK(oidp); + if (!arg1) { + OID_UNLOCK(oidp); return (EINVAL); + } tmpout = *(long *)arg1; - error = SYSCTL_OUT(req, &tmpout, sizeof(long)); + error = SYSCTL_OUT_MTX(req, &tmpout, sizeof(long), + oidp->oid_mtx != NULL); - if (error || !req->newptr) + if (error || !req->newptr) { + OID_UNLOCK(oidp); return (error); + } error = SYSCTL_IN(req, arg1, sizeof(long)); + OID_UNLOCK(oidp); return (error); } @@ -847,20 +861,27 @@ sysctl_handle_string(SYSCTL_HANDLER_ARGS * Attempt to get a coherent snapshot by copying to a * temporary kernel buffer. */ + OID_LOCK(oidp); retry: outlen = strlen((char *)arg1)+1; - tmparg = malloc(outlen, M_SYSCTLTMP, M_WAITOK); + tmparg = malloc(outlen, M_SYSCTLTMP, M_NOWAIT); + if (tmparg == NULL) { + OID_UNLOCK(oidp); + return (ENOMEM); + } if (strlcpy(tmparg, (char *)arg1, outlen) >= outlen) { free(tmparg, M_SYSCTLTMP); goto retry; } - error = SYSCTL_OUT(req, tmparg, outlen); + error = SYSCTL_OUT_MTX(req, tmparg, outlen, oidp->oid_mtx != NULL); free(tmparg, M_SYSCTLTMP); - if (error || !req->newptr) + if (error || !req->newptr) { + OID_UNLOCK(oidp); return (error); + } if ((req->newlen - req->newidx) >= arg2) { error = EINVAL; @@ -870,6 +891,7 @@ retry: ((char *)arg1)[arg2] = '\0'; } + OID_UNLOCK(oidp); return (error); } @@ -889,21 +911,26 @@ sysctl_handle_opaque(SYSCTL_HANDLER_ARGS * user space buffer or copying to a temporary kernel buffer * depending on the size of the data. */ + OID_LOCK(oidp); if (arg2 > PAGE_SIZE) { sysctl_wire_old_buffer(req, arg2); error = SYSCTL_OUT(req, arg1, arg2); } else { tmparg = malloc(arg2, M_SYSCTLTMP, M_WAITOK); bcopy(arg1, tmparg, arg2); - error = SYSCTL_OUT(req, tmparg, arg2); + error = SYSCTL_OUT_MTX(req, tmparg, arg2, + oidp->oid_mtx != NULL); free(tmparg, M_SYSCTLTMP); } - if (error || !req->newptr) + if (error || !req->newptr) { + OID_UNLOCK(oidp); return (error); + } error = SYSCTL_IN(req, arg1, arg2); + OID_UNLOCK(oidp); return (error); } @@ -912,7 +939,8 @@ sysctl_handle_opaque(SYSCTL_HANDLER_ARGS * XXX: rather untested at this point */ static int -sysctl_old_kernel(struct sysctl_req *req, const void *p, size_t l) +sysctl_old_kernel(struct sysctl_req *req, const void *p, size_t l, + int locked __unused) { size_t i = 0; @@ -1019,12 +1047,12 @@ kernel_sysctlbyname(struct thread *td, c * Transfer function to/from user space. */ static int -sysctl_old_user(struct sysctl_req *req, const void *p, size_t l) +sysctl_old_user(struct sysctl_req *req, const void *p, size_t l, int locked) { int error = 0; size_t i = 0; - if (req->lock == 1 && req->oldptr) + if (req->lock == 1 && req->oldptr && !locked) WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL, "sysctl_old_user()"); if (req->oldptr) { diff -upr /usr/src/sys/sys/sysctl.h src/sys/sys/sysctl.h --- /usr/src/sys/sys/sysctl.h Tue Jul 1 11:30:18 2003 +++ src/sys/sys/sysctl.h Sun Jul 13 16:37:28 2003 @@ -127,7 +127,8 @@ struct sysctl_req { void *oldptr; size_t oldlen; size_t oldidx; - int (*oldfunc)(struct sysctl_req *, const void *, size_t); + int (*oldfunc)(struct sysctl_req *, const void *, size_t, + int); void *newptr; size_t newlen; size_t newidx; @@ -140,6 +141,7 @@ SLIST_HEAD(sysctl_oid_list, sysctl_oid); * This describes one "oid" in the MIB tree. Potentially more nodes can * be hidden behind it, expanded by the handler. */ +struct mtx; struct sysctl_oid { struct sysctl_oid_list *oid_parent; SLIST_ENTRY(sysctl_oid) oid_link; @@ -151,11 +153,13 @@ struct sysctl_oid { int (*oid_handler)(SYSCTL_HANDLER_ARGS); const char *oid_fmt; int oid_refcnt; + struct mtx *oid_mtx; const char *descr; }; #define SYSCTL_IN(r, p, l) (r->newfunc)(r, p, l) -#define SYSCTL_OUT(r, p, l) (r->oldfunc)(r, p, l) +#define SYSCTL_OUT(r, p, l) SYSCTL_OUT_MTX(r, p, l, 0) +#define SYSCTL_OUT_MTX(r, p, l, m) (r->oldfunc)(r, p, l, m) int sysctl_handle_int(SYSCTL_HANDLER_ARGS); int sysctl_handle_long(SYSCTL_HANDLER_ARGS); @@ -194,88 +198,129 @@ TAILQ_HEAD(sysctl_ctx_list, sysctl_ctx_e /* This constructs a "raw" MIB oid. */ #define SYSCTL_OID(parent, nbr, name, kind, a1, a2, handler, fmt, descr) \ - static struct sysctl_oid sysctl__##parent##_##name = { \ - &sysctl_##parent##_children, { 0 }, \ - nbr, kind, a1, a2, #name, handler, fmt, 0, descr }; \ + SYSCTL_OID_MTX(parent, nbr, name, kind, a1, a2, handler, fmt, \ + NULL, descr) +/* Mutex that protects its value have to be given. */ +#define SYSCTL_OID_MTX(parent, nbr, name, kind, a1, a2, handler, fmt, mtx, descr) \ + static struct sysctl_oid sysctl__##parent##_##name = { \ + &sysctl_##parent##_children, { 0 }, nbr, kind, a1, a2, \ + #name, handler, fmt, 0, mtx, descr }; \ DATA_SET(sysctl_set, sysctl__##parent##_##name) #define SYSCTL_ADD_OID(ctx, parent, nbr, name, kind, a1, a2, handler, fmt, descr) \ - sysctl_add_oid(ctx, parent, nbr, name, kind, a1, a2, handler, fmt, descr) + SYSCTL_ADD_OID_MTX(ctx, parent, nbr, name, kind, a1, a2, \ + handler, fmt, NULL, descr) +#define SYSCTL_ADD_OID_MTX(ctx, parent, nbr, name, kind, a1, a2, handler, fmt, mtx, descr) \ + sysctl_add_oid(ctx, parent, nbr, name, kind, a1, a2, handler, \ + fmt, mtx, descr) /* This constructs a node from which other oids can hang. */ -#define SYSCTL_NODE(parent, nbr, name, access, handler, descr) \ - struct sysctl_oid_list SYSCTL_NODE_CHILDREN(parent, name); \ - SYSCTL_OID(parent, nbr, name, CTLTYPE_NODE|(access), \ - (void*)&SYSCTL_NODE_CHILDREN(parent, name), 0, handler, \ - "N", descr) - -#define SYSCTL_ADD_NODE(ctx, parent, nbr, name, access, handler, descr) \ - sysctl_add_oid(ctx, parent, nbr, name, CTLTYPE_NODE|(access), \ - 0, 0, handler, "N", descr) +#define SYSCTL_NODE(parent, nbr, name, access, handler, descr) \ + struct sysctl_oid_list SYSCTL_NODE_CHILDREN(parent, name); \ + SYSCTL_OID(parent, nbr, name, CTLTYPE_NODE|(access), \ + (void*)&SYSCTL_NODE_CHILDREN(parent, name), 0, handler, "N", descr) + +#define SYSCTL_ADD_NODE(ctx, parent, nbr, name, access, handler, descr) \ + sysctl_add_oid(ctx, parent, nbr, name, CTLTYPE_NODE|(access), 0,\ + 0, handler, "N", NULL, descr) /* Oid for a string. len can be 0 to indicate '\0' termination. */ -#define SYSCTL_STRING(parent, nbr, name, access, arg, len, descr) \ - SYSCTL_OID(parent, nbr, name, CTLTYPE_STRING|(access), \ - arg, len, sysctl_handle_string, "A", descr) +#define SYSCTL_STRING(parent, nbr, name, access, arg, len, descr) \ + SYSCTL_STRING_MTX(parent, nbr, name, access, arg, len, NULL, descr) +#define SYSCTL_STRING_MTX(parent, nbr, name, access, arg, len, mtx, descr) \ + SYSCTL_OID_MTX(parent, nbr, name, CTLTYPE_STRING|(access), arg, \ + len, sysctl_handle_string, "A", mtx, descr) #define SYSCTL_ADD_STRING(ctx, parent, nbr, name, access, arg, len, descr) \ - sysctl_add_oid(ctx, parent, nbr, name, CTLTYPE_STRING|(access), \ - arg, len, sysctl_handle_string, "A", descr) + SYSCTL_ADD_STRING_MTX(ctx, parent, nbr, name, access, arg, len, \ + NULL, descr) +#define SYSCTL_ADD_STRING_MTX(ctx, parent, nbr, name, access, arg, len, mtx, descr) \ + sysctl_add_oid(ctx, parent, nbr, name, CTLTYPE_STRING|(access), \ + arg, len, sysctl_handle_string, "A", mtx, descr) /* Oid for an int. If ptr is NULL, val is returned. */ #define SYSCTL_INT(parent, nbr, name, access, ptr, val, descr) \ - SYSCTL_OID(parent, nbr, name, CTLTYPE_INT|(access), \ - ptr, val, sysctl_handle_int, "I", descr) - -#define SYSCTL_ADD_INT(ctx, parent, nbr, name, access, ptr, val, descr) \ - sysctl_add_oid(ctx, parent, nbr, name, CTLTYPE_INT|(access), \ - ptr, val, sysctl_handle_int, "I", descr) + SYSCTL_INT_MTX(parent, nbr, name, access, ptr, val, NULL, descr) +#define SYSCTL_INT_MTX(parent, nbr, name, access, ptr, val, mtx, descr) \ + SYSCTL_OID_MTX(parent, nbr, name, CTLTYPE_INT|(access), ptr, \ + val, sysctl_handle_int, "I", mtx, descr) + +#define SYSCTL_ADD_INT(ctx, parent, nbr, name, access, ptr, val, descr) \ + SYSCTL_ADD_INT_MTX(ctx, parent, nbr, name, access, ptr, val, \ + NULL, descr) +#define SYSCTL_ADD_INT_MTX(ctx, parent, nbr, name, access, ptr, val, mtx, descr) \ + sysctl_add_oid(ctx, parent, nbr, name, CTLTYPE_INT|(access), \ + ptr, val, sysctl_handle_int, "I", mtx, descr) /* Oid for an unsigned int. If ptr is NULL, val is returned. */ -#define SYSCTL_UINT(parent, nbr, name, access, ptr, val, descr) \ - SYSCTL_OID(parent, nbr, name, CTLTYPE_UINT|(access), \ - ptr, val, sysctl_handle_int, "IU", descr) - -#define SYSCTL_ADD_UINT(ctx, parent, nbr, name, access, ptr, val, descr) \ - sysctl_add_oid(ctx, parent, nbr, name, CTLTYPE_UINT|(access), \ - ptr, val, sysctl_handle_int, "IU", descr) +#define SYSCTL_UINT(parent, nbr, name, access, ptr, val, descr) \ + SYSCTL_UINT_MTX(parent, nbr, name, access, ptr, val, NULL, descr) +#define SYSCTL_UINT_MTX(parent, nbr, name, access, ptr, val, mtx, descr) \ + SYSCTL_OID_MTX(parent, nbr, name, CTLTYPE_UINT|(access), ptr, \ + val, sysctl_handle_int, "IU", mtx, descr) + +#define SYSCTL_ADD_UINT(ctx, parent, nbr, name, access, ptr, val, descr) \ + SYSCTL_ADD_UINT_MTX(ctx, parent, nbr, name, access, ptr, val, \ + NULL, descr) +#define SYSCTL_ADD_UINT_MTX(ctx, parent, nbr, name, access, ptr, val, mtx, descr) \ + sysctl_add_oid(ctx, parent, nbr, name, CTLTYPE_UINT|(access), \ + ptr, val, sysctl_handle_int, "IU", mtx, descr) /* Oid for a long. The pointer must be non NULL. */ #define SYSCTL_LONG(parent, nbr, name, access, ptr, val, descr) \ - SYSCTL_OID(parent, nbr, name, CTLTYPE_LONG|(access), \ - ptr, val, sysctl_handle_long, "L", descr) - -#define SYSCTL_ADD_LONG(ctx, parent, nbr, name, access, ptr, descr) \ - sysctl_add_oid(ctx, parent, nbr, name, CTLTYPE_LONG|(access), \ - ptr, 0, sysctl_handle_long, "L", descr) + SYSCTL_LONG_MTX(parent, nbr, name, access, ptr, val, NULL, descr) +#define SYSCTL_LONG_MTX(parent, nbr, name, access, ptr, val, mtx, descr) \ + SYSCTL_OID_MTX(parent, nbr, name, CTLTYPE_LONG|(access), ptr, \ + val, sysctl_handle_long, "L", mtx, descr) + +#define SYSCTL_ADD_LONG(ctx, parent, nbr, name, access, ptr, descr) \ + SYSCTL_ADD_LONG_MTX(ctx, parent, nbr, name, access, ptr, NULL, descr) +#define SYSCTL_ADD_LONG_MTX(ctx, parent, nbr, name, access, ptr, mtx, descr) \ + sysctl_add_oid(ctx, parent, nbr, name, CTLTYPE_LONG|(access), \ + ptr, 0, sysctl_handle_long, "L", mtx, descr) /* Oid for an unsigned long. The pointer must be non NULL. */ #define SYSCTL_ULONG(parent, nbr, name, access, ptr, val, descr) \ - SYSCTL_OID(parent, nbr, name, CTLTYPE_ULONG|(access), \ - ptr, val, sysctl_handle_long, "LU", descr) - -#define SYSCTL_ADD_ULONG(ctx, parent, nbr, name, access, ptr, descr) \ - sysctl_add_oid(ctx, parent, nbr, name, CTLTYPE_ULONG|(access), \ - ptr, 0, sysctl_handle_long, "LU", descr) + SYSCTL_ULONG_MTX(parent, nbr, name, access, ptr, val, NULL, descr) +#define SYSCTL_ULONG_MTX(parent, nbr, name, access, ptr, val, mtx, descr) \ + SYSCTL_OID_MTX(parent, nbr, name, CTLTYPE_ULONG|(access), ptr, \ + val, sysctl_handle_long, "LU", mtx, descr) + +#define SYSCTL_ADD_ULONG(ctx, parent, nbr, name, access, ptr, descr) \ + SYSCTL_ADD_ULONG_MTX(ctx, parent, nbr, name, access, ptr, NULL, descr) +#define SYSCTL_ADD_ULONG_MTX(ctx, parent, nbr, name, access, ptr, mtx, descr) \ + sysctl_add_oid(ctx, parent, nbr, name, CTLTYPE_ULONG|(access), \ + ptr, 0, sysctl_handle_long, "LU", mtx, descr) /* Oid for an opaque object. Specified by a pointer and a length. */ -#define SYSCTL_OPAQUE(parent, nbr, name, access, ptr, len, fmt, descr) \ - SYSCTL_OID(parent, nbr, name, CTLTYPE_OPAQUE|(access), \ - ptr, len, sysctl_handle_opaque, fmt, descr) - -#define SYSCTL_ADD_OPAQUE(ctx, parent, nbr, name, access, ptr, len, fmt, descr)\ - sysctl_add_oid(ctx, parent, nbr, name, CTLTYPE_OPAQUE|(access), \ - ptr, len, sysctl_handle_opaque, fmt, descr) +#define SYSCTL_OPAQUE(parent, nbr, name, access, ptr, len, fmt, descr) \ + SYSCTL_OPAQUE_MTX(parent, nbr, name, access, ptr, len, fmt, NULL, descr) +#define SYSCTL_OPAQUE_MTX(parent, nbr, name, access, ptr, len, fmt, mtx, descr) \ + SYSCTL_OID_MTX(parent, nbr, name, CTLTYPE_OPAQUE|(access), ptr, \ + len, sysctl_handle_opaque, fmt, mtx, descr) + +#define SYSCTL_ADD_OPAQUE(ctx, parent, nbr, name, access, ptr, len, fmt, descr) \ + SYSCTL_ADD_OPAQUE_MTX(ctx, parent, nbr, name, access, ptr, len, \ + fmt, NULL, descr) +#define SYSCTL_ADD_OPAQUE_MTX(ctx, parent, nbr, name, access, ptr, len, fmt, mtx, descr) \ + sysctl_add_oid(ctx, parent, nbr, name, CTLTYPE_OPAQUE|(access), \ + ptr, len, sysctl_handle_opaque, fmt, mtx, descr) /* Oid for a struct. Specified by a pointer and a type. */ -#define SYSCTL_STRUCT(parent, nbr, name, access, ptr, type, descr) \ - SYSCTL_OID(parent, nbr, name, CTLTYPE_OPAQUE|(access), \ - ptr, sizeof(struct type), sysctl_handle_opaque, \ - "S," #type, descr) +#define SYSCTL_STRUCT(parent, nbr, name, access, ptr, type, descr) \ + SYSCTL_STRUCT_MTX(parent, nbr, name, access, ptr, type, NULL, descr) +#define SYSCTL_STRUCT_MTX(parent, nbr, name, access, ptr, type, mtx, descr) \ + SYSCTL_OID_MTX(parent, nbr, name, CTLTYPE_OPAQUE|(access), ptr, \ + sizeof(struct type), sysctl_handle_opaque, "S," #type, mtx, \ + descr) #define SYSCTL_ADD_STRUCT(ctx, parent, nbr, name, access, ptr, type, descr) \ - sysctl_add_oid(ctx, parent, nbr, name, CTLTYPE_OPAQUE|(access), \ - ptr, sizeof(struct type), sysctl_handle_opaque, "S," #type, descr) + SYSCTL_ADD_STRUCT_MTX(ctx, parent, nbr, name, access, ptr, \ + type, NULL, descr) +#define SYSCTL_ADD_STRUCT_MTX(ctx, parent, nbr, name, access, ptr, type, mtx, descr) \ + sysctl_add_oid(ctx, parent, nbr, name, CTLTYPE_OPAQUE|(access), \ + ptr, sizeof(struct type), sysctl_handle_opaque, "S," #type, \ + mtx, descr) /* Oid for a procedure. Specified by a pointer and an arg. */ #define SYSCTL_PROC(parent, nbr, name, access, ptr, arg, handler, fmt, descr) \ @@ -284,8 +329,12 @@ TAILQ_HEAD(sysctl_ctx_list, sysctl_ctx_e #define SYSCTL_ADD_PROC(ctx, parent, nbr, name, access, ptr, arg, handler, fmt, descr) \ sysctl_add_oid(ctx, parent, nbr, name, (access), \ - ptr, arg, handler, fmt, descr) + ptr, arg, handler, fmt, NULL, descr) +#define OID_LOCK(oidp) if ((oidp)->oid_mtx != NULL) \ + mtx_lock((oidp)->oid_mtx) +#define OID_UNLOCK(oidp) if ((oidp)->oid_mtx != NULL) \ + mtx_unlock((oidp)->oid_mtx) #endif /* _KERNEL */ /* @@ -589,7 +638,7 @@ struct sysctl_oid *sysctl_add_oid(struct struct sysctl_oid_list *parent, int nbr, const char *name, int kind, void *arg1, int arg2, int (*handler) (SYSCTL_HANDLER_ARGS), - const char *fmt, const char *descr); + const char *fmt, struct mtx *mtx, const char *descr); int sysctl_remove_oid(struct sysctl_oid *oidp, int del, int recurse); int sysctl_ctx_init(struct sysctl_ctx_list *clist); int sysctl_ctx_free(struct sysctl_ctx_list *clist);