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

DKMS module removed completely when last kernel removed #37

Closed
ian-abbott opened this issue Nov 8, 2017 · 10 comments
Closed

DKMS module removed completely when last kernel removed #37

ian-abbott opened this issue Nov 8, 2017 · 10 comments

Comments

@ian-abbott
Copy link
Contributor

I'm not sure if this is a bug. If a DKMS module/module-version has been added, built and installed for a single kernel/arch, and is then removed for that kernel/arch it is removed completely and cannot be built and installed for another kernel/arch until it is added again manually.

The relevant part of the dkms script is:

    # Delete the $module_version part of the tree if no other $module_version/$kernel_version dirs exist
    if ! find $dkms_tree/$module/$module_version/* -maxdepth 0 -type d 2>/dev/null | egrep -qv "(build|tarball|driver_disk|rpm|deb|source)$"; then
        echo $""
        echo $"------------------------------"
        echo $"Deleting module version: $module_version"
        echo $"completely from the DKMS tree."
        echo $"------------------------------"
        rm -rf "$dkms_tree/$module/$module_version"
        echo $"Done."
    fi

This looks as if the module/version should not be removed completely if $dkms_tree/$module/$module_version/source is a directory. It is usually a symbolic link, and the above find command will not find it in that case. Perhaps the above find command should use the -H or -L option so that it finds the source symlink. Or perhaps the module version should not be removed completely unless the --all option is given.

@GoPerry
Copy link
Contributor

GoPerry commented Nov 14, 2017

@ian-abbott
When you remove the dkms module with dkms remove -m xxx -v xxx,then if you want to build and install again. firstly you need to run dkms add command.

@ian-abbott
Copy link
Contributor Author

@yuzaipiaofei
The trouble I'm having is that the remove command does two different things. It acts like an "uninstall&unbuild" step, and then, if no more kernels are using it, it forgets the module/version entirely. I'm looking for some mechanism that skips the "forget the module/version entirely" part.

On Debian, if you reinstall a kernel package, it first removes the DKMS modules for the kernel, which may result in DKMS forgetting the module/version entirely. Then after the kernel is reinstalled and DKMS is triggered to rebuild the modules, the module/version is no longer present. This requires manual use of the dkms commands afterwards to re-add and reinstall the desired modules.

@GoPerry
Copy link
Contributor

GoPerry commented Nov 30, 2017

@ian-abbott
So your issue is failed to rebuild and reinstall the modules when you were updating your kernel image?
0c19129#diff-aad3509f2a95a1bef3d5a4dcd105e1fd

How do you remove your kernel image?

then which dkms version you are using ?

@ian-abbott
Copy link
Contributor Author

@yuzaipiaofei
I'm using the dkms 2.3-2 package from Debian "Stretch". I'm running it on an embedded ARM system with custom-built linux-image and linux-headers .deb packages installed with dkpg -i. The problem occurs when the linux-image package for the same kernel version (but possibly a different deb package revision) is reinstalled with dpkg -i. In that case, the /etc/kernel/prerm.d/dkms script from Debian's dkms package (not part of the upstream dkms sources) gets run, which removes all dkms modules for the kernel being reinstalled. SInce I only have one kernel version installed, the dkms remove command removes the module/version completely.

I think I have a clue what is going wrong. The custom linux-image debian package includes a "prerm" script that gets run by the dpkg command during upgrade/reinstallation or removal, and it is this script that runs the /etc/kernel/prerm.d/* scripts, including /etc/kernel/prerm.d/dkms. The first parameter of the package's "prerm" script is the operation type, e.g. "upgrade" or "remove". The "prerm" script in my custom-built linux-image package is running the /etc/kernel/prerm.d/* scripts regardless of the operation type, whereas the standard, shipped, Debian linux-image packages only run those scripts when the operation type is "remove". So I could fix it by replacing the "prerm" script in my custom linux-image package somehow. (The "prerm" script I am using is actually output by scripts/package/builddeb in the Linux kernel sources, run as part of the "deb-pkg" target of the Linux kernel Makefile, so it's not that bizarre!)

Still, it would be nice if the dkms remove command had an option (suggested name: --keep) to not undo the dkms add when the final kernel/arch is removed for the module/version.

@vmspike
Copy link

vmspike commented Mar 25, 2018

I have the same issue on upgrade between recent official Raspbian kernels.
/etc/kernel/prerm.d/dkms call (with dkms remove ... inside) completely remove all modules from dkms tree on kernel upgrade because it calls when new kernel headers are unavailable yet.

As a workaround for specific module some additional directory can be created in $dkms_tree/$module/$module_version/, for example /var/lib/dkms/mymodule/0.1/workaround_full_dkms_remove. This way we deceive this dkms check: if ! find $dkms_tree/$module/$module_version/* -maxdepth 0 -type d 2>/dev/null | egrep -qv "(build|tarball|driver_disk|rpm|deb|source)$"; then .

@ian-abbott
Copy link
Contributor Author

So the main problem seems to be that Debian's dkms is based on dkms 2.3, and doesn't have the changes from commit 0c19129 that made it into dkms 2.4. That changed the "uninstall" functionality to also effectively unbuild the module (by deleting the build directory), despite what the man page says, and changed the kernel_prerm.d_dkms script to do an "uninstall" instead of a "remove".

So Debian should probably cherry-pick that commit and update its own dkms kernel prerm script accordingly.

@evelikov
Copy link
Collaborator

MR #117 provides for a clear separation, allowing you to reach what you're looking for.

Namely, there are three commands each removing:

  • the symlinks/copy of the kernel module(s) in /lib/modules (uninstall)
  • all the build module(s) in /lib/modules and /var/lib/dkms (unbuild)
  • removing everything (remove)

@evelikov
Copy link
Collaborator

evelikov commented Feb 24, 2020

With the above MR, one can use "remove" or "unbuild" depending on their need.
I believe that resolves this issue and we can close this.

@RalfGoebel
Copy link

Is there any reason why the "unbuild" command is not used in the kernel prerm script?

dkms remove -m "$name" -v "$vers" -k "$inst_kern" -a "$arch"

@evelikov
Copy link
Collaborator

evelikov commented Mar 5, 2022

Good question @RalfGoebel - the script prerm seems to be Debian specific and my Debian knowledge is rather limited. I would encourage you to open a MR with some context behind the change.

As follow-up you might also want to help reduce (remove really) the Debian patchset and scripts - they have 12 year old, prerm duplicate 😱

ian-abbott added a commit to ian-abbott/dkms that referenced this issue Sep 19, 2023
When DKMS is invoked by the kernel_prerm.d_dkms script to remove modules
from a kernel that is being removed, it uses the DKMS 'remove' command.
If there are no other installations of the module, it will be removed
completely from DKMS.  That seems to be an undesirable side-effect and
predates the introduction of the DKMS 'unbuild' command which merely
undoes the 'install' and 'build' steps.

Change the script to use 'unbuild' instead of 'remove'.  Keep the echoed
message that says "dkms: removing: ..." because "dkms: unbuilding: ..."
may be confusing to the user.

I have tested it by removing a kernel with a module installed by DKMS
that was the only installed instance of the module.  Without the change,
the module was removed completely from DKMS.  With the change, the
module was removed from the kernel, but was not removed completely.  On
reinstalling the kernel, the module was rebuilt and reinstalled for the
kernel by DKMS.

This change was suggested by @RalfGoebel for issue dell#37 and might be
Debian-specific.

Link: dell#37 (comment)
Tested-by: Ian Abbott <[email protected]>
Signed-off-by: Ian Abbott <[email protected]>
ian-abbott added a commit to ian-abbott/dkms that referenced this issue Sep 25, 2023
When DKMS is invoked by the kernel_prerm.d_dkms script to remove modules
from a kernel that is being removed, it uses the DKMS 'remove' command.
If there are no other installations of the module, it will be removed
completely from DKMS.  That seems to be an undesirable side-effect and
predates the introduction of the DKMS 'unbuild' command which merely
undoes the 'install' and 'build' steps.

Change the script to use 'unbuild' instead of 'remove'.  Keep the echoed
message that says "dkms: removing: ..." because "dkms: unbuilding: ..."
may be confusing to the user.

I have tested it by removing a kernel with a module installed by DKMS
that was the only installed instance of the module.  Without the change,
the module was removed completely from DKMS.  With the change, the
module was removed from the kernel, but was not removed completely.  On
reinstalling the kernel, the module was rebuilt and reinstalled for the
kernel by DKMS.

This change was suggested by @RalfGoebel for issue dell#37 and might be
Debian-specific.

For Debian and Ubuntu, the 'kernel_postinst.d_dkms' script is installed as
'/etc/kernel/postinst.d/dkms' and '/etc/kernel/header_postinst.d/dkms',
and the 'kernel_prerm.d_dkms' script is installed as
'/etc/kernel/prerm.d/dkms'.  The scripts are invoked in the following
circumstances, with the script parameter $1 set to the kernel version
from the kernel package (referred to as "${KVER}" below):

1. When a "linux-headers-${KVER}" package is installed (containing the
   stuff needed to build external modules), the
   '/etc/kernel/header_postinst.d/dkms' ('kernel_postinst.d_dkms')
   script is invoked to autoinstall DKMS modules for the kernel version,
   building the modules if necessary.

2. When a "linux-image-${KVER}" package is installed (containing the
   Linux kernel binary, and in the case of Debian, also the kernel
   module binaries), the '/etc/kernel/postinst.d/dkms
   ('kernel_postinst.d_dkms') script is invoked to autoinstall DKMS
   modules for the kernel version, building the modules if necessary and
   possible.  (Building the modules will fail unless the
   "linux-headers-${KVER}" package is installed.)

3. When a "linux-headers-${KVER}" package is being removed, none of the
   DKMS scripts are invoked.

4. When a "linux-image-${KVER}" package is being removed, the
   '/etc/kernel/prerm.d/dkms' ('kernel_prerm.d_dkms') script is invoked
   to perform some sort of uninstallation action on all DKMS modules
   that have been built for the kernel version.  Prior to this patch,
   the DKMS 'remove' command was used to uninstall the modules.  This
   patch changes that to the DKMS 'unbuild' command which is less
   destructive.

On first glance, it may seem better to use the DKMS 'uninstall' command
when removing a "linux-image-${KVER}" package, and to use the DKMS
'unbuild' command  when removing a "linux-headers-${KVER}" package.
However, the "linux-image-${KVER}" and "linux-headers-${KVER}" packages
do not depend on each other, so unbuilding the DKMS modules when the
"linux-headers-${KVER}" package is being removed would have the side
effect of uninstalling the DKMS modules for the kernel, even if the
"linux-image-${KVER}" package is still installed.  Therefore, the
compromise is to use the DKMS 'unbuild' command when removing a
"linux-image-${KVER}" package and to do nothing when removing a
"linux-headers-${KVER}" package.  This is sub-optimal if the same
version of the "linux-image-${KVER}" package is to be reinstalled later
because the DKMS modules would need to be built again, but that should
be fairly rare.  Normally, kernel packages are upgraded to a different
version, requiring the DKMS modules to be built anyway.

Link: dell#37 (comment)
Tested-by: Ian Abbott <[email protected]>
Signed-off-by: Ian Abbott <[email protected]>
ian-abbott added a commit to ian-abbott/dkms that referenced this issue Sep 25, 2023
When DKMS is invoked by the kernel_prerm.d_dkms script to remove modules
from a kernel that is being removed, it uses the DKMS 'remove' command.
If there are no other installations of the module, it will be removed
completely from DKMS.  That seems to be an undesirable side-effect and
predates the introduction of the DKMS 'unbuild' command which merely
undoes the 'install' and 'build' steps.

Change the script to use 'unbuild' instead of 'remove'.  Keep the echoed
message that says "dkms: removing: ..." because "dkms: unbuilding: ..."
may be confusing to the user.

I have tested it by removing a kernel with a module installed by DKMS
that was the only installed instance of the module.  Without the change,
the module was removed completely from DKMS.  With the change, the
module was removed from the kernel, but was not removed completely.  On
reinstalling the kernel, the module was rebuilt and reinstalled for the
kernel by DKMS.

This change was suggested by @RalfGoebel for issue dell#37 and might be
Debian-specific.

For Debian and Ubuntu, the 'kernel_postinst.d_dkms' script is installed as
'/etc/kernel/postinst.d/dkms' and '/etc/kernel/header_postinst.d/dkms',
and the 'kernel_prerm.d_dkms' script is installed as
'/etc/kernel/prerm.d/dkms'.  The scripts are invoked in the following
circumstances, with the script parameter $1 set to the kernel version
from the kernel package (referred to as "${KVER}" below):

1. When a "linux-headers-${KVER}" package is installed (containing the
   stuff needed to build external modules), the
   '/etc/kernel/header_postinst.d/dkms' ('kernel_postinst.d_dkms')
   script is invoked to autoinstall DKMS modules for the kernel version,
   building the modules if necessary.

2. When a "linux-image-${KVER}" package is installed (containing the
   Linux kernel binary, and in the case of Debian, also the kernel
   module binaries), the '/etc/kernel/postinst.d/dkms
   ('kernel_postinst.d_dkms') script is invoked to autoinstall DKMS
   modules for the kernel version, building the modules if necessary and
   possible.  (Building the modules will fail unless the
   "linux-headers-${KVER}" package is installed.)

3. When a "linux-headers-${KVER}" package is being removed, none of the
   DKMS scripts are invoked.

4. When a "linux-image-${KVER}" package is being removed, the
   '/etc/kernel/prerm.d/dkms' ('kernel_prerm.d_dkms') script is invoked
   to perform some sort of uninstallation action on all DKMS modules
   that have been built for the kernel version.  Prior to this patch,
   the DKMS 'remove' command was used to uninstall the modules.  This
   patch changes that to the DKMS 'unbuild' command which is less
   destructive.

On first glance, it may seem better to use the DKMS 'uninstall' command
when removing a "linux-image-${KVER}" package, and to use the DKMS
'unbuild' command  when removing a "linux-headers-${KVER}" package.
However, the "linux-image-${KVER}" and "linux-headers-${KVER}" packages
do not depend on each other, so unbuilding the DKMS modules when the
"linux-headers-${KVER}" package is being removed would have the side
effect of uninstalling the DKMS modules for the kernel, even if the
"linux-image-${KVER}" package is still installed.  Therefore, the
compromise is to use the DKMS 'unbuild' command when removing a
"linux-image-${KVER}" package and to do nothing when removing a
"linux-headers-${KVER}" package.  This helps avoid littering the
'/var/lib/dkms' directory with stale builds.  It is sub-optimal if the
same version of the "linux-image-${KVER}" package is to be reinstalled
later because the DKMS modules would need to be built again, but that
should be fairly rare.  Normally, kernel packages are upgraded to a
different version, requiring the DKMS modules to be built anyway.

The script only affects DKMS modules with the "installed" status.  Only
DKMS modules with the "installed" status have files in
"/lib/modules/${KVER}" that need to be cleaned up.  It could be argued
that since the script is using the DKMS 'unbuild' command, it should
also unbuild DKMS modules with the "built" status.  There must have been
some external intervention outside of the kernel installation/removal
hook scripts to leave those modules at the "built" status, so the script
may be playing it safe by leaving those DKMS modules alone.

Link: dell#37 (comment)
Tested-by: Ian Abbott <[email protected]>
Signed-off-by: Ian Abbott <[email protected]>
ian-abbott added a commit to ian-abbott/dkms that referenced this issue Oct 11, 2023
When DKMS is invoked by the kernel_prerm.d_dkms script to remove modules
from a kernel that is being removed, it uses the DKMS 'remove' command.
If there are no other installations of the module, it will be removed
completely from DKMS.  That seems to be an undesirable side-effect and
predates the introduction of the DKMS 'unbuild' command which merely
undoes the 'install' and 'build' steps.

Change the script to use 'unbuild' instead of 'remove'.  Keep the echoed
message that says "dkms: removing: ..." because "dkms: unbuilding: ..."
may be confusing to the user.

I have tested it by removing a kernel with a module installed by DKMS
that was the only installed instance of the module.  Without the change,
the module was removed completely from DKMS.  With the change, the
module was removed from the kernel, but was not removed completely.  On
reinstalling the kernel, the module was rebuilt and reinstalled for the
kernel by DKMS.

This change was suggested by @RalfGoebel for issue dell#37 and might be
Debian-specific.

For Debian and Ubuntu, the 'kernel_postinst.d_dkms' script is installed as
'/etc/kernel/postinst.d/dkms' and '/etc/kernel/header_postinst.d/dkms',
and the 'kernel_prerm.d_dkms' script is installed as
'/etc/kernel/prerm.d/dkms'.  The scripts are invoked in the following
circumstances, with the script parameter $1 set to the kernel version
from the kernel package (referred to as "${KVER}" below):

1. When a "linux-headers-${KVER}" package is installed (containing the
   stuff needed to build external modules), the
   '/etc/kernel/header_postinst.d/dkms' ('kernel_postinst.d_dkms')
   script is invoked to autoinstall DKMS modules for the kernel version,
   building the modules if necessary.

2. When a "linux-image-${KVER}" package is installed (containing the
   Linux kernel binary, and in the case of Debian, also the kernel
   module binaries), the '/etc/kernel/postinst.d/dkms
   ('kernel_postinst.d_dkms') script is invoked to autoinstall DKMS
   modules for the kernel version, building the modules if necessary and
   possible.  (Building the modules will fail unless the
   "linux-headers-${KVER}" package is installed.)

3. When a "linux-headers-${KVER}" package is being removed, none of the
   DKMS scripts are invoked.

4. When a "linux-image-${KVER}" package is being removed, the
   '/etc/kernel/prerm.d/dkms' ('kernel_prerm.d_dkms') script is invoked
   to perform some sort of uninstallation action on all DKMS modules
   that have been built for the kernel version.  Prior to this patch,
   the DKMS 'remove' command was used to uninstall the modules.  This
   patch changes that to the DKMS 'unbuild' command which is less
   destructive.

On first glance, it may seem better to use the DKMS 'uninstall' command
when removing a "linux-image-${KVER}" package, and to use the DKMS
'unbuild' command  when removing a "linux-headers-${KVER}" package.
However, the "linux-image-${KVER}" and "linux-headers-${KVER}" packages
do not depend on each other, so unbuilding the DKMS modules when the
"linux-headers-${KVER}" package is being removed would have the side
effect of uninstalling the DKMS modules for the kernel, even if the
"linux-image-${KVER}" package is still installed.  Therefore, the
compromise is to use the DKMS 'unbuild' command when removing a
"linux-image-${KVER}" package and to do nothing when removing a
"linux-headers-${KVER}" package.  This helps avoid littering the
'/var/lib/dkms' directory with stale builds.  It is sub-optimal if the
same version of the "linux-image-${KVER}" package is to be reinstalled
later because the DKMS modules would need to be built again, but that
should be fairly rare.  Normally, kernel packages are upgraded to a
different version, requiring the DKMS modules to be built anyway.

The script only affects DKMS modules with the "installed" status.  Only
DKMS modules with the "installed" status have files in
"/lib/modules/${KVER}" that need to be cleaned up.  It could be argued
that since the script is using the DKMS 'unbuild' command, it should
also unbuild DKMS modules with the "built" status.  There must have been
some external intervention outside of the kernel installation/removal
hook scripts to leave those modules at the "built" status, so the script
may be playing it safe by leaving those DKMS modules alone.

Link: dell#37 (comment)
Tested-by: Ian Abbott <[email protected]>
Signed-off-by: Ian Abbott <[email protected]>
ian-abbott added a commit to ian-abbott/dkms that referenced this issue Oct 11, 2023
When DKMS is invoked by the kernel_prerm.d_dkms script to remove modules
from a kernel that is being removed, it uses the DKMS 'remove' command.
If there are no other installations of the module, it will be removed
completely from DKMS.  That seems to be an undesirable side-effect and
predates the introduction of the DKMS 'unbuild' command which merely
undoes the 'install' and 'build' steps.

Change the script to use 'unbuild' instead of 'remove'.  Keep the echoed
message that says "dkms: removing: ..." because "dkms: unbuilding: ..."
may be confusing to the user.

I have tested it by removing a kernel with a module installed by DKMS
that was the only installed instance of the module.  Without the change,
the module was removed completely from DKMS.  With the change, the
module was removed from the kernel, but was not removed completely.  On
reinstalling the kernel, the module was rebuilt and reinstalled for the
kernel by DKMS.

This change was suggested by @RalfGoebel for issue dell#37 and might be
Debian-specific.

For Debian and Ubuntu, the 'kernel_postinst.d_dkms' script is installed as
'/etc/kernel/postinst.d/dkms' and '/etc/kernel/header_postinst.d/dkms',
and the 'kernel_prerm.d_dkms' script is installed as
'/etc/kernel/prerm.d/dkms'.  The scripts are invoked in the following
circumstances, with the script parameter $1 set to the kernel version
from the kernel package (referred to as "${KVER}" below):

1. When a "linux-headers-${KVER}" package is installed (containing the
   stuff needed to build external modules), the
   '/etc/kernel/header_postinst.d/dkms' ('kernel_postinst.d_dkms')
   script is invoked to autoinstall DKMS modules for the kernel version,
   building the modules if necessary.

2. When a "linux-image-${KVER}" package is installed (containing the
   Linux kernel binary, and in the case of Debian, also the kernel
   module binaries), the '/etc/kernel/postinst.d/dkms
   ('kernel_postinst.d_dkms') script is invoked to autoinstall DKMS
   modules for the kernel version, building the modules if necessary and
   possible.  (Building the modules will fail unless the
   "linux-headers-${KVER}" package is installed.)

3. When a "linux-headers-${KVER}" package is being removed, none of the
   DKMS scripts are invoked.

4. When a "linux-image-${KVER}" package is being removed, the
   '/etc/kernel/prerm.d/dkms' ('kernel_prerm.d_dkms') script is invoked
   to perform some sort of uninstallation action on all DKMS modules
   that have been built for the kernel version.  Prior to this patch,
   the DKMS 'remove' command was used to uninstall the modules.  This
   patch changes that to the DKMS 'unbuild' command which is less
   destructive.

On first glance, it may seem better to use the DKMS 'uninstall' command
when removing a "linux-image-${KVER}" package, and to use the DKMS
'unbuild' command  when removing a "linux-headers-${KVER}" package.
However, the "linux-image-${KVER}" and "linux-headers-${KVER}" packages
do not depend on each other, so unbuilding the DKMS modules when the
"linux-headers-${KVER}" package is being removed would have the side
effect of uninstalling the DKMS modules for the kernel, even if the
"linux-image-${KVER}" package is still installed.  Therefore, the
compromise is to use the DKMS 'unbuild' command when removing a
"linux-image-${KVER}" package and to do nothing when removing a
"linux-headers-${KVER}" package.  This helps avoid littering the
'/var/lib/dkms' directory with stale builds.  It is sub-optimal if the
same version of the "linux-image-${KVER}" package is to be reinstalled
later because the DKMS modules would need to be built again, but that
should be fairly rare.  Normally, kernel packages are upgraded to a
different version, requiring the DKMS modules to be built anyway.

The script only affects DKMS modules with the "installed" status.  Only
DKMS modules with the "installed" status have files in
"/lib/modules/${KVER}" that need to be cleaned up.  It could be argued
that since the script is using the DKMS 'unbuild' command, it should
also unbuild DKMS modules with the "built" status.  There must have been
some external intervention outside of the kernel installation/removal
hook scripts to leave those modules at the "built" status, so the script
may be playing it safe by leaving those DKMS modules alone.

Link: dell#37 (comment)
Tested-by: Ian Abbott <[email protected]>
Signed-off-by: Ian Abbott <[email protected]>
ian-abbott added a commit to ian-abbott/dkms that referenced this issue Oct 11, 2023
When DKMS is invoked by the kernel_prerm.d_dkms script to remove modules
from a kernel that is being removed, it uses the DKMS 'remove' command.
If there are no other installations of the module, it will be removed
completely from DKMS.  That seems to be an undesirable side-effect and
predates the introduction of the DKMS 'unbuild' command which merely
undoes the 'install' and 'build' steps.

Change the script to use 'unbuild' instead of 'remove'.  Keep the echoed
message that says "dkms: removing: ..." because "dkms: unbuilding: ..."
may be confusing to the user.

I have tested it by removing a kernel with a module installed by DKMS
that was the only installed instance of the module.  Without the change,
the module was removed completely from DKMS.  With the change, the
module was removed from the kernel, but was not removed completely.  On
reinstalling the kernel, the module was rebuilt and reinstalled for the
kernel by DKMS.

This change was suggested by @RalfGoebel for issue dell#37 and might be
Debian-specific.

For Debian and Ubuntu, the 'kernel_postinst.d_dkms' script is installed as
'/etc/kernel/postinst.d/dkms' and '/etc/kernel/header_postinst.d/dkms',
and the 'kernel_prerm.d_dkms' script is installed as
'/etc/kernel/prerm.d/dkms'.  The scripts are invoked in the following
circumstances, with the script parameter $1 set to the kernel version
from the kernel package (referred to as "${KVER}" below):

1. When a "linux-headers-${KVER}" package is installed (containing the
   stuff needed to build external modules), the
   '/etc/kernel/header_postinst.d/dkms' ('kernel_postinst.d_dkms')
   script is invoked to autoinstall DKMS modules for the kernel version,
   building the modules if necessary.

2. When a "linux-image-${KVER}" package is installed (containing the
   Linux kernel binary, and in the case of Debian, also the kernel
   module binaries), the '/etc/kernel/postinst.d/dkms
   ('kernel_postinst.d_dkms') script is invoked to autoinstall DKMS
   modules for the kernel version, building the modules if necessary and
   possible.  (Building the modules will fail unless the
   "linux-headers-${KVER}" package is installed.)

3. When a "linux-headers-${KVER}" package is being removed, none of the
   DKMS scripts are invoked.

4. When a "linux-image-${KVER}" package is being removed, the
   '/etc/kernel/prerm.d/dkms' ('kernel_prerm.d_dkms') script is invoked
   to perform some sort of uninstallation action on all DKMS modules
   that have been built for the kernel version.  Prior to this patch,
   the DKMS 'remove' command was used to uninstall the modules.  This
   patch changes that to the DKMS 'unbuild' command which is less
   destructive.

On first glance, it may seem better to use the DKMS 'uninstall' command
when removing a "linux-image-${KVER}" package, and to use the DKMS
'unbuild' command  when removing a "linux-headers-${KVER}" package.
However, the "linux-image-${KVER}" and "linux-headers-${KVER}" packages
do not depend on each other, so unbuilding the DKMS modules when the
"linux-headers-${KVER}" package is being removed would have the side
effect of uninstalling the DKMS modules for the kernel, even if the
"linux-image-${KVER}" package is still installed.  Therefore, the
compromise is to use the DKMS 'unbuild' command when removing a
"linux-image-${KVER}" package and to do nothing when removing a
"linux-headers-${KVER}" package.  This helps avoid littering the
'/var/lib/dkms' directory with stale builds.  It is sub-optimal if the
same version of the "linux-image-${KVER}" package is to be reinstalled
later because the DKMS modules would need to be built again, but that
should be fairly rare.  Normally, kernel packages are upgraded to a
different version, requiring the DKMS modules to be built anyway.

The script only affects DKMS modules with the "installed" status.  Only
DKMS modules with the "installed" status have files in
"/lib/modules/${KVER}" that need to be cleaned up.  It could be argued
that since the script is using the DKMS 'unbuild' command, it should
also unbuild DKMS modules with the "built" status.  There must have been
some external intervention outside of the kernel installation/removal
hook scripts to leave those modules at the "built" status, so the script
may be playing it safe by leaving those DKMS modules alone.

Link: dell#37 (comment)
Tested-by: Ian Abbott <[email protected]>
Signed-off-by: Ian Abbott <[email protected]>
evelikov pushed a commit that referenced this issue Oct 11, 2023
When DKMS is invoked by the kernel_prerm.d_dkms script to remove modules
from a kernel that is being removed, it uses the DKMS 'remove' command.
If there are no other installations of the module, it will be removed
completely from DKMS.  That seems to be an undesirable side-effect and
predates the introduction of the DKMS 'unbuild' command which merely
undoes the 'install' and 'build' steps.

Change the script to use 'unbuild' instead of 'remove'.  Keep the echoed
message that says "dkms: removing: ..." because "dkms: unbuilding: ..."
may be confusing to the user.

I have tested it by removing a kernel with a module installed by DKMS
that was the only installed instance of the module.  Without the change,
the module was removed completely from DKMS.  With the change, the
module was removed from the kernel, but was not removed completely.  On
reinstalling the kernel, the module was rebuilt and reinstalled for the
kernel by DKMS.

This change was suggested by @RalfGoebel for issue #37 and might be
Debian-specific.

For Debian and Ubuntu, the 'kernel_postinst.d_dkms' script is installed as
'/etc/kernel/postinst.d/dkms' and '/etc/kernel/header_postinst.d/dkms',
and the 'kernel_prerm.d_dkms' script is installed as
'/etc/kernel/prerm.d/dkms'.  The scripts are invoked in the following
circumstances, with the script parameter $1 set to the kernel version
from the kernel package (referred to as "${KVER}" below):

1. When a "linux-headers-${KVER}" package is installed (containing the
   stuff needed to build external modules), the
   '/etc/kernel/header_postinst.d/dkms' ('kernel_postinst.d_dkms')
   script is invoked to autoinstall DKMS modules for the kernel version,
   building the modules if necessary.

2. When a "linux-image-${KVER}" package is installed (containing the
   Linux kernel binary, and in the case of Debian, also the kernel
   module binaries), the '/etc/kernel/postinst.d/dkms
   ('kernel_postinst.d_dkms') script is invoked to autoinstall DKMS
   modules for the kernel version, building the modules if necessary and
   possible.  (Building the modules will fail unless the
   "linux-headers-${KVER}" package is installed.)

3. When a "linux-headers-${KVER}" package is being removed, none of the
   DKMS scripts are invoked.

4. When a "linux-image-${KVER}" package is being removed, the
   '/etc/kernel/prerm.d/dkms' ('kernel_prerm.d_dkms') script is invoked
   to perform some sort of uninstallation action on all DKMS modules
   that have been built for the kernel version.  Prior to this patch,
   the DKMS 'remove' command was used to uninstall the modules.  This
   patch changes that to the DKMS 'unbuild' command which is less
   destructive.

On first glance, it may seem better to use the DKMS 'uninstall' command
when removing a "linux-image-${KVER}" package, and to use the DKMS
'unbuild' command  when removing a "linux-headers-${KVER}" package.
However, the "linux-image-${KVER}" and "linux-headers-${KVER}" packages
do not depend on each other, so unbuilding the DKMS modules when the
"linux-headers-${KVER}" package is being removed would have the side
effect of uninstalling the DKMS modules for the kernel, even if the
"linux-image-${KVER}" package is still installed.  Therefore, the
compromise is to use the DKMS 'unbuild' command when removing a
"linux-image-${KVER}" package and to do nothing when removing a
"linux-headers-${KVER}" package.  This helps avoid littering the
'/var/lib/dkms' directory with stale builds.  It is sub-optimal if the
same version of the "linux-image-${KVER}" package is to be reinstalled
later because the DKMS modules would need to be built again, but that
should be fairly rare.  Normally, kernel packages are upgraded to a
different version, requiring the DKMS modules to be built anyway.

The script only affects DKMS modules with the "installed" status.  Only
DKMS modules with the "installed" status have files in
"/lib/modules/${KVER}" that need to be cleaned up.  It could be argued
that since the script is using the DKMS 'unbuild' command, it should
also unbuild DKMS modules with the "built" status.  There must have been
some external intervention outside of the kernel installation/removal
hook scripts to leave those modules at the "built" status, so the script
may be playing it safe by leaving those DKMS modules alone.

Link: #37 (comment)
Tested-by: Ian Abbott <[email protected]>
Signed-off-by: Ian Abbott <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants