"Fossies" - the Fresh Open Source Software Archive

Member "stress-ng-0.13.05/stress-ng.c" (11 Oct 2021, 108090 Bytes) of package /linux/privat/stress-ng-0.13.05.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "stress-ng.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 0.13.04_vs_0.13.05.

    1 /*
    2  * Copyright (C) 2013-2021 Canonical, Ltd.
    3  *
    4  * This program is free software; you can redistribute it and/or
    5  * modify it under the terms of the GNU General Public License
    6  * as published by the Free Software Foundation; either version 2
    7  * of the License, or (at your option) any later version.
    8  *
    9  * This program is distributed in the hope that it will be useful,
   10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   12  * GNU General Public License for more details.
   13  *
   14  * You should have received a copy of the GNU General Public License
   15  * along with this program; if not, write to the Free Software
   16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
   17  *
   18  * This code is a complete clean re-write of the stress tool by
   19  * Colin Ian King <colin.king@canonical.com> and attempts to be
   20  * backwardly compatible with the stress tool by Amos Waterland
   21  * <apw@rossby.metr.ou.edu> but has more stress tests and more
   22  * functionality.
   23  *
   24  */
   25 #include "stress-ng.h"
   26 
   27 typedef struct {
   28     const int opt;          /* optarg option */
   29     const uint64_t opt_flag;    /* global options flag bit setting */
   30 } stress_opt_flag_t;
   31 
   32 /* Per stressor information */
   33 static stress_stressor_t *stressors_head, *stressors_tail;
   34 stress_stressor_t *g_stressor_current;
   35 
   36 /* Various option settings and flags */
   37 static volatile bool wait_flag = true;      /* false = exit run wait loop */
   38 static int terminate_signum;            /* signal sent to process */
   39 
   40 /* Globals */
   41 int32_t g_opt_sequential = DEFAULT_SEQUENTIAL;  /* # of sequential stressors */
   42 int32_t g_opt_parallel = DEFAULT_PARALLEL;  /* # of parallel stressors */
   43 uint64_t g_opt_timeout = TIMEOUT_NOT_SET;   /* timeout in seconds */
   44 uint64_t g_opt_flags = PR_ERROR | PR_INFO | OPT_FLAGS_MMAP_MADVISE;
   45 volatile bool g_keep_stressing_flag = true; /* false to exit stressor */
   46 volatile bool g_caught_sigint = false;      /* true if stopped by SIGINT */
   47 pid_t g_pgrp;                   /* process group leader */
   48 const char *g_app_name = "stress-ng";       /* Name of application */
   49 stress_shared_t *g_shared;          /* shared memory */
   50 jmp_buf g_error_env;                /* parsing error env */
   51 stress_put_val_t g_put_val;         /* sync data to somewhere */
   52 static bool g_unsupported = false;      /* true if stressors are unsupported */
   53 
   54 /*
   55  *  optarg option to global setting option flags
   56  */
   57 static const stress_opt_flag_t opt_flags[] = {
   58     { OPT_abort,        OPT_FLAGS_ABORT },
   59     { OPT_aggressive,   OPT_FLAGS_AGGRESSIVE_MASK },
   60     { OPT_cpu_online_all,   OPT_FLAGS_CPU_ONLINE_ALL },
   61     { OPT_dry_run,      OPT_FLAGS_DRY_RUN },
   62     { OPT_ftrace,       OPT_FLAGS_FTRACE },
   63     { OPT_ignite_cpu,   OPT_FLAGS_IGNITE_CPU },
   64     { OPT_keep_name,    OPT_FLAGS_KEEP_NAME },
   65     { OPT_log_brief,    OPT_FLAGS_LOG_BRIEF },
   66     { OPT_maximize,     OPT_FLAGS_MAXIMIZE },
   67     { OPT_metrics,      OPT_FLAGS_METRICS },
   68     { OPT_metrics_brief,    OPT_FLAGS_METRICS_BRIEF | OPT_FLAGS_METRICS },
   69     { OPT_minimize,     OPT_FLAGS_MINIMIZE },
   70     { OPT_no_oom_adjust,    OPT_FLAGS_NO_OOM_ADJUST },
   71     { OPT_no_rand_seed, OPT_FLAGS_NO_RAND_SEED },
   72     { OPT_oomable,      OPT_FLAGS_OOMABLE },
   73     { OPT_page_in,      OPT_FLAGS_MMAP_MINCORE },
   74     { OPT_pathological, OPT_FLAGS_PATHOLOGICAL },
   75 #if defined(STRESS_PERF_STATS) &&   \
   76     defined(HAVE_LINUX_PERF_EVENT_H)
   77     { OPT_perf_stats,   OPT_FLAGS_PERF_STATS },
   78 #endif
   79     { OPT_skip_silent,  OPT_FLAGS_SKIP_SILENT },
   80     { OPT_smart,        OPT_FLAGS_SMART },
   81     { OPT_sock_nodelay, OPT_FLAGS_SOCKET_NODELAY },
   82 #if defined(HAVE_SYSLOG_H)
   83     { OPT_syslog,       OPT_FLAGS_SYSLOG },
   84 #endif
   85     { OPT_thrash,       OPT_FLAGS_THRASH },
   86     { OPT_times,        OPT_FLAGS_TIMES },
   87     { OPT_timestamp,    OPT_FLAGS_TIMESTAMP },
   88     { OPT_thermal_zones,    OPT_FLAGS_THERMAL_ZONES },
   89     { OPT_verbose,      PR_ALL },
   90     { OPT_verify,       OPT_FLAGS_VERIFY | PR_FAIL },
   91 };
   92 
   93 /*
   94  *  Attempt to catch a range of signals so
   95  *  we can clean up rather than leave
   96  *  cruft everywhere.
   97  */
   98 static const int terminate_signals[] = {
   99     /* POSIX.1-1990 */
  100 #if defined(SIGHUP)
  101     SIGHUP,
  102 #endif
  103 #if defined(SIGINT)
  104     SIGINT,
  105 #endif
  106 #if defined(SIGILL)
  107     SIGILL,
  108 #endif
  109 #if defined(SIGQUIT)
  110     SIGQUIT,
  111 #endif
  112 #if defined(SIGABRT)
  113     SIGABRT,
  114 #endif
  115 #if defined(SIGFPE)
  116     SIGFPE,
  117 #endif
  118 #if defined(SIGTERM)
  119     SIGTERM,
  120 #endif
  121 #if defined(SIGXCPU)
  122     SIGXCPU,
  123 #endif
  124 #if defined(SIGXFSZ)
  125     SIGXFSZ,
  126 #endif
  127     /* Linux various */
  128 #if defined(SIGIOT)
  129     SIGIOT,
  130 #endif
  131 #if defined(SIGSTKFLT)
  132     SIGSTKFLT,
  133 #endif
  134 #if defined(SIGPWR)
  135     SIGPWR,
  136 #endif
  137 #if defined(SIGINFO)
  138     SIGINFO,
  139 #endif
  140 #if defined(SIGVTALRM)
  141     SIGVTALRM,
  142 #endif
  143 };
  144 
  145 static const int ignore_signals[] = {
  146 #if defined(SIGUSR1)
  147     SIGUSR1,
  148 #endif
  149 #if defined(SIGUSR2)
  150     SIGUSR2,
  151 #endif
  152 #if defined(SIGTTOU)
  153     SIGTTOU,
  154 #endif
  155 #if defined(SIGTTIN)
  156     SIGTTIN,
  157 #endif
  158 #if defined(SIGWINCH)
  159     SIGWINCH,
  160 #endif
  161 };
  162 
  163 /*
  164  *  Elements in stressor array
  165  */
  166 #define STRESSOR_ELEM(name)     \
  167 {                   \
  168     &stress_ ## name ## _info,  \
  169     STRESS_ ## name,        \
  170     OPT_ ## name,           \
  171     OPT_ ## name  ## _ops,      \
  172     # name              \
  173 },
  174 
  175 /*
  176  *  Human readable stress test names.
  177  */
  178 static const stress_t stressors[] = {
  179     STRESSORS(STRESSOR_ELEM)
  180     { NULL, STRESS_MAX, 0, OPT_undefined, NULL }
  181 };
  182 
  183 STRESS_ASSERT(SIZEOF_ARRAY(stressors) != STRESS_MAX)
  184 
  185 /*
  186  *  Different stress classes
  187  */
  188 static const stress_class_info_t classes[] = {
  189     { CLASS_CPU_CACHE,  "cpu-cache" },
  190     { CLASS_CPU,        "cpu" },
  191     { CLASS_DEV,        "device" },
  192     { CLASS_FILESYSTEM, "filesystem" },
  193     { CLASS_INTERRUPT,  "interrupt" },
  194     { CLASS_IO,     "io" },
  195     { CLASS_MEMORY,     "memory" },
  196     { CLASS_NETWORK,    "network" },
  197     { CLASS_OS,     "os" },
  198     { CLASS_PIPE_IO,    "pipe" },
  199     { CLASS_SCHEDULER,  "scheduler" },
  200     { CLASS_SECURITY,   "security" },
  201     { CLASS_VM,     "vm" },
  202 };
  203 
  204 /*
  205  *  command line options
  206  */
  207 static const struct option long_options[] = {
  208     { "abort",  0,  0,  OPT_abort },
  209     { "access", 1,  0,  OPT_access },
  210     { "access-ops", 1,  0,  OPT_access_ops },
  211     { "af-alg", 1,  0,  OPT_af_alg },
  212     { "af-alg-ops", 1,  0,  OPT_af_alg_ops },
  213     { "af-alg-dump",0,  0,  OPT_af_alg_dump },
  214     { "affinity",   1,  0,  OPT_affinity },
  215     { "affinity-delay",1,   0,  OPT_affinity_delay },
  216     { "affinity-ops",1, 0,  OPT_affinity_ops },
  217     { "affinity-pin",0, 0,  OPT_affinity_pin },
  218     { "affinity-rand",0,    0,  OPT_affinity_rand },
  219     { "affinity-sleep",1,   0,  OPT_affinity_sleep },
  220     { "aggressive", 0,  0,  OPT_aggressive },
  221     { "aio",    1,  0,  OPT_aio },
  222     { "aio-ops",    1,  0,  OPT_aio_ops },
  223     { "aio-requests",1, 0,  OPT_aio_requests },
  224     { "aiol",   1,  0,  OPT_aiol},
  225     { "aiol-ops",   1,  0,  OPT_aiol_ops },
  226     { "aiol-requests",1,    0,  OPT_aiol_requests },
  227     { "alarm",  1,  0,  OPT_alarm },
  228     { "alarm-ops",  1,  0,  OPT_alarm_ops },
  229     { "all",    1,  0,  OPT_all },
  230     { "apparmor",   1,  0,  OPT_apparmor },
  231     { "apparmor-ops",1, 0,  OPT_apparmor_ops },
  232     { "atomic", 1,  0,  OPT_atomic },
  233     { "atomic-ops", 1,  0,  OPT_atomic_ops },
  234     { "bad-altstack",1, 0,  OPT_bad_altstack },
  235     { "bad-altstack-ops",1, 0,  OPT_bad_altstack_ops },
  236     { "bad-ioctl",1,    0,  OPT_bad_ioctl },
  237     { "bad-ioctl-ops",1,    0,  OPT_bad_ioctl_ops },
  238     { "backoff",    1,  0,  OPT_backoff },
  239     { "bigheap",    1,  0,  OPT_bigheap },
  240     { "bigheap-ops",1,  0,  OPT_bigheap_ops },
  241     { "bigheap-growth",1,   0,  OPT_bigheap_growth },
  242     { "bind-mount", 1,  0,  OPT_bind_mount },
  243     { "bind-mount-ops",1,   0,  OPT_bind_mount_ops },
  244     { "binderfs",   1,  0,  OPT_binderfs },
  245     { "binderfs-opts",1,    0,  OPT_binderfs_ops },
  246     { "branch", 1,  0,  OPT_branch },
  247     { "branch-ops", 1,  0,  OPT_branch_ops },
  248     { "brk",    1,  0,  OPT_brk },
  249     { "brk-ops",    1,  0,  OPT_brk_ops },
  250     { "brk-mlock",0,    0,  OPT_brk_mlock },
  251     { "brk-notouch",0,  0,  OPT_brk_notouch },
  252     { "bsearch",    1,  0,  OPT_bsearch },
  253     { "bsearch-ops",1,  0,  OPT_bsearch_ops },
  254     { "bsearch-size",1, 0,  OPT_bsearch_size },
  255     { "cache",  1,  0,  OPT_cache },
  256     { "cache-ops",  1,  0,  OPT_cache_ops },
  257     { "cache-prefetch",0,   0,  OPT_cache_prefetch },
  258     { "cache-flush",0,  0,  OPT_cache_flush },
  259     { "cache-fence",0,  0,  OPT_cache_fence },
  260     { "cache-level",1,  0,  OPT_cache_level},
  261     { "cache-sfence",0, 0,  OPT_cache_sfence },
  262     { "cache-ways",1,   0,  OPT_cache_ways},
  263     { "cache-no-affinity",0,0,  OPT_cache_no_affinity },
  264     { "cap",    1,  0,  OPT_cap },
  265     { "cap-ops",    1,  0,  OPT_cap_ops },
  266     { "chattr", 1,  0,  OPT_chattr },
  267     { "chattr-ops", 1,  0,  OPT_chattr_ops },
  268     { "chdir",  1,  0,  OPT_chdir },
  269     { "chdir-ops",  1,  0,  OPT_chdir_ops },
  270     { "chdir-dirs", 1,  0,  OPT_chdir_dirs },
  271     { "chmod",  1,  0,  OPT_chmod },
  272     { "chmod-ops",  1,  0,  OPT_chmod_ops },
  273     { "chown",  1,  0,  OPT_chown},
  274     { "chown-ops",  1,  0,  OPT_chown_ops },
  275     { "chroot", 1,  0,  OPT_chroot},
  276     { "chroot-ops", 1,  0,  OPT_chroot_ops },
  277     { "class",  1,  0,  OPT_class },
  278     { "clock",  1,  0,  OPT_clock },
  279     { "clock-ops",  1,  0,  OPT_clock_ops },
  280     { "clone",  1,  0,  OPT_clone },
  281     { "clone-ops",  1,  0,  OPT_clone_ops },
  282     { "clone-max",  1,  0,  OPT_clone_max },
  283     { "close",  1,  0,  OPT_close },
  284     { "close-ops",  1,  0,  OPT_close_ops },
  285     { "context",    1,  0,  OPT_context },
  286     { "context-ops",1,  0,  OPT_context_ops },
  287     { "copy-file",  1,  0,  OPT_copy_file },
  288     { "copy-file-ops", 1,   0,  OPT_copy_file_ops },
  289     { "copy-file-bytes", 1, 0,  OPT_copy_file_bytes },
  290     { "cpu",    1,  0,  OPT_cpu },
  291     { "cpu-ops",    1,  0,  OPT_cpu_ops },
  292     { "cpu-load",   1,  0,  OPT_cpu_load },
  293     { "cpu-load-slice",1,   0,  OPT_cpu_load_slice },
  294     { "cpu-method", 1,  0,  OPT_cpu_method },
  295     { "cpu-online", 1,  0,  OPT_cpu_online },
  296     { "cpu-online-ops",1,   0,  OPT_cpu_online_ops },
  297     { "cpu-online-all", 0,  0,  OPT_cpu_online_all },
  298     { "crypt",  1,  0,  OPT_crypt },
  299     { "crypt-ops",  1,  0,  OPT_crypt_ops },
  300     { "cyclic", 1,  0,  OPT_cyclic },
  301     { "cyclic-dist",1,  0,  OPT_cyclic_dist },
  302     { "cyclic-method",1,    0,  OPT_cyclic_method },
  303     { "cyclic-ops",1,   0,  OPT_cyclic_ops },
  304     { "cyclic-policy",1,    0,  OPT_cyclic_policy },
  305     { "cyclic-prio",1,  0,  OPT_cyclic_prio },
  306     { "cyclic-sleep",1, 0,  OPT_cyclic_sleep },
  307     { "daemon", 1,  0,  OPT_daemon },
  308     { "daemon-ops", 1,  0,  OPT_daemon_ops },
  309     { "dccp",   1,  0,  OPT_dccp },
  310     { "dccp-domain",1,  0,  OPT_dccp_domain },
  311     { "dccp-ops",   1,  0,  OPT_dccp_ops },
  312     { "dccp-opts",  1,  0,  OPT_dccp_opts },
  313     { "dccp-port",  1,  0,  OPT_dccp_port },
  314     { "dentry", 1,  0,  OPT_dentry },
  315     { "dentry-ops", 1,  0,  OPT_dentry_ops },
  316     { "dentries",   1,  0,  OPT_dentries },
  317     { "dentry-order",1, 0,  OPT_dentry_order },
  318     { "dev",    1,  0,  OPT_dev },
  319     { "dev-ops",    1,  0,  OPT_dev_ops },
  320     { "dev-file",   1,  0,  OPT_dev_file },
  321     { "dev-shm",    1,  0,  OPT_dev_shm },
  322     { "dev-shm-ops",1,  0,  OPT_dev_shm_ops },
  323     { "dir",    1,  0,  OPT_dir },
  324     { "dir-ops",    1,  0,  OPT_dir_ops },
  325     { "dir-dirs",   1,  0,  OPT_dir_dirs },
  326     { "dirdeep",    1,  0,  OPT_dirdeep },
  327     { "dirdeep-ops",1,  0,  OPT_dirdeep_ops },
  328     { "dirdeep-dirs",1, 0,  OPT_dirdeep_dirs },
  329     { "dirdeep-inodes",1,   0,  OPT_dirdeep_inodes },
  330     { "dirmany",    1,  0,  OPT_dirmany },
  331     { "dirmany-ops",1,  0,  OPT_dirmany_ops },
  332     { "dry-run",    0,  0,  OPT_dry_run },
  333     { "dnotify",    1,  0,  OPT_dnotify },
  334     { "dnotify-ops",1,  0,  OPT_dnotify_ops },
  335     { "dup",    1,  0,  OPT_dup },
  336     { "dup-ops",    1,  0,  OPT_dup_ops },
  337     { "dynlib", 1,  0,  OPT_dynlib },
  338     { "dynlib-ops", 1,  0,  OPT_dynlib_ops },
  339     { "efivar", 1,  0,  OPT_efivar },
  340     { "efivar-ops", 1,  0,  OPT_efivar_ops },
  341     { "enosys", 1,  0,  OPT_enosys },
  342     { "enosys-ops", 1,  0,  OPT_enosys_ops },
  343     { "env",    1,  0,  OPT_env },
  344     { "env-ops",    1,  0,  OPT_env_ops },
  345     { "epoll",  1,  0,  OPT_epoll },
  346     { "epoll-ops",  1,  0,  OPT_epoll_ops },
  347     { "epoll-port", 1,  0,  OPT_epoll_port },
  348     { "epoll-domain",1, 0,  OPT_epoll_domain },
  349     { "eventfd",    1,  0,  OPT_eventfd },
  350     { "eventfd-ops",1,  0,  OPT_eventfd_ops },
  351     { "eventfd-nonblock",0, 0,  OPT_eventfd_nonblock },
  352     { "exclude",    1,  0,  OPT_exclude },
  353     { "exec",   1,  0,  OPT_exec },
  354     { "exec-ops",   1,  0,  OPT_exec_ops },
  355     { "exec-max",   1,  0,  OPT_exec_max },
  356     { "exit-group", 1,  0,  OPT_exit_group },
  357     { "exit-group-ops",1,   0,  OPT_exit_group_ops },
  358     { "fallocate",  1,  0,  OPT_fallocate },
  359     { "fallocate-ops",1,    0,  OPT_fallocate_ops },
  360     { "fallocate-bytes",1,  0,  OPT_fallocate_bytes },
  361     { "fault",  1,  0,  OPT_fault },
  362     { "fault-ops",  1,  0,  OPT_fault_ops },
  363     { "fcntl",  1,  0,  OPT_fcntl},
  364     { "fcntl-ops",  1,  0,  OPT_fcntl_ops },
  365     { "fiemap", 1,  0,  OPT_fiemap },
  366     { "fiemap-ops", 1,  0,  OPT_fiemap_ops },
  367     { "fiemap-bytes",1, 0,  OPT_fiemap_bytes },
  368     { "fifo",   1,  0,  OPT_fifo },
  369     { "fifo-ops",   1,  0,  OPT_fifo_ops },
  370     { "fifo-readers",1, 0,  OPT_fifo_readers },
  371     { "file-ioctl", 1,  0,  OPT_file_ioctl },
  372     { "file-ioctl-ops",1,   0,  OPT_file_ioctl_ops },
  373     { "filename",   1,  0,  OPT_filename },
  374     { "filename-ops",1, 0,  OPT_filename_ops },
  375     { "filename-opts",1,    0,  OPT_filename_opts },
  376     { "flock",  1,  0,  OPT_flock },
  377     { "flock-ops",  1,  0,  OPT_flock_ops },
  378     { "fanotify",   1,  0,  OPT_fanotify },
  379     { "fanotify-ops",1, 0,  OPT_fanotify_ops },
  380     { "fork",   1,  0,  OPT_fork },
  381     { "fork-ops",   1,  0,  OPT_fork_ops },
  382     { "fork-max",   1,  0,  OPT_fork_max },
  383     { "fork-vm",    0,  0,  OPT_fork_vm },
  384     { "fp-error",   1,  0,  OPT_fp_error},
  385     { "fp-error-ops",1, 0,  OPT_fp_error_ops },
  386     { "fpunch", 1,  0,  OPT_fpunch },
  387     { "fpunch-ops", 1,  0,  OPT_fpunch_ops },
  388     { "fstat",  1,  0,  OPT_fstat },
  389     { "fstat-ops",  1,  0,  OPT_fstat_ops },
  390     { "fstat-dir",  1,  0,  OPT_fstat_dir },
  391     { "ftrace", 0,  0,  OPT_ftrace },
  392     { "full",   1,  0,  OPT_full },
  393     { "full-ops",   1,  0,  OPT_full_ops },
  394     { "funccall",   1,  0,  OPT_funccall },
  395     { "funccall-ops",1, 0,  OPT_funccall_ops },
  396     { "funccall-method",1,  0,  OPT_funccall_method },
  397     { "funcret",    1,  0,  OPT_funcret },
  398     { "funcret-ops",1,  0,  OPT_funcret_ops },
  399     { "funcret-method",1,   0,  OPT_funcret_method },
  400     { "futex",  1,  0,  OPT_futex },
  401     { "futex-ops",  1,  0,  OPT_futex_ops },
  402     { "get",    1,  0,  OPT_get },
  403     { "get-ops",    1,  0,  OPT_get_ops },
  404     { "getrandom",  1,  0,  OPT_getrandom },
  405     { "getrandom-ops",1,    0,  OPT_getrandom_ops },
  406     { "getdent",    1,  0,  OPT_getdent },
  407     { "getdent-ops",1,  0,  OPT_getdent_ops },
  408     { "handle", 1,  0,  OPT_handle },
  409     { "handle-ops", 1,  0,  OPT_handle_ops },
  410     { "hdd",    1,  0,  OPT_hdd },
  411     { "hdd-ops",    1,  0,  OPT_hdd_ops },
  412     { "hdd-bytes",  1,  0,  OPT_hdd_bytes },
  413     { "hdd-write-size", 1,  0,  OPT_hdd_write_size },
  414     { "hdd-opts",   1,  0,  OPT_hdd_opts },
  415     { "heapsort",   1,  0,  OPT_heapsort },
  416     { "heapsort-ops",1, 0,  OPT_heapsort_ops },
  417     { "heapsort-size",1,    0,  OPT_heapsort_integers },
  418     { "hrtimers",   1,  0,  OPT_hrtimers },
  419     { "hrtimers-ops",1, 0,  OPT_hrtimers_ops },
  420     { "help",   0,  0,  OPT_help },
  421     { "hsearch",    1,  0,  OPT_hsearch },
  422     { "hsearch-ops",1,  0,  OPT_hsearch_ops },
  423     { "hsearch-size",1, 0,  OPT_hsearch_size },
  424     { "icache", 1,  0,  OPT_icache },
  425     { "icache-ops", 1,  0,  OPT_icache_ops },
  426     { "icmp-flood", 1,  0,  OPT_icmp_flood },
  427     { "icmp-flood-ops",1,   0,  OPT_icmp_flood_ops },
  428     { "idle-page",  1,  0,  OPT_idle_page },
  429     { "idle-page-ops",1,    0,  OPT_idle_page_ops },
  430     { "ignite-cpu", 0,  0,  OPT_ignite_cpu },
  431     { "inode-flags",1,  0,  OPT_inode_flags },
  432     { "inode-flags-ops",1,  0,  OPT_inode_flags_ops },
  433     { "inotify",    1,  0,  OPT_inotify },
  434     { "inotify-ops",1,  0,  OPT_inotify_ops },
  435     { "io",     1,  0,  OPT_io },
  436     { "io-ops", 1,  0,  OPT_io_ops },
  437     { "iomix",  1,  0,  OPT_iomix },
  438     { "iomix-bytes",1,  0,  OPT_iomix_bytes },
  439     { "iomix-ops",  1,  0,  OPT_iomix_ops },
  440     { "ionice-class",1, 0,  OPT_ionice_class },
  441     { "ionice-level",1, 0,  OPT_ionice_level },
  442     { "ioport", 1,  0,  OPT_ioport },
  443     { "ioport-ops", 1,  0,  OPT_ioport_ops },
  444     { "ioport-opts",1,  0,  OPT_ioport_opts },
  445     { "ioprio", 1,  0,  OPT_ioprio },
  446     { "ioprio-ops", 1,  0,  OPT_ioprio_ops },
  447     { "iostat", 1,  0,  OPT_iostat },
  448     { "io-uring",   1,  0,  OPT_io_uring },
  449     { "io-uring-ops",1, 0,  OPT_io_uring_ops },
  450     { "ipsec-mb",   1,  0,  OPT_ipsec_mb },
  451     { "ipsec-mb-ops",1, 0,  OPT_ipsec_mb_ops },
  452     { "ipsec-mb-feature",1, 0,  OPT_ipsec_mb_feature },
  453     { "itimer", 1,  0,  OPT_itimer },
  454     { "itimer-ops", 1,  0,  OPT_itimer_ops },
  455     { "itimer-freq",1,  0,  OPT_itimer_freq },
  456     { "itimer-rand",0,  0,  OPT_itimer_rand },
  457     { "job",    1,  0,  OPT_job },
  458     { "judy",   1,  0,  OPT_judy },
  459     { "judy-ops",   1,  0,  OPT_judy_ops },
  460     { "judy-size",  1,  0,  OPT_judy_size },
  461     { "kcmp",   1,  0,  OPT_kcmp },
  462     { "kcmp-ops",   1,  0,  OPT_kcmp_ops },
  463     { "key",    1,  0,  OPT_key },
  464     { "key-ops",    1,  0,  OPT_key_ops },
  465     { "keep-name",  0,  0,  OPT_keep_name },
  466     { "kill",   1,  0,  OPT_kill },
  467     { "kill-ops",   1,  0,  OPT_kill_ops },
  468     { "klog",   1,  0,  OPT_klog },
  469     { "klog-ops",   1,  0,  OPT_klog_ops },
  470     { "l1cache",    1,  0,  OPT_l1cache },
  471     { "l1cache-ops",1,  0,  OPT_l1cache_ops },
  472     { "l1cache-line-size",1,0,  OPT_l1cache_line_size },
  473     { "l1cache-sets",1, 0,  OPT_l1cache_sets},
  474     { "l1cache-size",1, 0,  OPT_l1cache_size },
  475     { "l1cache-ways",1, 0,  OPT_l1cache_ways},
  476     { "landlock",   1,  0,  OPT_landlock },
  477     { "landlock-ops",1, 0,  OPT_landlock_ops },
  478     { "lease",  1,  0,  OPT_lease },
  479     { "lease-ops",  1,  0,  OPT_lease_ops },
  480     { "lease-breakers",1,   0,  OPT_lease_breakers },
  481     { "link",   1,  0,  OPT_link },
  482     { "link-ops",   1,  0,  OPT_link_ops },
  483     { "list",   1,  0,  OPT_list },
  484     { "list-ops",   1,  0,  OPT_list_ops },
  485     { "list-method",1,  0,  OPT_list_method },
  486     { "list-size",  1,  0,  OPT_list_size },
  487     { "loadavg",    1,  0,  OPT_loadavg },
  488     { "loadavg-ops",1,  0,  OPT_loadavg_ops },
  489     { "locka",  1,  0,  OPT_locka },
  490     { "locka-ops",  1,  0,  OPT_locka_ops },
  491     { "lockbus",    1,  0,  OPT_lockbus },
  492     { "lockbus-ops",1,  0,  OPT_lockbus_ops },
  493     { "lockf",  1,  0,  OPT_lockf },
  494     { "lockf-ops",  1,  0,  OPT_lockf_ops },
  495     { "lockf-nonblock", 0,  0,  OPT_lockf_nonblock },
  496     { "lockofd",    1,  0,  OPT_lockofd },
  497     { "lockofd-ops",1,  0,  OPT_lockofd_ops },
  498     { "log-brief",  0,  0,  OPT_log_brief },
  499     { "log-file",   1,  0,  OPT_log_file },
  500     { "longjmp",    1,  0,  OPT_longjmp },
  501     { "longjmp-ops",1,  0,  OPT_longjmp_ops },
  502     { "loop",   1,  0,  OPT_loop },
  503     { "loop-ops",   1,  0,  OPT_loop_ops },
  504     { "lsearch",    1,  0,  OPT_lsearch },
  505     { "lsearch-ops",1,  0,  OPT_lsearch_ops },
  506     { "lsearch-size",1, 0,  OPT_lsearch_size },
  507     { "madvise",    1,  0,  OPT_madvise },
  508     { "madvise-ops",1,  0,  OPT_madvise_ops },
  509     { "malloc", 1,  0,  OPT_malloc },
  510     { "malloc-bytes",1, 0,  OPT_malloc_bytes },
  511     { "malloc-max", 1,  0,  OPT_malloc_max },
  512     { "malloc-ops", 1,  0,  OPT_malloc_ops },
  513     { "malloc-pthreads",1,  0,  OPT_malloc_pthreads },
  514     { "malloc-thresh",1,    0,  OPT_malloc_threshold },
  515     { "malloc-touch",0, 0,  OPT_malloc_touch },
  516     { "matrix", 1,  0,  OPT_matrix },
  517     { "matrix-ops", 1,  0,  OPT_matrix_ops },
  518     { "matrix-method",1,    0,  OPT_matrix_method },
  519     { "matrix-size",1,  0,  OPT_matrix_size },
  520     { "matrix-yx",  0,  0,  OPT_matrix_yx },
  521     { "matrix-3d",  1,  0,  OPT_matrix_3d },
  522     { "matrix-3d-ops",1,    0,  OPT_matrix_3d_ops },
  523     { "matrix-3d-method",1, 0,  OPT_matrix_3d_method },
  524     { "matrix-3d-size",1,   0,  OPT_matrix_3d_size },
  525     { "matrix-3d-zyx",0,    0,  OPT_matrix_3d_zyx },
  526     { "maximize",   0,  0,  OPT_maximize },
  527     { "max-fd", 1,  0,  OPT_max_fd },
  528     { "mcontend",   1,  0,  OPT_mcontend },
  529     { "mcontend-ops",1, 0,  OPT_mcontend_ops },
  530     { "membarrier", 1,  0,  OPT_membarrier },
  531     { "membarrier-ops",1,   0,  OPT_membarrier_ops },
  532     { "memcpy", 1,  0,  OPT_memcpy },
  533     { "memcpy-ops", 1,  0,  OPT_memcpy_ops },
  534     { "memcpy-method",1,    0,  OPT_memcpy_method },
  535     { "memfd",  1,  0,  OPT_memfd },
  536     { "memfd-ops",  1,  0,  OPT_memfd_ops },
  537     { "memfd-bytes",1,  0,  OPT_memfd_bytes },
  538     { "memfd-fds",  1,  0,  OPT_memfd_fds },
  539     { "memhotplug", 1,  0,  OPT_memhotplug },
  540     { "memhotplug-ops",1,   0,  OPT_memhotplug_ops },
  541     { "memrate",    1,  0,  OPT_memrate },
  542     { "memrate-ops",1,  0,  OPT_memrate_ops },
  543     { "memrate-rd-mbs",1,   0,  OPT_memrate_rd_mbs },
  544     { "memrate-wr-mbs",1,   0,  OPT_memrate_wr_mbs },
  545     { "memrate-bytes",1,    0,  OPT_memrate_bytes },
  546     { "memthrash",  1,  0,  OPT_memthrash },
  547     { "memthrash-ops",1,    0,  OPT_memthrash_ops },
  548     { "memthrash-method",1, 0,  OPT_memthrash_method },
  549     { "mergesort",  1,  0,  OPT_mergesort },
  550     { "mergesort-ops",1,    0,  OPT_mergesort_ops },
  551     { "mergesort-size",1,   0,  OPT_mergesort_integers },
  552     { "metrics",    0,  0,  OPT_metrics },
  553     { "metrics-brief",0,    0,  OPT_metrics_brief },
  554     { "mincore",    1,  0,  OPT_mincore },
  555     { "mincore-ops",1,  0,  OPT_mincore_ops },
  556     { "mincore-random",0,   0,  OPT_mincore_rand },
  557     { "misaligned", 1,  0,  OPT_misaligned },
  558     { "misaligned-ops",1,   0,  OPT_misaligned_ops },
  559     { "misaligned-method",1,0,  OPT_misaligned_method },
  560     { "minimize",   0,  0,  OPT_minimize },
  561     { "mknod",  1,  0,  OPT_mknod },
  562     { "mknod-ops",  1,  0,  OPT_mknod_ops },
  563     { "mlock",  1,  0,  OPT_mlock },
  564     { "mlock-ops",  1,  0,  OPT_mlock_ops },
  565     { "mlockmany",  1,  0,  OPT_mlockmany },
  566     { "mlockmany-ops",1,    0,  OPT_mlockmany_ops },
  567     { "mlockmany-procs",1,  0,  OPT_mlockmany_procs },
  568     { "mmap",   1,  0,  OPT_mmap },
  569     { "mmap-ops",   1,  0,  OPT_mmap_ops },
  570     { "mmap-async", 0,  0,  OPT_mmap_async },
  571     { "mmap-bytes", 1,  0,  OPT_mmap_bytes },
  572     { "mmap-file",  0,  0,  OPT_mmap_file },
  573     { "mmap-mprotect",0,    0,  OPT_mmap_mprotect },
  574     { "mmap-osync", 0,  0,  OPT_mmap_osync },
  575     { "mmap-odirect",0, 0,  OPT_mmap_odirect },
  576     { "mmap-mmap2", 0,  0,  OPT_mmap_mmap2 },
  577     { "mmapaddr",   1,  0,  OPT_mmapaddr },
  578     { "mmapaddr-ops",1, 0,  OPT_mmapaddr_ops },
  579     { "mmapfixed",  1,  0,  OPT_mmapfixed},
  580     { "mmapfixed-ops",1,    0,  OPT_mmapfixed_ops },
  581     { "mmapfork",   1,  0,  OPT_mmapfork },
  582     { "mmapfork-ops",1, 0,  OPT_mmapfork_ops },
  583     { "mmaphuge",   1,  0,  OPT_mmaphuge },
  584     { "mmaphuge-ops",1, 0,  OPT_mmaphuge_ops },
  585     { "mmaphuge-mmaps",1,   0,  OPT_mmaphuge_mmaps },
  586     { "mmapmany",   1,  0,  OPT_mmapmany },
  587     { "mmapmany-ops",1, 0,  OPT_mmapmany_ops },
  588     { "mq",     1,  0,  OPT_mq },
  589     { "mq-ops", 1,  0,  OPT_mq_ops },
  590     { "mq-size",    1,  0,  OPT_mq_size },
  591     { "mremap", 1,  0,  OPT_mremap },
  592     { "mremap-ops", 1,  0,  OPT_mremap_ops },
  593     { "mremap-bytes",1, 0,  OPT_mremap_bytes },
  594     { "mremap-mlock",0, 0,  OPT_mremap_mlock },
  595     { "msg",    1,  0,  OPT_msg },
  596     { "msg-ops",    1,  0,  OPT_msg_ops },
  597     { "msg-types",  1,  0,  OPT_msg_types },
  598     { "msync",  1,  0,  OPT_msync },
  599     { "msync-ops",  1,  0,  OPT_msync_ops },
  600     { "msync-bytes",1,  0,  OPT_msync_bytes },
  601     { "munmap", 1,  0,  OPT_munmap },
  602     { "munmap-ops", 1,  0,  OPT_munmap_ops },
  603     { "nanosleep",  1,  0,  OPT_nanosleep },
  604     { "nanosleep-ops",1,    0,  OPT_nanosleep_ops },
  605     { "netdev", 1,  0,  OPT_netdev },
  606     { "netdev-ops",1,   0,  OPT_netdev_ops },
  607     { "netlink-proc",1, 0,  OPT_netlink_proc },
  608     { "netlink-proc-ops",1, 0,  OPT_netlink_proc_ops },
  609     { "netlink-task",1, 0,  OPT_netlink_task },
  610     { "netlink-task-ops",1, 0,  OPT_netlink_task_ops },
  611     { "nice",   1,  0,  OPT_nice },
  612     { "nice-ops",   1,  0,  OPT_nice_ops },
  613     { "no-madvise", 0,  0,  OPT_no_madvise },
  614     { "no-oom-adjust",0,    0,  OPT_no_oom_adjust },
  615     { "no-rand-seed", 0,    0,  OPT_no_rand_seed },
  616     { "nop",    1,  0,  OPT_nop },
  617     { "nop-ops",    1,  0,  OPT_nop_ops },
  618     { "nop-instr",  1,  0,  OPT_nop_instr },
  619     { "null",   1,  0,  OPT_null },
  620     { "null-ops",   1,  0,  OPT_null_ops },
  621     { "numa",   1,  0,  OPT_numa },
  622     { "numa-ops",   1,  0,  OPT_numa_ops },
  623     { "oomable",    0,  0,  OPT_oomable },
  624     { "oom-pipe",   1,  0,  OPT_oom_pipe },
  625     { "oom-pipe-ops",1, 0,  OPT_oom_pipe_ops },
  626     { "opcode", 1,  0,  OPT_opcode },
  627     { "opcode-ops", 1,  0,  OPT_opcode_ops },
  628     { "opcode-method",1,    0,  OPT_opcode_method },
  629     { "open",   1,  0,  OPT_open },
  630     { "open-fd",    0,  0,  OPT_open_fd },
  631     { "open-ops",   1,  0,  OPT_open_ops },
  632     { "page-in",    0,  0,  OPT_page_in },
  633     { "parallel",   1,  0,  OPT_all },
  634     { "pathological",0, 0,  OPT_pathological },
  635     { "pci",    1,  0,  OPT_pci},
  636     { "pci-ops",    1,  0,  OPT_pci_ops },
  637 #if defined(STRESS_PERF_STATS) &&   \
  638     defined(HAVE_LINUX_PERF_EVENT_H)
  639     { "perf",   0,  0,  OPT_perf_stats },
  640 #endif
  641     { "personality",1,  0,  OPT_personality },
  642     { "personality-ops",1,  0,  OPT_personality_ops },
  643     { "physpage",   1,  0,  OPT_physpage },
  644     { "physpage-ops",1, 0,  OPT_physpage_ops },
  645     { "pidfd",  1,  0,  OPT_pidfd },
  646     { "pidfd-ops",  1,  0,  OPT_pidfd_ops },
  647     { "ping-sock",  1,  0,  OPT_ping_sock },
  648     { "ping-sock-ops",1,    0,  OPT_ping_sock_ops },
  649     { "pipe",   1,  0,  OPT_pipe },
  650     { "pipe-ops",   1,  0,  OPT_pipe_ops },
  651     { "pipe-data-size",1,   0,  OPT_pipe_data_size },
  652 #if defined(F_SETPIPE_SZ)
  653     { "pipe-size",  1,  0,  OPT_pipe_size },
  654 #endif
  655     { "pipeherd",   1,  0,  OPT_pipeherd },
  656     { "pipeherd-ops",1, 0,  OPT_pipeherd_ops },
  657     { "pipeherd-yield", 0,  0,  OPT_pipeherd_yield },
  658     { "pkey",   1,  0,  OPT_pkey },
  659     { "pkey-ops",   1,  0,  OPT_pkey_ops },
  660     { "poll",   1,  0,  OPT_poll },
  661     { "poll-ops",   1,  0,  OPT_poll_ops },
  662     { "poll-fds",   1,  0,  OPT_poll_fds },
  663     { "prctl",  1,  0,  OPT_prctl },
  664     { "prctl-ops",  1,  0,  OPT_prctl_ops },
  665     { "prefetch",   1,  0,  OPT_prefetch },
  666     { "prefetch-ops",1, 0,  OPT_prefetch_ops },
  667     { "prefetch-l3-size",1, 0,  OPT_prefetch_l3_size },
  668     { "procfs", 1,  0,  OPT_procfs },
  669     { "procfs-ops", 1,  0,  OPT_procfs_ops },
  670     { "pthread",    1,  0,  OPT_pthread },
  671     { "pthread-ops",1,  0,  OPT_pthread_ops },
  672     { "pthread-max",1,  0,  OPT_pthread_max },
  673     { "ptrace", 1,  0,  OPT_ptrace },
  674     { "ptrace-ops",1,   0,  OPT_ptrace_ops },
  675     { "pty",    1,  0,  OPT_pty },
  676     { "pty-ops",    1,  0,  OPT_pty_ops },
  677     { "pty-max",    1,  0,  OPT_pty_max },
  678     { "qsort",  1,  0,  OPT_qsort },
  679     { "qsort-ops",  1,  0,  OPT_qsort_ops },
  680     { "qsort-size", 1,  0,  OPT_qsort_integers },
  681     { "quiet",  0,  0,  OPT_quiet },
  682     { "quota",  1,  0,  OPT_quota },
  683     { "quota-ops",  1,  0,  OPT_quota_ops },
  684     { "radixsort",  1,  0,  OPT_radixsort },
  685     { "radixsort-ops",1,    0,  OPT_radixsort_ops },
  686     { "radixsort-size",1,   0,  OPT_radixsort_size },
  687     { "ramfs",  1,  0,  OPT_ramfs },
  688     { "ramfs-ops",  1,  0,  OPT_ramfs_ops },
  689     { "ramfs-size", 1,  0,  OPT_ramfs_size },
  690     { "random", 1,  0,  OPT_random },
  691     { "rawdev", 1,  0,  OPT_rawdev },
  692     { "rawdev-ops",1,   0,  OPT_rawdev_ops },
  693     { "rawdev-method",1,    0,  OPT_rawdev_method },
  694     { "rawpkt", 1,  0,  OPT_rawpkt },
  695     { "rawpkt-ops",1,   0,  OPT_rawpkt_ops },
  696     { "rawpkt-port",1,  0,  OPT_rawpkt_port },
  697     { "rawsock",    1,  0,  OPT_rawsock },
  698     { "rawsock-ops",1,  0,  OPT_rawsock_ops },
  699     { "rawudp", 1,  0,  OPT_rawudp },
  700     { "rawudp-ops", 1,  0,  OPT_rawudp_ops },
  701     { "rawudp-port",1,  0,  OPT_rawudp_port },
  702     { "rdrand", 1,  0,  OPT_rdrand },
  703     { "rdrand-ops", 1,  0,  OPT_rdrand_ops },
  704     { "readahead",  1,  0,  OPT_readahead },
  705     { "readahead-ops",1,    0,  OPT_readahead_ops },
  706     { "readahead-bytes",1,  0,  OPT_readahead_bytes },
  707     { "reboot", 1,  0,  OPT_reboot },
  708     { "reboot-ops", 1,  0,  OPT_reboot_ops },
  709     { "remap",  1,  0,  OPT_remap },
  710     { "remap-ops",  1,  0,  OPT_remap_ops },
  711     { "rename", 1,  0,  OPT_rename },
  712     { "rename-ops", 1,  0,  OPT_rename_ops },
  713     { "resources",  1,  0,  OPT_resources },
  714     { "resources-ops",1,    0,  OPT_resources_ops },
  715     { "revio",  1,  0,  OPT_revio },
  716     { "revio-ops",  1,  0,  OPT_revio_ops },
  717     { "revio-opts", 1,  0,  OPT_revio_opts },
  718     { "revio-bytes",1,  0,  OPT_revio_bytes },
  719     { "rlimit", 1,  0,  OPT_rlimit },
  720     { "rlimit-ops", 1,  0,  OPT_rlimit_ops },
  721     { "rmap",   1,  0,  OPT_rmap },
  722     { "rmap-ops",   1,  0,  OPT_rmap_ops },
  723     { "rseq",   1,  0,  OPT_rseq },
  724     { "rseq-ops",   1,  0,  OPT_rseq_ops },
  725     { "rtc",    1,  0,  OPT_rtc },
  726     { "rtc-ops",    1,  0,  OPT_rtc_ops },
  727     { "sched",  1,  0,  OPT_sched },
  728     { "sched-prio", 1,  0,  OPT_sched_prio },
  729     { "schedpolicy",1,  0,  OPT_schedpolicy },
  730     { "schedpolicy-ops",1,  0,  OPT_schedpolicy_ops },
  731     { "sched-period",1, 0,  OPT_sched_period },
  732     { "sched-runtime",1,    0,  OPT_sched_runtime },
  733     { "sched-deadline",1,   0,  OPT_sched_deadline },
  734     { "sched-reclaim",0,    0,      OPT_sched_reclaim },
  735     { "schedpolicy",1,  0,  OPT_schedpolicy },
  736     { "sctp",   1,  0,  OPT_sctp },
  737     { "sctp-ops",   1,  0,  OPT_sctp_ops },
  738     { "sctp-domain",1,  0,  OPT_sctp_domain },
  739     { "sctp-port",  1,  0,  OPT_sctp_port },
  740     { "seal",   1,  0,  OPT_seal },
  741     { "seal-ops",   1,  0,  OPT_seal_ops },
  742     { "seccomp",    1,  0,  OPT_seccomp },
  743     { "seccomp-ops",1,  0,  OPT_seccomp_ops },
  744     { "secretmem",  1,  0,  OPT_secretmem },
  745     { "secretmem-ops",1,    0,  OPT_secretmem_ops },
  746     { "seed",   1,  0,  OPT_seed },
  747     { "seek",   1,  0,  OPT_seek },
  748     { "seek-ops",   1,  0,  OPT_seek_ops },
  749     { "seek-punch", 0,  0,  OPT_seek_punch  },
  750     { "seek-size",  1,  0,  OPT_seek_size },
  751     { "sem",    1,  0,  OPT_sem },
  752     { "sem-ops",    1,  0,  OPT_sem_ops },
  753     { "sem-procs",  1,  0,  OPT_sem_procs },
  754     { "sem-sysv",   1,  0,  OPT_sem_sysv },
  755     { "sem-sysv-ops",1, 0,  OPT_sem_sysv_ops },
  756     { "sem-sysv-procs",1,   0,  OPT_sem_sysv_procs },
  757     { "sendfile",   1,  0,  OPT_sendfile },
  758     { "sendfile-ops",1, 0,  OPT_sendfile_ops },
  759     { "sendfile-size",1,    0,  OPT_sendfile_size },
  760     { "sequential", 1,  0,  OPT_sequential },
  761     { "session",    1,  0,  OPT_session },
  762     { "session-ops",1,  0,  OPT_session_ops },
  763     { "set",    1,  0,  OPT_set },
  764     { "set-ops",    1,  0,  OPT_set_ops },
  765     { "shellsort",  1,  0,  OPT_shellsort },
  766     { "shellsort-ops",1,    0,  OPT_shellsort_ops },
  767     { "shellsort-size",1,   0,  OPT_shellsort_integers },
  768     { "shm",    1,  0,  OPT_shm },
  769     { "shm-ops",    1,  0,  OPT_shm_ops },
  770     { "shm-bytes",  1,  0,  OPT_shm_bytes },
  771     { "shm-objs",   1,  0,  OPT_shm_objects },
  772     { "shm-sysv",   1,  0,  OPT_shm_sysv },
  773     { "shm-sysv-ops",1, 0,  OPT_shm_sysv_ops },
  774     { "shm-sysv-bytes",1,   0,  OPT_shm_sysv_bytes },
  775     { "shm-sysv-segs",1,    0,  OPT_shm_sysv_segments },
  776     { "sigabrt",    1,  0,  OPT_sigabrt },
  777     { "sigabrt-ops",1,  0,  OPT_sigabrt_ops },
  778     { "sigchld",    1,  0,  OPT_sigchld },
  779     { "sigchld-ops",1,  0,  OPT_sigchld_ops },
  780     { "sigfd",  1,  0,  OPT_sigfd },
  781     { "sigfd-ops",  1,  0,  OPT_sigfd_ops },
  782     { "sigio",  1,  0,  OPT_sigio },
  783     { "sigio-ops",  1,  0,  OPT_sigio_ops },
  784     { "sigfpe", 1,  0,  OPT_sigfpe },
  785     { "sigfpe-ops", 1,  0,  OPT_sigfpe_ops },
  786     { "signal", 1,  0,  OPT_signal },
  787     { "signal-ops", 1,  0,  OPT_signal_ops },
  788     { "signest",    1,  0,  OPT_signest },
  789     { "signest-ops",1,  0,  OPT_signest_ops },
  790     { "sigpending", 1,  0,  OPT_sigpending},
  791     { "sigpending-ops",1,   0,  OPT_sigpending_ops },
  792     { "sigpipe",    1,  0,  OPT_sigpipe },
  793     { "sigpipe-ops",1,  0,  OPT_sigpipe_ops },
  794     { "sigq",   1,  0,  OPT_sigq },
  795     { "sigq-ops",   1,  0,  OPT_sigq_ops },
  796     { "sigrt",  1,  0,  OPT_sigrt },
  797     { "sigrt-ops",  1,  0,  OPT_sigrt_ops },
  798     { "sigsegv",    1,  0,  OPT_sigsegv },
  799     { "sigsegv-ops",1,  0,  OPT_sigsegv_ops },
  800     { "sigsuspend", 1,  0,  OPT_sigsuspend },
  801     { "sigsuspend-ops",1,   0,  OPT_sigsuspend_ops },
  802     { "sigtrap",    1,  0,  OPT_sigtrap },
  803     { "sigtrap-ops",1,  0,  OPT_sigtrap_ops},
  804     { "skiplist",   1,  0,  OPT_skiplist },
  805     { "skiplist-ops",1, 0,  OPT_skiplist_ops },
  806     { "skiplist-size",1,    0,  OPT_skiplist_size },
  807     { "skip-silent",0,  0,  OPT_skip_silent },
  808     { "sleep",  1,  0,  OPT_sleep },
  809     { "sleep-ops",  1,  0,  OPT_sleep_ops },
  810     { "sleep-max",  1,  0,  OPT_sleep_max },
  811     { "smart",  0,  0,  OPT_smart },
  812     { "smi",    1,  0,  OPT_smi },
  813     { "smi-ops",    1,  0,  OPT_smi_ops },
  814     { "sock",   1,  0,  OPT_sock },
  815     { "sock-domain",1,  0,  OPT_sock_domain },
  816     { "sock-nodelay",0, 0,  OPT_sock_nodelay },
  817     { "sock-ops",   1,  0,  OPT_sock_ops },
  818     { "sock-opts",  1,  0,  OPT_sock_opts },
  819     { "sock-port",  1,  0,  OPT_sock_port },
  820     { "sock-protocol",1,    0,  OPT_sock_protocol },
  821     { "sock-type",  1,  0,  OPT_sock_type },
  822     { "sock-zerocopy", 0,   0,  OPT_sock_zerocopy },
  823     { "sockabuse",  1,  0,  OPT_sockabuse },
  824     { "sockabuse-ops",1,    0,  OPT_sockabuse_ops },
  825     { "sockdiag",   1,  0,  OPT_sockdiag },
  826     { "sockdiag-ops",1, 0,  OPT_sockdiag_ops },
  827     { "sockfd", 1,  0,  OPT_sockfd },
  828     { "sockfd-ops",1,   0,  OPT_sockfd_ops },
  829     { "sockfd-port",1,  0,  OPT_sockfd_port },
  830     { "sockmany",   1,  0,  OPT_sockmany },
  831     { "sockmany-ops",1, 0,  OPT_sockmany_ops },
  832     { "sockpair",   1,  0,  OPT_sockpair },
  833     { "sockpair-ops",1, 0,  OPT_sockpair_ops },
  834     { "softlockup", 1,  0,  OPT_softlockup },
  835     { "softlockup-ops",1,   0,  OPT_softlockup_ops },
  836     { "spawn",  1,  0,  OPT_spawn },
  837     { "spawn-ops",  1,  0,  OPT_spawn_ops },
  838     { "splice", 1,  0,  OPT_splice },
  839     { "splice-bytes",1, 0,  OPT_splice_bytes },
  840     { "splice-ops", 1,  0,  OPT_splice_ops },
  841     { "stack",  1,  0,  OPT_stack},
  842     { "stack-fill", 0,  0,  OPT_stack_fill },
  843     { "stack-mlock",0,  0,  OPT_stack_mlock },
  844     { "stack-ops",  1,  0,  OPT_stack_ops },
  845     { "stackmmap",  1,  0,  OPT_stackmmap },
  846     { "stackmmap-ops",1,    0,  OPT_stackmmap_ops },
  847     { "str",    1,  0,  OPT_str },
  848     { "str-ops",    1,  0,  OPT_str_ops },
  849     { "str-method", 1,  0,  OPT_str_method },
  850     { "stressors",  0,  0,  OPT_stressors },
  851     { "stream", 1,  0,  OPT_stream },
  852     { "stream-ops", 1,  0,  OPT_stream_ops },
  853     { "stream-index",1, 0,  OPT_stream_index },
  854     { "stream-l3-size",1,   0,  OPT_stream_l3_size },
  855     { "stream-madvise",1,   0,  OPT_stream_madvise },
  856     { "swap",   1,  0,  OPT_swap },
  857     { "swap-ops",   1,  0,  OPT_swap_ops },
  858     { "switch", 1,  0,  OPT_switch },
  859     { "switch-ops", 1,  0,  OPT_switch_ops },
  860     { "switch-freq",1,  0,  OPT_switch_freq },
  861     { "symlink",    1,  0,  OPT_symlink },
  862     { "symlink-ops",1,  0,  OPT_symlink_ops },
  863     { "sync-file",  1,  0,  OPT_sync_file },
  864     { "sync-file-ops", 1,   0,  OPT_sync_file_ops },
  865     { "sync-file-bytes", 1, 0,  OPT_sync_file_bytes },
  866     { "sysbadaddr", 1,  0,  OPT_sysbadaddr },
  867     { "sysbadaddr-ops",1,   0,  OPT_sysbadaddr_ops },
  868     { "sysfs",  1,  0,  OPT_sysfs },
  869     { "sysfs-ops",1,    0,  OPT_sysfs_ops },
  870     { "sysinfo",    1,  0,  OPT_sysinfo },
  871     { "sysinfo-ops",1,  0,  OPT_sysinfo_ops },
  872     { "sysinval",   1,  0,  OPT_sysinval },
  873     { "sysinval-ops",1, 0,  OPT_sysinval_ops },
  874 #if defined(HAVE_SYSLOG_H)
  875     { "syslog", 0,  0,  OPT_syslog },
  876 #endif
  877     { "taskset",    1,  0,  OPT_taskset },
  878     { "tee",    1,  0,  OPT_tee },
  879     { "tee-ops",    1,  0,  OPT_tee_ops },
  880     { "temp-path",  1,  0,  OPT_temp_path },
  881     { "timeout",    1,  0,  OPT_timeout },
  882     { "timer",  1,  0,  OPT_timer },
  883     { "timer-ops",  1,  0,  OPT_timer_ops },
  884     { "timer-freq", 1,  0,  OPT_timer_freq },
  885     { "timer-rand", 0,  0,  OPT_timer_rand },
  886     { "timerfd",    1,  0,  OPT_timerfd },
  887     { "timerfd-ops",1,  0,  OPT_timerfd_ops },
  888     { "timerfd-fds",1,  0,  OPT_timerfd_fds },
  889     { "timerfd-freq",1, 0,  OPT_timerfd_freq },
  890     { "timerfd-rand",0, 0,  OPT_timerfd_rand },
  891     { "timer-slack" ,1, 0,  OPT_timer_slack },
  892     { "tlb-shootdown",1,    0,  OPT_tlb_shootdown },
  893     { "tlb-shootdown-ops",1,0,  OPT_tlb_shootdown_ops },
  894     { "tmpfs",  1,  0,  OPT_tmpfs },
  895     { "tmpfs-ops",  1,  0,  OPT_tmpfs_ops },
  896     { "tmpfs-mmap-async",0, 0,  OPT_tmpfs_mmap_async },
  897     { "tmpfs-mmap-file",0,  0,  OPT_tmpfs_mmap_file },
  898     { "tree",   1,  0,  OPT_tree },
  899     { "tree-ops",   1,  0,  OPT_tree_ops },
  900     { "tree-method",1,  0,  OPT_tree_method },
  901     { "tree-size",  1,  0,  OPT_tree_size },
  902     { "tsc",    1,  0,  OPT_tsc },
  903     { "tsc-ops",    1,  0,  OPT_tsc_ops },
  904     { "tsearch",    1,  0,  OPT_tsearch },
  905     { "tsearch-ops",1,  0,  OPT_tsearch_ops },
  906     { "tsearch-size",1, 0,  OPT_tsearch_size },
  907     { "thermalstat",1,  0,  OPT_thermalstat },
  908     { "thrash", 0,  0,  OPT_thrash },
  909     { "times",  0,  0,  OPT_times },
  910     { "timestamp",  0,  0,  OPT_timestamp },
  911     { "tz",     0,  0,  OPT_thermal_zones },
  912     { "tun",    1,  0,  OPT_tun},
  913     { "tun-ops",    1,  0,  OPT_tun_ops },
  914     { "tun-tap",    0,  0,  OPT_tun_tap },
  915     { "udp",    1,  0,  OPT_udp },
  916     { "udp-ops",    1,  0,  OPT_udp_ops },
  917     { "udp-domain",1,   0,  OPT_udp_domain },
  918     { "udp-lite",   0,  0,  OPT_udp_lite },
  919     { "udp-port",   1,  0,  OPT_udp_port },
  920     { "udp-flood",  1,  0,  OPT_udp_flood },
  921     { "udp-flood-domain",1, 0,  OPT_udp_flood_domain },
  922     { "udp-flood-ops",1,    0,  OPT_udp_flood_ops },
  923     { "unshare",    1,  0,  OPT_unshare },
  924     { "unshare-ops",1,  0,  OPT_unshare_ops },
  925     { "uprobe", 1,  0,  OPT_uprobe },
  926     { "uprobe-ops", 1,  0,  OPT_uprobe_ops },
  927     { "urandom",    1,  0,  OPT_urandom },
  928     { "urandom-ops",1,  0,  OPT_urandom_ops },
  929     { "userfaultfd",1,  0,  OPT_userfaultfd },
  930     { "userfaultfd-ops",1,  0,  OPT_userfaultfd_ops },
  931     { "userfaultfd-bytes",1,0,  OPT_userfaultfd_bytes },
  932     { "utime",  1,  0,  OPT_utime },
  933     { "utime-ops",  1,  0,  OPT_utime_ops },
  934     { "utime-fsync",0,  0,  OPT_utime_fsync },
  935     { "vdso",   1,  0,  OPT_vdso },
  936     { "vdso-ops",   1,  0,  OPT_vdso_ops },
  937     { "vdso-func",  1,  0,  OPT_vdso_func },
  938     { "vecmath",    1,  0,  OPT_vecmath },
  939     { "vecmath-ops",1,  0,  OPT_vecmath_ops },
  940     { "verbose",    0,  0,  OPT_verbose },
  941     { "verify", 0,  0,  OPT_verify },
  942     { "verity", 1,  0,  OPT_verity },
  943     { "verity-ops", 1,  0,  OPT_verity_ops },
  944     { "version",    0,  0,  OPT_version },
  945     { "vfork",  1,  0,  OPT_vfork },
  946     { "vfork-ops",  1,  0,  OPT_vfork_ops },
  947     { "vfork-max",  1,  0,  OPT_vfork_max },
  948     { "vfork-vm",   0,  0,  OPT_vfork_vm },
  949     { "vforkmany",  1,  0,  OPT_vforkmany },
  950     { "vforkmany-ops", 1,   0,  OPT_vforkmany_ops },
  951     { "vforkmany-vm", 0,    0,  OPT_vforkmany_vm },
  952     { "vm",     1,  0,  OPT_vm },
  953     { "vm-bytes",   1,  0,  OPT_vm_bytes },
  954     { "vm-hang",    1,  0,  OPT_vm_hang },
  955     { "vm-keep",    0,  0,  OPT_vm_keep },
  956 #if defined(MAP_POPULATE)
  957     { "vm-populate",0,  0,  OPT_vm_mmap_populate },
  958 #endif
  959 #if defined(MAP_LOCKED)
  960     { "vm-locked",  0,  0,  OPT_vm_mmap_locked },
  961 #endif
  962     { "vm-ops", 1,  0,  OPT_vm_ops },
  963     { "vm-madvise", 1,  0,  OPT_vm_madvise },
  964     { "vm-method",  1,  0,  OPT_vm_method },
  965     { "vm-addr",    1,  0,  OPT_vm_addr },
  966     { "vm-addr-ops",1,  0,  OPT_vm_addr_ops },
  967     { "vm-addr-method",1,   0,  OPT_vm_addr_method },
  968     { "vm-rw",  1,  0,  OPT_vm_rw },
  969     { "vm-rw-bytes",1,  0,  OPT_vm_rw_bytes },
  970     { "vm-rw-ops",  1,  0,  OPT_vm_rw_ops },
  971     { "vm-segv",    1,  0,  OPT_vm_segv },
  972     { "vm-segv-ops",1,  0,  OPT_vm_segv_ops },
  973     { "vm-splice",  1,  0,  OPT_vm_splice },
  974     { "vm-splice-bytes",1,  0,  OPT_vm_splice_bytes },
  975     { "vm-splice-ops",1,    0,  OPT_vm_splice_ops },
  976     { "vmstat", 1,  0,  OPT_vmstat },
  977     { "wait",   1,  0,  OPT_wait },
  978     { "wait-ops",   1,  0,  OPT_wait_ops },
  979     { "watchdog",   1,  0,  OPT_watchdog },
  980     { "watchdog-ops",1, 0,  OPT_watchdog_ops },
  981     { "wcs",    1,  0,  OPT_wcs},
  982     { "wcs-ops",    1,  0,  OPT_wcs_ops },
  983     { "wcs-method", 1,  0,  OPT_wcs_method },
  984     { "x86syscall", 1,  0,  OPT_x86syscall },
  985     { "x86syscall-ops",1,   0,  OPT_x86syscall_ops },
  986     { "x86syscall-func",1,  0,  OPT_x86syscall_func },
  987     { "xattr",  1,  0,  OPT_xattr },
  988     { "xattr-ops",  1,  0,  OPT_xattr_ops },
  989     { "yaml",   1,  0,  OPT_yaml },
  990     { "yield",  1,  0,  OPT_yield },
  991     { "yield-ops",  1,  0,  OPT_yield_ops },
  992     { "zero",   1,  0,  OPT_zero },
  993     { "zero-ops",   1,  0,  OPT_zero_ops },
  994     { "zlib",   1,  0,  OPT_zlib },
  995     { "zlib-ops",   1,  0,  OPT_zlib_ops },
  996     { "zlib-method",1,  0,  OPT_zlib_method },
  997     { "zlib-level", 1,  0,  OPT_zlib_level },
  998     { "zlib-mem-level", 1,  0,  OPT_zlib_mem_level },
  999     { "zlib-window-bits",   1,  0,  OPT_zlib_window_bits },
 1000     { "zlib-stream-bytes",  1,  0,  OPT_zlib_stream_bytes, },
 1001     { "zlib-strategy",  1,  0,  OPT_zlib_strategy, },
 1002     { "zombie", 1,  0,  OPT_zombie },
 1003     { "zombie-ops", 1,  0,  OPT_zombie_ops },
 1004     { "zombie-max", 1,  0,  OPT_zombie_max },
 1005     { NULL,     0,  0,  0 }
 1006 };
 1007 
 1008 /*
 1009  *  Generic help options
 1010  */
 1011 static const stress_help_t help_generic[] = {
 1012     { NULL,     "abort",        "abort all stressors if any stressor fails" },
 1013     { NULL,     "aggressive",       "enable all aggressive options" },
 1014     { "a N",    "all N",        "start N workers of each stress test" },
 1015     { "b N",    "backoff N",        "wait of N microseconds before work starts" },
 1016     { NULL,     "class name",       "specify a class of stressors, use with --sequential" },
 1017     { "n",      "dry-run",      "do not run" },
 1018     { NULL,     "ftrace",       "enable kernel function call tracing" },
 1019     { "h",      "help",         "show help" },
 1020     { NULL,     "ignite-cpu",       "alter kernel controls to make CPU run hot" },
 1021     { NULL,     "ionice-class C",   "specify ionice class (idle, besteffort, realtime)" },
 1022     { NULL,     "ionice-level L",   "specify ionice level (0 max, 7 min)" },
 1023     { "j",      "job jobfile",      "run the named jobfile" },
 1024     { "k",      "keep-name",        "keep stress worker names to be 'stress-ng'" },
 1025     { NULL,     "log-brief",        "less verbose log messages" },
 1026     { NULL,     "log-file filename",    "log messages to a log file" },
 1027     { NULL,     "maximize",     "enable maximum stress options" },
 1028     { NULL,     "max-fd",       "set maximum file descriptor limit" },
 1029     { "M",      "metrics",      "print pseudo metrics of activity" },
 1030     { NULL,     "metrics-brief",    "enable metrics and only show non-zero results" },
 1031     { NULL,     "minimize",     "enable minimal stress options" },
 1032     { NULL,     "no-madvise",       "don't use random madvise options for each mmap" },
 1033     { NULL,     "no-rand-seed",     "seed random numbers with the same constant" },
 1034     { NULL,     "oomable",      "Do not respawn a stressor if it gets OOM'd" },
 1035     { NULL,     "page-in",      "touch allocated pages that are not in core" },
 1036     { NULL,     "parallel N",       "synonym for 'all N'" },
 1037     { NULL,     "pathological",     "enable stressors that are known to hang a machine" },
 1038 #if defined(STRESS_PERF_STATS) &&   \
 1039     defined(HAVE_LINUX_PERF_EVENT_H)
 1040     { NULL,     "perf",         "display perf statistics" },
 1041 #endif
 1042     { "q",      "quiet",        "quiet output" },
 1043     { "r",      "random N",     "start N random workers" },
 1044     { NULL,     "sched type",       "set scheduler type" },
 1045     { NULL,     "sched-prio N",     "set scheduler priority level N" },
 1046     { NULL,     "sched-period N",   "set period for SCHED_DEADLINE to N nanosecs (Linux only)" },
 1047     { NULL,     "sched-runtime N",  "set runtime for SCHED_DEADLINE to N nanosecs (Linux only)" },
 1048     { NULL,     "sched-deadline N", "set deadline for SCHED_DEADLINE to N nanosecs (Linux only)" },
 1049     { NULL,     "sched-reclaim",        "set reclaim cpu bandwidth for deadline scheduler (Linux only)" },
 1050     { NULL,     "seed N",       "set the random number generator seed with a 64 bit value" },
 1051     { NULL,     "sequential N",     "run all stressors one by one, invoking N of them" },
 1052     { NULL,     "skip-silent",      "silently skip unimplemented stressors" },
 1053     { NULL,     "stressors",        "show available stress tests" },
 1054     { NULL,     "smarg",        "show changes in S.M.A.R.T. data" },
 1055 #if defined(HAVE_SYSLOG_H)
 1056     { NULL,     "syslog",       "log messages to the syslog" },
 1057 #endif
 1058     { NULL,     "taskset",      "use specific CPUs (set CPU affinity)" },
 1059     { NULL,     "temp-path path",   "specify path for temporary directories and files" },
 1060     { NULL,     "thrash",       "force all pages in causing swap thrashing" },
 1061     { "t N",    "timeout T",        "timeout after T seconds" },
 1062     { NULL,     "timer-slack",      "enable timer slack mode" },
 1063     { NULL,     "times",        "show run time summary at end of the run" },
 1064     { NULL,     "timestamp",        "timestamp log output " },
 1065 #if defined(STRESS_THERMAL_ZONES)
 1066     { NULL,     "tz",           "collect temperatures from thermal zones (Linux only)" },
 1067 #endif
 1068     { "v",      "verbose",      "verbose output" },
 1069     { NULL,     "verify",       "verify results (not available on all tests)" },
 1070     { "V",      "version",      "show version" },
 1071     { "Y",      "yaml file",        "output results to YAML formatted file" },
 1072     { "x",      "exclude",      "list of stressors to exclude (not run)" },
 1073     { NULL,     NULL,           NULL }
 1074 };
 1075 
 1076 /*
 1077  *  stress_hash_checksum()
 1078  *  generate a hash of the checksum data
 1079  */
 1080 static inline void stress_hash_checksum(stress_checksum_t *checksum)
 1081 {
 1082     checksum->hash = stress_hash_jenkin((uint8_t *)&checksum->data,
 1083                 sizeof(checksum->data));
 1084 }
 1085 
 1086 /*
 1087  *  stressor_name_find()
 1088  *      Find index into stressors by name
 1089  */
 1090 static inline int32_t stressor_name_find(const char *name)
 1091 {
 1092     int32_t i;
 1093     const char *tmp = stress_munge_underscore(name);
 1094     size_t len = strlen(tmp) + 1;
 1095     char munged_name[len];
 1096 
 1097     (void)shim_strlcpy(munged_name, tmp, len);
 1098 
 1099     for (i = 0; stressors[i].name; i++) {
 1100         const char *munged_stressor_name =
 1101             stress_munge_underscore(stressors[i].name);
 1102 
 1103         if (!strcmp(munged_stressor_name, munged_name))
 1104             break;
 1105     }
 1106 
 1107     return i;   /* End of array is a special "NULL" entry */
 1108 }
 1109 
 1110 /*
 1111  *  stress_remove_stressor()
 1112  *  remove stressor from stressor list
 1113  */
 1114 static void stress_remove_stressor(stress_stressor_t *ss)
 1115 {
 1116     if (stressors_head == ss) {
 1117         stressors_head = ss->next;
 1118         if (ss->next)
 1119             ss->next->prev = ss->prev;
 1120     } else {
 1121         if (ss->prev)
 1122             ss->prev->next = ss->next;
 1123     }
 1124 
 1125     if (stressors_tail == ss) {
 1126         stressors_tail = ss->prev;
 1127         if (ss->prev)
 1128             ss->prev->next = ss->next;
 1129     } else {
 1130         if (ss->next)
 1131             ss->next->prev = ss->prev;
 1132     }
 1133     free(ss);
 1134 }
 1135 
 1136 /*
 1137  *  stress_get_class_id()
 1138  *  find the class id of a given class name
 1139  */
 1140 static uint32_t stress_get_class_id(char *const str)
 1141 {
 1142     size_t i;
 1143 
 1144     for (i = 0; i < SIZEOF_ARRAY(classes); i++) {
 1145         if (!strcmp(classes[i].name, str))
 1146             return classes[i].class;
 1147     }
 1148     return 0;
 1149 }
 1150 
 1151 /*
 1152  *  stress_get_class()
 1153  *  parse for allowed class types, return bit mask of types, 0 if error
 1154  */
 1155 static int stress_get_class(char *const class_str, uint32_t *class)
 1156 {
 1157     char *str, *token;
 1158     int ret = 0;
 1159 
 1160     *class = 0;
 1161     for (str = class_str; (token = strtok(str, ",")) != NULL; str = NULL) {
 1162         uint32_t cl = stress_get_class_id(token);
 1163 
 1164         if (!cl) {
 1165             size_t i;
 1166             const size_t len = strlen(token);
 1167 
 1168             if ((len > 1) && (token[len - 1] == '?')) {
 1169                 token[len - 1] = '\0';
 1170 
 1171                 cl = stress_get_class_id(token);
 1172                 if (cl) {
 1173                     size_t j;
 1174 
 1175                     (void)printf("class '%s' stressors:",
 1176                         token);
 1177                     for (j = 0; stressors[j].name; j++) {
 1178                         if (stressors[j].info->class & cl)
 1179                             (void)printf(" %s", stress_munge_underscore(stressors[j].name));
 1180                     }
 1181                     (void)printf("\n");
 1182                     return 1;
 1183                 }
 1184             }
 1185             (void)fprintf(stderr, "Unknown class: '%s', "
 1186                 "available classes:", token);
 1187             for (i = 0; i < SIZEOF_ARRAY(classes); i++)
 1188                 (void)fprintf(stderr, " %s", classes[i].name);
 1189             (void)fprintf(stderr, "\n\n");
 1190             return -1;
 1191         }
 1192         *class |= cl;
 1193     }
 1194     return ret;
 1195 }
 1196 
 1197 /*
 1198  *  stress_exclude()
 1199  *      parse -x --exlude exclude list
 1200  */
 1201 static int stress_exclude(void)
 1202 {
 1203     char *str, *token, *opt_exclude;
 1204 
 1205     if (!stress_get_setting("exclude", &opt_exclude))
 1206         return 0;
 1207 
 1208     for (str = opt_exclude; (token = strtok(str, ",")) != NULL; str = NULL) {
 1209         stress_id_t id;
 1210         stress_stressor_t *ss = stressors_head;
 1211         const int32_t i = stressor_name_find(token);
 1212 
 1213         if (!stressors[i].name) {
 1214             (void)fprintf(stderr, "Unknown stressor: '%s', "
 1215                 "invalid exclude option\n", token);
 1216             return -1;
 1217         }
 1218         id = stressors[i].id;
 1219 
 1220         while (ss) {
 1221             stress_stressor_t *next = ss->next;
 1222 
 1223             if (ss->stressor->id == id)
 1224                 stress_remove_stressor(ss);
 1225             ss = next;
 1226         }
 1227     }
 1228     return 0;
 1229 }
 1230 
 1231 /*
 1232  *  stress_sigint_handler()
 1233  *  catch signals and set flag to break out of stress loops
 1234  */
 1235 static void MLOCKED_TEXT stress_sigint_handler(int signum)
 1236 {
 1237     (void)signum;
 1238     g_caught_sigint = true;
 1239     keep_stressing_set_flag(false);
 1240     wait_flag = false;
 1241 
 1242     (void)kill(-getpid(), SIGALRM);
 1243 }
 1244 
 1245 /*
 1246  *  stress_sigalrm_parent_handler()
 1247  *  handle signal in parent process, don't block on waits
 1248  */
 1249 static void MLOCKED_TEXT stress_sigalrm_parent_handler(int signum)
 1250 {
 1251     (void)signum;
 1252     wait_flag = false;
 1253 }
 1254 
 1255 #if defined(SIGUSR2)
 1256 /*
 1257  *  stress_stats_handler()
 1258  *  dump current system stats
 1259  */
 1260 static void MLOCKED_TEXT stress_stats_handler(int signum)
 1261 {
 1262     static char buffer[80];
 1263     char *ptr = buffer;
 1264     int ret;
 1265     double min1, min5, min15;
 1266     size_t shmall, freemem, totalmem, freeswap;
 1267 
 1268     (void)signum;
 1269 
 1270     *ptr = '\0';
 1271 
 1272     if (stress_get_load_avg(&min1, &min5, &min15) == 0) {
 1273         ret = snprintf(ptr, sizeof(buffer),
 1274             "Load Avg: %.2f %.2f %.2f, ",
 1275             min1, min5, min15);
 1276         if (ret > 0)
 1277             ptr += ret;
 1278     }
 1279     stress_get_memlimits(&shmall, &freemem, &totalmem, &freeswap);
 1280 
 1281     (void)snprintf(ptr, (size_t)(buffer - ptr),
 1282         "MemFree: %zu MB, MemTotal: %zu MB",
 1283         freemem / (size_t)MB, totalmem / (size_t)MB);
 1284     /* Really shouldn't do this in a signal handler */
 1285     (void)fprintf(stdout, "%s\n", buffer);
 1286     (void)fflush(stdout);
 1287 }
 1288 #endif
 1289 
 1290 /*
 1291  *  stress_set_handler()
 1292  *  set signal handler to catch SIGINT, SIGALRM, SIGHUP
 1293  */
 1294 static int stress_set_handler(const char *stress, const bool child)
 1295 {
 1296     if (stress_sighandler(stress, SIGINT, stress_sigint_handler, NULL) < 0)
 1297         return -1;
 1298     if (stress_sighandler(stress, SIGHUP, stress_sigint_handler, NULL) < 0)
 1299         return -1;
 1300 #if defined(SIGUSR2)
 1301     if (!child) {
 1302         if (stress_sighandler(stress, SIGUSR2,
 1303             stress_stats_handler, NULL) < 0) {
 1304             return -1;
 1305         }
 1306     }
 1307 #endif
 1308     if (stress_sighandler(stress, SIGALRM,
 1309         child ? stress_handle_stop_stressing :
 1310             stress_sigalrm_parent_handler, NULL) < 0)
 1311         return -1;
 1312     return 0;
 1313 }
 1314 
 1315 /*
 1316  *  stress_version()
 1317  *  print program version info
 1318  */
 1319 static void stress_version(void)
 1320 {
 1321     (void)printf("%s, version " VERSION " (%s, %s)%s\n",
 1322         g_app_name, stress_get_compiler(), stress_get_uname_info(),
 1323         stress_is_dev_tty(STDOUT_FILENO) ? "" : " \U0001F4BB\U0001F525");
 1324 }
 1325 
 1326 /*
 1327  *  stress_usage_help()
 1328  *  show generic help information
 1329  */
 1330 static void stress_usage_help(const stress_help_t help_info[])
 1331 {
 1332     size_t i;
 1333     const int cols = stress_tty_width();
 1334 
 1335     for (i = 0; help_info[i].description; i++) {
 1336         char opt_s[10] = "";
 1337         int wd = 0;
 1338         bool first = true;
 1339         const char *ptr, *space = NULL;
 1340         const char *start = help_info[i].description;
 1341 
 1342         if (help_info[i].opt_s)
 1343             (void)snprintf(opt_s, sizeof(opt_s), "-%s,",
 1344                     help_info[i].opt_s);
 1345         (void)printf("%-6s--%-20s", opt_s,
 1346             help_info[i].opt_l);
 1347 
 1348         for (ptr = start; *ptr; ptr++) {
 1349             if (*ptr == ' ')
 1350                 space = ptr;
 1351             wd++;
 1352             if (wd >= cols - 28) {
 1353                 const int n = space - start;
 1354 
 1355                 if (!first)
 1356                     (void)printf("%-28s", "");
 1357                 first = false;
 1358                 (void)printf("%*.*s\n", n, n,start);
 1359                 start = space + 1;
 1360                 wd = 0;
 1361             }
 1362         }
 1363         if (start != ptr) {
 1364             const int n = ptr - start;
 1365             if (!first)
 1366                 (void)printf("%-28s", "");
 1367             (void)printf("%*.*s\n", n, n, start);
 1368         }
 1369     }
 1370 }
 1371 
 1372 /*
 1373  *  stress_usage_help_stressors()
 1374  *  show per stressor help information
 1375  */
 1376 static void stress_usage_help_stressors(void)
 1377 {
 1378     size_t i;
 1379 
 1380     for (i = 0; stressors[i].id != STRESS_MAX; i++) {
 1381         if (stressors[i].info->help)
 1382             stress_usage_help(stressors[i].info->help);
 1383     }
 1384 }
 1385 
 1386 /*
 1387  *  stress_show_stressor_names()
 1388  *  show stressor names
 1389  */
 1390 static inline void stress_show_stressor_names(void)
 1391 {
 1392     size_t i;
 1393 
 1394     for (i = 0; stressors[i].name; i++)
 1395         (void)printf("%s%s", i ? " " : "",
 1396             stress_munge_underscore(stressors[i].name));
 1397     (void)putchar('\n');
 1398 }
 1399 
 1400 /*
 1401  *  stress_usage()
 1402  *  print some help
 1403  */
 1404 static void NORETURN stress_usage(void)
 1405 {
 1406     stress_version();
 1407     (void)printf("\nUsage: %s [OPTION [ARG]]\n", g_app_name);
 1408     (void)printf("\nGeneral control options:\n");
 1409     stress_usage_help(help_generic);
 1410     (void)printf("\nStressor specific options:\n");
 1411     stress_usage_help_stressors();
 1412     (void)printf("\nExample: %s --cpu 8 --io 4 --vm 2 --vm-bytes 128M "
 1413         "--fork 4 --timeout 10s\n\n"
 1414         "Note: Sizes can be suffixed with B,K,M,G and times with "
 1415         "s,m,h,d,y\n", g_app_name);
 1416     stress_settings_free();
 1417     stress_temp_path_free();
 1418     exit(EXIT_SUCCESS);
 1419 }
 1420 
 1421 /*
 1422  *  stress_opt_name()
 1423  *  find name associated with an option value
 1424  */
 1425 static const char *stress_opt_name(const int opt_val)
 1426 {
 1427     size_t i;
 1428 
 1429     for (i = 0; long_options[i].name; i++)
 1430         if (long_options[i].val == opt_val)
 1431             return long_options[i].name;
 1432 
 1433     return "<unknown>";
 1434 }
 1435 
 1436 /*
 1437  *  stress_get_processors()
 1438  *  get number of processors, set count if <=0 as:
 1439  *      count = 0 -> number of CPUs in system
 1440  *      count < 0 -> number of CPUs online
 1441  */
 1442 static void stress_get_processors(int32_t *count)
 1443 {
 1444     if (*count == 0)
 1445         *count = stress_get_processors_configured();
 1446     else if (*count < 0)
 1447         *count = stress_get_processors_online();
 1448 }
 1449 
 1450 /*
 1451  *  stress_stressor_finished()
 1452  *  mark a stressor process as complete
 1453  */
 1454 static inline void stress_stressor_finished(pid_t *pid)
 1455 {
 1456     *pid = 0;
 1457 }
 1458 
 1459 /*
 1460  *  stress_kill_stressors()
 1461  *  kill stressor tasks using signal sig
 1462  */
 1463 static void stress_kill_stressors(const int sig)
 1464 {
 1465     static int count = 0;
 1466     int signum = sig;
 1467     stress_stressor_t *ss;
 1468 
 1469     /* multiple calls will always fallback to SIGKILL */
 1470     count++;
 1471     if (count > 5) {
 1472         pr_dbg("killing process group %d with SIGKILL\n", (int)g_pgrp);
 1473         signum = SIGKILL;
 1474     }
 1475 
 1476     (void)killpg(g_pgrp, sig);
 1477 
 1478     for (ss = stressors_head; ss; ss = ss->next) {
 1479         int32_t i;
 1480 
 1481         for (i = 0; i < ss->started_instances; i++) {
 1482             if (ss->pids[i])
 1483                 (void)kill(ss->pids[i], signum);
 1484         }
 1485     }
 1486 }
 1487 
 1488 /*
 1489  *  stress_exit_status_to_string()
 1490  *  map stress-ng exit status returns into text
 1491  */
 1492 static char *stress_exit_status_to_string(const int status)
 1493 {
 1494     switch (status) {
 1495     case EXIT_SUCCESS:
 1496         return "success";
 1497     case EXIT_FAILURE:
 1498         return "stress-ng core failure";
 1499     case EXIT_NOT_SUCCESS:
 1500         return "stressor failed";
 1501     case EXIT_NO_RESOURCE:
 1502         return "no resource(s)";
 1503     case EXIT_NOT_IMPLEMENTED:
 1504         return "not implemented";
 1505     case EXIT_SIGNALED:
 1506         return "killed by signal";
 1507     case EXIT_BY_SYS_EXIT:
 1508         return "stressor terminated using _exit()";
 1509     case EXIT_METRICS_UNTRUSTWORTHY:
 1510         return "metrics may be untrustyworthy";
 1511     default:
 1512         return "unknown";
 1513     }
 1514 }
 1515 
 1516 /*
 1517  *  Filter out dot files . and ..
 1518  */
 1519 static int stress_dot_filter(const struct dirent *d)
 1520 {
 1521     if (d->d_name[0] == '.') {
 1522         if (d->d_name[1] == '\0')
 1523             return 0;
 1524         if ((d->d_name[1] == '.') && (d->d_name[2] == '\0'))
 1525             return 0;
 1526     }
 1527     return 1;
 1528 }
 1529 
 1530 /*
 1531  *  stress_clean_dir_files()
 1532  *      recursively delete files in directories
 1533  */
 1534 static void stress_clean_dir_files(
 1535     const char *temp_path,
 1536     const size_t temp_path_len,
 1537     char *path,
 1538     const size_t path_posn)
 1539 {
 1540     struct stat statbuf;
 1541     char *ptr = path + path_posn;
 1542     char *end = path + PATH_MAX;
 1543     int n;
 1544     struct dirent **names = NULL;
 1545 
 1546     if (stat(path, &statbuf) < 0) {
 1547         pr_inf("STAT FAIL: %s %d %s\n", path, errno, strerror(errno));
 1548         return;
 1549     }
 1550 
 1551     /* We don't follow symlinks */
 1552     if (S_ISLNK(statbuf.st_mode))
 1553         return;
 1554 
 1555     /* We don't remove paths with .. in */
 1556     if (strstr(path, ".."))
 1557         return;
 1558 
 1559     /* We don't remove paths that our out of the scope */
 1560     if (strncmp(path, temp_path, temp_path_len))
 1561         return;
 1562 
 1563     n = scandir(path, &names, stress_dot_filter, alphasort);
 1564     if (n < 0) {
 1565         (void)rmdir(path);
 1566         return;
 1567     }
 1568 
 1569     while (n--) {
 1570         size_t name_len = strlen(names[n]->d_name) + 1;
 1571 #if !defined(DT_DIR) || \
 1572     !defined(DT_LNK) || \
 1573     !defined(DT_REG)
 1574         int ret;
 1575 #endif
 1576 
 1577         /* No more space */
 1578         if (ptr + name_len > end) {
 1579             free(names[n]);
 1580             continue;
 1581         }
 1582 
 1583         snprintf(ptr, (size_t)(end - ptr), "/%s", names[n]->d_name);
 1584         name_len = strlen(ptr);
 1585         free(names[n]);
 1586 
 1587 #if defined(DT_DIR) &&  \
 1588     defined(DT_LNK) &&  \
 1589     defined(DT_REG)
 1590         /* Modern fast d_type method */
 1591         switch (names[n]->d_type) {
 1592         case DT_DIR:
 1593             stress_clean_dir_files(temp_path, temp_path_len, path, path_posn + name_len);
 1594             (void)rmdir(path);
 1595             break;
 1596         case DT_LNK:
 1597         case DT_REG:
 1598             (void)unlink(path);
 1599             break;
 1600         default:
 1601             break;
 1602         }
 1603 #else
 1604         /* Slower stat method */
 1605         ret = stat(path, &statbuf);
 1606         if (ret < 0)
 1607             continue;
 1608 
 1609         if ((statbuf.st_mode & S_IFMT) == S_IFDIR) {
 1610             stress_clean_dir_files(temp_path, temp_path_len, path, path_posn + name_len);
 1611             (void)rmdir(path);
 1612         } else if (((statbuf.st_mode & S_IFMT) == S_IFLNK) ||
 1613                ((statbuf.st_mode & S_IFMT) == S_IFREG)) {
 1614             (void)unlink(path);
 1615         }
 1616 #endif
 1617     }
 1618     *ptr = '\0';
 1619     free(names);
 1620     (void)rmdir(path);
 1621 }
 1622 
 1623 /*
 1624  *  stress_clean_dir()
 1625  *  perform tidy up of any residual temp files; this
 1626  *  happens if a stressor was terminated before it could
 1627  *  tidy itself up, e.g. OOM'd or KILL'd
 1628  */
 1629 static void stress_clean_dir(
 1630     const char *name,
 1631     const pid_t pid,
 1632     uint32_t instance)
 1633 {
 1634     char path[PATH_MAX];
 1635     const char *temp_path = stress_get_temp_path();
 1636     const size_t temp_path_len = strlen(temp_path);
 1637 
 1638     (void)stress_temp_dir(path, sizeof(path), name, pid, instance);
 1639 
 1640     if (access(path, F_OK) == 0) {
 1641         pr_dbg("%s: removing temporary files in %s\n", name, path);
 1642         stress_clean_dir_files(temp_path, temp_path_len, path, strlen(path));
 1643     }
 1644 }
 1645 
 1646 /*
 1647  *  stress_wait_stressors()
 1648  *  wait for stressor child processes
 1649  */
 1650 static void MLOCKED_TEXT stress_wait_stressors(
 1651     stress_stressor_t *stressors_list,
 1652     bool *success,
 1653     bool *resource_success,
 1654     bool *metrics_success)
 1655 {
 1656     stress_stressor_t *ss;
 1657 
 1658     if (g_opt_flags & OPT_FLAGS_IGNITE_CPU)
 1659         stress_ignite_cpu_start();
 1660 
 1661 #if defined(HAVE_SCHED_GETAFFINITY) &&  \
 1662     NEED_GLIBC(2,3,0)
 1663     /*
 1664      *  On systems that support changing CPU affinity
 1665      *  we keep on moving processes between processors
 1666      *  to impact on memory locality (e.g. NUMA) to
 1667      *  try to thrash the system when in aggressive mode
 1668      */
 1669     if (g_opt_flags & OPT_FLAGS_AGGRESSIVE) {
 1670         cpu_set_t proc_mask;
 1671         unsigned long int cpu = 0;
 1672         const int32_t ticks_per_sec =
 1673             stress_get_ticks_per_second() * 5;
 1674         const useconds_t usec_sleep =
 1675             ticks_per_sec ? 1000000 / (useconds_t)ticks_per_sec : 1000000 / 250;
 1676 
 1677         while (wait_flag) {
 1678             const int32_t cpus = stress_get_processors_configured();
 1679             bool procs_alive = false;
 1680 
 1681             /*
 1682              *  If we can't get the mask, then don't do
 1683              *  any affinity twiddling
 1684              */
 1685             if (sched_getaffinity(0, sizeof(proc_mask), &proc_mask) < 0)
 1686                 goto do_wait;
 1687             if (!CPU_COUNT(&proc_mask)) /* Highly unlikely */
 1688                 goto do_wait;
 1689 
 1690             (void)shim_usleep(usec_sleep);
 1691 
 1692             for (ss = stressors_list; ss; ss = ss->next) {
 1693                 int32_t j;
 1694 
 1695                 for (j = 0; j < ss->started_instances; j++) {
 1696                     const pid_t pid = ss->pids[j];
 1697 
 1698                     if (pid) {
 1699                         cpu_set_t mask;
 1700                         int32_t cpu_num;
 1701                         int status, ret;
 1702 
 1703                         ret = waitpid(pid, &status, WNOHANG);
 1704                         if ((ret < 0) && (errno == ESRCH))
 1705                             continue;
 1706                         procs_alive = true;
 1707 
 1708                         do {
 1709                             cpu_num = (int32_t)stress_mwc32() % cpus;
 1710                         } while (!(CPU_ISSET(cpu_num, &proc_mask)));
 1711 
 1712                         CPU_ZERO(&mask);
 1713                         CPU_SET(cpu_num, &mask);
 1714                         if (sched_setaffinity(pid, sizeof(mask), &mask) < 0)
 1715                             goto do_wait;
 1716                     }
 1717                 }
 1718             }
 1719             if (!procs_alive)
 1720                 break;
 1721             cpu++;
 1722         }
 1723     }
 1724 do_wait:
 1725 #endif
 1726     for (ss = stressors_list; ss; ss = ss->next) {
 1727         int32_t j;
 1728 
 1729         for (j = 0; j < ss->started_instances; j++) {
 1730             pid_t pid;
 1731 redo:
 1732             pid = ss->pids[j];
 1733             if (pid) {
 1734                 int status, ret;
 1735                 bool do_abort = false;
 1736                 const char *stressor_name = stress_munge_underscore(ss->stressor->name);
 1737                 char name[64];
 1738 
 1739                 (void)snprintf(name, sizeof(name), "%s-%s", g_app_name,
 1740                                         stress_munge_underscore(stressor_name));
 1741 
 1742                 ret = shim_waitpid(pid, &status, 0);
 1743                 if (ret > 0) {
 1744                     int wexit_status = WEXITSTATUS(status);
 1745 
 1746                     if (WIFSIGNALED(status)) {
 1747 #if defined(WTERMSIG)
 1748 #if NEED_GLIBC(2,1,0)
 1749                         const char *signame = strsignal(WTERMSIG(status));
 1750 
 1751                         pr_dbg("process [%d] (stress-ng-%s) terminated on signal: %d (%s)\n",
 1752                             ret, stressor_name,
 1753                             WTERMSIG(status), signame);
 1754 #else
 1755                         pr_dbg("process [%d] (stress-ng-%s) terminated on signal: %d\n",
 1756                             ret, stressor_name,
 1757                             WTERMSIG(status));
 1758 #endif
 1759 #else
 1760                         pr_dbg("process [%d] (stress-ng-%s) terminated on signal\n",
 1761                             ret, stressor_name);
 1762 #endif
 1763                         /*
 1764                          *  If the stressor got killed by OOM or SIGKILL
 1765                          *  then somebody outside of our control nuked it
 1766                          *  so don't necessarily flag that up as a direct
 1767                          *  failure.
 1768                          */
 1769                         if (stress_process_oomed(ret)) {
 1770                             pr_dbg("process [%d] (stress-ng-%s) was killed by the OOM killer\n",
 1771                                 ret, stressor_name);
 1772                         } else if (WTERMSIG(status) == SIGKILL) {
 1773                             pr_dbg("process [%d] (stress-ng-%s) was possibly killed by the OOM killer\n",
 1774                                 ret, stressor_name);
 1775                         } else {
 1776                             *success = false;
 1777                         }
 1778                     }
 1779                     switch (wexit_status) {
 1780                     case EXIT_SUCCESS:
 1781                         break;
 1782                     case EXIT_NO_RESOURCE:
 1783                         pr_err_skip("process [%d] (stress-ng-%s) aborted early, out of system resources\n",
 1784                             ret, stressor_name);
 1785                         *resource_success = false;
 1786                         do_abort = true;
 1787                         break;
 1788                     case EXIT_NOT_IMPLEMENTED:
 1789                         do_abort = true;
 1790                         break;
 1791                     case EXIT_BY_SYS_EXIT:
 1792                         pr_dbg("process [%d] (stress-ng-%s) aborted via exit() which was not expected\n",
 1793                             ret, stressor_name);
 1794                         do_abort = true;
 1795                         break;
 1796                     case EXIT_METRICS_UNTRUSTWORTHY:
 1797                         *metrics_success = false;
 1798                         break;
 1799                     case EXIT_FAILURE:
 1800                         /*
 1801                          *  Stressors should really return EXIT_NOT_SUCCESS
 1802                          *  as EXIT_FAILURE should indicate a core stress-ng
 1803                          *  problem.
 1804                          */
 1805                         wexit_status = EXIT_NOT_SUCCESS;
 1806                         CASE_FALLTHROUGH;
 1807                     default:
 1808                         pr_err("process %d (stress-ng-%s) terminated with an error, exit status=%d (%s)\n",
 1809                             ret, stressor_name, wexit_status,
 1810                             stress_exit_status_to_string(wexit_status));
 1811                         *success = false;
 1812                         do_abort = true;
 1813                         break;
 1814                     }
 1815                     if ((g_opt_flags & OPT_FLAGS_ABORT) && do_abort) {
 1816                         keep_stressing_set_flag(false);
 1817                         wait_flag = false;
 1818                         stress_kill_stressors(SIGALRM);
 1819                     }
 1820 
 1821                     stress_stressor_finished(&ss->pids[j]);
 1822                     pr_dbg("process [%d] terminated\n", ret);
 1823 
 1824                     stress_clean_dir(name, pid, (uint32_t)j);
 1825 
 1826                 } else if (ret == -1) {
 1827                     /* Somebody interrupted the wait */
 1828                     if (errno == EINTR)
 1829                         goto redo;
 1830                     /* This child did not exist, mark it done anyhow */
 1831                     if (errno == ECHILD)
 1832                         stress_stressor_finished(&ss->pids[j]);
 1833                 }
 1834             }
 1835         }
 1836     }
 1837     if (g_opt_flags & OPT_FLAGS_IGNITE_CPU)
 1838         stress_ignite_cpu_stop();
 1839 }
 1840 
 1841 /*
 1842  *  stress_handle_terminate()
 1843  *  catch terminating signals
 1844  */
 1845 static void MLOCKED_TEXT stress_handle_terminate(int signum)
 1846 {
 1847     terminate_signum = signum;
 1848     keep_stressing_set_flag(false);
 1849     stress_kill_stressors(SIGALRM);
 1850 
 1851     switch (signum) {
 1852     case SIGILL:
 1853     case SIGSEGV:
 1854     case SIGFPE:
 1855     case SIGBUS:
 1856         (void)fprintf(stderr, "%s: info:  [%d] terminated with unexpected signal %s\n",
 1857             g_app_name, (int)getpid(), stress_strsignal(signum));
 1858         (void)fflush(stderr);
 1859         _exit(EXIT_SIGNALED);
 1860     default:
 1861         break;
 1862     }
 1863 }
 1864 
 1865 /*
 1866  *  stress_get_nth_stressor()
 1867  *  return nth stressor from list
 1868  */
 1869 static stress_stressor_t *stress_get_nth_stressor(const uint32_t n)
 1870 {
 1871     stress_stressor_t *ss = stressors_head;
 1872     uint32_t i;
 1873 
 1874     for (i = 0; ss && (i < n); i++)
 1875         ss = ss->next;
 1876 
 1877     return ss;
 1878 }
 1879 
 1880 /*
 1881  *  stress_get_num_stressors()
 1882  *  return number of stressors in stressor list
 1883  */
 1884 static uint32_t stress_get_num_stressors(void)
 1885 {
 1886     uint32_t n = 0;
 1887     stress_stressor_t *ss;
 1888 
 1889     for (ss = stressors_head; ss; ss = ss->next)
 1890         n++;
 1891 
 1892     return n;
 1893 }
 1894 
 1895 /*
 1896  *  stress_stressors_free()
 1897  *  free stressor info from stressor list
 1898  */
 1899 static void stress_stressors_free(void)
 1900 {
 1901     stress_stressor_t *ss = stressors_head;
 1902 
 1903     while (ss) {
 1904         stress_stressor_t *next = ss->next;
 1905 
 1906         free(ss->pids);
 1907         free(ss->stats);
 1908         free(ss);
 1909 
 1910         ss = next;
 1911     }
 1912 
 1913     stressors_head = NULL;
 1914     stressors_tail = NULL;
 1915 }
 1916 
 1917 /*
 1918  *  stress_get_total_num_instances()
 1919  *  deterimine number of runnable stressors from list
 1920  */
 1921 static int32_t stress_get_total_num_instances(stress_stressor_t *stressors_list)
 1922 {
 1923     int32_t total_num_instances = 0;
 1924     stress_stressor_t *ss;
 1925 
 1926     for (ss = stressors_list; ss; ss = ss->next)
 1927         total_num_instances += ss->num_instances;
 1928 
 1929     return total_num_instances;
 1930 }
 1931 
 1932 /*
 1933  *  stress_child_atexit(void)
 1934  *  handle unexpected exit() call in child stressor
 1935  */
 1936 static void NORETURN stress_child_atexit(void)
 1937 {
 1938     _exit(EXIT_BY_SYS_EXIT);
 1939 }
 1940 
 1941 void stress_misc_stats_set(
 1942     stress_misc_stats_t *misc_stats,
 1943     const int idx,
 1944     const char *description,
 1945     const double value)
 1946 {
 1947     if ((idx < 0) || (idx >= STRESS_MISC_STATS_MAX))
 1948         return;
 1949 
 1950     (void)shim_strlcpy(misc_stats[idx].description, description,
 1951             sizeof(misc_stats[idx].description));
 1952     misc_stats[idx].value = value;
 1953 }
 1954 
 1955 /*
 1956  *  stress_run ()
 1957  *  kick off and run stressors
 1958  */
 1959 static void MLOCKED_TEXT stress_run(
 1960     stress_stressor_t *stressors_list,
 1961     double *duration,
 1962     bool *success,
 1963     bool *resource_success,
 1964     bool *metrics_success,
 1965     stress_checksum_t **checksum)
 1966 {
 1967     double time_start, time_finish;
 1968     int32_t started_instances = 0;
 1969 
 1970     wait_flag = true;
 1971     time_start = stress_time_now();
 1972     pr_dbg("starting stressors\n");
 1973 
 1974     /*
 1975      *  Work through the list of stressors to run
 1976      */
 1977     for (g_stressor_current = stressors_list; g_stressor_current; g_stressor_current = g_stressor_current->next) {
 1978         int32_t j;
 1979 
 1980         /*
 1981          *  Each stressor has 1 or more instances to run
 1982          */
 1983         for (j = 0; j < g_stressor_current->num_instances; j++, (*checksum)++) {
 1984             int rc = EXIT_SUCCESS;
 1985             size_t i;
 1986             pid_t pid;
 1987             char name[64];
 1988             int64_t backoff = DEFAULT_BACKOFF;
 1989             int32_t ionice_class = UNDEFINED;
 1990             int32_t ionice_level = UNDEFINED;
 1991             stress_stats_t *stats = g_stressor_current->stats[j];
 1992 
 1993             if (g_opt_timeout && (stress_time_now() - time_start > (double)g_opt_timeout))
 1994                 goto abort;
 1995 
 1996             (void)stress_get_setting("backoff", &backoff);
 1997             (void)stress_get_setting("ionice-class", &ionice_class);
 1998             (void)stress_get_setting("ionice-level", &ionice_level);
 1999 
 2000             stats->counter_ready = true;
 2001             stats->counter = 0;
 2002             stats->checksum = *checksum;
 2003             for (i = 0; i < SIZEOF_ARRAY(stats->misc_stats); i++) {
 2004                 stress_misc_stats_set(stats->misc_stats, i, "", -1);
 2005             }
 2006 again:
 2007             if (!keep_stressing_flag())
 2008                 break;
 2009             pid = fork();
 2010             switch (pid) {
 2011             case -1:
 2012                 if (errno == EAGAIN) {
 2013                     (void)shim_usleep(100000);
 2014                     goto again;
 2015                 }
 2016                 pr_err("Cannot fork: errno=%d (%s)\n",
 2017                     errno, strerror(errno));
 2018                 stress_kill_stressors(SIGALRM);
 2019                 goto wait_for_stressors;
 2020             case 0:
 2021                 /* Child */
 2022                 (void)snprintf(name, sizeof(name), "%s-%s", g_app_name,
 2023                     stress_munge_underscore(g_stressor_current->stressor->name));
 2024                 stress_set_proc_state(name, STRESS_STATE_START);
 2025 
 2026                 (void)sched_settings_apply(true);
 2027                 (void)atexit(stress_child_atexit);
 2028                 (void)setpgid(0, g_pgrp);
 2029                 if (stress_set_handler(name, true) < 0) {
 2030                     rc = EXIT_FAILURE;
 2031                     goto child_exit;
 2032                 }
 2033                 stress_parent_died_alarm();
 2034                 stress_process_dumpable(false);
 2035                 stress_set_timer_slack();
 2036 
 2037                 if (g_opt_timeout)
 2038                     (void)alarm((unsigned int)g_opt_timeout);
 2039 
 2040                 stress_set_proc_state(name, STRESS_STATE_INIT);
 2041                 stress_mwc_reseed();
 2042                 stress_set_oom_adjustment(name, false);
 2043                 stress_set_max_limits();
 2044                 stress_set_iopriority(ionice_class, ionice_level);
 2045                 //stress_set_proc_name(name);
 2046                 (void)umask(0077);
 2047 
 2048                 pr_dbg("%s: started [%d] (instance %" PRIu32 ")\n",
 2049                     name, (int)getpid(), j);
 2050 
 2051                 stats->start = stats->finish = stress_time_now();
 2052 #if defined(STRESS_PERF_STATS) &&   \
 2053     defined(HAVE_LINUX_PERF_EVENT_H)
 2054                 if (g_opt_flags & OPT_FLAGS_PERF_STATS)
 2055                     (void)stress_perf_open(&stats->sp);
 2056 #endif
 2057                 (void)shim_usleep((useconds_t)(backoff * started_instances));
 2058 #if defined(STRESS_PERF_STATS) &&   \
 2059     defined(HAVE_LINUX_PERF_EVENT_H)
 2060                 if (g_opt_flags & OPT_FLAGS_PERF_STATS)
 2061                     (void)stress_perf_enable(&stats->sp);
 2062 #endif
 2063                 if (keep_stressing_flag() && !(g_opt_flags & OPT_FLAGS_DRY_RUN)) {
 2064                     const stress_args_t args = {
 2065                         .counter = &stats->counter,
 2066                         .counter_ready = &stats->counter_ready,
 2067                         .name = name,
 2068                         .max_ops = g_stressor_current->bogo_ops,
 2069                         .instance = (uint32_t)j,
 2070                         .num_instances = (uint32_t)g_stressor_current->num_instances,
 2071                         .pid = getpid(),
 2072                         .ppid = getppid(),
 2073                         .page_size = stress_get_pagesize(),
 2074                         .mapped = &g_shared->mapped,
 2075                         .misc_stats = stats->misc_stats
 2076                     };
 2077 
 2078                     (void)memset(*checksum, 0, sizeof(**checksum));
 2079                     rc = g_stressor_current->stressor->info->stressor(&args);
 2080                     pr_fail_check(&rc);
 2081                     if (rc == EXIT_SUCCESS) {
 2082                         stats->run_ok = true;
 2083                         (*checksum)->data.run_ok = true;
 2084                     }
 2085 
 2086                     /*
 2087                      *  We're done, cancel SIGALRM
 2088                      */
 2089                     (void)alarm(0);
 2090 
 2091                     stress_set_proc_state(name, STRESS_STATE_STOP);
 2092                     /*
 2093                      *  Bogo ops counter should be OK for reading,
 2094                      *  if not then flag up that the counter may
 2095                      *  be untrustyworthy
 2096                      */
 2097                     if (!stats->counter_ready) {
 2098                         pr_inf("%s: NOTE: bogo-ops counter in non-ready state, metrics are untrustworthy (process may have been terminated prematurely)\n",
 2099                             name);
 2100                         rc = EXIT_METRICS_UNTRUSTWORTHY;
 2101                     }
 2102                     (*checksum)->data.counter = *args.counter;
 2103                     stress_hash_checksum(*checksum);
 2104                 }
 2105 #if defined(STRESS_PERF_STATS) &&   \
 2106     defined(HAVE_LINUX_PERF_EVENT_H)
 2107                 if (g_opt_flags & OPT_FLAGS_PERF_STATS) {
 2108                     (void)stress_perf_disable(&stats->sp);
 2109                     (void)stress_perf_close(&stats->sp);
 2110                 }
 2111 #endif
 2112 #if defined(STRESS_THERMAL_ZONES)
 2113                 if (g_opt_flags & OPT_FLAGS_THERMAL_ZONES)
 2114                     (void)stress_tz_get_temperatures(&g_shared->tz_info, &stats->tz);
 2115 #endif
 2116                 stats->finish = stress_time_now();
 2117                 if (times(&stats->tms) == (clock_t)-1) {
 2118                     pr_dbg("times failed: errno=%d (%s)\n",
 2119                         errno, strerror(errno));
 2120                 }
 2121                 pr_dbg("%s: exited [%d] (instance %" PRIu32 ")\n",
 2122                     name, (int)getpid(), j);
 2123 
 2124 child_exit:
 2125                 stress_stressors_free();
 2126                 stress_cache_free();
 2127                 stress_settings_free();
 2128                 stress_temp_path_free();
 2129                 (void)stress_ftrace_free();
 2130 
 2131                 if ((rc != 0) && (g_opt_flags & OPT_FLAGS_ABORT)) {
 2132                     keep_stressing_set_flag(false);
 2133                     wait_flag = false;
 2134                     (void)kill(getppid(), SIGALRM);
 2135                 }
 2136                 stress_set_proc_state(name, STRESS_STATE_EXIT);
 2137                 if (terminate_signum)
 2138                     rc = EXIT_SIGNALED;
 2139                 _exit(rc);
 2140             default:
 2141                 if (pid > -1) {
 2142                     (void)setpgid(pid, g_pgrp);
 2143                     g_stressor_current->pids[j] = pid;
 2144                     g_stressor_current->started_instances++;
 2145                     started_instances++;
 2146                     stress_ftrace_add_pid(pid);
 2147                 }
 2148 
 2149                 /* Forced early abort during startup? */
 2150                 if (!keep_stressing_flag()) {
 2151                     pr_dbg("abort signal during startup, cleaning up\n");
 2152                     stress_kill_stressors(SIGALRM);
 2153                     goto wait_for_stressors;
 2154                 }
 2155                 break;
 2156             }
 2157         }
 2158     }
 2159     (void)stress_set_handler("stress-ng", false);
 2160     if (g_opt_timeout)
 2161         (void)alarm((unsigned int)g_opt_timeout);
 2162 
 2163 abort:
 2164     pr_dbg("%d stressor%s started\n", started_instances,
 2165          started_instances == 1 ? "" : "s");
 2166 
 2167 wait_for_stressors:
 2168     stress_wait_stressors(stressors_list, success, resource_success, metrics_success);
 2169     time_finish = stress_time_now();
 2170 
 2171     *duration += time_finish - time_start;
 2172 }
 2173 
 2174 /*
 2175  *  stress_show_stressors()
 2176  *  show names of stressors that are going to be run
 2177  */
 2178 static int stress_show_stressors(void)
 2179 {
 2180     char *newstr, *str = NULL;
 2181     ssize_t len = 0;
 2182     char buffer[64];
 2183     bool previous = false;
 2184     stress_stressor_t *ss;
 2185 
 2186     for (ss = stressors_head; ss; ss = ss->next) {
 2187         const int32_t n = ss->num_instances;
 2188 
 2189         if (n) {
 2190             const ssize_t buffer_len =
 2191                 snprintf(buffer, sizeof(buffer),
 2192                     "%s %" PRId32 " %s",
 2193                     previous ? "," : "", n,
 2194                     stress_munge_underscore(ss->stressor->name));
 2195             previous = true;
 2196             if (buffer_len >= 0) {
 2197                 newstr = realloc(str, (size_t)(len + buffer_len + 1));
 2198                 if (!newstr) {
 2199                     pr_err("Cannot allocate temporary buffer\n");
 2200                     free(str);
 2201                     return -1;
 2202                 }
 2203                 str = newstr;
 2204                 (void)shim_strlcpy(str + len, buffer, (size_t)(buffer_len + 1));
 2205             }
 2206             len += buffer_len;
 2207         }
 2208     }
 2209     pr_inf("dispatching hogs:%s\n", str ? str : "");
 2210     free(str);
 2211     (void)fflush(stdout);
 2212 
 2213     return 0;
 2214 }
 2215 
 2216 /*
 2217  *  stress_metrics_check()
 2218  *  as per ELISA request, sanity check bogo ops and run flag
 2219  *  to see if corruption occurred and print failure messages
 2220  *  and set *success to false if hash and data is dubious.
 2221  */
 2222 static void stress_metrics_check(bool *success)
 2223 {
 2224     stress_stressor_t *ss;
 2225     bool ok = true;
 2226 
 2227     for (ss = stressors_head; ss; ss = ss->next) {
 2228         int32_t j;
 2229 
 2230         for (j = 0; j < ss->started_instances; j++) {
 2231             const stress_stats_t *const stats = ss->stats[j];
 2232             const stress_checksum_t *checksum = stats->checksum;
 2233             stress_checksum_t stats_checksum;
 2234 
 2235             if (checksum == NULL) {
 2236                 pr_fail("%s instance %d unexpected null checksum data\n",
 2237                     ss->stressor->name, j);
 2238                 ok = false;
 2239                 continue;
 2240             }
 2241 
 2242             (void)memset(&stats_checksum, 0, sizeof(stats_checksum));
 2243             stats_checksum.data.counter = stats->counter;
 2244             stats_checksum.data.run_ok = stats->run_ok;
 2245             stress_hash_checksum(&stats_checksum);
 2246 
 2247             if (stats->counter != checksum->data.counter) {
 2248                 pr_fail("%s instance %d corrupted bogo-ops counter, %" PRIu64 " vs %" PRIu64 "\n",
 2249                     ss->stressor->name, j,
 2250                     stats->counter, checksum->data.counter);
 2251                 ok = false;
 2252             }
 2253             if (stats->run_ok != checksum->data.run_ok) {
 2254                 pr_fail("%s instance %d corrupted run flag, %d vs %d\n",
 2255                     ss->stressor->name, j,
 2256                     stats->run_ok, checksum->data.run_ok);
 2257                 ok = false;
 2258             }
 2259             if (stats_checksum.hash != checksum->hash) {
 2260                 pr_fail("%s instance %d hash error in bogo-ops counter and run flag, %" PRIu32 " vs %" PRIu32 "\n",
 2261                     ss->stressor->name, j,
 2262                     stats_checksum.hash, checksum->hash);
 2263                 ok = false;
 2264             }
 2265         }
 2266     }
 2267     if (ok) {
 2268         pr_dbg("metrics-check: all stressor metrics validated and sane\n");
 2269     } else {
 2270         pr_fail("metrics-check: stressor metrics corrupted, data is compromised\n");
 2271         *success = false;
 2272     }
 2273 }
 2274 
 2275 static char *stess_description_yamlify(const char *description)
 2276 {
 2277     static char yamlified[40];
 2278     char *dst, *end = yamlified + sizeof(yamlified);
 2279     const char *src;
 2280 
 2281     for (dst = yamlified, src = description; *src; src++) {
 2282         register int ch = (int)*src;
 2283 
 2284         if (isalpha(ch)) {
 2285             *(dst++) = (char)tolower(ch);
 2286         } else if (isdigit(ch)) {
 2287             *(dst++) = (char)ch;
 2288         } else if (ch == ' ') {
 2289             *(dst++) = '-';
 2290         }
 2291         if (dst >= end - 1)
 2292             break;
 2293     }
 2294     *dst = '\0';
 2295 
 2296     return yamlified;
 2297 }
 2298 
 2299 /*
 2300  *  stress_metrics_dump()
 2301  *  output metrics
 2302  */
 2303 static void stress_metrics_dump(
 2304     FILE *yaml,
 2305     const int32_t ticks_per_sec)
 2306 {
 2307     stress_stressor_t *ss;
 2308 
 2309     if (g_opt_flags & OPT_FLAGS_METRICS_BRIEF) {
 2310         pr_inf("%-13s %9.9s %9.9s %9.9s %9.9s %12s %14s\n",
 2311             "stressor", "bogo ops", "real time", "usr time",
 2312             "sys time", "bogo ops/s", "bogo ops/s");
 2313         pr_inf("%-13s %9.9s %9.9s %9.9s %9.9s %12s %14s\n",
 2314             "", "", "(secs) ", "(secs) ", "(secs) ", "(real time)",
 2315             "(usr+sys time)");
 2316     } else {
 2317         pr_inf("%-13s %9.9s %9.9s %9.9s %9.9s %12s %14s %12.12s\n",
 2318             "stressor", "bogo ops", "real time", "usr time",
 2319             "sys time", "bogo ops/s", "bogo ops/s", "CPU used per");
 2320         pr_inf("%-13s %9.9s %9.9s %9.9s %9.9s %12s %14s %12.12s\n",
 2321             "", "", "(secs) ", "(secs) ", "(secs) ", "(real time)",
 2322             "(usr+sys time)","instance (%)");
 2323     }
 2324     pr_yaml(yaml, "metrics:\n");
 2325 
 2326     for (ss = stressors_head; ss; ss = ss->next) {
 2327         uint64_t c_total = 0, u_total = 0, s_total = 0;
 2328         double   r_total = 0.0;
 2329         int32_t  j;
 2330         size_t i;
 2331         const char *munged = stress_munge_underscore(ss->stressor->name);
 2332         double u_time, s_time, t_time, bogo_rate_r_time, bogo_rate, cpu_usage;
 2333         bool run_ok = false;
 2334         bool lock = false;
 2335 
 2336         for (j = 0; j < ss->started_instances; j++) {
 2337             const stress_stats_t *const stats = ss->stats[j];
 2338 
 2339             run_ok  |= stats->run_ok;
 2340             c_total += stats->counter;
 2341             u_total += (uint64_t)(stats->tms.tms_utime +
 2342                           stats->tms.tms_cutime);
 2343             s_total += (uint64_t)(stats->tms.tms_stime +
 2344                           stats->tms.tms_cstime);
 2345             r_total += stats->finish - stats->start;
 2346         }
 2347         /* Real time in terms of average wall clock time of all procs */
 2348         r_total = ss->started_instances ?
 2349             r_total / (double)ss->started_instances : 0.0;
 2350 
 2351         if ((g_opt_flags & OPT_FLAGS_METRICS_BRIEF) &&
 2352             (c_total == 0) && (!run_ok))
 2353             continue;
 2354 
 2355         u_time = (ticks_per_sec > 0) ? (double)u_total / (double)ticks_per_sec : 0.0;
 2356         s_time = (ticks_per_sec > 0) ? (double)s_total / (double)ticks_per_sec : 0.0;
 2357         t_time = u_time + s_time;
 2358 
 2359         /* Total usr + sys time of all procs */
 2360         bogo_rate_r_time = (r_total > 0.0) ? (double)c_total / r_total : 0.0;
 2361         {
 2362             register uint64_t us_total = u_total + s_total;
 2363 
 2364             bogo_rate = (us_total > 0) ? (double)c_total / ((double)us_total / (double)ticks_per_sec) : 0.0;
 2365         }
 2366         cpu_usage = (r_total > 0) ? 100.0 * t_time / r_total : 0.0;
 2367         cpu_usage = ss->started_instances ? cpu_usage / ss->started_instances : 0.0;
 2368 
 2369         pr_lock(&lock);
 2370         if (g_opt_flags & OPT_FLAGS_METRICS_BRIEF) {
 2371             pr_inf("%-13s %9" PRIu64 " %9.2f %9.2f %9.2f %12.2f %14.2f\n",
 2372                 munged,     /* stress test name */
 2373                 c_total,    /* op count */
 2374                 r_total,    /* average real (wall) clock time */
 2375                 u_time,     /* actual user time */
 2376                 s_time,     /* actual system time */
 2377                 bogo_rate_r_time, /* bogo ops on wall clock time */
 2378                 bogo_rate); /* bogo ops per second */
 2379         } else {
 2380             /* extended metrics */
 2381             pr_inf("%-13s %9" PRIu64 " %9.2f %9.2f %9.2f %12.2f %14.2f %12.2f\n",
 2382                 munged,     /* stress test name */
 2383                 c_total,    /* op count */
 2384                 r_total,    /* average real (wall) clock time */
 2385                 u_time,     /* actual user time */
 2386                 s_time,     /* actual system time */
 2387                 bogo_rate_r_time, /* bogo ops on wall clock time */
 2388                 bogo_rate,  /* bogo ops per second */
 2389                 cpu_usage); /* % cpu usage */
 2390         }
 2391         for (i = 0; i < SIZEOF_ARRAY(ss->stats[j]->misc_stats); i++) {
 2392             const char *description = ss->stats[0]->misc_stats[i].description;
 2393 
 2394             if (*description) {
 2395                 double metric, total = 0.0;
 2396 
 2397                 for (j = 0; j < ss->started_instances; j++) {
 2398                     const stress_stats_t *const stats = ss->stats[j];
 2399 
 2400                     total += stats->misc_stats[i].value;
 2401                 }
 2402                 metric = ss->started_instances ? total / ss->started_instances : 0.0;
 2403                 pr_inf("%-13s %9.2f %s (average per stressor)\n",
 2404                     munged, metric, description);
 2405             };
 2406         }
 2407         pr_unlock(&lock);
 2408 
 2409         pr_yaml(yaml, "    - stressor: %s\n", munged);
 2410         pr_yaml(yaml, "      bogo-ops: %" PRIu64 "\n", c_total);
 2411         pr_yaml(yaml, "      bogo-ops-per-second-usr-sys-time: %f\n", bogo_rate);
 2412         pr_yaml(yaml, "      bogo-ops-per-second-real-time: %f\n", bogo_rate_r_time);
 2413         pr_yaml(yaml, "      wall-clock-time: %f\n", r_total);
 2414         pr_yaml(yaml, "      user-time: %f\n", u_time);
 2415         pr_yaml(yaml, "      system-time: %f\n", s_time);
 2416         pr_yaml(yaml, "      cpu-usage-per-instance: %f\n", cpu_usage);
 2417 
 2418         for (i = 0; i < SIZEOF_ARRAY(ss->stats[j]->misc_stats); i++) {
 2419             const char *description = ss->stats[0]->misc_stats[i].description;
 2420 
 2421             if (*description) {
 2422                 double metric, total = 0.0;
 2423 
 2424                 for (j = 0; j < ss->started_instances; j++) {
 2425                     const stress_stats_t *const stats = ss->stats[j];
 2426 
 2427                     total += stats->misc_stats[i].value;
 2428                 }
 2429                 metric = ss->started_instances ? total / ss->started_instances : 0.0;
 2430                 pr_yaml(yaml, "      %s: %f\n", stess_description_yamlify(description), metric);
 2431             };
 2432         }
 2433 
 2434         pr_yaml(yaml, "\n");
 2435     }
 2436 }
 2437 
 2438 /*
 2439  *  stress_times_dump()
 2440  *  output the run times
 2441  */
 2442 static void stress_times_dump(
 2443     FILE *yaml,
 2444     const int32_t ticks_per_sec,
 2445     const double duration)
 2446 {
 2447     struct tms buf;
 2448     double total_cpu_time = stress_get_processors_configured() * duration;
 2449     double u_time, s_time, t_time, u_pc, s_pc, t_pc;
 2450     double min1, min5, min15;
 2451     int rc;
 2452 
 2453     if (!(g_opt_flags & OPT_FLAGS_TIMES))
 2454         return;
 2455 
 2456     if (times(&buf) == (clock_t)-1) {
 2457         pr_err("cannot get run time information: errno=%d (%s)\n",
 2458             errno, strerror(errno));
 2459         return;
 2460     }
 2461     rc = stress_get_load_avg(&min1, &min5, &min15);
 2462 
 2463     u_time = (double)buf.tms_cutime / (double)ticks_per_sec;
 2464     s_time = (double)buf.tms_cstime / (double)ticks_per_sec;
 2465     t_time = ((double)buf.tms_cutime + (double)buf.tms_cstime) / (double)ticks_per_sec;
 2466     u_pc = (total_cpu_time > 0.0) ? 100.0 * u_time / total_cpu_time : 0.0;
 2467     s_pc = (total_cpu_time > 0.0) ? 100.0 * s_time / total_cpu_time : 0.0;
 2468     t_pc = (total_cpu_time > 0.0) ? 100.0 * t_time / total_cpu_time : 0.0;
 2469 
 2470     pr_inf("for a %.2fs run time:\n", duration);
 2471     pr_inf("  %8.2fs available CPU time\n",
 2472         total_cpu_time);
 2473     pr_inf("  %8.2fs user time   (%6.2f%%)\n", u_time, u_pc);
 2474     pr_inf("  %8.2fs system time (%6.2f%%)\n", s_time, s_pc);
 2475     pr_inf("  %8.2fs total time  (%6.2f%%)\n", t_time, t_pc);
 2476 
 2477     if (!rc) {
 2478         pr_inf("load average: %.2f %.2f %.2f\n",
 2479             min1, min5, min15);
 2480     }
 2481 
 2482     pr_yaml(yaml, "times:\n");
 2483     pr_yaml(yaml, "      run-time: %f\n", duration);
 2484     pr_yaml(yaml, "      available-cpu-time: %f\n", total_cpu_time);
 2485     pr_yaml(yaml, "      user-time: %f\n", u_time);
 2486     pr_yaml(yaml, "      system-time: %f\n", s_time);
 2487     pr_yaml(yaml, "      total-time: %f\n", t_time);
 2488     pr_yaml(yaml, "      user-time-percent: %f\n", u_pc);
 2489     pr_yaml(yaml, "      system-time-percent: %f\n", s_pc);
 2490     pr_yaml(yaml, "      total-time-percent: %f\n", t_pc);
 2491     if (!rc) {
 2492         pr_yaml(yaml, "      load-average-1-minute: %f\n", min1);
 2493         pr_yaml(yaml, "      load-average-5-minute: %f\n", min5);
 2494         pr_yaml(yaml, "      load-average-15-minute: %f\n", min15);
 2495     }
 2496 }
 2497 
 2498 /*
 2499  *  stress_log_args()
 2500  *  dump to syslog argv[]
 2501  */
 2502 static void stress_log_args(int argc, char **argv)
 2503 {
 2504     size_t i, len, buflen, arglen[argc];
 2505     char *buf;
 2506     const char *user = shim_getlogin();
 2507 
 2508     for (buflen = 0, i = 0; i < (size_t)argc; i++) {
 2509         arglen[i] = strlen(argv[i]);
 2510         buflen += arglen[i] + 1;
 2511     }
 2512 
 2513     buf = calloc(buflen, sizeof(*buf));
 2514     if (!buf)
 2515         return;
 2516 
 2517     for (len = 0, i = 0; i < (size_t)argc; i++) {
 2518         if (i) {
 2519             (void)shim_strlcat(buf + len, " ", buflen - len);
 2520             len++;
 2521         }
 2522         (void)shim_strlcat(buf + len, argv[i], buflen - len);
 2523         len += arglen[i];
 2524     }
 2525     if (user)
 2526         shim_syslog(LOG_INFO, "invoked with '%s' by user %d '%s'", buf, getuid(), user);
 2527     else
 2528         shim_syslog(LOG_INFO, "invoked with '%s' by user %d", buf, getuid());
 2529     free(buf);
 2530 }
 2531 
 2532 /*
 2533  *  stress_log_system_mem_info()
 2534  *  dump system memory info
 2535  */
 2536 void stress_log_system_mem_info(void)
 2537 {
 2538 #if defined(HAVE_SYS_SYSINFO_H) && \
 2539     defined(HAVE_SYSINFO) && \
 2540     defined(HAVE_SYSLOG_H)
 2541     struct sysinfo info;
 2542 
 2543     (void)memset(&info, 0, sizeof(info));
 2544     if (sysinfo(&info) == 0) {
 2545         shim_syslog(LOG_INFO, "memory (MB): total %.2f, "
 2546             "free %.2f, "
 2547             "shared %.2f, "
 2548             "buffer %.2f, "
 2549             "swap %.2f, "
 2550             "free swap %.2f\n",
 2551             (double)(info.totalram * info.mem_unit) / MB,
 2552             (double)(info.freeram * info.mem_unit) / MB,
 2553             (double)(info.sharedram * info.mem_unit) / MB,
 2554             (double)(info.bufferram * info.mem_unit) / MB,
 2555             (double)(info.totalswap * info.mem_unit) / MB,
 2556             (double)(info.freeswap * info.mem_unit) / MB);
 2557     }
 2558 #endif
 2559 }
 2560 
 2561 /*
 2562  *  stress_log_system_info()
 2563  *  dump system info
 2564  */
 2565 static void stress_log_system_info(void)
 2566 {
 2567 #if defined(HAVE_UNAME) &&      \
 2568     defined(HAVE_SYS_UTSNAME_H) &&  \
 2569     defined(HAVE_SYSLOG_H)
 2570     struct utsname buf;
 2571 
 2572     if (uname(&buf) == 0) {
 2573         shim_syslog(LOG_INFO, "system: '%s' %s %s %s %s\n",
 2574             buf.nodename,
 2575             buf.sysname,
 2576             buf.release,
 2577             buf.version,
 2578             buf.machine);
 2579     }
 2580 #endif
 2581 }
 2582 
 2583 static void *stress_map_page(int prot, char *prot_str, size_t page_size)
 2584 {
 2585     void *ptr;
 2586 
 2587     ptr = mmap(NULL, page_size, prot,
 2588         MAP_PRIVATE | MAP_ANON, -1, 0);
 2589     if (ptr == MAP_FAILED) {
 2590         pr_err("cannot mmap %s shared page, errno=%d (%s)\n",
 2591             prot_str, errno, strerror(errno));
 2592     }
 2593     return ptr;
 2594 }
 2595 
 2596 /*
 2597  *  stress_shared_map()
 2598  *  mmap shared region, with an extra page at the end
 2599  *  that is marked read-only to stop accidental smashing
 2600  *  from a run-away stack expansion
 2601  */
 2602 static inline void stress_shared_map(const int32_t num_procs)
 2603 {
 2604     const size_t page_size = stress_get_pagesize();
 2605     size_t len = sizeof(stress_shared_t) +
 2606              (sizeof(stress_stats_t) * (size_t)num_procs);
 2607     size_t sz = (len + (page_size << 1)) & ~(page_size - 1);
 2608 #if defined(HAVE_MPROTECT)
 2609     void *last_page;
 2610 #endif
 2611 
 2612     g_shared = (stress_shared_t *)mmap(NULL, sz, PROT_READ | PROT_WRITE,
 2613         MAP_SHARED | MAP_ANON, -1, 0);
 2614     if (g_shared == MAP_FAILED) {
 2615         pr_err("cannot mmap to shared memory region, errno=%d (%s)\n",
 2616             errno, strerror(errno));
 2617         stress_stressors_free();
 2618         exit(EXIT_FAILURE);
 2619     }
 2620 
 2621     /* Paraniod */
 2622     (void)memset(g_shared, 0, sz);
 2623     g_shared->length = sz;
 2624 
 2625 #if defined(HAVE_MPROTECT)
 2626     last_page = ((uint8_t *)g_shared) + sz - page_size;
 2627 
 2628     /* Make last page trigger a segfault if it is accessed */
 2629     (void)mprotect(last_page, page_size, PROT_NONE);
 2630 #elif defined(HAVE_MREMAP) &&   \
 2631       defined(MAP_FIXED)
 2632     {
 2633         void *new_last_page;
 2634 
 2635         /* Try to remap last page with PROT_NONE */
 2636         (void)munmap(last_page, page_size);
 2637         new_last_page = mmap(last_page, page_size, PROT_NONE,
 2638             MAP_SHARED | MAP_ANON | MAP_FIXED, -1, 0);
 2639 
 2640         /* Failed, retry read-only */
 2641         if (new_last_page == MAP_FAILED)
 2642             new_last_page = mmap(last_page, page_size, PROT_READ,
 2643                 MAP_SHARED | MAP_ANON | MAP_FIXED, -1, 0);
 2644         /* Can't remap, bump length down a page */
 2645         if (new_last_page == MAP_FAILED)
 2646             g_shared->length -= sz;
 2647     }
 2648 #endif
 2649 
 2650     /*
 2651      *  copy of checksums and run data in a different shared
 2652      *  memory segment so that we can sanity check these for
 2653      *  any form of corruption
 2654      */
 2655     len = sizeof(stress_checksum_t) * STRESS_PROCS_MAX;
 2656     sz = (len + page_size) & ~(page_size - 1);
 2657     g_shared->checksums = (stress_checksum_t *)mmap(NULL, sz,
 2658         PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
 2659     if (g_shared->checksums == MAP_FAILED) {
 2660         pr_err("cannot mmap checksums, errno=%d (%s)\n",
 2661             errno, strerror(errno));
 2662         goto err_unmap_shared;
 2663     }
 2664     (void)memset(g_shared->checksums, 0, sz);
 2665     g_shared->checksums_length = sz;
 2666 
 2667     /*
 2668      *  mmap some pages for testing invalid arguments in
 2669      *  various stressors, get the allocations done early
 2670      *  to avoid later mmap failures on stressor child
 2671      *  processes
 2672      */
 2673     g_shared->mapped.page_none = stress_map_page(PROT_NONE, "PROT_NONE", page_size);
 2674     if (g_shared->mapped.page_none == MAP_FAILED)
 2675         goto err_unmap_checksums;
 2676     g_shared->mapped.page_ro = stress_map_page(PROT_READ, "PROT_READ", page_size);
 2677     if (g_shared->mapped.page_ro == MAP_FAILED)
 2678         goto err_unmap_page_none;
 2679     g_shared->mapped.page_wo = stress_map_page(PROT_READ, "PROT_WRITE", page_size);
 2680     if (g_shared->mapped.page_wo == MAP_FAILED)
 2681         goto err_unmap_page_ro;
 2682     return;
 2683 
 2684 err_unmap_page_ro:
 2685     (void)munmap((void *)g_shared->mapped.page_ro, page_size);
 2686 err_unmap_page_none:
 2687     (void)munmap((void *)g_shared->mapped.page_none, page_size);
 2688 err_unmap_checksums:
 2689     (void)munmap((void *)g_shared->checksums, g_shared->checksums_length);
 2690 err_unmap_shared:
 2691     (void)munmap((void *)g_shared, g_shared->length);
 2692     stress_stressors_free();
 2693     exit(EXIT_FAILURE);
 2694 
 2695 }
 2696 
 2697 /*
 2698  *  stress_shared_unmap()
 2699  *  unmap shared region
 2700  */
 2701 void stress_shared_unmap(void)
 2702 {
 2703     const size_t page_size = stress_get_pagesize();
 2704 
 2705     (void)munmap((void *)g_shared->mapped.page_wo, page_size);
 2706     (void)munmap((void *)g_shared->mapped.page_ro, page_size);
 2707     (void)munmap((void *)g_shared->mapped.page_none, page_size);
 2708     (void)munmap((void *)g_shared->checksums, g_shared->checksums_length);
 2709     (void)munmap((void *)g_shared, g_shared->length);
 2710 }
 2711 
 2712 /*
 2713  *  stress_exclude_unsupported()
 2714  *  tag stressor proc count to be excluded
 2715  */
 2716 static inline void stress_exclude_unsupported(void)
 2717 {
 2718     size_t i;
 2719 
 2720     for (i = 0; i < SIZEOF_ARRAY(stressors); i++) {
 2721         if (stressors[i].info && stressors[i].info->supported) {
 2722             stress_stressor_t *ss = stressors_head;
 2723             stress_id_t id = stressors[i].id;
 2724 
 2725             while (ss) {
 2726                 stress_stressor_t *next = ss->next;
 2727 
 2728                 if ((ss->stressor->id == id) &&
 2729                     ss->num_instances &&
 2730                     (stressors[i].info->supported(stressors[i].name) < 0)) {
 2731                     stress_remove_stressor(ss);
 2732                     g_unsupported = true;
 2733                 }
 2734                 ss = next;
 2735             }
 2736         }
 2737     }
 2738 }
 2739 
 2740 /*
 2741  *  stress_set_proc_limits()
 2742  *  set maximum number of processes for specific stressors
 2743  */
 2744 static void stress_set_proc_limits(void)
 2745 {
 2746 #if defined(RLIMIT_NPROC)
 2747     stress_stressor_t *ss;
 2748     struct rlimit limit;
 2749 
 2750     if (getrlimit(RLIMIT_NPROC, &limit) < 0)
 2751         return;
 2752 
 2753     for (ss = stressors_head; ss; ss = ss->next) {
 2754         size_t i;
 2755 
 2756         for (i = 0; i < SIZEOF_ARRAY(stressors); i++) {
 2757             if (stressors[i].info &&
 2758                 stressors[i].info->set_limit &&
 2759                 (stressors[i].id == ss->stressor->id) &&
 2760                 ss->num_instances) {
 2761                 const uint64_t max = (uint64_t)limit.rlim_cur / (uint64_t)ss->num_instances;
 2762 
 2763                 stressors[i].info->set_limit(max);
 2764             }
 2765         }
 2766     }
 2767 #endif
 2768 }
 2769 
 2770 /*
 2771  *  stress_find_proc_info()
 2772  *  find proc info that is associated with a specific
 2773  *  stressor.  If it does not exist, create a new one
 2774  *  and return that. Terminate if out of memory.
 2775  */
 2776 static stress_stressor_t *stress_find_proc_info(const stress_t *stressor)
 2777 {
 2778     stress_stressor_t *ss;
 2779 
 2780 #if 0
 2781     /* Scan backwards in time to find last matching stressor */
 2782     for (ss = stressors_tail; ss; ss = ss->prev) {
 2783         if (ss->stressor == stressor)
 2784             return ss;
 2785     }
 2786 #endif
 2787 
 2788     ss = calloc(1, sizeof(*ss));
 2789     if (!ss) {
 2790         (void)fprintf(stderr, "Cannot allocate stressor state info\n");
 2791         exit(EXIT_FAILURE);
 2792     }
 2793 
 2794     ss->stressor = stressor;
 2795 
 2796     /* Add to end of procs list */
 2797     if (stressors_tail)
 2798         stressors_tail->next = ss;
 2799     else
 2800         stressors_head = ss;
 2801     ss->prev = stressors_tail;
 2802     stressors_tail = ss;
 2803 
 2804     return ss;
 2805 }
 2806 
 2807 /*
 2808  *  stress_stressors_init()
 2809  *  initialize any stressors that will be used
 2810  */
 2811 static void stress_stressors_init(void)
 2812 {
 2813     stress_stressor_t *ss;
 2814 
 2815     for (ss = stressors_head; ss; ss = ss->next) {
 2816         size_t i;
 2817 
 2818         for (i = 0; i < SIZEOF_ARRAY(stressors); i++) {
 2819             if (stressors[i].info &&
 2820                 stressors[i].info->init &&
 2821                 stressors[i].id == ss->stressor->id)
 2822                 stressors[i].info->init();
 2823         }
 2824     }
 2825 }
 2826 
 2827 /*
 2828  *  stress_stressors_deinit()
 2829  *  de-initialize any stressors that will be used
 2830  */
 2831 static void stress_stressors_deinit(void)
 2832 {
 2833     stress_stressor_t *ss;
 2834 
 2835     for (ss = stressors_head; ss; ss = ss->next) {
 2836         size_t i;
 2837 
 2838         for (i = 0; i < SIZEOF_ARRAY(stressors); i++) {
 2839             if (stressors[i].info &&
 2840                 stressors[i].info->deinit &&
 2841                 stressors[i].id == ss->stressor->id)
 2842                 stressors[i].info->deinit();
 2843         }
 2844     }
 2845 }
 2846 
 2847 
 2848 /*
 2849  *  stessor_set_defaults()
 2850  *  set up stressor default settings that can be overridden
 2851  *  by user later on
 2852  */
 2853 static inline void stressor_set_defaults(void)
 2854 {
 2855     size_t i;
 2856 
 2857     for (i = 0; i < SIZEOF_ARRAY(stressors); i++) {
 2858         if (stressors[i].info && stressors[i].info->set_default) {
 2859             stressors[i].info->set_default();
 2860         }
 2861     }
 2862 }
 2863 
 2864 /*
 2865  *  stress_exclude_pathological()
 2866  *  Disable pathological stressors if user has not explicitly
 2867  *  request them to be used. Let's play safe.
 2868  */
 2869 static inline void stress_exclude_pathological(void)
 2870 {
 2871     if (!(g_opt_flags & OPT_FLAGS_PATHOLOGICAL)) {
 2872         stress_stressor_t *ss = stressors_head;
 2873 
 2874         while (ss) {
 2875             stress_stressor_t *next = ss->next;
 2876 
 2877             if (ss->stressor->info->class & CLASS_PATHOLOGICAL) {
 2878                 if (ss->num_instances > 0) {
 2879                     pr_inf("disabled '%s' as it "
 2880                         "may hang or reboot the machine "
 2881                         "(enable it with the "
 2882                         "--pathological option)\n",
 2883                         stress_munge_underscore(ss->stressor->name));
 2884                 }
 2885                 stress_remove_stressor(ss);
 2886             }
 2887             ss = next;
 2888         }
 2889     }
 2890 }
 2891 
 2892 /*
 2893  *  stress_setup_stats_buffers()
 2894  *  setup the stats data from the shared memory
 2895  */
 2896 static inline void stress_setup_stats_buffers(void)
 2897 {
 2898     stress_stressor_t *ss;
 2899     stress_stats_t *stats = g_shared->stats;
 2900 
 2901     for (ss = stressors_head; ss; ss = ss->next) {
 2902         int32_t j;
 2903 
 2904         for (j = 0; j < ss->num_instances; j++, stats++)
 2905             ss->stats[j] = stats;
 2906     }
 2907 }
 2908 
 2909 /*
 2910  *  stress_set_random_stressors()
 2911  *  select stressors at random
 2912  */
 2913 static inline void stress_set_random_stressors(void)
 2914 {
 2915     int32_t opt_random = 0;
 2916 
 2917     (void)stress_get_setting("random", &opt_random);
 2918 
 2919     if (g_opt_flags & OPT_FLAGS_RANDOM) {
 2920         int32_t n = opt_random;
 2921         const uint32_t n_procs = stress_get_num_stressors();
 2922 
 2923         if (g_opt_flags & OPT_FLAGS_SET) {
 2924             (void)fprintf(stderr, "Cannot specify random "
 2925                 "option with other stress processes "
 2926                 "selected\n");
 2927             exit(EXIT_FAILURE);
 2928         }
 2929 
 2930         if (!n_procs) {
 2931             (void)fprintf(stderr,
 2932                 "No stressors are available, unable to continue\n");
 2933             exit(EXIT_FAILURE);
 2934         }
 2935 
 2936         /* create n randomly chosen stressors */
 2937         while (n > 0) {
 2938             const uint32_t i = stress_mwc32() % n_procs;
 2939             stress_stressor_t *ss = stress_get_nth_stressor(i);
 2940 
 2941             if (!ss)
 2942                 continue;
 2943 
 2944             ss->num_instances++;
 2945             n--;
 2946         }
 2947     }
 2948 }
 2949 
 2950 /*
 2951  *  stress_enable_all_stressors()
 2952  *  enable all the stressors
 2953  */
 2954 static void stress_enable_all_stressors(const int32_t instances)
 2955 {
 2956     size_t i;
 2957 
 2958     /* Don't enable all if some stressors are set */
 2959     if (g_opt_flags & OPT_FLAGS_SET)
 2960         return;
 2961 
 2962     for (i = 0; i < STRESS_MAX; i++) {
 2963         stress_stressor_t *ss = stress_find_proc_info(&stressors[i]);
 2964 
 2965         if (!ss) {
 2966             (void)fprintf(stderr, "Cannot allocate stressor state info\n");
 2967             exit(EXIT_FAILURE);
 2968         }
 2969         ss->num_instances = instances;
 2970     }
 2971 }
 2972 
 2973 /*
 2974  *  stress_enable_classes()
 2975  *  enable stressors based on class
 2976  */
 2977 static void stress_enable_classes(const uint32_t class)
 2978 {
 2979     size_t i;
 2980 
 2981     if (!class)
 2982         return;
 2983 
 2984     /* This indicates some stressors are set */
 2985     g_opt_flags |= OPT_FLAGS_SET;
 2986 
 2987     for (i = 0; stressors[i].id != STRESS_MAX; i++) {
 2988         if (stressors[i].info->class & class) {
 2989             stress_stressor_t *ss = stress_find_proc_info(&stressors[i]);
 2990 
 2991             if (g_opt_flags & OPT_FLAGS_SEQUENTIAL)
 2992                 ss->num_instances = g_opt_sequential;
 2993             if (g_opt_flags & OPT_FLAGS_ALL)
 2994                 ss->num_instances = g_opt_parallel;
 2995         }
 2996     }
 2997 }
 2998 
 2999 
 3000 /*
 3001  *  stress_parse_opts
 3002  *  parse argv[] and set stress-ng options accordingly
 3003  */
 3004 int stress_parse_opts(int argc, char **argv, const bool jobmode)
 3005 {
 3006     optind = 0;
 3007 
 3008     for (;;) {
 3009         int64_t i64;
 3010         int32_t i32;
 3011         uint32_t u32;
 3012         uint64_t u64, max_fds;
 3013         int16_t i16;
 3014         int c, option_index, ret;
 3015         size_t i;
 3016 
 3017         opterr = (!jobmode) ? opterr : 0;
 3018 
 3019 next_opt:
 3020         if ((c = getopt_long(argc, argv, "?khMVvqnt:b:c:i:j:m:d:f:s:l:p:P:C:S:a:y:F:D:T:u:o:r:B:R:Y:x:",
 3021             long_options, &option_index)) == -1) {
 3022             break;
 3023         }
 3024 
 3025         for (i = 0; stressors[i].id != STRESS_MAX; i++) {
 3026             if (stressors[i].short_getopt == c) {
 3027                 const char *name = stress_opt_name(c);
 3028                 stress_stressor_t *ss = stress_find_proc_info(&stressors[i]);
 3029                 g_stressor_current = ss;
 3030 
 3031                 g_opt_flags |= OPT_FLAGS_SET;
 3032                 ss->num_instances = stress_get_int32(optarg);
 3033                 stress_get_processors(&ss->num_instances);
 3034                 stress_check_value(name, ss->num_instances);
 3035 
 3036                 goto next_opt;
 3037             }
 3038             if (stressors[i].op == (stress_op_t)c) {
 3039                 uint64_t bogo_ops;
 3040 
 3041                 bogo_ops = stress_get_uint64(optarg);
 3042                 stress_check_range(stress_opt_name(c), bogo_ops,
 3043                     MIN_OPS, MAX_OPS);
 3044                 /* We don't need to set this, but it may be useful */
 3045                 stress_set_setting(stress_opt_name(c), TYPE_ID_UINT64, &bogo_ops);
 3046                 if (g_stressor_current)
 3047                     g_stressor_current->bogo_ops = bogo_ops;
 3048                 goto next_opt;
 3049             }
 3050             if (stressors[i].info->opt_set_funcs) {
 3051                 size_t j;
 3052                 const stressor_info_t *info = stressors[i].info;
 3053 
 3054                 for (j = 0; info->opt_set_funcs[j].opt_set_func; j++) {
 3055                     if (info->opt_set_funcs[j].opt == c) {
 3056                         ret = info->opt_set_funcs[j].opt_set_func(optarg);
 3057                         if (ret < 0)
 3058                             return EXIT_FAILURE;
 3059                         goto next_opt;
 3060                     }
 3061                 }
 3062             }
 3063         }
 3064 
 3065         for (i = 0; i < SIZEOF_ARRAY(opt_flags); i++) {
 3066             if (c == opt_flags[i].opt) {
 3067                 g_opt_flags |= opt_flags[i].opt_flag;
 3068                 goto next_opt;
 3069             }
 3070         }
 3071 
 3072         switch (c) {
 3073         case OPT_all:
 3074             g_opt_flags |= OPT_FLAGS_ALL;
 3075             g_opt_parallel = stress_get_int32(optarg);
 3076             stress_get_processors(&g_opt_parallel);
 3077             stress_check_value("all", g_opt_parallel);
 3078             break;
 3079         case OPT_backoff:
 3080             i64 = (int64_t)stress_get_uint64(optarg);
 3081             stress_set_setting_global("backoff", TYPE_ID_INT64, &i64);
 3082             break;
 3083         case OPT_cache_level:
 3084             /*
 3085              * Note: Overly high values will be caught in the
 3086              * caching code.
 3087              */
 3088             i16 = atoi(optarg);
 3089             if ((i16 <= 0) || (i16 > 3))
 3090                 i16 = DEFAULT_CACHE_LEVEL;
 3091             stress_set_setting("cache-level", TYPE_ID_INT16, &i16);
 3092             break;
 3093         case OPT_cache_ways:
 3094             u32 = stress_get_uint32(optarg);
 3095             stress_set_setting("cache-ways", TYPE_ID_UINT32, &u32);
 3096             break;
 3097         case OPT_class:
 3098             ret = stress_get_class(optarg, &u32);
 3099             if (ret < 0)
 3100                 return EXIT_FAILURE;
 3101             else if (ret > 0)
 3102                 exit(EXIT_SUCCESS);
 3103             else {
 3104                 stress_set_setting("class", TYPE_ID_UINT32, &u32);
 3105                 stress_enable_classes(u32);
 3106             }
 3107             break;
 3108         case OPT_exclude:
 3109             stress_set_setting_global("exclude", TYPE_ID_STR, (void *)optarg);
 3110             break;
 3111         case OPT_help:
 3112             stress_usage();
 3113             break;
 3114         case OPT_ionice_class:
 3115             i32 = stress_get_opt_ionice_class(optarg);
 3116             stress_set_setting("ionice-class", TYPE_ID_INT32, &i32);
 3117             break;
 3118         case OPT_ionice_level:
 3119             i32 = stress_get_int32(optarg);
 3120             stress_set_setting("ionice-level", TYPE_ID_INT32, &i32);
 3121             break;
 3122         case OPT_job:
 3123             stress_set_setting_global("job", TYPE_ID_STR, (void *)optarg);
 3124             break;
 3125         case OPT_log_file:
 3126             stress_set_setting_global("log-file", TYPE_ID_STR, (void *)optarg);
 3127             break;
 3128         case OPT_max_fd:
 3129             max_fds = (uint64_t)stress_get_file_limit();
 3130             u64 = stress_get_uint64_percent(optarg, 1, max_fds,
 3131                 "Cannot determine maximum file descriptor limit");
 3132             stress_check_range(optarg, u64, 8, max_fds);
 3133             stress_set_setting_global("max-fd", TYPE_ID_UINT64, &u64);
 3134             break;
 3135         case OPT_no_madvise:
 3136             g_opt_flags &= ~OPT_FLAGS_MMAP_MADVISE;
 3137             break;
 3138         case OPT_query:
 3139             if (!jobmode) {
 3140                 (void)printf("Try '%s --help' for more information.\n", g_app_name);
 3141             }
 3142             return EXIT_FAILURE;
 3143         case OPT_quiet:
 3144             g_opt_flags &= ~(PR_ALL);
 3145             break;
 3146         case OPT_random:
 3147             g_opt_flags |= OPT_FLAGS_RANDOM;
 3148             i32 = stress_get_int32(optarg);
 3149             stress_get_processors(&i32);
 3150             stress_check_value("random", i32);
 3151             stress_set_setting("random", TYPE_ID_INT32, &i32);
 3152             break;
 3153         case OPT_sched:
 3154             i32 = stress_get_opt_sched(optarg);
 3155             stress_set_setting_global("sched", TYPE_ID_INT32, &i32);
 3156             break;
 3157         case OPT_sched_prio:
 3158             i32 = stress_get_int32(optarg);
 3159             stress_set_setting_global("sched-prio", TYPE_ID_INT32, &i32);
 3160             break;
 3161         case OPT_sched_period:
 3162             u64 = stress_get_uint64(optarg);
 3163             stress_set_setting_global("sched-period", TYPE_ID_UINT64, &u64);
 3164             break;
 3165         case OPT_sched_runtime:
 3166             u64 = stress_get_uint64(optarg);
 3167             stress_set_setting_global("sched-runtime", TYPE_ID_UINT64, &u64);
 3168             break;
 3169         case OPT_sched_deadline:
 3170             u64 = stress_get_uint64(optarg);
 3171             stress_set_setting_global("sched-deadline", TYPE_ID_UINT64, &u64);
 3172             break;
 3173         case OPT_sched_reclaim:
 3174             g_opt_flags |= OPT_FLAGS_DEADLINE_GRUB;
 3175             break;
 3176         case OPT_seed:
 3177             u64 = stress_get_uint64(optarg);
 3178             g_opt_flags |= OPT_FLAGS_SEED;
 3179             stress_set_setting_global("seed", TYPE_ID_UINT64, &u64);
 3180             break;
 3181         case OPT_sequential:
 3182             g_opt_flags |= OPT_FLAGS_SEQUENTIAL;
 3183             g_opt_sequential = stress_get_int32(optarg);
 3184             stress_get_processors(&g_opt_sequential);
 3185             stress_check_range("sequential", (uint64_t)g_opt_sequential,
 3186                 MIN_SEQUENTIAL, MAX_SEQUENTIAL);
 3187             break;
 3188         case OPT_stressors:
 3189             stress_show_stressor_names();
 3190             exit(EXIT_SUCCESS);
 3191         case OPT_taskset:
 3192             if (stress_set_cpu_affinity(optarg) < 0)
 3193                 exit(EXIT_FAILURE);
 3194             break;
 3195         case OPT_temp_path:
 3196             if (stress_set_temp_path(optarg) < 0)
 3197                 exit(EXIT_FAILURE);
 3198             break;
 3199         case OPT_timeout:
 3200             g_opt_timeout = stress_get_uint64_time(optarg);
 3201             break;
 3202         case OPT_timer_slack:
 3203             (void)stress_set_timer_slack_ns(optarg);
 3204             break;
 3205         case OPT_version:
 3206             stress_version();
 3207             exit(EXIT_SUCCESS);
 3208         case OPT_vmstat:
 3209             if (stress_set_vmstat(optarg) < 0)
 3210                 exit(EXIT_FAILURE);
 3211             break;
 3212         case OPT_thermalstat:
 3213             if (stress_set_thermalstat(optarg) < 0)
 3214                 exit(EXIT_FAILURE);
 3215             break;
 3216         case OPT_iostat:
 3217             if (stress_set_iostat(optarg) < 0)
 3218                 exit(EXIT_FAILURE);
 3219             break;
 3220         case OPT_yaml:
 3221             stress_set_setting_global("yaml", TYPE_ID_STR, (void *)optarg);
 3222             break;
 3223         default:
 3224             if (!jobmode)
 3225                 (void)printf("Unknown option (%d)\n",c);
 3226             return EXIT_FAILURE;
 3227         }
 3228     }
 3229 
 3230     if (optind < argc) {
 3231         bool unicode = false;
 3232 
 3233         printf("Error: unrecognised option:");
 3234         while (optind < argc) {
 3235             printf(" %s", argv[optind]);
 3236             if (((argv[optind][0] & 0xff) == 0xe2) &&
 3237                 ((argv[optind][1] & 0xff) == 0x88)) {
 3238                 unicode = true;
 3239             }
 3240             optind++;
 3241         }
 3242         printf("\n");
 3243         if (unicode)
 3244             printf("note: a Unicode minus sign was used instead of an ASCII '-' for an option\n");
 3245         return EXIT_FAILURE;
 3246     }
 3247     return EXIT_SUCCESS;
 3248 }
 3249 
 3250 /*
 3251  *  stress_alloc_proc_resources()
 3252  *  allocate array of pids based on n pids required
 3253  */
 3254 static void stress_alloc_proc_resources(
 3255     pid_t **pids,
 3256     stress_stats_t ***stats,
 3257     const int32_t n)
 3258 {
 3259     *pids = calloc((size_t)n, sizeof(pid_t));
 3260     if (!*pids) {
 3261         pr_err("cannot allocate pid list\n");
 3262         stress_stressors_free();
 3263         exit(EXIT_FAILURE);
 3264     }
 3265 
 3266     *stats = calloc((size_t)n, sizeof(stress_stats_t *));
 3267     if (!*stats) {
 3268         pr_err("cannot allocate stats list\n");
 3269         free(*pids);
 3270         *pids = NULL;
 3271         stress_stressors_free();
 3272         exit(EXIT_FAILURE);
 3273     }
 3274 }
 3275 
 3276 /*
 3277  *  stress_set_default_timeout()
 3278  *  set timeout to a default value if not already set
 3279  */
 3280 static void stress_set_default_timeout(const uint64_t timeout)
 3281 {
 3282     char *action;
 3283 
 3284     if (g_opt_timeout == TIMEOUT_NOT_SET) {
 3285         g_opt_timeout = timeout;
 3286         action = "defaulting";
 3287     } else {
 3288         action = "setting";
 3289     }
 3290 
 3291     pr_inf("%s to a %" PRIu64 " second%s run per stressor\n",
 3292         action, g_opt_timeout,
 3293         stress_duration_to_str((double)g_opt_timeout));
 3294 }
 3295 
 3296 /*
 3297  *  stress_setup_sequential()
 3298  *  setup for sequential --seq mode stressors
 3299  */
 3300 static void stress_setup_sequential(const uint32_t class)
 3301 {
 3302     stress_stressor_t *ss;
 3303 
 3304     stress_set_default_timeout(60);
 3305 
 3306     for (ss = stressors_head; ss; ss = ss->next) {
 3307         if (ss->stressor->info->class & class)
 3308             ss->num_instances = g_opt_sequential;
 3309         stress_alloc_proc_resources(&ss->pids, &ss->stats, ss->num_instances);
 3310     }
 3311 }
 3312 
 3313 /*
 3314  *  stress_setup_parallel()
 3315  *  setup for parallel mode stressors
 3316  */
 3317 static void stress_setup_parallel(const uint32_t class)
 3318 {
 3319     stress_stressor_t *ss;
 3320 
 3321     stress_set_default_timeout(DEFAULT_TIMEOUT);
 3322 
 3323     for (ss = stressors_head; ss; ss = ss->next) {
 3324         if (ss->stressor->info->class & class)
 3325             ss->num_instances = g_opt_parallel;
 3326         /*
 3327          * Share bogo ops between processes equally, rounding up
 3328          * if nonzero bogo_ops
 3329          */
 3330         ss->bogo_ops = ss->num_instances ?
 3331             (ss->bogo_ops + (ss->num_instances - 1)) / ss->num_instances : 0;
 3332         if (ss->num_instances)
 3333             stress_alloc_proc_resources(&ss->pids, &ss->stats, ss->num_instances);
 3334     }
 3335 }
 3336 
 3337 /*
 3338  *  stress_run_sequential()
 3339  *  run stressors sequentially
 3340  */
 3341 static inline void stress_run_sequential(
 3342     double *duration,
 3343     bool *success,
 3344     bool *resource_success,
 3345     bool *metrics_success)
 3346 {
 3347     stress_stressor_t *ss;
 3348     stress_checksum_t *checksum = g_shared->checksums;
 3349 
 3350     /*
 3351      *  Step through each stressor one by one
 3352      */
 3353     for (ss = stressors_head; ss && keep_stressing_flag(); ss = ss->next) {
 3354         stress_stressor_t *next = ss->next;
 3355 
 3356         ss->next = NULL;
 3357         stress_run(ss, duration, success, resource_success,
 3358             metrics_success, &checksum);
 3359         ss->next = next;
 3360 
 3361     }
 3362 }
 3363 
 3364 /*
 3365  *  stress_run_parallel()
 3366  *  run stressors in parallel
 3367  */
 3368 static inline void stress_run_parallel(
 3369     double *duration,
 3370     bool *success,
 3371     bool *resource_success,
 3372     bool *metrics_success)
 3373 {
 3374     stress_checksum_t *checksum = g_shared->checksums;
 3375 
 3376     /*
 3377      *  Run all stressors in parallel
 3378      */
 3379     stress_run(stressors_head, duration, success, resource_success,
 3380             metrics_success, &checksum);
 3381 }
 3382 
 3383 /*
 3384  *  stress_mlock_executable()
 3385  *  try to mlock image into memory so it
 3386  *  won't get swapped out
 3387  */
 3388 static inline void stress_mlock_executable(void)
 3389 {
 3390 #if defined(MLOCKED_SECTION)
 3391     extern void *__start_mlocked_text;
 3392     extern void *__stop_mlocked_text;
 3393 
 3394     stress_mlock_region(&__start_mlocked_text, &__stop_mlocked_text);
 3395 #endif
 3396 }
 3397 
 3398 int main(int argc, char **argv, char **envp)
 3399 {
 3400     double duration = 0.0;          /* stressor run time in secs */
 3401     bool success = true;
 3402     bool resource_success = true;
 3403     bool metrics_success = true;
 3404     FILE *yaml;             /* YAML output file */
 3405     char *yaml_filename = NULL;     /* YAML file name */
 3406     char *log_filename;         /* log filename */
 3407     char *job_filename = NULL;      /* job filename */
 3408     int32_t ticks_per_sec;          /* clock ticks per second (jiffies) */
 3409     int32_t ionice_class = UNDEFINED;   /* ionice class */
 3410     int32_t ionice_level = UNDEFINED;   /* ionice level */
 3411     size_t i;
 3412     uint32_t class = 0;
 3413     const uint32_t cpus_online = (uint32_t)stress_get_processors_online();
 3414     const uint32_t cpus_configured = (uint32_t)stress_get_processors_configured();
 3415     int ret;
 3416 
 3417     /* Enable stress-ng stack smashing message */
 3418     stress_set_stack_smash_check_flag(true);
 3419 
 3420     if (stress_set_temp_path(".") < 0)
 3421         exit(EXIT_FAILURE);
 3422     stress_set_proc_name_init(argc, argv, envp);
 3423 
 3424     if (setjmp(g_error_env) == 1)
 3425         exit(EXIT_FAILURE);
 3426 
 3427     yaml = NULL;
 3428 
 3429     /* --exec stressor uses this to exec itself and then exit early */
 3430     if ((argc == 2) && !strcmp(argv[1], "--exec-exit"))
 3431         exit(EXIT_SUCCESS);
 3432 
 3433     stressors_head = NULL;
 3434     stressors_tail = NULL;
 3435     stress_mwc_reseed();
 3436 
 3437     (void)stress_get_pagesize();
 3438     stressor_set_defaults();
 3439     g_pgrp = getpid();
 3440 
 3441     if (stress_get_processors_configured() < 0) {
 3442         pr_err("sysconf failed, number of cpus configured "
 3443             "unknown: errno=%d: (%s)\n",
 3444             errno, strerror(errno));
 3445         exit(EXIT_FAILURE);
 3446     }
 3447     ticks_per_sec = stress_get_ticks_per_second();
 3448     if (ticks_per_sec < 0) {
 3449         pr_err("sysconf failed, clock ticks per second "
 3450             "unknown: errno=%d (%s)\n",
 3451             errno, strerror(errno));
 3452         exit(EXIT_FAILURE);
 3453     }
 3454 
 3455     ret = stress_parse_opts(argc, argv, false);
 3456     if (ret != EXIT_SUCCESS)
 3457         exit(ret);
 3458     /*
 3459      *  Load in job file options
 3460      */
 3461     (void)stress_get_setting("job", &job_filename);
 3462     if (stress_parse_jobfile(argc, argv, job_filename) < 0)
 3463         exit(EXIT_FAILURE);
 3464 
 3465     /*
 3466      *  Sanity check minimize/maximize options
 3467      */
 3468     if ((g_opt_flags & OPT_FLAGS_MINMAX_MASK) == OPT_FLAGS_MINMAX_MASK) {
 3469         (void)fprintf(stderr, "maximize and minimize cannot "
 3470             "be used together\n");
 3471         exit(EXIT_FAILURE);
 3472     }
 3473 
 3474     /*
 3475      *  Sanity check seq/all settings
 3476      */
 3477     if ((g_opt_flags & (OPT_FLAGS_SEQUENTIAL | OPT_FLAGS_ALL)) ==
 3478         (OPT_FLAGS_SEQUENTIAL | OPT_FLAGS_ALL)) {
 3479         (void)fprintf(stderr, "cannot invoke --sequential and --all "
 3480             "options together\n");
 3481         exit(EXIT_FAILURE);
 3482     }
 3483     (void)stress_get_setting("class", &class);
 3484 
 3485     if (class &&
 3486         !(g_opt_flags & (OPT_FLAGS_SEQUENTIAL | OPT_FLAGS_ALL))) {
 3487         (void)fprintf(stderr, "class option is only used with "
 3488             "--sequential or --all options\n");
 3489         exit(EXIT_FAILURE);
 3490     }
 3491 
 3492     /*
 3493      *  Sanity check mutually exclusive random seed flags
 3494      */
 3495     if ((g_opt_flags & (OPT_FLAGS_NO_RAND_SEED | OPT_FLAGS_SEED)) ==
 3496         (OPT_FLAGS_NO_RAND_SEED | OPT_FLAGS_SEED)) {
 3497         (void)fprintf(stderr, "cannot invoke mutually exclusive "
 3498             "--seed and --no-rand-seed options together\n");
 3499         exit(EXIT_FAILURE);
 3500     }
 3501 
 3502     /*
 3503      *  Setup logging
 3504      */
 3505     if (stress_get_setting("log-file", &log_filename))
 3506         pr_openlog(log_filename);
 3507     shim_openlog("stress-ng", 0, LOG_USER);
 3508     stress_log_args(argc, argv);
 3509     stress_log_system_info();
 3510     stress_log_system_mem_info();
 3511 
 3512     pr_runinfo();
 3513     pr_dbg("%" PRId32 " processor%s online, %" PRId32
 3514         " processor%s configured\n",
 3515         cpus_online, cpus_online == 1 ? "" : "s",
 3516         cpus_configured, cpus_configured == 1 ? "" : "s");
 3517 
 3518     /*
 3519      *  For random mode the stressors must be available
 3520      */
 3521     if (g_opt_flags & OPT_FLAGS_RANDOM)
 3522         stress_enable_all_stressors(0);
 3523     /*
 3524      *  These two options enable all the stressors
 3525      */
 3526     if (g_opt_flags & OPT_FLAGS_SEQUENTIAL)
 3527         stress_enable_all_stressors(g_opt_sequential);
 3528     if (g_opt_flags & OPT_FLAGS_ALL)
 3529         stress_enable_all_stressors(g_opt_parallel);
 3530 
 3531     /*
 3532      *  Discard stressors that we can't run
 3533      */
 3534     stress_exclude_unsupported();
 3535     stress_exclude_pathological();
 3536     /*
 3537      *  Throw away excluded stressors
 3538      */
 3539     if (stress_exclude() < 0)
 3540         exit(EXIT_FAILURE);
 3541 
 3542     /*
 3543      *  Setup random stressors if requested
 3544      */
 3545     stress_set_random_stressors();
 3546 
 3547     (void)stress_ftrace_start();
 3548 #if defined(STRESS_PERF_STATS) &&   \
 3549     defined(HAVE_LINUX_PERF_EVENT_H)
 3550     if (g_opt_flags & OPT_FLAGS_PERF_STATS)
 3551         stress_perf_init();
 3552 #endif
 3553 
 3554     /*
 3555      *  Setup running environment
 3556      */
 3557     stress_process_dumpable(false);
 3558     stress_cwd_readwriteable();
 3559     stress_set_oom_adjustment("main", false);
 3560 
 3561     /*
 3562      *  Get various user defined settings
 3563      */
 3564     if (sched_settings_apply(false) < 0)
 3565         exit(EXIT_FAILURE);
 3566     (void)stress_get_setting("ionice-class", &ionice_class);
 3567     (void)stress_get_setting("ionice-level", &ionice_level);
 3568     stress_set_iopriority(ionice_class, ionice_level);
 3569     (void)stress_get_setting("yaml", &yaml_filename);
 3570 
 3571     stress_mlock_executable();
 3572 
 3573     /*
 3574      *  Enable signal handers
 3575      */
 3576     for (i = 0; i < SIZEOF_ARRAY(terminate_signals); i++) {
 3577         if (stress_sighandler("stress-ng", terminate_signals[i], stress_handle_terminate, NULL) < 0)
 3578             exit(EXIT_FAILURE);
 3579     }
 3580     /*
 3581      *  Ignore other signals
 3582      */
 3583     for (i = 0; i < SIZEOF_ARRAY(ignore_signals); i++) {
 3584         ret = stress_sighandler("stress-ng", ignore_signals[i], SIG_IGN, NULL);
 3585         (void)ret;  /* We don't care if it fails */
 3586     }
 3587 
 3588     /*
 3589      *  Setup stressor proc info
 3590      */
 3591     if (g_opt_flags & OPT_FLAGS_SEQUENTIAL) {
 3592         stress_setup_sequential(class);
 3593     } else {
 3594         stress_setup_parallel(class);
 3595     }
 3596     /*
 3597      *  Seq/parallel modes may have added in
 3598      *  excluded stressors, so exclude check again
 3599      */
 3600     stress_exclude_unsupported();
 3601     stress_exclude_pathological();
 3602 
 3603     stress_set_proc_limits();
 3604 
 3605     if (!stressors_head) {
 3606         pr_err("No stress workers invoked%s\n",
 3607             g_unsupported ? " (one or more were unsupported)" : "");
 3608         stress_stressors_free();
 3609         /*
 3610          *  If some stressors were given but marked as
 3611          *  unsupported then this is not an error.
 3612          */
 3613         exit(g_unsupported ? EXIT_SUCCESS : EXIT_FAILURE);
 3614     }
 3615 
 3616     /*
 3617      *  Show the stressors we're going to run
 3618      */
 3619     if (stress_show_stressors() < 0) {
 3620         stress_stressors_free();
 3621         exit(EXIT_FAILURE);
 3622     }
 3623 
 3624     /*
 3625      *  Allocate shared memory segment for shared data
 3626      *  across all the child stressors
 3627      */
 3628     stress_shared_map(stress_get_total_num_instances(stressors_head));
 3629 
 3630     /*
 3631      *  Setup spinlocks
 3632      */
 3633 #if defined(STRESS_PERF_STATS) &&   \
 3634     defined(HAVE_LINUX_PERF_EVENT_H)
 3635     shim_pthread_spin_init(&g_shared->perf.lock, 0);
 3636 #endif
 3637 #if defined(HAVE_LIB_PTHREAD)
 3638     shim_pthread_spin_init(&g_shared->warn_once.lock, 0);
 3639 #endif
 3640 
 3641     /*
 3642      *  Assign procs with shared stats memory
 3643      */
 3644     stress_setup_stats_buffers();
 3645 
 3646     /*
 3647      *  Allocate shared cache memory
 3648      */
 3649     g_shared->mem_cache_level = DEFAULT_CACHE_LEVEL;
 3650     (void)stress_get_setting("cache-level", &g_shared->mem_cache_level);
 3651     g_shared->mem_cache_ways = 0;
 3652     (void)stress_get_setting("cache-ways", &g_shared->mem_cache_ways);
 3653     if (stress_cache_alloc("cache allocate") < 0) {
 3654         stress_shared_unmap();
 3655         stress_stressors_free();
 3656         exit(EXIT_FAILURE);
 3657     }
 3658 
 3659 #if defined(STRESS_THERMAL_ZONES)
 3660     /*
 3661      *  Setup thermal zone data
 3662      */
 3663     if (g_opt_flags & OPT_FLAGS_THERMAL_ZONES)
 3664         stress_tz_init(&g_shared->tz_info);
 3665 #endif
 3666 
 3667     stress_stressors_init();
 3668 
 3669     /* Start thrasher process if required */
 3670     if (g_opt_flags & OPT_FLAGS_THRASH)
 3671         stress_thrash_start();
 3672 
 3673     stress_vmstat_start();
 3674     stress_smart_start();
 3675 
 3676     if (g_opt_flags & OPT_FLAGS_SEQUENTIAL) {
 3677         stress_run_sequential(&duration,
 3678             &success, &resource_success, &metrics_success);
 3679     } else {
 3680         stress_run_parallel(&duration,
 3681             &success, &resource_success, &metrics_success);
 3682     }
 3683 
 3684     /* Stop thasher process */
 3685     if (g_opt_flags & OPT_FLAGS_THRASH)
 3686         stress_thrash_stop();
 3687 
 3688     pr_inf("%s run completed in %.2fs%s\n",
 3689         success ? "successful" : "unsuccessful",
 3690         duration, stress_duration_to_str(duration));
 3691 
 3692     /*
 3693      *  Save results to YAML file
 3694      */
 3695     if (yaml_filename) {
 3696         yaml = fopen(yaml_filename, "w");
 3697         if (!yaml)
 3698             pr_err("Cannot output YAML data to %s\n", yaml_filename);
 3699 
 3700         pr_yaml(yaml, "---\n");
 3701         pr_yaml_runinfo(yaml);
 3702     }
 3703 
 3704     /*
 3705      *  Dump metrics
 3706      */
 3707     if (g_opt_flags & OPT_FLAGS_METRICS)
 3708         stress_metrics_dump(yaml, ticks_per_sec);
 3709 
 3710     stress_metrics_check(&success);
 3711 
 3712 #if defined(STRESS_PERF_STATS) &&   \
 3713     defined(HAVE_LINUX_PERF_EVENT_H)
 3714     /*
 3715      *  Dump perf statistics
 3716      */
 3717     if (g_opt_flags & OPT_FLAGS_PERF_STATS)
 3718         stress_perf_stat_dump(yaml, stressors_head, duration);
 3719 #endif
 3720 
 3721 #if defined(STRESS_THERMAL_ZONES)
 3722     /*
 3723      *  Dump thermal zone measurements
 3724      */
 3725     if (g_opt_flags & OPT_FLAGS_THERMAL_ZONES) {
 3726         stress_tz_dump(yaml, stressors_head);
 3727         stress_tz_free(&g_shared->tz_info);
 3728     }
 3729 #endif
 3730     /*
 3731      *  Dump run times
 3732      */
 3733     stress_times_dump(yaml, ticks_per_sec, duration);
 3734 
 3735     stress_smart_stop();
 3736     stress_vmstat_stop();
 3737     stress_ftrace_stop();
 3738     stress_ftrace_free();
 3739 
 3740     /*
 3741      *  Tidy up
 3742      */
 3743     stress_stressors_deinit();
 3744     stress_stressors_free();
 3745     stress_cache_free();
 3746     stress_shared_unmap();
 3747     stress_settings_free();
 3748     stress_temp_path_free();
 3749 
 3750     /*
 3751      *  Close logs
 3752      */
 3753     shim_closelog();
 3754     pr_closelog();
 3755     if (yaml) {
 3756         pr_yaml(yaml, "...\n");
 3757         (void)fclose(yaml);
 3758     }
 3759 
 3760     /*
 3761      *  Done!
 3762      */
 3763     if (!success)
 3764         exit(EXIT_NOT_SUCCESS);
 3765     if (!resource_success)
 3766         exit(EXIT_NO_RESOURCE);
 3767     if (!metrics_success)
 3768         exit(EXIT_METRICS_UNTRUSTWORTHY);
 3769     exit(EXIT_SUCCESS);
 3770 }