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.
|
||||
.It
|
||||
Execute all registered shutdown hooks.
|
||||
See
|
||||
.Sx SHUTDOWN HOOKS
|
||||
below.
|
||||
.It
|
||||
As a last resort, if none of the shutdown hooks handled the reboot, call the
|
||||
machine-dependent
|
||||
@ -172,6 +175,58 @@ is called before the
|
||||
process has been spawned, or if the system has panicked or otherwise halted,
|
||||
.Fn kern_reboot
|
||||
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
|
||||
The
|
||||
.Fn kern_reboot
|
||||
@ -183,9 +238,65 @@ function will usually return to its caller, having initiated the asynchronous
|
||||
system shutdown.
|
||||
It will not return when called from a panic or debugger context, or during
|
||||
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
|
||||
.Xr reboot 2 ,
|
||||
.Xr init 8 ,
|
||||
.Xr DEVICE_SHUTDOWN 9 ,
|
||||
.Xr EVENTHANDLER 9 ,
|
||||
.Xr module 9 ,
|
||||
.Xr panic 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_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);
|
||||
|
||||
#define SHUTDOWN_PRI_FIRST EVENTHANDLER_PRI_FIRST
|
||||
|
Loading…
Reference in New Issue
Block a user