| ... | ... |
@@ -90,6 +90,7 @@ func (daemon *Daemon) StateChanged(id string, e libcontainerd.StateInfo) error {
|
| 90 | 90 |
// Container is already locked in this case |
| 91 | 91 |
c.SetRunning(int(e.Pid), e.State == libcontainerd.StateStart) |
| 92 | 92 |
c.HasBeenManuallyStopped = false |
| 93 |
+ c.HasBeenStartedBefore = true |
|
| 93 | 94 |
if err := c.ToDisk(); err != nil {
|
| 94 | 95 |
c.Reset(false) |
| 95 | 96 |
return err |
| ... | ... |
@@ -78,9 +78,6 @@ func (daemon *Daemon) createSpec(c *container.Container) (*libcontainerd.Spec, e |
| 78 | 78 |
s.Root.Path = c.BaseFS |
| 79 | 79 |
s.Root.Readonly = c.HostConfig.ReadonlyRootfs |
| 80 | 80 |
|
| 81 |
- // In s.Windows |
|
| 82 |
- s.Windows.FirstStart = !c.HasBeenStartedBefore |
|
| 83 |
- |
|
| 84 | 81 |
// s.Windows.LayerFolder. |
| 85 | 82 |
m, err := c.RWLayer.Metadata() |
| 86 | 83 |
if err != nil {
|
| ... | ... |
@@ -6,5 +6,7 @@ import ( |
| 6 | 6 |
) |
| 7 | 7 |
|
| 8 | 8 |
func (daemon *Daemon) getLibcontainerdCreateOptions(container *container.Container) (*[]libcontainerd.CreateOption, error) {
|
| 9 |
- return &[]libcontainerd.CreateOption{}, nil
|
|
| 9 |
+ createOptions := []libcontainerd.CreateOption{}
|
|
| 10 |
+ createOptions = append(createOptions, &libcontainerd.FlushOption{IgnoreFlushesDuringBoot: !container.HasBeenStartedBefore})
|
|
| 11 |
+ return &createOptions, nil |
|
| 10 | 12 |
} |
| ... | ... |
@@ -41,12 +41,11 @@ func (clnt *client) Create(containerID string, checkpoint string, checkpointDir |
| 41 | 41 |
logrus.Debugln("libcontainerd: client.Create() with spec", spec)
|
| 42 | 42 |
|
| 43 | 43 |
configuration := &hcsshim.ContainerConfig{
|
| 44 |
- SystemType: "Container", |
|
| 45 |
- Name: containerID, |
|
| 46 |
- Owner: defaultOwner, |
|
| 47 |
- |
|
| 44 |
+ SystemType: "Container", |
|
| 45 |
+ Name: containerID, |
|
| 46 |
+ Owner: defaultOwner, |
|
| 48 | 47 |
VolumePath: spec.Root.Path, |
| 49 |
- IgnoreFlushesDuringBoot: spec.Windows.FirstStart, |
|
| 48 |
+ IgnoreFlushesDuringBoot: false, |
|
| 50 | 49 |
LayerFolderPath: spec.Windows.LayerFolder, |
| 51 | 50 |
HostName: spec.Hostname, |
| 52 | 51 |
} |
| ... | ... |
@@ -106,6 +105,10 @@ func (clnt *client) Create(containerID string, checkpoint string, checkpointDir |
| 106 | 106 |
configuration.Servicing = s.IsServicing |
| 107 | 107 |
break |
| 108 | 108 |
} |
| 109 |
+ if s, ok := option.(*FlushOption); ok {
|
|
| 110 |
+ configuration.IgnoreFlushesDuringBoot = s.IgnoreFlushesDuringBoot |
|
| 111 |
+ break |
|
| 112 |
+ } |
|
| 109 | 113 |
} |
| 110 | 114 |
|
| 111 | 115 |
for _, layerPath := range spec.Windows.LayerPaths {
|
| ... | ... |
@@ -38,6 +38,13 @@ type ServicingOption struct {
|
| 38 | 38 |
IsServicing bool |
| 39 | 39 |
} |
| 40 | 40 |
|
| 41 |
+// FlushOption is an empty CreateOption that signifies if the container should be |
|
| 42 |
+// started with flushes ignored until boot has completed. This is an optimisation |
|
| 43 |
+// for first boot of a container. |
|
| 44 |
+type FlushOption struct {
|
|
| 45 |
+ IgnoreFlushesDuringBoot bool |
|
| 46 |
+} |
|
| 47 |
+ |
|
| 41 | 48 |
// Checkpoint holds the details of a checkpoint (not supported in windows) |
| 42 | 49 |
type Checkpoint struct {
|
| 43 | 50 |
Name string |
| ... | ... |
@@ -23,6 +23,11 @@ func (s *ServicingOption) Apply(interface{}) error {
|
| 23 | 23 |
return nil |
| 24 | 24 |
} |
| 25 | 25 |
|
| 26 |
+// Apply for the flush option is a no-op. |
|
| 27 |
+func (s *FlushOption) Apply(interface{}) error {
|
|
| 28 |
+ return nil |
|
| 29 |
+} |
|
| 30 |
+ |
|
| 26 | 31 |
// buildFromVersion takes an image version string and returns the Windows build |
| 27 | 32 |
// number. It returns 0 if the build number is not present. |
| 28 | 33 |
func buildFromVersion(osver string) int {
|
| ... | ... |
@@ -39,8 +39,6 @@ type Windows struct {
|
| 39 | 39 |
Resources *Resources `json:"resources,omitempty"` |
| 40 | 40 |
// Networking contains the platform specific network settings for the container. |
| 41 | 41 |
Networking *Networking `json:"networking,omitempty"` |
| 42 |
- // FirstStart is used for an optimization on first boot of Windows |
|
| 43 |
- FirstStart bool `json:"first_start,omitempty"` |
|
| 44 | 42 |
// LayerFolder is the path to the current layer folder |
| 45 | 43 |
LayerFolder string `json:"layer_folder,omitempty"` |
| 46 | 44 |
// Layer paths of the parent layers |