"Fossies" - the Fresh Open Source Software Archive

Member "stress-ng-0.09.56/stress-lease.c" (15 Mar 2019, 4867 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-lease.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 0.09.52_vs_0.09.54.

    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(F_SETLEASE) && defined(F_WRLCK) && defined(F_UNLCK)
   28 
   29 static uint64_t lease_sigio;
   30 #endif
   31 
   32 int stress_set_lease_breakers(const char *opt)
   33 {
   34     uint64_t lease_breakers;
   35 
   36     lease_breakers = get_uint64(opt);
   37     check_range("lease-breakers", lease_breakers,
   38         MIN_LEASE_BREAKERS, MAX_LEASE_BREAKERS);
   39     return set_setting("lease-breakers", TYPE_ID_UINT64, &lease_breakers);
   40 }
   41 
   42 #if defined(F_SETLEASE) && defined(F_WRLCK) && defined(F_UNLCK)
   43 
   44 /*
   45  *  stress_lease_handler()
   46  *  lease signal handler
   47  */
   48 static void MLOCKED_TEXT stress_lease_handler(int signum)
   49 {
   50     (void)signum;
   51 
   52     lease_sigio++;
   53 }
   54 
   55 /*
   56  *  stress_lease_spawn()
   57  *  spawn a process
   58  */
   59 static pid_t stress_lease_spawn(
   60     const args_t *args,
   61     const char *filename)
   62 {
   63     pid_t pid;
   64 
   65 again:
   66     pid = fork();
   67     if (pid < 0) {
   68         if (g_keep_stressing_flag &&
   69             ((errno == EAGAIN) || (errno == ENOMEM)))
   70             goto again;
   71         return -1;
   72     }
   73     if (pid == 0) {
   74         (void)setpgid(0, g_pgrp);
   75         stress_parent_died_alarm();
   76 
   77         do {
   78             int fd;
   79 
   80             errno = 0;
   81             fd = open(filename, O_NONBLOCK | O_WRONLY, S_IRUSR | S_IWUSR);
   82             if (fd < 0) {
   83                 if (errno != EWOULDBLOCK && errno != EACCES) {
   84                     pr_dbg("%s: open failed (child): errno=%d: (%s)\n",
   85                         args->name, errno, strerror(errno));
   86                 }
   87                 continue;
   88             }
   89             (void)close(fd);
   90         } while (keep_stressing());
   91         _exit(EXIT_SUCCESS);
   92     }
   93     (void)setpgid(pid, g_pgrp);
   94     return pid;
   95 }
   96 
   97 /*
   98  *  stress_lease
   99  *  stress by fcntl lease activity
  100  */
  101 static int stress_lease(const args_t *args)
  102 {
  103     char filename[PATH_MAX];
  104     int ret, fd, status;
  105     pid_t l_pids[MAX_LEASE_BREAKERS];
  106     uint64_t i, lease_breakers = DEFAULT_LEASE_BREAKERS;
  107 
  108     if (!get_setting("lease-breakers", &lease_breakers)) {
  109         if (g_opt_flags & OPT_FLAGS_MAXIMIZE)
  110             lease_breakers = MAX_LEASE_BREAKERS;
  111         if (g_opt_flags & OPT_FLAGS_MINIMIZE)
  112             lease_breakers = MIN_LEASE_BREAKERS;
  113     }
  114 
  115     (void)memset(l_pids, 0, sizeof(l_pids));
  116 
  117     if (stress_sighandler(args->name, SIGIO, stress_lease_handler, NULL) < 0)
  118         return EXIT_FAILURE;
  119 
  120     ret = stress_temp_dir_mk_args(args);
  121     if (ret < 0)
  122         return exit_status(-ret);
  123     (void)stress_temp_filename_args(args,
  124         filename, sizeof(filename), mwc32());
  125 
  126     fd = creat(filename, S_IRUSR | S_IWUSR);
  127     if (fd < 0) {
  128         ret = exit_status(errno);
  129         pr_err("%s: creat failed: errno=%d: (%s)\n",
  130             args->name, errno, strerror(errno));
  131         (void)stress_temp_dir_rm_args(args);
  132         return ret;
  133     }
  134     (void)close(fd);
  135 
  136     for (i = 0; i < lease_breakers; i++) {
  137         l_pids[i] = stress_lease_spawn(args, filename);
  138         if (l_pids[i] < 0) {
  139             pr_err("%s: failed to start all the lease breaker processes\n", args->name);
  140             goto reap;
  141         }
  142     }
  143 
  144     do {
  145         fd = open(filename, O_WRONLY | O_APPEND, S_IRUSR | S_IWUSR);
  146         if (fd < 0) {
  147             ret = exit_status(errno);
  148             pr_err("%s: open failed (parent): errno=%d: (%s)\n",
  149                 args->name, errno, strerror(errno));
  150             goto reap;
  151         }
  152         while (fcntl(fd, F_SETLEASE, F_WRLCK) < 0) {
  153             if (!g_keep_stressing_flag) {
  154                 (void)close(fd);
  155                 goto reap;
  156             }
  157         }
  158         inc_counter(args);
  159         (void)shim_sched_yield();
  160         if (fcntl(fd, F_SETLEASE, F_UNLCK) < 0) {
  161             pr_err("%s: fcntl failed: errno=%d: (%s)\n",
  162                 args->name, errno, strerror(errno));
  163             (void)close(fd);
  164             break;
  165         }
  166         (void)close(fd);
  167     } while (keep_stressing());
  168 
  169     ret = EXIT_SUCCESS;
  170 
  171 reap:
  172     for (i = 0; i < lease_breakers; i++) {
  173         if (l_pids[i]) {
  174             (void)kill(l_pids[i], SIGKILL);
  175             (void)waitpid(l_pids[i], &status, 0);
  176         }
  177     }
  178 
  179     (void)unlink(filename);
  180     (void)stress_temp_dir_rm_args(args);
  181 
  182     pr_dbg("%s: %" PRIu64 " lease sigio interrupts caught\n", args->name, lease_sigio);
  183 
  184     return ret;
  185 }
  186 
  187 stressor_info_t stress_lease_info = {
  188     .stressor = stress_lease,
  189     .class = CLASS_FILESYSTEM | CLASS_OS
  190 };
  191 #else
  192 stressor_info_t stress_lease_info = {
  193     .stressor = stress_not_implemented,
  194     .class = CLASS_FILESYSTEM | CLASS_OS
  195 };
  196 #endif