Explorar el Código

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

Signed-off-by: John Howard (VM) <jhoward@ntdev.microsoft.com>
John Howard (VM) hace 8 años
padre
commit
481d2633fe
Se han modificado 3 ficheros con 53 adiciones y 1 borrados
  1. 20 0
      daemon/archive.go
  2. 6 0
      daemon/archive_unix.go
  3. 27 1
      daemon/archive_windows.go

+ 20 - 0
daemon/archive.go

@@ -34,6 +34,11 @@ func (daemon *Daemon) ContainerCopy(name string, res string) (io.ReadCloser, err
 		res = res[1:]
 		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)
 	return daemon.containerCopy(container, res)
 }
 }
 
 
@@ -45,6 +50,11 @@ func (daemon *Daemon) ContainerStatPath(name string, path string) (stat *types.C
 		return nil, err
 		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)
 	return daemon.containerStatPath(container, path)
 }
 }
 
 
@@ -57,6 +67,11 @@ func (daemon *Daemon) ContainerArchivePath(name string, path string) (content io
 		return nil, nil, err
 		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)
 	return daemon.containerArchivePath(container, path)
 }
 }
 
 
@@ -72,6 +87,11 @@ func (daemon *Daemon) ContainerExtractToDir(name, path string, noOverwriteDirNon
 		return err
 		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)
 	return daemon.containerExtractToDir(container, path, noOverwriteDirNonDir, content)
 }
 }
 
 

+ 6 - 0
daemon/archive_unix.go

@@ -56,3 +56,9 @@ func fixPermissions(source, destination string, uid, gid int, destExisted bool)
 		return os.Lchown(fullpath, uid, gid)
 		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
+}

+ 27 - 1
daemon/archive_windows.go

@@ -1,6 +1,11 @@
 package daemon
 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
 // 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
 // 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
 	// chown is not supported on Windows
 	return nil
 	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
+}