diff options
author | Manuel Bentele | 2020-10-23 15:18:01 +0200 |
---|---|---|
committer | Manuel Bentele | 2020-10-23 15:18:01 +0200 |
commit | dbb41ce2b7f309d394054a6bd1e33afd578798a5 (patch) | |
tree | 6a31092063d9f2fb5ac5720ec6759040e793c3d5 /kernel/tests/lib | |
parent | Set Linux kernel version to unknown if it is not detectable (diff) | |
download | xloop-dbb41ce2b7f309d394054a6bd1e33afd578798a5.tar.gz xloop-dbb41ce2b7f309d394054a6bd1e33afd578798a5.tar.xz xloop-dbb41ce2b7f309d394054a6bd1e33afd578798a5.zip |
Move the source code of all xloop components to the common 'src' directory
Diffstat (limited to 'kernel/tests/lib')
67 files changed, 0 insertions, 15556 deletions
diff --git a/kernel/tests/lib/CMakeLists.txt b/kernel/tests/lib/CMakeLists.txt deleted file mode 100644 index 0ce8982..0000000 --- a/kernel/tests/lib/CMakeLists.txt +++ /dev/null @@ -1,70 +0,0 @@ -cmake_minimum_required(VERSION 3.10) - -project(xloop-kernel-test-lib) - -add_library(libltp STATIC ${CMAKE_CURRENT_SOURCE_DIR}/cloner.c - ${CMAKE_CURRENT_SOURCE_DIR}/get_path.c - ${CMAKE_CURRENT_SOURCE_DIR}/parse_opts.c - ${CMAKE_CURRENT_SOURCE_DIR}/random_range.c - ${CMAKE_CURRENT_SOURCE_DIR}/safe_file_ops.c - ${CMAKE_CURRENT_SOURCE_DIR}/safe_macros.c - ${CMAKE_CURRENT_SOURCE_DIR}/safe_net.c - ${CMAKE_CURRENT_SOURCE_DIR}/safe_pthread.c - ${CMAKE_CURRENT_SOURCE_DIR}/safe_stdio.c - ${CMAKE_CURRENT_SOURCE_DIR}/self_exec.c - ${CMAKE_CURRENT_SOURCE_DIR}/tlibio.c - ${CMAKE_CURRENT_SOURCE_DIR}/tst_af_alg.c - ${CMAKE_CURRENT_SOURCE_DIR}/tst_ansi_color.c - ${CMAKE_CURRENT_SOURCE_DIR}/tst_assert.c - ${CMAKE_CURRENT_SOURCE_DIR}/tst_buffers.c - ${CMAKE_CURRENT_SOURCE_DIR}/tst_capability.c - ${CMAKE_CURRENT_SOURCE_DIR}/tst_cgroup.c - ${CMAKE_CURRENT_SOURCE_DIR}/tst_checkpoint.c - ${CMAKE_CURRENT_SOURCE_DIR}/tst_checksum.c - ${CMAKE_CURRENT_SOURCE_DIR}/tst_clocks.c - ${CMAKE_CURRENT_SOURCE_DIR}/tst_cmd.c - ${CMAKE_CURRENT_SOURCE_DIR}/tst_coredump.c - ${CMAKE_CURRENT_SOURCE_DIR}/tst_cpu.c - ${CMAKE_CURRENT_SOURCE_DIR}/tst_crypto.c - ${CMAKE_CURRENT_SOURCE_DIR}/tst_device.c - ${CMAKE_CURRENT_SOURCE_DIR}/tst_dir_is_empty.c - ${CMAKE_CURRENT_SOURCE_DIR}/tst_fill_file.c - ${CMAKE_CURRENT_SOURCE_DIR}/tst_fill_fs.c - ${CMAKE_CURRENT_SOURCE_DIR}/tst_fs_has_free.c - ${CMAKE_CURRENT_SOURCE_DIR}/tst_fs_link_count.c - ${CMAKE_CURRENT_SOURCE_DIR}/tst_fs_setup.c - ${CMAKE_CURRENT_SOURCE_DIR}/tst_fs_type.c - ${CMAKE_CURRENT_SOURCE_DIR}/tst_get_bad_addr.c - ${CMAKE_CURRENT_SOURCE_DIR}/tst_hugepage.c - ${CMAKE_CURRENT_SOURCE_DIR}/tst_ioctl.c - ${CMAKE_CURRENT_SOURCE_DIR}/tst_kconfig.c - ${CMAKE_CURRENT_SOURCE_DIR}/tst_kernel.c - ${CMAKE_CURRENT_SOURCE_DIR}/tst_kvercmp.c - ${CMAKE_CURRENT_SOURCE_DIR}/tst_lockdown.c - ${CMAKE_CURRENT_SOURCE_DIR}/tst_memutils.c - ${CMAKE_CURRENT_SOURCE_DIR}/tst_mkfs.c - ${CMAKE_CURRENT_SOURCE_DIR}/tst_module.c - ${CMAKE_CURRENT_SOURCE_DIR}/tst_net.c - ${CMAKE_CURRENT_SOURCE_DIR}/tst_parse_opts.c - ${CMAKE_CURRENT_SOURCE_DIR}/tst_path_has_mnt_flags.c - ${CMAKE_CURRENT_SOURCE_DIR}/tst_pid.c - ${CMAKE_CURRENT_SOURCE_DIR}/tst_process_state.c - ${CMAKE_CURRENT_SOURCE_DIR}/tst_res.c - ${CMAKE_CURRENT_SOURCE_DIR}/tst_resource.c - ${CMAKE_CURRENT_SOURCE_DIR}/tst_safe_macros.c - ${CMAKE_CURRENT_SOURCE_DIR}/tst_safe_sysv_ipc.c - ${CMAKE_CURRENT_SOURCE_DIR}/tst_safe_timerfd.c - ${CMAKE_CURRENT_SOURCE_DIR}/tst_sig.c - ${CMAKE_CURRENT_SOURCE_DIR}/tst_sig_proc.c - ${CMAKE_CURRENT_SOURCE_DIR}/tst_status.c - ${CMAKE_CURRENT_SOURCE_DIR}/tst_supported_fs_types.c - ${CMAKE_CURRENT_SOURCE_DIR}/tst_sys_conf.c - ${CMAKE_CURRENT_SOURCE_DIR}/tst_taint.c - ${CMAKE_CURRENT_SOURCE_DIR}/tst_test.c - ${CMAKE_CURRENT_SOURCE_DIR}/tst_timer.c - ${CMAKE_CURRENT_SOURCE_DIR}/tst_timer_test.c - ${CMAKE_CURRENT_SOURCE_DIR}/tst_tmpdir.c - ${CMAKE_CURRENT_SOURCE_DIR}/tst_virt.c - ${CMAKE_CURRENT_SOURCE_DIR}/tst_wallclock.c) -target_include_directories(libltp PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) -target_compile_options(libltp PUBLIC "-Wno-deprecated-declarations") diff --git a/kernel/tests/lib/cloner.c b/kernel/tests/lib/cloner.c deleted file mode 100644 index 11401f2..0000000 --- a/kernel/tests/lib/cloner.c +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Copyright (c) International Business Machines Corp., 2009 - * Some wrappers for clone functionality. Thrown together by Serge Hallyn - * <serue@us.ibm.com> based on existing clone usage in ltp. - * - * 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 - */ - -#ifndef _GNU_SOURCE -# define _GNU_SOURCE -#endif - -#include <stdio.h> -#include <errno.h> -#include <unistd.h> -#include <string.h> -#include <stdlib.h> -#include <sched.h> -#include <stdarg.h> -#include "config.h" -#include "tst_clone.h" - -#undef clone /* we want to use clone() */ - -/* - * The ia64 port has never included a prototype for __clone2(). It was updated - * to take eight parameters in glibc commit: - * - * commit 625f22fc7f8e0d61e3e6cff2c65468b91dbad426 - * Author: Ulrich Drepper <drepper@redhat.com> - * Date: Mon Mar 3 19:53:27 2003 +0000 - * - * The first release that contained this commit was glibc-2.3.3 which is old - * enough to assume that __clone2() takes eight parameters. - */ -#if defined(__ia64__) -extern int __clone2(int (*fn) (void *arg), void *child_stack_base, - size_t child_stack_size, int flags, void *arg, - pid_t *parent_tid, void *tls, pid_t *child_tid); -#endif - -#ifndef CLONE_SUPPORTS_7_ARGS -# define clone(fn, stack, flags, arg, ptid, tls, ctid) \ - clone(fn, stack, flags, arg) -#endif - -/* - * ltp_clone: wrapper for clone to hide the architecture dependencies. - * 1. hppa takes bottom of stack and no stacksize (stack grows up) - * 2. __ia64__ takes bottom of stack and uses clone2 - * 3. all others take top of stack (stack grows down) - */ -static int -ltp_clone_(unsigned long flags, int (*fn)(void *arg), void *arg, - size_t stack_size, void *stack, pid_t *ptid, void *tls, pid_t *ctid) -{ - int ret; - -#if defined(__ia64__) - ret = __clone2(fn, stack, stack_size, flags, arg, ptid, tls, ctid); -#else -# if defined(__hppa__) || defined(__metag__) - /* - * These arches grow their stack up, so don't need to adjust the base. - * XXX: This should be made into a runtime test. - */ -# else - /* - * For archs where stack grows downwards, stack points to the topmost - * address of the memory space set up for the child stack. - */ - if (stack) - stack += stack_size; -# endif - - ret = clone(fn, stack, flags, arg, ptid, tls, ctid); -#endif - - return ret; -} - -int ltp_clone(unsigned long flags, int (*fn)(void *arg), void *arg, - size_t stack_size, void *stack) -{ - return ltp_clone_(flags, fn, arg, stack_size, stack, NULL, NULL, NULL); -} - -int ltp_clone7(unsigned long flags, int (*fn)(void *arg), void *arg, - size_t stack_size, void *stack, ...) -{ - pid_t *ptid, *ctid; - void *tls; - va_list arg_clone; - - va_start(arg_clone, stack); - ptid = va_arg(arg_clone, pid_t *); - tls = va_arg(arg_clone, void *); - ctid = va_arg(arg_clone, pid_t *); - va_end(arg_clone); - -#ifdef CLONE_SUPPORTS_7_ARGS - return ltp_clone_(flags, fn, arg, stack_size, stack, ptid, tls, ctid); -#else - errno = ENOSYS; - return -1; -#endif -} - -/* - * ltp_alloc_stack: allocate stack of size 'size', that is sufficiently - * aligned for all arches. User is responsible for freeing allocated - * memory. - * Returns pointer to new stack. On error, returns NULL with errno set. - */ -void *ltp_alloc_stack(size_t size) -{ - void *ret = NULL; - int err; - - err = posix_memalign(&ret, 64, size); - if (err) - errno = err; - - return ret; -} - -/* - * ltp_clone_alloc: also does the memory allocation for clone with a - * caller-specified size. - */ -int -ltp_clone_alloc(unsigned long clone_flags, int (*fn) (void *arg), void *arg, - size_t stack_size) -{ - void *stack; - int ret; - int saved_errno; - - stack = ltp_alloc_stack(stack_size); - if (stack == NULL) - return -1; - - ret = ltp_clone(clone_flags, fn, arg, stack_size, stack); - - if (ret == -1) { - saved_errno = errno; - free(stack); - errno = saved_errno; - } - - return ret; -} - -/* - * ltp_clone_quick: calls ltp_clone_alloc with predetermined stack size. - * Experience thus far suggests that one page is often insufficient, - * while 6*getpagesize() seems adequate. - */ -int ltp_clone_quick(unsigned long clone_flags, int (*fn) (void *arg), void *arg) -{ - size_t stack_size = getpagesize() * 6; - - return ltp_clone_alloc(clone_flags, fn, arg, stack_size); -} diff --git a/kernel/tests/lib/errnos.h b/kernel/tests/lib/errnos.h deleted file mode 100644 index df8fea8..0000000 --- a/kernel/tests/lib/errnos.h +++ /dev/null @@ -1,186 +0,0 @@ -/* - * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. - * Copyright (c) 2009-2013 Cyril Hrubis <chrubis@suse.cz> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it would be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * Further, this software is distributed without any warranty that it is - * free of the rightful claim of any third person regarding infringement - * or the like. Any license provided herein, whether implied or - * otherwise, applies only to this software file. Patent licenses, if - * any, provided herein do not apply to combinations of this program with - * other software, or any other product whatsoever. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, - * Mountain View, CA 94043, or: - */ - -const char *tst_strerrno(int err) -{ - static const struct pair errno_pairs[] = { - STRPAIR(0, "SUCCESS") - /* asm-generic/errno-base.h */ - PAIR(EPERM) - PAIR(ENOENT) - PAIR(ESRCH) - PAIR(EINTR) - PAIR(EIO) - PAIR(ENXIO) - PAIR(E2BIG) - PAIR(ENOEXEC) - PAIR(EBADF) - PAIR(ECHILD) - STRPAIR(EAGAIN, "EAGAIN/EWOULDBLOCK") - PAIR(ENOMEM) - PAIR(EACCES) - PAIR(EFAULT) - PAIR(ENOTBLK) - PAIR(EBUSY) - PAIR(EEXIST) - PAIR(EXDEV) - PAIR(ENODEV) - PAIR(ENOTDIR) - PAIR(EISDIR) - PAIR(EINVAL) - PAIR(ENFILE) - PAIR(EMFILE) - PAIR(ENOTTY) - PAIR(ETXTBSY) - PAIR(EFBIG) - PAIR(ENOSPC) - PAIR(ESPIPE) - PAIR(EROFS) - PAIR(EMLINK) - PAIR(EPIPE) - PAIR(EDOM) - PAIR(ERANGE) - /* asm-generic/errno.h */ - PAIR(EDEADLK) - PAIR(ENAMETOOLONG) - PAIR(ENOLCK) - PAIR(ENOSYS) - PAIR(ENOTEMPTY) - PAIR(ELOOP) - /* EWOULDBLOCK == EAGAIN skipped */ - PAIR(ENOMSG) - PAIR(EIDRM) - PAIR(ECHRNG) - PAIR(EL2NSYNC) - PAIR(EL3HLT) - PAIR(EL3RST) - PAIR(ELNRNG) - PAIR(EUNATCH) - PAIR(ENOCSI) - PAIR(EL2HLT) - PAIR(EBADE) - PAIR(EBADR) - PAIR(EXFULL) - PAIR(ENOANO) - PAIR(EBADRQC) - PAIR(EBADSLT) - /* EDEADLOCK == EDEADLK skipped */ - PAIR(EBFONT) - PAIR(ENOSTR) - PAIR(ENODATA) - PAIR(ETIME) - PAIR(ENOSR) - PAIR(ENONET) - PAIR(ENOPKG) - PAIR(EREMOTE) - PAIR(ENOLINK) - PAIR(EADV) - PAIR(ESRMNT) - PAIR(ECOMM) - PAIR(EPROTO) - PAIR(EMULTIHOP) - PAIR(EDOTDOT) - PAIR(EBADMSG) - PAIR(EOVERFLOW) - PAIR(ENOTUNIQ) - PAIR(EBADFD) - PAIR(EREMCHG) - PAIR(ELIBACC) - PAIR(ELIBBAD) - PAIR(ELIBSCN) - PAIR(ELIBMAX) - PAIR(ELIBEXEC) - PAIR(EILSEQ) - PAIR(ERESTART) - PAIR(ESTRPIPE) - PAIR(EUSERS) - PAIR(ENOTSOCK) - PAIR(EDESTADDRREQ) - PAIR(EMSGSIZE) - PAIR(EPROTOTYPE) - PAIR(ENOPROTOOPT) - PAIR(EPROTONOSUPPORT) - PAIR(ESOCKTNOSUPPORT) - PAIR(EOPNOTSUPP) - PAIR(EPFNOSUPPORT) - PAIR(EAFNOSUPPORT) - PAIR(EADDRINUSE) - PAIR(EADDRNOTAVAIL) - PAIR(ENETDOWN) - PAIR(ENETUNREACH) - PAIR(ENETRESET) - PAIR(ECONNABORTED) - PAIR(ECONNRESET) - PAIR(ENOBUFS) - PAIR(EISCONN) - PAIR(ENOTCONN) - PAIR(ESHUTDOWN) - PAIR(ETOOMANYREFS) - PAIR(ETIMEDOUT) - PAIR(ECONNREFUSED) - PAIR(EHOSTDOWN) - PAIR(EHOSTUNREACH) - PAIR(EALREADY) - PAIR(EINPROGRESS) - PAIR(ESTALE) - PAIR(EUCLEAN) - PAIR(ENOTNAM) - PAIR(ENAVAIL) - PAIR(EISNAM) - PAIR(EREMOTEIO) - PAIR(EDQUOT) - PAIR(ENOMEDIUM) - PAIR(EMEDIUMTYPE) - PAIR(ECANCELED) -#ifdef ENOKEY - PAIR(ENOKEY) -#endif -#ifdef EKEYEXPIRED - PAIR(EKEYEXPIRED) -#endif -#ifdef EKEYREVOKED - PAIR(EKEYREVOKED) -#endif -#ifdef EKEYREJECTED - PAIR(EKEYREJECTED) -#endif -#ifdef EOWNERDEAD - PAIR(EOWNERDEAD) -#endif -#ifdef ENOTRECOVERABLE - PAIR(ENOTRECOVERABLE) -#endif -#ifdef ERFKILL - PAIR(ERFKILL) -#endif -#ifdef EHWPOISON - PAIR(EHWPOISON) -#endif - }; - - PAIR_LOOKUP(errno_pairs, err); -} diff --git a/kernel/tests/lib/get_path.c b/kernel/tests/lib/get_path.c deleted file mode 100644 index aafbc2c..0000000 --- a/kernel/tests/lib/get_path.c +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (C) 2010 Cyril Hrubis chrubis@suse.cz - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it would be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * Further, this software is distributed without any warranty that it is - * free of the rightful claim of any third person regarding infringement - * or the like. Any license provided herein, whether implied or - * otherwise, applies only to this software file. Patent licenses, if - * any, provided herein do not apply to combinations of this program with - * other software, or any other product whatsoever. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - /* - * Looks for binary prog_name in $PATH. - * - * If such file exists and if you are able at least to read it, zero is - * returned and absolute path to the file is filled into buf. In case buf is - * too short to hold the absolute path + prog_name for the file we are looking - * for -1 is returned as well as when there is no such file in all paths in - * $PATH. - */ - -#include <stdio.h> -#include <string.h> -#include <stdlib.h> -#include <unistd.h> -#include <sys/types.h> -#include <sys/stat.h> - -#include "test.h" - -static int file_exist(const char *path) -{ - struct stat st; - - if (!access(path, R_OK) && !stat(path, &st) && S_ISREG(st.st_mode)) - return 1; - - return 0; -} - -int tst_get_path(const char *prog_name, char *buf, size_t buf_len) -{ - const char *path = (const char *)getenv("PATH"); - const char *start = path; - const char *end; - size_t size, ret; - - if (path == NULL) - return -1; - - do { - end = strchr(start, ':'); - - if (end != NULL) - snprintf(buf, MIN(buf_len, (size_t) (end - start + 1)), - "%s", start); - else - snprintf(buf, buf_len, "%s", start); - - size = strlen(buf); - - /* - * "::" inside $PATH, $PATH ending with ':' or $PATH starting - * with ':' should be expanded into current working directory. - */ - if (size == 0) { - snprintf(buf, buf_len, "."); - size = strlen(buf); - } - - /* - * If there is no '/' ad the end of path from $PATH add it. - */ - if (buf[size - 1] != '/') - ret = - snprintf(buf + size, buf_len - size, "/%s", - prog_name); - else - ret = - snprintf(buf + size, buf_len - size, "%s", - prog_name); - - if (buf_len - size > ret && file_exist(buf)) - return 0; - - start = end + 1; - - } while (end != NULL); - - return -1; -} diff --git a/kernel/tests/lib/parse_opts.c b/kernel/tests/lib/parse_opts.c deleted file mode 100644 index a9d5058..0000000 --- a/kernel/tests/lib/parse_opts.c +++ /dev/null @@ -1,621 +0,0 @@ -/* - * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. - * AUTHOR : William Roske/Richard Logan - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it would be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * Further, this software is distributed without any warranty that it is - * free of the rightful claim of any third person regarding infringement - * or the like. Any license provided herein, whether implied or - * otherwise, applies only to this software file. Patent licenses, if - * any, provided herein do not apply to combinations of this program with - * other software, or any other product whatsoever. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, - * Mountain View, CA 94043, or: - * - * http://www.sgi.com - * - * For further information regarding this notice, see: - * - * http://oss.sgi.com/projects/GenInfo/NoticeExplan/ - */ - -#include "config.h" -#include <errno.h> -#include <stdlib.h> -#include <string.h> -#include <sys/param.h> -#include <sys/signal.h> -#include <sys/types.h> -#include <unistd.h> -#include <time.h> -#include <stdint.h> - -#include "test.h" -#include "ltp_priv.h" -#include "usctest.h" -#include "tst_clocks.h" - -#ifndef UNIT_TEST -#define UNIT_TEST 0 -#endif - -/* Define flags and args for standard options */ -static int STD_INFINITE = 0; /* flag indciating to loop forever */ -int STD_LOOP_COUNT = 1; /* number of iterations */ - -static float STD_LOOP_DURATION = 0.0; /* duration value in fractional seconds */ - -static char **STD_opt_arr = NULL; /* array of option strings */ -static int STD_argind = 1; /* argv index to next argv element */ - /* (first argument) */ - /* To getopt users, it is like optind */ - -/* - * The following variables are to support system testing additions. - */ -static int STD_TP_barrier = 0; /* flag to do barrier in TEST_PAUSE */ - /* 2 - wait_barrier(), 3 - set_barrier(), * - barrier() */ -static int STD_LP_barrier = 0; /* flag to do barrier in TEST_LOOPING */ - /* 2 - wait_barrier(), 3 - set_barrier(), * - barrier() */ -static int STD_TP_shmem_sz = 0; /* shmalloc this many words per pe in TEST_PAUSE */ -static int STD_LD_shmem = 0; /* flag to do shmem_puts and shmem_gets during delay */ -static int STD_LP_shmem = 0; /* flag to do shmem_puts and gets during TEST_LOOPING */ -static int STD_LD_recfun = 0; /* do recressive function calls in loop delay */ -static int STD_LP_recfun = 0; /* do recressive function calls in TEST_LOOPING */ -static int STD_TP_sbrk = 0; /* do sbrk in TEST_PAUSE */ -static int STD_LP_sbrk = 0; /* do sbrk in TEST_LOOPING */ -static char *STD_start_break = 0; /* original sbrk size */ -static int Debug = 0; - -static struct std_option_t { - char *optstr; - char *help; - char *flag; - char **arg; -} std_options[] = { - {"h", " -h Show this help screen\n", NULL, NULL}, - {"i:", " -i n Execute test n times\n", NULL, NULL}, - {"I:", " -I x Execute test for x seconds\n", NULL, NULL}, -#ifdef UCLINUX - {"C:", - " -C ARG Run the child process with arguments ARG (for internal use)\n", - NULL, NULL}, -#endif - {NULL, NULL, NULL, NULL} -}; - -/* - * Structure for usc_recressive_func argument - */ -struct usc_bigstack_t { - char space[4096]; -}; - -static struct usc_bigstack_t *STD_bigstack = NULL; - -/* define the string length for Mesg and Mesg2 strings */ -#define STRLEN 2048 - -static char Mesg2[STRLEN]; /* holds possible return string */ -static void usc_recressive_func(); - -/* - * Define bits for options that might have env variable default - */ -#define OPT_iteration 01 -#define OPT_duration 04 -#define OPT_delay 010 - -#ifdef UCLINUX -/* Allocated and used in self_exec.c: */ -extern char *child_args; /* Arguments to child when -C is used */ -#endif - -static void print_help(void (*user_help)(void)) -{ - int i; - - for (i = 0; std_options[i].optstr; ++i) { - if (std_options[i].help) - printf("%s", std_options[i].help); - } - - if (user_help) - user_help(); -} - -/********************************************************************** - * parse_opts: - **********************************************************************/ -const char *parse_opts(int ac, char **av, const option_t * user_optarr, - void (*uhf)(void)) -{ - int found; /* flag to indicate that an option specified was */ - /* found in the user's list */ - int k; /* scratch integer for returns and short time usage */ - float ftmp; /* tmp float for parsing env variables */ - char *ptr; /* used in getting env variables */ - int options = 0; /* no options specified */ - int optstrlen, i; - char *optionstr; - int opt; - - /* - * If not the first time this function is called, release the old STD_opt_arr - * vector. - */ - if (STD_opt_arr != NULL) { - free(STD_opt_arr); - STD_opt_arr = NULL; - } - /* Calculate how much space we need for the option string */ - optstrlen = 0; - for (i = 0; std_options[i].optstr; ++i) - optstrlen += strlen(std_options[i].optstr); - if (user_optarr) - for (i = 0; user_optarr[i].option; ++i) { - if (strlen(user_optarr[i].option) > 2) - return - "parse_opts: ERROR - Only short options are allowed"; - optstrlen += strlen(user_optarr[i].option); - } - optstrlen += 1; - - /* Create the option string for getopt */ - optionstr = malloc(optstrlen); - if (!optionstr) - return - "parse_opts: ERROR - Could not allocate memory for optionstr"; - - optionstr[0] = '\0'; - - for (i = 0; std_options[i].optstr; ++i) - strcat(optionstr, std_options[i].optstr); - if (user_optarr) - for (i = 0; user_optarr[i].option; ++i) - /* only add the option if it wasn't there already */ - if (strchr(optionstr, user_optarr[i].option[0]) == NULL) - strcat(optionstr, user_optarr[i].option); - - /* - * Loop through av parsing options. - */ - while ((opt = getopt(ac, av, optionstr)) > 0) { - - STD_argind = optind; - - switch (opt) { - case '?': /* Unknown option */ - return "Unknown option"; - break; - case ':': /* Missing Arg */ - return "Missing argument"; - break; - case 'i': /* Iterations */ - options |= OPT_iteration; - STD_LOOP_COUNT = atoi(optarg); - if (STD_LOOP_COUNT == 0) - STD_INFINITE = 1; - break; - case 'I': /* Time duration */ - options |= OPT_duration; - STD_LOOP_DURATION = atof(optarg); - if (STD_LOOP_DURATION == 0.0) - STD_INFINITE = 1; - break; - case 'h': /* Help */ - print_help(uhf); - exit(0); - break; -#ifdef UCLINUX - case 'C': /* Run child */ - child_args = optarg; - break; -#endif - default: - - /* Check all the user specified options */ - found = 0; - for (i = 0; user_optarr[i].option; ++i) { - - if (opt == user_optarr[i].option[0]) { - /* Yup, This is a user option, set the flag and look for argument */ - if (user_optarr[i].flag) { - *user_optarr[i].flag = 1; - } - found++; - - /* save the argument at the user's location */ - if (user_optarr[i]. - option[strlen(user_optarr[i].option) - - 1] == ':') { - *user_optarr[i].arg = optarg; - } - break; /* option found - break out of the for loop */ - } - } - /* This condition "should never happen". SO CHECK FOR IT!!!! */ - if (!found) { - sprintf(Mesg2, - "parse_opts: ERROR - option:\"%c\" NOT FOUND... INTERNAL " - "ERROR", opt); - return (Mesg2); - } - } - - } - free(optionstr); - - STD_argind = optind; - - /* - * Turn on debug - */ - if (getenv("USC_DEBUG") != NULL) { - Debug = 1; - printf("env USC_DEBUG is defined, turning on debug\n"); - } - if (getenv("USC_VERBOSE") != NULL) { - Debug = 1; - printf("env USC_VERBOSE is defined, turning on debug\n"); - } - - /* - * If the USC_ITERATION_ENV environmental variable is set to - * a number, use that number as iteration count (same as -c option). - * The -c option with arg will be used even if this env var is set. - */ - if (!(options & OPT_iteration) - && (ptr = getenv(USC_ITERATION_ENV)) != NULL) { - if (sscanf(ptr, "%i", &k) == 1) { - if (k == 0) { /* if arg is 0, set infinite loop flag */ - STD_INFINITE = 1; - if (Debug) - printf - ("Using env %s, set STD_INFINITE to 1\n", - USC_ITERATION_ENV); - } else { /* else, set the loop count to the arguement */ - STD_LOOP_COUNT = k; - if (Debug) - printf - ("Using env %s, set STD_LOOP_COUNT to %d\n", - USC_ITERATION_ENV, k); - } - } - } - - /* - * If the USC_LOOP_WALLTIME environmental variable is set, - * use that number as duration (same as -I option). - * The -I option with arg will be used even if this env var is set. - */ - - if (!(options & OPT_duration) && - (ptr = getenv(USC_LOOP_WALLTIME)) != NULL) { - if (sscanf(ptr, "%f", &ftmp) == 1 && ftmp >= 0.0) { - STD_LOOP_DURATION = ftmp; - if (Debug) - printf - ("Using env %s, set STD_LOOP_DURATION to %f\n", - USC_LOOP_WALLTIME, ftmp); - if (STD_LOOP_DURATION == 0.0) { /* if arg is 0, set infinite loop flag */ - STD_INFINITE = 1; - if (Debug) - printf - ("Using env %s, set STD_INFINITE to 1\n", - USC_LOOP_WALLTIME); - } - } - } - if (!(options & OPT_duration) && (ptr = getenv("USC_DURATION")) != NULL) { - if (sscanf(ptr, "%f", &ftmp) == 1 && ftmp >= 0.0) { - STD_LOOP_DURATION = ftmp; - if (Debug) - printf - ("Using env USC_DURATION, set STD_LOOP_DURATION to %f\n", - ftmp); - if (STD_LOOP_DURATION == 0.0) { /* if arg is 0, set infinite loop flag */ - STD_INFINITE = 1; - if (Debug) - printf - ("Using env USC_DURATION, set STD_INFINITE to 1\n"); - } - } - } - - /* - * The following are special system testing envs to turn on special - * hooks in the code. - */ - if ((ptr = getenv("USC_TP_BARRIER")) != NULL) { - if (sscanf(ptr, "%i", &k) == 1 && k >= 0) - STD_TP_barrier = k; - else - STD_TP_barrier = 1; - if (Debug) - printf - ("using env USC_TP_BARRIER, Set STD_TP_barrier to %d\n", - STD_TP_barrier); - } - - if ((ptr = getenv("USC_LP_BARRIER")) != NULL) { - if (sscanf(ptr, "%i", &k) == 1 && k >= 0) - STD_LP_barrier = k; - else - STD_LP_barrier = 1; - if (Debug) - printf - ("using env USC_LP_BARRIER, Set STD_LP_barrier to %d\n", - STD_LP_barrier); - } - - if ((ptr = getenv("USC_TP_SHMEM")) != NULL) { - if (sscanf(ptr, "%i", &k) == 1 && k >= 0) { - STD_TP_shmem_sz = k; - if (Debug) - printf - ("Using env USC_TP_SHMEM, Set STD_TP_shmem_sz to %d\n", - STD_TP_shmem_sz); - } - } - - if ((ptr = getenv("USC_LP_SHMEM")) != NULL) { - if (sscanf(ptr, "%i", &k) == 1 && k >= 0) { - STD_LP_shmem = k; - if (Debug) - printf - ("Using env USC_LP_SHMEM, Set STD_LP_shmem to %d\n", - STD_LP_shmem); - } - } - - if ((ptr = getenv("USC_LD_SHMEM")) != NULL) { - if (sscanf(ptr, "%i", &k) == 1 && k >= 0) { - STD_LD_shmem = k; - if (Debug) - printf - ("Using env USC_LD_SHMEM, Set STD_LD_shmem to %d\n", - STD_LD_shmem); - } - } - - if ((ptr = getenv("USC_TP_SBRK")) != NULL) { - if (sscanf(ptr, "%i", &k) == 1 && k >= 0) { - STD_TP_sbrk = k; - if (Debug) - printf - ("Using env USC_TP_SBRK, Set STD_TP_sbrk to %d\n", - STD_TP_sbrk); - } - } -#if !defined(UCLINUX) - if ((ptr = getenv("USC_LP_SBRK")) != NULL) { - if (sscanf(ptr, "%i", &k) == 1 && k >= 0) { - STD_LP_sbrk = k; - if (Debug) - printf - ("Using env USC_LP_SBRK, Set STD_LP_sbrk to %d\n", - STD_LP_sbrk); - } - } -#endif /* if !defined(UCLINUX) */ - - if ((ptr = getenv("USC_LP_RECFUN")) != NULL) { - if (sscanf(ptr, "%i", &k) == 1 && k >= 0) { - STD_LP_recfun = k; - if (STD_bigstack != NULL) - STD_bigstack = - malloc(sizeof(struct usc_bigstack_t)); - if (Debug) - printf - ("Using env USC_LP_RECFUN, Set STD_LP_recfun to %d\n", - STD_LP_recfun); - } - } - - if ((ptr = getenv("USC_LD_RECFUN")) != NULL) { - if (sscanf(ptr, "%i", &k) == 1 && k >= 0) { - STD_LD_recfun = k; - if (STD_bigstack != NULL) - STD_bigstack = - malloc(sizeof(struct usc_bigstack_t)); - if (Debug) - printf - ("Using env USC_LD_RECFUN, Set STD_LD_recfun to %d\n", - STD_LD_recfun); - } - } -#if UNIT_TEST - printf("The following variables after option and env parsing:\n"); - printf("STD_LOOP_DURATION = %f\n", STD_LOOP_DURATION); - printf("STD_LOOP_COUNT = %d\n", STD_LOOP_COUNT); - printf("STD_INFINITE = %d\n", STD_INFINITE); -#endif - - return NULL; -} - -/*********************************************************************** - * This function will do desired end of global setup test - * hooks. - ***********************************************************************/ -int usc_global_setup_hook(void) -{ -#ifndef UCLINUX - if (STD_TP_sbrk || STD_LP_sbrk) - STD_start_break = sbrk(0); /* get original sbreak size */ - - if (STD_TP_sbrk) { - sbrk(STD_TP_sbrk); - if (Debug) - printf("after sbrk(%d)\n", STD_TP_sbrk); - } -#endif - return 0; -} - -#define USECS_PER_SEC 1000000 /* microseconds per second */ - -static uint64_t get_current_time(void) -{ - struct timespec ts; - - tst_clock_gettime(CLOCK_MONOTONIC, &ts); - - return (((uint64_t) ts.tv_sec) * USECS_PER_SEC) + ts.tv_nsec / 1000; -} - -/*********************************************************************** - * - * This function will determine if test should continue iterating - * If the STD_INFINITE flag is set, return 1. - * If the STD_LOOP_COUNT variable is set, compare it against - * the counter. - * If the STD_LOOP_DURATION variable is set, compare current time against - * calculated stop_time. - * This function will return 1 until all desired looping methods - * have been met. - * - * counter integer is supplied by the user program. - ***********************************************************************/ -int usc_test_looping(int counter) -{ - static int first_time = 1; - static uint64_t stop_time = 0; - int keepgoing = 0; - - /* - * If this is the first iteration and we are looping for - * duration of STD_LOOP_DURATION seconds (fractional) or - * doing loop delays, get the clocks per second. - */ - if (first_time) { - first_time = 0; - - /* - * If looping for duration, calculate stop time in - * clocks. - */ - if (STD_LOOP_DURATION) { - stop_time = - (uint64_t) (USECS_PER_SEC * STD_LOOP_DURATION) - + get_current_time(); - } - } - - if (STD_INFINITE) - keepgoing++; - - if (STD_LOOP_COUNT && counter < STD_LOOP_COUNT) - keepgoing++; - - if (STD_LOOP_DURATION != 0.0 && get_current_time() < stop_time) - keepgoing++; - - if (keepgoing == 0) - return 0; - - /* - * The following code allows special system testing hooks. - */ - - if (STD_LP_recfun) { - if (Debug) - printf - ("calling usc_recressive_func(0, %d, *STD_bigstack)\n", - STD_LP_recfun); - usc_recressive_func(0, STD_LP_recfun, *STD_bigstack); - } -#if !defined(UCLINUX) - if (STD_LP_sbrk) { - if (Debug) - printf("about to do sbrk(%d)\n", STD_LP_sbrk); - sbrk(STD_LP_sbrk); - } -#endif - - if (keepgoing) - return 1; - else - return 0; -} - -/* - * This function recressively calls itself max times. - */ -static void usc_recressive_func(int cnt, int max, struct usc_bigstack_t bstack) -{ - if (cnt < max) - usc_recressive_func(cnt + 1, max, bstack); - -} - -#if UNIT_TEST - -/****************************************************************************** - * UNIT TEST CODE - * UNIT TEST CODE - * - * this following code is provide so that unit testing can - * be done fairly easily. - ******************************************************************************/ - -int Help = 0; -int Help2 = 0; -char *ptr; - -long TEST_RETURN; -int TEST_ERRNO; - -/* for test specific parse_opts options */ -option_t Options[] = { - {"help", &Help2, NULL}, /* -help option */ - {"h", &Help, NULL}, /* -h option */ - -#if INVALID_TEST_CASES - {"missingflag", NULL, &ptr}, /* error */ - {"missingarg:", &Help, NULL}, /* error */ -#endif /* INVALID_TEST_CASES */ - - {NULL, NULL, NULL} -}; - -int main(int argc, char **argv) -{ - int lc; - char *msg; - struct timeval t; - int cnt; - - if ((msg = parse_opts(argc, argv, Options, NULL)) != NULL) { - printf("ERROR: %s\n", msg); - exit(1); - } - - TEST_PAUSE; - - for (lc = 0; TEST_LOOPING(lc); lc++) { - - TEST(gettimeofday(&t, NULL)); - printf("iter=%d: sec:%d, usec:%6.6d %s", lc + 1, t.tv_sec, - t.tv_usec, ctime(&t.tv_sec)); - } - - TEST_CLEANUP; - - exit(0); -} - -#endif /* UNIT_TEST */ diff --git a/kernel/tests/lib/random_range.c b/kernel/tests/lib/random_range.c deleted file mode 100644 index 510a4a1..0000000 --- a/kernel/tests/lib/random_range.c +++ /dev/null @@ -1,892 +0,0 @@ -/* - * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it would be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * Further, this software is distributed without any warranty that it is - * free of the rightful claim of any third person regarding infringement - * or the like. Any license provided herein, whether implied or - * otherwise, applies only to this software file. Patent licenses, if - * any, provided herein do not apply to combinations of this program with - * other software, or any other product whatsoever. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, - * Mountain View, CA 94043, or: - * - * http://www.sgi.com - * - * For further information regarding this notice, see: - * - * http://oss.sgi.com/projects/GenInfo/NoticeExplan/ - */ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <malloc.h> -#include "random_range.h" - -/* - * Internal format of the range array set up by parse_range() - */ - -struct range { - int min; - int max; - int mult; -}; - -/* - * parse_ranges() is a function to parse a comma-separated list of range - * tokens each having the following form: - * - * num - * or - * min:max[:mult] - * - * any of the values may be blank (ie. min::mult, :max, etc.) and default - * values for missing arguments may be supplied by the caller. - * - * The special first form is short hand for 'num:num'. - * - * After parsing the string, the ranges are put into an array of integers, - * which is malloc'd by the routine. The min, max, and mult entries of each - * range can be extracted from the array using the range_min(), range_max(), - * and range_mult() functions. - * - * It is the responsibility of the caller to free the space allocated by - * parse_ranges() - a single call to free() will free the space. - * - * str The string to parse - assumed to be a comma-separated - * list of tokens having the above format. - * defmin default value to plug in for min, if it is missing - * defmax default value to plug in for max, if it is missing - * defmult default value to plug in for mult, if missing - * parse_func A user-supplied function pointer, which parse_ranges() - * can call to parse the min, max, and mult strings. This - * allows for customized number formats. The function - * MUST have the following prototype: - * parse_func(char *str, int *val) - * The function should return -1 if str cannot be parsed - * into an integer, or >= 0 if it was successfully - * parsed. The resulting integer will be stored in - * *val. If parse_func is NULL, parse_ranges will parse - * the tokens in a manner consistent with the the sscanf - * %i format. - * range_ptr A user-supplied char **, which will be set to point - * at malloc'd space which holds the parsed range - * values. If range_ptr is NULL, parse_ranges() just - * parses the string. The data returned in range_ptr - * should not be processed directly - use the functions - * range_min(), range_max(), and range_mult() to access - * data for a given range. - * errptr user-supplied char ** which can be set to point to a - * static error string. If errptr is NULL, it is ignored. - * - * parse_range() returns -1 on error, or the number of ranges parsed. - */ - -static int str_to_int(); -static long long divider(long long, long long, long long, long long); - -int parse_ranges(char *str, int defmin, int defmax, int defmult, - int (*parse_func)(), char **rangeptr, char **errptr) -{ - int ncommas; - char *tmpstr, *cp, *tok, *n1str, *n2str, *multstr; - struct range *rp, *ranges; - static char errmsg[256]; - - if (errptr != NULL) { - *errptr = errmsg; - } - - for (ncommas = 0, cp = str; *cp != '\0'; cp++) { - if (*cp == ',') { - ncommas++; - } - } - - if (parse_func == NULL) { - parse_func = str_to_int; - } - - tmpstr = strdup(str); - ranges = malloc((ncommas + 1) * sizeof(struct range)); - rp = ranges; - - tok = strtok(tmpstr, ","); - while (tok != NULL) { - n1str = tok; - n2str = NULL; - multstr = NULL; - - rp->min = defmin; - rp->max = defmax; - rp->mult = defmult; - - if ((cp = strchr(n1str, ':')) != NULL) { - *cp = '\0'; - n2str = cp + 1; - - if ((cp = strchr(n2str, ':')) != NULL) { - *cp = '\0'; - multstr = cp + 1; - } - } - - /* - * Parse the 'min' field - if it is zero length (:n2[:mult] - * format), retain the default value, otherwise, pass the - * string to the parse function. - */ - - if ((int)strlen(n1str) > 0) { - if ((*parse_func) (n1str, &rp->min) < 0) { - sprintf(errmsg, - "error parsing string %s into an integer", - n1str); - free(tmpstr); - free(ranges); - return -1; - } - } - - /* - * Process the 'max' field - if one was not present (n1 format) - * set max equal to min. If the field was present, but - * zero length (n1: format), retain the default. Otherwise - * pass the string to the parse function. - */ - - if (n2str == NULL) { - rp->max = rp->min; - } else if ((int)strlen(n2str) > 0) { - if ((*parse_func) (n2str, &rp->max) < 0) { - sprintf(errmsg, - "error parsing string %s into an integer", - n2str); - free(tmpstr); - free(ranges); - return -1; - } - } - - /* - * Process the 'mult' field - if one was not present - * (n1:n2 format), or the field was zero length (n1:n2: format) - * then set the mult field to defmult - otherwise pass then - * mult field to the parse function. - */ - - if (multstr != NULL && (int)strlen(multstr) > 0) { - if ((*parse_func) (multstr, &rp->mult) < 0) { - sprintf(errmsg, - "error parsing string %s into an integer", - multstr); - free(tmpstr); - free(ranges); - return -1; - } - } - - rp++; - tok = strtok(NULL, ","); - } - - free(tmpstr); - - if (rangeptr != NULL) { - *rangeptr = (char *)ranges; - } else { - free(ranges); /* just running in parse mode */ - } - - return (rp - ranges); -} - -/* - * The default integer-parsing function - */ - -static int str_to_int(char *str, int *ip) -{ - char c; - - if (sscanf(str, "%i%c", ip, &c) != 1) { - return -1; - } else { - return 0; - } -} - -/* - * Three simple functions to return the min, max, and mult values for a given - * range. It is assumed that rbuf is a range buffer set up by parse_ranges(), - * and that r is a valid range within that buffer. - */ - -int range_min(char *rbuf, int r) -{ - return ((struct range *)rbuf)[r].min; -} - -int range_max(char *rbuf, int r) -{ - return ((struct range *)rbuf)[r].max; -} - -int range_mult(char *rbuf, int r) -{ - return ((struct range *)rbuf)[r].mult; -} - -/***************************************************************************** - * random_range(int start, int end, int mult, char **errp) - * - * Returns a psuedo-random number which is >= 'start', <= 'end', and a multiple - * of 'mult'. Start and end may be any valid integer, but mult must be an - * integer > 0. errp is a char ** which will be set to point to a static - * error message buffer if it is not NULL, and an error occurs. - * - * The errp is the only way to check if the routine fails - currently the only - * failure conditions are: - * - * mult < 1 - * no numbers in the start-end range that are a multiple of 'mult' - * - * If random_range_fails, and errp is a valid pointer, it will point to an - * internal error buffer. If errp is a vaild pointer, and random_range - * is successful, errp will be set to NULL. - * - * Note - if mult is 1 (the most common case), there are error conditions - * possible, and errp need not be used. - * - * Note: Uses lrand48(), assuming that set_random_seed() uses srand48() when - * setting the seed. - *****************************************************************************/ - -long random_range(int min, int max, int mult, char **errp) -{ - int r, nmults, orig_min, orig_max, orig_mult, tmp; - extern long lrand48(); - static char errbuf[128]; - - /* - * Sanity check - */ - - if (mult < 1) { - if (errp != NULL) { - sprintf(errbuf, "mult arg must be greater than 0"); - *errp = errbuf; - } - return -1; - } - - /* - * Save original parameter values for use in error message - */ - - orig_min = min; - orig_max = max; - orig_mult = mult; - - /* - * switch min/max if max < min - */ - - if (max < min) { - tmp = max; - max = min; - min = tmp; - } - - /* - * select the random number - */ - - if ((r = min % mult)) /* bump to the next higher 'mult' multiple */ - min += mult - r; - - if ((r = max % mult)) /* reduce to the next lower 'mult' multiple */ - max -= r; - - if (min > max) { /* no 'mult' multiples between min & max */ - if (errp != NULL) { - sprintf(errbuf, - "no numbers in the range %d:%d that are a multiple of %d", - orig_min, orig_max, orig_mult); - *errp = errbuf; - } - return -1; - } - - if (errp != NULL) { - *errp = NULL; - } - - nmults = ((max - min) / mult) + 1; -#if CRAY - /* - * If max is less than 2gb, then the value can fit in 32 bits - * and the standard lrand48() routine can be used. - */ - if (max <= (long)2147483647) { - return (long)(min + (((long)lrand48() % nmults) * mult)); - } else { - /* - * max is greater than 2gb - meeds more than 32 bits. - * Since lrand48 only will get a number up to 32bits. - */ - long randnum; - randnum = divider(min, max, 0, -1); - return (long)(min + ((randnum % nmults) * mult)); - } - -#else - return (min + ((lrand48() % nmults) * mult)); -#endif - -} - -/* - * Just like random_range, but all values are longs. - */ -long random_rangel(long min, long max, long mult, char **errp) -{ - long r, nmults, orig_min, orig_max, orig_mult, tmp; - extern long lrand48(); - static char errbuf[128]; - - /* - * Sanity check - */ - - if (mult < 1) { - if (errp != NULL) { - sprintf(errbuf, "mult arg must be greater than 0"); - *errp = errbuf; - } - return -1; - } - - /* - * Save original parameter values for use in error message - */ - - orig_min = min; - orig_max = max; - orig_mult = mult; - - /* - * switch min/max if max < min - */ - - if (max < min) { - tmp = max; - max = min; - min = tmp; - } - - /* - * select the random number - */ - - if ((r = min % mult)) /* bump to the next higher 'mult' multiple */ - min += mult - r; - - if ((r = max % mult)) /* reduce to the next lower 'mult' multiple */ - max -= r; - - if (min > max) { /* no 'mult' multiples between min & max */ - if (errp != NULL) { - sprintf(errbuf, - "no numbers in the range %ld:%ld that are a multiple of %ld", - orig_min, orig_max, orig_mult); - *errp = errbuf; - } - return -1; - } - - if (errp != NULL) { - *errp = NULL; - } - - nmults = ((max - min) / mult) + 1; -#if CRAY || (_MIPS_SZLONG == 64) - /* - * If max is less than 2gb, then the value can fit in 32 bits - * and the standard lrand48() routine can be used. - */ - if (max <= (long)2147483647) { - return (long)(min + (((long)lrand48() % nmults) * mult)); - } else { - /* - * max is greater than 2gb - meeds more than 32 bits. - * Since lrand48 only will get a number up to 32bits. - */ - long randnum; - randnum = divider(min, max, 0, -1); - return (long)(min + ((randnum % nmults) * mult)); - } - -#else - return (min + ((lrand48() % nmults) * mult)); -#endif -} - -/* - * Attempts to be just like random_range, but everything is long long (64 bit) - */ -long long random_rangell(long long min, long long max, - long long mult, char **errp) -{ - long long r, nmults, orig_min, orig_max, orig_mult, tmp; - long long randnum; - extern long lrand48(); - static char errbuf[128]; - - /* - * Sanity check - */ - - if (mult < 1) { - if (errp != NULL) { - sprintf(errbuf, "mult arg must be greater than 0"); - *errp = errbuf; - } - return -1; - } - - /* - * Save original parameter values for use in error message - */ - - orig_min = min; - orig_max = max; - orig_mult = mult; - - /* - * switch min/max if max < min - */ - - if (max < min) { - tmp = max; - max = min; - min = tmp; - } - - /* - * select the random number - */ - - if ((r = min % mult)) /* bump to the next higher 'mult' multiple */ - min += mult - r; - - if ((r = max % mult)) /* reduce to the next lower 'mult' multiple */ - max -= r; - - if (min > max) { /* no 'mult' multiples between min & max */ - if (errp != NULL) { - sprintf(errbuf, - "no numbers in the range %lld:%lld that are a multiple of %lld", - orig_min, orig_max, orig_mult); - *errp = errbuf; - } - return -1; - } - - if (errp != NULL) { - *errp = NULL; - } - - nmults = ((max - min) / mult) + 1; - /* - * If max is less than 2gb, then the value can fit in 32 bits - * and the standard lrand48() routine can be used. - */ - if (max <= (long)2147483647) { - return (long long)(min + - (((long long)lrand48() % nmults) * mult)); - } else { - /* - * max is greater than 2gb - meeds more than 32 bits. - * Since lrand48 only will get a number up to 32bits. - */ - randnum = divider(min, max, 0, -1); - return (long long)(min + ((randnum % nmults) * mult)); - } - -} - -/* - * This functional will recusively call itself to return a random - * number min and max. It was designed to work the 64bit numbers - * even when compiled as 32 bit process. - * algorithm: to use the official lrand48() routine - limited to 32 bits. - * find the difference between min and max (max-min). - * if the difference is 2g or less, use the random number gotton from lrand48(). - * Determine the midway point between min and max. - * if the midway point is less than 2g from min or max, - * randomly add the random number gotton from lrand48() to - * either min or the midpoint. - * Otherwise, call outself with min and max being min and midway value or - * midway value and max. This will reduce the range in half. - */ -static long long -divider(long long min, long long max, long long cnt, long long rand) -{ - long long med, half, diff; - - /* - * prevent run away code. We are dividing by two each count. - * if we get to a count of more than 32, we should have gotten - * to 2gb. - */ - if (cnt > 32) - return -1; - - /* - * Only get a random number the first time. - */ - if (cnt == 0 || rand < -1) { - rand = (long long)lrand48(); /* 32 bit random number */ - } - - diff = max - min; - - if (diff <= 2147483647) - return min + rand; - - half = diff / (long long)2; /* half the distance between min and max */ - med = min + half; /* med way point between min and max */ - -#if DEBUG - printf("divider: min=%lld, max=%lld, cnt=%lld, rand=%lld\n", min, max, - cnt, rand); - printf(" diff = %lld, half = %lld, med = %lld\n", diff, half, med); -#endif - - if (half <= 2147483647) { - /* - * If half is smaller than 2gb, we can use the random number - * to pick the number within the min to med or med to max - * if the cnt bit of rand is zero or one, respectively. - */ - if (rand & (1 << cnt)) - return med + rand; - else - return min + rand; - } else { - /* - * recursively call ourself to reduce the value to the bottom half - * or top half (bit cnt is set). - */ - if (rand & (1 << cnt)) { - return divider(med, max, cnt + 1, rand); - } else { - return divider(min, med, cnt + 1, rand); - } - - } - -} - -/***************************************************************************** - * random_range_seed(s) - * - * Sets the random seed to s. Uses srand48(), assuming that lrand48() will - * be used in random_range(). - *****************************************************************************/ - -void random_range_seed(long s) -{ - extern void srand48(); - - srand48(s); -} - -/**************************************************************************** - * random_bit(mask) - * - * This function randomly returns a single bit from the bits - * set in mask. If mask is zero, zero is returned. - * - ****************************************************************************/ -long random_bit(long mask) -{ - int nbits = 0; /* number of set bits in mask */ - long bit; /* used to count bits and num of set bits choosen */ - int nshift; /* used to count bit shifts */ - - if (mask == 0) - return 0; - - /* - * get the number of bits set in mask - */ -#ifndef CRAY - - bit = 1L; - for (nshift = 0; (unsigned int)nshift < sizeof(long) * 8; nshift++) { - if (mask & bit) - nbits++; - bit = bit << 1; - } - -#else - nbits = _popcnt(mask); -#endif /* if CRAY */ - - /* - * randomly choose a bit. - */ - bit = random_range(1, nbits, 1, NULL); - - /* - * shift bits until you determine which bit was randomly choosen. - * nshift will hold the number of shifts to make. - */ - - nshift = 0; - while (bit) { - /* check if the current one's bit is set */ - if (mask & 1L) { - bit--; - } - mask = mask >> 1; - nshift++; - } - - return 01L << (nshift - 1); - -} - -#if RANDOM_BIT_UNITTEST -/* - * The following is a unit test main function for random_bit(). - */ -main(argc, argv) -int argc; -char **argv; -{ - int ind; - int cnt, iter; - long mask, ret; - - printf("test for first and last bit set\n"); - mask = 1L; - ret = random_bit(mask); - printf("random_bit(%#o) returned %#o\n", mask, ret); - - mask = 1L << (sizeof(long) * 8 - 1); - ret = random_bit(mask); - printf("random_bit(%#o) returned %#o\n", mask, ret); - - if (argc >= 3) { - iter = atoi(argv[1]); - for (ind = 2; ind < argc; ind++) { - printf("Calling random_bit %d times for mask %#o\n", - iter, mask); - sscanf(argv[ind], "%i", &mask); - for (cnt = 0; cnt < iter; cnt++) { - ret = random_bit(mask); - printf("random_bit(%#o) returned %#o\n", mask, - ret); - } - } - } - exit(0); -} - -#endif /* end if RANDOM_BIT_UNITTEST */ - -#if UNIT_TEST -/* - * The following is a unit test main function for random_range*(). - */ - -#define PARTNUM 10 /* used to determine even distribution of random numbers */ -#define MEG 1024*1024*1024 -#define GIG 1073741824 -int main(argc, argv) -int argc; -char **argv; -{ - int ind; - int cnt, iter = 10; - int imin = 0, imult = 1, itmin, itmax = 0; -#if CRAY - int imax = 6 * GIG; /* higher than 32 bits */ -#else - int imax = 1048576; -#endif - - long lret, lmin = 0, lmult = 1, ltmin, ltmax = 0; -#if CRAY || (_MIPS_SZLONG == 64) - long lmax = 6 * (long)GIG; /* higher than 32 bits */ -#else - long lmax = 1048576; -#endif - long long llret, llmin = 0, llmult = 1, lltmin, lltmax = 0; - long long llmax = (long long)80 * (long long)GIG; - - long part; - long long lpart; - long cntarr[PARTNUM]; - long valbound[PARTNUM]; - long long lvalbound[PARTNUM]; - - for (ind = 0; ind < PARTNUM; ind++) - cntarr[ind] = 0; - - if (argc < 2) { - printf("Usage: %s func [iterations] \n", argv[0]); - printf - ("func can be random_range, random_rangel, random_rangell\n"); - exit(1); - } - - if (argc >= 3) { - if (sscanf(argv[2], "%i", &iter) != 1) { - printf("Usage: %s [func iterations] \n", argv[0]); - printf("argv[2] is not a number\n"); - exit(1); - } - } - - /* - * random_rangel () - */ - if (strcmp(argv[1], "random_rangel") == 0) { - ltmin = lmax; - part = lmax / PARTNUM; - for (ind = 0; ind < PARTNUM; ind++) { - valbound[ind] = part * ind; - } - - for (cnt = 0; cnt < iter; cnt++) { - lret = random_rangel(lmin, lmax, lmult, NULL); - if (iter < 100) - printf("%ld\n", lret); - if (lret < ltmin) - ltmin = lret; - if (lret > ltmax) - ltmax = lret; - for (ind = 0; ind < PARTNUM - 1; ind++) { - if (valbound[ind] < lret - && lret <= valbound[ind + 1]) { - cntarr[ind]++; - break; - } - } - if (lret > valbound[PARTNUM - 1]) { - cntarr[PARTNUM - 1]++; - } - } - for (ind = 0; ind < PARTNUM - 1; ind++) { - printf("%2d %-13ld to %-13ld %5ld %4.4f\n", ind + 1, - valbound[ind], valbound[ind + 1], cntarr[ind], - (float)(cntarr[ind] / (float)iter)); - } - printf("%2d %-13ld to %-13ld %5ld %4.4f\n", PARTNUM, - valbound[PARTNUM - 1], lmax, cntarr[PARTNUM - 1], - (float)(cntarr[PARTNUM - 1] / (float)iter)); - printf(" min=%ld, max=%ld\n", ltmin, ltmax); - - } else if (strcmp(argv[1], "random_rangell") == 0) { - /* - * random_rangell() unit test - */ - lltmin = llmax; - lpart = llmax / PARTNUM; - for (ind = 0; ind < PARTNUM; ind++) { - lvalbound[ind] = (long long)(lpart * ind); - } - - for (cnt = 0; cnt < iter; cnt++) { - llret = random_rangell(llmin, llmax, llmult, NULL); - if (iter < 100) - printf("random_rangell returned %lld\n", llret); - if (llret < lltmin) - lltmin = llret; - if (llret > lltmax) - lltmax = llret; - - for (ind = 0; ind < PARTNUM - 1; ind++) { - if (lvalbound[ind] < llret - && llret <= lvalbound[ind + 1]) { - cntarr[ind]++; - break; - } - } - if (llret > lvalbound[PARTNUM - 1]) { - cntarr[PARTNUM - 1]++; - } - } - for (ind = 0; ind < PARTNUM - 1; ind++) { - printf("%2d %-13lld to %-13lld %5ld %4.4f\n", - ind + 1, lvalbound[ind], lvalbound[ind + 1], - cntarr[ind], (float)(cntarr[ind] / (float)iter)); - } - printf("%2d %-13lld to %-13lld %5ld %4.4f\n", PARTNUM, - lvalbound[PARTNUM - 1], llmax, cntarr[PARTNUM - 1], - (float)(cntarr[PARTNUM - 1] / (float)iter)); - printf(" min=%lld, max=%lld\n", lltmin, lltmax); - - } else { - /* - * random_range() unit test - */ - itmin = imax; - part = imax / PARTNUM; - for (ind = 0; ind < PARTNUM; ind++) { - valbound[ind] = part * ind; - } - - for (cnt = 0; cnt < iter; cnt++) { - lret = random_range(imin, imax, imult, NULL); - if (iter < 100) - printf("%ld\n", lret); - if (lret < itmin) - itmin = lret; - if (lret > itmax) - itmax = lret; - - for (ind = 0; ind < PARTNUM - 1; ind++) { - if (valbound[ind] < lret - && lret <= valbound[ind + 1]) { - cntarr[ind]++; - break; - } - } - if (lret > valbound[PARTNUM - 1]) { - cntarr[PARTNUM - 1]++; - } - } - for (ind = 0; ind < PARTNUM - 1; ind++) { - printf("%2d %-13ld to %-13ld %5ld %4.4f\n", ind + 1, - valbound[ind], valbound[ind + 1], cntarr[ind], - (float)(cntarr[ind] / (float)iter)); - } - printf("%2d %-13ld to %-13ld %5ld %4.4f\n", PARTNUM, - valbound[PARTNUM - 1], (long)imax, cntarr[PARTNUM - 1], - (float)(cntarr[PARTNUM - 1] / (float)iter)); - printf(" min=%d, max=%d\n", itmin, itmax); - - } - - exit(0); -} - -#endif diff --git a/kernel/tests/lib/safe_file_ops.c b/kernel/tests/lib/safe_file_ops.c deleted file mode 100644 index e06d399..0000000 --- a/kernel/tests/lib/safe_file_ops.c +++ /dev/null @@ -1,422 +0,0 @@ -/* - * Copyright (C) 2012 Cyril Hrubis chrubis@suse.cz - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it would be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * Further, this software is distributed without any warranty that it is - * free of the rightful claim of any third person regarding infringement - * or the like. Any license provided herein, whether implied or - * otherwise, applies only to this software file. Patent licenses, if - * any, provided herein do not apply to combinations of this program with - * other software, or any other product whatsoever. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include "config.h" -#include <stdarg.h> -#include <stdio.h> -#include <sys/time.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <unistd.h> -#include <utime.h> - -#include "test.h" -#include "safe_file_ops_fn.h" - -/* - * Count number of expected assigned conversions. Any conversion starts with '%'. - * The '%%' matches % and no assignment is done. The %*x matches as x would do but - * the assignment is suppressed. - * - * NOTE: This is not 100% correct for complex scanf strings, but will do for - * all of our intended usage. - */ -static int count_scanf_conversions(const char *fmt) -{ - unsigned int cnt = 0; - int flag = 0; - - while (*fmt) { - switch (*fmt) { - case '%': - if (flag) { - cnt--; - flag = 0; - } else { - flag = 1; - cnt++; - } - break; - case '*': - if (flag) { - cnt--; - flag = 0; - } - break; - default: - flag = 0; - } - - fmt++; - } - - return cnt; -} - -int file_scanf(const char *file, const int lineno, - const char *path, const char *fmt, ...) -{ - va_list va; - FILE *f; - int exp_convs, ret; - - f = fopen(path, "r"); - - if (f == NULL) { - tst_resm(TWARN, - "Failed to open FILE '%s' at %s:%d", - path, file, lineno); - return 1; - } - - exp_convs = count_scanf_conversions(fmt); - - va_start(va, fmt); - ret = vfscanf(f, fmt, va); - va_end(va); - - if (ret == EOF) { - tst_resm(TWARN, - "The FILE '%s' ended prematurely at %s:%d", - path, file, lineno); - goto err; - } - - if (ret != exp_convs) { - tst_resm(TWARN, - "Expected %i conversions got %i FILE '%s' at %s:%d", - exp_convs, ret, path, file, lineno); - goto err; - } - - if (fclose(f)) { - tst_resm(TWARN, - "Failed to close FILE '%s' at %s:%d", - path, file, lineno); - return 1; - } - - return 0; - -err: - if (fclose(f)) { - tst_resm(TWARN, - "Failed to close FILE '%s' at %s:%d", - path, file, lineno); - } - return 1; -} - -void safe_file_scanf(const char *file, const int lineno, - void (*cleanup_fn) (void), - const char *path, const char *fmt, ...) -{ - va_list va; - FILE *f; - int exp_convs, ret; - - f = fopen(path, "r"); - - if (f == NULL) { - tst_brkm(TBROK | TERRNO, cleanup_fn, - "Failed to open FILE '%s' for reading at %s:%d", - path, file, lineno); - return; - } - - exp_convs = count_scanf_conversions(fmt); - - va_start(va, fmt); - ret = vfscanf(f, fmt, va); - va_end(va); - - if (ret == EOF) { - tst_brkm(TBROK, cleanup_fn, - "The FILE '%s' ended prematurely at %s:%d", - path, file, lineno); - return; - } - - if (ret != exp_convs) { - tst_brkm(TBROK, cleanup_fn, - "Expected %i conversions got %i FILE '%s' at %s:%d", - exp_convs, ret, path, file, lineno); - return; - } - - if (fclose(f)) { - tst_brkm(TBROK | TERRNO, cleanup_fn, - "Failed to close FILE '%s' at %s:%d", - path, file, lineno); - return; - } -} - - -/* - * Try to parse each line from file specified by 'path' according - * to scanf format 'fmt'. If all fields could be parsed, stop and - * return 0, otherwise continue or return 1 if EOF is reached. - */ -int file_lines_scanf(const char *file, const int lineno, - void (*cleanup_fn)(void), int strict, - const char *path, const char *fmt, ...) -{ - FILE *fp; - int ret = 0; - int arg_count = 0; - char line[BUFSIZ]; - va_list ap; - - if (!fmt) { - tst_brkm(TBROK, cleanup_fn, "pattern is NULL, %s:%d", - file, lineno); - return 1; - } - - fp = fopen(path, "r"); - if (fp == NULL) { - tst_brkm(TBROK | TERRNO, cleanup_fn, - "Failed to open FILE '%s' for reading at %s:%d", - path, file, lineno); - return 1; - } - - arg_count = count_scanf_conversions(fmt); - - while (fgets(line, BUFSIZ, fp) != NULL) { - va_start(ap, fmt); - ret = vsscanf(line, fmt, ap); - va_end(ap); - - if (ret == arg_count) - break; - } - fclose(fp); - - if (strict && ret != arg_count) { - tst_brkm(TBROK, cleanup_fn, "Expected %i conversions got %i" - " FILE '%s' at %s:%d", arg_count, ret, path, file, lineno); - return 1; - } - - return !(ret == arg_count); -} - -int file_printf(const char *file, const int lineno, - const char *path, const char *fmt, ...) -{ - va_list va; - FILE *f; - - f = fopen(path, "w"); - - if (f == NULL) { - tst_resm(TWARN, - "Failed to open FILE '%s' at %s:%d", - path, file, lineno); - return 1; - } - - va_start(va, fmt); - - if (vfprintf(f, fmt, va) < 0) { - tst_resm(TWARN, - "Failed to print to FILE '%s' at %s:%d", - path, file, lineno); - goto err; - } - - va_end(va); - - if (fclose(f)) { - tst_resm(TWARN, - "Failed to close FILE '%s' at %s:%d", - path, file, lineno); - return 1; - } - - return 0; - -err: - if (fclose(f)) { - tst_resm(TWARN, - "Failed to close FILE '%s' at %s:%d", - path, file, lineno); - } - return 1; -} - -void safe_file_printf(const char *file, const int lineno, - void (*cleanup_fn) (void), - const char *path, const char *fmt, ...) -{ - va_list va; - FILE *f; - - f = fopen(path, "w"); - - if (f == NULL) { - tst_brkm(TBROK | TERRNO, cleanup_fn, - "Failed to open FILE '%s' for writing at %s:%d", - path, file, lineno); - return; - } - - va_start(va, fmt); - - if (vfprintf(f, fmt, va) < 0) { - tst_brkm(TBROK, cleanup_fn, - "Failed to print to FILE '%s' at %s:%d", - path, file, lineno); - return; - } - - va_end(va); - - if (fclose(f)) { - tst_brkm(TBROK | TERRNO, cleanup_fn, - "Failed to close FILE '%s' at %s:%d", - path, file, lineno); - return; - } -} - -//TODO: C implementation? better error condition reporting? -void safe_cp(const char *file, const int lineno, - void (*cleanup_fn) (void), const char *src, const char *dst) -{ - size_t len = strlen(src) + strlen(dst) + 16; - char buf[len]; - int ret; - - snprintf(buf, sizeof(buf), "cp \"%s\" \"%s\"", src, dst); - - ret = system(buf); - - if (ret) { - tst_brkm(TBROK, cleanup_fn, - "Failed to copy '%s' to '%s' at %s:%d", - src, dst, file, lineno); - } -} - -#ifndef HAVE_UTIMENSAT - -static void set_time(struct timeval *res, const struct timespec *src, - long cur_tv_sec, long cur_tv_usec) -{ - switch (src->tv_nsec) { - case UTIME_NOW: - break; - case UTIME_OMIT: - res->tv_sec = cur_tv_sec; - res->tv_usec = cur_tv_usec; - break; - default: - res->tv_sec = src->tv_sec; - res->tv_usec = src->tv_nsec / 1000; - } -} - -#endif - -void safe_touch(const char *file, const int lineno, - void (*cleanup_fn)(void), - const char *pathname, - mode_t mode, const struct timespec times[2]) -{ - int ret; - mode_t defmode; - - defmode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; - - ret = open(pathname, O_CREAT | O_WRONLY, defmode); - if (ret == -1) { - tst_brkm(TBROK | TERRNO, cleanup_fn, - "Failed to open file '%s' at %s:%d", - pathname, file, lineno); - return; - } - - ret = close(ret); - if (ret == -1) { - tst_brkm(TBROK | TERRNO, cleanup_fn, - "Failed to close file '%s' at %s:%d", - pathname, file, lineno); - return; - } - - if (mode != 0) { - ret = chmod(pathname, mode); - if (ret == -1) { - tst_brkm(TBROK | TERRNO, cleanup_fn, - "Failed to chmod file '%s' at %s:%d", - pathname, file, lineno); - return; - } - } - - -#ifdef HAVE_UTIMENSAT - ret = utimensat(AT_FDCWD, pathname, times, 0); -#else - if (times == NULL) { - ret = utimes(pathname, NULL); - } else { - struct stat sb; - struct timeval cotimes[2]; - - ret = stat(pathname, &sb); - if (ret == -1) { - tst_brkm(TBROK | TERRNO, cleanup_fn, - "Failed to stat file '%s' at %s:%d", - pathname, file, lineno); - return; - } - - ret = gettimeofday(cotimes, NULL); - if (ret == -1) { - tst_brkm(TBROK | TERRNO, cleanup_fn, - "Failed to gettimeofday() at %s:%d", - file, lineno); - return; - } - - cotimes[1] = cotimes[0]; - - set_time(cotimes, times, - sb.st_atime, sb.st_atim.tv_nsec / 1000); - set_time(cotimes + 1, times + 1, - sb.st_mtime, sb.st_mtim.tv_nsec / 1000); - - ret = utimes(pathname, cotimes); - } -#endif - if (ret == -1) { - tst_brkm(TBROK | TERRNO, cleanup_fn, - "Failed to update the access/modification time on file" - " '%s' at %s:%d", pathname, file, lineno); - } -} diff --git a/kernel/tests/lib/safe_macros.c b/kernel/tests/lib/safe_macros.c deleted file mode 100644 index 4f48d75..0000000 --- a/kernel/tests/lib/safe_macros.c +++ /dev/null @@ -1,1109 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (c) Linux Test Project, 2010-2020 - */ - -#define _GNU_SOURCE -#include <sys/types.h> -#include <sys/mman.h> -#include <sys/resource.h> -#include <sys/stat.h> -#include <sys/wait.h> -#include <sys/mount.h> -#include <sys/xattr.h> -#include <sys/sysinfo.h> -#include <errno.h> -#include <fcntl.h> -#include <libgen.h> -#include <limits.h> -#include <pwd.h> -#include <stdarg.h> -#include <stdlib.h> -#include <unistd.h> -#include <malloc.h> -#include "test.h" -#include "safe_macros.h" - -char *safe_basename(const char *file, const int lineno, - void (*cleanup_fn) (void), char *path) -{ - char *rval; - - rval = basename(path); - if (rval == NULL) { - tst_brkm(TBROK | TERRNO, cleanup_fn, - "%s:%d: basename(%s) failed", - file, lineno, path); - } - - return rval; -} - -int -safe_chdir(const char *file, const int lineno, void (*cleanup_fn) (void), - const char *path) -{ - int rval; - - rval = chdir(path); - if (rval == -1) { - tst_brkm(TBROK | TERRNO, cleanup_fn, - "%s:%d: chdir(%s) failed", - file, lineno, path); - } - - return rval; -} - -int -safe_close(const char *file, const int lineno, void (*cleanup_fn) (void), - int fildes) -{ - int rval; - - rval = close(fildes); - if (rval == -1) { - tst_brkm(TBROK | TERRNO, cleanup_fn, - "%s:%d: close(%d) failed", - file, lineno, fildes); - } - - return rval; -} - -int -safe_creat(const char *file, const int lineno, void (*cleanup_fn) (void), - const char *pathname, mode_t mode) -{ - int rval; - - rval = creat(pathname, mode); - if (rval == -1) { - tst_brkm(TBROK | TERRNO, cleanup_fn, - "%s:%d: creat(%s,0%o) failed", - file, lineno, pathname, mode); - } - - return rval; -} - -char *safe_dirname(const char *file, const int lineno, - void (*cleanup_fn) (void), char *path) -{ - char *rval; - - rval = dirname(path); - if (rval == NULL) { - tst_brkm(TBROK | TERRNO, cleanup_fn, - "%s:%d: dirname(%s) failed", - file, lineno, path); - } - - return rval; -} - -char *safe_getcwd(const char *file, const int lineno, void (*cleanup_fn) (void), - char *buf, size_t size) -{ - char *rval; - - rval = getcwd(buf, size); - if (rval == NULL) { - tst_brkm(TBROK | TERRNO, cleanup_fn, - "%s:%d: getcwd(%p,%zu) failed", - file, lineno, buf, size); - } - - return rval; -} - -struct passwd *safe_getpwnam(const char *file, const int lineno, - void (*cleanup_fn) (void), const char *name) -{ - struct passwd *rval; - - rval = getpwnam(name); - if (rval == NULL) { - tst_brkm(TBROK | TERRNO, cleanup_fn, - "%s:%d: getpwnam(%s) failed", - file, lineno, name); - } - - return rval; -} - -int -safe_getrusage(const char *file, const int lineno, void (*cleanup_fn) (void), - int who, struct rusage *usage) -{ - int rval; - - rval = getrusage(who, usage); - if (rval == -1) { - tst_brkm(TBROK | TERRNO, cleanup_fn, - "%s:%d: getrusage(%d,%p) failed", - file, lineno, who, usage); - } - - return rval; -} - -void *safe_malloc(const char *file, const int lineno, void (*cleanup_fn) (void), - size_t size) -{ - void *rval; - - rval = malloc(size); - if (rval == NULL) { - tst_brkm(TBROK | TERRNO, cleanup_fn, - "%s:%d: malloc(%zu) failed", - file, lineno, size); - } - - return rval; -} - -int safe_mkdir(const char *file, const int lineno, void (*cleanup_fn) (void), - const char *pathname, mode_t mode) -{ - int rval; - - rval = mkdir(pathname, mode); - if (rval == -1) { - tst_brkm(TBROK | TERRNO, cleanup_fn, - "%s:%d: mkdir(%s,0%o) failed", - file, lineno, pathname, mode); - } - - return (rval); -} - -int safe_rmdir(const char *file, const int lineno, void (*cleanup_fn) (void), - const char *pathname) -{ - int rval; - - rval = rmdir(pathname); - if (rval == -1) { - tst_brkm(TBROK | TERRNO, cleanup_fn, - "%s:%d: rmdir(%s) failed", - file, lineno, pathname); - } - - return (rval); -} - -int safe_munmap(const char *file, const int lineno, void (*cleanup_fn) (void), - void *addr, size_t length) -{ - int rval; - - rval = munmap(addr, length); - if (rval == -1) { - tst_brkm(TBROK | TERRNO, cleanup_fn, - "%s:%d: munmap(%p,%zu) failed", - file, lineno, addr, length); - } - - return rval; -} - -int safe_open(const char *file, const int lineno, void (*cleanup_fn) (void), - const char *pathname, int oflags, ...) -{ - va_list ap; - int rval; - mode_t mode; - - va_start(ap, oflags); - - /* Android's NDK's mode_t is smaller than an int, which results in - * SIGILL here when passing the mode_t type. - */ - mode = va_arg(ap, int); - - va_end(ap); - - rval = open(pathname, oflags, mode); - if (rval == -1) { - tst_brkm(TBROK | TERRNO, cleanup_fn, - "%s:%d: open(%s,%d,0%o) failed", - file, lineno, pathname, oflags, mode); - } - - return rval; -} - -int safe_pipe(const char *file, const int lineno, void (*cleanup_fn) (void), - int fildes[2]) -{ - int rval; - - rval = pipe(fildes); - if (rval == -1) { - tst_brkm(TBROK | TERRNO, cleanup_fn, - "%s:%d: pipe({%d,%d}) failed", - file, lineno, fildes[0], fildes[1]); - } - - return rval; -} - -ssize_t safe_read(const char *file, const int lineno, void (*cleanup_fn) (void), - char len_strict, int fildes, void *buf, size_t nbyte) -{ - ssize_t rval; - - rval = read(fildes, buf, nbyte); - if (rval == -1 || (len_strict && (size_t)rval != nbyte)) { - tst_brkm(TBROK | TERRNO, cleanup_fn, - "%s:%d: read(%d,%p,%zu) failed, returned %zd", - file, lineno, fildes, buf, nbyte, rval); - } - - return rval; -} - -int safe_setegid(const char *file, const int lineno, void (*cleanup_fn) (void), - gid_t egid) -{ - int rval; - - rval = setegid(egid); - if (rval == -1) { - tst_brkm(TBROK | TERRNO, cleanup_fn, - "%s:%d: setegid(%u) failed", - file, lineno, (unsigned) egid); - } - - return rval; -} - -int safe_seteuid(const char *file, const int lineno, void (*cleanup_fn) (void), - uid_t euid) -{ - int rval; - - rval = seteuid(euid); - if (rval == -1) { - tst_brkm(TBROK | TERRNO, cleanup_fn, - "%s:%d: seteuid(%u) failed", - file, lineno, (unsigned) euid); - } - - return rval; -} - -int safe_setgid(const char *file, const int lineno, void (*cleanup_fn) (void), - gid_t gid) -{ - int rval; - - rval = setgid(gid); - if (rval == -1) { - tst_brkm(TBROK | TERRNO, cleanup_fn, - "%s:%d: setgid(%u) failed", - file, lineno, (unsigned) gid); - } - - return rval; -} - -int safe_setuid(const char *file, const int lineno, void (*cleanup_fn) (void), - uid_t uid) -{ - int rval; - - rval = setuid(uid); - if (rval == -1) { - tst_brkm(TBROK | TERRNO, cleanup_fn, - "%s:%d: setuid(%u) failed", - file, lineno, (unsigned) uid); - } - - return rval; -} - -int safe_getresuid(const char *file, const int lineno, void (*cleanup_fn)(void), - uid_t *ruid, uid_t *euid, uid_t *suid) -{ - int rval; - - rval = getresuid(ruid, euid, suid); - if (rval == -1) { - tst_brkm(TBROK | TERRNO, cleanup_fn, - "%s:%d: getresuid(%p, %p, %p) failed", - file, lineno, ruid, euid, suid); - } - - return rval; -} - -int safe_getresgid(const char *file, const int lineno, void (*cleanup_fn)(void), - gid_t *rgid, gid_t *egid, gid_t *sgid) -{ - int rval; - - rval = getresgid(rgid, egid, sgid); - if (rval == -1) { - tst_brkm(TBROK | TERRNO, cleanup_fn, - "%s:%d: getresgid(%p, %p, %p) failed", - file, lineno, rgid, egid, sgid); - } - - return rval; -} - -int safe_unlink(const char *file, const int lineno, void (*cleanup_fn) (void), - const char *pathname) -{ - int rval; - - rval = unlink(pathname); - if (rval == -1) { - tst_brkm(TBROK | TERRNO, cleanup_fn, - "%s:%d: unlink(%s) failed", - file, lineno, pathname); - } - - return rval; -} - - -int safe_link(const char *file, const int lineno, - void (cleanup_fn)(void), const char *oldpath, - const char *newpath) -{ - int rval; - - rval = link(oldpath, newpath); - - if (rval == -1) { - tst_brkm(TBROK | TERRNO, cleanup_fn, - "%s:%d: link(%s,%s) failed", - file, lineno, oldpath, newpath); - } - - return rval; -} - -int safe_linkat(const char *file, const int lineno, - void (cleanup_fn)(void), int olddirfd, const char *oldpath, - int newdirfd, const char *newpath, int flags) -{ - int rval; - - rval = linkat(olddirfd, oldpath, newdirfd, newpath, flags); - - if (rval == -1) { - tst_brkm(TBROK | TERRNO, cleanup_fn, - "%s:%d: linkat(%d,%s,%d,%s,%d) failed", - file, lineno, olddirfd, oldpath, newdirfd, - newpath, flags); - } - - return rval; -} - -ssize_t safe_readlink(const char *file, const int lineno, - void (cleanup_fn)(void), const char *path, - char *buf, size_t bufsize) -{ - ssize_t rval; - - rval = readlink(path, buf, bufsize); - - if (rval == -1) { - tst_brkm(TBROK | TERRNO, cleanup_fn, - "%s:%d: readlink(%s,%p,%zu) failed", - file, lineno, path, buf, bufsize); - } else { - /* readlink does not append a NUL byte to the buffer. - * Add it now. */ - if ((size_t) rval < bufsize) - buf[rval] = '\0'; - else - buf[bufsize-1] = '\0'; - } - - return rval; -} - -int safe_symlink(const char *file, const int lineno, - void (cleanup_fn)(void), const char *oldpath, - const char *newpath) -{ - int rval; - - rval = symlink(oldpath, newpath); - - if (rval == -1) { - tst_brkm(TBROK | TERRNO, cleanup_fn, - "%s:%d: symlink(%s,%s) failed", - file, lineno, oldpath, newpath); - } - - return rval; -} - -ssize_t safe_write(const char *file, const int lineno, void (cleanup_fn) (void), - char len_strict, int fildes, const void *buf, size_t nbyte) -{ - ssize_t rval; - - rval = write(fildes, buf, nbyte); - if (rval == -1 || (len_strict && (size_t)rval != nbyte)) { - tst_brkm(TBROK | TERRNO, cleanup_fn, - "%s:%d: write(%d,%p,%zu) failed", - file, lineno, fildes, buf, rval); - } - - return rval; -} - -long safe_strtol(const char *file, const int lineno, - void (cleanup_fn) (void), char *str, long min, long max) -{ - long rval; - char *endptr; - - errno = 0; - rval = strtol(str, &endptr, 10); - - if ((errno == ERANGE && (rval == LONG_MAX || rval == LONG_MIN)) - || (errno != 0 && rval == 0)) { - tst_brkm(TBROK | TERRNO, cleanup_fn, - "%s:%d: strtol(%s) failed", file, lineno, str); - return rval; - } - - if (endptr == str || (*endptr != '\0' && *endptr != '\n')) { - tst_brkm(TBROK, cleanup_fn, - "%s:%d: strtol(%s): Invalid value", file, lineno, str); - return 0; - } - - if (rval > max || rval < min) { - tst_brkm(TBROK, cleanup_fn, - "%s:%d: strtol(%s): %ld is out of range %ld - %ld", - file, lineno, str, rval, min, max); - return 0; - } - - return rval; -} - -unsigned long safe_strtoul(const char *file, const int lineno, - void (cleanup_fn) (void), char *str, - unsigned long min, unsigned long max) -{ - unsigned long rval; - char *endptr; - - errno = 0; - rval = strtoul(str, &endptr, 10); - - if ((errno == ERANGE && rval == ULONG_MAX) - || (errno != 0 && rval == 0)) { - tst_brkm(TBROK | TERRNO, cleanup_fn, - "%s:%d: strtoul(%s) failed", file, lineno, str); - return rval; - } - - if (rval > max || rval < min) { - tst_brkm(TBROK, cleanup_fn, - "%s:%d: strtoul(%s): %lu is out of range %lu - %lu", - file, lineno, str, rval, min, max); - return 0; - } - - if (endptr == str || (*endptr != '\0' && *endptr != '\n')) { - tst_brkm(TBROK, cleanup_fn, - "Invalid value: '%s' at %s:%d", str, file, lineno); - return 0; - } - - return rval; -} - -long safe_sysconf(const char *file, const int lineno, - void (cleanup_fn) (void), int name) -{ - long rval; - errno = 0; - - rval = sysconf(name); - - if (rval == -1) { - if (errno) { - tst_brkm(TBROK | TERRNO, cleanup_fn, - "%s:%d: sysconf(%d) failed", - file, lineno, name); - } else { - tst_resm(TINFO, "%s:%d: sysconf(%d): " - "queried option is not available" - " or there is no definite limit", - file, lineno, name); - } - } - - return rval; -} - -int safe_chmod(const char *file, const int lineno, - void (cleanup_fn)(void), const char *path, mode_t mode) -{ - int rval; - - rval = chmod(path, mode); - - if (rval == -1) { - tst_brkm(TBROK | TERRNO, cleanup_fn, - "%s:%d: chmod(%s,0%o) failed", - file, lineno, path, mode); - } - - return rval; -} - -int safe_fchmod(const char *file, const int lineno, - void (cleanup_fn)(void), int fd, mode_t mode) -{ - int rval; - - rval = fchmod(fd, mode); - - if (rval == -1) { - tst_brkm(TBROK | TERRNO, cleanup_fn, - "%s:%d: fchmod(%d,0%o) failed", - file, lineno, fd, mode); - } - - return rval; -} - -int safe_chown(const char *file, const int lineno, void (cleanup_fn)(void), - const char *path, uid_t owner, gid_t group) -{ - int rval; - - rval = chown(path, owner, group); - - if (rval == -1) { - tst_brkm(TBROK | TERRNO, cleanup_fn, - "%s:%d: chown(%s,%d,%d) failed", - file, lineno, path, owner, group); - } - - return rval; -} - -int safe_fchown(const char *file, const int lineno, void (cleanup_fn)(void), - int fd, uid_t owner, gid_t group) -{ - int rval; - - rval = fchown(fd, owner, group); - - if (rval == -1) { - tst_brkm(TBROK | TERRNO, cleanup_fn, - "%s:%d: fchown(%d,%d,%d) failed", - file, lineno, fd, owner, group); - } - - return rval; -} - -pid_t safe_wait(const char *file, const int lineno, void (cleanup_fn)(void), - int *status) -{ - pid_t rval; - - rval = wait(status); - if (rval == -1) { - tst_brkm(TBROK | TERRNO, cleanup_fn, - "%s:%d: wait(%p) failed", - file, lineno, status); - } - - return rval; -} - -pid_t safe_waitpid(const char *file, const int lineno, void (cleanup_fn)(void), - pid_t pid, int *status, int opts) -{ - pid_t rval; - - rval = waitpid(pid, status, opts); - if (rval == -1) { - tst_brkm(TBROK | TERRNO, cleanup_fn, - "%s:%d: waitpid(%d,%p,%d) failed", - file, lineno, pid, status, opts); - } - - return rval; -} - -void *safe_memalign(const char *file, const int lineno, - void (*cleanup_fn) (void), size_t alignment, size_t size) -{ - void *rval; - - rval = memalign(alignment, size); - if (rval == NULL) - tst_brkm(TBROK | TERRNO, cleanup_fn, "memalign failed at %s:%d", - file, lineno); - - return rval; -} - -int safe_kill(const char *file, const int lineno, void (cleanup_fn)(void), - pid_t pid, int sig) -{ - int rval; - - rval = kill(pid, sig); - - if (rval == -1) { - tst_brkm(TBROK | TERRNO, cleanup_fn, - "%s:%d: kill(%d,%s) failed", - file, lineno, pid, tst_strsig(sig)); - } - - return rval; -} - -int safe_mkfifo(const char *file, const int lineno, - void (*cleanup_fn)(void), const char *pathname, mode_t mode) -{ - int rval; - - rval = mkfifo(pathname, mode); - - if (rval == -1) { - tst_brkm(TBROK | TERRNO, cleanup_fn, - "%s:%d: mkfifo(%s, 0%o) failed", - file, lineno, pathname, mode); - } - - return rval; -} - -int safe_rename(const char *file, const int lineno, void (*cleanup_fn)(void), - const char *oldpath, const char *newpath) -{ - int rval; - - rval = rename(oldpath, newpath); - - if (rval == -1) { - tst_brkm(TBROK | TERRNO, cleanup_fn, - "%s:%d: rename(%s, %s) failed", - file, lineno, oldpath, newpath); - } - - return rval; -} - -static const char *const fuse_fs_types[] = { - "exfat", - "ntfs", -}; - -static int possibly_fuse(const char *fs_type) -{ - unsigned int i; - - if (!fs_type) - return 0; - - for (i = 0; i < ARRAY_SIZE(fuse_fs_types); i++) { - if (!strcmp(fuse_fs_types[i], fs_type)) - return 1; - } - - return 0; -} - -int safe_mount(const char *file, const int lineno, void (*cleanup_fn)(void), - const char *source, const char *target, - const char *filesystemtype, unsigned long mountflags, - const void *data) -{ - int rval; - - /* - * Don't try using the kernel's NTFS driver when mounting NTFS, since - * the kernel's NTFS driver doesn't have proper write support. - */ - if (!filesystemtype || strcmp(filesystemtype, "ntfs")) { - rval = mount(source, target, filesystemtype, mountflags, data); - if (!rval) - return 0; - } - - /* - * The FUSE filesystem executes mount.fuse helper, which tries to - * execute corresponding binary name which is encoded at the start of - * the source string and separated by # from the device name. - * - * The mount helpers are called mount.$fs_type. - */ - if (possibly_fuse(filesystemtype)) { - char buf[1024]; - - tst_resm(TINFO, "Trying FUSE..."); - snprintf(buf, sizeof(buf), "mount.%s '%s' '%s'", - filesystemtype, source, target); - - rval = tst_system(buf); - if (WIFEXITED(rval) && WEXITSTATUS(rval) == 0) - return 0; - - tst_brkm(TBROK, cleanup_fn, "mount.%s failed with %i", - filesystemtype, rval); - return -1; - } else { - tst_brkm(TBROK | TERRNO, cleanup_fn, - "%s:%d: mount(%s, %s, %s, %lu, %p) failed", - file, lineno, source, target, filesystemtype, - mountflags, data); - } - - return -1; -} - -int safe_umount(const char *file, const int lineno, void (*cleanup_fn)(void), - const char *target) -{ - int rval; - - rval = tst_umount(target); - - if (rval == -1) { - tst_brkm(TBROK | TERRNO, cleanup_fn, - "%s:%d: umount(%s) failed", - file, lineno, target); - } - - return rval; -} - -DIR* safe_opendir(const char *file, const int lineno, void (cleanup_fn)(void), - const char *name) -{ - DIR *rval; - - rval = opendir(name); - - if (!rval) { - tst_brkm(TBROK | TERRNO, cleanup_fn, - "%s:%d: opendir(%s) failed", file, lineno, name); - } - - return rval; -} - -int safe_closedir(const char *file, const int lineno, void (cleanup_fn)(void), - DIR *dirp) -{ - int rval; - - rval = closedir(dirp); - - if (rval) { - tst_brkm(TBROK | TERRNO, cleanup_fn, - "%s:%d: closedir(%p) failed", file, lineno, dirp); - } - - return rval; -} - -struct dirent *safe_readdir(const char *file, const int lineno, void (cleanup_fn)(void), - DIR *dirp) -{ - struct dirent *rval; - int err = errno; - - errno = 0; - rval = readdir(dirp); - - if (!rval && errno) { - tst_brkm(TBROK | TERRNO, cleanup_fn, - "%s:%d: readdir(%p) failed", file, lineno, dirp); - } - - errno = err; - return rval; -} - -int safe_getpriority(const char *file, const int lineno, int which, id_t who) -{ - int rval, err = errno; - - errno = 0; - rval = getpriority(which, who); - if (errno) { - tst_brkm(TBROK | TERRNO, NULL, - "%s:%d getpriority(%i, %i) failed", - file, lineno, which, who); - } - - errno = err; - return rval; -} - -ssize_t safe_getxattr(const char *file, const int lineno, const char *path, - const char *name, void *value, size_t size) -{ - ssize_t rval; - - rval = getxattr(path, name, value, size); - - if (rval == -1) { - if (errno == ENOTSUP) { - tst_brkm(TCONF, NULL, - "%s:%d: no xattr support in fs or mounted " - "without user_xattr option", file, lineno); - } - - tst_brkm(TBROK | TERRNO, NULL, - "%s:%d: getxattr(%s, %s, %p, %zu) failed", - file, lineno, path, name, value, size); - } - - return rval; -} - -int safe_setxattr(const char *file, const int lineno, const char *path, - const char *name, const void *value, size_t size, int flags) -{ - int rval; - - rval = setxattr(path, name, value, size, flags); - - if (rval) { - if (errno == ENOTSUP) { - tst_brkm(TCONF, NULL, - "%s:%d: no xattr support in fs or mounted " - "without user_xattr option", file, lineno); - } - - tst_brkm(TBROK | TERRNO, NULL, - "%s:%d: setxattr(%s, %s, %p, %zu) failed", - file, lineno, path, name, value, size); - } - - return rval; -} - -int safe_lsetxattr(const char *file, const int lineno, const char *path, - const char *name, const void *value, size_t size, int flags) -{ - int rval; - - rval = lsetxattr(path, name, value, size, flags); - - if (rval) { - if (errno == ENOTSUP) { - tst_brkm(TCONF, NULL, - "%s:%d: no xattr support in fs or mounted " - "without user_xattr option", file, lineno); - } - - tst_brkm(TBROK | TERRNO, NULL, - "%s:%d: lsetxattr(%s, %s, %p, %zu, %i) failed", - file, lineno, path, name, value, size, flags); - } - - return rval; -} - -int safe_fsetxattr(const char *file, const int lineno, int fd, const char *name, - const void *value, size_t size, int flags) -{ - int rval; - - rval = fsetxattr(fd, name, value, size, flags); - - if (rval) { - if (errno == ENOTSUP) { - tst_brkm(TCONF, NULL, - "%s:%d: no xattr support in fs or mounted " - "without user_xattr option", file, lineno); - } - - tst_brkm(TBROK | TERRNO, NULL, - "%s:%d: fsetxattr(%i, %s, %p, %zu, %i) failed", - file, lineno, fd, name, value, size, flags); - } - - return rval; -} - -int safe_removexattr(const char *file, const int lineno, const char *path, - const char *name) -{ - int rval; - - rval = removexattr(path, name); - - if (rval) { - if (errno == ENOTSUP) { - tst_brkm(TCONF, NULL, - "%s:%d: no xattr support in fs or mounted " - "without user_xattr option", file, lineno); - } - - tst_brkm(TBROK | TERRNO, NULL, - "%s:%d: removexattr(%s, %s) failed", - file, lineno, path, name); - } - - return rval; -} - -int safe_lremovexattr(const char *file, const int lineno, const char *path, - const char *name) -{ - int rval; - - rval = lremovexattr(path, name); - - if (rval) { - if (errno == ENOTSUP) { - tst_brkm(TCONF, NULL, - "%s:%d: no xattr support in fs or mounted " - "without user_xattr option", file, lineno); - } - - tst_brkm(TBROK | TERRNO, NULL, - "%s:%d: lremovexattr(%s, %s) failed", - file, lineno, path, name); - } - - return rval; -} - -int safe_fremovexattr(const char *file, const int lineno, int fd, - const char *name) -{ - int rval; - - rval = fremovexattr(fd, name); - - if (rval) { - if (errno == ENOTSUP) { - tst_brkm(TCONF, NULL, - "%s:%d: no xattr support in fs or mounted " - "without user_xattr option", file, lineno); - } - - tst_brkm(TBROK | TERRNO, NULL, - "%s:%d: fremovexattr(%i, %s) failed", - file, lineno, fd, name); - } - - return rval; -} - -int safe_fsync(const char *file, const int lineno, int fd) -{ - int rval; - - rval = fsync(fd); - - if (rval) { - tst_brkm(TBROK | TERRNO, NULL, - "%s:%d: fsync(%i) failed", file, lineno, fd); - } - - return rval; -} - -pid_t safe_setsid(const char *file, const int lineno) -{ - pid_t rval; - - rval = setsid(); - if (rval == -1) { - tst_brkm(TBROK | TERRNO, NULL, - "%s:%d: setsid() failed", file, lineno); - } - - return rval; -} - -int safe_mknod(const char *file, const int lineno, const char *pathname, - mode_t mode, dev_t dev) -{ - int rval; - - rval = mknod(pathname, mode, dev); - if (rval == -1) { - tst_brkm(TBROK | TERRNO, NULL, - "%s:%d: mknod() failed", file, lineno); - } - - return rval; -} - -int safe_mlock(const char *file, const int lineno, const void *addr, - size_t len) -{ - int rval; - - rval = mlock(addr, len); - if (rval == -1) { - tst_brkm(TBROK | TERRNO, NULL, - "%s:%d: mlock() failed", file, lineno); - } - - return rval; -} - -int safe_munlock(const char *file, const int lineno, const void *addr, - size_t len) -{ - int rval; - - rval = munlock(addr, len); - if (rval == -1) { - tst_brkm(TBROK | TERRNO, NULL, - "%s:%d: munlock() failed", file, lineno); - } - - return rval; -} - -int safe_mincore(const char *file, const int lineno, void *start, - size_t length, unsigned char *vec) -{ - int rval; - - rval = mincore(start, length, vec); - if (rval == -1) { - tst_brkm(TBROK | TERRNO, NULL, - "%s:%d: mincore() failed", file, lineno); - } - - return rval; -} - -int safe_sysinfo(const char *file, const int lineno, struct sysinfo *info) -{ - int ret; - - errno = 0; - ret = sysinfo(info); - - if (ret == -1) { - tst_brkm_(file, lineno, TBROK | TERRNO, NULL, - "sysinfo() failed"); - } else if (ret) { - tst_brkm_(file, lineno, TBROK | TERRNO, NULL, - "Invalid sysinfo() return value %d", ret); - } - - return ret; -} diff --git a/kernel/tests/lib/safe_net.c b/kernel/tests/lib/safe_net.c deleted file mode 100644 index 4993680..0000000 --- a/kernel/tests/lib/safe_net.c +++ /dev/null @@ -1,459 +0,0 @@ -/* - * Copyright (c) 2015 Fujitsu Ltd. - * - * 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 3 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, see <http://www.gnu.org/licenses/>. - * - */ - -#include <errno.h> -#include "test.h" -#include "safe_net_fn.h" - -char *tst_sock_addr(const struct sockaddr *sa, socklen_t salen, char *res, - size_t len) -{ - char portstr[8]; - - switch (sa->sa_family) { - - case AF_INET: { - struct sockaddr_in *sin = (struct sockaddr_in *)sa; - - if (!inet_ntop(AF_INET, &sin->sin_addr, res, len)) - return NULL; - - if (ntohs(sin->sin_port) != 0) { - snprintf(portstr, sizeof(portstr), ":%d", - ntohs(sin->sin_port)); - strcat(res, portstr); - } - - return res; - } - - case AF_INET6: { - struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa; - - res[0] = '['; - if (!inet_ntop(AF_INET6, &sin6->sin6_addr, res + 1, len - 1)) - return NULL; - - if (ntohs(sin6->sin6_port) != 0) { - snprintf(portstr, sizeof(portstr), "]:%d", - ntohs(sin6->sin6_port)); - strcat(res, portstr); - return res; - } - - return res + 1; - } - - case AF_UNIX: { - struct sockaddr_un *unp = (struct sockaddr_un *)sa; - - if (unp->sun_path[0] == '\0') - strcpy(res, "(no pathname bound)"); - else - snprintf(res, len, "%s", unp->sun_path); - - return res; - } - - default: { - snprintf(res, len, - "sock_ntop: unknown AF_xxx: %d, len: %d", - sa->sa_family, salen); - - return res; - } - - } -} - -int tst_getsockport(const char *file, const int lineno, int sockfd) -{ - struct sockaddr_storage ss; - socklen_t addrlen = sizeof(ss); - struct sockaddr *sa = (struct sockaddr *)&ss; - - safe_getsockname(file, lineno, NULL, sockfd, sa, &addrlen); - - switch (sa->sa_family) { - case AF_INET: { - struct sockaddr_in *sin = (struct sockaddr_in *)sa; - - return ntohs(sin->sin_port); - } - case AF_INET6: { - struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa; - - return ntohs(sin6->sin6_port); - } } - - return -1; -} - -int safe_socket(const char *file, const int lineno, void (cleanup_fn)(void), - int domain, int type, int protocol) -{ - int rval, ttype; - - rval = socket(domain, type, protocol); - - if (rval < 0) { - switch (errno) { - case EPROTONOSUPPORT: - case ESOCKTNOSUPPORT: - case EOPNOTSUPP: - case EPFNOSUPPORT: - case EAFNOSUPPORT: - ttype = TCONF; - break; - default: - ttype = TBROK; - } - - tst_brkm(ttype | TERRNO, cleanup_fn, - "%s:%d: socket(%d, %d, %d) failed", file, lineno, - domain, type, protocol); - } - - return rval; -} - -int safe_socketpair(const char *file, const int lineno, int domain, int type, - int protocol, int sv[]) -{ - int rval, ttype; - - rval = socketpair(domain, type, protocol, sv); - - if (rval < 0) { - switch (errno) { - case EPROTONOSUPPORT: - case EOPNOTSUPP: - case EAFNOSUPPORT: - ttype = TCONF; - break; - default: - ttype = TBROK; - } - - tst_brkm(ttype | TERRNO, NULL, - "%s:%d: socketpair(%d, %d, %d, %p) failed", - file, lineno, domain, type, protocol, sv); - } - - return rval; -} - -int safe_getsockopt(const char *file, const int lineno, int sockfd, int level, - int optname, void *optval, socklen_t *optlen) -{ - int rval = getsockopt(sockfd, level, optname, optval, optlen); - - if (!rval) - return 0; - - tst_brkm(TBROK | TERRNO, NULL, - "%s:%d: getsockopt(%d, %d, %d, %p, %p) failed", - file, lineno, sockfd, level, optname, optval, optlen); - - return rval; -} - -int safe_setsockopt(const char *file, const int lineno, int sockfd, int level, - int optname, const void *optval, socklen_t optlen) -{ - int rval; - - rval = setsockopt(sockfd, level, optname, optval, optlen); - - if (rval) { - tst_brkm(TBROK | TERRNO, NULL, - "%s:%d: setsockopt(%d, %d, %d, %p, %d) failed", - file, lineno, sockfd, level, optname, optval, optlen); - } - - return rval; -} - -ssize_t safe_send(const char *file, const int lineno, char len_strict, - int sockfd, const void *buf, size_t len, int flags) -{ - ssize_t rval; - - rval = send(sockfd, buf, len, flags); - - if (rval == -1 || (len_strict && (size_t)rval != len)) { - tst_brkm(TBROK | TERRNO, NULL, - "%s:%d: send(%d, %p, %zu, %d) failed", - file, lineno, sockfd, buf, len, flags); - } - - return rval; -} - -ssize_t safe_sendto(const char *file, const int lineno, char len_strict, - int sockfd, const void *buf, size_t len, int flags, - const struct sockaddr *dest_addr, socklen_t addrlen) -{ - ssize_t rval; - char res[128]; - - rval = sendto(sockfd, buf, len, flags, dest_addr, addrlen); - - if (rval == -1 || (len_strict && (size_t)rval != len)) { - tst_brkm(TBROK | TERRNO, NULL, - "%s:%d: sendto(%d, %p, %zu, %d, %s, %d) failed", - file, lineno, sockfd, buf, len, flags, - tst_sock_addr(dest_addr, addrlen, res, sizeof(res)), - addrlen); - } - - return rval; -} - -ssize_t safe_sendmsg(const char *file, const int lineno, size_t len, - int sockfd, const struct msghdr *msg, int flags) -{ - ssize_t rval; - - rval = sendmsg(sockfd, msg, flags); - - if (rval == -1) { - tst_brkm(TBROK | TERRNO, NULL, - "%s:%d: sendmsg(%d, %p, %d) failed", - file, lineno, sockfd, msg, flags); - } - - if (len && (size_t)rval != len) { - tst_brkm(TBROK, NULL, - "%s:%d: sendmsg(%d, %p, %d) ret(%zd) != len(%zu)", - file, lineno, sockfd, msg, flags, rval, len); - } - - return rval; -} - -ssize_t safe_recvmsg(const char *file, const int lineno, size_t len, - int sockfd, struct msghdr *msg, int flags) -{ - ssize_t rval; - - rval = recvmsg(sockfd, msg, flags); - - if (rval == -1) { - tst_brkm(TBROK | TERRNO, NULL, - "%s:%d: recvmsg(%d, %p, %d) failed", - file, lineno, sockfd, msg, flags); - } - - if (len && (size_t)rval != len) { - tst_brkm(TBROK, NULL, - "%s:%d: recvmsg(%d, %p, %d) ret(%zd) != len(%zu)", - file, lineno, sockfd, msg, flags, rval, len); - } - - return rval; - -} - -int safe_bind(const char *file, const int lineno, void (cleanup_fn)(void), - int socket, const struct sockaddr *address, - socklen_t address_len) -{ - int i; - char buf[128]; - - for (i = 0; i < 120; i++) { - if (!bind(socket, address, address_len)) - return 0; - - if (errno != EADDRINUSE) { - tst_brkm(TBROK | TERRNO, cleanup_fn, - "%s:%d: bind(%d, %s, %d) failed", file, lineno, - socket, tst_sock_addr(address, address_len, - buf, sizeof(buf)), - address_len); - return -1; - } - - if ((i + 1) % 10 == 0) { - tst_resm(TINFO, "address is in use, waited %3i sec", - i + 1); - } - - sleep(1); - } - - tst_brkm(TBROK | TERRNO, cleanup_fn, - "%s:%d: Failed to bind(%d, %s, %d) after 120 retries", file, - lineno, socket, - tst_sock_addr(address, address_len, buf, sizeof(buf)), - address_len); - return -1; -} - -int safe_listen(const char *file, const int lineno, void (cleanup_fn)(void), - int socket, int backlog) -{ - int rval; - - rval = listen(socket, backlog); - - if (rval < 0) { - tst_brkm(TBROK | TERRNO, cleanup_fn, - "%s:%d: listen(%d, %d) failed", file, lineno, socket, - backlog); - } - - return rval; -} - -int safe_accept(const char *file, const int lineno, void (cleanup_fn)(void), - int sockfd, struct sockaddr *addr, socklen_t *addrlen) -{ - int rval; - - rval = accept(sockfd, addr, addrlen); - - if (rval < 0) { - tst_brkm(TBROK | TERRNO, cleanup_fn, - "%s:%d: accept(%d, %p, %d) failed", file, lineno, - sockfd, addr, *addrlen); - } - - return rval; -} - -int safe_connect(const char *file, const int lineno, void (cleanup_fn)(void), - int sockfd, const struct sockaddr *addr, socklen_t addrlen) -{ - int rval; - char buf[128]; - - rval = connect(sockfd, addr, addrlen); - - if (rval < 0) { - tst_brkm(TBROK | TERRNO, cleanup_fn, - "%s:%d: connect(%d, %s, %d) failed", file, lineno, - sockfd, tst_sock_addr(addr, addrlen, buf, - sizeof(buf)), addrlen); - } - - return rval; -} - -int safe_getsockname(const char *file, const int lineno, - void (cleanup_fn)(void), int sockfd, struct sockaddr *addr, - socklen_t *addrlen) -{ - int rval; - char buf[128]; - - rval = getsockname(sockfd, addr, addrlen); - - if (rval < 0) { - tst_brkm(TBROK | TERRNO, cleanup_fn, - "%s:%d: getsockname(%d, %s, %d) failed", file, lineno, - sockfd, tst_sock_addr(addr, *addrlen, buf, - sizeof(buf)), *addrlen); - } - - return rval; -} - -int safe_gethostname(const char *file, const int lineno, - char *name, size_t size) -{ - int rval = gethostname(name, size); - - if (rval < 0) { - tst_brkm(TBROK | TERRNO, NULL, - "%s:%d: gethostname(%p, %zu) failed", - file, lineno, name, size); - } - - return rval; -} - -/* - * @return port in network byte order. - */ -unsigned short tst_get_unused_port(const char *file, const int lineno, - void (cleanup_fn)(void), unsigned short family, int type) -{ - int sock; - socklen_t slen; - struct sockaddr_storage _addr; - struct sockaddr *addr = (struct sockaddr *)&_addr; - struct sockaddr_in *addr4 = (struct sockaddr_in *)addr; - struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)addr; - - switch (family) { - case AF_INET: - addr4->sin_family = AF_INET; - addr4->sin_port = 0; - addr4->sin_addr.s_addr = INADDR_ANY; - slen = sizeof(*addr4); - break; - - case AF_INET6: - addr6->sin6_family = AF_INET6; - addr6->sin6_port = 0; - addr6->sin6_addr = in6addr_any; - slen = sizeof(*addr6); - break; - - default: - tst_brkm(TBROK, cleanup_fn, - "%s:%d: unknown family", file, lineno); - return -1; - } - - sock = socket(addr->sa_family, type, 0); - if (sock < 0) { - tst_brkm(TBROK | TERRNO, cleanup_fn, - "%s:%d: socket failed", file, lineno); - return -1; - } - - if (bind(sock, addr, slen) < 0) { - tst_brkm(TBROK | TERRNO, cleanup_fn, - "%s:%d: bind failed", file, lineno); - return -1; - } - - if (getsockname(sock, addr, &slen) == -1) { - tst_brkm(TBROK | TERRNO, cleanup_fn, - "%s:%d: getsockname failed", file, lineno); - return -1; - } - - if (close(sock) == -1) { - tst_brkm(TBROK | TERRNO, cleanup_fn, - "%s:%d: close failed", file, lineno); - return -1; - } - - switch (family) { - case AF_INET: - return addr4->sin_port; - case AF_INET6: - return addr6->sin6_port; - default: - return -1; - } -} diff --git a/kernel/tests/lib/safe_pthread.c b/kernel/tests/lib/safe_pthread.c deleted file mode 100644 index 2866aa5..0000000 --- a/kernel/tests/lib/safe_pthread.c +++ /dev/null @@ -1,43 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (c) 2016 Oracle and/or its affiliates. All Rights Reserved. - */ - -#include <pthread.h> -#include <stdio.h> - -#define TST_NO_DEFAULT_MAIN -#include "tst_test.h" - -int safe_pthread_create(const char *file, const int lineno, - pthread_t *thread_id, const pthread_attr_t *attr, - void *(*thread_fn)(void *), void *arg) -{ - int rval; - - rval = pthread_create(thread_id, attr, thread_fn, arg); - - if (rval) { - tst_brk_(file, lineno, TBROK, - "pthread_create(%p,%p,%p,%p) failed: %s", thread_id, - attr, thread_fn, arg, tst_strerrno(rval)); - } - - return rval; -} - -int safe_pthread_join(const char *file, const int lineno, - pthread_t thread_id, void **retval) -{ - int rval; - - rval = pthread_join(thread_id, retval); - - if (rval) { - tst_brk_(file, lineno, TBROK, - "pthread_join(..., %p) failed: %s", - retval, tst_strerrno(rval)); - } - - return rval; -} diff --git a/kernel/tests/lib/safe_stdio.c b/kernel/tests/lib/safe_stdio.c deleted file mode 100644 index 966a039..0000000 --- a/kernel/tests/lib/safe_stdio.c +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright (c) 2013 Cyril Hrubis <chrubis@suse.cz> - * - * 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 would 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 the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#define _GNU_SOURCE -#include <stdarg.h> -#include <stdio.h> -#include <errno.h> -#include "test.h" -#include "safe_stdio_fn.h" - -FILE *safe_fopen(const char *file, const int lineno, void (cleanup_fn)(void), - const char *path, const char *mode) -{ - FILE *f = fopen(path, mode); - - if (f == NULL) { - tst_brkm(TBROK | TERRNO, cleanup_fn, - "%s:%d: fopen(%s,%s) failed", - file, lineno, path, mode); - } - - return f; -} - -int safe_fclose(const char *file, const int lineno, void (cleanup_fn)(void), - FILE *f) -{ - int ret; - - ret = fclose(f); - - if (ret) { - tst_brkm(TBROK | TERRNO, cleanup_fn, - "%s:%d: fclose(%p) failed", file, lineno, f); - } - - return ret; -} - -int safe_asprintf(const char *file, const int lineno, void (cleanup_fn)(void), - char **strp, const char *fmt, ...) -{ - int ret; - va_list va; - - va_start(va, fmt); - ret = vasprintf(strp, fmt, va); - va_end(va); - - if (ret < 0) { - tst_brkm(TBROK | TERRNO, cleanup_fn, - "%s:%d: asprintf(%s,...) failed", file, lineno, fmt); - } - - return ret; -} - -FILE *safe_popen(const char *file, const int lineno, void (cleanup_fn)(void), - const char *command, const char *type) -{ - FILE *stream; - const int saved_errno = errno; - - errno = 0; - stream = popen(command, type); - - if (stream == NULL) { - if (errno != 0) { - tst_brkm(TBROK | TERRNO, cleanup_fn, - "%s:%d: popen(%s,%s) failed", - file, lineno, command, type); - } else { - tst_brkm(TBROK, cleanup_fn, - "%s:%d: popen(%s,%s) failed: Out of memory", - file, lineno, command, type); - } - } - - errno = saved_errno; - - return stream; -} diff --git a/kernel/tests/lib/self_exec.c b/kernel/tests/lib/self_exec.c deleted file mode 100644 index de7d095..0000000 --- a/kernel/tests/lib/self_exec.c +++ /dev/null @@ -1,225 +0,0 @@ -/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: t -*- */ -/* - * self_exec.c: self_exec magic required to run child functions on uClinux - * - * Copyright (C) 2005 Paul J.Y. Lahaie <pjlahaie-at-steamballoon.com> - * - * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * This software was produced by Steamballoon Incorporated - * 55 Byward Market Square, 2nd Floor North, Ottawa, ON K1N 9C3, Canada - */ - -#define _GNU_SOURCE /* for asprintf */ - -#include "config.h" - -#ifdef UCLINUX - -#include <stdarg.h> -#include <string.h> -#include <stdio.h> -#include "test.h" -#include "safe_macros.h" - -/* Set from parse_opts.c: */ -char *child_args; /* Arguments to child when -C is used */ - -static char *start_cwd; /* Stores the starting directory for self_exec */ - -int asprintf(char **app, const char *fmt, ...) -{ - va_list ptr; - int rv; - char *p; - - /* - * First iteration - find out size of buffer required and allocate it. - */ - va_start(ptr, fmt); - rv = vsnprintf(NULL, 0, fmt, ptr); - va_end(ptr); - - p = malloc(++rv); /* allocate the buffer */ - *app = p; - if (!p) { - return -1; - } - - /* - * Second iteration - actually produce output. - */ - va_start(ptr, fmt); - rv = vsnprintf(p, rv, fmt, ptr); - va_end(ptr); - - return rv; -} - -void maybe_run_child(void (*child) (), const char *fmt, ...) -{ - va_list ap; - char *child_dir; - char *p, *tok; - int *iptr, i, j; - char *s; - char **sptr; - char *endptr; - - /* Store the current directory for later use. */ - start_cwd = getcwd(NULL, 0); - - if (child_args) { - char *args = strdup(child_args); - - child_dir = strtok(args, ","); - if (strlen(child_dir) == 0) { - tst_brkm(TBROK, NULL, - "Could not get directory from -C option"); - return; - } - - va_start(ap, fmt); - - for (p = fmt; *p; p++) { - tok = strtok(NULL, ","); - if (!tok || strlen(tok) == 0) { - tst_brkm(TBROK, NULL, - "Invalid argument to -C option"); - return; - } - - switch (*p) { - case 'd': - iptr = va_arg(ap, int *); - i = strtol(tok, &endptr, 10); - if (*endptr != '\0') { - tst_brkm(TBROK, NULL, - "Invalid argument to -C option"); - return; - } - *iptr = i; - break; - case 'n': - j = va_arg(ap, int); - i = strtol(tok, &endptr, 10); - if (*endptr != '\0') { - tst_brkm(TBROK, NULL, - "Invalid argument to -C option"); - return; - } - if (j != i) { - va_end(ap); - free(args); - return; - } - break; - case 's': - s = va_arg(ap, char *); - if (!strncpy(s, tok, strlen(tok) + 1)) { - tst_brkm(TBROK, NULL, - "Could not strncpy for -C option"); - return; - } - break; - case 'S': - sptr = va_arg(ap, char **); - *sptr = strdup(tok); - if (!*sptr) { - tst_brkm(TBROK, NULL, - "Could not strdup for -C option"); - return; - } - break; - default: - tst_brkm(TBROK, NULL, - "Format string option %c not implemented", - *p); - return; - } - } - - va_end(ap); - free(args); - SAFE_CHDIR(NULL, child_dir); - - (*child) (); - tst_resm(TWARN, "Child function returned unexpectedly"); - /* Exit here? or exit silently? */ - } -} - -int self_exec(const char *argv0, const char *fmt, ...) -{ - va_list ap; - char *p; - char *tmp_cwd; - char *arg; - int ival; - char *str; - - if ((tmp_cwd = getcwd(NULL, 0)) == NULL) { - tst_resm(TBROK, "Could not getcwd()"); - return -1; - } - - arg = strdup(tmp_cwd); - if (arg == NULL) { - tst_resm(TBROK, "Could not produce self_exec string"); - return -1; - } - - va_start(ap, fmt); - - for (p = fmt; *p; p++) { - switch (*p) { - case 'd': - case 'n': - ival = va_arg(ap, int); - if (asprintf(&arg, "%s,%d", arg, ival) < 0) { - tst_resm(TBROK, - "Could not produce self_exec string"); - return -1; - } - break; - case 's': - case 'S': - str = va_arg(ap, char *); - if (asprintf(&arg, "%s,%s", arg, str) < 0) { - tst_resm(TBROK, - "Could not produce self_exec string"); - return -1; - } - break; - default: - tst_resm(TBROK, - "Format string option %c not implemented", *p); - return -1; - break; - } - } - - va_end(ap); - - if (chdir(start_cwd) < 0) { - tst_resm(TBROK, "Could not change to %s for self_exec", - start_cwd); - return -1; - } - - return execlp(argv0, argv0, "-C", arg, (char *)NULL); -} - -#endif /* UCLINUX */ diff --git a/kernel/tests/lib/signame.h b/kernel/tests/lib/signame.h deleted file mode 100644 index d420458..0000000 --- a/kernel/tests/lib/signame.h +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (c) 2014 Fujitsu Ltd. - * Author: Xiaoguang Wang <wangxg.fnst@cn.fujitsu.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it would be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -const char *tst_strsig(int sig) -{ - static const struct pair signal_pairs[] = { - PAIR(SIGHUP) - PAIR(SIGINT) - PAIR(SIGQUIT) - PAIR(SIGILL) - #ifdef SIGTRAP - PAIR(SIGTRAP) - #endif - - #ifdef SIGIOT - /* SIGIOT same as SIGABRT */ - STRPAIR(SIGABRT, "SIGIOT/SIGABRT") - #else - PAIR(SIGABRT) - #endif - - #ifdef SIGEMT - PAIR(SIGEMT) - #endif - #ifdef SIGBUS - PAIR(SIGBUS) - #endif - PAIR(SIGFPE) - PAIR(SIGKILL) - PAIR(SIGUSR1) - PAIR(SIGSEGV) - PAIR(SIGUSR2) - PAIR(SIGPIPE) - PAIR(SIGALRM) - PAIR(SIGTERM) - #ifdef SIGSTKFLT - PAIR(SIGSTKFLT) - #endif - PAIR(SIGCHLD) - PAIR(SIGCONT) - PAIR(SIGSTOP) - PAIR(SIGTSTP) - PAIR(SIGTTIN) - PAIR(SIGTTOU) - #ifdef SIGURG - PAIR(SIGURG) - #endif - #ifdef SIGXCPU - PAIR(SIGXCPU) - #endif - #ifdef SIGXFSZ - PAIR(SIGXFSZ) - #endif - #ifdef SIGVTALRM - PAIR(SIGVTALRM) - #endif - #ifdef SIGPROF - PAIR(SIGPROF) - #endif - #ifdef SIGWINCH - PAIR(SIGWINCH) - #endif - - #if defined(SIGIO) && defined(SIGPOLL) - /* SIGPOLL same as SIGIO */ - STRPAIR(SIGIO, "SIGIO/SIGPOLL") - #elif defined(SIGIO) - PAIR(SIGIO) - #elif defined(SIGPOLL) - PAIR(SIGPOLL) - #endif - - #ifdef SIGINFO - PAIR(SIGINFO) - #endif - #ifdef SIGLOST - PAIR(SIGLOST) - #endif - #ifdef SIGPWR - PAIR(SIGPWR) - #endif - #if defined(SIGSYS) - /* - * According to signal(7)'s manpage, SIGUNUSED is synonymous - * with SIGSYS on most architectures. - */ - STRPAIR(SIGSYS, "SIGSYS/SIGUNUSED") - #endif - }; - - PAIR_LOOKUP(signal_pairs, sig); -}; diff --git a/kernel/tests/lib/tlibio.c b/kernel/tests/lib/tlibio.c deleted file mode 100644 index cc110d1..0000000 --- a/kernel/tests/lib/tlibio.c +++ /dev/null @@ -1,2161 +0,0 @@ -/* - * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it would be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * Further, this software is distributed without any warranty that it is - * free of the rightful claim of any third person regarding infringement - * or the like. Any license provided herein, whether implied or - * otherwise, applies only to this software file. Patent licenses, if - * any, provided herein do not apply to combinations of this program with - * other software, or any other product whatsoever. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, - * Mountain View, CA 94043, or: - * - * http://www.sgi.com - * - * For further information regarding this notice, see: - * - * http://oss.sgi.com/projects/GenInfo/NoticeExplan/ - */ -/* - * - * Lib i/o - * - * This file contains several functions to doing reads and writes. - * It was written so that a single function could be called in a test - * program and only a io type field value would have to change to - * do different types of io. There is even a couple of functions that - * will allow you to parse a string to determine the iotype. - * - * This file contains functions for writing/reading to/from open files - * Prototypes: - * - * Functions declared in this module - see individual function code for - * usage comments: - * - * int stride_bounds(int offset, int stride, int nstrides, - * int bytes_per_stride, int *min, int *max); - - * int lio_write_buffer(int fd, int method, char *buffer, int size, - * char **errmsg, long wrd); - * int lio_read_buffer(int fd, int method, char *buffer, int size, - * char **errmsg, long wrd); - * - * #ifdef CRAY - * int lio_wait4asyncio(int method, int fd, struct iosw **statptr) - * int lio_check_asyncio(char *io_type, int size, struct iosw *status) - * #endif - * #ifdef sgi - * int lio_wait4asyncio(int method, int fd, aiocb_t *aiocbp) - * int lio_check_asyncio(char *io_type, int size, aiocb_t *aiocbp, int method) - * #endif - * - * int lio_parse_io_arg1(char *string) - * void lio_help1(char *prefix); - * - * int lio_parse_io_arg2(char *string, char **badtoken) - * void lio_help2(char *prefix); - * - * int lio_set_debug(int level); - * - * char Lio_SysCall[]; - * struct lio_info_type Lio_info1[]; - * struct lio_info_type Lio_info2[]; - * - * Author : Richard Logan - * - */ - -#ifdef __linux__ -#ifndef _GNU_SOURCE -#define _GNU_SOURCE -#endif -#define _LARGEFILE64_SOURCE -#endif -#include "config.h" -#include <stdio.h> -#include <ctype.h> -#include <fcntl.h> -#include <unistd.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/time.h> -#include <sys/param.h> -#include <errno.h> -#include <sys/types.h> -#include <sys/file.h> -#include <signal.h> -#include <stdint.h> -#ifdef CRAY -#include <sys/secparm.h> -#include <sys/iosw.h> -#include <sys/listio.h> -#else -/* for linux or sgi */ -#include <sys/uio.h> /* readv(2)/writev(2) */ -#include <string.h> -#endif -#if defined(__linux__) || defined(__sun) || defined(__hpux) || defined(_AIX) -#if !defined(UCLINUX) && !defined(__UCLIBC__) -#include <aio.h> -#endif -#endif -#include <stdlib.h> /* atoi, abs */ - -#include "tlibio.h" /* defines LIO* marcos */ -#include "random_range.h" - -#ifndef PATH_MAX -#define PATH_MAX MAXPATHLEN -#endif - -#if 0 /* disabled until it's needed -- roehrich 6/11/97 */ -#define BUG1_workaround 1 /* Work around a condition where aio_return gives - * a value of zero but there is no errno followup - * and the read/write operation actually did its - * job. spr/pv 705244 - */ -#endif - - -/* - * Define the structure as used in lio_parse_arg1 and lio_help1 - */ -struct lio_info_type Lio_info1[] = { - {"s", LIO_IO_SYNC, "sync i/o"}, - {"p", LIO_IO_ASYNC | LIO_WAIT_SIGACTIVE, - "async i/o using a loop to wait for a signal"}, - {"b", LIO_IO_ASYNC | LIO_WAIT_SIGPAUSE, "async i/o using pause"}, - {"a", LIO_IO_ASYNC | LIO_WAIT_RECALL, - "async i/o using recall/aio_suspend"}, -#if defined(sgi) || (defined(__linux__) && !defined(__UCLIBC__)) - {"r", - LIO_RANDOM | LIO_IO_TYPES | LIO_WAIT_TYPES, - "random sync i/o types and wait methods"}, - {"R", - LIO_RANDOM | LIO_IO_ATYPES | LIO_WAIT_ATYPES, - "random i/o types and wait methods"}, -#else - {"r", - LIO_RANDOM | LIO_IO_TYPES | LIO_WAIT_TYPES, - "random i/o types and wait methods"}, - {"R", - LIO_RANDOM | LIO_IO_TYPES | LIO_WAIT_TYPES, - "random i/o types and wait methods"}, -#endif - {"l", LIO_IO_SLISTIO | LIO_WAIT_RECALL, "single stride sync listio"}, - {"L", LIO_IO_ALISTIO | LIO_WAIT_RECALL, - "single stride async listio using recall"}, - {"X", LIO_IO_ALISTIO | LIO_WAIT_SIGPAUSE, - "single stride async listio using pause"}, - {"v", LIO_IO_SYNCV, "single buffer sync readv/writev"}, - {"P", LIO_IO_SYNCP, "sync pread/pwrite"}, -}; - -/* - * Define the structure used by lio_parse_arg2 and lio_help2 - */ -struct lio_info_type Lio_info2[] = { - {"sync", LIO_IO_SYNC, "sync i/o (read/write)"}, - {"async", LIO_IO_ASYNC, "async i/o (reada/writea/aio_read/aio_write)"}, - {"slistio", LIO_IO_SLISTIO, "single stride sync listio"}, - {"alistio", LIO_IO_ALISTIO, "single stride async listio"}, - {"syncv", LIO_IO_SYNCV, "single buffer sync readv/writev"}, - {"syncp", LIO_IO_SYNCP, "pread/pwrite"}, - {"active", LIO_WAIT_ACTIVE, "spin on status/control values"}, - {"recall", LIO_WAIT_RECALL, - "use recall(2)/aio_suspend(3) to wait for i/o to complete"}, - {"sigactive", LIO_WAIT_SIGACTIVE, "spin waiting for signal"}, - {"sigpause", LIO_WAIT_SIGPAUSE, "call pause(2) to wait for signal"}, -/* nowait is a touchy thing, it's an accident that this implementation worked at all. 6/27/97 roehrich */ -/* { "nowait", LIO_WAIT_NONE, "do not wait for async io to complete" },*/ - {"random", LIO_RANDOM, "set random bit"}, - {"randomall", - LIO_RANDOM | LIO_IO_TYPES | LIO_WAIT_TYPES, - "all random i/o types and wait methods (except nowait)"}, -}; - -char Lio_SysCall[PATH_MAX]; /* string containing last i/o system call */ - -static volatile int Received_signal = 0; /* number of signals received */ -static volatile int Rec_signal; -#if defined(sgi) || (defined(__linux__) && !defined(__UCLIBC__)) -static volatile int Received_callback = 0; /* number of callbacks received */ -static volatile int Rec_callback; -#endif -static char Errormsg[500]; -static int Debug_level = 0; - -/*********************************************************************** - * stride_bounds() - * - * Determine the bounds of a strided request, normalized to offset. Returns - * the number of bytes needed to satisfy the request, and optionally sets - * *min and *max to the mininum and maximum bytes referenced, normalized - * around offset. - * - * Returns -1 on error - the only possible error conditions are illegal values - * for nstrides and/or bytes_per_stride - both parameters must be >= 0. - * - * (maule, 11/16/95) - ***********************************************************************/ - -int stride_bounds(int offset, int stride, int nstrides, int bytes_per_stride, - int *min, int *max) -{ - int nbytes, min_byte, max_byte; - - /* - * sanity checks ... - */ - - if (nstrides < 0 || bytes_per_stride < 0) { - return -1; - } - - if (stride == 0) { - stride = bytes_per_stride; - } - - /* - * Determine the # of bytes needed to satisfy the request. This - * value, along with the offset argument, determines the min and max - * bytes referenced. - */ - - nbytes = abs(stride) * (nstrides - 1) + bytes_per_stride; - - if (stride < 0) { - max_byte = offset + bytes_per_stride - 1; - min_byte = max_byte - nbytes + 1; - } else { - min_byte = offset; - max_byte = min_byte + nbytes - 1; - } - - if (min != NULL) { - *min = min_byte; - } - - if (max != NULL) { - *max = max_byte; - } - - return nbytes; -} - -/*********************************************************************** - * This function will allow someone to set the debug level. - ***********************************************************************/ -int lio_set_debug(int level) -{ - int old; - - old = Debug_level; - Debug_level = level; - return old; -} - -/*********************************************************************** - * This function will parse a string and return desired io-method. - * Only the first character of the string is used. - * - * This function does not provide for meaningful option arguments, - * but it supports current growfiles/btlk interface. - * - * (rrl 04/96) - ***********************************************************************/ -int lio_parse_io_arg1(char *string) -{ - unsigned int ind; - int found = 0; - int mask = 0; - - /* - * Determine if token is a valid string. - */ - for (ind = 0; ind < sizeof(Lio_info1) / sizeof(struct lio_info_type); - ind++) { - if (strcmp(string, Lio_info1[ind].token) == 0) { - mask |= Lio_info1[ind].bits; - found = 1; - break; - } - } - - if (found == 0) { - return -1; - } - - return mask; - -} - -/*********************************************************************** - * This function will print a help message describing the characters - * that can be parsed by lio_parse_io_arg1(). - * They will be printed one per line. - * (rrl 04/96) - ***********************************************************************/ -void lio_help1(char *prefix) -{ - unsigned int ind; - - for (ind = 0; ind < sizeof(Lio_info1) / sizeof(struct lio_info_type); - ind++) { - printf("%s %s : %s\n", prefix, Lio_info1[ind].token, - Lio_info1[ind].desc); - } - - return; -} - -/*********************************************************************** - * This function will parse a string and return the desired io-method. - * This function will take a comma separated list of io type and wait - * method tokens as defined in Lio_info2[]. If a token does not match - * any of the tokens in Lio_info2[], it will be coverted to a number. - * If it was a number, those bits are also set. - * - * (rrl 04/96) - ***********************************************************************/ -int lio_parse_io_arg2(char *string, char **badtoken) -{ - char *token = string; - char *cc = token; - char savecc; - int found; - int mask = 0; - - int tmp; - unsigned int ind; - char chr; - - if (token == NULL) - return -1; - - for (;;) { - for (; ((*cc != ',') && (*cc != '\0')); cc++) ; - savecc = *cc; - *cc = '\0'; - - found = 0; - - /* - * Determine if token is a valid string or number and if - * so, add the bits to the mask. - */ - for (ind = 0; - ind < sizeof(Lio_info2) / sizeof(struct lio_info_type); - ind++) { - if (strcmp(token, Lio_info2[ind].token) == 0) { - mask |= Lio_info2[ind].bits; - found = 1; - break; - } - } - - /* - * If token does not match one of the defined tokens, determine - * if it is a number, if so, add the bits. - */ - if (!found) { - if (sscanf(token, "%i%c", &tmp, &chr) == 1) { - mask |= tmp; - found = 1; - } - } - - *cc = savecc; - - if (!found) { /* token is not valid */ - if (badtoken != NULL) - *badtoken = token; - return (-1); - } - - if (savecc == '\0') - break; - - token = ++cc; - } - - return mask; -} - -/*********************************************************************** - * This function will print a help message describing the tokens - * that can be parsed by lio_parse_io_arg2(). - * It will print them one per line. - * - * (rrl 04/96) - ***********************************************************************/ -void lio_help2(char *prefix) -{ - unsigned int ind; - - for (ind = 0; ind < sizeof(Lio_info2) / sizeof(struct lio_info_type); - ind++) { - printf("%s %s : %s\n", prefix, Lio_info2[ind].token, - Lio_info2[ind].desc); - } - return; -} - -/*********************************************************************** - * This is an internal signal handler. - * If the handler is called, it will increment the Received_signal - * global variable. - ***********************************************************************/ -static void lio_async_signal_handler(int sig) -{ - if (Debug_level) - printf - ("DEBUG %s/%d: received signal %d, a signal caught %d times\n", - __FILE__, __LINE__, sig, Received_signal + 1); - - Received_signal++; - - return; -} - -#if defined(sgi) || (defined(__linux__) && !defined(__UCLIBC__)) -/*********************************************************************** - * This is an internal callback handler. - * If the handler is called, it will increment the Received_callback - * global variable. - ***********************************************************************/ -static void lio_async_callback_handler(union sigval sigval) -{ - if (Debug_level) - printf - ("DEBUG %s/%d: received callback, nbytes=%ld, a callback called %d times\n", - __FILE__, __LINE__, (long)sigval.sival_int, - Received_callback + 1); - - Received_callback++; - - return; -} -#endif /* sgi */ - -/*********************************************************************** - * lio_random_methods - * This function will randomly choose an io type and wait method - * from set of io types and wait methods. Since this information - * is stored in a bitmask, it randomly chooses an io type from - * the io type bits specified and does the same for wait methods. - * - * Return Value - * This function will return a value with all non choosen io type - * and wait method bits cleared. The LIO_RANDOM bit is also - * cleared. All other bits are left unchanged. - * - * (rrl 04/96) - ***********************************************************************/ -int lio_random_methods(long curr_mask) -{ - int mask = 0; - - /* remove random select, io type, and wait method bits from curr_mask */ - mask = curr_mask & (~(LIO_IO_TYPES | LIO_WAIT_TYPES | LIO_RANDOM)); - - /* randomly select io type from specified io types */ - mask = mask | random_bit(curr_mask & LIO_IO_TYPES); - - /* randomly select wait methods from specified wait methods */ - mask = mask | random_bit(curr_mask & LIO_WAIT_TYPES); - - return mask; -} - -static void wait4sync_io(int fd, int read) -{ - fd_set s; - FD_ZERO(&s); - FD_SET(fd, &s); - - select(fd + 1, read ? &s : NULL, read ? NULL : &s, NULL, NULL); -} - -/*********************************************************************** - * Generic write function - * This function can be used to do a write using write(2), writea(2), - * aio_write(3), writev(2), pwrite(2), - * or single stride listio(2)/lio_listio(3). - * By setting the desired bits in the method - * bitmask, the caller can control the type of write and the wait method - * that will be used. If no io type bits are set, write will be used. - * - * If async io was attempted and no wait method bits are set then the - * wait method is: recall(2) for writea(2) and listio(2); aio_suspend(3) for - * aio_write(3) and lio_listio(3). - * - * If multiple wait methods are specified, - * only one wait method will be used. The order is predetermined. - * - * If the call specifies a signal and one of the two signal wait methods, - * a signal handler for the signal is set. This will reset an already - * set handler for this signal. - * - * If the LIO_RANDOM method bit is set, this function will randomly - * choose a io type and wait method from bits in the method argument. - * - * If an error is encountered, an error message will be generated - * in a internal static buffer. If errmsg is not NULL, it will - * be updated to point to the static buffer, allowing the caller - * to print the error message. - * - * Return Value - * If a system call fails, -errno is returned. - * If LIO_WAIT_NONE bit is set, the return value is the return value - * of the system call. - * If the io did not fail, the amount of data written is returned. - * If the size the system call say was written is different - * then what was asked to be written, errmsg is updated for - * this error condition. The return value is still the amount - * the system call says was written. - * - * (rrl 04/96) - ***********************************************************************/ -int lio_write_buffer(int fd, /* open file descriptor */ - int method, /* contains io type and wait method bitmask */ - char *buffer, /* pointer to buffer */ - int size, /* the size of the io */ - int sig, /* signal to use if async io */ - char **errmsg, /* char pointer that will be updated to point to err message */ - long wrd) /* to allow future features, use zero for now */ -{ - int ret = 0; /* syscall return or used to get random method */ - char *io_type; /* Holds string of type of io */ - int omethod = method; - int listio_cmd; /* Holds the listio/lio_listio cmd */ -#ifdef CRAY - struct listreq request; /* Used when a listio is wanted */ - struct iosw status, *statptr[1]; -#else - /* for linux or sgi */ - struct iovec iov; /* iovec for writev(2) */ -#endif -#if defined (sgi) - aiocb_t aiocbp; /* POSIX aio control block */ - aiocb_t *aiolist[1]; /* list of aio control blocks for lio_listio */ - off64_t poffset; /* pwrite(2) offset */ -#endif -#if defined(__linux__) && !defined(__UCLIBC__) - struct aiocb aiocbp; /* POSIX aio control block */ - struct aiocb *aiolist[1]; /* list of aio control blocks for lio_listio */ - off64_t poffset; /* pwrite(2) offset */ -#endif - /* - * If LIO_RANDOM bit specified, get new method randomly. - */ - if (method & LIO_RANDOM) { - if (Debug_level > 3) - printf("DEBUG %s/%d: method mask to choose from: %#o\n", - __FILE__, __LINE__, method); - method = lio_random_methods(method); - if (Debug_level > 2) - printf("DEBUG %s/%d: random chosen method %#o\n", - __FILE__, __LINE__, method); - } - - if (errmsg != NULL) - *errmsg = Errormsg; - - Rec_signal = Received_signal; /* get the current number of signals received */ -#if defined(sgi) || (defined(__linux__) && !defined(__UCLIBC__)) - Rec_callback = Received_callback; /* get the current number of callbacks received */ -#endif - -#ifdef CRAY - memset(&status, 0x00, sizeof(struct iosw)); - memset(&request, 0x00, sizeof(struct listreq)); - statptr[0] = &status; -#else - /* for linux or sgi */ - memset(&iov, 0x00, sizeof(struct iovec)); - iov.iov_base = buffer; - iov.iov_len = size; -#endif -#if defined(sgi) || (defined(__linux__) && !defined(__UCLIBC__)) -#if defined(sgi) - memset(&aiocbp, 0x00, sizeof(aiocb_t)); -#else - memset(&aiocbp, 0x00, sizeof(struct aiocb)); -#endif - aiocbp.aio_fildes = fd; - aiocbp.aio_nbytes = size; - aiocbp.aio_buf = buffer; -/* aiocbp.aio_offset = lseek( fd, 0, SEEK_CUR ); -- set below */ - aiocbp.aio_sigevent.sigev_notify = SIGEV_NONE; - aiocbp.aio_sigevent.sigev_signo = 0; -#ifdef sgi - aiocbp.aio_sigevent.sigev_func = NULL; - aiocbp.aio_sigevent.sigev_value.sival_int = 0; -#elif defined(__linux__) && !defined(__UCLIBC__) - aiocbp.aio_sigevent.sigev_notify_function = NULL; - aiocbp.aio_sigevent.sigev_notify_attributes = 0; -#endif - aiolist[0] = &aiocbp; - - if ((ret = lseek(fd, 0, SEEK_CUR)) == -1) { - ret = 0; - /* If there is an error and it is not ESPIPE then kick out the error. - * If the fd is a fifo then we have to make sure that - * lio_random_methods() didn't select pwrite/pread; if it did then - * switch to write/read. - */ - if (errno == ESPIPE) { - if (method & LIO_IO_SYNCP) { - if (omethod & LIO_RANDOM) { - method &= ~LIO_IO_SYNCP; - method |= LIO_IO_SYNC; - if (Debug_level > 2) - printf - ("DEBUG %s/%d: random chosen method switched to %#o for fifo\n", - __FILE__, __LINE__, - method); - } else if (Debug_level) { - printf - ("DEBUG %s/%d: pwrite will fail when it writes to a fifo\n", - __FILE__, __LINE__); - } - } - /* else: let it ride */ - } else { - sprintf(Errormsg, - "%s/%d lseek(fd=%d,0,SEEK_CUR) failed, errno=%d %s", - __FILE__, __LINE__, fd, errno, strerror(errno)); - return -errno; - } - } -#if defined(sgi) || (defined(__linux__) && !defined(__UCLIBC__)) - poffset = (off64_t) ret; -#endif - aiocbp.aio_offset = ret; - -#endif - - /* - * If the LIO_USE_SIGNAL bit is not set, only use the signal - * if the LIO_WAIT_SIGPAUSE or the LIO_WAIT_SIGACTIVE bits are bit. - * Otherwise there is not necessary a signal handler to trap - * the signal. - */ - if (sig && !(method & LIO_USE_SIGNAL) && !(method & LIO_WAIT_SIGTYPES)) { - - sig = 0; /* ignore signal parameter */ - } -#if defined(sgi) || (defined(__linux__) && !defined(__UCLIBC__)) - if (sig && (method & LIO_WAIT_CBTYPES)) - sig = 0; /* ignore signal parameter */ -#endif - - /* - * only setup signal hander if sig was specified and - * a sig wait method was specified. - * Doing this will change the handler for this signal. The - * old signal handler will not be restored. - *** restoring the signal handler could be added *** - */ - - if (sig && (method & LIO_WAIT_SIGTYPES)) { -#ifdef CRAY - sigctl(SCTL_REG, sig, lio_async_signal_handler); -#endif -#if defined(sgi) || (defined(__linux__) && !defined(__UCLIBC__)) - aiocbp.aio_sigevent.sigev_notify = SIGEV_SIGNAL; - aiocbp.aio_sigevent.sigev_signo = sig; - sigset(sig, lio_async_signal_handler); -#endif /* sgi */ - } -#if defined(sgi) - else if (method & LIO_WAIT_CBTYPES) { - /* sival_int just has to be something that I can use - * to identify the callback, and "size" happens to be handy... - */ - aiocbp.aio_sigevent.sigev_notify = SIGEV_CALLBACK; - aiocbp.aio_sigevent.sigev_func = lio_async_callback_handler; - aiocbp.aio_sigevent.sigev_value.sival_int = size; - } -#endif -#if defined(__linux__) && !defined(__UCLIBC__) - else if (method & LIO_WAIT_CBTYPES) { - /* sival_int just has to be something that I can use - * to identify the callback, and "size" happens to be handy... - */ - aiocbp.aio_sigevent.sigev_notify = SIGEV_THREAD; - aiocbp.aio_sigevent.sigev_notify_function = - lio_async_callback_handler; - aiocbp.aio_sigevent.sigev_notify_attributes = - (void *)(uintptr_t) size; - } -#endif - /* - * Determine the system call that will be called and produce - * the string of the system call and place it in Lio_SysCall. - * Also update the io_type char pointer to give brief description - * of system call. Execute the system call and check for - * system call failure. If sync i/o, return the number of - * bytes written/read. - */ - - if ((method & LIO_IO_SYNC) - || (method & (LIO_IO_TYPES | LIO_IO_ATYPES)) == 0) { - /* - * write(2) is used if LIO_IO_SYNC bit is set or not none - * of the LIO_IO_TYPES bits are set (default). - */ - - sprintf(Lio_SysCall, "write(%d, buf, %d)", fd, size); - io_type = "write"; - - if (Debug_level) { - printf("DEBUG %s/%d: %s\n", __FILE__, __LINE__, - Lio_SysCall); - } - while (1) { - if (((ret = write(fd, buffer, size)) == -1) - && errno != EAGAIN && errno != EINTR) { - sprintf(Errormsg, - "%s/%d write(%d, buf, %d) ret:-1, errno=%d %s", - __FILE__, __LINE__, fd, size, errno, - strerror(errno)); - return -errno; - } - - if (ret != -1) { - if (ret != size) { - sprintf(Errormsg, - "%s/%d write(%d, buf, %d) returned=%d", - __FILE__, __LINE__, - fd, size, ret); - size -= ret; - buffer += ret; - } else { - if (Debug_level > 1) - printf - ("DEBUG %s/%d: write completed without error (ret %d)\n", - __FILE__, __LINE__, ret); - - return ret; - } - } - wait4sync_io(fd, 0); - } - - } - - else if (method & LIO_IO_ASYNC) { -#ifdef CRAY - sprintf(Lio_SysCall, - "writea(%d, buf, %d, &status, %d)", fd, size, sig); - io_type = "writea"; - - if (Debug_level) { - printf("DEBUG %s/%d: %s\n", __FILE__, __LINE__, - Lio_SysCall); - } - - sigoff(); - if ((ret = writea(fd, buffer, size, &status, sig)) == -1) { - sprintf(Errormsg, - "%s/%d writea(%d, buf, %d, &stat, %d) ret:-1, errno=%d %s", - __FILE__, __LINE__, - fd, size, sig, errno, strerror(errno)); - sigon(); - return -errno; - } -#endif -#if defined(sgi) || (defined(__linux__) && !defined(__UCLIBC__)) - sprintf(Lio_SysCall, - "aio_write(fildes=%d, buf, nbytes=%d, signo=%d)", fd, - size, sig); - io_type = "aio_write"; - - if (Debug_level) { - printf("DEBUG %s/%d: %s\n", __FILE__, __LINE__, - Lio_SysCall); - } - - if (sig) - sighold(sig); - if ((ret = aio_write(&aiocbp)) == -1) { - sprintf(Errormsg, - "%s/%d aio_write(fildes=%d, buf, nbytes=%d, signo=%d) ret:-1, errno=%d %s", - __FILE__, __LINE__, - fd, size, sig, errno, strerror(errno)); - if (sig) - sigrelse(sig); - return -errno; - } -#endif - } - /* LIO_IO_ASYNC */ - else if (method & LIO_IO_SLISTIO) { -#ifdef CRAY - request.li_opcode = LO_WRITE; - request.li_fildes = fd; - request.li_buf = buffer; - request.li_nbyte = size; - request.li_status = &status; - request.li_signo = sig; - request.li_nstride = 0; - request.li_filstride = 0; - request.li_memstride = 0; - - listio_cmd = LC_WAIT; - io_type = "listio(2) sync write"; - - sprintf(Lio_SysCall, - "listio(LC_WAIT, &req, 1) LO_WRITE, fd:%d, nbyte:%d", - fd, size); - - if (Debug_level) { - printf("DEBUG %s/%d: %s\n", __FILE__, __LINE__, - Lio_SysCall); - } - - sigoff(); - if (listio(listio_cmd, &request, 1) == -1) { - sprintf(Errormsg, - "%s/%d %s failed, fd:%d, nbyte:%d errno=%d %s", - __FILE__, __LINE__, Lio_SysCall, fd, size, - errno, strerror(errno)); - sigon(); - return -errno; - } - - if (Debug_level > 1) - printf("DEBUG %s/%d: %s did not return -1\n", - __FILE__, __LINE__, Lio_SysCall); - - ret = lio_check_asyncio(io_type, size, &status); - return ret; - -#endif -#if defined(sgi) || (defined(__linux__) && !defined(__UCLIBC__)) - - aiocbp.aio_lio_opcode = LIO_WRITE; - listio_cmd = LIO_WAIT; - io_type = "lio_listio(3) sync write"; - - sprintf(Lio_SysCall, - "lio_listio(LIO_WAIT, aiolist, 1, NULL) LIO_WRITE, fd:%d, nbyte:%d, sig:%d", - fd, size, sig); - - if (Debug_level) { - printf("DEBUG %s/%d: %s\n", __FILE__, __LINE__, - Lio_SysCall); - } - - if (sig) - sighold(sig); - if (lio_listio(listio_cmd, aiolist, 1, NULL) == -1) { - sprintf(Errormsg, - "%s/%d %s failed, fd:%d, nbyte:%d errno=%d %s", - __FILE__, __LINE__, Lio_SysCall, fd, size, - errno, strerror(errno)); - if (sig) - sigrelse(sig); - return -errno; - } - - if (Debug_level > 1) - printf("DEBUG %s/%d: %s did not return -1\n", - __FILE__, __LINE__, Lio_SysCall); - - ret = lio_check_asyncio(io_type, size, &aiocbp, method); - return ret; -#endif - } - /* LIO_IO_SLISTIO */ - else if (method & LIO_IO_ALISTIO) { -#ifdef CRAY - request.li_opcode = LO_WRITE; - request.li_fildes = fd; - request.li_buf = buffer; - request.li_nbyte = size; - request.li_status = &status; - request.li_signo = sig; - request.li_nstride = 0; - request.li_filstride = 0; - request.li_memstride = 0; - - listio_cmd = LC_START; - io_type = "listio(2) async write"; - - sprintf(Lio_SysCall, - "listio(LC_START, &req, 1) LO_WRITE, fd:%d, nbyte:%d", - fd, size); - - if (Debug_level) { - printf("DEBUG %s/%d: %s\n", __FILE__, __LINE__, - Lio_SysCall); - } - - sigoff(); - if (listio(listio_cmd, &request, 1) == -1) { - sprintf(Errormsg, - "%s/%d %s failed, fd:%d, nbyte:%d errno=%d %s", - __FILE__, __LINE__, Lio_SysCall, fd, size, - errno, strerror(errno)); - sigon(); - return -errno; - } -#endif -#if defined (sgi) || (defined(__linux__) && !defined(__UCLIBC__)) - aiocbp.aio_lio_opcode = LIO_WRITE; - listio_cmd = LIO_NOWAIT; - io_type = "lio_listio(3) async write"; - - sprintf(Lio_SysCall, - "lio_listio(LIO_NOWAIT, aiolist, 1, NULL) LIO_WRITE, fd:%d, nbyte:%d", - fd, size); - - if (Debug_level) { - printf("DEBUG %s/%d: %s\n", __FILE__, __LINE__, - Lio_SysCall); - } - - if (sig) - sighold(sig); - if (lio_listio(listio_cmd, aiolist, 1, NULL) == -1) { - sprintf(Errormsg, - "%s/%d %s failed, fd:%d, nbyte:%d errno=%d %s", - __FILE__, __LINE__, Lio_SysCall, fd, size, - errno, strerror(errno)); - if (sig) - sigrelse(sig); - return -errno; - } -#endif - } - /* LIO_IO_ALISTIO */ -#ifndef CRAY - else if (method & LIO_IO_SYNCV) { - io_type = "writev(2)"; - - sprintf(Lio_SysCall, "writev(%d, &iov, 1) nbyte:%d", fd, size); - - if (Debug_level) { - printf("DEBUG %s/%d: %s\n", __FILE__, __LINE__, - Lio_SysCall); - } - if ((ret = writev(fd, &iov, 1)) == -1) { - sprintf(Errormsg, - "%s/%d writev(%d, iov, 1) nbyte:%d ret:-1, errno=%d %s", - __FILE__, __LINE__, fd, size, errno, - strerror(errno)); - return -errno; - } - - if (ret != size) { - sprintf(Errormsg, - "%s/%d writev(%d, iov, 1) nbyte:%d returned=%d", - __FILE__, __LINE__, fd, size, ret); - } else if (Debug_level > 1) - printf - ("DEBUG %s/%d: writev completed without error (ret %d)\n", - __FILE__, __LINE__, ret); - - return ret; - } /* LIO_IO_SYNCV */ -#endif - -#if defined(sgi) || (defined(__linux__) && !defined(__UCLIBC__)) - else if (method & LIO_IO_SYNCP) { - io_type = "pwrite(2)"; - - sprintf(Lio_SysCall, - "pwrite(%d, buf, %d, %lld)", fd, size, - (long long)poffset); - - if (Debug_level) { - printf("DEBUG %s/%d: %s\n", __FILE__, __LINE__, - Lio_SysCall); - } - if ((ret = pwrite(fd, buffer, size, poffset)) == -1) { - sprintf(Errormsg, - "%s/%d pwrite(%d, buf, %d, %lld) ret:-1, errno=%d %s", - __FILE__, __LINE__, fd, size, - (long long)poffset, errno, strerror(errno)); - return -errno; - } - - if (ret != size) { - sprintf(Errormsg, - "%s/%d pwrite(%d, buf, %d, %lld) returned=%d", - __FILE__, __LINE__, - fd, size, (long long)poffset, ret); - } else if (Debug_level > 1) - printf - ("DEBUG %s/%d: pwrite completed without error (ret %d)\n", - __FILE__, __LINE__, ret); - - return ret; - } /* LIO_IO_SYNCP */ -#endif - - else { - printf("DEBUG %s/%d: No I/O method chosen\n", __FILE__, - __LINE__); - return -1; - } - - /* - * wait for async io to complete. - */ -#ifdef CRAY - ret = lio_wait4asyncio(method, fd, statptr); -#endif -#if defined(sgi) || (defined(__linux__) && !defined(__UCLIBC__)) - ret = lio_wait4asyncio(method, fd, &aiocbp); -#endif - - /* - * If there was an error waiting for async i/o to complete, - * return the error value (errno) to the caller. - * Note: Errormsg should already have been updated. - */ - if (ret < 0) { - return ret; - } - - /* - * If i/o was not waited for (may not have been completed at this time), - * return the size that was requested. - */ - if (ret == 1) - return size; - - /* - * check that async io was successful. - * Note: if the there was an system call failure, -errno - * was returned and Errormsg should already have been updated. - * If amount i/o was different than size, Errormsg should already - * have been updated but the actual i/o size if returned. - */ - -#ifdef CRAY - ret = lio_check_asyncio(io_type, size, &status); -#endif -#if defined(sgi) || (defined(__linux__) && !defined(__UCLIBC__)) - ret = lio_check_asyncio(io_type, size, &aiocbp, method); -#endif - - return ret; -} /* end of lio_write_buffer */ - -/*********************************************************************** - * Generic read function - * This function can be used to do a read using read(2), reada(2), - * aio_read(3), readv(2), pread(2), - * or single stride listio(2)/lio_listio(3). - * By setting the desired bits in the method - * bitmask, the caller can control the type of read and the wait method - * that will be used. If no io type bits are set, read will be used. - * - * If async io was attempted and no wait method bits are set then the - * wait method is: recall(2) for reada(2) and listio(2); aio_suspend(3) for - * aio_read(3) and lio_listio(3). - * - * If multiple wait methods are specified, - * only one wait method will be used. The order is predetermined. - * - * If the call specifies a signal and one of the two signal wait methods, - * a signal handler for the signal is set. This will reset an already - * set handler for this signal. - * - * If the LIO_RANDOM method bit is set, this function will randomly - * choose a io type and wait method from bits in the method argument. - * - * If an error is encountered, an error message will be generated - * in a internal static buffer. If errmsg is not NULL, it will - * be updated to point to the static buffer, allowing the caller - * to print the error message. - * - * Return Value - * If a system call fails, -errno is returned. - * If LIO_WAIT_NONE bit is set, the return value is the return value - * of the system call. - * If the io did not fail, the amount of data written is returned. - * If the size the system call say was written is different - * then what was asked to be written, errmsg is updated for - * this error condition. The return value is still the amount - * the system call says was written. - * - * (rrl 04/96) - ***********************************************************************/ -int lio_read_buffer(int fd, /* open file descriptor */ - int method, /* contains io type and wait method bitmask*/ - char *buffer, /* pointer to buffer */ - int size, /* the size of the io */ - int sig, /* signal to use if async io */ - char **errmsg, /* char pointer that will be updated to point to err message */ - long wrd) /* to allow future features, use zero for now */ -{ - int ret = 0; /* syscall return or used to get random method */ - char *io_type; /* Holds string of type of io */ - int listio_cmd; /* Holds the listio/lio_listio cmd */ - int omethod = method; -#ifdef CRAY - struct listreq request; /* Used when a listio is wanted */ - struct iosw status, *statptr[1]; -#else - /* for linux or sgi */ - struct iovec iov; /* iovec for readv(2) */ -#endif -#ifdef sgi - aiocb_t aiocbp; /* POSIX aio control block */ - aiocb_t *aiolist[1]; /* list of aio control blocks for lio_listio */ - off64_t poffset; /* pread(2) offset */ -#endif -#if defined (__linux__) && !defined(__UCLIBC__) - struct aiocb aiocbp; /* POSIX aio control block */ - struct aiocb *aiolist[1]; /* list of aio control blocks for lio_listio */ - off64_t poffset; /* pread(2) offset */ -#endif - - /* - * If LIO_RANDOM bit specified, get new method randomly. - */ - if (method & LIO_RANDOM) { - if (Debug_level > 3) - printf("DEBUG %s/%d: method mask to choose from: %#o\n", - __FILE__, __LINE__, method); - method = lio_random_methods(method); - if (Debug_level > 2) - printf("DEBUG %s/%d: random chosen method %#o\n", - __FILE__, __LINE__, method); - } - - if (errmsg != NULL) - *errmsg = Errormsg; - - Rec_signal = Received_signal; /* get the current number of signals received */ -#if defined(sgi) || (defined(__linux__) && !defined(__UCLIBC__)) - Rec_callback = Received_callback; /* get the current number of callbacks received */ -#endif - -#ifdef CRAY - memset(&status, 0x00, sizeof(struct iosw)); - memset(&request, 0x00, sizeof(struct listreq)); - statptr[0] = &status; -#else - /* for linux or sgi */ - memset(&iov, 0x00, sizeof(struct iovec)); - iov.iov_base = buffer; - iov.iov_len = size; -#endif -#if defined(sgi) || (defined(__linux__) && !defined(__UCLIBC__)) -#if defined(sgi) - memset(&aiocbp, 0x00, sizeof(aiocb_t)); -#else - memset(&aiocbp, 0x00, sizeof(struct aiocb)); -#endif - aiocbp.aio_fildes = fd; - aiocbp.aio_nbytes = size; - aiocbp.aio_buf = buffer; -/* aiocbp.aio_offset = lseek( fd, 0, SEEK_CUR ); -- set below */ - aiocbp.aio_sigevent.sigev_notify = SIGEV_NONE; - aiocbp.aio_sigevent.sigev_signo = 0; -#ifdef sgi - aiocbp.aio_sigevent.sigev_func = NULL; - aiocbp.aio_sigevent.sigev_value.sival_int = 0; -#elif defined(__linux__) && !defined(__UCLIBC__) - aiocbp.aio_sigevent.sigev_notify_function = NULL; - aiocbp.aio_sigevent.sigev_notify_attributes = 0; -#endif - aiolist[0] = &aiocbp; - - if ((ret = lseek(fd, 0, SEEK_CUR)) == -1) { - ret = 0; - /* If there is an error and it is not ESPIPE then kick out the error. - * If the fd is a fifo then we have to make sure that - * lio_random_methods() didn't select pwrite/pread; if it did then - * switch to write/read. - */ - if (errno == ESPIPE) { - if (method & LIO_IO_SYNCP) { - if (omethod & LIO_RANDOM) { - method &= ~LIO_IO_SYNCP; - method |= LIO_IO_SYNC; - if (Debug_level > 2) - printf - ("DEBUG %s/%d: random chosen method switched to %#o for fifo\n", - __FILE__, __LINE__, - method); - } else if (Debug_level) { - printf - ("DEBUG %s/%d: pread will fail when it reads from a fifo\n", - __FILE__, __LINE__); - } - } - /* else: let it ride */ - } else { - sprintf(Errormsg, - "%s/%d lseek(fd=%d,0,SEEK_CUR) failed, errno=%d %s", - __FILE__, __LINE__, fd, errno, strerror(errno)); - return -errno; - } - } -#if defined(sgi) || (defined(__linux__) && !defined(__UCLIBC__)) - poffset = (off64_t) ret; -#endif - aiocbp.aio_offset = ret; - -#endif - - /* - * If the LIO_USE_SIGNAL bit is not set, only use the signal - * if the LIO_WAIT_SIGPAUSE or the LIO_WAIT_SIGACTIVE bits are set. - * Otherwise there is not necessarily a signal handler to trap - * the signal. - */ - if (sig && !(method & LIO_USE_SIGNAL) && !(method & LIO_WAIT_SIGTYPES)) { - - sig = 0; /* ignore signal parameter */ - } -#if defined(sgi) || (defined(__linux__)&& !defined(__UCLIBC__)) - if (sig && (method & LIO_WAIT_CBTYPES)) - sig = 0; /* ignore signal parameter */ -#endif - - /* - * only setup signal hander if sig was specified and - * a sig wait method was specified. - * Doing this will change the handler for this signal. The - * old signal handler will not be restored. - *** restoring the signal handler could be added *** - */ - - if (sig && (method & LIO_WAIT_SIGTYPES)) { -#ifdef CRAY - sigctl(SCTL_REG, sig, lio_async_signal_handler); -#endif -#if defined(sgi) || (defined(__linux__) && !defined(__UCLIBC__)) - aiocbp.aio_sigevent.sigev_notify = SIGEV_SIGNAL; - aiocbp.aio_sigevent.sigev_signo = sig; - sigset(sig, lio_async_signal_handler); -#endif /* CRAY */ - } -#if defined(sgi) - else if (method & LIO_WAIT_CBTYPES) { - aiocbp.aio_sigevent.sigev_notify = SIGEV_CALLBACK; - aiocbp.aio_sigevent.sigev_func = lio_async_callback_handler; - /* sival_int just has to be something that I can use - * to identify the callback, and "size" happens to be handy... - */ - aiocbp.aio_sigevent.sigev_value.sival_int = size; - } -#endif -#if defined(__linux__) && !defined(__UCLIBC__) - else if (method & LIO_WAIT_CBTYPES) { - aiocbp.aio_sigevent.sigev_notify = SIGEV_THREAD; - aiocbp.aio_sigevent.sigev_notify_function = - lio_async_callback_handler; - /* sival_int just has to be something that I can use - * to identify the callback, and "size" happens to be handy... - */ - aiocbp.aio_sigevent.sigev_notify_attributes = - (void *)(uintptr_t) size; - } -#endif - - /* - * Determine the system call that will be called and produce - * the string of the system call and place it in Lio_SysCall. - * Also update the io_type char pointer to give brief description - * of system call. Execute the system call and check for - * system call failure. If sync i/o, return the number of - * bytes written/read. - */ - - if ((method & LIO_IO_SYNC) - || (method & (LIO_IO_TYPES | LIO_IO_ATYPES)) == 0) { - /* - * read(2) is used if LIO_IO_SYNC bit is set or not none - * of the LIO_IO_TYPES bits are set (default). - */ - - sprintf(Lio_SysCall, "read(%d, buf, %d)", fd, size); - io_type = "read"; - - if (Debug_level) { - printf("DEBUG %s/%d: %s\n", __FILE__, __LINE__, - Lio_SysCall); - } - - while (1) { - if (((ret = read(fd, buffer, size)) == -1) - && errno != EINTR && errno != EAGAIN) { - sprintf(Errormsg, - "%s/%d read(%d, buf, %d) ret:-1, errno=%d %s", - __FILE__, __LINE__, fd, size, errno, - strerror(errno)); - return -errno; - } - - if (ret == 0) - return 0; - if (ret != -1) { - if (ret != size) { - sprintf(Errormsg, - "%s/%d read(%d, buf, %d) returned=%d", - __FILE__, __LINE__, - fd, size, ret); - size -= ret; - buffer += ret; - } else { - if (Debug_level > 1) - printf - ("DEBUG %s/%d: read completed without error (ret %d)\n", - __FILE__, __LINE__, ret); - - return ret; - } - } - wait4sync_io(fd, 1); - } - - } - - else if (method & LIO_IO_ASYNC) { -#ifdef CRAY - sprintf(Lio_SysCall, - "reada(%d, buf, %d, &status, %d)", fd, size, sig); - io_type = "reada"; - - if (Debug_level) { - printf("DEBUG %s/%d: %s\n", __FILE__, __LINE__, - Lio_SysCall); - } - - sigoff(); - if ((ret = reada(fd, buffer, size, &status, sig)) == -1) { - sprintf(Errormsg, - "%s/%d reada(%d, buf, %d, &stat, %d) ret:-1, errno=%d %s", - __FILE__, __LINE__, - fd, size, sig, errno, strerror(errno)); - sigon(); - return -errno; - } -#endif -#if defined(sgi) || (defined(__linux__) && !defined(__UCLIBC__)) - sprintf(Lio_SysCall, - "aio_read(fildes=%d, buf, nbytes=%d, signo=%d)", fd, - size, sig); - io_type = "aio_read"; - - if (Debug_level) { - printf("DEBUG %s/%d: %s\n", __FILE__, __LINE__, - Lio_SysCall); - } - - if (sig) - sighold(sig); - if ((ret = aio_read(&aiocbp)) == -1) { - sprintf(Errormsg, - "%s/%d aio_read(fildes=%d, buf, nbytes=%d, signo=%d) ret:-1, errno=%d %s", - __FILE__, __LINE__, - fd, size, sig, errno, strerror(errno)); - if (sig) - sigrelse(sig); - return -errno; - } -#endif - } - /* LIO_IO_ASYNC */ - else if (method & LIO_IO_SLISTIO) { -#ifdef CRAY - request.li_opcode = LO_READ; - request.li_fildes = fd; - request.li_buf = buffer; - request.li_nbyte = size; - request.li_status = &status; - request.li_signo = sig; - request.li_nstride = 0; - request.li_filstride = 0; - request.li_memstride = 0; - - listio_cmd = LC_WAIT; - io_type = "listio(2) sync read"; - - sprintf(Lio_SysCall, - "listio(LC_WAIT, &req, 1) LO_READ, fd:%d, nbyte:%d", - fd, size); - - if (Debug_level) { - printf("DEBUG %s/%d: %s\n", __FILE__, __LINE__, - Lio_SysCall); - } - - sigoff(); - if (listio(listio_cmd, &request, 1) == -1) { - sprintf(Errormsg, - "%s/%d %s failed, fd:%d, nbyte:%d errno=%d %s", - __FILE__, __LINE__, Lio_SysCall, fd, size, - errno, strerror(errno)); - sigon(); - return -errno; - } - - if (Debug_level > 1) - printf("DEBUG %s/%d: %s did not return -1\n", - __FILE__, __LINE__, Lio_SysCall); - - ret = lio_check_asyncio(io_type, size, &status); - return ret; -#endif -#if defined(sgi) || (defined(__linux__) && !defined(__UCLIBC__)) - aiocbp.aio_lio_opcode = LIO_READ; - listio_cmd = LIO_WAIT; - io_type = "lio_listio(3) sync read"; - - sprintf(Lio_SysCall, - "lio_listio(LIO_WAIT, aiolist, 1, NULL) LIO_READ, fd:%d, nbyte:%d", - fd, size); - - if (Debug_level) { - printf("DEBUG %s/%d: %s\n", __FILE__, __LINE__, - Lio_SysCall); - } - - if (sig) - sighold(sig); - if (lio_listio(listio_cmd, aiolist, 1, NULL) == -1) { - sprintf(Errormsg, - "%s/%d %s failed, fd:%d, nbyte:%d errno=%d %s", - __FILE__, __LINE__, Lio_SysCall, fd, size, - errno, strerror(errno)); - if (sig) - sigrelse(sig); - return -errno; - } - - if (Debug_level > 1) - printf("DEBUG %s/%d: %s did not return -1\n", - __FILE__, __LINE__, Lio_SysCall); - - ret = lio_check_asyncio(io_type, size, &aiocbp, method); - return ret; -#endif - } - /* LIO_IO_SLISTIO */ - else if (method & LIO_IO_ALISTIO) { -#ifdef CRAY - request.li_opcode = LO_READ; - request.li_fildes = fd; - request.li_buf = buffer; - request.li_nbyte = size; - request.li_status = &status; - request.li_signo = sig; - request.li_nstride = 0; - request.li_filstride = 0; - request.li_memstride = 0; - - listio_cmd = LC_START; - io_type = "listio(2) async read"; - - sprintf(Lio_SysCall, - "listio(LC_START, &req, 1) LO_READ, fd:%d, nbyte:%d", - fd, size); - - if (Debug_level) { - printf("DEBUG %s/%d: %s\n", __FILE__, __LINE__, - Lio_SysCall); - } - - sigoff(); - if (listio(listio_cmd, &request, 1) == -1) { - sprintf(Errormsg, - "%s/%d %s failed, fd:%d, nbyte:%d errno=%d %s", - __FILE__, __LINE__, Lio_SysCall, fd, size, - errno, strerror(errno)); - sigon(); - return -errno; - } -#endif -#if defined(sgi) || (defined(__linux__) && !defined(__UCLIBC__)) - aiocbp.aio_lio_opcode = LIO_READ; - listio_cmd = LIO_NOWAIT; - io_type = "lio_listio(3) async read"; - - sprintf(Lio_SysCall, - "lio_listio(LIO_NOWAIT, aiolist, 1, NULL) LIO_READ, fd:%d, nbyte:%d", - fd, size); - - if (Debug_level) { - printf("DEBUG %s/%d: %s\n", __FILE__, __LINE__, - Lio_SysCall); - } - - if (sig) - sighold(sig); - if (lio_listio(listio_cmd, aiolist, 1, NULL) == -1) { - sprintf(Errormsg, - "%s/%d %s failed, fd:%d, nbyte:%d errno=%d %s", - __FILE__, __LINE__, Lio_SysCall, fd, size, - errno, strerror(errno)); - if (sig) - sigrelse(sig); - return -errno; - } -#endif - } - /* LIO_IO_ALISTIO */ -#ifndef CRAY - else if (method & LIO_IO_SYNCV) { - io_type = "readv(2)"; - - sprintf(Lio_SysCall, "readv(%d, &iov, 1) nbyte:%d", fd, size); - - if (Debug_level) { - printf("DEBUG %s/%d: %s\n", __FILE__, __LINE__, - Lio_SysCall); - } - if ((ret = readv(fd, &iov, 1)) == -1) { - sprintf(Errormsg, - "%s/%d readv(%d, iov, 1) nbyte:%d ret:-1, errno=%d %s", - __FILE__, __LINE__, fd, size, errno, - strerror(errno)); - return -errno; - } - - if (ret != size) { - sprintf(Errormsg, - "%s/%d readv(%d, iov, 1) nbyte:%d returned=%d", - __FILE__, __LINE__, fd, size, ret); - } else if (Debug_level > 1) - printf - ("DEBUG %s/%d: readv completed without error (ret %d)\n", - __FILE__, __LINE__, ret); - - return ret; - } /* LIO_IO_SYNCV */ -#endif - -#if defined(sgi) || (defined(__linux__) && !defined(__UCLIBC__)) - else if (method & LIO_IO_SYNCP) { - io_type = "pread(2)"; - - sprintf(Lio_SysCall, - "pread(%d, buf, %d, %lld)", fd, size, - (long long)poffset); - - if (Debug_level) { - printf("DEBUG %s/%d: %s\n", __FILE__, __LINE__, - Lio_SysCall); - } - if ((ret = pread(fd, buffer, size, poffset)) == -1) { - sprintf(Errormsg, - "%s/%d pread(%d, buf, %d, %lld) ret:-1, errno=%d %s", - __FILE__, __LINE__, fd, size, - (long long)poffset, errno, strerror(errno)); - return -errno; - } - - if (ret != size) { - sprintf(Errormsg, - "%s/%d pread(%d, buf, %d, %lld) returned=%d", - __FILE__, __LINE__, - fd, size, (long long)poffset, ret); - } else if (Debug_level > 1) - printf - ("DEBUG %s/%d: pread completed without error (ret %d)\n", - __FILE__, __LINE__, ret); - - return ret; - } /* LIO_IO_SYNCP */ -#endif - - else { - printf("DEBUG %s/%d: No I/O method chosen\n", __FILE__, - __LINE__); - return -1; - } - - /* - * wait for async io to complete. - * Note: Sync io should have returned prior to getting here. - */ -#ifdef CRAY - ret = lio_wait4asyncio(method, fd, statptr); -#endif -#if defined(sgi) || (defined(__linux__) && !defined(__UCLIBC__)) - ret = lio_wait4asyncio(method, fd, &aiocbp); -#endif - - /* - * If there was an error waiting for async i/o to complete, - * return the error value (errno) to the caller. - * Note: Errormsg should already have been updated. - */ - if (ret < 0) { - return ret; - } - - /* - * If i/o was not waited for (may not have been completed at this time), - * return the size that was requested. - */ - if (ret == 1) - return size; - - /* - * check that async io was successful. - * Note: if the there was an system call failure, -errno - * was returned and Errormsg should already have been updated. - * If amount i/o was different than size, Errormsg should already - * have been updated but the actual i/o size if returned. - */ - -#ifdef CRAY - ret = lio_check_asyncio(io_type, size, &status); -#endif -#if defined(sgi) || (defined(__linux__) && !defined(__UCLIBC__)) - ret = lio_check_asyncio(io_type, size, &aiocbp, method); -#endif - - return ret; -} /* end of lio_read_buffer */ - -#if !defined(__sun) && !defined(__hpux) && !defined(_AIX) -/*********************************************************************** - * This function will check that async io was successful. - * It can also be used to check sync listio since it uses the - * same method. - * - * Return Values - * If status.sw_error is set, -status.sw_error is returned. - * Otherwise sw_count's field value is returned. - * - * (rrl 04/96) - ***********************************************************************/ -#ifdef CRAY -int lio_check_asyncio(char *io_type, int size, struct iosw *status) -#elif defined(sgi) -int lio_check_asyncio(char *io_type, int size, aiocb_t * aiocbp, int method) -#elif defined(__linux__) && !defined(__UCLIBC__) -int lio_check_asyncio(char *io_type, int size, struct aiocb *aiocbp, int method) -{ - int ret; - -#ifdef CRAY - if (status->sw_error) { - sprintf(Errormsg, - "%s/%d %s, sw_error set = %d %s, sw_count = %d", - __FILE__, __LINE__, io_type, - status->sw_error, strerror(status->sw_error), - status->sw_count); - return -status->sw_error; - } else if (status->sw_count != size) { - sprintf(Errormsg, - "%s/%d %s, sw_count not as expected(%d), but actual:%d", - __FILE__, __LINE__, io_type, size, status->sw_count); - } else if (Debug_level > 1) { - printf - ("DEBUG %s/%d: %s completed without error (sw_error == 0, sw_count == %d)\n", - __FILE__, __LINE__, io_type, status->sw_count); - } - - return status->sw_count; - -#else - - int cnt = 1; - - /* The I/O may have been synchronous with signal completion. It doesn't - * make sense, but the combination could be generated. Release the - * completion signal here otherwise it'll hang around and bite us - * later. - */ - if (aiocbp->aio_sigevent.sigev_notify == SIGEV_SIGNAL) - sigrelse(aiocbp->aio_sigevent.sigev_signo); - - ret = aio_error(aiocbp); - - while (ret == EINPROGRESS) { - ret = aio_error(aiocbp); - ++cnt; - } - if (cnt > 1) { - sprintf(Errormsg, - "%s/%d %s, aio_error had to loop on EINPROGRESS, cnt=%d; random method %#o; sigev_notify=%s", - __FILE__, __LINE__, io_type, cnt, method, - (aiocbp->aio_sigevent.sigev_notify == - SIGEV_SIGNAL ? "signal" : aiocbp->aio_sigevent. - sigev_notify == SIGEV_NONE ? "none" : -#ifdef SIGEV_CALLBACK - aiocbp->aio_sigevent.sigev_notify == - SIGEV_CALLBACK ? "callback" : -#endif - aiocbp->aio_sigevent.sigev_notify == - SIGEV_THREAD ? "thread" : "unknown")); - return -ret; - } - - if (ret != 0) { - sprintf(Errormsg, - "%s/%d %s, aio_error = %d %s; random method %#o", - __FILE__, __LINE__, io_type, - ret, strerror(ret), method); - return -ret; - } - ret = aio_return(aiocbp); - if (ret != size) { - sprintf(Errormsg, - "%s/%d %s, aio_return not as expected(%d), but actual:%d", - __FILE__, __LINE__, io_type, size, ret); - -#ifdef BUG1_workaround - if (ret == 0) { - ret = size; - if (Debug_level > 1) { - printf - ("WARN %s/%d: %s completed with bug1_workaround (aio_error == 0, aio_return now == %d)\n", - __FILE__, __LINE__, io_type, ret); - } - } -#endif /* BUG1_workaround */ - - } else if (Debug_level > 1) { - printf - ("DEBUG %s/%d: %s completed without error (aio_error == 0, aio_return == %d)\n", - __FILE__, __LINE__, io_type, ret); - } - - return ret; - -#endif -} /* end of lio_check_asyncio */ -#endif - -/*********************************************************************** - * - * This function will wait for async io to complete. - * If multiple wait methods are specified, the order is predetermined - * to LIO_WAIT_RECALL, - * LIO_WAIT_ACTIVE, LIO_WAIT_SIGPAUSE, LIO_WAIT_SIGACTIVE, - * then LIO_WAIT_NONE. - * - * If no wait method was specified the default wait method is: recall(2) - * or aio_suspend(3), as appropriate. - * - * Return Values - * <0: errno of failed recall - * 0 : async io was completed - * 1 : async was not waited for, io may not have completed. - * - * (rrl 04/96) - ***********************************************************************/ -#ifdef CRAY -int lio_wait4asyncio(int method, int fd, struct iosw **statptr) -#elif defined(sgi) -int lio_wait4asyncio(int method, int fd, aiocb_t * aiocbp) -#elif defined(__linux__) && !defined(__UCLIBC__) -int lio_wait4asyncio(int method, int fd, struct aiocb *aiocbp) -{ - int cnt; -#ifdef sgi - int ret; - const aiocb_t *aioary[1]; -#endif -#if defined(__linux__)&& !defined(__UCLIBC__) - int ret; - const struct aiocb *aioary[1]; -#endif - - if ((method & LIO_WAIT_RECALL) -#if defined(sgi) || (defined(__linux__)&& !defined(__UCLIBC__)) - || (method & LIO_WAIT_CBSUSPEND) - || (method & LIO_WAIT_SIGSUSPEND) -#endif - || ((method & LIO_WAIT_TYPES) == 0)) { - /* - * If method has LIO_WAIT_RECALL bit set or method does - * not have any wait method bits set (default), use recall/aio_suspend. - */ -#ifdef CRAY - if (Debug_level > 2) - printf("DEBUG %s/%d: wait method : recall\n", __FILE__, - __LINE__); - sigon(); - if (recall(fd, 1, statptr)) { - sprintf(Errormsg, - "%s/%d recall(%d, 1, stat) failed, errno:%d %s", - __FILE__, __LINE__, fd, errno, strerror(errno)); - return -errno; - } -#else - if (Debug_level > 2) - printf - ("DEBUG %s/%d: wait method : aio_suspend, sigev_notify=%s\n", - __FILE__, __LINE__, - (aiocbp->aio_sigevent.sigev_notify == - SIGEV_SIGNAL ? "signal" : aiocbp->aio_sigevent. - sigev_notify == SIGEV_NONE ? "none" : -#ifdef SIGEV_CALLBACK - aiocbp->aio_sigevent.sigev_notify == - SIGEV_CALLBACK ? "callback" : -#endif - aiocbp->aio_sigevent.sigev_notify == - SIGEV_THREAD ? "thread" : "unknown")); - - aioary[0] = aiocbp; - ret = aio_suspend(aioary, 1, NULL); - if ((ret == -1) && (errno == EINTR)) { - if (aiocbp->aio_sigevent.sigev_notify == SIGEV_SIGNAL) { - if (Debug_level > 2) { - printf - ("DEBUG %s/%d: aio_suspend received EINTR, sigev_notify=SIGEV_SIGNAL -- ok\n", - __FILE__, __LINE__); - } - } else { - sprintf(Errormsg, - "%s/%d aio_suspend received EINTR, sigev_notify=%s, not ok\n", - __FILE__, __LINE__, - (aiocbp->aio_sigevent.sigev_notify == - SIGEV_SIGNAL ? "signal" : aiocbp-> - aio_sigevent.sigev_notify == - SIGEV_NONE ? "none" : -#ifdef SIGEV_CALLBACK - aiocbp->aio_sigevent.sigev_notify == - SIGEV_CALLBACK ? "callback" : -#endif - aiocbp->aio_sigevent.sigev_notify == - SIGEV_THREAD ? "thread" : "unknown")); - return -errno; - } - } else if (ret) { - sprintf(Errormsg, - "%s/%d aio_suspend(fildes=%d, aioary, 1, NULL) failed, errno:%d %s", - __FILE__, __LINE__, fd, errno, strerror(errno)); - return -errno; - } -#endif - - } else if (method & LIO_WAIT_ACTIVE) { - if (Debug_level > 2) - printf("DEBUG %s/%d: wait method : active\n", __FILE__, - __LINE__); -#ifdef CRAY - sigon(); - /* - * loop until sw_flag, sw_count or sw_error field elements - * change to non-zero. - */ - cnt = 0; - while ((*statptr)->sw_flag == 0 && - (*statptr)->sw_count == 0 && (*statptr)->sw_error == 0) { - cnt++; - } -#else - /* loop while aio_error() returns EINPROGRESS */ - cnt = 0; - while (1) { - ret = aio_error(aiocbp); - if (ret != EINPROGRESS) { - break; - } - ++cnt; - } - -#endif - if (Debug_level > 5 && cnt && (cnt % 50) == 0) - printf("DEBUG %s/%d: wait active cnt = %d\n", - __FILE__, __LINE__, cnt); - - } else if (method & LIO_WAIT_SIGPAUSE) { - if (Debug_level > 2) - printf("DEBUG %s/%d: wait method : sigpause\n", - __FILE__, __LINE__); -#ifdef sgi - /* note: don't do the sigon() for CRAY in this case. why? -- roehrich 6/11/97 */ - if (aiocbp->aio_sigevent.sigev_notify == SIGEV_SIGNAL) - sigrelse(aiocbp->aio_sigevent.sigev_signo); - else { - printf("DEBUG %s/%d: sigev_notify != SIGEV_SIGNAL\n", - __FILE__, __LINE__); - return -1; - } -#endif - pause(); - - } else if (method & LIO_WAIT_SIGACTIVE) { - if (Debug_level > 2) - printf("DEBUG %s/%d: wait method : sigactive\n", - __FILE__, __LINE__); -#ifdef CRAY - sigon(); -#else - if (aiocbp->aio_sigevent.sigev_notify == SIGEV_SIGNAL) - sigrelse(aiocbp->aio_sigevent.sigev_signo); - else { - printf("DEBUG %s/%d: sigev_notify != SIGEV_SIGNAL\n", - __FILE__, __LINE__); - return -1; - } -#endif - /* loop waiting for signal */ - while (Received_signal == Rec_signal) { -#ifdef CRAY - sigon(); -#else - sigrelse(aiocbp->aio_sigevent.sigev_signo); -#endif - } - - } else if (method & LIO_WAIT_NONE) { - if (Debug_level > 2) - printf("DEBUG %s/%d: wait method : none\n", __FILE__, - __LINE__); - /* It's broken because the aiocb/iosw is an automatic variable in - * lio_{read,write}_buffer, so when the function returns and the - * I/O completes there will be nowhere to write the I/O status. - * It doesn't cause a problem on unicos--probably because of some - * compiler quirk, or an accident. It causes POSIX async I/O - * to core dump some threads. spr/pv 705909. 6/27/97 roehrich - */ - sprintf(Errormsg, - "%s/%d LIO_WAIT_NONE was selected (this is broken)\n", - __FILE__, __LINE__); -#ifdef CRAY - sigon(); -#endif -/* return 1;*/ - return -1; - } else { - if (Debug_level > 2) - printf("DEBUG %s/%d: no wait method was chosen\n", - __FILE__, __LINE__); - return -1; - } - - return 0; - -} /* end of lio_wait4asyncio */ - -#endif /* ifndef linux */ -#endif - -#if UNIT_TEST -/*********************************************************************** - * The following code is provided as unit test. - * Just define add "-DUNIT_TEST=1" to the cc line. - * - * (rrl 04/96) - ***********************************************************************/ -struct unit_info_t { - int method; - int sig; - char *str; -} Unit_info[] = { - { - LIO_IO_SYNC, 0, "sync io"}, { - LIO_IO_SYNCV, 0, "sync readv/writev"}, { - LIO_IO_SYNCP, 0, "sync pread/pwrite"}, { - LIO_IO_ASYNC, 0, "async io, def wait"}, { - LIO_IO_SLISTIO, 0, "sync listio"}, { - LIO_IO_ALISTIO, 0, "async listio, def wait"}, { - LIO_IO_ASYNC | LIO_WAIT_ACTIVE, 0, "async active"}, { - LIO_IO_ASYNC | LIO_WAIT_RECALL, 0, "async recall/suspend"}, { - LIO_IO_ASYNC | LIO_WAIT_SIGPAUSE, SIGUSR1, "async sigpause"}, { - LIO_IO_ASYNC | LIO_WAIT_SIGACTIVE, SIGUSR1, "async sigactive"}, { - LIO_IO_ALISTIO | LIO_WAIT_ACTIVE, 0, "async listio active"}, { - LIO_IO_ALISTIO | LIO_WAIT_RECALL, 0, "async listio recall"}, { - LIO_IO_ALISTIO | LIO_WAIT_SIGACTIVE, SIGUSR1, "async listio sigactive"}, - { - LIO_IO_ALISTIO | LIO_WAIT_SIGPAUSE, SIGUSR1, "async listio sigpause"}, - { - LIO_IO_ASYNC, SIGUSR2, "async io, def wait, sigusr2"}, { -LIO_IO_ALISTIO, SIGUSR2, "async listio, def wait, sigusr2"},}; - -int main(argc, argv) -int argc; -char **argv; -{ - extern char *optarg; - extern int optind; - - int fd; - char *err; - char buffer[4096]; - int size = 4096; - int ret; - int ind; - int iter = 3; - int method; - int exit_status = 0; - int c; - int i; - char *symbols = NULL; - int die_on_err = 0; - - while ((c = getopt(argc, argv, "s:di:")) != -1) { - switch (c) { - case 's': - symbols = optarg; - break; - case 'd': - ++die_on_err; - break; - case 'i': - iter = atoi(optarg); - break; - } - } - - if ((fd = - open("unit_test_file", O_CREAT | O_RDWR | O_TRUNC, 0777)) == -1) { - perror - ("open(unit_test_file, O_CREAT|O_RDWR|O_TRUNC, 0777) failed"); - exit(1); - } - - Debug_level = 9; - - if (symbols != NULL) { - if ((method = lio_parse_io_arg2(symbols, &err)) == -1) { - printf - ("lio_parse_io_arg2(%s, &err) failed, bad token starting at %s\n", - symbols, err); - if (die_on_err) - exit(1); - } else - printf("lio_parse_io_arg2(%s, &err) returned %#o\n", - symbols, method); - - exit_status = 0; - for (ind = 0; ind < iter; ind++) { - memset(buffer, 'A', 4096); - if (lseek(fd, 0, 0) == -1) { - printf("lseek(fd,0,0), %d, failed, errno %d\n", - __LINE__, errno); - ++exit_status; - } - if ((ret = lio_write_buffer(fd, method, buffer, - size, SIGUSR1, &err, - 0)) != size) { - printf - ("lio_write_buffer returned -1, err = %s\n", - err); - } else - printf("lio_write_buffer returned %d\n", ret); - - memset(buffer, 'B', 4096); - if (lseek(fd, 0, 0) == -1) { - printf("lseek(fd,0,0), %d, failed, errno %d\n", - __LINE__, errno); - ++exit_status; - } - if ((ret = lio_read_buffer(fd, method, buffer, - size, SIGUSR2, &err, - 0)) != size) { - printf - ("lio_read_buffer returned -1, err = %s\n", - err); - } else - printf("lio_read_buffer returned %d\n", ret); - - for (i = 0; i < 4096; ++i) { - if (buffer[i] != 'A') { - printf(" buffer[%d] = %d\n", i, - buffer[i]); - ++exit_status; - break; - } - } - - if (exit_status) - exit(exit_status); - - } - - unlink("unit_test_file"); - exit(0); - } - - for (ind = 0; ind < sizeof(Unit_info) / sizeof(struct unit_info_t); - ind++) { - - printf("\n********* write %s ***************\n", - Unit_info[ind].str); - if (lseek(fd, 0, 0) == -1) { - printf("lseek(fd,0,0), %d, failed, errno %d\n", - __LINE__, errno); - ++exit_status; - } - - memset(buffer, 'A', 4096); - if ((ret = lio_write_buffer(fd, Unit_info[ind].method, buffer, - size, Unit_info[ind].sig, &err, - 0)) != size) { - printf - (">>>>> lio_write_buffer(fd,0%x,buffer,%d,%d,err,0) returned -1,\n err = %s\n", - Unit_info[ind].method, size, Unit_info[ind].sig, - err); - ++exit_status; - if (die_on_err) - exit(exit_status); - } else { - printf("lio_write_buffer returned %d\n", ret); - } - - printf("\n********* read %s ***************\n", - Unit_info[ind].str); - if (lseek(fd, 0, 0) == -1) { - printf("lseek(fd,0,0), %d, failed, errno %d\n", - __LINE__, errno); - ++exit_status; - } - memset(buffer, 'B', 4096); - if ((ret = lio_read_buffer(fd, Unit_info[ind].method, buffer, - size, Unit_info[ind].sig, &err, - 0)) != size) { - printf - (">>>>> lio_read_buffer(fd,0%x,buffer,%d,%d,err,0) returned -1,\n err = %s\n", - Unit_info[ind].method, size, Unit_info[ind].sig, - err); - ++exit_status; - if (die_on_err) - exit(exit_status); - } else { - printf("lio_read_buffer returned %d\n", ret); - } - - for (i = 0; i < 4096; ++i) { - if (buffer[i] != 'A') { - printf(" buffer[%d] = %d\n", i, buffer[i]); - ++exit_status; - if (die_on_err) - exit(exit_status); - break; - } - } - - fflush(stdout); - fflush(stderr); - sleep(1); - - } - - unlink("unit_test_file"); - - exit(exit_status); -} -#endif diff --git a/kernel/tests/lib/tst_af_alg.c b/kernel/tests/lib/tst_af_alg.c deleted file mode 100644 index d3895a8..0000000 --- a/kernel/tests/lib/tst_af_alg.c +++ /dev/null @@ -1,212 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright 2019 Google LLC - */ - -#include <errno.h> -#include <stdlib.h> - -#define TST_NO_DEFAULT_MAIN -#include "tst_test.h" -#include "tst_af_alg.h" -#include "lapi/socket.h" - -int tst_alg_create(void) -{ - TEST(socket(AF_ALG, SOCK_SEQPACKET, 0)); - if (TST_RET >= 0) - return TST_RET; - if (TST_ERR == EAFNOSUPPORT) - tst_brk(TCONF, "kernel doesn't support AF_ALG"); - tst_brk(TBROK | TTERRNO, "unexpected error creating AF_ALG socket"); - return -1; -} - -void tst_alg_bind_addr(int algfd, const struct sockaddr_alg *addr) -{ - TEST(bind(algfd, (const struct sockaddr *)addr, sizeof(*addr))); - if (TST_RET == 0) - return; - if (TST_ERR == ENOENT) { - tst_brk(TCONF, "kernel doesn't support %s algorithm '%s'", - addr->salg_type, addr->salg_name); - } - tst_brk(TBROK | TTERRNO, - "unexpected error binding AF_ALG socket to %s algorithm '%s'", - addr->salg_type, addr->salg_name); -} - -static void init_sockaddr_alg(struct sockaddr_alg *addr, - const char *algtype, const char *algname) -{ - memset(addr, 0, sizeof(*addr)); - - addr->salg_family = AF_ALG; - - strncpy((char *)addr->salg_type, algtype, sizeof(addr->salg_type)); - if (addr->salg_type[sizeof(addr->salg_type) - 1] != '\0') - tst_brk(TBROK, "algorithm type too long: '%s'", algtype); - - strncpy((char *)addr->salg_name, algname, sizeof(addr->salg_name)); - if (addr->salg_name[sizeof(addr->salg_name) - 1] != '\0') - tst_brk(TBROK, "algorithm name too long: '%s'", algname); -} - -void tst_alg_bind(int algfd, const char *algtype, const char *algname) -{ - struct sockaddr_alg addr; - - init_sockaddr_alg(&addr, algtype, algname); - - tst_alg_bind_addr(algfd, &addr); -} - -bool tst_have_alg(const char *algtype, const char *algname) -{ - int algfd; - struct sockaddr_alg addr; - bool have_alg = true; - - algfd = tst_alg_create(); - - init_sockaddr_alg(&addr, algtype, algname); - - TEST(bind(algfd, (const struct sockaddr *)&addr, sizeof(addr))); - if (TST_RET != 0) { - if (TST_ERR != ENOENT) { - tst_brk(TBROK | TTERRNO, - "unexpected error binding AF_ALG socket to %s algorithm '%s'", - algtype, algname); - } - have_alg = false; - } - - close(algfd); - return have_alg; -} - -void tst_require_alg(const char *algtype, const char *algname) -{ - int algfd = tst_alg_create(); - - tst_alg_bind(algfd, algtype, algname); - - close(algfd); -} - -void tst_alg_setkey(int algfd, const uint8_t *key, unsigned int keylen) -{ - uint8_t *keybuf = NULL; - unsigned int i; - - if (key == NULL) { - /* generate a random key */ - keybuf = SAFE_MALLOC(keylen); - for (i = 0; i < keylen; i++) - keybuf[i] = rand(); - key = keybuf; - } - TEST(setsockopt(algfd, SOL_ALG, ALG_SET_KEY, key, keylen)); - if (TST_RET != 0) { - tst_brk(TBROK | TTERRNO, - "unexpected error setting key (len=%u)", keylen); - } - free(keybuf); -} - -int tst_alg_accept(int algfd) -{ - TEST(accept(algfd, NULL, NULL)); - if (TST_RET < 0) { - tst_brk(TBROK | TTERRNO, - "unexpected error accept()ing AF_ALG request socket"); - } - return TST_RET; -} - -int tst_alg_setup(const char *algtype, const char *algname, - const uint8_t *key, unsigned int keylen) -{ - int algfd = tst_alg_create(); - - tst_alg_bind(algfd, algtype, algname); - - if (keylen != 0) - tst_alg_setkey(algfd, key, keylen); - - return algfd; -} - -int tst_alg_setup_reqfd(const char *algtype, const char *algname, - const uint8_t *key, unsigned int keylen) -{ - int algfd = tst_alg_setup(algtype, algname, key, keylen); - int reqfd = tst_alg_accept(algfd); - - close(algfd); - return reqfd; -} - -void tst_alg_sendmsg(int reqfd, const void *data, size_t datalen, - const struct tst_alg_sendmsg_params *params) -{ - struct iovec iov = { - .iov_base = (void *)data, - .iov_len = datalen, - }; - struct msghdr msg = { - .msg_iov = &iov, - .msg_iovlen = 1, - .msg_flags = params->msg_flags, - }; - size_t controllen; - uint8_t *control; - struct cmsghdr *cmsg; - struct af_alg_iv *alg_iv; - - if (params->encrypt && params->decrypt) - tst_brk(TBROK, "Both encrypt and decrypt are specified"); - - controllen = 0; - if (params->encrypt || params->decrypt) - controllen += CMSG_SPACE(sizeof(uint32_t)); - if (params->ivlen) - controllen += CMSG_SPACE(sizeof(struct af_alg_iv) + - params->ivlen); - if (params->assoclen) - controllen += CMSG_SPACE(sizeof(uint32_t)); - - control = SAFE_MALLOC(controllen); - memset(control, 0, controllen); - msg.msg_control = control; - msg.msg_controllen = controllen; - cmsg = CMSG_FIRSTHDR(&msg); - - if (params->encrypt || params->decrypt) { - cmsg->cmsg_level = SOL_ALG; - cmsg->cmsg_type = ALG_SET_OP; - cmsg->cmsg_len = CMSG_LEN(sizeof(uint32_t)); - *(uint32_t *)CMSG_DATA(cmsg) = - params->encrypt ? ALG_OP_ENCRYPT : ALG_OP_DECRYPT; - cmsg = CMSG_NXTHDR(&msg, cmsg); - } - if (params->ivlen) { - cmsg->cmsg_level = SOL_ALG; - cmsg->cmsg_type = ALG_SET_IV; - cmsg->cmsg_len = CMSG_LEN(sizeof(struct af_alg_iv) + - params->ivlen); - alg_iv = (struct af_alg_iv *)CMSG_DATA(cmsg); - alg_iv->ivlen = params->ivlen; - memcpy(alg_iv->iv, params->iv, params->ivlen); - cmsg = CMSG_NXTHDR(&msg, cmsg); - } - if (params->assoclen) { - cmsg->cmsg_level = SOL_ALG; - cmsg->cmsg_type = ALG_SET_AEAD_ASSOCLEN; - cmsg->cmsg_len = CMSG_LEN(sizeof(uint32_t)); - *(uint32_t *)CMSG_DATA(cmsg) = params->assoclen; - cmsg = CMSG_NXTHDR(&msg, cmsg); - } - - SAFE_SENDMSG(datalen, reqfd, &msg, 0); -} diff --git a/kernel/tests/lib/tst_ansi_color.c b/kernel/tests/lib/tst_ansi_color.c deleted file mode 100644 index 1c29268..0000000 --- a/kernel/tests/lib/tst_ansi_color.c +++ /dev/null @@ -1,64 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (c) 2017 Petr Vorel <pvorel@suse.cz> - */ - -#include <unistd.h> -#include <stdlib.h> -#include <string.h> - -#include "tst_res_flags.h" -#include "tst_ansi_color.h" - -char* tst_ttype2color(int ttype) -{ - switch (TTYPE_RESULT(ttype)) { - case TPASS: - return ANSI_COLOR_GREEN; - break; - case TFAIL: - return ANSI_COLOR_RED; - break; - case TBROK: - return ANSI_COLOR_RED; - break; - case TCONF: - return ANSI_COLOR_YELLOW; - break; - case TWARN: - return ANSI_COLOR_MAGENTA; - break; - case TINFO: - return ANSI_COLOR_BLUE; - break; - default: - return ""; - } -} - -int tst_color_enabled(int fd) -{ - static int color; - - if (color) - return color - 1; - - char *env = getenv("LTP_COLORIZE_OUTPUT"); - - if (env) { - if (!strcmp(env, "n") || !strcmp(env, "0")) - color = 1; - - if (!strcmp(env, "y") || !strcmp(env, "1")) - color = 2; - - return color - 1; - } - - if (isatty(fd) == 0) - color = 1; - else - color = 2; - - return color - 1; -} diff --git a/kernel/tests/lib/tst_assert.c b/kernel/tests/lib/tst_assert.c deleted file mode 100644 index 9b8ebc1..0000000 --- a/kernel/tests/lib/tst_assert.c +++ /dev/null @@ -1,83 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (c) 2020 FUJITSU LIMITED. All rights reserved. - * Author: Yang Xu <xuyang2018.jy@cn.fujitsu.com> - * Copyright (c) 2020 Cyril Hrubis <chrubis@suse.cz> - */ -#include <stdio.h> -#define TST_NO_DEFAULT_MAIN -#include "tst_assert.h" -#include "tst_test.h" - -void tst_assert_int(const char *file, const int lineno, const char *path, int val) -{ - int sys_val; - - safe_file_scanf(file, lineno, NULL, path, "%d", &sys_val); - - if (val == sys_val) { - tst_res_(file, lineno, TPASS, "%s = %d", path, val); - return; - } - - tst_res_(file, lineno, TFAIL, "%s != %d got %d", path, val, sys_val); -} - -void tst_assert_ulong(const char *file, const int lineno, const char *path, unsigned long val) -{ - unsigned long sys_val; - - safe_file_scanf(file, lineno, NULL, path, "%lu", &sys_val); - - if (val == sys_val) { - tst_res_(file, lineno, TPASS, "%s = %lu", path, val); - return; - } - - tst_res_(file, lineno, TFAIL, "%s != %lu got %lu", path, val, sys_val); -} - -void tst_assert_file_int(const char *file, const int lineno, const char *path, const char *prefix, int val) -{ - int sys_val; - char fmt[1024]; - - snprintf(fmt, sizeof(fmt), "%s%%d", prefix); - file_lines_scanf(file, lineno, NULL, 1, path, fmt, &sys_val); - - if (val == sys_val) { - tst_res_(file, lineno, TPASS, "%s %s = %d", path, prefix, sys_val); - return; - } - - tst_res_(file, lineno, TFAIL, "%s %s != %d got %d", path, prefix, val, sys_val); -} - -void tst_assert_str(const char *file, const int lineno, const char *path, const char *val) -{ - char sys_val[1024]; - - safe_file_scanf(file, lineno, NULL, path, "%1024s", sys_val); - if (!strcmp(val, sys_val)) { - tst_res_(file, lineno, TPASS, "%s = '%s'", path, val); - return; - } - - tst_res_(file, lineno, TFAIL, "%s != '%s' got '%s'", path, val, sys_val); -} - -void tst_assert_file_str(const char *file, const int lineno, const char *path, const char *prefix, const char *val) -{ - char sys_val[1024]; - char fmt[2048]; - - snprintf(fmt, sizeof(fmt), "%s: %%1024s", prefix); - file_lines_scanf(file, lineno, NULL, 1, path, fmt, sys_val); - - if (!strcmp(val, sys_val)) { - tst_res_(file, lineno, TPASS, "%s %s = '%s'", path, prefix, sys_val); - return; - } - - tst_res_(file, lineno, TFAIL, "%s %s != '%s' got '%s'", path, prefix, val, sys_val); -} diff --git a/kernel/tests/lib/tst_buffers.c b/kernel/tests/lib/tst_buffers.c deleted file mode 100644 index b8b597a..0000000 --- a/kernel/tests/lib/tst_buffers.c +++ /dev/null @@ -1,143 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (c) 2019 Cyril Hrubis <chrubis@suse.cz> - */ - -#include <sys/mman.h> -#include <stdlib.h> -#define TST_NO_DEFAULT_MAIN -#include "tst_test.h" - -struct map { - void *addr; - size_t size; - size_t buf_shift; - struct map *next; -}; - -static struct map *maps; - -static void setup_canary(struct map *map) -{ - size_t i; - char *buf = map->addr; - - for (i = 0; i < map->buf_shift/2; i++) { - char c = random(); - buf[map->buf_shift - i - 1] = c; - buf[i] = c; - } -} - -static void check_canary(struct map *map) -{ - size_t i; - char *buf = map->addr; - - for (i = 0; i < map->buf_shift/2; i++) { - if (buf[map->buf_shift - i - 1] != buf[i]) { - tst_res(TWARN, - "pid %i: buffer modified address %p[%zi]", - getpid(), (char*)map->addr + map->buf_shift, -i-1); - } - } -} - -void *tst_alloc(size_t size) -{ - size_t page_size = getpagesize(); - unsigned int pages = (size / page_size) + !!(size % page_size) + 1; - void *ret; - struct map *map = SAFE_MALLOC(sizeof(struct map)); - static int print_msg = 1; - - if (print_msg) { - tst_res(TINFO, "Test is using guarded buffers"); - print_msg = 0; - } - - ret = SAFE_MMAP(NULL, page_size * pages, PROT_READ | PROT_WRITE, - MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); - - mprotect(ret + (pages-1) * page_size, page_size, PROT_NONE); - - map->addr = ret; - map->size = pages * page_size; - map->next = maps; - maps = map; - - if (size % page_size) - map->buf_shift = page_size - (size % page_size); - else - map->buf_shift = 0; - - setup_canary(map); - - return ret + map->buf_shift; -} - -static int count_iovec(int *sizes) -{ - int ret = 0; - - while (sizes[ret++] != -1); - - return ret - 1; -} - -struct iovec *tst_iovec_alloc(int sizes[]) -{ - int i, cnt = count_iovec(sizes); - struct iovec *iovec; - - if (cnt <= 0) - return NULL; - - iovec = tst_alloc(sizeof(struct iovec) * cnt); - - for (i = 0; i < cnt; i++) { - if (sizes[i]) { - iovec[i].iov_base = tst_alloc(sizes[i]); - iovec[i].iov_len = sizes[i]; - } else { - iovec[i].iov_base = NULL; - iovec[i].iov_base = 0; - } - } - - return iovec; -} - -void tst_buffers_alloc(struct tst_buffers bufs[]) -{ - unsigned int i; - - for (i = 0; bufs[i].ptr; i++) { - if (bufs[i].size) - *((void**)bufs[i].ptr) = tst_alloc(bufs[i].size); - else - *((void**)bufs[i].ptr) = tst_iovec_alloc(bufs[i].iov_sizes); - } -} - -char *tst_strdup(const char *str) -{ - size_t len = strlen(str); - char *ret = tst_alloc(len + 1); - return strcpy(ret, str); -} - -void tst_free_all(void) -{ - struct map *i = maps; - - while (i) { - struct map *j = i; - check_canary(i); - SAFE_MUNMAP(i->addr, i->size); - i = i->next; - free(j); - } - - maps = NULL; -} diff --git a/kernel/tests/lib/tst_capability.c b/kernel/tests/lib/tst_capability.c deleted file mode 100644 index 1fa0e49..0000000 --- a/kernel/tests/lib/tst_capability.c +++ /dev/null @@ -1,90 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (c) 2019 Richard Palethorpe <rpalethorpe@suse.com> - */ - -#include <string.h> - -#define TST_NO_DEFAULT_MAIN -#include "tst_test.h" -#include "tst_capability.h" - -#include "lapi/syscalls.h" - -int tst_capget(struct tst_cap_user_header *hdr, - struct tst_cap_user_data *data) -{ - return tst_syscall(__NR_capget, hdr, data); -} - -int tst_capset(struct tst_cap_user_header *hdr, - const struct tst_cap_user_data *data) -{ - return tst_syscall(__NR_capset, hdr, data); -} - -static void do_cap_drop(uint32_t *set, uint32_t mask, const struct tst_cap *cap) -{ - if (*set & mask) { - tst_res(TINFO, "Dropping %s(%d)", cap->name, cap->id); - *set &= ~mask; - } -} - -static void do_cap_req(uint32_t *permitted, uint32_t *effective, uint32_t mask, - const struct tst_cap *cap) -{ - if (!(*permitted & mask)) - tst_brk(TCONF, "Need %s(%d)", cap->name, cap->id); - - if (!(*effective & mask)) { - tst_res(TINFO, "Permitting %s(%d)", cap->name, cap->id); - *effective |= mask; - } -} - -void tst_cap_action(struct tst_cap *cap) -{ - struct tst_cap_user_header hdr = { - .version = 0x20080522, - .pid = tst_syscall(__NR_gettid), - }; - struct tst_cap_user_data cur[2] = { {0} }; - struct tst_cap_user_data new[2] = { {0} }; - uint32_t act = cap->action; - uint32_t *pE = &new[CAP_TO_INDEX(cap->id)].effective; - uint32_t *pP = &new[CAP_TO_INDEX(cap->id)].permitted; - uint32_t mask = CAP_TO_MASK(cap->id); - - if (tst_capget(&hdr, cur)) - tst_brk(TBROK | TTERRNO, "tst_capget()"); - - memcpy(new, cur, sizeof(new)); - - switch (act) { - case TST_CAP_DROP: - do_cap_drop(pE, mask, cap); - break; - case TST_CAP_REQ: - do_cap_req(pP, pE, mask, cap); - break; - default: - tst_brk(TBROK, "Unrecognised action %d", cap->action); - } - - if (!memcmp(cur, new, sizeof(new))) - return; - - if (tst_capset(&hdr, new)) - tst_brk(TBROK | TERRNO, "tst_capset(%s)", cap->name); -} - -void tst_cap_setup(struct tst_cap *caps, unsigned int action_mask) -{ - struct tst_cap *cap; - - for (cap = caps; cap->action; cap++) { - if (cap->action & action_mask) - tst_cap_action(cap); - } -} diff --git a/kernel/tests/lib/tst_cgroup.c b/kernel/tests/lib/tst_cgroup.c deleted file mode 100644 index ba413d8..0000000 --- a/kernel/tests/lib/tst_cgroup.c +++ /dev/null @@ -1,452 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (c) 2020 Red Hat, Inc. - * Copyright (c) 2020 Li Wang <liwang@redhat.com> - */ - -#define TST_NO_DEFAULT_MAIN - -#include <stdio.h> -#include <stdlib.h> -#include <sys/mount.h> -#include <fcntl.h> -#include <unistd.h> - -#include "tst_test.h" -#include "tst_safe_macros.h" -#include "tst_safe_stdio.h" -#include "tst_cgroup.h" -#include "tst_device.h" - -static enum tst_cgroup_ver tst_cg_ver; -static int clone_children; - -static int tst_cgroup_check(const char *cgroup) -{ - char line[PATH_MAX]; - FILE *file; - int cg_check = 0; - - file = SAFE_FOPEN("/proc/filesystems", "r"); - while (fgets(line, sizeof(line), file)) { - if (strstr(line, cgroup) != NULL) { - cg_check = 1; - break; - } - } - SAFE_FCLOSE(file); - - return cg_check; -} - -enum tst_cgroup_ver tst_cgroup_version(void) -{ - enum tst_cgroup_ver cg_ver; - - if (tst_cgroup_check("cgroup2")) { - if (!tst_is_mounted("cgroup2") && tst_is_mounted("cgroup")) - cg_ver = TST_CGROUP_V1; - else - cg_ver = TST_CGROUP_V2; - - goto out; - } - - if (tst_cgroup_check("cgroup")) - cg_ver = TST_CGROUP_V1; - - if (!cg_ver) - tst_brk(TCONF, "Cgroup is not configured"); - -out: - return cg_ver; -} - -static void tst_cgroup1_mount(const char *name, const char *option, - const char *mnt_path, const char *new_path) -{ - char knob_path[PATH_MAX]; - if (tst_is_mounted(mnt_path)) - goto out; - - SAFE_MKDIR(mnt_path, 0777); - if (mount(name, mnt_path, "cgroup", 0, option) == -1) { - if (errno == ENODEV) { - if (rmdir(mnt_path) == -1) - tst_res(TWARN | TERRNO, "rmdir %s failed", mnt_path); - tst_brk(TCONF, - "Cgroup v1 is not configured in kernel"); - } - tst_brk(TBROK | TERRNO, "mount %s", mnt_path); - } - - /* - * We should assign one or more memory nodes to cpuset.mems and - * cpuset.cpus, otherwise, echo $$ > tasks gives “ENOSPC: no space - * left on device” when trying to use cpuset. - * - * Or, setting cgroup.clone_children to 1 can help in automatically - * inheriting memory and node setting from parent cgroup when a - * child cgroup is created. - */ - if (strcmp(option, "cpuset") == 0) { - sprintf(knob_path, "%s/cgroup.clone_children", mnt_path); - SAFE_FILE_SCANF(knob_path, "%d", &clone_children); - SAFE_FILE_PRINTF(knob_path, "%d", 1); - } -out: - SAFE_MKDIR(new_path, 0777); - - tst_res(TINFO, "Cgroup(%s) v1 mount at %s success", option, mnt_path); -} - -static void tst_cgroup2_mount(const char *mnt_path, const char *new_path) -{ - if (tst_is_mounted(mnt_path)) - goto out; - - SAFE_MKDIR(mnt_path, 0777); - if (mount("cgroup2", mnt_path, "cgroup2", 0, NULL) == -1) { - if (errno == ENODEV) { - if (rmdir(mnt_path) == -1) - tst_res(TWARN | TERRNO, "rmdir %s failed", mnt_path); - tst_brk(TCONF, - "Cgroup v2 is not configured in kernel"); - } - tst_brk(TBROK | TERRNO, "mount %s", mnt_path); - } - -out: - SAFE_MKDIR(new_path, 0777); - - tst_res(TINFO, "Cgroup v2 mount at %s success", mnt_path); -} - -static void tst_cgroupN_umount(const char *mnt_path, const char *new_path) -{ - FILE *fp; - int fd; - char s_new[BUFSIZ], s[BUFSIZ], value[BUFSIZ]; - char knob_path[PATH_MAX]; - - if (!tst_is_mounted(mnt_path)) - return; - - /* Move all processes in task(v2: cgroup.procs) to its parent node. */ - if (tst_cg_ver & TST_CGROUP_V1) - sprintf(s, "%s/tasks", mnt_path); - if (tst_cg_ver & TST_CGROUP_V2) - sprintf(s, "%s/cgroup.procs", mnt_path); - - fd = open(s, O_WRONLY); - if (fd == -1) - tst_res(TWARN | TERRNO, "open %s", s); - - if (tst_cg_ver & TST_CGROUP_V1) - snprintf(s_new, BUFSIZ, "%s/tasks", new_path); - if (tst_cg_ver & TST_CGROUP_V2) - snprintf(s_new, BUFSIZ, "%s/cgroup.procs", new_path); - - fp = fopen(s_new, "r"); - if (fp == NULL) - tst_res(TWARN | TERRNO, "fopen %s", s_new); - if ((fd != -1) && (fp != NULL)) { - while (fgets(value, BUFSIZ, fp) != NULL) - if (write(fd, value, strlen(value) - 1) - != (ssize_t)strlen(value) - 1) - tst_res(TWARN | TERRNO, "write %s", s); - } - if (tst_cg_ver & TST_CGROUP_V1) { - sprintf(knob_path, "%s/cpuset.cpus", mnt_path); - if (!access(knob_path, F_OK)) { - sprintf(knob_path, "%s/cgroup.clone_children", mnt_path); - SAFE_FILE_PRINTF(knob_path, "%d", clone_children); - } - } - if (fd != -1) - close(fd); - if (fp != NULL) - fclose(fp); - if (rmdir(new_path) == -1) - tst_res(TWARN | TERRNO, "rmdir %s", new_path); - if (umount(mnt_path) == -1) - tst_res(TWARN | TERRNO, "umount %s", mnt_path); - if (rmdir(mnt_path) == -1) - tst_res(TWARN | TERRNO, "rmdir %s", mnt_path); - - if (tst_cg_ver & TST_CGROUP_V1) - tst_res(TINFO, "Cgroup v1 unmount success"); - if (tst_cg_ver & TST_CGROUP_V2) - tst_res(TINFO, "Cgroup v2 unmount success"); -} - -struct tst_cgroup_path { - char *mnt_path; - char *new_path; - struct tst_cgroup_path *next; -}; - -static struct tst_cgroup_path *tst_cgroup_paths; - -static void tst_cgroup_set_path(const char *cgroup_dir) -{ - char cgroup_new_dir[PATH_MAX]; - struct tst_cgroup_path *tst_cgroup_path, *a; - - if (!cgroup_dir) - tst_brk(TBROK, "Invalid cgroup dir, plese check cgroup_dir"); - - sprintf(cgroup_new_dir, "%s/ltp_%d", cgroup_dir, rand()); - - /* To store cgroup path in the 'path' list */ - tst_cgroup_path = SAFE_MALLOC(sizeof(struct tst_cgroup_path)); - tst_cgroup_path->mnt_path = SAFE_MALLOC(strlen(cgroup_dir) + 1); - tst_cgroup_path->new_path = SAFE_MALLOC(strlen(cgroup_new_dir) + 1); - tst_cgroup_path->next = NULL; - - if (!tst_cgroup_paths) { - tst_cgroup_paths = tst_cgroup_path; - } else { - a = tst_cgroup_paths; - do { - if (!a->next) { - a->next = tst_cgroup_path; - break; - } - a = a->next; - } while (a); - } - - sprintf(tst_cgroup_path->mnt_path, "%s", cgroup_dir); - sprintf(tst_cgroup_path->new_path, "%s", cgroup_new_dir); -} - -static char *tst_cgroup_get_path(const char *cgroup_dir) -{ - struct tst_cgroup_path *a; - - if (!tst_cgroup_paths) - return NULL; - - a = tst_cgroup_paths; - - while (strcmp(a->mnt_path, cgroup_dir) != 0){ - if (!a->next) { - tst_res(TINFO, "%s is not found", cgroup_dir); - return NULL; - } - a = a->next; - }; - - return a->new_path; -} - -static void tst_cgroup_del_path(const char *cgroup_dir) -{ - struct tst_cgroup_path *a, *b; - - if (!tst_cgroup_paths) - return; - - a = b = tst_cgroup_paths; - - while (strcmp(b->mnt_path, cgroup_dir) != 0) { - if (!b->next) { - tst_res(TINFO, "%s is not found", cgroup_dir); - return; - } - a = b; - b = b->next; - }; - - if (b == tst_cgroup_paths) - tst_cgroup_paths = b->next; - else - a->next = b->next; - - free(b->mnt_path); - free(b->new_path); - free(b); -} - -void tst_cgroup_mount(enum tst_cgroup_ctrl ctrl, const char *cgroup_dir) -{ - char *cgroup_new_dir; - char knob_path[PATH_MAX]; - - tst_cg_ver = tst_cgroup_version(); - - tst_cgroup_set_path(cgroup_dir); - cgroup_new_dir = tst_cgroup_get_path(cgroup_dir); - - if (tst_cg_ver & TST_CGROUP_V1) { - switch(ctrl) { - case TST_CGROUP_MEMCG: - tst_cgroup1_mount("memcg", "memory", cgroup_dir, cgroup_new_dir); - break; - case TST_CGROUP_CPUSET: - tst_cgroup1_mount("cpusetcg", "cpuset", cgroup_dir, cgroup_new_dir); - break; - default: - tst_brk(TBROK, "Invalid cgroup controller: %d", ctrl); - } - } - - if (tst_cg_ver & TST_CGROUP_V2) { - tst_cgroup2_mount(cgroup_dir, cgroup_new_dir); - - switch(ctrl) { - case TST_CGROUP_MEMCG: - sprintf(knob_path, "%s/cgroup.subtree_control", cgroup_dir); - SAFE_FILE_PRINTF(knob_path, "%s", "+memory"); - break; - case TST_CGROUP_CPUSET: - tst_brk(TCONF, "Cgroup v2 hasn't achieve cpuset subsystem"); - break; - default: - tst_brk(TBROK, "Invalid cgroup controller: %d", ctrl); - } - } -} - -void tst_cgroup_umount(const char *cgroup_dir) -{ - char *cgroup_new_dir; - - cgroup_new_dir = tst_cgroup_get_path(cgroup_dir); - tst_cgroupN_umount(cgroup_dir, cgroup_new_dir); - tst_cgroup_del_path(cgroup_dir); -} - -void tst_cgroup_set_knob(const char *cgroup_dir, const char *knob, long value) -{ - char *cgroup_new_dir; - char knob_path[PATH_MAX]; - - cgroup_new_dir = tst_cgroup_get_path(cgroup_dir); - sprintf(knob_path, "%s/%s", cgroup_new_dir, knob); - SAFE_FILE_PRINTF(knob_path, "%ld", value); -} - -void tst_cgroup_move_current(const char *cgroup_dir) -{ - if (tst_cg_ver & TST_CGROUP_V1) - tst_cgroup_set_knob(cgroup_dir, "tasks", getpid()); - - if (tst_cg_ver & TST_CGROUP_V2) - tst_cgroup_set_knob(cgroup_dir, "cgroup.procs", getpid()); -} - -void tst_cgroup_mem_set_maxbytes(const char *cgroup_dir, long memsz) -{ - if (tst_cg_ver & TST_CGROUP_V1) - tst_cgroup_set_knob(cgroup_dir, "memory.limit_in_bytes", memsz); - - if (tst_cg_ver & TST_CGROUP_V2) - tst_cgroup_set_knob(cgroup_dir, "memory.max", memsz); -} - -int tst_cgroup_mem_swapacct_enabled(const char *cgroup_dir) -{ - char *cgroup_new_dir; - char knob_path[PATH_MAX]; - - cgroup_new_dir = tst_cgroup_get_path(cgroup_dir); - - if (tst_cg_ver & TST_CGROUP_V1) { - sprintf(knob_path, "%s/%s", - cgroup_new_dir, "/memory.memsw.limit_in_bytes"); - - if ((access(knob_path, F_OK) == -1)) { - if (errno == ENOENT) - tst_res(TCONF, "memcg swap accounting is disabled"); - else - tst_brk(TBROK | TERRNO, "failed to access %s", knob_path); - } else { - return 1; - } - } - - if (tst_cg_ver & TST_CGROUP_V2) { - sprintf(knob_path, "%s/%s", - cgroup_new_dir, "/memory.swap.max"); - - if ((access(knob_path, F_OK) == -1)) { - if (errno == ENOENT) - tst_res(TCONF, "memcg swap accounting is disabled"); - else - tst_brk(TBROK | TERRNO, "failed to access %s", knob_path); - } else { - return 1; - } - } - - return 0; -} - -void tst_cgroup_mem_set_maxswap(const char *cgroup_dir, long memsz) -{ - if (tst_cg_ver & TST_CGROUP_V1) - tst_cgroup_set_knob(cgroup_dir, "memory.memsw.limit_in_bytes", memsz); - - if (tst_cg_ver & TST_CGROUP_V2) - tst_cgroup_set_knob(cgroup_dir, "memory.swap.max", memsz); -} - -void tst_cgroup_cpuset_read_files(const char *cgroup_dir, const char *filename, char *retbuf) -{ - int fd; - char *cgroup_new_dir; - char knob_path[PATH_MAX]; - - cgroup_new_dir = tst_cgroup_get_path(cgroup_dir); - - /* - * try either '/dev/cpuset/XXXX' or '/dev/cpuset/cpuset.XXXX' - * please see Documentation/cgroups/cpusets.txt from kernel src - * for details - */ - sprintf(knob_path, "%s/%s", cgroup_new_dir, filename); - fd = open(knob_path, O_RDONLY); - if (fd == -1) { - if (errno == ENOENT) { - sprintf(knob_path, "%s/cpuset.%s", - cgroup_new_dir, filename); - fd = SAFE_OPEN(knob_path, O_RDONLY); - } else - tst_brk(TBROK | TERRNO, "open %s", knob_path); - } - - if (read(fd, retbuf, sizeof(retbuf)) < 0) - tst_brk(TBROK | TERRNO, "read %s", knob_path); - - close(fd); -} - -void tst_cgroup_cpuset_write_files(const char *cgroup_dir, const char *filename, const char *buf) -{ - int fd; - char *cgroup_new_dir; - char knob_path[PATH_MAX]; - - cgroup_new_dir = tst_cgroup_get_path(cgroup_dir); - - /* - * try either '/dev/cpuset/XXXX' or '/dev/cpuset/cpuset.XXXX' - * please see Documentation/cgroups/cpusets.txt from kernel src - * for details - */ - sprintf(knob_path, "%s/%s", cgroup_new_dir, filename); - fd = open(knob_path, O_WRONLY); - if (fd == -1) { - if (errno == ENOENT) { - sprintf(knob_path, "%s/cpuset.%s", cgroup_new_dir, filename); - fd = SAFE_OPEN(knob_path, O_WRONLY); - } else - tst_brk(TBROK | TERRNO, "open %s", knob_path); - } - - SAFE_WRITE(1, fd, buf, strlen(buf)); - - close(fd); -} diff --git a/kernel/tests/lib/tst_checkpoint.c b/kernel/tests/lib/tst_checkpoint.c deleted file mode 100644 index 5e5b114..0000000 --- a/kernel/tests/lib/tst_checkpoint.c +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright (C) 2015 Cyril Hrubis <chrubis@suse.cz> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it would be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * Further, this software is distributed without any warranty that it is - * free of the rightful claim of any third person regarding infringement - * or the like. Any license provided herein, whether implied or - * otherwise, applies only to this software file. Patent licenses, if - * any, provided herein do not apply to combinations of this program with - * other software, or any other product whatsoever. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include <stdint.h> -#include <limits.h> -#include <errno.h> -#include <sys/syscall.h> -#include <linux/futex.h> - -#include "test.h" -#include "safe_macros.h" -#include "lapi/futex.h" - -#define DEFAULT_MSEC_TIMEOUT 10000 - -futex_t *tst_futexes; -unsigned int tst_max_futexes; - -void tst_checkpoint_init(const char *file, const int lineno, - void (*cleanup_fn)(void)) -{ - int fd; - unsigned int page_size; - - if (tst_futexes) { - tst_brkm(TBROK, cleanup_fn, - "%s: %d checkpoints already initialized", - file, lineno); - return; - } - - /* - * The parent test process is responsible for creating the temporary - * directory and therefore must pass non-zero cleanup (to remove the - * directory if something went wrong). - * - * We cannot do this check unconditionally because if we need to init - * the checkpoint from a binary that was started by exec() the - * tst_tmpdir_created() will return false because the tmpdir was - * created by parent. In this case we expect the subprogram can call - * the init as a first function with NULL as cleanup function. - */ - if (cleanup_fn && !tst_tmpdir_created()) { - tst_brkm(TBROK, cleanup_fn, - "%s:%d You have to create test temporary directory " - "first (call tst_tmpdir())", file, lineno); - return; - } - - page_size = getpagesize(); - - fd = SAFE_OPEN(cleanup_fn, "checkpoint_futex_base_file", - O_RDWR | O_CREAT, 0666); - - SAFE_FTRUNCATE(cleanup_fn, fd, page_size); - - tst_futexes = SAFE_MMAP(cleanup_fn, NULL, page_size, - PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); - - tst_max_futexes = page_size / sizeof(uint32_t); - - SAFE_CLOSE(cleanup_fn, fd); -} - -int tst_checkpoint_wait(unsigned int id, unsigned int msec_timeout) -{ - struct timespec timeout; - int ret; - - if (id >= tst_max_futexes) { - errno = EOVERFLOW; - return -1; - } - - timeout.tv_sec = msec_timeout/1000; - timeout.tv_nsec = (msec_timeout%1000) * 1000000; - - do { - ret = syscall(SYS_futex, &tst_futexes[id], FUTEX_WAIT, - tst_futexes[id], &timeout); - } while (ret == -1 && errno == EINTR); - - return ret; -} - -int tst_checkpoint_wake(unsigned int id, unsigned int nr_wake, - unsigned int msec_timeout) -{ - unsigned int msecs = 0, waked = 0; - - if (id >= tst_max_futexes) { - errno = EOVERFLOW; - return -1; - } - - for (;;) { - waked += syscall(SYS_futex, &tst_futexes[id], FUTEX_WAKE, - INT_MAX, NULL); - - if (waked == nr_wake) - break; - - usleep(1000); - msecs++; - - if (msecs >= msec_timeout) { - errno = ETIMEDOUT; - return -1; - } - } - - return 0; -} - -void tst_safe_checkpoint_wait(const char *file, const int lineno, - void (*cleanup_fn)(void), unsigned int id, - unsigned int msec_timeout) -{ - int ret; - - if (!msec_timeout) - msec_timeout = DEFAULT_MSEC_TIMEOUT; - - ret = tst_checkpoint_wait(id, msec_timeout); - - if (ret) { - tst_brkm(TBROK | TERRNO, cleanup_fn, - "%s:%d: tst_checkpoint_wait(%u, %i)", - file, lineno, id, msec_timeout); - } -} - -void tst_safe_checkpoint_wake(const char *file, const int lineno, - void (*cleanup_fn)(void), unsigned int id, - unsigned int nr_wake) -{ - int ret = tst_checkpoint_wake(id, nr_wake, DEFAULT_MSEC_TIMEOUT); - - if (ret) { - tst_brkm(TBROK | TERRNO, cleanup_fn, - "%s:%d: tst_checkpoint_wake(%u, %u, %i)", - file, lineno, id, nr_wake, DEFAULT_MSEC_TIMEOUT); - } -} diff --git a/kernel/tests/lib/tst_checksum.c b/kernel/tests/lib/tst_checksum.c deleted file mode 100644 index 903bf3d..0000000 --- a/kernel/tests/lib/tst_checksum.c +++ /dev/null @@ -1,81 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* Copyright (c) 2018 Oracle and/or its affiliates. All Rights Reserved. */ - -#include "tst_checksum.h" - -static const uint32_t crc32c_table[] = { - 0x00000000, 0xf26b8303, 0xe13b70f7, 0x1350f3f4, - 0xc79a971f, 0x35f1141c, 0x26a1e7e8, 0xd4ca64eb, - 0x8ad958cf, 0x78b2dbcc, 0x6be22838, 0x9989ab3b, - 0x4d43cfd0, 0xbf284cd3, 0xac78bf27, 0x5e133c24, - 0x105ec76f, 0xe235446c, 0xf165b798, 0x030e349b, - 0xd7c45070, 0x25afd373, 0x36ff2087, 0xc494a384, - 0x9a879fa0, 0x68ec1ca3, 0x7bbcef57, 0x89d76c54, - 0x5d1d08bf, 0xaf768bbc, 0xbc267848, 0x4e4dfb4b, - 0x20bd8ede, 0xd2d60ddd, 0xc186fe29, 0x33ed7d2a, - 0xe72719c1, 0x154c9ac2, 0x061c6936, 0xf477ea35, - 0xaa64d611, 0x580f5512, 0x4b5fa6e6, 0xb93425e5, - 0x6dfe410e, 0x9f95c20d, 0x8cc531f9, 0x7eaeb2fa, - 0x30e349b1, 0xc288cab2, 0xd1d83946, 0x23b3ba45, - 0xf779deae, 0x05125dad, 0x1642ae59, 0xe4292d5a, - 0xba3a117e, 0x4851927d, 0x5b016189, 0xa96ae28a, - 0x7da08661, 0x8fcb0562, 0x9c9bf696, 0x6ef07595, - 0x417b1dbc, 0xb3109ebf, 0xa0406d4b, 0x522bee48, - 0x86e18aa3, 0x748a09a0, 0x67dafa54, 0x95b17957, - 0xcba24573, 0x39c9c670, 0x2a993584, 0xd8f2b687, - 0x0c38d26c, 0xfe53516f, 0xed03a29b, 0x1f682198, - 0x5125dad3, 0xa34e59d0, 0xb01eaa24, 0x42752927, - 0x96bf4dcc, 0x64d4cecf, 0x77843d3b, 0x85efbe38, - 0xdbfc821c, 0x2997011f, 0x3ac7f2eb, 0xc8ac71e8, - 0x1c661503, 0xee0d9600, 0xfd5d65f4, 0x0f36e6f7, - 0x61c69362, 0x93ad1061, 0x80fde395, 0x72966096, - 0xa65c047d, 0x5437877e, 0x4767748a, 0xb50cf789, - 0xeb1fcbad, 0x197448ae, 0x0a24bb5a, 0xf84f3859, - 0x2c855cb2, 0xdeeedfb1, 0xcdbe2c45, 0x3fd5af46, - 0x7198540d, 0x83f3d70e, 0x90a324fa, 0x62c8a7f9, - 0xb602c312, 0x44694011, 0x5739b3e5, 0xa55230e6, - 0xfb410cc2, 0x092a8fc1, 0x1a7a7c35, 0xe811ff36, - 0x3cdb9bdd, 0xceb018de, 0xdde0eb2a, 0x2f8b6829, - 0x82f63b78, 0x709db87b, 0x63cd4b8f, 0x91a6c88c, - 0x456cac67, 0xb7072f64, 0xa457dc90, 0x563c5f93, - 0x082f63b7, 0xfa44e0b4, 0xe9141340, 0x1b7f9043, - 0xcfb5f4a8, 0x3dde77ab, 0x2e8e845f, 0xdce5075c, - 0x92a8fc17, 0x60c37f14, 0x73938ce0, 0x81f80fe3, - 0x55326b08, 0xa759e80b, 0xb4091bff, 0x466298fc, - 0x1871a4d8, 0xea1a27db, 0xf94ad42f, 0x0b21572c, - 0xdfeb33c7, 0x2d80b0c4, 0x3ed04330, 0xccbbc033, - 0xa24bb5a6, 0x502036a5, 0x4370c551, 0xb11b4652, - 0x65d122b9, 0x97baa1ba, 0x84ea524e, 0x7681d14d, - 0x2892ed69, 0xdaf96e6a, 0xc9a99d9e, 0x3bc21e9d, - 0xef087a76, 0x1d63f975, 0x0e330a81, 0xfc588982, - 0xb21572c9, 0x407ef1ca, 0x532e023e, 0xa145813d, - 0x758fe5d6, 0x87e466d5, 0x94b49521, 0x66df1622, - 0x38cc2a06, 0xcaa7a905, 0xd9f75af1, 0x2b9cd9f2, - 0xff56bd19, 0x0d3d3e1a, 0x1e6dcdee, 0xec064eed, - 0xc38d26c4, 0x31e6a5c7, 0x22b65633, 0xd0ddd530, - 0x0417b1db, 0xf67c32d8, 0xe52cc12c, 0x1747422f, - 0x49547e0b, 0xbb3ffd08, 0xa86f0efc, 0x5a048dff, - 0x8ecee914, 0x7ca56a17, 0x6ff599e3, 0x9d9e1ae0, - 0xd3d3e1ab, 0x21b862a8, 0x32e8915c, 0xc083125f, - 0x144976b4, 0xe622f5b7, 0xf5720643, 0x07198540, - 0x590ab964, 0xab613a67, 0xb831c993, 0x4a5a4a90, - 0x9e902e7b, 0x6cfbad78, 0x7fab5e8c, 0x8dc0dd8f, - 0xe330a81a, 0x115b2b19, 0x020bd8ed, 0xf0605bee, - 0x24aa3f05, 0xd6c1bc06, 0xc5914ff2, 0x37faccf1, - 0x69e9f0d5, 0x9b8273d6, 0x88d28022, 0x7ab90321, - 0xae7367ca, 0x5c18e4c9, 0x4f48173d, 0xbd23943e, - 0xf36e6f75, 0x0105ec76, 0x12551f82, 0xe03e9c81, - 0x34f4f86a, 0xc69f7b69, 0xd5cf889d, 0x27a40b9e, - 0x79b737ba, 0x8bdcb4b9, 0x988c474d, 0x6ae7c44e, - 0xbe2da0a5, 0x4c4623a6, 0x5f16d052, 0xad7d5351, -}; - -uint32_t tst_crc32c(uint8_t *buf, size_t buf_len) -{ - uint32_t crc = 0xffffffff; - - while (buf_len--) - crc = crc32c_table[(crc ^ (*buf++)) & 0xff] ^ (crc >> 8); - - return ~crc; -} diff --git a/kernel/tests/lib/tst_clocks.c b/kernel/tests/lib/tst_clocks.c deleted file mode 100644 index cdcb9fc..0000000 --- a/kernel/tests/lib/tst_clocks.c +++ /dev/null @@ -1,144 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (c) 2017 Cyril Hrubis <chrubis@suse.cz> - */ - -#include <time.h> - -#define TST_NO_DEFAULT_MAIN -#include "tst_test.h" -#include "tst_timer.h" -#include "tst_clocks.h" -#include "lapi/syscalls.h" -#include "lapi/posix_clocks.h" - -typedef int (*mysyscall)(clockid_t clk_id, void *ts); - -int syscall_supported_by_kernel(long sysnr) -{ - int ret; - - ret = syscall(sysnr, 0, NULL); - if (ret == -1 && errno == ENOSYS) - return 0; - - return 1; -} - -int tst_clock_getres(clockid_t clk_id, struct timespec *res) -{ - static struct tst_ts tts = { 0, }; - static mysyscall func; - int ret; - -#if (__NR_clock_getres_time64 != __LTP__NR_INVALID_SYSCALL) - if (!func && syscall_supported_by_kernel(__NR_clock_getres_time64)) { - func = sys_clock_getres64; - tts.type = TST_KERN_TIMESPEC; - } -#endif - - if (!func && syscall_supported_by_kernel(__NR_clock_getres)) { - func = sys_clock_getres; - tts.type = TST_KERN_OLD_TIMESPEC; - } - - if (!func) { - tst_res(TCONF, "clock_getres() not available"); - errno = ENOSYS; - return -1; - } - - ret = func(clk_id, tst_ts_get(&tts)); - res->tv_sec = tst_ts_get_sec(tts); - res->tv_nsec = tst_ts_get_nsec(tts); - return ret; -} - -int tst_clock_gettime(clockid_t clk_id, struct timespec *ts) -{ - static struct tst_ts tts = { 0, }; - static mysyscall func; - int ret; - -#if (__NR_clock_gettime64 != __LTP__NR_INVALID_SYSCALL) - if (!func && syscall_supported_by_kernel(__NR_clock_gettime64)) { - func = sys_clock_gettime64; - tts.type = TST_KERN_TIMESPEC; - } -#endif - - if (!func && syscall_supported_by_kernel(__NR_clock_gettime)) { - func = sys_clock_gettime; - tts.type = TST_KERN_OLD_TIMESPEC; - } - - if (!func) { - tst_res(TCONF, "clock_gettime() not available"); - errno = ENOSYS; - return -1; - } - - ret = func(clk_id, tst_ts_get(&tts)); - ts->tv_sec = tst_ts_get_sec(tts); - ts->tv_nsec = tst_ts_get_nsec(tts); - return ret; -} - -int tst_clock_settime(clockid_t clk_id, struct timespec *ts) -{ - static struct tst_ts tts = { 0, }; - static mysyscall func; - -#if (__NR_clock_settime64 != __LTP__NR_INVALID_SYSCALL) - if (!func && syscall_supported_by_kernel(__NR_clock_settime64)) { - func = sys_clock_settime64; - tts.type = TST_KERN_TIMESPEC; - } -#endif - - if (!func && syscall_supported_by_kernel(__NR_clock_settime)) { - func = sys_clock_settime; - tts.type = TST_KERN_OLD_TIMESPEC; - } - - if (!func) { - tst_res(TCONF, "clock_settime() not available"); - errno = ENOSYS; - return -1; - } - - tst_ts_set_sec(&tts, ts->tv_sec); - tst_ts_set_nsec(&tts, ts->tv_nsec); - return func(clk_id, tst_ts_get(&tts)); -} - -const char *tst_clock_name(clockid_t clk_id) -{ - switch (clk_id) { - case CLOCK_REALTIME: - return "CLOCK_REALTIME"; - case CLOCK_MONOTONIC: - return "CLOCK_MONOTONIC"; - case CLOCK_PROCESS_CPUTIME_ID: - return "CLOCK_PROCESS_CPUTIME_ID"; - case CLOCK_THREAD_CPUTIME_ID: - return "CLOCK_THREAD_CPUTIME_ID"; - case CLOCK_MONOTONIC_RAW: - return "CLOCK_MONOTONIC_RAW"; - case CLOCK_REALTIME_COARSE: - return "CLOCK_REALTIME_COARSE"; - case CLOCK_MONOTONIC_COARSE: - return "CLOCK_MONOTONIC_COARSE"; - case CLOCK_BOOTTIME: - return "CLOCK_BOOTTIME"; - case CLOCK_REALTIME_ALARM: - return "CLOCK_REALTIME_ALARM"; - case CLOCK_BOOTTIME_ALARM: - return "CLOCK_BOOTTIME_ALARM"; - case CLOCK_TAI: - return "CLOCK_TAI"; - default: - return "INVALID/UNKNOWN CLOCK"; - } -} diff --git a/kernel/tests/lib/tst_cmd.c b/kernel/tests/lib/tst_cmd.c deleted file mode 100644 index 7446249..0000000 --- a/kernel/tests/lib/tst_cmd.c +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All Rights Reserved. - * Copyright (c) 2020 Petr Vorel <pvorel@suse.cz> - * - * 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 would 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 the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - * Author: Alexey Kodanev <alexey.kodanev@oracle.com> - */ - -#include <errno.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/wait.h> -#include <fcntl.h> -#include <unistd.h> -#include <signal.h> -#include "test.h" -#include "tst_cmd.h" - -#define OPEN_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) -#define OPEN_FLAGS (O_WRONLY | O_APPEND | O_CREAT) - -int tst_cmd_fds_(void (cleanup_fn)(void), - const char *const argv[], - int stdout_fd, - int stderr_fd, - enum tst_cmd_flags flags) -{ - int rc; - - if (argv == NULL || argv[0] == NULL) { - tst_brkm(TBROK, cleanup_fn, - "argument list is empty at %s:%d", __FILE__, __LINE__); - return -1; - } - - /* - * The tst_sig() install poisoned signal handlers for all signals the - * test is not expected to get. - * - * So we temporarily disable the handler for sigchild we get after our - * child exits so that we don't have to disable it in each test that - * uses this interface. - */ - void *old_handler = signal(SIGCHLD, SIG_DFL); - - char path[PATH_MAX]; - - if (tst_get_path(argv[0], path, sizeof(path))) { - if (flags & TST_CMD_TCONF_ON_MISSING) - tst_brkm(TCONF, cleanup_fn, "Couldn't find '%s' in $PATH at %s:%d", argv[0], - __FILE__, __LINE__); - else - return 255; - } - - pid_t pid = vfork(); - if (pid == -1) { - tst_brkm(TBROK | TERRNO, cleanup_fn, "vfork failed at %s:%d", - __FILE__, __LINE__); - return -1; - } - if (!pid) { - /* redirecting stdout and stderr if needed */ - if (stdout_fd != -1) { - close(STDOUT_FILENO); - dup2(stdout_fd, STDOUT_FILENO); - } - - if (stderr_fd != -1) { - close(STDERR_FILENO); - dup2(stderr_fd, STDERR_FILENO); - } - - execvp(argv[0], (char *const *)argv); - _exit(254); - } - - int ret = -1; - if (waitpid(pid, &ret, 0) != pid) { - tst_brkm(TBROK | TERRNO, cleanup_fn, "waitpid failed at %s:%d", - __FILE__, __LINE__); - return -1; - } - - signal(SIGCHLD, old_handler); - - if (!WIFEXITED(ret)) { - tst_brkm(TBROK, cleanup_fn, "failed to exec cmd '%s' at %s:%d", - argv[0], __FILE__, __LINE__); - return -1; - } - - rc = WEXITSTATUS(ret); - - if (!(flags & TST_CMD_PASS_RETVAL) && rc) { - tst_brkm(TBROK, cleanup_fn, - "'%s' exited with a non-zero code %d at %s:%d", - argv[0], rc, __FILE__, __LINE__); - return -1; - } - - return rc; -} - -int tst_cmd_(void (cleanup_fn)(void), - const char *const argv[], - const char *stdout_path, - const char *stderr_path, - enum tst_cmd_flags flags) -{ - int stdout_fd = -1; - int stderr_fd = -1; - int rc; - - if (stdout_path != NULL) { - stdout_fd = open(stdout_path, - OPEN_FLAGS, OPEN_MODE); - - if (stdout_fd == -1) - tst_resm(TWARN | TERRNO, - "open() on %s failed at %s:%d", - stdout_path, __FILE__, __LINE__); - } - - if (stderr_path != NULL) { - stderr_fd = open(stderr_path, - OPEN_FLAGS, OPEN_MODE); - - if (stderr_fd == -1) - tst_resm(TWARN | TERRNO, - "open() on %s failed at %s:%d", - stderr_path, __FILE__, __LINE__); - } - - rc = tst_cmd_fds(cleanup_fn, argv, stdout_fd, stderr_fd, flags); - - if ((stdout_fd != -1) && (close(stdout_fd) == -1)) - tst_resm(TWARN | TERRNO, - "close() on %s failed at %s:%d", - stdout_path, __FILE__, __LINE__); - - if ((stderr_fd != -1) && (close(stderr_fd) == -1)) - tst_resm(TWARN | TERRNO, - "close() on %s failed at %s:%d", - stderr_path, __FILE__, __LINE__); - - return rc; -} - -int tst_system(const char *command) -{ - int ret = 0; - - /* - *Temporarily disable SIGCHLD of user defined handler, so the - *system(3) function will not cause unexpected SIGCHLD signal - *callback function for test cases. - */ - void *old_handler = signal(SIGCHLD, SIG_DFL); - - ret = system(command); - - signal(SIGCHLD, old_handler); - return ret; -} diff --git a/kernel/tests/lib/tst_coredump.c b/kernel/tests/lib/tst_coredump.c deleted file mode 100644 index 83aa2c3..0000000 --- a/kernel/tests/lib/tst_coredump.c +++ /dev/null @@ -1,35 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (c) 2019 Red Hat, Inc. - */ - -#define TST_NO_DEFAULT_MAIN - -#include <sys/time.h> -#include <sys/resource.h> - -#include "tst_test.h" -#include "tst_coredump.h" - -void tst_no_corefile(int verbose) -{ - struct rlimit new_r, old_r; - - SAFE_GETRLIMIT(RLIMIT_CORE, &old_r); - if (old_r.rlim_max >= 1 || geteuid() == 0) { - /* - * 1 is a special value, that disables core-to-pipe. - * At the same time it is small enough value for - * core-to-file, so it skips creating cores as well. - */ - new_r.rlim_cur = 1; - new_r.rlim_max = 1; - SAFE_SETRLIMIT(RLIMIT_CORE, &new_r); - - if (verbose) { - tst_res(TINFO, - "Avoid dumping corefile for process(pid=%d)", - getpid()); - } - } -} diff --git a/kernel/tests/lib/tst_cpu.c b/kernel/tests/lib/tst_cpu.c deleted file mode 100644 index 033155e..0000000 --- a/kernel/tests/lib/tst_cpu.c +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2012 Fujitsu Ltd. - * Author: Wanlong Gao <gaowanlong@cn.fujitsu.com> - * - * 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 - */ - -#include <stdlib.h> -#include <unistd.h> -#include "test.h" -#include "safe_macros.h" - -long tst_ncpus(void) -{ - long ncpus = -1; -#ifdef _SC_NPROCESSORS_ONLN - ncpus = SAFE_SYSCONF(NULL, _SC_NPROCESSORS_ONLN); -#else - tst_brkm(TBROK, NULL, "could not determine number of CPUs online"); -#endif - return ncpus; -} - -long tst_ncpus_conf(void) -{ - long ncpus_conf = -1; -#ifdef _SC_NPROCESSORS_CONF - ncpus_conf = SAFE_SYSCONF(NULL, _SC_NPROCESSORS_CONF); -#else - tst_brkm(TBROK, NULL, "could not determine number of CPUs configured"); -#endif - return ncpus_conf; -} - -#define KERNEL_MAX "/sys/devices/system/cpu/kernel_max" - -long tst_ncpus_max(void) -{ - long ncpus_max = -1; - struct stat buf; - - /* sched_getaffinity() and sched_setaffinity() cares about number of - * possible CPUs the OS or hardware can support, which can be larger - * than what sysconf(_SC_NPROCESSORS_CONF) currently provides - * (by enumarating /sys/devices/system/cpu/cpu* entries). - * - * Use /sys/devices/system/cpu/kernel_max, if available. This - * represents NR_CPUS-1, a compile time option which specifies - * "maximum number of CPUs which this kernel will support". - * This should provide cpu mask size large enough for any purposes. */ - if (stat(KERNEL_MAX, &buf) == 0) { - SAFE_FILE_SCANF(NULL, KERNEL_MAX, "%ld", &ncpus_max); - /* this is maximum CPU index allowed by the kernel - * configuration, so # of cpus allowed by config is +1 */ - ncpus_max++; - } else { - /* fall back to _SC_NPROCESSORS_CONF */ - ncpus_max = tst_ncpus_conf(); - } - return ncpus_max; -} diff --git a/kernel/tests/lib/tst_crypto.c b/kernel/tests/lib/tst_crypto.c deleted file mode 100644 index 685e087..0000000 --- a/kernel/tests/lib/tst_crypto.c +++ /dev/null @@ -1,110 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (c) 2018 Richard Palethorpe <rpalethorpe@suse.com> - * Nicolai Stange <nstange@suse.de> - */ - -#include <errno.h> -#include <stdio.h> - -#define TST_NO_DEFAULT_MAIN -#include "tst_test.h" -#include "tst_crypto.h" -#include "tst_netlink.h" - -void tst_crypto_open(struct tst_crypto_session *ses) -{ - TEST(socket(AF_NETLINK, SOCK_DGRAM, NETLINK_CRYPTO)); - if (TST_RET < 0 && TST_ERR == EPROTONOSUPPORT) - tst_brk(TCONF | TTERRNO, "NETLINK_CRYPTO is probably disabled"); - - if (TST_RET < 0) { - tst_brk(TBROK | TTERRNO, - "socket(AF_NETLINK, SOCK_DGRAM, NETLINK_CRYPTO)"); - } - - ses->fd = TST_RET; - ses->seq_num = 0; -} - -void tst_crypto_close(struct tst_crypto_session *ses) -{ - SAFE_CLOSE(ses->fd); -} - -static int tst_crypto_recv_ack(struct tst_crypto_session *ses) -{ - uint32_t len; - char buf[BUFSIZ]; - struct nlmsghdr *nh; - - len = SAFE_NETLINK_RECV(ses->fd, buf, sizeof(buf)); - - for (nh = (struct nlmsghdr *) buf; - NLMSG_OK(nh, len); - nh = NLMSG_NEXT(nh, len)) { - if (nh->nlmsg_seq != ses->seq_num) { - tst_brk(TBROK, - "Message out of sequence; type=0%hx, seq_num=%u (not %u)", - nh->nlmsg_type, nh->nlmsg_seq, ses->seq_num); - } - - /* Acks use the error message type with error number set to - * zero. Ofcourse we could also receive an actual error. - */ - if (nh->nlmsg_type == NLMSG_ERROR) - return ((struct nlmsgerr *)NLMSG_DATA(nh))->error; - - tst_brk(TBROK, "Unexpected message type; type=0x%hx, seq_num=%u", - nh->nlmsg_type, nh->nlmsg_seq); - } - - tst_brk(TBROK, "Empty message from netlink socket?"); - - return ENODATA; -} - -int tst_crypto_add_alg(struct tst_crypto_session *ses, - const struct crypto_user_alg *alg) -{ - struct nlmsghdr nh = { - .nlmsg_len = sizeof(struct nlmsghdr) + sizeof(*alg), - .nlmsg_type = CRYPTO_MSG_NEWALG, - .nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK, - .nlmsg_seq = ++(ses->seq_num), - .nlmsg_pid = 0, - }; - - SAFE_NETLINK_SEND(ses->fd, &nh, alg); - - return tst_crypto_recv_ack(ses); -} - -int tst_crypto_del_alg(struct tst_crypto_session *ses, - const struct crypto_user_alg *alg) -{ - unsigned int i = 0; - struct nlmsghdr nh = { - .nlmsg_len = sizeof(struct nlmsghdr) + sizeof(*alg), - .nlmsg_type = CRYPTO_MSG_DELALG, - .nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK, - .nlmsg_pid = 0, - }; - - while (1) { - nh.nlmsg_seq = ++(ses->seq_num), - - SAFE_NETLINK_SEND(ses->fd, &nh, alg); - - TEST(tst_crypto_recv_ack(ses)); - if (TST_RET != -EBUSY || i >= ses->retries) - break; - - if (usleep(1) && errno != EINTR) - tst_brk(TBROK | TERRNO, "usleep(1)"); - - ++i; - } - - return TST_RET; -} diff --git a/kernel/tests/lib/tst_device.c b/kernel/tests/lib/tst_device.c deleted file mode 100644 index 0df8efe..0000000 --- a/kernel/tests/lib/tst_device.c +++ /dev/null @@ -1,531 +0,0 @@ -/* - * Copyright (C) 2014 Cyril Hrubis chrubis@suse.cz - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it would be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * Further, this software is distributed without any warranty that it is - * free of the rightful claim of any third person regarding infringement - * or the like. Any license provided herein, whether implied or - * otherwise, applies only to this software file. Patent licenses, if - * any, provided herein do not apply to combinations of this program with - * other software, or any other product whatsoever. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/ioctl.h> -#include <sys/mount.h> -#include <errno.h> -#include <unistd.h> -#include <stdlib.h> -#include <uapi_xloop.h> -#include <stdint.h> -#include <inttypes.h> -#include <sys/sysmacros.h> -#include "lapi/syscalls.h" -#include "test.h" -#include "safe_macros.h" - -#ifndef XLOOP_CTL_GET_FREE -# define XLOOP_CTL_GET_FREE 0x4C82 -#endif - -#define XLOOP_CONTROL_FILE "/dev/xloop-control" - -#define DEV_FILE "test_dev.img" -#define DEV_SIZE_MB 256u - -static char dev_path[1024]; -static int device_acquired; -static unsigned long prev_dev_sec_write; - -static const char *dev_variants[] = { - "/dev/xloop%i", - "/dev/xloop/%i", - "/dev/block/xloop%i" -}; - -static int set_dev_path(int dev, char *path, size_t path_len) -{ - unsigned int i; - struct stat st; - - for (i = 0; i < ARRAY_SIZE(dev_variants); i++) { - snprintf(path, path_len, dev_variants[i], dev); - - if (stat(path, &st) == 0 && S_ISBLK(st.st_mode)) - return 1; - } - - return 0; -} - -int tst_find_free_xloopdev(char *path, size_t path_len) -{ - int ctl_fd, dev_fd, rc, i; - struct xloop_info xloopinfo; - char buf[1024]; - - /* since Linux 3.1 */ - ctl_fd = open(XLOOP_CONTROL_FILE, O_RDWR); - - if (ctl_fd > 0) { - rc = ioctl(ctl_fd, XLOOP_CTL_GET_FREE); - close(ctl_fd); - if (rc >= 0) { - if (path) - set_dev_path(rc, path, path_len); - tst_resm(TINFO, "Found free device %d '%s'", - rc, path ?: ""); - return rc; - } - tst_resm(TINFO, "Couldn't find free xloop device"); - return -1; - } - - switch (errno) { - case ENOENT: - break; - case EACCES: - tst_resm(TINFO | TERRNO, - "Not allowed to open " XLOOP_CONTROL_FILE ". " - "Are you root?"); - break; - default: - tst_resm(TBROK | TERRNO, "Failed to open " XLOOP_CONTROL_FILE); - } - - /* - * Older way is to iterate over /dev/xloop%i and /dev/xloop/%i and try - * XLOOP_GET_STATUS ioctl() which fails for free xloop devices. - */ - for (i = 0; i < 256; i++) { - - if (!set_dev_path(i, buf, sizeof(buf))) - continue; - - dev_fd = open(buf, O_RDONLY); - - if (dev_fd < 0) - continue; - - if (ioctl(dev_fd, XLOOP_GET_STATUS, &xloopinfo) == 0) { - tst_resm(TINFO, "Device '%s' in use", buf); - } else { - if (errno != ENXIO) - continue; - tst_resm(TINFO, "Found free device '%s'", buf); - close(dev_fd); - if (path != NULL) { - strncpy(path, buf, path_len); - path[path_len-1] = '\0'; - } - return i; - } - - close(dev_fd); - } - - tst_resm(TINFO, "No free devices found"); - - return -1; -} - -int tst_attach_device(const char *dev, const char *file) -{ - int dev_fd, file_fd; - struct xloop_info xloopinfo; - - dev_fd = open(dev, O_RDWR); - if (dev_fd < 0) { - tst_resm(TWARN | TERRNO, "open('%s', O_RDWR) failed", dev); - return 1; - } - - file_fd = open(file, O_RDWR); - if (file_fd < 0) { - tst_resm(TWARN | TERRNO, "open('%s', O_RDWR) failed", file); - close(dev_fd); - return 1; - } - - if (ioctl(dev_fd, XLOOP_SET_FD, file_fd) < 0) { - close(dev_fd); - close(file_fd); - tst_resm(TWARN | TERRNO, "ioctl(%s, XLOOP_SET_FD, %s) failed", - dev, file); - return 1; - } - - /* Old mkfs.btrfs use XLOOP_GET_STATUS instead of backing_file to get - * associated filename, so we need to set up the device by calling - * XLOOP_SET_FD and XLOOP_SET_STATUS. - */ - memset(&xloopinfo, 0, sizeof(xloopinfo)); - strcpy(xloopinfo.xlo_name, file); - - if (ioctl(dev_fd, XLOOP_SET_STATUS, &xloopinfo)) { - close(dev_fd); - close(file_fd); - tst_resm(TWARN | TERRNO, - "ioctl(%s, XLOOP_SET_STATUS, %s) failed", dev, file); - return 1; - } - - close(dev_fd); - close(file_fd); - return 0; -} - -int tst_detach_device_by_fd(const char *dev, int dev_fd) -{ - int ret, i; - - /* keep trying to clear XLOOPDEV until we get ENXIO, a quick succession - * of attach/detach might not give udev enough time to complete */ - for (i = 0; i < 40; i++) { - ret = ioctl(dev_fd, XLOOP_CLR_FD, 0); - - if (ret && (errno == ENXIO)) - return 0; - - if (ret && (errno != EBUSY)) { - tst_resm(TWARN, - "ioctl(%s, XLOOP_CLR_FD, 0) unexpectedly failed with: %s", - dev, tst_strerrno(errno)); - return 1; - } - - usleep(50000); - } - - tst_resm(TWARN, - "ioctl(%s, XLOOP_CLR_FD, 0) no ENXIO for too long", dev); - return 1; -} - -int tst_detach_device(const char *dev) -{ - int dev_fd, ret; - - dev_fd = open(dev, O_RDONLY); - if (dev_fd < 0) { - tst_resm(TWARN | TERRNO, "open(%s) failed", dev); - return 1; - } - - ret = tst_detach_device_by_fd(dev, dev_fd); - close(dev_fd); - return ret; -} - -int tst_dev_sync(int fd) -{ - return syscall(__NR_syncfs, fd); -} - -const char *tst_acquire_xloop_device(unsigned int size, const char *filename) -{ - unsigned int acq_dev_size = MAX(size, DEV_SIZE_MB); - - if (tst_prealloc_file(filename, 1024 * 1024, acq_dev_size)) { - tst_resm(TWARN | TERRNO, "Failed to create %s", filename); - return NULL; - } - - if (tst_find_free_xloopdev(dev_path, sizeof(dev_path)) == -1) - return NULL; - - if (tst_attach_device(dev_path, filename)) - return NULL; - - return dev_path; -} - -const char *tst_acquire_device__(unsigned int size) -{ - int fd; - const char *dev; - struct stat st; - unsigned int acq_dev_size; - uint64_t ltp_dev_size; - - acq_dev_size = MAX(size, DEV_SIZE_MB); - - dev = getenv("LTP_DEV"); - - if (dev) { - tst_resm(TINFO, "Using test device LTP_DEV='%s'", dev); - - if (stat(dev, &st)) { - tst_resm(TWARN | TERRNO, "stat() failed"); - return NULL; - } - - if (!S_ISBLK(st.st_mode)) { - tst_resm(TWARN, "%s is not a block device", dev); - return NULL; - } - - fd = open(dev, O_RDONLY); - if (fd < 0) { - tst_resm(TWARN | TERRNO, - "open(%s, O_RDONLY) failed", dev); - return NULL; - } - - if (ioctl(fd, BLKGETSIZE64, <p_dev_size)) { - tst_resm(TWARN | TERRNO, - "ioctl(fd, BLKGETSIZE64, ...) failed"); - close(fd); - return NULL; - } - - if (close(fd)) { - tst_resm(TWARN | TERRNO, - "close(fd) failed"); - return NULL; - } - - ltp_dev_size = ltp_dev_size/1024/1024; - - if (acq_dev_size <= ltp_dev_size) - return dev; - - tst_resm(TINFO, "Skipping $LTP_DEV size %"PRIu64"MB, requested size %uMB", - ltp_dev_size, acq_dev_size); - } - - dev = tst_acquire_xloop_device(acq_dev_size, DEV_FILE); - - if (dev) - device_acquired = 1; - - return dev; -} - -const char *tst_acquire_device_(void (cleanup_fn)(void), unsigned int size) -{ - const char *device; - - if (device_acquired) { - tst_brkm(TBROK, cleanup_fn, "Device already acquired"); - return NULL; - } - - if (!tst_tmpdir_created()) { - tst_brkm(TBROK, cleanup_fn, - "Cannot acquire device without tmpdir() created"); - return NULL; - } - - device = tst_acquire_device__(size); - - if (!device) { - tst_brkm(TBROK, cleanup_fn, "Failed to acquire device"); - return NULL; - } - - return device; -} - -int tst_release_device(const char *dev) -{ - int ret; - - if (!device_acquired) - return 0; - - /* - * Loop device was created -> we need to detach it. - * - * The file image is deleted in tst_rmdir(); - */ - ret = tst_detach_device(dev); - - device_acquired = 0; - - return ret; -} - -int tst_clear_device(const char *dev) -{ - if (tst_fill_file(dev, 0, 1024, 512)) { - tst_resm(TWARN, "Failed to clear 512k block on %s", dev); - return 1; - } - - return 0; -} - -int tst_umount(const char *path) -{ - int err, ret, i; - - for (i = 0; i < 50; i++) { - ret = umount(path); - err = errno; - - if (!ret) - return 0; - - if (err != EBUSY) { - tst_resm(TWARN, "umount('%s') failed with %s", - path, tst_strerrno(err)); - errno = err; - return ret; - } - - tst_resm(TINFO, "umount('%s') failed with %s, try %2i...", - path, tst_strerrno(err), i+1); - - if (i == 0) { - tst_resm(TINFO, "Likely gvfsd-trash is probing newly " - "mounted fs, kill it to speed up tests."); - } - - usleep(100000); - } - - tst_resm(TWARN, "Failed to umount('%s') after 50 retries", path); - errno = err; - return -1; -} - -int tst_is_mounted(const char *path) -{ - char line[PATH_MAX]; - FILE *file; - int ret = 0; - - file = SAFE_FOPEN(NULL, "/proc/mounts", "r"); - - while (fgets(line, sizeof(line), file)) { - if (strstr(line, path) != NULL) { - ret = 1; - break; - } - } - - SAFE_FCLOSE(NULL, file); - - if (!ret) - tst_resm(TINFO, "No device is mounted at %s", path); - - return ret; -} - -int tst_is_mounted_at_tmpdir(const char *path) -{ - char cdir[PATH_MAX], mpath[PATH_MAX]; - int ret; - - if (!getcwd(cdir, PATH_MAX)) { - tst_resm(TWARN | TERRNO, "Failed to find current directory"); - return 0; - } - - ret = snprintf(mpath, PATH_MAX, "%s/%s", cdir, path); - if (ret < 0 || ret >= PATH_MAX) { - tst_resm(TWARN | TERRNO, - "snprintf() should have returned %d instead of %d", - PATH_MAX, ret); - return 0; - } - - return tst_is_mounted(mpath); -} - -int find_stat_file(const char *dev, char *path, size_t path_len) -{ - const char *devname = strrchr(dev, '/') + 1; - - snprintf(path, path_len, "/sys/block/%s/stat", devname); - - if (!access(path, F_OK)) - return 1; - - DIR *dir = SAFE_OPENDIR(NULL, "/sys/block/"); - struct dirent *ent; - - while ((ent = readdir(dir))) { - snprintf(path, path_len, "/sys/block/%s/%s/stat", ent->d_name, devname); - - if (!access(path, F_OK)) { - SAFE_CLOSEDIR(NULL, dir); - return 1; - } - } - - SAFE_CLOSEDIR(NULL, dir); - return 0; -} - -unsigned long tst_dev_bytes_written(const char *dev) -{ - unsigned long dev_sec_write = 0, dev_bytes_written, io_ticks = 0; - char dev_stat_path[1024]; - - if (!find_stat_file(dev, dev_stat_path, sizeof(dev_stat_path))) - tst_brkm(TCONF, NULL, "Test device stat file: %s not found", - dev_stat_path); - - SAFE_FILE_SCANF(NULL, dev_stat_path, - "%*s %*s %*s %*s %*s %*s %lu %*s %*s %lu", - &dev_sec_write, &io_ticks); - - if (!io_ticks) - tst_brkm(TCONF, NULL, "Test device stat file: %s broken", - dev_stat_path); - - dev_bytes_written = (dev_sec_write - prev_dev_sec_write) * 512; - - prev_dev_sec_write = dev_sec_write; - - return dev_bytes_written; -} - -void tst_find_backing_dev(const char *path, char *dev) -{ - char fmt[20]; - struct stat buf; - FILE *file; - char line[PATH_MAX]; - char *pre = NULL; - char *next = NULL; - - if (stat(path, &buf) < 0) - tst_brkm(TWARN | TERRNO, NULL, "stat() failed"); - - snprintf(fmt, sizeof(fmt), "%u:%u", major(buf.st_dev), minor(buf.st_dev)); - file = SAFE_FOPEN(NULL, "/proc/self/mountinfo", "r"); - - while (fgets(line, sizeof(line), file)) { - if (strstr(line, fmt) != NULL) { - pre = strstr(line, " - "); - pre = strtok_r(pre, " ", &next); - pre = strtok_r(NULL, " ", &next); - pre = strtok_r(NULL, " ", &next); - strcpy(dev, pre); - break; - } - } - - SAFE_FCLOSE(NULL, file); - - if (stat(dev, &buf) < 0) - tst_brkm(TWARN | TERRNO, NULL, "stat(%s) failed", dev); - - if (S_ISBLK(buf.st_mode) != 1) - tst_brkm(TCONF, NULL, "dev(%s) isn't a block dev", dev); -} diff --git a/kernel/tests/lib/tst_dir_is_empty.c b/kernel/tests/lib/tst_dir_is_empty.c deleted file mode 100644 index 43764ee..0000000 --- a/kernel/tests/lib/tst_dir_is_empty.c +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2016 Oracle and/or its affiliates. All Rights Reserved. - * - * 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 would 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, see <http://www.gnu.org/licenses/>. - * - * Author: Alexey Kodanev <alexey.kodanev@oracle.com> - * - */ - -#include <string.h> -#include <sys/types.h> -#include <dirent.h> - -#include "test.h" -#include "safe_macros.h" - -int tst_dir_is_empty_(void (cleanup_fn)(void), const char *name, int verbose) -{ - struct dirent *entry; - DIR *dir = SAFE_OPENDIR(cleanup_fn, name); - int ret = 1; - - while ((entry = SAFE_READDIR(cleanup_fn, dir)) != NULL) { - const char *file = entry->d_name; - - if (!strcmp(file, "..") || !strcmp(file, ".")) - continue; - - if (verbose) - tst_resm(TINFO, "found a file: %s", file); - ret = 0; - break; - } - - SAFE_CLOSEDIR(cleanup_fn, dir); - - return ret; -} diff --git a/kernel/tests/lib/tst_fill_file.c b/kernel/tests/lib/tst_fill_file.c deleted file mode 100644 index 8047200..0000000 --- a/kernel/tests/lib/tst_fill_file.c +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All Rights Reserved. - * - * 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 would 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 the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - * Author: Stanislav Kholmanskikh <stanislav.kholmanskikh@oracle.com> - * - */ - -#define _GNU_SOURCE -#include <stdio.h> -#include <stdlib.h> -#include <fcntl.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <unistd.h> -#include "lapi/fallocate.h" - -#include "test.h" - -int tst_fill_fd(int fd, char pattern, size_t bs, size_t bcount) -{ - size_t i; - char *buf; - - /* Filling a memory buffer with provided pattern */ - buf = malloc(bs); - if (buf == NULL) - return -1; - - for (i = 0; i < bs; i++) - buf[i] = pattern; - - /* Filling the file */ - for (i = 0; i < bcount; i++) { - if (write(fd, buf, bs) != (ssize_t)bs) { - free(buf); - return -1; - } - } - - free(buf); - - return 0; -} - -int tst_prealloc_size_fd(int fd, size_t bs, size_t bcount) -{ - int ret; - - errno = 0; - ret = fallocate(fd, 0, 0, bs * bcount); - - if (ret && errno == ENOSPC) - return ret; - - if (ret) - ret = tst_fill_fd(fd, 0, bs, bcount); - - return ret; -} - -int tst_fill_file(const char *path, char pattern, size_t bs, size_t bcount) -{ - int fd; - - fd = open(path, O_CREAT|O_WRONLY|O_TRUNC, S_IRUSR|S_IWUSR); - if (fd < 0) - return -1; - - if (tst_fill_fd(fd, pattern, bs, bcount)) { - close(fd); - unlink(path); - return -1; - } - - if (close(fd) < 0) { - unlink(path); - - return -1; - } - - return 0; -} - -int tst_prealloc_file(const char *path, size_t bs, size_t bcount) -{ - int fd; - - fd = open(path, O_CREAT|O_WRONLY|O_TRUNC, S_IRUSR|S_IWUSR); - if (fd < 0) - return -1; - - if (tst_prealloc_size_fd(fd, bs, bcount)) { - close(fd); - unlink(path); - return -1; - } - - if (close(fd) < 0) { - unlink(path); - return -1; - } - - return 0; -} diff --git a/kernel/tests/lib/tst_fill_fs.c b/kernel/tests/lib/tst_fill_fs.c deleted file mode 100644 index 121dd2f..0000000 --- a/kernel/tests/lib/tst_fill_fs.c +++ /dev/null @@ -1,68 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (c) 2017 Cyril Hrubis <chrubis@suse.cz> - */ - -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <sys/statvfs.h> - -#define TST_NO_DEFAULT_MAIN -#include "tst_test.h" -#include "tst_fs.h" - -void tst_fill_fs(const char *path, int verbose) -{ - int i = 0; - char file[PATH_MAX]; - char buf[4096]; - size_t len; - ssize_t ret; - int fd; - struct statvfs fi; - statvfs(path, &fi); - - for (;;) { - len = random() % (1024 * 102400); - - snprintf(file, sizeof(file), "%s/file%i", path, i++); - - if (verbose) - tst_res(TINFO, "Creating file %s size %zu", file, len); - - fd = open(file, O_WRONLY | O_CREAT, 0700); - if (fd == -1) { - if (errno != ENOSPC) - tst_brk(TBROK | TERRNO, "open()"); - - tst_res(TINFO | TERRNO, "open()"); - return; - } - - while (len) { - ret = write(fd, buf, MIN(len, sizeof(buf))); - - if (ret < 0) { - /* retry on ENOSPC to make sure filesystem is really full */ - if (errno == ENOSPC && len >= fi.f_bsize/2) { - SAFE_FSYNC(fd); - len /= 2; - continue; - } - - SAFE_CLOSE(fd); - - if (errno != ENOSPC) - tst_brk(TBROK | TERRNO, "write()"); - - tst_res(TINFO | TERRNO, "write()"); - return; - } - - len -= ret; - } - - SAFE_CLOSE(fd); - } -} diff --git a/kernel/tests/lib/tst_fs_has_free.c b/kernel/tests/lib/tst_fs_has_free.c deleted file mode 100644 index e82dfa8..0000000 --- a/kernel/tests/lib/tst_fs_has_free.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2014 Fujitsu Ltd. - * Author: Xiaoguang Wang <wangxg.fnst@cn.fujitsu.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it would be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -/* - * DESCRIPTION - * Check if the mounted file system has enough free space, - * if it is, tst_fs_has_free() returns 1, otherwise 0. - */ - -#include <stdint.h> -#include <sys/vfs.h> -#include "test.h" -#include "tst_fs.h" - -int tst_fs_has_free_(void (*cleanup)(void), const char *path, - unsigned int size, unsigned int mult) -{ - struct statfs sf; - - if (statfs(path, &sf)) { - tst_brkm(TBROK | TERRNO, cleanup, - "tst_fs_has_free: failed to statfs(%s)", path); - return 0; - } - - if ((uint64_t)sf.f_bavail * sf.f_bsize >= (uint64_t)size * mult) - return 1; - - return 0; -} diff --git a/kernel/tests/lib/tst_fs_link_count.c b/kernel/tests/lib/tst_fs_link_count.c deleted file mode 100644 index 860510d..0000000 --- a/kernel/tests/lib/tst_fs_link_count.c +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Copyright (c) 2014 Fujitsu Ltd. - * Author: Xiaoguang Wang <wangxg.fnst@cn.fujitsu.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it would be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include <string.h> -#include <errno.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <unistd.h> - -#include "test.h" -#include "usctest.h" -#include "safe_macros.h" - -#define MAX_SANE_HARD_LINKS 65535 - -/* - * filesystems whose subdir limit is less than MAX_SANE_HARD_LINKS - * XXX: we cannot filter ext4 out, because ext2/ext3/ext4 have the - * same magic number - */ -const long subdir_limit_whitelist[] = { - TST_EXT2_OLD_MAGIC, TST_EXT234_MAGIC, TST_MINIX_MAGIC, - TST_MINIX_MAGIC2, TST_MINIX2_MAGIC, TST_MINIX2_MAGIC2, - TST_MINIX3_MAGIC, TST_UDF_MAGIC, TST_SYSV2_MAGIC, - TST_SYSV4_MAGIC, TST_UFS_MAGIC, TST_UFS2_MAGIC, - TST_F2FS_MAGIC, TST_NILFS_MAGIC, TST_EXOFS_MAGIC -}; - -int tst_fs_fill_hardlinks_(void (*cleanup) (void), const char *dir) -{ - unsigned int i, j; - char base_filename[PATH_MAX], link_filename[PATH_MAX]; - struct stat s; - - if (stat(dir, &s) == -1 && errno == ENOENT) - SAFE_MKDIR(cleanup, dir, 0744); - - SAFE_STAT(cleanup, dir, &s); - if (!S_ISDIR(s.st_mode)) { - tst_brkm(TBROK, cleanup, "%s is not directory", dir); - return 0; - } - - sprintf(base_filename, "%s/testfile0", dir); - SAFE_TOUCH(cleanup, base_filename, 0644, NULL); - - for (i = 1; i < MAX_SANE_HARD_LINKS; i++) { - sprintf(link_filename, "%s/testfile%d", dir, i); - - if (link(base_filename, link_filename) == 0) - continue; - - switch (errno) { - case EMLINK: - SAFE_STAT(cleanup, base_filename, &s); - if (s.st_nlink != i) { - tst_brkm(TBROK, cleanup, "wrong number of " - "hard links for %s have %i, should be" - " %d", base_filename, - (int)s.st_nlink, i); - return 0; - } else { - tst_resm(TINFO, "the maximum number of hard " - "links to %s is hit: %d", - base_filename, (int)s.st_nlink); - return s.st_nlink; - } - case ENOSPC: - case EDQUOT: - tst_resm(TINFO | TERRNO, "link(%s, %s) failed", - base_filename, link_filename); - goto max_hardlinks_cleanup; - default: - tst_brkm(TBROK, cleanup, "link(%s, %s) failed " - "unexpectedly: %s", base_filename, - link_filename, strerror(errno)); - return 0; - } - } - - tst_resm(TINFO, "Failed reach the hardlinks limit"); - -max_hardlinks_cleanup: - for (j = 0; j < i; j++) { - sprintf(link_filename, "%s/testfile%d", dir, j); - SAFE_UNLINK(cleanup, link_filename); - } - - return 0; -} - -int tst_fs_fill_subdirs_(void (*cleanup) (void), const char *dir) -{ - unsigned int i, j, whitelist_size; - char dirname[PATH_MAX]; - struct stat s; - long fs_type; - - if (stat(dir, &s) == -1 && errno == ENOENT) - SAFE_MKDIR(cleanup, dir, 0744); - - SAFE_STAT(cleanup, dir, &s); - if (!S_ISDIR(s.st_mode)) { - tst_brkm(TBROK, cleanup, "%s is not directory", dir); - return 0; - } - - /* for current kernel, subdir limit is not availiable for all fs */ - fs_type = tst_fs_type(cleanup, dir); - - whitelist_size = ARRAY_SIZE(subdir_limit_whitelist); - for (i = 0; i < whitelist_size; i++) { - if (fs_type == subdir_limit_whitelist[i]) - break; - } - if (i == whitelist_size) { - tst_resm(TINFO, "subdir limit is not availiable for " - "%s filesystem", tst_fs_type_name(fs_type)); - return 0; - } - - for (i = 0; i < MAX_SANE_HARD_LINKS; i++) { - sprintf(dirname, "%s/testdir%d", dir, i); - - if (mkdir(dirname, 0755) == 0) - continue; - - switch (errno) { - case EMLINK: - SAFE_STAT(cleanup, dir, &s); - /* - * i+2 because there are two links to each newly - * created directory (the '.' and link from parent dir) - */ - if (s.st_nlink != (i + 2)) { - tst_brkm(TBROK, cleanup, "%s link counts have" - "%d, should be %d", dir, - (int)s.st_nlink, i + 2); - return 0; - } else { - tst_resm(TINFO, "the maximum subdirectories in " - "%s is hit: %d", dir, (int)s.st_nlink); - return s.st_nlink; - } - case ENOSPC: - case EDQUOT: - tst_resm(TINFO | TERRNO, "mkdir(%s, 0755) failed", - dirname); - goto max_subdirs_cleanup; - default: - tst_brkm(TBROK, cleanup, "mkdir(%s, 0755) failed " - "unexpectedly: %s", dirname, - strerror(errno)); - return 0; - } - - } - - tst_resm(TINFO, "Failed reach the subdirs limit on %s filesystem", - tst_fs_type_name(fs_type)); - -max_subdirs_cleanup: - for (j = 0; j < i; j++) { - sprintf(dirname, "%s/testdir%d", dir, j); - SAFE_RMDIR(cleanup, dirname); - } - - return 0; -} diff --git a/kernel/tests/lib/tst_fs_setup.c b/kernel/tests/lib/tst_fs_setup.c deleted file mode 100644 index 54ea370..0000000 --- a/kernel/tests/lib/tst_fs_setup.c +++ /dev/null @@ -1,49 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later - -#include <dirent.h> -#include <errno.h> -#include <sys/mount.h> - -#define TST_NO_DEFAULT_MAIN -#include "tst_test.h" -#include "tst_fs.h" - -#define TST_FS_SETUP_OVERLAYFS_MSG "overlayfs is not configured in this kernel" -#define TST_FS_SETUP_OVERLAYFS_CONFIG "lowerdir="OVL_LOWER",upperdir="OVL_UPPER",workdir="OVL_WORK - -void create_overlay_dirs(void) -{ - DIR *dir = opendir(OVL_LOWER); - if (dir == NULL) { - SAFE_MKDIR(OVL_LOWER, 0755); - SAFE_MKDIR(OVL_UPPER, 0755); - SAFE_MKDIR(OVL_WORK, 0755); - SAFE_MKDIR(OVL_MNT, 0755); - return; - } - closedir(dir); -} - -int mount_overlay(const char *file, const int lineno, int skip) -{ - int ret; - - create_overlay_dirs(); - ret = mount("overlay", OVL_MNT, "overlay", 0, - TST_FS_SETUP_OVERLAYFS_CONFIG); - if (ret == 0) - return 0; - - if (errno == ENODEV) { - if (skip) { - tst_brk(TCONF, "%s:%d: " TST_FS_SETUP_OVERLAYFS_MSG, - file, lineno); - } else { - tst_res(TINFO, "%s:%d: " TST_FS_SETUP_OVERLAYFS_MSG, - file, lineno); - } - } else { - tst_brk(TBROK | TERRNO, "overlayfs mount failed"); - } - return ret; -} diff --git a/kernel/tests/lib/tst_fs_type.c b/kernel/tests/lib/tst_fs_type.c deleted file mode 100644 index 1d0ac96..0000000 --- a/kernel/tests/lib/tst_fs_type.c +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) 2005-2014 Linux Test Project - * - * Cyril Hrubis <chrubis@suse.cz> 2014 - * Michal Simek <monstr@monstr.eu> 2009 - * Kumar Gala <galak@kernel.crashing.org> 2007 - * Ricky Ng-Adam <rngadam@yahoo.com> 2005 - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it would be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * Further, this software is distributed without any warranty that it is - * free of the rightful claim of any third person regarding infringement - * or the like. Any license provided herein, whether implied or - * otherwise, applies only to this software file. Patent licenses, if - * any, provided herein do not apply to combinations of this program with - * other software, or any other product whatsoever. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include <sys/vfs.h> -#include "test.h" -#include "tst_fs.h" - -long tst_fs_type_(void (*cleanup)(void), const char *path) -{ - struct statfs sbuf; - - if (statfs(path, &sbuf)) { - tst_brkm(TBROK | TERRNO, cleanup, - "tst_fs_type: Failed to statfs(%s)", path); - return 0; - } - - return sbuf.f_type; -} - -const char *tst_fs_type_name(long f_type) -{ - switch (f_type) { - case TST_TMPFS_MAGIC: - return "TMPFS"; - case TST_NFS_MAGIC: - return "NFS"; - case TST_V9FS_MAGIC: - return "9P"; - case TST_RAMFS_MAGIC: - return "RAMFS"; - case TST_BTRFS_MAGIC: - return "BTRFS"; - case TST_XFS_MAGIC: - return "XFS"; - case TST_EXT2_OLD_MAGIC: - return "EXT2"; - case TST_EXT234_MAGIC: - return "EXT2/EXT3/EXT4"; - case TST_MINIX_MAGIC: - case TST_MINIX_MAGIC2: - case TST_MINIX2_MAGIC: - case TST_MINIX2_MAGIC2: - case TST_MINIX3_MAGIC: - return "MINIX"; - case TST_UDF_MAGIC: - return "UDF"; - case TST_SYSV2_MAGIC: - case TST_SYSV4_MAGIC: - return "SYSV"; - case TST_UFS_MAGIC: - case TST_UFS2_MAGIC: - return "UFS"; - case TST_F2FS_MAGIC: - return "F2FS"; - case TST_NILFS_MAGIC: - return "NILFS"; - case TST_EXOFS_MAGIC: - return "EXOFS"; - case TST_OVERLAYFS_MAGIC: - return "OVERLAYFS"; - default: - return "Unknown"; - } -} diff --git a/kernel/tests/lib/tst_get_bad_addr.c b/kernel/tests/lib/tst_get_bad_addr.c deleted file mode 100644 index 098e72b..0000000 --- a/kernel/tests/lib/tst_get_bad_addr.c +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. - * - * 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, see <http://www.gnu.org/licenses/>. - */ - -#include <sys/mman.h> -#include "test.h" -#include "tst_get_bad_addr.h" - -void *tst_get_bad_addr(void (*cleanup_fn) (void)) -{ - void *bad_addr; - - bad_addr = mmap(0, 1, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0); - if (bad_addr == MAP_FAILED) - tst_brkm(TBROK, cleanup_fn, "mmap() failed to get bad address"); - - return bad_addr; -} diff --git a/kernel/tests/lib/tst_hugepage.c b/kernel/tests/lib/tst_hugepage.c deleted file mode 100644 index 1d0e62e..0000000 --- a/kernel/tests/lib/tst_hugepage.c +++ /dev/null @@ -1,61 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (c) 2019 Red Hat, Inc. - */ - -#define TST_NO_DEFAULT_MAIN - -#include "tst_test.h" -#include "tst_hugepage.h" - -unsigned long tst_hugepages; -char *nr_opt; -char *Hopt; - -size_t tst_get_hugepage_size(void) -{ - if (access(PATH_HUGEPAGES, F_OK)) - return 0; - - return SAFE_READ_MEMINFO("Hugepagesize:") * 1024; -} - -unsigned long tst_request_hugepages(unsigned long hpages) -{ - unsigned long val, max_hpages; - - if (access(PATH_HUGEPAGES, F_OK)) { - tst_hugepages = 0; - goto out; - } - - if (nr_opt) - tst_hugepages = SAFE_STRTOL(nr_opt, 1, LONG_MAX); - else - tst_hugepages = hpages; - - SAFE_FILE_PRINTF("/proc/sys/vm/drop_caches", "3"); - max_hpages = SAFE_READ_MEMINFO("MemFree:") / SAFE_READ_MEMINFO("Hugepagesize:"); - - if (tst_hugepages > max_hpages) { - tst_res(TINFO, "Requested number(%lu) of hugepages is too large, " - "limiting to 80%% of the max hugepage count %lu", - tst_hugepages, max_hpages); - tst_hugepages = max_hpages * 0.8; - - if (tst_hugepages < 1) - goto out; - } - - tst_sys_conf_save("?/proc/sys/vm/nr_hugepages"); - SAFE_FILE_PRINTF(PATH_NR_HPAGES, "%lu", tst_hugepages); - SAFE_FILE_SCANF(PATH_NR_HPAGES, "%lu", &val); - if (val != tst_hugepages) - tst_brk(TCONF, "nr_hugepages = %lu, but expect %lu. " - "Not enough hugepages for testing.", - val, tst_hugepages); - - tst_res(TINFO, "%lu hugepage(s) reserved", tst_hugepages); -out: - return tst_hugepages; -} diff --git a/kernel/tests/lib/tst_ioctl.c b/kernel/tests/lib/tst_ioctl.c deleted file mode 100644 index 364220b..0000000 --- a/kernel/tests/lib/tst_ioctl.c +++ /dev/null @@ -1,37 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later - -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <sys/ioctl.h> -#include <linux/fs.h> - -#define TST_NO_DEFAULT_MAIN - -#include "tst_test.h" - -int tst_fibmap(const char *filename) -{ - /* test if FIBMAP ioctl is supported */ - int fd, block = 0; - - fd = open(filename, O_RDWR | O_CREAT, 0666); - if (fd < 0) { - tst_res(TWARN | TERRNO, - "open(%s, O_RDWR | O_CREAT, 0666) failed", filename); - return -1; - } - - if (ioctl(fd, FIBMAP, &block)) { - tst_res(TINFO | TERRNO, "FIBMAP ioctl is NOT supported"); - close(fd); - return 1; - } - tst_res(TINFO, "FIBMAP ioctl is supported"); - - if (close(fd)) { - tst_res(TWARN | TERRNO, "close(fd) failed"); - return -1; - } - return 0; -} diff --git a/kernel/tests/lib/tst_kconfig.c b/kernel/tests/lib/tst_kconfig.c deleted file mode 100644 index d49187b..0000000 --- a/kernel/tests/lib/tst_kconfig.c +++ /dev/null @@ -1,285 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (c) 2018 Cyril Hrubis <chrubis@suse.cz> - */ - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <ctype.h> -#include <sys/utsname.h> - -#define TST_NO_DEFAULT_MAIN -#include "tst_test.h" -#include "tst_kconfig.h" - -static const char *kconfig_path(char *path_buf, size_t path_buf_len) -{ - const char *path = getenv("KCONFIG_PATH"); - struct utsname un; - - if (path) { - if (!access(path, F_OK)) - return path; - - tst_res(TWARN, "KCONFIG_PATH='%s' does not exist", path); - } - - if (!access("/proc/config.gz", F_OK)) - return "/proc/config.gz"; - - uname(&un); - - /* Debian and derivatives */ - snprintf(path_buf, path_buf_len, "/boot/config-%s", un.release); - - if (!access(path_buf, F_OK)) - return path_buf; - - /* Clear Linux */ - snprintf(path_buf, path_buf_len, "/lib/kernel/config-%s", un.release); - - if (!access(path_buf, F_OK)) - return path_buf; - - tst_res(TINFO, "Couldn't locate kernel config!"); - - return NULL; -} - -static char is_gzip; - -static FILE *open_kconfig(void) -{ - FILE *fp; - char buf[1064]; - char path_buf[1024]; - const char *path = kconfig_path(path_buf, sizeof(path_buf)); - - if (!path) - return NULL; - - tst_res(TINFO, "Parsing kernel config '%s'", path); - - is_gzip = !!strstr(path, ".gz"); - - if (is_gzip) { - snprintf(buf, sizeof(buf), "zcat '%s'", path); - fp = popen(buf, "r"); - } else { - fp = fopen(path, "r"); - } - - if (!fp) - tst_brk(TBROK | TERRNO, "Failed to open '%s'", path); - - return fp; -} - -static void close_kconfig(FILE *fp) -{ - if (is_gzip) - pclose(fp); - else - fclose(fp); -} - -struct match { - /* match len, string length up to \0 or = */ - size_t len; - /* if set part of conf string after = */ - const char *val; - /* if set the config option was matched already */ - int match; -}; - -static int is_set(const char *str, const char *val) -{ - size_t vlen = strlen(val); - - while (isspace(*str)) - str++; - - if (strncmp(str, val, vlen)) - return 0; - - switch (str[vlen]) { - case ' ': - case '\n': - case '\0': - return 1; - break; - default: - return 0; - } -} - -static inline int match(struct match *match, const char *conf, - struct tst_kconfig_res *result, const char *line) -{ - if (match->match) - return 0; - - const char *cfg = strstr(line, "CONFIG_"); - - if (!cfg) - return 0; - - if (strncmp(cfg, conf, match->len)) - return 0; - - const char *val = &cfg[match->len]; - - switch (cfg[match->len]) { - case '=': - break; - case ' ': - if (is_set(val, "is not set")) { - result->match = 'n'; - goto match; - } - /* fall through */ - default: - return 0; - } - - if (is_set(val, "=y")) { - result->match = 'y'; - goto match; - } - - if (is_set(val, "=m")) { - result->match = 'm'; - goto match; - } - - result->match = 'v'; - result->value = strndup(val+1, strlen(val)-2); - -match: - match->match = 1; - return 1; -} - -void tst_kconfig_read(const char *const *kconfigs, - struct tst_kconfig_res results[], size_t cnt) -{ - struct match matches[cnt]; - FILE *fp; - unsigned int i, j; - char buf[1024]; - - for (i = 0; i < cnt; i++) { - const char *val = strchr(kconfigs[i], '='); - - if (strncmp("CONFIG_", kconfigs[i], 7)) - tst_brk(TBROK, "Invalid config string '%s'", kconfigs[i]); - - matches[i].match = 0; - matches[i].len = strlen(kconfigs[i]); - - if (val) { - matches[i].val = val + 1; - matches[i].len -= strlen(val); - } - - results[i].match = 0; - results[i].value = NULL; - } - - fp = open_kconfig(); - if (!fp) - tst_brk(TBROK, "Cannot parse kernel .config"); - - while (fgets(buf, sizeof(buf), fp)) { - for (i = 0; i < cnt; i++) { - if (match(&matches[i], kconfigs[i], &results[i], buf)) { - for (j = 0; j < cnt; j++) { - if (matches[j].match) - break; - } - - if (j == cnt) - goto exit; - } - } - - } - -exit: - close_kconfig(fp); -} - -static size_t array_len(const char *const kconfigs[]) -{ - size_t i = 0; - - while (kconfigs[++i]); - - return i; -} - -static int compare_res(struct tst_kconfig_res *res, const char *kconfig, - char match, const char *val) -{ - if (res->match != match) { - tst_res(TINFO, "Needs kernel %s, have %c", kconfig, res->match); - return 1; - } - - if (match != 'v') - return 0; - - if (strcmp(res->value, val)) { - tst_res(TINFO, "Needs kernel %s, have %s", kconfig, res->value); - return 1; - } - - return 0; -} - -void tst_kconfig_check(const char *const kconfigs[]) -{ - size_t cnt = array_len(kconfigs); - struct tst_kconfig_res results[cnt]; - unsigned int i; - int abort_test = 0; - - tst_kconfig_read(kconfigs, results, cnt); - - for (i = 0; i < cnt; i++) { - if (results[i].match == 0) { - tst_res(TINFO, "Missing kernel %s", kconfigs[i]); - abort_test = 1; - continue; - } - - if (results[i].match == 'n') { - tst_res(TINFO, "Kernel %s is not set", kconfigs[i]); - abort_test = 1; - continue; - } - - const char *val = strchr(kconfigs[i], '='); - - if (val) { - char match = 'v'; - val++; - - if (!strcmp(val, "y")) - match = 'y'; - - if (!strcmp(val, "m")) - match = 'm'; - - if (compare_res(&results[i], kconfigs[i], match, val)) - abort_test = 1; - - } - - free(results[i].value); - } - - if (abort_test) - tst_brk(TCONF, "Aborting due to unsuitable kernel config, see above!"); -} diff --git a/kernel/tests/lib/tst_kernel.c b/kernel/tests/lib/tst_kernel.c deleted file mode 100644 index 57fa4b2..0000000 --- a/kernel/tests/lib/tst_kernel.c +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (c) 2017 Cyril Hrubis <chrubis@suse.cz> - * - * 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, see <http://www.gnu.org/licenses/>. - */ - -#include <sys/personality.h> -#include <sys/utsname.h> -#include "test.h" -#include "tst_kernel.h" - -static int get_kernel_bits_from_uname(struct utsname *buf) -{ - if (uname(buf)) { - tst_brkm(TBROK | TERRNO, NULL, "uname()"); - return -1; - } - - return strstr(buf->machine, "64") ? 64 : 32; -} - -int tst_kernel_bits(void) -{ - struct utsname buf; - int kernel_bits = get_kernel_bits_from_uname(&buf); - - if (kernel_bits == -1) - return -1; - - /* - * ARM64 (aarch64) defines 32-bit compatibility modes as - * armv8l and armv8b (little and big endian). - * s390x is 64bit but not contain 64 in the words. - */ - if (!strcmp(buf.machine, "armv8l") || !strcmp(buf.machine, "armv8b") - || !strcmp(buf.machine, "s390x")) - kernel_bits = 64; - -#ifdef __ANDROID__ - /* Android's bionic libc sets the PER_LINUX32 personality for all 32-bit - * programs. This will cause buf.machine to report as i686 even though - * the kernel itself is 64-bit. - */ - if (!strcmp(buf.machine, "i686") && - (personality(0xffffffff) & PER_MASK) == PER_LINUX32) { - /* Set the personality back to the default. */ - if (personality(PER_LINUX) == -1) { - tst_brkm(TBROK | TERRNO, NULL, "personality()"); - return -1; - } - - /* Redo the uname check without the PER_LINUX32 personality to - * determine the actual kernel bits value. - */ - kernel_bits = get_kernel_bits_from_uname(&buf); - if (kernel_bits == -1) - return -1; - - /* Set the personality back to PER_LINUX32. */ - if (personality(PER_LINUX32) == -1) { - tst_brkm(TBROK | TERRNO, NULL, "personality()"); - return -1; - } - } -#endif /* __ANDROID__ */ - - tst_resm(TINFO, "uname.machine=%s kernel is %ibit", - buf.machine, kernel_bits); - - return kernel_bits; -} - -int tst_check_driver(const char *name) -{ -#ifndef __ANDROID__ - const char * const argv[] = { "modprobe", "-n", name, NULL }; - int res = tst_cmd_(NULL, argv, "/dev/null", "/dev/null", - TST_CMD_PASS_RETVAL); - - /* 255 - it looks like modprobe not available */ - return (res == 255) ? 0 : res; -#else - /* Android modprobe may not have '-n', or properly installed - * module.*.bin files to determine built-in drivers. Assume - * all drivers are available. - */ - return 0; -#endif -} diff --git a/kernel/tests/lib/tst_kvercmp.c b/kernel/tests/lib/tst_kvercmp.c deleted file mode 100644 index 5d56e30..0000000 --- a/kernel/tests/lib/tst_kvercmp.c +++ /dev/null @@ -1,195 +0,0 @@ -/* - * Copyright (c) International Business Machines Corp., 2003 - * AUTHOR: Paul Larson <plars@linuxtestproject.org> - * Copyright (c) 2016 Cyril Hrubis <chrubis@suse.cz> - * - * 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 - */ - -#include <ctype.h> -#include <stdlib.h> -#include <unistd.h> -#include <string.h> -#include <limits.h> -#include <sys/utsname.h> -#include "test.h" - -#define OSRELEASE_PATH "/etc/os-release" - -static char *parse_digit(const char *str, int *d) -{ - unsigned long v; - char *end; - - v = strtoul(str, &end, 10); - if (str == end) - return NULL; - - if (v > INT_MAX) - return NULL; - - *d = v; - - return end; -} - -int tst_parse_kver(const char *str_kver, int *v1, int *v2, int *v3) -{ - const char *str = str_kver; - - *v1 = 0; - *v2 = 0; - *v3 = 0; - - if (!(str = parse_digit(str, v1))) - return 1; - - if (*(str++) != '.') - return 1; - - if (!(str = parse_digit(str, v2))) - return 1; - - /* - * Check for a short version e.g '2.4' - */ - if (*str == ' ' || *str == '\0') - return 0; - - if (*(str++) != '.') - return 1; - - /* - * Ignore rest of the string in order not to break on versions as - * 4.8.1-52-default. - */ - if (!parse_digit(str, v3)) - return 1; - - return 0; -} - -int tst_kvcmp(const char *cur_kver, int r1, int r2, int r3) -{ - int a1, a2, a3; - int testver, currver; - - if (tst_parse_kver(cur_kver, &a1, &a2, &a3)) { - tst_resm(TWARN, - "Invalid kernel version %s, expected %%d.%%d.%%d", - cur_kver); - } - - testver = (r1 << 16) + (r2 << 8) + r3; - currver = (a1 << 16) + (a2 << 8) + a3; - - return currver - testver; -} - -int tst_kvercmp(int r1, int r2, int r3) -{ - struct utsname uval; - - uname(&uval); - - return tst_kvcmp(uval.release, r1, r2, r3); -} - -int tst_kvexcmp(const char *tst_exv, const char *cur_ver) -{ - int c1 = 0, c2 = 0, c3 = 0, c4 = 0, c5 = 0; - int t1 = 0, t2 = 0, t3 = 0, t4 = 0, t5 = 0; - int ret; - - sscanf(cur_ver, "%d.%d.%d-%d.%d", &c1, &c2, &c3, &c4, &c5); - sscanf(tst_exv, "%d.%d.%d-%d.%d", &t1, &t2, &t3, &t4, &t5); - - if ((ret = c1 - t1)) - return ret; - if ((ret = c2 - t2)) - return ret; - if ((ret = c3 - t3)) - return ret; - if ((ret = c4 - t4)) - return ret; - - return c5 - t5; -} - -const char *tst_kvcmp_distname(const char *kver) -{ - static char distname[64]; - char *ret = distname; - char *p = distname; - - if (strstr(kver, ".el5uek")) - return "OL5UEK"; - - if (strstr(kver, ".el5")) - return "RHEL5"; - - if (strstr(kver, ".el6uek")) - return "OL6UEK"; - - if (strstr(kver, ".el6")) - return "RHEL6"; - - if (access(OSRELEASE_PATH, F_OK) != -1) { - SAFE_FILE_LINES_SCANF(NULL, OSRELEASE_PATH, "ID=%s", distname); - - if (p[0] == '"') { - ret = distname + 1; - p = ret; - } - - while (*p) { - if (*p == '"') { - *p = 0; - break; - } - *p = toupper((unsigned char)*p); - p++; - } - - return ret; - } - - return NULL; -} - -int tst_kvercmp2(int r1, int r2, int r3, struct tst_kern_exv *vers) -{ - int i; - const char *kver; - struct utsname uval; - const char *cur_dist_name; - - uname(&uval); - kver = uval.release; - cur_dist_name = tst_kvcmp_distname(kver); - - if (cur_dist_name == NULL) - return tst_kvercmp(r1, r2, r3); - - for (i = 0; vers[i].dist_name; i++) { - if (!strcmp(vers[i].dist_name, cur_dist_name)) { - tst_resm(TINFO, "Detected %s using kernel version %s", - cur_dist_name, kver); - return tst_kvexcmp(vers[i].extra_ver, kver); - } - } - - return tst_kvcmp(kver, r1, r2, r3); -} diff --git a/kernel/tests/lib/tst_lockdown.c b/kernel/tests/lib/tst_lockdown.c deleted file mode 100644 index e7c1981..0000000 --- a/kernel/tests/lib/tst_lockdown.c +++ /dev/null @@ -1,30 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later - -#define TST_NO_DEFAULT_MAIN - -#include <stdio.h> -#include <stdlib.h> -#include <sys/mount.h> - -#include "tst_test.h" -#include "tst_safe_macros.h" -#include "tst_safe_stdio.h" -#include "tst_lockdown.h" - -int tst_lockdown_enabled(void) -{ - char line[BUFSIZ]; - FILE *file; - - if (access(PATH_LOCKDOWN, F_OK) != 0) { - tst_res(TINFO, "Unable to determine system lockdown state"); - return 0; - } - - file = SAFE_FOPEN(PATH_LOCKDOWN, "r"); - if (!fgets(line, sizeof(line), file)) - tst_brk(TBROK | TERRNO, "fgets %s", PATH_LOCKDOWN); - SAFE_FCLOSE(file); - - return (strstr(line, "[none]") == NULL); -} diff --git a/kernel/tests/lib/tst_memutils.c b/kernel/tests/lib/tst_memutils.c deleted file mode 100644 index f134d90..0000000 --- a/kernel/tests/lib/tst_memutils.c +++ /dev/null @@ -1,62 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (c) 2020 SUSE LLC <mdoucha@suse.cz> - */ - -#include <unistd.h> -#include <limits.h> -#include <sys/sysinfo.h> -#include <stdlib.h> - -#define TST_NO_DEFAULT_MAIN -#include "tst_test.h" - -#define BLOCKSIZE (16 * 1024 * 1024) - -void tst_pollute_memory(size_t maxsize, int fillchar) -{ - size_t i, map_count = 0, safety = 0, blocksize = BLOCKSIZE; - void **map_blocks; - struct sysinfo info; - - SAFE_SYSINFO(&info); - safety = 4096 * SAFE_SYSCONF(_SC_PAGESIZE) / info.mem_unit; - - if (info.freeswap > safety) - safety = 0; - - /* Not enough free memory to avoid invoking OOM killer */ - if (info.freeram <= safety) - return; - - if (!maxsize) - maxsize = SIZE_MAX; - - if (info.freeram - safety < maxsize / info.mem_unit) - maxsize = (info.freeram - safety) * info.mem_unit; - - blocksize = MIN(maxsize, blocksize); - map_count = maxsize / blocksize; - map_blocks = SAFE_MALLOC(map_count * sizeof(void *)); - - /* - * Keep allocating until the first failure. The address space may be - * too fragmented or just smaller than maxsize. - */ - for (i = 0; i < map_count; i++) { - map_blocks[i] = mmap(NULL, blocksize, PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); - - if (map_blocks[i] == MAP_FAILED) { - map_count = i; - break; - } - - memset(map_blocks[i], fillchar, blocksize); - } - - for (i = 0; i < map_count; i++) - SAFE_MUNMAP(map_blocks[i], blocksize); - - free(map_blocks); -} diff --git a/kernel/tests/lib/tst_mkfs.c b/kernel/tests/lib/tst_mkfs.c deleted file mode 100644 index 38b2e71..0000000 --- a/kernel/tests/lib/tst_mkfs.c +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright (c) 2013-2016 Cyril Hrubis <chrubis@suse.cz> - * - * 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, see <http://www.gnu.org/licenses/>. - */ - -#include "test.h" -#include "ltp_priv.h" -#include "tst_mkfs.h" -#include "tst_device.h" - -#define OPTS_MAX 32 - -void tst_mkfs_(const char *file, const int lineno, void (cleanup_fn)(void), - const char *dev, const char *fs_type, - const char *const fs_opts[], const char *const extra_opts[]) -{ - int i, pos = 1, ret; - char mkfs[64]; - const char *argv[OPTS_MAX] = {mkfs}; - char fs_opts_str[1024] = ""; - char extra_opts_str[1024] = ""; - - if (!dev) { - tst_brkm(TBROK, cleanup_fn, - "%s:%d: No device specified", file, lineno); - return; - } - - if (!fs_type) { - tst_brkm(TBROK, cleanup_fn, - "%s:%d: No fs_type specified", file, lineno); - return; - } - - snprintf(mkfs, sizeof(mkfs), "mkfs.%s", fs_type); - - if (fs_opts) { - for (i = 0; fs_opts[i]; i++) { - argv[pos++] = fs_opts[i]; - - if (pos + 2 > OPTS_MAX) { - tst_brkm(TBROK, cleanup_fn, - "%s:%d: Too much mkfs options", - file, lineno); - return; - } - - if (i) - strcat(fs_opts_str, " "); - strcat(fs_opts_str, fs_opts[i]); - } - } - - argv[pos++] = dev; - - if (extra_opts) { - for (i = 0; extra_opts[i]; i++) { - argv[pos++] = extra_opts[i]; - - if (pos + 1 > OPTS_MAX) { - tst_brkm(TBROK, cleanup_fn, - "%s:%d: Too much mkfs options", file, lineno); - return; - } - - if (i) - strcat(extra_opts_str, " "); - strcat(extra_opts_str, extra_opts[i]); - } - } - - argv[pos] = NULL; - - if (tst_clear_device(dev)) - tst_brkm(TBROK, cleanup_fn, "tst_clear_device() failed"); - - tst_resm(TINFO, "Formatting %s with %s opts='%s' extra opts='%s'", - dev, fs_type, fs_opts_str, extra_opts_str); - ret = tst_cmd(cleanup_fn, argv, "/dev/null", NULL, TST_CMD_PASS_RETVAL | - TST_CMD_TCONF_ON_MISSING); - - switch (ret) { - case 0: - break; - case 255: - tst_brkm(TCONF, cleanup_fn, - "%s:%d: %s not found in $PATH", file, lineno, mkfs); - break; - default: - tst_brkm(TBROK, cleanup_fn, - "%s:%d: %s failed with %i", file, lineno, mkfs, ret); - } -} - -const char *tst_dev_fs_type(void) -{ - const char *fs_type; - - fs_type = getenv("LTP_DEV_FS_TYPE"); - - if (fs_type) - return fs_type; - - return DEFAULT_FS_TYPE; -} diff --git a/kernel/tests/lib/tst_module.c b/kernel/tests/lib/tst_module.c deleted file mode 100644 index eda6187..0000000 --- a/kernel/tests/lib/tst_module.c +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All Rights Reserved. - * - * 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 would 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 the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - * Author: Alexey Kodanev <alexey.kodanev@oracle.com> - * - */ - -#define _GNU_SOURCE -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> - -#include "test.h" -#include "ltp_priv.h" -#include "old_module.h" - -void tst_module_exists(void (cleanup_fn)(void), - const char *mod_name, char **mod_path) -{ - /* check current working directory */ - if (access(mod_name, F_OK) == 0) { - if (mod_path != NULL) - *mod_path = strdup(mod_name); - return; - } - char *buf = NULL; - int err = -1; - /* check LTP installation path */ - const char *ltproot = getenv("LTPROOT"); - if (ltproot != NULL) { - if (asprintf(&buf, "%s/testcases/bin/%s", - ltproot, mod_name) == -1) { - tst_brkm(TBROK | TERRNO, cleanup_fn, - "asprintf failed at %s:%d", - __FILE__, __LINE__); - return; - } - err = access(buf, F_OK); - } - /* check start working directory */ - if (err == -1 && tst_tmpdir_created()) { - free(buf); - if (asprintf(&buf, "%s/%s", tst_get_startwd(), - mod_name) == -1) { - tst_brkm(TBROK | TERRNO, cleanup_fn, - "asprintf failed at %s:%d", - __FILE__, __LINE__); - return; - } - err = access(buf, F_OK); - } - - if (err != 0) { - free(buf); - tst_brkm(TCONF, cleanup_fn, "Failed to find module '%s'", - mod_name); - return; - } - - if (mod_path != NULL) - *mod_path = buf; - else - free(buf); -} - -void tst_module_load(void (cleanup_fn)(void), - const char *mod_name, char *const argv[]) -{ - char *mod_path = NULL; - tst_module_exists(cleanup_fn, mod_name, &mod_path); - - const int offset = 2; /* command name & module path */ - int size = 0; - while (argv && argv[size]) - ++size; - size += offset; - const char *mod_argv[size + 1]; /* + NULL in the end */ - mod_argv[size] = NULL; - mod_argv[0] = "insmod"; - mod_argv[1] = mod_path; - - int i; - for (i = offset; i < size; ++i) - mod_argv[i] = argv[i - offset]; - - tst_cmd(cleanup_fn, mod_argv, NULL, NULL, 0); - free(mod_path); -} - -void tst_module_unload(void (cleanup_fn)(void), const char *mod_name) -{ - int i, rc; - - const char *const argv[] = { "rmmod", mod_name, NULL }; - - rc = 1; - for (i = 0; i < 50; i++) { - rc = tst_cmd(NULL, argv, "/dev/null", "/dev/null", - TST_CMD_PASS_RETVAL); - if (!rc) - break; - - usleep(20000); - } - - if (rc) { - tst_brkm(TBROK, cleanup_fn, - "could not unload %s module", mod_name); - } -} diff --git a/kernel/tests/lib/tst_net.c b/kernel/tests/lib/tst_net.c deleted file mode 100644 index 8a589b0..0000000 --- a/kernel/tests/lib/tst_net.c +++ /dev/null @@ -1,221 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (c) 2017-2019 Petr Vorel <pvorel@suse.cz> - * Copyright (c) 2019 Martin Doucha <mdoucha@suse.cz> - */ - -#include <errno.h> -#include <netdb.h> -#include <string.h> -#include <stdlib.h> - -#define TST_NO_DEFAULT_MAIN -#include "tst_test.h" -#include "tst_net.h" -#include "tst_private.h" - -void tst_print_svar(const char *name, const char *val) -{ - if (name && val) - printf("export %s=\"%s\"\n", name, val); -} - -void tst_print_svar_change(const char *name, const char *val) -{ - if (name && val) - printf("export %s=\"${%s:-%s}\"\n", name, name, val); -} - -/* - * Function bit_count is from ipcalc project, ipcalc.c. - */ -static int tst_bit_count(uint32_t i) -{ - int c = 0; - unsigned int seen_one = 0; - - while (i > 0) { - if (i & 1) { - seen_one = 1; - c++; - } else { - if (seen_one) - return -1; - } - i >>= 1; - } - - return c; -} - -/* - * Function mask2prefix is from ipcalc project, ipcalc.c. - */ -static int tst_mask2prefix(struct in_addr mask) -{ - return tst_bit_count(ntohl(mask.s_addr)); -} - -/* - * Function ipv4_mask_to_int is from ipcalc project, ipcalc.c. - */ -static int tst_ipv4_mask_to_int(const char *prefix) -{ - int ret; - struct in_addr in; - - ret = inet_pton(AF_INET, prefix, &in); - if (ret == 0) - return -1; - - return tst_mask2prefix(in); -} - -/* - * Function safe_atoi is from ipcalc project, ipcalc.c. - */ -static int tst_safe_atoi(const char *s, int *ret_i) -{ - char *x = NULL; - long l; - - errno = 0; - l = strtol(s, &x, 0); - - if (!x || x == s || *x || errno) - return errno > 0 ? -errno : -EINVAL; - - if ((long)(int)l != l) - return -ERANGE; - - *ret_i = (int)l; - - return 0; -} - -/* - * Function get_prefix use code from ipcalc project, str_to_prefix/ipcalc.c. - */ -int tst_get_prefix(const char *ip_str, int is_ipv6) -{ - char *prefix_str = NULL; - int prefix = -1, r; - - prefix_str = strchr(ip_str, '/'); - if (!prefix_str) - return -1; - - *(prefix_str++) = '\0'; - - if (!is_ipv6 && strchr(prefix_str, '.')) - prefix = tst_ipv4_mask_to_int(prefix_str); - else { - r = tst_safe_atoi(prefix_str, &prefix); - if (r != 0) - tst_brk_comment("conversion error: '%s' is not integer", - prefix_str); - } - - if (prefix < 0 || ((is_ipv6 && prefix > MAX_IPV6_PREFIX) || - (!is_ipv6 && prefix > MAX_IPV4_PREFIX))) - tst_brk_comment("bad %s prefix: %s", is_ipv6 ? "IPv6" : "IPv4", - prefix_str); - - return prefix; -} - -void tst_get_in_addr(const char *ip_str, struct in_addr *ip) -{ - if (inet_pton(AF_INET, ip_str, ip) <= 0) - tst_brk_comment("bad IPv4 address: '%s'", ip_str); -} - -void tst_get_in6_addr(const char *ip_str, struct in6_addr *ip6) -{ - if (inet_pton(AF_INET6, ip_str, ip6) <= 0) - tst_brk_comment("bad IPv6 address: '%s'", ip_str); -} - -socklen_t tst_get_connect_address(int sock, struct sockaddr_storage *addr) -{ - struct sockaddr_in *inet_ptr; - struct sockaddr_in6 *inet6_ptr; - size_t tmp_size; - socklen_t ret = sizeof(*addr); - - SAFE_GETSOCKNAME(sock, (struct sockaddr*)addr, &ret); - - /* Sanitize wildcard addresses */ - switch (addr->ss_family) { - case AF_INET: - inet_ptr = (struct sockaddr_in*)addr; - - switch (ntohl(inet_ptr->sin_addr.s_addr)) { - case INADDR_ANY: - case INADDR_BROADCAST: - inet_ptr->sin_addr.s_addr = htonl(INADDR_LOOPBACK); - break; - } - - break; - - case AF_INET6: - inet6_ptr = (struct sockaddr_in6*)addr; - tmp_size = sizeof(struct in6_addr); - - if (!memcmp(&inet6_ptr->sin6_addr, &in6addr_any, tmp_size)) { - memcpy(&inet6_ptr->sin6_addr, &in6addr_loopback, - tmp_size); - } - - break; - } - - return ret; -} - -void tst_init_sockaddr_inet(struct sockaddr_in *sa, const char *ip_str, uint16_t port) -{ - memset(sa, 0, sizeof(struct sockaddr_in)); - sa->sin_family = AF_INET; - sa->sin_port = htons(port); - tst_get_in_addr(ip_str, &sa->sin_addr); -} - -void tst_init_sockaddr_inet_bin(struct sockaddr_in *sa, uint32_t ip_val, uint16_t port) -{ - memset(sa, 0, sizeof(struct sockaddr_in)); - sa->sin_family = AF_INET; - sa->sin_port = htons(port); - sa->sin_addr.s_addr = htonl(ip_val); -} - -void tst_init_sockaddr_inet6(struct sockaddr_in6 *sa, const char *ip_str, uint16_t port) -{ - memset(sa, 0, sizeof(struct sockaddr_in6)); - sa->sin6_family = AF_INET6; - sa->sin6_port = htons(port); - tst_get_in6_addr(ip_str, &sa->sin6_addr); -} - -void tst_init_sockaddr_inet6_bin(struct sockaddr_in6 *sa, const struct in6_addr *ip_val, uint16_t port) -{ - memset(sa, 0, sizeof(struct sockaddr_in6)); - sa->sin6_family = AF_INET6; - sa->sin6_port = htons(port); - memcpy(&sa->sin6_addr, ip_val, sizeof(struct in6_addr)); -} - -void safe_getaddrinfo(const char *file, const int lineno, const char *src_addr, - const char *port, const struct addrinfo *hints, - struct addrinfo **addr_info) -{ - int err = getaddrinfo(src_addr, port, hints, addr_info); - - if (err) - tst_brk(TBROK, "%s:%d: getaddrinfo failed, %s", file, lineno, - gai_strerror(err)); - - if (!*addr_info) - tst_brk(TBROK, "%s:%d: failed to get the address", file, lineno); -} diff --git a/kernel/tests/lib/tst_parse_opts.c b/kernel/tests/lib/tst_parse_opts.c deleted file mode 100644 index 94970e1..0000000 --- a/kernel/tests/lib/tst_parse_opts.c +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2015 Cyril Hrubis chrubis@suse.cz - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it would be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * Further, this software is distributed without any warranty that it is - * free of the rightful claim of any third person regarding infringement - * or the like. Any license provided herein, whether implied or - * otherwise, applies only to this software file. Patent licenses, if - * any, provided herein do not apply to combinations of this program with - * other software, or any other product whatsoever. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include "test.h" -#include "ltp_priv.h" - -void tst_parse_opts(int argc, char *argv[], const option_t *user_optarg, - void (*user_help)(void)) -{ - const char *msg; - - msg = parse_opts(argc, argv, user_optarg, user_help); - - if (msg) - tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg); -} diff --git a/kernel/tests/lib/tst_path_has_mnt_flags.c b/kernel/tests/lib/tst_path_has_mnt_flags.c deleted file mode 100644 index 154bf41..0000000 --- a/kernel/tests/lib/tst_path_has_mnt_flags.c +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (c) 2014 Fujitsu Ltd. - * Author: Xing Gu <gux.fnst@cn.fujitsu.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it would be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include <unistd.h> -#include <mntent.h> -#include <stdio.h> -#include <string.h> -#include "test.h" - -/* - * Check whether a path is on a filesystem that is mounted with - * specified flags. - */ -int tst_path_has_mnt_flags_(void (cleanup_fn)(void), - const char *path, const char *flags[]) -{ - struct mntent *mnt; - size_t prefix_max = 0, prefix_len; - int flags_matched = 0; - FILE *f; - int i; - char *tmpdir = NULL; - - /* - * Default parameter is test temporary directory - */ - if (path == NULL) - path = tmpdir = tst_get_tmpdir(); - - if (access(path, F_OK) == -1) { - tst_brkm(TBROK | TERRNO, cleanup_fn, - "tst_path_has_mnt_flags: path %s doesn't exist", path); - return -1; - } - - f = setmntent("/proc/mounts", "r"); - if (f == NULL) { - tst_brkm(TBROK | TERRNO, cleanup_fn, - "tst_path_has_mnt_flags: failed to open /proc/mounts"); - return -1; - } - - while ((mnt = getmntent(f))) { - /* ignore duplicit record for root fs */ - if (!strcmp(mnt->mnt_fsname, "rootfs")) - continue; - - prefix_len = strlen(mnt->mnt_dir); - - if (strncmp(path, mnt->mnt_dir, prefix_len) == 0 - && prefix_len > prefix_max) { - prefix_max = prefix_len; - flags_matched = 0; - i = 0; - - while (flags[i] != NULL) { - if (hasmntopt(mnt, flags[i]) != NULL) - flags_matched++; - i++; - } - } - } - - endmntent(f); - - free(tmpdir); - - return flags_matched; -} diff --git a/kernel/tests/lib/tst_pid.c b/kernel/tests/lib/tst_pid.c deleted file mode 100644 index 9568cc9..0000000 --- a/kernel/tests/lib/tst_pid.c +++ /dev/null @@ -1,64 +0,0 @@ -/* - * - * Copyright (c) International Business Machines Corp., 2009 - * Copyright (c) 2014 Oracle and/or its affiliates. All Rights Reserved. - * - * 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 - */ - -#include <fcntl.h> -#include <limits.h> -#include <sys/types.h> -#include "test.h" -#include "tst_pid.h" -#include "old_safe_file_ops.h" - -#define PID_MAX_PATH "/proc/sys/kernel/pid_max" - -pid_t tst_get_unused_pid_(void (*cleanup_fn) (void)) -{ - pid_t pid; - - SAFE_FILE_SCANF(cleanup_fn, PID_MAX_PATH, "%d", &pid); - - return pid; -} - -int tst_get_free_pids_(void (*cleanup_fn) (void)) -{ - FILE *f; - int rc, used_pids, max_pids; - - f = popen("ps -eT | wc -l", "r"); - if (!f) { - tst_resm(TBROK, "Could not run 'ps' to calculate used " "pids"); - return -1; - } - rc = fscanf(f, "%i", &used_pids); - pclose(f); - - if (rc != 1 || used_pids < 0) { - tst_resm(TBROK, "Could not read output of 'ps' to " - "calculate used pids"); - return -1; - } - - SAFE_FILE_SCANF(cleanup_fn, PID_MAX_PATH, "%d", &max_pids); - - /* max_pids contains the maximum PID + 1, - * used_pids contains used PIDs + 1, - * so this additional '1' is eliminated by the substraction */ - return max_pids - used_pids; -} diff --git a/kernel/tests/lib/tst_process_state.c b/kernel/tests/lib/tst_process_state.c deleted file mode 100644 index 11790c9..0000000 --- a/kernel/tests/lib/tst_process_state.c +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (C) 2012-2014 Cyril Hrubis chrubis@suse.cz - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it would be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * Further, this software is distributed without any warranty that it is - * free of the rightful claim of any third person regarding infringement - * or the like. Any license provided herein, whether implied or - * otherwise, applies only to this software file. Patent licenses, if - * any, provided herein do not apply to combinations of this program with - * other software, or any other product whatsoever. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include <stdio.h> -#include <string.h> -#include <errno.h> - -#include "test.h" -#include "tst_process_state.h" - -int tst_process_state_wait(const char *file, const int lineno, - void (*cleanup_fn)(void), pid_t pid, - const char state, unsigned int msec_timeout) -{ - char proc_path[128], cur_state; - unsigned int msecs = 0; - - snprintf(proc_path, sizeof(proc_path), "/proc/%i/stat", pid); - - for (;;) { - safe_file_scanf(file, lineno, cleanup_fn, proc_path, - "%*i %*s %c", &cur_state); - - if (state == cur_state) - break; - - usleep(1000); - msecs += 1; - - if (msec_timeout && msecs >= msec_timeout) { - errno = ETIMEDOUT; - return -1; - } - } - - return 0; -} - -int tst_process_state_wait2(pid_t pid, const char state) -{ - char proc_path[128], cur_state; - - snprintf(proc_path, sizeof(proc_path), "/proc/%i/stat", pid); - - for (;;) { - FILE *f = fopen(proc_path, "r"); - if (!f) { - fprintf(stderr, "Failed to open '%s': %s\n", - proc_path, strerror(errno)); - return 1; - } - - if (fscanf(f, "%*i %*s %c", &cur_state) != 1) { - fclose(f); - fprintf(stderr, "Failed to read '%s': %s\n", - proc_path, strerror(errno)); - return 1; - } - fclose(f); - - if (state == cur_state) - return 0; - - usleep(10000); - } -} diff --git a/kernel/tests/lib/tst_res.c b/kernel/tests/lib/tst_res.c deleted file mode 100644 index c35f41b..0000000 --- a/kernel/tests/lib/tst_res.c +++ /dev/null @@ -1,606 +0,0 @@ -/* - * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. - * AUTHOR : Kent Rogers (from Dave Fenner's original) - * CO-PILOT : Rich Logan - * DATE STARTED : 05/01/90 (rewritten 1/96) - * Copyright (c) 2009-2016 Cyril Hrubis <chrubis@suse.cz> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it would be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * Further, this software is distributed without any warranty that it is - * free of the rightful claim of any third person regarding infringement - * or the like. Any license provided herein, whether implied or - * otherwise, applies only to this software file. Patent licenses, if - * any, provided herein do not apply to combinations of this program with - * other software, or any other product whatsoever. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, - * Mountain View, CA 94043, or: - * - * http://www.sgi.com - * - * For further information regarding this notice, see: - * - * http://oss.sgi.com/projects/GenInfo/NoticeExplan/ - */ - -#define _GNU_SOURCE - -#include <pthread.h> -#include <assert.h> -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <stdarg.h> -#include <string.h> -#include <unistd.h> -#include <sys/types.h> -#include <sys/wait.h> - -#include "test.h" -#include "safe_macros.h" -#include "usctest.h" -#include "ltp_priv.h" -#include "tst_ansi_color.h" - -long TEST_RETURN; -int TEST_ERRNO; -void *TST_RET_PTR; - -#define VERBOSE 1 -#define NOPASS 3 -#define DISCARD 4 - -#define MAXMESG 80 /* max length of internal messages */ -#define USERMESG 2048 /* max length of user message */ -#define TRUE 1 -#define FALSE 0 - -/* - * EXPAND_VAR_ARGS - Expand the variable portion (arg_fmt) of a result - * message into the specified string. - * - * NOTE (garrcoop): arg_fmt _must_ be the last element in each function - * argument list that employs this. - */ -#define EXPAND_VAR_ARGS(buf, arg_fmt, buf_len) do {\ - va_list ap; \ - assert(arg_fmt != NULL); \ - va_start(ap, arg_fmt); \ - vsnprintf(buf, buf_len, arg_fmt, ap); \ - va_end(ap); \ - assert(strlen(buf) > 0); \ -} while (0) - -#ifndef PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP -# ifdef __ANDROID__ -# define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP \ - PTHREAD_RECURSIVE_MUTEX_INITIALIZER -# else -/* MUSL: http://www.openwall.com/lists/musl/2017/02/20/5 */ -# define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP { {PTHREAD_MUTEX_RECURSIVE} } -# endif -#endif - -static pthread_mutex_t tmutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; - -static void check_env(void); -static void tst_condense(int tnum, int ttype, const char *tmesg); -static void tst_print(const char *tcid, int tnum, int ttype, const char *tmesg); - -static int T_exitval = 0; /* exit value used by tst_exit() */ -static int passed_cnt; -static int T_mode = VERBOSE; /* flag indicating print mode: VERBOSE, */ - /* NOPASS, DISCARD */ - -static char Warn_mesg[MAXMESG]; /* holds warning messages */ - -/* - * These are used for condensing output when NOT in verbose mode. - */ -static int Buffered = FALSE; /* TRUE if condensed output is currently */ - /* buffered (i.e. not yet printed) */ -static char *Last_tcid; /* previous test case id */ -static int Last_num; /* previous test case number */ -static int Last_type; /* previous test result type */ -static char *Last_mesg; /* previous test result message */ - -int tst_count = 0; - -/* - * These globals must be defined in the test. - */ -extern char *TCID; /* Test case identifier from the test source */ -extern int TST_TOTAL; /* Total number of test cases from the test */ - - -struct pair { - const char *name; - int val; -}; - -#define PAIR(def) [def] = {.name = #def, .val = def}, -#define STRPAIR(key, value) [key] = {.name = value, .val = key}, - -#define PAIR_LOOKUP(pair_arr, idx) do { \ - if (idx < 0 || (size_t)idx >= ARRAY_SIZE(pair_arr) || \ - pair_arr[idx].name == NULL) \ - return "???"; \ - return pair_arr[idx].name; \ -} while (0) - -const char *strttype(int ttype) -{ - static const struct pair ttype_pairs[] = { - PAIR(TPASS) - PAIR(TFAIL) - PAIR(TBROK) - PAIR(TCONF) - PAIR(TWARN) - PAIR(TINFO) - }; - - PAIR_LOOKUP(ttype_pairs, TTYPE_RESULT(ttype)); -} - -#include "errnos.h" -#include "signame.h" - -static void tst_res__(const char *file, const int lineno, int ttype, - const char *arg_fmt, ...) -{ - pthread_mutex_lock(&tmutex); - - char tmesg[USERMESG]; - int len = 0; - int ttype_result = TTYPE_RESULT(ttype); - - if (file && (ttype_result != TPASS && ttype_result != TINFO)) - len = sprintf(tmesg, "%s:%d: ", file, lineno); - EXPAND_VAR_ARGS(tmesg + len, arg_fmt, USERMESG - len); - - /* - * Save the test result type by ORing ttype into the current exit - * value (used by tst_exit()). - */ - T_exitval |= ttype_result; - - if (ttype_result == TPASS) - passed_cnt++; - - check_env(); - - /* - * Set the test case number and print the results, depending on the - * display type. - */ - if (ttype_result == TWARN || ttype_result == TINFO) { - tst_print(TCID, 0, ttype, tmesg); - } else { - if (tst_count < 0) - tst_print(TCID, 0, TWARN, - "tst_res(): tst_count < 0 is not valid"); - - /* - * Process each display type. - */ - switch (T_mode) { - case DISCARD: - break; - case NOPASS: /* filtered by tst_print() */ - tst_condense(tst_count + 1, ttype, tmesg); - break; - default: /* VERBOSE */ - tst_print(TCID, tst_count + 1, ttype, tmesg); - break; - } - - tst_count++; - } - - pthread_mutex_unlock(&tmutex); -} - -static void tst_condense(int tnum, int ttype, const char *tmesg) -{ - int ttype_result = TTYPE_RESULT(ttype); - - /* - * If this result is the same as the previous result, return. - */ - if (Buffered == TRUE) { - if (strcmp(Last_tcid, TCID) == 0 && Last_type == ttype_result && - strcmp(Last_mesg, tmesg) == 0) - return; - - /* - * This result is different from the previous result. First, - * print the previous result. - */ - tst_print(Last_tcid, Last_num, Last_type, Last_mesg); - free(Last_tcid); - free(Last_mesg); - } - - /* - * If a file was specified, print the current result since we have no - * way of retaining the file contents for comparing with future - * results. Otherwise, buffer the current result info for next time. - */ - Last_tcid = malloc(strlen(TCID) + 1); - strcpy(Last_tcid, TCID); - Last_num = tnum; - Last_type = ttype_result; - Last_mesg = malloc(strlen(tmesg) + 1); - strcpy(Last_mesg, tmesg); - Buffered = TRUE; -} - -void tst_old_flush(void) -{ - NO_NEWLIB_ASSERT("Unknown", 0); - - pthread_mutex_lock(&tmutex); - - /* - * Print out last line if in NOPASS mode. - */ - if (Buffered == TRUE && T_mode == NOPASS) { - tst_print(Last_tcid, Last_num, Last_type, Last_mesg); - Buffered = FALSE; - } - - fflush(stdout); - - pthread_mutex_unlock(&tmutex); -} - -static void tst_print(const char *tcid, int tnum, int ttype, const char *tmesg) -{ - int err = errno; - const char *type; - int ttype_result = TTYPE_RESULT(ttype); - char message[USERMESG]; - size_t size = 0; - - /* - * Save the test result type by ORing ttype into the current exit value - * (used by tst_exit()). This is already done in tst_res(), but is - * also done here to catch internal warnings. For internal warnings, - * tst_print() is called directly with a case of TWARN. - */ - T_exitval |= ttype_result; - - /* - * If output mode is DISCARD, or if the output mode is NOPASS and this - * result is not one of FAIL, BROK, or WARN, just return. This check - * is necessary even though we check for DISCARD mode inside of - * tst_res(), since occasionally we get to this point without going - * through tst_res() (e.g. internal TWARN messages). - */ - if (T_mode == DISCARD || (T_mode == NOPASS && ttype_result != TFAIL && - ttype_result != TBROK - && ttype_result != TWARN)) - return; - - /* - * Build the result line and print it. - */ - type = strttype(ttype); - - if (T_mode == VERBOSE) { - size += snprintf(message + size, sizeof(message) - size, - "%-8s %4d ", tcid, tnum); - } else { - size += snprintf(message + size, sizeof(message) - size, - "%-8s %4d ", tcid, tnum); - } - - if (size >= sizeof(message)) { - printf("%s: %i: line too long\n", __func__, __LINE__); - abort(); - } - - if (tst_color_enabled(STDOUT_FILENO)) - size += snprintf(message + size, sizeof(message) - size, - "%s%s%s : %s", tst_ttype2color(ttype), type, ANSI_COLOR_RESET, tmesg); - else - size += snprintf(message + size, sizeof(message) - size, - "%s : %s", type, tmesg); - - if (size >= sizeof(message)) { - printf("%s: %i: line too long\n", __func__, __LINE__); - abort(); - } - - if (ttype & TERRNO) { - size += snprintf(message + size, sizeof(message) - size, - ": errno=%s(%i): %s", tst_strerrno(err), - err, strerror(err)); - } - - if (size >= sizeof(message)) { - printf("%s: %i: line too long\n", __func__, __LINE__); - abort(); - } - - if (ttype & TTERRNO) { - size += snprintf(message + size, sizeof(message) - size, - ": TEST_ERRNO=%s(%i): %s", - tst_strerrno(TEST_ERRNO), (int)TEST_ERRNO, - strerror(TEST_ERRNO)); - } - - if (size >= sizeof(message)) { - printf("%s: %i: line too long\n", __func__, __LINE__); - abort(); - } - - if (ttype & TRERRNO) { - err = TEST_RETURN < 0 ? -(int)TEST_RETURN : (int)TEST_RETURN; - size += snprintf(message + size, sizeof(message) - size, - ": TEST_RETURN=%s(%i): %s", - tst_strerrno(err), err, strerror(err)); - } - - if (size + 1 >= sizeof(message)) { - printf("%s: %i: line too long\n", __func__, __LINE__); - abort(); - } - - message[size] = '\n'; - message[size + 1] = '\0'; - - fputs(message, stdout); -} - -static void check_env(void) -{ - static int first_time = 1; - char *value; - - if (!first_time) - return; - - first_time = 0; - - /* BTOUTPUT not defined, use default */ - if ((value = getenv(TOUTPUT)) == NULL) { - T_mode = VERBOSE; - return; - } - - if (strcmp(value, TOUT_NOPASS_S) == 0) { - T_mode = NOPASS; - return; - } - - if (strcmp(value, TOUT_DISCARD_S) == 0) { - T_mode = DISCARD; - return; - } - - T_mode = VERBOSE; - return; -} - -void tst_exit(void) -{ - NO_NEWLIB_ASSERT("Unknown", 0); - - pthread_mutex_lock(&tmutex); - - tst_old_flush(); - - T_exitval &= ~TINFO; - - if (T_exitval == TCONF && passed_cnt) - T_exitval &= ~TCONF; - - exit(T_exitval); -} - -pid_t tst_fork(void) -{ - pid_t child; - - NO_NEWLIB_ASSERT("Unknown", 0); - - tst_old_flush(); - - child = fork(); - if (child == 0) - T_exitval = 0; - - return child; -} - -void tst_record_childstatus(void (*cleanup)(void), pid_t child) -{ - int status, ttype_result; - - NO_NEWLIB_ASSERT("Unknown", 0); - - SAFE_WAITPID(cleanup, child, &status, 0); - - if (WIFEXITED(status)) { - ttype_result = WEXITSTATUS(status); - ttype_result = TTYPE_RESULT(ttype_result); - T_exitval |= ttype_result; - - if (ttype_result == TPASS) - tst_resm(TINFO, "Child process returned TPASS"); - - if (ttype_result & TFAIL) - tst_resm(TINFO, "Child process returned TFAIL"); - - if (ttype_result & TBROK) - tst_resm(TINFO, "Child process returned TBROK"); - - if (ttype_result & TCONF) - tst_resm(TINFO, "Child process returned TCONF"); - - } else { - tst_brkm(TBROK, cleanup, "child process(%d) killed by " - "unexpected signal %s(%d)", child, - tst_strsig(WTERMSIG(status)), WTERMSIG(status)); - } -} - -pid_t tst_vfork(void) -{ - NO_NEWLIB_ASSERT("Unknown", 0); - - tst_old_flush(); - return vfork(); -} - -/* - * Make tst_brk reentrant so that one can call the SAFE_* macros from within - * user-defined cleanup functions. - */ -static int tst_brk_entered = 0; - -static void tst_brk__(const char *file, const int lineno, int ttype, - void (*func)(void), const char *arg_fmt, ...) -{ - pthread_mutex_lock(&tmutex); - - char tmesg[USERMESG]; - int ttype_result = TTYPE_RESULT(ttype); - - EXPAND_VAR_ARGS(tmesg, arg_fmt, USERMESG); - - /* - * Only FAIL, BROK, CONF, and RETR are supported by tst_brk(). - */ - if (ttype_result != TFAIL && ttype_result != TBROK && - ttype_result != TCONF) { - sprintf(Warn_mesg, "%s: Invalid Type: %d. Using TBROK", - __func__, ttype_result); - tst_print(TCID, 0, TWARN, Warn_mesg); - /* Keep TERRNO, TTERRNO, etc. */ - ttype = (ttype & ~ttype_result) | TBROK; - } - - tst_res__(file, lineno, ttype, "%s", tmesg); - if (tst_brk_entered == 0) { - if (ttype_result == TCONF) { - tst_res__(file, lineno, ttype, - "Remaining cases not appropriate for " - "configuration"); - } else if (ttype_result == TBROK) { - tst_res__(file, lineno, TBROK, - "Remaining cases broken"); - } - } - - /* - * If no cleanup function was specified, just return to the caller. - * Otherwise call the specified function. - */ - if (func != NULL) { - tst_brk_entered++; - (*func) (); - tst_brk_entered--; - } - if (tst_brk_entered == 0) - tst_exit(); - - pthread_mutex_unlock(&tmutex); -} - -void tst_resm_(const char *file, const int lineno, int ttype, - const char *arg_fmt, ...) -{ - char tmesg[USERMESG]; - - EXPAND_VAR_ARGS(tmesg, arg_fmt, USERMESG); - - if (tst_test) - tst_res_(file, lineno, ttype, "%s", tmesg); - else - tst_res__(file, lineno, ttype, "%s", tmesg); -} - -typedef void (*tst_res_func_t)(const char *file, const int lineno, - int ttype, const char *fmt, ...); - -void tst_resm_hexd_(const char *file, const int lineno, int ttype, - const void *buf, size_t size, const char *arg_fmt, ...) -{ - char tmesg[USERMESG]; - static const size_t symb_num = 2; /* xx */ - static const size_t size_max = 16; - size_t offset; - size_t i; - char *pmesg = tmesg; - tst_res_func_t res_func; - - if (tst_test) - res_func = tst_res_; - else - res_func = tst_res__; - - EXPAND_VAR_ARGS(tmesg, arg_fmt, USERMESG); - offset = strlen(tmesg); - - if (size > size_max || size == 0 || - (offset + size * (symb_num + 1)) >= USERMESG) - res_func(file, lineno, ttype, "%s", tmesg); - else - pmesg += offset; - - for (i = 0; i < size; ++i) { - /* add space before byte except first one */ - if (pmesg != tmesg) - *(pmesg++) = ' '; - - sprintf(pmesg, "%02x", ((unsigned char *)buf)[i]); - pmesg += symb_num; - if ((i + 1) % size_max == 0 || i + 1 == size) { - res_func(file, lineno, ttype, "%s", tmesg); - pmesg = tmesg; - } - } -} - -void tst_brkm_(const char *file, const int lineno, int ttype, - void (*func)(void), const char *arg_fmt, ...) -{ - char tmesg[USERMESG]; - - EXPAND_VAR_ARGS(tmesg, arg_fmt, USERMESG); - - if (tst_test) { - if (func) { - tst_brk_(file, lineno, TBROK, - "Non-NULL cleanup in newlib!"); - } - - tst_brk_(file, lineno, ttype, "%s", tmesg); - } else { - tst_brk__(file, lineno, ttype, func, "%s", tmesg); - } - - /* Shouldn't be reached, but fixes build time warnings about noreturn. */ - abort(); -} - -void tst_require_root(void) -{ - NO_NEWLIB_ASSERT("Unknown", 0); - - if (geteuid() != 0) - tst_brkm(TCONF, NULL, "Test needs to be run as root"); -} diff --git a/kernel/tests/lib/tst_resource.c b/kernel/tests/lib/tst_resource.c deleted file mode 100644 index 0b9b381..0000000 --- a/kernel/tests/lib/tst_resource.c +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright (C) 2012 Cyril Hrubis chrubis@suse.cz - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it would be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * Further, this software is distributed without any warranty that it is - * free of the rightful claim of any third person regarding infringement - * or the like. Any license provided herein, whether implied or - * otherwise, applies only to this software file. Patent licenses, if - * any, provided herein do not apply to combinations of this program with - * other software, or any other product whatsoever. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include <pthread.h> -#include "test.h" -#include "old_resource.h" -#include "ltp_priv.h" - -#ifndef PATH_MAX -#ifdef MAXPATHLEN -#define PATH_MAX MAXPATHLEN -#else -#define PATH_MAX 1024 -#endif -#endif - -static pthread_mutex_t tmutex = PTHREAD_MUTEX_INITIALIZER; -static char dataroot[PATH_MAX]; -extern char *TCID; - -static void tst_dataroot_init(void) -{ - const char *ltproot = getenv("LTPROOT"); - char curdir[PATH_MAX]; - const char *startdir; - int ret; - - /* 1. if LTPROOT is set, use $LTPROOT/testcases/data/$TCID - * 2. else if startwd is set by tst_tmpdir(), use $STARWD/datafiles - * 3. else use $CWD/datafiles */ - if (ltproot) { - ret = snprintf(dataroot, PATH_MAX, "%s/testcases/data/%s", - ltproot, TCID); - } else { - startdir = tst_get_startwd(); - if (startdir[0] == 0) { - if (getcwd(curdir, PATH_MAX) == NULL) { - tst_brkm(TBROK | TERRNO, NULL, - "tst_dataroot getcwd"); - return; - } - startdir = curdir; - } - ret = snprintf(dataroot, PATH_MAX, "%s/datafiles", startdir); - } - - if (ret < 0 || ret >= PATH_MAX) - tst_brkm(TBROK, NULL, "tst_dataroot snprintf: %d", ret); -} - -const char *tst_dataroot(void) -{ - if (dataroot[0] == 0) { - pthread_mutex_lock(&tmutex); - if (dataroot[0] == 0) - tst_dataroot_init(); - pthread_mutex_unlock(&tmutex); - } - return dataroot; -} - -static int file_copy(const char *file, const int lineno, - void (*cleanup_fn)(void), const char *path, - const char *filename, const char *dest) -{ - size_t len = strlen(path) + strlen(filename) + 2; - char buf[len]; - - snprintf(buf, sizeof(buf), "%s/%s", path, filename); - - /* check if file exists */ - if (access(buf, R_OK)) - return 0; - - safe_cp(file, lineno, cleanup_fn, buf, dest); - - return 1; -} - -void tst_resource_copy(const char *file, const int lineno, - void (*cleanup_fn)(void), - const char *filename, const char *dest) -{ - if (!tst_tmpdir_created()) { - tst_brkm(TBROK, cleanup_fn, - "Temporary directory doesn't exist at %s:%d", - file, lineno); - return; - } - - if (dest == NULL) - dest = "."; - - const char *ltproot = getenv("LTPROOT"); - const char *dataroot = tst_dataroot(); - - /* look for data files in $LTP_DATAROOT, $LTPROOT/testcases/bin - * and $CWD */ - if (file_copy(file, lineno, cleanup_fn, dataroot, filename, dest)) - return; - - if (ltproot != NULL) { - char buf[strlen(ltproot) + 64]; - - snprintf(buf, sizeof(buf), "%s/testcases/bin", ltproot); - - if (file_copy(file, lineno, cleanup_fn, buf, filename, dest)) - return; - } - - /* try directory test started in as last resort */ - const char *startwd = tst_get_startwd(); - if (file_copy(file, lineno, cleanup_fn, startwd, filename, dest)) - return; - - tst_brkm(TBROK, cleanup_fn, "Failed to copy resource '%s' at %s:%d", - filename, file, lineno); -} diff --git a/kernel/tests/lib/tst_safe_macros.c b/kernel/tests/lib/tst_safe_macros.c deleted file mode 100644 index 25c37df..0000000 --- a/kernel/tests/lib/tst_safe_macros.c +++ /dev/null @@ -1,333 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (c) 2017 Cyril Hrubis <chrubis@suse.cz> - */ - -#define _GNU_SOURCE -#include <unistd.h> -#include <errno.h> -#include <sched.h> -#include <sys/ptrace.h> -#include "config.h" -#ifdef HAVE_SYS_FANOTIFY_H -# include <sys/fanotify.h> -#endif -#define TST_NO_DEFAULT_MAIN -#include "tst_test.h" -#include "lapi/setns.h" -#include "tst_safe_macros.h" -#include "lapi/personality.h" - -int safe_setpgid(const char *file, const int lineno, pid_t pid, pid_t pgid) -{ - int rval; - - rval = setpgid(pid, pgid); - if (rval) { - tst_brk(TBROK | TERRNO, - "%s:%d: setpgid(%i, %i) failed", - file, lineno, pid, pgid); - } - - return rval; -} - -pid_t safe_getpgid(const char *file, const int lineno, pid_t pid) -{ - pid_t pgid; - - pgid = getpgid(pid); - if (pgid == -1) { - tst_brk(TBROK | TERRNO, - "%s:%d: getpgid(%i) failed", file, lineno, pid); - } - - return pgid; -} - -int safe_fanotify_init(const char *file, const int lineno, - unsigned int flags, unsigned int event_f_flags) -{ - int rval; - -#ifdef HAVE_SYS_FANOTIFY_H - rval = fanotify_init(flags, event_f_flags); - - if (rval == -1) { - if (errno == ENOSYS) { - tst_brk(TCONF, - "fanotify is not configured in this kernel."); - } - tst_brk(TBROK | TERRNO, - "%s:%d: fanotify_init() failed", file, lineno); - } -#else - tst_brk(TCONF, "Header <sys/fanotify.h> is not present"); -#endif /* HAVE_SYS_FANOTIFY_H */ - - return rval; -} - -int safe_personality(const char *filename, unsigned int lineno, - unsigned long persona) -{ - int prev_persona = personality(persona); - - if (prev_persona < 0) { - tst_brk_(filename, lineno, TBROK | TERRNO, - "persona(%ld) failed", persona); - } - - return prev_persona; -} - -int safe_setregid(const char *file, const int lineno, - gid_t rgid, gid_t egid) -{ - int rval; - - rval = setregid(rgid, egid); - if (rval == -1) { - tst_brk_(file, lineno, TBROK | TERRNO, - "setregid(%li, %li) failed", - (long)rgid, (long)egid); - } - - return rval; -} - - -int safe_setreuid(const char *file, const int lineno, - uid_t ruid, uid_t euid) -{ - int rval; - - rval = setreuid(ruid, euid); - if (rval == -1) { - tst_brk_(file, lineno, TBROK | TERRNO, - "setreuid(%li, %li) failed", - (long)ruid, (long)euid); - } - - return rval; -} - - -int safe_sigaction(const char *file, const int lineno, - int signum, const struct sigaction *act, - struct sigaction *oldact) -{ - int rval; - - rval = sigaction(signum, act, oldact); - - if (rval == -1) { - tst_brk_(file, lineno, TBROK | TERRNO, - "sigaction(%s (%d), %p, %p) failed", - tst_strsig(signum), signum, act, oldact); - } - - return rval; -} - -void safe_sigaddset(const char *file, const int lineno, - sigset_t *sigs, int signo) -{ - int rval; - - rval = sigaddset(sigs, signo); - if (rval == -1) { - tst_brk_(file, lineno, TBROK | TERRNO, - "sigaddset() %s (%i) failed", - tst_strsig(signo), signo); - } -} - -void safe_sigdelset(const char *file, const int lineno, - sigset_t *sigs, int signo) -{ - int rval; - - rval = sigdelset(sigs, signo); - if (rval == -1) { - tst_brk_(file, lineno, TBROK | TERRNO, - "sigdelset() %s (%i) failed", - tst_strsig(signo), signo); - } -} - -void safe_sigemptyset(const char *file, const int lineno, - sigset_t *sigs) -{ - int rval; - - rval = sigemptyset(sigs); - if (rval == -1) - tst_brk_(file, lineno, TBROK | TERRNO, "sigemptyset() failed"); -} - -void safe_sigfillset(const char *file, const int lineno, - sigset_t *sigs) -{ - int rval; - - rval = sigfillset(sigs); - if (rval == -1) - tst_brk_(file, lineno, TBROK | TERRNO, "sigfillset() failed"); -} - -static const char *strhow(int how) -{ - switch (how) { - case SIG_BLOCK: - return "SIG_BLOCK"; - case SIG_UNBLOCK: - return "SIG_UNBLOCK"; - case SIG_SETMASK: - return "SIG_SETMASK"; - default: - return "???"; - } -} - -void safe_sigprocmask(const char *file, const int lineno, - int how, sigset_t *set, sigset_t *oldset) -{ - int rval; - - rval = sigprocmask(how, set, oldset); - if (rval == -1) { - tst_brk_(file, lineno, TBROK | TERRNO, - "sigprocmask(%s, %p, %p)", strhow(how), set, oldset); - } -} - -void safe_sigwait(const char *file, const int lineno, - sigset_t *set, int *sig) -{ - int rval; - - rval = sigwait(set, sig); - if (rval != 0) { - errno = rval; - tst_brk_(file, lineno, TBROK, "sigwait(%p, %p)", set, sig); - } -} - -struct group *safe_getgrnam(const char *file, const int lineno, - const char *name) -{ - struct group *rval; - - errno = 0; - rval = getgrnam(name); - if (rval == NULL) { - tst_brk_(file, lineno, TBROK | TERRNO, - "getgrnam(%s) failed", name); - } - - return rval; -} - -struct group *safe_getgrnam_fallback(const char *file, const int lineno, - const char *name, const char *fallback) -{ - struct group *rval; - - errno = 0; - rval = getgrnam(name); - if (rval == NULL) { - tst_res_(file, lineno, TINFO, - "getgrnam(%s) failed - try fallback %s", - name, fallback); - rval = safe_getgrnam(file, lineno, fallback); - } - - return rval; -} - -struct group *safe_getgrgid(const char *file, const int lineno, gid_t gid) -{ - struct group *rval; - - errno = 0; - rval = getgrgid(gid); - if (rval == NULL) { - tst_brk_(file, lineno, TBROK | TERRNO, - "getgrgid(%li) failed", (long)gid); - } - - return rval; -} - -int safe_chroot(const char *file, const int lineno, const char *path) -{ - int rval; - - rval = chroot(path); - if (rval == -1) { - tst_brk_(file, lineno, TBROK | TERRNO, - "chroot(%s) failed", path); - } - - return rval; -} - -void safe_unshare(const char *file, const int lineno, int flags) -{ - int res; - - res = unshare(flags); - if (res == -1) { - if (errno == EINVAL) { - tst_brk_(file, lineno, TCONF | TERRNO, - "unshare(%d) unsupported", flags); - } else { - tst_brk_(file, lineno, TBROK | TERRNO, - "unshare(%d) failed", flags); - } - } -} - -void safe_setns(const char *file, const int lineno, int fd, int nstype) -{ - int ret; - - ret = setns(fd, nstype); - if (ret == -1) { - tst_brk_(file, lineno, TBROK | TERRNO, "setns(%i, %i) failed", - fd, nstype); - } -} - -long tst_safe_ptrace(const char *file, const int lineno, int req, pid_t pid, - void *addr, void *data) -{ - long ret; - - errno = 0; - ret = ptrace(req, pid, addr, data); - - if (ret == -1) { - tst_brk_(file, lineno, TBROK | TERRNO, "ptrace() failed"); - } else if (ret) { - tst_brk_(file, lineno, TBROK | TERRNO, - "Invalid ptrace() return value %ld", ret); - } - - return ret; -} - -int safe_pipe2(const char *file, const int lineno, int fildes[2], int flags) -{ - int ret; - - ret = pipe2(fildes, flags); - if (ret == -1) { - tst_brk_(file, lineno, TBROK | TERRNO, - "pipe2({%d,%d}) failed with flag(%d)", - fildes[0], fildes[1], flags); - } - - return ret; -} diff --git a/kernel/tests/lib/tst_safe_sysv_ipc.c b/kernel/tests/lib/tst_safe_sysv_ipc.c deleted file mode 100644 index 30b5f6e..0000000 --- a/kernel/tests/lib/tst_safe_sysv_ipc.c +++ /dev/null @@ -1,145 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (c) 2017 Xiao yang <yangx.jy@cn.fujitsu.com> - */ - -#include <sys/types.h> -#include <sys/ipc.h> -#include <sys/msg.h> -#include <sys/shm.h> -#define TST_NO_DEFAULT_MAIN -#include "tst_test.h" -#include "tst_safe_sysv_ipc.h" - -/* - * The IPC_STAT, IPC_SET and IPC_RMID can return either 0 or -1. - * - * Linux specific cmds either returns -1 on failure or positive integer - * either index into an kernel array or shared primitive indentifier. - */ -static int ret_check(int cmd, int ret) -{ - switch (cmd) { - case IPC_STAT: - case IPC_SET: - case IPC_RMID: - return ret != 0; - default: - return ret == -1; - } -} - -int safe_msgget(const char *file, const int lineno, key_t key, int msgflg) -{ - int rval; - - rval = msgget(key, msgflg); - if (rval == -1) { - tst_brk(TBROK | TERRNO, "%s:%d: msgget(%i, %x) failed", - file, lineno, (int)key, msgflg); - } - - return rval; -} - -int safe_msgsnd(const char *file, const int lineno, int msqid, const void *msgp, - size_t msgsz, int msgflg) -{ - int rval; - - rval = msgsnd(msqid, msgp, msgsz, msgflg); - if (rval == -1) { - tst_brk(TBROK | TERRNO, - "%s:%d: msgsnd(%i, %p, %zu, %x) failed", - file, lineno, msqid, msgp, msgsz, msgflg); - } - - return rval; -} - -ssize_t safe_msgrcv(const char *file, const int lineno, int msqid, void *msgp, - size_t msgsz, long msgtyp, int msgflg) -{ - ssize_t rval; - - rval = msgrcv(msqid, msgp, msgsz, msgtyp, msgflg); - if (rval == -1) { - tst_brk(TBROK | TERRNO, - "%s:%d: msgrcv(%i, %p, %zu, %li, %x) failed", - file, lineno, msqid, msgp, msgsz, msgtyp, msgflg); - } - - return rval; -} - -int safe_msgctl(const char *file, const int lineno, int msqid, int cmd, - struct msqid_ds *buf) -{ - int rval; - - rval = msgctl(msqid, cmd, buf); - if (ret_check(cmd, rval)) { - tst_brk(TBROK | TERRNO, - "%s:%d: msgctl(%i, %i, %p) = %i failed", - file, lineno, msqid, cmd, buf, rval); - } - - - return rval; -} - -int safe_shmget(const char *file, const int lineno, key_t key, size_t size, - int shmflg) -{ - int rval; - - rval = shmget(key, size, shmflg); - if (rval == -1) { - tst_brk(TBROK | TERRNO, "%s:%d: shmget(%i, %zu, %x) failed", - file, lineno, (int)key, size, shmflg); - } - - return rval; -} - -void *safe_shmat(const char *file, const int lineno, int shmid, - const void *shmaddr, int shmflg) -{ - void *rval; - - rval = shmat(shmid, shmaddr, shmflg); - if (rval == (void *)-1) { - tst_brk(TBROK | TERRNO, "%s:%d: shmat(%i, %p, %x) failed", - file, lineno, shmid, shmaddr, shmflg); - } - - return rval; -} - -int safe_shmdt(const char *file, const int lineno, const void *shmaddr) -{ - int rval; - - rval = shmdt(shmaddr); - if (rval == -1) { - tst_brk(TBROK | TERRNO, "%s:%d: shmdt(%p) failed", - file, lineno, shmaddr); - } - - return rval; -} - -int safe_shmctl(const char *file, const int lineno, int shmid, int cmd, - struct shmid_ds *buf) -{ - int rval; - - rval = shmctl(shmid, cmd, buf); - if (ret_check(cmd, rval)) { - tst_brk(TBROK | TERRNO, - "%s:%d: shmctl(%i, %i, %p) = %i failed", - file, lineno, shmid, cmd, buf, rval); - } - - return rval; -} diff --git a/kernel/tests/lib/tst_safe_timerfd.c b/kernel/tests/lib/tst_safe_timerfd.c deleted file mode 100644 index ffe7b2e..0000000 --- a/kernel/tests/lib/tst_safe_timerfd.c +++ /dev/null @@ -1,56 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (c) 2020 Petr Vorel <pvorel@suse.cz> - */ - -#include "tst_safe_timerfd.h" -#include "lapi/timerfd.h" -#include "tst_clocks.h" -#define TST_NO_DEFAULT_MAIN -#include "tst_test.h" - -#define TTYPE (errno == ENOTSUP ? TCONF : TBROK) - -int safe_timerfd_create(const char *file, const int lineno, - int clockid, int flags) -{ - int fd; - - fd = timerfd_create(clockid, flags); - if (fd < 0) { - tst_brk(TTYPE | TERRNO, "%s:%d timerfd_create(%s) failed", - file, lineno, tst_clock_name(clockid)); - } - - return fd; -} - -int safe_timerfd_gettime(const char *file, const int lineno, - int fd, struct itimerspec *curr_value) -{ - int rval; - - rval = timerfd_gettime(fd, curr_value); - if (rval != 0) { - tst_brk(TTYPE | TERRNO, "%s:%d timerfd_gettime() failed", - file, lineno); - } - - return rval; -} - -int safe_timerfd_settime(const char *file, const int lineno, - int fd, int flags, - const struct itimerspec *new_value, - struct itimerspec *old_value) -{ - int rval; - - rval = timerfd_settime(fd, flags, new_value, old_value); - if (rval != 0) { - tst_brk(TTYPE | TERRNO, "%s:%d timerfd_settime() failed", - file, lineno); - } - - return rval; -} diff --git a/kernel/tests/lib/tst_sig.c b/kernel/tests/lib/tst_sig.c deleted file mode 100644 index 6d77aea..0000000 --- a/kernel/tests/lib/tst_sig.c +++ /dev/null @@ -1,255 +0,0 @@ -/* - * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it would be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * Further, this software is distributed without any warranty that it is - * free of the rightful claim of any third person regarding infringement - * or the like. Any license provided herein, whether implied or - * otherwise, applies only to this software file. Patent licenses, if - * any, provided herein do not apply to combinations of this program with - * other software, or any other product whatsoever. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, - * Mountain View, CA 94043, or: - * - * http://www.sgi.com - * - * For further information regarding this notice, see: - * - * http://oss.sgi.com/projects/GenInfo/NoticeExplan/ - */ - -/* $Id: tst_sig.c,v 1.13 2009/08/28 09:29:01 vapier Exp $ */ - -/***************************************************************************** - OS Testing - Silicon Graphics, Inc. - - FUNCTION IDENTIFIER : tst_sig Set up for unexpected signals. - - AUTHOR : David D. Fenner - - CO-PILOT : Bill Roske - - DATE STARTED : 06/06/90 - - This module may be linked with c-modules requiring unexpected - signal handling. The parameters to tst_sig are as follows: - - fork_flag - set to FORK or NOFORK depending upon whether the - calling program executes a fork() system call. It - is normally the case that the calling program treats - SIGCHLD as an expected signal if fork() is being used. - - handler - a pointer to the unexpected signal handler to - be executed after an unexpected signal has been - detected. If handler is set to DEF_HANDLER, a - default handler is used. This routine should be - declared as function returning an int. - - cleanup - a pointer to a cleanup routine to be executed - by the unexpected signal handler before tst_exit is - called. This parameter is set to NULL if no cleanup - routine is required. An external variable, T_cleanup - is set so that other user-defined handlers have - access to the cleanup routine. This routine should be - declared as returning type void. - -***************************************************************************/ - -#include <errno.h> -#include <string.h> -#include <signal.h> -#include <unistd.h> -#include "test.h" -#include "lapi/signal.h" - -#define MAXMESG 150 /* size of mesg string sent to tst_res */ - -static void (*T_cleanup) (); - -static void def_handler(); /* default signal handler */ -static void (*tst_setup_signal(int, void (*)(int))) (int); - -/**************************************************************************** - * tst_sig() : set-up to catch unexpected signals. fork_flag is set to NOFORK - * if SIGCHLD is to be an "unexpected signal", otherwise it is set to - * FORK. cleanup points to a cleanup routine to be executed before - * tst_exit is called (cleanup is set to NULL if no cleanup is desired). - * handler is a pointer to the signal handling routine (if handler is - * set to NULL, a default handler is used). - ***************************************************************************/ - -void tst_sig(int fork_flag, void (*handler) (), void (*cleanup) ()) -{ - int sig; -#ifdef _SC_SIGRT_MIN - long sigrtmin, sigrtmax; -#endif - - /* - * save T_cleanup and handler function pointers - */ - T_cleanup = cleanup; /* used by default handler */ - - if (handler == DEF_HANDLER) { - /* use default handler */ - handler = def_handler; - } -#ifdef _SC_SIGRT_MIN - sigrtmin = sysconf(_SC_SIGRT_MIN); - sigrtmax = sysconf(_SC_SIGRT_MAX); -#endif - - /* - * now loop through all signals and set the handlers - */ - - for (sig = 1; sig < NSIG; sig++) { - /* - * SIGKILL is never unexpected. - * SIGCHLD is only unexpected when - * no forking is being done. - * SIGINFO is used for file quotas and should be expected - */ - -#ifdef _SC_SIGRT_MIN - if (sig >= sigrtmin && sig <= sigrtmax) - continue; -#endif - - switch (sig) { - case SIGKILL: - case SIGSTOP: - case SIGCONT: -#if !defined(_SC_SIGRT_MIN) && defined(__SIGRTMIN) && defined(__SIGRTMAX) - /* Ignore all real-time signals */ - case __SIGRTMIN: - case __SIGRTMIN + 1: - case __SIGRTMIN + 2: - case __SIGRTMIN + 3: - case __SIGRTMIN + 4: - case __SIGRTMIN + 5: - case __SIGRTMIN + 6: - case __SIGRTMIN + 7: - case __SIGRTMIN + 8: - case __SIGRTMIN + 9: - case __SIGRTMIN + 10: - case __SIGRTMIN + 11: - case __SIGRTMIN + 12: - case __SIGRTMIN + 13: - case __SIGRTMIN + 14: - case __SIGRTMIN + 15: -/* __SIGRTMIN is 37 on HPPA rather than 32 * - * as on i386, etc. */ -#if !defined(__hppa__) - case __SIGRTMAX - 15: - case __SIGRTMAX - 14: - case __SIGRTMAX - 13: - case __SIGRTMAX - 12: - case __SIGRTMAX - 11: -#endif - case __SIGRTMAX - 10: - case __SIGRTMAX - 9: - case __SIGRTMAX - 8: - case __SIGRTMAX - 7: - case __SIGRTMAX - 6: - case __SIGRTMAX - 5: - case __SIGRTMAX - 4: - case __SIGRTMAX - 3: - case __SIGRTMAX - 2: - case __SIGRTMAX - 1: - case __SIGRTMAX: -#endif -#ifdef SIGSWAP - case SIGSWAP: -#endif /* SIGSWAP */ - -#ifdef SIGCKPT - case SIGCKPT: -#endif -#ifdef SIGRESTART - case SIGRESTART: -#endif - /* - * pthread-private signals SIGPTINTR and SIGPTRESCHED. - * Setting a handler for these signals is disallowed when - * the binary is linked against libpthread. - */ -#ifdef SIGPTINTR - case SIGPTINTR: -#endif /* SIGPTINTR */ -#ifdef SIGPTRESCHED - case SIGPTRESCHED: -#endif /* SIGPTRESCHED */ -#ifdef _SIGRESERVE - case _SIGRESERVE: -#endif -#ifdef _SIGDIL - case _SIGDIL: -#endif -#ifdef _SIGCANCEL - case _SIGCANCEL: -#endif -#ifdef _SIGGFAULT - case _SIGGFAULT: -#endif - break; - - case SIGCHLD: - if (fork_flag == FORK) - continue; - - default: - if (tst_setup_signal(sig, handler) == SIG_ERR) - tst_resm(TWARN | TERRNO, - "signal failed for signal %d", sig); - break; - } - } -} - -/**************************************************************************** - * def_handler() : default signal handler that is invoked when - * an unexpected signal is caught. - ***************************************************************************/ - -static void def_handler(int sig) -{ - /* - * Break remaining test cases, do any cleanup, then exit - */ - tst_brkm(TBROK, T_cleanup, - "unexpected signal %s(%d) received (pid = %d).", - tst_strsig(sig), sig, getpid()); -} - -/* - * tst_setup_signal - A function like signal(), but we have - * control over its personality. - */ -static void (*tst_setup_signal(int sig, void (*handler) (int))) (int) { - struct sigaction my_act, old_act; - int ret; - - my_act.sa_handler = handler; - my_act.sa_flags = SA_RESTART; - sigemptyset(&my_act.sa_mask); - - ret = sigaction(sig, &my_act, &old_act); - - if (ret == 0) - return old_act.sa_handler; - else - return SIG_ERR; -} diff --git a/kernel/tests/lib/tst_sig_proc.c b/kernel/tests/lib/tst_sig_proc.c deleted file mode 100644 index 509418a..0000000 --- a/kernel/tests/lib/tst_sig_proc.c +++ /dev/null @@ -1,31 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (c) 2016 Linux Test Project - */ - -#include <stdlib.h> -#include <sys/types.h> - -#include "tst_sig_proc.h" - -#define TST_NO_DEFAULT_MAIN -#include "tst_test.h" - -pid_t create_sig_proc(int sig, int count, unsigned int usec) -{ - pid_t pid, cpid; - - pid = getpid(); - cpid = SAFE_FORK(); - - if (cpid == 0) { - while (count-- > 0) { - usleep(usec); - if (kill(pid, sig) == -1) - break; - } - exit(0); - } - - return cpid; -} diff --git a/kernel/tests/lib/tst_status.c b/kernel/tests/lib/tst_status.c deleted file mode 100644 index f1affea..0000000 --- a/kernel/tests/lib/tst_status.c +++ /dev/null @@ -1,50 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (c) 2017 Cyril Hrubis <chrubis@suse.cz> - */ - -#include <sys/types.h> -#include <sys/wait.h> -#include <stdio.h> -#define TST_NO_DEFAULT_MAIN -#include "tst_test.h" - -static char buf[32]; - -const char *exited(int status) -{ - snprintf(buf, sizeof(buf), "exited with %i", WEXITSTATUS(status)); - - return buf; -} - -const char *signaled(int status) -{ - snprintf(buf, sizeof(buf), "killed by %s", tst_strsig(status)); - - return buf; -} - -const char *invalid(int status) -{ - snprintf(buf, sizeof(buf), "invalid status 0x%x", status); - - return buf; -} - -const char *tst_strstatus(int status) -{ - if (WIFEXITED(status)) - return exited(status); - - if (WIFSIGNALED(status)) - return signaled(status); - - if (WIFSTOPPED(status)) - return "is stopped"; - - if (WIFCONTINUED(status)) - return "is resumed"; - - return invalid(status); -} diff --git a/kernel/tests/lib/tst_supported_fs_types.c b/kernel/tests/lib/tst_supported_fs_types.c deleted file mode 100644 index 00ede54..0000000 --- a/kernel/tests/lib/tst_supported_fs_types.c +++ /dev/null @@ -1,111 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (c) 2017 Cyril Hrubis <chrubis@suse.cz> - */ - -#include <stdio.h> -#include <errno.h> -#include <stdlib.h> -#include <sys/mount.h> -#include <sys/wait.h> - -#define TST_NO_DEFAULT_MAIN -#include "tst_test.h" -#include "tst_fs.h" - -static const char *const fs_type_whitelist[] = { - "ext2", - "ext3", - "ext4", - "xfs", - "btrfs", - "vfat", - "exfat", - "ntfs", - NULL -}; - -static const char *fs_types[ARRAY_SIZE(fs_type_whitelist)]; - -static int has_mkfs(const char *fs_type) -{ - char buf[128]; - int ret; - - sprintf(buf, "mkfs.%s >/dev/null 2>&1", fs_type); - - ret = tst_system(buf); - - if (WEXITSTATUS(ret) == 127) { - tst_res(TINFO, "mkfs.%s does not exist", fs_type); - return 0; - } - - tst_res(TINFO, "mkfs.%s does exist", fs_type); - return 1; -} - -static int has_kernel_support(const char *fs_type, int flags) -{ - static int fuse_supported = -1; - const char *tmpdir = getenv("TMPDIR"); - char buf[128]; - int ret; - - if (!tmpdir) - tmpdir = "/tmp"; - - mount("/dev/zero", tmpdir, fs_type, 0, NULL); - if (errno != ENODEV) { - tst_res(TINFO, "Kernel supports %s", fs_type); - return 1; - } - - /* Is FUSE supported by kernel? */ - if (fuse_supported == -1) { - ret = open("/dev/fuse", O_RDWR); - if (ret < 0) { - fuse_supported = 0; - } else { - fuse_supported = 1; - SAFE_CLOSE(ret); - } - } - - if (!fuse_supported) - return 0; - - /* Is FUSE implementation installed? */ - sprintf(buf, "mount.%s >/dev/null 2>&1", fs_type); - - ret = tst_system(buf); - if (WEXITSTATUS(ret) == 127) { - tst_res(TINFO, "Filesystem %s is not supported", fs_type); - return 0; - } - - if (flags & TST_FS_SKIP_FUSE) { - tst_res(TINFO, "Skipping FUSE as requested by the test"); - return 0; - } - - tst_res(TINFO, "FUSE does support %s", fs_type); - return 1; -} - -int tst_fs_is_supported(const char *fs_type, int flags) -{ - return has_kernel_support(fs_type, flags) && has_mkfs(fs_type); -} - -const char **tst_get_supported_fs_types(int flags) -{ - unsigned int i, j = 0; - - for (i = 0; fs_type_whitelist[i]; i++) { - if (tst_fs_is_supported(fs_type_whitelist[i], flags)) - fs_types[j++] = fs_type_whitelist[i]; - } - - return fs_types; -} diff --git a/kernel/tests/lib/tst_sys_conf.c b/kernel/tests/lib/tst_sys_conf.c deleted file mode 100644 index 4ad9f8b..0000000 --- a/kernel/tests/lib/tst_sys_conf.c +++ /dev/null @@ -1,105 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (c) 2018 Jan Stancek <jstancek@redhat.com> - */ - -#include <limits.h> -#include <stdio.h> -#include <unistd.h> -#include <string.h> - -#define TST_NO_DEFAULT_MAIN -#include "tst_test.h" -#include "tst_sys_conf.h" - -static struct tst_sys_conf *save_restore_data; - -void tst_sys_conf_dump(void) -{ - struct tst_sys_conf *i; - - for (i = save_restore_data; i; i = i->next) - tst_res(TINFO, "%s = %s", i->path, i->value); -} - -int tst_sys_conf_save_str(const char *path, const char *value) -{ - struct tst_sys_conf *n = SAFE_MALLOC(sizeof(*n)); - - strncpy(n->path, path, sizeof(n->path)-1); - strncpy(n->value, value, sizeof(n->value)-1); - - n->path[sizeof(n->path) - 1] = 0; - n->value[sizeof(n->value) - 1] = 0; - - n->next = save_restore_data; - save_restore_data = n; - - return 0; -} - -int tst_sys_conf_save(const char *path) -{ - char line[PATH_MAX]; - FILE *fp; - void *ret; - char flag; - - if (!path) - tst_brk(TBROK, "path is empty"); - - flag = path[0]; - if (flag == '?' || flag == '!') - path++; - - if (access(path, F_OK) != 0) { - switch (flag) { - case '?': - tst_res(TINFO, "Path not found: '%s'", path); - break; - case '!': - tst_brk(TBROK|TERRNO, "Path not found: '%s'", path); - break; - default: - tst_brk(TCONF|TERRNO, "Path not found: '%s'", path); - } - return 1; - } - - fp = fopen(path, "r"); - if (fp == NULL) { - if (flag == '?') - return 1; - - tst_brk(TBROK | TERRNO, "Failed to open FILE '%s' for reading", - path); - return 1; - } - - ret = fgets(line, sizeof(line), fp); - fclose(fp); - - if (ret == NULL) { - if (flag == '?') - return 1; - - tst_brk(TBROK | TERRNO, "Failed to read anything from '%s'", - path); - } - - return tst_sys_conf_save_str(path, line); -} - -void tst_sys_conf_restore(int verbose) -{ - struct tst_sys_conf *i; - - for (i = save_restore_data; i; i = i->next) { - if (verbose) { - tst_res(TINFO, "Restoring conf.: %s -> %s\n", - i->path, i->value); - } - FILE_PRINTF(i->path, "%s", i->value); - } -} - diff --git a/kernel/tests/lib/tst_taint.c b/kernel/tests/lib/tst_taint.c deleted file mode 100644 index 49146aa..0000000 --- a/kernel/tests/lib/tst_taint.c +++ /dev/null @@ -1,107 +0,0 @@ -#define TST_NO_DEFAULT_MAIN - -#include "tst_test.h" -#include "tst_taint.h" -#include "tst_safe_stdio.h" - -#define TAINT_FILE "/proc/sys/kernel/tainted" - -static unsigned int taint_mask = -1; - -static unsigned int tst_taint_read(void) -{ - unsigned int val; - - SAFE_FILE_SCANF(TAINT_FILE, "%u", &val); - - return val; -} - -static int tst_taint_check_kver(unsigned int mask) -{ - int r1; - int r2; - int r3 = 0; - - if (mask & TST_TAINT_X) { - r1 = 4; - r2 = 15; - } else if (mask & TST_TAINT_K) { - r1 = 4; - r2 = 0; - } else if (mask & TST_TAINT_L) { - r1 = 3; - r2 = 17; - } else if (mask & TST_TAINT_E) { - r1 = 3; - r2 = 15; - } else if (mask & TST_TAINT_O) { - r1 = 3; - r2 = 2; - } else if (mask & TST_TAINT_I) { - r1 = 2; - r2 = 6; - r3 = 35; - } else if (mask & TST_TAINT_C) { - r1 = 2; - r2 = 6; - r3 = 28; - } else if (mask & TST_TAINT_W) { - r1 = 2; - r2 = 6; - r3 = 26; - } else if (mask & TST_TAINT_A) { - r1 = 2; - r2 = 6; - r3 = 25; - } else if (mask & TST_TAINT_D) { - r1 = 2; - r2 = 6; - r3 = 23; - } else if (mask & TST_TAINT_U) { - r1 = 2; - r2 = 6; - r3 = 21; - } else { - r1 = 2; - r2 = 6; - r3 = 16; - } - - return tst_kvercmp(r1, r2, r3); -} - -void tst_taint_init(unsigned int mask) -{ - unsigned int taint = -1; - - if (mask == 0) - tst_brk(TBROK, "mask is not allowed to be 0"); - - if (tst_taint_check_kver(mask) < 0) - tst_res(TCONF, "Kernel is too old for requested mask"); - - taint_mask = mask; - taint = tst_taint_read(); - - if (taint & TST_TAINT_W) { - tst_res(TCONF, "Ignoring already set kernel warning taint"); - taint_mask &= ~TST_TAINT_W; - } - - if ((taint & taint_mask) != 0) - tst_brk(TBROK, "Kernel is already tainted: %u", taint); -} - - -unsigned int tst_taint_check(void) -{ - unsigned int taint = -1; - - if (taint_mask == (unsigned int) -1) - tst_brk(TBROK, "need to call tst_taint_init() first"); - - taint = tst_taint_read(); - - return (taint & taint_mask); -} diff --git a/kernel/tests/lib/tst_test.c b/kernel/tests/lib/tst_test.c deleted file mode 100644 index 135cd4e..0000000 --- a/kernel/tests/lib/tst_test.c +++ /dev/null @@ -1,1387 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (c) 2015-2016 Cyril Hrubis <chrubis@suse.cz> - */ - -#include <limits.h> -#include <stdio.h> -#include <stdarg.h> -#include <unistd.h> -#include <string.h> -#include <stdlib.h> -#include <errno.h> -#include <sys/mount.h> -#include <sys/types.h> -#include <sys/wait.h> - -#define TST_NO_DEFAULT_MAIN -#include "tst_test.h" -#include "tst_device.h" -#include "lapi/futex.h" -#include "lapi/syscalls.h" -#include "tst_ansi_color.h" -#include "tst_safe_stdio.h" -#include "tst_timer_test.h" -#include "tst_clocks.h" -#include "tst_timer.h" -#include "tst_wallclock.h" -#include "tst_sys_conf.h" -#include "tst_kconfig.h" - -#include "old_resource.h" -#include "old_device.h" -#include "old_tmpdir.h" - -/* - * Hack to get TCID defined in newlib tests - */ -const char *TCID __attribute__((weak)); - -#define LINUX_GIT_URL "https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=" -#define CVE_DB_URL "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-" - -struct tst_test *tst_test; - -static const char *tid; -static int iterations = 1; -static float duration = -1; -static float timeout_mul = -1; -static pid_t main_pid, lib_pid; -static int mntpoint_mounted; -static int ovl_mounted; -static struct timespec tst_start_time; /* valid only for test pid */ - -struct results { - int passed; - int skipped; - int failed; - int warnings; - unsigned int timeout; -}; - -static struct results *results; - -static int ipc_fd; - -extern void *tst_futexes; -extern unsigned int tst_max_futexes; - -#define IPC_ENV_VAR "LTP_IPC_PATH" - -static char ipc_path[1064]; -const char *tst_ipc_path = ipc_path; - -static char shm_path[1024]; - -int TST_ERR; -long TST_RET; - -static void do_cleanup(void); -static void do_exit(int ret) __attribute__ ((noreturn)); - -static void setup_ipc(void) -{ - size_t size = getpagesize(); - - if (access("/dev/shm", F_OK) == 0) { - snprintf(shm_path, sizeof(shm_path), "/dev/shm/ltp_%s_%d", - tid, getpid()); - } else { - char *tmpdir; - - if (!tst_tmpdir_created()) - tst_tmpdir(); - - tmpdir = tst_get_tmpdir(); - snprintf(shm_path, sizeof(shm_path), "%s/ltp_%s_%d", - tmpdir, tid, getpid()); - free(tmpdir); - } - - ipc_fd = open(shm_path, O_CREAT | O_EXCL | O_RDWR, 0600); - if (ipc_fd < 0) - tst_brk(TBROK | TERRNO, "open(%s)", shm_path); - SAFE_CHMOD(shm_path, 0666); - - SAFE_FTRUNCATE(ipc_fd, size); - - results = SAFE_MMAP(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, ipc_fd, 0); - - /* Checkpoints needs to be accessible from processes started by exec() */ - if (tst_test->needs_checkpoints || tst_test->child_needs_reinit) { - sprintf(ipc_path, IPC_ENV_VAR "=%s", shm_path); - putenv(ipc_path); - } else { - SAFE_UNLINK(shm_path); - } - - SAFE_CLOSE(ipc_fd); - - if (tst_test->needs_checkpoints) { - tst_futexes = (char*)results + sizeof(struct results); - tst_max_futexes = (size - sizeof(struct results))/sizeof(futex_t); - } -} - -static void cleanup_ipc(void) -{ - size_t size = getpagesize(); - - if (ipc_fd > 0 && close(ipc_fd)) - tst_res(TWARN | TERRNO, "close(ipc_fd) failed"); - - if (shm_path[0] && !access(shm_path, F_OK) && unlink(shm_path)) - tst_res(TWARN | TERRNO, "unlink(%s) failed", shm_path); - - if (results) { - msync((void*)results, size, MS_SYNC); - munmap((void*)results, size); - results = NULL; - } -} - -void tst_reinit(void) -{ - const char *path = getenv(IPC_ENV_VAR); - size_t size = getpagesize(); - int fd; - - if (!path) - tst_brk(TBROK, IPC_ENV_VAR" is not defined"); - - if (access(path, F_OK)) - tst_brk(TBROK, "File %s does not exist!", path); - - fd = SAFE_OPEN(path, O_RDWR); - - results = SAFE_MMAP(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); - tst_futexes = (char*)results + sizeof(struct results); - tst_max_futexes = (size - sizeof(struct results))/sizeof(futex_t); - - SAFE_CLOSE(fd); -} - -static void update_results(int ttype) -{ - if (!results) - return; - - switch (ttype) { - case TCONF: - tst_atomic_inc(&results->skipped); - break; - case TPASS: - tst_atomic_inc(&results->passed); - break; - case TWARN: - tst_atomic_inc(&results->warnings); - break; - case TFAIL: - tst_atomic_inc(&results->failed); - break; - } -} - -static void print_result(const char *file, const int lineno, int ttype, - const char *fmt, va_list va) -{ - char buf[1024]; - char *str = buf; - int ret, size = sizeof(buf), ssize, int_errno, buflen; - const char *str_errno = NULL; - const char *res; - - switch (TTYPE_RESULT(ttype)) { - case TPASS: - res = "PASS"; - break; - case TFAIL: - res = "FAIL"; - break; - case TBROK: - res = "BROK"; - break; - case TCONF: - res = "CONF"; - break; - case TWARN: - res = "WARN"; - break; - case TINFO: - res = "INFO"; - break; - default: - tst_brk(TBROK, "Invalid ttype value %i", ttype); - abort(); - } - - if (ttype & TERRNO) { - str_errno = tst_strerrno(errno); - int_errno = errno; - } - - if (ttype & TTERRNO) { - str_errno = tst_strerrno(TST_ERR); - int_errno = TST_ERR; - } - - if (ttype & TRERRNO) { - int_errno = TST_RET < 0 ? -(int)TST_RET : (int)TST_RET; - str_errno = tst_strerrno(int_errno); - } - - ret = snprintf(str, size, "%s:%i: ", file, lineno); - str += ret; - size -= ret; - - if (tst_color_enabled(STDERR_FILENO)) - ret = snprintf(str, size, "%s%s: %s", tst_ttype2color(ttype), - res, ANSI_COLOR_RESET); - else - ret = snprintf(str, size, "%s: ", res); - str += ret; - size -= ret; - - ssize = size - 2; - ret = vsnprintf(str, size, fmt, va); - str += MIN(ret, ssize); - size -= MIN(ret, ssize); - if (ret >= ssize) { - tst_res_(file, lineno, TWARN, - "Next message is too long and truncated:"); - } else if (str_errno) { - ssize = size - 2; - ret = snprintf(str, size, ": %s (%d)", str_errno, int_errno); - str += MIN(ret, ssize); - size -= MIN(ret, ssize); - if (ret >= ssize) - tst_res_(file, lineno, TWARN, - "Next message is too long and truncated:"); - } - - snprintf(str, size, "\n"); - - /* we might be called from signal handler, so use write() */ - buflen = str - buf + 1; - str = buf; - while (buflen) { - ret = write(STDERR_FILENO, str, buflen); - if (ret <= 0) - break; - - str += ret; - buflen -= ret; - } -} - -void tst_vres_(const char *file, const int lineno, int ttype, - const char *fmt, va_list va) -{ - print_result(file, lineno, ttype, fmt, va); - - update_results(TTYPE_RESULT(ttype)); -} - -void tst_vbrk_(const char *file, const int lineno, int ttype, - const char *fmt, va_list va); - -static void (*tst_brk_handler)(const char *file, const int lineno, int ttype, - const char *fmt, va_list va) = tst_vbrk_; - -static void tst_cvres(const char *file, const int lineno, int ttype, - const char *fmt, va_list va) -{ - if (TTYPE_RESULT(ttype) == TBROK) { - ttype &= ~TTYPE_MASK; - ttype |= TWARN; - } - - print_result(file, lineno, ttype, fmt, va); - update_results(TTYPE_RESULT(ttype)); -} - -static void do_test_cleanup(void) -{ - tst_brk_handler = tst_cvres; - - if (tst_test->cleanup) - tst_test->cleanup(); - - tst_free_all(); - - tst_brk_handler = tst_vbrk_; -} - -void tst_vbrk_(const char *file, const int lineno, int ttype, - const char *fmt, va_list va) -{ - print_result(file, lineno, ttype, fmt, va); - update_results(TTYPE_RESULT(ttype)); - - /* - * The getpid implementation in some C library versions may cause cloned - * test threads to show the same pid as their parent when CLONE_VM is - * specified but CLONE_THREAD is not. Use direct syscall to avoid - * cleanup running in the child. - */ - if (syscall(SYS_getpid) == main_pid) - do_test_cleanup(); - - if (getpid() == lib_pid) - do_exit(TTYPE_RESULT(ttype)); - - exit(TTYPE_RESULT(ttype)); -} - -void tst_res_(const char *file, const int lineno, int ttype, - const char *fmt, ...) -{ - va_list va; - - va_start(va, fmt); - tst_vres_(file, lineno, ttype, fmt, va); - va_end(va); -} - -void tst_brk_(const char *file, const int lineno, int ttype, - const char *fmt, ...) -{ - va_list va; - - va_start(va, fmt); - tst_brk_handler(file, lineno, ttype, fmt, va); - va_end(va); -} - -static void check_child_status(pid_t pid, int status) -{ - int ret; - - if (WIFSIGNALED(status)) { - tst_brk(TBROK, "Child (%i) killed by signal %s", - pid, tst_strsig(WTERMSIG(status))); - } - - if (!(WIFEXITED(status))) - tst_brk(TBROK, "Child (%i) exited abnormally", pid); - - ret = WEXITSTATUS(status); - switch (ret) { - case TPASS: - break; - case TBROK: - case TCONF: - tst_brk(ret, "Reported by child (%i)", pid); - break; - default: - tst_brk(TBROK, "Invalid child (%i) exit value %i", pid, ret); - } -} - -void tst_reap_children(void) -{ - int status; - pid_t pid; - - for (;;) { - pid = wait(&status); - - if (pid > 0) { - check_child_status(pid, status); - continue; - } - - if (errno == ECHILD) - break; - - if (errno == EINTR) - continue; - - tst_brk(TBROK | TERRNO, "wait() failed"); - } -} - - -pid_t safe_fork(const char *filename, unsigned int lineno) -{ - pid_t pid; - - if (!tst_test->forks_child) - tst_brk(TBROK, "test.forks_child must be set!"); - - tst_flush(); - - pid = fork(); - if (pid < 0) - tst_brk_(filename, lineno, TBROK | TERRNO, "fork() failed"); - - if (!pid) - atexit(tst_free_all); - - return pid; -} - -static struct option { - char *optstr; - char *help; -} options[] = { - {"h", "-h Prints this help"}, - {"i:", "-i n Execute test n times"}, - {"I:", "-I x Execute test for n seconds"}, - {"C:", "-C ARG Run child process with ARG arguments (used internally)"}, -}; - -static void print_help(void) -{ - unsigned int i; - - fprintf(stderr, "Options\n"); - fprintf(stderr, "-------\n"); - - for (i = 0; i < ARRAY_SIZE(options); i++) - fprintf(stderr, "%s\n", options[i].help); - - if (!tst_test->options) - return; - - for (i = 0; tst_test->options[i].optstr; i++) - fprintf(stderr, "%s\n", tst_test->options[i].help); -} - -static void print_test_tags(void) -{ - unsigned int i; - const struct tst_tag *tags = tst_test->tags; - - if (!tags) - return; - - printf("\nTags\n"); - printf("----\n"); - - for (i = 0; tags[i].name; i++) { - if (!strcmp(tags[i].name, "CVE")) - printf(CVE_DB_URL "%s\n", tags[i].value); - else if (!strcmp(tags[i].name, "linux-git")) - printf(LINUX_GIT_URL "%s\n", tags[i].value); - else - printf("%s: %s\n", tags[i].name, tags[i].value); - } - - printf("\n"); -} - -static void check_option_collision(void) -{ - unsigned int i, j; - struct tst_option *toptions = tst_test->options; - - if (!toptions) - return; - - for (i = 0; toptions[i].optstr; i++) { - for (j = 0; j < ARRAY_SIZE(options); j++) { - if (toptions[i].optstr[0] == options[j].optstr[0]) { - tst_brk(TBROK, "Option collision '%s'", - options[j].help); - } - } - } -} - -static unsigned int count_options(void) -{ - unsigned int i; - - if (!tst_test->options) - return 0; - - for (i = 0; tst_test->options[i].optstr; i++); - - return i; -} - -static void parse_topt(unsigned int topts_len, int opt, char *optarg) -{ - unsigned int i; - struct tst_option *toptions = tst_test->options; - - for (i = 0; i < topts_len; i++) { - if (toptions[i].optstr[0] == opt) - break; - } - - if (i >= topts_len) - tst_brk(TBROK, "Invalid option '%c' (should not happen)", opt); - - if (*toptions[i].arg) - tst_res(TWARN, "Option -%c passed multiple times", opt); - - *(toptions[i].arg) = optarg ? optarg : ""; -} - -/* see self_exec.c */ -#ifdef UCLINUX -extern char *child_args; -#endif - -static void parse_opts(int argc, char *argv[]) -{ - unsigned int i, topts_len = count_options(); - char optstr[2 * ARRAY_SIZE(options) + 2 * topts_len]; - int opt; - - check_option_collision(); - - optstr[0] = 0; - - for (i = 0; i < ARRAY_SIZE(options); i++) - strcat(optstr, options[i].optstr); - - for (i = 0; i < topts_len; i++) - strcat(optstr, tst_test->options[i].optstr); - - while ((opt = getopt(argc, argv, optstr)) > 0) { - switch (opt) { - case '?': - print_help(); - tst_brk(TBROK, "Invalid option"); - break; - case 'h': - print_help(); - print_test_tags(); - exit(0); - case 'i': - iterations = atoi(optarg); - break; - case 'I': - duration = atof(optarg); - break; - case 'C': -#ifdef UCLINUX - child_args = optarg; -#endif - break; - default: - parse_topt(topts_len, opt, optarg); - } - } - - if (optind < argc) - tst_brk(TBROK, "Unexpected argument(s) '%s'...", argv[optind]); -} - -int tst_parse_int(const char *str, int *val, int min, int max) -{ - long rval; - - if (!str) - return 0; - - int ret = tst_parse_long(str, &rval, min, max); - - if (ret) - return ret; - - *val = (int)rval; - return 0; -} - -int tst_parse_long(const char *str, long *val, long min, long max) -{ - long rval; - char *end; - - if (!str) - return 0; - - errno = 0; - rval = strtol(str, &end, 10); - - if (str == end || *end != '\0') - return EINVAL; - - if (errno) - return errno; - - if (rval > max || rval < min) - return ERANGE; - - *val = rval; - return 0; -} - -int tst_parse_float(const char *str, float *val, float min, float max) -{ - double rval; - char *end; - - if (!str) - return 0; - - errno = 0; - rval = strtod(str, &end); - - if (str == end || *end != '\0') - return EINVAL; - - if (errno) - return errno; - - if (rval > (double)max || rval < (double)min) - return ERANGE; - - *val = (float)rval; - return 0; -} - -static void print_colored(const char *str) -{ - if (tst_color_enabled(STDOUT_FILENO)) - printf("%s%s%s", ANSI_COLOR_YELLOW, str, ANSI_COLOR_RESET); - else - printf("%s", str); -} - -static void print_failure_hints(void) -{ - unsigned int i; - const struct tst_tag *tags = tst_test->tags; - - if (!tags) - return; - - int hint_printed = 0; - for (i = 0; tags[i].name; i++) { - if (!strcmp(tags[i].name, "linux-git")) { - if (!hint_printed) { - hint_printed = 1; - printf("\n"); - print_colored("HINT: "); - printf("You _MAY_ be missing kernel fixes, see:\n\n"); - } - - printf(LINUX_GIT_URL "%s\n", tags[i].value); - } - - } - - hint_printed = 0; - for (i = 0; tags[i].name; i++) { - if (!strcmp(tags[i].name, "CVE")) { - if (!hint_printed) { - hint_printed = 1; - printf("\n"); - print_colored("HINT: "); - printf("You _MAY_ be vulnerable to CVE(s), see:\n\n"); - } - - printf(CVE_DB_URL "%s\n", tags[i].value); - } - } -} - -static void do_exit(int ret) -{ - if (results) { - if (results->passed && ret == TCONF) - ret = 0; - - if (results->failed) { - ret |= TFAIL; - print_failure_hints(); - } - - if (results->skipped && !results->passed) - ret |= TCONF; - - if (results->warnings) - ret |= TWARN; - - printf("\nSummary:\n"); - printf("passed %d\n", results->passed); - printf("failed %d\n", results->failed); - printf("skipped %d\n", results->skipped); - printf("warnings %d\n", results->warnings); - } - - do_cleanup(); - - exit(ret); -} - -void check_kver(void) -{ - int v1, v2, v3; - - if (tst_parse_kver(tst_test->min_kver, &v1, &v2, &v3)) { - tst_res(TWARN, - "Invalid kernel version %s, expected %%d.%%d.%%d", - tst_test->min_kver); - } - - if (tst_kvercmp(v1, v2, v3) < 0) { - tst_brk(TCONF, "The test requires kernel %s or newer", - tst_test->min_kver); - } -} - -static int results_equal(struct results *a, struct results *b) -{ - if (a->passed != b->passed) - return 0; - - if (a->failed != b->failed) - return 0; - - if (a->skipped != b->skipped) - return 0; - - return 1; -} - -static int needs_tmpdir(void) -{ - return tst_test->needs_tmpdir || - tst_test->needs_device || - tst_test->mntpoint || - tst_test->resource_files || - tst_test->needs_checkpoints; -} - -static void copy_resources(void) -{ - unsigned int i; - - for (i = 0; tst_test->resource_files[i]; i++) - TST_RESOURCE_COPY(NULL, tst_test->resource_files[i], NULL); -} - -static const char *get_tid(char *argv[]) -{ - char *p; - - if (!argv[0] || !argv[0][0]) { - tst_res(TINFO, "argv[0] is empty!"); - return "ltp_empty_argv"; - } - - p = strrchr(argv[0], '/'); - if (p) - return p+1; - - return argv[0]; -} - -static struct tst_device tdev; -struct tst_device *tst_device; - -static void assert_test_fn(void) -{ - int cnt = 0; - - if (tst_test->test) - cnt++; - - if (tst_test->test_all) - cnt++; - - if (tst_test->sample) - cnt++; - - if (!cnt) - tst_brk(TBROK, "No test function specified"); - - if (cnt != 1) - tst_brk(TBROK, "You can define only one test function"); - - if (tst_test->test && !tst_test->tcnt) - tst_brk(TBROK, "Number of tests (tcnt) must be > 0"); - - if (!tst_test->test && tst_test->tcnt) - tst_brk(TBROK, "You can define tcnt only for test()"); -} - -static int prepare_and_mount_ro_fs(const char *dev, - const char *mntpoint, - const char *fs_type) -{ - char buf[PATH_MAX]; - - if (mount(dev, mntpoint, fs_type, 0, NULL)) { - tst_res(TINFO | TERRNO, "Can't mount %s at %s (%s)", - dev, mntpoint, fs_type); - return 1; - } - - mntpoint_mounted = 1; - - snprintf(buf, sizeof(buf), "%s/dir/", mntpoint); - SAFE_MKDIR(buf, 0777); - - snprintf(buf, sizeof(buf), "%s/file", mntpoint); - SAFE_FILE_PRINTF(buf, "file content"); - SAFE_CHMOD(buf, 0777); - - SAFE_MOUNT(dev, mntpoint, fs_type, MS_REMOUNT | MS_RDONLY, NULL); - - return 0; -} - -static void prepare_and_mount_dev_fs(const char *mntpoint) -{ - const char *flags[] = {"nodev", NULL}; - int mounted_nodev; - - mounted_nodev = tst_path_has_mnt_flags(NULL, flags); - if (mounted_nodev) { - tst_res(TINFO, "tmpdir isn't suitable for creating devices, " - "mounting tmpfs without nodev on %s", mntpoint); - SAFE_MOUNT(NULL, mntpoint, "tmpfs", 0, NULL); - mntpoint_mounted = 1; - } -} - -static void prepare_device(void) -{ - if (tst_test->format_device) { - SAFE_MKFS(tdev.dev, tdev.fs_type, tst_test->dev_fs_opts, - tst_test->dev_extra_opts); - } - - if (tst_test->needs_rofs) { - prepare_and_mount_ro_fs(tdev.dev, tst_test->mntpoint, - tdev.fs_type); - return; - } - - if (tst_test->mount_device) { - SAFE_MOUNT(tdev.dev, tst_test->mntpoint, tdev.fs_type, - tst_test->mnt_flags, tst_test->mnt_data); - mntpoint_mounted = 1; - } -} - -static void do_setup(int argc, char *argv[]) -{ - if (!tst_test) - tst_brk(TBROK, "No tests to run"); - - if (tst_test->tconf_msg) - tst_brk(TCONF, "%s", tst_test->tconf_msg); - - if (tst_test->needs_kconfigs) - tst_kconfig_check(tst_test->needs_kconfigs); - - assert_test_fn(); - - tid = get_tid(argv); - - if (tst_test->sample) - tst_test = tst_timer_test_setup(tst_test); - - parse_opts(argc, argv); - - if (tst_test->needs_root && geteuid() != 0) - tst_brk(TCONF, "Test needs to be run as root"); - - if (tst_test->min_kver) - check_kver(); - - if (tst_test->needs_cmds) { - const char *cmd; - char path[PATH_MAX]; - int i; - - for (i = 0; (cmd = tst_test->needs_cmds[i]); ++i) - if (tst_get_path(cmd, path, sizeof(path))) - tst_brk(TCONF, "Couldn't find '%s' in $PATH", cmd); - } - - if (tst_test->needs_drivers) { - const char *name; - int i; - - for (i = 0; (name = tst_test->needs_drivers[i]); ++i) - if (tst_check_driver(name)) - tst_brk(TCONF, "%s driver not available", name); - } - - if (tst_test->format_device) - tst_test->needs_device = 1; - - if (tst_test->mount_device) { - tst_test->needs_device = 1; - tst_test->format_device = 1; - } - - if (tst_test->all_filesystems) - tst_test->needs_device = 1; - - if (tst_test->request_hugepages) - tst_request_hugepages(tst_test->request_hugepages); - - setup_ipc(); - - if (tst_test->bufs) - tst_buffers_alloc(tst_test->bufs); - - if (needs_tmpdir() && !tst_tmpdir_created()) - tst_tmpdir(); - - if (tst_test->save_restore) { - const char * const *name = tst_test->save_restore; - - while (*name) { - tst_sys_conf_save(*name); - name++; - } - } - - if (tst_test->mntpoint) - SAFE_MKDIR(tst_test->mntpoint, 0777); - - if ((tst_test->needs_devfs || tst_test->needs_rofs || - tst_test->mount_device || tst_test->all_filesystems) && - !tst_test->mntpoint) { - tst_brk(TBROK, "tst_test->mntpoint must be set!"); - } - - if (!!tst_test->needs_rofs + !!tst_test->needs_devfs + - !!tst_test->needs_device > 1) { - tst_brk(TBROK, - "Two or more of needs_{rofs, devfs, device} are set"); - } - - if (tst_test->needs_devfs) - prepare_and_mount_dev_fs(tst_test->mntpoint); - - if (tst_test->needs_rofs) { - /* If we failed to mount read-only tmpfs. Fallback to - * using a device with read-only filesystem. - */ - if (prepare_and_mount_ro_fs(NULL, tst_test->mntpoint, "tmpfs")) { - tst_res(TINFO, "Can't mount tmpfs read-only, " - "falling back to block device..."); - tst_test->needs_device = 1; - tst_test->format_device = 1; - } - } - - if (tst_test->needs_device && !mntpoint_mounted) { - tdev.dev = tst_acquire_device_(NULL, tst_test->dev_min_size); - - if (!tdev.dev) - tst_brk(TCONF, "Failed to acquire device"); - - tst_device = &tdev; - - if (tst_test->dev_fs_type) - tdev.fs_type = tst_test->dev_fs_type; - else - tdev.fs_type = tst_dev_fs_type(); - - if (!tst_test->all_filesystems) - prepare_device(); - } - - if (tst_test->needs_overlay && !tst_test->mount_device) { - tst_brk(TBROK, "tst_test->mount_device must be set"); - } - if (tst_test->needs_overlay && !mntpoint_mounted) { - tst_brk(TBROK, "tst_test->mntpoint must be mounted"); - } - if (tst_test->needs_overlay && !ovl_mounted) { - SAFE_MOUNT_OVERLAY(); - ovl_mounted = 1; - } - - if (tst_test->resource_files) - copy_resources(); - - if (tst_test->restore_wallclock) - tst_wallclock_save(); - - if (tst_test->taint_check) - tst_taint_init(tst_test->taint_check); -} - -static void do_test_setup(void) -{ - main_pid = getpid(); - - if (tst_test->caps) - tst_cap_setup(tst_test->caps, TST_CAP_REQ); - - if (tst_test->setup) - tst_test->setup(); - - if (main_pid != getpid()) - tst_brk(TBROK, "Runaway child in setup()!"); - - if (tst_test->caps) - tst_cap_setup(tst_test->caps, TST_CAP_DROP); -} - -static void do_cleanup(void) -{ - if (ovl_mounted) - SAFE_UMOUNT(OVL_MNT); - - if (mntpoint_mounted) - tst_umount(tst_test->mntpoint); - - if (tst_test->needs_device && tdev.dev) - tst_release_device(tdev.dev); - - if (tst_tmpdir_created()) { - /* avoid munmap() on wrong pointer in tst_rmdir() */ - tst_futexes = NULL; - tst_rmdir(); - } - - tst_sys_conf_restore(0); - - if (tst_test->restore_wallclock) - tst_wallclock_restore(); - - cleanup_ipc(); -} - -static void run_tests(void) -{ - unsigned int i; - struct results saved_results; - - if (!tst_test->test) { - saved_results = *results; - tst_test->test_all(); - - if (getpid() != main_pid) { - exit(0); - } - - tst_reap_children(); - - if (results_equal(&saved_results, results)) - tst_brk(TBROK, "Test haven't reported results!"); - return; - } - - for (i = 0; i < tst_test->tcnt; i++) { - saved_results = *results; - tst_test->test(i); - - if (getpid() != main_pid) { - exit(0); - } - - tst_reap_children(); - - if (results_equal(&saved_results, results)) - tst_brk(TBROK, "Test %i haven't reported results!", i); - } -} - -static unsigned long long get_time_ms(void) -{ - struct timespec ts; - - if (tst_clock_gettime(CLOCK_MONOTONIC, &ts)) - tst_brk(TBROK | TERRNO, "tst_clock_gettime()"); - - return tst_timespec_to_ms(ts); -} - -static void add_paths(void) -{ - char *old_path = getenv("PATH"); - const char *start_dir; - char *new_path; - - start_dir = tst_get_startwd(); - - if (old_path) - SAFE_ASPRINTF(&new_path, "%s::%s", old_path, start_dir); - else - SAFE_ASPRINTF(&new_path, "::%s", start_dir); - - SAFE_SETENV("PATH", new_path, 1); - free(new_path); -} - -static void heartbeat(void) -{ - if (tst_clock_gettime(CLOCK_MONOTONIC, &tst_start_time)) - tst_res(TWARN | TERRNO, "tst_clock_gettime() failed"); - - kill(getppid(), SIGUSR1); -} - -static void testrun(void) -{ - unsigned int i = 0; - unsigned long long stop_time = 0; - int cont = 1; - - heartbeat(); - add_paths(); - do_test_setup(); - - if (duration > 0) - stop_time = get_time_ms() + (unsigned long long)(duration * 1000); - - for (;;) { - cont = 0; - - if (i < (unsigned int)iterations) { - i++; - cont = 1; - } - - if (stop_time && get_time_ms() < stop_time) - cont = 1; - - if (!cont) - break; - - run_tests(); - heartbeat(); - } - - do_test_cleanup(); - exit(0); -} - -static pid_t test_pid; - - -static volatile sig_atomic_t sigkill_retries; - -#define WRITE_MSG(msg) do { \ - if (write(2, msg, sizeof(msg) - 1)) { \ - /* https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66425 */ \ - } \ -} while (0) - -static void alarm_handler(int sig LTP_ATTRIBUTE_UNUSED) -{ - WRITE_MSG("Test timeouted, sending SIGKILL!\n"); - kill(-test_pid, SIGKILL); - alarm(5); - - if (++sigkill_retries > 10) { - WRITE_MSG("Cannot kill test processes!\n"); - WRITE_MSG("Congratulation, likely test hit a kernel bug.\n"); - WRITE_MSG("Exitting uncleanly...\n"); - _exit(TFAIL); - } -} - -static void heartbeat_handler(int sig LTP_ATTRIBUTE_UNUSED) -{ - alarm(results->timeout); - sigkill_retries = 0; -} - -static void sigint_handler(int sig LTP_ATTRIBUTE_UNUSED) -{ - if (test_pid > 0) { - WRITE_MSG("Sending SIGKILL to test process...\n"); - kill(-test_pid, SIGKILL); - } -} - -unsigned int tst_timeout_remaining(void) -{ - static struct timespec now; - unsigned int elapsed; - - if (tst_clock_gettime(CLOCK_MONOTONIC, &now)) - tst_res(TWARN | TERRNO, "tst_clock_gettime() failed"); - - elapsed = (tst_timespec_diff_ms(now, tst_start_time) + 500) / 1000; - if (results->timeout > elapsed) - return results->timeout - elapsed; - - return 0; -} - -unsigned int tst_multiply_timeout(unsigned int timeout) -{ - char *mul; - int ret; - - if (timeout_mul == -1) { - mul = getenv("LTP_TIMEOUT_MUL"); - if (mul) { - if ((ret = tst_parse_float(mul, &timeout_mul, 1, 10000))) { - tst_brk(TBROK, "Failed to parse LTP_TIMEOUT_MUL: %s", - tst_strerrno(ret)); - } - } else { - timeout_mul = 1; - } - } - if (timeout_mul < 1) - tst_brk(TBROK, "LTP_TIMEOUT_MUL must to be int >= 1! (%.2f)", - timeout_mul); - - if (timeout < 1) - tst_brk(TBROK, "timeout must to be >= 1! (%d)", timeout); - - return timeout * timeout_mul; -} - -void tst_set_timeout(int timeout) -{ - if (timeout == -1) { - tst_res(TINFO, "Timeout per run is disabled"); - return; - } - - if (timeout < 1) - tst_brk(TBROK, "timeout must to be >= 1! (%d)", timeout); - - results->timeout = tst_multiply_timeout(timeout); - - tst_res(TINFO, "Timeout per run is %uh %02um %02us", - results->timeout/3600, (results->timeout%3600)/60, - results->timeout % 60); - - if (getpid() == lib_pid) - alarm(results->timeout); - else - heartbeat(); -} - -static int fork_testrun(void) -{ - int status; - - if (tst_test->timeout) - tst_set_timeout(tst_test->timeout); - else - tst_set_timeout(300); - - SAFE_SIGNAL(SIGINT, sigint_handler); - - test_pid = fork(); - if (test_pid < 0) - tst_brk(TBROK | TERRNO, "fork()"); - - if (!test_pid) { - SAFE_SIGNAL(SIGALRM, SIG_DFL); - SAFE_SIGNAL(SIGUSR1, SIG_DFL); - SAFE_SIGNAL(SIGINT, SIG_DFL); - SAFE_SETPGID(0, 0); - testrun(); - } - - SAFE_WAITPID(test_pid, &status, 0); - alarm(0); - SAFE_SIGNAL(SIGINT, SIG_DFL); - - if (tst_test->taint_check && tst_taint_check()) { - tst_res(TFAIL, "Kernel is now tainted."); - return TFAIL; - } - - if (WIFEXITED(status) && WEXITSTATUS(status)) - return WEXITSTATUS(status); - - if (WIFSIGNALED(status) && WTERMSIG(status) == SIGKILL) { - tst_res(TINFO, "If you are running on slow machine, " - "try exporting LTP_TIMEOUT_MUL > 1"); - tst_brk(TBROK, "Test killed! (timeout?)"); - } - - if (WIFSIGNALED(status)) - tst_brk(TBROK, "Test killed by %s!", tst_strsig(WTERMSIG(status))); - - return 0; -} - -static int run_tcases_per_fs(void) -{ - int ret = 0; - unsigned int i; - const char *const *filesystems = tst_get_supported_fs_types(tst_test->dev_fs_flags); - - if (!filesystems[0]) - tst_brk(TCONF, "There are no supported filesystems"); - - for (i = 0; filesystems[i]; i++) { - - tst_res(TINFO, "Testing on %s", filesystems[i]); - tdev.fs_type = filesystems[i]; - - prepare_device(); - - ret = fork_testrun(); - - if (mntpoint_mounted) { - tst_umount(tst_test->mntpoint); - mntpoint_mounted = 0; - } - - if (ret == TCONF) - continue; - - if (ret == 0) - continue; - - do_exit(ret); - } - - return ret; -} - -unsigned int tst_variant; - -void tst_run_tcases(int argc, char *argv[], struct tst_test *self) -{ - int ret = 0; - unsigned int test_variants = 1; - - lib_pid = getpid(); - tst_test = self; - - do_setup(argc, argv); - - TCID = tid; - - SAFE_SIGNAL(SIGALRM, alarm_handler); - SAFE_SIGNAL(SIGUSR1, heartbeat_handler); - - if (tst_test->test_variants) - test_variants = tst_test->test_variants; - - for (tst_variant = 0; tst_variant < test_variants; tst_variant++) { - if (tst_test->all_filesystems) - ret |= run_tcases_per_fs(); - else - ret |= fork_testrun(); - - if (ret & ~(TCONF)) - goto exit; - } - -exit: - do_exit(ret); -} - - -void tst_flush(void) -{ - int rval; - - rval = fflush(stderr); - if (rval != 0) - tst_brk(TBROK | TERRNO, "fflush(stderr) failed"); - - rval = fflush(stdout); - if (rval != 0) - tst_brk(TBROK | TERRNO, "fflush(stdout) failed"); - -} diff --git a/kernel/tests/lib/tst_timer.c b/kernel/tests/lib/tst_timer.c deleted file mode 100644 index 62d8f90..0000000 --- a/kernel/tests/lib/tst_timer.c +++ /dev/null @@ -1,59 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Copyright (C) 2015 Cyril Hrubis <chrubis@suse.cz> - */ - -#include <errno.h> - -#define TST_NO_DEFAULT_MAIN - -#include "tst_test.h" -#include "tst_timer.h" -#include "tst_clocks.h" -#include "lapi/posix_clocks.h" - -static struct timespec start_time, stop_time; -static clockid_t clock_id; - -void tst_timer_check(clockid_t clk_id) -{ - if (tst_clock_gettime(clk_id, &start_time)) { - if (errno == EINVAL) { - tst_brk(TCONF, - "Clock id %s(%u) not supported by kernel", - tst_clock_name(clk_id), clk_id); - return; - } - - tst_brk(TBROK | TERRNO, "tst_clock_gettime() failed"); - } -} - -void tst_timer_start(clockid_t clk_id) -{ - clock_id = clk_id; - - if (tst_clock_gettime(clock_id, &start_time)) - tst_res(TWARN | TERRNO, "tst_clock_gettime() failed"); -} - -int tst_timer_expired_ms(long long ms) -{ - struct timespec cur_time; - - if (tst_clock_gettime(clock_id, &cur_time)) - tst_res(TWARN | TERRNO, "tst_clock_gettime() failed"); - - return tst_timespec_diff_ms(cur_time, start_time) >= ms; -} - -void tst_timer_stop(void) -{ - if (tst_clock_gettime(clock_id, &stop_time)) - tst_res(TWARN | TERRNO, "tst_clock_gettime() failed"); -} - -struct timespec tst_timer_elapsed(void) -{ - return tst_timespec_diff(stop_time, start_time); -} diff --git a/kernel/tests/lib/tst_timer_test.c b/kernel/tests/lib/tst_timer_test.c deleted file mode 100644 index 196c512..0000000 --- a/kernel/tests/lib/tst_timer_test.c +++ /dev/null @@ -1,472 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (c) 2017 Cyril Hrubis <chrubis@suse.cz> - */ - -#include <sys/prctl.h> -#include <stdlib.h> -#include <stdio.h> -#include <limits.h> -#include <string.h> - -#define TST_NO_DEFAULT_MAIN -#include "tst_test.h" -#include "tst_clocks.h" -#include "tst_timer_test.h" - -#define MAX_SAMPLES 500 - -static const char *scall; -static void (*setup)(void); -static void (*cleanup)(void); -static int (*sample)(int clk_id, long long usec); -static struct tst_test *test; - -static long long *samples; -static unsigned int cur_sample; -static unsigned int monotonic_resolution; -static unsigned int timerslack; -static int virt_env; - -static char *print_frequency_plot; -static char *file_name; -static char *str_sleep_time; -static char *str_sample_cnt; -static int sleep_time = -1; -static int sample_cnt; - -static void print_line(char c, int len) -{ - while (len-- > 0) - fputc(c, stderr); -} - -static unsigned int ceilu(float f) -{ - if (f - (int)f > 0) - return (unsigned int)f + 1; - - return (unsigned int)f; -} - -static unsigned int flooru(float f) -{ - return (unsigned int)f; -} - -static float bucket_len(unsigned int bucket, unsigned int max_bucket, - unsigned int cols) -{ - return 1.00 * bucket * cols / max_bucket; -} - -static const char *table_heading = " Time: us "; - -/* - * Line Header: '10023 | ' - */ -static unsigned int header_len(long long max_sample) -{ - unsigned int l = 1; - - while (max_sample/=10) - l++; - - return MAX(strlen(table_heading) + 2, l + 3); -} - -static void frequency_plot(void) -{ - unsigned int cols = 80; - unsigned int rows = 20; - unsigned int i, buckets[rows]; - long long max_sample = samples[0]; - long long min_sample = samples[cur_sample-1]; - unsigned int line_header_len = header_len(max_sample); - unsigned int plot_line_len = cols - line_header_len; - unsigned int bucket_size; - - memset(buckets, 0, sizeof(buckets)); - - /* - * We work with discrete data buckets smaller than 1 does not make - * sense as well as it's a good idea to keep buckets integer sized - * to avoid scaling artifacts. - */ - bucket_size = MAX(1u, ceilu(1.00 * (max_sample - min_sample)/(rows-1))); - - for (i = 0; i < cur_sample; i++) { - unsigned int bucket; - bucket = flooru(1.00 * (samples[i] - min_sample)/bucket_size); - buckets[bucket]++; - } - - unsigned int max_bucket = buckets[0]; - for (i = 1; i < rows; i++) - max_bucket = MAX(max_bucket, buckets[i]); - - fprintf(stderr, "\n%*s| Frequency\n", line_header_len - 2, table_heading); - - print_line('-', cols); - fputc('\n', stderr); - - unsigned int l, r; - - for (l = 0; l < rows; l++) { - if (buckets[l]) - break; - } - - for (r = rows-1; r > l; r--) { - if (buckets[r]) - break; - } - - for (i = l; i <= r; i++) { - float len = bucket_len(buckets[i], max_bucket, plot_line_len); - - fprintf(stderr, "%*lli | ", - line_header_len - 3, min_sample + bucket_size*i); - print_line('*', len); - - if ((len - (int)len) >= 0.5) - fputc('+', stderr); - else if ((len - (int)len) >= 0.25) - fputc('-', stderr); - else if (len < 0.25 && buckets[i]) - fputc('.', stderr); - - fputc('\n', stderr); - } - - print_line('-', cols); - fputc('\n', stderr); - - float scale = 1.00 * plot_line_len / max_bucket; - - fprintf(stderr, - "%*uus | 1 sample = %.5f '*', %.5f '+', %.5f '-', non-zero '.'\n", - line_header_len - 5, bucket_size, scale, scale * 2, scale * 4); - - fputc('\n', stderr); -} - -void tst_timer_sample(void) -{ - samples[cur_sample++] = tst_timer_elapsed_us(); -} - -static int cmp(const void *a, const void *b) -{ - const long long *aa = a, *bb = b; - - return (*bb - *aa); -} - -/* - * The threshold per one syscall is computed as a sum of: - * - * 400 us - accomodates for context switches, process - * migrations between CPUs on SMP, etc. - * 2*monotonic_resolution - accomodates for granurality of the CLOCK_MONOTONIC - * slack_per_scall - max of 0.1% of the sleep capped on 100ms or - * current->timer_slack_ns, which is slack allowed - * in kernel - * - * The formula for slack_per_scall applies to select() and *poll*() syscalls, - * the futex and *nanosleep() use only the timer_slack_ns, so we are a bit - * less strict here that we could be for these two for longer sleep times... - * - * We also allow for outliners, i.e. add some number to the threshold in case - * that the number of iteration is small. For large enoung number of iterations - * outliners are discarded and averaged out. - */ -static long long compute_threshold(long long requested_us, - unsigned int nsamples) -{ - unsigned int slack_per_scall = MIN(100000, requested_us / 1000); - - slack_per_scall = MAX(slack_per_scall, timerslack); - - return (400 + 2 * monotonic_resolution + slack_per_scall) * nsamples - + 3000/nsamples; -} - -/* - * Returns number of samples to discard. - * - * We set it to either at least 1 if number of samples > 1 or 5%. - */ -static unsigned int compute_discard(unsigned int nsamples) -{ - if (nsamples == 1) - return 0; - - return MAX(1u, nsamples / 20); -} - -static void write_to_file(void) -{ - unsigned int i; - FILE *f; - - if (!file_name) - return; - - f = fopen(file_name, "w"); - - if (!f) { - tst_res(TWARN | TERRNO, - "Failed to open '%s'", file_name); - return; - } - - for (i = 0; i < cur_sample; i++) - fprintf(f, "%lli\n", samples[i]); - - if (fclose(f)) { - tst_res(TWARN | TERRNO, - "Failed to close file '%s'", file_name); - } -} - - -/* - * Timer testing function. - * - * What we do here is: - * - * * Take nsamples measurements of the timer function, the function - * to be sampled is defined in the the actual test. - * - * * We sort the array of samples, then: - * - * - look for outliners which are samples where the sleep time has exceeded - * requested sleep time by an order of magnitude and, at the same time, are - * greater than clock resolution multiplied by three. - * - * - check for samples where the call has woken up too early which is a plain - * old bug - * - * - then we compute truncated mean and compare that with the requested sleep - * time increased by a threshold - */ -void do_timer_test(long long usec, unsigned int nsamples) -{ - long long trunc_mean, median; - unsigned int discard = compute_discard(nsamples); - unsigned int keep_samples = nsamples - discard; - long long threshold = compute_threshold(usec, keep_samples); - int i; - int failed = 0; - - tst_res(TINFO, - "%s sleeping for %llius %u iterations, threshold %.2fus", - scall, usec, nsamples, 1.00 * threshold / (keep_samples)); - - cur_sample = 0; - for (i = 0; i < (int)nsamples; i++) { - if (sample(CLOCK_MONOTONIC, usec)) { - tst_res(TINFO, "sampling function failed, exitting"); - return; - } - } - - qsort(samples, nsamples, sizeof(samples[0]), cmp); - - write_to_file(); - - for (i = 0; samples[i] > 10 * usec && i < (int)nsamples; i++) { - if (samples[i] <= 3 * monotonic_resolution) - break; - } - - if (i > 0) { - tst_res(TINFO, "Found %i outliners in [%lli,%lli] range", - i, samples[0], samples[i-1]); - } - - for (i = nsamples - 1; samples[i] < usec && i > -1; i--); - - if (i < (int)nsamples - 1) { - tst_res(TFAIL, "%s woken up early %u times range: [%lli,%lli]", - scall, nsamples - 1 - i, - samples[i+1], samples[nsamples-1]); - failed = 1; - } - - median = samples[nsamples/2]; - - trunc_mean = 0; - - for (i = discard; i < (int)nsamples; i++) - trunc_mean += samples[i]; - - tst_res(TINFO, - "min %llius, max %llius, median %llius, trunc mean %.2fus (discarded %u)", - samples[nsamples-1], samples[0], median, - 1.00 * trunc_mean / keep_samples, discard); - - if (virt_env) { - tst_res(TINFO, - "Virtualisation detected, skipping oversleep checks"); - } else if (trunc_mean > (nsamples - discard) * usec + threshold) { - tst_res(TFAIL, "%s slept for too long", scall); - - if (!print_frequency_plot) - frequency_plot(); - - failed = 1; - } - - if (print_frequency_plot) - frequency_plot(); - - if (!failed) - tst_res(TPASS, "Measured times are within thresholds"); -} - -static void parse_timer_opts(void); - -static int set_latency(void) -{ - int fd, latency = 0; - - fd = open("/dev/cpu_dma_latency", O_WRONLY); - if (fd < 0) - return fd; - - return write(fd, &latency, sizeof(latency)); -} - -static void timer_setup(void) -{ - struct timespec t; - int ret; - - if (setup) - setup(); - - /* - * Running tests in VM may cause timing issues, disable upper bound - * checks if any hypervisor is detected. - */ - virt_env = tst_is_virt(VIRT_ANY); - tst_clock_getres(CLOCK_MONOTONIC, &t); - - tst_res(TINFO, "CLOCK_MONOTONIC resolution %lins", (long)t.tv_nsec); - - monotonic_resolution = t.tv_nsec / 1000; - timerslack = 50; - -#ifdef PR_GET_TIMERSLACK - ret = prctl(PR_GET_TIMERSLACK); - if (ret < 0) { - tst_res(TINFO, "prctl(PR_GET_TIMERSLACK) = -1, using %uus", - timerslack); - } else { - timerslack = ret / 1000; - tst_res(TINFO, "prctl(PR_GET_TIMERSLACK) = %ius", timerslack); - } -#else - tst_res(TINFO, "PR_GET_TIMERSLACK not defined, using %uus", - timerslack); -#endif /* PR_GET_TIMERSLACK */ - parse_timer_opts(); - - samples = SAFE_MALLOC(sizeof(long long) * MAX(MAX_SAMPLES, sample_cnt)); - if (set_latency() < 0) - tst_res(TINFO, "Failed to set zero latency constraint: %m"); -} - -static void timer_cleanup(void) -{ - free(samples); - - if (cleanup) - cleanup(); -} - -static struct tst_timer_tcase { - long long usec; - unsigned int samples; -} tcases[] = { - {1000, 500}, - {2000, 500}, - {5000, 300}, - {10000, 100}, - {25000, 50}, - {100000, 10}, - {1000000, 2}, -}; - -static void timer_test_fn(unsigned int n) -{ - do_timer_test(tcases[n].usec, tcases[n].samples); -} - -static void single_timer_test(void) -{ - do_timer_test(sleep_time, sample_cnt); -} - -static struct tst_option options[] = { - {"p", &print_frequency_plot, "-p Print frequency plot"}, - {"s:", &str_sleep_time, "-s us Sleep time"}, - {"n:", &str_sample_cnt, "-n uint Number of samples to take"}, - {"f:", &file_name, "-f fname Write measured samples into a file"}, - {NULL, NULL, NULL} -}; - -static void parse_timer_opts(void) -{ - if (str_sleep_time) { - if (tst_parse_int(str_sleep_time, &sleep_time, 0, INT_MAX)) { - tst_brk(TBROK, - "Invalid sleep time '%s'", str_sleep_time); - } - } - - if (str_sample_cnt) { - if (tst_parse_int(str_sample_cnt, &sample_cnt, 1, INT_MAX)) { - tst_brk(TBROK, - "Invalid sample count '%s'", str_sample_cnt); - } - } - - if (str_sleep_time || str_sample_cnt) { - if (sleep_time < 0) - sleep_time = 10000; - - if (!sample_cnt) - sample_cnt = 500; - - long long timeout = sleep_time * sample_cnt / 1000000; - - tst_set_timeout(timeout + timeout/10); - - test->test_all = single_timer_test; - test->test = NULL; - test->tcnt = 0; - } -} - -struct tst_test *tst_timer_test_setup(struct tst_test *timer_test) -{ - setup = timer_test->setup; - cleanup = timer_test->cleanup; - scall = timer_test->scall; - sample = timer_test->sample; - - timer_test->scall = NULL; - timer_test->setup = timer_setup; - timer_test->cleanup = timer_cleanup; - timer_test->test = timer_test_fn; - timer_test->tcnt = ARRAY_SIZE(tcases); - timer_test->sample = NULL; - timer_test->options = options; - - test = timer_test; - - return timer_test; -} diff --git a/kernel/tests/lib/tst_tmpdir.c b/kernel/tests/lib/tst_tmpdir.c deleted file mode 100644 index 0c39eb8..0000000 --- a/kernel/tests/lib/tst_tmpdir.c +++ /dev/null @@ -1,347 +0,0 @@ -/********************************************************** - * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it would be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * Further, this software is distributed without any warranty that it is - * free of the rightful claim of any third person regarding infringement - * or the like. Any license provided herein, whether implied or - * otherwise, applies only to this software file. Patent licenses, if - * any, provided herein do not apply to combinations of this program with - * other software, or any other product whatsoever. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, - * Mountain View, CA 94043, or: - * - * http://www.sgi.com - * - * For further information regarding this notice, see: - * - * http://oss.sgi.com/projects/GenInfo/NoticeExplan/ - *********************************************************/ - -/********************************************************** - * - * OS Testing - Silicon Graphics, Inc. - * - * FUNCTION NAME : tst_tmpdir, tst_rmdir - * - * FUNCTION TITLE : Create/remove a testing temp dir - * - * SYNOPSIS: - * void tst_tmpdir(); - * void tst_rmdir(); - * - * AUTHOR : Dave Fenner - * - * INITIAL RELEASE : UNICOS 8.0 - * - * DESCRIPTION - * tst_tmpdir() is used to create a unique, temporary testing - * directory, and make it the current working directory. - * tst_rmdir() is used to remove the directory created by - * tst_tmpdir(). - * - * RETURN VALUE - * Neither tst_tmpdir() or tst_rmdir() has a return value. - * - *********************************************************/ -#define _GNU_SOURCE -#include <sys/mman.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <assert.h> -#include <errno.h> -#include <libgen.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <dirent.h> -#include <fcntl.h> - -#include "test.h" -#include "safe_macros.h" -#include "ltp_priv.h" -#include "lapi/futex.h" - -/* - * Define some useful macros. - */ -#define DIR_MODE (S_IRWXU|S_IRWXG|S_IRWXO) - -#ifndef PATH_MAX -#ifdef MAXPATHLEN -#define PATH_MAX MAXPATHLEN -#else -#define PATH_MAX 1024 -#endif -#endif - -/* - * Define global variables. - */ -extern char *TCID; /* defined/initialized in main() */ -static char *TESTDIR = NULL; /* the directory created */ - -static char test_start_work_dir[PATH_MAX]; - -/* lib/tst_checkpoint.c */ -extern futex_t *tst_futexes; - -static int rmobj(const char *obj, char **errmsg); - -int tst_tmpdir_created(void) -{ - return TESTDIR != NULL; -} - -char *tst_get_tmpdir(void) -{ - if (TESTDIR == NULL) { - tst_brkm(TBROK, NULL, "you must call tst_tmpdir() first"); - return NULL; - } - - return strdup(TESTDIR); -} - -const char *tst_get_startwd(void) -{ - return test_start_work_dir; -} - -static int purge_dir(const char *path, char **errptr) -{ - int ret_val = 0; - DIR *dir; - struct dirent *dir_ent; - char dirobj[PATH_MAX]; - static char err_msg[PATH_MAX + 1280]; - - /* Do NOT perform the request if the directory is "/" */ - if (!strcmp(path, "/")) { - if (errptr) { - strcpy(err_msg, "Cannot purge system root directory"); - *errptr = err_msg; - } - - return -1; - } - - errno = 0; - - /* Open the directory to get access to what is in it */ - if (!(dir = opendir(path))) { - if (errptr) { - sprintf(err_msg, - "Cannot open directory %s; errno=%d: %s", - path, errno, tst_strerrno(errno)); - *errptr = err_msg; - } - return -1; - } - - /* Loop through the entries in the directory, removing each one */ - for (dir_ent = readdir(dir); dir_ent; dir_ent = readdir(dir)) { - /* Don't remove "." or ".." */ - if (!strcmp(dir_ent->d_name, ".") - || !strcmp(dir_ent->d_name, "..")) - continue; - - /* Recursively remove the current entry */ - sprintf(dirobj, "%s/%s", path, dir_ent->d_name); - if (rmobj(dirobj, errptr) != 0) - ret_val = -1; - } - - closedir(dir); - return ret_val; -} - -static int rmobj(const char *obj, char **errmsg) -{ - int ret_val = 0; - struct stat statbuf; - static char err_msg[PATH_MAX + 1280]; - int fd; - - fd = open(obj, O_DIRECTORY | O_NOFOLLOW); - if (fd >= 0) { - close(fd); - ret_val = purge_dir(obj, errmsg); - - /* If there were problems removing an entry, don't attempt to - remove the directory itself */ - if (ret_val == -1) - return -1; - - /* Get the link count, now that all the entries have been removed */ - if (lstat(obj, &statbuf) < 0) { - if (errmsg != NULL) { - sprintf(err_msg, - "lstat(%s) failed; errno=%d: %s", obj, - errno, tst_strerrno(errno)); - *errmsg = err_msg; - } - return -1; - } - - /* Remove the directory itself */ - if (statbuf.st_nlink >= 3) { - /* The directory is linked; unlink() must be used */ - if (unlink(obj) < 0) { - if (errmsg != NULL) { - sprintf(err_msg, - "unlink(%s) failed; errno=%d: %s", - obj, errno, tst_strerrno(errno)); - *errmsg = err_msg; - } - return -1; - } - } else { - /* The directory is not linked; remove() can be used */ - if (remove(obj) < 0) { - if (errmsg != NULL) { - sprintf(err_msg, - "remove(%s) failed; errno=%d: %s", - obj, errno, tst_strerrno(errno)); - *errmsg = err_msg; - } - return -1; - } - } - } else { - if (unlink(obj) < 0) { - if (errmsg != NULL) { - sprintf(err_msg, - "unlink(%s) failed; errno=%d: %s", obj, - errno, tst_strerrno(errno)); - *errmsg = err_msg; - } - return -1; - } - } - - return 0; -} - -void tst_tmpdir(void) -{ - char template[PATH_MAX]; - char *env_tmpdir; - char *errmsg, *c; - - /* - * Create a template for the temporary directory. Use the - * environment variable TMPDIR if it is available, otherwise - * use our default TEMPDIR. - */ - env_tmpdir = getenv("TMPDIR"); - if (env_tmpdir) { - c = strchr(env_tmpdir, '/'); - /* - * Now we force environment variable TMPDIR to be an absolute - * pathname, which dose not make much sense, but it will - * greatly simplify code in tst_rmdir(). - */ - if (c != env_tmpdir) { - tst_brkm(TBROK, NULL, "You must specify an absolute " - "pathname for environment variable TMPDIR"); - return; - } - snprintf(template, PATH_MAX, "%s/%.3sXXXXXX", env_tmpdir, TCID); - } else { - snprintf(template, PATH_MAX, "%s/%.3sXXXXXX", TEMPDIR, TCID); - } - - /* Make the temporary directory in one shot using mkdtemp. */ - if (mkdtemp(template) == NULL) { - tst_brkm(TBROK | TERRNO, NULL, - "%s: mkdtemp(%s) failed", __func__, template); - return; - } - - if ((TESTDIR = strdup(template)) == NULL) { - tst_brkm(TBROK | TERRNO, NULL, - "%s: strdup(%s) failed", __func__, template); - return; - } - - SAFE_CHOWN(NULL, TESTDIR, -1, getgid()); - - SAFE_CHMOD(NULL, TESTDIR, DIR_MODE); - - if (getcwd(test_start_work_dir, sizeof(test_start_work_dir)) == NULL) { - tst_resm(TINFO, "Failed to record test working dir"); - test_start_work_dir[0] = '\0'; - } - - /* - * Change to the temporary directory. If the chdir() fails, issue - * TBROK messages for all test cases, attempt to remove the - * directory (if it was created), and exit. If the removal also - * fails, also issue a TWARN message. - */ - if (chdir(TESTDIR) == -1) { - tst_resm(TERRNO, "%s: chdir(%s) failed", __func__, TESTDIR); - - /* Try to remove the directory */ - if (rmobj(TESTDIR, &errmsg) == -1) { - tst_resm(TWARN, "%s: rmobj(%s) failed: %s", - __func__, TESTDIR, errmsg); - } - - tst_exit(); - } -} - -void tst_rmdir(void) -{ - char *errmsg; - - /* - * Check that TESTDIR is not NULL. - */ - if (TESTDIR == NULL) { - tst_resm(TWARN, - "%s: TESTDIR was NULL; no removal attempted", - __func__); - return; - } - - /* - * Unmap the backend file. - * This is needed to overcome the NFS "silly rename" feature. - */ - if (tst_futexes) { - msync((void *)tst_futexes, getpagesize(), MS_SYNC); - munmap((void *)tst_futexes, getpagesize()); - } - - /* - * Attempt to remove the "TESTDIR" directory, using rmobj(). - */ - if (rmobj(TESTDIR, &errmsg) == -1) { - tst_resm(TWARN, "%s: rmobj(%s) failed: %s", - __func__, TESTDIR, errmsg); - } -} - -void tst_purge_dir(const char *path) -{ - char *err; - - if (purge_dir(path, &err)) - tst_brkm(TBROK, NULL, "%s: %s", __func__, err); -} diff --git a/kernel/tests/lib/tst_virt.c b/kernel/tests/lib/tst_virt.c deleted file mode 100644 index 53d33e6..0000000 --- a/kernel/tests/lib/tst_virt.c +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright (C) 2013 Linux Test Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it would be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * Further, this software is distributed without any warranty that it - * is free of the rightful claim of any third person regarding - * infringement or the like. Any license provided herein, whether - * implied or otherwise, applies only to this software file. Patent - * licenses, if any, provided herein do not apply to combinations of - * this program with other software, or any other product whatsoever. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#include <unistd.h> -#include "test.h" -#include "safe_macros.h" - -static int is_kvm(void) -{ - FILE *cpuinfo; - char line[64]; - int found; - - /* this doesn't work with custom -cpu values, since there's - * no easy, reasonable or reliable way to work around those */ - cpuinfo = SAFE_FOPEN(NULL, "/proc/cpuinfo", "r"); - found = 0; - while (fgets(line, sizeof(line), cpuinfo) != NULL) { - if (strstr(line, "QEMU Virtual CPU")) { - found = 1; - break; - } - } - - SAFE_FCLOSE(NULL, cpuinfo); - return found; -} - -static int is_xen(void) -{ - char hypervisor_type[4]; - - if (access("/proc/xen", F_OK) == 0) - return 1; - - if (access("/sys/hypervisor/type", F_OK) == 0) { - SAFE_FILE_SCANF(NULL, "/sys/hypervisor/type", "%3s", - hypervisor_type); - return strncmp("xen", hypervisor_type, - sizeof(hypervisor_type)) == 0; - } - - return 0; -} - -static int try_systemd_detect_virt(void) -{ - FILE *f; - char virt_type[64]; - int ret; - - /* See tst_cmd.c */ - void *old_handler = signal(SIGCHLD, SIG_DFL); - - f = popen("systemd-detect-virt", "r"); - if (!f) { - signal(SIGCHLD, old_handler); - return 0; - } - - if (!fgets(virt_type, sizeof(virt_type), f)) - virt_type[0] = '\0'; - - ret = pclose(f); - - signal(SIGCHLD, old_handler); - - /* - * systemd-detect-virt not found by shell or no virtualization detected - * (systemd-detect-virt returns non-zero) - */ - if (ret < 0 || (WIFEXITED(ret) && WEXITSTATUS(ret) == 127)) - return -1; - - if (ret) - return 0; - - if (!strncmp("kvm", virt_type, 3)) - return VIRT_KVM; - - if (!strncmp("xen", virt_type, 3)) - return VIRT_XEN; - - return VIRT_OTHER; -} - -int tst_is_virt(int virt_type) -{ - int ret = try_systemd_detect_virt(); - - if (ret >= 0) { - if (virt_type == VIRT_ANY) - return ret != 0; - else - return ret == virt_type; - } - - switch (virt_type) { - case VIRT_ANY: - return is_xen() || is_kvm(); - case VIRT_XEN: - return is_xen(); - case VIRT_KVM: - return is_kvm(); - case VIRT_OTHER: - return 0; - } - - tst_brkm(TBROK, NULL, "invalid virt_type flag: %d", virt_type); - return -1; -} diff --git a/kernel/tests/lib/tst_wallclock.c b/kernel/tests/lib/tst_wallclock.c deleted file mode 100644 index 282d6ad..0000000 --- a/kernel/tests/lib/tst_wallclock.c +++ /dev/null @@ -1,60 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (c) 2019 Linaro Limited. All rights reserved. - * Author: Rafael David Tinoco <rafael.tinoco@linaro.org> - */ - -#include <errno.h> - -#define TST_NO_DEFAULT_MAIN - -#include "tst_test.h" -#include "tst_timer.h" -#include "tst_clocks.h" -#include "tst_wallclock.h" -#include "lapi/posix_clocks.h" - -static struct timespec real_begin, mono_begin; - -static int clock_saved; - -void tst_wallclock_save(void) -{ - /* save initial monotonic time to restore it when needed */ - - if (tst_clock_gettime(CLOCK_REALTIME, &real_begin)) - tst_brk(TBROK | TERRNO, "tst_clock_gettime() realtime failed"); - - if (tst_clock_gettime(CLOCK_MONOTONIC_RAW, &mono_begin)) { - if (errno == EINVAL) { - tst_brk(TCONF | TERRNO, - "tst_clock_gettime() didn't support CLOCK_MONOTONIC_RAW"); - } - - tst_brk(TBROK | TERRNO, "tst_clock_gettime() monotonic failed"); - } - - clock_saved = 1; -} - -void tst_wallclock_restore(void) -{ - static struct timespec mono_end, elapsed, adjust; - - if (!clock_saved) - return; - - clock_saved = 0; - - if (tst_clock_gettime(CLOCK_MONOTONIC_RAW, &mono_end)) - tst_brk(TBROK | TERRNO, "tst_clock_gettime() monotonic failed"); - - elapsed = tst_timespec_diff(mono_end, mono_begin); - - adjust = tst_timespec_add(real_begin, elapsed); - - /* restore realtime clock based on monotonic delta */ - - if (tst_clock_settime(CLOCK_REALTIME, &adjust)) - tst_brk(TBROK | TERRNO, "tst_clock_settime() realtime failed"); -} |