이 예에서 remap_file_pages ()가 실패한 이유는 무엇입니까?
-
19-09-2019 - |
문제
다음 C 코드는 Linux 2.6.30.5-43.fc11.x86_64에서보고있는 문제를 보여줍니다.
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main() {
char buf[1024];
void *base;
int fd;
size_t pagesz = sysconf(_SC_PAGE_SIZE);
fd = open("<some file, at least 4*pagesz in length>", O_RDONLY);
if (fd < 0) {
perror("open");
return 1;
}
base = mmap(0, 4*pagesz, PROT_READ, MAP_SHARED, fd, 0);
if (base < 0) {
perror("mmap");
close(fd);
return 1;
}
memcpy(buf, (char*)base + 2*pagesz, 1024);
if (remap_file_pages(base, pagesz, 0, 2, 0) < 0) {
perror("remap_file_pages");
munmap(base, 4*pagesz);
close(fd);
return 1;
}
printf("%d\n", memcmp(buf, base, 1024));
munmap(base, 4*pagesz);
close(fd);
return 0;
}
remap_file_pages ()가 -1을 반환하고 errno가 einval로 설정하면 항상 실패합니다. 커널 소스를 살펴보면 remap_file_pages ()의 모든 조건이 실패 할 수 있지만 내 예제에 적용되지 않는 것 같습니다. 무슨 일이야?
해결책
파일이 열려 있기 때문에 발생합니다 O_RDONLY
. 열기 모드를 변경하면 O_RDWR
, 그것은 작동합니다 (하더라도 mmap()
여전히 단지 지정합니다 PROT_READ
).
이 코드는 do_mmap_pgoff
근본 원인입니다. VMA를 다음과 같이 표시합니다. VM_SHARED
작성을 위해 파일이 열린 경우 :
vm_flags |= VM_SHARED | VM_MAYSHARE;
if (!(file->f_mode & FMODE_WRITE))
vm_flags &= ~(VM_MAYWRITE | VM_SHARED);
그래서 remap_file_pages()
, 당신은 첫 번째 점검에서 실패합니다.
if (!vma || !(vma->vm_flags & VM_SHARED))
goto out;
제휴하지 않습니다 StackOverflow