All of lore.kernel.org
 help / color / mirror / Atom feed
* [LTP] [PATCH 0/9] Rewrite shmctl() testcases
@ 2020-07-17 16:34 Cyril Hrubis
  2020-07-17 16:34 ` [LTP] [PATCH 1/9] syscalls/ipc: shmctl02: Convert to the new library Cyril Hrubis
                   ` (9 more replies)
  0 siblings, 10 replies; 24+ messages in thread
From: Cyril Hrubis @ 2020-07-17 16:34 UTC (permalink / raw)
  To: ltp

This patchset mostly rewrites old shmctl testcases from scratch and also
increases the coverage at least threefold.

There are still missing pieces though, there are no test that would
check that shm_atime and shm_dtime are valid as well as shm_lpid as well
as the coverage of ipc_perm is still lacking and should be added later
on.

Cyril Hrubis (9):
  syscalls/ipc: shmctl02: Convert to the new library
  syscalls/ipc: shmctl03: Remove.
  syscalls/ipc: shmctl04: Rewrite from scratch.
  syscalls/ipc: shmctl05 remove lib dependency
  lib/tst_assert: Add TST_ASSERT_ULONG()
  syscalls/ipc: Add shmctl() IPC_INFO test
  syscalls/ipc: Add shmctl07 test
  syscalls/ipc: Add shmctl IPC_SET test
  syscalls/ipc: Rewrite shmctl01

 include/tst_assert.h                          |   9 +
 lib/tst_assert.c                              |  14 +
 runtest/syscalls                              |   2 +
 runtest/syscalls-ipc                          |   2 +
 .../kernel/syscalls/ipc/shmctl/.gitignore     |   2 +
 testcases/kernel/syscalls/ipc/shmctl/Makefile |   3 +-
 .../kernel/syscalls/ipc/shmctl/shmctl01.c     | 586 ++++++------------
 .../kernel/syscalls/ipc/shmctl/shmctl02.c     | 263 +++-----
 .../kernel/syscalls/ipc/shmctl/shmctl03.c     | 214 +------
 .../kernel/syscalls/ipc/shmctl/shmctl04.c     | 190 +++---
 .../kernel/syscalls/ipc/shmctl/shmctl07.c     |  66 ++
 .../kernel/syscalls/ipc/shmctl/shmctl08.c     | 101 +++
 12 files changed, 593 insertions(+), 859 deletions(-)
 create mode 100644 testcases/kernel/syscalls/ipc/shmctl/shmctl07.c
 create mode 100644 testcases/kernel/syscalls/ipc/shmctl/shmctl08.c

-- 
2.26.2


^ permalink raw reply	[flat|nested] 24+ messages in thread

* [LTP] [PATCH 1/9] syscalls/ipc: shmctl02: Convert to the new library
  2020-07-17 16:34 [LTP] [PATCH 0/9] Rewrite shmctl() testcases Cyril Hrubis
@ 2020-07-17 16:34 ` Cyril Hrubis
  2020-07-19  2:51   ` Li Wang
  2020-07-21 14:32   ` Martin Doucha
  2020-07-17 16:34 ` [LTP] [PATCH 2/9] syscalls/ipc: shmctl03: Remove Cyril Hrubis
                   ` (8 subsequent siblings)
  9 siblings, 2 replies; 24+ messages in thread
From: Cyril Hrubis @ 2020-07-17 16:34 UTC (permalink / raw)
  To: ltp

Signed-off-by: Cyril Hrubis <chrubis@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 0172bb495..bc5bd7c2e 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: LDLIBS += -lltpipc
-shmctl06: LDLIBS += -lltpnewipc
+shmctl01 shmctl03 shmctl04 shmctl05: LDLIBS += -lltpipc
+shmctl02 shmctl06: LDLIBS += -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..7b05325ee 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
+ * * EPERM - attempt to stat root owned shm
+ * * EPERM - attempt 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, "msgctl(%i, %i, %p)",
+		        *tc[i].shm_id, tc[i].cmd, tc[i].buf);
+		return;
+	}
 
-	tst_exit();
+	tst_res(TFAIL | TTERRNO, "msgctl(%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] 24+ messages in thread

* [LTP] [PATCH 2/9] syscalls/ipc: shmctl03: Remove.
  2020-07-17 16:34 [LTP] [PATCH 0/9] Rewrite shmctl() testcases Cyril Hrubis
  2020-07-17 16:34 ` [LTP] [PATCH 1/9] syscalls/ipc: shmctl02: Convert to the new library Cyril Hrubis
@ 2020-07-17 16:34 ` Cyril Hrubis
  2020-07-17 16:34 ` [LTP] [PATCH 3/9] syscalls/ipc: shmctl04: Rewrite from scratch Cyril Hrubis
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 24+ messages in thread
From: Cyril Hrubis @ 2020-07-17 16:34 UTC (permalink / raw)
  To: ltp

All these cases are now covered by shmctl02.

Signed-off-by: Cyril Hrubis <chrubis@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 819e8d8ee..5ce482dc7 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 c3a35896c..10cb92c7d 100644
--- a/runtest/syscalls-ipc
+++ b/runtest/syscalls-ipc
@@ -53,7 +53,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 bc5bd7c2e..33e102797 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: LDLIBS += -lltpipc
+shmctl01 shmctl04 shmctl05: LDLIBS += -lltpipc
 shmctl02 shmctl06: LDLIBS += -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] 24+ messages in thread

