Ver código fonte

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

Xiang Li 10 anos atrás
pai
commit
150e646b05
2 arquivos alterados com 18 adições e 7 exclusões
  1. 6 7
      etcdserver/server.go
  2. 12 0
      pkg/fileutil/fileutil.go

+ 6 - 7
etcdserver/server.go

@@ -204,6 +204,10 @@ func NewServer(cfg *ServerConfig) (*EtcdServer, error) {
 		cl *cluster
 	)
 
+	if terr := fileutil.TouchDirAll(cfg.DataDir); terr != nil {
+		return nil, fmt.Errorf("cannot access data directory: %v", terr)
+	}
+
 	if !cfg.V3demo && fileutil.Exist(path.Join(cfg.SnapDir(), databaseFilename)) {
 		return nil, errors.New("experimental-v3demo cannot be disabled once it is enabled")
 	}
@@ -284,10 +288,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)
 		}
@@ -323,9 +323,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{

+ 12 - 0
pkg/fileutil/fileutil.go

@@ -26,6 +26,8 @@ import (
 
 const (
 	privateFileMode = 0600
+	// owner can make/remove files inside the directory
+	privateDirMode = 0700
 )
 
 var (
@@ -57,6 +59,16 @@ func ReadDir(dirpath string) ([]string, error) {
 	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)
+}
+
 func Exist(name string) bool {
 	_, err := os.Stat(name)
 	return err == nil