* [Qemu-devel] [PATCH 0/4] QemuOpts: config file support. @ 2009-10-14 8:39 Gerd Hoffmann 2009-10-14 8:39 ` [Qemu-devel] [PATCH 1/4] QemuOpts: add find_list() Gerd Hoffmann ` (5 more replies) 0 siblings, 6 replies; 14+ messages in thread From: Gerd Hoffmann @ 2009-10-14 8:39 UTC (permalink / raw) To: qemu-devel; +Cc: Gerd Hoffmann Hi, Very first cut of config file support, to get the discussion rolling ;) We might use this some day to provide defaults for vga, nic, serial etc. Also host-wide defaults (network setup for example) should be doable. Just needs some careful planning which config files to read in which cases and in which order ;) cheers, Gerd ^ permalink raw reply [flat|nested] 14+ messages in thread
* [Qemu-devel] [PATCH 1/4] QemuOpts: add find_list() 2009-10-14 8:39 [Qemu-devel] [PATCH 0/4] QemuOpts: config file support Gerd Hoffmann @ 2009-10-14 8:39 ` Gerd Hoffmann 2009-10-14 8:39 ` [Qemu-devel] [PATCH 2/4] QemuOpts: dump config Gerd Hoffmann ` (4 subsequent siblings) 5 siblings, 0 replies; 14+ messages in thread From: Gerd Hoffmann @ 2009-10-14 8:39 UTC (permalink / raw) To: qemu-devel; +Cc: Gerd Hoffmann Factor out the QemuOptsList search code for upcoming users. Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> --- qemu-config.c | 29 ++++++++++++++++++++--------- 1 files changed, 20 insertions(+), 9 deletions(-) diff --git a/qemu-config.c b/qemu-config.c index bafaea2..f02dd42 100644 --- a/qemu-config.c +++ b/qemu-config.c @@ -193,11 +193,26 @@ static QemuOptsList *lists[] = { NULL, }; +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]; +} + int qemu_set_option(const char *str) { char group[64], id[64], arg[64]; + QemuOptsList *list; QemuOpts *opts; - int i, rc, offset; + int rc, offset; rc = sscanf(str, "%63[^.].%63[^.].%63[^=]%n", group, id, arg, &offset); if (rc < 3 || str[offset] != '=') { @@ -205,19 +220,15 @@ int qemu_set_option(const char *str) return -1; } - 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); + list = find_list(group); + if (list == NULL) { return -1; } - opts = qemu_opts_find(lists[i], id); + opts = qemu_opts_find(list, id); if (!opts) { qemu_error("there is no %s \"%s\" defined\n", - lists[i]->name, id); + list->name, id); return -1; } -- 1.6.2.5 ^ permalink raw reply related [flat|nested] 14+ messages in thread
* [Qemu-devel] [PATCH 2/4] QemuOpts: dump config. 2009-10-14 8:39 [Qemu-devel] [PATCH 0/4] QemuOpts: config file support Gerd Hoffmann 2009-10-14 8:39 ` [Qemu-devel] [PATCH 1/4] QemuOpts: add find_list() Gerd Hoffmann @ 2009-10-14 8:39 ` Gerd Hoffmann 2009-10-14 18:56 ` Anthony Liguori 2009-10-14 8:39 ` [Qemu-devel] [PATCH 3/4] QemuOpts: parse config from file Gerd Hoffmann ` (3 subsequent siblings) 5 siblings, 1 reply; 14+ messages in thread From: Gerd Hoffmann @ 2009-10-14 8:39 UTC (permalink / raw) To: qemu-devel; +Cc: Gerd Hoffmann Add a function to write the QemuOpts configuration to a git-style config file. Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> --- qemu-config.c | 39 +++++++++++++++++++++++++++++++++++++++ qemu-config.h | 2 ++ 2 files changed, 41 insertions(+), 0 deletions(-) diff --git a/qemu-config.c b/qemu-config.c index f02dd42..fa236e9 100644 --- a/qemu-config.c +++ b/qemu-config.c @@ -238,3 +238,42 @@ int qemu_set_option(const char *str) return 0; } +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); + } +} diff --git a/qemu-config.h b/qemu-config.h index cdad5ac..33fce7e 100644 --- a/qemu-config.h +++ b/qemu-config.h @@ -9,4 +9,6 @@ extern QemuOptsList qemu_rtc_opts; int qemu_set_option(const char *str); +void qemu_config_write(FILE *fp); + #endif /* QEMU_CONFIG_H */ -- 1.6.2.5 ^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [Qemu-devel] [PATCH 2/4] QemuOpts: dump config. 2009-10-14 8:39 ` [Qemu-devel] [PATCH 2/4] QemuOpts: dump config Gerd Hoffmann @ 2009-10-14 18:56 ` Anthony Liguori 0 siblings, 0 replies; 14+ messages in thread From: Anthony Liguori @ 2009-10-14 18:56 UTC (permalink / raw) To: Gerd Hoffmann; +Cc: qemu-devel Gerd Hoffmann wrote: > Add a function to write the QemuOpts configuration to a git-style > config file. > > Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> > --- > qemu-config.c | 39 +++++++++++++++++++++++++++++++++++++++ > qemu-config.h | 2 ++ > 2 files changed, 41 insertions(+), 0 deletions(-) > > diff --git a/qemu-config.c b/qemu-config.c > index f02dd42..fa236e9 100644 > --- a/qemu-config.c > +++ b/qemu-config.c > @@ -238,3 +238,42 @@ int qemu_set_option(const char *str) > return 0; > } > > +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); > This id syntax is a good idea. Regards, Anthony Liguori ^ permalink raw reply [flat|nested] 14+ messages in thread
* [Qemu-devel] [PATCH 3/4] QemuOpts: parse config from file. 2009-10-14 8:39 [Qemu-devel] [PATCH 0/4] QemuOpts: config file support Gerd Hoffmann 2009-10-14 8:39 ` [Qemu-devel] [PATCH 1/4] QemuOpts: add find_list() Gerd Hoffmann 2009-10-14 8:39 ` [Qemu-devel] [PATCH 2/4] QemuOpts: dump config Gerd Hoffmann @ 2009-10-14 8:39 ` Gerd Hoffmann 2009-10-14 18:55 ` Anthony Liguori 2009-10-14 8:39 ` [Qemu-devel] [PATCH 4/4] QemuOpts: command line switches for the config file Gerd Hoffmann ` (2 subsequent siblings) 5 siblings, 1 reply; 14+ messages in thread From: Gerd Hoffmann @ 2009-10-14 8:39 UTC (permalink / raw) To: qemu-devel; +Cc: Gerd Hoffmann Add functions to parse QemuOpts from a git-style config file. Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> --- qemu-config.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ qemu-config.h | 1 + 2 files changed, 51 insertions(+), 0 deletions(-) diff --git a/qemu-config.c b/qemu-config.c index fa236e9..1b24ec8 100644 --- a/qemu-config.c +++ b/qemu-config.c @@ -277,3 +277,53 @@ void qemu_config_write(FILE *fp) qemu_opts_foreach(data.list, config_write_opts, &data, 0); } } + +int qemu_config_parse(FILE *fp) +{ + char line[1024], group[64], id[64], arg[64], value[1024]; + QemuOptsList *list = NULL; + QemuOpts *opts = NULL; + + while (fgets(line, sizeof(line), fp) != NULL) { + if (line[0] == '\n') { + /* skip empty lines */ + continue; + } + if (line[0] == '#') { + /* comment */ + continue; + } + if (sscanf(line, "[%63s \"%63[^\"]\"]", group, id) == 2) { + /* group with id */ + list = find_list(group); + if (list == NULL) + return -1; + opts = qemu_opts_create(list, id, 1); + continue; + } + if (sscanf(line, "[%63[^]]]", group) == 1) { + /* group without id */ + list = find_list(group); + if (list == NULL) + return -1; + opts = qemu_opts_create(list, NULL, 0); + continue; + } + if (sscanf(line, " %63s = \"%1023[^\"]\"", arg, value) == 2) { + /* arg = value */ + if (opts == NULL) { + fprintf(stderr, "no group defined\n"); + return -1; + } + if (qemu_opt_set(opts, arg, value) != 0) { + fprintf(stderr, "failed to set \"%s\" for %s\n", + arg, group); + return -1; + } + continue; + } + fprintf(stderr, "parse error: %s\n", line); + return -1; + } + return 0; +} diff --git a/qemu-config.h b/qemu-config.h index 33fce7e..0448ab4 100644 --- a/qemu-config.h +++ b/qemu-config.h @@ -10,5 +10,6 @@ extern QemuOptsList qemu_rtc_opts; int qemu_set_option(const char *str); void qemu_config_write(FILE *fp); +int qemu_config_parse(FILE *fp); #endif /* QEMU_CONFIG_H */ -- 1.6.2.5 ^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [Qemu-devel] [PATCH 3/4] QemuOpts: parse config from file. 2009-10-14 8:39 ` [Qemu-devel] [PATCH 3/4] QemuOpts: parse config from file Gerd Hoffmann @ 2009-10-14 18:55 ` Anthony Liguori 0 siblings, 0 replies; 14+ messages in thread From: Anthony Liguori @ 2009-10-14 18:55 UTC (permalink / raw) To: Gerd Hoffmann; +Cc: qemu-devel [-- Attachment #1: Type: text/plain, Size: 195 bytes --] Gerd Hoffmann wrote: > Add functions to parse QemuOpts from a git-style config file. > > Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> > FWIW, here's my parser. Regards, Anthony Liguori [-- Attachment #2: config-parser.patch --] [-- Type: text/x-patch, Size: 15181 bytes --] commit 8b65f2a706e15efd40a308fd66bcf613f6569962 Author: Anthony Liguori <aliguori@us.ibm.com> Date: Mon Oct 12 09:25:21 2009 -0500 Config parser diff --git a/Makefile b/Makefile index 8d78dc1..0a8dadf 100644 --- a/Makefile +++ b/Makefile @@ -125,6 +125,7 @@ obj-y += qemu-char.o aio.o net-checksum.o savevm.o obj-y += msmouse.o ps2.o obj-y += qdev.o qdev-properties.o obj-y += qint.o qstring.o qdict.o qlist.o qemu-config.o +obj-y += config-parser.o obj-$(CONFIG_BRLAPI) += baum.o obj-$(CONFIG_WIN32) += tap-win32.o @@ -212,6 +213,7 @@ check-qint: check-qint.o qint.o qemu-malloc.o check-qstring: check-qstring.o qstring.o qemu-malloc.o check-qdict: check-qdict.o qdict.o qint.o qstring.o qemu-malloc.o check-qlist: check-qlist.o qlist.o qint.o qemu-malloc.o +check-config-parser: check-config-parser.o config-parser.o qlist.o qstring.o qemu-malloc.o clean: # avoid old build problems by removing potentially incorrect old files diff --git a/config-parser.c b/config-parser.c new file mode 100644 index 0000000..aa8c08a --- /dev/null +++ b/config-parser.c @@ -0,0 +1,384 @@ +#include "qemu-common.h" +#include "qemu-queue.h" +#include "qlist.h" +#include "qstring.h" + +#include "config-parser.h" + +typedef struct ConfigParser +{ +} ConfigParser; + +static void parser_error(ConfigParser *parser, const char *ptr, const char *fmt, ...) +{ + va_list ap; + + fprintf(stderr, "parse error: "); + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); + fprintf(stderr, "\n"); + exit(1); +} + +static int parse_is_whitespace(char ch) +{ + if (ch == ' ' || ch == '\t' || ch == '\r') { + return 1; + } + + return 0; +} + +static int parse_is_alpha(char ch) +{ + if ((ch >= 'A' && ch <= 'Z') || + (ch >= 'a' && ch <= 'z') || + (ch == '-') || + (ch == '_')) { + return 1; + } + + return 0; +} + +static int parse_is_digit(char ch) +{ + if (ch >= '0' && ch <= '9') { + return 1; + } + + return 0; +} + +static int parse_is_hexdigit(char ch) +{ + if (parse_is_digit(ch) || + (ch >= 'a' && ch <= 'f') || + (ch >= 'A' && ch <= 'F')) { + return 1; + } + + return 0; +} + +static size_t parse_whitespace(ConfigParser *parser, const char *input) +{ + const char *ptr = input; + + while (parse_is_whitespace(*ptr)) { + ptr++; + } + + return (ptr - input); +} + +static size_t parse_skip(ConfigParser *parser, const char *input) +{ + const char *ptr = input; + + while (*ptr == '#' || parse_is_whitespace(*ptr)) { + ptr += parse_whitespace(parser, ptr); + + if (*ptr == '#') { + ptr++; + + while (*ptr != '\n' && *ptr) { + ptr++; + } + } + } + + return (ptr - input); +} + +static size_t parse_symbol(ConfigParser *parser, QString **str, const char *input) +{ + const char *ptr = input; + + if (parse_is_alpha(*ptr)) { + ptr++; + + while (parse_is_alpha(*ptr) || + (*ptr >= '0' && *ptr <= '9')) { + ptr++; + } + } + + if (ptr != input) { + *str = qstring_from_substr(input, (ptr - input)); + } + + return (ptr - input); +} + +static size_t parse_escaped_string(ConfigParser *parser, QString **str, const char *input) +{ + const char *ptr = input; + + if (*ptr != '\"') { + goto err; + } + + ptr++; + + while (*ptr && *ptr != '\"' && *ptr != '\n') { + if (*ptr == '\\') { + ptr++; + + if (*ptr == 'x') { /* hex */ + ptr++; + + if (parse_is_hexdigit(*ptr)) { + ptr++; + } + if (parse_is_hexdigit(*ptr)) { + ptr++; + } + } else if (parse_is_digit(*ptr)) { /* decimal/octal */ + ptr++; + + if (parse_is_digit(*ptr)) { + ptr++; + } + if (parse_is_digit(*ptr)) { + ptr++; + } + } else if (*ptr && *ptr != '\n') { + ptr++; + } + } else { + ptr++; + } + } + + if (*ptr != '\"') { + parser_error(parser, ptr, "Unterminated string literal"); + goto err; + } + ptr++; + + /* FIXME unquote */ + *str = qstring_from_substr(input + 1, (ptr - input) - 2); + return (ptr - input); + +err: + return 0; +} + +static size_t parse_string(ConfigParser *parser, QString **str, const char *input) +{ + const char *ptr = input; + + while (*ptr && *ptr != '\n' && *ptr != '#') { + size_t ret; + + if (parse_is_whitespace(*ptr)) { + ret = parse_whitespace(parser, ptr); + + if (ptr[ret] == 0 || ptr[ret] == '\n' || ptr[ret] == '#') { + break; + } + + ptr += ret; + } else { + ptr++; + } + } + + if (ptr != input) { + *str = qstring_from_substr(input, (ptr - input)); + } + + return (ptr - input); +} + +static size_t parse_empty_lines(ConfigParser *parser, const char *input) +{ + const char *ptr = input; + + do { + if (*ptr == '\n') { + ptr++; + } + + ptr += parse_skip(parser, ptr); + } while (*ptr == '\n'); + + return (ptr - input); +} + +static size_t parse_item(ConfigParser *parser, QList **item, const char *input) +{ + QString *key = NULL; + QString *value = NULL; + const char *ptr = input; + size_t ret; + + ptr += parse_empty_lines(parser, input); + + ptr += parse_skip(parser, ptr); + + ret = parse_symbol(parser, &key, ptr); + if (!ret) { + goto err; + } + + ptr += ret; + + ptr += parse_skip(parser, ptr); + if (*ptr != '=') { + parser_error(parser, ptr, "For key '%s', expected '=', got '%c'", + input, *ptr); + goto err; + } + ptr++; + + ptr += parse_skip(parser, ptr); + + ret = parse_escaped_string(parser, &value, ptr); + if (ret == 0) { + ret = parse_string(parser, &value, ptr); + } + + if (!ret) { + parser_error(parser, ptr, "No value for key `%s'", qstring_get_str(key)); + goto err; + } + ptr += ret; + + ptr += parse_skip(parser, ptr); + if (*ptr != '\n' && *ptr != 0) { + parser_error(parser, ptr, "Unexpected input at end of line"); + goto err; + } + + if (*ptr == '\n') { + ptr++; + } + + *item = qlist_new(); + + qlist_append(*item, key); + qlist_append(*item, value); + + return (ptr - input); + +err: + QDECREF(key); + QDECREF(value); + return 0; +} + +static size_t parse_section_name(ConfigParser *parser, QString **name, const char *input) +{ + const char *ptr = input; + size_t ret = 0; + + ptr += parse_empty_lines(parser, input); + + ptr += parse_skip(parser, ptr); + if (*ptr != '[') { + goto err; + } + ptr++; + + ptr += parse_skip(parser, ptr); + + ret = parse_symbol(parser, name, ptr); + if (!ret) { + goto err; + } + ptr += ret; + + ptr += parse_skip(parser, ptr); + if (*ptr != ']') { + parser_error(parser, ptr, "Expected ']', got '%c'", *ptr); + goto err; + } + ptr++; + + ptr += parse_skip(parser, ptr); + if (*ptr != '\n' && *ptr != 0) { + parser_error(parser, ptr, "Unexpected input at end of line"); + goto err; + } + + ptr++; + + return (ptr - input); + +err: + QDECREF(*name); + *name = NULL; + return 0; +} + +static size_t parse_items(ConfigParser *parser, QList **section, const char *input) +{ + const char *ptr = input; + size_t ret; + + do { + QList *item = NULL; + + ret = parse_item(parser, &item, ptr); + if (ret) { + qlist_append(*section, item); + ptr += ret; + } + } while (ret); + + return (ptr - input); +} + +QList *parse_config(const char *input) +{ + ConfigParser parser; + QList *sections = NULL; + QList *section = NULL; + const char *ptr = input; + size_t ret; + + memset(&parser, 0, sizeof(parser)); + + sections = qlist_new(); + + section = qlist_new(); + qlist_append(section, qstring_from_str("DEFAULT")); + + ret = parse_items(&parser, §ion, ptr); + if (ret) { + qlist_append(sections, section); + ptr += ret; + } else { + QDECREF(section); + } + + do { + QString *name = NULL; + + ret = parse_section_name(&parser, &name, ptr); + if (ret) { + ptr += ret; + + section = qlist_new(); + qlist_append(section, name); + + ptr += parse_items(&parser, §ion, ptr); + + qlist_append(sections, section); + } + } while (ret); + + ptr += parse_empty_lines(&parser, ptr); + + ptr += parse_skip(&parser, ptr); + + if (*ptr != 0) { + parser_error(&parser, ptr, "Garbage at end of input"); + return NULL; + } + + return sections; +} diff --git a/config-parser.h b/config-parser.h new file mode 100644 index 0000000..cb113d4 --- /dev/null +++ b/config-parser.h @@ -0,0 +1,8 @@ +#ifndef CONFIG_PARSER_H +#define CONFIG_PARSER_H + +#include "qlist.h" + +QList *parse_config(const char *input); + +#endif diff --git a/qemu-config.c b/qemu-config.c index bafaea2..6960874 100644 --- a/qemu-config.c +++ b/qemu-config.c @@ -2,6 +2,8 @@ #include "qemu-option.h" #include "qemu-config.h" #include "sysemu.h" +#include "qlist.h" +#include "qstring.h" QemuOptsList qemu_drive_opts = { .name = "drive", @@ -193,6 +195,51 @@ static QemuOptsList *lists[] = { NULL, }; +typedef struct QOptionSectionState +{ + int index; +} QOptionSectionState; + +static void qemu_set_qoption_items(QObject *obj, void *opaque) +{ + QOptionSectionState *s = opaque; + + if (s->index == 0) { + QString *name; + int i; + + name = qobject_to_qstring(obj); + + for (i = 0; lists[i] != NULL; i++) { + if (strcmp(lists[i]->name, qstring_get_str(name)) == 0) { + break; + } + } + + if (lists[i] == NULL) { + qemu_error("there is no option group '%s'\n", + qstring_get_str(name)); + return; + } + + opts = qemu_opts_find(lists[i], id); + } +} + +static void qemu_set_qoption_section(QObject *obj, void *opaque) +{ + QOptionSectionState s = {}; + + qlist_iter(qobject_to_qlist(obj), qemu_set_qoption_items, &s); +} + +int qemu_set_qoption(QList *options) +{ + qlist_iter(options, qemu_set_qoption_section, NULL); + + return 0; +} + int qemu_set_option(const char *str) { char group[64], id[64], arg[64]; diff --git a/qemu-config.h b/qemu-config.h index cdad5ac..bb3693a 100644 --- a/qemu-config.h +++ b/qemu-config.h @@ -1,6 +1,8 @@ #ifndef QEMU_CONFIG_H #define QEMU_CONFIG_H +#include "qlist.h" + extern QemuOptsList qemu_drive_opts; extern QemuOptsList qemu_chardev_opts; extern QemuOptsList qemu_device_opts; @@ -8,5 +10,6 @@ extern QemuOptsList qemu_net_opts; extern QemuOptsList qemu_rtc_opts; int qemu_set_option(const char *str); +int qemu_set_qoption(QList *options); #endif /* QEMU_CONFIG_H */ diff --git a/qemu-options.hx b/qemu-options.hx index 3dd76b3..074956b 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -1665,6 +1665,13 @@ Immediately before starting guest execution, drop root privileges, switching to the specified user. ETEXI +DEF("config", HAS_ARG, QEMU_OPTION_config, \ + "-config file Load configuratino file.") +STEXI +@item -config file +Load configuration file. +ETEXI + STEXI @end table ETEXI diff --git a/qobject.h b/qobject.h index 4cc9287..76f669f 100644 --- a/qobject.h +++ b/qobject.h @@ -60,7 +60,7 @@ typedef struct QObject { QObject base /* Get the 'base' part of an object */ -#define QOBJECT(obj) (&obj->base) +#define QOBJECT(obj) (&(obj)->base) /* High-level interface for qobject_incref() */ #define QINCREF(obj) \ diff --git a/qstring.c b/qstring.c index 6d411da..8b6e9ba 100644 --- a/qstring.c +++ b/qstring.c @@ -37,6 +37,23 @@ QString *qstring_from_str(const char *str) } /** + * qstring_from_str(): Create a new QString from a C string up to a certain length + * + * Return strong reference. + */ +QString *qstring_from_substr(const char *str, size_t len) +{ + QString *qstring; + + qstring = qemu_malloc(sizeof(*qstring)); + qstring->string = qemu_mallocz(len + 1); + strncpy(qstring->string, str, len); + QOBJECT_INIT(qstring, &qstring_type); + + return qstring; +} + +/** * qobject_to_qstring(): Convert a QObject to a QString */ QString *qobject_to_qstring(const QObject *obj) diff --git a/qstring.h b/qstring.h index e012cb7..ca7d87d 100644 --- a/qstring.h +++ b/qstring.h @@ -9,6 +9,7 @@ typedef struct QString { } QString; QString *qstring_from_str(const char *str); +QString *qstring_from_substr(const char *str, size_t len); const char *qstring_get_str(const QString *qstring); QString *qobject_to_qstring(const QObject *obj); diff --git a/vl.c b/vl.c index 374f85b..87afd75 100644 --- a/vl.c +++ b/vl.c @@ -1,7 +1,7 @@ /* * QEMU System Emulator * - * Copyright (c) 2003-2008 Fabrice Bellard + * Copyright (c) 2008 Fabrice Bellard * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -171,6 +171,8 @@ int main(int argc, char **argv) #include "slirp/libslirp.h" #include "qemu-queue.h" +#include "config-parser.h" +#include "qlist.h" //#define DEBUG_NET //#define DEBUG_SLIRP @@ -4770,6 +4772,7 @@ int main(int argc, char **argv, char **envp) #endif CPUState *env; int show_vnc_port = 0; + const char *config_file = NULL; init_clocks(); @@ -5513,10 +5516,51 @@ int main(int argc, char **argv, char **envp) xen_mode = XEN_ATTACH; break; #endif + case QEMU_OPTION_config: + config_file = optarg; + break; } } } + if (config_file) { + struct stat stbuf; + int fd; + char *buffer; + size_t offset = 0; + QList *config; + + fd = open(config_file, O_RDONLY); + if (fd == -1) + abort(); + + if (fstat(fd, &stbuf) == -1) + abort(); + + buffer = qemu_malloc(stbuf.st_size + 1); + while (offset < stbuf.st_size) { + ssize_t len; + + len = read(fd, buffer + offset, stbuf.st_size - offset); + if (len < 1) + abort(); + + offset += len; + } + + close(fd); + + buffer[offset] = 0; + + config = parse_config(buffer); + if (config == NULL) + abort(); + + printf("successfully parsed config\n"); + + QDECREF(config); + } + /* If no data_dir is specified then try to find it relative to the executable path. */ if (!data_dir) { ^ permalink raw reply related [flat|nested] 14+ messages in thread
* [Qemu-devel] [PATCH 4/4] QemuOpts: command line switches for the config file. 2009-10-14 8:39 [Qemu-devel] [PATCH 0/4] QemuOpts: config file support Gerd Hoffmann ` (2 preceding siblings ...) 2009-10-14 8:39 ` [Qemu-devel] [PATCH 3/4] QemuOpts: parse config from file Gerd Hoffmann @ 2009-10-14 8:39 ` Gerd Hoffmann 2009-10-16 18:39 ` Nathan Baum 2009-10-16 18:48 ` Nathan Baum 2009-10-14 18:53 ` [Qemu-devel] [PATCH 0/4] QemuOpts: config file support Anthony Liguori 2009-10-14 19:01 ` Anthony Liguori 5 siblings, 2 replies; 14+ messages in thread From: Gerd Hoffmann @ 2009-10-14 8:39 UTC (permalink / raw) To: qemu-devel; +Cc: Gerd Hoffmann Adds -readconfig and -writeconfig command line switches to read/write QemuOpts from config file. In theory you should be able to do: qemu < machine config cmd line switches here > -writeconfig vm.cfg qemu -readconfig vm.cfg In practice it will not work. Not all command line switches are converted to QemuOpts, so you'll have to keep the not-yet converted ones on the second line. Also there might be bugs lurking which prevent even the converted ones from working correctly. Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> --- qemu-options.hx | 5 +++++ vl.c | 30 ++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 0 deletions(-) diff --git a/qemu-options.hx b/qemu-options.hx index 3dd76b3..6cbf9e2 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -1682,3 +1682,8 @@ DEF("semihosting", 0, QEMU_OPTION_semihosting, DEF("old-param", 0, QEMU_OPTION_old_param, "-old-param old param mode\n") #endif +DEF("readconfig", HAS_ARG, QEMU_OPTION_readconfig, + "-readconfig <file>\n") +DEF("writeconfig", HAS_ARG, QEMU_OPTION_writeconfig, + "-writeconfig <file>\n" + " read/write config file") diff --git a/vl.c b/vl.c index afe01af..ad902fe 100644 --- a/vl.c +++ b/vl.c @@ -5513,6 +5513,36 @@ int main(int argc, char **argv, char **envp) xen_mode = XEN_ATTACH; break; #endif + case QEMU_OPTION_readconfig: + { + FILE *fp; + fp = fopen(optarg, "r"); + if (fp == NULL) { + fprintf(stderr, "open %s: %s\n", optarg, strerror(errno)); + exit(1); + } + if (qemu_config_parse(fp) != 0) { + exit(1); + } + fclose(fp); + break; + } + case QEMU_OPTION_writeconfig: + { + FILE *fp; + if (strcmp(optarg, "-") == 0) { + fp = stdout; + } else { + fp = fopen(optarg, "w"); + if (fp == NULL) { + fprintf(stderr, "open %s: %s\n", optarg, strerror(errno)); + exit(1); + } + } + qemu_config_write(fp); + fclose(fp); + break; + } } } } -- 1.6.2.5 ^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [Qemu-devel] [PATCH 4/4] QemuOpts: command line switches for the config file. 2009-10-14 8:39 ` [Qemu-devel] [PATCH 4/4] QemuOpts: command line switches for the config file Gerd Hoffmann @ 2009-10-16 18:39 ` Nathan Baum 2009-10-16 19:29 ` Gerd Hoffmann 2009-10-16 18:48 ` Nathan Baum 1 sibling, 1 reply; 14+ messages in thread From: Nathan Baum @ 2009-10-16 18:39 UTC (permalink / raw) To: Gerd Hoffmann; +Cc: qemu-devel On Wed, 2009-10-14 at 10:39 +0200, Gerd Hoffmann wrote: > Adds -readconfig and -writeconfig command line switches to read/write > QemuOpts from config file. > > In theory you should be able to do: > > qemu < machine config cmd line switches here > -writeconfig vm.cfg > qemu -readconfig vm.cfg > > In practice it will not work. Not all command line switches are > converted to QemuOpts, so you'll have to keep the not-yet converted ones > on the second line. Also there might be bugs lurking which prevent even > the converted ones from working correctly. > > Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> > --- > qemu-options.hx | 5 +++++ > vl.c | 30 ++++++++++++++++++++++++++++++ > 2 files changed, 35 insertions(+), 0 deletions(-) > > diff --git a/qemu-options.hx b/qemu-options.hx > index 3dd76b3..6cbf9e2 100644 > --- a/qemu-options.hx > +++ b/qemu-options.hx > @@ -1682,3 +1682,8 @@ DEF("semihosting", 0, QEMU_OPTION_semihosting, > DEF("old-param", 0, QEMU_OPTION_old_param, > "-old-param old param mode\n") > #endif > +DEF("readconfig", HAS_ARG, QEMU_OPTION_readconfig, > + "-readconfig <file>\n") > +DEF("writeconfig", HAS_ARG, QEMU_OPTION_writeconfig, > + "-writeconfig <file>\n" > + " read/write config file") > diff --git a/vl.c b/vl.c > index afe01af..ad902fe 100644 > --- a/vl.c > +++ b/vl.c > @@ -5513,6 +5513,36 @@ int main(int argc, char **argv, char **envp) > xen_mode = XEN_ATTACH; > break; > #endif > + case QEMU_OPTION_readconfig: > + { > + FILE *fp; > + fp = fopen(optarg, "r"); > + if (fp == NULL) { > + fprintf(stderr, "open %s: %s\n", optarg, strerror(errno)); > + exit(1); > + } > + if (qemu_config_parse(fp) != 0) { > + exit(1); > + } > + fclose(fp); > + break; > + } > + case QEMU_OPTION_writeconfig: > + { > + FILE *fp; > + if (strcmp(optarg, "-") == 0) { > + fp = stdout; > + } else { > + fp = fopen(optarg, "w"); > + if (fp == NULL) { > + fprintf(stderr, "open %s: %s\n", optarg, strerror(errno)); > + exit(1); > + } > + } > + qemu_config_write(fp); > + fclose(fp); > + break; > + } > } > } > } It seems like the typical use-case for -writeconfig will be for "upgrading" to the config file system. Might it be more useful for qemu to exit after writing the config? Signed-off-by: Nathan Baum <nathan@parenthephobia.org.uk> --- a/vl.c +++ b/vl.c @@ -5546,7 +5546,7 @@ int main(int argc, char **argv, char **envp) } qemu_config_write(fp); fclose(fp); - break; + exit(0); } } } ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [Qemu-devel] [PATCH 4/4] QemuOpts: command line switches for the config file. 2009-10-16 18:39 ` Nathan Baum @ 2009-10-16 19:29 ` Gerd Hoffmann 0 siblings, 0 replies; 14+ messages in thread From: Gerd Hoffmann @ 2009-10-16 19:29 UTC (permalink / raw) To: Nathan Baum; +Cc: qemu-devel On 10/16/09 20:39, Nathan Baum wrote: > It seems like the typical use-case for -writeconfig will be for > "upgrading" to the config file system. Might it be more useful for qemu > to exit after writing the config? Yes, good idea. cheers, Gerd ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [Qemu-devel] [PATCH 4/4] QemuOpts: command line switches for the config file. 2009-10-14 8:39 ` [Qemu-devel] [PATCH 4/4] QemuOpts: command line switches for the config file Gerd Hoffmann 2009-10-16 18:39 ` Nathan Baum @ 2009-10-16 18:48 ` Nathan Baum 2009-10-16 19:33 ` Gerd Hoffmann 1 sibling, 1 reply; 14+ messages in thread From: Nathan Baum @ 2009-10-16 18:48 UTC (permalink / raw) To: Gerd Hoffmann; +Cc: qemu-devel On Wed, 2009-10-14 at 10:39 +0200, Gerd Hoffmann wrote: > Adds -readconfig and -writeconfig command line switches to read/write > QemuOpts from config file. > > In theory you should be able to do: > > qemu < machine config cmd line switches here > -writeconfig vm.cfg > qemu -readconfig vm.cfg > > In practice it will not work. Not all command line switches are > converted to QemuOpts, so you'll have to keep the not-yet converted ones > on the second line. It would probably be helpful for Qemu to put those in the config file. In the medium term, perhaps a "legacy_options" option which can be automatically parsed by -readconfig. In the short term, just put the non-QemuOpt options in a comment. (In the long term, hopefully there won't be any legacy options.) I've knocked up something which does the short term solution. There's probably a much more elegant way. (Thinking about it, maybe another field of QEMUOption should simply record whether the option has been QemuOptified, then it shouldn't need to touch the code for each option.) Signed-off-by: Nathan Baum <nathan@parenthephobia.org.uk> --- diff --git a/qemu-config.c b/qemu-config.c index 6075c20..fe4837d 100644 --- a/qemu-config.c +++ b/qemu-config.c @@ -285,6 +285,9 @@ void qemu_config_write(FILE *fp) int i; fprintf(fp, "# qemu config file\n\n"); + fprintf(fp, "# legacy options:\n# "); + qemu_opt_legacy_print(fp); + fprintf(fp, "\n\n"); for (i = 0; lists[i] != NULL; i++) { data.list = lists[i]; qemu_opts_foreach(data.list, config_write_opts, &data, 0); diff --git a/qemu-option.c b/qemu-option.c index 49efd39..4d1453c 100644 --- a/qemu-option.c +++ b/qemu-option.c @@ -819,3 +819,20 @@ int qemu_opts_foreach(QemuOptsList *list, qemu_opts_loopfunc func, void *opaque, } return rc; } + +static char legacy_options[8192]; + +void qemu_opt_legacy_add(const char *opt, const char *optarg) +{ + strncat(legacy_options, " -", 8192); + strncat(legacy_options, opt, 8192); + if (optarg) { + strncat(legacy_options, " ", 8192); + strncat(legacy_options, optarg, 8192); + } +} + +void qemu_opt_legacy_print(FILE *file) +{ + fprintf(file, "%s", legacy_options); +} diff --git a/qemu-option.h b/qemu-option.h index 666b666..5a8cb61 100644 --- a/qemu-option.h +++ b/qemu-option.h @@ -124,4 +124,7 @@ int qemu_opts_print(QemuOpts *opts, void *dummy); int qemu_opts_foreach(QemuOptsList *list, qemu_opts_loopfunc func, void *opaque, int abort_on_failure); +void qemu_opt_legacy_add(const char *opt, const char *optarg); +void qemu_opt_legacy_print(FILE *file); + #endif diff --git a/vl.c b/vl.c index b090022..44f8fed 100644 --- a/vl.c +++ b/vl.c @@ -4887,6 +4887,7 @@ int main(int argc, char **argv, char **envp) switch(popt->index) { case QEMU_OPTION_M: + qemu_opt_legacy_add("M", optarg); machine = find_machine(optarg); if (!machine) { QEMUMachine *m; @@ -4903,6 +4904,7 @@ int main(int argc, char **argv, char **envp) } break; case QEMU_OPTION_cpu: + qemu_opt_legacy_add("cpu", optarg); /* hw initialization will check this */ if (*optarg == '?') { /* XXX: implement xxx_cpu_list for targets that still miss it */ @@ -4915,6 +4917,7 @@ int main(int argc, char **argv, char **envp) } break; case QEMU_OPTION_initrd: + qemu_opt_legacy_add("initrd", optarg); initrd_filename = optarg; break; case QEMU_OPTION_hda: @@ -4951,6 +4954,7 @@ int main(int argc, char **argv, char **envp) drive_add(optarg, PFLASH_ALIAS); break; case QEMU_OPTION_snapshot: + qemu_opt_legacy_add("snapshot", NULL); snapshot = 1; break; case QEMU_OPTION_hdachs: @@ -5003,6 +5007,7 @@ int main(int argc, char **argv, char **envp) } break; case QEMU_OPTION_numa: + qemu_opt_legacy_add("numa", optarg); if (nb_numa_nodes >= MAX_NODES) { fprintf(stderr, "qemu: too many NUMA nodes\n"); exit(1); @@ -5010,26 +5015,32 @@ int main(int argc, char **argv, char **envp) numa_add(optarg); break; case QEMU_OPTION_nographic: + qemu_opt_legacy_add("nographic", NULL); display_type = DT_NOGRAPHIC; break; #ifdef CONFIG_CURSES case QEMU_OPTION_curses: + qemu_opt_legacy_add("curses", NULL); display_type = DT_CURSES; break; #endif case QEMU_OPTION_portrait: + qemu_opt_legacy_add("portrait", NULL); graphic_rotate = 1; break; case QEMU_OPTION_kernel: + qemu_opt_legacy_add("kernel", optarg); kernel_filename = optarg; break; case QEMU_OPTION_append: + qemu_opt_legacy_add("append", optarg); kernel_cmdline = optarg; break; case QEMU_OPTION_cdrom: drive_add(optarg, CDROM_ALIAS); break; case QEMU_OPTION_boot: + qemu_opt_legacy_add("boot", optarg); { static const char * const params[] = { "order", "once", "menu", NULL @@ -5084,6 +5095,7 @@ int main(int argc, char **argv, char **envp) break; #ifdef TARGET_I386 case QEMU_OPTION_no_fd_bootchk: + qemu_opt_legacy_add("no-fd-bootchk", NULL); fd_bootchk = 0; break; #endif @@ -5099,23 +5111,28 @@ int main(int argc, char **argv, char **envp) break; #ifdef CONFIG_SLIRP case QEMU_OPTION_tftp: + qemu_opt_legacy_add("tftp", optarg); legacy_tftp_prefix = optarg; break; case QEMU_OPTION_bootp: + qemu_opt_legacy_add("bootp", optarg); legacy_bootp_filename = optarg; break; #ifndef _WIN32 case QEMU_OPTION_smb: + qemu_opt_legacy_add("smb", optarg); if (net_slirp_smb(optarg) < 0) exit(1); break; #endif case QEMU_OPTION_redir: + qemu_opt_legacy_add("redir", optarg); if (net_slirp_redir(optarg) < 0) exit(1); break; #endif case QEMU_OPTION_bt: + qemu_opt_legacy_add("bt", optarg); add_device_config(DEV_BT, optarg); break; #ifdef HAS_AUDIO @@ -5124,6 +5141,7 @@ int main(int argc, char **argv, char **envp) exit (0); break; case QEMU_OPTION_soundhw: + qemu_opt_legacy_add("soundhw", optarg); select_soundhw (optarg); break; #endif @@ -5135,6 +5153,7 @@ int main(int argc, char **argv, char **envp) exit(0); break; case QEMU_OPTION_m: { + qemu_opt_legacy_add("m", optarg); uint64_t value; char *ptr; @@ -5164,6 +5183,7 @@ int main(int argc, char **argv, char **envp) break; } case QEMU_OPTION_d: + qemu_opt_legacy_add("d", optarg); { int mask; const CPULogItem *item; @@ -5180,32 +5200,41 @@ int main(int argc, char **argv, char **envp) } break; case QEMU_OPTION_s: + qemu_opt_legacy_add("s", NULL); gdbstub_dev = "tcp::" DEFAULT_GDBSTUB_PORT; break; case QEMU_OPTION_gdb: + qemu_opt_legacy_add("gdb", optarg); gdbstub_dev = optarg; break; case QEMU_OPTION_L: + qemu_opt_legacy_add("L", optarg); data_dir = optarg; break; case QEMU_OPTION_bios: + qemu_opt_legacy_add("bios", optarg); bios_name = optarg; break; case QEMU_OPTION_singlestep: + qemu_opt_legacy_add("singlestep", NULL); singlestep = 1; break; case QEMU_OPTION_S: + qemu_opt_legacy_add("S", NULL); autostart = 0; break; #ifndef _WIN32 case QEMU_OPTION_k: + qemu_opt_legacy_add("k", optarg); keyboard_layout = optarg; break; #endif case QEMU_OPTION_localtime: + qemu_opt_legacy_add("localtime", NULL); rtc_utc = 0; break; case QEMU_OPTION_vga: + qemu_opt_legacy_add("vga", optarg); select_vgahw (optarg); break; #if defined(TARGET_PPC) || defined(TARGET_SPARC) @@ -5245,6 +5274,7 @@ int main(int argc, char **argv, char **envp) break; #endif case QEMU_OPTION_echr: + qemu_opt_legacy_add("echr", optarg); { char *r; term_escape_char = strtol(optarg, &r, 0); @@ -5253,6 +5283,7 @@ int main(int argc, char **argv, char **envp) break; } case QEMU_OPTION_monitor: + qemu_opt_legacy_add("monitor", optarg); if (monitor_device_index >= MAX_MONITOR_DEVICES) { fprintf(stderr, "qemu: too many monitor devices \n"); exit(1); @@ -5271,6 +5302,7 @@ int main(int argc, char **argv, char **envp) } break; case QEMU_OPTION_serial: + qemu_opt_legacy_add("serial", optarg); if (serial_device_index >= MAX_SERIAL_PORTS) { fprintf(stderr, "qemu: too many serial ports\n"); exit(1); @@ -5279,6 +5311,7 @@ int main(int argc, char **argv, char **envp) serial_device_index++; break; case QEMU_OPTION_watchdog: + qemu_opt_legacy_add("watchdog", optarg); if (watchdog) { fprintf(stderr, "qemu: only one watchdog option may be given\n"); @@ -5287,12 +5320,14 @@ int main(int argc, char **argv, char **envp) watchdog = optarg; break; case QEMU_OPTION_watchdog_action: + qemu_opt_legacy_add("watchdog-action", optarg); if (select_watchdog_action(optarg) == -1) { fprintf(stderr, "Unknown -watchdog-action parameter \n"); exit(1); } break; case QEMU_OPTION_virtiocon: + qemu_opt_legacy_add("virtiocon", optarg); if (virtio_console_index >= MAX_VIRTIO_CONSOLES) { fprintf(stderr, "qemu: too many virtio consoles \n"); exit(1); @@ -5301,6 +5336,7 @@ int main(int argc, char **argv, char **envp) virtio_console_index++; break; case QEMU_OPTION_parallel: + qemu_opt_legacy_add("parallel", optarg); if (parallel_device_index >= MAX_PARALLEL_PORTS) { fprintf(stderr, "qemu: too many parallel ports\n"); exit(1); @@ -5309,45 +5345,57 @@ int main(int argc, char **argv, char **envp) parallel_device_index++; break; case QEMU_OPTION_loadvm: + qemu_opt_legacy_add("loadvm", optarg); loadvm = optarg; break; case QEMU_OPTION_full_screen: + qemu_opt_legacy_add("full-screen", NULL); full_screen = 1; break; #ifdef CONFIG_SDL case QEMU_OPTION_no_frame: + qemu_opt_legacy_add("no-frame", NULL); no_frame = 1; break; case QEMU_OPTION_alt_grab: + qemu_opt_legacy_add("alt-grab", NULL); alt_grab = 1; break; case QEMU_OPTION_ctrl_grab: + qemu_opt_legacy_add("ctrl-grab", NULL); ctrl_grab = 1; break; case QEMU_OPTION_no_quit: + qemu_opt_legacy_add("no-quit", NULL); no_quit = 1; break; case QEMU_OPTION_sdl: + qemu_opt_legacy_add("sdl", NULL); display_type = DT_SDL; break; #endif case QEMU_OPTION_pidfile: + qemu_opt_legacy_add("pidfile", optarg); pid_file = optarg; break; #ifdef TARGET_I386 case QEMU_OPTION_win2k_hack: + qemu_opt_legacy_add("win2k-hack", NULL); win2k_install_hack = 1; break; case QEMU_OPTION_rtc_td_hack: + qemu_opt_legacy_add("rtc-td-hack", NULL); rtc_td_hack = 1; break; case QEMU_OPTION_acpitable: + qemu_opt_legacy_add("acpitable", optarg); if(acpi_table_add(optarg) < 0) { fprintf(stderr, "Wrong acpi table provided\n"); exit(1); } break; case QEMU_OPTION_smbios: + qemu_opt_legacy_add("smbios", optarg); if(smbios_entry_add(optarg) < 0) { fprintf(stderr, "Wrong smbios provided\n"); exit(1); @@ -5356,13 +5404,16 @@ int main(int argc, char **argv, char **envp) #endif #ifdef CONFIG_KVM case QEMU_OPTION_enable_kvm: + qemu_opt_legacy_add("enable-kvm", NULL); kvm_allowed = 1; break; #endif case QEMU_OPTION_usb: + qemu_opt_legacy_add("usb", NULL); usb_enabled = 1; break; case QEMU_OPTION_usbdevice: + qemu_opt_legacy_add("usbdevice", optarg); usb_enabled = 1; add_device_config(DEV_USB, optarg); break; @@ -5372,6 +5423,7 @@ int main(int argc, char **argv, char **envp) } break; case QEMU_OPTION_smp: + qemu_opt_legacy_add("smp", optarg); smp_parse(optarg); if (smp_cpus < 1) { fprintf(stderr, "Invalid number of CPUs\n"); @@ -5388,17 +5440,21 @@ int main(int argc, char **argv, char **envp) } break; case QEMU_OPTION_vnc: + qemu_opt_legacy_add("vnc", optarg); display_type = DT_VNC; vnc_display = optarg; break; #ifdef TARGET_I386 case QEMU_OPTION_no_acpi: + qemu_opt_legacy_add("no-acpi", NULL); acpi_enabled = 0; break; case QEMU_OPTION_no_hpet: + qemu_opt_legacy_add("no-hpet", NULL); no_hpet = 1; break; case QEMU_OPTION_balloon: + qemu_opt_legacy_add("balloon", optarg); if (balloon_parse(optarg) < 0) { fprintf(stderr, "Unknown -balloon argument %s\n", optarg); exit(1); @@ -5406,15 +5462,19 @@ int main(int argc, char **argv, char **envp) break; #endif case QEMU_OPTION_no_reboot: + qemu_opt_legacy_add("no-reboot", NULL); no_reboot = 1; break; case QEMU_OPTION_no_shutdown: + qemu_opt_legacy_add("no-shutdown", NULL); no_shutdown = 1; break; case QEMU_OPTION_show_cursor: + qemu_opt_legacy_add("show-cursor", NULL); cursor_hide = 0; break; case QEMU_OPTION_uuid: + qemu_opt_legacy_add("uuid", optarg); if(qemu_uuid_parse(optarg, qemu_uuid) < 0) { fprintf(stderr, "Fail to parse UUID string." " Wrong format.\n"); @@ -5423,10 +5483,12 @@ int main(int argc, char **argv, char **envp) break; #ifndef _WIN32 case QEMU_OPTION_daemonize: + qemu_opt_legacy_add("daemonize", NULL); daemonize = 1; break; #endif case QEMU_OPTION_option_rom: + qemu_opt_legacy_add("option-rom", optarg); if (nb_option_roms >= MAX_OPTION_ROMS) { fprintf(stderr, "Too many option ROMs\n"); exit(1); @@ -5436,10 +5498,12 @@ int main(int argc, char **argv, char **envp) break; #if defined(TARGET_ARM) || defined(TARGET_M68K) case QEMU_OPTION_semihosting: + qemu_opt_legacy_add("semihosting", NULL); semihosting_enabled = 1; break; #endif case QEMU_OPTION_name: + qemu_opt_legacy_add("name", optarg); qemu_name = qemu_strdup(optarg); { char *p = strchr(qemu_name, ','); @@ -5456,6 +5520,7 @@ int main(int argc, char **argv, char **envp) break; #if defined(TARGET_SPARC) || defined(TARGET_PPC) case QEMU_OPTION_prom_env: + qemu_opt_legacy_add("prom-env", optarg); if (nb_prom_envs >= MAX_PROM_ENVS) { fprintf(stderr, "Too many prom variables\n"); exit(1); @@ -5466,13 +5531,16 @@ int main(int argc, char **argv, char **envp) #endif #ifdef TARGET_ARM case QEMU_OPTION_old_param: + qemu_opt_legacy_add("old-param", NULL); old_param = 1; break; #endif case QEMU_OPTION_clock: + qemu_opt_legacy_add("clock", optarg); configure_alarms(optarg); break; case QEMU_OPTION_startdate: + qemu_opt_legacy_add("startdate", optarg); configure_rtc_date_offset(optarg, 1); break; case QEMU_OPTION_rtc: @@ -5484,11 +5552,13 @@ int main(int argc, char **argv, char **envp) configure_rtc(opts); break; case QEMU_OPTION_tb_size: + qemu_opt_legacy_add("tb-size", optarg); tb_size = strtol(optarg, NULL, 0); if (tb_size < 0) tb_size = 0; break; case QEMU_OPTION_icount: + qemu_opt_legacy_add("icount", optarg); use_icount = 1; if (strcmp(optarg, "auto") == 0) { icount_time_shift = -1; @@ -5497,24 +5567,30 @@ int main(int argc, char **argv, char **envp) } break; case QEMU_OPTION_incoming: + qemu_opt_legacy_add("incoming", optarg); incoming = optarg; break; #ifndef _WIN32 case QEMU_OPTION_chroot: + qemu_opt_legacy_add("chroot", optarg); chroot_dir = optarg; break; case QEMU_OPTION_runas: + qemu_opt_legacy_add("runas", optarg); run_as = optarg; break; #endif #ifdef CONFIG_XEN case QEMU_OPTION_xen_domid: + qemu_opt_legacy_add("xen-domid", optarg); xen_domid = atoi(optarg); break; case QEMU_OPTION_xen_create: + qemu_opt_legacy_add("xen-create", NULL); xen_mode = XEN_CREATE; break; case QEMU_OPTION_xen_attach: + qemu_opt_legacy_add("xen-attach", NULL); xen_mode = XEN_ATTACH; break; #endif ^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [Qemu-devel] [PATCH 4/4] QemuOpts: command line switches for the config file. 2009-10-16 18:48 ` Nathan Baum @ 2009-10-16 19:33 ` Gerd Hoffmann 0 siblings, 0 replies; 14+ messages in thread From: Gerd Hoffmann @ 2009-10-16 19:33 UTC (permalink / raw) To: Nathan Baum; +Cc: qemu-devel On 10/16/09 20:48, Nathan Baum wrote: > In the medium term, perhaps a "legacy_options" option which can be > automatically parsed by -readconfig. > > In the short term, just put the non-QemuOpt options in a comment. > > (In the long term, hopefully there won't be any legacy options.) Yes. > I've knocked up something which does the short term solution. Hmm, I'd prefer to simply ignore legacy options. Then join forces for the long-term solution instead of implementing something temporary. cheers, Gerd ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [Qemu-devel] [PATCH 0/4] QemuOpts: config file support. 2009-10-14 8:39 [Qemu-devel] [PATCH 0/4] QemuOpts: config file support Gerd Hoffmann ` (3 preceding siblings ...) 2009-10-14 8:39 ` [Qemu-devel] [PATCH 4/4] QemuOpts: command line switches for the config file Gerd Hoffmann @ 2009-10-14 18:53 ` Anthony Liguori 2009-10-14 19:01 ` Anthony Liguori 5 siblings, 0 replies; 14+ messages in thread From: Anthony Liguori @ 2009-10-14 18:53 UTC (permalink / raw) To: Gerd Hoffmann; +Cc: qemu-devel Gerd Hoffmann wrote: > Hi, > > Very first cut of config file support, to get the discussion rolling ;) > I actually spent some time on this last week. I ran into a fundamental problem though--default devices don't have id's associated with them so there is no way to configure them via -set. Regards, Anthony Liguori > We might use this some day to provide defaults for vga, nic, serial etc. > Also host-wide defaults (network setup for example) should be doable. > Just needs some careful planning which config files to read in which > cases and in which order ;) > > cheers, > Gerd > > > > ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [Qemu-devel] [PATCH 0/4] QemuOpts: config file support. 2009-10-14 8:39 [Qemu-devel] [PATCH 0/4] QemuOpts: config file support Gerd Hoffmann ` (4 preceding siblings ...) 2009-10-14 18:53 ` [Qemu-devel] [PATCH 0/4] QemuOpts: config file support Anthony Liguori @ 2009-10-14 19:01 ` Anthony Liguori 2009-10-16 10:16 ` Gerd Hoffmann 5 siblings, 1 reply; 14+ messages in thread From: Anthony Liguori @ 2009-10-14 19:01 UTC (permalink / raw) To: Gerd Hoffmann; +Cc: qemu-devel Gerd Hoffmann wrote: > Hi, > > Very first cut of config file support, to get the discussion rolling ;) > > We might use this some day to provide defaults for vga, nic, serial etc. > Also host-wide defaults (network setup for example) should be doable. > Just needs some careful planning which config files to read in which > cases and in which order ;) > What I really want to do, which I don't think is possibly in right now, is: [net "default"] type=tap script=/etc/qemu-ifup-bridge In /etc/qemurc to globally change from slirp default to tap default. Of course, why stop there, we should install an /etc/qemurc by default with: [net "default"] type=user host=10.0.1.2 net=10.0.1.0/24 dhcpstart=10.0.1.10 dns=10.0.1.2 And completely get rid of any baked in defaults. Regards, Anthony Liguori ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [Qemu-devel] [PATCH 0/4] QemuOpts: config file support. 2009-10-14 19:01 ` Anthony Liguori @ 2009-10-16 10:16 ` Gerd Hoffmann 0 siblings, 0 replies; 14+ messages in thread From: Gerd Hoffmann @ 2009-10-16 10:16 UTC (permalink / raw) To: Anthony Liguori; +Cc: qemu-devel > What I really want to do, which I don't think is possibly in right now, is: > > [net "default"] > type=tap > script=/etc/qemu-ifup-bridge > > In /etc/qemurc to globally change from slirp default to tap default. Of > course, why stop there, we should install an /etc/qemurc by default with: > > [net "default"] > type=user > host=10.0.1.2 > net=10.0.1.0/24 > dhcpstart=10.0.1.10 > dns=10.0.1.2 > > And completely get rid of any baked in defaults. Yes. Kill all these automagic devices from qemu, move them into config files. So long-term we'll have something like: /usr/share/qemu/boards/pc.dtc -> your virtual mainboard, i.e. all piix3/4 and core stuff like pic, apic, ... /usr/share/qemu/defaults/pc.conf -> useful default configuration for pc, i.e. cirrus vga, e1000 nic, serial port, parallel port, cdrom drive, ... /etc/qemu/host.conf -> host-wide config, i.e. slirp networking, maybe chardevs for serial0+parallel0, ... $HOME/.qemu.conf (maybe) -> user-wide config qemu would (by default) read all these files in the specified order, additionally a virtual-machine config file specified on the command line. Asking qemu to NOT read defaults/pc.conf would zap all default devices from your configuration. Maybe it is useful to have some kind of profiles, i.e. /etc/qemu/default.conf, /etc/qemu/nographic.conf, ... cheers, Gerd ^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2009-10-16 19:34 UTC | newest] Thread overview: 14+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2009-10-14 8:39 [Qemu-devel] [PATCH 0/4] QemuOpts: config file support Gerd Hoffmann 2009-10-14 8:39 ` [Qemu-devel] [PATCH 1/4] QemuOpts: add find_list() Gerd Hoffmann 2009-10-14 8:39 ` [Qemu-devel] [PATCH 2/4] QemuOpts: dump config Gerd Hoffmann 2009-10-14 18:56 ` Anthony Liguori 2009-10-14 8:39 ` [Qemu-devel] [PATCH 3/4] QemuOpts: parse config from file Gerd Hoffmann 2009-10-14 18:55 ` Anthony Liguori 2009-10-14 8:39 ` [Qemu-devel] [PATCH 4/4] QemuOpts: command line switches for the config file Gerd Hoffmann 2009-10-16 18:39 ` Nathan Baum 2009-10-16 19:29 ` Gerd Hoffmann 2009-10-16 18:48 ` Nathan Baum 2009-10-16 19:33 ` Gerd Hoffmann 2009-10-14 18:53 ` [Qemu-devel] [PATCH 0/4] QemuOpts: config file support Anthony Liguori 2009-10-14 19:01 ` Anthony Liguori 2009-10-16 10:16 ` Gerd Hoffmann
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).