Thread (35 messages) flat view 35 messages, 6 authors, 2023-10-13

Re: [Buildroot] [PATCH v3 07/16] package/pkg-generic.mk: detect files overwritten in TARGET_DIR and HOST_DIR

From: Arnout Vandecappelle <hidden>
Date: 2021-08-30 09:46:37


On 29/08/2021 18:40, Yann E. MORIN wrote:
Thomas, All,

On 2021-08-29 14:51 +0200, Yann E. MORIN spake thusly:
[--SNIP--]
quoted
Finally, as a side note: there is still a case of file overwrite that we
do not detect, even with this series: if two packages that are not part
of the same dependency chain (i.e. they do not depend one on the other),
and they both install the same file, then the file-overwrite will only
happen when we eventually assemble the global target/ and host/ from the
individual PPD target/ and host/ and we still have to add a detection
for that case (which is not a pre-requisite before we apply the current
series, of course).
And of course, this will also cause an overwrite when two such packages
are also dependencies of a third patckage, and so when the PPD of that
third package is prepared, we would have to detect file overwrite.

Note: let's assume the following hypotetical dependency graph (where the
notation A --<-- B means that B depends on A):

      .-<-- A --<-.                 S: skeleton
     /             \                F: target-finalize
    S --<-- B --<-- C
     \               \
      `-<-- D --<-----<-- F

If A and B both install the same file, then we do not have a sane PPD
to build C.

If D and any package in the dependency chain of C (i.e. S, A, B, or C
itself) install the same file, then we can only detect it in
target-finalize.

So, let's take a step back, and have a wider look. I wonder if the end
of a package installation step is the best location to detected file
overwrite...

Indeed, let's assume that we do file overwrite detection:

 1. in PPD preparation (when we rsync the dependencies, in the macro
    per-package-rsync): we can also detect that a package overwrites one
    or more files of another package, report those files, *and* prevent
    building a package with unsound dependencies;

 2. in {target,host}-finalize: we can detect that a package overwrites
    one or more files provided by another package, and report those
    files.

So, the above (still theoretical implementation) is all we would need,
in the end, and we would not need to do the detection at the end of a
package installation step of each package, because it would not provide
any information that we couldn't have with the above.
 Fabrice's patches have shown that the overwritten file detection is too
aggressive in the sense to that it *will* cause (many?) failures in the current
situation.

 So, taking a step further back, what really is the problem we're trying to
solve here? Why can't we overwrite files from other packages?

 I think there are three distinct problems. Let's take Yann's example from above.

1. A file written in A and overwritten in C is only a problem because the
finalize step doesn't take into account dependencies when combining the trees.
We could solve that by taking into the account the dependencies.

2. A file written by both A and B is a problem for package C, because it is not
predictable which version it will see. This problem can be solved by adding a
dependency between A and B.

3. A file written by S and overwritten by A - this, I think, is the big problem.
At first sight it's like case 1 - by taking into account the dependencies, the
finalize stage will see the version from A. However, the problem is for stuff
installed into staging, where B sees the version from S while C sees the version
from A or from S, depending on order of A/B installation. This has two problems:
3a. C's version depends on the order of A/B installation;
3b. B sees a different version of the file than A - this could be a problem for
e.g. header files that affect compilation.

 The original scheme we discussed three or four years ago already took into
account situations 1 and 2, I think, but not yet situation 3. Note that back
then, the overwritten file detection was assumed to happen only in finalize and
accept overwrites in case there's a dependency.

 The curses and crypt issues that Fabrice detected fall in category 3. And
they're extra nasty, because one of the packages involved is the toolchain that
everybody depends on, so you can't just add a dependency to break it.

 I haven't given sufficient thought to it yet, but one idea is to allow packages
to add a post-install hook to another package. That way, ncurses could remove
curses.h from the toolchain, and libxcrypt could remove crypt.h. Still tricky
though because it would mean that any package that uses crypt.h would need to
optionally depend on libxcrypt - so that particular case would probably have to
be solved by making libxcrypt be part of the toolchain... Or maybe making sure
it doesn't overwrite crypt.h and teach its dependencies to include the
libxcrypt-specific crypt.h.

 One thing is certain: it's complicated :-)

 Regards,
 Arnout

However, a benefit of also doing it at the end of the installation step,
of a package, is that we can cut short on the build time. However, I am
not sure that benefit is that important or major...

So, I'd like we think a bit harder before we apply this patch...

Regards,
Yann E. MORIN.
_______________________________________________
buildroot mailing list
buildroot@busybox.net
http://lists.busybox.net/mailman/listinfo/buildroot
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help