aboutsummaryrefslogtreecommitdiff
path: root/libpod/volume_internal_linux.go
diff options
context:
space:
mode:
authorDoug Rabson <dfr@rabson.org>2022-09-20 11:25:20 +0100
committerDoug Rabson <dfr@rabson.org>2022-09-27 16:31:40 +0100
commit9de2a5ff795f25da0d887304db3559d06832caef (patch)
tree4f05f5efadc622c908f964781df1bea5f431eba4 /libpod/volume_internal_linux.go
parent065474755b7bcca1521bc9e3d30583768518a5cb (diff)
downloadpodman-9de2a5ff795f25da0d887304db3559d06832caef.tar.gz
podman-9de2a5ff795f25da0d887304db3559d06832caef.tar.bz2
podman-9de2a5ff795f25da0d887304db3559d06832caef.zip
libpod: Move volume_internal_linux.go to volume_internal_common.go
[NO NEW TESTS NEEDED] Signed-off-by: Doug Rabson <dfr@rabson.org>
Diffstat (limited to 'libpod/volume_internal_linux.go')
-rw-r--r--libpod/volume_internal_linux.go194
1 files changed, 0 insertions, 194 deletions
diff --git a/libpod/volume_internal_linux.go b/libpod/volume_internal_linux.go
deleted file mode 100644
index 440bceec3..000000000
--- a/libpod/volume_internal_linux.go
+++ /dev/null
@@ -1,194 +0,0 @@
-//go:build linux
-// +build linux
-
-package libpod
-
-import (
- "errors"
- "fmt"
- "os/exec"
- "strings"
-
- "github.com/containers/podman/v4/libpod/define"
- pluginapi "github.com/docker/go-plugins-helpers/volume"
- "github.com/sirupsen/logrus"
- "golang.org/x/sys/unix"
-)
-
-// This is a pseudo-container ID to use when requesting a mount or unmount from
-// the volume plugins.
-// This is the shas256 of the string "placeholder\n".
-const pseudoCtrID = "2f73349cfc4630255319c6c8dfc1b46a8996ace9d14d8e07563b165915918ec2"
-
-// mount mounts the volume if necessary.
-// A mount is necessary if a volume has any options set.
-// If a mount is necessary, v.state.MountCount will be incremented.
-// If it was 0 when the increment occurred, the volume will be mounted on the
-// host. Otherwise, we assume it is already mounted.
-// Must be done while the volume is locked.
-// Is a no-op on volumes that do not require a mount (as defined by
-// volumeNeedsMount()).
-func (v *Volume) mount() error {
- if !v.needsMount() {
- return nil
- }
-
- // Update the volume from the DB to get an accurate mount counter.
- if err := v.update(); err != nil {
- return err
- }
-
- // If the count is non-zero, the volume is already mounted.
- // Nothing to do.
- if v.state.MountCount > 0 {
- v.state.MountCount++
- logrus.Debugf("Volume %s mount count now at %d", v.Name(), v.state.MountCount)
- return v.save()
- }
-
- // Volume plugins implement their own mount counter, based on the ID of
- // the mounting container. But we already have one, and honestly I trust
- // ours more. So hardcode container ID to something reasonable, and use
- // the same one for everything.
- if v.UsesVolumeDriver() {
- if v.plugin == nil {
- return fmt.Errorf("volume plugin %s (needed by volume %s) missing: %w", v.Driver(), v.Name(), define.ErrMissingPlugin)
- }
-
- req := new(pluginapi.MountRequest)
- req.Name = v.Name()
- req.ID = pseudoCtrID
- mountPoint, err := v.plugin.MountVolume(req)
- if err != nil {
- return err
- }
-
- v.state.MountCount++
- v.state.MountPoint = mountPoint
- return v.save()
- } else if v.config.Driver == define.VolumeDriverImage {
- mountPoint, err := v.runtime.storageService.MountContainerImage(v.config.StorageID)
- if err != nil {
- return fmt.Errorf("mounting volume %s image failed: %w", v.Name(), err)
- }
-
- v.state.MountCount++
- v.state.MountPoint = mountPoint
- return v.save()
- }
-
- volDevice := v.config.Options["device"]
- volType := v.config.Options["type"]
- volOptions := v.config.Options["o"]
-
- // Some filesystems (tmpfs) don't have a device, but we still need to
- // give the kernel something.
- if volDevice == "" && volType != "" {
- volDevice = volType
- }
-
- // We need to use the actual mount command.
- // Convincing unix.Mount to use the same semantics as the mount command
- // itself seems prohibitively difficult.
- // TODO: might want to cache this path in the runtime?
- mountPath, err := exec.LookPath("mount")
- if err != nil {
- return fmt.Errorf("locating 'mount' binary: %w", err)
- }
- mountArgs := []string{}
- if volOptions != "" {
- mountArgs = append(mountArgs, "-o", volOptions)
- }
- switch volType {
- case "":
- case "bind":
- mountArgs = append(mountArgs, "-o", volType)
- default:
- mountArgs = append(mountArgs, "-t", volType)
- }
-
- mountArgs = append(mountArgs, volDevice, v.config.MountPoint)
- mountCmd := exec.Command(mountPath, mountArgs...)
-
- logrus.Debugf("Running mount command: %s %s", mountPath, strings.Join(mountArgs, " "))
- if output, err := mountCmd.CombinedOutput(); err != nil {
- logrus.Debugf("Mount %v failed with %v", mountCmd, err)
- return errors.New(string(output))
- }
-
- logrus.Debugf("Mounted volume %s", v.Name())
-
- // Increment the mount counter
- v.state.MountCount++
- logrus.Debugf("Volume %s mount count now at %d", v.Name(), v.state.MountCount)
- return v.save()
-}
-
-// unmount unmounts the volume if necessary.
-// Unmounting a volume that is not mounted is a no-op.
-// Unmounting a volume that does not require a mount is a no-op.
-// The volume must be locked for this to occur.
-// The mount counter will be decremented if non-zero. If the counter reaches 0,
-// the volume will really be unmounted, as no further containers are using the
-// volume.
-// If force is set, the volume will be unmounted regardless of mount counter.
-func (v *Volume) unmount(force bool) error {
- if !v.needsMount() {
- return nil
- }
-
- // Update the volume from the DB to get an accurate mount counter.
- if err := v.update(); err != nil {
- return err
- }
-
- if v.state.MountCount == 0 {
- logrus.Debugf("Volume %s already unmounted", v.Name())
- return nil
- }
-
- if !force {
- v.state.MountCount--
- } else {
- v.state.MountCount = 0
- }
-
- logrus.Debugf("Volume %s mount count now at %d", v.Name(), v.state.MountCount)
-
- if v.state.MountCount == 0 {
- if v.UsesVolumeDriver() {
- if v.plugin == nil {
- return fmt.Errorf("volume plugin %s (needed by volume %s) missing: %w", v.Driver(), v.Name(), define.ErrMissingPlugin)
- }
-
- req := new(pluginapi.UnmountRequest)
- req.Name = v.Name()
- req.ID = pseudoCtrID
- if err := v.plugin.UnmountVolume(req); err != nil {
- return err
- }
-
- v.state.MountPoint = ""
- return v.save()
- } else if v.config.Driver == define.VolumeDriverImage {
- if _, err := v.runtime.storageService.UnmountContainerImage(v.config.StorageID, force); err != nil {
- return fmt.Errorf("unmounting volume %s image: %w", v.Name(), err)
- }
-
- v.state.MountPoint = ""
- return v.save()
- }
-
- // Unmount the volume
- if err := unix.Unmount(v.config.MountPoint, unix.MNT_DETACH); err != nil {
- if err == unix.EINVAL {
- // Ignore EINVAL - the mount no longer exists.
- return nil
- }
- return fmt.Errorf("unmounting volume %s: %w", v.Name(), err)
- }
- logrus.Debugf("Unmounted volume %s", v.Name())
- }
-
- return v.save()
-}