diff options
author | Matthew Heon <matthew.heon@pm.me> | 2019-09-03 15:03:44 -0400 |
---|---|---|
committer | Matthew Heon <matthew.heon@pm.me> | 2019-09-05 17:12:27 -0400 |
commit | a760e325f3180638f9fedd0ee79d4c6695d8ba64 (patch) | |
tree | 7969ab74dfe2c41df7387fd0601014dcd9656052 /libpod/container_internal_linux.go | |
parent | 5a8a71ed817a4fa50fd9444846a50b76f25228d1 (diff) | |
download | podman-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_linux.go')
-rw-r--r-- | libpod/container_internal_linux.go | 49 |
1 files changed, 30 insertions, 19 deletions
diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go index cb19b5484..33c57729b 100644 --- a/libpod/container_internal_linux.go +++ b/libpod/container_internal_linux.go @@ -61,7 +61,7 @@ func (c *Container) unmountSHM(mount string) error { // prepare mounts the container and sets up other required resources like net // namespaces -func (c *Container) prepare() (err error) { +func (c *Container) prepare() (Err error) { var ( wg sync.WaitGroup netNS ns.NetNS @@ -108,31 +108,42 @@ func (c *Container) prepare() (err error) { logrus.Debugf("Created root filesystem for container %s at %s", c.ID(), c.state.Mountpoint) }() - defer func() { - if err != nil { - if err2 := c.cleanupNetwork(); err2 != nil { - logrus.Errorf("Error cleaning up container %s network: %v", c.ID(), err2) - } - if err2 := c.cleanupStorage(); err2 != nil { - logrus.Errorf("Error cleaning up container %s storage: %v", c.ID(), err2) - } - } - }() - wg.Wait() + var createErr error if createNetNSErr != nil { - if mountStorageErr != nil { - logrus.Error(createNetNSErr) - return mountStorageErr - } - return createNetNSErr + createErr = createNetNSErr } if mountStorageErr != nil { - return mountStorageErr + logrus.Errorf("Error preparing container %s: %v", c.ID(), createErr) + createErr = mountStorageErr + } + + // Only trigger storage cleanup if mountStorage was successful. + // Otherwise, we may mess up mount counters. + if createNetNSErr != nil && mountStorageErr == nil { + if err := c.cleanupStorage(); err != nil { + // createErr is guaranteed non-nil, so print + // unconditionally + logrus.Errorf("Error preparing container %s: %v", c.ID(), createErr) + createErr = errors.Wrapf(err, "error unmounting storage for container %s after network create failure", c.ID()) + } + } + + // It's OK to unconditionally trigger network cleanup. If the network + // isn't ready it will do nothing. + if createErr != nil { + if err := c.cleanupNetwork(); err != nil { + logrus.Errorf("Error preparing container %s: %v", c.ID(), createErr) + createErr = errors.Wrapf(err, "error cleaning up container %s network after setup failure", c.ID()) + } + } + + if createErr != nil { + return createErr } - // Save the container + // Save changes to container state return c.save() } |