2011-07-04 11 views
6

Poniżej znajduje się kod, którego używam do mmapowania pliku w Ubuntu z wawrzynami, ale to połączenie kończy się błędem "nieprawidłowy argument". Jednakże, gdy przekazuję flagę MAP_ANON bez parametru deskryptora pliku w mmap, to działa. Nie jestem w stanie zrozumieć możliwego powodu tego.Ubuntu 10.04, błąd w użyciu MAP_HUGETLB z MAP_SHARED

Po drugie, nie jestem w stanie zrozumieć, dlaczego plik mmaping jest dozwolony w MAP_PRIVATE, gdy ta sama flaga oznacza, że ​​żadna zmiana nie zostanie zapisana z powrotem do pliku. Można to zawsze osiągnąć za pomocą MAP_ANON, czy jest coś, czego mi brakuje?

Czy ktoś może mi w tym pomóc?

int32_t main(int32_t argc, char** argv) { 
int32_t map_length = 16*1024*1024; // 16 MB , huge page size is 2 MB 
int32_t protection = PROT_READ | PROT_WRITE; 
int32_t flags = MAP_SHARED | MAP_HUGETLB; 
int32_t file__ = open("test",O_RDWR|O_CREAT | O_LARGEFILE,s_IRWXU | S_IRGRP | S_IROTH); 
if(file__ < 0) { 
    std::cerr << "Unable to open file\n"; 
    return -1; 
} 

if (ftruncate(file__, map_length) < 0) { 
    std::cerr 
    << "main :: unable to truncate the file\n" 
    << "main :: " << strerror(errno) << "\n" 
    << "main :: error number is " << errno << "\n"; 
    return -1; 
} 
void *addr= mmap(NULL, map_length, protection, flags, file__, 0); 
if (addr == MAP_FAILED) { 
    perror("mmap"); 
    return -1; 
} 
const char* msg = "Hello World\n"; 
int32_t len = strlen(msg); 
memcpy(addr,msg,len); 
munmap(addr, map_length); 
close(file__); 
return 0; 
} 
+0

'int32_t main' jest błędem. Zgodnie ze standardem C++, typ powrotu 'main' i typ' argc' powinny być po prostu 'int'. –

+0

larsmans, czy to ma wpływ na wyjście programu? Na mojej architekturze int jest takie samo jak int32_t, więc nie powinno to w ogóle mieć znaczenia. Ale ze standardowego punktu widzenia to nie w porządku, zgadzam się. (Wcześniej popełniłem jakiś błąd przy pisaniu tego komentarza) – Faraz

+0

Faraz: Nie, on po prostu chwytał. – BjoernD

Odpowiedz

4

Oba pytania sprowadzają się do tego samego punktu: Za pomocą mmap() można uzyskać dwa rodzaje odwzorowań: anonimową pamięć i pliki.

Pamięć anonimowa jest (jak podano na stronie podręcznika) nie jest wspierana przez żaden plik w systemie plików. Zamiast tego pamięć, którą otrzymujesz z połączenia MAP_ANON do mmap(), jest zwykłą pamięcią systemową. Głównym użytkownikiem tego interfejsu jest biblioteka C, która wykorzystuje ją do uzyskiwania przechowywania kopii zapasowych dla malloc/free. Tak więc użycie MAP_ANON wyraźnie mówi, że nie chcesz mapować pliku.

Pamięć z pamięcią zapasową rodzaj połączenia w pliku (lub jego częściach) w przestrzeni adresowej aplikacji. W tym przypadku zawartość pamięci jest faktycznie wspierana przez zawartość pliku. Pomyśl o flagę MAP_PRIVATE jako pierwszej alokacji pamięci dla pliku, a następnie skopiować zawartość do tej pamięci. Tak naprawdę nie będzie to, co robi jądro, ale po prostu udawajmy.

HUGE_TLB to funkcja, którą jądro zapewnia anonimowej pamięci (patrz Dokumentacja/vm/hugetlb-page.txt zgodnie z odnośnikiem na stronie podręcznika mmap()). To powinno być powodem niepowodzenia twojego wywołania mmap() podczas używania HUGETLB dla pliku. * Edycja: nie do końca poprawne. Istnieje system plików RAM (hugetlbfs), który obsługuje ogromne strony. Jednak mapowanie huge_tlb nie będzie działało na arbitralnych plikach, ponieważ rozumiem dokumenty. *

Aby uzyskać szczegółowe informacje na temat używania HUGE_TLB i odpowiedniego systemu plików w pamięci (hugetlbfs), warto rozważyć następujące artykuły na LWN:

+0

Napisałem, że mmap nie działa z błędem "Nieprawidłowy argument", to jest ciąg, który otrzymujesz, gdy robisz strerno (22) – Faraz

+1

Przeszedłem przez całą dokumentację przed napisaniem tego zapytania i nigdzie nie ma jasności. Z przyjemnością przeczytam coś podobnego do "MAP_HUGETLB działa tylko z MAP_ANON". Po drugie, po zamontowaniu hugetlbfs możemy zrobić plik mmap z wielkimi stronami (na tym fs). Jeśli rzeczywiście MAP_HUGETLB nie jest obsługiwany dla mmap w pliku z kopią zapasową, to w jaki sposób możemy użyć wodzików dla plików mmap w tym pliku? Musi być coś, czego brakuje, prawda? – Faraz

+0

Zmieniono moją odpowiedź. – BjoernD

0

Dodanie MAP_PRIVATE do flag naprawiono to dla mnie.

+0

Na stronie mmap można podać tylko jedną z MAP_SHARED lub MAP_PRIVATE, a nie obie. http://man7.org/linux/man-pages/man2/mmap.2.html –

Powiązane problemy