mirror of
https://github.com/containers/podman.git
synced 2025-06-19 16:33:24 +08:00
SetLock for all virt providers
Implements a shared `GetLock` function for virtualization providers. Returns a pointer to a lockfile used for serializing write operations. [NO NEW TESTS NEEDED] Signed-off-by: Jake Correnti <jakecorrenti+github@proton.me>
This commit is contained in:
@ -24,6 +24,7 @@ import (
|
|||||||
"github.com/containers/podman/v4/pkg/strongunits"
|
"github.com/containers/podman/v4/pkg/strongunits"
|
||||||
"github.com/containers/podman/v4/pkg/util"
|
"github.com/containers/podman/v4/pkg/util"
|
||||||
"github.com/containers/podman/v4/utils"
|
"github.com/containers/podman/v4/utils"
|
||||||
|
"github.com/containers/storage/pkg/lockfile"
|
||||||
vfConfig "github.com/crc-org/vfkit/pkg/config"
|
vfConfig "github.com/crc-org/vfkit/pkg/config"
|
||||||
vfRest "github.com/crc-org/vfkit/pkg/rest"
|
vfRest "github.com/crc-org/vfkit/pkg/rest"
|
||||||
"github.com/docker/go-units"
|
"github.com/docker/go-units"
|
||||||
@ -77,6 +78,9 @@ type MacMachine struct {
|
|||||||
LogPath machine.VMFile
|
LogPath machine.VMFile
|
||||||
GvProxyPid machine.VMFile
|
GvProxyPid machine.VMFile
|
||||||
GvProxySock machine.VMFile
|
GvProxySock machine.VMFile
|
||||||
|
|
||||||
|
// Used at runtime for serializing write operations
|
||||||
|
lock *lockfile.LockFile
|
||||||
}
|
}
|
||||||
|
|
||||||
// setGVProxyInfo sets the VM's gvproxy pid and socket files
|
// setGVProxyInfo sets the VM's gvproxy pid and socket files
|
||||||
@ -353,6 +357,9 @@ func (m *MacMachine) Remove(name string, opts machine.RemoveOptions) (string, fu
|
|||||||
files []string
|
files []string
|
||||||
)
|
)
|
||||||
|
|
||||||
|
m.lock.Lock()
|
||||||
|
defer m.lock.Unlock()
|
||||||
|
|
||||||
vmState, err := m.Vfkit.state()
|
vmState, err := m.Vfkit.state()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", nil, err
|
return "", nil, err
|
||||||
@ -403,6 +410,10 @@ func (m *MacMachine) writeConfig() error {
|
|||||||
|
|
||||||
func (m *MacMachine) Set(name string, opts machine.SetOptions) ([]error, error) {
|
func (m *MacMachine) Set(name string, opts machine.SetOptions) ([]error, error) {
|
||||||
var setErrors []error
|
var setErrors []error
|
||||||
|
|
||||||
|
m.lock.Lock()
|
||||||
|
defer m.lock.Unlock()
|
||||||
|
|
||||||
vmState, err := m.State(false)
|
vmState, err := m.State(false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -527,6 +538,9 @@ func (m *MacMachine) addVolumesToVfKit() error {
|
|||||||
func (m *MacMachine) Start(name string, opts machine.StartOptions) error {
|
func (m *MacMachine) Start(name string, opts machine.StartOptions) error {
|
||||||
var ignitionSocket *machine.VMFile
|
var ignitionSocket *machine.VMFile
|
||||||
|
|
||||||
|
m.lock.Lock()
|
||||||
|
defer m.lock.Unlock()
|
||||||
|
|
||||||
st, err := m.State(false)
|
st, err := m.State(false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -680,6 +694,9 @@ func (m *MacMachine) State(_ bool) (machine.Status, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *MacMachine) Stop(name string, opts machine.StopOptions) error {
|
func (m *MacMachine) Stop(name string, opts machine.StopOptions) error {
|
||||||
|
m.lock.Lock()
|
||||||
|
defer m.lock.Unlock()
|
||||||
|
|
||||||
vmState, err := m.State(false)
|
vmState, err := m.State(false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -718,6 +735,13 @@ func (m *MacMachine) loadFromFile() (*MacMachine, error) {
|
|||||||
if err := loadMacMachineFromJSON(jsonPath, &mm); err != nil {
|
if err := loadMacMachineFromJSON(jsonPath, &mm); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lock, err := machine.GetLock(mm.Name, vmtype)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
mm.lock = lock
|
||||||
|
|
||||||
return &mm, nil
|
return &mm, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/containers/storage/pkg/homedir"
|
"github.com/containers/storage/pkg/homedir"
|
||||||
|
"github.com/containers/storage/pkg/lockfile"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -137,6 +138,24 @@ type VM interface {
|
|||||||
Stop(name string, opts StopOptions) error
|
Stop(name string, opts StopOptions) error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetLock(name string, vmtype VMType) (*lockfile.LockFile, error) {
|
||||||
|
// FIXME: there's a painful amount of `GetConfDir` calls scattered
|
||||||
|
// across the code base. This should be done once and stored
|
||||||
|
// somewhere instead.
|
||||||
|
vmConfigDir, err := GetConfDir(vmtype)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
lockPath := filepath.Join(vmConfigDir, name+".lock")
|
||||||
|
lock, err := lockfile.GetLockFile(lockPath)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("creating lockfile for VM: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return lock, nil
|
||||||
|
}
|
||||||
|
|
||||||
type DistributionDownload interface {
|
type DistributionDownload interface {
|
||||||
HasUsableCache() (bool, error)
|
HasUsableCache() (bool, error)
|
||||||
Get() *Download
|
Get() *Download
|
||||||
|
@ -21,6 +21,7 @@ import (
|
|||||||
"github.com/containers/podman/v4/pkg/strongunits"
|
"github.com/containers/podman/v4/pkg/strongunits"
|
||||||
"github.com/containers/podman/v4/pkg/util"
|
"github.com/containers/podman/v4/pkg/util"
|
||||||
"github.com/containers/podman/v4/utils"
|
"github.com/containers/podman/v4/utils"
|
||||||
|
"github.com/containers/storage/pkg/lockfile"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -66,6 +67,8 @@ type HyperVMachine struct {
|
|||||||
LastUp time.Time
|
LastUp time.Time
|
||||||
// GVProxy will write its PID here
|
// GVProxy will write its PID here
|
||||||
GvProxyPid machine.VMFile
|
GvProxyPid machine.VMFile
|
||||||
|
// Used at runtime for serializing write operations
|
||||||
|
lock *lockfile.LockFile
|
||||||
}
|
}
|
||||||
|
|
||||||
// addNetworkAndReadySocketsToRegistry adds the Network and Ready sockets to the
|
// addNetworkAndReadySocketsToRegistry adds the Network and Ready sockets to the
|
||||||
@ -358,6 +361,9 @@ func (m *HyperVMachine) Remove(_ string, opts machine.RemoveOptions) (string, fu
|
|||||||
files []string
|
files []string
|
||||||
diskPath string
|
diskPath string
|
||||||
)
|
)
|
||||||
|
m.lock.Lock()
|
||||||
|
defer m.lock.Unlock()
|
||||||
|
|
||||||
vmm := hypervctl.NewVirtualMachineManager()
|
vmm := hypervctl.NewVirtualMachineManager()
|
||||||
vm, err := vmm.GetMachine(m.Name)
|
vm, err := vmm.GetMachine(m.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -400,6 +406,10 @@ func (m *HyperVMachine) Set(name string, opts machine.SetOptions) ([]error, erro
|
|||||||
cpuChanged, memoryChanged bool
|
cpuChanged, memoryChanged bool
|
||||||
setErrors []error
|
setErrors []error
|
||||||
)
|
)
|
||||||
|
|
||||||
|
m.lock.Lock()
|
||||||
|
defer m.lock.Unlock()
|
||||||
|
|
||||||
vmm := hypervctl.NewVirtualMachineManager()
|
vmm := hypervctl.NewVirtualMachineManager()
|
||||||
// Considering this a hard return if we cannot lookup the machine
|
// Considering this a hard return if we cannot lookup the machine
|
||||||
vm, err := vmm.GetMachine(m.Name)
|
vm, err := vmm.GetMachine(m.Name)
|
||||||
@ -476,6 +486,9 @@ func (m *HyperVMachine) SSH(name string, opts machine.SSHOptions) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *HyperVMachine) Start(name string, opts machine.StartOptions) error {
|
func (m *HyperVMachine) Start(name string, opts machine.StartOptions) error {
|
||||||
|
m.lock.Lock()
|
||||||
|
defer m.lock.Unlock()
|
||||||
|
|
||||||
vmm := hypervctl.NewVirtualMachineManager()
|
vmm := hypervctl.NewVirtualMachineManager()
|
||||||
vm, err := vmm.GetMachine(m.Name)
|
vm, err := vmm.GetMachine(m.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -536,6 +549,9 @@ func (m *HyperVMachine) State(_ bool) (machine.Status, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *HyperVMachine) Stop(name string, opts machine.StopOptions) error {
|
func (m *HyperVMachine) Stop(name string, opts machine.StopOptions) error {
|
||||||
|
m.lock.Lock()
|
||||||
|
defer m.lock.Unlock()
|
||||||
|
|
||||||
vmm := hypervctl.NewVirtualMachineManager()
|
vmm := hypervctl.NewVirtualMachineManager()
|
||||||
vm, err := vmm.GetMachine(m.Name)
|
vm, err := vmm.GetMachine(m.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -582,6 +598,13 @@ func (m *HyperVMachine) loadFromFile() (*HyperVMachine, error) {
|
|||||||
}
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lock, err := machine.GetLock(mm.Name, vmtype)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
mm.lock = lock
|
||||||
|
|
||||||
vmm := hypervctl.NewVirtualMachineManager()
|
vmm := hypervctl.NewVirtualMachineManager()
|
||||||
vm, err := vmm.GetMachine(m.Name)
|
vm, err := vmm.GetMachine(m.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -125,6 +125,12 @@ func (p *QEMUVirtualization) LoadVMByName(name string) (machine.VM, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lock, err := machine.GetLock(vm.Name, vmtype)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
vm.lock = lock
|
||||||
|
|
||||||
return vm, nil
|
return vm, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,29 +80,6 @@ type MachineVM struct {
|
|||||||
lock *lockfile.LockFile
|
lock *lockfile.LockFile
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *MachineVM) setLock() error {
|
|
||||||
if v.lock != nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME: there's a painful amount of `GetConfDir` calls scattered
|
|
||||||
// across the code base. This should be done once and stored
|
|
||||||
// somewhere instead.
|
|
||||||
vmConfigDir, err := machine.GetConfDir(vmtype)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
lockPath := filepath.Join(vmConfigDir, v.Name+".lock")
|
|
||||||
lock, err := lockfile.GetLockFile(lockPath)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("creating lockfile for VM: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
v.lock = lock
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type Monitor struct {
|
type Monitor struct {
|
||||||
// Address portion of the qmp monitor (/tmp/tmp.sock)
|
// Address portion of the qmp monitor (/tmp/tmp.sock)
|
||||||
Address machine.VMFile
|
Address machine.VMFile
|
||||||
@ -360,9 +337,6 @@ func (v *MachineVM) Set(_ string, opts machine.SetOptions) ([]error, error) {
|
|||||||
// The setting(s) that failed to be applied will have its errors returned in setErrors
|
// The setting(s) that failed to be applied will have its errors returned in setErrors
|
||||||
var setErrors []error
|
var setErrors []error
|
||||||
|
|
||||||
if err := v.setLock(); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
v.lock.Lock()
|
v.lock.Lock()
|
||||||
defer v.lock.Unlock()
|
defer v.lock.Unlock()
|
||||||
|
|
||||||
@ -596,9 +570,6 @@ func (v *MachineVM) Start(name string, opts machine.StartOptions) error {
|
|||||||
defaultBackoff := 500 * time.Millisecond
|
defaultBackoff := 500 * time.Millisecond
|
||||||
maxBackoffs := 6
|
maxBackoffs := 6
|
||||||
|
|
||||||
if err := v.setLock(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
v.lock.Lock()
|
v.lock.Lock()
|
||||||
defer v.lock.Unlock()
|
defer v.lock.Unlock()
|
||||||
|
|
||||||
@ -929,9 +900,6 @@ func (v *MachineVM) VMPid() (int, error) {
|
|||||||
|
|
||||||
// Stop uses the qmp monitor to call a system_powerdown
|
// Stop uses the qmp monitor to call a system_powerdown
|
||||||
func (v *MachineVM) Stop(_ string, _ machine.StopOptions) error {
|
func (v *MachineVM) Stop(_ string, _ machine.StopOptions) error {
|
||||||
if err := v.setLock(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
v.lock.Lock()
|
v.lock.Lock()
|
||||||
defer v.lock.Unlock()
|
defer v.lock.Unlock()
|
||||||
|
|
||||||
@ -1154,9 +1122,6 @@ func (v *MachineVM) Remove(_ string, opts machine.RemoveOptions) (string, func()
|
|||||||
files []string
|
files []string
|
||||||
)
|
)
|
||||||
|
|
||||||
if err := v.setLock(); err != nil {
|
|
||||||
return "", nil, err
|
|
||||||
}
|
|
||||||
v.lock.Lock()
|
v.lock.Lock()
|
||||||
defer v.lock.Unlock()
|
defer v.lock.Unlock()
|
||||||
|
|
||||||
|
@ -71,6 +71,16 @@ func (p *WSLVirtualization) LoadVMByName(name string) (machine.VM, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
vm, err := readAndMigrate(configPath, name)
|
vm, err := readAndMigrate(configPath, name)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
lock, err := machine.GetLock(vm.Name, vmtype)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
vm.lock = lock
|
||||||
|
|
||||||
return vm, err
|
return vm, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,6 +22,7 @@ import (
|
|||||||
"github.com/containers/podman/v4/pkg/machine/wsl/wutil"
|
"github.com/containers/podman/v4/pkg/machine/wsl/wutil"
|
||||||
"github.com/containers/podman/v4/pkg/util"
|
"github.com/containers/podman/v4/pkg/util"
|
||||||
"github.com/containers/storage/pkg/homedir"
|
"github.com/containers/storage/pkg/homedir"
|
||||||
|
"github.com/containers/storage/pkg/lockfile"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"golang.org/x/text/encoding/unicode"
|
"golang.org/x/text/encoding/unicode"
|
||||||
"golang.org/x/text/transform"
|
"golang.org/x/text/transform"
|
||||||
@ -300,6 +301,8 @@ type MachineVM struct {
|
|||||||
Version int
|
Version int
|
||||||
// Whether to use user-mode networking
|
// Whether to use user-mode networking
|
||||||
UserModeNetworking bool
|
UserModeNetworking bool
|
||||||
|
// Used at runtime for serializing write operations
|
||||||
|
lock *lockfile.LockFile
|
||||||
}
|
}
|
||||||
|
|
||||||
type ExitCodeError struct {
|
type ExitCodeError struct {
|
||||||
@ -1061,6 +1064,9 @@ func (v *MachineVM) Set(_ string, opts machine.SetOptions) ([]error, error) {
|
|||||||
// The setting(s) that failed to be applied will have its errors returned in setErrors
|
// The setting(s) that failed to be applied will have its errors returned in setErrors
|
||||||
var setErrors []error
|
var setErrors []error
|
||||||
|
|
||||||
|
v.lock.Lock()
|
||||||
|
defer v.lock.Unlock()
|
||||||
|
|
||||||
if opts.Rootful != nil && v.Rootful != *opts.Rootful {
|
if opts.Rootful != nil && v.Rootful != *opts.Rootful {
|
||||||
err := v.setRootful(*opts.Rootful)
|
err := v.setRootful(*opts.Rootful)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -1118,6 +1124,9 @@ func (v *MachineVM) Set(_ string, opts machine.SetOptions) ([]error, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (v *MachineVM) Start(name string, opts machine.StartOptions) error {
|
func (v *MachineVM) Start(name string, opts machine.StartOptions) error {
|
||||||
|
v.lock.Lock()
|
||||||
|
defer v.lock.Unlock()
|
||||||
|
|
||||||
if v.isRunning() {
|
if v.isRunning() {
|
||||||
return machine.ErrVMAlreadyRunning
|
return machine.ErrVMAlreadyRunning
|
||||||
}
|
}
|
||||||
@ -1406,6 +1415,9 @@ func isSystemdRunning(dist string) (bool, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (v *MachineVM) Stop(name string, _ machine.StopOptions) error {
|
func (v *MachineVM) Stop(name string, _ machine.StopOptions) error {
|
||||||
|
v.lock.Lock()
|
||||||
|
defer v.lock.Unlock()
|
||||||
|
|
||||||
dist := toDist(v.Name)
|
dist := toDist(v.Name)
|
||||||
|
|
||||||
wsl, err := isWSLRunning(dist)
|
wsl, err := isWSLRunning(dist)
|
||||||
@ -1529,6 +1541,9 @@ func readWinProxyTid(v *MachineVM) (uint32, uint32, string, error) {
|
|||||||
func (v *MachineVM) Remove(name string, opts machine.RemoveOptions) (string, func() error, error) {
|
func (v *MachineVM) Remove(name string, opts machine.RemoveOptions) (string, func() error, error) {
|
||||||
var files []string
|
var files []string
|
||||||
|
|
||||||
|
v.lock.Lock()
|
||||||
|
defer v.lock.Unlock()
|
||||||
|
|
||||||
if v.isRunning() {
|
if v.isRunning() {
|
||||||
if !opts.Force {
|
if !opts.Force {
|
||||||
return "", nil, &machine.ErrVMRunningCannotDestroyed{Name: v.Name}
|
return "", nil, &machine.ErrVMRunningCannotDestroyed{Name: v.Name}
|
||||||
|
Reference in New Issue
Block a user