Re: [PATCH v3 00/10] liveupdate: Preserve tmpfs files across Live Update
From: Christian Brauner
Date: Thu Nov 05 2026 - 10:56:36 EST
On Tue, Nov 03, 2026 at 01:02:06AM +0000, David Matlack wrote:
> The kernel preserves the contents, size, file position and seals of each
> file. After the Live Update, userspace retrieves each file onto a tmpfs
> mount of its choice and links it at the path of its choice, so userspace
> decides the directory structure, names, owners and permissions of the
> restored files.
[...]
> 4. Retrieve files that were preserved from a tmpfs mount onto a tmpfs
> mount chosen by userspace, via the new struct
> liveupdate_shmem_retrieve_arg. The kernel creates the file as if by
> openat(dirfd, ".", O_TMPFILE | flags, mode), so the file gets the
> same flags, owner, permission checks and security labels as any
> other new file in that directory, and is charged to that mount.
> The kernel fills the file before returning it, so nothing else can
> access the file before it is complete, and userspace links it at
> the path it wants with linkat() (patch 7).
No, sorry. That's not what we discussed at LPC and it's not what the RFC
and v1 did.
There userspace created the file and LUO filled in the contents. That
got turned around in the v1 thread and I think that was a big mistake.
The kernel is now responsible for creating the file and for its
permissions but it preserves none of that? No owner, no mode, no
xattrs, no security labels, nothing.
Instead userspace passes a struct that duplicates the open() argument
list and the kernel runs umask, setgid inheritance, default ACLs and LSM
labeling on it. That makes no sense whatsoever. Either the kernel owns
the metadata as well or it stays out of it completely.
Spoiler, it should stay out of it.
Userspace is responsible for everything but the contents. Take systemd
wanting to preserve a whole tmpfs. We already know how that works and
discussed that at LPC with you.
- We generate a manifest of the filesystem ith every file with its owner,
mode and xattrs using UAPI.17 manifests (cf. [1]).
We stash it in a memfd and reassemble the tree in userspace after the
live update. All it needs from the kernel are the contents. Having the
kernel recreate any of that is pointlessly complex.
So instead of LUO handing out a file descriptor for a file it invented,
let userspace create the file, O_TMPFILE, O_CREAT, whatever it likes,
with the owner, mode and xattrs it wants, and let LUO put the contents
into it. That's what the RFC did.
The checks on the target are trivial: a writable fd to an empty shmem
file with the inode lock held while you fill it. A tmpfs file can't be
sealed, it only ever has F_SEAL_SEAL, so there's nothing to restore but
contents and size anyway.
Pasha, your argument for creating the file in the kernel was that
nobody can reach it while it's being filled. **That's what O_TMPFILE is
for**: Userspace creates it unlinked, LUO fills it, userspace links it.
If userspace hands a half-filled file to iommufd that's its own problem.
I also really dislike file_open_root() for this. It's an openat()
emulation inside an ioctl which is completely terrible.
It redoes the openat2() validation by hand (reject O_PATH, unknown
flags, stray mode bits), force O_LARGEFILE, and because O_TMPFILE
insists on write access you open the file O_RDWR, copy the normalized
f_flags out of the first struct file, dentry_open() the same path a
second time read-only without any permission check and drop the first
file again.
So an LSM sees an O_RDWR open for what userspace asked to be O_RDONLY.
Whatever path_openat() happens to do for that synthesized flag
combination becomes LUO's behavior. That's brittle as fsck. All of it
goes away when userspace is responsible for that.
Fwiw, the permission model you end up with on retrieve is write and
search permission on the target directory, i.e. vfs_tmpfile()'s
inode_permission(dir, MAY_WRITE | MAY_EXEC) plus mnt_want_write() on
that mount. The new inode is owned by whoever runs the ioctl with
whatever mode they asked for. Nothing about the original file matters.
IOW, the kernel has nothing to contribute here that open() doesn't
already do.
Really, please make the kernel's job stupidly simple: let userspace get
the contents and let it be responsible for the actual complex restore
and the filesystem layout.
A hybrid helps absolutely no one.
> - Is patch 9 (retrieving tmpfs files with O_RDONLY) worth merging?
No. With userspace creating the file this doesn't exist.
> are created with mode 0777 (or 0666). Is this the right permission
> model for preserving files? Should this apply all files or just
> shmem files?
The preserve side seems fine to me. If you freeze the size of a file
for everyone you better be allowed to write to it.
[1]: https://uapi-group.org/specifications/specs/file_manifest/