summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarkus Armbruster <armbru@redhat.com>2009-07-28 23:31:58 +0200
committerEduardo Habkost <ehabkost@redhat.com>2009-07-29 11:43:31 -0300
commit448844a369d533dbebf3e282c44f650f9903680d (patch)
tree4d6980935ea5d195a500444ab8995c5318e04163
parentdfe5ae0887b74fa7507a13dfa3f620334a67f89d (diff)
Disable unsupported block formats
We get block drivers in two ways: the user explicitly specifies one, or he lets QEMU probe the image. Explicit specification is easy. It always goes through bdrv_find_format(). Utility programs and QEMU proper use different call sites. Change QEMU's to use bdrv_find_supported_format() instead, which filters out unsupported formats. Probing is a bit more complicated. We can't just get rid of the unsupported formats, because that makes probing fall back to raw (I'm simplifying, but it'll do to illustrate the problem). We don't want to fall back, we want to reject the image as unsupported. Insert a check for supportedness between probing and opening in bdrv_open2(). Fail if unsupported. This makes a probed image that calls for an unsupported format fail similar to an image that can't be opened. This check also catches any use of an unsupported block driver that wasn't directly requested by the user, e.g. a qcow2 backing file with protocol "fat:". This patch identical to my previous one, except it leaves the "host_device" block driver enabled. Without that, -cdrom /dev/cdrom is rejected as unsupported. Please ACK. Message-ID: <87ws5ssddd.fsf_-_@pike.pond.sub.org> Signed-off-by: Eduardo Habkost <ehabkost@redhat.com> Bugzilla: 512837 Obsoletes: <87y6qgqnc1.fsf@pike.pond.sub.org> Obsoletes: <528ddc93c31408561b1ad838a0fb518d4be81930.1248207933.git.quintela@redhat.com> Obsoletes: <b8c2bdbe25f43b4d0e0e95a0044cca4c31e505c7.1248095798.git.quintela@redhat.com> Acked-by: Juan Quintela <quintela@redhat.com> Acked-by: Dor Laor <dlaor@redhat.com> Acked-by: Kevin Wolf <kwolf@redhat.com>
-rw-r--r--qemu/block.c34
-rw-r--r--qemu/block.h2
-rw-r--r--qemu/hw/usb-msd.c2
-rw-r--r--qemu/monitor.c2
-rw-r--r--qemu/vl.c4
5 files changed, 39 insertions, 5 deletions
diff --git a/qemu/block.c b/qemu/block.c
index d506b838..b5704da0 100644
--- a/qemu/block.c
+++ b/qemu/block.c
@@ -64,6 +64,8 @@ BlockDriverState *bdrv_first;
static BlockDriver *first_drv;
+static int only_supported_bdrv;
+
int path_is_absolute(const char *path)
{
const char *p;
@@ -175,6 +177,27 @@ BlockDriver *bdrv_find_format(const char *format_name)
return NULL;
}
+static int bdrv_is_supported(BlockDriver *drv)
+{
+ static const char *supported[] = {
+ "raw", "qcow2", "nbd", "host_device", NULL
+ };
+ const char **p;
+
+ for (p = supported; *p; p++) {
+ if (!strcmp(drv->format_name, *p)) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+BlockDriver *bdrv_find_supported_format(const char *format_name)
+{
+ BlockDriver *drv = bdrv_find_format(format_name);
+ return drv && bdrv_is_supported(drv) ? drv : NULL;
+}
+
int bdrv_create2(BlockDriver *drv,
const char *filename, int64_t size_in_sectors,
const char *backing_file, const char *backing_format,
@@ -431,7 +454,10 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags,
open_flags = BDRV_O_RDWR | (flags & BDRV_O_CACHE_MASK);
else
open_flags = flags & ~(BDRV_O_FILE | BDRV_O_SNAPSHOT);
- ret = drv->bdrv_open(bs, filename, open_flags);
+ if (only_supported_bdrv && !bdrv_is_supported(drv))
+ ret = -ENOTSUP;
+ else
+ ret = drv->bdrv_open(bs, filename, open_flags);
if ((ret == -EACCES || ret == -EPERM) && !(flags & BDRV_O_FILE)) {
ret = drv->bdrv_open(bs, filename, open_flags & ~BDRV_O_RDWR);
bs->read_only = 1;
@@ -1557,6 +1583,12 @@ void bdrv_init(void)
bdrv_register(&bdrv_nbd);
}
+void bdrv_init_supported_only(void)
+{
+ only_supported_bdrv = 1;
+ bdrv_init();
+}
+
void *qemu_aio_get(BlockDriverState *bs, BlockDriverCompletionFunc *cb,
void *opaque)
{
diff --git a/qemu/block.h b/qemu/block.h
index d93c1c64..662082af 100644
--- a/qemu/block.h
+++ b/qemu/block.h
@@ -54,7 +54,9 @@ void bdrv_info(void);
void bdrv_info_stats(void);
void bdrv_init(void);
+void bdrv_init_supported_only(void);
BlockDriver *bdrv_find_format(const char *format_name);
+BlockDriver *bdrv_find_supported_format(const char *format_name);
int bdrv_create(BlockDriver *drv,
const char *filename, int64_t size_in_sectors,
const char *backing_file, int flags);
diff --git a/qemu/hw/usb-msd.c b/qemu/hw/usb-msd.c
index f7ad25e6..143cdc5b 100644
--- a/qemu/hw/usb-msd.c
+++ b/qemu/hw/usb-msd.c
@@ -529,7 +529,7 @@ USBDevice *usb_msd_init(const char *filename)
int len = MIN(p1 - p2, sizeof(fmt));
pstrcpy(fmt, len, p2);
- drv = bdrv_find_format(fmt);
+ drv = bdrv_find_supported_format(fmt);
if (!drv) {
printf("invalid format %s\n", fmt);
return NULL;
diff --git a/qemu/monitor.c b/qemu/monitor.c
index 1b1c939e..219f6132 100644
--- a/qemu/monitor.c
+++ b/qemu/monitor.c
@@ -543,7 +543,7 @@ static void do_change_block(const char *device, const char *filename, const char
return;
}
if (fmt) {
- drv = bdrv_find_format(fmt);
+ drv = bdrv_find_supported_format(fmt);
if (!drv) {
term_printf("invalid format %s\n", fmt);
return;
diff --git a/qemu/vl.c b/qemu/vl.c
index 3062006c..bfa2b323 100644
--- a/qemu/vl.c
+++ b/qemu/vl.c
@@ -2548,7 +2548,7 @@ int drive_init(struct drive_opt *arg, int snapshot,
fprintf(stderr, "\n");
return -1;
}
- drv = bdrv_find_format(buf);
+ drv = bdrv_find_supported_format(buf);
if (!drv) {
fprintf(stderr, "qemu: '%s' invalid format\n", buf);
return -1;
@@ -6160,7 +6160,7 @@ int main(int argc, char **argv, char **envp)
ksm_register_memory();
- bdrv_init();
+ bdrv_init_supported_only();
/* we always create the cdrom drive, even if no disk is there */