Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add kernel module auto-loading #7287

Merged
merged 1 commit into from Mar 13, 2018
Merged

Conversation

behlendorf
Copy link
Contributor

Description

Historically a dynamic misc minor number was registered for the
/dev/zfs device in order to prevent minor number collisions. This
was fine but it prevented us from being able to use the kernel
module auto-loaded which requires a known reserved value.

Resolve this issue by adding a configure test to find an available
misc minor number which can then be used in MODULE_ALIAS_MISCDEV at
build time. By adding this alias the zfs kmod is added to the list
of known static-nodes and the systemd-tmpfiles-setup-dev service
will create a /dev/zfs character device at boot time.

This in turn allows us to update the 90-zfs.rules file to make it
aware this is a static node. The upshot of this is that whenever
a process (zpool, zfs, zed) opens the /dev/zfs the kmods will be
automatic loaded. This even works for unprivileged users so there
is no longer a need to manually load the modules at boot time.

As an additional bonus the zed now no longer needs to start after
the zfs-import.service since it will trigger the module load.

In the unlikely event the minor number we selected conflicts with
another out of tree unregistered minor number the code falls back
to dynamically allocating it. In this case the modules again
must be manually loaded.

Motivation and Context

This is a long overdue bit of functionality. This way things will just work.

How Has This Been Tested?

Manually on Fedora 27.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Performance enhancement (non-breaking change which improves efficiency)
  • Code cleanup (non-breaking change which makes code smaller or more readable)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation (a change to man pages or other documentation)

Checklist:

  • My code follows the ZFS on Linux code style requirements.
  • I have updated the documentation accordingly.
  • I have read the CONTRIBUTING document.
  • I have added tests to cover my changes.
  • All new and existing tests passed.
  • All commit messages are properly formatted and contain Signed-off-by.
  • Change has been approved by a ZFS on Linux member.

Copy link
Contributor

@Fabian-Gruenbichler Fabian-Gruenbichler left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

two small nits, LGTM otherwise 👍

AC_MSG_CHECKING([for available /dev/zfs minor])

for i in $(seq 249 -1 200); do
if ! grep -q "#define.*_MINOR.*$i" \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"^#define\s\+.*_MINOR\s\+.*$i" would be a bit more exact and prevent potential future false negatives (they currently match the same device minor numbers).

* In this case the kernel modules must be manually loaded.
*/
zfs_misc.minor = MISC_DYNAMIC_MINOR;
error = misc_register(&zfs_misc);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

keeping the existing printk (moved into a second if after the EBUSY one) and adding a second printk inside the if like this:

printk(KERN_INFO "ZFS: misc_register() with static minor %d failed %d, retrying with MISC_DYNAMIC_MINOR\n", ZFS_MINOR, error);

would make debugging issues here a lot easier I think (although they will probably trigger rarely if at all).

@utopiabound
Copy link
Contributor

So, if I understand the udev rules. udev will load zfs modules if any block devices are part of a zpool. But on initial installation, we still have to worry about loading module prior to zed starting?

@jgrund
Copy link

jgrund commented Mar 9, 2018

Will this load the kernel-module (and start dependent services) when installing ZFS for the first time?

@behlendorf
Copy link
Contributor Author

@Fabian-Gruenbichler thanks for the review and keeping me honest! I've updated the PR and addressed your review feedback.

I also did a little testing of the patch on CentOS 7 and discovered a few small issues which have been subsequently fixed upstream in Fedora.

https://lists.freedesktop.org/archives/systemd-devel/2014-October/024673.html

Anyway the take away is that for CentOS 7 for things to just work after installing the packages (without a reboot) we need to manually restart the kmod-static-nodes and systemd-tmpfiles-setup-dev services, then run udevadm trigger to properly permission the /dev/zfs device. For simplicity I've opted to do this in the %posttrans section and only for CentOS 7. This does mean you'll want to use yum/dnf to install the packages instead of directly calling rpm.

@utopiabound @jgrund it would be great if you could verify this PR does work as intended on your sytstems.

So, if I understand the udev rules. udev will load zfs modules if any block devices are part of a zpool.

Yes. It will proactively load the modules for you, although that really shouldn't been needed anymore with this change.

But on initial installation, we still have to worry about loading module prior to zed starting?

Nope, with this change starting the zed will trigger the module load. Effectively the zed service has been completely decoupled from the import step and it can run at any time. It is still the case that in accordance with the Fdora packaging guidelines the service won't be automatically started as part of the install, only enabled.

