[sheepdog] [PATCH v3] tests: add a DynamoRIO client for testing the jounaling mechanism

MORITA Kazutaka morita.kazutaka at gmail.com
Wed Jul 3 02:36:33 CEST 2013


At Mon,  1 Jul 2013 18:23:01 +0900,
Hitoshi Mitake wrote:
> 
> This patch adds a DynamoRIO (often called DR) client for testing the
> jounaling mechanism. Because of its nature, the recoverying path is
> the most important and hard to test part of the journaling
> mechanism. They need to be tested well.
> 
> But testing targetted recovery paths with traditional tests/ stuff is
> hard because:
> 1. killing sheeps with kill commands doesn't take into account the
>    internal state
> 2. inserting exit()s into sheep manually is a painful work
> 
> So this patch implements a fault injection mechanism with DR. DR
> provides rich functionalities of transparent dynamic
> instrumentation. One of the functionalities makes inserting function
> calls before and after system calls possible. With this mechanism, the
> fault injection mechanism lets sheep exit at suitable timings for
> testing recovery paths of the journaling.
> 
> How to use:
> 0. preparation
>    $ cd
>    $ svn checkout http://dynamorio.googlecode.com/svn/trunk/ dynamorio
>    $ cd dynamorio
>    $ mkdir build
>    $ cd build
>    $ cmake ..
>    $ make
> 
> (This patch assumes the source code of DR is store in $HOME/dynamorio,
> and the build is done in $HOME/dynamorio/build)
> 
> 1. build the DR client
>    $ cd tests/dynamorio/journaling/
>    $ cmake .
>    $ make
> 
> 2. run tests with preset scenarios
>    $ ./01.sh 	  # for testing recovery of object store
>      		  # after this, actual completion of recovery can be
> 		    checked via sheep.log
> 
> The fault injection implemented with this patch is so slack and not
> capable for exhaustive testing. This is only a supoprted care. But I
> believe it is useful.
> 
> With this patch, I tested the recovery path for object store and
> checked it work well.
> 
> Signed-off-by: Hitoshi Mitake <mitake.hitoshi at lab.ntt.co.jp>
> ---
> v2: DR now supports signalfd(), so we can use the DR client with
>     shepherd (timerfd() is not supported yet, but its only user is the
>     local cluster driver).

What happens if we use the local driver and call timerfd?

> 
> v3: rename fi/ -> dynamorio/
> 
>  tests/dynamorio/.gitignore                |    6 +
>  tests/dynamorio/journaling/01.sh          |   21 ++
>  tests/dynamorio/journaling/CMakeLists.txt |   10 +
>  tests/dynamorio/journaling/journaling.c   |  358 +++++++++++++++++++++++++++++
>  4 files changed, 395 insertions(+)
>  create mode 100644 tests/dynamorio/.gitignore
>  create mode 100755 tests/dynamorio/journaling/01.sh
>  create mode 100644 tests/dynamorio/journaling/CMakeLists.txt
>  create mode 100644 tests/dynamorio/journaling/journaling.c
> 
> diff --git a/tests/dynamorio/.gitignore b/tests/dynamorio/.gitignore
> new file mode 100644
> index 0000000..09c1215
> --- /dev/null
> +++ b/tests/dynamorio/.gitignore
> @@ -0,0 +1,6 @@
> +*/CMakeCache.txt
> +*/CMakeFiles
> +*/Makefile
> +*/cmake_install.cmake
> +*/ldscript
> +*/*.so
> diff --git a/tests/dynamorio/journaling/01.sh b/tests/dynamorio/journaling/01.sh
> new file mode 100755
> index 0000000..dd2fb45
> --- /dev/null
> +++ b/tests/dynamorio/journaling/01.sh
> @@ -0,0 +1,21 @@
> +#! /bin/bash
> +
> +# fault injection for testing journaling with object store
> +
> +sudo killall -KILL sheep
> +sudo killall -KILL shepherd
> +
> +sudo rm -rf /tmp/sheepdog*
> +sudo mkdir -p /tmp/sheepdog/0
> +
> +sudo shepherd
> +
> +sudo ~/dynamorio/build/bin64/drrun -c libjournaling.so 1 --\
> + sheep -d -c shepherd:127.0.0.1 -p 7000 -j size=64 /tmp/sheepdog/0
> +
> +sleep 3
> +
> +collie cluster format -c 1
> +collie vdi create test 100M
> +
> +sudo sheep -d -c shepherd:127.0.0.1 -p 7000 -j size=64 /tmp/sheepdog/0
> diff --git a/tests/dynamorio/journaling/CMakeLists.txt b/tests/dynamorio/journaling/CMakeLists.txt
> new file mode 100644
> index 0000000..fcfabbd
> --- /dev/null
> +++ b/tests/dynamorio/journaling/CMakeLists.txt
> @@ -0,0 +1,10 @@
> +cmake_minimum_required(VERSION 2.8)
> +
> +SET(DynamoRIO_DIR "~/dynamorio/exports/cmake")
> +find_package(DynamoRIO)
> +
> +add_library(journaling SHARED journaling.c)
> +configure_DynamoRIO_client(journaling)
> +
> +use_DynamoRIO_extension(journaling drwrap)
> +use_DynamoRIO_extension(journaling drcontainers)
> diff --git a/tests/dynamorio/journaling/journaling.c b/tests/dynamorio/journaling/journaling.c
> new file mode 100644
> index 0000000..4c604df
> --- /dev/null
> +++ b/tests/dynamorio/journaling/journaling.c
> @@ -0,0 +1,358 @@
> +/*
> + * Copyright (C) 2013 Nippon Telegraph and Telephone Corporation.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License version
> + * 2 as published by the Free Software Foundation.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program. If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +/*
> + * DynamoRIO client for fault injection which can be used to test
> + * journaling mechanism
> + */
> +
> +#include "dr_api.h"
> +#include "drwrap.h"
> +#include "drmgr.h"
> +#include "hashtable.h"
> +#include "dr_tools.h"
> +
> +#include <string.h>
> +#include <syscall.h>
> +
> +#include <stdint.h>
> +
> +struct journal_descriptor {
> +	uint32_t magic;
> +	uint16_t flag;
> +	uint16_t reserved;
> +	union {
> +		uint32_t epoch;
> +		uint64_t oid;
> +	};
> +	uint64_t offset;
> +	uint64_t size;
> +	uint8_t create;
> +	uint8_t pad[475];
> +} __packed;

