xref: /openbmc/qemu/block/export/export.c (revision a6ff7989662d659aed0888670e77e68cb8c9bd81)
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"
2256ee8626SKevin Wolf 
2356ee8626SKevin Wolf static const BlockExportDriver *blk_exp_drivers[] = {
2456ee8626SKevin Wolf     &blk_exp_nbd,
2556ee8626SKevin Wolf };
2656ee8626SKevin Wolf 
2756ee8626SKevin Wolf static const BlockExportDriver *blk_exp_find_driver(BlockExportType type)
2856ee8626SKevin Wolf {
2956ee8626SKevin Wolf     int i;
3056ee8626SKevin Wolf 
3156ee8626SKevin Wolf     for (i = 0; i < ARRAY_SIZE(blk_exp_drivers); i++) {
3256ee8626SKevin Wolf         if (blk_exp_drivers[i]->type == type) {
3356ee8626SKevin Wolf             return blk_exp_drivers[i];
3456ee8626SKevin Wolf         }
3556ee8626SKevin Wolf     }
3656ee8626SKevin Wolf     return NULL;
3756ee8626SKevin Wolf }
3856ee8626SKevin Wolf 
399b562c64SKevin Wolf BlockExport *blk_exp_add(BlockExportOptions *export, Error **errp)
4056ee8626SKevin Wolf {
4156ee8626SKevin Wolf     const BlockExportDriver *drv;
42*a6ff7989SKevin Wolf     BlockExport *exp;
43*a6ff7989SKevin Wolf     int ret;
4456ee8626SKevin Wolf 
4556ee8626SKevin Wolf     drv = blk_exp_find_driver(export->type);
4656ee8626SKevin Wolf     if (!drv) {
4756ee8626SKevin Wolf         error_setg(errp, "No driver found for the requested export type");
489b562c64SKevin Wolf         return NULL;
4956ee8626SKevin Wolf     }
5056ee8626SKevin Wolf 
51*a6ff7989SKevin Wolf     assert(drv->instance_size >= sizeof(BlockExport));
52*a6ff7989SKevin Wolf     exp = g_malloc0(drv->instance_size);
53*a6ff7989SKevin Wolf     *exp = (BlockExport) {
54*a6ff7989SKevin Wolf         .drv        = drv,
55*a6ff7989SKevin Wolf         .refcount   = 1,
56*a6ff7989SKevin Wolf     };
57*a6ff7989SKevin Wolf 
58*a6ff7989SKevin Wolf     ret = drv->create(exp, export, errp);
59*a6ff7989SKevin Wolf     if (ret < 0) {
60*a6ff7989SKevin Wolf         g_free(exp);
61*a6ff7989SKevin Wolf         return NULL;
62*a6ff7989SKevin Wolf     }
63*a6ff7989SKevin Wolf 
64*a6ff7989SKevin Wolf     return exp;
659b562c64SKevin Wolf }
669b562c64SKevin Wolf 
678612c686SKevin Wolf /* Callers must hold exp->ctx lock */
68c69de1beSKevin Wolf void blk_exp_ref(BlockExport *exp)
69c69de1beSKevin Wolf {
70c69de1beSKevin Wolf     assert(exp->refcount > 0);
71c69de1beSKevin Wolf     exp->refcount++;
72c69de1beSKevin Wolf }
73c69de1beSKevin Wolf 
748612c686SKevin Wolf /* Callers must hold exp->ctx lock */
75c69de1beSKevin Wolf void blk_exp_unref(BlockExport *exp)
76c69de1beSKevin Wolf {
77c69de1beSKevin Wolf     assert(exp->refcount > 0);
78c69de1beSKevin Wolf     if (--exp->refcount == 0) {
79c69de1beSKevin Wolf         exp->drv->delete(exp);
80*a6ff7989SKevin Wolf         g_free(exp);
81c69de1beSKevin Wolf     }
82c69de1beSKevin Wolf }
83c69de1beSKevin Wolf 
849b562c64SKevin Wolf void qmp_block_export_add(BlockExportOptions *export, Error **errp)
859b562c64SKevin Wolf {
869b562c64SKevin Wolf     blk_exp_add(export, errp);
8756ee8626SKevin Wolf }
88