All of lore.kernel.org
 help / color / mirror / Atom feed
* [LTP] [PATCH 1/2] containers: added mountns/mountns03.c
@ 2014-08-26  9:59 Matus Marhefka
  2014-08-26  9:59 ` [LTP] [PATCH 2/2] containers: added mountns/mountns04.c Matus Marhefka
                   ` (2 more replies)
  0 siblings, 3 replies; 17+ messages in thread
From: Matus Marhefka @ 2014-08-26  9:59 UTC (permalink / raw)
  To: ltp-list

* Tests a slave mount: slave mount is like a shared mount except that
  mount and umount events only propagate towards it

Signed-off-by: Matus Marhefka <mmarhefk@redhat.com>
---
 runtest/containers                              |   1 +
 testcases/kernel/containers/.gitignore          |   1 +
 testcases/kernel/containers/mountns/mountns03.c | 241 ++++++++++++++++++++++++
 3 files changed, 243 insertions(+)
 create mode 100644 testcases/kernel/containers/mountns/mountns03.c

diff --git a/runtest/containers b/runtest/containers
index 56977c0..3653c9c 100644
--- a/runtest/containers
+++ b/runtest/containers
@@ -58,3 +58,4 @@ utstest_clone_5 utstest clone 5
 
 mountns01 mountns01
 mountns02 mountns02
+mountns03 mountns03
diff --git a/testcases/kernel/containers/.gitignore b/testcases/kernel/containers/.gitignore
index f175296..5b96cb9 100644
--- a/testcases/kernel/containers/.gitignore
+++ b/testcases/kernel/containers/.gitignore
@@ -1,3 +1,4 @@
 /check_for_unshare
 mountns/mountns01
 mountns/mountns02
+mountns/mountns03
diff --git a/testcases/kernel/containers/mountns/mountns03.c b/testcases/kernel/containers/mountns/mountns03.c
new file mode 100644
index 0000000..330d83e
--- /dev/null
+++ b/testcases/kernel/containers/mountns/mountns03.c
@@ -0,0 +1,241 @@
+/* Copyright (c) 2014 Red Hat, Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of version 2 the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ ***********************************************************************
+ * File: mountns03.c
+ *
+ * Tests a slave mount: slave mount is like a shared mount except that
+ * mount and umount events only propagate towards it.
+ * Description:
+ * 1. Creates directories "A", "B", "C", "D" and files "A/A", "B/B"
+ *    "C/C", "D/D"
+ * 2. Unshares mount namespace and makes it private (so mounts/umounts
+ *    have no effect on a real system)
+ * 3. Bind mounts directory "A" to "A" and "B" to "B"
+ * 4. Makes both directories ("A" and "B") shared
+ * 5. Clones a new child process with CLONE_NEWNS flag - the new child
+ *    then:
+ *    a) bind mounts directory "A" to directory "B"
+ *    b) makes mount "B" a slave of "A"
+ *    c) bind mounts directory "C" to "A"
+ *    d) checks that mount in c) propagated also to direcoty "B" (as "B"
+ *       is a slave of "A"):
+ *       - if it does, test #1 passes
+ *       - if it doesn't, test #1 fails
+ *    e) bind mounts direcory "D" to "B"
+ *    f) waits for parent approval to terminate
+ * 6. Parent checks if directory "A" doesn't contain the file "D"
+ *    (as slave mount ("B") doesn't forward propagation (to "A")):
+ *    - if it doesn't, test #2 passes
+ *    - if it does, test #2 fails
+ * 7. Parent allows child to terminate
+ ***********************************************************************/
+
+#define _GNU_SOURCE
+#include <sys/wait.h>
+#include <sys/mount.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <errno.h>
+#include "test.h"
+#include "usctest.h"
+#include "libclone.h"
+#include "safe_macros.h"
+#include "safe_file_ops.h"
+#include "mountns_helper.h"
+
+
+#define DIRA "A"
+#define DIRB "B"
+#define DIRC "C"
+#define DIRD "D"
+char *TCID	= "mountns03";
+int TST_TOTAL	= 2;
+int pipefd1[2];
+int pipefd2[2];
+
+
+static void cleanup(void)
+{
+	close(pipefd1[0]);
+	close(pipefd1[1]);
+	close(pipefd2[0]);
+	close(pipefd2[1]);
+	umount(DIRA);
+	umount(DIRB);
+	tst_rmdir();
+}
+
+static void setup(void)
+{
+	tst_require_root(NULL);
+	check_newns();	/* from mountns_helper.h */
+
+	/* checks if following mountflags are defined */
+	#if !defined(MS_SHARED) || !defined(MS_PRIVATE) \
+	    || !defined(MS_REC) || !defined(MS_SLAVE)
+		tst_brkm(TCONF, NULL, "needed mountflags are not defined");
+	#endif
+
+	tst_tmpdir();
+	SAFE_MKDIR(cleanup, DIRA, 0777);
+	SAFE_MKDIR(cleanup, DIRB, 0777);
+	SAFE_MKDIR(cleanup, DIRC, 0777);
+	SAFE_MKDIR(cleanup, DIRD, 0777);
+	SAFE_TOUCH(cleanup, DIRA"/A", 0, NULL);
+	SAFE_TOUCH(cleanup, DIRB"/B", 0, NULL);
+	SAFE_TOUCH(cleanup, DIRC"/C", 0, NULL);
+	SAFE_TOUCH(cleanup, DIRD"/D", 0, NULL);
+}
+
+int child_func(void *arg)
+{
+	char buf;
+
+	/* bind mounts DIRA to DIRB making contents of DIRA visible
+	 * in DIRB */
+	if (mount(DIRA, DIRB, "none", MS_BIND, NULL) == -1) {
+		perror("mount");
+		write(pipefd1[1], "1", 1);
+		return 1;
+	}
+
+	/* makes mount DIRB a slave of DIRA (all slave mounts have
+	 * a master mount which is a shared mount. */
+	if (mount("none", DIRB, "none", MS_SLAVE, NULL) == -1) {
+		perror("mount");
+		umount(DIRB);
+		write(pipefd1[1], "1", 1);
+		return 1;
+	}
+
+	/* bind mounts DIRC to DIRA making contents of DIRC visible
+	 * in DIRA */
+	if (mount(DIRC, DIRA, "none", MS_BIND, NULL) == -1) {
+		perror("mount");
+		umount(DIRB);
+		write(pipefd1[1], "1", 1);
+		return 1;
+	}
+
+	/* as DIRB is a slave of DIRA, previous mount (DIRC to DIRA)
+	 * should be also propageted into DIRB */
+	if (access(DIRB"/C", F_OK) != -1)
+		tst_resm(TPASS, "propagation to slave mount passed");
+	else
+		tst_resm(TFAIL, "propagation to slave mount failed");
+
+	/* bind mounts DIRD to DIRB making contents of DIRD visible
+	 * in DIRB (should not propagate to DIRA as DIRB is its slave) */
+	if (mount(DIRD, DIRB, "none", MS_BIND, NULL) == -1) {
+		perror("mount");
+		umount(DIRA);
+		umount(DIRB);
+		write(pipefd1[1], "1", 1);
+		return 1;
+	}
+
+	/* tells parent to stop waiting and continue */
+	write(pipefd1[1], "0", 1);
+
+	/* waits for parent approval to terminate */
+	read(pipefd2[0], &buf, 1);
+
+	umount(DIRB);
+	umount(DIRA);
+	umount(DIRB);
+	return 0;
+}
+
+static void test(void)
+{
+	int status, pass;
+	char buf;
+
+	/* creates a pipe for synchronization between parent and child */
+	SAFE_PIPE(cleanup, pipefd1);
+	SAFE_PIPE(cleanup, pipefd2);
+
+	/* unshares the mount ns */
+	if (unshare(CLONE_NEWNS) == -1)
+		tst_brkm(TBROK | TERRNO, cleanup, "unshare failed");
+	/* makes sure parent mounts/umounts have no effect on a real system */
+	SAFE_MOUNT(cleanup, "none", "/", "none", MS_REC|MS_PRIVATE, NULL);
+
+	/* bind mounts DIRA to itself */
+	SAFE_MOUNT(cleanup, DIRA, DIRA, "none", MS_BIND, NULL);
+	/* bind mounts DIRB to itself */
+	SAFE_MOUNT(cleanup, DIRB, DIRB, "none", MS_BIND, NULL);
+
+	/* makes mount DIRA shared */
+	SAFE_MOUNT(cleanup, "none", DIRA, "none", MS_SHARED, NULL);
+	/* makes mount DIRB shared */
+	SAFE_MOUNT(cleanup, "none", DIRB, "none", MS_SHARED, NULL);
+
+	if (do_clone_tests(CLONE_NEWNS, child_func, NULL, NULL, NULL) == -1)
+		tst_brkm(TBROK | TERRNO, cleanup, "clone failed");
+
+	/* waits for child bind mount */
+	SAFE_READ(cleanup, 0, pipefd1[0], &buf, 1);
+
+	/* checks that mount in slave (DIRB) doesn't propagate to shared
+	 * mount (DIRA) */
+	if (access(DIRA"/D", F_OK) == -1)
+		pass = 1;
+	else
+		pass = 0;
+
+	/* tells child to terminate (if no error occured in child) */
+	SAFE_WRITE(cleanup, 0, pipefd2[1], "0", 1);
+
+	SAFE_WAIT(cleanup, &status);
+
+	if (WIFEXITED(status) && WEXITSTATUS(status) != 0)
+		tst_brkm(TBROK, cleanup, "child failed");
+
+	if (WIFSIGNALED(status)) {
+		tst_resm(TFAIL, "child was killed with signal %s",
+			 tst_strsig(WTERMSIG(status)));
+		return;
+	}
+
+	close(pipefd1[0]);
+	close(pipefd1[1]);
+	close(pipefd2[0]);
+	close(pipefd2[1]);
+	umount(DIRA);
+	umount(DIRB);
+
+	if (pass)
+		tst_resm(TPASS, "propagation from slave mount passed");
+	else
+		tst_resm(TFAIL, "propagation form slave mount failed");
+}
+
+int main(int argc, char *argv[])
+{
+	const char *msg;
+	int lc;
+
+	msg = parse_opts(argc, argv, NULL, NULL);
+	if (msg != NULL)
+		tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
+
+	setup();
+
+	for (lc = 0; TEST_LOOPING(lc); lc++)
+		test();
+
+	cleanup();
+	tst_exit();
+}
-- 
1.8.3.1


------------------------------------------------------------------------------
Slashdot TV.  
Video for Nerds.  Stuff that matters.
http://tv.slashdot.org/
_______________________________________________
Ltp-list mailing list
Ltp-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ltp-list

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

* [LTP] [PATCH 2/2] containers: added mountns/mountns04.c
  2014-08-26  9:59 [LTP] [PATCH 1/2] containers: added mountns/mountns03.c Matus Marhefka
@ 2014-08-26  9:59 ` Matus Marhefka
  2014-08-29 13:47   ` [LTP] [PATCH 2/2 v2] " Matus Marhefka
  2014-10-02 12:29   ` [LTP] [PATCH 2/2 v3] " Matus Marhefka
  2014-08-29 13:46 ` [LTP] [PATCH 1/2 v2] containers: added mountns/mountns03.c Matus Marhefka
  2014-10-02 12:28 ` [LTP] [PATCH 1/2 v3] " Matus Marhefka
  2 siblings, 2 replies; 17+ messages in thread
From: Matus Marhefka @ 2014-08-26  9:59 UTC (permalink / raw)
  To: ltp-list

* Tests an unbindable mount: unbindable mount is an unbindable
  private mount

Signed-off-by: Matus Marhefka <mmarhefk@redhat.com>
---
 runtest/containers                              |   1 +
 testcases/kernel/containers/.gitignore          |   1 +
 testcases/kernel/containers/mountns/mountns04.c | 120 ++++++++++++++++++++++++
 3 files changed, 122 insertions(+)
 create mode 100644 testcases/kernel/containers/mountns/mountns04.c

diff --git a/runtest/containers b/runtest/containers
index 3653c9c..8e8e067 100644
--- a/runtest/containers
+++ b/runtest/containers
@@ -59,3 +59,4 @@ utstest_clone_5 utstest clone 5
 mountns01 mountns01
 mountns02 mountns02
 mountns03 mountns03
+mountns04 mountns04
diff --git a/testcases/kernel/containers/.gitignore b/testcases/kernel/containers/.gitignore
index 5b96cb9..4a98373 100644
--- a/testcases/kernel/containers/.gitignore
+++ b/testcases/kernel/containers/.gitignore
@@ -2,3 +2,4 @@
 mountns/mountns01
 mountns/mountns02
 mountns/mountns03
+mountns/mountns04
diff --git a/testcases/kernel/containers/mountns/mountns04.c b/testcases/kernel/containers/mountns/mountns04.c
new file mode 100644
index 0000000..470953e
--- /dev/null
+++ b/testcases/kernel/containers/mountns/mountns04.c
@@ -0,0 +1,120 @@
+/* Copyright (c) 2014 Red Hat, Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of version 2 the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ ***********************************************************************
+ * File: mountns04.c
+ *
+ * Tests an unbindable mount: unbindable mount is an unbindable
+ * private mount.
+ * Description:
+ * 1. Creates directories "A", "B" and files "A/A", "B/B"
+ * 2. Unshares mount namespace and makes it private (so mounts/umounts
+ *    have no effect on a real system)
+ * 3. Bind mounts directory "A" to "A" and "B" to "B"
+ * 4. Makes directory "B" shared and directory "A" unbindable
+ * 5. Tries to bind mount unbindable "A" to "B":
+ *    - if it fails, test passes
+ *    - if it passes, test fails
+ ***********************************************************************/
+
+#define _GNU_SOURCE
+#include <sys/wait.h>
+#include <sys/mount.h>
+#include <stdio.h>
+#include <errno.h>
+#include "test.h"
+#include "usctest.h"
+#include "libclone.h"
+#include "safe_macros.h"
+#include "safe_file_ops.h"
+#include "mountns_helper.h"
+
+
+#define DIRA "A"
+#define DIRB "B"
+char *TCID	= "mountns04";
+int TST_TOTAL	= 1;
+
+
+static void cleanup(void)
+{
+	umount(DIRA);
+	umount(DIRB);
+	tst_rmdir();
+}
+
+static void setup(void)
+{
+	tst_require_root(NULL);
+	check_newns();	/* from mountns_helper.h */
+
+	/* checks if following mountflags are defined */
+	#if !defined(MS_SHARED) || !defined(MS_PRIVATE) \
+	    || !defined(MS_REC) || !defined(MS_UNBINDABLE)
+		tst_brkm(TCONF, NULL, "needed mountflags are not defined");
+	#endif
+
+	tst_tmpdir();
+	SAFE_MKDIR(cleanup, DIRA, 0777);
+	SAFE_MKDIR(cleanup, DIRB, 0777);
+	SAFE_TOUCH(cleanup, DIRA"/A", 0, NULL);
+	SAFE_TOUCH(cleanup, DIRB"/B", 0, NULL);
+}
+
+static void test(void)
+{
+	/* unshares the mount ns */
+	if (unshare(CLONE_NEWNS) == -1)
+		tst_brkm(TBROK | TERRNO, cleanup, "unshare failed");
+	/* makes sure mounts/umounts have no effect on a real system */
+	SAFE_MOUNT(cleanup, "none", "/", "none", MS_REC|MS_PRIVATE, NULL);
+
+	/* bind mounts DIRA to itself */
+	SAFE_MOUNT(cleanup, DIRA, DIRA, "none", MS_BIND, NULL);
+	/* bind mounts DIRB to itself */
+	SAFE_MOUNT(cleanup, DIRB, DIRB, "none", MS_BIND, NULL);
+
+	/* makes mount DIRA unbindable */
+	SAFE_MOUNT(cleanup, "none", DIRA, "none", MS_UNBINDABLE, NULL);
+	/* makes mount DIRB shared */
+	SAFE_MOUNT(cleanup, "none", DIRB, "none", MS_SHARED, NULL);
+
+	/* tries to bind mount unbindable DIRA to DIRB which should fail */
+	if (mount(DIRA, DIRB, "none", MS_BIND, NULL) == -1)
+		tst_resm(TPASS, "unbindable mount passed");
+	else {
+		umount(DIRB);
+		tst_resm(TFAIL, "unbindable mount faled");
+	}
+
+	umount(DIRA);
+	umount(DIRB);
+}
+
+int main(int argc, char *argv[])
+{
+	const char *msg;
+	int lc;
+
+	msg = parse_opts(argc, argv, NULL, NULL);
+	if (msg != NULL)
+		tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
+
+	setup();
+
+	for (lc = 0; TEST_LOOPING(lc); lc++)
+		test();
+
+	cleanup();
+	tst_exit();
+}
-- 
1.8.3.1


------------------------------------------------------------------------------
Slashdot TV.  
Video for Nerds.  Stuff that matters.
http://tv.slashdot.org/
_______________________________________________
Ltp-list mailing list
Ltp-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ltp-list

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

* [LTP] [PATCH 1/2 v2] containers: added mountns/mountns03.c
  2014-08-26  9:59 [LTP] [PATCH 1/2] containers: added mountns/mountns03.c Matus Marhefka
  2014-08-26  9:59 ` [LTP] [PATCH 2/2] containers: added mountns/mountns04.c Matus Marhefka
