summaryrefslogtreecommitdiff
path: root/libpod
diff options
context:
space:
mode:
Diffstat (limited to 'libpod')
-rw-r--r--libpod/container.go148
1 files changed, 72 insertions, 76 deletions
diff --git a/libpod/container.go b/libpod/container.go
index 60c63d14e..bd7455147 100644
--- a/libpod/container.go
+++ b/libpod/container.go
@@ -420,25 +420,10 @@ func (c *Container) Init() (err error) {
return errors.Wrapf(ErrCtrExists, "container %s has already been created in runtime", c.ID())
}
- mountPoint, err := c.runtime.storageService.StartContainer(c.ID())
- if err != nil {
- return errors.Wrapf(err, "error mounting storage for container %s", c.ID())
+ // Mount storage for the container
+ if err := c.mountStorage(); err != nil {
+ return err
}
- c.state.Mounted = true
- c.state.Mountpoint = mountPoint
-
- logrus.Debugf("Created root filesystem for container %s at %s", c.ID(), c.state.Mountpoint)
-
- defer func() {
- if err != nil {
- if err2 := c.runtime.storageService.StopContainer(c.ID()); err2 != nil {
- logrus.Errorf("Error unmounting storage for container %s: %v", c.ID(), err2)
- }
-
- c.state.Mounted = false
- c.state.Mountpoint = ""
- }
- }()
// Make the OCI runtime spec we will use
g := generate.NewFromSpec(c.config.Spec)
@@ -484,45 +469,14 @@ func (c *Container) Start() error {
return err
}
- mounted, err := mount.Mounted(c.config.ShmDir)
- if err != nil {
- return errors.Wrapf(err, "unable to determine if %q is mounted", c.config.ShmDir)
- }
-
- if !mounted {
- shmOptions := "mode=1777,size=" + strconv.Itoa(DefaultShmSize)
- if err := unix.Mount("shm", c.config.ShmDir, "tmpfs", unix.MS_NOEXEC|unix.MS_NOSUID|unix.MS_NODEV,
- label.FormatMountLabel(shmOptions, c.config.MountLabel)); err != nil {
- return errors.Wrapf(err, "failed to mount shm tmpfs %q", c.config.ShmDir)
- }
- }
-
// Container must be created or stopped to be started
if !(c.state.State == ContainerStateCreated || c.state.State == ContainerStateStopped) {
return errors.Wrapf(ErrCtrStateInvalid, "container %s must be in Created or Stopped state to be started", c.ID())
}
- // If the container isn't mounted, mount it
- if !c.state.Mounted {
- mountPoint, err := c.runtime.storageService.StartContainer(c.ID())
- if err != nil {
- return errors.Wrapf(err, "error mounting storage for container %s", c.ID())
- }
- c.state.Mounted = true
- c.state.Mountpoint = mountPoint
-
- logrus.Debugf("Created root filesystem for container %s at %s", c.ID(), c.state.Mountpoint)
-
- defer func() {
- if err != nil {
- if err2 := c.runtime.storageService.StopContainer(c.ID()); err2 != nil {
- logrus.Errorf("Error unmounting storage for container %s: %v", c.ID(), err2)
- }
-
- c.state.Mounted = false
- c.state.Mountpoint = ""
- }
- }()
+ // Mount storage for the container
+ if err := c.mountStorage(); err != nil {
+ return err
}
if err := c.runtime.ociRuntime.startContainer(c); err != nil {
@@ -667,18 +621,7 @@ func (c *Container) Unmount() error {
return errors.Wrapf(ErrCtrStateInvalid, "cannot remove storage for container %s as it is running or paused", c.ID())
}
- if !c.state.Mounted {
- return nil
- }
-
- err := c.runtime.store.Unmount(c.ID())
- if err != nil {
- return errors.Wrapf(err, "error unmounting container %q", c.ID())
- }
- c.state.Mountpoint = ""
- c.state.Mounted = false
-
- return c.save()
+ return c.cleanupStorage()
}
// Pause pauses a container
@@ -813,7 +756,7 @@ func (c *Container) isStopped() (bool, error) {
return c.state.State == ContainerStateStopped, nil
}
-// nil container state to the database
+// save container state to the database
func (c *Container) save() error {
if err := c.runtime.state.SaveContainer(c); err != nil {
return errors.Wrapf(err, "error saving container %s state", c.ID())
@@ -821,6 +764,56 @@ func (c *Container) save() error {
return nil
}
+// mountStorage sets up the container's root filesystem
+// It mounts the image and any other requested mounts
+// TODO: Add ability to override mount label so we can use this for Mount() too
+// TODO: Can we use this for export? Copying SHM into the export might not be
+// good
+func (c *Container) mountStorage() (err error) {
+ // Container already mounted, nothing to do
+ if c.state.Mounted {
+ return nil
+ }
+
+ // TODO: generalize this mount code so it will mount every mount in ctr.config.Mounts
+
+ mounted, err := mount.Mounted(c.config.ShmDir)
+ if err != nil {
+ return errors.Wrapf(err, "unable to determine if %q is mounted", c.config.ShmDir)
+ }
+
+ if !mounted {
+ shmOptions := "mode=1777,size=" + strconv.Itoa(DefaultShmSize)
+ if err := unix.Mount("shm", c.config.ShmDir, "tmpfs", unix.MS_NOEXEC|unix.MS_NOSUID|unix.MS_NODEV,
+ label.FormatMountLabel(shmOptions, c.config.MountLabel)); err != nil {
+ return errors.Wrapf(err, "failed to mount shm tmpfs %q", c.config.ShmDir)
+ }
+ }
+
+ mountPoint, err := c.runtime.storageService.StartContainer(c.ID())
+ if err != nil {
+ return errors.Wrapf(err, "error mounting storage for container %s", c.ID())
+ }
+ c.state.Mounted = true
+ c.state.Mountpoint = mountPoint
+
+ logrus.Debugf("Created root filesystem for container %s at %s", c.ID(), c.state.Mountpoint)
+
+ defer func() {
+ if err != nil {
+ if err2 := c.cleanupStorage(); err2 != nil {
+ logrus.Errorf("Error unmounting storage for container %s: %v", c.ID(), err)
+ }
+ }
+ }()
+
+ if err := c.runtime.state.SaveContainer(c); err != nil {
+ return errors.Wrapf(err, "error saving container %s state", c.ID())
+ }
+
+ return nil
+}
+
// CleanupStorage unmounts all mount points in container and cleans up container storage
func (c *Container) CleanupStorage() error {
c.lock.Lock()
@@ -831,22 +824,24 @@ func (c *Container) CleanupStorage() error {
return c.cleanupStorage()
}
+// cleanupStorage unmounts and cleans up the container's root filesystem
func (c *Container) cleanupStorage() error {
+ if !c.state.Mounted {
+ // Already unmounted, do nothing
+ return nil
+ }
- if c.state.Mounted {
- for _, mount := range c.config.Mounts {
- if err := unix.Unmount(mount, unix.MNT_DETACH); err != nil {
- if err != syscall.EINVAL {
- logrus.Warnf("container %s failed to unmount %s : %v", c.ID(), mount, err)
- }
+ for _, mount := range c.config.Mounts {
+ if err := unix.Unmount(mount, unix.MNT_DETACH); err != nil {
+ if err != syscall.EINVAL {
+ logrus.Warnf("container %s failed to unmount %s : %v", c.ID(), mount, err)
}
}
- c.config.Mounts = []string{}
+ }
- // Also unmount storage
- if err := c.runtime.storageService.StopContainer(c.ID()); err != nil {
- return errors.Wrapf(err, "error unmounting container %s root filesystem", c.ID())
- }
+ // Also unmount storage
+ if err := c.runtime.storageService.StopContainer(c.ID()); err != nil {
+ return errors.Wrapf(err, "error unmounting container %s root filesystem", c.ID())
}
c.state.Mountpoint = ""
@@ -855,5 +850,6 @@ func (c *Container) cleanupStorage() error {
if err := c.runtime.state.SaveContainer(c); err != nil {
return errors.Wrapf(err, "error saving container %s state", c.ID())
}
+
return nil
}