[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