Moving modprobe.d files to (/usr)/lib
Historically, modprobe configuration files have been installed in /etc/modprobe.d on openSUSE. This has a number of disadvantages. - packages should generally avoid shipping files under /etc - customization requires %config or %config(noreplace), with the well-known issues this may cause on upgrades. The more "modern" style to enable user customization is to place distribution-shipped configuration files under /lib/modprobe.d or /usr/lib/modprobe.d, and let users override them by files of the same name under /etc/modprobe.d if they desire. This technique has been supported by kmod for years, and is well established these days by systemd, udev, dracut, etc., which use the same scheme. I've started an effort to move all modprobe configuration files shipped by packages into /usr/lib/modprobe.d on Factory, and /lib/modprobe.d on Leap. The %config or %config(noreplace) file attributes for the distribution-shipped defaults are removed. If the user has modified some of the distro-shipped %config files, they'll be renamed to .rpmsave by rpm when the update package moves the config file out of /etc. This would undo user customizations, which is undesirable. To avoid it, code is added to the spec files of affected packages, which looks like this (example from "bluez"): %global modprobe_d_files 50-bluetooth.conf %pre # Avoid restoring pre-existing .rpmsave files in %posttrans later by renaming them for _f in %{?modprobe_d_files}; do [ ! -f "%{_sysconfdir}/modprobe.d/${_f}.rpmsave" ] || \ mv -f "%{_sysconfdir}/modprobe.d/${_f}.rpmsave" "%{_sysconfdir}/modprobe.d/${_f}.rpmsave.%{name}-%{VERSION}-%{RELEASE}" || : done %posttrans # Modified config files are renamed to .rpmsave by rpm when moved to /usr/lib. # Restore the user's customizations. for _f in %{?modprobe_d_files}; do [ ! -f "%{_sysconfdir}/modprobe.d/${_f}.rpmsave" ] || \ mv -fv "%{_sysconfdir}/modprobe.d/${_f}.rpmsave" "%{_sysconfdir}/modprobe.d/${_f}" || : done The current status can be seen on OBS in the home:mwilck:modprobe.d project (currently WIP). There has been some confusion about the correct path (/usr/lib/modprobe.d vs. /lib/modprobe.d). Here's a short summary of the discussion: - upstream kmod does supports /lib/modprobe.d only. - SUSE's kmod is currently patched to support both /lib/modprobe.d and /usr/lib/modprobe.d. - On usr-merged Factory, /lib/modprobe.d is an alias for /usr/lib/modprobe.d, thus they can be used interchangeably. For correctness and to avoid filename clashes, we use /usr/lib. - on non-usr-merged distros, we keep the upstream path /lib/modprobe.d. Scripts and "consumers" of modprobe.d files can safely look them up under /lib/modprobe.d, which will "work" on both usr-merged and non- usr-merged variants. In the future, %_modprobedir should be used by packages. Currently though, %_modprobedir is (wrongly) set to /usr/lib/modprobe.d in the systemd-rpm-macros package on SLE/Leap up to 15.3. Likewise, the filesystem package on Leap currently contains /usr/lib/modprobe.d but not /lib/modprobe.d. This will be fixed sooner or later, but spec files currently need to work around this issue with a conditional. packages that install into %_modprobedir should add a "%dir %{_modprobedir}" line to the %files list to avoid build errors. Furthermore, discussion is ongoing whether the definition of %_modprobedir should be moved to a different package, and which. Regards Martin PS: @maintainers of affected packages: I've sent a bunch of OBS requests on Friday and revoked them, because I hadn't added the code for restoring user modifications yet and I figured I should rather do that first.
On Sunday 2022-03-06 22:55, Martin Wilck wrote:
Furthermore, discussion is ongoing whether the definition of %_modprobedir should be moved to a different package, and which.
if upstream does not provide the macro, /usr/lib/rpm/suse/macros looks like a workable dumping ground.
On Sun, Mar 6, 2022 at 6:03 PM Jan Engelhardt
On Sunday 2022-03-06 22:55, Martin Wilck wrote:
Furthermore, discussion is ongoing whether the definition of %_modprobedir should be moved to a different package, and which.
if upstream does not provide the macro, /usr/lib/rpm/suse/macros looks like a workable dumping ground.
%_modprobedir is already part of systemd upstream macros. The openSUSE systemd package currently maintains an old custom fork of the macros in the systemd-rpm-macros package. I hope that one day we can just use the upstream ones... -- 真実はいつも一つ!/ Always, there's only one truth!
On 3/6/22 22:55, Martin Wilck wrote: [..]
%global modprobe_d_files 50-bluetooth.conf
%pre # Avoid restoring pre-existing .rpmsave files in %posttrans later by renaming them for _f in %{?modprobe_d_files}; do [ ! -f "%{_sysconfdir}/modprobe.d/${_f}.rpmsave" ] || \ mv -f "%{_sysconfdir}/modprobe.d/${_f}.rpmsave" "%{_sysconfdir}/modprobe.d/${_f}.rpmsave.%{name}-%{VERSION}-%{RELEASE}" || : done
%posttrans # Modified config files are renamed to .rpmsave by rpm when moved to /usr/lib. # Restore the user's customizations. for _f in %{?modprobe_d_files}; do [ ! -f "%{_sysconfdir}/modprobe.d/${_f}.rpmsave" ] || \ mv -fv "%{_sysconfdir}/modprobe.d/${_f}.rpmsave" "%{_sysconfdir}/modprobe.d/${_f}" || : done
It might be nice to have a freely available function that does this. This is probably not the last we'll have to migrate config files from one directory to another, and having a sane/tested function that takes org,dest,files as arguments would be helpful then! Nicolas
On Wed, 2022-03-09 at 13:56 +0100, Nicolas Morey-Chaisemartin wrote:
On 3/6/22 22:55, Martin Wilck wrote: [..]
%global modprobe_d_files 50-bluetooth.conf
%pre # Avoid restoring pre-existing .rpmsave files in %posttrans later by renaming them for _f in %{?modprobe_d_files}; do [ ! -f "%{_sysconfdir}/modprobe.d/${_f}.rpmsave" ] || \ mv -f "%{_sysconfdir}/modprobe.d/${_f}.rpmsave" "%{_sysconfdir}/modprobe.d/${_f}.rpmsave.%{name}-%{VERSION}- %{RELEASE}" || : done
%posttrans # Modified config files are renamed to .rpmsave by rpm when moved to /usr/lib. # Restore the user's customizations. for _f in %{?modprobe_d_files}; do [ ! -f "%{_sysconfdir}/modprobe.d/${_f}.rpmsave" ] || \ mv -fv "%{_sysconfdir}/modprobe.d/${_f}.rpmsave" "%{_sysconfdir}/modprobe.d/${_f}" || : done
It might be nice to have a freely available function that does this. This is probably not the last we'll have to migrate config files from one directory to another, and having a sane/tested function that takes org,dest,files as arguments would be helpful then!
Thanks for the suggestion. There are two options to do this: 1) provide rpm macros in some package X 2) create scripts shipped by some package Y 1) would require that X is a package that's always present when a package using the macro is installed; otherwise the macro can't be safely used. We don't want to introduce new hard dependencies for this purpose, thus it must be a package that is already directly or indrectly required by all affected packages. There are only very few packages for which this holds. rpm-config-SUSE would probably be the prime candidate, but I'm unsure if the maintainer would be happy to take these scripts. Even if this was decided upon, we'd still need to add dependencies to all affected spec files to make sure the macros are actually available. For 2), scripts would also need to be shipped in "basic" packages, leading to the same set of problems. Either that, or (e.g. if I shipped them in suse-module-tools) every spec file would need to test for the existence of the script first, like this: [ ! -x /usr/lib/module-init-tools/reinstate-config ] || \ /usr/lib/module-init-tools/reinstate-config %{?modprobe_d_files} This must be done both in %pre and %posttrans. I pondered this, and came to the conclusion that it's not a big win over including the code explicitly. The code is simple enough to be verified quickly, and by including it verbatim it's immediately obvious to the reader of the spec file what it does. I experimented with both options, and figured that integrating new generic functionality just for the dozen-or-so packages shipping files in /etc/modprobe.d was unnecessary and over-complicated. As you said, the cost-benefit assessment might look different if there was more stuff like this to handle, but it seems that the bulk of /usr/etc migration [1] has been completed already without generic helper functions. Martin [1] https://en.opensuse.org/openSUSE:Packaging_UsrEtc
participants (4)
-
Jan Engelhardt
-
Martin Wilck
-
Neal Gompa
-
Nicolas Morey-Chaisemartin