Hacktoberfest 2026: những issue maintainer đã đánh dấu cho tháng Mười, đang mở và phù hợp người mới. Xem issue Hacktoberfest

orchestrator: NBDProvider.Close() syncs device before disconnecting, causing spurious EIO on sandbox cleanup after VM crash

Đang mở Phù hợp với người mới
#3,273 0 bình luận 0 reaction 0 người được giao Xem trên GitHub

Maintainer thường phản hồi trong vòng 1 ngày

Chưa có ai nhận issue này.

Đánh giá

Độ khó
2/5
Thời gian dự kiến
1-3 giờ
Mức phù hợp với người mới
75/100
Loại issue
Lỗi
Độ rõ ràng
Đặc tả rõ ràng
Mức độ hoạt động
Ít trao đổi
Công nghệ
go
Lĩnh vực
infrastructure

Hướng nghiên cứu

Bắt đầu trong packages/orchestrator/pkg/sandbox/rootfs/nbd.go, tập trung vào NBDProvider.Close() và sync(). Xác minh hành vi dọn dẹp sau khi VM gặp sự cố: EIO từ sync() phải được ghi log ở mức WARN mà không được truyền tiếp dưới dạng lỗi dọn dẹp, trong khi các lỗi sync khác vẫn phải được truyền tiếp.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

Describe the bug

When a Firecracker VM exits abnormally (OOM-kill, crash, etc.), NBDProvider.Close() in packages/orchestrator/pkg/sandbox/rootfs/nbd.go calls sync() before mnt.Close(). Because the NBD device is already in an error state after the VM dies, the ioctl(BLKFLSBUF) + fsync inside sync() returns EIO. This causes every sandbox cleanup after an abnormal VM exit to log:

failed to cleanup sandbox: error flushing cow device: failed to fsync path: input/output error

even though no data loss has occurred — the error is an expected consequence of the VM being dead, not a real storage failure.

Root cause

NBDProvider.Close() (line 130 of rootfs/nbd.go):

func (o *NBDProvider) Close(ctx context.Context) error {
    var errs []error

    err := o.sync(ctx)         // ← calls BLKFLSBUF ioctl + fsync on /dev/nbdX
    if err != nil {
        errs = append(errs, fmt.Errorf("error flushing cow device: %w", err))
    }

    err = o.mnt.Close(ctx)     // ← disconnects the NBD device (too late)
    ...
}

sync() (line 162) opens /dev/nbdX, issues BLKFLSBUF, then calls flush() which does syscall.Fsync. When the VM has already crashed, the NBD device is in error state and Fsync returns syscall.EIO. The error propagates up through Sandbox.Close() → setupSandboxLifecycle() which logs it at ERROR level.

Expected behavior

EIO from sync() during sandbox cleanup should be treated as an expected condition (VM died, no data to flush) and logged at WARN level rather than propagating as an error that triggers the "failed to cleanup sandbox" ERROR log.

Impact

  • Spurious "failed to cleanup sandbox" ERROR log on every abnormal VM exit
  • Noise in production alerting / on-call signals

Suggested fix

In NBDProvider.Close(), detect syscall.EIO from sync() and downgrade to a warning:

err := o.sync(ctx)
if err != nil {
    if errors.Is(err, syscall.EIO) {
        logger.L().Warn(ctx, "error flushing cow device (VM likely crashed, ignoring)", zap.Error(err))
    } else {
        errs = append(errs, fmt.Errorf("error flushing cow device: %w", err))
    }
}

Environment

  • Bare-metal deployment with Nomad
  • Observed under high sandbox creation load (thundering herd from client retries)
Ngôn ngữ chính
Go
Star
1.6k
Fork
438
Chỉ số merge pull request
Không có pull request nào được merge trong 30 ngày

Chuẩn bị môi trường

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của e2b-dev/runtime

Tất cả issue của e2b-dev/runtime

Issue tương tự

Thêm issue về Go

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.