2 * Copyright (c) 2008 Vijay Kumar B. <vijaykumar@bravegnu.org>
4 * Based on testcases/kernel/syscalls/waitpid/waitpid01.c
5 * Original copyright message:
7 * Copyright (c) International Business Machines Corp., 2001
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
17 * the GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29 * Failure when trying move shared pages.
32 * 1. Allocate a shared memory in NUMA node A.
33 * 2. Fork another process.
34 * 3. Use move_pages() to move the pages to NUMA node B, with the
36 * 4. Check if errno is set to EPERM.
38 * USAGE: <for command-line>
39 * move_pages11 [-c n] [-i n] [-I x] [-P x] [-t]
40 * where, -c n : Run n copies concurrently.
41 * -i n : Execute test n times.
42 * -I x : Execute test for x seconds.
43 * -P x : Pause for x seconds between iterations.
44 * -t : Turn on syscall timing.
54 #include <sys/types.h>
58 #include <semaphore.h>
69 #include "move_pages_support.h"
84 char *TCID
= "move_pages11";
89 * child() - touches shared pages, and waits for signal from parent.
90 * @pages: shared pages allocated in parent
91 * @sem: semaphore to sync with parent
93 void child(void **pages
, sem_t
* sem
)
97 for (i
= 0; i
< TEST_PAGES
; i
++) {
104 /* Setup complete. Ask parent to continue. */
105 if (sem_post(&sem
[SEM_CHILD_SETUP
]) == -1)
106 tst_resm(TWARN
, "error post semaphore: %s", strerror(errno
));
108 /* Wait for testcase in parent to complete. */
109 if (sem_wait(&sem
[SEM_PARENT_TEST
]) == -1)
110 tst_resm(TWARN
, "error wait semaphore: %s", strerror(errno
));
115 int main(int argc
, char **argv
)
117 char *msg
; /* message returned from parse_opts */
119 /* parse standard options */
120 msg
= parse_opts(argc
, argv
, (option_t
*) NULL
, NULL
);
122 tst_brkm(TBROK
, NULL
, "OPTION PARSING ERROR - %s", msg
);
129 #if HAVE_NUMA_MOVE_PAGES
131 int lc
; /* loop counter */
132 unsigned int from_node
= 0;
133 unsigned int to_node
= 1;
135 /* check for looping state if -i option is given */
136 for (lc
= 0; TEST_LOOPING(lc
); lc
++) {
137 void *pages
[TEST_PAGES
] = { 0 };
138 int nodes
[TEST_PAGES
];
139 int status
[TEST_PAGES
];
144 /* reset Tst_count in case we are looping */
147 ret
= alloc_shared_pages_on_node(pages
, TEST_PAGES
, from_node
);
151 for (i
= 0; i
< TEST_PAGES
; i
++) {
155 sem
= alloc_sem(MAX_SEMS
);
161 * Fork a child process so that the shared pages are
162 * now really shared between two processes.
166 tst_resm(TBROK
, "forking child failed: %s",
169 } else if (cpid
== 0) {
173 /* Wait for child to setup and signal. */
174 if (sem_wait(&sem
[SEM_CHILD_SETUP
]) == -1)
175 tst_resm(TWARN
, "error wait semaphore: %s",
178 ret
= numa_move_pages(0, TEST_PAGES
, pages
, nodes
,
179 status
, MPOL_MF_MOVE_ALL
);
181 if (ret
== -1 && errno
== EPERM
)
182 tst_resm(TPASS
, "move_pages failed with "
183 "EPERM as expected");
185 tst_resm(TFAIL
, "move_pages did not fail "
188 /* Test done. Ask child to terminate. */
189 if (sem_post(&sem
[SEM_PARENT_TEST
]) == -1)
190 tst_resm(TWARN
, "error post semaphore: %s",
192 /* Read the status, no zombies! */
195 free_sem(sem
, MAX_SEMS
);
197 free_shared_pages(pages
, TEST_PAGES
);
200 tst_resm(TCONF
, "move_pages support not found.");
210 * setup() - performs all ONE TIME setup for this test
214 struct passwd
*ltpuser
;
216 /* capture signals */
217 tst_sig(FORK
, DEF_HANDLER
, cleanup
);
219 check_config(TEST_NODES
);
221 if (geteuid() != 0) {
222 tst_resm(TBROK
, "test must be run as root");
226 if ((ltpuser
= getpwnam("nobody")) == NULL
) {
227 tst_resm(TBROK
, "'nobody' user not present");
231 if (seteuid(ltpuser
->pw_uid
) == -1) {
232 tst_resm(TBROK
, "setting uid to %d failed", ltpuser
->pw_uid
);
236 /* Pause if that option was specified
237 * TEST_PAUSE contains the code to fork the test with the -c option.
243 * cleanup() - performs all ONE TIME cleanup for this test at completion
248 * print timing stats if that option was specified.
249 * print errno log if that option was specified.
253 /* exit with return code appropriate for results */