Skip to content

Commit 72b7f4b

Browse files
committed
task: allow checkpoint on pause state
task.Checkpoint should check status of container before handle checkpoint. If the container has been paused, task.Checkpoint should handle checkpoint and leave it paused. Signed-off-by: Wei Fu <[email protected]> Signed-off-by: Baijia <[email protected]>
1 parent 31a0f92 commit 72b7f4b

2 files changed

Lines changed: 92 additions & 3 deletions

File tree

integration/client/container_checkpoint_test.go

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -533,3 +533,83 @@ func TestCheckpointRestoreWithImagePath(t *testing.T) {
533533
<-statusC
534534
ntask.Delete(ctx)
535535
}
536+
537+
func TestCheckpointOnPauseStatus(t *testing.T) {
538+
if !supportsCriu {
539+
t.Skip("system does not have criu installed")
540+
}
541+
client, err := newClient(t, address)
542+
if err != nil {
543+
t.Fatal(err)
544+
}
545+
defer client.Close()
546+
if client.Runtime() == plugin.RuntimeLinuxV1 {
547+
t.Skip()
548+
}
549+
550+
var (
551+
ctx, cancel = testContext(t)
552+
id = t.Name()
553+
)
554+
defer cancel()
555+
556+
image, err := client.GetImage(ctx, testImage)
557+
if err != nil {
558+
t.Fatal(err)
559+
}
560+
container, err := client.NewContainer(ctx, id, WithNewSnapshot(id, image), WithNewSpec(oci.WithImageConfig(image), oci.WithProcessArgs("sleep", "10")))
561+
if err != nil {
562+
t.Fatal(err)
563+
}
564+
defer container.Delete(ctx, WithSnapshotCleanup)
565+
566+
task, err := container.NewTask(ctx, empty())
567+
if err != nil {
568+
t.Fatal(err)
569+
}
570+
defer func() {
571+
task.Resume(ctx)
572+
task.Delete(ctx)
573+
}()
574+
575+
statusC, err := task.Wait(ctx)
576+
if err != nil {
577+
t.Fatal(err)
578+
}
579+
580+
if err := task.Start(ctx); err != nil {
581+
t.Fatal(err)
582+
}
583+
584+
if err := task.Pause(ctx); err != nil {
585+
t.Fatal(err)
586+
}
587+
588+
_, err = container.Checkpoint(ctx, testCheckpointName+"on-pause", []CheckpointOpts{
589+
WithCheckpointRuntime,
590+
WithCheckpointRW,
591+
WithCheckpointTask,
592+
}...)
593+
if err != nil {
594+
t.Fatal(err)
595+
}
596+
597+
status, err := task.Status(ctx)
598+
if err != nil {
599+
t.Fatal(err)
600+
}
601+
602+
if status.Status != Paused {
603+
t.Fatalf("expected paused state, but got %s", status.Status)
604+
}
605+
606+
if err := task.Resume(ctx); err != nil {
607+
t.Fatal(err)
608+
}
609+
610+
if err := task.Kill(ctx, syscall.SIGKILL); err != nil {
611+
t.Fatal(err)
612+
}
613+
614+
<-statusC
615+
}

task.go

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -451,11 +451,20 @@ func (t *task) Checkpoint(ctx context.Context, opts ...CheckpointTaskOpts) (Imag
451451
}
452452
request.Options = any
453453
}
454-
// make sure we pause it and resume after all other filesystem operations are completed
455-
if err := t.Pause(ctx); err != nil {
454+
455+
status, err := t.Status(ctx)
456+
if err != nil {
456457
return nil, err
457458
}
458-
defer t.Resume(ctx)
459+
460+
if status.Status != Paused {
461+
// make sure we pause it and resume after all other filesystem operations are completed
462+
if err := t.Pause(ctx); err != nil {
463+
return nil, err
464+
}
465+
defer t.Resume(ctx)
466+
}
467+
459468
index := v1.Index{
460469
Versioned: is.Versioned{
461470
SchemaVersion: 2,

0 commit comments

Comments
 (0)