diff --git a/daemon/monitor.go b/daemon/monitor.go index b88dff6890..aec771fd17 100644 --- a/daemon/monitor.go +++ b/daemon/monitor.go @@ -90,6 +90,7 @@ func (daemon *Daemon) StateChanged(id string, e libcontainerd.StateInfo) error { // Container is already locked in this case c.SetRunning(int(e.Pid), e.State == libcontainerd.StateStart) c.HasBeenManuallyStopped = false + c.HasBeenStartedBefore = true if err := c.ToDisk(); err != nil { c.Reset(false) return err diff --git a/daemon/oci_windows.go b/daemon/oci_windows.go index cb01cb2602..d304220335 100644 --- a/daemon/oci_windows.go +++ b/daemon/oci_windows.go @@ -78,9 +78,6 @@ func (daemon *Daemon) createSpec(c *container.Container) (*libcontainerd.Spec, e s.Root.Path = c.BaseFS s.Root.Readonly = c.HostConfig.ReadonlyRootfs - // In s.Windows - s.Windows.FirstStart = !c.HasBeenStartedBefore - // s.Windows.LayerFolder. m, err := c.RWLayer.Metadata() if err != nil { diff --git a/daemon/start_windows.go b/daemon/start_windows.go index af3fe7602b..7804a877ff 100644 --- a/daemon/start_windows.go +++ b/daemon/start_windows.go @@ -6,5 +6,7 @@ import ( ) func (daemon *Daemon) getLibcontainerdCreateOptions(container *container.Container) (*[]libcontainerd.CreateOption, error) { - return &[]libcontainerd.CreateOption{}, nil + createOptions := []libcontainerd.CreateOption{} + createOptions = append(createOptions, &libcontainerd.FlushOption{IgnoreFlushesDuringBoot: !container.HasBeenStartedBefore}) + return &createOptions, nil } diff --git a/libcontainerd/client_windows.go b/libcontainerd/client_windows.go index b164ca507b..9c750b39f9 100644 --- a/libcontainerd/client_windows.go +++ b/libcontainerd/client_windows.go @@ -41,12 +41,11 @@ func (clnt *client) Create(containerID string, checkpoint string, checkpointDir logrus.Debugln("libcontainerd: client.Create() with spec", spec) configuration := &hcsshim.ContainerConfig{ - SystemType: "Container", - Name: containerID, - Owner: defaultOwner, - + SystemType: "Container", + Name: containerID, + Owner: defaultOwner, VolumePath: spec.Root.Path, - IgnoreFlushesDuringBoot: spec.Windows.FirstStart, + IgnoreFlushesDuringBoot: false, LayerFolderPath: spec.Windows.LayerFolder, HostName: spec.Hostname, } @@ -106,6 +105,10 @@ func (clnt *client) Create(containerID string, checkpoint string, checkpointDir configuration.Servicing = s.IsServicing break } + if s, ok := option.(*FlushOption); ok { + configuration.IgnoreFlushesDuringBoot = s.IgnoreFlushesDuringBoot + break + } } for _, layerPath := range spec.Windows.LayerPaths { diff --git a/libcontainerd/types_windows.go b/libcontainerd/types_windows.go index fa96f0ed8d..5f3223316b 100644 --- a/libcontainerd/types_windows.go +++ b/libcontainerd/types_windows.go @@ -38,6 +38,13 @@ type ServicingOption struct { IsServicing bool } +// FlushOption is an empty CreateOption that signifies if the container should be +// started with flushes ignored until boot has completed. This is an optimisation +// for first boot of a container. +type FlushOption struct { + IgnoreFlushesDuringBoot bool +} + // Checkpoint holds the details of a checkpoint (not supported in windows) type Checkpoint struct { Name string diff --git a/libcontainerd/utils_windows.go b/libcontainerd/utils_windows.go index 70e77bb812..fcd72145c6 100644 --- a/libcontainerd/utils_windows.go +++ b/libcontainerd/utils_windows.go @@ -23,6 +23,11 @@ func (s *ServicingOption) Apply(interface{}) error { return nil } +// Apply for the flush option is a no-op. +func (s *FlushOption) Apply(interface{}) error { + return nil +} + // buildFromVersion takes an image version string and returns the Windows build // number. It returns 0 if the build number is not present. func buildFromVersion(osver string) int { diff --git a/libcontainerd/windowsoci/oci_windows.go b/libcontainerd/windowsoci/oci_windows.go index 63d5abdfb0..d6de7423b5 100644 --- a/libcontainerd/windowsoci/oci_windows.go +++ b/libcontainerd/windowsoci/oci_windows.go @@ -39,8 +39,6 @@ type Windows struct { Resources *Resources `json:"resources,omitempty"` // Networking contains the platform specific network settings for the container. Networking *Networking `json:"networking,omitempty"` - // FirstStart is used for an optimization on first boot of Windows - FirstStart bool `json:"first_start,omitempty"` // LayerFolder is the path to the current layer folder LayerFolder string `json:"layer_folder,omitempty"` // Layer paths of the parent layers