qemu-config.c 7.3 KB
Newer Older
G
Gerd Hoffmann 已提交
1 2 3
#include "qemu-common.h"
#include "qemu-option.h"
#include "qemu-config.h"
G
Gerd Hoffmann 已提交
4
#include "sysemu.h"
G
Gerd Hoffmann 已提交
5 6 7

QemuOptsList qemu_drive_opts = {
    .name = "drive",
B
Blue Swirl 已提交
8
    .head = QTAILQ_HEAD_INITIALIZER(qemu_drive_opts.head),
G
Gerd Hoffmann 已提交
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
    .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)",
56 57 58 59
        },{
            .name = "aio",
            .type = QEMU_OPT_STRING,
            .help = "host AIO implementation (threads, native)",
G
Gerd Hoffmann 已提交
60 61 62 63 64 65 66 67 68 69 70 71 72 73
        },{
            .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)",
74 75 76
        },{
            .name = "readonly",
            .type = QEMU_OPT_BOOL,
G
Gerd Hoffmann 已提交
77 78 79 80 81
        },
        { /* end if list */ }
    },
};

82 83
QemuOptsList qemu_chardev_opts = {
    .name = "chardev",
B
Blue Swirl 已提交
84
    .head = QTAILQ_HEAD_INITIALIZER(qemu_chardev_opts.head),
85
    .desc = {
86 87 88 89 90 91
        {
            .name = "backend",
            .type = QEMU_OPT_STRING,
        },{
            .name = "path",
            .type = QEMU_OPT_STRING,
92 93 94 95 96 97
        },{
            .name = "host",
            .type = QEMU_OPT_STRING,
        },{
            .name = "port",
            .type = QEMU_OPT_STRING,
G
Gerd Hoffmann 已提交
98 99 100 101 102 103
        },{
            .name = "localaddr",
            .type = QEMU_OPT_STRING,
        },{
            .name = "localport",
            .type = QEMU_OPT_STRING,
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
        },{
            .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,
G
Gerd Hoffmann 已提交
125 126 127 128 129 130 131 132 133 134 135 136
        },{
            .name = "width",
            .type = QEMU_OPT_NUMBER,
        },{
            .name = "height",
            .type = QEMU_OPT_NUMBER,
        },{
            .name = "cols",
            .type = QEMU_OPT_NUMBER,
        },{
            .name = "rows",
            .type = QEMU_OPT_NUMBER,
G
Gerd Hoffmann 已提交
137 138 139
        },{
            .name = "mux",
            .type = QEMU_OPT_BOOL,
140 141 142
        },{
            .name = "signal",
            .type = QEMU_OPT_BOOL,
143
        },
144 145 146 147
        { /* end if list */ }
    },
};

G
Gerd Hoffmann 已提交
148 149
QemuOptsList qemu_device_opts = {
    .name = "device",
B
Blue Swirl 已提交
150
    .head = QTAILQ_HEAD_INITIALIZER(qemu_device_opts.head),
G
Gerd Hoffmann 已提交
151 152 153 154 155 156 157 158 159 160
    .desc = {
        /*
         * no elements => accept any
         * sanity checking will happen later
         * when setting device properties
         */
        { /* end if list */ }
    },
};

M
Mark McLoughlin 已提交
161 162 163 164 165 166 167 168 169 170 171 172
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 */ }
    },
};

M
Mark McLoughlin 已提交
173 174 175 176 177 178 179 180 181 182 183 184
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 */ }
    },
};

J
Jan Kiszka 已提交
185 186 187 188 189 190 191
QemuOptsList qemu_rtc_opts = {
    .name = "rtc",
    .head = QTAILQ_HEAD_INITIALIZER(qemu_rtc_opts.head),
    .desc = {
        {
            .name = "base",
            .type = QEMU_OPT_STRING,
J
Jan Kiszka 已提交
192 193 194
        },{
            .name = "clock",
            .type = QEMU_OPT_STRING,
J
Jan Kiszka 已提交
195 196 197 198 199 200 201 202 203 204
#ifdef TARGET_I386
        },{
            .name = "driftfix",
            .type = QEMU_OPT_STRING,
#endif
        },
        { /* end if list */ }
    },
};

