为什么mmap()的失败,一个1TB稀疏文件ENOMEM? [英] Why does mmap() fail with ENOMEM on a 1TB sparse file?
问题描述
我一直与在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<< 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屋!