aboutsummaryrefslogtreecommitdiff
path: root/crosperf/machine_manager.py
diff options
context:
space:
mode:
Diffstat (limited to 'crosperf/machine_manager.py')
-rw-r--r--crosperf/machine_manager.py121
1 files changed, 114 insertions, 7 deletions
diff --git a/crosperf/machine_manager.py b/crosperf/machine_manager.py
index eb0b7539..8562e929 100644
--- a/crosperf/machine_manager.py
+++ b/crosperf/machine_manager.py
@@ -1,9 +1,12 @@
+import hashlib
+import image_chromeos
+import lock_machine
+import math
+import os.path
import sys
import threading
import time
from image_checksummer import ImageChecksummer
-import image_chromeos
-import lock_machine
from utils import command_executer
from utils import logger
from utils.file_utils import FileUtils
@@ -12,13 +15,90 @@ CHECKSUM_FILE = "/usr/local/osimage_checksum_file"
class CrosMachine(object):
- def __init__(self, name):
+ def __init__(self, name, chromeos_root):
self.name = name
self.image = None
self.checksum = None
self.locked = False
self.released_time = time.time()
self.autotest_run = None
+ self.chromeos_root = chromeos_root
+ self._GetMemoryInfo()
+ self._GetCPUInfo()
+ self._ComputeMachineChecksumString()
+ self._ComputeMachineChecksum()
+
+ def _ParseMemoryInfo(self):
+ line = self.meminfo.splitlines()[0]
+ usable_kbytes = int(line.split()[1])
+ # This code is from src/third_party/autotest/files/client/bin/base_utils.py
+ # usable_kbytes is system's usable DRAM in kbytes,
+ # as reported by memtotal() from device /proc/meminfo memtotal
+ # after Linux deducts 1.5% to 9.5% for system table overhead
+ # Undo the unknown actual deduction by rounding up
+ # to next small multiple of a big power-of-two
+ # eg 12GB - 5.1% gets rounded back up to 12GB
+ mindeduct = 0.005 # 0.5 percent
+ maxdeduct = 0.095 # 9.5 percent
+ # deduction range 1.5% .. 9.5% supports physical mem sizes
+ # 6GB .. 12GB in steps of .5GB
+ # 12GB .. 24GB in steps of 1 GB
+ # 24GB .. 48GB in steps of 2 GB ...
+ # Finer granularity in physical mem sizes would require
+ # tighter spread between min and max possible deductions
+
+ # increase mem size by at least min deduction, without rounding
+ min_kbytes = int(usable_kbytes / (1.0 - mindeduct))
+ # increase mem size further by 2**n rounding, by 0..roundKb or more
+ round_kbytes = int(usable_kbytes / (1.0 - maxdeduct)) - min_kbytes
+ # find least binary roundup 2**n that covers worst-cast roundKb
+ mod2n = 1 << int(math.ceil(math.log(round_kbytes, 2)))
+ # have round_kbytes <= mod2n < round_kbytes*2
+ # round min_kbytes up to next multiple of mod2n
+ phys_kbytes = min_kbytes + mod2n - 1
+ phys_kbytes -= phys_kbytes % mod2n # clear low bits
+ self.phys_kbytes = phys_kbytes
+
+ def _GetMemoryInfo(self):
+ #TODO yunlian: when the machine in rebooting, it will not return
+ #meminfo, the assert does not catch it either
+ ce = command_executer.GetCommandExecuter()
+ command = "cat /proc/meminfo"
+ ret, self.meminfo, _ = ce.CrosRunCommand(
+ command, return_output=True,
+ machine=self.name, username="root", chromeos_root=self.chromeos_root)
+ assert ret == 0, "Could not get meminfo from machine: %s" % self.name
+ if ret == 0:
+ self._ParseMemoryInfo()
+
+ #cpuinfo format is different across architecture
+ #need to find a better way to parse it.
+ def _ParseCPUInfo(self,cpuinfo):
+ return 0
+
+ def _GetCPUInfo(self):
+ ce = command_executer.GetCommandExecuter()
+ command = "cat /proc/cpuinfo"
+ ret, self.cpuinfo, _ = ce.CrosRunCommand(
+ command, return_output=True,
+ machine=self.name, username="root", chromeos_root=self.chromeos_root)
+ assert ret == 0, "Could not get cpuinfo from machine: %s" % self.name
+ if ret == 0:
+ self._ParseCPUInfo(self.cpuinfo)
+
+ def _ComputeMachineChecksumString(self):
+ self.checksum_string = ""
+ exclude_lines_list = ["MHz", "BogoMIPS", "bogomips"]
+ for line in self.cpuinfo.splitlines():
+ if not any([e in line for e in exclude_lines_list]):
+ self.checksum_string += line
+ self.checksum_string += " " + str(self.phys_kbytes)
+
+ def _ComputeMachineChecksum(self):
+ if self.checksum_string:
+ self.machine_checksum = hashlib.md5(self.checksum_string).hexdigest()
+ else:
+ self.machine_checksum = ""
def __str__(self):
l = []
@@ -38,7 +118,10 @@ class MachineManager(object):
self.image_lock = threading.Lock()
self.num_reimages = 0
self.chromeos_root = None
- self.no_lock = False
+ if os.path.isdir(lock_machine.FileLock.LOCKS_DIR):
+ self.no_lock = False
+ else:
+ self.no_lock = True
self.initialized = False
self.chromeos_root = chromeos_root
@@ -69,6 +152,20 @@ class MachineManager(object):
return retval
+ def ComputeCommonCheckSum(self):
+ self.machine_checksum = ""
+ for machine in self.GetMachines():
+ if machine.machine_checksum:
+ self.machine_checksum = machine.machine_checksum
+ break
+
+ def ComputeCommonCheckSumString(self):
+ self.machine_checksum_string = ""
+ for machine in self.GetMachines():
+ if machine.checksum_string:
+ self.machine_checksum_string = machine.checksum_string
+ break
+
def _TryToLockMachine(self, cros_machine):
with self._lock:
assert cros_machine, "Machine can't be None"
@@ -96,7 +193,14 @@ class MachineManager(object):
with self._lock:
for m in self._all_machines:
assert m.name != machine_name, "Tried to double-add %s" % machine_name
- self._all_machines.append(CrosMachine(machine_name))
+ cm = CrosMachine(machine_name, self.chromeos_root)
+ assert cm.machine_checksum, ("Could not find checksum for machine %s" %
+ machine_name)
+ self._all_machines.append(cm)
+
+ def AreAllMachineSame(self):
+ checksums = [m.machine_checksum for m in self.GetMachines()]
+ return len(set(checksums)) == 1
def AcquireMachine(self, chromeos_image):
image_checksum = ImageChecksummer().Checksum(chromeos_image)
@@ -109,12 +213,15 @@ class MachineManager(object):
for m in self._all_machines:
m.released_time = time.time()
+ if not self.AreAllMachineSame():
+ logger.GetLogger().LogFatal("-- not all the machine are identical")
if not self._machines:
machine_names = []
for machine in self._all_machines:
machine_names.append(machine.name)
- raise Exception("Could not acquire any of the following machines: '%s'"
- % ", ".join(machine_names))
+ logger.GetLogger().LogFatal("Could not acquire any of the"
+ "following machines: '%s'"
+ % ", ".join(machine_names))
### for m in self._machines:
### if (m.locked and time.time() - m.released_time < 10 and