github.com/docker/docker@v299999999.0.0-20200612211812-aaf470eca7b5+incompatible/daemon/daemon.go (about)

     1  // Package daemon exposes the functions that occur on the host server
     2  // that the Docker daemon is running.
     3  //
     4  // In implementing the various functions of the daemon, there is often
     5  // a method-specific struct for configuring the runtime behavior.
     6  package daemon // import "github.com/docker/docker/daemon"
     7  
     8  import (
     9  	"context"
    10  	"fmt"
    11  	"io/ioutil"
    12  	"net"
    13  	"net/url"
    14  	"os"
    15  	"path"
    16  	"path/filepath"
    17  	"runtime"
    18  	"strings"
    19  	"sync"
    20  	"time"
    21  
    22  	"github.com/docker/docker/pkg/fileutils"
    23  	"google.golang.org/grpc"
    24  	"google.golang.org/grpc/backoff"
    25  
    26  	"github.com/containerd/containerd"
    27  	"github.com/containerd/containerd/defaults"
    28  	"github.com/containerd/containerd/pkg/dialer"
    29  	"github.com/containerd/containerd/remotes/docker"
    30  	"github.com/docker/docker/api/types"
    31  	containertypes "github.com/docker/docker/api/types/container"
    32  	"github.com/docker/docker/api/types/swarm"
    33  	"github.com/docker/docker/builder"
    34  	"github.com/docker/docker/container"
    35  	"github.com/docker/docker/daemon/config"
    36  	"github.com/docker/docker/daemon/discovery"
    37  	"github.com/docker/docker/daemon/events"
    38  	"github.com/docker/docker/daemon/exec"
    39  	"github.com/docker/docker/daemon/images"
    40  	"github.com/docker/docker/daemon/logger"
    41  	"github.com/docker/docker/daemon/network"
    42  	"github.com/docker/docker/errdefs"
    43  	bkconfig "github.com/moby/buildkit/cmd/buildkitd/config"
    44  	"github.com/moby/buildkit/util/resolver"
    45  	rsystem "github.com/opencontainers/runc/libcontainer/system"
    46  	"github.com/sirupsen/logrus"
    47  
    48  	// register graph drivers
    49  	_ "github.com/docker/docker/daemon/graphdriver/register"
    50  	"github.com/docker/docker/daemon/stats"
    51  	dmetadata "github.com/docker/docker/distribution/metadata"
    52  	"github.com/docker/docker/dockerversion"
    53  	"github.com/docker/docker/image"
    54  	"github.com/docker/docker/layer"
    55  	"github.com/docker/docker/libcontainerd"
    56  	libcontainerdtypes "github.com/docker/docker/libcontainerd/types"
    57  	"github.com/docker/docker/pkg/idtools"
    58  	"github.com/docker/docker/pkg/locker"
    59  	"github.com/docker/docker/pkg/plugingetter"
    60  	"github.com/docker/docker/pkg/system"
    61  	"github.com/docker/docker/pkg/truncindex"
    62  	"github.com/docker/docker/plugin"
    63  	pluginexec "github.com/docker/docker/plugin/executor/containerd"
    64  	refstore "github.com/docker/docker/reference"
    65  	"github.com/docker/docker/registry"
    66  	"github.com/docker/docker/runconfig"
    67  	volumesservice "github.com/docker/docker/volume/service"
    68  	"github.com/docker/libnetwork"
    69  	"github.com/docker/libnetwork/cluster"
    70  	nwconfig "github.com/docker/libnetwork/config"
    71  	"github.com/pkg/errors"
    72  	"golang.org/x/sync/semaphore"
    73  )
    74  
    75  // ContainersNamespace is the name of the namespace used for users containers
    76  const (
    77  	ContainersNamespace = "moby"
    78  )
    79  
    80  var (
    81  	errSystemNotSupported = errors.New("the Docker daemon is not supported on this platform")
    82  )
    83  
    84  // Daemon holds information about the Docker daemon.
    85  type Daemon struct {
    86  	ID                string
    87  	repository        string
    88  	containers        container.Store
    89  	containersReplica container.ViewDB
    90  	execCommands      *exec.Store
    91  	imageService      *images.ImageService
    92  	idIndex           *truncindex.TruncIndex
    93  	configStore       *config.Config
    94  	statsCollector    *stats.Collector
    95  	defaultLogConfig  containertypes.LogConfig
    96  	RegistryService   registry.Service
    97  	EventsService     *events.Events
    98  	netController     libnetwork.NetworkController
    99  	volumes           *volumesservice.VolumesService
   100  	discoveryWatcher  discovery.Reloader
   101  	root              string
   102  	seccompEnabled    bool
   103  	apparmorEnabled   bool
   104  	shutdown          bool
   105  	idMapping         *idtools.IdentityMapping
   106  	// TODO: move graphDrivers field to an InfoService
   107  	graphDrivers map[string]string // By operating system
   108  
   109  	PluginStore           *plugin.Store // todo: remove
   110  	pluginManager         *plugin.Manager
   111  	linkIndex             *linkIndex
   112  	containerdCli         *containerd.Client
   113  	containerd            libcontainerdtypes.Client
   114  	defaultIsolation      containertypes.Isolation // Default isolation mode on Windows
   115  	clusterProvider       cluster.Provider
   116  	cluster               Cluster
   117  	genericResources      []swarm.GenericResource
   118  	metricsPluginListener net.Listener
   119  
   120  	machineMemory uint64
   121  
   122  	seccompProfile     []byte
   123  	seccompProfilePath string
   124  
   125  	diskUsageRunning int32
   126  	pruneRunning     int32
   127  	hosts            map[string]bool // hosts stores the addresses the daemon is listening on
   128  	startupDone      chan struct{}
   129  
   130  	attachmentStore       network.AttachmentStore
   131  	attachableNetworkLock *locker.Locker
   132  }
   133  
   134  // StoreHosts stores the addresses the daemon is listening on
   135  func (daemon *Daemon) StoreHosts(hosts []string) {
   136  	if daemon.hosts == nil {
   137  		daemon.hosts = make(map[string]bool)
   138  	}
   139  	for _, h := range hosts {
   140  		daemon.hosts[h] = true
   141  	}
   142  }
   143  
   144  // HasExperimental returns whether the experimental features of the daemon are enabled or not
   145  func (daemon *Daemon) HasExperimental() bool {
   146  	return daemon.configStore != nil && daemon.configStore.Experimental
   147  }
   148  
   149  // Features returns the features map from configStore
   150  func (daemon *Daemon) Features() *map[string]bool {
   151  	return &daemon.configStore.Features
   152  }
   153  
   154  // RegistryHosts returns registry configuration in containerd resolvers format
   155  func (daemon *Daemon) RegistryHosts() docker.RegistryHosts {
   156  	var (
   157  		registryKey = "docker.io"
   158  		mirrors     = make([]string, len(daemon.configStore.Mirrors))
   159  		m           = map[string]bkconfig.RegistryConfig{}
   160  	)
   161  	// must trim "https://" or "http://" prefix
   162  	for i, v := range daemon.configStore.Mirrors {
   163  		if uri, err := url.Parse(v); err == nil {
   164  			v = uri.Host
   165  		}
   166  		mirrors[i] = v
   167  	}
   168  	// set mirrors for default registry
   169  	m[registryKey] = bkconfig.RegistryConfig{Mirrors: mirrors}
   170  
   171  	for _, v := range daemon.configStore.InsecureRegistries {
   172  		u, err := url.Parse(v)
   173  		c := bkconfig.RegistryConfig{}
   174  		if err == nil {
   175  			v = u.Host
   176  			t := true
   177  			if u.Scheme == "http" {
   178  				c.PlainHTTP = &t
   179  			} else {
   180  				c.Insecure = &t
   181  			}
   182  		}
   183  		m[v] = c
   184  	}
   185  
   186  	for k, v := range m {
   187  		if d, err := registry.HostCertsDir(k); err == nil {
   188  			v.TLSConfigDir = []string{d}
   189  			m[k] = v
   190  		}
   191  	}
   192  
   193  	certsDir := registry.CertsDir()
   194  	if fis, err := ioutil.ReadDir(certsDir); err == nil {
   195  		for _, fi := range fis {
   196  			if _, ok := m[fi.Name()]; !ok {
   197  				m[fi.Name()] = bkconfig.RegistryConfig{
   198  					TLSConfigDir: []string{filepath.Join(certsDir, fi.Name())},
   199  				}
   200  			}
   201  		}
   202  	}
   203  
   204  	return resolver.NewRegistryConfig(m)
   205  }
   206  
   207  func (daemon *Daemon) restore() error {
   208  	var mapLock sync.Mutex
   209  	containers := make(map[string]*container.Container)
   210  
   211  	logrus.Info("Loading containers: start.")
   212  
   213  	dir, err := ioutil.ReadDir(daemon.repository)
   214  	if err != nil {
   215  		return err
   216  	}
   217  
   218  	// parallelLimit is the maximum number of parallel startup jobs that we
   219  	// allow (this is the limited used for all startup semaphores). The multipler
   220  	// (128) was chosen after some fairly significant benchmarking -- don't change
   221  	// it unless you've tested it significantly (this value is adjusted if
   222  	// RLIMIT_NOFILE is small to avoid EMFILE).
   223  	parallelLimit := adjustParallelLimit(len(dir), 128*runtime.NumCPU())
   224  
   225  	// Re-used for all parallel startup jobs.
   226  	var group sync.WaitGroup
   227  	sem := semaphore.NewWeighted(int64(parallelLimit))
   228  
   229  	for _, v := range dir {
   230  		group.Add(1)
   231  		go func(id string) {
   232  			defer group.Done()
   233  			_ = sem.Acquire(context.Background(), 1)
   234  			defer sem.Release(1)
   235  
   236  			container, err := daemon.load(id)
   237  			if err != nil {
   238  				logrus.Errorf("Failed to load container %v: %v", id, err)
   239  				return
   240  			}
   241  			if !system.IsOSSupported(container.OS) {
   242  				logrus.Errorf("Failed to load container %v: %s (%q)", id, system.ErrNotSupportedOperatingSystem, container.OS)
   243  				return
   244  			}
   245  			// Ignore the container if it does not support the current driver being used by the graph
   246  			currentDriverForContainerOS := daemon.graphDrivers[container.OS]
   247  			if (container.Driver == "" && currentDriverForContainerOS == "aufs") || container.Driver == currentDriverForContainerOS {
   248  				rwlayer, err := daemon.imageService.GetLayerByID(container.ID, container.OS)
   249  				if err != nil {
   250  					logrus.Errorf("Failed to load container mount %v: %v", id, err)
   251  					return
   252  				}
   253  				container.RWLayer = rwlayer
   254  				logrus.Debugf("Loaded container %v, isRunning: %v", container.ID, container.IsRunning())
   255  
   256  				mapLock.Lock()
   257  				containers[container.ID] = container
   258  				mapLock.Unlock()
   259  			} else {
   260  				logrus.Debugf("Cannot load container %s because it was created with another graph driver.", container.ID)
   261  			}
   262  		}(v.Name())
   263  	}
   264  	group.Wait()
   265  
   266  	removeContainers := make(map[string]*container.Container)
   267  	restartContainers := make(map[*container.Container]chan struct{})
   268  	activeSandboxes := make(map[string]interface{})
   269  
   270  	for _, c := range containers {
   271  		group.Add(1)
   272  		go func(c *container.Container) {
   273  			defer group.Done()
   274  			_ = sem.Acquire(context.Background(), 1)
   275  			defer sem.Release(1)
   276  
   277  			if err := daemon.registerName(c); err != nil {
   278  				logrus.Errorf("Failed to register container name %s: %s", c.ID, err)
   279  				mapLock.Lock()
   280  				delete(containers, c.ID)
   281  				mapLock.Unlock()
   282  				return
   283  			}
   284  			if err := daemon.Register(c); err != nil {
   285  				logrus.Errorf("Failed to register container %s: %s", c.ID, err)
   286  				mapLock.Lock()
   287  				delete(containers, c.ID)
   288  				mapLock.Unlock()
   289  				return
   290  			}
   291  
   292  			// The LogConfig.Type is empty if the container was created before docker 1.12 with default log driver.
   293  			// We should rewrite it to use the daemon defaults.
   294  			// Fixes https://github.com/docker/docker/issues/22536
   295  			if c.HostConfig.LogConfig.Type == "" {
   296  				if err := daemon.mergeAndVerifyLogConfig(&c.HostConfig.LogConfig); err != nil {
   297  					logrus.Errorf("Failed to verify log config for container %s: %q", c.ID, err)
   298  				}
   299  			}
   300  		}(c)
   301  	}
   302  	group.Wait()
   303  
   304  	for _, c := range containers {
   305  		group.Add(1)
   306  		go func(c *container.Container) {
   307  			defer group.Done()
   308  			_ = sem.Acquire(context.Background(), 1)
   309  			defer sem.Release(1)
   310  
   311  			daemon.backportMountSpec(c)
   312  			if err := daemon.checkpointAndSave(c); err != nil {
   313  				logrus.WithError(err).WithField("container", c.ID).Error("error saving backported mountspec to disk")
   314  			}
   315  
   316  			daemon.setStateCounter(c)
   317  
   318  			logrus.WithFields(logrus.Fields{
   319  				"container": c.ID,
   320  				"running":   c.IsRunning(),
   321  				"paused":    c.IsPaused(),
   322  			}).Debug("restoring container")
   323  
   324  			var (
   325  				err      error
   326  				alive    bool
   327  				ec       uint32
   328  				exitedAt time.Time
   329  				process  libcontainerdtypes.Process
   330  			)
   331  
   332  			alive, _, process, err = daemon.containerd.Restore(context.Background(), c.ID, c.InitializeStdio)
   333  			if err != nil && !errdefs.IsNotFound(err) {
   334  				logrus.Errorf("Failed to restore container %s with containerd: %s", c.ID, err)
   335  				return
   336  			}
   337  			if !alive && process != nil {
   338  				ec, exitedAt, err = process.Delete(context.Background())
   339  				if err != nil && !errdefs.IsNotFound(err) {
   340  					logrus.WithError(err).Errorf("Failed to delete container %s from containerd", c.ID)
   341  					return
   342  				}
   343  			} else if !daemon.configStore.LiveRestoreEnabled {
   344  				if err := daemon.shutdownContainer(c); err != nil && !errdefs.IsNotFound(err) {
   345  					logrus.WithError(err).WithField("container", c.ID).Error("error shutting down container")
   346  					return
   347  				}
   348  				c.ResetRestartManager(false)
   349  			}
   350  
   351  			if c.IsRunning() || c.IsPaused() {
   352  				c.RestartManager().Cancel() // manually start containers because some need to wait for swarm networking
   353  
   354  				if c.IsPaused() && alive {
   355  					s, err := daemon.containerd.Status(context.Background(), c.ID)
   356  					if err != nil {
   357  						logrus.WithError(err).WithField("container", c.ID).
   358  							Errorf("Failed to get container status")
   359  					} else {
   360  						logrus.WithField("container", c.ID).WithField("state", s).
   361  							Info("restored container paused")
   362  						switch s {
   363  						case containerd.Paused, containerd.Pausing:
   364  							// nothing to do
   365  						case containerd.Stopped:
   366  							alive = false
   367  						case containerd.Unknown:
   368  							logrus.WithField("container", c.ID).
   369  								Error("Unknown status for container during restore")
   370  						default:
   371  							// running
   372  							c.Lock()
   373  							c.Paused = false
   374  							daemon.setStateCounter(c)
   375  							if err := c.CheckpointTo(daemon.containersReplica); err != nil {
   376  								logrus.WithError(err).WithField("container", c.ID).
   377  									Error("Failed to update stopped container state")
   378  							}
   379  							c.Unlock()
   380  						}
   381  					}
   382  				}
   383  
   384  				if !alive {
   385  					c.Lock()
   386  					c.SetStopped(&container.ExitStatus{ExitCode: int(ec), ExitedAt: exitedAt})
   387  					daemon.Cleanup(c)
   388  					if err := c.CheckpointTo(daemon.containersReplica); err != nil {
   389  						logrus.Errorf("Failed to update stopped container %s state: %v", c.ID, err)
   390  					}
   391  					c.Unlock()
   392  				}
   393  
   394  				// we call Mount and then Unmount to get BaseFs of the container
   395  				if err := daemon.Mount(c); err != nil {
   396  					// The mount is unlikely to fail. However, in case mount fails
   397  					// the container should be allowed to restore here. Some functionalities
   398  					// (like docker exec -u user) might be missing but container is able to be
   399  					// stopped/restarted/removed.
   400  					// See #29365 for related information.
   401  					// The error is only logged here.
   402  					logrus.Warnf("Failed to mount container on getting BaseFs path %v: %v", c.ID, err)
   403  				} else {
   404  					if err := daemon.Unmount(c); err != nil {
   405  						logrus.Warnf("Failed to umount container on getting BaseFs path %v: %v", c.ID, err)
   406  					}
   407  				}
   408  
   409  				c.ResetRestartManager(false)
   410  				if !c.HostConfig.NetworkMode.IsContainer() && c.IsRunning() {
   411  					options, err := daemon.buildSandboxOptions(c)
   412  					if err != nil {
   413  						logrus.Warnf("Failed build sandbox option to restore container %s: %v", c.ID, err)
   414  					}
   415  					mapLock.Lock()
   416  					activeSandboxes[c.NetworkSettings.SandboxID] = options
   417  					mapLock.Unlock()
   418  				}
   419  			}
   420  
   421  			// get list of containers we need to restart
   422  
   423  			// Do not autostart containers which
   424  			// has endpoints in a swarm scope
   425  			// network yet since the cluster is
   426  			// not initialized yet. We will start
   427  			// it after the cluster is
   428  			// initialized.
   429  			if daemon.configStore.AutoRestart && c.ShouldRestart() && !c.NetworkSettings.HasSwarmEndpoint && c.HasBeenStartedBefore {
   430  				mapLock.Lock()
   431  				restartContainers[c] = make(chan struct{})
   432  				mapLock.Unlock()
   433  			} else if c.HostConfig != nil && c.HostConfig.AutoRemove {
   434  				mapLock.Lock()
   435  				removeContainers[c.ID] = c
   436  				mapLock.Unlock()
   437  			}
   438  
   439  			c.Lock()
   440  			if c.RemovalInProgress {
   441  				// We probably crashed in the middle of a removal, reset
   442  				// the flag.
   443  				//
   444  				// We DO NOT remove the container here as we do not
   445  				// know if the user had requested for either the
   446  				// associated volumes, network links or both to also
   447  				// be removed. So we put the container in the "dead"
   448  				// state and leave further processing up to them.
   449  				logrus.Debugf("Resetting RemovalInProgress flag from %v", c.ID)
   450  				c.RemovalInProgress = false
   451  				c.Dead = true
   452  				if err := c.CheckpointTo(daemon.containersReplica); err != nil {
   453  					logrus.Errorf("Failed to update RemovalInProgress container %s state: %v", c.ID, err)
   454  				}
   455  			}
   456  			c.Unlock()
   457  		}(c)
   458  	}
   459  	group.Wait()
   460  
   461  	daemon.netController, err = daemon.initNetworkController(daemon.configStore, activeSandboxes)
   462  	if err != nil {
   463  		return fmt.Errorf("Error initializing network controller: %v", err)
   464  	}
   465  
   466  	// Now that all the containers are registered, register the links
   467  	for _, c := range containers {
   468  		group.Add(1)
   469  		go func(c *container.Container) {
   470  			_ = sem.Acquire(context.Background(), 1)
   471  
   472  			if err := daemon.registerLinks(c, c.HostConfig); err != nil {
   473  				logrus.Errorf("failed to register link for container %s: %v", c.ID, err)
   474  			}
   475  
   476  			sem.Release(1)
   477  			group.Done()
   478  		}(c)
   479  	}
   480  	group.Wait()
   481  
   482  	for c, notifier := range restartContainers {
   483  		group.Add(1)
   484  		go func(c *container.Container, chNotify chan struct{}) {
   485  			_ = sem.Acquire(context.Background(), 1)
   486  			logrus.Debugf("Starting container %s", c.ID)
   487  
   488  			// ignore errors here as this is a best effort to wait for children to be
   489  			//   running before we try to start the container
   490  			children := daemon.children(c)
   491  			timeout := time.NewTimer(5 * time.Second)
   492  			defer timeout.Stop()
   493  
   494  			for _, child := range children {
   495  				if notifier, exists := restartContainers[child]; exists {
   496  					select {
   497  					case <-notifier:
   498  					case <-timeout.C:
   499  					}
   500  				}
   501  			}
   502  
   503  			// Make sure networks are available before starting
   504  			daemon.waitForNetworks(c)
   505  			if err := daemon.containerStart(c, "", "", true); err != nil {
   506  				logrus.Errorf("Failed to start container %s: %s", c.ID, err)
   507  			}
   508  			close(chNotify)
   509  
   510  			sem.Release(1)
   511  			group.Done()
   512  		}(c, notifier)
   513  	}
   514  	group.Wait()
   515  
   516  	for id := range removeContainers {
   517  		group.Add(1)
   518  		go func(cid string) {
   519  			_ = sem.Acquire(context.Background(), 1)
   520  
   521  			if err := daemon.ContainerRm(cid, &types.ContainerRmConfig{ForceRemove: true, RemoveVolume: true}); err != nil {
   522  				logrus.Errorf("Failed to remove container %s: %s", cid, err)
   523  			}
   524  
   525  			sem.Release(1)
   526  			group.Done()
   527  		}(id)
   528  	}
   529  	group.Wait()
   530  
   531  	// any containers that were started above would already have had this done,
   532  	// however we need to now prepare the mountpoints for the rest of the containers as well.
   533  	// This shouldn't cause any issue running on the containers that already had this run.
   534  	// This must be run after any containers with a restart policy so that containerized plugins
   535  	// can have a chance to be running before we try to initialize them.
   536  	for _, c := range containers {
   537  		// if the container has restart policy, do not
   538  		// prepare the mountpoints since it has been done on restarting.
   539  		// This is to speed up the daemon start when a restart container
   540  		// has a volume and the volume driver is not available.
   541  		if _, ok := restartContainers[c]; ok {
   542  			continue
   543  		} else if _, ok := removeContainers[c.ID]; ok {
   544  			// container is automatically removed, skip it.
   545  			continue
   546  		}
   547  
   548  		group.Add(1)
   549  		go func(c *container.Container) {
   550  			_ = sem.Acquire(context.Background(), 1)
   551  
   552  			if err := daemon.prepareMountPoints(c); err != nil {
   553  				logrus.Error(err)
   554  			}
   555  
   556  			sem.Release(1)
   557  			group.Done()
   558  		}(c)
   559  	}
   560  	group.Wait()
   561  
   562  	logrus.Info("Loading containers: done.")
   563  
   564  	return nil
   565  }
   566  
   567  // RestartSwarmContainers restarts any autostart container which has a
   568  // swarm endpoint.
   569  func (daemon *Daemon) RestartSwarmContainers() {
   570  	ctx := context.Background()
   571  
   572  	// parallelLimit is the maximum number of parallel startup jobs that we
   573  	// allow (this is the limited used for all startup semaphores). The multipler
   574  	// (128) was chosen after some fairly significant benchmarking -- don't change
   575  	// it unless you've tested it significantly (this value is adjusted if
   576  	// RLIMIT_NOFILE is small to avoid EMFILE).
   577  	parallelLimit := adjustParallelLimit(len(daemon.List()), 128*runtime.NumCPU())
   578  
   579  	var group sync.WaitGroup
   580  	sem := semaphore.NewWeighted(int64(parallelLimit))
   581  
   582  	for _, c := range daemon.List() {
   583  		if !c.IsRunning() && !c.IsPaused() {
   584  			// Autostart all the containers which has a
   585  			// swarm endpoint now that the cluster is
   586  			// initialized.
   587  			if daemon.configStore.AutoRestart && c.ShouldRestart() && c.NetworkSettings.HasSwarmEndpoint && c.HasBeenStartedBefore {
   588  				group.Add(1)
   589  				go func(c *container.Container) {
   590  					if err := sem.Acquire(ctx, 1); err != nil {
   591  						// ctx is done.
   592  						group.Done()
   593  						return
   594  					}
   595  
   596  					if err := daemon.containerStart(c, "", "", true); err != nil {
   597  						logrus.Error(err)
   598  					}
   599  
   600  					sem.Release(1)
   601  					group.Done()
   602  				}(c)
   603  			}
   604  		}
   605  	}
   606  	group.Wait()
   607  }
   608  
   609  // waitForNetworks is used during daemon initialization when starting up containers
   610  // It ensures that all of a container's networks are available before the daemon tries to start the container.
   611  // In practice it just makes sure the discovery service is available for containers which use a network that require discovery.
   612  func (daemon *Daemon) waitForNetworks(c *container.Container) {
   613  	if daemon.discoveryWatcher == nil {
   614  		return
   615  	}
   616  
   617  	// Make sure if the container has a network that requires discovery that the discovery service is available before starting
   618  	for netName := range c.NetworkSettings.Networks {
   619  		// If we get `ErrNoSuchNetwork` here, we can assume that it is due to discovery not being ready
   620  		// Most likely this is because the K/V store used for discovery is in a container and needs to be started
   621  		if _, err := daemon.netController.NetworkByName(netName); err != nil {
   622  			if _, ok := err.(libnetwork.ErrNoSuchNetwork); !ok {
   623  				continue
   624  			}
   625  
   626  			// use a longish timeout here due to some slowdowns in libnetwork if the k/v store is on anything other than --net=host
   627  			// FIXME: why is this slow???
   628  			dur := 60 * time.Second
   629  			timer := time.NewTimer(dur)
   630  
   631  			logrus.Debugf("Container %s waiting for network to be ready", c.Name)
   632  			select {
   633  			case <-daemon.discoveryWatcher.ReadyCh():
   634  			case <-timer.C:
   635  			}
   636  			timer.Stop()
   637  
   638  			return
   639  		}
   640  	}
   641  }
   642  
   643  func (daemon *Daemon) children(c *container.Container) map[string]*container.Container {
   644  	return daemon.linkIndex.children(c)
   645  }
   646  
   647  // parents returns the names of the parent containers of the container
   648  // with the given name.
   649  func (daemon *Daemon) parents(c *container.Container) map[string]*container.Container {
   650  	return daemon.linkIndex.parents(c)
   651  }
   652  
   653  func (daemon *Daemon) registerLink(parent, child *container.Container, alias string) error {
   654  	fullName := path.Join(parent.Name, alias)
   655  	if err := daemon.containersReplica.ReserveName(fullName, child.ID); err != nil {
   656  		if err == container.ErrNameReserved {
   657  			logrus.Warnf("error registering link for %s, to %s, as alias %s, ignoring: %v", parent.ID, child.ID, alias, err)
   658  			return nil
   659  		}
   660  		return err
   661  	}
   662  	daemon.linkIndex.link(parent, child, fullName)
   663  	return nil
   664  }
   665  
   666  // DaemonJoinsCluster informs the daemon has joined the cluster and provides
   667  // the handler to query the cluster component
   668  func (daemon *Daemon) DaemonJoinsCluster(clusterProvider cluster.Provider) {
   669  	daemon.setClusterProvider(clusterProvider)
   670  }
   671  
   672  // DaemonLeavesCluster informs the daemon has left the cluster
   673  func (daemon *Daemon) DaemonLeavesCluster() {
   674  	// Daemon is in charge of removing the attachable networks with
   675  	// connected containers when the node leaves the swarm
   676  	daemon.clearAttachableNetworks()
   677  	// We no longer need the cluster provider, stop it now so that
   678  	// the network agent will stop listening to cluster events.
   679  	daemon.setClusterProvider(nil)
   680  	// Wait for the networking cluster agent to stop
   681  	daemon.netController.AgentStopWait()
   682  	// Daemon is in charge of removing the ingress network when the
   683  	// node leaves the swarm. Wait for job to be done or timeout.
   684  	// This is called also on graceful daemon shutdown. We need to
   685  	// wait, because the ingress release has to happen before the
   686  	// network controller is stopped.
   687  
   688  	if done, err := daemon.ReleaseIngress(); err == nil {
   689  		timeout := time.NewTimer(5 * time.Second)
   690  		defer timeout.Stop()
   691  
   692  		select {
   693  		case <-done:
   694  		case <-timeout.C:
   695  			logrus.Warn("timeout while waiting for ingress network removal")
   696  		}
   697  	} else {
   698  		logrus.Warnf("failed to initiate ingress network removal: %v", err)
   699  	}
   700  
   701  	daemon.attachmentStore.ClearAttachments()
   702  }
   703  
   704  // setClusterProvider sets a component for querying the current cluster state.
   705  func (daemon *Daemon) setClusterProvider(clusterProvider cluster.Provider) {
   706  	daemon.clusterProvider = clusterProvider
   707  	daemon.netController.SetClusterProvider(clusterProvider)
   708  	daemon.attachableNetworkLock = locker.New()
   709  }
   710  
   711  // IsSwarmCompatible verifies if the current daemon
   712  // configuration is compatible with the swarm mode
   713  func (daemon *Daemon) IsSwarmCompatible() error {
   714  	if daemon.configStore == nil {
   715  		return nil
   716  	}
   717  	return daemon.configStore.IsSwarmCompatible()
   718  }
   719  
   720  // NewDaemon sets up everything for the daemon to be able to service
   721  // requests from the webserver.
   722  func NewDaemon(ctx context.Context, config *config.Config, pluginStore *plugin.Store) (daemon *Daemon, err error) {
   723  	setDefaultMtu(config)
   724  
   725  	registryService, err := registry.NewService(config.ServiceOptions)
   726  	if err != nil {
   727  		return nil, err
   728  	}
   729  
   730  	// Ensure that we have a correct root key limit for launching containers.
   731  	if err := ModifyRootKeyLimit(); err != nil {
   732  		logrus.Warnf("unable to modify root key limit, number of containers could be limited by this quota: %v", err)
   733  	}
   734  
   735  	// Ensure we have compatible and valid configuration options
   736  	if err := verifyDaemonSettings(config); err != nil {
   737  		return nil, err
   738  	}
   739  
   740  	// Do we have a disabled network?
   741  	config.DisableBridge = isBridgeNetworkDisabled(config)
   742  
   743  	// Setup the resolv.conf
   744  	setupResolvConf(config)
   745  
   746  	// Verify the platform is supported as a daemon
   747  	if !platformSupported {
   748  		return nil, errSystemNotSupported
   749  	}
   750  
   751  	// Validate platform-specific requirements
   752  	if err := checkSystem(); err != nil {
   753  		return nil, err
   754  	}
   755  
   756  	idMapping, err := setupRemappedRoot(config)
   757  	if err != nil {
   758  		return nil, err
   759  	}
   760  	rootIDs := idMapping.RootPair()
   761  	if err := setupDaemonProcess(config); err != nil {
   762  		return nil, err
   763  	}
   764  
   765  	// set up the tmpDir to use a canonical path
   766  	tmp, err := prepareTempDir(config.Root, rootIDs)
   767  	if err != nil {
   768  		return nil, fmt.Errorf("Unable to get the TempDir under %s: %s", config.Root, err)
   769  	}
   770  	realTmp, err := fileutils.ReadSymlinkedDirectory(tmp)
   771  	if err != nil {
   772  		return nil, fmt.Errorf("Unable to get the full path to the TempDir (%s): %s", tmp, err)
   773  	}
   774  	if isWindows {
   775  		if _, err := os.Stat(realTmp); err != nil && os.IsNotExist(err) {
   776  			if err := system.MkdirAll(realTmp, 0700); err != nil {
   777  				return nil, fmt.Errorf("Unable to create the TempDir (%s): %s", realTmp, err)
   778  			}
   779  		}
   780  		os.Setenv("TEMP", realTmp)
   781  		os.Setenv("TMP", realTmp)
   782  	} else {
   783  		os.Setenv("TMPDIR", realTmp)
   784  	}
   785  
   786  	d := &Daemon{
   787  		configStore: config,
   788  		PluginStore: pluginStore,
   789  		startupDone: make(chan struct{}),
   790  	}
   791  
   792  	// Ensure the daemon is properly shutdown if there is a failure during
   793  	// initialization
   794  	defer func() {
   795  		if err != nil {
   796  			if err := d.Shutdown(); err != nil {
   797  				logrus.Error(err)
   798  			}
   799  		}
   800  	}()
   801  
   802  	if err := d.setGenericResources(config); err != nil {
   803  		return nil, err
   804  	}
   805  	// set up SIGUSR1 handler on Unix-like systems, or a Win32 global event
   806  	// on Windows to dump Go routine stacks
   807  	stackDumpDir := config.Root
   808  	if execRoot := config.GetExecRoot(); execRoot != "" {
   809  		stackDumpDir = execRoot
   810  	}
   811  	d.setupDumpStackTrap(stackDumpDir)
   812  
   813  	if err := d.setupSeccompProfile(); err != nil {
   814  		return nil, err
   815  	}
   816  
   817  	// Set the default isolation mode (only applicable on Windows)
   818  	if err := d.setDefaultIsolation(); err != nil {
   819  		return nil, fmt.Errorf("error setting default isolation mode: %v", err)
   820  	}
   821  
   822  	if err := configureMaxThreads(config); err != nil {
   823  		logrus.Warnf("Failed to configure golang's threads limit: %v", err)
   824  	}
   825  
   826  	// ensureDefaultAppArmorProfile does nothing if apparmor is disabled
   827  	if err := ensureDefaultAppArmorProfile(); err != nil {
   828  		logrus.Errorf(err.Error())
   829  	}
   830  
   831  	daemonRepo := filepath.Join(config.Root, "containers")
   832  	if err := idtools.MkdirAllAndChown(daemonRepo, 0700, rootIDs); err != nil {
   833  		return nil, err
   834  	}
   835  
   836  	// Create the directory where we'll store the runtime scripts (i.e. in
   837  	// order to support runtimeArgs)
   838  	daemonRuntimes := filepath.Join(config.Root, "runtimes")
   839  	if err := system.MkdirAll(daemonRuntimes, 0700); err != nil {
   840  		return nil, err
   841  	}
   842  	if err := d.loadRuntimes(); err != nil {
   843  		return nil, err
   844  	}
   845  
   846  	if isWindows {
   847  		if err := system.MkdirAll(filepath.Join(config.Root, "credentialspecs"), 0); err != nil {
   848  			return nil, err
   849  		}
   850  	}
   851  
   852  	// On Windows we don't support the environment variable, or a user supplied graphdriver
   853  	// as Windows has no choice in terms of which graphdrivers to use. It's a case of
   854  	// running Windows containers on Windows - windowsfilter, running Linux containers on Windows,
   855  	// lcow. Unix platforms however run a single graphdriver for all containers, and it can
   856  	// be set through an environment variable, a daemon start parameter, or chosen through
   857  	// initialization of the layerstore through driver priority order for example.
   858  	d.graphDrivers = make(map[string]string)
   859  	layerStores := make(map[string]layer.Store)
   860  	if isWindows {
   861  		d.graphDrivers[runtime.GOOS] = "windowsfilter"
   862  		if system.LCOWSupported() {
   863  			d.graphDrivers["linux"] = "lcow"
   864  		}
   865  	} else {
   866  		driverName := os.Getenv("DOCKER_DRIVER")
   867  		if driverName == "" {
   868  			driverName = config.GraphDriver
   869  		} else {
   870  			logrus.Infof("Setting the storage driver from the $DOCKER_DRIVER environment variable (%s)", driverName)
   871  		}
   872  		d.graphDrivers[runtime.GOOS] = driverName // May still be empty. Layerstore init determines instead.
   873  	}
   874  
   875  	d.RegistryService = registryService
   876  	logger.RegisterPluginGetter(d.PluginStore)
   877  
   878  	metricsSockPath, err := d.listenMetricsSock()
   879  	if err != nil {
   880  		return nil, err
   881  	}
   882  	registerMetricsPluginCallback(d.PluginStore, metricsSockPath)
   883  
   884  	backoffConfig := backoff.DefaultConfig
   885  	backoffConfig.MaxDelay = 3 * time.Second
   886  	connParams := grpc.ConnectParams{
   887  		Backoff: backoffConfig,
   888  	}
   889  	gopts := []grpc.DialOption{
   890  		// WithBlock makes sure that the following containerd request
   891  		// is reliable.
   892  		//
   893  		// NOTE: In one edge case with high load pressure, kernel kills
   894  		// dockerd, containerd and containerd-shims caused by OOM.
   895  		// When both dockerd and containerd restart, but containerd
   896  		// will take time to recover all the existing containers. Before
   897  		// containerd serving, dockerd will failed with gRPC error.
   898  		// That bad thing is that restore action will still ignore the
   899  		// any non-NotFound errors and returns running state for
   900  		// already stopped container. It is unexpected behavior. And
   901  		// we need to restart dockerd to make sure that anything is OK.
   902  		//
   903  		// It is painful. Add WithBlock can prevent the edge case. And
   904  		// n common case, the containerd will be serving in shortly.
   905  		// It is not harm to add WithBlock for containerd connection.
   906  		grpc.WithBlock(),
   907  
   908  		grpc.WithInsecure(),
   909  		grpc.WithConnectParams(connParams),
   910  		grpc.WithContextDialer(dialer.ContextDialer),
   911  
   912  		// TODO(stevvooe): We may need to allow configuration of this on the client.
   913  		grpc.WithDefaultCallOptions(grpc.MaxCallRecvMsgSize(defaults.DefaultMaxRecvMsgSize)),
   914  		grpc.WithDefaultCallOptions(grpc.MaxCallSendMsgSize(defaults.DefaultMaxSendMsgSize)),
   915  	}
   916  	if config.ContainerdAddr != "" {
   917  		d.containerdCli, err = containerd.New(config.ContainerdAddr, containerd.WithDefaultNamespace(config.ContainerdNamespace), containerd.WithDialOpts(gopts), containerd.WithTimeout(60*time.Second))
   918  		if err != nil {
   919  			return nil, errors.Wrapf(err, "failed to dial %q", config.ContainerdAddr)
   920  		}
   921  	}
   922  
   923  	createPluginExec := func(m *plugin.Manager) (plugin.Executor, error) {
   924  		var pluginCli *containerd.Client
   925  
   926  		// Windows is not currently using containerd, keep the
   927  		// client as nil
   928  		if config.ContainerdAddr != "" {
   929  			pluginCli, err = containerd.New(config.ContainerdAddr, containerd.WithDefaultNamespace(config.ContainerdPluginNamespace), containerd.WithDialOpts(gopts), containerd.WithTimeout(60*time.Second))
   930  			if err != nil {
   931  				return nil, errors.Wrapf(err, "failed to dial %q", config.ContainerdAddr)
   932  			}
   933  		}
   934  
   935  		return pluginexec.New(ctx, getPluginExecRoot(config.Root), pluginCli, config.ContainerdPluginNamespace, m, d.useShimV2())
   936  	}
   937  
   938  	// Plugin system initialization should happen before restore. Do not change order.
   939  	d.pluginManager, err = plugin.NewManager(plugin.ManagerConfig{
   940  		Root:               filepath.Join(config.Root, "plugins"),
   941  		ExecRoot:           getPluginExecRoot(config.Root),
   942  		Store:              d.PluginStore,
   943  		CreateExecutor:     createPluginExec,
   944  		RegistryService:    registryService,
   945  		LiveRestoreEnabled: config.LiveRestoreEnabled,
   946  		LogPluginEvent:     d.LogPluginEvent, // todo: make private
   947  		AuthzMiddleware:    config.AuthzMiddleware,
   948  	})
   949  	if err != nil {
   950  		return nil, errors.Wrap(err, "couldn't create plugin manager")
   951  	}
   952  
   953  	if err := d.setupDefaultLogConfig(); err != nil {
   954  		return nil, err
   955  	}
   956  
   957  	for operatingSystem, gd := range d.graphDrivers {
   958  		layerStores[operatingSystem], err = layer.NewStoreFromOptions(layer.StoreOptions{
   959  			Root:                      config.Root,
   960  			MetadataStorePathTemplate: filepath.Join(config.Root, "image", "%s", "layerdb"),
   961  			GraphDriver:               gd,
   962  			GraphDriverOptions:        config.GraphOptions,
   963  			IDMapping:                 idMapping,
   964  			PluginGetter:              d.PluginStore,
   965  			ExperimentalEnabled:       config.Experimental,
   966  			OS:                        operatingSystem,
   967  		})
   968  		if err != nil {
   969  			return nil, err
   970  		}
   971  
   972  		// As layerstore initialization may set the driver
   973  		d.graphDrivers[operatingSystem] = layerStores[operatingSystem].DriverName()
   974  	}
   975  
   976  	// Configure and validate the kernels security support. Note this is a Linux/FreeBSD
   977  	// operation only, so it is safe to pass *just* the runtime OS graphdriver.
   978  	if err := configureKernelSecuritySupport(config, d.graphDrivers[runtime.GOOS]); err != nil {
   979  		return nil, err
   980  	}
   981  
   982  	imageRoot := filepath.Join(config.Root, "image", d.graphDrivers[runtime.GOOS])
   983  	ifs, err := image.NewFSStoreBackend(filepath.Join(imageRoot, "imagedb"))
   984  	if err != nil {
   985  		return nil, err
   986  	}
   987  
   988  	lgrMap := make(map[string]image.LayerGetReleaser)
   989  	for los, ls := range layerStores {
   990  		lgrMap[los] = ls
   991  	}
   992  	imageStore, err := image.NewImageStore(ifs, lgrMap)
   993  	if err != nil {
   994  		return nil, err
   995  	}
   996  
   997  	d.volumes, err = volumesservice.NewVolumeService(config.Root, d.PluginStore, rootIDs, d)
   998  	if err != nil {
   999  		return nil, err
  1000  	}
  1001  
  1002  	trustKey, err := loadOrCreateTrustKey(config.TrustKeyPath)
  1003  	if err != nil {
  1004  		return nil, err
  1005  	}
  1006  
  1007  	trustDir := filepath.Join(config.Root, "trust")
  1008  
  1009  	if err := system.MkdirAll(trustDir, 0700); err != nil {
  1010  		return nil, err
  1011  	}
  1012  
  1013  	// We have a single tag/reference store for the daemon globally. However, it's
  1014  	// stored under the graphdriver. On host platforms which only support a single
  1015  	// container OS, but multiple selectable graphdrivers, this means depending on which
  1016  	// graphdriver is chosen, the global reference store is under there. For
  1017  	// platforms which support multiple container operating systems, this is slightly
  1018  	// more problematic as where does the global ref store get located? Fortunately,
  1019  	// for Windows, which is currently the only daemon supporting multiple container
  1020  	// operating systems, the list of graphdrivers available isn't user configurable.
  1021  	// For backwards compatibility, we just put it under the windowsfilter
  1022  	// directory regardless.
  1023  	refStoreLocation := filepath.Join(imageRoot, `repositories.json`)
  1024  	rs, err := refstore.NewReferenceStore(refStoreLocation)
  1025  	if err != nil {
  1026  		return nil, fmt.Errorf("Couldn't create reference store repository: %s", err)
  1027  	}
  1028  
  1029  	distributionMetadataStore, err := dmetadata.NewFSMetadataStore(filepath.Join(imageRoot, "distribution"))
  1030  	if err != nil {
  1031  		return nil, err
  1032  	}
  1033  
  1034  	// Discovery is only enabled when the daemon is launched with an address to advertise.  When
  1035  	// initialized, the daemon is registered and we can store the discovery backend as it's read-only
  1036  	if err := d.initDiscovery(config); err != nil {
  1037  		return nil, err
  1038  	}
  1039  
  1040  	sysInfo := d.RawSysInfo(false)
  1041  	// Check if Devices cgroup is mounted, it is hard requirement for container security,
  1042  	// on Linux.
  1043  	if runtime.GOOS == "linux" && !sysInfo.CgroupDevicesEnabled && !rsystem.RunningInUserNS() {
  1044  		return nil, errors.New("Devices cgroup isn't mounted")
  1045  	}
  1046  
  1047  	d.ID = trustKey.PublicKey().KeyID()
  1048  	d.repository = daemonRepo
  1049  	d.containers = container.NewMemoryStore()
  1050  	if d.containersReplica, err = container.NewViewDB(); err != nil {
  1051  		return nil, err
  1052  	}
  1053  	d.execCommands = exec.NewStore()
  1054  	d.idIndex = truncindex.NewTruncIndex([]string{})
  1055  	d.statsCollector = d.newStatsCollector(1 * time.Second)
  1056  
  1057  	d.EventsService = events.New()
  1058  	d.root = config.Root
  1059  	d.idMapping = idMapping
  1060  	d.seccompEnabled = sysInfo.Seccomp
  1061  	d.apparmorEnabled = sysInfo.AppArmor
  1062  
  1063  	d.linkIndex = newLinkIndex()
  1064  
  1065  	// TODO: imageStore, distributionMetadataStore, and ReferenceStore are only
  1066  	// used above to run migration. They could be initialized in ImageService
  1067  	// if migration is called from daemon/images. layerStore might move as well.
  1068  	d.imageService = images.NewImageService(images.ImageServiceConfig{
  1069  		ContainerStore:            d.containers,
  1070  		DistributionMetadataStore: distributionMetadataStore,
  1071  		EventsService:             d.EventsService,
  1072  		ImageStore:                imageStore,
  1073  		LayerStores:               layerStores,
  1074  		MaxConcurrentDownloads:    *config.MaxConcurrentDownloads,
  1075  		MaxConcurrentUploads:      *config.MaxConcurrentUploads,
  1076  		MaxDownloadAttempts:       *config.MaxDownloadAttempts,
  1077  		ReferenceStore:            rs,
  1078  		RegistryService:           registryService,
  1079  		TrustKey:                  trustKey,
  1080  	})
  1081  
  1082  	go d.execCommandGC()
  1083  
  1084  	d.containerd, err = libcontainerd.NewClient(ctx, d.containerdCli, filepath.Join(config.ExecRoot, "containerd"), config.ContainerdNamespace, d, d.useShimV2())
  1085  	if err != nil {
  1086  		return nil, err
  1087  	}
  1088  
  1089  	if err := d.restore(); err != nil {
  1090  		return nil, err
  1091  	}
  1092  	close(d.startupDone)
  1093  
  1094  	info := d.SystemInfo()
  1095  
  1096  	engineInfo.WithValues(
  1097  		dockerversion.Version,
  1098  		dockerversion.GitCommit,
  1099  		info.Architecture,
  1100  		info.Driver,
  1101  		info.KernelVersion,
  1102  		info.OperatingSystem,
  1103  		info.OSType,
  1104  		info.OSVersion,
  1105  		info.ID,
  1106  	).Set(1)
  1107  	engineCpus.Set(float64(info.NCPU))
  1108  	engineMemory.Set(float64(info.MemTotal))
  1109  
  1110  	gd := ""
  1111  	for os, driver := range d.graphDrivers {
  1112  		if len(gd) > 0 {
  1113  			gd += ", "
  1114  		}
  1115  		gd += driver
  1116  		if len(d.graphDrivers) > 1 {
  1117  			gd = fmt.Sprintf("%s (%s)", gd, os)
  1118  		}
  1119  	}
  1120  	logrus.WithFields(logrus.Fields{
  1121  		"version":        dockerversion.Version,
  1122  		"commit":         dockerversion.GitCommit,
  1123  		"graphdriver(s)": gd,
  1124  	}).Info("Docker daemon")
  1125  
  1126  	return d, nil
  1127  }
  1128  
  1129  // DistributionServices returns services controlling daemon storage
  1130  func (daemon *Daemon) DistributionServices() images.DistributionServices {
  1131  	return daemon.imageService.DistributionServices()
  1132  }
  1133  
  1134  func (daemon *Daemon) waitForStartupDone() {
  1135  	<-daemon.startupDone
  1136  }
  1137  
  1138  func (daemon *Daemon) shutdownContainer(c *container.Container) error {
  1139  	stopTimeout := c.StopTimeout()
  1140  
  1141  	// If container failed to exit in stopTimeout seconds of SIGTERM, then using the force
  1142  	if err := daemon.containerStop(c, stopTimeout); err != nil {
  1143  		return fmt.Errorf("Failed to stop container %s with error: %v", c.ID, err)
  1144  	}
  1145  
  1146  	// Wait without timeout for the container to exit.
  1147  	// Ignore the result.
  1148  	<-c.Wait(context.Background(), container.WaitConditionNotRunning)
  1149  	return nil
  1150  }
  1151  
  1152  // ShutdownTimeout returns the timeout (in seconds) before containers are forcibly
  1153  // killed during shutdown. The default timeout can be configured both on the daemon
  1154  // and per container, and the longest timeout will be used. A grace-period of
  1155  // 5 seconds is added to the configured timeout.
  1156  //
  1157  // A negative (-1) timeout means "indefinitely", which means that containers
  1158  // are not forcibly killed, and the daemon shuts down after all containers exit.
  1159  func (daemon *Daemon) ShutdownTimeout() int {
  1160  	shutdownTimeout := daemon.configStore.ShutdownTimeout
  1161  	if shutdownTimeout < 0 {
  1162  		return -1
  1163  	}
  1164  	if daemon.containers == nil {
  1165  		return shutdownTimeout
  1166  	}
  1167  
  1168  	graceTimeout := 5
  1169  	for _, c := range daemon.containers.List() {
  1170  		stopTimeout := c.StopTimeout()
  1171  		if stopTimeout < 0 {
  1172  			return -1
  1173  		}
  1174  		if stopTimeout+graceTimeout > shutdownTimeout {
  1175  			shutdownTimeout = stopTimeout + graceTimeout
  1176  		}
  1177  	}
  1178  	return shutdownTimeout
  1179  }
  1180  
  1181  // Shutdown stops the daemon.
  1182  func (daemon *Daemon) Shutdown() error {
  1183  	daemon.shutdown = true
  1184  	// Keep mounts and networking running on daemon shutdown if
  1185  	// we are to keep containers running and restore them.
  1186  
  1187  	if daemon.configStore.LiveRestoreEnabled && daemon.containers != nil {
  1188  		// check if there are any running containers, if none we should do some cleanup
  1189  		if ls, err := daemon.Containers(&types.ContainerListOptions{}); len(ls) != 0 || err != nil {
  1190  			// metrics plugins still need some cleanup
  1191  			daemon.cleanupMetricsPlugins()
  1192  			return nil
  1193  		}
  1194  	}
  1195  
  1196  	if daemon.containers != nil {
  1197  		logrus.Debugf("daemon configured with a %d seconds minimum shutdown timeout", daemon.configStore.ShutdownTimeout)
  1198  		logrus.Debugf("start clean shutdown of all containers with a %d seconds timeout...", daemon.ShutdownTimeout())
  1199  		daemon.containers.ApplyAll(func(c *container.Container) {
  1200  			if !c.IsRunning() {
  1201  				return
  1202  			}
  1203  			logrus.Debugf("stopping %s", c.ID)
  1204  			if err := daemon.shutdownContainer(c); err != nil {
  1205  				logrus.Errorf("Stop container error: %v", err)
  1206  				return
  1207  			}
  1208  			if mountid, err := daemon.imageService.GetLayerMountID(c.ID, c.OS); err == nil {
  1209  				daemon.cleanupMountsByID(mountid)
  1210  			}
  1211  			logrus.Debugf("container stopped %s", c.ID)
  1212  		})
  1213  	}
  1214  
  1215  	if daemon.volumes != nil {
  1216  		if err := daemon.volumes.Shutdown(); err != nil {
  1217  			logrus.Errorf("Error shutting down volume store: %v", err)
  1218  		}
  1219  	}
  1220  
  1221  	if daemon.imageService != nil {
  1222  		daemon.imageService.Cleanup()
  1223  	}
  1224  
  1225  	// If we are part of a cluster, clean up cluster's stuff
  1226  	if daemon.clusterProvider != nil {
  1227  		logrus.Debugf("start clean shutdown of cluster resources...")
  1228  		daemon.DaemonLeavesCluster()
  1229  	}
  1230  
  1231  	daemon.cleanupMetricsPlugins()
  1232  
  1233  	// Shutdown plugins after containers and layerstore. Don't change the order.
  1234  	daemon.pluginShutdown()
  1235  
  1236  	// trigger libnetwork Stop only if it's initialized
  1237  	if daemon.netController != nil {
  1238  		daemon.netController.Stop()
  1239  	}
  1240  
  1241  	if daemon.containerdCli != nil {
  1242  		daemon.containerdCli.Close()
  1243  	}
  1244  
  1245  	return daemon.cleanupMounts()
  1246  }
  1247  
  1248  // Mount sets container.BaseFS
  1249  // (is it not set coming in? why is it unset?)
  1250  func (daemon *Daemon) Mount(container *container.Container) error {
  1251  	if container.RWLayer == nil {
  1252  		return errors.New("RWLayer of container " + container.ID + " is unexpectedly nil")
  1253  	}
  1254  	dir, err := container.RWLayer.Mount(container.GetMountLabel())
  1255  	if err != nil {
  1256  		return err
  1257  	}
  1258  	logrus.Debugf("container mounted via layerStore: %v", dir)
  1259  
  1260  	if container.BaseFS != nil && container.BaseFS.Path() != dir.Path() {
  1261  		// The mount path reported by the graph driver should always be trusted on Windows, since the
  1262  		// volume path for a given mounted layer may change over time.  This should only be an error
  1263  		// on non-Windows operating systems.
  1264  		if runtime.GOOS != "windows" {
  1265  			daemon.Unmount(container)
  1266  			return fmt.Errorf("Error: driver %s is returning inconsistent paths for container %s ('%s' then '%s')",
  1267  				daemon.imageService.GraphDriverForOS(container.OS), container.ID, container.BaseFS, dir)
  1268  		}
  1269  	}
  1270  	container.BaseFS = dir // TODO: combine these fields
  1271  	return nil
  1272  }
  1273  
  1274  // Unmount unsets the container base filesystem
  1275  func (daemon *Daemon) Unmount(container *container.Container) error {
  1276  	if container.RWLayer == nil {
  1277  		return errors.New("RWLayer of container " + container.ID + " is unexpectedly nil")
  1278  	}
  1279  	if err := container.RWLayer.Unmount(); err != nil {
  1280  		logrus.Errorf("Error unmounting container %s: %s", container.ID, err)
  1281  		return err
  1282  	}
  1283  
  1284  	return nil
  1285  }
  1286  
  1287  // Subnets return the IPv4 and IPv6 subnets of networks that are manager by Docker.
  1288  func (daemon *Daemon) Subnets() ([]net.IPNet, []net.IPNet) {
  1289  	var v4Subnets []net.IPNet
  1290  	var v6Subnets []net.IPNet
  1291  
  1292  	managedNetworks := daemon.netController.Networks()
  1293  
  1294  	for _, managedNetwork := range managedNetworks {
  1295  		v4infos, v6infos := managedNetwork.Info().IpamInfo()
  1296  		for _, info := range v4infos {
  1297  			if info.IPAMData.Pool != nil {
  1298  				v4Subnets = append(v4Subnets, *info.IPAMData.Pool)
  1299  			}
  1300  		}
  1301  		for _, info := range v6infos {
  1302  			if info.IPAMData.Pool != nil {
  1303  				v6Subnets = append(v6Subnets, *info.IPAMData.Pool)
  1304  			}
  1305  		}
  1306  	}
  1307  
  1308  	return v4Subnets, v6Subnets
  1309  }
  1310  
  1311  // prepareTempDir prepares and returns the default directory to use
  1312  // for temporary files.
  1313  // If it doesn't exist, it is created. If it exists, its content is removed.
  1314  func prepareTempDir(rootDir string, rootIdentity idtools.Identity) (string, error) {
  1315  	var tmpDir string
  1316  	if tmpDir = os.Getenv("DOCKER_TMPDIR"); tmpDir == "" {
  1317  		tmpDir = filepath.Join(rootDir, "tmp")
  1318  		newName := tmpDir + "-old"
  1319  		if err := os.Rename(tmpDir, newName); err == nil {
  1320  			go func() {
  1321  				if err := os.RemoveAll(newName); err != nil {
  1322  					logrus.Warnf("failed to delete old tmp directory: %s", newName)
  1323  				}
  1324  			}()
  1325  		} else if !os.IsNotExist(err) {
  1326  			logrus.Warnf("failed to rename %s for background deletion: %s. Deleting synchronously", tmpDir, err)
  1327  			if err := os.RemoveAll(tmpDir); err != nil {
  1328  				logrus.Warnf("failed to delete old tmp directory: %s", tmpDir)
  1329  			}
  1330  		}
  1331  	}
  1332  	// We don't remove the content of tmpdir if it's not the default,
  1333  	// it may hold things that do not belong to us.
  1334  	return tmpDir, idtools.MkdirAllAndChown(tmpDir, 0700, rootIdentity)
  1335  }
  1336  
  1337  func (daemon *Daemon) setGenericResources(conf *config.Config) error {
  1338  	genericResources, err := config.ParseGenericResources(conf.NodeGenericResources)
  1339  	if err != nil {
  1340  		return err
  1341  	}
  1342  
  1343  	daemon.genericResources = genericResources
  1344  
  1345  	return nil
  1346  }
  1347  
  1348  func setDefaultMtu(conf *config.Config) {
  1349  	// do nothing if the config does not have the default 0 value.
  1350  	if conf.Mtu != 0 {
  1351  		return
  1352  	}
  1353  	conf.Mtu = config.DefaultNetworkMtu
  1354  }
  1355  
  1356  // IsShuttingDown tells whether the daemon is shutting down or not
  1357  func (daemon *Daemon) IsShuttingDown() bool {
  1358  	return daemon.shutdown
  1359  }
  1360  
  1361  // initDiscovery initializes the discovery watcher for this daemon.
  1362  func (daemon *Daemon) initDiscovery(conf *config.Config) error {
  1363  	advertise, err := config.ParseClusterAdvertiseSettings(conf.ClusterStore, conf.ClusterAdvertise)
  1364  	if err != nil {
  1365  		if err == discovery.ErrDiscoveryDisabled {
  1366  			return nil
  1367  		}
  1368  		return err
  1369  	}
  1370  
  1371  	conf.ClusterAdvertise = advertise
  1372  	discoveryWatcher, err := discovery.Init(conf.ClusterStore, conf.ClusterAdvertise, conf.ClusterOpts)
  1373  	if err != nil {
  1374  		return fmt.Errorf("discovery initialization failed (%v)", err)
  1375  	}
  1376  
  1377  	daemon.discoveryWatcher = discoveryWatcher
  1378  	return nil
  1379  }
  1380  
  1381  func isBridgeNetworkDisabled(conf *config.Config) bool {
  1382  	return conf.BridgeConfig.Iface == config.DisableNetworkBridge
  1383  }
  1384  
  1385  func (daemon *Daemon) networkOptions(dconfig *config.Config, pg plugingetter.PluginGetter, activeSandboxes map[string]interface{}) ([]nwconfig.Option, error) {
  1386  	options := []nwconfig.Option{}
  1387  	if dconfig == nil {
  1388  		return options, nil
  1389  	}
  1390  
  1391  	options = append(options, nwconfig.OptionExperimental(dconfig.Experimental))
  1392  	options = append(options, nwconfig.OptionDataDir(dconfig.Root))
  1393  	options = append(options, nwconfig.OptionExecRoot(dconfig.GetExecRoot()))
  1394  
  1395  	dd := runconfig.DefaultDaemonNetworkMode()
  1396  	dn := runconfig.DefaultDaemonNetworkMode().NetworkName()
  1397  	options = append(options, nwconfig.OptionDefaultDriver(string(dd)))
  1398  	options = append(options, nwconfig.OptionDefaultNetwork(dn))
  1399  
  1400  	if strings.TrimSpace(dconfig.ClusterStore) != "" {
  1401  		kv := strings.Split(dconfig.ClusterStore, "://")
  1402  		if len(kv) != 2 {
  1403  			return nil, errors.New("kv store daemon config must be of the form KV-PROVIDER://KV-URL")
  1404  		}
  1405  		options = append(options, nwconfig.OptionKVProvider(kv[0]))
  1406  		options = append(options, nwconfig.OptionKVProviderURL(kv[1]))
  1407  	}
  1408  	if len(dconfig.ClusterOpts) > 0 {
  1409  		options = append(options, nwconfig.OptionKVOpts(dconfig.ClusterOpts))
  1410  	}
  1411  
  1412  	if daemon.discoveryWatcher != nil {
  1413  		options = append(options, nwconfig.OptionDiscoveryWatcher(daemon.discoveryWatcher))
  1414  	}
  1415  
  1416  	if dconfig.ClusterAdvertise != "" {
  1417  		options = append(options, nwconfig.OptionDiscoveryAddress(dconfig.ClusterAdvertise))
  1418  	}
  1419  
  1420  	options = append(options, nwconfig.OptionLabels(dconfig.Labels))
  1421  	options = append(options, driverOptions(dconfig)...)
  1422  
  1423  	if len(dconfig.NetworkConfig.DefaultAddressPools.Value()) > 0 {
  1424  		options = append(options, nwconfig.OptionDefaultAddressPoolConfig(dconfig.NetworkConfig.DefaultAddressPools.Value()))
  1425  	}
  1426  
  1427  	if daemon.configStore != nil && daemon.configStore.LiveRestoreEnabled && len(activeSandboxes) != 0 {
  1428  		options = append(options, nwconfig.OptionActiveSandboxes(activeSandboxes))
  1429  	}
  1430  
  1431  	if pg != nil {
  1432  		options = append(options, nwconfig.OptionPluginGetter(pg))
  1433  	}
  1434  
  1435  	options = append(options, nwconfig.OptionNetworkControlPlaneMTU(dconfig.NetworkControlPlaneMTU))
  1436  
  1437  	return options, nil
  1438  }
  1439  
  1440  // GetCluster returns the cluster
  1441  func (daemon *Daemon) GetCluster() Cluster {
  1442  	return daemon.cluster
  1443  }
  1444  
  1445  // SetCluster sets the cluster
  1446  func (daemon *Daemon) SetCluster(cluster Cluster) {
  1447  	daemon.cluster = cluster
  1448  }
  1449  
  1450  func (daemon *Daemon) pluginShutdown() {
  1451  	manager := daemon.pluginManager
  1452  	// Check for a valid manager object. In error conditions, daemon init can fail
  1453  	// and shutdown called, before plugin manager is initialized.
  1454  	if manager != nil {
  1455  		manager.Shutdown()
  1456  	}
  1457  }
  1458  
  1459  // PluginManager returns current pluginManager associated with the daemon
  1460  func (daemon *Daemon) PluginManager() *plugin.Manager { // set up before daemon to avoid this method
  1461  	return daemon.pluginManager
  1462  }
  1463  
  1464  // PluginGetter returns current pluginStore associated with the daemon
  1465  func (daemon *Daemon) PluginGetter() *plugin.Store {
  1466  	return daemon.PluginStore
  1467  }
  1468  
  1469  // CreateDaemonRoot creates the root for the daemon
  1470  func CreateDaemonRoot(config *config.Config) error {
  1471  	// get the canonical path to the Docker root directory
  1472  	var realRoot string
  1473  	if _, err := os.Stat(config.Root); err != nil && os.IsNotExist(err) {
  1474  		realRoot = config.Root
  1475  	} else {
  1476  		realRoot, err = fileutils.ReadSymlinkedDirectory(config.Root)
  1477  		if err != nil {
  1478  			return fmt.Errorf("Unable to get the full path to root (%s): %s", config.Root, err)
  1479  		}
  1480  	}
  1481  
  1482  	idMapping, err := setupRemappedRoot(config)
  1483  	if err != nil {
  1484  		return err
  1485  	}
  1486  	return setupDaemonRoot(config, realRoot, idMapping.RootPair())
  1487  }
  1488  
  1489  // checkpointAndSave grabs a container lock to safely call container.CheckpointTo
  1490  func (daemon *Daemon) checkpointAndSave(container *container.Container) error {
  1491  	container.Lock()
  1492  	defer container.Unlock()
  1493  	if err := container.CheckpointTo(daemon.containersReplica); err != nil {
  1494  		return fmt.Errorf("Error saving container state: %v", err)
  1495  	}
  1496  	return nil
  1497  }
  1498  
  1499  // because the CLI sends a -1 when it wants to unset the swappiness value
  1500  // we need to clear it on the server side
  1501  func fixMemorySwappiness(resources *containertypes.Resources) {
  1502  	if resources.MemorySwappiness != nil && *resources.MemorySwappiness == -1 {
  1503  		resources.MemorySwappiness = nil
  1504  	}
  1505  }
  1506  
  1507  // GetAttachmentStore returns current attachment store associated with the daemon
  1508  func (daemon *Daemon) GetAttachmentStore() *network.AttachmentStore {
  1509  	return &daemon.attachmentStore
  1510  }
  1511  
  1512  // IdentityMapping returns uid/gid mapping or a SID (in the case of Windows) for the builder
  1513  func (daemon *Daemon) IdentityMapping() *idtools.IdentityMapping {
  1514  	return daemon.idMapping
  1515  }
  1516  
  1517  // ImageService returns the Daemon's ImageService
  1518  func (daemon *Daemon) ImageService() *images.ImageService {
  1519  	return daemon.imageService
  1520  }
  1521  
  1522  // BuilderBackend returns the backend used by builder
  1523  func (daemon *Daemon) BuilderBackend() builder.Backend {
  1524  	return struct {
  1525  		*Daemon
  1526  		*images.ImageService
  1527  	}{daemon, daemon.imageService}
  1528  }