qemu with hax to log dma reads & writes jcs.org/2018/11/12/vfio

Merge remote-tracking branch 'remotes/ericb/tags/pull-nbd-2019-09-24-v2' into staging

nbd patches for 2019-09-24

- Improved error message for plaintext client of encrypted server
- Fix various assertions when -object iothread is in use
- Silence a Coverity error for use-after-free on error path

# gpg: Signature made Wed 25 Sep 2019 14:35:52 BST
# gpg: using RSA key 71C2CC22B1C4602927D2F3AAA7A16B4A2527436A
# gpg: Good signature from "Eric Blake <eblake@redhat.com>" [full]
# gpg: aka "Eric Blake (Free Software Programmer) <ebb9@byu.net>" [full]
# gpg: aka "[jpeg image of size 6874]" [full]
# Primary key fingerprint: 71C2 CC22 B1C4 6029 27D2 F3AA A7A1 6B4A 2527 436A

* remotes/ericb/tags/pull-nbd-2019-09-24-v2:
util/qemu-sockets: fix keep_alive handling in inet_connect_saddr
tests: Use iothreads during iotest 223
nbd: Grab aio context lock in more places
nbd/server: attach client channel to the export's AioContext
nbd/client: Add hint when TLS is missing

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

+47 -10
+12 -2
blockdev-nbd.c
··· 151 151 BlockBackend *on_eject_blk; 152 152 NBDExport *exp; 153 153 int64_t len; 154 + AioContext *aio_context; 154 155 155 156 if (!nbd_server) { 156 157 error_setg(errp, "NBD server not running"); ··· 173 174 return; 174 175 } 175 176 177 + aio_context = bdrv_get_aio_context(bs); 178 + aio_context_acquire(aio_context); 176 179 len = bdrv_getlength(bs); 177 180 if (len < 0) { 178 181 error_setg_errno(errp, -len, 179 182 "Failed to determine the NBD export's length"); 180 - return; 183 + goto out; 181 184 } 182 185 183 186 if (!has_writable) { ··· 190 193 exp = nbd_export_new(bs, 0, len, name, NULL, bitmap, !writable, !writable, 191 194 NULL, false, on_eject_blk, errp); 192 195 if (!exp) { 193 - return; 196 + goto out; 194 197 } 195 198 196 199 /* The list of named exports has a strong reference to this export now and 197 200 * our only way of accessing it is through nbd_export_find(), so we can drop 198 201 * the strong reference that is @exp. */ 199 202 nbd_export_put(exp); 203 + 204 + out: 205 + aio_context_release(aio_context); 200 206 } 201 207 202 208 void qmp_nbd_server_remove(const char *name, ··· 204 210 Error **errp) 205 211 { 206 212 NBDExport *exp; 213 + AioContext *aio_context; 207 214 208 215 if (!nbd_server) { 209 216 error_setg(errp, "NBD server not running"); ··· 220 227 mode = NBD_SERVER_REMOVE_MODE_SAFE; 221 228 } 222 229 230 + aio_context = nbd_export_aio_context(exp); 231 + aio_context_acquire(aio_context); 223 232 nbd_export_remove(exp, mode, errp); 233 + aio_context_release(aio_context); 224 234 } 225 235 226 236 void qmp_nbd_server_stop(Error **errp)
+1
include/block/nbd.h
··· 340 340 341 341 BlockBackend *nbd_export_get_blockdev(NBDExport *exp); 342 342 343 + AioContext *nbd_export_aio_context(NBDExport *exp); 343 344 NBDExport *nbd_export_find(const char *name); 344 345 void nbd_export_close_all(void); 345 346
+1
nbd/client.c
··· 204 204 case NBD_REP_ERR_TLS_REQD: 205 205 error_setg(errp, "TLS negotiation required before option %" PRIu32 206 206 " (%s)", reply->option, nbd_opt_lookup(reply->option)); 207 + error_append_hint(errp, "Did you forget a valid tls-creds?\n"); 207 208 break; 208 209 209 210 case NBD_REP_ERR_UNKNOWN:
+23 -4
nbd/server.c
··· 1297 1297 return ret; 1298 1298 } 1299 1299 1300 + /* Attach the channel to the same AioContext as the export */ 1301 + if (client->exp && client->exp->ctx) { 1302 + qio_channel_attach_aio_context(client->ioc, client->exp->ctx); 1303 + } 1304 + 1300 1305 assert(!client->optlen); 1301 1306 trace_nbd_negotiate_success(); 1302 1307 ··· 1456 1461 static void nbd_eject_notifier(Notifier *n, void *data) 1457 1462 { 1458 1463 NBDExport *exp = container_of(n, NBDExport, eject_notifier); 1464 + AioContext *aio_context; 1465 + 1466 + aio_context = exp->ctx; 1467 + aio_context_acquire(aio_context); 1459 1468 nbd_export_close(exp); 1469 + aio_context_release(aio_context); 1460 1470 } 1461 1471 1462 1472 NBDExport *nbd_export_new(BlockDriverState *bs, uint64_t dev_offset, ··· 1475 1485 * NBD exports are used for non-shared storage migration. Make sure 1476 1486 * that BDRV_O_INACTIVE is cleared and the image is ready for write 1477 1487 * access since the export could be available before migration handover. 1488 + * ctx was acquired in the caller. 1478 1489 */ 1479 1490 assert(name); 1480 1491 ctx = bdrv_get_aio_context(bs); 1481 - aio_context_acquire(ctx); 1482 1492 bdrv_invalidate_cache(bs, NULL); 1483 - aio_context_release(ctx); 1484 1493 1485 1494 /* Don't allow resize while the NBD server is running, otherwise we don't 1486 1495 * care what happens with the node. */ ··· 1488 1497 if (!readonly) { 1489 1498 perm |= BLK_PERM_WRITE; 1490 1499 } 1491 - blk = blk_new(bdrv_get_aio_context(bs), perm, 1500 + blk = blk_new(ctx, perm, 1492 1501 BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE_UNCHANGED | 1493 1502 BLK_PERM_WRITE | BLK_PERM_GRAPH_MOD); 1494 1503 ret = blk_insert_bs(blk, bs, errp); ··· 1555 1564 } 1556 1565 1557 1566 exp->close = close; 1558 - exp->ctx = blk_get_aio_context(blk); 1567 + exp->ctx = ctx; 1559 1568 blk_add_aio_context_notifier(blk, blk_aio_attached, blk_aio_detach, exp); 1560 1569 1561 1570 if (on_eject_blk) { ··· 1588 1597 return NULL; 1589 1598 } 1590 1599 1600 + AioContext * 1601 + nbd_export_aio_context(NBDExport *exp) 1602 + { 1603 + return exp->ctx; 1604 + } 1605 + 1591 1606 void nbd_export_close(NBDExport *exp) 1592 1607 { 1593 1608 NBDClient *client, *next; ··· 1682 1697 void nbd_export_close_all(void) 1683 1698 { 1684 1699 NBDExport *exp, *next; 1700 + AioContext *aio_context; 1685 1701 1686 1702 QTAILQ_FOREACH_SAFE(exp, &exports, next, next) { 1703 + aio_context = exp->ctx; 1704 + aio_context_acquire(aio_context); 1687 1705 nbd_export_close(exp); 1706 + aio_context_release(aio_context); 1688 1707 } 1689 1708 } 1690 1709
+4 -2
tests/qemu-iotests/223
··· 2 2 # 3 3 # Test reading dirty bitmap over NBD 4 4 # 5 - # Copyright (C) 2018 Red Hat, Inc. 5 + # Copyright (C) 2018-2019 Red Hat, Inc. 6 6 # 7 7 # This program is free software; you can redistribute it and/or modify 8 8 # it under the terms of the GNU General Public License as published by ··· 109 109 echo "=== End dirty bitmaps, and start serving image over NBD ===" 110 110 echo 111 111 112 - _launch_qemu 2> >(_filter_nbd) 112 + _launch_qemu -object iothread,id=io0 2> >(_filter_nbd) 113 113 114 114 # Intentionally provoke some errors as well, to check error handling 115 115 silent= ··· 117 117 _send_qemu_cmd $QEMU_HANDLE '{"execute":"blockdev-add", 118 118 "arguments":{"driver":"qcow2", "node-name":"n", 119 119 "file":{"driver":"file", "filename":"'"$TEST_IMG"'"}}}' "return" 120 + _send_qemu_cmd $QEMU_HANDLE '{"execute":"x-blockdev-set-iothread", 121 + "arguments":{"node-name":"n", "iothread":"io0"}}' "return" 120 122 _send_qemu_cmd $QEMU_HANDLE '{"execute":"block-dirty-bitmap-disable", 121 123 "arguments":{"node":"n", "name":"b"}}' "return" 122 124 _send_qemu_cmd $QEMU_HANDLE '{"execute":"nbd-server-add",
+1
tests/qemu-iotests/223.out
··· 27 27 {"return": {}} 28 28 {"return": {}} 29 29 {"return": {}} 30 + {"return": {}} 30 31 {"error": {"class": "GenericError", "desc": "NBD server not running"}} 31 32 {"return": {}} 32 33 {"error": {"class": "GenericError", "desc": "NBD server already running"}}
+2
tests/qemu-iotests/233.out
··· 21 21 22 22 == check plain client to TLS server fails == 23 23 qemu-img: Could not open 'nbd://localhost:PORT': TLS negotiation required before option 7 (go) 24 + Did you forget a valid tls-creds? 24 25 server reported: Option 0x7 not permitted before TLS 25 26 qemu-nbd: TLS negotiation required before option 3 (list) 27 + Did you forget a valid tls-creds? 26 28 server reported: Option 0x3 not permitted before TLS 27 29 28 30 == check TLS works ==
+3 -2
util/qemu-sockets.c
··· 461 461 } 462 462 } 463 463 464 + freeaddrinfo(res); 465 + 464 466 if (sock < 0) { 465 467 error_propagate(errp, local_err); 468 + return sock; 466 469 } 467 - 468 - freeaddrinfo(res); 469 470 470 471 if (saddr->keep_alive) { 471 472 int val = 1;