@ 2014-08-29 13:46 ` Matus Marhefka
  2014-09-04 14:13   ` Jan Stancek
  2014-09-24  7:56   ` chrubis
  2014-10-02 12:28 ` [LTP] [PATCH 1/2 v3] " Matus Marhefka
  2 siblings, 2 replies; 17+ messages in thread
From: Matus Marhefka @ 2014-08-29 13:46 UTC (permalink / raw)
  To: ltp-list

* Tests a slave mount: slave mount is like a shared mount except that
  mount and umount events only propagate towards it

Signed-off-by: Matus Marhefka <mmarhefk@redhat.com>
---
 runtest/containers                              |   1 +
 testcases/kernel/containers/.gitignore          |   1 +
 testcases/kernel/containers/mountns/mountns03.c | 245 ++++++++++++++++++++++++
 3 files changed, 247 insertions(+)
 create mode 100644 testcases/kernel/containers/mountns/mountns03.c

diff --git a/runtest/containers b/runtest/containers
index 56977c0..3653c9c 100644
--- a/runtest/containers
+++ b/runtest/containers
@@ -58,3 +58,4 @@ utstest_clone_5 utstest clone 5
 
 mountns01 mountns01
 mountns02 mountns02
+mountns03 mountns03
diff --git a/testcases/kernel/containers/.gitignore b/testcases/kernel/containers/.gitignore
index f175296..5b96cb9 100644
--- a/testcases/kernel/containers/.gitignore
+++ b/testcases/kernel/containers/.gitignore
@@ -1,3 +1,4 @@
 /check_for_unshare
 mountns/mountns01
 mountns/mountns02
+mountns/mountns03
diff --git a/testcases/kernel/containers/mountns/mountns03.c b/testcases/kernel/containers/mountns/mountns03.c
new file mode 100644
index 0000000..acca44c
--- /dev/null
+++ b/testcases/kernel/containers/mountns/mountns03.c
@@ -0,0 +1,245 @@
+/* Copyright (c) 2014 Red Hat, Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of version 2 the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ ***********************************************************************
+ * File: mountns03.c
+ *
+ * Tests a slave mount: slave mount is like a shared mount except that
+ * mount and umount events only propagate towards it.
+ * Description:
+ * 1. Creates directories "A", "B", "C", "D" and files "A/A", "B/B"
+ *    "C/C", "D/D"
+ * 2. Unshares mount namespace and makes it private (so mounts/umounts
+ *    have no effect on a real system)
+ * 3. Bind mounts directory "A" to "A" and "B" to "B"
+ * 4. Makes both directories ("A" and "B") shared
+ * 5. Clones a new child process with CLONE_NEWNS flag - the new child
+ *    then:
+ *    a) bind mounts directory "A" to directory "B"
+ *    b) makes mount "B" a slave of "A"
+ *    c) bind mounts directory "C" to "A"
+ *    d) checks that mount in c) propagated also to direcoty "B" (as "B"
+ *       is a slave of "A"):
+ *       - if it does, test #1 passes
+ *       - if it doesn't, test #1 fails
+ *    e) bind mounts direcory "D" to "B"
+ *    f) waits for parent approval to terminate
+ * 6. Parent checks if directory "A" doesn't contain the file "D"
+ *    (as slave mount ("B") doesn't forward propagation (to "A")):
+ *    - if it doesn't, test #2 passes
+ *    - if it does, test #2 fails
+ * 7. Parent allows child to terminate
+ ***********************************************************************/
+
+#define _GNU_SOURCE
+#include <sys/wait.h>
+#include <sys/mount.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <errno.h>
+#include "test.h"
+#include "usctest.h"
+#include "libclone.h"
+#include "safe_macros.h"
+#include "safe_file_ops.h"
+#include "mountns_helper.h"
+
+
+#define DIRA "A"
+#define DIRB "B"
+#define DIRC "C"
+#define DIRD "D"
+char *TCID	= "mountns03";
+int TST_TOTAL	= 2;
+int pipefd1[2];
+int pipefd2[2];
+
+
+/* checks if following mountflags are defined */
+#if defined(MS_SHARED) && defined(MS_PRIVATE) \
+    && defined(MS_REC) && defined(MS_SLAVE)
+
+static void cleanup(void)
+{
+	close(pipefd1[0]);
+	close(pipefd1[1]);
+	close(pipefd2[0]);
+	close(pipefd2[1]);
+	umount(DIRA);
+	umount(DIRB);
+	tst_rmdir();
+}
+
+static void setup(void)
+{
+	tst_require_root(NULL);
+	check_newns();	/* from mountns_helper.h */
+	tst_tmpdir();
+	SAFE_MKDIR(cleanup, DIRA, 0777);
+	SAFE_MKDIR(cleanup, DIRB, 0777);
+	SAFE_MKDIR(cleanup, DIRC, 0777);
+	SAFE_MKDIR(cleanup, DIRD, 0777);
+	SAFE_TOUCH(cleanup, DIRA"/A", 0, NULL);
+	SAFE_TOUCH(cleanup, DIRB"/B", 0, NULL);
+	SAFE_TOUCH(cleanup, DIRC"/C", 0, NULL);
+	SAFE_TOUCH(cleanup, DIRD"/D", 0, NULL);
+}
+
+int child_func(void *arg)
+{
+	char buf;
+
+	/* bind mounts DIRA to DIRB making contents of DIRA visible
+	 * in DIRB */
+	if (mount(DIRA, DIRB, "none", MS_BIND, NULL) == -1) {
+		perror("mount");
+		write(pipefd1[1], "1", 1);
+		return 1;
+	}
+
+	/* makes mount DIRB a slave of DIRA (all slave mounts have
+	 * a master mount which is a shared mount) */
+	if (mount("none", DIRB, "none", MS_SLAVE, NULL) == -1) {
+		perror("mount");
+		umount(DIRB);
+		write(pipefd1[1], "1", 1);
+		return 1;
+	}
+
+	/* bind mounts DIRC to DIRA making contents of DIRC visible
+	 * in DIRA */
+	if (mount(DIRC, DIRA, "none", MS_BIND, NULL) == -1) {
+		perror("mount");
+		umount(DIRB);
+		write(pipefd1[1], "1", 1);
+		return 1;
+	}
+
+	/* as DIRB is a slave of DIRA, previous mount (DIRC to DIRA)
+	 * should be also propageted into DIRB */
+	if (access(DIRB"/C", F_OK) != -1)
+		tst_resm(TPASS, "propagation to slave mount passed");
+	else
+		tst_resm(TFAIL, "propagation to slave mount failed");
+
+	/* bind mounts DIRD to DIRB making contents of DIRD visible
+	 * in DIRB (should not propagate to DIRA as DIRB is its slave) */
+	if (mount(DIRD, DIRB, "none", MS_BIND, NULL) == -1) {
+		perror("mount");
+		umount(DIRA);
+		umount(DIRB);
+		write(pipefd1[1], "1", 1);
+		return 1;
+	}
+
+	/* tells parent to stop waiting and continue */
+	write(pipefd1[1], "0", 1);
+
+	/* waits for parent approval to terminate */
+	read(pipefd2[0], &buf, 1);
+
+	umount(DIRB);
+	umount(DIRA);
+	umount(DIRB);
+	return 0;
+}
+
+static void test(void)
+{
+	int status, pass;
+	char buf;
+
+	/* creates a pipe for synchronization between parent and child */
+	SAFE_PIPE(cleanup, pipefd1);
+	SAFE_PIPE(cleanup, pipefd2);
+
+	/* unshares the mount ns */
+	if (unshare(CLONE_NEWNS) == -1)
+		tst_brkm(TBROK | TERRNO, cleanup, "unshare failed");
+	/* makes sure parent mounts/umounts have no effect on a real system */
+	SAFE_MOUNT(cleanup, "none", "/", "none", MS_REC|MS_PRIVATE, NULL);
+
+	/* bind mounts DIRA to itself */
+	SAFE_MOUNT(cleanup, DIRA, DIRA, "none", MS_BIND, NULL);
+	/* bind mounts DIRB to itself */
+	SAFE_MOUNT(cleanup, DIRB, DIRB, "none", MS_BIND, NULL);
+
+	/* makes mount DIRA shared */
+	SAFE_MOUNT(cleanup, "none", DIRA, "none", MS_SHARED, NULL);
+	/* makes mount DIRB shared */
+	SAFE_MOUNT(cleanup, "none", DIRB, "none", MS_SHARED, NULL);
+
+	if (do_clone_tests(CLONE_NEWNS, child_func, NULL, NULL, NULL) == -1)
+		tst_brkm(TBROK | TERRNO, cleanup, "clone failed");
+
+	/* waits for child bind mount */
+	SAFE_READ(cleanup, 0, pipefd1[0], &buf, 1);
+
+	/* checks that mount in slave (DIRB) doesn't propagate to shared
+	 * mount (DIRA) */
+	if (access(DIRA"/D", F_OK) == -1)
+		pass = 1;
+	else
+		pass = 0;
+
+	/* tells child to terminate (if no error occured in child) */
+	SAFE_WRITE(cleanup, 0, pipefd2[1], "0", 1);
+
+	SAFE_WAIT(cleanup, &status);
+
+	if (WIFEXITED(status) && WEXITSTATUS(status) != 0)
+		tst_brkm(TBROK, cleanup, "child failed");
+
+	if (WIFSIGNALED(status)) {
+		tst_resm(TFAIL, "child was killed with signal %s",
+			 tst_strsig(WTERMSIG(status)));
+		return;
+	}
+
+	close(pipefd1[0]);
+	close(pipefd1[1]);
+	close(pipefd2[0]);
+	close(pipefd2[1]);
+	SAFE_UMOUNT(cleanup, DIRA);
+	SAFE_UMOUNT(cleanup, DIRB);
+
+	if (pass)
+		tst_resm(TPASS, "propagation from slave mount passed");
+	else
+		tst_resm(TFAIL, "propagation form slave mount failed");
+}
+
+int main(int argc, char *argv[])
+{
+	const char *msg;
+	int lc;
+
+	msg = parse_opts(argc, argv, NULL, NULL);
+	if (msg != NULL)
+		tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
+
+	setup();
+
+	for (lc = 0; TEST_LOOPING(lc); lc++)
+		test();
+
+	cleanup();
+	tst_exit();
+}
+
+#else /* MS_SHARED && MS_PRIVATE && MS_REC && MS_SLAVE */
+int main(void)
+{
+	tst_brkm(TCONF, NULL, "needed mountflags are not defined");
+}
+#endif
-- 
1.8.3.1


------------------------------------------------------------------------------
Slashdot TV.  
Video for Nerds.  Stuff that matters.
http://tv.slashdot.org/
_______________________________________________
Ltp-list mailing list
Ltp-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ltp-list

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

