我一直在使用openSUSE 11.2 x86_64上的大型稀疏文件。當我嘗試mmap()1TB稀疏文件時,它與ENOMEM一起失敗。我本以爲64位地址空間足以映射成TB,但似乎不是。進一步試驗,1GB文件可以正常工作,但2GB文件(以及其他更大的文件)會失敗。我猜測可能有一個設置在某處進行調整,但廣泛的搜索沒有任何結果。爲什麼在1TB稀疏文件上mmap()會失敗並顯示ENOMEM?
下面是一些顯示問題的示例代碼 - 任何線索?
#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;
}
作爲一個興趣點,你的程序對我來說最多可以處理256GB('1 << 38')的大小,而返回EINVAL的任何數據都會更高。這是在RHEL4上(內核2.6.9-42.0.3.ELsmp)。 – caf 2010-05-26 04:39:38
ulimit -a說什麼? – bmargulies 2010-05-26 04:49:13
謝謝,bmargulies - 就是這樣。 ulimit - 報告的虛擬內存爲1804800千字節(略高於1.7GB)。 ulimit -v 1610612736(1.5TB)讓我mmap我的1TB稀疏文件。我會回答我自己的問題,所以我可以'關閉'它... – metadaddy 2010-05-27 05:47:39