2009-07-31 14:25:35 +04:00
|
|
|
#include "qemu-common.h"
|
|
|
|
#include "qemu-option.h"
|
|
|
|
#include "qemu-config.h"
|
2009-09-25 23:42:40 +04:00
|
|
|
#include "sysemu.h"
|
2009-07-31 14:25:35 +04:00
|
|
|
|
|
|
|
QemuOptsList qemu_drive_opts = {
|
|
|
|
.name = "drive",
|
2009-09-12 11:36:22 +04:00
|
|
|
.head = QTAILQ_HEAD_INITIALIZER(qemu_drive_opts.head),
|
2009-07-31 14:25:35 +04:00
|
|
|
.desc = {
|
|
|
|
{
|
|
|
|
.name = "bus",
|
|
|
|
.type = QEMU_OPT_NUMBER,
|
|
|
|
.help = "bus number",
|
|
|
|
},{
|
|
|
|
.name = "unit",
|
|
|
|
.type = QEMU_OPT_NUMBER,
|
|
|
|
.help = "unit number (i.e. lun for scsi)",
|
|
|
|
},{
|
|
|
|
.name = "if",
|
|
|
|
.type = QEMU_OPT_STRING,
|
|
|
|
.help = "interface (ide, scsi, sd, mtd, floppy, pflash, virtio)",
|
|
|
|
},{
|
|
|
|
.name = "index",
|
|
|
|
.type = QEMU_OPT_NUMBER,
|
|
|
|
},{
|
|
|
|
.name = "cyls",
|
|
|
|
.type = QEMU_OPT_NUMBER,
|
|
|
|
.help = "number of cylinders (ide disk geometry)",
|
|
|
|
},{
|
|
|
|
.name = "heads",
|
|
|
|
.type = QEMU_OPT_NUMBER,
|
|
|
|
.help = "number of heads (ide disk geometry)",
|
|
|
|
},{
|
|
|
|
.name = "secs",
|
|
|
|
.type = QEMU_OPT_NUMBER,
|
|
|
|
.help = "number of sectors (ide disk geometry)",
|
|
|
|
},{
|
|
|
|
.name = "trans",
|
|
|
|
.type = QEMU_OPT_STRING,
|
|
|
|
.help = "chs translation (auto, lba. none)",
|
|
|
|
},{
|
|
|
|
.name = "media",
|
|
|
|
.type = QEMU_OPT_STRING,
|
|
|
|
.help = "media type (disk, cdrom)",
|
|
|
|
},{
|
|
|
|
.name = "snapshot",
|
|
|
|
.type = QEMU_OPT_BOOL,
|
|
|
|
},{
|
|
|
|
.name = "file",
|
|
|
|
.type = QEMU_OPT_STRING,
|
|
|
|
.help = "disk image",
|
|
|
|
},{
|
|
|
|
.name = "cache",
|
|
|
|
.type = QEMU_OPT_STRING,
|
|
|
|
.help = "host cache usage (none, writeback, writethrough)",
|
2009-08-20 18:58:35 +04:00
|
|
|
},{
|
|
|
|
.name = "aio",
|
|
|
|
.type = QEMU_OPT_STRING,
|
|
|
|
.help = "host AIO implementation (threads, native)",
|
2009-07-31 14:25:35 +04:00
|
|
|
},{
|
|
|
|
.name = "format",
|
|
|
|
.type = QEMU_OPT_STRING,
|
|
|
|
.help = "disk format (raw, qcow2, ...)",
|
|
|
|
},{
|
|
|
|
.name = "serial",
|
|
|
|
.type = QEMU_OPT_STRING,
|
|
|
|
},{
|
|
|
|
.name = "werror",
|
|
|
|
.type = QEMU_OPT_STRING,
|
|
|
|
},{
|
|
|
|
.name = "addr",
|
|
|
|
.type = QEMU_OPT_STRING,
|
|
|
|
.help = "pci address (virtio only)",
|
|
|
|
},
|
|
|
|
{ /* end if list */ }
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2009-09-10 12:58:35 +04:00
|
|
|
QemuOptsList qemu_chardev_opts = {
|
|
|
|
.name = "chardev",
|
2009-09-12 11:36:22 +04:00
|
|
|
.head = QTAILQ_HEAD_INITIALIZER(qemu_chardev_opts.head),
|
2009-09-10 12:58:35 +04:00
|
|
|
.desc = {
|
2009-09-10 12:58:36 +04:00
|
|
|
{
|
|
|
|
.name = "backend",
|
|
|
|
.type = QEMU_OPT_STRING,
|
|
|
|
},{
|
|
|
|
.name = "path",
|
|
|
|
.type = QEMU_OPT_STRING,
|
2009-09-10 12:58:42 +04:00
|
|
|
},{
|
|
|
|
.name = "host",
|
|
|
|
.type = QEMU_OPT_STRING,
|
|
|
|
},{
|
|
|
|
.name = "port",
|
|
|
|
.type = QEMU_OPT_STRING,
|
2009-09-10 12:58:51 +04:00
|
|
|
},{
|
|
|
|
.name = "localaddr",
|
|
|
|
.type = QEMU_OPT_STRING,
|
|
|
|
},{
|
|
|
|
.name = "localport",
|
|
|
|
.type = QEMU_OPT_STRING,
|
2009-09-10 12:58:42 +04:00
|
|
|
},{
|
|
|
|
.name = "to",
|
|
|
|
.type = QEMU_OPT_NUMBER,
|
|
|
|
},{
|
|
|
|
.name = "ipv4",
|
|
|
|
.type = QEMU_OPT_BOOL,
|
|
|
|
},{
|
|
|
|
.name = "ipv6",
|
|
|
|
.type = QEMU_OPT_BOOL,
|
|
|
|
},{
|
|
|
|
.name = "wait",
|
|
|
|
.type = QEMU_OPT_BOOL,
|
|
|
|
},{
|
|
|
|
.name = "server",
|
|
|
|
.type = QEMU_OPT_BOOL,
|
|
|
|
},{
|
|
|
|
.name = "delay",
|
|
|
|
.type = QEMU_OPT_BOOL,
|
|
|
|
},{
|
|
|
|
.name = "telnet",
|
|
|
|
.type = QEMU_OPT_BOOL,
|
2009-09-10 12:58:49 +04:00
|
|
|
},{
|
|
|
|
.name = "width",
|
|
|
|
.type = QEMU_OPT_NUMBER,
|
|
|
|
},{
|
|
|
|
.name = "height",
|
|
|
|
.type = QEMU_OPT_NUMBER,
|
|
|
|
},{
|
|
|
|
.name = "cols",
|
|
|
|
.type = QEMU_OPT_NUMBER,
|
|
|
|
},{
|
|
|
|
.name = "rows",
|
|
|
|
.type = QEMU_OPT_NUMBER,
|
2009-09-10 12:58:52 +04:00
|
|
|
},{
|
|
|
|
.name = "mux",
|
|
|
|
.type = QEMU_OPT_BOOL,
|
2009-09-10 12:58:36 +04:00
|
|
|
},
|
2009-09-10 12:58:35 +04:00
|
|
|
{ /* end if list */ }
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2009-07-31 14:25:37 +04:00
|
|
|
QemuOptsList qemu_device_opts = {
|
|
|
|
.name = "device",
|
2009-09-12 11:36:22 +04:00
|
|
|
.head = QTAILQ_HEAD_INITIALIZER(qemu_device_opts.head),
|
2009-07-31 14:25:37 +04:00
|
|
|
.desc = {
|
|
|
|
/*
|
|
|
|
* no elements => accept any
|
|
|
|
* sanity checking will happen later
|
|
|
|
* when setting device properties
|
|
|
|
*/
|
|
|
|
{ /* end if list */ }
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2009-10-08 22:58:26 +04:00
|
|
|
QemuOptsList qemu_netdev_opts = {
|
|
|
|
.name = "netdev",
|
|
|
|
.head = QTAILQ_HEAD_INITIALIZER(qemu_netdev_opts.head),
|
|
|
|
.desc = {
|
|
|
|
/*
|
|
|
|
* no elements => accept any params
|
|
|
|
* validation will happen later
|
|
|
|
*/
|
|
|
|
{ /* end of list */ }
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2009-10-06 15:17:05 +04:00
|
|
|
QemuOptsList qemu_net_opts = {
|
|
|
|
.name = "net",
|
|
|
|
.head = QTAILQ_HEAD_INITIALIZER(qemu_net_opts.head),
|
|
|
|
.desc = {
|
|
|
|
/*
|
|
|
|
* no elements => accept any params
|
|
|
|
* validation will happen later
|
|
|
|
*/
|
|
|
|
{ /* end of list */ }
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2009-09-15 15:36:04 +04:00
|
|
|
QemuOptsList qemu_rtc_opts = {
|
|
|
|
.name = "rtc",
|
|
|
|
.head = QTAILQ_HEAD_INITIALIZER(qemu_rtc_opts.head),
|
|
|
|
.desc = {
|
|
|
|
{
|
|
|
|
.name = "base",
|
|
|
|
.type = QEMU_OPT_STRING,
|
2009-09-15 15:36:04 +04:00
|
|
|
},{
|
|
|
|
.name = "clock",
|
|
|
|
.type = QEMU_OPT_STRING,
|
2009-09-15 15:36:04 +04:00
|
|
|
#ifdef TARGET_I386
|
|
|
|
},{
|
|
|
|
.name = "driftfix",
|
|
|
|
.type = QEMU_OPT_STRING,
|
|
|
|
#endif
|
|
|
|
},
|
|
|
|
{ /* end if list */ }
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2009-07-31 14:25:36 +04:00
|
|
|
static QemuOptsList *lists[] = {
|
|
|
|
&qemu_drive_opts,
|
2009-09-10 12:58:35 +04:00
|
|
|
&qemu_chardev_opts,
|
2009-07-31 14:25:37 +04:00
|
|
|
&qemu_device_opts,
|
2009-10-08 22:58:26 +04:00
|
|
|
&qemu_netdev_opts,
|
2009-10-06 15:17:05 +04:00
|
|
|
&qemu_net_opts,
|
2009-10-06 15:16:50 +04:00
|
|
|
&qemu_rtc_opts,
|
2009-07-31 14:25:36 +04:00
|
|
|
NULL,
|
|
|
|
};
|
|
|
|
|
|
|
|
int qemu_set_option(const char *str)
|
|
|
|
{
|
|
|
|
char group[64], id[64], arg[64];
|
|
|
|
QemuOpts *opts;
|
|
|
|
int i, rc, offset;
|
|
|
|
|
|
|
|
rc = sscanf(str, "%63[^.].%63[^.].%63[^=]%n", group, id, arg, &offset);
|
|
|
|
if (rc < 3 || str[offset] != '=') {
|
2009-09-25 23:42:40 +04:00
|
|
|
qemu_error("can't parse: \"%s\"\n", str);
|
2009-07-31 14:25:36 +04:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; lists[i] != NULL; i++) {
|
|
|
|
if (strcmp(lists[i]->name, group) == 0)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (lists[i] == NULL) {
|
2009-09-25 23:42:40 +04:00
|
|
|
qemu_error("there is no option group \"%s\"\n", group);
|
2009-07-31 14:25:36 +04:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
opts = qemu_opts_find(lists[i], id);
|
|
|
|
if (!opts) {
|
2009-09-25 23:42:40 +04:00
|
|
|
qemu_error("there is no %s \"%s\" defined\n",
|
2009-07-31 14:25:36 +04:00
|
|
|
lists[i]->name, id);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2009-09-23 14:24:05 +04:00
|
|
|
if (qemu_opt_set(opts, arg, str+offset+1) == -1) {
|
2009-07-31 14:25:36 +04:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|