From 3daa14834ae9ffab55cae67808508d47d1b53dbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Bosdonnat?= Date: Wed, 5 Feb 2014 15:09:59 +0100 Subject: [PATCH] Improve virConf parse to handle LXC config format virConf now honours a VIR_CONF_FLAG_LXC_FORMAT flag to handle LXC configuration files. The differences are that property names can contain '.' character and values are all strings without any bounding quotes. Provide a new virConfWalk function calling a handler on all non-comment values. This function will be used by the LXC conversion code to loop over LXC configuration lines. --- src/libvirt_private.syms | 1 + src/util/virconf.c | 46 ++++++++++++++++++++++++++++++++++++++-- src/util/virconf.h | 10 +++++++++ 3 files changed, 55 insertions(+), 2 deletions(-) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 2c9536aa9a..0b28bac26c 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1130,6 +1130,7 @@ virConfNew; virConfReadFile; virConfReadMem; virConfSetValue; +virConfWalk; virConfWriteFile; virConfWriteMem; diff --git a/src/util/virconf.c b/src/util/virconf.c index e882d15075..63aa56918d 100644 --- a/src/util/virconf.c +++ b/src/util/virconf.c @@ -429,6 +429,16 @@ virConfParseString(virConfParserCtxtPtr ctxt) if (VIR_STRNDUP(ret, base, ctxt->cur - base) < 0) return NULL; NEXT; + } else if (ctxt->conf->flags & VIR_CONF_FLAG_LXC_FORMAT) { + base = ctxt->cur; + /* LXC config format doesn't support comments after the value */ + while ((ctxt->cur < ctxt->end) && (!IS_EOL(CUR))) + NEXT; + /* Reverse to exclude the trailing blanks from the value */ + while ((ctxt->cur > base) && (c_isblank(CUR))) + ctxt->cur--; + if (VIR_STRNDUP(ret, base, ctxt->cur - base) < 0) + return NULL; } return ret; } @@ -454,7 +464,8 @@ virConfParseValue(virConfParserCtxtPtr ctxt) virConfError(ctxt, VIR_ERR_CONF_SYNTAX, _("expecting a value")); return NULL; } - if ((CUR == '"') || (CUR == '\'')) { + if ((CUR == '"') || (CUR == '\'') || + (ctxt->conf->flags & VIR_CONF_FLAG_LXC_FORMAT)) { type = VIR_CONF_STRING; str = virConfParseString(ctxt); if (str == NULL) @@ -561,7 +572,9 @@ virConfParseName(virConfParserCtxtPtr ctxt) while ((ctxt->cur < ctxt->end) && (c_isalnum(CUR) || (CUR == '_') || ((ctxt->conf->flags & VIR_CONF_FLAG_VMX_FORMAT) && - ((CUR == ':') || (CUR == '.') || (CUR == '-'))))) + ((CUR == ':') || (CUR == '.') || (CUR == '-'))) || + ((ctxt->conf->flags & VIR_CONF_FLAG_LXC_FORMAT) && + (CUR == '.')))) NEXT; if (VIR_STRNDUP(ret, base, ctxt->cur - base) < 0) return NULL; @@ -905,6 +918,35 @@ virConfSetValue(virConfPtr conf, return 0; } +/** + * virConfWalk: + * @conf: a configuration file handle + * @callback: the function to call to process each entry + * @data: obscure data passed to callback + * + * Walk over all entries of the configuration file and run the callback + * for each with entry name, value and the obscure data. + * + * Returns 0 on success, or -1 on failure. + */ +int virConfWalk(virConfPtr conf, + virConfWalkCallback callback, + void *opaque) +{ + virConfEntryPtr cur; + + if (!conf) + return 0; + + cur = conf->entries; + while (cur != NULL) { + if (cur->name && cur->value && + callback(cur->name, cur->value, opaque) < 0) + return -1; + cur = cur->next; + } + return 0; +} /** * virConfWriteFile: diff --git a/src/util/virconf.h b/src/util/virconf.h index 577af8c547..2a6b050d98 100644 --- a/src/util/virconf.h +++ b/src/util/virconf.h @@ -40,6 +40,9 @@ typedef enum { VIR_CONF_FLAG_VMX_FORMAT = 1, /* allow ':', '.' and '-' in names for compatibility with VMware VMX configuration file, but restrict allowed value types to string only */ + VIR_CONF_FLAG_LXC_FORMAT = 2, /* allow '.' in names for compatibility with LXC + configuration file, restricts allowed value types + to string only and don't expect quotes for values */ } virConfFlags; static inline const char * @@ -79,6 +82,10 @@ struct _virConfValue { typedef struct _virConf virConf; typedef virConf *virConfPtr; +typedef int (*virConfWalkCallback)(const char* name, + virConfValuePtr value, + void *opaque); + virConfPtr virConfNew (void); virConfPtr virConfReadFile (const char *filename, unsigned int flags); virConfPtr virConfReadMem (const char *memory, @@ -91,6 +98,9 @@ virConfValuePtr virConfGetValue (virConfPtr conf, int virConfSetValue (virConfPtr conf, const char *setting, virConfValuePtr value); +int virConfWalk(virConfPtr conf, + virConfWalkCallback callback, + void *opaque); int virConfWriteFile (const char *filename, virConfPtr conf); int virConfWriteMem (char *memory,