Browse Source

fix: require explicit build tags for io_uring backends, add implementation logging

All three io_uring backends (iceber, giouring, raw) now require explicit
build tags — no tag means standard-only. Each backend registers its name
via IOUringImpl so startup logs show compiled implementation alongside
requested/selected backend mode.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
feature/sw-block
Ping Qiu 17 hours ago
parent
commit
003b8c2f28
  1. 5
      weed/storage/blockvol/batchio/batchio.go
  2. 2
      weed/storage/blockvol/batchio/iouring_giouring_linux.go
  3. 2
      weed/storage/blockvol/batchio/iouring_iceber_linux.go
  4. 9
      weed/storage/blockvol/batchio/iouring_other.go
  5. 4
      weed/storage/blockvol/batchio/iouring_raw_linux.go
  6. 14
      weed/storage/blockvol/blockvol.go

5
weed/storage/blockvol/batchio/batchio.go

@ -23,6 +23,11 @@ import (
// Callers decide whether to fall back to standard or fail. // Callers decide whether to fall back to standard or fail.
var ErrIOUringUnavailable = errors.New("batchio: io_uring unavailable") var ErrIOUringUnavailable = errors.New("batchio: io_uring unavailable")
// IOUringImpl reports the compiled io_uring implementation name.
// Set by each iouring_*_linux.go file. Empty string means no io_uring
// backend was compiled in (standard only).
var IOUringImpl string
// Op represents a single I/O operation: read or write buf at offset. // Op represents a single I/O operation: read or write buf at offset.
type Op struct { type Op struct {
Buf []byte Buf []byte

2
weed/storage/blockvol/batchio/iouring_giouring_linux.go

@ -10,6 +10,8 @@ import (
"github.com/pawelgaczynski/giouring" "github.com/pawelgaczynski/giouring"
) )
func init() { IOUringImpl = "giouring" }
// giouringBatchIO implements BatchIO using giouring (direct liburing port). // giouringBatchIO implements BatchIO using giouring (direct liburing port).
// No goroutines or channels — direct SQE/CQE ring manipulation. // No goroutines or channels — direct SQE/CQE ring manipulation.
// Requires kernel 6.0+. // Requires kernel 6.0+.

2
weed/storage/blockvol/batchio/iouring_iceber_linux.go

@ -9,6 +9,8 @@ import (
"github.com/iceber/iouring-go" "github.com/iceber/iouring-go"
) )
func init() { IOUringImpl = "iceber" }
// ioUringBatchIO implements BatchIO using Linux io_uring. // ioUringBatchIO implements BatchIO using Linux io_uring.
// Requires kernel 5.6+ (linked fsync: 5.10+). // Requires kernel 5.6+ (linked fsync: 5.10+).
type ioUringBatchIO struct { type ioUringBatchIO struct {

9
weed/storage/blockvol/batchio/iouring_other.go

@ -1,9 +1,12 @@
//go:build !linux || no_iouring
//go:build !linux || (!iouring_iceber && !iouring_giouring && !iouring_raw)
package batchio package batchio
// NewIOUring returns ErrIOUringUnavailable on non-Linux platforms
// or when io_uring is disabled via the no_iouring build tag.
// NewIOUring returns ErrIOUringUnavailable when no io_uring backend is
// compiled in. On Linux, use one of these build tags to enable a backend:
// - iouring_iceber (iceber/iouring-go library)
// - iouring_giouring (pawelgaczynski/giouring library)
// - iouring_raw (raw syscall wrappers, zero deps)
func NewIOUring(ringSize uint) (BatchIO, error) { func NewIOUring(ringSize uint) (BatchIO, error) {
return nil, ErrIOUringUnavailable return nil, ErrIOUringUnavailable
} }

4
weed/storage/blockvol/batchio/iouring_raw_linux.go

@ -1,4 +1,4 @@
//go:build linux && !no_iouring && !iouring_iceber && !iouring_giouring
//go:build linux && iouring_raw
package batchio package batchio
@ -10,6 +10,8 @@ import (
"unsafe" "unsafe"
) )
func init() { IOUringImpl = "raw" }
// Raw io_uring syscall numbers. // Raw io_uring syscall numbers.
const ( const (
sysIOUringSetup = 425 sysIOUringSetup = 425

14
weed/storage/blockvol/blockvol.go

@ -1165,25 +1165,31 @@ func (v *BlockVol) Close() error {
// - "auto": tries io_uring, falls back to standard with warning // - "auto": tries io_uring, falls back to standard with warning
// - "io_uring": requires io_uring, returns error if unavailable // - "io_uring": requires io_uring, returns error if unavailable
func newBatchIO(mode IOBackendMode, logger *log.Logger) (batchio.BatchIO, string, error) { func newBatchIO(mode IOBackendMode, logger *log.Logger) (batchio.BatchIO, string, error) {
impl := batchio.IOUringImpl // compiled-in implementation ("iceber", "giouring", "raw", or "")
if impl == "" {
impl = "none"
}
switch mode { switch mode {
case IOBackendIOUring: case IOBackendIOUring:
bio, err := batchio.NewIOUring(256) bio, err := batchio.NewIOUring(256)
if err != nil { if err != nil {
return nil, "", fmt.Errorf("io_uring requested but unavailable: %w", err)
return nil, "", fmt.Errorf("io_uring requested but unavailable (compiled=%s): %w", impl, err)
} }
logger.Printf("io backend: requested=io_uring selected=io_uring")
logger.Printf("io backend: requested=io_uring implementation=%s selected=io_uring", impl)
return bio, "io_uring", nil return bio, "io_uring", nil
case IOBackendAuto: case IOBackendAuto:
bio, err := batchio.NewIOUring(256) bio, err := batchio.NewIOUring(256)
if err != nil { if err != nil {
logger.Printf("io backend: requested=auto selected=standard reason=%v", err)
logger.Printf("io backend: requested=auto implementation=%s selected=standard reason=%v", impl, err)
return batchio.NewStandard(), "standard", nil return batchio.NewStandard(), "standard", nil
} }
logger.Printf("io backend: requested=auto selected=io_uring")
logger.Printf("io backend: requested=auto implementation=%s selected=io_uring", impl)
return bio, "io_uring", nil return bio, "io_uring", nil
default: // IOBackendStandard or empty default: // IOBackendStandard or empty
logger.Printf("io backend: requested=standard implementation=%s selected=standard", impl)
return batchio.NewStandard(), "standard", nil return batchio.NewStandard(), "standard", nil
} }
} }
Loading…
Cancel
Save