mirror of
https://github.com/openharmony/third_party_ltp.git
synced 2026-07-01 12:25:45 -04:00
!24 【内核子系统】【master】升级ltp代码
Merge pull request !24 from 李猛/kernel_lite_20220629_01_master
This commit is contained in:
-114
@@ -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"
|
||||
@@ -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:
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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."
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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 $?
|
||||
|
||||
@@ -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 -
|
||||
@@ -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
|
||||
@@ -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
@@ -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
|
||||
@@ -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
|
||||
Regular → Executable
+99
-19
@@ -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
@@ -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
@@ -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
|
||||
|
||||
Executable
+2371
File diff suppressed because it is too large
Load Diff
Regular → Executable
+18
-12
@@ -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
|
||||
|
||||
Regular → Executable
+29
@@ -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
@@ -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
|
||||
|
||||
|
||||
Executable
+59
@@ -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
Regular → Executable
Regular → Executable
Regular → Executable
Regular → Executable
Regular → Executable
Regular → Executable
Regular → Executable
Regular → Executable
Regular → Executable
Regular → Executable
Regular → Executable
Regular → Executable
Regular → Executable
Regular → Executable
Regular → Executable
Executable
+476
@@ -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
Executable
+6
@@ -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 '{}')
|
||||
|
Executable
+763
@@ -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
|
||||
-------------------------------------------------------------------------------
|
||||
Executable
+66
@@ -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
File diff suppressed because it is too large
Load Diff
Regular → Executable
+14
-3
@@ -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').
|
||||
|==============================================================================
|
||||
|
||||
|
||||
Executable
+5
@@ -0,0 +1,5 @@
|
||||
/*.txt
|
||||
/docbook-xsl.css
|
||||
/metadata.html
|
||||
/metadata.pdf
|
||||
/metadata.chunked/
|
||||
Executable
+69
@@ -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
|
||||
Executable
+248
@@ -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.
|
||||
Executable
+521
@@ -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
@@ -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 ?= ..
|
||||
|
||||
|
||||
Regular → Executable
Regular → Executable
+1
-1
@@ -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);
|
||||
Regular → Executable
Regular → Executable
Regular → Executable
+3
-3
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
Executable
+28
@@ -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
@@ -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
@@ -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
@@ -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
Regular → Executable
+48
-3
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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__ */
|
||||
|
||||
Executable
+19
@@ -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
@@ -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__ */
|
||||
|
||||
Executable
+19
@@ -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
@@ -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__ */
|
||||
|
||||
Executable
+37
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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__ */
|
||||
|
||||
Executable
+47
@@ -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__ */
|
||||
Executable
+195
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -5,7 +5,7 @@
|
||||
*/
|
||||
|
||||
#ifndef LAPI_MLOCK2_H__
|
||||
# define LAPI_MLOCK2_H__
|
||||
#define LAPI_MLOCK2_H__
|
||||
|
||||
#include <linux/mman.h>
|
||||
|
||||
|
||||
Regular → Executable
+10
@@ -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
@@ -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
Reference in New Issue
Block a user