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); }
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"); /* bind mounts DIRB to DIRA making contents of DIRB visible * in DIRA */ SAFE_MOUNT(cleanup, DIRB, DIRA, "none", MS_BIND, NULL); TST_SAFE_CHECKPOINT_WAKE_AND_WAIT(cleanup, 0); SAFE_UMOUNT(cleanup, DIRA); TST_SAFE_CHECKPOINT_WAKE_AND_WAIT(cleanup, 0); if (access(DIRA"/B", F_OK) == 0) tst_resm(TPASS, "shared mount in child passed"); else tst_resm(TFAIL, "shared mount in child failed"); TST_SAFE_CHECKPOINT_WAKE(cleanup, 0); SAFE_WAIT(cleanup, &status); if (WIFEXITED(status)) { if ((WEXITSTATUS(status) == 0)) tst_resm(TPASS, "shared mount in parent passed"); else tst_resm(TFAIL, "shared mount in parent failed"); } if (WIFSIGNALED(status)) { tst_resm(TBROK, "child was killed with signal %s", tst_strsig(WTERMSIG(status))); return; } SAFE_UMOUNT(cleanup, DIRA); }
int do_clone_unshare_test(int use_clone, unsigned long clone_flags, int (*fn1) (void *arg), void *arg1) { switch (use_clone) { case T_NONE: return do_plain_tests(fn1, arg1, NULL, NULL); case T_CLONE: return do_clone_tests(clone_flags, fn1, arg1, NULL, NULL); case T_UNSHARE: return do_unshare_tests(clone_flags, fn1, arg1, NULL, NULL); default: printf("%s: bad use_clone option: %d\n", __FUNCTION__, use_clone); return -1; } }