Re: [RFC] connectat()/bindat() or an alternative design
From: John Ericson <hidden>
Date: 2026-07-02 03:23:05
Also in:
linux-fsdevel
On Wed, Jul 1, 2026, at 8:32 PM, Cong Wang wrote:
Hm? Why not just setsockopt()? Something like:
struct unix_lookup_ctx {
int dirfd;
__u64 resolve_flags; /* RESOLVE_BENEATH, RESOLVE_NO_SYMLINKS, etc. */
__u64 op_flags; /* maybe future */
};
setsockopt(fd, SOL_UNIX, UNIX_NEXT_LOOKUP,
&ctx, sizeof(ctx));
bind(fd, (struct sockaddr *)&addr, addrlen);
/* or connect(fd, ...) */
Zero new syscall is needed.
If this supports the `AT_EMPTY_PATH` no filesystem at all use-case
(which is what I chose to highlight in the previous summary email), I'll
take it --- it hits my desiderata. But implementation-side, I don't
relish the thought of even more state for socket setup --- since we need
to persist the lookup context until the bind.
If setsockopt is the "ioctl of sockets" --- a convenient way to de facto
create syscalls without doing so de jure --- I would think it would be
better to just make it do the bind in one go so there is no state:
struct unix_bind_anon_ctx {
int *connect_fd; /* fd used to connect to this socket
written to this */
__u64 op_flags; /* future usage */
};
setsockopt(fd, SOL_UNIX, UNIX_BIND_ANON,
&ctx, sizeof(ctx));
Regular `linkat` can be used to place the "connect fd" in the filesystem
for regular file-based connecting (e.g. to cope with long paths), in
addition to how the "connect fd" can directly be used in the
`AT_EMPTY_PATH` case.
and for the connecting side:
struct unix_connect_at_ctx {
int dirfd;
const char *path;
__u64 resolve_flags; /* RESOLVE_BENEATH, RESOLVE_NO_SYMLINKS, etc. */
__u64 op_flags; /* SOMETHING_EMPTY_PATH, other future usage */
};
setsockopt(fd, SOL_UNIX, UNIX_CONNECT_AT,
&ctx, sizeof(ctx));
This is just what I had in my previous `summary email`, but with the new
system calls twisted into `setsockopt` variations instead. (I forgot to
mention the `linkat` usage in that email, oops, but it was always
intended to be part of the plan.)
Cheers,
John