From 0e370a34027914f4894fbe03302c9701757ef02f Mon Sep 17 00:00:00 2001 From: "John Howard (VM)" Date: Wed, 15 Mar 2017 11:29:12 -0700 Subject: [PATCH] Windows: Fail fs ops on running Hyper-V containers gracefully Signed-off-by: John Howard (VM) Upstream-commit: 481d2633fee30bdc4d00b9d61b031064f5af5739 Component: engine --- components/engine/daemon/archive.go | 20 +++++++++++++++ components/engine/daemon/archive_unix.go | 6 +++++ components/engine/daemon/archive_windows.go | 28 ++++++++++++++++++++- 3 files changed, 53 insertions(+), 1 deletion(-) diff --git a/components/engine/daemon/archive.go b/components/engine/daemon/archive.go index 1999f1243b..4dc43344d1 100644 --- a/components/engine/daemon/archive.go +++ b/components/engine/daemon/archive.go @@ -34,6 +34,11 @@ func (daemon *Daemon) ContainerCopy(name string, res string) (io.ReadCloser, err res = res[1:] } + // Make sure an online file-system operation is permitted. + if err := daemon.isOnlineFSOperationPermitted(container); err != nil { + return nil, err + } + return daemon.containerCopy(container, res) } @@ -45,6 +50,11 @@ func (daemon *Daemon) ContainerStatPath(name string, path string) (stat *types.C return nil, err } + // Make sure an online file-system operation is permitted. + if err := daemon.isOnlineFSOperationPermitted(container); err != nil { + return nil, err + } + return daemon.containerStatPath(container, path) } @@ -57,6 +67,11 @@ func (daemon *Daemon) ContainerArchivePath(name string, path string) (content io return nil, nil, err } + // Make sure an online file-system operation is permitted. + if err := daemon.isOnlineFSOperationPermitted(container); err != nil { + return nil, nil, err + } + return daemon.containerArchivePath(container, path) } @@ -72,6 +87,11 @@ func (daemon *Daemon) ContainerExtractToDir(name, path string, noOverwriteDirNon return err } + // Make sure an online file-system operation is permitted. + if err := daemon.isOnlineFSOperationPermitted(container); err != nil { + return err + } + return daemon.containerExtractToDir(container, path, noOverwriteDirNonDir, content) } diff --git a/components/engine/daemon/archive_unix.go b/components/engine/daemon/archive_unix.go index 47666fe5e8..8806e2e198 100644 --- a/components/engine/daemon/archive_unix.go +++ b/components/engine/daemon/archive_unix.go @@ -56,3 +56,9 @@ func fixPermissions(source, destination string, uid, gid int, destExisted bool) return os.Lchown(fullpath, uid, gid) }) } + +// isOnlineFSOperationPermitted returns an error if an online filesystem operation +// is not permitted. +func (daemon *Daemon) isOnlineFSOperationPermitted(container *container.Container) error { + return nil +} diff --git a/components/engine/daemon/archive_windows.go b/components/engine/daemon/archive_windows.go index b3a1045341..1c5a894f7c 100644 --- a/components/engine/daemon/archive_windows.go +++ b/components/engine/daemon/archive_windows.go @@ -1,6 +1,11 @@ package daemon -import "github.com/docker/docker/container" +import ( + "errors" + + containertypes "github.com/docker/docker/api/types/container" + "github.com/docker/docker/container" +) // checkIfPathIsInAVolume checks if the path is in a volume. If it is, it // cannot be in a read-only volume. If it is not in a volume, the container @@ -16,3 +21,24 @@ func fixPermissions(source, destination string, uid, gid int, destExisted bool) // chown is not supported on Windows return nil } + +// isOnlineFSOperationPermitted returns an error if an online filesystem operation +// is not permitted (such as stat or for copying). Running Hyper-V containers +// cannot have their file-system interrogated from the host as the filter is +// loaded inside the utility VM, not the host. +// IMPORTANT: The container lock must NOT be held when calling this function. +func (daemon *Daemon) isOnlineFSOperationPermitted(container *container.Container) error { + if !container.IsRunning() { + return nil + } + + // Determine isolation. If not specified in the hostconfig, use daemon default. + actualIsolation := container.HostConfig.Isolation + if containertypes.Isolation.IsDefault(containertypes.Isolation(actualIsolation)) { + actualIsolation = daemon.defaultIsolation + } + if containertypes.Isolation.IsHyperV(actualIsolation) { + return errors.New("filesystem operations against a running Hyper-V container are not supported") + } + return nil +}