summaryrefslogtreecommitdiff
path: root/vendor/github.com/checkpoint-restore/go-criu/test
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/checkpoint-restore/go-criu/test')
-rw-r--r--vendor/github.com/checkpoint-restore/go-criu/test/main.go133
-rw-r--r--vendor/github.com/checkpoint-restore/go-criu/test/phaul-main.go192
-rw-r--r--vendor/github.com/checkpoint-restore/go-criu/test/piggie.c57
3 files changed, 382 insertions, 0 deletions
diff --git a/vendor/github.com/checkpoint-restore/go-criu/test/main.go b/vendor/github.com/checkpoint-restore/go-criu/test/main.go
new file mode 100644
index 000000000..418ebb843
--- /dev/null
+++ b/vendor/github.com/checkpoint-restore/go-criu/test/main.go
@@ -0,0 +1,133 @@
+package main
+
+import (
+ "fmt"
+ "github.com/checkpoint-restore/go-criu"
+ "github.com/checkpoint-restore/go-criu/rpc"
+ "github.com/golang/protobuf/proto"
+ "os"
+ "strconv"
+)
+
+// TestNfy struct
+type TestNfy struct {
+ criu.NoNotify
+}
+
+// PreDump test function
+func (c TestNfy) PreDump() error {
+ fmt.Printf("TEST PRE DUMP\n")
+ return nil
+}
+
+func doDump(c *criu.Criu, pidS string, imgDir string, pre bool, prevImg string) error {
+ fmt.Printf("Dumping\n")
+ pid, _ := strconv.Atoi(pidS)
+ img, err := os.Open(imgDir)
+ if err != nil {
+ return fmt.Errorf("can't open image dir (%s)", err)
+ }
+ defer img.Close()
+
+ opts := rpc.CriuOpts{
+ Pid: proto.Int32(int32(pid)),
+ ImagesDirFd: proto.Int32(int32(img.Fd())),
+ LogLevel: proto.Int32(4),
+ LogFile: proto.String("dump.log"),
+ }
+
+ if prevImg != "" {
+ opts.ParentImg = proto.String(prevImg)
+ opts.TrackMem = proto.Bool(true)
+ }
+
+ if pre {
+ err = c.PreDump(opts, TestNfy{})
+ } else {
+ err = c.Dump(opts, TestNfy{})
+ }
+ if err != nil {
+ return fmt.Errorf("dump fail (%s)", err)
+ }
+
+ return nil
+}
+
+// Usage: test $act $pid $images_dir
+func main() {
+ c := criu.MakeCriu()
+ // Read out CRIU version
+ version, err := c.GetCriuVersion()
+ if err != nil {
+ fmt.Println(err)
+ os.Exit(1)
+ }
+ fmt.Println("CRIU version", version)
+ // Check if version at least 3.2
+ result, err := c.IsCriuAtLeast(30200)
+ if err != nil {
+ fmt.Println(err)
+ os.Exit(1)
+ }
+ if !result {
+ fmt.Println("CRIU too old")
+ os.Exit(1)
+ }
+ act := os.Args[1]
+ switch act {
+ case "dump":
+ err := doDump(c, os.Args[2], os.Args[3], false, "")
+ if err != nil {
+ fmt.Print(err)
+ os.Exit(1)
+ }
+ case "dump2":
+ err := c.Prepare()
+ if err != nil {
+ fmt.Print(err)
+ os.Exit(1)
+ }
+
+ err = doDump(c, os.Args[2], os.Args[3]+"/pre", true, "")
+ if err != nil {
+ fmt.Printf("pre-dump failed")
+ fmt.Print(err)
+ os.Exit(1)
+ }
+ err = doDump(c, os.Args[2], os.Args[3], false, "./pre")
+ if err != nil {
+ fmt.Printf("dump failed")
+ fmt.Print(err)
+ os.Exit(1)
+ }
+
+ c.Cleanup()
+ case "restore":
+ fmt.Printf("Restoring\n")
+ img, err := os.Open(os.Args[2])
+ if err != nil {
+ fmt.Printf("can't open image dir")
+ os.Exit(1)
+ }
+ defer img.Close()
+
+ opts := rpc.CriuOpts{
+ ImagesDirFd: proto.Int32(int32(img.Fd())),
+ LogLevel: proto.Int32(4),
+ LogFile: proto.String("restore.log"),
+ }
+
+ err = c.Restore(opts, nil)
+ if err != nil {
+ fmt.Printf("Error:")
+ fmt.Print(err)
+ fmt.Printf("\n")
+ os.Exit(1)
+ }
+ default:
+ fmt.Printf("unknown action\n")
+ os.Exit(1)
+ }
+
+ fmt.Printf("Success\n")
+}
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")
+}
diff --git a/vendor/github.com/checkpoint-restore/go-criu/test/piggie.c b/vendor/github.com/checkpoint-restore/go-criu/test/piggie.c
new file mode 100644
index 000000000..1dc0801c0
--- /dev/null
+++ b/vendor/github.com/checkpoint-restore/go-criu/test/piggie.c
@@ -0,0 +1,57 @@
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <signal.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <sched.h>
+
+#define STKS (4*4096)
+
+#ifndef CLONE_NEWPID
+#define CLONE_NEWPID 0x20000000
+#endif
+
+static int do_test(void *logf)
+{
+ int fd, i = 0;
+
+ setsid();
+
+ close(0);
+ close(1);
+ close(2);
+
+ fd = open("/dev/null", O_RDONLY);
+ if (fd != 0) {
+ dup2(fd, 0);
+ close(fd);
+ }
+
+ fd = open(logf, O_WRONLY | O_TRUNC | O_CREAT, 0600);
+ dup2(fd, 1);
+ dup2(fd, 2);
+ if (fd != 1 && fd != 2)
+ close(fd);
+
+ while (1) {
+ sleep(1);
+ printf("%d\n", i++);
+ fflush(stdout);
+ }
+
+ return 0;
+}
+
+int main(int argc, char **argv)
+{
+ int pid;
+ void *stk;
+
+ stk = mmap(NULL, STKS, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANON | MAP_GROWSDOWN, 0, 0);
+ pid = clone(do_test, stk + STKS, SIGCHLD | CLONE_NEWPID, argv[1]);
+ printf("Child forked, pid %d\n", pid);
+
+ return 0;
+}