This must be as same as the one in sheep/journal.c and I think it's
likely to be broken when we update the definition.  I think we should
define journal_descriptor in include/internal_proto.h and this file
should include the header file.

> +
> +#define JOURNAL_DESC_MAGIC 0xfee1900d
> +
> +#define JF_STORE 0
> +#define JF_REMOVE_OBJ 2
> +
> +enum scenario_id {
> +	SID_UNDEF = -1,
> +
> +	SID_DO_NOTHING = 0,
> +	SID_DEATH_AFTER_STORE,
> +};
> +
> +enum scenario_id sid = SID_UNDEF;
> +
> +static int tls_idx;
> +static file_t log_file = INVALID_FILE;
> +
> +static int jfile_fds[2];
> +
> +#define fi_printf(fmt, args...) do {					\
> +		if (log_file == INVALID_FILE)				\
> +			dr_printf("%s(%d), " fmt,			\
> +				__func__, __LINE__, ## args);		\
> +		else							\
> +			dr_fprintf(log_file, "%s(%d), " fmt,		\
> +				__func__, __LINE__, ## args);		\
> +	} while (0)
> +
> +#define die(fmt, args...) do {						\
> +		fi_printf("FATAL %s(%d), " fmt,				\
> +			__func__, __LINE__, ## args);			\
> +	} while (0)
> +
> +static void *xmalloc(size_t size)
> +{
> +	void *ret;
> +
> +	ret = __wrap_malloc(size);
> +	if (!ret)
> +		die("allocating memory with __wrap_malloc() failed\n");
> +
> +	return ret;
> +}
> +
> +static void *xzalloc(size_t size)
> +{
> +	void *ret;
> +
> +	ret = xmalloc(size);
> +	memset(ret, 0, size);
> +
> +	return ret;
> +}
> +
> +static void *xcalloc(size_t size, size_t nmnb)
> +{
> +	void *ret;
> +	size_t length = size * nmnb;
> +
> +	ret = __wrap_malloc(length);
> +	if (!ret)
> +		die("allocating memory with __wrap_malloc() failed\n");
> +	memset(ret, 0, length);
> +
> +	return ret;
> +}
> +
> +static void xfree(void *ptr)
> +{
> +	__wrap_free(ptr);
> +}

No plan to use DynamoRIO for other sheepdog features than journaling?
I guess some functions in this file should be defined in a more common
place like common.c.

Thanks,

Kazutaka



More information about the sheepdog mailing list