为什么mmap()的失败,一个1TB稀疏文件ENOMEM? [英] Why does mmap() fail with ENOMEM on a 1TB sparse file?

查看:710
本文介绍了为什么mmap()的失败,一个1TB稀疏文件ENOMEM?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直与在openSUSE 11.2 x86_64的大稀疏文件。当我尝试mmap()的1TB的稀疏文件时,出现ENOMEM。我本来以为64位地址空间就足够了TB级映射,但似乎并非如此。进一步的实验,一个1GB的文件工作正常,但一个2GB的文件(还有更大的)失败。我猜有可能是一个地方的设置来调整,而是一个广泛的搜索变成了什么。

下面是一些示例code,显示问题 - 任何线索

 的#include<&errno.h中GT;
#包括LT&;&fcntl.h GT;
#包括LT&;&stdio.h中GT;
#包括LT&;&stdlib.h中GT;
#包括LT&;&string.h中GT;
#包括LT&; SYS / mman.h>
#包括LT&; SYS / types.h中>
#包括LT&;&unistd.h中GT;INT主(INT ARGC,CHAR *的argv []){
    字符*文件名=的argv [1];
    INT的fd;
    off_t大小= 1UL&L​​T;< 40; // 30 == 1GB,40 1TB = =    FD =开放(文件名,O_RDWR | O_CREAT | O_TRUNC,0666);
    ftruncate(FD,大小);
    的printf(创建%ld个字节的稀疏文件\\ n,大小);    字符*缓冲=(字符*)MMAP(NULL,(为size_t)大小,PROT_READ | PROT_WRITE,MAP_SHARED,FD,0);
    如果(缓冲== MAP_FAILED){
        PERROR(MMAP);
        出口(1);
    }
    的printf(完成MMAP - 返回为0x0%LX \\ n,(无符号长)缓冲区);    的strcpy(缓冲器cafebabe);
    的printf(中写道启动\\ n);    的strcpy(缓冲液+(大小 - 9),DEADBEEF);
    的printf(中写道结束\\ n);    如果(在munmap(缓冲液,(为size_t)大小)小于0){
        PERROR(则munmap);
        出口(1);
    }
    关闭(FD);    返回0;
}


解决方案

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

I've been working with large sparse files on openSUSE 11.2 x86_64. When I try to mmap() a 1TB sparse file, it fails with ENOMEM. I would have thought that the 64 bit address space would be adequate to map in a terabyte, but it seems not. Experimenting further, a 1GB file works fine, but a 2GB file (and anything bigger) fails. I'm guessing there might be a setting somewhere to tweak, but an extensive search turns up nothing.

Here's some sample code that shows the problem - any clues?

#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;
}

解决方案

The problem was that the per-process virtual memory limit was set to only 1.7GB. ulimit -v 1610612736 set it to 1.5TB and my mmap() call succeeded. Thanks, bmargulies, for the hint to try ulimit -a!

这篇关于为什么mmap()的失败,一个1TB稀疏文件ENOMEM?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