* [LTP] [PATCH 3/9] syscalls/ipc: shmctl04: Rewrite from scratch.
  2020-07-17 16:34 [LTP] [PATCH 0/9] Rewrite shmctl() testcases Cyril Hrubis
  2020-07-17 16:34 ` [LTP] [PATCH 1/9] syscalls/ipc: shmctl02: Convert to the new library Cyril Hrubis
  2020-07-17 16:34 ` [LTP] [PATCH 2/9] syscalls/ipc: shmctl03: Remove Cyril Hrubis
@ 2020-07-17 16:34 ` Cyril Hrubis
  2020-07-19  7:48   ` Li Wang
  2020-07-28  9:16   ` Petr Vorel
  2020-07-17 16:34 ` [LTP] [PATCH 4/9] syscalls/ipc: shmctl05 remove lib dependency Cyril Hrubis
                   ` (6 subsequent siblings)
  9 siblings, 2 replies; 24+ messages in thread
From: Cyril Hrubis @ 2020-07-17 16:34 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     | 190 ++++++++++--------
 2 files changed, 109 insertions(+), 85 deletions(-)

diff --git a/testcases/kernel/syscalls/ipc/shmctl/Makefile b/testcases/kernel/syscalls/ipc/shmctl/Makefile
index 33e102797..30bb1a537 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: LDLIBS += -lltpipc
-shmctl02 shmctl06: LDLIBS += -lltpnewipc
+shmctl01 shmctl05: LDLIBS += -lltpipc
+shmctl02 shmctl04 shmctl06: LDLIBS += -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..bbcfd75f0 100644
--- a/testcases/kernel/syscalls/ipc/shmctl/shmctl04.c
+++ b/testcases/kernel/syscalls/ipc/shmctl/shmctl04.c
@@ -1,115 +1,139 @@
+// 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
- *
- * DESCRIPTION
- *	shmctl04 - test the SHM_INFO command
- *		   they are used with shmctl() in ipcs
+ * Call shmctl() with SHM_INFO flag and check that:
  *
- * 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.
+ * * The returned index points to a valid SHM by calling SHM_STAT_ANY
+ * * And the data are consistent with /proc/sysvipc/shm
  *
- * HISTORY
- *	09/2002 - Written by Mingming Cao
+ * 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.
  *
- * 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"
+#define _GNU_SOURCE
+#include <stdio.h>
+#include "tst_test.h"
+#include "tst_safe_sysv_ipc.h"
+#include "libnewipc.h"
 
-char *TCID = "shmctl04";
-int TST_TOTAL = 1;
+#define SHM_SIZE 2048
 
-struct shm_info shm_info;
-int max_ids;
-
-/*
- * 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 max_id)
 {
-	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();
+	if (max_id != shmid_max) {
+		tst_res(TFAIL, "highest shmid = %i, expected %i",
+		        max_id, shmid_max);
+	} else {
+		tst_res(TPASS, "highest shmid = %i", max_id);
+	}
 }
 
-/*
- * 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;
 
-	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();
+	TEST(shmctl(TST_RET, SHM_STAT_ANY, &ds));
 
+	if (TST_RET == -1)
+		tst_res(TFAIL | TTERRNO, "SHM_INFO haven't returned a valid index");
+	else
+		tst_res(TPASS, "SHM_INFO returned valid index %li", TST_RET);
+
+	parse_proc_sysvipc(&info, TST_RET);
 }
 
-/*
- * cleanup() - performs all the ONE TIME cleanup for this test at 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] 24+ messages in thread

* [LTP] [PATCH 4/9] syscalls/ipc: shmctl05 remove lib dependency
  2020-07-17 16:34 [LTP] [PATCH 0/9] Rewrite shmctl() testcases Cyril Hrubis
                   ` (2 preceding siblings ...)
  2020-07-17 16:34 ` [LTP] [PATCH 3/9] syscalls/ipc: shmctl04: Rewrite from scratch Cyril Hrubis
@ 2020-07-17 16:34 ` Cyril Hrubis
  2020-07-17 16:34 ` [LTP] [PATCH 5/9] lib/tst_assert: Add TST_ASSERT_ULONG() Cyril Hrubis
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 24+ messages in thread
From: Cyril Hrubis @ 2020-07-17 16:34 UTC (permalink / raw)
  To: ltp

The shmctl05 does not need any SHM library.

Signed-off-by: Cyril Hrubis <chrubis@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 30bb1a537..a004084ad 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: LDLIBS += -lltpipc
+shmctl01: LDLIBS += -lltpipc
 shmctl02 shmctl04 shmctl06: LDLIBS += -lltpnewipc
 
 include $(top_srcdir)/include/mk/generic_leaf_target.mk
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [LTP] [PATCH 5/9] lib/tst_assert: Add TST_ASSERT_ULONG()
  2020-07-17 16:34 [LTP] [PATCH 0/9] Rewrite shmctl() testcases Cyril Hrubis
                   ` (3 preceding siblings ...)
  2020-07-17 16:34 ` [LTP] [PATCH 4/9] syscalls/ipc: shmctl05 remove lib dependency Cyril Hrubis
@ 2020-07-17 16:34 ` Cyril Hrubis
  2020-07-17 16:34 ` [LTP] [PATCH 6/9] syscalls/ipc: Add shmctl() IPC_INFO test Cyril Hrubis
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 24+ messages in thread
From: Cyril Hrubis @ 2020-07-17 16:34 UTC (permalink / raw)
  To: ltp

Signed-off-by: Cyril Hrubis <chrubis@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] 24+ messages in thread

* [LTP] [PATCH 6/9] syscalls/ipc: Add shmctl() IPC_INFO test
  2020-07-17 16:34 [LTP] [PATCH 0/9] Rewrite shmctl() testcases Cyril Hrubis
                   ` (4 preceding siblings ...)
  2020-07-17 16:34 ` [LTP] [PATCH 5/9] lib/tst_assert: Add TST_ASSERT_ULONG() Cyril Hrubis
@ 2020-07-17 16:34 ` Cyril Hrubis
  2020-07-19  9:36   ` Li Wang
  2020-07-21 16:03   ` Martin Doucha
  2020-07-17 16:34 ` [LTP] [PATCH 7/9] syscalls/ipc: Add shmctl07 test Cyril Hrubis
                   ` (3 subsequent siblings)
  9 siblings, 2 replies; 24+ messages in thread
