126f54e9aSMarkus Armbruster /* 226f54e9aSMarkus Armbruster * QEMU Block backends 326f54e9aSMarkus Armbruster * 426f54e9aSMarkus Armbruster * Copyright (C) 2014 Red Hat, Inc. 526f54e9aSMarkus Armbruster * 626f54e9aSMarkus Armbruster * Authors: 726f54e9aSMarkus Armbruster * Markus Armbruster <armbru@redhat.com>, 826f54e9aSMarkus Armbruster * 926f54e9aSMarkus Armbruster * This work is licensed under the terms of the GNU LGPL, version 2.1 1026f54e9aSMarkus Armbruster * or later. See the COPYING.LIB file in the top-level directory. 1126f54e9aSMarkus Armbruster */ 1226f54e9aSMarkus Armbruster 1326f54e9aSMarkus Armbruster #include "sysemu/block-backend.h" 1426f54e9aSMarkus Armbruster #include "block/block_int.h" 1518e46a03SMarkus Armbruster #include "sysemu/blockdev.h" 1626f54e9aSMarkus Armbruster 1726f54e9aSMarkus Armbruster struct BlockBackend { 1826f54e9aSMarkus Armbruster char *name; 1926f54e9aSMarkus Armbruster int refcnt; 207e7d56d9SMarkus Armbruster BlockDriverState *bs; 2118e46a03SMarkus Armbruster DriveInfo *legacy_dinfo; 2226f54e9aSMarkus Armbruster QTAILQ_ENTRY(BlockBackend) link; /* for blk_backends */ 2326f54e9aSMarkus Armbruster }; 2426f54e9aSMarkus Armbruster 258fb3c76cSMarkus Armbruster static void drive_info_del(DriveInfo *dinfo); 268fb3c76cSMarkus Armbruster 277e7d56d9SMarkus Armbruster /* All the BlockBackends (except for hidden ones) */ 2826f54e9aSMarkus Armbruster static QTAILQ_HEAD(, BlockBackend) blk_backends = 2926f54e9aSMarkus Armbruster QTAILQ_HEAD_INITIALIZER(blk_backends); 3026f54e9aSMarkus Armbruster 3126f54e9aSMarkus Armbruster /* 3226f54e9aSMarkus Armbruster * Create a new BlockBackend with @name, with a reference count of one. 3326f54e9aSMarkus Armbruster * @name must not be null or empty. 3426f54e9aSMarkus Armbruster * Fail if a BlockBackend with this name already exists. 3526f54e9aSMarkus Armbruster * Store an error through @errp on failure, unless it's null. 3626f54e9aSMarkus Armbruster * Return the new BlockBackend on success, null on failure. 3726f54e9aSMarkus Armbruster */ 3826f54e9aSMarkus Armbruster BlockBackend *blk_new(const char *name, Error **errp) 3926f54e9aSMarkus Armbruster { 4026f54e9aSMarkus Armbruster BlockBackend *blk; 4126f54e9aSMarkus Armbruster 4226f54e9aSMarkus Armbruster assert(name && name[0]); 43*7f06d47eSMarkus Armbruster if (!id_wellformed(name)) { 44*7f06d47eSMarkus Armbruster error_setg(errp, "Invalid device name"); 45*7f06d47eSMarkus Armbruster return NULL; 46*7f06d47eSMarkus Armbruster } 4726f54e9aSMarkus Armbruster if (blk_by_name(name)) { 4826f54e9aSMarkus Armbruster error_setg(errp, "Device with id '%s' already exists", name); 4926f54e9aSMarkus Armbruster return NULL; 5026f54e9aSMarkus Armbruster } 51*7f06d47eSMarkus Armbruster if (bdrv_find_node(name)) { 52*7f06d47eSMarkus Armbruster error_setg(errp, 53*7f06d47eSMarkus Armbruster "Device name '%s' conflicts with an existing node name", 54*7f06d47eSMarkus Armbruster name); 55*7f06d47eSMarkus Armbruster return NULL; 56*7f06d47eSMarkus Armbruster } 5726f54e9aSMarkus Armbruster 5826f54e9aSMarkus Armbruster blk = g_new0(BlockBackend, 1); 5926f54e9aSMarkus Armbruster blk->name = g_strdup(name); 6026f54e9aSMarkus Armbruster blk->refcnt = 1; 6126f54e9aSMarkus Armbruster QTAILQ_INSERT_TAIL(&blk_backends, blk, link); 6226f54e9aSMarkus Armbruster return blk; 6326f54e9aSMarkus Armbruster } 6426f54e9aSMarkus Armbruster 657e7d56d9SMarkus Armbruster /* 667e7d56d9SMarkus Armbruster * Create a new BlockBackend with a new BlockDriverState attached. 677e7d56d9SMarkus Armbruster * Otherwise just like blk_new(), which see. 687e7d56d9SMarkus Armbruster */ 697e7d56d9SMarkus Armbruster BlockBackend *blk_new_with_bs(const char *name, Error **errp) 707e7d56d9SMarkus Armbruster { 717e7d56d9SMarkus Armbruster BlockBackend *blk; 727e7d56d9SMarkus Armbruster BlockDriverState *bs; 737e7d56d9SMarkus Armbruster 747e7d56d9SMarkus Armbruster blk = blk_new(name, errp); 757e7d56d9SMarkus Armbruster if (!blk) { 767e7d56d9SMarkus Armbruster return NULL; 777e7d56d9SMarkus Armbruster } 787e7d56d9SMarkus Armbruster 79*7f06d47eSMarkus Armbruster bs = bdrv_new_root(); 807e7d56d9SMarkus Armbruster blk->bs = bs; 817e7d56d9SMarkus Armbruster bs->blk = blk; 827e7d56d9SMarkus Armbruster return blk; 837e7d56d9SMarkus Armbruster } 847e7d56d9SMarkus Armbruster 8526f54e9aSMarkus Armbruster static void blk_delete(BlockBackend *blk) 8626f54e9aSMarkus Armbruster { 8726f54e9aSMarkus Armbruster assert(!blk->refcnt); 887e7d56d9SMarkus Armbruster if (blk->bs) { 899ba10c95SMarkus Armbruster assert(blk->bs->blk == blk); 907e7d56d9SMarkus Armbruster blk->bs->blk = NULL; 919ba10c95SMarkus Armbruster bdrv_unref(blk->bs); 927e7d56d9SMarkus Armbruster blk->bs = NULL; 937e7d56d9SMarkus Armbruster } 947e7d56d9SMarkus Armbruster /* Avoid double-remove after blk_hide_on_behalf_of_do_drive_del() */ 957e7d56d9SMarkus Armbruster if (blk->name[0]) { 9626f54e9aSMarkus Armbruster QTAILQ_REMOVE(&blk_backends, blk, link); 977e7d56d9SMarkus Armbruster } 9826f54e9aSMarkus Armbruster g_free(blk->name); 9918e46a03SMarkus Armbruster drive_info_del(blk->legacy_dinfo); 10026f54e9aSMarkus Armbruster g_free(blk); 10126f54e9aSMarkus Armbruster } 10226f54e9aSMarkus Armbruster 1038fb3c76cSMarkus Armbruster static void drive_info_del(DriveInfo *dinfo) 1048fb3c76cSMarkus Armbruster { 1058fb3c76cSMarkus Armbruster if (!dinfo) { 1068fb3c76cSMarkus Armbruster return; 1078fb3c76cSMarkus Armbruster } 1088fb3c76cSMarkus Armbruster qemu_opts_del(dinfo->opts); 1098fb3c76cSMarkus Armbruster g_free(dinfo->id); 1108fb3c76cSMarkus Armbruster g_free(dinfo->serial); 1118fb3c76cSMarkus Armbruster g_free(dinfo); 1128fb3c76cSMarkus Armbruster } 1138fb3c76cSMarkus Armbruster 11426f54e9aSMarkus Armbruster /* 11526f54e9aSMarkus Armbruster * Increment @blk's reference count. 11626f54e9aSMarkus Armbruster * @blk must not be null. 11726f54e9aSMarkus Armbruster */ 11826f54e9aSMarkus Armbruster void blk_ref(BlockBackend *blk) 11926f54e9aSMarkus Armbruster { 12026f54e9aSMarkus Armbruster blk->refcnt++; 12126f54e9aSMarkus Armbruster } 12226f54e9aSMarkus Armbruster 12326f54e9aSMarkus Armbruster /* 12426f54e9aSMarkus Armbruster * Decrement @blk's reference count. 12526f54e9aSMarkus Armbruster * If this drops it to zero, destroy @blk. 12626f54e9aSMarkus Armbruster * For convenience, do nothing if @blk is null. 12726f54e9aSMarkus Armbruster */ 12826f54e9aSMarkus Armbruster void blk_unref(BlockBackend *blk) 12926f54e9aSMarkus Armbruster { 13026f54e9aSMarkus Armbruster if (blk) { 13126f54e9aSMarkus Armbruster assert(blk->refcnt > 0); 13226f54e9aSMarkus Armbruster if (!--blk->refcnt) { 13326f54e9aSMarkus Armbruster blk_delete(blk); 13426f54e9aSMarkus Armbruster } 13526f54e9aSMarkus Armbruster } 13626f54e9aSMarkus Armbruster } 13726f54e9aSMarkus Armbruster 13826f54e9aSMarkus Armbruster /* 13926f54e9aSMarkus Armbruster * Return the BlockBackend after @blk. 14026f54e9aSMarkus Armbruster * If @blk is null, return the first one. 14126f54e9aSMarkus Armbruster * Else, return @blk's next sibling, which may be null. 14226f54e9aSMarkus Armbruster * 14326f54e9aSMarkus Armbruster * To iterate over all BlockBackends, do 14426f54e9aSMarkus Armbruster * for (blk = blk_next(NULL); blk; blk = blk_next(blk)) { 14526f54e9aSMarkus Armbruster * ... 14626f54e9aSMarkus Armbruster * } 14726f54e9aSMarkus Armbruster */ 14826f54e9aSMarkus Armbruster BlockBackend *blk_next(BlockBackend *blk) 14926f54e9aSMarkus Armbruster { 15026f54e9aSMarkus Armbruster return blk ? QTAILQ_NEXT(blk, link) : QTAILQ_FIRST(&blk_backends); 15126f54e9aSMarkus Armbruster } 15226f54e9aSMarkus Armbruster 15326f54e9aSMarkus Armbruster /* 1547e7d56d9SMarkus Armbruster * Return @blk's name, a non-null string. 1557e7d56d9SMarkus Armbruster * Wart: the name is empty iff @blk has been hidden with 1567e7d56d9SMarkus Armbruster * blk_hide_on_behalf_of_do_drive_del(). 15726f54e9aSMarkus Armbruster */ 15826f54e9aSMarkus Armbruster const char *blk_name(BlockBackend *blk) 15926f54e9aSMarkus Armbruster { 16026f54e9aSMarkus Armbruster return blk->name; 16126f54e9aSMarkus Armbruster } 16226f54e9aSMarkus Armbruster 16326f54e9aSMarkus Armbruster /* 16426f54e9aSMarkus Armbruster * Return the BlockBackend with name @name if it exists, else null. 16526f54e9aSMarkus Armbruster * @name must not be null. 16626f54e9aSMarkus Armbruster */ 16726f54e9aSMarkus Armbruster BlockBackend *blk_by_name(const char *name) 16826f54e9aSMarkus Armbruster { 16926f54e9aSMarkus Armbruster BlockBackend *blk; 17026f54e9aSMarkus Armbruster 17126f54e9aSMarkus Armbruster assert(name); 17226f54e9aSMarkus Armbruster QTAILQ_FOREACH(blk, &blk_backends, link) { 17326f54e9aSMarkus Armbruster if (!strcmp(name, blk->name)) { 17426f54e9aSMarkus Armbruster return blk; 17526f54e9aSMarkus Armbruster } 17626f54e9aSMarkus Armbruster } 17726f54e9aSMarkus Armbruster return NULL; 17826f54e9aSMarkus Armbruster } 1797e7d56d9SMarkus Armbruster 1807e7d56d9SMarkus Armbruster /* 1817e7d56d9SMarkus Armbruster * Return the BlockDriverState attached to @blk if any, else null. 1827e7d56d9SMarkus Armbruster */ 1837e7d56d9SMarkus Armbruster BlockDriverState *blk_bs(BlockBackend *blk) 1847e7d56d9SMarkus Armbruster { 1857e7d56d9SMarkus Armbruster return blk->bs; 1867e7d56d9SMarkus Armbruster } 1877e7d56d9SMarkus Armbruster 1887e7d56d9SMarkus Armbruster /* 18918e46a03SMarkus Armbruster * Return @blk's DriveInfo if any, else null. 19018e46a03SMarkus Armbruster */ 19118e46a03SMarkus Armbruster DriveInfo *blk_legacy_dinfo(BlockBackend *blk) 19218e46a03SMarkus Armbruster { 19318e46a03SMarkus Armbruster return blk->legacy_dinfo; 19418e46a03SMarkus Armbruster } 19518e46a03SMarkus Armbruster 19618e46a03SMarkus Armbruster /* 19718e46a03SMarkus Armbruster * Set @blk's DriveInfo to @dinfo, and return it. 19818e46a03SMarkus Armbruster * @blk must not have a DriveInfo set already. 19918e46a03SMarkus Armbruster * No other BlockBackend may have the same DriveInfo set. 20018e46a03SMarkus Armbruster */ 20118e46a03SMarkus Armbruster DriveInfo *blk_set_legacy_dinfo(BlockBackend *blk, DriveInfo *dinfo) 20218e46a03SMarkus Armbruster { 20318e46a03SMarkus Armbruster assert(!blk->legacy_dinfo); 20418e46a03SMarkus Armbruster return blk->legacy_dinfo = dinfo; 20518e46a03SMarkus Armbruster } 20618e46a03SMarkus Armbruster 20718e46a03SMarkus Armbruster /* 20818e46a03SMarkus Armbruster * Return the BlockBackend with DriveInfo @dinfo. 20918e46a03SMarkus Armbruster * It must exist. 21018e46a03SMarkus Armbruster */ 21118e46a03SMarkus Armbruster BlockBackend *blk_by_legacy_dinfo(DriveInfo *dinfo) 21218e46a03SMarkus Armbruster { 21318e46a03SMarkus Armbruster BlockBackend *blk; 21418e46a03SMarkus Armbruster 21518e46a03SMarkus Armbruster QTAILQ_FOREACH(blk, &blk_backends, link) { 21618e46a03SMarkus Armbruster if (blk->legacy_dinfo == dinfo) { 21718e46a03SMarkus Armbruster return blk; 21818e46a03SMarkus Armbruster } 21918e46a03SMarkus Armbruster } 22018e46a03SMarkus Armbruster abort(); 22118e46a03SMarkus Armbruster } 22218e46a03SMarkus Armbruster 22318e46a03SMarkus Armbruster /* 2247e7d56d9SMarkus Armbruster * Hide @blk. 2257e7d56d9SMarkus Armbruster * @blk must not have been hidden already. 2267e7d56d9SMarkus Armbruster * Make attached BlockDriverState, if any, anonymous. 2277e7d56d9SMarkus Armbruster * Once hidden, @blk is invisible to all functions that don't receive 2287e7d56d9SMarkus Armbruster * it as argument. For example, blk_by_name() won't return it. 2297e7d56d9SMarkus Armbruster * Strictly for use by do_drive_del(). 2307e7d56d9SMarkus Armbruster * TODO get rid of it! 2317e7d56d9SMarkus Armbruster */ 2327e7d56d9SMarkus Armbruster void blk_hide_on_behalf_of_do_drive_del(BlockBackend *blk) 2337e7d56d9SMarkus Armbruster { 2347e7d56d9SMarkus Armbruster QTAILQ_REMOVE(&blk_backends, blk, link); 2357e7d56d9SMarkus Armbruster blk->name[0] = 0; 2367e7d56d9SMarkus Armbruster if (blk->bs) { 2377e7d56d9SMarkus Armbruster bdrv_make_anon(blk->bs); 2387e7d56d9SMarkus Armbruster } 2397e7d56d9SMarkus Armbruster } 240