1616// under the License.
1717package org .apache .cloudstack .utils .linux ;
1818
19- import com .cloud .hypervisor .kvm .resource .LibvirtCapXMLParser ;
20- import com .cloud .hypervisor .kvm .resource .LibvirtConnection ;
21- import com .cloud .utils .script .Script ;
19+ import java .io .FileReader ;
20+ import java .io .IOException ;
21+ import java .io .Reader ;
22+ import java .io .StringReader ;
23+ import java .util .ArrayList ;
24+ import java .util .List ;
2225
26+ import javax .xml .parsers .DocumentBuilder ;
27+ import javax .xml .parsers .DocumentBuilderFactory ;
28+
29+ import org .apache .cloudstack .utils .security .ParserUtils ;
2330import org .apache .commons .io .IOUtils ;
31+ import org .apache .commons .lang3 .StringUtils ;
2432import org .apache .log4j .Logger ;
2533import org .libvirt .Connect ;
2634import org .libvirt .LibvirtException ;
2735import org .libvirt .NodeInfo ;
36+ import org .w3c .dom .Document ;
37+ import org .w3c .dom .Element ;
38+ import org .w3c .dom .NamedNodeMap ;
39+ import org .w3c .dom .Node ;
40+ import org .w3c .dom .NodeList ;
41+ import org .xml .sax .InputSource ;
2842
29- import java .io .FileReader ;
30- import java .io .IOException ;
31- import java .io .Reader ;
32- import java .util .ArrayList ;
33- import java .util .List ;
43+ import com .cloud .hypervisor .kvm .resource .LibvirtCapXMLParser ;
44+ import com .cloud .hypervisor .kvm .resource .LibvirtConnection ;
45+ import com .cloud .utils .script .Script ;
3446
3547public class KVMHostInfo {
3648
@@ -82,7 +94,7 @@ public List<String> getCapabilities() {
8294 return this .capabilities ;
8395 }
8496
85- protected static long getCpuSpeed (final NodeInfo nodeInfo ) {
97+ protected static long getCpuSpeed (final String cpabilities , final NodeInfo nodeInfo ) {
8698 long speed = 0L ;
8799 speed = getCpuSpeedFromCommandLscpu ();
88100 if (speed > 0L ) {
@@ -94,6 +106,11 @@ protected static long getCpuSpeed(final NodeInfo nodeInfo) {
94106 return speed ;
95107 }
96108
109+ speed = getCpuSpeedFromHostCapabilities (cpabilities );
110+ if (speed > 0L ) {
111+ return speed ;
112+ }
113+
97114 LOGGER .info (String .format ("Using the value [%s] provided by Libvirt." , nodeInfo .mhz ));
98115 speed = nodeInfo .mhz ;
99116 return speed ;
@@ -125,12 +142,41 @@ private static long getCpuSpeedFromFile() {
125142 }
126143 }
127144
145+ protected static long getCpuSpeedFromHostCapabilities (final String capabilities ) {
146+ LOGGER .info ("Fetching CPU speed from \" host capabilities\" " );
147+ long speed = 0L ;
148+ try {
149+ DocumentBuilderFactory docFactory = ParserUtils .getSaferDocumentBuilderFactory ();
150+ DocumentBuilder docBuilder = docFactory .newDocumentBuilder ();
151+ Document doc = docBuilder .parse (new InputSource (new StringReader (capabilities )));
152+ Element rootElement = doc .getDocumentElement ();
153+ NodeList nodes = rootElement .getElementsByTagName ("cpu" );
154+ Node node = nodes .item (0 );
155+ nodes = ((Element )node ).getElementsByTagName ("counter" );
156+ for (int i = 0 ; i < nodes .getLength (); i ++) {
157+ node = nodes .item (i );
158+ NamedNodeMap attributes = node .getAttributes ();
159+ Node nameNode = attributes .getNamedItem ("name" );
160+ Node freqNode = attributes .getNamedItem ("frequency" );
161+ if (nameNode != null && "tsc" .equals (nameNode .getNodeValue ()) && freqNode != null && StringUtils .isNotEmpty (freqNode .getNodeValue ())) {
162+ speed = Long .parseLong (freqNode .getNodeValue ()) / 1000000 ;
163+ LOGGER .info (String .format ("Retrieved value [%s] from \" host capabilities\" . This corresponds to a CPU speed of [%s] MHz." , freqNode .getNodeValue (), speed ));
164+ }
165+ }
166+ } catch (Exception ex ) {
167+ LOGGER .error ("Unable to fetch CPU speed from \" host capabilities\" " , ex );
168+ speed = 0L ;
169+ }
170+ return speed ;
171+ }
172+
128173 private void getHostInfoFromLibvirt () {
129174 try {
130175 final Connect conn = LibvirtConnection .getConnection ();
131176 final NodeInfo hosts = conn .nodeInfo ();
177+ final String capabilities = conn .getCapabilities ();
132178 if (this .cpuSpeed == 0 ) {
133- this .cpuSpeed = getCpuSpeed (hosts );
179+ this .cpuSpeed = getCpuSpeed (capabilities , hosts );
134180 } else {
135181 LOGGER .debug (String .format ("Using existing configured CPU frequency %s" , this .cpuSpeed ));
136182 }
@@ -146,7 +192,7 @@ private void getHostInfoFromLibvirt() {
146192 this .cpus = hosts .cpus ;
147193
148194 final LibvirtCapXMLParser parser = new LibvirtCapXMLParser ();
149- parser .parseCapabilitiesXML (conn . getCapabilities () );
195+ parser .parseCapabilitiesXML (capabilities );
150196 final ArrayList <String > oss = parser .getGuestOsType ();
151197 for (final String s : oss ) {
152198 /*
0 commit comments