* [LTP] [PATCH 2/2 v2] containers: added mountns/mountns04.c
  2014-08-26  9:59 ` [LTP] [PATCH 2/2] containers: added mountns/mountns04.c Matus Marhefka
@ 2014-08-29 13:47   ` Matus Marhefka
  2014-09-04 14:21     ` Jan Stancek
  2014-09-24  8:14     ` chrubis
  2014-10-02 12:29   ` [LTP] [PATCH 2/2 v3] " Matus Marhefka
  1 sibling, 2 replies; 17+ messages in thread
From: Matus Marhefka @ 2014-08-29 13:47 UTC (permalink / raw)
  To: ltp-list

* Tests an unbindable mount: unbindable mount is an unbindable
  private mount

Signed-off-by: Matus Marhefka <mmarhefk@redhat.com>
---
 runtest/containers                              |   1 +
 testcases/kernel/containers/.gitignore          |   1 +
 testcases/kernel/containers/mountns/mountns04.c | 124 ++++++++++++++++++++++++
 3 files changed, 126 insertions(+)
 create mode 100644 testcases/kernel/containers/mountns/mountns04.c

diff --git a/runtest/containers b/runtest/containers
index 3653c9c..8e8e067 100644
--- a/runtest/containers
+++ b/runtest/containers
@@ -59,3 +59,4 @@ utstest_clone_5 utstest clone 5
 mountns01 mountns01
 mountns02 mountns02
 mountns03 mountns03
+mountns04 mountns04
diff --git a/testcases/kernel/containers/.gitignore b/testcases/kernel/containers/.gitignore
index 5b96cb9..4a98373 100644
--- a/testcases/kernel/containers/.gitignore
+++ b/testcases/kernel/containers/.gitignore
@@ -2,3 +2,4 @@
 mountns/mountns01
 mountns/mountns02
 mountns/mountns03
+mountns/mountns04
diff --git a/testcases/kernel/containers/mountns/mountns04.c b/testcases/kernel/containers/mountns/mountns04.c
new file mode 100644
index 0000000..32ba8c9
--- /dev/null
+++ b/testcases/kernel/containers/mountns/mountns04.c
@@ -0,0 +1,124 @@
+/* Copyright (c) 2014 Red Hat, Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of version 2 the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ ***********************************************************************
+ * File: mountns04.c
+ *
+ * Tests an unbindable mount: unbindable mount is an unbindable
+ * private mount.
+ * Description:
+ * 1. Creates directories "A", "B" and files "A/A", "B/B"
+ * 2. Unshares mount namespace and makes it private (so mounts/umounts
+ *    have no effect on a real system)
+ * 3. Bind mounts directory "A" to "A" and "B" to "B"
+ * 4. Makes directory "B" shared and directory "A" unbindable
+ * 5. Tries to bind mount unbindable "A" to "B":
+ *    - if it fails, test passes
+ *    - if it passes, test fails
+ ***********************************************************************/
+
+#define _GNU_SOURCE
+#include <sys/wait.h>
+#include <sys/mount.h>
+#include <stdio.h>
+#include <errno.h>
+#include "test.h"
+#include "usctest.h"
+#include "libclone.h"
+#include "safe_macros.h"
+#include "safe_file_ops.h"
+#include "mountns_helper.h"
+
+
+#define DIRA "A"
+#define DIRB "B"
+char *TCID	= "mountns04";
+int TST_TOTAL	= 1;
+
+
+/* checks if following mountflags are defined */
+#if defined(MS_SHARED) && defined(MS_PRIVATE) \
+    && defined(MS_REC) && defined(MS_UNBINDABLE)
+
+static void cleanup(void)
+{
+	umount(DIRA);
+	umount(DIRB);
+	tst_rmdir();
+}
+
+static void setup(void)
+{
+	tst_require_root(NULL);
+	check_newns();	/* from mountns_helper.h */
+	tst_tmpdir();
+	SAFE_MKDIR(cleanup, DIRA, 0777);
+	SAFE_MKDIR(cleanup, DIRB, 0777);
+	SAFE_TOUCH(cleanup, DIRA"/A", 0, NULL);
+	SAFE_TOUCH(cleanup, DIRB"/B", 0, NULL);
+}
+
+static void test(void)
+{
+	/* unshares the mount ns */
+	if (unshare(CLONE_NEWNS) == -1)
+		tst_brkm(TBROK | TERRNO, cleanup, "unshare failed");
+	/* makes sure mounts/umounts have no effect on a real system */
+	SAFE_MOUNT(cleanup, "none", "/", "none", MS_REC|MS_PRIVATE, NULL);
+
+	/* bind mounts DIRA to itself */
+	SAFE_MOUNT(cleanup, DIRA, DIRA, "none", MS_BIND, NULL);
+	/* bind mounts DIRB to itself */
+	SAFE_MOUNT(cleanup, DIRB, DIRB, "none", MS_BIND, NULL);
+
+	/* makes mount DIRA unbindable */
+	SAFE_MOUNT(cleanup, "none", DIRA, "none", MS_UNBINDABLE, NULL);
+	/* makes mount DIRB shared */
+	SAFE_MOUNT(cleanup, "none", DIRB, "none", MS_SHARED, NULL);
+
+	/* tries to bind mount unbindable DIRA to DIRB which should fail */
+	if (mount(DIRA, DIRB, "none", MS_BIND, NULL) == -1)
+		tst_resm(TPASS, "unbindable mount passed");
+	else {
+		SAFE_UMOUNT(cleanup, DIRB);
+		tst_resm(TFAIL, "unbindable mount faled");
+	}
+
+	SAFE_UMOUNT(cleanup, DIRA);
+	SAFE_UMOUNT(cleanup, DIRB);
+}
+
+int main(int argc, char *argv[])
+{
+	const char *msg;
+	int lc;
+
+	msg = parse_opts(argc, argv, NULL, NULL);
+	if (msg != NULL)
+		tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
+
+	setup();
+
+	for (lc = 0; TEST_LOOPING(lc); lc++)
+		test();
+
+	cleanup();
+	tst_exit();
+}
+
+#else /* MS_SHARED && MS_PRIVATE && MS_REC && MS_UNBINDABLE */
+int main(void)
+{
+	tst_brkm(TCONF, NULL, "needed mountflags are not defined");
+}
+#endif
-- 
1.8.3.1


------------------------------------------------------------------------------
Slashdot TV.  
Video for Nerds.  Stuff that matters.
http://tv.slashdot.org/
_______________________________________________
Ltp-list mailing list
Ltp-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ltp-list

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

* Re: [LTP] [PATCH 1/2 v2] containers: added mountns/mountns03.c
  2014-08-29 13:46 ` [LTP] [PATCH 1/2 v2] containers: added mountns/mountns03.c Matus Marhefka
@ 2014-09-04 14:13   ` Jan Stancek
  2014-09-11 15:09     ` Jiri Jaburek
  2014-09-24  7:56   ` chrubis
  1 sibling, 1 reply; 17+ messages in thread
From: Jan Stancek @ 2014-09-04 14:13 UTC (permalink / raw)
  To: Matus Marhefka; +Cc: ltp-list





----- Original Message -----
> From: "Matus Marhefka" <mmarhefk@redhat.com>
> To: ltp-list@lists.sourceforge.net
> Sent: Friday, 29 August, 2014 3:46:07 PM
> Subject: [LTP] [PATCH 1/2 v2] containers: added mountns/mountns03.c
> 
> * Tests a slave mount: slave mount is like a shared mount except that
>   mount and umount events only propagate towards it
> 
> Signed-off-by: Matus Marhefka <mmarhefk@redhat.com>
> ---
>  runtest/containers                              |   1 +
>  testcases/kernel/containers/.gitignore          |   1 +
>  testcases/kernel/containers/mountns/mountns03.c | 245
>  ++++++++++++++++++++++++
>  3 files changed, 247 insertions(+)
>  create mode 100644 testcases/kernel/containers/mountns/mountns03.c
> 
> diff --git a/runtest/containers b/runtest/containers
> index 56977c0..3653c9c 100644
> --- a/runtest/containers
> +++ b/runtest/containers
> @@ -58,3 +58,4 @@ utstest_clone_5 utstest clone 5
>  
>  mountns01 mountns01
>  mountns02 mountns02
> +mountns03 mountns03
> diff --git a/testcases/kernel/containers/.gitignore
> b/testcases/kernel/containers/.gitignore
> index f175296..5b96cb9 100644
> --- a/testcases/kernel/containers/.gitignore
> +++ b/testcases/kernel/containers/.gitignore
> @@ -1,3 +1,4 @@
>  /check_for_unshare
>  mountns/mountns01
>  mountns/mountns02
> +mountns/mountns03
> diff --git a/testcases/kernel/containers/mountns/mountns03.c
> b/testcases/kernel/containers/mountns/mountns03.c
> new file mode 100644
> index 0000000..acca44c
> --- /dev/null
> +++ b/testcases/kernel/containers/mountns/mountns03.c
> @@ -0,0 +1,245 @@
> +/* Copyright (c) 2014 Red Hat, Inc.
> + *
> + * This program is free software: you can redistribute it and/or modify
> + * it under the terms of version 2 the GNU General Public License as
> + * published by the Free Software Foundation.
> + *
> + * 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, see <http://www.gnu.org/licenses/>.
> + ***********************************************************************
> + * File: mountns03.c
> + *
> + * Tests a slave mount: slave mount is like a shared mount except that
> + * mount and umount events only propagate towards it.
> + * Description:
> + * 1. Creates directories "A", "B", "C", "D" and files "A/A", "B/B"
> + *    "C/C", "D/D"
> + * 2. Unshares mount namespace and makes it private (so mounts/umounts
> + *    have no effect on a real system)

Hi,

> + * 3. Bind mounts directory "A" to "A" and "B" to "B"

is the "B" to "B" part necessary in this case? First thing child does is
it mounts A to B.

> + * 4. Makes both directories ("A" and "B") shared

related to above, is it necessary to make B shared?

> + * 5. Clones a new child process with CLONE_NEWNS flag - the new child
> + *    then:
> + *    a) bind mounts directory "A" to directory "B"
> + *    b) makes mount "B" a slave of "A"
> + *    c) bind mounts directory "C" to "A"
> + *    d) checks that mount in c) propagated also to direcoty "B" (as "B"
> + *       is a slave of "A"):
> + *       - if it does, test #1 passes
> + *       - if it doesn't, test #1 fails
> + *    e) bind mounts direcory "D" to "B"
> + *    f) waits for parent approval to terminate
> + * 6. Parent checks if directory "A" doesn't contain the file "D"
> + *    (as slave mount ("B") doesn't forward propagation (to "A")):
> + *    - if it doesn't, test #2 passes
> + *    - if it does, test #2 fails
> + * 7. Parent allows child to terminate
> + ***********************************************************************/
> +
> +#define _GNU_SOURCE
> +#include <sys/wait.h>
> +#include <sys/mount.h>
> +#include <stdio.h>
> +#include <unistd.h>
> +#include <errno.h>
> +#include "test.h"
> +#include "usctest.h"
> +#include "libclone.h"
> +#include "safe_macros.h"
> +#include "safe_file_ops.h"
> +#include "mountns_helper.h"
> +
> +
> +#define DIRA "A"
> +#define DIRB "B"
> +#define DIRC "C"
> +#define DIRD "D"
> +char *TCID	= "mountns03";
> +int TST_TOTAL	= 2;
> +int pipefd1[2];
> +int pipefd2[2];
> +
> +
> +/* checks if following mountflags are defined */
> +#if defined(MS_SHARED) && defined(MS_PRIVATE) \
> +    && defined(MS_REC) && defined(MS_SLAVE)
> +
> +static void cleanup(void)
> +{
> +	close(pipefd1[0]);
> +	close(pipefd1[1]);
> +	close(pipefd2[0]);
> +	close(pipefd2[1]);
> +	umount(DIRA);
> +	umount(DIRB);
> +	tst_rmdir();
> +}
> +
> +static void setup(void)
> +{
> +	tst_require_root(NULL);
> +	check_newns();	/* from mountns_helper.h */
> +	tst_tmpdir();
> +	SAFE_MKDIR(cleanup, DIRA, 0777);
> +	SAFE_MKDIR(cleanup, DIRB, 0777);
> +	SAFE_MKDIR(cleanup, DIRC, 0777);
> +	SAFE_MKDIR(cleanup, DIRD, 0777);
> +	SAFE_TOUCH(cleanup, DIRA"/A", 0, NULL);
> +	SAFE_TOUCH(cleanup, DIRB"/B", 0, NULL);
> +	SAFE_TOUCH(cleanup, DIRC"/C", 0, NULL);
> +	SAFE_TOUCH(cleanup, DIRD"/D", 0, NULL);
> +}
> +
> +int child_func(void *arg)
> +{
> +	char buf;
> +
> +	/* bind mounts DIRA to DIRB making contents of DIRA visible
> +	 * in DIRB */
> +	if (mount(DIRA, DIRB, "none", MS_BIND, NULL) == -1) {
> +		perror("mount");
> +		write(pipefd1[1], "1", 1);
> +		return 1;
> +	}
> +
> +	/* makes mount DIRB a slave of DIRA (all slave mounts have
> +	 * a master mount which is a shared mount) */
> +	if (mount("none", DIRB, "none", MS_SLAVE, NULL) == -1) {
> +		perror("mount");
> +		umount(DIRB);
> +		write(pipefd1[1], "1", 1);
> +		return 1;
> +	}
> +
> +	/* bind mounts DIRC to DIRA making contents of DIRC visible
> +	 * in DIRA */
> +	if (mount(DIRC, DIRA, "none", MS_BIND, NULL) == -1) {
> +		perror("mount");
> +		umount(DIRB);
> +		write(pipefd1[1], "1", 1);
> +		return 1;
> +	}
> +
> +	/* as DIRB is a slave of DIRA, previous mount (DIRC to DIRA)
> +	 * should be also propageted into DIRB */
> +	if (access(DIRB"/C", F_OK) != -1)
> +		tst_resm(TPASS, "propagation to slave mount passed");
> +	else
> +		tst_resm(TFAIL, "propagation to slave mount failed");
> +
> +	/* bind mounts DIRD to DIRB making contents of DIRD visible
> +	 * in DIRB (should not propagate to DIRA as DIRB is its slave) */
> +	if (mount(DIRD, DIRB, "none", MS_BIND, NULL) == -1) {
> +		perror("mount");
> +		umount(DIRA);
> +		umount(DIRB);
> +		write(pipefd1[1], "1", 1);
> +		return 1;
> +	}
> +
> +	/* tells parent to stop waiting and continue */
> +	write(pipefd1[1], "0", 1);
> +
> +	/* waits for parent approval to terminate */
> +	read(pipefd2[0], &buf, 1);
> +
> +	umount(DIRB);
> +	umount(DIRA);
> +	umount(DIRB);
> +	return 0;

You need to use tst_exit() to propagate exit value from tst_resm above.

> +}
> +
> +static void test(void)
> +{
> +	int status, pass;
> +	char buf;
> +
> +	/* creates a pipe for synchronization between parent and child */
> +	SAFE_PIPE(cleanup, pipefd1);
> +	SAFE_PIPE(cleanup, pipefd2);
> +
> +	/* unshares the mount ns */
> +	if (unshare(CLONE_NEWNS) == -1)
> +		tst_brkm(TBROK | TERRNO, cleanup, "unshare failed");
> +	/* makes sure parent mounts/umounts have no effect on a real system */
> +	SAFE_MOUNT(cleanup, "none", "/", "none", MS_REC|MS_PRIVATE, NULL);
> +
> +	/* bind mounts DIRA to itself */
> +	SAFE_MOUNT(cleanup, DIRA, DIRA, "none", MS_BIND, NULL);
> +	/* bind mounts DIRB to itself */
> +	SAFE_MOUNT(cleanup, DIRB, DIRB, "none", MS_BIND, NULL);
> +
> +	/* makes mount DIRA shared */
> +	SAFE_MOUNT(cleanup, "none", DIRA, "none", MS_SHARED, NULL);
> +	/* makes mount DIRB shared */
> +	SAFE_MOUNT(cleanup, "none", DIRB, "none", MS_SHARED, NULL);
> +
> +	if (do_clone_tests(CLONE_NEWNS, child_func, NULL, NULL, NULL) == -1)
> +		tst_brkm(TBROK | TERRNO, cleanup, "clone failed");
> +
> +	/* waits for child bind mount */
> +	SAFE_READ(cleanup, 0, pipefd1[0], &buf, 1);
> +
> +	/* checks that mount in slave (DIRB) doesn't propagate to shared
> +	 * mount (DIRA) */
> +	if (access(DIRA"/D", F_OK) == -1)

I'd suggest to add here: "&& access(DIRA"/C", F_OK) == 0"
it's more restrictive in case something unexpected happens.

> +		pass = 1;
> +	else
> +		pass = 0;
> +
> +	/* tells child to terminate (if no error occured in child) */
> +	SAFE_WRITE(cleanup, 0, pipefd2[1], "0", 1);
> +
> +	SAFE_WAIT(cleanup, &status);
> +
> +	if (WIFEXITED(status) && WEXITSTATUS(status) != 0)
> +		tst_brkm(TBROK, cleanup, "child failed");
> +
> +	if (WIFSIGNALED(status)) {
> +		tst_resm(TFAIL, "child was killed with signal %s",
> +			 tst_strsig(WTERMSIG(status)));
> +		return;
> +	}

Hmm, shouldn't this be the other way around? TFAIL on exit code
and TBROK on signal?

Regards,
Jan

> +
> +	close(pipefd1[0]);
> +	close(pipefd1[1]);
> +	close(pipefd2[0]);
> +	close(pipefd2[1]);
> +	SAFE_UMOUNT(cleanup, DIRA);
> +	SAFE_UMOUNT(cleanup, DIRB);
> +
> +	if (pass)
> +		tst_resm(TPASS, "propagation from slave mount passed");
> +	else
> +		tst_resm(TFAIL, "propagation form slave mount failed");
> +}
> +
> +int main(int argc, char *argv[])
> +{
> +	const char *msg;
> +	int lc;
> +
> +	msg = parse_opts(argc, argv, NULL, NULL);
> +	if (msg != NULL)
> +		tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
> +
> +	setup();
> +
> +	for (lc = 0; TEST_LOOPING(lc); lc++)
> +		test();
> +
> +	cleanup();
> +	tst_exit();
> +}
> +
> +#else /* MS_SHARED && MS_PRIVATE && MS_REC && MS_SLAVE */
> +int main(void)
> +{
> +	tst_brkm(TCONF, NULL, "needed mountflags are not defined");
> +}
> +#endif
> --
> 1.8.3.1
> 
> 
> ------------------------------------------------------------------------------
> Slashdot TV.
> Video for Nerds.  Stuff that matters.
> http://tv.slashdot.org/
> _______________________________________________
> Ltp-list mailing list
> Ltp-list@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/ltp-list
> 

------------------------------------------------------------------------------
Slashdot TV.  
Video for Nerds.  Stuff that matters.
http://tv.slashdot.org/
_______________________________________________
Ltp-list mailing list
Ltp-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ltp-list

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

* Re: [LTP] [PATCH 2/2 v2] containers: added mountns/mountns04.c
  2014-08-29 13:47   ` [LTP] [PATCH 2/2 v2] " Matus Marhefka
