Skip to content

Commit b50e9ea

Browse files
committed
Refactor spots to make use of sys.IgnoringEintr
This makes use of pkg/sys's IgnoringEintr function to clean up some of the redundant eintr loops we had laying around. Signed-off-by: Danny Canter <[email protected]>
1 parent 3ea69db commit b50e9ea

File tree

4 files changed

+39
-77
lines changed

4 files changed

+39
-77
lines changed

core/metrics/cgroups/v1/oom.go

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525
"golang.org/x/sys/unix"
2626

2727
cgroups "github.com/containerd/cgroups/v3/cgroup1"
28+
"github.com/containerd/containerd/v2/pkg/sys"
2829
"github.com/containerd/log"
2930
metrics "github.com/docker/go-metrics"
3031
"github.com/prometheus/client_golang/prometheus"
@@ -110,16 +111,20 @@ func (o *oomCollector) Close() error {
110111
}
111112

112113
func (o *oomCollector) start() {
113-
var events [128]unix.EpollEvent
114+
var (
115+
n int
116+
err error
117+
events [128]unix.EpollEvent
118+
)
114119
for {
115-
n, err := unix.EpollWait(o.fd, events[:], -1)
116-
if err != nil {
117-
if err == unix.EINTR {
118-
continue
119-
}
120+
if err := sys.IgnoringEINTR(func() error {
121+
n, err = unix.EpollWait(o.fd, events[:], -1)
122+
return err
123+
}); err != nil {
120124
log.L.WithError(err).Error("cgroups: epoll wait failed, OOM notifications disabled")
121125
return
122126
}
127+
123128
for i := 0; i < n; i++ {
124129
o.process(uintptr(events[i].Fd))
125130
}

core/mount/mount_idmapped_linux.go

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -190,13 +190,9 @@ func getUsernsFD(uidMaps, gidMaps []syscall.SysProcIDMap) (_usernsFD *os.File, r
190190
}
191191

192192
func pidfdWaitid(pidFD *os.File) error {
193-
for {
194-
err := unix.Waitid(unix.P_PIDFD, int(pidFD.Fd()), nil, unix.WEXITED, nil)
195-
if err == unix.EINTR {
196-
continue
197-
}
198-
return err
199-
}
193+
return sys.IgnoringEINTR(func() error {
194+
return unix.Waitid(unix.P_PIDFD, int(pidFD.Fd()), nil, unix.WEXITED, nil)
195+
})
200196
}
201197

202198
var (

pkg/archive/link_freebsd.go

Lines changed: 2 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -18,65 +18,17 @@ package archive
1818

1919
import (
2020
"os"
21-
"syscall"
2221

22+
"github.com/containerd/containerd/v2/pkg/sys"
2323
"golang.org/x/sys/unix"
2424
)
2525

2626
func link(oldname, newname string) error {
27-
e := ignoringEINTR(func() error {
27+
e := sys.IgnoringEINTR(func() error {
2828
return unix.Linkat(unix.AT_FDCWD, oldname, unix.AT_FDCWD, newname, 0)
2929
})
3030
if e != nil {
3131
return &os.LinkError{Op: "link", Old: oldname, New: newname, Err: e}
3232
}
3333
return nil
3434
}
35-
36-
// The following contents were copied from Go 1.18.2.
37-
// Use of this source code is governed by the following
38-
// BSD-style license:
39-
//
40-
// Copyright (c) 2009 The Go Authors. All rights reserved.
41-
//
42-
// Redistribution and use in source and binary forms, with or without
43-
// modification, are permitted provided that the following conditions are
44-
// met:
45-
//
46-
// * Redistributions of source code must retain the above copyright
47-
// notice, this list of conditions and the following disclaimer.
48-
// * Redistributions in binary form must reproduce the above
49-
// copyright notice, this list of conditions and the following disclaimer
50-
// in the documentation and/or other materials provided with the
51-
// distribution.
52-
// * Neither the name of Google Inc. nor the names of its
53-
// contributors may be used to endorse or promote products derived from
54-
// this software without specific prior written permission.
55-
//
56-
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
57-
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
58-
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
59-
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
60-
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
61-
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
62-
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
63-
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
64-
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
65-
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
66-
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
67-
68-
// ignoringEINTR makes a function call and repeats it if it returns an
69-
// EINTR error. This appears to be required even though we install all
70-
// signal handlers with SA_RESTART: see #22838, #38033, #38836, #40846.
71-
// Also #20400 and #36644 are issues in which a signal handler is
72-
// installed without setting SA_RESTART. None of these are the common case,
73-
// but there are enough of them that it seems that we can't avoid
74-
// an EINTR loop.
75-
func ignoringEINTR(fn func() error) error {
76-
for {
77-
err := fn()
78-
if err != syscall.EINTR {
79-
return err
80-
}
81-
}
82-
}

pkg/oom/v1/v1.go

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import (
2828
"github.com/containerd/containerd/v2/core/runtime"
2929
"github.com/containerd/containerd/v2/pkg/oom"
3030
"github.com/containerd/containerd/v2/pkg/shim"
31+
"github.com/containerd/containerd/v2/pkg/sys"
3132
"github.com/containerd/log"
3233
"golang.org/x/sys/unix"
3334
)
@@ -67,23 +68,31 @@ func (e *epoller) Close() error {
6768

6869
// Run the epoll loop
6970
func (e *epoller) Run(ctx context.Context) {
70-
var events [128]unix.EpollEvent
71+
var (
72+
n int
73+
err error
74+
events [128]unix.EpollEvent
75+
)
7176
for {
72-
select {
73-
case <-ctx.Done():
74-
e.Close()
75-
return
76-
default:
77-
n, err := unix.EpollWait(e.fd, events[:], -1)
78-
if err != nil {
79-
if err == unix.EINTR {
80-
continue
81-
}
82-
log.G(ctx).WithError(err).Error("cgroups: epoll wait")
77+
err = sys.IgnoringEINTR(func() error {
78+
select {
79+
case <-ctx.Done():
80+
e.Close()
81+
return ctx.Err()
82+
default:
83+
n, err = unix.EpollWait(e.fd, events[:], -1)
84+
return err
8385
}
84-
for i := 0; i < n; i++ {
85-
e.process(ctx, uintptr(events[i].Fd))
86+
})
87+
if err != nil {
88+
if err == context.DeadlineExceeded || err == context.Canceled {
89+
return
8690
}
91+
log.G(ctx).WithError(err).Error("cgroups: epoll wait")
92+
}
93+
94+
for i := 0; i < n; i++ {
95+
e.process(ctx, uintptr(events[i].Fd))
8796
}
8897
}
8998
}

0 commit comments

Comments
 (0)