diff --git a/vendor/github.com/hashicorp/raft/file_snapshot.go b/vendor/github.com/hashicorp/raft/file_snapshot.go index 7ec7b7a75..119bfd308 100644 --- a/vendor/github.com/hashicorp/raft/file_snapshot.go +++ b/vendor/github.com/hashicorp/raft/file_snapshot.go @@ -37,10 +37,11 @@ type snapMetaSlice []*fileSnapshotMeta // FileSnapshotSink implements SnapshotSink with a file. type FileSnapshotSink struct { - store *FileSnapshotStore - logger *log.Logger - dir string - meta fileSnapshotMeta + store *FileSnapshotStore + logger *log.Logger + dir string + parentDir string + meta fileSnapshotMeta stateFile *os.File stateHash hash.Hash64 @@ -158,9 +159,10 @@ func (f *FileSnapshotStore) Create(version SnapshotVersion, index, term uint64, // Create the sink sink := &FileSnapshotSink{ - store: f, - logger: f.logger, - dir: path, + store: f, + logger: f.logger, + dir: path, + parentDir: f.path, meta: fileSnapshotMeta{ SnapshotMeta: SnapshotMeta{ Version: version, @@ -404,6 +406,19 @@ func (s *FileSnapshotSink) Close() error { return err } + // fsync the parent directory, to sync directory edits to disk + parentFH, err := os.Open(s.parentDir) + defer parentFH.Close() + if err != nil { + s.logger.Printf("[ERR] snapshot: Failed to open snapshot parent directory %v, error: %v", s.parentDir, err) + return err + } + + if err = parentFH.Sync(); err != nil { + s.logger.Printf("[ERR] snapshot: Failed syncing parent directory %v, error: %v", s.parentDir, err) + return err + } + // Reap any old snapshots if err := s.store.ReapSnapshots(); err != nil { return err @@ -437,6 +452,11 @@ func (s *FileSnapshotSink) finalize() error { return err } + // Sync to force fsync to disk + if err := s.stateFile.Sync(); err != nil { + return err + } + // Get the file size stat, statErr := s.stateFile.Stat() @@ -468,13 +488,21 @@ func (s *FileSnapshotSink) writeMeta() error { // Buffer the file IO buffered := bufio.NewWriter(fh) - defer buffered.Flush() // Write out as JSON enc := json.NewEncoder(buffered) if err := enc.Encode(&s.meta); err != nil { return err } + + if err = buffered.Flush(); err != nil { + return err + } + + if err = fh.Sync(); err != nil { + return err + } + return nil } diff --git a/vendor/github.com/hashicorp/raft/observer.go b/vendor/github.com/hashicorp/raft/observer.go index 22500fa87..76c4d555d 100644 --- a/vendor/github.com/hashicorp/raft/observer.go +++ b/vendor/github.com/hashicorp/raft/observer.go @@ -24,6 +24,12 @@ type FilterFn func(o *Observation) bool // Observer describes what to do with a given observation. type Observer struct { + // numObserved and numDropped are performance counters for this observer. + // 64 bit types must be 64 bit aligned to use with atomic operations on + // 32 bit platforms, so keep them at the top of the struct. + numObserved uint64 + numDropped uint64 + // channel receives observations. channel chan Observation @@ -37,10 +43,6 @@ type Observer struct { // id is the ID of this observer in the Raft map. id uint64 - - // numObserved and numDropped are performance counters for this observer. - numObserved uint64 - numDropped uint64 } // NewObserver creates a new observer that can be registered diff --git a/vendor/github.com/hashicorp/raft/state.go b/vendor/github.com/hashicorp/raft/state.go index f6d658b8b..a58cd0d19 100644 --- a/vendor/github.com/hashicorp/raft/state.go +++ b/vendor/github.com/hashicorp/raft/state.go @@ -42,6 +42,10 @@ func (s RaftState) String() string { // and provides an interface to set/get the variables in a // thread safe manner. type raftState struct { + // currentTerm commitIndex, lastApplied, must be kept at the top of + // the struct so they're 64 bit aligned which is a requirement for + // atomic ops on 32 bit platforms. + // The current term, cache of StableStore currentTerm uint64 diff --git a/vendor/vendor.json b/vendor/vendor.json index d180973f5..873a60bb8 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -869,10 +869,10 @@ "revision": "a14192a58a694c123d8fe5481d4a4727d6ae82f3" }, { - "checksumSHA1": "OCPP4JxnuSSmweEL9khCd6OdIts=", + "checksumSHA1": "ecpaHOImbL/NaivWrUDUUe5461E=", "path": "github.com/hashicorp/raft", - "revision": "e45173826775c4b782961c7b5758ba484b91464b", - "revisionTime": "2017-07-10T17:20:01Z" + "revision": "3a6f3bdfe4fc69e300c6d122b1a92051af6f0b95", + "revisionTime": "2017-08-07T22:22:24Z" }, { "checksumSHA1": "QAxukkv54/iIvLfsUP6IK4R0m/A=",