Browse code

Windows: Fail fs ops on running Hyper-V containers gracefully

Signed-off-by: John Howard (VM) <jhoward@ntdev.microsoft.com>

John Howard (VM) authored on 2017/03/16 03:29:12
Showing 3 changed files
... ...
@@ -34,6 +34,11 @@ func (daemon *Daemon) ContainerCopy(name string, res string) (io.ReadCloser, err
34 34
 		res = res[1:]
35 35
 	}
36 36
 
37
+	// Make sure an online file-system operation is permitted.
38
+	if err := daemon.isOnlineFSOperationPermitted(container); err != nil {
39
+		return nil, err
40
+	}
41
+
37 42
 	return daemon.containerCopy(container, res)
38 43
 }
39 44
 
... ...
@@ -45,6 +50,11 @@ func (daemon *Daemon) ContainerStatPath(name string, path string) (stat *types.C
45 45
 		return nil, err
46 46
 	}
47 47
 
48
+	// Make sure an online file-system operation is permitted.
49
+	if err := daemon.isOnlineFSOperationPermitted(container); err != nil {
50
+		return nil, err
51
+	}
52
+
48 53
 	return daemon.containerStatPath(container, path)
49 54
 }
50 55
 
... ...
@@ -57,6 +67,11 @@ func (daemon *Daemon) ContainerArchivePath(name string, path string) (content io
57 57
 		return nil, nil, err
58 58
 	}
59 59
 
60
+	// Make sure an online file-system operation is permitted.
61
+	if err := daemon.isOnlineFSOperationPermitted(container); err != nil {
62
+		return nil, nil, err
63
+	}
64
+
60 65
 	return daemon.containerArchivePath(container, path)
61 66
 }
62 67
 
... ...
@@ -72,6 +87,11 @@ func (daemon *Daemon) ContainerExtractToDir(name, path string, noOverwriteDirNon
72 72
 		return err
73 73
 	}
74 74
 
75
+	// Make sure an online file-system operation is permitted.
76
+	if err := daemon.isOnlineFSOperationPermitted(container); err != nil {
77
+		return err
78
+	}
79
+
75 80
 	return daemon.containerExtractToDir(container, path, noOverwriteDirNonDir, content)
76 81
 }
77 82
 
... ...
@@ -56,3 +56,9 @@ func fixPermissions(source, destination string, uid, gid int, destExisted bool)
56 56
 		return os.Lchown(fullpath, uid, gid)
57 57
 	})
58 58
 }
59
+
60
+// isOnlineFSOperationPermitted returns an error if an online filesystem operation
61
+// is not permitted.
62
+func (daemon *Daemon) isOnlineFSOperationPermitted(container *container.Container) error {
63
+	return nil
64
+}
... ...
@@ -1,6 +1,11 @@
1 1
 package daemon
2 2
 
3
-import "github.com/docker/docker/container"
3
+import (
4
+	"errors"
5
+
6
+	containertypes "github.com/docker/docker/api/types/container"
7
+	"github.com/docker/docker/container"
8
+)
4 9
 
5 10
 // checkIfPathIsInAVolume checks if the path is in a volume. If it is, it
6 11
 // 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)
16 16
 	// chown is not supported on Windows
17 17
 	return nil
18 18
 }
19
+
20
+// isOnlineFSOperationPermitted returns an error if an online filesystem operation
21
+// is not permitted (such as stat or for copying). Running Hyper-V containers
22
+// cannot have their file-system interrogated from the host as the filter is
23
+// loaded inside the utility VM, not the host.
24
+// IMPORTANT: The container lock must NOT be held when calling this function.
25
+func (daemon *Daemon) isOnlineFSOperationPermitted(container *container.Container) error {
26
+	if !container.IsRunning() {
27
+		return nil
28
+	}
29
+
30
+	// Determine isolation. If not specified in the hostconfig, use daemon default.
31
+	actualIsolation := container.HostConfig.Isolation
32
+	if containertypes.Isolation.IsDefault(containertypes.Isolation(actualIsolation)) {
33
+		actualIsolation = daemon.defaultIsolation
34
+	}
35
+	if containertypes.Isolation.IsHyperV(actualIsolation) {
36
+		return errors.New("filesystem operations against a running Hyper-V container are not supported")
37
+	}
38
+	return nil
39
+}