blob: 1c4f2c243f8adc06042096a6744b10b1fe7ed7ef [file] [log] [blame]
# Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import logging
import traceback
from autotest_lib.client.common_lib import error
from autotest_lib.server import test
class platform_SyncCrash(test.test):
"""Tests syncing to the file system before a crash.
This test works in conjunction with testsync (found in
punybench) to test various forms of sync. Testsync runs
on the client to create a file, fill it with data, sync
that data and crash the system. The server side (this
code), waits for the client to restart and then invokes
testsync to verify the data did sync.
Testsync has different phases for testing sync
writer - syncs a file using fsync
mapper - syncs a memory mapped file using msync
verifier - verifies that content of the file
The tests are run on both the stateful partition
and ecryptfs mounted on a directory in the stateful
partition.
"""
version = 1
_STATEFUL_DIR = '/usr/local/CrashDir/'
_ECRYPT_DIR = '/usr/local/ecryptfs_tst/'
_ECRYPT_MOUNT_POINT = '/usr/local/ecryptfs_mnt/'
_ECRYPT_TEST_DIR = '%s/CrashDir/' % _ECRYPT_MOUNT_POINT
_FILE = 'xyzzy'
_Testsync = '/usr/local/opt/punybench/bin/testsync'
def _run(self, cmd):
"""Run the given command and log results
@param cmd: command to be run
"""
result = self.client.run(cmd)
if result.exit_status != 0:
logging.error('%s: %s', cmd, result.stdout)
else:
logging.info('%s', cmd)
def _testsync_crash(self, args):
"""Run testsync on the client
Since testsync forces a crash of the system, the code
waits for the reboot.
@param args: arguments to pass testsync
"""
logging.info('Crash: %s', self.client.hostname)
try:
cmd = '%s %s' % (self._Testsync, args)
logging.info('Crash: %s', cmd)
self.client.reboot(reboot_cmd=cmd)
except error.AutoservRebootError as e:
raise error.TestFail('%s.\nTest failed with error %s' % (
traceback.format_exc(), str(e)))
def _testsync_verify(self, args):
"""Verify the results from previous testsync
@param args: arguments to pass to testsync
"""
cmd = '%s %s -p verifier' % (self._Testsync, args)
result = self.client.run(cmd)
if result.exit_status != 0:
logging.error('%s: %s', cmd, result.stdout)
def _ecrypt_setup(self):
"""Setup an eCrypt File System and mount it
"""
edir = self._ECRYPT_DIR
mnt = self._ECRYPT_MOUNT_POINT
options = ('-o'
' key=passphrase:passphrase_passwd=secret'
',ecryptfs_cipher=aes'
',ecryptfs_key_bytes=32'
',no_sig_cache'
',ecryptfs_passthrough=no'
',ecryptfs_enable_filename_crypto=no')
self._run('mkdir -p %s %s' % (edir, mnt))
self._run('mount -t ecryptfs %s %s %s' %
(options, edir, mnt))
def _ecrypt_teardown(self):
"""Teardown the eCrypt File System
"""
edir = self._ECRYPT_DIR
mnt = self._ECRYPT_MOUNT_POINT
self._run('umount %s' % mnt)
self._run('rm -R %s %s' % (edir, mnt))
def _sync_stateful(self, dir, phase):
"""Crash the stateful file system while changing it
@param dir - directory where test files are created
@param phase - which phase of testsync to invoke
"""
size = 0x1000
file = dir + self._FILE
self._run('mkdir -p %s' % dir)
self._testsync_crash('-f %s -z %s -p %s' % (file, size, phase))
self._testsync_verify('-f %s -z %s' % (file, size))
self._run('rm -r %s' % dir)
def _sync_ecryptfs(self, dir, phase):
"""Crash an ecryptfs file system right after a sync
@param edir - directory used for the encrypted file system
@param mnt - mount point for the encrypted file system
@param dir - directory where test files are created
@param phase - which phase of testsync to invoke
"""
size = 0x1000
file = dir + self._FILE
self._ecrypt_setup()
self._run('mkdir -p %s' % dir)
self._testsync_crash('-f %s -z %s -p %s' % (file, size, phase))
self._ecrypt_setup()
self._testsync_verify('-f %s -z %s' % (file, size))
self._run('rm -r %s' % dir)
self._ecrypt_teardown()
def run_once(self, host=None):
"""run_once runs the test.
1. Runs a crash test on stateful partition
2. Create an ecryptfs volume and run the same
crash test
@param host - the host machine running the test
"""
self.client = host
self._sync_stateful(self._STATEFUL_DIR, 'writer')
self._sync_stateful(self._STATEFUL_DIR, 'mapper')
self._sync_ecryptfs(self._ECRYPT_TEST_DIR, 'writer')
self._sync_ecryptfs(self._ECRYPT_TEST_DIR, 'mapper')