Musl and glibc syscall wrappers handles the null mq name in different
ways and report different errors. Glibc reports EINVAL error if the mq_name
is not preceded by "/" character but musl library does not treat this as an
error and invokes the kernel mq_open syscall which finally fails with
ENOENT error.
Introduce an alternative return error ENOENT so that this test passes with
musl library.
Signed-off-by: Amit Daniel Kachhap <amit.kachhap(a)arm.com>
---
changes in v3:
*) Retain the mq_open library call and add new error code for musl
failure as suggested by Beata.
testcases/kernel/syscalls/mq_open/mq_open01.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/testcases/kernel/syscalls/mq_open/mq_open01.c b/testcases/kernel/syscalls/mq_open/mq_open01.c
index cd2a229d8..8a229d298 100644
--- a/testcases/kernel/syscalls/mq_open/mq_open01.c
+++ b/testcases/kernel/syscalls/mq_open/mq_open01.c
@@ -34,6 +34,7 @@ struct test_case {
struct mq_attr *rq;
int ret;
int err;
+ int alt_err;
void (*setup)(void);
void (*cleanup)(void);
};
@@ -96,6 +97,7 @@ static struct test_case tcase[] = {
.oflag = O_CREAT,
.ret = -1,
.err = EINVAL,
+ .alt_err = ENOENT, /* Musl library reports this error for empty mqueue name */
},
{
.desc = "NORMAL",
@@ -260,9 +262,11 @@ static void do_test(unsigned int i)
}
if (TST_ERR != tc->err) {
- tst_res(TFAIL | TTERRNO, "%s expected errno: %d",
- tc->desc, TST_ERR);
- goto CLEANUP;
+ if (TST_ERR != tc->alt_err) {
+ tst_res(TFAIL | TTERRNO, "%s expected errno: %d",
+ tc->desc, TST_ERR);
+ goto CLEANUP;
+ }
}
if (TST_RET != tc->ret) {
--
2.25.1
We observed failures of the msgstress0{3,4} because they hit the PID
limit imposed by cgroup. This usually is not an issue as either:
- the system is fast enough for the threads to complete before hitting the limit,
- the PID limit is far higher than the number of threads started by the tests,
- there is no cgroup restricting the PID count further,
- the limit can be found in the cgroup user slice.
In the case of our distributions on the Morello boards, neither of those is true.
Indeed, the tasks do not complete fast enough to prevent hitting the limit,
the limit is quite low (4915 PIDs!) because of the low number of cores and the
default limit set by systemd of 15% per service, and the root user is not in its
own cgroup user-slice, rather under the serial or sshd service, depending on the
access method to the board.
This means that we needed to find a way in the test to find this limit. In this
patch, I implement it by checking /proc/self/cgroup and /proc/self/mountinfo to
find the cgroup imposing the PID limit as well as where the cgroup sysfs is
mounted, if it is.
This has proven more reliable than the previous patch's implementation and more
stable, however it is still imperfect in a few ways:
- it cannot find the limit if the cgroup sysfs is not mounted,
- it assumes only one cgroup imposing limits (might be OK),
- it assumes the cgroup is the one with the limit (it might be set by a parent
cgroup),
- it assumes the mountinfo peer groups are consistent across systems.
It also introduces a few warings as I use a #define to set the array lengths,
which cannot be used in the format string to limit the number of characters.
An alternate solution could be implemented by writing a shell script parsing this
data directly and passing it as an argument to the affected tests. See for
example runtest/cap_bounds or runtest/commands.
But this implies changing each affected tests.
To note, upstream is aware that those tests are quite broken[0]. There was a
patch series updating them but it was never followed-through.
As this is not really Morello related, rather it is directly linked to the tests
and the systems they are run on, this change might be shelved undefinitely.
Thanks a lot to Beata for the help while investigating this !
[0]: https://lists.linux.it/pipermail/ltp/2022-January/027163.html
Teo Couprie Diaz (1):
lib/tst_pid: Find cgroup pid.max programatically
lib/tst_pid.c | 43 +++++++++++++++++++
.../syscalls/ipc/msgstress/msgstress03.c | 2 +-
2 files changed, 44 insertions(+), 1 deletion(-)
--
2.25.1
Musl and glibc syscall wrappers handles the null mq name in different
ways and report different errors. Glibc reports error if the mq_name
is not preceded by "/" character but musl does not treat this as an error.
Avoid the syscall wrapper by calling the syscall directly. This needs
skipping the leading "/" character in mq_name as expected by the kernel.
Signed-off-by: Amit Daniel Kachhap <amit.kachhap(a)arm.com>
---
Changes in v3:
* Updated commit messages for musl and glibc as pointed by Beata.
testcases/kernel/syscalls/mq_open/mq_open01.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/testcases/kernel/syscalls/mq_open/mq_open01.c b/testcases/kernel/syscalls/mq_open/mq_open01.c
index cd2a229d8..06858991e 100644
--- a/testcases/kernel/syscalls/mq_open/mq_open01.c
+++ b/testcases/kernel/syscalls/mq_open/mq_open01.c
@@ -14,6 +14,7 @@
#include "tst_test.h"
#include "tst_safe_file_ops.h"
#include "tst_safe_posix_ipc.h"
+#include "lapi/syscalls.h"
#define QUEUE_NAME "/test_mqueue"
#define QUEUE_INIT "/init_mqueue"
@@ -95,7 +96,7 @@ static struct test_case tcase[] = {
.qname = "",
.oflag = O_CREAT,
.ret = -1,
- .err = EINVAL,
+ .err = ENOENT,
},
{
.desc = "NORMAL",
@@ -228,7 +229,10 @@ static void do_test(unsigned int i)
if (tc->setup)
tc->setup();
- TEST(fd = mq_open(qname, tc->oflag, S_IRWXU, tc->rq));
+ if (*qname == '/')
+ TEST(fd = tst_syscall(__NR_mq_open, qname + 1, tc->oflag, S_IRWXU, tc->rq));
+ else
+ TEST(fd = tst_syscall(__NR_mq_open, qname, tc->oflag, S_IRWXU, tc->rq));
if (fd > 0 && tc->rq) {
if (mq_getattr(fd, &oldattr) < 0) {
--
2.25.1
This fixes two tests that were failing in our debian distribution because
of a PID limit imposed by systemd which was not properly detected.
This was fixed by adding another file to read the max_pid from that should
be available everywhere.
This worked for msgstress04, but doing some testing msgstress03 still hit
the limit. Printing the number of PIDs in use, it seems like msgstress03
had some accounting issues, the real number of PIDs in use always being
5-10% greater than what it thought it was.
Not finding where this accounting error was, I reduced the number of
free PIDs by 10% which proved to do the trick.
I'm not too sure about these solutions and would be happy to receive some
feedback, hence the RFC state.
(It might make sense to split the patch as well, but it would be two very
small diffs.)
Thanks in advance !
Teo Couprie Diaz (1):
lib/tst_pid: Add a new file to get pid_max
lib/tst_pid.c | 4 ++++
testcases/kernel/syscalls/ipc/msgstress/msgstress03.c | 2 +-
2 files changed, 5 insertions(+), 1 deletion(-)
--
2.25.1