Skip to content

Commit a3e2ecd

Browse files
authored
Merge pull request #25 from lifubang/fix-getfreezer-error
fs2: ignore no device error when reading freezer state
2 parents 5766eb4 + 6df7bae commit a3e2ecd

File tree

1 file changed

+24
-8
lines changed

1 file changed

+24
-8
lines changed

fs2/freezer.go

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,9 @@ func setFreezer(dirPath string, state cgroups.FreezerState) error {
5353
func getFreezer(dirPath string) (cgroups.FreezerState, error) {
5454
fd, err := cgroups.OpenFile(dirPath, "cgroup.freeze", unix.O_RDONLY)
5555
if err != nil {
56-
// If the kernel is too old, then we just treat the freezer as being in
57-
// an "undefined" state.
58-
if os.IsNotExist(err) || errors.Is(err, unix.ENODEV) {
59-
err = nil
60-
}
61-
return cgroups.Undefined, err
56+
// If the kernel is too old, then we just treat the freezer as
57+
// being in an "undefined" state and ignore the error.
58+
return cgroups.Undefined, ignoreNotExistOrNoDeviceError(err)
6259
}
6360
defer fd.Close()
6461

@@ -67,11 +64,15 @@ func getFreezer(dirPath string) (cgroups.FreezerState, error) {
6764

6865
func readFreezer(dirPath string, fd *os.File) (cgroups.FreezerState, error) {
6966
if _, err := fd.Seek(0, 0); err != nil {
70-
return cgroups.Undefined, err
67+
// If the cgroup path is deleted at this point, then we just treat the freezer as
68+
// being in an "undefined" state and ignore the error.
69+
return cgroups.Undefined, ignoreNotExistOrNoDeviceError(err)
7170
}
7271
state := make([]byte, 2)
7372
if _, err := fd.Read(state); err != nil {
74-
return cgroups.Undefined, err
73+
// If the cgroup path is deleted at this point, then we just treat the freezer as
74+
// being in an "undefined" state and ignore the error.
75+
return cgroups.Undefined, ignoreNotExistOrNoDeviceError(err)
7576
}
7677
switch string(state) {
7778
case "0\n":
@@ -83,6 +84,21 @@ func readFreezer(dirPath string, fd *os.File) (cgroups.FreezerState, error) {
8384
}
8485
}
8586

87+
// ignoreNotExistOrNoDeviceError checks if the error is either a "not exist" error
88+
// or a "no device" error, and returns nil in those cases. Otherwise, it returns the error.
89+
func ignoreNotExistOrNoDeviceError(err error) error {
90+
// We can safely ignore the error in the following two common situations:
91+
// 1. The cgroup path does not exist at the time of opening(eg: the kernel is too old)
92+
// — indicated by os.IsNotExist.
93+
// 2. The cgroup path is deleted during the seek/read operation — indicated by
94+
// errors.Is(err, unix.ENODEV).
95+
// These conditions are expected and do not require special handling.
96+
if os.IsNotExist(err) || errors.Is(err, unix.ENODEV) {
97+
return nil
98+
}
99+
return err
100+
}
101+
86102
// waitFrozen polls cgroup.events until it sees "frozen 1" in it.
87103
func waitFrozen(dirPath string) (cgroups.FreezerState, error) {
88104
fd, err := cgroups.OpenFile(dirPath, "cgroup.events", unix.O_RDONLY)

0 commit comments

Comments
 (0)