Skip to content

Conversation

@fhbash
Copy link
Contributor

@fhbash fhbash commented Nov 12, 2025

Adds --oldinstallonly flag to remove old installonly packages (e.g., kernels) that exceed the configured installonly_limit.

Optional --limit parameter allows overriding the config value (must be >1 to keep newest installed version).

Usage:

  dnf5 remove --oldinstallonly              # Remove all old installonly pkgs
  dnf5 remove --oldinstallonly kernel       # Remove old kernels only
  dnf5 remove --oldinstallonly --limit=2    # Keep only 2 newest versions

ci-tests: rpm-software-management/ci-dnf-stack#1782

Closes: #762

@fhbash fhbash requested a review from a team as a code owner November 12, 2025 13:48
@fhbash fhbash requested review from m-blaha and removed request for a team November 12, 2025 13:48
@m-blaha m-blaha self-assigned this Nov 19, 2025
@m-blaha
Copy link
Member

m-blaha commented Nov 19, 2025

Why is the limitation for --limit being > 1 needed? DNF4's implementation removes all older versions of any installonly package, which corresponds to dnf5 remove --oldinstallonly --limit=1.

@m-blaha
Copy link
Member

m-blaha commented Nov 19, 2025

Also what's expected behavior regarding to currently installed kernel version? I mean in this situation:

❯ uname -r
6.17.7-100.fc41.x86_64

❯ dnf repoquery --installed kernel
kernel-0:6.16.8-100.fc41.x86_64
kernel-0:6.17.4-100.fc41.x86_64
kernel-0:6.17.7-100.fc41.x86_64
kernel-0:6.17.8-100.fc41.x86_64

What should happen after dnf5 remove --oldinstallonly --limit=1? DNF4 in this situation will keep both, the latest (kernel-0:6.17.8-100.fc41.x86_64) and currently running kernel (kernel-0:6.17.7-100.fc41.x86_64) and remove old kernel-0:6.16.8-100.fc41.x86_64 and kernel-0:6.17.4-100.fc41.x86_64.

@fhbash
Copy link
Contributor Author

fhbash commented Nov 19, 2025

Why is the limitation for --limit being > 1 needed? DNF4's implementation removes all older versions of any installonly package, which corresponds to dnf5 remove --oldinstallonly --limit=1.

Because this new parameter is intent to remove old packages leaving at least 1 installed. If user want to remove all packages, need to use remove without the new parameter.

@fhbash
Copy link
Contributor Author

fhbash commented Nov 19, 2025

Also what's expected behavior regarding to currently installed kernel version? I mean in this situation:

❯ uname -r
6.17.7-100.fc41.x86_64

❯ dnf repoquery --installed kernel
kernel-0:6.16.8-100.fc41.x86_64
kernel-0:6.17.4-100.fc41.x86_64
kernel-0:6.17.7-100.fc41.x86_64
kernel-0:6.17.8-100.fc41.x86_64

What should happen after dnf5 remove --oldinstallonly --limit=1? DNF4 in this situation will keep both, the latest (kernel-0:6.17.8-100.fc41.x86_64) and currently running kernel (kernel-0:6.17.7-100.fc41.x86_64) and remove old kernel-0:6.16.8-100.fc41.x86_64 and kernel-0:6.17.4-100.fc41.x86_64.

for example, if you have 4 kernels which is installonly package, this new argument removes the oldest ones.. leaving you with the limit defined on installonly_limit options... but if you pass --limit=X this will remove the X packages, not respecting the installonly_limit options.. --limit need to be > 1 because we need to have at least 1 package installed... if the user want to remove all packages just use the remove without this new parameter

@m-blaha
Copy link
Member

m-blaha commented Nov 21, 2025

@fhbash Sorry, I was not clear enough about the running kernel example. Current code does not exclude the currently running kernel from removal which (in case the currently running kernel is not the latest one) results in failures like this:

❯ uname -r
6.17.7-100.fc41.x86_64

❯ dnf repoquery --installed kernel
kernel-0:6.16.8-100.fc41.x86_64
kernel-0:6.17.4-100.fc41.x86_64
kernel-0:6.17.7-100.fc41.x86_64
kernel-0:6.17.8-100.fc41.x86_64

❯ dnf5 remove --oldinstallonly --limit=1 --assumeno
Failed to resolve the transaction:
Problem: The operation would result in removing of running kernel: kernel-core-0:6.17.7-100.fc41.x86_64

I think dnf5 should remove only kernel-0:6.16.8-100.fc41.x86_64 and kernel-0:6.17.4-100.fc41.x86_64 kernels, keep kernel-0:6.17.7-100.fc41.x86_64 as this one is currently running (ideally with a message that the kernel was skipped from removal) and keep kernel-0:6.17.8-100.fc41.x86_64 as the user wants to keep only the latest version.

Adds --oldinstallonly flag to remove old installonly packages (e.g., kernels)
that exceed the configured installonly_limit. Optional --limit parameter allows
overriding the config value (must be >1 to keep newest installed version).

Usage:
  dnf5 remove --oldinstallonly              # Remove all old installonly pkgs
  dnf5 remove --oldinstallonly kernel       # Remove old kernels only
  dnf5 remove --oldinstallonly --limit=2    # Keep only 2 newest versions

Closes: rpm-software-management#762

Signed-off-by: Fellipe Henrique <[email protected]>
@fhbash fhbash force-pushed the remove-oldinstallonly branch from 7ce6161 to 3d80771 Compare November 24, 2025 18:07
@fhbash
Copy link
Contributor Author

fhbash commented Nov 24, 2025

@m-blaha I made the change to allow limit=1 and got these:

