qmp: Add ro argument for block-device hotplug funcs

We should allow users to specify if a block device should be hotplugged
as read-only.

Fixes: #157

Signed-off-by: Eric Ernst <eric.g.ernst@gmail.com>
This commit is contained in:
Eric Ernst 2021-01-11 15:27:51 -08:00 committed by Eric Ernst
parent 5b0331c0fa
commit e2eb549fcd
2 changed files with 9 additions and 8 deletions

View File

@ -773,11 +773,12 @@ func (q *QMP) ExecuteQuit(ctx context.Context) error {
return q.executeCommand(ctx, "quit", nil, nil) return q.executeCommand(ctx, "quit", nil, nil)
} }
func (q *QMP) blockdevAddBaseArgs(device, blockdevID string) (map[string]interface{}, map[string]interface{}) { func (q *QMP) blockdevAddBaseArgs(device, blockdevID string, ro bool) (map[string]interface{}, map[string]interface{}) {
var args map[string]interface{} var args map[string]interface{}
blockdevArgs := map[string]interface{}{ blockdevArgs := map[string]interface{}{
"driver": "raw", "driver": "raw",
"read-only": ro,
"file": map[string]interface{}{ "file": map[string]interface{}{
"driver": "file", "driver": "file",
"filename": device, "filename": device,
@ -801,8 +802,8 @@ func (q *QMP) blockdevAddBaseArgs(device, blockdevID string) (map[string]interfa
// path of the device to add, e.g., /dev/rdb0, and blockdevID is an identifier // path of the device to add, e.g., /dev/rdb0, and blockdevID is an identifier
// used to name the device. As this identifier will be passed directly to QMP, // 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. // 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 { func (q *QMP) ExecuteBlockdevAdd(ctx context.Context, device, blockdevID string, ro bool) error {
args, _ := q.blockdevAddBaseArgs(device, blockdevID) args, _ := q.blockdevAddBaseArgs(device, blockdevID, ro)
return q.executeCommand(ctx, "blockdev-add", args, nil) return q.executeCommand(ctx, "blockdev-add", args, nil)
} }
@ -814,8 +815,8 @@ func (q *QMP) ExecuteBlockdevAdd(ctx context.Context, device, blockdevID string)
// direct denotes whether use of O_DIRECT (bypass the host page cache) // direct denotes whether use of O_DIRECT (bypass the host page cache)
// is enabled. noFlush denotes whether flush requests for the device are // is enabled. noFlush denotes whether flush requests for the device are
// ignored. // ignored.
func (q *QMP) ExecuteBlockdevAddWithCache(ctx context.Context, device, blockdevID string, direct, noFlush bool) error { func (q *QMP) ExecuteBlockdevAddWithCache(ctx context.Context, device, blockdevID string, direct, noFlush, ro bool) error {
args, blockdevArgs := q.blockdevAddBaseArgs(device, blockdevID) args, blockdevArgs := q.blockdevAddBaseArgs(device, blockdevID, ro)
if q.version.Major < 2 || (q.version.Major == 2 && q.version.Minor < 9) { if q.version.Major < 2 || (q.version.Major == 2 && q.version.Minor < 9) {
return fmt.Errorf("versions of qemu (%d.%d) older than 2.9 do not support set cache-related options for block devices", return fmt.Errorf("versions of qemu (%d.%d) older than 2.9 do not support set cache-related options for block devices",

View File

@ -408,7 +408,7 @@ func TestQMPBlockdevAdd(t *testing.T) {
q := startQMPLoop(buf, cfg, connectedCh, disconnectedCh) q := startQMPLoop(buf, cfg, connectedCh, disconnectedCh)
q.version = checkVersion(t, connectedCh) q.version = checkVersion(t, connectedCh)
err := q.ExecuteBlockdevAdd(context.Background(), "/dev/rbd0", err := q.ExecuteBlockdevAdd(context.Background(), "/dev/rbd0",
fmt.Sprintf("drive_%s", volumeUUID)) fmt.Sprintf("drive_%s", volumeUUID), false)
if err != nil { if err != nil {
t.Fatalf("Unexpected error %v", err) t.Fatalf("Unexpected error %v", err)
} }
@ -432,7 +432,7 @@ func TestQMPBlockdevAddWithCache(t *testing.T) {
q := startQMPLoop(buf, cfg, connectedCh, disconnectedCh) q := startQMPLoop(buf, cfg, connectedCh, disconnectedCh)
q.version = checkVersion(t, connectedCh) q.version = checkVersion(t, connectedCh)
err := q.ExecuteBlockdevAddWithCache(context.Background(), "/dev/rbd0", err := q.ExecuteBlockdevAddWithCache(context.Background(), "/dev/rbd0",
fmt.Sprintf("drive_%s", volumeUUID), true, true) fmt.Sprintf("drive_%s", volumeUUID), true, true, false)
if err != nil { if err != nil {
t.Fatalf("Unexpected error %v", err) t.Fatalf("Unexpected error %v", err)
} }