1 /* 2 * Common block export infrastructure 3 * 4 * Copyright (c) 2012, 2020 Red Hat, Inc. 5 * 6 * Authors: 7 * Paolo Bonzini <pbonzini@redhat.com> 8 * Kevin Wolf <kwolf@redhat.com> 9 * 10 * This work is licensed under the terms of the GNU GPL, version 2 or 11 * later. See the COPYING file in the top-level directory. 12 */ 13 14 #include "qemu/osdep.h" 15 16 #include "block/block.h" 17 #include "sysemu/block-backend.h" 18 #include "sysemu/iothread.h" 19 #include "block/export.h" 20 #include "block/nbd.h" 21 #include "qapi/error.h" 22 #include "qapi/qapi-commands-block-export.h" 23 #include "qapi/qapi-events-block-export.h" 24 #include "qemu/id.h" 25 #if defined(CONFIG_LINUX) && defined(CONFIG_VHOST_USER) 26 #include "vhost-user-blk-server.h" 27 #endif 28 29 static const BlockExportDriver *blk_exp_drivers[] = { 30 &blk_exp_nbd, 31 #if defined(CONFIG_LINUX) && defined(CONFIG_VHOST_USER) 32 &blk_exp_vhost_user_blk, 33 #endif 34 }; 35 36 /* Only accessed from the main thread */ 37 static QLIST_HEAD(, BlockExport) block_exports = 38 QLIST_HEAD_INITIALIZER(block_exports); 39 40 BlockExport *blk_exp_find(const char *id) 41 { 42 BlockExport *exp; 43 44 QLIST_FOREACH(exp, &block_exports, next) { 45 if (strcmp(id, exp->id) == 0) { 46 return exp; 47 } 48 } 49 50 return NULL; 51 } 52 53 static const BlockExportDriver *blk_exp_find_driver(BlockExportType type) 54 { 55 int i; 56 57 for (i = 0; i < ARRAY_SIZE(blk_exp_drivers); i++) { 58 if (blk_exp_drivers[i]->type == type) { 59 return blk_exp_drivers[i]; 60 } 61 } 62 return NULL; 63 } 64 65 BlockExport *blk_exp_add(BlockExportOptions *export, Error **errp) 66 { 67 bool fixed_iothread = export->has_fixed_iothread && export->fixed_iothread; 68 const BlockExportDriver *drv; 69 BlockExport *exp = NULL; 70 BlockDriverState *bs; 71 BlockBackend *blk = NULL; 72 AioContext *ctx; 73 uint64_t perm; 74 int ret; 75 76 if (!id_wellformed(export->id)) { 77 error_setg(errp, "Invalid block export id"); 78 return NULL; 79 } 80 if (blk_exp_find(export->id)) { 81 error_setg(errp, "Block export id '%s' is already in use", export->id); 82 return NULL; 83 } 84 85 drv = blk_exp_find_driver(export->type); 86 if (!drv) { 87 error_setg(errp, "No driver found for the requested export type"); 88 return NULL; 89 } 90 91 bs = bdrv_lookup_bs(NULL, export->node_name, errp); 92 if (!bs) { 93 return NULL; 94 } 95 96 if (!export->has_writable) { 97 export->writable = false; 98 } 99 if (bdrv_is_read_only(bs) && export->writable) { 100 error_setg(errp, "Cannot export read-only node as writable"); 101 return NULL; 102 } 103 104 ctx = bdrv_get_aio_context(bs); 105 aio_context_acquire(ctx); 106 107 if (export->has_iothread) { 108 IOThread *iothread; 109 AioContext *new_ctx; 110 111 iothread = iothread_by_id(export->iothread); 112 if (!iothread) { 113 error_setg(errp, "iothread \"%s\" not found", export->iothread); 114 goto fail; 115 } 116 117 new_ctx = iothread_get_aio_context(iothread); 118 119 ret = bdrv_try_set_aio_context(bs, new_ctx, errp); 120 if (ret == 0) { 121 aio_context_release(ctx); 122 aio_context_acquire(new_ctx); 123 ctx = new_ctx; 124 } else if (fixed_iothread) { 125 goto fail; 126 } 127 } 128 129 /* 130 * Block exports are used for non-shared storage migration. Make sure 131 * that BDRV_O_INACTIVE is cleared and the image is ready for write 132 * access since the export could be available before migration handover. 133 * ctx was acquired in the caller. 134 */ 135 bdrv_invalidate_cache(bs, NULL); 136 137 perm = BLK_PERM_CONSISTENT_READ; 138 if (export->writable) { 139 perm |= BLK_PERM_WRITE; 140 } 141 142 blk = blk_new(ctx, perm, BLK_PERM_ALL); 143 144 if (!fixed_iothread) { 145 blk_set_allow_aio_context_change(blk, true); 146 } 147 148 ret = blk_insert_bs(blk, bs, errp); 149 if (ret < 0) { 150 goto fail; 151 } 152 153 if (!export->has_writethrough) { 154 export->writethrough = false; 155 } 156 blk_set_enable_write_cache(blk, !export->writethrough); 157 158 assert(drv->instance_size >= sizeof(BlockExport)); 159 exp = g_malloc0(drv->instance_size); 160 *exp = (BlockExport) { 161 .drv = drv, 162 .refcount = 1, 163 .user_owned = true, 164 .id = g_strdup(export->id), 165 .ctx = ctx, 166 .blk = blk, 167 }; 168 169 ret = drv->create(exp, export, errp); 170 if (ret < 0) { 171 goto fail; 172 } 173 174 assert(exp->blk != NULL); 175 176 QLIST_INSERT_HEAD(&block_exports, exp, next); 177 178 aio_context_release(ctx); 179 return exp; 180 181 fail: 182 blk_unref(blk); 183 aio_context_release(ctx); 184 if (exp) { 185 g_free(exp->id); 186 g_free(exp); 187 } 188 return NULL; 189 } 190 191 /* Callers must hold exp->ctx lock */ 192 void blk_exp_ref(BlockExport *exp) 193 { 194 assert(exp->refcount > 0); 195 exp->refcount++; 196 } 197 198 /* Runs in the main thread */ 199 static void blk_exp_delete_bh(void *opaque) 200 { 201 BlockExport *exp = opaque; 202 AioContext *aio_context = exp->ctx; 203 204 aio_context_acquire(aio_context); 205 206 assert(exp->refcount == 0); 207 QLIST_REMOVE(exp, next); 208 exp->drv->delete(exp); 209 blk_unref(exp->blk); 210 qapi_event_send_block_export_deleted(exp->id); 211 g_free(exp->id); 212 g_free(exp); 213 214 aio_context_release(aio_context); 215 } 216 217 /* Callers must hold exp->ctx lock */ 218 void blk_exp_unref(BlockExport *exp) 219 { 220 assert(exp->refcount > 0); 221 if (--exp->refcount == 0) { 222 /* Touch the block_exports list only in the main thread */ 223 aio_bh_schedule_oneshot(qemu_get_aio_context(), blk_exp_delete_bh, 224 exp); 225 } 226 } 227 228 /* 229 * Drops the user reference to the export and requests that all client 230 * connections and other internally held references start to shut down. When 231 * the function returns, there may still be active references while the export 232 * is in the process of shutting down. 233 * 234 * Acquires exp->ctx internally. Callers must *not* hold the lock. 235 */ 236 void blk_exp_request_shutdown(BlockExport *exp) 237 { 238 AioContext *aio_context = exp->ctx; 239 240 aio_context_acquire(aio_context); 241 242 /* 243 * If the user doesn't own the export any more, it is already shutting 244 * down. We must not call .request_shutdown and decrease the refcount a 245 * second time. 246 */ 247 if (!exp->user_owned) { 248 goto out; 249 } 250 251 exp->drv->request_shutdown(exp); 252 253 assert(exp->user_owned); 254 exp->user_owned = false; 255 blk_exp_unref(exp); 256 257 out: 258 aio_context_release(aio_context); 259 } 260 261 /* 262 * Returns whether a block export of the given type exists. 263 * type == BLOCK_EXPORT_TYPE__MAX checks for an export of any type. 264 */ 265 static bool blk_exp_has_type(BlockExportType type) 266 { 267 BlockExport *exp; 268 269 if (type == BLOCK_EXPORT_TYPE__MAX) { 270 return !QLIST_EMPTY(&block_exports); 271 } 272 273 QLIST_FOREACH(exp, &block_exports, next) { 274 if (exp->drv->type == type) { 275 return true; 276 } 277 } 278 279 return false; 280 } 281 282 /* type == BLOCK_EXPORT_TYPE__MAX for all types */ 283 void blk_exp_close_all_type(BlockExportType type) 284 { 285 BlockExport *exp, *next; 286 287 assert(in_aio_context_home_thread(qemu_get_aio_context())); 288 289 QLIST_FOREACH_SAFE(exp, &block_exports, next, next) { 290 if (type != BLOCK_EXPORT_TYPE__MAX && exp->drv->type != type) { 291 continue; 292 } 293 blk_exp_request_shutdown(exp); 294 } 295 296 AIO_WAIT_WHILE(NULL, blk_exp_has_type(type)); 297 } 298 299 void blk_exp_close_all(void) 300 { 301 blk_exp_close_all_type(BLOCK_EXPORT_TYPE__MAX); 302 } 303 304 void qmp_block_export_add(BlockExportOptions *export, Error **errp) 305 { 306 blk_exp_add(export, errp); 307 } 308 309 void qmp_block_export_del(const char *id, 310 bool has_mode, BlockExportRemoveMode mode, 311 Error **errp) 312 { 313 ERRP_GUARD(); 314 BlockExport *exp; 315 316 exp = blk_exp_find(id); 317 if (exp == NULL) { 318 error_setg(errp, "Export '%s' is not found", id); 319 return; 320 } 321 if (!exp->user_owned) { 322 error_setg(errp, "Export '%s' is already shutting down", id); 323 return; 324 } 325 326 if (!has_mode) { 327 mode = BLOCK_EXPORT_REMOVE_MODE_SAFE; 328 } 329 if (mode == BLOCK_EXPORT_REMOVE_MODE_SAFE && exp->refcount > 1) { 330 error_setg(errp, "export '%s' still in use", exp->id); 331 error_append_hint(errp, "Use mode='hard' to force client " 332 "disconnect\n"); 333 return; 334 } 335 336 blk_exp_request_shutdown(exp); 337 } 338 339 BlockExportInfoList *qmp_query_block_exports(Error **errp) 340 { 341 BlockExportInfoList *head = NULL, **p_next = &head; 342 BlockExport *exp; 343 344 QLIST_FOREACH(exp, &block_exports, next) { 345 BlockExportInfoList *entry = g_new0(BlockExportInfoList, 1); 346 BlockExportInfo *info = g_new(BlockExportInfo, 1); 347 *info = (BlockExportInfo) { 348 .id = g_strdup(exp->id), 349 .type = exp->drv->type, 350 .node_name = g_strdup(bdrv_get_node_name(blk_bs(exp->blk))), 351 .shutting_down = !exp->user_owned, 352 }; 353 354 entry->value = info; 355 *p_next = entry; 356 p_next = &entry->next; 357 } 358 359 return head; 360 } 361