[Ocfs2-test-devel] [PATCH 2/2] Ocfs2-test: Add semaphore to protect file_writes and log_writes.
Tristan Ye
tristan.ye at oracle.com
Thu Dec 3 02:47:48 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. and we also
want the crash will be right after a successful write or reflink.
Signed-off-by: Tristan Ye <tristan.ye at oracle.com>
---
programs/reflink_tests/reflink_test.c | 78 +++++++++++++++++++++++----
programs/reflink_tests/reflink_test.h | 15 +++++
programs/reflink_tests/reflink_test_utils.c | 57 +++++++++++++++++++
3 files changed, 140 insertions(+), 10 deletions(-)
diff --git a/programs/reflink_tests/reflink_test.c b/programs/reflink_tests/reflink_test.c
index 41bd544..9c95a24 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, 1);
+ if (ret < 0) {
+ fprintf(stderr, "Set semaphore value failed!\n");
+ return ret;
+ }
+
while (align_filesz < file_size)
align_filesz += CHUNK_SIZE;
@@ -1876,6 +1893,11 @@ static int destructive_test(void)
for (j = 0; j < chunk_no; j++) {
+ if (semaphore_p(sem_id) < 0) {
+ ret = -1;
+ goto child_bail;
+ }
+
memset(log_rec, 0, sizeof(log_rec));
prep_rand_dest_write_unit(&dwu, get_rand(0,
chunk_no - 1));
@@ -1886,22 +1908,38 @@ static int destructive_test(void)
ret = do_write_chunk(fd, &dwu);
if (ret)
- return -1;
+ goto child_bail;
write(sockfd, log_rec, strlen(log_rec) + 1);
+ if (semaphore_v(sem_id) < 0) {
+ ret = -1;
+ goto child_bail;
+ }
+
if (get_rand(0, 1)) {
+
+ if (semaphore_p(sem_id) < 0) {
+ ret = -1;
+ goto child_bail;
+ }
+
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);
+ ret = reflink(orig_path, dest, 1);
+ if (ret)
+ goto child_bail;
write(sockfd, log_rec,
strlen(log_rec) + 1);
-
+
+ if (semaphore_v(sem_id) < 0) {
+ ret = -1;
+ goto child_bail;
+ }
}
/*
@@ -1909,21 +1947,38 @@ static int destructive_test(void)
*/
if ((j > 1) && (j < chunk_no - 1)) {
- if (get_rand(1, chunk_no) == chunk_no / 2)
+ if (get_rand(1, chunk_no) == chunk_no / 2) {
+
+ if (semaphore_p(sem_id) < 0) {
+ ret = -1;
+ goto child_bail;
+ }
+
system("echo b>/proc/sysrq-trigger");
- } else if (j == chunk_no - 1)
+ }
+ } else if (j == chunk_no - 1) {
+
+ if (semaphore_p(sem_id) < 0) {
+ ret = -1;
+ goto child_bail;
+ }
+
system("echo b>/proc/sysrq-trigger");
+ }
usleep(10000);
}
-
- if (!fd)
+child_bail:
+ if (fd)
close(fd);
- if (!sockfd)
+ if (sockfd)
close(sockfd);
- exit(0);
+ if (sem_id)
+ semaphore_close(sem_id);
+
+ exit(ret);
}
if (pid > 0)
@@ -1960,6 +2015,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..3db48f1 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 val);
+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..925cb41 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, int val)
+{
+ union semun sem_union;
+
+ sem_union.val = val;
+ 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