zfs module: perform cleanup during shutdown in addition to module unload

- move init and fini code into separate functions (like it is done upstream)
- invoke fini code via shutdown_post_sync event hook

This should make zfs close its underlying devices during shutdown,
which may be important for their drivers.

MFC after:	20 days
This commit is contained in:
Andriy Gapon 2013-07-24 09:59:16 +00:00
parent 3ab5cdbc13
commit f66c1f6482

View File

@ -6187,13 +6187,16 @@ _info(struct modinfo *modinfop)
}
#endif /* sun */
static int
zfs_modevent(module_t mod, int type, void *unused __unused)
{
int error = 0;
static int zfs__init(void);
static int zfs__fini(void);
static void zfs_shutdown(void *, int);
static eventhandler_tag zfs_shutdown_event_tag;
int
zfs__init(void)
{
switch (type) {
case MOD_LOAD:
zfs_root_token = root_mount_hold("ZFS");
mutex_init(&zfs_share_lock, NULL, MUTEX_DEFAULT, NULL);
@ -6211,12 +6214,16 @@ zfs_modevent(module_t mod, int type, void *unused __unused)
root_mount_rel(zfs_root_token);
zfsdev_init();
break;
case MOD_UNLOAD:
return (0);
}
int
zfs__fini(void)
{
if (spa_busy() || zfs_busy() || zvol_busy() ||
zio_injection_enabled) {
error = EBUSY;
break;
return (EBUSY);
}
zfsdev_fini();
@ -6229,12 +6236,47 @@ zfs_modevent(module_t mod, int type, void *unused __unused)
tsd_destroy(&zfs_allow_log_key);
mutex_destroy(&zfs_share_lock);
break;
return (0);
}
static void
zfs_shutdown(void *arg __unused, int howto __unused)
{
/*
* ZFS fini routines can not properly work in a panic-ed system.
*/
if (panicstr == NULL)
(void)zfs__fini();
}
static int
zfs_modevent(module_t mod, int type, void *unused __unused)
{
int err;
switch (type) {
case MOD_LOAD:
err = zfs__init();
if (err == 0)
zfs_shutdown_event_tag = EVENTHANDLER_REGISTER(
shutdown_post_sync, zfs_shutdown, NULL,
SHUTDOWN_PRI_FIRST);
return (err);
case MOD_UNLOAD:
err = zfs__fini();
if (err == 0 && zfs_shutdown_event_tag != NULL)
EVENTHANDLER_DEREGISTER(shutdown_post_sync,
zfs_shutdown_event_tag);
return (err);
case MOD_SHUTDOWN:
return (0);
default:
error = EOPNOTSUPP;
break;
}
return (error);
return (EOPNOTSUPP);
}
static moduledata_t zfs_mod = {