summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRadostin Stoyanov <rstoyanov@fedoraproject.org>2021-12-20 19:28:24 +0000
committerRadostin Stoyanov <rstoyanov@fedoraproject.org>2021-12-23 05:47:25 +0000
commitf3d485d4d7050b6bd5f121f95eceb8c4b789ffd4 (patch)
tree5542f09a4f156bc7ea71f2f6b1d49cf1ded41cac
parent2d7dbda415b41724d0900403c3ac50b29985e763 (diff)
downloadpodman-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.go42
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