Merge pull request #114 from dong-liuliu/xliu2/vhost-user-dev

qmp: add ExecutePCIVhostUserDevAdd and ExecuteChardevDel to hotplug vhost-user device
This commit is contained in:
Mark Ryan
2020-01-15 10:03:26 +01:00
committed by GitHub
2 changed files with 74 additions and 0 deletions

View File

@@ -946,6 +946,17 @@ func (q *QMP) ExecuteBlockdevDel(ctx context.Context, blockdevID string) error {
return q.executeCommand(ctx, "x-blockdev-del", args, nil) return q.executeCommand(ctx, "x-blockdev-del", args, nil)
} }
// ExecuteChardevDel deletes a char device by sending a chardev-remove command.
// chardevID is the id of the char device to be deleted. Typically, this will
// match the id passed to ExecuteCharDevUnixSocketAdd. It must be a valid QMP id.
func (q *QMP) ExecuteChardevDel(ctx context.Context, chardevID string) error {
args := map[string]interface{}{
"id": chardevID,
}
return q.executeCommand(ctx, "chardev-remove", args, nil)
}
// ExecuteNetdevAdd adds a Net device to a QEMU instance // ExecuteNetdevAdd adds a Net device to a QEMU instance
// using the netdev_add command. netdevID is the id of the device to add. // using the netdev_add command. netdevID is the id of the device to add.
// Must be valid QMP identifier. // Must be valid QMP identifier.
@@ -1124,6 +1135,27 @@ func (q *QMP) ExecutePCIDeviceAdd(ctx context.Context, blockdevID, devID, driver
return q.executeCommand(ctx, "device_add", args, nil) return q.executeCommand(ctx, "device_add", args, nil)
} }
// ExecutePCIVhostUserDevAdd adds a vhost-user device to a QEMU instance using the device_add command.
// This function can be used to hot plug vhost-user devices on PCI(E) bridges.
// It receives the bus and the device address on its parent bus. bus is optional.
// devID is the id of the device to add.Must be valid QMP identifier. chardevID
// is the QMP identifier of character device using a unix socket as backend.
// driver is the name of vhost-user driver, like vhost-user-blk-pci.
func (q *QMP) ExecutePCIVhostUserDevAdd(ctx context.Context, driver, devID, chardevID, addr, bus string) error {
args := map[string]interface{}{
"driver": driver,
"id": devID,
"chardev": chardevID,
"addr": addr,
}
if bus != "" {
args["bus"] = bus
}
return q.executeCommand(ctx, "device_add", args, nil)
}
// ExecuteVFIODeviceAdd adds a VFIO device to a QEMU instance // ExecuteVFIODeviceAdd adds a VFIO device to a QEMU instance
// using the device_add command. devID is the id of the device to add. // using the device_add command. devID is the id of the device to add.
// Must be valid QMP identifier. bdf is the PCI bus-device-function // Must be valid QMP identifier. bdf is the PCI bus-device-function

View File

@@ -638,6 +638,28 @@ func TestQMPBlockdevDel(t *testing.T) {
<-disconnectedCh <-disconnectedCh
} }
// Checks that the chardev-remove command is correctly sent.
//
// We start a QMPLoop, send the chardev-remove command and stop the loop.
//
// The chardev-remove command should be correctly sent and the QMP loop should
// exit gracefully.
func TestQMPChardevDel(t *testing.T) {
connectedCh := make(chan *QMPVersion)
disconnectedCh := make(chan struct{})
buf := newQMPTestCommandBuffer(t)
buf.AddCommand("chardev-remove", nil, "return", nil)
cfg := QMPConfig{Logger: qmpTestLogger{}}
q := startQMPLoop(buf, cfg, connectedCh, disconnectedCh)
q.version = checkVersion(t, connectedCh)
err := q.ExecuteChardevDel(context.Background(), "chardev-0")
if err != nil {
t.Fatalf("Unexpected error %v", err)
}
q.Shutdown()
<-disconnectedCh
}
// Checks that the device_del command is correctly sent. // Checks that the device_del command is correctly sent.
// //
// We start a QMPLoop, send the device_del command and wait for it to complete. // We start a QMPLoop, send the device_del command and wait for it to complete.
@@ -1307,6 +1329,26 @@ func TestExecutePCIVSockAdd(t *testing.T) {
<-disconnectedCh <-disconnectedCh
} }
// Checks vhost-user-pci hotplug
func TestExecutePCIVhostUserDevAdd(t *testing.T) {
connectedCh := make(chan *QMPVersion)
disconnectedCh := make(chan struct{})
buf := newQMPTestCommandBuffer(t)
buf.AddCommand("device_add", nil, "return", nil)
cfg := QMPConfig{Logger: qmpTestLogger{}}
q := startQMPLoop(buf, cfg, connectedCh, disconnectedCh)
checkVersion(t, connectedCh)
driver := "vhost-user-blk-pci"
devID := "vhost-user-blk0"
chardevID := "vhost-user-blk-char0"
err := q.ExecutePCIVhostUserDevAdd(context.Background(), driver, devID, chardevID, "1", "1")
if err != nil {
t.Fatalf("Unexpected error %v", err)
}
q.Shutdown()
<-disconnectedCh
}
// Checks getfd // Checks getfd
func TestExecuteGetFdD(t *testing.T) { func TestExecuteGetFdD(t *testing.T) {
connectedCh := make(chan *QMPVersion) connectedCh := make(chan *QMPVersion)