aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--config/kernel-misc-minor.m426
-rw-r--r--config/kernel.m41
-rw-r--r--etc/modules-load.d/zfs.conf.in4
-rw-r--r--etc/systemd/system/zfs-import-cache.service.in1
-rw-r--r--etc/systemd/system/zfs-import-scan.service.in1
-rw-r--r--etc/systemd/system/zfs-zed.service.in1
-rw-r--r--lib/libzfs/libzfs_util.c13
-rw-r--r--module/zfs/zfs_ioctl.c25
-rw-r--r--rpm/generic/zfs.spec.in9
-rw-r--r--udev/rules.d/90-zfs.rules.in2
10 files changed, 66 insertions, 17 deletions
diff --git a/config/kernel-misc-minor.m4 b/config/kernel-misc-minor.m4
new file mode 100644
index 000000000..3917e28ff
--- /dev/null
+++ b/config/kernel-misc-minor.m4
@@ -0,0 +1,26 @@
+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.])
+ ])
+])
diff --git a/config/kernel.m4 b/config/kernel.m4
index b80e57b1c..1887b178c 100644
--- a/config/kernel.m4
+++ b/config/kernel.m4
@@ -6,6 +6,7 @@ AC_DEFUN([ZFS_AC_CONFIG_KERNEL], [
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
diff --git a/etc/modules-load.d/zfs.conf.in b/etc/modules-load.d/zfs.conf.in
index 8b41baa30..44e1bb3ed 100644
--- a/etc/modules-load.d/zfs.conf.in
+++ b/etc/modules-load.d/zfs.conf.in
@@ -1,3 +1,3 @@
-# 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
diff --git a/etc/systemd/system/zfs-import-cache.service.in b/etc/systemd/system/zfs-import-cache.service.in
index 23c725d71..44c26802b 100644
--- a/etc/systemd/system/zfs-import-cache.service.in
+++ b/etc/systemd/system/zfs-import-cache.service.in
@@ -12,7 +12,6 @@ ConditionPathExists=@sysconfdir@/zfs/zpool.cache
[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}')"
diff --git a/etc/systemd/system/zfs-import-scan.service.in b/etc/systemd/system/zfs-import-scan.service.in
index 851d96cbc..44a50a76b 100644
--- a/etc/systemd/system/zfs-import-scan.service.in
+++ b/etc/systemd/system/zfs-import-scan.service.in
@@ -11,7 +11,6 @@ ConditionPathExists=!@sysconfdir@/zfs/zpool.cache
[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}')"
diff --git a/etc/systemd/system/zfs-zed.service.in b/etc/systemd/system/zfs-zed.service.in
index 317515003..f4313625e 100644
--- a/etc/systemd/system/zfs-zed.service.in
+++ b/etc/systemd/system/zfs-zed.service.in
@@ -1,7 +1,6 @@
[Unit]
Description=ZFS Event Daemon (zed)
Documentation=man:zed(8)
-After=zfs-import.target
[Service]
ExecStart=@sbindir@/zed -F
diff --git a/lib/libzfs/libzfs_util.c b/lib/libzfs/libzfs_util.c
index ee8d09b11..6b9cfc272 100644
--- a/lib/libzfs/libzfs_util.c
+++ b/lib/libzfs/libzfs_util.c
@@ -965,13 +965,14 @@ libzfs_load_module(const char *module)
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
diff --git a/module/zfs/zfs_ioctl.c b/module/zfs/zfs_ioctl.c
index 994b3af36..92bdec4b9 100644
--- a/module/zfs/zfs_ioctl.c
+++ b/module/zfs/zfs_ioctl.c
@@ -6947,11 +6947,14 @@ static const struct file_operations zfsdev_fops = {
};
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)
{
@@ -6962,12 +6965,24 @@ 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
diff --git a/rpm/generic/zfs.spec.in b/rpm/generic/zfs.spec.in
index 27a2424df..52dc80a4e 100644
--- a/rpm/generic/zfs.spec.in
+++ b/rpm/generic/zfs.spec.in
@@ -284,6 +284,15 @@ fi
%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}
diff --git a/udev/rules.d/90-zfs.rules.in b/udev/rules.d/90-zfs.rules.in
index 855c15404..82f8cf1cf 100644
--- a/udev/rules.d/90-zfs.rules.in
+++ b/udev/rules.d/90-zfs.rules.in
@@ -7,6 +7,6 @@ ENV{ID_FS_TYPE}=="zfs_member", RUN+="/sbin/modprobe zfs"
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"