Skip to content

Commit

Permalink
Merge pull request #12333 from rst0git/file-locks
Browse files Browse the repository at this point in the history
Add --file-locks checkpoint/restore option
  • Loading branch information
openshift-merge-robot authored Nov 18, 2021
2 parents 0376e60 + 7098463 commit b24110e
Show file tree
Hide file tree
Showing 13 changed files with 101 additions and 0 deletions.
1 change: 1 addition & 0 deletions cmd/podman/containers/checkpoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ func init() {
flags.BoolVarP(&checkpointOptions.Keep, "keep", "k", false, "Keep all temporary checkpoint files")
flags.BoolVarP(&checkpointOptions.LeaveRunning, "leave-running", "R", false, "Leave the container running after writing checkpoint to disk")
flags.BoolVar(&checkpointOptions.TCPEstablished, "tcp-established", false, "Checkpoint a container with established TCP connections")
flags.BoolVar(&checkpointOptions.FileLocks, "file-locks", false, "Checkpoint a container with file locks")
flags.BoolVarP(&checkpointOptions.All, "all", "a", false, "Checkpoint all running containers")

exportFlagName := "export"
Expand Down
1 change: 1 addition & 0 deletions cmd/podman/containers/restore.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ func init() {
flags.BoolVarP(&restoreOptions.All, "all", "a", false, "Restore all checkpointed containers")
flags.BoolVarP(&restoreOptions.Keep, "keep", "k", false, "Keep all temporary checkpoint files")
flags.BoolVar(&restoreOptions.TCPEstablished, "tcp-established", false, "Restore a container with established TCP connections")
flags.BoolVar(&restoreOptions.FileLocks, "file-locks", false, "Restore a container with file locks")

importFlagName := "import"
flags.StringVarP(&restoreOptions.Import, importFlagName, "i", "", "Restore from exported checkpoint archive (tar.gz)")
Expand Down
8 changes: 8 additions & 0 deletions docs/source/markdown/podman-container-checkpoint.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,14 @@ restore. Defaults to not checkpointing *containers* with established TCP
connections.\
The default is **false**.

#### **--file-locks**

Checkpoint a *container* with file locks. If an application running in the container
is using file locks, this OPTION is required during checkpoint and restore. Otherwise
checkpointing *containers* with file locks is expected to fail. If file locks are not
used, this option is ignored.\
The default is **false**.

#### **--with-previous**

Check out the *container* with previous criu image files in pre-dump. It only works on `runc 1.0-rc3` or `higher`.\
Expand Down
8 changes: 8 additions & 0 deletions docs/source/markdown/podman-container-restore.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,14 @@ option is ignored. Defaults to not restoring *containers* with established TCP
connections.\
The default is **false**.

#### **--file-locks**

Restore a *container* with file locks. This option is required to
restore file locks from a checkpoint image. If the checkpoint image
does not contain file locks, this option is ignored. Defaults to not
restoring file locks.\
The default is **false**.

## EXAMPLE
Restores the container "mywebserver".
```
Expand Down
3 changes: 3 additions & 0 deletions libpod/container_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -798,6 +798,9 @@ type ContainerCheckpointOptions struct {
// how much time each component in the stack requires to
// checkpoint a container.
PrintStats bool
// FileLocks tells the API to checkpoint/restore a container
// with file-locks
FileLocks bool
}

// Checkpoint checkpoints a container
Expand Down
6 changes: 6 additions & 0 deletions libpod/oci_conmon_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -794,6 +794,9 @@ func (r *ConmonOCIRuntime) CheckpointContainer(ctr *Container, options Container
if options.TCPEstablished {
args = append(args, "--tcp-established")
}
if options.FileLocks {
args = append(args, "--file-locks")
}
if !options.PreCheckPoint && options.KeepRunning {
args = append(args, "--leave-running")
}
Expand Down Expand Up @@ -1101,6 +1104,9 @@ func (r *ConmonOCIRuntime) createOCIContainer(ctr *Container, restoreOptions *Co
if restoreOptions.TCPEstablished {
args = append(args, "--runtime-opt", "--tcp-established")
}
if restoreOptions.FileLocks {
args = append(args, "--runtime-opt", "--file-locks")
}
if restoreOptions.Pod != "" {
mountLabel := ctr.config.MountLabel
processLabel := ctr.config.ProcessLabel
Expand Down
2 changes: 2 additions & 0 deletions pkg/bindings/containers/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ type CheckpointOptions struct {
PrintStats *bool
PreCheckpoint *bool
WithPrevious *bool
FileLocks *bool
}

//go:generate go run ../generator/generator.go RestoreOptions
Expand All @@ -69,6 +70,7 @@ type RestoreOptions struct {
Pod *string
PrintStats *bool
PublishPorts []string
FileLocks *bool
}

//go:generate go run ../generator/generator.go CreateOptions
Expand Down
15 changes: 15 additions & 0 deletions pkg/bindings/containers/types_checkpoint_options.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 15 additions & 0 deletions pkg/bindings/containers/types_restore_options.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions pkg/domain/entities/containers.go
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ type CheckpointOptions struct {
WithPrevious bool
Compression archive.Compression
PrintStats bool
FileLocks bool
}

type CheckpointReport struct {
Expand All @@ -215,6 +216,7 @@ type RestoreOptions struct {
PublishPorts []string
Pod string
PrintStats bool
FileLocks bool
}

type RestoreReport struct {
Expand Down
1 change: 1 addition & 0 deletions pkg/domain/infra/abi/containers.go
Original file line number Diff line number Diff line change
Expand Up @@ -516,6 +516,7 @@ func (ic *ContainerEngine) ContainerCheckpoint(ctx context.Context, namesOrIds [
WithPrevious: options.WithPrevious,
Compression: options.Compression,
PrintStats: options.PrintStats,
FileLocks: options.FileLocks,
}

if options.All {
Expand Down
2 changes: 2 additions & 0 deletions pkg/domain/infra/tunnel/containers.go
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,7 @@ func (ic *ContainerEngine) ContainerExport(ctx context.Context, nameOrID string,

func (ic *ContainerEngine) ContainerCheckpoint(ctx context.Context, namesOrIds []string, opts entities.CheckpointOptions) ([]*entities.CheckpointReport, error) {
options := new(containers.CheckpointOptions)
options.WithFileLocks(opts.FileLocks)
options.WithIgnoreRootfs(opts.IgnoreRootFS)
options.WithKeep(opts.Keep)
options.WithExport(opts.Export)
Expand Down Expand Up @@ -352,6 +353,7 @@ func (ic *ContainerEngine) ContainerRestore(ctx context.Context, namesOrIds []st
}

options := new(containers.RestoreOptions)
options.WithFileLocks(opts.FileLocks)
options.WithIgnoreRootfs(opts.IgnoreRootFS)
options.WithIgnoreVolumes(opts.IgnoreVolumes)
options.WithIgnoreStaticIP(opts.IgnoreStaticIP)
Expand Down
37 changes: 37 additions & 0 deletions test/e2e/checkpoint_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1340,4 +1340,41 @@ var _ = Describe("Podman checkpoint", func() {
Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0))
})

It("podman checkpoint and restore container with --file-locks", func() {
if !strings.Contains(podmanTest.OCIRuntime, "runc") {
// TODO: Enable test for crun when this feature has been released
// https://github.com/containers/crun/pull/783
Skip("FIXME: requires crun >= 1.4")
}
localRunString := getRunString([]string{"--name", "test_name", ALPINE, "flock", "test.lock", "sleep", "100"})
session := podmanTest.Podman(localRunString)
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))

// Checkpoint is expected to fail without --file-locks
result := podmanTest.Podman([]string{"container", "checkpoint", "test_name"})
result.WaitWithDefaultTimeout()
Expect(result).Should(Exit(125))
Expect(result.ErrorToString()).To(ContainSubstring("criu failed"))
Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1))

// Checkpoint is expected to succeed with --file-locks
result = podmanTest.Podman([]string{"container", "checkpoint", "--file-locks", "test_name"})
result.WaitWithDefaultTimeout()
Expect(result).Should(Exit(0))
Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0))
Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Exited"))

result = podmanTest.Podman([]string{"container", "restore", "--file-locks", "test_name"})
result.WaitWithDefaultTimeout()

Expect(result).Should(Exit(0))
Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1))
Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up"))

result = podmanTest.Podman([]string{"rm", "-t", "0", "-f", "test_name"})
result.WaitWithDefaultTimeout()
Expect(result).Should(Exit(0))
Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0))
})
})

0 comments on commit b24110e

Please sign in to comment.