From 9e10ad3d5035686e4676c208c7d88f55f1c1a05c Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Tue, 19 Oct 2010 14:30:07 +0200 Subject: [PATCH] tests: add libmount lock test Signed-off-by: Karel Zak --- shlibs/mount/src/lock.c | 53 ++++++++++++++++++++++++++++++------ tests/commands.sh.in | 1 + tests/expected/libmount/lock | 1 + tests/ts/libmount/lock | 37 +++++++++++++++++++++++++ 4 files changed, 83 insertions(+), 9 deletions(-) create mode 100644 tests/expected/libmount/lock create mode 100755 tests/ts/libmount/lock diff --git a/shlibs/mount/src/lock.c b/shlibs/mount/src/lock.c index b168526c..5e18ba25 100644 --- a/shlibs/mount/src/lock.c +++ b/shlibs/mount/src/lock.c @@ -75,7 +75,7 @@ mnt_lock *mnt_new_lock(const char *datafile, pid_t id) ml->linkfile = ln; ml->lockfile = lo; - DBG(LOCKS, mnt_debug_h(ml, "alloc")); + DBG(LOCKS, mnt_debug_h(ml, "alloc: linkfile=%s, lockfile=%s", ln, lo)); return ml; err: free(lo); @@ -482,17 +482,34 @@ void sig_handler(int sig) int test_lock(struct mtest *ts, int argc, char *argv[]) { - const char *datafile; - int verbose = 0, loops, l; + time_t synctime = 0; + unsigned int usecs; + struct timeval tv; + const char *datafile = NULL; + int verbose = 0, loops = 0, l, idx = 1; if (argc < 3) - return -1; - - datafile = argv[1]; - loops = atoi(argv[2]); + return -EINVAL; - if (argc == 5 && strcmp(argv[4], "--verbose") == 0) + if (strcmp(argv[idx], "--synctime") == 0) { + synctime = (time_t) atol(argv[idx + 1]); + idx += 2; + } + if (idx < argc && strcmp(argv[idx], "--verbose") == 0) { verbose = 1; + idx++; + } + + if (idx < argc) + datafile = argv[idx++]; + if (idx < argc) + loops = atoi(argv[idx++]); + + if (!datafile || !loops) + return -EINVAL; + + fprintf(stderr, "%d: start: synctime=%u, verbose=%d, datafile=%s, loops=%d\n", + getpid(), (int) synctime, verbose, datafile, loops); atexit(clean_lock); @@ -509,6 +526,16 @@ int test_lock(struct mtest *ts, int argc, char *argv[]) sigaction (sig, &sa, (struct sigaction *) 0); } + /* start the test in exactly defined time */ + if (synctime) { + gettimeofday(&tv, NULL); + if (synctime && synctime - tv.tv_sec > 1) { + usecs = ((synctime - tv.tv_sec) * 1000000UL) - + (1000000UL - tv.tv_usec); + usleep(usecs); + } + } + for (l = 0; l < loops; l++) { lock = mnt_new_lock(datafile, 0); if (!lock) @@ -525,6 +552,13 @@ int test_lock(struct mtest *ts, int argc, char *argv[]) mnt_unlock_file(lock); mnt_free_lock(lock); lock = NULL; + + /* The mount command usually finish after mtab update. We + * simulate this via short sleep -- it's also enough to make + * concurrent processes happy. + */ + if (synctime) + usleep(25000); } return 0; @@ -537,7 +571,8 @@ int test_lock(struct mtest *ts, int argc, char *argv[]) int main(int argc, char *argv[]) { struct mtest tss[] = { - { "--lock", test_lock, " [--verbose] increment number in datafile" }, + { "--lock", test_lock, " [--synctime ] [--verbose] " + "increment a number in datafile" }, { NULL } }; diff --git a/tests/commands.sh.in b/tests/commands.sh.in index d5e166bd..bcb428d4 100644 --- a/tests/commands.sh.in +++ b/tests/commands.sh.in @@ -19,6 +19,7 @@ TS_HELPER_CPUSET="$top_builddir/lib/test_cpuset" TS_HELPER_LIBMOUNT_OPTSTR="$top_builddir/shlibs/mount/src/test_optstr" TS_HELPER_LIBMOUNT_TAB="$top_builddir/shlibs/mount/src/test_tab" TS_HELPER_LIBMOUNT_UTILS="$top_builddir/shlibs/mount/src/test_utils" +TS_HELPER_LIBMOUNT_LOCK="$top_builddir/shlibs/mount/src/test_lock" # TODO: use partx TS_HELPER_PARTITIONS="$top_builddir/shlibs/blkid/samples/partitions" diff --git a/tests/expected/libmount/lock b/tests/expected/libmount/lock new file mode 100644 index 00000000..d7e318d9 --- /dev/null +++ b/tests/expected/libmount/lock @@ -0,0 +1 @@ +50000 \ No newline at end of file diff --git a/tests/ts/libmount/lock b/tests/ts/libmount/lock new file mode 100755 index 00000000..1230e5cc --- /dev/null +++ b/tests/ts/libmount/lock @@ -0,0 +1,37 @@ +#!/bin/bash + +# Copyright (C) 2010 Karel Zak + +TS_TOPDIR="$(dirname $0)/../.." +TS_DESC="lock" + +. $TS_TOPDIR/functions.sh +ts_init "$*" + +TESTPROG="$TS_HELPER_LIBMOUNT_LOCK" + +# +# Be careful with number of processes. Don't forget that there is time limit +# when the mount waits on the mtab lock. If you define too much processes some +# of them will fail with timeout. +# +# Note: the original version (< 2.13) of util-linux is completely useless for +# this test (maximum for this old version is NLOOPS=10 and NPROCESSES=5 (2-way +# 2GHz machine)). It has terrible performance due a bad timeouts implemntation +# in lock_mtab(). +# +NLOOPS=1000 +NPROCESSES=50 + + +> $TS_OUTPUT.debug +echo 0 > $TS_OUTPUT +SYNCTIME=$(( $(date +%s) + 5 )) + +for id in $(seq 0 $(( $NPROCESSES - 1 ))); do + $TESTPROG --lock --synctime $SYNCTIME $TS_OUTPUT $NLOOPS >> $TS_OUTPUT.debug 2>&1 & +done + +wait + +ts_finalize -- 2.39.5