--- /dev/null
+dnl #
+dnl # Determine an available miscellaneous minor number which can be used
+dnl # for the /dev/zfs device. This is needed because kernel module
+dnl # auto-loading depends on registering a reserved non-conflicting minor
+dnl # number. Start with a large known available unreserved minor and work
+dnl # our way down to lower value if a collision is detected.
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_MISC_MINOR], [
+ AC_MSG_CHECKING([for available /dev/zfs minor])
+
+ for i in $(seq 249 -1 200); do
+ if ! grep -q "^#define\s\+.*_MINOR\s\+.*$i" \
+ ${LINUX}/include/linux/miscdevice.h; then
+ ZFS_MINOR="$i"
+ AC_MSG_RESULT($ZFS_MINOR)
+ AC_DEFINE_UNQUOTED([ZFS_MINOR], [$ZFS_MINOR],
+ [/dev/zfs minor])
+ break
+ fi
+ done
+
+ AS_IF([ test -z "$ZFS_MINOR"], [
+ AC_MSG_ERROR([
+ *** No available misc minor numbers available for use.])
+ ])
+])
ZFS_AC_SPL
ZFS_AC_QAT
ZFS_AC_TEST_MODULE
+ ZFS_AC_KERNEL_MISC_MINOR
ZFS_AC_KERNEL_OBJTOOL
ZFS_AC_KERNEL_CONFIG
ZFS_AC_KERNEL_DECLARE_EVENT_CLASS
-# Always load kernel modules at boot. The default behavior is to load the
-# kernel modules in the zfs-import-*.service or when blkid(8) detects a pool.
+# The default behavior is to allow udev to load the kernel modules on demand.
+# Uncomment the following line to unconditionally load them at boot.
#zfs
[Service]
Type=oneshot
RemainAfterExit=yes
-ExecStartPre=-/sbin/modprobe zfs
ExecStart=@sbindir@/zpool import -c @sysconfdir@/zfs/zpool.cache -aN
ExecStartPost=/bin/bash -c "/bin/systemctl set-environment BOOTFS=$(@sbindir@/zpool list -H -o bootfs | /bin/awk '$1 != \"-\" {print; exit}')"
[Service]
Type=oneshot
RemainAfterExit=yes
-ExecStartPre=-/sbin/modprobe zfs
ExecStart=@sbindir@/zpool import -aN -o cachefile=none
ExecStartPost=/bin/bash -c "/bin/systemctl set-environment BOOTFS=$(@sbindir@/zpool list -H -o bootfs | /bin/awk '$1 != \"-\" {print; exit}')"
[Unit]
Description=ZFS Event Daemon (zed)
Documentation=man:zed(8)
-After=zfs-import.target
[Service]
ExecStart=@sbindir@/zed -F
load = 0;
}
- if (load && libzfs_run_process("/sbin/modprobe", argv, 0))
- return (ENOEXEC);
- }
+ if (load) {
+ if (libzfs_run_process("/sbin/modprobe", argv, 0))
+ return (ENOEXEC);
- /* Module loading is synchronous it must be available */
- if (!libzfs_module_loaded(module))
- return (ENXIO);
+ if (!libzfs_module_loaded(module))
+ return (ENXIO);
+ }
+ }
/*
* Device creation by udev is asynchronous and waiting may be
};
static struct miscdevice zfs_misc = {
- .minor = MISC_DYNAMIC_MINOR,
+ .minor = ZFS_MINOR,
.name = ZFS_DRIVER,
.fops = &zfsdev_fops,
};
+MODULE_ALIAS_MISCDEV(ZFS_MINOR);
+MODULE_ALIAS("devname:zfs");
+
static int
zfs_attach(void)
{
zfsdev_state_list->zs_minor = -1;
error = misc_register(&zfs_misc);
- if (error != 0) {
- printk(KERN_INFO "ZFS: misc_register() failed %d\n", error);
- return (error);
+ if (error == -EBUSY) {
+ /*
+ * Fallback to dynamic minor allocation in the event of a
+ * collision with a reserved minor in linux/miscdevice.h.
+ * In this case the kernel modules must be manually loaded.
+ */
+ printk(KERN_INFO "ZFS: misc_register() with static minor %d "
+ "failed %d, retrying with MISC_DYNAMIC_MINOR\n",
+ ZFS_MINOR, error);
+
+ zfs_misc.minor = MISC_DYNAMIC_MINOR;
+ error = misc_register(&zfs_misc);
}
- return (0);
+ if (error)
+ printk(KERN_INFO "ZFS: misc_register() failed %d\n", error);
+
+ return (error);
}
static void
%endif
exit 0
+# On RHEL/CentOS 7 the static nodes aren't refreshed by default after
+# installing a package. This is the default behavior for Fedora.
+%posttrans
+%if 0%{?rhel} == 7 || 0%{?centos} == 7
+systemctl restart kmod-static-nodes
+systemctl restart systemd-tmpfiles-setup-dev
+udevadm trigger
+%endif
+
%preun
%if 0%{?_systemd}
%if 0%{?systemd_preun:1}
KERNEL=="null", SYMLINK+="root"
SYMLINK=="null", SYMLINK+="root"
-SUBSYSTEM=="misc", KERNEL=="zfs", MODE="0666"
+KERNEL=="zfs", MODE="0666", OPTIONS+="static_node=zfs"
LABEL="zfs_end"