一尘不染

为什么mmap()在1TB稀疏文件上的ENOMEM失败?

linux

我一直在使用openSUSE 11.2
x86_64上的大型稀疏文件。当我尝试mmap()1TB的稀疏文件时,它因ENOMEM而失败。我本以为64位地址空间足以映射到TB级,但似乎还不够。进一步试验,一个1GB的文件可以正常工作,但是一个2GB的文件(以及更大的文件)会失败。我猜想可能有一个需要调整的地方,但是广泛的搜索没有任何效果。

这是一些显示问题的示例代码-有什么线索吗?

#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <unistd.h>

int main(int argc, char *argv[]) {
    char * filename = argv[1];
    int fd;
    off_t size = 1UL << 40; // 30 == 1GB, 40 == 1TB

    fd = open(filename, O_RDWR | O_CREAT | O_TRUNC, 0666);
    ftruncate(fd, size);
    printf("Created %ld byte sparse file\n", size);

    char * buffer = (char *)mmap(NULL, (size_t)size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    if ( buffer == MAP_FAILED ) {
        perror("mmap");
        exit(1);
    }
    printf("Done mmap - returned 0x0%lx\n", (unsigned long)buffer);

    strcpy( buffer, "cafebabe" );
    printf("Wrote to start\n");

    strcpy( buffer + (size - 9), "deadbeef" );
    printf("Wrote to end\n");

    if ( munmap(buffer, (size_t)size) < 0 ) {
        perror("munmap");
        exit(1);
    }
    close(fd);

    return 0;
}

阅读 373

收藏
2020-06-07

共1个答案

一尘不染

问题是每个进程的虚拟内存限制设置为仅1.7GB。ulimit-v1610612736将其设置为1.5TB,我的mmap()调用成功。谢谢bmargulies,提示您尝试ulimit-a!

2020-06-07