Bug#1057199: debian-policy: express more clearly that Conflicts to not reliably prevent concurrent unpacks

2024-01-18 Thread Guillem Jover
Hi!

On Wed, 2024-01-03 at 15:04:01 -0700, Sam Hartman wrote:
> > "Guillem" == Guillem Jover  writes:
> Guillem> At least the dpkg behavior seems entirely
> Guillem> correct to me and required for safe upgrades (
> 
> Can you help me understand the sentence above?
> Where is the case where this behavior is needed for safe upgrades?
> (I am asking out of curiosity; I'm guessing it's some corner case with
> essential packages, but I would like to understand.)

I should probably have qualified that statement, where safe upgrades
is restricted to the specific scenarios at hand. In any case, I don't
think this is specific to essential packages, this seems more general.
But of course the effects of not supporting such safe upgrades for
essential packages would be potentially more severe (although an
essential package can never be a conflictor as dpkg would refuse to
remove it).

In essence this involves a cyclic restriction where a set of packages
are stating they cannot be unpacked at the same time, but later
versions might be. There are several subcases for this depending on
the strength of the dependencies from each side, whether these are
versioned, and also whether the package manager front-end or the user
decides whether to fully evict a conflictor or wants to upgrade to a
latest version that can co-exist.

What the current behavior permits is to safely intertwine an unpack,
a conflictors files transfer and its removal in the same step, so that
the front-end or the user does not need to apply --force-* options to
forcibly remove the conflictor while breaking the dependency system
for an undetermined amount of time, to be able to proceed with such
upgrade.

I don't see any other way around this kind of upgrade that does not
break the dependency system besides the current behavior (if someone
does, I'm happy to hear it). Of course there's always the option to
prohibit those kinds of relationships, which means the behavior never
is brought up, and there's no need either to be concerned about whether
it needs to be supported or not. But that seems overly restrictive,
because once or if you need to express that kind of relationship, then
that path would be closed.


All this being said, when Helmut brought this up, I noticed that dpkg
is expecting to be hand held by giving to it the proper order for these
operations (as front-ends do), or it will either fail to upgrade
depending on the scenario, or unnecessarily use the conflictor eviction
behavior, which are not ideal (but do not break the dependency system).
I've got some test cases (Conflicts vs Breaks, Conflicts vs Conflicts),
which I should expand to add addition restrictions in the form of
Depends and Pre-Depends, unversioned relationships and similar, after
which I'll look into improving the way dpkg schedules its processing
queue in these cases so that it is a bit smarter about them and does
not fail so easily or uses this behavior unnecessarily when there's a
path forward at hand. But this seems besides the point of the conflictor
eviction behavior.

Thanks,
Guillem



Bug#1057199: debian-policy: express more clearly that Conflicts to not reliably prevent concurrent unpacks

2024-01-03 Thread Sam Hartman
> "Guillem" == Guillem Jover  writes:

Guillem> At least the dpkg behavior seems entirely
Guillem> correct to me and required for safe upgrades (

Can you help me understand the sentence above?
Where is the case where this behavior is needed for safe upgrades?
(I am asking out of curiosity; I'm guessing it's some corner case with
essential packages, but I would like to understand.)

--Sam



Bug#1057199: debian-policy: express more clearly that Conflicts to not reliably prevent concurrent unpacks

2024-01-03 Thread Guillem Jover
Hi!

On Fri, 2023-12-15 at 16:40:09 +, Sean Whitton wrote:
> On Fri 01 Dec 2023 at 02:11pm +01, Helmut Grohne wrote:
> > §7.4 currently starts with:
> >
> > When one binary package declares a conflict with another using a
> > Conflicts field, dpkg will refuse to allow them to be unpacked on
> > the system at the same time.
> >
> > I believe this is technically wrong. There are situations where dpkg
> > will allow such unpacks to temporarily co-exist. §6.6 goes into further
> > detail and is accurate.
> 
> Thank you for the detailed report.
> 
> Do the dpkg and apt people think that the bug here is just in Policy, or
> are there any code changes under consideration in response to this work?

I think it is just a documentation issue in the Debian Policy, yes. At
least the dpkg behavior seems entirely correct to me and required for safe
upgrades (and definitely not something like an accidental regression as it
has behaved that way since pretty much the beginning of its git history).

In addition I think the paragraph in §7.4 that states:

,---
A package will not cause a conflict merely because its configuration
files are still installed; it must be at least “Half-Installed”.
`---

could also be clarified that what is stated here does not apply either
to conflicting packages that are being removed, as those will be in
half-installed state. Perhaps as part of this, also make this state
change explicit in §6.6.2.3.

Thanks,
Guillem



Bug#1057199: debian-policy: express more clearly that Conflicts to not reliably prevent concurrent unpacks

2023-12-15 Thread Sean Whitton
Hello,

On Fri 01 Dec 2023 at 02:11pm +01, Helmut Grohne wrote:

> §7.4 currently starts with:
>
> When one binary package declares a conflict with another using a
> Conflicts field, dpkg will refuse to allow them to be unpacked on
> the system at the same time.
>
> I believe this is technically wrong. There are situations where dpkg
> will allow such unpacks to temporarily co-exist. §6.6 goes into further
> detail and is accurate.

Thank you for the detailed report.

Do the dpkg and apt people think that the bug here is just in Policy, or
are there any code changes under consideration in response to this work?

-- 
Sean Whitton


signature.asc
Description: PGP signature


Bug#1057199: debian-policy: express more clearly that Conflicts to not reliably prevent concurrent unpacks

2023-12-01 Thread Helmut Grohne
Package: debian-policy
Version: 4.6.2.0
X-Debbugs-Cc: debian-d...@lists.debian.org, de...@lists.debian.org

Hi,

first of all huge thanks to David, Guillem and Julian for all of their
explanations. In large parts, this bug report is yours and I'm just the
one writing it down.

§7.4 currently starts with:

When one binary package declares a conflict with another using a
Conflicts field, dpkg will refuse to allow them to be unpacked on
the system at the same time.

I believe this is technically wrong. There are situations where dpkg
will allow such unpacks to temporarily co-exist. §6.6 goes into further
detail and is accurate.

Suppose we have two arch:all packages a version 1 and b version 1 both
of which are installed. Now we attempt to install a version 2, which
happens to declare "Conflicts: b (<< 2)". We may therefore mark b for
removal

echo "b:all deinstall" | dpkg --set-selections

and proceed to installing a:

dpkg --auto-deconfigure --unpack a_2.deb

When we do this, dpkg will unpack a version 2 before removing the files
of b version 1. I argue this is very briefly allowing these packages to
be unpacked at the same time as the next thing dpkg does is removing b's
files.

This situation can be forced if we add package b version 2, which
declares "Breaks: a (<< 2)" and attempt to install both. apt figures
that it has to temporarily remove b and hence issues the selection
above. Then it proceeds to unpacking both packages.

The difference actually is rather subtle. As dpkg is tracking ownership
of files, one should not be observing a difference. What one can see is
that a.preinst version 2 is run at a time where b version 1 is still
unpacked (and that's fine as the statement only talks about unpack). The
effects of concurrent unpack are theoretically not observable, due to
dpkg tracking files. However when you add aliasing to the mix, dpkg can
now delete files that are still needed via differences in aliasing. That
way - and I am fully aware that this violates fundamental assumptions of
dpkg - we can make the order of unpacks visible and demonstrate that
indeed a version 2 is unpacked before b version 1 has its files removed.
All of this is fully in line with the long description in §6.6. What I
take issue with is the executive summary at the start of §7.4.

In case you like some kind of test case to tinker with, I'm attaching a
script that demonstrates the situation.

Helmut


conflict-demo.sh
Description: Bourne shell script