From: Cyril Hrubis @ 2020-07-17 16:34 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     | 38 +++++++++++++++++++
 4 files changed, 41 insertions(+)
 create mode 100644 testcases/kernel/syscalls/ipc/shmctl/shmctl03.c

diff --git a/runtest/syscalls b/runtest/syscalls
index 5ce482dc7..819e8d8ee 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 10cb92c7d..c3a35896c 100644
--- a/runtest/syscalls-ipc
+++ b/runtest/syscalls-ipc
@@ -53,6 +53,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..7df8c12ce
--- /dev/null
+++ b/testcases/kernel/syscalls/ipc/shmctl/shmctl03.c
@@ -0,0 +1,38 @@
+// 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 == -1) {
+		tst_res(TFAIL | TTERRNO, "shmctl(0, IPC_INFO, ...)");
+		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] 24+ messages in thread

* [LTP] [PATCH 7/9] syscalls/ipc: Add shmctl07 test
  2020-07-17 16:34 [LTP] [PATCH 0/9] Rewrite shmctl() testcases Cyril Hrubis
                   ` (5 preceding siblings ...)
  2020-07-17 16:34 ` [LTP] [PATCH 6/9] syscalls/ipc: Add shmctl() IPC_INFO test Cyril Hrubis
@ 2020-07-17 16:34 ` Cyril Hrubis
  2020-07-19  9:50   ` Li Wang
  2020-07-17 16:34 ` [LTP] [PATCH 8/9] syscalls/ipc: Add shmctl IPC_SET test Cyril Hrubis
                   ` (2 subsequent siblings)
  9 siblings, 1 reply; 24+ messages in thread
From: Cyril Hrubis @ 2020-07-17 16:34 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 819e8d8ee..1dc4973e7 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 c3a35896c..613987589 100644
--- a/runtest/syscalls-ipc
+++ b/runtest/syscalls-ipc
@@ -57,6 +57,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] 24+ messages in thread

* [LTP] [PATCH 8/9] syscalls/ipc: Add shmctl IPC_SET test
  2020-07-17 16:34 [LTP] [PATCH 0/9] Rewrite shmctl() testcases Cyril Hrubis
                   ` (6 preceding siblings ...)
  2020-07-17 16:34 ` [LTP] [PATCH 7/9] syscalls/ipc: Add shmctl07 test Cyril Hrubis
@ 2020-07-17 16:34 ` Cyril Hrubis
  2020-07-20  2:26   ` Li Wang
  2020-07-22 10:35   ` Martin Doucha
  2020-07-17 16:34 ` [LTP] [PATCH 9/9] syscalls/ipc: Rewrite shmctl01 Cyril Hrubis
  2020-07-20  7:14 ` [LTP] [PATCH 0/9] Rewrite shmctl() testcases Yang Xu
  9 siblings, 2 replies; 24+ messages in thread
From: Cyril Hrubis @ 2020-07-17 16:34 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/shmctl08.c     | 101 ++++++++++++++++++
 4 files changed, 104 insertions(+)
 create mode 100644 testcases/kernel/syscalls/ipc/shmctl/shmctl08.c

diff --git a/runtest/syscalls b/runtest/syscalls
index 1dc4973e7..00c8d6d66 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 613987589..d3d477741 100644
--- a/runtest/syscalls-ipc
+++ b/runtest/syscalls-ipc
@@ -58,6 +58,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/shmctl08.c b/testcases/kernel/syscalls/ipc/shmctl/shmctl08.c
new file mode 100644
index 000000000..2c83e9901
--- /dev/null
+++ b/testcases/kernel/syscalls/ipc/shmctl/shmctl08.c
@@ -0,0 +1,101 @@
+// 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=%i})",
+		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=%i was updated", exp_mode);
+		return;
+	}
+
+	tst_res(TFAIL, "shm_perm.mode=%i wasn't updated, 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;
+
+	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 > 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] 24+ messages in thread

* [LTP] [PATCH 9/9] syscalls/ipc: Rewrite shmctl01
  2020-07-17 16:34 [LTP] [PATCH 0/9] Rewrite shmctl() testcases Cyril Hrubis
                   ` (7 preceding siblings ...)
  2020-07-17 16:34 ` [LTP] [PATCH 8/9] syscalls/ipc: Add shmctl IPC_SET test Cyril Hrubis
@ 2020-07-17 16:34 ` Cyril Hrubis
  2020-07-22 14:50   ` Martin Doucha
  2020-07-20  7:14 ` [LTP] [PATCH 0/9] Rewrite shmctl() testcases Yang Xu
  9 siblings, 1 reply; 24+ messages in thread
