<feed xmlns='http://www.w3.org/2005/Atom'>
<title>apt/apt-pkg, branch 3.1.3</title>
<subtitle>Debians commandline package manager</subtitle>
<id>https://git.kalnischkies.de/apt/atom?h=3.1.3</id>
<link rel='self' href='https://git.kalnischkies.de/apt/atom?h=3.1.3'/>
<link rel='alternate' type='text/html' href='https://git.kalnischkies.de/apt/'/>
<updated>2025-06-24T16:47:18Z</updated>
<entry>
<title>Fix stuck acquire queues on partial server errors</title>
<updated>2025-06-24T16:47:18Z</updated>
<author>
<name>Julian Andres Klode</name>
<email>jak@debian.org</email>
</author>
<published>2025-06-24T14:52:06Z</published>
<link rel='alternate' type='text/html' href='https://git.kalnischkies.de/apt/commit/?id=5378c38db0a5dedef34fdf35e357f76c104d717a'/>
<id>urn:sha1:5378c38db0a5dedef34fdf35e357f76c104d717a</id>
<content type='text'>
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=&lt;something&gt;, 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
</content>
</entry>
<entry>
<title>Include standard headers to fix clang compiler error</title>
<updated>2025-06-18T14:03:24Z</updated>
<author>
<name>Biswapriyo Nath</name>
<email>nathbappai@gmail.com</email>
</author>
<published>2025-06-18T14:03:19Z</published>
<link rel='alternate' type='text/html' href='https://git.kalnischkies.de/apt/commit/?id=06d0c12be00ee50c965830127f5812d2156681b1'/>
<id>urn:sha1:06d0c12be00ee50c965830127f5812d2156681b1</id>
<content type='text'>
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'
</content>
</entry>
<entry>
<title>solver3: Avoid FTBFS with g++ 14.2 on arm{el,hf}</title>
<updated>2025-06-10T18:51:09Z</updated>
<author>
<name>Julian Andres Klode</name>
<email>jak@debian.org</email>
</author>
<published>2025-06-10T18:51:09Z</published>
<link rel='alternate' type='text/html' href='https://git.kalnischkies.de/apt/commit/?id=d9b87e3e2b2615eb3be1e6a4413aa18384f04328'/>
<id>urn:sha1:d9b87e3e2b2615eb3be1e6a4413aa18384f04328</id>
<content type='text'>
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 /&lt;&lt;PKGBUILDDIR&gt;&gt;/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&lt;_Tp, _Alloc&gt;::~_Vector_base() [with _Tp = APT::Solver::Work; _Alloc = std::allocator&lt;APT::Solver::Work&gt;]’:
    /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 /&lt;&lt;PKGBUILDDIR&gt;&gt;/apt-pkg/edsp.cc:22:
    /&lt;&lt;PKGBUILDDIR&gt;&gt;/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&lt;_Tp, _Alloc&gt;::~_Vector_base() [with _Tp = APT::Solver::Solved; _Alloc = std::allocator&lt;APT::Solver::Solved&gt;]’:
    /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);
          |                       ~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~
    /&lt;&lt;PKGBUILDDIR&gt;&gt;/obj-arm-linux-gnueabihf/include/apt-pkg/solver3.h:88:11: note: forward declaration of ‘struct APT::Solver::Solved’
       88 |    struct Solved;
          |           ^~~~~~