@ 2014-09-04 14:21     ` Jan Stancek
  2014-10-02 13:47       ` Cyril Hrubis
  2014-09-24  8:14     ` chrubis
  1 sibling, 1 reply; 17+ messages in thread
From: Jan Stancek @ 2014-09-04 14:21 UTC (permalink / raw)
  To: Matus Marhefka; +Cc: ltp-list




----- Original Message -----
> From: "Matus Marhefka" <mmarhefk@redhat.com>
> To: ltp-list@lists.sourceforge.net
> Sent: Friday, 29 August, 2014 3:47:05 PM
> Subject: [LTP] [PATCH 2/2 v2] containers: added mountns/mountns04.c
> 
> * Tests an unbindable mount: unbindable mount is an unbindable
>   private mount
> 
> Signed-off-by: Matus Marhefka <mmarhefk@redhat.com>
> ---
>  runtest/containers                              |   1 +
>  testcases/kernel/containers/.gitignore          |   1 +
>  testcases/kernel/containers/mountns/mountns04.c | 124
>  ++++++++++++++++++++++++
>  3 files changed, 126 insertions(+)
>  create mode 100644 testcases/kernel/containers/mountns/mountns04.c
> 
> diff --git a/runtest/containers b/runtest/containers
> index 3653c9c..8e8e067 100644
> --- a/runtest/containers
> +++ b/runtest/containers
> @@ -59,3 +59,4 @@ utstest_clone_5 utstest clone 5
>  mountns01 mountns01
>  mountns02 mountns02
>  mountns03 mountns03
> +mountns04 mountns04
> diff --git a/testcases/kernel/containers/.gitignore
> b/testcases/kernel/containers/.gitignore
> index 5b96cb9..4a98373 100644
> --- a/testcases/kernel/containers/.gitignore
> +++ b/testcases/kernel/containers/.gitignore
> @@ -2,3 +2,4 @@
>  mountns/mountns01
>  mountns/mountns02
>  mountns/mountns03
> +mountns/mountns04
> diff --git a/testcases/kernel/containers/mountns/mountns04.c
> b/testcases/kernel/containers/mountns/mountns04.c
> new file mode 100644
> index 0000000..32ba8c9
> --- /dev/null
> +++ b/testcases/kernel/containers/mountns/mountns04.c
> @@ -0,0 +1,124 @@
> +/* Copyright (c) 2014 Red Hat, Inc.
> + *
> + * This program is free software: you can redistribute it and/or modify
> + * it under the terms of version 2 the GNU General Public License as
> + * published by the Free Software Foundation.
> + *
> + * 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, see <http://www.gnu.org/licenses/>.
> + ***********************************************************************
> + * File: mountns04.c
> + *
> + * Tests an unbindable mount: unbindable mount is an unbindable
> + * private mount.
> + * Description:
> + * 1. Creates directories "A", "B" and files "A/A", "B/B"
> + * 2. Unshares mount namespace and makes it private (so mounts/umounts
> + *    have no effect on a real system)
> + * 3. Bind mounts directory "A" to "A" and "B" to "B"
> + * 4. Makes directory "B" shared and directory "A" unbindable

Hi,

Same question as for mountns03, is it necessary for B to be bind mounted
to itself and shared?

Regards,
Jan

> + * 5. Tries to bind mount unbindable "A" to "B":
> + *    - if it fails, test passes
> + *    - if it passes, test fails
> + ***********************************************************************/
> +
> +#define _GNU_SOURCE
> +#include <sys/wait.h>
> +#include <sys/mount.h>
> +#include <stdio.h>
> +#include <errno.h>
> +#include "test.h"
> +#include "usctest.h"
> +#include "libclone.h"
> +#include "safe_macros.h"
> +#include "safe_file_ops.h"
> +#include "mountns_helper.h"
> +
> +
> +#define DIRA "A"
> +#define DIRB "B"
> +char *TCID	= "mountns04";
> +int TST_TOTAL	= 1;
> +
> +
> +/* checks if following mountflags are defined */
> +#if defined(MS_SHARED) && defined(MS_PRIVATE) \
> +    && defined(MS_REC) && defined(MS_UNBINDABLE)
> +
> +static void cleanup(void)
> +{
> +	umount(DIRA);
> +	umount(DIRB);
> +	tst_rmdir();
> +}
> +
> +static void setup(void)
> +{
> +	tst_require_root(NULL);
> +	check_newns();	/* from mountns_helper.h */
> +	tst_tmpdir();
> +	SAFE_MKDIR(cleanup, DIRA, 0777);
> +	SAFE_MKDIR(cleanup, DIRB, 0777);
> +	SAFE_TOUCH(cleanup, DIRA"/A", 0, NULL);
> +	SAFE_TOUCH(cleanup, DIRB"/B", 0, NULL);
> +}
> +
> +static void test(void)
> +{
> +	/* unshares the mount ns */
> +	if (unshare(CLONE_NEWNS) == -1)
> +		tst_brkm(TBROK | TERRNO, cleanup, "unshare failed");
> +	/* makes sure mounts/umounts have no effect on a real system */
> +	SAFE_MOUNT(cleanup, "none", "/", "none", MS_REC|MS_PRIVATE, NULL);
> +
> +	/* bind mounts DIRA to itself */
> +	SAFE_MOUNT(cleanup, DIRA, DIRA, "none", MS_BIND, NULL);
> +	/* bind mounts DIRB to itself */
> +	SAFE_MOUNT(cleanup, DIRB, DIRB, "none", MS_BIND, NULL);
> +
> +	/* makes mount DIRA unbindable */
> +	SAFE_MOUNT(cleanup, "none", DIRA, "none", MS_UNBINDABLE, NULL);
> +	/* makes mount DIRB shared */
> +	SAFE_MOUNT(cleanup, "none", DIRB, "none", MS_SHARED, NULL);
> +
> +	/* tries to bind mount unbindable DIRA to DIRB which should fail */
> +	if (mount(DIRA, DIRB, "none", MS_BIND, NULL) == -1)
> +		tst_resm(TPASS, "unbindable mount passed");
> +	else {
> +		SAFE_UMOUNT(cleanup, DIRB);
> +		tst_resm(TFAIL, "unbindable mount faled");
> +	}
> +
> +	SAFE_UMOUNT(cleanup, DIRA);
> +	SAFE_UMOUNT(cleanup, DIRB);
> +}
> +
> +int main(int argc, char *argv[])
> +{
> +	const char *msg;
> +	int lc;
> +
> +	msg = parse_opts(argc, argv, NULL, NULL);
> +	if (msg != NULL)
> +		tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
> +
> +	setup();
> +
> +	for (lc = 0; TEST_LOOPING(lc); lc++)
> +		test();
> +
> +	cleanup();
> +	tst_exit();
> +}
> +
> +#else /* MS_SHARED && MS_PRIVATE && MS_REC && MS_UNBINDABLE */
> +int main(void)
> +{
> +	tst_brkm(TCONF, NULL, "needed mountflags are not defined");
> +}
> +#endif
> --
> 1.8.3.1
> 
> 
> ------------------------------------------------------------------------------
> Slashdot TV.
> Video for Nerds.  Stuff that matters.
> http://tv.slashdot.org/
> _______________________________________________
> Ltp-list mailing list
> Ltp-list@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/ltp-list
> 

------------------------------------------------------------------------------
Slashdot TV.  
Video for Nerds.  Stuff that matters.
http://tv.slashdot.org/
_______________________________________________
Ltp-list mailing list
Ltp-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ltp-list

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

* Re: [LTP] [PATCH 1/2 v2] containers: added mountns/mountns03.c
  2014-09-04 14:13   ` Jan Stancek
@ 2014-09-11 15:09     ` Jiri Jaburek
  2014-09-12 12:59       ` Jan Stancek
  0 siblings, 1 reply; 17+ messages in thread
From: Jiri Jaburek @ 2014-09-11 15:09 UTC (permalink / raw)
  To: Matus Marhefka; +Cc: ltp-list

