Skip to content

Commit c487840

Browse files
committed
Remove main package dependency on criurpc
Commit 7f64fb4 made the main package, and runc/libcontainer's CriuOpts depend on criu/rpc. This is not good; among the other things, it makes it complicated to make c/r optional. Let's switch CriuOpts.ManageCgroupsMode to a string (yes, it's an APIt breaking change) and move the cgroup mode string parsing to libcontainer. While at it, let's better document ManageCgroupsMode. Signed-off-by: Kir Kolyshkin <[email protected]>
1 parent e075206 commit c487840

File tree

3 files changed

+69
-63
lines changed

3 files changed

+69
-63
lines changed

checkpoint.go

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import (
88
"path/filepath"
99
"strconv"
1010

11-
criu "github.com/checkpoint-restore/go-criu/v6/rpc"
1211
"github.com/moby/sys/userns"
1312
"github.com/opencontainers/runtime-spec/specs-go"
1413
"github.com/sirupsen/logrus"
@@ -132,6 +131,7 @@ func criuOptions(context *cli.Context) (*libcontainer.CriuOpts, error) {
132131
StatusFd: context.Int("status-fd"),
133132
LsmProfile: context.String("lsm-profile"),
134133
LsmMountContext: context.String("lsm-mount-context"),
134+
ManageCgroupsMode: context.String("manage-cgroups-mode"),
135135
}
136136

137137
// CRIU options below may or may not be set.
@@ -152,21 +152,6 @@ func criuOptions(context *cli.Context) (*libcontainer.CriuOpts, error) {
152152
}
153153
}
154154

155-
switch context.String("manage-cgroups-mode") {
156-
case "":
157-
// do nothing
158-
case "soft":
159-
opts.ManageCgroupsMode = criu.CriuCgMode_SOFT
160-
case "full":
161-
opts.ManageCgroupsMode = criu.CriuCgMode_FULL
162-
case "strict":
163-
opts.ManageCgroupsMode = criu.CriuCgMode_STRICT
164-
case "ignore":
165-
opts.ManageCgroupsMode = criu.CriuCgMode_IGNORE
166-
default:
167-
return nil, errors.New("Invalid manage-cgroups-mode value")
168-
}
169-
170155
// runc doesn't manage network devices and their configuration.
171156
nsmask := unix.CLONE_NEWNET
172157

libcontainer/criu_linux.go

Lines changed: 62 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,11 @@ func (c *Container) Checkpoint(criuOpts *CriuOpts) error {
295295
return errors.New("invalid directory to save checkpoint")
296296
}
297297

298+
cgMode, err := criuCgMode(criuOpts.ManageCgroupsMode)
299+
if err != nil {
300+
return err
301+
}
302+
298303
// Since a container can be C/R'ed multiple times,
299304
// the checkpoint directory may already exist.
300305
if err := os.Mkdir(criuOpts.ImagesDirectory, 0o700); err != nil && !os.IsExist(err) {
@@ -309,22 +314,23 @@ func (c *Container) Checkpoint(criuOpts *CriuOpts) error {
309314
defer imageDir.Close()
310315

311316
rpcOpts := criurpc.CriuOpts{
312-
ImagesDirFd: proto.Int32(int32(imageDir.Fd())),
313-
LogLevel: proto.Int32(4),
314-
LogFile: proto.String(logFile),
315-
Root: proto.String(c.config.Rootfs),
316-
ManageCgroups: proto.Bool(true),
317-
NotifyScripts: proto.Bool(true),
318-
Pid: proto.Int32(int32(c.initProcess.pid())),
319-
ShellJob: proto.Bool(criuOpts.ShellJob),
320-
LeaveRunning: proto.Bool(criuOpts.LeaveRunning),
321-
TcpEstablished: proto.Bool(criuOpts.TcpEstablished),
322-
ExtUnixSk: proto.Bool(criuOpts.ExternalUnixConnections),
323-
FileLocks: proto.Bool(criuOpts.FileLocks),
324-
EmptyNs: proto.Uint32(criuOpts.EmptyNs),
325-
OrphanPtsMaster: proto.Bool(true),
326-
AutoDedup: proto.Bool(criuOpts.AutoDedup),
327-
LazyPages: proto.Bool(criuOpts.LazyPages),
317+
ImagesDirFd: proto.Int32(int32(imageDir.Fd())),
318+
LogLevel: proto.Int32(4),
319+
LogFile: proto.String(logFile),
320+
Root: proto.String(c.config.Rootfs),
321+
ManageCgroups: proto.Bool(true), // Obsoleted by ManageCgroupsMode.
322+
ManageCgroupsMode: &cgMode,
323+
NotifyScripts: proto.Bool(true),
324+
Pid: proto.Int32(int32(c.initProcess.pid())),
325+
ShellJob: proto.Bool(criuOpts.ShellJob),
326+
LeaveRunning: proto.Bool(criuOpts.LeaveRunning),
327+
TcpEstablished: proto.Bool(criuOpts.TcpEstablished),
328+
ExtUnixSk: proto.Bool(criuOpts.ExternalUnixConnections),
329+
FileLocks: proto.Bool(criuOpts.FileLocks),
330+
EmptyNs: proto.Uint32(criuOpts.EmptyNs),
331+
OrphanPtsMaster: proto.Bool(true),
332+
AutoDedup: proto.Bool(criuOpts.AutoDedup),
333+
LazyPages: proto.Bool(criuOpts.LazyPages),
328334
}
329335

330336
// if criuOpts.WorkDirectory is not set, criu default is used.
@@ -381,12 +387,6 @@ func (c *Container) Checkpoint(criuOpts *CriuOpts) error {
381387
rpcOpts.TrackMem = proto.Bool(true)
382388
}
383389

384-
// append optional manage cgroups mode
385-
if criuOpts.ManageCgroupsMode != 0 {
386-
mode := criuOpts.ManageCgroupsMode
387-
rpcOpts.ManageCgroupsMode = &mode
388-
}
389-
390390
var t criurpc.CriuReqType
391391
if criuOpts.PreDump {
392392
feat := criurpc.CriuFeatures{
@@ -634,6 +634,12 @@ func (c *Container) Restore(process *Process, criuOpts *CriuOpts) error {
634634
if criuOpts.ImagesDirectory == "" {
635635
return errors.New("invalid directory to restore checkpoint")
636636
}
637+
638+
cgMode, err := criuCgMode(criuOpts.ManageCgroupsMode)
639+
if err != nil {
640+
return err
641+
}
642+
637643
logDir := criuOpts.ImagesDirectory
638644
imageDir, err := os.Open(criuOpts.ImagesDirectory)
639645
if err != nil {
@@ -663,22 +669,23 @@ func (c *Container) Restore(process *Process, criuOpts *CriuOpts) error {
663669
req := &criurpc.CriuReq{
664670
Type: &t,
665671
Opts: &criurpc.CriuOpts{
666-
ImagesDirFd: proto.Int32(int32(imageDir.Fd())),
667-
EvasiveDevices: proto.Bool(true),
668-
LogLevel: proto.Int32(4),
669-
LogFile: proto.String(logFile),
670-
RstSibling: proto.Bool(true),
671-
Root: proto.String(root),
672-
ManageCgroups: proto.Bool(true),
673-
NotifyScripts: proto.Bool(true),
674-
ShellJob: proto.Bool(criuOpts.ShellJob),
675-
ExtUnixSk: proto.Bool(criuOpts.ExternalUnixConnections),
676-
TcpEstablished: proto.Bool(criuOpts.TcpEstablished),
677-
FileLocks: proto.Bool(criuOpts.FileLocks),
678-
EmptyNs: proto.Uint32(criuOpts.EmptyNs),
679-
OrphanPtsMaster: proto.Bool(true),
680-
AutoDedup: proto.Bool(criuOpts.AutoDedup),
681-
LazyPages: proto.Bool(criuOpts.LazyPages),
672+
ImagesDirFd: proto.Int32(int32(imageDir.Fd())),
673+
EvasiveDevices: proto.Bool(true),
674+
LogLevel: proto.Int32(4),
675+
LogFile: proto.String(logFile),
676+
RstSibling: proto.Bool(true),
677+
Root: proto.String(root),
678+
ManageCgroups: proto.Bool(true), // Obsoleted by ManageCgroupsMode.
679+
ManageCgroupsMode: &cgMode,
680+
NotifyScripts: proto.Bool(true),
681+
ShellJob: proto.Bool(criuOpts.ShellJob),
682+
ExtUnixSk: proto.Bool(criuOpts.ExternalUnixConnections),
683+
TcpEstablished: proto.Bool(criuOpts.TcpEstablished),
684+
FileLocks: proto.Bool(criuOpts.FileLocks),
685+
EmptyNs: proto.Uint32(criuOpts.EmptyNs),
686+
OrphanPtsMaster: proto.Bool(true),
687+
AutoDedup: proto.Bool(criuOpts.AutoDedup),
688+
LazyPages: proto.Bool(criuOpts.LazyPages),
682689
},
683690
}
684691

@@ -757,12 +764,6 @@ func (c *Container) Restore(process *Process, criuOpts *CriuOpts) error {
757764
c.restoreNetwork(req, criuOpts)
758765
}
759766

760-
// append optional manage cgroups mode
761-
if criuOpts.ManageCgroupsMode != 0 {
762-
mode := criuOpts.ManageCgroupsMode
763-
req.Opts.ManageCgroupsMode = &mode
764-
}
765-
766767
var (
767768
fds []string
768769
fdJSON []byte
@@ -1184,3 +1185,20 @@ func (c *Container) criuNotifications(resp *criurpc.CriuResp, process *Process,
11841185
}
11851186
return nil
11861187
}
1188+
1189+
func criuCgMode(mode string) (criurpc.CriuCgMode, error) {
1190+
switch mode {
1191+
case "":
1192+
return criurpc.CriuCgMode_DEFAULT, nil
1193+
case "soft":
1194+
return criurpc.CriuCgMode_SOFT, nil
1195+
case "full":
1196+
return criurpc.CriuCgMode_FULL, nil
1197+
case "strict":
1198+
return criurpc.CriuCgMode_STRICT, nil
1199+
case "ignore":
1200+
return criurpc.CriuCgMode_IGNORE, nil
1201+
default:
1202+
return 0, errors.New("invalid manage-cgroups-mode value")
1203+
}
1204+
}

libcontainer/criu_opts_linux.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
package libcontainer
22

3-
import criu "github.com/checkpoint-restore/go-criu/v6/rpc"
4-
53
type CriuPageServerInfo struct {
64
Address string // IP address of CRIU page server
75
Port int32 // port number of CRIU page server
@@ -24,11 +22,16 @@ type CriuOpts struct {
2422
PreDump bool // call criu predump to perform iterative checkpoint
2523
PageServer CriuPageServerInfo // allow to dump to criu page server
2624
VethPairs []VethPairName // pass the veth to criu when restore
27-
ManageCgroupsMode criu.CriuCgMode // dump or restore cgroup mode
2825
EmptyNs uint32 // don't c/r properties for namespace from this mask
2926
AutoDedup bool // auto deduplication for incremental dumps
3027
LazyPages bool // restore memory pages lazily using userfaultfd
3128
StatusFd int // fd for feedback when lazy server is ready
3229
LsmProfile string // LSM profile used to restore the container
3330
LsmMountContext string // LSM mount context value to use during restore
31+
32+
// ManageCgroupsMode tells how criu should manage cgroups during
33+
// checkpoint or restore. Possible values are: "soft", "full",
34+
// "strict", "ignore", or "" (empty string) for criu default.
35+
// See https://criu.org/CGroups for more details.
36+
ManageCgroupsMode string
3437
}

0 commit comments

Comments
 (0)