G
Gerd Hoffmann 已提交
205 206
static QemuOptsList *lists[] = {
    &qemu_drive_opts,
207
    &qemu_chardev_opts,
G
Gerd Hoffmann 已提交
208
    &qemu_device_opts,
M
Mark McLoughlin 已提交
209
    &qemu_netdev_opts,
M
Mark McLoughlin 已提交
210
    &qemu_net_opts,
J
Jan Kiszka 已提交
211
    &qemu_rtc_opts,
G
Gerd Hoffmann 已提交
212 213 214
    NULL,
};

G
Gerd Hoffmann 已提交
215 216 217 218 219 220 221 222 223 224 225 226 227 228
static QemuOptsList *find_list(const char *group)
{
    int i;

    for (i = 0; lists[i] != NULL; i++) {
        if (strcmp(lists[i]->name, group) == 0)
            break;
    }
    if (lists[i] == NULL) {
        qemu_error("there is no option group \"%s\"\n", group);
    }
    return lists[i];
}

G
Gerd Hoffmann 已提交
229 230 231
int qemu_set_option(const char *str)
{
    char group[64], id[64], arg[64];
G
Gerd Hoffmann 已提交
232
    QemuOptsList *list;
G
Gerd Hoffmann 已提交
233
    QemuOpts *opts;
G
Gerd Hoffmann 已提交
234
    int rc, offset;
G
Gerd Hoffmann 已提交
235 236 237

    rc = sscanf(str, "%63[^.].%63[^.].%63[^=]%n", group, id, arg, &offset);
    if (rc < 3 || str[offset] != '=') {
G
Gerd Hoffmann 已提交
238
        qemu_error("can't parse: \"%s\"\n", str);
G
Gerd Hoffmann 已提交
239 240 241
        return -1;
    }

G
Gerd Hoffmann 已提交
242 243
    list = find_list(group);
    if (list == NULL) {
G
Gerd Hoffmann 已提交
244 245 246
        return -1;
    }

G
Gerd Hoffmann 已提交
247
    opts = qemu_opts_find(list, id);
G
Gerd Hoffmann 已提交
248
    if (!opts) {
G
Gerd Hoffmann 已提交
249
        qemu_error("there is no %s \"%s\" defined\n",
G
Gerd Hoffmann 已提交
250
                   list->name, id);
G
Gerd Hoffmann 已提交
251 252 253
        return -1;
    }

M
Mark McLoughlin 已提交
254
    if (qemu_opt_set(opts, arg, str+offset+1) == -1) {
G
Gerd Hoffmann 已提交
255 256 257 258 259
        return -1;
    }
    return 0;
}

G
Gerd Hoffmann 已提交
260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298
struct ConfigWriteData {
    QemuOptsList *list;
    FILE *fp;
};

static int config_write_opt(const char *name, const char *value, void *opaque)
{
    struct ConfigWriteData *data = opaque;

    fprintf(data->fp, "  %s = \"%s\"\n", name, value);
    return 0;
}

static int config_write_opts(QemuOpts *opts, void *opaque)
{
    struct ConfigWriteData *data = opaque;
    const char *id = qemu_opts_id(opts);

    if (id) {
        fprintf(data->fp, "[%s \"%s\"]\n", data->list->name, id);
    } else {
        fprintf(data->fp, "[%s]\n", data->list->name);
    }
    qemu_opt_foreach(opts, config_write_opt, data, 0);
    fprintf(data->fp, "\n");
    return 0;
}

void qemu_config_write(FILE *fp)
{
    struct ConfigWriteData data = { .fp = fp };
    int i;

    fprintf(fp, "# qemu config file\n\n");
    for (i = 0; lists[i] != NULL; i++) {
        data.list = lists[i];
        qemu_opts_foreach(data.list, config_write_opts, &data, 0);
    }
}