Re: [RFC v1 1/3] luo: Live Update Orchestrator
From: Jason Gunthorpe
Date: Mon Mar 31 2025 - 12:37:51 EST
On Thu, Mar 27, 2025 at 03:29:18PM -0400, Pasha Tatashin wrote:
> Here’s a summary of the planned approach:
>
> 1. Unified Location: LUO will be moved under misc/liveupdate/ to house
> the consolidated functionality.
It make sense to me, and I prefer all this live update stuff be as
isolated and "side car" as possible to keep the normal kernel flow
simple..
> 2. User Interfaces: A primary character device (/dev/liveupdate)
> utilizing an ioctl interface for control operations. (An initial draft
> of this interface is available here:
> https://raw.githubusercontent.com/soleen/linux/refs/heads/luo/rfc-v2.1/include/uapi/linux/liveupdate.h)
That looks like a pretty comprehensive view
I'd probably nitpick some things but nothing fundamental..
You *may* want to look at drivers/fwctl/main.c around fwctl_fops_ioctl
for some thoughts on how to structure an ioctl implementation to be
safely extensible. You can even just copy that stuff, I copied it
already from iommufd..
Little confusing how you imagine to use UNPRESERVE_XX, EVENT_CANCEL
and close() as various error handling strategies? Especially depending
on how we are able to "freeze" a file descriptor.
> An optional sysfs interface will allow userspace applications to
> monitor the LUO's state and react appropriately. e.g. allows SystemD
> to load different services during different live update states.
Make sense, systemd works alot better with a sysfs file for knowing if
the boot is a kexec live update boot or not.
Though I don't know why you'd keep /sys/kernel/liveupdate/prepare and
others ? It seems really weird that something would be able to safely
sequence the update but not have access to the FD?
> 3. Dependency Management: The viability of preserving a specific
> resource (file, device) will be checked when it initially requests
> participation.
> However, the actual dependencies will only be pulled and the final
> ordered list assembled during the prepare phase. This avoids the churn
> of repeatedly adding/removing dependencies as individual components
> register.
Maybe, will have to see how the code works out in practice with real
implementations. I did not imagine having a full "unprepare" idea
since that significantly complicates everything. close() would just
nuke everything.
> struct liveupdate_fs_handle {
> struct list_head liveupdate_entry;
Don't mix data and const function pointers..
> int (*prepare)(struct file *filp, void *preserve_page, ...); // Callback during prepare phase
> int (*reboot)(struct file *filp, void *preserve_page,...); // Callback during reboot phase
> void (*finish)(struct file *filp, void *preserve_page,...); // Callback after successful update to do state clean-up
> void (*cancel)(struct file *filp, void *preserve_page,...); // Callback if prepare/reboot is cancelled
> };
But it makes sense over all
> Preserved File Descriptors (e.g., memfd, kvmfd, iommufd, vfiofd)
> Preserved Devices (ordered appropriately, leaves-to-root)
I think because of the cyclic ordering between kvm/iommu/vfio it may
become a bit complicated. You will want LIVEUPDATE_IOCTL_FD_PRESERVE
to not check dependencies but leave some kind of placeholder so the
cycles can be broken.
> Global State Components
You may need a LIVEUPDATE_IOCTL_GLOBAL_PRESERVE as well to select
these?
Jason