github.com/zhuohuang-hust/src-cbuild@v0.0.0-20230105071821-c7aab3e7c840/mergeCode/runc/libcontainer/integration/checkpoint_test.go (about)

     1  package integration
     2  
     3  import (
     4  	"bufio"
     5  	"bytes"
     6  	"io/ioutil"
     7  	"os"
     8  	"path/filepath"
     9  	"strings"
    10  	"syscall"
    11  	"testing"
    12  
    13  	"github.com/opencontainers/runc/libcontainer"
    14  	"github.com/opencontainers/runc/libcontainer/configs"
    15  )
    16  
    17  func showFile(t *testing.T, fname string) error {
    18  	t.Logf("=== %s ===\n", fname)
    19  
    20  	f, err := os.Open(fname)
    21  	if err != nil {
    22  		t.Log(err)
    23  		return err
    24  	}
    25  	defer f.Close()
    26  
    27  	scanner := bufio.NewScanner(f)
    28  	for scanner.Scan() {
    29  		t.Log(scanner.Text())
    30  	}
    31  
    32  	if err := scanner.Err(); err != nil {
    33  		return err
    34  	}
    35  
    36  	t.Logf("=== END ===\n")
    37  
    38  	return nil
    39  }
    40  
    41  func TestCheckpoint(t *testing.T) {
    42  	if testing.Short() {
    43  		return
    44  	}
    45  	root, err := newTestRoot()
    46  	if err != nil {
    47  		t.Fatal(err)
    48  	}
    49  	defer os.RemoveAll(root)
    50  
    51  	rootfs, err := newRootfs()
    52  	if err != nil {
    53  		t.Fatal(err)
    54  	}
    55  	defer remove(rootfs)
    56  
    57  	config := newTemplateConfig(rootfs)
    58  
    59  	config.Mounts = append(config.Mounts, &configs.Mount{
    60  		Destination: "/sys/fs/cgroup",
    61  		Device:      "cgroup",
    62  		Flags:       defaultMountFlags | syscall.MS_RDONLY,
    63  	})
    64  
    65  	factory, err := libcontainer.New(root, libcontainer.Cgroupfs)
    66  
    67  	if err != nil {
    68  		t.Fatal(err)
    69  	}
    70  
    71  	container, err := factory.Create("test", config)
    72  	if err != nil {
    73  		t.Fatal(err)
    74  	}
    75  	defer container.Destroy()
    76  
    77  	stdinR, stdinW, err := os.Pipe()
    78  	if err != nil {
    79  		t.Fatal(err)
    80  	}
    81  
    82  	var stdout bytes.Buffer
    83  
    84  	pconfig := libcontainer.Process{
    85  		Cwd:    "/",
    86  		Args:   []string{"cat"},
    87  		Env:    standardEnvironment,
    88  		Stdin:  stdinR,
    89  		Stdout: &stdout,
    90  	}
    91  
    92  	err = container.Run(&pconfig)
    93  	stdinR.Close()
    94  	defer stdinW.Close()
    95  	if err != nil {
    96  		t.Fatal(err)
    97  	}
    98  
    99  	pid, err := pconfig.Pid()
   100  	if err != nil {
   101  		t.Fatal(err)
   102  	}
   103  
   104  	process, err := os.FindProcess(pid)
   105  	if err != nil {
   106  		t.Fatal(err)
   107  	}
   108  
   109  	imagesDir, err := ioutil.TempDir("", "criu")
   110  	if err != nil {
   111  		t.Fatal(err)
   112  	}
   113  	defer os.RemoveAll(imagesDir)
   114  
   115  	checkpointOpts := &libcontainer.CriuOpts{
   116  		ImagesDirectory: imagesDir,
   117  		WorkDirectory:   imagesDir,
   118  	}
   119  	dumpLog := filepath.Join(checkpointOpts.WorkDirectory, "dump.log")
   120  	restoreLog := filepath.Join(checkpointOpts.WorkDirectory, "restore.log")
   121  
   122  	if err := container.Checkpoint(checkpointOpts); err != nil {
   123  		showFile(t, dumpLog)
   124  		t.Fatal(err)
   125  	}
   126  
   127  	state, err := container.Status()
   128  	if err != nil {
   129  		t.Fatal(err)
   130  	}
   131  
   132  	if state != libcontainer.Running {
   133  		t.Fatal("Unexpected state checkpoint: ", state)
   134  	}
   135  
   136  	stdinW.Close()
   137  	_, err = process.Wait()
   138  	if err != nil {
   139  		t.Fatal(err)
   140  	}
   141  
   142  	// reload the container
   143  	container, err = factory.Load("test")
   144  	if err != nil {
   145  		t.Fatal(err)
   146  	}
   147  
   148  	restoreStdinR, restoreStdinW, err := os.Pipe()
   149  	if err != nil {
   150  		t.Fatal(err)
   151  	}
   152  
   153  	restoreProcessConfig := &libcontainer.Process{
   154  		Cwd:    "/",
   155  		Stdin:  restoreStdinR,
   156  		Stdout: &stdout,
   157  	}
   158  
   159  	err = container.Restore(restoreProcessConfig, checkpointOpts)
   160  	restoreStdinR.Close()
   161  	defer restoreStdinW.Close()
   162  	if err != nil {
   163  		showFile(t, restoreLog)
   164  		t.Fatal(err)
   165  	}
   166  
   167  	state, err = container.Status()
   168  	if err != nil {
   169  		t.Fatal(err)
   170  	}
   171  	if state != libcontainer.Running {
   172  		t.Fatal("Unexpected restore state: ", state)
   173  	}
   174  
   175  	pid, err = restoreProcessConfig.Pid()
   176  	if err != nil {
   177  		t.Fatal(err)
   178  	}
   179  
   180  	process, err = os.FindProcess(pid)
   181  	if err != nil {
   182  		t.Fatal(err)
   183  	}
   184  
   185  	_, err = restoreStdinW.WriteString("Hello!")
   186  	if err != nil {
   187  		t.Fatal(err)
   188  	}
   189  
   190  	restoreStdinW.Close()
   191  	s, err := process.Wait()
   192  	if err != nil {
   193  		t.Fatal(err)
   194  	}
   195  
   196  	if !s.Success() {
   197  		t.Fatal(s.String(), pid)
   198  	}
   199  
   200  	output := string(stdout.Bytes())
   201  	if !strings.Contains(output, "Hello!") {
   202  		t.Fatal("Did not restore the pipe correctly:", output)
   203  	}
   204  }