[libvirt] [PATCH v3 01/21] Improve virConf parse to handle LXC config format

Cédric Bosdonnat cbosdonnat at suse.com
Wed Feb 5 14:09:59 UTC 2014


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 c5a7637..ba10b4e 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1128,6 +1128,7 @@ virConfNew;
 virConfReadFile;
 virConfReadMem;
 virConfSetValue;
+virConfWalk;
 virConfWriteFile;
 virConfWriteMem;
 
diff --git a/src/util/virconf.c b/src/util/virconf.c
index e882d15..63aa569 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 577af8c..2a6b050 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,
-- 
1.8.5.2




More information about the libvir-list mailing list