mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-09-16 06:18:58 +00:00
qemu/qmp: re-implement mainLoop
In newer versions of QEMU, like 4.0-rc2, QMP events can be thrown even before the QMP-version response, one example of this behaviour is when a virtio serial is closed and a VSERPORT_CHANGE event is thrown. Re-implement mainLoop to check the data received from the VM channel, since it's not a guarantee that the first data read from the VM channel is the QMP version. fixes https://github.com/kata-containers/runtime/issues/1474 Signed-off-by: Julio Montes <julio.montes@intel.com>
This commit is contained in:
@@ -103,6 +103,19 @@ func newQMPTestCommandBuffer(t *testing.T) *qmpTestCommandBuffer {
|
||||
return b
|
||||
}
|
||||
|
||||
func newQMPTestCommandBufferNoGreeting(t *testing.T) *qmpTestCommandBuffer {
|
||||
b := &qmpTestCommandBuffer{
|
||||
newDataCh: make(chan []byte, 1),
|
||||
t: t,
|
||||
buf: bytes.NewBuffer([]byte{}),
|
||||
forceFail: make(chan struct{}),
|
||||
}
|
||||
b.cmds = make([]qmpTestCommand, 0, 8)
|
||||
b.events = make([]qmpTestEvent, 0, 8)
|
||||
b.results = make([]qmpTestResult, 0, 8)
|
||||
return b
|
||||
}
|
||||
|
||||
func (b *qmpTestCommandBuffer) startEventLoop(wg *sync.WaitGroup) {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
@@ -1504,3 +1517,48 @@ func TestExecuteNVDIMMDeviceAdd(t *testing.T) {
|
||||
q.Shutdown()
|
||||
<-disconnectedCh
|
||||
}
|
||||
|
||||
func TestMainLoopEventBeforeGreeting(t *testing.T) {
|
||||
const (
|
||||
seconds = 1352167040730
|
||||
microseconds = 123456
|
||||
)
|
||||
|
||||
connectedCh := make(chan *QMPVersion)
|
||||
disconnectedCh := make(chan struct{})
|
||||
buf := newQMPTestCommandBufferNoGreeting(t)
|
||||
|
||||
// Add events
|
||||
var wg sync.WaitGroup
|
||||
buf.AddEvent("VSERPORT_CHANGE", time.Millisecond*100,
|
||||
map[string]interface{}{
|
||||
"open": false,
|
||||
"id": "channel0",
|
||||
},
|
||||
map[string]interface{}{
|
||||
"seconds": seconds,
|
||||
"microseconds": microseconds,
|
||||
})
|
||||
buf.AddEvent("POWERDOWN", time.Millisecond*200, nil,
|
||||
map[string]interface{}{
|
||||
"seconds": seconds,
|
||||
"microseconds": microseconds,
|
||||
})
|
||||
|
||||
// register a channel to receive events
|
||||
eventCh := make(chan QMPEvent)
|
||||
cfg := QMPConfig{EventCh: eventCh, Logger: qmpTestLogger{}}
|
||||
q := startQMPLoop(buf, cfg, connectedCh, disconnectedCh)
|
||||
|
||||
// Start events, this will lead to a deadlock if mainLoop is not implemented
|
||||
// correctly
|
||||
buf.startEventLoop(&wg)
|
||||
wg.Wait()
|
||||
|
||||
// Send greeting and check version
|
||||
buf.newDataCh <- []byte(qmpHello)
|
||||
checkVersion(t, connectedCh)
|
||||
|
||||
q.Shutdown()
|
||||
<-disconnectedCh
|
||||
}
|
||||
|
Reference in New Issue
Block a user