From patchwork Fri Mar 12 12:02:17 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yang Xu X-Patchwork-Id: 1451947 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.linux.it (client-ip=2001:1418:10:5::2; helo=picard.linux.it; envelope-from=ltp-bounces+incoming=patchwork.ozlabs.org@lists.linux.it; receiver=) Received: from picard.linux.it (picard.linux.it [IPv6:2001:1418:10:5::2]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4Dxkvm5j8rz9sS8 for ; Fri, 12 Mar 2021 23:02:26 +1100 (AEDT) Received: from picard.linux.it (localhost [IPv6:::1]) by picard.linux.it (Postfix) with ESMTP id 119F33C684C for ; Fri, 12 Mar 2021 13:02:22 +0100 (CET) X-Original-To: ltp@lists.linux.it Delivered-To: ltp@picard.linux.it Received: from in-4.smtp.seeweb.it (in-4.smtp.seeweb.it [217.194.8.4]) by picard.linux.it (Postfix) with ESMTP id 09CE03C6828 for ; Fri, 12 Mar 2021 13:02:19 +0100 (CET) Received: from heian.cn.fujitsu.com (mail.cn.fujitsu.com [183.91.158.132]) by in-4.smtp.seeweb.it (Postfix) with ESMTP id 9BE2A100134C for ; Fri, 12 Mar 2021 13:02:18 +0100 (CET) IronPort-HdrOrdr: A9a23:s1OYCq6bvx2FmzuhqgPXwCjXdLJzesId70hD6mlaTxtJfsuE0/2/hfhz726RtB89elEF3eqBNq6JXG/G+fdOjLU5EL++UGDd1leAA41v4IDryT+lOwCWzIRg/Ih6dawWMrzNJHxbqeq/3wWiCdYnx7C8gcWVrMPT1W1kQw0vS4wI1XYbNi+hHkd7RBZLCPMCffLy2uN8uzGidX4LB/7LZEUtYu6rnb32vaOjSRsHKjpi0wOWkA6vgYSQLzGomjsYTBNDqI1PzVT4 X-IronPort-AV: E=Sophos;i="5.81,243,1610380800"; d="scan'208";a="105549566" Received: from unknown (HELO cn.fujitsu.com) ([10.167.33.5]) by heian.cn.fujitsu.com with ESMTP; 12 Mar 2021 20:02:16 +0800 Received: from G08CNEXMBPEKD04.g08.fujitsu.local (unknown [10.167.33.201]) by cn.fujitsu.com (Postfix) with ESMTP id 1BE984CEA9A2 for ; Fri, 12 Mar 2021 20:02:12 +0800 (CST) Received: from localhost.localdomain (10.167.220.84) by G08CNEXMBPEKD04.g08.fujitsu.local (10.167.33.201) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Fri, 12 Mar 2021 20:02:12 +0800 From: Yang Xu To: Date: Fri, 12 Mar 2021 20:02:17 +0800 Message-ID: <1615550541-21714-1-git-send-email-xuyang2018.jy@cn.fujitsu.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <20201111163114.GB23576@yuki.lan> References: <20201111163114.GB23576@yuki.lan> MIME-Version: 1.0 X-Originating-IP: [10.167.220.84] X-ClientProxiedBy: G08CNEXCHPEKD06.g08.fujitsu.local (10.167.33.205) To G08CNEXMBPEKD04.g08.fujitsu.local (10.167.33.201) X-yoursite-MailScanner-ID: 1BE984CEA9A2.AE330 X-yoursite-MailScanner: Found to be clean X-yoursite-MailScanner-From: xuyang2018.jy@cn.fujitsu.com X-Spam-Status: No, score=0.1 required=7.0 tests=KHOP_HELO_FCRDNS, SPF_HELO_NONE, SPF_NONE autolearn=disabled version=3.4.4 X-Virus-Scanned: clamav-milter 0.102.4 at in-4.smtp.seeweb.it X-Virus-Status: Clean X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on in-4.smtp.seeweb.it Subject: [LTP] [PATCH v4 1/5] libs/libltpnewipc/libnewipc.c: Add msg_do_reader/msg_do_writer function X-BeenThere: ltp@lists.linux.it X-Mailman-Version: 2.1.29 Precedence: list List-Id: Linux Test Project List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: ltp-bounces+incoming=patchwork.ozlabs.org@lists.linux.it Sender: "ltp" Copy old libmsgctl.c three functions(doreader,dowriter,verify) into libnewipc.c. It is prepared for upcoming new api msgstress case. The reason for not using a new c lib file(ie libnewmsgctl.c) is that current libnewipc is small(only has getipckey, get_used_queues, probe_free_addr, get_ipc_timestamp function). So put them into libnewipc.c. Also use tst_brk for failure because we don't want to print many info in stress test when case fails. Signed-off-by: Yang Xu --- include/libnewipc.h | 11 +++++ libs/libltpnewipc/libnewipc.c | 75 +++++++++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+) diff --git a/include/libnewipc.h b/include/libnewipc.h index 075364f85..0f099c939 100644 --- a/include/libnewipc.h +++ b/include/libnewipc.h @@ -45,6 +45,14 @@ #define INT_SIZE 4 #define MODE_MASK 0x01FF +struct mbuffer { + long type; + struct { + char len; + char pbytes[99]; + } data; +}; + key_t getipckey(const char *file, const int lineno); #define GETIPCKEY() \ getipckey(__FILE__, __LINE__) @@ -59,4 +67,7 @@ void *probe_free_addr(const char *file, const int lineno); time_t get_ipc_timestamp(void); +void msg_do_reader(long key, int tid, long type, int child, int nreps); + +void msg_do_writer(long key, int tid, long type, int child, int nreps); #endif /* newlibipc.h */ diff --git a/libs/libltpnewipc/libnewipc.c b/libs/libltpnewipc/libnewipc.c index d0974bbe0..09871b421 100644 --- a/libs/libltpnewipc/libnewipc.c +++ b/libs/libltpnewipc/libnewipc.c @@ -99,3 +99,78 @@ time_t get_ipc_timestamp(void) return ts.tv_sec; } + +static int verify(char *buf, char val, int size, int child) +{ + while (size-- > 0) { + if (*buf++ != val) { + tst_res(TFAIL, + "Verify error in child %d, *buf = %x, val = %x, size = %d", + child, *buf, val, size); + return 1; + } + } + return 0; +} + +void msg_do_reader(long key, int tid, long type, int child, int nreps) +{ + int i, size; + int id; + struct mbuffer buffer; + + id = SAFE_MSGGET(key, 0); + if (id != tid) { + tst_brk(TFAIL, + "Message queue mismatch in the reader of child group %d for message queue id %d ", + child, id); + } + for (i = 0; i < nreps; i++) { + memset(&buffer, 0, sizeof(buffer)); + + size = SAFE_MSGRCV(id, &buffer, 100, type, 0); + if (buffer.type != type) { + tst_brk(TFAIL, + "Type mismatch in child %d, read #%d, for message got %ld, exected %ld", + child, (i + 1), buffer.type, type); + } + if (buffer.data.len + 1 != size) { + tst_brk(TFAIL, + "Size mismatch in child %d, read #%d, for message got %d, expected %d", + child, (i + 1), buffer.data.len + 1, size); + } + if (verify(buffer.data.pbytes, (key % 255), size - 1, child)) { + tst_brk(TFAIL, + "Verify failed in child %d read # = %d, key = %lx", + child, (i + 1), key); + } + key++; + } +} + +void msg_do_writer(long key, int tid, long type, int child, int nreps) +{ + int i, size; + int id; + struct mbuffer buffer; + + id = SAFE_MSGGET(key, 0); + if (id != tid) { + tst_brk(TFAIL, + "Message queue mismatch in the writer of child group %d for message queue id %d", + child, id); + } + + for (i = 0; i < nreps; i++) { + memset(&buffer, 0, sizeof(buffer)); + + do { + size = (lrand48() % 99); + } while (size == 0); + memset(buffer.data.pbytes, (key % 255), size); + buffer.data.len = size; + buffer.type = type; + SAFE_MSGSND(id, &buffer, size + 1, 0); + key++; + } +} From patchwork Fri Mar 12 12:02:18 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yang Xu X-Patchwork-Id: 1451948 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.linux.it (client-ip=213.254.12.146; helo=picard.linux.it; envelope-from=ltp-bounces+incoming=patchwork.ozlabs.org@lists.linux.it; receiver=) Received: from picard.linux.it (picard.linux.it [213.254.12.146]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4Dxkvy5RRMz9sS8 for ; Fri, 12 Mar 2021 23:02:38 +1100 (AEDT) Received: from picard.linux.it (localhost [IPv6:::1]) by picard.linux.it (Postfix) with ESMTP id B39883C6857 for ; Fri, 12 Mar 2021 13:02:35 +0100 (CET) X-Original-To: ltp@lists.linux.it Delivered-To: ltp@picard.linux.it Received: from in-6.smtp.seeweb.it (in-6.smtp.seeweb.it [IPv6:2001:4b78:1:20::6]) by picard.linux.it (Postfix) with ESMTP id 195AB3C682A for ; Fri, 12 Mar 2021 13:02:32 +0100 (CET) Received: from heian.cn.fujitsu.com (mail.cn.fujitsu.com [183.91.158.132]) by in-6.smtp.seeweb.it (Postfix) with ESMTP id 736F21401399 for ; Fri, 12 Mar 2021 13:02:29 +0100 (CET) IronPort-HdrOrdr: A9a23:Gj5SFKvehtjf8S3XeDlW3Jkv7skDltV00zAX/kB9WHVpW+afkN2jm+le6A/shF8qKRUdsP2jGI3Fe3PT8pZp/ZIcVI3OYCDKsHalRbsN0aLMzzHsECX19Kp8+M5bGZRWJ8b3CTFB7PrSxCmdP5IezMKc8Kau7N2uqktFaQ1xcalv40NYJ2+gYy5LbTJLD5Y4C5aQj/Avz1WdUE4KZce2DGRtZZmgm/T3kvvdASIuNloO7QmiqXeS4qfmLh7w5HwjegIK7bA80WWtqWDE2pk= X-IronPort-AV: E=Sophos;i="5.81,243,1610380800"; d="scan'208";a="105549576" Received: from unknown (HELO cn.fujitsu.com) ([10.167.33.5]) by heian.cn.fujitsu.com with ESMTP; 12 Mar 2021 20:02:28 +0800 Received: from G08CNEXMBPEKD04.g08.fujitsu.local (unknown [10.167.33.201]) by cn.fujitsu.com (Postfix) with ESMTP id 25B6A4CEA9A0 for ; Fri, 12 Mar 2021 20:02:24 +0800 (CST) Received: from localhost.localdomain (10.167.220.84) by G08CNEXMBPEKD04.g08.fujitsu.local (10.167.33.201) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Fri, 12 Mar 2021 20:02:14 +0800 From: Yang Xu To: Date: Fri, 12 Mar 2021 20:02:18 +0800 Message-ID: <1615550541-21714-2-git-send-email-xuyang2018.jy@cn.fujitsu.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1615550541-21714-1-git-send-email-xuyang2018.jy@cn.fujitsu.com> References: <20201111163114.GB23576@yuki.lan> <1615550541-21714-1-git-send-email-xuyang2018.jy@cn.fujitsu.com> MIME-Version: 1.0 X-Originating-IP: [10.167.220.84] X-ClientProxiedBy: G08CNEXCHPEKD06.g08.fujitsu.local (10.167.33.205) To G08CNEXMBPEKD04.g08.fujitsu.local (10.167.33.201) X-yoursite-MailScanner-ID: 25B6A4CEA9A0.AEE27 X-yoursite-MailScanner: Found to be clean X-yoursite-MailScanner-From: xuyang2018.jy@cn.fujitsu.com X-Spam-Status: No, score=0.1 required=7.0 tests=KHOP_HELO_FCRDNS, SPF_HELO_NONE, SPF_NONE autolearn=disabled version=3.4.4 X-Virus-Scanned: clamav-milter 0.102.4 at in-6.smtp.seeweb.it X-Virus-Status: Clean X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on in-6.smtp.seeweb.it Subject: [LTP] [PATCH v4 2/5] syscalls/msgstress01: Convert into new api and merge msgstress03 into it X-BeenThere: ltp@lists.linux.it X-Mailman-Version: 2.1.29 Precedence: list List-Id: Linux Test Project List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: ltp-bounces+incoming=patchwork.ozlabs.org@lists.linux.it Sender: "ltp" Since msgstress01 and msgstress03 has the small difference(whether use procfs value, msgstress01 uses 16 procs 100000 reps as default and msgstress03 uses 10000 procs 10000 reps as default). We can merge the two cases directly by using proper process and rep value in runtest. In here, I use 1000/100000 value as default in msgstress01 tag instead of original 16/10000 value because 16 procs is so small and 1000 procs make more sense(It also not exceed the maximum process limit). After this change, excuting msgstress01 doesn't take a lot of time than before. msgstress03 tag uses "msgstress01 -n 10000 -l 10000" to replace. We will use the bigger process num when we add process num check according into available memory in the future. Of course, we can add it into smoke-test at that time since it may take a lot of time. Some changes since old api: 1) cleanup is useless since tid value is always -1 because we assign value in child but use it in parent. Use a tid array instead and put the position of getting msgget id into parent process. 2)Ignore SIGTERM instead of empty signhanlder and sighold/sigrelease 3)Add get_avail_queues and setup_msg_key_array in new ipc library 4)Add timeout=-1 since it maybe a smoke test when using bigger proc num or reps num Signed-off-by: Yang Xu --- include/libnewipc.h | 11 + libs/libltpnewipc/libnewipc.c | 39 +++ runtest/syscalls | 2 +- runtest/syscalls-ipc | 2 +- .../kernel/syscalls/ipc/msgstress/.gitignore | 1 - .../kernel/syscalls/ipc/msgstress/Makefile | 5 +- .../syscalls/ipc/msgstress/msgstress01.c | 314 +++++------------- .../syscalls/ipc/msgstress/msgstress03.c | 290 ---------------- 8 files changed, 131 insertions(+), 533 deletions(-) delete mode 100644 testcases/kernel/syscalls/ipc/msgstress/msgstress03.c diff --git a/include/libnewipc.h b/include/libnewipc.h index 0f099c939..c1fa45ec3 100644 --- a/include/libnewipc.h +++ b/include/libnewipc.h @@ -44,6 +44,11 @@ #define SHM_SIZE 2048 #define INT_SIZE 4 #define MODE_MASK 0x01FF +#define MAXNPROCS 1000000 +#define MAXNREPS 100000 + +key_t keyarray[MAXNPROCS]; +int pidarray[MAXNPROCS]; struct mbuffer { long type; @@ -65,9 +70,15 @@ void *probe_free_addr(const char *file, const int lineno); #define PROBE_FREE_ADDR() \ probe_free_addr(__FILE__, __LINE__) +int get_avail_queues(const char *file, const int lineno); +#define GET_AVAIL_QUEUES() \ + get_avail_queues(__FILE__, __LINE__) + time_t get_ipc_timestamp(void); void msg_do_reader(long key, int tid, long type, int child, int nreps); void msg_do_writer(long key, int tid, long type, int child, int nreps); + +void setup_msg_key_array(int nprocs); #endif /* newlibipc.h */ diff --git a/libs/libltpnewipc/libnewipc.c b/libs/libltpnewipc/libnewipc.c index 09871b421..cb885da13 100644 --- a/libs/libltpnewipc/libnewipc.c +++ b/libs/libltpnewipc/libnewipc.c @@ -69,6 +69,19 @@ int get_used_queues(const char *file, const int lineno) return used_queues; } +int get_avail_queues(const char *file, const int lineno) +{ + int used_queues = -1; + int max_queues = -1; + int avail_queues = -1; + + safe_file_scanf(file, lineno, NULL, "/proc/sys/kernel/msgmni", "%d", &max_queues); + used_queues = get_used_queues(file, lineno); + avail_queues = max_queues - used_queues; + + return avail_queues; +} + void *probe_free_addr(const char *file, const int lineno) { void *addr; @@ -174,3 +187,29 @@ void msg_do_writer(long key, int tid, long type, int child, int nreps) key++; } } + +void setup_msg_key_array(int nprocs) +{ + int i, j, ok; + + srand(getpid()); + /* Set up array of unique keys for use in allocating message queues */ + for (i = 0; i < nprocs; i++) { + ok = 1; + do { + keyarray[i] = (key_t) rand(); + /* Make sure key is unique and not private */ + if (keyarray[i] == IPC_PRIVATE) { + ok = 0; + continue; + } + for (j = 0; j < i; j++) { + if (keyarray[j] == keyarray[i]) { + ok = 0; + break; + } + ok = 1; + } + } while (ok == 0); + } +} diff --git a/runtest/syscalls b/runtest/syscalls index fe22ae5b6..68feb9390 100644 --- a/runtest/syscalls +++ b/runtest/syscalls @@ -815,7 +815,7 @@ msgctl05 msgctl05 msgctl06 msgctl06 msgstress01 msgstress01 msgstress02 msgstress02 -msgstress03 msgstress03 +msgstress03 msgstress01 -n 10000 -l 10000 msgstress04 msgstress04 msgctl12 msgctl12 diff --git a/runtest/syscalls-ipc b/runtest/syscalls-ipc index 68fff4038..8adb686c1 100644 --- a/runtest/syscalls-ipc +++ b/runtest/syscalls-ipc @@ -6,7 +6,7 @@ msgctl05 msgctl05 msgctl06 msgctl06 msgstress01 msgstress01 msgstress02 msgstress02 -msgstress03 msgstress03 +msgstress03 msgstress01 -n 10000 -l 10000 msgstress04 msgstress04 msgctl12 msgctl12 diff --git a/testcases/kernel/syscalls/ipc/msgstress/.gitignore b/testcases/kernel/syscalls/ipc/msgstress/.gitignore index a8f675399..e1df4cda8 100644 --- a/testcases/kernel/syscalls/ipc/msgstress/.gitignore +++ b/testcases/kernel/syscalls/ipc/msgstress/.gitignore @@ -1,4 +1,3 @@ /msgstress01 /msgstress02 -/msgstress03 /msgstress04 diff --git a/testcases/kernel/syscalls/ipc/msgstress/Makefile b/testcases/kernel/syscalls/ipc/msgstress/Makefile index b821bda01..27caffb35 100644 --- a/testcases/kernel/syscalls/ipc/msgstress/Makefile +++ b/testcases/kernel/syscalls/ipc/msgstress/Makefile @@ -3,10 +3,11 @@ top_srcdir ?= ../../../../.. -LTPLIBS = ltpipc +LTPLIBS = ltpipc ltpnewipc include $(top_srcdir)/include/mk/testcases.mk -LTPLDLIBS += -lltpipc +msgstress01: LTPLDLIBS = -lltpnewipc +msgstress02 msgstress04: LTPLDLIBS = -lltpipc include $(top_srcdir)/include/mk/generic_leaf_target.mk diff --git a/testcases/kernel/syscalls/ipc/msgstress/msgstress01.c b/testcases/kernel/syscalls/ipc/msgstress/msgstress01.c index 0a660c042..d1954616f 100644 --- a/testcases/kernel/syscalls/ipc/msgstress/msgstress01.c +++ b/testcases/kernel/syscalls/ipc/msgstress/msgstress01.c @@ -1,29 +1,22 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * Copyright (c) International Business Machines Corp., 2002 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See - * the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Copyright (c) 2021 FUJITSU LIMITED. All rights reserved. * * 06/30/2001 Port to Linux nsharoff@us.ibm.com * 11/06/2002 Port to LTP dbarrera@us.ibm.com + * 03/10/2021 Convert to new api xuyang2018.jy@cn.fujitsu.com */ -/* +/*\ + * [DESCRIPTION] + * * Get and manipulate a message queue. - */ + * Fork a number of processes, each of which will create a message queue + * with one reader/writer pair which will read and write a number (iterations) + * of random length messages with specific values. +\*/ -#define _XOPEN_SOURCE 500 #include #include #include @@ -31,271 +24,116 @@ #include #include #include -#include #include #include #include #include #include -#include "test.h" -#include "ipcmsg.h" -#include "libmsgctl.h" - -char *TCID = "msgstress01"; -int TST_TOTAL = 1; - -#ifndef CONFIG_COLDFIRE -#define MAXNPROCS 1000000 /* This value is set to an arbitrary high limit. */ -#else -#define MAXNPROCS 100000 /* Coldfire can't deal with 1000000 */ -#endif -#define MAXNREPS 100000 - -static key_t keyarray[MAXNPROCS]; -static int pidarray[MAXNPROCS]; -static int tid; -static int MSGMNI, nprocs, nreps; -static int procstat; -static int mykid; - -void setup(void); -void cleanup(void); - -static int dotest(key_t key, int child_process); -static void sig_handler(); +#include "tst_test.h" +#include "libnewipc.h" +#include "tst_safe_sysv_ipc.h" +static int nprocs = 1000; +static int nreps = MAXNREPS; static char *opt_nprocs; +static int tid[MAXNPROCS]; static char *opt_nreps; -static option_t options[] = { - {"n:", NULL, &opt_nprocs}, - {"l:", NULL, &opt_nreps}, - {NULL, NULL, NULL}, +static struct tst_option options[] = { + {"n:", &opt_nprocs, "-n N Number of processes"}, + {"l:", &opt_nreps, "-l N Number of iterations"}, + {NULL, NULL, NULL} }; -static void usage(void) -{ - printf(" -n Number of processes\n"); - printf(" -l Number of iterations\n"); -} - -int main(int argc, char **argv) +static void dotest(key_t key, int id, int child_process) { - int i, j, ok, pid; - int count, status; - struct sigaction act; + int pid; - tst_parse_opts(argc, argv, options, usage); - - setup(); - - nreps = MAXNREPS; - nprocs = MSGMNI; - - if (opt_nreps) { - nreps = atoi(opt_nreps); - if (nreps > MAXNREPS) { - tst_resm(TINFO, - "Requested number of iterations too large, " - "setting to Max. of %d", MAXNREPS); - nreps = MAXNREPS; - } - } - - if (opt_nprocs) { - nprocs = atoi(opt_nprocs); - if (nprocs > MSGMNI) { - tst_resm(TINFO, - "Requested number of processes too large, " - "setting to Max. of %d", MSGMNI); - nprocs = MSGMNI; - } + pid = SAFE_FORK(); + if (pid == 0) { + msg_do_reader(key, id, 1, child_process, nreps); + exit(0); } + msg_do_writer(key, id, 1, child_process, nreps); + SAFE_WAIT(NULL); + SAFE_MSGCTL(id, IPC_RMID, NULL); +} - srand(getpid()); - tid = -1; - - /* Setup signal handling routine */ - memset(&act, 0, sizeof(act)); - act.sa_handler = sig_handler; - sigemptyset(&act.sa_mask); - sigaddset(&act.sa_mask, SIGTERM); - if (sigaction(SIGTERM, &act, NULL) < 0) { - tst_brkm(TFAIL, NULL, "Sigset SIGTERM failed"); - } - /* Set up array of unique keys for use in allocating message - * queues - */ - for (i = 0; i < nprocs; i++) { - ok = 1; - do { - /* Get random key */ - keyarray[i] = (key_t) rand(); - /* Make sure key is unique and not private */ - if (keyarray[i] == IPC_PRIVATE) { - ok = 0; - continue; - } - for (j = 0; j < i; j++) { - if (keyarray[j] == keyarray[i]) { - ok = 0; - break; - } - ok = 1; - } - } while (ok == 0); - } +static void verify_msgstress(void) +{ + int i, pid; + int count; - /* Fork a number of processes, each of which will - * create a message queue with one reader/writer - * pair which will read and write a number (iterations) - * of random length messages with specific values. + /* + * Set up array of unique keys for use in allocating message + * queues. */ + setup_msg_key_array(nprocs); for (i = 0; i < nprocs; i++) { - fflush(stdout); - if ((pid = FORK_OR_VFORK()) < 0) { - tst_brkm(TFAIL, - NULL, - "\tFork failed (may be OK if under stress)"); - } - /* Child does this */ + tid[i] = SAFE_MSGGET(keyarray[i], IPC_CREAT | S_IRUSR | S_IWUSR); + pid = SAFE_FORK(); if (pid == 0) { - procstat = 1; - exit(dotest(keyarray[i], i)); + dotest(keyarray[i], tid[i], i); + exit(0); } - pidarray[i] = pid; } count = 0; + while (1) { - if ((wait(&status)) > 0) { - if (status >> 8 != 0) { - tst_brkm(TFAIL, NULL, - "Child exit status = %d", - status >> 8); - } + if (wait(NULL) > 0) { count++; } else { - if (errno != EINTR) { + if (errno != EINTR) break; - } -#ifdef DEBUG - tst_resm(TINFO, "Signal detected during wait"); -#endif } } - /* Make sure proper number of children exited */ - if (count != nprocs) { - tst_brkm(TFAIL, - NULL, - "Wrong number of children exited, Saw %d, Expected %d", - count, nprocs); - } - tst_resm(TPASS, "Test ran successfully!"); + if (count != nprocs) + tst_brk(TFAIL, "Wrong number of children exited, Saw %d, Expected %d", + count, nprocs); - cleanup(); - tst_exit(); + tst_res(TPASS, "Test ran successfully!"); } -static int dotest(key_t key, int child_process) +static void setup(void) { - int id, pid; - int ret, status; - - sighold(SIGTERM); - TEST(msgget(key, IPC_CREAT | S_IRUSR | S_IWUSR)); - if (TEST_RETURN < 0) { - printf("msgget() error in child %d: %s\n", - child_process, strerror(TEST_ERRNO)); - - return FAIL; - } - tid = id = TEST_RETURN; - sigrelse(SIGTERM); + int avail_msg_queues; - fflush(stdout); - if ((pid = FORK_OR_VFORK()) < 0) { - printf("\tFork failed (may be OK if under stress)\n"); - TEST(msgctl(tid, IPC_RMID, 0)); - if (TEST_RETURN < 0) { - printf("mscgtl() error in cleanup: %s\n", - strerror(TEST_ERRNO)); - } - return FAIL; - } - /* Child does this */ - if (pid == 0) - exit(doreader(key, id, 1, child_process, nreps)); - /* Parent does this */ - mykid = pid; - procstat = 2; - ret = dowriter(key, id, 1, child_process, nreps); - wait(&status); + avail_msg_queues = GET_AVAIL_QUEUES(); + if (avail_msg_queues <= 0) + tst_brk(TCONF, "Max message queues is used, cannot create more."); - if (ret != PASS) - exit(FAIL); + if (opt_nreps) + nreps = SAFE_STRTOL(opt_nreps, 1, MAXNREPS); - if ((!WIFEXITED(status) || (WEXITSTATUS(status) != PASS))) - exit(FAIL); + if (opt_nprocs) + nprocs = SAFE_STRTOL(opt_nprocs, 1, MAXNPROCS); - TEST(msgctl(id, IPC_RMID, 0)); - if (TEST_RETURN < 0) { - printf("msgctl() errno %d: %s\n", - TEST_ERRNO, strerror(TEST_ERRNO)); - - return FAIL; + if (nprocs > avail_msg_queues) { + tst_res(TINFO, "Setting max processes to %u", avail_msg_queues); + nprocs = avail_msg_queues; } - return PASS; -} -static void sig_handler(void) -{ + SAFE_SIGNAL(SIGTERM, SIG_IGN); + tst_res(TINFO, "process is %d, iterations is %d", nprocs, nreps); } -void setup(void) +static void cleanup(void) { - int nr_msgqs; - - tst_tmpdir(); - - tst_sig(FORK, DEF_HANDLER, cleanup); + int i = 0; - TEST_PAUSE; - - nr_msgqs = get_max_msgqueues(); - if (nr_msgqs < 0) - cleanup(); - - nr_msgqs -= get_used_msgqueues(); - if (nr_msgqs <= 0) { - tst_resm(TBROK, - "Max number of message queues already used, cannot create more."); - cleanup(); - } - - /* - * Since msgmni scales to the memory size, it may reach huge values - * that are not necessary for this test. - * That's why we define NR_MSGQUEUES as a high boundary for it. - */ - MSGMNI = min(nr_msgqs, NR_MSGQUEUES); + for (i = 0; i < nprocs; i++) + msgctl(tid[i], IPC_RMID, NULL); } -void cleanup(void) -{ - int status; - -#ifdef DEBUG - tst_resm(TINFO, "Removing the message queue"); -#endif - (void)msgctl(tid, IPC_RMID, NULL); - if ((status = msgctl(tid, IPC_STAT, NULL)) != -1) { - (void)msgctl(tid, IPC_RMID, NULL); - tst_resm(TFAIL, "msgctl(tid, IPC_RMID) failed"); - - } - - tst_rmdir(); -} +static struct tst_test test = { + .timeout = -1, + .needs_tmpdir = 1, + .options = options, + .setup = setup, + .cleanup = cleanup, + .forks_child = 1, + .test_all = verify_msgstress, +}; diff --git a/testcases/kernel/syscalls/ipc/msgstress/msgstress03.c b/testcases/kernel/syscalls/ipc/msgstress/msgstress03.c deleted file mode 100644 index 294b401b1..000000000 --- a/testcases/kernel/syscalls/ipc/msgstress/msgstress03.c +++ /dev/null @@ -1,290 +0,0 @@ -/* - * Copyright (c) International Business Machines Corp., 2002 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See - * the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * 06/30/2001 Port to Linux nsharoff@us.ibm.com - * 11/06/2002 Port to LTP dbarrera@us.ibm.com - */ - -/* - * Get and manipulate a message queue. - * Same as msgstress01 but gets the actual msgmni value under procfs. - */ - -#define _XOPEN_SOURCE 500 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "test.h" -#include "ipcmsg.h" -#include "libmsgctl.h" - -char *TCID = "msgstress03"; -int TST_TOTAL = 1; - -#define MAXNPROCS 10000 /*These should be sufficient */ -#define MAXNREPS 10000 /*Else they srewup the system un-necessarily */ - -static key_t keyarray[MAXNPROCS]; -static int pidarray[MAXNPROCS]; -static int tid; -static int MSGMNI, nprocs, nreps; -static int procstat; -static int mykid; - -void setup(void); -void cleanup(void); - -static int dotest(key_t key, int child_process); -static void sig_handler(int signo); - -static char *opt_nprocs; -static char *opt_nreps; - -static option_t options[] = { - {"n:", NULL, &opt_nprocs}, - {"l:", NULL, &opt_nreps}, - {NULL, NULL, NULL}, -}; - -static void usage(void) -{ - printf(" -n Number of processes\n"); - printf(" -l Number of iterations\n"); -} - -int main(int argc, char **argv) -{ - int i, j, ok, pid; - int count, status; - struct sigaction act; - - tst_parse_opts(argc, argv, options, usage); - - setup(); - - nreps = MAXNREPS; - nprocs = MSGMNI; - - if (opt_nreps) { - nreps = atoi(opt_nreps); - if (nreps > MAXNREPS) { - tst_resm(TINFO, - "Requested number of iterations too large, " - "setting to Max. of %d", MAXNREPS); - nreps = MAXNREPS; - } - } - - if (opt_nprocs) { - nprocs = atoi(opt_nprocs); - if (nprocs > MSGMNI) { - tst_resm(TINFO, - "Requested number of processes too large, " - "setting to Max. of %d", MSGMNI); - nprocs = MSGMNI; - } - } - - srand(getpid()); - tid = -1; - - /* Setup signal handling routine */ - memset(&act, 0, sizeof(act)); - act.sa_handler = sig_handler; - sigemptyset(&act.sa_mask); - sigaddset(&act.sa_mask, SIGTERM); - if (sigaction(SIGTERM, &act, NULL) < 0) { - tst_brkm(TFAIL, NULL, "Sigset SIGTERM failed"); - } - /* Set up array of unique keys for use in allocating message - * queues - */ - for (i = 0; i < nprocs; i++) { - ok = 1; - do { - /* Get random key */ - keyarray[i] = (key_t) rand(); - /* Make sure key is unique and not private */ - if (keyarray[i] == IPC_PRIVATE) { - ok = 0; - continue; - } - for (j = 0; j < i; j++) { - if (keyarray[j] == keyarray[i]) { - ok = 0; - break; - } - ok = 1; - } - } while (ok == 0); - } - - /* Fork a number of processes, each of which will - * create a message queue with one reader/writer - * pair which will read and write a number (iterations) - * of random length messages with specific values. - */ - - for (i = 0; i < nprocs; i++) { - fflush(stdout); - if ((pid = FORK_OR_VFORK()) < 0) { - tst_brkm(TFAIL, - NULL, - "\tFork failed (may be OK if under stress)"); - } - /* Child does this */ - if (pid == 0) { - procstat = 1; - exit(dotest(keyarray[i], i)); - } - pidarray[i] = pid; - } - - count = 0; - while (1) { - if ((wait(&status)) > 0) { - if (status >> 8 != 0) { - tst_brkm(TFAIL, NULL, - "Child exit status = %d", - status >> 8); - } - count++; - } else { - if (errno != EINTR) { - break; - } -#ifdef DEBUG - tst_resm(TINFO, "Signal detected during wait"); -#endif - } - } - /* Make sure proper number of children exited */ - if (count != nprocs) { - tst_brkm(TFAIL, - NULL, - "Wrong number of children exited, Saw %d, Expected %d", - count, nprocs); - } - - tst_resm(TPASS, "Test ran successfully!"); - - cleanup(); - tst_exit(); -} - -static int dotest(key_t key, int child_process) -{ - int id, pid; - int ret, status; - - sighold(SIGTERM); - TEST(msgget(key, IPC_CREAT | S_IRUSR | S_IWUSR)); - if (TEST_RETURN < 0) { - printf("msgget() error in child %d: %s\n", - child_process, strerror(TEST_ERRNO)); - return FAIL; - } - tid = id = TEST_RETURN; - sigrelse(SIGTERM); - - fflush(stdout); - if ((pid = FORK_OR_VFORK()) < 0) { - printf("Fork failed (may be OK if under stress)\n"); - TEST(msgctl(tid, IPC_RMID, 0)); - if (TEST_RETURN < 0) { - printf("msgctl() error in cleanup: %s\n", - strerror(TEST_ERRNO)); - } - return FAIL; - } - if (pid == 0) - exit(doreader(key, id, 1, child_process, nreps)); - - mykid = pid; - procstat = 2; - ret = dowriter(key, id, 1, child_process, nreps); - wait(&status); - - if (ret != PASS) - exit(FAIL); - - if ((!WIFEXITED(status) || (WEXITSTATUS(status) != PASS))) - exit(FAIL); - - TEST(msgctl(id, IPC_RMID, 0)); - if (TEST_RETURN < 0) { - printf("msgctl() failed: %s\n", - strerror(TEST_ERRNO)); - return FAIL; - } - return PASS; -} - -static void sig_handler(int signo LTP_ATTRIBUTE_UNUSED) -{ -} - -void setup(void) -{ - int nr_msgqs; - - tst_tmpdir(); - - tst_sig(FORK, DEF_HANDLER, cleanup); - - TEST_PAUSE; - - nr_msgqs = get_max_msgqueues(); - if (nr_msgqs < 0) - cleanup(); - - MSGMNI = nr_msgqs - get_used_msgqueues(); - if (MSGMNI > MAXNPROCS) - MSGMNI = MAXNPROCS; - if (MSGMNI <= 0) { - tst_resm(TBROK, - "Max number of message queues already used, cannot create more."); - cleanup(); - } -} - -void cleanup(void) -{ - int status; - -#ifdef DEBUG - tst_resm(TINFO, "Removing the message queue"); -#endif - (void)msgctl(tid, IPC_RMID, NULL); - if ((status = msgctl(tid, IPC_STAT, NULL)) != -1) { - (void)msgctl(tid, IPC_RMID, NULL); - tst_resm(TFAIL, "msgctl(tid, IPC_RMID) failed"); - - } - - tst_rmdir(); -} From patchwork Fri Mar 12 12:02:19 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yang Xu X-Patchwork-Id: 1451949 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.linux.it (client-ip=2001:1418:10:5::2; helo=picard.linux.it; envelope-from=ltp-bounces+incoming=patchwork.ozlabs.org@lists.linux.it; receiver=) Received: from picard.linux.it (picard.linux.it [IPv6:2001:1418:10:5::2]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4DxkwJ2S2fz9sS8 for ; Fri, 12 Mar 2021 23:02:56 +1100 (AEDT) Received: from picard.linux.it (localhost [IPv6:::1]) by picard.linux.it (Postfix) with ESMTP id A87233C6857 for ; Fri, 12 Mar 2021 13:02:53 +0100 (CET) X-Original-To: ltp@lists.linux.it Delivered-To: ltp@picard.linux.it Received: from in-7.smtp.seeweb.it (in-7.smtp.seeweb.it [IPv6:2001:4b78:1:20::7]) by picard.linux.it (Postfix) with ESMTP id A60173C6828 for ; Fri, 12 Mar 2021 13:02:51 +0100 (CET) Received: from heian.cn.fujitsu.com (mail.cn.fujitsu.com [183.91.158.132]) by in-7.smtp.seeweb.it (Postfix) with ESMTP id 642852000D5 for ; Fri, 12 Mar 2021 13:02:48 +0100 (CET) IronPort-HdrOrdr: A9a23:qIurD61g7dZmuappc6zjOQqjBFIkLtp033Aq2lEZdDV+dMuEm8ey2MkKzBOcskd0ZFgMu/ClfJOBT3TV6IJv7eAqUIuKcQH6tAKTQr1KwofvzjbpES+71sM1781dWodkDtmYNzlHpOLbxCX9LNo62tmA98mT9ILj5lNgVxtjZa0lzyoRMHf5LmRMSANLBYU0GfOnj6IpmxObZX8VYs6nb0N1PdTrmtujrvLbSC9DLxsmxS3Ltjmw9YP9eiLy4j4uFx9J3pcumFKorzDE X-IronPort-AV: E=Sophos;i="5.81,243,1610380800"; d="scan'208";a="105549595" Received: from unknown (HELO cn.fujitsu.com) ([10.167.33.5]) by heian.cn.fujitsu.com with ESMTP; 12 Mar 2021 20:02:47 +0800 Received: from G08CNEXMBPEKD04.g08.fujitsu.local (unknown [10.167.33.201]) by cn.fujitsu.com (Postfix) with ESMTP id 5C47F4CEA9B0 for ; Fri, 12 Mar 2021 20:02:47 +0800 (CST) Received: from localhost.localdomain (10.167.220.84) by G08CNEXMBPEKD04.g08.fujitsu.local (10.167.33.201) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Fri, 12 Mar 2021 20:02:37 +0800 From: Yang Xu To: Date: Fri, 12 Mar 2021 20:02:19 +0800 Message-ID: <1615550541-21714-3-git-send-email-xuyang2018.jy@cn.fujitsu.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1615550541-21714-1-git-send-email-xuyang2018.jy@cn.fujitsu.com> References: <20201111163114.GB23576@yuki.lan> <1615550541-21714-1-git-send-email-xuyang2018.jy@cn.fujitsu.com> MIME-Version: 1.0 X-Originating-IP: [10.167.220.84] X-ClientProxiedBy: G08CNEXCHPEKD06.g08.fujitsu.local (10.167.33.205) To G08CNEXMBPEKD04.g08.fujitsu.local (10.167.33.201) X-yoursite-MailScanner-ID: 5C47F4CEA9B0.A1B47 X-yoursite-MailScanner: Found to be clean X-yoursite-MailScanner-From: xuyang2018.jy@cn.fujitsu.com X-Spam-Status: No, score=0.1 required=7.0 tests=KHOP_HELO_FCRDNS, SPF_HELO_NONE, SPF_NONE autolearn=disabled version=3.4.4 X-Virus-Scanned: clamav-milter 0.102.4 at in-7.smtp.seeweb.it X-Virus-Status: Clean X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on in-7.smtp.seeweb.it Subject: [LTP] [PATCH v4 3/5] syscalls/msgstress02: Convert into new api X-BeenThere: ltp@lists.linux.it X-Mailman-Version: 2.1.29 Precedence: list List-Id: Linux Test Project List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: ltp-bounces+incoming=patchwork.ozlabs.org@lists.linux.it Sender: "ltp" 1)Remove SIGTERM signal handler and ignore it 2)use fork because SAFE_FORK not clean the another writer or reader proceess It also missed process num limit check and we will add it in the future. Signed-off-by: Yang Xu --- .../kernel/syscalls/ipc/msgstress/Makefile | 4 +- .../syscalls/ipc/msgstress/msgstress02.c | 429 +++++------------- 2 files changed, 116 insertions(+), 317 deletions(-) diff --git a/testcases/kernel/syscalls/ipc/msgstress/Makefile b/testcases/kernel/syscalls/ipc/msgstress/Makefile index 27caffb35..d80d0bf98 100644 --- a/testcases/kernel/syscalls/ipc/msgstress/Makefile +++ b/testcases/kernel/syscalls/ipc/msgstress/Makefile @@ -7,7 +7,7 @@ LTPLIBS = ltpipc ltpnewipc include $(top_srcdir)/include/mk/testcases.mk -msgstress01: LTPLDLIBS = -lltpnewipc -msgstress02 msgstress04: LTPLDLIBS = -lltpipc +msgstress01 msgstress02: LTPLDLIBS = -lltpnewipc +msgstress04: LTPLDLIBS = -lltpipc include $(top_srcdir)/include/mk/generic_leaf_target.mk diff --git a/testcases/kernel/syscalls/ipc/msgstress/msgstress02.c b/testcases/kernel/syscalls/ipc/msgstress/msgstress02.c index e15131043..672f79e24 100644 --- a/testcases/kernel/syscalls/ipc/msgstress/msgstress02.c +++ b/testcases/kernel/syscalls/ipc/msgstress/msgstress02.c @@ -1,29 +1,22 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * Copyright (c) International Business Machines Corp., 2002 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See - * the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Copyright (c) 2021 FUJITSU LIMITED. All rights reserved. * * 06/30/2001 Port to Linux nsharoff@us.ibm.com * 11/11/2002 Port to LTP dbarrera@us.ibm.com + * 03/12/2021 Convert to new api xuyang2018.jy@cn.fujitsu.com */ -/* +/*\ + * [DESCRIPTION] + * * Get and manipulate a message queue. - */ + * Fork a number of processes (nprocs), each of which will create a message + * queue with several (nkids) reader/writer pairs which will read and write + * a number (iterations) of random length messages with specific values (keys). +\*/ -#define _XOPEN_SOURCE 500 #include #include #include @@ -35,270 +28,82 @@ #include #include #include -#include "test.h" -#include "ipcmsg.h" -#include "libmsgctl.h" - -char *TCID = "msgstress02"; -int TST_TOTAL = 1; +#include "tst_test.h" +#include "libnewipc.h" +#include "tst_safe_sysv_ipc.h" -#define MAXNREPS 1000 -#ifndef CONFIG_COLDFIRE -#define MAXNPROCS 1000000 /* This value is set to an arbitrary high limit. */ -#else -#define MAXNPROCS 100000 /* Coldfire can't deal with 1000000 */ -#endif #define MAXNKIDS 10 -static key_t keyarray[MAXNPROCS]; -static int pidarray[MAXNPROCS]; static int rkidarray[MAXNKIDS]; static int wkidarray[MAXNKIDS]; -static int tid; -static int nprocs, nreps, nkids, MSGMNI; -static int procstat; - -void setup(void); -void cleanup(void); - -static void term(int); -static int dotest(key_t, int); -static void cleanup_msgqueue(int i, int tid); - +static int tid[MAXNPROCS]; +static int nprocs = 1000; +static int nreps = 1000; +static int nkids = MAXNKIDS; static char *opt_nprocs; static char *opt_nkids; static char *opt_nreps; -static option_t options[] = { - {"n:", NULL, &opt_nprocs}, - {"c:", NULL, &opt_nkids}, - {"l:", NULL, &opt_nreps}, - {NULL, NULL, NULL}, +static struct tst_option options[] = { + {"n:", &opt_nprocs, "-n N Number of processes"}, + {"c:", &opt_nkids, "-c -N Number of read/write child pairs"}, + {"l:", &opt_nreps, "-l N Number of iterations"}, + {NULL, NULL, NULL} }; -static void usage(void) -{ - printf(" -n Number of processes\n"); - printf(" -c Number of read/write child pairs\n"); - printf(" -l Number of iterations\n"); -} - -int main(int argc, char **argv) -{ - int i, j, ok, pid; - int count, status; - - tst_parse_opts(argc, argv, options, usage); - - setup(); - - nreps = MAXNREPS; - nprocs = MSGMNI; - nkids = MAXNKIDS; - - if (opt_nreps) { - nreps = atoi(opt_nreps); - if (nreps > MAXNREPS) { - tst_resm(TINFO, - "Requested number of iterations too large, " - "setting to Max. of %d", MAXNREPS); - nreps = MAXNREPS; - } - } - - if (opt_nprocs) { - nprocs = atoi(opt_nprocs); - if (nprocs > MSGMNI) { - tst_resm(TINFO, - "Requested number of processes too large, " - "setting to Max. of %d", MSGMNI); - nprocs = MSGMNI; - } - } - - if (opt_nkids) { - nkids = atoi(opt_nkids); - if (nkids > MAXNKIDS) { - tst_resm(TINFO, - "Requested number of read/write pairs too " - "large, setting to Max. of %d", MAXNKIDS); - nkids = MAXNKIDS; - } - } - - procstat = 0; - srand48((unsigned)getpid() + (unsigned)(getppid() << 16)); - tid = -1; - - /* Setup signal handleing routine */ - if (sigset(SIGTERM, term) == SIG_ERR) { - tst_brkm(TFAIL, NULL, "Sigset SIGTERM failed"); - } - /* Set up array of unique keys for use in allocating message - * queues - */ - for (i = 0; i < nprocs; i++) { - ok = 1; - do { - /* Get random key */ - keyarray[i] = (key_t) lrand48(); - /* Make sure key is unique and not private */ - if (keyarray[i] == IPC_PRIVATE) { - ok = 0; - continue; - } - for (j = 0; j < i; j++) { - if (keyarray[j] == keyarray[i]) { - ok = 0; - break; - } - ok = 1; - } - } while (ok == 0); - } - /* Fork a number of processes (nprocs), each of which will - * create a message queue with several (nkids) reader/writer - * pairs which will read and write a number (iterations) - * of random length messages with specific values (keys). - */ - - for (i = 0; i < nprocs; i++) { - fflush(stdout); - if ((pid = FORK_OR_VFORK()) < 0) { - tst_brkm(TFAIL, - NULL, - "\tFork failed (may be OK if under stress)"); - } - /* Child does this */ - if (pid == 0) { - procstat = 1; - exit(dotest(keyarray[i], i)); - } - pidarray[i] = pid; - } - - count = 0; - while (1) { - if ((wait(&status)) > 0) { - if (status >> 8 != PASS) { - tst_brkm(TFAIL, NULL, - "Child exit status = %d", - status >> 8); - } - count++; - } else { - if (errno != EINTR) { - break; - } -#ifdef DEBUG - tst_resm(TINFO, "Signal detected during wait"); -#endif - } - } - /* Make sure proper number of children exited */ - if (count != nprocs) { - tst_brkm(TFAIL, - NULL, - "Wrong number of children exited, Saw %d, Expected %d", - count, nprocs); - } - - tst_resm(TPASS, "Test ran successfully!"); - - cleanup(); - tst_exit(); -} - -static void cleanup_msgqueue(int i, int tid) +static void cleanup_msgqueue(int i, int id) { /* - * Decrease the value of i by 1 because it - * is getting incremented even if the fork - * is failing. + * Decrease the value of i by 1 because it is getting incremented + * even if the fork is failing. */ - i--; - /* - * Kill all children & free message queue. - */ + + /* Kill all children & free message queue. */ for (; i >= 0; i--) { (void)kill(rkidarray[i], SIGKILL); (void)kill(wkidarray[i], SIGKILL); } - - if (msgctl(tid, IPC_RMID, 0) < 0) { - tst_brkm(TFAIL | TERRNO, NULL, "Msgctl error in cleanup"); - } + SAFE_MSGCTL(id, IPC_RMID, 0); } -static int dotest(key_t key, int child_process) +static void dotest(key_t key, int child_process, int id) { - int id, pid; - int i, count, status, exit_status; - - sighold(SIGTERM); - if ((id = msgget(key, IPC_CREAT | S_IRUSR | S_IWUSR)) < 0) { - printf("msgget() error in child %d: %s\n", - child_process, strerror(errno)); - return FAIL; - } - tid = id; - sigrelse(SIGTERM); - - exit_status = PASS; + int pid, i, count; for (i = 0; i < nkids; i++) { - fflush(stdout); - if ((pid = FORK_OR_VFORK()) < 0) { - printf("Fork failure in the first child of child group %d\n", + pid = fork(); + if (pid < 0) { + tst_res(TFAIL, "Fork failure in the first child of child group %d\n", child_process); - cleanup_msgqueue(i, tid); - return FAIL; + cleanup_msgqueue(i, id); + return; } /* First child does this */ if (pid == 0) { - procstat = 2; - exit(doreader(key, tid, getpid(), - child_process, nreps)); + msg_do_reader(key, id, getpid(), child_process, nreps); + exit(0); } rkidarray[i] = pid; - fflush(stdout); - if ((pid = FORK_OR_VFORK()) < 0) { - printf("Fork failure in the second child of child group %d\n", - child_process); - /* - * Kill the reader child process - */ - (void)kill(rkidarray[i], SIGKILL); - cleanup_msgqueue(i, tid); - return FAIL; + pid = fork(); + if (pid < 0) { + tst_res(TFAIL, "Fork failure in the second child of child group %d\n", + child_process); + cleanup_msgqueue(i, id); + return; } /* Second child does this */ if (pid == 0) { - procstat = 2; - exit(dowriter(key, tid, rkidarray[i], - child_process, nreps)); + msg_do_writer(key, id, rkidarray[i], child_process, nreps); + exit(0); } wkidarray[i] = pid; } /* Parent does this */ count = 0; while (1) { - if ((wait(&status)) > 0) { - if (status >> 8 != PASS) { - printf("Child exit status = %d from child group %d\n", - status >> 8, child_process); - for (i = 0; i < nkids; i++) { - kill(rkidarray[i], SIGTERM); - kill(wkidarray[i], SIGTERM); - } - if (msgctl(tid, IPC_RMID, 0) < 0) { - printf("msgctl() error: %s\n", - strerror(errno)); - } - return FAIL; - } + if (wait(NULL) > 0) { count++; } else { if (errno != EINTR) { @@ -307,102 +112,96 @@ static int dotest(key_t key, int child_process) } } /* Make sure proper number of children exited */ - if (count != (nkids * 2)) { - printf("Wrong number of children exited in child group %d, saw %d, expected %d\n", + if (count != (nkids * 2)) + tst_res(TFAIL, + "Wrong number of children exited in child group %d, saw %d, expected %d\n", child_process, count, (nkids * 2)); - if (msgctl(tid, IPC_RMID, 0) < 0) { - printf("msgctl() error: %s\n", strerror(errno)); - } - return FAIL; - } - if (msgctl(id, IPC_RMID, 0) < 0) { - printf("msgctl() failure in child group %d: %s\n", - child_process, strerror(errno)); - return FAIL; - } - return exit_status; + + SAFE_MSGCTL(id, IPC_RMID, NULL); } -static void term(int sig LTP_ATTRIBUTE_UNUSED) +static void verify_msgstress(void) { - int i; + int i, pid; + int count; - if (procstat == 0) { -#ifdef DEBUG - tst_resm(TINFO, "SIGTERM signal received, test killing kids"); -#endif - for (i = 0; i < nprocs; i++) { - if (pidarray[i] > 0) { - if (kill(pidarray[i], SIGTERM) < 0) { - printf("Kill failed to kill child %d", - i); - exit(FAIL); - } - } + /* + * Set up array of unique keys for use in allocating message + * queues + */ + setup_msg_key_array(nprocs); + + for (i = 0; i < nprocs; i++) { + tid[i] = SAFE_MSGGET(keyarray[i], IPC_CREAT | S_IRUSR | S_IWUSR); + pid = SAFE_FORK(); + if (pid == 0) { + dotest(keyarray[i], i, tid[i]); + exit(0); } - return; + pidarray[i] = pid; } - if (procstat == 2) { - fflush(stdout); - exit(PASS); - } + count = 0; + while (1) { + if ((wait(NULL)) > 0) { + count++; - if (tid == -1) { - exit(FAIL); + } else { + if (errno != EINTR) + break; + } } - for (i = 0; i < nkids; i++) { - if (rkidarray[i] > 0) - kill(rkidarray[i], SIGTERM); - if (wkidarray[i] > 0) - kill(wkidarray[i], SIGTERM); + /* Make sure proper number of children exited */ + if (count != nprocs) { + tst_brk(TFAIL, + "Wrong number of children exited, Saw %d, Expected %d", + count, nprocs); + return; } + + tst_res(TPASS, "Test ran successfully!"); } -void setup(void) +static void setup(void) { - int nr_msgqs; + int avail_msg_queues; - tst_tmpdir(); + avail_msg_queues = GET_AVAIL_QUEUES(); + if (avail_msg_queues <= 0) + tst_brk(TCONF, "Max message queues is used, cannot create more."); - tst_sig(FORK, DEF_HANDLER, cleanup); + if (opt_nreps) + nreps = SAFE_STRTOL(opt_nreps, 1, MAXNREPS); - TEST_PAUSE; + if (opt_nprocs) + nprocs = SAFE_STRTOL(opt_nprocs, 1, MAXNPROCS); - nr_msgqs = get_max_msgqueues(); - if (nr_msgqs < 0) - cleanup(); - - nr_msgqs -= get_used_msgqueues(); - if (nr_msgqs <= 0) { - tst_resm(TBROK, - "Max number of message queues already used, cannot create more."); - cleanup(); + if (nprocs > avail_msg_queues) { + tst_res(TINFO, "Setting max processes to %u", avail_msg_queues); + nprocs = avail_msg_queues; } - /* - * Since msgmni scales to the memory size, it may reach huge values - * that are not necessary for this test. - * That's why we define NR_MSGQUEUES as a high boundary for it. - */ - MSGMNI = min(nr_msgqs, NR_MSGQUEUES); + if (opt_nkids) + nkids = SAFE_STRTOL(opt_nkids, 1, MAXNKIDS); + + SAFE_SIGNAL(SIGTERM, SIG_IGN); + tst_res(TINFO, "process is %d, iterations is %d, read/write pairs is %d", + nprocs, nreps, nkids); } -void cleanup(void) +static void cleanup(void) { - int status; - -#ifdef DEBUG - tst_resm(TINFO, "Removing the message queue"); -#endif - fflush(stdout); - (void)msgctl(tid, IPC_RMID, NULL); - if ((status = msgctl(tid, IPC_STAT, NULL)) != -1) { - (void)msgctl(tid, IPC_RMID, NULL); - tst_resm(TFAIL, "msgctl(tid, IPC_RMID) failed"); - - } + int i = 0; - fflush(stdout); - tst_rmdir(); + for (i = 0; i < nprocs; i++) + msgctl(tid[i], IPC_RMID, NULL); } + +static struct tst_test test = { + .needs_tmpdir = 1, + .options = options, + .setup = setup, + .cleanup = cleanup, + .forks_child = 1, + .test_all = verify_msgstress, +}; From patchwork Fri Mar 12 12:02:20 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yang Xu X-Patchwork-Id: 1451950 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.linux.it (client-ip=2001:1418:10:5::2; helo=picard.linux.it; envelope-from=ltp-bounces+incoming=patchwork.ozlabs.org@lists.linux.it; receiver=) Received: from picard.linux.it (picard.linux.it [IPv6:2001:1418:10:5::2]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4DxkwX5fwNz9sS8 for ; Fri, 12 Mar 2021 23:03:08 +1100 (AEDT) Received: from picard.linux.it (localhost [IPv6:::1]) by picard.linux.it (Postfix) with ESMTP id 6C5B23C685A for ; Fri, 12 Mar 2021 13:03:05 +0100 (CET) X-Original-To: ltp@lists.linux.it Delivered-To: ltp@picard.linux.it Received: from in-7.smtp.seeweb.it (in-7.smtp.seeweb.it [217.194.8.7]) by picard.linux.it (Postfix) with ESMTP id 6518F3C682A for ; Fri, 12 Mar 2021 13:03:03 +0100 (CET) Received: from heian.cn.fujitsu.com (mail.cn.fujitsu.com [183.91.158.132]) by in-7.smtp.seeweb.it (Postfix) with ESMTP id 50DC1200B00 for ; Fri, 12 Mar 2021 13:03:00 +0100 (CET) IronPort-HdrOrdr: A9a23:C6lAramweEcd2t7WUrpEPvXT4i3pDfLM3DAbvn1ZSRFFG/GwvcaogfgdyFvImC8cMUtQ/eyoFYuhZTfn9ZBz6ZQMJrvKZmTbkUahMY0K1+Xf6hLtFyD0/uRekYdMGpIVNPTeFl5/5Pya3CCdM/INhOaK67qpg+C29QYJcShPZ7t75wl0Tia3e3cGJzVuPpYyGJqC6scvnVPJFkg/VNixBXUOQoH41r/2va/hCCRnOzcXrCGKjR6NrIXxCgWk2H4lOA9n8PMP9nfknmXCipmejw== X-IronPort-AV: E=Sophos;i="5.81,243,1610380800"; d="scan'208";a="105549603" Received: from unknown (HELO cn.fujitsu.com) ([10.167.33.5]) by heian.cn.fujitsu.com with ESMTP; 12 Mar 2021 20:02:59 +0800 Received: from G08CNEXMBPEKD04.g08.fujitsu.local (unknown [10.167.33.201]) by cn.fujitsu.com (Postfix) with ESMTP id CA3D34CEA98A for ; Fri, 12 Mar 2021 20:02:58 +0800 (CST) Received: from localhost.localdomain (10.167.220.84) by G08CNEXMBPEKD04.g08.fujitsu.local (10.167.33.201) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Fri, 12 Mar 2021 20:02:59 +0800 From: Yang Xu To: Date: Fri, 12 Mar 2021 20:02:20 +0800 Message-ID: <1615550541-21714-4-git-send-email-xuyang2018.jy@cn.fujitsu.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1615550541-21714-1-git-send-email-xuyang2018.jy@cn.fujitsu.com> References: <20201111163114.GB23576@yuki.lan> <1615550541-21714-1-git-send-email-xuyang2018.jy@cn.fujitsu.com> MIME-Version: 1.0 X-Originating-IP: [10.167.220.84] X-ClientProxiedBy: G08CNEXCHPEKD06.g08.fujitsu.local (10.167.33.205) To G08CNEXMBPEKD04.g08.fujitsu.local (10.167.33.201) X-yoursite-MailScanner-ID: CA3D34CEA98A.A3C36 X-yoursite-MailScanner: Found to be clean X-yoursite-MailScanner-From: xuyang2018.jy@cn.fujitsu.com X-Spam-Status: No, score=0.1 required=7.0 tests=KHOP_HELO_FCRDNS, SPF_HELO_NONE, SPF_NONE autolearn=disabled version=3.4.4 X-Virus-Scanned: clamav-milter 0.102.4 at in-7.smtp.seeweb.it X-Virus-Status: Clean X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on in-7.smtp.seeweb.it Subject: [LTP] [PATCH v4 4/5] sycalls/msgstress04: Convert into new api X-BeenThere: ltp@lists.linux.it X-Mailman-Version: 2.1.29 Precedence: list List-Id: Linux Test Project List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: ltp-bounces+incoming=patchwork.ozlabs.org@lists.linux.it Sender: "ltp" It also missed process num check according to available memory. Signed-off-by: Yang Xu --- .../kernel/syscalls/ipc/msgstress/Makefile | 5 +- .../syscalls/ipc/msgstress/msgstress04.c | 489 +++++------------- 2 files changed, 142 insertions(+), 352 deletions(-) diff --git a/testcases/kernel/syscalls/ipc/msgstress/Makefile b/testcases/kernel/syscalls/ipc/msgstress/Makefile index d80d0bf98..b1201281d 100644 --- a/testcases/kernel/syscalls/ipc/msgstress/Makefile +++ b/testcases/kernel/syscalls/ipc/msgstress/Makefile @@ -3,11 +3,10 @@ top_srcdir ?= ../../../../.. -LTPLIBS = ltpipc ltpnewipc +LTPLIBS = ltpnewipc include $(top_srcdir)/include/mk/testcases.mk -msgstress01 msgstress02: LTPLDLIBS = -lltpnewipc -msgstress04: LTPLDLIBS = -lltpipc +LTPLDLIBS = -lltpnewipc include $(top_srcdir)/include/mk/generic_leaf_target.mk diff --git a/testcases/kernel/syscalls/ipc/msgstress/msgstress04.c b/testcases/kernel/syscalls/ipc/msgstress/msgstress04.c index f1c124990..b6536e349 100644 --- a/testcases/kernel/syscalls/ipc/msgstress/msgstress04.c +++ b/testcases/kernel/syscalls/ipc/msgstress/msgstress04.c @@ -1,30 +1,23 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * Copyright (c) International Business Machines Corp., 2002 * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See - * the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * * 06/30/2001 Port to Linux nsharoff@us.ibm.com * 11/11/2002 Port to LTP dbarrera@us.ibm.com + * 03/12/2021 Convert to new api xuyang2018.jy@cn.fujitsu.com */ -/* +/*\ + * [DESCRIPTION] + * * Get and manipulate a message queue. - * Same as msgstress02 but gets the actual msgmni value under procfs. - */ + * Fork a number of processes, each of which will create a message queue + * with several (nkids) reader/writer pairs which will read and write a + * number (iterations) of random length messages with specific values (keys). + * We do not fork more than maxnprocs at a time and we fork until all the + * message queues get used. +\*/ -#define _XOPEN_SOURCE 500 #include #include #include @@ -36,415 +29,213 @@ #include #include #include -#include "test.h" -#include "ipcmsg.h" -#include "libmsgctl.h" - -char *TCID = "msgstress04"; -int TST_TOTAL = 1; +#include "tst_test.h" +#include "libnewipc.h" +#include "tst_safe_sysv_ipc.h" -#define MAXNREPS 1000 -#ifndef CONFIG_COLDFIRE -#define MAXNPROCS 1000000 /* This value is set to an arbitrary high limit. */ -#else -#define MAXNPROCS 100000 /* Coldfire can't deal with 1000000 */ -#endif #define MAXNKIDS 10 -#define DEFNKIDS 2 -static int maxnkids = MAXNKIDS; /* Used if pid_max is exceeded */ -static key_t keyarray[MAXNPROCS]; -static int pidarray[MAXNPROCS]; static int rkidarray[MAXNKIDS]; static int wkidarray[MAXNKIDS]; -static int tid; -static int nprocs, nreps, nkids, MSGMNI; -static int maxnprocs; -static int procstat; - -void setup(void); -void cleanup(void); - -static void term(int); -static int dotest(key_t, int); -static void dotest_iteration(int off); -static void cleanup_msgqueue(int i, int tid); - +static int tid[MAXNPROCS]; +static int maxnprocs = MAXNPROCS; +static int nreps = 1000; +static int nkids = MAXNKIDS; +static int MSGMNI, nprocs; static char *opt_maxnprocs; static char *opt_nkids; static char *opt_nreps; -static option_t options[] = { - {"n:", NULL, &opt_maxnprocs}, - {"c:", NULL, &opt_nkids}, - {"l:", NULL, &opt_nreps}, - {NULL, NULL, NULL}, +static struct tst_option options[] = { + {"n:", &opt_maxnprocs, "-n N Number of processes"}, + {"c:", &opt_nkids, "-c -N Number of read/write child pairs"}, + {"l:", &opt_nreps, "-l N Number of iterations"}, + {NULL, NULL, NULL} }; -static void usage(void) -{ - printf(" -n Number of processes\n"); - printf(" -c Number of read/write child pairs\n"); - printf(" -l Number of iterations\n"); -} - - -int main(int argc, char **argv) -{ - int i, j, ok; - - tst_parse_opts(argc, argv, options, usage); - - setup(); - - nreps = MAXNREPS; - nkids = MAXNKIDS; - - if (opt_nreps) { - nreps = atoi(opt_nreps); - if (nreps > MAXNREPS) { - tst_resm(TINFO, - "Requested number of iterations too large, " - "setting to Max. of %d", MAXNREPS); - nreps = MAXNREPS; - } - } - - if (opt_nkids) { - nkids = atoi(opt_nkids); - if (nkids > MAXNKIDS) { - tst_resm(TINFO, - "Requested number of read/write pairs too " - "large, setting to Max. of %d", MAXNKIDS); - nkids = MAXNKIDS; - } - } - - - if (opt_maxnprocs) { - if (atoi(opt_maxnprocs) > maxnprocs) { - tst_resm(TINFO, - "Requested number of processes too large, " - "setting to Max. of %d", MSGMNI); - } else { - maxnprocs = atoi(opt_maxnprocs); - } - } - - procstat = 0; - srand48((unsigned)getpid() + (unsigned)(getppid() << 16)); - tid = -1; - - /* Setup signal handling routine */ - if (sigset(SIGTERM, term) == SIG_ERR) - tst_brkm(TFAIL, cleanup, "Sigset SIGTERM failed"); - - /* Set up array of unique keys for use in allocating message - * queues - */ - for (i = 0; i < MSGMNI; i++) { - ok = 1; - do { - /* Get random key */ - keyarray[i] = (key_t) lrand48(); - /* Make sure key is unique and not private */ - if (keyarray[i] == IPC_PRIVATE) { - ok = 0; - continue; - } - for (j = 0; j < i; j++) { - if (keyarray[j] == keyarray[i]) { - ok = 0; - break; - } - ok = 1; - } - } while (ok == 0); - } - /* Fork a number of processes, each of which will - * create a message queue with several (nkids) reader/writer - * pairs which will read and write a number (iterations) - * of random length messages with specific values (keys). - * - * We do not fork more than maxnprocs at a time and - * we fork until all the message queues get used. - */ - - if (MSGMNI <= maxnprocs) { - nprocs = MSGMNI; - dotest_iteration(0); - } else { - for (i = 0; i < (MSGMNI / maxnprocs); i++) { - nprocs = maxnprocs; - dotest_iteration(i * maxnprocs); - } - - nprocs = MSGMNI % maxnprocs; - dotest_iteration(i * maxnprocs); - } - - tst_resm(TPASS, "Test ran successfully!"); - - cleanup(); - tst_exit(); -} - -static void dotest_iteration(int off) -{ - key_t key; - int i, count, status; - pid_t pid; - - memset(pidarray, 0, sizeof(pidarray)); - - for (i = 0; i < nprocs; i++) { - key = keyarray[off + i]; - - if ((pid = FORK_OR_VFORK()) < 0) - tst_brkm(TFAIL, cleanup, - "Fork failed (may be OK if under stress)"); - - /* Child does this */ - if (pid == 0) { - procstat = 1; - exit(dotest(key, i)); - } - pidarray[i] = pid; - } - - count = 0; - while (1) { - if ((wait(&status)) > 0) { - if (status >> 8 != PASS) - tst_brkm(TFAIL, cleanup, - "Child exit status = %d", status >> 8); - count++; - } else { - if (errno != EINTR) { - break; - } -#ifdef DEBUG - tst_resm(TINFO, "Signal detected during wait"); -#endif - } - } - /* Make sure proper number of children exited */ - if (count != nprocs) - tst_brkm(TFAIL, cleanup, - "Wrong number of children exited, Saw %d, Expected %d", - count, nprocs); -} - -static void cleanup_msgqueue(int i, int tid) +static void cleanup_msgqueue(int i, int id) { /* - * Decrease the value of i by 1 because it - * is getting incremented even if the fork - * is failing. + * Decrease the value of i by 1 because it is getting incremented + * even if the fork is failing. */ - i--; - /* - * Kill all children & free message queue. - */ + /* Kill all children & free message queue. */ for (; i >= 0; i--) { (void)kill(rkidarray[i], SIGKILL); (void)kill(wkidarray[i], SIGKILL); } - - if (msgctl(tid, IPC_RMID, 0) < 0) { - printf("Msgctl error in cleanup_msgqueue %d\n", errno); - exit(FAIL); - } + SAFE_MSGCTL(id, IPC_RMID, 0); } -static int dotest(key_t key, int child_process) +static void dotest(key_t key, int child_process, int id) { - int id, pid; - int i, count, status, exit_status; - - sighold(SIGTERM); - if ((id = msgget(key, IPC_CREAT | S_IRUSR | S_IWUSR)) < 0) { - printf("msgget() error in child %d: %s\n", - child_process, strerror(errno)); - return FAIL; - } - tid = id; - sigrelse(SIGTERM); - - exit_status = PASS; + int pid; + int i, count; for (i = 0; i < nkids; i++) { - if ((pid = FORK_OR_VFORK()) < 0) { - printf("Fork failure in the first child of child group %d\n", + pid = fork(); + if (pid < 0) { + tst_res(TFAIL, + "Fork failure in the first child of child group %d\n", child_process); - cleanup_msgqueue(i, tid); - return FAIL; + cleanup_msgqueue(i, id); + return; } /* First child does this */ if (pid == 0) { - procstat = 2; - exit(doreader(key, tid, getpid(), - child_process, nreps)); + msg_do_reader(key, id, getpid(), child_process, nreps); + exit(0); } rkidarray[i] = pid; - if ((pid = FORK_OR_VFORK()) < 0) { - printf("Fork failure in the second child of child group %d\n", + pid = fork(); + if (pid < 0) { + tst_res(TFAIL, + "Fork failure in the first child of child group %d\n", child_process); - /* - * Kill the reader child process - */ - (void)kill(rkidarray[i], SIGKILL); - - cleanup_msgqueue(i, tid); - return FAIL; + cleanup_msgqueue(i, id); + return; } /* Second child does this */ if (pid == 0) { - procstat = 2; - exit(dowriter(key, tid, rkidarray[i], - child_process, nreps)); + msg_do_writer(key, id, rkidarray[i], child_process, nreps); + exit(0); } wkidarray[i] = pid; } /* Parent does this */ count = 0; while (1) { - if ((wait(&status)) > 0) { - if (status >> 8 != PASS) { - printf("Child exit status = %d from child group %d\n", - status >> 8, child_process); - for (i = 0; i < nkids; i++) { - kill(rkidarray[i], SIGTERM); - kill(wkidarray[i], SIGTERM); - } - if (msgctl(tid, IPC_RMID, 0) < 0) { - printf("msgctl() error: %s\n", - strerror(errno)); - } - return FAIL; - } + if (wait(NULL) > 0) { count++; } else { - if (errno != EINTR) { + if (errno != EINTR) break; - } } } /* Make sure proper number of children exited */ if (count != (nkids * 2)) { - printf("Wrong number of children exited in child group %d, saw %d, expected %d\n", + tst_res(TFAIL, + "Wrong number of children exited in child group %d, saw %d, expected %d\n", child_process, count, (nkids * 2)); - if (msgctl(tid, IPC_RMID, 0) < 0) { - printf("msgctl() error: %s\n", strerror(errno)); - } - return FAIL; } - if (msgctl(id, IPC_RMID, 0) < 0) { - printf("msgctl() failure in child group %d: %s\n", - child_process, strerror(errno)); - return FAIL; - } - return exit_status; + SAFE_MSGCTL(id, IPC_RMID, NULL); } -/* ARGSUSED */ -static void term(int sig LTP_ATTRIBUTE_UNUSED) +static void dotest_iteration(int off) { - int i; + key_t key; + int i, count; + pid_t pid; - if (procstat == 0) { -#ifdef DEBUG - tst_resm(TINFO, "SIGTERM signal received, test killing kids"); -#endif - for (i = 0; i < nprocs; i++) { - if (pidarray[i] > 0) { - if (kill(pidarray[i], SIGTERM) < 0) { - tst_resm(TBROK, - "Kill failed to kill child %d", - i); - exit(FAIL); - } - } - } - return; - } + memset(pidarray, 0, sizeof(pidarray)); + + for (i = 0; i < nprocs; i++) { + key = keyarray[off + i]; + tid[i] = SAFE_MSGGET(key, IPC_CREAT | S_IRUSR | S_IWUSR); + pid = SAFE_FORK(); - if (procstat == 2) { - exit(PASS); + /* Child does this */ + if (pid == 0) { + dotest(key, i, tid[i]); + exit(0); + } + pidarray[i] = pid; } - if (tid == -1) { - exit(FAIL); + count = 0; + while (1) { + if (wait(NULL) > 0) { + count++; + } else { + if (errno != EINTR) + break; + } } - for (i = 0; i < nkids; i++) { - if (rkidarray[i] > 0) - kill(rkidarray[i], SIGTERM); - if (wkidarray[i] > 0) - kill(wkidarray[i], SIGTERM); + /* Make sure proper number of children exited */ + if (count != nprocs) { + tst_brk(TFAIL, + "Wrong number of children exited, Saw %d, Expected %d", + count, nprocs); } } -void setup(void) +static void verify_msgstress(void) { - int nr_msgqs, free_pids; + int i; - tst_tmpdir(); - /* You will want to enable some signal handling so you can capture - * unexpected signals like SIGSEGV. + /* + * Set up array of unique keys for use in allocating message + * queues. */ - tst_sig(FORK, DEF_HANDLER, cleanup); + setup_msg_key_array(MSGMNI); - /* One cavet that hasn't been fixed yet. TEST_PAUSE contains the code to - * fork the test with the -c option. You want to make sure you do this - * before you create your temporary directory. - */ - TEST_PAUSE; + if (MSGMNI <= maxnprocs) { + nprocs = MSGMNI; + dotest_iteration(0); + } else { + for (i = 0; i < (MSGMNI / maxnprocs); i++) { + nprocs = maxnprocs; + dotest_iteration(i * maxnprocs); + } - nr_msgqs = get_max_msgqueues(); - if (nr_msgqs < 0) - tst_brkm(TBROK, cleanup, "get_max_msgqueues() failed"); + nprocs = MSGMNI % maxnprocs; + dotest_iteration(i * maxnprocs); + } - MSGMNI = nr_msgqs - get_used_msgqueues(); - if (MSGMNI <= 0) - tst_brkm(TBROK, cleanup, - "Max number of message queues already used, cannot create more."); + tst_res(TPASS, "Test ran successfully!"); +} - tst_resm(TINFO, "Found %d available message queues", MSGMNI); +static void setup(void) +{ + int free_pids; - free_pids = tst_get_free_pids(cleanup); + MSGMNI = GET_AVAIL_QUEUES(); + if (MSGMNI <= 0) + tst_brk(TCONF, "Max message queues is used, cannot create more."); + tst_res(TINFO, "Found %d available message queues", MSGMNI); + + free_pids = tst_get_free_pids(); if (free_pids < 0) { - tst_brkm(TBROK, cleanup, "Can't obtain free_pid count"); + tst_brk(TBROK, "Can't obtain free_pid count"); } else if (!free_pids) { - tst_brkm(TBROK, cleanup, "No free pids"); + tst_brk(TBROK, "No free pids"); } + if (opt_nreps) + nreps = SAFE_STRTOL(opt_nreps, 1, MAXNREPS); + + if (opt_nkids) + nkids = SAFE_STRTOL(opt_nkids, 1, MAXNKIDS); + + if (opt_maxnprocs) + maxnprocs = SAFE_STRTOL(opt_maxnprocs, 1, MAXNPROCS); + /* We don't use more than a half of available pids. * For each child we fork up to 2*maxnkids grandchildren. */ - maxnprocs = (free_pids / 2) / (1 + 2 * maxnkids); - + maxnprocs = (free_pids / 2) / (1 + 2 * nkids); if (!maxnprocs) - tst_brkm(TBROK, cleanup, "Not enough free pids"); + tst_brk(TBROK, "Not enough free pids"); - tst_resm(TINFO, "Using upto %d pids", free_pids / 2); + SAFE_SIGNAL(SIGTERM, SIG_IGN); + tst_res(TINFO, + "Using upto %d pids, total %d processes, per %d processs %d read/write pairs, %d repeats ", + free_pids/2, MSGMNI, maxnprocs, nkids, nreps); } -void cleanup(void) +static void cleanup(void) { - int status; - - /* - * Remove the message queue from the system - */ -#ifdef DEBUG - tst_resm(TINFO, "Removing the message queue"); -#endif - (void)msgctl(tid, IPC_RMID, NULL); - if ((status = msgctl(tid, IPC_STAT, NULL)) != -1) { - (void)msgctl(tid, IPC_RMID, NULL); - tst_resm(TFAIL, "msgctl(tid, IPC_RMID) failed"); + int i = 0; - } - - tst_rmdir(); + for (i = 0; i < nprocs; i++) + msgctl(tid[i], IPC_RMID, NULL); } + +static struct tst_test test = { + .needs_tmpdir = 1, + .options = options, + .setup = setup, + .cleanup = cleanup, + .forks_child = 1, + .test_all = verify_msgstress, +}; From patchwork Fri Mar 12 12:02:21 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yang Xu X-Patchwork-Id: 1451951 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.linux.it (client-ip=213.254.12.146; helo=picard.linux.it; envelope-from=ltp-bounces+incoming=patchwork.ozlabs.org@lists.linux.it; receiver=) Received: from picard.linux.it (picard.linux.it [213.254.12.146]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4Dxkwp37Mfz9sW1 for ; Fri, 12 Mar 2021 23:03:22 +1100 (AEDT) Received: from picard.linux.it (localhost [IPv6:::1]) by picard.linux.it (Postfix) with ESMTP id B8D9D3C686D for ; Fri, 12 Mar 2021 13:03:17 +0100 (CET) X-Original-To: ltp@lists.linux.it Delivered-To: ltp@picard.linux.it Received: from in-4.smtp.seeweb.it (in-4.smtp.seeweb.it [IPv6:2001:4b78:1:20::4]) by picard.linux.it (Postfix) with ESMTP id 414233C6830 for ; Fri, 12 Mar 2021 13:03:15 +0100 (CET) Received: from heian.cn.fujitsu.com (mail.cn.fujitsu.com [183.91.158.132]) by in-4.smtp.seeweb.it (Postfix) with ESMTP id 8B4C0100127C for ; Fri, 12 Mar 2021 13:03:13 +0100 (CET) IronPort-HdrOrdr: A9a23:My95Rq/Zuiib8N0UY3puk+A4I+orLtY04lQ7vn1ZYxpTb8CeioSSjO0WvCWE7Ao5dVMBvZS7OKeGSW7B7pId2+QsFJqrQQWOggWVBa5v4YboyzfjXw3Sn9Q26Y5OaK57YeeQMXFfreLXpDa1CMwhxt7vytHMuc77w212RQ9nL4FMhj0JaTqzKUF9SAlYCZdRLvP1ifZvnSaqengcc62Adxs4dtXEzueqqLvWJTYCBzMCrDKFlC6U7tfBeCSw71MzVCxuzN4ZnVT4rw== X-IronPort-AV: E=Sophos;i="5.81,243,1610380800"; d="scan'208";a="105549625" Received: from unknown (HELO cn.fujitsu.com) ([10.167.33.5]) by heian.cn.fujitsu.com with ESMTP; 12 Mar 2021 20:03:12 +0800 Received: from G08CNEXMBPEKD04.g08.fujitsu.local (unknown [10.167.33.201]) by cn.fujitsu.com (Postfix) with ESMTP id 35A524CEA9B7 for ; Fri, 12 Mar 2021 20:03:12 +0800 (CST) Received: from localhost.localdomain (10.167.220.84) by G08CNEXMBPEKD04.g08.fujitsu.local (10.167.33.201) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Fri, 12 Mar 2021 20:03:02 +0800 From: Yang Xu To: Date: Fri, 12 Mar 2021 20:02:21 +0800 Message-ID: <1615550541-21714-5-git-send-email-xuyang2018.jy@cn.fujitsu.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1615550541-21714-1-git-send-email-xuyang2018.jy@cn.fujitsu.com> References: <20201111163114.GB23576@yuki.lan> <1615550541-21714-1-git-send-email-xuyang2018.jy@cn.fujitsu.com> MIME-Version: 1.0 X-Originating-IP: [10.167.220.84] X-ClientProxiedBy: G08CNEXCHPEKD06.g08.fujitsu.local (10.167.33.205) To G08CNEXMBPEKD04.g08.fujitsu.local (10.167.33.201) X-yoursite-MailScanner-ID: 35A524CEA9B7.ADF3E X-yoursite-MailScanner: Found to be clean X-yoursite-MailScanner-From: xuyang2018.jy@cn.fujitsu.com X-Spam-Status: No, score=0.1 required=7.0 tests=KHOP_HELO_FCRDNS, SPF_HELO_NONE, SPF_NONE autolearn=disabled version=3.4.4 X-Virus-Scanned: clamav-milter 0.102.4 at in-4.smtp.seeweb.it X-Virus-Status: Clean X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on in-4.smtp.seeweb.it Subject: [LTP] [PATCH v4 5/5] libs/libltpipc: Remove useless function and c file X-BeenThere: ltp@lists.linux.it X-Mailman-Version: 2.1.29 Precedence: list List-Id: Linux Test Project List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: ltp-bounces+incoming=patchwork.ozlabs.org@lists.linux.it Sender: "ltp" Only old msgstress* case use these apis, so we can remove them Signed-off-by: Yang Xu --- include/libmsgctl.h | 39 ---------- libs/libltpipc/libipc.c | 46 ------------ libs/libltpipc/libmsgctl.c | 147 ------------------------------------- 3 files changed, 232 deletions(-) delete mode 100644 include/libmsgctl.h delete mode 100644 libs/libltpipc/libmsgctl.c diff --git a/include/libmsgctl.h b/include/libmsgctl.h deleted file mode 100644 index e1afeab5f..000000000 --- a/include/libmsgctl.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) International Business Machines Corp., 2002 - * Copyright (c) 2013 Oracle and/or its affiliates. All Rights Reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it would be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef __LIBMSGCTL_H__ -#define __LIBMSGCTL_H__ - -#define FAIL 1 -#define PASS 0 - -struct mbuffer { - long type; - struct { - char len; - char pbytes[99]; - } data; -}; - -int doreader(long key, int tid, long type, int child, int nreps); -int dowriter(long key, int tid, long type, int child, int nreps); -int fill_buffer(char *buf, char val, int size); -int verify(char *buf, char val, int size, int child); - -#endif /*__LIBMSGCTL_H__ */ diff --git a/libs/libltpipc/libipc.c b/libs/libltpipc/libipc.c index d94880f54..aeefaa9f4 100644 --- a/libs/libltpipc/libipc.c +++ b/libs/libltpipc/libipc.c @@ -172,49 +172,3 @@ void rm_shm(int shm_id) } #define BUFSIZE 512 - -/* - * Get the number of message queues already in use - */ -int get_used_msgqueues(void) -{ - FILE *f; - int used_queues; - char buff[BUFSIZE]; - - f = popen("ipcs -q", "r"); - if (!f) { - tst_brkm(TBROK | TERRNO, NULL, "pipe failed"); - } - /* FIXME: Start at -4 because ipcs prints four lines of header */ - for (used_queues = -4; fgets(buff, BUFSIZE, f); used_queues++) ; - pclose(f); - if (used_queues < 0) { - tst_brkm(TBROK, NULL, "Could not read output of 'ipcs' to " - "calculate used message queues"); - } - return used_queues; -} - -/* - * Get the max number of message queues allowed on system - */ -int get_max_msgqueues(void) -{ - FILE *f; - char buff[BUFSIZE]; - - /* Get the max number of message queues allowed on system */ - f = fopen("/proc/sys/kernel/msgmni", "r"); - if (!f) { - tst_resm(TBROK, "Could not open /proc/sys/kernel/msgmni"); - return -1; - } - if (!fgets(buff, BUFSIZE, f)) { - fclose(f); - tst_resm(TBROK, "Could not read /proc/sys/kernel/msgmni"); - return -1; - } - fclose(f); - return atoi(buff); -} diff --git a/libs/libltpipc/libmsgctl.c b/libs/libltpipc/libmsgctl.c deleted file mode 100644 index ae459d480..000000000 --- a/libs/libltpipc/libmsgctl.c +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright (c) International Business Machines Corp., 2002 - * Copyright (c) 2013 Oracle and/or its affiliates. All Rights Reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it would be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include "libmsgctl.h" - -int doreader(long key, int tid, long type, int child, int nreps) -{ - int i, size; - int id; - struct mbuffer buffer; - - id = msgget(key, 0); - if (id < 0) { - printf("msgget() error in the reader of child group %d: %s\n", - child, strerror(errno)); - - return FAIL; - } - if (id != tid) { - printf("Message queue mismatch in the reader of child group %d for message queue id %d\n", - child, id); - - return FAIL; - } - for (i = 0; i < nreps; i++) { - memset(&buffer, 0, sizeof(buffer)); - - size = msgrcv(id, &buffer, 100, type, 0); - if (size < 0) { - printf("msgrcv() error in child %d, read # = %d: %s\n", - child, (i + 1), strerror(errno)); - - return FAIL; - } - if (buffer.type != type) { - printf("Type mismatch in child %d, read #d = %d: ", - child, (i + 1)); - printf("for message got %ld, expected - %ld\n", - buffer.type, type); - - return FAIL; - } - if (buffer.data.len + 1 != size) { - printf("Size mismatch in child %d, read # = %d: ", - child, (i + 1)); - printf("for message got %d, expected - %d\n", - buffer.data.len + 1, size); - - return FAIL; - } - if (verify(buffer.data.pbytes, (key % 255), size - 1, child)) { - printf("Verify failed in child %d read # = %d, key = %lx\n", - child, (i + 1), key); - - return FAIL; - } - key++; - } - return PASS; -} - -int dowriter(long key, int tid, long type, int child, int nreps) -{ - int i, size; - int id; - struct mbuffer buffer; - - id = msgget(key, 0); - if (id < 0) { - printf("msgget() error in the writer of child group %d: %s\n", - child, strerror(errno)); - - return FAIL; - } - if (id != tid) { - printf("Message queue mismatch in the reader of child group %d for message queue id %d\n", - child, id); - - return FAIL; - } - - for (i = 0; i < nreps; i++) { - memset(&buffer, 0, sizeof(buffer)); - - do { - size = (lrand48() % 99); - } while (size == 0); - fill_buffer(buffer.data.pbytes, (key % 255), size); - buffer.data.len = size; - buffer.type = type; - if (msgsnd(id, &buffer, size + 1, 0) < 0) { - printf("msgsnd() error in child %d, write # = %d, key = %lx: %s\n", - child, nreps, key, strerror(errno)); - - return FAIL; - } - key++; - } - return PASS; -} - -int fill_buffer(char *buf, char val, int size) -{ - int i; - - for (i = 0; i < size; i++) - buf[i] = val; - return 0; -} - -/* Check a buffer for correct values */ -int verify(char *buf, char val, int size, int child) -{ - while (size-- > 0) { - if (*buf++ != val) { - printf("Verify error in child %d, *buf = %x, val = %x, size = %d\n", - child, *buf, val, size); - - return FAIL; - } - } - return PASS; -}