"Fossies" - the Fresh Open Source Software Archive

Member "stress-ng-0.09.56/core-job.c" (15 Mar 2019, 4698 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 "core-job.c" see the Fossies "Dox" file reference documentation.

    1 /*
    2  * Copyright (C) 2017-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 #define MAX_ARGS    (64)
   28 #define RUN_SEQUENTIAL  (0x01)
   29 #define RUN_PARALLEL    (0x02)
   30 
   31 #define ISBLANK(ch) isblank((int)(ch))
   32 
   33 /*
   34  *  chop()
   35  *  chop off end of line that matches char ch
   36  */
   37 static void chop(char *str, const char ch)
   38 {
   39     char *ptr = strchr(str, ch);
   40 
   41     if (ptr)
   42         *ptr = '\0';
   43 }
   44 
   45 /*
   46  *  parse_run()
   47  *  parse the special job file "run" command
   48  *  that informs stress-ng to run the job file
   49  *  stressors sequentially or in parallel
   50  */
   51 static int parse_run(
   52     const char *jobfile,
   53     int argc,
   54     char **argv,
   55     uint32_t *flag)
   56 {
   57     if (argc < 3)
   58         return 0;
   59     if (strcmp(argv[1], "run"))
   60         return 0;
   61 
   62     if (!strcmp(argv[2], "sequential") ||
   63         !strcmp(argv[2], "sequentially") ||
   64             !strcmp(argv[2], "seq")) {
   65         if (*flag & RUN_PARALLEL)
   66             goto err;
   67         *flag |= RUN_SEQUENTIAL;
   68         g_opt_flags |= OPT_FLAGS_SEQUENTIAL;
   69         return 1;
   70     }
   71     if (!strcmp(argv[2], "parallel") ||
   72             !strcmp(argv[2], "par") ||
   73         !strcmp(argv[2], "together")) {
   74         if (*flag & RUN_SEQUENTIAL)
   75             goto err;
   76         *flag |= RUN_PARALLEL;
   77         g_opt_flags &= ~OPT_FLAGS_SEQUENTIAL;
   78         g_opt_flags |= OPT_FLAGS_ALL;
   79         return 1;
   80     }
   81 err:
   82     (void)fprintf(stderr, "Cannot have both run sequential "
   83         "and run parallel in jobfile %s\n",
   84         jobfile);
   85     return -1;
   86 }
   87 
   88 /*
   89  *  generic job error message
   90  */
   91 static void parse_error(
   92     const uint32_t lineno,
   93     const char *line)
   94 {
   95     fprintf(stderr, "error in line %" PRIu32 ": '%s'\n",
   96         lineno, line);
   97 }
   98 
   99 /*
  100  *  parse_jobfile()
  101  *  parse a jobfile, turn job commands into
  102  *  individual stress-ng options
  103  */
  104 int parse_jobfile(
  105     const int argc,
  106     char **argv,
  107     const char *jobfile)
  108 {
  109     NOCLOBBER FILE *fp;
  110     char buf[4096];
  111     char *new_argv[MAX_ARGS];
  112     char txt[sizeof(buf)];
  113     int ret;
  114     uint32_t flag;
  115     static uint32_t lineno;
  116 
  117     if (!jobfile) {
  118         if (argc < 2)
  119             return 0;
  120         fp = fopen(argv[1], "r");
  121         if (!fp)
  122             return 0;
  123     } else {
  124         fp = fopen(jobfile, "r");
  125     }
  126     if (!fp) {
  127         (void)fprintf(stderr, "Cannot open jobfile '%s'\n", jobfile);
  128         return -1;
  129     }
  130 
  131     if (setjmp(g_error_env) == 1) {
  132         parse_error(lineno, txt);
  133         ret = -1;
  134         goto err;
  135     }
  136 
  137     flag = 0;
  138     ret = -1;
  139 
  140     while (fgets(buf, sizeof(buf), fp)) {
  141         char *ptr = buf;
  142         int new_argc = 1;
  143 
  144         (void)memset(new_argv, 0, sizeof(new_argv));
  145         new_argv[0] = argv[0];
  146         lineno++;
  147 
  148         /* remove \n */
  149         chop(buf, '\n');
  150         (void)shim_strlcpy(txt, buf, sizeof(txt) - 1);
  151 
  152         /* remove comments */
  153         chop(buf, '#');
  154 
  155         if (!*ptr)
  156             continue;
  157 
  158         /* skip leading blanks */
  159         while (ISBLANK(*ptr))
  160             ptr++;
  161 
  162         while (new_argc < MAX_ARGS && *ptr) {
  163             new_argv[new_argc++] = ptr;
  164 
  165             /* eat up chars until eos or blank */
  166             while (*ptr && !ISBLANK(*ptr))
  167                 ptr++;
  168 
  169             if (!*ptr)
  170                 break;
  171             *ptr++ = '\0';
  172 
  173             /* skip over blanks */
  174             while (ISBLANK(*ptr))
  175                 ptr++;
  176         }
  177 
  178         /* managed to get any tokens? */
  179         if (new_argc > 1) {
  180             const size_t len = strlen(new_argv[1]) + 3;
  181             char tmp[len];
  182             int rc;
  183 
  184             /* Must check for --job -h option! */
  185             if (!strcmp(new_argv[1], "job") ||
  186                 !strcmp(new_argv[1], "j")) {
  187                 fprintf(stderr, "Cannot read job file in from a job script!\n");
  188                 goto err;
  189             }
  190 
  191             /* Check for job run option */
  192             rc = parse_run(jobfile, new_argc, new_argv, &flag);
  193             if (rc < 0) {
  194                 ret = -1;
  195                 parse_error(lineno, txt);
  196                 goto err;
  197             } else if (rc == 1) {
  198                 continue;
  199             }
  200 
  201             /* prepend -- to command to make them into stress-ng options */
  202             (void)snprintf(tmp, len, "--%s", new_argv[1]);
  203             new_argv[1] = tmp;
  204             if (parse_opts(new_argc, new_argv, true) != EXIT_SUCCESS) {
  205                 parse_error(lineno, txt);
  206                 ret = -1;
  207                 goto err;
  208             }
  209             new_argv[1] = NULL;
  210         }
  211     }
  212     ret = 0;
  213 err:
  214     (void)fclose(fp);
  215 
  216     return ret;
  217 }