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

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