$ yum install zfs
$ systemctl start zfs-zed
$ systemctl status zfs-zed
● zfs-zed.service - ZFS Event Daemon (zed)
   Loaded: loaded (/usr/lib/systemd/system/zfs-zed.service; enabled; vendor preset: enabled)
   Active: active (running) since Fri 2018-03-09 20:52:07 UTC; 49s ago
     Docs: man:zed(8)
 Main PID: 1428 (zed)
   CGroup: /system.slice/zfs-zed.service
           └─1428 /sbin/zed -F

Mar 09 20:52:07 ip-172-31-21-231.us-west-1.compute.internal systemd[1]: Started ZFS Event Daemon (zed).
Mar 09 20:52:07 ip-172-31-21-231.us-west-1.compute.internal systemd[1]: Starting ZFS Event Daemon (zed)...
Mar 09 20:52:07 ip-172-31-21-231.us-west-1.compute.internal zed[1428]: ZFS Event Daemon 0.7.0-361_gdba361e (PID 1428)
Mar 09 20:52:08 ip-172-31-21-231.us-west-1.compute.internal zed[1428]: Processing events since eid=0
...

Historically a dynamic misc minor number was registered for the
/dev/zfs device in order to prevent minor number collisions.  This
was fine but it prevented us from being able to use the kernel
module auto-loaded which requires a known reserved value.

Resolve this issue by adding a configure test to find an available
misc minor number which can then be used in MODULE_ALIAS_MISCDEV at
build time.  By adding this alias the zfs kmod is added to the list
of known static-nodes and the systemd-tmpfiles-setup-dev service
will create a /dev/zfs character device at boot time.

This in turn allows us to update the 90-zfs.rules file to make it
aware this is a static node.  The upshot of this is that whenever
a process (zpool, zfs, zed) opens the /dev/zfs the kmods will be
automatic loaded.  This even works for unprivileged users so there
is no longer a need to manually load the modules at boot time.

As an additional bonus the zed now no longer needs to start after
the zfs-import.service since it will trigger the module load.

In the unlikely event the minor number we selected conflicts with
another out of tree unregistered minor number the code falls back
to dynamically allocating it.  In this case the modules again
must be manually loaded.

Note that due to the change in the method of registering the minor
number the zimport.sh test case may incorrectly fail when the
static node for the installed packages is created instead of the
dynamic one.  This issue will only transiently impact zimport.sh
for this single commit when we transition and are mixing and
matching methods.

Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
TEST_ZIMPORT_SKIP="yes"
@codecov
Copy link

codecov bot commented Mar 13, 2018

Codecov Report

Merging #7287 into master will increase coverage by 0.06%.
The diff coverage is 30%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #7287      +/-   ##
==========================================
+ Coverage   76.33%    76.4%   +0.06%     
==========================================
  Files         328      328              
  Lines      104014   104019       +5     
==========================================
+ Hits        79403    79473      +70     
+ Misses      24611    24546      -65
Flag Coverage Δ
#kernel 75.88% <42.85%> (-0.32%) ⬇️
#user 65.75% <0%> (+0.33%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 83362e8...5feb0da. Read the comment docs.

@behlendorf behlendorf merged commit a6cc975 into openzfs:master Mar 13, 2018
@jgrund
Copy link

jgrund commented Mar 14, 2018

@behlendorf What release will this change be part of?

@behlendorf
Copy link
Contributor Author

@jgrund it will be part of the 0.8 release, and is under consideration for inclusion in a future 0.7.x point release.

@jgrund
Copy link

jgrund commented Mar 15, 2018

Thanks

@behlendorf behlendorf deleted the autoload branch March 15, 2018 19:27
@behlendorf
Copy link
Contributor Author

@kpande sorry! That case didn't get covered in the manual testing. I would have expected the updated udev rule to take care of it, but it sounds like that isn't the case. Did you settle on a solution?

@behlendorf behlendorf added this to TODO in 0.7.9 Mar 21, 2018
behlendorf pushed a commit that referenced this pull request Mar 22, 2018
Resolves importing root pool during boot in dracut.  This case was
inadvertently broken with the module autoloading change in #7287.

Reviewed-by: Matthew Thode <prometheanfire@gentoo.org>
Reviewed-by: George Melikov <mail@gmelikov.ru>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Giuseppe Di Natale <dinatale2@llnl.gov>
Signed-off-by: Kash Pande <kash@tripleback.net>
Closes #7322
@Mic92
Copy link
Contributor

Mic92 commented Apr 6, 2018

Also breaks NixOS with linux 4.16. Earlier kernels versions still work.

@Mic92
Copy link
Contributor

Mic92 commented Apr 6, 2018

So manually modprobing zfs is required now?

@behlendorf
Copy link
Contributor Author

@Mic92 it may be needed early in the boot before the normal kernel module autoloading infrastructure is in place.

