summaryrefslogtreecommitdiffstats
path: root/etc
diff options
context:
space:
mode:
authorSeth Mos <seth.mos@xs4all.nl>2009-03-13 02:43:57 +0100
committerSeth Mos <seth.mos@xs4all.nl>2009-03-13 02:43:57 +0100
commit957d8f756240363ad43ac68a4c18b7f9e8e1c57b (patch)
tree19012d4f239df5f6b193981bcd80ff29b5b71c2b /etc
parent6edc48fe40c2167182cd88a86c43de8f514e5531 (diff)
downloadpfsense-957d8f756240363ad43ac68a4c18b7f9e8e1c57b.zip
pfsense-957d8f756240363ad43ac68a4c18b7f9e8e1c57b.tar.gz
Rewrite the rrd upgrade code to use the newly added xml2array function specifically for the rrd upgrade code.
This is about 4 times faster then our builtin parser. Hoping this can solve part of the the 45 minute upgrade cycles on embedded builds
Diffstat (limited to 'etc')
-rw-r--r--etc/inc/config.inc16
-rw-r--r--etc/inc/rrd.inc136
2 files changed, 147 insertions, 5 deletions
diff --git a/etc/inc/config.inc b/etc/inc/config.inc
index faf5af7..7c8597e 100644
--- a/etc/inc/config.inc
+++ b/etc/inc/config.inc
@@ -2086,7 +2086,9 @@ endif;
mwexec("$rrdtool tune {$rrddbpath}{$database} -r roundtrip:delay 2>&1");
dump_rrd_to_xml("{$rrddbpath}/{$database}", "{$g['tmp_path']}/{$xmldump}");
- $rrdold = parse_xml_config_raw("{$g['tmp_path']}/{$xmldump}", "rrd");
+ $rrdoldxml = file_get_contents("{$g['tmp_path']}/{$xmldump}");
+ $rrdold = xml2array($rrdoldxml, 1, "tag");
+ $rrdold = $rrdold['rrd'];
$i = 0;
foreach($rrdold['rra'] as $rra) {
@@ -2140,9 +2142,14 @@ endif;
/* create temporary xml from new RRD */
dump_rrd_to_xml("{$g['tmp_path']}/{$databasetmp}", "{$g['tmp_path']}/{$xmldumptmp}");
- $rrdold = parse_xml_config_raw("{$g['tmp_path']}/{$xmldump}", "rrd");
- $rrdnew = parse_xml_config_raw("{$g['tmp_path']}/{$xmldumptmp}", "rrd");
-
+ $rrdoldxml = file_get_contents("{$g['tmp_path']}/{$xmldump}");
+ $rrdold = xml2array($rrdoldxml, 1, "tag");
+ $rrdold = $rrdold['rrd'];
+
+ $rrdnewxml = file_get_contents("{$g['tmp_path']}/{$xmldumptmp}");
+ $rrdnew = xml2array($rrdnewxml, 1, "tag");
+ $rrdnew = $rrdnew['rrd'];
+
/* remove any MAX RRA's. Not needed for traffic. */
$i = 0;
foreach ($rrdold['rra'] as $rra) {
@@ -2156,7 +2163,6 @@ endif;
$rrdxml = dump_xml_config_raw($rrdxmlarray, "rrd");
file_put_contents("{$g['tmp_path']}/{$xmldumpnew}", $rrdxml);
mwexec("$rrdtool restore -f {$g['tmp_path']}/{$xmldumpnew} {$rrddbpath}/{$database} 2>&1");
- // mwexec("$rrdtool resize {$rrddbpath}/{$database} 3 GROW 3000 2>&1");
}
enable_rrd_graphing();
diff --git a/etc/inc/rrd.inc b/etc/inc/rrd.inc
index 1d02970..1160f40 100644
--- a/etc/inc/rrd.inc
+++ b/etc/inc/rrd.inc
@@ -616,3 +616,139 @@ function kill_traffic_collector() {
mwexec("ps awwwux | grep '/[u]pdaterrd.sh' | awk '{print $2}' | xargs kill");
}
+/* This xml 2 array function is courtesy of the php.net comment section on xml_parse.
+ * it is roughly 4 times faster then our existing pfSense parser but due to the large
+ * size of the RRD xml dumps this is required.
+ * The reason we do not use it for pfSense is that it does not know about array fields
+ * which causes it to fail on array fields with single items. Possible Todo?
+ */
+function xml2array($contents, $get_attributes = 1, $priority = 'tag')
+{
+ if (!function_exists('xml_parser_create'))
+ {
+ return array ();
+ }
+ $parser = xml_parser_create('');
+ xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING, "UTF-8");
+ xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
+ xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1);
+ xml_parse_into_struct($parser, trim($contents), $xml_values);
+ xml_parser_free($parser);
+ if (!$xml_values)
+ return; //Hmm...
+ $xml_array = array ();
+ $parents = array ();
+ $opened_tags = array ();
+ $arr = array ();
+ $current = & $xml_array;
+ $repeated_tag_index = array ();
+ foreach ($xml_values as $data)
+ {
+ unset ($attributes, $value);
+ extract($data);
+ $result = array ();
+ $attributes_data = array ();
+ if (isset ($value))
+ {
+ if ($priority == 'tag')
+ $result = $value;
+ else
+ $result['value'] = $value;
+ }
+ if (isset ($attributes) and $get_attributes)
+ {
+ foreach ($attributes as $attr => $val)
+ {
+ if ($priority == 'tag')
+ $attributes_data[$attr] = $val;
+ else
+ $result['attr'][$attr] = $val; //Set all the attributes in a array called 'attr'
+ }
+ }
+ if ($type == "open")
+ {
+ $parent[$level -1] = & $current;
+ if (!is_array($current) or (!in_array($tag, array_keys($current))))
+ {
+ $current[$tag] = $result;
+ if ($attributes_data)
+ $current[$tag . '_attr'] = $attributes_data;
+ $repeated_tag_index[$tag . '_' . $level] = 1;
+ $current = & $current[$tag];
+ }
+ else
+ {
+ if (isset ($current[$tag][0]))
+ {
+ $current[$tag][$repeated_tag_index[$tag . '_' . $level]] = $result;
+ $repeated_tag_index[$tag . '_' . $level]++;
+ }
+ else
+ {
+ $current[$tag] = array (
+ $current[$tag],
+ $result
+ );
+ $repeated_tag_index[$tag . '_' . $level] = 2;
+ if (isset ($current[$tag . '_attr']))
+ {
+ $current[$tag]['0_attr'] = $current[$tag . '_attr'];
+ unset ($current[$tag . '_attr']);
+ }
+ }
+ $last_item_index = $repeated_tag_index[$tag . '_' . $level] - 1;
+ $current = & $current[$tag][$last_item_index];
+ }
+ }
+ elseif ($type == "complete")
+ {
+ if (!isset ($current[$tag]))
+ {
+ $current[$tag] = $result;
+ $repeated_tag_index[$tag . '_' . $level] = 1;
+ if ($priority == 'tag' and $attributes_data)
+ $current[$tag . '_attr'] = $attributes_data;
+ }
+ else
+ {
+ if (isset ($current[$tag][0]) and is_array($current[$tag]))
+ {
+ $current[$tag][$repeated_tag_index[$tag . '_' . $level]] = $result;
+ if ($priority == 'tag' and $get_attributes and $attributes_data)
+ {
+ $current[$tag][$repeated_tag_index[$tag . '_' . $level] . '_attr'] = $attributes_data;
+ }
+ $repeated_tag_index[$tag . '_' . $level]++;
+ }
+ else
+ {
+ $current[$tag] = array (
+ $current[$tag],
+ $result
+ );
+ $repeated_tag_index[$tag . '_' . $level] = 1;
+ if ($priority == 'tag' and $get_attributes)
+ {
+ if (isset ($current[$tag . '_attr']))
+ {
+ $current[$tag]['0_attr'] = $current[$tag . '_attr'];
+ unset ($current[$tag . '_attr']);
+ }
+ if ($attributes_data)
+ {
+ $current[$tag][$repeated_tag_index[$tag . '_' . $level] . '_attr'] = $attributes_data;
+ }
+ }
+ $repeated_tag_index[$tag . '_' . $level]++; //0 and 1 index is already taken
+ }
+ }
+ }
+ elseif ($type == 'close')
+ {
+ $current = & $parent[$level -1];
+ }
+ }
+ return ($xml_array);
+}
+
+?>
OpenPOWER on IntegriCloud