mirror of
https://github.com/apache/cloudstack.git
synced 2025-11-04 20:29:27 +01:00
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 Signed-off-by: Rohit Yadav <rohit.yadav@shapeblue.com>
This commit is contained in:
parent
1d8382ab49
commit
212a05a345
@ -61,6 +61,7 @@ import java.util.regex.Pattern;
|
||||
import javax.ejb.Local;
|
||||
import javax.naming.ConfigurationException;
|
||||
|
||||
import org.apache.cloudstack.utils.linux.MemStat;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.log4j.Logger;
|
||||
@ -463,6 +464,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
|
||||
protected int _timeout;
|
||||
protected int _cmdsTimeout;
|
||||
protected int _stopTimeout;
|
||||
private MemStat _memStat = new MemStat();
|
||||
|
||||
protected static final HashMap<DomainState, PowerState> s_powerStatesTable;
|
||||
static {
|
||||
@ -3276,28 +3278,9 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
|
||||
}
|
||||
double cpuUtil = (100.0D - Double.parseDouble(parser.getLine()));
|
||||
|
||||
long freeMem = 0;
|
||||
final Script memScript = new Script("/bin/bash", 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(cmd, false, result);
|
||||
}
|
||||
freeMem = Long.parseLong(Memparser.getLine());
|
||||
|
||||
Script totalMem = new Script("/bin/bash", 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(cmd, false, result);
|
||||
}
|
||||
long totMem = Long.parseLong(totMemparser.getLine());
|
||||
_memStat.refresh();
|
||||
double totMem = _memStat.getTotal();
|
||||
double freeMem = _memStat.getAvailable();
|
||||
|
||||
Pair<Double, Double> nicStats = getNicStats(_publicBridgeName);
|
||||
|
||||
|
||||
@ -0,0 +1,72 @@
|
||||
// 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() {
|
||||
refresh();
|
||||
}
|
||||
|
||||
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+","")));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,55 @@
|
||||
// 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));
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user