]> Git Repo - qemu.git/blob - qemu-config.c
configure: Fix spelling in comment and rework the comment
[qemu.git] / qemu-config.c
1 #include "qemu-common.h"
2 #include "qemu-option.h"
3 #include "qemu-config.h"
4 #include "sysemu.h"
5
6 QemuOptsList qemu_drive_opts = {
7     .name = "drive",
8     .head = QTAILQ_HEAD_INITIALIZER(qemu_drive_opts.head),
9     .desc = {
10         {
11             .name = "bus",
12             .type = QEMU_OPT_NUMBER,
13             .help = "bus number",
14         },{
15             .name = "unit",
16             .type = QEMU_OPT_NUMBER,
17             .help = "unit number (i.e. lun for scsi)",
18         },{
19             .name = "if",
20             .type = QEMU_OPT_STRING,
21             .help = "interface (ide, scsi, sd, mtd, floppy, pflash, virtio)",
22         },{
23             .name = "index",
24             .type = QEMU_OPT_NUMBER,
25         },{
26             .name = "cyls",
27             .type = QEMU_OPT_NUMBER,
28             .help = "number of cylinders (ide disk geometry)",
29         },{
30             .name = "heads",
31             .type = QEMU_OPT_NUMBER,
32             .help = "number of heads (ide disk geometry)",
33         },{
34             .name = "secs",
35             .type = QEMU_OPT_NUMBER,
36             .help = "number of sectors (ide disk geometry)",
37         },{
38             .name = "trans",
39             .type = QEMU_OPT_STRING,
40             .help = "chs translation (auto, lba. none)",
41         },{
42             .name = "media",
43             .type = QEMU_OPT_STRING,
44             .help = "media type (disk, cdrom)",
45         },{
46             .name = "snapshot",
47             .type = QEMU_OPT_BOOL,
48         },{
49             .name = "file",
50             .type = QEMU_OPT_STRING,
51             .help = "disk image",
52         },{
53             .name = "cache",
54             .type = QEMU_OPT_STRING,
55             .help = "host cache usage (none, writeback, writethrough)",
56         },{
57             .name = "aio",
58             .type = QEMU_OPT_STRING,
59             .help = "host AIO implementation (threads, native)",
60         },{
61             .name = "format",
62             .type = QEMU_OPT_STRING,
63             .help = "disk format (raw, qcow2, ...)",
64         },{
65             .name = "serial",
66             .type = QEMU_OPT_STRING,
67         },{
68             .name = "werror",
69             .type = QEMU_OPT_STRING,
70         },{
71             .name = "addr",
72             .type = QEMU_OPT_STRING,
73             .help = "pci address (virtio only)",
74         },{
75             .name = "readonly",
76             .type = QEMU_OPT_BOOL,
77         },
78         { /* end if list */ }
79     },
80 };
81
82 QemuOptsList qemu_chardev_opts = {
83     .name = "chardev",
84     .head = QTAILQ_HEAD_INITIALIZER(qemu_chardev_opts.head),
85     .desc = {
86         {
87             .name = "backend",
88             .type = QEMU_OPT_STRING,
89         },{
90             .name = "path",
91             .type = QEMU_OPT_STRING,
92         },{
93             .name = "host",
94             .type = QEMU_OPT_STRING,
95         },{
96             .name = "port",
97             .type = QEMU_OPT_STRING,
98         },{
99             .name = "localaddr",
100             .type = QEMU_OPT_STRING,
101         },{
102             .name = "localport",
103             .type = QEMU_OPT_STRING,
104         },{
105             .name = "to",
106             .type = QEMU_OPT_NUMBER,
107         },{
108             .name = "ipv4",
109             .type = QEMU_OPT_BOOL,
110         },{
111             .name = "ipv6",
112             .type = QEMU_OPT_BOOL,
113         },{
114             .name = "wait",
115             .type = QEMU_OPT_BOOL,
116         },{
117             .name = "server",
118             .type = QEMU_OPT_BOOL,
119         },{
120             .name = "delay",
121             .type = QEMU_OPT_BOOL,
122         },{
123             .name = "telnet",
124             .type = QEMU_OPT_BOOL,
125         },{
126             .name = "width",
127             .type = QEMU_OPT_NUMBER,
128         },{
129             .name = "height",
130             .type = QEMU_OPT_NUMBER,
131         },{
132             .name = "cols",
133             .type = QEMU_OPT_NUMBER,
134         },{
135             .name = "rows",
136             .type = QEMU_OPT_NUMBER,
137         },{
138             .name = "mux",
139             .type = QEMU_OPT_BOOL,
140         },{
141             .name = "signal",
142             .type = QEMU_OPT_BOOL,
143         },
144         { /* end if list */ }
145     },
146 };
147
148 QemuOptsList qemu_device_opts = {
149     .name = "device",
150     .head = QTAILQ_HEAD_INITIALIZER(qemu_device_opts.head),
151     .desc = {
152         /*
153          * no elements => accept any
154          * sanity checking will happen later
155          * when setting device properties
156          */
157         { /* end if list */ }
158     },
159 };
160
161 QemuOptsList qemu_netdev_opts = {
162     .name = "netdev",
163     .head = QTAILQ_HEAD_INITIALIZER(qemu_netdev_opts.head),
164     .desc = {
165         /*
166          * no elements => accept any params
167          * validation will happen later
168          */
169         { /* end of list */ }
170     },
171 };
172
173 QemuOptsList qemu_net_opts = {
174     .name = "net",
175     .head = QTAILQ_HEAD_INITIALIZER(qemu_net_opts.head),
176     .desc = {
177         /*
178          * no elements => accept any params
179          * validation will happen later
180          */
181         { /* end of list */ }
182     },
183 };
184
185 QemuOptsList qemu_rtc_opts = {
186     .name = "rtc",
187     .head = QTAILQ_HEAD_INITIALIZER(qemu_rtc_opts.head),
188     .desc = {
189         {
190             .name = "base",
191             .type = QEMU_OPT_STRING,
192         },{
193             .name = "clock",
194             .type = QEMU_OPT_STRING,
195 #ifdef TARGET_I386
196         },{
197             .name = "driftfix",
198             .type = QEMU_OPT_STRING,
199 #endif
200         },
201         { /* end if list */ }
202     },
203 };
204
205 static QemuOptsList *lists[] = {
206     &qemu_drive_opts,
207     &qemu_chardev_opts,
208     &qemu_device_opts,
209     &qemu_netdev_opts,
210     &qemu_net_opts,
211     &qemu_rtc_opts,
212     NULL,
213 };
214
215 static QemuOptsList *find_list(const char *group)
216 {
217     int i;
218
219     for (i = 0; lists[i] != NULL; i++) {
220         if (strcmp(lists[i]->name, group) == 0)
221             break;
222     }
223     if (lists[i] == NULL) {
224         qemu_error("there is no option group \"%s\"\n", group);
225     }
226     return lists[i];
227 }
228
229 int qemu_set_option(const char *str)
230 {
231     char group[64], id[64], arg[64];
232     QemuOptsList *list;
233     QemuOpts *opts;
234     int rc, offset;
235
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);
239         return -1;
240     }
241
242     list = find_list(group);
243     if (list == NULL) {
244         return -1;
245     }
246
247     opts = qemu_opts_find(list, id);
248     if (!opts) {
249         qemu_error("there is no %s \"%s\" defined\n",
250                    list->name, id);
251         return -1;
252     }
253
254     if (qemu_opt_set(opts, arg, str+offset+1) == -1) {
255         return -1;
256     }
257     return 0;
258 }
259
260 struct ConfigWriteData {
261     QemuOptsList *list;
262     FILE *fp;
263 };
264
265 static int config_write_opt(const char *name, const char *value, void *opaque)
266 {
267     struct ConfigWriteData *data = opaque;
268
269     fprintf(data->fp, "  %s = \"%s\"\n", name, value);
270     return 0;
271 }
272
273 static int config_write_opts(QemuOpts *opts, void *opaque)
274 {
275     struct ConfigWriteData *data = opaque;
276     const char *id = qemu_opts_id(opts);
277
278     if (id) {
279         fprintf(data->fp, "[%s \"%s\"]\n", data->list->name, id);
280     } else {
281         fprintf(data->fp, "[%s]\n", data->list->name);
282     }
283     qemu_opt_foreach(opts, config_write_opt, data, 0);
284     fprintf(data->fp, "\n");
285     return 0;
286 }
287
288 void qemu_config_write(FILE *fp)
289 {
290     struct ConfigWriteData data = { .fp = fp };
291     int i;
292
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);
297     }
298 }
299
300 int qemu_config_parse(FILE *fp)
301 {
302     char line[1024], group[64], id[64], arg[64], value[1024];
303     QemuOptsList *list = NULL;
304     QemuOpts *opts = NULL;
305
306     while (fgets(line, sizeof(line), fp) != NULL) {
307         if (line[0] == '\n') {
308             /* skip empty lines */
309             continue;
310         }
311         if (line[0] == '#') {
312             /* comment */
313             continue;
314         }
315         if (sscanf(line, "[%63s \"%63[^\"]\"]", group, id) == 2) {
316             /* group with id */
317             list = find_list(group);
318             if (list == NULL)
319                 return -1;
320             opts = qemu_opts_create(list, id, 1);
321             continue;
322         }
323         if (sscanf(line, "[%63[^]]]", group) == 1) {
324             /* group without id */
325             list = find_list(group);
326             if (list == NULL)
327                 return -1;
328             opts = qemu_opts_create(list, NULL, 0);
329             continue;
330         }
331         if (sscanf(line, " %63s = \"%1023[^\"]\"", arg, value) == 2) {
332             /* arg = value */
333             if (opts == NULL) {
334                 fprintf(stderr, "no group defined\n");
335                 return -1;
336             }
337             if (qemu_opt_set(opts, arg, value) != 0) {
338                 fprintf(stderr, "failed to set \"%s\" for %s\n",
339                         arg, group);
340                 return -1;
341             }
342             continue;
343         }
344         fprintf(stderr, "parse error: %s\n", line);
345         return -1;
346     }
347     return 0;
348 }
This page took 0.042685 seconds and 4 git commands to generate.