This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: Principles for syscall wrappers, again
- From: Rich Felker <dalias at libc dot org>
- To: libc-alpha at sourceware dot org
- Date: Mon, 18 May 2015 20:09:18 -0400
- Subject: Re: Principles for syscall wrappers, again
- Authentication-results: sourceware.org; auth=none
- References: <alpine dot DEB dot 2 dot 10 dot 1505182114090 dot 16300 at digraph dot polyomino dot org dot uk>
On Mon, May 18, 2015 at 10:15:59PM +0000, Joseph Myers wrote:
> We've had various past discussions of when to add wrappers for Linux
> kernel syscalls that have failed to reach a conclusion. The result is
> a de facto status of "syscall wrappers present for almost all syscalls
> added up to Linux 3.2 / glibc 2.15 but for nothing added since then",
> which certainly doesn't make sense.
>
> Existing bugs asking for such wrappers include: 6399 (gettid) 9712 (futex)
> 17252 (getrandom) 17662 (renameat2) 18271 (bpf).
>
> Sample messages from past discussions include:
> <https://sourceware.org/ml/libc-alpha/2012-05/msg01733.html>
> <https://sourceware.org/ml/libc-alpha/2012-06/msg00048.html>
> <https://sourceware.org/ml/libc-alpha/2013-01/msg01007.html>
> <https://sourceware.org/ml/libc-alpha/2013-02/msg00030.html>
> <https://sourceware.org/ml/libc-alpha/2014-10/msg00535.html>
> <https://sourceware.org/ml/libc-alpha/2014-10/msg00541.html>
> <https://sourceware.org/ml/libc-alpha/2014-10/msg00591.html>
> <https://sourceware.org/ml/libc-alpha/2015-01/msg00315.html>.
>
> There were objections to what I suggested in
> <https://sourceware.org/ml/libc-alpha/2014-10/msg00535.html> regarding
> defaulting to adding wrappers unless there's a reason (syscall being
> obsolete, can't meaningfully be used behind glibc's back, or a glibc
> function provides all the useful functionality without being a direct
> wrapper) not to do so. So here is a narrower proposal:
>
> Direct wrappers to non-architecture-specific Linux syscalls are
> appropriate if none of the previously mentioned issues apply, *and* the
> functionality provided by the syscall is naturally useful in
> non-Linux-specific applications (although those applications might use
> different interfaces to access it on other OSes), *and* it is expected
> that more than one application or library might wish to use that
> functionality directly, rather than a single library providing
> higher-level wrappers that everything else will then use, or a single
> package containing all the uses of the syscall.
>
> That is, wrappers are appropriate when the functionality could plausibly
> form part of the OS-independent GNU API. However, there would be no
> expectation that such a wrapper is added to the OS-independent GNU API
> (i.e., that an ENOSYS version is added for other OSes) at the time it's
> added to glibc, nor is there an expectation that an attempt is made to
> develop an OS-independent abstraction. If someone decides such an
> interface is useful to implement on another OS, at that point we can make
> it part of the OS-independent GNU API (with an ENOSYS version for all
> other OSes added at that point).
>
> For example: under these principles it's fine that we have direct wrappers
> for the Linux epoll interfaces. If the kFreeBSD port gets added it would
> be fine for that to provide direct access to kqueue. There would be no
> expectation that either interface needs to become part of the
> OS-independent GNU API and be emulated in terms of the other on the other
> OS (if that were even possible). If a new interface for the same use
> cases were added to POSIX in future, it would become part of the
> OS-independent GNU API and get implemented in terms of whatever underlying
> interfaces are available on each OS.
>
> Under these principles, at least the following existing syscall wrappers
> would probably not be added now (or at least these principles would not by
> themselves provide reason to add them): bdflush create_module
> delete_module get_kernel_syms init_module query_module uselib. However, I
> think most wrappers added up to Linux 3.2 / glibc 2.15 are appropriate
> under these principles (albeit generally lacking documentation and
> testcases).
>
> * bdflush create_module get_kernel_syms query_module uselib: obsolete.
> Despite this, glibc provides them as ABIs even on architectures that have
> never had those syscalls (in which case they just give ENOSYS errors).
> They should become compat symbols (requiring a new syscalls.list feature
> to create a compat symbol with a SHLIB_COMPAT conditional so that new
> architectures don't get the symbol at all).
>
> * delete_module init_module: inherently Linux-specific and only expected
> to be used by a single package. A few other existing wrappers might be
> similarly suspect (e.g. klogctl nfsservctl).
>
> Under these principles, I think the first four above-mentioned requested
> syscalls (futex gettid getrandom renameat2) would be appropriate for
> wrappers, but I don't know about bpf. Of other post-3.2 syscalls, I think
> the following would be appropriate for wrappers: sched_setattr
> sched_getattr memfd_create; finit_module wouldn't be and I don't know
> about kcmp and seccomp. execveat would be appropriate for a wrapper *and*
> making part of the OS-independent GNU API immediately.
The big practical questions left are where to expose the interfaces,
and with what signatures.
I would like to see futex in its own header, sys/futex.h, since it has
a number of macros. I also tend to think the function itself should be
variadic since a few of the argument slots have different types
depending on the command in use.
For gettid, I would not mind having it in unistd.h under _ALL_SOURCE.
I don't think it warrants its own header. sched.h might also be
appropriate. Even sys/futex.h might be ok as a stretch. Its return
type should probably be pid_t or int (not sure which). For use of tids
in the futex API, a tid is necessarily an int with the sign bit and
highest two value bits clear, so int might be appropriate to match
futex.
For renameat2 I think it's obvious that it belongs in the same place
as renameat, stdio.h.
Not sure about getrandom. There's also an open question of whether
getrandom should be a pure syscall wrapper or have emulation for
kernels too old to provide it.
Rich