From 22c3208fb3b351f9acbace05385cf44fe8c6260c Mon Sep 17 00:00:00 2001 From: Xiang Li Date: Tue, 29 Dec 2015 10:40:58 -0800 Subject: [PATCH] etcdserver: always check if the data dir is writable before starting etcd --- etcdserver/server.go | 14 +++++++------- pkg/fileutil/fileutil.go | 12 ++++++++++++ 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/etcdserver/server.go b/etcdserver/server.go index 44605cf01..cf4ac01d9 100644 --- a/etcdserver/server.go +++ b/etcdserver/server.go @@ -174,12 +174,17 @@ type EtcdServer struct { // configuration is considered static for the lifetime of the EtcdServer. func NewServer(cfg *ServerConfig) (*EtcdServer, error) { st := store.New(StoreClusterPrefix, StoreKeysPrefix) + var w *wal.WAL var n raft.Node var s *raft.MemoryStorage var id types.ID var cl *cluster + if terr := fileutil.TouchDirAll(cfg.DataDir); terr != nil { + return nil, fmt.Errorf("cannot access data directory: %v", terr) + } + // Run the migrations. dataVer, err := version.DetectDataDir(cfg.DataDir) if err != nil { @@ -250,10 +255,6 @@ func NewServer(cfg *ServerConfig) (*EtcdServer, error) { cfg.PrintWithInitial() id, n, s, w = startNode(cfg, cl, cl.MemberIDs()) case haveWAL: - if err := fileutil.IsDirWriteable(cfg.DataDir); err != nil { - return nil, fmt.Errorf("cannot write to data directory: %v", err) - } - if err := fileutil.IsDirWriteable(cfg.MemberDir()); err != nil { return nil, fmt.Errorf("cannot write to member directory: %v", err) } @@ -290,9 +291,8 @@ func NewServer(cfg *ServerConfig) (*EtcdServer, error) { return nil, fmt.Errorf("unsupported bootstrap config") } - err = os.MkdirAll(cfg.MemberDir(), privateDirMode) - if err != nil && err != os.ErrExist { - return nil, err + if terr := fileutil.TouchDirAll(cfg.MemberDir()); terr != nil { + return nil, fmt.Errorf("cannot access member directory: %v", terr) } sstats := &stats.ServerStats{ diff --git a/pkg/fileutil/fileutil.go b/pkg/fileutil/fileutil.go index acb7a6b81..16f6564f6 100644 --- a/pkg/fileutil/fileutil.go +++ b/pkg/fileutil/fileutil.go @@ -25,6 +25,8 @@ import ( const ( privateFileMode = 0600 + // owner can make/remove files inside the directory + privateDirMode = 0700 ) var ( @@ -55,3 +57,13 @@ func ReadDir(dirpath string) ([]string, error) { sort.Strings(names) return names, nil } + +// TouchDirAll is simliar to os.MkdirAll. It creates directories with 0700 permission if any directory +// does not exists. TouchDirAll also ensures the given directory is writable. +func TouchDirAll(dir string) error { + err := os.MkdirAll(dir, privateDirMode) + if err != nil && err != os.ErrExist { + return err + } + return IsDirWriteable(dir) +}