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

qapi: add nbd-server-remove

Add command for removing an export. It is needed for cases when we
don't want to keep the export after the operation on it was completed.
The other example is a temporary node, created with blockdev-add.
If we want to delete it we should firstly remove any corresponding
NBD export.

Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Message-Id: <20180119135719.24745-3-vsementsov@virtuozzo.com>
[eblake: drop dead nb_clients code]
Signed-off-by: Eric Blake <eblake@redhat.com>

authored by

Vladimir Sementsov-Ogievskiy and committed by
Eric Blake
a3b0dc75 dba49323

+79
+24
blockdev-nbd.c
··· 189 189 nbd_export_put(exp); 190 190 } 191 191 192 + void qmp_nbd_server_remove(const char *name, 193 + bool has_mode, NbdServerRemoveMode mode, 194 + Error **errp) 195 + { 196 + NBDExport *exp; 197 + 198 + if (!nbd_server) { 199 + error_setg(errp, "NBD server not running"); 200 + return; 201 + } 202 + 203 + exp = nbd_export_find(name); 204 + if (exp == NULL) { 205 + error_setg(errp, "Export '%s' is not found", name); 206 + return; 207 + } 208 + 209 + if (!has_mode) { 210 + mode = NBD_SERVER_REMOVE_MODE_SAFE; 211 + } 212 + 213 + nbd_export_remove(exp, mode, errp); 214 + } 215 + 192 216 void qmp_nbd_server_stop(Error **errp) 193 217 { 194 218 nbd_export_close_all();
+1
include/block/nbd.h
··· 261 261 bool writethrough, BlockBackend *on_eject_blk, 262 262 Error **errp); 263 263 void nbd_export_close(NBDExport *exp); 264 + void nbd_export_remove(NBDExport *exp, NbdServerRemoveMode mode, Error **errp); 264 265 void nbd_export_get(NBDExport *exp); 265 266 void nbd_export_put(NBDExport *exp); 266 267
+13
nbd/server.c
··· 1177 1177 nbd_export_put(exp); 1178 1178 } 1179 1179 1180 + void nbd_export_remove(NBDExport *exp, NbdServerRemoveMode mode, Error **errp) 1181 + { 1182 + if (mode == NBD_SERVER_REMOVE_MODE_HARD || QTAILQ_EMPTY(&exp->clients)) { 1183 + nbd_export_close(exp); 1184 + return; 1185 + } 1186 + 1187 + assert(mode == NBD_SERVER_REMOVE_MODE_SAFE); 1188 + 1189 + error_setg(errp, "export '%s' still in use", exp->name); 1190 + error_append_hint(errp, "Use mode='hard' to force client disconnect\n"); 1191 + } 1192 + 1180 1193 void nbd_export_get(NBDExport *exp) 1181 1194 { 1182 1195 assert(exp->refcount > 0);
+41
qapi/block.json
··· 228 228 'data': {'device': 'str', '*name': 'str', '*writable': 'bool'} } 229 229 230 230 ## 231 + # @NbdServerRemoveMode: 232 + # 233 + # Mode for removing an NBD export. 234 + # 235 + # @safe: Remove export if there are no existing connections, fail otherwise. 236 + # 237 + # @hard: Drop all connections immediately and remove export. 238 + # 239 + # Potential additional modes to be added in the future: 240 + # 241 + # hide: Just hide export from new clients, leave existing connections as is. 242 + # Remove export after all clients are disconnected. 243 + # 244 + # soft: Hide export from new clients, answer with ESHUTDOWN for all further 245 + # requests from existing clients. 246 + # 247 + # Since: 2.12 248 + ## 249 + {'enum': 'NbdServerRemoveMode', 'data': ['safe', 'hard']} 250 + 251 + ## 252 + # @nbd-server-remove: 253 + # 254 + # Remove NBD export by name. 255 + # 256 + # @name: Export name. 257 + # 258 + # @mode: Mode of command operation. See @NbdServerRemoveMode description. 259 + # Default is 'safe'. 260 + # 261 + # Returns: error if 262 + # - the server is not running 263 + # - export is not found 264 + # - mode is 'safe' and there are existing connections 265 + # 266 + # Since: 2.12 267 + ## 268 + { 'command': 'nbd-server-remove', 269 + 'data': {'name': 'str', '*mode': 'NbdServerRemoveMode'} } 270 + 271 + ## 231 272 # @nbd-server-stop: 232 273 # 233 274 # Stop QEMU's embedded NBD server, and unregister all devices previously