diff --git a/etcdmain/etcd.go b/etcdmain/etcd.go index 7c4de29c2..8e147a9e8 100644 --- a/etcdmain/etcd.go +++ b/etcdmain/etcd.go @@ -40,6 +40,7 @@ import ( "github.com/coreos/etcd/etcdserver/etcdserverpb" "github.com/coreos/etcd/pkg/cors" "github.com/coreos/etcd/pkg/fileutil" + pkgioutil "github.com/coreos/etcd/pkg/ioutil" "github.com/coreos/etcd/pkg/osutil" runtimeutil "github.com/coreos/etcd/pkg/runtime" "github.com/coreos/etcd/pkg/transport" @@ -409,7 +410,7 @@ func startProxy(cfg *config) error { return clientURLs } - err = ioutil.WriteFile(clusterfile+".bak", b, 0600) + err = pkgioutil.WriteAndSyncFile(clusterfile+".bak", b, 0600) if err != nil { plog.Warningf("proxy: error on writing urls %s", err) return clientURLs diff --git a/pkg/ioutil/util.go b/pkg/ioutil/util.go new file mode 100644 index 000000000..d7ed18b45 --- /dev/null +++ b/pkg/ioutil/util.go @@ -0,0 +1,41 @@ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package ioutil + +import ( + "io" + "os" +) + +// WriteAndSyncFile behaviors just like ioutil.WriteFile in standard library +// but calls Sync before closing the file. WriteAndSyncFile guarantees the data +// is synced if there is no error returned. +func WriteAndSyncFile(filename string, data []byte, perm os.FileMode) error { + f, err := os.OpenFile(filename, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm) + if err != nil { + return err + } + n, err := f.Write(data) + if err == nil && n < len(data) { + err = io.ErrShortWrite + } + if err == nil { + err = f.Sync() + } + if err1 := f.Close(); err == nil { + err = err1 + } + return err +}