Skip to content

Commit f2c27b8

Browse files
Retry file writes on EINTR errors
Go 1.14 introduces asynchronous preemption, which results in applications that invoke slow syscalls (e.g. writing to a cgroup file) getting EINTR errors. The Go runtime will fix this in version 1.15 onwards: golang/go#38033 But this fix won't be backported: golang/go#39026 (comment) As such, introduce a 'writeFile' helper function that retries when the error is an EINTR error. Signed-off-by: Andrew Dunham <[email protected]>
1 parent e9676da commit f2c27b8

File tree

14 files changed

+48
-30
lines changed

14 files changed

+48
-30
lines changed

blkio.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ import (
2020
"bufio"
2121
"fmt"
2222
"io"
23-
"io/ioutil"
2423
"os"
2524
"path/filepath"
2625
"strconv"
@@ -72,7 +71,7 @@ func (b *blkioController) Create(path string, resources *specs.LinuxResources) e
7271
}
7372
for _, t := range createBlkioSettings(resources.BlockIO) {
7473
if t.value != nil {
75-
if err := ioutil.WriteFile(
74+
if err := retryingWriteFile(
7675
filepath.Join(b.Path(path), fmt.Sprintf("blkio.%s", t.name)),
7776
t.format(t.value),
7877
defaultFilePerm,

cgroup.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ package cgroups
1818

1919
import (
2020
"fmt"
21-
"io/ioutil"
2221
"os"
2322
"path/filepath"
2423
"strconv"
@@ -169,7 +168,7 @@ func (c *cgroup) add(process Process) error {
169168
if err != nil {
170169
return err
171170
}
172-
if err := ioutil.WriteFile(
171+
if err := retryingWriteFile(
173172
filepath.Join(s.Path(p), cgroupProcs),
174173
[]byte(strconv.Itoa(process.Pid)),
175174
defaultFilePerm,
@@ -199,7 +198,7 @@ func (c *cgroup) addTask(process Process) error {
199198
if err != nil {
200199
return err
201200
}
202-
if err := ioutil.WriteFile(
201+
if err := retryingWriteFile(
203202
filepath.Join(s.Path(p), cgroupTasks),
204203
[]byte(strconv.Itoa(process.Pid)),
205204
defaultFilePerm,

cpu.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ package cgroups
1919
import (
2020
"bufio"
2121
"fmt"
22-
"io/ioutil"
2322
"os"
2423
"path/filepath"
2524
"strconv"
@@ -84,7 +83,7 @@ func (c *cpuController) Create(path string, resources *specs.LinuxResources) err
8483
value = []byte(strconv.FormatInt(*t.ivalue, 10))
8584
}
8685
if value != nil {
87-
if err := ioutil.WriteFile(
86+
if err := retryingWriteFile(
8887
filepath.Join(c.Path(path), fmt.Sprintf("cpu.%s", t.name)),
8988
value,
9089
defaultFilePerm,

cpuset.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ func (c *cpusetController) Create(path string, resources *specs.LinuxResources)
6969
},
7070
} {
7171
if t.value != "" {
72-
if err := ioutil.WriteFile(
72+
if err := retryingWriteFile(
7373
filepath.Join(c.Path(path), fmt.Sprintf("cpuset.%s", t.name)),
7474
[]byte(t.value),
7575
defaultFilePerm,
@@ -134,7 +134,7 @@ func (c *cpusetController) copyIfNeeded(current, parent string) error {
134134
return err
135135
}
136136
if isEmpty(currentCpus) {
137-
if err := ioutil.WriteFile(
137+
if err := retryingWriteFile(
138138
filepath.Join(current, "cpuset.cpus"),
139139
parentCpus,
140140
defaultFilePerm,
@@ -143,7 +143,7 @@ func (c *cpusetController) copyIfNeeded(current, parent string) error {
143143
}
144144
}
145145
if isEmpty(currentMems) {
146-
if err := ioutil.WriteFile(
146+
if err := retryingWriteFile(
147147
filepath.Join(current, "cpuset.mems"),
148148
parentMems,
149149
defaultFilePerm,

devices.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ package cgroups
1818

1919
import (
2020
"fmt"
21-
"io/ioutil"
2221
"os"
2322
"path/filepath"
2423

@@ -61,7 +60,7 @@ func (d *devicesController) Create(path string, resources *specs.LinuxResources)
6160
if device.Type == "" {
6261
device.Type = "a"
6362
}
64-
if err := ioutil.WriteFile(
63+
if err := retryingWriteFile(
6564
filepath.Join(d.Path(path), file),
6665
[]byte(deviceString(device)),
6766
defaultFilePerm,

freezer.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ func (f *freezerController) Thaw(path string) error {
5050
}
5151

5252
func (f *freezerController) changeState(path string, state State) error {
53-
return ioutil.WriteFile(
53+
return retryingWriteFile(
5454
filepath.Join(f.root, path, "freezer.state"),
5555
[]byte(strings.ToUpper(string(state))),
5656
defaultFilePerm,

hugetlb.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
package cgroups
1818

1919
import (
20-
"io/ioutil"
2120
"os"
2221
"path/filepath"
2322
"strconv"
@@ -57,7 +56,7 @@ func (h *hugetlbController) Create(path string, resources *specs.LinuxResources)
5756
return err
5857
}
5958
for _, limit := range resources.HugepageLimits {
60-
if err := ioutil.WriteFile(
59+
if err := retryingWriteFile(
6160
filepath.Join(h.Path(path), strings.Join([]string{"hugetlb", limit.Pagesize, "limit_in_bytes"}, ".")),
6261
[]byte(strconv.FormatUint(limit.Limit, 10)),
6362
defaultFilePerm,

memory.go

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ import (
2020
"bufio"
2121
"fmt"
2222
"io"
23-
"io/ioutil"
2423
"os"
2524
"path/filepath"
2625
"strconv"
@@ -214,7 +213,7 @@ func (m *memoryController) Create(path string, resources *specs.LinuxResources)
214213
// until a limit is set on the cgroup and limit cannot be set once the
215214
// cgroup has children, or if there are already tasks in the cgroup.
216215
for _, i := range []int64{1, -1} {
217-
if err := ioutil.WriteFile(
216+
if err := retryingWriteFile(
218217
filepath.Join(m.Path(path), "memory.kmem.limit_in_bytes"),
219218
[]byte(strconv.FormatInt(i, 10)),
220219
defaultFilePerm,
@@ -378,7 +377,7 @@ func (m *memoryController) parseStats(r io.Reader, stat *v1.MemoryStat) error {
378377
func (m *memoryController) set(path string, settings []memorySettings) error {
379378
for _, t := range settings {
380379
if t.value != nil {
381-
if err := ioutil.WriteFile(
380+
if err := retryingWriteFile(
382381
filepath.Join(m.Path(path), fmt.Sprintf("memory.%s", t.name)),
383382
[]byte(strconv.FormatInt(*t.value, 10)),
384383
defaultFilePerm,
@@ -468,7 +467,7 @@ func (m *memoryController) memoryEvent(path string, event MemoryEvent) (uintptr,
468467
defer evtFile.Close()
469468
data := fmt.Sprintf("%d %d %s", efd, evtFile.Fd(), event.Arg())
470469
evctlPath := filepath.Join(root, "cgroup.event_control")
471-
if err := ioutil.WriteFile(evctlPath, []byte(data), 0700); err != nil {
470+
if err := retryingWriteFile(evctlPath, []byte(data), 0700); err != nil {
472471
unix.Close(efd)
473472
return 0, err
474473
}

net_cls.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
package cgroups
1818

1919
import (
20-
"io/ioutil"
2120
"os"
2221
"path/filepath"
2322
"strconv"
@@ -48,7 +47,7 @@ func (n *netclsController) Create(path string, resources *specs.LinuxResources)
4847
return err
4948
}
5049
if resources.Network != nil && resources.Network.ClassID != nil && *resources.Network.ClassID > 0 {
51-
return ioutil.WriteFile(
50+
return retryingWriteFile(
5251
filepath.Join(n.Path(path), "net_cls.classid"),
5352
[]byte(strconv.FormatUint(uint64(*resources.Network.ClassID), 10)),
5453
defaultFilePerm,

net_prio.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ package cgroups
1818

1919
import (
2020
"fmt"
21-
"io/ioutil"
2221
"os"
2322
"path/filepath"
2423

@@ -49,7 +48,7 @@ func (n *netprioController) Create(path string, resources *specs.LinuxResources)
4948
}
5049
if resources.Network != nil {
5150
for _, prio := range resources.Network.Priorities {
52-
if err := ioutil.WriteFile(
51+
if err := retryingWriteFile(
5352
filepath.Join(n.Path(path), "net_prio.ifpriomap"),
5453
formatPrio(prio.Name, prio.Priority),
5554
defaultFilePerm,

0 commit comments

Comments
 (0)