Skip to content

Commit 5e4833d

Browse files
committed
Revert "syscalls/msgstress*: cleanup and convert into new api"
This reverts commit e5c1aff. Merged by accident, sorry. Signed-off-by: Cyril Hrubis <[email protected]>
1 parent 9c460b4 commit 5e4833d

File tree

5 files changed

+943
-366
lines changed

5 files changed

+943
-366
lines changed

testcases/kernel/syscalls/ipc/msgstress/Makefile

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,10 @@
33

44
top_srcdir ?= ../../../../..
55

6-
LTPLIBS = ltpnewipc
6+
LTPLIBS = ltpipc
77

88
include $(top_srcdir)/include/mk/testcases.mk
9-
10-
LTPLDLIBS = -lltpnewipc
119
FILTER_OUT_MAKE_TARGETS := msgstress_common
12-
MAKE_TARGETS := $(patsubst $(abs_srcdir)/%.c,%,$(wildcard $(abs_srcdir)/*[1-4].c))
13-
$(MAKE_TARGETS): %: msgstress_common.o
10+
LTPLDLIBS += -lltpipc
1411

1512
include $(top_srcdir)/include/mk/generic_leaf_target.mk
Lines changed: 206 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,25 @@
1-
// SPDX-License-Identifier: GPL-2.0-or-later
21
/*
32
* Copyright (c) International Business Machines Corp., 2002
4-
* Copyright (c) 2020 FUJITSU LIMITED. All rights reserved.
3+
*
4+
* This program is free software; you can redistribute it and/or modify
5+
* it under the terms of the GNU General Public License as published by
6+
* the Free Software Foundation; either version 2 of the License, or
7+
* (at your option) any later version.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
12+
* the GNU General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU General Public License
15+
* along with this program; if not, write to the Free Software
16+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
517
*
618
* 06/30/2001 Port to Linux [email protected]
719
* 11/06/2002 Port to LTP [email protected]
8-
* 10/21/2020 Convert to new api [email protected]
9-
*
20+
*/
21+
22+
/*
1023
* Get and manipulate a message queue.
1124
*/
1225

@@ -18,61 +31,105 @@
1831
#include <stdlib.h>
1932
#include <stdio.h>
2033
#include <unistd.h>
34+
#include <values.h>
2135
#include <sys/types.h>
2236
#include <sys/wait.h>
2337
#include <sys/stat.h>
2438
#include <sys/ipc.h>
2539
#include <sys/msg.h>
26-
#include "tst_test.h"
27-
#include "libnewipc.h"
28-
#include "tst_safe_sysv_ipc.h"
29-
#include "msgstress_common.h"
40+
#include "test.h"
41+
#include "ipcmsg.h"
42+
#include "libmsgctl.h"
3043

31-
#define MAXNPROCS 1000000
44+
char *TCID = "msgstress01";
45+
int TST_TOTAL = 1;
46+
47+
#ifndef CONFIG_COLDFIRE
48+
#define MAXNPROCS 1000000 /* This value is set to an arbitrary high limit. */
49+
#else
50+
#define MAXNPROCS 100000 /* Coldfire can't deal with 1000000 */
51+
#endif
3252
#define MAXNREPS 100000
3353

3454
static key_t keyarray[MAXNPROCS];
55+
static int pidarray[MAXNPROCS];
3556
static int tid;
3657
static int MSGMNI, nprocs, nreps;
58+
static int procstat;
59+
static int mykid;
60+
61+
void setup(void);
62+
void cleanup(void);
63+
64+
static int dotest(key_t key, int child_process);
65+
static void sig_handler();
66+
3767
static char *opt_nprocs;
3868
static char *opt_nreps;
39-
static void cleanup(void);
4069

41-
static struct tst_option options[] = {
42-
{"n:", &opt_nprocs, "-n N Number of processes"},
43-
{"l:", &opt_nreps, "-l N Number of iterations"},
44-
{NULL, NULL, NULL}
70+
static option_t options[] = {
71+
{"n:", NULL, &opt_nprocs},
72+
{"l:", NULL, &opt_nreps},
73+
{NULL, NULL, NULL},
4574
};
4675

47-
static void dotest(key_t key, int child_process)
76+
static void usage(void)
4877
{
49-
int pid;
50-
51-
tid = SAFE_MSGGET(key, IPC_CREAT | S_IRUSR | S_IWUSR);
52-
53-
pid = SAFE_FORK();
54-
if (pid == 0) {
55-
do_reader(key, tid, 1, child_process, nreps);
56-
exit(0);
57-
}
58-
59-
do_writer(key, tid, 1, child_process, nreps);
60-
SAFE_WAIT(NULL);
61-
SAFE_MSGCTL(tid, IPC_RMID, NULL);
78+
printf(" -n Number of processes\n");
79+
printf(" -l Number of iterations\n");
6280
}
6381

64-
static void verify_msgstress(void)
82+
int main(int argc, char **argv)
6583
{
6684
int i, j, ok, pid;
67-
int count;
85+
int count, status;
86+
struct sigaction act;
87+
88+
tst_parse_opts(argc, argv, options, usage);
89+
90+
setup();
91+
92+
nreps = MAXNREPS;
93+
nprocs = MSGMNI;
94+
95+
if (opt_nreps) {
96+
nreps = atoi(opt_nreps);
97+
if (nreps > MAXNREPS) {
98+
tst_resm(TINFO,
99+
"Requested number of iterations too large, "
100+
"setting to Max. of %d", MAXNREPS);
101+
nreps = MAXNREPS;
102+
}
103+
}
104+
105+
if (opt_nprocs) {
106+
nprocs = atoi(opt_nprocs);
107+
if (nprocs > MSGMNI) {
108+
tst_resm(TINFO,
109+
"Requested number of processes too large, "
110+
"setting to Max. of %d", MSGMNI);
111+
nprocs = MSGMNI;
112+
}
113+
}
68114

69115
srand(getpid());
70116
tid = -1;
71117

72-
/* Set up array of unique keys for use in allocating message queues */
118+
/* Setup signal handling routine */
119+
memset(&act, 0, sizeof(act));
120+
act.sa_handler = sig_handler;
121+
sigemptyset(&act.sa_mask);
122+
sigaddset(&act.sa_mask, SIGTERM);
123+
if (sigaction(SIGTERM, &act, NULL) < 0) {
124+
tst_brkm(TFAIL, NULL, "Sigset SIGTERM failed");
125+
}
126+
/* Set up array of unique keys for use in allocating message
127+
* queues
128+
*/
73129
for (i = 0; i < nprocs; i++) {
74130
ok = 1;
75131
do {
132+
/* Get random key */
76133
keyarray[i] = (key_t) rand();
77134
/* Make sure key is unique and not private */
78135
if (keyarray[i] == IPC_PRIVATE) {
@@ -89,83 +146,156 @@ static void verify_msgstress(void)
89146
} while (ok == 0);
90147
}
91148

92-
/*
93-
* Fork a number of processes, each of which will
149+
/* Fork a number of processes, each of which will
94150
* create a message queue with one reader/writer
95151
* pair which will read and write a number (iterations)
96152
* of random length messages with specific values.
97153
*/
154+
98155
for (i = 0; i < nprocs; i++) {
99-
pid = SAFE_FORK();
156+
fflush(stdout);
157+
if ((pid = FORK_OR_VFORK()) < 0) {
158+
tst_brkm(TFAIL,
159+
NULL,
160+
"\tFork failed (may be OK if under stress)");
161+
}
162+
/* Child does this */
100163
if (pid == 0) {
101-
dotest(keyarray[i], i);
102-
exit(0);
164+
procstat = 1;
165+
exit(dotest(keyarray[i], i));
103166
}
167+
pidarray[i] = pid;
104168
}
105169

106170
count = 0;
107-
108171
while (1) {
109-
if (wait(NULL) > 0) {
172+
if ((wait(&status)) > 0) {
173+
if (status >> 8 != 0) {
174+
tst_brkm(TFAIL, NULL,
175+
"Child exit status = %d",
176+
status >> 8);
177+
}
110178
count++;
111179
} else {
112-
if (errno != EINTR)
180+
if (errno != EINTR) {
113181
break;
182+
}
183+
#ifdef DEBUG
184+
tst_resm(TINFO, "Signal detected during wait");
185+
#endif
114186
}
115187
}
188+
/* Make sure proper number of children exited */
189+
if (count != nprocs) {
190+
tst_brkm(TFAIL,
191+
NULL,
192+
"Wrong number of children exited, Saw %d, Expected %d",
193+
count, nprocs);
194+
}
116195

117-
if (count != nprocs)
118-
tst_brk(TFAIL, "Wrong number of children exited, Saw %d, Expected %d",
119-
count, nprocs);
196+
tst_resm(TPASS, "Test ran successfully!");
120197

121-
tst_res(TPASS, "Test ran successfully!");
122198
cleanup();
199+
tst_exit();
123200
}
124201

125-
static void setup(void)
202+
static int dotest(key_t key, int child_process)
126203
{
127-
int nr_msgqs;
204+
int id, pid;
205+
int ret, status;
128206

129-
SAFE_FILE_SCANF("/proc/sys/kernel/msgmni", "%d", &nr_msgqs);
207+
sighold(SIGTERM);
208+
TEST(msgget(key, IPC_CREAT | S_IRUSR | S_IWUSR));
209+
if (TEST_RETURN < 0) {
210+
printf("msgget() error in child %d: %s\n",
211+
child_process, strerror(TEST_ERRNO));
130212

131-
nr_msgqs -= GET_USED_QUEUES();
132-
if (nr_msgqs <= 0)
133-
tst_brk(TCONF, "Max number of message queues already used, "
134-
"cannot create more.");
213+
return FAIL;
214+
}
215+
tid = id = TEST_RETURN;
216+
sigrelse(SIGTERM);
135217

136-
MSGMNI = min(nr_msgqs, NR_MSGQUEUES);
218+
fflush(stdout);
219+
if ((pid = FORK_OR_VFORK()) < 0) {
220+
printf("\tFork failed (may be OK if under stress)\n");
221+
TEST(msgctl(tid, IPC_RMID, 0));
222+
if (TEST_RETURN < 0) {
223+
printf("mscgtl() error in cleanup: %s\n",
224+
strerror(TEST_ERRNO));
225+
}
226+
return FAIL;
227+
}
228+
/* Child does this */
229+
if (pid == 0)
230+
exit(doreader(key, id, 1, child_process, nreps));
231+
/* Parent does this */
232+
mykid = pid;
233+
procstat = 2;
234+
ret = dowriter(key, id, 1, child_process, nreps);
235+
wait(&status);
137236

138-
if (opt_nreps) {
139-
nreps = SAFE_STRTOL(opt_nreps, 1, INT_MAX);
140-
nreps = min(nreps, MAXNREPS);
141-
} else {
142-
nreps = MAXNREPS;
237+
if (ret != PASS)
238+
exit(FAIL);
239+
240+
if ((!WIFEXITED(status) || (WEXITSTATUS(status) != PASS)))
241+
exit(FAIL);
242+
243+
TEST(msgctl(id, IPC_RMID, 0));
244+
if (TEST_RETURN < 0) {
245+
printf("msgctl() errno %d: %s\n",
246+
TEST_ERRNO, strerror(TEST_ERRNO));
247+
248+
return FAIL;
143249
}
250+
return PASS;
251+
}
144252

145-
if (opt_nprocs) {
146-
nprocs = SAFE_STRTOL(opt_nprocs, 1, INT_MAX);
147-
nprocs = min(nprocs, MAXNPROCS);
148-
nprocs = min(nprocs, MSGMNI);
149-
} else {
150-
nprocs = MSGMNI;
253+
static void sig_handler(void)
254+
{
255+
}
256+
257+
void setup(void)
258+
{
259+
int nr_msgqs;
260+
261+
tst_tmpdir();
262+
263+
tst_sig(FORK, DEF_HANDLER, cleanup);
264+
265+
TEST_PAUSE;
266+
267+
nr_msgqs = get_max_msgqueues();
268+
if (nr_msgqs < 0)
269+
cleanup();
270+
271+
nr_msgqs -= get_used_msgqueues();
272+
if (nr_msgqs <= 0) {
273+
tst_resm(TBROK,
274+
"Max number of message queues already used, cannot create more.");
275+
cleanup();
151276
}
152277

153-
SAFE_SIGNAL(SIGTERM, SIG_IGN);
154-
tst_res(TINFO, "Number of message queues is %d, process is %d, "
155-
"iterations is %d", MSGMNI, nprocs, nreps);
278+
/*
279+
* Since msgmni scales to the memory size, it may reach huge values
280+
* that are not necessary for this test.
281+
* That's why we define NR_MSGQUEUES as a high boundary for it.
282+
*/
283+
MSGMNI = min(nr_msgqs, NR_MSGQUEUES);
156284
}
157285

158286
void cleanup(void)
159287
{
160-
if (tid >= 0)
161-
SAFE_MSGCTL(tid, IPC_RMID, NULL);
162-
}
288+
int status;
163289

164-
static struct tst_test test = {
165-
.needs_tmpdir = 1,
166-
.options = options,
167-
.setup = setup,
168-
.cleanup = cleanup,
169-
.forks_child = 1,
170-
.test_all = verify_msgstress,
171-
};
290+
#ifdef DEBUG
291+
tst_resm(TINFO, "Removing the message queue");
292+
#endif
293+
(void)msgctl(tid, IPC_RMID, NULL);
294+
if ((status = msgctl(tid, IPC_STAT, NULL)) != -1) {
295+
(void)msgctl(tid, IPC_RMID, NULL);
296+
tst_resm(TFAIL, "msgctl(tid, IPC_RMID) failed");
297+
298+
}
299+
300+
tst_rmdir();
301+
}

0 commit comments

Comments
 (0)