components/docker/patches/0001-Solaris-v1.10.3.patch
changeset 7070 cc52fb049d9b
parent 6874 4b09efc24535
child 7082 c589e79cefef
equal deleted inserted replaced
7066:83336d48cee7 7070:cc52fb049d9b
     1 In-house patch which contains a full port of the v1.10.3 Docker
     1 From 3cf1310ac1de1c3ed1be6341d5d8e6afe255c89f Mon Sep 17 00:00:00 2001
     2 Engine for Solaris. This is being integrated as the first
     2 From: Amit Krishnan <[email protected]>
     3 version of Docker on Solaris, targeting release with Solaris 12.
     3 Date: Thu, 6 Oct 2016 14:24:52 -0700
     4 
       
     5 While work is ongoing upstream in the public project, and
       
     6 most if not all of that code will be integrated upstream, that
       
     7 work will not be done in time to target a Solaris 12 release.
       
     8 This version is the first in hopefully many, and this patch
       
     9 will be deprecated in future release integrations. 
       
    10 Subject: [PATCH] Solaris-v1.10.3
     4 Subject: [PATCH] Solaris-v1.10.3
    11 
     5 
    12 ---
     6 ---
    13  Dockerfile.solaris                                 |   26 +
     7  Dockerfile.solaris                                 |   26 +
    14  Makefile                                           |   35 +-
     8  Makefile                                           |   35 +-
    15  api/client/run.go                                  |    1 +
     9  api/client/run.go                                  |    1 +
       
    10  api/client/version.go                              |   20 -
    16  api/server/router/container/container_routes.go    |    7 +
    11  api/server/router/container/container_routes.go    |    7 +
    17  api/server/server_unix.go                          |    2 +-
    12  api/server/server_unix.go                          |    2 +-
    18  container/container_solaris.go                     |  649 ++++++++++++
    13  container/container_solaris.go                     |  649 ++++++++++++
    19  container/monitor.go                               |    9 +
    14  container/monitor.go                               |    9 +
    20  container/state_solaris.go                         |    9 +
    15  container/state_solaris.go                         |    9 +
    25  daemon/commit.go                                   |   22 +-
    20  daemon/commit.go                                   |   22 +-
    26  daemon/config.go                                   |    4 +
    21  daemon/config.go                                   |    4 +
    27  daemon/config_solaris.go                           |   66 ++
    22  daemon/config_solaris.go                           |   66 ++
    28  daemon/config_test.go                              |   30 +-
    23  daemon/config_test.go                              |   30 +-
    29  daemon/container_operations_solaris.go             |  973 ++++++++++++++++++
    24  daemon/container_operations_solaris.go             |  973 ++++++++++++++++++
    30  daemon/daemon.go                                   |    9 +-
    25  daemon/daemon.go                                   |    6 +-
    31  daemon/daemon_solaris.go                           |  544 ++++++++++
    26  daemon/daemon_solaris.go                           |  544 ++++++++++
    32  daemon/daemon_test.go                              |    2 +
    27  daemon/daemon_test.go                              |    2 +
    33  daemon/daemon_unix_test.go                         |    2 +-
    28  daemon/daemon_unix_test.go                         |    2 +-
    34  daemon/daemon_unsupported.go                       |    2 +-
    29  daemon/daemon_unsupported.go                       |    2 +-
    35  daemon/daemonbuilder/builder_unix.go               |    2 +-
    30  daemon/daemonbuilder/builder_unix.go               |    2 +-
    36  daemon/debugtrap_unsupported.go                    |    2 +-
    31  daemon/debugtrap_unsupported.go                    |    2 +-
    37  daemon/exec_solaris.go                             |   18 +
    32  daemon/exec_solaris.go                             |   18 +
    38  daemon/execdriver/driver_solaris.go                |   76 ++
    33  daemon/execdriver/driver_solaris.go                |   76 ++
    39  daemon/execdriver/driver_unix.go                   |    2 +-
    34  daemon/execdriver/driver_unix.go                   |    2 +-
    40  .../execdriver/execdrivers/execdrivers_solaris.go  |   13 +
    35  .../execdriver/execdrivers/execdrivers_solaris.go  |   13 +
    41  daemon/execdriver/zones/driver.go                  |  772 ++++++++++++++
    36  daemon/execdriver/zones/driver.go                  |  745 ++++++++++++++
    42  daemon/execdriver/zones/driver_unsupported.go      |   12 +
    37  daemon/execdriver/zones/driver_unsupported.go      |   12 +
    43  .../execdriver/zones/driver_unsupported_nocgo.go   |   13 +
    38  .../execdriver/zones/driver_unsupported_nocgo.go   |   13 +
    44  daemon/graphdriver/driver_solaris.go               |    8 +
    39  daemon/graphdriver/driver_solaris.go               |    8 +
    45  daemon/graphdriver/driver_unsupported.go           |    2 +-
    40  daemon/graphdriver/driver_unsupported.go           |    2 +-
    46  daemon/graphdriver/graphtest/graphtest_unix.go     |    2 +-
    41  daemon/graphdriver/graphtest/graphtest_unix.go     |    2 +-
    48  daemon/graphdriver/zfs/zfs.go                      |   47 +-
    43  daemon/graphdriver/zfs/zfs.go                      |   47 +-
    49  daemon/graphdriver/zfs/zfs_freebsd.go              |   36 +
    44  daemon/graphdriver/zfs/zfs_freebsd.go              |   36 +
    50  daemon/graphdriver/zfs/zfs_linux.go                |   37 +
    45  daemon/graphdriver/zfs/zfs_linux.go                |   37 +
    51  daemon/graphdriver/zfs/zfs_solaris.go              |   95 ++
    46  daemon/graphdriver/zfs/zfs_solaris.go              |   95 ++
    52  daemon/graphdriver/zfs/zfs_unsupported.go          |    2 +-
    47  daemon/graphdriver/zfs/zfs_unsupported.go          |    2 +-
       
    48  daemon/info.go                                     |    2 -
    53  daemon/inspect_solaris.go                          |   30 +
    49  daemon/inspect_solaris.go                          |   30 +
    54  daemon/inspect_unix.go                             |    2 +-
    50  daemon/inspect_unix.go                             |    2 +-
    55  daemon/list_unix.go                                |    2 +-
    51  daemon/list_unix.go                                |    2 +-
    56  daemon/network.go                                  |    7 +
    52  daemon/network.go                                  |    7 +
    57  daemon/selinux_unsupported.go                      |    8 +
    53  daemon/selinux_unsupported.go                      |    8 +
    58  daemon/start.go                                    |   63 ++
    54  daemon/start.go                                    |   65 ++
    59  daemon/stats_collector_solaris.go                  |  139 +++
    55  daemon/stats_collector_solaris.go                  |  537 ++++++++++
    60  daemon/stats_collector_unix.go                     |    2 +-
    56  daemon/stats_collector_unix.go                     |    2 +-
    61  daemon/stats_solaris.go                            |   82 ++
    57  daemon/stats_solaris.go                            |   84 ++
    62  docker/daemon_solaris.go                           |   58 ++
    58  docker/daemon_solaris.go                           |   58 ++
    63  docker/daemon_unix.go                              |    2 +-
    59  docker/daemon_unix.go                              |    2 +-
    64  hack/.vendor-helpers.sh                            |    8 +-
    60  hack/.vendor-helpers.sh                            |    8 +-
    65  hack/make.sh                                       |   14 +-
    61  hack/make.sh                                       |   14 +-
    66  hack/make/.detect-daemon-osarch                    |   20 +-
    62  hack/make/.detect-daemon-osarch                    |   20 +-
   126  pkg/reexec/command_solaris.go                      |   23 +
   122  pkg/reexec/command_solaris.go                      |   23 +
   127  pkg/reexec/command_unsupported.go                  |    2 +-
   123  pkg/reexec/command_unsupported.go                  |    2 +-
   128  pkg/signal/signal_solaris.go                       |   42 +
   124  pkg/signal/signal_solaris.go                       |   42 +
   129  pkg/signal/signal_unsupported.go                   |    2 +-
   125  pkg/signal/signal_unsupported.go                   |    2 +-
   130  pkg/sysinfo/sysinfo_solaris.go                     |  117 +++
   126  pkg/sysinfo/sysinfo_solaris.go                     |  117 +++
   131  pkg/system/meminfo_solaris.go                      |  133 +++
   127  pkg/system/meminfo_solaris.go                      |  127 +++
   132  pkg/system/meminfo_unsupported.go                  |    2 +-
   128  pkg/system/meminfo_unsupported.go                  |    2 +-
   133  pkg/system/stat_linux.go                           |   33 -
   129  pkg/system/stat_linux.go                           |   33 -
   134  pkg/system/stat_solaris.go                         |   20 +-
   130  pkg/system/stat_solaris.go                         |   20 +-
   135  pkg/system/stat_unix.go                            |   35 +
   131  pkg/system/stat_unix.go                            |   35 +
   136  pkg/system/stat_unsupported.go                     |    2 +-
   132  pkg/system/stat_unsupported.go                     |    2 +-
   146  runconfig/hostconfig_unix.go                       |    1 +
   142  runconfig/hostconfig_unix.go                       |    1 +
   147  runconfig/opts/parse.go                            |    2 +
   143  runconfig/opts/parse.go                            |    2 +
   148  .../github.com/Sirupsen/logrus/terminal_solaris.go |   15 +
   144  .../github.com/Sirupsen/logrus/terminal_solaris.go |   15 +
   149  .../docker/engine-api/types/container/config.go    |    4 +
   145  .../docker/engine-api/types/container/config.go    |    4 +
   150  .../engine-api/types/container/host_config.go      |    1 +
   146  .../engine-api/types/container/host_config.go      |    1 +
       
   147  .../github.com/docker/engine-api/types/types.go    |    2 -
   151  .../docker/go-connections/sockets/unix_socket.go   |    2 +-
   148  .../docker/go-connections/sockets/unix_socket.go   |    2 +-
   152  .../docker/libnetwork/default_gateway_solaris.go   |    7 +
   149  .../docker/libnetwork/default_gateway_solaris.go   |    7 +
   153  .../libnetwork/drivers/solaris/bridge/bridge.go    | 1062 ++++++++++++++++++++
   150  .../libnetwork/drivers/solaris/bridge/bridge.go    | 1076 ++++++++++++++++++++
   154  .../drivers/solaris/bridge/bridge_store.go         |  212 ++++
   151  .../drivers/solaris/bridge/bridge_store.go         |  212 ++++
   155  .../libnetwork/drivers/solaris/bridge/errors.go    |  341 +++++++
   152  .../libnetwork/drivers/solaris/bridge/errors.go    |  341 +++++++
   156  .../drivers/solaris/bridge/port_mapping.go         |  199 ++++
   153  .../drivers/solaris/bridge/port_mapping.go         |  218 ++++
   157  .../docker/libnetwork/drivers_solaris.go           |   13 +
   154  .../docker/libnetwork/drivers_solaris.go           |   13 +
   158  .../docker/libnetwork/ipamutils/utils_solaris.go   |   92 ++
   155  .../docker/libnetwork/ipamutils/utils_solaris.go   |   92 ++
   159  vendor/src/github.com/docker/libnetwork/network.go |    2 -
   156  vendor/src/github.com/docker/libnetwork/network.go |    2 -
   160  .../docker/libnetwork/osl/interface_solaris.go     |    6 +
   157  .../docker/libnetwork/osl/interface_solaris.go     |    6 +
   161  .../docker/libnetwork/osl/namespace_solaris.go     |   41 +
   158  .../docker/libnetwork/osl/namespace_solaris.go     |   41 +
   170  .../docker/libnetwork/portmapper/mapper_solaris.go |  150 +++
   167  .../docker/libnetwork/portmapper/mapper_solaris.go |  150 +++
   171  .../docker/libnetwork/portmapper/mock_proxy.go     |   18 -
   168  .../docker/libnetwork/portmapper/mock_proxy.go     |   18 -
   172  .../libnetwork/portmapper/mock_proxy_linux.go      |   18 +
   169  .../libnetwork/portmapper/mock_proxy_linux.go      |   18 +
   173  .../docker/libnetwork/portmapper/proxy.go          |  209 ----
   170  .../docker/libnetwork/portmapper/proxy.go          |  209 ----
   174  .../docker/libnetwork/portmapper/proxy_linux.go    |  209 ++++
   171  .../docker/libnetwork/portmapper/proxy_linux.go    |  209 ++++
       
   172  vendor/src/github.com/docker/libnetwork/sandbox.go |    7 +-
   175  .../libnetwork/sandbox_externalkey_solaris.go      |   45 +
   173  .../libnetwork/sandbox_externalkey_solaris.go      |   45 +
   176  .../docker/libnetwork/sandbox_externalkey_unix.go  |    2 +-
   174  .../docker/libnetwork/sandbox_externalkey_unix.go  |    2 +-
   177  .../src/github.com/godbus/dbus/transport_unix.go   |    2 +-
   175  .../src/github.com/godbus/dbus/transport_unix.go   |    2 +-
   178  vendor/src/github.com/kr/pty/ioctl.go              |    2 +
   176  vendor/src/github.com/kr/pty/ioctl.go              |    2 +
   179  vendor/src/github.com/kr/pty/util.go               |   11 -
   177  vendor/src/github.com/kr/pty/util.go               |   11 -
   188  .../github.com/mistifyio/go-zfs/zpool_solaris.go   |   40 +
   186  .../github.com/mistifyio/go-zfs/zpool_solaris.go   |   40 +
   189  .../runc/libcontainer/configs/cgroup_solaris.go    |    6 +
   187  .../runc/libcontainer/configs/cgroup_solaris.go    |    6 +
   190  .../libcontainer/configs/cgroup_unsupported.go     |    2 +-
   188  .../libcontainer/configs/cgroup_unsupported.go     |    2 +-
   191  .../runc/libcontainer/configs/device_defaults.go   |    4 +-
   189  .../runc/libcontainer/configs/device_defaults.go   |    4 +-
   192  .../runc/libcontainer/console_solaris.go           |   13 +
   190  .../runc/libcontainer/console_solaris.go           |   13 +
   193  .../runc/libcontainer/container_solaris.go         |  103 ++
   191  .../runc/libcontainer/container_solaris.go         |   22 +
   194  .../runc/libcontainer/stats_solaris.go             |    8 +
   192  .../runc/libcontainer/stats_solaris.go             |    8 +
   195  .../runc/libcontainer/system/sysconfig.go          |    2 +-
   193  .../runc/libcontainer/system/sysconfig.go          |    2 +-
   196  .../runc/libcontainer/zones/stats.go               |   86 ++
   194  .../runc/libcontainer/zones/stats.go               |   86 ++
   197  vendor/src/gopkg.in/fsnotify.v1/fen.go             |  188 ++++
   195  vendor/src/gopkg.in/fsnotify.v1/fen.go             |  188 ++++
   198  vendor/src/gopkg.in/fsnotify.v1/fen_cgo.go         |   82 ++
   196  vendor/src/gopkg.in/fsnotify.v1/fen_cgo.go         |   82 ++
   199  vendor/src/gopkg.in/fsnotify.v1/fsnotify.go        |    2 +-
   197  vendor/src/gopkg.in/fsnotify.v1/fsnotify.go        |    2 +-
   200  volume/local/local_unix.go                         |    2 +-
   198  volume/local/local_unix.go                         |    2 +-
   201  volume/store/store_unix.go                         |    2 +-
   199  volume/store/store_unix.go                         |    2 +-
   202  189 files changed, 8839 insertions(+), 1215 deletions(-)
   200  193 files changed, 9162 insertions(+), 1241 deletions(-)
   203  create mode 100644 Dockerfile.solaris
   201  create mode 100644 Dockerfile.solaris
   204  create mode 100644 container/container_solaris.go
   202  create mode 100644 container/container_solaris.go
   205  create mode 100644 container/state_solaris.go
   203  create mode 100644 container/state_solaris.go
   206  create mode 100755 contrib/mkimage/solaris
   204  create mode 100755 contrib/mkimage/solaris
   207  create mode 100644 daemon/config_solaris.go
   205  create mode 100644 daemon/config_solaris.go
   396  	} else {
   394  	} else {
   397 +
   395 +
   398  		// No Autoremove: Simply retrieve the exit code
   396  		// No Autoremove: Simply retrieve the exit code
   399  		if !config.Tty {
   397  		if !config.Tty {
   400  			// In non-TTY mode, we can't detach, so we must wait for container exit
   398  			// In non-TTY mode, we can't detach, so we must wait for container exit
       
   399 diff --git a/api/client/version.go b/api/client/version.go
       
   400 index a64deef..3000b1a 100644
       
   401 --- a/api/client/version.go
       
   402 +++ b/api/client/version.go
       
   403 @@ -3,7 +3,6 @@ package client
       
   404  import (
       
   405  	"runtime"
       
   406  	"text/template"
       
   407 -	"time"
       
   408  
       
   409  	Cli "github.com/docker/docker/cli"
       
   410  	"github.com/docker/docker/dockerversion"
       
   411 @@ -16,8 +15,6 @@ var versionTemplate = `Client:
       
   412   Version:      {{.Client.Version}}
       
   413   API version:  {{.Client.APIVersion}}
       
   414   Go version:   {{.Client.GoVersion}}
       
   415 - Git commit:   {{.Client.GitCommit}}
       
   416 - Built:        {{.Client.BuildTime}}
       
   417   OS/Arch:      {{.Client.Os}}/{{.Client.Arch}}{{if .Client.Experimental}}
       
   418   Experimental: {{.Client.Experimental}}{{end}}{{if .ServerOK}}
       
   419  
       
   420 @@ -25,8 +22,6 @@ Server:
       
   421   Version:      {{.Server.Version}}
       
   422   API version:  {{.Server.APIVersion}}
       
   423   Go version:   {{.Server.GoVersion}}
       
   424 - Git commit:   {{.Server.GitCommit}}
       
   425 - Built:        {{.Server.BuildTime}}
       
   426   OS/Arch:      {{.Server.Os}}/{{.Server.Arch}}{{if .Server.Experimental}}
       
   427   Experimental: {{.Server.Experimental}}{{end}}{{end}}`
       
   428  
       
   429 @@ -58,8 +53,6 @@ func (cli *DockerCli) CmdVersion(args ...string) (err error) {
       
   430  			Version:      dockerversion.Version,
       
   431  			APIVersion:   cli.client.ClientVersion(),
       
   432  			GoVersion:    runtime.Version(),
       
   433 -			GitCommit:    dockerversion.GitCommit,
       
   434 -			BuildTime:    dockerversion.BuildTime,
       
   435  			Os:           runtime.GOOS,
       
   436  			Arch:         runtime.GOARCH,
       
   437  			Experimental: utils.ExperimentalBuild(),
       
   438 @@ -71,19 +64,6 @@ func (cli *DockerCli) CmdVersion(args ...string) (err error) {
       
   439  		vd.Server = &serverVersion
       
   440  	}
       
   441  
       
   442 -	// first we need to make BuildTime more human friendly
       
   443 -	t, errTime := time.Parse(time.RFC3339Nano, vd.Client.BuildTime)
       
   444 -	if errTime == nil {
       
   445 -		vd.Client.BuildTime = t.Format(time.ANSIC)
       
   446 -	}
       
   447 -
       
   448 -	if vd.ServerOK() {
       
   449 -		t, errTime = time.Parse(time.RFC3339Nano, vd.Server.BuildTime)
       
   450 -		if errTime == nil {
       
   451 -			vd.Server.BuildTime = t.Format(time.ANSIC)
       
   452 -		}
       
   453 -	}
       
   454 -
       
   455  	if err2 := tmpl.Execute(cli.out, vd); err2 != nil && err == nil {
       
   456  		err = err2
       
   457  	}
   401 diff --git a/api/server/router/container/container_routes.go b/api/server/router/container/container_routes.go
   458 diff --git a/api/server/router/container/container_routes.go b/api/server/router/container/container_routes.go
   402 index 4e2ffca..e58405b 100644
   459 index 4e2ffca..e58405b 100644
   403 --- a/api/server/router/container/container_routes.go
   460 --- a/api/server/router/container/container_routes.go
   404 +++ b/api/server/router/container/container_routes.go
   461 +++ b/api/server/router/container/container_routes.go
   405 @@ -27,6 +27,11 @@ import (
   462 @@ -27,6 +27,11 @@ import (
  2469 +
  2526 +
  2470 +func errRemovalContainer(containerID string) error {
  2527 +func errRemovalContainer(containerID string) error {
  2471 +	return fmt.Errorf("Container %s is marked for removal and cannot be connected or disconnected to the network", containerID)
  2528 +	return fmt.Errorf("Container %s is marked for removal and cannot be connected or disconnected to the network", containerID)
  2472 +}
  2529 +}
  2473 diff --git a/daemon/daemon.go b/daemon/daemon.go
  2530 diff --git a/daemon/daemon.go b/daemon/daemon.go
  2474 index 6cb7f8c..3d2b2f8 100644
  2531 index 6cb7f8c..f360392 100644
  2475 --- a/daemon/daemon.go
  2532 --- a/daemon/daemon.go
  2476 +++ b/daemon/daemon.go
  2533 +++ b/daemon/daemon.go
  2477 @@ -766,7 +766,7 @@ func NewDaemon(config *Config, registryService *registry.Service) (daemon *Daemo
  2534 @@ -766,7 +766,7 @@ func NewDaemon(config *Config, registryService *registry.Service) (daemon *Daemo
  2478  	sysInfo := sysinfo.New(false)
  2535  	sysInfo := sysinfo.New(false)
  2479  	// Check if Devices cgroup is mounted, it is hard requirement for container security,
  2536  	// Check if Devices cgroup is mounted, it is hard requirement for container security,
  2495  	}
  2552  	}
  2496 +	return nil
  2553 +	return nil
  2497  }
  2554  }
  2498  
  2555  
  2499  // Run uses the execution driver to run a given container
  2556  // Run uses the execution driver to run a given container
  2500 @@ -1040,6 +1042,9 @@ func (daemon *Daemon) ExportImage(names []string, outStream io.Writer) error {
       
  2501  
       
  2502  // PushImage initiates a push operation on the repository named localName.
       
  2503  func (daemon *Daemon) PushImage(ref reference.Named, metaHeaders map[string][]string, authConfig *types.AuthConfig, outStream io.Writer) error {
       
  2504 +	if runtime.GOOS == "solaris" {
       
  2505 +		return fmt.Errorf("Pushing an image not supported on Solaris platform")
       
  2506 +	}
       
  2507  	// Include a buffer so that slow client connections don't affect
       
  2508  	// transfer performance.
       
  2509  	progressChan := make(chan progress.Progress, 100)
       
  2510 diff --git a/daemon/daemon_solaris.go b/daemon/daemon_solaris.go
  2557 diff --git a/daemon/daemon_solaris.go b/daemon/daemon_solaris.go
  2511 new file mode 100644
  2558 new file mode 100644
  2512 index 0000000..ebec5ad
  2559 index 0000000..ebec5ad
  2513 --- /dev/null
  2560 --- /dev/null
  2514 +++ b/daemon/daemon_solaris.go
  2561 +++ b/daemon/daemon_solaris.go
  3242 +func NewDriver(options []string, root, libPath string, sysInfo *sysinfo.SysInfo) (execdriver.Driver, error) {
  3289 +func NewDriver(options []string, root, libPath string, sysInfo *sysinfo.SysInfo) (execdriver.Driver, error) {
  3243 +	return zones.NewDriver(root, options)
  3290 +	return zones.NewDriver(root, options)
  3244 +}
  3291 +}
  3245 diff --git a/daemon/execdriver/zones/driver.go b/daemon/execdriver/zones/driver.go
  3292 diff --git a/daemon/execdriver/zones/driver.go b/daemon/execdriver/zones/driver.go
  3246 new file mode 100644
  3293 new file mode 100644
  3247 index 0000000..b407ba5
  3294 index 0000000..de5b637
  3248 --- /dev/null
  3295 --- /dev/null
  3249 +++ b/daemon/execdriver/zones/driver.go
  3296 +++ b/daemon/execdriver/zones/driver.go
  3250 @@ -0,0 +1,772 @@
  3297 @@ -0,0 +1,745 @@
  3251 +// +build solaris,cgo
  3298 +// +build solaris,cgo
  3252 +
  3299 +
  3253 +package zones
  3300 +package zones
  3254 +
  3301 +
  3255 +import (
  3302 +import (
  3264 +	"path/filepath"
  3311 +	"path/filepath"
  3265 +	"strconv"
  3312 +	"strconv"
  3266 +	"strings"
  3313 +	"strings"
  3267 +	"sync"
  3314 +	"sync"
  3268 +	"syscall"
  3315 +	"syscall"
  3269 +	"time"
       
  3270 +
  3316 +
  3271 +	"github.com/Sirupsen/logrus"
  3317 +	"github.com/Sirupsen/logrus"
  3272 +	"github.com/docker/docker/daemon/execdriver"
  3318 +	"github.com/docker/docker/daemon/execdriver"
  3273 +	sysinfo "github.com/docker/docker/pkg/system"
       
  3274 +	"github.com/opencontainers/runc/libcontainer"
  3319 +	"github.com/opencontainers/runc/libcontainer"
  3275 +)
  3320 +)
  3276 +
  3321 +
  3277 +/*
  3322 +/*
  3278 +
  3323 +
  3369 +}
  3414 +}
  3370 +
  3415 +
  3371 +type Driver struct {
  3416 +type Driver struct {
  3372 +	root             string
  3417 +	root             string
  3373 +	activeContainers map[string]*activeContainer
  3418 +	activeContainers map[string]*activeContainer
  3374 +	machineMemory    int64
       
  3375 +	sync.Mutex
  3419 +	sync.Mutex
  3376 +}
  3420 +}
  3377 +
  3421 +
  3378 +type info struct {
  3422 +type info struct {
  3379 +	ID     string
  3423 +	ID     string
  3445 +	Uid            int64   `json:"uid"`
  3489 +	Uid            int64   `json:"uid"`
  3446 +}
  3490 +}
  3447 +
  3491 +
  3448 +func startWrapper(cmd *exec.Cmd) error {
  3492 +func startWrapper(cmd *exec.Cmd) error {
  3449 +	// create processes in their own process contracts
  3493 +	// create processes in their own process contracts
  3450 +	var errn, cttmpl C.int
  3494 +	var cttmpl C.int
  3451 +
  3495 +	var err error
  3452 +	if cttmpl = C.ct_pr_tmpl(); cttmpl == -1 {
  3496 +
  3453 +		errno_msg := C.GoString(C.strerror(errn))
  3497 +	if cttmpl, err = C.ct_pr_tmpl(); cttmpl == -1 {
  3454 +		return errors.New("Failed to create process contract template: " + errno_msg)
  3498 +		return err
  3455 +	}
  3499 +	}
  3456 +	defer func() {
  3500 +	defer func() {
  3457 +		if errn = C.ct_abandon_latest(); errn != 0 {
  3501 +		if errn := C.ct_abandon_latest(); errn != 0 {
  3458 +			logrus.Error("Failed to abandon process contract: %v", C.GoString(C.strerror(errn)))
  3502 +			logrus.Error("Failed to abandon process contract: ", C.GoString(C.strerror(errn)))
  3459 +		} else if errn = C.ct_clear(cttmpl); errn != 0 {
  3503 +		}
  3460 +			logrus.Error("Failed to clear process contract template %v", C.GoString(C.strerror(errn)))
  3504 +		if errn := C.ct_clear(cttmpl); errn != 0 {
       
  3505 +			logrus.Error("Failed to clear process contract template ", C.GoString(C.strerror(errn)))
  3461 +		}
  3506 +		}
  3462 +	}()
  3507 +	}()
  3463 +	err := cmd.Start()
  3508 +	err = cmd.Start()
  3464 +
  3509 +
  3465 +	return err
  3510 +	return err
  3466 +}
  3511 +}
  3467 +
  3512 +
  3468 +func NewDriver(root string, options []string) (*Driver, error) {
  3513 +func NewDriver(root string, options []string) (*Driver, error) {
  3469 +	meminfo, err := sysinfo.ReadMemInfo()
       
  3470 +	if err != nil {
       
  3471 +		return nil, err
       
  3472 +	}
       
  3473 +	if err := os.MkdirAll(root, 0700); err != nil {
  3514 +	if err := os.MkdirAll(root, 0700); err != nil {
  3474 +		return nil, err
  3515 +		return nil, err
  3475 +	}
  3516 +	}
  3476 +
  3517 +
  3477 +	return &Driver{
  3518 +	return &Driver{
  3478 +		root:             root,
  3519 +		root:             root,
  3479 +		activeContainers: make(map[string]*activeContainer),
  3520 +		activeContainers: make(map[string]*activeContainer),
  3480 +		machineMemory:    meminfo.MemTotal,
       
  3481 +	}, nil
  3521 +	}, nil
  3482 +}
  3522 +}
  3483 +
  3523 +
  3484 +func getEnv(key string, env []string) string {
  3524 +func getEnv(key string, env []string) string {
  3485 +	for _, pair := range env {
  3525 +	for _, pair := range env {
  3824 +	r, w, err := os.Pipe()
  3864 +	r, w, err := os.Pipe()
  3825 +	if err != nil {
  3865 +	if err != nil {
  3826 +		return execdriver.ExitStatus{ExitCode: -1}, err
  3866 +		return execdriver.ExitStatus{ExitCode: -1}, err
  3827 +	}
  3867 +	}
  3828 +
  3868 +
  3829 +
       
  3830 +	if pipes.Stdin != nil {
  3869 +	if pipes.Stdin != nil {
  3831 +		go func() {
  3870 +		go func() {
  3832 +			io.Copy(w, pipes.Stdin)
  3871 +			io.Copy(w, pipes.Stdin)
  3833 +			w.Close()
  3872 +			w.Close()
  3834 +		}()
  3873 +		}()
  3971 +	return os.RemoveAll(filepath.Join(d.root, id))
  4010 +	return os.RemoveAll(filepath.Join(d.root, id))
  3972 +}
  4011 +}
  3973 +
  4012 +
  3974 +// Stats implements the exec driver Driver interface.
  4013 +// Stats implements the exec driver Driver interface.
  3975 +func (d *Driver) Stats(id string) (*execdriver.ResourceStats, error) {
  4014 +func (d *Driver) Stats(id string) (*execdriver.ResourceStats, error) {
  3976 +	stats, err := libcontainer.GetStats(id)
  4015 +	return nil, errors.New("Stats is not supported in zones execdriver")
  3977 +	if err != nil {
       
  3978 +		return nil, err
       
  3979 +	}
       
  3980 +	// XXX: get from container configuration the memory resource limit
       
  3981 +	//      in linux: c.Config().Cgroups.Resources.Memory
       
  3982 +	var memoryLimit int64 = 0
       
  3983 +	// if the container does not have any memory limit specified set the
       
  3984 +	// limit to the machines memory
       
  3985 +	if memoryLimit == 0 {
       
  3986 +		memoryLimit = d.machineMemory
       
  3987 +	}
       
  3988 +
       
  3989 +	p := &execdriver.ResourceStats{
       
  3990 +		Stats:       stats,
       
  3991 +		Read:        time.Now(),
       
  3992 +		MemoryLimit: memoryLimit,
       
  3993 +	}
       
  3994 +
       
  3995 +	return p, nil
       
  3996 +}
  4016 +}
  3997 +
  4017 +
  3998 +// Stats implements the exec driver Driver interface.
  4018 +// Stats implements the exec driver Driver interface.
  3999 +func (d *Driver) Update(c *execdriver.Command) error {
  4019 +func (d *Driver) Update(c *execdriver.Command) error {
  4000 +	return errors.New("Update is not supported in zones execdriver")
  4020 +	return errors.New("Update is not supported in zones execdriver")
  4415 -// +build !linux,!freebsd
  4435 -// +build !linux,!freebsd
  4416 +// +build !linux,!freebsd,!solaris
  4436 +// +build !linux,!freebsd,!solaris
  4417  
  4437  
  4418  package zfs
  4438  package zfs
  4419  
  4439  
       
  4440 diff --git a/daemon/info.go b/daemon/info.go
       
  4441 index 008ac20..3d86bc0 100644
       
  4442 --- a/daemon/info.go
       
  4443 +++ b/daemon/info.go
       
  4444 @@ -134,11 +134,9 @@ func (daemon *Daemon) SystemInfo() (*types.Info, error) {
       
  4445  func (daemon *Daemon) SystemVersion() types.Version {
       
  4446  	v := types.Version{
       
  4447  		Version:      dockerversion.Version,
       
  4448 -		GitCommit:    dockerversion.GitCommit,
       
  4449  		GoVersion:    runtime.Version(),
       
  4450  		Os:           runtime.GOOS,
       
  4451  		Arch:         runtime.GOARCH,
       
  4452 -		BuildTime:    dockerversion.BuildTime,
       
  4453  		Experimental: utils.ExperimentalBuild(),
       
  4454  	}
       
  4455  
  4420 diff --git a/daemon/inspect_solaris.go b/daemon/inspect_solaris.go
  4456 diff --git a/daemon/inspect_solaris.go b/daemon/inspect_solaris.go
  4421 new file mode 100644
  4457 new file mode 100644
  4422 index 0000000..e42a61d
  4458 index 0000000..e42a61d
  4423 --- /dev/null
  4459 --- /dev/null
  4424 +++ b/daemon/inspect_solaris.go
  4460 +++ b/daemon/inspect_solaris.go
  4527 +
  4563 +
  4528 +func mergeLxcConfIntoOptions(hostConfig *containertypes.HostConfig) ([]string, error) {
  4564 +func mergeLxcConfIntoOptions(hostConfig *containertypes.HostConfig) ([]string, error) {
  4529 +	return nil, nil
  4565 +	return nil, nil
  4530 +}
  4566 +}
  4531 diff --git a/daemon/start.go b/daemon/start.go
  4567 diff --git a/daemon/start.go b/daemon/start.go
  4532 index 418dace..c74f07a 100644
  4568 index 418dace..9d5e6cb 100644
  4533 --- a/daemon/start.go
  4569 --- a/daemon/start.go
  4534 +++ b/daemon/start.go
  4570 +++ b/daemon/start.go
  4535 @@ -1,7 +1,10 @@
  4571 @@ -1,7 +1,10 @@
  4536  package daemon
  4572  package daemon
  4537  
  4573  
  4550 +const SVCCFG = "/usr/sbin/svccfg"
  4586 +const SVCCFG = "/usr/sbin/svccfg"
  4551 +
  4587 +
  4552  // ContainerStart starts a container.
  4588  // ContainerStart starts a container.
  4553  func (daemon *Daemon) ContainerStart(name string, hostConfig *containertypes.HostConfig) error {
  4589  func (daemon *Daemon) ContainerStart(name string, hostConfig *containertypes.HostConfig) error {
  4554  	container, err := daemon.GetContainer(name)
  4590  	container, err := daemon.GetContainer(name)
  4555 @@ -109,6 +114,10 @@ func (daemon *Daemon) containerStart(container *container.Container) (err error)
  4591 @@ -142,6 +147,24 @@ func (daemon *Daemon) containerStart(container *container.Container) (err error)
  4556  		return err
       
  4557  	}
       
  4558  
       
  4559 +	if err := daemon.injectHostConfig(container); err != nil {
       
  4560 +		return err
       
  4561 +	}
       
  4562 +
       
  4563  	// Make sure NetworkMode has an acceptable value. We do this to ensure
       
  4564  	// backwards API compatibility.
       
  4565  	container.HostConfig = runconfig.SetDefaultNetModeIfBlank(container.HostConfig)
       
  4566 @@ -142,6 +151,18 @@ func (daemon *Daemon) containerStart(container *container.Container) (err error)
       
  4567  	mounts = append(mounts, container.TmpfsMounts()...)
  4592  	mounts = append(mounts, container.TmpfsMounts()...)
  4568  
  4593  
  4569  	container.Command.Mounts = mounts
  4594  	container.Command.Mounts = mounts
  4570 +
  4595 +
  4571 +	if runtime.GOOS == "solaris" {
  4596 +	if runtime.GOOS == "solaris" {
  4577 +			}
  4602 +			}
  4578 +		}
  4603 +		}
  4579 +		container.Command.ContOS = img.Os
  4604 +		container.Command.ContOS = img.Os
  4580 +	}
  4605 +	}
  4581 +
  4606 +
       
  4607 +	if container.Command.ContOS == "solaris" {
       
  4608 +		if err := daemon.injectHostConfig(container); err != nil {
       
  4609 +			return err
       
  4610 +	}
       
  4611 +
       
  4612 +	}
  4582  	if err := daemon.waitForStart(container); err != nil {
  4613  	if err := daemon.waitForStart(container); err != nil {
  4583  		return err
  4614  		return err
  4584  	}
  4615  	}
  4585 @@ -170,3 +191,45 @@ func (daemon *Daemon) Cleanup(container *container.Container) {
  4616 @@ -170,3 +193,45 @@ func (daemon *Daemon) Cleanup(container *container.Container) {
  4586  		logrus.Warnf("%s cleanup: Failed to umount volumes: %v", container.ID, err)
  4617  		logrus.Warnf("%s cleanup: Failed to umount volumes: %v", container.ID, err)
  4587  	}
  4618  	}
  4588  }
  4619  }
  4589 +
  4620 +
  4590 +// injectHostConfig() should be abstracted away.
  4621 +// injectHostConfig() should be abstracted away.
  4628 +
  4659 +
  4629 +	return err
  4660 +	return err
  4630 +}
  4661 +}
  4631 diff --git a/daemon/stats_collector_solaris.go b/daemon/stats_collector_solaris.go
  4662 diff --git a/daemon/stats_collector_solaris.go b/daemon/stats_collector_solaris.go
  4632 new file mode 100644
  4663 new file mode 100644
  4633 index 0000000..9a51b27
  4664 index 0000000..4d4b4a0
  4634 --- /dev/null
  4665 --- /dev/null
  4635 +++ b/daemon/stats_collector_solaris.go
  4666 +++ b/daemon/stats_collector_solaris.go
  4636 @@ -0,0 +1,139 @@
  4667 @@ -0,0 +1,537 @@
  4637 +package daemon
  4668 +package daemon
  4638 +
  4669 +
  4639 +import (
  4670 +import (
  4640 +	"bufio"
  4671 +	"bufio"
  4641 +	"sync"
       
  4642 +	"time"
       
  4643 +	"github.com/Sirupsen/logrus"
  4672 +	"github.com/Sirupsen/logrus"
  4644 +	"github.com/docker/docker/container"
  4673 +	"github.com/docker/docker/container"
  4645 +	"github.com/docker/docker/daemon/execdriver"
  4674 +	"github.com/docker/docker/daemon/execdriver"
  4646 +	"github.com/docker/docker/pkg/pubsub"
  4675 +	"github.com/docker/docker/pkg/pubsub"
       
  4676 +	"github.com/docker/docker/pkg/system"
       
  4677 +	"github.com/docker/libnetwork/types"
       
  4678 +	"github.com/opencontainers/runc/libcontainer"
       
  4679 +	"github.com/opencontainers/runc/libcontainer/zones"
       
  4680 +	"strings"
       
  4681 +	"sync"
       
  4682 +	"time"
  4647 +)
  4683 +)
       
  4684 +
       
  4685 +/*
       
  4686 +
       
  4687 +#cgo LDFLAGS: -lzonestat -lkstat2
       
  4688 +
       
  4689 +#include <errno.h>
       
  4690 +#include <kstat2.h>
       
  4691 +#include <string.h>
       
  4692 +#include <strings.h>
       
  4693 +#include <stdlib.h>
       
  4694 +#include <zone.h>
       
  4695 +#include <zonestat.h>
       
  4696 +#include <sys/param.h>
       
  4697 +
       
  4698 +typedef struct z_iostat {
       
  4699 +	int64_t	nread;
       
  4700 +	int64_t	read_bytes;
       
  4701 +	int64_t nwrite;
       
  4702 +	int64_t write_bytes;
       
  4703 +} z_iostat_t;
       
  4704 +
       
  4705 +typedef struct z_netstat {
       
  4706 +	int64_t	ibytes;
       
  4707 +	int64_t	ipackets;
       
  4708 +	int64_t ierrors;
       
  4709 +	int64_t	idrops;
       
  4710 +	int64_t	obytes;
       
  4711 +	int64_t	opackets;
       
  4712 +	int64_t oerrors;
       
  4713 +	int64_t	odrops;
       
  4714 +} z_netstat_t;
       
  4715 +
       
  4716 +#define KSTAT2_IO_URI	"kstat:/misc/unix/vopstats_zfs/%d"
       
  4717 +z_iostat_t *
       
  4718 +get_io_stats(zoneid_t zoneid) {
       
  4719 +	kstat2_handle_t handle;
       
  4720 +	kstat2_status_t stat;
       
  4721 +	kstat2_map_t    map;
       
  4722 +	kstat2_mapiter_t iter;
       
  4723 +	boolean_t has_next;
       
  4724 +	z_iostat_t *zio = malloc(sizeof(*zio));
       
  4725 +
       
  4726 +	if (zio == NULL) {
       
  4727 +		errno = ENOMEM;
       
  4728 +		return (NULL);
       
  4729 +	}
       
  4730 +	char lookup_uri[sizeof(KSTAT2_IO_URI) + 10]; // 12 extra digits
       
  4731 +
       
  4732 +	(void) snprintf(lookup_uri, sizeof(lookup_uri), KSTAT2_IO_URI, zoneid);
       
  4733 +
       
  4734 +	stat = kstat2_open(&handle, NULL);
       
  4735 +	if (stat != KSTAT2_S_OK) {
       
  4736 +		return (NULL);
       
  4737 +	}
       
  4738 +
       
  4739 +	stat = kstat2_lookup_map(handle, lookup_uri, &map);
       
  4740 +	if (stat != KSTAT2_S_OK) {
       
  4741 +		(void) kstat2_close(&handle);
       
  4742 +		return (NULL);
       
  4743 +	}
       
  4744 +
       
  4745 +	if ((stat = kstat2_mapiter_start(map, KSTAT2_NVK_ALL, &iter)) !=
       
  4746 +	    KSTAT2_S_OK) {
       
  4747 +		(void) kstat2_close(&handle);
       
  4748 +		return (NULL);
       
  4749 +	}
       
  4750 +
       
  4751 +	while (kstat2_mapiter_hasnext(iter, &has_next) == KSTAT2_S_OK &&
       
  4752 +	    has_next) {
       
  4753 +		kstat2_nv_t val;
       
  4754 +
       
  4755 +		if (kstat2_mapiter_next(iter, &val) != KSTAT2_S_OK) {
       
  4756 +			continue;
       
  4757 +		}
       
  4758 +
       
  4759 +		if (!strcmp(val->name, "nread") && (val->type == KSTAT2_NVVT_INT))
       
  4760 +			zio->nread = val->data.integer;
       
  4761 +		else if (!strcmp(val->name, "read_bytes") && (val->type == KSTAT2_NVVT_INT))
       
  4762 +			zio->read_bytes = val->data.integer;
       
  4763 +		else if (!strcmp(val->name, "nwrite") && (val->type == KSTAT2_NVVT_INT))
       
  4764 +			zio->nwrite = val->data.integer;
       
  4765 +		else if (!strcmp(val->name, "write_bytes") && (val->type == KSTAT2_NVVT_INT))
       
  4766 +			zio->write_bytes = val->data.integer;
       
  4767 +	}
       
  4768 +
       
  4769 +	(void) kstat2_close(&handle);
       
  4770 +	return (zio);
       
  4771 +}
       
  4772 +
       
  4773 +void
       
  4774 +io_stats_free(z_iostat_t *p)
       
  4775 +{
       
  4776 +	free(p);
       
  4777 +}
       
  4778 +
       
  4779 +#define KSTAT2_NET_LINK_URI	"kstat:/net/link"
       
  4780 +
       
  4781 +z_netstat_t *
       
  4782 +get_net_stats(const char *linkname, zoneid_t zoneid) {
       
  4783 +	kstat2_handle_t handle;
       
  4784 +	kstat2_status_t stat;
       
  4785 +	kstat2_map_t    map;
       
  4786 +	kstat2_mapiter_t iter;
       
  4787 +	boolean_t has_next;
       
  4788 +	// URI prefix + '/' + max data link name + '/' + zoneid digits + '\0'
       
  4789 +	char lookup_uri[sizeof(KSTAT2_NET_LINK_URI) + MAXLINKNAMELEN + 12];
       
  4790 +	z_netstat_t *zns = calloc(1, sizeof(*zns));
       
  4791 +
       
  4792 +	if (zns == NULL) {
       
  4793 +		errno = ENOMEM;
       
  4794 +		return (NULL);
       
  4795 +	}
       
  4796 +
       
  4797 +	(void) snprintf(lookup_uri, sizeof(lookup_uri), "%s/%s/%d",
       
  4798 +	    KSTAT2_NET_LINK_URI, linkname, zoneid);
       
  4799 +
       
  4800 +	stat = kstat2_open(&handle, NULL);
       
  4801 +	if (stat != KSTAT2_S_OK) {
       
  4802 +		free(zns);
       
  4803 +		return (NULL);
       
  4804 +	}
       
  4805 +
       
  4806 +	stat = kstat2_lookup_map(handle, lookup_uri, &map);
       
  4807 +	if (stat != KSTAT2_S_OK) {
       
  4808 +		(void) kstat2_close(&handle);
       
  4809 +		free(zns);
       
  4810 +		return (NULL);
       
  4811 +	}
       
  4812 +
       
  4813 +	stat = kstat2_mapiter_start(map, KSTAT2_NVK_ALL, &iter);
       
  4814 +	if (stat != KSTAT2_S_OK) {
       
  4815 +		(void) kstat2_close(&handle);
       
  4816 +		free(zns);
       
  4817 +		return (NULL);
       
  4818 +	}
       
  4819 +
       
  4820 +	while (kstat2_mapiter_hasnext(iter, &has_next) == KSTAT2_S_OK &&
       
  4821 +	    has_next) {
       
  4822 +		kstat2_nv_t val;
       
  4823 +
       
  4824 +		if (kstat2_mapiter_next(iter, &val) != KSTAT2_S_OK ||
       
  4825 +		    val->type != KSTAT2_NVVT_INT) {
       
  4826 +			continue;
       
  4827 +		}
       
  4828 +
       
  4829 +		if (strcmp(val->name, "ipackets64") == 0) {
       
  4830 +			zns->ipackets = val->data.integer;
       
  4831 +		} else if (strcmp(val->name, "rbytes64") == 0) {
       
  4832 +			zns->ibytes = val->data.integer;
       
  4833 +		} else if (strcmp(val->name, "ierrors") == 0) {
       
  4834 +			zns->ierrors = val->data.integer;
       
  4835 +		} else if (strcmp(val->name, "dl_idrops") == 0) {
       
  4836 +			zns->idrops = val->data.integer;
       
  4837 +		} else if (strcmp(val->name, "opackets64") == 0) {
       
  4838 +			zns->opackets = val->data.integer;
       
  4839 +		} else if (strcmp(val->name, "obytes64") == 0) {
       
  4840 +			zns->obytes = val->data.integer;
       
  4841 +		} else if (strcmp(val->name, "oerrors") == 0) {
       
  4842 +			zns->oerrors = val->data.integer;
       
  4843 +		} else if (strcmp(val->name, "dl_odrops") == 0) {
       
  4844 +			zns->odrops = val->data.integer;
       
  4845 +		}
       
  4846 +	}
       
  4847 +
       
  4848 +	(void) kstat2_close(&handle);
       
  4849 +	return (zns);
       
  4850 +}
       
  4851 +
       
  4852 +void
       
  4853 +net_stats_free(z_netstat_t *p)
       
  4854 +{
       
  4855 +	free(p);
       
  4856 +}
       
  4857 +
       
  4858 +uint64_t
       
  4859 +getSystemCPUUsage(zs_usage_t usage)
       
  4860 +{
       
  4861 +	timestruc_t cpu;
       
  4862 +
       
  4863 +	zs_resource_total_time(usage, ZS_RESOURCE_CPU, &cpu);
       
  4864 +	return (1000000000ULL * cpu.tv_sec + cpu.tv_nsec);
       
  4865 +}
       
  4866 +
       
  4867 +char *
       
  4868 +get_zone_name(zs_zone_t z)
       
  4869 +{
       
  4870 +	zs_property_t prop;
       
  4871 +
       
  4872 +	prop = zs_zone_property(z, ZS_ZONE_PROP_NAME);
       
  4873 +	if (prop == NULL)
       
  4874 +		return (NULL);
       
  4875 +
       
  4876 +	return (zs_property_string(prop));
       
  4877 +}
       
  4878 +
       
  4879 +zs_usage_t
       
  4880 +get_usage(zs_ctl_t zsctl)
       
  4881 +{
       
  4882 +	zs_usage_t zsu;
       
  4883 +
       
  4884 +        while ((zsu = zs_usage_read(zsctl)) == NULL &&
       
  4885 +	    (errno == EINTR || errno == EAGAIN))
       
  4886 +		;
       
  4887 +
       
  4888 +	return (zsu);
       
  4889 +}
       
  4890 +
       
  4891 +uint64_t
       
  4892 +getCpuUsage(zs_zone_t z)
       
  4893 +{
       
  4894 +	timestruc_t cpu;
       
  4895 +
       
  4896 +	zs_resource_used_zone_time(z, ZS_RESOURCE_CPU, &cpu);
       
  4897 +	return ((uint64_t)(cpu.tv_sec * 1000000000ULL + cpu.tv_nsec));
       
  4898 +}
       
  4899 +
       
  4900 +*/
       
  4901 +import "C"
       
  4902 +
       
  4903 +func getZoneName(z C.zs_zone_t) string {
       
  4904 +	return C.GoString(C.get_zone_name(z))
       
  4905 +}
  4648 +
  4906 +
  4649 +// XXX solaris: TODO Copied from Windows, refactor accordingly for collector actions.
  4907 +// XXX solaris: TODO Copied from Windows, refactor accordingly for collector actions.
  4650 +// XXX: Copied statsCollector struct and interface from unix
  4908 +// XXX: Copied statsCollector struct and interface from unix
  4651 +
  4909 +
  4652 +type statsSupervisor interface {
  4910 +type statsSupervisor interface {
  4653 +	// GetContainerStats collects all the stats related to a container
  4911 +	// GetZoneStats collects all the stats related to a zone container
  4654 +	GetContainerStats(container *container.Container) (*execdriver.ResourceStats, error)
  4912 +	getZoneStats(z C.zs_zone_t, zoneid uint64, container *container.Container) (*execdriver.ResourceStats, error)
       
  4913 +}
       
  4914 +
       
  4915 +type zonePublisher struct {
       
  4916 +	publisher *pubsub.Publisher
       
  4917 +	zoneid    uint64
  4655 +}
  4918 +}
  4656 +
  4919 +
  4657 +// newStatsCollector returns a new statsCollector for collection stats
  4920 +// newStatsCollector returns a new statsCollector for collection stats
  4658 +// for a registered container at the specified interval. The collector allows
  4921 +// for a registered container at the specified interval. The collector allows
  4659 +// non-running containers to be added and will start processing stats when
  4922 +// non-running containers to be added and will start processing stats when
  4660 +// they are started.
  4923 +// they are started.
  4661 +func (daemon *Daemon) newStatsCollector(interval time.Duration) *statsCollector {
  4924 +func (daemon *Daemon) newStatsCollector(interval time.Duration) *statsCollector {
  4662 +	s := &statsCollector{
  4925 +	s := &statsCollector{
  4663 +		interval:            interval,
  4926 +		interval:   interval,
  4664 +		supervisor:          daemon,
  4927 +		supervisor: daemon,
  4665 +		publishers:          make(map[*container.Container]*pubsub.Publisher),
  4928 +		publishers: make(map[*container.Container]*zonePublisher),
  4666 +		bufReader:           bufio.NewReaderSize(nil, 128),
  4929 +		bufReader:  bufio.NewReaderSize(nil, 128),
  4667 +	}
  4930 +	}
  4668 +	go s.run()
  4931 +	go s.run()
  4669 +
  4932 +
  4670 +	return s
  4933 +	return s
  4671 +}
  4934 +}
  4672 +
  4935 +
  4673 +// statsCollector manages and provides container resource stats
  4936 +// statsCollector manages and provides container resource stats
  4674 +type statsCollector struct {
  4937 +type statsCollector struct {
  4675 +	m                   sync.Mutex
  4938 +	m          sync.Mutex
  4676 +	supervisor          statsSupervisor
  4939 +	supervisor statsSupervisor
  4677 +	interval            time.Duration
  4940 +	interval   time.Duration
  4678 +	publishers          map[*container.Container]*pubsub.Publisher
  4941 +	publishers map[*container.Container]*zonePublisher
  4679 +	bufReader           *bufio.Reader
  4942 +	bufReader  *bufio.Reader
  4680 +}
  4943 +}
  4681 +
  4944 +
  4682 +// collect registers the container with the collector and adds it to
  4945 +// collect registers the container with the collector and adds it to
       
  4946 +
  4683 +// the event loop for collection on the specified interval returning
  4947 +// the event loop for collection on the specified interval returning
  4684 +// a channel for the subscriber to receive on.
  4948 +// a channel for the subscriber to receive on.
  4685 +func (s *statsCollector) collect(c *container.Container) chan interface{} {
  4949 +func (s *statsCollector) collect(c *container.Container) chan interface{} {
  4686 +	s.m.Lock()
  4950 +	s.m.Lock()
  4687 +	defer s.m.Unlock()
  4951 +	defer s.m.Unlock()
  4688 +	publisher, exists := s.publishers[c]
  4952 +	zpub, exists := s.publishers[c]
  4689 +	if !exists {
  4953 +	if !exists {
  4690 +		publisher = pubsub.NewPublisher(100*time.Millisecond, 1024)
  4954 +		zid, err := C.getzoneidbyname(C.CString(strings.TrimPrefix(c.Name, "/")))
  4691 +		s.publishers[c] = publisher
  4955 +		if err != nil {
  4692 +	}
  4956 +			// Too early to get zoneid, flag and defer
  4693 +	return publisher.Subscribe()
  4957 +			zid = 0
       
  4958 +		}
       
  4959 +		zpub = &zonePublisher{
       
  4960 +			publisher: pubsub.NewPublisher(100*time.Millisecond, 1024),
       
  4961 +			zoneid:    uint64(zid),
       
  4962 +		}
       
  4963 +		s.publishers[c] = zpub
       
  4964 +	}
       
  4965 +	return zpub.publisher.Subscribe()
  4694 +}
  4966 +}
  4695 +
  4967 +
  4696 +// stopCollection closes the channels for all subscribers and removes
  4968 +// stopCollection closes the channels for all subscribers and removes
  4697 +// the container from metrics collection.
  4969 +// the container from metrics collection.
  4698 +func (s *statsCollector) stopCollection(c *container.Container) {
  4970 +func (s *statsCollector) stopCollection(c *container.Container) {
  4699 +	s.m.Lock()
  4971 +	s.m.Lock()
  4700 +	defer s.m.Unlock()
  4972 +	defer s.m.Unlock()
  4701 +	if publisher, exists := s.publishers[c]; exists {
  4973 +	if zpub, exists := s.publishers[c]; exists {
  4702 +		publisher.Close()
  4974 +		zpub.publisher.Close()
  4703 +		delete(s.publishers, c)
  4975 +		delete(s.publishers, c)
  4704 +	}
  4976 +	}
  4705 +}
  4977 +}
  4706 +
  4978 +
  4707 +// unsubscribe removes a specific subscriber from receiving updates for a container's stats.
  4979 +// unsubscribe removes a specific subscriber from receiving updates for a container's stats.
  4708 +func (s *statsCollector) unsubscribe(c *container.Container, ch chan interface{}) {
  4980 +func (s *statsCollector) unsubscribe(c *container.Container, ch chan interface{}) {
  4709 +	s.m.Lock()
  4981 +	s.m.Lock()
  4710 +	defer s.m.Unlock()
  4982 +	defer s.m.Unlock()
  4711 +	publisher := s.publishers[c]
  4983 +	zpub, exists := s.publishers[c]
  4712 +	if publisher != nil {
  4984 +	if exists {
  4713 +		publisher.Evict(ch)
  4985 +		zpub.publisher.Evict(ch)
  4714 +		if publisher.Len() == 0 {
  4986 +		if zpub.publisher.Len() == 0 {
  4715 +			delete(s.publishers, c)
  4987 +			delete(s.publishers, c)
  4716 +		}
  4988 +		}
  4717 +	}
  4989 +	}
  4718 +}
  4990 +}
  4719 +
  4991 +
  4720 +// XXX copied from unix
  4992 +// XXX copied from unix
  4721 +func (s *statsCollector) run() {
  4993 +func (s *statsCollector) run() {
  4722 +	type publishersPair struct {
  4994 +	type publishersPair struct {
  4723 +		container *container.Container
  4995 +		container *container.Container
  4724 +		publisher *pubsub.Publisher
  4996 +		zpub      *zonePublisher
  4725 +	}
  4997 +	}
       
  4998 +	memoryInfo, err := system.ReadMemInfo()
       
  4999 +	machineMemory := memoryInfo.MemTotal
       
  5000 +
  4726 +	// we cannot determine the capacity here.
  5001 +	// we cannot determine the capacity here.
  4727 +	// it will grow enough in first iteration
  5002 +	// it will grow enough in first iteration
  4728 +	var pairs []publishersPair
  5003 +	pairs := make(map[string]publishersPair)
  4729 +
  5004 +
       
  5005 +	zsctl := C.zs_open()
       
  5006 +	usage_last, err := C.get_usage(zsctl)
       
  5007 +	if usage_last == nil {
       
  5008 +		logrus.Error("Failed to get usage: ", err)
       
  5009 +		C.zs_close(zsctl)
       
  5010 +		return
       
  5011 +	}
  4730 +	for range time.Tick(s.interval) {
  5012 +	for range time.Tick(s.interval) {
  4731 +		// it does not make sense in the first iteration,
  5013 +		var usage_diff C.zs_usage_t
  4732 +		// but saves allocations in further iterations
       
  4733 +		pairs = pairs[:0]
       
  4734 +
  5014 +
  4735 +		s.m.Lock()
  5015 +		s.m.Lock()
  4736 +		for container, publisher := range s.publishers {
  5016 +		for container, zpub := range s.publishers {
  4737 +			// copy pointers here to release the lock ASAP
  5017 +			// copy pointers here to release the lock ASAP
  4738 +			pairs = append(pairs, publishersPair{container, publisher})
  5018 +			pairs[strings.TrimPrefix(container.Name, "/")] = publishersPair{container, zpub}
  4739 +		}
  5019 +		}
  4740 +		s.m.Unlock()
  5020 +		s.m.Unlock()
  4741 +		if len(pairs) == 0 {
  5021 +		if len(pairs) == 0 {
  4742 +			continue
  5022 +			continue
  4743 +		}
  5023 +		}
  4744 +
  5024 +
  4745 +		// XXX: need to implement getSystmCPUUsage()
  5025 +		usage, err := C.get_usage(zsctl)
  4746 +		// XXX: ? whole system usage or how much of container allocated resources used?
  5026 +		if usage != nil {
  4747 +		// XXX: The output of docker stats seem broken as the CPU % column show changes
  5027 +			usage_diff = C.zs_usage_diff(usage_last, usage)
  4748 +		//      from previous reading, instead of actual usage.
  5028 +		}
  4749 +		//      Thats in api/client/stats.go calculateCPUUsage()
  5029 +		if usage == nil || usage_diff == nil {
  4750 +		//
  5030 +			logrus.Error("Failed to get usage: ", err)
  4751 +		systemUsage, err := s.getSystemCPUUsage()
  5031 +			// empty the map
  4752 +		if err != nil {
  5032 +			for name, _ := range pairs {
  4753 +			logrus.Errorf("collecting system cpu usage: %v", err)
  5033 +				delete(pairs, name)
       
  5034 +			}
  4754 +			continue
  5035 +			continue
  4755 +		}
  5036 +		}
  4756 +
  5037 +		systemUsage := uint64(C.getSystemCPUUsage(usage_diff))
  4757 +		for _, pair := range pairs {
  5038 +
  4758 +			stats, err := s.supervisor.GetContainerStats(pair.container)
  5039 +		var z C.zs_zone_t
       
  5040 +		z = nil
       
  5041 +		for z = C.zs_zone_walk(usage_diff, z); z != nil; z = C.zs_zone_walk(usage_diff, z) {
       
  5042 +			name := getZoneName(z)
       
  5043 +			pair, ok := pairs[name]
       
  5044 +			if ok == false {
       
  5045 +				continue
       
  5046 +			}
       
  5047 +			zoneid := pair.zpub.zoneid
       
  5048 +			if zoneid == 0 {
       
  5049 +				zid, err := C.getzoneidbyname(C.CString(name))
       
  5050 +				if err != nil {
       
  5051 +					// zoneid is not available yet
       
  5052 +					delete(pairs, name)
       
  5053 +					continue
       
  5054 +				}
       
  5055 +				pair.zpub.zoneid = uint64(zid)
       
  5056 +				zoneid = pair.zpub.zoneid
       
  5057 +			}
       
  5058 +			stats, err := s.supervisor.getZoneStats(z, zoneid, pair.container)
  4759 +			if err != nil {
  5059 +			if err != nil {
  4760 +				if err != execdriver.ErrNotRunning {
  5060 +				if err != execdriver.ErrNotRunning {
  4761 +					logrus.Errorf("collecting stats for %s: %v", pair.container.ID, err)
  5061 +					logrus.Errorf("collecting stats for %s: %v", pair.container.ID, err)
  4762 +				}
  5062 +				}
       
  5063 +				delete(pairs, name)
  4763 +				continue
  5064 +				continue
  4764 +			}
  5065 +			}
       
  5066 +			if stats.MemoryLimit == 0 {
       
  5067 +				stats.MemoryLimit = machineMemory
       
  5068 +			}
  4765 +			stats.SystemUsage = systemUsage
  5069 +			stats.SystemUsage = systemUsage
  4766 +
  5070 +
  4767 +			pair.publisher.Publish(stats)
  5071 +			pair.zpub.publisher.Publish(stats)
  4768 +		}
  5072 +			delete(pairs, name)
  4769 +	}
  5073 +		}
  4770 +}
  5074 +		C.zs_usage_free(usage_last)
  4771 +
  5075 +		C.zs_usage_free(usage_diff)
  4772 +// XXX needs to be implemented.
  5076 +		usage_last = usage
  4773 +func (s *statsCollector) getSystemCPUUsage() (uint64, error) {
  5077 +	}
  4774 +	return 0, nil
  5078 +	C.zs_close(zsctl)
       
  5079 +}
       
  5080 +
       
  5081 +func getIOStats(zoneid uint64) (*zones.BlkioStats, error) {
       
  5082 +	iostats, err := C.get_io_stats(C.zoneid_t(zoneid))
       
  5083 +	if iostats == nil {
       
  5084 +		return nil, err
       
  5085 +	}
       
  5086 +
       
  5087 +	ioBytes := []zones.BlkioStatEntry{
       
  5088 +		{
       
  5089 +			Op:    "write",
       
  5090 +			Value: uint64(iostats.write_bytes),
       
  5091 +		},
       
  5092 +		{
       
  5093 +			Op:    "read",
       
  5094 +			Value: uint64(iostats.read_bytes),
       
  5095 +		},
       
  5096 +	}
       
  5097 +	ioCount := []zones.BlkioStatEntry{
       
  5098 +		{
       
  5099 +			Op:    "write",
       
  5100 +			Value: uint64(iostats.nwrite),
       
  5101 +		},
       
  5102 +		{
       
  5103 +			Op:    "read",
       
  5104 +			Value: uint64(iostats.nread),
       
  5105 +		},
       
  5106 +	}
       
  5107 +	C.io_stats_free(iostats)
       
  5108 +	ioStats := zones.BlkioStats{
       
  5109 +		IoServiceBytesRecursive: ioBytes,
       
  5110 +		IoServicedRecursive:     ioCount,
       
  5111 +	}
       
  5112 +
       
  5113 +	return &ioStats, nil
       
  5114 +}
       
  5115 +
       
  5116 +func getNetStats(zoneid uint64) ([]*libcontainer.NetworkInterface, error) {
       
  5117 +	m := make(map[string]*types.InterfaceStatistics)
       
  5118 +	s := types.InterfaceStatistics{}
       
  5119 +
       
  5120 +	// XXX: Should get an array with all data links in the container from its
       
  5121 +	// configuration. For now, net0 suffices. If multi-homed containers are allowed
       
  5122 +	// in the future, this will be required to have accuarte network statistics.
       
  5123 +	datalink := []string{"net0"}
       
  5124 +	for _, linkname := range datalink {
       
  5125 +		ns, err := C.get_net_stats(C.CString(linkname), C.zoneid_t(zoneid))
       
  5126 +		if ns == nil {
       
  5127 +			return nil, err
       
  5128 +		}
       
  5129 +
       
  5130 +		s.RxBytes = uint64(ns.ibytes)
       
  5131 +		s.RxPackets = uint64(ns.ipackets)
       
  5132 +		s.RxErrors = uint64(ns.ierrors)
       
  5133 +		s.RxDropped = uint64(ns.idrops)
       
  5134 +
       
  5135 +		s.TxBytes = uint64(ns.obytes)
       
  5136 +		s.TxPackets = uint64(ns.opackets)
       
  5137 +		s.TxErrors = uint64(ns.oerrors)
       
  5138 +		s.TxDropped = uint64(ns.odrops)
       
  5139 +		m[linkname] = &s
       
  5140 +		C.net_stats_free(ns)
       
  5141 +
       
  5142 +	}
       
  5143 +	// Convert libnetwork nw stats into libcontainer nw stats
       
  5144 +	var list []*libcontainer.NetworkInterface
       
  5145 +	for ifName, ifStats := range m {
       
  5146 +		list = append(list, convertLnNetworkStats(ifName, ifStats))
       
  5147 +	}
       
  5148 +
       
  5149 +	return list, nil
       
  5150 +}
       
  5151 +
       
  5152 +func getContainerStats(z C.zs_zone_t, zoneid uint64) (*libcontainer.Stats, error) {
       
  5153 +	cstats := &libcontainer.Stats{}
       
  5154 +	zstats := zones.Stats{}
       
  5155 +	iostats, err := getIOStats(zoneid)
       
  5156 +	if iostats == nil {
       
  5157 +		return nil, err
       
  5158 +	}
       
  5159 +
       
  5160 +	// For now we only retrieve what's needed by docker stats
       
  5161 +	cpuUsage := uint64(C.getCpuUsage(z))
       
  5162 +	memUsage := uint64(C.zs_resource_used_zone_uint64(z, C.ZS_RESOURCE_RAM_RSS))
       
  5163 +
       
  5164 +	// XXX: Need to use kstat2 for CPU usage
       
  5165 +	// CPU% only seems to work if all these fields are populated.
       
  5166 +	// Once kstat2 are used, these statistics will be filled accurately.
       
  5167 +	zstats.CpuStats.CpuUsage.PercpuUsage = []uint64{cpuUsage}
       
  5168 +	zstats.CpuStats.CpuUsage.TotalUsage = uint64(cpuUsage)
       
  5169 +	zstats.CpuStats.CpuUsage.UsageInKernelmode = uint64(cpuUsage)
       
  5170 +	zstats.CpuStats.CpuUsage.UsageInUsermode = uint64(cpuUsage)
       
  5171 +	zstats.MemoryStats.Usage.Usage = memUsage
       
  5172 +	zstats.BlkioStats = *iostats
       
  5173 +
       
  5174 +	cstats.Stats = &zstats
       
  5175 +
       
  5176 +	return cstats, nil
       
  5177 +}
       
  5178 +
       
  5179 +func (daemon *Daemon) getZoneStats(z C.zs_zone_t, zoneid uint64, container *container.Container) (*execdriver.ResourceStats, error) {
       
  5180 +
       
  5181 +	zstats, err := getContainerStats(z, zoneid)
       
  5182 +	if zstats == nil {
       
  5183 +		return nil, err
       
  5184 +	}
       
  5185 +	netstats, err := getNetStats(zoneid)
       
  5186 +	if netstats == nil {
       
  5187 +		return nil, err
       
  5188 +	}
       
  5189 +
       
  5190 +	memoryLimit := int64(C.zs_zone_limit_uint64(z, C.ZS_LIMIT_RAM_RSS))
       
  5191 +
       
  5192 +	if memoryLimit == C.ZS_LIMIT_NONE {
       
  5193 +		memoryLimit = 0
       
  5194 +	}
       
  5195 +
       
  5196 +	zstats.Interfaces = netstats
       
  5197 +	stats := &execdriver.ResourceStats{
       
  5198 +		Read:        time.Now(),
       
  5199 +		MemoryLimit: memoryLimit,
       
  5200 +		Stats:       zstats,
       
  5201 +	}
       
  5202 +
       
  5203 +	return stats, nil
  4775 +}
  5204 +}
  4776 diff --git a/daemon/stats_collector_unix.go b/daemon/stats_collector_unix.go
  5205 diff --git a/daemon/stats_collector_unix.go b/daemon/stats_collector_unix.go
  4777 index 2fd368c..ec408c6 100644
  5206 index 2fd368c..ec408c6 100644
  4778 --- a/daemon/stats_collector_unix.go
  5207 --- a/daemon/stats_collector_unix.go
  4779 +++ b/daemon/stats_collector_unix.go
  5208 +++ b/daemon/stats_collector_unix.go
  4783  
  5212  
  4784  package daemon
  5213  package daemon
  4785  
  5214  
  4786 diff --git a/daemon/stats_solaris.go b/daemon/stats_solaris.go
  5215 diff --git a/daemon/stats_solaris.go b/daemon/stats_solaris.go
  4787 new file mode 100644
  5216 new file mode 100644
  4788 index 0000000..1d99f1f
  5217 index 0000000..a1230c6
  4789 --- /dev/null
  5218 --- /dev/null
  4790 +++ b/daemon/stats_solaris.go
  5219 +++ b/daemon/stats_solaris.go
  4791 @@ -0,0 +1,82 @@
  5220 @@ -0,0 +1,84 @@
  4792 +package daemon
  5221 +package daemon
  4793 +
  5222 +
  4794 +import (
  5223 +import (
  4795 +	"github.com/docker/engine-api/types"
  5224 +	"github.com/docker/engine-api/types"
  4796 +	"github.com/opencontainers/runc/libcontainer"
  5225 +	"github.com/opencontainers/runc/libcontainer"
  4820 +				TxDropped: iface.TxDropped,
  5249 +				TxDropped: iface.TxDropped,
  4821 +			}
  5250 +			}
  4822 +		}
  5251 +		}
  4823 +	}
  5252 +	}
  4824 +
  5253 +
  4825 +	if cs != nil {
  5254 +	if cs == nil {
  4826 +		s.BlkioStats = types.BlkioStats{
  5255 +		return s
  4827 +			IoServiceBytesRecursive: copyBlkioEntry(cs.BlkioStats.IoServiceBytesRecursive),
  5256 +	}
  4828 +			IoServicedRecursive:     copyBlkioEntry(cs.BlkioStats.IoServicedRecursive),
  5257 +
  4829 +			IoQueuedRecursive:       copyBlkioEntry(cs.BlkioStats.IoQueuedRecursive),
  5258 +	s.BlkioStats = types.BlkioStats{
  4830 +			IoServiceTimeRecursive:  copyBlkioEntry(cs.BlkioStats.IoServiceTimeRecursive),
  5259 +		IoServiceBytesRecursive: copyBlkioEntry(cs.BlkioStats.IoServiceBytesRecursive),
  4831 +			IoWaitTimeRecursive:     copyBlkioEntry(cs.BlkioStats.IoWaitTimeRecursive),
  5260 +		IoServicedRecursive:     copyBlkioEntry(cs.BlkioStats.IoServicedRecursive),
  4832 +			IoMergedRecursive:       copyBlkioEntry(cs.BlkioStats.IoMergedRecursive),
  5261 +		IoQueuedRecursive:       copyBlkioEntry(cs.BlkioStats.IoQueuedRecursive),
  4833 +			IoTimeRecursive:         copyBlkioEntry(cs.BlkioStats.IoTimeRecursive),
  5262 +		IoServiceTimeRecursive:  copyBlkioEntry(cs.BlkioStats.IoServiceTimeRecursive),
  4834 +			SectorsRecursive:        copyBlkioEntry(cs.BlkioStats.SectorsRecursive),
  5263 +		IoWaitTimeRecursive:     copyBlkioEntry(cs.BlkioStats.IoWaitTimeRecursive),
  4835 +		}
  5264 +		IoMergedRecursive:       copyBlkioEntry(cs.BlkioStats.IoMergedRecursive),
  4836 +		cpu := cs.CpuStats
  5265 +		IoTimeRecursive:         copyBlkioEntry(cs.BlkioStats.IoTimeRecursive),
  4837 +		s.CPUStats = types.CPUStats{
  5266 +		SectorsRecursive:        copyBlkioEntry(cs.BlkioStats.SectorsRecursive),
  4838 +			CPUUsage: types.CPUUsage{
  5267 +	}
  4839 +				TotalUsage:        cpu.CpuUsage.TotalUsage,
  5268 +	cpu := cs.CpuStats
  4840 +				PercpuUsage:       cpu.CpuUsage.PercpuUsage,
  5269 +	s.CPUStats = types.CPUStats{
  4841 +				UsageInKernelmode: cpu.CpuUsage.UsageInKernelmode,
  5270 +		CPUUsage: types.CPUUsage{
  4842 +				UsageInUsermode:   cpu.CpuUsage.UsageInUsermode,
  5271 +			TotalUsage:        cpu.CpuUsage.TotalUsage,
  4843 +			},
  5272 +			PercpuUsage:       cpu.CpuUsage.PercpuUsage,
  4844 +			ThrottlingData: types.ThrottlingData{
  5273 +			UsageInKernelmode: cpu.CpuUsage.UsageInKernelmode,
  4845 +				Periods:          cpu.ThrottlingData.Periods,
  5274 +			UsageInUsermode:   cpu.CpuUsage.UsageInUsermode,
  4846 +				ThrottledPeriods: cpu.ThrottlingData.ThrottledPeriods,
  5275 +		},
  4847 +				ThrottledTime:    cpu.ThrottlingData.ThrottledTime,
  5276 +		ThrottlingData: types.ThrottlingData{
  4848 +			},
  5277 +			Periods:          cpu.ThrottlingData.Periods,
  4849 +		}
  5278 +			ThrottledPeriods: cpu.ThrottlingData.ThrottledPeriods,
  4850 +		mem := cs.MemoryStats
  5279 +			ThrottledTime:    cpu.ThrottlingData.ThrottledTime,
  4851 +		s.MemoryStats = types.MemoryStats{
  5280 +		},
  4852 +			Usage:    mem.Usage.Usage,
  5281 +	}
  4853 +			MaxUsage: mem.Usage.MaxUsage,
  5282 +	mem := cs.MemoryStats
  4854 +			Stats:    mem.Stats,
  5283 +	s.MemoryStats = types.MemoryStats{
  4855 +			Failcnt:  mem.Usage.Failcnt,
  5284 +		Usage:    mem.Usage.Usage,
  4856 +		}
  5285 +		MaxUsage: mem.Usage.MaxUsage,
       
  5286 +		Stats:    mem.Stats,
       
  5287 +		Failcnt:  mem.Usage.Failcnt,
  4857 +	}
  5288 +	}
  4858 +
  5289 +
  4859 +	return s
  5290 +	return s
  4860 +}
  5291 +}
  4861 +
  5292 +
  8297 +	}
  8728 +	}
  8298 +	return strconv.FormatInt(int64(nlgrps), 16)
  8729 +	return strconv.FormatInt(int64(nlgrps), 16)
  8299 +}
  8730 +}
  8300 diff --git a/pkg/system/meminfo_solaris.go b/pkg/system/meminfo_solaris.go
  8731 diff --git a/pkg/system/meminfo_solaris.go b/pkg/system/meminfo_solaris.go
  8301 new file mode 100644
  8732 new file mode 100644
  8302 index 0000000..f8c0af3
  8733 index 0000000..bad227f
  8303 --- /dev/null
  8734 --- /dev/null
  8304 +++ b/pkg/system/meminfo_solaris.go
  8735 +++ b/pkg/system/meminfo_solaris.go
  8305 @@ -0,0 +1,133 @@
  8736 @@ -0,0 +1,127 @@
  8306 +// +build solaris,cgo
  8737 +// +build solaris,cgo
  8307 +
  8738 +
  8308 +package system
  8739 +package system
  8309 +
  8740 +
  8310 +import (
  8741 +import (
  8376 +	pagesize := C.sysconf(C._SC_PAGESIZE)
  8807 +	pagesize := C.sysconf(C._SC_PAGESIZE)
  8377 +	npages := C.sysconf(C._SC_PHYS_PAGES)
  8808 +	npages := C.sysconf(C._SC_PHYS_PAGES)
  8378 +	return int64(pagesize * npages)
  8809 +	return int64(pagesize * npages)
  8379 +}
  8810 +}
  8380 +
  8811 +
  8381 +func getFreeMem() int64 {
       
  8382 +	pagesize := C.sysconf(C._SC_PAGESIZE)
       
  8383 +	npages := C.sysconf(C._SC_AVPHYS_PAGES)
       
  8384 +	return int64(pagesize * npages)
       
  8385 +}
       
  8386 +
       
  8387 +// ReadMemInfo retrieves memory statistics of the host system and returns a
  8812 +// ReadMemInfo retrieves memory statistics of the host system and returns a
  8388 +//  MemInfo type.
  8813 +//  MemInfo type.
  8389 +func ReadMemInfo() (*MemInfo, error) {
  8814 +func ReadMemInfo() (*MemInfo, error) {
  8390 +
  8815 +
  8391 +	ppKernel := C.getPpKernel()
  8816 +	ppKernel := C.getPpKernel()
  8392 +	MemTotal := getTotalMem()
  8817 +	MemTotal := getTotalMem()
  8393 +	MemFree := getFreeMem()
  8818 +	MemFree := MemTotal - int64(ppKernel)
  8394 +	SwapTotal, SwapFree, err := getSysSwap()
  8819 +	SwapTotal, SwapFree, err := getSysSwap()
  8395 +
  8820 +
  8396 +	if ppKernel < 0 || MemTotal < 0 || MemFree < 0 || SwapTotal < 0 ||
  8821 +	if ppKernel < 0 || MemTotal < 0 || MemFree < 0 || SwapTotal < 0 ||
  8397 +		SwapFree < 0 {
  8822 +		SwapFree < 0 {
  8398 +		return nil, fmt.Errorf("Error getting system memory info %v\n", err)
  8823 +		return nil, fmt.Errorf("Error getting system memory info %v\n", err)
  8399 +	}
  8824 +	}
  8400 +
  8825 +
  8401 +	meminfo := &MemInfo{}
  8826 +	meminfo := &MemInfo{}
  8402 +	// Total memory is total physical memory less than memory locked by kernel
  8827 +	// Total memory is total physical memory less than memory locked by kernel
  8403 +	meminfo.MemTotal = MemTotal - int64(ppKernel)
  8828 +	meminfo.MemTotal = MemTotal
  8404 +	meminfo.MemFree = MemFree
  8829 +	meminfo.MemFree = MemFree
  8405 +	meminfo.SwapTotal = SwapTotal
  8830 +	meminfo.SwapTotal = SwapTotal
  8406 +	meminfo.SwapFree = SwapFree
  8831 +	meminfo.SwapFree = SwapFree
  8407 +
  8832 +
  8408 +	return meminfo, nil
  8833 +	return meminfo, nil
  8954  
  9379  
  8955  	// Contains container's resources (cgroups, ulimits)
  9380  	// Contains container's resources (cgroups, ulimits)
  8956  	Resources
  9381  	Resources
  8957 +	LimitPriv string // Comma separated list of privileges to limit container to
  9382 +	LimitPriv string // Comma separated list of privileges to limit container to
  8958  }
  9383  }
       
  9384 diff --git a/vendor/src/github.com/docker/engine-api/types/types.go b/vendor/src/github.com/docker/engine-api/types/types.go
       
  9385 index 64c9981..d42395e 100644
       
  9386 --- a/vendor/src/github.com/docker/engine-api/types/types.go
       
  9387 +++ b/vendor/src/github.com/docker/engine-api/types/types.go
       
  9388 @@ -178,13 +178,11 @@ type ContainerProcessList struct {
       
  9389  type Version struct {
       
  9390  	Version       string
       
  9391  	APIVersion    string `json:"ApiVersion"`
       
  9392 -	GitCommit     string
       
  9393  	GoVersion     string
       
  9394  	Os            string
       
  9395  	Arch          string
       
  9396  	KernelVersion string `json:",omitempty"`
       
  9397  	Experimental  bool   `json:",omitempty"`
       
  9398 -	BuildTime     string `json:",omitempty"`
       
  9399  }
       
  9400  
       
  9401  // Info contains response of Remote API:
  8959 diff --git a/vendor/src/github.com/docker/go-connections/sockets/unix_socket.go b/vendor/src/github.com/docker/go-connections/sockets/unix_socket.go
  9402 diff --git a/vendor/src/github.com/docker/go-connections/sockets/unix_socket.go b/vendor/src/github.com/docker/go-connections/sockets/unix_socket.go
  8960 index c10aced..d162734 100644
  9403 index c10aced..d162734 100644
  8961 --- a/vendor/src/github.com/docker/go-connections/sockets/unix_socket.go
  9404 --- a/vendor/src/github.com/docker/go-connections/sockets/unix_socket.go
  8962 +++ b/vendor/src/github.com/docker/go-connections/sockets/unix_socket.go
  9405 +++ b/vendor/src/github.com/docker/go-connections/sockets/unix_socket.go
  8963 @@ -1,4 +1,4 @@
  9406 @@ -1,4 +1,4 @@
  8979 +func (c *controller) createGWNetwork() (Network, error) {
  9422 +func (c *controller) createGWNetwork() (Network, error) {
  8980 +	return nil, types.NotImplementedErrorf("default gateway functionality is not implemented in solaris")
  9423 +	return nil, types.NotImplementedErrorf("default gateway functionality is not implemented in solaris")
  8981 +}
  9424 +}
  8982 diff --git a/vendor/src/github.com/docker/libnetwork/drivers/solaris/bridge/bridge.go b/vendor/src/github.com/docker/libnetwork/drivers/solaris/bridge/bridge.go
  9425 diff --git a/vendor/src/github.com/docker/libnetwork/drivers/solaris/bridge/bridge.go b/vendor/src/github.com/docker/libnetwork/drivers/solaris/bridge/bridge.go
  8983 new file mode 100644
  9426 new file mode 100644
  8984 index 0000000..960f8ea
  9427 index 0000000..12c8b69
  8985 --- /dev/null
  9428 --- /dev/null
  8986 +++ b/vendor/src/github.com/docker/libnetwork/drivers/solaris/bridge/bridge.go
  9429 +++ b/vendor/src/github.com/docker/libnetwork/drivers/solaris/bridge/bridge.go
  8987 @@ -0,0 +1,1062 @@
  9430 @@ -0,0 +1,1076 @@
  8988 +package bridge
  9431 +package bridge
  8989 +
  9432 +
  8990 +import (
  9433 +import (
  8991 +	"bufio"
  9434 +	"bufio"
  8992 +	"errors"
  9435 +	"errors"
  9416 +
  9859 +
  9417 +	fmt.Println("Creating bridge network:", config.ID[:12],
  9860 +	fmt.Println("Creating bridge network:", config.ID[:12],
  9418 +		config.BridgeName, config.AddressIPv4)
  9861 +		config.BridgeName, config.AddressIPv4)
  9419 +
  9862 +
  9420 +	networkList := d.getNetworks()
  9863 +	networkList := d.getNetworks()
  9421 +	for _, nw := range networkList {
  9864 +	for i, nw := range networkList {
  9422 +		nw.Lock()
  9865 +		nw.Lock()
  9423 +		nwConfig := nw.config
  9866 +		nwConfig := nw.config
  9424 +		nw.Unlock()
  9867 +		nw.Unlock()
  9425 +		if err := nwConfig.Conflicts(config); err != nil {
  9868 +		if err := nwConfig.Conflicts(config); err != nil {
  9426 +			return types.ForbiddenErrorf(
  9869 +			if config.DefaultBridge {
  9427 +				"cannot create network %s (%s): "+
  9870 +				// We encountered and identified a stale default network
  9428 +					"conflicts with network %s (%s): %s",
  9871 +				// We must delete it as libnetwork is the source of thruth
  9429 +				nwConfig.BridgeName, config.ID, nw.id,
  9872 +				// The default network being created must be the only one
  9430 +				nw.config.BridgeName, err.Error())
  9873 +				// This can happen only from docker 1.12 on ward
       
  9874 +				logrus.Infof("Removing stale default bridge network %s (%s)", nwConfig.ID, nwConfig.BridgeName)
       
  9875 +				if err := d.DeleteNetwork(nwConfig.ID); err != nil {
       
  9876 +					logrus.Warnf("Failed to remove stale default network: %s (%s): %v. Will remove from store.", nwConfig.ID, nwConfig.BridgeName, err)
       
  9877 +					d.storeDelete(nwConfig)
       
  9878 +				}
       
  9879 +				networkList = append(networkList[:i], networkList[i+1:]...)
       
  9880 +			} else {
       
  9881 +				return types.ForbiddenErrorf(
       
  9882 +					"cannot create network %s (%s): "+
       
  9883 +						"conflicts with network %s (%s): %s",
       
  9884 +					nwConfig.BridgeName, config.ID, nw.id,
       
  9885 +					nw.config.BridgeName, err.Error())
       
  9886 +			}
  9431 +		}
  9887 +		}
  9432 +	}
  9888 +	}
  9433 +	if config.DefaultBindingIP == nil ||
  9889 +	if config.DefaultBindingIP == nil ||
  9434 +		config.DefaultBindingIP.IsUnspecified() {
  9890 +		config.DefaultBindingIP.IsUnspecified() {
  9435 +		config.DefaultBindingIP = d.defrouteIP
  9891 +		config.DefaultBindingIP = d.defrouteIP
  9592 +	endpoint.addrv6 = ifInfo.AddressIPv6()
 10048 +	endpoint.addrv6 = ifInfo.AddressIPv6()
  9593 +	c := n.config
 10049 +	c := n.config
  9594 +
 10050 +
  9595 +	// Program any required port mapping and store them in the endpoint
 10051 +	// Program any required port mapping and store them in the endpoint
  9596 +	endpoint.portMapping, err = n.allocatePorts(epConfig,
 10052 +	endpoint.portMapping, err = n.allocatePorts(epConfig,
  9597 +		endpoint, c.DefaultBindingIntf, c.DefaultBindingIP)
 10053 +		endpoint, c.DefaultBindingIntf, c.DefaultBindingIP,
       
 10054 +		c.BridgeName+"_gw0")
  9598 +	if err != nil {
 10055 +	if err != nil {
  9599 +		return err
 10056 +		return err
  9600 +	}
 10057 +	}
  9601 +
 10058 +
  9602 +	return nil
 10059 +	return nil
 10612 +
 11069 +
 10613 +// BadRequest denotes the type of this error
 11070 +// BadRequest denotes the type of this error
 10614 +func (address InvalidLinkIPAddrError) BadRequest() {}
 11071 +func (address InvalidLinkIPAddrError) BadRequest() {}
 10615 diff --git a/vendor/src/github.com/docker/libnetwork/drivers/solaris/bridge/port_mapping.go b/vendor/src/github.com/docker/libnetwork/drivers/solaris/bridge/port_mapping.go
 11072 diff --git a/vendor/src/github.com/docker/libnetwork/drivers/solaris/bridge/port_mapping.go b/vendor/src/github.com/docker/libnetwork/drivers/solaris/bridge/port_mapping.go
 10616 new file mode 100644
 11073 new file mode 100644
 10617 index 0000000..3fae520
 11074 index 0000000..f2b1fd5
 10618 --- /dev/null
 11075 --- /dev/null
 10619 +++ b/vendor/src/github.com/docker/libnetwork/drivers/solaris/bridge/port_mapping.go
 11076 +++ b/vendor/src/github.com/docker/libnetwork/drivers/solaris/bridge/port_mapping.go
 10620 @@ -0,0 +1,199 @@
 11077 @@ -0,0 +1,218 @@
 10621 +package bridge
 11078 +package bridge
 10622 +
 11079 +
 10623 +import (
 11080 +import (
 10624 +	"bytes"
 11081 +	"bytes"
 10625 +	"errors"
 11082 +	"errors"
 10638 +
 11095 +
 10639 +const (
 11096 +const (
 10640 +	maxAllocatePortAttempts = 10
 11097 +	maxAllocatePortAttempts = 10
 10641 +)
 11098 +)
 10642 +
 11099 +
 10643 +func addPFRules(epid, bindIntf string, bs []types.PortBinding) {
 11100 +func addPFRules(epid, bindIntf string, bs []types.PortBinding,
       
 11101 +	gwIntf string) {
 10644 +	id := epid[:12]
 11102 +	id := epid[:12]
 10645 +	fname := "/var/lib/docker/network/files/pf." + id
 11103 +	fname := "/var/lib/docker/network/files/pf." + id
 10646 +
 11104 +
 10647 +	f, err := os.OpenFile(fname,
 11105 +	f, err := os.OpenFile(fname,
 10648 +		os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0600)
 11106 +		os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0600)
 10658 +			b.IP.String(), b.Port)
 11116 +			b.IP.String(), b.Port)
 10659 +		_, err = f.WriteString(r)
 11117 +		_, err = f.WriteString(r)
 10660 +		if err != nil {
 11118 +		if err != nil {
 10661 +			logrus.Warnf("cannot write to %s: %v", fname, err)
 11119 +			logrus.Warnf("cannot write to %s: %v", fname, err)
 10662 +		}
 11120 +		}
       
 11121 +		r = fmt.Sprintf(
       
 11122 +			"pass out inet proto %s from (%s) to (%s) port %d " +
       
 11123 +			"rdr-to %s port %d route-to %s" + "@" + "%s\n",
       
 11124 +			b.Proto.String(), bindIntf, bindIntf, b.HostPort,
       
 11125 +			b.IP.String(), b.Port, b.IP.String(), gwIntf)
       
 11126 +		_, err = f.WriteString(r)
       
 11127 +		if err != nil {
       
 11128 +			logrus.Warnf("cannot write to %s: %v", fname, err)
       
 11129 +		}
       
 11130 +		r = fmt.Sprintf(
       
 11131 +			"pass out on %s inet proto %s from (%s) to %s " +
       
 11132 +			"port %d reply-to %s\n", gwIntf,
       
 11133 +			b.Proto.String(), bindIntf, b.IP.String(), b.Port,
       
 11134 +			bindIntf)
       
 11135 +		_, err = f.WriteString(r)
       
 11136 +		if err != nil {
       
 11137 +			logrus.Warnf("cannot write to %s: %v", fname, err)
       
 11138 +		}
 10663 +	}
 11139 +	}
 10664 +	f.Close()
 11140 +	f.Close()
 10665 +
 11141 +
 10666 +	anchor := fmt.Sprintf("_auto/docker/ep%s", id)
 11142 +	anchor := fmt.Sprintf("_auto/docker/ep%s", id)
 10667 +	err = exec.Command("/usr/sbin/pfctl", "-a", anchor, "-f", fname).Run()
 11143 +	err = exec.Command("/usr/sbin/pfctl", "-a", anchor, "-f", fname).Run()
 10677 +	if err != nil {
 11153 +	if err != nil {
 10678 +		logrus.Warnf("pfctl -F failed: %v", err)
 11154 +		logrus.Warnf("pfctl -F failed: %v", err)
 10679 +	}
 11155 +	}
 10680 +}
 11156 +}
 10681 +
 11157 +
 10682 +func (n *bridgeNetwork) allocatePorts(epc *endpointConfiguration, ep *bridgeEndpoint, bindIntf string, reqDefBindIP net.IP) ([]types.PortBinding, error) {
 11158 +func (n *bridgeNetwork) allocatePorts(epc *endpointConfiguration, ep *bridgeEndpoint, bindIntf string, reqDefBindIP net.IP, gwIntf string) ([]types.PortBinding, error) {
 10683 +	if epc == nil || epc.PortBindings == nil || len(epc.PortBindings) == 0 {
 11159 +	if epc == nil || epc.PortBindings == nil || len(epc.PortBindings) == 0 {
 10684 +		return nil, nil
 11160 +		return nil, nil
 10685 +	}
 11161 +	}
 10686 +
 11162 +
 10687 +	defHostIP := defaultBindingIP
 11163 +	defHostIP := defaultBindingIP
 10692 +	bs, err := n.allocatePortsInternal(epc.PortBindings,
 11168 +	bs, err := n.allocatePortsInternal(epc.PortBindings,
 10693 +		bindIntf, ep.addr.IP, defHostIP)
 11169 +		bindIntf, ep.addr.IP, defHostIP)
 10694 +	if err != nil {
 11170 +	if err != nil {
 10695 +		return nil, err
 11171 +		return nil, err
 10696 +	}
 11172 +	}
 10697 +	addPFRules(ep.id, bindIntf, bs)
 11173 +	addPFRules(ep.id, bindIntf, bs, gwIntf)
 10698 +	return bs, err
 11174 +	return bs, err
 10699 +}
 11175 +}
 10700 +
 11176 +
 10701 +func (n *bridgeNetwork) allocatePortsInternal(bindings []types.PortBinding, bindIntf string, containerIP, defHostIP net.IP) ([]types.PortBinding, error) {
 11177 +func (n *bridgeNetwork) allocatePortsInternal(bindings []types.PortBinding, bindIntf string, containerIP, defHostIP net.IP) ([]types.PortBinding, error) {
 10702 +	bs := make([]types.PortBinding, 0, len(bindings))
 11178 +	bs := make([]types.PortBinding, 0, len(bindings))
 12233 +	if p.listener != nil {
 12709 +	if p.listener != nil {
 12234 +		return p.listener.Close()
 12710 +		return p.listener.Close()
 12235 +	}
 12711 +	}
 12236 +	return nil
 12712 +	return nil
 12237 +}
 12713 +}
       
 12714 diff --git a/vendor/src/github.com/docker/libnetwork/sandbox.go b/vendor/src/github.com/docker/libnetwork/sandbox.go
       
 12715 index 71c8ebb..4853ee4 100644
       
 12716 --- a/vendor/src/github.com/docker/libnetwork/sandbox.go
       
 12717 +++ b/vendor/src/github.com/docker/libnetwork/sandbox.go
       
 12718 @@ -148,12 +148,15 @@ func (sb *sandbox) Labels() map[string]interface{} {
       
 12719  func (sb *sandbox) Statistics() (map[string]*types.InterfaceStatistics, error) {
       
 12720  	m := make(map[string]*types.InterfaceStatistics)
       
 12721  
       
 12722 -	if sb.osSbox == nil {
       
 12723 +	sb.Lock()
       
 12724 +	osb := sb.osSbox
       
 12725 +	sb.Unlock()
       
 12726 +	if osb == nil {
       
 12727  		return m, nil
       
 12728  	}
       
 12729  
       
 12730  	var err error
       
 12731 -	for _, i := range sb.osSbox.Info().Interfaces() {
       
 12732 +	for _, i := range osb.Info().Interfaces() {
       
 12733  		if m[i.DstName()], err = i.Statistics(); err != nil {
       
 12734  			return m, err
       
 12735  		}
 12238 diff --git a/vendor/src/github.com/docker/libnetwork/sandbox_externalkey_solaris.go b/vendor/src/github.com/docker/libnetwork/sandbox_externalkey_solaris.go
 12736 diff --git a/vendor/src/github.com/docker/libnetwork/sandbox_externalkey_solaris.go b/vendor/src/github.com/docker/libnetwork/sandbox_externalkey_solaris.go
 12239 new file mode 100644
 12737 new file mode 100644
 12240 index 0000000..7569e46
 12738 index 0000000..7569e46
 12241 --- /dev/null
 12739 --- /dev/null
 12242 +++ b/vendor/src/github.com/docker/libnetwork/sandbox_externalkey_solaris.go
 12740 +++ b/vendor/src/github.com/docker/libnetwork/sandbox_externalkey_solaris.go
 13257 +func NewConsole(uid, gid int) (Console, error) {
 13755 +func NewConsole(uid, gid int) (Console, error) {
 13258 +	return nil, errors.New("libcontainer console is not supported on Solaris")
 13756 +	return nil, errors.New("libcontainer console is not supported on Solaris")
 13259 +}
 13757 +}
 13260 diff --git a/vendor/src/github.com/opencontainers/runc/libcontainer/container_solaris.go b/vendor/src/github.com/opencontainers/runc/libcontainer/container_solaris.go
 13758 diff --git a/vendor/src/github.com/opencontainers/runc/libcontainer/container_solaris.go b/vendor/src/github.com/opencontainers/runc/libcontainer/container_solaris.go
 13261 new file mode 100644
 13759 new file mode 100644
 13262 index 0000000..27639a1
 13760 index 0000000..503c339
 13263 --- /dev/null
 13761 --- /dev/null
 13264 +++ b/vendor/src/github.com/opencontainers/runc/libcontainer/container_solaris.go
 13762 +++ b/vendor/src/github.com/opencontainers/runc/libcontainer/container_solaris.go
 13265 @@ -0,0 +1,103 @@
 13763 @@ -0,0 +1,22 @@
 13266 +// +build solaris
 13764 +// +build solaris
 13267 +
 13765 +
 13268 +package libcontainer
 13766 +package libcontainer
 13269 +
       
 13270 +import (
       
 13271 +	"github.com/opencontainers/runc/libcontainer/zones"
       
 13272 +)
       
 13273 +
 13767 +
 13274 +// State represents a running container's state
 13768 +// State represents a running container's state
 13275 +type State struct {
 13769 +type State struct {
 13276 +	BaseState
 13770 +	BaseState
 13277 +
 13771 +
 13286 +type Container interface {
 13780 +type Container interface {
 13287 +	BaseContainer
 13781 +	BaseContainer
 13288 +
 13782 +
 13289 +	// Methods below here are platform specific
 13783 +	// Methods below here are platform specific
 13290 +
 13784 +
 13291 +}
       
 13292 +
       
 13293 +// XXX: Should collect the networking stats too.
       
 13294 +// 	For the stubs, need config with slice of NICs.
       
 13295 +func GetStats(id string) (*Stats, error) {
       
 13296 +	stats := &Stats{}
       
 13297 +	zstats := zones.Stats{}
       
 13298 +	cpuUsage := zones.CpuUsage {
       
 13299 +		TotalUsage:		5,
       
 13300 +		/* XXX: currently only TotalUsage is consumed.
       
 13301 +		PercpuUsage:		[]uint64 { 1, 2, 3 },
       
 13302 +		UsageInKernelmode:	3,
       
 13303 +		UsageInUsermode:	2,
       
 13304 +		*/
       
 13305 +	}
       
 13306 +	cpuStats := zones.CpuStats {
       
 13307 +		CpuUsage:	cpuUsage,
       
 13308 +		/* XXX: currently only CpuUsage.TotalUsage is consumed.
       
 13309 +		ThrottlingData:	ThrottlingData {
       
 13310 +			Periods:		100,
       
 13311 +			ThrottledPeriods:	5,
       
 13312 +			ThrottledTime:		1,
       
 13313 +		},
       
 13314 +		*/
       
 13315 +	}
       
 13316 +	memoryStats := zones.MemoryStats {
       
 13317 +		Cache:	65536,
       
 13318 +		Usage:	zones.MemoryData {
       
 13319 +			Usage:		32000000,
       
 13320 +			MaxUsage:	64000000,
       
 13321 +			Failcnt:	10,
       
 13322 +		},
       
 13323 +		/* XXX: currently only MemboriStats.Usage is consumed
       
 13324 +		SwapUsage: MemoryData {
       
 13325 +			Usage:		8192000,
       
 13326 +			MaxUsage:	8192000,
       
 13327 +			Failcnt:	128,
       
 13328 +		},
       
 13329 +		KernelUsage: MemoryData {
       
 13330 +			Usage:		4096000,
       
 13331 +			MaxUsage:	2048000,
       
 13332 +			Failcnt:	0,
       
 13333 +		},
       
 13334 +		*/
       
 13335 +	}
       
 13336 +	blkioStats := zones.BlkioStats {
       
 13337 +		IoServiceBytesRecursive: []zones.BlkioStatEntry {
       
 13338 +			{
       
 13339 +				Major:	14,
       
 13340 +				Minor:	1,
       
 13341 +				Op:	"read", //op name from api/client/stats.go
       
 13342 +				Value:	9000000,
       
 13343 +			},
       
 13344 +			{
       
 13345 +				Major:	13,
       
 13346 +				Minor:	0,
       
 13347 +				Op:	"write", //op name from api/client/stats.go
       
 13348 +				Value:	500000,
       
 13349 +			},
       
 13350 +		},
       
 13351 +		/* XXX: currently only IoServiceBytesRecursive is consumed
       
 13352 +		IoServicedRecursive: []BlkioStatEntry {
       
 13353 +			{
       
 13354 +				Major:	14000000,
       
 13355 +				Minor:	10000000,
       
 13356 +				Op:	"",
       
 13357 +				Value:	9000000,
       
 13358 +			},
       
 13359 +		},
       
 13360 +		*/
       
 13361 +	}
       
 13362 +	zstats.CpuStats = cpuStats
       
 13363 +	zstats.MemoryStats = memoryStats
       
 13364 +	zstats.BlkioStats = blkioStats
       
 13365 +
       
 13366 +	stats.Stats = &zstats
       
 13367 +	return stats, nil
       
 13368 +}
 13785 +}
 13369 diff --git a/vendor/src/github.com/opencontainers/runc/libcontainer/stats_solaris.go b/vendor/src/github.com/opencontainers/runc/libcontainer/stats_solaris.go
 13786 diff --git a/vendor/src/github.com/opencontainers/runc/libcontainer/stats_solaris.go b/vendor/src/github.com/opencontainers/runc/libcontainer/stats_solaris.go
 13370 new file mode 100644
 13787 new file mode 100644
 13371 index 0000000..7353cd8
 13788 index 0000000..7353cd8
 13372 --- /dev/null
 13789 --- /dev/null