On 09/04/2014 04:13 PM, Jan Stancek wrote:
> 
> 
> 
> 
> ----- Original Message -----
>> From: "Matus Marhefka" <mmarhefk@redhat.com>
>> To: ltp-list@lists.sourceforge.net
>> Sent: Friday, 29 August, 2014 3:46:07 PM
>> Subject: [LTP] [PATCH 1/2 v2] containers: added mountns/mountns03.c
>>
>> * Tests a slave mount: slave mount is like a shared mount except that
>>   mount and umount events only propagate towards it
>>
>> Signed-off-by: Matus Marhefka <mmarhefk@redhat.com>
>> ---
>>  runtest/containers                              |   1 +
>>  testcases/kernel/containers/.gitignore          |   1 +
>>  testcases/kernel/containers/mountns/mountns03.c | 245
>>  ++++++++++++++++++++++++
>>  3 files changed, 247 insertions(+)
>>  create mode 100644 testcases/kernel/containers/mountns/mountns03.c
>>
>> diff --git a/runtest/containers b/runtest/containers
>> index 56977c0..3653c9c 100644
>> --- a/runtest/containers
>> +++ b/runtest/containers
>> @@ -58,3 +58,4 @@ utstest_clone_5 utstest clone 5
>>  
>>  mountns01 mountns01
>>  mountns02 mountns02
>> +mountns03 mountns03
>> diff --git a/testcases/kernel/containers/.gitignore
>> b/testcases/kernel/containers/.gitignore
>> index f175296..5b96cb9 100644
>> --- a/testcases/kernel/containers/.gitignore
>> +++ b/testcases/kernel/containers/.gitignore
>> @@ -1,3 +1,4 @@
>>  /check_for_unshare
>>  mountns/mountns01
>>  mountns/mountns02
>> +mountns/mountns03
>> diff --git a/testcases/kernel/containers/mountns/mountns03.c
>> b/testcases/kernel/containers/mountns/mountns03.c
>> new file mode 100644
>> index 0000000..acca44c
>> --- /dev/null
>> +++ b/testcases/kernel/containers/mountns/mountns03.c
>> @@ -0,0 +1,245 @@
>> +/* Copyright (c) 2014 Red Hat, Inc.
>> + *
>> + * This program is free software: you can redistribute it and/or modify
>> + * it under the terms of version 2 the GNU General Public License as
>> + * published by the Free Software Foundation.
>> + *
>> + * 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, see <http://www.gnu.org/licenses/>.
>> + ***********************************************************************
>> + * File: mountns03.c
>> + *
>> + * Tests a slave mount: slave mount is like a shared mount except that
>> + * mount and umount events only propagate towards it.
>> + * Description:
>> + * 1. Creates directories "A", "B", "C", "D" and files "A/A", "B/B"
>> + *    "C/C", "D/D"
>> + * 2. Unshares mount namespace and makes it private (so mounts/umounts
>> + *    have no effect on a real system)
> 
> Hi,
> 
>> + * 3. Bind mounts directory "A" to "A" and "B" to "B"
> 
> is the "B" to "B" part necessary in this case? First thing child does is
> it mounts A to B.
> 
>> + * 4. Makes both directories ("A" and "B") shared
> 
> related to above, is it necessary to make B shared?

The obvious answer would be "yes", because mount namespaces work with
mount points - if you create a mountpoint, make it shared and *then*
create a new namespace, both namespaces are going to share that mount
point and any change to it (ie. bind mount over it) is going to be
"propagated" to both (or all namespaces that share it).

This is in contrast with slave mountpoints, which only "receive"
propagation events, not "send" them to other namespaces.

The logic however doesn't end there, a mountpoint can be both "shared"
and "slave" at the same time, essentially "receiving" propagation events
from one group of namespaces and "sending" local propagation events to
a different group.

However as the test logic is not really simple, I don't know if bind
mounting "B" is in fact necessary for this test case, meaning the
answer is not obvious (see also further below).


I guess it could be simplified and extended by the "slave + shared" case
like ie.:

(the following expects A and B to be directories, with A bind-mounted
to itself, creating a mount point, made private, with A having file
a and B having file b, essentially A/a and B/b)
(also, X, Y and Z are namespaces)

To set-up:

  private:
    X) create Y

  shared:
    X) make A shared
    X) create Y

  slave:
    X) make A shared
    X) create Y
    Y) make A slave

  slave-shared:
    X) make A shared
    X) create Y
    Y) make A slave
    Y) make A shared
    Y) create Z

To test/verify:

  private:
    X) bind mount B over A
    Y) see A/a
    X) umount A
    AND
    Y) bind mount B over A
    X) see A/a
    Y) umount A

  shared:
    X) bind mount B over A
    Y) see A/b
    X) umount A
    AND
    Y) bind mount B over A
    X) see A/b
    Y) umount A

  slave:
    X) bind mount B over A
    Y) see A/b
    X) umount A
    AND
    Y) bind mount B over A
    X) see A/a  # slave cannot propagate up (to master)
    Y) umount A

  slave-shared:
    X) bind mount B over A
    Y) see A/b
    Z) see A/b
    X) umount
    AND
    Y) bind mount B over A
    X) see A/a  # slave cannot propagate up
    Z) see A/b  # Z shares A with Y
    Y) umount A
    AND
    Z) bind mount B over A
    X) see A/a  # slave cannot propagate up
    Y) see A/b  # Y shares A with Z
    Z) umount A

This could be continued with ie. slave-shared-slave (by making A slave
in Z), but that wouldn't exercise any new code paths.

See also the state/transition diagrams in the kernel docs,
Documentation/filesystems/sharedsubtree.txt


On 08/29/2014 03:46 PM, Matus Marhefka wrote:
> + * 1. Creates directories "A", "B", "C", "D" and files "A/A", "B/B"
> + *    "C/C", "D/D"
> + * 2. Unshares mount namespace and makes it private (so mounts/umounts
> + *    have no effect on a real system)
> + * 3. Bind mounts directory "A" to "A" and "B" to "B"
> + * 4. Makes both directories ("A" and "B") shared
> + * 5. Clones a new child process with CLONE_NEWNS flag - the new child
> + *    then:
> + *    a) bind mounts directory "A" to directory "B"
> + *    b) makes mount "B" a slave of "A"
> + *    c) bind mounts directory "C" to "A"
> + *    d) checks that mount in c) propagated also to direcoty "B" (as "B"
> + *       is a slave of "A"):

So you're checking slave propagation within the same (child) namespace?
I guess it makes sense, since it should work on mountpoints in general,
but then how do you "make mount B a slave of A" without a namespace
switch? Doing MS_SLAVE on a MS_SHARED mountpoint with a single member in
the peer group (no master) makes it MS_PRIVATE automatically.
Does the parent process here serve as a placeholder to prevent that?

> + *       - if it does, test #1 passes
> + *       - if it doesn't, test #1 fails
> + *    e) bind mounts direcory "D" to "B"
> + *    f) waits for parent approval to terminate
> + * 6. Parent checks if directory "A" doesn't contain the file "D"
> + *    (as slave mount ("B") doesn't forward propagation (to "A")):
> + *    - if it doesn't, test #2 passes
> + *    - if it does, test #2 fails
> + * 7. Parent allows child to terminate

If I understood it correctly,

     parent | child
----------- +--------
A (shared)  | A (shared)
            | |
            | V
B (shared)  | B (slave)

with the tests being performed on B in the child. This raises a question
- why do you need B at all? Why not do MS_SLAVE on A? In this sense,
B (child) is not a slave of B (parent), but a slave of A (parent), with
B (parent) being slave of A (parent) due to the shared propagation.

(It's why my extended test matrix above doesn't make B a mountpoint,
because all the testing is done on A).

Thanks & feel free to ask,
Jiri


------------------------------------------------------------------------------
Want excitement?
Manually upgrade your production database.
When you want reliability, choose Perforce
Perforce version control. Predictably reliable.
http://pubads.g.doubleclick.net/gampad/clk?id=157508191&iu=/4140/ostg.clktrk
_______________________________________________
Ltp-list mailing list
Ltp-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ltp-list

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

* Re: [LTP] [PATCH 1/2 v2] containers: added mountns/mountns03.c
  2014-09-11 15:09     ` Jiri Jaburek
@ 2014-09-12 12:59       ` Jan Stancek
  2014-09-12 13:41         ` Jiri Jaburek
  0 siblings, 1 reply; 17+ messages in thread
From: Jan Stancek @ 2014-09-12 12:59 UTC (permalink / raw)
  To: Jiri Jaburek; +Cc: ltp-list



----- Original Message -----
> From: "Jiri Jaburek" <jjaburek@redhat.com>
> To: "Matus Marhefka" <mmarhefk@redhat.com>
> Cc: ltp-list@lists.sourceforge.net, "Jan Stancek" <jstancek@redhat.com>
> Sent: Thursday, 11 September, 2014 5:09:46 PM
> Subject: Re: [LTP] [PATCH 1/2 v2] containers: added mountns/mountns03.c

> >> +++ b/testcases/kernel/containers/mountns/mountns03.c
> >> @@ -0,0 +1,245 @@
> >> +/* Copyright (c) 2014 Red Hat, Inc.
> >> + *
> >> + * This program is free software: you can redistribute it and/or modify
> >> + * it under the terms of version 2 the GNU General Public License as
> >> + * published by the Free Software Foundation.
> >> + *
> >> + * 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, see <http://www.gnu.org/licenses/>.
> >> + ***********************************************************************
> >> + * File: mountns03.c
> >> + *
> >> + * Tests a slave mount: slave mount is like a shared mount except that
> >> + * mount and umount events only propagate towards it.
> >> + * Description:
> >> + * 1. Creates directories "A", "B", "C", "D" and files "A/A", "B/B"
> >> + *    "C/C", "D/D"
> >> + * 2. Unshares mount namespace and makes it private (so mounts/umounts
> >> + *    have no effect on a real system)
> > 
> > Hi,
> > 
> >> + * 3. Bind mounts directory "A" to "A" and "B" to "B"
> > 
> > is the "B" to "B" part necessary in this case? First thing child does is
> > it mounts A to B.
> > 
> >> + * 4. Makes both directories ("A" and "B") shared
> > 
> > related to above, is it necessary to make B shared?
> 
> The obvious answer would be "yes", because ...

(atm. replying to this part only)

If you don't make B shared in parent, doesn't a bind operation in child make
it shared regardless? You are bind mounting a shared mount to non-shared one.

   ---------------------------------------------------------------------------
   |         BIND MOUNT OPERATION                                            |
   |**************************************************************************
   |source(A)->| shared       |       private  |       slave    | unbindable |
   | dest(B)  |               |                |                |            |
   |   |      |               |                |                |            |
   |   v      |               |                |                |            |
   |**************************************************************************
   |  shared  | shared        |     shared     | shared & slave |  invalid   |
   |          |               |                |                |            |
   |non-shared| shared        |      private   |      slave     |  invalid   |
   ***************************************************************************

I modified the mountns03 testcase, so it doesn't bind and make B shared,
consider following strace output:

unshare(CLONE_NEWNS)                    = 0
mount("none", "/", "none", MS_REC|MS_PRIVATE, NULL) = 0
mount("A", "A", 0x407ab0, MS_BIND, NULL) = 0  --> bind mounts directory "A" to "A"
mount("none", "A", "none", MS_SHARED, NULL) = 0  --> make "A" shared
access("A/C", F_OK)                     = -1 ENOENT (No such file or directory)  --> there's no C file in "A"
clone(child_stack=0x2597030, flags=CLONE_NEWNS|SIGCHLD) = 2396
read(3, Process 2396 attached
 <unfinished ...>
[pid  2396] getpid()                    = 2396
[pid  2396] mount("A", "B", 0x407ab0, MS_BIND, NULL) = 0  --> bind shared mount "A" to "B"
[pid  2396] mount("C", "B", 0x407ab0, MS_BIND, NULL) = 0  --> bind mount "C" to "B"
[pid  2396] write(4, "0", 1 <unfinished ...>
[pid  2394] <... read resumed> "0", 1)  = 1
[pid  2394] access("A/C", F_OK)         = 0  --> parent can see file "C" in "A"

Regards,
Jan

------------------------------------------------------------------------------
Want excitement?
Manually upgrade your production database.
When you want reliability, choose Perforce
Perforce version control. Predictably reliable.
http://pubads.g.doubleclick.net/gampad/clk?id=157508191&iu=/4140/ostg.clktrk
_______________________________________________
Ltp-list mailing list
Ltp-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ltp-list

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

* Re: [LTP] [PATCH 1/2 v2] containers: added mountns/mountns03.c
  2014-09-12 12:59       ` Jan Stancek
@ 2014-09-12 13:41         ` Jiri Jaburek
  2014-09-12 14:19           ` Jan Stancek
  0 siblings, 1 reply; 17+ messages in thread
From: Jiri Jaburek @ 2014-09-12 13:41 UTC (permalink / raw)
  To: Jan Stancek; +Cc: ltp-list

On 09/12/2014 02:59 PM, Jan Stancek wrote:
> 
> 
> ----- Original Message -----
>> From: "Jiri Jaburek" <jjaburek@redhat.com>
>> To: "Matus Marhefka" <mmarhefk@redhat.com>
>> Cc: ltp-list@lists.sourceforge.net, "Jan Stancek" <jstancek@redhat.com>
>> Sent: Thursday, 11 September, 2014 5:09:46 PM
>> Subject: Re: [LTP] [PATCH 1/2 v2] containers: added mountns/mountns03.c
> 
>>>> +++ b/testcases/kernel/containers/mountns/mountns03.c
>>>> @@ -0,0 +1,245 @@
>>>> +/* Copyright (c) 2014 Red Hat, Inc.
>>>> + *
>>>> + * This program is free software: you can redistribute it and/or modify
>>>> + * it under the terms of version 2 the GNU General Public License as
>>>> + * published by the Free Software Foundation.
>>>> + *
>>>> + * 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, see <http://www.gnu.org/licenses/>.
>>>> + ***********************************************************************
>>>> + * File: mountns03.c
>>>> + *
>>>> + * Tests a slave mount: slave mount is like a shared mount except that
>>>> + * mount and umount events only propagate towards it.
>>>> + * Description:
>>>> + * 1. Creates directories "A", "B", "C", "D" and files "A/A", "B/B"
>>>> + *    "C/C", "D/D"
>>>> + * 2. Unshares mount namespace and makes it private (so mounts/umounts
>>>> + *    have no effect on a real system)
>>>
>>> Hi,
>>>
>>>> + * 3. Bind mounts directory "A" to "A" and "B" to "B"
>>>
>>> is the "B" to "B" part necessary in this case? First thing child does is
>>> it mounts A to B.
>>>
>>>> + * 4. Makes both directories ("A" and "B") shared
>>>
>>> related to above, is it necessary to make B shared?
>>
>> The obvious answer would be "yes", because ...
> 
> (atm. replying to this part only)
> 
> If you don't make B shared in parent, doesn't a bind operation in child make
> it shared regardless? You are bind mounting a shared mount to non-shared one.

No, not really. Consider the following situation:

    parent  |  child
------------+-----------
A (shared)  | A (shared)
B (private) | B (shared)

(that is, you unshare a mount namespace from the parent and do
MS_SHARED on B in the child)

The "sharedness" of B isn't propagated to the parent. If it would, it
could be considered a serious security issue w.r.t. containers, since
any container could force the "host" to share anything mounted with it.

The rule of thumb is that a private mountpoint cannot be affected by
other (mount) namespaces. In this case, if the child were to spawn its
own child, it would share B with it, but the original parent would still
have its own B.

IOW bind mounting A to B in the child in the situation illustrated above
would not affect the parent.

> 
>    ---------------------------------------------------------------------------
>    |         BIND MOUNT OPERATION                                            |
>    |**************************************************************************
>    |source(A)->| shared       |       private  |       slave    | unbindable |
>    | dest(B)  |               |                |                |            |
>    |   |      |               |                |                |            |
>    |   v      |               |                |                |            |
>    |**************************************************************************
>    |  shared  | shared        |     shared     | shared & slave |  invalid   |
>    |          |               |                |                |            |
>    |non-shared| shared        |      private   |      slave     |  invalid   |
>    ***************************************************************************

True, the mountpoint in the child is changed from private to shared,
but such operation doesn't affect the private mountpoint of the parent.

> I modified the mountns03 testcase, so it doesn't bind and make B shared,
> consider following strace output:
> 
> unshare(CLONE_NEWNS)                    = 0
> mount("none", "/", "none", MS_REC|MS_PRIVATE, NULL) = 0
> mount("A", "A", 0x407ab0, MS_BIND, NULL) = 0  --> bind mounts directory "A" to "A"
> mount("none", "A", "none", MS_SHARED, NULL) = 0  --> make "A" shared
> access("A/C", F_OK)                     = -1 ENOENT (No such file or directory)  --> there's no C file in "A"
> clone(child_stack=0x2597030, flags=CLONE_NEWNS|SIGCHLD) = 2396
> read(3, Process 2396 attached
>  <unfinished ...>
> [pid  2396] getpid()                    = 2396
> [pid  2396] mount("A", "B", 0x407ab0, MS_BIND, NULL) = 0  --> bind shared mount "A" to "B"

... making B the same as A, so anything on B done directly on A.

> [pid  2396] mount("C", "B", 0x407ab0, MS_BIND, NULL) = 0  --> bind mount "C" to "B"

... which is essentially bind mount C to A.

> [pid  2396] write(4, "0", 1 <unfinished ...>
> [pid  2394] <... read resumed> "0", 1)  = 1
> [pid  2394] access("A/C", F_OK)         = 0  --> parent can see file "C" in "A"

Indeed, but only because A was shared by the parent. This means the
child can affect it in any way (bind mount any number of additional
mountpoints to it, umount it, etc.). If you bind-mounted B to B and
made it private, it would retain its B/B file.

The test works likely due to reasons I mentioned before,

On 09/11/2014 05:09 PM, Jiri Jaburek wrote:
> This raises a question
> - why do you need B at all? Why not do MS_SLAVE on A? In this sense,
> B (child) is not a slave of B (parent), but a slave of A (parent), with
> B (parent) being slave of A (parent) due to the shared propagation.

Meaning that B could be entirely omitted, because it's not used for
anything in the parent, therefore it doesn't matter whether you
bind-mount it or not. Meaning, in essence, that you were originally
correct. :)

I would like to help Matus with this test case when he gets back to it.


I'm personally not a namespace kernel developer, so I may be wrong,
but my testing using multiple shells + mount(8) seems to confirm my
theories.

Jiri


------------------------------------------------------------------------------
Want excitement?
Manually upgrade your production database.
When you want reliability, choose Perforce
Perforce version control. Predictably reliable.
http://pubads.g.doubleclick.net/gampad/clk?id=157508191&iu=/4140/ostg.clktrk
_______________________________________________
Ltp-list mailing list
Ltp-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ltp-list

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

* Re: [LTP] [PATCH 1/2 v2] containers: added mountns/mountns03.c
  2014-09-12 13:41         ` Jiri Jaburek
@ 2014-09-12 14:19           ` Jan Stancek
  0 siblings, 0 replies; 17+ messages in thread
From: Jan Stancek @ 2014-09-12 14:19 UTC (permalink / raw)
  To: Jiri Jaburek; +Cc: ltp-list





----- Original Message -----
> From: "Jiri Jaburek" <jjaburek@redhat.com>
> To: "Jan Stancek" <jstancek@redhat.com>
> Cc: "Matus Marhefka" <mmarhefk@redhat.com>, ltp-list@lists.sourceforge.net
> Sent: Friday, 12 September, 2014 3:41:25 PM
> Subject: Re: [LTP] [PATCH 1/2 v2] containers: added mountns/mountns03.c
> 
> On 09/12/2014 02:59 PM, Jan Stancek wrote:
> > 
> > 
> > ----- Original Message -----
> >> From: "Jiri Jaburek" <jjaburek@redhat.com>
> >> To: "Matus Marhefka" <mmarhefk@redhat.com>
> >> Cc: ltp-list@lists.sourceforge.net, "Jan Stancek" <jstancek@redhat.com>
> >> Sent: Thursday, 11 September, 2014 5:09:46 PM
> >> Subject: Re: [LTP] [PATCH 1/2 v2] containers: added mountns/mountns03.c
> > 
> >>>> +++ b/testcases/kernel/containers/mountns/mountns03.c
> >>>> @@ -0,0 +1,245 @@
> >>>> +/* Copyright (c) 2014 Red Hat, Inc.
> >>>> + *
> >>>> + * This program is free software: you can redistribute it and/or modify
> >>>> + * it under the terms of version 2 the GNU General Public License as
> >>>> + * published by the Free Software Foundation.
> >>>> + *
> >>>> + * 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, see
> >>>> <http://www.gnu.org/licenses/>.
> >>>> +
> >>>> ***********************************************************************
> >>>> + * File: mountns03.c
> >>>> + *
> >>>> + * Tests a slave mount: slave mount is like a shared mount except that
> >>>> + * mount and umount events only propagate towards it.
> >>>> + * Description:
> >>>> + * 1. Creates directories "A", "B", "C", "D" and files "A/A", "B/B"
> >>>> + *    "C/C", "D/D"
> >>>> + * 2. Unshares mount namespace and makes it private (so mounts/umounts
> >>>> + *    have no effect on a real system)
> >>>
> >>> Hi,
> >>>
> >>>> + * 3. Bind mounts directory "A" to "A" and "B" to "B"
> >>>
> >>> is the "B" to "B" part necessary in this case? First thing child does is
> >>> it mounts A to B.
> >>>
> >>>> + * 4. Makes both directories ("A" and "B") shared
> >>>
> >>> related to above, is it necessary to make B shared?
> >>
> >> The obvious answer would be "yes", because ...
> > 
> > (atm. replying to this part only)
> > 
> > If you don't make B shared in parent, doesn't a bind operation in child
> > make
> > it shared regardless? You are bind mounting a shared mount to non-shared
> > one.
> 
> No, not really. Consider the following situation:
> 
>     parent  |  child
> ------------+-----------
> A (shared)  | A (shared)
> B (private) | B (shared)
> 
> (that is, you unshare a mount namespace from the parent and do
> MS_SHARED on B in the child)
> 
> The "sharedness" of B isn't propagated to the parent...

I was not implying it is. My point was that after bind in child,
mount "B" receives and forwards event propagations with mount "A" in parent.

> 
> The rule of thumb is that a private mountpoint cannot be affected by
> other (mount) namespaces. In this case, if the child were to spawn its
> own child, it would share B with it, but the original parent would still
> have its own B.
> 
> IOW bind mounting A to B in the child in the situation illustrated above
> would not affect the parent.
> 
> > 
> >    ---------------------------------------------------------------------------
> >    |         BIND MOUNT OPERATION
> >    |         |
> >    |**************************************************************************
> >    |source(A)->| shared       |       private  |       slave    |
> >    |unbindable |
> >    | dest(B)  |               |                |                |
> >    | |
> >    |   |      |               |                |                |            |
> >    |   v      |               |                |                |
> >    |   |
> >    |**************************************************************************
> >    |  shared  | shared        |     shared     | shared & slave |  invalid
> >    |  |
> >    |          |               |                |                |            |
> >    |non-shared| shared        |      private   |      slave     |  invalid
> >    ||
> >    ***************************************************************************
> 
> True, the mountpoint in the child is changed from private to shared,
> but such operation doesn't affect the private mountpoint of the parent.

I agree - I don't think we care what happens with "B" in parent, when test
is about "A".

> 
> > I modified the mountns03 testcase, so it doesn't bind and make B shared,
> > consider following strace output:
> > 
> > unshare(CLONE_NEWNS)                    = 0
> > mount("none", "/", "none", MS_REC|MS_PRIVATE, NULL) = 0
> > mount("A", "A", 0x407ab0, MS_BIND, NULL) = 0  --> bind mounts directory "A"
> > to "A"
> > mount("none", "A", "none", MS_SHARED, NULL) = 0  --> make "A" shared
> > access("A/C", F_OK)                     = -1 ENOENT (No such file or
> > directory)  --> there's no C file in "A"
> > clone(child_stack=0x2597030, flags=CLONE_NEWNS|SIGCHLD) = 2396
> > read(3, Process 2396 attached
> >  <unfinished ...>
> > [pid  2396] getpid()                    = 2396
> > [pid  2396] mount("A", "B", 0x407ab0, MS_BIND, NULL) = 0  --> bind shared
> > mount "A" to "B"
> 
> ... making B the same as A, so anything on B done directly on A.
> 
> > [pid  2396] mount("C", "B", 0x407ab0, MS_BIND, NULL) = 0  --> bind mount
> > "C" to "B"
> 
> ... which is essentially bind mount C to A.
> 
> > [pid  2396] write(4, "0", 1 <unfinished ...>
> > [pid  2394] <... read resumed> "0", 1)  = 1
> > [pid  2394] access("A/C", F_OK)         = 0  --> parent can see file "C" in
> > "A"
> 
> Indeed, but only because A was shared by the parent. This means the
> child can affect it in any way (bind mount any number of additional
> mountpoints to it, umount it, etc.). If you bind-mounted B to B and
> made it private, it would retain its B/B file.
> 
> The test works likely due to reasons I mentioned before,
> 
> On 09/11/2014 05:09 PM, Jiri Jaburek wrote:
> > This raises a question
> > - why do you need B at all? Why not do MS_SLAVE on A? In this sense,
> > B (child) is not a slave of B (parent), but a slave of A (parent), with
> > B (parent) being slave of A (parent) due to the shared propagation.
> 
> Meaning that B could be entirely omitted, because it's not used for
> anything in the parent, therefore it doesn't matter whether you
> bind-mount it or not. Meaning, in essence, that you were originally
> correct. :)
> 
> I would like to help Matus with this test case when he gets back to it.

Looking at the discussion this triggered, the more simple we can make it, the better :-)

Regards,
Jan

> 
> 
> I'm personally not a namespace kernel developer, so I may be wrong,
> but my testing using multiple shells + mount(8) seems to confirm my
> theories.
> 
> Jiri
> 
> 

------------------------------------------------------------------------------
Want excitement?
Manually upgrade your production database.
When you want reliability, choose Perforce
Perforce version control. Predictably reliable.
http://pubads.g.doubleclick.net/gampad/clk?id=157508191&iu=/4140/ostg.clktrk
_______________________________________________
Ltp-list mailing list
Ltp-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ltp-list

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

* Re: [LTP] [PATCH 1/2 v2] containers: added mountns/mountns03.c
  2014-08-29 13:46 ` [LTP] [PATCH 1/2 v2] containers: added mountns/mountns03.c Matus Marhefka
  2014-09-04 14:13   ` Jan Stancek
@ 2014-09-24  7:56   ` chrubis
       [not found]     ` <273164774.30346037.1411649870605.JavaMail.zimbra@redhat.com>
  1 sibling, 1 reply; 17+ messages in thread
From: chrubis @ 2014-09-24  7:56 UTC (permalink / raw)
  To: Matus Marhefka; +Cc: ltp-list

Hi!
> +static void setup(void)
> +{
> +	tst_require_root(NULL);
> +	check_newns();	/* from mountns_helper.h */

