Merge pull request #74691 from cpuguy83/epoll_use_cloexec
Use EPOLL_CLOEXEC to prevent fd leaks.
This commit is contained in:
@@ -48,12 +48,12 @@ var _ CgroupNotifier = &linuxCgroupNotifier{}
|
|||||||
func NewCgroupNotifier(path, attribute string, threshold int64) (CgroupNotifier, error) {
|
func NewCgroupNotifier(path, attribute string, threshold int64) (CgroupNotifier, error) {
|
||||||
var watchfd, eventfd, epfd, controlfd int
|
var watchfd, eventfd, epfd, controlfd int
|
||||||
var err error
|
var err error
|
||||||
watchfd, err = unix.Open(fmt.Sprintf("%s/%s", path, attribute), unix.O_RDONLY, 0)
|
watchfd, err = unix.Open(fmt.Sprintf("%s/%s", path, attribute), unix.O_RDONLY|unix.O_CLOEXEC, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer unix.Close(watchfd)
|
defer unix.Close(watchfd)
|
||||||
controlfd, err = unix.Open(fmt.Sprintf("%s/cgroup.event_control", path), unix.O_WRONLY, 0)
|
controlfd, err = unix.Open(fmt.Sprintf("%s/cgroup.event_control", path), unix.O_WRONLY|unix.O_CLOEXEC, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -72,7 +72,7 @@ func NewCgroupNotifier(path, attribute string, threshold int64) (CgroupNotifier,
|
|||||||
unix.Close(eventfd)
|
unix.Close(eventfd)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
epfd, err = unix.EpollCreate1(0)
|
epfd, err = unix.EpollCreate1(unix.EPOLL_CLOEXEC)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@@ -23,7 +23,7 @@ import "golang.org/x/sys/unix"
|
|||||||
// Acquire acquires a lock on a file for the duration of the process. This method
|
// Acquire acquires a lock on a file for the duration of the process. This method
|
||||||
// is reentrant.
|
// is reentrant.
|
||||||
func Acquire(path string) error {
|
func Acquire(path string) error {
|
||||||
fd, err := unix.Open(path, unix.O_CREAT|unix.O_RDWR, 0600)
|
fd, err := unix.Open(path, unix.O_CREAT|unix.O_RDWR|unix.O_CLOEXEC, 0600)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@@ -497,7 +497,7 @@ func ExclusiveOpenFailsOnDevice(pathname string) (bool, error) {
|
|||||||
klog.Errorf("Path %q is not referring to a device.", pathname)
|
klog.Errorf("Path %q is not referring to a device.", pathname)
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
fd, errno := unix.Open(pathname, unix.O_RDONLY|unix.O_EXCL, 0)
|
fd, errno := unix.Open(pathname, unix.O_RDONLY|unix.O_EXCL|unix.O_CLOEXEC, 0)
|
||||||
// If the device is in use, open will return an invalid fd.
|
// If the device is in use, open will return an invalid fd.
|
||||||
// When this happens, it is expected that Close will fail and throw an error.
|
// When this happens, it is expected that Close will fail and throw an error.
|
||||||
defer unix.Close(fd)
|
defer unix.Close(fd)
|
||||||
|
@@ -398,7 +398,7 @@ func doSafeMakeDir(pathname string, base string, perm os.FileMode) error {
|
|||||||
return fmt.Errorf("cannot create directory %s: %s", currentPath, err)
|
return fmt.Errorf("cannot create directory %s: %s", currentPath, err)
|
||||||
}
|
}
|
||||||
// Dive into the created directory
|
// Dive into the created directory
|
||||||
childFD, err = syscall.Openat(parentFD, dir, nofollowFlags, 0)
|
childFD, err = syscall.Openat(parentFD, dir, nofollowFlags|unix.O_CLOEXEC, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("cannot open %s: %s", currentPath, err)
|
return fmt.Errorf("cannot open %s: %s", currentPath, err)
|
||||||
}
|
}
|
||||||
@@ -454,7 +454,7 @@ func findExistingPrefix(base, pathname string) (string, []string, error) {
|
|||||||
// This should be faster than looping through all dirs and calling os.Stat()
|
// This should be faster than looping through all dirs and calling os.Stat()
|
||||||
// on each of them, as the symlinks are resolved only once with OpenAt().
|
// on each of them, as the symlinks are resolved only once with OpenAt().
|
||||||
currentPath := base
|
currentPath := base
|
||||||
fd, err := syscall.Open(currentPath, syscall.O_RDONLY, 0)
|
fd, err := syscall.Open(currentPath, syscall.O_RDONLY|syscall.O_CLOEXEC, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return pathname, nil, fmt.Errorf("error opening %s: %s", currentPath, err)
|
return pathname, nil, fmt.Errorf("error opening %s: %s", currentPath, err)
|
||||||
}
|
}
|
||||||
@@ -466,7 +466,7 @@ func findExistingPrefix(base, pathname string) (string, []string, error) {
|
|||||||
for i, dir := range dirs {
|
for i, dir := range dirs {
|
||||||
// Using O_PATH here will prevent hangs in case user replaces directory with
|
// Using O_PATH here will prevent hangs in case user replaces directory with
|
||||||
// fifo
|
// fifo
|
||||||
childFD, err := syscall.Openat(fd, dir, unix.O_PATH, 0)
|
childFD, err := syscall.Openat(fd, dir, unix.O_PATH|unix.O_CLOEXEC, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if os.IsNotExist(err) {
|
if os.IsNotExist(err) {
|
||||||
return currentPath, dirs[i:], nil
|
return currentPath, dirs[i:], nil
|
||||||
@@ -499,7 +499,7 @@ func doSafeOpen(pathname string, base string) (int, error) {
|
|||||||
|
|
||||||
// Assumption: base is the only directory that we have under control.
|
// Assumption: base is the only directory that we have under control.
|
||||||
// Base dir is not allowed to be a symlink.
|
// Base dir is not allowed to be a symlink.
|
||||||
parentFD, err := syscall.Open(base, nofollowFlags, 0)
|
parentFD, err := syscall.Open(base, nofollowFlags|unix.O_CLOEXEC, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return -1, fmt.Errorf("cannot open directory %s: %s", base, err)
|
return -1, fmt.Errorf("cannot open directory %s: %s", base, err)
|
||||||
}
|
}
|
||||||
@@ -531,7 +531,7 @@ func doSafeOpen(pathname string, base string) (int, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
klog.V(5).Infof("Opening path %s", currentPath)
|
klog.V(5).Infof("Opening path %s", currentPath)
|
||||||
childFD, err = syscall.Openat(parentFD, seg, openFDFlags, 0)
|
childFD, err = syscall.Openat(parentFD, seg, openFDFlags|unix.O_CLOEXEC, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return -1, fmt.Errorf("cannot open %s: %s", currentPath, err)
|
return -1, fmt.Errorf("cannot open %s: %s", currentPath, err)
|
||||||
}
|
}
|
||||||
|
@@ -83,7 +83,7 @@ func TestCheckDeviceInode(t *testing.T) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
fd, err := unix.Open(test.srcPath, unix.O_CREAT, 0644)
|
fd, err := unix.Open(test.srcPath, unix.O_CREAT|unix.O_CLOEXEC, 0644)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Test %q: cannot open srcPath %s: %s", test.name, test.srcPath, err)
|
t.Errorf("Test %q: cannot open srcPath %s: %s", test.name, test.srcPath, err)
|
||||||
continue
|
continue
|
||||||
|
Reference in New Issue
Block a user