This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Principles for syscall wrappers, again
- From: Joseph Myers <joseph at codesourcery dot com>
- To: <libc-alpha at sourceware dot org>
- Date: Mon, 18 May 2015 22:15:59 +0000
- Subject: Principles for syscall wrappers, again
- Authentication-results: sourceware.org; auth=none
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.
All of that would be conditional on someone with a copyright assignment
implementing such patches that conform to the usual standards for patches
adding new APIs (header, documentation, tests at least that uses of the
APIs compile and link, symbol versions, updating all ABI baselines).
Patches may or may not already have been posted in some cases.
Documentation for some interfaces might defer to external Linux
documentation, but at least a statement to that effect would need to be in
the glibc manual alongside the function prototype. The documentation
would also need to state the return value / errno setting, since errno
setting is a userspace thing not something done by the kernel, and it
would be necessary in each case to consider whether the syscall should be
a cancellation point.
--
Joseph S. Myers
joseph@codesourcery.com