etcdserver: always check if the data dir is writable before starting etcd

This commit is contained in:
Xiang Li
2015-12-29 10:40:58 -08:00
parent e44372e430
commit 22c3208fb3
2 changed files with 19 additions and 7 deletions

View File

@ -174,12 +174,17 @@ type EtcdServer struct {
// configuration is considered static for the lifetime of the EtcdServer. // configuration is considered static for the lifetime of the EtcdServer.
func NewServer(cfg *ServerConfig) (*EtcdServer, error) { func NewServer(cfg *ServerConfig) (*EtcdServer, error) {
st := store.New(StoreClusterPrefix, StoreKeysPrefix) st := store.New(StoreClusterPrefix, StoreKeysPrefix)
var w *wal.WAL var w *wal.WAL
var n raft.Node var n raft.Node
var s *raft.MemoryStorage var s *raft.MemoryStorage
var id types.ID var id types.ID
var cl *cluster var cl *cluster
if terr := fileutil.TouchDirAll(cfg.DataDir); terr != nil {
return nil, fmt.Errorf("cannot access data directory: %v", terr)
}
// Run the migrations. // Run the migrations.
dataVer, err := version.DetectDataDir(cfg.DataDir) dataVer, err := version.DetectDataDir(cfg.DataDir)
if err != nil { if err != nil {
@ -250,10 +255,6 @@ func NewServer(cfg *ServerConfig) (*EtcdServer, error) {
cfg.PrintWithInitial() cfg.PrintWithInitial()
id, n, s, w = startNode(cfg, cl, cl.MemberIDs()) id, n, s, w = startNode(cfg, cl, cl.MemberIDs())
case haveWAL: 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 { if err := fileutil.IsDirWriteable(cfg.MemberDir()); err != nil {
return nil, fmt.Errorf("cannot write to member directory: %v", err) 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") return nil, fmt.Errorf("unsupported bootstrap config")
} }
err = os.MkdirAll(cfg.MemberDir(), privateDirMode) if terr := fileutil.TouchDirAll(cfg.MemberDir()); terr != nil {
if err != nil && err != os.ErrExist { return nil, fmt.Errorf("cannot access member directory: %v", terr)
return nil, err
} }
sstats := &stats.ServerStats{ sstats := &stats.ServerStats{

View File

@ -25,6 +25,8 @@ import (
const ( const (
privateFileMode = 0600 privateFileMode = 0600
// owner can make/remove files inside the directory
privateDirMode = 0700
) )
var ( var (
@ -55,3 +57,13 @@ func ReadDir(dirpath string) ([]string, error) {
sort.Strings(names) sort.Strings(names)
return names, nil 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)
}