[prev in list] [next in list] [prev in thread] [next in thread] 

List:       sanlock-devel
Subject:    tests/devcount.c tests/devcount-dmsetup
From:       teigland () fedoraproject ! org (David Teigland)
Date:       2011-04-26 21:16:50
Message-ID: 20110426211650.9989F120272 () lists ! fedorahosted ! org
[Download RAW message or body]

 tests/devcount-dmsetup |   28 ++++++
 tests/devcount.c       |  206 ++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 231 insertions(+), 3 deletions(-)

New commits:
commit 1ee905695cc9053412fe58aca267e1f0cd69f0fe
Author: David Teigland <teigland at redhat.com>
Date:   Tue Apr 26 16:15:53 2011 -0500

    devcount: add expire test
    
    forces host_id renewals to expire using dmsetup

diff --git a/tests/devcount-dmsetup b/tests/devcount-dmsetup
new file mode 100755
index 0000000..0a92f76
--- /dev/null
+++ b/tests/devcount-dmsetup
@@ -0,0 +1,28 @@
+#!/bin/bash
+
+if [ $# -le 1 ]; then
+	echo "num $#"
+	echo ""
+	echo "devcount-dmsetup save <dev>"
+	echo ""
+	echo "devcount-dmsetup error <dev>"
+	echo ""
+	echo "devcount-dmsetup linear <dev>"
+	echo ""
+fi
+
+cmd=$1
+dev=$2
+
+if [ "$cmd" == "save" ]; then
+	rm -f /tmp/table-linear.txt
+	rm -f /tmp/table-error.txt
+	dmsetup table $dev > /tmp/table-linear.txt
+	sed "s/linear/error/" /tmp/table-linear.txt > /tmp/table-error.txt
+	exit 0
+fi
+
+dmsetup suspend $dev
+dmsetup load $dev /tmp/table-$cmd.txt
+dmsetup resume $dev
+
diff --git a/tests/devcount.c b/tests/devcount.c
index 4ad389f..fc7a1fb 100644
--- a/tests/devcount.c
+++ b/tests/devcount.c
@@ -380,7 +380,7 @@ static int do_count(int argc, char *argv[])
 		if (write_seconds && (our_we->time - start >= write_seconds))
 			break;
 
-		if (check_pause(pause_fd)) {
+		if (!(writes % 64) && check_pause(pause_fd)) {
 			print_our_we(count_path, our_pid, writes, our_we, "pause");
 			fprintf(stderr, "we_are_paused\n");
 			raise(SIGSTOP);
@@ -436,7 +436,7 @@ static int do_count(int argc, char *argv[])
 	return -1;
 }
 
-static void add_lockspace(void)
+static int add_lockspace(void)
 {
 	int rv;
 
@@ -446,7 +446,11 @@ static void add_lockspace(void)
 	lockspace.host_id = our_hostid;
 
 	rv = sanlock_add_lockspace(&lockspace, 0);
-	printf("%d sanlock_add_lockspace %d\n", getpid(), rv);
+
+	log_debug("%s p %d sanlock_add_lockspace %d",
+		  lock_path, getpid(), rv);
+
+	return rv;
 }
 
 /*
@@ -641,6 +645,7 @@ static int do_relock(int argc, char *argv[])
 
  kill_child:
 		kill_pid(pid);
+		log_debug("%s p %d killed c %d", count_path, parent_pid, pid);
  dead_child:
 		close(c2p[0]);
 		close(c2p[1]);
@@ -1126,6 +1131,7 @@ static int do_migrate(int argc, char *argv[])
 		write_migrate_incoming(state); /* to dest */
 
 		kill_pid(pid);
+		log_debug("%s p %d killed c %d", count_path, parent_pid, pid);
 		close(c2p[0]);
 		close(c2p[1]);
 		free(state);
@@ -1137,6 +1143,195 @@ static int do_migrate(int argc, char *argv[])
 	return -1;
 }
 
+/*
+ * dmsetup table /dev/bull/lock1 > /tmp/table-linear.txt
+ * sed "s/linear/error/" /tmp/table-linear.txt > /tmp/table-error.txt
+ *
+ * dmsetup suspend /dev/bull/lock1
+ * dmsetup load /dev/bull/lock1 /tmp/table-error.txt
+ * dmsetup resume /dev/bull/lock1
+ *
+ * dmsetup suspend /dev/bull/lock1
+ * dmsetup load /dev/bull/lock1 /tmp/table-linear.txt
+ * dmsetup resume /dev/bull/lock1
+ */
+
+static void dmsetup_save_lock_disk(void)
+{
+	char cmd[128];
+	sprintf(cmd, "./devcount-dmsetup save %s", lock_path);
+	system(cmd);
+}
+
+static void dmsetup_error_lock_disk(void)
+{
+	char cmd[128];
+	sprintf(cmd, "./devcount-dmsetup error %s", lock_path);
+	system(cmd);
+}
+
+static void dmsetup_linear_lock_disk(void)
+{
+	char cmd[128];
+	sprintf(cmd, "./devcount-dmsetup linear %s", lock_path);
+	system(cmd);
+}
+
+int do_expire(int argc, char *argv[])
+{
+	char *av[COUNT_ARGS+1];
+	struct sanlk_resource *res;
+	uint32_t parent_pid = getpid();
+	int i, j, pid, rv, sock, len, status;
+	int c2p[2];
+	char result[5];
+
+	if (argc < LOCK_ARGS)
+		return -1;
+
+	count_offset = 0;
+
+	strcpy(lock_path, argv[2]);
+	strcpy(count_path, argv[4]);
+	our_hostid = atoi(argv[7]);
+
+	dmsetup_save_lock_disk();
+
+	add_lockspace();
+
+	len = sizeof(struct sanlk_resource) + sizeof(struct sanlk_disk);
+	res = malloc(len);
+	memset(res, 0, len);
+	strcpy(res->lockspace_name, lockspace.name);
+	snprintf(res->name, SANLK_NAME_LEN, "resource%s", count_path);
+	res->name[SANLK_NAME_LEN-1] = '\0';
+	res->num_disks = 1;
+	strncpy(res->disks[0].path, lock_path, SANLK_PATH_LEN);
+	res->disks[0].path[SANLK_PATH_LEN-1] = '\0';
+	res->disks[0].offset = 1024000;
+
+	/* 
+	 * argv[0] = devcount
+	 * argv[1] = expire
+	 * argv[2] = <lock_disk>
+	 * argv[3] = rw
+	 * start copying at argv[3]
+	 */
+
+	j = 0;
+	av[j++] = strdup(argv[0]);
+	for (i = 3; i < LOCK_ARGS; i++)
+		av[j++] = strdup(argv[i]);
+	av[j] = NULL;
+
+	while (1) {
+		pipe(c2p);
+
+		pid = fork();
+		if (!pid) {
+			int child_pid = getpid();
+
+			sock = sanlock_register();
+			if (sock < 0) {
+				log_error("%s c %d sanlock_register error %d",
+					  count_path, child_pid, sock);
+				exit(-1);
+			}
+
+			/* this acquire can take up to 90 seconds waiting for
+			   the host_id of the owner to time out */
+
+			log_debug("%s c %d sanlock_acquire begin",
+				  count_path, child_pid);
+
+			rv = sanlock_acquire(sock, -1, 0, 1, &res, NULL);
+			if (rv < 0) {
+				log_debug("%s c %d sanlock_acquire error %d",
+					  count_path, child_pid, rv);
+
+				/* all hosts are trying to acquire so we
+				   expect this to acquire only sometimes;
+				   TODO: exit with an error for some rv's */
+
+				write(c2p[1], "fail", 4);
+				close(c2p[0]);
+				close(c2p[1]);
+				exit(0);
+			}
+			log_debug("%s c %d sanlock_acquire done",
+				  count_path, child_pid);
+
+			write(c2p[1], "good", 4);
+			close(c2p[0]);
+			close(c2p[1]);
+			execv(av[0], av);
+			perror("execv devcount problem");
+			exit(EXIT_FAILURE);
+		}
+
+		memset(&result, 0, sizeof(result));
+		read(c2p[0], &result, 4);
+		close(c2p[0]);
+		close(c2p[1]);
+
+		if (strstr(result, "fail")) {
+			/* we expect child to exit when it fails to acquire the
+			   lock because it's held by someone else */
+			waitpid(pid, &status, 0);
+			goto dead_child;
+		}
+
+		/* this test should be run with sec2 set to some large value
+		   that won't run out before sanlock daemon kills rw */
+
+		sleep(rand_int(6, 100));
+
+		dmsetup_error_lock_disk();
+		log_debug("%s p %d disable %s", count_path, parent_pid, lock_path);
+
+		/* sanlock daemon kills pid when the renewals fail; after the
+		   kill it will try to release the resource lease, which will
+		   also fail if the resource lease is on the same disk as the
+		   host_id lease.  Other nodes trying to get pid's resource
+		   lease are watching our host_id for 90 seconds, after which
+		   they will take pid's resource lease.  If the resource lease
+		   is on a different disk, the daemon will be able to release
+		   it after the kill, and another node will be able to take it
+		   immediately after that, without watching our host_id for 90
+		   seconds */
+
+		/* other nodes can't rely on the daemon being able to kill rw,
+		   so they need to wait 90 seconds to ensure that the watchdog
+		   has killed the host before taking pid's resource lease.
+		   In a different test, have the daemon kill fail, causing rw
+		   to continue running until the watchdog fires, after which
+		   another host will take pid's resource lease */
+
+		waitpid(pid, &status, 0);
+		log_debug("%s p %d waitpid c %d done", count_path, parent_pid, pid);
+
+		sleep(rand_int(0, 3));
+
+		dmsetup_linear_lock_disk();
+		log_debug("%s p %d enable %s", count_path, parent_pid, lock_path);
+
+		log_debug("%s p %d sanlock_add_lockspace begin",
+			  lock_path, parent_pid);
+		while (1) {
+			sleep(1);
+			rv = add_lockspace();
+			if (!rv)
+				break;
+		}
+ dead_child:
+		sleep(rand_int(0, 1));
+	}
+
+	printf("test failed...\n");
+	sleep(1000000);
+	return -1;
+}
+
 /* 
  * devcount init <lock_disk> <count_disk>
  * sanlock direct init -n 8 -s devcount:0:<lock_disk>:0
@@ -1248,6 +1443,9 @@ int main(int argc, char *argv[])
 	else if (!strcmp(argv[1], "migrate"))
 		rv = do_migrate(argc, argv);
 
+	else if (!strcmp(argv[1], "expire"))
+		rv = do_expire(argc, argv);
+
 	if (!rv)
 		return 0;
 
@@ -1281,10 +1479,12 @@ int main(int argc, char *argv[])
 	printf("devcount wrap <lock_disk> rw <count_disk> <sec1> <sec2> <hostid>\n");
 	printf("  sanlock add_lockspace -s devcount:<hostid>:<lock_disk>:0\n");
 	printf("  sanlock_acquire, exec devcount rw\n");
+	printf("\n");
 	printf("devcount migrate <lock_disk> rw <count_disk> <sec1> <sec2> <hostid> <max_hostid>\n");
 	printf("  sanlock add_lockspace -s devcount:<hostid>:<lock_disk>:0\n");
 	printf("  loop around fork, sanlock_acquire, exec devcount rw\n");
 	printf("\n");
+	printf("devcount expire <lock_disk> rw <count_disk> <sec1> <sec2> <hostid>\n");
 	printf("\n");
 	return -1;
 }



[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic