Fix kernel testing and make it target specific.

Note that this change is in R11, as it should be enabled asap.

This CL fixes kernel messages autotest by introducing
platform specific lists of the kernel warning and error
messages expected on startup.

Some of these messages are harmless, and some require
investigation/fixing. This CL just cleans up the lists of
accepted error/warning messages and provides for platform
specific extensions.

The recently introduced crossystem utility is the way to
deteremine system specific parameters in a platform
independent way. This CL introduces a class to represent
the crossystem reported information in a programmatic way.

The crossystem output of form 'name = value' is parsed and
placed in a dictionary.  The __getatttr__() method override
allows to use object_instance.name() to access the value of
the parameter 'name'.

Instead of using exact warning/error messages' list the
regexes of messages are allowed, which is handy in
situations when messages are run time specific (use hash
values or addresses, etc.)

Change-Id: Ia4af19e231c9bc2665f7f6094e7c4f541f69148b

BUG=chromium-os:13937
TEST=manual, see below

./run_remote_tests.sh --board x86-alex --remote  172.22.75.120 kernel_BootMessagesServer
...
INFO    : Test results:
---------------------------------------------------------
kernel_BootMessagesServer                           PASS
kernel_BootMessagesServer/kernel_BootMessagesServer PASS
  coldboot_active_mb                                59
  coldboot_anonpages_mb                             37
  coldboot_buffers_mb                               3
  coldboot_cached_mb                                177
  coldboot_inactive_mb                              159
  coldboot_memfree_mb                               1637
---------------------------------------------------------
Total PASS: 2/2 (100%)

===========================================================
./run_remote_tests.sh --board x86-mario --remote  172.22.75.17 kernel_BootMessagesServer
...
INFO    : Test results:
---------------------------------------------------------
kernel_BootMessagesServer                           PASS
kernel_BootMessagesServer/kernel_BootMessagesServer PASS
  coldboot_active_mb                                48
  coldboot_anonpages_mb                             35
  coldboot_buffers_mb                               3
  coldboot_cached_mb                                155
  coldboot_inactive_mb                              145
  coldboot_memfree_mb                               1662
---------------------------------------------------------
Total PASS: 2/2 (100%)

Review URL: http://codereview.chromium.org/6810022
diff --git a/client/bin/site_utils.py b/client/bin/site_utils.py
index b6cc26f..61a9e14 100644
--- a/client/bin/site_utils.py
+++ b/client/bin/site_utils.py
@@ -2,14 +2,47 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-import logging, os, platform, time
+import logging, os, platform, re, tempfile, time
 from autotest_lib.client.common_lib import error
+from autotest_lib.client.common_lib import utils
 
 
 class TimeoutError(error.TestError):
     """Error raised when we time out when waiting on a condition."""
 
 
+class Crossystem(object):
+    """A wrapper for the crossystem utility."""
+
+    def __init__(self, client):
+        self.cros_system_data = {}
+        self._client = client
+
+    def init(self):
+        self.cros_system_data = {}
+        (_, fname) = tempfile.mkstemp()
+        f = open(fname, 'w')
+        self._client.run('crossystem', stdout_tee=f)
+        f.close()
+        text = utils.read_file(fname)
+        for line in text.splitlines():
+            assignment_string = line.split('#')[0]
+            if not assignment_string.count('='):
+                continue
+            (name, value) = assignment_string.split('=', 1)
+            self.cros_system_data[name.strip()] = value.strip()
+        os.remove(fname)
+
+    def __getattr__(self, name):
+        """
+        Retrieve a crosssystem attribute.
+
+        The call crossystemobject.name() will return the crossystem reported
+        string.
+        """
+        return lambda : self.cros_system_data[name]
+
+
 def poll_for_condition(
     condition, exception=None, timeout=10, sleep_interval=0.1, desc=None):
     """Poll until a condition becomes true.
@@ -77,12 +110,12 @@
     Returns:
       List of unexpected warnings
     """
-
+    whitelist_re = re.compile(r'(%s)' % '|'.join(whitelist))
     unexpected = []
     for line in dmesg.splitlines():
         if int(line[1]) <= message_level:
-            if not 'used greatest stack depth' in line:
-                stripped_line = line.split('] ', 1)[1]
-                if not stripped_line in whitelist:
-                    unexpected.append(stripped_line)
+            stripped_line = line.split('] ', 1)[1]
+            if whitelist_re.search(stripped_line):
+                continue
+            unexpected.append(stripped_line)
     return unexpected
