Add two skip files for running the syscalls set of tests in compat.
One skips the tests failing because of Musl, the second the tests that
we skip or don't build at all.
Update the README to reflect those additions and explain how to use
the skip files.
Signed-off-by: Teo Couprie Diaz <teo.coupriediaz(a)arm.com>
---
v2:
- Removed mentions of COMPAT
- Reworded comment around Alpine
- Added bpf_prog02 to the musl skips after further testing
README.rst | 22 +++++++
runtest/syscalls_aarch64_pcuabi.skip | 96 ++++++++++++++++++++++++++++
runtest/syscalls_musl.skip | 17 +++++
3 files changed, 135 insertions(+)
create mode 100644 runtest/syscalls_aarch64_pcuabi.skip
create mode 100644 runtest/syscalls_musl.skip
diff --git a/README.rst b/README.rst
index 8b6e3a776..0c1646f46 100644
--- a/README.rst
+++ b/README.rst
@@ -136,6 +136,28 @@ Running tests:
runltp -f morello_transitional,morello_transitional_extended
+Skipping tests:
+---------------
+
+In certain cases, you might want to skip tests that are known to be failing or are yet to be supported.
+
+This is done by passing a file containing the names of the tests to be skip with the option ``-S`` to
+``runltp``.
+
+We currently provide the following skip files under ``runtest/``:
+ - ``syscalls_musl.skip``: Skips all tests failing on a regular Aarch64 Musl based system.
+ - ``syscalls_aarch64_pcuabi.skip``: Skips all tests not considered while testing plain Aarch64
+ with a PCuABI kernel.
+
+``runltp`` does not support passing multiple skip files, however this can be circumvented by using
+process substitution.
+
+For example, in plain Aarch64 on a Musl system with a PCuABI kernel to test all syscalls but skip all
+failures unrelated to the PCuABI kernel, one could run the following command:
+
+.. code-block::
+
+ ./runltp -f syscalls -S <( cat runtest/syscalls_{aarch64_pcuabi,musl}.skip )
Developers playground
---------------------
diff --git a/runtest/syscalls_aarch64_pcuabi.skip b/runtest/syscalls_aarch64_pcuabi.skip
new file mode 100644
index 000000000..be9712906
--- /dev/null
+++ b/runtest/syscalls_aarch64_pcuabi.skip
@@ -0,0 +1,96 @@
+# This skip file contains all the tests skipped from the syscalls command file
+# for testing the PCuABI kernel in plain Aarch64.
+
+# leapsec01 is skipped as systemd-timesyncd interfers with it and it doesn't
+# test any worthwhile functionality.
+leapsec01
+
+# We do not build most *_64 tests, skip them.
+posix_fadvise01_64
+posix_fadvise02_64
+posix_fadvise03_64
+posix_fadvise04_64
+fcntl01_64
+fcntl02_64
+fcntl03_64
+fcntl04_64
+fcntl05_64
+fcntl06_64
+fcntl07_64
+fcntl08_64
+fcntl09_64
+fcntl10_64
+fcntl11_64
+fcntl12_64
+fcntl13_64
+fcntl14_64
+fcntl15_64
+fcntl16_64
+fcntl17_64
+fcntl18_64
+fcntl19_64
+fcntl20_64
+fcntl21_64
+fcntl22_64
+fcntl23_64
+fcntl24_64
+fcntl25_64
+fcntl26_64
+fcntl27_64
+fcntl28_64
+fcntl29_64
+fcntl30_64
+fcntl31_64
+fcntl32_64
+fcntl33_64
+fcntl34_64
+fcntl35_64
+fcntl36_64
+fcntl37_64
+fcntl38_64
+fcntl39_64
+fstat02_64
+fstat03_64
+fstatfs01_64
+fstatfs02_64
+ftruncate01_64
+ftruncate03_64
+ftruncate04_64
+lstat01A_64
+lstat02_64
+pread01_64
+pread02_64
+preadv01_64
+preadv02_64
+preadv03_64
+preadv201_64
+preadv202_64
+preadv203_64
+pselect01_64
+pselect02_64
+pselect03_64
+pwrite01_64
+pwrite02_64
+pwrite03_64
+pwrite04_64
+pwritev01_64
+pwritev02_64
+pwritev03_64
+pwritev201_64
+pwritev202_64
+sendfile02_64
+sendfile03_64
+sendfile04_64
+sendfile05_64
+sendfile06_64
+sendfile07_64
+sendfile08_64
+sendfile09_64
+stat01_64
+stat02_64
+stat03_64
+statfs01_64
+statfs02_64
+statfs03_64
+truncate02_64
+truncate03_64
diff --git a/runtest/syscalls_musl.skip b/runtest/syscalls_musl.skip
new file mode 100644
index 000000000..016d2728c
--- /dev/null
+++ b/runtest/syscalls_musl.skip
@@ -0,0 +1,17 @@
+# All the following tests from the syscalls test list are failing in Aarch64
+# Musl-based systems (Alpine, Debian...). Thus they depend on Musl or LTP,
+# rather than the kernel, to be fixed.
+bpf_prog02
+gethostbyname_r01
+mq_open01
+nftw01
+nftw6401
+open13
+perf_event_open02
+recvmmsg01
+sbrk01
+sendmsg01
+setgroups03
+sigrelse01
+sigtimedwait01
+sigwaitinfo01
--
2.25.1
Add two skip files for running the syscalls set of tests in compat.
One skips the tests failing because of Musl, the second the tests that
we skip or don't build at all.
Update the README to reflect those additions and explain how to use
the skip files.
Signed-off-by: Teo Couprie Diaz <teo.coupriediaz(a)arm.com>
---
README.rst | 21 ++++++++
runtest/syscalls_compat.skip | 96 ++++++++++++++++++++++++++++++++++++
runtest/syscalls_musl.skip | 16 ++++++
3 files changed, 133 insertions(+)
create mode 100644 runtest/syscalls_compat.skip
create mode 100644 runtest/syscalls_musl.skip
diff --git a/README.rst b/README.rst
index 8b6e3a776..4efa6d38f 100644
--- a/README.rst
+++ b/README.rst
@@ -136,6 +136,27 @@ Running tests:
runltp -f morello_transitional,morello_transitional_extended
+Skipping tests:
+---------------
+
+In certain cases, you might want to skip tests that are known to be failing or are yet to be supported.
+
+This is done by passing a file containing the names of the tests to be skip with the option ``-S`` to
+``runltp``.
+
+We currently provide the following skip files under ``runtest/``:
+ - ``syscalls_musl.skip``: Skips all tests failing on a regular Aarch64 Musl based system.
+ - ``syscalls_compat.skip``: Skips all tests not considered for COMPAT64 with a PCuABI kernel.
+
+``runltp`` does not support passing multiple skip files, however this can be circumvented by using
+process substitution.
+
+For example, in COMPAT64 on a Musl system to test all syscalls but skip all known failures, one
+could run the following command:
+
+.. code-block::
+
+ ./runltp -f syscalls -S <( cat runtest/syscalls_{compat,musl}.skip )
Developers playground
---------------------
diff --git a/runtest/syscalls_compat.skip b/runtest/syscalls_compat.skip
new file mode 100644
index 000000000..b9af14a3a
--- /dev/null
+++ b/runtest/syscalls_compat.skip
@@ -0,0 +1,96 @@
+# This skip file contains all the tests skipped from the syscalls command file
+# for testing the PCuABI kernel in COMPAT64.
+
+# leapsec01 is skipped as systemd-timesyncd interfers with it and it doesn't
+# test any worthwhile functionality.
+leapsec01
+
+# We do not build most *_64 tests, skip them.
+posix_fadvise01_64
+posix_fadvise02_64
+posix_fadvise03_64
+posix_fadvise04_64
+fcntl01_64
+fcntl02_64
+fcntl03_64
+fcntl04_64
+fcntl05_64
+fcntl06_64
+fcntl07_64
+fcntl08_64
+fcntl09_64
+fcntl10_64
+fcntl11_64
+fcntl12_64
+fcntl13_64
+fcntl14_64
+fcntl15_64
+fcntl16_64
+fcntl17_64
+fcntl18_64
+fcntl19_64
+fcntl20_64
+fcntl21_64
+fcntl22_64
+fcntl23_64
+fcntl24_64
+fcntl25_64
+fcntl26_64
+fcntl27_64
+fcntl28_64
+fcntl29_64
+fcntl30_64
+fcntl31_64
+fcntl32_64
+fcntl33_64
+fcntl34_64
+fcntl35_64
+fcntl36_64
+fcntl37_64
+fcntl38_64
+fcntl39_64
+fstat02_64
+fstat03_64
+fstatfs01_64
+fstatfs02_64
+ftruncate01_64
+ftruncate03_64
+ftruncate04_64
+lstat01A_64
+lstat02_64
+pread01_64
+pread02_64
+preadv01_64
+preadv02_64
+preadv03_64
+preadv201_64
+preadv202_64
+preadv203_64
+pselect01_64
+pselect02_64
+pselect03_64
+pwrite01_64
+pwrite02_64
+pwrite03_64
+pwrite04_64
+pwritev01_64
+pwritev02_64
+pwritev03_64
+pwritev201_64
+pwritev202_64
+sendfile02_64
+sendfile03_64
+sendfile04_64
+sendfile05_64
+sendfile06_64
+sendfile07_64
+sendfile08_64
+sendfile09_64
+stat01_64
+stat02_64
+stat03_64
+statfs01_64
+statfs02_64
+statfs03_64
+truncate02_64
+truncate03_64
diff --git a/runtest/syscalls_musl.skip b/runtest/syscalls_musl.skip
new file mode 100644
index 000000000..92c952dac
--- /dev/null
+++ b/runtest/syscalls_musl.skip
@@ -0,0 +1,16 @@
+# All the following tests from the syscalls test list are failing in a standard
+# Aarch64 Musl-based distribution (Alpine Linux). Thus they depend on Musl
+# or LTP, rather than the kernel, to be fixed.
+gethostbyname_r01
+mq_open01
+nftw01
+nftw6401
+open13
+perf_event_open02
+recvmmsg01
+sbrk01
+sendmsg01
+setgroups03
+sigrelse01
+sigtimedwait01
+sigwaitinfo01
--
2.25.1
In some distributions, the two files used in lib/tst_pid.c are not
available, but cgroups still imposes a task limit far smaller than
the kernel pid_max.
If the cgroup sysfs is mounted, we can use it to retrieve the current task
limit imposed to the process. Implement the retrieval of this limit.
This can be done by first checking /proc/self/cgroup to get the cgroup
the process is in, which will be a path under the cgroup sysfs.
To get the path to the cgroup sysfs, check /proc/self/mountinfo.
Finally, concatenate those two paths with pid.max to get the full path
to the file containing the limit.
This patch changes the way read_session_pids_limit is called, not passing
a format string to be completed anymore, but is still used the same way.
A following patch will update this function.
This fixes failures for msgstress04.
Signed-off-by: Teo Couprie Diaz <teo.coupriediaz(a)arm.com>
---
lib/tst_pid.c | 53 +++++++++++++++++++++++++++++++++++++++++----------
1 file changed, 43 insertions(+), 10 deletions(-)
diff --git a/lib/tst_pid.c b/lib/tst_pid.c
index 21cadef2a..98f733d33 100644
--- a/lib/tst_pid.c
+++ b/lib/tst_pid.c
@@ -31,8 +31,6 @@
#include "tst_safe_macros.h"
#define PID_MAX_PATH "/proc/sys/kernel/pid_max"
-#define CGROUPS_V1_SLICE_FMT "/sys/fs/cgroup/pids/user.slice/user-%d.slice/pids.max"
-#define CGROUPS_V2_SLICE_FMT "/sys/fs/cgroup/user.slice/user-%d.slice/pids.max"
/* Leave some available processes for the OS */
#define PIDS_RESERVE 50
@@ -96,18 +94,53 @@ static int read_session_pids_limit(const char *path_fmt, int uid,
static int get_session_pids_limit(void (*cleanup_fn) (void))
{
- int max_pids, uid;
+ char path[PATH_MAX + 1];
+ char cgroup_pids[PATH_MAX + 1];
+ char catchall;
+ int uid, ret = 0;
uid = get_session_uid();
- max_pids = read_session_pids_limit(CGROUPS_V2_SLICE_FMT, uid, cleanup_fn);
- if (max_pids < 0)
- max_pids = read_session_pids_limit(CGROUPS_V1_SLICE_FMT, uid,
- cleanup_fn);
+ /* Check for generic cgroup v1 pid.max */
+ ret = FILE_LINES_SCANF(cleanup_fn, "/proc/self/cgroup",
+ "%*d:pids:%s\n", cgroup_pids);
+ /*
+ * This is a bit of a hack of scanf format strings. Indeed, if all
+ * conversion specifications have been matched the return of scanf will be
+ * the same whether any outstanding literal characters match or not.
+ * As we want to match the literal part, we can add a catchall after it
+ * so that it won't be counted if the literal part doesn't match.
+ * This makes the macro go to the next line until the catchall, thus
+ * the literal parts, is matched.
+ *
+ * Assume that the root of the mount is '/'. It can be anything,
+ * but it should be '/' on any normal system.
+ */
+ if (!ret)
+ ret = FILE_LINES_SCANF(cleanup_fn, "/proc/self/mountinfo",
+ "%*s %*s %*s %*s %s %*[^-] - cgroup %*s %*[rw],pid%c",
+ path, &catchall);
+
+ if (!ret) {
+ strncat(path, cgroup_pids, PATH_MAX);
+ strncat(path, "/pids.max", PATH_MAX);
+ return read_session_pids_limit(path, uid, cleanup_fn);
+ }
- if (max_pids < 0)
- return -1;
+ /* Check for generic cgroup v2 pid.max */
+ ret = FILE_LINES_SCANF(cleanup_fn, "/proc/self/cgroup",
+ "%*d::%s\n", cgroup_pids);
+ if (!ret)
+ ret = FILE_LINES_SCANF(cleanup_fn, "/proc/self/mountinfo",
+ "%*s %*s %*s %*s %s %*[^-] - cgroup2 %c",
+ path, &catchall);
+
+ if (!ret) {
+ strncat(path, cgroup_pids, PATH_MAX);
+ strncat(path, "/pids.max", PATH_MAX);
+ return read_session_pids_limit(path, uid, cleanup_fn);
+ }
- return max_pids;
+ return -1;
}
int tst_get_free_pids_(void (*cleanup_fn) (void))
--
2.25.1
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
Add 'tools/apicmds' to build targets to satisfy the dependency for
the tests that do rely on it. Namely: test_ioctl which, despite being
shell-based, does not follow the usual approach of using the test.sh test
library, instead relying on the legacy approach of using apicmds binaries.
It should be reworked to use the new framework at some point though.
Signed-off-by: Teo Couprie Diaz <teo.coupriediaz(a)arm.com>
---
README.rst | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/README.rst b/README.rst
index 4aebadd35..8b6e3a776 100644
--- a/README.rst
+++ b/README.rst
@@ -97,9 +97,9 @@ Assumptions:
*TRIPLE* & *MORELLO_SUPPORT* in `Building Musl`)
LTP_BUILD - out-of-tree build path (created by LTP's build.sh script if needed)
LTP_INSTALL - destination path where LTP tests are to be installed
- TARGETS - build targets, currently only pan and testcases/kernel/syscalls
- are supported, it can be further narrowed down for specific syscall
- testcases:
+ TARGETS - build targets, currently only pan, tools/apicmds and
+ testcases/kernel/syscalls are supported, it can be further narrowed
+ down for specific syscall testcases:
TARGETS="pan testcases/kernel/syscalls/${syscall}"
TARGET_FEATURE - morello+c64 (purecap) only: -march=morello+c64
@@ -117,7 +117,7 @@ Assumptions:
export CONFIGURE_OPT_EXTRA="--prefix=/ --host=aarch64-linux-gnu --disable-metadata --without-numa"
MAKE_OPTS="TST_NEWER_64_SYSCALL=no TST_COMPAT_16_SYSCALL=no" \
- TARGETS="pan testcases/kernel/syscalls" BUILD_DIR="$LTP_BUILD" \
+ TARGETS="pan tools/apicmds testcases/kernel/syscalls" BUILD_DIR="$LTP_BUILD" \
CFLAGS="$CFLAGS" LDFLAGS="$LDFLAGS" \
./build.sh -t cross -o out -ip "${LTP_INSTALL}"
--
2.25.1
In some distributions, the two files used in lib/tst_pid.c are not
available, but cgroups still imposes a task limit far smaller than
the kernel pid_max.
If the cgroup sysfs is mounted, we can use it to retrieve the current task
limit imposed to the process. Implement the retrieval of this limit.
This can be done by first checking /proc/self/cgroup to get the cgroup
the process is in, which will be a path under the cgroup sysfs.
To get the path to the cgroup sysfs, check /proc/self/mountinfo.
Finally, concatenate those two paths with pid.max to get the full path
to the file containing the limit.
This patch changes the way read_session_pids_limit is called, not passing
a format string to be completed anymore, but is still used the same way.
A following patch will update this function.
This fixes failures for msgstress04.
Signed-off-by: Teo Couprie Diaz <teo.coupriediaz(a)arm.com>
---
lib/tst_pid.c | 53 +++++++++++++++++++++++++++++++++++++++++----------
1 file changed, 43 insertions(+), 10 deletions(-)
diff --git a/lib/tst_pid.c b/lib/tst_pid.c
index 21cadef2a..f140acbc0 100644
--- a/lib/tst_pid.c
+++ b/lib/tst_pid.c
@@ -31,8 +31,6 @@
#include "tst_safe_macros.h"
#define PID_MAX_PATH "/proc/sys/kernel/pid_max"
-#define CGROUPS_V1_SLICE_FMT "/sys/fs/cgroup/pids/user.slice/user-%d.slice/pids.max"
-#define CGROUPS_V2_SLICE_FMT "/sys/fs/cgroup/user.slice/user-%d.slice/pids.max"
/* Leave some available processes for the OS */
#define PIDS_RESERVE 50
@@ -96,18 +94,53 @@ static int read_session_pids_limit(const char *path_fmt, int uid,
static int get_session_pids_limit(void (*cleanup_fn) (void))
{
- int max_pids, uid;
+ char path[PATH_MAX + 1];
+ char cgroup_pids[PATH_MAX + 1];
+ char catchall;
+ int uid, ret = 0;
uid = get_session_uid();
- max_pids = read_session_pids_limit(CGROUPS_V2_SLICE_FMT, uid, cleanup_fn);
- if (max_pids < 0)
- max_pids = read_session_pids_limit(CGROUPS_V1_SLICE_FMT, uid,
- cleanup_fn);
+ /* Check for generic cgroup v1 pid.max */
+ ret = FILE_LINES_SCANF(cleanup_fn, "/proc/self/cgroup",
+ "%*d:pids:%s\n", cgroup_pids);
+ /*
+ * This is a bit of a hack of scanf format strings. Indeed, if all
+ * conversion specifications have been matched the return of scanf will be
+ * the same whether any outstanding literal characters match or not.
+ * As we want to match the literal part, we can add a catchall after it
+ * so that it won't be counted if the literal part doesn't match.
+ * This makes the macro go to the next line until the catchall, thus
+ * the literal parts, is matched.
+ *
+ * Assume that the root of the mount is '/'. It can be anything,
+ * but it should be '/' on any normal system.
+ */
+ if (!ret)
+ ret = FILE_LINES_SCANF(cleanup_fn, "/proc/self/mountinfo",
+ "%*s %*s %*s %*s %s %*s %*s - %*s cgroup %*[rw],pid%c",
+ path, &catchall);
+
+ if (!ret) {
+ strncat(path, cgroup_pids, PATH_MAX);
+ strncat(path, "/pids.max", PATH_MAX);
+ return read_session_pids_limit(path, uid, cleanup_fn);
+ }
- if (max_pids < 0)
- return -1;
+ /* Check for generic cgroup v2 pid.max */
+ ret = FILE_LINES_SCANF(cleanup_fn, "/proc/self/cgroup",
+ "%*d::%s\n", cgroup_pids);
+ if (!ret)
+ ret = FILE_LINES_SCANF(cleanup_fn, "/proc/self/mountinfo",
+ "%*s %*s %*s %*s %s %*s %*s - cgroup2 %c",
+ path, &catchall);
+
+ if (!ret) {
+ strncat(path, cgroup_pids, PATH_MAX);
+ strncat(path, "/pids.max", PATH_MAX);
+ return read_session_pids_limit(path, uid, cleanup_fn);
+ }
- return max_pids;
+ return -1;
}
int tst_get_free_pids_(void (*cleanup_fn) (void))
--
2.25.1
In our debian-based distribution, the two files used in lib/tst_pid.c
are not available, but cgroups still imposes a task limit far smaller than
the kernel pid_max.
If the cgroup sysfs is mounted, we can use it to retrieve the current task
limit imposed to the process. Implement the retrieval of this limit.
This can be done by first checking /proc/self/cgroup to get the cgroup
the process is in, which will be a path under the cgroup sysfs.
To get the path to the cgroup sysfs, check /proc/self/mountinfo.
Finally, concatenate those two paths with pid.max to get the full path
to the file containing the limit.
This fixes failures for msgstress04.
Signed-off-by: Teo Couprie Diaz <teo.coupriediaz(a)arm.com>
---
Review branch as the changes are quite large:
https://git.morello-project.org/Teo-CD/morello-linux-ltp/-/commits/review/t…
lib/tst_pid.c | 55 ++++++++++++++++++++++++++++++++++++++++-----------
1 file changed, 44 insertions(+), 11 deletions(-)
diff --git a/lib/tst_pid.c b/lib/tst_pid.c
index 21cadef2a..ee3b98771 100644
--- a/lib/tst_pid.c
+++ b/lib/tst_pid.c
@@ -31,8 +31,6 @@
#include "tst_safe_macros.h"
#define PID_MAX_PATH "/proc/sys/kernel/pid_max"
-#define CGROUPS_V1_SLICE_FMT "/sys/fs/cgroup/pids/user.slice/user-%d.slice/pids.max"
-#define CGROUPS_V2_SLICE_FMT "/sys/fs/cgroup/user.slice/user-%d.slice/pids.max"
/* Leave some available processes for the OS */
#define PIDS_RESERVE 50
@@ -96,18 +94,53 @@ static int read_session_pids_limit(const char *path_fmt, int uid,
static int get_session_pids_limit(void (*cleanup_fn) (void))
{
- int max_pids, uid;
-
+ char path[PATH_MAX + 1];
+ char cgroup_pids[PATH_MAX + 1];
+ char catchall;
+ int uid, cgroup_ok = 0;
uid = get_session_uid();
- max_pids = read_session_pids_limit(CGROUPS_V2_SLICE_FMT, uid, cleanup_fn);
- if (max_pids < 0)
- max_pids = read_session_pids_limit(CGROUPS_V1_SLICE_FMT, uid,
- cleanup_fn);
- if (max_pids < 0)
- return -1;
+ /* Check for generic cgroup v1 pid.max */
+ cgroup_ok = FILE_LINES_SCANF(cleanup_fn, "/proc/self/cgroup",
+ "%*d :pids: %s\n", &cgroup_pids);
+ /*
+ * This is a bit of hack of scanf format strings. It only works forward
+ * which means that if a variable has been matched, but not a later
+ * part of the format it still counts as a match. Thus, we need a
+ * catch-all match later in the string that will _not_ be counted if
+ * the static part of the format doesn't match.
+ * This way, the macro will go on the next line rather than returning
+ * on a line matching the %s but not the static part later.
+ *
+ * Assume that the root of the mount is /. It can technically be anything,
+ * but it should be / on any normal system.
+ */
+ if (!cgroup_ok)
+ cgroup_ok = FILE_LINES_SCANF(cleanup_fn, "/proc/self/mountinfo",
+ "%*s %*s %*s %*s %s %*s %*s - %*s cgroup %*[rw],pid%c",
+ &path, &catchall);
+
+ if (!cgroup_ok) {
+ strncat(path, cgroup_pids, PATH_MAX);
+ strncat(path, "/pids.max", PATH_MAX);
+ return read_session_pids_limit(path, uid, cleanup_fn);
+ }
- return max_pids;
+ /* Check for generic cgroup v2 pid.max */
+ cgroup_ok = FILE_LINES_SCANF(cleanup_fn, "/proc/self/cgroup",
+ "%*d :: %s\n", &cgroup_pids);
+ if (!cgroup_ok)
+ cgroup_ok = FILE_LINES_SCANF(cleanup_fn, "/proc/self/mountinfo",
+ "%*s %*s %*s %*s %s %*s %*s - cgroup2 %c",
+ &path, &catchall);
+
+ if (!cgroup_ok) {
+ strncat(path, cgroup_pids, PATH_MAX);
+ strncat(path, "/pids.max", PATH_MAX);
+ return read_session_pids_limit(path, uid, cleanup_fn);
+ }
+
+ return -1;
}
int tst_get_free_pids_(void (*cleanup_fn) (void))
--
2.25.1
test_ioctl calls functions from the shell test framework but does not
source it.
For unexplained reasons this works on a regular LTP build, but not ours.
Source the framework to be able to successfully complete.
Signed-off-by: Teo Couprie Diaz <teo.coupriediaz(a)arm.com>
---
NB: This needs a change to the build script used for LTP fix the failure.
Indeed, the build framework is in the testcases/lib target which we
do not build by default, thus not making the framework available anyway.
testcases/kernel/syscalls/ioctl/test_ioctl | 2 ++
1 file changed, 2 insertions(+)
diff --git a/testcases/kernel/syscalls/ioctl/test_ioctl b/testcases/kernel/syscalls/ioctl/test_ioctl
index 923275433..cf960dd35 100755
--- a/testcases/kernel/syscalls/ioctl/test_ioctl
+++ b/testcases/kernel/syscalls/ioctl/test_ioctl
@@ -23,6 +23,8 @@ export TCID=ioctl01_02
export TST_TOTAL=2
export TST_COUNT=0
+. test.sh
+
has_tty()
{
if command -v stty >/dev/null 2>&1; then
--
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