c - Linux 系统调用 clock_settime(...) 在 Docker 容器中因 EPERM 失败

标签 c linux docker ubuntu time

Tl;dr:当我尝试在 Ubuntu 18.04 容器中执行 clock_settime(...) linux 系统调用时,它失败并出现 EPERM 错误,尽管该程序以 root 身份运行。在 Ubuntu 18.04 的容器外以 root 身份运行完全相同的程序成功。

程序如下:

/*  main.c: This program sets the clock forward 1 day. */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>

int main( void )
{
    struct timespec stime;

    if( clock_gettime( CLOCK_REALTIME, &stime) == -1 ) {
        perror( "getclock" );
        exit( EXIT_FAILURE );
    }

    stime.tv_sec += (60*60)*24L;  /* Add one day */
    stime.tv_nsec = 0;

    if( clock_settime( CLOCK_REALTIME, &stime) == -1 ) {
        perror( "setclock" );
        exit( EXIT_FAILURE );
    }

    return( EXIT_SUCCESS );
}

(摘自https://users.pja.edu.pl/~jms/qnx/help/watcom/clibref/qnx/clock_settime.html)

在容器外运行时,日期更新成功:

# gcc main.c -o pushtime
# date && ./pushtime && date
Wed Dec 12 09:38:36 PST 2018
Tue Dec 11 09:38:38 PST 2018

在容器内部运行时,会引发 EPERM 错误:

# gcc main.c -o pushtime
# docker run -it -v `pwd`:/workspace ubuntu:bionic /workspace/pushtime
setclock: Operation not permitted

鉴于命令以 root 身份运行,我很困惑为什么会出现权限错误,而且我还没有在 Docker 的文档中找到任何解释原因的内容。

编辑:我刚刚意识到错误的更简单演示如下:

root@host:~# sudo docker run -it ubuntu:bionic /bin/bash
root@container:/# date -s '2018-02-01 21:39'
date: cannot set date: Operation not permitted
Thu Feb  1 21:39:00 UTC 2018

最佳答案

啊哈,简短的回答是在运行容器时需要传递 --privileged 标志。

来自 Docker 文档:

Full container capabilities (--privileged)

$ docker run -t -i --rm ubuntu bash

root@bc338942ef20:/# mount -t tmpfs none /mnt

mount: permission denied

This will not work, because by default, most potentially dangerous kernel capabilities are dropped; including cap_sys_admin (which is required to mount filesystems). However, the --privileged flag will allow it to run...

关于c - Linux 系统调用 clock_settime(...) 在 Docker 容器中因 EPERM 失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53748644/

相关文章:

linux - 系统 crontab 提供了哪些 root 用户 crontab 不能提供的功能?

python - 我是否总是需要重建 docker 才能安装新的 pip 包?

c++ - 函数调用中char[]和char*的区别

对 http 请求 header 值的格式感到困惑吗?

c++ - 在Solaris 9上安装Git

linux - systemd 脚本有效但不使用 curl

linux - Go 应用程序在生产环境中运行

docker - 如何验证从 docker-compose 构建的 docker images 的有效性?

docker run -w 从 go 脚本运行时出现意外错误

c - 为什么calloc指针类型是void *?