[libvirt] libvirt and redis

B Gordon bbgordonn at fastmail.fm
Tue Apr 26 15:48:34 UTC 2011


Is there interest in teaching libvirt to store configs in a DB? I'd
like to talk out what's desirable in the scope and design with someone
who knows libvirt.

My eventual goal is to synchronize config between multiple libvirtds
using Redis. I've been playing with a prototype that abstracts config
writing and reading into handlers that can be selected at run time or
from libvirtd.conf. This was to get me some familiarity--please tell
me what aspects I should change to suit the rest of libvirt.

The high-level, emphasizing the more questionable aspects:

* "conf drivers" that cargo-cult the jargon used in "drivers" a bit
even though they (currently) aren't quite a fit with the way current
ones are used.

* One global conf driver, because it needs to be accessed in other
state drivers when a connection is not currently present in the API.

* conf drivers present a file system-like key/value API to the rest of
libvirt to minimize disruption. They receive an XML string to store
and must be able to list the keys in a given "directory". Retrieval
is done by passing an optional callback to xml.c that it will use
instead of xmlCtxtReadFile().

* Keys should probably not include the full sysconfdir path, and
many other ways the prototype is too FS-like.

* With a relational DB, API calls to store each type of libvirt struct
might make more sense than formatted XML strings. I have not tried to
do this and vaguely hope that working with XML in a relational DB
would be acceptable or that those calls could be added later. Using
the DB's native XML handling might better for abstraction, actually.

* The conf driver needs a way to receive parameters from
libvirtd.conf. URI parsing? Some other key-value format?

As a low-level example, here's my (current, expected to change based
on feedback!) conversion of domain_conf.c:

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index b6aaf33..0c7bb3c 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -47,6 +47,7 @@
 #include "storage_file.h"
 #include "files.h"
 #include "bitmap.h"
+#include "conf_driver.h"
 
 #define VIR_FROM_THIS VIR_FROM_DOMAIN
 
