On Wed, Jun 17, 2026 at 03:52:27PM +0200, Petr Mladek wrote:
> On Tue 2026-06-16 16:15:17, Joe Lawrence wrote:
> > On Thu, Jun 11, 2026 at 02:58:39PM +0200, Petr Mladek wrote:
> > > On Tue 2026-06-09 18:00:55, Petr Mladek wrote:
> > > > On Sun 2026-06-07 21:16:55, Yafang Shao wrote:
> [ ... snip ... ]
> > I'm not against supercedes functionality, but continuing the
> > brainstorming: what about solution 1 (.replace_set=0 special) with a
> > special zero-day overlay?
>
> I continue with the brainstorming ;-)
>
Thanks for walking through it with me. Your reply crossed with my note
to Yafang at nearly the same time.
> [ ... snip ... ]
> > So maybe it boils down to: is the supercedes big hammer desired and safe
> > enough to deploy?
>
> I personally like the solution with a zero-terminated array of
> replace_sets:
>
> struct patch {
> [...]
> unsigned int *replace_sets;
> [...],
> };
>
> , which would allow to build a cumulative livepatch which replaces
> known hotfixes out of box.
>
Question on this at the bottom ...
> Note that the hotfix should not be allowed to modify a function or
> livepatch state which is modified by another livepatch. It would
> be dangerous. We should allow to solve this only by a cumulative
> livepatch.
>
Agreed.
> IMHO, the OS vendor should not touch customer specific livepatches
> by default. The customer installed them for a reason. We should
> just refuse to install two conflicting livepatches. Where
> we could reliably compare only the livepatched functions.
> But it still is good because most livepatches only modify
> functions.
>
> Plus, I would still allow to resolve the possible conflict by using
> the atomic replace. It could be done by a module-specific parameter.
> I would call it: override_replace_sets=X[,Y]... or so.
>
Naming nitpick: "override_replace_sets" sounds like it may override the
"replace_sets" value and not supplement it. But that's just an
implementation detail to bikeshed later :D
> Finally, I assume that most users will keep using only the default
> replace_sets=0 [*]. They will never have to deal with another sets.
>
> The non-default replace sets will be only for adventurous users
> who want to deal with the complexity and accept the risks.
>
> [*] It we allow the zero-terminated array of replace_sets then
> zero should not be the default. Or it could be but it would
> be a special set which could never be replaced by anything
> else than another zero replace set.
>
> The zero replace set might be for users who do not want to
> deal with the complexity at all. For example, for an os-vendor
> who does not want to release separate hotfixes.
>
Hmm, I do like the default replace_sets=0 not dealing with the
complication of the replace sets.
But first, back to the larger question I mentioned at the beginning.
Originally there was:
unsigned int replace_set; /* the set I belong to */
const unsigned int *supersedes; /* other sets I also replace */
and now it's just:
unsigned int *replace_sets; /* sets I belong to AND replace? */
Could you trace through a few cycles of cumulative + hotfix releases with
this approach? For example:
Wed: klp-1a: cumulative (replace_sets={1})
Thu: klp-1b: hotfix (replace_sets={2}) <- coexists with klp-1a
Fri: klp-1c: hotfix v2 (replace_sets={2}) <- replaces klp-1b (same
set)
Mon: klp-2a: cumulative (replace_sets={1,2}) <- replaces klp-1a AND
wipes klp-1c *
Tue: klp-2b: hotfix (replace_sets={2}) <- coexists with klp-2a
[*] After klp-2a loads with {1, 2}, is it permanently in both sets? Or
does it just evict set 2 and then only occupy set 1 going forward? The
latter makes klp-2b's load straightforward.
I can read replace_sets two ways:
1. Positional: { set [, eviction_set ...] } where the first element is
the patch's own set and the rest are evicted on load.
2. Flat: the patch belongs to every listed set equally. But then how
could klp-2b load into set 2 without replacing the entire
cumulative klp-2a that also occupies it?
Thanks,
--
Joe