@@ -13,6 +13,7 @@ import (
1313 "syscall"
1414 "time"
1515
16+ "github.com/docker/libcontainer"
1617 "github.com/docker/libcontainer/label"
1718
1819 "github.com/Sirupsen/logrus"
@@ -255,7 +256,7 @@ func (container *Container) Start() (err error) {
255256 if err := container .Mount (); err != nil {
256257 return err
257258 }
258- if err := container .initializeNetworking (); err != nil {
259+ if err := container .initializeNetworking (false ); err != nil {
259260 return err
260261 }
261262 container .verifyDaemonSettings ()
@@ -339,12 +340,11 @@ func (container *Container) isNetworkAllocated() bool {
339340 return container .NetworkSettings .IPAddress != ""
340341}
341342
342-
343343// cleanup releases any network resources allocated to the container along with any rules
344344// around how containers are linked together. It also unmounts the container's root filesystem.
345345func (container * Container ) cleanup () {
346346 if container .IsCheckpointed () {
347- log . CRDbg ("not calling ReleaseNetwork() for checkpointed container %s" , container .ID )
347+ logrus . Debugf ("not calling ReleaseNetwork() for checkpointed container %s" , container .ID )
348348 } else {
349349 container .ReleaseNetwork ()
350350 }
@@ -569,7 +569,6 @@ func validateID(id string) error {
569569 return nil
570570}
571571
572-
573572func (container * Container ) Checkpoint (opts * libcontainer.CriuOpts ) error {
574573 if err := container .daemon .Checkpoint (container , opts ); err != nil {
575574 return err
@@ -581,6 +580,43 @@ func (container *Container) Checkpoint(opts *libcontainer.CriuOpts) error {
581580 return nil
582581}
583582
583+ func (container * Container ) Restore (opts * libcontainer.CriuOpts , forceRestore bool ) error {
584+ var err error
585+ container .Lock ()
586+ defer container .Unlock ()
587+
588+ defer func () {
589+ if err != nil {
590+ container .cleanup ()
591+ }
592+ }()
593+ if err := container .Mount (); err != nil {
594+ return err
595+ }
596+ if err = container .initializeNetworking (true ); err != nil {
597+ return err
598+ }
599+ container .verifyDaemonSettings ()
600+
601+ linkedEnv , err := container .setupLinkedContainers ()
602+ if err != nil {
603+ return err
604+ }
605+ if err = container .setupWorkingDirectory (); err != nil {
606+ return err
607+ }
608+
609+ env := container .createDaemonEnvironment (linkedEnv )
610+ if err = populateCommand (container , env ); err != nil {
611+ return err
612+ }
613+
614+ if err = container .setupMounts (); err != nil {
615+ return err
616+ }
617+
618+ return container .waitForRestore (opts , forceRestore )
619+ }
584620
585621func (container * Container ) Copy (resource string ) (io.ReadCloser , error ) {
586622 container .Lock ()
@@ -641,41 +677,6 @@ func (container *Container) Copy(resource string) (io.ReadCloser, error) {
641677 nil
642678}
643679
644- func (container * Container ) Checkpoint () error {
645- return container .daemon .Checkpoint (container )
646- }
647-
648- func (container * Container ) Restore () error {
649- var err error
650-
651- container .Lock ()
652- defer container .Unlock ()
653-
654- defer func () {
655- if err != nil {
656- container .cleanup ()
657- }
658- }()
659-
660- if err = container .initializeNetworking (); err != nil {
661- return err
662- }
663-
664- linkedEnv , err := container .setupLinkedContainers ()
665- if err != nil {
666- return err
667- }
668- if err = container .setupWorkingDirectory (); err != nil {
669- return err
670- }
671- env := container .createDaemonEnvironment (linkedEnv )
672- if err = populateCommandRestore (container , env ); err != nil {
673- return err
674- }
675-
676- return container .waitForRestore ()
677- }
678-
679680// Returns true if the container exposes a certain port
680681func (container * Container ) Exposes (p nat.Port ) bool {
681682 _ , exists := container .Config .ExposedPorts [p ]
@@ -762,10 +763,7 @@ func (container *Container) waitForStart() error {
762763 return nil
763764}
764765
765- // Like waitForStart() but for restoring a container.
766- //
767- // XXX Does RestartPolicy apply here?
768- func (container * Container ) waitForRestore () error {
766+ func (container * Container ) waitForRestore (opts * libcontainer.CriuOpts , forceRestore bool ) error {
769767 container .monitor = newContainerMonitor (container , container .hostConfig .RestartPolicy )
770768
771769 // After calling promise.Go() we'll have two goroutines:
@@ -778,7 +776,7 @@ func (container *Container) waitForRestore() error {
778776 if container .ExitCode != 0 {
779777 return fmt .Errorf ("restore process failed" )
780778 }
781- case err := <- promise .Go (container .monitor .Restore ):
779+ case err := <- promise .Go (func () error { return container .monitor .Restore ( opts , forceRestore ) } ):
782780 return err
783781 }
784782
@@ -989,6 +987,7 @@ func attach(streamConfig *StreamConfig, openStdin, stdinOnce, tty bool, stdin io
989987 _ , err = copyEscapable (cStdin , stdin )
990988 } else {
991989 _ , err = io .Copy (cStdin , stdin )
990+
992991 }
993992 if err == io .ErrClosedPipe {
994993 err = nil
0 commit comments