@behlendorf behlendorf removed this from TODO in 0.7.9 Apr 12, 2018
tonyhutter pushed a commit to tonyhutter/zfs that referenced this pull request Apr 16, 2018
Resolves importing root pool during boot in dracut.  This case was
inadvertently broken with the module autoloading change in openzfs#7287.

Reviewed-by: Matthew Thode <prometheanfire@gentoo.org>
Reviewed-by: George Melikov <mail@gmelikov.ru>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Giuseppe Di Natale <dinatale2@llnl.gov>
Signed-off-by: Kash Pande <kash@tripleback.net>
Closes openzfs#7322
tonyhutter pushed a commit to tonyhutter/zfs that referenced this pull request May 4, 2018
Resolves importing root pool during boot in dracut.  This case was
inadvertently broken with the module autoloading change in openzfs#7287.

Reviewed-by: Matthew Thode <prometheanfire@gentoo.org>
Reviewed-by: George Melikov <mail@gmelikov.ru>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Giuseppe Di Natale <dinatale2@llnl.gov>
Signed-off-by: Kash Pande <kash@tripleback.net>
Closes openzfs#7322
tonyhutter pushed a commit that referenced this pull request May 10, 2018
Resolves importing root pool during boot in dracut.  This case was
inadvertently broken with the module autoloading change in #7287.

Reviewed-by: Matthew Thode <prometheanfire@gentoo.org>
Reviewed-by: George Melikov <mail@gmelikov.ru>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Giuseppe Di Natale <dinatale2@llnl.gov>
Signed-off-by: Kash Pande <kash@tripleback.net>
Closes #7322
@qiaoqiang
Copy link

When no pool has been created at all,and all disks are free to use which have no metadata about zfs_member, manually modprobing zfs is required after reboot. I found this situation in CentOS 7.2.

tonyhutter pushed a commit to tonyhutter/zfs that referenced this pull request Jan 30, 2019
Historically a dynamic misc minor number was registered for the
/dev/zfs device in order to prevent minor number collisions.  This
was fine but it prevented us from being able to use the kernel
module auto-loaded which requires a known reserved value.

Resolve this issue by adding a configure test to find an available
misc minor number which can then be used in MODULE_ALIAS_MISCDEV at
build time.  By adding this alias the zfs kmod is added to the list
of known static-nodes and the systemd-tmpfiles-setup-dev service
will create a /dev/zfs character device at boot time.

This in turn allows us to update the 90-zfs.rules file to make it
aware this is a static node.  The upshot of this is that whenever
a process (zpool, zfs, zed) opens the /dev/zfs the kmods will be
automatic loaded.  This even works for unprivileged users so there
is no longer a need to manually load the modules at boot time.

As an additional bonus the zed now no longer needs to start after
the zfs-import.service since it will trigger the module load.

In the unlikely event the minor number we selected conflicts with
another out of tree unregistered minor number the code falls back
to dynamically allocating it.  In this case the modules again
must be manually loaded.

Note that due to the change in the method of registering the minor
number the zimport.sh test case may incorrectly fail when the
static node for the installed packages is created instead of the
dynamic one.  This issue will only transiently impact zimport.sh
for this single commit when we transition and are mixing and
matching methods.

Reviewed-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
TEST_ZIMPORT_SKIP="yes"
Closes openzfs#7287
tonyhutter pushed a commit that referenced this pull request Mar 4, 2019
Historically a dynamic misc minor number was registered for the
/dev/zfs device in order to prevent minor number collisions.  This
was fine but it prevented us from being able to use the kernel
module auto-loaded which requires a known reserved value.

Resolve this issue by adding a configure test to find an available
misc minor number which can then be used in MODULE_ALIAS_MISCDEV at
build time.  By adding this alias the zfs kmod is added to the list
of known static-nodes and the systemd-tmpfiles-setup-dev service
will create a /dev/zfs character device at boot time.

This in turn allows us to update the 90-zfs.rules file to make it
aware this is a static node.  The upshot of this is that whenever
a process (zpool, zfs, zed) opens the /dev/zfs the kmods will be
automatic loaded.  This even works for unprivileged users so there
is no longer a need to manually load the modules at boot time.

As an additional bonus the zed now no longer needs to start after
the zfs-import.service since it will trigger the module load.

In the unlikely event the minor number we selected conflicts with
another out of tree unregistered minor number the code falls back
to dynamically allocating it.  In this case the modules again
must be manually loaded.

Note that due to the change in the method of registering the minor
number the zimport.sh test case may incorrectly fail when the
static node for the installed packages is created instead of the
dynamic one.  This issue will only transiently impact zimport.sh
for this single commit when we transition and are mixing and
matching methods.

Reviewed-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
TEST_ZIMPORT_SKIP="yes"
Closes #7287
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants