Skip to content

Commit

Permalink
qemu: Update blockdev-add qmp command to support newer qemu versions
Browse files Browse the repository at this point in the history
With qemu 2.9, the qmp block-dev command was updated  from:
{ "execute": "blockdev-add", "arguments": { "options": { ... } } }

to:
{ "execute": "blockdev-add", "arguments": { ... } }

Also, instead of id, blockdev-add now requires a node-name for the
root node(https://wiki.qemu.org/index.php/ChangeLog/2.9)

Store the version information with QMPStart and use that to issue
qmp command for adding block devices in the correct format.

Signed-off-by: Archana Shinde <[email protected]>
  • Loading branch information
amshinde committed Aug 8, 2017
1 parent 476269e commit 81b734b
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 14 deletions.
34 changes: 22 additions & 12 deletions qemu/qmp.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ type QMP struct {
cfg QMPConfig
connectedCh chan<- *QMPVersion
disconnectedCh chan struct{}
version *QMPVersion
}

// QMPVersion contains the version number and the capabailities of a QEMU
Expand Down Expand Up @@ -533,7 +534,6 @@ func QMPStart(ctx context.Context, socket string, cfg QMPConfig, disconnectedCh

connectedCh := make(chan *QMPVersion)

var version *QMPVersion
q := startQMPLoop(conn, cfg, connectedCh, disconnectedCh)
select {
case <-ctx.Done():
Expand All @@ -542,13 +542,13 @@ func QMPStart(ctx context.Context, socket string, cfg QMPConfig, disconnectedCh
return nil, nil, fmt.Errorf("Canceled by caller")
case <-disconnectedCh:
return nil, nil, fmt.Errorf("Lost connection to VM")
case version = <-connectedCh:
if version == nil {
case q.version = <-connectedCh:
if q.version == nil {
return nil, nil, fmt.Errorf("Failed to find QMP version information")
}
}

return q, version, nil
return q, q.version, nil
}

// Shutdown closes the domain socket used to monitor a QEMU instance and
Expand Down Expand Up @@ -602,16 +602,26 @@ func (q *QMP) ExecuteQuit(ctx context.Context) error {
// used to name the device. As this identifier will be passed directly to QMP,
// it must obey QMP's naming rules, e,g., it must start with a letter.
func (q *QMP) ExecuteBlockdevAdd(ctx context.Context, device, blockdevID string) error {
args := map[string]interface{}{
"options": map[string]interface{}{
"driver": "raw",
"file": map[string]interface{}{
"driver": "file",
"filename": device,
},
"id": blockdevID,
var args map[string]interface{}

blockdevArgs := map[string]interface{}{
"driver": "raw",
"file": map[string]interface{}{
"driver": "file",
"filename": device,
},
}

if q.version.Major > 2 || (q.version.Major == 2 && q.version.Minor >= 9) {
blockdevArgs["node-name"] = blockdevID
args = blockdevArgs
} else {
blockdevArgs["id"] = blockdevID
args = map[string]interface{}{
"options": blockdevArgs,
}
}

return q.executeCommand(ctx, "blockdev-add", args, nil)
}

Expand Down
6 changes: 4 additions & 2 deletions qemu/qmp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ func (b *qmpTestCommandBuffer) Write(p []byte) (int, error) {
return len(p), nil
}

func checkVersion(t *testing.T, connectedCh <-chan *QMPVersion) {
func checkVersion(t *testing.T, connectedCh <-chan *QMPVersion) *QMPVersion {
var version *QMPVersion
select {
case <-time.After(time.Second):
Expand All @@ -233,6 +233,8 @@ func checkVersion(t *testing.T, connectedCh <-chan *QMPVersion) {
t.Fatal("Invalid capabilities")
}
}

return version
}

// Checks that a QMP Loop can be started and shutdown.
Expand Down Expand Up @@ -356,7 +358,7 @@ func TestQMPBlockdevAdd(t *testing.T) {
buf.AddCommand("blockdev-add", nil, "return", nil)
cfg := QMPConfig{Logger: qmpTestLogger{}}
q := startQMPLoop(buf, cfg, connectedCh, disconnectedCh)
checkVersion(t, connectedCh)
q.version = checkVersion(t, connectedCh)
err := q.ExecuteBlockdevAdd(context.Background(), "/dev/rbd0",
fmt.Sprintf("drive_%s", testutil.VolumeUUID))
if err != nil {
Expand Down

0 comments on commit 81b734b

Please sign in to comment.