!24 【内核子系统】【master】升级ltp代码

Merge pull request !24 from 李猛/kernel_lite_20220629_01_master
This commit is contained in:
openharmony_ci
2022-07-04 06:53:47 +00:00
committed by Gitee
9726 changed files with 171553 additions and 119797 deletions
-114
View File
@@ -1,114 +0,0 @@
# Copyright (c) 2017-2020 Petr Vorel <pvorel@suse.cz>
sudo: required
language: c
services:
- docker
matrix:
include:
# 32 bit build
- os: linux
env: DISTRO=debian:stable VARIANT=i386
compiler: gcc
# cross compilation builds
- os: linux
env: DISTRO=debian:stable VARIANT=cross-compile ARCH=ppc64el TREE=out MAKE_INSTALL=1
compiler: powerpc64le-linux-gnu-gcc
- os: linux
env: DISTRO=debian:stable VARIANT=cross-compile ARCH=arm64 TREE=out
compiler: aarch64-linux-gnu-gcc
- os: linux
env: DISTRO=debian:stable VARIANT=cross-compile ARCH=s390x TREE=out
compiler: s390x-linux-gnu-gcc
# musl (native)
- os: linux
# Message: WARNING: xsltproc: cannot process http://docbook.sourceforge.net/release/xsl-ns/current/manpages/docbook.xsl
# doc/meson.build:70:1: ERROR: Problem encountered: Docs cannot be built: xsltproc does not work correctly
env: DISTRO=alpine:latest
compiler: gcc
# build with minimal dependencies
- os: linux
env: DISTRO=debian:stable VARIANT=minimal TREE=out
compiler: clang
# native non-intel
- os: linux
arch: ppc64le
compiler: gcc
env: DISTRO=debian:testing
# other builds
- os: linux
env: DISTRO=fedora:rawhide MAKE_INSTALL=1
compiler: clang
- os: linux
env: DISTRO=centos:6 TREE=out
compiler: gcc
- os: linux
env: DISTRO=debian:testing
compiler: gcc
- os: linux
env: DISTRO=debian:oldstable
compiler: clang
- os: linux
env: DISTRO=opensuse/tumbleweed
compiler: gcc
- os: linux
env: DISTRO=opensuse/leap
compiler: gcc
- os: linux
env: DISTRO=debian:oldstable
compiler: gcc
- os: linux
env: DISTRO=debian:testing
compiler: clang
- os: linux
env: DISTRO=ubuntu:eoan TREE=out
compiler: gcc
- os: linux
env: DISTRO=ubuntu:xenial
compiler: gcc
- os: linux
env: DISTRO=centos:latest
compiler: gcc
before_install:
- df -hT
- DIR="/usr/src/ltp"
- printf "FROM $DISTRO\nRUN mkdir -p $DIR\nWORKDIR $DIR\nCOPY . $DIR\n" > Dockerfile
- cat Dockerfile
- docker build -t ltp .
script:
- INSTALL="${DISTRO%%:*}"
- INSTALL="${INSTALL%%/*}"
- if [ "$MAKE_INSTALL" = 1 ]; then INSTALL_OPT="-i"; fi
- if [ ! "$TREE" ]; then TREE="in"; fi
- case $VARIANT in cross-compile*) BUILD="cross";; i386) BUILD="32";; *) BUILD="native";; esac
# Tumbleweed requires newer Docker version
- >
if [ "${DISTRO//*\/}" = "tumbleweed" -o "$INSTALL" = "fedora" ]; then
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository "deb [arch=$(dpkg --print-architecture)] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
sudo apt-get update
sudo apt-get -y -o Dpkg::Options::="--force-confnew" install docker-ce
fi
- docker run -t ltp /bin/sh -c "cd travis && ./$INSTALL.sh && if [ \"$VARIANT\" ]; then ARCH=\"$ARCH\" ./$INSTALL.$VARIANT.sh; fi && ../build.sh -o $TREE -t $BUILD -c $CC $INSTALL_OPT"
Regular → Executable
View File
Regular → Executable
+28 -66
View File
@@ -1,20 +1,23 @@
Requirements
-------------------
------------
Tools are needed for LTP compilation. They should be available as a
package in any Linux distribution (no specific version is required).
Debian / Ubuntu
# apt install gcc git make pkgconf autoconf automake bison flex m4 linux-headers-$(uname -r) libc6-dev
OpenSUSE / SLES
# zypper install gcc git make pkgconf autoconf automake bison flex m4 linux-glibc-devel glibc-devel
# apt install gcc git make pkgconf autoconf automake bison flex m4 linux-headers-$(uname -r) libc6-dev
openSUSE / SLES
# zypper install gcc git make pkg-config autoconf automake bison flex m4 linux-glibc-devel glibc-devel
Fedora / CentOS / RHEL
# yum install gcc git make pkgconf autoconf automake bison flex m4 kernel-headers glibc-headers
# yum install gcc git make pkgconf autoconf automake bison flex m4 kernel-headers glibc-headers
These are minimal build requirements for git compilation. Some tests require
extra development files of some libraries, see travis/*.sh. There is also
extra development files of some libraries, see ci/*.sh. There is also
support for other Linux distributions not listed here.
autoconf, automake, m4 (autoconf requirement), git and pkgconf (or pkg-config
@@ -27,14 +30,14 @@ does automatic detection of some library support.
GNU Bison / Berkeley Yacc is required for ltp-scanner.
Configuration
-------------------
-------------
Configuration requires autoconf:
$ cd $TOP_SRCDIR
$ make autotools
$ mkdir -p $TOP_BUILDDIR
$ cd $TOP_BUILDDIR && ./configure # configure args go here, e.g. CC=$CC, LDFLAGS=$LDFLAGS, etc
$ cd $TOP_BUILDDIR && $TOP_SRCDIR/configure # configure args go here, e.g. CC=$CC, LDFLAGS=$LDFLAGS, etc
- $TOP_SRCDIR and $TOP_BUILDDIR are the same for in-build-tree scenarios.
- $TOP_SRCDIR and $TOP_BUILDDIR differ for out-of-build-tree scenarios.
@@ -43,10 +46,11 @@ See the In-build-tree and Out-of-build-tree sections below for more details on
what to do next.
Compiling LTP
-------------------
-------------
In-build-tree
-------------------
-------------
In-build-tree support is when you build binaries (applications, binary objects)
in the same directory where the source files reside.
@@ -71,7 +75,8 @@ following information,
iii. config.log
Out-of-build-tree
-------------------
-----------------
Out-of-build-tree support is when you build binaries (applications, binary
objects, generated files) outside of the directory where the source files
reside. This is typically used when cross-compiling for multiple targets.
@@ -103,12 +108,12 @@ items which need fixing in the LTP tree.
Quick Start
-----------
1> tar xzf ltp-XXXXXXXX.tar.gz
2> cd ltp
3> ./configure
4> make all
5> make install
6> /opt/ltp/runltp
$ tar xzf ltp-XXXXXXXX.tar.gz
$ cd ltp
$ ./configure
$ make all
# make install
$ /opt/ltp/runltp
*NOTE:
- LTP assumes the existence of the nobody, bin, and daemon users and their
@@ -146,56 +151,11 @@ contributions are welcome.
in the CD-ROM drive. The corresponding tests will fail if either disk is
missing.
5. The network tests are executed by running the network.sh script. The network
tests require some configuration for them to work correctly:
i) First, there MUST be another test machine setup to act as the server
to these client side tests. This machine MUST have the LTP installed
in the same exact location, i.e. if the client has /root/ltp, then the
server must have /root/ltp. This is required because certain tests
expect to find server files in certain locations. Make sure to compile
the LTP on this server machine also.
ii) Second, the server must be setup to allow the client to connect using
the "r" commands, such as rsh. This is done by simply creating/editing
the ".rhosts" file under /root. Place the hostname of the client
machine in this file to allow root to remotely connect without the use
of a password. If server has the PAM system security tool, you need
to add the following lines to /etc/securetty:
rlogin
rsh
rexec
pts/0
pts/1
:
pts/9
iii) Next, certain services must be activated in order for certain tests to
execute. The following services are activated via inetd/xinetd:
rlogind
ftpd
telnetd
echo (stream)
fingerd
rshd
Also, because certain RPC programs are tested, the "portmapper" daemon
MUST be started, as well as NFS server AND lock services.
iv) Finally, before running the network.sh script, two variables must be
set: The "RHOST" variable should be set to the hostname of the server.
The "PASSWD" variable should be set to root's password on the server
machine. This is necessary for tests such as telnet01.sh and ftp01.sh.
You can now successfully execute the network.sh script.
You can run the test category which you are interested in, -h option shows
the list of the test category:
# ./network.sh -h
For more info about howto run network.sh see testcases/network/README.md.
5. The network tests related installation see testcases/network/README.md.
Cross compiling
---------------
To cross compile, you must specify the correct variables when running configure.
e.g. CC, LDFLAGS, etc.
For correct pkgconf / pkg-config detection you need to set
@@ -207,6 +167,7 @@ command-line when running make.
32 bit build on 64 bit machine
------------------------------
You need to set CFLAGS=-m32 LDFLAGS=-m32 and PKG_CONFIG_LIBDIR
* RPM based distributions (openSUSE, Fedora, etc.)
@@ -220,13 +181,14 @@ PKG_CONFIG_LIBDIR=/usr/lib32/pkgconfig CFLAGS=-m32 LDFLAGS=-m32 ./configure
Android Users
-------------
Specify ANDROID=1 when calling make. Many tests which would otherwise work are
currently not built because they share a directory with an incompatible test.
The shell scripts expect /bin/sh to exist, so create a symlink.
Variables in Makefile
----------------------
---------------------
The conventions enforced are standard ones. Here's a quick summary:
@@ -245,7 +207,7 @@ For other variables and more info about the build systems see
doc/build-system-guide.txt.
Common Issues
----------------------
-------------
Issue: When executing configure it says:
Regular → Executable
+39 -7
View File
@@ -1,8 +1,8 @@
#
# Top-level Makefile for LTP. See INSTALL for more info.
#
# Copyright (C) 2009-2010, Cisco Systems Inc.
# Copyright (C) 2010-2011, Linux Test Project.
# Copyright (c) Linux Test Project, 2009-2020
# Copyright (c) Cisco Systems Inc., 2009-2010
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -62,7 +62,8 @@ $(1):: | $$(abs_top_builddir)/$$(basename $$(subst -,.,$(1)))
endif
endef
COMMON_TARGETS += testcases tools
COMMON_TARGETS += testcases tools metadata
# Don't want to nuke the original files if we're installing in-build-tree.
ifneq ($(BUILD_TREE_STATE),$(BUILD_TREE_SRCDIR_INSTALL))
INSTALL_TARGETS += runtest scenario_groups testscripts
@@ -75,6 +76,7 @@ BOOTSTRAP_TARGETS := $(sort $(COMMON_TARGETS) $(CLEAN_TARGETS) $(INSTALL_TARGETS
CLEAN_TARGETS := $(addsuffix -clean,$(CLEAN_TARGETS))
INSTALL_TARGETS := $(addsuffix -install,$(INSTALL_TARGETS))
MAKE_TARGETS := $(addsuffix -all,$(filter-out lib,$(COMMON_TARGETS)))
CHECK_TARGETS := $(addsuffix -check,testcases lib)
# There's no reason why we should run `all' twice. Otherwise we're just wasting
# 3+ mins of useful CPU cycles on a modern machine, and even more time on an
@@ -89,11 +91,7 @@ include-install: $(top_builddir)/include/config.h include/mk/config.mk include-a
INSTALL_DIR := $(DESTDIR)/$(prefix)
# DO NOT REMOVE THIS CALL (see clean_install_dir call below...)!!!!
ifdef MAKE_3_80_COMPAT
INSTALL_DIR := $(call MAKE_3_80_abspath,$(INSTALL_DIR))
else
INSTALL_DIR := $(abspath $(INSTALL_DIR))
endif
# build tree bootstrap targets and $(INSTALL_DIR) target.
$(sort $(addprefix $(abs_top_builddir)/,$(BOOTSTRAP_TARGETS)) $(INSTALL_DIR) $(DESTDIR)/$(bindir)):
@@ -108,6 +106,10 @@ $(MAKE_TARGETS) include-all lib-all libs-all:
$(MAKE) -C "$(subst -all,,$@)" \
-f "$(abs_top_srcdir)/$(subst -all,,$@)/Makefile" all
$(CHECK_TARGETS): tools-all
$(MAKE) -C "$(subst -check,,$@)" \
-f "$(abs_top_srcdir)/$(subst -check,,$@)/Makefile" check
# Let's not conflict with ac-clean, maintainer-clean, etc, so.
$(filter-out include-clean,$(CLEAN_TARGETS))::
-$(MAKE) -C "$(subst -clean,,$@)" \
@@ -189,9 +191,39 @@ INSTALL_TARGETS += $(addprefix $(DESTDIR)/$(bindir)/,$(BINDIR_INSTALL_SCRIPTS))
$(INSTALL_TARGETS): $(INSTALL_DIR) $(DESTDIR)/$(bindir)
.PHONY: check
check: $(CHECK_TARGETS)
## Install
install: $(INSTALL_TARGETS)
## Test
define _test
@set -e; $(top_srcdir)/lib/newlib_tests/runtest.sh -b $(abs_builddir) $(1)
endef
test: lib-all
ifneq ($(build),$(host))
$(error running tests on cross-compile build not supported)
endif
$(call _test)
$(MAKE) test-metadata
test-c: lib-all
ifneq ($(build),$(host))
$(error running tests on cross-compile build not supported)
endif
$(call _test,-c)
test-shell: lib-all
ifneq ($(build),$(host))
$(error running tests on cross-compile build not supported)
endif
$(call _test,-s)
test-metadata: metadata-all
$(MAKE) -C $(abs_srcdir)/metadata/ test
## Help
.PHONY: help
help:
Regular → Executable
View File
Executable → Regular
+5
View File
@@ -62,6 +62,10 @@ Note:If the text contains special characters, please escape them according to th
<policyitem type="compatibility" name="GPLStyleLicense" path="testcases/open_posix_testsuite/.*.*" desc="Independent process running."/>
<policyitem type="compatibility" name="GPL-2.0+" path="testcases/open_posix_testsuite/.*.*" desc="Independent process running."/>
<policyitem type="compatibility" name="GPL-2.0-or-later" path="testcases/open_posix_testsuite/.*.*" desc="Independent process running."/>
<policyitem type="compatibility" name="GPL-2.0-or-later" path="libs/.*.*" desc="Independent process running."/>
<policyitem type="compatibility" name="GPL-2.0-or-later" path="lib/.*.*" desc="Independent process running."/>
<policyitem type="compatibility" name="GPL-2.0-or-later" path="docparse/.*.*" desc="Independent process running."/>
<policyitem type="compatibility" name="GPL-2.0-or-later" path="metadata/.*.*" desc="Independent process running."/>
</policy>
</policylist>
@@ -70,6 +74,7 @@ Note:If the text contains special characters, please escape them according to th
<filteritem type="filepath" name="doc/.*.*" desc="not used in ohos"/>
<filteritem type="filepath" name="include/.*" desc="not used in ohos"/>
<filteritem type="filepath" name="lib/.*" desc="not used in ohos"/>
<filteritem type="filepath" name="libs/.*" desc="not used in ohos"/>
<filteritem type="filepath" name="m4/.*" desc="not used in ohos"/>
<filteritem type="filepath" name="pan/.*" desc="not used in ohos"/>
<filteritem type="filepath" name="scripts/.*" desc="not used in ohos"/>
+1 -1
View File
@@ -3,7 +3,7 @@
"Name" : "ltp",
"License" : "GPL V2.0",
"License File" : "COPYING",
"Version Number" : "20200515",
"Version Number" : "20220121",
"Owner" : "liuxun@huawei.com",
"Upstream URL" : "https://github.com/linux-test-project/ltp",
"Description" : "The LTP testsuite contains a collection of tools for testing the Linux kernel and related features."
Regular → Executable
+6 -8
View File
@@ -39,7 +39,7 @@ Quick guide to running the tests
If you have git, autoconf, automake, m4, pkgconf / pkg-config, libc headers,
linux kernel headers and other common development packages installed (see
INSTALL and travis/*.sh), the chances are the following will work:
INSTALL and ci/*.sh), the chances are the following will work:
```
$ git clone https://github.com/linux-test-project/ltp.git
@@ -52,7 +52,7 @@ Now you can continue either with compiling and running a single test or with
compiling and installing the whole testsuite.
For optional library dependencies look into scripts for major distros in
`travis/` directory. You can also build whole LTP with `./build.sh` script.
`ci/` directory. You can also build whole LTP with `./build.sh` script.
Shortcut to running a single test
---------------------------------
@@ -178,8 +178,7 @@ https://github.com/linux-test-project/ltp/wiki/User-Guidelines.
Network tests
-------------
Network tests require certain setup, described in `testcases/network/README.md`
(online at https://github.com/linux-test-project/ltp/tree/master/testcases/network)
and `INSTALL`.
(online at https://github.com/linux-test-project/ltp/tree/master/testcases/network).
Developers corner
=================
@@ -204,8 +203,7 @@ list. Also note that these documents are available online at:
Although we accept GitHub pull requests, the preferred way is sending patches to our mailing list.
It's a good idea to test patches on Travis CI before posting to mailing
list. Our travis setup covers various architectures and distributions in
It's a good idea to test patches on GitHub Actions before posting to mailing
list. Our GitHub Actions setup covers various architectures and distributions in
order to make sure LTP compiles cleanly on most common configurations.
For testing you need to sign up to Travis CI, enable running builds on your LTP fork on
https://travis-ci.org/account/repositories and push your branch.
For testing you need to just to push your changes to your own LTP fork on GitHub.
Regular → Executable
View File
Regular → Executable
+1 -1
View File
@@ -1 +1 @@
20200515
20220121
+178 -113
View File
@@ -1,113 +1,33 @@
#!/bin/sh
# Copyright (c) 2017-2018 Petr Vorel <pvorel@suse.cz>
# Script for travis builds.
#
# TODO: Implement comparison of installed files. List of installed files can
# be used only for local builds as Travis currently doesn't support sharing
# file between jobs, see
# https://github.com/travis-ci/travis-ci/issues/6054
# Copyright (c) 2017-2021 Petr Vorel <pvorel@suse.cz>
# Script for CI builds.
set -e
CFLAGS="${CFLAGS:--Werror=implicit-function-declaration -fno-common}"
CFLAGS="${CFLAGS:--Wformat -Werror=format-security -Werror=implicit-function-declaration -Werror=return-type -fno-common}"
CC="${CC:-gcc}"
DEFAULT_PREFIX="$HOME/ltp-install"
DEFAULT_BUILD="native"
DEFAULT_TREE="in"
CONFIGURE_OPTS_IN_TREE="--with-open-posix-testsuite --with-realtime-testsuite"
CONFIGURE_OPTS_IN_TREE="--with-open-posix-testsuite --with-realtime-testsuite $CONFIGURE_OPT_EXTRA"
# TODO: open posix testsuite is currently broken in out-tree-build. Enable it once it's fixed.
CONFIGURE_OPTS_OUT_TREE="--with-realtime-testsuite"
CONFIGURE_OPTS_OUT_TREE="--with-realtime-testsuite $CONFIGURE_OPT_EXTRA"
SRC_DIR="$(cd $(dirname $0); pwd)"
BUILD_DIR="$SRC_DIR/../ltp-build"
MAKE_OPTS="-j$(getconf _NPROCESSORS_ONLN)"
build_32()
{
echo "===== 32-bit ${1}-tree build into $PREFIX ====="
CFLAGS="-m32 $CFLAGS" LDFLAGS="-m32 $LDFLAGS"
build $1 $2
}
build_native()
{
echo "===== native ${1}-tree build into $PREFIX ====="
build $1 $2
}
build_cross()
{
local host="${CC%-gcc}"
[ -n "$host" ] || \
{ echo "Missing CC variable, pass it with -c option." >&2; exit 1; }
echo "===== cross-compile ${host} ${1}-tree build into $PREFIX ====="
build $1 $2 "--host=$host" CROSS_COMPILE="${host}-"
}
build()
{
local tree="$1"
local install="$2"
shift 2
echo "=== autotools ==="
make autotools
if [ "$tree" = "in" ]; then
build_in_tree $install $@
else
build_out_tree $install $@
fi
}
build_out_tree()
{
local install="$1"
shift
local tree="$PWD"
local build="$tree/../ltp-build"
local make_opts="$MAKE_OPTS -C $build -f $tree/Makefile top_srcdir=$tree top_builddir=$build"
mkdir -p $build
cd $build
run_configure $tree/configure $CONFIGURE_OPTS_OUT_TREE $@
echo "=== build ==="
make $make_opts
if [ "$install" = 1 ]; then
echo "=== install ==="
make $make_opts DESTDIR="$PREFIX" SKIP_IDCHECK=1 install
else
echo "make install skipped, use -i to run it"
fi
}
build_in_tree()
{
local install="$1"
shift
run_configure ./configure $CONFIGURE_OPTS_IN_TREE --prefix=$PREFIX $@
echo "=== build ==="
make $MAKE_OPTS
if [ "$install" = 1 ]; then
echo "=== install ==="
make $MAKE_OPTS install
else
echo "make install skipped, use -i to run it"
fi
}
MAKE_OPTS_OUT_TREE="$MAKE_OPTS -C $BUILD_DIR -f $SRC_DIR/Makefile top_srcdir=$SRC_DIR top_builddir=$BUILD_DIR"
run_configure()
{
local configure=$1
local configure="$1"
shift
export CC CFLAGS LDFLAGS
echo "CC='$CC' CFLAGS='$CFLAGS' LDFLAGS='$LDFLAGS'"
export CC CFLAGS LDFLAGS PKG_CONFIG_LIBDIR
echo "CC='$CC' CFLAGS='$CFLAGS' LDFLAGS='$LDFLAGS' PKG_CONFIG_LIBDIR='$PKG_CONFIG_LIBDIR'"
echo "=== configure $configure $@ ==="
if ! $configure $@; then
@@ -120,16 +40,118 @@ run_configure()
cat include/config.h
}
configure_in_tree()
{
run_configure ./configure $CONFIGURE_OPTS_IN_TREE --prefix=$prefix $@
}
configure_out_tree()
{
mkdir -p $BUILD_DIR
cd $BUILD_DIR
run_configure $SRC_DIR/configure $CONFIGURE_OPTS_OUT_TREE $@
}
configure_32()
{
local tree="$1"
local prefix="$2"
local arch="$(uname -m)"
local dir
echo "===== 32-bit ${tree}-tree build into $prefix ====="
if [ -z "$PKG_CONFIG_LIBDIR" ]; then
if [ "$arch" != "x86_64" ]; then
echo "ERROR: auto-detection not supported platform $arch, export PKG_CONFIG_LIBDIR!"
exit 1
fi
for dir in /usr/lib/i386-linux-gnu/pkgconfig \
/usr/lib32/pkgconfig /usr/lib/pkgconfig; do
if [ -d "$dir" ]; then
PKG_CONFIG_LIBDIR="$dir"
break
fi
done
if [ -z "$PKG_CONFIG_LIBDIR" ]; then
echo "WARNING: PKG_CONFIG_LIBDIR not found, build might fail"
fi
fi
CFLAGS="-m32 $CFLAGS" LDFLAGS="-m32 $LDFLAGS"
eval configure_${tree}_tree
}
configure_native()
{
local tree="$1"
local prefix="$2"
echo "===== native ${tree}-tree build into $prefix ====="
eval configure_${tree}_tree
}
configure_cross()
{
local tree="$1"
local prefix="$2"
local host=$(basename "${CC%-gcc}")
if [ "$host" = "gcc" ]; then
echo "Invalid CC variable for cross compilation: $CC (clang not supported)" >&2
exit 1
fi
echo "===== cross-compile ${host} ${1}-tree build into $prefix ====="
eval configure_${tree}_tree "--host=$host"
}
build_in_tree()
{
make $MAKE_OPTS
}
build_out_tree()
{
cd $BUILD_DIR
make $MAKE_OPTS_OUT_TREE
}
test_in_tree()
{
make $1
}
test_out_tree()
{
cd $BUILD_DIR
make $MAKE_OPTS_OUT_TREE $1
}
install_in_tree()
{
make $MAKE_OPTS install
}
install_out_tree()
{
cd $BUILD_DIR
make $MAKE_OPTS_OUT_TREE DESTDIR="$prefix" SKIP_IDCHECK=1 install
}
usage()
{
cat << EOF
Usage:
$0 [ -c CC ] [ -o TREE ] [ -p DIR ] [ -t TYPE ]
$0 [ -c CC ] [ -i ] [ -o TREE ] [ -p DIR ] [-r RUN ] [ -t TYPE ]
$0 -h
Options:
-h Print this help
-c CC Define compiler (\$CC variable)
-c CC Define compiler (\$CC variable), needed only for configure step
-i Run 'make install', needed only for install step
-o TREE Specify build tree, default: $DEFAULT_TREE
-p DIR Change installation directory. For in-tree build is this value passed
to --prefix option of configure script. For out-of-tree build is this
@@ -138,25 +160,42 @@ Options:
DIR/PREFIX (i.e. DIR/opt/ltp).
Default for in-tree build: '$DEFAULT_PREFIX'
Default for out-of-tree build: '$DEFAULT_PREFIX/opt/ltp'
-t TYPE Specify build type, default: $DEFAULT_BUILD
-r RUN Run only certain step (usable for CI), default: all
-t TYPE Specify build type, default: $DEFAULT_BUILD, only for configure step
BUILD TREE:
TREE:
in in-tree build
out out-of-tree build
BUILD TYPES:
32 32-bit in-tree build
cross cross-compile in-tree build (requires set compiler via -c switch)
native native in-tree build
TYPES:
32 32-bit build (PKG_CONFIG_LIBDIR auto-detection for x86_64)
cross cross-compile build (requires set compiler via -c switch)
native native build
RUN:
autotools run only 'make autotools'
configure run only 'configure'
build run only 'make'
test run only 'make test' (not supported for cross-compile build)
test-c run only 'make test-c' (not supported for cross-compile build)
test-shell run only 'make test-shell' (not supported for cross-compile build)
install run only 'make install'
Default configure options:
in-tree: $CONFIGURE_OPTS_IN_TREE
out-of-tree $CONFIGURE_OPTS_OUT_TREE
configure options can extend the default with \$CONFIGURE_OPT_EXTRA environment variable
EOF
}
PREFIX="$DEFAULT_PREFIX"
prefix="$DEFAULT_PREFIX"
build="$DEFAULT_BUILD"
tree="$DEFAULT_TREE"
install=0
install=
run=
while getopts "c:hio:p:t:" opt; do
while getopts "c:hio:p:r:t:" opt; do
case "$opt" in
c) CC="$OPTARG";;
h) usage; exit 0;;
@@ -165,7 +204,11 @@ while getopts "c:hio:p:t:" opt; do
in|out) tree="$OPTARG";;
*) echo "Wrong build tree '$OPTARG'" >&2; usage; exit 1;;
esac;;
p) PREFIX="$OPTARG";;
p) prefix="$OPTARG";;
r) case "$OPTARG" in
autotools|configure|build|test|test-c|test-shell|install) run="$OPTARG";;
*) echo "Wrong run type '$OPTARG'" >&2; usage; exit 1;;
esac;;
t) case "$OPTARG" in
32|cross|native) build="$OPTARG";;
*) echo "Wrong build type '$OPTARG'" >&2; usage; exit 1;;
@@ -174,13 +217,35 @@ while getopts "c:hio:p:t:" opt; do
esac
done
cd `dirname $0`
cd $SRC_DIR
echo "=== ver_linux ==="
./ver_linux
echo
if [ -z "$run" -o "$run" = "autotools" ]; then
make autotools
fi
echo "=== compiler version ==="
$CC --version
if [ -z "$run" -o "$run" = "configure" ]; then
eval configure_$build $tree $prefix
fi
eval build_$build $tree $install
if [ -z "$run" -o "$run" = "build" ]; then
echo "=== build ==="
eval build_${tree}_tree
fi
if [ -z "$run" -o "$run" = "test" -o "$run" = "test-c" -o "$run" = "test-shell" ]; then
if [ "$build" = "cross" ]; then
echo "cross-compile build, skipping running tests" >&2
else
eval test_${tree}_tree $run
fi
fi
if [ -z "$run" -o "$run" = "install" ]; then
if [ "$install" = 1 ]; then
eval install_${tree}_tree
else
echo "make install skipped, use -i to run it"
fi
fi
exit $?
+8 -7
View File
@@ -1,15 +1,18 @@
#!/bin/sh
# Copyright (c) 2019-2020 Petr Vorel <petr.vorel@gmail.com>
# Copyright (c) 2019-2021 Petr Vorel <petr.vorel@gmail.com>
set -ex
apk update
apk add \
acl-dev \
asciidoc \
asciidoctor \
autoconf \
automake \
clang \
gcc \
git \
keyutils-dev \
libaio-dev \
libacl \
@@ -22,21 +25,19 @@ apk add \
musl-dev \
numactl-dev \
openssl-dev \
perl-json \
pkgconfig
cat /etc/os-release
echo "WARNING: remove unsupported tests (until they're fixed)"
cd ..
cd $(dirname $0)/..
rm -rfv \
testcases/kernel/sched/process_stress/process.c \
testcases/kernel/syscalls/confstr/confstr01.c \
testcases/kernel/syscalls/fmtmsg/fmtmsg01.c \
testcases/kernel/syscalls/getcontext/getcontext01.c \
testcases/kernel/syscalls/getdents/getdents01.c \
testcases/kernel/syscalls/getdents/getdents02.c \
testcases/kernel/syscalls/rt_tgsigqueueinfo/rt_tgsigqueueinfo01.c \
testcases/kernel/syscalls/timer_create/timer_create01.c \
testcases/kernel/syscalls/timer_create/timer_create03.c \
utils/benchmark/ebizzy-0.3
testcases/kernel/syscalls/timer_create/timer_create03.c
cd -
View File
@@ -11,7 +11,7 @@ case "$ARCH" in
arm64) gcc_arch="aarch64";;
ppc64el) gcc_arch="powerpc64le";;
s390x) gcc_arch="$ARCH";;
*) echo "unsupported arch: '$1'!" >&2; exit 1;;
*) echo "unsupported arch: '$ARCH'!" >&2; exit 1;;
esac
dpkg --add-architecture $ARCH
@@ -2,18 +2,22 @@
# Copyright (c) 2018-2020 Petr Vorel <pvorel@suse.cz>
set -ex
apt remove -y \
apt="apt remove -y"
$apt \
asciidoc \
asciidoctor \
libacl1-dev \
libaio-dev \
libaio1 \
libcap-dev \
libcap2 \
libkeyutils-dev \
libkeyutils1 \
libmm-dev \
libnuma-dev \
libnuma1 \
libselinux1-dev \
libsepol1-dev \
libssl-dev \
libtirpc-dev
libsepol-dev \
libssl-dev
$apt asciidoc-base ruby-asciidoctor || true
+16 -3
View File
@@ -1,5 +1,5 @@
#!/bin/sh
# Copyright (c) 2018-2020 Petr Vorel <pvorel@suse.cz>
# Copyright (c) 2018-2021 Petr Vorel <pvorel@suse.cz>
set -ex
# workaround for missing oldstable-updates repository
@@ -8,8 +8,15 @@ grep -v oldstable-updates /etc/apt/sources.list > /tmp/sources.list && mv /tmp/s
apt update
apt install -y --no-install-recommends \
# workaround for Ubuntu impish asking to interactively configure tzdata
export DEBIAN_FRONTEND="noninteractive"
apt="apt install -y --no-install-recommends"
$apt \
acl-dev \
asciidoc \
asciidoctor \
autoconf \
automake \
build-essential \
@@ -17,6 +24,8 @@ apt install -y --no-install-recommends \
devscripts \
clang \
gcc \
git \
iproute2 \
libacl1 \
libacl1-dev \
libaio-dev \
@@ -25,6 +34,7 @@ apt install -y --no-install-recommends \
libcap2 \
libc6 \
libc6-dev \
libjson-perl \
libkeyutils-dev \
libkeyutils1 \
libmm-dev \
@@ -32,11 +42,14 @@ apt install -y --no-install-recommends \
libnuma-dev \
libnuma1 \
libselinux1-dev \
libsepol1-dev \
libsepol-dev \
libssl-dev \
libtirpc-dev \
linux-libc-dev \
lsb-release \
pkg-config
$apt ruby-asciidoctor-pdf || true
$apt asciidoc-dblatex || true
df -hT
Executable
+27
View File
@@ -0,0 +1,27 @@
#!/bin/sh
# Copyright (c) 2018-2021 Petr Vorel <pvorel@suse.cz>
set -ex
yum="yum -y install"
$yum \
asciidoc \
autoconf \
automake \
make \
clang \
gcc \
git \
findutils \
iproute \
numactl-devel \
libtirpc \
libtirpc-devel \
perl-JSON \
perl-libwww-perl \
pkg-config \
redhat-lsb-core
# CentOS 8 fixes
$yum libmnl-devel || $yum libmnl
$yum rubygem-asciidoctor || true
+10 -2
View File
@@ -1,14 +1,19 @@
#!/bin/sh
# Copyright (c) 2018-2020 Petr Vorel <pvorel@suse.cz>
# Copyright (c) 2018-2021 Petr Vorel <pvorel@suse.cz>
set -ex
zypper --non-interactive install --force-resolution --no-recommends \
zyp="zypper --non-interactive install --force-resolution --no-recommends"
$zyp \
asciidoc \
autoconf \
automake \
clang \
findutils \
gcc \
git \
gzip \
iproute2 \
make \
kernel-default-devel \
keyutils-devel \
@@ -22,4 +27,7 @@ zypper --non-interactive install --force-resolution --no-recommends \
libtirpc-devel \
linux-glibc-devel \
lsb-release \
perl-JSON \
pkg-config
$zyp ruby2.7-rubygem-asciidoctor || $zyp ruby2.5-rubygem-asciidoctor || true
View File
Regular → Executable
+99 -19
View File
@@ -13,9 +13,9 @@ AC_CONFIG_FILES([ \
execltp \
])
AM_MAINTAINER_MODE([enable])
AC_ARG_VAR(HOSTCC, [The C compiler on the host])
AM_CONDITIONAL(CROSS_COMPILATION, test x$cross_compiling = xyes)
AM_MAINTAINER_MODE([enable])
AC_CANONICAL_HOST
@@ -30,25 +30,32 @@ AC_DEFUN([AC_PROG_STRIP], [AC_CHECK_TOOL(STRIP, strip, :)])
AC_PROG_STRIP
AC_PROG_YACC
m4_ifndef([PKG_CHECK_EXISTS],
[m4_fatal([must install pkg-config or pkgconfig and pkg.m4 macro (usual dependency), see INSTALL])])
AC_PREFIX_DEFAULT(/opt/ltp)
AC_CHECK_DECLS([IFLA_NET_NS_PID],,,[#include <linux/if_link.h>])
AC_CHECK_DECLS([MADV_MERGEABLE],,,[#include <sys/mman.h>])
AC_CHECK_DECLS([PR_CAPBSET_DROP, PR_CAPBSET_READ],,,[#include <sys/prctl.h>])
AC_CHECK_DECLS([SEM_STAT_ANY],,,[#include <sys/sem.h>])
AC_CHECK_HEADERS([ \
AC_CHECK_HEADERS_ONCE([ \
asm/ldt.h \
emmintrin.h \
ifaddrs.h \
keyutils.h \
linux/can.h \
linux/cgroupstats.h \
linux/cryptouser.h \
linux/close_range.h \
linux/dccp.h \
linux/fs.h \
linux/genetlink.h \
linux/if_alg.h \
linux/if_ether.h \
linux/if_packet.h \
linux/io_uring.h \
linux/keyctl.h \
linux/mempolicy.h \
linux/module.h \
@@ -58,7 +65,6 @@ AC_CHECK_HEADERS([ \
linux/tty.h \
linux/types.h \
linux/userfaultfd.h \
mm.h \
netinet/sctp.h \
pthread.h \
sys/epoll.h \
@@ -74,11 +80,14 @@ AC_CHECK_HEADERS([ \
])
AC_CHECK_HEADERS(fts.h, [have_fts=1])
AC_SUBST(HAVE_FTS_H, $have_fts)
AC_CHECK_HEADERS(linux/vm_sockets.h, [], [], [#include <sys/socket.h>])
AC_CHECK_FUNCS([ \
AC_CHECK_FUNCS_ONCE([ \
clone3 \
close_range \
copy_file_range \
epoll_pwait \
epoll_pwait2 \
execveat \
fallocate \
fchownat \
@@ -87,6 +96,7 @@ AC_CHECK_FUNCS([ \
fsopen \
fspick \
fstatat \
getauxval \
getdents \
getdents64 \
io_pgetevents \
@@ -94,6 +104,9 @@ AC_CHECK_FUNCS([ \
io_uring_register \
io_uring_enter \
kcmp \
mallinfo \
mallinfo2 \
mallopt \
mkdirat \
mknodat \
modify_ldt \
@@ -110,12 +123,15 @@ AC_CHECK_FUNCS([ \
profil \
pwritev \
pwritev2 \
quotactl_fd \
rand_r \
readlinkat \
recvmmsg \
renameat \
renameat2 \
sched_getcpu \
sendmmsg \
sethostid \
setns \
sigpending \
splice \
@@ -136,6 +152,10 @@ AC_CHECK_FUNCS(mkdtemp,[],AC_MSG_ERROR(mkdtemp() not found!))
AC_CHECK_MEMBERS([struct fanotify_event_info_fid.fsid.__val],,,[#include <sys/fanotify.h>])
AC_CHECK_MEMBERS([struct perf_event_mmap_page.aux_head],,,[#include <linux/perf_event.h>])
AC_CHECK_MEMBERS([struct sigaction.sa_sigaction],[],[],[#include <signal.h>])
AC_CHECK_MEMBERS([struct statx.stx_mnt_id],,,[
#define _GNU_SOURCE
#include <sys/stat.h>
])
AC_CHECK_MEMBERS([struct utsname.domainname],,,[
#define _GNU_SOURCE
@@ -144,12 +164,21 @@ AC_CHECK_MEMBERS([struct utsname.domainname],,,[
AC_CHECK_TYPES([enum kcmp_type],,,[#include <linux/kcmp.h>])
AC_CHECK_TYPES([struct acct_v3],,,[#include <sys/acct.h>])
AC_CHECK_TYPES([struct fanotify_event_info_fid],,,[#include <sys/fanotify.h>])
AC_CHECK_TYPES([struct fanotify_event_info_header],,,[#include <sys/fanotify.h>])
AC_CHECK_TYPES([struct af_alg_iv, struct sockaddr_alg],,,[# include <linux/if_alg.h>])
AC_CHECK_TYPES([struct fanotify_event_info_fid, struct fanotify_event_info_error,
struct fanotify_event_info_header, struct fanotify_event_info_pidfd],,,[#include <sys/fanotify.h>])
AC_CHECK_TYPES([struct file_dedupe_range],,,[#include <linux/fs.h>])
AC_CHECK_TYPES([struct file_handle],,,[
#define _GNU_SOURCE
#include <fcntl.h>
])
AC_CHECK_TYPES([struct fs_quota_statv],,,[#include <xfs/xqm.h>])
AC_CHECK_TYPES([struct if_nextdqblk],,,[#include <linux/quota.h>])
AC_CHECK_TYPES([struct iovec],,,[#include <sys/uio.h>])
AC_CHECK_TYPES([struct ipc64_perm],,,[#include <sys/ipcbuf.h>])
AC_CHECK_TYPES([struct loop_config],,,[#include <linux/loop.h>])
AC_CHECK_TYPES([struct mmsghdr],,,[
#define _GNU_SOURCE
@@ -157,27 +186,24 @@ AC_CHECK_TYPES([struct mmsghdr],,,[
#include <sys/socket.h>
])
AC_CHECK_TYPES([struct msqid64_ds],,,[#include <sys/msgbuf.h>])
AC_CHECK_TYPES([struct rlimit64],,,[
#define _LARGEFILE64_SOURCE
#include <sys/resource.h>
])
AC_CHECK_TYPES([struct semid64_ds],,,[#include <sys/sem.h>])
AC_CHECK_TYPES([struct shmid64_ds],,,[#include <sys/shmbuf.h>])
AC_CHECK_TYPES([struct statx, struct statx_timestamp],,,[
#define _GNU_SOURCE
#include <sys/stat.h>
])
AC_CHECK_TYPES([struct termio],,,[#include <sys/ioctl.h>])
AC_CHECK_TYPES([struct tpacket_req3],,,[
#ifdef HAVE_LINUX_IF_PACKET_H
# include <linux/if_packet.h>
#endif
])
AC_CHECK_TYPES([struct user_desc, struct modify_ldt_ldt_s],[],[],[
#include <asm/ldt.h>
])
AC_CHECK_TYPES([struct tpacket_req3],,,[# include <linux/if_packet.h>])
AC_CHECK_TYPES([struct user_desc, struct modify_ldt_ldt_s],[],[],[#include <asm/ldt.h>])
AC_CHECK_TYPES([struct xt_entry_match, struct xt_entry_target],,,[
#include <sys/types.h>
@@ -187,9 +213,12 @@ AC_CHECK_TYPES([struct xt_entry_match, struct xt_entry_target],,,[
#include <linux/netfilter_ipv4/ip_tables.h>
])
AC_CHECK_TYPES([struct __kernel_old_timeval, struct __kernel_old_timespec, struct __kernel_timespec,
struct __kernel_old_itimerspec, struct __kernel_itimerspec],,,[#include <sys/socket.h>])
# Tools knobs
# Expect
# Bash
AC_ARG_WITH([bash],
[AC_HELP_STRING([--with-bash],
[have the Bourne Again Shell interpreter])],
@@ -202,6 +231,34 @@ else
AC_SUBST([WITH_BASH],["no"])
fi
# metadata
AC_ARG_ENABLE([metadata],
[AC_HELP_STRING([--disable-metadata],
[Disable metadata generation (both HTML and PDF, default no)])],
[], [enable_metadata=yes]
)
AC_ARG_ENABLE([metadata_html],
[AC_HELP_STRING([--disable-metadata-html],
[Disable metadata HTML generation (default no)])],
[], [enable_metadata_html=yes]
)
AC_ARG_ENABLE([metadata_pdf],
[AC_HELP_STRING([--enable-metadata-pdf],
[Enable metadata PDF generation (default no)])],
[], [enable_metadata_pdf=no]
)
AC_ARG_WITH([metadata_generator],
[AC_HELP_STRING([--with-metadata-generator=asciidoc|asciidoctor],
[Specify metadata generator to use (default autodetect)])],
[with_metadata_generator=$withval],
[with_metadata_generator=detect]
)
LTP_DOCPARSE
# Expect
AC_ARG_WITH([expect],
[AC_HELP_STRING([--with-expect],
[have the Tcl/expect library])],
@@ -313,7 +370,7 @@ LTP_CHECK_SYSCALL_FCNTL
if test "x$with_numa" = xyes; then
LTP_CHECK_SYSCALL_NUMA
numa_error_msg="test requires libnuma >= 2 and it's development packages"
numa_error_msg="test requires libnuma development packages with LIBNUMA_API_VERSION >= 2"
else
numa_error_msg="NUMA support was disabled during build"
fi
@@ -328,3 +385,26 @@ test "x$with_tirpc" = xyes && LTP_CHECK_TIRPC
LTP_DETECT_HOST_CPU
AC_OUTPUT
cat << EOF
TESTSUITES
open posix testsuite: ${with_open_posix_testsuite:-no}
realtime testsuite: ${with_realtime_testsuite:-no}
LIBRARIES
keyutils: ${have_keyutils:-no}
libacl: ${have_libacl:-no}
libaio: ${have_libaio:-no} (aio: ${have_aio:-no})
libcap: $cap_libs (newer: ${has_newer_libcap:-no})
libcrypto: $have_libcrypto (sha: ${have_sha:-no})
libmnl: ${have_libmnl:-no}
libnuma: ${have_libnuma:-no} (headers: ${have_numa_headers:-no}, v2 headers: ${have_numa_headers_v2:-no})
libtirpc: ${have_libtirpc:-no}
glibc SUN-RPC: ${have_rpc_glibc:-no}
METADATA
metadata generator: $with_metadata_generator
HTML metadata: $with_metadata_html
PDF metadata: $with_metadata_pdf
EOF
Regular → Executable
+2 -20
View File
@@ -1,24 +1,6 @@
#
# Doc Makefile.
#
# Copyright (C) 2009, Cisco Systems Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
# SPDX-License-Identifier: GPL-2.0-or-later
# Copyright (C) 2009, Cisco Systems Inc.
# Ngie Cooper, July 2009
#
top_srcdir ?= ..
Regular → Executable
+2
View File
@@ -158,6 +158,8 @@ $(LDFLAGS) : What to pass in to the linker, including -L arguments
$(LDLIBS) : Libraries to pass to the linker (e.g. -lltp, etc).
$(LTPLDLIBS) : LTP internal libraries i.e. these in libs/ directory.
$(OPT_CFLAGS) : Optimization flags to pass into the C compiler, -O2,
etc. If you specify -O2 or higher, you should also
specify -fno-strict-aliasing, because of gcc
+2371
View File
File diff suppressed because it is too large Load Diff
Regular → Executable
+18 -12
View File
@@ -1,6 +1,10 @@
C Test Case Tutorial
====================
NOTE: See also
https://github.com/linux-test-project/ltp/wiki/Test-Writing-Guidelines[Test Writing Guidelines],
https://github.com/linux-test-project/ltp/wiki/C-Test-API[C Test API].
This is a step-by-step tutorial on writing a simple C LTP test, where topics
of the LTP and Linux kernel testing will be introduced gradually using a
concrete example. Most sections will include exercises, some trivial and
@@ -302,12 +306,11 @@ Wiki]).
Is your +.gitignore+ correct?
3.3 Run checkpatch.pl on the source file
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3.3 Run make check
~~~~~~~~~~~~~~~~~~
The LTP follows the Linux style guidelines where possible. Check what happens
if you run +kernel/linux/scripts/checkpatch.pl --no-tree -f statx01.c+ and
correct any style issues.
Check coding style with `make check`
(more in https://github.com/linux-test-project/ltp/wiki/Test-Writing-Guidelines#21-c-coding-style[C coding style])
3.4 Install the LTP and run the test with runtest
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -763,7 +766,7 @@ failing due to some faulty logic.
6.1 What is wrong with the switch statement?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Were you paying attention? Also see the output of +checkpatch.pl+.
Were you paying attention? Also see the output of +make check+.
6.2 Test a feature unique to statx
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -791,9 +794,9 @@ of fallback logic in the build system. We can now get our test ready for
submission.
The first thing you need to do before considering submitting your test is run
+scripts/checkpatch.pl --no-tree -f+ on +statx01.c+. Again, we use the kernel
style guidelines where possible. Next you should create a new branch, this
will allow you to reshape your commit history without fear.
+make check-statx01+ or + make check+ in the test's directory. Again, we use
the kernel style guidelines where possible. Next you should create a new
branch, this will allow you to reshape your commit history without fear.
After that we have the pleasure of doing an interactive 'rebase' to clean up
our commit history. In its current form the test only really needs a single
@@ -1061,9 +1064,12 @@ One important topic which has not been covered by this tutorial, is
multi-process or multi-threaded testing. The LTP library functions work inside
child processes and threads, but their semantics change slightly. There are
also various helper functions for synchronising and forking processes. For
more information see the Test Writing Guidelines (either at
https://github.com/linux-test-project/ltp/wiki/Test-Writing-Guidelines[the
Wiki] or in ./doc), in particular sections 2.2.7 to 2.2.10 and 2.2.13.
more information see
https://github.com/linux-test-project/ltp/wiki/C-Test-API[C Test API],
in particular sections
https://github.com/linux-test-project/ltp/wiki/C-Test-API#17-fork-ing[1.7 Fork()-ing] to
https://github.com/linux-test-project/ltp/wiki/C-Test-API#110-signals-and-signal-handlers[1.10 Signals and signal handlers] and
https://github.com/linux-test-project/ltp/wiki/C-Test-API#114-thread-safety-in-the-ltp-library[1.14 Thread-safety in the LTP library].
When it comes time to submit a test, the preferred way to do it is on the
mailing list although you can also use GitHub. The LTP follows similar rules
+29
View File
@@ -1,6 +1,11 @@
LTP Library API Writing Guidelines
==================================
NOTE: See also
https://github.com/linux-test-project/ltp/wiki/Test-Writing-Guidelines[Test Writing Guidelines],
https://github.com/linux-test-project/ltp/wiki/C-Test-API[C Test API],
https://github.com/linux-test-project/ltp/wiki/Shell-Test-API[Shell Test API].
1. General Rules
----------------
@@ -16,10 +21,34 @@ Don't forget to update docs when you change the API.
2. C API
--------
2.1 LTP-001: Sources have tst_ prefix
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
API source code is in headers `include/*.h`, `include/lapi/*.h` (backward
compatibility for old kernel and libc) and C sources in `lib/*.c`. Files have
'tst_' prefix.
2.2 LTP-002: TST_RET and TST_ERR are not modified
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The test author is guaranteed that the test API will not modify these
variables. This prevents silent errors where the return value and
errno are overwritten before the test has chance to check them.
The macros which are clearly intended to update these variables. That
is +TEST+ and those in 'tst_test_macros.h'. Are of course allowed to
update these variables.
2.3 LTP-003: Externally visible library symbols have the tst_ prefix
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Functions, types and variables in the public test API should have the
tst_ prefix. With some exceptions for symbols already prefixed with
safe_ or ltp_.
Static (private) symbols should not have the prefix.
3. Shell API
------------
Regular → Executable
+1 -4
View File
@@ -56,9 +56,7 @@ if run network tests flag is passed these additional tests are run
- nfs
To test filesystem with LVM
- ltpfslvm.sh
w/o LVM
- ltpfsnolvm.sh
- testscripts/lvmtest.sh
Device Mapper tests
- ltpdmmapper.sh
@@ -71,7 +69,6 @@ other filesystem or disk type tests
- autofs1.sh
- autofs4.sh
- diskio.sh
- exportfs.sh
- isofs.sh
- sysfs.sh
+59
View File
@@ -0,0 +1,59 @@
# Maintainer Patch Review Checklist
Patchset should be tested locally and ideally also in maintainer's fork in
GitHub Actions on GitHub.
NOTE: Travis does only build testing, passing the CI means only that the
test compiles fine on variety of different distributions and
releases.
The test should be executed at least once locally and should PASS as well.
Commit messages should have
* Author's `Signed-off-by` tag
* Committer's `Reviewed-by` or `Signed-off-by` tag
* Check also mailing lists for other reviewers / testers tags, notes and failure reports
* `Fixes: hash` if it fixes particular LTP commit
* `Fixes: #N` if it fixes github issue number N, so it's automatically closed
After patch is accepted or rejected, set correct state and archive in
https://patchwork.ozlabs.org/project/ltp/list/[LTP patchwork instance].
Also update `.github/workflows/wiki-mirror.yml` script which mirrors
`doc/*.txt` to LTP wiki (git URL https://github.com/linux-test-project/ltp.wiki.git)
if new wiki page is added.
## New tests
New test should
* Have a record in runtest file
* Test should work fine with more than one iteration
(e.g. run with `-i 100`)
* Have a brief description
* License: the default license for new tests is GPL v2 or later, use
GPL-2.0-or-later; the licence for test (e.g. GPL-2.0) should not change
unless test is completely rewritten
* Old copyrights should be kept unless test is completely rewritten
### C tests
* Use new https://github.com/linux-test-project/ltp/wiki/Test-Writing-Guidelines#22-writing-a-test-in-c[C API]
* Test binaries are added into corresponding '.gitignore' files
* Check coding style with `make check`
(more in https://github.com/linux-test-project/ltp/wiki/Test-Writing-Guidelines#21-c-coding-style[C coding style])
* Docparse documentation
* If a test is a regression test it should include tags
(more in https://github.com/linux-test-project/ltp/wiki/Test-Writing-Guidelines#2238-test-tags[Test tags])
* When rewriting old tests, https://en.wikipedia.org/wiki/%CE%9CClinux[uClinux]
support should be removed (project has been discontinued).
E.g. remove `#ifdef UCLINUX`, replace `FORK_OR_VFORK()` with simple `fork()` or `SAFE_FORK()`.
### Shell tests
* Use new https://github.com/linux-test-project/ltp/wiki/Test-Writing-Guidelines#23-writing-a-testcase-in-shell[shell API]
* Check coding style with `make check`
(more in https://github.com/linux-test-project/ltp/wiki/Test-Writing-Guidelines#132-shell-coding-style[Shell coding style])
* If a test is a regression test it should include related kernel or glibc commits as a comment
## LTP library
For patchset touching library please check also
https://github.com/linux-test-project/ltp/wiki/LTP-Library-API-Writing-Guidelines[LTP Library API Writing Guidelines].
Regular → Executable
View File
Regular → Executable
View File
Regular → Executable
View File
Regular → Executable
View File
Regular → Executable
View File
Regular → Executable
View File
Regular → Executable
View File
Regular → Executable
View File
Regular → Executable
View File
Regular → Executable
View File
Regular → Executable
View File
Regular → Executable
View File
Regular → Executable
View File
Regular → Executable
View File
View File
Regular → Executable
View File
+476
View File
@@ -0,0 +1,476 @@
LTP C Test Network API
======================
NOTE: See also
https://github.com/linux-test-project/ltp/wiki/Test-Writing-Guidelines[Test Writing Guidelines],
https://github.com/linux-test-project/ltp/wiki/C-Test-Case-Tutorial[C Test Case Tutorial],
https://github.com/linux-test-project/ltp/wiki/C-Test-API[C Test API],
https://github.com/linux-test-project/ltp/wiki/Shell-Test-API[Shell Test API].
LTP library includes helper functions for configuring sockets and setting up
network devices.
1 Configuring sockets
---------------------
1.1 Safe syscall variants
~~~~~~~~~~~~~~~~~~~~~~~~~
+#include "tst_safe_net.h"+
Most common standard syscalls and libc functions for configuring sockets have a
"safe" variant in LTP library which will call +tst_brk()+ if the underlying
system function fails. See
https://github.com/linux-test-project/ltp/wiki/C-Test-API[C Test API]. The
safe function names are in uppercase with the +SAFE_+ prefix (e.g. the safe
variant of +socket()+ is called +SAFE_SOCKET()+). For most safe functions, the
parameters and return type are identical to the standard system function:
- +SAFE_SOCKET()+
- +SAFE_SOCKETPAIR()+
- +SAFE_GETSOCKOPT()+
- +SAFE_SETSOCKOPT()+
- +SAFE_BIND()+
- +SAFE_LISTEN()+
- +SAFE_ACCEPT()+
- +SAFE_CONNECT()+
- +SAFE_GETSOCKNAME()+
- +SAFE_GETHOSTNAME()+
- +SAFE_GETADDRINFO()+
A few safe functions have extra parameters for quick return value validation.
The ellipsis (+...+) represents the standard parameters of the underlying system
function:
* +SAFE_SEND(char strict, ...)+
* +SAFE_SENDTO(char strict, ...)+
** If +strict+ is non-zero, the return value must be equal to the data length
argument. Otherwise the test will fail and exit.
* +SAFE_SENDMSG(size_t msg_len, ...)+
* +SAFE_RECV(size_t msg_len, ...)+
* +SAFE_RECVMSG(size_t msg_len, ...)+
** If +msg_len+ is non-zero, the return value must be equal to the +msg_len+
argument. Otherwise the test will fail and exit.
There are also some custom functions for simpler configuration and queries:
- +int SAFE_SETSOCKOPT_INT(int sockfd, int level, int optname, int value)+
Simple setsockopt() variant for passing integers by value.
- +int TST_GETSOCKPORT(int sockfd)+ Get port number (in host byte order) of a
bound socket.
- +unsigned short TST_GET_UNUSED_PORT(int family, int type)+ Get a random
port number (in network byte order) which is currently closed for the given
socket family and type. Note that another application may open the port while
the test is still running. The test user is responsible for setting up test
environment without such interference.
1.2 Address conversion functions
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#include "tst_net.h"+
LTP library also provides helper functions for quick initialization of socket
address structures:
- +void tst_get_in_addr(const char *ip_str, struct in_addr *ip)+ Convert
human-readable IPv4 address string +ip_str+ to binary representation in
network byte order. The converted value will be stored in the second argument.
- +void tst_get_in6_addr(const char *ip_str, struct in6_addr *ip6)+ Convert
human-readable IPv6 address string +ip_str+ to binary representation in
network byte order. The converted value will be stored in the second argument.
- +socklen_t tst_get_connect_address(int sock, struct sockaddr_storage *addr)+
Find the address which can be used to send data to bound socket +sock+ from
another socket. The address will be stored in the second argument. This
function automatically converts wildcard bind address to localhost. Returns
size of the address in bytes.
- +void tst_init_sockaddr_inet(struct sockaddr_in *sa, const char *ip_str,
uint16_t port)+ Initialize socket address structure +sa+ using
human-readable IPv4 address +ip_str+ and port number +port+ in host byte
order.
- +void tst_init_sockaddr_inet_bin(struct sockaddr_in *sa, uint32_t ip_val,
uint16_t port)+ Initialize socket address structure +sa+ using binary IPv4
address +ip_val+ and port number +port+, both in host byte order.
- +void tst_init_sockaddr_inet6(struct sockaddr_in6 *sa, const char *ip_str,
uint16_t port)+ Initialize socket address structure +sa+ using
human-readable IPv6 address +ip_str+ and port number +port+ in host byte
order.
- +void tst_init_sockaddr_inet6_bin(struct sockaddr_in6 *sa, const struct
in6_addr *ip_val, uint16_t port)+ Initialize socket address structure +sa+
using binary IPv6 address +ip_val+ and port number +port+, both in host byte
order.
.Example Usage
[source,c]
-------------------------------------------------------------------------------
#include <sys/socket.h>
#include <netinet/in.h>
#include "tst_test.h"
#include "tst_safe_net.h"
#include "tst_net.h"
static int sockfd = -1;
static void setup(void)
{
struct sockaddr_in addr;
tst_init_sockaddr_inet_bin(&addr, INADDR_ANY, 0);
sockfd = SAFE_SOCKET(AF_INET, SOCK_STREAM, 0);
SAFE_SETSOCKOPT_INT(sockfd, SOL_SOCKET, SO_SNDBUF, 4096);
SAFE_BIND(sockfd, (struct sockaddr *)&addr, sizeof(addr));
SAFE_LISTEN(sockfd, 8);
}
-------------------------------------------------------------------------------
2 Configuring network devices
-----------------------------
+#include "tst_netdevice.h"+
When opening a localhost socket isn't enough and the test needs special device
or routing configuration, the netdevice library can create the required network
setup without calling external programs. Internally, the netdevice functions
use a rtnetlink socket to communicate with the kernel.
All of these functions will call +tst_brk()+ on failure, unless stated
otherwise. Error values described below are returned only during test cleanup
stage.
2.1 Network device management
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- +int NETDEV_INDEX_BY_NAME(const char *ifname)+ Returns the device index for
the given device name, or -1 on error.
- +int NETDEV_SET_STATE(const char *ifname, int up)+ Enable or disable a
network device +ifname+. Returns 0 on success, -1 on error.
- +int CREATE_VETH_PAIR(const char *ifname1, const char *ifname2)+ Creates a
connected pair of virtual network devices with given device names. Returns 1
on success, 0 on error. Add +"CONFIG_VETH"+ to +test.needs_kconfigs+ if your
test calls this function.
- +int NETDEV_ADD_DEVICE(const char *ifname, const char *devtype)+ - Creates
a new network device named +ifname+ of specified device type. Returns 1 on
success, 0 on error.
- +int NETDEV_REMOVE_DEVICE(const char *ifname)+ Removes network device
+ifname+. Returns 1 on success, 0 on error.
2.2 Network address management
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- +int NETDEV_ADD_ADDRESS(const char \*ifname, unsigned int family, const void
*address, unsigned int prefix, size_t addrlen, unsigned int flags)+ Adds
new address to network device +ifname+. This is a low-level function which
allows setting any type of address. You must specify the protocol +family+,
address length in bytes (+addrlen+) and network prefix length (+prefix+). The
+address+ itself must be in binary representation in network byte order. You
can also pass rtnetlink flags from the +IFA_F_*+ group. Returns 1 on success,
0 on error.
- +int NETDEV_ADD_ADDRESS_INET(const char *ifname, in_addr_t address, unsigned
int prefix, unsigned int flags)+ Adds new IPv4 address to network device
+ifname+. Parameters have the same meaning as in +NETDEV_ADD_ADDRESS()+.
Returns 1 on success, 0 on error.
- +int NETDEV_REMOVE_ADDRESS(const char *ifname, unsigned int family, const
void *address, size_t addrlen)+ Removes the specified address from network
device +ifname+. Parameters have the same meaning as in
+NETDEV_ADD_ADDRESS()+. Returns 1 on success, 0 on error.
- +int NETDEV_REMOVE_ADDRESS_INET(const char *ifname, in_addr_t address)+
Removes specified IPv4 +address+ (in network byte order) from network device
+ifname+. Returns 1 on success, 0 on error.
2.3 Network namespace device assignment
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
WARNING: Moving a network device to another namespace will erase previous
configuration. Move the device to the correct namespace first, then
configure it.
- +int NETDEV_CHANGE_NS_FD(const char *ifname, int nsfd)+ Moves network
device +ifname+ to network namespace designated by open file descriptor
+nsfd+. Returns 1 on success, 0 on error.
- +int NETDEV_CHANGE_NS_PID(const char *ifname, pid_t nspid)+ Moves network
device +ifname+ to the network namespace currently used by process +nspid+.
Returns 1 on success, 0 on error.
2.4 Routing table management
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- +int NETDEV_ADD_ROUTE(const char *ifname, unsigned int family, const void
*srcaddr, unsigned int srcprefix, size_t srclen, const void *dstaddr,
unsigned int dstprefix, size_t dstlen, const void *gateway, size_t
gatewaylen)+ Adds new route to the main routing table. This is a low-level
function which allows creating routes for any protocol. You must specify the
protocol +family+ and either network device name +ifname+ or +gateway+
address. Both packet source address +srcaddr+ and destination address
+dstaddr+ are optional. You must also specify the corresponding length
and prefix argument for any address which is not +NULL+. All addresses must
be in binary representation in network byte order. Returns 1 on success,
0 on error.
- +int NETDEV_ADD_ROUTE_INET(const char *ifname, in_addr_t srcaddr, unsigned
int srcprefix, in_addr_t dstaddr, unsigned int dstprefix, in_addr_t
gateway)+ Adds new IPv4 route to the main routing table. Parameters have
the same meaning as in +NETDEV_ADD_ROUTE()+. If you do not want to set
explicit +gateway+ address, set it to 0. If the routing rule should ignore
the source or destination address, set the corresponding prefix argument
to 0. Returns 1 on success, 0 on error.
- +int NETDEV_REMOVE_ROUTE(const char *ifname, unsigned int family, const void
*srcaddr, unsigned int srcprefix, size_t srclen, const void *dstaddr,
unsigned int dstprefix, size_t dstlen, const void *gateway, size_t
gatewaylen)+ Removes a route from the main routing table. Parameters have
the same meaning as in +NETDEV_ADD_ROUTE()+. Returns 1 on success, 0 on
error.
- +int NETDEV_REMOVE_ROUTE_INET(const char *ifname, in_addr_t srcaddr,
unsigned int srcprefix, in_addr_t dstaddr, unsigned int dstprefix, in_addr_t
gateway)+ Removes IPv4 route from the main routing table. Parameters have
the same meaning as in +NETDEV_ADD_ROUTE_INET()+. Returns 1 on success,
0 on error.
.Example Usage
[source,c]
-------------------------------------------------------------------------------
#include <arpa/inet.h>
#include <linux/if_addr.h>
#include "tst_test.h"
#include "tst_netdevice.h"
...
static void setup(void)
{
CREATE_VETH_PAIR("ltp_veth1", "ltp_veth2");
NETDEV_ADD_ADDRESS_INET("ltp_veth2", htonl(DSTADDR), NETMASK,
IFA_F_NOPREFIXROUTE);
NETDEV_SET_STATE("ltp_veth2", 1);
NETDEV_ADD_ROUTE_INET("ltp_veth2", 0, 0, htonl(SRCNET), NETMASK, 0);
NETDEV_ADD_ADDRESS_INET("ltp_veth1", htonl(SRCADDR), NETMASK,
IFA_F_NOPREFIXROUTE);
NETDEV_SET_STATE("ltp_veth1", 1);
NETDEV_ADD_ROUTE_INET("ltp_veth1", 0, 0, htonl(DSTNET), NETMASK, 0);
...
}
-------------------------------------------------------------------------------
3 rtnetlink API
---------------
+#include "tst_rtnetlink.h"+
The rtnetlink library provides helper functions for constructing and sending
arbitrary messages and parsing kernel responses.
All of the functions below will call +tst_brk()+ on failure, unless stated
otherwise. Error values described below are returned only during test cleanup
stage.
3.1 Data structures
~~~~~~~~~~~~~~~~~~~
[source,c]
-------------------------------------------------------------------------------
struct tst_rtnl_context;
struct tst_rtnl_attr_list {
unsigned short type;
const void *data;
ssize_t len;
const struct tst_rtnl_attr_list *sublist;
};
struct tst_rtnl_message {
struct nlmsghdr *header;
struct nlmsgerr *err;
void *payload;
size_t payload_size;
};
-------------------------------------------------------------------------------
+struct tst_rtnl_context+ is an opaque rtnetlink socket with buffer for
constructing and sending arbitrary messages using the functions described
below. Create a new context using +RTNL_CREATE_CONTEXT()+, then free it using
+RTNL_DESTROY_CONTEXT()+ when you're done with it.
+struct tst_rtnl_attr_list+ is a helper structure for defining complex
rtnetlink message attribute payloads, including nested attribute lists. Every
list and sublist defined using this structure is terminated by item with
negative +len+.
- +type+ is the attribute type that will be stored in +struct rtattr.rta_type+.
- +data+ contains arbitrary attribute payload.
- +len+ contains length of the +data+ attribute in bytes. If +data+ is +NULL+,
set +len+ to 0. The last item in a list or sublist must have negative length.
- +sublist+ contains a nested attribute list which will be appended after
+data+ as part of the attribute payload. +struct rtattr.rta_len+ will be
calculated automatically with proper alignment, do _not_ add the sublist size
to the +len+ field. If you do not want to add nested attributes, set
+sublist+ to +NULL+.
+struct tst_rtnl_message+ is a structure holding partially parsed rtnetlink
messages received from the kernel. +RTNL_RECV()+ returns an array of these
structures with the last item having +NULL+ in the +header+ field. Call
+RTNL_FREE_MESSAGE()+ to free a message list returned by +RTNL_RECV()+.
- +header+ is the netlink header structure of the message. +NULL+ in the header
field terminates a list of messages.
- +err+ points to the payload of +NLMSG_ERROR+ messages. It is set to +NULL+
for all other message types.
- +payload+ is a pointer to message data.
- +payload_size+ is the length of +payload+ data in bytes.
3.2 Sending and receiving messages
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- +struct tst_rtnl_context *RTNL_CREATE_CONTEXT(void)+ Creates a new
rtnetlink communication context for use with the functions described below.
Returns +NULL+ on error.
- +void RTNL_FREE_MESSAGE(struct tst_rtnl_message *msg)+ Frees an array of
messages returned by +RTNL_RECV()+.
- +void RTNL_DESTROY_CONTEXT(struct tst_rtnl_context *ctx)+ Closes a
communication context created by +RTNL_CREATE_CONTEXT()+.
- +int RTNL_SEND(struct tst_rtnl_context *ctx)+ Sends all messages waiting
in +ctx+ buffer to the kernel. If there are multiple messages to send, a new
+NLMSG_DONE+ message will be added automatically. Returns the number of
bytes sent on success. Return 0 or negative value on error.
- +int RTNL_SEND_VALIDATE(struct tst_rtnl_context *ctx)+ Sends all messages
just like +RTNL_SEND()+, then receives the response from the kernel and
validates results of requests sent with the +NLM_F_ACK+ flag. This function
calls +tst_brk()+ as usual if communication fails but it will return error
status without terminating the test if one of the received messages contains
error code. See +RTNL_CHECK_ACKS()+ below for explanation of the return
value.
- +int RTNL_WAIT(struct tst_rtnl_context *ctx)+ Waits until data becomes
available to read from the rtnetlink socket (timeout: 1 second). Returns 1
if there is data to read, 0 on timeout or -1 on error.
- +struct tst_rtnl_message *RTNL_RECV(struct tst_rtnl_context *ctx)+ Receives
rtnetlink messages from the kernel. The messages are received in non-blocking
mode so calling +RTNL_WAIT()+ first is recommended. Returns an array of
partially parsed messages terminated by an item with +NULL+ in the +header+
field. On error or when there are no messages to receive, returns +NULL+.
Call +RTNL_FREE_MESSAGE()+ to free the returned data.
- +int RTNL_CHECK_ACKS(struct tst_rtnl_context *ctx, struct tst_rtnl_message
*response)+ Validate results of requests sent with the +NLM_F_ACK+ flag.
Do not call +RTNL_ADD_MESSAGE()+ between +RTNL_SEND()+ and
+RTNL_CHECK_ACKS()+ because it will reset the state of +ctx+ and prevent
result validation. Returns 1 if all messages sent with the +NLM_F_ACK+ flag
have a corresponding message in +response+ and the error code is 0. If any
of the expected response messages is missing, this function will call
+tst_brk()+ (or return 0 during test cleanup phase). If any of the response
messages has non-zero error code, this function will return 0 and store the
first non-zero error code in global variable +tst_rtnl_errno+ (sign-flipped
just like regular libc +errno+).
3.3 Creating messages
~~~~~~~~~~~~~~~~~~~~~
- +int RTNL_ADD_MESSAGE(struct tst_rtnl_context *ctx, const struct nlmsghdr
*header, const void *payload, size_t payload_size)+ Adds new rtnetlink
message to +ctx+ buffer. You need to provide message +header+ and optional
+payload+. +payload_size+ is the size of +payload+ data in bytes. If you
don't want to add any payload data, set +payload+ to +NULL+ and
+payload_size+ to 0. This function will automatically fill the +nlmsg_len+,
+nlmsg_seq+ and +nlmsg_pid+ fields of the new message header. You don't need
to set those. It'll also automatically add +NLM_F_MULTI+ flag when needed.
Returns 1 on success, 0 on error. Note that the first call of
+RTNL_ADD_MESSAGE()+ after +RTNL_SEND()+ will reset the state of +ctx+
and +RTNL_CHECK_ACKS()+ will not work correctly until the next +RTNL_SEND()+.
- +int RTNL_ADD_ATTR(struct tst_rtnl_context *ctx, unsigned short type, const
void *data, unsigned short len)+ Adds new attribute to the last message
in +ctx+ buffer. See +RTNL_ADD_MESSAGE()+. You need to provide attribute
+type+ which will be stored in +struct rtattr.rta_type+, optional payload
+data+ and payload size +len+ in bytes. If you don't want to add any payload,
set +data+ to +NULL+ and +len+ to 0. Returns 1 on success, 0 on error.
- +int RTNL_ADD_ATTR_STRING(struct tst_rtnl_context *ctx, unsigned short type,
const char *data)+ Adds new string attribute to the last message in +ctx+
buffer. Parameters and return value are the same as for +RTNL_ADD_ATTR()+,
except the payload length is calculated using +strlen()+.
- +int RTNL_ADD_ATTR_LIST(struct tst_rtnl_context *ctx, const struct
tst_rtnl_attr_list *list)+ Adds a list of attributes to the last message
in +ctx+ buffer. See description of +struct tst_rtnl_attr_list+ and
+RTNL_ADD_MESSAGE()+ above. Returns the number of added attributes on
success (nested attributes are not counted), -1 on error.
.Example Usage
[source,c]
-------------------------------------------------------------------------------
#include <asm/types.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "tst_test.h"
#include "tst_rtnetlink.h"
#include "tst_netdevice.h"
...
void setup(void)
{
struct tst_rtnl_context *ctx;
int index, ret;
in_addr_t addr;
struct nlmsghdr header = {
.nlmsg_type = RTM_NEWADDR,
.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_CREATE |
NLM_F_EXCL
};
struct ifaddrmsg info = {
.ifa_family = AF_INET,
.ifa_prefixlen = 24
};
index = NETDEV_INDEX_BY_NAME("ltp_veth1");
info.ifa_index = index;
ctx = RTNL_CREATE_CONTEXT();
RTNL_ADD_MESSAGE(ctx, &header, &info, sizeof(info));
addr = inet_addr("192.168.123.45");
RTNL_ADD_ATTR(ctx, IFA_LOCAL, &addr, sizeof(addr));
ret = RTNL_SEND_VALIDATE(ctx);
RTNL_DESTROY_CONTEXT(ctx);
if (!ret) {
tst_brk(TBROK, "Failed to set ltp_veth1 address");
}
}
-------------------------------------------------------------------------------
Regular → Executable
View File
Executable
+6
View File
@@ -0,0 +1,6 @@
ID DESCRIPTION
LTP-001 Library source files have tst_ prefix
LTP-002 TST_RET and TST_ERR are never modified by test library functions
LTP-003 Externally visible library symbols have the tst_ prefix
LTP-004 Test executable symbols are marked static
LTP-005 Array must terminate with a sentinel value (i.e. NULL or '{}')
1 ID DESCRIPTION
2 LTP-001 Library source files have tst_ prefix
3 LTP-002 TST_RET and TST_ERR are never modified by test library functions
4 LTP-003 Externally visible library symbols have the tst_ prefix
5 LTP-004 Test executable symbols are marked static
6 LTP-005 Array must terminate with a sentinel value (i.e. NULL or '{}')
+763
View File
@@ -0,0 +1,763 @@
LTP Shell Test API
==================
NOTE: See also
https://github.com/linux-test-project/ltp/wiki/Test-Writing-Guidelines[Test Writing Guidelines],
https://github.com/linux-test-project/ltp/wiki/C-Test-API[C Test API].
1 Writing a testcase in shell
-----------------------------
LTP supports testcases to be written in a portable shell too.
There is a shell library modeled closely to the C interface at
'testcases/lib/tst_test.sh'.
WARNING: All identifiers starting with 'TST_' or 'tst_' are reserved for the
test library.
1.1 Basic test interface
~~~~~~~~~~~~~~~~~~~~~~~~
[source,sh]
-------------------------------------------------------------------------------
#!/bin/sh
# SPDX-License-Identifier: GPL-2.0-or-later
# This is a basic test for true shell builtin
TST_TESTFUNC=do_test
. tst_test.sh
do_test()
{
true
ret=$?
if [ $ret -eq 0 ]; then
tst_res TPASS "true returned 0"
else
tst_res TFAIL "true returned $ret"
fi
}
tst_run
-------------------------------------------------------------------------------
TIP: To execute this test the 'tst_test.sh' library must be in '$PATH'. If you
are executing the test from a git checkout you can run it as
'PATH="$PATH:../../lib" ./foo01.sh'
The shell library expects test setup, cleanup and the test function executing
the test in the '$TST_SETUP', '$TST_CLEANUP' and '$TST_TESTFUNC' variables.
Both '$TST_SETUP' and '$TST_CLEANUP' are optional.
The '$TST_TESTFUNC' may be called several times if more than one test
iteration was requested by passing right command line options to the test.
The '$TST_CLEANUP' may be called even in the middle of the setup and must be
able to clean up correctly even in this situation. The easiest solution for
this is to keep track of what was initialized and act accordingly in the
cleanup.
WARNING: Similar to the C library, calling 'tst_brk' in the $TST_CLEANUP does
not exit the test and 'TBROK' is converted to 'TWARN'.
Notice also the 'tst_run' shell API function called at the end of the test that
actually starts the test.
WARNING: cleanup function is called only after 'tst_run' has been started.
Calling 'tst_brk' in shell libraries, e.g. 'tst_test.sh' or 'tst_net.sh' does
not trigger calling it.
[source,sh]
-------------------------------------------------------------------------------
#!/bin/sh
# SPDX-License-Identifier: GPL-2.0-or-later
# Example test with tests in separate functions
TST_TESTFUNC=test
TST_CNT=2
. tst_test.sh
test1()
{
tst_res TPASS "Test $1 passed"
}
test2()
{
tst_res TPASS "Test $1 passed"
}
tst_run
# output:
# foo 1 TPASS: Test 1 passed
# foo 2 TPASS: Test 2 passed
-------------------------------------------------------------------------------
If '$TST_CNT' is set, the test library looks if there are functions named
'$\{TST_TESTFUNC\}1', ..., '$\{TST_TESTFUNC\}$\{TST_CNT\}' and if these are
found they are executed one by one. The test number is passed to it in the '$1'.
[source,sh]
-------------------------------------------------------------------------------
#!/bin/sh
# SPDX-License-Identifier: GPL-2.0-or-later
# Example test with tests in a single function
TST_TESTFUNC=do_test
TST_CNT=2
. tst_test.sh
do_test()
{
case $1 in
1) tst_res TPASS "Test $1 passed";;
2) tst_res TPASS "Test $1 passed";;
esac
}
tst_run
# output:
# foo 1 TPASS: Test 1 passed
# foo 2 TPASS: Test 2 passed
-------------------------------------------------------------------------------
Otherwise, if '$TST_CNT' is set but there is no '$\{TST_TESTFUNC\}1', etc.,
the '$TST_TESTFUNC' is executed '$TST_CNT' times and the test number is passed
to it in the '$1'.
[source,sh]
-------------------------------------------------------------------------------
#!/bin/sh
# SPDX-License-Identifier: GPL-2.0-or-later
# Example test with tests in a single function, using $TST_TEST_DATA and
# $TST_TEST_DATA_IFS
TST_TESTFUNC=do_test
TST_TEST_DATA="foo:bar:d dd"
TST_TEST_DATA_IFS=":"
. tst_test.sh
do_test()
{
tst_res TPASS "Test $1 passed with data '$2'"
}
tst_run
# output:
# foo 1 TPASS: Test 1 passed with data 'foo'
# foo 2 TPASS: Test 1 passed with data 'bar'
# foo 3 TPASS: Test 1 passed with data 'd dd'
-------------------------------------------------------------------------------
It's possible to pass data for function with '$TST_TEST_DATA'. Optional
'$TST_TEST_DATA_IFS' is used for splitting, default value is space.
[source,sh]
-------------------------------------------------------------------------------
#!/bin/sh
# SPDX-License-Identifier: GPL-2.0-or-later
# Example test with tests in a single function, using $TST_TEST_DATA and $TST_CNT
TST_TESTFUNC=do_test
TST_CNT=2
TST_TEST_DATA="foo bar"
. tst_test.sh
do_test()
{
case $1 in
1) tst_res TPASS "Test $1 passed with data '$2'";;
2) tst_res TPASS "Test $1 passed with data '$2'";;
esac
}
tst_run
# output:
# foo 1 TPASS: Test 1 passed with data 'foo'
# foo 2 TPASS: Test 2 passed with data 'foo'
# foo 3 TPASS: Test 1 passed with data 'bar'
# foo 4 TPASS: Test 2 passed with data 'bar'
-------------------------------------------------------------------------------
'$TST_TEST_DATA' can be used with '$TST_CNT'. If '$TST_TEST_DATA_IFS' not specified,
space as default value is used. Of course, it's possible to use separate functions.
1.2 Library environment variables and functions for shell
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Similarily to the C library various checks and preparations can be requested
simply by setting right '$TST_NEEDS_FOO'.
[options="header"]
|=============================================================================
| Variable name | Action done
| 'TST_NEEDS_ROOT' | Exit the test with 'TCONF' unless executed under root.
| | Alternatively the 'tst_require_root' command can be used.
| 'TST_NEEDS_TMPDIR' | Create test temporary directory and cd into it.
| 'TST_NEEDS_DEVICE' | Prepare test temporary device, the path to testing
device is stored in '$TST_DEVICE' variable.
The option implies 'TST_NEEDS_TMPDIR'.
| 'TST_NEEDS_CMDS' | String with command names that has to be present for
the test (see below).
| 'TST_NEEDS_MODULE' | Test module name needed for the test (see below).
| 'TST_NEEDS_DRIVERS' | Checks kernel drivers support for the test.
| 'TST_NEEDS_KCONFIGS' | Checks kernel kconfigs support for the test (see below).
| 'TST_NEEDS_KCONFIGS_IFS' | Used for splitting '$TST_NEEDS_KCONFIGS' variable,
default value is comma, it only supports single character.
| 'TST_TIMEOUT' | Maximum timeout set for the test in sec. Must be int >= 1,
or -1 (special value to disable timeout), default is 300.
Variable is meant be set in tests, not by user.
It's an equivalent of `tst_test.timeout` in C, can be set
via 'tst_set_timeout(timeout)' after test has started.
|=============================================================================
[options="header"]
|=============================================================================
| Function name | Action done
| 'tst_set_timeout(timeout)' | Maximum timeout set for the test in sec.
See 'TST_TIMEOUT' variable.
|=============================================================================
NOTE: Network tests (see testcases/network/README.md) use additional variables
and functions in 'tst_net.sh'.
Checking for presence of commands
+++++++++++++++++++++++++++++++++
[source,sh]
-------------------------------------------------------------------------------
#!/bin/sh
...
TST_NEEDS_CMDS="modinfo modprobe"
. tst_test.sh
...
-------------------------------------------------------------------------------
Setting '$TST_NEEDS_CMDS' to a string listing required commands will check for
existence each of them and exits the test with 'TCONF' on first missing.
Alternatively the 'tst_require_cmds()' function can be used to do the same on
runtime, since sometimes we need to the check at runtime too.
'tst_check_cmds()' can be used for requirements just for a particular test
as it doesn't exit (it issues 'tst_res TCONF'). Expected usage is:
[source,sh]
-------------------------------------------------------------------------------
#!/bin/sh
TST_TESTFUNC=do_test
. tst_test.sh
do_test()
{
tst_check_cmds cmd || return
cmd --foo
...
}
tst_run
-------------------------------------------------------------------------------
Locating kernel modules
+++++++++++++++++++++++
The LTP build system can build kernel modules as well, setting
'$TST_NEEDS_MODULE' to module name will cause the library to look for the
module in a few possible paths.
If module was found the path to it will be stored into '$TST_MODPATH'
variable, if module wasn't found the test will exit with 'TCONF'.
Alternatively the 'tst_require_module()' function can be used to do the same
at runtime.
1.3 Optional command line parameters
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[source,sh]
-------------------------------------------------------------------------------
#!/bin/sh
# SPDX-License-Identifier: GPL-2.0-or-later
# Optional test command line parameters
TST_OPTS="af:"
TST_USAGE=usage
TST_PARSE_ARGS=parse_args
TST_TESTFUNC=do_test
. tst_test.sh
ALTERNATIVE=0
MODE="foo"
usage()
{
cat << EOF
usage: $0 [-a] [-f <foo|bar>]
OPTIONS
-a Enable support for alternative foo
-f Specify foo or bar mode
EOF
}
parse_args()
{
case $1 in
a) ALTERNATIVE=1;;
f) MODE="$2";;
esac
}
do_test()
{
...
}
tst_run
-------------------------------------------------------------------------------
The 'getopts' string for optional parameters is passed in the '$TST_OPTS'
variable. There are a few default parameters that cannot be used by a test,
these can be listed with passing help '-h' option to any test.
The function that prints the usage is passed in '$TST_USAGE', the help for
the options implemented in the library is appended when usage is printed.
Lastly the function '$PARSE_ARGS' is called with the option name in the '$1'
and, if option has argument, its value in the '$2'.
[source,sh]
-------------------------------------------------------------------------------
#!/bin/sh
# SPDX-License-Identifier: GPL-2.0-or-later
# Optional test positional parameters
TST_POS_ARGS=3
TST_USAGE=usage
TST_TESTFUNC=do_test
. tst_test.sh
usage()
{
cat << EOF
usage: $0 [min] [max] [size]
EOF
}
min="$1"
max="$2"
size="$3"
do_test()
{
...
}
tst_run
-------------------------------------------------------------------------------
You can also request a number of positional parameters by setting the
'$TST_POS_ARGS' variable. If you do, these will be available as they were
passed directly to the script in '$1', '$2', ..., '$n'.
1.4 Useful library functions
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Retrieving configuration variables
++++++++++++++++++++++++++++++++++
You may need to retrieve configuration values such as PAGESIZE, there is
'getconf' but as some system may not have it, you are advised to use
'tst_getconf' instead. Note that it implements subset of 'getconf'
system variables used by the testcases only.
[source,sh]
-------------------------------------------------------------------------------
# retrieve PAGESIZE
pagesize=`tst_getconf PAGESIZE`
-------------------------------------------------------------------------------
Sleeping for subsecond intervals
++++++++++++++++++++++++++++++++
Albeit there is a sleep command available basically everywhere not all
implementations can support sleeping for less than one second. And most of the
time sleeping for a second is too much. Therefore LTP includes 'tst_sleep'
that can sleep for defined amount of seconds, milliseconds or microseconds.
[source,sh]
-------------------------------------------------------------------------------
# sleep for 100 milliseconds
tst_sleep 100ms
-------------------------------------------------------------------------------
Retry a function call multiple times
++++++++++++++++++++++++++++++++++++
Sometimes an LTP test needs to retry a function call multiple times because
the system is not ready to process it successfully on the first try. The LTP
library has useful tools to handle the call retry automatically.
'TST_RETRY_FUNC()' will keep retrying for up to 1 second. If you want a custom
time limit use 'TST_RETRY_FN_EXP_BACKOFF()'. Both methods return the value
returned by the last 'FUNC' call.
The delay between retries starts at 1 microsecond and doubles after each call.
The retry loop ends when the function call succeeds or when the next delay
exceeds the specified time (1 second for 'TST_RETRY_FUNC()'). The maximum
delay is multiplied by TST_TIMEOUT_MUL. The total cumulative delay may be up
to twice as long as the adjusted maximum delay.
The C version of 'TST_RETRY_FUNC()' is a macro which takes two arguments:
* 'FUNC' is the complete function call with arguments which should be retried
multiple times.
* 'SUCCESS_CHECK' is a macro or function which will validate 'FUNC' return
value. 'FUNC' call was successful if 'SUCCESS_CHECK(ret)' evaluates to
non-zero.
Both retry methods clear 'errno' before every 'FUNC' call so your
'SUCCESS_CHECK' can look for specific error codes as well. The LTP library
also includes predefined 'SUCCESS_CHECK' macros for the most common call
conventions:
* 'TST_RETVAL_EQ0()' - The call was successful if 'FUNC' returned 0 or NULL
* 'TST_RETVAL_NOTNULL()' - The call was successful if 'FUNC' returned any
value other than 0 or NULL.
* 'TST_RETVAL_GE0()' - The call was successful if 'FUNC' returned value >= 0.
[source,c]
-------------------------------------------------------------------------------
/* Keep trying for 1 second */
TST_RETRY_FUNC(FUNC, SUCCESS_CHECK)
/* Keep trying for up to 2*N seconds */
TST_RETRY_FN_EXP_BACKOFF(FUNC, SUCCESS_CHECK, N)
-------------------------------------------------------------------------------
The shell version of 'TST_RETRY_FUNC()' is simpler and takes slightly
different arguments:
* 'FUNC' is a string containing the complete function or program call with
arguments.
* 'EXPECTED_RET' is a single expected return value. 'FUNC' call was successful
if the return value is equal to EXPECTED_RET.
[source,sh]
-------------------------------------------------------------------------------
# Keep trying for 1 second
TST_RETRY_FUNC "FUNC arg1 arg2 ..." "EXPECTED_RET"
# Keep trying for up to 2*N seconds
TST_RETRY_FN_EXP_BACKOFF "FUNC arg1 arg2 ..." "EXPECTED_RET" "N"
-------------------------------------------------------------------------------
Checking for integers
+++++++++++++++++++++
[source,sh]
-------------------------------------------------------------------------------
# returns zero if passed an integer parameter, non-zero otherwise
tst_is_int "$FOO"
-------------------------------------------------------------------------------
Checking for integers and floating point numbers
++++++++++++++++++++++++++++++++++++++++++++++++
[source,sh]
-------------------------------------------------------------------------------
# returns zero if passed an integer or floating point number parameter,
# non-zero otherwise
tst_is_num "$FOO"
-------------------------------------------------------------------------------
Obtaining random numbers
++++++++++++++++++++++++
There is no '$RANDOM' in portable shell, use 'tst_random' instead.
[source,sh]
-------------------------------------------------------------------------------
# get random integer between 0 and 1000 (including 0 and 1000)
tst_random 0 1000
-------------------------------------------------------------------------------
Formatting device with a filesystem
+++++++++++++++++++++++++++++++++++
The 'tst_mkfs' helper will format device with the filesystem.
[source,sh]
-------------------------------------------------------------------------------
# format test device with ext2
tst_mkfs ext2 $TST_DEVICE
# default params are $TST_FS_TYPE $TST_DEVICE
tst_mkfs
# optional parameters
tst_mkfs ext4 /dev/device -T largefile
-------------------------------------------------------------------------------
Mounting and unmounting filesystems
+++++++++++++++++++++++++++++++++++
The 'tst_mount' and 'tst_umount' helpers are a safe way to mount/umount
a filesystem.
The 'tst_mount' mounts '$TST_DEVICE' of '$TST_FS_TYPE' (optional) to
'$TST_MNTPOINT' (defaults to mntpoint), optionally using the
'$TST_MNT_PARAMS'. The '$TST_MNTPOINT' directory is created if it didn't
exist prior to the function call.
If the path passed (optional, must be absolute path, defaults to '$TST_MNTPOINT')
to the 'tst_umount' is not mounted (present in '/proc/mounts') it's noop.
Otherwise it retries to umount the filesystem a few times on failure.
This is a workaround since there are daemons dumb enough to probe all newly
mounted filesystems, and prevents them from being umounted shortly after they
were mounted.
ROD and ROD_SILENT
++++++++++++++++++
These functions supply the 'SAFE_MACROS' used in C although they work and are
named differently.
[source,sh]
-------------------------------------------------------------------------------
ROD_SILENT command arg1 arg2 ...
# is shorthand for:
command arg1 arg2 ... > /dev/null 2>&1
if [ $? -ne 0 ]; then
tst_brk TBROK "..."
fi
ROD command arg1 arg2 ...
# is shorthand for:
ROD arg1 arg2 ...
if [ $? -ne 0 ]; then
tst_brk TBROK "..."
fi
-------------------------------------------------------------------------------
WARNING: Keep in mind that output redirection (to a file) happens in the
caller rather than in the ROD function and cannot be checked for
write errors by the ROD function.
As a matter of a fact doing +ROD echo a > /proc/cpuinfo+ would work just fine
since the 'ROD' function will only get the +echo a+ part that will run just
fine.
[source,sh]
-------------------------------------------------------------------------------
# Redirect output to a file with ROD
ROD echo foo \> bar
-------------------------------------------------------------------------------
Note the '>' is escaped with '\', this causes that the '>' and filename are
passed to the 'ROD' function as parameters and the 'ROD' function contains
code to split '$@' on '>' and redirects the output to the file.
EXPECT_PASS{,_BRK} and EXPECT_FAIL{,_BRK}
+++++++++++++++++++++++++++++++++++++++++
[source,sh]
-------------------------------------------------------------------------------
EXPECT_PASS command arg1 arg2 ... [ \> file ]
EXPECT_FAIL command arg1 arg2 ... [ \> file ]
-------------------------------------------------------------------------------
'EXPECT_PASS' calls 'tst_res TPASS' if the command exited with 0 exit code,
and 'tst_res TFAIL' otherwise. 'EXPECT_FAIL' does vice versa.
Output redirection rules are the same as for the 'ROD' function. In addition
to that, 'EXPECT_FAIL' always redirects the command's stderr to '/dev/null'.
There are also 'EXPECT_PASS_BRK' and 'EXPECT_FAIL_BRK', which works the same way
except breaking a test when unexpected action happen.
It's possible to detect whether expected value happened:
[source,sh]
-------------------------------------------------------------------------------
if ! EXPECT_PASS command arg1 2\> /dev/null; then
continue
fi
-------------------------------------------------------------------------------
tst_kvcmp
+++++++++
This command compares the currently running kernel version given conditions
with syntax similar to the shell test command.
[source,sh]
-------------------------------------------------------------------------------
# Exit the test if kernel version is older or equal to 2.6.8
if tst_kvcmp -le 2.6.8; then
tst_brk TCONF "Kernel newer than 2.6.8 is needed"
fi
# Exit the test if kernel is newer than 3.8 and older than 4.0.1
if tst_kvcmp -gt 3.8 -a -lt 4.0.1; then
tst_brk TCONF "Kernel must be older than 3.8 or newer than 4.0.1"
fi
-------------------------------------------------------------------------------
[options="header"]
|=======================================================================
| expression | description
| -eq kver | Returns true if kernel version is equal
| -ne kver | Returns true if kernel version is not equal
| -gt kver | Returns true if kernel version is greater
| -ge kver | Returns true if kernel version is greater or equal
| -lt kver | Returns true if kernel version is lesser
| -le kver | Returns true if kernel version is lesser or equal
| -a | Does logical and between two expressions
| -o | Does logical or between two expressions
|=======================================================================
The format for kernel version has to either be with one dot e.g. '2.6' or with
two dots e.g. '4.8.1'.
.tst_fs_has_free
[source,sh]
-------------------------------------------------------------------------------
#!/bin/sh
...
# whether current directory has 100MB free space at least.
if ! tst_fs_has_free . 100MB; then
tst_brkm TCONF "Not enough free space"
fi
...
-------------------------------------------------------------------------------
The 'tst_fs_has_free' shell interface returns 0 if the specified free space is
satisfied, 1 if not, and 2 on error.
The second argument supports suffixes kB, MB and GB, the default unit is Byte.
.tst_retry
[source,sh]
-------------------------------------------------------------------------------
#!/bin/sh
...
# Retry ping command three times
tst_retry "ping -c 1 127.0.0.1"
if [ $? -ne 0 ]; then
tst_resm TFAIL "Failed to ping 127.0.0.1"
else
tst_resm TPASS "Successfully pinged 127.0.0.1"
fi
...
-------------------------------------------------------------------------------
The 'tst_retry' function allows you to retry a command after waiting small
amount of time until it succeeds or until given amount of retries has been
reached (default is three attempts).
1.5 Restarting daemons
~~~~~~~~~~~~~~~~~~~~~~
Restarting system daemons is a complicated task for two reasons.
* There are different init systems
(SysV init, systemd, etc...)
* Daemon names are not unified between distributions
(apache vs httpd, cron vs crond, various syslog variations)
To solve these problems LTP has 'testcases/lib/daemonlib.sh' library that
provides functions to start/stop/query daemons as well as variables that store
correct daemon name.
.Supported operations
|==============================================================================
| start_daemon() | Starts daemon, name is passed as first parameter.
| stop_daemon() | Stops daemon, name is passed as first parameter.
| restart_daemon() | Restarts daemon, name is passed as first parameter.
| status_daemon() | Detect daemon status (exit code: 0: running, 1: not running).
|==============================================================================
.Variables with detected names
|==============================================================================
| CROND_DAEMON | Cron daemon name (cron, crond).
| SYSLOG_DAEMON | Syslog daemon name (syslog, syslog-ng, rsyslog).
|==============================================================================
.Cron daemon restart example
[source,sh]
-------------------------------------------------------------------------------
#!/bin/sh
# SPDX-License-Identifier: GPL-2.0-or-later
# Cron daemon restart example
TCID=cron01
TST_COUNT=1
. test.sh
. daemonlib.sh
...
restart_daemon $CROND_DAEMON
...
tst_exit
-------------------------------------------------------------------------------
1.6 Access to the checkpoint interface
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The shell library provides an implementation of the checkpoint interface
compatible with the C version. All 'TST_CHECKPOINT_*' functions are available.
In order to initialize checkpoints '$TST_NEEDS_CHECKPOINTS' must be set to '1'
before the inclusion of 'tst_test.sh':
[source,sh]
-------------------------------------------------------------------------------
#!/bin/sh
TST_NEEDS_CHECKPOINTS=1
. tst_test.sh
-------------------------------------------------------------------------------
Since both the implementations are compatible, it's also possible to start
a child binary process from a shell test and synchronize with it. This process
must have checkpoints initialized by calling 'tst_reinit()'.
1.7 Parsing kernel .config
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The shell library provides an implementation of the kconfig parsing interface
compatible with the C version.
It's possible to pass kernel kconfig list for tst_require_kconfigs API with
'$TST_NEEDS_KCONFIGS'.
Optional '$TST_NEEDS_KCONFIGS_IFS' is used for splitting, default value is comma.
-------------------------------------------------------------------------------
#!/bin/sh
TST_NEEDS_KCONFIGS="CONFIG_EXT4_FS, CONFIG_QUOTACTL=y"
. tst_test.sh
-------------------------------------------------------------------------------
+66
View File
@@ -0,0 +1,66 @@
Supported kernel, libc, toolchain versions
==========================================
1. Build testing with GitHub Actions
------------------------------------
We test master branch in https://github.com/linux-test-project/ltp/actions[GitHub Actions]
to ensure LTP builds on various distributions including old, current and bleeding edge.
We test both gcc and clang toolchains, various architectures with cross-compilation.
For list of tested distros see
https://github.com/linux-test-project/ltp/blob/master/.github/workflows/ci.yml[.github/workflows/ci.yml].
NOTE: GitHub Actions does only build testing, passing the CI means only that
the test compiles fine on variety of different distributions and releases.
GitHub Actions also uses the latest distribution image of a particular release.
1.1 Oldest tested distributions
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[align="center",options="header"]
|==============================================================
| Distro | kernel | glibc | gcc | clang
| CentOS 7 | 3.10 | 2.17 | 4.8.5 | -
| Ubuntu 16.04 LTS xenial | 4.4 | 2.23 | 5.3.1 | -
| Debian 9 stretch (oldstable) | 4.9.30 | 2.24 | 6.3.0 | 3.8
|==============================================================
Older distributions are not officially supported, which means that it
may or may not work. It all depends on your luck. It should be possible
to compile latest LTP even on slightly older distributions than we
support with a few manual tweaks, e.g. disabling manually tests for
newly added syscalls, etc. Trivial fixes/workarounds may be accepted,
but users are encouraged to move to a newer distro.
If latest LTP cannot be compiled even with some amount of workarounds,
you may result to older LTP releases, however these are _not_ supported
in any way. Also if you are trying to run LTP on more than 10 years old
distribution you may as well reconsider you life choices.
1.2 Tested architectures
~~~~~~~~~~~~~~~~~~~~~~~~
[align="center",options="header"]
|==================================
| arch | build
| x86_64 | native
| x86 emulation | native
| aarch64 | cross compilation
| ppc64le | cross compilation
| s390x | cross compilation
|==================================
1.3 Supported libc
~~~~~~~~~~~~~~~~~~
[align="center",options="header"]
|==================================
| Libc | Note
| https://www.gnu.org/software/libc/[GNU C Library (glibc)] | Targetted libc, tested both compilation and actual test results.
| https://uclibc-ng.org/[uClibc-ng] | Although not being tested it should work as well as it attempt to maintain a glibc compatible interface.
| https://www.uclibc.org/[uClibc] | Older https://www.uclibc.org/[uClibc] might have problems.
| https://musl.libc.org/[musl] | Not yet fully supported (see
https://github.com/linux-test-project/ltp/blob/master/ci/alpine.sh[CI script]
for list of files which need to be deleted in order to compile under musl).
| binder (Android) | Please use https://android.googlesource.com/platform/external/ltp/[AOSP fork].
Regular → Executable
+173 -2685
View File
File diff suppressed because it is too large Load Diff
Regular → Executable
+14 -3
View File
@@ -1,7 +1,7 @@
LTP User Guidelines
===================
For compiling and installing and running the tests see `README.md`.
For compiling, installing and running the tests see `README.md`.
For running LTP network tests see `testcases/network/README.md`.
1. Library environment variables
@@ -10,16 +10,27 @@ For running LTP network tests see `testcases/network/README.md`.
|==============================================================================
| 'KCONFIG_PATH' | The path to the kernel config file, (if not set, it tries
the usual paths '/boot/config-RELEASE' or '/proc/config.gz').
| 'KCONFIG_SKIP_CHECK' | Skip kernel config check if variable set (not set by default).
| 'LTPROOT' | Prefix for installed LTP, the default is '/opt/ltp'.
| 'LTP_COLORIZE_OUTPUT' | Force colorized output behaviour. 'y' or '1': always colorize
'n' or '0': never colorize.
| 'LTP_DEV' | Path to the block device to be used
(C: '.needs_device = 1', shell: 'TST_NEEDS_DEVICE=1').
| 'LTP_SINGLE_FS_TYPE' | Testing only - specifies filesystem instead all
supported (for tests with '.all_filesystems').
| 'LTP_DEV_FS_TYPE' | Filesystem used for testing (default: 'ext2').
| 'LTP_TIMEOUT_MUL' | Multiply timeout, must be number >= 1 (> 1 is useful for
slow machines to avoid unexpected timeout).
Variable is also used in shell tests, but ceiled to int.
| 'LTP_VIRT_OVERRIDE' | Overrides virtual machine detection in the test
library. Setting it to empty string tell the library
that system is not a virtual machine. Other possible
values are 'kvm', 'xen', 'zvm' and 'microsoft' that
describe different types supervisors.
| 'PATH' | It's required to addjust path:
`PATH="$PATH:$LTPROOT/testcases/bin"`
| 'TMPDIR' | Base directory for template directory, which is required by C tests
`tst_test->needs_tmpdir=1` (or others) or shell 'TST_NEEDS_TMPDIR=1').
| 'TMPDIR' | Base directory for template directory (C: '.needs_tmpdir = 1'
and others, which imply it, shell: 'TST_NEEDS_TMPDIR=1').
| 'TST_NO_CLEANUP' | Disable running test cleanup (defined in 'TST_CLEANUP').
|==============================================================================
+5
View File
@@ -0,0 +1,5 @@
/*.txt
/docbook-xsl.css
/metadata.html
/metadata.pdf
/metadata.chunked/
+69
View File
@@ -0,0 +1,69 @@
# SPDX-License-Identifier: GPL-2.0-or-later
# Copyright (c) 2019 Cyril Hrubis <chrubis@suse.cz>
# Copyright (c) 2020 Petr Vorel <pvorel@suse.cz>
top_srcdir ?= ..
include $(top_srcdir)/include/mk/env_pre.mk
include $(top_srcdir)/include/mk/functions.mk
ifeq ($(METADATA_GENERATOR),asciidoctor)
METADATA_GENERATOR_CMD := asciidoctor
METADATA_GENERATOR_PARAMS := -d book metadata.txt
METADATA_GENERATOR_PARAMS_HTML := -b xhtml
METADATA_GENERATOR_PARAMS_PDF := -b pdf -r asciidoctor-pdf
else ifeq ($(METADATA_GENERATOR),asciidoc)
METADATA_GENERATOR_CMD := a2x
METADATA_GENERATOR_PARAMS := --xsltproc-opts "--stringparam toc.section.depth 1" -d book -L --resource="$(PWD)" metadata.txt
METADATA_GENERATOR_PARAMS_HTML := -f xhtml
METADATA_GENERATOR_PARAMS_PDF := -f pdf
METADATA_GENERATOR_PARAMS_HTML_CHUNKED := -f chunked
else ifeq ($(METADATA_GENERATOR),)
$(error 'METADATA_GENERATOR' not not configured, run ./configure in the root directory)
else
$(error '$(METADATA_GENERATOR)' not supported, only asciidoctor and asciidoc are supported)
endif
ifdef VERBOSE
METADATA_GENERATOR_PARAMS += -v
endif
CLEAN_TARGETS := *.css *.js *.txt
ifeq ($(WITH_METADATA_HTML),yes)
MAKE_TARGETS += metadata.html
ifneq ($(METADATA_GENERATOR_PARAMS_HTML_CHUNKED),)
MAKE_TARGETS += metadata.chunked
endif
endif
ifeq ($(WITH_METADATA_PDF),yes)
MAKE_TARGETS += metadata.pdf
endif
INSTALL_DIR = metadata
INSTALL_TARGETS = *.css *.js
ifndef METADATA_GENERATOR
METADATA_GENERATOR := asciidoctor
endif
txt: ${abs_top_builddir}/metadata/ltp.json
$(abs_srcdir)/testinfo.pl $<
ifeq ($(WITH_METADATA_HTML),yes)
metadata.html: txt
$(METADATA_GENERATOR_CMD) $(METADATA_GENERATOR_PARAMS) $(METADATA_GENERATOR_PARAMS_HTML)
ifneq ($(METADATA_GENERATOR_PARAMS_HTML_CHUNKED),)
metadata.chunked: txt
$(METADATA_GENERATOR_CMD) $(METADATA_GENERATOR_PARAMS) $(METADATA_GENERATOR_PARAMS_HTML_CHUNKED)
endif
endif
ifeq ($(WITH_METADATA_PDF),yes)
metadata.pdf: txt
$(METADATA_GENERATOR_CMD) $(METADATA_GENERATOR_PARAMS) $(METADATA_GENERATOR_PARAMS_PDF)
endif
include $(top_srcdir)/include/mk/generic_leaf_target.mk
+248
View File
@@ -0,0 +1,248 @@
Motivation for metadata extraction
==================================
Exporting documentation
-----------------------
This allow us to build browsable documentation for the testcases, e.g. a
catalogue of test information that would be searchable etc. At this point there
is a single page generated from the extracted data that tries to outline the
intent.
Propagating test requirements
-----------------------------
Some subtests require different hardware resources/software versions/etc. the
test execution framework needs to consume these so that it can locate proper
hardware, install proper software, etc.
Some examples of requirements are:
* Test needs at least 1GB of RAM.
* Test needs a block device at least 512MB in size
* Test needs a NUMA machine with two memory nodes and at least 300 free pages on each node
* Test needs i2c eeprom connected on a i2c bus
* Test needs two serial ports connected via null-modem cable
With this information extracted from the tests the testrunner can then map the
requirements on the available machines in a lab and select a proper machine for
the particular (sub)set of testcases as well as supply a particular test with
additional information needed for the test, such as address of the i2c device,
paths to the serial devices, etc. In the case of virtual machines the test could
also dynamically prepare the correct environment for the test on demand.
Parallel test execution
-----------------------
An LTP testrun on a modern hardware wastes most of the machine resources
because the testcases are running sequentially. However in order to execute
tests in parallel we need to know which system resources are utilized by a
given test, as obviously we cannot run two tests that monopolize the same
resource. In some cases we would also need to partition the system resource
accordingly, e.g. if we have two memory stress tests running at the same time
we will need to cap each of these tests on half of the available memory, or
make sure that sum of the memory used by these two tests is not greater an
available memory.
Examples of such tests are:
* Tests that mess with global system state
- system time (e.g. settimeofday() test and leap second test)
- SysV SHM
- ...
* Tests that use block device
* Tests that work with a particular hardware resource
- i2c eeprom test
- serial port tests
- ...
Exporting test runtime/timeout to the testrunner
------------------------------------------------
Currently most of the testrunners usually do not know for how long is the test
supposed to run, this means that we have to guess some upper limit on how long
a test is supposed to run. The value is usually twice of the maximal runtime
for all testcases or whole suite or even larger. This means that we are wasting
time in the case that the test ends up stuck and we could have failed it much
sooner in most of the cases. This becomes quite important for a kernel
regression tests that do crash the host, if the information that the test is
supposed to crash a kernel under a minute is exported to the testrunner we can
reboot the machine much faster in an event of a crash.
Getting rid of runtest files
----------------------------
This would also allow us to get rid of the unflexible and hard to maintain
runtest files. Once this system is in place we will have a list of all tests
along with their respective metadata - which means that we will be able to
generate subsets of the test easily on the fly.
In order to achieve this we need two things:
Each test will describe which syscall/functionality it tests in the metadata.
Then we could define groups of tests based on that. I.e. instead of having
syscall runtest file we would ask the testrunner to run all test that have a
defined which syscall they test, or whose filename matches a particular syscall name.
Secondly we will have to store the test variants in the test metadata instead
of putting them in a file that is unrelated to the test.
For example:
* To run CVE related test we would select testcases with CVE tag
* To run IPC test we will define a list of IPC syscalls and run all syscall
test that are in the list
* And many more...
Implementation
==============
The docparser is implemented as a minimal C tokenizer that can parse and
extract code comments and C structures. The docparser then runs over all C
sources in the testcases directory and if tst\_test structure is present in the
source it's parsed and the result is included in the resulting metadata.
During parsing the metadata is stored in a simple key/value storage that more
or less follows C structure layout, i.e. can include hash, array, and string.
Once the parsing is finished the result is filtered so that only interesting
fields of the tst\_test structure are included and then converted into JSON
output.
This process produces one big JSON file with metadata for all tests, that
is then installed along with the testcases. This would then be used by the
testrunner.
The test requirements are stored in the tst\_test structure either as
bitflags, integers or arrays of strings:
```c
struct tst_test test = {
...
/* tests needs to run with UID=0 */
.needs_root = 1,
/*
* Tests needs a block device at least 1024MB in size and also
* mkfs.ext4 installed.
*/
.needs_device = 1,
.dev_min_size = 1024,
.dev_fs_type = ext4,
/* Indicates that the test is messing with system wall clock */
.restore_wallclock = 1,
/* Tests needs uinput either compiled in or loaded as a module */
.needs_drivers = (const char *[]) {
"uinput",
NULL
},
/* Tests needs enabled kernel config flags */
.needs_kconfigs = (const char *[]) {
"CONFIG_X86_INTEL_UMIP=y",
NULL
},
/* Additional array of key value pairs */
.tags = (const struct tst_tag[]) {
{"linux-git", "43a6684519ab"},
{"CVE", "2017-2671"},
{NULL, NULL}
}
};
```
The test documentation is stored in a special comment such as:
```
/*\
* Test description
*
* This is a test description.
* Consisting of several lines.
*/
```
Which will yield following JSON output:
```json
"testcaseXY": {
"needs_root": "1",
"needs_device": "1",
"dev_min_size": "1024",
"dev_fs_type": "ext4",
"restore_wallclock": "1",
"needs_drivers": [
"uinput",
],
"needs_kconfigs": [
"CONFIG_X86_INTEL_UMIP=y",
],
"tags": [
[
"linux-git",
"43a6684519ab"
],
[
"CVE",
"2017-2671"
],
],
"doc": [
"Test description",
"",
"This is a test description.",
"Consisting of several lines."
],
"fname": "testcases/kernel/syscalls/foo/testcaseXY.c"
},
```
The final JSON file is JSON object of test descriptions indexed by a test name
with a header describing the testsuite:
```json
{
"testsuite": "Linux Test Project",
"testsuite_short": "LTP",
"url": "https://github.com/linux-test-project/ltp/",
"scm_url_base": "https://github.com/linux-test-project/ltp/tree/master/",
"timeout": 300,
"version": "20200930",
"tests": {
"testcaseXY": {
...
},
...
}
}
```
Open Points
===========
There are stil some loose ends. Mostly it's not well defined where to put
things and how to format them.
* Some of the hardware requirements are already listed in the tst\_test. Should
we put all of them there?
* What would be the format for test documentation and how to store things such
as test variants there?
So far this proof of concept generates a metadata file. I guess that we need
actual consumers which will help to settle things down, I will try to look into
making use of this in the runltp-ng at least as a reference implementation.
+521
View File
@@ -0,0 +1,521 @@
#!/usr/bin/perl
# SPDX-License-Identifier: GPL-2.0-or-later
# Copyright (c) 2019 Cyril Hrubis <chrubis@suse.cz>
# Copyright (c) 2020-2021 Petr Vorel <pvorel@suse.cz>
use strict;
use warnings;
use JSON qw(decode_json);
use Cwd qw(abs_path);
use File::Basename qw(dirname);
use constant OUTDIR => dirname(abs_path($0));
# tags which expect git tree, also need constant for URL
our @TAGS_GIT = ("linux-git", "linux-stable-git", "glibc-git");
# tags should map these in lib/tst_test.c
use constant LINUX_GIT_URL => "https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=";
use constant LINUX_STABLE_GIT_URL => "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=";
use constant GLIBC_GIT_URL => "https://sourceware.org/git/?p=glibc.git;a=commit;h=";
use constant CVE_DB_URL => "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-";
sub load_json
{
my ($fname, $mode) = @_;
local $/;
open(my $fh, '<', $fname) or die("Can't open $fname $!");
return <$fh>;
}
sub log_info
{
my $msg = shift;
print STDERR "INFO: $msg\n";
}
sub log_warn
{
my $msg = shift;
print STDERR "WARN: $msg\n";
}
sub print_asciidoc_page
{
my ($fh, $json, $title, $content) = @_;
print $fh <<EOL;
// -*- mode:doc; -*-
// vim: set syntax=asciidoc:
$title
$content
EOL
}
sub tag_url {
my ($tag, $value, $scm_url_base) = @_;
if ($tag eq "fname") {
return $scm_url_base . $value;
}
if ($tag eq "CVE") {
return CVE_DB_URL . $value;
}
# *_GIT_URL
my $key = tag2env($tag) . "_URL";
if (defined($constant::declared{"main::$key"})) {
return eval("main::$key") . $value;
}
if ('known-fail') {
return '';
}
die("unknown constant '$key' for tag $tag, define it!");
}
sub bold
{
return "*$_[0]*";
}
sub code
{
return "+$_[0]+";
}
sub hr
{
return "\n\n'''\n\n";
}
sub html_a
{
my ($url, $text) = @_;
# escape: ] |
$text =~ s/([]|])/\\$1/g;
return "$url\[$text\]";
}
sub h1
{
return "== $_[0]\n";
}
sub h2
{
return "=== $_[0]\n";
}
sub h3
{
return "==== $_[0]\n";
}
sub label
{
return "[[$_[0]]]\n";
}
sub paragraph
{
return "$_[0]\n\n";
}
sub reference
{
my ($link, %args) = @_;
$args{text} //= $link;
$args{delimiter} //= "";
return "xref:$link\[$args{text}\]$args{delimiter}\n";
}
sub table
{
return "|===\n";
}
sub table_escape
{
my $out = $_[0];
$out =~ s/\|/\\|/g;
return $out;
}
sub print_defined
{
my ($key, $val, $val2) = @_;
if (defined($val)) {
return paragraph(bold($key) . ": " . $val . (defined($val2) ? " $val2" : ""));
}
}
sub content_about
{
my $json = shift;
my $content;
$content .= print_defined("URL", $json->{'testsuite'}->{'url'});
$content .= print_defined("Version", $json->{'testsuite'}->{'version'});
$content .= print_defined("Default timeout", $json->{'defaults'}->{'timeout'}, "seconds");
return $content;
}
sub uniq {
my %seen;
grep !$seen{$_}++, @_;
}
sub get_test_names
{
my @names = @{$_[0]};
my ($letter, $prev_letter);
my $content;
for my $name (sort @names) {
$letter = substr($name, 0, 1);
if (defined($prev_letter) && $letter ne $prev_letter) {
$content .= "\n";
}
$content .= reference($name, delimiter => " ");
$prev_letter = $letter;
}
$content .= "\n";
return $content;
}
sub get_test_letters
{
my @names = @{$_[0]};
my $letter;
my $prev_letter = "";
my $content;
for (@names) {
$_ = substr($_, 0, 1);
}
@names = uniq(@names);
for my $letter (@names) {
$content .= reference($letter);
}
$content .= "\n";
return $content;
}
sub tag2title
{
my $tag = shift;
return code(".$tag");
}
sub get_filters
{
my $json = shift;
my %data;
while (my ($k, $v) = each %{$json->{'tests'}}) {
for my $j (keys %{$v}) {
next if ($j eq 'fname' || $j eq 'doc');
$data{$j} = () unless (defined($data{$j}));
if ($j eq 'tags') {
for my $tags (@{$v}{'tags'}) {
for my $tag (@$tags) {
my $k2 = $$tag[0];
my $v2 = $$tag[1];
$data{$j}{$k2} = () unless (defined($data{$j}{$k2}));
push @{$data{$j}{$k2}}, $k unless grep{$_ eq $k} @{$data{$j}{$k2}};
}
}
} else {
push @{$data{$j}}, $k unless grep{$_ eq $k} @{$data{$j}};
}
}
}
return \%data;
}
sub content_filter
{
my $k = $_[0];
my $title = $_[1];
my $desc = $_[2];
my $h = $_[3];
my ($letter, $prev_letter, $content);
$content = label($k);
$content .= $title;
$content .= paragraph("Tests containing $desc flag.");
$content .= get_test_names(\@{$h});
return $content;
}
sub content_filters
{
my $json = shift;
my $data = get_filters($json);
my %h = %$data;
my $content;
for my $k (sort keys %$data) {
my $title = tag2title($k);
if (ref($h{$k}) eq 'HASH') {
$content .= label($k);
$content .= h2($title);
for my $k2 (sort keys %{$h{$k}}) {
my $title2 = code($k2);
$content .= content_filter($k2, h3($title2), "$title $title2", $h{$k}{$k2});
}
} else {
$content .= content_filter($k, h2($title), $title, \@{$h{$k}});
}
}
return $content;
}
sub tag2env
{
my $tag = shift;
$tag =~ s/-/_/g;
return uc($tag);
}
sub detect_git
{
my %data;
for my $tag (@TAGS_GIT) {
my $env = tag2env($tag);
unless (defined $ENV{$env} && $ENV{$env}) {
log_warn("git repository $tag not defined. Define it in \$$env");
next;
}
unless (-d $ENV{$env}) {
log_warn("\$$env does not exit ('$ENV{$env}')");
next;
}
if (system("which git >/dev/null")) {
log_warn("git not in \$PATH ('$ENV{'PATH'}')");
next;
}
chdir($ENV{$env});
if (!system("git log -1 > /dev/null")) {
log_info("using '$ENV{$env}' as $env repository");
$data{$tag} = $ENV{$env};
} else {
log_warn("git failed, git not installed or \$$env is not a git repository? ('$ENV{$env}')");
}
chdir(OUTDIR);
}
return \%data;
}
sub content_all_tests
{
my $json = shift;
my @names = sort keys %{$json->{'tests'}};
my $letters = paragraph(get_test_letters(\@names));
my $git_url = detect_git();
my $tmp = undef;
my $printed = "";
my $content;
$content .= paragraph("Total $#names tests.");
$content .= $letters;
$content .= get_test_names(\@names);
for my $name (@names) {
my $letter = substr($name, 0, 1);
if ($printed ne $letter) {
$content .= label($letter);
$content .= h2($letter);
$printed = $letter;
}
$content .= hr() if (defined($tmp));
$content .= label($name);
$content .= h3($name);
$content .= $letters;
if (defined($json->{'testsuite'}->{'scm_url_base'}) &&
defined($json->{'tests'}{$name}{fname})) {
$content .= paragraph(html_a(tag_url("fname", $json->{'tests'}{$name}{fname},
$json->{'testsuite'}->{'scm_url_base'}), "source"));
}
if (defined $json->{'tests'}{$name}{doc}) {
for my $doc (@{$json->{'tests'}{$name}{doc}}) {
# fix formatting for asciidoc [DOCUMENTATION] => *Documentation*
if ($doc =~ s/^\[(.*)\]$/$1/) {
$doc = paragraph(bold(ucfirst(lc($doc))));
}
$content .= "$doc\n";
}
$content .= "\n";
}
if ($json->{'tests'}{$name}{timeout}) {
if ($json->{'tests'}{$name}{timeout} eq -1) {
$content .= paragraph("Test timeout is disabled");
} else {
$content .= paragraph("Test timeout is $json->{'tests'}{$name}{timeout} seconds");
}
} else {
$content .= paragraph("Test timeout defaults to $json->{'defaults'}->{'timeout'} seconds");
}
my $tmp2 = undef;
for my $k (sort keys %{$json->{'tests'}{$name}}) {
my $v = $json->{'tests'}{$name}{$k};
next if ($k eq "tags" || $k eq "fname" || $k eq "doc");
if (!defined($tmp2)) {
$content .= table . "|Key|Value\n\n"
}
$content .= "|" . reference($k, text => tag2title($k)) . "\n|";
if (ref($v) eq 'ARRAY') {
# two dimensional array
if (ref(@$v[0]) eq 'ARRAY') {
for my $v2 (@$v) {
$content .= paragraph(table_escape(join(' ', @$v2)));
}
} else {
# one dimensional array
$content .= table_escape(join(', ', @$v));
}
} else {
# plain content
$content .= table_escape($v);
}
$content .= "\n";
$tmp2 = 1;
}
if (defined($tmp2)) {
$content .= table . "\n";
}
$tmp2 = undef;
my %commits;
my @sorted_tags = sort { $a->[0] cmp $b->[0] } @{$json->{'tests'}{$name}{tags} // []};
for my $tag (@sorted_tags) {
if (!defined($tmp2)) {
$content .= table . "|Tag|Info\n"
}
my $k = @$tag[0];
my $v = @$tag[1];
my $url;
if (defined($$git_url{$k})) {
$commits{$k} = () unless (defined($commits{$k}));
unless (defined($commits{$k}{$v})) {
chdir($$git_url{$k});
$commits{$k}{$v} = `git log --pretty=format:'%s' -1 $v`;
chdir(OUTDIR);
}
$v .= ' ("' . $commits{$k}{$v} . '")';
}
$url = tag_url($k, @$tag[1]);
if ($url) {
$v = html_a($url, $v);
}
# tag value value can be split into more lines if too long
# i.e. URL in known-fail
for (@$tag[2 .. $#$tag]) {
$v .= " $_";
}
$content .= "\n|" . reference($k) . "\n|$v\n";
$tmp2 = 1;
}
if (defined($tmp2)) {
$content .= table . "\n";
}
$tmp = 1;
}
return $content;
}
my $json = decode_json(load_json($ARGV[0]));
my $config = [
{
file => "about.txt",
title => h2("About $json->{'testsuite'}->{'name'}"),
content => \&content_about,
},
{
file => "filters.txt",
title => h1("Test filtered by used flags"),
content => \&content_filters,
},
{
file => "all-tests.txt",
title => h1("All tests"),
content => \&content_all_tests,
},
];
sub print_asciidoc_main
{
my $config = shift;
my $file = "metadata.txt";
my $content;
open(my $fh, '>', $file) or die("Can't open $file $!");
$content = <<EOL;
:doctype: inline
:sectanchors:
:toc:
EOL
for my $c (@{$config}) {
$content .= "include::$c->{'file'}\[\]\n";
}
print_asciidoc_page($fh, $json, h1($json->{'testsuite'}->{'short_name'} . " test catalog"), $content);
}
for my $c (@{$config}) {
open(my $fh, '>', $c->{'file'}) or die("Can't open $c->{'file'} $!");
print_asciidoc_page($fh, $json, $c->{'title'}, $c->{'content'}->($json));
}
print_asciidoc_main($config);
Regular → Executable
+2 -20
View File
@@ -1,24 +1,6 @@
#
# include Makefile.
#
# Copyright (C) 2009, Cisco Systems Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
# SPDX-License-Identifier: GPL-2.0-or-later
# Copyright (C) 2009, Cisco Systems Inc.
# Ngie Cooper, July 2009
#
top_srcdir ?= ..
View File
+1 -1
View File
@@ -29,7 +29,7 @@
#include <sys/sem.h>
#include "test.h"
#include "lapi/semun.h"
#include "lapi/sem.h"
void cleanup(void);
void setup(void);
View File
Regular → Executable
View File
Regular → Executable
+3 -3
View File
@@ -5,8 +5,8 @@
* Petr Vorel <petr.vorel@gmail.com>
*/
#ifndef ABISIZE_H__
#define ABISIZE_H__
#ifndef LAPI_ABISIZE_H__
#define LAPI_ABISIZE_H__
/* __WORDSIZE replacement */
#if defined(__LP64__) || defined(_LP64)
@@ -28,4 +28,4 @@
(defined(__aarch64__) && defined(__ILP32__)) || \
defined(TST_ABI64)
#endif /* ABISIZE_H__ */
#endif /* LAPI_ABISIZE_H__ */
Regular → Executable
+3 -3
View File
@@ -1,7 +1,7 @@
//SPDX-License-Identifier: GPL-2.0-or-later
#ifndef LAPI_ACCT_H
#define LAPI_ACCT_H
#ifndef LAPI_ACCT_H__
#define LAPI_ACCT_H__
#include <sys/types.h>
#include "config.h"
@@ -71,4 +71,4 @@ enum {
# endif
#endif /* HAVE_STRUCT_ACCT_V3 */
#endif /* LAPI_ACCT_H */
#endif /* LAPI_ACCT_H__ */
Regular → Executable
+30 -3
View File
@@ -8,8 +8,8 @@
* some eBPF testing without any external dependencies.
*/
#ifndef BPF_H
# define BPF_H
#ifndef LAPI_BPF_H__
#define LAPI_BPF_H__
#include <stdint.h>
@@ -27,6 +27,7 @@
#define BPF_JNE 0x50 /* jump != */
#define BPF_SIZE(code) ((code) & 0x18)
#define BPF_B 0x10 /* 8-bit */
#define BPF_W 0x00 /* 32-bit */
#define BPF_DW 0x18 /* double word (64-bit) */
@@ -37,8 +38,10 @@
#define BPF_OP(code) ((code) & 0xf0)
#define BPF_ADD 0x00
#define BPF_SUB 0x10
#define BPF_DIV 0x30
#define BPF_LSH 0x60
#define BPF_RSH 0x70
#define BPF_MOD 0x90
#define BPF_JEQ 0x10
@@ -449,6 +452,14 @@ enum bpf_func_id {
.off = 0, \
.imm = 0 })
#define BPF_ALU32_REG(OP, DST, SRC) \
((struct bpf_insn) { \
.code = BPF_ALU | BPF_OP(OP) | BPF_X, \
.dst_reg = DST, \
.src_reg = SRC, \
.off = 0, \
.imm = 0 })
#define BPF_ALU64_IMM(OP, DST, IMM) \
((struct bpf_insn) { \
.code = BPF_ALU64 | BPF_OP(OP) | BPF_K, \
@@ -457,6 +468,14 @@ enum bpf_func_id {
.off = 0, \
.imm = IMM })
#define BPF_ALU32_IMM(OP, DST, IMM) \
((struct bpf_insn) { \
.code = BPF_ALU | BPF_OP(OP) | BPF_K, \
.dst_reg = DST, \
.src_reg = 0, \
.off = 0, \
.imm = IMM })
#define BPF_MOV64_REG(DST, SRC) \
((struct bpf_insn) { \
.code = BPF_ALU64 | BPF_MOV | BPF_X, \
@@ -465,6 +484,14 @@ enum bpf_func_id {
.off = 0, \
.imm = 0 })
#define BPF_MOV32_REG(DST, SRC) \
((struct bpf_insn) { \
.code = BPF_ALU | BPF_MOV | BPF_X, \
.dst_reg = DST, \
.src_reg = SRC, \
.off = 0, \
.imm = 0 })
#define BPF_LD_IMM64(DST, IMM) \
BPF_LD_IMM64_RAW(DST, 0, IMM)
@@ -564,4 +591,4 @@ static inline int bpf(enum bpf_cmd cmd, union bpf_attr *attr, unsigned int size)
}
/* End copy from tools/lib/bpf */
#endif /* BPF_H */
#endif /* LAPI_BPF_H__ */
Regular → Executable
+11 -3
View File
@@ -3,8 +3,8 @@
* Copyright (c) 2019 Richard Palethorpe <rpalethorpe@suse.com>
*/
#ifndef LAPI_CAPABILITY_H
#define LAPI_CAPABILITY_H
#ifndef LAPI_CAPABILITY_H__
#define LAPI_CAPABILITY_H__
#include "config.h"
@@ -24,6 +24,10 @@
# define CAP_NET_RAW 13
#endif
#ifndef CAP_SYS_CHROOT
# define CAP_SYS_CHROOT 18
#endif
#ifndef CAP_SYS_ADMIN
# define CAP_SYS_ADMIN 21
#endif
@@ -40,6 +44,10 @@
# define CAP_SYS_RESOURCE 24
#endif
#ifndef CAP_BPF
# define CAP_BPF 39
#endif
#ifndef CAP_TO_INDEX
# define CAP_TO_INDEX(x) ((x) >> 5)
#endif
@@ -48,4 +56,4 @@
# define CAP_TO_MASK(x) (1 << ((x) & 31))
#endif
#endif
#endif /* LAPI_CAPABILITY_H__ */
Regular → Executable
+11 -4
View File
@@ -10,6 +10,7 @@
#include <sys/syscall.h>
#include <linux/types.h>
#include <sched.h>
#include <stdint.h>
#include "config.h"
#include "lapi/syscalls.h"
@@ -26,7 +27,7 @@ struct clone_args {
uint64_t __attribute__((aligned(8))) tls;
};
int clone3(struct clone_args *args, size_t size)
static inline int clone3(struct clone_args *args, size_t size)
{
return tst_syscall(__NR_clone3, args, size);
}
@@ -36,12 +37,18 @@ int clone3(struct clone_args *args, size_t size)
#define CLONE_PIDFD 0x00001000 /* set if a pidfd should be placed in parent */
#endif
void clone3_supported_by_kernel(void)
#ifndef CLONE_NEWUSER
# define CLONE_NEWUSER 0x10000000
#endif
static inline void clone3_supported_by_kernel(void)
{
long ret;
if ((tst_kvercmp(5, 3, 0)) < 0) {
/* Check if the syscall is backported on an older kernel */
TEST(syscall(__NR_clone3, NULL, 0));
if (TST_RET == -1 && TST_ERR == ENOSYS)
ret = syscall(__NR_clone3, NULL, 0);
if (ret == -1 && errno == ENOSYS)
tst_brk(TCONF, "Test not supported on kernel version < v5.3");
}
}
+28
View File
@@ -0,0 +1,28 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/* Copyright (c) 2021 SUSE LLC */
#ifndef LAPI_CLOSE_RANGE__
# define LAPI_CLOSE_RANGE__
# include "lapi/syscalls.h"
# ifdef HAVE_LINUX_CLOSE_RANGE_H
# include <linux/close_range.h>
# endif
# ifndef CLOSE_RANGE_UNSHARE
# define CLOSE_RANGE_UNSHARE (1U << 1)
# endif
# ifndef CLOSE_RANGE_CLOEXEC
# define CLOSE_RANGE_CLOEXEC (1U << 2)
# endif
# ifndef HAVE_CLOSE_RANGE
static inline int close_range(unsigned int fd, unsigned int max_fd,
unsigned int flags)
{
return tst_syscall(__NR_close_range, fd, max_fd, flags);
}
# endif
#endif /* LAPI_CLOSE_RANGE_H__ */
Regular → Executable
+4 -4
View File
@@ -4,15 +4,15 @@
* Keep all the common defines/checks for the timer tests here
*/
#ifndef __COMMON_TIMERS_H__
#define __COMMON_TIMERS_H__
#ifndef LAPI_COMMON_TIMERS_H__
#define LAPI_COMMON_TIMERS_H__
#include "config.h"
#include "lapi/syscalls.h"
#include "lapi/posix_clocks.h"
#ifndef NSEC_PER_SEC
#define NSEC_PER_SEC (1000000000L)
#define NSEC_PER_SEC (1000000000LL)
#endif
static const clock_t clock_list[] = {
@@ -78,4 +78,4 @@ static inline int have_cputime_timers(void)
*/
typedef int kernel_timer_t;
#endif
#endif /* LAPI_COMMON_TIMERS_H__ */
Regular → Executable
+3 -3
View File
@@ -17,8 +17,8 @@
#define _GNU_SOURCE
#include <sched.h>
#ifndef LTP_CPUSET_H
#define LTP_CPUSET_H
#ifndef LAPI_CPUSET_H__
#define LAPI_CPUSET_H__
#ifndef CPU_ALLOC
#define CPU_ALLOC(ncpus) malloc(sizeof(cpu_set_t)); \
@@ -48,4 +48,4 @@ if (ncpus > CPU_SETSIZE) { \
#define CPU_ISSET_S(cpu, size, mask) CPU_ISSET(cpu, mask)
#endif
#endif /* LTP_CPUSET_H */
#endif /* LAPI_CPUSET_H__ */
Regular → Executable
+3 -3
View File
@@ -3,8 +3,8 @@
* Copyright (c) 2018 Richard Palethorpe <rpalethorpe@suse.com>
*/
#ifndef CRYPTOUSER_H__
#define CRYPTOUSER_H__
#ifndef LAPI_CRYPTOUSER_H__
#define LAPI_CRYPTOUSER_H__
#ifdef HAVE_LINUX_CRYPTOUSER_H
# include <linux/cryptouser.h>
@@ -179,4 +179,4 @@ struct crypto_report_acomp {
# define CRYPTO_ALG_TYPE_ACOMPRESS_MASK 0x0000000e
#endif
#endif /* CRYPTOUSER_H__ */
#endif /* LAPI_CRYPTOUSER_H__ */
Regular → Executable
View File
Regular → Executable
+48 -3
View File
@@ -1,13 +1,58 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
/* SPDX-License-Identifier: GPL-2.0-or-later
*
* Copyright (c) 2016 Cyril Hrubis <chrubis@suse.cz>
* Copyright (c) 2021 Xie Ziyao <xieziyao@huawei.com>
*/
#ifndef LAPI_EPOLL_H__
#define LAPI_EPOLL_H__
#include "lapi/syscalls.h"
#include "tst_timer.h"
#ifndef EPOLL_CLOEXEC
# define EPOLL_CLOEXEC 02000000
#define EPOLL_CLOEXEC 02000000
#endif
static inline void epoll_pwait_supported(void)
{
/* allow the tests to fail early */
tst_syscall(__NR_epoll_pwait);
}
#ifndef HAVE_EPOLL_PWAIT
static inline int epoll_pwait(int epfd, struct epoll_event *events,
int maxevents, int timeout,
const sigset_t *sigmask)
{
return tst_syscall(__NR_epoll_pwait, epfd, events, maxevents,
timeout, sigmask, _NSIG / 8);
}
#endif
static inline void epoll_pwait2_supported(void)
{
/* allow the tests to fail early */
tst_syscall(__NR_epoll_pwait2);
}
#ifndef HAVE_EPOLL_PWAIT2
static inline int epoll_pwait2(int epfd, struct epoll_event *events,
int maxevents, const struct timespec *timeout,
const sigset_t *sigmask)
{
if (timeout == NULL)
return tst_syscall(__NR_epoll_pwait2, epfd, events, maxevents,
NULL, sigmask, _NSIG / 8);
struct __kernel_timespec ts;
ts.tv_sec = timeout->tv_sec;
ts.tv_nsec = timeout->tv_nsec;
return tst_syscall(__NR_epoll_pwait2, epfd, events, maxevents,
&ts, sigmask, _NSIG / 8);
}
#endif
#endif /* LAPI_EPOLL_H__ */
Regular → Executable
+6 -6
View File
@@ -3,20 +3,20 @@
* Copyright (C) 2018 MediaTek Inc. All Rights Reserved.
*/
#ifndef EXECVEAT_H
#define EXECVEAT_H
#ifndef LAPI_EXECVEAT_H__
#define LAPI_EXECVEAT_H__
#include <sys/types.h>
#include "config.h"
#include "lapi/syscalls.h"
#if !defined(HAVE_EXECVEAT)
int execveat(int dirfd, const char *pathname,
char *const argv[], char *const envp[],
int flags)
static inline int execveat(int dirfd, const char *pathname,
char *const argv[], char *const envp[],
int flags)
{
return tst_syscall(__NR_execveat, dirfd, pathname, argv, envp, flags);
}
#endif
#endif /* EXECVEAT_H */
#endif /* LAPI_EXECVEAT_H__ */
Regular → Executable
+3 -3
View File
@@ -4,8 +4,8 @@
* Copyright (c) 2014 Fujitsu Ltd.
*/
#ifndef FALLOCATE_H
#define FALLOCATE_H
#ifndef LAPI_FALLOCATE_H__
#define LAPI_FALLOCATE_H__
#include <sys/types.h>
#include <endian.h>
@@ -57,4 +57,4 @@ static inline long fallocate(int fd, int mode, loff_t offset, loff_t len)
}
#endif
#endif /* FALLOCATE_H */
#endif /* LAPI_FALLOCATE_H__ */
Regular → Executable
+17 -3
View File
@@ -3,9 +3,10 @@
* Copyright (c) 2014 Cyril Hrubis <chrubis@suse.cz>
*/
#ifndef __LAPI_FCNTL_H__
#define __LAPI_FCNTL_H__
#ifndef LAPI_FCNTL_H__
#define LAPI_FCNTL_H__
#include "config.h"
#include <fcntl.h>
#include <sys/socket.h>
@@ -136,4 +137,17 @@
# define SPLICE_F_NONBLOCK 2
#endif
#endif /* __LAPI_FCNTL_H__ */
#ifndef MAX_HANDLE_SZ
# define MAX_HANDLE_SZ 128
#endif
#ifndef HAVE_STRUCT_FILE_HANDLE
struct file_handle {
unsigned int handle_bytes;
int handle_type;
/* File identifier. */
unsigned char f_handle[0];
};
#endif /* HAVE_STRUCT_FILE_HANDLE */
#endif /* LAPI_FCNTL_H__ */
Regular → Executable
+3 -3
View File
@@ -4,11 +4,11 @@
* Author: Rafael David Tinoco <rafael.tinoco@linaro.org>
*/
#ifndef FNMATCH_H__
#define FNMATCH_H__
#ifndef LAPI_FNMATCH_H__
#define LAPI_FNMATCH_H__
#ifndef FNM_EXTMATCH
#define FNM_EXTMATCH 0
#endif
#endif
#endif /* LAPI_FNMATCH_H__ */
Regular → Executable
+3 -3
View File
@@ -14,8 +14,8 @@
#include <limits.h>
#include "lapi/abisize.h"
#ifndef LAPI_FS_H
#define LAPI_FS_H
#ifndef LAPI_FS_H__
#define LAPI_FS_H__
#ifndef FS_IOC_GETFLAGS
#define FS_IOC_GETFLAGS _IOR('f', 1, long)
@@ -63,4 +63,4 @@ static inline loff_t tst_max_lfs_filesize(void)
#endif
}
#endif
#endif /* LAPI_FS_H__ */
Regular → Executable
+19 -16
View File
@@ -4,8 +4,8 @@
* Author: Viresh Kumar <viresh.kumar@linaro.org>
*/
#ifndef FSMOUNT_H__
#define FSMOUNT_H__
#ifndef LAPI_FSMOUNT_H__
#define LAPI_FSMOUNT_H__
#include <sys/mount.h>
#include <sys/syscall.h>
@@ -16,37 +16,38 @@
#include "lapi/syscalls.h"
#ifndef HAVE_FSOPEN
int fsopen(const char *fsname, unsigned int flags)
static inline int fsopen(const char *fsname, unsigned int flags)
{
return tst_syscall(__NR_fsopen, fsname, flags);
}
#endif /* HAVE_FSOPEN */
#ifndef HAVE_FSCONFIG
int fsconfig(int fd, unsigned int cmd, const char *key,
const void *value, int aux)
static inline int fsconfig(int fd, unsigned int cmd, const char *key,
const void *value, int aux)
{
return tst_syscall(__NR_fsconfig, fd, cmd, key, value, aux);
}
#endif /* HAVE_FSCONFIG */
#ifndef HAVE_FSMOUNT
int fsmount(int fd, unsigned int flags, unsigned int mount_attrs)
static inline int fsmount(int fd, unsigned int flags, unsigned int mount_attrs)
{
return tst_syscall(__NR_fsmount, fd, flags, mount_attrs);
}
#endif /* HAVE_FSMOUNT */
#ifndef HAVE_FSPICK
int fspick(int dirfd, const char *pathname, unsigned int flags)
static inline int fspick(int dirfd, const char *pathname, unsigned int flags)
{
return tst_syscall(__NR_fspick, dirfd, pathname, flags);
}
#endif /* HAVE_FSPICK */
#ifndef HAVE_MOVE_MOUNT
int move_mount(int from_dirfd, const char *from_pathname, int to_dirfd,
const char *to_pathname, unsigned int flags)
static inline int move_mount(int from_dirfd, const char *from_pathname,
int to_dirfd, const char *to_pathname,
unsigned int flags)
{
return tst_syscall(__NR_move_mount, from_dirfd, from_pathname, to_dirfd,
to_pathname, flags);
@@ -54,7 +55,7 @@ int move_mount(int from_dirfd, const char *from_pathname, int to_dirfd,
#endif /* HAVE_MOVE_MOUNT */
#ifndef HAVE_OPEN_TREE
int open_tree(int dirfd, const char *pathname, unsigned int flags)
static inline int open_tree(int dirfd, const char *pathname, unsigned int flags)
{
return tst_syscall(__NR_open_tree, dirfd, pathname, flags);
}
@@ -130,16 +131,18 @@ enum fsconfig_command {
#endif /* OPEN_TREE_CLONE */
void fsopen_supported_by_kernel(void)
static inline void fsopen_supported_by_kernel(void)
{
long ret;
if ((tst_kvercmp(5, 2, 0)) < 0) {
/* Check if the syscall is backported on an older kernel */
TEST(syscall(__NR_fsopen, NULL, 0));
if (TST_RET != -1)
SAFE_CLOSE(TST_RET);
else if (TST_ERR == ENOSYS)
ret = syscall(__NR_fsopen, NULL, 0);
if (ret != -1)
SAFE_CLOSE(ret);
else if (errno == ENOSYS)
tst_brk(TCONF, "Test not supported on kernel version < v5.2");
}
}
#endif /* FSMOUNT_H__ */
#endif /* LAPI_FSMOUNT_H__ */
Regular → Executable
+4
View File
@@ -10,4 +10,8 @@
typedef volatile uint32_t futex_t;
#if !defined(SYS_futex) && defined(SYS_futex_time64)
#define SYS_futex SYS_futex_time64
#endif
#endif /* LAPI_FUTEX_H__ */
Regular → Executable
+3 -3
View File
@@ -3,8 +3,8 @@
* Copyright (c) 2015 Linux Test Project
*/
#ifndef __GETRANDOM_H__
#define __GETRANDOM_H__
#ifndef LAPI_GETRANDOM_H__
#define LAPI_GETRANDOM_H__
#include "config.h"
@@ -27,4 +27,4 @@
# define GRND_RANDOM 0x0002
#endif
#endif /* __GETRANDOM_H__ */
#endif /* LAPI_GETRANDOM_H__ */
+19
View File
@@ -0,0 +1,19 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (c) 2021 Petr Vorel <petr.vorel@gmail.com>
*/
#ifndef LAPI_IF_ADDR_H__
#define LAPI_IF_ADDR_H__
#include <linux/if_addr.h>
#ifndef IFA_FLAGS
# define IFA_FLAGS 8
#endif
#ifndef IFA_F_NOPREFIXROUTE
# define IFA_F_NOPREFIXROUTE 0x200
#endif
#endif /* LAPI_IF_ADDR_H__ */
Regular → Executable
+33 -12
View File
@@ -3,14 +3,15 @@
* Copyright 2019 Google LLC
*/
#ifndef IF_ALG_H__
#define IF_ALG_H__
#ifndef LAPI_IF_ALG_H__
#define LAPI_IF_ALG_H__
#ifdef HAVE_LINUX_IF_ALG_H
# include <linux/if_alg.h>
#else
#endif
# include <stdint.h>
#ifndef HAVE_STRUCT_SOCKADDR_ALG
struct sockaddr_alg {
uint16_t salg_family;
uint8_t salg_type[14];
@@ -18,21 +19,41 @@ struct sockaddr_alg {
uint32_t salg_mask;
uint8_t salg_name[64];
};
#endif
#ifndef HAVE_STRUCT_AF_ALG_IV
struct af_alg_iv {
uint32_t ivlen;
uint8_t iv[0];
};
#endif
#define ALG_SET_KEY 1
#define ALG_SET_IV 2
#define ALG_SET_OP 3
#define ALG_SET_AEAD_ASSOCLEN 4
#define ALG_SET_AEAD_AUTHSIZE 5
#ifndef ALG_SET_KEY
# define ALG_SET_KEY 1
#endif
#define ALG_OP_DECRYPT 0
#define ALG_OP_ENCRYPT 1
#ifndef ALG_SET_IV
# define ALG_SET_IV 2
#endif
#endif /* !HAVE_LINUX_IF_ALG_H */
#ifndef ALG_SET_OP
# define ALG_SET_OP 3
#endif
#endif /* IF_ALG_H__ */
#ifndef ALG_SET_AEAD_ASSOCLEN
# define ALG_SET_AEAD_ASSOCLEN 4
#endif
#ifndef ALG_SET_AEAD_AUTHSIZE
# define ALG_SET_AEAD_AUTHSIZE 5
#endif
#ifndef ALG_OP_DECRYPT
# define ALG_OP_DECRYPT 0
#endif
#ifndef ALG_OP_ENCRYPT
# define ALG_OP_ENCRYPT 1
#endif
#endif /* LAPI_IF_ALG_H__ */
+19
View File
@@ -0,0 +1,19 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (c) 2020 SUSE LLC <mdoucha@suse.cz>
*/
#ifndef LAPI_IF_ETHER_H__
#define LAPI_IF_ETHER_H__
#include "config.h"
#ifdef HAVE_LINUX_IF_ETHER_H
# include <linux/if_ether.h>
#endif
#ifndef ETH_P_ALL
# define ETH_P_ALL 0x0003
#endif
#endif /* LAPI_IF_ETHER_H__ */
Regular → Executable
+41 -5
View File
@@ -4,15 +4,51 @@
* Author: Jinhui huang <huangjh.jy@cn.fujitsu.com>
*/
#ifndef __LAPI_IF_PACKET_H__
#define __LAPI_IF_PACKET_H__
#ifndef LAPI_IF_PACKET_H__
#define LAPI_IF_PACKET_H__
#include "config.h"
#ifdef HAVE_LINUX_IF_PACKET_H
# include <linux/if_packet.h>
#endif
#ifndef PACKET_RX_RING
# define PACKET_RX_RING 5
#endif
#ifndef PACKET_VERSION
# define PACKET_VERSION 10
#endif
#ifndef PACKET_RESERVE
# define PACKET_RESERVE 12
#endif
#ifndef PACKET_VNET_HDR
# define PACKET_VNET_HDR 15
#endif
#ifndef PACKET_FANOUT
#define PACKET_FANOUT 18
# define PACKET_FANOUT 18
#endif
#ifndef PACKET_FANOUT_ROLLOVER
#define PACKET_FANOUT_ROLLOVER 3
# define PACKET_FANOUT_ROLLOVER 3
#endif
#endif /* __LAPI_IF_PACKET_H__ */
#ifndef HAVE_STRUCT_TPACKET_REQ3
# define TPACKET_V3 2
struct tpacket_req3 {
unsigned int tp_block_size;
unsigned int tp_block_nr;
unsigned int tp_frame_size;
unsigned int tp_frame_nr;
unsigned int tp_retire_blk_tov;
unsigned int tp_sizeof_priv;
unsigned int tp_feature_req_word;
};
#endif
#endif /* LAPI_IF_PACKET_H__ */
+37
View File
@@ -0,0 +1,37 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (c) 2020 Linaro Limited. All rights reserved.
* Author: Viresh Kumar <viresh.kumar@linaro.org>
*/
#ifndef LAPI_INIT_MODULE_H__
#define LAPI_INIT_MODULE_H__
#include "config.h"
#include "lapi/syscalls.h"
#include "tst_test.h"
static inline int init_module(void *module_image, unsigned long len,
const char *param_values)
{
return tst_syscall(__NR_init_module, module_image, len, param_values);
}
static inline int finit_module(int fd, const char *param_values, int flags)
{
return tst_syscall(__NR_finit_module, fd, param_values, flags);
}
static inline void finit_module_supported_by_kernel(void)
{
long ret;
if ((tst_kvercmp(3, 8, 0)) < 0) {
/* Check if the syscall is backported on an older kernel */
ret = syscall(__NR_finit_module, 0, "", 0);
if (ret == -1 && errno == ENOSYS)
tst_brk(TCONF, "Test not supported on kernel version < v3.8");
}
}
#endif /* LAPI_INIT_MODULE_H__ */
Regular → Executable
+13 -8
View File
@@ -4,8 +4,8 @@
* Author: Viresh Kumar <viresh.kumar@linaro.org>
*/
#ifndef IO_PGETEVENTS_H
#define IO_PGETEVENTS_H
#ifndef LAPI_IO_PGETEVENTS_H__
#define LAPI_IO_PGETEVENTS_H__
#include <sys/syscall.h>
#include <sys/types.h>
@@ -16,15 +16,20 @@
#ifdef HAVE_LIBAIO
#include <libaio.h>
#ifndef HAVE_IO_PGETEVENTS
int io_pgetevents(io_context_t ctx, long min_nr, long max_nr,
struct io_event *events, struct timespec *timeout,
sigset_t *sigmask)
static inline int sys_io_pgetevents(io_context_t ctx, long min_nr, long max_nr,
struct io_event *events, void *timeout, sigset_t *sigmask)
{
return tst_syscall(__NR_io_pgetevents, ctx, min_nr, max_nr, events,
timeout, sigmask);
}
#endif /* HAVE_IO_PGETEVENTS */
static inline int sys_io_pgetevents_time64(io_context_t ctx, long min_nr, long max_nr,
struct io_event *events, void *timeout, sigset_t *sigmask)
{
return tst_syscall(__NR_io_pgetevents_time64, ctx, min_nr, max_nr,
events, timeout, sigmask);
}
#endif /* HAVE_LIBAIO */
#endif /* IO_PGETEVENTS_H */
#endif /* LAPI_IO_PGETEVENTS_H__ */
Regular → Executable
+41 -14
View File
@@ -6,8 +6,8 @@
* Mostly copied/adapted from <linux/io_uring.h>
*/
#ifndef IO_URING_H__
#define IO_URING_H__
#ifndef LAPI_IO_URING_H__
#define LAPI_IO_URING_H__
#include <unistd.h>
#include <fcntl.h>
@@ -18,8 +18,16 @@
#include "lapi/syscalls.h"
#ifdef HAVE_LINUX_IO_URING_H
#include <linux/io_uring.h>
#endif
#ifndef IOSQE_FIXED_FILE
#ifndef __kernel_rwf_t
typedef int __kernel_rwf_t;
#endif
/*
* IO submission data structure (Submission Queue Entry)
*/
@@ -63,8 +71,6 @@ enum {
IOSQE_FIXED_FILE_BIT,
IOSQE_IO_DRAIN_BIT,
IOSQE_IO_LINK_BIT,
IOSQE_IO_HARDLINK_BIT,
IOSQE_ASYNC_BIT,
};
/*
@@ -76,10 +82,6 @@ enum {
#define IOSQE_IO_DRAIN (1U << IOSQE_IO_DRAIN_BIT)
/* links next sqe */
#define IOSQE_IO_LINK (1U << IOSQE_IO_LINK_BIT)
/* like LINK, but stronger */
#define IOSQE_IO_HARDLINK (1U << IOSQE_IO_HARDLINK_BIT)
/* always go async */
#define IOSQE_ASYNC (1U << IOSQE_ASYNC_BIT)
/*
* io_uring_setup() flags
@@ -254,10 +256,21 @@ struct io_uring_probe {
#endif /* IOSQE_FIXED_FILE */
#ifndef IOSQE_IO_HADRLINK
/* like LINK, but stronger */
#define IOSQE_IO_HARDLINK_BIT 3
#define IOSQE_IO_HARDLINK (1U << IOSQE_IO_HARDLINK_BIT)
#endif /* IOSQE_IO_HADRLINK */
#ifndef IOSQE_ASYNC
/* always go async */
#define IOSQE_ASYNC_BIT 4
#define IOSQE_ASYNC (1U << IOSQE_ASYNC_BIT)
#endif /* IOSQE_ASYNC */
#ifndef HAVE_IO_URING_REGISTER
int io_uring_register(int fd, unsigned int opcode, void *arg,
unsigned int nr_args)
static inline int io_uring_register(int fd, unsigned int opcode, void *arg,
unsigned int nr_args)
{
return tst_syscall(__NR_io_uring_register, fd, opcode, arg, nr_args);
}
@@ -265,19 +278,33 @@ int io_uring_register(int fd, unsigned int opcode, void *arg,
#ifndef HAVE_IO_URING_SETUP
int io_uring_setup(unsigned int entries, struct io_uring_params *p)
static inline int io_uring_setup(unsigned int entries,
struct io_uring_params *p)
{
return tst_syscall(__NR_io_uring_setup, entries, p);
}
#endif /* HAVE_IO_URING_SETUP */
#ifndef HAVE_IO_URING_ENTER
int io_uring_enter(int fd, unsigned int to_submit, unsigned int min_complete,
unsigned int flags, sigset_t *sig)
static inline int io_uring_enter(int fd, unsigned int to_submit,
unsigned int min_complete, unsigned int flags, sigset_t *sig)
{
return tst_syscall(__NR_io_uring_enter, fd, to_submit, min_complete,
flags, sig, _NSIG / 8);
}
#endif /* HAVE_IO_URING_ENTER */
#endif /* IO_URING_H__ */
static inline void io_uring_setup_supported_by_kernel(void)
{
long ret;
if ((tst_kvercmp(5, 1, 0)) < 0) {
ret = syscall(__NR_io_uring_setup, NULL, 0);
if (ret != -1)
SAFE_CLOSE(ret);
else if (errno == ENOSYS)
tst_brk(TCONF,
"Test not supported on kernel version < v5.1");
}
}
#endif /* LAPI_IO_URING_H__ */
Regular → Executable
+3 -3
View File
@@ -4,8 +4,8 @@
* Copyright (c) 2020 Petr Vorel <pvorel@suse.cz>
*/
#ifndef IOCTL_H__
#define IOCTL_H__
#ifndef LAPI_IOCTL_H__
#define LAPI_IOCTL_H__
#include "config.h"
#include <sys/ioctl.h>
@@ -37,4 +37,4 @@ struct termio
};
#endif /* HAVE_STRUCT_TERMIO */
#endif /* IOCTL_H__ */
#endif /* LAPI_IOCTL_H__ */
Regular → Executable
+3 -3
View File
@@ -3,8 +3,8 @@
* Copyright (c) 2019 Federico Bonfiglio fedebonfi95@gmail.com
*/
#ifndef IOCTL_NS_H__
#define IOCTL_NS_H__
#ifndef LAPI_IOCTL_NS_H__
#define LAPI_IOCTL_NS_H__
#include <asm-generic/ioctl.h>
@@ -25,4 +25,4 @@
#endif
#endif /* IOCTL_NS_H__ */
#endif /* LAPI_IOCTL_NS_H__ */
Regular → Executable
+3 -3
View File
@@ -3,8 +3,8 @@
* Copyright (c) 2014 Cyril Hrubis <chrubis@suse.cz>
*/
#ifndef IOVEC_H
#define IOVEC_H
#ifndef LAPI_IOVEC_H__
#define LAPI_IOVEC_H__
#include "config.h"
@@ -17,4 +17,4 @@ struct iovec {
# include <sys/uio.h>
#endif
#endif /* IOVEC_H */
#endif /* LAPI_IOVEC_H__ */
+47
View File
@@ -0,0 +1,47 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#ifndef LAPI_IP_TABLES__
#define LAPI_IP_TABLES__
#include "config.h"
#include <net/if.h>
#include <linux/netfilter_ipv4/ip_tables.h>
#ifndef HAVE_STRUCT_XT_ENTRY_MATCH
struct xt_entry_match {
union {
struct {
uint16_t match_size;
char name[29];
uint8_t revision;
} user;
struct {
uint16_t match_size;
void *match;
} kernel;
uint16_t match_size;
} u;
unsigned char data[0];
};
#endif
#ifndef HAVE_STRUCT_XT_ENTRY_TARGET
struct xt_entry_target {
union {
struct {
uint16_t target_size;
char name[29];
uint8_t revision;
} user;
struct {
uint16_t target_size;
void *target;
} kernel;
uint16_t target_size;
} u;
unsigned char data[0];
};
#endif
#endif /* LAPI_IP_TABLES__ */
+195
View File
@@ -0,0 +1,195 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (c) 2020 Linaro Limited. All rights reserved.
* Author: Viresh Kumar <viresh.kumar@linaro.org>
*/
#ifndef LAPI_IPCBUF_H__
#define LAPI_IPCBUF_H__
#include "config.h"
#include "lapi/posix_types.h"
#ifndef HAVE_IPC64_PERM
#if defined(__hppa__)
#define HAVE_IPC64_PERM
/*
* The ipc64_perm structure for PA-RISC is almost identical to
* kern_ipc_perm as we have always had 32-bit UIDs and GIDs in the kernel.
* 'seq' has been changed from long to int so that it's the same size
* on 64-bit kernels as on 32-bit ones.
*/
struct ipc64_perm
{
__kernel_key_t key;
__kernel_uid_t uid;
__kernel_gid_t gid;
__kernel_uid_t cuid;
__kernel_gid_t cgid;
#if __BITS_PER_LONG != 64
unsigned short int __pad1;
#endif
__kernel_mode_t mode;
unsigned short int __pad2;
unsigned short int seq;
unsigned int __pad3;
unsigned long long int __unused1;
unsigned long long int __unused2;
};
#endif /* __hppa__ */
#if defined(__powerpc__) || defined(__powerpc64__)
#define HAVE_IPC64_PERM
/*
* The ipc64_perm structure for the powerpc is identical to
* kern_ipc_perm as we have always had 32-bit UIDs and GIDs in the
* kernel. Note extra padding because this structure is passed back
* and forth between kernel and user space. Pad space is left for:
* - 1 32-bit value to fill up for 8-byte alignment
* - 2 miscellaneous 64-bit values
*/
struct ipc64_perm
{
__kernel_key_t key;
__kernel_uid_t uid;
__kernel_gid_t gid;
__kernel_uid_t cuid;
__kernel_gid_t cgid;
__kernel_mode_t mode;
unsigned int seq;
unsigned int __pad1;
unsigned long long __unused1;
unsigned long long __unused2;
};
#endif /* defined(__powerpc__) || defined(__powerpc64__) */
#if defined(__s390__)
#define HAVE_IPC64_PERM
/*
* The user_ipc_perm structure for S/390 architecture.
* Note extra padding because this structure is passed back and forth
* between kernel and user space.
*
* Pad space is left for:
* - 32-bit mode_t and seq
* - 2 miscellaneous 32-bit values
*/
struct ipc64_perm
{
__kernel_key_t key;
__kernel_uid32_t uid;
__kernel_gid32_t gid;
__kernel_uid32_t cuid;
__kernel_gid32_t cgid;
__kernel_mode_t mode;
unsigned short __pad1;
unsigned short seq;
#ifndef __s390x__
unsigned short __pad2;
#endif /* ! __s390x__ */
unsigned long __unused1;
unsigned long __unused2;
};
#endif /* defined(__powerpc__) || defined(__powerpc64__) */
#if defined(__sparc__)
#define HAVE_IPC64_PERM
/*
* The ipc64_perm structure for sparc/sparc64 architecture.
* Note extra padding because this structure is passed back and forth
* between kernel and user space.
*
* Pad space is left for:
* - 32-bit seq
* - on sparc for 32 bit mode (it is 32 bit on sparc64)
* - 2 miscellaneous 64-bit values
*/
struct ipc64_perm
{
__kernel_key_t key;
__kernel_uid32_t uid;
__kernel_gid32_t gid;
__kernel_uid32_t cuid;
__kernel_gid32_t cgid;
#ifndef __arch64__
unsigned short __pad0;
#endif
__kernel_mode_t mode;
unsigned short __pad1;
unsigned short seq;
unsigned long long __unused1;
unsigned long long __unused2;
};
#endif /* __sparc__ */
#if defined(__xtensa__)
#define HAVE_IPC64_PERM
/*
* Pad space is left for:
* - 32-bit mode_t and seq
* - 2 miscellaneous 32-bit values
*
* This file is subject to the terms and conditions of the GNU General
* Public License. See the file "COPYING" in the main directory of
* this archive for more details.
*/
struct ipc64_perm
{
__kernel_key_t key;
__kernel_uid32_t uid;
__kernel_gid32_t gid;
__kernel_uid32_t cuid;
__kernel_gid32_t cgid;
__kernel_mode_t mode;
unsigned long seq;
unsigned long __unused1;
unsigned long __unused2;
};
#endif /* __xtensa__ */
#ifndef HAVE_IPC64_PERM
/*
* The generic ipc64_perm structure:
* Note extra padding because this structure is passed back and forth
* between kernel and user space.
*
* ipc64_perm was originally meant to be architecture specific, but
* everyone just ended up making identical copies without specific
* optimizations, so we may just as well all use the same one.
*
* Pad space is left for:
* - 32-bit mode_t on architectures that only had 16 bit
* - 32-bit seq
* - 2 miscellaneous 32-bit values
*/
struct ipc64_perm {
__kernel_key_t key;
__kernel_uid32_t uid;
__kernel_gid32_t gid;
__kernel_uid32_t cuid;
__kernel_gid32_t cgid;
__kernel_mode_t mode;
/* pad if mode_t is u16: */
unsigned char __pad1[4 - sizeof(__kernel_mode_t)];
unsigned short seq;
unsigned short __pad2;
__kernel_ulong_t __unused1;
__kernel_ulong_t __unused2;
};
#endif /* ipc64_perm */
#endif /* HAVE_IPC64_PERM */
#endif /* LAPI_IPCBUF_H__ */
Regular → Executable
+3 -3
View File
@@ -3,8 +3,8 @@
* Copyright (c) 2017 Cyril Hrubis <chrubis@suse.cz>
*/
#ifndef KEYCTL_H__
#define KEYCTL_H__
#ifndef LAPI_KEYCTL_H__
#define LAPI_KEYCTL_H__
#include "config.h"
@@ -175,4 +175,4 @@ static inline key_serial_t keyctl_join_session_keyring(const char *name) {
# define KEY_OTH_ALL 0x0000003f
#endif /* !KEY_POS_VIEW */
#endif /* KEYCTL_H__ */
#endif /* LAPI_KEYCTL_H__ */
Regular → Executable
+25 -2
View File
@@ -3,9 +3,10 @@
* Copyright (c) 2020 FUJITSU LIMITED. All rights reserved.
* Author: Yang Xu <xuyang2018.jy@cn.fujitsu.com>
*/
#ifndef LAPI_LOOP_H
#define LAPI_LOOP_H
#ifndef LAPI_LOOP_H__
#define LAPI_LOOP_H__
#include "config.h"
#include <linux/types.h>
#include <linux/loop.h>
@@ -29,4 +30,26 @@
# define LOOP_SET_BLOCK_SIZE 0x4C09
#endif
#ifndef LOOP_CONFIGURE
# define LOOP_CONFIGURE 0x4C0A
#endif
#ifndef HAVE_STRUCT_LOOP_CONFIG
/*
* struct loop_config - Complete configuration for a loop device.
* @fd: fd of the file to be used as a backing file for the loop device.
* @block_size: block size to use; ignored if 0.
* @info: struct loop_info64 to configure the loop device with.
*
* This structure is used with the LOOP_CONFIGURE ioctl, and can be used to
* atomically setup and configure all loop device parameters at once.
*/
struct loop_config {
__u32 fd;
__u32 block_size;
struct loop_info64 info;
__u64 __reserved[8];
};
#endif
#endif /* LAPI_LOOP_H__ */
Regular → Executable
+3 -3
View File
@@ -4,8 +4,8 @@
* Author: Rafael David Tinoco <rafael.tinoco@linaro.org>
*/
#ifndef LAPI_MEMBARRIER_H
#define LAPI_MEMBARRIER_H
#ifndef LAPI_MEMBARRIER_H__
#define LAPI_MEMBARRIER_H__
/*
* Having <linux/membarrier.h> is enough to know if the test should run or
@@ -27,4 +27,4 @@ enum membarrier_cmd {
MEMBARRIER_CMD_SHARED = MEMBARRIER_CMD_GLOBAL,
};
#endif
#endif /* LAPI_MEMBARRIER_H__ */
Regular → Executable
+3 -3
View File
@@ -3,8 +3,8 @@
* Copyright (C) 2017 Red Hat, Inc.
*/
#ifndef LAPI_MEMFD_H
#define LAPI_MEMFD_H
#ifndef LAPI_MEMFD_H__
#define LAPI_MEMFD_H__
/* flags for memfd_create(2) (unsigned int) */
#ifndef MFD_CLOEXEC
@@ -47,4 +47,4 @@
#define MFD_HUGE_16GB (34 << 26)
#endif
#endif
#endif /* LAPI_MEMFD_H__ */
Regular → Executable
+4 -4
View File
@@ -3,18 +3,18 @@
* Copyright (c) 2014 Cyril Hrubis <chrubis@suse.cz>
*/
#ifndef __MKDIRAT_H__
#define __MKDIRAT_H__
#ifndef LAPI_MKDIRAT_H__
#define LAPI_MKDIRAT_H__
#include "config.h"
#include "lapi/syscalls.h"
#include "lapi/fcntl.h"
#ifndef HAVE_MKDIRAT
int mkdirat(int dirfd, const char *dirname, int mode)
static inline int mkdirat(int dirfd, const char *dirname, int mode)
{
return ltp_syscall(__NR_mkdirat, dirfd, dirname, mode);
}
#endif
#endif /* __MKDIRAT_H__ */
#endif /* LAPI_MKDIRAT_H__ */
Regular → Executable
+1 -1
View File
@@ -5,7 +5,7 @@
*/
#ifndef LAPI_MLOCK2_H__
# define LAPI_MLOCK2_H__
#define LAPI_MLOCK2_H__
#include <linux/mman.h>
Regular → Executable
+10
View File
@@ -66,6 +66,16 @@
# define MADV_KEEPONFORK 19
#endif
#ifndef MAP_FIXED_NOREPLACE
#ifdef __alpha__
# define MAP_FIXED_NOREPLACE 0x200000
#else
# define MAP_FIXED_NOREPLACE 0x100000
#endif
#endif /* MAP_FIXED_NOREPLACE */
#ifdef HAVE_SYS_SHM_H
# include <sys/shm.h>
# define MMAP_GRANULARITY SHMLBA
Regular → Executable
+3 -3
View File
@@ -3,8 +3,8 @@
* Copyright (c) 2015 Cui Bixuan <cuibixuan@huawei.com>
*/
#ifndef __MOUNT_H__
#define __MOUNT_H__
#ifndef LAPI_MOUNT_H__
#define LAPI_MOUNT_H__
#ifndef MS_REC
#define MS_REC 16384
@@ -30,4 +30,4 @@
#define UMOUNT_NOFOLLOW 8
#endif
#endif /* __MOUNT_H__ */
#endif /* LAPI_MOUNT_H__ */

Some files were not shown because too many files have changed in this diff Show More