[CRIU] [PATCH 10/11] zdtm: add posix file lock's test case
Qiang Huang
h.huangqiang at huawei.com
Thu Jan 17 03:09:36 EST 2013
We check read lock and write lock for posix file locks. After restore,
we use fcntl(fd, F_GETLK, &lock), to see if the file is hold the same
lock as it was dumped.
Signed-off-by: Qiang Huang <h.huangqiang at huawei.com>
---
test/zdtm.sh | 11 ++-
test/zdtm/live/static/Makefile | 1 +
test/zdtm/live/static/file_locks00.c | 179 ++++++++++++++++++++++++++++++++++
3 files changed, 190 insertions(+), 1 deletions(-)
create mode 100644 test/zdtm/live/static/file_locks00.c
diff --git a/test/zdtm.sh b/test/zdtm.sh
index 2ed2c87..bbfa0f7 100644
--- a/test/zdtm.sh
+++ b/test/zdtm.sh
@@ -116,6 +116,10 @@ static/sem
transition/ipc
"
+FILE_LOCK_TEST_LIST="
+static/file_locks00
+"
+
TEST_CR_KERNEL="
static/sock_opts01
static/sockets01
@@ -410,8 +414,11 @@ if [ $# -eq 0 ]; then
for t in $IPC_TEST_LIST; do
run_test $t -n ipc || case_error $t
done
+ for t in $FILE_LOCK_TEST_LIST; do
+ run_test $t -l || case_error $t
+ done
elif [ "$1" = "-l" ]; then
- echo $TEST_LIST $UTS_TEST_LIST $MNT_TEST_LIST $IPC_TEST_LIST | tr ' ' '\n'
+ echo $TEST_LIST $UTS_TEST_LIST $MNT_TEST_LIST $IPC_TEST_LIST $FILE_LOCK_TEST_LIST | tr ' ' '\n'
elif [ "$1" = "-h" ]; then
cat >&2 <<EOF
This script is used for executing unit tests.
@@ -430,6 +437,8 @@ else
run_test $1 -n mnt || case_error $1
elif echo $IPC_TEST_LIST | fgrep -qw $1; then
run_test $1 -n ipc || case_error $1
+ elif echo $FILE_LOCK_TEST_LIST | fgrep -qw $1; then
+ run_test $1 -l || case_error $1
else
run_test $1 || case_error $1
fi
diff --git a/test/zdtm/live/static/Makefile b/test/zdtm/live/static/Makefile
index 55555ab..d8210e4 100644
--- a/test/zdtm/live/static/Makefile
+++ b/test/zdtm/live/static/Makefile
@@ -83,6 +83,7 @@ TST_NOFILE = \
cow00 \
child_opened_proc \
posix_timers \
+ file_locks00 \
# jobctl00 \
TST_FILE = \
diff --git a/test/zdtm/live/static/file_locks00.c b/test/zdtm/live/static/file_locks00.c
new file mode 100644
index 0000000..77d9e0b
--- /dev/null
+++ b/test/zdtm/live/static/file_locks00.c
@@ -0,0 +1,179 @@
+#define _GNU_SOURCE
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/file.h>
+#include <sys/wait.h>
+#include <string.h>
+
+#include "zdtmtst.h"
+
+const char *test_doc = "Check that posix flocks are restored";
+const char *test_author = "Qiang Huang <h.huangqiang at huawei.com>";
+
+char file0[] = "/tmp/zdtm_file_locks_XXXXXX";
+char file1[] = "/tmp/zdtm_file_locks_XXXXXX";
+
+static int lock_reg(int fd, int cmd, int type, int whence,
+ off_t offset, off_t len)
+{
+ struct flock lock;
+
+ lock.l_type = type; /* F_RDLCK, F_WRLCK, F_UNLCK */
+ lock.l_whence = whence; /* SEEK_SET, SEEK_CUR, SEEK_END */
+ lock.l_start = offset; /* byte offset, relative to l_whence */
+ lock.l_len = len; /* #bytes (0 means to EOF) */
+
+ return fcntl(fd, cmd, &lock);
+}
+
+#define set_read_lock(fd, whence, offset, len) \
+ lock_reg(fd, F_SETLK, F_RDLCK, whence, offset, len)
+#define set_write_lock(fd, whence, offset, len) \
+ lock_reg(fd, F_SETLK, F_WRLCK, whence, offset, len)
+
+static int check_read_lock(int fd, int whence, off_t offset, off_t len)
+{
+ struct flock lock;
+ int ret;
+
+ lock.l_type = F_RDLCK; /* F_RDLCK, F_WRLCK, F_UNLCK */
+ lock.l_whence = whence; /* SEEK_SET, SEEK_CUR, SEEK_END */
+ lock.l_start = offset; /* byte offset, relative to l_whence */
+ lock.l_len = len; /* #bytes (0 means to EOF) */
+ lock.l_pid = -1;
+
+ ret = fcntl(fd, F_GETLK, &lock);
+ if (ret == -1) {
+ err("F_GETLK failed.\n");
+ return -1;
+ }
+
+ if (lock.l_pid == -1) {
+ /* Share lock should succeed. */
+ return 0;
+ }
+
+ fail("Read lock check failed.");
+ return -1;
+}
+
+static int check_write_lock(int fd, int whence, off_t offset, off_t len)
+{
+ struct flock lock;
+
+ int ret;
+ pid_t ppid = getppid();
+
+ lock.l_type = F_WRLCK; /* F_RDLCK, F_WRLCK, F_UNLCK */
+ lock.l_whence = whence; /* SEEK_SET, SEEK_CUR, SEEK_END */
+ lock.l_start = offset; /* byte offset, relative to l_whence */
+ lock.l_len = len; /* #bytes (0 means to EOF) */
+ lock.l_pid = -1;
+
+ ret = fcntl(fd, F_GETLK, &lock);
+ if (ret == -1) {
+ err("F_GETLK failed.\n");
+ return -1;
+ }
+
+ if (lock.l_pid == -1) {
+ fail("Write lock check failed.");
+ return -1;
+ }
+
+ /*
+ * It only succeed when the file lock's owner is exactly
+ * the same as the file lock was dumped.
+ */
+ if (lock.l_pid == ppid)
+ return 0;
+
+ fail("Write lock check failed.");
+ return -1;
+}
+
+static int check_file_locks()
+{
+ int fd_0, fd_1;
+ int ret0, ret1;
+
+ fd_0 = open(file0, O_RDWR | O_CREAT, 0644);
+ if (fd_0 < 0) {
+ err("Unable to open file %s", file0);
+ return -1;
+ }
+ ret0 = check_read_lock(fd_0, SEEK_SET, 0, 0);
+
+ fd_1 = open(file1, O_RDWR | O_CREAT, 0644);
+ if (fd_1 < 0) {
+ close(fd_0);
+ unlink(file0);
+ err("Unable to open file %s", file1);
+ return -1;
+ }
+ ret1 = check_write_lock(fd_1, SEEK_SET, 0, 0);
+
+ close(fd_0);
+ close(fd_1);
+
+ return ret0 | ret1;
+}
+
+int main(int argc, char **argv)
+{
+ int fd_0, fd_1;
+ pid_t pid;
+
+ test_init(argc, argv);
+
+ fd_0 = mkstemp(file0);
+ if (fd_0 < 0) {
+ err("Unable to open file %s", file0);
+ return -1;
+ }
+
+ fd_1 = mkstemp(file1);
+ if (fd_1 < 0) {
+ close(fd_0);
+ unlink(file0);
+ err("Unable to open file %s", file1);
+ return -1;
+ }
+
+ pid = fork();
+ if (pid < 0) {
+ err("Can't fork: %m\n");
+ return -1;
+ }
+
+ if (pid == 0) { /* child will check father's file locks */
+ test_waitsig();
+
+ if (check_file_locks()) {
+ fail("Posix file lock check failed");
+ exit(1);
+ }
+
+ pass();
+ exit(0);
+ }
+
+ set_read_lock(fd_0, SEEK_SET, 0, 0);
+ set_write_lock(fd_1, SEEK_SET, 0, 0);
+
+ test_daemon();
+ test_waitsig();
+
+ kill(pid, SIGTERM);
+ waitpid(pid, NULL, 0);
+ close(fd_0);
+ close(fd_1);
+ unlink(file0);
+ unlink(file1);
+
+ return 0;
+}
--
1.7.1
More information about the CRIU
mailing list