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

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