"Fossies" - the Fresh Open Source Software Archive

Member "stress-ng-0.09.56/stress-watchdog.c" (15 Mar 2019, 4958 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-watchdog.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(HAVE_LINUX_WATCHDOG_H) 
   28 
   29 static sigjmp_buf jmp_env;
   30 
   31 static const int sigs[] = {
   32 #if defined(SIGILL)
   33     SIGILL,
   34 #endif
   35 #if defined(SIGTRAP)
   36     SIGTRAP,
   37 #endif
   38 #if defined(SIGFPE)
   39     SIGFPE,
   40 #endif
   41 #if defined(SIGBUS)
   42     SIGBUS,
   43 #endif
   44 #if defined(SIGSEGV)
   45     SIGSEGV,
   46 #endif
   47 #if defined(SIGIOT)
   48     SIGIOT,
   49 #endif
   50 #if defined(SIGEMT)
   51     SIGEMT,
   52 #endif
   53 #if defined(SIGALRM)
   54     SIGALRM,
   55 #endif
   56 #if defined(SIGINT)
   57     SIGINT,
   58 #endif
   59 #if defined(SIGHUP)
   60     SIGHUP
   61 #endif
   62 };
   63 
   64 static const char *dev_watchdog = "/dev/watchdog";
   65 static int fd;
   66 
   67 static void stress_watchdog_magic_close(void)
   68 {
   69     /*
   70      *  Some watchdog drivers support the magic close option
   71      *  where writing "V" will forcefully disable the watchdog
   72      */
   73     if (fd >= 0) {
   74         int ret;
   75 
   76         ret = write(fd, "V", 1);
   77         (void)ret;
   78     }
   79 }
   80 
   81 static void MLOCKED_TEXT stress_watchdog_handler(int signum)
   82 {
   83     (void)signum;
   84 
   85     stress_watchdog_magic_close();
   86 
   87     /* trigger early termination */
   88     g_keep_stressing_flag = 0;
   89 
   90     /* jump back */
   91         siglongjmp(jmp_env, 1);
   92 }
   93 
   94 /*
   95  *  stress_watchdog()
   96  *  stress /dev/watchdog
   97  */
   98 static int stress_watchdog(const args_t *args)
   99 {
  100     int ret, rc = EXIT_SUCCESS;
  101     size_t i;
  102 
  103     fd = -1;
  104     for (i = 0; i < SIZEOF_ARRAY(sigs); i++) {
  105         if (stress_sighandler(args->name, sigs[i], stress_watchdog_handler, NULL) < 0)
  106             return EXIT_FAILURE;
  107     }
  108 
  109     /*
  110      *  Sanity check for existence and r/w permissions
  111      *  on /dev/shm, it may not be configure for the
  112      *  kernel, so don't make it a failure of it does
  113      *  not exist or we can't access it.
  114      */
  115     if (access(dev_watchdog, R_OK | W_OK) < 0) {
  116         if (errno == ENOENT) {
  117             pr_inf("%s: %s does not exist, skipping test\n",
  118                 args->name, dev_watchdog);
  119             return EXIT_SUCCESS;
  120         } else {
  121             pr_inf("%s: cannot access %s, errno=%d (%s), skipping test\n",
  122                 args->name, dev_watchdog, errno, strerror(errno));
  123             return EXIT_SUCCESS;
  124         }
  125     }
  126 
  127     fd = 0;
  128     ret = sigsetjmp(jmp_env, 1);
  129     if (ret) {
  130         /* We got interrupted, so abort cleanly */
  131         if (fd >= 0) {
  132             stress_watchdog_magic_close();
  133             (void)close(fd);
  134         }
  135         return EXIT_SUCCESS;
  136     }
  137 
  138     while (keep_stressing()) {
  139         fd = open(dev_watchdog, O_RDWR);
  140 
  141         /* Mutiple stressors can lock the device, so retry */
  142         if (fd < 0) {
  143             struct timespec tv;
  144 
  145             tv.tv_sec = 0;
  146             tv.tv_nsec = 10000;
  147             (void)nanosleep(&tv, NULL);
  148             continue;
  149         }
  150 
  151         stress_watchdog_magic_close();
  152 
  153 #if defined(WDIOC_KEEPALIVE)
  154         ret = ioctl(fd, WDIOC_KEEPALIVE, 0);
  155         (void)ret;
  156 #endif
  157 
  158 #if defined(WDIOC_GETTIMEOUT)
  159         {
  160             int timeout;
  161 
  162             ret = ioctl(fd, WDIOC_GETTIMEOUT, &timeout);
  163             (void)ret;
  164         }
  165 #endif
  166 
  167 #if defined(WDIOC_GETPRETIMEOUT)
  168         {
  169             int timeout;
  170 
  171             ret = ioctl(fd, WDIOC_GETPRETIMEOUT, &timeout);
  172             (void)ret;
  173         }
  174 #endif
  175 
  176 #if defined(WDIOC_GETPRETIMEOUT)
  177         {
  178             int timeout;
  179 
  180             ret = ioctl(fd, WDIOC_GETTIMELEFT, &timeout);
  181             (void)ret;
  182         }
  183 #endif
  184 
  185 #if defined(WDIOC_GETSUPPORT)
  186         {
  187             struct watchdog_info ident;
  188 
  189             ret = ioctl(fd, WDIOC_GETSUPPORT, &ident);
  190             (void)ret;
  191         }
  192 #endif
  193 
  194 #if defined(WDIOC_GETSTATUS)
  195         {
  196             int flags;
  197 
  198             ret = ioctl(fd, WDIOC_GETSTATUS, &flags);
  199             (void)ret;
  200         }
  201 #endif
  202 
  203 #if defined(WDIOC_GETBOOTSTATUS)
  204         {
  205             int flags;
  206 
  207             ret = ioctl(fd, WDIOC_GETBOOTSTATUS, &flags);
  208             (void)ret;
  209         }
  210 #endif
  211 
  212 #if defined(WDIOC_GETTEMP)
  213         {
  214             int temperature;
  215 
  216             ret = ioctl(fd, WDIOC_GETBOOTSTATUS, &temperature);
  217             (void)ret;
  218         }
  219 #endif
  220         stress_watchdog_magic_close();
  221         ret = close(fd);
  222         fd = -1;
  223         if (ret < 0) {
  224             pr_fail("%s: cannot close %s, errno=%d (%s)\n",
  225                 args->name, dev_watchdog, errno, strerror(errno));
  226             rc = EXIT_FAILURE;
  227             break;
  228         }
  229         (void)shim_sched_yield();
  230         inc_counter(args);
  231     }
  232 
  233     return rc;
  234 }
  235 
  236 stressor_info_t stress_watchdog_info = {
  237     .stressor = stress_watchdog,
  238     .class = CLASS_VM | CLASS_OS | CLASS_PATHOLOGICAL
  239 };
  240 #else
  241 stressor_info_t stress_watchdog_info = {
  242     .stressor = stress_not_implemented,
  243     .class = CLASS_VM | CLASS_OS | CLASS_PATHOLOGICAL
  244 };
  245 #endif