[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