diff options
author | Radostin Stoyanov <rstoyanov@fedoraproject.org> | 2021-12-20 19:28:24 +0000 |
---|---|---|
committer | Radostin Stoyanov <rstoyanov@fedoraproject.org> | 2021-12-23 05:47:25 +0000 |
commit | f3d485d4d7050b6bd5f121f95eceb8c4b789ffd4 (patch) | |
tree | 5542f09a4f156bc7ea71f2f6b1d49cf1ded41cac | |
parent | 2d7dbda415b41724d0900403c3ac50b29985e763 (diff) | |
download | podman-f3d485d4d7050b6bd5f121f95eceb8c4b789ffd4.tar.gz podman-f3d485d4d7050b6bd5f121f95eceb8c4b789ffd4.tar.bz2 podman-f3d485d4d7050b6bd5f121f95eceb8c4b789ffd4.zip |
Enable checkpoint/restore for /dev/shm
When Podman is running a container in private IPC mode (default), it
creates a bind mount for /dev/shm that is then attached to a tmpfs
folder on the host file system. However, checkpointing a container has
the side-effect of stopping that container and unmount the tmpfs used
for /dev/shm. As a result, after checkpoint all files stored in the
container's /dev/shm would be lost and the container might fail to
restore from checkpoint.
To address this problem, this patch creates a tar file with the
content of /dev/shm that is included in the container checkpoint and
used to restore the container.
Signed-off-by: Radostin Stoyanov <rstoyanov@fedoraproject.org>
-rw-r--r-- | libpod/container_internal_linux.go | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go index 0226f30c7..62e198d7c 100644 --- a/libpod/container_internal_linux.go +++ b/libpod/container_internal_linux.go @@ -990,6 +990,7 @@ func (c *Container) exportCheckpoint(options ContainerCheckpointOptions) error { includeFiles := []string{ "artifacts", + metadata.DevShmCheckpointTar, metadata.ConfigDumpFile, metadata.SpecDumpFile, metadata.NetworkStatusFile, @@ -1143,6 +1144,29 @@ func (c *Container) checkpoint(ctx context.Context, options ContainerCheckpointO return nil, 0, err } + // Keep the content of /dev/shm directory + if c.config.ShmDir != "" && c.state.BindMounts["/dev/shm"] == c.config.ShmDir { + shmDirTarFileFullPath := filepath.Join(c.bundlePath(), metadata.DevShmCheckpointTar) + + shmDirTarFile, err := os.Create(shmDirTarFileFullPath) + if err != nil { + return nil, 0, err + } + defer shmDirTarFile.Close() + + input, err := archive.TarWithOptions(c.config.ShmDir, &archive.TarOptions{ + Compression: archive.Uncompressed, + IncludeSourceDir: true, + }) + if err != nil { + return nil, 0, err + } + + if _, err = io.Copy(shmDirTarFile, input); err != nil { + return nil, 0, err + } + } + // Save network.status. This is needed to restore the container with // the same IP. Currently limited to one IP address in a container // with one interface. @@ -1486,6 +1510,24 @@ func (c *Container) restore(ctx context.Context, options ContainerCheckpointOpti } } + // Restore /dev/shm content + if c.config.ShmDir != "" && c.state.BindMounts["/dev/shm"] == c.config.ShmDir { + shmDirTarFileFullPath := filepath.Join(c.bundlePath(), metadata.DevShmCheckpointTar) + if _, err := os.Stat(shmDirTarFileFullPath); err != nil { + logrus.Debug("Container checkpoint doesn't contain dev/shm: ", err.Error()) + } else { + shmDirTarFile, err := os.Open(shmDirTarFileFullPath) + if err != nil { + return nil, 0, err + } + defer shmDirTarFile.Close() + + if err := archive.UntarUncompressed(shmDirTarFile, c.config.ShmDir, nil); err != nil { + return nil, 0, err + } + } + } + // Cleanup for a working restore. if err := c.removeConmonFiles(); err != nil { return nil, 0, err |