diff options
author | Matthew Heon <matthew.heon@gmail.com> | 2017-12-03 12:17:44 -0500 |
---|---|---|
committer | Atomic Bot <atomic-devel@projectatomic.io> | 2017-12-04 18:10:52 +0000 |
commit | 750fc239b5da8e3f2792ae33f46a671ddf4622e3 (patch) | |
tree | 06cf04d72e67d31d995189242ee35222be21b3bf | |
parent | 1f482c9f1f919026aff139127639083959a8f021 (diff) | |
download | podman-750fc239b5da8e3f2792ae33f46a671ddf4622e3.tar.gz podman-750fc239b5da8e3f2792ae33f46a671ddf4622e3.tar.bz2 podman-750fc239b5da8e3f2792ae33f46a671ddf4622e3.zip |
Consolidate mount logic
There are still two places that don't use the new function,
export and mount, but both can probably be converted to it
in the future.
Signed-off-by: Matthew Heon <matthew.heon@gmail.com>
Closes: #99
Approved by: rhatdan
-rw-r--r-- | libpod/container.go | 148 |
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 } |