</content>
</entry>
<entry>
<title>Avoid cast alignment warning in cache string view</title>
<updated>2025-06-10T15:29:33Z</updated>
<author>
<name>Julian Andres Klode</name>
<email>jak@debian.org</email>
</author>
<published>2025-06-10T15:23:41Z</published>
<link rel='alternate' type='text/html' href='https://git.kalnischkies.de/apt/commit/?id=ed836aa73a87b9d60e81c607d5b4f57e9b82f948'/>
<id>urn:sha1:ed836aa73a87b9d60e81c607d5b4f57e9b82f948</id>
<content type='text'>
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.
</content>
</entry>
<entry>
<title>solver3: Filter installed Recommends</title>
<updated>2025-06-10T14:27:36Z</updated>
<author>
<name>Julian Andres Klode</name>
<email>jak@debian.org</email>
</author>
<published>2025-06-10T14:09:19Z</published>
<link rel='alternate' type='text/html' href='https://git.kalnischkies.de/apt/commit/?id=b99ec5f1d80962e39e9debb05f1a7c7840e7d97c'/>
<id>urn:sha1:b99ec5f1d80962e39e9debb05f1a7c7840e7d97c</id>
<content type='text'>
When inspecting Recommends of installed packages, filter
them to the installed packages only, as we want to avoid
switching between alternatives of recommended packages.
</content>
</entry>
<entry>
<title>solver3: Explicitly declare and define ~Solver</title>
<updated>2025-06-10T14:27:36Z</updated>
<author>
<name>Julian Andres Klode</name>
<email>jak@debian.org</email>
</author>
<published>2025-06-10T11:44:18Z</published>
<link rel='alternate' type='text/html' href='https://git.kalnischkies.de/apt/commit/?id=060f4e274f08ea338158606fc81b451924a293d0'/>
<id>urn:sha1:060f4e274f08ea338158606fc81b451924a293d0</id>
<content type='text'>
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 /&lt;&lt;PKGBUILDDIR&gt;&gt;/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&lt;_Tp, _Alloc&gt;::~_Vector_base() [with _Tp = APT::Solver::Work; _Alloc = std::allocator&lt;APT::Solver::Work&gt;]’:
/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 /&lt;&lt;PKGBUILDDIR&gt;&gt;/apt-pkg/edsp.cc:22:
/&lt;&lt;PKGBUILDDIR&gt;&gt;/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&lt;_Tp, _Alloc&gt;::~_Vector_base() [with _Tp = APT::Solver::Solved; _Alloc = std::allocator&lt;APT::Solver::Solved&gt;]’:
/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);
      |                       ~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~
/&lt;&lt;PKGBUILDDIR&gt;&gt;/obj-arm-linux-gnueabihf/include/apt-pkg/solver3.h:88:11: note: forward declaration of ‘struct APT::Solver::Solved’
   88 |    struct Solved;
      |           ^~~~~~
</content>
</entry>
<entry>
<title>solver3: Ignore Architecture: all for obsoleted-by</title>
<updated>2025-06-10T14:27:36Z</updated>
<author>
<name>Julian Andres Klode</name>
<email>jak@debian.org</email>
</author>
<published>2025-06-10T09:47:41Z</published>
<link rel='alternate' type='text/html' href='https://git.kalnischkies.de/apt/commit/?id=15f48dcd65fb17a4cb4cd1f93b872b3bb810c3b2'/>
<id>urn:sha1:15f48dcd65fb17a4cb4cd1f93b872b3bb810c3b2</id>
<content type='text'>
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.
</content>
</entry>
<entry>
<title>solver3: Only merge dependencies on the same package</title>
<updated>2025-05-28T11:58:04Z</updated>
<author>
<name>Julian Andres Klode</name>
<email>jak@debian.org</email>
</author>
<published>2025-05-28T11:57:17Z</published>
<link rel='alternate' type='text/html' href='https://git.kalnischkies.de/apt/commit/?id=3f8162ea008b8a3330a1113a94bc654f05000660'/>
<id>urn:sha1:3f8162ea008b8a3330a1113a94bc654f05000660</id>
<content type='text'>
Avoid or groups and dependencies on different (virtual) packages,
to avoid some common pitfalls like the added xorg test case.
</content>
</entry>
<entry>
<title>solver3: Merge Depends into Recommends</title>
<updated>2025-05-27T14:06:06Z</updated>
<author>
<name>Julian Andres Klode</name>
<email>jak@debian.org</email>
</author>
<published>2025-05-27T12:24:09Z</published>
<link rel='alternate' type='text/html' href='https://git.kalnischkies.de/apt/commit/?id=86c44166b470ecee5a192ffb434fb7931b7c0afd'/>
<id>urn:sha1:86c44166b470ecee5a192ffb434fb7931b7c0afd</id>
<content type='text'>
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.
</content>
</entry>
<entry>
<title>solver3: Merge intersecting dependencies</title>
<updated>2025-05-27T13:56:55Z</updated>
<author>
<name>Julian Andres Klode</name>
<email>jak@debian.org</email>
</author>
<published>2025-05-27T12:24:09Z</published>
<link rel='alternate' type='text/html' href='https://git.kalnischkies.de/apt/commit/?id=eafc52e942d4daec30fb80e70c035ed935f31afb'/>
<id>urn:sha1:eafc52e942d4daec30fb80e70c035ed935f31afb</id>
<content type='text'>
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 (&gt;&gt; 1:2.26.2), git (&lt;&lt; 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 (&gt;&gt; 1:2.26.2)
    "real git" (= 1:2.25.1-1) to satisfy git (&lt;&lt; 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 (&gt;&gt; 1:2.26.2) and git (&lt;&lt; 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
</content>
</entry>
</feed>
