kern_reboot(9): describe event handlers
Add more details about the execution and purpose of these shutdown handlers. Make a point to mention the requirement that they can be run in a normal or panic context. Add some simple examples. Add a brief comment to the declaration in sys/eventhandler.h. Reviewed by: markj Discussed with: rpokala, Pau Amma <pauamma@gundo.com> MFC after: 1 week Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D39135
This commit is contained in:
parent
b7caa912f9
commit
f6f8cbda8e
@ -128,6 +128,9 @@ Print a message indicating that the system is about to be halted
|
|||||||
or rebooted, and a report of the total system uptime.
|
or rebooted, and a report of the total system uptime.
|
||||||
.It
|
.It
|
||||||
Execute all registered shutdown hooks.
|
Execute all registered shutdown hooks.
|
||||||
|
See
|
||||||
|
.Sx SHUTDOWN HOOKS
|
||||||
|
below.
|
||||||
.It
|
.It
|
||||||
As a last resort, if none of the shutdown hooks handled the reboot, call the
|
As a last resort, if none of the shutdown hooks handled the reboot, call the
|
||||||
machine-dependent
|
machine-dependent
|
||||||
@ -172,6 +175,58 @@ is called before the
|
|||||||
process has been spawned, or if the system has panicked or otherwise halted,
|
process has been spawned, or if the system has panicked or otherwise halted,
|
||||||
.Fn kern_reboot
|
.Fn kern_reboot
|
||||||
will be called directly.
|
will be called directly.
|
||||||
|
.Sh SHUTDOWN HOOKS
|
||||||
|
The system defines three separate
|
||||||
|
.Xr EVENTHANDLER 9
|
||||||
|
events, which are invoked successively during the shutdown procedure.
|
||||||
|
These are
|
||||||
|
.Va shutdown_pre_sync ,
|
||||||
|
.Va shutdown_post_sync ,
|
||||||
|
and
|
||||||
|
.Va shutdown_final .
|
||||||
|
They will be executed unconditionally in the listed order.
|
||||||
|
Handler functions registered to any of these events will receive the value of
|
||||||
|
.Fa howto
|
||||||
|
as their second argument, which may be used to decide what action to take.
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Va shutdown_pre_sync
|
||||||
|
event is invoked before syncing filesystems to disk.
|
||||||
|
It enables any action or state transition that must happen before this point to
|
||||||
|
take place.
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Va shutdown_post_sync
|
||||||
|
event is invoked at the point immediately after the filesystem sync has
|
||||||
|
finished.
|
||||||
|
It enables, for example, disk drivers to complete the sync by flushing their
|
||||||
|
cache to disk.
|
||||||
|
Note that this event still takes place before the optional kernel core dump.
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Va shutdown_final
|
||||||
|
event is invoked as the very last step of
|
||||||
|
.Fn kern_reboot .
|
||||||
|
Drivers and subsystems such as
|
||||||
|
.Xr acpi 4
|
||||||
|
can register handlers to this event that will perform the actual reboot,
|
||||||
|
power-off, or halt.
|
||||||
|
.Pp
|
||||||
|
Notably, the
|
||||||
|
.Va shutdown_final
|
||||||
|
event is also the point at which all kernel modules will have their shutdown
|
||||||
|
.Po
|
||||||
|
.Dv MOD_SHUTDOWN
|
||||||
|
.Pc
|
||||||
|
hooks executed, and when the
|
||||||
|
.Xr DEVICE_SHUTDOWN 9
|
||||||
|
method will be executed recursively on all devices.
|
||||||
|
.Pp
|
||||||
|
All event handlers, like
|
||||||
|
.Fn kern_reboot
|
||||||
|
itself, may be run in either normal shutdown context or a kernel panic or
|
||||||
|
debugger context.
|
||||||
|
Handler functions are expected to take care not to trigger recursive panics.
|
||||||
.Sh RETURN VALUES
|
.Sh RETURN VALUES
|
||||||
The
|
The
|
||||||
.Fn kern_reboot
|
.Fn kern_reboot
|
||||||
@ -183,9 +238,65 @@ function will usually return to its caller, having initiated the asynchronous
|
|||||||
system shutdown.
|
system shutdown.
|
||||||
It will not return when called from a panic or debugger context, or during
|
It will not return when called from a panic or debugger context, or during
|
||||||
early boot.
|
early boot.
|
||||||
|
.Sh EXAMPLES
|
||||||
|
A hypothetical driver, foo(4), defines a
|
||||||
|
.Va shutdown_final
|
||||||
|
event handler that can handle system power-off by writing to a device register,
|
||||||
|
but it does not handle halt or reset.
|
||||||
|
.Bd -literal -offset indent
|
||||||
|
void
|
||||||
|
foo_poweroff_handler(struct void *arg, int howto)
|
||||||
|
{
|
||||||
|
struct foo_softc *sc = arg;
|
||||||
|
uint32_t reg;
|
||||||
|
|
||||||
|
if ((howto & RB_POWEROFF) != 0) {
|
||||||
|
reg = FOO_POWEROFF;
|
||||||
|
WRITE4(sc, FOO_POWEROFF_REG, reg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.Ed
|
||||||
|
.Pp
|
||||||
|
The handler is then registered in the device attach routine:
|
||||||
|
.Bd -literal -offset indent
|
||||||
|
int
|
||||||
|
foo_attach(device_t dev)
|
||||||
|
{
|
||||||
|
struct foo_softc *sc;
|
||||||
|
|
||||||
|
...
|
||||||
|
|
||||||
|
/* Pass the device's software context as the private arg. */
|
||||||
|
EVENTHANDLER_REGISTER(shutdown_final, foo_poweroff_handler, sc,
|
||||||
|
SHUTDOWN_PRI_DEFAULT);
|
||||||
|
|
||||||
|
...
|
||||||
|
}
|
||||||
|
.Ed
|
||||||
|
.Pp
|
||||||
|
This
|
||||||
|
.Va shutdown_final
|
||||||
|
handler uses the
|
||||||
|
.Dv RB_NOSYNC
|
||||||
|
flag to detect that a panic or other unusual condition has occurred, and
|
||||||
|
returns early:
|
||||||
|
.Bd -literal -offset indent
|
||||||
|
void
|
||||||
|
bar_shutdown_final(struct void *arg, int howto)
|
||||||
|
{
|
||||||
|
|
||||||
|
if ((howto & RB_NOSYNC) != 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Some code that is not panic-safe. */
|
||||||
|
...
|
||||||
|
}
|
||||||
|
.Ed
|
||||||
.Sh SEE ALSO
|
.Sh SEE ALSO
|
||||||
.Xr reboot 2 ,
|
.Xr reboot 2 ,
|
||||||
.Xr init 8 ,
|
.Xr init 8 ,
|
||||||
|
.Xr DEVICE_SHUTDOWN 9 ,
|
||||||
.Xr EVENTHANDLER 9 ,
|
.Xr EVENTHANDLER 9 ,
|
||||||
|
.Xr module 9 ,
|
||||||
.Xr panic 9 ,
|
.Xr panic 9 ,
|
||||||
.Xr vfs_unmountall 9
|
.Xr vfs_unmountall 9
|
||||||
|
@ -184,7 +184,14 @@ eventhandler_tag vimage_eventhandler_register(struct eventhandler_list *list,
|
|||||||
#define EVENTHANDLER_PRI_ANY 10000
|
#define EVENTHANDLER_PRI_ANY 10000
|
||||||
#define EVENTHANDLER_PRI_LAST 20000
|
#define EVENTHANDLER_PRI_LAST 20000
|
||||||
|
|
||||||
/* Shutdown events */
|
/*
|
||||||
|
* Successive shutdown events invoked by kern_reboot(9).
|
||||||
|
*
|
||||||
|
* Handlers will receive the 'howto' value as their second argument.
|
||||||
|
*
|
||||||
|
* All handlers must be prepared to be executed from a panic/debugger context;
|
||||||
|
* see the man page for details.
|
||||||
|
*/
|
||||||
typedef void (*shutdown_fn)(void *, int);
|
typedef void (*shutdown_fn)(void *, int);
|
||||||
|
|
||||||
#define SHUTDOWN_PRI_FIRST EVENTHANDLER_PRI_FIRST
|
#define SHUTDOWN_PRI_FIRST EVENTHANDLER_PRI_FIRST
|
||||||
|
Loading…
Reference in New Issue
Block a user