Blame SOURCES/netcf-optimize-aug_match-query-for-all-ifcfg-files-related.patch

ff66b3
From 396e4e0698d9fb542f2eb8b32790a069e1c0df61 Mon Sep 17 00:00:00 2001
ff66b3
From: Laine Stump <laine@laine.org>
ff66b3
Date: Wed, 7 Oct 2015 13:49:45 -0400
ff66b3
Subject: [PATCH] optimize aug_match() query for all ifcfg files related to an
ff66b3
 interface
ff66b3
ff66b3
This resolves:
ff66b3
ff66b3
 https://bugzilla.redhat.com/show_bug.cgi?id=1271341 (Fedora)
ff66b3
 https://bugzilla.redhat.com/show_bug.cgi?id=1269613 (RHEL7)
ff66b3
ff66b3
The original augeas search term used by netcf to find, for example, all the
ff66b3
ifcfg files associated with device "br1" was:
ff66b3
ff66b3
     "/files/etc/sysconfig/network-scripts/*[ "
ff66b3
     "DEVICE = 'br1' or BRIDGE = 'br1' or MASTER = 'br1' or MASTER = "
ff66b3
     "../*[BRIDGE = 'br1']/DEVICE ]/DEVICE"
ff66b3
ff66b3
This is *extremely* inefficient - on a test host with 514 host
ff66b3
bridges, each with an attached vlan interface, a dumpxml of all
ff66b3
toplevel interfaces took 6m40s (*after* installing an augeas that
ff66b3
included augeas upstream commits a659f09a, 41e989ca, and 23d5e480
ff66b3
which were all pushed after the augeas-1.4.0 release).
ff66b3
ff66b3
In these two messages:
ff66b3
ff66b3
 https://www.redhat.com/archives/augeas-devel/2015-October/msg00003.html
ff66b3
 https://www.redhat.com/archives/augeas-devel/2015-October/msg00004.html
ff66b3
ff66b3
David Lutterkort suggested changing the search term to:
ff66b3
ff66b3
  "(/files/etc/sysconfig/network-scripts/*[(DEVICE|BRIDGE|MASTER) = 'br1']"
ff66b3
  "|/files/etc/sysconfig/network-scripts/*[MASTER]"
ff66b3
  "[MASTER = ../*[BRIDGE = 'br1']/DEVICE ])/DEVICE
ff66b3
ff66b3
That's what this patch does. Testing shows that it is functionally
ff66b3
equivalent, and reduces the dumpxml time in the previously described
ff66b3
test from 6m40s down to 17 seconds.
ff66b3
---
ff66b3
 src/drv_redhat.c | 44 ++++++++++++++++++++++++++++++++++----------
ff66b3
 1 file changed, 34 insertions(+), 10 deletions(-)
ff66b3
ff66b3
diff --git a/src/drv_redhat.c b/src/drv_redhat.c
ff66b3
index 4935f98..092ef5c 100644
ff66b3
--- a/src/drv_redhat.c
ff66b3
+++ b/src/drv_redhat.c
ff66b3
@@ -88,6 +88,38 @@ static const struct augeas_xfm_table augeas_xfm_common =
ff66b3
     { .size = ARRAY_CARDINALITY(augeas_xfm_common_pv),
ff66b3
       .pv = augeas_xfm_common_pv };
ff66b3
 
ff66b3
+/* aug_all_related_ifcfgs() - return the count of (and optionally a list
ff66b3
+ * of, if matches != NULL) the paths for all ifcfg files that are
ff66b3
+ * related to the interface "name".
ff66b3
+ */
ff66b3
+static
ff66b3
+int aug_all_related_ifcfgs(struct netcf *ncf, char ***matches, const char *name) {
ff66b3
+    int nmatches;
ff66b3
+
ff66b3
+    /* this includes the ifcfg files for:
ff66b3
+     *
ff66b3
+     * 1) the named interface itself (DEVICE=$name)
ff66b3
+     *
ff66b3
+     * 2) any interface naming $name as a bridge it is attached to
ff66b3
+     *    (BRIDGE=$name)
ff66b3
+     *
ff66b3
+     * 3) any interface naming $name as the master of a bond it is
ff66b3
+     *    enslaved to (MASTER=$name)
ff66b3
+     *
ff66b3
+     * 4) any interface with a MASTER, where the device named as
ff66b3
+     *    MASTER contains a BRIDGE=$name *and* DEVICE=$itself (thus
ff66b3
+     *    catching ethernet devices that are enslaved to a bond that
ff66b3
+     *    is attached to a bridge).
ff66b3
+     */
ff66b3
+    nmatches = aug_fmt_match(ncf, matches,
ff66b3
+                             "(%s[(DEVICE|BRIDGE|MASTER) = '%s']"
ff66b3
+                             "|%s[MASTER][MASTER = ../*[BRIDGE = '%s']/DEVICE "
ff66b3
+                             "])/DEVICE",
ff66b3
+                             ifcfg_path, name, ifcfg_path, name);
ff66b3
+    return nmatches;
ff66b3
+
ff66b3
+}
ff66b3
+
ff66b3
 /* Entries in a ifcfg file that tell us that the interface
ff66b3
  * is not a toplevel interface
ff66b3
  */
ff66b3
@@ -108,12 +140,7 @@ static int is_slave(struct netcf *ncf, const char *intf) {
ff66b3
 static bool has_ifcfg_file(struct netcf *ncf, const char *name) {
ff66b3
     int nmatches;
ff66b3
 
ff66b3
-    nmatches = aug_fmt_match(ncf, NULL,
ff66b3
-                             "%s[ DEVICE = '%s'"
ff66b3
-                             "    or BRIDGE = '%s'"
ff66b3
-                             "    or MASTER = '%s'"
ff66b3
-                             "    or MASTER = ../*[BRIDGE = '%s']/DEVICE ]/DEVICE",
ff66b3
-                             ifcfg_path, name, name, name, name);
ff66b3
+    nmatches = aug_all_related_ifcfgs(ncf, NULL, name);
ff66b3
     return nmatches > 0;
ff66b3
 }
ff66b3
 
ff66b3
@@ -588,10 +615,7 @@ static xmlDocPtr aug_get_xml_for_nif(struct netcf_if *nif) {
ff66b3
     int ndevs = 0, nint = 0;
ff66b3
 
ff66b3
     ncf = nif->ncf;
ff66b3
-    ndevs = aug_fmt_match(ncf, &devs,
ff66b3
-              "%s[ DEVICE = '%s' or BRIDGE = '%s' or MASTER = '%s'"
ff66b3
-              "    or MASTER = ../*[BRIDGE = '%s']/DEVICE ]/DEVICE",
ff66b3
-              ifcfg_path, nif->name, nif->name, nif->name, nif->name);
ff66b3
+    ndevs = aug_all_related_ifcfgs(ncf, &devs, nif->name);
ff66b3
     ERR_BAIL(ncf);
ff66b3
 
ff66b3
     nint = uniq_ifcfg_paths(ncf, ndevs, devs, &intf;;
ff66b3
-- 
ff66b3
2.4.3
ff66b3