summaryrefslogtreecommitdiff
path: root/vendor/github.com/checkpoint-restore/go-criu/test/phaul-main.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/checkpoint-restore/go-criu/test/phaul-main.go')
-rw-r--r--vendor/github.com/checkpoint-restore/go-criu/test/phaul-main.go192
1 files changed, 192 insertions, 0 deletions
diff --git a/vendor/github.com/checkpoint-restore/go-criu/test/phaul-main.go b/vendor/github.com/checkpoint-restore/go-criu/test/phaul-main.go
new file mode 100644
index 000000000..f1bec2c55
--- /dev/null
+++ b/vendor/github.com/checkpoint-restore/go-criu/test/phaul-main.go
@@ -0,0 +1,192 @@
+package main
+
+import (
+ "fmt"
+ "os"
+ "strconv"
+ "strings"
+ "syscall"
+
+ "github.com/checkpoint-restore/go-criu"
+ "github.com/checkpoint-restore/go-criu/phaul"
+ "github.com/checkpoint-restore/go-criu/rpc"
+ "github.com/golang/protobuf/proto"
+)
+
+type testLocal struct {
+ criu.NoNotify
+ r *testRemote
+}
+
+type testRemote struct {
+ srv *phaul.Server
+}
+
+/* Dir where test will put dump images */
+const imagesDir = "image"
+
+func prepareImages() error {
+ err := os.Mkdir(imagesDir, 0700)
+ if err != nil {
+ return err
+ }
+
+ /* Work dir for PhaulClient */
+ err = os.Mkdir(imagesDir+"/local", 0700)
+ if err != nil {
+ return err
+ }
+
+ /* Work dir for PhaulServer */
+ err = os.Mkdir(imagesDir+"/remote", 0700)
+ if err != nil {
+ return err
+ }
+
+ /* Work dir for DumpCopyRestore */
+ err = os.Mkdir(imagesDir+"/test", 0700)
+ if err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func mergeImages(dumpDir, lastPreDumpDir string) error {
+ idir, err := os.Open(dumpDir)
+ if err != nil {
+ return err
+ }
+
+ defer idir.Close()
+
+ imgs, err := idir.Readdirnames(0)
+ if err != nil {
+ return err
+ }
+
+ for _, fname := range imgs {
+ if !strings.HasSuffix(fname, ".img") {
+ continue
+ }
+
+ fmt.Printf("\t%s -> %s/\n", fname, lastPreDumpDir)
+ err = syscall.Link(dumpDir+"/"+fname, lastPreDumpDir+"/"+fname)
+ if err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+func (r *testRemote) doRestore() error {
+ lastSrvImagesDir := r.srv.LastImagesDir()
+ /*
+ * In imagesDir we have images from dump, in the
+ * lastSrvImagesDir -- where server-side images
+ * (from page server, with pages and pagemaps) are.
+ * Need to put former into latter and restore from
+ * them.
+ */
+ err := mergeImages(imagesDir+"/test", lastSrvImagesDir)
+ if err != nil {
+ return err
+ }
+
+ imgDir, err := os.Open(lastSrvImagesDir)
+ if err != nil {
+ return err
+ }
+ defer imgDir.Close()
+
+ opts := rpc.CriuOpts{
+ LogLevel: proto.Int32(4),
+ LogFile: proto.String("restore.log"),
+ ImagesDirFd: proto.Int32(int32(imgDir.Fd())),
+ }
+
+ cr := r.srv.GetCriu()
+ fmt.Printf("Do restore\n")
+ return cr.Restore(opts, nil)
+}
+
+func (l *testLocal) PostDump() error {
+ return l.r.doRestore()
+}
+
+func (l *testLocal) DumpCopyRestore(cr *criu.Criu, cfg phaul.Config, lastClnImagesDir string) error {
+ fmt.Printf("Final stage\n")
+
+ imgDir, err := os.Open(imagesDir + "/test")
+ if err != nil {
+ return err
+ }
+ defer imgDir.Close()
+
+ psi := rpc.CriuPageServerInfo{
+ Fd: proto.Int32(int32(cfg.Memfd)),
+ }
+
+ opts := rpc.CriuOpts{
+ Pid: proto.Int32(int32(cfg.Pid)),
+ LogLevel: proto.Int32(4),
+ LogFile: proto.String("dump.log"),
+ ImagesDirFd: proto.Int32(int32(imgDir.Fd())),
+ TrackMem: proto.Bool(true),
+ ParentImg: proto.String(lastClnImagesDir),
+ Ps: &psi,
+ }
+
+ fmt.Printf("Do dump\n")
+ return cr.Dump(opts, l)
+}
+
+func main() {
+ pid, _ := strconv.Atoi(os.Args[1])
+ fds, err := syscall.Socketpair(syscall.AF_LOCAL, syscall.SOCK_STREAM, 0)
+ if err != nil {
+ fmt.Printf("Can't make socketpair: %v\n", err)
+ os.Exit(1)
+ }
+
+ err = prepareImages()
+ if err != nil {
+ fmt.Printf("Can't prepare dirs for images: %v\n", err)
+ os.Exit(1)
+ return
+ }
+
+ fmt.Printf("Make server part (socket %d)\n", fds[1])
+ srv, err := phaul.MakePhaulServer(phaul.Config{
+ Pid: pid,
+ Memfd: fds[1],
+ Wdir: imagesDir + "/remote"})
+ if err != nil {
+ fmt.Printf("Unable to run a server: %v", err)
+ os.Exit(1)
+ return
+ }
+
+ r := &testRemote{srv}
+
+ fmt.Printf("Make client part (socket %d)\n", fds[0])
+ cln, err := phaul.MakePhaulClient(&testLocal{r: r}, srv,
+ phaul.Config{
+ Pid: pid,
+ Memfd: fds[0],
+ Wdir: imagesDir + "/local"})
+ if err != nil {
+ fmt.Printf("Unable to run a client: %v\n", err)
+ os.Exit(1)
+ }
+
+ fmt.Printf("Migrate\n")
+ err = cln.Migrate()
+ if err != nil {
+ fmt.Printf("Failed: %v\n", err)
+ os.Exit(1)
+ }
+
+ fmt.Printf("SUCCESS!\n")
+}