From: Cyril Hrubis @ 2020-07-17 16:34 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>
---
 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 a004084ad..64d76112a 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: LDLIBS += -lltpipc
 shmctl02 shmctl04 shmctl06: LDLIBS += -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] 24+ messages in thread

* [LTP] [PATCH 1/9] syscalls/ipc: shmctl02: Convert to the new library
  2020-07-17 16:34 ` [LTP] [PATCH 1/9] syscalls/ipc: shmctl02: Convert to the new library Cyril Hrubis
@ 2020-07-19  2:51   ` Li Wang
  2020-07-21 14:32   ` Martin Doucha
  1 sibling, 0 replies; 24+ messages in thread
From: Li Wang @ 2020-07-19  2:51 UTC (permalink / raw)
  To: ltp

Hi Cyril,

This patch looks quite good except for some typos.
(Test get passed on both RHEL8(x86_64) and RHEL7(ppc64))

On Sat, Jul 18, 2020 at 12:34 AM Cyril Hrubis <chrubis@suse.cz> wrote:

> Signed-off-by: Cyril Hrubis <chrubis@suse.cz>
>

Reviewed-by: Li Wang <liwang@redhat.com>


> ---
>  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 0172bb495..bc5bd7c2e 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: LDLIBS += -lltpipc
> -shmctl06: LDLIBS += -lltpnewipc
> +shmctl01 shmctl03 shmctl04 shmctl05: LDLIBS += -lltpipc
> +shmctl02 shmctl06: LDLIBS += -lltpnewipc
>
> ...
> + * * 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
> + * * EPERM - attempt to stat root owned shm
>

^ EACCES

> + * * EPERM - attempt 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
>   */
>
> ...
>
> -       cleanup();
> +       if (TST_ERR == tc[i].error) {
> +               tst_res(TPASS | TTERRNO, "msgctl(%i, %i, %p)",
>

Here should be shmctl() but not msgctl().


> +                       *tc[i].shm_id, tc[i].cmd, tc[i].buf);
> +               return;
> +       }
>
> -       tst_exit();
> +       tst_res(TFAIL | TTERRNO, "msgctl(%i, %i, %p) expected %s",
>

msgctl -- > shmctl().

-- 
Regards,
Li Wang
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.linux.it/pipermail/ltp/attachments/20200719/be70d645/attachment.htm>

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [LTP] [PATCH 3/9] syscalls/ipc: shmctl04: Rewrite from scratch.
  2020-07-17 16:34 ` [LTP] [PATCH 3/9] syscalls/ipc: shmctl04: Rewrite from scratch Cyril Hrubis
@ 2020-07-19  7:48   ` Li Wang
  2020-09-07 11:16     ` Cyril Hrubis
  2020-07-28  9:16   ` Petr Vorel
  1 sibling, 1 reply; 24+ messages in thread
From: Li Wang @ 2020-07-19  7:48 UTC (permalink / raw)
  To: ltp

On Sat, Jul 18, 2020 at 12:35 AM Cyril Hrubis <chrubis@suse.cz> wrote:

> ...
> +       /*
> +        * 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;
> +       }
>
> ...
>
> -       tst_exit();
> +       if (max_id != shmid_max) {
> +               tst_res(TFAIL, "highest shmid = %i, expected %i",
> +                       max_id, shmid_max);
>

It failed many times on my personal laptop (5.4.19-100.fc30.x86_64).

$ cat /proc/sysvipc/shm
       key      shmid   perms        size      cpid    lpid    nattch   uid
  gid    cuid    cgid      atime         dtime              ctime
     rss        swap
         0          6         1600      524288   2778   5447      2     1000
 1000  1000  1000 1595120306 1595120306 1595119412      4096        0
         0          8         1600      524288   1903   2043      2     1000
 1000  1000  1000 1595119515     0                 1595119515     24576
   0

$ ./shmctl04
tst_test.c:1245: INFO: Timeout per run is 0h 05m 00s
shmctl04.c:119: PASS: SHM_INFO returned valid index 8
shmctl04.c:70: PASS: used_ids = 3
shmctl04.c:77: PASS: shm_rss = 7
shmctl04.c:84: PASS: shm_swp = 0
shmctl04.c:91: PASS: shm_tot = 257
shmctl04.c:95: FAIL: highest shmid = 8, expected 65537

Summary:
passed   5
failed   1
skipped  0
warnings 0

After printing the shm_proc during test running, I guess the 'shmid' is not
listing in number order sometimes which probably caused that failure.

       key      shmid perms                  size  cpid  lpid nattch   uid
  gid  cuid  cgid      atime      dtime      ctime                   rss
               swap
         0      98306   600                  2048 29586     0      0  1000
 1000  1000  1000          0          0 1595144682                     0
                  0
         0          6  1600                524288  2778 26559      2  1000
 1000  1000  1000 1595142041 1595142041 1595119412                  4096
                  0
         0          8  1600                524288  1903  2043      2  1000
 1000  1000  1000 1595119515          0 1595119515                 24576
                  0



> +       } else {
> +               tst_res(TPASS, "highest shmid = %i", max_id);
> +       }
>  }
>
> -/*
> - * 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;
>
> -       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();
> +       TEST(shmctl(TST_RET, SHM_STAT_ANY, &ds));
>

'SHM_STAT_ANY' is introduced since Linux 4.17. We have to confirm the SUT
supporting before we running it.

Also, we'd better define it in "ipcshm.h" to avoid compiling errors with
the old distro.

shmctl04.c: In function 'verify_shminfo':
shmctl04.c:114: error: 'SHM_STAT_ANY' undeclared (first use in this
function)
shmctl04.c:114: error: (Each undeclared identifier is reported only once
shmctl04.c:114: error: for each function it appears in.)

-- 
Regards,
Li Wang
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.linux.it/pipermail/ltp/attachments/20200719/4506f466/attachment.htm>

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [LTP] [PATCH 6/9] syscalls/ipc: Add shmctl() IPC_INFO test
  2020-07-17 16:34 ` [LTP] [PATCH 6/9] syscalls/ipc: Add shmctl() IPC_INFO test Cyril Hrubis
