1 #include "qemu/osdep.h"
2 #include "block/qdict.h" /* for qdict_extract_subqdict() */
3 #include "qapi/error.h"
4 #include "qapi/qmp/qdict.h"
5 #include "qapi/qmp/qlist.h"
6 #include "qemu/error-report.h"
7 #include "qemu/option.h"
8 #include "qemu/config-file.h"
10 QemuOptsList
*vm_config_groups
[48];
11 QemuOptsList
*drive_config_groups
[5];
13 static QemuOptsList
*find_list(QemuOptsList
**lists
, const char *group
,
18 qemu_load_module_for_opts(group
);
19 for (i
= 0; lists
[i
] != NULL
; i
++) {
20 if (strcmp(lists
[i
]->name
, group
) == 0)
23 if (lists
[i
] == NULL
) {
24 error_setg(errp
, "There is no option group '%s'", group
);
29 QemuOptsList
*qemu_find_opts(const char *group
)
32 Error
*local_err
= NULL
;
34 ret
= find_list(vm_config_groups
, group
, &local_err
);
36 error_report_err(local_err
);
42 QemuOpts
*qemu_find_opts_singleton(const char *group
)
47 list
= qemu_find_opts(group
);
49 opts
= qemu_opts_find(list
, NULL
);
51 opts
= qemu_opts_create(list
, NULL
, 0, &error_abort
);
56 QemuOptsList
*qemu_find_opts_err(const char *group
, Error
**errp
)
58 return find_list(vm_config_groups
, group
, errp
);
61 void qemu_add_drive_opts(QemuOptsList
*list
)
65 entries
= ARRAY_SIZE(drive_config_groups
);
66 entries
--; /* keep list NULL terminated */
67 for (i
= 0; i
< entries
; i
++) {
68 if (drive_config_groups
[i
] == NULL
) {
69 drive_config_groups
[i
] = list
;
73 fprintf(stderr
, "ran out of space in drive_config_groups");
77 void qemu_add_opts(QemuOptsList
*list
)
81 entries
= ARRAY_SIZE(vm_config_groups
);
82 entries
--; /* keep list NULL terminated */
83 for (i
= 0; i
< entries
; i
++) {
84 if (vm_config_groups
[i
] == NULL
) {
85 vm_config_groups
[i
] = list
;
89 fprintf(stderr
, "ran out of space in vm_config_groups");
93 /* Returns number of config groups on success, -errno on error */
94 static int qemu_config_foreach(FILE *fp
, QEMUConfigCB
*cb
, void *opaque
,
95 const char *fname
, Error
**errp
)
98 char line
[1024], prev_group
[64], group
[64], arg
[64], value
[1024];
101 int res
= -EINVAL
, lno
= 0;
105 while (fgets(line
, sizeof(line
), fp
) != NULL
) {
107 if (line
[0] == '\n') {
108 /* skip empty lines */
111 if (line
[0] == '#') {
115 if (line
[0] == '[') {
117 if (sscanf(line
, "[%63s \"%63[^\"]\"]", group
, value
) == 2) {
119 qdict_put_str(qdict
, "id", value
);
121 } else if (sscanf(line
, "[%63[^]]]", group
) == 1) {
127 cb(prev_group
, prev
, opaque
, errp
);
133 strcpy(prev_group
, group
);
137 loc_set_file(fname
, lno
);
139 if (sscanf(line
, " %63s = \"%1023[^\"]\"", arg
, value
) == 2 ||
140 sscanf(line
, " %63s = \"\"", arg
) == 1) {
143 error_setg(errp
, "no group defined");
146 qdict_put_str(qdict
, arg
, value
);
149 error_setg(errp
, "parse error");
154 error_setg_errno(errp
, errno
, "Cannot read config file");
159 cb(group
, qdict
, opaque
, errp
);
164 qobject_unref(qdict
);
168 void qemu_config_do_parse(const char *group
, QDict
*qdict
, void *opaque
, Error
**errp
)
170 QemuOptsList
**lists
= opaque
;
173 list
= find_list(lists
, group
, errp
);
178 qemu_opts_from_qdict(list
, qdict
, errp
);
181 int qemu_config_parse(FILE *fp
, QemuOptsList
**lists
, const char *fname
, Error
**errp
)
183 return qemu_config_foreach(fp
, qemu_config_do_parse
, lists
, fname
, errp
);
186 int qemu_read_config_file(const char *filename
, QEMUConfigCB
*cb
, Error
**errp
)
188 FILE *f
= fopen(filename
, "r");
192 error_setg_file_open(errp
, errno
, filename
);
196 ret
= qemu_config_foreach(f
, cb
, vm_config_groups
, filename
, errp
);
201 static bool config_parse_qdict_section(QDict
*options
, QemuOptsList
*opts
,
205 g_autoptr(QDict
) subqdict
= NULL
;
206 g_autoptr(QList
) list
= NULL
;
207 size_t orig_size
, enum_size
;
210 prefix
= g_strdup_printf("%s.", opts
->name
);
211 qdict_extract_subqdict(options
, &subqdict
, prefix
);
213 orig_size
= qdict_size(subqdict
);
218 subopts
= qemu_opts_create(opts
, NULL
, 0, errp
);
223 if (!qemu_opts_absorb_qdict(subopts
, subqdict
, errp
)) {
227 enum_size
= qdict_size(subqdict
);
228 if (enum_size
< orig_size
&& enum_size
) {
229 error_setg(errp
, "Unknown option '%s' for [%s]",
230 qdict_first(subqdict
)->key
, opts
->name
);
235 /* Multiple, enumerated sections */
236 QListEntry
*list_entry
;
239 /* Not required anymore */
240 qemu_opts_del(subopts
);
242 qdict_array_split(subqdict
, &list
);
243 if (qdict_size(subqdict
)) {
244 error_setg(errp
, "Unused option '%s' for [%s]",
245 qdict_first(subqdict
)->key
, opts
->name
);
249 QLIST_FOREACH_ENTRY(list
, list_entry
) {
250 QDict
*section
= qobject_to(QDict
, qlist_entry_obj(list_entry
));
254 error_setg(errp
, "[%s] section (index %u) does not consist of "
255 "keys", opts
->name
, i
);
259 opt_name
= g_strdup_printf("%s.%u", opts
->name
, i
++);
260 subopts
= qemu_opts_create(opts
, opt_name
, 1, errp
);
266 if (!qemu_opts_absorb_qdict(subopts
, section
, errp
)) {
267 qemu_opts_del(subopts
);
271 if (qdict_size(section
)) {
272 error_setg(errp
, "[%s] section doesn't support the option '%s'",
273 opts
->name
, qdict_first(section
)->key
);
274 qemu_opts_del(subopts
);
283 bool qemu_config_parse_qdict(QDict
*options
, QemuOptsList
**lists
,
288 for (i
= 0; lists
[i
]; i
++) {
289 if (!config_parse_qdict_section(options
, lists
[i
], errp
)) {