2011-07-04 20 views
6

Sau đây là mã mà tôi đang sử dụng để định dạng tệp trong ubuntu với ôm, nhưng cuộc gọi này không thành công với lỗi "đối số không hợp lệ". Tuy nhiên, khi tôi vượt qua cờ MAP_ANON không có tham số mô tả tệp trong mmap, thì nó hoạt động. Tôi không thể hiểu được lý do có thể có đằng sau điều này.Ubuntu 10.04, lỗi khi sử dụng MAP_HUGETLB với MAP_SHARED

Thứ hai, tôi không thể hiểu tại sao tệp mmaping được phép với MAP_PRIVATE khi cờ này chính nó có nghĩa là không có thay đổi nào được ghi lại vào tệp. Điều này luôn luôn có thể được thực hiện bằng cách sử dụng MAP_ANON, hoặc là có một cái gì đó tôi đang mất tích?

Ai đó có thể giúp tôi với những thứ này không?

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' là lỗi. Theo tiêu chuẩn C++, kiểu trả về của 'main' và kiểu' argc' phải là 'int'. –

+0

larsmans, điều đó có ảnh hưởng đến đầu ra của chương trình không? Trên int kiến ​​trúc của tôi là giống như int32_t, vì vậy nó không quan trọng cả. Nhưng từ quan điểm tiêu chuẩn của xem nó là không đúng, mà tôi đồng ý. (Trước đó tôi đã thực hiện một số sai sót trong văn bản bình luận này) – Faraz

+0

Faraz: Không, anh ta chỉ là nitpicking. – BjoernD

Trả lời

4

Cả hai câu hỏi của bạn đều xuống cùng một điểm: Sử dụng mmap() bạn có thể nhận được hai loại ánh xạ: bộ nhớ ẩn danh và tệp.

Bộ nhớ ẩn danh (như được nêu trong trang hướng dẫn) không được hỗ trợ bởi bất kỳ tệp nào trong hệ thống tệp. Thay vào đó, bộ nhớ bạn nhận được từ một cuộc gọi MAP_ANON tới mmap() là bộ nhớ hệ thống đơn giản. Người dùng chính của giao diện này là thư viện C sử dụng nó để có được lưu trữ sao lưu cho malloc/miễn phí. Vì vậy, bằng cách sử dụng MAP_ANON là một cách rõ ràng nói rằng bạn không muốn ánh xạ một tập tin.

Bộ nhớ được hỗ trợ tệp loại hỗn hợp trong một tệp (hoặc một phần của nó) vào không gian địa chỉ của ứng dụng của bạn. Trong trường hợp này, nội dung bộ nhớ thực sự được hỗ trợ bởi nội dung của tệp. Hãy nghĩ về cờ MAP_PRIVATE là lần đầu tiên cấp phát bộ nhớ cho tệp và sau đó sao chép nội dung vào bộ nhớ này. Trong thực tế, điều này sẽ không phải là những gì hạt nhân đang làm, nhưng chúng ta hãy giả vờ.

HUGE_TLB là một tính năng mà hạt nhân cung cấp cho bộ nhớ ẩn danh (xem Tài liệu/vm/hugetlb ‐ page.txt như được tham chiếu trong trang hướng dẫn mmap()). Điều này sẽ là lý do cho cuộc gọi mmap() của bạn không thành công khi sử dụng HUGETLB cho một tệp. * Chỉnh sửa: không hoàn toàn chính xác. Có một hệ thống tập tin RAM (hugetlbfs) không hỗ trợ các trang lớn. Tuy nhiên, ánh xạ big_tlb sẽ không hoạt động trên các tệp tùy ý, vì tôi hiểu tài liệu. *

Để biết chi tiết về cách sử dụng HUGE_TLB và hệ thống tệp trong bộ nhớ tương ứng (hugetlbfs), bạn có thể xem xét các bài viết sau trên LWN:

+0

tôi đã viết rằng mmap không thành công với lỗi "Đối số không hợp lệ", đó là chuỗi bạn nhận được khi bạn làm strerno (22) – Faraz

+1

Tôi đã đọc tất cả tài liệu trước khi viết truy vấn này và không có sự rõ ràng ở bất cứ đâu. Tôi sẽ rất vui khi đọc một cái gì đó tương tự như "MAP_HUGETLB chỉ hoạt động với MAP_ANON". Thứ hai, sau khi cài đặt hugetlbfs, chúng ta có thể thực hiện tập tin mmap với các trang lớn (trên trang này). Nếu thực sự MAP_HUGETLB không được hỗ trợ cho tệp mmap được sao lưu, thì làm thế nào chúng ta có thể sử dụng hugepages cho tệp mmap được sao lưu trong fs đó? Phải có cái gì đó bị thiếu, đúng không? – Faraz

+0

Đã chỉnh sửa câu trả lời của tôi. – BjoernD

0

Thêm MAP_PRIVATE vào cờ đã sửa lỗi này cho tôi.

+0

Trang mmap cho biết bạn chỉ có thể chỉ định một trong MAP_SHARED hoặc MAP_PRIVATE, chứ không phải cả hai. http://man7.org/linux/man-pages/man2/mmap.2.html –

Các vấn đề liên quan