Please remove this comment.

> +	tst_tmpdir();
> +	SAFE_MKDIR(cleanup, DIRA, 0777);
> +	SAFE_MKDIR(cleanup, DIRB, 0777);
> +	SAFE_MKDIR(cleanup, DIRC, 0777);
> +	SAFE_MKDIR(cleanup, DIRD, 0777);
> +	SAFE_TOUCH(cleanup, DIRA"/A", 0, NULL);
> +	SAFE_TOUCH(cleanup, DIRB"/B", 0, NULL);
> +	SAFE_TOUCH(cleanup, DIRC"/C", 0, NULL);
> +	SAFE_TOUCH(cleanup, DIRD"/D", 0, NULL);
> +}
> +
> +int child_func(void *arg)
> +{
> +	char buf;
> +
> +	/* bind mounts DIRA to DIRB making contents of DIRA visible
> +	 * in DIRB */
> +	if (mount(DIRA, DIRB, "none", MS_BIND, NULL) == -1) {
> +		perror("mount");
> +		write(pipefd1[1], "1", 1);
> +		return 1;
> +	}
> +
> +	/* makes mount DIRB a slave of DIRA (all slave mounts have
> +	 * a master mount which is a shared mount) */
> +	if (mount("none", DIRB, "none", MS_SLAVE, NULL) == -1) {
> +		perror("mount");
> +		umount(DIRB);
> +		write(pipefd1[1], "1", 1);
> +		return 1;
> +	}
> +
> +	/* bind mounts DIRC to DIRA making contents of DIRC visible
> +	 * in DIRA */
> +	if (mount(DIRC, DIRA, "none", MS_BIND, NULL) == -1) {
> +		perror("mount");
> +		umount(DIRB);
> +		write(pipefd1[1], "1", 1);
> +		return 1;
> +	}
> +
> +	/* as DIRB is a slave of DIRA, previous mount (DIRC to DIRA)
> +	 * should be also propageted into DIRB */
> +	if (access(DIRB"/C", F_OK) != -1)
> +		tst_resm(TPASS, "propagation to slave mount passed");
> +	else
> +		tst_resm(TFAIL, "propagation to slave mount failed");
> +
> +	/* bind mounts DIRD to DIRB making contents of DIRD visible
> +	 * in DIRB (should not propagate to DIRA as DIRB is its slave) */
> +	if (mount(DIRD, DIRB, "none", MS_BIND, NULL) == -1) {
> +		perror("mount");
> +		umount(DIRA);
> +		umount(DIRB);
> +		write(pipefd1[1], "1", 1);
> +		return 1;
> +	}
> +
> +	/* tells parent to stop waiting and continue */
> +	write(pipefd1[1], "0", 1);
> +
> +	/* waits for parent approval to terminate */
> +	read(pipefd2[0], &buf, 1);

We have a child-parent synchronization functions in the LTP test
library. Have look at include/tst_checkpoint.h and
lib/tests/tst_checkpoint* and make use of it.

In short these two statements would became:

TST_CHECKPOINT_SIGNAL_PARENT(&checkpoint);
TST_CHECKPOINT_CHILD_WAIT(&checkpoint);

And you would have to declare checkpoint structure and initialize the
checkpoint in setup with:

struct tst_checkpoint checkpoint;

...

static void setup(void)
{
	...
	TST_CHECKPOINT_INIT(&checkpoint);
	...
}

The difference between doing write() and checkpoint interfaces is that
checkpoint checks return values from write(), suppport timeouts, etc.

> +	umount(DIRB);
> +	umount(DIRA);
> +	umount(DIRB);
> +	return 0;
> +}
> +
> +static void test(void)
> +{
> +	int status, pass;
> +	char buf;
> +
> +	/* creates a pipe for synchronization between parent and child */
> +	SAFE_PIPE(cleanup, pipefd1);
> +	SAFE_PIPE(cleanup, pipefd2);
> +
> +	/* unshares the mount ns */
> +	if (unshare(CLONE_NEWNS) == -1)
> +		tst_brkm(TBROK | TERRNO, cleanup, "unshare failed");
> +	/* makes sure parent mounts/umounts have no effect on a real system */
> +	SAFE_MOUNT(cleanup, "none", "/", "none", MS_REC|MS_PRIVATE, NULL);
> +
> +	/* bind mounts DIRA to itself */
> +	SAFE_MOUNT(cleanup, DIRA, DIRA, "none", MS_BIND, NULL);
> +	/* bind mounts DIRB to itself */
> +	SAFE_MOUNT(cleanup, DIRB, DIRB, "none", MS_BIND, NULL);
> +
> +	/* makes mount DIRA shared */
> +	SAFE_MOUNT(cleanup, "none", DIRA, "none", MS_SHARED, NULL);
> +	/* makes mount DIRB shared */
> +	SAFE_MOUNT(cleanup, "none", DIRB, "none", MS_SHARED, NULL);
> +
> +	if (do_clone_tests(CLONE_NEWNS, child_func, NULL, NULL, NULL) == -1)
> +		tst_brkm(TBROK | TERRNO, cleanup, "clone failed");
> +
> +	/* waits for child bind mount */
> +	SAFE_READ(cleanup, 0, pipefd1[0], &buf, 1);

Here you should do TST_CHECKPOINT_PARENT_WAIT(cleanup, &checkpoint);

> +	/* checks that mount in slave (DIRB) doesn't propagate to shared
> +	 * mount (DIRA) */
> +	if (access(DIRA"/D", F_OK) == -1)
> +		pass = 1;
> +	else
> +		pass = 0;
> +
> +	/* tells child to terminate (if no error occured in child) */
> +	SAFE_WRITE(cleanup, 0, pipefd2[1], "0", 1);

Here you should do TST_CHECKPOINT_SIGNAL_CHILD(cleanup, &checkpoint);

> +	SAFE_WAIT(cleanup, &status);
> +
> +	if (WIFEXITED(status) && WEXITSTATUS(status) != 0)
> +		tst_brkm(TBROK, cleanup, "child failed");
> +
> +	if (WIFSIGNALED(status)) {
> +		tst_resm(TFAIL, "child was killed with signal %s",
> +			 tst_strsig(WTERMSIG(status)));
> +		return;
> +	}
> +
> +	close(pipefd1[0]);
> +	close(pipefd1[1]);
> +	close(pipefd2[0]);
> +	close(pipefd2[1]);
> +	SAFE_UMOUNT(cleanup, DIRA);
> +	SAFE_UMOUNT(cleanup, DIRB);
> +
> +	if (pass)
> +		tst_resm(TPASS, "propagation from slave mount passed");
> +	else
> +		tst_resm(TFAIL, "propagation form slave mount failed");
> +}
> +
> +int main(int argc, char *argv[])
> +{
> +	const char *msg;
> +	int lc;
> +
> +	msg = parse_opts(argc, argv, NULL, NULL);
> +	if (msg != NULL)
> +		tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
> +
> +	setup();
> +
> +	for (lc = 0; TEST_LOOPING(lc); lc++)
> +		test();
> +
> +	cleanup();
> +	tst_exit();
> +}
> +
> +#else /* MS_SHARED && MS_PRIVATE && MS_REC && MS_SLAVE */

