qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

export.c (9255B)


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