1 #include "qemu-common.h"
2 #include "qemu-option.h"
3 #include "qemu-config.h"
6 QemuOptsList qemu_drive_opts = {
8 .head = QTAILQ_HEAD_INITIALIZER(qemu_drive_opts.head),
12 .type = QEMU_OPT_NUMBER,
16 .type = QEMU_OPT_NUMBER,
17 .help = "unit number (i.e. lun for scsi)",
20 .type = QEMU_OPT_STRING,
21 .help = "interface (ide, scsi, sd, mtd, floppy, pflash, virtio)",
24 .type = QEMU_OPT_NUMBER,
27 .type = QEMU_OPT_NUMBER,
28 .help = "number of cylinders (ide disk geometry)",
31 .type = QEMU_OPT_NUMBER,
32 .help = "number of heads (ide disk geometry)",
35 .type = QEMU_OPT_NUMBER,
36 .help = "number of sectors (ide disk geometry)",
39 .type = QEMU_OPT_STRING,
40 .help = "chs translation (auto, lba. none)",
43 .type = QEMU_OPT_STRING,
44 .help = "media type (disk, cdrom)",
47 .type = QEMU_OPT_BOOL,
50 .type = QEMU_OPT_STRING,
54 .type = QEMU_OPT_STRING,
55 .help = "host cache usage (none, writeback, writethrough)",
58 .type = QEMU_OPT_STRING,
59 .help = "host AIO implementation (threads, native)",
62 .type = QEMU_OPT_STRING,
63 .help = "disk format (raw, qcow2, ...)",
66 .type = QEMU_OPT_STRING,
69 .type = QEMU_OPT_STRING,
72 .type = QEMU_OPT_STRING,
73 .help = "pci address (virtio only)",
76 .type = QEMU_OPT_BOOL,
82 QemuOptsList qemu_chardev_opts = {
84 .head = QTAILQ_HEAD_INITIALIZER(qemu_chardev_opts.head),
88 .type = QEMU_OPT_STRING,
91 .type = QEMU_OPT_STRING,
94 .type = QEMU_OPT_STRING,
97 .type = QEMU_OPT_STRING,
100 .type = QEMU_OPT_STRING,
103 .type = QEMU_OPT_STRING,
106 .type = QEMU_OPT_NUMBER,
109 .type = QEMU_OPT_BOOL,
112 .type = QEMU_OPT_BOOL,
115 .type = QEMU_OPT_BOOL,
118 .type = QEMU_OPT_BOOL,
121 .type = QEMU_OPT_BOOL,
124 .type = QEMU_OPT_BOOL,
127 .type = QEMU_OPT_NUMBER,
130 .type = QEMU_OPT_NUMBER,
133 .type = QEMU_OPT_NUMBER,
136 .type = QEMU_OPT_NUMBER,
139 .type = QEMU_OPT_BOOL,
142 .type = QEMU_OPT_BOOL,
144 { /* end if list */ }
148 QemuOptsList qemu_device_opts = {
150 .head = QTAILQ_HEAD_INITIALIZER(qemu_device_opts.head),
153 * no elements => accept any
154 * sanity checking will happen later
155 * when setting device properties
157 { /* end if list */ }
161 QemuOptsList qemu_netdev_opts = {
163 .head = QTAILQ_HEAD_INITIALIZER(qemu_netdev_opts.head),
166 * no elements => accept any params
167 * validation will happen later
169 { /* end of list */ }
173 QemuOptsList qemu_net_opts = {
175 .head = QTAILQ_HEAD_INITIALIZER(qemu_net_opts.head),
178 * no elements => accept any params
179 * validation will happen later
181 { /* end of list */ }
185 QemuOptsList qemu_rtc_opts = {
187 .head = QTAILQ_HEAD_INITIALIZER(qemu_rtc_opts.head),
191 .type = QEMU_OPT_STRING,
194 .type = QEMU_OPT_STRING,
198 .type = QEMU_OPT_STRING,
201 { /* end if list */ }
205 static QemuOptsList *lists[] = {
215 static QemuOptsList *find_list(const char *group)
219 for (i = 0; lists[i] != NULL; i++) {
220 if (strcmp(lists[i]->name, group) == 0)
223 if (lists[i] == NULL) {
224 qemu_error("there is no option group \"%s\"\n", group);
229 int qemu_set_option(const char *str)
231 char group[64], id[64], arg[64];
236 rc = sscanf(str, "%63[^.].%63[^.].%63[^=]%n", group, id, arg, &offset);
237 if (rc < 3 || str[offset] != '=') {
238 qemu_error("can't parse: \"%s\"\n", str);
242 list = find_list(group);
247 opts = qemu_opts_find(list, id);
249 qemu_error("there is no %s \"%s\" defined\n",
254 if (qemu_opt_set(opts, arg, str+offset+1) == -1) {
260 struct ConfigWriteData {
265 static int config_write_opt(const char *name, const char *value, void *opaque)
267 struct ConfigWriteData *data = opaque;
269 fprintf(data->fp, " %s = \"%s\"\n", name, value);
273 static int config_write_opts(QemuOpts *opts, void *opaque)
275 struct ConfigWriteData *data = opaque;
276 const char *id = qemu_opts_id(opts);
279 fprintf(data->fp, "[%s \"%s\"]\n", data->list->name, id);
281 fprintf(data->fp, "[%s]\n", data->list->name);
283 qemu_opt_foreach(opts, config_write_opt, data, 0);
284 fprintf(data->fp, "\n");
288 void qemu_config_write(FILE *fp)
290 struct ConfigWriteData data = { .fp = fp };
293 fprintf(fp, "# qemu config file\n\n");
294 for (i = 0; lists[i] != NULL; i++) {
295 data.list = lists[i];
296 qemu_opts_foreach(data.list, config_write_opts, &data, 0);
300 int qemu_config_parse(FILE *fp)
302 char line[1024], group[64], id[64], arg[64], value[1024];
303 QemuOptsList *list = NULL;
304 QemuOpts *opts = NULL;
306 while (fgets(line, sizeof(line), fp) != NULL) {
307 if (line[0] == '\n') {
308 /* skip empty lines */
311 if (line[0] == '#') {
315 if (sscanf(line, "[%63s \"%63[^\"]\"]", group, id) == 2) {
317 list = find_list(group);
320 opts = qemu_opts_create(list, id, 1);
323 if (sscanf(line, "[%63[^]]]", group) == 1) {
324 /* group without id */
325 list = find_list(group);
328 opts = qemu_opts_create(list, NULL, 0);
331 if (sscanf(line, " %63s = \"%1023[^\"]\"", arg, value) == 2) {
334 fprintf(stderr, "no group defined\n");
337 if (qemu_opt_set(opts, arg, value) != 0) {
338 fprintf(stderr, "failed to set \"%s\" for %s\n",
344 fprintf(stderr, "parse error: %s\n", line);