This series allows preserving files in tmpfs via LUO to survive across a
live update, and allows userspace to decide when to freeze a session
instead of delaying until auto-freeze at kexec time. Once userspace is
done with a session, it can freeze the session immediately (and across
multiple sessions in parallel), reducing blackout time by not postponing
this operation to kexec shutdown where all sessions are frozen serially:
1. Early session freeze (LIVEUPDATE_SESSION_FREEZE):
Currently, LUO sessions are frozen automatically only inside the
reboot(LINUX_REBOOT_CMD_KEXEC) path, where luo_session_serialize()
iterates through all outgoing sessions under global write locks and
freezes them serially during shutdown.
Add the LIVEUPDATE_SESSION_FREEZE ioctl on session file descriptors so
userspace can freeze a session as soon as it is done with it (and freeze
multiple sessions concurrently, since luo_session_freeze() only acquires
the per-session mutex). During kexec, already-frozen sessions skip the
late auto-freeze step; if an early-frozen session is closed before
kexec, its files are rolled back via .unfreeze() before being
unpreserved.
2. Per-file user argument on preserve and retrieve:
File handlers may need handler-specific context when preserving or
retrieving a file descriptor without introducing custom session ioctls
for each file type. Whether the argument is required, optional, or
unused depends on the file handler.
Extend struct liveupdate_session_preserve_fd and
struct liveupdate_session_retrieve_fd with a 64-bit 'arg' field pointing
to a handler-defined argument structure that begins with a 32-bit 'size'
field. Because IOCTL_OP validates a minimum struct size up to 'token',
existing userspace callers passing the 16-byte structure remain
backward-compatible and have 'arg' zero-filled by
copy_struct_from_user().
Add parg and rarg (struct liveupdate_arg_spec) to
struct liveupdate_file_ops, initialized via LIVEUPDATE_ARG(_struct,
_min_last), which records the full struct size and minimum required
size while enforcing at compile time that the argument structure begins
with a 32-bit 'size' field. Core LUO validates the minimum size and
copies non-zero user arguments via copy_struct_from_user() up to the
handler's expected size (or rejects them with -EOPNOTSUPP when the
handler does not accept an argument) and passes the kernel copy to
.preserve() and .retrieve() in struct liveupdate_file_op_args. Also
allow .retrieve() callbacks to mark early argument/target validation
failures as retryable so userspace can retry
LIVEUPDATE_SESSION_RETRIEVE_FD without losing preserved KHO state.
3. Tmpfs file preservation and retrieval:
Using the file handler retrieve argument, extend mm/memfd_luo to allow
preserving generic shmem-backed tmpfs files (not just unlinked memfd
pseudofiles), recording MEMFD_LUO_FLAG_TMPFS in
struct memfd_luo_ser.flags so that preserved tmpfs files must be
retrieved as tmpfs files and preserved memfd files must be retrieved as
memfd files. Introduce struct liveupdate_memfd_retrieve_arg so
userspace can pass a writable, empty, linked tmpfs file descriptor via
the retrieve argument and have the kernel populate its address space
with the preserved folios.
David Matlack (2):
mm/memfd_luo: Support tmpfs preservation and retrieval
selftests: liveupdate: Add test coverage for tmpfs preservation and
retrieval
Pasha Tatashin (5):
liveupdate: Add LIVEUPDATE_SESSION_FREEZE ioctl to freeze sessions
early
selftests: liveupdate: Add tests for LIVEUPDATE_SESSION_FREEZE
liveupdate: Pass user argument to file preserve and retrieve
selftests: liveupdate: Add tests for preserve and retrieve user
argument
liveupdate: Allow file handlers to mark retrieve failures as retryable
include/linux/kho/abi/memfd.h | 13 +-
include/linux/liveupdate.h | 74 ++++++++-
include/uapi/linux/liveupdate.h | 59 ++++++-
kernel/liveupdate/luo_file.c | 152 ++++++++++++++----
kernel/liveupdate/luo_internal.h | 8 +-
kernel/liveupdate/luo_session.c | 58 ++++++-
mm/memfd_luo.c | 144 +++++++++++++----
.../liveupdate/lib/include/libliveupdate.h | 6 +
.../selftests/liveupdate/lib/lu_utils.c | 71 +++++++-
.../testing/selftests/liveupdate/liveupdate.c | 84 ++++++++++
.../selftests/liveupdate/luo_kexec_simple.c | 5 +
.../selftests/liveupdate/luo_multi_session.c | 110 +++++++++++--
12 files changed, 695 insertions(+), 89 deletions(-)
base-commit: cee9395acd8043be0644b25c34bfa86623f2b935
--
2.56.0.385.gd3acb90ef8-goog