github.com/akerouanton/docker@v1.11.0-rc3/libcontainerd/client_liverestore_linux.go (about)

     1  // +build experimental
     2  
     3  package libcontainerd
     4  
     5  import (
     6  	"fmt"
     7  
     8  	"github.com/Sirupsen/logrus"
     9  	containerd "github.com/docker/containerd/api/grpc/types"
    10  )
    11  
    12  func (clnt *client) restore(cont *containerd.Container, options ...CreateOption) (err error) {
    13  	clnt.lock(cont.Id)
    14  	defer clnt.unlock(cont.Id)
    15  
    16  	logrus.Debugf("restore container %s state %s", cont.Id, cont.Status)
    17  
    18  	containerID := cont.Id
    19  	if _, err := clnt.getContainer(containerID); err == nil {
    20  		return fmt.Errorf("container %s is aleady active", containerID)
    21  	}
    22  
    23  	defer func() {
    24  		if err != nil {
    25  			clnt.deleteContainer(cont.Id)
    26  		}
    27  	}()
    28  
    29  	container := clnt.newContainer(cont.BundlePath, options...)
    30  	container.systemPid = systemPid(cont)
    31  
    32  	var terminal bool
    33  	for _, p := range cont.Processes {
    34  		if p.Pid == InitFriendlyName {
    35  			terminal = p.Terminal
    36  		}
    37  	}
    38  
    39  	iopipe, err := container.openFifos(terminal)
    40  	if err != nil {
    41  		return err
    42  	}
    43  
    44  	if err := clnt.backend.AttachStreams(containerID, *iopipe); err != nil {
    45  		return err
    46  	}
    47  
    48  	clnt.appendContainer(container)
    49  
    50  	err = clnt.backend.StateChanged(containerID, StateInfo{
    51  		State: StateRestore,
    52  		Pid:   container.systemPid,
    53  	})
    54  
    55  	if err != nil {
    56  		return err
    57  	}
    58  
    59  	if event, ok := clnt.remote.pastEvents[containerID]; ok {
    60  		// This should only be a pause or resume event
    61  		if event.Type == StatePause || event.Type == StateResume {
    62  			return clnt.backend.StateChanged(containerID, StateInfo{
    63  				State: event.Type,
    64  				Pid:   container.systemPid,
    65  			})
    66  		}
    67  
    68  		logrus.Warnf("unexpected backlog event: %#v", event)
    69  	}
    70  
    71  	return nil
    72  }
    73  
    74  func (clnt *client) Restore(containerID string, options ...CreateOption) error {
    75  	cont, err := clnt.getContainerdContainer(containerID)
    76  	if err == nil && cont.Status != "stopped" {
    77  		if err := clnt.restore(cont, options...); err != nil {
    78  			logrus.Errorf("error restoring %s: %v", containerID, err)
    79  		}
    80  		return nil
    81  	}
    82  	return clnt.setExited(containerID)
    83  }