diff --git a/runc.go b/runc.go index 61646df..b831f87 100644 --- a/runc.go +++ b/runc.go @@ -526,7 +526,9 @@ type CheckpointOpts struct { LazyPages bool // StatusFile is the file criu writes \0 to once lazy-pages is ready StatusFile *os.File - ExtraArgs []string + // AutoDedup enables auto deduplication of memory images + AutoDedup bool + ExtraArgs []string } // CgroupMode defines the cgroup mode used for checkpointing @@ -575,6 +577,9 @@ func (o *CheckpointOpts) args() (out []string) { if o.LazyPages { out = append(out, "--lazy-pages") } + if o.AutoDedup { + out = append(out, "--auto-dedup") + } if len(o.ExtraArgs) > 0 { out = append(out, o.ExtraArgs...) } diff --git a/runc_test.go b/runc_test.go index 610cffd..2ad2793 100644 --- a/runc_test.go +++ b/runc_test.go @@ -287,7 +287,7 @@ func interrupt(ctx context.Context, t *testing.T, started <-chan int) { } } -// dummySleepRunc creates s simple script that just runs `sleep 10` to replace +// dummySleepRunc creates a simple script that just runs `sleep 10` to replace // runc for testing process that are longer running. func dummySleepRunc() (_ string, err error) { fh, err := os.CreateTemp("", "*.sh") @@ -314,6 +314,42 @@ func dummySleepRunc() (_ string, err error) { return fh.Name(), nil } +func TestRuncCheckpoint(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + okRunc := &Runc{ + Command: "/bin/true", + } + + opts := &CheckpointOpts{ + AutoDedup: true, + } + err := okRunc.Checkpoint(ctx, "fake-id", opts) + if err != nil { + t.Fatalf("unexpected error from Checkpoint: %v", err) + } +} + +func TestRuncRestore(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + okRunc := &Runc{ + Command: "/bin/true", + } + + opts := &RestoreOpts{ + CheckpointOpts: CheckpointOpts{ + AutoDedup: true, + }, + } + _, err := okRunc.Restore(ctx, "fake-id", "fake-bundle", opts) + if err != nil { + t.Fatalf("unexpected error from Checkpoint: %v", err) + } +} + func TestCreateArgs(t *testing.T) { o := &CreateOpts{} args, err := o.args() @@ -336,6 +372,24 @@ func TestCreateArgs(t *testing.T) { } } +func TestCheckpointArgs(t *testing.T) { + o := &CheckpointOpts{} + args := o.args() + if len(args) != 0 { + t.Fatal("args should be empty") + } + o = &CheckpointOpts{ + AutoDedup: true, + } + args = o.args() + if len(args) != 1 { + t.Fatal("args should have 1 arg") + } + if actual := args[0]; actual != "--auto-dedup" { + t.Fatalf("arg should be --auto-dedup but got %s", actual) + } +} + func TestRuncFeatures(t *testing.T) { ctx := context.Background() if _, err := exec.LookPath(DefaultCommand); err != nil {