github.com/containers/podman/v2@v2.2.2-0.20210501105131-c1e07d070c4c/pkg/util/utils_linux.go (about)

     1  package util
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"path/filepath"
     7  	"syscall"
     8  
     9  	"github.com/containers/podman/v2/pkg/rootless"
    10  	"github.com/containers/psgo"
    11  	"github.com/pkg/errors"
    12  	"github.com/sirupsen/logrus"
    13  )
    14  
    15  // GetContainerPidInformationDescriptors returns a string slice of all supported
    16  // format descriptors of GetContainerPidInformation.
    17  func GetContainerPidInformationDescriptors() ([]string, error) {
    18  	return psgo.ListDescriptors(), nil
    19  }
    20  
    21  // FindDeviceNodes parses /dev/ into a set of major:minor -> path, where
    22  // [major:minor] is the device's major and minor numbers formatted as, for
    23  // example, 2:0 and path is the path to the device node.
    24  // Symlinks to nodes are ignored.
    25  func FindDeviceNodes() (map[string]string, error) {
    26  	nodes := make(map[string]string)
    27  	err := filepath.Walk("/dev", func(path string, info os.FileInfo, err error) error {
    28  		if err != nil {
    29  			logrus.Warnf("Error descending into path %s: %v", path, err)
    30  			return filepath.SkipDir
    31  		}
    32  
    33  		// If we aren't a device node, do nothing.
    34  		if info.Mode()&(os.ModeDevice|os.ModeCharDevice) == 0 {
    35  			return nil
    36  		}
    37  
    38  		// We are a device node. Get major/minor.
    39  		sysstat, ok := info.Sys().(*syscall.Stat_t)
    40  		if !ok {
    41  			return errors.Errorf("Could not convert stat output for use")
    42  		}
    43  		major := sysstat.Rdev / 256
    44  		minor := sysstat.Rdev % 256
    45  
    46  		nodes[fmt.Sprintf("%d:%d", major, minor)] = path
    47  
    48  		return nil
    49  	})
    50  	if err != nil {
    51  		return nil, err
    52  	}
    53  
    54  	return nodes, nil
    55  }
    56  
    57  // CheckRootlessUIDRange checks the uid within the rootless container is in the range from /etc/subuid
    58  func CheckRootlessUIDRange(uid int) error {
    59  	uids, _, err := rootless.GetConfiguredMappings()
    60  	if err != nil {
    61  		return err
    62  	}
    63  	total := 0
    64  	for _, u := range uids {
    65  		total += u.Size
    66  	}
    67  	if uid > total {
    68  		return errors.Errorf("requested user's UID %d is too large for the rootless user namespace", uid)
    69  	}
    70  	return nil
    71  }