qemu-config: add error propagation to qemu_config_parse
This enables some simplification of vl.c via error_fatal, and improves error messages. Before: $ ./qemu-system-x86_64 -readconfig . qemu-system-x86_64: error reading file qemu-system-x86_64: -readconfig .: read config .: Invalid argument $ /usr/libexec/qemu-kvm -readconfig foo qemu-kvm: -readconfig foo: read config foo: No such file or directory After: $ ./qemu-system-x86_64 -readconfig . qemu-system-x86_64: -readconfig .: Cannot read config file: Is a directory $ ./qemu-system-x86_64 -readconfig foo qemu-system-x86_64: -readconfig foo: Could not open 'foo': No such file or directory Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20210226170816.231173-1-pbonzini@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
e20e182ea0
commit
f7544edcd3
@ -279,9 +279,8 @@ static int read_config(BDRVBlkdebugState *s, const char *filename,
|
|||||||
return -errno;
|
return -errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = qemu_config_parse(f, config_groups, filename);
|
ret = qemu_config_parse(f, config_groups, filename, errp);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
error_setg(errp, "Could not parse blkdebug config file");
|
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,9 +11,10 @@ void qemu_add_drive_opts(QemuOptsList *list);
|
|||||||
int qemu_global_option(const char *str);
|
int qemu_global_option(const char *str);
|
||||||
|
|
||||||
void qemu_config_write(FILE *fp);
|
void qemu_config_write(FILE *fp);
|
||||||
int qemu_config_parse(FILE *fp, QemuOptsList **lists, const char *fname);
|
int qemu_config_parse(FILE *fp, QemuOptsList **lists, const char *fname,
|
||||||
|
Error **errp);
|
||||||
|
|
||||||
int qemu_read_config_file(const char *filename);
|
int qemu_read_config_file(const char *filename, Error **errp);
|
||||||
|
|
||||||
/* Parse QDict options as a replacement for a config file (allowing multiple
|
/* Parse QDict options as a replacement for a config file (allowing multiple
|
||||||
enumerated (0..(n-1)) configuration "sections") */
|
enumerated (0..(n-1)) configuration "sections") */
|
||||||
|
27
softmmu/vl.c
27
softmmu/vl.c
@ -2062,17 +2062,19 @@ static int global_init_func(void *opaque, QemuOpts *opts, Error **errp)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int qemu_read_default_config_file(void)
|
static void qemu_read_default_config_file(Error **errp)
|
||||||
{
|
{
|
||||||
|
ERRP_GUARD();
|
||||||
int ret;
|
int ret;
|
||||||
g_autofree char *file = get_relocated_path(CONFIG_QEMU_CONFDIR "/qemu.conf");
|
g_autofree char *file = get_relocated_path(CONFIG_QEMU_CONFDIR "/qemu.conf");
|
||||||
|
|
||||||
ret = qemu_read_config_file(file);
|
ret = qemu_read_config_file(file, errp);
|
||||||
if (ret < 0 && ret != -ENOENT) {
|
if (ret < 0) {
|
||||||
return ret;
|
if (ret == -ENOENT) {
|
||||||
|
error_free(*errp);
|
||||||
|
*errp = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int qemu_set_option(const char *str)
|
static int qemu_set_option(const char *str)
|
||||||
@ -2633,9 +2635,7 @@ void qemu_init(int argc, char **argv, char **envp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (userconfig) {
|
if (userconfig) {
|
||||||
if (qemu_read_default_config_file() < 0) {
|
qemu_read_default_config_file(&error_fatal);
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* second pass of option parsing */
|
/* second pass of option parsing */
|
||||||
@ -3323,15 +3323,8 @@ void qemu_init(int argc, char **argv, char **envp)
|
|||||||
qemu_plugin_opt_parse(optarg, &plugin_list);
|
qemu_plugin_opt_parse(optarg, &plugin_list);
|
||||||
break;
|
break;
|
||||||
case QEMU_OPTION_readconfig:
|
case QEMU_OPTION_readconfig:
|
||||||
{
|
qemu_read_config_file(optarg, &error_fatal);
|
||||||
int ret = qemu_read_config_file(optarg);
|
|
||||||
if (ret < 0) {
|
|
||||||
error_report("read config %s: %s", optarg,
|
|
||||||
strerror(-ret));
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
case QEMU_OPTION_spice:
|
case QEMU_OPTION_spice:
|
||||||
olist = qemu_find_opts_err("spice", NULL);
|
olist = qemu_find_opts_err("spice", NULL);
|
||||||
if (!olist) {
|
if (!olist) {
|
||||||
|
@ -350,7 +350,7 @@ void qemu_config_write(FILE *fp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Returns number of config groups on success, -errno on error */
|
/* Returns number of config groups on success, -errno on error */
|
||||||
int qemu_config_parse(FILE *fp, QemuOptsList **lists, const char *fname)
|
int qemu_config_parse(FILE *fp, QemuOptsList **lists, const char *fname, Error **errp)
|
||||||
{
|
{
|
||||||
char line[1024], group[64], id[64], arg[64], value[1024];
|
char line[1024], group[64], id[64], arg[64], value[1024];
|
||||||
Location loc;
|
Location loc;
|
||||||
@ -375,7 +375,7 @@ int qemu_config_parse(FILE *fp, QemuOptsList **lists, const char *fname)
|
|||||||
/* group with id */
|
/* group with id */
|
||||||
list = find_list(lists, group, &local_err);
|
list = find_list(lists, group, &local_err);
|
||||||
if (local_err) {
|
if (local_err) {
|
||||||
error_report_err(local_err);
|
error_propagate(errp, local_err);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
opts = qemu_opts_create(list, id, 1, NULL);
|
opts = qemu_opts_create(list, id, 1, NULL);
|
||||||
@ -386,7 +386,7 @@ int qemu_config_parse(FILE *fp, QemuOptsList **lists, const char *fname)
|
|||||||
/* group without id */
|
/* group without id */
|
||||||
list = find_list(lists, group, &local_err);
|
list = find_list(lists, group, &local_err);
|
||||||
if (local_err) {
|
if (local_err) {
|
||||||
error_report_err(local_err);
|
error_propagate(errp, local_err);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
opts = qemu_opts_create(list, NULL, 0, &error_abort);
|
opts = qemu_opts_create(list, NULL, 0, &error_abort);
|
||||||
@ -398,21 +398,21 @@ int qemu_config_parse(FILE *fp, QemuOptsList **lists, const char *fname)
|
|||||||
sscanf(line, " %63s = \"\"", arg) == 1) {
|
sscanf(line, " %63s = \"\"", arg) == 1) {
|
||||||
/* arg = value */
|
/* arg = value */
|
||||||
if (opts == NULL) {
|
if (opts == NULL) {
|
||||||
error_report("no group defined");
|
error_setg(errp, "no group defined");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
if (!qemu_opt_set(opts, arg, value, &local_err)) {
|
if (!qemu_opt_set(opts, arg, value, errp)) {
|
||||||
error_report_err(local_err);
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
error_report("parse error");
|
error_setg(errp, "parse error");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
if (ferror(fp)) {
|
if (ferror(fp)) {
|
||||||
error_report("error reading file");
|
loc_pop(&loc);
|
||||||
goto out;
|
error_setg_errno(errp, errno, "Cannot read config file");
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
res = count;
|
res = count;
|
||||||
out:
|
out:
|
||||||
@ -420,16 +420,17 @@ out:
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
int qemu_read_config_file(const char *filename)
|
int qemu_read_config_file(const char *filename, Error **errp)
|
||||||
{
|
{
|
||||||
FILE *f = fopen(filename, "r");
|
FILE *f = fopen(filename, "r");
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (f == NULL) {
|
if (f == NULL) {
|
||||||
|
error_setg_file_open(errp, errno, filename);
|
||||||
return -errno;
|
return -errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = qemu_config_parse(f, vm_config_groups, filename);
|
ret = qemu_config_parse(f, vm_config_groups, filename, errp);
|
||||||
fclose(f);
|
fclose(f);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user