@ 2020-07-19  9:36   ` Li Wang
  2020-07-21 16:03   ` Martin Doucha
  1 sibling, 0 replies; 24+ messages in thread
From: Li Wang @ 2020-07-19  9:36 UTC (permalink / raw)
  To: ltp

For patches 2/4/5/6:
  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/20200719/63958bb9/attachment-0001.htm>

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [LTP] [PATCH 7/9] syscalls/ipc: Add shmctl07 test
  2020-07-17 16:34 ` [LTP] [PATCH 7/9] syscalls/ipc: Add shmctl07 test Cyril Hrubis
@ 2020-07-19  9:50   ` Li Wang
  2020-09-07 14:45     ` Cyril Hrubis
  0 siblings, 1 reply; 24+ messages in thread
From: Li Wang @ 2020-07-19  9:50 UTC (permalink / raw)
  To: ltp

On Sat, Jul 18, 2020 at 12:35 AM Cyril Hrubis <chrubis@suse.cz> wrote:

> ...
> +
> +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);
> +
>

Shouldn't we do update 'ds' before checking the ds.shm_perm.mode?

--- a/testcases/kernel/syscalls/ipc/shmctl/shmctl07.c
+++ b/testcases/kernel/syscalls/ipc/shmctl/shmctl07.c
@@ -42,10 +42,11 @@ 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");
 }



> +       if (ds.shm_perm.mode & SHM_LOCKED)
> +               tst_res(TPASS, "SHM_LOCKED bit is off in shm_perm.mode");
>

And in this branch, the status should be "on" but not "off".



> +       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
>
>
> --
> Mailing list info: https://lists.linux.it/listinfo/ltp
>
>

-- 
Regards,
Li Wang
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.linux.it/pipermail/ltp/attachments/20200719/7f32d3a4/attachment.htm>

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [LTP] [PATCH 8/9] syscalls/ipc: Add shmctl IPC_SET test
  2020-07-17 16:34 ` [LTP] [PATCH 8/9] syscalls/ipc: Add shmctl IPC_SET test Cyril Hrubis
@ 2020-07-20  2:26   ` Li Wang
  2020-09-07 14:47     ` Cyril Hrubis
  2020-07-22 10:35   ` Martin Doucha
  1 sibling, 1 reply; 24+ messages in thread
From: Li Wang @ 2020-07-20  2:26 UTC (permalink / raw)
  To: ltp

On Sat, Jul 18, 2020 at 12:36 AM Cyril Hrubis <chrubis@suse.cz> wrote:

> ...
> +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;
> +
> +       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 > 10) {
>

Maybe we also need to consider a situation that timestamp is just as
previous value?
i.e.
    if (ds.shm_ctime - old_ctime > 10 || ds.shm_ctime - old_ctime == 0)

> +               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));
> +       }
> +
>


-- 
Regards,
Li Wang
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.linux.it/pipermail/ltp/attachments/20200720/3ac9f733/attachment.htm>

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [LTP] [PATCH 0/9] Rewrite shmctl() testcases
  2020-07-17 16:34 [LTP] [PATCH 0/9] Rewrite shmctl() testcases Cyril Hrubis
                   ` (8 preceding siblings ...)
  2020-07-17 16:34 ` [LTP] [PATCH 9/9] syscalls/ipc: Rewrite shmctl01 Cyril Hrubis
@ 2020-07-20  7:14 ` Yang Xu
  9 siblings, 0 replies; 24+ messages in thread
From: Yang Xu @ 2020-07-20  7:14 UTC (permalink / raw)
  To: ltp

Hi Cyril


> This patchset mostly rewrites old shmctl testcases from scratch and also
> increases the coverage at least threefold.
> 
> There are still missing pieces though, there are no test that would
> check that shm_atime and shm_dtime are valid as well as shm_lpid as well
> as the coverage of ipc_perm is still lacking and should be added later
> on.
It seems that we miss shm_next_id. Also for msg_next_id, sem_next_id in ltp.
> 
> Cyril Hrubis (9):
>    syscalls/ipc: shmctl02: Convert to the new library
>    syscalls/ipc: shmctl03: Remove.
>    syscalls/ipc: shmctl04: Rewrite from scratch.
>    syscalls/ipc: shmctl05 remove lib dependency
>    lib/tst_assert: Add TST_ASSERT_ULONG()
>    syscalls/ipc: Add shmctl() IPC_INFO test
>    syscalls/ipc: Add shmctl07 test
>    syscalls/ipc: Add shmctl IPC_SET test
>    syscalls/ipc: Rewrite shmctl01
> 
>   include/tst_assert.h                          |   9 +
>   lib/tst_assert.c                              |  14 +
>   runtest/syscalls                              |   2 +
>   runtest/syscalls-ipc                          |   2 +
>   .../kernel/syscalls/ipc/shmctl/.gitignore     |   2 +
>   testcases/kernel/syscalls/ipc/shmctl/Makefile |   3 +-
>   .../kernel/syscalls/ipc/shmctl/shmctl01.c     | 586 ++++++------------
>   .../kernel/syscalls/ipc/shmctl/shmctl02.c     | 263 +++-----
>   .../kernel/syscalls/ipc/shmctl/shmctl03.c     | 214 +------
>   .../kernel/syscalls/ipc/shmctl/shmctl04.c     | 190 +++---
>   .../kernel/syscalls/ipc/shmctl/shmctl07.c     |  66 ++
>   .../kernel/syscalls/ipc/shmctl/shmctl08.c     | 101 +++
>   12 files changed, 593 insertions(+), 859 deletions(-)
>   create mode 100644 testcases/kernel/syscalls/ipc/shmctl/shmctl07.c
>   create mode 100644 testcases/kernel/syscalls/ipc/shmctl/shmctl08.c
> 



