Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
Bug 721080 - Removal of package proceeds even though pkg_prerm() calls `die`
Summary: Removal of package proceeds even though pkg_prerm() calls `die`
Status: UNCONFIRMED
Alias: None
Product: Portage Development
Classification: Unclassified
Component: Core - Ebuild Support (show other bugs)
Hardware: All Linux
: Normal normal (vote)
Assignee: Portage team
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2020-05-05 12:05 UTC by Gordon Bos
Modified: 2022-03-26 05:56 UTC (History)
2 users (show)

See Also:
Package list:
Runtime testing required: ---


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Gordon Bos 2020-05-05 12:05:08 UTC
I am writing a package for a binary kernel that should not allow uninstall of the current running kernel. The package accurately calls `die` when it detects that attempt, but the removal of the package proceeds as if nothing happened

Reproducible: Always

Actual Results:  
>>> Unmerging (1 of 1) sys-kernel/bubba-b3-kernel-5.4.28...
 * Checking current running kernel version ...                                                                   [ !! ]
 * ERROR: sys-kernel/bubba-b3-kernel-5.4.28::x-tmp failed (prerm phase):
 *   Cowardly refusing to uninstall the current running kernel
 * 
 * Call stack:
 *     ebuild.sh, line 125:  Called pkg_prerm
 *   environment, line 505:  Called die
 * The specific snippet of code:
 *           die "Cowardly refusing to uninstall the current running kernel";
 * 
 * If you need support, post the output of `emerge --info '=sys-kernel/bubba-b3-kernel-5.4.28::x-tmp'`,
 * the complete build log and the output of `emerge -pqv '=sys-kernel/bubba-b3-kernel-5.4.28::x-tmp'`.
 * The complete build log is located at '/var/tmp/portage/._unmerge_/sys-kernel/bubba-b3-kernel-5.4.28/temp/build.log'.
 * The ebuild environment file is located at '/var/tmp/portage/._unmerge_/sys-kernel/bubba-b3-kernel-5.4.28/temp/environment'.
 * Working directory: '/var/tmp/portage/._unmerge_/sys-kernel/bubba-b3-kernel-5.4.28/homedir'
 * S: '/var/tmp/portage/._unmerge_/sys-kernel/bubba-b3-kernel-5.4.28/work/bubba-b3-kernel-5.4.28'
!!! FAILED prerm: 1
No package files given... Grabbing a set.
<<<          obj /usr/src/linux-5.4.28-gentoo/System.map
<<<          obj /usr/src/linux-5.4.28-gentoo/Module.symvers
<<<          obj /usr/src/linux-5.4.28-gentoo/.config
--- cfgpro   sym /lib/modules/5.4.28-gentoo-b3/source
--- cfgpro   obj /lib/modules/5.4.28-gentoo-b3/modules.symbols.bin
--- cfgpro   obj /lib/modules/5.4.28-gentoo-b3/modules.symbols
--- cfgpro   obj /lib/modules/5.4.28-gentoo-b3/modules.softdep
--- cfgpro   obj /lib/modules/5.4.28-gentoo-b3/modules.order
--- cfgpro   obj /lib/modules/5.4.28-gentoo-b3/modules.devname
--- cfgpro   obj /lib/modules/5.4.28-gentoo-b3/modules.dep.bin
--- cfgpro   obj /lib/modules/5.4.28-gentoo-b3/modules.dep
--- cfgpro   obj /lib/modules/5.4.28-gentoo-b3/modules.builtin.modinfo
...

...
--- cfgpro   sym /lib/modules/5.4.28-gentoo-b3/build
--- cfgpro   dir /lib/modules/5.4.28-gentoo-b3
<<<          obj /boot/vmlinuz-5.4.28-gentoo-b3
<<<          obj /boot/config-5.4.28-gentoo-b3
<<<          obj /boot/System.map-5.4.28-gentoo-b3
<<<          obj /boot/Module.symvers-5.4.28-gentoo-b3
<<<          dir /usr/src/linux-5.4.28-gentoo
--- !empty   dir /usr/src
--- !empty   dir /usr
--- !empty   dir /lib/modules
--- !empty   dir /lib
--- !empty   dir /boot
Packages installed:   617
Packages in world:    63
Packages in system:   43
Required packages:    617
Number removed:       1




Expected Results:  
Execution stop rather than simply print that the programmed preconditions were not met.
Comment 1 Gordon Bos 2020-07-10 13:05:45 UTC
Updated to version 2.3.99-r2 today.

No change, die() called in the prerm() phase still does not prevent portage to proceed with package removal.


Note that this may be verified with any binary kernel installation by having /boot unmounted during removal, in which case it will proceed to remove the associated modules and the /var/db/pkg entry.
Comment 2 Zac Medico gentoo-dev 2020-07-10 23:19:03 UTC
I think we could probably change the portage behavior but then we'd probably have to add an option to allow people to forcefully remove the package if necessary.
Comment 3 Michał Górny archtester Gentoo Infrastructure gentoo-dev Security 2020-07-11 06:16:29 UTC
How would that work with weak blockers though?
Comment 4 Gordon Bos 2020-07-11 06:28:52 UTC
Right. Should have probably mentioned that the function I was referring to in my previous comment is part of the `mount-boot` eclass, which unlike what its name appears to indicate does not mount boot if it was not already mounted, but returns an error if it is not.

