summaryrefslogtreecommitdiffstats
path: root/block.c
diff options
context:
space:
mode:
authorChristoph Hellwig2009-06-15 13:55:19 +0200
committerChristoph Hellwig2009-06-15 13:55:19 +0200
commitf3a5d3f8a1a992376e3dd128ceee917cd1281da7 (patch)
tree52182d1855b05d0f16868bcd0a5a742ea3e9bfe6 /block.c
parentraw-posix: add a raw_open_common helper (diff)
downloadqemu-f3a5d3f8a1a992376e3dd128ceee917cd1281da7.tar.gz
qemu-f3a5d3f8a1a992376e3dd128ceee917cd1281da7.tar.xz
qemu-f3a5d3f8a1a992376e3dd128ceee917cd1281da7.zip
raw-posix: split hdev drivers
Instead of declaring one BlockDriver for all host devices declared one for each type: a generic one for normal disk devices, a Linux floppy driver and a CDROM driver for Linux and FreeBSD. This gets rid of a lot of messy ifdefs and switching based on the type in the various removal device methods. block.c grows a new method to find the correct host device driver based on OS-sepcific criteria, which will later into the actual drivers in a later patch in this series. Signed-off-by: Christoph Hellwig <hch@lst.de>
Diffstat (limited to 'block.c')
-rw-r--r--block.c60
1 files changed, 43 insertions, 17 deletions
diff --git a/block.c b/block.c
index e6b91c60ac..2e2059333c 100644
--- a/block.c
+++ b/block.c
@@ -249,32 +249,55 @@ static BlockDriver *find_protocol(const char *filename)
return NULL;
}
-/* XXX: force raw format if block or character device ? It would
- simplify the BSD case */
-static BlockDriver *find_image_format(const char *filename)
+/*
+ * Detect host devices. By convention, /dev/cdrom[N] is always
+ * recognized as a host CDROM.
+ */
+#ifdef _WIN32
+static BlockDriver *find_hdev_driver(const char *filename)
{
- int ret, score, score_max;
- BlockDriver *drv1, *drv;
- uint8_t buf[2048];
- BlockDriverState *bs;
-
- /* detect host devices. By convention, /dev/cdrom[N] is always
- recognized as a host CDROM */
if (strstart(filename, "/dev/cdrom", NULL))
return bdrv_find_format("host_device");
-#ifdef _WIN32
if (is_windows_drive(filename))
return bdrv_find_format("host_device");
+ return NULL;
+}
#else
- {
- struct stat st;
- if (stat(filename, &st) >= 0 &&
+static BlockDriver *find_hdev_driver(const char *filename)
+{
+ struct stat st;
+
+#ifdef __linux__
+ if (strstart(filename, "/dev/fd", NULL))
+ return bdrv_find_format("host_floppy");
+ if (strstart(filename, "/dev/cd", NULL))
+ return bdrv_find_format("host_cdrom");
+#elif defined(__FreeBSD__)
+ if (strstart(filename, "/dev/cd", NULL) ||
+ strstart(filename, "/dev/acd", NULL)) {
+ return bdrv_find_format("host_cdrom");
+ }
+#else
+ if (strstart(filename, "/dev/cdrom", NULL))
+ return bdrv_find_format("host_device");
+#endif
+
+ if (stat(filename, &st) >= 0 &&
(S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode))) {
- return bdrv_find_format("host_device");
- }
+ return bdrv_find_format("host_device");
}
+
+ return NULL;
+}
#endif
+static BlockDriver *find_image_format(const char *filename)
+{
+ int ret, score, score_max;
+ BlockDriver *drv1, *drv;
+ uint8_t buf[2048];
+ BlockDriverState *bs;
+
drv = find_protocol(filename);
/* no need to test disk image formats for vvfat */
if (drv && strcmp(drv->format_name, "vvfat") == 0)
@@ -394,7 +417,10 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags,
if (flags & BDRV_O_FILE) {
drv = find_protocol(filename);
} else if (!drv) {
- drv = find_image_format(filename);
+ drv = find_hdev_driver(filename);
+ if (!drv) {
+ drv = find_image_format(filename);
+ }
}
if (!drv) {
ret = -ENOENT;