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