|
|
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 |
|