diff --git a/blockdev-nbd.c b/blockdev-nbd.c index 582ffded77..ec8cf0ab8c 100644 --- a/blockdev-nbd.c +++ b/blockdev-nbd.c @@ -140,7 +140,8 @@ void qmp_nbd_server_start(SocketAddressLegacy *addr, } void qmp_nbd_server_add(const char *device, bool has_name, const char *name, - bool has_writable, bool writable, Error **errp) + bool has_writable, bool writable, + bool has_bitmap, const char *bitmap, Error **errp) { BlockDriverState *bs = NULL; BlockBackend *on_eject_blk; @@ -185,6 +186,15 @@ void qmp_nbd_server_add(const char *device, bool has_name, const char *name, * our only way of accessing it is through nbd_export_find(), so we can drop * the strong reference that is @exp. */ nbd_export_put(exp); + + if (has_bitmap) { + Error *err = NULL; + nbd_export_bitmap(exp, bitmap, bitmap, &err); + if (err) { + error_propagate(errp, err); + nbd_export_remove(exp, NBD_SERVER_REMOVE_MODE_HARD, NULL); + } + } } void qmp_nbd_server_remove(const char *name, diff --git a/hmp.c b/hmp.c index 80aa5ab504..8da5fd8760 100644 --- a/hmp.c +++ b/hmp.c @@ -2326,7 +2326,7 @@ void hmp_nbd_server_start(Monitor *mon, const QDict *qdict) } qmp_nbd_server_add(info->value->device, false, NULL, - true, writable, &local_err); + true, writable, false, NULL, &local_err); if (local_err != NULL) { qmp_nbd_server_stop(NULL); @@ -2347,7 +2347,8 @@ void hmp_nbd_server_add(Monitor *mon, const QDict *qdict) bool writable = qdict_get_try_bool(qdict, "writable", false); Error *local_err = NULL; - qmp_nbd_server_add(device, !!name, name, true, writable, &local_err); + qmp_nbd_server_add(device, !!name, name, true, writable, + false, NULL, &local_err); hmp_handle_error(mon, &local_err); } diff --git a/qapi/block.json b/qapi/block.json index 11f01f28ef..3d70420f76 100644 --- a/qapi/block.json +++ b/qapi/block.json @@ -246,6 +246,10 @@ # # @writable: Whether clients should be able to write to the device via the # NBD connection (default false). + +# @bitmap: Also export the dirty bitmap reachable from @device, so the +# NBD client can use NBD_OPT_SET_META_CONTEXT with +# "qemu:dirty-bitmap:NAME" to inspect the bitmap. (since 4.0) # # Returns: error if the server is not running, or export with the same name # already exists. @@ -253,7 +257,8 @@ # Since: 1.3.0 ## { 'command': 'nbd-server-add', - 'data': {'device': 'str', '*name': 'str', '*writable': 'bool'} } + 'data': {'device': 'str', '*name': 'str', '*writable': 'bool', + '*bitmap': 'str' } } ## # @NbdServerRemoveMode: diff --git a/tests/qemu-iotests/223 b/tests/qemu-iotests/223 index f200e313c0..0bcc98a867 100755 --- a/tests/qemu-iotests/223 +++ b/tests/qemu-iotests/223 @@ -126,23 +126,20 @@ _send_qemu_cmd $QEMU_HANDLE '{"execute":"nbd-server-start", "arguments":{"addr":{"type":"unix", "data":{"path":"'"$TEST_DIR/nbd"1'"}}}}' "error" # Attempt second server _send_qemu_cmd $QEMU_HANDLE '{"execute":"nbd-server-add", - "arguments":{"device":"n"}}' "return" + "arguments":{"device":"n", "bitmap":"b"}}' "return" _send_qemu_cmd $QEMU_HANDLE '{"execute":"nbd-server-add", "arguments":{"device":"nosuch"}}' "error" # Attempt to export missing node _send_qemu_cmd $QEMU_HANDLE '{"execute":"nbd-server-add", "arguments":{"device":"n"}}' "error" # Attempt to export same name twice -_send_qemu_cmd $QEMU_HANDLE '{"execute":"x-nbd-server-add-bitmap", - "arguments":{"name":"n", "bitmap":"b"}}' "return" _send_qemu_cmd $QEMU_HANDLE '{"execute":"nbd-server-add", - "arguments":{"device":"n", "name":"n2"}}' "return" -_send_qemu_cmd $QEMU_HANDLE '{"execute":"x-nbd-server-add-bitmap", - "arguments":{"name":"n2", "bitmap":"b2"}}' "error" # Enabled vs. read-only -_send_qemu_cmd $QEMU_HANDLE '{"execute":"nbd-server-remove", - "arguments":{"name":"n2"}}' "return" + "arguments":{"device":"n", "name":"n2", + "bitmap":"b2"}}' "error" # enabled vs. read-only _send_qemu_cmd $QEMU_HANDLE '{"execute":"nbd-server-add", - "arguments":{"device":"n", "name":"n2", "writable":true}}' "return" -_send_qemu_cmd $QEMU_HANDLE '{"execute":"x-nbd-server-add-bitmap", - "arguments":{"name":"n2", "bitmap":"b2"}}' "return" + "arguments":{"device":"n", "name":"n2", + "bitmap":"b3"}}' "error" # Missing bitmap +_send_qemu_cmd $QEMU_HANDLE '{"execute":"nbd-server-add", + "arguments":{"device":"n", "name":"n2", "writable":true, + "bitmap":"b2"}}' "return" echo echo "=== Contrast normal status to large granularity dirty-bitmap ===" diff --git a/tests/qemu-iotests/223.out b/tests/qemu-iotests/223.out index 7d147291d4..ebd3935c97 100644 --- a/tests/qemu-iotests/223.out +++ b/tests/qemu-iotests/223.out @@ -33,11 +33,8 @@ wrote 2097152/2097152 bytes at offset 2097152 {"return": {}} {"error": {"class": "GenericError", "desc": "Cannot find device=nosuch nor node_name=nosuch"}} {"error": {"class": "GenericError", "desc": "NBD server already has export named 'n'"}} -{"return": {}} -{"return": {}} {"error": {"class": "GenericError", "desc": "Enabled bitmap 'b2' incompatible with readonly export"}} -{"return": {}} -{"return": {}} +{"error": {"class": "GenericError", "desc": "Bitmap 'b3' is not found"}} {"return": {}} === Contrast normal status to large granularity dirty-bitmap ===