156ee8626SKevin Wolf /* 256ee8626SKevin Wolf * Common block export infrastructure 356ee8626SKevin Wolf * 456ee8626SKevin Wolf * Copyright (c) 2012, 2020 Red Hat, Inc. 556ee8626SKevin Wolf * 656ee8626SKevin Wolf * Authors: 756ee8626SKevin Wolf * Paolo Bonzini <pbonzini@redhat.com> 856ee8626SKevin Wolf * Kevin Wolf <kwolf@redhat.com> 956ee8626SKevin Wolf * 1056ee8626SKevin Wolf * This work is licensed under the terms of the GNU GPL, version 2 or 1156ee8626SKevin Wolf * later. See the COPYING file in the top-level directory. 1256ee8626SKevin Wolf */ 1356ee8626SKevin Wolf 1456ee8626SKevin Wolf #include "qemu/osdep.h" 1556ee8626SKevin Wolf 169b562c64SKevin Wolf #include "block/block.h" 179b562c64SKevin Wolf #include "sysemu/block-backend.h" 1856ee8626SKevin Wolf #include "block/export.h" 1956ee8626SKevin Wolf #include "block/nbd.h" 2056ee8626SKevin Wolf #include "qapi/error.h" 2156ee8626SKevin Wolf #include "qapi/qapi-commands-block-export.h" 221a9f7a80SKevin Wolf #include "qapi/qapi-events-block-export.h" 23d53be9ceSKevin Wolf #include "qemu/id.h" 2456ee8626SKevin Wolf 2556ee8626SKevin Wolf static const BlockExportDriver *blk_exp_drivers[] = { 2656ee8626SKevin Wolf &blk_exp_nbd, 2756ee8626SKevin Wolf }; 2856ee8626SKevin Wolf 29bc4ee65bSKevin Wolf /* Only accessed from the main thread */ 30bc4ee65bSKevin Wolf static QLIST_HEAD(, BlockExport) block_exports = 31bc4ee65bSKevin Wolf QLIST_HEAD_INITIALIZER(block_exports); 32bc4ee65bSKevin Wolf 333c3bc462SKevin Wolf BlockExport *blk_exp_find(const char *id) 34d53be9ceSKevin Wolf { 35d53be9ceSKevin Wolf BlockExport *exp; 36d53be9ceSKevin Wolf 37d53be9ceSKevin Wolf QLIST_FOREACH(exp, &block_exports, next) { 38d53be9ceSKevin Wolf if (strcmp(id, exp->id) == 0) { 39d53be9ceSKevin Wolf return exp; 40d53be9ceSKevin Wolf } 41d53be9ceSKevin Wolf } 42d53be9ceSKevin Wolf 43d53be9ceSKevin Wolf return NULL; 44d53be9ceSKevin Wolf } 45d53be9ceSKevin Wolf 4656ee8626SKevin Wolf static const BlockExportDriver *blk_exp_find_driver(BlockExportType type) 4756ee8626SKevin Wolf { 4856ee8626SKevin Wolf int i; 4956ee8626SKevin Wolf 5056ee8626SKevin Wolf for (i = 0; i < ARRAY_SIZE(blk_exp_drivers); i++) { 5156ee8626SKevin Wolf if (blk_exp_drivers[i]->type == type) { 5256ee8626SKevin Wolf return blk_exp_drivers[i]; 5356ee8626SKevin Wolf } 5456ee8626SKevin Wolf } 5556ee8626SKevin Wolf return NULL; 5656ee8626SKevin Wolf } 5756ee8626SKevin Wolf 589b562c64SKevin Wolf BlockExport *blk_exp_add(BlockExportOptions *export, Error **errp) 5956ee8626SKevin Wolf { 6056ee8626SKevin Wolf const BlockExportDriver *drv; 61*331170e0SKevin Wolf BlockExport *exp = NULL; 62*331170e0SKevin Wolf BlockDriverState *bs; 63*331170e0SKevin Wolf BlockBackend *blk; 64*331170e0SKevin Wolf AioContext *ctx; 65a6ff7989SKevin Wolf int ret; 6656ee8626SKevin Wolf 67d53be9ceSKevin Wolf if (!id_wellformed(export->id)) { 68d53be9ceSKevin Wolf error_setg(errp, "Invalid block export id"); 69d53be9ceSKevin Wolf return NULL; 70d53be9ceSKevin Wolf } 71d53be9ceSKevin Wolf if (blk_exp_find(export->id)) { 72d53be9ceSKevin Wolf error_setg(errp, "Block export id '%s' is already in use", export->id); 73d53be9ceSKevin Wolf return NULL; 74d53be9ceSKevin Wolf } 75d53be9ceSKevin Wolf 7656ee8626SKevin Wolf drv = blk_exp_find_driver(export->type); 7756ee8626SKevin Wolf if (!drv) { 7856ee8626SKevin Wolf error_setg(errp, "No driver found for the requested export type"); 799b562c64SKevin Wolf return NULL; 8056ee8626SKevin Wolf } 8156ee8626SKevin Wolf 82*331170e0SKevin Wolf bs = bdrv_lookup_bs(NULL, export->node_name, errp); 83*331170e0SKevin Wolf if (!bs) { 84*331170e0SKevin Wolf return NULL; 85*331170e0SKevin Wolf } 86*331170e0SKevin Wolf 87*331170e0SKevin Wolf ctx = bdrv_get_aio_context(bs); 88*331170e0SKevin Wolf aio_context_acquire(ctx); 89*331170e0SKevin Wolf 90*331170e0SKevin Wolf /* 91*331170e0SKevin Wolf * Block exports are used for non-shared storage migration. Make sure 92*331170e0SKevin Wolf * that BDRV_O_INACTIVE is cleared and the image is ready for write 93*331170e0SKevin Wolf * access since the export could be available before migration handover. 94*331170e0SKevin Wolf * ctx was acquired in the caller. 95*331170e0SKevin Wolf */ 96*331170e0SKevin Wolf bdrv_invalidate_cache(bs, NULL); 97*331170e0SKevin Wolf 98*331170e0SKevin Wolf blk = blk_new(ctx, BLK_PERM_CONSISTENT_READ, BLK_PERM_ALL); 99*331170e0SKevin Wolf ret = blk_insert_bs(blk, bs, errp); 100*331170e0SKevin Wolf if (ret < 0) { 101*331170e0SKevin Wolf goto fail; 102*331170e0SKevin Wolf } 103*331170e0SKevin Wolf 104*331170e0SKevin Wolf if (!export->has_writethrough) { 105*331170e0SKevin Wolf export->writethrough = false; 106*331170e0SKevin Wolf } 107*331170e0SKevin Wolf blk_set_enable_write_cache(blk, !export->writethrough); 108*331170e0SKevin Wolf 109a6ff7989SKevin Wolf assert(drv->instance_size >= sizeof(BlockExport)); 110a6ff7989SKevin Wolf exp = g_malloc0(drv->instance_size); 111a6ff7989SKevin Wolf *exp = (BlockExport) { 112a6ff7989SKevin Wolf .drv = drv, 113a6ff7989SKevin Wolf .refcount = 1, 1143859ad36SKevin Wolf .user_owned = true, 115d53be9ceSKevin Wolf .id = g_strdup(export->id), 116*331170e0SKevin Wolf .ctx = ctx, 117*331170e0SKevin Wolf .blk = blk, 118a6ff7989SKevin Wolf }; 119a6ff7989SKevin Wolf 120a6ff7989SKevin Wolf ret = drv->create(exp, export, errp); 121a6ff7989SKevin Wolf if (ret < 0) { 122*331170e0SKevin Wolf goto fail; 123a6ff7989SKevin Wolf } 124a6ff7989SKevin Wolf 12537a4f70cSKevin Wolf assert(exp->blk != NULL); 12637a4f70cSKevin Wolf 127bc4ee65bSKevin Wolf QLIST_INSERT_HEAD(&block_exports, exp, next); 128*331170e0SKevin Wolf 129*331170e0SKevin Wolf aio_context_release(ctx); 130a6ff7989SKevin Wolf return exp; 131*331170e0SKevin Wolf 132*331170e0SKevin Wolf fail: 133*331170e0SKevin Wolf blk_unref(blk); 134*331170e0SKevin Wolf aio_context_release(ctx); 135*331170e0SKevin Wolf if (exp) { 136*331170e0SKevin Wolf g_free(exp->id); 137*331170e0SKevin Wolf g_free(exp); 138*331170e0SKevin Wolf } 139*331170e0SKevin Wolf return NULL; 1409b562c64SKevin Wolf } 1419b562c64SKevin Wolf 1428612c686SKevin Wolf /* Callers must hold exp->ctx lock */ 143c69de1beSKevin Wolf void blk_exp_ref(BlockExport *exp) 144c69de1beSKevin Wolf { 145c69de1beSKevin Wolf assert(exp->refcount > 0); 146c69de1beSKevin Wolf exp->refcount++; 147c69de1beSKevin Wolf } 148c69de1beSKevin Wolf 149bc4ee65bSKevin Wolf /* Runs in the main thread */ 150bc4ee65bSKevin Wolf static void blk_exp_delete_bh(void *opaque) 151bc4ee65bSKevin Wolf { 152bc4ee65bSKevin Wolf BlockExport *exp = opaque; 153bc4ee65bSKevin Wolf AioContext *aio_context = exp->ctx; 154bc4ee65bSKevin Wolf 155bc4ee65bSKevin Wolf aio_context_acquire(aio_context); 156bc4ee65bSKevin Wolf 157bc4ee65bSKevin Wolf assert(exp->refcount == 0); 158bc4ee65bSKevin Wolf QLIST_REMOVE(exp, next); 159bc4ee65bSKevin Wolf exp->drv->delete(exp); 16037a4f70cSKevin Wolf blk_unref(exp->blk); 1611a9f7a80SKevin Wolf qapi_event_send_block_export_deleted(exp->id); 162d53be9ceSKevin Wolf g_free(exp->id); 163bc4ee65bSKevin Wolf g_free(exp); 164bc4ee65bSKevin Wolf 165bc4ee65bSKevin Wolf aio_context_release(aio_context); 166bc4ee65bSKevin Wolf } 167bc4ee65bSKevin Wolf 1688612c686SKevin Wolf /* Callers must hold exp->ctx lock */ 169c69de1beSKevin Wolf void blk_exp_unref(BlockExport *exp) 170c69de1beSKevin Wolf { 171c69de1beSKevin Wolf assert(exp->refcount > 0); 172c69de1beSKevin Wolf if (--exp->refcount == 0) { 173bc4ee65bSKevin Wolf /* Touch the block_exports list only in the main thread */ 174bc4ee65bSKevin Wolf aio_bh_schedule_oneshot(qemu_get_aio_context(), blk_exp_delete_bh, 175bc4ee65bSKevin Wolf exp); 176c69de1beSKevin Wolf } 177c69de1beSKevin Wolf } 178c69de1beSKevin Wolf 179bc4ee65bSKevin Wolf /* 180bc4ee65bSKevin Wolf * Drops the user reference to the export and requests that all client 181bc4ee65bSKevin Wolf * connections and other internally held references start to shut down. When 182bc4ee65bSKevin Wolf * the function returns, there may still be active references while the export 183bc4ee65bSKevin Wolf * is in the process of shutting down. 184bc4ee65bSKevin Wolf * 185bc4ee65bSKevin Wolf * Acquires exp->ctx internally. Callers must *not* hold the lock. 186bc4ee65bSKevin Wolf */ 187bc4ee65bSKevin Wolf void blk_exp_request_shutdown(BlockExport *exp) 188bc4ee65bSKevin Wolf { 189bc4ee65bSKevin Wolf AioContext *aio_context = exp->ctx; 190bc4ee65bSKevin Wolf 191bc4ee65bSKevin Wolf aio_context_acquire(aio_context); 1923c3bc462SKevin Wolf 1933c3bc462SKevin Wolf /* 1943c3bc462SKevin Wolf * If the user doesn't own the export any more, it is already shutting 1953c3bc462SKevin Wolf * down. We must not call .request_shutdown and decrease the refcount a 1963c3bc462SKevin Wolf * second time. 1973c3bc462SKevin Wolf */ 1983c3bc462SKevin Wolf if (!exp->user_owned) { 1993c3bc462SKevin Wolf goto out; 2003c3bc462SKevin Wolf } 2013c3bc462SKevin Wolf 202bc4ee65bSKevin Wolf exp->drv->request_shutdown(exp); 2033859ad36SKevin Wolf 2043859ad36SKevin Wolf assert(exp->user_owned); 2053859ad36SKevin Wolf exp->user_owned = false; 2063859ad36SKevin Wolf blk_exp_unref(exp); 2073859ad36SKevin Wolf 2083c3bc462SKevin Wolf out: 209bc4ee65bSKevin Wolf aio_context_release(aio_context); 210bc4ee65bSKevin Wolf } 211bc4ee65bSKevin Wolf 212bc4ee65bSKevin Wolf /* 213bc4ee65bSKevin Wolf * Returns whether a block export of the given type exists. 214bc4ee65bSKevin Wolf * type == BLOCK_EXPORT_TYPE__MAX checks for an export of any type. 215bc4ee65bSKevin Wolf */ 216bc4ee65bSKevin Wolf static bool blk_exp_has_type(BlockExportType type) 217bc4ee65bSKevin Wolf { 218bc4ee65bSKevin Wolf BlockExport *exp; 219bc4ee65bSKevin Wolf 220bc4ee65bSKevin Wolf if (type == BLOCK_EXPORT_TYPE__MAX) { 221bc4ee65bSKevin Wolf return !QLIST_EMPTY(&block_exports); 222bc4ee65bSKevin Wolf } 223bc4ee65bSKevin Wolf 224bc4ee65bSKevin Wolf QLIST_FOREACH(exp, &block_exports, next) { 225bc4ee65bSKevin Wolf if (exp->drv->type == type) { 226bc4ee65bSKevin Wolf return true; 227bc4ee65bSKevin Wolf } 228bc4ee65bSKevin Wolf } 229bc4ee65bSKevin Wolf 230bc4ee65bSKevin Wolf return false; 231bc4ee65bSKevin Wolf } 232bc4ee65bSKevin Wolf 233bc4ee65bSKevin Wolf /* type == BLOCK_EXPORT_TYPE__MAX for all types */ 234bc4ee65bSKevin Wolf void blk_exp_close_all_type(BlockExportType type) 235bc4ee65bSKevin Wolf { 236bc4ee65bSKevin Wolf BlockExport *exp, *next; 237bc4ee65bSKevin Wolf 238bc4ee65bSKevin Wolf assert(in_aio_context_home_thread(qemu_get_aio_context())); 239bc4ee65bSKevin Wolf 240bc4ee65bSKevin Wolf QLIST_FOREACH_SAFE(exp, &block_exports, next, next) { 241bc4ee65bSKevin Wolf if (type != BLOCK_EXPORT_TYPE__MAX && exp->drv->type != type) { 242bc4ee65bSKevin Wolf continue; 243bc4ee65bSKevin Wolf } 244bc4ee65bSKevin Wolf blk_exp_request_shutdown(exp); 245bc4ee65bSKevin Wolf } 246bc4ee65bSKevin Wolf 247bc4ee65bSKevin Wolf AIO_WAIT_WHILE(NULL, blk_exp_has_type(type)); 248bc4ee65bSKevin Wolf } 249bc4ee65bSKevin Wolf 250bc4ee65bSKevin Wolf void blk_exp_close_all(void) 251bc4ee65bSKevin Wolf { 252bc4ee65bSKevin Wolf blk_exp_close_all_type(BLOCK_EXPORT_TYPE__MAX); 253bc4ee65bSKevin Wolf } 254bc4ee65bSKevin Wolf 2559b562c64SKevin Wolf void qmp_block_export_add(BlockExportOptions *export, Error **errp) 2569b562c64SKevin Wolf { 2579b562c64SKevin Wolf blk_exp_add(export, errp); 25856ee8626SKevin Wolf } 2593c3bc462SKevin Wolf 2603c3bc462SKevin Wolf void qmp_block_export_del(const char *id, 2613c3bc462SKevin Wolf bool has_mode, BlockExportRemoveMode mode, 2623c3bc462SKevin Wolf Error **errp) 2633c3bc462SKevin Wolf { 2643c3bc462SKevin Wolf ERRP_GUARD(); 2653c3bc462SKevin Wolf BlockExport *exp; 2663c3bc462SKevin Wolf 2673c3bc462SKevin Wolf exp = blk_exp_find(id); 2683c3bc462SKevin Wolf if (exp == NULL) { 2693c3bc462SKevin Wolf error_setg(errp, "Export '%s' is not found", id); 2703c3bc462SKevin Wolf return; 2713c3bc462SKevin Wolf } 2723c3bc462SKevin Wolf if (!exp->user_owned) { 2733c3bc462SKevin Wolf error_setg(errp, "Export '%s' is already shutting down", id); 2743c3bc462SKevin Wolf return; 2753c3bc462SKevin Wolf } 2763c3bc462SKevin Wolf 2773c3bc462SKevin Wolf if (!has_mode) { 2783c3bc462SKevin Wolf mode = BLOCK_EXPORT_REMOVE_MODE_SAFE; 2793c3bc462SKevin Wolf } 2803c3bc462SKevin Wolf if (mode == BLOCK_EXPORT_REMOVE_MODE_SAFE && exp->refcount > 1) { 2813c3bc462SKevin Wolf error_setg(errp, "export '%s' still in use", exp->id); 2823c3bc462SKevin Wolf error_append_hint(errp, "Use mode='hard' to force client " 2833c3bc462SKevin Wolf "disconnect\n"); 2843c3bc462SKevin Wolf return; 2853c3bc462SKevin Wolf } 2863c3bc462SKevin Wolf 2873c3bc462SKevin Wolf blk_exp_request_shutdown(exp); 2883c3bc462SKevin Wolf } 289