^ permalink raw reply	[flat|nested] 24+ messages in thread

* [LTP] [PATCH 1/9] syscalls/ipc: shmctl02: Convert to the new library
  2020-07-17 16:34 ` [LTP] [PATCH 1/9] syscalls/ipc: shmctl02: Convert to the new library Cyril Hrubis
  2020-07-19  2:51   ` Li Wang
@ 2020-07-21 14:32   ` Martin Doucha
  1 sibling, 0 replies; 24+ messages in thread
From: Martin Doucha @ 2020-07-21 14:32 UTC (permalink / raw)
  To: ltp

Hello,
Li Wang already suggested the most important fixes so I'll just add two
more typos on top. Otherwise it looks good.

On 17. 07. 20 18:34, Cyril Hrubis wrote:
> Signed-off-by: Cyril Hrubis <chrubis@suse.cz>

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/shmctl02.c b/testcases/kernel/syscalls/ipc/shmctl/shmctl02.c
> index 0b97bb240..7b05325ee 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
>  /*
> ...
>   *
> - *      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
> + * * EPERM - attempt to stat root owned shm

^ "root-owned" is missing a dash throughout this file

> + * * EPERM - attempt delete root owned shm

^ attempt *TO* delete ...

> + * * 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>
>  
> ...
> +} 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 */

^ Last instance of "root-owned" without a dash

-- 
Martin Doucha   mdoucha@suse.cz
QA Engineer for Software Maintenance
SUSE LINUX, s.r.o.
CORSO IIa
Krizikova 148/34
186 00 Prague 8
Czech Republic

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [LTP] [PATCH 6/9] syscalls/ipc: Add shmctl() IPC_INFO test
  2020-07-17 16:34 ` [LTP] [PATCH 6/9] syscalls/ipc: Add shmctl() IPC_INFO test Cyril Hrubis
  2020-07-19  9:36   ` Li Wang
@ 2020-07-21 16:03   ` Martin Doucha
  1 sibling, 0 replies; 24+ messages in thread
From: Martin Doucha @ 2020-07-21 16:03 UTC (permalink / raw)
  To: ltp

Hello,
for patches 2, 4 and 5:
Reviewed-by: Martin Doucha <mdoucha@suse.cz>

Patch 3 needs a test scenario redesign as reported by Li Wang.

In this patch, you should also check for other negative return values
from shmctl() besides -1.

On 17. 07. 20 18:34, Cyril Hrubis wrote:
> 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     | 38 +++++++++++++++++++
>  4 files changed, 41 insertions(+)
>  create mode 100644 testcases/kernel/syscalls/ipc/shmctl/shmctl03.c
> 
> diff --git a/runtest/syscalls b/runtest/syscalls
> index 5ce482dc7..819e8d8ee 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 10cb92c7d..c3a35896c 100644
> --- a/runtest/syscalls-ipc
> +++ b/runtest/syscalls-ipc
> @@ -53,6 +53,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..7df8c12ce
> --- /dev/null
> +++ b/testcases/kernel/syscalls/ipc/shmctl/shmctl03.c
> @@ -0,0 +1,38 @@
> +// 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 == -1) {
> +		tst_res(TFAIL | TTERRNO, "shmctl(0, IPC_INFO, ...)");
> +		return;
> +	}
> +

if (TST_RET < 0)
	tst_res(TFAIL...)

> +	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,
> +};
> 


-- 
Martin Doucha   mdoucha@suse.cz
QA Engineer for Software Maintenance
SUSE LINUX, s.r.o.
CORSO IIa
Krizikova 148/34
186 00 Prague 8
Czech Republic

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [LTP] [PATCH 8/9] syscalls/ipc: Add shmctl IPC_SET test
  2020-07-17 16:34 ` [LTP] [PATCH 8/9] syscalls/ipc: Add shmctl IPC_SET test Cyril Hrubis
  2020-07-20  2:26   ` Li Wang
