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

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