From: Miod Vallat Subject: kernel hook_*establish() simplification To: tech@openbsd.org Date: Sat, 31 Oct 2026 13:07:00 +0000 It's been $MANY years since shutdown hooks have been replaced with per-device ca_activate(DVACT_xxx) calls. As a result: - the second argument of hook_establish() always has the same value (1). - hook_disestablish() is not used anymore. - the second argument of dohooks() always has the same value (HOOK_REMOVE | HOOK_FREE). The following diff: - removes hook_disestablish(). - simplifies hook_establish() and dohooks() by removing the second argument and hardwiring the behaviour given the value this argument used to have. - updates the manual pages accordingly. Index: share/man/man9/dohooks.9 =================================================================== RCS file: /OpenBSD/src/share/man/man9/dohooks.9,v diff -u -p -r1.8 dohooks.9 --- share/man/man9/dohooks.9 12 Dec 2015 11:26:32 -0000 1.8 +++ share/man/man9/dohooks.9 31 Oct 2026 13:06:13 -0000 @@ -30,12 +30,12 @@ .Os .Sh NAME .Nm dohooks -.Nd run all hooks in a list +.Nd run and remove all hooks in a list .Sh SYNOPSIS .In sys/types.h .In sys/systm.h .Ft void -.Fn dohooks "struct hook_desc_head *head" "int flags" +.Fn dohooks "struct hook_desc_head *head" .Sh DESCRIPTION The .Fn dohooks @@ -44,24 +44,8 @@ function invokes all hooks established u function. Hooks are called in the order of the TAILQ that .Fa head -points to, however -.Xr hook_establish 9 -can put the hooks either at the head or the tail of that queue, -making it possible to call the hooks either in the order of -establishment, or its reverse. -.Pp -The flags can specify -.Dv HOOK_REMOVE -to remove already processed hooks from the hook list and -.Dv HOOK_FREE -to also free them. -In most cases either no flags should be used or -.Dv HOOK_REMOVE -and -.Dv HOOK_FREE -at the same time, since just HOOK_REMOVE will drop the only reference to -allocated memory and should only be used in situations where freeing -memory would be illegal and unnecessary. +points to, which is the order of their establishment. +Hooks are then removed from the hook list and freed. .Pp This function is used to implement the .Xr dostartuphooks 9 Index: share/man/man9/hook_establish.9 =================================================================== RCS file: /OpenBSD/src/share/man/man9/hook_establish.9,v diff -u -p -r1.12 hook_establish.9 --- share/man/man9/hook_establish.9 12 Dec 2015 11:26:32 -0000 1.12 +++ share/man/man9/hook_establish.9 31 Oct 2026 13:06:13 -0000 @@ -29,16 +29,13 @@ .Dt HOOK_ESTABLISH 9 .Os .Sh NAME -.Nm hook_establish , -.Nm hook_disestablish -.Nd add or remove a hook from a specified list +.Nm hook_establish +.Nd add a hook to a specified list .Sh SYNOPSIS .In sys/types.h .In sys/systm.h .Ft void * -.Fn hook_establish "struct hook_desc_head *head" "int tail" "void (*fn)(void *)" "void *arg" -.Ft void -.Fn hook_disestablish "struct hook_desc_head *head" "void *cookie" +.Fn hook_establish "struct hook_desc_head *head" "void (*fn)(void *)" "void *arg" .Sh DESCRIPTION The .Fn hook_establish @@ -46,12 +43,8 @@ function adds .Fa fn to the list of hooks invoked by .Xr dohooks 9 . -If -.Fa tail -is non-zero, the hook is added to the tail of the list -denoted by the TAILQ_HEAD pointer -.Fa head , -otherwise to the front. +The hook is added to the tail of the list denoted by the TAILQ_HEAD pointer +.Fa head . The .Xr dohooks 9 function will at its invocation call each hook from the front of this @@ -62,25 +55,12 @@ will be passed .Fa arg as its only argument. .Pp -The -.Fn hook_disestablish -function removes the hook described by the opaque pointer -.Fa cookie -from the list of hooks denoted by the TAILQ_HEAD pointer -.Fa head . -If -.Fa cookie -is invalid, the result of -.Fn hook_disestablish -is undefined. -.Pp The startup and mountroot systems use this API for their implementation. .Sh RETURN VALUES If successful, .Fn hook_establish -returns an opaque pointer describing the newly established -hook. +returns an opaque pointer describing the newly established hook. Otherwise, it returns .Dv NULL . .Sh SEE ALSO Index: share/man/man9/startuphook_establish.9 =================================================================== RCS file: /OpenBSD/src/share/man/man9/startuphook_establish.9,v diff -u -p -r1.8 startuphook_establish.9 --- share/man/man9/startuphook_establish.9 10 Dec 2014 15:29:52 -0000 1.8 +++ share/man/man9/startuphook_establish.9 31 Oct 2026 13:06:13 -0000 @@ -29,16 +29,13 @@ .Dt STARTUPHOOK_ESTABLISH 9 .Os .Sh NAME -.Nm startuphook_establish , -.Nm startuphook_disestablish -.Nd add or remove a startup hook +.Nm startuphook_establish +.Nd add a startup hook .Sh SYNOPSIS .In sys/types.h .In sys/systm.h .Ft void * .Fn startuphook_establish "void (*fn)(void *)" "void *arg" -.Ft void -.Fn startuphook_disestablish "void *cookie" .Sh DESCRIPTION The .Fn startuphook_establish @@ -52,17 +49,6 @@ When invoked, the hook function will be passed .Fa arg as its only argument. -.Pp -The -.Fn startuphook_disestablish -function removes the hook described by the opaque pointer -.Fa cookie -from the list of hooks to be invoked at startup. -If -.Fa cookie -is invalid, the result of -.Fn startuphook_disestablish -is undefined. .Pp Startup hooks should be used to perform one-time activities that must happen immediately before the root and swap devices Index: sys/kern/kern_subr.c =================================================================== RCS file: /OpenBSD/src/sys/kern/kern_subr.c,v diff -u -p -r1.52 kern_subr.c --- sys/kern/kern_subr.c 31 Jan 2023 15:18:56 -0000 1.52 +++ sys/kern/kern_subr.c 31 Oct 2026 13:06:15 -0000 @@ -262,7 +262,7 @@ struct hook_desc_head startuphook_list = TAILQ_HEAD_INITIALIZER(startuphook_list); void * -hook_establish(struct hook_desc_head *head, int tail, void (*fn)(void *), +hook_establish(struct hook_desc_head *head, void (*fn)(void *), void *arg) { struct hook_desc *hdp; @@ -273,53 +273,23 @@ hook_establish(struct hook_desc_head *he hdp->hd_fn = fn; hdp->hd_arg = arg; - if (tail) - TAILQ_INSERT_TAIL(head, hdp, hd_list); - else - TAILQ_INSERT_HEAD(head, hdp, hd_list); + TAILQ_INSERT_TAIL(head, hdp, hd_list); return (hdp); } -void -hook_disestablish(struct hook_desc_head *head, void *vhook) -{ - struct hook_desc *hdp; - -#ifdef DIAGNOSTIC - for (hdp = TAILQ_FIRST(head); hdp != NULL; - hdp = TAILQ_NEXT(hdp, hd_list)) - if (hdp == vhook) - break; - if (hdp == NULL) - return; -#endif - hdp = vhook; - TAILQ_REMOVE(head, hdp, hd_list); - free(hdp, M_DEVBUF, sizeof(*hdp)); -} - /* * Run hooks. Startup hooks are invoked right after scheduler_start but - * before root is mounted. Shutdown hooks are invoked immediately before the - * system is halted or rebooted, i.e. after file systems unmounted, - * after crash dump done, etc. + * before root is mounted. */ void -dohooks(struct hook_desc_head *head, int flags) +dohooks(struct hook_desc_head *head) { - struct hook_desc *hdp, *hdp_temp; + struct hook_desc *hdp; - if ((flags & HOOK_REMOVE) == 0) { - TAILQ_FOREACH_SAFE(hdp, head, hd_list, hdp_temp) { - (*hdp->hd_fn)(hdp->hd_arg); - } - } else { - while ((hdp = TAILQ_FIRST(head)) != NULL) { - TAILQ_REMOVE(head, hdp, hd_list); - (*hdp->hd_fn)(hdp->hd_arg); - if ((flags & HOOK_FREE) != 0) - free(hdp, M_DEVBUF, sizeof(*hdp)); - } + while ((hdp = TAILQ_FIRST(head)) != NULL) { + TAILQ_REMOVE(head, hdp, hd_list); + (*hdp->hd_fn)(hdp->hd_arg); + free(hdp, M_DEVBUF, sizeof(*hdp)); } } Index: sys/sys/systm.h =================================================================== RCS file: /OpenBSD/src/sys/sys/systm.h,v diff -u -p -r1.179 systm.h --- sys/sys/systm.h 22 Apr 2026 01:51:37 -0000 1.179 +++ sys/sys/systm.h 31 Oct 2026 13:06:15 -0000 @@ -310,18 +310,12 @@ TAILQ_HEAD(hook_desc_head, hook_desc); extern struct hook_desc_head startuphook_list; -void *hook_establish(struct hook_desc_head *, int, void (*)(void *), void *); -void hook_disestablish(struct hook_desc_head *, void *); -void dohooks(struct hook_desc_head *, int); - -#define HOOK_REMOVE 0x01 -#define HOOK_FREE 0x02 +void *hook_establish(struct hook_desc_head *, void (*)(void *), void *); +void dohooks(struct hook_desc_head *); #define startuphook_establish(fn, arg) \ - hook_establish(&startuphook_list, 1, (fn), (arg)) -#define startuphook_disestablish(vhook) \ - hook_disestablish(&startuphook_list, (vhook)) -#define dostartuphooks() dohooks(&startuphook_list, HOOK_REMOVE|HOOK_FREE) + hook_establish(&startuphook_list, (fn), (arg)) +#define dostartuphooks() dohooks(&startuphook_list) struct uio; int uiomove(void *, size_t, struct uio *);