[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH] block: add read only to whitelist
From: |
Stefan Hajnoczi |
Subject: |
Re: [Qemu-devel] [PATCH] block: add read only to whitelist |
Date: |
Tue, 28 May 2013 10:02:46 +0200 |
User-agent: |
Mutt/1.5.21 (2010-09-15) |
On Tue, May 28, 2013 at 02:44:26PM +0800, Fam Zheng wrote:
> We may want to include a driver in the whitelist for read only tasks
> such as diagnosing or exporting guest data (with libguestfs as a good
> example). This patch introduces the magic prefix ^ to include a driver
> to the whitelist, but only enables qemu to open specific image
> format readonly, and returns -ENOTSUP for RW opening.
>
> Example: To include vmdk readonly, and others read+write:
> ./configure --block-drv-whitelist=qcow2,raw,file,qed,^vmdk
This is great, thanks for tackling this. block/vmdk.c isn't suitable
for running real VMs (read-write) since it's not optimized for
concurrent I/O but it is usable for libguestfs (read-only).
> Signed-off-by: Fam Zheng <address@hidden>
> ---
> block.c | 43 +++++++++++++++++++++++++++----------------
> blockdev.c | 4 ++--
> configure | 2 ++
> include/block/block.h | 3 ++-
> scripts/create_config | 9 ++++++++-
> 5 files changed, 41 insertions(+), 20 deletions(-)
>
> diff --git a/block.c b/block.c
> index 3f87489..e6a7270 100644
> --- a/block.c
> +++ b/block.c
> @@ -328,28 +328,40 @@ BlockDriver *bdrv_find_format(const char *format_name)
> return NULL;
> }
>
> -static int bdrv_is_whitelisted(BlockDriver *drv)
> +static int bdrv_is_whitelisted(BlockDriver *drv, bool read_only)
> {
> - static const char *whitelist[] = {
> - CONFIG_BDRV_WHITELIST
> + static const char *whitelist_rw[] = {
> + CONFIG_BDRV_WHITELIST_RW
> + };
> + static const char *whitelist_ro[] = {
> + CONFIG_BDRV_WHITELIST_RO
> };
> const char **p;
Please also make the ./configure lists separate. The funky ^ syntax is
not obvious. Better to have:
./configure --block-drv-whitelist-rw=qcow2,raw,file,qed \
--block-drv-whitelist-ro=vmdk,vpc
>
> - if (!whitelist[0])
> + if (!whitelist_rw[0] && !whitelist_ro[0]) {
> return 1; /* no whitelist, anything goes */
> + }
>
> - for (p = whitelist; *p; p++) {
> + for (p = whitelist_rw; *p; p++) {
> if (!strcmp(drv->format_name, *p)) {
> return 1;
> }
> }
> + if (read_only) {
> + for (p = whitelist_ro; *p; p++) {
> + if (!strcmp(drv->format_name, *p)) {
> + return 1;
> + }
> + }
> + }
> return 0;
> }
>
> -BlockDriver *bdrv_find_whitelisted_format(const char *format_name)
> +BlockDriver *bdrv_find_whitelisted_format(const char *format_name,
> + bool read_only)
> {
> BlockDriver *drv = bdrv_find_format(format_name);
> - return drv && bdrv_is_whitelisted(drv) ? drv : NULL;
> + return drv && bdrv_is_whitelisted(drv, read_only) ? drv : NULL;
> }
>
> typedef struct CreateCo {
> @@ -684,10 +696,6 @@ static int bdrv_open_common(BlockDriverState *bs,
> BlockDriverState *file,
>
> trace_bdrv_open_common(bs, filename ?: "", flags, drv->format_name);
>
> - if (use_bdrv_whitelist && !bdrv_is_whitelisted(drv)) {
> - return -ENOTSUP;
> - }
> -
> /* bdrv_open() with directly using a protocol as drv. This layer is
> already
> * opened, so assign it to bs (while file becomes a closed
> BlockDriverState)
> * and return immediately. */
if (file != NULL && drv->bdrv_file_open) {
bdrv_swap(file, bs);
return 0;
}
I think your change is okay. You moved the check after this early
return, but file is already opened so we passed the whitelist check
already. This is a little tricky but it seems fine.
Stefan