[LTP] [PATCH] lib: tst_fd: Avoid tst_brk(TCONF, ...) on older distros
Cyril Hrubis
chrubis@suse.cz
Wed Jan 24 16:19:24 CET 2024
Hi!
> Actually, the solution I posted [1] works on both old (affected) kernel and new
> one:
>
> - fd->fd = syscall(__NR_pidfd_open, getpid(), 0);
> + fd->fd = tst_syscall(__NR_pidfd_open, getpid(), 0);
> if (fd->fd < 0)
> tst_brk(TBROK | TERRNO, "pidfd_open()");
This cannot work on kenrel that does not implement pidfd_open. That's
what the code in tst_syscall() does:
#define tst_syscall(NR, ...) ({ \
intptr_t tst_ret; \
if (NR == __LTP__NR_INVALID_SYSCALL) { \
errno = ENOSYS; \
tst_ret = -1; \
} else { \
tst_ret = syscall(NR, ##__VA_ARGS__); \
} \
if (tst_ret == -1 && errno == ENOSYS) { \
TST_SYSCALL_BRK__(NR, #NR); \
} \
tst_ret; \
})
This means that either if the syscall number is undefined or if the
actuall syscall fails with ENOSYS we call tst_brk(TCONF, ...) or
tst_brkm(TCONF, ...) on old API.
> I guess we should merge your solution (otherwise we would need to change other
> cases to be consistent), but I'm a bit confused. Is it the reason why we use
> syscall() + tst_res(TCONF) instead of tst_syscall() + tst_brk(TBROK) that for
> some cases it's expected to fail, thus TBROK is not accepted? Again, I was blind
> when doing review.
The problem is that if kernel does not implement a particular syscall
the tst_syscall() calls tst_brk() which ends the tst_fd iteration in the
middle. The tst_fd iterator just loop over different types of file
descriptors, if you call tst_brk() anywhere the test ends before we
managed to finish the loop. We do not want that to happen because of
either syscall not implemented in older kernels or syscalls disabled by
CONFIG options.
That's why we have to call syscall() and do tst_res(TCONF, ...) when the
syscall had failed. The tst_fd_next() will just continue with next fd
type if we failed to produce a valid fd.
--
Cyril Hrubis
chrubis@suse.cz
More information about the ltp
mailing list