[RFC PATCH v2 3/4] liveupdate: Replace compatibility string with a 2-bit pair feature header

Pasha Tatashin pasha.tatashin at soleen.com
Wed Oct 21 18:26:06 PDT 2026


On Wed, Oct 21, 2026 at 7:28 PM David Matlack <dmatlack at google.com> wrote:
>
> On 2026-10-21 02:50 PM, Pasha Tatashin wrote:
> > On Wed, Oct 21, 2026 at 2:47 PM David Matlack <dmatlack at google.com> wrote:
> > >
> > > On Wed, Oct 21, 2026 at 11:40 AM <tarunsahu at google.com> wrote:
> > > >
> > > > Pasha Tatashin <pasha.tatashin at soleen.com> writes:
> > > >
> > > > > On Wed, Oct 21, 2026 at 11:25 AM Tarun Sahu <tarunsahu at google.com> wrote:
> > > > >>
> > > > >> LUO and its file handlers validate handed-over state with monolithic
> > > > >> compatibility strings ("luo-v5", "memfd-v2"). Any change to a serialized
> > > > >> structure, even an optional additive one, must bump the string, which
> > > > >> breaks live update between adjacent kernels. Replace the string in
> > > > >> struct luo_ser with a feature header, so that the target kernel can
> > > > >> accept or reject the source kernel state per feature.
> > > > >>
> > > > >> struct luo_feature_hdr is a fixed 128-byte header: the serialized
> > > > >
> > > > > This patch is all wrong; 128 bytes is far too large. For every _ser
> > > > > struct, we only need 8 bytes instead.
> > > >
> > > > NOO, It is not. It is intended to avoid complex mess with unnecessary
> > > > over-engineering.
> >
> > 128-byte per serialized struct is not starter.
> >
> > > >
> > > > >
> > > > > The first 4 bytes are the size, and the next 4 bytes are flags (i.e.,
> > > > > 30 feature flags + 2 reserved bits for flags extension). The last two
> > > > > bits of the flags indicate whether an extended flags field is present.
> > > > > Each extended flags field is 8 bytes, and its last two bits indicate
> > > > > that yet another extended flags field follows.
> > > >
> > > > If we will have dynamic extension of flags, Think about this.
> > >
> > > To support dynamic extensions in a backward compatible way you want
> > > something like this:
> > >
> > > struct luo_feature_hdr {
> > >    size
> > >    flags
> >
> > __u32 size
> > __u32 flags
> >
> > >    extensions  // offset of first luo_feature_extensions (or 0)
> >
> > __u64 extensions[0]  --> but the size should be specificed in
> > declaration macro that I showed in the next patch.
>
> I think you may have misunderstood what I meant. In my proposal,
> extensions is an offset to the first extension, not an array of
> extensions that immediately follow the header.
>
> If the extensions immediately follow the header, then the number of
> extensions is baked into the struct layout. Every field after them sits
> at an offset that depends on how many extensions there are. If we ever
> need one more extension, all the fields shift and old and new kernels
> can no longer read each other's struct. That is the problem Tarun

We can structure it cleanly by nesting the payload: something like
struct { struct header {...}h; struct serialize_data { ... }p; };
That way, the header can expand dynamically at the front, while all
fields inside `serialize_data` stay at fixed offsets relative to the
start
of the payload.

Since the header size is self-describing via continuation bits (e.g.,
the last two bits indicating whether another flag word follows), LUO
can
easily compute where the payload begins in the incoming blob. This
keeps the implementation simple, avoids linked lists of offsets.



More information about the kexec mailing list