Have we settled if we should go with ifdefs or with defining the
constatns in include/lapi/?

I remeber that we disscussed it in one of the latter patches.

> +int main(void)
> +{
> +	tst_brkm(TCONF, NULL, "needed mountflags are not defined");
> +}
> +#endif

-- 
Cyril Hrubis
chrubis@suse.cz

------------------------------------------------------------------------------
Meet PCI DSS 3.0 Compliance Requirements with EventLog Analyzer
Achieve PCI DSS 3.0 Compliant Status with Out-of-the-box PCI DSS Reports
Are you Audit-Ready for PCI DSS 3.0 Compliance? Download White paper
Comply to PCI DSS 3.0 Requirement 10 and 11.5 with EventLog Analyzer
http://pubads.g.doubleclick.net/gampad/clk?id=154622311&iu=/4140/ostg.clktrk
_______________________________________________
Ltp-list mailing list
Ltp-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ltp-list

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

* Re: [LTP] [PATCH 2/2 v2] containers: added mountns/mountns04.c
  2014-08-29 13:47   ` [LTP] [PATCH 2/2 v2] " Matus Marhefka
  2014-09-04 14:21     ` Jan Stancek
@ 2014-09-24  8:14     ` chrubis
  1 sibling, 0 replies; 17+ messages in thread
From: chrubis @ 2014-09-24  8:14 UTC (permalink / raw)
  To: Matus Marhefka; +Cc: ltp-list

Hi!
> +static void setup(void)
> +{
> +	tst_require_root(NULL);
> +	check_newns();	/* from mountns_helper.h */

Please remove this comment.

> +	tst_tmpdir();
> +	SAFE_MKDIR(cleanup, DIRA, 0777);
> +	SAFE_MKDIR(cleanup, DIRB, 0777);
> +	SAFE_TOUCH(cleanup, DIRA"/A", 0, NULL);
> +	SAFE_TOUCH(cleanup, DIRB"/B", 0, NULL);
> +}
> +
> +static void test(void)
> +{
> +	/* unshares the mount ns */
> +	if (unshare(CLONE_NEWNS) == -1)
> +		tst_brkm(TBROK | TERRNO, cleanup, "unshare failed");
> +	/* makes sure mounts/umounts have no effect on a real system */
> +	SAFE_MOUNT(cleanup, "none", "/", "none", MS_REC|MS_PRIVATE, NULL);
> +
> +	/* bind mounts DIRA to itself */
> +	SAFE_MOUNT(cleanup, DIRA, DIRA, "none", MS_BIND, NULL);
> +	/* bind mounts DIRB to itself */
> +	SAFE_MOUNT(cleanup, DIRB, DIRB, "none", MS_BIND, NULL);
> +
> +	/* makes mount DIRA unbindable */
> +	SAFE_MOUNT(cleanup, "none", DIRA, "none", MS_UNBINDABLE, NULL);
> +	/* makes mount DIRB shared */
> +	SAFE_MOUNT(cleanup, "none", DIRB, "none", MS_SHARED, NULL);
> +
> +	/* tries to bind mount unbindable DIRA to DIRB which should fail */
> +	if (mount(DIRA, DIRB, "none", MS_BIND, NULL) == -1)
> +		tst_resm(TPASS, "unbindable mount passed");
> +	else {
> +		SAFE_UMOUNT(cleanup, DIRB);
> +		tst_resm(TFAIL, "unbindable mount faled");
> +	}

This is merely cosmetic, but LKML coding style preffers having curly
brackets on both branches if they needs to be over one of them.

> +#else /* MS_SHARED && MS_PRIVATE && MS_REC && MS_UNBINDABLE */

And the comment about ifdefs applies here as well.


Otherwise it looks good.

-- 
Cyril Hrubis
chrubis@suse.cz

------------------------------------------------------------------------------
Meet PCI DSS 3.0 Compliance Requirements with EventLog Analyzer
Achieve PCI DSS 3.0 Compliant Status with Out-of-the-box PCI DSS Reports
Are you Audit-Ready for PCI DSS 3.0 Compliance? Download White paper
Comply to PCI DSS 3.0 Requirement 10 and 11.5 with EventLog Analyzer
http://pubads.g.doubleclick.net/gampad/clk?id=154622311&iu=/4140/ostg.clktrk
_______________________________________________
Ltp-list mailing list
Ltp-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ltp-list

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

* Re: [LTP] [PATCH 1/2 v2] containers: added mountns/mountns03.c
       [not found]       ` <461070711.43439951.1411650253035.JavaMail.zimbra@redhat.com>
@ 2014-09-29  8:14         ` chrubis
  0 siblings, 0 replies; 17+ messages in thread
From: chrubis @ 2014-09-29  8:14 UTC (permalink / raw)
  To: Matus Marhefka; +Cc: ltp-list

Hi!
> I also prefer staying with defines.

Ok.

-- 
Cyril Hrubis
chrubis@suse.cz

------------------------------------------------------------------------------
Slashdot TV.  Videos for Nerds.  Stuff that Matters.
http://pubads.g.doubleclick.net/gampad/clk?id=160591471&iu=/4140/ostg.clktrk
_______________________________________________
Ltp-list mailing list
Ltp-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ltp-list

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

* [LTP] [PATCH 1/2 v3] containers: added mountns/mountns03.c
  2014-08-26  9:59 [LTP] [PATCH 1/2] containers: added mountns/mountns03.c Matus Marhefka
  2014-08-26  9:59 ` [LTP] [PATCH 2/2] containers: added mountns/mountns04.c Matus Marhefka
  2014-08-29 13:46 ` [LTP] [PATCH 1/2 v2] containers: added mountns/mountns03.c Matus Marhefka
@ 2014-10-02 12:28 ` Matus Marhefka
  2 siblings, 0 replies; 17+ messages in thread
From: Matus Marhefka @ 2014-10-02 12:28 UTC (permalink / raw)
  To: ltp-list

* Tests a slave mount: slave mount is like a shared mount except that
  mount and umount events only propagate towards it

Signed-off-by: Matus Marhefka <mmarhefk@redhat.com>
---
 runtest/containers                              |   1 +
 testcases/kernel/containers/.gitignore          |   1 +
 testcases/kernel/containers/mountns/mountns03.c | 179 ++++++++++++++++++++++++
 3 files changed, 181 insertions(+)
 create mode 100644 testcases/kernel/containers/mountns/mountns03.c

diff --git a/runtest/containers b/runtest/containers
index 56977c0..3653c9c 100644
--- a/runtest/containers
+++ b/runtest/containers
@@ -58,3 +58,4 @@ utstest_clone_5 utstest clone 5
 
 mountns01 mountns01
 mountns02 mountns02
+mountns03 mountns03
diff --git a/testcases/kernel/containers/.gitignore b/testcases/kernel/containers/.gitignore
index f175296..5b96cb9 100644
--- a/testcases/kernel/containers/.gitignore
+++ b/testcases/kernel/containers/.gitignore
@@ -1,3 +1,4 @@
 /check_for_unshare
 mountns/mountns01
 mountns/mountns02
+mountns/mountns03
diff --git a/testcases/kernel/containers/mountns/mountns03.c b/testcases/kernel/containers/mountns/mountns03.c
new file mode 100644
index 0000000..eb64581
--- /dev/null
+++ b/testcases/kernel/containers/mountns/mountns03.c
@@ -0,0 +1,179 @@
+/* Copyright (c) 2014 Red Hat, Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of version 2 the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ ***********************************************************************
+ * File: mountns03.c
+ *
+ * Tests a slave mount: slave mount is like a shared mount except that
+ * mount and umount events only propagate towards it.
+ *
+ * Description:
+ * 1. Creates directories "A", "B" and files "A/A", "B/B"
+ * 2. Unshares mount namespace and makes it private (so mounts/umounts
+ *    have no effect on a real system)
+ * 3. Bind mounts directory "A" to itself
+ * 4. Makes directory "A" shared
+ * 5. Clones a new child process with CLONE_NEWNS flag and makes "A"
+ *    a slave mount
+ * 6. There are two testcases (where X is parent namespace and Y child
+ *    namespace):
+ *    1)
+ *	X: bind mounts "B" to "A"
+ *	Y: must see the file "A/B"
+ *	X: umounts "A"
+ *    2)
+ *	Y: bind mounts "B" to "A"
+ *	X: must see only the "A/A" and must not see "A/B" (as slave
+ *	   mount does not forward propagation)
+ *	Y: umounts "A"
+ ***********************************************************************/
+
+#define _GNU_SOURCE
+#include <sys/wait.h>
+#include <sys/mount.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <errno.h>
+#include "test.h"
+#include "usctest.h"
+#include "libclone.h"
+#include "safe_macros.h"
+#include "safe_file_ops.h"
+#include "mountns_helper.h"
+
+
+char *TCID	= "mountns03";
+int TST_TOTAL	= 2;
+
+
+#if defined(MS_SHARED) && defined(MS_PRIVATE) \
+    && defined(MS_REC) && defined(MS_SLAVE)
+
+int child_func(void *arg)
+{
+	int ret = 0;
+
+	/* makes mount DIRA a slave of DIRA (all slave mounts have
+	 * a master mount which is a shared mount) */
+	if (mount("none", DIRA, "none", MS_SLAVE, NULL) == -1) {
+		perror("mount");
+		return 1;
+	}
+
+	TST_CHECKPOINT_SIGNAL_PARENT(&checkpoint1);
+	TST_CHECKPOINT_CHILD_WAIT(&checkpoint2);
+
+	/* checks that shared mounts propagates to slave mount */
+	if (access(DIRA"/B", F_OK) == -1)
+		ret = 2;
+
+	TST_CHECKPOINT_SIGNAL_PARENT(&checkpoint1);
+	TST_CHECKPOINT_CHILD_WAIT(&checkpoint2);
+
+	/* bind mounts DIRB to DIRA making contents of DIRB visible
+	 * in DIRA */
+	if (mount(DIRB, DIRA, "none", MS_BIND, NULL) == -1) {
+		perror("mount");
+		return 1;
+	}
+
+	TST_CHECKPOINT_SIGNAL_PARENT(&checkpoint1);
+	TST_CHECKPOINT_CHILD_WAIT(&checkpoint2);
+
+	umount(DIRA);
+	return ret;
+}
+
+static void test(void)
+{
+	int status;
+
+	/* unshares the mount ns */
+	if (unshare(CLONE_NEWNS) == -1)
+		tst_brkm(TBROK | TERRNO, cleanup, "unshare failed");
+	/* makes sure parent mounts/umounts have no effect on a real system */
+	SAFE_MOUNT(cleanup, "none", "/", "none", MS_REC|MS_PRIVATE, NULL);
+
+	/* bind mounts DIRA to itself */
+	SAFE_MOUNT(cleanup, DIRA, DIRA, "none", MS_BIND, NULL);
+
+	/* makes mount DIRA shared */
+	SAFE_MOUNT(cleanup, "none", DIRA, "none", MS_SHARED, NULL);
+
+	if (do_clone_tests(CLONE_NEWNS, child_func, NULL, NULL, NULL) == -1)
+		tst_brkm(TBROK | TERRNO, cleanup, "clone failed");
+
+	/* waits for child to make a slave mount */
+	TST_CHECKPOINT_PARENT_WAIT(cleanup, &checkpoint1);
+
+	/* bind mounts DIRB to DIRA making contents of DIRB visible
+	 * in DIRA */
+	SAFE_MOUNT(cleanup, DIRB, DIRA, "none", MS_BIND, NULL);
+
+	TST_CHECKPOINT_SIGNAL_CHILD(cleanup, &checkpoint2);
+	TST_CHECKPOINT_PARENT_WAIT(cleanup, &checkpoint1);
+
+	SAFE_UMOUNT(cleanup, DIRA);
+
+	TST_CHECKPOINT_SIGNAL_CHILD(cleanup, &checkpoint2);
+	TST_CHECKPOINT_PARENT_WAIT(cleanup, &checkpoint1);
+
+	/* checks that slave mount doesn't propagate to shared mount */
+	if ((access(DIRA"/A", F_OK) == 0) && (access(DIRA"/B", F_OK) == -1))
+		tst_resm(TPASS, "propagation from slave mount passed");
+	else
+		tst_resm(TFAIL, "propagation form slave mount failed");
+
+	TST_CHECKPOINT_SIGNAL_CHILD(cleanup, &checkpoint2);
+
+
+	SAFE_WAIT(cleanup, &status);
+	if (WIFEXITED(status)) {
+		if (WEXITSTATUS(status) == 0)
+			tst_resm(TPASS, "propagation to slave mount passed");
+		else
+			tst_resm(TFAIL, "propagation to slave mount failed");
+	}
+	if (WIFSIGNALED(status)) {
+		tst_resm(TBROK, "child was killed with signal %s",
+			 tst_strsig(WTERMSIG(status)));
+		return;
+	}
+
+	SAFE_UMOUNT(cleanup, DIRA);
+}
+
+int main(int argc, char *argv[])
+{
+	const char *msg;
+	int lc;
+
+	msg = parse_opts(argc, argv, NULL, NULL);
+	if (msg != NULL)
+		tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
+
+	setup();
+
+	for (lc = 0; TEST_LOOPING(lc); lc++)
+		test();
+
+	cleanup();
+	tst_exit();
+}
+
+#else
+int main(void)
+{
+	tst_brkm(TCONF, NULL, "needed mountflags are not defined");
+}
+#endif
-- 
1.8.3.1


