From 66aeb467de80c92a099e49eaad6c25974c96f9cf Mon Sep 17 00:00:00 2001 From: Dmitry Vyukov Date: Thu, 12 Oct 2017 19:08:18 +0200 Subject: pkg/ipc: don't send program padding to executor Currently we always send 2MB of data to executor in ipc_simple.go. Send only what's consumed by the program, and don't send the trailing zeros. Serialized programs usually take only few KBs. --- pkg/csource/csource.go | 2 +- pkg/ipc/ipc_linux.go | 2 +- pkg/ipc/ipc_simple.go | 5 +++-- prog/encodingexec.go | 7 ++++--- prog/encodingexec_test.go | 4 ++-- 5 files changed, 11 insertions(+), 9 deletions(-) diff --git a/pkg/csource/csource.go b/pkg/csource/csource.go index 1bd818962..b0d44a94f 100644 --- a/pkg/csource/csource.go +++ b/pkg/csource/csource.go @@ -72,7 +72,7 @@ func Write(p *prog.Prog, opts Options) ([]byte, error) { return nil, fmt.Errorf("csource: invalid opts: %v", err) } exec := make([]byte, prog.ExecBufferSize) - if err := p.SerializeForExec(exec, 0); err != nil { + if _, err := p.SerializeForExec(exec, 0); err != nil { return nil, fmt.Errorf("failed to serialize program: %v", err) } w := new(bytes.Buffer) diff --git a/pkg/ipc/ipc_linux.go b/pkg/ipc/ipc_linux.go index 793611b91..0279b0ee8 100644 --- a/pkg/ipc/ipc_linux.go +++ b/pkg/ipc/ipc_linux.go @@ -128,7 +128,7 @@ func (env *Env) Close() error { func (env *Env) Exec(opts *ExecOpts, p *prog.Prog) (output []byte, info []CallInfo, failed, hanged bool, err0 error) { if p != nil { // Copy-in serialized program. - if err := p.SerializeForExec(env.in, env.pid); err != nil { + if _, err := p.SerializeForExec(env.in, env.pid); err != nil { err0 = fmt.Errorf("executor %v: failed to serialize: %v", env.pid, err) return } diff --git a/pkg/ipc/ipc_simple.go b/pkg/ipc/ipc_simple.go index 4c2ac6925..50dcce661 100644 --- a/pkg/ipc/ipc_simple.go +++ b/pkg/ipc/ipc_simple.go @@ -70,7 +70,8 @@ func (env *Env) Exec(opts *ExecOpts, p *prog.Prog) (output []byte, info []CallIn defer os.RemoveAll(dir) data := make([]byte, prog.ExecBufferSize) - if err := p.SerializeForExec(data, env.pid); err != nil { + n, err := p.SerializeForExec(data, env.pid) + if err != nil { err0 = err return } @@ -78,7 +79,7 @@ func (env *Env) Exec(opts *ExecOpts, p *prog.Prog) (output []byte, info []CallIn binary.Write(inbuf, binary.LittleEndian, uint64(env.config.Flags)) binary.Write(inbuf, binary.LittleEndian, uint64(opts.Flags)) binary.Write(inbuf, binary.LittleEndian, uint64(env.pid)) - inbuf.Write(data) + inbuf.Write(data[:n]) cmd := exec.Command(env.bin[0], env.bin[1:]...) cmd.Env = []string{} diff --git a/prog/encodingexec.go b/prog/encodingexec.go index b2b173bbe..e45ba1192 100644 --- a/prog/encodingexec.go +++ b/prog/encodingexec.go @@ -57,8 +57,9 @@ func (s ByPhysicalAddr) Less(i, j int) bool { } // SerializeForExec serializes program p for execution by process pid into the provided buffer. +// Returns number of bytes written to the buffer. // If the provided buffer is too small for the program an error is returned. -func (p *Prog) SerializeForExec(buffer []byte, pid int) error { +func (p *Prog) SerializeForExec(buffer []byte, pid int) (int, error) { if debug { if err := p.validate(); err != nil { panic(fmt.Errorf("serializing invalid program: %v", err)) @@ -193,9 +194,9 @@ func (p *Prog) SerializeForExec(buffer []byte, pid int) error { } w.write(ExecInstrEOF) if w.eof { - return fmt.Errorf("provided buffer is too small") + return 0, fmt.Errorf("provided buffer is too small") } - return nil + return len(buffer) - len(w.buf), nil } func (target *Target) physicalAddr(arg Arg) uint64 { diff --git a/prog/encodingexec_test.go b/prog/encodingexec_test.go index 3b37783f2..cff800911 100644 --- a/prog/encodingexec_test.go +++ b/prog/encodingexec_test.go @@ -15,7 +15,7 @@ func TestSerializeForExecRandom(t *testing.T) { buf := make([]byte, ExecBufferSize) for i := 0; i < iters; i++ { p := target.Generate(rs, 10, nil) - if err := p.SerializeForExec(buf, i%16); err != nil { + if _, err := p.SerializeForExec(buf, i%16); err != nil { t.Fatalf("failed to serialize: %v", err) } } @@ -269,7 +269,7 @@ func TestSerializeForExec(t *testing.T) { if err != nil { t.Fatalf("failed to deserialize prog %v: %v", i, err) } - if err := p.SerializeForExec(buf, i%16); err != nil { + if _, err := p.SerializeForExec(buf, i%16); err != nil { t.Fatalf("failed to serialize: %v", err) } w := new(bytes.Buffer) -- cgit mrf-deployment