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

     1  //go:build !remote
     2  // +build !remote
     3  
     4  package libpod
     5  
     6  import (
     7  	"fmt"
     8  
     9  	"github.com/containers/podman/v4/libpod/define"
    10  	"github.com/containers/podman/v4/libpod/events"
    11  )
    12  
    13  // RenumberLocks reassigns lock numbers for all containers and pods in the
    14  // state. This should NOT be run while there are other Libpod
    15  func (r *Runtime) RenumberLocks() error {
    16  	// TODO: It would be desirable to make it impossible to call this until all
    17  	// other libpod sessions are dead.
    18  	// Possibly use a read-write file lock, with all non-renumber podmans owning the
    19  	// lock as read, renumber attempting to take a write lock?
    20  	// The alternative is some sort of session tracking, and I don't know how
    21  	// reliable that can be.
    22  
    23  	// Acquire the alive lock and hold it.
    24  	// Ensures that we don't let other Podman commands run while we are
    25  	// changing around lock numbers.
    26  	aliveLock, err := r.getRuntimeAliveLock()
    27  	if err != nil {
    28  		return fmt.Errorf("retrieving alive lock: %w", err)
    29  	}
    30  	aliveLock.Lock()
    31  	defer aliveLock.Unlock()
    32  
    33  	if !r.valid {
    34  		return define.ErrRuntimeStopped
    35  	}
    36  
    37  	// Start off by deallocating all locks
    38  	if err := r.lockManager.FreeAllLocks(); err != nil {
    39  		return err
    40  	}
    41  
    42  	allCtrs, err := r.state.AllContainers(false)
    43  	if err != nil {
    44  		return err
    45  	}
    46  	for _, ctr := range allCtrs {
    47  		lock, err := r.lockManager.AllocateLock()
    48  		if err != nil {
    49  			return fmt.Errorf("allocating lock for container %s: %w", ctr.ID(), err)
    50  		}
    51  
    52  		ctr.config.LockID = lock.ID()
    53  
    54  		// Write the new lock ID
    55  		if err := r.state.RewriteContainerConfig(ctr, ctr.config); err != nil {
    56  			return err
    57  		}
    58  	}
    59  	allPods, err := r.state.AllPods()
    60  	if err != nil {
    61  		return err
    62  	}
    63  	for _, pod := range allPods {
    64  		lock, err := r.lockManager.AllocateLock()
    65  		if err != nil {
    66  			return fmt.Errorf("allocating lock for pod %s: %w", pod.ID(), err)
    67  		}
    68  
    69  		pod.config.LockID = lock.ID()
    70  
    71  		// Write the new lock ID
    72  		if err := r.state.RewritePodConfig(pod, pod.config); err != nil {
    73  			return err
    74  		}
    75  	}
    76  	allVols, err := r.state.AllVolumes()
    77  	if err != nil {
    78  		return err
    79  	}
    80  	for _, vol := range allVols {
    81  		lock, err := r.lockManager.AllocateLock()
    82  		if err != nil {
    83  			return fmt.Errorf("allocating lock for volume %s: %w", vol.Name(), err)
    84  		}
    85  
    86  		vol.config.LockID = lock.ID()
    87  
    88  		// Write the new lock ID
    89  		if err := r.state.RewriteVolumeConfig(vol, vol.config); err != nil {
    90  			return err
    91  		}
    92  	}
    93  
    94  	r.NewSystemEvent(events.Renumber)
    95  
    96  	return r.Shutdown(false)
    97  }