| Commit message (Collapse) | Author | Age | Files | Lines |
| | |
|
| |
|
|
|
|
|
|
|
| |
Record a silly string if we backtracked such that we are aware
of it. We need to handle this in a broader fashion, but
this was at least breaking test-apt-never-markauto-sections
with remove-manual
LP: #2129819
|
| |
|
|
|
| |
Do not prevent us from changing the version of a foreign package
because a sibling that is being removed has a different candidate.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Architecture variants are children of an architecture that share
the same ABI but are optimized for different ISA levels. They
are available in Ubuntu 25.10 and newer, and not supported in
Debian or other distributions.
A deb built for a variant contains the Architecture-Variant field,
and the Architecture field points to the baseline, for example:
Architecture: amd64
Architecture-Variant: amd64v3
However, the apt-get indextargets command reports the variant in the
Architecture: field, and most of the code in APT presents the variant
as the architecture.
There are two types of variants:
1. Standalone variants are recorded in the Architectures field of the
Release file as if they were a real architecture:
Architectures: amd64 amd64v3
Standalone architecture variants only fetch the standalone
architecture variant's Packages file. To do this, this patch
changes the code such that the variants indextargets "supplant"
the base targets.
This may have complicated outcomes on the apt-get indextargets
command.
2. Other variants can only be identified by their files being recorded
with hashes in the Release file.
APT fetches both the base architecture's as well as the variant's
Packages file.
Variants are configured in the
APT::Architecture-Variants
list.
Image builders may want to build specific variant images using
APT::Architecture-Variants { "amd64v3"; }
But this commit also implements an automatic discovery mechanism
using the varianttable and /proc/cpuinfo.
APT::Architecture-Variants "auto";
|
| |
|
|
| |
This splits based upon contiguous whitespace as separators
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
When a user ran `apt install gpg`, the solver decided to remove
`gnupg` and `seahorse` because `seahorse` was only pulled in as
a Recommends of ubuntu-desktop and Recommends were resolved after
all other dependencies.
Solve this to most extent by introducing eager optionality: These
dependencies, while they do not take part in classic unit propagation,
are otherwise treated like hard dependencies and resolved as soon
as possible rather than after any hard dependencies.
This ensures that the Recommends of ubuntu-desktop on seahorse
is retained correctly, and as a result, gnupg is updated to the
latest version.
Oops: 6c8e32eb-665d-11f0-a985-fa163ec8ca8c
|
| | |
|
| |
|
|
|
| |
Rather than just setting the flags to 0 or FD_CLOEXEC, read
the current value and append or remove as needed.
|
| |
|
|
|
|
|
|
|
| |
Implement a wrapper around FD_CLOEXEC and use it in place of
the raw fcntl(). This wrapper _Exit()s the child if the operation
failed.
Restructure the close_range() handling to simply mark all fds for
closing first and then "reopen" the ones we should keep.
|
| | |
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
Use close_range() if we have it in preference to iterating
over /proc/self/fd and falling back to closing all possible
fds.
This builds sets of ranges to close that take into account
the APT::Keep-Fds vector, and a test case is provided to
ensure correctness of the splitting logic.
Preference is given to close_range() over /proc as in the
optimal case, this results in a single system call!
|
| |
|
|
|
|
|
|
| |
We don't quite know why a stuck queue cannot get unstuck here,
and it's possible that this is causing the queue to stall, but
shrug.
Closes: #1111554
|
| | |
|
| | |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
We skipped the Architecture: line because when the outer
loop got to it, the inner loop started and read the next
line after it.
Get rid of the nested loop instead, and first run a loop
to find the request line, and then a second loop to parse
the request flags.
An alternative would be to use a combined loop that
supports non-compliant protocol implementations, but
that's harder to read and we don't expect there to be
any especially on the request side.
|
| |
|
|
| |
We need to actually use the architecture values we set
|
| |
|
|
|
|
| |
This commit fixes the following compiler warning.
cacheiterators.h:423:54: warning: misleading indentation;
statement is not part of the previous 'if' [-Wmisleading-indentation]
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Lookup these variables in the constructor once, rather than
once per package.
This requires a bit of care as debListParser::UsePackage()
defaults to "all" for essential when unset, hence we simply
change its == "all" comparisons to == "all" || .empty().#
This removes any per-paragraph configuration lookups
from the file parser.
Also parse myArch from ParseProvides down to ParseDepends()
as that call ended up causing it to query APT::Architecture
*again* since the function we call is static.
Together, the removed config lookups safe about 2.3% of
cache generation runtime.
|
| |
|
|
|
|
|
|
|
|
|
|
| |
Lots of people have pinned an older version that is no longer
installable, or more common yesterday, we saw a lot of people
who seemingly manually installed a newer version of a deb than
in the repositories, causing the package to be considered obsolete,
which does not make much sense.
Oops: 4c39d922-410f-11f0-bbf9-fa163ec44ecd
Oops: a64054f6-4140-11f0-bbfd-fa163ec44ecd
Oops: a32196c1-661d-11f0-a97c-fa163ec8ca8c
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Instead of inadvertently sorting dependency targets against
the first alternative in an or group, sort them against the
current alternative as we should.
Otherwise we ended up sorting
gnome-shell | notification-daemon
With
Package: notification-daemon
Package: awesome
Provides: notification-daemon
into
gnome-shell | awesome | notification-daemon
<-we sorted this part wrongly->
This fixes a minor difference in test-release-candidate-switching
in one case, but not the other where the difference was actually
caused by the loss of install argument ordering information in
the new solver, so just flip the arguments so both solvers produce
the same outcome.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
When a server responds with two InRelease files, but one
is good, and the other indicates a temporary error, we
queued the other indices from the good repository for
downloading and then queued the retry.
The resulting queue ended up with items having fetchAfter=0
before the item with fetchAfter=<something>, causing the
Run() loop to not detect a stuck queue.
Change the order of the queue such that the highest retry-after
items comes first; this ensures that we always see stuck queues.
This of course changes the behavior of retries in that if one
file fails temporarily we block the entire server. This does
seem more beneficial in the common case - if one file fails,
probably all of them fail, and there's no point bombarding
the server with requests for indices from good repositories
until all have failed.
The actual root cause is more that the remaining items are
Enqueued like this:
1. Enqueue jammy/InRelease (delayed)
2. Enqueue jammy-updates/main all Packages
The resulting queue ended up being:
jammy-updates/main all Packages
jammy/InRelease (delayed)
But Enqueue() only calls Cycle() when there are no items in
the queue already - after all, any item that is already running
will call Cycle() eventually. Or so was the case until we added
the retry-after handling.
It's unclear why we don't Cycle() all the time when enqueuing
a new item, given that our pipeline might not be filled yet,
and we could send the request to the server while waiting for
data on a running item.
Trying to always Cycle() however led to regressions that still
need investigating. Given that, this solution certainly is the
more easy to reason about one.
LP: #2003851
|
| |
|
|
|
|
|
|
| |
This commit fixes the following compiler errors.
apt-pkg/acquire.cc:833:51: error: no template named 'function' in namespace 'std'
apt-pkg/contrib/error.cc:198:59: error: no member named 'front_inserter' in namespace 'std'
apt-pkg/solver3.h:44:22: error: no template named 'is_trivially_constructible_v' in namespace 'std'
methods/http.cc:1029:24: error: no member named 'inserter' in namespace 'std'
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
With an explicit {} initialization, g++ 14.2 on armhf and armel
seems to generate the default constructor for the vector too early,
or in the first place, outside of solver3.cc where the constructor
is defined.
Without {}, this compiles again.
In file included from /usr/include/c++/14/vector:66,
from /<<PKGBUILDDIR>>/obj-arm-linux-gnueabihf/include/apt-pkg/cachefilter.h:14:
/usr/include/c++/14/bits/stl_vector.h: In instantiation of ‘constexpr std::_Vector_base<_Tp, _Alloc>::~_Vector_base() [with _Tp = APT::Solver::Work; _Alloc = std::allocator<APT::Solver::Work>]’:
/usr/include/c++/14/bits/stl_vector.h:531:7: required from here
531 | vector() = default;
| ^~~~~~
/usr/include/c++/14/bits/stl_vector.h:369:49: error: invalid use of incomplete type ‘struct APT::Solver::Work’
369 | _M_impl._M_end_of_storage - _M_impl._M_start);
| ~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~
In file included from /<<PKGBUILDDIR>>/apt-pkg/edsp.cc:22:
/<<PKGBUILDDIR>>/obj-arm-linux-gnueabihf/include/apt-pkg/solver3.h:87:11: note: forward declaration of ‘struct APT::Solver::Work’
87 | struct Work;
| ^~~~
/usr/include/c++/14/bits/stl_vector.h: In instantiation of ‘constexpr std::_Vector_base<_Tp, _Alloc>::~_Vector_base() [with _Tp = APT::Solver::Solved; _Alloc = std::allocator<APT::Solver::Solved>]’:
/usr/include/c++/14/bits/stl_vector.h:531:7: required from here
531 | vector() = default;
| ^~~~~~
/usr/include/c++/14/bits/stl_vector.h:369:49: error: invalid use of incomplete type ‘struct APT::Solver::Solved’
369 | _M_impl._M_end_of_storage - _M_impl._M_start);
| ~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~
/<<PKGBUILDDIR>>/obj-arm-linux-gnueabihf/include/apt-pkg/solver3.h:88:11: note: forward declaration of ‘struct APT::Solver::Solved’
88 | struct Solved;
| ^~~~~~
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The cache allocates strings as
uint16_t size;
char content[];
char zero;
Aligned to the uint16_t. When doing the casting, this causes a
warning on some architectures that cannot do unaligned loads, such
as armhf.
Use __builtin_assume_aligned() to explictly say that the pointer
is aligned to 16 bits. This is a bit of a backhanded approach,
as the warning seems to be actually avoided by the function
returning a void* rather than the assumed alignment, but this
is very much self-documenting.
|
| |
|
|
|
|
| |
When inspecting Recommends of installed packages, filter
them to the installed packages only, as we want to avoid
switching between alternatives of recommended packages.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
On recent armfhf and s390x builds in the PPA, the compiler seems to have
generated the destructor at the wrong point where the definitions where
not yet complete, and it does seem ill-advised to rely on a
default-constructed destructor in the solver for future ABI sake.
In file included from /usr/include/c++/14/vector:66,
from /<<PKGBUILDDIR>>/obj-arm-linux-gnueabihf/include/apt-pkg/cachefilter.h:14:
/usr/include/c++/14/bits/stl_vector.h: In instantiation of ‘constexpr std::_Vector_base<_Tp, _Alloc>::~_Vector_base() [with _Tp = APT::Solver::Work; _Alloc = std::allocator<APT::Solver::Work>]’:
/usr/include/c++/14/bits/stl_vector.h:531:7: required from here
531 | vector() = default;
| ^~~~~~
/usr/include/c++/14/bits/stl_vector.h:369:49: error: invalid use of incomplete type ‘struct APT::Solver::Work’
369 | _M_impl._M_end_of_storage - _M_impl._M_start);
| ~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~
In file included from /<<PKGBUILDDIR>>/apt-pkg/edsp.cc:22:
/<<PKGBUILDDIR>>/obj-arm-linux-gnueabihf/include/apt-pkg/solver3.h:87:11: note: forward declaration of ‘struct APT::Solver::Work’
87 | struct Work;
| ^~~~
/usr/include/c++/14/bits/stl_vector.h: In instantiation of ‘constexpr std::_Vector_base<_Tp, _Alloc>::~_Vector_base() [with _Tp = APT::Solver::Solved; _Alloc = std::allocator<APT::Solver::Solved>]’:
/usr/include/c++/14/bits/stl_vector.h:531:7: required from here
531 | vector() = default;
| ^~~~~~
/usr/include/c++/14/bits/stl_vector.h:369:49: error: invalid use of incomplete type ‘struct APT::Solver::Solved’
369 | _M_impl._M_end_of_storage - _M_impl._M_start);
| ~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~
/<<PKGBUILDDIR>>/obj-arm-linux-gnueabihf/include/apt-pkg/solver3.h:88:11: note: forward declaration of ‘struct APT::Solver::Solved’
88 | struct Solved;
| ^~~~~~
|
| |
|
|
|
|
|
|
|
|
|
|
| |
In case a new version of the source package is published, we
check that if there's a newer binary for the same architecture
and then consider the binary obsoleted.
This logic did not properly account for Architecture: all packages
which are considered as native architecture package with an "All"
multi-arch flag set, and hence a native architecture package may
inadvertently be considered obsoleted by a package that only built
on Architecture: all.
|
| |
|
|
|
| |
Avoid or groups and dependencies on different (virtual) packages,
to avoid some common pitfalls like the added xorg test case.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Merge any hard clauses into optional clauses, such that
optional clauses don't end up with more choices.
For example if you have
Depends: a | b
Recommends: a | c
This becomes:
Depends: a | b
Recommends: a
We have simulated this with the chaos-actor in the test case
and a
Depends: git (not satisfied by chaos provider)
Recommends: git (satisfied by chaos provider)
and the latter constraint is limited to the former.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
If a package declares multiple dependencies that can be solved by
the same packages we should use the common set of packages to
solve them.
A common example is requiring the same Debian source version, or the
same upstream version as in our test case:
git-ng Depends: git (>> 1:2.26.2), git (<< 1:2.26.2-.)
The solver expands this to the concrete objects:
git-ng Depends: "real git" (= 1:2.26.2-1) | chaos-actor, "real git" (= 1:2.26.2-1) | "real git" (= 1:2.25.1-1)
When given an upgrade request, the solver would now choose
chaos-actor to satisfy git (>> 1:2.26.2)
"real git" (= 1:2.25.1-1) to satisfy git (<< 1:2.26.2-.)
To satisfy the two constraints, which is not the intended outcome.
Address this problem by introducing a concept of merged clauses:
If two dependencies of a package have overlapping solutions, replace
the dependency by the intersection, and record the merged clause
instead, this leads to a single clause:
Depends: git (>> 1:2.26.2) and git (<< 1:2.26.2-.)
which expands to just the real git binary.
The implementation is a bit finicky in that it removes the variables
from the original clause which may not be helpful for debugging, but
it records the clauses merged with, as seen in the test case, so the
reasoning is clear.
LP: #2111792
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
If we have allowed the removal of manual packages, assume them
all before starting the solver. This should ensure that as long
as there is a solution that does not remove a manually installed
package, it is found.
This requires a sweeping set of changes in the test suite, but
ensures that we get "safe" behavior from the solver. We have
in particular seen that without asserting the installed packages,
several people ended up with ubuntu-minimal and perl removed in
a situation where that was not warranted, that is, they install
winehq, and then pull in some new perl packages in a newer version
than the installed one, and the solver chose to create a mismatched
version set, which then caused the main perl package to not be
installable.
Oops: 1b55173a-3526-11f0-b7ac-fa163e171f02
Oops: dbd5149e-36b9-11f0-bb74-fa163ec44ecd
|
| |
|
|
|
|
|
|
| |
If the user pushes Assumptions that fail, we could inadvertently
timeout during the Pop() as the variable was not initialized.
Always initialize it to 0, and if we haven't set an actual time
by the time we Pop() set it there.
|
| |
|
|
|
|
| |
This can be used to compare arbitrary packages in non-dependency
contexts. It remains to be seen whether this is a meaningful
approach.
|
| |
|
|
|
|
|
|
|
| |
We sometimes enqueue no choice as the choice, specifically when
an optional clause became unsat as we need to reenqueue it on
undo.
But of course, this breaks undoing stuff because now it tries to
insert !root and then solver breaks.
|
| |
|
|
|
|
|
|
|
|
|
| |
If an Assume() failed, we will have pushed the choices stack,
but not actually pushed anything to the solved stack.
This would cause a segmentation fault trying to read the referenced
entry that doesn't actually exists, namely solved[solved.size()].
Handle this by exiting early as there's nothing to do except
pop the entry back out of the array.
|
| |
|
|
|
|
|
|
|
|
|
|
| |
Instead of having the historic choice here, follow MiniSAT and
use the assigned variable from the tail. This should also make
the Assume() function work now, albeit we still need to actually
migrate to it.
This is a first step towards refactoring the Solve() loop to use
a propagate/find next literal/assume it kind of loop, albeit there
is a bit more to prepare there as we need to also reinsert work
items when backtracking.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
The function getline is used to read data from different streams, however,
the error handling is not accurate.
From the man page, getline returns -1 on failure and sets errno accordingly,
but the current implementation only checks errno to see if there was a
failure. With this approach, in case getline returns success but also sets
errno it is consider and error.
Fix the issue but also checking the return value of getline.
Signed-off-by: Walter Lozano <walter.lozano@collabora.com>
|
| |
|
|
|
|
|
|
|
|
|
| |
These are implemented somewhat differently from aptitudes
why and why-not commands: They produce the actual solver
trace for why a particular decision has been taken.
For the why-not case, we need to explicitly discover our
specified package, as if nothing else depends on it in
our graph, it would otherwise always be undiscovered and
conflicts not detected (see e.g. level-3 in the test).
|
| | |
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
'Include' allows limiting a repository to a allowlist of packages,
'Exclude' allows removing packages from a repository.
Implementation wise this is not the nicest as it goes via the
IndexTarget options, so we first parse our option value into a
vector, then we turn the vector into a string, and then vectorize
it again. That said, we support both "," and " " as separators due
to the construction (we split by "," then we join using " ").
Gbp-Dch: full
|
| |
|
|
|
|
|
|
|
|
| |
As a followup to the previous commit, restore the exact behavior
of the old solver to break the Suggests on upgrade here by erasing
any choices not previously installed.
This ensures that the Suggests never installs any new package, but
it will still retain previously installed packages when solver3 is
doing autoremove.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
In #2103556 we can see that avahi-daemon Suggests avahi-autoipd,
which is previously satisfied by dhcpcd-base due to a Provides;
that Provides has now been dropped; and solver3 keeps the update
back.
As in LP: #2102720 this is a Suggests and it seems wrong for the
Suggests to actually influence dependency choices and be able to
hold back updates.
Instead, satisfy previously satisfied Suggests at the end. For the
particular case in this bug report, this results in avahi-autoipd,
the real package, to be installed to keep the Suggests working
which needs further consideration whether that is the right choice
(we can argue either way), but in any case this is a better solution.
This in turn breaks the conkeror test which is a somewhat awkward
unrealistic test these days as it has no automatically installed
packages; because previously something must have had a Suggests
on say libdatrie1 or something that was processed first.
This would be fine before 5daf6dbfd272be2f8e3c59d4bab4be8c119b7aa1
but as of that commit we no longer rewrite
conkeror Depends xulrunner-1.9 | xulrunner-1.9.1
into
conkeror Depends xulrunner-1.9.1 | xulrunner-1.9
Because xulrunner-1.9 is manually installed. Mark xulrunner-1.9
as automatically installed to fix the test case.
The resulting behavior seems correct: If you manually want
xulrunner-1.9 specifically we should not replace it with
xulrunner-1.9.1; but if it's automatically installed we should.
LP: #2103556
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
When discovering packages we look at the manual flag to avoid
reordering obsolete manually installed packages last.
We inadvertently initialized that flag interlaced with discovering
packages so if we discovered packages depending on obsolete, but
manually installed, packages first, we were not aware they were
manually installed and demoted them.
I am struggling to come up with a test case for this as I can't
get the package objects in the cache to be in the right order for
the bug to trigger.
LP: #2102720
|
| | |
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
Add a variant of WriteLimitedScenario that does not take a pkgset,
but creates one on the fly based on the transitive closure of installed
packages, to be installed packages, and their dependencies and provides.
This includes more packages than strictly necessary, i.e. we do not
really need to include foo just because a package we want to install
Conflicts with it, but oh well, this is easy to read.
Trying to extend the filtering is hard as the dependencies being written
are also filtered...
|
| |
|
|
|
| |
We created a very slow zstd, we don't default to high levels
for other compressors...
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
With older compilers (g++ and clang from Bookworm), static_assert(false)
will result in:
/home/josch/git/apt/build/include/apt-pkg/solver3.h:52:24: error: static assertion failed: Cannot construct map for key type
52 | static_assert(false, "Cannot construct map for key type");
| ^~~~~
This commit implements the terrible but more valid workaround according to:
https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2593r0.html
Original solution from here:
https://stackoverflow.com/questions/14637356/static-assert-fails-compilation-even-though-template-function-is-called-nowhere/14637534#14637534
That way, apt will compile with compilers in Bookworm again.
|
| |
|
|
|
|
|
|
| |
Particularly as Helmut pointed out we need to show which version we
selected for install if there is only one but there is a versioned
conflicts.
Reported-By: Helmut Grohne <helmut@subdivi.de> on IRC
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Reorder the if branches a bit to simplify the understanding
of the promotions, and allow us to keep track of which
dependency existed in the installed version.
Change the rule for promoting new recommends to only promote
new recommends to depends in *upgrade* and not *dist-upgrade*
per the test-resolve-by-keep-new-recommends test case.
This makes some sense: In a dist-upgrade, the solver could
otherwise decide to remove an installed package if both the
following hold:
(1) something needs the upgraded version | something else
(2) the upgraded version is not installable due to unsat recommends
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
We accidentally considered an Enhances a reason to keep
a package installed, which of course it is not, fix the
determination of "existing soft dependency" to only include
soft dependencies that should keep a package installed in
the autoremover to solve the issue.
This also fixes edsp/mantic-upgrade-rel-to-2024-05-29.edsp
to not install llvm-13-dev for clang-13 which is an installed
package with no upgrade.
Also ensure we stop after the first match; the DependsList()
is ordered by decreasing priority and we don't want to override
Recommends by Suggests in case a package declares both...
LP: #2101800
|