aboutsummaryrefslogtreecommitdiff
path: root/libpod/container_internal.go
diff options
context:
space:
mode:
authorOpenShift Merge Robot <openshift-merge-robot@users.noreply.github.com>2019-09-06 13:48:33 +0200
committerGitHub <noreply@github.com>2019-09-06 13:48:33 +0200
commit0d8a22496e3c7e3d44251bdbac194c55de141e2c (patch)
treec3591e9470b5b90842e6764b71b3e3988bc8fab5 /libpod/container_internal.go
parenta4572c4f681ef23495495f313ae513d5ba3fd495 (diff)
parentde9a394fcff19ae4422a3f65502c8790787351fd (diff)
downloadpodman-0d8a22496e3c7e3d44251bdbac194c55de141e2c.tar.gz
podman-0d8a22496e3c7e3d44251bdbac194c55de141e2c.tar.bz2
podman-0d8a22496e3c7e3d44251bdbac194c55de141e2c.zip
Merge pull request #3931 from mheon/volumes_with_options
Add support for mounting volumes with local driver and options
Diffstat (limited to 'libpod/container_internal.go')
-rw-r--r--libpod/container_internal.go86
1 files changed, 79 insertions, 7 deletions
diff --git a/libpod/container_internal.go b/libpod/container_internal.go
index f51b53e85..ffc6c11ee 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()
+ if err := vol.unmount(false); err != nil {
+ logrus.Errorf("Error unmounting volume %s after error mounting container %s: %v", vol.Name(), c.ID(), err)
+ }
+ vol.lock.Unlock()
+ }()
+ }
}
// TODO: generalize this mount code so it will mount every mount in ctr.config.Mounts
@@ -1247,14 +1281,19 @@ func (c *Container) cleanupStorage() error {
return nil
}
+ var cleanupErr error
+
for _, containerMount := range c.config.Mounts {
if err := c.unmountSHM(containerMount); err != nil {
- return err
+ if cleanupErr != nil {
+ logrus.Errorf("Error unmounting container %s: %v", c.ID(), cleanupErr)
+ }
+ cleanupErr = err
}
}
if c.config.Rootfs != "" {
- return nil
+ return cleanupErr
}
if err := c.unmount(false); err != nil {
@@ -1264,19 +1303,52 @@ func (c *Container) cleanupStorage() error {
// state
if errors.Cause(err) == storage.ErrNotAContainer || errors.Cause(err) == storage.ErrContainerUnknown {
logrus.Errorf("Storage for container %s has been removed", c.ID())
- return nil
+ } else {
+ if cleanupErr != nil {
+ logrus.Errorf("Error cleaning up container %s storage: %v", c.ID(), cleanupErr)
+ }
+ cleanupErr = err
}
+ }
- return err
+ // 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