Skip to contentSkip to conversation

dio_sparse: prevent race between kill and signal

PATCH Superseded Jan Stancek 1 participant 2 messages Jun 5, 2012

v1 of 2 Superseded Latest is v2 →

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 dio_sparse: prevent race between kill and signal

If child gets killed before it completes signal(SIGTERM, SIG_DFL), then kill(childpid, SIGTERM) causes testcase to fail, because it is caught by LTP def_handler.

For example:

dio_sparse    0  TINFO  :  Dirtying free blocks
dio_sparse    0  TINFO  :  Starting I/O tests
dio_sparse    1  TBROK  :  unexpected signal 15 received (pid = 10319).
dio_sparse    2  TBROK  :  Remaining cases broken

...

Fix this by adding semaphore to wait until all children complete signal() before killing them.

---
 testcases/kernel/io/ltp-aiodio/dio_sparse.c |   43 +++++++++++++++++++++++++-
 1 files changed, 41 insertions(+), 2 deletions(-)
testcases/kernel/io/ltp-aiodio/dio_sparse.c +41 -2
index e93dcd9..376da33 100644
@@ -30,7 +30,10 @@
 #include <stdio.h>
 #include <unistd.h>
 #include <memory.h>
+#include <sys/ipc.h>
 #include <sys/mman.h>
+#include <sys/sem.h>
+#include <sys/types.h>
 #include <sys/wait.h>
 #include <limits.h>
 #include <getopt.h>
@@ -110,6 +113,13 @@ int main(int argc, char **argv)
 	int c;
 	int children_errors = 0;
 	int ret;
+	int sem_id;
+	struct sembuf sem_op;
+	union semun {
+		int val;
+		struct semid_ds *buf;
+		unsigned short int *array;
+	} u;
 
 	while ((c = getopt(argc, argv, "dw:n:a:s:")) != -1) {
 		char *endp;
@@ -145,6 +155,15 @@ int main(int argc, char **argv)
 	}
 
 	setup();
+
+	if ((sem_id = semget(IPC_PRIVATE, 1, IPC_CREAT|S_IRWXU)) == -1)
+		tst_brkm(TBROK|TERRNO, NULL, "allocate semaphore");
+
+	/* semaphore to hold off killing children */
+	u.val = 0;
+	if (semctl(sem_id, 0, SETVAL, u) == -1)
+		tst_brkm(TBROK|TERRNO, NULL, "init semaphore");
+
 	tst_resm(TINFO, "Dirtying free blocks");
 	dirty_freeblocks(filesize);
 
@@ -153,7 +172,15 @@ int main(int argc, char **argv)
 		switch (pid[i] = fork()) {
 		case 0:
 			signal(SIGTERM, SIG_DFL);
+			sem_op = (struct sembuf) {
+				.sem_num = 0,
+				.sem_op = 1,
+				.sem_flg = 0
+			};
+			if (semop(sem_id, &sem_op, 1) == -1)
+				tst_brkm(TBROK|TERRNO, NULL, "raise semaphore");
 			read_sparse(filename, filesize);
+			/* shouldn't be reached, read_sparse calls exit() */
 		break;
 		case -1:
 			while (i-- > 0)
@@ -168,7 +195,16 @@ int main(int argc, char **argv)
 	ret = dio_sparse(filename, alignment, writesize, filesize);
 
 	tst_resm(TINFO, "Killing childrens(s)");
-	
+
+	/* parent waits until all children complete signal() */
+	sem_op = (struct sembuf) {
+		.sem_num = 0,
+		.sem_op = -num_children,
+		.sem_flg = 0
+	};
+	if (semop(sem_id, &sem_op, 1) == -1)
+		tst_brkm(TBROK|TERRNO, NULL, "lower semaphore");
+
 	for (i = 0; i < num_children; i++)
 		kill(pid[i], SIGTERM);
 
@@ -191,7 +227,10 @@ int main(int argc, char **argv)
 		
 	if (!children_errors && !ret)
 		tst_resm(TPASS, "Test passed");
-	
+
+	if (semctl(sem_id, 0, IPC_RMID) == -1)
+		tst_brkm(TBROK|TERRNO, NULL, "remove semaphore");
+
 	cleanup();
 	tst_exit();
 }

------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and threat landscape has changed and how IT managers can respond. Discussions will include endpoint security, mobile security and the latest in malware threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/

_______________________________________________
Ltp-list mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ltp-list

#1 lore raw

I just came across this commit:

commit d8f1292181b486b2073cc6fe1ec226f5cedea342

Author: Cyril Hrubis <[email protected]>
Date:   Fri Mar 2 13:37:47 2012 +0100

ltp-aiodio: aiodio_sparse fix race condition

which is patch for same situation but in 'aiodio_sparse.c' file. So, it makes sense to fix both in same style.

Regards,
Jan

----- Original Message -----

Quoted 29 lines

From: "Jan Stancek" <[email protected]>
To: [email protected]
Sent: Tuesday, 5 June, 2012 1:29:37 PM
Subject: [LTP] [PATCH] dio_sparse: prevent race between kill and signal

If child gets killed before it completes signal(SIGTERM, SIG_DFL), then kill(childpid, SIGTERM) causes testcase to fail, because it is caught by LTP def_handler.

For example:

dio_sparse    0  TINFO  :  Dirtying free blocks
dio_sparse    0  TINFO  :  Starting I/O tests
dio_sparse    1  TBROK  :  unexpected signal 15 received (pid =

10319).
dio_sparse 2 TBROK : Remaining cases broken
...

Fix this by adding semaphore to wait until all children complete signal() before killing them.

---
 testcases/kernel/io/ltp-aiodio/dio_sparse.c |   43
 +++++++++++++++++++++++++-
 1 files changed, 41 insertions(+), 2 deletions(-)
Quoted 13 lines

------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and threat landscape has changed and how IT managers can respond. Discussions
will include endpoint security, mobile security and the latest in malware
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
Ltp-list mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ltp-list

------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and threat landscape has changed and how IT managers can respond. Discussions will include endpoint security, mobile security and the latest in malware threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
Ltp-list mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ltp-list