Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
040afab
watch event files for setFreeze
cblin321 Jan 1, 2026
ef6b6f9
fix implementation
cblin321 Jan 2, 2026
c9ef1cc
Update ci.yml
cblin321 Jan 2, 2026
a69b3a7
remove goroutine
cblin321 Jan 2, 2026
07249cc
restart on EINTR
cblin321 Jan 2, 2026
6d48dee
remove read
cblin321 Jan 2, 2026
a475332
linter errs
cblin321 Jan 2, 2026
593cb87
revert ci.yml
cblin321 Jan 2, 2026
35a2825
remove eintr err handling
cblin321 Jan 2, 2026
4a5f43c
improve err msgs; improve err handling
cblin321 Jan 2, 2026
b0a5a6d
update setFreezeState
cblin321 Jan 3, 2026
5111e2a
update warning; update err msgs
cblin321 Jan 10, 2026
b17a3d4
updates
cblin321 Jan 11, 2026
2bcd46d
Merge branch 'open-lambda:main' into main
cblin321 Jan 12, 2026
e71675a
refactor setFreeze state; update Release; fix typo
cblin321 Jan 13, 2026
91c53cb
fix typo
cblin321 Jan 13, 2026
62d284d
updates
cblin321 Jan 13, 2026
903b3cf
tighten up err msgs
cblin321 Jan 14, 2026
07fb393
start
cblin321 Jan 16, 2026
e6c2dbc
read from same open file in setFreezeState
cblin321 Jan 16, 2026
21b815c
bugs
cblin321 Jan 16, 2026
62cc32f
update
cblin321 Jan 16, 2026
78fca1b
reduce buffer size
cblin321 Jan 16, 2026
5fa8008
linter errs
cblin321 Jan 16, 2026
4816ac7
update ReadIntKVFromFile
cblin321 Jan 16, 2026
7be2db3
fix linter errs
cblin321 Jan 16, 2026
1508804
add warning for setFreezeState
cblin321 Jan 16, 2026
245e246
update read err handling
cblin321 Jan 16, 2026
6246a04
update TryReadIntKVFromFile
cblin321 Jan 20, 2026
a31b386
close file
cblin321 Jan 20, 2026
c42f691
err handling for seek
cblin321 Jan 20, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 34 additions & 9 deletions go/worker/sandbox/cgroups/cgroup.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"bufio"
"errors"
"fmt"
"golang.org/x/sys/unix"
"io"
"io/ioutil"
"log/slog"
"os"
Expand All @@ -13,7 +15,6 @@ import (
"time"

"github.com/open-lambda/open-lambda/go/common"
"golang.org/x/sys/unix"
)

type CgroupImpl struct {
Expand Down Expand Up @@ -138,12 +139,16 @@ func (cg *CgroupImpl) WriteString(resource string, val string) {
}
}

func (cg *CgroupImpl) TryReadIntKV(resource string, key string) (int64, error) {
raw, err := ioutil.ReadFile(cg.ResourcePath(resource))
func (_ *CgroupImpl) TryReadIntKVFromFile(file *os.File, key string) (int64, error) {
_, err := file.Seek(0, io.SeekStart)
if err != nil {
return 0, err
return 0, fmt.Errorf("failed to seek to start of file: %w", err)
}
data, err := io.ReadAll(file)
if err != nil {
return 0, fmt.Errorf("failed to read key %s from file: %w", key, err)
}
body := string(raw)
body := string(data)
lines := strings.Split(body, "\n")
for i := 0; i <= len(lines); i++ {
parts := strings.Split(lines[i], " ")
Expand All @@ -158,6 +163,16 @@ func (cg *CgroupImpl) TryReadIntKV(resource string, key string) (int64, error) {
return 0, fmt.Errorf("could not find key '%s' in file: %s", key, body)
}

func (cg *CgroupImpl) TryReadIntKV(resource string, key string) (int64, error) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the cleanest implementation of this function would be just opening the file, and passing the file to TryReadIntKVFromFile.

resourcePath := cg.ResourcePath(resource)
file, err := os.Open(resourcePath)
if err != nil {
return 0, fmt.Errorf("failed to open file %s: %w", resourcePath, err)
}
defer file.Close()
return cg.TryReadIntKVFromFile(file, key)
}

func (cg *CgroupImpl) TryReadInt(resource string) (int64, error) {
raw, err := ioutil.ReadFile(cg.ResourcePath(resource))
if err != nil {
Expand Down Expand Up @@ -201,22 +216,30 @@ func (cg *CgroupImpl) setFreezeState(state int64) error {
}
defer eventFile.Close()

// poll(2): POLLPRI indicates "cgroup.events file modified"
// cgroups(7): POLLPRI indicates "cgroup.events file modified"
// for poll to decide a POLLPRI event occurs it maintains 2 event counters:
// 1. the event counter when you last read the file
// 2. the file's current event counter
// if the last read's counter is different from the current event counter poll returns POLLPRI
pollFDs := []unix.PollFd{
{
Fd: int32(eventFile.Fd()),
Events: unix.POLLPRI,
},
}
pollCalls := 0

start := time.Now()

defer func(start time.Time) {
defer func() {
elapsed := time.Since(start)
if elapsed >= 250*time.Millisecond {
cg.printf("WARNING! setFreezeState to state %v took %v to complete", state, elapsed)
}
}(start)
if pollCalls > 5 {
cg.printf("WARNING! setFreezeState called poll %v times, could be busy waiting", pollCalls)
}
}()

cg.WriteInt("cgroup.freeze", state)

Expand All @@ -228,12 +251,14 @@ func (cg *CgroupImpl) setFreezeState(state int64) error {
return fmt.Errorf("cgroup freeze timeout after %v (expected state %v)", timeout, state)
}

pollCalls++
_, err := unix.Poll(pollFDs, int(remaining.Milliseconds()))
if err != nil && !errors.Is(err, unix.EINTR) {
return fmt.Errorf("poll syscall failed on %s: %w", resourcePath, err)
}

freezerState, err := cg.TryReadIntKV("cgroup.events", "frozen")
// read from the same file to update event counter, prevents busy wait
freezerState, err := cg.TryReadIntKVFromFile(eventFile, "frozen")
if err != nil {
return fmt.Errorf("failed to check self_freezing state :: %w", err)
}
Expand Down
2 changes: 1 addition & 1 deletion go/worker/sandbox/sock.go
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ func (container *SOCKContainer) DestroyIfPaused(reason string) {
}

// when the count goes to zero, it means (a) this container and (b)
// all it's descendants are destroyed. Thus, it's safe to release it's
// all its descendants are destroyed. Thus, it's safe to release its
// cgroups, and return the memory allocation to the memPool
func (container *SOCKContainer) decCgRefCount() {
newCount := atomic.AddInt32(&container.cgRefCount, -1)
Expand Down
Loading