Commit b5c46276 authored by Brandon Duffany's avatar Brandon Duffany Committed by Han-Wen Nienhuys

Lazily init /dev/null fd

Fixes an issue that the init() func in splice.go panics if
/dev is not yet mounted.

This allows supporting go-based init binaries which set up all the
filesystems on the machine, including both /dev as well as
FUSE-mounted dirs.

Change-Id: I74dab18effe4df410689ae7a2ef43670fcab7bd8
parent 7b4f97c3
......@@ -40,7 +40,7 @@ func (p *Pair) WriteTo(fd uintptr, n int) (int, error) {
const _SPLICE_F_NONBLOCK = 0x2
func (p *Pair) discard() {
_, err := syscall.Splice(p.r, nil, int(devNullFD), nil, int(p.size), _SPLICE_F_NONBLOCK)
_, err := syscall.Splice(p.r, nil, devNullFD(), nil, int(p.size), _SPLICE_F_NONBLOCK)
if err == syscall.EAGAIN {
// all good.
} else if err != nil {
......
......@@ -11,6 +11,7 @@ import (
"io/ioutil"
"log"
"os"
"sync"
"syscall"
)
......@@ -30,8 +31,10 @@ func MaxPipeSize() int {
// Since Linux 2.6.11, the pipe capacity is 65536 bytes.
const DefaultPipeSize = 16 * 4096
// We empty pipes by splicing to /dev/null.
var devNullFD uintptr
var (
devNullFDOnce sync.Once
devNullFDValue int
)
func init() {
content, err := ioutil.ReadFile("/proc/sys/fs/pipe-max-size")
......@@ -51,13 +54,18 @@ func init() {
resizable = resizable && (errNo == 0)
r.Close()
w.Close()
}
// We empty pipes by splicing to /dev/null.
func devNullFD() int {
devNullFDOnce.Do(func() {
fd, err := syscall.Open("/dev/null", os.O_WRONLY, 0)
if err != nil {
log.Panicf("splice: %v", err)
panic(fmt.Sprintf("failed to open /dev/null: %s", err))
}
devNullFD = uintptr(fd)
devNullFDValue = fd
})
return devNullFDValue
}
// copy & paste from syscall.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment