block: add bdrv_probe_device method
Add a bdrv_probe_device method to all BlockDriver instances implementing host devices to move matching of host device types into the actual drivers. For now we keep exacly the old matching behaviour based on the devices names, although we really should have better detetion methods based on device information in the future. Signed-off-by: Christoph Hellwig <hch@lst.de>
This commit is contained in:
parent
f3a5d3f8a1
commit
508c7cb3fa
44
block.c
44
block.c
@ -209,7 +209,7 @@ static int is_windows_drive_prefix(const char *filename)
|
||||
filename[1] == ':');
|
||||
}
|
||||
|
||||
static int is_windows_drive(const char *filename)
|
||||
int is_windows_drive(const char *filename)
|
||||
{
|
||||
if (is_windows_drive_prefix(filename) &&
|
||||
filename[2] == '\0')
|
||||
@ -253,43 +253,23 @@ static BlockDriver *find_protocol(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)
|
||||
{
|
||||
if (strstart(filename, "/dev/cdrom", NULL))
|
||||
return bdrv_find_format("host_device");
|
||||
if (is_windows_drive(filename))
|
||||
return bdrv_find_format("host_device");
|
||||
return NULL;
|
||||
}
|
||||
#else
|
||||
static BlockDriver *find_hdev_driver(const char *filename)
|
||||
{
|
||||
struct stat st;
|
||||
int score_max = 0, score;
|
||||
BlockDriver *drv = NULL, *d;
|
||||
|
||||
#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");
|
||||
for (d = first_drv; d; d = d->next) {
|
||||
if (d->bdrv_probe_device) {
|
||||
score = d->bdrv_probe_device(filename);
|
||||
if (score > score_max) {
|
||||
score_max = score;
|
||||
drv = d;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return drv;
|
||||
}
|
||||
#endif
|
||||
|
||||
static BlockDriver *find_image_format(const char *filename)
|
||||
{
|
||||
|
@ -953,6 +953,22 @@ kern_return_t GetBSDPath( io_iterator_t mediaIterator, char *bsdPath, CFIndex ma
|
||||
|
||||
#endif
|
||||
|
||||
static int hdev_probe_device(const char *filename)
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
/* allow a dedicated CD-ROM driver to match with a higher priority */
|
||||
if (strstart(filename, "/dev/cdrom", NULL))
|
||||
return 50;
|
||||
|
||||
if (stat(filename, &st) >= 0 &&
|
||||
(S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode))) {
|
||||
return 100;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hdev_open(BlockDriverState *bs, const char *filename, int flags)
|
||||
{
|
||||
BDRVRawState *s = bs->opaque;
|
||||
@ -1152,6 +1168,7 @@ static int hdev_create(const char *filename, QEMUOptionParameter *options)
|
||||
static BlockDriver bdrv_host_device = {
|
||||
.format_name = "host_device",
|
||||
.instance_size = sizeof(BDRVRawState),
|
||||
.bdrv_probe_device = hdev_probe_device,
|
||||
.bdrv_open = hdev_open,
|
||||
.bdrv_close = raw_close,
|
||||
.bdrv_create = hdev_create,
|
||||
@ -1197,6 +1214,14 @@ static int floppy_open(BlockDriverState *bs, const char *filename, int flags)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int floppy_probe_device(const char *filename)
|
||||
{
|
||||
if (strstart(filename, "/dev/fd", NULL))
|
||||
return 100;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int floppy_is_inserted(BlockDriverState *bs)
|
||||
{
|
||||
return fd_open(bs) >= 0;
|
||||
@ -1242,6 +1267,7 @@ static int floppy_eject(BlockDriverState *bs, int eject_flag)
|
||||
static BlockDriver bdrv_host_floppy = {
|
||||
.format_name = "host_floppy",
|
||||
.instance_size = sizeof(BDRVRawState),
|
||||
.bdrv_probe_device = floppy_probe_device,
|
||||
.bdrv_open = floppy_open,
|
||||
.bdrv_close = raw_close,
|
||||
.bdrv_create = hdev_create,
|
||||
@ -1279,6 +1305,13 @@ static int cdrom_open(BlockDriverState *bs, const char *filename, int flags)
|
||||
return raw_open_common(bs, filename, flags);
|
||||
}
|
||||
|
||||
static int cdrom_probe_device(const char *filename)
|
||||
{
|
||||
if (strstart(filename, "/dev/cd", NULL))
|
||||
return 100;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cdrom_is_inserted(BlockDriverState *bs)
|
||||
{
|
||||
BDRVRawState *s = bs->opaque;
|
||||
@ -1323,6 +1356,7 @@ static int cdrom_set_locked(BlockDriverState *bs, int locked)
|
||||
static BlockDriver bdrv_host_cdrom = {
|
||||
.format_name = "host_cdrom",
|
||||
.instance_size = sizeof(BDRVRawState),
|
||||
.bdrv_probe_device = cdrom_probe_device,
|
||||
.bdrv_open = cdrom_open,
|
||||
.bdrv_close = raw_close,
|
||||
.bdrv_create = hdev_create,
|
||||
@ -1367,6 +1401,14 @@ static int cdrom_open(BlockDriverState *bs, const char *filename, int flags)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cdrom_probe_device(const char *filename)
|
||||
{
|
||||
if (strstart(filename, "/dev/cd", NULL) ||
|
||||
strstart(filename, "/dev/acd", NULL))
|
||||
return 100;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cdrom_reopen(BlockDriverState *bs)
|
||||
{
|
||||
BDRVRawState *s = bs->opaque;
|
||||
@ -1437,6 +1479,7 @@ static int cdrom_set_locked(BlockDriverState *bs, int locked)
|
||||
static BlockDriver bdrv_host_cdrom = {
|
||||
.format_name = "host_cdrom",
|
||||
.instance_size = sizeof(BDRVRawState),
|
||||
.bdrv_probe_device = cdrom_probe_device,
|
||||
.bdrv_open = cdrom_open,
|
||||
.bdrv_close = raw_close,
|
||||
.bdrv_create = hdev_create,
|
||||
@ -1466,6 +1509,10 @@ static BlockDriver bdrv_host_cdrom = {
|
||||
|
||||
static void bdrv_raw_init(void)
|
||||
{
|
||||
/*
|
||||
* Register all the drivers. Note that order is important, the driver
|
||||
* registered last will get probed first.
|
||||
*/
|
||||
bdrv_register(&bdrv_raw);
|
||||
bdrv_register(&bdrv_host_device);
|
||||
#ifdef __linux__
|
||||
|
@ -306,6 +306,15 @@ static int find_device_type(BlockDriverState *bs, const char *filename)
|
||||
}
|
||||
}
|
||||
|
||||
static int hdev_probe_device(const char *filename)
|
||||
{
|
||||
if (strstart(filename, "/dev/cdrom", NULL))
|
||||
return 100;
|
||||
if (is_windows_drive(filename))
|
||||
return 100;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hdev_open(BlockDriverState *bs, const char *filename, int flags)
|
||||
{
|
||||
BDRVRawState *s = bs->opaque;
|
||||
@ -391,6 +400,7 @@ static int raw_set_locked(BlockDriverState *bs, int locked)
|
||||
static BlockDriver bdrv_host_device = {
|
||||
.format_name = "host_device",
|
||||
.instance_size = sizeof(BDRVRawState),
|
||||
.bdrv_probe_device = hdev_probe_device,
|
||||
.bdrv_open = hdev_open,
|
||||
.bdrv_close = raw_close,
|
||||
.bdrv_flush = raw_flush,
|
||||
|
@ -48,6 +48,7 @@ struct BlockDriver {
|
||||
const char *format_name;
|
||||
int instance_size;
|
||||
int (*bdrv_probe)(const uint8_t *buf, int buf_size, const char *filename);
|
||||
int (*bdrv_probe_device)(const char *filename);
|
||||
int (*bdrv_open)(BlockDriverState *bs, const char *filename, int flags);
|
||||
int (*bdrv_read)(BlockDriverState *bs, int64_t sector_num,
|
||||
uint8_t *buf, int nb_sectors);
|
||||
@ -177,4 +178,8 @@ void *qemu_blockalign(BlockDriverState *bs, size_t size);
|
||||
|
||||
extern BlockDriverState *bdrv_first;
|
||||
|
||||
#ifdef _WIN32
|
||||
int is_windows_drive(const char *filename);
|
||||
#endif
|
||||
|
||||
#endif /* BLOCK_INT_H */
|
||||
|
Loading…
Reference in New Issue
Block a user