summaryrefslogtreecommitdiff
path: root/libpod/container_internal_linux.go
diff options
context:
space:
mode:
Diffstat (limited to 'libpod/container_internal_linux.go')
-rw-r--r--libpod/container_internal_linux.go62
1 files changed, 52 insertions, 10 deletions
diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go
index aa477611f..399220b9a 100644
--- a/libpod/container_internal_linux.go
+++ b/libpod/container_internal_linux.go
@@ -510,21 +510,44 @@ func (c *Container) addNamespaceContainer(g *generate.Generator, ns LinuxNS, ctr
return nil
}
-func (c *Container) exportCheckpoint(dest string) (err error) {
+func (c *Container) exportCheckpoint(dest string, ignoreRootfs bool) (err error) {
if (len(c.config.NamedVolumes) > 0) || (len(c.Dependencies()) > 0) {
return errors.Errorf("Cannot export checkpoints of containers with named volumes or dependencies")
}
logrus.Debugf("Exporting checkpoint image of container %q to %q", c.ID(), dest)
+
+ includeFiles := []string{
+ "checkpoint",
+ "artifacts",
+ "ctr.log",
+ "config.dump",
+ "spec.dump",
+ "network.status"}
+
+ // Get root file-system changes included in the checkpoint archive
+ rootfsDiffPath := filepath.Join(c.bundlePath(), "rootfs-diff.tar")
+ if !ignoreRootfs {
+ rootfsDiffFile, err := os.Create(rootfsDiffPath)
+ if err != nil {
+ return errors.Wrapf(err, "error creating root file-system diff file %q", rootfsDiffPath)
+ }
+ tarStream, err := c.runtime.GetDiffTarStream("", c.ID())
+ if err != nil {
+ return errors.Wrapf(err, "error exporting root file-system diff to %q", rootfsDiffPath)
+ }
+ _, err = io.Copy(rootfsDiffFile, tarStream)
+ if err != nil {
+ return errors.Wrapf(err, "error exporting root file-system diff to %q", rootfsDiffPath)
+ }
+ tarStream.Close()
+ rootfsDiffFile.Close()
+ includeFiles = append(includeFiles, "rootfs-diff.tar")
+ }
+
input, err := archive.TarWithOptions(c.bundlePath(), &archive.TarOptions{
Compression: archive.Gzip,
IncludeSourceDir: true,
- IncludeFiles: []string{
- "checkpoint",
- "artifacts",
- "ctr.log",
- "config.dump",
- "spec.dump",
- "network.status"},
+ IncludeFiles: includeFiles,
})
if err != nil {
@@ -546,6 +569,8 @@ func (c *Container) exportCheckpoint(dest string) (err error) {
return err
}
+ os.Remove(rootfsDiffPath)
+
return nil
}
@@ -605,7 +630,7 @@ func (c *Container) checkpoint(ctx context.Context, options ContainerCheckpointO
}
if options.TargetFile != "" {
- if err = c.exportCheckpoint(options.TargetFile); err != nil {
+ if err = c.exportCheckpoint(options.TargetFile, options.IgnoreRootfs); err != nil {
return err
}
}
@@ -792,6 +817,23 @@ func (c *Container) restore(ctx context.Context, options ContainerCheckpointOpti
if err := c.saveSpec(g.Spec()); err != nil {
return err
}
+
+ // Before actually restarting the container, apply the root file-system changes
+ if !options.IgnoreRootfs {
+ rootfsDiffPath := filepath.Join(c.bundlePath(), "rootfs-diff.tar")
+ if _, err := os.Stat(rootfsDiffPath); err == nil {
+ // Only do this if a rootfs-diff.tar actually exists
+ rootfsDiffFile, err := os.Open(rootfsDiffPath)
+ if err != nil {
+ return errors.Wrapf(err, "Failed to open root file-system diff file %s", rootfsDiffPath)
+ }
+ if err := c.runtime.ApplyDiffTarStream(c.ID(), rootfsDiffFile); err != nil {
+ return errors.Wrapf(err, "Failed to apply root file-system diff file %s", rootfsDiffPath)
+ }
+ rootfsDiffFile.Close()
+ }
+ }
+
if err := c.ociRuntime.createContainer(c, c.config.CgroupParent, &options); err != nil {
return err
}
@@ -809,7 +851,7 @@ func (c *Container) restore(ctx context.Context, options ContainerCheckpointOpti
if err != nil {
logrus.Debugf("Non-fatal: removal of checkpoint directory (%s) failed: %v", c.CheckpointPath(), err)
}
- cleanup := [...]string{"restore.log", "dump.log", "stats-dump", "stats-restore", "network.status"}
+ cleanup := [...]string{"restore.log", "dump.log", "stats-dump", "stats-restore", "network.status", "rootfs-diff.tar"}
for _, del := range cleanup {
file := filepath.Join(c.bundlePath(), del)
err = os.Remove(file)