Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
24f2e71
WIP
ValentaTomas Dec 10, 2025
179cd6a
Cleanup
ValentaTomas Dec 10, 2025
934c151
Reduce changes
ValentaTomas Dec 10, 2025
2b944be
Clarify call
ValentaTomas Dec 10, 2025
02ceff0
Clarify
ValentaTomas Dec 10, 2025
4ef608d
Add break
ValentaTomas Dec 10, 2025
7e8ad28
Add explicit error
ValentaTomas Dec 10, 2025
03df796
Fix shadowing
ValentaTomas Dec 10, 2025
d551f57
Fix range
ValentaTomas Dec 10, 2025
01dfa38
Improve export cleanup
ValentaTomas Dec 10, 2025
fe86cbe
Refactor
ValentaTomas Dec 10, 2025
9d7bdd6
Cleanup
ValentaTomas Dec 10, 2025
2081e9b
WIP
ValentaTomas Dec 16, 2025
565caf7
Fix error
ValentaTomas Dec 18, 2025
73857b6
Fix test offsets
ValentaTomas Dec 18, 2025
842a87d
Merge branch 'main' into process-read
ValentaTomas Dec 18, 2025
56c6b30
Update deps
ValentaTomas Dec 18, 2025
18f1b33
Fix 1.10 client call
ValentaTomas Dec 19, 2025
2d86614
Merge branch 'main' into process-read
ValentaTomas Dec 21, 2025
4da1210
Update FC versions
ValentaTomas Dec 21, 2025
1ad4777
Cleanup
ValentaTomas Dec 22, 2025
c65e4b8
Hide address
ValentaTomas Dec 22, 2025
7a3ccf2
Refactor
ValentaTomas Dec 22, 2025
a77af2c
Cleanup
ValentaTomas Dec 22, 2025
f5ae9d4
Remove log
ValentaTomas Dec 22, 2025
8751e41
Fix deps
ValentaTomas Dec 22, 2025
9c23c88
Cleanup
ValentaTomas Dec 22, 2025
4f1804d
Close cache on failure
ValentaTomas Dec 22, 2025
44433cd
Cleanup
ValentaTomas Dec 22, 2025
1e12ae7
Remove unused
ValentaTomas Dec 22, 2025
4fe3b23
Refactor
ValentaTomas Dec 22, 2025
04f6e8c
Cleanup
ValentaTomas Dec 22, 2025
3ddb00f
Merge branch 'main' into process-read
ValentaTomas Dec 22, 2025
7797ff9
Describe sandbox pause process
ValentaTomas Dec 22, 2025
e8ff76a
Merge branch 'process-read' of https://github.com/e2b-dev/infra into …
ValentaTomas Dec 22, 2025
75c965f
Add remote to nil cache
ValentaTomas Dec 22, 2025
9876039
Fix format
ValentaTomas Dec 22, 2025
02190a6
Fix comment
ValentaTomas Dec 22, 2025
518e4ee
Make test less flaky
ValentaTomas Dec 22, 2025
6fc9d96
Remove unused env var
ValentaTomas Dec 22, 2025
f7ff3b2
Remove unused env var
ValentaTomas Dec 22, 2025
9533b13
Merge branch 'main' into uffd-2nd
ValentaTomas Dec 22, 2025
44414c2
WIP
ValentaTomas Dec 22, 2025
b971e46
Cleanup
ValentaTomas Dec 22, 2025
7e9c8eb
Merge branch 'main' into uffd-2nd
ValentaTomas Dec 22, 2025
3ada4ff
Merge branch 'main' into uffd-2nd
ValentaTomas Dec 23, 2025
1530943
Merge branch 'main' into uffd-2nd
ValentaTomas Dec 29, 2025
d1804e7
Cleanup
ValentaTomas Dec 30, 2025
a722156
Merge branch 'main' into uffd-2nd
ValentaTomas Dec 30, 2025
b5d4345
Merge branch 'main' into uffd-2nd
ValentaTomas Dec 30, 2025
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
1 change: 0 additions & 1 deletion .github/actions/start-services/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,6 @@ runs:
STORAGE_PROVIDER: "Local"
ENVIRONMENT: "local"
OTEL_COLLECTOR_GRPC_ENDPOINT: "localhost:4317"
MAX_PARALLEL_MEMFILE_SNAPSHOTTING: "2"
SHARED_CHUNK_CACHE_PATH: "./.e2b-chunk-cache"
EDGE_TOKEN: "abdcdefghijklmnop"
run: |
Expand Down
1 change: 0 additions & 1 deletion packages/orchestrator/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ run-debug:
GCP_DOCKER_REPOSITORY_NAME=$(GCP_DOCKER_REPOSITORY_NAME) \
GOOGLE_SERVICE_ACCOUNT_BASE64=$(GOOGLE_SERVICE_ACCOUNT_BASE64) \
OTEL_COLLECTOR_GRPC_ENDPOINT=$(OTEL_COLLECTOR_GRPC_ENDPOINT) \
MAX_PARALLEL_MEMFILE_SNAPSHOTTING=$(MAX_PARALLEL_MEMFILE_SNAPSHOTTING) \
./bin/orchestrator

