Re: [PATCH v9 4/5] liveupdate: luo_flb: Introduce File-Lifecycle-Bound global state

From: David Matlack

Date: Thu Mar 12 2026 - 19:59:47 EST


On Thu, Dec 18, 2025 at 7:58 AM Pasha Tatashin
<pasha.tatashin@xxxxxxxxxx> wrote:

> +static inline int liveupdate_register_flb(struct liveupdate_file_handler *fh,
> + struct liveupdate_flb *flb)
> +{
> + return -EOPNOTSUPP;
> +}

I think LUO could use a cleanup to return 0 in all the register
functions when Live Update is not enabled via CONFIG or parameter.

I think all of the users of these functions are going to want to
ignore -EOPNOTSUPP. memfd already does.

> +static int luo_flb_retrieve_one(struct liveupdate_flb *flb)
> +{
> + struct luo_flb_private *private = luo_flb_get_private(flb);
> + struct luo_flb_header *fh = &luo_flb_global.incoming;
> + struct liveupdate_flb_op_args args = {0};
> + bool found = false;
> + int err;
> +
> + guard(mutex)(&private->incoming.lock);
> +
> + if (private->incoming.finished)
> + return -ENODATA;
> +
> + if (private->incoming.retrieved)
> + return 0;
> +
> + if (!fh->active)
> + return -ENODATA;
> +
> + for (int i = 0; i < fh->header_ser->count; i++) {
> + if (!strcmp(fh->ser[i].name, flb->compatible)) {
> + private->incoming.data = fh->ser[i].data;
> + private->incoming.count = fh->ser[i].count;
> + found = true;
> + break;
> + }
> + }
> +
> + if (!found)
> + return -ENOENT;

FLB users have no way to distinguish between "there was no data
preserved" and "there was data preserved, but it was not a supported
version".

This is especially going to be important for PCI [1] since there's a
big difference between "there were no devices preserved" and "there
were devices preserved but the incoming kernel isn't compatible". The
former means there's nothing for the PCI subsystem to do wrt Live
Update. The latter means we should probably panic the system.

[1] https://lore.kernel.org/kvm/20260129212510.967611-3-dmatlack@xxxxxxxxxx/

> +/**
> + * liveupdate_unregister_flb - Remove an FLB dependency from a file handler.
> + * @fh: The file handler that is currently depending on the FLB.
> + * @flb: The File-Lifecycle-Bound object to remove.
> + *
> + * Removes the association between the specified file handler and the FLB
> + * previously established by liveupdate_register_flb().
> + *
> + * This function manages the global lifecycle of the FLB. It decrements the
> + * FLB's usage count. If this was the last file handler referencing this FLB,
> + * the FLB is removed from the global registry and the reference to its
> + * owner module (acquired during registration) is released.
> + *
> + * Context: This function ensures the session is quiesced (no active FDs
> + * being created) during the update. It is typically called from a
> + * subsystem's module exit function.
> + * Return: 0 on success.
> + * -EOPNOTSUPP if live update is disabled.
> + * -EBUSY if the live update session is active and cannot be quiesced.
> + * -ENOENT if the FLB was not found in the file handler's list.
> + */
> +int liveupdate_unregister_flb(struct liveupdate_file_handler *fh,
> + struct liveupdate_flb *flb)

Alex Williamson and Jason Gunthrope both suggested this should return void.

https://lore.kernel.org/kvm/20260303210733.GG972761@xxxxxxxxxx/

I suspect liveupdate_unregister_file_handler() should as well. I don't
think there's anything callers can do if unregister fails.