diff --git a/server/site_tests/kernel_BootMessagesServer/kernel_BootMessagesServer.py b/server/site_tests/kernel_BootMessagesServer/kernel_BootMessagesServer.py
index 3e0dfea..d5804d1 100644
--- a/server/site_tests/kernel_BootMessagesServer/kernel_BootMessagesServer.py
+++ b/server/site_tests/kernel_BootMessagesServer/kernel_BootMessagesServer.py
@@ -10,29 +10,46 @@
 
 _KERN_WARNING = 4
 
-_WHITELIST = [
+_WHITELIST_COMMON = [
+    r"used greatest stack depth: \d+ bytes left",
     "Kernel-defined memdesc doesn't match the one from EFI!",
-    "Warning only 1919MB will be used.",
     "Use a HIGHMEM enabled kernel.",
-    "pnp 00:01: io resource (0x164e-0x164f) overlaps 0000:00:1c.0 "
-    "BAR 7 (0x1000-0x1fff), disabling",
-    "i915 0000:00:02.0: Invalid ROM contents",
-    "[drm:intel_init_bios] *ERROR* VBT signature missing",
-    "usb 1-2: config 1 has an invalid interface number: 1 but max is 0",
-    "usb 1-2: config 1 has no interface number 0",
-    "device-mapper: verity: Failed to acquire device 'ROOT_DEV': -1",
-    "device-mapper: table: 254:0: verity: Device lookup failed",
-    "dm: starting dm-0 (vroot) failed",
-    "EXT3-fs warning: maximal mount count reached, running e2fsck is "
-    "recommended",
+   "GPT: Use GNU Parted to correct GPT errors.",
+    r"GPT:\d+ != \d+",
+    "GPT:Alternate GPT header not at the end of the disk.",
+    "GPT:Primary header thinks Alt. header is not at the end of the disk.",
+    r"GPT:partition_entry_array_crc32 values don't match: 0x[\da-f]+ !="
+    " 0x[\da-f]+",
+    r"Warning only \d+MB will be used.",
+    "\[drm:intel_init_bios\] \*ERROR\* VBT signature missing",
     "i2c i2c-2: The new_device interface is still experimental and may change "
     "in a near future",
-    "industrialio: module is from the staging directory, "
-    "the quality is unknown, you have been warned.",
-    "tsl2563: module is from the staging directory, the quality is unknown, "
-    "you have been warned.",
+    "i915 0000:00:02.0: Invalid ROM contents",
+    "industrialio: module is from the staging directory, the quality is "
+    "unknown, you have been warned.",
+    "pnp 00:01: io resource \(0x164e-0x164f\) overlaps 0000:00:1c.0 "
+    "BAR 7 \(0x1000-0x1fff\), disabling",
+    r"sd \d:\d:\d:\d: \[sd[a-z]\] Assuming drive cache: write through",
+    "tsl[\da-z]+: module is from the staging directory, the quality is "
+    "unknown, you have been warned.",
 ]
 
+_WHITELIST_TARGETS = {
+    'Alex' : [
+        r"CE: hpet increasing min_delta_ns to \d+ nsec",
+        r"Measured \d+ cycles TSC warp between CPUs, turning off TSC clock.",
+        "pci 0000:01:00.0: BAR 6: no parent found for of device "
+        "\[0xffff0000-0xffffffff]",
+        "tsl258x 2-0029: taos_get_lux data not valid",
+        "usb 1-2: config 1 has an invalid interface number: 1 but max is 0",
+        "usb 1-2: config 1 has no interface number 0",
+        ],
+    'Mario' : [
+        "chromeos_acpi: failed to retrieve MLST \(5\)",
+        r"btusb_[a-z]{4}_complete: hci\d urb [\da-f]+ failed to resubmit \(1\)",
+        ]
+}
+
 """ Interesting fields from meminfo that we want to log
     If you add fields here, you must add them to the constraints
     in the control file
@@ -106,6 +123,12 @@
         assert host is not None, "The host must be specified."
 
         self._client = host
+
+        # get the firmware identifier from Crossystem
+        cs = utils.Crossystem(self._client)
+        cs.init()
+        fwid = cs.fwid().split('.')[0]
+
         dmesg_filename = os.path.join(self.resultsdir, 'dmesg')
         meminfo_filename = os.path.join(self.resultsdir, 'meminfo')
         perf_vals = {}
@@ -114,7 +137,8 @@
         meminfo = self._read_meminfo(meminfo_filename)
         self._parse_meminfo(meminfo, perf_vals)
         dmesg = self._read_dmesg(dmesg_filename)
-        unexpected = utils.check_raw_dmesg(dmesg, _KERN_WARNING, _WHITELIST)
+        unexpected = utils.check_raw_dmesg(
+            dmesg, _KERN_WARNING, _WHITELIST_COMMON + _WHITELIST_TARGETS[fwid])
 
         if unexpected:
             f = open(os.path.join(self.resultsdir, 'dmesg.err'), 'w')