From 7ab132983560b067eb71b8043220778faebf0ea2 Mon Sep 17 00:00:00 2001 From: Kir Kolyshkin Date: Mon, 11 May 2020 16:37:45 -0700 Subject: [PATCH 1/2] libct/criuNotifications: simplify switch Signed-off-by: Kir Kolyshkin --- libcontainer/container_linux.go | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/libcontainer/container_linux.go b/libcontainer/container_linux.go index b4aa98af..4faa07be 100644 --- a/libcontainer/container_linux.go +++ b/libcontainer/container_linux.go @@ -1575,23 +1575,24 @@ func (c *linuxContainer) criuNotifications(resp *criurpc.CriuResp, process *Proc if notify == nil { return fmt.Errorf("invalid response: %s", resp.String()) } - logrus.Debugf("notify: %s\n", notify.GetScript()) - switch { - case notify.GetScript() == "post-dump": + script := notify.GetScript() + logrus.Debugf("notify: %s\n", script) + switch script { + case "post-dump": f, err := os.Create(filepath.Join(c.root, "checkpoint")) if err != nil { return err } f.Close() - case notify.GetScript() == "network-unlock": + case "network-unlock": if err := unlockNetwork(c.config); err != nil { return err } - case notify.GetScript() == "network-lock": + case "network-lock": if err := lockNetwork(c.config); err != nil { return err } - case notify.GetScript() == "setup-namespaces": + case "setup-namespaces": if c.config.Hooks != nil { s, err := c.currentOCIState() if err != nil { @@ -1604,7 +1605,7 @@ func (c *linuxContainer) criuNotifications(resp *criurpc.CriuResp, process *Proc } } } - case notify.GetScript() == "post-restore": + case "post-restore": pid := notify.GetPid() p, err := os.FindProcess(int(pid)) @@ -1634,7 +1635,7 @@ func (c *linuxContainer) criuNotifications(resp *criurpc.CriuResp, process *Proc logrus.Error(err) } } - case notify.GetScript() == "orphan-pts-master": + case "orphan-pts-master": scm, err := unix.ParseSocketControlMessage(oob) if err != nil { return err From 68391c0e9679a1f00bb6cfc0bc186beaf6e6b449 Mon Sep 17 00:00:00 2001 From: Kir Kolyshkin Date: Tue, 12 May 2020 10:57:04 -0700 Subject: [PATCH 2/2] use lazy-pages ready notification for criu >= 3.15 This relies on https://github.com/checkpoint-restore/criu/pull/1069 and emulates the previous behavior by writing \0 and closing status fd (as it was done by criu). Signed-off-by: Kir Kolyshkin --- libcontainer/container_linux.go | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/libcontainer/container_linux.go b/libcontainer/container_linux.go index 4faa07be..139b7d0a 100644 --- a/libcontainer/container_linux.go +++ b/libcontainer/container_linux.go @@ -973,7 +973,11 @@ func (c *linuxContainer) Checkpoint(criuOpts *CriuOpts) error { return fmt.Errorf("invalid --status-fd argument %d: not writable", fd) } - rpcOpts.StatusFd = proto.Int32(int32(fd)) + if c.checkCriuVersion(31500) != nil { + // For criu 3.15+, use notifications (see case "status-ready" + // in criuNotifications). Otherwise, rely on criu status fd. + rpcOpts.StatusFd = proto.Int32(int32(fd)) + } } } @@ -1652,6 +1656,16 @@ func (c *linuxContainer) criuNotifications(resp *criurpc.CriuResp, process *Proc if err := utils.SendFd(process.ConsoleSocket, master.Name(), master.Fd()); err != nil { return err } + case "status-ready": + if opts.StatusFd != -1 { + // write \0 to status fd to notify that lazy page server is ready + _, err := unix.Write(opts.StatusFd, []byte{0}) + if err != nil { + logrus.Warnf("can't write \\0 to status fd: %v", err) + } + _ = unix.Close(opts.StatusFd) + opts.StatusFd = -1 + } } return nil }