2016-06-29 6 views
1

Я пытался выяснить, могу ли я иметь ОС, linux, перенести изменения памяти на диск для меня. Я бы привязал некоторые разделы файла в память. Файл, скажем, будет круговой. Я понял, что было бы более эффективно, если бы я позволил ОС обрабатывать записанные страницы на диск.с linux persist изменения памяти на диск

Я начал изучать mmap(), msync() и munmap(). Я нашел следующую статью:

c linux msync(MS_ASYNC) flush order

, в которых один из постов указывают, что MS_ASYNC из msync() является не-оп, так как операционная система уже отслеживает грязных страниц и промывает их хранения при необходимости. Было бы хорошо знать, что это значит. Я также нашел это:

msync() behaviour broken for MS_ASYNC, revert patch?

Я не понимал большую часть этого разговора. Наверное, я искал эффективный способ внесения изменений в представление памяти, которые сохраняются на диске даже в случае сбоя.

Я написал небольшое примерное приложение ниже. Кажется, что даже когда я ввожу крах, последние данные, которые я написал в сопоставленную память, хранятся на диске.

#include <stdio.h> 
#include <string.h> 
#include <unistd.h> 
#include <sys/types.h> 
#include <sys/stat.h> 
#include <sys/mman.h> 
#include <fcntl.h> 
#include <errno.h> 

void main(int argc, char* argv[]) 
{ 
    int result; 
    int fd = -1; 

    if (argc != 2) 
     { 
     printf("Error, missing file name argument\n"); 
     goto done; 
     } 

    fd = open(argv[1], O_RDWR | O_CREAT, S_IWUSR | S_IRUSR); 
    if (fd == -1) 
     { 
     printf("Failed opening file %s: %d\n", argv[1], errno); 
     goto done; 
     } 

    unsigned int size = 8 * 1024L * 1024L; 
    result = ftruncate(fd, size); 
    if (result != 0) 
     { 
     printf("Failed setting file size: %d\n", errno); 
     goto done; 
     } 

    void* addr; 
    addr = mmap(NULL, size, PROT_WRITE, MAP_FILE | MAP_SHARED, 
      fd, 0); 
    if (addr == MAP_FAILED) 
     { 
     printf("Failed to map memory: %d\n", errno); 
     goto done; 
     } 
    memset(addr, 'r', size); 
    result = msync(addr, size, MS_ASYNC); 
    getchar(); 
    if (result != 0) 
     { 
     printf("Failed syncing mapped memory: %d\n", errno); 
     goto done; 
     } 
    memset(addr, 'p', size); 
    getchar(); 

    memset(addr, 'm', size); 

    // crash. 

    *((int*) 0) = 0; 

done: 
    printf("done\n"); 
    if (fd != -1) 
     close(fd); 
    printf("closed file\n"); 
    return; 
} 

Так использует ММАП(), msync (MS_ASYNC) разумный способ иметь ОС сохраняются мои изменения в оперативной памяти на диск?

Спасибо, Ник

+0

Вы еще раз пробовали 'O_DIRECT'? –

+0

Вы имеете в виду использование O_DIRECT при вызове функции open()? Если да, то нет. Я ищу, чтобы посмотреть, как OS будет сохранять изменения для меня, в отличие от того, что я делаю это сам. – nickdu

ответ

1

Так использует mmap(), msync(MS_ASYNC) разумный способ иметь ОС сохраняются мои изменения в оперативной памяти на диск?

Нет, это не так.

Ваш тестовый пример не доказывает, что во всех случаях ваши данные будут сохраняться в стабильном хранилище - только в том, что это было видно в вашем узком сценарии. Кроме того, когда люди говорят о том, что данные, записанные на диск, сохраняются перед лицом «краха», они обычно означают потерю операционной системы или потери аппаратной мощности (например, паника ядра, резкое отключение питания и т. Д.) - программа пользовательской программы просто отключается 't остановить запущенное ядро, способное получить доступ (и даже синхронизировать) грязные данные, перемещающиеся в памяти. К сожалению, это означает, что ваш тест демонстрирует что-то другое, что вам нужно.

Как уже упоминалось here, чтобы знать, если данные действительно сделали это в постоянном хранилище, вы должны использовать (и проверить результат) одно из следующих действий:

  • msync(MS_SYNC)
  • fsync
  • sync_file_range + fsync (для метаданных)

Вы никогда не были в состоянии использовать msync(MS_ASYNC), потому что он не сообщает вам, когда данные были успешно сохранены (и в Linux он даже не заставляет забыть о обратной записи, о чем предупреждают сообщения, на которые ссылаются).Либо:

  • Вы заботитесь о настойчивости, и вы должны знать, когда что данные закончил записываемый постоянное стабильное хранение (например, вы хотите отложить некоторые другие действия, пока не будет).
  • Или вам все равно, и все в порядке, когда данные доступны только для чтения, а система продолжает работать правильно, поэтому вы в порядке с неопределенностью данных в других сценариях.