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