github.com/uppal0016/docker_new@v0.0.0-20240123060250-1c98be13ac2c/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
     7  
     8  import (
     9  	"fmt"
    10  	"io"
    11  	"io/ioutil"
    12  	"net"
    13  	"os"
    14  	"path"
    15  	"path/filepath"
    16  	"runtime"
    17  	"strings"
    18  	"sync"
    19  	"syscall"
    20  	"time"
    21  
    22  	"github.com/Sirupsen/logrus"
    23  	containerd "github.com/docker/containerd/api/grpc/types"
    24  	"github.com/docker/docker/api"
    25  	"github.com/docker/docker/builder"
    26  	"github.com/docker/docker/container"
    27  	"github.com/docker/docker/daemon/events"
    28  	"github.com/docker/docker/daemon/exec"
    29  	"github.com/docker/docker/errors"
    30  	"github.com/docker/engine-api/types"
    31  	containertypes "github.com/docker/engine-api/types/container"
    32  	eventtypes "github.com/docker/engine-api/types/events"
    33  	"github.com/docker/engine-api/types/filters"
    34  	networktypes "github.com/docker/engine-api/types/network"
    35  	registrytypes "github.com/docker/engine-api/types/registry"
    36  	"github.com/docker/engine-api/types/strslice"
    37  	// register graph drivers
    38  	_ "github.com/docker/docker/daemon/graphdriver/register"
    39  	"github.com/docker/docker/daemon/logger"
    40  	"github.com/docker/docker/daemon/network"
    41  	dmetadata "github.com/docker/docker/distribution/metadata"
    42  	"github.com/docker/docker/distribution/xfer"
    43  	"github.com/docker/docker/dockerversion"
    44  	"github.com/docker/docker/image"
    45  	"github.com/docker/docker/image/tarexport"
    46  	"github.com/docker/docker/layer"
    47  	"github.com/docker/docker/libcontainerd"
    48  	"github.com/docker/docker/migrate/v1"
    49  	"github.com/docker/docker/pkg/archive"
    50  	"github.com/docker/docker/pkg/fileutils"
    51  	"github.com/docker/docker/pkg/graphdb"
    52  	"github.com/docker/docker/pkg/idtools"
    53  	"github.com/docker/docker/pkg/namesgenerator"
    54  	"github.com/docker/docker/pkg/progress"
    55  	"github.com/docker/docker/pkg/registrar"
    56  	"github.com/docker/docker/pkg/signal"
    57  	"github.com/docker/docker/pkg/streamformatter"
    58  	"github.com/docker/docker/pkg/stringid"
    59  	"github.com/docker/docker/pkg/sysinfo"
    60  	"github.com/docker/docker/pkg/system"
    61  	"github.com/docker/docker/pkg/truncindex"
    62  	"github.com/docker/docker/reference"
    63  	"github.com/docker/docker/registry"
    64  	"github.com/docker/docker/runconfig"
    65  	"github.com/docker/docker/utils"
    66  	volumedrivers "github.com/docker/docker/volume/drivers"
    67  	"github.com/docker/docker/volume/local"
    68  	"github.com/docker/docker/volume/store"
    69  	"github.com/docker/go-connections/nat"
    70  	"github.com/docker/libnetwork"
    71  	nwconfig "github.com/docker/libnetwork/config"
    72  	"github.com/docker/libtrust"
    73  	"golang.org/x/net/context"
    74  )
    75  
    76  const (
    77  	// maxDownloadConcurrency is the maximum number of downloads that
    78  	// may take place at a time for each pull.
    79  	maxDownloadConcurrency = 3
    80  	// maxUploadConcurrency is the maximum number of uploads that
    81  	// may take place at a time for each push.
    82  	maxUploadConcurrency = 5
    83  )
    84  
    85  var (
    86  	validContainerNameChars   = utils.RestrictedNameChars
    87  	validContainerNamePattern = utils.RestrictedNamePattern
    88  
    89  	errSystemNotSupported = fmt.Errorf("The Docker daemon is not supported on this platform.")
    90  )
    91  
    92  // ErrImageDoesNotExist is error returned when no image can be found for a reference.
    93  type ErrImageDoesNotExist struct {
    94  	RefOrID string
    95  }
    96  
    97  func (e ErrImageDoesNotExist) Error() string {
    98  	return fmt.Sprintf("no such id: %s", e.RefOrID)
    99  }
   100  
   101  // Daemon holds information about the Docker daemon.
   102  type Daemon struct {
   103  	ID                        string
   104  	repository                string
   105  	containers                container.Store
   106  	execCommands              *exec.Store
   107  	referenceStore            reference.Store
   108  	downloadManager           *xfer.LayerDownloadManager
   109  	uploadManager             *xfer.LayerUploadManager
   110  	distributionMetadataStore dmetadata.Store
   111  	trustKey                  libtrust.PrivateKey
   112  	idIndex                   *truncindex.TruncIndex
   113  	configStore               *Config
   114  	statsCollector            *statsCollector
   115  	defaultLogConfig          containertypes.LogConfig
   116  	RegistryService           *registry.Service
   117  	EventsService             *events.Events
   118  	netController             libnetwork.NetworkController
   119  	volumes                   *store.VolumeStore
   120  	discoveryWatcher          discoveryReloader
   121  	root                      string
   122  	seccompEnabled            bool
   123  	shutdown                  bool
   124  	uidMaps                   []idtools.IDMap
   125  	gidMaps                   []idtools.IDMap
   126  	layerStore                layer.Store
   127  	imageStore                image.Store
   128  	nameIndex                 *registrar.Registrar
   129  	linkIndex                 *linkIndex
   130  	containerd                libcontainerd.Client
   131  	defaultIsolation          containertypes.Isolation // Default isolation mode on Windows
   132  }
   133  
   134  // GetContainer looks for a container using the provided information, which could be
   135  // one of the following inputs from the caller:
   136  //  - A full container ID, which will exact match a container in daemon's list
   137  //  - A container name, which will only exact match via the GetByName() function
   138  //  - A partial container ID prefix (e.g. short ID) of any length that is
   139  //    unique enough to only return a single container object
   140  //  If none of these searches succeed, an error is returned
   141  func (daemon *Daemon) GetContainer(prefixOrName string) (*container.Container, error) {
   142  	if containerByID := daemon.containers.Get(prefixOrName); containerByID != nil {
   143  		// prefix is an exact match to a full container ID
   144  		return containerByID, nil
   145  	}
   146  
   147  	// GetByName will match only an exact name provided; we ignore errors
   148  	if containerByName, _ := daemon.GetByName(prefixOrName); containerByName != nil {
   149  		// prefix is an exact match to a full container Name
   150  		return containerByName, nil
   151  	}
   152  
   153  	containerID, indexError := daemon.idIndex.Get(prefixOrName)
   154  	if indexError != nil {
   155  		// When truncindex defines an error type, use that instead
   156  		if indexError == truncindex.ErrNotExist {
   157  			err := fmt.Errorf("No such container: %s", prefixOrName)
   158  			return nil, errors.NewRequestNotFoundError(err)
   159  		}
   160  		return nil, indexError
   161  	}
   162  	return daemon.containers.Get(containerID), nil
   163  }
   164  
   165  // Exists returns a true if a container of the specified ID or name exists,
   166  // false otherwise.
   167  func (daemon *Daemon) Exists(id string) bool {
   168  	c, _ := daemon.GetContainer(id)
   169  	return c != nil
   170  }
   171  
   172  // IsPaused returns a bool indicating if the specified container is paused.
   173  func (daemon *Daemon) IsPaused(id string) bool {
   174  	c, _ := daemon.GetContainer(id)
   175  	return c.State.IsPaused()
   176  }
   177  
   178  func (daemon *Daemon) containerRoot(id string) string {
   179  	return filepath.Join(daemon.repository, id)
   180  }
   181  
   182  // Load reads the contents of a container from disk
   183  // This is typically done at startup.
   184  func (daemon *Daemon) load(id string) (*container.Container, error) {
   185  	container := daemon.newBaseContainer(id)
   186  
   187  	if err := container.FromDisk(); err != nil {
   188  		return nil, err
   189  	}
   190  
   191  	if container.ID != id {
   192  		return container, fmt.Errorf("Container %s is stored at %s", container.ID, id)
   193  	}
   194  
   195  	return container, nil
   196  }
   197  
   198  func (daemon *Daemon) registerName(container *container.Container) error {
   199  	if daemon.Exists(container.ID) {
   200  		return fmt.Errorf("Container is already loaded")
   201  	}
   202  	if err := validateID(container.ID); err != nil {
   203  		return err
   204  	}
   205  	if container.Name == "" {
   206  		name, err := daemon.generateNewName(container.ID)
   207  		if err != nil {
   208  			return err
   209  		}
   210  		container.Name = name
   211  
   212  		if err := container.ToDiskLocking(); err != nil {
   213  			logrus.Errorf("Error saving container name to disk: %v", err)
   214  		}
   215  	}
   216  	return daemon.nameIndex.Reserve(container.Name, container.ID)
   217  }
   218  
   219  // Register makes a container object usable by the daemon as <container.ID>
   220  func (daemon *Daemon) Register(c *container.Container) error {
   221  	// Attach to stdout and stderr
   222  	if c.Config.OpenStdin {
   223  		c.NewInputPipes()
   224  	} else {
   225  		c.NewNopInputPipe()
   226  	}
   227  
   228  	daemon.containers.Add(c.ID, c)
   229  	daemon.idIndex.Add(c.ID)
   230  
   231  	return nil
   232  }
   233  
   234  func (daemon *Daemon) restore() error {
   235  	var (
   236  		debug         = utils.IsDebugEnabled()
   237  		currentDriver = daemon.GraphDriverName()
   238  		containers    = make(map[string]*container.Container)
   239  	)
   240  
   241  	if !debug {
   242  		logrus.Info("Loading containers: start.")
   243  	}
   244  	dir, err := ioutil.ReadDir(daemon.repository)
   245  	if err != nil {
   246  		return err
   247  	}
   248  
   249  	for _, v := range dir {
   250  		id := v.Name()
   251  		container, err := daemon.load(id)
   252  		if !debug && logrus.GetLevel() == logrus.InfoLevel {
   253  			fmt.Print(".")
   254  		}
   255  		if err != nil {
   256  			logrus.Errorf("Failed to load container %v: %v", id, err)
   257  			continue
   258  		}
   259  
   260  		// Ignore the container if it does not support the current driver being used by the graph
   261  		if (container.Driver == "" && currentDriver == "aufs") || container.Driver == currentDriver {
   262  			rwlayer, err := daemon.layerStore.GetRWLayer(container.ID)
   263  			if err != nil {
   264  				logrus.Errorf("Failed to load container mount %v: %v", id, err)
   265  				continue
   266  			}
   267  			container.RWLayer = rwlayer
   268  			logrus.Debugf("Loaded container %v", container.ID)
   269  
   270  			containers[container.ID] = container
   271  		} else {
   272  			logrus.Debugf("Cannot load container %s because it was created with another graph driver.", container.ID)
   273  		}
   274  	}
   275  
   276  	var migrateLegacyLinks bool
   277  	restartContainers := make(map[*container.Container]chan struct{})
   278  	for _, c := range containers {
   279  		if err := daemon.registerName(c); err != nil {
   280  			logrus.Errorf("Failed to register container %s: %s", c.ID, err)
   281  			continue
   282  		}
   283  		if err := daemon.Register(c); err != nil {
   284  			logrus.Errorf("Failed to register container %s: %s", c.ID, err)
   285  			continue
   286  		}
   287  	}
   288  	var wg sync.WaitGroup
   289  	var mapLock sync.Mutex
   290  	for _, c := range containers {
   291  		wg.Add(1)
   292  		go func(c *container.Container) {
   293  			defer wg.Done()
   294  			rm := c.RestartManager(false)
   295  			if c.IsRunning() || c.IsPaused() {
   296  				// Fix activityCount such that graph mounts can be unmounted later
   297  				if err := daemon.layerStore.ReinitRWLayer(c.RWLayer); err != nil {
   298  					logrus.Errorf("Failed to ReinitRWLayer for %s due to %s", c.ID, err)
   299  					return
   300  				}
   301  				if err := daemon.containerd.Restore(c.ID, libcontainerd.WithRestartManager(rm)); err != nil {
   302  					logrus.Errorf("Failed to restore with containerd: %q", err)
   303  					return
   304  				}
   305  			}
   306  			// fixme: only if not running
   307  			// get list of containers we need to restart
   308  			if daemon.configStore.AutoRestart && !c.IsRunning() && !c.IsPaused() && c.ShouldRestart() {
   309  				mapLock.Lock()
   310  				restartContainers[c] = make(chan struct{})
   311  				mapLock.Unlock()
   312  			}
   313  
   314  			// if c.hostConfig.Links is nil (not just empty), then it is using the old sqlite links and needs to be migrated
   315  			if c.HostConfig != nil && c.HostConfig.Links == nil {
   316  				migrateLegacyLinks = true
   317  			}
   318  		}(c)
   319  	}
   320  	wg.Wait()
   321  
   322  	// migrate any legacy links from sqlite
   323  	linkdbFile := filepath.Join(daemon.root, "linkgraph.db")
   324  	var legacyLinkDB *graphdb.Database
   325  	if migrateLegacyLinks {
   326  		legacyLinkDB, err = graphdb.NewSqliteConn(linkdbFile)
   327  		if err != nil {
   328  			return fmt.Errorf("error connecting to legacy link graph DB %s, container links may be lost: %v", linkdbFile, err)
   329  		}
   330  		defer legacyLinkDB.Close()
   331  	}
   332  
   333  	// Now that all the containers are registered, register the links
   334  	for _, c := range containers {
   335  		if migrateLegacyLinks {
   336  			if err := daemon.migrateLegacySqliteLinks(legacyLinkDB, c); err != nil {
   337  				return err
   338  			}
   339  		}
   340  		if err := daemon.registerLinks(c, c.HostConfig); err != nil {
   341  			logrus.Errorf("failed to register link for container %s: %v", c.ID, err)
   342  		}
   343  	}
   344  
   345  	group := sync.WaitGroup{}
   346  	for c, notifier := range restartContainers {
   347  		group.Add(1)
   348  
   349  		go func(c *container.Container, chNotify chan struct{}) {
   350  			defer group.Done()
   351  
   352  			logrus.Debugf("Starting container %s", c.ID)
   353  
   354  			// ignore errors here as this is a best effort to wait for children to be
   355  			//   running before we try to start the container
   356  			children := daemon.children(c)
   357  			timeout := time.After(5 * time.Second)
   358  			for _, child := range children {
   359  				if notifier, exists := restartContainers[child]; exists {
   360  					select {
   361  					case <-notifier:
   362  					case <-timeout:
   363  					}
   364  				}
   365  			}
   366  			if err := daemon.containerStart(c); err != nil {
   367  				logrus.Errorf("Failed to start container %s: %s", c.ID, err)
   368  			}
   369  			close(chNotify)
   370  		}(c, notifier)
   371  
   372  	}
   373  	group.Wait()
   374  
   375  	// any containers that were started above would already have had this done,
   376  	// however we need to now prepare the mountpoints for the rest of the containers as well.
   377  	// This shouldn't cause any issue running on the containers that already had this run.
   378  	// This must be run after any containers with a restart policy so that containerized plugins
   379  	// can have a chance to be running before we try to initialize them.
   380  	for _, c := range containers {
   381  		// if the container has restart policy, do not
   382  		// prepare the mountpoints since it has been done on restarting.
   383  		// This is to speed up the daemon start when a restart container
   384  		// has a volume and the volume dirver is not available.
   385  		if _, ok := restartContainers[c]; ok {
   386  			continue
   387  		}
   388  		group.Add(1)
   389  		go func(c *container.Container) {
   390  			defer group.Done()
   391  			if err := daemon.prepareMountPoints(c); err != nil {
   392  				logrus.Error(err)
   393  			}
   394  		}(c)
   395  	}
   396  
   397  	group.Wait()
   398  
   399  	if !debug {
   400  		if logrus.GetLevel() == logrus.InfoLevel {
   401  			fmt.Println()
   402  		}
   403  		logrus.Info("Loading containers: done.")
   404  	}
   405  
   406  	return nil
   407  }
   408  
   409  func (daemon *Daemon) mergeAndVerifyConfig(config *containertypes.Config, img *image.Image) error {
   410  	if img != nil && img.Config != nil {
   411  		if err := merge(config, img.Config); err != nil {
   412  			return err
   413  		}
   414  	}
   415  	if len(config.Entrypoint) == 0 && len(config.Cmd) == 0 {
   416  		return fmt.Errorf("No command specified")
   417  	}
   418  	return nil
   419  }
   420  
   421  func (daemon *Daemon) generateIDAndName(name string) (string, string, error) {
   422  	var (
   423  		err error
   424  		id  = stringid.GenerateNonCryptoID()
   425  	)
   426  
   427  	if name == "" {
   428  		if name, err = daemon.generateNewName(id); err != nil {
   429  			return "", "", err
   430  		}
   431  		return id, name, nil
   432  	}
   433  
   434  	if name, err = daemon.reserveName(id, name); err != nil {
   435  		return "", "", err
   436  	}
   437  
   438  	return id, name, nil
   439  }
   440  
   441  func (daemon *Daemon) reserveName(id, name string) (string, error) {
   442  	if !validContainerNamePattern.MatchString(name) {
   443  		return "", fmt.Errorf("Invalid container name (%s), only %s are allowed", name, validContainerNameChars)
   444  	}
   445  	if name[0] != '/' {
   446  		name = "/" + name
   447  	}
   448  
   449  	if err := daemon.nameIndex.Reserve(name, id); err != nil {
   450  		if err == registrar.ErrNameReserved {
   451  			id, err := daemon.nameIndex.Get(name)
   452  			if err != nil {
   453  				logrus.Errorf("got unexpected error while looking up reserved name: %v", err)
   454  				return "", err
   455  			}
   456  			return "", fmt.Errorf("Conflict. The name %q is already in use by container %s. You have to remove (or rename) that container to be able to reuse that name.", name, id)
   457  		}
   458  		return "", fmt.Errorf("error reserving name: %s, error: %v", name, err)
   459  	}
   460  	return name, nil
   461  }
   462  
   463  func (daemon *Daemon) releaseName(name string) {
   464  	daemon.nameIndex.Release(name)
   465  }
   466  
   467  func (daemon *Daemon) generateNewName(id string) (string, error) {
   468  	var name string
   469  	for i := 0; i < 6; i++ {
   470  		name = namesgenerator.GetRandomName(i)
   471  		if name[0] != '/' {
   472  			name = "/" + name
   473  		}
   474  
   475  		if err := daemon.nameIndex.Reserve(name, id); err != nil {
   476  			if err == registrar.ErrNameReserved {
   477  				continue
   478  			}
   479  			return "", err
   480  		}
   481  		return name, nil
   482  	}
   483  
   484  	name = "/" + stringid.TruncateID(id)
   485  	if err := daemon.nameIndex.Reserve(name, id); err != nil {
   486  		return "", err
   487  	}
   488  	return name, nil
   489  }
   490  
   491  func (daemon *Daemon) generateHostname(id string, config *containertypes.Config) {
   492  	// Generate default hostname
   493  	if config.Hostname == "" {
   494  		config.Hostname = id[:12]
   495  	}
   496  }
   497  
   498  func (daemon *Daemon) getEntrypointAndArgs(configEntrypoint strslice.StrSlice, configCmd strslice.StrSlice) (string, []string) {
   499  	if len(configEntrypoint) != 0 {
   500  		return configEntrypoint[0], append(configEntrypoint[1:], configCmd...)
   501  	}
   502  	return configCmd[0], configCmd[1:]
   503  }
   504  
   505  func (daemon *Daemon) newContainer(name string, config *containertypes.Config, imgID image.ID) (*container.Container, error) {
   506  	var (
   507  		id             string
   508  		err            error
   509  		noExplicitName = name == ""
   510  	)
   511  	id, name, err = daemon.generateIDAndName(name)
   512  	if err != nil {
   513  		return nil, err
   514  	}
   515  
   516  	daemon.generateHostname(id, config)
   517  	entrypoint, args := daemon.getEntrypointAndArgs(config.Entrypoint, config.Cmd)
   518  
   519  	base := daemon.newBaseContainer(id)
   520  	base.Created = time.Now().UTC()
   521  	base.Path = entrypoint
   522  	base.Args = args //FIXME: de-duplicate from config
   523  	base.Config = config
   524  	base.HostConfig = &containertypes.HostConfig{}
   525  	base.ImageID = imgID
   526  	base.NetworkSettings = &network.Settings{IsAnonymousEndpoint: noExplicitName}
   527  	base.Name = name
   528  	base.Driver = daemon.GraphDriverName()
   529  
   530  	return base, err
   531  }
   532  
   533  // GetByName returns a container given a name.
   534  func (daemon *Daemon) GetByName(name string) (*container.Container, error) {
   535  	fullName := name
   536  	if name[0] != '/' {
   537  		fullName = "/" + name
   538  	}
   539  	id, err := daemon.nameIndex.Get(fullName)
   540  	if err != nil {
   541  		return nil, fmt.Errorf("Could not find entity for %s", name)
   542  	}
   543  	e := daemon.containers.Get(id)
   544  	if e == nil {
   545  		return nil, fmt.Errorf("Could not find container for entity id %s", id)
   546  	}
   547  	return e, nil
   548  }
   549  
   550  // SubscribeToEvents returns the currently record of events, a channel to stream new events from, and a function to cancel the stream of events.
   551  func (daemon *Daemon) SubscribeToEvents(since, sinceNano int64, filter filters.Args) ([]eventtypes.Message, chan interface{}) {
   552  	ef := events.NewFilter(filter)
   553  	return daemon.EventsService.SubscribeTopic(since, sinceNano, ef)
   554  }
   555  
   556  // UnsubscribeFromEvents stops the event subscription for a client by closing the
   557  // channel where the daemon sends events to.
   558  func (daemon *Daemon) UnsubscribeFromEvents(listener chan interface{}) {
   559  	daemon.EventsService.Evict(listener)
   560  }
   561  
   562  // GetLabels for a container or image id
   563  func (daemon *Daemon) GetLabels(id string) map[string]string {
   564  	// TODO: TestCase
   565  	container := daemon.containers.Get(id)
   566  	if container != nil {
   567  		return container.Config.Labels
   568  	}
   569  
   570  	img, err := daemon.GetImage(id)
   571  	if err == nil {
   572  		return img.ContainerConfig.Labels
   573  	}
   574  	return nil
   575  }
   576  
   577  func (daemon *Daemon) children(c *container.Container) map[string]*container.Container {
   578  	return daemon.linkIndex.children(c)
   579  }
   580  
   581  // parents returns the names of the parent containers of the container
   582  // with the given name.
   583  func (daemon *Daemon) parents(c *container.Container) map[string]*container.Container {
   584  	return daemon.linkIndex.parents(c)
   585  }
   586  
   587  func (daemon *Daemon) registerLink(parent, child *container.Container, alias string) error {
   588  	fullName := path.Join(parent.Name, alias)
   589  	if err := daemon.nameIndex.Reserve(fullName, child.ID); err != nil {
   590  		if err == registrar.ErrNameReserved {
   591  			logrus.Warnf("error registering link for %s, to %s, as alias %s, ignoring: %v", parent.ID, child.ID, alias, err)
   592  			return nil
   593  		}
   594  		return err
   595  	}
   596  	daemon.linkIndex.link(parent, child, fullName)
   597  	return nil
   598  }
   599  
   600  // NewDaemon sets up everything for the daemon to be able to service
   601  // requests from the webserver.
   602  func NewDaemon(config *Config, registryService *registry.Service, containerdRemote libcontainerd.Remote) (daemon *Daemon, err error) {
   603  	setDefaultMtu(config)
   604  
   605  	// Ensure we have compatible and valid configuration options
   606  	if err := verifyDaemonSettings(config); err != nil {
   607  		return nil, err
   608  	}
   609  
   610  	// Do we have a disabled network?
   611  	config.DisableBridge = isBridgeNetworkDisabled(config)
   612  
   613  	// Verify the platform is supported as a daemon
   614  	if !platformSupported {
   615  		return nil, errSystemNotSupported
   616  	}
   617  
   618  	// Validate platform-specific requirements
   619  	if err := checkSystem(); err != nil {
   620  		return nil, err
   621  	}
   622  
   623  	// set up SIGUSR1 handler on Unix-like systems, or a Win32 global event
   624  	// on Windows to dump Go routine stacks
   625  	setupDumpStackTrap()
   626  
   627  	uidMaps, gidMaps, err := setupRemappedRoot(config)
   628  	if err != nil {
   629  		return nil, err
   630  	}
   631  	rootUID, rootGID, err := idtools.GetRootUIDGID(uidMaps, gidMaps)
   632  	if err != nil {
   633  		return nil, err
   634  	}
   635  
   636  	// get the canonical path to the Docker root directory
   637  	var realRoot string
   638  	if _, err := os.Stat(config.Root); err != nil && os.IsNotExist(err) {
   639  		realRoot = config.Root
   640  	} else {
   641  		realRoot, err = fileutils.ReadSymlinkedDirectory(config.Root)
   642  		if err != nil {
   643  			return nil, fmt.Errorf("Unable to get the full path to root (%s): %s", config.Root, err)
   644  		}
   645  	}
   646  
   647  	if err = setupDaemonRoot(config, realRoot, rootUID, rootGID); err != nil {
   648  		return nil, err
   649  	}
   650  
   651  	// set up the tmpDir to use a canonical path
   652  	tmp, err := tempDir(config.Root, rootUID, rootGID)
   653  	if err != nil {
   654  		return nil, fmt.Errorf("Unable to get the TempDir under %s: %s", config.Root, err)
   655  	}
   656  	realTmp, err := fileutils.ReadSymlinkedDirectory(tmp)
   657  	if err != nil {
   658  		return nil, fmt.Errorf("Unable to get the full path to the TempDir (%s): %s", tmp, err)
   659  	}
   660  	os.Setenv("TMPDIR", realTmp)
   661  
   662  	d := &Daemon{configStore: config}
   663  	// Ensure the daemon is properly shutdown if there is a failure during
   664  	// initialization
   665  	defer func() {
   666  		if err != nil {
   667  			if err := d.Shutdown(); err != nil {
   668  				logrus.Error(err)
   669  			}
   670  		}
   671  	}()
   672  
   673  	// Set the default isolation mode (only applicable on Windows)
   674  	if err := d.setDefaultIsolation(); err != nil {
   675  		return nil, fmt.Errorf("error setting default isolation mode: %v", err)
   676  	}
   677  
   678  	// Verify logging driver type
   679  	if config.LogConfig.Type != "none" {
   680  		if _, err := logger.GetLogDriver(config.LogConfig.Type); err != nil {
   681  			return nil, fmt.Errorf("error finding the logging driver: %v", err)
   682  		}
   683  	}
   684  	logrus.Debugf("Using default logging driver %s", config.LogConfig.Type)
   685  
   686  	if err := configureMaxThreads(config); err != nil {
   687  		logrus.Warnf("Failed to configure golang's threads limit: %v", err)
   688  	}
   689  
   690  	installDefaultAppArmorProfile()
   691  	daemonRepo := filepath.Join(config.Root, "containers")
   692  	if err := idtools.MkdirAllAs(daemonRepo, 0700, rootUID, rootGID); err != nil && !os.IsExist(err) {
   693  		return nil, err
   694  	}
   695  
   696  	driverName := os.Getenv("DOCKER_DRIVER")
   697  	if driverName == "" {
   698  		driverName = config.GraphDriver
   699  	}
   700  	d.layerStore, err = layer.NewStoreFromOptions(layer.StoreOptions{
   701  		StorePath:                 config.Root,
   702  		MetadataStorePathTemplate: filepath.Join(config.Root, "image", "%s", "layerdb"),
   703  		GraphDriver:               driverName,
   704  		GraphDriverOptions:        config.GraphOptions,
   705  		UIDMaps:                   uidMaps,
   706  		GIDMaps:                   gidMaps,
   707  	})
   708  	if err != nil {
   709  		return nil, err
   710  	}
   711  
   712  	graphDriver := d.layerStore.DriverName()
   713  	imageRoot := filepath.Join(config.Root, "image", graphDriver)
   714  
   715  	// Configure and validate the kernels security support
   716  	if err := configureKernelSecuritySupport(config, graphDriver); err != nil {
   717  		return nil, err
   718  	}
   719  
   720  	d.downloadManager = xfer.NewLayerDownloadManager(d.layerStore, maxDownloadConcurrency)
   721  	d.uploadManager = xfer.NewLayerUploadManager(maxUploadConcurrency)
   722  
   723  	ifs, err := image.NewFSStoreBackend(filepath.Join(imageRoot, "imagedb"))
   724  	if err != nil {
   725  		return nil, err
   726  	}
   727  
   728  	d.imageStore, err = image.NewImageStore(ifs, d.layerStore)
   729  	if err != nil {
   730  		return nil, err
   731  	}
   732  
   733  	// Configure the volumes driver
   734  	volStore, err := configureVolumes(config, rootUID, rootGID)
   735  	if err != nil {
   736  		return nil, err
   737  	}
   738  
   739  	trustKey, err := api.LoadOrCreateTrustKey(config.TrustKeyPath)
   740  	if err != nil {
   741  		return nil, err
   742  	}
   743  
   744  	trustDir := filepath.Join(config.Root, "trust")
   745  
   746  	if err := system.MkdirAll(trustDir, 0700); err != nil {
   747  		return nil, err
   748  	}
   749  
   750  	distributionMetadataStore, err := dmetadata.NewFSMetadataStore(filepath.Join(imageRoot, "distribution"))
   751  	if err != nil {
   752  		return nil, err
   753  	}
   754  
   755  	eventsService := events.New()
   756  
   757  	referenceStore, err := reference.NewReferenceStore(filepath.Join(imageRoot, "repositories.json"))
   758  	if err != nil {
   759  		return nil, fmt.Errorf("Couldn't create Tag store repositories: %s", err)
   760  	}
   761  
   762  	if err := restoreCustomImage(d.imageStore, d.layerStore, referenceStore); err != nil {
   763  		return nil, fmt.Errorf("Couldn't restore custom images: %s", err)
   764  	}
   765  
   766  	migrationStart := time.Now()
   767  	if err := v1.Migrate(config.Root, graphDriver, d.layerStore, d.imageStore, referenceStore, distributionMetadataStore); err != nil {
   768  		logrus.Errorf("Graph migration failed: %q. Your old graph data was found to be too inconsistent for upgrading to content-addressable storage. Some of the old data was probably not upgraded. We recommend starting over with a clean storage directory if possible.", err)
   769  	}
   770  	logrus.Infof("Graph migration to content-addressability took %.2f seconds", time.Since(migrationStart).Seconds())
   771  
   772  	// Discovery is only enabled when the daemon is launched with an address to advertise.  When
   773  	// initialized, the daemon is registered and we can store the discovery backend as its read-only
   774  	if err := d.initDiscovery(config); err != nil {
   775  		return nil, err
   776  	}
   777  
   778  	d.netController, err = d.initNetworkController(config)
   779  	if err != nil {
   780  		return nil, fmt.Errorf("Error initializing network controller: %v", err)
   781  	}
   782  
   783  	sysInfo := sysinfo.New(false)
   784  	// Check if Devices cgroup is mounted, it is hard requirement for container security,
   785  	// on Linux/FreeBSD.
   786  	if runtime.GOOS != "windows" && !sysInfo.CgroupDevicesEnabled {
   787  		return nil, fmt.Errorf("Devices cgroup isn't mounted")
   788  	}
   789  
   790  	d.ID = trustKey.PublicKey().KeyID()
   791  	d.repository = daemonRepo
   792  	d.containers = container.NewMemoryStore()
   793  	d.execCommands = exec.NewStore()
   794  	d.referenceStore = referenceStore
   795  	d.distributionMetadataStore = distributionMetadataStore
   796  	d.trustKey = trustKey
   797  	d.idIndex = truncindex.NewTruncIndex([]string{})
   798  	d.statsCollector = d.newStatsCollector(1 * time.Second)
   799  	d.defaultLogConfig = containertypes.LogConfig{
   800  		Type:   config.LogConfig.Type,
   801  		Config: config.LogConfig.Config,
   802  	}
   803  	d.RegistryService = registryService
   804  	d.EventsService = eventsService
   805  	d.volumes = volStore
   806  	d.root = config.Root
   807  	d.uidMaps = uidMaps
   808  	d.gidMaps = gidMaps
   809  	d.seccompEnabled = sysInfo.Seccomp
   810  
   811  	d.nameIndex = registrar.NewRegistrar()
   812  	d.linkIndex = newLinkIndex()
   813  
   814  	go d.execCommandGC()
   815  
   816  	d.containerd, err = containerdRemote.Client(d)
   817  	if err != nil {
   818  		return nil, err
   819  	}
   820  
   821  	if err := d.restore(); err != nil {
   822  		return nil, err
   823  	}
   824  
   825  	return d, nil
   826  }
   827  
   828  func (daemon *Daemon) shutdownContainer(c *container.Container) error {
   829  	// TODO(windows): Handle docker restart with paused containers
   830  	if c.IsPaused() {
   831  		// To terminate a process in freezer cgroup, we should send
   832  		// SIGTERM to this process then unfreeze it, and the process will
   833  		// force to terminate immediately.
   834  		logrus.Debugf("Found container %s is paused, sending SIGTERM before unpause it", c.ID)
   835  		sig, ok := signal.SignalMap["TERM"]
   836  		if !ok {
   837  			return fmt.Errorf("System doesn not support SIGTERM")
   838  		}
   839  		if err := daemon.kill(c, int(sig)); err != nil {
   840  			return fmt.Errorf("sending SIGTERM to container %s with error: %v", c.ID, err)
   841  		}
   842  		if err := daemon.containerUnpause(c); err != nil {
   843  			return fmt.Errorf("Failed to unpause container %s with error: %v", c.ID, err)
   844  		}
   845  		if _, err := c.WaitStop(10 * time.Second); err != nil {
   846  			logrus.Debugf("container %s failed to exit in 10 second of SIGTERM, sending SIGKILL to force", c.ID)
   847  			sig, ok := signal.SignalMap["KILL"]
   848  			if !ok {
   849  				return fmt.Errorf("System does not support SIGKILL")
   850  			}
   851  			if err := daemon.kill(c, int(sig)); err != nil {
   852  				logrus.Errorf("Failed to SIGKILL container %s", c.ID)
   853  			}
   854  			c.WaitStop(-1 * time.Second)
   855  			return err
   856  		}
   857  	}
   858  	// If container failed to exit in 10 seconds of SIGTERM, then using the force
   859  	if err := daemon.containerStop(c, 10); err != nil {
   860  		return fmt.Errorf("Stop container %s with error: %v", c.ID, err)
   861  	}
   862  
   863  	c.WaitStop(-1 * time.Second)
   864  	return nil
   865  }
   866  
   867  // Shutdown stops the daemon.
   868  func (daemon *Daemon) Shutdown() error {
   869  	daemon.shutdown = true
   870  	if daemon.containers != nil {
   871  		logrus.Debug("starting clean shutdown of all containers...")
   872  		daemon.containers.ApplyAll(func(c *container.Container) {
   873  			if !c.IsRunning() {
   874  				return
   875  			}
   876  			logrus.Debugf("stopping %s", c.ID)
   877  			if err := daemon.shutdownContainer(c); err != nil {
   878  				logrus.Errorf("Stop container error: %v", err)
   879  				return
   880  			}
   881  			if mountid, err := daemon.layerStore.GetMountID(c.ID); err == nil {
   882  				daemon.cleanupMountsByID(mountid)
   883  			}
   884  			logrus.Debugf("container stopped %s", c.ID)
   885  		})
   886  	}
   887  
   888  	// trigger libnetwork Stop only if it's initialized
   889  	if daemon.netController != nil {
   890  		daemon.netController.Stop()
   891  	}
   892  
   893  	if daemon.layerStore != nil {
   894  		if err := daemon.layerStore.Cleanup(); err != nil {
   895  			logrus.Errorf("Error during layer Store.Cleanup(): %v", err)
   896  		}
   897  	}
   898  
   899  	if err := daemon.cleanupMounts(); err != nil {
   900  		return err
   901  	}
   902  
   903  	return nil
   904  }
   905  
   906  // Mount sets container.BaseFS
   907  // (is it not set coming in? why is it unset?)
   908  func (daemon *Daemon) Mount(container *container.Container) error {
   909  	dir, err := container.RWLayer.Mount(container.GetMountLabel())
   910  	if err != nil {
   911  		return err
   912  	}
   913  	logrus.Debugf("container mounted via layerStore: %v", dir)
   914  
   915  	if container.BaseFS != dir {
   916  		// The mount path reported by the graph driver should always be trusted on Windows, since the
   917  		// volume path for a given mounted layer may change over time.  This should only be an error
   918  		// on non-Windows operating systems.
   919  		if container.BaseFS != "" && runtime.GOOS != "windows" {
   920  			daemon.Unmount(container)
   921  			return fmt.Errorf("Error: driver %s is returning inconsistent paths for container %s ('%s' then '%s')",
   922  				daemon.GraphDriverName(), container.ID, container.BaseFS, dir)
   923  		}
   924  	}
   925  	container.BaseFS = dir // TODO: combine these fields
   926  	return nil
   927  }
   928  
   929  // Unmount unsets the container base filesystem
   930  func (daemon *Daemon) Unmount(container *container.Container) error {
   931  	if err := container.RWLayer.Unmount(); err != nil {
   932  		logrus.Errorf("Error unmounting container %s: %s", container.ID, err)
   933  		return err
   934  	}
   935  	return nil
   936  }
   937  
   938  func (daemon *Daemon) kill(c *container.Container, sig int) error {
   939  	return daemon.containerd.Signal(c.ID, sig)
   940  }
   941  
   942  func (daemon *Daemon) subscribeToContainerStats(c *container.Container) chan interface{} {
   943  	return daemon.statsCollector.collect(c)
   944  }
   945  
   946  func (daemon *Daemon) unsubscribeToContainerStats(c *container.Container, ch chan interface{}) {
   947  	daemon.statsCollector.unsubscribe(c, ch)
   948  }
   949  
   950  func (daemon *Daemon) changes(container *container.Container) ([]archive.Change, error) {
   951  	return container.RWLayer.Changes()
   952  }
   953  
   954  func writeDistributionProgress(cancelFunc func(), outStream io.Writer, progressChan <-chan progress.Progress) {
   955  	progressOutput := streamformatter.NewJSONStreamFormatter().NewProgressOutput(outStream, false)
   956  	operationCancelled := false
   957  
   958  	for prog := range progressChan {
   959  		if err := progressOutput.WriteProgress(prog); err != nil && !operationCancelled {
   960  			// don't log broken pipe errors as this is the normal case when a client aborts
   961  			if isBrokenPipe(err) {
   962  				logrus.Info("Pull session cancelled")
   963  			} else {
   964  				logrus.Errorf("error writing progress to client: %v", err)
   965  			}
   966  			cancelFunc()
   967  			operationCancelled = true
   968  			// Don't return, because we need to continue draining
   969  			// progressChan until it's closed to avoid a deadlock.
   970  		}
   971  	}
   972  }
   973  
   974  func isBrokenPipe(e error) bool {
   975  	if netErr, ok := e.(*net.OpError); ok {
   976  		e = netErr.Err
   977  		if sysErr, ok := netErr.Err.(*os.SyscallError); ok {
   978  			e = sysErr.Err
   979  		}
   980  	}
   981  	return e == syscall.EPIPE
   982  }
   983  
   984  // ExportImage exports a list of images to the given output stream. The
   985  // exported images are archived into a tar when written to the output
   986  // stream. All images with the given tag and all versions containing
   987  // the same tag are exported. names is the set of tags to export, and
   988  // outStream is the writer which the images are written to.
   989  func (daemon *Daemon) ExportImage(names []string, outStream io.Writer) error {
   990  	imageExporter := tarexport.NewTarExporter(daemon.imageStore, daemon.layerStore, daemon.referenceStore)
   991  	return imageExporter.Save(names, outStream)
   992  }
   993  
   994  // LookupImage looks up an image by name and returns it as an ImageInspect
   995  // structure.
   996  func (daemon *Daemon) LookupImage(name string) (*types.ImageInspect, error) {
   997  	img, err := daemon.GetImage(name)
   998  	if err != nil {
   999  		return nil, fmt.Errorf("No such image: %s", name)
  1000  	}
  1001  
  1002  	refs := daemon.referenceStore.References(img.ID())
  1003  	repoTags := []string{}
  1004  	repoDigests := []string{}
  1005  	for _, ref := range refs {
  1006  		switch ref.(type) {
  1007  		case reference.NamedTagged:
  1008  			repoTags = append(repoTags, ref.String())
  1009  		case reference.Canonical:
  1010  			repoDigests = append(repoDigests, ref.String())
  1011  		}
  1012  	}
  1013  
  1014  	var size int64
  1015  	var layerMetadata map[string]string
  1016  	layerID := img.RootFS.ChainID()
  1017  	if layerID != "" {
  1018  		l, err := daemon.layerStore.Get(layerID)
  1019  		if err != nil {
  1020  			return nil, err
  1021  		}
  1022  		defer layer.ReleaseAndLog(daemon.layerStore, l)
  1023  		size, err = l.Size()
  1024  		if err != nil {
  1025  			return nil, err
  1026  		}
  1027  
  1028  		layerMetadata, err = l.Metadata()
  1029  		if err != nil {
  1030  			return nil, err
  1031  		}
  1032  	}
  1033  
  1034  	comment := img.Comment
  1035  	if len(comment) == 0 && len(img.History) > 0 {
  1036  		comment = img.History[len(img.History)-1].Comment
  1037  	}
  1038  
  1039  	imageInspect := &types.ImageInspect{
  1040  		ID:              img.ID().String(),
  1041  		RepoTags:        repoTags,
  1042  		RepoDigests:     repoDigests,
  1043  		Parent:          img.Parent.String(),
  1044  		Comment:         comment,
  1045  		Created:         img.Created.Format(time.RFC3339Nano),
  1046  		Container:       img.Container,
  1047  		ContainerConfig: &img.ContainerConfig,
  1048  		DockerVersion:   img.DockerVersion,
  1049  		Author:          img.Author,
  1050  		Config:          img.Config,
  1051  		Architecture:    img.Architecture,
  1052  		Os:              img.OS,
  1053  		Size:            size,
  1054  		VirtualSize:     size, // TODO: field unused, deprecate
  1055  		RootFS:          rootFSToAPIType(img.RootFS),
  1056  	}
  1057  
  1058  	imageInspect.GraphDriver.Name = daemon.GraphDriverName()
  1059  
  1060  	imageInspect.GraphDriver.Data = layerMetadata
  1061  
  1062  	return imageInspect, nil
  1063  }
  1064  
  1065  // LoadImage uploads a set of images into the repository. This is the
  1066  // complement of ImageExport.  The input stream is an uncompressed tar
  1067  // ball containing images and metadata.
  1068  func (daemon *Daemon) LoadImage(inTar io.ReadCloser, outStream io.Writer, quiet bool) error {
  1069  	imageExporter := tarexport.NewTarExporter(daemon.imageStore, daemon.layerStore, daemon.referenceStore)
  1070  	return imageExporter.Load(inTar, outStream, quiet)
  1071  }
  1072  
  1073  // ImageHistory returns a slice of ImageHistory structures for the specified image
  1074  // name by walking the image lineage.
  1075  func (daemon *Daemon) ImageHistory(name string) ([]*types.ImageHistory, error) {
  1076  	img, err := daemon.GetImage(name)
  1077  	if err != nil {
  1078  		return nil, err
  1079  	}
  1080  
  1081  	history := []*types.ImageHistory{}
  1082  
  1083  	layerCounter := 0
  1084  	rootFS := *img.RootFS
  1085  	rootFS.DiffIDs = nil
  1086  
  1087  	for _, h := range img.History {
  1088  		var layerSize int64
  1089  
  1090  		if !h.EmptyLayer {
  1091  			if len(img.RootFS.DiffIDs) <= layerCounter {
  1092  				return nil, fmt.Errorf("too many non-empty layers in History section")
  1093  			}
  1094  
  1095  			rootFS.Append(img.RootFS.DiffIDs[layerCounter])
  1096  			l, err := daemon.layerStore.Get(rootFS.ChainID())
  1097  			if err != nil {
  1098  				return nil, err
  1099  			}
  1100  			layerSize, err = l.DiffSize()
  1101  			layer.ReleaseAndLog(daemon.layerStore, l)
  1102  			if err != nil {
  1103  				return nil, err
  1104  			}
  1105  
  1106  			layerCounter++
  1107  		}
  1108  
  1109  		history = append([]*types.ImageHistory{{
  1110  			ID:        "<missing>",
  1111  			Created:   h.Created.Unix(),
  1112  			CreatedBy: h.CreatedBy,
  1113  			Comment:   h.Comment,
  1114  			Size:      layerSize,
  1115  		}}, history...)
  1116  	}
  1117  
  1118  	// Fill in image IDs and tags
  1119  	histImg := img
  1120  	id := img.ID()
  1121  	for _, h := range history {
  1122  		h.ID = id.String()
  1123  
  1124  		var tags []string
  1125  		for _, r := range daemon.referenceStore.References(id) {
  1126  			if _, ok := r.(reference.NamedTagged); ok {
  1127  				tags = append(tags, r.String())
  1128  			}
  1129  		}
  1130  
  1131  		h.Tags = tags
  1132  
  1133  		id = histImg.Parent
  1134  		if id == "" {
  1135  			break
  1136  		}
  1137  		histImg, err = daemon.GetImage(id.String())
  1138  		if err != nil {
  1139  			break
  1140  		}
  1141  	}
  1142  
  1143  	return history, nil
  1144  }
  1145  
  1146  // GetImageID returns an image ID corresponding to the image referred to by
  1147  // refOrID.
  1148  func (daemon *Daemon) GetImageID(refOrID string) (image.ID, error) {
  1149  	id, ref, err := reference.ParseIDOrReference(refOrID)
  1150  	if err != nil {
  1151  		return "", err
  1152  	}
  1153  	if id != "" {
  1154  		if _, err := daemon.imageStore.Get(image.ID(id)); err != nil {
  1155  			return "", ErrImageDoesNotExist{refOrID}
  1156  		}
  1157  		return image.ID(id), nil
  1158  	}
  1159  
  1160  	if id, err := daemon.referenceStore.Get(ref); err == nil {
  1161  		return id, nil
  1162  	}
  1163  	if tagged, ok := ref.(reference.NamedTagged); ok {
  1164  		if id, err := daemon.imageStore.Search(tagged.Tag()); err == nil {
  1165  			for _, namedRef := range daemon.referenceStore.References(id) {
  1166  				if namedRef.Name() == ref.Name() {
  1167  					return id, nil
  1168  				}
  1169  			}
  1170  		}
  1171  	}
  1172  
  1173  	// Search based on ID
  1174  	if id, err := daemon.imageStore.Search(refOrID); err == nil {
  1175  		return id, nil
  1176  	}
  1177  
  1178  	return "", ErrImageDoesNotExist{refOrID}
  1179  }
  1180  
  1181  // GetImage returns an image corresponding to the image referred to by refOrID.
  1182  func (daemon *Daemon) GetImage(refOrID string) (*image.Image, error) {
  1183  	imgID, err := daemon.GetImageID(refOrID)
  1184  	if err != nil {
  1185  		return nil, err
  1186  	}
  1187  	return daemon.imageStore.Get(imgID)
  1188  }
  1189  
  1190  // GetImageOnBuild looks up a Docker image referenced by `name`.
  1191  func (daemon *Daemon) GetImageOnBuild(name string) (builder.Image, error) {
  1192  	img, err := daemon.GetImage(name)
  1193  	if err != nil {
  1194  		return nil, err
  1195  	}
  1196  	return img, nil
  1197  }
  1198  
  1199  // GraphDriverName returns the name of the graph driver used by the layer.Store
  1200  func (daemon *Daemon) GraphDriverName() string {
  1201  	return daemon.layerStore.DriverName()
  1202  }
  1203  
  1204  // GetUIDGIDMaps returns the current daemon's user namespace settings
  1205  // for the full uid and gid maps which will be applied to containers
  1206  // started in this instance.
  1207  func (daemon *Daemon) GetUIDGIDMaps() ([]idtools.IDMap, []idtools.IDMap) {
  1208  	return daemon.uidMaps, daemon.gidMaps
  1209  }
  1210  
  1211  // GetRemappedUIDGID returns the current daemon's uid and gid values
  1212  // if user namespaces are in use for this daemon instance.  If not
  1213  // this function will return "real" root values of 0, 0.
  1214  func (daemon *Daemon) GetRemappedUIDGID() (int, int) {
  1215  	uid, gid, _ := idtools.GetRootUIDGID(daemon.uidMaps, daemon.gidMaps)
  1216  	return uid, gid
  1217  }
  1218  
  1219  // GetCachedImage returns the most recent created image that is a child
  1220  // of the image with imgID, that had the same config when it was
  1221  // created. nil is returned if a child cannot be found. An error is
  1222  // returned if the parent image cannot be found.
  1223  func (daemon *Daemon) GetCachedImage(imgID image.ID, config *containertypes.Config) (*image.Image, error) {
  1224  	// Loop on the children of the given image and check the config
  1225  	getMatch := func(siblings []image.ID) (*image.Image, error) {
  1226  		var match *image.Image
  1227  		for _, id := range siblings {
  1228  			img, err := daemon.imageStore.Get(id)
  1229  			if err != nil {
  1230  				return nil, fmt.Errorf("unable to find image %q", id)
  1231  			}
  1232  
  1233  			if runconfig.Compare(&img.ContainerConfig, config) {
  1234  				// check for the most up to date match
  1235  				if match == nil || match.Created.Before(img.Created) {
  1236  					match = img
  1237  				}
  1238  			}
  1239  		}
  1240  		return match, nil
  1241  	}
  1242  
  1243  	// In this case, this is `FROM scratch`, which isn't an actual image.
  1244  	if imgID == "" {
  1245  		images := daemon.imageStore.Map()
  1246  		var siblings []image.ID
  1247  		for id, img := range images {
  1248  			if img.Parent == imgID {
  1249  				siblings = append(siblings, id)
  1250  			}
  1251  		}
  1252  		return getMatch(siblings)
  1253  	}
  1254  
  1255  	// find match from child images
  1256  	siblings := daemon.imageStore.Children(imgID)
  1257  	return getMatch(siblings)
  1258  }
  1259  
  1260  // GetCachedImageOnBuild returns a reference to a cached image whose parent equals `parent`
  1261  // and runconfig equals `cfg`. A cache miss is expected to return an empty ID and a nil error.
  1262  func (daemon *Daemon) GetCachedImageOnBuild(imgID string, cfg *containertypes.Config) (string, error) {
  1263  	cache, err := daemon.GetCachedImage(image.ID(imgID), cfg)
  1264  	if cache == nil || err != nil {
  1265  		return "", err
  1266  	}
  1267  	return cache.ID().String(), nil
  1268  }
  1269  
  1270  // tempDir returns the default directory to use for temporary files.
  1271  func tempDir(rootDir string, rootUID, rootGID int) (string, error) {
  1272  	var tmpDir string
  1273  	if tmpDir = os.Getenv("DOCKER_TMPDIR"); tmpDir == "" {
  1274  		tmpDir = filepath.Join(rootDir, "tmp")
  1275  	}
  1276  	return tmpDir, idtools.MkdirAllAs(tmpDir, 0700, rootUID, rootGID)
  1277  }
  1278  
  1279  func (daemon *Daemon) setSecurityOptions(container *container.Container, hostConfig *containertypes.HostConfig) error {
  1280  	container.Lock()
  1281  	defer container.Unlock()
  1282  	return parseSecurityOpt(container, hostConfig)
  1283  }
  1284  
  1285  func (daemon *Daemon) setHostConfig(container *container.Container, hostConfig *containertypes.HostConfig) error {
  1286  	// Do not lock while creating volumes since this could be calling out to external plugins
  1287  	// Don't want to block other actions, like `docker ps` because we're waiting on an external plugin
  1288  	if err := daemon.registerMountPoints(container, hostConfig); err != nil {
  1289  		return err
  1290  	}
  1291  
  1292  	container.Lock()
  1293  	defer container.Unlock()
  1294  
  1295  	// Register any links from the host config before starting the container
  1296  	if err := daemon.registerLinks(container, hostConfig); err != nil {
  1297  		return err
  1298  	}
  1299  
  1300  	// make sure links is not nil
  1301  	// this ensures that on the next daemon restart we don't try to migrate from legacy sqlite links
  1302  	if hostConfig.Links == nil {
  1303  		hostConfig.Links = []string{}
  1304  	}
  1305  
  1306  	container.HostConfig = hostConfig
  1307  	return container.ToDisk()
  1308  }
  1309  
  1310  func (daemon *Daemon) setupInitLayer(initPath string) error {
  1311  	rootUID, rootGID := daemon.GetRemappedUIDGID()
  1312  	return setupInitLayer(initPath, rootUID, rootGID)
  1313  }
  1314  
  1315  func setDefaultMtu(config *Config) {
  1316  	// do nothing if the config does not have the default 0 value.
  1317  	if config.Mtu != 0 {
  1318  		return
  1319  	}
  1320  	config.Mtu = defaultNetworkMtu
  1321  }
  1322  
  1323  // verifyContainerSettings performs validation of the hostconfig and config
  1324  // structures.
  1325  func (daemon *Daemon) verifyContainerSettings(hostConfig *containertypes.HostConfig, config *containertypes.Config, update bool) ([]string, error) {
  1326  
  1327  	// First perform verification of settings common across all platforms.
  1328  	if config != nil {
  1329  		if config.WorkingDir != "" {
  1330  			config.WorkingDir = filepath.FromSlash(config.WorkingDir) // Ensure in platform semantics
  1331  			if !system.IsAbs(config.WorkingDir) {
  1332  				return nil, fmt.Errorf("The working directory '%s' is invalid. It needs to be an absolute path", config.WorkingDir)
  1333  			}
  1334  		}
  1335  
  1336  		if len(config.StopSignal) > 0 {
  1337  			_, err := signal.ParseSignal(config.StopSignal)
  1338  			if err != nil {
  1339  				return nil, err
  1340  			}
  1341  		}
  1342  	}
  1343  
  1344  	if hostConfig == nil {
  1345  		return nil, nil
  1346  	}
  1347  
  1348  	logCfg := daemon.getLogConfig(hostConfig.LogConfig)
  1349  	if err := logger.ValidateLogOpts(logCfg.Type, logCfg.Config); err != nil {
  1350  		return nil, err
  1351  	}
  1352  
  1353  	for port := range hostConfig.PortBindings {
  1354  		_, portStr := nat.SplitProtoPort(string(port))
  1355  		if _, err := nat.ParsePort(portStr); err != nil {
  1356  			return nil, fmt.Errorf("Invalid port specification: %q", portStr)
  1357  		}
  1358  		for _, pb := range hostConfig.PortBindings[port] {
  1359  			_, err := nat.NewPort(nat.SplitProtoPort(pb.HostPort))
  1360  			if err != nil {
  1361  				return nil, fmt.Errorf("Invalid port specification: %q", pb.HostPort)
  1362  			}
  1363  		}
  1364  	}
  1365  
  1366  	// Now do platform-specific verification
  1367  	return verifyPlatformContainerSettings(daemon, hostConfig, config, update)
  1368  }
  1369  
  1370  // Checks if the client set configurations for more than one network while creating a container
  1371  func (daemon *Daemon) verifyNetworkingConfig(nwConfig *networktypes.NetworkingConfig) error {
  1372  	if nwConfig == nil || len(nwConfig.EndpointsConfig) <= 1 {
  1373  		return nil
  1374  	}
  1375  	l := make([]string, 0, len(nwConfig.EndpointsConfig))
  1376  	for k := range nwConfig.EndpointsConfig {
  1377  		l = append(l, k)
  1378  	}
  1379  	err := fmt.Errorf("Container cannot be connected to network endpoints: %s", strings.Join(l, ", "))
  1380  	return errors.NewBadRequestError(err)
  1381  }
  1382  
  1383  func configureVolumes(config *Config, rootUID, rootGID int) (*store.VolumeStore, error) {
  1384  	volumesDriver, err := local.New(config.Root, rootUID, rootGID)
  1385  	if err != nil {
  1386  		return nil, err
  1387  	}
  1388  
  1389  	volumedrivers.Register(volumesDriver, volumesDriver.Name())
  1390  	return store.New(config.Root)
  1391  }
  1392  
  1393  // AuthenticateToRegistry checks the validity of credentials in authConfig
  1394  func (daemon *Daemon) AuthenticateToRegistry(ctx context.Context, authConfig *types.AuthConfig) (string, string, error) {
  1395  	return daemon.RegistryService.Auth(authConfig, dockerversion.DockerUserAgent(ctx))
  1396  }
  1397  
  1398  // SearchRegistryForImages queries the registry for images matching
  1399  // term. authConfig is used to login.
  1400  func (daemon *Daemon) SearchRegistryForImages(ctx context.Context, term string,
  1401  	authConfig *types.AuthConfig,
  1402  	headers map[string][]string) (*registrytypes.SearchResults, error) {
  1403  	return daemon.RegistryService.Search(term, authConfig, dockerversion.DockerUserAgent(ctx), headers)
  1404  }
  1405  
  1406  // IsShuttingDown tells whether the daemon is shutting down or not
  1407  func (daemon *Daemon) IsShuttingDown() bool {
  1408  	return daemon.shutdown
  1409  }
  1410  
  1411  // GetContainerStats collects all the stats published by a container
  1412  func (daemon *Daemon) GetContainerStats(container *container.Container) (*types.StatsJSON, error) {
  1413  	stats, err := daemon.stats(container)
  1414  	if err != nil {
  1415  		return nil, err
  1416  	}
  1417  
  1418  	if stats.Networks, err = daemon.getNetworkStats(container); err != nil {
  1419  		return nil, err
  1420  	}
  1421  
  1422  	return stats, nil
  1423  }
  1424  
  1425  // Resolve Network SandboxID in case the container reuse another container's network stack
  1426  func (daemon *Daemon) getNetworkSandboxID(c *container.Container) (string, error) {
  1427  	curr := c
  1428  	for curr.HostConfig.NetworkMode.IsContainer() {
  1429  		containerID := curr.HostConfig.NetworkMode.ConnectedContainer()
  1430  		connected, err := daemon.GetContainer(containerID)
  1431  		if err != nil {
  1432  			return "", fmt.Errorf("Could not get container for %s", containerID)
  1433  		}
  1434  		curr = connected
  1435  	}
  1436  	return curr.NetworkSettings.SandboxID, nil
  1437  }
  1438  
  1439  func (daemon *Daemon) getNetworkStats(c *container.Container) (map[string]types.NetworkStats, error) {
  1440  	sandboxID, err := daemon.getNetworkSandboxID(c)
  1441  	if err != nil {
  1442  		return nil, err
  1443  	}
  1444  
  1445  	sb, err := daemon.netController.SandboxByID(sandboxID)
  1446  	if err != nil {
  1447  		return nil, err
  1448  	}
  1449  
  1450  	lnstats, err := sb.Statistics()
  1451  	if err != nil {
  1452  		return nil, err
  1453  	}
  1454  
  1455  	stats := make(map[string]types.NetworkStats)
  1456  	// Convert libnetwork nw stats into engine-api stats
  1457  	for ifName, ifStats := range lnstats {
  1458  		stats[ifName] = types.NetworkStats{
  1459  			RxBytes:   ifStats.RxBytes,
  1460  			RxPackets: ifStats.RxPackets,
  1461  			RxErrors:  ifStats.RxErrors,
  1462  			RxDropped: ifStats.RxDropped,
  1463  			TxBytes:   ifStats.TxBytes,
  1464  			TxPackets: ifStats.TxPackets,
  1465  			TxErrors:  ifStats.TxErrors,
  1466  			TxDropped: ifStats.TxDropped,
  1467  		}
  1468  	}
  1469  
  1470  	return stats, nil
  1471  }
  1472  
  1473  // newBaseContainer creates a new container with its initial
  1474  // configuration based on the root storage from the daemon.
  1475  func (daemon *Daemon) newBaseContainer(id string) *container.Container {
  1476  	return container.NewBaseContainer(id, daemon.containerRoot(id))
  1477  }
  1478  
  1479  // initDiscovery initializes the discovery watcher for this daemon.
  1480  func (daemon *Daemon) initDiscovery(config *Config) error {
  1481  	advertise, err := parseClusterAdvertiseSettings(config.ClusterStore, config.ClusterAdvertise)
  1482  	if err != nil {
  1483  		if err == errDiscoveryDisabled {
  1484  			return nil
  1485  		}
  1486  		return err
  1487  	}
  1488  
  1489  	config.ClusterAdvertise = advertise
  1490  	discoveryWatcher, err := initDiscovery(config.ClusterStore, config.ClusterAdvertise, config.ClusterOpts)
  1491  	if err != nil {
  1492  		return fmt.Errorf("discovery initialization failed (%v)", err)
  1493  	}
  1494  
  1495  	daemon.discoveryWatcher = discoveryWatcher
  1496  	return nil
  1497  }
  1498  
  1499  // Reload reads configuration changes and modifies the
  1500  // daemon according to those changes.
  1501  // These are the settings that Reload changes:
  1502  // - Daemon labels.
  1503  // - Daemon debug log level.
  1504  // - Cluster discovery (reconfigure and restart).
  1505  func (daemon *Daemon) Reload(config *Config) error {
  1506  	daemon.configStore.reloadLock.Lock()
  1507  	defer daemon.configStore.reloadLock.Unlock()
  1508  	if config.IsValueSet("label") {
  1509  		daemon.configStore.Labels = config.Labels
  1510  	}
  1511  	if config.IsValueSet("debug") {
  1512  		daemon.configStore.Debug = config.Debug
  1513  	}
  1514  	return daemon.reloadClusterDiscovery(config)
  1515  }
  1516  
  1517  func (daemon *Daemon) reloadClusterDiscovery(config *Config) error {
  1518  	var err error
  1519  	newAdvertise := daemon.configStore.ClusterAdvertise
  1520  	newClusterStore := daemon.configStore.ClusterStore
  1521  	if config.IsValueSet("cluster-advertise") {
  1522  		if config.IsValueSet("cluster-store") {
  1523  			newClusterStore = config.ClusterStore
  1524  		}
  1525  		newAdvertise, err = parseClusterAdvertiseSettings(newClusterStore, config.ClusterAdvertise)
  1526  		if err != nil && err != errDiscoveryDisabled {
  1527  			return err
  1528  		}
  1529  	}
  1530  
  1531  	// check discovery modifications
  1532  	if !modifiedDiscoverySettings(daemon.configStore, newAdvertise, newClusterStore, config.ClusterOpts) {
  1533  		return nil
  1534  	}
  1535  
  1536  	// enable discovery for the first time if it was not previously enabled
  1537  	if daemon.discoveryWatcher == nil {
  1538  		discoveryWatcher, err := initDiscovery(newClusterStore, newAdvertise, config.ClusterOpts)
  1539  		if err != nil {
  1540  			return fmt.Errorf("discovery initialization failed (%v)", err)
  1541  		}
  1542  		daemon.discoveryWatcher = discoveryWatcher
  1543  	} else {
  1544  		if err == errDiscoveryDisabled {
  1545  			// disable discovery if it was previously enabled and it's disabled now
  1546  			daemon.discoveryWatcher.Stop()
  1547  		} else {
  1548  			// reload discovery
  1549  			if err = daemon.discoveryWatcher.Reload(config.ClusterStore, newAdvertise, config.ClusterOpts); err != nil {
  1550  				return err
  1551  			}
  1552  		}
  1553  	}
  1554  
  1555  	daemon.configStore.ClusterStore = newClusterStore
  1556  	daemon.configStore.ClusterOpts = config.ClusterOpts
  1557  	daemon.configStore.ClusterAdvertise = newAdvertise
  1558  
  1559  	if daemon.netController == nil {
  1560  		return nil
  1561  	}
  1562  	netOptions, err := daemon.networkOptions(daemon.configStore)
  1563  	if err != nil {
  1564  		logrus.Warnf("Failed to reload configuration with network controller: %v", err)
  1565  		return nil
  1566  	}
  1567  	err = daemon.netController.ReloadConfiguration(netOptions...)
  1568  	if err != nil {
  1569  		logrus.Warnf("Failed to reload configuration with network controller: %v", err)
  1570  	}
  1571  
  1572  	return nil
  1573  }
  1574  
  1575  func validateID(id string) error {
  1576  	if id == "" {
  1577  		return fmt.Errorf("Invalid empty id")
  1578  	}
  1579  	return nil
  1580  }
  1581  
  1582  func isBridgeNetworkDisabled(config *Config) bool {
  1583  	return config.bridgeConfig.Iface == disableNetworkBridge
  1584  }
  1585  
  1586  func (daemon *Daemon) networkOptions(dconfig *Config) ([]nwconfig.Option, error) {
  1587  	options := []nwconfig.Option{}
  1588  	if dconfig == nil {
  1589  		return options, nil
  1590  	}
  1591  
  1592  	options = append(options, nwconfig.OptionDataDir(dconfig.Root))
  1593  
  1594  	dd := runconfig.DefaultDaemonNetworkMode()
  1595  	dn := runconfig.DefaultDaemonNetworkMode().NetworkName()
  1596  	options = append(options, nwconfig.OptionDefaultDriver(string(dd)))
  1597  	options = append(options, nwconfig.OptionDefaultNetwork(dn))
  1598  
  1599  	if strings.TrimSpace(dconfig.ClusterStore) != "" {
  1600  		kv := strings.Split(dconfig.ClusterStore, "://")
  1601  		if len(kv) != 2 {
  1602  			return nil, fmt.Errorf("kv store daemon config must be of the form KV-PROVIDER://KV-URL")
  1603  		}
  1604  		options = append(options, nwconfig.OptionKVProvider(kv[0]))
  1605  		options = append(options, nwconfig.OptionKVProviderURL(kv[1]))
  1606  	}
  1607  	if len(dconfig.ClusterOpts) > 0 {
  1608  		options = append(options, nwconfig.OptionKVOpts(dconfig.ClusterOpts))
  1609  	}
  1610  
  1611  	if daemon.discoveryWatcher != nil {
  1612  		options = append(options, nwconfig.OptionDiscoveryWatcher(daemon.discoveryWatcher))
  1613  	}
  1614  
  1615  	if dconfig.ClusterAdvertise != "" {
  1616  		options = append(options, nwconfig.OptionDiscoveryAddress(dconfig.ClusterAdvertise))
  1617  	}
  1618  
  1619  	options = append(options, nwconfig.OptionLabels(dconfig.Labels))
  1620  	options = append(options, driverOptions(dconfig)...)
  1621  	return options, nil
  1622  }
  1623  
  1624  func copyBlkioEntry(entries []*containerd.BlkioStatsEntry) []types.BlkioStatEntry {
  1625  	out := make([]types.BlkioStatEntry, len(entries))
  1626  	for i, re := range entries {
  1627  		out[i] = types.BlkioStatEntry{
  1628  			Major: re.Major,
  1629  			Minor: re.Minor,
  1630  			Op:    re.Op,
  1631  			Value: re.Value,
  1632  		}
  1633  	}
  1634  	return out
  1635  }