1
0

Implements timeout for qemu

This commit is contained in:
dump_stack() 2018-09-22 07:28:08 +00:00
parent a33d658001
commit ac6dc96d69
2 changed files with 45 additions and 5 deletions

View File

@ -70,6 +70,13 @@ type QemuSystem struct {
Cpus int Cpus int
Memory int Memory int
// Timeout works after Start invocation
Timeout time.Duration
KilledByTimeout bool
Died bool
sshAddrPort string
// accessible while qemu is runned // accessible while qemu is runned
cmd *exec.Cmd cmd *exec.Cmd
pipe struct { pipe struct {
@ -77,8 +84,6 @@ type QemuSystem struct {
stderr io.ReadCloser stderr io.ReadCloser
stdout io.ReadCloser stdout io.ReadCloser
} }
died bool
sshAddrPort string
// accessible after qemu is closed // accessible after qemu is closed
Stdout, Stderr string Stdout, Stderr string
@ -197,15 +202,23 @@ func (q *QemuSystem) Start() (err error) {
q.Stdout, _ = readUntilEOF(q.pipe.stdout) q.Stdout, _ = readUntilEOF(q.pipe.stdout)
q.Stderr, _ = readUntilEOF(q.pipe.stderr) q.Stderr, _ = readUntilEOF(q.pipe.stderr)
q.exitErr = q.cmd.Wait() q.exitErr = q.cmd.Wait()
q.died = true q.Died = true
}() }()
time.Sleep(time.Second / 10) // wait for immediately die time.Sleep(time.Second / 10) // wait for immediately die
if q.died { if q.Died {
err = errors.New("qemu died immediately: " + q.Stderr) err = errors.New("qemu died immediately: " + q.Stderr)
} }
if q.Timeout != 0 {
go func() {
time.Sleep(q.Timeout)
q.KilledByTimeout = true
q.Stop()
}()
}
return return
} }
@ -215,7 +228,7 @@ func (q *QemuSystem) Stop() {
fmt.Fprintf(q.pipe.stdin, "%cx", 1) fmt.Fprintf(q.pipe.stdin, "%cx", 1)
// wait for die // wait for die
time.Sleep(time.Second / 10) time.Sleep(time.Second / 10)
if !q.died { if !q.Died {
q.cmd.Process.Signal(syscall.SIGTERM) q.cmd.Process.Signal(syscall.SIGTERM)
time.Sleep(time.Second / 10) time.Sleep(time.Second / 10)
q.cmd.Process.Signal(syscall.SIGKILL) q.cmd.Process.Signal(syscall.SIGKILL)

View File

@ -8,6 +8,7 @@ import (
"net" "net"
"strings" "strings"
"testing" "testing"
"time"
) )
func TestQemuSystemNew_InvalidKernelPath(t *testing.T) { func TestQemuSystemNew_InvalidKernelPath(t *testing.T) {
@ -55,6 +56,30 @@ func TestQemuSystemStart(t *testing.T) {
qemu.Stop() qemu.Stop()
} }
func TestQemuSystemStart_Timeout(t *testing.T) {
kernel := Kernel{Name: "Host kernel", Path: testConfigVmlinuz}
qemu, err := NewQemuSystem(X86_64, kernel, "/bin/sh")
if err != nil {
t.Fatal(err)
}
qemu.Timeout = time.Second
if err = qemu.Start(); err != nil {
t.Fatal(err)
}
time.Sleep(2 * time.Second)
if !qemu.Died {
t.Fatal("qemu does not died :c")
}
if !qemu.KilledByTimeout {
t.Fatal("qemu died not because of timeout O_o")
}
}
func TestGetFreeAddrPort(t *testing.T) { func TestGetFreeAddrPort(t *testing.T) {
addrPort := getFreeAddrPort() addrPort := getFreeAddrPort()
ln, err := net.Listen("tcp", addrPort) ln, err := net.Listen("tcp", addrPort)
@ -71,6 +96,8 @@ func startTestQemu() (q *QemuSystem, err error) {
return return
} }
q.Timeout = 10 * time.Second
if err = q.Start(); err != nil { if err = q.Start(); err != nil {
return return
} }