define setup_local_env
Expand Down
5 changes: 2 additions & 3 deletions packages/orchestrator/benchmark_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -304,9 +304,8 @@ func BenchmarkBaseImageLaunch(b *testing.B) {
type testCycle string

const (
onlyStart testCycle = "only-start"
startAndPause testCycle = "start-and-pause"
startPauseResume testCycle = "start-pause-resume"
onlyStart testCycle = "only-start"
startAndPause testCycle = "start-and-pause"
)

type testContainer struct {
Expand Down
29 changes: 8 additions & 21 deletions packages/orchestrator/internal/sandbox/block/cache_test.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
package block

import (
"bytes"
"crypto/rand"
"fmt"
"math"
"os"
"syscall"
Expand Down Expand Up @@ -60,7 +58,7 @@ func TestCopyFromProcess_FullRange(t *testing.T) {
require.NoError(t, err)
require.Equal(t, int(size), n)

require.NoError(t, compareData(data[:n], mem[:n]))
require.NoError(t, testutils.ErrorFromByteSlicesDifference(mem[:n], data[:n]))
}

func TestCopyFromProcess_LargeRanges(t *testing.T) {
Expand Down Expand Up @@ -94,19 +92,19 @@ func TestCopyFromProcess_LargeRanges(t *testing.T) {
n, err := cache.ReadAt(data1, 0)
require.NoError(t, err)
require.Equal(t, int(pageSize), n)
require.NoError(t, compareData(data1[:n], mem[0:pageSize]))
require.NoError(t, testutils.ErrorFromByteSlicesDifference(mem[0:pageSize], data1[:n]))

data2 := make([]byte, pageSize)
n, err = cache.ReadAt(data2, int64(pageSize))
require.NoError(t, err)
require.Equal(t, int(pageSize), n)
require.NoError(t, compareData(data2[:n], mem[pageSize*3:pageSize*4]))
require.NoError(t, testutils.ErrorFromByteSlicesDifference(mem[pageSize*3:pageSize*4], data2[:n]))

data3 := make([]byte, pageSize)
n, err = cache.ReadAt(data3, int64(pageSize*2))
require.NoError(t, err)
require.Equal(t, int(pageSize), n)
require.NoError(t, compareData(data3[:n], mem[pageSize:pageSize*2]))
require.NoError(t, testutils.ErrorFromByteSlicesDifference(mem[pageSize:pageSize*2], data3[:n]))
}

func TestCopyFromProcess_MultipleRanges(t *testing.T) {
Expand Down Expand Up @@ -152,7 +150,7 @@ func TestCopyFromProcess_MultipleRanges(t *testing.T) {
require.NoError(t, err)
require.Equal(t, int(pageSize), n)

require.NoError(t, compareData(data[:n], mem[alignedOffset:alignedOffset+int64(pageSize)]))
require.NoError(t, testutils.ErrorFromByteSlicesDifference(mem[alignedOffset:alignedOffset+int64(pageSize)], data[:n]))
}
}

Expand Down Expand Up @@ -192,13 +190,13 @@ func TestCopyFromProcess_HugepageToRegularPage(t *testing.T) {
n, err = cache.ReadAt(data, 0)
require.NoError(t, err)
require.Equal(t, int(pageSize*2), n)
require.NoError(t, compareData(data[:n], mem[0:pageSize*2]))
require.NoError(t, testutils.ErrorFromByteSlicesDifference(mem[0:pageSize*2], data[:n]))

data = make([]byte, pageSize*4)
n, err = cache.ReadAt(data, pageSize*2)
require.NoError(t, err)
require.Equal(t, int(pageSize*4), n)
require.NoError(t, compareData(data[:n], mem[pageSize*4:pageSize*8]))
require.NoError(t, testutils.ErrorFromByteSlicesDifference(mem[pageSize*4:pageSize*8], data[:n]))
}

func TestEmptyRanges(t *testing.T) {
Expand All @@ -218,17 +216,6 @@ func TestEmptyRanges(t *testing.T) {
})
}

func compareData(readBytes []byte, expectedBytes []byte) error {
// The bytes.Equal is the first place in this flow that actually touches the uffd managed memory and triggers the pagefault, so any deadlocks will manifest here.
if !bytes.Equal(readBytes, expectedBytes) {
idx, want, got := testutils.FirstDifferentByte(readBytes, expectedBytes)

return fmt.Errorf("content mismatch: want '%x, got %x at index %d", want, got, idx)
}

return nil
}

func TestSplitOversizedRanges(t *testing.T) {
t.Parallel()

Expand Down Expand Up @@ -395,7 +382,7 @@ func TestCopyFromProcess_Exceed_MAX_RW_COUNT(t *testing.T) {
n, err = cache.ReadAt(data, 0)
require.NoError(t, err)
require.Equal(t, int(size), n)
require.NoError(t, compareData(data[:n], mem[0:size]))
require.NoError(t, testutils.ErrorFromByteSlicesDifference(mem[0:size], data[:n]))
}

func BenchmarkCopyFromHugepagesFile(b *testing.B) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import (
"sync"
)

var ErrFdExit = errors.New("fd exit signal")

// FdExit is a wrapper around a pipe that allows to signal the exit of the uffd.
type FdExit struct {
r *os.File
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,31 @@
package testutils

import (
"errors"
"fmt"
)

// FirstDifferentByte returns the first byte index where a and b differ.
// It also returns the differing byte values (want, got).
// If slices are identical, it returns idx -1.
func FirstDifferentByte(a, b []byte) (idx int, want, got byte) {
smallerSize := min(len(a), len(b))
func ErrorFromByteSlicesDifference(expected, actual []byte) error {
var errs []error

for i := range smallerSize {
if a[i] != b[i] {
return i, b[i], a[i]
}
if len(expected) > len(actual) {
errs = append(errs, fmt.Errorf("expected slice (%d bytes) is longer than actual slice (%d bytes)", len(expected), len(actual)))
} else if len(expected) < len(actual) {
errs = append(errs, fmt.Errorf("actual slice (%d bytes) is longer than expected slice (%d bytes)", len(actual), len(expected)))
}

if len(a) != len(b) {
return smallerSize, 0, 0
smallerSize := min(len(expected), len(actual))

for i := range smallerSize {
if expected[i] != actual[i] {
errs = append(errs, fmt.Errorf("first different byte: want '%x', got '%x' at index %d", expected[i], actual[i], i))

break
}
}

return -1, 0, 0
return errors.Join(errs...)
}
5 changes: 4 additions & 1 deletion packages/orchestrator/internal/sandbox/uffd/uffd.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ func (u *Uffd) handle(ctx context.Context, sandboxId string) error {
m := memory.NewMapping(regions)

uffd, err := userfaultfd.NewUserfaultfdFromFd(
uintptr(fds[0]),
userfaultfd.Fd(fds[0]),
u.memfile,
m,
logger.L().With(logger.WithSandboxID(sandboxId)),
Expand All @@ -164,6 +164,9 @@ func (u *Uffd) handle(ctx context.Context, sandboxId string) error {
ctx,
u.fdExit,
)
if errors.Is(err, fdexit.ErrFdExit) {
return nil
}
if err != nil {
return fmt.Errorf("failed handling uffd: %w", err)
}
Expand Down
Loading
Loading