Repository: cloudstack
Updated Branches:
  refs/heads/master 0c6758f91 -> c37060a1f


CLOUDSTACK-8338: Fix hypervisor stats reporting for KVM on EL7

EL7 has a different output to 'free', use /proc/meminfo instead of a tool to be
more consistent across distros

(cherry picked from commit 212a05a345aa19cd2597b7ff5d6a1da7b35b9fc1)
Signed-off-by: Rohit Yadav <[email protected]>

Conflicts:
        
plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/c37060a1
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/c37060a1
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/c37060a1

Branch: refs/heads/master
Commit: c37060a1ffc1e63ea2f7ec01887b4c9ff5fcbb48
Parents: 0c6758f
Author: Rohit Yadav <[email protected]>
Authored: Fri May 22 09:25:03 2015 +0100
Committer: Rohit Yadav <[email protected]>
Committed: Fri May 22 12:10:54 2015 +0100

----------------------------------------------------------------------
 .../LibvirtGetHostStatsCommandWrapper.java      | 27 ++------
 .../apache/cloudstack/utils/linux/MemStat.java  | 71 ++++++++++++++++++++
 .../cloudstack/utils/linux/MemStatTest.java     | 54 +++++++++++++++
 3 files changed, 130 insertions(+), 22 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c37060a1/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetHostStatsCommandWrapper.java
----------------------------------------------------------------------
diff --git 
a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetHostStatsCommandWrapper.java
 
b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetHostStatsCommandWrapper.java
index 32bec35..198eb3b 100644
--- 
a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetHostStatsCommandWrapper.java
+++ 
b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetHostStatsCommandWrapper.java
@@ -19,6 +19,7 @@
 
 package com.cloud.hypervisor.kvm.resource.wrapper;
 
+import org.apache.cloudstack.utils.linux.MemStat;
 import org.apache.log4j.Logger;
 
 import com.cloud.agent.api.Answer;
@@ -55,28 +56,10 @@ public final class LibvirtGetHostStatsCommandWrapper 
extends CommandWrapper<GetH
         }
         final double cpuUtil = 100.0D - Double.parseDouble(parser.getLine());
 
