github.com/containers/podman/v4@v4.9.4/libpod/volume_internal.go (about)

     1  //go:build !remote
     2  // +build !remote
     3  
     4  package libpod
     5  
     6  import (
     7  	"fmt"
     8  	"os"
     9  	"path/filepath"
    10  
    11  	"github.com/containers/podman/v4/libpod/define"
    12  )
    13  
    14  // Creates a new volume
    15  func newVolume(runtime *Runtime) *Volume {
    16  	volume := new(Volume)
    17  	volume.config = new(VolumeConfig)
    18  	volume.state = new(VolumeState)
    19  	volume.runtime = runtime
    20  	volume.config.Labels = make(map[string]string)
    21  	volume.config.Options = make(map[string]string)
    22  	volume.state.NeedsCopyUp = true
    23  	volume.state.NeedsChown = true
    24  	return volume
    25  }
    26  
    27  // teardownStorage deletes the volume from volumePath
    28  func (v *Volume) teardownStorage() error {
    29  	if v.UsesVolumeDriver() {
    30  		return nil
    31  	}
    32  
    33  	// TODO: Should this be converted to use v.config.MountPoint?
    34  	return os.RemoveAll(filepath.Join(v.runtime.config.Engine.VolumePath, v.Name()))
    35  }
    36  
    37  // Volumes with options set, or a filesystem type, or a device to mount need to
    38  // be mounted and unmounted.
    39  func (v *Volume) needsMount() bool {
    40  	// Non-local driver always needs mount
    41  	if v.UsesVolumeDriver() {
    42  		return true
    43  	}
    44  
    45  	// Image driver always needs mount
    46  	if v.config.Driver == define.VolumeDriverImage {
    47  		return true
    48  	}
    49  
    50  	// Commit 28138dafcc added the UID and GID options to this map
    51  	// However we should only mount when options other than uid and gid are set.
    52  	// see https://github.com/containers/podman/issues/10620
    53  	index := 0
    54  	if _, ok := v.config.Options["UID"]; ok {
    55  		index++
    56  	}
    57  	if _, ok := v.config.Options["GID"]; ok {
    58  		index++
    59  	}
    60  	if _, ok := v.config.Options["SIZE"]; ok {
    61  		index++
    62  	}
    63  	if _, ok := v.config.Options["NOQUOTA"]; ok {
    64  		index++
    65  	}
    66  	if _, ok := v.config.Options["nocopy"]; ok {
    67  		index++
    68  	}
    69  	if _, ok := v.config.Options["copy"]; ok {
    70  		index++
    71  	}
    72  	// when uid or gid is set there is also the "o" option
    73  	// set so we have to ignore this one as well
    74  	if index > 0 {
    75  		index++
    76  	}
    77  	// Local driver with options other than uid,gid needs mount
    78  	return len(v.config.Options) > index
    79  }
    80  
    81  // update() updates the volume state from the DB.
    82  func (v *Volume) update() error {
    83  	if err := v.runtime.state.UpdateVolume(v); err != nil {
    84  		return err
    85  	}
    86  	if !v.valid {
    87  		return define.ErrVolumeRemoved
    88  	}
    89  	return nil
    90  }
    91  
    92  // save() saves the volume state to the DB
    93  func (v *Volume) save() error {
    94  	return v.runtime.state.SaveVolume(v)
    95  }
    96  
    97  // Refresh volume state after a restart.
    98  func (v *Volume) refresh() error {
    99  	lock, err := v.runtime.lockManager.AllocateAndRetrieveLock(v.config.LockID)
   100  	if err != nil {
   101  		return fmt.Errorf("acquiring lock %d for volume %s: %w", v.config.LockID, v.Name(), err)
   102  	}
   103  	v.lock = lock
   104  
   105  	return nil
   106  }
   107  
   108  // resetVolumeState resets state fields to default values.
   109  // It is performed before a refresh and clears the state after a reboot.
   110  // It does not save the results - assumes the database will do that for us.
   111  func resetVolumeState(state *VolumeState) {
   112  	state.MountCount = 0
   113  	state.MountPoint = ""
   114  }