When exposing kernel functionality, there are several alternatives for kernel developers. They can either create a new system call or expose the functionality through /sys, or /proc entries.

Is there a reason to prefer one over another?

Do kernel developers avoid adding new system calls, unless it offers a considerable advantage, or do they add calls freely, as and when required ?

EDIT: I am working on a project to expose netfilter functionality to a Linux container (LXC). The functionality must be exposed in a controlled way, for example, when a container (say c1), want to place a netfilter hook, the hook must be called only when the packets are for the network interfaces in c1.

I can either create new system calls, or allow containers to install a module, and provide a translation layer in the kernel, which protects the host kernel from the kernel module installed by the guest. (The implementation of this translation module, or security implications of allowing containers to install a module can be a topic for another discussion).

Adding a new system call would ensure better isolation, while allowing guests to install module will have better performance. The latter can also expose functionality which cannot be exposed by systems calls, for example if guest wants to use its own version of TCP/IP stack.

What would a seasoned Linux kernel developer prefer?

  • 1
    lets not forget the possibility of making a new kind of special (device) file! – infixed Jun 14 '16 at 21:30
  • yes, we can create /dev device as well, and issue ioctls to achieve whatever functionality we want, I was just pointing out that, out of the several existing mechanisms, adding a system call looks like least favoured? Developers are quite miserly when it comes to adding a new system call. – Sahil Singh Jun 15 '16 at 9:43

New system calls are added pretty rarely. Most new kernel functionality can be reached through a few general mechanisms:

  • File descriptors are a very general feature for resource management.
  • Custom actions on file descriptors happen through ioctl.
  • Interactions are also possible through the proc filesystem and its variant sysfs for hardware- and driver-related information.

These general mechanisms benefit from existing generic support. For example, resources attached to a descriptor are automatically shared with child processes, automatically closed on execve if flagged to do so, freed when the descriptor is closed (which happens when the process dies), etc. Access control to new features implemented as files is provided through the well-established file access control mechanisms (permissions, SELinux, etc.).

These general mechanisms are also easier to use than a new system call because they can be used immediately, without waiting for library support. A new entry in /proc can be used directly from a shell script. A new ioctl can be used directly from application. A new system call needs to be declared in the standard library.

The syscalls man page lists the kernel version in which each system call was added. Most new system calls offer new ways to manipulate certain types of files, either to manage metadata and credentials (e.g. extended attribute support in 2.6) or as variations operations that weren't quite possible before (e.g. execveat, renameat2).

  • copy_file_range() was added in Linux 4.5. Developers want to maintain backwards compatibility, hence this call will be present in foreseeable future, and will have to be maintained constantly for that duration. This could be another factor why adding a new system call is a bigger challenge. Also see my edit in the question. – Sahil Singh Jun 15 '16 at 10:10
  • You said that a new system call cannot be used immediately, and must wait for library support. This is a little misleading. see man7.org/linux/man-pages/man2/syscall.2.html . – Sahil Singh Jun 15 '16 at 13:58

This Linux document gives the guidelines for adding a new system calls.

Here are the key points from the it, related to our discussion

  • When a new system call is added, it becomes a part of the kernel API, and has to be supported indefinitely.
  • Creating a new system call is also a bigger responsibility as it involves creating test code, man pages, and a motivation big enough to include it in mainline kernel, instead of shipping as a kernel module.
  • If the new functionality resembles file-system like interactions in usage (for eg. runtime information like memory usage can be obtained by a simple read on /proc/meminfo), use /proc, /sys, /dev entries. These can be created by a module, and can be put into and pulled out of kernel as and when required. They also offer the advantages given in Gilles's answer.

These lines from another file in Linux kernel's documentation, explaining development process, highlight the effort that must be done before exposing a user-space ABI.

Once an interface has been exported to user space, it must be supported indefinitely. This fact makes the creation of user-space interfaces particularly challenging: since they cannot be changed in incompatible ways, they must be done right the first time.

For this reason, a great deal of thought, clear documentation, and wide review for user-space interfaces is always required.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.