-        long freeMem = 0;
-        final Script memScript = new Script(bashScriptPath, s_logger);
-        memScript.add("-c");
-        memScript.add("freeMem=$(free|grep cache:|awk '{print $4}');echo 
$freeMem");
-        final OutputInterpreter.OneLineParser Memparser = new 
OutputInterpreter.OneLineParser();
-        result = memScript.execute(Memparser);
-        if (result != null) {
-            s_logger.debug("Unable to get the host Mem state: " + result);
-            return new Answer(command, false, result);
-        }
-        freeMem = Long.parseLong(Memparser.getLine());
-
-        final Script totalMem = new Script(bashScriptPath, s_logger);
-        totalMem.add("-c");
-        totalMem.add("free|grep Mem:|awk '{print $2}'");
-        final OutputInterpreter.OneLineParser totMemparser = new 
OutputInterpreter.OneLineParser();
-        result = totalMem.execute(totMemparser);
-        if (result != null) {
-            s_logger.debug("Unable to get the host Mem state: " + result);
-            return new Answer(command, false, result);
-        }
-        final long totMem = Long.parseLong(totMemparser.getLine());
+        MemStat memStat = new MemStat();
+        memStat.refresh();
+        double totMem = memStat.getTotal();
+        double freeMem = memStat.getAvailable();
 
         final Pair<Double, Double> nicStats = 
libvirtComputingResource.getNicStats(libvirtComputingResource.getPublicBridgeName());
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c37060a1/plugins/hypervisors/kvm/src/org/apache/cloudstack/utils/linux/MemStat.java
----------------------------------------------------------------------
diff --git 
a/plugins/hypervisors/kvm/src/org/apache/cloudstack/utils/linux/MemStat.java 
b/plugins/hypervisors/kvm/src/org/apache/cloudstack/utils/linux/MemStat.java
new file mode 100644
index 0000000..1e3c872
--- /dev/null
+++ b/plugins/hypervisors/kvm/src/org/apache/cloudstack/utils/linux/MemStat.java
@@ -0,0 +1,71 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// the License.  You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.utils.linux;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.util.Scanner;
+
+public class MemStat {
+    protected final static String MEMINFO_FILE = "/proc/meminfo";
+    protected final static String FREE_KEY = "MemFree";
+    protected final static String CACHE_KEY = "Cached";
+    protected final static String TOTAL_KEY = "MemTotal";
+
+    private Map<String, Double> _memStats = new HashMap<String, Double>();
+
+    public MemStat() {
+    }
+
+    public Double getTotal() {
+        return _memStats.get(TOTAL_KEY);
+    }
+
+    public Double getAvailable() {
+        return getFree() + getCache();
+    }
+
+    public Double getFree() {
+        return _memStats.get(FREE_KEY);
+    }
+
+    public Double getCache() {
+        return _memStats.get(CACHE_KEY);
+    }
+
+    public void refresh() {
+        try {
+            Scanner fileScanner = new Scanner(new File(MEMINFO_FILE));
+            parseFromScanner(fileScanner);
+        } catch (FileNotFoundException ex) {
+            throw new RuntimeException("File " + MEMINFO_FILE + " not found:" 
+ ex.toString());
+        }
+    }
+
+    protected void parseFromScanner(Scanner scanner) {
+        scanner.useDelimiter("\\n");
+        while(scanner.hasNext()) {
+            String[] stats = scanner.next().split("\\:\\s+");
+            if (stats.length == 2) {
+                _memStats.put(stats[0], 
Double.valueOf(stats[1].replaceAll("\\s+\\w+","")));
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c37060a1/plugins/hypervisors/kvm/test/org/apache/cloudstack/utils/linux/MemStatTest.java
----------------------------------------------------------------------
diff --git 
a/plugins/hypervisors/kvm/test/org/apache/cloudstack/utils/linux/MemStatTest.java
 
b/plugins/hypervisors/kvm/test/org/apache/cloudstack/utils/linux/MemStatTest.java
new file mode 100644
index 0000000..5e77606
--- /dev/null
+++ 
b/plugins/hypervisors/kvm/test/org/apache/cloudstack/utils/linux/MemStatTest.java
@@ -0,0 +1,54 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// the License.  You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.utils.linux;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.util.Scanner;
+
+public class MemStatTest {
+    @Test
+    public void getMemInfoParseTest() {
+        String memInfo = "MemTotal:        5830236 kB\n" +
+                         "MemFree:          156752 kB\n" +
+                         "Buffers:          326836 kB\n" +
+                         "Cached:          2606764 kB\n" +
+                         "SwapCached:            0 kB\n" +
+                         "Active:          4260808 kB\n" +
+                         "Inactive:         949392 kB\n";
+
+        MemStat memStat = null;
+        try {
+            memStat = new MemStat();
+        } catch (RuntimeException ex) {
+            // If test isn't run on linux we'll fail creation of 
linux-specific MemStat class due
+            // to dependency on /proc/meminfo if we don't catch here.
+            // We are really only interested in testing the parsing algorithm 
and getters.
+            if (memStat == null) {
+                throw ex;
+            }
+        }
+        Scanner scanner = new Scanner(memInfo);
+        memStat.parseFromScanner(scanner);
+
+        Assert.assertEquals(memStat.getTotal(), Double.valueOf(5830236));
+        Assert.assertEquals(memStat.getAvailable(), Double.valueOf(2763516));
+        Assert.assertEquals(memStat.getFree(), Double.valueOf(156752));
+        Assert.assertEquals(memStat.getCache(), Double.valueOf(2606764));
+    }
+}

Reply via email to