------------------------------------------------------------------------------
Meet PCI DSS 3.0 Compliance Requirements with EventLog Analyzer
Achieve PCI DSS 3.0 Compliant Status with Out-of-the-box PCI DSS Reports
Are you Audit-Ready for PCI DSS 3.0 Compliance? Download White paper
Comply to PCI DSS 3.0 Requirement 10 and 11.5 with EventLog Analyzer
http://pubads.g.doubleclick.net/gampad/clk?id=154622311&iu=/4140/ostg.clktrk
_______________________________________________
Ltp-list mailing list
Ltp-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ltp-list

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

* [LTP] [PATCH 2/2 v3] containers: added mountns/mountns04.c
  2014-08-26  9:59 ` [LTP] [PATCH 2/2] containers: added mountns/mountns04.c Matus Marhefka
  2014-08-29 13:47   ` [LTP] [PATCH 2/2 v2] " Matus Marhefka
@ 2014-10-02 12:29   ` Matus Marhefka
  1 sibling, 0 replies; 17+ messages in thread
From: Matus Marhefka @ 2014-10-02 12:29 UTC (permalink / raw)
  To: ltp-list

* Tests an unbindable mount: unbindable mount is an unbindable
  private mount

Signed-off-by: Matus Marhefka <mmarhefk@redhat.com>
---
 runtest/containers                              |   1 +
 testcases/kernel/containers/.gitignore          |   1 +
 testcases/kernel/containers/mountns/mountns04.c | 103 ++++++++++++++++++++++++
 3 files changed, 105 insertions(+)
 create mode 100644 testcases/kernel/containers/mountns/mountns04.c

diff --git a/runtest/containers b/runtest/containers
index 3653c9c..8e8e067 100644
--- a/runtest/containers
+++ b/runtest/containers
@@ -59,3 +59,4 @@ utstest_clone_5 utstest clone 5
 mountns01 mountns01
 mountns02 mountns02
 mountns03 mountns03
+mountns04 mountns04
diff --git a/testcases/kernel/containers/.gitignore b/testcases/kernel/containers/.gitignore
index 5b96cb9..4a98373 100644
--- a/testcases/kernel/containers/.gitignore
+++ b/testcases/kernel/containers/.gitignore
@@ -2,3 +2,4 @@
 mountns/mountns01
 mountns/mountns02
 mountns/mountns03
+mountns/mountns04
diff --git a/testcases/kernel/containers/mountns/mountns04.c b/testcases/kernel/containers/mountns/mountns04.c
new file mode 100644
index 0000000..fe80e95
--- /dev/null
+++ b/testcases/kernel/containers/mountns/mountns04.c
@@ -0,0 +1,103 @@
+/* Copyright (c) 2014 Red Hat, Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of version 2 the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ ***********************************************************************
+ * File: mountns04.c
+ *
+ * Tests an unbindable mount: unbindable mount is an unbindable
+ * private mount.
+ * Description:
+ * 1. Creates directories "A", "B" and files "A/A", "B/B"
+ * 2. Unshares mount namespace and makes it private (so mounts/umounts
+ *    have no effect on a real system)
+ * 3. Bind mounts directory "A" to "A" and "B" to "B"
+ * 4. Makes directory "B" shared and directory "A" unbindable
+ * 5. Tries to bind mount unbindable "A" to "B":
+ *    - if it fails, test passes
+ *    - if it passes, test fails
+ ***********************************************************************/
+
+#define _GNU_SOURCE
+#include <sys/wait.h>
+#include <sys/mount.h>
+#include <stdio.h>
+#include <errno.h>
+#include "test.h"
+#include "usctest.h"
+#include "libclone.h"
+#include "safe_macros.h"
+#include "safe_file_ops.h"
+#include "mountns_helper.h"
+
+
+char *TCID	= "mountns04";
+int TST_TOTAL	= 1;
+
+
+#if defined(MS_SHARED) && defined(MS_PRIVATE) \
+    && defined(MS_REC) && defined(MS_UNBINDABLE)
+
+static void test(void)
+{
+	/* unshares the mount ns */
+	if (unshare(CLONE_NEWNS) == -1)
+		tst_brkm(TBROK | TERRNO, cleanup, "unshare failed");
+	/* makes sure mounts/umounts have no effect on a real system */
+	SAFE_MOUNT(cleanup, "none", "/", "none", MS_REC|MS_PRIVATE, NULL);
+
+	/* bind mounts DIRA to itself */
+	SAFE_MOUNT(cleanup, DIRA, DIRA, "none", MS_BIND, NULL);
+	/* bind mounts DIRB to itself */
+	SAFE_MOUNT(cleanup, DIRB, DIRB, "none", MS_BIND, NULL);
+
+	/* makes mount DIRA unbindable */
+	SAFE_MOUNT(cleanup, "none", DIRA, "none", MS_UNBINDABLE, NULL);
+	/* makes mount DIRB shared */
+	SAFE_MOUNT(cleanup, "none", DIRB, "none", MS_SHARED, NULL);
+
+	/* tries to bind mount unbindable DIRA to DIRB which should fail */
+	if (mount(DIRA, DIRB, "none", MS_BIND, NULL) == -1) {
+		tst_resm(TPASS, "unbindable mount passed");
+	} else {
+		SAFE_UMOUNT(cleanup, DIRB);
+		tst_resm(TFAIL, "unbindable mount faled");
+	}
+
+	SAFE_UMOUNT(cleanup, DIRA);
+	SAFE_UMOUNT(cleanup, DIRB);
+}
+
+int main(int argc, char *argv[])
+{
+	const char *msg;
+	int lc;
+
+	msg = parse_opts(argc, argv, NULL, NULL);
+	if (msg != NULL)
+		tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
+
+	setup();
+
+	for (lc = 0; TEST_LOOPING(lc); lc++)
+		test();
+
+	cleanup();
+	tst_exit();
+}
+
+#else
+int main(void)
+{
+	tst_brkm(TCONF, NULL, "needed mountflags are not defined");
+}
+#endif
-- 
1.8.3.1


------------------------------------------------------------------------------
Meet PCI DSS 3.0 Compliance Requirements with EventLog Analyzer
Achieve PCI DSS 3.0 Compliant Status with Out-of-the-box PCI DSS Reports
Are you Audit-Ready for PCI DSS 3.0 Compliance? Download White paper
Comply to PCI DSS 3.0 Requirement 10 and 11.5 with EventLog Analyzer
http://pubads.g.doubleclick.net/gampad/clk?id=154622311&iu=/4140/ostg.clktrk
_______________________________________________
Ltp-list mailing list
Ltp-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ltp-list

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

* Re: [LTP] [PATCH 2/2 v2] containers: added mountns/mountns04.c
  2014-09-04 14:21     ` Jan Stancek
@ 2014-10-02 13:47       ` Cyril Hrubis
       [not found]         ` <1080778288.46330076.1412258911538.JavaMail.zimbra@redhat.com>
  0 siblings, 1 reply; 17+ messages in thread
From: Cyril Hrubis @ 2014-10-02 13:47 UTC (permalink / raw)
  To: Jan Stancek; +Cc: ltp-list

Hi!
> Same question as for mountns03, is it necessary for B to be bind mounted
> to itself and shared?

I see that this part was removed from mountns03 but not from the latest
version of mountns04. Has this been resolved for mountns04?

-- 
Cyril Hrubis
chrubis@suse.cz

------------------------------------------------------------------------------
Meet PCI DSS 3.0 Compliance Requirements with EventLog Analyzer
Achieve PCI DSS 3.0 Compliant Status with Out-of-the-box PCI DSS Reports
Are you Audit-Ready for PCI DSS 3.0 Compliance? Download White paper
Comply to PCI DSS 3.0 Requirement 10 and 11.5 with EventLog Analyzer
http://pubads.g.doubleclick.net/gampad/clk?id=154622311&iu=/4140/ostg.clktrk
_______________________________________________
Ltp-list mailing list
Ltp-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ltp-list

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

* Re: [LTP] [PATCH 2/2 v2] containers: added mountns/mountns04.c
       [not found]         ` <1080778288.46330076.1412258911538.JavaMail.zimbra@redhat.com>
@ 2014-10-15 12:39           ` Cyril Hrubis
  0 siblings, 0 replies; 17+ messages in thread
From: Cyril Hrubis @ 2014-10-15 12:39 UTC (permalink / raw)
  To: Matus Marhefka; +Cc: ltp-list

Hi!
> Yes, mounting B is unnecessary and it does not affect the test result.
> The test() function can be simplified to:
> 
> static void test(void)
> {
>         /* unshares the mount ns */
>         if (unshare(CLONE_NEWNS) == -1)
>                 tst_brkm(TBROK | TERRNO, cleanup, "unshare failed");
>         /* makes sure mounts/umounts have no effect on a real system */
>         SAFE_MOUNT(cleanup, "none", "/", "none", MS_REC|MS_PRIVATE, NULL);
> 
>         /* bind mounts DIRA to itself */
>         SAFE_MOUNT(cleanup, DIRA, DIRA, "none", MS_BIND, NULL);
>         /* makes mount DIRA unbindable */
>         SAFE_MOUNT(cleanup, "none", DIRA, "none", MS_UNBINDABLE, NULL);
> 
>         /* tries to bind mount unbindable DIRA to DIRB which should fail */
>         if (mount(DIRA, DIRB, "none", MS_BIND, NULL) == -1) {
>                 tst_resm(TPASS, "unbindable mount passed");
>         } else {
>                 SAFE_UMOUNT(cleanup, DIRB);
>                 tst_resm(TFAIL, "unbindable mount faled");
>         }
> 
>         SAFE_UMOUNT(cleanup, DIRA);
> }

I've simplified the test function and updated the test description (in
the comment at the start of the file) and pushed, thanks.

-- 
Cyril Hrubis
chrubis@suse.cz

------------------------------------------------------------------------------
Comprehensive Server Monitoring with Site24x7.
Monitor 10 servers for $9/Month.
Get alerted through email, SMS, voice calls or mobile push notifications.
Take corrective actions from your mobile device.
http://p.sf.net/sfu/Zoho
_______________________________________________
Ltp-list mailing list
Ltp-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ltp-list

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

end of thread, other threads:[~2014-10-15 12:39 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-08-26  9:59 [LTP] [PATCH 1/2] containers: added mountns/mountns03.c Matus Marhefka
2014-08-26  9:59 ` [LTP] [PATCH 2/2] containers: added mountns/mountns04.c Matus Marhefka
2014-08-29 13:47   ` [LTP] [PATCH 2/2 v2] " Matus Marhefka
2014-09-04 14:21     ` Jan Stancek
2014-10-02 13:47       ` Cyril Hrubis
     [not found]         ` <1080778288.46330076.1412258911538.JavaMail.zimbra@redhat.com>
2014-10-15 12:39           ` Cyril Hrubis
2014-09-24  8:14     ` chrubis
2014-10-02 12:29   ` [LTP] [PATCH 2/2 v3] " Matus Marhefka
2014-08-29 13:46 ` [LTP] [PATCH 1/2 v2] containers: added mountns/mountns03.c Matus Marhefka
2014-09-04 14:13   ` Jan Stancek
2014-09-11 15:09     ` Jiri Jaburek
2014-09-12 12:59       ` Jan Stancek
2014-09-12 13:41         ` Jiri Jaburek
2014-09-12 14:19           ` Jan Stancek
2014-09-24  7:56   ` chrubis
     [not found]     ` <273164774.30346037.1411649870605.JavaMail.zimbra@redhat.com>
     [not found]       ` <461070711.43439951.1411650253035.JavaMail.zimbra@redhat.com>
2014-09-29  8:14         ` chrubis
2014-10-02 12:28 ` [LTP] [PATCH 1/2 v3] " Matus Marhefka

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.