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 }