Home | History | Annotate | Download | only in hardware_DiskSize
      1 # Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
      2 # Use of this source code is governed by a BSD-style license that can be
      3 # found in the LICENSE file.
      4 
      5 import logging
      6 import os
      7 
      8 from autotest_lib.client.bin import test, utils
      9 from autotest_lib.client.common_lib import error
     10 
     11 DEFAULT_MIN_GB = 16
     12 # Allowable amount of bits eMMC vendor can use in firmware to support bad block
     13 # replacement and metadata.
     14 EMMC_VENDOR_ALLOWED_GB = 0.25
     15 # Amount of data available for user data in device, the rest is left for
     16 # over provisioning.
     17 # Typically a SATA device will use 7% over provisioning [the difference
     18 # between GB and GiB], but some eMMC device can use 9%.
     19 # With Flash becoming more error prone as lithography shrinks, the trend
     20 # is to increase over provisioning.
     21 DEFAULT_USER_DENSITY = 0.9
     22 
     23 
     24 class hardware_DiskSize(test.test):
     25     """
     26     Check that disk size is around 16GB at least.
     27     """
     28 
     29     version = 1
     30 
     31     def _is_emmc(self):
     32         path = os.path.join("/sys/class/block/", self._device,
     33                             "device", "type")
     34         if not os.path.exists(path):
     35             return False
     36         return utils.read_one_line(path) == 'MMC'
     37 
     38 
     39     @classmethod
     40     def _gib_to_gb(cls, gib):
     41         return float(gib) * (1 << 30) / (10 ** 9)
     42 
     43     def _compute_min_gb(self):
     44         """Computes minimum size allowed primary storage device.
     45 
     46         TODO(tbroch): Add computation of raw bytes in eMMC using 'Chip Specific
     47         Data' (CSD & EXT_CSD) defined by JEDEC JESD84-A44.pdf if possible.
     48 
     49         CSD :: /sys/class/block/<device>/device/csd
     50         EXT_CSD :: debugfs
     51 
     52         Algorithm should look something like this:
     53         CSD[C_SIZE] = 0xfff == eMMC > 2GB
     54         EXT_CSD[SEC_COUNT] = # of 512byte sectors
     55 
     56         Now for existing eMMC I've examined I do see the C_SIZE == 0xfff.
     57         Unfortunately the SEC_COUNT appears to have excluded the sectors
     58         reserved for metadata & repair.  Perhaps thats by design in which case
     59         there is no mechanism to determine the actual raw sectors.
     60 
     61         For now I use 0.25GB as an acceptable fudge.
     62 
     63         Returns:
     64             integer, in GB of minimum storage size.
     65         """
     66 
     67         min_gb = DEFAULT_MIN_GB
     68         if self._is_emmc():
     69             min_gb -= EMMC_VENDOR_ALLOWED_GB
     70         min_gb *= DEFAULT_USER_DENSITY
     71         return self._gib_to_gb(min_gb)
     72 
     73 
     74     def run_once(self):
     75         root_dev = utils.get_root_device()
     76         self._device = os.path.basename(root_dev)
     77         disk_size = utils.get_disk_size(root_dev)
     78         if not disk_size:
     79             raise error.TestError('Unable to determine main disk size')
     80 
     81         # Capacity of a hard disk is quoted with SI prefixes, incrementing by
     82         # powers of 1000, instead of powers of 1024.
     83         gb = float(disk_size) / (10 ** 9)
     84 
     85         self.write_perf_keyval({"gb_main_disk_size": gb})
     86         min_gb = self._compute_min_gb()
     87         logging.info("DiskSize: %.3f GB MinDiskSize: %.3f GB", gb, min_gb)
     88         if (gb < min_gb):
     89             raise error.TestError("DiskSize %.3f GB below minimum (%.3f GB)" \
     90                 % (gb, min_gb))
     91 
     92