Home | History | Annotate | Download | only in platform_CrashStateful
      1 # Copyright (c) 2013 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 traceback
      7 from autotest_lib.client.common_lib import error
      8 from autotest_lib.server import test
      9 
     10 class platform_CrashStateful(test.test):
     11     """Tests the crash recovery of the stateful file system
     12 
     13     1. Create a specific file 'charlie'
     14     2. Sync
     15     3. Crash system
     16     4. Wait for reboot
     17     5. Check if 'charlie' is there and complete
     18     6. Clean up
     19 
     20     Do the samething with an ecryptfs volume.
     21     """
     22     version = 1
     23     _STATEFUL_DIR = '/usr/local/CrashDir'
     24     _ECRYPT_DIR = '/usr/local/ecryptfs_tst'
     25     _ECRYPT_MOUNT_POINT = '/usr/local/ecryptfs_mnt'
     26     _ECRYPT_TEST_DIR = '%s/CrashDir' % _ECRYPT_MOUNT_POINT
     27 
     28 
     29     def _run(self, cmd):
     30         """Run the give command and log results
     31 
     32         @param cmd: command to be run
     33         """
     34         result = self.client.run(cmd)
     35         if result.exit_status != 0:
     36             logging.error('%s: %s', cmd, result.stdout)
     37 
     38 
     39     def _ecrypt_mount(self, edir, mnt):
     40         """Mount the eCrypt File System
     41 
     42         @param ddir: directory where encrypted file system is stored
     43         @param mnt: mount point for encrypted file system
     44         """
     45         options = ('-o'
     46                    ' key=passphrase:passphrase_passwd=secret'
     47                    ',ecryptfs_cipher=aes'
     48                    ',ecryptfs_key_bytes=32'
     49                    ',no_sig_cache'
     50                    ',ecryptfs_passthrough=no'
     51                    ',ecryptfs_enable_filename_crypto=no')
     52         self._run('mkdir -p %s %s' % (edir, mnt))
     53         self._run('mount -t ecryptfs %s %s %s' %
     54                            (options, edir, mnt))
     55 
     56 
     57     def _ecrypt_unmount(self, edir, mnt):
     58         """Unmount the eCrypt File System and remove it and its mount point
     59 
     60         @param dir: directory where encrypted file system is stored
     61         @param mnt: mount point for encrypted file system
     62         """
     63         self._run('umount %s' % mnt)
     64         self._run('rm -R %s' % edir)
     65         self._run('rm -R %s' % mnt)
     66 
     67 
     68     def _crash(self):
     69         """crash the client without giving anything a chance to clean up
     70 
     71         We use the kernel crash testing interface to immediately reboot the
     72         system. No chance for any flushing of I/O or cleaning up.
     73         """
     74         logging.info('CrashStateful: force panic %s', self.client.hostname)
     75         interface = "/sys/kernel/debug/provoke-crash/DIRECT"
     76         cmd = 'echo PANIC > %s' % interface
     77         if not self.client.run('ls %s' % interface,
     78                                ignore_status=True).exit_status == 0:
     79             interface = "/proc/breakme"
     80             cmd = 'echo panic > %s' % interface
     81         try:
     82             """The following is necessary to avoid command execution errors
     83             1) If ssh on the DUT doesn't terminate cleanly, it will exit with
     84                status 255 causing an exception
     85             2) ssh won't terminate if a background process holds open stdin,
     86                stdout, or stderr
     87             3) without a sleep delay, the reboot may close the connection with
     88                an error
     89             """
     90             wrapped_cmd = 'sleep 1; %s'
     91             self.client.reboot(reboot_cmd=wrapped_cmd % cmd)
     92         except error.AutoservRebootError as e:
     93             raise error.TestFail('%s.\nTest failed with error %s' % (
     94                     traceback.format_exc(), str(e)))
     95 
     96 
     97     def _create_file_and_crash(self, dir):
     98         """Sets up first part of test, then crash
     99 
    100         @param dir - directory where test files are created
    101         """
    102         self._run('mkdir -p %s' % dir)
    103         self._run('echo charlie smith >%s/charlie' % dir)
    104         self._run('sync')
    105         self._crash()
    106 
    107 
    108     def _verify_and_cleanup(self, dir):
    109         """Verify results and clean up
    110 
    111         @param dir - directory where test files were created
    112         """
    113         result = self.client.run('cat %s/charlie' % dir)
    114         hi = result.stdout.strip()
    115         if hi != 'charlie smith':
    116             raise error.TestFail('Test failed, Sync mechanism failed')
    117         self._run('rm -fr %s' % dir)
    118 
    119 
    120     def _crash_stateful(self, dir):
    121         """Crash the stateful file system while changing it
    122 
    123         @param dir - directory where test files are created
    124         """
    125         self._create_file_and_crash(dir)
    126         self._verify_and_cleanup(dir)
    127 
    128 
    129     def _crash_ecrptfs(self, edir, mnt, dir):
    130         """Crash the stateful file system while changing it
    131 
    132         @param edir - directory used for the encrypted file system
    133         @param mnt - mount point for the encrypted file system
    134         @param dir - directory where test files are created
    135         """
    136         self._ecrypt_mount(edir, mnt)
    137         self._create_file_and_crash(dir)
    138         self._ecrypt_mount(edir, mnt)
    139         self._verify_and_cleanup(dir)
    140         self._ecrypt_unmount(edir, mnt)
    141 
    142 
    143     def run_once(self, host=None):
    144         """run_once runs the test.
    145 
    146         1. Runs a crash test on stateful partition
    147         2. Create an ecryptfs volume and run the same
    148            crash test
    149 
    150         @param host - the host machine running the test
    151         """
    152         self.client = host
    153 
    154         self._crash_stateful(self._STATEFUL_DIR)
    155 
    156         self._crash_ecrptfs(self._ECRYPT_DIR, self._ECRYPT_MOUNT_POINT,
    157             self._ECRYPT_TEST_DIR)
    158