[Rpm-maint] [RFC] Change to Packing Uninstallation Ordering
slawrence at tresys.com
Wed May 12 21:01:22 UTC 2010
On Wed, 2010-05-12 at 10:27 +0300, Panu Matilainen wrote:
> On Mon, 10 May 2010, Steve Lawrence wrote:
> > After digging into the design of our new Collection idea  a bit more,
> > we've realized there are potential ordering problems with the SELinux
> > part of collections, specifically with upgrades and obsoletes. For
> > example, assume we already have foo-1.rpm and foo-policy-1.rpm installed
> > and we are upgrading both packages to version 2. Currently, RPM would
> > order the upgrade transaction like this:
> > 1. ADD foo-policy-2
> > 2. ADD foo-2
> > 3. REMOVE foo-1
> > 4. REMOVE foo-policy-1
> > RPM first performs all adds, then all removals. This means that the
> > sepolicy collection plugin wouldn't be triggered until after step 4,
> > when the last member of the sepolicy collection is handled. This means
> > that when foo-2 is added, the policy from foo-policy-2.rpm won't be
> > loaded yet, resulting in a potential for files with incorrect SELinux
> > labels.
> > Ideally, the ordering would be done like this instead:
> > 1. ADD foo-policy-2
> > 2. REMOVE foo-policy-1
> > 3. ADD foo-2
> > 4. REMOVE foo-1
> > The idea is that all removals are performed immediately after the new
> > package is added rather than at the end of the transaction. In this
> > case, policy would be loaded after step 2, and foo-2 would be installed
> > with the correct SELinux labels.
> > It seems to us that this change in ordering shouldn't break anything.
> > Though, it looks like this ordering was done very deliberately, so maybe
> > there are some corner cases or something we are missing.
> > Thoughts?
> A long long time ago, rpm used to do the erasures immediately after the
> upgrade element. Assuming packages have their dependencies right, either
> ordering should be ok for the transaction itself. Where it does make a
> difference is updates on a live system: if erasure of the old version is
> done immediately after new version, there can be large windows where the
> depending packages are broken (consider eg library soname bump) while
> other depending packages are being updated. Doing erasures only after
> everything has been installed helps keeping the system functional while a
> transaction is running, changing that is not really an option I'm afraid.
So our backup plan is to make our Collection design do a bit more of the
work. Rather than always executing the plugin on the last add/remove of
a transaction element of a collection, there would be two hooks into the
plugins. One hook would be executed normally during the last add/remove
and would be used by the generic exec plugin, which is used by all
collections except the selinux collection. The second plugin hook would
be a post add hook, and would only be executed when the last transaction
element of a collection was added (not removed). The selinux plugin
would use this hook, and examine the entire transaction and figure out
what policies will be removed and remove them them (via semodule -r).
A side effect of this is that the selinux plugin will remove policy well
before it removes the package, and a failure somewhere during that
window could cause an inconsistency in the rpmdb. For example, the
ordering would be something like this:
1. ADD foo-policy-2
1a semodule -r foo -i foo.pp # remove the old foo from foo-policy-1
# and install the new from foo-policy-2
2. ADD foo-2
3. REMOVE foo-1
4. REMOVE foo-policy-1
So if something fails at step 2 or 3 and aborts the RPM transaction we
would have upgraded the policy but the rpm database will still list both
foo-policy-2 and foo-policy-1 as being installed. So the system and the
rpm database are out of sync. Future transactions involving policy
should still work, but this does leave the rpmdb in an odd state.
Does that seem reasonable? Does rpm currently have a method of dealing
with these types of inconsistencies?
More information about the Rpm-maint