diff --git a/etcdserver/server.go b/etcdserver/server.go index fad9136f0..252ef1632 100644 --- a/etcdserver/server.go +++ b/etcdserver/server.go @@ -88,9 +88,9 @@ type Response struct { type Storage interface { // Save function saves ents and state to the underlying stable storage. // Save MUST block until st and ents are on stable storage. - Save(st raftpb.HardState, ents []raftpb.Entry) + Save(st raftpb.HardState, ents []raftpb.Entry) error // SaveSnap function saves snapshot to the underlying stable storage. - SaveSnap(snap raftpb.Snapshot) + SaveSnap(snap raftpb.Snapshot) error // TODO: WAL should be able to control cut itself. After implement self-controled cut, // remove it in this interface. @@ -314,8 +314,12 @@ func (s *EtcdServer) run() { } } - s.storage.Save(rd.HardState, rd.Entries) - s.storage.SaveSnap(rd.Snapshot) + if err := s.storage.Save(rd.HardState, rd.Entries); err != nil { + log.Panicf("etcdserver: save state and entries error: %v", err) + } + if err := s.storage.SaveSnap(rd.Snapshot); err != nil { + log.Panicf("etcdserver: create snapshot error: %v", err) + } s.send(rd.Messages) // TODO(bmizerany): do this in the background, but take @@ -671,7 +675,9 @@ func (s *EtcdServer) snapshot(snapi uint64, snapnodes []uint64) { panic("TODO: this is bad, what do we do about it?") } s.node.Compact(snapi, snapnodes, d) - s.storage.Cut() + if err := s.storage.Cut(); err != nil { + log.Panicf("etcdserver: rotate wal file error: %v", err) + } } func GetClusterFromPeers(urls []string) (*Cluster, error) { diff --git a/etcdserver/server_test.go b/etcdserver/server_test.go index 1e7c06a4c..cb1a7cbce 100644 --- a/etcdserver/server_test.go +++ b/etcdserver/server_test.go @@ -1222,18 +1222,19 @@ type storageRecorder struct { recorder } -func (p *storageRecorder) Save(st raftpb.HardState, ents []raftpb.Entry) { +func (p *storageRecorder) Save(st raftpb.HardState, ents []raftpb.Entry) error { p.record(action{name: "Save"}) + return nil } func (p *storageRecorder) Cut() error { p.record(action{name: "Cut"}) return nil } -func (p *storageRecorder) SaveSnap(st raftpb.Snapshot) { - if raft.IsEmptySnap(st) { - return +func (p *storageRecorder) SaveSnap(st raftpb.Snapshot) error { + if !raft.IsEmptySnap(st) { + p.record(action{name: "SaveSnap"}) } - p.record(action{name: "SaveSnap"}) + return nil } type readyNode struct { diff --git a/snap/snapshotter.go b/snap/snapshotter.go index b3d0466f0..3675b1045 100644 --- a/snap/snapshotter.go +++ b/snap/snapshotter.go @@ -52,11 +52,11 @@ func New(dir string) *Snapshotter { } } -func (s *Snapshotter) SaveSnap(snapshot raftpb.Snapshot) { +func (s *Snapshotter) SaveSnap(snapshot raftpb.Snapshot) error { if raft.IsEmptySnap(snapshot) { - return + return nil } - s.save(&snapshot) + return s.save(&snapshot) } func (s *Snapshotter) save(snapshot *raftpb.Snapshot) error { diff --git a/wal/wal.go b/wal/wal.go index 2655823ee..0051b8b09 100644 --- a/wal/wal.go +++ b/wal/wal.go @@ -273,13 +273,17 @@ func (w *WAL) SaveState(s *raftpb.HardState) error { return w.encoder.encode(rec) } -func (w *WAL) Save(st raftpb.HardState, ents []raftpb.Entry) { +func (w *WAL) Save(st raftpb.HardState, ents []raftpb.Entry) error { // TODO(xiangli): no more reference operator - w.SaveState(&st) - for i := range ents { - w.SaveEntry(&ents[i]) + if err := w.SaveState(&st); err != nil { + return err } - w.Sync() + for i := range ents { + if err := w.SaveEntry(&ents[i]); err != nil { + return err + } + } + return w.Sync() } func (w *WAL) saveCrc(prevCrc uint32) error {