2016-06-29 26 views
1

Ich habe versucht, um zu sehen, ob ich das Betriebssystem, Linux, persist Speicheränderungen auf Festplatte für mich haben könnte. Ich würde bestimmte Abschnitte einer Datei in den Speicher abbilden. Die Datei wäre eine ringförmige Warteschlange. Ich dachte mir, dass es effizienter wäre, wenn ich das OS damit beauftragen würde, die geänderten Seiten auf die Festplatte zu schreiben.mit Linux persist Speicher ändert sich auf Festplatte

Ich begann in mmap(), msync() und munmap() zu suchen. Ich fand den folgenden Artikel:

c linux msync(MS_ASYNC) flush order

in dem einer der Beiträge zeigen, dass MS_ASYNC von msync() ist eine no-op, da das OS bereits schmutzigen Seiten verfolgt und spült sie den Speicher bei Bedarf. Es wäre schön, genau zu wissen, was das bedeutet. Ich fand auch diese:

msync() behaviour broken for MS_ASYNC, revert patch?

ich nicht von diesem Gespräch viel verstand. Ich glaube, ich suchte nach einer effizienten Möglichkeit, Änderungen, die ich an einer In-Memory-Repräsentation mache, auch im Falle eines Absturzes auf der Festplatte zu speichern.

Ich schrieb die kleine Beispiel-App unten. Es scheint, selbst wenn ich einen Absturz einführe, werden die neuesten Daten, die ich in den zugeordneten Speicher geschrieben habe, auf der Festplatte gespeichert.

#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; 
} 

So wird unter Verwendung von mmap(), msync (MS_ASYNC) eine angemessene Art und Weise das Betriebssystem zu haben, meine In-Memory-Änderungen auf der Festplatte bestehen bleiben?

Danke, Nick

+0

Haben Sie schon 'O_DIRECT' probiert? –

+0

Sie meinen O_DIRECT beim Aufruf von open()? Wenn ja, nein. Ich schaue, um zu sehen, wie das OS Veränderungen für mich persistieren würde, im Gegensatz zu mir, es selbst zu machen. – nickdu

Antwort

1

So mmap(), msync(MS_ASYNC) eine vernünftige Art und Weise das Betriebssystem bestehen bleibt Änderungen auf der Festplatte meine im Speicher zu haben, verwendet?

Nein, ist es nicht.

Ihr Testfall beweist nicht, dass Ihre Daten in allen Fällen dauerhaft gespeichert werden - nur dass sie in Ihrem engen Szenario sichtbar waren. Wenn die Leute darüber reden, dass Daten auf die Festplatte geschrieben werden, so bedeutet das normalerweise einen Absturz des Betriebssystems oder einen Stromausfall der Hardware (z. B. Kernel Panic, abruptes Abschalten usw.) - ein Userland-Programm segfailing tut das nicht Halte den laufenden Kernel nicht auf, um auf die im Speicher herumrollenden schmutzigen Daten zuzugreifen (und sie sogar zu synchronisieren). Leider bedeutet dies, dass Ihr Test etwas anderes gezeigt hat als Sie es brauchten.

Wie erwähnt here, zu wissen, ob die Daten wirklich es in den stabilen Speicher hergestellt Sie verwenden (und überprüfen das Ergebnis) eine der folgenden Möglichkeiten:

  • msync(MS_SYNC)
  • fsync
  • sync_file_range + fsync (für Metadaten)

Sie waren nie in der Lage,zu verwenden, weil es Ihnen nicht sagt, wann die Daten erfolgreich erhalten wurden (und unter Linux erzwingt es nicht einmal das Zurückschreiben, um anzufangen, worüber die Beiträge, die Sie verlinken, gewarnt werden).Entweder:

  • Sie kümmern uns um Ausdauer und Sie müssen wissen, wann diese Daten hat fertig zu persistenten stabilen Speicher geschrieben werden (zum Beispiel wollen Sie eine andere Aktion zu verschieben, bis es ist).
  • Oder es ist Ihnen egal, und Sie sind in Ordnung mit diesen Daten nur lesbar, während das System weiterhin einwandfrei funktioniert, damit Sie in Ordnung mit diesen Daten in anderen Szenarien unbestimmt sind.