提交 98289620 编写于 作者: K Kevin Wolf

block: Don't parse protocol from file.filename

One of the major reasons for doing something new for -blockdev and
blockdev-add was that the old block layer code parses filenames instead
of just taking them literally. So we should really leave it untouched
when it's passing using the new interfaces (like -drive
file.filename=...).

This allows opening relative file names that contain a colon.
Signed-off-by: NKevin Wolf <kwolf@redhat.com>
Reviewed-by: NEric Blake <eblake@redhat.com>
上级 de90930a
...@@ -417,7 +417,7 @@ int bdrv_create_file(const char* filename, QEMUOptionParameter *options) ...@@ -417,7 +417,7 @@ int bdrv_create_file(const char* filename, QEMUOptionParameter *options)
{ {
BlockDriver *drv; BlockDriver *drv;
drv = bdrv_find_protocol(filename); drv = bdrv_find_protocol(filename, true);
if (drv == NULL) { if (drv == NULL) {
return -ENOENT; return -ENOENT;
} }
...@@ -482,7 +482,8 @@ static BlockDriver *find_hdev_driver(const char *filename) ...@@ -482,7 +482,8 @@ static BlockDriver *find_hdev_driver(const char *filename)
return drv; return drv;
} }
BlockDriver *bdrv_find_protocol(const char *filename) BlockDriver *bdrv_find_protocol(const char *filename,
bool allow_protocol_prefix)
{ {
BlockDriver *drv1; BlockDriver *drv1;
char protocol[128]; char protocol[128];
...@@ -503,9 +504,10 @@ BlockDriver *bdrv_find_protocol(const char *filename) ...@@ -503,9 +504,10 @@ BlockDriver *bdrv_find_protocol(const char *filename)
return drv1; return drv1;
} }
if (!path_has_protocol(filename)) { if (!path_has_protocol(filename) || !allow_protocol_prefix) {
return bdrv_find_format("file"); return bdrv_find_format("file");
} }
p = strchr(filename, ':'); p = strchr(filename, ':');
assert(p != NULL); assert(p != NULL);
len = p - filename; len = p - filename;
...@@ -784,6 +786,7 @@ int bdrv_file_open(BlockDriverState **pbs, const char *filename, ...@@ -784,6 +786,7 @@ int bdrv_file_open(BlockDriverState **pbs, const char *filename,
BlockDriverState *bs; BlockDriverState *bs;
BlockDriver *drv; BlockDriver *drv;
const char *drvname; const char *drvname;
bool allow_protocol_prefix = false;
int ret; int ret;
/* NULL means an empty set of options */ /* NULL means an empty set of options */
...@@ -800,6 +803,7 @@ int bdrv_file_open(BlockDriverState **pbs, const char *filename, ...@@ -800,6 +803,7 @@ int bdrv_file_open(BlockDriverState **pbs, const char *filename,
filename = qdict_get_try_str(options, "filename"); filename = qdict_get_try_str(options, "filename");
} else if (filename && !qdict_haskey(options, "filename")) { } else if (filename && !qdict_haskey(options, "filename")) {
qdict_put(options, "filename", qstring_from_str(filename)); qdict_put(options, "filename", qstring_from_str(filename));
allow_protocol_prefix = true;
} else { } else {
qerror_report(ERROR_CLASS_GENERIC_ERROR, "Can't specify 'file' and " qerror_report(ERROR_CLASS_GENERIC_ERROR, "Can't specify 'file' and "
"'filename' options at the same time"); "'filename' options at the same time");
...@@ -813,7 +817,10 @@ int bdrv_file_open(BlockDriverState **pbs, const char *filename, ...@@ -813,7 +817,10 @@ int bdrv_file_open(BlockDriverState **pbs, const char *filename,
drv = bdrv_find_whitelisted_format(drvname, !(flags & BDRV_O_RDWR)); drv = bdrv_find_whitelisted_format(drvname, !(flags & BDRV_O_RDWR));
qdict_del(options, "driver"); qdict_del(options, "driver");
} else if (filename) { } else if (filename) {
drv = bdrv_find_protocol(filename); drv = bdrv_find_protocol(filename, allow_protocol_prefix);
if (!drv) {
qerror_report(ERROR_CLASS_GENERIC_ERROR, "Unknown protocol");
}
} else { } else {
qerror_report(ERROR_CLASS_GENERIC_ERROR, qerror_report(ERROR_CLASS_GENERIC_ERROR,
"Must specify either driver or file"); "Must specify either driver or file");
...@@ -4452,7 +4459,7 @@ void bdrv_img_create(const char *filename, const char *fmt, ...@@ -4452,7 +4459,7 @@ void bdrv_img_create(const char *filename, const char *fmt,
return; return;
} }
proto_drv = bdrv_find_protocol(filename); proto_drv = bdrv_find_protocol(filename, true);
if (!proto_drv) { if (!proto_drv) {
error_setg(errp, "Unknown protocol '%s'", filename); error_setg(errp, "Unknown protocol '%s'", filename);
return; return;
......
...@@ -1510,7 +1510,7 @@ static int sd_create(const char *filename, QEMUOptionParameter *options) ...@@ -1510,7 +1510,7 @@ static int sd_create(const char *filename, QEMUOptionParameter *options)
BlockDriver *drv; BlockDriver *drv;
/* Currently, only Sheepdog backing image is supported. */ /* Currently, only Sheepdog backing image is supported. */
drv = bdrv_find_protocol(backing_file); drv = bdrv_find_protocol(backing_file, true);
if (!drv || strcmp(drv->protocol_name, "sheepdog") != 0) { if (!drv || strcmp(drv->protocol_name, "sheepdog") != 0) {
error_report("backing_file must be a sheepdog image"); error_report("backing_file must be a sheepdog image");
ret = -EINVAL; ret = -EINVAL;
......
...@@ -111,7 +111,8 @@ bool bdrv_io_limits_enabled(BlockDriverState *bs); ...@@ -111,7 +111,8 @@ bool bdrv_io_limits_enabled(BlockDriverState *bs);
void bdrv_init(void); void bdrv_init(void);
void bdrv_init_with_whitelist(void); void bdrv_init_with_whitelist(void);
BlockDriver *bdrv_find_protocol(const char *filename); BlockDriver *bdrv_find_protocol(const char *filename,
bool allow_protocol_prefix);
BlockDriver *bdrv_find_format(const char *format_name); BlockDriver *bdrv_find_format(const char *format_name);
BlockDriver *bdrv_find_whitelisted_format(const char *format_name, BlockDriver *bdrv_find_whitelisted_format(const char *format_name,
bool readonly); bool readonly);
......
...@@ -240,7 +240,7 @@ static int print_block_option_help(const char *filename, const char *fmt) ...@@ -240,7 +240,7 @@ static int print_block_option_help(const char *filename, const char *fmt)
return 1; return 1;
} }
proto_drv = bdrv_find_protocol(filename); proto_drv = bdrv_find_protocol(filename, true);
if (!proto_drv) { if (!proto_drv) {
error_report("Unknown protocol '%s'", filename); error_report("Unknown protocol '%s'", filename);
return 1; return 1;
...@@ -1261,7 +1261,7 @@ static int img_convert(int argc, char **argv) ...@@ -1261,7 +1261,7 @@ static int img_convert(int argc, char **argv)
goto out; goto out;
} }
proto_drv = bdrv_find_protocol(out_filename); proto_drv = bdrv_find_protocol(out_filename, true);
if (!proto_drv) { if (!proto_drv) {
error_report("Unknown protocol '%s'", out_filename); error_report("Unknown protocol '%s'", out_filename);
ret = -1; ret = -1;
......
...@@ -149,6 +149,18 @@ echo ...@@ -149,6 +149,18 @@ echo
run_qemu -drive file=$TEST_IMG,file.driver=file run_qemu -drive file=$TEST_IMG,file.driver=file
run_qemu -drive file=$TEST_IMG,file.driver=qcow2 run_qemu -drive file=$TEST_IMG,file.driver=qcow2
echo
echo === Parsing protocol from file name ===
echo
# Protocol strings are supposed to be parsed from traditional option strings,
# but not when using driver-specific options. We can distinguish them by the
# error message for non-existing files.
run_qemu -hda foo:bar
run_qemu -drive file=foo:bar
run_qemu -drive file.filename=foo:bar
# success, all done # success, all done
echo "*** done" echo "*** done"
rm -f $seq.full rm -f $seq.full
......
...@@ -169,4 +169,18 @@ Testing: -drive file=TEST_DIR/t.qcow2,file.driver=qcow2 ...@@ -169,4 +169,18 @@ Testing: -drive file=TEST_DIR/t.qcow2,file.driver=qcow2
QEMU_PROG: -drive file=TEST_DIR/t.qcow2,file.driver=qcow2: Can't use 'qcow2' as a block driver for the protocol level QEMU_PROG: -drive file=TEST_DIR/t.qcow2,file.driver=qcow2: Can't use 'qcow2' as a block driver for the protocol level
QEMU_PROG: -drive file=TEST_DIR/t.qcow2,file.driver=qcow2: could not open disk image TEST_DIR/t.qcow2: Invalid argument QEMU_PROG: -drive file=TEST_DIR/t.qcow2,file.driver=qcow2: could not open disk image TEST_DIR/t.qcow2: Invalid argument
=== Parsing protocol from file name ===
Testing: -hda foo:bar
QEMU_PROG: -hda foo:bar: Unknown protocol
QEMU_PROG: -hda foo:bar: could not open disk image foo:bar: No such file or directory
Testing: -drive file=foo:bar
QEMU_PROG: -drive file=foo:bar: Unknown protocol
QEMU_PROG: -drive file=foo:bar: could not open disk image foo:bar: No such file or directory
Testing: -drive file.filename=foo:bar
QEMU_PROG: -drive file.filename=foo:bar: could not open disk image ide0-hd0: No such file or directory
*** done *** done
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册