Opened 7 years ago

Last modified 7 years ago

#260 new defect

Failures when updating critical components in a batch

Reported by: dmik Owned by:
Priority: critical Milestone:
Component: rpm Version:
Severity: medium Keywords:
Cc:

Description

There are known failures if a number of critical components related to YUM/RPM are being updated in a batch (e.g. by yum update which tries to install all available updates).

Consider this scenario: some DLL to be updated (e.g. LIBCx) gets a new function that is used by some application to be updated which is part of the update tool itself (e.g. RPM) and there also are some other applications to be updated in this batch besides the first two.

First, YUM will update LIBCx (all fine). Then it will update RPM using the older RPM which uses the old LIBCx (also fine as the old LIBCx is kept in memory by python running YUM even after being replaced by a new LIBCx). From this point on YUM will try to use the new (updated) RPM executable to install the remaining updates in the batch. But given that the new RPM needs the new LIBCx which won't be loaded because the old one is still in memory, it will have to use the old one but the old one misses a function it needs, so RPM will bail out. There are other possible scenarios similar to this one.

The only workaround for this problem is to update packages in a specific order which is manually defined by the user. I.e. in the above scenario it would be yum update libcx followed by a reboot (to have a newer LIBCx loaded), then update all the rest (other failing scenarios could require a different order). This clearly needs a better solution as forcing the end user to decide which packages to update first and do it manually beats the whole purpose of the smart package manager.

This ticket originates from #257 which contains a real life example in the comments.

Change History (1)

comment:1 Changed 7 years ago by dmik

The root of this problem is that under OS/2 it's generally impossible to pick up changes to DLLs on the fly if these DLLs are being used by an already running process. OS/2 locks them not only on the file level (which can be unlocked) but also in terms of handling DLL exports — and all newly started applications importing these DLLs will use in-memory copies even if the DLL file is updated on disk. I'm almost sure that it's not possible to overcome this even with setting LIBPATHSTRICT=T because the full DLL file path doesn't change in this case so OS/2 will most likely still use the old copy. But even if it worked, this wouldn't be an ultimate solution: there are DLLs that are not designed to have multiple copies of themselves being loaded and used at the same time (kLIBC is one of them — having two copies of it, no matter different or completely the same, will e.g. kill the fork mechanics).

The only legal way to resolve this to force all applications using the given DLL to terminate so that the old one is released a the new one gets loaded, or, if termination is not possible, reboot the system. And this is where a proper solution for this problem should go. Since RPM already knows which DLLs it replaces, it should force dependent application termination or a reboot — and refuse to operate (i.e. install/update/remove) until the user does so. This is worth a separate ticket so I created # for that. The only special addition of this ticket to #261 is that when a termination of YUM (python) is required, YUM should be aware of it and restart itself gracefully to continue executing the requested command. And YUM should refuse any further operation as well if there is still some dependent DLL which is not reloaded after restarting YUM itself because it is being held by some other application which hasn't been restarted yet.

As a temporary solution, until #261 is done, we may simply use a special flag created in the post-install script of a mission-critical package (LIBCx in the imaginary scenario above) which will tell YUM to forbid any package manipulation (with a respective message informing the user) until the system is rebooted.

Note: See TracTickets for help on using tickets.