summaryrefslogtreecommitdiff
path: root/daemon/daemon_windows.go
diff options
context:
space:
mode:
authorKir Kolyshkin <kolyshkin@gmail.com>2017-09-25 12:39:36 -0700
committerKir Kolyshkin <kolyshkin@gmail.com>2017-11-27 17:32:12 -0800
commit516010e92d56cfcd6d1e343bdc02b6f04bc43039 (patch)
tree32c23708a5221bc875c6a9330316c74ff7a28a5e /daemon/daemon_windows.go
parent2aa13f86f0c9cf3ed58a648a7b1506d4b06f3589 (diff)
downloaddocker-516010e92d56cfcd6d1e343bdc02b6f04bc43039.tar.gz
Simplify/fix MkdirAll usage
This subtle bug keeps lurking in because error checking for `Mkdir()` and `MkdirAll()` is slightly different wrt to `EEXIST`/`IsExist`: - for `Mkdir()`, `IsExist` error should (usually) be ignored (unless you want to make sure directory was not there before) as it means "the destination directory was already there" - for `MkdirAll()`, `IsExist` error should NEVER be ignored. Mostly, this commit just removes ignoring the IsExist error, as it should not be ignored. Also, there are a couple of cases then IsExist is handled as "directory already exist" which is wrong. As a result, some code that never worked as intended is now removed. NOTE that `idtools.MkdirAndChown()` behaves like `os.MkdirAll()` rather than `os.Mkdir()` -- so its description is amended accordingly, and its usage is handled as such (i.e. IsExist error is not ignored). For more details, a quote from my runc commit 6f82d4b (July 2015): TL;DR: check for IsExist(err) after a failed MkdirAll() is both redundant and wrong -- so two reasons to remove it. Quoting MkdirAll documentation: > MkdirAll creates a directory named path, along with any necessary > parents, and returns nil, or else returns an error. If path > is already a directory, MkdirAll does nothing and returns nil. This means two things: 1. If a directory to be created already exists, no error is returned. 2. If the error returned is IsExist (EEXIST), it means there exists a non-directory with the same name as MkdirAll need to use for directory. Example: we want to MkdirAll("a/b"), but file "a" (or "a/b") already exists, so MkdirAll fails. The above is a theory, based on quoted documentation and my UNIX knowledge. 3. In practice, though, current MkdirAll implementation [1] returns ENOTDIR in most of cases described in #2, with the exception when there is a race between MkdirAll and someone else creating the last component of MkdirAll argument as a file. In this very case MkdirAll() will indeed return EEXIST. Because of #1, IsExist check after MkdirAll is not needed. Because of #2 and #3, ignoring IsExist error is just plain wrong, as directory we require is not created. It's cleaner to report the error now. Note this error is all over the tree, I guess due to copy-paste, or trying to follow the same usage pattern as for Mkdir(), or some not quite correct examples on the Internet. [1] https://github.com/golang/go/blob/f9ed2f75/src/os/path.go Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
Diffstat (limited to 'daemon/daemon_windows.go')
-rw-r--r--daemon/daemon_windows.go3
1 files changed, 1 insertions, 2 deletions
diff --git a/daemon/daemon_windows.go b/daemon/daemon_windows.go
index 8545a2f651..8029bbf0ef 100644
--- a/daemon/daemon_windows.go
+++ b/daemon/daemon_windows.go
@@ -3,7 +3,6 @@ package daemon
import (
"context"
"fmt"
- "os"
"path/filepath"
"strings"
@@ -485,7 +484,7 @@ func setupRemappedRoot(config *config.Config) (*idtools.IDMappings, error) {
func setupDaemonRoot(config *config.Config, rootDir string, rootIDs idtools.IDPair) error {
config.Root = rootDir
// Create the root directory if it doesn't exists
- if err := system.MkdirAllWithACL(config.Root, 0, system.SddlAdministratorsLocalSystem); err != nil && !os.IsExist(err) {
+ if err := system.MkdirAllWithACL(config.Root, 0, system.SddlAdministratorsLocalSystem); err != nil {
return err
}
return nil