mirror of
https://github.com/checkpoint-restore/criu.git
synced 2026-07-17 16:47:50 +00:00
Go-criu clean up
The Go bindings for CRIU and the P.Haul extension have been moved into a separate repository. This patch removes the following from the criu-dev branch: - lib/go/* - phaul/* - scripts/travis/phaul The removed files are available in https://github.com/checkpoint-restore/go-criu Signed-off-by: Radostin Stoyanov <rstoyanov1@gmail.com> Signed-off-by: Andrei Vagin <avagin@gmail.com>
This commit is contained in:
parent
44a10467a6
commit
12fb7f5af0
6 changed files with 3 additions and 353 deletions
|
|
@ -39,7 +39,9 @@ injection and libsoccr for TCP connections checkpoint-restore.
|
|||
|
||||
True [live migration](https://criu.org/Live_migration) using CRIU is possible, but doing
|
||||
all the steps by hands might be complicated. The [phaul sub-project](https://criu.org/P.Haul)
|
||||
provides a Go library that encapsulates most of the complexity.
|
||||
provides a Go library that encapsulates most of the complexity. This library and the Go bindings
|
||||
for CRIU are stored in the [go-criu](https://github.com/checkpoint-restore/go-criu) repository.
|
||||
|
||||
|
||||
### Parasite code injection
|
||||
|
||||
|
|
|
|||
1
lib/go/.gitignore
vendored
1
lib/go/.gitignore
vendored
|
|
@ -1 +0,0 @@
|
|||
src/rpc/rpc.pb.go
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
all: test
|
||||
|
||||
test: rpc
|
||||
GOPATH=$(shell pwd):/usr/share/gocode go build -o test test
|
||||
|
||||
rpc:
|
||||
mkdir -p src/rpc/
|
||||
protoc --go_out=src/rpc/ --proto_path=../../images/ ../../images/rpc.proto
|
||||
|
|
@ -1,177 +0,0 @@
|
|||
package criu
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/golang/protobuf/proto"
|
||||
"os"
|
||||
"os/exec"
|
||||
"rpc"
|
||||
"strconv"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
type Criu struct {
|
||||
swrk_cmd *exec.Cmd
|
||||
swrk_sk *os.File
|
||||
}
|
||||
|
||||
func MakeCriu() *Criu {
|
||||
return &Criu{}
|
||||
}
|
||||
|
||||
func (c *Criu) Prepare() error {
|
||||
fds, err := syscall.Socketpair(syscall.AF_LOCAL, syscall.SOCK_SEQPACKET, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cln := os.NewFile(uintptr(fds[0]), "criu-xprt-cln")
|
||||
syscall.CloseOnExec(fds[0])
|
||||
srv := os.NewFile(uintptr(fds[1]), "criu-xprt-srv")
|
||||
defer srv.Close()
|
||||
|
||||
args := []string{"swrk", strconv.Itoa(fds[1])}
|
||||
cmd := exec.Command("criu", args...)
|
||||
|
||||
err = cmd.Start()
|
||||
if err != nil {
|
||||
cln.Close()
|
||||
return err
|
||||
}
|
||||
|
||||
c.swrk_cmd = cmd
|
||||
c.swrk_sk = cln
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Criu) Cleanup() {
|
||||
if c.swrk_cmd != nil {
|
||||
c.swrk_sk.Close()
|
||||
c.swrk_sk = nil
|
||||
c.swrk_cmd.Wait()
|
||||
c.swrk_cmd = nil
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Criu) sendAndRecv(req_b []byte) ([]byte, int, error) {
|
||||
cln := c.swrk_sk
|
||||
_, err := cln.Write(req_b)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
resp_b := make([]byte, 2*4096)
|
||||
n, err := cln.Read(resp_b)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
return resp_b, n, nil
|
||||
}
|
||||
|
||||
func (c *Criu) doSwrk(req_type rpc.CriuReqType, opts *rpc.CriuOpts, nfy CriuNotify) error {
|
||||
req := rpc.CriuReq{
|
||||
Type: &req_type,
|
||||
Opts: opts,
|
||||
}
|
||||
|
||||
if nfy != nil {
|
||||
opts.NotifyScripts = proto.Bool(true)
|
||||
}
|
||||
|
||||
if c.swrk_cmd == nil {
|
||||
err := c.Prepare()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer c.Cleanup()
|
||||
}
|
||||
|
||||
for {
|
||||
req_b, err := proto.Marshal(&req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
resp_b, resp_s, err := c.sendAndRecv(req_b)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
resp := &rpc.CriuResp{}
|
||||
err = proto.Unmarshal(resp_b[:resp_s], resp)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !resp.GetSuccess() {
|
||||
return fmt.Errorf("operation failed (msg:%s err:%d)",
|
||||
resp.GetCrErrmsg(), resp.GetCrErrno())
|
||||
}
|
||||
|
||||
resp_type := resp.GetType()
|
||||
if resp_type == req_type {
|
||||
break
|
||||
}
|
||||
if resp_type != rpc.CriuReqType_NOTIFY {
|
||||
return errors.New("unexpected responce")
|
||||
}
|
||||
if nfy == nil {
|
||||
return errors.New("unexpected notify")
|
||||
}
|
||||
|
||||
notify := resp.GetNotify()
|
||||
switch notify.GetScript() {
|
||||
case "pre-dump":
|
||||
err = nfy.PreDump()
|
||||
case "post-dump":
|
||||
err = nfy.PostDump()
|
||||
case "pre-restore":
|
||||
err = nfy.PreRestore()
|
||||
case "post-restore":
|
||||
err = nfy.PostRestore(notify.GetPid())
|
||||
case "network-lock":
|
||||
err = nfy.NetworkLock()
|
||||
case "network-unlock":
|
||||
err = nfy.NetworkUnlock()
|
||||
case "setup-namespaces":
|
||||
err = nfy.SetupNamespaces(notify.GetPid())
|
||||
case "post-setup-namespaces":
|
||||
err = nfy.PostSetupNamespaces()
|
||||
case "post-resume":
|
||||
err = nfy.PostResume()
|
||||
default:
|
||||
err = nil
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
req = rpc.CriuReq{
|
||||
Type: &resp_type,
|
||||
NotifySuccess: proto.Bool(true),
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Criu) Dump(opts rpc.CriuOpts, nfy CriuNotify) error {
|
||||
return c.doSwrk(rpc.CriuReqType_DUMP, &opts, nfy)
|
||||
}
|
||||
|
||||
func (c *Criu) Restore(opts rpc.CriuOpts, nfy CriuNotify) error {
|
||||
return c.doSwrk(rpc.CriuReqType_RESTORE, &opts, nfy)
|
||||
}
|
||||
|
||||
func (c *Criu) PreDump(opts rpc.CriuOpts, nfy CriuNotify) error {
|
||||
return c.doSwrk(rpc.CriuReqType_PRE_DUMP, &opts, nfy)
|
||||
}
|
||||
|
||||
func (c *Criu) StartPageServer(opts rpc.CriuOpts) error {
|
||||
return c.doSwrk(rpc.CriuReqType_PAGE_SERVER, &opts, nil)
|
||||
}
|
||||
|
|
@ -1,52 +0,0 @@
|
|||
package criu
|
||||
|
||||
type CriuNotify interface {
|
||||
PreDump() error
|
||||
PostDump() error
|
||||
PreRestore() error
|
||||
PostRestore(pid int32) error
|
||||
NetworkLock() error
|
||||
NetworkUnlock() error
|
||||
SetupNamespaces(pid int32) error
|
||||
PostSetupNamespaces() error
|
||||
PostResume() error
|
||||
}
|
||||
|
||||
type CriuNoNotify struct {
|
||||
}
|
||||
|
||||
func (c CriuNoNotify) PreDump() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c CriuNoNotify) PostDump() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c CriuNoNotify) PreRestore() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c CriuNoNotify) PostRestore(pid int32) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c CriuNoNotify) NetworkLock() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c CriuNoNotify) NetworkUnlock() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c CriuNoNotify) SetupNamespaces(pid int32) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c CriuNoNotify) PostSetupNamespaces() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c CriuNoNotify) PostResume() error {
|
||||
return nil
|
||||
}
|
||||
|
|
@ -1,114 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"criu"
|
||||
"fmt"
|
||||
"github.com/golang/protobuf/proto"
|
||||
"os"
|
||||
"rpc"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
type TestNfy struct {
|
||||
criu.CriuNoNotify
|
||||
}
|
||||
|
||||
func (c TestNfy) PreDump() error {
|
||||
fmt.Printf("TEST PRE DUMP\n")
|
||||
return nil
|
||||
}
|
||||
|
||||
func doDump(c *criu.Criu, pid_s string, img_dir string, pre bool, prev_img string) error {
|
||||
fmt.Printf("Dumping\n")
|
||||
pid, _ := strconv.Atoi(pid_s)
|
||||
img, err := os.Open(img_dir)
|
||||
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 prev_img != "" {
|
||||
opts.ParentImg = proto.String(prev_img)
|
||||
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()
|
||||
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")
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue