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.go77
1 files changed, 60 insertions, 17 deletions
diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go
index 867ecc2ad..3187724ca 100644
--- a/libpod/container_internal_linux.go
+++ b/libpod/container_internal_linux.go
@@ -21,6 +21,7 @@ import (
"time"
metadata "github.com/checkpoint-restore/checkpointctl/lib"
+ "github.com/checkpoint-restore/go-criu/v5/stats"
cdi "github.com/container-orchestrated-devices/container-device-interface/pkg"
"github.com/containernetworking/plugins/pkg/ns"
"github.com/containers/buildah/pkg/chrootuser"
@@ -50,6 +51,7 @@ import (
runcuser "github.com/opencontainers/runc/libcontainer/user"
spec "github.com/opencontainers/runtime-spec/specs-go"
"github.com/opencontainers/runtime-tools/generate"
+ "github.com/opencontainers/selinux/go-selinux"
"github.com/opencontainers/selinux/go-selinux/label"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
@@ -321,7 +323,7 @@ func (c *Container) generateSpec(ctx context.Context) (*spec.Spec, error) {
return nil, err
}
- g := generate.Generator{Config: c.config.Spec}
+ g := generate.NewFromSpec(c.config.Spec)
// If network namespace was requested, add it now
if c.config.CreateNetNS {
@@ -390,11 +392,11 @@ func (c *Container) generateSpec(ctx context.Context) (*spec.Spec, error) {
for _, o := range namedVol.Options {
switch o {
case "U":
- if err := chown.ChangeHostPathOwnership(mountPoint, true, int(hostUID), int(hostGID)); err != nil {
+ if err := c.ChangeHostPathOwnership(mountPoint, true, int(hostUID), int(hostGID)); err != nil {
return nil, err
}
- if err := chown.ChangeHostPathOwnership(contentDir, true, int(hostUID), int(hostGID)); err != nil {
+ if err := c.ChangeHostPathOwnership(contentDir, true, int(hostUID), int(hostGID)); err != nil {
return nil, err
}
}
@@ -423,14 +425,15 @@ func (c *Container) generateSpec(ctx context.Context) (*spec.Spec, error) {
if m.Type == "tmpfs" {
options = append(options, []string{fmt.Sprintf("uid=%d", execUser.Uid), fmt.Sprintf("gid=%d", execUser.Gid)}...)
} else {
- if err := chown.ChangeHostPathOwnership(m.Source, true, int(hostUID), int(hostGID)); err != nil {
+ // only chown on initial creation of container
+ if err := c.ChangeHostPathOwnership(m.Source, true, int(hostUID), int(hostGID)); err != nil {
return nil, err
}
}
case "z":
fallthrough
case "Z":
- if err := label.Relabel(m.Source, c.MountLabel(), label.IsShared(o)); err != nil {
+ if err := c.relabel(m.Source, c.MountLabel(), label.IsShared(o)); err != nil {
return nil, err
}
@@ -477,11 +480,11 @@ func (c *Container) generateSpec(ctx context.Context) (*spec.Spec, error) {
for _, o := range overlayVol.Options {
switch o {
case "U":
- if err := chown.ChangeHostPathOwnership(overlayVol.Source, true, int(hostUID), int(hostGID)); err != nil {
+ if err := c.ChangeHostPathOwnership(overlayVol.Source, true, int(hostUID), int(hostGID)); err != nil {
return nil, err
}
- if err := chown.ChangeHostPathOwnership(contentDir, true, int(hostUID), int(hostGID)); err != nil {
+ if err := c.ChangeHostPathOwnership(contentDir, true, int(hostUID), int(hostGID)); err != nil {
return nil, err
}
}
@@ -1008,12 +1011,16 @@ func (c *Container) exportCheckpoint(options ContainerCheckpointOptions) error {
includeFiles := []string{
"artifacts",
- "ctr.log",
metadata.ConfigDumpFile,
metadata.SpecDumpFile,
metadata.NetworkStatusFile,
+ stats.StatsDump,
}
+ if c.LogDriver() == define.KubernetesLogging ||
+ c.LogDriver() == define.JSONLogging {
+ includeFiles = append(includeFiles, "ctr.log")
+ }
if options.PreCheckPoint {
includeFiles = append(includeFiles, preCheckpointDir)
} else {
@@ -1192,7 +1199,7 @@ func (c *Container) checkpoint(ctx context.Context, options ContainerCheckpointO
if !options.Keep && !options.PreCheckPoint {
cleanup := []string{
"dump.log",
- "stats-dump",
+ stats.StatsDump,
metadata.ConfigDumpFile,
metadata.SpecDumpFile,
}
@@ -1214,7 +1221,8 @@ func (c *Container) importCheckpoint(input string) error {
}
// Make sure the newly created config.json exists on disk
- g := generate.Generator{Config: c.config.Spec}
+ g := generate.NewFromSpec(c.config.Spec)
+
if err := c.saveSpec(g.Config); err != nil {
return errors.Wrap(err, "saving imported container specification for restore failed")
}
@@ -1540,6 +1548,7 @@ func (c *Container) restore(ctx context.Context, options ContainerCheckpointOpti
logrus.Debugf("Restored container %s", c.ID())
c.state.State = define.ContainerStateRunning
+ c.state.Checkpointed = false
if !options.Keep {
// Delete all checkpoint related files. At this point, in theory, all files
@@ -1557,8 +1566,8 @@ func (c *Container) restore(ctx context.Context, options ContainerCheckpointOpti
cleanup := [...]string{
"restore.log",
"dump.log",
- "stats-dump",
- "stats-restore",
+ stats.StatsDump,
+ stats.StatsRestore,
metadata.NetworkStatusFile,
metadata.RootFsDiffTar,
metadata.DeletedFilesFile,
@@ -1706,13 +1715,13 @@ func (c *Container) makeBindMounts() error {
}
if c.state.BindMounts["/etc/hosts"] != "" {
- if err := label.Relabel(c.state.BindMounts["/etc/hosts"], c.config.MountLabel, true); err != nil {
+ if err := c.relabel(c.state.BindMounts["/etc/hosts"], c.config.MountLabel, true); err != nil {
return err
}
}
if c.state.BindMounts["/etc/resolv.conf"] != "" {
- if err := label.Relabel(c.state.BindMounts["/etc/resolv.conf"], c.config.MountLabel, true); err != nil {
+ if err := c.relabel(c.state.BindMounts["/etc/resolv.conf"], c.config.MountLabel, true); err != nil {
return err
}
}
@@ -1994,7 +2003,7 @@ func (c *Container) generateResolvConf() (string, error) {
}
// Relabel resolv.conf for the container
- if err := label.Relabel(destPath, c.config.MountLabel, true); err != nil {
+ if err := c.relabel(destPath, c.config.MountLabel, true); err != nil {
return "", err
}
@@ -2016,7 +2025,7 @@ func (c *Container) generateHosts(path string) (string, error) {
}
// based on networking mode we may want to append the localhost
-// if there isn't any record for it and also this shoud happen
+// if there isn't any record for it and also this should happen
// in slirp4netns and similar network modes.
func (c *Container) appendLocalhost(hosts string) string {
if !strings.Contains(hosts, "localhost") &&
@@ -2611,7 +2620,7 @@ func (c *Container) copyTimezoneFile(zonePath string) (string, error) {
if err != nil {
return "", err
}
- if err := label.Relabel(localtimeCopy, c.config.MountLabel, false); err != nil {
+ if err := c.relabel(localtimeCopy, c.config.MountLabel, false); err != nil {
return "", err
}
if err := dest.Chown(c.RootUID(), c.RootGID()); err != nil {
@@ -2746,3 +2755,37 @@ func (c *Container) fixVolumePermissions(v *ContainerNamedVolume) error {
}
return nil
}
+
+func (c *Container) relabel(src, mountLabel string, recurse bool) error {
+ if !selinux.GetEnabled() || mountLabel == "" {
+ return nil
+ }
+ // only relabel on initial creation of container
+ if !c.ensureState(define.ContainerStateConfigured, define.ContainerStateUnknown) {
+ label, err := label.FileLabel(src)
+ if err != nil {
+ return err
+ }
+ // If labels are different, might be on a tmpfs
+ if label == mountLabel {
+ return nil
+ }
+ }
+ return label.Relabel(src, mountLabel, recurse)
+}
+
+func (c *Container) ChangeHostPathOwnership(src string, recurse bool, uid, gid int) error {
+ // only chown on initial creation of container
+ if !c.ensureState(define.ContainerStateConfigured, define.ContainerStateUnknown) {
+ st, err := os.Stat(src)
+ if err != nil {
+ return err
+ }
+
+ // If labels are different, might be on a tmpfs
+ if int(st.Sys().(*syscall.Stat_t).Uid) == uid && int(st.Sys().(*syscall.Stat_t).Gid) == gid {
+ return nil
+ }
+ }
+ return chown.ChangeHostPathOwnership(src, recurse, uid, gid)
+}