@ 2020-07-22 10:35   ` Martin Doucha
  1 sibling, 0 replies; 24+ messages in thread
From: Martin Doucha @ 2020-07-22 10:35 UTC (permalink / raw)
  To: ltp

Hi,
I'm skipping patch 7 because Li Wang already reported the missing
shmctl(IPC_STAT) before the (flipped) final check for SHM_LOCKED flag.

Here, Li Wang already reported the issue with ctime check so I'll just
add two minor suggestions for improvement.

On 17. 07. 20 18:34, Cyril Hrubis wrote:
> 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/shmctl08.c     | 101 ++++++++++++++++++
>  4 files changed, 104 insertions(+)
>  create mode 100644 testcases/kernel/syscalls/ipc/shmctl/shmctl08.c
> 
> diff --git a/runtest/syscalls b/runtest/syscalls
> index 1dc4973e7..00c8d6d66 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 613987589..d3d477741 100644
> --- a/runtest/syscalls-ipc
> +++ b/runtest/syscalls-ipc
> @@ -58,6 +58,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/shmctl08.c b/testcases/kernel/syscalls/ipc/shmctl/shmctl08.c
> new file mode 100644
> index 000000000..2c83e9901
> --- /dev/null
> +++ b/testcases/kernel/syscalls/ipc/shmctl/shmctl08.c
> @@ -0,0 +1,101 @@
> +// 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=%i})",

Formatting mode values with %04o would be better here, also in
check_mode() below.

> +		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=%i was updated", exp_mode);
> +		return;
> +	}
> +
> +	tst_res(TFAIL, "shm_perm.mode=%i wasn't updated, 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;

I'd recommend validating old_mode as well.

> +
> +	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 > 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,
> +};
> 


-- 
Martin Doucha   mdoucha@suse.cz
QA Engineer for Software Maintenance
SUSE LINUX, s.r.o.
CORSO IIa
Krizikova 148/34
186 00 Prague 8
Czech Republic

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [LTP] [PATCH 9/9] syscalls/ipc: Rewrite shmctl01
  2020-07-17 16:34 ` [LTP] [PATCH 9/9] syscalls/ipc: Rewrite shmctl01 Cyril Hrubis
@ 2020-07-22 14:50   ` Martin Doucha
  0 siblings, 0 replies; 24+ messages in thread
From: Martin Doucha @ 2020-07-22 14:50 UTC (permalink / raw)
  To: ltp

Hello,
redesigned test scenario looks good so the only thing blocking merge
here are the bugs in preceding patches.

On 17. 07. 20 18:34, Cyril Hrubis wrote:
> 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 a004084ad..64d76112a 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: LDLIBS += -lltpipc
>  shmctl02 shmctl04 shmctl06: LDLIBS += -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 at 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),
> +};
> 


-- 
Martin Doucha   mdoucha@suse.cz
QA Engineer for Software Maintenance
SUSE LINUX, s.r.o.
CORSO IIa
Krizikova 148/34
186 00 Prague 8
Czech Republic

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [LTP] [PATCH 3/9] syscalls/ipc: shmctl04: Rewrite from scratch.
  2020-07-17 16:34 ` [LTP] [PATCH 3/9] syscalls/ipc: shmctl04: Rewrite from scratch Cyril Hrubis
  2020-07-19  7:48   ` Li Wang
@ 2020-07-28  9:16   ` Petr Vorel
  1 sibling, 0 replies; 24+ messages in thread
From: Petr Vorel @ 2020-07-28  9:16 UTC (permalink / raw)
  To: ltp

Hi Cyril,

