2003-06-30 14:03:06 +04:00
/*
* QEMU System Emulator block driver
2007-09-17 01:08:06 +04:00
*
2003-06-30 14:03:06 +04:00
* Copyright ( c ) 2003 Fabrice Bellard
2021-04-28 18:18:04 +03:00
* Copyright ( c ) 2020 Virtuozzo International GmbH .
2007-09-17 01:08:06 +04:00
*
2003-06-30 14:03:06 +04:00
* Permission is hereby granted , free of charge , to any person obtaining a copy
* of this software and associated documentation files ( the " Software " ) , to deal
* in the Software without restriction , including without limitation the rights
* to use , copy , modify , merge , publish , distribute , sublicense , and / or sell
* copies of the Software , and to permit persons to whom the Software is
* furnished to do so , subject to the following conditions :
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software .
*
* THE SOFTWARE IS PROVIDED " AS IS " , WITHOUT WARRANTY OF ANY KIND , EXPRESS OR
* IMPLIED , INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY ,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT . IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM , DAMAGES OR OTHER
* LIABILITY , WHETHER IN AN ACTION OF CONTRACT , TORT OR OTHERWISE , ARISING FROM ,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE .
*/
2018-02-01 14:18:31 +03:00
2016-01-29 20:50:05 +03:00
# include "qemu/osdep.h"
2017-01-25 19:14:15 +03:00
# include "block/trace.h"
2012-12-17 21:19:44 +04:00
# include "block/block_int.h"
# include "block/blockjob.h"
2022-12-21 16:35:49 +03:00
# include "block/dirty-bitmap.h"
2020-10-27 22:05:42 +03:00
# include "block/fuse.h"
2016-07-06 12:22:39 +03:00
# include "block/nbd.h"
2018-06-14 22:14:28 +03:00
# include "block/qdict.h"
2015-03-17 20:29:20 +03:00
# include "qemu/error-report.h"
2019-08-29 21:34:43 +03:00
# include "block/module_block.h"
Include qemu/main-loop.h less
In my "build everything" tree, changing qemu/main-loop.h triggers a
recompile of some 5600 out of 6600 objects (not counting tests and
objects that don't depend on qemu/osdep.h). It includes block/aio.h,
which in turn includes qemu/event_notifier.h, qemu/notify.h,
qemu/processor.h, qemu/qsp.h, qemu/queue.h, qemu/thread-posix.h,
qemu/thread.h, qemu/timer.h, and a few more.
Include qemu/main-loop.h only where it's needed. Touching it now
recompiles only some 1700 objects. For block/aio.h and
qemu/event_notifier.h, these numbers drop from 5600 to 2800. For the
others, they shrink only slightly.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Message-Id: <20190812052359.30071-21-armbru@redhat.com>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
2019-08-12 08:23:50 +03:00
# include "qemu/main-loop.h"
2012-12-17 21:20:00 +04:00
# include "qemu/module.h"
2018-02-01 14:18:31 +03:00
# include "qapi/error.h"
2018-02-01 14:18:39 +03:00
# include "qapi/qmp/qdict.h"
2012-12-17 21:19:43 +04:00
# include "qapi/qmp/qjson.h"
2018-02-24 18:40:32 +03:00
# include "qapi/qmp/qnull.h"
2018-02-01 14:18:40 +03:00
# include "qapi/qmp/qstring.h"
2018-01-10 17:52:33 +03:00
# include "qapi/qobject-output-visitor.h"
# include "qapi/qapi-visit-block-core.h"
2014-10-07 15:59:11 +04:00
# include "sysemu/block-backend.h"
2012-12-17 21:20:00 +04:00
# include "qemu/notify.h"
2018-02-01 14:18:46 +03:00
# include "qemu/option.h"
2015-09-01 16:48:02 +03:00
# include "qemu/coroutine.h"
2014-01-24 00:31:34 +04:00
# include "block/qapi.h"
2012-12-17 21:20:00 +04:00
# include "qemu/timer.h"
2016-03-20 20:16:19 +03:00
# include "qemu/cutils.h"
# include "qemu/id.h"
block: block-status cache for data regions
As we have attempted before
(https://lists.gnu.org/archive/html/qemu-devel/2019-01/msg06451.html,
"file-posix: Cache lseek result for data regions";
https://lists.nongnu.org/archive/html/qemu-block/2021-02/msg00934.html,
"file-posix: Cache next hole"), this patch seeks to reduce the number of
SEEK_DATA/HOLE operations the file-posix driver has to perform. The
main difference is that this time it is implemented as part of the
general block layer code.
The problem we face is that on some filesystems or in some
circumstances, SEEK_DATA/HOLE is unreasonably slow. Given the
implementation is outside of qemu, there is little we can do about its
performance.
We have already introduced the want_zero parameter to
bdrv_co_block_status() to reduce the number of SEEK_DATA/HOLE calls
unless we really want zero information; but sometimes we do want that
information, because for files that consist largely of zero areas,
special-casing those areas can give large performance boosts. So the
real problem is with files that consist largely of data, so that
inquiring the block status does not gain us much performance, but where
such an inquiry itself takes a lot of time.
To address this, we want to cache data regions. Most of the time, when
bad performance is reported, it is in places where the image is iterated
over from start to end (qemu-img convert or the mirror job), so a simple
yet effective solution is to cache only the current data region.
(Note that only caching data regions but not zero regions means that
returning false information from the cache is not catastrophic: Treating
zeroes as data is fine. While we try to invalidate the cache on zero
writes and discards, such incongruences may still occur when there are
other processes writing to the image.)
We only use the cache for nodes without children (i.e. protocol nodes),
because that is where the problem is: Drivers that rely on block-status
implementations outside of qemu (e.g. SEEK_DATA/HOLE).
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/307
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
Message-Id: <20210812084148.14458-3-hreitz@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
[hreitz: Added `local_file == bs` assertion, as suggested by Vladimir]
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
2021-08-12 11:41:44 +03:00
# include "qemu/range.h"
# include "qemu/rcu.h"
2020-09-24 21:54:10 +03:00
# include "block/coroutines.h"
2003-06-30 14:03:06 +04:00
2009-07-27 18:12:56 +04:00
# ifdef CONFIG_BSD
2005-04-27 01:59:26 +04:00
# include <sys/ioctl.h>
2009-09-12 11:36:22 +04:00
# include <sys/queue.h>
2021-03-15 21:03:39 +03:00
# if defined(HAVE_SYS_DISK_H)
2005-04-27 01:59:26 +04:00
# include <sys/disk.h>
# endif
2009-03-07 23:06:23 +03:00
# endif
2005-04-27 01:59:26 +04:00
2009-03-08 19:26:59 +03:00
# ifdef _WIN32
# include <windows.h>
# endif
2011-10-13 16:08:22 +04:00
# define NOT_DONE 0x7fffffff /* used while emulated sync operation in progress */
2022-03-03 18:15:48 +03:00
/* Protected by BQL */
2014-01-24 00:31:32 +04:00
static QTAILQ_HEAD ( , BlockDriverState ) graph_bdrv_states =
QTAILQ_HEAD_INITIALIZER ( graph_bdrv_states ) ;
2022-03-03 18:15:48 +03:00
/* Protected by BQL */
2016-01-29 18:36:11 +03:00
static QTAILQ_HEAD ( , BlockDriverState ) all_bdrv_states =
QTAILQ_HEAD_INITIALIZER ( all_bdrv_states ) ;
2022-03-03 18:15:48 +03:00
/* Protected by BQL */
2010-04-13 13:29:33 +04:00
static QLIST_HEAD ( , BlockDriver ) bdrv_drivers =
QLIST_HEAD_INITIALIZER ( bdrv_drivers ) ;
2004-08-02 01:59:26 +04:00
2016-05-17 17:41:31 +03:00
static BlockDriverState * bdrv_open_inherit ( const char * filename ,
const char * reference ,
QDict * options , int flags ,
BlockDriverState * parent ,
2020-05-13 14:05:13 +03:00
const BdrvChildClass * child_class ,
2020-05-13 14:05:17 +03:00
BdrvChildRole child_role ,
2024-04-25 15:56:02 +03:00
bool parse_filename ,
2016-05-17 17:41:31 +03:00
Error * * errp ) ;
2015-04-08 14:43:47 +03:00
2021-10-18 16:47:14 +03:00
static bool bdrv_recurse_has_child ( BlockDriverState * bs ,
BlockDriverState * child ) ;
2023-09-11 12:46:07 +03:00
static void GRAPH_WRLOCK
bdrv_replace_child_noperm ( BdrvChild * child , BlockDriverState * new_bs ) ;
2023-09-11 12:46:08 +03:00
static void GRAPH_WRLOCK
bdrv_remove_child ( BdrvChild * child , Transaction * tran ) ;
2021-04-28 18:17:44 +03:00
2021-04-28 18:17:58 +03:00
static int bdrv_reopen_prepare ( BDRVReopenState * reopen_state ,
BlockReopenQueue * queue ,
2021-06-10 15:05:36 +03:00
Transaction * change_child_tran , Error * * errp ) ;
2021-04-28 18:17:35 +03:00
static void bdrv_reopen_commit ( BDRVReopenState * reopen_state ) ;
static void bdrv_reopen_abort ( BDRVReopenState * reopen_state ) ;
2021-12-15 15:11:38 +03:00
static bool bdrv_backing_overridden ( BlockDriverState * bs ) ;
block: use transactions as a replacement of ->{can_}set_aio_context()
Simplify the way the aiocontext can be changed in a BDS graph.
There are currently two problems in bdrv_try_set_aio_context:
- There is a confusion of AioContext locks taken and released, because
we assume that old aiocontext is always taken and new one is
taken inside.
- It doesn't look very safe to call bdrv_drained_begin while some
nodes have already switched to the new aiocontext and others haven't.
This could be especially dangerous because bdrv_drained_begin polls, so
something else could be executed while graph is in an inconsistent
state.
Additional minor nitpick: can_set and set_ callbacks both traverse the
graph, both using the ignored list of visited nodes in a different way.
Therefore, get rid of all of this and introduce a new callback,
change_aio_context, that uses transactions to efficiently, cleanly
and most importantly safely change the aiocontext of a graph.
This new callback is a "merge" of the two previous ones:
- Just like can_set_aio_context, recursively traverses the graph.
Marks all nodes that are visited using a GList, and checks if
they *could* change the aio_context.
- For each node that passes the above check, drain it and add a new transaction
that implements a callback that effectively changes the aiocontext.
- Once done, the recursive function returns if *all* nodes can change
the AioContext. If so, commit the above transactions.
Regardless of the outcome, call transaction.clean() to undo all drains
done in the recursion.
- The transaction list is scanned only after all nodes are being drained, so
we are sure that they all are in the same context, and then
we switch their AioContext, concluding the drain only after all nodes
switched to the new AioContext. In this way we make sure that
bdrv_drained_begin() is always called under the old AioContext, and
bdrv_drained_end() under the new one.
- Because of the above, we don't need to release and re-acquire the
old AioContext every time, as everything is done once (and not
per-node drain and aiocontext change).
Note that the "change" API is not yet invoked anywhere.
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
Message-Id: <20221025084952.2139888-3-eesposit@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2022-10-25 11:49:44 +03:00
static bool bdrv_change_aio_context ( BlockDriverState * bs , AioContext * ctx ,
2022-10-25 11:49:45 +03:00
GHashTable * visited , Transaction * tran ,
block: use transactions as a replacement of ->{can_}set_aio_context()
Simplify the way the aiocontext can be changed in a BDS graph.
There are currently two problems in bdrv_try_set_aio_context:
- There is a confusion of AioContext locks taken and released, because
we assume that old aiocontext is always taken and new one is
taken inside.
- It doesn't look very safe to call bdrv_drained_begin while some
nodes have already switched to the new aiocontext and others haven't.
This could be especially dangerous because bdrv_drained_begin polls, so
something else could be executed while graph is in an inconsistent
state.
Additional minor nitpick: can_set and set_ callbacks both traverse the
graph, both using the ignored list of visited nodes in a different way.
Therefore, get rid of all of this and introduce a new callback,
change_aio_context, that uses transactions to efficiently, cleanly
and most importantly safely change the aiocontext of a graph.
This new callback is a "merge" of the two previous ones:
- Just like can_set_aio_context, recursively traverses the graph.
Marks all nodes that are visited using a GList, and checks if
they *could* change the aio_context.
- For each node that passes the above check, drain it and add a new transaction
that implements a callback that effectively changes the aiocontext.
- Once done, the recursive function returns if *all* nodes can change
the AioContext. If so, commit the above transactions.
Regardless of the outcome, call transaction.clean() to undo all drains
done in the recursion.
- The transaction list is scanned only after all nodes are being drained, so
we are sure that they all are in the same context, and then
we switch their AioContext, concluding the drain only after all nodes
switched to the new AioContext. In this way we make sure that
bdrv_drained_begin() is always called under the old AioContext, and
bdrv_drained_end() under the new one.
- Because of the above, we don't need to release and re-acquire the
old AioContext every time, as everything is done once (and not
per-node drain and aiocontext change).
Note that the "change" API is not yet invoked anywhere.
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
Message-Id: <20221025084952.2139888-3-eesposit@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2022-10-25 11:49:44 +03:00
Error * * errp ) ;
2009-10-27 20:41:44 +03:00
/* If non-zero, use only whitelisted block drivers */
static int use_bdrv_whitelist ;
2010-12-09 14:53:00 +03:00
# ifdef _WIN32
static int is_windows_drive_prefix ( const char * filename )
{
return ( ( ( filename [ 0 ] > = ' a ' & & filename [ 0 ] < = ' z ' ) | |
( filename [ 0 ] > = ' A ' & & filename [ 0 ] < = ' Z ' ) ) & &
filename [ 1 ] = = ' : ' ) ;
}
int is_windows_drive ( const char * filename )
{
if ( is_windows_drive_prefix ( filename ) & &
filename [ 2 ] = = ' \0 ' )
return 1 ;
if ( strstart ( filename , " \\ \\ . \\ " , NULL ) | |
strstart ( filename , " //./ " , NULL ) )
return 1 ;
return 0 ;
}
# endif
2013-11-28 13:23:32 +04:00
size_t bdrv_opt_mem_align ( BlockDriverState * bs )
{
if ( ! bs | | ! bs - > drv ) {
block: align bounce buffers to page
The following sequence
int fd = open(argv[1], O_RDWR | O_CREAT | O_DIRECT, 0644);
for (i = 0; i < 100000; i++)
write(fd, buf, 4096);
performs 5% better if buf is aligned to 4096 bytes.
The difference is quite reliable.
On the other hand we do not want at the moment to enforce bounce
buffering if guest request is aligned to 512 bytes.
The patch changes default bounce buffer optimal alignment to
MAX(page size, 4k). 4k is chosen as maximal known sector size on real
HDD.
The justification of the performance improve is quite interesting.
From the kernel point of view each request to the disk was split
by two. This could be seen by blktrace like this:
9,0 11 1 0.000000000 11151 Q WS 312737792 + 1023 [qemu-img]
9,0 11 2 0.000007938 11151 Q WS 312738815 + 8 [qemu-img]
9,0 11 3 0.000030735 11151 Q WS 312738823 + 1016 [qemu-img]
9,0 11 4 0.000032482 11151 Q WS 312739839 + 8 [qemu-img]
9,0 11 5 0.000041379 11151 Q WS 312739847 + 1016 [qemu-img]
9,0 11 6 0.000042818 11151 Q WS 312740863 + 8 [qemu-img]
9,0 11 7 0.000051236 11151 Q WS 312740871 + 1017 [qemu-img]
9,0 5 1 0.169071519 11151 Q WS 312741888 + 1023 [qemu-img]
After the patch the pattern becomes normal:
9,0 6 1 0.000000000 12422 Q WS 314834944 + 1024 [qemu-img]
9,0 6 2 0.000038527 12422 Q WS 314835968 + 1024 [qemu-img]
9,0 6 3 0.000072849 12422 Q WS 314836992 + 1024 [qemu-img]
9,0 6 4 0.000106276 12422 Q WS 314838016 + 1024 [qemu-img]
and the amount of requests sent to disk (could be calculated counting
number of lines in the output of blktrace) is reduced about 2 times.
Both qemu-img and qemu-io are affected while qemu-kvm is not. The guest
does his job well and real requests comes properly aligned (to page).
Signed-off-by: Denis V. Lunev <den@openvz.org>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Message-id: 1431441056-26198-3-git-send-email-den@openvz.org
CC: Paolo Bonzini <pbonzini@redhat.com>
CC: Kevin Wolf <kwolf@redhat.com>
CC: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2015-05-12 17:30:56 +03:00
/* page size or 4k (hdd sector size) should be on the safe side */
2022-03-23 18:57:22 +03:00
return MAX ( 4096 , qemu_real_host_page_size ( ) ) ;
2013-11-28 13:23:32 +04:00
}
2022-03-03 18:15:50 +03:00
IO_CODE ( ) ;
2013-11-28 13:23:32 +04:00
return bs - > bl . opt_mem_alignment ;
}
2015-05-12 17:30:55 +03:00
size_t bdrv_min_mem_align ( BlockDriverState * bs )
{
if ( ! bs | | ! bs - > drv ) {
block: align bounce buffers to page
The following sequence
int fd = open(argv[1], O_RDWR | O_CREAT | O_DIRECT, 0644);
for (i = 0; i < 100000; i++)
write(fd, buf, 4096);
performs 5% better if buf is aligned to 4096 bytes.
The difference is quite reliable.
On the other hand we do not want at the moment to enforce bounce
buffering if guest request is aligned to 512 bytes.
The patch changes default bounce buffer optimal alignment to
MAX(page size, 4k). 4k is chosen as maximal known sector size on real
HDD.
The justification of the performance improve is quite interesting.
From the kernel point of view each request to the disk was split
by two. This could be seen by blktrace like this:
9,0 11 1 0.000000000 11151 Q WS 312737792 + 1023 [qemu-img]
9,0 11 2 0.000007938 11151 Q WS 312738815 + 8 [qemu-img]
9,0 11 3 0.000030735 11151 Q WS 312738823 + 1016 [qemu-img]
9,0 11 4 0.000032482 11151 Q WS 312739839 + 8 [qemu-img]
9,0 11 5 0.000041379 11151 Q WS 312739847 + 1016 [qemu-img]
9,0 11 6 0.000042818 11151 Q WS 312740863 + 8 [qemu-img]
9,0 11 7 0.000051236 11151 Q WS 312740871 + 1017 [qemu-img]
9,0 5 1 0.169071519 11151 Q WS 312741888 + 1023 [qemu-img]
After the patch the pattern becomes normal:
9,0 6 1 0.000000000 12422 Q WS 314834944 + 1024 [qemu-img]
9,0 6 2 0.000038527 12422 Q WS 314835968 + 1024 [qemu-img]
9,0 6 3 0.000072849 12422 Q WS 314836992 + 1024 [qemu-img]
9,0 6 4 0.000106276 12422 Q WS 314838016 + 1024 [qemu-img]
and the amount of requests sent to disk (could be calculated counting
number of lines in the output of blktrace) is reduced about 2 times.
Both qemu-img and qemu-io are affected while qemu-kvm is not. The guest
does his job well and real requests comes properly aligned (to page).
Signed-off-by: Denis V. Lunev <den@openvz.org>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Message-id: 1431441056-26198-3-git-send-email-den@openvz.org
CC: Paolo Bonzini <pbonzini@redhat.com>
CC: Kevin Wolf <kwolf@redhat.com>
CC: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2015-05-12 17:30:56 +03:00
/* page size or 4k (hdd sector size) should be on the safe side */
2022-03-23 18:57:22 +03:00
return MAX ( 4096 , qemu_real_host_page_size ( ) ) ;
2015-05-12 17:30:55 +03:00
}
2022-03-03 18:15:50 +03:00
IO_CODE ( ) ;
2015-05-12 17:30:55 +03:00
return bs - > bl . min_mem_alignment ;
}
2010-12-09 14:53:00 +03:00
/* check if the path starts with "<protocol>:" */
2014-12-03 16:57:22 +03:00
int path_has_protocol ( const char * path )
2010-12-09 14:53:00 +03:00
{
2012-05-08 18:51:48 +04:00
const char * p ;
2010-12-09 14:53:00 +03:00
# ifdef _WIN32
if ( is_windows_drive ( path ) | |
is_windows_drive_prefix ( path ) ) {
return 0 ;
}
2012-05-08 18:51:48 +04:00
p = path + strcspn ( path , " :/ \\ " ) ;
# else
p = path + strcspn ( path , " :/ " ) ;
2010-12-09 14:53:00 +03:00
# endif
2012-05-08 18:51:48 +04:00
return * p = = ' : ' ;
2010-12-09 14:53:00 +03:00
}
2006-08-01 20:21:11 +04:00
int path_is_absolute ( const char * path )
2005-10-30 21:30:10 +03:00
{
2007-01-07 21:22:37 +03:00
# ifdef _WIN32
/* specific case for names like: "\\.\d:" */
2012-05-08 18:51:47 +04:00
if ( is_windows_drive ( path ) | | is_windows_drive_prefix ( path ) ) {
2007-01-07 21:22:37 +03:00
return 1 ;
2012-05-08 18:51:47 +04:00
}
return ( * path = = ' / ' | | * path = = ' \\ ' ) ;
2007-01-07 20:27:07 +03:00
# else
2012-05-08 18:51:47 +04:00
return ( * path = = ' / ' ) ;
2007-01-07 20:27:07 +03:00
# endif
2005-10-30 21:30:10 +03:00
}
2019-02-01 22:29:13 +03:00
/* if filename is absolute, just return its duplicate. Otherwise, build a
2006-08-01 20:21:11 +04:00
path to it by considering it is relative to base_path . URL are
supported . */
2019-02-01 22:29:13 +03:00
char * path_combine ( const char * base_path , const char * filename )
2005-10-30 21:30:10 +03:00
{
2019-02-01 22:29:13 +03:00
const char * protocol_stripped = NULL ;
2006-08-01 20:21:11 +04:00
const char * p , * p1 ;
2019-02-01 22:29:13 +03:00
char * result ;
2006-08-01 20:21:11 +04:00
int len ;
if ( path_is_absolute ( filename ) ) {
2019-02-01 22:29:13 +03:00
return g_strdup ( filename ) ;
}
2017-05-22 22:52:15 +03:00
2019-02-01 22:29:13 +03:00
if ( path_has_protocol ( base_path ) ) {
protocol_stripped = strchr ( base_path , ' : ' ) ;
if ( protocol_stripped ) {
protocol_stripped + + ;
2017-05-22 22:52:15 +03:00
}
2019-02-01 22:29:13 +03:00
}
p = protocol_stripped ? : base_path ;
2017-05-22 22:52:15 +03:00
2019-02-01 22:29:13 +03:00
p1 = strrchr ( base_path , ' / ' ) ;
2007-01-07 20:27:07 +03:00
# ifdef _WIN32
2019-02-01 22:29:13 +03:00
{
const char * p2 ;
p2 = strrchr ( base_path , ' \\ ' ) ;
if ( ! p1 | | p2 > p1 ) {
p1 = p2 ;
2007-01-07 20:27:07 +03:00
}
2019-02-01 22:29:13 +03:00
}
2007-01-07 20:27:07 +03:00
# endif
2019-02-01 22:29:13 +03:00
if ( p1 ) {
p1 + + ;
} else {
p1 = base_path ;
}
if ( p1 > p ) {
p = p1 ;
2005-10-30 21:30:10 +03:00
}
2019-02-01 22:29:13 +03:00
len = p - base_path ;
result = g_malloc ( len + strlen ( filename ) + 1 ) ;
memcpy ( result , base_path , len ) ;
strcpy ( result + len , filename ) ;
return result ;
}
2017-05-22 22:52:16 +03:00
/*
* Helper function for bdrv_parse_filename ( ) implementations to remove optional
* protocol prefixes ( especially " file: " ) from a filename and for putting the
* stripped filename into the options QDict if there is such a prefix .
*/
void bdrv_parse_filename_strip_prefix ( const char * filename , const char * prefix ,
QDict * options )
{
if ( strstart ( filename , prefix , & filename ) ) {
/* Stripping the explicit protocol prefix may result in a protocol
* prefix being ( wrongly ) detected ( if the filename contains a colon ) */
if ( path_has_protocol ( filename ) ) {
2020-12-11 20:11:51 +03:00
GString * fat_filename ;
2017-05-22 22:52:16 +03:00
/* This means there is some colon before the first slash; therefore,
* this cannot be an absolute path */
assert ( ! path_is_absolute ( filename ) ) ;
/* And we can thus fix the protocol detection issue by prefixing it
* by " ./ " */
2020-12-11 20:11:51 +03:00
fat_filename = g_string_new ( " ./ " ) ;
g_string_append ( fat_filename , filename ) ;
2017-05-22 22:52:16 +03:00
2020-12-11 20:11:51 +03:00
assert ( ! path_has_protocol ( fat_filename - > str ) ) ;
2017-05-22 22:52:16 +03:00
2020-12-11 20:11:51 +03:00
qdict_put ( options , " filename " ,
qstring_from_gstring ( fat_filename ) ) ;
2017-05-22 22:52:16 +03:00
} else {
/* If no protocol prefix was detected, we can use the shortened
* filename as - is */
qdict_put_str ( options , " filename " , filename ) ;
}
}
}
2017-05-04 19:52:40 +03:00
/* Returns whether the image file is opened as read-only. Note that this can
* return false and writing to the image file is still not possible because the
* image is inactivated . */
2017-04-07 23:55:28 +03:00
bool bdrv_is_read_only ( BlockDriverState * bs )
{
2022-03-03 18:15:50 +03:00
IO_CODE ( ) ;
2021-05-27 18:40:55 +03:00
return ! ( bs - > open_flags & BDRV_O_RDWR ) ;
2017-04-07 23:55:28 +03:00
}
2023-09-29 17:51:47 +03:00
static int GRAPH_RDLOCK
bdrv_can_set_read_only ( BlockDriverState * bs , bool read_only ,
bool ignore_allow_rdw , Error * * errp )
2017-04-07 23:55:25 +03:00
{
2022-03-03 18:15:50 +03:00
IO_CODE ( ) ;
block: do not set BDS read_only if copy_on_read enabled
A few block drivers will set the BDS read_only flag from their
.bdrv_open() function. This means the bs->read_only flag could
be set after we enable copy_on_read, as the BDRV_O_COPY_ON_READ
flag check occurs prior to the call to bdrv->bdrv_open().
This adds an error return to bdrv_set_read_only(), and an error will be
return if we try to set the BDS to read_only while copy_on_read is
enabled.
This patch also changes the behavior of vvfat. Before, vvfat could
override the drive 'readonly' flag with its own, internal 'rw' flag.
For instance, this -drive parameter would result in a writable image:
"-drive format=vvfat,dir=/tmp/vvfat,rw,if=virtio,readonly=on"
This is not correct. Now, attempting to use the above -drive parameter
will result in an error (i.e., 'rw' is incompatible with 'readonly=on').
Signed-off-by: Jeff Cody <jcody@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: John Snow <jsnow@redhat.com>
Message-id: 0c5b4c1cc2c651471b131f21376dfd5ea24d2196.1491597120.git.jcody@redhat.com
2017-04-07 23:55:26 +03:00
/* Do not set read_only if copy_on_read is enabled */
if ( bs - > copy_on_read & & read_only ) {
error_setg ( errp , " Can't set node '%s' to r/o with copy-on-read enabled " ,
bdrv_get_device_or_node_name ( bs ) ) ;
return - EINVAL ;
}
2017-04-07 23:55:27 +03:00
/* Do not clear read_only if it is prohibited */
2017-08-03 18:02:58 +03:00
if ( ! read_only & & ! ( bs - > open_flags & BDRV_O_ALLOW_RDWR ) & &
! ignore_allow_rdw )
{
2017-04-07 23:55:27 +03:00
error_setg ( errp , " Node '%s' is read only " ,
bdrv_get_device_or_node_name ( bs ) ) ;
return - EPERM ;
}
2017-04-07 23:55:29 +03:00
return 0 ;
}
2018-10-12 12:27:41 +03:00
/*
* Called by a driver that can only provide a read - only image .
*
* Returns 0 if the node is already read - only or it could switch the node to
* read - only because BDRV_O_AUTO_RDONLY is set .
*
* Returns - EACCES if the node is read - write and BDRV_O_AUTO_RDONLY is not set
* or bdrv_can_set_read_only ( ) forbids making the node read - only . If @ errmsg
* is not NULL , it is used as the error message for the Error object .
*/
int bdrv_apply_auto_read_only ( BlockDriverState * bs , const char * errmsg ,
Error * * errp )
2017-04-07 23:55:29 +03:00
{
int ret = 0 ;
2022-03-03 18:15:50 +03:00
IO_CODE ( ) ;
2017-04-07 23:55:29 +03:00
2018-10-12 12:27:41 +03:00
if ( ! ( bs - > open_flags & BDRV_O_RDWR ) ) {
return 0 ;
}
if ( ! ( bs - > open_flags & BDRV_O_AUTO_RDONLY ) ) {
goto fail ;
2017-04-07 23:55:29 +03:00
}
2018-10-12 12:27:41 +03:00
ret = bdrv_can_set_read_only ( bs , true , false , NULL ) ;
if ( ret < 0 ) {
goto fail ;
2018-10-09 17:57:12 +03:00
}
2018-10-12 12:27:41 +03:00
bs - > open_flags & = ~ BDRV_O_RDWR ;
block: do not set BDS read_only if copy_on_read enabled
A few block drivers will set the BDS read_only flag from their
.bdrv_open() function. This means the bs->read_only flag could
be set after we enable copy_on_read, as the BDRV_O_COPY_ON_READ
flag check occurs prior to the call to bdrv->bdrv_open().
This adds an error return to bdrv_set_read_only(), and an error will be
return if we try to set the BDS to read_only while copy_on_read is
enabled.
This patch also changes the behavior of vvfat. Before, vvfat could
override the drive 'readonly' flag with its own, internal 'rw' flag.
For instance, this -drive parameter would result in a writable image:
"-drive format=vvfat,dir=/tmp/vvfat,rw,if=virtio,readonly=on"
This is not correct. Now, attempting to use the above -drive parameter
will result in an error (i.e., 'rw' is incompatible with 'readonly=on').
Signed-off-by: Jeff Cody <jcody@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: John Snow <jsnow@redhat.com>
Message-id: 0c5b4c1cc2c651471b131f21376dfd5ea24d2196.1491597120.git.jcody@redhat.com
2017-04-07 23:55:26 +03:00
return 0 ;
2018-10-12 12:27:41 +03:00
fail :
error_setg ( errp , " %s " , errmsg ? : " Image is read-only " ) ;
return - EACCES ;
2017-04-07 23:55:25 +03:00
}
2019-02-01 22:29:14 +03:00
/*
* If @ backing is empty , this function returns NULL without setting
* @ errp . In all other cases , NULL will only be returned with @ errp
* set .
*
* Therefore , a return value of NULL without @ errp set means that
* there is no backing file ; if @ errp is set , there is one but its
* absolute filename cannot be generated .
*/
char * bdrv_get_full_backing_filename_from_filename ( const char * backed ,
const char * backing ,
Error * * errp )
2012-05-08 18:51:50 +04:00
{
2019-02-01 22:29:14 +03:00
if ( backing [ 0 ] = = ' \0 ' ) {
return NULL ;
} else if ( path_has_protocol ( backing ) | | path_is_absolute ( backing ) ) {
return g_strdup ( backing ) ;
2014-11-26 19:20:26 +03:00
} else if ( backed [ 0 ] = = ' \0 ' | | strstart ( backed , " json: " , NULL ) ) {
error_setg ( errp , " Cannot use relative backing file names for '%s' " ,
backed ) ;
2019-02-01 22:29:14 +03:00
return NULL ;
2012-05-08 18:51:50 +04:00
} else {
2019-02-01 22:29:14 +03:00
return path_combine ( backed , backing ) ;
2012-05-08 18:51:50 +04:00
}
}
2019-02-01 22:29:16 +03:00
/*
* If @ filename is empty or NULL , this function returns NULL without
* setting @ errp . In all other cases , NULL will only be returned with
* @ errp set .
*/
2023-09-29 17:51:45 +03:00
static char * GRAPH_RDLOCK
bdrv_make_absolute_filename ( BlockDriverState * relative_to ,
const char * filename , Error * * errp )
2014-11-26 19:20:25 +03:00
{
2019-02-01 22:29:23 +03:00
char * dir , * full_name ;
2019-02-01 22:29:16 +03:00
2019-02-01 22:29:23 +03:00
if ( ! filename | | filename [ 0 ] = = ' \0 ' ) {
return NULL ;
} else if ( path_has_protocol ( filename ) | | path_is_absolute ( filename ) ) {
return g_strdup ( filename ) ;
}
2014-11-26 19:20:26 +03:00
2019-02-01 22:29:23 +03:00
dir = bdrv_dirname ( relative_to , errp ) ;
if ( ! dir ) {
return NULL ;
}
block: Use bdrv_refresh_filename() to pull
Before this patch, bdrv_refresh_filename() is used in a pushing manner:
Whenever the BDS graph is modified, the parents of the modified edges
are supposed to be updated (recursively upwards). However, that is
nonviable, considering that we want child changes not to concern
parents.
Also, in the long run we want a pull model anyway: Here, we would have a
bdrv_filename() function which returns a BDS's filename, freshly
constructed.
This patch is an intermediate step. It adds bdrv_refresh_filename()
calls before every place a BDS.filename value is used. The only
exceptions are protocol drivers that use their own filename, which
clearly would not profit from refreshing that filename before.
Also, bdrv_get_encrypted_filename() is removed along the way (as a user
of BDS.filename), since it is completely unused.
In turn, all of the calls to bdrv_refresh_filename() before this patch
are removed, because we no longer have to call this function on graph
changes.
Signed-off-by: Max Reitz <mreitz@redhat.com>
Message-id: 20190201192935.18394-2-mreitz@redhat.com
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Max Reitz <mreitz@redhat.com>
2019-02-01 22:29:05 +03:00
2019-02-01 22:29:23 +03:00
full_name = g_strconcat ( dir , filename , NULL ) ;
g_free ( dir ) ;
return full_name ;
2019-02-01 22:29:16 +03:00
}
char * bdrv_get_full_backing_filename ( BlockDriverState * bs , Error * * errp )
{
2022-03-03 18:15:49 +03:00
GLOBAL_STATE_CODE ( ) ;
2019-02-01 22:29:16 +03:00
return bdrv_make_absolute_filename ( bs , bs - > backing_file , errp ) ;
2014-11-26 19:20:25 +03:00
}
2015-04-28 16:27:51 +03:00
void bdrv_register ( BlockDriver * bdrv )
{
2020-03-19 01:22:35 +03:00
assert ( bdrv - > format_name ) ;
2022-03-03 18:15:49 +03:00
GLOBAL_STATE_CODE ( ) ;
2010-04-13 13:29:33 +04:00
QLIST_INSERT_HEAD ( & bdrv_drivers , bdrv , list ) ;
2004-08-02 01:59:26 +04:00
}
2004-03-15 00:38:54 +03:00
2014-10-07 15:59:03 +04:00
BlockDriverState * bdrv_new ( void )
{
BlockDriverState * bs ;
int i ;
2022-03-03 18:15:49 +03:00
GLOBAL_STATE_CODE ( ) ;
block: Use g_new() & friends where that makes obvious sense
g_new(T, n) is neater than g_malloc(sizeof(T) * n). It's also safer,
for two reasons. One, it catches multiplication overflowing size_t.
Two, it returns T * rather than void *, which lets the compiler catch
more type errors.
Patch created with Coccinelle, with two manual changes on top:
* Add const to bdrv_iterate_format() to keep the types straight
* Convert the allocation in bdrv_drop_intermediate(), which Coccinelle
inexplicably misses
Coccinelle semantic patch:
@@
type T;
@@
-g_malloc(sizeof(T))
+g_new(T, 1)
@@
type T;
@@
-g_try_malloc(sizeof(T))
+g_try_new(T, 1)
@@
type T;
@@
-g_malloc0(sizeof(T))
+g_new0(T, 1)
@@
type T;
@@
-g_try_malloc0(sizeof(T))
+g_try_new0(T, 1)
@@
type T;
expression n;
@@
-g_malloc(sizeof(T) * (n))
+g_new(T, n)
@@
type T;
expression n;
@@
-g_try_malloc(sizeof(T) * (n))
+g_try_new(T, n)
@@
type T;
expression n;
@@
-g_malloc0(sizeof(T) * (n))
+g_new0(T, n)
@@
type T;
expression n;
@@
-g_try_malloc0(sizeof(T) * (n))
+g_try_new0(T, n)
@@
type T;
expression p, n;
@@
-g_realloc(p, sizeof(T) * (n))
+g_renew(T, p, n)
@@
type T;
expression p, n;
@@
-g_try_realloc(p, sizeof(T) * (n))
+g_try_renew(T, p, n)
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Jeff Cody <jcody@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-08-19 12:31:08 +04:00
bs = g_new0 ( BlockDriverState , 1 ) ;
2013-11-13 14:29:43 +04:00
QLIST_INIT ( & bs - > dirty_bitmaps ) ;
2014-05-23 17:29:42 +04:00
for ( i = 0 ; i < BLOCK_OP_TYPE_MAX ; i + + ) {
QLIST_INIT ( & bs - > op_blockers [ i ] ) ;
}
2023-08-08 18:58:52 +03:00
qemu_mutex_init ( & bs - > reqs_lock ) ;
2017-06-05 15:39:03 +03:00
qemu_mutex_init ( & bs - > dirty_bitmap_mutex ) ;
2013-08-23 05:14:46 +04:00
bs - > refcnt = 1 ;
2014-05-08 18:34:37 +04:00
bs - > aio_context = qemu_get_aio_context ( ) ;
2012-08-23 13:20:36 +04:00
2016-07-18 22:39:52 +03:00
qemu_co_queue_init ( & bs - > flush_queue ) ;
block: block-status cache for data regions
As we have attempted before
(https://lists.gnu.org/archive/html/qemu-devel/2019-01/msg06451.html,
"file-posix: Cache lseek result for data regions";
https://lists.nongnu.org/archive/html/qemu-block/2021-02/msg00934.html,
"file-posix: Cache next hole"), this patch seeks to reduce the number of
SEEK_DATA/HOLE operations the file-posix driver has to perform. The
main difference is that this time it is implemented as part of the
general block layer code.
The problem we face is that on some filesystems or in some
circumstances, SEEK_DATA/HOLE is unreasonably slow. Given the
implementation is outside of qemu, there is little we can do about its
performance.
We have already introduced the want_zero parameter to
bdrv_co_block_status() to reduce the number of SEEK_DATA/HOLE calls
unless we really want zero information; but sometimes we do want that
information, because for files that consist largely of zero areas,
special-casing those areas can give large performance boosts. So the
real problem is with files that consist largely of data, so that
inquiring the block status does not gain us much performance, but where
such an inquiry itself takes a lot of time.
To address this, we want to cache data regions. Most of the time, when
bad performance is reported, it is in places where the image is iterated
over from start to end (qemu-img convert or the mirror job), so a simple
yet effective solution is to cache only the current data region.
(Note that only caching data regions but not zero regions means that
returning false information from the cache is not catastrophic: Treating
zeroes as data is fine. While we try to invalidate the cache on zero
writes and discards, such incongruences may still occur when there are
other processes writing to the image.)
We only use the cache for nodes without children (i.e. protocol nodes),
because that is where the problem is: Drivers that rely on block-status
implementations outside of qemu (e.g. SEEK_DATA/HOLE).
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/307
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
Message-Id: <20210812084148.14458-3-hreitz@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
[hreitz: Added `local_file == bs` assertion, as suggested by Vladimir]
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
2021-08-12 11:41:44 +03:00
qemu_co_mutex_init ( & bs - > bsc_modify_lock ) ;
bs - > block_status_cache = g_new0 ( BdrvBlockStatusCache , 1 ) ;
2018-03-28 19:29:18 +03:00
for ( i = 0 ; i < bdrv_drain_all_count ; i + + ) {
bdrv_drained_begin ( bs ) ;
}
2016-01-29 18:36:11 +03:00
QTAILQ_INSERT_TAIL ( & all_bdrv_states , bs , bs_list ) ;
2004-03-15 00:38:54 +03:00
return bs ;
}
blockdev: Add dynamic module loading for block drivers
Extend the current module interface to allow for block drivers to be
loaded dynamically on request. The only block drivers that can be
converted into modules are the drivers that don't perform any init
operation except for registering themselves.
In addition, only the protocol drivers are being modularized, as they
are the only ones which see significant performance benefits. The format
drivers do not generally link to external libraries, so modularizing
them is of no benefit from a performance perspective.
All the necessary module information is located in a new structure found
in module_block.h
This spoils the purpose of 5505e8b76f (block/dmg: make it modular).
Before this patch, if module build is enabled, block-dmg.so is linked to
libbz2, whereas the main binary is not. In downstream, theoretically, it
means only the qemu-block-extra package depends on libbz2, while the
main QEMU package needn't to. With this patch, we (temporarily) change
the case so that the main QEMU depends on libbz2 again.
Signed-off-by: Marc Marí <markmb@redhat.com>
Signed-off-by: Colin Lord <clord@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: 1471008424-16465-4-git-send-email-clord@redhat.com
Reviewed-by: Max Reitz <mreitz@redhat.com>
[mreitz: Do a signed comparison against the length of
block_driver_modules[], so it will not cause a compile error when
empty]
Signed-off-by: Max Reitz <mreitz@redhat.com>
2016-08-12 16:27:03 +03:00
static BlockDriver * bdrv_do_find_format ( const char * format_name )
2004-08-02 01:59:26 +04:00
{
BlockDriver * drv1 ;
2022-03-03 18:16:02 +03:00
GLOBAL_STATE_CODE ( ) ;
blockdev: Add dynamic module loading for block drivers
Extend the current module interface to allow for block drivers to be
loaded dynamically on request. The only block drivers that can be
converted into modules are the drivers that don't perform any init
operation except for registering themselves.
In addition, only the protocol drivers are being modularized, as they
are the only ones which see significant performance benefits. The format
drivers do not generally link to external libraries, so modularizing
them is of no benefit from a performance perspective.
All the necessary module information is located in a new structure found
in module_block.h
This spoils the purpose of 5505e8b76f (block/dmg: make it modular).
Before this patch, if module build is enabled, block-dmg.so is linked to
libbz2, whereas the main binary is not. In downstream, theoretically, it
means only the qemu-block-extra package depends on libbz2, while the
main QEMU package needn't to. With this patch, we (temporarily) change
the case so that the main QEMU depends on libbz2 again.
Signed-off-by: Marc Marí <markmb@redhat.com>
Signed-off-by: Colin Lord <clord@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: 1471008424-16465-4-git-send-email-clord@redhat.com
Reviewed-by: Max Reitz <mreitz@redhat.com>
[mreitz: Do a signed comparison against the length of
block_driver_modules[], so it will not cause a compile error when
empty]
Signed-off-by: Max Reitz <mreitz@redhat.com>
2016-08-12 16:27:03 +03:00
2010-04-13 13:29:33 +04:00
QLIST_FOREACH ( drv1 , & bdrv_drivers , list ) {
if ( ! strcmp ( drv1 - > format_name , format_name ) ) {
2004-08-02 01:59:26 +04:00
return drv1 ;
2010-04-13 13:29:33 +04:00
}
2004-08-02 01:59:26 +04:00
}
blockdev: Add dynamic module loading for block drivers
Extend the current module interface to allow for block drivers to be
loaded dynamically on request. The only block drivers that can be
converted into modules are the drivers that don't perform any init
operation except for registering themselves.
In addition, only the protocol drivers are being modularized, as they
are the only ones which see significant performance benefits. The format
drivers do not generally link to external libraries, so modularizing
them is of no benefit from a performance perspective.
All the necessary module information is located in a new structure found
in module_block.h
This spoils the purpose of 5505e8b76f (block/dmg: make it modular).
Before this patch, if module build is enabled, block-dmg.so is linked to
libbz2, whereas the main binary is not. In downstream, theoretically, it
means only the qemu-block-extra package depends on libbz2, while the
main QEMU package needn't to. With this patch, we (temporarily) change
the case so that the main QEMU depends on libbz2 again.
Signed-off-by: Marc Marí <markmb@redhat.com>
Signed-off-by: Colin Lord <clord@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: 1471008424-16465-4-git-send-email-clord@redhat.com
Reviewed-by: Max Reitz <mreitz@redhat.com>
[mreitz: Do a signed comparison against the length of
block_driver_modules[], so it will not cause a compile error when
empty]
Signed-off-by: Max Reitz <mreitz@redhat.com>
2016-08-12 16:27:03 +03:00
2004-08-02 01:59:26 +04:00
return NULL ;
}
blockdev: Add dynamic module loading for block drivers
Extend the current module interface to allow for block drivers to be
loaded dynamically on request. The only block drivers that can be
converted into modules are the drivers that don't perform any init
operation except for registering themselves.
In addition, only the protocol drivers are being modularized, as they
are the only ones which see significant performance benefits. The format
drivers do not generally link to external libraries, so modularizing
them is of no benefit from a performance perspective.
All the necessary module information is located in a new structure found
in module_block.h
This spoils the purpose of 5505e8b76f (block/dmg: make it modular).
Before this patch, if module build is enabled, block-dmg.so is linked to
libbz2, whereas the main binary is not. In downstream, theoretically, it
means only the qemu-block-extra package depends on libbz2, while the
main QEMU package needn't to. With this patch, we (temporarily) change
the case so that the main QEMU depends on libbz2 again.
Signed-off-by: Marc Marí <markmb@redhat.com>
Signed-off-by: Colin Lord <clord@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: 1471008424-16465-4-git-send-email-clord@redhat.com
Reviewed-by: Max Reitz <mreitz@redhat.com>
[mreitz: Do a signed comparison against the length of
block_driver_modules[], so it will not cause a compile error when
empty]
Signed-off-by: Max Reitz <mreitz@redhat.com>
2016-08-12 16:27:03 +03:00
BlockDriver * bdrv_find_format ( const char * format_name )
{
BlockDriver * drv1 ;
int i ;
2022-03-03 18:15:49 +03:00
GLOBAL_STATE_CODE ( ) ;
blockdev: Add dynamic module loading for block drivers
Extend the current module interface to allow for block drivers to be
loaded dynamically on request. The only block drivers that can be
converted into modules are the drivers that don't perform any init
operation except for registering themselves.
In addition, only the protocol drivers are being modularized, as they
are the only ones which see significant performance benefits. The format
drivers do not generally link to external libraries, so modularizing
them is of no benefit from a performance perspective.
All the necessary module information is located in a new structure found
in module_block.h
This spoils the purpose of 5505e8b76f (block/dmg: make it modular).
Before this patch, if module build is enabled, block-dmg.so is linked to
libbz2, whereas the main binary is not. In downstream, theoretically, it
means only the qemu-block-extra package depends on libbz2, while the
main QEMU package needn't to. With this patch, we (temporarily) change
the case so that the main QEMU depends on libbz2 again.
Signed-off-by: Marc Marí <markmb@redhat.com>
Signed-off-by: Colin Lord <clord@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: 1471008424-16465-4-git-send-email-clord@redhat.com
Reviewed-by: Max Reitz <mreitz@redhat.com>
[mreitz: Do a signed comparison against the length of
block_driver_modules[], so it will not cause a compile error when
empty]
Signed-off-by: Max Reitz <mreitz@redhat.com>
2016-08-12 16:27:03 +03:00
drv1 = bdrv_do_find_format ( format_name ) ;
if ( drv1 ) {
return drv1 ;
}
/* The driver isn't registered, maybe we need to load a module */
for ( i = 0 ; i < ( int ) ARRAY_SIZE ( block_driver_modules ) ; + + i ) {
if ( ! strcmp ( block_driver_modules [ i ] . format_name , format_name ) ) {
module: add Error arguments to module_load and module_load_qom
improve error handling during module load, by changing:
bool module_load(const char *prefix, const char *lib_name);
void module_load_qom(const char *type);
to:
int module_load(const char *prefix, const char *name, Error **errp);
int module_load_qom(const char *type, Error **errp);
where the return value is:
-1 on module load error, and errp is set with the error
0 on module or one of its dependencies are not installed
1 on module load success
2 on module load success (module already loaded or built-in)
module_load_qom_one has been introduced in:
commit 28457744c345 ("module: qom module support"), which built on top of
module_load_one, but discarded the bool return value. Restore it.
Adapt all callers to emit errors, or ignore them, or fail hard,
as appropriate in each context.
Replace the previous emission of errors via fprintf in _some_ error
conditions with Error and error_report, so as to emit to the appropriate
target.
A memory leak is also fixed as part of the module_load changes.
audio: when attempting to load an audio module, report module load errors.
Note that still for some callers, a single issue may generate multiple
error reports, and this could be improved further.
Regarding the audio code itself, audio_add() seems to ignore errors,
and this should probably be improved.
block: when attempting to load a block module, report module load errors.
For the code paths that already use the Error API, take advantage of those
to report module load errors into the Error parameter.
For the other code paths, we currently emit the error, but this could be
improved further by adding Error parameters to all possible code paths.
console: when attempting to load a display module, report module load errors.
qdev: when creating a new qdev Device object (DeviceState), report load errors.
If a module cannot be loaded to create that device, now abort execution
(if no CONFIG_MODULE) or exit (if CONFIG_MODULE).
qom/object.c: when initializing a QOM object, or looking up class_by_name,
report module load errors.
qtest: when processing the "module_load" qtest command, report errors
in the load of the module.
Signed-off-by: Claudio Fontana <cfontana@suse.de>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20220929093035.4231-4-cfontana@suse.de>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2022-09-29 12:30:33 +03:00
Error * local_err = NULL ;
int rv = block_module_load ( block_driver_modules [ i ] . library_name ,
& local_err ) ;
if ( rv > 0 ) {
return bdrv_do_find_format ( format_name ) ;
} else if ( rv < 0 ) {
error_report_err ( local_err ) ;
}
blockdev: Add dynamic module loading for block drivers
Extend the current module interface to allow for block drivers to be
loaded dynamically on request. The only block drivers that can be
converted into modules are the drivers that don't perform any init
operation except for registering themselves.
In addition, only the protocol drivers are being modularized, as they
are the only ones which see significant performance benefits. The format
drivers do not generally link to external libraries, so modularizing
them is of no benefit from a performance perspective.
All the necessary module information is located in a new structure found
in module_block.h
This spoils the purpose of 5505e8b76f (block/dmg: make it modular).
Before this patch, if module build is enabled, block-dmg.so is linked to
libbz2, whereas the main binary is not. In downstream, theoretically, it
means only the qemu-block-extra package depends on libbz2, while the
main QEMU package needn't to. With this patch, we (temporarily) change
the case so that the main QEMU depends on libbz2 again.
Signed-off-by: Marc Marí <markmb@redhat.com>
Signed-off-by: Colin Lord <clord@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: 1471008424-16465-4-git-send-email-clord@redhat.com
Reviewed-by: Max Reitz <mreitz@redhat.com>
[mreitz: Do a signed comparison against the length of
block_driver_modules[], so it will not cause a compile error when
empty]
Signed-off-by: Max Reitz <mreitz@redhat.com>
2016-08-12 16:27:03 +03:00
break ;
}
}
module: add Error arguments to module_load and module_load_qom
improve error handling during module load, by changing:
bool module_load(const char *prefix, const char *lib_name);
void module_load_qom(const char *type);
to:
int module_load(const char *prefix, const char *name, Error **errp);
int module_load_qom(const char *type, Error **errp);
where the return value is:
-1 on module load error, and errp is set with the error
0 on module or one of its dependencies are not installed
1 on module load success
2 on module load success (module already loaded or built-in)
module_load_qom_one has been introduced in:
commit 28457744c345 ("module: qom module support"), which built on top of
module_load_one, but discarded the bool return value. Restore it.
Adapt all callers to emit errors, or ignore them, or fail hard,
as appropriate in each context.
Replace the previous emission of errors via fprintf in _some_ error
conditions with Error and error_report, so as to emit to the appropriate
target.
A memory leak is also fixed as part of the module_load changes.
audio: when attempting to load an audio module, report module load errors.
Note that still for some callers, a single issue may generate multiple
error reports, and this could be improved further.
Regarding the audio code itself, audio_add() seems to ignore errors,
and this should probably be improved.
block: when attempting to load a block module, report module load errors.
For the code paths that already use the Error API, take advantage of those
to report module load errors into the Error parameter.
For the other code paths, we currently emit the error, but this could be
improved further by adding Error parameters to all possible code paths.
console: when attempting to load a display module, report module load errors.
qdev: when creating a new qdev Device object (DeviceState), report load errors.
If a module cannot be loaded to create that device, now abort execution
(if no CONFIG_MODULE) or exit (if CONFIG_MODULE).
qom/object.c: when initializing a QOM object, or looking up class_by_name,
report module load errors.
qtest: when processing the "module_load" qtest command, report errors
in the load of the module.
Signed-off-by: Claudio Fontana <cfontana@suse.de>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20220929093035.4231-4-cfontana@suse.de>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2022-09-29 12:30:33 +03:00
return NULL ;
blockdev: Add dynamic module loading for block drivers
Extend the current module interface to allow for block drivers to be
loaded dynamically on request. The only block drivers that can be
converted into modules are the drivers that don't perform any init
operation except for registering themselves.
In addition, only the protocol drivers are being modularized, as they
are the only ones which see significant performance benefits. The format
drivers do not generally link to external libraries, so modularizing
them is of no benefit from a performance perspective.
All the necessary module information is located in a new structure found
in module_block.h
This spoils the purpose of 5505e8b76f (block/dmg: make it modular).
Before this patch, if module build is enabled, block-dmg.so is linked to
libbz2, whereas the main binary is not. In downstream, theoretically, it
means only the qemu-block-extra package depends on libbz2, while the
main QEMU package needn't to. With this patch, we (temporarily) change
the case so that the main QEMU depends on libbz2 again.
Signed-off-by: Marc Marí <markmb@redhat.com>
Signed-off-by: Colin Lord <clord@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: 1471008424-16465-4-git-send-email-clord@redhat.com
Reviewed-by: Max Reitz <mreitz@redhat.com>
[mreitz: Do a signed comparison against the length of
block_driver_modules[], so it will not cause a compile error when
empty]
Signed-off-by: Max Reitz <mreitz@redhat.com>
2016-08-12 16:27:03 +03:00
}
2019-03-07 16:33:58 +03:00
static int bdrv_format_is_whitelisted ( const char * format_name , bool read_only )
2009-10-27 20:41:44 +03:00
{
2013-05-29 15:35:40 +04:00
static const char * whitelist_rw [ ] = {
CONFIG_BDRV_RW_WHITELIST
2020-08-04 19:14:26 +03:00
NULL
2013-05-29 15:35:40 +04:00
} ;