Signed-off-by: Amit Krishnan <krish.amit@gmail.com>
| 1 | 1 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,74 @@ |
| 0 |
+// +build solaris |
|
| 1 |
+ |
|
| 2 |
+package main |
|
| 3 |
+ |
|
| 4 |
+import ( |
|
| 5 |
+ "fmt" |
|
| 6 |
+ "net" |
|
| 7 |
+ "os" |
|
| 8 |
+ "path/filepath" |
|
| 9 |
+ "syscall" |
|
| 10 |
+ |
|
| 11 |
+ "github.com/docker/docker/libcontainerd" |
|
| 12 |
+ "github.com/docker/docker/pkg/system" |
|
| 13 |
+) |
|
| 14 |
+ |
|
| 15 |
+const defaultDaemonConfigFile = "" |
|
| 16 |
+ |
|
| 17 |
+// currentUserIsOwner checks whether the current user is the owner of the given |
|
| 18 |
+// file. |
|
| 19 |
+func currentUserIsOwner(f string) bool {
|
|
| 20 |
+ if fileInfo, err := system.Stat(f); err == nil && fileInfo != nil {
|
|
| 21 |
+ if int(fileInfo.UID()) == os.Getuid() {
|
|
| 22 |
+ return true |
|
| 23 |
+ } |
|
| 24 |
+ } |
|
| 25 |
+ return false |
|
| 26 |
+} |
|
| 27 |
+ |
|
| 28 |
+// setDefaultUmask sets the umask to 0022 to avoid problems |
|
| 29 |
+// caused by custom umask |
|
| 30 |
+func setDefaultUmask() error {
|
|
| 31 |
+ desiredUmask := 0022 |
|
| 32 |
+ syscall.Umask(desiredUmask) |
|
| 33 |
+ if umask := syscall.Umask(desiredUmask); umask != desiredUmask {
|
|
| 34 |
+ return fmt.Errorf("failed to set umask: expected %#o, got %#o", desiredUmask, umask)
|
|
| 35 |
+ } |
|
| 36 |
+ |
|
| 37 |
+ return nil |
|
| 38 |
+} |
|
| 39 |
+ |
|
| 40 |
+func getDaemonConfDir() string {
|
|
| 41 |
+ return "/etc/docker" |
|
| 42 |
+} |
|
| 43 |
+ |
|
| 44 |
+// setupConfigReloadTrap configures the USR2 signal to reload the configuration. |
|
| 45 |
+func (cli *DaemonCli) setupConfigReloadTrap() {
|
|
| 46 |
+} |
|
| 47 |
+ |
|
| 48 |
+// notifySystem sends a message to the host when the server is ready to be used |
|
| 49 |
+func notifySystem() {
|
|
| 50 |
+} |
|
| 51 |
+ |
|
| 52 |
+func (cli *DaemonCli) getPlatformRemoteOptions() []libcontainerd.RemoteOption {
|
|
| 53 |
+ opts := []libcontainerd.RemoteOption{}
|
|
| 54 |
+ return opts |
|
| 55 |
+} |
|
| 56 |
+ |
|
| 57 |
+// getLibcontainerdRoot gets the root directory for libcontainerd/containerd to |
|
| 58 |
+// store their state. |
|
| 59 |
+func (cli *DaemonCli) getLibcontainerdRoot() string {
|
|
| 60 |
+ return filepath.Join(cli.Config.ExecRoot, "libcontainerd") |
|
| 61 |
+} |
|
| 62 |
+ |
|
| 63 |
+func allocateDaemonPort(addr string) error {
|
|
| 64 |
+ return nil |
|
| 65 |
+} |
|
| 66 |
+ |
|
| 67 |
+// notifyShutdown is called after the daemon shuts down but before the process exits. |
|
| 68 |
+func notifyShutdown(err error) {
|
|
| 69 |
+} |
|
| 70 |
+ |
|
| 71 |
+func wrapListeners(proto string, ls []net.Listener) []net.Listener {
|
|
| 72 |
+ return ls |
|
| 73 |
+} |
| 5 | 5 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,95 @@ |
| 0 |
+// +build solaris |
|
| 1 |
+ |
|
| 2 |
+package container |
|
| 3 |
+ |
|
| 4 |
+import ( |
|
| 5 |
+ "os" |
|
| 6 |
+ "path/filepath" |
|
| 7 |
+ |
|
| 8 |
+ "github.com/docker/docker/volume" |
|
| 9 |
+ "github.com/docker/engine-api/types/container" |
|
| 10 |
+) |
|
| 11 |
+ |
|
| 12 |
+// Container holds fields specific to the Solaris implementation. See |
|
| 13 |
+// CommonContainer for standard fields common to all containers. |
|
| 14 |
+type Container struct {
|
|
| 15 |
+ CommonContainer |
|
| 16 |
+ |
|
| 17 |
+ // fields below here are platform specific. |
|
| 18 |
+ HostnamePath string |
|
| 19 |
+ HostsPath string |
|
| 20 |
+ ResolvConfPath string |
|
| 21 |
+} |
|
| 22 |
+ |
|
| 23 |
+// ExitStatus provides exit reasons for a container. |
|
| 24 |
+type ExitStatus struct {
|
|
| 25 |
+ // The exit code with which the container exited. |
|
| 26 |
+ ExitCode int |
|
| 27 |
+} |
|
| 28 |
+ |
|
| 29 |
+// CreateDaemonEnvironment creates a new environment variable slice for this container. |
|
| 30 |
+func (container *Container) CreateDaemonEnvironment(linkedEnv []string) []string {
|
|
| 31 |
+ return nil |
|
| 32 |
+} |
|
| 33 |
+ |
|
| 34 |
+func appendNetworkMounts(container *Container, volumeMounts []volume.MountPoint) ([]volume.MountPoint, error) {
|
|
| 35 |
+ return volumeMounts, nil |
|
| 36 |
+} |
|
| 37 |
+ |
|
| 38 |
+// TrySetNetworkMount attempts to set the network mounts given a provided destination and |
|
| 39 |
+// the path to use for it; return true if the given destination was a network mount file |
|
| 40 |
+func (container *Container) TrySetNetworkMount(destination string, path string) bool {
|
|
| 41 |
+ return true |
|
| 42 |
+} |
|
| 43 |
+ |
|
| 44 |
+// NetworkMounts returns the list of network mounts. |
|
| 45 |
+func (container *Container) NetworkMounts() []Mount {
|
|
| 46 |
+ var mount []Mount |
|
| 47 |
+ return mount |
|
| 48 |
+} |
|
| 49 |
+ |
|
| 50 |
+// CopyImagePathContent copies files in destination to the volume. |
|
| 51 |
+func (container *Container) CopyImagePathContent(v volume.Volume, destination string) error {
|
|
| 52 |
+ return nil |
|
| 53 |
+} |
|
| 54 |
+ |
|
| 55 |
+// UnmountIpcMounts unmount Ipc related mounts. |
|
| 56 |
+func (container *Container) UnmountIpcMounts(unmount func(pth string) error) {
|
|
| 57 |
+} |
|
| 58 |
+ |
|
| 59 |
+// IpcMounts returns the list of Ipc related mounts. |
|
| 60 |
+func (container *Container) IpcMounts() []Mount {
|
|
| 61 |
+ return nil |
|
| 62 |
+} |
|
| 63 |
+ |
|
| 64 |
+// UpdateContainer updates configuration of a container |
|
| 65 |
+func (container *Container) UpdateContainer(hostConfig *container.HostConfig) error {
|
|
| 66 |
+ return nil |
|
| 67 |
+} |
|
| 68 |
+ |
|
| 69 |
+// UnmountVolumes explicitly unmounts volumes from the container. |
|
| 70 |
+func (container *Container) UnmountVolumes(forceSyscall bool, volumeEventLog func(name, action string, attributes map[string]string)) error {
|
|
| 71 |
+ return nil |
|
| 72 |
+} |
|
| 73 |
+ |
|
| 74 |
+// TmpfsMounts returns the list of tmpfs mounts |
|
| 75 |
+func (container *Container) TmpfsMounts() []Mount {
|
|
| 76 |
+ var mounts []Mount |
|
| 77 |
+ return mounts |
|
| 78 |
+} |
|
| 79 |
+ |
|
| 80 |
+// cleanResourcePath cleans a resource path and prepares to combine with mnt path |
|
| 81 |
+func cleanResourcePath(path string) string {
|
|
| 82 |
+ return filepath.Join(string(os.PathSeparator), path) |
|
| 83 |
+} |
|
| 84 |
+ |
|
| 85 |
+// BuildHostnameFile writes the container's hostname file. |
|
| 86 |
+func (container *Container) BuildHostnameFile() error {
|
|
| 87 |
+ return nil |
|
| 88 |
+} |
|
| 89 |
+ |
|
| 90 |
+// canMountFS determines if the file system for the container |
|
| 91 |
+// can be mounted locally. A no-op on non-Windows platforms |
|
| 92 |
+func (container *Container) canMountFS() bool {
|
|
| 93 |
+ return true |
|
| 94 |
+} |
| 0 | 95 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,7 @@ |
| 0 |
+package container |
|
| 1 |
+ |
|
| 2 |
+// setFromExitStatus is a platform specific helper function to set the state |
|
| 3 |
+// based on the ExitStatus structure. |
|
| 4 |
+func (s *State) setFromExitStatus(exitStatus *ExitStatus) {
|
|
| 5 |
+ s.ExitCode = exitStatus.ExitCode |
|
| 6 |
+} |
| 0 | 7 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,39 @@ |
| 0 |
+package daemon |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ flag "github.com/docker/docker/pkg/mflag" |
|
| 4 |
+) |
|
| 5 |
+ |
|
| 6 |
+var ( |
|
| 7 |
+ defaultPidFile = "/var/run/docker.pid" |
|
| 8 |
+ defaultGraph = "/var/lib/docker" |
|
| 9 |
+ defaultExec = "zones" |
|
| 10 |
+) |
|
| 11 |
+ |
|
| 12 |
+// Config defines the configuration of a docker daemon. |
|
| 13 |
+// These are the configuration settings that you pass |
|
| 14 |
+// to the docker daemon when you launch it with say: `docker -d -e lxc` |
|
| 15 |
+type Config struct {
|
|
| 16 |
+ CommonConfig |
|
| 17 |
+ |
|
| 18 |
+ // Fields below here are platform specific. |
|
| 19 |
+ ExecRoot string `json:"exec-root,omitempty"` |
|
| 20 |
+} |
|
| 21 |
+ |
|
| 22 |
+// bridgeConfig stores all the bridge driver specific |
|
| 23 |
+// configuration. |
|
| 24 |
+type bridgeConfig struct {
|
|
| 25 |
+ commonBridgeConfig |
|
| 26 |
+} |
|
| 27 |
+ |
|
| 28 |
+// InstallFlags adds command-line options to the top-level flag parser for |
|
| 29 |
+// the current process. |
|
| 30 |
+// Subsequent calls to `flag.Parse` will populate config with values parsed |
|
| 31 |
+// from the command-line. |
|
| 32 |
+func (config *Config) InstallFlags(cmd *flag.FlagSet, usageFn func(string) string) {
|
|
| 33 |
+ // First handle install flags which are consistent cross-platform |
|
| 34 |
+ config.InstallCommonFlags(cmd, usageFn) |
|
| 35 |
+ |
|
| 36 |
+ // Then platform-specific install flags |
|
| 37 |
+ config.attachExperimentalFlags(cmd, usageFn) |
|
| 38 |
+} |
| 0 | 39 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,50 @@ |
| 0 |
+// +build solaris |
|
| 1 |
+ |
|
| 2 |
+package daemon |
|
| 3 |
+ |
|
| 4 |
+import ( |
|
| 5 |
+ "fmt" |
|
| 6 |
+ |
|
| 7 |
+ "github.com/docker/docker/container" |
|
| 8 |
+ networktypes "github.com/docker/engine-api/types/network" |
|
| 9 |
+ "github.com/docker/libnetwork" |
|
| 10 |
+) |
|
| 11 |
+ |
|
| 12 |
+func (daemon *Daemon) setupLinkedContainers(container *container.Container) ([]string, error) {
|
|
| 13 |
+ return nil, nil |
|
| 14 |
+} |
|
| 15 |
+ |
|
| 16 |
+// ConnectToNetwork connects a container to a network |
|
| 17 |
+func (daemon *Daemon) ConnectToNetwork(container *container.Container, idOrName string, endpointConfig *networktypes.EndpointSettings) error {
|
|
| 18 |
+ return fmt.Errorf("Solaris does not support connecting a running container to a network")
|
|
| 19 |
+} |
|
| 20 |
+ |
|
| 21 |
+// getSize returns real size & virtual size |
|
| 22 |
+func (daemon *Daemon) getSize(container *container.Container) (int64, int64) {
|
|
| 23 |
+ return 0, 0 |
|
| 24 |
+} |
|
| 25 |
+ |
|
| 26 |
+// DisconnectFromNetwork disconnects a container from the network |
|
| 27 |
+func (daemon *Daemon) DisconnectFromNetwork(container *container.Container, n libnetwork.Network, force bool) error {
|
|
| 28 |
+ return fmt.Errorf("Solaris does not support disconnecting a running container from a network")
|
|
| 29 |
+} |
|
| 30 |
+ |
|
| 31 |
+func (daemon *Daemon) setupIpcDirs(container *container.Container) error {
|
|
| 32 |
+ return nil |
|
| 33 |
+} |
|
| 34 |
+ |
|
| 35 |
+func (daemon *Daemon) mountVolumes(container *container.Container) error {
|
|
| 36 |
+ return nil |
|
| 37 |
+} |
|
| 38 |
+ |
|
| 39 |
+func killProcessDirectly(container *container.Container) error {
|
|
| 40 |
+ return nil |
|
| 41 |
+} |
|
| 42 |
+ |
|
| 43 |
+func detachMounted(path string) error {
|
|
| 44 |
+ return nil |
|
| 45 |
+} |
|
| 46 |
+ |
|
| 47 |
+func isLinkable(child *container.Container) bool {
|
|
| 48 |
+ return false |
|
| 49 |
+} |
| ... | ... |
@@ -799,7 +799,7 @@ func NewDaemon(config *Config, registryService *registry.Service, containerdRemo |
| 799 | 799 |
sysInfo := sysinfo.New(false) |
| 800 | 800 |
// Check if Devices cgroup is mounted, it is hard requirement for container security, |
| 801 | 801 |
// on Linux/FreeBSD. |
| 802 |
- if runtime.GOOS != "windows" && !sysInfo.CgroupDevicesEnabled {
|
|
| 802 |
+ if runtime.GOOS != "windows" && runtime.GOOS != "solaris" && !sysInfo.CgroupDevicesEnabled {
|
|
| 803 | 803 |
return nil, fmt.Errorf("Devices cgroup isn't mounted")
|
| 804 | 804 |
} |
| 805 | 805 |
|
| 806 | 806 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,159 @@ |
| 0 |
+// +build solaris,cgo |
|
| 1 |
+ |
|
| 2 |
+package daemon |
|
| 3 |
+ |
|
| 4 |
+import ( |
|
| 5 |
+ "fmt" |
|
| 6 |
+ |
|
| 7 |
+ "github.com/docker/docker/container" |
|
| 8 |
+ "github.com/docker/docker/image" |
|
| 9 |
+ "github.com/docker/docker/layer" |
|
| 10 |
+ "github.com/docker/docker/pkg/idtools" |
|
| 11 |
+ "github.com/docker/docker/pkg/parsers/kernel" |
|
| 12 |
+ "github.com/docker/docker/reference" |
|
| 13 |
+ "github.com/docker/engine-api/types" |
|
| 14 |
+ containertypes "github.com/docker/engine-api/types/container" |
|
| 15 |
+ "github.com/docker/libnetwork" |
|
| 16 |
+ nwconfig "github.com/docker/libnetwork/config" |
|
| 17 |
+) |
|
| 18 |
+ |
|
| 19 |
+//#include <zone.h> |
|
| 20 |
+import "C" |
|
| 21 |
+ |
|
| 22 |
+const ( |
|
| 23 |
+ defaultVirtualSwitch = "Virtual Switch" |
|
| 24 |
+ platformSupported = true |
|
| 25 |
+ solarisMinCPUShares = 1 |
|
| 26 |
+ solarisMaxCPUShares = 65535 |
|
| 27 |
+) |
|
| 28 |
+ |
|
| 29 |
+func (daemon *Daemon) cleanupMountsByID(id string) error {
|
|
| 30 |
+ return nil |
|
| 31 |
+} |
|
| 32 |
+ |
|
| 33 |
+func parseSecurityOpt(container *container.Container, config *containertypes.HostConfig) error {
|
|
| 34 |
+ return nil |
|
| 35 |
+} |
|
| 36 |
+ |
|
| 37 |
+func setupRemappedRoot(config *Config) ([]idtools.IDMap, []idtools.IDMap, error) {
|
|
| 38 |
+ return nil, nil, nil |
|
| 39 |
+} |
|
| 40 |
+ |
|
| 41 |
+func setupDaemonRoot(config *Config, rootDir string, rootUID, rootGID int) error {
|
|
| 42 |
+ return nil |
|
| 43 |
+} |
|
| 44 |
+ |
|
| 45 |
+// setupInitLayer populates a directory with mountpoints suitable |
|
| 46 |
+// for bind-mounting dockerinit into the container. The mountpoint is simply an |
|
| 47 |
+// empty file at /.dockerinit |
|
| 48 |
+// |
|
| 49 |
+// This extra layer is used by all containers as the top-most ro layer. It protects |
|
| 50 |
+// the container from unwanted side-effects on the rw layer. |
|
| 51 |
+func setupInitLayer(initLayer string, rootUID, rootGID int) error {
|
|
| 52 |
+ return nil |
|
| 53 |
+} |
|
| 54 |
+ |
|
| 55 |
+func checkKernel() error {
|
|
| 56 |
+ // solaris can rely upon checkSystem() below, we don't skew kernel versions |
|
| 57 |
+ return nil |
|
| 58 |
+} |
|
| 59 |
+ |
|
| 60 |
+func (daemon *Daemon) getCgroupDriver() string {
|
|
| 61 |
+ return "" |
|
| 62 |
+} |
|
| 63 |
+ |
|
| 64 |
+func (daemon *Daemon) adaptContainerSettings(hostConfig *containertypes.HostConfig, adjustCPUShares bool) error {
|
|
| 65 |
+ return nil |
|
| 66 |
+} |
|
| 67 |
+ |
|
| 68 |
+// verifyPlatformContainerSettings performs platform-specific validation of the |
|
| 69 |
+// hostconfig and config structures. |
|
| 70 |
+func verifyPlatformContainerSettings(daemon *Daemon, hostConfig *containertypes.HostConfig, config *containertypes.Config, update bool) ([]string, error) {
|
|
| 71 |
+ warnings := []string{}
|
|
| 72 |
+ return warnings, nil |
|
| 73 |
+} |
|
| 74 |
+ |
|
| 75 |
+// verifyDaemonSettings performs validation of daemon config struct |
|
| 76 |
+func verifyDaemonSettings(config *Config) error {
|
|
| 77 |
+ // checkSystem validates platform-specific requirements |
|
| 78 |
+ return nil |
|
| 79 |
+} |
|
| 80 |
+ |
|
| 81 |
+func checkSystem() error {
|
|
| 82 |
+ // check OS version for compatibility, ensure running in global zone |
|
| 83 |
+ var err error |
|
| 84 |
+ var id C.zoneid_t |
|
| 85 |
+ |
|
| 86 |
+ if id, err = C.getzoneid(); err != nil {
|
|
| 87 |
+ return fmt.Errorf("Exiting. Error getting zone id: %+v", err)
|
|
| 88 |
+ } |
|
| 89 |
+ if int(id) != 0 {
|
|
| 90 |
+ return fmt.Errorf("Exiting because the Docker daemon is not running in the global zone")
|
|
| 91 |
+ } |
|
| 92 |
+ |
|
| 93 |
+ v, err := kernel.GetKernelVersion() |
|
| 94 |
+ if kernel.CompareKernelVersion(*v, kernel.VersionInfo{Kernel: 5, Major: 12, Minor: 0}) < 0 {
|
|
| 95 |
+ return fmt.Errorf("Your Solaris kernel version: %s doesn't support Docker. Please upgrade to 5.12.0", v.String())
|
|
| 96 |
+ } |
|
| 97 |
+ return err |
|
| 98 |
+} |
|
| 99 |
+ |
|
| 100 |
+// configureMaxThreads sets the Go runtime max threads threshold |
|
| 101 |
+// which is 90% of the kernel setting from /proc/sys/kernel/threads-max |
|
| 102 |
+func configureMaxThreads(config *Config) error {
|
|
| 103 |
+ return nil |
|
| 104 |
+} |
|
| 105 |
+ |
|
| 106 |
+// configureKernelSecuritySupport configures and validate security support for the kernel |
|
| 107 |
+func configureKernelSecuritySupport(config *Config, driverName string) error {
|
|
| 108 |
+ return nil |
|
| 109 |
+} |
|
| 110 |
+ |
|
| 111 |
+func (daemon *Daemon) initNetworkController(config *Config) (libnetwork.NetworkController, error) {
|
|
| 112 |
+ return nil, nil |
|
| 113 |
+} |
|
| 114 |
+ |
|
| 115 |
+// registerLinks sets up links between containers and writes the |
|
| 116 |
+// configuration out for persistence. |
|
| 117 |
+func (daemon *Daemon) registerLinks(container *container.Container, hostConfig *containertypes.HostConfig) error {
|
|
| 118 |
+ return nil |
|
| 119 |
+} |
|
| 120 |
+ |
|
| 121 |
+func (daemon *Daemon) cleanupMounts() error {
|
|
| 122 |
+ return nil |
|
| 123 |
+} |
|
| 124 |
+ |
|
| 125 |
+// conditionalMountOnStart is a platform specific helper function during the |
|
| 126 |
+// container start to call mount. |
|
| 127 |
+func (daemon *Daemon) conditionalMountOnStart(container *container.Container) error {
|
|
| 128 |
+ return nil |
|
| 129 |
+} |
|
| 130 |
+ |
|
| 131 |
+// conditionalUnmountOnCleanup is a platform specific helper function called |
|
| 132 |
+// during the cleanup of a container to unmount. |
|
| 133 |
+func (daemon *Daemon) conditionalUnmountOnCleanup(container *container.Container) error {
|
|
| 134 |
+ return daemon.Unmount(container) |
|
| 135 |
+} |
|
| 136 |
+ |
|
| 137 |
+func restoreCustomImage(is image.Store, ls layer.Store, rs reference.Store) error {
|
|
| 138 |
+ // Solaris has no custom images to register |
|
| 139 |
+ return nil |
|
| 140 |
+} |
|
| 141 |
+ |
|
| 142 |
+func driverOptions(config *Config) []nwconfig.Option {
|
|
| 143 |
+ return []nwconfig.Option{}
|
|
| 144 |
+} |
|
| 145 |
+ |
|
| 146 |
+func (daemon *Daemon) stats(c *container.Container) (*types.StatsJSON, error) {
|
|
| 147 |
+ return nil, nil |
|
| 148 |
+} |
|
| 149 |
+ |
|
| 150 |
+// setDefaultIsolation determine the default isolation mode for the |
|
| 151 |
+// daemon to run in. This is only applicable on Windows |
|
| 152 |
+func (daemon *Daemon) setDefaultIsolation() error {
|
|
| 153 |
+ return nil |
|
| 154 |
+} |
|
| 155 |
+ |
|
| 156 |
+func rootFSToAPIType(rootfs *image.RootFS) types.RootFS {
|
|
| 157 |
+ return types.RootFS{}
|
|
| 158 |
+} |
| 5 | 5 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,11 @@ |
| 0 |
+package daemon |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "github.com/docker/docker/container" |
|
| 4 |
+ "github.com/docker/docker/daemon/exec" |
|
| 5 |
+ "github.com/docker/docker/libcontainerd" |
|
| 6 |
+) |
|
| 7 |
+ |
|
| 8 |
+func execSetPlatformOpt(c *container.Container, ec *exec.Config, p *libcontainerd.Process) error {
|
|
| 9 |
+ return nil |
|
| 10 |
+} |
| 0 | 11 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,65 @@ |
| 0 |
+// +build solaris,cgo |
|
| 1 |
+ |
|
| 2 |
+package graphdriver |
|
| 3 |
+ |
|
| 4 |
+/* |
|
| 5 |
+#include <sys/statvfs.h> |
|
| 6 |
+#include <stdlib.h> |
|
| 7 |
+ |
|
| 8 |
+static inline struct statvfs *getstatfs(char *s) {
|
|
| 9 |
+ struct statvfs *buf; |
|
| 10 |
+ int err; |
|
| 11 |
+ buf = (struct statvfs *)malloc(sizeof(struct statvfs)); |
|
| 12 |
+ err = statvfs(s, buf); |
|
| 13 |
+ return buf; |
|
| 14 |
+} |
|
| 15 |
+*/ |
|
| 16 |
+import "C" |
|
| 17 |
+import ( |
|
| 18 |
+ "path/filepath" |
|
| 19 |
+ "unsafe" |
|
| 20 |
+ |
|
| 21 |
+ log "github.com/Sirupsen/logrus" |
|
| 22 |
+) |
|
| 23 |
+ |
|
| 24 |
+const ( |
|
| 25 |
+ // FsMagicZfs filesystem id for Zfs |
|
| 26 |
+ FsMagicZfs = FsMagic(0x2fc12fc1) |
|
| 27 |
+) |
|
| 28 |
+ |
|
| 29 |
+var ( |
|
| 30 |
+ // Slice of drivers that should be used in an order |
|
| 31 |
+ priority = []string{
|
|
| 32 |
+ "zfs", |
|
| 33 |
+ } |
|
| 34 |
+ |
|
| 35 |
+ // FsNames maps filesystem id to name of the filesystem. |
|
| 36 |
+ FsNames = map[FsMagic]string{
|
|
| 37 |
+ FsMagicZfs: "zfs", |
|
| 38 |
+ } |
|
| 39 |
+) |
|
| 40 |
+ |
|
| 41 |
+// GetFSMagic returns the filesystem id given the path. |
|
| 42 |
+func GetFSMagic(rootpath string) (FsMagic, error) {
|
|
| 43 |
+ return 0, nil |
|
| 44 |
+} |
|
| 45 |
+ |
|
| 46 |
+// Mounted checks if the given path is mounted as the fs type |
|
| 47 |
+//Solaris supports only ZFS for now |
|
| 48 |
+func Mounted(fsType FsMagic, mountPath string) (bool, error) {
|
|
| 49 |
+ |
|
| 50 |
+ cs := C.CString(filepath.Dir(mountPath)) |
|
| 51 |
+ buf := C.getstatfs(cs) |
|
| 52 |
+ |
|
| 53 |
+ // on Solaris buf.f_basetype contains ['z', 'f', 's', 0 ... ] |
|
| 54 |
+ if (buf.f_basetype[0] != 122) || (buf.f_basetype[1] != 102) || (buf.f_basetype[2] != 115) || |
|
| 55 |
+ (buf.f_basetype[3] != 0) {
|
|
| 56 |
+ log.Debugf("[zfs] no zfs dataset found for rootdir '%s'", mountPath)
|
|
| 57 |
+ C.free(unsafe.Pointer(buf)) |
|
| 58 |
+ return false, ErrPrerequisites |
|
| 59 |
+ } |
|
| 60 |
+ |
|
| 61 |
+ C.free(unsafe.Pointer(buf)) |
|
| 62 |
+ C.free(unsafe.Pointer(cs)) |
|
| 63 |
+ return true, nil |
|
| 64 |
+} |
| 5 | 5 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,59 @@ |
| 0 |
+// +build solaris,cgo |
|
| 1 |
+ |
|
| 2 |
+package zfs |
|
| 3 |
+ |
|
| 4 |
+/* |
|
| 5 |
+#include <sys/statvfs.h> |
|
| 6 |
+#include <stdlib.h> |
|
| 7 |
+ |
|
| 8 |
+static inline struct statvfs *getstatfs(char *s) {
|
|
| 9 |
+ struct statvfs *buf; |
|
| 10 |
+ int err; |
|
| 11 |
+ buf = (struct statvfs *)malloc(sizeof(struct statvfs)); |
|
| 12 |
+ err = statvfs(s, buf); |
|
| 13 |
+ return buf; |
|
| 14 |
+} |
|
| 15 |
+*/ |
|
| 16 |
+import "C" |
|
| 17 |
+import ( |
|
| 18 |
+ "path/filepath" |
|
| 19 |
+ "strings" |
|
| 20 |
+ "unsafe" |
|
| 21 |
+ |
|
| 22 |
+ log "github.com/Sirupsen/logrus" |
|
| 23 |
+ "github.com/docker/docker/daemon/graphdriver" |
|
| 24 |
+) |
|
| 25 |
+ |
|
| 26 |
+func checkRootdirFs(rootdir string) error {
|
|
| 27 |
+ |
|
| 28 |
+ cs := C.CString(filepath.Dir(rootdir)) |
|
| 29 |
+ buf := C.getstatfs(cs) |
|
| 30 |
+ |
|
| 31 |
+ // on Solaris buf.f_basetype contains ['z', 'f', 's', 0 ... ] |
|
| 32 |
+ if (buf.f_basetype[0] != 122) || (buf.f_basetype[1] != 102) || (buf.f_basetype[2] != 115) || |
|
| 33 |
+ (buf.f_basetype[3] != 0) {
|
|
| 34 |
+ log.Debugf("[zfs] no zfs dataset found for rootdir '%s'", rootdir)
|
|
| 35 |
+ C.free(unsafe.Pointer(buf)) |
|
| 36 |
+ return graphdriver.ErrPrerequisites |
|
| 37 |
+ } |
|
| 38 |
+ |
|
| 39 |
+ C.free(unsafe.Pointer(buf)) |
|
| 40 |
+ C.free(unsafe.Pointer(cs)) |
|
| 41 |
+ return nil |
|
| 42 |
+} |
|
| 43 |
+ |
|
| 44 |
+/* rootfs is introduced to comply with the OCI spec |
|
| 45 |
+which states that root filesystem must be mounted at <CID>/rootfs/ instead of <CID>/ |
|
| 46 |
+*/ |
|
| 47 |
+func getMountpoint(id string) string {
|
|
| 48 |
+ maxlen := 12 |
|
| 49 |
+ |
|
| 50 |
+ // we need to preserve filesystem suffix |
|
| 51 |
+ suffix := strings.SplitN(id, "-", 2) |
|
| 52 |
+ |
|
| 53 |
+ if len(suffix) > 1 {
|
|
| 54 |
+ return filepath.Join(id[:maxlen]+"-"+suffix[1], "rootfs", "root") |
|
| 55 |
+ } |
|
| 56 |
+ |
|
| 57 |
+ return filepath.Join(id[:maxlen], "rootfs", "root") |
|
| 58 |
+} |
| 5 | 5 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,40 @@ |
| 0 |
+package daemon |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "github.com/docker/docker/api/types/backend" |
|
| 4 |
+ "github.com/docker/docker/container" |
|
| 5 |
+ "github.com/docker/docker/daemon/exec" |
|
| 6 |
+ "github.com/docker/engine-api/types" |
|
| 7 |
+) |
|
| 8 |
+ |
|
| 9 |
+// This sets platform-specific fields |
|
| 10 |
+func setPlatformSpecificContainerFields(container *container.Container, contJSONBase *types.ContainerJSONBase) *types.ContainerJSONBase {
|
|
| 11 |
+ return contJSONBase |
|
| 12 |
+} |
|
| 13 |
+ |
|
| 14 |
+// containerInspectPre120 get containers for pre 1.20 APIs. |
|
| 15 |
+func (daemon *Daemon) containerInspectPre120(name string) (*types.ContainerJSON, error) {
|
|
| 16 |
+ return daemon.containerInspectCurrent(name, false) |
|
| 17 |
+} |
|
| 18 |
+ |
|
| 19 |
+func addMountPoints(container *container.Container) []types.MountPoint {
|
|
| 20 |
+ mountPoints := make([]types.MountPoint, 0, len(container.MountPoints)) |
|
| 21 |
+ for _, m := range container.MountPoints {
|
|
| 22 |
+ mountPoints = append(mountPoints, types.MountPoint{
|
|
| 23 |
+ Name: m.Name, |
|
| 24 |
+ Source: m.Path(), |
|
| 25 |
+ Destination: m.Destination, |
|
| 26 |
+ Driver: m.Driver, |
|
| 27 |
+ RW: m.RW, |
|
| 28 |
+ }) |
|
| 29 |
+ } |
|
| 30 |
+ return mountPoints |
|
| 31 |
+} |
|
| 32 |
+ |
|
| 33 |
+func inspectExecProcessConfig(e *exec.Config) *backend.ExecProcessConfig {
|
|
| 34 |
+ return &backend.ExecProcessConfig{
|
|
| 35 |
+ Tty: e.Tty, |
|
| 36 |
+ Entrypoint: e.Entrypoint, |
|
| 37 |
+ Arguments: e.Args, |
|
| 38 |
+ } |
|
| 39 |
+} |
| 5 | 5 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,18 @@ |
| 0 |
+package daemon |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "github.com/docker/docker/container" |
|
| 4 |
+ "github.com/docker/docker/libcontainerd" |
|
| 5 |
+) |
|
| 6 |
+ |
|
| 7 |
+// platformConstructExitStatus returns a platform specific exit status structure |
|
| 8 |
+func platformConstructExitStatus(e libcontainerd.StateInfo) *container.ExitStatus {
|
|
| 9 |
+ return &container.ExitStatus{
|
|
| 10 |
+ ExitCode: int(e.ExitCode), |
|
| 11 |
+ } |
|
| 12 |
+} |
|
| 13 |
+ |
|
| 14 |
+// postRunProcessing perfoms any processing needed on the container after it has stopped. |
|
| 15 |
+func (daemon *Daemon) postRunProcessing(container *container.Container, e libcontainerd.StateInfo) error {
|
|
| 16 |
+ return nil |
|
| 17 |
+} |
| 0 | 18 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,12 @@ |
| 0 |
+package daemon |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "github.com/docker/docker/container" |
|
| 4 |
+ "github.com/docker/docker/libcontainerd" |
|
| 5 |
+ "github.com/docker/docker/oci" |
|
| 6 |
+) |
|
| 7 |
+ |
|
| 8 |
+func (daemon *Daemon) createSpec(c *container.Container) (*libcontainerd.Spec, error) {
|
|
| 9 |
+ s := oci.DefaultSpec() |
|
| 10 |
+ return (*libcontainerd.Spec)(&s), nil |
|
| 11 |
+} |
| 0 | 12 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,34 @@ |
| 0 |
+package daemon |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "github.com/docker/docker/container" |
|
| 4 |
+ "time" |
|
| 5 |
+) |
|
| 6 |
+ |
|
| 7 |
+// newStatsCollector returns a new statsCollector for collection stats |
|
| 8 |
+// for a registered container at the specified interval. The collector allows |
|
| 9 |
+// non-running containers to be added and will start processing stats when |
|
| 10 |
+// they are started. |
|
| 11 |
+func (daemon *Daemon) newStatsCollector(interval time.Duration) *statsCollector {
|
|
| 12 |
+ return &statsCollector{}
|
|
| 13 |
+} |
|
| 14 |
+ |
|
| 15 |
+// statsCollector manages and provides container resource stats |
|
| 16 |
+type statsCollector struct {
|
|
| 17 |
+} |
|
| 18 |
+ |
|
| 19 |
+// collect registers the container with the collector and adds it to |
|
| 20 |
+// the event loop for collection on the specified interval returning |
|
| 21 |
+// a channel for the subscriber to receive on. |
|
| 22 |
+func (s *statsCollector) collect(c *container.Container) chan interface{} {
|
|
| 23 |
+ return nil |
|
| 24 |
+} |
|
| 25 |
+ |
|
| 26 |
+// stopCollection closes the channels for all subscribers and removes |
|
| 27 |
+// the container from metrics collection. |
|
| 28 |
+func (s *statsCollector) stopCollection(c *container.Container) {
|
|
| 29 |
+} |
|
| 30 |
+ |
|
| 31 |
+// unsubscribe removes a specific subscriber from receiving updates for a container's stats. |
|
| 32 |
+func (s *statsCollector) unsubscribe(c *container.Container, ch chan interface{}) {
|
|
| 33 |
+} |
| 5 | 5 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,11 @@ |
| 0 |
+package daemon |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "github.com/docker/docker/libcontainerd" |
|
| 4 |
+ "github.com/docker/engine-api/types/container" |
|
| 5 |
+) |
|
| 6 |
+ |
|
| 7 |
+func toContainerdResources(resources container.Resources) libcontainerd.Resources {
|
|
| 8 |
+ var r libcontainerd.Resources |
|
| 9 |
+ return r |
|
| 10 |
+} |
| ... | ... |
@@ -93,7 +93,7 @@ if command -v git &> /dev/null && [ -d .git ] && git rev-parse &> /dev/null; the |
| 93 | 93 |
git status --porcelain --untracked-files=no |
| 94 | 94 |
echo "#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" |
| 95 | 95 |
fi |
| 96 |
- ! BUILDTIME=$(date --rfc-3339 ns | sed -e 's/ /T/') &> /dev/null |
|
| 96 |
+ ! BUILDTIME=$(date --rfc-3339 ns 2> /dev/null | sed -e 's/ /T/') &> /dev/null |
|
| 97 | 97 |
if [ -z $BUILDTIME ]; then |
| 98 | 98 |
# If using bash 3.1 which doesn't support --rfc-3389, eg Windows CI |
| 99 | 99 |
BUILDTIME=$(date -u) |
| ... | ... |
@@ -113,6 +113,12 @@ if [ "$AUTO_GOPATH" ]; then |
| 113 | 113 |
mkdir -p .gopath/src/"$(dirname "${DOCKER_PKG}")"
|
| 114 | 114 |
ln -sf ../../../.. .gopath/src/"${DOCKER_PKG}"
|
| 115 | 115 |
export GOPATH="${PWD}/.gopath:${PWD}/vendor"
|
| 116 |
+ |
|
| 117 |
+ if [ "$(go env GOOS)" = 'solaris' ]; then |
|
| 118 |
+ # sys/unix is installed outside the standard library on solaris |
|
| 119 |
+ # TODO need to allow for version change, need to get version from go |
|
| 120 |
+ export GOPATH="${GOPATH}:/usr/lib/gocode/1.5"
|
|
| 121 |
+ fi |
|
| 116 | 122 |
fi |
| 117 | 123 |
|
| 118 | 124 |
if [ ! "$GOPATH" ]; then |
| 5 | 5 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,56 @@ |
| 0 |
+package libcontainerd |
|
| 1 |
+ |
|
| 2 |
+type client struct {
|
|
| 3 |
+ clientCommon |
|
| 4 |
+ |
|
| 5 |
+ // Platform specific properties below here. |
|
| 6 |
+} |
|
| 7 |
+ |
|
| 8 |
+func (clnt *client) AddProcess(containerID, processFriendlyName string, specp Process) error {
|
|
| 9 |
+ return nil |
|
| 10 |
+} |
|
| 11 |
+ |
|
| 12 |
+func (clnt *client) Create(containerID string, spec Spec, options ...CreateOption) (err error) {
|
|
| 13 |
+ return nil |
|
| 14 |
+} |
|
| 15 |
+ |
|
| 16 |
+func (clnt *client) Signal(containerID string, sig int) error {
|
|
| 17 |
+ return nil |
|
| 18 |
+} |
|
| 19 |
+ |
|
| 20 |
+func (clnt *client) Resize(containerID, processFriendlyName string, width, height int) error {
|
|
| 21 |
+ return nil |
|
| 22 |
+} |
|
| 23 |
+ |
|
| 24 |
+func (clnt *client) Pause(containerID string) error {
|
|
| 25 |
+ return nil |
|
| 26 |
+} |
|
| 27 |
+ |
|
| 28 |
+func (clnt *client) Resume(containerID string) error {
|
|
| 29 |
+ return nil |
|
| 30 |
+} |
|
| 31 |
+ |
|
| 32 |
+func (clnt *client) Stats(containerID string) (*Stats, error) {
|
|
| 33 |
+ return nil, nil |
|
| 34 |
+} |
|
| 35 |
+ |
|
| 36 |
+// Restore is the handler for restoring a container |
|
| 37 |
+func (clnt *client) Restore(containerID string, unusedOnWindows ...CreateOption) error {
|
|
| 38 |
+ return nil |
|
| 39 |
+} |
|
| 40 |
+ |
|
| 41 |
+func (clnt *client) GetPidsForContainer(containerID string) ([]int, error) {
|
|
| 42 |
+ return nil, nil |
|
| 43 |
+} |
|
| 44 |
+ |
|
| 45 |
+// Summary returns a summary of the processes running in a container. |
|
| 46 |
+func (clnt *client) Summary(containerID string) ([]Summary, error) {
|
|
| 47 |
+ return nil, nil |
|
| 48 |
+} |
|
| 49 |
+ |
|
| 50 |
+// UpdateResources updates resources for a running container. |
|
| 51 |
+func (clnt *client) UpdateResources(containerID string, resources Resources) error {
|
|
| 52 |
+ // Updating resource isn't supported on Solaris |
|
| 53 |
+ // but we should return nil for enabling updating container |
|
| 54 |
+ return nil |
|
| 55 |
+} |
| 0 | 6 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,25 @@ |
| 0 |
+package libcontainerd |
|
| 1 |
+ |
|
| 2 |
+import "github.com/docker/docker/pkg/locker" |
|
| 3 |
+ |
|
| 4 |
+type remote struct {
|
|
| 5 |
+} |
|
| 6 |
+ |
|
| 7 |
+func (r *remote) Client(b Backend) (Client, error) {
|
|
| 8 |
+ c := &client{
|
|
| 9 |
+ clientCommon: clientCommon{
|
|
| 10 |
+ backend: b, |
|
| 11 |
+ containers: make(map[string]*container), |
|
| 12 |
+ locker: locker.New(), |
|
| 13 |
+ }, |
|
| 14 |
+ } |
|
| 15 |
+ return c, nil |
|
| 16 |
+} |
|
| 17 |
+ |
|
| 18 |
+func (r *remote) Cleanup() {
|
|
| 19 |
+} |
|
| 20 |
+ |
|
| 21 |
+// New creates a fresh instance of libcontainerd remote. |
|
| 22 |
+func New(_ string, _ ...RemoteOption) (Remote, error) {
|
|
| 23 |
+ return &remote{}, nil
|
|
| 24 |
+} |
| 0 | 25 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,38 @@ |
| 0 |
+package libcontainerd |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "github.com/opencontainers/specs/specs-go" |
|
| 4 |
+) |
|
| 5 |
+ |
|
| 6 |
+// Spec is the base configuration for the container. It specifies platform |
|
| 7 |
+// independent configuration. This information must be included when the |
|
| 8 |
+// bundle is packaged for distribution. |
|
| 9 |
+type Spec specs.Spec |
|
| 10 |
+ |
|
| 11 |
+// Process contains information to start a specific application inside the container. |
|
| 12 |
+type Process struct {
|
|
| 13 |
+ // Terminal creates an interactive terminal for the container. |
|
| 14 |
+ Terminal bool `json:"terminal"` |
|
| 15 |
+ // Args specifies the binary and arguments for the application to execute. |
|
| 16 |
+ Args []string `json:"args"` |
|
| 17 |
+} |
|
| 18 |
+ |
|
| 19 |
+// Stats contains a stats properties from containerd. |
|
| 20 |
+type Stats struct{}
|
|
| 21 |
+ |
|
| 22 |
+// Summary container a container summary from containerd |
|
| 23 |
+type Summary struct{}
|
|
| 24 |
+ |
|
| 25 |
+// StateInfo contains description about the new state container has entered. |
|
| 26 |
+type StateInfo struct {
|
|
| 27 |
+ CommonStateInfo |
|
| 28 |
+ |
|
| 29 |
+ // Platform specific StateInfo |
|
| 30 |
+} |
|
| 31 |
+ |
|
| 32 |
+// User specifies Solaris specific user and group information for the container's |
|
| 33 |
+// main process. |
|
| 34 |
+type User specs.User |
|
| 35 |
+ |
|
| 36 |
+// Resources defines updatable container resource values. |
|
| 37 |
+type Resources struct{}
|
| 0 | 7 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,31 @@ |
| 0 |
+package listeners |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "crypto/tls" |
|
| 4 |
+ "fmt" |
|
| 5 |
+ "net" |
|
| 6 |
+ |
|
| 7 |
+ "github.com/docker/go-connections/sockets" |
|
| 8 |
+) |
|
| 9 |
+ |
|
| 10 |
+// Init creates new listeners for the server. |
|
| 11 |
+func Init(proto, addr, socketGroup string, tlsConfig *tls.Config) (ls []net.Listener, err error) {
|
|
| 12 |
+ switch proto {
|
|
| 13 |
+ case "tcp": |
|
| 14 |
+ l, err := sockets.NewTCPSocket(addr, tlsConfig) |
|
| 15 |
+ if err != nil {
|
|
| 16 |
+ return nil, err |
|
| 17 |
+ } |
|
| 18 |
+ ls = append(ls, l) |
|
| 19 |
+ case "unix": |
|
| 20 |
+ l, err := sockets.NewUnixSocket(addr, socketGroup) |
|
| 21 |
+ if err != nil {
|
|
| 22 |
+ return nil, fmt.Errorf("can't create unix socket %s: %v", addr, err)
|
|
| 23 |
+ } |
|
| 24 |
+ ls = append(ls, l) |
|
| 25 |
+ default: |
|
| 26 |
+ return nil, fmt.Errorf("Invalid protocol format: %q", proto)
|
|
| 27 |
+ } |
|
| 28 |
+ |
|
| 29 |
+ return |
|
| 30 |
+} |
| ... | ... |
@@ -9,8 +9,8 @@ func GetMounts() ([]*Info, error) {
|
| 9 | 9 |
return parseMountTable() |
| 10 | 10 |
} |
| 11 | 11 |
|
| 12 |
-// Mounted looks at /proc/self/mountinfo to determine of the specified |
|
| 13 |
-// mountpoint has been mounted |
|
| 12 |
+// Mounted determines if a specified mountpoint has been mounted. |
|
| 13 |
+// On Linux it looks at /proc/self/mountinfo and on Solaris at mnttab. |
|
| 14 | 14 |
func Mounted(mountpoint string) (bool, error) {
|
| 15 | 15 |
entries, err := parseMountTable() |
| 16 | 16 |
if err != nil {
|
| 17 | 17 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,33 @@ |
| 0 |
+// +build solaris,cgo |
|
| 1 |
+ |
|
| 2 |
+package mount |
|
| 3 |
+ |
|
| 4 |
+import ( |
|
| 5 |
+ "golang.org/x/sys/unix" |
|
| 6 |
+ "unsafe" |
|
| 7 |
+) |
|
| 8 |
+ |
|
| 9 |
+// #include <stdlib.h> |
|
| 10 |
+// #include <stdio.h> |
|
| 11 |
+// #include <sys/mount.h> |
|
| 12 |
+// int Mount(const char *spec, const char *dir, int mflag, |
|
| 13 |
+// char *fstype, char *dataptr, int datalen, char *optptr, int optlen) {
|
|
| 14 |
+// return mount(spec, dir, mflag, fstype, dataptr, datalen, optptr, optlen); |
|
| 15 |
+// } |
|
| 16 |
+import "C" |
|
| 17 |
+ |
|
| 18 |
+func mount(device, target, mType string, flag uintptr, data string) error {
|
|
| 19 |
+ spec := C.CString(device) |
|
| 20 |
+ dir := C.CString(target) |
|
| 21 |
+ fstype := C.CString(mType) |
|
| 22 |
+ _, err := C.Mount(spec, dir, C.int(flag), fstype, nil, 0, nil, 0) |
|
| 23 |
+ C.free(unsafe.Pointer(spec)) |
|
| 24 |
+ C.free(unsafe.Pointer(dir)) |
|
| 25 |
+ C.free(unsafe.Pointer(fstype)) |
|
| 26 |
+ return err |
|
| 27 |
+} |
|
| 28 |
+ |
|
| 29 |
+func unmount(target string, flag int) error {
|
|
| 30 |
+ err := unix.Unmount(target, flag) |
|
| 31 |
+ return err |
|
| 32 |
+} |
| 5 | 5 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,37 @@ |
| 0 |
+// +build solaris,cgo |
|
| 1 |
+ |
|
| 2 |
+package mount |
|
| 3 |
+ |
|
| 4 |
+/* |
|
| 5 |
+#include <stdio.h> |
|
| 6 |
+#include <sys/mnttab.h> |
|
| 7 |
+*/ |
|
| 8 |
+import "C" |
|
| 9 |
+ |
|
| 10 |
+import ( |
|
| 11 |
+ "fmt" |
|
| 12 |
+) |
|
| 13 |
+ |
|
| 14 |
+func parseMountTable() ([]*Info, error) {
|
|
| 15 |
+ mnttab := C.fopen(C.CString(C.MNTTAB), C.CString("r"))
|
|
| 16 |
+ if mnttab == nil {
|
|
| 17 |
+ return nil, fmt.Errorf("Failed to open %s", C.MNTTAB)
|
|
| 18 |
+ } |
|
| 19 |
+ |
|
| 20 |
+ var out []*Info |
|
| 21 |
+ var mp C.struct_mnttab |
|
| 22 |
+ |
|
| 23 |
+ ret := C.getmntent(mnttab, &mp) |
|
| 24 |
+ for ret == 0 {
|
|
| 25 |
+ var mountinfo Info |
|
| 26 |
+ mountinfo.Mountpoint = C.GoString(mp.mnt_mountp) |
|
| 27 |
+ mountinfo.Source = C.GoString(mp.mnt_special) |
|
| 28 |
+ mountinfo.Fstype = C.GoString(mp.mnt_fstype) |
|
| 29 |
+ mountinfo.Opts = C.GoString(mp.mnt_mntopts) |
|
| 30 |
+ out = append(out, &mountinfo) |
|
| 31 |
+ ret = C.getmntent(mnttab, &mp) |
|
| 32 |
+ } |
|
| 33 |
+ |
|
| 34 |
+ C.fclose(mnttab) |
|
| 35 |
+ return out, nil |
|
| 36 |
+} |
| 5 | 5 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,37 @@ |
| 0 |
+// +build solaris,cgo |
|
| 1 |
+ |
|
| 2 |
+package operatingsystem |
|
| 3 |
+ |
|
| 4 |
+/* |
|
| 5 |
+#include <zone.h> |
|
| 6 |
+*/ |
|
| 7 |
+import "C" |
|
| 8 |
+ |
|
| 9 |
+import ( |
|
| 10 |
+ "bytes" |
|
| 11 |
+ "errors" |
|
| 12 |
+ "io/ioutil" |
|
| 13 |
+) |
|
| 14 |
+ |
|
| 15 |
+var etcOsRelease = "/etc/release" |
|
| 16 |
+ |
|
| 17 |
+// GetOperatingSystem gets the name of the current operating system. |
|
| 18 |
+func GetOperatingSystem() (string, error) {
|
|
| 19 |
+ b, err := ioutil.ReadFile(etcOsRelease) |
|
| 20 |
+ if err != nil {
|
|
| 21 |
+ return "", err |
|
| 22 |
+ } |
|
| 23 |
+ if i := bytes.Index(b, []byte("\n")); i >= 0 {
|
|
| 24 |
+ b = bytes.Trim(b[:i], " ") |
|
| 25 |
+ return string(b), nil |
|
| 26 |
+ } |
|
| 27 |
+ return "", errors.New("release not found")
|
|
| 28 |
+} |
|
| 29 |
+ |
|
| 30 |
+// IsContainerized returns true if we are running inside a container. |
|
| 31 |
+func IsContainerized() (bool, error) {
|
|
| 32 |
+ if C.getzoneid() != 0 {
|
|
| 33 |
+ return true, nil |
|
| 34 |
+ } |
|
| 35 |
+ return false, nil |
|
| 36 |
+} |
| 0 | 37 |
deleted file mode 100644 |
| ... | ... |
@@ -1,15 +0,0 @@ |
| 1 |
-package platform |
|
| 2 |
- |
|
| 3 |
-import ( |
|
| 4 |
- "os/exec" |
|
| 5 |
-) |
|
| 6 |
- |
|
| 7 |
-// runtimeArchitecture gets the name of the current architecture (x86, x86_64, …) |
|
| 8 |
-func runtimeArchitecture() (string, error) {
|
|
| 9 |
- cmd := exec.Command("uname", "-m")
|
|
| 10 |
- machine, err := cmd.Output() |
|
| 11 |
- if err != nil {
|
|
| 12 |
- return "", err |
|
| 13 |
- } |
|
| 14 |
- return string(machine), nil |
|
| 15 |
-} |
| 16 | 1 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,18 @@ |
| 0 |
+// +build freebsd solaris |
|
| 1 |
+ |
|
| 2 |
+package platform |
|
| 3 |
+ |
|
| 4 |
+import ( |
|
| 5 |
+ "os/exec" |
|
| 6 |
+ "strings" |
|
| 7 |
+) |
|
| 8 |
+ |
|
| 9 |
+// runtimeArchitecture get the name of the current architecture (i86pc, sun4v) |
|
| 10 |
+func runtimeArchitecture() (string, error) {
|
|
| 11 |
+ cmd := exec.Command("/usr/bin/uname", "-m")
|
|
| 12 |
+ machine, err := cmd.Output() |
|
| 13 |
+ if err != nil {
|
|
| 14 |
+ return "", err |
|
| 15 |
+ } |
|
| 16 |
+ return strings.TrimSpace(string(machine)), nil |
|
| 17 |
+} |
| 0 | 18 |
deleted file mode 100644 |
| ... | ... |
@@ -1,23 +0,0 @@ |
| 1 |
-// +build freebsd |
|
| 2 |
- |
|
| 3 |
-package reexec |
|
| 4 |
- |
|
| 5 |
-import ( |
|
| 6 |
- "os/exec" |
|
| 7 |
-) |
|
| 8 |
- |
|
| 9 |
-// Self returns the path to the current process's binary. |
|
| 10 |
-// Uses os.Args[0]. |
|
| 11 |
-func Self() string {
|
|
| 12 |
- return naiveSelf() |
|
| 13 |
-} |
|
| 14 |
- |
|
| 15 |
-// Command returns *exec.Cmd which have Path as current binary. |
|
| 16 |
-// For example if current binary is "docker" at "/usr/bin/", then cmd.Path will |
|
| 17 |
-// be set to "/usr/bin/docker". |
|
| 18 |
-func Command(args ...string) *exec.Cmd {
|
|
| 19 |
- return &exec.Cmd{
|
|
| 20 |
- Path: Self(), |
|
| 21 |
- Args: args, |
|
| 22 |
- } |
|
| 23 |
-} |
| 24 | 1 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,23 @@ |
| 0 |
+// +build freebsd solaris |
|
| 1 |
+ |
|
| 2 |
+package reexec |
|
| 3 |
+ |
|
| 4 |
+import ( |
|
| 5 |
+ "os/exec" |
|
| 6 |
+) |
|
| 7 |
+ |
|
| 8 |
+// Self returns the path to the current process's binary. |
|
| 9 |
+// Uses os.Args[0]. |
|
| 10 |
+func Self() string {
|
|
| 11 |
+ return naiveSelf() |
|
| 12 |
+} |
|
| 13 |
+ |
|
| 14 |
+// Command returns *exec.Cmd which have Path as current binary. |
|
| 15 |
+// For example if current binary is "docker" at "/usr/bin/", then cmd.Path will |
|
| 16 |
+// be set to "/usr/bin/docker". |
|
| 17 |
+func Command(args ...string) *exec.Cmd {
|
|
| 18 |
+ return &exec.Cmd{
|
|
| 19 |
+ Path: Self(), |
|
| 20 |
+ Args: args, |
|
| 21 |
+ } |
|
| 22 |
+} |
| 5 | 5 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,42 @@ |
| 0 |
+package signal |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "syscall" |
|
| 4 |
+) |
|
| 5 |
+ |
|
| 6 |
+// SignalMap is a map of Solaris signals. |
|
| 7 |
+// SIGINFO and SIGTHR not defined for Solaris |
|
| 8 |
+var SignalMap = map[string]syscall.Signal{
|
|
| 9 |
+ "ABRT": syscall.SIGABRT, |
|
| 10 |
+ "ALRM": syscall.SIGALRM, |
|
| 11 |
+ "BUF": syscall.SIGBUS, |
|
| 12 |
+ "CHLD": syscall.SIGCHLD, |
|
| 13 |
+ "CONT": syscall.SIGCONT, |
|
| 14 |
+ "EMT": syscall.SIGEMT, |
|
| 15 |
+ "FPE": syscall.SIGFPE, |
|
| 16 |
+ "HUP": syscall.SIGHUP, |
|
| 17 |
+ "ILL": syscall.SIGILL, |
|
| 18 |
+ "INT": syscall.SIGINT, |
|
| 19 |
+ "IO": syscall.SIGIO, |
|
| 20 |
+ "IOT": syscall.SIGIOT, |
|
| 21 |
+ "KILL": syscall.SIGKILL, |
|
| 22 |
+ "LWP": syscall.SIGLWP, |
|
| 23 |
+ "PIPE": syscall.SIGPIPE, |
|
| 24 |
+ "PROF": syscall.SIGPROF, |
|
| 25 |
+ "QUIT": syscall.SIGQUIT, |
|
| 26 |
+ "SEGV": syscall.SIGSEGV, |
|
| 27 |
+ "STOP": syscall.SIGSTOP, |
|
| 28 |
+ "SYS": syscall.SIGSYS, |
|
| 29 |
+ "TERM": syscall.SIGTERM, |
|
| 30 |
+ "TRAP": syscall.SIGTRAP, |
|
| 31 |
+ "TSTP": syscall.SIGTSTP, |
|
| 32 |
+ "TTIN": syscall.SIGTTIN, |
|
| 33 |
+ "TTOU": syscall.SIGTTOU, |
|
| 34 |
+ "URG": syscall.SIGURG, |
|
| 35 |
+ "USR1": syscall.SIGUSR1, |
|
| 36 |
+ "USR2": syscall.SIGUSR2, |
|
| 37 |
+ "VTALRM": syscall.SIGVTALRM, |
|
| 38 |
+ "WINCH": syscall.SIGWINCH, |
|
| 39 |
+ "XCPU": syscall.SIGXCPU, |
|
| 40 |
+ "XFSZ": syscall.SIGXFSZ, |
|
| 41 |
+} |
| 5 | 5 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,119 @@ |
| 0 |
+// +build solaris,cgo |
|
| 1 |
+ |
|
| 2 |
+package sysinfo |
|
| 3 |
+ |
|
| 4 |
+import ( |
|
| 5 |
+ "bytes" |
|
| 6 |
+ "os/exec" |
|
| 7 |
+ "strconv" |
|
| 8 |
+ "strings" |
|
| 9 |
+) |
|
| 10 |
+ |
|
| 11 |
+/* |
|
| 12 |
+#cgo LDFLAGS: -llgrp |
|
| 13 |
+#include <unistd.h> |
|
| 14 |
+#include <stdlib.h> |
|
| 15 |
+#include <sys/lgrp_user.h> |
|
| 16 |
+int getLgrpCount() {
|
|
| 17 |
+ lgrp_cookie_t lgrpcookie = LGRP_COOKIE_NONE; |
|
| 18 |
+ uint_t nlgrps; |
|
| 19 |
+ |
|
| 20 |
+ if ((lgrpcookie = lgrp_init(LGRP_VIEW_OS)) == LGRP_COOKIE_NONE) {
|
|
| 21 |
+ return -1; |
|
| 22 |
+ } |
|
| 23 |
+ nlgrps = lgrp_nlgrps(lgrpcookie); |
|
| 24 |
+ return nlgrps; |
|
| 25 |
+} |
|
| 26 |
+*/ |
|
| 27 |
+import "C" |
|
| 28 |
+ |
|
| 29 |
+// IsCPUSharesAvailable returns whether CPUShares setting is supported. |
|
| 30 |
+// We need FSS to be set as default scheduling class to support CPU Shares |
|
| 31 |
+func IsCPUSharesAvailable() bool {
|
|
| 32 |
+ cmd := exec.Command("/usr/sbin/dispadmin", "-d")
|
|
| 33 |
+ outBuf := new(bytes.Buffer) |
|
| 34 |
+ errBuf := new(bytes.Buffer) |
|
| 35 |
+ cmd.Stderr = errBuf |
|
| 36 |
+ cmd.Stdout = outBuf |
|
| 37 |
+ |
|
| 38 |
+ if err := cmd.Run(); err != nil {
|
|
| 39 |
+ return false |
|
| 40 |
+ } |
|
| 41 |
+ return (strings.Contains(outBuf.String(), "FSS")) |
|
| 42 |
+} |
|
| 43 |
+ |
|
| 44 |
+// New returns a new SysInfo, using the filesystem to detect which features |
|
| 45 |
+// the kernel supports. |
|
| 46 |
+//NOTE Solaris: If we change the below capabilities be sure |
|
| 47 |
+// to update verifyPlatformContainerSettings() in daemon_solaris.go |
|
| 48 |
+func New(quiet bool) *SysInfo {
|
|
| 49 |
+ sysInfo := &SysInfo{}
|
|
| 50 |
+ sysInfo.cgroupMemInfo = setCgroupMem(quiet) |
|
| 51 |
+ sysInfo.cgroupCPUInfo = setCgroupCPU(quiet) |
|
| 52 |
+ sysInfo.cgroupBlkioInfo = setCgroupBlkioInfo(quiet) |
|
| 53 |
+ sysInfo.cgroupCpusetInfo = setCgroupCPUsetInfo(quiet) |
|
| 54 |
+ |
|
| 55 |
+ sysInfo.IPv4ForwardingDisabled = false |
|
| 56 |
+ |
|
| 57 |
+ sysInfo.AppArmor = false |
|
| 58 |
+ |
|
| 59 |
+ return sysInfo |
|
| 60 |
+} |
|
| 61 |
+ |
|
| 62 |
+// setCgroupMem reads the memory information for Solaris. |
|
| 63 |
+func setCgroupMem(quiet bool) cgroupMemInfo {
|
|
| 64 |
+ |
|
| 65 |
+ return cgroupMemInfo{
|
|
| 66 |
+ MemoryLimit: true, |
|
| 67 |
+ SwapLimit: true, |
|
| 68 |
+ MemoryReservation: false, |
|
| 69 |
+ OomKillDisable: false, |
|
| 70 |
+ MemorySwappiness: false, |
|
| 71 |
+ KernelMemory: false, |
|
| 72 |
+ } |
|
| 73 |
+} |
|
| 74 |
+ |
|
| 75 |
+// setCgroupCPU reads the cpu information for Solaris. |
|
| 76 |
+func setCgroupCPU(quiet bool) cgroupCPUInfo {
|
|
| 77 |
+ |
|
| 78 |
+ return cgroupCPUInfo{
|
|
| 79 |
+ CPUShares: true, |
|
| 80 |
+ CPUCfsPeriod: false, |
|
| 81 |
+ CPUCfsQuota: true, |
|
| 82 |
+ } |
|
| 83 |
+} |
|
| 84 |
+ |
|
| 85 |
+// blkio switches are not supported in Solaris. |
|
| 86 |
+func setCgroupBlkioInfo(quiet bool) cgroupBlkioInfo {
|
|
| 87 |
+ |
|
| 88 |
+ return cgroupBlkioInfo{
|
|
| 89 |
+ BlkioWeight: false, |
|
| 90 |
+ BlkioWeightDevice: false, |
|
| 91 |
+ } |
|
| 92 |
+} |
|
| 93 |
+ |
|
| 94 |
+// setCgroupCPUsetInfo reads the cpuset information for Solaris. |
|
| 95 |
+func setCgroupCPUsetInfo(quiet bool) cgroupCpusetInfo {
|
|
| 96 |
+ |
|
| 97 |
+ return cgroupCpusetInfo{
|
|
| 98 |
+ Cpuset: true, |
|
| 99 |
+ Cpus: getCPUCount(), |
|
| 100 |
+ Mems: getLgrpCount(), |
|
| 101 |
+ } |
|
| 102 |
+} |
|
| 103 |
+ |
|
| 104 |
+func getCPUCount() string {
|
|
| 105 |
+ ncpus := C.sysconf(C._SC_NPROCESSORS_ONLN) |
|
| 106 |
+ if ncpus <= 0 {
|
|
| 107 |
+ return "" |
|
| 108 |
+ } |
|
| 109 |
+ return strconv.FormatInt(int64(ncpus), 16) |
|
| 110 |
+} |
|
| 111 |
+ |
|
| 112 |
+func getLgrpCount() string {
|
|
| 113 |
+ nlgrps := C.getLgrpCount() |
|
| 114 |
+ if nlgrps <= 0 {
|
|
| 115 |
+ return "" |
|
| 116 |
+ } |
|
| 117 |
+ return strconv.FormatInt(int64(nlgrps), 16) |
|
| 118 |
+} |
| 0 | 119 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,128 @@ |
| 0 |
+// +build solaris,cgo |
|
| 1 |
+ |
|
| 2 |
+package system |
|
| 3 |
+ |
|
| 4 |
+import ( |
|
| 5 |
+ "fmt" |
|
| 6 |
+ "unsafe" |
|
| 7 |
+) |
|
| 8 |
+ |
|
| 9 |
+// #cgo LDFLAGS: -lkstat |
|
| 10 |
+// #include <unistd.h> |
|
| 11 |
+// #include <stdlib.h> |
|
| 12 |
+// #include <stdio.h> |
|
| 13 |
+// #include <kstat.h> |
|
| 14 |
+// #include <sys/swap.h> |
|
| 15 |
+// #include <sys/param.h> |
|
| 16 |
+// struct swaptable *allocSwaptable(int num) {
|
|
| 17 |
+// struct swaptable *st; |
|
| 18 |
+// struct swapent *swapent; |
|
| 19 |
+// st = (struct swaptable *)malloc(num * sizeof(swapent_t) + sizeof (int)); |
|
| 20 |
+// swapent = st->swt_ent; |
|
| 21 |
+// for (int i = 0; i < num; i++,swapent++) {
|
|
| 22 |
+// swapent->ste_path = (char *)malloc(MAXPATHLEN * sizeof (char)); |
|
| 23 |
+// } |
|
| 24 |
+// st->swt_n = num; |
|
| 25 |
+// return st; |
|
| 26 |
+//} |
|
| 27 |
+// void freeSwaptable (struct swaptable *st) {
|
|
| 28 |
+// struct swapent *swapent = st->swt_ent; |
|
| 29 |
+// for (int i = 0; i < st->swt_n; i++,swapent++) {
|
|
| 30 |
+// free(swapent->ste_path); |
|
| 31 |
+// } |
|
| 32 |
+// free(st); |
|
| 33 |
+// } |
|
| 34 |
+// swapent_t getSwapEnt(swapent_t *ent, int i) {
|
|
| 35 |
+// return ent[i]; |
|
| 36 |
+// } |
|
| 37 |
+// int64_t getPpKernel() {
|
|
| 38 |
+// int64_t pp_kernel = 0; |
|
| 39 |
+// kstat_ctl_t *ksc; |
|
| 40 |
+// kstat_t *ks; |
|
| 41 |
+// kstat_named_t *knp; |
|
| 42 |
+// kid_t kid; |
|
| 43 |
+// |
|
| 44 |
+// if ((ksc = kstat_open()) == NULL) {
|
|
| 45 |
+// return -1; |
|
| 46 |
+// } |
|
| 47 |
+// if ((ks = kstat_lookup(ksc, "unix", 0, "system_pages")) == NULL) {
|
|
| 48 |
+// return -1; |
|
| 49 |
+// } |
|
| 50 |
+// if (((kid = kstat_read(ksc, ks, NULL)) == -1) || |
|
| 51 |
+// ((knp = kstat_data_lookup(ks, "pp_kernel")) == NULL)) {
|
|
| 52 |
+// return -1; |
|
| 53 |
+// } |
|
| 54 |
+// switch (knp->data_type) {
|
|
| 55 |
+// case KSTAT_DATA_UINT64: |
|
| 56 |
+// pp_kernel = knp->value.ui64; |
|
| 57 |
+// break; |
|
| 58 |
+// case KSTAT_DATA_UINT32: |
|
| 59 |
+// pp_kernel = knp->value.ui32; |
|
| 60 |
+// break; |
|
| 61 |
+// } |
|
| 62 |
+// pp_kernel *= sysconf(_SC_PAGESIZE); |
|
| 63 |
+// return (pp_kernel > 0 ? pp_kernel : -1); |
|
| 64 |
+// } |
|
| 65 |
+import "C" |
|
| 66 |
+ |
|
| 67 |
+// Get the system memory info using sysconf same as prtconf |
|
| 68 |
+func getTotalMem() int64 {
|
|
| 69 |
+ pagesize := C.sysconf(C._SC_PAGESIZE) |
|
| 70 |
+ npages := C.sysconf(C._SC_PHYS_PAGES) |
|
| 71 |
+ return int64(pagesize * npages) |
|
| 72 |
+} |
|
| 73 |
+ |
|
| 74 |
+func getFreeMem() int64 {
|
|
| 75 |
+ pagesize := C.sysconf(C._SC_PAGESIZE) |
|
| 76 |
+ npages := C.sysconf(C._SC_AVPHYS_PAGES) |
|
| 77 |
+ return int64(pagesize * npages) |
|
| 78 |
+} |
|
| 79 |
+ |
|
| 80 |
+// ReadMemInfo retrieves memory statistics of the host system and returns a |
|
| 81 |
+// MemInfo type. |
|
| 82 |
+func ReadMemInfo() (*MemInfo, error) {
|
|
| 83 |
+ |
|
| 84 |
+ ppKernel := C.getPpKernel() |
|
| 85 |
+ MemTotal := getTotalMem() |
|
| 86 |
+ MemFree := getFreeMem() |
|
| 87 |
+ SwapTotal, SwapFree, err := getSysSwap() |
|
| 88 |
+ |
|
| 89 |
+ if ppKernel < 0 || MemTotal < 0 || MemFree < 0 || SwapTotal < 0 || |
|
| 90 |
+ SwapFree < 0 {
|
|
| 91 |
+ return nil, fmt.Errorf("Error getting system memory info %v\n", err)
|
|
| 92 |
+ } |
|
| 93 |
+ |
|
| 94 |
+ meminfo := &MemInfo{}
|
|
| 95 |
+ // Total memory is total physical memory less than memory locked by kernel |
|
| 96 |
+ meminfo.MemTotal = MemTotal - int64(ppKernel) |
|
| 97 |
+ meminfo.MemFree = MemFree |
|
| 98 |
+ meminfo.SwapTotal = SwapTotal |
|
| 99 |
+ meminfo.SwapFree = SwapFree |
|
| 100 |
+ |
|
| 101 |
+ return meminfo, nil |
|
| 102 |
+} |
|
| 103 |
+ |
|
| 104 |
+func getSysSwap() (int64, int64, error) {
|
|
| 105 |
+ var tSwap int64 |
|
| 106 |
+ var fSwap int64 |
|
| 107 |
+ var diskblksPerPage int64 |
|
| 108 |
+ num, err := C.swapctl(C.SC_GETNSWP, nil) |
|
| 109 |
+ if err != nil {
|
|
| 110 |
+ return -1, -1, err |
|
| 111 |
+ } |
|
| 112 |
+ st := C.allocSwaptable(num) |
|
| 113 |
+ _, err = C.swapctl(C.SC_LIST, unsafe.Pointer(st)) |
|
| 114 |
+ if err != nil {
|
|
| 115 |
+ C.freeSwaptable(st) |
|
| 116 |
+ return -1, -1, err |
|
| 117 |
+ } |
|
| 118 |
+ |
|
| 119 |
+ diskblksPerPage = int64(C.sysconf(C._SC_PAGESIZE) >> C.DEV_BSHIFT) |
|
| 120 |
+ for i := 0; i < int(num); i++ {
|
|
| 121 |
+ swapent := C.getSwapEnt(&st.swt_ent[0], C.int(i)) |
|
| 122 |
+ tSwap += int64(swapent.ste_pages) * diskblksPerPage |
|
| 123 |
+ fSwap += int64(swapent.ste_free) * diskblksPerPage |
|
| 124 |
+ } |
|
| 125 |
+ C.freeSwaptable(st) |
|
| 126 |
+ return tSwap, fSwap, nil |
|
| 127 |
+} |
| ... | ... |
@@ -15,3 +15,20 @@ func fromStatT(s *syscall.Stat_t) (*StatT, error) {
|
| 15 | 15 |
rdev: uint64(s.Rdev), |
| 16 | 16 |
mtim: s.Mtim}, nil |
| 17 | 17 |
} |
| 18 |
+ |
|
| 19 |
+// FromStatT loads a system.StatT from a syscal.Stat_t. |
|
| 20 |
+func FromStatT(s *syscall.Stat_t) (*StatT, error) {
|
|
| 21 |
+ return fromStatT(s) |
|
| 22 |
+} |
|
| 23 |
+ |
|
| 24 |
+// Stat takes a path to a file and returns |
|
| 25 |
+// a system.StatT type pertaining to that file. |
|
| 26 |
+// |
|
| 27 |
+// Throws an error if the file does not exist |
|
| 28 |
+func Stat(path string) (*StatT, error) {
|
|
| 29 |
+ s := &syscall.Stat_t{}
|
|
| 30 |
+ if err := syscall.Stat(path, s); err != nil {
|
|
| 31 |
+ return nil, err |
|
| 32 |
+ } |
|
| 33 |
+ return fromStatT(s) |
|
| 34 |
+} |
| 18 | 35 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,48 @@ |
| 0 |
+package runconfig |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "fmt" |
|
| 4 |
+ "strings" |
|
| 5 |
+ |
|
| 6 |
+ "github.com/docker/engine-api/types/container" |
|
| 7 |
+) |
|
| 8 |
+ |
|
| 9 |
+// DefaultDaemonNetworkMode returns the default network stack the daemon should |
|
| 10 |
+// use. |
|
| 11 |
+func DefaultDaemonNetworkMode() container.NetworkMode {
|
|
| 12 |
+ return container.NetworkMode("default")
|
|
| 13 |
+} |
|
| 14 |
+ |
|
| 15 |
+// IsPreDefinedNetwork indicates if a network is predefined by the daemon |
|
| 16 |
+func IsPreDefinedNetwork(network string) bool {
|
|
| 17 |
+ return false |
|
| 18 |
+} |
|
| 19 |
+ |
|
| 20 |
+// ValidateNetMode ensures that the various combinations of requested |
|
| 21 |
+// network settings are valid. |
|
| 22 |
+func ValidateNetMode(c *container.Config, hc *container.HostConfig) error {
|
|
| 23 |
+ // We may not be passed a host config, such as in the case of docker commit |
|
| 24 |
+ if hc == nil {
|
|
| 25 |
+ return nil |
|
| 26 |
+ } |
|
| 27 |
+ parts := strings.Split(string(hc.NetworkMode), ":") |
|
| 28 |
+ switch mode := parts[0]; mode {
|
|
| 29 |
+ case "default", "none": |
|
| 30 |
+ default: |
|
| 31 |
+ return fmt.Errorf("invalid --net: %s", hc.NetworkMode)
|
|
| 32 |
+ } |
|
| 33 |
+ return nil |
|
| 34 |
+} |
|
| 35 |
+ |
|
| 36 |
+// ValidateIsolation performs platform specific validation of the |
|
| 37 |
+// isolation level in the hostconfig structure. |
|
| 38 |
+// This setting is currently discarded for Solaris so this is a no-op. |
|
| 39 |
+func ValidateIsolation(hc *container.HostConfig) error {
|
|
| 40 |
+ return nil |
|
| 41 |
+} |
|
| 42 |
+ |
|
| 43 |
+// ValidateQoS performs platform specific validation of the QoS settings |
|
| 44 |
+// a disk can be limited by either Bps or IOps, but not both. |
|
| 45 |
+func ValidateQoS(hc *container.HostConfig) error {
|
|
| 46 |
+ return nil |
|
| 47 |
+} |