Stop qemu if kernel panic occurs
This commit is contained in:
		| @@ -71,6 +71,8 @@ type QemuSystem struct { | ||||
| 	Timeout         time.Duration | ||||
| 	KilledByTimeout bool | ||||
|  | ||||
| 	KernelPanic bool | ||||
|  | ||||
| 	Died        bool | ||||
| 	sshAddrPort string | ||||
|  | ||||
| @@ -154,6 +156,19 @@ func kvmExists() bool { | ||||
| 	return true | ||||
| } | ||||
|  | ||||
| func (q *QemuSystem) panicWatcher() { | ||||
| 	for { | ||||
| 		time.Sleep(time.Second) | ||||
| 		if bytes.Contains(q.Stdout, []byte("Kernel panic")) { | ||||
| 			time.Sleep(time.Second) | ||||
| 			// There is no reason to stay alive after kernel panic | ||||
| 			q.Stop() | ||||
| 			q.KernelPanic = true | ||||
| 			return | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Start qemu process | ||||
| func (q *QemuSystem) Start() (err error) { | ||||
| 	rand.Seed(time.Now().UnixNano()) // Are you sure? | ||||
| @@ -214,6 +229,8 @@ func (q *QemuSystem) Start() (err error) { | ||||
| 		err = errors.New("qemu died immediately: " + string(q.Stderr)) | ||||
| 	} | ||||
|  | ||||
| 	go q.panicWatcher() | ||||
|  | ||||
| 	if q.Timeout != 0 { | ||||
| 		go func() { | ||||
| 			time.Sleep(q.Timeout) | ||||
|   | ||||
| @@ -240,6 +240,41 @@ func TestQemuSystemCopyAndInsmod(t *testing.T) { | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestQemuSystemKernelPanic(t *testing.T) { | ||||
| 	qemu, err := startTestQemu(t, time.Minute) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| 	defer qemu.Stop() | ||||
|  | ||||
| 	// Enable sysrq | ||||
| 	_, err = qemu.Command("root", "echo 1 > /proc/sys/kernel/sysrq") | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
|  | ||||
| 	// Trigger kernel panic | ||||
| 	err = qemu.AsyncCommand("root", "sleep 1s && echo c > /proc/sysrq-trigger") | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
|  | ||||
| 	// Wait for panic watcher timeout | ||||
| 	time.Sleep(5 * time.Second) | ||||
|  | ||||
| 	if qemu.KilledByTimeout { | ||||
| 		t.Fatal("qemu is killed by timeout, not because of panic") | ||||
| 	} | ||||
|  | ||||
| 	if !qemu.Died { | ||||
| 		t.Fatal("qemu is not killed after kernel panic") | ||||
| 	} | ||||
|  | ||||
| 	if !qemu.KernelPanic { | ||||
| 		t.Fatal("qemu is died but there's no information about panic") | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestQemuSystemRun(t *testing.T) { | ||||
| 	qemu, err := startTestQemu(t, 0) | ||||
| 	if err != nil { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user