[Ocfs2-test-devel] [PATCH 2/2] Ocfs2-test: Add semaphore to protect file_writes and log_writes.

Tristan Ye tristan.ye at oracle.com
Wed Dec 2 22:22:20 PST 2009


File writes and log writes together should be finished like a transaction,
we therefore use sem to guarantee the atomicity of such ops.

Signed-off-by: Tristan Ye <tristan.ye at oracle.com>
---
 programs/reflink_tests/reflink_test.c       |   33 ++++++++++++++-
 programs/reflink_tests/reflink_test.h       |   15 +++++++
 programs/reflink_tests/reflink_test_utils.c |   57 +++++++++++++++++++++++++++
 3 files changed, 102 insertions(+), 3 deletions(-)

diff --git a/programs/reflink_tests/reflink_test.c b/programs/reflink_tests/reflink_test.c
index 41bd544..a235382 100755
--- a/programs/reflink_tests/reflink_test.c
+++ b/programs/reflink_tests/reflink_test.c
@@ -1807,6 +1807,23 @@ static int destructive_test(void)
 
 	pid_t pid;
 
+	int sem_id;
+	key_t sem_key = IPC_PRIVATE;
+
+	/*get and init semaphore*/
+	sem_id = semget(sem_key, 1, 0766 | IPC_CREAT);
+	if (sem_id < 0) {
+		sem_id = errno;
+		fprintf(stderr, "semget failed, %s.\n", strerror(sem_id));
+		return -1;
+	}
+
+	ret = set_semvalue(sem_id);
+	if (ret < 0) {
+		fprintf(stderr, "Set semaphore value failed!\n");
+		return ret;
+	}
+
 	while (align_filesz < file_size)
 		align_filesz += CHUNK_SIZE;
 
@@ -1884,24 +1901,31 @@ static int destructive_test(void)
 					 dwu.d_timestamp, dwu.d_checksum,
 					 dwu.d_char);
 
+				if (semaphore_p(sem_id) < 0)
+					exit(-1);
 				ret = do_write_chunk(fd, &dwu);
 				if (ret)
 					return -1;
 				write(sockfd, log_rec, strlen(log_rec) + 1);
+				if (semaphore_v(sem_id) < 0)
+					exit(-1);
 
 				if (get_rand(0, 1)) {
 					snprintf(dest, PATH_MAX,
 						 "%s_target_%d_%d",
 						 orig_path, getpid(), j);
-					ret = reflink(orig_path, dest, 1);
-					should_exit(ret);
 					memset(log_rec, 0, sizeof(log_rec));
 					snprintf(log_rec, sizeof(log_rec),
 						 "Reflink:\t%s\t->\t%s\n",
 						 orig_path, dest);
+					if (semaphore_p(sem_id) < 0)
+						exit(-1);
+					ret = reflink(orig_path, dest, 1);
+					should_exit(ret);
 					write(sockfd, log_rec,
 					      strlen(log_rec) + 1);
-
+					if (semaphore_v(sem_id) < 0)
+						exit(-1);
 				}
 
 				/*
@@ -1960,6 +1984,9 @@ static int destructive_test(void)
 	if (sockfd)
 		close(sockfd);
 
+	if (sem_id)
+		semaphore_close(sem_id);
+
 	return 0;
 }
 
diff --git a/programs/reflink_tests/reflink_test.h b/programs/reflink_tests/reflink_test.h
index 6b12e84..8b45c20 100755
--- a/programs/reflink_tests/reflink_test.h
+++ b/programs/reflink_tests/reflink_test.h
@@ -34,6 +34,7 @@
 #include <inttypes.h>
 #include <linux/types.h>
 #include <sys/time.h>
+#include <sys/sem.h>
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -105,6 +106,13 @@ struct dest_logs {
 	unsigned long index;
 };
 
+union semun {
+	int val;                    /* value for SETVAL */
+	struct semid_ds *buf;       /* buffer for IPC_STAT, IPC_SET */
+	unsigned short int *array;  /* array for GETALL, SETALL */
+	struct seminfo *__buf;      /* buffer for IPC_INFO */
+};
+
 char rand_char(void);
 unsigned long get_rand(unsigned long min, unsigned long max);
 int get_rand_buf(char *buf, unsigned long size);
@@ -165,4 +173,11 @@ long get_verify_logs_num(char *log);
 int verify_dest_file(char *log, struct dest_logs d_log, unsigned long chunk_no);
 int verify_dest_files(char *log, char *orig, unsigned long chunk_no);
 uint32_t crc32_checksum(uint32_t crc, char *p, size_t len);
+
+/* Add utils for semaphore ops */
+int set_semvalue(int sem_id);
+int semaphore_close(int sem_id);
+int semaphore_p(int sem_id);
+int semaphore_v(int sem_id);
+
 #endif
diff --git a/programs/reflink_tests/reflink_test_utils.c b/programs/reflink_tests/reflink_test_utils.c
index 4f314d0..687b19d 100755
--- a/programs/reflink_tests/reflink_test_utils.c
+++ b/programs/reflink_tests/reflink_test_utils.c
@@ -1768,3 +1768,60 @@ bail:
 
 	return ret;
 }
+
+int set_semvalue(int sem_id)
+{
+	union semun sem_union;
+
+	sem_union.val = 1;
+	if (semctl(sem_id, 0, SETVAL, sem_union) == -1) {
+		perror("semctl");
+		return -1;
+	}
+
+	return 0;
+}
+
+int semaphore_close(int sem_id)
+{
+	int ret = 0;
+
+	ret = semctl(sem_id, 1, IPC_RMID);
+	if (ret < 0) {
+		ret = errno;
+		fprintf(stderr, "semctl failed, %s.\n", strerror(ret));
+		return -1;
+	}
+
+	return ret;
+}
+
+int semaphore_p(int sem_id)
+{
+	struct sembuf sem_b;
+
+	sem_b.sem_num = 0;
+	sem_b.sem_op = -1; /* P() */
+	sem_b.sem_flg = SEM_UNDO;
+	if (semop(sem_id, &sem_b, 1) == -1) {
+		fprintf(stderr, "semaphore_p failed\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+int semaphore_v(int sem_id)
+{
+	struct sembuf sem_b;
+
+	sem_b.sem_num = 0;
+	sem_b.sem_op = 1; /* V() */
+	sem_b.sem_flg = SEM_UNDO;
+	if (semop(sem_id, &sem_b, 1) == -1) {
+		fprintf(stderr, "semaphore_v failed\n");
+		return -1;
+	}
+
+	return 0;
+}
-- 
1.5.5




More information about the Ocfs2-test-devel mailing list