~/repos/dnf5/remove-oldinstallonly/build/dnf5 remove-oldinstallonly@3d80771
❯ dnf repoquery --installed kernel

kernel-0:6.17.1-300.fc43.x86_64
kernel-0:6.17.7-300.fc43.x86_64
kernel-0:6.17.8-300.fc43.x86_64

❯ sudo ./dnf5 remove --oldinstallonly --limit=1 --assumeno
Package                                                               Arch          Version                                                               Repository                                            Size
Removing:
 kernel                                                               x86_64        0:6.17.1-300.fc43                                                     d15e557246b143e68b4d7cf7c8078e9c                   0.0   B
 kernel                                                               x86_64        0:6.17.7-300.fc43                                                     <unknown>                                          0.0   B
 kernel-core                                                          x86_64        0:6.17.1-300.fc43                                                     d15e557246b143e68b4d7cf7c8078e9c                  97.9 MiB
 kernel-core                                                          x86_64        0:6.17.7-300.fc43                                                     <unknown>                                         98.8 MiB
 kernel-devel                                                         x86_64        0:6.17.7-300.fc43                                                     <unknown>                                         84.6 MiB
 kernel-modules                                                       x86_64        0:6.17.1-300.fc43                                                     d15e557246b143e68b4d7cf7c8078e9c                  95.6 MiB
 kernel-modules                                                       x86_64        0:6.17.7-300.fc43                                                     <unknown>                                         95.6 MiB
 kernel-modules-core                                                  x86_64        0:6.17.1-300.fc43                                                     d15e557246b143e68b4d7cf7c8078e9c                  68.3 MiB
 kernel-modules-core                                                  x86_64        0:6.17.7-300.fc43                                                     <unknown>                                         68.3 MiB
 kernel-modules-extra                                                 x86_64        0:6.17.1-300.fc43                                                     d15e557246b143e68b4d7cf7c8078e9c                   4.2 MiB
 kernel-modules-extra                                                 x86_64        0:6.17.7-300.fc43                                                     <unknown>                                          4.2 MiB
Removing dependent packages:
 kernel-devel-matched                                                 x86_64        0:6.17.7-300.fc43                                                     <unknown>                                          0.0   B
 kernel-modules-internal                                              x86_64        0:6.17.7-300.fc43                                                     <unknown>                                          3.0 MiB
 kernel-uki-virt                                                      x86_64        0:6.17.7-300.fc43                                                     <unknown>                                         80.9 MiB
 kernel-uki-virt-addons                                               x86_64        0:6.17.7-300.fc43                                                     <unknown>                                         58.9 KiB

Transaction Summary:
 Removing:          15 packages

After this operation, 702 MiB will be freed (install 0 B, remove 702 MiB).
Operation aborted by the user.

Now it's working as supposed to.. removing the old 2 versions, leaving the current one.

@m-blaha
Copy link
Member

m-blaha commented Jan 6, 2026

What's expected behavior in case the running kernel is not the one with the highest version number?

❯ fakeuname 6.17.1-300.fc43.x86_64 uname -r
6.17.1-300.fc43.x86_64

❯ fakeuname 6.17.1-300.fc43.x86_64 ./dnf5/dnf5 remove --oldinstallonly --limit=1 --assumeno
Failed to resolve the transaction:
Problem: The operation would result in removing of running kernel: kernel-core-0:6.17.1-300.fc43.x86_64

@ppisar
Copy link
Contributor

ppisar commented Jan 6, 2026

I guess it should depend on protect_running_kernel option value.

@m-blaha
Copy link
Member

m-blaha commented Jan 6, 2026

That's an option. Do I understand correctly that you mean that the dnf5 remove --oldinstallonly --limit=1 command will still try to remove all installed kernel versions except the newest one (regardless which kernel is currently running), allowing removal the running kernel if protect_running_kernel=false?
This behavior is

  1. dangerous (but the user specifically switched the protection off, so it's probably OK)
  2. different from what dnf4 did - dnf4 remove --oldinstallonly never attempts to remove the running kernel, so you can end up with two installed kernels left after running it - the latest version, and the currently running version. See https://github.com/rpm-software-management/dnf/blob/ba14891d868f7858486c62c09ed4dff3ccebe011/dnf/cli/commands/remove.py#L112-L127 for dnf4 implementation

@ppisar
Copy link
Contributor

ppisar commented Jan 6, 2026

Yes, that's what I meant. I did not know how DNF4 behaves.

I described my expectation that protect_running_kernel works independently from install-only feature and that non-latest kernel is old not matter whether it is running. I think it would keep the code and a documentation simple.

Of course there is a matter of compatibility which I did not take into account. I'm not strongly against DNF4 behavior. I only find it more complex and less intuitive.

@m-blaha
Copy link
Member

m-blaha commented Jan 7, 2026

Thanks for your opinion. I'm also not convinced we need to replicate safer, but less intuitive dnf4 behavior. There is one use case that dnf4 implementation resolves well, though: "Hey, dnf, I need to free some disk space. Remove all unneeded kernels I have installed on my box". In this case "dnf4 remove --oldinstallonly" would keep the running kernel and the latest version (to be used after reboot) and remove everything else, which I find useful.

Some links:
PR that introduced running kernel protection in dnf4: rpm-software-management/dnf#1540
Here is yum implementation of the same feature (called package-cleanup --oldkernels back then) which also protected running kernel: https://github.com/rpm-software-management/yum-utils/blob/05db7ef501fc9d6698935bcc039c83c0761c3be2/package-cleanup.py#L272-L322

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.

dnf [options] remove --oldinstallonly

3 participants