@@ -6158,7 +6159,7 @@ virDomainDefParse(const char *xmlStr,
     xmlDocPtr xml;
     virDomainDefPtr def = NULL;
 
-    if ((xml = virXMLParse(filename, xmlStr, "domain.xml"))) {
+    if ((xml = virConfParse(filename, xmlStr, "domain.xml"))) {
         def = virDomainDefParseNode(caps, xml,
         xmlDocGetRootElement(xml), flags);
         xmlFreeDoc(xml);
     }
@@ -6245,7 +6246,7 @@ virDomainObjPtr virDomainObjParseFile(virCapsPtr
caps,
     xmlDocPtr xml;
     virDomainObjPtr obj = NULL;
 
-    if ((xml = virXMLParseFile(filename))) {
+    if ((xml = virConfParse(filename, NULL, filename))) {
         obj = virDomainObjParseNode(caps, xml,
         xmlDocGetRootElement(xml));
         xmlFreeDoc(xml);
     }
@@ -8324,46 +8325,26 @@ int virDomainSaveXML(const char *configDir,
                      const char *xml)
 {
     char *configFile = NULL;
-    int fd = -1, ret = -1;
-    size_t towrite;
+    int ret = -1;
+    int err;
 
     if ((configFile = virDomainConfigFile(configDir, def->name)) ==
     NULL)
         goto cleanup;
 
-    if (virFileMakePath(configDir)) {
-        virReportSystemError(errno,
+    if ((err = virConfMakePath(configDir, 0))) {
+        virReportSystemError(err,
                              _("cannot create config directory '%s'"),
                              configDir);
         goto cleanup;
     }
 
-    if ((fd = open(configFile,
-                   O_WRONLY | O_CREAT | O_TRUNC,
-                   S_IRUSR | S_IWUSR )) < 0) {
-        virReportSystemError(errno,
-                             _("cannot create config file '%s'"),
-                             configFile);
-        goto cleanup;
-    }
-
-    towrite = strlen(xml);
-    if (safewrite(fd, xml, towrite) < 0) {
-        virReportSystemError(errno,
-                             _("cannot write config file '%s'"),
-                             configFile);
-        goto cleanup;
-    }
-
-    if (VIR_CLOSE(fd) < 0) {
-        virReportSystemError(errno,
-                             _("cannot save config file '%s'"),
-                             configFile);
+    if (virConfSave(configFile, xml, 0) < 0) {
         goto cleanup;
     }
 
     ret = 0;
+
  cleanup:
-    VIR_FORCE_CLOSE(fd);
 
     VIR_FREE(configFile);
     return ret;
@@ -8441,7 +8422,7 @@ static virDomainObjPtr
virDomainLoadConfig(virCapsPtr caps,
     if ((autostartLink = virDomainConfigFile(autostartDir, name)) ==
     NULL)
         goto error;
 
-    if ((autostart = virFileLinkPointsTo(autostartLink, configFile)) <
0)
+    if ((autostart = virConfLinkPointsTo(autostartLink, configFile, 0))
< 0)
         goto error;
 
     if (!(dom = virDomainAssignDef(caps, doms, def, false)))
@@ -8514,12 +8495,12 @@ int virDomainLoadAllConfigs(virCapsPtr caps,
                             virDomainLoadConfigNotify notify,
                             void *opaque)
 {
-    DIR *dir;
-    struct dirent *entry;
+    virConfDirPtr dir;
+    virConfDirEntryPtr entry;
 
     VIR_INFO("Scanning for configs in %s", configDir);
 
-    if (!(dir = opendir(configDir))) {
+    if (!(dir = virConfOpenDir(configDir, 0))) {
         if (errno == ENOENT)
             return 0;
         virReportSystemError(errno,
@@ -8528,23 +8509,17 @@ int virDomainLoadAllConfigs(virCapsPtr caps,
         return -1;
     }
 
-    while ((entry = readdir(dir))) {
+    while ((entry = virConfReadDir(dir, 0))) {
         virDomainObjPtr dom;
 
-        if (entry->d_name[0] == '.')
-            continue;
-
-        if (!virFileStripSuffix(entry->d_name, ".xml"))
-            continue;
-
         /* NB: ignoring errors, so one malformed config doesn't
            kill the whole process */
-        VIR_INFO("Loading config file '%s.xml'", entry->d_name);
+        VIR_INFO("Loading config file '%s.xml'", entry->name);
         if (liveStatus)
             dom = virDomainLoadStatus(caps,
                                       doms,
                                       configDir,
-                                      entry->d_name,
+                                      entry->name,
                                       notify,
                                       opaque);
         else
@@ -8552,7 +8527,7 @@ int virDomainLoadAllConfigs(virCapsPtr caps,
                                       doms,
                                       configDir,
                                       autostartDir,
-                                      entry->d_name,
+                                      entry->name,
                                       notify,
                                       opaque);
         if (dom) {
@@ -8562,7 +8537,7 @@ int virDomainLoadAllConfigs(virCapsPtr caps,
         }
     }
 
-    closedir(dir);
+    virConfCloseDir(dir, 0);
 
     return 0;
 }
@@ -8580,9 +8555,9 @@ int virDomainDeleteConfig(const char *configDir,
         goto cleanup;
 
     /* Not fatal if this doesn't work */
-    unlink(autostartLink);
+    virConfDeletePath(autostartLink, 0);
 
-    if (unlink(configFile) < 0 &&
+    if (virConfDeletePath(autostartLink, 0) < 0 &&
         errno != ENOENT) {
         virReportSystemError(errno,
                              _("cannot remove config %s"),
@@ -8863,7 +8838,7 @@ virDomainSnapshotDefPtr
virDomainSnapshotDefParseString(const char *xmlStr,
     char *creation = NULL, *state = NULL;
     struct timeval tv;
 
-    xml = virXMLParse(NULL, xmlStr, "domainsnapshot.xml");
+    xml = virXMLParseString(xmlStr, "domainsnapshot.xml");
     if (!xml) {
         virDomainReportError(VIR_ERR_XML_ERROR,
                              "%s",_("failed to parse snapshot xml
                              document"));


-- 
http://www.fastmail.fm - Choose from over 50 domains or use your own




More information about the libvir-list mailing list