This patch updates the existing test that checks for `open(O_TMPFILE)` and `linkat()` behaviors in mount namespaces to use the kselftest framework.
This includes the following changes:
- Replaced direct error handling with `ksft_test_result_*` macros for better reporting of test outcomes.
- Added `ksft_print_header()` and `ksft_set_plan()` to structure test outputs more effectively.
- Introduced the helper function `is_unshare()` to handle unshare-related checks.
- Improved the test flow by adding more detailed pass/fail reporting for unshare, mounting, file opening, and linking operations.
- Skips the test if it's not run as root, providing an appropriate Warning.
Test logs:
Before change:
- Withou root error: unshare, errno 1
- With root No, output
After change:
- Without root TAP version 13 1..1 ok 1 # SKIP This test needs root to ru
- With root TAP version 13 1..1 ok 1 unshare(): we have a new mount namespace. 1..2 ok 2 mount(): Root filesystem private mount: Success 1..3 ok 3 mount(): Mounting tmpfs on /tmp: Success 1..4 ok 4 openat(): Open first temporary file: Success 1..5 ok 5 linkat(): Linking the temporary file: Success 1..6 ok 6 openat(): Opening the second temporary file: Success # Totals: pass:6 fail:0 xfail:0 xpass:0 skip:0 error:0
Signed-off-by: Shivam Chaudhary cvam0000@gmail.com --- .../selftests/tmpfs/bug-link-o-tmpfile.c | 72 +++++++++++++++---- 1 file changed, 58 insertions(+), 14 deletions(-)
diff --git a/tools/testing/selftests/tmpfs/bug-link-o-tmpfile.c b/tools/testing/selftests/tmpfs/bug-link-o-tmpfile.c index b5c3ddb90942..26dea19c1614 100644 --- a/tools/testing/selftests/tmpfs/bug-link-o-tmpfile.c +++ b/tools/testing/selftests/tmpfs/bug-link-o-tmpfile.c @@ -23,45 +23,89 @@ #include <sys/mount.h> #include <unistd.h>
-int main(void) -{ - int fd; +#include "../kselftest.h"
- if (unshare(CLONE_NEWNS) == -1) { +static int is_unshare(int flag) +{ + if (unshare(flag) == -1) { if (errno == ENOSYS || errno == EPERM) { - fprintf(stderr, "error: unshare, errno %d\n", errno); - return 4; + ksft_test_result_fail("error: unshare, errno %d\n", errno); + return -1; // Return -1 for failure } fprintf(stderr, "error: unshare, errno %d\n", errno); + return -1; + } + + return 0; // Return 0 for success +} + +int main(void) +{ + int fd; + + // Setting up kselftest framework + ksft_print_header(); + ksft_set_plan(1); + + // Check if test is run as root + if (geteuid()) { + ksft_test_result_skip("This test needs root to run!\n"); return 1; } - if (mount(NULL, "/", NULL, MS_PRIVATE|MS_REC, NULL) == -1) { - fprintf(stderr, "error: mount '/', errno %d\n", errno); + + if (is_unshare(CLONE_NEWNS) == 0) { + ksft_test_result_pass("unshare(): we have a new mount namespace.\n"); + } else { + ksft_test_result_fail("unshare(): failed\n"); return 1; }
+ ksft_set_plan(2); + + if (mount(NULL, "/", NULL, MS_PRIVATE | MS_REC, NULL) == -1) { + ksft_test_result_fail("mount(): Root filesystem private mount: Fail %d\n", errno); + return 1; + } else { + ksft_test_result_pass("mount(): Root filesystem private mount: Success\n"); + } + + ksft_set_plan(3); /* Our heroes: 1 root inode, 1 O_TMPFILE inode, 1 permanent inode. */ if (mount(NULL, "/tmp", "tmpfs", 0, "nr_inodes=3") == -1) { - fprintf(stderr, "error: mount tmpfs, errno %d\n", errno); + ksft_test_result_fail("mount(): Mounting tmpfs on /tmp: Fail %d\n", errno); return 1; + } else { + ksft_test_result_pass("mount(): Mounting tmpfs on /tmp: Success\n"); }
- fd = openat(AT_FDCWD, "/tmp", O_WRONLY|O_TMPFILE, 0600); + ksft_set_plan(4); + fd = openat(AT_FDCWD, "/tmp", O_WRONLY | O_TMPFILE, 0600); if (fd == -1) { - fprintf(stderr, "error: open 1, errno %d\n", errno); + ksft_test_result_fail("openat(): Open first temporary file: Fail %d\n", errno); return 1; + } else { + ksft_test_result_pass("openat(): Open first temporary file: Success\n"); } + + ksft_set_plan(5); if (linkat(fd, "", AT_FDCWD, "/tmp/1", AT_EMPTY_PATH) == -1) { - fprintf(stderr, "error: linkat, errno %d\n", errno); + ksft_test_result_fail("linkat(): Linking the temporary file: Fail %d\n", errno); + close(fd); // Ensure fd is closed on failure return 1; + } else { + ksft_test_result_pass("linkat(): Linking the temporary file: Success\n"); } close(fd);
- fd = openat(AT_FDCWD, "/tmp", O_WRONLY|O_TMPFILE, 0600); + ksft_set_plan(6); + fd = openat(AT_FDCWD, "/tmp", O_WRONLY | O_TMPFILE, 0600); if (fd == -1) { - fprintf(stderr, "error: open 2, errno %d\n", errno); + ksft_test_result_fail("openat(): Opening the second temporary file: Fail %d\n", errno); return 1; + } else { + ksft_test_result_pass("openat(): Opening the second temporary file: Success\n"); }
+ ksft_exit_pass(); return 0; }
On 10/24/24 10:55, Shivam Chaudhary wrote:
This patch updates the existing test that checks for `open(O_TMPFILE)` and `linkat()` behaviors in mount namespaces to use the kselftest framework.
This includes the following changes:
- Replaced direct error handling with `ksft_test_result_*` macros for better reporting of test outcomes.
Replace
Added `ksft_print_header()` and `ksft_set_plan()` to structure test outputs more effectively.
Introduced the helper function `is_unshare()` to handle unshare-related checks.
Introduce
- Improved the test flow by adding more detailed pass/fail reporting for unshare, mounting, file opening, and linking operations.
Improve
- Skips the test if it's not run as root, providing an appropriate Warning.
Check submitting patches document for details how to write short log and change log that hep reviewers.
Also - you haven't cc'ed the right mailing lists. Send v2 cc'ing kselftest mailing list and correcting the short log and change log problems.
Test logs:
Before change:
Withou root error: unshare, errno 1
With root No, output
After change:
Without root TAP version 13 1..1 ok 1 # SKIP This test needs root to ru
With root TAP version 13 1..1 ok 1 unshare(): we have a new mount namespace. 1..2 ok 2 mount(): Root filesystem private mount: Success 1..3 ok 3 mount(): Mounting tmpfs on /tmp: Success 1..4 ok 4 openat(): Open first temporary file: Success 1..5 ok 5 linkat(): Linking the temporary file: Success 1..6 ok 6 openat(): Opening the second temporary file: Success # Totals: pass:6 fail:0 xfail:0 xpass:0 skip:0 error:0
Signed-off-by: Shivam Chaudhary cvam0000@gmail.com
.../selftests/tmpfs/bug-link-o-tmpfile.c | 72 +++++++++++++++---- 1 file changed, 58 insertions(+), 14 deletions(-)
diff --git a/tools/testing/selftests/tmpfs/bug-link-o-tmpfile.c b/tools/testing/selftests/tmpfs/bug-link-o-tmpfile.c index b5c3ddb90942..26dea19c1614 100644 --- a/tools/testing/selftests/tmpfs/bug-link-o-tmpfile.c +++ b/tools/testing/selftests/tmpfs/bug-link-o-tmpfile.c @@ -23,45 +23,89 @@ #include <sys/mount.h> #include <unistd.h> -int main(void) -{
- int fd;
+#include "../kselftest.h"
- if (unshare(CLONE_NEWNS) == -1) {
+static int is_unshare(int flag) +{
- if (unshare(flag) == -1) { if (errno == ENOSYS || errno == EPERM) {
fprintf(stderr, "error: unshare, errno %d\n", errno);
return 4;
ksft_test_result_fail("error: unshare, errno %d\n", errno);
} fprintf(stderr, "error: unshare, errno %d\n", errno);return -1; // Return -1 for failure
return -1;
- }
- return 0; // Return 0 for success
+}
+int main(void) +{
- int fd;
- // Setting up kselftest framework
- ksft_print_header();
- ksft_set_plan(1);
- // Check if test is run as root
- if (geteuid()) {
return 1; }ksft_test_result_skip("This test needs root to run!\n");
- if (mount(NULL, "/", NULL, MS_PRIVATE|MS_REC, NULL) == -1) {
fprintf(stderr, "error: mount '/', errno %d\n", errno);
- if (is_unshare(CLONE_NEWNS) == 0) {
ksft_test_result_pass("unshare(): we have a new mount namespace.\n");
- } else {
return 1; }ksft_test_result_fail("unshare(): failed\n");
- ksft_set_plan(2);
- if (mount(NULL, "/", NULL, MS_PRIVATE | MS_REC, NULL) == -1) {
ksft_test_result_fail("mount(): Root filesystem private mount: Fail %d\n", errno);
return 1;
- } else {
ksft_test_result_pass("mount(): Root filesystem private mount: Success\n");
- }
- ksft_set_plan(3); /* Our heroes: 1 root inode, 1 O_TMPFILE inode, 1 permanent inode. */ if (mount(NULL, "/tmp", "tmpfs", 0, "nr_inodes=3") == -1) {
fprintf(stderr, "error: mount tmpfs, errno %d\n", errno);
return 1;ksft_test_result_fail("mount(): Mounting tmpfs on /tmp: Fail %d\n", errno);
- } else {
}ksft_test_result_pass("mount(): Mounting tmpfs on /tmp: Success\n");
- fd = openat(AT_FDCWD, "/tmp", O_WRONLY|O_TMPFILE, 0600);
- ksft_set_plan(4);
- fd = openat(AT_FDCWD, "/tmp", O_WRONLY | O_TMPFILE, 0600); if (fd == -1) {
fprintf(stderr, "error: open 1, errno %d\n", errno);
return 1;ksft_test_result_fail("openat(): Open first temporary file: Fail %d\n", errno);
- } else {
}ksft_test_result_pass("openat(): Open first temporary file: Success\n");
- ksft_set_plan(5); if (linkat(fd, "", AT_FDCWD, "/tmp/1", AT_EMPTY_PATH) == -1) {
fprintf(stderr, "error: linkat, errno %d\n", errno);
ksft_test_result_fail("linkat(): Linking the temporary file: Fail %d\n", errno);
return 1;close(fd); // Ensure fd is closed on failure
- } else {
} close(fd);ksft_test_result_pass("linkat(): Linking the temporary file: Success\n");
- fd = openat(AT_FDCWD, "/tmp", O_WRONLY|O_TMPFILE, 0600);
- ksft_set_plan(6);
- fd = openat(AT_FDCWD, "/tmp", O_WRONLY | O_TMPFILE, 0600); if (fd == -1) {
fprintf(stderr, "error: open 2, errno %d\n", errno);
return 1;ksft_test_result_fail("openat(): Opening the second temporary file: Fail %d\n", errno);
- } else {
}ksft_test_result_pass("openat(): Opening the second temporary file: Success\n");
- ksft_exit_pass(); return 0; }
Add kselftest support for open, linkat, unshare, mount tests
- Replace direct error handling with `ksft_test_result_*` macros for better reporting of test outcomes.
- Add `ksft_print_header()` and `ksft_set_plan()` to structure test outputs more effectively.
- Introduce the helper function `is_unshare()` to handle unshare() related checks.
- Improve the test flow by adding more detailed pass/fail reporting for unshare, mounting, file opening, and linking operations.
- Skip the test if it's not run as root, providing an appropriate Warning.
Test logs:
Before change:
- Without root error: unshare, errno 1
- With root No, output
After change:
- Without root TAP version 13 1..1 ok 1 # SKIP This test needs root to run
- With root TAP version 13 1..1 ok 1 unshare(): we have a new mount namespace. 1..2 ok 2 mount(): Root filesystem private mount: Success 1..3 ok 3 mount(): Mounting tmpfs on /tmp: Success 1..4 ok 4 openat(): Open first temporary file: Success 1..5 ok 5 linkat(): Linking the temporary file: Success 1..6 ok 6 openat(): Opening the second temporary file: Success # Totals: pass:6 fail:0 xfail:0 xpass:0 skip:0 error:0
Signed-off-by: Shivam Chaudhary cvam0000@gmail.com --- Changes in v2: - Make the commit message more clear.
.../selftests/tmpfs/bug-link-o-tmpfile.c | 72 +++++++++++++++---- 1 file changed, 58 insertions(+), 14 deletions(-)
diff --git a/tools/testing/selftests/tmpfs/bug-link-o-tmpfile.c b/tools/testing/selftests/tmpfs/bug-link-o-tmpfile.c index b5c3ddb90942..26dea19c1614 100644 --- a/tools/testing/selftests/tmpfs/bug-link-o-tmpfile.c +++ b/tools/testing/selftests/tmpfs/bug-link-o-tmpfile.c @@ -23,45 +23,89 @@ #include <sys/mount.h> #include <unistd.h>
-int main(void) -{ - int fd; +#include "../kselftest.h"
- if (unshare(CLONE_NEWNS) == -1) { +static int is_unshare(int flag) +{ + if (unshare(flag) == -1) { if (errno == ENOSYS || errno == EPERM) { - fprintf(stderr, "error: unshare, errno %d\n", errno); - return 4; + ksft_test_result_fail("error: unshare, errno %d\n", errno); + return -1; // Return -1 for failure } fprintf(stderr, "error: unshare, errno %d\n", errno); + return -1; + } + + return 0; // Return 0 for success +} + +int main(void) +{ + int fd; + + // Setting up kselftest framework + ksft_print_header(); + ksft_set_plan(1); + + // Check if test is run as root + if (geteuid()) { + ksft_test_result_skip("This test needs root to run!\n"); return 1; } - if (mount(NULL, "/", NULL, MS_PRIVATE|MS_REC, NULL) == -1) { - fprintf(stderr, "error: mount '/', errno %d\n", errno); + + if (is_unshare(CLONE_NEWNS) == 0) { + ksft_test_result_pass("unshare(): we have a new mount namespace.\n"); + } else { + ksft_test_result_fail("unshare(): failed\n"); return 1; }
+ ksft_set_plan(2); + + if (mount(NULL, "/", NULL, MS_PRIVATE | MS_REC, NULL) == -1) { + ksft_test_result_fail("mount(): Root filesystem private mount: Fail %d\n", errno); + return 1; + } else { + ksft_test_result_pass("mount(): Root filesystem private mount: Success\n"); + } + + ksft_set_plan(3); /* Our heroes: 1 root inode, 1 O_TMPFILE inode, 1 permanent inode. */ if (mount(NULL, "/tmp", "tmpfs", 0, "nr_inodes=3") == -1) { - fprintf(stderr, "error: mount tmpfs, errno %d\n", errno); + ksft_test_result_fail("mount(): Mounting tmpfs on /tmp: Fail %d\n", errno); return 1; + } else { + ksft_test_result_pass("mount(): Mounting tmpfs on /tmp: Success\n"); }
- fd = openat(AT_FDCWD, "/tmp", O_WRONLY|O_TMPFILE, 0600); + ksft_set_plan(4); + fd = openat(AT_FDCWD, "/tmp", O_WRONLY | O_TMPFILE, 0600); if (fd == -1) { - fprintf(stderr, "error: open 1, errno %d\n", errno); + ksft_test_result_fail("openat(): Open first temporary file: Fail %d\n", errno); return 1; + } else { + ksft_test_result_pass("openat(): Open first temporary file: Success\n"); } + + ksft_set_plan(5); if (linkat(fd, "", AT_FDCWD, "/tmp/1", AT_EMPTY_PATH) == -1) { - fprintf(stderr, "error: linkat, errno %d\n", errno); + ksft_test_result_fail("linkat(): Linking the temporary file: Fail %d\n", errno); + close(fd); // Ensure fd is closed on failure return 1; + } else { + ksft_test_result_pass("linkat(): Linking the temporary file: Success\n"); } close(fd);
- fd = openat(AT_FDCWD, "/tmp", O_WRONLY|O_TMPFILE, 0600); + ksft_set_plan(6); + fd = openat(AT_FDCWD, "/tmp", O_WRONLY | O_TMPFILE, 0600); if (fd == -1) { - fprintf(stderr, "error: open 2, errno %d\n", errno); + ksft_test_result_fail("openat(): Opening the second temporary file: Fail %d\n", errno); return 1; + } else { + ksft_test_result_pass("openat(): Opening the second temporary file: Success\n"); }
+ ksft_exit_pass(); return 0; }
linux-kselftest-mirror@lists.linaro.org