【问题标题】:Different results when running inside a docker container在 docker 容器中运行时的不同结果
【发布时间】:2018-07-05 20:33:01
【问题描述】:

我正在尝试基于此 libaio 示例运行一些代码: https://oxnz.github.io/2016/10/13/linux-aio/#example-1

我根据 libaio 的文档添加了 O_DIRECT 标志。 它似乎可以在我的 ubuntu 16.04 台式机中运行(hello 写入 /tmp/test)。

但是,当我在 docker 容器中编译和运行相同的示例时,不会将任何内容写入文件。在 gdb 中运行时,我可以看到 io_getevents 读取了一个事件,结果设置为 -22 (EINVAL)。

有什么想法吗?

这是我修改后的代码

#define _GNU_SOURCE

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <err.h>
#include <errno.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <libaio.h>

int main() {
    io_context_t ctx;
    struct iocb iocb;
    struct iocb * iocbs[1];
    struct io_event events[1];
    struct timespec timeout;
    int fd;

    fd = open("/tmp/test", O_WRONLY | O_CREAT | O_DIRECT) ;
    if (fd < 0) err(1, "open");

    memset(&ctx, 0, sizeof(ctx));
    if (io_setup(10, &ctx) != 0) err(1, "io_setup");

    const char *msg = "hello";
    io_prep_pwrite(&iocb, fd, (void *)msg, strlen(msg), 0);
    iocb.data = (void *)msg;

    iocbs[0] = &iocb;

    if (io_submit(ctx, 1, iocbs) != 1) {
        io_destroy(ctx);
        err(1, "io_submit");
    }

    while (1) {
        timeout.tv_sec = 0;
        timeout.tv_nsec = 500000000;
    int ret = io_getevents(ctx, 0, 1, events, &timeout);
        printf("ret=%d\n", ret);
    if (ret == 1) {
            close(fd);
            break;
        }
        printf("not done yet\n");
        sleep(1);
    }
    io_destroy(ctx);

    return 0;
}

【问题讨论】:

  • 在 docker 容器内运行程序将向容器的 MNT 命名空间中的/tmp/test 写入问候,而不是主机。你检查了哪个/tmp/test
  • 我检查了正确的。文件存在但为空。
  • 它可能会失败,因为容器和主机之间的 devicemapper 附加层会施加更严格的限制。要解决的一件事:要使用直接 I/O,您的内存指针和要写入的消息的长度都必须与底层设备的块大小对齐,这可能是 512 字节或 4096。最容易假设4096 字节。使用posix_memalign 为消息分配内存,并写入长度为4096 字节的倍数。如果这个程序在主机上运行,​​它就会回退到非直接 I/O。

标签: c linux docker aio


【解决方案1】:

容器内的文件系统可能与主机的文件系统不同(在现代设置上可能是overlayfs,但在旧系统上可能是aufs)。对于开放工作的O_DIRECT,设备/文件系统必须至少“支持”它(注意引号),并且您的容器的文件系统可能不支持。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-10
    • 1970-01-01
    • 2023-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-04
    相关资源
    最近更新 更多