[netcf-devel] [PATCH 3/4] Allow multiple tables of Augeas transforms

David Lutterkort lutter at redhat.com
Thu Sep 10 19:28:45 UTC 2009


---
 src/drv_initscripts.c |   16 +++++++--
 src/dutil.c           |   94 ++++++++++++++++++++++++++++++++++++++----------
 src/dutil.h           |   18 ++++++++-
 3 files changed, 103 insertions(+), 25 deletions(-)

diff --git a/src/drv_initscripts.c b/src/drv_initscripts.c
index 86bf475..6436bcc 100644
--- a/src/drv_initscripts.c
+++ b/src/drv_initscripts.c
@@ -52,7 +52,7 @@ static const char *const ifcfg_path =
     "/files/etc/sysconfig/network-scripts/*";
 
 /* Augeas should only load the files we are interested in */
-static const struct augeas_pv augeas_xfm[] = {
+static const struct augeas_pv augeas_xfm_common_pv[] = {
     /* Ifcfg files */
     { "/augeas/load/Ifcfg/lens", "Shellvars.lns" },
     { "/augeas/load/Ifcfg/incl",
@@ -85,6 +85,10 @@ static const struct augeas_pv augeas_xfm[] = {
     { "/augeas/load/Sysfs/incl", "/sys/class/net/*/address" }
 };
 
+static const struct augeas_xfm_table augeas_xfm_common =
+    { .size = ARRAY_CARDINALITY(augeas_xfm_common_pv),
+      .pv = augeas_xfm_common_pv };
+
 static const char *const prog_lokkit = "/usr/sbin/lokkit";
 static const char *const lokkit_custom_rules =
     "--custom-rules=ipv4:filter:" DATADIR "/netcf/iptables-forward-bridged";
@@ -447,12 +451,16 @@ static void bridge_physdevs(struct netcf *ncf) {
 }
 
 int drv_init(struct netcf *ncf) {
+    int r;
+
     if (ALLOC(ncf->driver) < 0)
         return -1;
 
     ncf->driver->ioctl_fd = -1;
-    ncf->driver->augeas_xfm_size = ARRAY_CARDINALITY(augeas_xfm);
-    ncf->driver->augeas_xfm = augeas_xfm;
+
+    r = add_augeas_xfm_table(ncf, &augeas_xfm_common);
+    if (r < 0)
+        goto error;
 
     // FIXME: Check for errors
     xsltInit();
@@ -471,6 +479,7 @@ int drv_init(struct netcf *ncf) {
  error:
     if (ncf->driver->ioctl_fd >= 0)
         close(ncf->driver->ioctl_fd);
+    FREE(ncf->driver->augeas_xfm_tables);
     FREE(ncf->driver);
     return -1;
 }
@@ -482,6 +491,7 @@ void drv_close(struct netcf *ncf) {
     if (ncf->driver->ioctl_fd >= 0)
         close(ncf->driver->ioctl_fd);
     aug_close(ncf->driver->augeas);
+    FREE(ncf->driver->augeas_xfm_tables);
     FREE(ncf->driver);
 }
 
diff --git a/src/dutil.c b/src/dutil.c
index 24516a8..c044766 100644
--- a/src/dutil.c
+++ b/src/dutil.c
@@ -63,6 +63,50 @@ int xasprintf(char **strp, const char *format, ...) {
   return result;
 }
 
+int add_augeas_xfm_table(struct netcf *ncf,
+                         const struct augeas_xfm_table *xfm) {
+    int slot, r;
+    struct driver *d = ncf->driver;
+
+    if (d->augeas_xfm_num_tables == 0) {
+        slot = 0;
+        r = ALLOC(d->augeas_xfm_tables);
+        ERR_NOMEM(r < 0, ncf);
+        d->augeas_xfm_num_tables = 1;
+    } else {
+        for (slot =0;
+             slot < d->augeas_xfm_num_tables
+                 && d->augeas_xfm_tables[slot] != NULL;
+             slot++);
+        if (slot == d->augeas_xfm_num_tables) {
+            r = REALLOC_N(ncf->driver->augeas_xfm_tables, slot + 1);
+            ERR_COND_BAIL(r < 0, ncf, ENOMEM);
+            d->augeas_xfm_num_tables = slot + 1;
+        }
+    }
+
+    ncf->driver->augeas_xfm_tables[slot] = xfm;
+    ncf->driver->copy_augeas_xfm = 1;
+    return 0;
+ error:
+    return -1;
+}
+
+int remove_augeas_xfm_table(struct netcf *ncf,
+                            const struct augeas_xfm_table *xfm) {
+    int slot;
+    const int last = ncf->driver->augeas_xfm_num_tables;
+    const struct augeas_xfm_table **tables =
+        ncf->driver->augeas_xfm_tables;
+
+    for (slot = 0; slot < last && tables[slot] != xfm; slot++);
+    if (tables[slot] == xfm) {
+        tables[slot] = NULL;
+        ncf->driver->copy_augeas_xfm = 1;
+    }
+    return 0;
+}
+
 /* Get the Augeas instance; if we already initialized it, just return
  * it. Otherwise, create a new one and return that.
  */
@@ -80,17 +124,39 @@ struct augeas *get_augeas(struct netcf *ncf) {
         FREE(path);
         ERR_THROW(aug == NULL, ncf, EOTHER, "aug_init failed");
         ncf->driver->augeas = aug;
+        ncf->driver->copy_augeas_xfm = 1;
+    }
+
+    if (ncf->driver->copy_augeas_xfm) {
+        struct augeas *aug = ncf->driver->augeas;
         /* Only look at a few config files */
         r = aug_rm(aug, "/augeas/load/*");
         ERR_THROW(r < 0, ncf, EOTHER, "aug_rm failed in get_augeas");
 
-        for (int i=0; i < ncf->driver->augeas_xfm_size; i++) {
-            r = aug_set(aug, ncf->driver->augeas_xfm[i].path,
-                    ncf->driver->augeas_xfm[i].value);
-            ERR_THROW(r < 0, ncf, EOTHER,
-                      "transform setup failed to set %s",
-                      ncf->driver->augeas_xfm[i].path);
+        for (int slot = 0; slot < ncf->driver->augeas_xfm_num_tables; slot++) {
+            const struct augeas_xfm_table *t =
+                ncf->driver->augeas_xfm_tables[slot];
+            if (t == NULL)
+                continue;
+            for (int i=0; i < t->size; i++) {
+                r = aug_set(aug, t->pv[i].path, t->pv[i].value);
+                ERR_THROW(r < 0, ncf, EOTHER,
+                          "transform setup failed to set %s",
+                          t->pv[i].path);
+            }
         }
+        ncf->driver->copy_augeas_xfm = 0;
+        ncf->driver->load_augeas = 1;
+    }
+
+    if (ncf->driver->load_augeas) {
+        struct augeas *aug = ncf->driver->augeas;
+        /* Undefine all our variables to work around bug 79 in Augeas */
+        aug_defvar(aug, "iptables", NULL);
+        aug_defvar(aug, "fw", NULL);
+        aug_defvar(aug, "fw_custom", NULL);
+        aug_defvar(aug, "ipt_filter", NULL);
+
         r = aug_load(aug);
         ERR_THROW(r < 0, ncf, EOTHER, "failed to load config files");
 
@@ -105,20 +171,8 @@ struct augeas *get_augeas(struct netcf *ncf) {
             fprintf(stderr, "please file a bug with the following lines in the bug report:\n");
             aug_print(aug, stderr, "/augeas//error");
         }
-        ERR_THROW(r > 0, ncf, EOTHER, "errors in augeas initialization");
-    } else {
-        if (ncf->driver->load_augeas) {
-            struct augeas *aug = ncf->driver->augeas;
-            /* Undefine all our variables to work around bug 79 in Augeas */
-            aug_defvar(aug, "iptables", NULL);
-            aug_defvar(aug, "fw", NULL);
-            aug_defvar(aug, "fw_custom", NULL);
-            aug_defvar(aug, "ipt_filter", NULL);
-
-            r = aug_load(ncf->driver->augeas);
-            ERR_THROW(r < 0, ncf, EOTHER, "failed to reload config files");
-            ncf->driver->load_augeas = 0;
-        }
+        ERR_THROW(r > 0, ncf, EOTHER, "errors in loading some config files");
+        ncf->driver->load_augeas = 0;
     }
     return ncf->driver->augeas;
  error:
diff --git a/src/dutil.h b/src/dutil.h
index 38aec5f..fc86e00 100644
--- a/src/dutil.h
+++ b/src/dutil.h
@@ -33,8 +33,9 @@ struct driver {
     xmlRelaxNGPtr      rng;
     int                ioctl_fd;
     unsigned int       load_augeas : 1;
-    unsigned int augeas_xfm_size;
-    const struct augeas_pv *augeas_xfm;
+    unsigned int       copy_augeas_xfm : 1;
+    unsigned int       augeas_xfm_num_tables;
+    const struct augeas_xfm_table **augeas_xfm_tables;
 };
 
 struct augeas_pv {
@@ -42,9 +43,22 @@ struct augeas_pv {
     const char *const value;
 };
 
+struct augeas_xfm_table {
+    unsigned int            size;
+    const struct augeas_pv *pv;
+};
+
 /* Like asprintf, but set *STRP to NULL on error */
 int xasprintf(char **strp, const char *format, ...);
 
+/* Add a table of transformations that the next GET_AUGEAS should run */
+int add_augeas_xfm_table(struct netcf *ncf,
+                         const struct augeas_xfm_table *table);
+
+/* Remove a table of transformations that the next GET_AUGEAS should run */
+int remove_augeas_xfm_table(struct netcf *ncf,
+                            const struct augeas_xfm_table *table);
+
 /* Get or create the augeas instance from NCF */
 struct augeas *get_augeas(struct netcf *ncf);
 
-- 
1.6.2.5



More information about the netcf-devel mailing list