aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2017-10-12 19:08:18 +0200
committerDmitry Vyukov <dvyukov@google.com>2017-10-12 19:08:18 +0200
commit66aeb467de80c92a099e49eaad6c25974c96f9cf (patch)
treecde1ee4dca1033104b2b858007c4cd2d5e0b5d12
parent81e199f71969b97c80cbb4473ddd53adeed3b4d4 (diff)
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.
-rw-r--r--pkg/csource/csource.go2
-rw-r--r--pkg/ipc/ipc_linux.go2
-rw-r--r--pkg/ipc/ipc_simple.go5
-rw-r--r--prog/encodingexec.go7
-rw-r--r--prog/encodingexec_test.go4
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)