New Syscalls of Linux 4.x


New Syscalls of Linux 4.x

引言

Linux 4.19 就要发布了,按照套路,4.19应该是Linux 4.x的最后一个版本。Linux 4.0发布在2015年4月(那时候还是大二的小懵懂)。这几年中Linux改变了那些东西呢。这篇是总结了一下新增的syscalls的,其实syscall与新特性大部分时候都没啥关系,这里只是为了好玩。

Syscalls

copy_file_range

ssize_t copy_file_range(int fd_in, loff_t *off_in,
                        int fd_out, loff_t *off_out,
                        size_t len, unsigned int flags);

Linux 4.5中添加的,主要是为了减少不必要的数据拷贝。比如从一个文件的数据拷贝到另外一个文件是,可以不经过user space。

mlock2

int mlock(const void *addr, size_t len);
int mlock2(const void *addr, size_t len, int flags);
int munlock(const void *addr, size_t len);

Linux 4.4 添加的,mlock的强化版本,主要就是添加了一个flags的参数。主要功能就是将一个process的page不要被sweep到磁盘上面。

pkey_alloc, pkey_free, pkey_mprotect

int pkey_alloc(unsigned long flags, unsigned long access_rights);
int pkey_free(int pkey);
int pkey_mprotect(void *addr, size_t len, int prot, int pkey);

这个主要是对page权限的改进。

Memory Protection Keys provide a mechanism for changing protections without requiring modification of the page tables on every permission change.

preadv2, pwritev2

ssize_t preadv(int fd, const struct iovec *iov, int iovcnt,
                      off_t offset);

ssize_t pwritev(int fd, const struct iovec *iov, int iovcnt,
                       off_t offset);

ssize_t preadv2(int fd, const struct iovec *iov, int iovcnt,
                       off_t offset, int flags);

ssize_t pwritev2(int fd, const struct iovec *iov, int iovcnt,
                        off_t offset, int flags);

preadv, pwritev的添加了一个flags参数的版本。

statx

int statx(int dirfd, const char *pathname, int flags,
                 unsigned int mask, struct statx *statxbuf);

stat的强化版本。

To access a file's status, no permissions are required on the file itself, but in the case of statx() with a pathname, execute (search) permission is required on all of the directories in pathname that lead to the file.

userfaultfd

int userfaultfd(int flags);

上面的几个都很无聊,这个比较有意思一点,在Linux 4.3 添加。通常情况下,page fault是有kernel处理的,这个syscall通过文件的形式给user space处理page fault提供了一些功能。[2]中有一些说明。

New Syscalls of Linux 3.x

顺便看一下3.x的吧,emmmm。

bpf

int bpf(int cmd, union bpf_attr *attr, unsigned int size);

Berkeley Packet Filters相关的一个syscall,挺有用的。

execveat

int execveat(int dirfd, const char *pathname,
	char *const argv[], char *const envp[], int flags);

execve(2)的强化版本。

finit_module

int finit_module(int fd, const char *param_values, int flags);

Load一个ELF image到kernel space,类似init_module。

getrandom

ssize_t getrandom(void *buf, size_t buflen, unsigned int flags);

借助内核生成随机数,比直接读区/dev/random更加好用。

kcmp

int kcmp(pid_t pid1, pid_t pid2, int type,
                unsigned long idx1, unsigned long idx2);

检查2个进程的共享资源的信息。

kexec_file_load

long kexec_file_load(int kernel_fd, int initrd_fd,
                           unsigned long cmdline_len, const char *cmdline,
                           unsigned long flags);

kexec_file_load用来用于在reboot之后使用新的kernel。

membarrier

int membarrier(int cmd, int flags);

提供一个类似内存屏障的功能.

memfd_create

int memfd_create(const char *name, unsigned int flags);

将内存当作文件。

process_vm_readv, process_vm_writev

ssize_t process_vm_readv(pid_t pid,
                                const struct iovec *local_iov,
                                unsigned long liovcnt,
                                const struct iovec *remote_iov,
                                unsigned long riovcnt,
                                unsigned long flags);

ssize_t process_vm_writev(pid_t pid,
                                 const struct iovec *local_iov,
                                 unsigned long liovcnt,
                                 const struct iovec *remote_iov,
                                 unsigned long riovcnt,
                                 unsigned long flags);

对vm space做一些操作。

renameat2

int renameat2(int olddirfd, const char *oldpath,
                     int newdirfd, const char *newpath, unsigned int flags);

renameat添加了flags参数.

sched_setattr, sched_getattr

int sched_setattr(pid_t pid, struct sched_attr *attr,
                         unsigned int flags);

int sched_getattr(pid_t pid, struct sched_attr *attr,
                         unsigned int size, unsigned int flags);

scheduling policy相关的syscalls。

seccomp

 int seccomp(unsigned int operation, unsigned int flags, void *args);

Secure Computing (seccomp),终于看到一个有趣的一点的了,这个syscall在一些地方很有用,最大的一个用处就是,终于看到一个有趣的一点的了,这个syscall在一些地方很有用,最大的一个用处就是可以对调用syscall做一些限制。

sendmmsg

 int sendmmsg(int sockfd, struct mmsghdr *msgvec, unsigned int vlen,
                    int flags);

这个也是一个比较有用的syscall,主要就是将多个syscall合在一起,平摊(amortize)syscall的开支。

setns

int setns(int fd, int nstype);

Linux namespace 直接相关的syscall,Docker之类的都要使用的东西。Linux 3.0的时候就添加了。

参考

  1. http://man7.org/linux/man-pages/man2/syscall.2.html
  2. http://xiaogr.com/?p=96, Look Into Userfaultfd