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; 61331170e0SKevin Wolf BlockExport *exp = NULL; 62331170e0SKevin Wolf BlockDriverState *bs; 63331170e0SKevin Wolf BlockBackend *blk; 64331170e0SKevin Wolf AioContext *ctx; 65*30dbc81dSKevin Wolf uint64_t perm; 66a6ff7989SKevin Wolf int ret; 6756ee8626SKevin Wolf 68d53be9ceSKevin Wolf if (!id_wellformed(export->id)) { 69d53be9ceSKevin Wolf error_setg(errp, "Invalid block export id"); 70d53be9ceSKevin Wolf return NULL; 71d53be9ceSKevin Wolf } 72d53be9ceSKevin Wolf if (blk_exp_find(export->id)) { 73d53be9ceSKevin Wolf error_setg(errp, "Block export id '%s' is already in use", export->id); 74d53be9ceSKevin Wolf return NULL; 75d53be9ceSKevin Wolf } 76d53be9ceSKevin Wolf 7756ee8626SKevin Wolf drv = blk_exp_find_driver(export->type); 7856ee8626SKevin Wolf if (!drv) { 7956ee8626SKevin Wolf error_setg(errp, "No driver found for the requested export type"); 809b562c64SKevin Wolf return NULL; 8156ee8626SKevin Wolf } 8256ee8626SKevin Wolf 83331170e0SKevin Wolf bs = bdrv_lookup_bs(NULL, export->node_name, errp); 84331170e0SKevin Wolf if (!bs) { 85331170e0SKevin Wolf return NULL; 86331170e0SKevin Wolf } 87331170e0SKevin Wolf 88*30dbc81dSKevin Wolf if (!export->has_writable) { 89*30dbc81dSKevin Wolf export->writable = false; 90*30dbc81dSKevin Wolf } 91*30dbc81dSKevin Wolf if (bdrv_is_read_only(bs) && export->writable) { 92*30dbc81dSKevin Wolf error_setg(errp, "Cannot export read-only node as writable"); 93*30dbc81dSKevin Wolf return NULL; 94*30dbc81dSKevin Wolf } 95*30dbc81dSKevin Wolf 96331170e0SKevin Wolf ctx = bdrv_get_aio_context(bs); 97331170e0SKevin Wolf aio_context_acquire(ctx); 98331170e0SKevin Wolf 99331170e0SKevin Wolf /* 100331170e0SKevin Wolf * Block exports are used for non-shared storage migration. Make sure 101331170e0SKevin Wolf * that BDRV_O_INACTIVE is cleared and the image is ready for write 102331170e0SKevin Wolf * access since the export could be available before migration handover. 103331170e0SKevin Wolf * ctx was acquired in the caller. 104331170e0SKevin Wolf */ 105331170e0SKevin Wolf bdrv_invalidate_cache(bs, NULL); 106331170e0SKevin Wolf 107*30dbc81dSKevin Wolf perm = BLK_PERM_CONSISTENT_READ; 108*30dbc81dSKevin Wolf if (export->writable) { 109*30dbc81dSKevin Wolf perm |= BLK_PERM_WRITE; 110*30dbc81dSKevin Wolf } 111*30dbc81dSKevin Wolf 112*30dbc81dSKevin Wolf blk = blk_new(ctx, perm, BLK_PERM_ALL); 113331170e0SKevin Wolf ret = blk_insert_bs(blk, bs, errp); 114331170e0SKevin Wolf if (ret < 0) { 115331170e0SKevin Wolf goto fail; 116331170e0SKevin Wolf } 117331170e0SKevin Wolf 118331170e0SKevin Wolf if (!export->has_writethrough) { 119331170e0SKevin Wolf export->writethrough = false; 120331170e0SKevin Wolf } 121331170e0SKevin Wolf blk_set_enable_write_cache(blk, !export->writethrough); 122331170e0SKevin Wolf 123a6ff7989SKevin Wolf assert(drv->instance_size >= sizeof(BlockExport)); 124a6ff7989SKevin Wolf exp = g_malloc0(drv->instance_size); 125a6ff7989SKevin Wolf *exp = (BlockExport) { 126a6ff7989SKevin Wolf .drv = drv, 127a6ff7989SKevin Wolf .refcount = 1, 1283859ad36SKevin Wolf .user_owned = true, 129d53be9ceSKevin Wolf .id = g_strdup(export->id), 130331170e0SKevin Wolf .ctx = ctx, 131331170e0SKevin Wolf .blk = blk, 132a6ff7989SKevin Wolf }; 133a6ff7989SKevin Wolf 134a6ff7989SKevin Wolf ret = drv->create(exp, export, errp); 135a6ff7989SKevin Wolf if (ret < 0) { 136331170e0SKevin Wolf goto fail; 137a6ff7989SKevin Wolf } 138a6ff7989SKevin Wolf 13937a4f70cSKevin Wolf assert(exp->blk != NULL); 14037a4f70cSKevin Wolf 141bc4ee65bSKevin Wolf QLIST_INSERT_HEAD(&block_exports, exp, next); 142331170e0SKevin Wolf 143331170e0SKevin Wolf aio_context_release(ctx); 144a6ff7989SKevin Wolf return exp; 145331170e0SKevin Wolf 146331170e0SKevin Wolf fail: 147331170e0SKevin Wolf blk_unref(blk); 148331170e0SKevin Wolf aio_context_release(ctx); 149331170e0SKevin Wolf if (exp) { 150331170e0SKevin Wolf g_free(exp->id); 151331170e0SKevin Wolf g_free(exp); 152331170e0SKevin Wolf } 153331170e0SKevin Wolf return NULL; 1549b562c64SKevin Wolf } 1559b562c64SKevin Wolf 1568612c686SKevin Wolf /* Callers must hold exp->ctx lock */ 157c69de1beSKevin Wolf void blk_exp_ref(BlockExport *exp) 158c69de1beSKevin Wolf { 159c69de1beSKevin Wolf assert(exp->refcount > 0); 160c69de1beSKevin Wolf exp->refcount++; 161c69de1beSKevin Wolf } 162c69de1beSKevin Wolf 163bc4ee65bSKevin Wolf /* Runs in the main thread */ 164bc4ee65bSKevin Wolf static void blk_exp_delete_bh(void *opaque) 165bc4ee65bSKevin Wolf { 166bc4ee65bSKevin Wolf BlockExport *exp = opaque; 167bc4ee65bSKevin Wolf AioContext *aio_context = exp->ctx; 168bc4ee65bSKevin Wolf 169bc4ee65bSKevin Wolf aio_context_acquire(aio_context); 170bc4ee65bSKevin Wolf 171bc4ee65bSKevin Wolf assert(exp->refcount == 0); 172bc4ee65bSKevin Wolf QLIST_REMOVE(exp, next); 173bc4ee65bSKevin Wolf exp->drv->delete(exp); 17437a4f70cSKevin Wolf blk_unref(exp->blk); 1751a9f7a80SKevin Wolf qapi_event_send_block_export_deleted(exp->id); 176d53be9ceSKevin Wolf g_free(exp->id); 177bc4ee65bSKevin Wolf g_free(exp); 178bc4ee65bSKevin Wolf 179bc4ee65bSKevin Wolf aio_context_release(aio_context); 180bc4ee65bSKevin Wolf } 181bc4ee65bSKevin Wolf 1828612c686SKevin Wolf /* Callers must hold exp->ctx lock */ 183c69de1beSKevin Wolf void blk_exp_unref(BlockExport *exp) 184c69de1beSKevin Wolf { 185c69de1beSKevin Wolf assert(exp->refcount > 0); 186c69de1beSKevin Wolf if (--exp->refcount == 0) { 187bc4ee65bSKevin Wolf /* Touch the block_exports list only in the main thread */ 188bc4ee65bSKevin Wolf aio_bh_schedule_oneshot(qemu_get_aio_context(), blk_exp_delete_bh, 189bc4ee65bSKevin Wolf exp); 190c69de1beSKevin Wolf } 191c69de1beSKevin Wolf } 192c69de1beSKevin Wolf 193bc4ee65bSKevin Wolf /* 194bc4ee65bSKevin Wolf * Drops the user reference to the export and requests that all client 195bc4ee65bSKevin Wolf * connections and other internally held references start to shut down. When 196bc4ee65bSKevin Wolf * the function returns, there may still be active references while the export 197bc4ee65bSKevin Wolf * is in the process of shutting down. 198bc4ee65bSKevin Wolf * 199bc4ee65bSKevin Wolf * Acquires exp->ctx internally. Callers must *not* hold the lock. 200bc4ee65bSKevin Wolf */ 201bc4ee65bSKevin Wolf void blk_exp_request_shutdown(BlockExport *exp) 202bc4ee65bSKevin Wolf { 203bc4ee65bSKevin Wolf AioContext *aio_context = exp->ctx; 204bc4ee65bSKevin Wolf 205bc4ee65bSKevin Wolf aio_context_acquire(aio_context); 2063c3bc462SKevin Wolf 2073c3bc462SKevin Wolf /* 2083c3bc462SKevin Wolf * If the user doesn't own the export any more, it is already shutting 2093c3bc462SKevin Wolf * down. We must not call .request_shutdown and decrease the refcount a 2103c3bc462SKevin Wolf * second time. 2113c3bc462SKevin Wolf */ 2123c3bc462SKevin Wolf if (!exp->user_owned) { 2133c3bc462SKevin Wolf goto out; 2143c3bc462SKevin Wolf } 2153c3bc462SKevin Wolf 216bc4ee65bSKevin Wolf exp->drv->request_shutdown(exp); 2173859ad36SKevin Wolf 2183859ad36SKevin Wolf assert(exp->user_owned); 2193859ad36SKevin Wolf exp->user_owned = false; 2203859ad36SKevin Wolf blk_exp_unref(exp); 2213859ad36SKevin Wolf 2223c3bc462SKevin Wolf out: 223bc4ee65bSKevin Wolf aio_context_release(aio_context); 224bc4ee65bSKevin Wolf } 225bc4ee65bSKevin Wolf 226bc4ee65bSKevin Wolf /* 227bc4ee65bSKevin Wolf * Returns whether a block export of the given type exists. 228bc4ee65bSKevin Wolf * type == BLOCK_EXPORT_TYPE__MAX checks for an export of any type. 229bc4ee65bSKevin Wolf */ 230bc4ee65bSKevin Wolf static bool blk_exp_has_type(BlockExportType type) 231bc4ee65bSKevin Wolf { 232bc4ee65bSKevin Wolf BlockExport *exp; 233bc4ee65bSKevin Wolf 234bc4ee65bSKevin Wolf if (type == BLOCK_EXPORT_TYPE__MAX) { 235bc4ee65bSKevin Wolf return !QLIST_EMPTY(&block_exports); 236bc4ee65bSKevin Wolf } 237bc4ee65bSKevin Wolf 238bc4ee65bSKevin Wolf QLIST_FOREACH(exp, &block_exports, next) { 239bc4ee65bSKevin Wolf if (exp->drv->type == type) { 240bc4ee65bSKevin Wolf return true; 241bc4ee65bSKevin Wolf } 242bc4ee65bSKevin Wolf } 243bc4ee65bSKevin Wolf 244bc4ee65bSKevin Wolf return false; 245bc4ee65bSKevin Wolf } 246bc4ee65bSKevin Wolf 247bc4ee65bSKevin Wolf /* type == BLOCK_EXPORT_TYPE__MAX for all types */ 248bc4ee65bSKevin Wolf void blk_exp_close_all_type(BlockExportType type) 249bc4ee65bSKevin Wolf { 250bc4ee65bSKevin Wolf BlockExport *exp, *next; 251bc4ee65bSKevin Wolf 252bc4ee65bSKevin Wolf assert(in_aio_context_home_thread(qemu_get_aio_context())); 253bc4ee65bSKevin Wolf 254bc4ee65bSKevin Wolf QLIST_FOREACH_SAFE(exp, &block_exports, next, next) { 255bc4ee65bSKevin Wolf if (type != BLOCK_EXPORT_TYPE__MAX && exp->drv->type != type) { 256bc4ee65bSKevin Wolf continue; 257bc4ee65bSKevin Wolf } 258bc4ee65bSKevin Wolf blk_exp_request_shutdown(exp); 259bc4ee65bSKevin Wolf } 260bc4ee65bSKevin Wolf 261bc4ee65bSKevin Wolf AIO_WAIT_WHILE(NULL, blk_exp_has_type(type)); 262bc4ee65bSKevin Wolf } 263bc4ee65bSKevin Wolf 264bc4ee65bSKevin Wolf void blk_exp_close_all(void) 265bc4ee65bSKevin Wolf { 266bc4ee65bSKevin Wolf blk_exp_close_all_type(BLOCK_EXPORT_TYPE__MAX); 267bc4ee65bSKevin Wolf } 268bc4ee65bSKevin Wolf 2699b562c64SKevin Wolf void qmp_block_export_add(BlockExportOptions *export, Error **errp) 2709b562c64SKevin Wolf { 2719b562c64SKevin Wolf blk_exp_add(export, errp); 27256ee8626SKevin Wolf } 2733c3bc462SKevin Wolf 2743c3bc462SKevin Wolf void qmp_block_export_del(const char *id, 2753c3bc462SKevin Wolf bool has_mode, BlockExportRemoveMode mode, 2763c3bc462SKevin Wolf Error **errp) 2773c3bc462SKevin Wolf { 2783c3bc462SKevin Wolf ERRP_GUARD(); 2793c3bc462SKevin Wolf BlockExport *exp; 2803c3bc462SKevin Wolf 2813c3bc462SKevin Wolf exp = blk_exp_find(id); 2823c3bc462SKevin Wolf if (exp == NULL) { 2833c3bc462SKevin Wolf error_setg(errp, "Export '%s' is not found", id); 2843c3bc462SKevin Wolf return; 2853c3bc462SKevin Wolf } 2863c3bc462SKevin Wolf if (!exp->user_owned) { 2873c3bc462SKevin Wolf error_setg(errp, "Export '%s' is already shutting down", id); 2883c3bc462SKevin Wolf return; 2893c3bc462SKevin Wolf } 2903c3bc462SKevin Wolf 2913c3bc462SKevin Wolf if (!has_mode) { 2923c3bc462SKevin Wolf mode = BLOCK_EXPORT_REMOVE_MODE_SAFE; 2933c3bc462SKevin Wolf } 2943c3bc462SKevin Wolf if (mode == BLOCK_EXPORT_REMOVE_MODE_SAFE && exp->refcount > 1) { 2953c3bc462SKevin Wolf error_setg(errp, "export '%s' still in use", exp->id); 2963c3bc462SKevin Wolf error_append_hint(errp, "Use mode='hard' to force client " 2973c3bc462SKevin Wolf "disconnect\n"); 2983c3bc462SKevin Wolf return; 2993c3bc462SKevin Wolf } 3003c3bc462SKevin Wolf 3013c3bc462SKevin Wolf blk_exp_request_shutdown(exp); 3023c3bc462SKevin Wolf } 3038cade320SKevin Wolf 3048cade320SKevin Wolf BlockExportInfoList *qmp_query_block_exports(Error **errp) 3058cade320SKevin Wolf { 3068cade320SKevin Wolf BlockExportInfoList *head = NULL, **p_next = &head; 3078cade320SKevin Wolf BlockExport *exp; 3088cade320SKevin Wolf 3098cade320SKevin Wolf QLIST_FOREACH(exp, &block_exports, next) { 3108cade320SKevin Wolf BlockExportInfoList *entry = g_new0(BlockExportInfoList, 1); 3118cade320SKevin Wolf BlockExportInfo *info = g_new(BlockExportInfo, 1); 3128cade320SKevin Wolf *info = (BlockExportInfo) { 3138cade320SKevin Wolf .id = g_strdup(exp->id), 3148cade320SKevin Wolf .type = exp->drv->type, 3158cade320SKevin Wolf .node_name = g_strdup(bdrv_get_node_name(blk_bs(exp->blk))), 3168cade320SKevin Wolf .shutting_down = !exp->user_owned, 3178cade320SKevin Wolf }; 3188cade320SKevin Wolf 3198cade320SKevin Wolf entry->value = info; 3208cade320SKevin Wolf *p_next = entry; 3218cade320SKevin Wolf p_next = &entry->next; 3228cade320SKevin Wolf } 3238cade320SKevin Wolf 3248cade320SKevin Wolf return head; 3258cade320SKevin Wolf } 326