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