1a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh#include <stdlib.h> 2a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh#include <stdio.h> 3a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh#include <sys/types.h> 4a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh#include <sys/ipc.h> 5a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh#include <sys/sem.h> 6a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh#include <signal.h> 7a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh#include <assert.h> 8a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh#include <fcntl.h> 9a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh#include <string.h> 10a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh#include <unistd.h> 11a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh#include <wait.h> 12a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh#include <sys/shm.h> 13a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh 14a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh/* 15a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh * Creates dirty data and issue sync at the end. 16a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh * Child creates enough dirty data, issues fsync. Parent synchronizes with 17a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh * child and soon as fsync is issued, dispatches KILL. 18a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh * If KILL was unsuccessful, a flag in shared memory is set. 19a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh * Parent verifies this flag to ensure test result. 20a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh */ 21a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh 22a404bb0ab766a7ee63d6756e5f7e19a2185df162mblighunion semun { 23a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh int val; 24a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh struct semid_ds *buf; 25a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh unsigned short *array; 26a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh struct seminfo *__buf; 27a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh}; 28a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh 29a404bb0ab766a7ee63d6756e5f7e19a2185df162mblighint main(int argc, char ** argv) 30a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh{ 31a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh int shm_id; 32a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh char* shm_addr, *data_array; 33a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh struct shmid_ds shm_desc; 34a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh union semun data; 35a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh struct sembuf op; 36a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh int sem_id; 37a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh 38a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh int status, pid, fd, len, loop; 39a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh int count = 0, ret = 1, data_size; 40a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh int *post_sync; 41a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh 42a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh if (argc != 3) { 43a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh printf("Usage : synctest <len> <loop> \n"); 44a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh exit(1); 45a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh } 46a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh 47a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh len = atoi(argv[1]); 48a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh loop = atoi(argv[2]); 49a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh 50a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh data_size = len * 1024 * 1024; 51a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh 52a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh /* allocate a shared memory segment with size of 10 bytes. */ 53a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh shm_id = shmget(IPC_PRIVATE, 10, IPC_CREAT | IPC_EXCL | 0600); 54a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh if (shm_id == -1) { 55a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh perror("main : shmget \n"); 56a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh exit(1); 57a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh } 58a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh 59a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh /* attach the shared memory segment to our process's address space. */ 60a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh shm_addr = shmat(shm_id, NULL, 0); 61a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh if (!shm_addr) { /* operation failed. */ 62a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh perror("main : shmat \n"); 63a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh goto early_out; 64a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh } 65a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh 66a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh post_sync = (int*) shm_addr; 67a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh *post_sync = 0; 68a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh 69a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh fd = open("testfile", O_RDWR|O_CREAT|O_APPEND|O_NONBLOCK); 70a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh if (!fd) { 71a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh perror("main : Failed to create data file \n"); 72a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh goto out; 73a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh } 74a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh 75a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh data_array = (char *)malloc(data_size * sizeof(char)); 76a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh if (!data_array) { 77a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh perror("main : Not enough memory \n"); 78a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh goto out; 79a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh } 80a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh 81a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh op.sem_num = 0; 82a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh sem_id = semget(IPC_PRIVATE, 1, IPC_CREAT); 83a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh 84a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh if (sem_id < 0){ 85a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh perror("main : semget \n"); 86a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh goto out; 87a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh } 88a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh 89a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh data.val = 0; 90a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh semctl(sem_id, 0, SETVAL, data); 91a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh 92a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh pid = fork(); 93a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh if (pid < 0) 94a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh { 95a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh perror("main : fork failed \n"); 96a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh goto out; 97a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh } 98a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh if (!pid) 99a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh { 100a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh /* child process */ 101a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh while (count++ < loop) { 102a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh write(fd, data_array, data_size * (sizeof(char))); 103a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh } 104a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh 105a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh printf("CHLD : start sync \n"); 106a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh /* increment sema */ 107a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh op.sem_op = 1; 108a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh semop(sem_id, &op, 1); 109a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh 110a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh /* wait for parent */ 111a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh op.sem_op = 0; 112a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh semop(sem_id, &op, 1); 113a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh fsync(fd); 114a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh *post_sync = 1; 115a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh return 0 ; 116a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh } else { 117a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh /* parent process */ 118a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh /* waiting for child to increment sema */ 119a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh op.sem_op = -1; 120a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh semop(sem_id, &op, 1); 121a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh /* some sleep so fsync gets started before we kill*/ 122a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh sleep(1); 123a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh 124a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh ret = kill(pid, SIGKILL); 125a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh if (ret) { 126a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh perror("main : kill failed \n"); 127a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh goto out; 128a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh } 129a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh 130a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh printf("PAR : waiting\n"); 131a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh wait(&status); 132a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh } 133a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh 134a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh ret = *post_sync; 135a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh 136a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh if (!ret) 137a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh printf("PASS : sync interrupted \n"); 138a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh else 139a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh printf("FAIL : sync not interrupted \n"); 140a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh 141a404bb0ab766a7ee63d6756e5f7e19a2185df162mblighout: 142a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh /* detach the shared memory segment from our process's address space. */ 143a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh if (shmdt(shm_addr) == -1) { 144a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh perror("main : shmdt"); 145a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh } 146a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh 147a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh close(fd); 148a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh system("rm -f testfile \n"); 149a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh 150a404bb0ab766a7ee63d6756e5f7e19a2185df162mblighearly_out: 151a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh 152a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh /* de-allocate the shared memory segment. */ 153a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh if (shmctl(shm_id, IPC_RMID, &shm_desc) == -1) { 154a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh perror("main : shmctl"); 155a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh } 156a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh 157a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh return ret; 158a404bb0ab766a7ee63d6756e5f7e19a2185df162mbligh} 159