github.com/containers/libpod@v1.9.4-0.20220419124438-4284fd425507/pkg/rootless/rootless.go (about)

     1  package rootless
     2  
     3  import (
     4  	"os"
     5  
     6  	"github.com/containers/storage"
     7  	"github.com/pkg/errors"
     8  )
     9  
    10  // TryJoinPauseProcess attempts to join the namespaces of the pause PID via
    11  // TryJoinFromFilePaths.  If joining fails, it attempts to delete the specified
    12  // file.
    13  func TryJoinPauseProcess(pausePidPath string) (bool, int, error) {
    14  	if _, err := os.Stat(pausePidPath); err != nil {
    15  		return false, -1, nil
    16  	}
    17  
    18  	became, ret, err := TryJoinFromFilePaths("", false, []string{pausePidPath})
    19  	if err == nil {
    20  		return became, ret, err
    21  	}
    22  
    23  	// It could not join the pause process, let's lock the file before trying to delete it.
    24  	pidFileLock, err := storage.GetLockfile(pausePidPath)
    25  	if err != nil {
    26  		// The file was deleted by another process.
    27  		if os.IsNotExist(err) {
    28  			return false, -1, nil
    29  		}
    30  		return false, -1, errors.Wrapf(err, "error acquiring lock on %s", pausePidPath)
    31  	}
    32  
    33  	pidFileLock.Lock()
    34  	defer func() {
    35  		if pidFileLock.Locked() {
    36  			pidFileLock.Unlock()
    37  		}
    38  	}()
    39  
    40  	// Now the pause PID file is locked.  Try to join once again in case it changed while it was not locked.
    41  	became, ret, err = TryJoinFromFilePaths("", false, []string{pausePidPath})
    42  	if err != nil {
    43  		// It is still failing.  We can safely remove it.
    44  		os.Remove(pausePidPath)
    45  		return false, -1, nil
    46  	}
    47  	return became, ret, err
    48  }