> -	/*
> -	 * 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();
> +	TEST(shmctl(TST_RET, SHM_STAT_ANY, &ds));
Several old distros fail [1] as they miss SHM_STAT_ANY in <bits/shm.h> (added to
glibc in 2.28, to kernel in 4.17).
Of course, it's just enough to add the definition to include/tst_safe_sysv_ipc.h
(or some LAPI file).

Kind regards,
Petr

[1] https://travis-ci.org/github/pevik/ltp/builds/712476731

diff --git include/tst_safe_sysv_ipc.h include/tst_safe_sysv_ipc.h
index 3e0e50e8d..dea85f97c 100644
--- include/tst_safe_sysv_ipc.h
+++ include/tst_safe_sysv_ipc.h
@@ -10,6 +10,10 @@
 #include <sys/msg.h>
 #include <sys/shm.h>
 
+#ifndef SHM_STAT_ANY
+# define SHM_STAT_ANY	15
+#endif
+
 int safe_msgget(const char *file, const int lineno, key_t key, int msgflg);
 #define SAFE_MSGGET(key, msgflg) \
 	safe_msgget(__FILE__, __LINE__, (key), (msgflg))

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [LTP] [PATCH 3/9] syscalls/ipc: shmctl04: Rewrite from scratch.
  2020-07-19  7:48   ` Li Wang
@ 2020-09-07 11:16     ` Cyril Hrubis
  0 siblings, 0 replies; 24+ messages in thread
From: Cyril Hrubis @ 2020-09-07 11:16 UTC (permalink / raw)
  To: ltp

Hi!
> It failed many times on my personal laptop (5.4.19-100.fc30.x86_64).
> 
> $ cat /proc/sysvipc/shm
>        key      shmid   perms        size      cpid    lpid    nattch   uid
>   gid    cuid    cgid      atime         dtime              ctime
>      rss        swap
>          0          6         1600      524288   2778   5447      2     1000
>  1000  1000  1000 1595120306 1595120306 1595119412      4096        0
>          0          8         1600      524288   1903   2043      2     1000
>  1000  1000  1000 1595119515     0                 1595119515     24576
>    0
> 
> $ ./shmctl04
> tst_test.c:1245: INFO: Timeout per run is 0h 05m 00s
> shmctl04.c:119: PASS: SHM_INFO returned valid index 8
> shmctl04.c:70: PASS: used_ids = 3
> shmctl04.c:77: PASS: shm_rss = 7
> shmctl04.c:84: PASS: shm_swp = 0
> shmctl04.c:91: PASS: shm_tot = 257
> shmctl04.c:95: FAIL: highest shmid = 8, expected 65537
> 
> Summary:
> passed   5
> failed   1
> skipped  0
> warnings 0
> 
> After printing the shm_proc during test running, I guess the 'shmid' is not
> listing in number order sometimes which probably caused that failure.

Looking at the result closely, I guess that I messed up and got confused
here, the return value from SHM_INFO is highest index into the kernel
array, which is equal to highest shmid only by an accident on a freshly
booted machine. I will fix that part in v2.

> 'SHM_STAT_ANY' is introduced since Linux 4.17. We have to confirm the SUT
> supporting before we running it.
> 
> Also, we'd better define it in "ipcshm.h" to avoid compiling errors with
> the old distro.
> 
> shmctl04.c: In function 'verify_shminfo':
> shmctl04.c:114: error: 'SHM_STAT_ANY' undeclared (first use in this
> function)
> shmctl04.c:114: error: (Each undeclared identifier is reported only once
> shmctl04.c:114: error: for each function it appears in.)

Will fix as well.

-- 
Cyril Hrubis
chrubis@suse.cz

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [LTP] [PATCH 7/9] syscalls/ipc: Add shmctl07 test
  2020-07-19  9:50   ` Li Wang
@ 2020-09-07 14:45     ` Cyril Hrubis
  0 siblings, 0 replies; 24+ messages in thread
From: Cyril Hrubis @ 2020-09-07 14:45 UTC (permalink / raw)
  To: ltp

Hi!
> Shouldn't we do update 'ds' before checking the ds.shm_perm.mode?
> 
> --- a/testcases/kernel/syscalls/ipc/shmctl/shmctl07.c
> +++ b/testcases/kernel/syscalls/ipc/shmctl/shmctl07.c
> @@ -42,10 +42,11 @@ 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");
>  }
> 
> 
> 
> > +       if (ds.shm_perm.mode & SHM_LOCKED)
> > +               tst_res(TPASS, "SHM_LOCKED bit is off in shm_perm.mode");
> >
> 
> And in this branch, the status should be "on" but not "off".

And also TFAIL.

All will be fixed in v2, thx for the review.

-- 
Cyril Hrubis
chrubis@suse.cz

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [LTP] [PATCH 8/9] syscalls/ipc: Add shmctl IPC_SET test
  2020-07-20  2:26   ` Li Wang
@ 2020-09-07 14:47     ` Cyril Hrubis
  0 siblings, 0 replies; 24+ messages in thread
From: Cyril Hrubis @ 2020-09-07 14:47 UTC (permalink / raw)
  To: ltp

Hi!
> Maybe we also need to consider a situation that timestamp is just as
> previous value?
> i.e.
>     if (ds.shm_ctime - old_ctime > 10 || ds.shm_ctime - old_ctime == 0)

I will change that to a range check, I.e. the ds.shm_ctime must be
greater than old_ctime and smaller than old_ctime + 10.

-- 
Cyril Hrubis
chrubis@suse.cz

^ permalink raw reply	[flat|nested] 24+ messages in thread

end of thread, other threads:[~2020-09-07 14:47 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-07-17 16:34 [LTP] [PATCH 0/9] Rewrite shmctl() testcases Cyril Hrubis
2020-07-17 16:34 ` [LTP] [PATCH 1/9] syscalls/ipc: shmctl02: Convert to the new library Cyril Hrubis
2020-07-19  2:51   ` Li Wang
2020-07-21 14:32   ` Martin Doucha
2020-07-17 16:34 ` [LTP] [PATCH 2/9] syscalls/ipc: shmctl03: Remove Cyril Hrubis
2020-07-17 16:34 ` [LTP] [PATCH 3/9] syscalls/ipc: shmctl04: Rewrite from scratch Cyril Hrubis
2020-07-19  7:48   ` Li Wang
2020-09-07 11:16     ` Cyril Hrubis
2020-07-28  9:16   ` Petr Vorel
2020-07-17 16:34 ` [LTP] [PATCH 4/9] syscalls/ipc: shmctl05 remove lib dependency Cyril Hrubis
2020-07-17 16:34 ` [LTP] [PATCH 5/9] lib/tst_assert: Add TST_ASSERT_ULONG() Cyril Hrubis
2020-07-17 16:34 ` [LTP] [PATCH 6/9] syscalls/ipc: Add shmctl() IPC_INFO test Cyril Hrubis
2020-07-19  9:36   ` Li Wang
2020-07-21 16:03   ` Martin Doucha
2020-07-17 16:34 ` [LTP] [PATCH 7/9] syscalls/ipc: Add shmctl07 test Cyril Hrubis
2020-07-19  9:50   ` Li Wang
2020-09-07 14:45     ` Cyril Hrubis
2020-07-17 16:34 ` [LTP] [PATCH 8/9] syscalls/ipc: Add shmctl IPC_SET test Cyril Hrubis
2020-07-20  2:26   ` Li Wang
2020-09-07 14:47     ` Cyril Hrubis
2020-07-22 10:35   ` Martin Doucha
2020-07-17 16:34 ` [LTP] [PATCH 9/9] syscalls/ipc: Rewrite shmctl01 Cyril Hrubis
2020-07-22 14:50   ` Martin Doucha
2020-07-20  7:14 ` [LTP] [PATCH 0/9] Rewrite shmctl() testcases Yang Xu

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.