summaryrefslogtreecommitdiff
path: root/libpod/container_internal.go
diff options
context:
space:
mode:
authorMatthew Heon <matthew.heon@pm.me>2019-09-03 15:03:44 -0400
committerMatthew Heon <matthew.heon@pm.me>2019-09-05 17:12:27 -0400
commita760e325f3180638f9fedd0ee79d4c6695d8ba64 (patch)
tree7969ab74dfe2c41df7387fd0601014dcd9656052 /libpod/container_internal.go
parent5a8a71ed817a4fa50fd9444846a50b76f25228d1 (diff)
downloadpodman-a760e325f3180638f9fedd0ee79d4c6695d8ba64.tar.gz
podman-a760e325f3180638f9fedd0ee79d4c6695d8ba64.tar.bz2
podman-a760e325f3180638f9fedd0ee79d4c6695d8ba64.zip
Add ability for volumes with options to mount/umount
When volume options and the local volume driver are specified, the volume is intended to be mounted using the 'mount' command. Supported options will be used to volume the volume before the first container using it starts, and unmount the volume after the last container using it dies. This should work for any local filesystem, though at present I've only tested with tmpfs and btrfs. Signed-off-by: Matthew Heon <matthew.heon@pm.me>
Diffstat (limited to 'libpod/container_internal.go')
-rw-r--r--libpod/container_internal.go73
1 files changed, 70 insertions, 3 deletions
diff --git a/libpod/container_internal.go b/libpod/container_internal.go
index f51b53e85..67503f148 100644
--- a/libpod/container_internal.go
+++ b/libpod/container_internal.go
@@ -1205,7 +1205,7 @@ func (c *Container) restartWithTimeout(ctx context.Context, timeout uint) (err e
// 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() (string, error) {
+func (c *Container) mountStorage() (_ string, Err error) {
var err error
// Container already mounted, nothing to do
if c.state.Mounted {
@@ -1225,6 +1225,40 @@ func (c *Container) mountStorage() (string, error) {
if err := os.Chown(c.config.ShmDir, c.RootUID(), c.RootGID()); err != nil {
return "", errors.Wrapf(err, "failed to chown %s", c.config.ShmDir)
}
+ defer func() {
+ if Err != nil {
+ if err := c.unmountSHM(c.config.ShmDir); err != nil {
+ logrus.Errorf("Error unmounting SHM for container %s after mount error: %v", c.ID(), err)
+ }
+ }
+ }()
+ }
+
+ // Request a mount of all named volumes
+ for _, v := range c.config.NamedVolumes {
+ vol, err := c.runtime.state.Volume(v.Name)
+ if err != nil {
+ return "", errors.Wrapf(err, "error retrieving named volume %s for container %s", v.Name, c.ID())
+ }
+
+ if vol.needsMount() {
+ vol.lock.Lock()
+ if err := vol.mount(); err != nil {
+ vol.lock.Unlock()
+ return "", errors.Wrapf(err, "error mounting volume %s for container %s", vol.Name(), c.ID())
+ }
+ vol.lock.Unlock()
+ defer func() {
+ if Err == nil {
+ return
+ }
+ vol.lock.Lock()
+ defer vol.lock.Unlock()
+ if err := vol.unmount(false); err != nil {
+ logrus.Errorf("Error unmounting volume %s after error mounting container %s: %v", vol.Name(), c.ID(), err)
+ }
+ }()
+ }
}
// TODO: generalize this mount code so it will mount every mount in ctr.config.Mounts
@@ -1270,13 +1304,46 @@ func (c *Container) cleanupStorage() error {
return err
}
+ var cleanupErr error
+
+ // Request an unmount of all named volumes
+ for _, v := range c.config.NamedVolumes {
+ vol, err := c.runtime.state.Volume(v.Name)
+ if err != nil {
+ if cleanupErr != nil {
+ logrus.Errorf("Error unmounting container %s: %v", c.ID(), cleanupErr)
+ }
+ cleanupErr = errors.Wrapf(err, "error retrieving named volume %s for container %s", v.Name, c.ID())
+
+ // We need to try and unmount every volume, so continue
+ // if they fail.
+ continue
+ }
+
+ if vol.needsMount() {
+ vol.lock.Lock()
+ if err := vol.unmount(false); err != nil {
+ if cleanupErr != nil {
+ logrus.Errorf("Error unmounting container %s: %v", c.ID(), cleanupErr)
+ }
+ cleanupErr = errors.Wrapf(err, "error unmounting volume %s for container %s", vol.Name(), c.ID())
+ }
+ vol.lock.Unlock()
+ }
+ }
+
c.state.Mountpoint = ""
c.state.Mounted = false
if c.valid {
- return c.save()
+ if err := c.save(); err != nil {
+ if cleanupErr != nil {
+ logrus.Errorf("Error unmounting container %s: %v", c.ID(), cleanupErr)
+ }
+ cleanupErr = err
+ }
}
- return nil
+ return cleanupErr
}
// Unmount the a container and free its resources