"Fossies" - the Fresh Open Source Software Archive

Member "stress-ng-0.09.56/stress-spawn.c" (15 Mar 2019, 3453 Bytes) of package /linux/privat/stress-ng-0.09.56.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-spawn.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 0.09.50_vs_0.09.51.

    1 /*
    2  * Copyright (C) 2013-2019 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 #if defined(HAVE_SPAWN_H) &&    \
   28     defined(HAVE_POSIX_SPAWN)
   29 
   30 /*
   31  *  stress_spawn_supported()
   32  *      check that we don't run this as root
   33  */
   34 static int stress_spawn_supported(void)
   35 {
   36     /*
   37      *  Don't want to run this when running as root as
   38      *  this could allow somebody to try and run another
   39      *  executable as root.
   40      */
   41         if (geteuid() == 0) {
   42         pr_inf("spawn stressor must not run as root, skipping the stressor\n");
   43                 return -1;
   44         }
   45         return 0;
   46 }
   47 
   48 /*
   49  *  stress_spawn()
   50  *  stress by forking and spawn'ing
   51  */
   52 static int stress_spawn(const args_t *args)
   53 {
   54     char path[PATH_MAX + 1];
   55     ssize_t len;
   56     uint64_t spawn_fails = 0, spawn_calls = 0;
   57     static char *argv_new[] = { NULL, "--exec-exit", NULL };
   58     static char *env_new[] = { NULL };
   59 
   60     /*
   61      *  Don't want to run this when running as root as
   62      *  this could allow somebody to try and run another
   63      *  spawnable as root.
   64      */
   65     if (geteuid() == 0) {
   66         pr_inf("%s: running as root, won't run test.\n", args->name);
   67         return EXIT_FAILURE;
   68     }
   69 
   70     /*
   71      *  Determine our own self as the spawnutable, e.g. run stress-ng
   72      */
   73     len = readlink("/proc/self/exe", path, sizeof(path));
   74     if (len < 0 || len > PATH_MAX) {
   75         if (errno == ENOENT) {
   76             pr_inf("%s: skipping stressor, can't determine stress-ng "
   77                 "executable name\n", args->name);
   78             return EXIT_NOT_IMPLEMENTED;
   79         }
   80         pr_fail("%s: readlink on /proc/self/exe failed\n", args->name);
   81         return EXIT_FAILURE;
   82     }
   83     path[len] = '\0';
   84     argv_new[0] = path;
   85 
   86     do {
   87         int ret;
   88         pid_t pid;
   89 
   90         spawn_calls++;
   91         ret = posix_spawn(&pid, path, NULL, NULL, argv_new, env_new);
   92         if (ret < 0) {
   93             pr_fail_err("posix_spawn()");
   94             spawn_fails++;
   95         } else {
   96             int status;
   97             /* Parent, wait for child */
   98 
   99             (void)waitpid(pid, &status, 0);
  100             inc_counter(args);
  101             if (WEXITSTATUS(status) != EXIT_SUCCESS)
  102                 spawn_fails++;
  103         }
  104     } while (keep_stressing());
  105 
  106     if ((spawn_fails > 0) && (g_opt_flags & OPT_FLAGS_VERIFY)) {
  107         pr_fail("%s: %" PRIu64 " spawns failed (%.2f%%)\n",
  108             args->name, spawn_fails,
  109             (double)spawn_fails * 100.0 / (double)(spawn_calls));
  110     }
  111 
  112     return EXIT_SUCCESS;
  113 }
  114 
  115 stressor_info_t stress_spawn_info = {
  116     .stressor = stress_spawn,
  117     .supported = stress_spawn_supported,
  118     .class = CLASS_SCHEDULER | CLASS_OS
  119 };
  120 #else
  121 stressor_info_t stress_spawn_info = {
  122     .stressor = stress_not_implemented,
  123     .class = CLASS_SCHEDULER | CLASS_OS
  124 };
  125 #endif