[LTP] [PATCH] semctl01: wait for children to exit between tests

Wanlong Gao wanlong.gao@gmail.com
Mon Nov 16 03:42:56 CET 2015


On Fri, Nov 13, 2015 at 02:19:49PM +0100, Jan Stancek wrote:
> This testcase occasionally hanged:
>  semctl01    1  TPASS  :  buf.sem_nsems and buf.sem_perm.mode are correct
>  semctl01    2  TPASS  :  buf.sem_perm.mode is correct
>  semctl01    3  TPASS  :  semaphores have expected values
>  semctl01    4  TPASS  :  number of sleeping processes is correct
>  semctl01    5  TPASS  :  last pid value is correct
>  semctl01    6  TPASS  :  semaphore value is correct
>  semctl01    7  TBROK  :  semctl01.c:338: semop succeeded - cnt_setup
> <hangs here>
> 
> because somop in GETZCNT test unexpectedly suceeded. All children
> are supposed to block here, because semval is not zero.
> 
> Problem is that semctl01 sends SIGKILL to children from previous
> test (GETNCNT), but it doesn't wait for them to finish. Then it
> proceeds to increase semval for GETZCNT test and one child from
> previous test, which is still blocked on sem_op == -1 for SEM4
> and has not exited yet, will decrease semval to 0. This breaks
> GETZCNT test, child unexpectedly completes and becomes zombie.
> Parent process then waits forever in TST_PROCESS_STATE_WAIT()
> for state to be 'S' - sleeping.
> 
> Signed-off-by: Jan Stancek <jstancek@redhat.com>

Acked-by: Wanlong Gao <wanlong.gao@gmail.com>

> ---
>  testcases/kernel/syscalls/ipc/semctl/semctl01.c | 30 +++++++++++++++++++------
>  1 file changed, 23 insertions(+), 7 deletions(-)
> 
> diff --git a/testcases/kernel/syscalls/ipc/semctl/semctl01.c b/testcases/kernel/syscalls/ipc/semctl/semctl01.c
> index 9a516ed5e1f8..39cf64e118a7 100644
> --- a/testcases/kernel/syscalls/ipc/semctl/semctl01.c
> +++ b/testcases/kernel/syscalls/ipc/semctl/semctl01.c
> @@ -45,10 +45,10 @@
>  #ifndef _GNU_SOURCE
>  #define _GNU_SOURCE
>  #endif
> +#include <sys/wait.h>
>  #include "ipcsem.h"
>  
>  char *TCID = "semctl01";
> -int TST_TOTAL = 13;
>  
>  static int sem_id_1 = -1;
>  static int sem_index;
> @@ -120,10 +120,30 @@ static struct test_case_t {
>  	{&sem_id_1, 0, IPC_RMID, func_rmid, SEMUN_CAST & buf, NULL},
>  };
>  
> +int TST_TOTAL = ARRAY_SIZE(TC);
> +
> +static void kill_all_children(void)
> +{
> +	int j, status;
> +
> +	for (j = 0; j < NCHILD; j++) {
> +		if (kill(pid_arr[j], SIGKILL) == -1)
> +			tst_brkm(TBROK | TERRNO, cleanup, "child kill failed");
> +	}
> +
> +	/*
> +	 * make sure children finished before we proceed with next testcase
> +	 */
> +	for (j = 0; j < NCHILD; j++) {
> +		if (wait(&status) == -1)
> +			tst_brkm(TBROK | TERRNO, cleanup, "wait() failed");
> +	}
> +}
> +
>  int main(int argc, char *argv[])
>  {
>  	int lc;
> -	int i, j;
> +	int i;
>  
>  	tst_parse_opts(argc, argv, NULL, NULL);
>  
> @@ -192,11 +212,7 @@ int main(int argc, char *argv[])
>  			switch (TC[i].cmd) {
>  			case GETNCNT:
>  			case GETZCNT:
> -				for (j = 0; j < NCHILD; j++) {
> -					if (kill(pid_arr[j], SIGKILL) == -1)
> -						tst_brkm(TBROK, cleanup,
> -							 "child kill failed");
> -				}
> +				kill_all_children();
>  				break;
>  			}
>  		}
> -- 
> 1.8.3.1
> 
> 
> -- 
> Mailing list info: http://lists.linux.it/listinfo/ltp


More information about the Ltp mailing list