* [LTP] [PATCH v2 01/10] syscalls/ipc: shmctl02: Convert to the new library
2020-09-07 15:01 [LTP] [PATCH v2 00/10] Rewrite shmctl() testcases Cyril Hrubis
@ 2020-09-07 15:01 ` Cyril Hrubis
2020-09-07 15:01 ` [LTP] [PATCH v2 02/10] syscalls/ipc: shmctl03: Remove Cyril Hrubis
` (9 subsequent siblings)
10 siblings, 0 replies; 16+ messages in thread
From: Cyril Hrubis @ 2020-09-07 15:01 UTC (permalink / raw)
To: ltp
Signed-off-by: Cyril Hrubis <chrubis@suse.cz>
Reviewed-by: Li Wang <liwang@redhat.com>
Reviewed-by: Martin Doucha <mdoucha@suse.cz>
---
testcases/kernel/syscalls/ipc/shmctl/Makefile | 4 +-
.../kernel/syscalls/ipc/shmctl/shmctl02.c | 263 ++++++------------
2 files changed, 89 insertions(+), 178 deletions(-)
diff --git a/testcases/kernel/syscalls/ipc/shmctl/Makefile b/testcases/kernel/syscalls/ipc/shmctl/Makefile
index 2e0ed0ceb..10db57fcc 100644
--- a/testcases/kernel/syscalls/ipc/shmctl/Makefile
+++ b/testcases/kernel/syscalls/ipc/shmctl/Makefile
@@ -10,7 +10,7 @@ shmctl05: LDLIBS += -lrt
include $(top_srcdir)/include/mk/testcases.mk
-shmctl01 shmctl02 shmctl03 shmctl04 shmctl05: LTPLDLIBS = -lltpipc
-shmctl06: LTPLDLIBS = -lltpnewipc
+shmctl01 shmctl03 shmctl04 shmctl05: LTPLDLIBS = -lltpipc
+shmctl02 shmctl06: LTPLDLIBS = -lltpnewipc
include $(top_srcdir)/include/mk/generic_leaf_target.mk
diff --git a/testcases/kernel/syscalls/ipc/shmctl/shmctl02.c b/testcases/kernel/syscalls/ipc/shmctl/shmctl02.c
index 0b97bb240..677b15d40 100644
--- a/testcases/kernel/syscalls/ipc/shmctl/shmctl02.c
+++ b/testcases/kernel/syscalls/ipc/shmctl/shmctl02.c
@@ -1,213 +1,124 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
+ * Copyright (c) International Business Machines Corp., 2001
+ * 03/2001 - Written by Wayne Boyer
*
- * Copyright (c) International Business Machines Corp., 2001
+ * Copyright (c) 2008 Renaud Lottiaux (Renaud.Lottiaux@kerlabs.com)
*
- * 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) 2020 Cyril Hrubis <chrubis@suse.cz>
*/
/*
- * NAME
- * shmctl02.c
- *
- * DESCRIPTION
- * shmctl02 - check for EACCES, EFAULT and EINVAL errors
- *
- * ALGORITHM
- * create a shared memory segment without read or write permissions
- * create a shared memory segment with read & write permissions
- * loop if that option was specified
- * call shmctl() using five different invalid cases
- * check the errno value
- * issue a PASS message if we get EACCES, EFAULT or EINVAL
- * otherwise, the tests fails
- * issue a FAIL message
- * call cleanup
- *
- * USAGE: <for command-line>
- * shmctl02 [-c n] [-e] [-i n] [-I x] [-P x] [-t]
- * where, -c n : Run n copies concurrently.
- * -e : Turn on errno logging.
- * -i n : Execute test n times.
- * -I x : Execute test for x seconds.
- * -P x : Pause for x seconds between iterations.
- * -t : Turn on syscall timing.
- *
- * HISTORY
- * 03/2001 - Written by Wayne Boyer
+ * Test for EACCES, EFAULT and EINVAL errors.
*
- * 06/03/2008 Renaud Lottiaux (Renaud.Lottiaux@kerlabs.com)
- * - Fix concurrency issue. The second key used for this test could
- * conflict with the key from another task.
+ * * EACCES - segment has no read or write permissions
+ * * EFAULT - IPC_SET & buf isn't valid
+ * * EFAULT - IPC_STAT & buf isn't valid
+ * * EINVAL - the command is not valid
+ * * EINVAL - the shmid is not valid
+ * * EINVAL - the shmid belongs to removed shm
*
- * RESTRICTIONS
- * none
+ * * EACCES - attempt to stat root-owned shm
+ * * EPERM - attempt to delete root-owned shm
+ * * EPERM - attempt to change root-owned shm
+ * * EPERM - attempt to lock root-owned shm
+ * * EPERM - attempt to unlock root-owned shm
*/
-#include "ipcshm.h"
#include <pwd.h>
-char *TCID = "shmctl02";
-char nobody_uid[] = "nobody";
-struct passwd *ltpuser;
+#include "tst_test.h"
+#include "tst_safe_sysv_ipc.h"
+#include "libnewipc.h"
-int shm_id_1 = -1;
-int shm_id_2 = -1;
-int shm_id_3 = -1;
+#define SHM_SIZE 2048
-struct shmid_ds buf;
+static int shm_id1 = -1;
+static int shm_id2 = -1;
+static int shm_id3 = -1;
+static int shm_bad = -1;
+static int shm_rem;
-struct test_case_t {
- int *shmid;
+static struct shmid_ds buf;
+
+static struct tcase {
+ int *shm_id;
int cmd;
- struct shmid_ds *sbuf;
+ struct shmid_ds *buf;
int error;
-} TC[] = {
- /* EACCES - segment has no read or write permissions */
- {
- &shm_id_1, IPC_STAT, &buf, EACCES},
- /* EFAULT - IPC_SET & buf isn't valid */
- {
- &shm_id_2, IPC_SET, (struct shmid_ds *)-1, EFAULT},
- /* EFAULT - IPC_STAT & buf isn't valid */
- {
- &shm_id_2, IPC_STAT, (struct shmid_ds *)-1, EFAULT},
- /* EINVAL - the shmid is not valid */
- {
- &shm_id_3, IPC_STAT, &buf, EINVAL},
- /* EINVAL - the command is not valid */
- {
- &shm_id_2, -1, &buf, EINVAL},
- /* EPERM - the command is only valid for the super-user */
- {
- &shm_id_2, SHM_LOCK, &buf, EPERM},
- /* EPERM - the command is only valid for the super-user */
- {
- &shm_id_2, SHM_UNLOCK, &buf, EPERM}
+} tc[] = {
+ {&shm_id1, IPC_STAT, &buf, EACCES},
+ {&shm_id2, IPC_SET, (struct shmid_ds *)-1, EFAULT},
+ {&shm_id2, IPC_STAT, (struct shmid_ds *)-1, EFAULT},
+ {&shm_id2, -1, &buf, EINVAL},
+ {&shm_bad, IPC_STAT, &buf, EINVAL},
+ {&shm_rem, IPC_STAT, &buf, EINVAL},
+ /* Operations on root-owned shm */
+ {&shm_id3, IPC_STAT, &buf, EACCES},
+ {&shm_id3, IPC_RMID, NULL, EPERM},
+ {&shm_id3, IPC_SET, &buf, EPERM},
+ {&shm_id3, SHM_LOCK, &buf, EPERM},
+ {&shm_id3, SHM_UNLOCK, &buf, EPERM}
};
-int TST_TOTAL = ARRAY_SIZE(TC);
-
-int main(int ac, char **av)
+static void verify_shmctl(unsigned int i)
{
- int lc;
- int i;
-
- tst_parse_opts(ac, av, NULL, NULL);
-
- setup(); /* global setup */
-
- /* The following loop checks looping state if -i option given */
-
- for (lc = 0; TEST_LOOPING(lc); lc++) {
- /* reset tst_count in case we are looping */
- tst_count = 0;
-
- /* loop through the test cases */
- for (i = 0; i < TST_TOTAL; i++) {
- /*
- * use the TEST() macro to make the call
- */
-
- TEST(shmctl(*(TC[i].shmid), TC[i].cmd, TC[i].sbuf));
-
- if ((TEST_RETURN != -1) && (i < 5)) {
- tst_resm(TFAIL, "call succeeded unexpectedly");
- continue;
- }
-
- if (TEST_ERRNO == TC[i].error) {
- tst_resm(TPASS, "expected failure - errno = "
- "%d : %s", TEST_ERRNO,
- strerror(TEST_ERRNO));
- } else {
- if (i >= 5)
- tst_resm(TCONF,
- "shmctl() did not fail for non-root user."
- "This may be okay for your distribution.");
- else
- tst_resm(TFAIL, "call failed with an "
- "unexpected error - %d : %s",
- TEST_ERRNO,
- strerror(TEST_ERRNO));
- }
- }
+ TEST(shmctl(*(tc[i].shm_id), tc[i].cmd, tc[i].buf));
+
+ if (TST_RET != -1) {
+ tst_res(TFAIL, "shmctl() returned %li", TST_RET);
+ return;
}
- cleanup();
+ if (TST_ERR == tc[i].error) {
+ tst_res(TPASS | TTERRNO, "shmctl(%i, %i, %p)",
+ *tc[i].shm_id, tc[i].cmd, tc[i].buf);
+ return;
+ }
- tst_exit();
+ tst_res(TFAIL | TTERRNO, "shmctl(%i, %i, %p) expected %s",
+ *tc[i].shm_id, tc[i].cmd, tc[i].buf, tst_strerrno(tc[i].error));
}
-/*
- * setup() - performs all the ONE TIME setup for this test.
- */
-void setup(void)
+static void setup(void)
{
- key_t shmkey2;
+ key_t shmkey1, shmkey2;
+ struct passwd *ltpuser;
+ int tmp;
- tst_require_root();
+ shm_id3 = SAFE_SHMGET(IPC_PRIVATE, SHM_SIZE, IPC_CREAT | SHM_RW);
- /* Switch to nobody user for correct error code collection */
- ltpuser = getpwnam(nobody_uid);
- if (setuid(ltpuser->pw_uid) == -1) {
- tst_resm(TINFO, "setuid failed to "
- "to set the effective uid to %d", ltpuser->pw_uid);
- perror("setuid");
- }
-
- tst_sig(NOFORK, DEF_HANDLER, cleanup);
-
- TEST_PAUSE;
+ ltpuser = SAFE_GETPWNAM("nobody");
+ SAFE_SETEUID(ltpuser->pw_uid);
- /*
- * Create a temporary directory and cd into it.
- * This helps to ensure that a unique msgkey is created.
- * See libs/libltpipc/libipc.c for more information.
- */
- tst_tmpdir();
-
- /* get an IPC resource key */
- shmkey = getipckey();
-
- /* create a shared memory segment without read or write permissions */
- if ((shm_id_1 = shmget(shmkey, SHM_SIZE, IPC_CREAT | IPC_EXCL)) == -1) {
- tst_brkm(TBROK, cleanup, "couldn't create shared memory "
- "segment #1 in setup()");
- }
+ shmkey1 = GETIPCKEY();
+ shmkey2 = GETIPCKEY();
- /* Get an new IPC resource key. */
- shmkey2 = getipckey();
+ shm_id1 = SAFE_SHMGET(shmkey1, SHM_SIZE, IPC_CREAT | IPC_EXCL);
+ shm_id2 = SAFE_SHMGET(shmkey2, SHM_SIZE, IPC_CREAT | IPC_EXCL | SHM_RW);
- /* create a shared memory segment with read and write permissions */
- if ((shm_id_2 = shmget(shmkey2, SHM_SIZE, IPC_CREAT | IPC_EXCL |
- SHM_RW)) == -1) {
- tst_brkm(TBROK, cleanup, "couldn't create shared memory "
- "segment #2 in setup()");
- }
+ tmp = shm_rem = SAFE_SHMGET(IPC_PRIVATE, SHM_SIZE, IPC_CREAT | SHM_RW);
+ SAFE_SHMCTL(tmp, IPC_RMID, NULL);
}
-/*
- * cleanup() - performs all the ONE TIME cleanup for this test at completion
- * or premature exit.
- */
-void cleanup(void)
+static void cleanup(void)
{
- /* if they exist, remove the shared memory resources */
- rm_shm(shm_id_1);
- rm_shm(shm_id_2);
+ if (shm_id1 >= 0)
+ SAFE_SHMCTL(shm_id1, IPC_RMID, NULL);
- tst_rmdir();
+ if (shm_id2 >= 0)
+ SAFE_SHMCTL(shm_id2, IPC_RMID, NULL);
+ if (shm_id3 >= 0) {
+ SAFE_SETEUID(0);
+ SAFE_SHMCTL(shm_id3, IPC_RMID, NULL);
+ }
}
+
+static struct tst_test test = {
+ .setup = setup,
+ .cleanup = cleanup,
+ .test = verify_shmctl,
+ .tcnt = ARRAY_SIZE(tc),
+ .needs_root = 1,
+};
--
2.26.2
^ permalink raw reply related [flat|nested] 16+ messages in thread* [LTP] [PATCH v2 02/10] syscalls/ipc: shmctl03: Remove.
2020-09-07 15:01 [LTP] [PATCH v2 00/10] Rewrite shmctl() testcases Cyril Hrubis
2020-09-07 15:01 ` [LTP] [PATCH v2 01/10] syscalls/ipc: shmctl02: Convert to the new library Cyril Hrubis
@ 2020-09-07 15:01 ` Cyril Hrubis
2020-09-07 15:01 ` [LTP] [PATCH v2 03/10] lapi/shm.h: Add SHM_STAT_ANY Cyril Hrubis
` (8 subsequent siblings)
10 siblings, 0 replies; 16+ messages in thread
From: Cyril Hrubis @ 2020-09-07 15:01 UTC (permalink / raw)
To: ltp
All these cases are now covered by shmctl02.
Signed-off-by: Cyril Hrubis <chrubis@suse.cz>
Reviewed-by: Martin Doucha <mdoucha@suse.cz>
---
runtest/syscalls | 1 -
runtest/syscalls-ipc | 1 -
.../kernel/syscalls/ipc/shmctl/.gitignore | 1 -
testcases/kernel/syscalls/ipc/shmctl/Makefile | 2 +-
.../kernel/syscalls/ipc/shmctl/shmctl03.c | 204 ------------------
5 files changed, 1 insertion(+), 208 deletions(-)
delete mode 100644 testcases/kernel/syscalls/ipc/shmctl/shmctl03.c
diff --git a/runtest/syscalls b/runtest/syscalls
index 35770e6db..557fa7155 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -1355,7 +1355,6 @@ shmat03 shmat03
shmctl01 shmctl01
shmctl02 shmctl02
-shmctl03 shmctl03
shmctl04 shmctl04
shmctl05 shmctl05
shmctl06 shmctl06
diff --git a/runtest/syscalls-ipc b/runtest/syscalls-ipc
index e6837414c..a40ff083f 100644
--- a/runtest/syscalls-ipc
+++ b/runtest/syscalls-ipc
@@ -51,7 +51,6 @@ shmat02 shmat02
shmctl01 shmctl01
shmctl02 shmctl02
-shmctl03 shmctl03
shmctl04 shmctl04
shmctl05 shmctl05
shmctl06 shmctl06
diff --git a/testcases/kernel/syscalls/ipc/shmctl/.gitignore b/testcases/kernel/syscalls/ipc/shmctl/.gitignore
index 46b107344..08aa83c19 100644
--- a/testcases/kernel/syscalls/ipc/shmctl/.gitignore
+++ b/testcases/kernel/syscalls/ipc/shmctl/.gitignore
@@ -1,6 +1,5 @@
/shmctl01
/shmctl02
-/shmctl03
/shmctl04
/shmctl05
/shmctl06
diff --git a/testcases/kernel/syscalls/ipc/shmctl/Makefile b/testcases/kernel/syscalls/ipc/shmctl/Makefile
index 10db57fcc..176592e85 100644
--- a/testcases/kernel/syscalls/ipc/shmctl/Makefile
+++ b/testcases/kernel/syscalls/ipc/shmctl/Makefile
@@ -10,7 +10,7 @@ shmctl05: LDLIBS += -lrt
include $(top_srcdir)/include/mk/testcases.mk
-shmctl01 shmctl03 shmctl04 shmctl05: LTPLDLIBS = -lltpipc
+shmctl01 shmctl04 shmctl05: LTPLDLIBS = -lltpipc
shmctl02 shmctl06: LTPLDLIBS = -lltpnewipc
include $(top_srcdir)/include/mk/generic_leaf_target.mk
diff --git a/testcases/kernel/syscalls/ipc/shmctl/shmctl03.c b/testcases/kernel/syscalls/ipc/shmctl/shmctl03.c
deleted file mode 100644
index 798eadad6..000000000
--- a/testcases/kernel/syscalls/ipc/shmctl/shmctl03.c
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- *
- * Copyright (c) International Business Machines Corp., 2001
- *
- * 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
- */
-
-/*
- * NAME
- * shmctl03.c
- *
- * DESCRIPTION
- * shmctl03 - check for EACCES, and EPERM errors
- *
- * ALGORITHM
- * create a shared memory segment with root only read & write permissions
- * fork a child process
- * if child
- * set the ID of the child process to that of "ltpuser1"
- * call do_child()
- * loop if that option was specified
- * call shmctl() using three different invalid cases
- * check the errno value
- * issue a PASS message if we get EACCES or EPERM
- * otherwise, the tests fails
- * issue a FAIL message
- * call cleanup
- * if parent
- * wait for child to exit
- * remove the shared memory segment
- *
- * USAGE: <for command-line>
- * shmctl03 [-c n] [-e] [-i n] [-I x] [-P x] [-t]
- * where, -c n : Run n copies concurrently.
- * -e : Turn on errno logging.
- * -i n : Execute test n times.
- * -I x : Execute test for x seconds.
- * -P x : Pause for x seconds between iterations.
- * -t : Turn on syscall timing.
- *
- * HISTORY
- * 03/2001 - Written by Wayne Boyer
- *
- * RESTRICTIONS
- * test must be run as root
- */
-
-#include "ipcshm.h"
-#include <sys/types.h>
-#include <sys/wait.h>
-#include "safe_macros.h"
-
-char *TCID = "shmctl03";
-int shm_id_1 = -1;
-
-uid_t ltp_uid;
-char *ltp_user = "nobody";
-
-struct shmid_ds buf;
-
-struct test_case_t {
- int *shmid;
- int cmd;
- struct shmid_ds *sbuf;
- int error;
-} TC[] = {
- /* EACCES - child has no read permission for segment */
- {
- &shm_id_1, IPC_STAT, &buf, EACCES},
- /* EPERM - IPC_SET - child doesn't have permission to change segment */
- {
- &shm_id_1, IPC_SET, &buf, EPERM},
- /* EPERM - IPC_RMID - child can not remove the segment */
- {
-&shm_id_1, IPC_RMID, &buf, EPERM},};
-
-int TST_TOTAL = ARRAY_SIZE(TC);
-
-int main(int ac, char **av)
-{
- int pid;
- void do_child(void);
-
- tst_parse_opts(ac, av, NULL, NULL);
-
- setup(); /* global setup */
-
- if ((pid = FORK_OR_VFORK()) == -1) {
- tst_brkm(TBROK, cleanup, "could not fork");
- }
-
- if (pid == 0) { /* child */
- /* set the user ID of the child to the non root user */
- if (setuid(ltp_uid) == -1) {
- tst_resm(TBROK, "setuid() failed");
- exit(1);
- }
-
- do_child();
- } else {
- /* wait for the child to return */
- SAFE_WAITPID(cleanup, pid, NULL, 0);
-
- /* if it exists, remove the shared memory resource */
- rm_shm(shm_id_1);
-
- tst_rmdir();
- }
-
- cleanup();
- tst_exit();
-}
-
-/*
- * do_child - make the call as the child process
- */
-void do_child(void)
-{
- int i, lc;
-
- /* The following loop checks looping state if -i option given */
-
- for (lc = 0; TEST_LOOPING(lc); lc++) {
- /* reset tst_count in case we are looping */
- tst_count = 0;
-
- /* loop through the test cases */
- for (i = 0; i < TST_TOTAL; i++) {
- /*
- * use the TEST() macro to make the call
- */
-
- TEST(shmctl(*(TC[i].shmid), TC[i].cmd, TC[i].sbuf));
-
- if (TEST_RETURN != -1) {
- tst_resm(TFAIL, "call succeeded unexpectedly");
- continue;
- }
-
- if (TEST_ERRNO == TC[i].error) {
- tst_resm(TPASS, "expected failure - errno = "
- "%d : %s", TEST_ERRNO,
- strerror(TEST_ERRNO));
- } else {
- tst_resm(TFAIL, "call failed with an "
- "unexpected error - %d : %s",
- TEST_ERRNO, strerror(TEST_ERRNO));
- }
- }
- }
-}
-
-/*
- * setup() - performs all the ONE TIME setup for this test.
- */
-void setup(void)
-{
- tst_require_root();
-
- tst_sig(FORK, DEF_HANDLER, cleanup);
-
- TEST_PAUSE;
-
- /*
- * Create a temporary directory and cd into it.
- * This helps to ensure that a unique msgkey is created.
- * See libs/libltpipc/libipc.c for more information.
- */
- tst_tmpdir();
-
- /* get an IPC resource key */
- shmkey = getipckey();
-
- /* create a shared memory segment with read and write permissions */
- if ((shm_id_1 = shmget(shmkey, SHM_SIZE, IPC_CREAT | IPC_EXCL |
- SHM_RW)) == -1) {
- tst_brkm(TBROK, cleanup, "couldn't create shared memory "
- "segment in setup()");
- }
-
- /* get the userid for a non root user */
- ltp_uid = getuserid(ltp_user);
-}
-
-/*
- * cleanup() - performs all the ONE TIME cleanup for this test@completion
- * or premature exit.
- */
-void cleanup(void)
-{
-
-}
--
2.26.2
^ permalink raw reply related [flat|nested] 16+ messages in thread* [LTP] [PATCH v2 03/10] lapi/shm.h: Add SHM_STAT_ANY
2020-09-07 15:01 [LTP] [PATCH v2 00/10] Rewrite shmctl() testcases Cyril Hrubis
2020-09-07 15:01 ` [LTP] [PATCH v2 01/10] syscalls/ipc: shmctl02: Convert to the new library Cyril Hrubis
2020-09-07 15:01 ` [LTP] [PATCH v2 02/10] syscalls/ipc: shmctl03: Remove Cyril Hrubis
@ 2020-09-07 15:01 ` Cyril Hrubis
2020-09-07 15:01 ` [LTP] [PATCH v2 04/10] syscalls/ipc: shmctl04: Rewrite from scratch Cyril Hrubis
` (7 subsequent siblings)
10 siblings, 0 replies; 16+ messages in thread
From: Cyril Hrubis @ 2020-09-07 15:01 UTC (permalink / raw)
To: ltp
Signed-off-by: Cyril Hrubis <chrubis@suse.cz>
---
include/lapi/shm.h | 13 +++++++++++++
1 file changed, 13 insertions(+)
create mode 100644 include/lapi/shm.h
diff --git a/include/lapi/shm.h b/include/lapi/shm.h
new file mode 100644
index 000000000..61c4e37bf
--- /dev/null
+++ b/include/lapi/shm.h
@@ -0,0 +1,13 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2020 Cyril Hrubis <chrubis@suse.cz>
+ */
+
+#ifndef LAPI_SHM_H__
+#define LAPI_SHM_H__
+
+#ifndef SHM_STAT_ANY
+# define SHM_STAT_ANY 15
+#endif
+
+#endif /* LAPI_SHM_H__ */
--
2.26.2
^ permalink raw reply related [flat|nested] 16+ messages in thread* [LTP] [PATCH v2 04/10] syscalls/ipc: shmctl04: Rewrite from scratch.
2020-09-07 15:01 [LTP] [PATCH v2 00/10] Rewrite shmctl() testcases Cyril Hrubis
` (2 preceding siblings ...)
2020-09-07 15:01 ` [LTP] [PATCH v2 03/10] lapi/shm.h: Add SHM_STAT_ANY Cyril Hrubis
@ 2020-09-07 15:01 ` Cyril Hrubis
2020-09-07 15:01 ` [LTP] [PATCH v2 05/10] syscalls/ipc: shmctl05 remove lib dependency Cyril Hrubis
` (6 subsequent siblings)
10 siblings, 0 replies; 16+ messages in thread
From: Cyril Hrubis @ 2020-09-07 15:01 UTC (permalink / raw)
To: ltp
Write the test from a scratch and validate the content of the shm_info
structure and the return value.
The return value is highest used index to a kernel table, so we call
shmctl() with SHM_STAT_ANY which shouldn't fail if the value is correct.
We also parse /proc/sysvipc/shm and check that the information is
consistent with the content of shm_info structure.
Signed-off-by: Cyril Hrubis <chrubis@suse.cz>
---
testcases/kernel/syscalls/ipc/shmctl/Makefile | 4 +-
.../kernel/syscalls/ipc/shmctl/shmctl04.c | 203 +++++++++++-------
2 files changed, 122 insertions(+), 85 deletions(-)
diff --git a/testcases/kernel/syscalls/ipc/shmctl/Makefile b/testcases/kernel/syscalls/ipc/shmctl/Makefile
index 176592e85..789fd4227 100644
--- a/testcases/kernel/syscalls/ipc/shmctl/Makefile
+++ b/testcases/kernel/syscalls/ipc/shmctl/Makefile
@@ -10,7 +10,7 @@ shmctl05: LDLIBS += -lrt
include $(top_srcdir)/include/mk/testcases.mk
-shmctl01 shmctl04 shmctl05: LTPLDLIBS = -lltpipc
-shmctl02 shmctl06: LTPLDLIBS = -lltpnewipc
+shmctl01 shmctl05: LTPLDLIBS = -lltpipc
+shmctl02 shmctl04 shmctl06: LTPLDLIBS = -lltpnewipc
include $(top_srcdir)/include/mk/generic_leaf_target.mk
diff --git a/testcases/kernel/syscalls/ipc/shmctl/shmctl04.c b/testcases/kernel/syscalls/ipc/shmctl/shmctl04.c
index 40cfa9419..bf3c8546f 100644
--- a/testcases/kernel/syscalls/ipc/shmctl/shmctl04.c
+++ b/testcases/kernel/syscalls/ipc/shmctl/shmctl04.c
@@ -1,115 +1,152 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
- *
- * Copyright (c) International Business Machines Corp., 2001
- *
- * 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) 2020 Cyril Hrubis <chrubis@suse.cz>
*/
-
/*
- * NAME
- * shmctl04.c
+ * Call shmctl() with SHM_INFO flag and check that:
*
- * DESCRIPTION
- * shmctl04 - test the SHM_INFO command
- * they are used with shmctl() in ipcs
+ * * The returned index points to a valid SHM by calling SHM_STAT_ANY
+ * * Also count that valid indexes < returned max index sums up to used_ids
+ * * And the data are consistent with /proc/sysvipc/shm
*
- * USAGE: <for command-line>
- * shmctl04 [-c n] [-f] [-i n] [-I x] [-P x] [-t]
- * where, -c n : Run n copies concurrently.
- * -f : Turn off functionality Testing.
- * -i n : Execute test n times.
- * -I x : Execute test for x seconds.
- * -P x : Pause for x seconds between iterations.
- * -t : Turn on syscall timing.
+ * There is a possible race between the call to the shmctl() and read from the
+ * proc file so this test cannot be run in parallel with any IPC testcases that
+ * adds or removes SHM segments.
*
- * HISTORY
- * 09/2002 - Written by Mingming Cao
- *
- * RESTRICTIONS
- * none
+ * Note what we create a SHM segment in the test setup to make sure that there
+ * is at least one during the testrun.
*/
-#include "ipcshm.h"
-
-char *TCID = "shmctl04";
-int TST_TOTAL = 1;
+#define _GNU_SOURCE
+#include <stdio.h>
+#include "tst_test.h"
+#include "tst_safe_sysv_ipc.h"
+#include "libnewipc.h"
+#include "lapi/shm.h"
-struct shm_info shm_info;
-int max_ids;
+#define SHM_SIZE 2048
-/*
- * These are the various setup and check functions for the commands
- * that we are checking.
- */
+static int shm_id = -1;
-int main(int ac, char **av)
+static void parse_proc_sysvipc(struct shm_info *info)
{
- int lc;
-
- tst_parse_opts(ac, av, NULL, NULL);
-
- setup();
+ int page_size = getpagesize();
+ FILE *f = fopen("/proc/sysvipc/shm", "r");
+ int used_ids = 0;
+ int shmid_max = 0;
+ unsigned long shm_rss = 0;
+ unsigned long shm_swp = 0;
+ unsigned long shm_tot = 0;
+
+ /* Eat header */
+ for (;;) {
+ int c = fgetc(f);
+
+ if (c == '\n' || c == EOF)
+ break;
+ }
- /* The following loop checks looping state if -i option given */
+ int shmid, size, rss, swap;
- for (lc = 0; TEST_LOOPING(lc); lc++) {
- /* reset tst_count in case we are looping */
- tst_count = 0;
- TEST(shmctl(0, SHM_INFO, (struct shmid_ds *)&shm_info));
+ /*
+ * Sum rss, swap and size for all elements listed, which should equal
+ * the data returned in the shm_info structure.
+ *
+ * Note that the size has to be rounded up to nearest multiple of page
+ * size.
+ */
+ while (fscanf(f, "%*i %i %*i %i %*i %*i %*i %*i %*i %*i %*i %*i %*i %*i %i %i",
+ &shmid, &size, &rss, &swap) > 0) {
+ used_ids++;
+ shm_rss += rss/page_size;
+ shm_swp += swap/page_size;
+ shm_tot += (size + page_size - 1) / page_size;
+ if (shmid > shmid_max)
+ shmid_max = shmid;
+ }
- if (TEST_RETURN != -1) {
- tst_resm(TPASS, "SHM_INFO call succeeded");
- continue;
- }
+ if (info->used_ids != used_ids) {
+ tst_res(TFAIL, "used_ids = %i, expected %i",
+ info->used_ids, used_ids);
+ } else {
+ tst_res(TPASS, "used_ids = %i", used_ids);
+ }
- tst_resm(TFAIL, "SHM_INFO call failed with an unexpected error"
- " - %d : %s", TEST_ERRNO, strerror(TEST_ERRNO));
+ if (info->shm_rss != shm_rss) {
+ tst_res(TFAIL, "shm_rss = %li, expected %li",
+ info->shm_rss, shm_rss);
+ } else {
+ tst_res(TPASS, "shm_rss = %li", shm_rss);
+ }
+ if (info->shm_swp != shm_swp) {
+ tst_res(TFAIL, "shm_swp = %li, expected %li",
+ info->shm_swp, shm_swp);
+ } else {
+ tst_res(TPASS, "shm_swp = %li", shm_swp);
}
- cleanup();
+ if (info->shm_tot != shm_tot) {
+ tst_res(TFAIL, "shm_tot = %li, expected %li",
+ info->shm_tot, shm_tot);
+ } else {
+ tst_res(TPASS, "shm_tot = %li", shm_tot);
+ }
- tst_exit();
+ fclose(f);
}
-/*
- * setup() - performs all the ONE TIME setup for this test.
- */
-void setup(void)
+static void verify_shminfo(void)
{
+ struct shm_info info;
+ struct shmid_ds ds;
+ int i, shmid, cnt = 0;
- tst_sig(NOFORK, DEF_HANDLER, cleanup);
+ TEST(shmctl(0, SHM_INFO, (struct shmid_ds *)&info));
- TEST_PAUSE;
+ if (TST_RET == -1) {
+ tst_res(TFAIL | TTERRNO, "shmctl(0, SHM_INFO, ...)");
+ return;
+ }
- /*
- * Create a temporary directory and cd into it.
- * This helps to ensure that a unique msgkey is created.
- * See libs/libltpipc/libipc.c for more information.
- */
- tst_tmpdir();
+ shmid = shmctl(TST_RET, SHM_STAT_ANY, &ds);
+
+ if (shmid == -1) {
+ tst_res(TFAIL | TTERRNO, "SHM_INFO haven't returned a valid index");
+ } else {
+ tst_res(TPASS,
+ "SHM_INFO returned valid index %li maps to shmid %i",
+ TST_RET, shmid);
+ }
+
+ for (i = 0; i <= TST_RET; i++) {
+ if (shmctl(i, SHM_STAT_ANY, &ds) != -1)
+ cnt++;
+ }
+ if (cnt == info.used_ids) {
+ tst_res(TPASS, "Counted used = %i", cnt);
+ } else {
+ tst_res(TFAIL, "Counted used = %i, used_ids = %i",
+ cnt, info.used_ids);
+ }
+
+ parse_proc_sysvipc(&info);
}
-/*
- * cleanup() - performs all the ONE TIME cleanup for this test@completion
- * or premature exit.
- */
-void cleanup(void)
+static void setup(void)
{
+ shm_id = SAFE_SHMGET(IPC_PRIVATE, SHM_SIZE, IPC_CREAT | SHM_RW);
+}
- tst_rmdir();
-
+static void cleanup(void)
+{
+ if (shm_id >= 0)
+ SAFE_SHMCTL(shm_id, IPC_RMID, NULL);
}
+
+static struct tst_test test = {
+ .setup = setup,
+ .cleanup = cleanup,
+ .test_all = verify_shminfo,
+};
--
2.26.2
^ permalink raw reply related [flat|nested] 16+ messages in thread* [LTP] [PATCH v2 05/10] syscalls/ipc: shmctl05 remove lib dependency
2020-09-07 15:01 [LTP] [PATCH v2 00/10] Rewrite shmctl() testcases Cyril Hrubis
` (3 preceding siblings ...)
2020-09-07 15:01 ` [LTP] [PATCH v2 04/10] syscalls/ipc: shmctl04: Rewrite from scratch Cyril Hrubis
@ 2020-09-07 15:01 ` Cyril Hrubis
2020-09-07 15:01 ` [LTP] [PATCH v2 06/10] lib/tst_assert: Add TST_ASSERT_ULONG() Cyril Hrubis
` (5 subsequent siblings)
10 siblings, 0 replies; 16+ messages in thread
From: Cyril Hrubis @ 2020-09-07 15:01 UTC (permalink / raw)
To: ltp
The shmctl05 does not need any SHM library.
Signed-off-by: Cyril Hrubis <chrubis@suse.cz>
Reviewed-by: Martin Doucha <mdoucha@suse.cz>
---
testcases/kernel/syscalls/ipc/shmctl/Makefile | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/testcases/kernel/syscalls/ipc/shmctl/Makefile b/testcases/kernel/syscalls/ipc/shmctl/Makefile
index 789fd4227..9d535014f 100644
--- a/testcases/kernel/syscalls/ipc/shmctl/Makefile
+++ b/testcases/kernel/syscalls/ipc/shmctl/Makefile
@@ -10,7 +10,7 @@ shmctl05: LDLIBS += -lrt
include $(top_srcdir)/include/mk/testcases.mk
-shmctl01 shmctl05: LTPLDLIBS = -lltpipc
+shmctl01: LTPLDLIBS = -lltpipc
shmctl02 shmctl04 shmctl06: LTPLDLIBS = -lltpnewipc
include $(top_srcdir)/include/mk/generic_leaf_target.mk
--
2.26.2
^ permalink raw reply related [flat|nested] 16+ messages in thread* [LTP] [PATCH v2 06/10] lib/tst_assert: Add TST_ASSERT_ULONG()
2020-09-07 15:01 [LTP] [PATCH v2 00/10] Rewrite shmctl() testcases Cyril Hrubis
` (4 preceding siblings ...)
2020-09-07 15:01 ` [LTP] [PATCH v2 05/10] syscalls/ipc: shmctl05 remove lib dependency Cyril Hrubis
@ 2020-09-07 15:01 ` Cyril Hrubis
2020-09-07 15:01 ` [LTP] [PATCH v2 07/10] syscalls/ipc: Add shmctl() IPC_INFO test Cyril Hrubis
` (4 subsequent siblings)
10 siblings, 0 replies; 16+ messages in thread
From: Cyril Hrubis @ 2020-09-07 15:01 UTC (permalink / raw)
To: ltp
Signed-off-by: Cyril Hrubis <chrubis@suse.cz>
Reviewed-by: Martin Doucha <mdoucha@suse.cz>
---
include/tst_assert.h | 9 +++++++++
lib/tst_assert.c | 14 ++++++++++++++
2 files changed, 23 insertions(+)
diff --git a/include/tst_assert.h b/include/tst_assert.h
index 9969a8169..dcb62dfea 100644
--- a/include/tst_assert.h
+++ b/include/tst_assert.h
@@ -21,6 +21,15 @@ void tst_assert_int(const char *file, const int lineno,
#define TST_ASSERT_FILE_INT(path, prefix, val) \
tst_assert_file_int(__FILE__, __LINE__, path, prefix, val)
+/*
+ * Same as tst_assert_int() but for unsigned long.
+ */
+void tst_assert_ulong(const char *file, const int lineno,
+ const char *path, unsigned long val);
+
+#define TST_ASSERT_ULONG(path, val) \
+ tst_assert_ulong(__FILE__, __LINE__, path, val)
+
/*
* Asserts that integer value stored in the prefix field of file pointed by path
* equals to the value passed to this function. This is mostly useful for
diff --git a/lib/tst_assert.c b/lib/tst_assert.c
index c7908f64f..9b8ebc167 100644
--- a/lib/tst_assert.c
+++ b/lib/tst_assert.c
@@ -23,6 +23,20 @@ void tst_assert_int(const char *file, const int lineno, const char *path, int va
tst_res_(file, lineno, TFAIL, "%s != %d got %d", path, val, sys_val);
}
+void tst_assert_ulong(const char *file, const int lineno, const char *path, unsigned long val)
+{
+ unsigned long sys_val;
+
+ safe_file_scanf(file, lineno, NULL, path, "%lu", &sys_val);
+
+ if (val == sys_val) {
+ tst_res_(file, lineno, TPASS, "%s = %lu", path, val);
+ return;
+ }
+
+ tst_res_(file, lineno, TFAIL, "%s != %lu got %lu", path, val, sys_val);
+}
+
void tst_assert_file_int(const char *file, const int lineno, const char *path, const char *prefix, int val)
{
int sys_val;
--
2.26.2
^ permalink raw reply related [flat|nested] 16+ messages in thread* [LTP] [PATCH v2 07/10] syscalls/ipc: Add shmctl() IPC_INFO test
2020-09-07 15:01 [LTP] [PATCH v2 00/10] Rewrite shmctl() testcases Cyril Hrubis
` (5 preceding siblings ...)
2020-09-07 15:01 ` [LTP] [PATCH v2 06/10] lib/tst_assert: Add TST_ASSERT_ULONG() Cyril Hrubis
@ 2020-09-07 15:01 ` Cyril Hrubis
2020-09-07 15:01 ` [LTP] [PATCH v2 08/10] syscalls/ipc: Add shmctl07 test Cyril Hrubis
` (3 subsequent siblings)
10 siblings, 0 replies; 16+ messages in thread
From: Cyril Hrubis @ 2020-09-07 15:01 UTC (permalink / raw)
To: ltp
Signed-off-by: Cyril Hrubis <chrubis@suse.cz>
---
runtest/syscalls | 1 +
runtest/syscalls-ipc | 1 +
.../kernel/syscalls/ipc/shmctl/.gitignore | 1 +
.../kernel/syscalls/ipc/shmctl/shmctl03.c | 40 +++++++++++++++++++
4 files changed, 43 insertions(+)
create mode 100644 testcases/kernel/syscalls/ipc/shmctl/shmctl03.c
diff --git a/runtest/syscalls b/runtest/syscalls
index 557fa7155..35770e6db 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -1355,6 +1355,7 @@ shmat03 shmat03
shmctl01 shmctl01
shmctl02 shmctl02
+shmctl03 shmctl03
shmctl04 shmctl04
shmctl05 shmctl05
shmctl06 shmctl06
diff --git a/runtest/syscalls-ipc b/runtest/syscalls-ipc
index a40ff083f..e6837414c 100644
--- a/runtest/syscalls-ipc
+++ b/runtest/syscalls-ipc
@@ -51,6 +51,7 @@ shmat02 shmat02
shmctl01 shmctl01
shmctl02 shmctl02
+shmctl03 shmctl03
shmctl04 shmctl04
shmctl05 shmctl05
shmctl06 shmctl06
diff --git a/testcases/kernel/syscalls/ipc/shmctl/.gitignore b/testcases/kernel/syscalls/ipc/shmctl/.gitignore
index 08aa83c19..46b107344 100644
--- a/testcases/kernel/syscalls/ipc/shmctl/.gitignore
+++ b/testcases/kernel/syscalls/ipc/shmctl/.gitignore
@@ -1,5 +1,6 @@
/shmctl01
/shmctl02
+/shmctl03
/shmctl04
/shmctl05
/shmctl06
diff --git a/testcases/kernel/syscalls/ipc/shmctl/shmctl03.c b/testcases/kernel/syscalls/ipc/shmctl/shmctl03.c
new file mode 100644
index 000000000..8868ab1cb
--- /dev/null
+++ b/testcases/kernel/syscalls/ipc/shmctl/shmctl03.c
@@ -0,0 +1,40 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2020 Cyril Hrubis <chrubis@suse.cz>
+ */
+/*
+ * Call shmctl() with IPC_INFO flag and check that the data are consistent with
+ * /proc/sys/kernel/shm*.
+ */
+
+#define _GNU_SOURCE
+#include "tst_test.h"
+#include "tst_safe_sysv_ipc.h"
+#include "libnewipc.h"
+
+static void verify_ipcinfo(void)
+{
+ struct shminfo info;
+
+ TEST(shmctl(0, IPC_INFO, (struct shmid_ds *)&info));
+
+ if (TST_RET < 0) {
+ tst_res(TFAIL | TTERRNO,
+ "shmctl(0, IPC_INFO, ...) returned %li",
+ TST_RET);
+ return;
+ }
+
+ if (info.shmmin != 1)
+ tst_res(TFAIL, "shmmin = %li, expected 1", info.shmmin);
+ else
+ tst_res(TPASS, "shmmin = 1");
+
+ TST_ASSERT_ULONG("/proc/sys/kernel/shmmax", info.shmmax);
+ TST_ASSERT_ULONG("/proc/sys/kernel/shmmni", info.shmmni);
+ TST_ASSERT_ULONG("/proc/sys/kernel/shmall", info.shmall);
+}
+
+static struct tst_test test = {
+ .test_all = verify_ipcinfo,
+};
--
2.26.2
^ permalink raw reply related [flat|nested] 16+ messages in thread* [LTP] [PATCH v2 08/10] syscalls/ipc: Add shmctl07 test
2020-09-07 15:01 [LTP] [PATCH v2 00/10] Rewrite shmctl() testcases Cyril Hrubis
` (6 preceding siblings ...)
2020-09-07 15:01 ` [LTP] [PATCH v2 07/10] syscalls/ipc: Add shmctl() IPC_INFO test Cyril Hrubis
@ 2020-09-07 15:01 ` Cyril Hrubis
2020-09-07 15:01 ` [LTP] [PATCH v2 09/10] syscalls/ipc: Add shmctl IPC_SET test Cyril Hrubis
` (2 subsequent siblings)
10 siblings, 0 replies; 16+ messages in thread
From: Cyril Hrubis @ 2020-09-07 15:01 UTC (permalink / raw)
To: ltp
A new test for SHM_LOCK and SHM_UNLOCK.
Signed-off-by: Cyril Hrubis <chrubis@suse.cz>
---
runtest/syscalls | 1 +
runtest/syscalls-ipc | 1 +
.../kernel/syscalls/ipc/shmctl/.gitignore | 1 +
.../kernel/syscalls/ipc/shmctl/shmctl07.c | 66 +++++++++++++++++++
4 files changed, 69 insertions(+)
create mode 100644 testcases/kernel/syscalls/ipc/shmctl/shmctl07.c
diff --git a/runtest/syscalls b/runtest/syscalls
index 35770e6db..448b893ea 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -1359,6 +1359,7 @@ shmctl03 shmctl03
shmctl04 shmctl04
shmctl05 shmctl05
shmctl06 shmctl06
+shmctl07 shmctl07
shmdt01 shmdt01
shmdt02 shmdt02
diff --git a/runtest/syscalls-ipc b/runtest/syscalls-ipc
index e6837414c..5b50820d2 100644
--- a/runtest/syscalls-ipc
+++ b/runtest/syscalls-ipc
@@ -55,6 +55,7 @@ shmctl03 shmctl03
shmctl04 shmctl04
shmctl05 shmctl05
shmctl06 shmctl06
+shmctl07 shmctl07
shmdt01 shmdt01
shmdt02 shmdt02
diff --git a/testcases/kernel/syscalls/ipc/shmctl/.gitignore b/testcases/kernel/syscalls/ipc/shmctl/.gitignore
index 46b107344..4322d03b7 100644
--- a/testcases/kernel/syscalls/ipc/shmctl/.gitignore
+++ b/testcases/kernel/syscalls/ipc/shmctl/.gitignore
@@ -4,3 +4,4 @@
/shmctl04
/shmctl05
/shmctl06
+/shmctl07
diff --git a/testcases/kernel/syscalls/ipc/shmctl/shmctl07.c b/testcases/kernel/syscalls/ipc/shmctl/shmctl07.c
new file mode 100644
index 000000000..409203db7
--- /dev/null
+++ b/testcases/kernel/syscalls/ipc/shmctl/shmctl07.c
@@ -0,0 +1,66 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2020 Cyril Hrubis <chrubis@suse.cz>
+ */
+/*
+ * Test for a SHM_LOCK and SHM_UNLOCK.
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include "tst_test.h"
+#include "tst_safe_sysv_ipc.h"
+#include "libnewipc.h"
+
+#define SHM_SIZE 2048
+
+static int shm_id = -1;
+
+static void verify_shmlock(void)
+{
+ struct shmid_ds ds;
+
+ TEST(shmctl(shm_id, SHM_LOCK, NULL));
+
+ if (TST_RET != 0)
+ tst_res(TFAIL | TTERRNO, "shmctl(%i, SHM_LOCK, NULL)", shm_id);
+ else
+ tst_res(TPASS, "shmctl(%i, SHM_LOCK, NULL)", shm_id);
+
+
+ SAFE_SHMCTL(shm_id, IPC_STAT, &ds);
+
+ if (ds.shm_perm.mode & SHM_LOCKED)
+ tst_res(TPASS, "SMH_LOCKED bit is on in shm_perm.mode");
+ else
+ tst_res(TFAIL, "SHM_LOCKED bit is off in shm_perm.mode");
+
+ TEST(shmctl(shm_id, SHM_UNLOCK, NULL));
+
+ if (TST_RET != 0)
+ tst_res(TFAIL | TTERRNO, "shmctl(%i, SHM_UNLOCK, NULL)", shm_id);
+ else
+ tst_res(TPASS, "shmctl(%i, SHM_UNLOCK, NULL)", shm_id);
+
+ if (ds.shm_perm.mode & SHM_LOCKED)
+ tst_res(TPASS, "SHM_LOCKED bit is off in shm_perm.mode");
+ else
+ tst_res(TFAIL, "SMH_LOCKED bit is on in shm_perm.mode");
+}
+
+static void setup(void)
+{
+ shm_id = SAFE_SHMGET(IPC_PRIVATE, SHM_SIZE, IPC_CREAT | SHM_RW);
+}
+
+static void cleanup(void)
+{
+ if (shm_id >= 0)
+ SAFE_SHMCTL(shm_id, IPC_RMID, NULL);
+}
+
+static struct tst_test test = {
+ .setup = setup,
+ .cleanup = cleanup,
+ .test_all = verify_shmlock,
+};
--
2.26.2
^ permalink raw reply related [flat|nested] 16+ messages in thread* [LTP] [PATCH v2 09/10] syscalls/ipc: Add shmctl IPC_SET test
2020-09-07 15:01 [LTP] [PATCH v2 00/10] Rewrite shmctl() testcases Cyril Hrubis
` (7 preceding siblings ...)
2020-09-07 15:01 ` [LTP] [PATCH v2 08/10] syscalls/ipc: Add shmctl07 test Cyril Hrubis
@ 2020-09-07 15:01 ` Cyril Hrubis
2020-09-08 5:34 ` Yang Xu
2020-09-07 15:01 ` [LTP] [PATCH v2 10/10] syscalls/ipc: Rewrite shmctl01 Cyril Hrubis
2020-09-09 6:32 ` [LTP] [PATCH v2 00/10] Rewrite shmctl() testcases Li Wang
10 siblings, 1 reply; 16+ messages in thread
From: Cyril Hrubis @ 2020-09-07 15:01 UTC (permalink / raw)
To: ltp
Signed-off-by: Cyril Hrubis <chrubis@suse.cz>
---
runtest/syscalls | 1 +
runtest/syscalls-ipc | 1 +
.../kernel/syscalls/ipc/shmctl/.gitignore | 1 +
.../kernel/syscalls/ipc/shmctl/shmctl07.c | 6 +-
.../kernel/syscalls/ipc/shmctl/shmctl08.c | 103 ++++++++++++++++++
5 files changed, 110 insertions(+), 2 deletions(-)
create mode 100644 testcases/kernel/syscalls/ipc/shmctl/shmctl08.c
diff --git a/runtest/syscalls b/runtest/syscalls
index 448b893ea..9f1c9ee0c 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -1360,6 +1360,7 @@ shmctl04 shmctl04
shmctl05 shmctl05
shmctl06 shmctl06
shmctl07 shmctl07
+shmctl08 shmctl08
shmdt01 shmdt01
shmdt02 shmdt02
diff --git a/runtest/syscalls-ipc b/runtest/syscalls-ipc
index 5b50820d2..4eb71e3cb 100644
--- a/runtest/syscalls-ipc
+++ b/runtest/syscalls-ipc
@@ -56,6 +56,7 @@ shmctl04 shmctl04
shmctl05 shmctl05
shmctl06 shmctl06
shmctl07 shmctl07
+shmctl08 shmctl08
shmdt01 shmdt01
shmdt02 shmdt02
diff --git a/testcases/kernel/syscalls/ipc/shmctl/.gitignore b/testcases/kernel/syscalls/ipc/shmctl/.gitignore
index 4322d03b7..f3f88ee17 100644
--- a/testcases/kernel/syscalls/ipc/shmctl/.gitignore
+++ b/testcases/kernel/syscalls/ipc/shmctl/.gitignore
@@ -5,3 +5,4 @@
/shmctl05
/shmctl06
/shmctl07
+/shmctl08
diff --git a/testcases/kernel/syscalls/ipc/shmctl/shmctl07.c b/testcases/kernel/syscalls/ipc/shmctl/shmctl07.c
index 409203db7..39b9ad78a 100644
--- a/testcases/kernel/syscalls/ipc/shmctl/shmctl07.c
+++ b/testcases/kernel/syscalls/ipc/shmctl/shmctl07.c
@@ -42,10 +42,12 @@ static void verify_shmlock(void)
else
tst_res(TPASS, "shmctl(%i, SHM_UNLOCK, NULL)", shm_id);
+ SAFE_SHMCTL(shm_id, IPC_STAT, &ds);
+
if (ds.shm_perm.mode & SHM_LOCKED)
- tst_res(TPASS, "SHM_LOCKED bit is off in shm_perm.mode");
- else
tst_res(TFAIL, "SMH_LOCKED bit is on in shm_perm.mode");
+ else
+ tst_res(TPASS, "SHM_LOCKED bit is off in shm_perm.mode");
}
static void setup(void)
diff --git a/testcases/kernel/syscalls/ipc/shmctl/shmctl08.c b/testcases/kernel/syscalls/ipc/shmctl/shmctl08.c
new file mode 100644
index 000000000..157ced608
--- /dev/null
+++ b/testcases/kernel/syscalls/ipc/shmctl/shmctl08.c
@@ -0,0 +1,103 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2020 Cyril Hrubis <chrubis@suse.cz>
+ */
+/*
+ * Test for a SHM_SET.
+ *
+ * The test clears the group and others bits from the shm_perm.mode and checks
+ * the result as well as if the ctime was updated correctly.
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include "tst_test.h"
+#include "tst_safe_sysv_ipc.h"
+#include "libnewipc.h"
+
+#define SHM_SIZE 2048
+
+static int shm_id = -1;
+
+static int test_ipc_set(struct shmid_ds *ds)
+{
+ TEST(shmctl(shm_id, IPC_SET, ds));
+
+ if (TST_RET != 0) {
+ tst_res(TFAIL, "shmctl(%i, IPC_SET, ...)", shm_id);
+ return 1;
+ }
+
+ tst_res(TPASS, "shmctl(%i, IPC_SET, {shm_perm.mode=%04o})",
+ shm_id, ds->shm_perm.mode);
+ return 0;
+}
+
+static void check_mode(struct shmid_ds *ds, short exp_mode)
+{
+ if (ds->shm_perm.mode == exp_mode) {
+ tst_res(TPASS, "shm_perm.mode=%04o", exp_mode);
+ return;
+ }
+
+ tst_res(TFAIL, "shm_perm.mode=%04o, expected %i",
+ ds->shm_perm.mode, exp_mode);
+}
+
+static void verify_shmset(void)
+{
+ struct shmid_ds ds;
+ unsigned short old_mode;
+ time_t old_ctime;
+
+ SAFE_SHMCTL(shm_id, IPC_STAT, &ds);
+
+ old_mode = ds.shm_perm.mode;
+ old_ctime = ds.shm_ctime;
+
+ check_mode(&ds, 0666);
+
+ sleep(1);
+
+ ds.shm_perm.mode &= ~0066;
+
+ if (test_ipc_set(&ds))
+ return;
+
+ memset(&ds, 0, sizeof(ds));
+ SAFE_SHMCTL(shm_id, IPC_STAT, &ds);
+ check_mode(&ds, old_mode & ~0066);
+
+ if (ds.shm_ctime <= old_ctime || ds.shm_ctime > old_ctime + 10) {
+ tst_res(TFAIL, "shm_ctime not updated old %li new %li",
+ (long)old_ctime, (long)ds.shm_ctime);
+ } else {
+ tst_res(TPASS, "shm_ctime updated correctly diff=%li",
+ (long)(ds.shm_ctime - old_ctime));
+ }
+
+ ds.shm_perm.mode = old_mode;
+ if (test_ipc_set(&ds))
+ return;
+
+ memset(&ds, 0, sizeof(ds));
+ SAFE_SHMCTL(shm_id, IPC_STAT, &ds);
+ check_mode(&ds, old_mode & MODE_MASK);
+}
+
+static void setup(void)
+{
+ shm_id = SAFE_SHMGET(IPC_PRIVATE, SHM_SIZE, IPC_CREAT | 0666);
+}
+
+static void cleanup(void)
+{
+ if (shm_id >= 0)
+ SAFE_SHMCTL(shm_id, IPC_RMID, NULL);
+}
+
+static struct tst_test test = {
+ .setup = setup,
+ .cleanup = cleanup,
+ .test_all = verify_shmset,
+};
--
2.26.2
^ permalink raw reply related [flat|nested] 16+ messages in thread* [LTP] [PATCH v2 09/10] syscalls/ipc: Add shmctl IPC_SET test
2020-09-07 15:01 ` [LTP] [PATCH v2 09/10] syscalls/ipc: Add shmctl IPC_SET test Cyril Hrubis
@ 2020-09-08 5:34 ` Yang Xu
2020-09-08 6:58 ` Cyril Hrubis
0 siblings, 1 reply; 16+ messages in thread
From: Yang Xu @ 2020-09-08 5:34 UTC (permalink / raw)
To: ltp
Hi Cyril
> Signed-off-by: Cyril Hrubis <chrubis@suse.cz>
> ---
> runtest/syscalls | 1 +
> runtest/syscalls-ipc | 1 +
> .../kernel/syscalls/ipc/shmctl/.gitignore | 1 +
> .../kernel/syscalls/ipc/shmctl/shmctl07.c | 6 +-
> .../kernel/syscalls/ipc/shmctl/shmctl08.c | 103 ++++++++++++++++++
> 5 files changed, 110 insertions(+), 2 deletions(-)
> create mode 100644 testcases/kernel/syscalls/ipc/shmctl/shmctl08.c
>
> diff --git a/runtest/syscalls b/runtest/syscalls
> index 448b893ea..9f1c9ee0c 100644
> --- a/runtest/syscalls
> +++ b/runtest/syscalls
> @@ -1360,6 +1360,7 @@ shmctl04 shmctl04
> shmctl05 shmctl05
> shmctl06 shmctl06
> shmctl07 shmctl07
> +shmctl08 shmctl08
>
> shmdt01 shmdt01
> shmdt02 shmdt02
> diff --git a/runtest/syscalls-ipc b/runtest/syscalls-ipc
> index 5b50820d2..4eb71e3cb 100644
> --- a/runtest/syscalls-ipc
> +++ b/runtest/syscalls-ipc
> @@ -56,6 +56,7 @@ shmctl04 shmctl04
> shmctl05 shmctl05
> shmctl06 shmctl06
> shmctl07 shmctl07
> +shmctl08 shmctl08
>
> shmdt01 shmdt01
> shmdt02 shmdt02
> diff --git a/testcases/kernel/syscalls/ipc/shmctl/.gitignore b/testcases/kernel/syscalls/ipc/shmctl/.gitignore
> index 4322d03b7..f3f88ee17 100644
> --- a/testcases/kernel/syscalls/ipc/shmctl/.gitignore
> +++ b/testcases/kernel/syscalls/ipc/shmctl/.gitignore
> @@ -5,3 +5,4 @@
> /shmctl05
> /shmctl06
> /shmctl07
> +/shmctl08
> diff --git a/testcases/kernel/syscalls/ipc/shmctl/shmctl07.c b/testcases/kernel/syscalls/ipc/shmctl/shmctl07.c
> index 409203db7..39b9ad78a 100644
> --- a/testcases/kernel/syscalls/ipc/shmctl/shmctl07.c
> +++ b/testcases/kernel/syscalls/ipc/shmctl/shmctl07.c
> @@ -42,10 +42,12 @@ static void verify_shmlock(void)
> else
> tst_res(TPASS, "shmctl(%i, SHM_UNLOCK, NULL)", shm_id);
>
> + SAFE_SHMCTL(shm_id, IPC_STAT, &ds);
> +
> if (ds.shm_perm.mode & SHM_LOCKED)
> - tst_res(TPASS, "SHM_LOCKED bit is off in shm_perm.mode");
> - else
> tst_res(TFAIL, "SMH_LOCKED bit is on in shm_perm.mode");
> + else
> + tst_res(TPASS, "SHM_LOCKED bit is off in shm_perm.mode");
> }
>
This change should belong to "syscalls/ipc: Add shmctl07 test" patch.
> static void setup(void)
> diff --git a/testcases/kernel/syscalls/ipc/shmctl/shmctl08.c b/testcases/kernel/syscalls/ipc/shmctl/shmctl08.c
> new file mode 100644
> index 000000000..157ced608
> --- /dev/null
> +++ b/testcases/kernel/syscalls/ipc/shmctl/shmctl08.c
> @@ -0,0 +1,103 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Copyright (C) 2020 Cyril Hrubis <chrubis@suse.cz>
> + */
> +/*
> + * Test for a SHM_SET.
> + *
> + * The test clears the group and others bits from the shm_perm.mode and checks
> + * the result as well as if the ctime was updated correctly.
> + */
> +
> +#define _GNU_SOURCE
> +#include <stdio.h>
> +#include "tst_test.h"
> +#include "tst_safe_sysv_ipc.h"
> +#include "libnewipc.h"
> +
> +#define SHM_SIZE 2048
> +
> +static int shm_id = -1;
> +
> +static int test_ipc_set(struct shmid_ds *ds)
> +{
> + TEST(shmctl(shm_id, IPC_SET, ds));
> +
> + if (TST_RET != 0) {
> + tst_res(TFAIL, "shmctl(%i, IPC_SET, ...)", shm_id);
> + return 1;
> + }
> +
> + tst_res(TPASS, "shmctl(%i, IPC_SET, {shm_perm.mode=%04o})",
> + shm_id, ds->shm_perm.mode);
> + return 0;
> +}
> +
> +static void check_mode(struct shmid_ds *ds, short exp_mode)
> +{
> + if (ds->shm_perm.mode == exp_mode) {
> + tst_res(TPASS, "shm_perm.mode=%04o", exp_mode);
> + return;
> + }
> +
> + tst_res(TFAIL, "shm_perm.mode=%04o, expected %i",
> + ds->shm_perm.mode, exp_mode);
> +}
> +
> +static void verify_shmset(void)
> +{
> + struct shmid_ds ds;
> + unsigned short old_mode;
> + time_t old_ctime;
> +
> + SAFE_SHMCTL(shm_id, IPC_STAT, &ds);
> +
> + old_mode = ds.shm_perm.mode;
> + old_ctime = ds.shm_ctime;
> +
> + check_mode(&ds, 0666);
> +
> + sleep(1);
> +
> + ds.shm_perm.mode &= ~0066;
> +
> + if (test_ipc_set(&ds))
> + return;
> +
> + memset(&ds, 0, sizeof(ds));
> + SAFE_SHMCTL(shm_id, IPC_STAT, &ds);
> + check_mode(&ds, old_mode & ~0066);
> +
> + if (ds.shm_ctime <= old_ctime || ds.shm_ctime > old_ctime + 10) {
> + tst_res(TFAIL, "shm_ctime not updated old %li new %li",
> + (long)old_ctime, (long)ds.shm_ctime);
> + } else {
> + tst_res(TPASS, "shm_ctime updated correctly diff=%li",
> + (long)(ds.shm_ctime - old_ctime));
> + }
> +
> + ds.shm_perm.mode = old_mode;
> + if (test_ipc_set(&ds))
> + return;
> +
> + memset(&ds, 0, sizeof(ds));
> + SAFE_SHMCTL(shm_id, IPC_STAT, &ds);
> + check_mode(&ds, old_mode & MODE_MASK);
> +}
> +
> +static void setup(void)
> +{
> + shm_id = SAFE_SHMGET(IPC_PRIVATE, SHM_SIZE, IPC_CREAT | 0666);
> +}
> +
> +static void cleanup(void)
> +{
> + if (shm_id >= 0)
> + SAFE_SHMCTL(shm_id, IPC_RMID, NULL);
> +}
> +
> +static struct tst_test test = {
> + .setup = setup,
> + .cleanup = cleanup,
> + .test_all = verify_shmset,
> +};
>
^ permalink raw reply [flat|nested] 16+ messages in thread* [LTP] [PATCH v2 09/10] syscalls/ipc: Add shmctl IPC_SET test
2020-09-08 5:34 ` Yang Xu
@ 2020-09-08 6:58 ` Cyril Hrubis
2020-09-08 7:04 ` Yang Xu
0 siblings, 1 reply; 16+ messages in thread
From: Cyril Hrubis @ 2020-09-08 6:58 UTC (permalink / raw)
To: ltp
Hi!
> > diff --git a/testcases/kernel/syscalls/ipc/shmctl/shmctl07.c b/testcases/kernel/syscalls/ipc/shmctl/shmctl07.c
> > index 409203db7..39b9ad78a 100644
> > --- a/testcases/kernel/syscalls/ipc/shmctl/shmctl07.c
> > +++ b/testcases/kernel/syscalls/ipc/shmctl/shmctl07.c
> > @@ -42,10 +42,12 @@ static void verify_shmlock(void)
> > else
> > tst_res(TPASS, "shmctl(%i, SHM_UNLOCK, NULL)", shm_id);
> >
> > + SAFE_SHMCTL(shm_id, IPC_STAT, &ds);
> > +
> > if (ds.shm_perm.mode & SHM_LOCKED)
> > - tst_res(TPASS, "SHM_LOCKED bit is off in shm_perm.mode");
> > - else
> > tst_res(TFAIL, "SMH_LOCKED bit is on in shm_perm.mode");
> > + else
> > + tst_res(TPASS, "SHM_LOCKED bit is off in shm_perm.mode");
> > }
> >
> This change should belong to "syscalls/ipc: Add shmctl07 test" patch.
My bad I messed up, will fix that later on.
Anything else I missed there?
--
Cyril Hrubis
chrubis@suse.cz
^ permalink raw reply [flat|nested] 16+ messages in thread
* [LTP] [PATCH v2 09/10] syscalls/ipc: Add shmctl IPC_SET test
2020-09-08 6:58 ` Cyril Hrubis
@ 2020-09-08 7:04 ` Yang Xu
0 siblings, 0 replies; 16+ messages in thread
From: Yang Xu @ 2020-09-08 7:04 UTC (permalink / raw)
To: ltp
Hi Cyril
> Hi!
>>> diff --git a/testcases/kernel/syscalls/ipc/shmctl/shmctl07.c b/testcases/kernel/syscalls/ipc/shmctl/shmctl07.c
>>> index 409203db7..39b9ad78a 100644
>>> --- a/testcases/kernel/syscalls/ipc/shmctl/shmctl07.c
>>> +++ b/testcases/kernel/syscalls/ipc/shmctl/shmctl07.c
>>> @@ -42,10 +42,12 @@ static void verify_shmlock(void)
>>> else
>>> tst_res(TPASS, "shmctl(%i, SHM_UNLOCK, NULL)", shm_id);
>>>
>>> + SAFE_SHMCTL(shm_id, IPC_STAT, &ds);
>>> +
>>> if (ds.shm_perm.mode & SHM_LOCKED)
>>> - tst_res(TPASS, "SHM_LOCKED bit is off in shm_perm.mode");
>>> - else
>>> tst_res(TFAIL, "SMH_LOCKED bit is on in shm_perm.mode");
>>> + else
>>> + tst_res(TPASS, "SHM_LOCKED bit is off in shm_perm.mode");
>>> }
>>>
>> This change should belong to "syscalls/ipc: Add shmctl07 test" patch.
>
> My bad I messed up, will fix that later on.
>
> Anything else I missed there?
I have seen the whole patchset, only find this.
>
^ permalink raw reply [flat|nested] 16+ messages in thread
* [LTP] [PATCH v2 10/10] syscalls/ipc: Rewrite shmctl01
2020-09-07 15:01 [LTP] [PATCH v2 00/10] Rewrite shmctl() testcases Cyril Hrubis
` (8 preceding siblings ...)
2020-09-07 15:01 ` [LTP] [PATCH v2 09/10] syscalls/ipc: Add shmctl IPC_SET test Cyril Hrubis
@ 2020-09-07 15:01 ` Cyril Hrubis
2020-09-09 6:32 ` [LTP] [PATCH v2 00/10] Rewrite shmctl() testcases Li Wang
10 siblings, 0 replies; 16+ messages in thread
From: Cyril Hrubis @ 2020-09-07 15:01 UTC (permalink / raw)
To: ltp
This commit rewrites the shmctl01 and only keep testcases not covered
by the rest of the testcases.
Signed-off-by: Cyril Hrubis <chrubis@suse.cz>
Reviewed-by: Martin Doucha <mdoucha@suse.cz>
---
testcases/kernel/syscalls/ipc/shmctl/Makefile | 1 -
.../kernel/syscalls/ipc/shmctl/shmctl01.c | 586 ++++++------------
2 files changed, 178 insertions(+), 409 deletions(-)
diff --git a/testcases/kernel/syscalls/ipc/shmctl/Makefile b/testcases/kernel/syscalls/ipc/shmctl/Makefile
index 9d535014f..106b73697 100644
--- a/testcases/kernel/syscalls/ipc/shmctl/Makefile
+++ b/testcases/kernel/syscalls/ipc/shmctl/Makefile
@@ -10,7 +10,6 @@ shmctl05: LDLIBS += -lrt
include $(top_srcdir)/include/mk/testcases.mk
-shmctl01: LTPLDLIBS = -lltpipc
shmctl02 shmctl04 shmctl06: LTPLDLIBS = -lltpnewipc
include $(top_srcdir)/include/mk/generic_leaf_target.mk
diff --git a/testcases/kernel/syscalls/ipc/shmctl/shmctl01.c b/testcases/kernel/syscalls/ipc/shmctl/shmctl01.c
index 52bf23a40..3a39a4d74 100644
--- a/testcases/kernel/syscalls/ipc/shmctl/shmctl01.c
+++ b/testcases/kernel/syscalls/ipc/shmctl/shmctl01.c
@@ -1,499 +1,269 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (c) International Business Machines Corp., 2001
- *
- * 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) 2020 Cyril Hrubis <chrubis@suse.cz>
*/
-
/*
- * NAME
- * shmctl01.c
+ * Verify that shmctl() IPC_STAT and SHM_STAT reports correct data.
+ *
+ * The shm_nattach is excercised by:
*
- * DESCRIPTION
- * shmctl01 - test the IPC_STAT, IPC_SET and IPC_RMID commands as
- * they are used with shmctl()
+ * 1. forking() children that attach and detach SHM
+ * 2. attaching the SHM before fork and letting the children detach it
*
- * ALGORITHM
- * loop if that option was specified
- * create a shared memory segment with read and write permission
- * set up any test case specific conditions
- * call shmctl() using the TEST macro
- * check the return code
- * if failure, issue a FAIL message.
- * otherwise,
- * if doing functionality testing
- * call the correct test function
- * if the conditions are correct,
- * issue a PASS message
- * otherwise
- * issue a FAIL message
- * otherwise
- * issue a PASS message
- * call cleanup
+ * We check that the number shm_nattach is correct after each step we do.
*/
-#ifndef _GNU_SOURCE
#define _GNU_SOURCE
-#endif
-#include "ipcshm.h"
-#include "safe_macros.h"
-
-char *TCID = "shmctl01";
-
-static int shm_id_1 = -1;
-static int shm_index;
-static struct shmid_ds buf;
-static struct shminfo info;
-static long save_time;
-
-#define FIRST 0
-#define SECOND 1
-static int stat_time;
-
-static void *set_shared;
-
-#define N_ATTACH 4
-
-static pid_t pid_arr[N_ATTACH];
-
-/* Setup, cleanup and check routines for IPC_STAT */
-static void stat_setup(void), func_istat(int ret);
-static void stat_cleanup(void);
-
-/* Setup and check routines for IPC_SET */
-static void set_setup(void), func_set(int ret);
-
-/* Check routine for IPC_INFO */
-static void func_info(int ret);
-
-/* Check routine for SHM_STAT */
-static void func_sstat(int ret);
-static void func_sstat_setup(void);
-
-/* Check routine for SHM_LOCK */
-static void func_lock(int ret);
-
-/* Check routine for SHM_UNLOCK */
-static void func_unlock(int ret);
-
-/* Check routine for IPC_RMID */
-static void func_rmid(int ret);
-
-/* Child function */
-static void do_child(void);
-
-static struct test_case_t {
- int *shmid;
- int cmd;
- struct shmid_ds *arg;
- void (*func_test) (int);
- void (*func_setup) (void);
-} TC[] = {
- {&shm_id_1, IPC_STAT, &buf, func_istat, stat_setup},
-#ifndef UCLINUX
- /*
- * The second test is not applicable to uClinux;
- * shared memory segments are detached on exec(),
- * so cannot be passed to uClinux children.
- */
- {&shm_id_1, IPC_STAT, &buf, func_istat, stat_setup},
-#endif
- {&shm_id_1, IPC_SET, &buf, func_set, set_setup},
- {&shm_id_1, IPC_INFO, (struct shmid_ds *) &info, func_info, NULL},
- {&shm_index, SHM_STAT, &buf, func_sstat, func_sstat_setup},
- {&shm_id_1, SHM_LOCK, NULL, func_lock, NULL},
- {&shm_id_1, SHM_UNLOCK, NULL, func_unlock, NULL},
- {&shm_id_1, IPC_RMID, NULL, func_rmid, NULL},
-};
+#include <stdlib.h>
+#include "tst_test.h"
+#include "tst_safe_sysv_ipc.h"
+#include "libnewipc.h"
-static int TST_TOTAL = ARRAY_SIZE(TC);
+#define NCHILD 20
-#define NEWMODE 0066
+static pid_t children[NCHILD];
-#ifdef UCLINUX
-#define PIPE_NAME "shmctl01"
-static char *argv0;
-#endif
+static int shm_id;
+static int shm_idx;
+static time_t ctime_min, ctime_max;
-static int stat_i;
+static void *addr;
-int main(int argc, char *argv[])
+static void attach_child(void)
{
- int lc;
- int i;
-
- tst_parse_opts(argc, argv, NULL, NULL);
-#ifdef UCLINUX
- argv0 = argv[0];
- maybe_run_child(do_child, "ddd", &stat_i, &stat_time, &shm_id_1);
-#endif
-
- setup();
-
- for (lc = 0; TEST_LOOPING(lc); lc++) {
- tst_count = 0;
-
- stat_time = FIRST;
-
- /*
- * Create a shared memory segment with read and write
- * permissions. Do this here instead of in setup()
- * so that looping (-i) will work correctly.
- */
- shm_id_1 = shmget(shmkey, SHM_SIZE,
- IPC_CREAT | IPC_EXCL | SHM_RW);
- if (shm_id_1 == -1)
- tst_brkm(TBROK, cleanup, "couldn't create the shared"
- " memory segment");
-
- for (i = 0; i < TST_TOTAL; i++) {
-
- /*
- * if needed, set up any required conditions by
- * calling the appropriate setup function
- */
- if (TC[i].func_setup != NULL)
- (*TC[i].func_setup) ();
-
- TEST(shmctl(*(TC[i].shmid), TC[i].cmd, TC[i].arg));
-
- if (TEST_RETURN == -1) {
- tst_resm(TFAIL, "%s call failed - errno "
- "= %d : %s", TCID, TEST_ERRNO,
- strerror(TEST_ERRNO));
- continue;
- }
- (*TC[i].func_test) (TEST_RETURN);
- }
- }
+ pause();
+
+ addr = SAFE_SHMAT(shm_id, NULL, 0);
+
+ pause();
- cleanup();
- tst_exit();
+ SAFE_SHMDT(addr);
+
+ pause();
+
+ exit(0);
}
-/*
- * set_shmat() - Attach the shared memory and return the pointer. Use
- * this seperate routine to avoid code duplication in
- * stat_setup() below.
- */
-void *set_shmat(void)
+static void detach_child(void)
{
- void *rval;
-
- /* attach the shared memory */
- rval = shmat(shm_id_1, 0, 0);
-
- /*
- * if shmat() fails, the only thing we can do is
- * print a message to that effect.
- */
- if (rval == (void *)-1) {
- tst_resm(TBROK, "shmat() failed - %s", strerror(errno));
- cleanup();
- }
+ pause();
+
+ SAFE_SHMDT(addr);
- return rval;
+ pause();
+
+ exit(0);
}
-/*
- * stat_setup() - Set up for the IPC_STAT command with shmctl().
- * Make things interesting by forking some children
- * that will either attach or inherit the shared memory.
- */
-void stat_setup(void)
+static void fork_children(void (*child_func)(void))
{
- void *set_shmat();
- pid_t pid;
-
- /*
- * The first time through, let the children attach the memory.
- * The second time through, attach the memory first and let
- * the children inherit the memory.
- */
-
- if (stat_time == SECOND)
- /*
- * use the global "set_shared" variable here so that
- * it can be removed in the stat_func() routine.
- */
- set_shared = set_shmat();
-
- tst_old_flush();
- for (stat_i = 0; stat_i < N_ATTACH; stat_i++) {
- pid = FORK_OR_VFORK();
- if (pid == -1)
- tst_brkm(TBROK, cleanup, "could not fork");
-
- if (pid == 0) {
-#ifdef UCLINUX
- if (self_exec(argv0, "ddd", stat_i, stat_time,
- shm_id_1) < 0)
- tst_brkm(TBROK, cleanup, "could not self_exec");
-#else
- do_child();
-#endif
-
- } else {
- /* save the child's pid for cleanup later */
- pid_arr[stat_i] = pid;
- TST_PROCESS_STATE_WAIT(cleanup, pid, 'S');
- }
+ unsigned int i;
+
+ for (i = 0; i < NCHILD; i++) {
+ pid_t pid = SAFE_FORK();
+
+ if (!pid)
+ child_func();
+
+ children[i] = pid;
}
}
-void do_child(void)
+static void wait_for_children(void)
{
- void *test;
+ unsigned int i;
- if (stat_time == FIRST)
- test = set_shmat();
- else
- test = set_shared;
+ for (i = 0; i < NCHILD; i++)
+ TST_PROCESS_STATE_WAIT(children[i], 'S', 0);
+}
- memcpy(test, &stat_i, sizeof(stat_i));
+static void signal_children(void)
+{
+ unsigned int i;
- /* pause until we get a signal from stat_cleanup() */
- pause();
+ for (i = 0; i < NCHILD; i++)
+ SAFE_KILL(children[i], SIGUSR1);
+}
- /* now we're back - detach the memory and exit */
- if (shmdt(test) == -1)
- tst_resm(TBROK, "shmdt() failed - %d", errno);
+static void reap_children(void)
+{
+ unsigned int i;
- tst_exit();
+ for (i = 0; i < NCHILD; i++)
+ SAFE_WAITPID(children[i], NULL, 0);
}
-/*
- * func_istat() - check the functionality of the IPC_STAT command with shmctl()
- * by looking@the pid of the creator, the segement size,
- * the number of attaches and the mode.
- */
-void func_istat(int ret)
+static void check_nattch(int exp_nattch, const char *msg)
{
- int fail = 0;
- pid_t pid;
+ struct shmid_ds ds1;
+ struct shmid_ds ds2;
- /* check perm, pid, nattach and size */
+ SAFE_SHMCTL(shm_id, IPC_STAT, &ds1);
+ SAFE_SHMCTL(shm_idx, SHM_STAT, &ds2);
- pid = getpid();
-
- if (buf.shm_cpid != pid) {
- tst_resm(TFAIL, "creator pid is incorrect");
- fail = 1;
+ if (ds1.shm_nattch != ds2.shm_nattch) {
+ tst_res(TFAIL, "IPC_STAT nattch=%li SHM_STAT nattch=%li",
+ (long)ds1.shm_nattch, (long)ds2.shm_nattch);
+ return;
}
- if (!fail && buf.shm_segsz != SHM_SIZE) {
- tst_resm(TFAIL, "segment size is incorrect");
- fail = 1;
+ if ((int)ds1.shm_nattch == exp_nattch) {
+ tst_res(TPASS, "%s shm_nattch=%i", msg, exp_nattch);
+ return;
}
- /*
- * The first time through, only the children attach the memory, so
- * the attaches equal N_ATTACH + stat_time (0). The second time
- * through, the parent attaches the memory and the children inherit
- * that memory so the attaches equal N_ATTACH + stat_time (1).
- */
- if (!fail && buf.shm_nattch != N_ATTACH + stat_time) {
- tst_resm(TFAIL, "# of attaches is incorrect - %ld",
- buf.shm_nattch);
- fail = 1;
- }
+ tst_res(TFAIL, "%s shm_nattcg=%li expected %i",
+ msg, (long)ds1.shm_nattch, exp_nattch);
+}
- /* use MODE_MASK to make sure we are comparing the last 9 bits */
- if (!fail && (buf.shm_perm.mode & MODE_MASK) !=
- ((SHM_RW) & MODE_MASK)) {
- tst_resm(TFAIL, "segment mode is incorrect");
- fail = 1;
- }
+static void verify_shmstat_attach(void)
+{
+ fork_children(attach_child);
+ wait_for_children();
- stat_cleanup();
+ check_nattch(0, "before child shmat()");
- /* save the change time for use in the next test */
- save_time = buf.shm_ctime;
+ signal_children();
+ wait_for_children();
- if (fail)
- return;
+ check_nattch(NCHILD, "after child shmat()");
+
+ signal_children();
+ wait_for_children();
+
+ check_nattch(0, "after child shmdt()");
- tst_resm(TPASS, "pid, size, # of attaches and mode are correct "
- "- pass #%d", stat_time);
+ signal_children();
+ reap_children();
}
-/*
- * stat_cleanup() - signal the children to clean up after themselves and
- * have the parent make dessert, er, um, make that remove
- * the shared memory that is no longer needed.
- */
-void stat_cleanup(void)
+static void verify_shmstat_inherit(void)
{
- int i;
+ addr = SAFE_SHMAT(shm_id, NULL, 0);
- /* wake up the childern so they can detach the memory and exit */
- for (i = 0; i < N_ATTACH; i++) {
- SAFE_KILL(cleanup, pid_arr[i], SIGUSR1);
- }
+ fork_children(detach_child);
+ wait_for_children();
- /* remove the parent's shared memory the second time through */
- if (stat_time == SECOND) {
- if (shmdt(set_shared) == -1)
- tst_resm(TINFO, "shmdt() failed");
- }
+ check_nattch(NCHILD+1, "inherited after fork()");
- for (i = 0; i < N_ATTACH; i++) {
- SAFE_WAITPID(cleanup, pid_arr[i], NULL, 0);
- }
+ signal_children();
+ wait_for_children();
- stat_time++;
-}
+ check_nattch(1, "after child shmdt()");
-/*
- * set_setup() - set up for the IPC_SET command with shmctl()
- */
-void set_setup(void)
-{
- /* set up a new mode for the shared memory segment */
- buf.shm_perm.mode = SHM_RW | NEWMODE;
+ SAFE_SHMDT(addr);
- /* sleep for one second to get a different shm_ctime value */
- sleep(1);
+ check_nattch(0, "after parent shmdt()");
+
+ signal_children();
+ reap_children();
}
-/*
- * func_set() - check the functionality of the IPC_SET command with shmctl()
- */
-void func_set(int ret)
+static void check_ds(struct shmid_ds *ds, const char *desc)
{
- int fail = 0;
+ pid_t pid = getpid();
- /* first stat the shared memory to get the new data */
- if (shmctl(shm_id_1, IPC_STAT, &buf) == -1) {
- tst_resm(TBROK, "stat failed in func_set()");
- return;
+ if (ds->shm_segsz != SHM_SIZE) {
+ tst_res(TFAIL, "%s: shm_segsz=%zu, expected %i",
+ desc, ds->shm_segsz, SHM_SIZE);
+ } else {
+ tst_res(TPASS, "%s: shm_segsz=%i", desc, SHM_SIZE);
}
- if ((buf.shm_perm.mode & MODE_MASK) !=
- ((SHM_RW | NEWMODE) & MODE_MASK)) {
- tst_resm(TFAIL, "new mode is incorrect");
- fail = 1;
+ if (ds->shm_cpid != pid) {
+ tst_res(TFAIL, "%s: shm_cpid=%i, expected %i",
+ desc, ds->shm_cpid, pid);
+ } else {
+ tst_res(TPASS, "%s: shm_cpid=%i", desc, pid);
}
- if (!fail && save_time >= buf.shm_ctime) {
- tst_resm(TFAIL, "change time is incorrect");
- fail = 1;
+ if (ds->shm_ctime < ctime_min || ds->shm_ctime > ctime_max) {
+ tst_res(TFAIL, "%s: shm_ctime=%li, expected <%li,%li>",
+ desc, ds->shm_ctime, ctime_min, ctime_max);
+ } else {
+ tst_res(TPASS, "%s: shm_ctime=%li in range <%li,%li>",
+ desc, ds->shm_ctime, ctime_min, ctime_max);
}
-
- if (fail)
- return;
-
- tst_resm(TPASS, "new mode and change time are correct");
}
-static void func_info(int ret)
+static void shmstat_basic_check(void)
{
- if (info.shmmin != 1)
- tst_resm(TFAIL, "value of shmmin is incorrect");
- else
- tst_resm(TPASS, "get correct shared memory limits");
-}
+ struct shmid_ds ds;
-static void func_sstat(int ret)
-{
- if (ret >= 0)
- tst_resm(TPASS, "get correct shared memory id for index: %d",
- shm_index);
- else
- tst_resm(TFAIL, "shared memory id is incorrect, index: %d",
- shm_index);
-}
+ memset(&ds, 0, sizeof(ds));
+ SAFE_SHMCTL(shm_id, IPC_STAT, &ds);
-static void func_sstat_setup(void)
-{
- struct shm_info tmp;
- int ret;
-
- ret = shmctl(shm_id_1, SHM_INFO, (void *)&tmp);
- if (ret < 0)
- tst_resm(TFAIL|TERRNO, "shmctl(SHM_INFO)");
- else
- shm_index = ret;
-}
+ check_ds(&ds, "IPC_STAT");
-static void func_lock(int ret)
-{
- if (shmctl(shm_id_1, IPC_STAT, &buf) == -1) {
- tst_resm(TBROK, "stat failed in func_lock()");
- return;
- }
+ memset(&ds, 0, sizeof(ds));
+ SAFE_SHMCTL(shm_idx, SHM_STAT, &ds);
- if (buf.shm_perm.mode & SHM_LOCKED)
- tst_resm(TPASS, "SHM_LOCK is set");
- else
- tst_resm(TFAIL, "SHM_LOCK is cleared");
+ check_ds(&ds, "SHM_STAT");
}
-static void func_unlock(int ret)
-{
- if (shmctl(shm_id_1, IPC_STAT, &buf) == -1) {
- tst_resm(TBROK, "stat failed in func_unlock()");
- return;
- }
+static struct tcase {
+ void (*func)(void);
+ const char *desc;
+} tcases[] = {
+ {shmstat_basic_check, "Basic checks"},
+ {verify_shmstat_attach, "Children attach SHM"},
+ {verify_shmstat_inherit, "Chidlren inherit SHM"},
+};
- if (buf.shm_perm.mode & SHM_LOCKED)
- tst_resm(TFAIL, "SHM_LOCK is set");
- else
- tst_resm(TPASS, "SHM_LOCK is cleared");
+static void verify_shmstat(unsigned int n)
+{
+ tst_res(TINFO, "%s", tcases[n].desc);
+ tcases[n].func();
}
+static void dummy_sighandler(int sig)
+{
+ (void)sig;
+}
-/*
- * func_rmid() - check the functionality of the IPC_RMID command with shmctl()
- */
-void func_rmid(int ret)
+static int get_shm_idx_from_id(int shm_id)
{
- /* Do another shmctl() - we should get EINVAL */
- if (shmctl(shm_id_1, IPC_STAT, &buf) != -1)
- tst_brkm(TBROK, cleanup, "shmctl succeeded on expected fail");
+ struct shm_info dummy;
+ struct shmid_ds dummy_ds;
+ int max_idx, i;
- if (errno != EINVAL)
- tst_resm(TFAIL, "returned unexpected errno %d", errno);
- else
- tst_resm(TPASS, "shared memory appears to be removed");
+ max_idx = SAFE_SHMCTL(shm_id, SHM_INFO, (void*)&dummy);
- shm_id_1 = -1;
-}
+ for (i = 0; i <= max_idx; i++) {
+ if (shmctl(i, SHM_STAT, &dummy_ds) == shm_id)
+ return i;
+ }
-/*
- * sighandler() - handle signals, in this case SIGUSR1 is the only one expected
- */
-void sighandler(int sig)
-{
- if (sig != SIGUSR1)
- tst_resm(TBROK, "received unexpected signal %d", sig);
+ return -1;
}
-void setup(void)
+static void setup(void)
{
- tst_sig(FORK, sighandler, cleanup);
+ ctime_min = time(NULL);
+ shm_id = SAFE_SHMGET(IPC_PRIVATE, SHM_SIZE, IPC_CREAT | SHM_RW);
+ ctime_max = time(NULL);
+
+ shm_idx = get_shm_idx_from_id(shm_id);
- TEST_PAUSE;
+ if (shm_idx < 0)
+ tst_brk(TBROK, "Failed to get shm_id to idx mapping");
- tst_tmpdir();
+ tst_res(TINFO, "shm_id=%i maps to kernel index=%i", shm_id, shm_idx);
- shmkey = getipckey();
+ SAFE_SIGNAL(SIGUSR1, dummy_sighandler);
}
-void cleanup(void)
+static void cleanup(void)
{
- rm_shm(shm_id_1);
-
- tst_rmdir();
+ if (shm_id >= 0)
+ SAFE_SHMCTL(shm_id, IPC_RMID, NULL);
}
+
+static struct tst_test test = {
+ .setup = setup,
+ .cleanup = cleanup,
+ .forks_child = 1,
+ .test = verify_shmstat,
+ .tcnt = ARRAY_SIZE(tcases),
+};
--
2.26.2
^ permalink raw reply related [flat|nested] 16+ messages in thread* [LTP] [PATCH v2 00/10] Rewrite shmctl() testcases
2020-09-07 15:01 [LTP] [PATCH v2 00/10] Rewrite shmctl() testcases Cyril Hrubis
` (9 preceding siblings ...)
2020-09-07 15:01 ` [LTP] [PATCH v2 10/10] syscalls/ipc: Rewrite shmctl01 Cyril Hrubis
@ 2020-09-09 6:32 ` Li Wang
2020-09-10 16:06 ` Cyril Hrubis
10 siblings, 1 reply; 16+ messages in thread
From: Li Wang @ 2020-09-09 6:32 UTC (permalink / raw)
To: ltp
For the series:
Reviewed-by: Li Wang <liwang@redhat.com>
--
Regards,
Li Wang
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.linux.it/pipermail/ltp/attachments/20200909/787b8589/attachment.htm>
^ permalink raw reply [flat|nested] 16+ messages in thread