"Fossies" - the Fresh Open Source Software Archive

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

    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_RTC_H)
   28 
   29 /*
   30  *  RTC interfaces, as described by
   31  *      Documentation/rtc.txt
   32  */
   33 static const char *interfaces[] = {
   34     "date",
   35     "hctosys",
   36     "max_user_freq",
   37     "name",
   38     "since_epoch",
   39     "time",
   40     "wakealarm",
   41     "offset"
   42 };
   43 
   44 static inline int stress_rtc_dev(const args_t *args)
   45 {
   46 #if defined(RTC_RD_TIME) || defined(RTC_ALM_READ) || \
   47     defined(RTC_WKALM_RD) || defined(RTC_IRQP_READ)
   48     struct rtc_time rtc_tm;
   49     struct rtc_wkalrm wake_alarm;
   50     unsigned long tmp;
   51 #endif
   52     int fd, ret = 0;
   53     static bool do_dev = true;
   54     struct timeval timeout;
   55     fd_set rfds;
   56 
   57     if (!do_dev)
   58         return -EACCES;
   59 
   60     if ((fd = open("/dev/rtc", O_RDONLY)) < 0) {
   61         do_dev = false;
   62         return -errno;
   63     }
   64 
   65 #if defined(RTC_RD_TIME)
   66     if (ioctl(fd, RTC_RD_TIME, &rtc_tm) < 0) {
   67         if (errno != ENOTTY) {
   68             pr_fail_err("ioctl RTC_RD_TIME");
   69             ret = -errno;
   70             goto err;
   71         }
   72     }
   73 #endif
   74 
   75 #if defined(RTC_ALM_READ)
   76     if (ioctl(fd, RTC_ALM_READ, &wake_alarm) < 0) {
   77         if (errno != ENOTTY) {
   78             pr_fail_err("ioctl RTC_ALRM_READ");
   79             ret = -errno;
   80             goto err;
   81         }
   82     }
   83 #endif
   84 
   85 #if defined(RTC_WKALM_RD)
   86     if (ioctl(fd, RTC_WKALM_RD, &wake_alarm) < 0) {
   87         if (errno != ENOTTY) {
   88             pr_fail_err("ioctl RTC_WKALRM_RD");
   89             ret = -errno;
   90             goto err;
   91         }
   92     }
   93 #endif
   94 
   95 #if defined(RTC_IRQP_READ)
   96     if (ioctl(fd, RTC_IRQP_READ, &tmp) < 0) {
   97         if (errno != ENOTTY) {
   98             pr_fail_err("ioctl RTC_IRQP_READ");
   99             ret = -errno;
  100             goto err;
  101         }
  102     }
  103 #endif
  104 
  105     /*
  106      *  Very short delay select on the device
  107      *  that should normally always timeout because
  108      *  there are no RTC alarm interrupts pending
  109      */
  110     timeout.tv_sec = 0;
  111     timeout.tv_usec = 1000;
  112     FD_ZERO(&rfds);
  113     FD_SET(fd, &rfds);
  114     (void)select(fd + 1, &rfds, NULL, NULL, &timeout);
  115 
  116 #if defined(RTC_RD_TIME) || defined(RTC_ALM_READ) || \
  117     defined(RTC_WKALM_RD) || defined(RTC_IRQP_READ)
  118 err:
  119 #endif
  120     (void)close(fd);
  121 
  122     return ret;
  123 }
  124 
  125 static inline int stress_rtc_sys(const args_t *args)
  126 {
  127     size_t i;
  128     int rc = 0;
  129     int enoents = 0;
  130 
  131     for (i = 0; i < SIZEOF_ARRAY(interfaces); i++) {
  132         char path[PATH_MAX];
  133         char buf[4096];
  134         int ret;
  135 
  136         (void)snprintf(path, sizeof(path), "/sys/class/rtc/rtc0/%s", interfaces[i]);
  137         ret = system_read(path, buf, sizeof(buf));
  138         if (ret < 0) {
  139             if (ret == -EINTR) {
  140                 rc = ret;
  141                 break;
  142             } else if (ret == -ENOENT) {
  143                 enoents++;
  144             } else {
  145                 pr_fail("%s: read of %s failed: errno=%d (%s)\n",
  146                     args->name, path, -ret, strerror(-ret));
  147                 rc = ret;
  148             }
  149         }
  150     }
  151     if (enoents == SIZEOF_ARRAY(interfaces)) {
  152         pr_fail("%s: no RTC interfaces found for /sys/class/rtc/rtc0\n", args->name);
  153         rc = -ENOENT;
  154     }
  155 
  156     return rc;
  157 }
  158 
  159 static inline int stress_rtc_proc(const args_t *args)
  160 {
  161     int ret;
  162     char buf[4096];
  163     static char *path = "/proc/driver/rtc";
  164 
  165     ret = system_read(path, buf, sizeof(buf));
  166     if (ret < 0) {
  167         if ((ret != -ENOENT) && (ret != -EINTR)) {
  168             pr_fail("%s: read of %s failed: errno=%d (%s)\n",
  169             args->name, path, -ret, strerror(-ret));
  170         }
  171     }
  172     return ret;
  173 }
  174 
  175 /*
  176  *  stress_rtc
  177  *  stress some Linux RTC ioctls and /sys/class/rtc interface
  178  */
  179 static int stress_rtc(const args_t *args)
  180 {
  181     do {
  182         int ret;
  183 
  184         ret = stress_rtc_dev(args);
  185         if (ret < 0) {
  186             if ((ret != -EACCES) && (ret != -EBUSY))
  187                 break;
  188         }
  189         ret = stress_rtc_sys(args);
  190         if (ret < 0)
  191             break;
  192         ret = stress_rtc_proc(args);
  193         if (ret < 0)
  194             break;
  195         inc_counter(args);
  196     } while (keep_stressing());
  197 
  198     return EXIT_SUCCESS;
  199 }
  200 
  201 stressor_info_t stress_rtc_info = {
  202     .stressor = stress_rtc,
  203     .class = CLASS_OS
  204 };
  205 #else
  206 stressor_info_t stress_rtc_info = {
  207     .stressor = stress_not_implemented,
  208     .class = CLASS_OS
  209 };
  210 #endif