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 }