summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/Makefile.am3
-rw-r--r--tests/Makefile.in697
-rw-r--r--tests/README147
-rw-r--r--tests/kernel/Makefile.am92
-rw-r--r--tests/kernel/Makefile.in1112
-rwxr-xr-xtests/kernel/directory-concurrent.sh46
-rw-r--r--tests/kernel/directory-concurrent/test.c287
-rwxr-xr-xtests/kernel/enospc.sh53
-rw-r--r--tests/kernel/enospc/test.c94
-rwxr-xr-xtests/kernel/extend-file-random.sh47
-rw-r--r--tests/kernel/extend-file-random/test.c216
-rwxr-xr-xtests/kernel/file-concurrent.sh46
-rw-r--r--tests/kernel/file-concurrent/test.c331
-rwxr-xr-xtests/kernel/inode-race-stat.sh50
-rw-r--r--tests/kernel/inode-race-stat/test.c374
-rwxr-xr-xtests/kernel/inotify.sh46
-rw-r--r--tests/kernel/inotify/test.c659
-rwxr-xr-xtests/kernel/link.sh83
-rwxr-xr-xtests/kernel/llseek.sh45
-rw-r--r--tests/kernel/llseek/test.c253
-rwxr-xr-xtests/kernel/lp-1009207.sh58
-rwxr-xr-xtests/kernel/lp-469664.sh47
-rwxr-xr-xtests/kernel/lp-509180.sh66
-rw-r--r--tests/kernel/lp-509180/test.c123
-rwxr-xr-xtests/kernel/lp-524919.sh46
-rw-r--r--tests/kernel/lp-524919/test.c100
-rwxr-xr-xtests/kernel/lp-561129.sh62
-rwxr-xr-xtests/kernel/lp-613873.sh63
-rwxr-xr-xtests/kernel/lp-745836.sh57
-rwxr-xr-xtests/kernel/lp-870326.sh46
-rw-r--r--tests/kernel/lp-870326/test.c160
-rwxr-xr-xtests/kernel/lp-872905.sh77
-rwxr-xr-xtests/kernel/lp-885744.sh50
-rwxr-xr-xtests/kernel/lp-911507.sh78
-rwxr-xr-xtests/kernel/lp-926292.sh53
-rwxr-xr-xtests/kernel/lp-994247.sh37
-rw-r--r--tests/kernel/lp-994247/test.c77
-rwxr-xr-xtests/kernel/miscdev-bad-count.sh37
-rw-r--r--tests/kernel/miscdev-bad-count/test.c46
-rwxr-xr-xtests/kernel/mknod.sh64
-rwxr-xr-xtests/kernel/mmap-bmap.sh58
-rw-r--r--tests/kernel/mmap-bmap/test.c132
-rwxr-xr-xtests/kernel/mmap-close.sh65
-rw-r--r--tests/kernel/mmap-close/test.c77
-rwxr-xr-xtests/kernel/mmap-dir.sh46
-rw-r--r--tests/kernel/mmap-dir/test.c79
-rwxr-xr-xtests/kernel/read-dir.sh48
-rw-r--r--tests/kernel/read-dir/test.c79
-rwxr-xr-xtests/kernel/setattr-flush-dirty.sh74
-rw-r--r--tests/kernel/tests.rc2
-rwxr-xr-xtests/kernel/trunc-file.sh50
-rw-r--r--tests/kernel/trunc-file/test.c278
-rw-r--r--tests/kernel/xattr/test.c111
-rw-r--r--tests/lib/Makefile.am5
-rw-r--r--tests/lib/Makefile.in667
-rw-r--r--tests/lib/etl_add_passphrase_key_to_keyring.c50
-rw-r--r--tests/lib/etl_funcs.sh601
-rwxr-xr-xtests/new.sh36
-rwxr-xr-xtests/run_tests.sh348
-rw-r--r--tests/userspace/Makefile.am26
-rw-r--r--tests/userspace/Makefile.in1134
-rwxr-xr-xtests/userspace/lfs.sh37
-rw-r--r--tests/userspace/lfs/test.c46
-rw-r--r--tests/userspace/tests.rc1
-rwxr-xr-xtests/userspace/verify-passphrase-sig.sh64
-rw-r--r--tests/userspace/verify-passphrase-sig/test.c70
-rwxr-xr-xtests/userspace/wrap-unwrap.sh40
-rw-r--r--tests/userspace/wrap-unwrap/test.c112
68 files changed, 10364 insertions, 0 deletions
diff --git a/tests/Makefile.am b/tests/Makefile.am
new file mode 100644
index 0000000..16bf3b7
--- /dev/null
+++ b/tests/Makefile.am
@@ -0,0 +1,3 @@
+SUBDIRS = lib userspace kernel
+
+dist_noinst_SCRIPTS = run_tests.sh new.sh
diff --git a/tests/Makefile.in b/tests/Makefile.in
new file mode 100644
index 0000000..00b4977
--- /dev/null
+++ b/tests/Makefile.in
@@ -0,0 +1,697 @@
+# Makefile.in generated by automake 1.13.3 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+subdir = tests
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+ $(dist_noinst_SCRIPTS) README
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/ac_pkg_swig.m4 \
+ $(top_srcdir)/m4/ac_python_devel.m4 \
+ $(top_srcdir)/m4/intltool.m4 $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/swig_python.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+SCRIPTS = $(dist_noinst_SCRIPTS)
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+SOURCES =
+DIST_SOURCES =
+RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
+ ctags-recursive dvi-recursive html-recursive info-recursive \
+ install-data-recursive install-dvi-recursive \
+ install-exec-recursive install-html-recursive \
+ install-info-recursive install-pdf-recursive \
+ install-ps-recursive install-recursive installcheck-recursive \
+ installdirs-recursive pdf-recursive ps-recursive \
+ tags-recursive uninstall-recursive
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
+ distclean-recursive maintainer-clean-recursive
+am__recursive_targets = \
+ $(RECURSIVE_TARGETS) \
+ $(RECURSIVE_CLEAN_TARGETS) \
+ $(am__extra_recursive_targets)
+AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
+ distdir
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+DIST_SUBDIRS = $(SUBDIRS)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+am__relativize = \
+ dir0=`pwd`; \
+ sed_first='s,^\([^/]*\)/.*$$,\1,'; \
+ sed_rest='s,^[^/]*/*,,'; \
+ sed_last='s,^.*/\([^/]*\)$$,\1,'; \
+ sed_butlast='s,/*[^/]*$$,,'; \
+ while test -n "$$dir1"; do \
+ first=`echo "$$dir1" | sed -e "$$sed_first"`; \
+ if test "$$first" != "."; then \
+ if test "$$first" = ".."; then \
+ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
+ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
+ else \
+ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
+ if test "$$first2" = "$$first"; then \
+ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
+ else \
+ dir2="../$$dir2"; \
+ fi; \
+ dir0="$$dir0"/"$$first"; \
+ fi; \
+ fi; \
+ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
+ done; \
+ reldir="$$dir2"
+ACLOCAL = @ACLOCAL@
+ALL_LINGUAS = @ALL_LINGUAS@
+AMTAR = @AMTAR@
+AM_CPPFLAGS = @AM_CPPFLAGS@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CATALOGS = @CATALOGS@
+CATOBJEXT = @CATOBJEXT@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CRYPTO_CFLAGS = @CRYPTO_CFLAGS@
+CRYPTO_LIBS = @CRYPTO_LIBS@
+CYGPATH_W = @CYGPATH_W@
+DATADIRNAME = @DATADIRNAME@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+DVIPS = @DVIPS@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
+GMOFILES = @GMOFILES@
+GMSGFMT = @GMSGFMT@
+GPGME_CFLAGS = @GPGME_CFLAGS@
+GPGME_LIBS = @GPGME_LIBS@
+GREP = @GREP@
+GTK_CFLAGS = @GTK_CFLAGS@
+GTK_LIBS = @GTK_LIBS@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INSTOBJEXT = @INSTOBJEXT@
+INTLLIBS = @INTLLIBS@
+INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@
+INTLTOOL_MERGE = @INTLTOOL_MERGE@
+INTLTOOL_PERL = @INTLTOOL_PERL@
+INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
+INTLTOOL_V_MERGE = @INTLTOOL_V_MERGE@
+INTLTOOL_V_MERGE_OPTIONS = @INTLTOOL_V_MERGE_OPTIONS@
+INTLTOOL__v_MERGE_ = @INTLTOOL__v_MERGE_@
+INTLTOOL__v_MERGE_0 = @INTLTOOL__v_MERGE_0@
+KEYUTILS_CFLAGS = @KEYUTILS_CFLAGS@
+KEYUTILS_LIBS = @KEYUTILS_LIBS@
+LATEX = @LATEX@
+LATEX2HTML = @LATEX2HTML@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBECRYPTFS_LT_AGE = @LIBECRYPTFS_LT_AGE@
+LIBECRYPTFS_LT_CURRENT = @LIBECRYPTFS_LT_CURRENT@
+LIBECRYPTFS_LT_REVISION = @LIBECRYPTFS_LT_REVISION@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LOCALEDIR = @LOCALEDIR@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+MSGFMT = @MSGFMT@
+MSGFMT_OPTS = @MSGFMT_OPTS@
+MSGMERGE = @MSGMERGE@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NSS_CFLAGS = @NSS_CFLAGS@
+NSS_LIBS = @NSS_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OPENSSL_CFLAGS = @OPENSSL_CFLAGS@
+OPENSSL_LIBS = @OPENSSL_LIBS@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PAM_CFLAGS = @PAM_CFLAGS@
+PAM_LIBS = @PAM_LIBS@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKCS11_HELPER_CFLAGS = @PKCS11_HELPER_CFLAGS@
+PKCS11_HELPER_LIBS = @PKCS11_HELPER_LIBS@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+POD2MAN = @POD2MAN@
+POFILES = @POFILES@
+POSUB = @POSUB@
+PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@
+PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@
+PS2PDF = @PS2PDF@
+PYTHON = @PYTHON@
+PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@
+PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@
+PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@
+PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
+PYTHON_PLATFORM = @PYTHON_PLATFORM@
+PYTHON_PREFIX = @PYTHON_PREFIX@
+PYTHON_SITE_PKG = @PYTHON_SITE_PKG@
+PYTHON_VERSION = @PYTHON_VERSION@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+SWIG = @SWIG@
+SWIG_LIB = @SWIG_LIB@
+SWIG_PYTHON_CPPFLAGS = @SWIG_PYTHON_CPPFLAGS@
+SWIG_PYTHON_OPT = @SWIG_PYTHON_OPT@
+TAR = @TAR@
+TSPI_CFLAGS = @TSPI_CFLAGS@
+TSPI_LIBS = @TSPI_LIBS@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+XGETTEXT = @XGETTEXT@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+ecryptfskeymoddir = @ecryptfskeymoddir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+intltool__v_merge_options_ = @intltool__v_merge_options_@
+intltool__v_merge_options_0 = @intltool__v_merge_options_0@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pamdir = @pamdir@
+pamlibdir = @pamlibdir@
+pdfdir = @pdfdir@
+pkgconfigdir = @pkgconfigdir@
+pkgpyexecdir = @pkgpyexecdir@
+pkgpythondir = @pkgpythondir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+pyexecdir = @pyexecdir@
+pythondir = @pythondir@
+rootsbindir = @rootsbindir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+SUBDIRS = lib userspace kernel
+dist_noinst_SCRIPTS = run_tests.sh new.sh
+all: all-recursive
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tests/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign tests/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run 'make' without going through this Makefile.
+# To change the values of 'make' variables: instead of editing Makefiles,
+# (1) if the variable is set in 'config.status', edit 'config.status'
+# (which will cause the Makefiles to be regenerated when you run 'make');
+# (2) otherwise, pass the desired values on the 'make' command line.
+$(am__recursive_targets):
+ @fail=; \
+ if $(am__make_keepgoing); then \
+ failcom='fail=yes'; \
+ else \
+ failcom='exit 1'; \
+ fi; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ case "$@" in \
+ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+ *) list='$(SUBDIRS)' ;; \
+ esac; \
+ for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-recursive
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+ include_option=--etags-include; \
+ empty_fix=.; \
+ else \
+ include_option=--include; \
+ empty_fix=; \
+ fi; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test ! -f $$subdir/TAGS || \
+ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-recursive
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-recursive
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+ @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ $(am__make_dryrun) \
+ || test -d "$(distdir)/$$subdir" \
+ || $(MKDIR_P) "$(distdir)/$$subdir" \
+ || exit 1; \
+ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
+ $(am__relativize); \
+ new_distdir=$$reldir; \
+ dir1=$$subdir; dir2="$(top_distdir)"; \
+ $(am__relativize); \
+ new_top_distdir=$$reldir; \
+ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
+ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
+ ($(am__cd) $$subdir && \
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$$new_top_distdir" \
+ distdir="$$new_distdir" \
+ am__remove_distdir=: \
+ am__skip_length_check=: \
+ am__skip_mode_fix=: \
+ distdir) \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-recursive
+all-am: Makefile $(SCRIPTS)
+installdirs: installdirs-recursive
+installdirs-am:
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-recursive
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-recursive
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+html-am:
+
+info: info-recursive
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-recursive
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-recursive
+
+install-html-am:
+
+install-info: install-info-recursive
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-recursive
+
+install-pdf-am:
+
+install-ps: install-ps-recursive
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: $(am__recursive_targets) install-am install-strip
+
+.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \
+ check-am clean clean-generic clean-libtool cscopelist-am ctags \
+ ctags-am distclean distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ installdirs-am maintainer-clean maintainer-clean-generic \
+ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
+ ps ps-am tags tags-am uninstall uninstall-am
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/tests/README b/tests/README
new file mode 100644
index 0000000..442a206
--- /dev/null
+++ b/tests/README
@@ -0,0 +1,147 @@
+eCryptfs Test Suite
+
+Follow these steps when adding a new test:
+
+ NOTE: This guide primarily focuses on kernel test cases. If you're writing a
+ userspace test case, substitute all mentions of tests/kernel/ with
+ tests/userspace/ and pay attention to any other kernel-specific
+ instructions.
+
+ 1) Pick a name for the new test. This guide will be using the test case name
+ "mmap-close", but you'll need to substitute in the name of your own test
+ case.
+
+ If it is a reproducer for a bug, consider using the bug tracker and bug
+ number. For example, lp-469664 is the test for
+ https://launchpad.net/bugs/469664.
+
+ Otherwise, pick a short, but descriptive, name for the test. For example,
+ trunc-file is the name of a test that excercises file truncation.
+
+ 2) Copy the skeleton test script to the appropriate test directory. In this
+ guide, we're creating a kernel test so copy it to the tests/kernel/
+ directory:
+
+ ---
+ $ cp tests/new.sh tests/kernel/mmap-close.sh
+ ---
+
+ 3) Update the information in the comments at the top of your new test case.
+ Specifically, the words below in all caps need to be modified:
+
+ ---
+ # FILENAME: Test for BUG_URL|LIST_URL|DESCRIPTION
+ # Author: FIRST LAST <USER@DOMAIN>
+ #
+ # Copyright (C) YEAR COPYRIGHT_HOLDER
+ ---
+
+ In this case, we end up with something along these lines:
+
+ ---
+ # mmap-close.sh : Test for catching regressions when applications do this:
+ #
+ # open() -> mmap() -> *close()* -> dirty mapping -> munmap()
+ #
+ # Past regressions have been reported in these bugs:
+ #
+ # https://bugs.launchpad.net/bugs/870326
+ # https://bugs.launchpad.net/bugs/1047261
+ # Author: Tyler Hicks <tyhicks@canonical.com>
+ ---
+
+ 4) Now you can start writing the test. You'll probably need to set up a basic
+ eCryptfs mount. You can do that by pasting in these sequence of helper
+ functions after the "# TEST" line in your new test case:
+
+ ---
+ # TEST
+ etl_add_keys || exit
+ etl_lmount || exit
+ etl_mount_i || exit
+ test_dir=$(etl_create_test_dir) || exit
+ ---
+
+ This is probably a good time to introduce the library of helper functions.
+ It can be found in tests/lib/etl_funcs.sh. Take a look at the functions
+ available and feel free to add any new functions if you feel like they would
+ benefit multiple test cases.
+
+ 5) At this point, we have a lower filesystem mounted, an eCryptfs filesystem
+ mounted on top of it, and a test directory created inside of the eCryptfs
+ mount. We'll need to properly tear all of that down when the test case
+ exits, so update the test_cleanup() function accordingly:
+
+ ---
+ test_cleanup()
+ {
+ etl_remove_test_dir $test_dir
+ etl_umount
+ etl_lumount
+ etl_unlink_keys
+ exit $rc
+ }
+ trap test_cleanup 0 1 2 3 15
+ ---
+
+ 6) Now we are ready to implement the actual test. If it is simple enough to do
+ with basic bash commands, as is the case for lp-469664.sh, simply add those
+ commands and skip to step 11).
+
+ If you need to write a C (or possibly Python) program, proceed to step 7).
+
+ 7) Create a directory to hold the C source file(s) and any other data files
+ that you'll need. It should be named after your test case.
+
+ ---
+ $ mkdir tests/kernel/mmap-close/
+ ---
+
+ 8) Create a new file, inside that directory, called test.c and implement the
+ test case in the new file. Be sure to add a header, including the GPLv2
+ text, similar to what is in the example test script that was modified in
+ step 3).
+
+ 9) Update the test script (mmap-close.sh) to call the test binary after the
+ environment setup stage:
+
+ ---
+ ${test_script_dir}/mmap-close/test || exit
+ ---
+
+ 10) Add a line to tests/kernel/Makefile.am to build test.c:
+
+ ---
+ mmap_close_test_SOURCES = mmap-close/test.c
+ ---
+
+ And add the test binary to the noinst_PROGRAMS list:
+
+ ---
+ noinst_PROGRAMS = directory-concurrent/test \
+ ...
+ mmap-close/test \
+ ...
+ trunc-file/test
+
+ ---
+
+ 11) Add a line to tests/kernel/Makefile.am to place the new test script in the
+ dist_noinst_SCRIPTS list:
+
+ ---
+ dist_noinst_SCRIPTS = directory-concurrent.sh \
+ ...
+ mmap-close.sh \
+ ...
+ trunc-file.sh
+
+ ---
+
+ 12) Finally, add the new test script to the appropriate list in
+ tests/kernel/tests.rc. There are only two lists - safe and destructive.
+ Safe means that the tests aren't likely to cause a kernel oops or other
+ unrecoverable error. Everything else goes in the destructive list.
+
+This was a quick introduction into creating a new test case. Look at other
+existing test cases for more examples.
diff --git a/tests/kernel/Makefile.am b/tests/kernel/Makefile.am
new file mode 100644
index 0000000..5758677
--- /dev/null
+++ b/tests/kernel/Makefile.am
@@ -0,0 +1,92 @@
+AUTOMAKE_OPTIONS = subdir-objects
+
+dist_noinst_DATA = tests.rc
+
+dist_noinst_SCRIPTS = directory-concurrent.sh \
+ enospc.sh \
+ extend-file-random.sh \
+ file-concurrent.sh \
+ inode-race-stat.sh \
+ inotify.sh \
+ link.sh \
+ llseek.sh \
+ lp-1009207.sh \
+ lp-469664.sh \
+ lp-509180.sh \
+ lp-524919.sh \
+ lp-561129.sh \
+ lp-613873.sh \
+ lp-745836.sh \
+ lp-870326.sh \
+ lp-872905.sh \
+ lp-885744.sh \
+ lp-911507.sh \
+ lp-926292.sh \
+ lp-994247.sh \
+ miscdev-bad-count.sh \
+ mknod.sh \
+ mmap-bmap.sh \
+ mmap-close.sh \
+ mmap-dir.sh \
+ read-dir.sh \
+ setattr-flush-dirty.sh \
+ trunc-file.sh
+
+if ENABLE_TESTS
+noinst_PROGRAMS = directory-concurrent/test \
+ enospc/test \
+ extend-file-random/test \
+ file-concurrent/test \
+ inode-race-stat/test \
+ inotify/test \
+ llseek/test \
+ lp-509180/test \
+ lp-524919/test \
+ lp-870326/test \
+ lp-994247/test \
+ miscdev-bad-count/test \
+ mmap-bmap/test \
+ mmap-close/test \
+ mmap-dir/test \
+ read-dir/test \
+ trunc-file/test \
+ xattr/test
+endif
+
+directory_concurrent_test_SOURCES = directory-concurrent/test.c
+
+enospc_test_SOURCES = enospc/test.c
+
+extend_file_random_test_SOURCES = extend-file-random/test.c
+
+file_concurrent_test_SOURCES = file-concurrent/test.c
+
+inode_race_stat_test_SOURCES = inode-race-stat/test.c
+
+inotify_test_SOURCES = inotify/test.c
+
+llseek_test_SOURCES = llseek/test.c
+
+lp_509180_test_SOURCES = lp-509180/test.c
+
+lp_524919_test_SOURCES = lp-524919/test.c
+
+lp_870326_test_SOURCES = lp-870326/test.c
+
+lp_994247_test_SOURCES = lp-994247/test.c
+
+miscdev_bad_count_test_SOURCES = miscdev-bad-count/test.c
+miscdev_bad_count_test_LDADD = $(top_builddir)/src/libecryptfs/libecryptfs.la
+
+mmap_bmap_test_SOURCES = mmap-bmap/test.c
+
+mmap_close_test_SOURCES = mmap-close/test.c
+
+mmap_dir_test_SOURCES = mmap-dir/test.c
+
+read_dir_test_SOURCES = read-dir/test.c
+
+trunc_file_test_SOURCES = trunc-file/test.c
+
+xattr_test_SOURCES = xattr/test.c
+
diff --git a/tests/kernel/Makefile.in b/tests/kernel/Makefile.in
new file mode 100644
index 0000000..85e3355
--- /dev/null
+++ b/tests/kernel/Makefile.in
@@ -0,0 +1,1112 @@
+# Makefile.in generated by automake 1.13.3 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+
+
+VPATH = @srcdir@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+@ENABLE_TESTS_TRUE@noinst_PROGRAMS = \
+@ENABLE_TESTS_TRUE@ directory-concurrent/test$(EXEEXT) \
+@ENABLE_TESTS_TRUE@ enospc/test$(EXEEXT) \
+@ENABLE_TESTS_TRUE@ extend-file-random/test$(EXEEXT) \
+@ENABLE_TESTS_TRUE@ file-concurrent/test$(EXEEXT) \
+@ENABLE_TESTS_TRUE@ inode-race-stat/test$(EXEEXT) \
+@ENABLE_TESTS_TRUE@ inotify/test$(EXEEXT) llseek/test$(EXEEXT) \
+@ENABLE_TESTS_TRUE@ lp-509180/test$(EXEEXT) \
+@ENABLE_TESTS_TRUE@ lp-524919/test$(EXEEXT) \
+@ENABLE_TESTS_TRUE@ lp-870326/test$(EXEEXT) \
+@ENABLE_TESTS_TRUE@ lp-994247/test$(EXEEXT) \
+@ENABLE_TESTS_TRUE@ miscdev-bad-count/test$(EXEEXT) \
+@ENABLE_TESTS_TRUE@ mmap-bmap/test$(EXEEXT) \
+@ENABLE_TESTS_TRUE@ mmap-close/test$(EXEEXT) \
+@ENABLE_TESTS_TRUE@ mmap-dir/test$(EXEEXT) \
+@ENABLE_TESTS_TRUE@ read-dir/test$(EXEEXT) \
+@ENABLE_TESTS_TRUE@ trunc-file/test$(EXEEXT) \
+@ENABLE_TESTS_TRUE@ xattr/test$(EXEEXT)
+subdir = tests/kernel
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+ $(dist_noinst_SCRIPTS) $(top_srcdir)/depcomp \
+ $(dist_noinst_DATA)
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/ac_pkg_swig.m4 \
+ $(top_srcdir)/m4/ac_python_devel.m4 \
+ $(top_srcdir)/m4/intltool.m4 $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/swig_python.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+PROGRAMS = $(noinst_PROGRAMS)
+am__dirstamp = $(am__leading_dot)dirstamp
+am_directory_concurrent_test_OBJECTS = \
+ directory-concurrent/test.$(OBJEXT)
+directory_concurrent_test_OBJECTS = \
+ $(am_directory_concurrent_test_OBJECTS)
+directory_concurrent_test_LDADD = $(LDADD)
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+am_enospc_test_OBJECTS = enospc/test.$(OBJEXT)
+enospc_test_OBJECTS = $(am_enospc_test_OBJECTS)
+enospc_test_LDADD = $(LDADD)
+am_extend_file_random_test_OBJECTS = \
+ extend-file-random/test.$(OBJEXT)
+extend_file_random_test_OBJECTS = \
+ $(am_extend_file_random_test_OBJECTS)
+extend_file_random_test_LDADD = $(LDADD)
+am_file_concurrent_test_OBJECTS = file-concurrent/test.$(OBJEXT)
+file_concurrent_test_OBJECTS = $(am_file_concurrent_test_OBJECTS)
+file_concurrent_test_LDADD = $(LDADD)
+am_inode_race_stat_test_OBJECTS = inode-race-stat/test.$(OBJEXT)
+inode_race_stat_test_OBJECTS = $(am_inode_race_stat_test_OBJECTS)
+inode_race_stat_test_LDADD = $(LDADD)
+am_inotify_test_OBJECTS = inotify/test.$(OBJEXT)
+inotify_test_OBJECTS = $(am_inotify_test_OBJECTS)
+inotify_test_LDADD = $(LDADD)
+am_llseek_test_OBJECTS = llseek/test.$(OBJEXT)
+llseek_test_OBJECTS = $(am_llseek_test_OBJECTS)
+llseek_test_LDADD = $(LDADD)
+am_lp_509180_test_OBJECTS = lp-509180/test.$(OBJEXT)
+lp_509180_test_OBJECTS = $(am_lp_509180_test_OBJECTS)
+lp_509180_test_LDADD = $(LDADD)
+am_lp_524919_test_OBJECTS = lp-524919/test.$(OBJEXT)
+lp_524919_test_OBJECTS = $(am_lp_524919_test_OBJECTS)
+lp_524919_test_LDADD = $(LDADD)
+am_lp_870326_test_OBJECTS = lp-870326/test.$(OBJEXT)
+lp_870326_test_OBJECTS = $(am_lp_870326_test_OBJECTS)
+lp_870326_test_LDADD = $(LDADD)
+am_lp_994247_test_OBJECTS = lp-994247/test.$(OBJEXT)
+lp_994247_test_OBJECTS = $(am_lp_994247_test_OBJECTS)
+lp_994247_test_LDADD = $(LDADD)
+am_miscdev_bad_count_test_OBJECTS = miscdev-bad-count/test.$(OBJEXT)
+miscdev_bad_count_test_OBJECTS = $(am_miscdev_bad_count_test_OBJECTS)
+miscdev_bad_count_test_DEPENDENCIES = \
+ $(top_builddir)/src/libecryptfs/libecryptfs.la
+am_mmap_bmap_test_OBJECTS = mmap-bmap/test.$(OBJEXT)
+mmap_bmap_test_OBJECTS = $(am_mmap_bmap_test_OBJECTS)
+mmap_bmap_test_LDADD = $(LDADD)
+am_mmap_close_test_OBJECTS = mmap-close/test.$(OBJEXT)
+mmap_close_test_OBJECTS = $(am_mmap_close_test_OBJECTS)
+mmap_close_test_LDADD = $(LDADD)
+am_mmap_dir_test_OBJECTS = mmap-dir/test.$(OBJEXT)
+mmap_dir_test_OBJECTS = $(am_mmap_dir_test_OBJECTS)
+mmap_dir_test_LDADD = $(LDADD)
+am_read_dir_test_OBJECTS = read-dir/test.$(OBJEXT)
+read_dir_test_OBJECTS = $(am_read_dir_test_OBJECTS)
+read_dir_test_LDADD = $(LDADD)
+am_trunc_file_test_OBJECTS = trunc-file/test.$(OBJEXT)
+trunc_file_test_OBJECTS = $(am_trunc_file_test_OBJECTS)
+trunc_file_test_LDADD = $(LDADD)
+am_xattr_test_OBJECTS = xattr/test.$(OBJEXT)
+xattr_test_OBJECTS = $(am_xattr_test_OBJECTS)
+xattr_test_LDADD = $(LDADD)
+SCRIPTS = $(dist_noinst_SCRIPTS)
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = $(directory_concurrent_test_SOURCES) $(enospc_test_SOURCES) \
+ $(extend_file_random_test_SOURCES) \
+ $(file_concurrent_test_SOURCES) \
+ $(inode_race_stat_test_SOURCES) $(inotify_test_SOURCES) \
+ $(llseek_test_SOURCES) $(lp_509180_test_SOURCES) \
+ $(lp_524919_test_SOURCES) $(lp_870326_test_SOURCES) \
+ $(lp_994247_test_SOURCES) $(miscdev_bad_count_test_SOURCES) \
+ $(mmap_bmap_test_SOURCES) $(mmap_close_test_SOURCES) \
+ $(mmap_dir_test_SOURCES) $(read_dir_test_SOURCES) \
+ $(trunc_file_test_SOURCES) $(xattr_test_SOURCES)
+DIST_SOURCES = $(directory_concurrent_test_SOURCES) \
+ $(enospc_test_SOURCES) $(extend_file_random_test_SOURCES) \
+ $(file_concurrent_test_SOURCES) \
+ $(inode_race_stat_test_SOURCES) $(inotify_test_SOURCES) \
+ $(llseek_test_SOURCES) $(lp_509180_test_SOURCES) \
+ $(lp_524919_test_SOURCES) $(lp_870326_test_SOURCES) \
+ $(lp_994247_test_SOURCES) $(miscdev_bad_count_test_SOURCES) \
+ $(mmap_bmap_test_SOURCES) $(mmap_close_test_SOURCES) \
+ $(mmap_dir_test_SOURCES) $(read_dir_test_SOURCES) \
+ $(trunc_file_test_SOURCES) $(xattr_test_SOURCES)
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+DATA = $(dist_noinst_DATA)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALL_LINGUAS = @ALL_LINGUAS@
+AMTAR = @AMTAR@
+AM_CPPFLAGS = @AM_CPPFLAGS@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CATALOGS = @CATALOGS@
+CATOBJEXT = @CATOBJEXT@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CRYPTO_CFLAGS = @CRYPTO_CFLAGS@
+CRYPTO_LIBS = @CRYPTO_LIBS@
+CYGPATH_W = @CYGPATH_W@
+DATADIRNAME = @DATADIRNAME@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+DVIPS = @DVIPS@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
+GMOFILES = @GMOFILES@
+GMSGFMT = @GMSGFMT@
+GPGME_CFLAGS = @GPGME_CFLAGS@
+GPGME_LIBS = @GPGME_LIBS@
+GREP = @GREP@
+GTK_CFLAGS = @GTK_CFLAGS@
+GTK_LIBS = @GTK_LIBS@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INSTOBJEXT = @INSTOBJEXT@
+INTLLIBS = @INTLLIBS@
+INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@
+INTLTOOL_MERGE = @INTLTOOL_MERGE@
+INTLTOOL_PERL = @INTLTOOL_PERL@
+INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
+INTLTOOL_V_MERGE = @INTLTOOL_V_MERGE@
+INTLTOOL_V_MERGE_OPTIONS = @INTLTOOL_V_MERGE_OPTIONS@
+INTLTOOL__v_MERGE_ = @INTLTOOL__v_MERGE_@
+INTLTOOL__v_MERGE_0 = @INTLTOOL__v_MERGE_0@
+KEYUTILS_CFLAGS = @KEYUTILS_CFLAGS@
+KEYUTILS_LIBS = @KEYUTILS_LIBS@
+LATEX = @LATEX@
+LATEX2HTML = @LATEX2HTML@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBECRYPTFS_LT_AGE = @LIBECRYPTFS_LT_AGE@
+LIBECRYPTFS_LT_CURRENT = @LIBECRYPTFS_LT_CURRENT@
+LIBECRYPTFS_LT_REVISION = @LIBECRYPTFS_LT_REVISION@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LOCALEDIR = @LOCALEDIR@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+MSGFMT = @MSGFMT@
+MSGFMT_OPTS = @MSGFMT_OPTS@
+MSGMERGE = @MSGMERGE@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NSS_CFLAGS = @NSS_CFLAGS@
+NSS_LIBS = @NSS_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OPENSSL_CFLAGS = @OPENSSL_CFLAGS@
+OPENSSL_LIBS = @OPENSSL_LIBS@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PAM_CFLAGS = @PAM_CFLAGS@
+PAM_LIBS = @PAM_LIBS@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKCS11_HELPER_CFLAGS = @PKCS11_HELPER_CFLAGS@
+PKCS11_HELPER_LIBS = @PKCS11_HELPER_LIBS@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+POD2MAN = @POD2MAN@
+POFILES = @POFILES@
+POSUB = @POSUB@
+PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@
+PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@
+PS2PDF = @PS2PDF@
+PYTHON = @PYTHON@
+PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@
+PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@
+PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@
+PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
+PYTHON_PLATFORM = @PYTHON_PLATFORM@
+PYTHON_PREFIX = @PYTHON_PREFIX@
+PYTHON_SITE_PKG = @PYTHON_SITE_PKG@
+PYTHON_VERSION = @PYTHON_VERSION@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+SWIG = @SWIG@
+SWIG_LIB = @SWIG_LIB@
+SWIG_PYTHON_CPPFLAGS = @SWIG_PYTHON_CPPFLAGS@
+SWIG_PYTHON_OPT = @SWIG_PYTHON_OPT@
+TAR = @TAR@
+TSPI_CFLAGS = @TSPI_CFLAGS@
+TSPI_LIBS = @TSPI_LIBS@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+XGETTEXT = @XGETTEXT@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+ecryptfskeymoddir = @ecryptfskeymoddir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+intltool__v_merge_options_ = @intltool__v_merge_options_@
+intltool__v_merge_options_0 = @intltool__v_merge_options_0@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pamdir = @pamdir@
+pamlibdir = @pamlibdir@
+pdfdir = @pdfdir@
+pkgconfigdir = @pkgconfigdir@
+pkgpyexecdir = @pkgpyexecdir@
+pkgpythondir = @pkgpythondir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+pyexecdir = @pyexecdir@
+pythondir = @pythondir@
+rootsbindir = @rootsbindir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+AUTOMAKE_OPTIONS = subdir-objects
+dist_noinst_DATA = tests.rc
+dist_noinst_SCRIPTS = directory-concurrent.sh \
+ enospc.sh \
+ extend-file-random.sh \
+ file-concurrent.sh \
+ inode-race-stat.sh \
+ inotify.sh \
+ link.sh \
+ llseek.sh \
+ lp-1009207.sh \
+ lp-469664.sh \
+ lp-509180.sh \
+ lp-524919.sh \
+ lp-561129.sh \
+ lp-613873.sh \
+ lp-745836.sh \
+ lp-870326.sh \
+ lp-872905.sh \
+ lp-885744.sh \
+ lp-911507.sh \
+ lp-926292.sh \
+ lp-994247.sh \
+ miscdev-bad-count.sh \
+ mknod.sh \
+ mmap-bmap.sh \
+ mmap-close.sh \
+ mmap-dir.sh \
+ read-dir.sh \
+ setattr-flush-dirty.sh \
+ trunc-file.sh
+
+directory_concurrent_test_SOURCES = directory-concurrent/test.c
+enospc_test_SOURCES = enospc/test.c
+extend_file_random_test_SOURCES = extend-file-random/test.c
+file_concurrent_test_SOURCES = file-concurrent/test.c
+inode_race_stat_test_SOURCES = inode-race-stat/test.c
+inotify_test_SOURCES = inotify/test.c
+llseek_test_SOURCES = llseek/test.c
+lp_509180_test_SOURCES = lp-509180/test.c
+lp_524919_test_SOURCES = lp-524919/test.c
+lp_870326_test_SOURCES = lp-870326/test.c
+lp_994247_test_SOURCES = lp-994247/test.c
+miscdev_bad_count_test_SOURCES = miscdev-bad-count/test.c
+miscdev_bad_count_test_LDADD = $(top_builddir)/src/libecryptfs/libecryptfs.la
+mmap_bmap_test_SOURCES = mmap-bmap/test.c
+mmap_close_test_SOURCES = mmap-close/test.c
+mmap_dir_test_SOURCES = mmap-dir/test.c
+read_dir_test_SOURCES = read-dir/test.c
+trunc_file_test_SOURCES = trunc-file/test.c
+xattr_test_SOURCES = xattr/test.c
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tests/kernel/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign tests/kernel/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-noinstPROGRAMS:
+ @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+directory-concurrent/$(am__dirstamp):
+ @$(MKDIR_P) directory-concurrent
+ @: > directory-concurrent/$(am__dirstamp)
+directory-concurrent/$(DEPDIR)/$(am__dirstamp):
+ @$(MKDIR_P) directory-concurrent/$(DEPDIR)
+ @: > directory-concurrent/$(DEPDIR)/$(am__dirstamp)
+directory-concurrent/test.$(OBJEXT): \
+ directory-concurrent/$(am__dirstamp) \
+ directory-concurrent/$(DEPDIR)/$(am__dirstamp)
+
+directory-concurrent/test$(EXEEXT): $(directory_concurrent_test_OBJECTS) $(directory_concurrent_test_DEPENDENCIES) $(EXTRA_directory_concurrent_test_DEPENDENCIES) directory-concurrent/$(am__dirstamp)
+ @rm -f directory-concurrent/test$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(directory_concurrent_test_OBJECTS) $(directory_concurrent_test_LDADD) $(LIBS)
+enospc/$(am__dirstamp):
+ @$(MKDIR_P) enospc
+ @: > enospc/$(am__dirstamp)
+enospc/$(DEPDIR)/$(am__dirstamp):
+ @$(MKDIR_P) enospc/$(DEPDIR)
+ @: > enospc/$(DEPDIR)/$(am__dirstamp)
+enospc/test.$(OBJEXT): enospc/$(am__dirstamp) \
+ enospc/$(DEPDIR)/$(am__dirstamp)
+
+enospc/test$(EXEEXT): $(enospc_test_OBJECTS) $(enospc_test_DEPENDENCIES) $(EXTRA_enospc_test_DEPENDENCIES) enospc/$(am__dirstamp)
+ @rm -f enospc/test$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(enospc_test_OBJECTS) $(enospc_test_LDADD) $(LIBS)
+extend-file-random/$(am__dirstamp):
+ @$(MKDIR_P) extend-file-random
+ @: > extend-file-random/$(am__dirstamp)
+extend-file-random/$(DEPDIR)/$(am__dirstamp):
+ @$(MKDIR_P) extend-file-random/$(DEPDIR)
+ @: > extend-file-random/$(DEPDIR)/$(am__dirstamp)
+extend-file-random/test.$(OBJEXT): extend-file-random/$(am__dirstamp) \
+ extend-file-random/$(DEPDIR)/$(am__dirstamp)
+
+extend-file-random/test$(EXEEXT): $(extend_file_random_test_OBJECTS) $(extend_file_random_test_DEPENDENCIES) $(EXTRA_extend_file_random_test_DEPENDENCIES) extend-file-random/$(am__dirstamp)
+ @rm -f extend-file-random/test$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(extend_file_random_test_OBJECTS) $(extend_file_random_test_LDADD) $(LIBS)
+file-concurrent/$(am__dirstamp):
+ @$(MKDIR_P) file-concurrent
+ @: > file-concurrent/$(am__dirstamp)
+file-concurrent/$(DEPDIR)/$(am__dirstamp):
+ @$(MKDIR_P) file-concurrent/$(DEPDIR)
+ @: > file-concurrent/$(DEPDIR)/$(am__dirstamp)
+file-concurrent/test.$(OBJEXT): file-concurrent/$(am__dirstamp) \
+ file-concurrent/$(DEPDIR)/$(am__dirstamp)
+
+file-concurrent/test$(EXEEXT): $(file_concurrent_test_OBJECTS) $(file_concurrent_test_DEPENDENCIES) $(EXTRA_file_concurrent_test_DEPENDENCIES) file-concurrent/$(am__dirstamp)
+ @rm -f file-concurrent/test$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(file_concurrent_test_OBJECTS) $(file_concurrent_test_LDADD) $(LIBS)
+inode-race-stat/$(am__dirstamp):
+ @$(MKDIR_P) inode-race-stat
+ @: > inode-race-stat/$(am__dirstamp)
+inode-race-stat/$(DEPDIR)/$(am__dirstamp):
+ @$(MKDIR_P) inode-race-stat/$(DEPDIR)
+ @: > inode-race-stat/$(DEPDIR)/$(am__dirstamp)
+inode-race-stat/test.$(OBJEXT): inode-race-stat/$(am__dirstamp) \
+ inode-race-stat/$(DEPDIR)/$(am__dirstamp)
+
+inode-race-stat/test$(EXEEXT): $(inode_race_stat_test_OBJECTS) $(inode_race_stat_test_DEPENDENCIES) $(EXTRA_inode_race_stat_test_DEPENDENCIES) inode-race-stat/$(am__dirstamp)
+ @rm -f inode-race-stat/test$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(inode_race_stat_test_OBJECTS) $(inode_race_stat_test_LDADD) $(LIBS)
+inotify/$(am__dirstamp):
+ @$(MKDIR_P) inotify
+ @: > inotify/$(am__dirstamp)
+inotify/$(DEPDIR)/$(am__dirstamp):
+ @$(MKDIR_P) inotify/$(DEPDIR)
+ @: > inotify/$(DEPDIR)/$(am__dirstamp)
+inotify/test.$(OBJEXT): inotify/$(am__dirstamp) \
+ inotify/$(DEPDIR)/$(am__dirstamp)
+
+inotify/test$(EXEEXT): $(inotify_test_OBJECTS) $(inotify_test_DEPENDENCIES) $(EXTRA_inotify_test_DEPENDENCIES) inotify/$(am__dirstamp)
+ @rm -f inotify/test$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(inotify_test_OBJECTS) $(inotify_test_LDADD) $(LIBS)
+llseek/$(am__dirstamp):
+ @$(MKDIR_P) llseek
+ @: > llseek/$(am__dirstamp)
+llseek/$(DEPDIR)/$(am__dirstamp):
+ @$(MKDIR_P) llseek/$(DEPDIR)
+ @: > llseek/$(DEPDIR)/$(am__dirstamp)
+llseek/test.$(OBJEXT): llseek/$(am__dirstamp) \
+ llseek/$(DEPDIR)/$(am__dirstamp)
+
+llseek/test$(EXEEXT): $(llseek_test_OBJECTS) $(llseek_test_DEPENDENCIES) $(EXTRA_llseek_test_DEPENDENCIES) llseek/$(am__dirstamp)
+ @rm -f llseek/test$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(llseek_test_OBJECTS) $(llseek_test_LDADD) $(LIBS)
+lp-509180/$(am__dirstamp):
+ @$(MKDIR_P) lp-509180
+ @: > lp-509180/$(am__dirstamp)
+lp-509180/$(DEPDIR)/$(am__dirstamp):
+ @$(MKDIR_P) lp-509180/$(DEPDIR)
+ @: > lp-509180/$(DEPDIR)/$(am__dirstamp)
+lp-509180/test.$(OBJEXT): lp-509180/$(am__dirstamp) \
+ lp-509180/$(DEPDIR)/$(am__dirstamp)
+
+lp-509180/test$(EXEEXT): $(lp_509180_test_OBJECTS) $(lp_509180_test_DEPENDENCIES) $(EXTRA_lp_509180_test_DEPENDENCIES) lp-509180/$(am__dirstamp)
+ @rm -f lp-509180/test$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(lp_509180_test_OBJECTS) $(lp_509180_test_LDADD) $(LIBS)
+lp-524919/$(am__dirstamp):
+ @$(MKDIR_P) lp-524919
+ @: > lp-524919/$(am__dirstamp)
+lp-524919/$(DEPDIR)/$(am__dirstamp):
+ @$(MKDIR_P) lp-524919/$(DEPDIR)
+ @: > lp-524919/$(DEPDIR)/$(am__dirstamp)
+lp-524919/test.$(OBJEXT): lp-524919/$(am__dirstamp) \
+ lp-524919/$(DEPDIR)/$(am__dirstamp)
+
+lp-524919/test$(EXEEXT): $(lp_524919_test_OBJECTS) $(lp_524919_test_DEPENDENCIES) $(EXTRA_lp_524919_test_DEPENDENCIES) lp-524919/$(am__dirstamp)
+ @rm -f lp-524919/test$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(lp_524919_test_OBJECTS) $(lp_524919_test_LDADD) $(LIBS)
+lp-870326/$(am__dirstamp):
+ @$(MKDIR_P) lp-870326
+ @: > lp-870326/$(am__dirstamp)
+lp-870326/$(DEPDIR)/$(am__dirstamp):
+ @$(MKDIR_P) lp-870326/$(DEPDIR)
+ @: > lp-870326/$(DEPDIR)/$(am__dirstamp)
+lp-870326/test.$(OBJEXT): lp-870326/$(am__dirstamp) \
+ lp-870326/$(DEPDIR)/$(am__dirstamp)
+
+lp-870326/test$(EXEEXT): $(lp_870326_test_OBJECTS) $(lp_870326_test_DEPENDENCIES) $(EXTRA_lp_870326_test_DEPENDENCIES) lp-870326/$(am__dirstamp)
+ @rm -f lp-870326/test$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(lp_870326_test_OBJECTS) $(lp_870326_test_LDADD) $(LIBS)
+lp-994247/$(am__dirstamp):
+ @$(MKDIR_P) lp-994247
+ @: > lp-994247/$(am__dirstamp)
+lp-994247/$(DEPDIR)/$(am__dirstamp):
+ @$(MKDIR_P) lp-994247/$(DEPDIR)
+ @: > lp-994247/$(DEPDIR)/$(am__dirstamp)
+lp-994247/test.$(OBJEXT): lp-994247/$(am__dirstamp) \
+ lp-994247/$(DEPDIR)/$(am__dirstamp)
+
+lp-994247/test$(EXEEXT): $(lp_994247_test_OBJECTS) $(lp_994247_test_DEPENDENCIES) $(EXTRA_lp_994247_test_DEPENDENCIES) lp-994247/$(am__dirstamp)
+ @rm -f lp-994247/test$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(lp_994247_test_OBJECTS) $(lp_994247_test_LDADD) $(LIBS)
+miscdev-bad-count/$(am__dirstamp):
+ @$(MKDIR_P) miscdev-bad-count
+ @: > miscdev-bad-count/$(am__dirstamp)
+miscdev-bad-count/$(DEPDIR)/$(am__dirstamp):
+ @$(MKDIR_P) miscdev-bad-count/$(DEPDIR)
+ @: > miscdev-bad-count/$(DEPDIR)/$(am__dirstamp)
+miscdev-bad-count/test.$(OBJEXT): miscdev-bad-count/$(am__dirstamp) \
+ miscdev-bad-count/$(DEPDIR)/$(am__dirstamp)
+
+miscdev-bad-count/test$(EXEEXT): $(miscdev_bad_count_test_OBJECTS) $(miscdev_bad_count_test_DEPENDENCIES) $(EXTRA_miscdev_bad_count_test_DEPENDENCIES) miscdev-bad-count/$(am__dirstamp)
+ @rm -f miscdev-bad-count/test$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(miscdev_bad_count_test_OBJECTS) $(miscdev_bad_count_test_LDADD) $(LIBS)
+mmap-bmap/$(am__dirstamp):
+ @$(MKDIR_P) mmap-bmap
+ @: > mmap-bmap/$(am__dirstamp)
+mmap-bmap/$(DEPDIR)/$(am__dirstamp):
+ @$(MKDIR_P) mmap-bmap/$(DEPDIR)
+ @: > mmap-bmap/$(DEPDIR)/$(am__dirstamp)
+mmap-bmap/test.$(OBJEXT): mmap-bmap/$(am__dirstamp) \
+ mmap-bmap/$(DEPDIR)/$(am__dirstamp)
+
+mmap-bmap/test$(EXEEXT): $(mmap_bmap_test_OBJECTS) $(mmap_bmap_test_DEPENDENCIES) $(EXTRA_mmap_bmap_test_DEPENDENCIES) mmap-bmap/$(am__dirstamp)
+ @rm -f mmap-bmap/test$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(mmap_bmap_test_OBJECTS) $(mmap_bmap_test_LDADD) $(LIBS)
+mmap-close/$(am__dirstamp):
+ @$(MKDIR_P) mmap-close
+ @: > mmap-close/$(am__dirstamp)
+mmap-close/$(DEPDIR)/$(am__dirstamp):
+ @$(MKDIR_P) mmap-close/$(DEPDIR)
+ @: > mmap-close/$(DEPDIR)/$(am__dirstamp)
+mmap-close/test.$(OBJEXT): mmap-close/$(am__dirstamp) \
+ mmap-close/$(DEPDIR)/$(am__dirstamp)
+
+mmap-close/test$(EXEEXT): $(mmap_close_test_OBJECTS) $(mmap_close_test_DEPENDENCIES) $(EXTRA_mmap_close_test_DEPENDENCIES) mmap-close/$(am__dirstamp)
+ @rm -f mmap-close/test$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(mmap_close_test_OBJECTS) $(mmap_close_test_LDADD) $(LIBS)
+mmap-dir/$(am__dirstamp):
+ @$(MKDIR_P) mmap-dir
+ @: > mmap-dir/$(am__dirstamp)
+mmap-dir/$(DEPDIR)/$(am__dirstamp):
+ @$(MKDIR_P) mmap-dir/$(DEPDIR)
+ @: > mmap-dir/$(DEPDIR)/$(am__dirstamp)
+mmap-dir/test.$(OBJEXT): mmap-dir/$(am__dirstamp) \
+ mmap-dir/$(DEPDIR)/$(am__dirstamp)
+
+mmap-dir/test$(EXEEXT): $(mmap_dir_test_OBJECTS) $(mmap_dir_test_DEPENDENCIES) $(EXTRA_mmap_dir_test_DEPENDENCIES) mmap-dir/$(am__dirstamp)
+ @rm -f mmap-dir/test$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(mmap_dir_test_OBJECTS) $(mmap_dir_test_LDADD) $(LIBS)
+read-dir/$(am__dirstamp):
+ @$(MKDIR_P) read-dir
+ @: > read-dir/$(am__dirstamp)
+read-dir/$(DEPDIR)/$(am__dirstamp):
+ @$(MKDIR_P) read-dir/$(DEPDIR)
+ @: > read-dir/$(DEPDIR)/$(am__dirstamp)
+read-dir/test.$(OBJEXT): read-dir/$(am__dirstamp) \
+ read-dir/$(DEPDIR)/$(am__dirstamp)
+
+read-dir/test$(EXEEXT): $(read_dir_test_OBJECTS) $(read_dir_test_DEPENDENCIES) $(EXTRA_read_dir_test_DEPENDENCIES) read-dir/$(am__dirstamp)
+ @rm -f read-dir/test$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(read_dir_test_OBJECTS) $(read_dir_test_LDADD) $(LIBS)
+trunc-file/$(am__dirstamp):
+ @$(MKDIR_P) trunc-file
+ @: > trunc-file/$(am__dirstamp)
+trunc-file/$(DEPDIR)/$(am__dirstamp):
+ @$(MKDIR_P) trunc-file/$(DEPDIR)
+ @: > trunc-file/$(DEPDIR)/$(am__dirstamp)
+trunc-file/test.$(OBJEXT): trunc-file/$(am__dirstamp) \
+ trunc-file/$(DEPDIR)/$(am__dirstamp)
+
+trunc-file/test$(EXEEXT): $(trunc_file_test_OBJECTS) $(trunc_file_test_DEPENDENCIES) $(EXTRA_trunc_file_test_DEPENDENCIES) trunc-file/$(am__dirstamp)
+ @rm -f trunc-file/test$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(trunc_file_test_OBJECTS) $(trunc_file_test_LDADD) $(LIBS)
+xattr/$(am__dirstamp):
+ @$(MKDIR_P) xattr
+ @: > xattr/$(am__dirstamp)
+xattr/$(DEPDIR)/$(am__dirstamp):
+ @$(MKDIR_P) xattr/$(DEPDIR)
+ @: > xattr/$(DEPDIR)/$(am__dirstamp)
+xattr/test.$(OBJEXT): xattr/$(am__dirstamp) \
+ xattr/$(DEPDIR)/$(am__dirstamp)
+
+xattr/test$(EXEEXT): $(xattr_test_OBJECTS) $(xattr_test_DEPENDENCIES) $(EXTRA_xattr_test_DEPENDENCIES) xattr/$(am__dirstamp)
+ @rm -f xattr/test$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(xattr_test_OBJECTS) $(xattr_test_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+ -rm -f directory-concurrent/*.$(OBJEXT)
+ -rm -f enospc/*.$(OBJEXT)
+ -rm -f extend-file-random/*.$(OBJEXT)
+ -rm -f file-concurrent/*.$(OBJEXT)
+ -rm -f inode-race-stat/*.$(OBJEXT)
+ -rm -f inotify/*.$(OBJEXT)
+ -rm -f llseek/*.$(OBJEXT)
+ -rm -f lp-509180/*.$(OBJEXT)
+ -rm -f lp-524919/*.$(OBJEXT)
+ -rm -f lp-870326/*.$(OBJEXT)
+ -rm -f lp-994247/*.$(OBJEXT)
+ -rm -f miscdev-bad-count/*.$(OBJEXT)
+ -rm -f mmap-bmap/*.$(OBJEXT)
+ -rm -f mmap-close/*.$(OBJEXT)
+ -rm -f mmap-dir/*.$(OBJEXT)
+ -rm -f read-dir/*.$(OBJEXT)
+ -rm -f trunc-file/*.$(OBJEXT)
+ -rm -f xattr/*.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@directory-concurrent/$(DEPDIR)/test.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@enospc/$(DEPDIR)/test.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@extend-file-random/$(DEPDIR)/test.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@file-concurrent/$(DEPDIR)/test.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@inode-race-stat/$(DEPDIR)/test.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@inotify/$(DEPDIR)/test.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@llseek/$(DEPDIR)/test.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@lp-509180/$(DEPDIR)/test.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@lp-524919/$(DEPDIR)/test.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@lp-870326/$(DEPDIR)/test.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@lp-994247/$(DEPDIR)/test.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@miscdev-bad-count/$(DEPDIR)/test.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@mmap-bmap/$(DEPDIR)/test.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@mmap-close/$(DEPDIR)/test.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@mmap-dir/$(DEPDIR)/test.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@read-dir/$(DEPDIR)/test.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@trunc-file/$(DEPDIR)/test.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@xattr/$(DEPDIR)/test.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+ -rm -rf directory-concurrent/.libs directory-concurrent/_libs
+ -rm -rf enospc/.libs enospc/_libs
+ -rm -rf extend-file-random/.libs extend-file-random/_libs
+ -rm -rf file-concurrent/.libs file-concurrent/_libs
+ -rm -rf inode-race-stat/.libs inode-race-stat/_libs
+ -rm -rf inotify/.libs inotify/_libs
+ -rm -rf llseek/.libs llseek/_libs
+ -rm -rf lp-509180/.libs lp-509180/_libs
+ -rm -rf lp-524919/.libs lp-524919/_libs
+ -rm -rf lp-870326/.libs lp-870326/_libs
+ -rm -rf lp-994247/.libs lp-994247/_libs
+ -rm -rf miscdev-bad-count/.libs miscdev-bad-count/_libs
+ -rm -rf mmap-bmap/.libs mmap-bmap/_libs
+ -rm -rf mmap-close/.libs mmap-close/_libs
+ -rm -rf mmap-dir/.libs mmap-dir/_libs
+ -rm -rf read-dir/.libs read-dir/_libs
+ -rm -rf trunc-file/.libs trunc-file/_libs
+ -rm -rf xattr/.libs xattr/_libs
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(PROGRAMS) $(SCRIPTS) $(DATA)
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+ -rm -f directory-concurrent/$(DEPDIR)/$(am__dirstamp)
+ -rm -f directory-concurrent/$(am__dirstamp)
+ -rm -f enospc/$(DEPDIR)/$(am__dirstamp)
+ -rm -f enospc/$(am__dirstamp)
+ -rm -f extend-file-random/$(DEPDIR)/$(am__dirstamp)
+ -rm -f extend-file-random/$(am__dirstamp)
+ -rm -f file-concurrent/$(DEPDIR)/$(am__dirstamp)
+ -rm -f file-concurrent/$(am__dirstamp)
+ -rm -f inode-race-stat/$(DEPDIR)/$(am__dirstamp)
+ -rm -f inode-race-stat/$(am__dirstamp)
+ -rm -f inotify/$(DEPDIR)/$(am__dirstamp)
+ -rm -f inotify/$(am__dirstamp)
+ -rm -f llseek/$(DEPDIR)/$(am__dirstamp)
+ -rm -f llseek/$(am__dirstamp)
+ -rm -f lp-509180/$(DEPDIR)/$(am__dirstamp)
+ -rm -f lp-509180/$(am__dirstamp)
+ -rm -f lp-524919/$(DEPDIR)/$(am__dirstamp)
+ -rm -f lp-524919/$(am__dirstamp)
+ -rm -f lp-870326/$(DEPDIR)/$(am__dirstamp)
+ -rm -f lp-870326/$(am__dirstamp)
+ -rm -f lp-994247/$(DEPDIR)/$(am__dirstamp)
+ -rm -f lp-994247/$(am__dirstamp)
+ -rm -f miscdev-bad-count/$(DEPDIR)/$(am__dirstamp)
+ -rm -f miscdev-bad-count/$(am__dirstamp)
+ -rm -f mmap-bmap/$(DEPDIR)/$(am__dirstamp)
+ -rm -f mmap-bmap/$(am__dirstamp)
+ -rm -f mmap-close/$(DEPDIR)/$(am__dirstamp)
+ -rm -f mmap-close/$(am__dirstamp)
+ -rm -f mmap-dir/$(DEPDIR)/$(am__dirstamp)
+ -rm -f mmap-dir/$(am__dirstamp)
+ -rm -f read-dir/$(DEPDIR)/$(am__dirstamp)
+ -rm -f read-dir/$(am__dirstamp)
+ -rm -f trunc-file/$(DEPDIR)/$(am__dirstamp)
+ -rm -f trunc-file/$(am__dirstamp)
+ -rm -f xattr/$(DEPDIR)/$(am__dirstamp)
+ -rm -f xattr/$(am__dirstamp)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf directory-concurrent/$(DEPDIR) enospc/$(DEPDIR) extend-file-random/$(DEPDIR) file-concurrent/$(DEPDIR) inode-race-stat/$(DEPDIR) inotify/$(DEPDIR) llseek/$(DEPDIR) lp-509180/$(DEPDIR) lp-524919/$(DEPDIR) lp-870326/$(DEPDIR) lp-994247/$(DEPDIR) miscdev-bad-count/$(DEPDIR) mmap-bmap/$(DEPDIR) mmap-close/$(DEPDIR) mmap-dir/$(DEPDIR) read-dir/$(DEPDIR) trunc-file/$(DEPDIR) xattr/$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf directory-concurrent/$(DEPDIR) enospc/$(DEPDIR) extend-file-random/$(DEPDIR) file-concurrent/$(DEPDIR) inode-race-stat/$(DEPDIR) inotify/$(DEPDIR) llseek/$(DEPDIR) lp-509180/$(DEPDIR) lp-524919/$(DEPDIR) lp-870326/$(DEPDIR) lp-994247/$(DEPDIR) miscdev-bad-count/$(DEPDIR) mmap-bmap/$(DEPDIR) mmap-close/$(DEPDIR) mmap-dir/$(DEPDIR) read-dir/$(DEPDIR) trunc-file/$(DEPDIR) xattr/$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-noinstPROGRAMS cscopelist-am ctags \
+ ctags-am distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-pdf install-pdf-am \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags tags-am uninstall uninstall-am
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/tests/kernel/directory-concurrent.sh b/tests/kernel/directory-concurrent.sh
new file mode 100755
index 0000000..9fd7cbf
--- /dev/null
+++ b/tests/kernel/directory-concurrent.sh
@@ -0,0 +1,46 @@
+#!/bin/bash
+#
+# directory-concurrent: mkdir/rmdir race test, multiple processes
+# Author: Colin King <colin.king@canonical.com>
+#
+# Copyright (C) 2012 Canonical, Ltd.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+
+test_script_dir=$(dirname $0)
+rc=1
+test_dir=""
+
+. ${test_script_dir}/../lib/etl_funcs.sh
+
+test_cleanup()
+{
+ etl_remove_test_dir $test_dir
+ etl_umount
+ etl_lumount
+ etl_unlink_keys
+ exit $rc
+}
+trap test_cleanup 0 1 2 3 15
+
+etl_add_keys || exit
+etl_lmount || exit
+etl_mount_i || exit
+test_dir=$(etl_create_test_dir) || exit
+
+${test_script_dir}/directory-concurrent/test ${test_dir}
+
+rc=$?
+exit
diff --git a/tests/kernel/directory-concurrent/test.c b/tests/kernel/directory-concurrent/test.c
new file mode 100644
index 0000000..2759cf6
--- /dev/null
+++ b/tests/kernel/directory-concurrent/test.c
@@ -0,0 +1,287 @@
+/*
+ * Author: Colin King <colin.king@canonical.com>
+ *
+ * Copyright (C) 2012 Canonical, Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/select.h>
+#include <sys/wait.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <signal.h>
+
+#define TEST_PASSED (0)
+#define TEST_FAILED (1)
+#define TEST_ERROR (2)
+
+#define MAX_DIRS (16) /* number of directories to create per iteration */
+#define THREADS_PER_CPU (8) /* number of child processes per CPU */
+
+#define TIMEOUT (30) /* system hang timeout in seconds */
+
+#define TEST_DURATION (60) /* duration of test (seconds) */
+#define MIN_DURATION (1) /* minimum test duration (seconds) */
+
+#define MKDIR (0)
+#define RMDIR (1)
+
+#define DIE_SIGINT (1) /* Kill test threads because of SIGINT */
+#define DIE_COMPLETE (2) /* Kill test threads because end of test duration */
+
+static volatile int die = 0;
+
+/*
+ * Create many threads that try and create mkdir and rmdir races
+ * Aim to load each CPU and create mkdir/rmdir collisions.
+ */
+
+/*
+ * Run mkdir/rmdir as a child and detect any timeouts. This
+ * is a little heavy handed, but allows us to detect kernel
+ * hangs on the mkdir/rmdir syscalls if we lock up.
+ *
+ */
+int hang_check(int option, const char *filename)
+{
+ pid_t pid;
+ struct timeval tv;
+ int ret;
+ int status;
+ int pipefd[2];
+ fd_set readfds;
+
+ tv.tv_sec = TIMEOUT;
+ tv.tv_usec = 0;
+
+ if (pipe(pipefd) < 0) {
+ fprintf(stderr, "pipe error\n");
+ return TEST_ERROR;
+ }
+
+ pid = fork();
+ switch (pid) {
+ case -1:
+ fprintf(stderr, "failed to fork child\n");
+ return TEST_ERROR;
+
+ case 0:
+ /* Child */
+ close(pipefd[0]);
+
+ switch (option) {
+ case MKDIR:
+ mkdir(filename, 0700);
+ break;
+ case RMDIR:
+ rmdir(filename);
+ break;
+ default:
+ break;
+ }
+ if (write(pipefd[1], "EXIT", 4) < 0)
+ fprintf(stderr, "pipe write failed\n");
+
+ close(pipefd[1]);
+ _exit(0);
+ break;
+
+ default:
+ /* Parent */
+ close(pipefd[1]);
+
+ FD_ZERO(&readfds);
+ FD_SET(pipefd[0], &readfds);
+
+ /* parent, sleep until we get a message from the child */
+ ret = select(pipefd[0]+1, &readfds, NULL, NULL, &tv);
+ close(pipefd[0]);
+
+ switch (ret) {
+ case 0:
+ /* Timed out on select, no signal from child! */
+ fprintf(stderr, "Timed out after %d seconds doing %s - possible eCryptfs hang\n",
+ TIMEOUT, option == MKDIR ? "mkdir()" : "rmdir()");
+ /* Vainly attempt to kill child */
+ kill(pid, SIGINT);
+ return TEST_FAILED;
+ case -1:
+ if (errno != EINTR) {
+ fprintf(stderr, "Unexpected return from select(): %d %s\n", errno, strerror(errno));
+ waitpid(pid, &status, 0);
+ return TEST_ERROR;
+ } else {
+ /*
+ * We got sent a signal from controlling process to
+ * tell us to stop, so return TEST_PASSED since we have
+ * not detected any failures from our child
+ */
+ waitpid(pid, &status, 0);
+ return TEST_PASSED;
+ }
+ default:
+ /* Child completed the required operation and wrote down the pipe, lets reap */
+ waitpid(pid, &status, 0);
+ return TEST_PASSED;
+ }
+ }
+}
+
+int test_dirs(const char *path, const int max_dirs)
+{
+ int i;
+ char *filename;
+ size_t len = strlen(path) + 32;
+ int ret = TEST_PASSED;
+
+ if ((filename = malloc(len)) == NULL) {
+ fprintf(stderr, "failed to malloc filename\n");
+ return TEST_ERROR;
+ }
+
+ while (!die) {
+ for (i = 0; i < max_dirs; i++) {
+ snprintf(filename, len, "%s/%d", path, i);
+ if ((ret = hang_check(MKDIR, filename)) != TEST_PASSED) {
+ free(filename);
+ return ret;
+ }
+ }
+
+ for (i = 0; i < max_dirs; i++) {
+ snprintf(filename, len, "%s/%d", path, i);
+ if ((ret = hang_check(RMDIR, filename)) != TEST_PASSED) {
+ free(filename);
+ return ret;
+ }
+ }
+ }
+
+ free(filename);
+
+ if (die & DIE_SIGINT)
+ ret = TEST_ERROR; /* Got aborted */
+
+ return ret;
+}
+
+void sigint_handler(int dummy)
+{
+ die = DIE_SIGINT;
+}
+
+void sigusr1_handler(int dummy)
+{
+ die = DIE_COMPLETE;
+}
+
+int test_exercise(const char *path, const int max_dirs, const int duration)
+{
+ int i;
+ long threads = sysconf(_SC_NPROCESSORS_CONF) * THREADS_PER_CPU;
+ pid_t *pids;
+ int ret = TEST_PASSED;
+
+ if ((pids = calloc(threads, sizeof(pid_t))) == NULL) {
+ fprintf(stderr, "failed to calloc pids\n");
+ return TEST_ERROR;
+ }
+
+ /* Go forth and multiply.. */
+ for (i = 0; i < threads; i++) {
+ pid_t pid;
+
+ pid = fork();
+ switch (pid) {
+ case -1:
+ fprintf(stderr, "failed to fork child %d of %ld\n", i+1, threads);
+ break;
+ case 0:
+ exit(test_dirs(path, max_dirs));
+ default:
+ pids[i] = pid;
+ break;
+ }
+ }
+
+ sleep(duration);
+
+ for (i = 0; i < threads; i++)
+ kill(pids[i], SIGUSR1);
+
+ for (i = 0; i < threads; i++) {
+ int status;
+ waitpid(pids[i], &status, 0);
+
+ if (WEXITSTATUS(status) != TEST_PASSED)
+ ret = WEXITSTATUS(status);
+ }
+
+ free(pids);
+
+ return ret;
+}
+
+void show_usage(char *name)
+{
+ fprintf(stderr, "Syntax: %s [-d duration] pathname\n", name);
+ fprintf(stderr, "\t-d duration of test (in seconds)\n");
+ exit(TEST_ERROR);
+}
+
+int main(int argc, char **argv)
+{
+ int opt;
+ int duration = TEST_DURATION;
+
+ while ((opt = getopt(argc, argv, "d:")) != -1) {
+ switch (opt) {
+ case 'd':
+ duration = atoi(optarg);
+ break;
+ default:
+ show_usage(argv[0]);
+ break;
+ }
+ }
+
+ if (optind >= argc)
+ show_usage(argv[0]);
+
+ if (duration < MIN_DURATION) {
+ fprintf(stderr,
+ "Test duration must be %d or more seconds long.\n",
+ MIN_DURATION);
+ exit(TEST_ERROR);
+ }
+
+ if (access(argv[optind], R_OK | W_OK) < 0) {
+ fprintf(stderr, "Cannot access %s\n", argv[1]);
+ exit(TEST_ERROR);
+ }
+
+ signal(SIGINT, sigint_handler);
+ signal(SIGUSR1, sigusr1_handler);
+
+ exit(test_exercise(argv[optind], MAX_DIRS, duration));
+}
diff --git a/tests/kernel/enospc.sh b/tests/kernel/enospc.sh
new file mode 100755
index 0000000..06b28e1
--- /dev/null
+++ b/tests/kernel/enospc.sh
@@ -0,0 +1,53 @@
+#!/bin/bash
+#
+# extend-file-random: Randomly extend file size, read/write + unlink
+# Author: Colin King <colin.king@canonical.com>
+#
+# Copyright (C) 2012 Canonical, Ltd.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+
+test_script_dir=$(dirname $0)
+rc=1
+test_dir=""
+
+. ${test_script_dir}/../lib/etl_funcs.sh
+
+test_cleanup()
+{
+ etl_remove_test_dir $test_dir
+ etl_umount
+ etl_lumount
+ etl_unlink_keys
+ exit $rc
+}
+trap test_cleanup 0 1 2 3 15
+
+etl_add_keys || exit
+etl_lmount || exit
+etl_mount_i || exit
+test_dir=$(etl_create_test_dir) || exit
+
+#
+# We try to make a file way larger than the number of free blocks
+# to ensure we hit ENOSPC
+#
+blks=$(etl_lmax_filesize)
+blks=$((blks * 5))
+
+${test_script_dir}/enospc/test ${test_dir}/test.img $blks
+
+rc=$?
+exit
diff --git a/tests/kernel/enospc/test.c b/tests/kernel/enospc/test.c
new file mode 100644
index 0000000..f2c3916
--- /dev/null
+++ b/tests/kernel/enospc/test.c
@@ -0,0 +1,94 @@
+/*
+ * Author: Colin King <colin.king@canonical.com>
+ *
+ * Copyright (C) 2012 Canonical, Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <signal.h>
+#include <limits.h>
+#include <inttypes.h>
+
+#define TEST_PASSED (0)
+#define TEST_FAILED (1)
+#define TEST_ERROR (2)
+
+#define BUFF_SZ (65536)
+
+int test_exercise(char *filename, off_t size)
+{
+ int fd;
+ int ret = TEST_FAILED;
+ unsigned char buff[BUFF_SZ];
+
+ unlink(filename);
+ if ((fd = open(filename, O_RDWR | O_CREAT, 0600)) < 0) {
+ fprintf(stderr, "Failed to open %s: %s\n", filename, strerror(errno));
+ return TEST_FAILED;
+ }
+
+ memset(buff, 0, sizeof(buff));
+
+ while (size > 0) {
+ int rc;
+
+ rc = write(fd, buff, (size > BUFF_SZ) ? BUFF_SZ : size);
+ if (rc < 0) {
+ if (errno == ENOSPC)
+ ret = TEST_PASSED;
+ break;
+ }
+ size -= rc;
+ }
+ /* If we got here, we didn't get ENOSPC, so we've failed */
+
+ close(fd);
+ unlink(filename);
+
+ return ret;
+}
+
+void sighandler(int dummy)
+{
+ exit(TEST_ERROR);
+}
+
+int main(int argc, char **argv)
+{
+ off_t len;
+
+ if (argc < 3) {
+ fprintf(stderr, "Syntax: %s filename size_in_K\n", argv[0]);
+ fprintf(stderr, "\tsize must be bigger than available space on the file system\n");
+ exit(TEST_ERROR);
+ }
+
+ len = atoll(argv[2]);
+ if (len < 1) {
+ fprintf(stderr, "size should be > 0\n");
+ exit(TEST_ERROR);
+ }
+
+ signal(SIGINT, sighandler);
+ exit(test_exercise(argv[1], len * 1024));
+}
diff --git a/tests/kernel/extend-file-random.sh b/tests/kernel/extend-file-random.sh
new file mode 100755
index 0000000..5a0a99b
--- /dev/null
+++ b/tests/kernel/extend-file-random.sh
@@ -0,0 +1,47 @@
+#!/bin/bash
+#
+# extend-file-random: Randomly extend file size, read/write + unlink
+# Author: Colin King <colin.king@canonical.com>
+#
+# Copyright (C) 2012 Canonical, Ltd.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+
+test_script_dir=$(dirname $0)
+rc=1
+test_dir=""
+
+. ${test_script_dir}/../lib/etl_funcs.sh
+
+test_cleanup()
+{
+ etl_remove_test_dir $test_dir
+ etl_umount
+ etl_lumount
+ etl_unlink_keys
+ exit $rc
+}
+trap test_cleanup 0 1 2 3 15
+
+etl_add_keys || exit
+etl_lmount || exit
+etl_mount_i || exit
+test_dir=$(etl_create_test_dir) || exit
+blks=$(etl_lmax_filesize)
+
+${test_script_dir}/extend-file-random/test ${test_dir}/test.img $blks
+
+rc=$?
+exit
diff --git a/tests/kernel/extend-file-random/test.c b/tests/kernel/extend-file-random/test.c
new file mode 100644
index 0000000..90793b2
--- /dev/null
+++ b/tests/kernel/extend-file-random/test.c
@@ -0,0 +1,216 @@
+/*
+ * Author: Colin King <colin.king@canonical.com>
+ *
+ * Copyright (C) 2012 Canonical, Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <signal.h>
+#include <inttypes.h>
+
+#define TEST_PASSED (0)
+#define TEST_FAILED (1)
+#define TEST_ERROR (2)
+
+/*
+ * Attempt to create a file with lots of holes, a bit like downloading
+ * an ISO with a torrent client with many multiple random writes
+ */
+#define BUF_SZ 32
+
+#define DEFAULT_SIZE (660*1024) /* CD-ROM Size */
+
+int test_write(int fd, char *buffer, size_t len, off_t offset)
+{
+ ssize_t rc;
+
+ if (lseek(fd, offset, SEEK_SET) < 0) {
+ fprintf(stderr, "Failed to seek to position %jd: %s\n",
+ (intmax_t)offset, strerror(errno));
+ return TEST_FAILED;
+ }
+
+ rc = write(fd, buffer, len);
+ if (rc < 0) {
+ fprintf(stderr, "Failed to write %zu bytes, position %jd: %s\n",
+ len, (intmax_t)offset, strerror(errno));
+ return TEST_FAILED;
+ } else if (((size_t)rc) < len) {
+ fprintf(stderr, "Failed to write %zu bytes, position %jd: short write of %zd bytes\n",
+ len, (intmax_t)offset, rc);
+ return TEST_FAILED;
+ }
+ return TEST_PASSED;
+}
+
+int test_read(int fd, char *buffer, size_t len, off_t offset)
+{
+ ssize_t rc;
+
+ if (lseek(fd, offset, SEEK_SET) < 0) {
+ fprintf(stderr, "Failed to seek to position %jd: %s\n",
+ (intmax_t)offset, strerror(errno));
+ return TEST_FAILED;
+ }
+
+ rc = read(fd, buffer, len);
+ if (rc < 0) {
+ fprintf(stderr, "Failed to read %zu bytes, position %jd: %s\n",
+ len, (intmax_t)offset, strerror(errno));
+ return TEST_FAILED;
+ } else if (((size_t)rc) < len) {
+ fprintf(stderr, "Failed to read %zu bytes, position %jd: short read of %zd bytes\n",
+ len, (intmax_t)offset, rc);
+ return TEST_FAILED;
+ }
+ return TEST_PASSED;
+}
+
+int test_write_read(int fd, char *buffer1, size_t len, off_t offset)
+{
+ char buffer2[BUF_SZ];
+ int ret;
+
+ memset(buffer2, 0, BUF_SZ);
+
+ if ((ret = test_write(fd, buffer1, BUF_SZ, offset)) != 0)
+ return ret;
+
+ if ((ret = test_read(fd, buffer2, BUF_SZ, offset)) != 0)
+ return ret;
+
+ if (memcmp(buffer1, buffer2, BUF_SZ)) {
+ fprintf(stderr, "Data read is not same as data written, offset = %jd",
+ (intmax_t)offset);
+ return TEST_FAILED;
+ }
+ return TEST_PASSED;
+}
+
+int test_exercise(char *filename, off_t max_offset, char data)
+{
+ int fd;
+ int i;
+ int ret = TEST_FAILED;
+ struct stat statbuf;
+
+ char buffer1[BUF_SZ];
+ memset(buffer1, data, BUF_SZ);
+
+ srandom((unsigned int)max_offset);
+
+ unlink(filename);
+ if ((fd = open(filename, O_RDWR | O_CREAT, 0600)) < 0) {
+ fprintf(stderr, "Failed to open %s: %s\n", filename, strerror(errno));
+ return TEST_FAILED;
+ }
+
+ if (test_write_read(fd, buffer1, BUF_SZ, 0))
+ goto finish;
+
+ for (i=0; i<8192; i++) {
+ off_t offset = (off_t)random() % max_offset;
+
+ if (test_write_read(fd, buffer1, BUF_SZ, offset))
+ goto finish;
+ }
+
+ if (test_write_read(fd, buffer1, BUF_SZ, max_offset))
+ goto finish;
+
+ srandom((unsigned int)max_offset);
+ for (i=0; i<8192; i++) {
+ char buffer2[BUF_SZ];
+ off_t offset = (off_t)random() % max_offset;
+
+ if (test_read(fd, buffer2, BUF_SZ, offset))
+ goto finish;
+
+ if (memcmp(buffer1, buffer2, BUF_SZ)) {
+ fprintf(stderr, "Data read is not same as data written, offset = %jd",
+ (intmax_t)offset);
+ goto finish;
+ }
+ }
+
+ if (fstat(fd, &statbuf) < 0) {
+ fprintf(stderr, "Failed to fstat file %s: %s\n", filename, strerror(errno));
+ goto finish;
+ }
+
+ if (statbuf.st_size != max_offset + BUF_SZ) {
+ fprintf(stderr, "Filesize was %jd and not %jd\n",
+ (intmax_t)statbuf.st_size,
+ (intmax_t)(max_offset + BUF_SZ));
+ goto finish;
+ }
+
+ ret = TEST_PASSED;
+finish:
+ if (close(fd) < 0) {
+ fprintf(stderr, "Failed to close %s: %s\n", filename, strerror(errno));
+ return TEST_FAILED;
+ }
+
+ if (unlink(filename) < 0) {
+ fprintf(stderr, "Failed to unlink %s: %s\n", filename, strerror(errno));
+ return TEST_FAILED;
+ }
+
+ return ret;
+}
+
+void sighandler(int dummy)
+{
+ exit(TEST_ERROR);
+}
+
+int main(int argc, char **argv)
+{
+ off_t len = DEFAULT_SIZE;
+ int i;
+ int ret;
+
+ if (argc < 2) {
+ fprintf(stderr, "Syntax: filename [size_in_K]\n");
+ exit(TEST_ERROR);
+ }
+
+ if (argc == 3) {
+ len = atoll(argv[2]);
+ if (len < 1) {
+ fprintf(stderr, "size should be > 0\n");
+ exit(TEST_ERROR);
+ }
+ }
+ len *= 1024;
+
+ signal(SIGINT, sighandler);
+
+ for (i=0; i < 2; i++) {
+ ret = test_exercise(argv[1], len, i + '@');
+ if (ret != TEST_PASSED)
+ exit(ret);
+ }
+ exit(TEST_PASSED);
+}
diff --git a/tests/kernel/file-concurrent.sh b/tests/kernel/file-concurrent.sh
new file mode 100755
index 0000000..51e4ba6
--- /dev/null
+++ b/tests/kernel/file-concurrent.sh
@@ -0,0 +1,46 @@
+#!/bin/bash
+#
+# file-concurrent: creat/trunc/unlink race test, multiple processes
+# Author: Colin King <colin.king@canonical.com>
+#
+# Copyright (C) 2012 Canonical, Ltd.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+
+test_script_dir=$(dirname $0)
+rc=1
+test_dir=""
+
+. ${test_script_dir}/../lib/etl_funcs.sh
+
+test_cleanup()
+{
+ etl_remove_test_dir $test_dir
+ etl_umount
+ etl_lumount
+ etl_unlink_keys
+ exit $rc
+}
+trap test_cleanup 0 1 2 3 15
+
+etl_add_keys || exit
+etl_lmount || exit
+etl_mount_i || exit
+test_dir=$(etl_create_test_dir) || exit
+
+${test_script_dir}/file-concurrent/test ${test_dir}
+
+rc=$?
+exit
diff --git a/tests/kernel/file-concurrent/test.c b/tests/kernel/file-concurrent/test.c
new file mode 100644
index 0000000..deb028b
--- /dev/null
+++ b/tests/kernel/file-concurrent/test.c
@@ -0,0 +1,331 @@
+/*
+ * Author: Colin King <colin.king@canonical.com>
+ *
+ * Copyright (C) 2012 Canonical, Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/select.h>
+#include <sys/wait.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <signal.h>
+
+#define TEST_PASSED (0)
+#define TEST_FAILED (1)
+#define TEST_ERROR (2)
+
+#define MAX_FILES (16) /* number of files to create per iteration */
+#define THREADS_PER_CPU (8) /* number of child processes per CPU */
+
+#define TIMEOUT (30) /* system hang timeout in seconds */
+
+#define TEST_DURATION (60) /* duration of test (seconds) */
+#define MIN_DURATION (1) /* minimum test duration (seconds) */
+
+#define CREAT (0)
+#define TRUNCATE (1)
+#define UNLINK (2)
+#define UNKNOWN (3)
+
+#define DIE_SIGINT (1) /* Kill test threads because of SIGINT */
+#define DIE_COMPLETE (2) /* Kill test threads because end of test duration */
+
+static volatile int die = 0;
+
+static char *options[] = {
+ "creat()",
+ "unlink()",
+ "truncate()",
+ "<unknown>"
+};
+
+/*
+ * Create many threads that try and create create/truncate/unlink aces
+ */
+
+/*
+ * Run creat/tuncate/unlink as a child and detect any timeouts. This
+ * is a little heavy handed, but allows us to detect kernel
+ * hangs on the syscalls if we lock up.
+ *
+ */
+int hang_check(int option, const char *filename)
+{
+ pid_t pid;
+ struct timeval tv;
+ int ret;
+ int status;
+ int pipefd[2];
+ int fd;
+ fd_set readfds;
+
+ tv.tv_sec = TIMEOUT;
+ tv.tv_usec = 0;
+
+ if (pipe(pipefd) < 0) {
+ fprintf(stderr, "pipe error\n");
+ return TEST_ERROR;
+ }
+
+ pid = fork();
+ switch (pid) {
+ case -1:
+ fprintf(stderr, "failed to fork child\n");
+ return TEST_ERROR;
+
+ case 0:
+ /* Child */
+ close(pipefd[0]);
+
+ switch (option) {
+ case CREAT:
+ fd = creat(filename, 0700);
+ if (fd >= 0)
+ close(fd);
+ break;
+
+ case TRUNCATE:
+ /*
+ * We want to try and force a lock up -
+ * we don't care about the return since
+ * the file may not exit, but we assign
+ * ret to keep gcc happy
+ */
+ ret = truncate(filename, 64 * 1024);
+ ret = truncate(filename, 128 * 1024);
+ ret = truncate(filename, 64 * 1024);
+ ret = truncate(filename, 0);
+ ret = truncate(filename, 64 * 1024);
+ break;
+
+ case UNLINK:
+ unlink(filename);
+ break;
+
+ default:
+ break;
+ }
+ if (write(pipefd[1], "EXIT", 4) < 0)
+ fprintf(stderr, "pipe write failed\n");
+
+ close(pipefd[1]);
+ _exit(0);
+ break;
+
+ default:
+ /* Parent */
+ close(pipefd[1]);
+
+ FD_ZERO(&readfds);
+ FD_SET(pipefd[0], &readfds);
+
+ /* parent, sleep until we get a message from the child */
+ ret = select(pipefd[0]+1, &readfds, NULL, NULL, &tv);
+ close(pipefd[0]);
+
+ switch (ret) {
+ case 0:
+ /* Timed out on select, no signal from child! */
+ fprintf(stderr, "Timed out after %d seconds doing %s - possible eCryptfs hang\n",
+ TIMEOUT, options[option > TRUNCATE ? UNKNOWN : option]);
+ /* Vainly attempt to kill child */
+ kill(pid, SIGINT);
+ return TEST_FAILED;
+ case -1:
+ if (errno != EINTR) {
+ fprintf(stderr, "Unexpected return from select(): %d %s\n", errno, strerror(errno));
+ waitpid(pid, &status, 0);
+ return TEST_ERROR;
+ }
+ else {
+ /*
+ * We got sent a signal from controlling process to
+ * tell us to stop, so return TEST_PASSED since we have
+ * not detected any failures from our child
+ */
+ waitpid(pid, &status, 0);
+ return TEST_PASSED;
+ }
+ default:
+ /* Child completed the required operation and wrote down the pipe, lets reap */
+ waitpid(pid, &status, 0);
+ return TEST_PASSED;
+ }
+ }
+}
+
+int test_files(const char *path, const int max_files)
+{
+ int i;
+ char *filename;
+ size_t len = strlen(path) + 32;
+ int ret = TEST_PASSED;
+
+ if ((filename = malloc(len)) == NULL) {
+ fprintf(stderr, "failed to malloc filename\n");
+ return TEST_ERROR;
+ }
+
+ for (;;) {
+ for (i = 0; i < max_files; i++) {
+ snprintf(filename, len, "%s/%d", path, i);
+ if ((ret = hang_check(CREAT, filename)) != TEST_PASSED) {
+ free(filename);
+ return ret;
+ }
+ if (die)
+ goto cleanup;
+ }
+
+ for (i = 0; i < max_files; i++) {
+ snprintf(filename, len, "%s/%d", path, i);
+ if ((ret = hang_check(TRUNCATE, filename)) != TEST_PASSED) {
+ free(filename);
+ return ret;
+ }
+ if (die)
+ goto cleanup;
+ }
+
+cleanup:
+ for (i = 0; i < max_files; i++) {
+ snprintf(filename, len, "%s/%d", path, i);
+ if ((ret = hang_check(UNLINK, filename)) != TEST_PASSED) {
+ free(filename);
+ return ret;
+ }
+ }
+
+ if (die)
+ break;
+ }
+
+ free(filename);
+
+ if (die & DIE_SIGINT)
+ ret = TEST_ERROR; /* Got aborted */
+
+ return ret;
+}
+
+void sigint_handler(int dummy)
+{
+ die = DIE_SIGINT;
+}
+
+void sigusr1_handler(int dummy)
+{
+ die = DIE_COMPLETE;
+}
+
+int test_exercise(const char *path, const int max_files, const int duration)
+{
+ int i;
+ long threads = sysconf(_SC_NPROCESSORS_CONF) * THREADS_PER_CPU;
+ pid_t *pids;
+ int ret = TEST_PASSED;
+
+ if ((pids = calloc(threads, sizeof(pid_t))) == NULL) {
+ fprintf(stderr, "failed to calloc pids\n");
+ return TEST_ERROR;
+ }
+
+ /* Go forth and multiply.. */
+ for (i = 0; i < threads; i++) {
+ pid_t pid;
+
+ pid = fork();
+ switch (pid) {
+ case -1:
+ fprintf(stderr, "failed to fork child %d of %ld\n", i+1, threads);
+ break;
+ case 0:
+ exit(test_files(path, max_files));
+ default:
+ pids[i] = pid;
+ break;
+ }
+ }
+
+ sleep(duration);
+
+ for (i = 0; i < threads; i++)
+ kill(pids[i], SIGUSR1);
+
+ for (i = 0; i < threads; i++) {
+ int status;
+ waitpid(pids[i], &status, 0);
+
+ if (WEXITSTATUS(status) != TEST_PASSED)
+ ret = WEXITSTATUS(status);
+ }
+
+ free(pids);
+
+ return ret;
+}
+
+void show_usage(char *name)
+{
+ fprintf(stderr, "Syntax: %s [-d duration] pathname\n", name);
+ fprintf(stderr, "\t-d duration of test (in seconds)\n");
+ exit(TEST_ERROR);
+}
+
+int main(int argc, char **argv)
+{
+ int opt;
+ int duration = TEST_DURATION;
+
+ while ((opt = getopt(argc, argv, "d:")) != -1) {
+ switch (opt) {
+ case 'd':
+ duration = atoi(optarg);
+ break;
+ default:
+ show_usage(argv[0]);
+ break;
+ }
+ }
+
+ if (optind >= argc)
+ show_usage(argv[0]);
+
+ if (duration < MIN_DURATION) {
+ fprintf(stderr,
+ "Test duration must be %d or more seconds long.\n",
+ MIN_DURATION);
+ exit(TEST_ERROR);
+ }
+
+ if (access(argv[optind], R_OK | W_OK) < 0) {
+ fprintf(stderr, "Cannot access %s\n", argv[1]);
+ exit(TEST_ERROR);
+ }
+
+ signal(SIGINT, sigint_handler);
+ signal(SIGUSR1, sigusr1_handler);
+
+ exit(test_exercise(argv[optind], MAX_FILES, duration));
+}
diff --git a/tests/kernel/inode-race-stat.sh b/tests/kernel/inode-race-stat.sh
new file mode 100755
index 0000000..218b95a
--- /dev/null
+++ b/tests/kernel/inode-race-stat.sh
@@ -0,0 +1,50 @@
+#!/bin/bash
+#
+# inode-race-stat: check for inode race on stat()
+# regression test for https://bugzilla.kernel.org/show_bug.cgi?id=36002
+# commit 3b06b3ebf44170c90c893c6c80916db6e922b9f2
+#
+# Author: Colin King <colin.king@canonical.com>
+#
+# Copyright (C) 2012 Canonical, Ltd.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+
+test_script_dir=$(dirname $0)
+rc=1
+test_dir=""
+test_duration=20
+
+. ${test_script_dir}/../lib/etl_funcs.sh
+
+test_cleanup()
+{
+ etl_remove_test_dir $test_dir
+ etl_umount
+ etl_lumount
+ etl_unlink_keys
+ exit $rc
+}
+trap test_cleanup 0 1 2 3 15
+
+etl_add_keys || exit
+etl_lmount || exit
+etl_mount_i || exit
+test_dir=$(etl_create_test_dir) || exit
+
+${test_script_dir}/inode-race-stat/test -d ${test_duration} ${test_dir}/testfile
+
+rc=$?
+exit
diff --git a/tests/kernel/inode-race-stat/test.c b/tests/kernel/inode-race-stat/test.c
new file mode 100644
index 0000000..58fba99
--- /dev/null
+++ b/tests/kernel/inode-race-stat/test.c
@@ -0,0 +1,374 @@
+/*
+ * Author: Colin King <colin.king@canonical.com>
+ *
+ * Copyright (C) 2012 Canonical, Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/*
+ * Regression test for commit 3b06b3ebf44170c90c893c6c80916db6e922b9f2,
+ * bug https://bugzilla.kernel.org/show_bug.cgi?id=36002
+ *
+ * "Only unlock and d_add() new inodes after the plaintext inode size has
+ * been read from the lower filesystem. This fixes a race condition that
+ * was sometimes seen during a multi-job kernel build in an eCryptfs mount."
+ *
+ * Create file, drop inode cache, and stat file in multiple child processes to
+ * try and catch the inode size race.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <string.h>
+#include <stdint.h>
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <signal.h>
+#include <time.h>
+
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/stat.h>
+
+#define TEST_PASSED (0)
+#define TEST_FAILED (1)
+#define TEST_ERROR (2)
+
+#define THREADS_PER_CPU (16)
+
+#define MAX_CHILD (512) /* Maximum child processes */
+#define MIN_DURATION (10) /* Minimum time to run a test */
+#define TEST_DURATION (20) /* Default test duration in seconds */
+
+#define CHECK_SIZE_FAILED (-2) /* stat failed */
+#define CHECK_SIZE_ERROR (-1) /* stat error */
+#define CHECK_SIZE_PASSED (0) /* stat passed */
+
+#define CMD_QUIT 'q'
+#define CMD_TEST 't'
+#define CMD_PASSED 'p'
+#define CMD_FAILED 'f'
+#define CMD_READ_ERROR 'R'
+#define CMD_STAT_ERROR 'S'
+#define CMD_UNKNOWN_ERROR 'U'
+
+#define WARN_ON_FILE_SIZE_ERROR 0 /* true to report failures to stderr */
+
+static volatile bool keep_running = true;
+
+static int drop_cache(const int val)
+{
+ FILE *fp;
+
+ if ((fp = fopen("/proc/sys/vm/drop_caches", "w")) != NULL) {
+ fprintf(fp, "%d\n", val);
+ fclose(fp);
+ return 0;
+ }
+ return -1;
+}
+
+static int check_size(const char *filename, const off_t size)
+{
+ struct stat statbuf;
+
+ if (stat(filename, &statbuf) < 0) {
+ fprintf(stderr, "stat failed on %s: %s\n",
+ filename, strerror(errno));
+ return CHECK_SIZE_ERROR;
+ }
+ if (statbuf.st_size != size) {
+#if WARN_ON_FILE_SIZE_ERROR
+ fprintf(stderr, "Got incorrect file size: %zd vs %zd\n",
+ statbuf.st_size, size);
+#endif
+ return CHECK_SIZE_FAILED;
+ }
+ return CHECK_SIZE_PASSED;
+}
+
+static void do_test(const int fdin, const int fdout, const char *filename)
+{
+ for (;;) {
+ int n;
+ char cmd[32];
+
+ if ((n = read(fdin, cmd, sizeof(cmd))) < 1) {
+ cmd[0] = CMD_READ_ERROR;
+ if (write(fdout, cmd, 1) < 0)
+ fprintf(stderr, "write to pipe failed: %s\n",
+ strerror(errno));
+ exit(0);
+ }
+ if (cmd[0] == CMD_QUIT) {
+ exit(0);
+ }
+ if (cmd[0] == CMD_TEST) {
+ int ret;
+ off_t sz;
+ sscanf(cmd+1, "%jd", (intmax_t *)&sz);
+
+ ret = check_size(filename, sz);
+ switch (ret) {
+ case CHECK_SIZE_PASSED:
+ cmd[0] = CMD_PASSED;
+ if (write(fdout, cmd, 1) < 0)
+ fprintf(stderr, "write to pipe failed: %s\n",
+ strerror(errno));
+ break;
+ case CHECK_SIZE_ERROR:
+ cmd[0] = CMD_STAT_ERROR;
+ ret = write(fdout, cmd, 1);
+ exit(ret);
+ break;
+ case CHECK_SIZE_FAILED:
+ cmd[0] = CMD_FAILED;
+ ret = write(fdout, cmd, 1);
+ exit(ret);
+ default:
+ cmd[0] = CMD_UNKNOWN_ERROR;
+ ret = write(fdout, cmd, 1);
+ exit(ret);
+ }
+ }
+ }
+}
+
+void sigint_handler(int dummy)
+{
+ keep_running = false;
+}
+
+void show_usage(const char *name)
+{
+ fprintf(stderr, "Syntax: %s [-d duration] filename\n", name);
+ fprintf(stderr, "\t-d duration of test (in seconds)\n");
+ exit(TEST_ERROR);
+}
+
+int main(int argc, char **argv)
+{
+ int fd;
+ int ret = TEST_PASSED;
+ pid_t pids[MAX_CHILD];
+ int pipe_to[MAX_CHILD][2];
+ int pipe_from[MAX_CHILD][2];
+ char cmd[32];
+ char *filename;
+ int i;
+ off_t j;
+ long threads;
+ int duration = TEST_DURATION;
+ int opt;
+ time_t t1, t2;
+ int max_fd;
+ int opened_fd;
+ int max_threads;
+
+ if (geteuid() != 0) {
+ fprintf(stderr, "Need to run with root privilege\n");
+ exit(TEST_ERROR);
+ }
+
+ while ((opt = getopt(argc, argv, "d:")) != -1) {
+ switch (opt) {
+ case 'd':
+ duration = atoi(optarg);
+ break;
+ default:
+ show_usage(argv[0]);
+ break;
+ }
+ }
+
+ if (optind >= argc)
+ show_usage(argv[0]);
+
+ if (duration < MIN_DURATION) {
+ fprintf(stderr,
+ "Test duration must be %d or more seconds long.\n",
+ MIN_DURATION);
+ exit(TEST_ERROR);
+ }
+
+ filename = argv[optind];
+
+ /* Determine how many used file descriptors we have */
+ max_fd = (int)sysconf(_SC_OPEN_MAX);
+ for (i = 0, opened_fd = 0; i < max_fd; i++)
+ if (!fcntl(i, F_GETFD, 0))
+ opened_fd++;
+ /*
+ * Each process takes initially an extra 4 file descriptors
+ * on 2 pipe calls, but after the process has been successfully
+ * forked it closes two file descriptors. So we need 2*N + 2
+ * free file descriptors for N children which limits the
+ * maximum number of processes we can fork.
+ */
+ max_threads = (max_fd - (opened_fd + 2)) / 2;
+ max_threads = max_threads > MAX_CHILD ? MAX_CHILD : max_threads;
+
+ threads = (int)sysconf(_SC_NPROCESSORS_CONF) * THREADS_PER_CPU;
+ threads = threads > max_threads ? max_threads : threads;
+
+ signal(SIGINT, sigint_handler);
+ signal(SIGPIPE, sigint_handler);
+
+ for (i = 0; i < threads; i++) {
+ pid_t pid;
+
+ if (pipe(pipe_to[i]) < 0) {
+ fprintf(stderr, "pipe failed: %s\n", strerror(errno));
+ exit(TEST_ERROR);
+ }
+ if (pipe(pipe_from[i]) < 0) {
+ fprintf(stderr, "pipe failed: %s\n", strerror(errno));
+ exit(TEST_ERROR);
+ }
+
+ pid = fork();
+ switch (pid) {
+ case -1:
+ fprintf(stderr, "fork failed\n");
+ break;
+ case 0:
+ /* child */
+ (void)close(pipe_to[i][1]);
+ (void)close(pipe_from[i][0]);
+
+ do_test(pipe_to[i][0], pipe_from[i][1], filename);
+ _exit(0);
+ default:
+ /* parent */
+ (void)close(pipe_to[i][0]);
+ (void)close(pipe_from[i][1]);
+
+ pids[i] = pid;
+ break;
+ }
+ }
+
+ (void)time(&t1);
+
+ for (j = 0; keep_running; j++) {
+ off_t sz = j & 0xff;
+
+ /* Create a file, of a given size, sync it, drop caches */
+ if ((fd = creat(filename, S_IRUSR | S_IWUSR)) < 0) {
+ fprintf(stderr, "create failed: %s\n", strerror(errno));
+ ret = TEST_ERROR;
+ break;
+ }
+ if (ftruncate(fd, sz) < 0) {
+ fprintf(stderr, "ftruncate failed: %s\n",
+ strerror(errno));
+ ret = TEST_ERROR;
+ break;
+ }
+ if (fdatasync(fd) < 0) {
+ fprintf(stderr, "fdatasync failed: %s\n",
+ strerror(errno));
+ ret = TEST_ERROR;
+ break;
+ }
+ (void)close(fd);
+
+ if (drop_cache(1) < 0) {
+ fprintf(stderr, "could not free pagecache\n");
+ ret = TEST_ERROR;
+ break;
+ }
+ if (drop_cache(2) < 0) {
+ fprintf(stderr, "could free inodes and dentries\n");
+ ret = TEST_ERROR;
+ break;
+ }
+ if (drop_cache(3) < 0) {
+ fprintf(stderr, "could not free page cache, "
+ "inodes and dentries\n");
+ ret = TEST_ERROR;
+ break;
+ }
+
+ /* Now tell children to stat the file */
+ snprintf(cmd, sizeof(cmd), "%c%jd", CMD_TEST, (intmax_t)sz);
+ for (i = 0; i < threads; i++) {
+ if (write(pipe_to[i][1], cmd, strlen(cmd)+1) < 0) {
+ fprintf(stderr, "write to pipe failed: %s\n",
+ strerror(errno));
+ ret = TEST_ERROR;
+ break;
+ }
+ }
+
+ /* And check if it was OK */
+ for (i = 0; i < threads; i++) {
+ int n;
+
+ memset(cmd, 0, sizeof(cmd));
+ if ((n = read(pipe_from[i][0], cmd, 1)) < 0) {
+ fprintf(stderr, "read from pipe failed: %s\n",
+ strerror(errno));
+ ret = TEST_ERROR;
+ break;
+ }
+ if (n < 1) {
+ fprintf(stderr, "expecting data from pipe\n");
+ ret = TEST_ERROR;
+ break;
+ }
+
+ switch (cmd[0]) {
+ case CMD_PASSED:
+ break;
+ case CMD_FAILED:
+ ret = TEST_FAILED;
+ goto abort;
+ default:
+ ret = TEST_ERROR;
+ goto abort;
+ }
+ }
+
+ (void)time(&t2);
+
+ if (difftime(t2, t1) > (double)duration)
+ break;
+ }
+
+abort:
+ (void)unlink(filename);
+
+ if (!keep_running)
+ ret = TEST_ERROR; /* User aborted! */
+
+ cmd[0] = CMD_QUIT;
+ for (i = 0; i < threads; i++) {
+ int status;
+
+ if (write(pipe_to[i][1], cmd, 1) != 1)
+ continue;
+ (void)waitpid(pids[i], &status, 0);
+
+ (void)close(pipe_to[i][1]);
+ (void)close(pipe_from[i][0]);
+ }
+
+ exit(ret);
+}
diff --git a/tests/kernel/inotify.sh b/tests/kernel/inotify.sh
new file mode 100755
index 0000000..7d13887
--- /dev/null
+++ b/tests/kernel/inotify.sh
@@ -0,0 +1,46 @@
+#!/bin/bash
+#
+# inotify: inotify test
+# Author: Colin King <colin.king@canonical.com>
+#
+# Copyright (C) 2012 Canonical, Ltd.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+
+test_script_dir=$(dirname $0)
+rc=1
+test_dir=""
+
+. ${test_script_dir}/../lib/etl_funcs.sh
+
+test_cleanup()
+{
+ etl_remove_test_dir $test_dir
+ etl_umount
+ etl_lumount
+ etl_unlink_keys
+ exit $rc
+}
+trap test_cleanup 0 1 2 3 15
+
+etl_add_keys || exit
+etl_lmount || exit
+etl_mount_i || exit
+test_dir=$(etl_create_test_dir) || exit
+
+${test_script_dir}/inotify/test ${test_dir}
+
+rc=$?
+exit
diff --git a/tests/kernel/inotify/test.c b/tests/kernel/inotify/test.c
new file mode 100644
index 0000000..9f61449
--- /dev/null
+++ b/tests/kernel/inotify/test.c
@@ -0,0 +1,659 @@
+/*
+ * Author: Colin King <colin.king@canonical.com>
+ *
+ * Copyright (C) 2012 Canonical, Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <string.h>
+#include <limits.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/select.h>
+#include <sys/inotify.h>
+
+#define TEST_PASSED (0)
+#define TEST_FAILED (1)
+#define TEST_ERROR (2)
+
+#define DIR_FLAGS (S_IRWXU | S_IRWXG)
+#define FILE_FLAGS (S_IRUSR | S_IWUSR)
+
+#define TIME_OUT (15) /* Duration in secs for inotify to report something */
+#define BUF_SIZE (4096)
+#define MOVE_PATH "/tmp/test_file"
+
+typedef int (*test_helper)(char *path, void *private);
+typedef int (*test_func)(char *path);
+
+#define flags_check(buf, flags, flag) \
+ if (flags & flag) \
+ flags_add(buf, #flag)
+
+void flags_add(char *buff, char *flagstr)
+{
+ if (*buff == '\0') {
+ strcpy(buff, flagstr);
+ } else {
+ strcat(buff, " ");
+ strcat(buff, flagstr);
+ }
+}
+
+/*
+ * flags_to_str()
+ * convert inotify flags to human readable form
+ */
+char *flags_to_str(int flags)
+{
+ static char buf[4096];
+
+ *buf = '\0';
+
+ flags_check(buf, flags, IN_ACCESS);
+ flags_check(buf, flags, IN_MODIFY);
+ flags_check(buf, flags, IN_ATTRIB);
+ flags_check(buf, flags, IN_CLOSE_WRITE);
+ flags_check(buf, flags, IN_CLOSE_NOWRITE);
+ flags_check(buf, flags, IN_OPEN);
+ flags_check(buf, flags, IN_MOVED_FROM);
+ flags_check(buf, flags, IN_MOVED_TO);
+ flags_check(buf, flags, IN_CREATE);
+ flags_check(buf, flags, IN_DELETE);
+ flags_check(buf, flags, IN_DELETE_SELF);
+ flags_check(buf, flags, IN_MOVE_SELF);
+ flags_check(buf, flags, IN_UNMOUNT);
+
+ return buf;
+}
+
+
+/*
+ * test_inotify()
+ * run a given test helper function 'func' and see if this triggers the
+ * required inotify event flags 'flags'. Return TEST_FAILED if inotify()
+ * fails to work or match the require flags, TEST_ERROR if something went
+ * horribly wrong, or TEST_PASSED if it worked as expected
+ */
+int test_inotify(char *filename,/* Filename in test */
+ char *watchname, /* File or directory to watch using inotify */
+ char *matchname, /* Filename we expect inotify event to report */
+ test_helper func, /* Helper func */
+ int flags, /* IN_* flags to watch for */
+ void *private) /* Helper func private data */
+{
+ int len;
+ int fd;
+ int wd;
+ int ret = 0;
+ char buffer[1024];
+ int check_flags = flags;
+ int ignored = 0;
+
+ if ((fd = inotify_init()) < 0) {
+ fprintf(stderr, "inotify_init failed: %s", strerror(errno));
+ return TEST_FAILED;
+ }
+
+ if ((wd = inotify_add_watch(fd, watchname, flags)) < 0) {
+ close(fd);
+ fprintf(stderr, "inotify_add_watch failed: %s", strerror(errno));
+ return TEST_FAILED;
+ }
+
+ if (func(filename, private) < 0) {
+ close(fd);
+ return TEST_ERROR;
+ }
+
+ while (check_flags) {
+ int i = 0;
+ struct timeval tv;
+ fd_set rfds;
+ int err;
+
+ /* We give inotify TIME_OUT seconds to report back */
+ tv.tv_sec = TIME_OUT;
+ tv.tv_usec = 0;
+
+ FD_ZERO(&rfds);
+ FD_SET(fd, &rfds);
+
+ /* Wait for an inotify event ... */
+ err = select(fd + 1, &rfds, NULL, NULL, &tv);
+ if (err == -1) {
+ fprintf(stderr, "Select error: %s\n", strerror(errno));
+ ret = TEST_FAILED;
+ break;
+ } else if (err == 0) {
+ fprintf(stderr, "Timeout waiting for event flags 0x%x (%s)\n", flags, flags_to_str(flags));
+ ret = TEST_FAILED;
+ break;
+ }
+
+ if ((len = read(fd, buffer, sizeof(buffer))) < 0) {
+ fprintf(stderr, "Error reading inotify fd: %s\n", strerror(errno));
+ ret = TEST_FAILED;
+ break;
+ }
+
+ /* Scan through inotify events */
+ while (i < len) {
+ int f;
+ struct inotify_event *event = (struct inotify_event *)&buffer[i];
+
+ /*
+ * IN_IGNORED indicates the watch file/dir was removed and
+ * a side effect is that the kernel removes the watch so
+ * we shouldn't use inotify_rm_watch to reap this later
+ */
+ if (event->mask & IN_IGNORED)
+ ignored = 1;
+
+ f = event->mask & (IN_DELETE_SELF | IN_MOVE_SELF |
+ IN_MOVED_TO | IN_MOVED_FROM | IN_ATTRIB);
+
+ if (event->len &&
+ strcmp(event->name, matchname) == 0 &&
+ flags & event->mask)
+ check_flags &= ~(flags & event->mask);
+ else if (flags & f)
+ check_flags &= ~(flags & event->mask);
+
+ i += sizeof(struct inotify_event) + event->len;
+ }
+ }
+
+ /* Note: EINVAL happens if the watched file itself is deleted */
+ if (!ignored)
+ inotify_rm_watch(fd, wd);
+ close(fd);
+
+ return ret;
+}
+
+
+/*
+ * mk_filename()
+ * simple helper to create a filename
+ */
+inline void mk_filename(char *filename, size_t len, const char *path, const char *name)
+{
+ snprintf(filename, len, "%s/%s", path, name);
+}
+
+/*
+ * mk_file()
+ * create file of length sz bytes
+ */
+int mk_file(char *filename, size_t sz)
+{
+ int fd;
+
+ char buffer[BUF_SIZE];
+
+ (void)unlink(filename);
+
+ if ((fd = open(filename, O_CREAT | O_RDWR, FILE_FLAGS)) < 0) {
+ fprintf(stderr, "Cannot create %s: %s\n", filename, strerror(errno));
+ return -1;
+ }
+
+ memset(buffer, 'x', BUF_SIZE);
+
+ while (sz > 0) {
+ size_t n = (sz > BUF_SIZE) ? BUF_SIZE : sz;
+ int ret;
+
+ if ((ret = write(fd, buffer, n)) < 0) {
+ fprintf(stderr, "Error writing to file %s: %s\n",
+ filename, strerror(errno));
+ close(fd);
+ return -1;
+ }
+ sz -= ret;
+ }
+
+ if (close(fd) < 0) {
+ fprintf(stderr, "Cannot close %s: %s\n", filename, strerror(errno));
+ return -1;
+ }
+
+ return 0;
+}
+
+
+int test_attrib_helper(char *path, void *dummy)
+{
+ if (chmod(path, S_IRUSR | S_IWUSR) < 0) {
+ fprintf(stderr, "Cannot chmod %s: %s\n", path, strerror(errno));
+ return -1;
+ }
+ return 0;
+}
+
+int test_attrib_file(char *path)
+{
+ char filepath[PATH_MAX];
+ int ret;
+
+ mk_filename(filepath, PATH_MAX, path, "test_file");
+ if (mk_file(filepath, 4096) < 0)
+ return TEST_ERROR;
+
+ ret = test_inotify(filepath, path, "test_file", test_attrib_helper, IN_ATTRIB, NULL);
+ unlink(filepath);
+
+ return ret;
+}
+
+int test_access_helper(char *path, void *dummy)
+{
+ int fd;
+ char buffer[1];
+ int rc = 0;
+
+ if ((fd = open(path, O_RDONLY)) < 0) {
+ fprintf(stderr, "Cannot open %s: %s\n", path, strerror(errno));
+ return -1;
+ }
+
+ /* Just want to force an access */
+ if (read(fd, buffer, 1) < 0) {
+ fprintf(stderr, "Cannot read %s: %s\n", path, strerror(errno));
+ rc = -1;
+ }
+
+ close(fd);
+
+ return rc;
+}
+
+int test_access_file(char *path)
+{
+ char filepath[PATH_MAX];
+ int ret;
+
+ mk_filename(filepath, PATH_MAX, path, "test_file");
+ if (mk_file(filepath, 4096) < 0)
+ return TEST_ERROR;
+
+ ret = test_inotify(filepath, path, "test_file", test_access_helper, IN_ACCESS, NULL);
+ (void)unlink(filepath);
+
+ return ret;
+}
+
+int test_modify_helper(char *path, void *dummy)
+{
+ int fd;
+ char buffer[1] = { 0 };
+ int rc = 0;
+
+ if (mk_file(path, 4096) < 0)
+ return -1;
+
+ if ((fd = open(path, O_RDWR)) < 0) {
+ fprintf(stderr, "Cannot open %s: %s\n", path, strerror(errno));
+ rc = -1;
+ goto remove;
+ }
+
+ if (write(fd, buffer, 1) < 0) {
+ fprintf(stderr, "Cannot write %s: %s\n", path, strerror(errno));
+ rc = -1;
+ }
+
+ close(fd);
+remove:
+ (void)unlink(path);
+ return rc;
+}
+
+int test_modify_file(char *path)
+{
+ char filepath[PATH_MAX];
+
+ mk_filename(filepath, PATH_MAX, path, "test_file");
+
+ return test_inotify(filepath, path, "test_file", test_modify_helper, IN_MODIFY, NULL);
+}
+
+int test_creat_helper(char *path, void *dummy)
+{
+ if (creat(path, FILE_FLAGS) < 0) {
+ fprintf(stderr, "Cannot creat %s: %s\n", path, strerror(errno));
+ return -1;
+ }
+ return 0;
+}
+
+int test_creat_file(char *path)
+{
+ char filepath[PATH_MAX];
+ int ret;
+
+ mk_filename(filepath, PATH_MAX, path, "test_file");
+
+ ret = test_inotify(filepath, path, "test_file", test_creat_helper, IN_CREATE, NULL);
+ unlink(filepath);
+ return ret;
+}
+
+int test_open_helper(char *path, void *dummy)
+{
+ int fd;
+
+ if ((fd = open(path, O_RDONLY)) < 0) {
+ fprintf(stderr, "Cannot open %s: %s\n", path, strerror(errno));
+ return -1;
+ }
+ close(fd);
+ return 0;
+}
+
+int test_open_file(char *path)
+{
+ char filepath[PATH_MAX];
+ int ret;
+
+ mk_filename(filepath, PATH_MAX, path, "test_file");
+ if (mk_file(filepath, 4096) < 0)
+ return TEST_ERROR;
+
+ ret = test_inotify(filepath, path, "test_file", test_open_helper, IN_OPEN, NULL);
+ (void)unlink(filepath);
+ return ret;
+}
+
+
+int test_delete_helper(char *path, void *dummy)
+{
+ if (unlink(path) < 0) {
+ fprintf(stderr, "Cannot unlink %s: %s\n", path, strerror(errno));
+ return -1;
+ }
+ return 0;
+}
+
+int test_delete_file(char *path)
+{
+ char filepath[PATH_MAX];
+ int ret;
+
+ mk_filename(filepath, PATH_MAX, path, "test_file");
+ if (mk_file(filepath, 4096) < 0)
+ return TEST_ERROR;
+
+ ret = test_inotify(filepath, path, "test_file", test_delete_helper, IN_DELETE, NULL);
+
+ /* We remove (again) it just in case the test failed */
+ (void)unlink(filepath);
+ return ret;
+}
+
+int test_delete_self_helper(char *path, void *dummy)
+{
+ if (rmdir(path) < 0) {
+ fprintf(stderr, "Cannot rmdir %s: %s\n", path, strerror(errno));
+ return -1;
+ }
+ return 0;
+}
+
+int test_delete_self(char *path)
+{
+ char filepath[PATH_MAX];
+ int ret;
+
+ mk_filename(filepath, PATH_MAX, path, "test_dir");
+ if (mkdir(filepath, DIR_FLAGS) < 0)
+ return TEST_ERROR;
+
+ ret = test_inotify(filepath, filepath, "test_dir", test_delete_self_helper, IN_DELETE_SELF, NULL);
+ /* We remove (again) in case the test failed */
+ (void)rmdir(filepath);
+
+ return ret;
+}
+
+int test_move_self_helper(char *oldpath, void *private)
+{
+ char *newpath = (char*)private;
+
+ if (rename(oldpath, newpath) < 0) {
+ fprintf(stderr, "Cannot rename %s to %s: %s\n",
+ oldpath, newpath, strerror(errno));
+ return -1;
+ }
+ return 0;
+}
+
+int test_move_self(char *path)
+{
+ char filepath[PATH_MAX];
+ char newpath[PATH_MAX];
+ int ret;
+
+ mk_filename(filepath, PATH_MAX, path, "test_dir");
+ if (mkdir(filepath, DIR_FLAGS) < 0) {
+ fprintf(stderr, "Cannot mkdir %s: %s\n", filepath, strerror(errno));
+ return TEST_ERROR;
+ }
+ mk_filename(newpath, PATH_MAX, path, "renamed_dir");
+
+ ret = test_inotify(filepath, filepath, "test_dir", test_move_self_helper, IN_MOVE_SELF, newpath);
+ (void)rmdir(newpath);
+
+ return ret;
+}
+
+int test_moved_to_helper(char *newpath, void *private)
+{
+ char *oldpath = (char*)private;
+
+ if (rename(oldpath, newpath) < 0) {
+ fprintf(stderr, "Cannot rename %s to %s: %s\n",
+ oldpath, newpath, strerror(errno));
+ return -1;
+ }
+ return 0;
+}
+
+int test_moved_to(char *path)
+{
+ char olddir[PATH_MAX];
+ char oldfile[PATH_MAX];
+ char newfile[PATH_MAX];
+ int ret;
+
+ mk_filename(olddir, PATH_MAX, path, "new_dir");
+ (void)rmdir(olddir);
+ if (mkdir(olddir, DIR_FLAGS) < 0) {
+ fprintf(stderr, "Cannot create directory %s: %s\n", olddir, strerror(errno));
+ return TEST_ERROR;
+ }
+ mk_filename(oldfile, PATH_MAX, olddir, "test_file");
+ if (mk_file(oldfile, 4096) < 0)
+ return TEST_ERROR;
+
+ mk_filename(newfile, PATH_MAX, path, "test_file");
+
+ ret = test_inotify(newfile, path, "test_dir", test_moved_to_helper, IN_MOVED_TO, oldfile);
+ (void)rmdir(olddir);
+ (void)unlink(newfile);
+
+ return ret;
+}
+
+int test_moved_from_helper(char *oldpath, void *private)
+{
+ char *newpath = (char*)private;
+
+ if (rename(oldpath, newpath) < 0) {
+ fprintf(stderr, "Cannot rename %s to %s: %s\n",
+ oldpath, MOVE_PATH, strerror(errno));
+ return -1;
+ }
+ return 0;
+}
+
+int test_moved_from(char *path)
+{
+ char oldfile[PATH_MAX];
+ char newdir[PATH_MAX];
+ char newfile[PATH_MAX];
+ int ret;
+
+ mk_filename(oldfile, PATH_MAX, path, "test_file");
+ if (mk_file(oldfile, 4096) < 0)
+ return TEST_ERROR;
+ mk_filename(newdir, PATH_MAX, path, "new_dir");
+ (void)rmdir(newdir);
+ if (mkdir(newdir, DIR_FLAGS) < 0) {
+ fprintf(stderr, "Cannot create directory %s: %s\n", newdir, strerror(errno));
+ return TEST_ERROR;
+ }
+ mk_filename(newfile, PATH_MAX, newdir, "test_file");
+
+ ret = test_inotify(oldfile, path, "test_dir", test_moved_from_helper, IN_MOVED_FROM, newfile);
+ unlink(newfile);
+ (void)rmdir(newdir);
+
+ return ret;
+}
+
+int test_close_write_helper(char *path, void *fdptr)
+{
+ int fd = *(int*)fdptr;
+
+ (void)close(fd);
+
+ return 0;
+}
+
+int test_close_write_file(char *path)
+{
+ char filepath[PATH_MAX];
+ int fd;
+ int ret;
+
+ mk_filename(filepath, PATH_MAX, path, "test_file");
+ if (mk_file(filepath, 4096) < 0)
+ return -1;
+
+ if ((fd = open(filepath, O_RDWR)) < 0) {
+ fprintf(stderr, "Cannot re-open %s: %s\n", filepath, strerror(errno));
+ return -1;
+ }
+
+ ret = test_inotify(filepath, path, "test_file", test_close_write_helper, IN_CLOSE_WRITE, (void*)&fd);
+ (void)unlink(filepath);
+
+ return ret;
+}
+
+int test_close_nowrite_helper(char *path, void *fdptr)
+{
+ int fd = *(int*)fdptr;
+
+ (void)close(fd);
+
+ return 0;
+}
+
+int test_close_nowrite_file(char *path)
+{
+ char filepath[PATH_MAX];
+ int fd;
+ int ret;
+
+ mk_filename(filepath, PATH_MAX, path, "test_file");
+ if (mk_file(filepath, 4096) < 0)
+ return TEST_ERROR;
+
+ if ((fd = open(filepath, O_RDONLY)) < 0) {
+ fprintf(stderr, "Cannot re-open %s: %s\n", filepath, strerror(errno));
+ (void)unlink(filepath);
+ return TEST_ERROR;
+ }
+
+ ret = test_inotify(filepath, path, "test_file", test_close_nowrite_helper, IN_CLOSE_NOWRITE, (void*)&fd);
+ (void)unlink(filepath);
+
+ return ret;
+}
+
+struct {
+ test_func func;
+ char* description;
+} inotify_test[] = {
+ { test_access_file, "IN_ACCESS" },
+ { test_modify_file, "IN_MODIFY" },
+ { test_attrib_file, "IN_ATTRIB" },
+ { test_close_write_file, "IN_CLOSE_WRITE" },
+ { test_close_nowrite_file, "IN_CLOSE_NOWRITE" },
+ { test_open_file, "IN_OPEN" },
+ { test_moved_from, "IN_MOVED_FROM" },
+ { test_moved_to, "IN_MOVED_TO" },
+ { test_creat_file, "IN_CREATE" },
+ { test_delete_file, "IN_DELETE" },
+ { test_delete_self, "IN_DELETE_SELF" },
+ { test_move_self, "IN_MOVE_SELF" },
+ { NULL, NULL }
+};
+
+int main(int argc, char **argv)
+{
+ int i;
+ int test_failed = 0;
+
+ if (argc < 2) {
+ fprintf(stderr, "Usage: %s path\n", argv[0]);
+ fprintf(stderr, "\twhere path is the path to run the inotify file tests in\n");
+ exit(TEST_ERROR);
+ }
+
+ if (mkdir(argv[1], DIR_FLAGS) < 0) {
+ if (errno != EEXIST) {
+ fprintf(stderr, "Cannot create directory %s\n", argv[1]);
+ exit(TEST_ERROR);
+ }
+ }
+
+ for (i=0; inotify_test[i].func; i++) {
+ int ret = inotify_test[i].func(argv[1]);
+ /* Something went horribly wrong, bail out early */
+ if (ret == TEST_ERROR) {
+ printf("%s test encounted an error\n", inotify_test[i].description);
+ exit(TEST_ERROR);
+ }
+
+ if (ret == TEST_FAILED) {
+ test_failed++;
+ }
+
+ }
+
+ (void)rmdir(argv[1]);
+
+ exit(test_failed ? TEST_FAILED : TEST_PASSED);
+}
diff --git a/tests/kernel/link.sh b/tests/kernel/link.sh
new file mode 100755
index 0000000..e344e69
--- /dev/null
+++ b/tests/kernel/link.sh
@@ -0,0 +1,83 @@
+#!/bin/bash
+#
+# link.sh : Simple hard link sanity check
+#
+# Author: Colin Ian King <colin.king@canonical.com>
+#
+# Copyright (C) 2013 Canonical Ltd.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation version 2
+# of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+
+test_script_dir=$(dirname $0)
+rc=1
+test_dir=0
+
+. ${test_script_dir}/../lib/etl_funcs.sh
+
+test_cleanup()
+{
+ etl_remove_test_dir $test_dir
+ etl_umount
+ etl_lumount
+ etl_unlink_keys
+ exit $rc
+}
+trap test_cleanup 0 1 2 3 15
+
+# TEST
+etl_add_keys || exit
+etl_lmount || exit
+etl_mount_i || exit
+test_dir=$(etl_create_test_dir) || exit
+test_file1="${test_dir}/test1"
+test_file2="${test_dir}/test2"
+
+echo "Testing 1 2 3" > $test_file1
+
+ln $test_file1 $test_file2
+
+rc=0
+#
+# Contents should be the same
+#
+diff $test_file1 $test_file2 > /dev/null 2>&1
+if [ $? -ne 0 ]; then
+ rc=1
+fi
+
+#
+# Size should be the same
+#
+test_file1_size=$(stat -c%s $test_file1)
+test_file2_size=$(stat -c%s $test_file2)
+if [ $test_file1_size -ne $test_file2_size ]; then
+ rc=1
+fi
+
+#
+# Link count should be 2 for both
+#
+test_file1_links=$(stat -c%h $test_file1)
+test_file2_links=$(stat -c%h $test_file2)
+if [ $test_file1_links -ne 2 -a $test_file2_links -ne 2 ]; then
+ rc=1
+fi
+
+rm -f $test_file1 $test_file2
+
+etl_umount || exit
+etl_mount_i || exit
+
+exit
diff --git a/tests/kernel/llseek.sh b/tests/kernel/llseek.sh
new file mode 100755
index 0000000..89deb01
--- /dev/null
+++ b/tests/kernel/llseek.sh
@@ -0,0 +1,45 @@
+#!/bin/bash
+#
+# llseek: Test for llseek operations
+# Author: Tyler Hicks <tyhicks@canonical.com>
+#
+# Copyright (C) 2012 Canonical Ltd.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation version 2
+# of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+
+test_script_dir=$(dirname $0)
+rc=1
+
+. ${test_script_dir}/../lib/etl_funcs.sh
+
+test_cleanup()
+{
+ etl_remove_test_dir $test_dir
+ etl_umount
+ etl_lumount
+ etl_unlink_keys
+ exit $rc
+}
+trap test_cleanup 0 1 2 3 15
+
+etl_add_keys || exit
+etl_lmount || exit
+etl_mount_i || exit
+test_dir=$(etl_create_test_dir) || exit
+path="${test_dir}/foo"
+
+${test_script_dir}/llseek/test ${path}
+rc=$?
+exit
diff --git a/tests/kernel/llseek/test.c b/tests/kernel/llseek/test.c
new file mode 100644
index 0000000..5c8c1bd
--- /dev/null
+++ b/tests/kernel/llseek/test.c
@@ -0,0 +1,253 @@
+/**
+ * Author: Michael Halcrow
+ *
+ * Copyright (C) IBM
+ *
+ * Modified by Tyler Hicks <tyhicks@canonical.com> to fit into the eCryptfs
+ * test modern framework.
+ */
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+#include <inttypes.h>
+
+int main(int argc, char *argv[])
+{
+ off_t size;
+ int fd;
+ struct stat s;
+ uint32_t deadbeef = 0xdeadbeef;
+ uint32_t baadf00d = 0xbaadf00d;
+ char *path;
+ char buf[4096];
+ int i;
+ int rc;
+
+ if (argc != 2) {
+ fprintf(stderr, "Usage: %s path\n", argv[0]);
+ exit(1);
+ }
+ path = argv[1];
+
+ /* Verifying that lseek() doesn't change the file size */
+ fd = open(path, (O_CREAT | O_EXCL| O_WRONLY), S_IRUSR | S_IWUSR);
+ if (fd == -1) {
+ fprintf(stderr, "Error attempting to create new file [%s]\n",
+ path);
+ rc = 1;
+ goto out;
+ }
+ size = lseek(fd, 4096, SEEK_END);
+ if (size != 4096) {
+ fprintf(stderr, "Expected 4096 from lseek; got [%jd]\n",
+ (intmax_t)size);
+ rc = 1;
+ goto out;
+ }
+ close(fd);
+ rc = stat(path, &s);
+ if (rc == -1) {
+ fprintf(stderr, "Error attempting to stat file [%s]\n",
+ path);
+ rc = 1;
+ goto out;
+ }
+ if (s.st_size != 0) {
+ fprintf(stderr, "Filesize is [%jd]; expected 0\n",
+ (intmax_t)s.st_size);
+ rc = 1;
+ goto out;
+ }
+ unlink(path);
+
+ /**
+ * Verifying that intermediate regions of the file are initialized to 0
+ * on lseek() and write() events\n;
+ */
+ fd = open(path, (O_CREAT | O_EXCL| O_RDWR), S_IRWXU);
+ if (fd == -1) {
+ fprintf(stderr, "Error attempting to create new file [%s]\n",
+ path);
+ rc = 1;
+ goto out;
+ }
+ if ((size = lseek(fd, 4096, SEEK_END)) != 4096) {
+ fprintf(stderr, "Expected 4096 from lseek; got [%jd]\n",
+ (intmax_t)size);
+ rc = 1;
+ goto out;
+ }
+ if ((size = write(fd, (char *)&deadbeef, 4)) != 4) {
+ fprintf(stderr, "Expected a write of 4 bytes; got [%jd] "
+ "instead\n", (intmax_t)size);
+ rc = 1;
+ goto out;
+ }
+ if ((size = lseek(fd, 5120, SEEK_SET)) != 5120) {
+ fprintf(stderr, "Expected 5120 from lseek; got [%jd]\n",
+ (intmax_t)size);
+ rc = 1;
+ goto out;
+ }
+ if ((size = write(fd, (char *)&baadf00d, 4)) != 4) {
+ fprintf(stderr, "Expected a write of 4 bytes; got [%jd] "
+ "instead\n", (intmax_t)size);
+ rc = 1;
+ goto out;
+ }
+ if ((size = lseek(fd, 4096, SEEK_SET)) != 4096) {
+ fprintf(stderr, "Expected 4096 from lseek; got [%jd]\n",
+ (intmax_t)size);
+ rc = 1;
+ goto out;
+ }
+ if ((size = read(fd, buf, 4)) != 4) {
+ fprintf(stderr, "Error attempting to read data. Expected "
+ "[%d] bytes; read [%jd] instead\n", 4, (intmax_t)size);
+ rc = 1;
+ goto out;
+ }
+ if (memcmp((char *)&deadbeef, buf, 4) != 0) {
+ fprintf(stderr, "deadbeef data mismatch on initial write\n");
+ rc = 1;
+ goto out;
+ }
+ if ((size = read(fd, buf, 1020)) != 1020) {
+ fprintf(stderr, "Error attempting to read data. Expected "
+ "[%d] bytes; read [%jd] instead\n", 1020,
+ (intmax_t)size);
+ rc = 1;
+ goto out;
+ }
+ for (i = 0; i < 1020; i++)
+ if (buf[i] != 0x00) {
+ fprintf(stderr, "Byte [%d] is [0x%.2x]; expected "
+ "[0x00]\n", i, buf[i]);
+ rc = 1;
+ goto out;
+ }
+ if ((size = read(fd, buf, 4)) != 4) {
+ fprintf(stderr, "Error attempting to read data. Expected "
+ "[%d] bytes; read [%jd] instead\n", 4, (intmax_t)size);
+ rc = 1;
+ goto out;
+ }
+ if (memcmp((char *)&baadf00d, buf, 4) != 0) {
+ fprintf(stderr, "baadf00d data mismatch on initial write\n");
+ rc = 1;
+ goto out;
+ }
+ if ((size = read(fd, buf, 1)) != 0) {
+ fprintf(stderr, "Error attempting to read data. Expected "
+ "[%d] bytes; read [%jd] instead\n", 0, (intmax_t)size);
+ rc = 1;
+ goto out;
+ }
+ if ((size = lseek(fd, 0, SEEK_SET)) != 0) {
+ fprintf(stderr, "Expected 0 from lseek; got [%jd]\n",
+ (intmax_t)size);
+ rc = 1;
+ goto out;
+ }
+ if ((size = read(fd, buf, 4096)) != 4096) {
+ fprintf(stderr, "Error attempting to read data. Expected "
+ "[%d] bytes; read [%jd] instead\n", 4096,
+ (intmax_t)size);
+ rc = 1;
+ goto out;
+ }
+ for (i = 0; i < 4096; i++)
+ if (buf[i] != 0x00) {
+ fprintf(stderr, "Byte [%d] is [0x%.2x]; expected "
+ "[0x00]\n", i, buf[i]);
+ rc = 1;
+ goto out;
+ }
+ close(fd);
+ rc = stat(path, &s);
+ if (rc == -1) {
+ fprintf(stderr, "Error attempting to stat file [%s]\n",
+ path);
+ rc = 1;
+ goto out;
+ }
+ if (s.st_size != 5124) {
+ fprintf(stderr, "Filesize is [%jd]; expected 5124\n",
+ (intmax_t)s.st_size);
+ rc = 1;
+ goto out;
+ }
+ fd = open(path, (O_RDONLY));
+ if (fd == -1) {
+ fprintf(stderr, "Error attempting to create new file [%s]\n",
+ path);
+ rc = 1;
+ goto out;
+ }
+ if ((size = read(fd, buf, 4096)) != 4096) {
+ fprintf(stderr, "Error attempting to read data. Expected "
+ "[%d] bytes; read [%jd] instead\n", 4096,
+ (intmax_t)size);
+ rc = 1;
+ goto out;
+ }
+ for (i = 0; i < 4096; i++)
+ if (buf[i] != 0x00) {
+ fprintf(stderr, "Byte [%d] is [0x%.2x]; expected "
+ "[0x00]\n", i, buf[i]);
+ rc = 1;
+ goto out;
+ }
+ if ((size = read(fd, buf, 4)) != 4) {
+ fprintf(stderr, "Error attempting to read data. Expected "
+ "[%d] bytes; read [%jd] instead\n", 4, (intmax_t)size);
+ rc = 1;
+ goto out;
+ }
+ if (memcmp((char *)&deadbeef, buf, 4) != 0) {
+ fprintf(stderr, "deadbeef data mismatch after initial write\n");
+ rc = 1;
+ goto out;
+ }
+ if ((size = read(fd, buf, 1020)) != 1020) {
+ fprintf(stderr, "Error attempting to read data. Expected "
+ "[%d] bytes; read [%jd] instead\n", 1020,
+ (intmax_t)size);
+ rc = 1;
+ goto out;
+ }
+ for (i = 0; i < 1020; i++)
+ if (buf[i] != 0x00) {
+ fprintf(stderr, "Byte [%d] is [0x%.2x]; expected "
+ "[0x00]\n", i, buf[i]);
+ rc = 1;
+ goto out;
+ }
+ if ((size = read(fd, buf, 4)) != 4) {
+ fprintf(stderr, "Error attempting to read data. Expected "
+ "[%d] bytes; read [%jd] instead\n", 4, (intmax_t)size);
+ rc = 1;
+ goto out;
+ }
+ if (memcmp((char *)&baadf00d, buf, 4) != 0) {
+ fprintf(stderr, "baadf00d data mismatch after initial write\n");
+ rc = 1;
+ goto out;
+ }
+ if ((size = read(fd, buf, 1)) != 0) {
+ fprintf(stderr, "Error attempting to read data. Expected "
+ "[%d] bytes; read [%jd] instead\n", 0, (intmax_t)size);
+ rc = 1;
+ goto out;
+ }
+ close(fd);
+ unlink(path);
+ rc = 0;
+out:
+ return rc;
+}
diff --git a/tests/kernel/lp-1009207.sh b/tests/kernel/lp-1009207.sh
new file mode 100755
index 0000000..cd77f33
--- /dev/null
+++ b/tests/kernel/lp-1009207.sh
@@ -0,0 +1,58 @@
+#!/bin/bash
+#
+# lp-1009207.sh: Test for https://launchpad.net/bugs/1009207
+# Author: Tyler Hicks <tyhicks@canonical.com>
+#
+# Copyright (C) 2012 Canonical Ltd.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation version 2
+# of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+
+test_script_dir=$(dirname $0)
+rc=1
+test_dir=""
+
+. ${test_script_dir}/../lib/etl_funcs.sh
+
+test_cleanup()
+{
+ etl_remove_test_dir $test_dir
+ etl_umount
+ etl_lumount
+ etl_unlink_keys
+ exit $rc
+}
+trap test_cleanup 0 1 2 3 15
+
+etl_add_keys || exit
+etl_lmount || exit
+etl_mount_i || exit
+
+test_dir=$(etl_create_test_dir) || exit
+nomask="${test_dir}/nomask"
+masked="${test_dir}/masked"
+
+setfacl -dm m:rwx $test_dir
+umask 0000
+touch $nomask
+umask 0777
+touch $masked
+nomask_mode=$(stat -c %a $nomask)
+masked_mode=$(stat -c %a $masked)
+
+if [ "$nomask_mode" -eq "$masked_mode" ] && [ "$masked_mode" -gt 0 ]; then
+ rc=0
+fi
+
+exit
diff --git a/tests/kernel/lp-469664.sh b/tests/kernel/lp-469664.sh
new file mode 100755
index 0000000..c7bac84
--- /dev/null
+++ b/tests/kernel/lp-469664.sh
@@ -0,0 +1,47 @@
+#!/bin/bash
+#
+# lp-469664.sh: Test for https://launchpad.net/bugs/469664
+# Author: Colin Ian King <colin.king@canonical.com>
+#
+# Copyright (C) 2012 Canonical, Ltd.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+
+test_script_dir=$(dirname $0)
+rc=1
+test_dir=""
+
+. ${test_script_dir}/../lib/etl_funcs.sh
+
+test_cleanup()
+{
+ etl_remove_test_dir $test_dir
+ etl_umount
+ etl_lumount
+ etl_unlink_keys
+ exit $rc
+}
+trap test_cleanup 0 1 2 3 15
+
+etl_add_keys || exit
+etl_lmount || exit
+etl_mount_i || exit
+test_dir=$(etl_create_test_dir) || exit
+
+echo test > $test_dir/testfile
+lsattr $test_dir/testfile >& /dev/null
+rc=$?
+
+exit
diff --git a/tests/kernel/lp-509180.sh b/tests/kernel/lp-509180.sh
new file mode 100755
index 0000000..854bd56
--- /dev/null
+++ b/tests/kernel/lp-509180.sh
@@ -0,0 +1,66 @@
+#!/bin/bash
+#
+# lp-509180.sh: Test for https://launchpad.net/bugs/509180
+# Author: Colin Ian King <colin.king@canonical.com>
+#
+# Copyright (C) 2012 Canonical, Ltd.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+
+test_script_dir=$(dirname $0)
+rc=1
+test_dir=""
+
+. ${test_script_dir}/../lib/etl_funcs.sh
+
+test_cleanup()
+{
+ etl_remove_test_dir $test_dir
+ etl_umount
+ etl_lumount
+ etl_unlink_keys
+ exit $rc
+}
+trap test_cleanup 0 1 2 3 15
+
+# This test is mainly for the filename encryption case, but it is also valid for
+# plaintext filename support
+etl_add_keys || exit
+etl_lmount || exit
+etl_mount_i || exit
+test_dir=$(etl_create_test_dir) || exit
+
+# Test method: https://bugs.launchpad.net/ecryptfs/+bug/509180/comments/50
+# Create 1 byte test file
+echo "testing 1 2 3" > $test_dir/test_file
+old_sum=`md5sum $test_dir/test_file | cut -d ' ' -f 1`
+lower_file=`ls $ETL_MOUNT_SRC/ECRYPTFS*/*`
+
+# Increment 9th byte so that eCryptfs marker fails validation
+${test_script_dir}/lp-509180/test -i $lower_file || exit
+etl_umount
+
+etl_mount_i || exit
+cat $test_dir/test_file &> /dev/null
+# Decrement 9th byte so that eCryptfs marker passes validation
+${test_script_dir}/lp-509180/test -d $lower_file || exit
+new_sum=`md5sum $test_dir/test_file | cut -d ' ' -f 1`
+
+# md5sums should be the same
+if [ $old_sum = $new_sum ]; then
+ rc=0
+fi
+
+exit
diff --git a/tests/kernel/lp-509180/test.c b/tests/kernel/lp-509180/test.c
new file mode 100644
index 0000000..5b4886b
--- /dev/null
+++ b/tests/kernel/lp-509180/test.c
@@ -0,0 +1,123 @@
+/*
+ * Author: Colin King <colin.king@canonical.com>
+ *
+ * Copyright (C) 2012 Canonical, Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#define TEST_ERROR (2)
+
+#define OFFSET (9)
+
+#define OPT_INC (0x0001)
+#define OPT_DEC (0x0002)
+
+void usage(char *name)
+{
+ fprintf(stderr, "Usage: [-i | -d] file\n");
+}
+
+/*
+ * https://bugs.launchpad.net/ecryptfs/+bug/509180
+ * Increment/Decrement 9th byte in lower file
+ */
+int main(int argc, char **argv)
+{
+ int fd;
+ int opt, flags = 0;
+ int rc = 0;
+ char *file;
+ unsigned char buffer[1];
+
+ if (argc < 3) {
+ usage(argv[0]);
+ exit(TEST_ERROR);
+ }
+
+ while ((opt = getopt(argc, argv, "id")) != -1) {
+ switch (opt) {
+ case 'i':
+ flags |= OPT_INC;
+ break;
+ case 'd':
+ flags |= OPT_DEC;
+ break;
+ default:
+ usage(argv[0]);
+ exit(TEST_ERROR);
+ }
+ }
+
+ if ((flags == 0) || (flags == (OPT_INC | OPT_DEC))) {
+ fprintf(stderr, "Need to specify -i or -d\n");
+ exit(TEST_ERROR);
+ }
+
+ file = argv[optind];
+
+ if ((fd = open(file, O_RDWR, 0700)) < 0) {
+ fprintf(stderr, "Cannot open %s : %s\n", file, strerror(errno));
+ exit(TEST_ERROR);
+ }
+
+ if ((lseek(fd, (off_t)OFFSET, SEEK_SET)) < 0) {
+ fprintf(stderr, "Cannot lseek to offset %d in %s : %s\n",
+ OFFSET, file, strerror(errno));
+ rc = TEST_ERROR;
+ goto tidy;
+ }
+
+ if (read(fd, buffer, sizeof(buffer)) != sizeof(buffer)) {
+ fprintf(stderr, "Failed to read\n");
+ rc = TEST_ERROR;
+ goto tidy;
+ }
+
+ if (flags & OPT_INC)
+ buffer[0]++;
+
+ if (flags & OPT_DEC)
+ buffer[0]--;
+
+ if ((lseek(fd, (off_t)OFFSET, SEEK_SET)) < 0) {
+ fprintf(stderr, "Cannot lseek to offset %d in %s : %s\n",
+ OFFSET, file, strerror(errno));
+ rc = TEST_ERROR;
+ goto tidy;
+ }
+
+ if (write(fd, buffer, sizeof(buffer)) != sizeof(buffer)) {
+ fprintf(stderr, "Failed to write\n");
+ rc = TEST_ERROR;
+ }
+
+tidy:
+ if (close(fd) < 0) {
+ fprintf(stderr, "Close failed: %s\n", strerror(errno));
+ exit(TEST_ERROR);
+ }
+
+ exit(rc);
+}
diff --git a/tests/kernel/lp-524919.sh b/tests/kernel/lp-524919.sh
new file mode 100755
index 0000000..27acae3
--- /dev/null
+++ b/tests/kernel/lp-524919.sh
@@ -0,0 +1,46 @@
+#!/bin/bash
+#
+# lp-524919.sh: Test for https://launchpad.net/bugs/524919
+# Author: Colin Ian King <colin.king@canonical.com>
+#
+# Copyright (C) 2012 Canonical, Ltd.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+
+test_script_dir=$(dirname $0)
+rc=1
+test_dir=""
+
+. ${test_script_dir}/../lib/etl_funcs.sh
+
+test_cleanup()
+{
+ etl_remove_test_dir $test_dir
+ etl_umount
+ etl_lumount
+ etl_unlink_keys
+ exit $rc
+}
+trap test_cleanup 0 1 2 3 15
+
+etl_add_keys || exit
+etl_lmount || exit
+etl_mount_i || exit
+test_dir=$(etl_create_test_dir) || exit
+
+${test_script_dir}/lp-524919/test $test_dir/testfile || exit
+rc=$?
+
+exit
diff --git a/tests/kernel/lp-524919/test.c b/tests/kernel/lp-524919/test.c
new file mode 100644
index 0000000..ab9ea9f
--- /dev/null
+++ b/tests/kernel/lp-524919/test.c
@@ -0,0 +1,100 @@
+/*
+ * Author: Colin King <colin.king@canonical.com>
+ *
+ * Copyright (C) 2012 Canonical, Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <limits.h>
+#include <fcntl.h>
+
+#define TEST_PASSED (0)
+#define TEST_FAILED (1)
+#define TEST_ERROR (2)
+
+/*
+ * https://bugs.launchpad.net/ubuntu/+source/linux/+bug/524919
+ *
+ * test that readlink() and lstat() size of a symlink are the same length
+ */
+int main(int argc, char **argv)
+{
+ char link[PATH_MAX];
+ char buf[PATH_MAX];
+ struct stat statbuf;
+ int rc = TEST_PASSED;
+ int fd;
+ ssize_t n;
+
+ if (argc < 2) {
+ fprintf(stderr, "Usage: filename\n");
+ exit(TEST_ERROR);
+ }
+
+ if ((fd = open(argv[1], O_CREAT | O_RDWR, S_IRUSR | S_IWUSR)) < 0) {
+ fprintf(stderr, "cannot create %s : %s\n", argv[1],
+ strerror(errno));
+ exit(TEST_ERROR);
+ }
+
+ if (close(fd) < 0) {
+ fprintf(stderr, "close failed %s: %s\n", argv[1],
+ strerror(errno));
+ rc = TEST_ERROR;
+ goto tidy_file;
+ }
+
+ snprintf(link, sizeof(link), "%s-symlink", argv[1]);
+ if (symlink(argv[1], link) < 0) {
+ fprintf(stderr, "symlink failed %s: %s\n", argv[1],
+ strerror(errno));
+ rc = TEST_ERROR;
+ goto tidy_file;
+ }
+
+ n = readlink(link, buf, sizeof(buf));
+ if (n < 0) {
+ fprintf(stderr, "readlink failed %s: %s\n", argv[1],
+ strerror(errno));
+ rc = TEST_ERROR;
+ goto tidy_symlink;
+ }
+ if (lstat(link, &statbuf) < 0) {
+ fprintf(stderr, "lstat failed %s: %s\n", argv[1],
+ strerror(errno));
+ rc = TEST_ERROR;
+ goto tidy_symlink;
+ }
+
+ /* Should be the same size */
+ if (statbuf.st_size != n)
+ rc = TEST_FAILED;
+
+tidy_symlink:
+ unlink(link);
+tidy_file:
+ unlink(argv[1]);
+
+ exit(rc);
+}
diff --git a/tests/kernel/lp-561129.sh b/tests/kernel/lp-561129.sh
new file mode 100755
index 0000000..43e9a8c
--- /dev/null
+++ b/tests/kernel/lp-561129.sh
@@ -0,0 +1,62 @@
+#!/bin/bash
+#
+# lp-561129.sh: Test for https://launchpad.net/bugs/561129
+# Author: Tyler Hicks <tyhicks@canonical.com>
+#
+# Copyright (C) 2012 Canonical Ltd.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation version 2
+# of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+
+test_script_dir=$(dirname $0)
+rc=1
+test_dir=0
+
+. ${test_script_dir}/../lib/etl_funcs.sh
+
+test_cleanup()
+{
+ etl_remove_test_dir $test_dir
+ etl_umount
+ etl_lumount
+ etl_unlink_keys
+ exit $rc
+}
+trap test_cleanup 0 1 2 3 15
+
+# TEST
+etl_add_keys || exit
+etl_lmount || exit
+etl_mount_i || exit
+test_dir=$(etl_create_test_dir) || exit
+src="${test_dir}/src"
+dst="${test_dir}/dst"
+
+touch "$dst" || exit
+# IMPORTANT: This test gives false positives on filesystems that do not
+# report free inodes (btrfs, for example) in statfs(). On those
+# filesystems, we're testing [ 0 -eq 0 ]. Until this test framework has
+# the notion of skipped tests, we'll have to let it slide.
+expected_inodes=$(stat -fc %d "$dst") || exit
+# TODO: Mark test as skipped if [ $expected_inodes -eq 0 ]
+
+touch "$src" || exit
+mv "$src" "$dst" || exit
+free_inodes=$(stat -fc %d "$dst") || exit
+
+if [ $free_inodes -eq $expected_inodes ]; then
+ rc=0
+fi
+
+exit
diff --git a/tests/kernel/lp-613873.sh b/tests/kernel/lp-613873.sh
new file mode 100755
index 0000000..66c532c
--- /dev/null
+++ b/tests/kernel/lp-613873.sh
@@ -0,0 +1,63 @@
+#!/bin/bash
+#
+# lp-613873.sh: Test for https://launchpad.net/bugs/613873
+# Author: Colin Ian King <colin.king@canonical.com>
+#
+# Copyright (C) 2012 Canonical, Ltd.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+
+test_script_dir=$(dirname $0)
+rc=1
+test_dir=""
+
+. ${test_script_dir}/../lib/etl_funcs.sh
+
+test_cleanup()
+{
+ etl_remove_test_dir $test_dir
+ etl_umount
+ etl_lumount
+ etl_unlink_keys
+ exit $rc
+}
+trap test_cleanup 0 1 2 3 15
+
+etl_add_keys || exit
+etl_lmount || exit
+etl_mount_i || exit
+test_dir=$(etl_create_test_dir) || exit
+
+#
+# Test that modify time does not change
+#
+date > $test_dir/testfile
+stat_before=`stat -c%Y $test_dir/testfile`
+#
+# Wait a little
+#
+sleep 0.25
+chmod 0600 $test_dir/testfile
+stat_after=`stat -c%Y $test_dir/testfile`
+#
+# Modify time should be the same
+#
+if [ $stat_before -eq $stat_after ]; then
+ rc=0
+fi
+
+rm $test_dir/testfile
+
+exit
diff --git a/tests/kernel/lp-745836.sh b/tests/kernel/lp-745836.sh
new file mode 100755
index 0000000..4a23891
--- /dev/null
+++ b/tests/kernel/lp-745836.sh
@@ -0,0 +1,57 @@
+#!/bin/bash
+#
+# lp-74586.sh: Test for https://launchpad.net/bugs/745836
+# Author: Colin Ian King <colin.king@canonical.com>
+#
+# Copyright (C) 2012 Canonical Ltd.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation version 2
+# of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+
+test_script_dir=$(dirname $0)
+rc=1
+
+. ${test_script_dir}/../lib/etl_funcs.sh
+
+test_cleanup()
+{
+ etl_remove_test_dir $test_dir
+ etl_umount
+ etl_lumount
+ etl_unlink_keys
+ exit $rc
+}
+trap test_cleanup 0 1 2 3 15
+
+etl_add_keys || exit
+etl_lmount || exit
+etl_mount_i || exit
+test_dir=$(etl_create_test_dir) || exit
+test_file="${test_dir}/foo"
+
+touch $test_file || exit
+truncate -s 4096 $test_file || exit
+sync || exit
+echo 1 > /proc/sys/vm/drop_caches || exit
+#
+# File should be all full of zeros and hence have the
+# following md5sum:
+#
+sum=$(md5sum $test_file | cut -f1 -d ' ')
+if [ $sum == "620f0b67a91f7f74151bc5be745b7110" ]; then
+ rc=0
+fi
+rm $test_file
+
+exit
diff --git a/tests/kernel/lp-870326.sh b/tests/kernel/lp-870326.sh
new file mode 100755
index 0000000..29b64da
--- /dev/null
+++ b/tests/kernel/lp-870326.sh
@@ -0,0 +1,46 @@
+#!/bin/bash
+#
+# lp-870326.sh: Test for https://launchpad.net/bugs/870326
+# Author: Colin Ian King <colin.king@canonical.com>
+#
+# Copyright (C) 2012 Canonical, Ltd.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+
+test_script_dir=$(dirname $0)
+rc=1
+test_dir=""
+
+. ${test_script_dir}/../lib/etl_funcs.sh
+
+test_cleanup()
+{
+ etl_remove_test_dir $test_dir
+ etl_umount
+ etl_lumount
+ etl_unlink_keys
+ exit $rc
+}
+trap test_cleanup 0 1 2 3 15
+
+etl_add_keys || exit
+etl_lmount || exit
+etl_mount_i || exit
+test_dir=$(etl_create_test_dir) || exit
+
+${test_script_dir}/lp-870326/test $test_dir/testfile
+rc=$?
+
+exit
diff --git a/tests/kernel/lp-870326/test.c b/tests/kernel/lp-870326/test.c
new file mode 100644
index 0000000..b4926f8
--- /dev/null
+++ b/tests/kernel/lp-870326/test.c
@@ -0,0 +1,160 @@
+/*
+ * Author: Colin King <colin.king@canonical.com>
+ *
+ * Copyright (C) 2012 Canonical, Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/klog.h>
+#include <limits.h>
+
+#define TEST_PASSED (0)
+#define TEST_FAILED (1)
+#define TEST_ERROR (2)
+
+#define MMAP_LEN (8192)
+
+/* read kernel log */
+char *klog_read(void)
+{
+ int len;
+ char *klog;
+
+ if ((len = klogctl(10, NULL, 0)) < 0)
+ return NULL;
+
+ if ((klog = calloc(1, len)) == NULL)
+ return NULL;
+
+ if (klogctl(3, klog, len) < 0) {
+ free(klog);
+ return NULL;
+ }
+ return klog;
+}
+
+/*
+ * https://bugs.launchpad.net/ubuntu/+bug/870326
+ * open(), mmap(), close() and write to mapping causes
+ * an error.
+ */
+int main(int argc, char **argv)
+{
+ int fd;
+ int rc = TEST_PASSED;
+ unsigned int *ptr;
+ char buffer[MMAP_LEN];
+ char *klog_before;
+ char *klog_after, *klog_new_text;
+ size_t n, lastline_len = 0;
+
+ if (argc < 2) {
+ fprintf(stderr, "Usage: file\n");
+ exit(TEST_ERROR);
+ }
+
+ if ((fd = open(argv[1], O_CREAT | O_RDWR, S_IRUSR | S_IWUSR)) < 0) {
+ fprintf(stderr, "Cannot create %s : %s\n",
+ argv[1], strerror(errno));
+ exit(TEST_ERROR);
+ }
+
+ memset(buffer, 'X', sizeof(buffer));
+ if (write(fd, buffer, sizeof(buffer)) < 0) {
+ fprintf(stderr, "Failed to write to %s : %s\n",
+ argv[1], strerror(errno));
+ close(fd);
+ rc = TEST_ERROR;
+ goto tidy;
+ }
+
+ ptr = mmap(NULL, MMAP_LEN, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+ if (ptr == MAP_FAILED) {
+ fprintf(stderr, "Cannot mmap file %s : %s\n",
+ argv[1], strerror(errno));
+ close(fd);
+ rc = TEST_ERROR;
+ goto tidy;
+ }
+
+ if (close(fd) < 0) {
+ fprintf(stderr, "Failed to close : %s\n", strerror(errno));
+ munmap(ptr, MMAP_LEN);
+ rc = TEST_ERROR;
+ goto tidy;
+ }
+
+ if ((klog_before = klog_read()) == NULL) {
+ fprintf(stderr, "Failed to read kernel log\n");
+ munmap(ptr, MMAP_LEN);
+ rc = TEST_ERROR;
+ goto tidy;
+ }
+
+ /* Seek back to start of last line */
+ if ((n = strlen(klog_before)) > 0) {
+ n--;
+ lastline_len++;
+ while (n > 0 && klog_before[n-1] != '\n') {
+ n--;
+ lastline_len++;
+ }
+ }
+
+ /* Modify pages, this caused bug LP#870326 */
+ memset(ptr, ' ', MMAP_LEN);
+
+ if (munmap(ptr, MMAP_LEN) < 0) {
+ fprintf(stderr, "munmap failed : %s\n", strerror(errno));
+ free(klog_before);
+ rc = TEST_ERROR;
+ goto tidy;
+ }
+
+ /*
+ * Get klog again, find previous klog last line
+ * and offset to end of this
+ */
+ if ((klog_after = klog_read()) == NULL) {
+ fprintf(stderr, "Failed to read kernel log\n");
+ free(klog_before);
+ rc = TEST_ERROR;
+ goto tidy;
+ }
+ klog_new_text = strstr(klog_after, klog_before + n);
+
+ /* Any new kernel log lines contain the error message? */
+ if (klog_new_text &&
+ strstr(klog_new_text + lastline_len,
+ "Error attempting to write lower page"))
+ rc = TEST_FAILED;
+
+ free(klog_before);
+ free(klog_after);
+tidy:
+ unlink(argv[1]);
+
+ exit(rc);
+}
diff --git a/tests/kernel/lp-872905.sh b/tests/kernel/lp-872905.sh
new file mode 100755
index 0000000..59244b8
--- /dev/null
+++ b/tests/kernel/lp-872905.sh
@@ -0,0 +1,77 @@
+#!/bin/bash
+#
+# lp-872905: Test for https://launchpad.net/bugs/872905
+# Author: Colin Ian King <colin.king@canonical.com>
+#
+# Copyright (C) 2012 Canonical, Ltd.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+
+test_script_dir=$(dirname $0)
+rc=1
+test_dir=""
+
+. ${test_script_dir}/../lib/etl_funcs.sh
+
+test_cleanup()
+{
+ etl_remove_test_dir $test_dir
+ etl_umount
+ etl_lumount
+ etl_unlink_keys
+ exit $rc
+}
+trap test_cleanup 0 1 2 3 15
+
+etl_add_keys || exit
+etl_lmount || exit
+etl_mount_i || exit
+test_dir=$(etl_create_test_dir) || exit
+test_file="${test_dir}/test_file"
+
+lower_test_dir=$(etl_find_lower_path $test_dir)
+if [ $? -ne 0 ]; then
+ exit
+fi
+
+#
+# Fill the lower
+#
+dd if=/dev/zero of=${lower_test_dir}/filler bs=4K > /dev/null 2>&1
+
+#
+# Now attempt to create an upper and see how big it is
+#
+touch $test_file >& /dev/null
+if [ $? -ne 0 ]; then
+ rc=0
+ exit
+fi
+
+lower_test_file=$(etl_find_lower_path $test_file)
+if [ $? -ne 0 ]; then
+ exit
+fi
+
+#
+# We shouldn't have a lower file created of zero bytes size if
+# the bug is fixed
+#
+sz=$(stat -c%s $lower_test_file)
+if [ $sz -ne 0 ]; then
+ rc=0
+fi
+
+exit
diff --git a/tests/kernel/lp-885744.sh b/tests/kernel/lp-885744.sh
new file mode 100755
index 0000000..7b83ff1
--- /dev/null
+++ b/tests/kernel/lp-885744.sh
@@ -0,0 +1,50 @@
+#!/bin/bash
+#
+# lp-885744.sh: Test for https://launchpad.net/bugs/885744
+# Author: Tyler Hicks <tyhicks@canonical.com>
+#
+# Copyright (C) 2012 Canonical, Ltd.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+
+test_script_dir=$(dirname $0)
+rc=1
+test_dir=""
+
+. ${test_script_dir}/../lib/etl_funcs.sh
+
+test_cleanup()
+{
+ etl_remove_test_dir $test_dir
+ etl_umount
+ etl_lumount
+ etl_unlink_keys
+ exit $rc
+}
+trap test_cleanup 0 1 2 3 15
+
+# This test is mainly for the filename encryption case, but it is also valid for
+# plaintext filename support
+etl_add_keys || exit
+etl_lmount || exit
+etl_mount_i || exit
+test_dir=$(etl_create_test_dir) || exit
+
+name_max=$(getconf NAME_MAX "$test_dir" 2>/dev/null)
+name=$(printf "%*s" $name_max '' | tr ' ' 'a')
+touch ${test_dir}/${name} &>/dev/null
+
+rc=$?
+exit
diff --git a/tests/kernel/lp-911507.sh b/tests/kernel/lp-911507.sh
new file mode 100755
index 0000000..84eee83
--- /dev/null
+++ b/tests/kernel/lp-911507.sh
@@ -0,0 +1,78 @@
+#!/bin/bash
+#
+# lp-911507.sh: Test for https://launchpad.net/bugs/911507
+# Author: Colin Ian King <colin.king@canonical.com>
+#
+# Copyright (C) 2012 Canonical, Ltd.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+
+test_script_dir=$(dirname $0)
+rc=1
+test_dir=""
+
+. ${test_script_dir}/../lib/etl_funcs.sh
+
+test_cleanup()
+{
+ etl_remove_test_dir $test_dir
+ etl_umount
+ etl_lumount
+ etl_unlink_keys
+ exit $rc
+}
+trap test_cleanup 0 1 2 3 15
+
+etl_add_keys || exit
+etl_lmount || exit
+etl_mount_i || exit
+test_dir=$(etl_create_test_dir) || exit
+test_file="${test_dir}/test_file"
+
+touch $test_file
+
+#
+# Drop caches
+#
+echo 1 > /proc/sys/vm/drop_caches
+
+lower_test_file=$(etl_find_lower_path $test_file)
+if [ $? -ne 0 ] || [ -z "$lower_test_file" ]; then
+ rc=1
+ exit
+fi
+
+#
+# Truncate lower, this will force bug LP#911507 when reading the file
+#
+truncate -s 0 $lower_test_file
+
+#
+# Now read the file, eCryptfs should fix the lower file
+# and append the text without failing
+#
+cat $test_file > /dev/null 2>&1
+rc=$?
+if [ $rc -eq 0 ]; then
+ #
+ # Is the file contents correct?
+ #
+ sum=$(md5sum $test_file | cut -d' ' -f1)
+ if [ x$sum != xd41d8cd98f00b204e9800998ecf8427e ]; then
+ rc=1
+ fi
+fi
+
+exit
diff --git a/tests/kernel/lp-926292.sh b/tests/kernel/lp-926292.sh
new file mode 100755
index 0000000..4585e29
--- /dev/null
+++ b/tests/kernel/lp-926292.sh
@@ -0,0 +1,53 @@
+#!/bin/bash
+#
+# lp-926292.sh: Test for https://launchpad.net/bugs/926292
+# Author: Tyler Hicks <tyhicks@canonical.com>
+#
+# Copyright (C) 2012 Canonical Ltd.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation version 2
+# of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+
+test_script_dir=$(dirname $0)
+rc=1
+
+. ${test_script_dir}/../lib/etl_funcs.sh
+
+test_cleanup()
+{
+ etl_remove_test_dir $test_dir
+ etl_umount
+ etl_lumount
+ etl_unlink_keys
+ exit $rc
+}
+trap test_cleanup 0 1 2 3 15
+
+etl_add_keys || exit
+etl_lmount || exit
+etl_mount_i || exit
+test_dir=$(etl_create_test_dir) || exit
+dir="${test_dir}/foo"
+
+# This won't work for regular files because they have a special
+# ecryptfs_getattr() function which will mask the stale inode
+# attributes. eCryptfs directory inode don't have a special ->getattr()
+mkdir --mode=700 $dir || exit
+setfacl -m u::rx $dir || exit
+st=$(stat -c %a $dir) || exit
+if [ $st = "500" ]; then
+ rc=0
+fi
+
+exit
diff --git a/tests/kernel/lp-994247.sh b/tests/kernel/lp-994247.sh
new file mode 100755
index 0000000..9da00d2
--- /dev/null
+++ b/tests/kernel/lp-994247.sh
@@ -0,0 +1,37 @@
+#!/bin/bash
+#
+# lp-994247.sh: Test for https://launchpad.net/bugs/994247
+# Author: Tyler Hicks <tyhicks@canonical.com>
+#
+# Copyright (C) 2012 Canonical Ltd.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation version 2
+# of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+
+test_script_dir=$(dirname $0)
+rc=1
+
+. ${test_script_dir}/../lib/etl_funcs.sh
+
+test_cleanup()
+{
+ exit $rc
+}
+trap test_cleanup 0 1 2 3 15
+
+etl_load_ecryptfs || exit
+${test_script_dir}/lp-994247/test
+
+rc=$?
+exit
diff --git a/tests/kernel/lp-994247/test.c b/tests/kernel/lp-994247/test.c
new file mode 100644
index 0000000..3441dc1
--- /dev/null
+++ b/tests/kernel/lp-994247/test.c
@@ -0,0 +1,77 @@
+/**
+ * test.c: C-based test for https://launchpad.net/bugs/994247
+ * This should result in a kernel BUG().
+ * Author: Tyler Hicks <tyhicks@canonical.com>
+ *
+ * Copyright (C) 2012 Canonical, Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
+ */
+
+#include <fcntl.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+int miscdev;
+
+void sigusr1_handler(int ignored)
+{
+ exit(close(miscdev));
+}
+
+int main(void)
+{
+ struct sigaction sa;
+ pid_t pid;
+ int status, rc;
+
+ memset(&sa, 0, sizeof(sa));
+ sa.sa_handler = sigusr1_handler;
+
+ miscdev = open("/dev/ecryptfs", O_RDWR);
+ if (miscdev < 0)
+ return 1;
+
+ rc = sigaction(SIGUSR1, &sa, NULL);
+ if (rc < 0)
+ return 1;
+
+ pid = fork();
+ if (pid < 0)
+ return 1;
+ else if (!pid) {
+ pause();
+ exit(1);
+ }
+
+ /* The parent must close the file before the child */
+ close(miscdev);
+
+ rc = kill(pid, SIGUSR1);
+ if (rc < 0)
+ return 1;
+
+ rc = waitpid(pid, &status, 0);
+ if (rc < 0 || !WIFEXITED(status))
+ return 1;
+
+ return WEXITSTATUS(status);
+}
diff --git a/tests/kernel/miscdev-bad-count.sh b/tests/kernel/miscdev-bad-count.sh
new file mode 100755
index 0000000..2b4ced7
--- /dev/null
+++ b/tests/kernel/miscdev-bad-count.sh
@@ -0,0 +1,37 @@
+#!/bin/bash
+#
+# miscdev-bad-count.sh: Test for https://lkml.org/lkml/2012/1/11/394
+# Author: Tyler Hicks <tyhicks@canonical.com>
+#
+# Copyright (C) 2012 Canonical, Ltd.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+test_script_dir=$(dirname $0)
+rc=1
+
+. ${test_script_dir}/../lib/etl_funcs.sh
+
+test_cleanup()
+{
+ exit $rc
+}
+trap test_cleanup 0 1 2 3 15
+
+etl_load_ecryptfs || exit
+${test_script_dir}/miscdev-bad-count/test
+
+rc=$?
+exit
diff --git a/tests/kernel/miscdev-bad-count/test.c b/tests/kernel/miscdev-bad-count/test.c
new file mode 100644
index 0000000..891f53f
--- /dev/null
+++ b/tests/kernel/miscdev-bad-count/test.c
@@ -0,0 +1,46 @@
+
+/**
+ * test.c: C-based test for https://lkml.org/lkml/2012/1/11/394
+ * Author: Tyler Hicks <tyhicks@canonical.com>
+ *
+ * Copyright (C) 2012 Canonical, Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+int main(void)
+{
+ unsigned char buf[] = { 103, 0, 0, 0, 0, 220 };
+ ssize_t written;
+ int miscdev;
+
+
+ miscdev = open("/dev/ecryptfs", O_WRONLY);
+ if (miscdev < 0)
+ return 1;
+
+ written = write(miscdev, buf, 1073741824);
+
+ close(miscdev);
+
+ /* The write should fail */
+ return written < 0 ? 0 : 2;
+}
diff --git a/tests/kernel/mknod.sh b/tests/kernel/mknod.sh
new file mode 100755
index 0000000..1a939fb
--- /dev/null
+++ b/tests/kernel/mknod.sh
@@ -0,0 +1,64 @@
+#!/bin/bash
+#
+# mknod.sh : Simple mknod sanity check
+#
+# Author: Colin Ian King <colin.king@canonical.com>
+#
+# Copyright (C) 2013 Canonical Ltd.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation version 2
+# of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+
+test_script_dir=$(dirname $0)
+rc=1
+test_dir=0
+
+. ${test_script_dir}/../lib/etl_funcs.sh
+
+test_cleanup()
+{
+ etl_remove_test_dir $test_dir
+ etl_umount
+ etl_lumount
+ etl_unlink_keys
+ exit $rc
+}
+trap test_cleanup 0 1 2 3 15
+
+# TEST
+etl_add_keys || exit
+etl_lmount || exit
+etl_mount_i || exit
+test_dir=$(etl_create_test_dir) || exit
+test_file="${test_dir}/full"
+
+mknod $test_file c 1 7
+#
+# Check to see if mknod succeeded as expected
+#
+if [ $? -eq 0 ]; then
+ dev=$(stat $test_file -c%t:%T)
+ if [ $? -eq 0 ]; then
+ if [ x$dev == x1:7 ]; then
+ rc=0
+ fi
+ fi
+fi
+
+rm -f $test_file
+
+etl_umount || exit
+etl_mount_i || exit
+
+exit
diff --git a/tests/kernel/mmap-bmap.sh b/tests/kernel/mmap-bmap.sh
new file mode 100755
index 0000000..0f19579
--- /dev/null
+++ b/tests/kernel/mmap-bmap.sh
@@ -0,0 +1,58 @@
+#!/bin/bash
+#
+# mmap-bmap.sh : Test to see if bmap from upper is a subset of the lower
+#
+# Author: Colin Ian King <colin.king@canonical.com>
+#
+# Copyright (C) 2013 Canonical Ltd.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation version 2
+# of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+
+test_script_dir=$(dirname $0)
+rc=1
+test_dir=0
+
+. ${test_script_dir}/../lib/etl_funcs.sh
+
+test_cleanup()
+{
+ etl_remove_test_dir $test_dir
+ etl_umount
+ etl_lumount
+ etl_unlink_keys
+ exit $rc
+}
+trap test_cleanup 0 1 2 3 15
+
+# TEST
+etl_add_keys || exit
+etl_lmount || exit
+etl_mount_i || exit
+test_dir=$(etl_create_test_dir) || exit
+test_file="${test_dir}/test_file"
+
+dd if=/dev/zero of=$test_file bs=1M count=1 > /dev/null 2>&1 || exit
+lower_test_file=$(etl_find_lower_path $test_file)
+if [ $? -ne 0 ] || [ -z "$lower_test_file" ]; then
+ rc=1
+ exit
+fi
+${test_script_dir}/mmap-bmap/test $lower_test_file $test_file || exit
+rc=$?
+
+etl_umount || exit
+etl_mount_i || exit
+
+exit
diff --git a/tests/kernel/mmap-bmap/test.c b/tests/kernel/mmap-bmap/test.c
new file mode 100644
index 0000000..8f45f8f
--- /dev/null
+++ b/tests/kernel/mmap-bmap/test.c
@@ -0,0 +1,132 @@
+/*
+ * Author: Colin King <colin.king@canonical.com>
+ *
+ * Copyright (C) 2013 Canonical, Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <linux/fs.h>
+
+static int *get_blocks(const char *filename, int *num_blocks)
+{
+ int fd, block_size, i;
+ int *blocks;
+ struct stat statinfo;
+
+ if ((fd = open(filename, O_RDONLY)) < 0) {
+ fprintf(stderr, "Cannot open %s\n", filename);
+ return NULL;
+ }
+
+ if (ioctl(fd, FIGETBSZ, &block_size) < 0) {
+ fprintf(stderr, "Cannot get block size\n");
+ close(fd);
+ return NULL;
+ }
+
+ if (fstat(fd, &statinfo) < 0) {
+ fprintf(stderr, "Cannot stat %s\n", filename);
+ close(fd);
+ return NULL;
+ }
+
+ *num_blocks = (statinfo.st_size + block_size - 1) / block_size;
+
+ blocks = malloc(sizeof(int) * *num_blocks);
+ if (!blocks) {
+ fprintf(stderr, "Cannot allocate buffer for %d blocks\n", *num_blocks);
+ close(fd);
+ return NULL;
+ }
+
+ /*
+ * Collect blocks, some file systems may not support FIBMAP, so
+ * silently ignore errors.
+ */
+ for (i = 0; i < *num_blocks; i++) {
+ blocks[i] = i;
+ if (ioctl(fd, FIBMAP, &blocks[i]) < 0)
+ blocks[i] = 0;
+ }
+ close(fd);
+
+ return blocks;
+}
+
+int check_blocks(
+ int *lower_blocks, int lower_num_blocks,
+ int *upper_blocks, int upper_num_blocks)
+{
+ int i, j;
+
+ /* Upper must not have more blocks than lower */
+ if (upper_num_blocks > lower_num_blocks)
+ return EXIT_FAILURE;
+
+ /* Upper must have blocks that are in the lower */
+ for (i = 0; i < upper_num_blocks; i++) {
+ bool found = false;
+ for (j = 0; j < lower_num_blocks; j++) {
+ if (upper_blocks[i] == lower_blocks[j]) {
+ found = true;
+ break;
+ }
+ }
+ if (!found)
+ return EXIT_FAILURE;
+ }
+ return EXIT_SUCCESS;
+}
+
+int main(int argc, char **argv) {
+
+ int *lower_blocks, *upper_blocks;
+ int lower_num_blocks, upper_num_blocks;
+ int rc = EXIT_SUCCESS;
+
+ if (argc != 3) {
+ fprintf(stderr, "Usage: %s lower-file upper-file\n", argv[0]);
+ exit(EXIT_FAILURE);
+ }
+
+ lower_blocks = get_blocks(argv[1], &lower_num_blocks);
+ if (!lower_blocks)
+ exit(EXIT_FAILURE);
+
+ upper_blocks = get_blocks(argv[2], &upper_num_blocks);
+ if (!upper_blocks) {
+ free(lower_blocks);
+ exit(EXIT_FAILURE);
+ }
+
+ rc = check_blocks(lower_blocks, lower_num_blocks,
+ upper_blocks, upper_num_blocks);
+
+ free(upper_blocks);
+ free(lower_blocks);
+
+ exit(rc);
+}
diff --git a/tests/kernel/mmap-close.sh b/tests/kernel/mmap-close.sh
new file mode 100755
index 0000000..5f2d703
--- /dev/null
+++ b/tests/kernel/mmap-close.sh
@@ -0,0 +1,65 @@
+#!/bin/bash
+#
+# mmap-close.sh : Test for catching regressions when applications do this:
+#
+# open() -> mmap() -> *close()* -> dirty mapping -> munmap()
+#
+# Past regressions have been reported in these bugs:
+#
+# https://bugs.launchpad.net/bugs/870326
+# https://bugs.launchpad.net/bugs/1047261
+# Author: Tyler Hicks <tyhicks@canonical.com>
+#
+# Copyright (C) 2012 Canonical Ltd.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation version 2
+# of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+
+test_script_dir=$(dirname $0)
+rc=1
+test_dir=0
+
+. ${test_script_dir}/../lib/etl_funcs.sh
+
+test_cleanup()
+{
+ etl_remove_test_dir $test_dir
+ etl_umount
+ etl_lumount
+ etl_unlink_keys
+ exit $rc
+}
+trap test_cleanup 0 1 2 3 15
+
+# TEST
+etl_add_keys || exit
+etl_lmount || exit
+etl_mount_i || exit
+test_dir=$(etl_create_test_dir) || exit
+test_file="${test_dir}/test_file"
+
+${test_script_dir}/mmap-close/test $test_file || exit
+
+md5sum1=$(md5sum $test_file) || exit
+
+etl_umount || exit
+etl_mount_i || exit
+
+md5sum2=$(md5sum $test_file) || exit
+
+if [ "$md5sum1" == "$md5sum2" ]; then
+ rc=0
+fi
+
+exit
diff --git a/tests/kernel/mmap-close/test.c b/tests/kernel/mmap-close/test.c
new file mode 100644
index 0000000..0eec6a7
--- /dev/null
+++ b/tests/kernel/mmap-close/test.c
@@ -0,0 +1,77 @@
+/*
+ * Author: Tyler Hicks <tyhicks@canonical.com>
+ *
+ * Copyright (C) 2012 Canonical, Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <errno.h>
+#include <unistd.h>
+#include <string.h>
+
+#define MEM_LEN (4096*8)
+#define MEM_CHUNK (4096)
+
+int main(int argc, char **argv)
+{
+ void *mem;
+ int i, fd, rc;
+
+ if (argc != 2) {
+ fprintf(stderr, "Usage: %s FILE_PATH\n", argv[0]);
+ return EINVAL;
+ }
+
+ fd = open(argv[1], O_RDWR | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR);
+ if (fd < 0) {
+ perror("open");
+ return errno;
+ }
+
+ rc = ftruncate(fd, MEM_LEN);
+ if (rc < 0) {
+ perror("ftruncate");
+ return errno;
+ }
+
+ mem = mmap(NULL, MEM_LEN, PROT_WRITE, MAP_SHARED, fd, 0);
+ if (mem == MAP_FAILED) {
+ perror("mmap");
+ return errno;
+ }
+
+ /**
+ * This is the crux of the problem: close() before pages are dirtied
+ * and munmap() is called.
+ */
+ close(fd);
+
+ for (i = 0; i < MEM_LEN; i += MEM_CHUNK)
+ memset(((char *)mem) + i, 0xFF, MEM_CHUNK);
+
+ rc = munmap(mem, MEM_LEN);
+ if (rc < 0) {
+ perror("munmap");
+ return errno;
+ }
+
+ return 0;
+}
diff --git a/tests/kernel/mmap-dir.sh b/tests/kernel/mmap-dir.sh
new file mode 100755
index 0000000..9a1acf9
--- /dev/null
+++ b/tests/kernel/mmap-dir.sh
@@ -0,0 +1,46 @@
+#!/bin/bash
+#
+# mmap-dir: check we cannot mmap an ecryptfs directory
+# Author: Colin King <colin.king@canonical.com>
+#
+# Copyright (C) 2012 Canonical, Ltd.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+
+test_script_dir=$(dirname $0)
+rc=1
+test_dir=""
+
+. ${test_script_dir}/../lib/etl_funcs.sh
+
+test_cleanup()
+{
+ etl_remove_test_dir $test_dir
+ etl_umount
+ etl_lumount
+ etl_unlink_keys
+ exit $rc
+}
+trap test_cleanup 0 1 2 3 15
+
+etl_add_keys || exit
+etl_lmount || exit
+etl_mount_i || exit
+test_dir=$(etl_create_test_dir) || exit
+
+${test_script_dir}/mmap-dir/test ${test_dir}
+
+rc=$?
+exit
diff --git a/tests/kernel/mmap-dir/test.c b/tests/kernel/mmap-dir/test.c
new file mode 100644
index 0000000..e65e96d
--- /dev/null
+++ b/tests/kernel/mmap-dir/test.c
@@ -0,0 +1,79 @@
+/*
+ * Author: Colin King <colin.king@canonical.com>
+ *
+ * Copyright (C) 2012 Canonical, Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <limits.h>
+
+#define TEST_PASSED (0)
+#define TEST_FAILED (1)
+#define TEST_ERROR (2)
+
+#define MMAP_LEN (4096)
+
+/*
+ * https://bugs.launchpad.net/ecryptfs/+bug/400443
+ *
+ * mmap() on a directory should return -ENODEV, but bug LP: #400443
+ * ecryptfs returns a mmap'd address which causes SIGBUS on access.
+ */
+int main(int argc, char **argv)
+{
+ int fd;
+ unsigned int *ptr;
+ char path[PATH_MAX];
+
+ if (argc < 2) {
+ fprintf(stderr, "Usage: path\n");
+ exit(TEST_ERROR);
+ }
+ snprintf(path, sizeof(path), "%s/.", argv[1]);
+
+ if ((fd = open(path, O_RDONLY)) < 0) {
+ fprintf(stderr, "Cannot open ./. : %s\n", strerror(errno));
+ exit(TEST_ERROR);
+ }
+
+ ptr = mmap(NULL, MMAP_LEN, PROT_READ, MAP_PRIVATE, fd, 0);
+ close(fd);
+
+ if (ptr != MAP_FAILED) {
+ /* Should not be able to mmap onto a directory */
+ fprintf(stderr, "mmap() on a directory should produce return "
+ "MAP_FAILED, instead got %p\n", ptr);
+ munmap(ptr, MMAP_LEN);
+ exit(TEST_FAILED);
+ }
+
+ if (errno != ENODEV) {
+ fprintf(stderr, "mmap() on a directory should return ENODEV, "
+ "instead got %d (%s)\n", errno, strerror(errno));
+ exit(TEST_FAILED);
+ }
+
+ exit(TEST_PASSED);
+}
diff --git a/tests/kernel/read-dir.sh b/tests/kernel/read-dir.sh
new file mode 100755
index 0000000..51826ce
--- /dev/null
+++ b/tests/kernel/read-dir.sh
@@ -0,0 +1,48 @@
+#!/bin/bash
+#
+# read-dir: check we cannot read an ecryptfs directory
+# https://bugs.launchpad.net/ubuntu/+source/linux/+bug/719691
+#
+# Author: Colin King <colin.king@canonical.com>
+#
+# Copyright (C) 2012 Canonical, Ltd.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+
+test_script_dir=$(dirname $0)
+rc=1
+test_dir=""
+
+. ${test_script_dir}/../lib/etl_funcs.sh
+
+test_cleanup()
+{
+ etl_remove_test_dir $test_dir
+ etl_umount
+ etl_lumount
+ etl_unlink_keys
+ exit $rc
+}
+trap test_cleanup 0 1 2 3 15
+
+etl_add_keys || exit
+etl_lmount || exit
+etl_mount_i || exit
+test_dir=$(etl_create_test_dir) || exit
+
+${test_script_dir}/read-dir/test ${test_dir}
+
+rc=$?
+exit
diff --git a/tests/kernel/read-dir/test.c b/tests/kernel/read-dir/test.c
new file mode 100644
index 0000000..a24f909
--- /dev/null
+++ b/tests/kernel/read-dir/test.c
@@ -0,0 +1,79 @@
+/*
+ * Author: Colin King <colin.king@canonical.com>
+ *
+ * Copyright (C) 2012 Canonical, Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <limits.h>
+
+#define TEST_PASSED (0)
+#define TEST_FAILED (1)
+#define TEST_ERROR (2)
+
+#define BUFF_SIZE (4096)
+
+/*
+ * https://bugs.launchpad.net/ubuntu/+source/linux/+bug/719691
+ *
+ * read() on a directory should return EISDIR, but bug LP: #719691
+ * ecryptfs returns EINVAL in contradiction to SUSv2.
+ */
+int main(int argc, char **argv)
+{
+ int fd;
+ int ret;
+ char path[PATH_MAX];
+ char buff[BUFF_SIZE];
+
+ if (argc < 2) {
+ fprintf(stderr, "Usage: path\n");
+ exit(TEST_ERROR);
+ }
+ snprintf(path, sizeof(path), "%s/.", argv[1]);
+
+ if ((fd = open(path, O_RDONLY)) < 0) {
+ fprintf(stderr, "Cannot open ./. : %s\n", strerror(errno));
+ exit(TEST_ERROR);
+ }
+
+ ret = read(fd, buff, sizeof(buff));
+ if (ret >= 0) {
+ /* Should not be abled to read a directory */
+ fprintf(stderr, "read() on a directory should fail, but did not\n");
+ close(fd);
+ exit(TEST_FAILED);
+ }
+
+ if (errno != EISDIR) {
+ fprintf(stderr, "read() on a directory should set errno to EISDIR, "
+ "instead got: %d - %s\n", errno, strerror(errno));
+ close(fd);
+ exit(TEST_FAILED);
+ }
+
+ close(fd);
+ exit(TEST_PASSED);
+}
diff --git a/tests/kernel/setattr-flush-dirty.sh b/tests/kernel/setattr-flush-dirty.sh
new file mode 100755
index 0000000..84f53c0
--- /dev/null
+++ b/tests/kernel/setattr-flush-dirty.sh
@@ -0,0 +1,74 @@
+#!/bin/bash
+#
+# setattr-flush-dirty: test flush dirty pages in setattr
+# bug: https://bugzilla.kernel.org/show_bug.cgi?id=33372
+#
+# Author: Colin King <colin.king@canonical.com>
+#
+# Copyright (C) 2012 Canonical, Ltd.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+
+test_script_dir=$(dirname $0)
+test_dir=""
+
+. ${test_script_dir}/../lib/etl_funcs.sh
+
+test_same_timestamp()
+{
+ ts1=`stat -c '%y' $1`
+ ts2=`stat -c '%y' $2`
+
+ if [ "$ts1" != "$ts2" ]; then
+ rc=1
+ fi
+}
+
+test_cleanup()
+{
+ etl_remove_test_dir $test_dir
+ etl_umount
+ etl_lumount
+ etl_unlink_keys
+ exit $rc
+}
+trap test_cleanup 0 1 2 3 15
+
+etl_add_keys || exit
+etl_lmount || exit
+etl_mount_i || exit
+test_dir=$(etl_create_test_dir) || exit
+
+touch ${test_dir}/original
+sync
+sleep 1
+
+rc=0
+#
+# Copy -p preserves the original timestamp, check this works
+#
+cp -p ${test_dir}/original ${test_dir}/copy
+test_same_timestamp ${test_dir}/original ${test_dir}/copy
+
+sync
+#
+# Check that setattr is flushing dirty pages - the copied file
+# timestamp should not have changed after the sync
+#
+test_same_timestamp ${test_dir}/original ${test_dir}/copy
+
+rm -f ${test_dir}/original ${test_dir}/copy
+
+exit
diff --git a/tests/kernel/tests.rc b/tests/kernel/tests.rc
new file mode 100644
index 0000000..269266a
--- /dev/null
+++ b/tests/kernel/tests.rc
@@ -0,0 +1,2 @@
+destructive="miscdev-bad-count.sh extend-file-random.sh trunc-file.sh directory-concurrent.sh file-concurrent.sh lp-994247.sh"
+safe="llseek.sh lp-469664.sh lp-524919.sh lp-509180.sh lp-613873.sh lp-745836.sh lp-870326.sh lp-885744.sh lp-926292.sh inotify.sh mmap-bmap.sh mmap-close.sh mmap-dir.sh read-dir.sh setattr-flush-dirty.sh inode-race-stat.sh lp-1009207.sh enospc.sh lp-911507.sh lp-872905.sh lp-561129.sh mknod.sh link.sh xattr.sh"
diff --git a/tests/kernel/trunc-file.sh b/tests/kernel/trunc-file.sh
new file mode 100755
index 0000000..b0ce88c
--- /dev/null
+++ b/tests/kernel/trunc-file.sh
@@ -0,0 +1,50 @@
+#!/bin/bash
+#
+# trunc-file: Exericse file truncation
+# Author: Colin King <colin.king@canonical.com>
+#
+# Copyright (C) 2012 Canonical, Ltd.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+
+max_blks=16384
+test_script_dir=$(dirname $0)
+rc=1
+test_dir=""
+
+. ${test_script_dir}/../lib/etl_funcs.sh
+
+test_cleanup()
+{
+ etl_remove_test_dir $test_dir
+ etl_umount
+ etl_lumount
+ etl_unlink_keys
+ exit $rc
+}
+trap test_cleanup 0 1 2 3 15
+
+etl_add_keys || exit
+etl_lmount || exit
+etl_mount_i || exit
+test_dir=$(etl_create_test_dir) || exit
+blks=$(etl_lmax_filesize)
+if [ $blks -gt $max_blks ]; then
+ blks=$max_blks
+fi
+${test_script_dir}/trunc-file/test ${test_dir}/test.img $blks
+
+rc=$?
+exit
diff --git a/tests/kernel/trunc-file/test.c b/tests/kernel/trunc-file/test.c
new file mode 100644
index 0000000..0b7c57b
--- /dev/null
+++ b/tests/kernel/trunc-file/test.c
@@ -0,0 +1,278 @@
+/*
+ * Author: Colin King <colin.king@canonical.com>
+ *
+ * Copyright (C) 2012 Canonical, Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <signal.h>
+#include <limits.h>
+
+#define TEST_PASSED (0)
+#define TEST_FAILED (1)
+#define TEST_ERROR (2)
+
+#define SEED (0xdeadbeef)
+#define BUFF_SZ (65536)
+
+#define DEFAULT_SIZE (64*1024)
+
+int write_buff(int fd, unsigned char *data, ssize_t size)
+{
+ unsigned char *ptr = data;
+ ssize_t n;
+ ssize_t sz = size;
+
+ while (sz > 0) {
+ n = write(fd, ptr, sz);
+ if (n < 0)
+ return -1;
+ sz -= n;
+ ptr += n;
+ }
+ return size;
+}
+
+int read_buff(int fd, unsigned char *data, ssize_t size)
+{
+ unsigned char *ptr = data;
+ ssize_t n;
+ ssize_t sz = size;
+
+ while (sz > 0) {
+ n = read(fd, ptr, sz);
+ if (n <= 0)
+ return -1;
+ sz -= n;
+ ptr += n;
+ }
+ return size;
+}
+
+int test_write_random(char *filename, int fd, unsigned char *buff, ssize_t size)
+{
+ ssize_t buflen;
+
+ srandom((unsigned int)SEED);
+ buflen = size;
+ while (buflen > 0) {
+ int j;
+ ssize_t n = (buflen > BUFF_SZ) ? BUFF_SZ : buflen;
+
+ for (j = 0; j < n; j++)
+ buff[j] = random() & 0xff;
+
+ if (write_buff(fd, buff, n) < 0) {
+ close(fd);
+ return -1;
+ }
+ buflen -= n;
+ }
+
+ return 0;
+}
+
+int test_read_random(char *filename, int fd, unsigned char *buff, ssize_t size)
+{
+ ssize_t buflen;
+
+ if (lseek(fd, 0, SEEK_SET) < 0) {
+ fprintf(stderr, "seek failed: %s: %s\n", filename, strerror(errno));
+ return -1;
+ }
+
+ srandom((unsigned int)SEED);
+ buflen = size;
+ while (buflen > 0) {
+ int j;
+ ssize_t n = (buflen > BUFF_SZ) ? BUFF_SZ : buflen;
+
+ if (read_buff(fd, buff, n) < n) {
+ fprintf(stderr, "read failed: %s %s\n", filename, strerror(errno));
+ return -1;
+ }
+
+ for (j = 0; j < n; j++) {
+ unsigned char val = random() & 0xff;
+ if (buff[j] != val) {
+ fprintf(stderr, "Byte %d different from expected value: %d vs %d\n",
+ j, val, buff[j]);
+ return -1;
+ }
+ }
+ buflen -= n;
+ }
+ return 0;
+}
+
+int test_read_rest(char *filename, int fd, unsigned char *buff, ssize_t trunc_size, size_t size)
+{
+ ssize_t buflen;
+
+ if (lseek(fd, trunc_size, SEEK_SET) < 0) {
+ fprintf(stderr, "seek failed: %s: %s\n", filename, strerror(errno));
+ return -1;
+ }
+
+ buflen = size - trunc_size;
+ while (buflen > 0) {
+ int j;
+ ssize_t n = (buflen > BUFF_SZ) ? BUFF_SZ : buflen;
+
+ if (read_buff(fd, buff, n) < n) {
+ fprintf(stderr, "read failed: %s %s\n", filename, strerror(errno));
+ return -1;
+ }
+
+ for (j = 0; j < n; j++) {
+ if (buff[j] != 0) {
+ fprintf(stderr, "Byte %d different from expected value: %d vs %d\n",
+ j, 0, buff[j]);
+ return -1;
+ }
+ }
+ buflen -= n;
+ }
+ return 0;
+}
+
+int test_exercise(char *filename, ssize_t size)
+{
+ int fd;
+ int ret = TEST_FAILED;
+ ssize_t trunc_size = size / 2;
+ struct stat statbuf;
+
+ unsigned char buff[BUFF_SZ];
+
+ unlink(filename);
+ if ((fd = open(filename, O_RDWR | O_CREAT, 0600)) < 0) {
+ fprintf(stderr, "Failed to open %s: %s\n", filename, strerror(errno));
+ return TEST_FAILED;
+ }
+
+ /* Fill with random data */
+ if (test_write_random(filename, fd, buff, size) < 0)
+ goto done;
+
+ /* Read it back sanity check */
+ if (test_read_random(filename, fd, buff, size) < 0)
+ goto done;
+
+ /* Iteratively truncate file down */
+ while (trunc_size > 0) {
+ /* Truncate */
+ if (ftruncate(fd, (off_t)trunc_size) < 0) {
+ fprintf(stderr, "ftruncate failed: %s %s\n", filename, strerror(errno));
+ goto done;
+ }
+
+ /* Read check the truncated data again */
+ if (test_read_random(filename, fd, buff, trunc_size) < 0)
+ goto done;
+
+ /* Check the size */
+ if (fstat(fd, &statbuf) < 0) {
+ fprintf(stderr, "fstat failed: %s %s\n", filename, strerror(errno));
+ goto done;
+ }
+ if (statbuf.st_size != (off_t)trunc_size) {
+ fprintf(stderr, "truncated file size incorrect, got %lu, expected %lu\n",
+ (unsigned long)statbuf.st_size, (unsigned long)trunc_size);
+ goto done;
+ }
+
+ /* Extend to full size using truncate, end is now zero */
+ if (ftruncate(fd, (off_t)size) < 0) {
+ fprintf(stderr, "ftruncate failed: %s %s\n", filename, strerror(errno));
+ goto done;
+ }
+
+ /* Check the size */
+ if (fstat(fd, &statbuf) < 0) {
+ fprintf(stderr, "fstat failed: %s %s\n", filename, strerror(errno));
+ goto done;
+ }
+ if (statbuf.st_size != (off_t)size) {
+ fprintf(stderr, "truncated file size incorrect, got %lu, expected %lu\n",
+ (unsigned long)statbuf.st_size, (unsigned long)size);
+ goto done;
+ }
+
+ /* Check the first chunk */
+ if (test_read_random(filename, fd, buff, trunc_size) < 0)
+ goto done;
+ /* Check the end is all zero */
+ if (test_read_rest(filename, fd, buff, trunc_size, size) < 0)
+ goto done;
+
+ trunc_size >>= 1;
+ }
+
+ ret = TEST_PASSED;
+
+done:
+ if (close(fd) < 0) {
+ fprintf(stderr, "close failed: %s: %s\n", filename, strerror(errno));
+ return TEST_FAILED;
+ }
+
+ if (unlink(filename) < 0) {
+ fprintf(stderr, "unlink failed: %s: %s\n", filename, strerror(errno));
+ return TEST_FAILED;
+ }
+
+ return ret;
+}
+
+void sighandler(int dummy)
+{
+ exit(TEST_ERROR);
+}
+
+int main(int argc, char **argv)
+{
+ ssize_t len = DEFAULT_SIZE;
+ const ssize_t max_len = SSIZE_MAX / 1024;
+
+ if (argc < 2) {
+ fprintf(stderr, "Syntax: %s filename [size_in_K]\n", argv[0]);
+ exit(TEST_ERROR);
+ }
+
+ if (argc == 3) {
+ len = atoll(argv[2]);
+ if (len < 1) {
+ fprintf(stderr, "size should be > 0\n");
+ exit(TEST_ERROR);
+ }
+ }
+
+ if (len > max_len) {
+ fprintf(stderr, "size should be < %zd\n", max_len);
+ exit(TEST_ERROR);
+ }
+ signal(SIGINT, sighandler);
+
+ exit(test_exercise(argv[1], len * 1024));
+}
diff --git a/tests/kernel/xattr/test.c b/tests/kernel/xattr/test.c
new file mode 100644
index 0000000..a552fbc
--- /dev/null
+++ b/tests/kernel/xattr/test.c
@@ -0,0 +1,111 @@
+/*
+ * Author: Colin King <colin.king@canonical.com>
+ *
+ * Copyright (C) 2013 Canonical, Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/xattr.h>
+
+static const char *names[] = {
+ "user.test1",
+ "user.test2",
+ "user.test3",
+ NULL
+};
+
+static const char *values[] = {
+ "test value #1",
+ "test value #2",
+ "test value #3",
+ NULL
+};
+
+int main(int argc, char **argv)
+{
+ ssize_t len, names_len = 0;
+ int i, rc;
+ char buffer[1024];
+ char *ptr = buffer;
+
+ if (argc != 2) {
+ fprintf(stderr, "Usage: %s file\n", argv[0]);
+ exit(EXIT_FAILURE);
+ }
+
+ for (i = 0; names[i]; i++) {
+ if (setxattr(argv[1], names[i], values[i], strlen(values[i]), 0) < 0)
+ exit(EXIT_FAILURE);
+ names_len += 1 + strlen(names[i]);
+ }
+
+ /*
+ * Sanity check that listxattr returns correct length
+ */
+ len = listxattr(argv[1], NULL, 0);
+ if (len != names_len)
+ exit(EXIT_FAILURE);
+
+ len = listxattr(argv[1], buffer, sizeof(buffer));
+ if (len < 0)
+ exit(EXIT_FAILURE);
+
+ /*
+ * Check listxattr names match what has been just set
+ */
+ for (i = 0; names[i]; i++) {
+ if (strcmp(names[i], ptr))
+ exit(EXIT_FAILURE);
+ ptr += strlen(ptr) + 1;
+ }
+
+ /*
+ * Check contents of xattr
+ */
+ for (i = 0; names[i]; i++) {
+ len = getxattr(argv[1], names[i], buffer, sizeof(buffer));
+ if (len < 0)
+ exit(EXIT_FAILURE);
+ buffer[len] = '\0';
+
+ if (strcmp(values[i], buffer))
+ exit(EXIT_FAILURE);
+ }
+
+ /*
+ * Remove xattr
+ */
+ for (i = 0; names[i]; i++) {
+ rc = removexattr(argv[1], names[i]);
+ if (rc < 0)
+ exit(EXIT_FAILURE);
+ }
+
+ /*
+ * ..and there should be no xattrs left
+ */
+ len = listxattr(argv[1], NULL, 0);
+ if (len != 0)
+ exit(EXIT_FAILURE);
+
+ exit(EXIT_SUCCESS);
+}
diff --git a/tests/lib/Makefile.am b/tests/lib/Makefile.am
new file mode 100644
index 0000000..ea68c1f
--- /dev/null
+++ b/tests/lib/Makefile.am
@@ -0,0 +1,5 @@
+dist_noinst_SCRIPTS = etl_funcs.sh
+noinst_PROGRAMS = etl-add-passphrase-key-to-keyring
+
+etl_add_passphrase_key_to_keyring_SOURCES = etl_add_passphrase_key_to_keyring.c
+etl_add_passphrase_key_to_keyring_LDADD = $(top_builddir)/src/libecryptfs/libecryptfs.la
diff --git a/tests/lib/Makefile.in b/tests/lib/Makefile.in
new file mode 100644
index 0000000..2a431ae
--- /dev/null
+++ b/tests/lib/Makefile.in
@@ -0,0 +1,667 @@
+# Makefile.in generated by automake 1.13.3 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+
+VPATH = @srcdir@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+noinst_PROGRAMS = etl-add-passphrase-key-to-keyring$(EXEEXT)
+subdir = tests/lib
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+ $(dist_noinst_SCRIPTS) $(top_srcdir)/depcomp
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/ac_pkg_swig.m4 \
+ $(top_srcdir)/m4/ac_python_devel.m4 \
+ $(top_srcdir)/m4/intltool.m4 $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/swig_python.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+PROGRAMS = $(noinst_PROGRAMS)
+am_etl_add_passphrase_key_to_keyring_OBJECTS = \
+ etl_add_passphrase_key_to_keyring.$(OBJEXT)
+etl_add_passphrase_key_to_keyring_OBJECTS = \
+ $(am_etl_add_passphrase_key_to_keyring_OBJECTS)
+etl_add_passphrase_key_to_keyring_DEPENDENCIES = \
+ $(top_builddir)/src/libecryptfs/libecryptfs.la
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+SCRIPTS = $(dist_noinst_SCRIPTS)
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = $(etl_add_passphrase_key_to_keyring_SOURCES)
+DIST_SOURCES = $(etl_add_passphrase_key_to_keyring_SOURCES)
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALL_LINGUAS = @ALL_LINGUAS@
+AMTAR = @AMTAR@
+AM_CPPFLAGS = @AM_CPPFLAGS@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CATALOGS = @CATALOGS@
+CATOBJEXT = @CATOBJEXT@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CRYPTO_CFLAGS = @CRYPTO_CFLAGS@
+CRYPTO_LIBS = @CRYPTO_LIBS@
+CYGPATH_W = @CYGPATH_W@
+DATADIRNAME = @DATADIRNAME@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+DVIPS = @DVIPS@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
+GMOFILES = @GMOFILES@
+GMSGFMT = @GMSGFMT@
+GPGME_CFLAGS = @GPGME_CFLAGS@
+GPGME_LIBS = @GPGME_LIBS@
+GREP = @GREP@
+GTK_CFLAGS = @GTK_CFLAGS@
+GTK_LIBS = @GTK_LIBS@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INSTOBJEXT = @INSTOBJEXT@
+INTLLIBS = @INTLLIBS@
+INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@
+INTLTOOL_MERGE = @INTLTOOL_MERGE@
+INTLTOOL_PERL = @INTLTOOL_PERL@
+INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
+INTLTOOL_V_MERGE = @INTLTOOL_V_MERGE@
+INTLTOOL_V_MERGE_OPTIONS = @INTLTOOL_V_MERGE_OPTIONS@
+INTLTOOL__v_MERGE_ = @INTLTOOL__v_MERGE_@
+INTLTOOL__v_MERGE_0 = @INTLTOOL__v_MERGE_0@
+KEYUTILS_CFLAGS = @KEYUTILS_CFLAGS@
+KEYUTILS_LIBS = @KEYUTILS_LIBS@
+LATEX = @LATEX@
+LATEX2HTML = @LATEX2HTML@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBECRYPTFS_LT_AGE = @LIBECRYPTFS_LT_AGE@
+LIBECRYPTFS_LT_CURRENT = @LIBECRYPTFS_LT_CURRENT@
+LIBECRYPTFS_LT_REVISION = @LIBECRYPTFS_LT_REVISION@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LOCALEDIR = @LOCALEDIR@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+MSGFMT = @MSGFMT@
+MSGFMT_OPTS = @MSGFMT_OPTS@
+MSGMERGE = @MSGMERGE@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NSS_CFLAGS = @NSS_CFLAGS@
+NSS_LIBS = @NSS_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OPENSSL_CFLAGS = @OPENSSL_CFLAGS@
+OPENSSL_LIBS = @OPENSSL_LIBS@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PAM_CFLAGS = @PAM_CFLAGS@
+PAM_LIBS = @PAM_LIBS@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKCS11_HELPER_CFLAGS = @PKCS11_HELPER_CFLAGS@
+PKCS11_HELPER_LIBS = @PKCS11_HELPER_LIBS@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+POD2MAN = @POD2MAN@
+POFILES = @POFILES@
+POSUB = @POSUB@
+PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@
+PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@
+PS2PDF = @PS2PDF@
+PYTHON = @PYTHON@
+PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@
+PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@
+PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@
+PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
+PYTHON_PLATFORM = @PYTHON_PLATFORM@
+PYTHON_PREFIX = @PYTHON_PREFIX@
+PYTHON_SITE_PKG = @PYTHON_SITE_PKG@
+PYTHON_VERSION = @PYTHON_VERSION@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+SWIG = @SWIG@
+SWIG_LIB = @SWIG_LIB@
+SWIG_PYTHON_CPPFLAGS = @SWIG_PYTHON_CPPFLAGS@
+SWIG_PYTHON_OPT = @SWIG_PYTHON_OPT@
+TAR = @TAR@
+TSPI_CFLAGS = @TSPI_CFLAGS@
+TSPI_LIBS = @TSPI_LIBS@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+XGETTEXT = @XGETTEXT@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+ecryptfskeymoddir = @ecryptfskeymoddir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+intltool__v_merge_options_ = @intltool__v_merge_options_@
+intltool__v_merge_options_0 = @intltool__v_merge_options_0@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pamdir = @pamdir@
+pamlibdir = @pamlibdir@
+pdfdir = @pdfdir@
+pkgconfigdir = @pkgconfigdir@
+pkgpyexecdir = @pkgpyexecdir@
+pkgpythondir = @pkgpythondir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+pyexecdir = @pyexecdir@
+pythondir = @pythondir@
+rootsbindir = @rootsbindir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+dist_noinst_SCRIPTS = etl_funcs.sh
+etl_add_passphrase_key_to_keyring_SOURCES = etl_add_passphrase_key_to_keyring.c
+etl_add_passphrase_key_to_keyring_LDADD = $(top_builddir)/src/libecryptfs/libecryptfs.la
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tests/lib/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign tests/lib/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-noinstPROGRAMS:
+ @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+
+etl-add-passphrase-key-to-keyring$(EXEEXT): $(etl_add_passphrase_key_to_keyring_OBJECTS) $(etl_add_passphrase_key_to_keyring_DEPENDENCIES) $(EXTRA_etl_add_passphrase_key_to_keyring_DEPENDENCIES)
+ @rm -f etl-add-passphrase-key-to-keyring$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(etl_add_passphrase_key_to_keyring_OBJECTS) $(etl_add_passphrase_key_to_keyring_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/etl_add_passphrase_key_to_keyring.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(PROGRAMS) $(SCRIPTS)
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-noinstPROGRAMS cscopelist-am ctags \
+ ctags-am distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-pdf install-pdf-am \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags tags-am uninstall uninstall-am
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/tests/lib/etl_add_passphrase_key_to_keyring.c b/tests/lib/etl_add_passphrase_key_to_keyring.c
new file mode 100644
index 0000000..2a9c265
--- /dev/null
+++ b/tests/lib/etl_add_passphrase_key_to_keyring.c
@@ -0,0 +1,50 @@
+/**
+ * etl_add_passphrase_key_to_keyring: C bindings for libecryptfs's
+ * ecryptfs_add_passphrase_key_to_keyring() function
+ * Author: Tyler Hicks <tyhicks@canonical.com>
+ *
+ * Copyright (C) 2012 Canonical, Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
+ */
+
+#include <errno.h>
+#include <stdio.h>
+#include "../../src/include/ecryptfs.h"
+
+int main(int argc, char *argv[])
+{
+ char auth_tok_sig_hex[ECRYPTFS_SIG_SIZE_HEX + 1];
+ char salt[ECRYPTFS_SALT_SIZE + 1];
+ int rc;
+
+ if (argc != 3) {
+ fprintf(stderr, "%s PASSPHRASE SALT_HEX\n", argv[0]);
+ return EINVAL;
+ }
+
+ from_hex(salt, argv[2], ECRYPTFS_SALT_SIZE);
+ rc = ecryptfs_add_passphrase_key_to_keyring(auth_tok_sig_hex, argv[1],
+ salt);
+ /* If the key is already added to the keyring, 1 is returned */
+ if (rc == 1)
+ rc = 0;
+ if (!rc)
+ printf("%s\n", auth_tok_sig_hex);
+
+ return rc;
+}
+
diff --git a/tests/lib/etl_funcs.sh b/tests/lib/etl_funcs.sh
new file mode 100644
index 0000000..7803008
--- /dev/null
+++ b/tests/lib/etl_funcs.sh
@@ -0,0 +1,601 @@
+#!/bin/bash
+#
+# etl_funcs.sh: eCryptfs test library (etl) helper functions
+# Author: Tyler Hicks <tyhicks@canonical.com>
+#
+# Copyright (C) 2012 Canonical Ltd.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation version 2
+# of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+
+etl=$(dirname $BASH_SOURCE[0])
+
+default_fekek_pass="foo"
+default_fekek_salt_hex="0011223344556677"
+
+default_fnek_pass="$default_fekek_pass"
+default_fnek_salt_hex="9988776655443322"
+
+default_lfs="ext4"
+default_lmount_opts="rw,relatime"
+default_ext2_opts="user_xattr,acl"
+default_ext3_opts="user_xattr,acl,commit=600,barrier=1,data=ordered"
+default_btrfs_opts="nodatacow"
+default_mount_opts="rw,relatime,ecryptfs_cipher=aes,ecryptfs_key_bytes=16,ecryptfs_sig=\${ETL_FEKEK_SIG}"
+default_fne_mount_opts="${default_mount_opts},ecryptfs_fnek_sig=\${ETL_FNEK_SIG}"
+
+
+#
+# etl_add_fekek_passphrase [PASS] [SALT_HEX]
+#
+# Adds a passphrase-based file encryption key to the kernel keyring. A default
+# PASS and SALT_HEX will be used if they are not specified. The key signature
+# is exported into ETL_FEKEK_SIG upon success.
+#
+# Only call this directly if your test needs to add a specific fekek.
+#
+etl_add_fekek_passphrase()
+{
+ if [ -z "$1" ]; then
+ pass=$default_fekek_pass
+ else
+ pass=$1
+ fi
+ if [ -z "$2" ]; then
+ salt_hex=$default_fekek_salt_hex
+ else
+ salt_hex=$2
+ fi
+
+ sig=$(${etl}/etl-add-passphrase-key-to-keyring $pass $salt_hex)
+ if [ $? -ne 0 ]; then
+ return 1
+ fi
+
+ export ETL_FEKEK_SIG=$sig
+ return 0
+}
+
+#
+# etl_add_fnek_passphrase [PASS] [SALT_HEX]
+#
+# Adds a passphrase-based filename encryption key to the kernel keyring. A
+# default PASS and SALT_HEX will be used if they are not specified. The key
+# signature is exported into ETL_FNEK_SIG upon success.
+#
+# Only call this directly if your test needs to add a specific fnek.
+#
+etl_add_fnek_passphrase()
+{
+ if [ -z "$1" ]; then
+ pass=$default_fnek_pass
+ else
+ pass=$1
+ fi
+ if [ -z "$2" ]; then
+ salt_hex=$default_fnek_salt_hex
+ else
+ salt_hex=$2
+ fi
+
+ sig=$(${etl}/etl-add-passphrase-key-to-keyring $pass $salt_hex)
+ if [ $? -ne 0 ]; then
+ return 1
+ fi
+
+ export ETL_FNEK_SIG=$sig
+ return 0
+}
+
+#
+# etl_add_keys
+#
+# Adds a fekek and, if appropriate, a fnek to the kernel keyring using the
+# default values defined above. Most test cases requiring a generic mount will
+# use this rather than the lower level functions that this calls.
+#
+# Set ETL_TEST_FNE to true if you want filename encryption enabled (it is best
+# to lest the test harness handle that). ETL_FEKEK_SIG and, if appropriate,
+# ETL_FNEK_SIG will contain the key signatures upon success.
+#
+etl_add_keys()
+{
+ # TODO: This should support non-passphrase based keys, too
+
+ etl_add_fekek_passphrase
+ if [ $? -ne 0 ]; then
+ return 1
+ fi
+
+ if $ETL_TEST_FNE ; then
+ etl_add_fnek_passphrase
+ return $?
+ fi
+
+ return 0
+}
+
+#
+# etl_unlink_key_sig SIGNATURE
+#
+# Unlinks the key corresponding to the specified signature.
+#
+etl_unlink_key_sig()
+{
+ if [ -z "$1" ]; then
+ return 1
+ fi
+
+ show_line=$(keyctl list @u | grep -s $1)
+ if [ $? -ne 0 ]; then
+ return 1
+ fi
+
+ key=$(printf $show_line | awk -F ':' '{ print $1 }')
+ keyctl unlink $key &>/dev/null
+}
+
+#
+# etl_unlink_fekek
+#
+# Unlinks the key corresponding to the value of ETL_FEKEK_SIG. Unsets
+# that variable upon success.
+#
+etl_unlink_fekek()
+{
+ if [ -z "$ETL_FEKEK_SIG" ]; then
+ return 1
+ fi
+
+ etl_unlink_key_sig $ETL_FEKEK_SIG
+ if [ $? -ne 0 ]; then
+ return 1
+ fi
+
+ unset ETL_FEKEK_SIG
+}
+
+#
+# etl_unlink_fnek
+#
+# Unlinks the key corresponding to the value of ETL_FNEK_SIG. Unsets
+# that variable upon success.
+#
+etl_unlink_fnek()
+{
+ if [ -z "$ETL_FNEK_SIG" ]; then
+ return 1
+ fi
+
+ etl_unlink_key_sig $ETL_FNEK_SIG
+ if [ $? -ne 0 ]; then
+ return 1
+ fi
+
+ unset ETL_FNEK_SIG
+}
+
+#
+# etl_unlink_keys
+#
+# Unlinks the fekek and, if appropriate, the fnek from the kernel keyring. See
+# the functions called by etl_unlink_keys() for more information.
+#
+# Most test cases requiring a generic mount will use this rather than the lower
+# level functions that this calls.
+#
+etl_unlink_keys()
+{
+ etl_unlink_fekek
+ if [ $? -ne 0 ]; then
+ return 1
+ fi
+
+ if $ETL_TEST_FNE ; then
+ etl_unlink_fnek
+ return $?
+ fi
+
+ return 0
+}
+
+#
+# etl_create_disk DISK_SIZE [DIR_PATH]
+#
+# Creates a disk image for testing. This disk image will be formatted and ready
+# for mounting as the lower filesystem.
+#
+# DISK_SIZE must be specified in 1K block sizes. DIR_PATH can be specified so
+# that the image file is stored somewhere other than the /tmp/ directory.
+#
+etl_create_disk()
+{
+ if [ -z "$1" ]; then
+ return 1
+ fi
+ if [ -z "$2" ]; then
+ dir_path="/tmp"
+ else
+ dir_path="$2"
+ fi
+ if [ -z "$ETL_LFS" ]; then
+ lfs=$default_lfs
+ else
+ lfs=$ETL_LFS
+ fi
+
+ img=$(mktemp -q /${dir_path}/etl-img-XXXXXXXXXX)
+ if [ $? -ne 0 ]; then
+ return 1
+ fi
+
+ dd if=/dev/zero of=$img bs=1024 count=$1 &>/dev/null
+ if [ $? -ne 0 ]; then
+ rm $img &>/dev/null
+ return 1
+ fi
+
+ case $lfs in
+ ext2|ext3|ext4)
+ mkfs_force='-F'
+ ;;
+ xfs)
+ mkfs_force='-f'
+ ;;
+ *)
+ mkfs_force=''
+ ;;
+ esac
+
+ mkfs -t $lfs $mkfs_force $img &>/dev/null
+ if [ $? -ne 0 ]; then
+ rm $img &>/dev/null
+ return 1
+ fi
+
+ export ETL_DISK=$img
+ export ETL_LMOUNT_SRC=$img
+ export ETL_LFS=$lfs
+}
+
+#
+# etl_remove_disk
+#
+# Removes any lower test disk created by etl_create_disk().
+#
+etl_remove_disk()
+{
+ if [ -z "$ETL_DISK" ] || [ ! -f "$ETL_DISK" ]; then
+ return 1
+ fi
+ if grep -q $ETL_DISK /proc/mounts; then
+ return 1
+ fi
+
+ rm -f $ETL_DISK &>/dev/null
+ unset ETL_DISK
+}
+
+#
+# etl_load_ecryptfs
+#
+# Ensures that the eCryptfs kernel code is either loaded, if a module, or
+# compiled in.
+#
+# If your test only needs an eCryptfs mount, don't call this function. The mount
+# process will autoload the module for you. If you need access to something like
+# /dev/ecryptfs, but don't need an eCryptfs mount, this function is for you.
+#
+etl_load_ecryptfs()
+{
+ if ! grep -q ecryptfs /proc/filesystems; then
+ modprobe ecryptfs
+ return $?
+ fi
+
+ return 0
+}
+
+#
+# etl_construct_lmount_opts
+#
+# Construct the lower filesystem mount options. If mount options are already
+# set, nothing is done. Otherwise, the default mount options for the lower
+# filesystem are set.
+#
+# If you need specific options, you should probably construct them yourself and
+# simply export them as ETL_LMOUNT_OPTS. This function is mostly a helper for
+# other etl functions.
+#
+etl_construct_lmount_opts()
+{
+ if [ -n "$ETL_LMOUNT_OPTS" ]; then
+ return 0
+ fi
+ if [ -z "$ETL_LFS" ]; then
+ export ETL_LFS=$default_lfs
+ fi
+
+ # TODO: Add support for more filesystems
+ case $ETL_LFS in
+ ext2)
+ lmount_opts=${default_lmount_opts},${default_ext2_opts}
+ ;;
+ ext3|ext4)
+ lmount_opts=${default_lmount_opts},${default_ext3_opts}
+ ;;
+ btrfs)
+ lmount_opts=${default_lmount_opts},${default_btrfs_opts}
+ ;;
+ *)
+ lmount_opts=$default_lmount_opts
+ ;;
+ esac
+
+ if [ -f "$ETL_LMOUNT_SRC" ]; then
+ lmount_opts="${lmount_opts},loop"
+ fi
+
+ export ETL_LMOUNT_OPTS=$lmount_opts
+ return 0
+}
+
+#
+# etl_lmount
+#
+# Mounts the lower filesystem based upon the various env variables.
+#
+etl_lmount()
+{
+ if [ -z "$ETL_LMOUNT_SRC" ] || [ -z "$ETL_LMOUNT_DST" ]; then
+ return 1
+ fi
+ if ! etl_construct_lmount_opts; then
+ return 1
+ fi
+
+ mount -t "$ETL_LFS" -o "$ETL_LMOUNT_OPTS" \
+ "$ETL_LMOUNT_SRC" "$ETL_LMOUNT_DST" &>/dev/null
+}
+
+#
+# etl_lumount
+#
+# Unmounts the lower filesystem.
+#
+etl_lumount()
+{
+ if [ -z "$ETL_LMOUNT_SRC" ]; then
+ return 1
+ fi
+
+ sync
+ umount "$ETL_LMOUNT_DST" &>/dev/null
+}
+
+#
+# etl_lmax_filesize
+#
+# Estimate on largest file that one can
+# create in the lower filesystem.
+#
+etl_lmax_filesize()
+{
+ blks=$(df --total $ETL_LMOUNT_DST | tail -1 | awk '{print $4}')
+
+ case $ETL_LFS in
+ btrfs)
+ # btrfs is a pain, since there is a big difference between the
+ # amount of free space it reports and the maximum size of a file
+ # one can produce before filling up the partition, especially
+ # with small partitions. So instead we divide by 4 to ensure
+ # we have more than enough free space.
+ #
+ blks=$((blks / 4))
+ ;;
+ xfs)
+ # xfs misbehaves on small file systems when we truncate, according to
+ # david@fromorbit.com:
+ #
+ # "The space is considered "busy" and won't be reused until the
+ # truncate transaction hits the log and the space is free on disk. See
+ # xfs_busy_extent.c
+ #
+ # Basically, testing XFS performance on tiny filesystems is going to
+ # show false behaviours. XFS is optimised for large filesystems and
+ # will typically shows low space artifacts on small filesystems,
+ # especially when you are doing things like filling most of the free
+ # filesystem space with 1 file.
+ #
+ # e.g. 1GB free on at 100TB filesystem will throttle behaviours (say
+ # speculative preallocation) much more effectively because itis within
+ # 1% of ENOSPC. That same 1GB free on a 1GB filesystem won't throttle
+ # preallocation at all, and so that one file when it reaches a little
+ # over 500MB will try to preallocate half the remaining space in the
+ # filesystem because the filesystem is only 50% full...."
+ #
+ # So lets limit ourselves generously by using just 33% for 'small'
+ # xfs file systems to leave plenty of slop and 50% for larger xfs
+ # file systems.
+ #
+ if [ $blks -lt 5000000 ]; then
+ blks=$((blks / 3))
+ else
+ blks=$((blks / 2))
+ fi
+ ;;
+ *)
+ #
+ # for other file systems we take off ~5% for some slop
+ #
+ slop=$((blks / 20))
+ blks=$((blks - $slop))
+ ;;
+ esac
+
+ echo $blks
+}
+
+#
+# etl_mount_i
+#
+# Performs an eCryptfs mount, bypassing the eCryptfs mount helper.
+#
+# If you're fine with the default eCryptfs mount options, or have constructed
+# your own mount options, and have already added the appropriate keys to the
+# kernel keyring, this is the easiest way to do an eCryptfs mount.
+#
+etl_mount_i()
+{
+ if [ -z "$ETL_MOUNT_SRC" ] || [ -z "$ETL_MOUNT_DST" ]; then
+ return 1
+ fi
+ if [ -z "$ETL_MOUNT_OPTS" ]; then
+ if [ -n "ETL_FNEK_SIG" ]; then
+ export ETL_MOUNT_OPTS=$(eval \
+ "echo $default_fne_mount_opts")
+ else
+ export ETL_MOUNT_OPTS=$(eval "echo $default_mount_opts")
+ fi
+ fi
+
+ mount -it ecryptfs -o "$ETL_MOUNT_OPTS" \
+ "$ETL_MOUNT_SRC" "$ETL_MOUNT_DST"
+}
+
+#
+# etl_umount_i
+#
+# Unmounts the eCryptfs mount point specified by ETL_MOUNT_DST. Note that the
+# eCryptfs umount helper will not be called.
+#
+etl_umount_i()
+{
+ if [ -z "$ETL_MOUNT_DST" ]; then
+ return 1
+ fi
+
+ if ! grep -q $ETL_MOUNT_DST /proc/mounts; then
+ return 1
+ fi
+
+ sync
+ umount -i "$ETL_MOUNT_DST" &>/dev/null
+}
+
+#
+# etl_umount
+#
+# Unmounts the eCryptfs mount point specified by ETL_MOUNT_DST. Note that the
+# eCryptfs umount helper will be called.
+#
+etl_umount()
+{
+ if [ -z "$ETL_MOUNT_DST" ]; then
+ return 1
+ fi
+
+ if ! grep -q $ETL_MOUNT_DST /proc/mounts; then
+ return 1
+ fi
+
+ sync
+ umount "$ETL_MOUNT_DST" &>/dev/null
+}
+
+#
+# etl_create_test_dir
+#
+# Creates a directory for carrying out tests inside of the eCryptfs mount point
+# (ETL_MOUNT_DST).
+#
+# Upon success, the newly created directory's name is echoed to stdout.
+#
+etl_create_test_dir()
+{
+ parent=
+
+ if [ -z "$ETL_MOUNT_DST" ] && [ -z "$1" ]; then
+ return 1
+ fi
+
+ if [ -z "$1" ]; then
+ parent=$ETL_MOUNT_DST
+ else
+ parent=$1
+ fi
+ test_basename=$(basename $0)
+ test_dir=$(mktemp -qd ${parent}/etl-${test_basename}-XXXXXXXXXX)
+ if [ $? -ne 0 ]; then
+ return 1;
+ fi
+
+ echo $test_dir
+ return 0
+}
+
+#
+# etl_remove_test_dir TEST_DIR
+#
+# Removes the specified test directory.
+#
+# For now, it is nothing much more than a wrapper around rm -rf, but it may
+# gain more functionality and/or safety checks in the future, so please use it.
+#
+etl_remove_test_dir()
+{
+ if [ -z "$1" ]; then
+ return 0
+ elif [ ! -d "$1" ]; then
+ return 1
+ elif [ "$1" = "/" ]; then
+ return 1
+ fi
+
+ rm -rf $1 &>/dev/null
+}
+
+#
+# etl_find_lower_path UPPER_PATH [LOWER_MOUNT]
+#
+# Given a path to an eCryptfs inode, finds a path to the lower inode. Searches
+# for the lower inode in $ETL_LMOUNT_DST, unless LOWER_MOUNT is specified. Be
+# careful using this with an inode with multiple hard links, as only one lower
+# path will be returned.
+#
+# Upon success, the lower path is echoed to stdout and zero is returned.
+#
+etl_find_lower_path()
+{
+ lmount=$ETL_LMOUNT_DST
+ if [ -n "$2" ]; then
+ lmount=$2
+ fi
+ if [ -z "lmount" ]; then
+ return 1
+ fi
+
+ inum=$(stat --printf=%i $1)
+ if [ $? -ne 0 ]; then
+ return 1
+ fi
+
+ lower_path=$(find $lmount -inum $inum -print -quit 2>/dev/null)
+ if [ $? -ne 0 ] || [ -z "$lower_path" ]; then
+ return 1
+ fi
+
+ echo $lower_path
+ return 0
+}
diff --git a/tests/new.sh b/tests/new.sh
new file mode 100755
index 0000000..e17e879
--- /dev/null
+++ b/tests/new.sh
@@ -0,0 +1,36 @@
+#!/bin/bash
+#
+# FILENAME: Test for BUG_URL|LIST_URL|DESCRIPTION
+# Author: FIRST LAST <USER@DOMAIN>
+#
+# Copyright (C) 2012 COPYRIGHT_HOLDER
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation version 2
+# of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+
+test_script_dir=$(dirname $0)
+rc=1
+
+. ${test_script_dir}/../lib/etl_funcs.sh
+
+test_cleanup()
+{
+ exit $rc
+}
+trap test_cleanup 0 1 2 3 15
+
+# TEST
+
+rc=$?
+exit
diff --git a/tests/run_tests.sh b/tests/run_tests.sh
new file mode 100755
index 0000000..fe45250
--- /dev/null
+++ b/tests/run_tests.sh
@@ -0,0 +1,348 @@
+#!/bin/bash
+#
+# eCryptfs test suite harness
+# Author: Tyler Hicks <tyhicks@canonical.com>
+#
+# Copyright (C) 2012 Canonical, Ltd.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+#
+# Example usage:
+#
+# # ./tests/run_tests.sh -K -c destructive -d /dev/vdb -l /lower -u /upper
+#
+# This would run kernel tests in the destructive category, as defined in
+# kernel/tests.rc. /dev/vdb would be the block device containing the lower
+# filesystem, which would be mounted at /lower. The eCryptfs mount point would
+# be /upper.
+#
+
+run_tests_dir=$(dirname $0)
+rc=1
+
+. ${run_tests_dir}/lib/etl_funcs.sh
+
+blocks=0
+categories=""
+cleanup_lower_mnt=0
+cleanup_upper_mnt=0
+default_lower_fses="ext4"
+device=""
+disk_dir=""
+failed=0
+kernel=false
+ktests=""
+lower_fses=""
+lower_mnt=""
+passed=0
+tests=""
+upper_mnt=""
+userspace=false
+utests=""
+
+run_tests_cleanup()
+{
+ if [ $cleanup_upper_mnt -ne 0 ] && [ -n "$upper_mnt" ]; then
+ rm -rf "$upper_mnt"
+ fi
+ if [ $cleanup_lower_mnt -ne 0 ] && [ -n "$lower_mnt" ]; then
+ rm -rf "$lower_mnt"
+ fi
+ etl_remove_disk
+ exit $rc
+}
+trap run_tests_cleanup 0 1 2 3 15
+
+run_tests()
+{
+ test_dir=$1
+ tests=$2
+
+ for etest in $tests; do
+ printf "%-16s\t" $(basename "$etest" .sh)
+
+ ${test_dir}/${etest}
+ if [ $? -ne 0 ]; then
+ ((failed++))
+ printf "FAIL\n"
+ else
+ ((passed++))
+ printf "pass\n"
+ fi
+ done
+}
+
+run_kernel_tests_on_existing_device()
+{
+ echo "Running eCryptfs filesystem tests"
+
+ run_tests "${run_tests_dir}/kernel" "$ktests"
+ if [ $? -ne 0 ]; then
+ echo "Failed to run eCryptfs filesystem tests" 1>&2
+ rc=1
+ exit
+ fi
+
+ if [ -n "$ETL_DISK" ]; then
+ etl_remove_disk
+ fi
+}
+
+run_kernel_tests_on_created_disk_image()
+{
+ lower_fses=$(echo $lower_fses | tr ',' ' ')
+ for lower_fs in $lower_fses; do
+ echo "Running eCryptfs filesystem tests on $lower_fs"
+
+ if [ "$blocks" -gt 0 ]; then
+ export ETL_LFS=$lower_fs
+ etl_create_disk $blocks $disk_dir
+ if [ $? -ne 0 ]; then
+ echo "Failed to create disk for $lower_fs"\
+ "(skipping all tests on $lower_fs)" 1>&2
+ continue
+ fi
+ export ETL_LMOUNT_SRC=$ETL_DISK
+ fi
+
+ run_tests "${run_tests_dir}/kernel" "$ktests"
+ if [ $? -ne 0 ]; then
+ echo "Failed to run eCryptfs filesystem tests on"\
+ "$lower_fs" 1>&2
+ rc=1
+ exit
+ fi
+
+ if [ -n "$ETL_DISK" ]; then
+ etl_remove_disk
+ fi
+ done
+}
+
+usage()
+{
+ echo "Usage: $(basename $0) [options] -K -c categories -b blocks"
+ echo " or: $(basename $0) [options] -K -c categories -d device"
+ echo " or: $(basename $0) [options] -U -c categories"
+ echo " or: $(basename $0) [options] -K -U -c categories -b blocks"
+ echo
+ echo "eCryptfs test harness"
+ echo
+ echo " -b blocks number of 1K blocks used when creating backing "
+ echo " disk for lower filesystem (not compatible "
+ echo " with -d)"
+ echo " -c categories comma-separated test categories" \
+ "(e.g., -c safe,destructive)"
+ echo " -D disk_dir directory used to store created backing disk "
+ echo " when using -b (not compatible with -d)"
+ echo " -d device backing device to mount lower filesystem, such "
+ echo " as /dev/sdd3 (not compatible with -b)"
+ echo " -f lower_fses comma-separated lower filesystem types" \
+ "(e.g., -f ext4,btrfs)"
+ echo " defaults to $default_lower_fses" \
+ "(not compatible with -d)"
+ echo " -h display this help and exit"
+ echo " -K run tests relating to the kernel module"
+ echo " -l lower_mnt destination path to mount lower filesystem"
+ echo " -t tests comma-separated list of tests to run"
+ echo " -U run tests relating to the userspace utilities"
+ echo " -u upper_mnt destination path to mount upper filesystem"
+}
+
+while getopts "b:c:D:d:f:hKl:t:Uu:" opt; do
+ case $opt in
+ b)
+ blocks=$OPTARG
+ ;;
+ c)
+ categories=$OPTARG
+ ;;
+ d)
+ device=$OPTARG
+ ;;
+ D)
+ disk_dir=$OPTARG
+ ;;
+ f)
+ lower_fses=$OPTARG
+ ;;
+ h)
+ usage
+ rc=0
+ exit
+ ;;
+ K)
+ kernel=true
+ ;;
+ l)
+ lower_mnt=$OPTARG
+ ;;
+ t)
+ tests=$OPTARG
+ ;;
+ U)
+ userspace=true
+ ;;
+ u)
+ upper_mnt=$OPTARG
+ ;;
+ \?)
+ usage 1>&2
+ exit
+ ;;
+ :)
+ usage 1>&2
+ exit
+ ;;
+ esac
+done
+
+if ! $kernel && ! $userspace ; then
+ # Must specify at least one of these
+ echo "Must specify one of -U or -K" 1>&2
+ usage 1>&2
+ exit
+elif [ -z "$categories" ] && [ -z "$tests" ]; then
+ # Must either specify test categories or specific tests
+ echo "Must specify a list of test categories or a list of tests" 1>&2
+ usage 1>&2
+ exit
+fi
+
+if $kernel ; then
+ if [ "$blocks" -lt 1 ] && [ -z "$device" ]; then
+ # Must specify blocks for disk creation *or* an existing device
+ echo "Blocks for disk creation or an existing device must be" \
+ "specified" 1>&2
+ usage 1>&2
+ exit
+ elif [ "$blocks" -gt 0 ] && [ -n "$device" ]; then
+ # Can't specify blocks for disk *and* an existing device
+ echo "Cannot specify blocks for disk creation *and* also an" \
+ "existing device" 1>&2
+ usage 1>&2
+ exit
+ elif [ -n "$disk_dir" ] && [ -n "$device" ]; then
+ # Can't specify a dir for disk creation and an existing device
+ echo "Cannot specify a directory for disk creation *and* also" \
+ "an existing device" 1>&2
+ usage 1>&2
+ exit
+ elif [ -n "$device" ] && [ ! -b "$device" ]; then
+ # A small attempt at making sure we're dealing with a block dev
+ echo "Backing device must be a valid block device" 1>&2
+ usage 1>&2
+ exit
+ elif [ -n "$device" ] && [ -n "$lower_fses" ]; then
+ # We currently don't reformat block devices so we shouldn't
+ # accept a list of lower filesystems to test on
+ echo "Lower filesystems cannot be specified when using" \
+ "existing block devices" 1>&2
+ usage 1>&2
+ exit
+ elif [ -n "$lower_mnt" ] && [ ! -d "$lower_mnt" ]; then
+ # A small attempt at making sure we're dealing with directories
+ echo "Lower mount point must exist" 1>&2
+ usage 1>&2
+ exit
+ elif [ -n "$upper_mnt" ] && [ ! -d "$upper_mnt" ]; then
+ # A small attempt at making sure we're dealing with directories
+ echo "Upper mount point must exist" 1>&2
+ usage 1>&2
+ exit
+ elif [ -n "$disk_dir" ] && [ ! -d "$disk_dir" ]; then
+ # A small attempt at making sure we're dealing with a directory
+ echo "Directory used to store created backing disk must" \
+ "exist" 1>&2
+ usage 1>&2
+ exit
+ fi
+fi
+
+if [ -n "$device" ]; then
+ export ETL_LMOUNT_SRC=$device
+elif [ -z "$lower_fses" ]; then
+ lower_fses=$default_lower_fses
+fi
+
+if [ -z "$lower_mnt" ]; then
+ cleanup_lower_mnt=1
+ lower_mnt=$(mktemp -dq /tmp/etl-lower-XXXXXXXXXX)
+ if [ $? -ne 0 ]; then
+ cleanup_lower_mnt=0
+ rc=1
+ exit
+ fi
+fi
+export ETL_LMOUNT_DST=$lower_mnt
+export ETL_MOUNT_SRC=$lower_mnt
+
+if [ -z "$upper_mnt" ]; then
+ cleanup_upper_mnt=1
+ upper_mnt=$(mktemp -dq /tmp/etl-upper-XXXXXXXXXX)
+ if [ $? -ne 0 ]; then
+ cleanup_upper_mnt=0
+ rc=1
+ exit
+ fi
+fi
+export ETL_MOUNT_DST=$upper_mnt
+
+# Source in the kernel and/or userspace tests.rc files to build the test lists
+categories=$(echo $categories | tr ',' ' ')
+if $kernel ; then
+ if [ -n "$tests" ]; then
+ ktests=$(echo $tests | tr ',' ' ')
+ else
+ . ${run_tests_dir}/kernel/tests.rc
+ for cat in $categories ; do
+ eval cat_tests=\$$cat
+ ktests="$ktests $cat_tests"
+ done
+ fi
+
+ if [ -n "$device" ]; then
+ run_kernel_tests_on_existing_device
+ else
+ run_kernel_tests_on_created_disk_image
+ fi
+fi
+if $userspace ; then
+ if [ -n "$tests" ]; then
+ utests=$(echo $tests | tr ',' ' ')
+ else
+ . ${run_tests_dir}/userspace/tests.rc
+ for cat in $categories ; do
+ eval cat_tests=\$$cat
+ utests="$utests $cat_tests"
+ done
+ fi
+
+ echo "Running eCryptfs userspace tests"
+
+ run_tests "${run_tests_dir}/userspace" "$utests"
+ if [ $? -ne 0 ]; then
+ rc=1
+ exit
+ fi
+fi
+
+echo ""
+echo "Test Summary:"
+echo "$passed passed"
+echo "$failed failed"
+
+rc=$failed
+exit
diff --git a/tests/userspace/Makefile.am b/tests/userspace/Makefile.am
new file mode 100644
index 0000000..5f61d5a
--- /dev/null
+++ b/tests/userspace/Makefile.am
@@ -0,0 +1,26 @@
+AUTOMAKE_OPTIONS = subdir-objects
+
+# Only place tests worth of 'make check' here. All other tests are noinst.
+dist_check_SCRIPTS = lfs.sh verify-passphrase-sig.sh
+check_PROGRAMS = lfs/test verify-passphrase-sig/test
+
+dist_noinst_DATA = tests.rc
+
+dist_noinst_SCRIPTS = $(dist_check_SCRIPTS) \
+ wrap-unwrap.sh
+
+if ENABLE_TESTS
+noinst_PROGRAMS = $(check_PROGRAMS) \
+ wrap-unwrap/test
+endif
+
+lfs_test_SOURCES = lfs/test.c
+
+verify_passphrase_sig_test_SOURCES = verify-passphrase-sig/test.c
+verify_passphrase_sig_test_LDADD = $(top_builddir)/src/libecryptfs/libecryptfs.la
+
+wrap_unwrap_test_SOURCES = wrap-unwrap/test.c
+wrap_unwrap_test_LDADD = $(top_builddir)/src/libecryptfs/libecryptfs.la
+
+TESTS = lfs.sh verify-passphrase-sig.sh
+
diff --git a/tests/userspace/Makefile.in b/tests/userspace/Makefile.in
new file mode 100644
index 0000000..da54c3e
--- /dev/null
+++ b/tests/userspace/Makefile.in
@@ -0,0 +1,1134 @@
+# Makefile.in generated by automake 1.13.3 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+
+
+VPATH = @srcdir@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+check_PROGRAMS = lfs/test$(EXEEXT) verify-passphrase-sig/test$(EXEEXT)
+@ENABLE_TESTS_TRUE@noinst_PROGRAMS = $(check_PROGRAMS) \
+@ENABLE_TESTS_TRUE@ wrap-unwrap/test$(EXEEXT)
+subdir = tests/userspace
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+ $(dist_check_SCRIPTS) $(dist_noinst_SCRIPTS) \
+ $(top_srcdir)/depcomp $(dist_noinst_DATA) \
+ $(top_srcdir)/test-driver
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/ac_pkg_swig.m4 \
+ $(top_srcdir)/m4/ac_python_devel.m4 \
+ $(top_srcdir)/m4/intltool.m4 $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/swig_python.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+PROGRAMS = $(noinst_PROGRAMS)
+am__dirstamp = $(am__leading_dot)dirstamp
+am_lfs_test_OBJECTS = lfs/test.$(OBJEXT)
+lfs_test_OBJECTS = $(am_lfs_test_OBJECTS)
+lfs_test_LDADD = $(LDADD)
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+am_verify_passphrase_sig_test_OBJECTS = \
+ verify-passphrase-sig/test.$(OBJEXT)
+verify_passphrase_sig_test_OBJECTS = \
+ $(am_verify_passphrase_sig_test_OBJECTS)
+verify_passphrase_sig_test_DEPENDENCIES = \
+ $(top_builddir)/src/libecryptfs/libecryptfs.la
+am_wrap_unwrap_test_OBJECTS = wrap-unwrap/test.$(OBJEXT)
+wrap_unwrap_test_OBJECTS = $(am_wrap_unwrap_test_OBJECTS)
+wrap_unwrap_test_DEPENDENCIES = \
+ $(top_builddir)/src/libecryptfs/libecryptfs.la
+SCRIPTS = $(dist_noinst_SCRIPTS)
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = $(lfs_test_SOURCES) $(verify_passphrase_sig_test_SOURCES) \
+ $(wrap_unwrap_test_SOURCES)
+DIST_SOURCES = $(lfs_test_SOURCES) \
+ $(verify_passphrase_sig_test_SOURCES) \
+ $(wrap_unwrap_test_SOURCES)
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+DATA = $(dist_noinst_DATA)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors_dummy = \
+ mgn= red= grn= lgn= blu= brg= std=; \
+ am__color_tests=no
+am__tty_colors = { \
+ $(am__tty_colors_dummy); \
+ if test "X$(AM_COLOR_TESTS)" = Xno; then \
+ am__color_tests=no; \
+ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+ am__color_tests=yes; \
+ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+ am__color_tests=yes; \
+ fi; \
+ if test $$am__color_tests = yes; then \
+ red=''; \
+ grn=''; \
+ lgn=''; \
+ blu=''; \
+ mgn=''; \
+ brg=''; \
+ std=''; \
+ fi; \
+}
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__recheck_rx = ^[ ]*:recheck:[ ]*
+am__global_test_result_rx = ^[ ]*:global-test-result:[ ]*
+am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]*
+# A command that, given a newline-separated list of test names on the
+# standard input, print the name of the tests that are to be re-run
+# upon "make recheck".
+am__list_recheck_tests = $(AWK) '{ \
+ recheck = 1; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ { \
+ if ((getline line2 < ($$0 ".log")) < 0) \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
+ { \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
+ { \
+ break; \
+ } \
+ }; \
+ if (recheck) \
+ print $$0; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# A command that, given a newline-separated list of test names on the
+# standard input, create the global log from their .trs and .log files.
+am__create_global_log = $(AWK) ' \
+function fatal(msg) \
+{ \
+ print "fatal: making $@: " msg | "cat >&2"; \
+ exit 1; \
+} \
+function rst_section(header) \
+{ \
+ print header; \
+ len = length(header); \
+ for (i = 1; i <= len; i = i + 1) \
+ printf "="; \
+ printf "\n\n"; \
+} \
+{ \
+ copy_in_global_log = 1; \
+ global_test_result = "RUN"; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".trs"); \
+ if (line ~ /$(am__global_test_result_rx)/) \
+ { \
+ sub("$(am__global_test_result_rx)", "", line); \
+ sub("[ ]*$$", "", line); \
+ global_test_result = line; \
+ } \
+ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
+ copy_in_global_log = 0; \
+ }; \
+ if (copy_in_global_log) \
+ { \
+ rst_section(global_test_result ": " $$0); \
+ while ((rc = (getline line < ($$0 ".log"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".log"); \
+ print line; \
+ }; \
+ printf "\n"; \
+ }; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# Restructured Text title.
+am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
+# Solaris 10 'make', and several other traditional 'make' implementations,
+# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it
+# by disabling -e (using the XSI extension "set +e") if it's set.
+am__sh_e_setup = case $$- in *e*) set +e;; esac
+# Default flags passed to test drivers.
+am__common_driver_flags = \
+ --color-tests "$$am__color_tests" \
+ --enable-hard-errors "$$am__enable_hard_errors" \
+ --expect-failure "$$am__expect_failure"
+# To be inserted before the command running the test. Creates the
+# directory for the log if needed. Stores in $dir the directory
+# containing $f, in $tst the test, in $log the log. Executes the
+# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
+# passes TESTS_ENVIRONMENT. Set up options for the wrapper that
+# will run the test scripts (or their associated LOG_COMPILER, if
+# thy have one).
+am__check_pre = \
+$(am__sh_e_setup); \
+$(am__vpath_adj_setup) $(am__vpath_adj) \
+$(am__tty_colors); \
+srcdir=$(srcdir); export srcdir; \
+case "$@" in \
+ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \
+ *) am__odir=.;; \
+esac; \
+test "x$$am__odir" = x"." || test -d "$$am__odir" \
+ || $(MKDIR_P) "$$am__odir" || exit $$?; \
+if test -f "./$$f"; then dir=./; \
+elif test -f "$$f"; then dir=; \
+else dir="$(srcdir)/"; fi; \
+tst=$$dir$$f; log='$@'; \
+if test -n '$(DISABLE_HARD_ERRORS)'; then \
+ am__enable_hard_errors=no; \
+else \
+ am__enable_hard_errors=yes; \
+fi; \
+case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \
+ am__expect_failure=yes;; \
+ *) \
+ am__expect_failure=no;; \
+esac; \
+$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
+# A shell command to get the names of the tests scripts with any registered
+# extension removed (i.e., equivalently, the names of the test logs, with
+# the '.log' extension removed). The result is saved in the shell variable
+# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly,
+# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
+# since that might cause problem with VPATH rewrites for suffix-less tests.
+# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
+am__set_TESTS_bases = \
+ bases='$(TEST_LOGS)'; \
+ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
+ bases=`echo $$bases`
+RECHECK_LOGS = $(TEST_LOGS)
+AM_RECURSIVE_TARGETS = check recheck
+TEST_SUITE_LOG = test-suite.log
+TEST_EXTENSIONS = @EXEEXT@ .test
+LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver
+LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
+am__set_b = \
+ case '$@' in \
+ */*) \
+ case '$*' in \
+ */*) b='$*';; \
+ *) b=`echo '$@' | sed 's/\.log$$//'`; \
+ esac;; \
+ *) \
+ b='$*';; \
+ esac
+am__test_logs1 = $(TESTS:=.log)
+am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log)
+TEST_LOGS = $(am__test_logs2:.test.log=.log)
+TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver
+TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
+ $(TEST_LOG_FLAGS)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALL_LINGUAS = @ALL_LINGUAS@
+AMTAR = @AMTAR@
+AM_CPPFLAGS = @AM_CPPFLAGS@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CATALOGS = @CATALOGS@
+CATOBJEXT = @CATOBJEXT@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CRYPTO_CFLAGS = @CRYPTO_CFLAGS@
+CRYPTO_LIBS = @CRYPTO_LIBS@
+CYGPATH_W = @CYGPATH_W@
+DATADIRNAME = @DATADIRNAME@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+DVIPS = @DVIPS@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
+GMOFILES = @GMOFILES@
+GMSGFMT = @GMSGFMT@
+GPGME_CFLAGS = @GPGME_CFLAGS@
+GPGME_LIBS = @GPGME_LIBS@
+GREP = @GREP@
+GTK_CFLAGS = @GTK_CFLAGS@
+GTK_LIBS = @GTK_LIBS@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INSTOBJEXT = @INSTOBJEXT@
+INTLLIBS = @INTLLIBS@
+INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@
+INTLTOOL_MERGE = @INTLTOOL_MERGE@
+INTLTOOL_PERL = @INTLTOOL_PERL@
+INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
+INTLTOOL_V_MERGE = @INTLTOOL_V_MERGE@
+INTLTOOL_V_MERGE_OPTIONS = @INTLTOOL_V_MERGE_OPTIONS@
+INTLTOOL__v_MERGE_ = @INTLTOOL__v_MERGE_@
+INTLTOOL__v_MERGE_0 = @INTLTOOL__v_MERGE_0@
+KEYUTILS_CFLAGS = @KEYUTILS_CFLAGS@
+KEYUTILS_LIBS = @KEYUTILS_LIBS@
+LATEX = @LATEX@
+LATEX2HTML = @LATEX2HTML@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBECRYPTFS_LT_AGE = @LIBECRYPTFS_LT_AGE@
+LIBECRYPTFS_LT_CURRENT = @LIBECRYPTFS_LT_CURRENT@
+LIBECRYPTFS_LT_REVISION = @LIBECRYPTFS_LT_REVISION@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LOCALEDIR = @LOCALEDIR@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+MSGFMT = @MSGFMT@
+MSGFMT_OPTS = @MSGFMT_OPTS@
+MSGMERGE = @MSGMERGE@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NSS_CFLAGS = @NSS_CFLAGS@
+NSS_LIBS = @NSS_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OPENSSL_CFLAGS = @OPENSSL_CFLAGS@
+OPENSSL_LIBS = @OPENSSL_LIBS@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PAM_CFLAGS = @PAM_CFLAGS@
+PAM_LIBS = @PAM_LIBS@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKCS11_HELPER_CFLAGS = @PKCS11_HELPER_CFLAGS@
+PKCS11_HELPER_LIBS = @PKCS11_HELPER_LIBS@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+POD2MAN = @POD2MAN@
+POFILES = @POFILES@
+POSUB = @POSUB@
+PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@
+PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@
+PS2PDF = @PS2PDF@
+PYTHON = @PYTHON@
+PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@
+PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@
+PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@
+PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
+PYTHON_PLATFORM = @PYTHON_PLATFORM@
+PYTHON_PREFIX = @PYTHON_PREFIX@
+PYTHON_SITE_PKG = @PYTHON_SITE_PKG@
+PYTHON_VERSION = @PYTHON_VERSION@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+SWIG = @SWIG@
+SWIG_LIB = @SWIG_LIB@
+SWIG_PYTHON_CPPFLAGS = @SWIG_PYTHON_CPPFLAGS@
+SWIG_PYTHON_OPT = @SWIG_PYTHON_OPT@
+TAR = @TAR@
+TSPI_CFLAGS = @TSPI_CFLAGS@
+TSPI_LIBS = @TSPI_LIBS@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+XGETTEXT = @XGETTEXT@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+ecryptfskeymoddir = @ecryptfskeymoddir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+intltool__v_merge_options_ = @intltool__v_merge_options_@
+intltool__v_merge_options_0 = @intltool__v_merge_options_0@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pamdir = @pamdir@
+pamlibdir = @pamlibdir@
+pdfdir = @pdfdir@
+pkgconfigdir = @pkgconfigdir@
+pkgpyexecdir = @pkgpyexecdir@
+pkgpythondir = @pkgpythondir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+pyexecdir = @pyexecdir@
+pythondir = @pythondir@
+rootsbindir = @rootsbindir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+AUTOMAKE_OPTIONS = subdir-objects
+
+# Only place tests worth of 'make check' here. All other tests are noinst.
+dist_check_SCRIPTS = lfs.sh verify-passphrase-sig.sh
+dist_noinst_DATA = tests.rc
+dist_noinst_SCRIPTS = $(dist_check_SCRIPTS) \
+ wrap-unwrap.sh
+
+lfs_test_SOURCES = lfs/test.c
+verify_passphrase_sig_test_SOURCES = verify-passphrase-sig/test.c
+verify_passphrase_sig_test_LDADD = $(top_builddir)/src/libecryptfs/libecryptfs.la
+wrap_unwrap_test_SOURCES = wrap-unwrap/test.c
+wrap_unwrap_test_LDADD = $(top_builddir)/src/libecryptfs/libecryptfs.la
+TESTS = lfs.sh verify-passphrase-sig.sh
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tests/userspace/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign tests/userspace/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-checkPROGRAMS:
+ @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+
+clean-noinstPROGRAMS:
+ @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+lfs/$(am__dirstamp):
+ @$(MKDIR_P) lfs
+ @: > lfs/$(am__dirstamp)
+lfs/$(DEPDIR)/$(am__dirstamp):
+ @$(MKDIR_P) lfs/$(DEPDIR)
+ @: > lfs/$(DEPDIR)/$(am__dirstamp)
+lfs/test.$(OBJEXT): lfs/$(am__dirstamp) lfs/$(DEPDIR)/$(am__dirstamp)
+
+lfs/test$(EXEEXT): $(lfs_test_OBJECTS) $(lfs_test_DEPENDENCIES) $(EXTRA_lfs_test_DEPENDENCIES) lfs/$(am__dirstamp)
+ @rm -f lfs/test$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(lfs_test_OBJECTS) $(lfs_test_LDADD) $(LIBS)
+verify-passphrase-sig/$(am__dirstamp):
+ @$(MKDIR_P) verify-passphrase-sig
+ @: > verify-passphrase-sig/$(am__dirstamp)
+verify-passphrase-sig/$(DEPDIR)/$(am__dirstamp):
+ @$(MKDIR_P) verify-passphrase-sig/$(DEPDIR)
+ @: > verify-passphrase-sig/$(DEPDIR)/$(am__dirstamp)
+verify-passphrase-sig/test.$(OBJEXT): \
+ verify-passphrase-sig/$(am__dirstamp) \
+ verify-passphrase-sig/$(DEPDIR)/$(am__dirstamp)
+
+verify-passphrase-sig/test$(EXEEXT): $(verify_passphrase_sig_test_OBJECTS) $(verify_passphrase_sig_test_DEPENDENCIES) $(EXTRA_verify_passphrase_sig_test_DEPENDENCIES) verify-passphrase-sig/$(am__dirstamp)
+ @rm -f verify-passphrase-sig/test$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(verify_passphrase_sig_test_OBJECTS) $(verify_passphrase_sig_test_LDADD) $(LIBS)
+wrap-unwrap/$(am__dirstamp):
+ @$(MKDIR_P) wrap-unwrap
+ @: > wrap-unwrap/$(am__dirstamp)
+wrap-unwrap/$(DEPDIR)/$(am__dirstamp):
+ @$(MKDIR_P) wrap-unwrap/$(DEPDIR)
+ @: > wrap-unwrap/$(DEPDIR)/$(am__dirstamp)
+wrap-unwrap/test.$(OBJEXT): wrap-unwrap/$(am__dirstamp) \
+ wrap-unwrap/$(DEPDIR)/$(am__dirstamp)
+
+wrap-unwrap/test$(EXEEXT): $(wrap_unwrap_test_OBJECTS) $(wrap_unwrap_test_DEPENDENCIES) $(EXTRA_wrap_unwrap_test_DEPENDENCIES) wrap-unwrap/$(am__dirstamp)
+ @rm -f wrap-unwrap/test$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(wrap_unwrap_test_OBJECTS) $(wrap_unwrap_test_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+ -rm -f lfs/*.$(OBJEXT)
+ -rm -f verify-passphrase-sig/*.$(OBJEXT)
+ -rm -f wrap-unwrap/*.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@lfs/$(DEPDIR)/test.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@verify-passphrase-sig/$(DEPDIR)/test.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@wrap-unwrap/$(DEPDIR)/test.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+ -rm -rf lfs/.libs lfs/_libs
+ -rm -rf verify-passphrase-sig/.libs verify-passphrase-sig/_libs
+ -rm -rf wrap-unwrap/.libs wrap-unwrap/_libs
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+# Recover from deleted '.trs' file; this should ensure that
+# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
+# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells
+# to avoid problems with "make -n".
+.log.trs:
+ rm -f $< $@
+ $(MAKE) $(AM_MAKEFLAGS) $<
+
+# Leading 'am--fnord' is there to ensure the list of targets does not
+# expand to empty, as could happen e.g. with make check TESTS=''.
+am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
+am--force-recheck:
+ @:
+
+$(TEST_SUITE_LOG): $(TEST_LOGS)
+ @$(am__set_TESTS_bases); \
+ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
+ redo_bases=`for i in $$bases; do \
+ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
+ done`; \
+ if test -n "$$redo_bases"; then \
+ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
+ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
+ if $(am__make_dryrun); then :; else \
+ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
+ fi; \
+ fi; \
+ if test -n "$$am__remaking_logs"; then \
+ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
+ "recursion detected" >&2; \
+ else \
+ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
+ fi; \
+ if $(am__make_dryrun); then :; else \
+ st=0; \
+ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
+ for i in $$redo_bases; do \
+ test -f $$i.trs && test -r $$i.trs \
+ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \
+ test -f $$i.log && test -r $$i.log \
+ || { echo "$$errmsg $$i.log" >&2; st=1; }; \
+ done; \
+ test $$st -eq 0 || exit 1; \
+ fi
+ @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
+ ws='[ ]'; \
+ results=`for b in $$bases; do echo $$b.trs; done`; \
+ test -n "$$results" || results=/dev/null; \
+ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \
+ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \
+ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \
+ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \
+ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
+ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
+ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
+ if test `expr $$fail + $$xpass + $$error` -eq 0; then \
+ success=true; \
+ else \
+ success=false; \
+ fi; \
+ br='==================='; br=$$br$$br$$br$$br; \
+ result_count () \
+ { \
+ if test x"$$1" = x"--maybe-color"; then \
+ maybe_colorize=yes; \
+ elif test x"$$1" = x"--no-color"; then \
+ maybe_colorize=no; \
+ else \
+ echo "$@: invalid 'result_count' usage" >&2; exit 4; \
+ fi; \
+ shift; \
+ desc=$$1 count=$$2; \
+ if test $$maybe_colorize = yes && test $$count -gt 0; then \
+ color_start=$$3 color_end=$$std; \
+ else \
+ color_start= color_end=; \
+ fi; \
+ echo "$${color_start}# $$desc $$count$${color_end}"; \
+ }; \
+ create_testsuite_report () \
+ { \
+ result_count $$1 "TOTAL:" $$all "$$brg"; \
+ result_count $$1 "PASS: " $$pass "$$grn"; \
+ result_count $$1 "SKIP: " $$skip "$$blu"; \
+ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
+ result_count $$1 "FAIL: " $$fail "$$red"; \
+ result_count $$1 "XPASS:" $$xpass "$$red"; \
+ result_count $$1 "ERROR:" $$error "$$mgn"; \
+ }; \
+ { \
+ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \
+ $(am__rst_title); \
+ create_testsuite_report --no-color; \
+ echo; \
+ echo ".. contents:: :depth: 2"; \
+ echo; \
+ for b in $$bases; do echo $$b; done \
+ | $(am__create_global_log); \
+ } >$(TEST_SUITE_LOG).tmp || exit 1; \
+ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \
+ if $$success; then \
+ col="$$grn"; \
+ else \
+ col="$$red"; \
+ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \
+ fi; \
+ echo "$${col}$$br$${std}"; \
+ echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}"; \
+ echo "$${col}$$br$${std}"; \
+ create_testsuite_report --maybe-color; \
+ echo "$$col$$br$$std"; \
+ if $$success; then :; else \
+ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \
+ if test -n "$(PACKAGE_BUGREPORT)"; then \
+ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \
+ fi; \
+ echo "$$col$$br$$std"; \
+ fi; \
+ $$success || exit 1
+
+check-TESTS:
+ @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list
+ @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ trs_list=`for i in $$bases; do echo $$i.trs; done`; \
+ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
+ exit $$?;
+recheck: all $(check_PROGRAMS) $(dist_check_SCRIPTS)
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ bases=`for i in $$bases; do echo $$i; done \
+ | $(am__list_recheck_tests)` || exit 1; \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ log_list=`echo $$log_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
+ am__force_recheck=am--force-recheck \
+ TEST_LOGS="$$log_list"; \
+ exit $$?
+lfs.sh.log: lfs.sh
+ @p='lfs.sh'; \
+ b='lfs.sh'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+verify-passphrase-sig.sh.log: verify-passphrase-sig.sh
+ @p='verify-passphrase-sig.sh'; \
+ b='verify-passphrase-sig.sh'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+.test.log:
+ @p='$<'; \
+ $(am__set_b); \
+ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+@am__EXEEXT_TRUE@.test$(EXEEXT).log:
+@am__EXEEXT_TRUE@ @p='$<'; \
+@am__EXEEXT_TRUE@ $(am__set_b); \
+@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \
+@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT)
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) \
+ $(dist_check_SCRIPTS)
+ $(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-am
+all-am: Makefile $(PROGRAMS) $(SCRIPTS) $(DATA)
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+ -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
+ -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
+ -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+ -rm -f lfs/$(DEPDIR)/$(am__dirstamp)
+ -rm -f lfs/$(am__dirstamp)
+ -rm -f verify-passphrase-sig/$(DEPDIR)/$(am__dirstamp)
+ -rm -f verify-passphrase-sig/$(am__dirstamp)
+ -rm -f wrap-unwrap/$(DEPDIR)/$(am__dirstamp)
+ -rm -f wrap-unwrap/$(am__dirstamp)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-checkPROGRAMS clean-generic clean-libtool \
+ clean-noinstPROGRAMS mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf lfs/$(DEPDIR) verify-passphrase-sig/$(DEPDIR) wrap-unwrap/$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf lfs/$(DEPDIR) verify-passphrase-sig/$(DEPDIR) wrap-unwrap/$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-TESTS check-am clean \
+ clean-checkPROGRAMS clean-generic clean-libtool \
+ clean-noinstPROGRAMS cscopelist-am ctags ctags-am distclean \
+ distclean-compile distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
+ pdf pdf-am ps ps-am recheck tags tags-am uninstall \
+ uninstall-am
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/tests/userspace/lfs.sh b/tests/userspace/lfs.sh
new file mode 100755
index 0000000..6c205ce
--- /dev/null
+++ b/tests/userspace/lfs.sh
@@ -0,0 +1,37 @@
+#!/bin/bash
+#
+# lfs.sh: Test for large file support enabled builds
+# Author: Tyler Hicks <tyhicks@canonical.com>
+#
+# Copyright (C) 2013 Canonical, Ltd.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation version 2
+# of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+
+test_script_dir=$(dirname $0)
+rc=1
+
+. ${test_script_dir}/../lib/etl_funcs.sh
+
+test_cleanup()
+{
+ exit $rc
+}
+trap test_cleanup 0 1 2 3 15
+
+# Run the test program. See its source for the details of this test.
+${test_script_dir}/lfs/test
+
+rc=$?
+exit
diff --git a/tests/userspace/lfs/test.c b/tests/userspace/lfs/test.c
new file mode 100644
index 0000000..5530fd4
--- /dev/null
+++ b/tests/userspace/lfs/test.c
@@ -0,0 +1,46 @@
+/*
+ * Author: Tyler Hicks <tyhicks@canonical.com>
+ *
+ * Copyright (C) 2013 Canonical, Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/*
+ * This test is to ensure that off_t is the same size as off64_t in all
+ * ecryptfs-utils builds. On 64 bit machines, this is the default. On 32 bit
+ * machines, the build system must define special variables to enable what is
+ * known as Large File Support (LFS).
+ *
+ * In configure.ac, we enable LFS by using the AC_SYS_LARGEFILE autoconf macro.
+ * It defines _FILE_OFFSET_BITS=64, when needed by the target architecture, in
+ * config.h. Also in configure.ac, we force all .c files to #include config.h
+ * so the entire ecryptfs-utils build should always have LFS enabled.
+ *
+ * IMPORTANT: We intentionally do not include config.h in this file, because it
+ * is expected that the build system automatically does it for us. This test
+ * verifies that the inclusion on config.h happens.
+ *
+ * We must define _LARGEFILE64_SOURCE in this file so that off64_t is
+ * available. However, defining it does not enable large file support.
+ */
+
+#define _LARGEFILE64_SOURCE 1
+#include <sys/types.h>
+
+int main(void)
+{
+ return sizeof(off_t) == sizeof(off64_t) ? 0 : 1;
+}
diff --git a/tests/userspace/tests.rc b/tests/userspace/tests.rc
new file mode 100644
index 0000000..326523d
--- /dev/null
+++ b/tests/userspace/tests.rc
@@ -0,0 +1 @@
+safe="lfs.sh verify-passphrase-sig.sh wrap-unwrap.sh"
diff --git a/tests/userspace/verify-passphrase-sig.sh b/tests/userspace/verify-passphrase-sig.sh
new file mode 100755
index 0000000..ff522d4
--- /dev/null
+++ b/tests/userspace/verify-passphrase-sig.sh
@@ -0,0 +1,64 @@
+#!/bin/bash
+#
+# verify_passphrase_sig.sh: Check for regressions in libecryptfs'
+# generate_passphrase_sig()
+# Author: Tyler Hicks <tyhicks@canonical.com>
+#
+# Copyright (C) 2012 Canonical Ltd.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation version 2
+# of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+
+test_script_dir=$(dirname $0)
+rc=1
+
+pass="foo"
+salt="0011223344556677"
+# Expected values come from testing ecryptfs-utils version 30
+expected_sig="253ca7e88811d184"
+expected_fekek="3f0cffa9389d2c396ad887c6ec657898e2e9e74cbb3cb1d25d410f58de2aa6b70dd81ccedaf8fad725346d8f751b8fc2c50ad69fba27d1d4fb735f207e76c6e9"
+
+${test_script_dir}/verify-passphrase-sig/test "$pass" "$salt" \
+ "$expected_sig" \
+ "$expected_fekek"
+rc=$?
+if [ $rc -ne 0 ]; then
+ exit $rc
+fi
+
+
+pass="a"
+salt="aaaaaaaaaaaaaaaa"
+expected_sig="c42ec75301dc1674"
+expected_fekek="27f2ff49bfc520109f2579b36377a29955585cee6e8e5210b474a7ef7e5c4e9cf499075ace62d03b78d718d0e311726bb35b6699061f12d0731dd6a3efe9b3f2"
+
+${test_script_dir}/verify-passphrase-sig/test "$pass" "$salt" \
+ "$expected_sig" \
+ "$expected_fekek"
+rc=$?
+if [ $rc -ne 0 ]; then
+ exit $rc
+fi
+
+
+pass="ef2fa983a4ecc87b6f48821bd9b36940220345624949e6bf826efd692678d78b"
+salt="fa1507f9913d915b"
+expected_sig="09582907da54851e"
+expected_fekek="bdc9089cb08554ac6039c64345a82f49e175c1427104bb1906fed9f3ad703c4f3745b2ef9a2f4210b24c973fe17370ae39def8af31d7b3f304d1209ed4313f4d"
+
+${test_script_dir}/verify-passphrase-sig/test "$pass" "$salt" \
+ "$expected_sig" \
+ "$expected_fekek"
+rc=$?
+exit $rc
diff --git a/tests/userspace/verify-passphrase-sig/test.c b/tests/userspace/verify-passphrase-sig/test.c
new file mode 100644
index 0000000..a54d7bd
--- /dev/null
+++ b/tests/userspace/verify-passphrase-sig/test.c
@@ -0,0 +1,70 @@
+/**
+ * test.c: Check for expected output from generate_passphrase_sig() function
+ * Author: Tyler Hicks <tyhicks@canonical.com>
+ *
+ * Copyright (C) 2012 Canonical, Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
+ */
+
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include "../../src/include/ecryptfs.h"
+
+#define ECRYPTFS_MAX_KEY_HEX_BYTES (ECRYPTFS_MAX_KEY_BYTES * 2)
+
+void usage(const char *name)
+{
+ fprintf(stderr, "%s PASSPHRASE SALT_HEX EXPECTED_SIG_HEX "
+ "EXPECTED_FEKEK_HEX\n", name);
+}
+
+int main(int argc, char *argv[])
+{
+ char sig_hex[ECRYPTFS_PASSWORD_SIG_SIZE + 1];
+ char fekek[ECRYPTFS_MAX_KEY_BYTES + 1];
+ char fekek_hex[ECRYPTFS_MAX_KEY_HEX_BYTES + 1];
+ char salt[ECRYPTFS_SALT_SIZE + 1];
+ int rc;
+
+ if (argc != 5 ||
+ strlen(argv[2]) != ECRYPTFS_SALT_SIZE_HEX ||
+ strlen(argv[3]) != ECRYPTFS_PASSWORD_SIG_SIZE ||
+ strlen(argv[4]) != ECRYPTFS_MAX_KEY_HEX_BYTES) {
+ usage(argv[0]);
+ return EINVAL;
+ }
+
+ memset(sig_hex, 0, ECRYPTFS_PASSWORD_SIG_SIZE + 1);
+ memset(fekek, 0, ECRYPTFS_MAX_KEY_BYTES + 1);
+ memset(fekek_hex, 0, ECRYPTFS_MAX_KEY_HEX_BYTES + 1);
+ memset(salt, 0, ECRYPTFS_SALT_SIZE + 1);
+ from_hex(salt, argv[2], ECRYPTFS_SALT_SIZE);
+
+ rc = generate_passphrase_sig(sig_hex, fekek, salt, argv[1]);
+ if (rc)
+ return rc;
+
+ to_hex(fekek_hex, fekek, ECRYPTFS_MAX_KEY_BYTES);
+ if (strcmp(sig_hex, argv[3]) ||
+ strcmp(fekek_hex, argv[4])) {
+ return EINVAL;
+ }
+
+ return 0;
+}
+
diff --git a/tests/userspace/wrap-unwrap.sh b/tests/userspace/wrap-unwrap.sh
new file mode 100755
index 0000000..f678cac
--- /dev/null
+++ b/tests/userspace/wrap-unwrap.sh
@@ -0,0 +1,40 @@
+#!/bin/bash
+#
+# wrap-unwrap.sh: Check for regressions in libecryptfs'
+# wrapper functions
+# Author: Tyler Hicks <tyhicks@canonical.com>
+#
+# Copyright (C) 2012 Canonical Ltd.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation version 2
+# of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+
+test_script_dir=$(dirname $0)
+rc=1
+
+. ${test_script_dir}/../lib/etl_funcs.sh
+
+test_cleanup()
+{
+ etl_remove_test_dir $test_dir
+ exit $rc
+}
+trap test_cleanup 0 1 2 3 15
+
+test_dir=$(etl_create_test_dir) || exit
+path="${test_dir}/foo"
+
+${test_script_dir}/wrap-unwrap/test ${path}
+rc=$?
+exit
diff --git a/tests/userspace/wrap-unwrap/test.c b/tests/userspace/wrap-unwrap/test.c
new file mode 100644
index 0000000..371e5d8
--- /dev/null
+++ b/tests/userspace/wrap-unwrap/test.c
@@ -0,0 +1,112 @@
+/**
+ * Author: Michael Halcrow
+ *
+ * Copyright (C) IBM
+ *
+ * Modified by Tyler Hicks <tyhicks@canonical.com> to fit into the eCryptfs
+ * test modern framework.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "../../src/include/ecryptfs.h"
+
+int main(int argc, char *argv[])
+{
+ char passphrase[ECRYPTFS_MAX_PASSWORD_LENGTH + 8];
+ int passphrase_size;
+ char decrypted_passphrase[ECRYPTFS_MAX_PASSWORD_LENGTH + 1];
+ int decrypted_passphrase_size;
+ char salt[ECRYPTFS_SALT_SIZE + 1];
+ char *path;
+ int i;
+ int rc = 0;
+
+ if (argc != 2) {
+ fprintf(stderr, "Usage: %s path\n", argv[0]);
+ exit(1);
+ }
+ path = argv[1];
+
+ /* Sanity check */
+ from_hex(salt, ECRYPTFS_DEFAULT_SALT_HEX, ECRYPTFS_SALT_SIZE);
+ memcpy(passphrase, "012345679abcdef0\0", 17);
+ passphrase_size = strlen(passphrase);
+ if ((rc = ecryptfs_wrap_passphrase(path, "testwrappw", salt,
+ passphrase))) {
+ fprintf(stderr, "ecryptfs_wrap_passphrase() returned "
+ "rc = [%d]\n", rc);
+ rc = 1;
+ goto out;
+ }
+ if ((rc = ecryptfs_unwrap_passphrase(decrypted_passphrase, path,
+ "testwrappw", salt))) {
+ fprintf(stderr, "ecryptfs_unwrap_passphrase() returned "
+ "rc = [%d]\n", rc);
+ rc = 1;
+ goto out;
+ }
+ decrypted_passphrase_size = strlen(decrypted_passphrase);
+ if (decrypted_passphrase_size != passphrase_size) {
+ fprintf(stderr, "Invalid decrypted size [%d]; expected [%d]\n",
+ decrypted_passphrase_size, passphrase_size);
+ rc = 1;
+ goto out;
+ }
+ if (memcmp(decrypted_passphrase, passphrase, passphrase_size) != 0) {
+ fprintf(stderr, "decrypted passphrase = [%s]; expected [%s]\n",
+ decrypted_passphrase, passphrase);
+ rc = 1;
+ goto out;
+ }
+ /* Comprehensive check */
+ from_hex(salt, ECRYPTFS_DEFAULT_SALT_HEX, ECRYPTFS_SALT_SIZE);
+ for (i = 0; i < ECRYPTFS_MAX_PASSWORD_LENGTH; i++) {
+ passphrase[i] = 'a' + i;
+ passphrase[i + 1] = '\0';
+ if ((rc = ecryptfs_wrap_passphrase(path, "testwrappw", salt,
+ passphrase))) {
+ fprintf(stderr, "ecryptfs_wrap_passphrase() returned "
+ "rc = [%d]\n", rc);
+ rc = 1;
+ goto out;
+ }
+ if ((rc = ecryptfs_unwrap_passphrase(decrypted_passphrase,
+ path,
+ "testwrappw", salt))) {
+ fprintf(stderr, "ecryptfs_unwrap_passphrase() returned "
+ "rc = [%d]\n", rc);
+ rc = 1;
+ goto out;
+ }
+ decrypted_passphrase_size = strlen(decrypted_passphrase);
+ if (decrypted_passphrase_size != (i + 1)) {
+ fprintf(stderr, "Invalid decrypted size [%d]; expected "
+ "[%d]\n", decrypted_passphrase_size, (i + 1));
+ rc = 1;
+ goto out;
+ }
+ if (memcmp(decrypted_passphrase, passphrase, (i + 1)) != 0) {
+ fprintf(stderr, "decrypted passphrase = [%s]; expected "
+ "[%s]\n", decrypted_passphrase, passphrase);
+ rc = 1;
+ goto out;
+ }
+ }
+ /* Failure check */
+ from_hex(salt, ECRYPTFS_DEFAULT_SALT_HEX, ECRYPTFS_SALT_SIZE);
+ for (i = 0; i < 65; i++)
+ passphrase[i] = 'a' + i;
+ passphrase[66] = '\0';
+ passphrase_size = strlen(passphrase);
+ if ((rc = ecryptfs_wrap_passphrase(path, "testwrappw", salt,
+ passphrase)) == 0) {
+ fprintf(stderr, "ecryptfs_wrap_passphrase() returned rc = 0; "
+ "expected error result instead\n");
+ rc = 1;
+ goto out;
+ }
+ rc = 0;
+out:
+ return rc;
+}