When you install a binary kernel package (or a boot manager I presume) and /boot is not mounted, the `mount-boot` eclass will call die() in the pretend phase and that actually stops portage from proceeding. When you uninstall a package though, it never calls pretend() but goes straight to prerm() where die() causes a lot of error information to be printed (as expected) but portage carries on as if the error didn't occur.

A bit reading between the lines of your comment, could this be because the *rm() functions have a double function, also called to clean up a previous installed version of a package after install?
Comment 5 Michał Górny archtester Gentoo Infrastructure gentoo-dev Security 2020-07-11 06:32:17 UTC
(In reply to Gordon Bos from comment #4)
> A bit reading between the lines of your comment, could this be because the
> *rm() functions have a double function, also called to clean up a previous
> installed version of a package after install?

Yes, exactly, and I even didn't think of that simpler case.  The general problem is that removing some old package may be necessary for other installed package to function correctly.  Leaving it installed might leave the system in a weird state.  At the very least, Portage should abort further operations if that occurs.
Comment 6 Gordon Bos 2020-07-11 18:59:40 UTC
Reflecting on above comments. I had actually missed the remark about weak blockers and I do follow the reasoning that bad things may happen if conflicting packages are allowed to co-exist, but the same applies to a kernel where all the modules have been wiped. What I am wondering is if there is any actual use case of an unexpected die during a prerm phase? If there is, surely that must have some OS return code associated with it that allows distinguishing it from a deliberate call to die().
Comment 7 Zac Medico gentoo-dev 2020-07-12 19:28:51 UTC
(In reply to Gordon Bos from comment #6)
> What I am wondering is if there is any actual use case of an unexpected die
> during a prerm phase?

I suppose the die from comment #0 would be unexpected in a chroot, since there's no danger in unmerging the running kernel when it happens to be in a chroot.

> If there is, surely that must have some OS return code associated with it that
> allows distinguishing it from a deliberate call to die().

Portage is able to distinguish deliberate die calls via ipc (or if ipc is disabled then it uses a temporary file referenced by a variable named PORTAGE_EBUILD_EXIT_FILE to indicate deliberate exit).
Comment 8 Gordon Bos 2020-07-13 16:36:55 UTC
(In reply to Zac Medico from comment #7)
> (In reply to Gordon Bos from comment #6)
> > What I am wondering is if there is any actual use case of an unexpected die
> > during a prerm phase?
> 
> I suppose the die from comment #0 would be unexpected in a chroot, since
> there's no danger in unmerging the running kernel when it happens to be in a
> chroot.

 
Have to disagree, because this may still lead to a broken kernel without modules if /boot is not mounted within the chroot environment.

> > If there is, surely that must have some OS return code associated with it that
> > allows distinguishing it from a deliberate call to die().
> 
> Portage is able to distinguish deliberate die calls via ipc (or if ipc is
> disabled then it uses a temporary file referenced by a variable named
> PORTAGE_EBUILD_EXIT_FILE to indicate deliberate exit).

Okay, but that would mean that a call to die() which must be considered a deliberate action by the ebuild file can be identified and thus should be obeyed. But it isn't.
Comment 9 Zac Medico gentoo-dev 2020-07-13 16:46:41 UTC
(In reply to Gordon Bos from comment #8)
> (In reply to Zac Medico from comment #7)
> > (In reply to Gordon Bos from comment #6)
> > > What I am wondering is if there is any actual use case of an unexpected die
> > > during a prerm phase?
> > 
> > I suppose the die from comment #0 would be unexpected in a chroot, since
> > there's no danger in unmerging the running kernel when it happens to be in a
> > chroot.
> 
>  
> Have to disagree, because this may still lead to a broken kernel without
> modules if /boot is not mounted within the chroot environment.

You may want to support some notion of a non-live system. My regular update process involves creating a btrfs snapshot of my root filesystem, updating that snapshot in a chroot, and then rebooting into the updated snapshot. My /boot happens to be on a separate partition, but that need not always be the case.
Comment 10 Gordon Bos 2020-07-14 07:19:10 UTC
(In reply to Zac Medico from comment #9)
> You may want to support some notion of a non-live system. My regular update
> process involves creating a btrfs snapshot of my root filesystem, updating
> that snapshot in a chroot, and then rebooting into the updated snapshot. My
> /boot happens to be on a separate partition, but that need not always be the
> case.

Uhmmm.... That is actually the precise point that I was making. That if /boot is on a separate partition and thus proceeding to attempt removal will remove the kernel modules but will be unable to remove the kernel itself or make any required changes to the bootloader.

The only difference between live and non-live for this use case is that in the non-live system you can clear the complete /lib/modules/[kernel] folder whereas in a live environment you cannot.