[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