"Fossies" - the Fresh Open Source Software Archive

Member "stress-ng-0.13.05/stress-dev.c" (11 Oct 2021, 71784 Bytes) of package /linux/privat/stress-ng-0.13.05.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-dev.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 0.13.04_vs_0.13.05.

    1 /*
    2  * Copyright (C) 2013-2021 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 static const stress_help_t help[] = {
   28     { NULL, "dev N",    "start N device entry thrashing stressors" },
   29     { NULL, "dev-ops N",    "stop after N device thrashing bogo ops" },
   30     { NULL, "dev-file name","specify the /dev/ file to exercise" },
   31     { NULL, NULL,       NULL }
   32 };
   33 
   34 static int stress_set_dev_file(const char *opt)
   35 {
   36     return stress_set_setting("dev-file", TYPE_ID_STR, opt);
   37 }
   38 
   39 static const stress_opt_set_func_t opt_set_funcs[] = {
   40     { OPT_dev_file,         stress_set_dev_file },
   41         { 0,                    NULL },
   42 };
   43 
   44 #if defined(HAVE_POLL_H) &&     \
   45     defined(HAVE_LIB_PTHREAD) &&    \
   46     !defined(__sun__) &&        \
   47     !defined(__HAIKU__)
   48 
   49 #define STRESS_DEV_THREADS_MAX      (4)
   50 #define STRESS_DEV_OPEN_TRIES_MAX   (8)
   51 
   52 static sigset_t set;
   53 static shim_pthread_spinlock_t lock;
   54 static shim_pthread_spinlock_t parport_lock;
   55 static char *dev_path;
   56 static uint32_t mixup;
   57 
   58 typedef struct stress_dev_func {
   59     const char *devpath;
   60     const size_t devpath_len;
   61     void (*func)(const stress_args_t *args, const int fd, const char *devpath);
   62 } stress_dev_func_t;
   63 
   64 static stress_hash_table_t *dev_open_fail, *dev_open_ok, *dev_scsi;
   65 
   66 /*
   67  *  ioctl_set_timeout()
   68  *  set a itimer to interrupt ioctl call after secs seconds
   69  */
   70 static void ioctl_set_timeout(const double secs)
   71 {
   72 #if defined(ITIMER_REAL)
   73     if (secs > 0.0) {
   74         struct itimerval it;
   75         int ret;
   76         time_t tsecs = (time_t)secs;
   77 
   78         it.it_interval.tv_sec = (time_t)secs;
   79         it.it_interval.tv_usec = (suseconds_t)(1000000.0 * (secs - (double)tsecs));
   80         it.it_value.tv_sec = it.it_interval.tv_sec;
   81         it.it_value.tv_usec = it.it_interval.tv_usec;
   82         ret = setitimer(ITIMER_REAL, &it, NULL);
   83         (void)ret;
   84     }
   85 #else
   86     (void)secs;
   87 #endif
   88 }
   89 
   90 /*
   91  *  ioctl_clr_timeout()
   92  *  clear itimer ioctl timeout alarm
   93  */
   94 static void ioctl_clr_timeout(void)
   95 {
   96 #if defined(ITIMER_REAL)
   97     struct itimerval it;
   98     int ret;
   99 
  100     (void)memset(&it, 0, sizeof(it));
  101     ret = setitimer(ITIMER_REAL, &it, NULL);
  102     (void)ret;
  103 #endif
  104 }
  105 
  106 /*
  107  *   IOCTL_TIMEOUT()
  108  *  execute code, if time taken is > secs then
  109  *  execute the action.  Note there are limitations
  110  *  to the code that can be passed into the macro,
  111  *  variable declarations must be one variable at a
  112  *  time without any commas
  113  */
  114 #define IOCTL_TIMEOUT(secs, code, action)       \
  115 do {                            \
  116     static bool timed_out_ = false;         \
  117     double timeout_t_ = stress_time_now();      \
  118                             \
  119     if (!timed_out_) {              \
  120         ioctl_set_timeout(secs);        \
  121         code                    \
  122         ioctl_clr_timeout();            \
  123     }                       \
  124     if (stress_time_now() >= timeout_t_ + secs) {   \
  125         timed_out_ = true;          \
  126         action;                 \
  127     }                       \
  128 } while (0)
  129 
  130 /*
  131  *  linux_xen_guest()
  132  *  return true if stress-ng is running
  133  *  as a Linux Xen guest.
  134  */
  135 static bool linux_xen_guest(void)
  136 {
  137 #if defined(__linux__)
  138     static bool xen_guest = false;
  139     static bool xen_guest_cached = false;
  140     struct stat statbuf;
  141     int ret;
  142     DIR *dp;
  143     struct dirent *de;
  144 
  145     if (xen_guest_cached)
  146         return xen_guest;
  147 
  148     /*
  149      *  The features file is a good indicator for a Xen guest
  150      */
  151     ret = stat("/sys/hypervisor/properties/features", &statbuf);
  152     if (ret == 0) {
  153         xen_guest = true;
  154         goto done;
  155     }
  156     if (errno == EACCES) {
  157         xen_guest = true;
  158         goto done;
  159     }
  160 
  161     /*
  162      *  Non-dot files in /sys/bus/xen/devices indicate a Xen guest too
  163      */
  164     dp = opendir("/sys/bus/xen/devices");
  165     if (dp) {
  166         while ((de = readdir(dp)) != NULL) {
  167             if (de->d_name[0] != '.') {
  168                 xen_guest = true;
  169                 break;
  170             }
  171         }
  172         (void)closedir(dp);
  173         if (xen_guest)
  174             goto done;
  175     }
  176 
  177     /*
  178      *  At this point Xen is being sneaky and pretending, so
  179      *  apart from inspecting dmesg (which may not be possible),
  180      *  assume it's not a Xen hosted guest.
  181      */
  182     xen_guest = false;
  183 done:
  184     xen_guest_cached = true;
  185 
  186     return xen_guest;
  187 #else
  188     return false;
  189 #endif
  190 }
  191 
  192 
  193 #if defined(__linux__) &&       \
  194     defined(HAVE_LINUX_MEDIA_H) &&  \
  195     defined(MEDIA_IOC_DEVICE_INFO)
  196 static void stress_dev_media_linux(
  197     const stress_args_t *args,
  198     const int fd,
  199     const char *devpath)
  200 {
  201     (void)args;
  202     (void)fd;
  203     (void)devpath;
  204 
  205 #if defined(MEDIA_IOC_DEVICE_INFO) &&   \
  206     defined(HAVE_MEDIA_DEVICE_INFO)
  207     {
  208         struct media_device_info mdi;
  209         int ret;
  210 
  211         ret = ioctl(fd, MEDIA_IOC_DEVICE_INFO, &mdi);
  212         if (ret < 0)
  213             return;
  214 
  215         if (!mdi.driver[0])
  216             pr_inf("%s: ioctl MEDIA_IOC_DEVICE_INFO %s: null driver name\n",
  217                 args->name, devpath);
  218         if (!mdi.model[0])
  219             pr_inf("%s: ioctl MEDIA_IOC_DEVICE_INFO %s: null model name\n",
  220                 args->name, devpath);
  221         if (!mdi.bus_info[0])
  222             pr_inf("%s: ioctl MEDIA_IOC_DEVICE_INFO %s: null bus_info field\n",
  223                 args->name, devpath);
  224     }
  225 #endif
  226 }
  227 #endif
  228 
  229 #if defined(HAVE_LINUX_VT_H)
  230 static void stress_dev_vcs_linux(
  231     const stress_args_t *args,
  232     const int fd,
  233     const char *devpath)
  234 {
  235     (void)args;
  236     (void)fd;
  237     (void)devpath;
  238 
  239 #if defined(VT_GETMODE) &&  \
  240     defined(HAVE_VT_MODE)
  241     {
  242         struct vt_mode mode;
  243         int ret;
  244 
  245         ret = ioctl(fd, VT_GETMODE, &mode);
  246         (void)ret;
  247     }
  248 #endif
  249 #if defined(VT_GETSTATE) && \
  250     defined(HAVE_VT_STAT)
  251     {
  252         struct vt_stat vt_stat;
  253         int ret;
  254 
  255         ret = ioctl(fd, VT_GETSTATE, &vt_stat);
  256         (void)ret;
  257     }
  258 #endif
  259 }
  260 #endif
  261 
  262 #if defined(HAVE_LINUX_DM_IOCTL_H)
  263 static void stress_dev_dm_linux(
  264     const stress_args_t *args,
  265     const int fd,
  266     const char *devpath)
  267 {
  268     (void)args;
  269     (void)fd;
  270     (void)devpath;
  271 
  272 #if defined(DM_VERSION) &&  \
  273     defined(HAVE_DM_IOCTL)
  274     {
  275         struct dm_ioctl dm;
  276         int ret;
  277 
  278         ret = ioctl(fd, DM_VERSION, &dm);
  279         (void)ret;
  280     }
  281 #endif
  282 #if defined(DM_STATUS) &&   \
  283     defined(HAVE_DM_IOCTL)
  284     {
  285         struct dm_ioctl dm;
  286         int ret;
  287 
  288         ret = ioctl(fd, DM_STATUS, &dm);
  289         (void)ret;
  290     }
  291 #endif
  292 }
  293 #endif
  294 
  295 #if defined(HAVE_LINUX_VIDEODEV2_H)
  296 static void stress_dev_video_linux(
  297     const stress_args_t *args,
  298     const int fd,
  299     const char *devpath)
  300 {
  301     (void)args;
  302     (void)fd;
  303     (void)devpath;
  304 
  305 #if defined(VIDIOC_QUERYCAP) && \
  306     defined(HAVE_V4L2_CAPABILITY)
  307     {
  308         struct v4l2_capability c;
  309         int ret;
  310 
  311         (void)memset(&c, 0, sizeof(c));
  312         ret = ioctl(fd, VIDIOC_QUERYCAP, &c);
  313         (void)ret;
  314     }
  315 #endif
  316 #if defined(VIDIOC_G_FBUF) &&   \
  317     defined(HAVE_V4L2_FRAMEBUFFER)
  318     {
  319         struct v4l2_framebuffer f;
  320         int ret;
  321 
  322         (void)memset(&f, 0, sizeof(f));
  323         ret = ioctl(fd, VIDIOC_G_FBUF, &f);
  324         (void)ret;
  325     }
  326 #endif
  327 #if defined(VIDIOC_G_STD) &&    \
  328     defined(HAVE_V4L2_STD_ID)
  329     {
  330         v4l2_std_id id;
  331         int ret;
  332 
  333         (void)memset(&id, 0, sizeof(id));
  334         ret = ioctl(fd, VIDIOC_G_STD, &id);
  335         (void)ret;
  336     }
  337 #endif
  338 #if defined(VIDIOC_G_AUDIO) &&  \
  339     defined(HAVE_V4L2_AUDIO)
  340     {
  341         struct v4l2_audio a;
  342         int ret;
  343 
  344         (void)memset(&a, 0, sizeof(a));
  345         ret = ioctl(fd, VIDIOC_G_AUDIO, &a);
  346         (void)ret;
  347     }
  348 #endif
  349 #if defined(VIDIOC_G_INPUT)
  350     {
  351         int in = 0, ret;
  352 
  353         ret = ioctl(fd, VIDIOC_G_INPUT, &in);
  354         (void)ret;
  355     }
  356 #endif
  357 #if defined(VIDIOC_G_OUTPUT)
  358     {
  359         int in = 0, ret;
  360 
  361         ret = ioctl(fd, VIDIOC_G_OUTPUT, &in);
  362         (void)ret;
  363     }
  364 #endif
  365 #if defined(VIDIOC_G_AUDOUT) && \
  366     defined(HAVE_V4L2_AUDIOOUT)
  367     {
  368         struct v4l2_audioout a;
  369         int ret;
  370 
  371         (void)memset(&a, 0, sizeof(a));
  372         ret = ioctl(fd, VIDIOC_G_AUDOUT, &a);
  373         (void)ret;
  374     }
  375 #endif
  376 #if defined(VIDIOC_G_JPEGCOMP) && \
  377     defined(HAVE_V4L2_JPEGCOMPRESSION)
  378     {
  379         struct v4l2_jpegcompression a;
  380         int ret;
  381 
  382         (void)memset(&a, 0, sizeof(a));
  383         ret = ioctl(fd, VIDIOC_G_JPEGCOMP, &a);
  384         (void)ret;
  385     }
  386 #endif
  387 #if defined(VIDIOC_QUERYSTD) && \
  388     defined(HAVE_V4L2_STD_ID)
  389     {
  390         v4l2_std_id a;
  391         int ret;
  392 
  393         (void)memset(&a, 0, sizeof(a));
  394         ret = ioctl(fd, VIDIOC_QUERYSTD, &a);
  395         (void)ret;
  396     }
  397 #endif
  398 #if defined(VIDIOC_G_PRIORITY)
  399     {
  400         uint32_t a;
  401         int ret;
  402 
  403         ret = ioctl(fd, VIDIOC_G_PRIORITY, &a);
  404         (void)ret;
  405     }
  406 #endif
  407 #if defined(VIDIOC_G_ENC_INDEX) &&  \
  408     defined(HAVE_V4L2_ENC_IDX)
  409     {
  410         struct v4l2_enc_idx a;
  411         int ret;
  412 
  413         (void)memset(&a, 0, sizeof(a));
  414         ret = ioctl(fd, VIDIOC_G_ENC_INDEX, &a);
  415         (void)ret;
  416     }
  417 #endif
  418 #if defined(VIDIOC_QUERY_DV_TIMINGS) && \
  419     defined(HAVE_V4L2_DV_TIMINGS)
  420     {
  421         struct v4l2_dv_timings a;
  422         int ret;
  423 
  424         (void)memset(&a, 0, sizeof(a));
  425         ret = ioctl(fd, VIDIOC_QUERY_DV_TIMINGS, &a);
  426         (void)ret;
  427     }
  428 #endif
  429 }
  430 #endif
  431 
  432 #if defined(HAVE_TERMIOS_H) &&  \
  433     defined(TCGETS) &&      \
  434     defined(HAVE_TERMIOS)
  435 static void stress_dev_tty(
  436     const stress_args_t *args,
  437     const int fd,
  438     const char *devpath)
  439 {
  440     int ret;
  441     struct termios t;
  442 
  443     (void)args;
  444     (void)devpath;
  445 
  446     if (!isatty(fd))
  447         return;
  448 
  449     ret = tcgetattr(fd, &t);
  450     (void)ret;
  451 #if defined(TCGETS)
  452     {
  453         ret = ioctl(fd, TCGETS, &t);
  454 #if defined(TCSETS)
  455         if (ret == 0) {
  456             ret = ioctl(fd, TCSETS, &t);
  457         }
  458 #endif
  459         (void)ret;
  460     }
  461 #endif
  462 #if defined(TIOCGPTLCK)
  463     {
  464         int lck;
  465 
  466         ret = ioctl(fd, TIOCGPTLCK, &lck);
  467 #if defined(TIOCSPTLCK)
  468         if (ret == 0) {
  469             ret = ioctl(fd, TIOCSPTLCK, &lck);
  470         }
  471 #endif
  472         (void)ret;
  473     }
  474 #endif
  475 #if defined(TIOCGPKT)
  476     {
  477         int pktmode;
  478 
  479         ret = ioctl(fd, TIOCGPKT, &pktmode);
  480 #if defined(TIOCPKT)
  481         if (ret == 0) {
  482             ret = ioctl(fd, TIOCPKT, &pktmode);
  483         }
  484 #endif
  485         (void)ret;
  486     }
  487 #endif
  488 #if defined(TIOCGPTN)
  489     {
  490         int ptnum;
  491 
  492         ret = ioctl(fd, TIOCGPTN, &ptnum);
  493         (void)ret;
  494     }
  495 #endif
  496 #if defined(TIOCSIG) && \
  497     defined(SIGCONT)
  498     {
  499         int sig = SIGCONT;
  500 
  501         /* generally causes EINVAL */
  502         ret = ioctl(fd, TIOCSIG, &sig);
  503         (void)ret;
  504     }
  505 #endif
  506 #if defined(TIOCGWINSZ) && \
  507     defined(HAVE_WINSIZE)
  508     {
  509         struct winsize ws;
  510 
  511         ret = ioctl(fd, TIOCGWINSZ, &ws);
  512 #if defined(TIOCSWINSZ)
  513         if (ret == 0) {
  514             ret = ioctl(fd, TIOCSWINSZ, &ws);
  515         }
  516 #endif
  517         (void)ret;
  518     }
  519 #endif
  520 #if defined(FIONREAD)
  521     {
  522         int n;
  523 
  524         ret = ioctl(fd, FIONREAD, &n);
  525         (void)ret;
  526     }
  527 #endif
  528 #if defined(TIOCINQ)
  529     {
  530         int n;
  531 
  532         ret = ioctl(fd, TIOCINQ, &n);
  533         (void)ret;
  534     }
  535 #endif
  536 #if defined(TIOCOUTQ)
  537     {
  538         int n;
  539 
  540         ret = ioctl(fd, TIOCOUTQ, &n);
  541         (void)ret;
  542     }
  543 #endif
  544 #if defined(TIOCGPGRP)
  545     {
  546         pid_t pgrp;
  547 
  548         ret = ioctl(fd, TIOCGPGRP, &pgrp);
  549 #if defined(TIOCSPGRP)
  550         if (ret == 0) {
  551             ret = ioctl(fd, TIOCSPGRP, &pgrp);
  552         }
  553 #endif
  554         (void)ret;
  555     }
  556 #endif
  557 #if defined(TIOCGSID)
  558     {
  559         pid_t gsid;
  560 
  561         ret = ioctl(fd, TIOCGSID, &gsid);
  562         (void)ret;
  563     }
  564 #endif
  565 #if defined(TIOCGEXCL)
  566     {
  567         int excl;
  568 
  569         ret = ioctl(fd, TIOCGEXCL, &excl);
  570         if (ret == 0) {
  571 #if defined(TIOCNXCL) &&    \
  572     defined(TIOCEXCL)
  573             if (excl) {
  574                 ret = ioctl(fd, TIOCNXCL, NULL);
  575                 (void)ret;
  576                 ret = ioctl(fd, TIOCEXCL, NULL);
  577             } else {
  578                 ret = ioctl(fd, TIOCEXCL, NULL);
  579                 (void)ret;
  580                 ret = ioctl(fd, TIOCNXCL, NULL);
  581             }
  582 #endif
  583         }
  584         (void)ret;
  585     }
  586 #endif
  587 /*
  588  *  On some older 3.13 kernels this can lock up, need to add
  589  *  a method to detect and skip this somehow. For the moment
  590  *  disable this stress test.
  591  */
  592 #if defined(TIOCGETD) && 0
  593     {
  594         int ldis;
  595 
  596         ret = ioctl(fd, TIOCGETD, &ldis);
  597 #if defined(TIOCSETD)
  598         if (ret == 0) {
  599             ret = ioctl(fd, TIOCSETD, &ldis);
  600         }
  601 #endif
  602         (void)ret;
  603     }
  604 #endif
  605 
  606 #if defined(TIOCGPTPEER)
  607     {
  608         ret = ioctl(fd, TIOCGPTPEER, O_RDWR);
  609         (void)ret;
  610     }
  611 #endif
  612 
  613 #if defined(TCOOFF) &&  \
  614     defined(TCOON)
  615     {
  616         ret = ioctl(fd, TCOOFF, 0);
  617         if (ret == 0)
  618             ret = ioctl(fd, TCOON, 0);
  619         (void)ret;
  620     }
  621 #endif
  622 
  623 #if defined(TCIOFF) &&  \
  624     defined(TCION)
  625     {
  626         ret = ioctl(fd, TCIOFF, 0);
  627         if (ret == 0)
  628             ret = ioctl(fd, TCION, 0);
  629         (void)ret;
  630     }
  631 #endif
  632 
  633     /* Modem */
  634 #if defined(TIOCGSOFTCAR)
  635     {
  636         int flag;
  637 
  638         ret = ioctl(fd, TIOCGSOFTCAR, &flag);
  639 #if defined(TIOCSSOFTCAR)
  640         if (ret == 0) {
  641             ret = ioctl(fd, TIOCSSOFTCAR, &flag);
  642         }
  643 #endif
  644         (void)ret;
  645     }
  646 #endif
  647 
  648 #if defined(KDGETLED)
  649     {
  650         char state;
  651 
  652         ret = ioctl(fd, KDGETLED, &state);
  653         (void)ret;
  654     }
  655 #endif
  656 
  657 #if defined(KDGKBTYPE)
  658     {
  659         char type;
  660 
  661         ret = ioctl(fd, KDGKBTYPE, &type);
  662         (void)ret;
  663     }
  664 #endif
  665 
  666 #if defined(KDGETMODE)
  667     {
  668         int mode;
  669 
  670         ret = ioctl(fd, KDGETMODE, &mode);
  671         (void)ret;
  672     }
  673 #endif
  674 
  675 #if defined(KDGKBMODE)
  676     {
  677         long mode;
  678 
  679         ret = ioctl(fd, KDGKBMODE, &mode);
  680         (void)ret;
  681     }
  682 #endif
  683 
  684 #if defined(KDGKBMETA)
  685     {
  686         long mode;
  687 
  688         ret = ioctl(fd, KDGKBMETA, &mode);
  689         (void)ret;
  690     }
  691 #endif
  692 #if defined(TIOCMGET)
  693     {
  694         int status;
  695 
  696         ret = ioctl(fd, TIOCMGET, &status);
  697 #if defined(TIOCMSET)
  698         if (ret == 0) {
  699 #if defined(TIOCMBIC)
  700             ret = ioctl(fd, TIOCMBIC, &status);
  701             (void)ret;
  702 #endif
  703 #if defined(TIOCMBIS)
  704             ret = ioctl(fd, TIOCMBIS, &status);
  705             (void)ret;
  706 #endif
  707             ret = ioctl(fd, TIOCMSET, &status);
  708         }
  709 #endif
  710         (void)ret;
  711     }
  712 #endif
  713 #if defined(TIOCGICOUNT) &&     \
  714     defined(HAVE_LINUX_SERIAL_H) && \
  715     defined(HAVE_SERIAL_ICOUNTER)
  716     {
  717         struct serial_icounter_struct counter;
  718 
  719         ret = ioctl(fd, TIOCGICOUNT, &counter);
  720         (void)ret;
  721     }
  722 #endif
  723 #if defined(TIOCGSERIAL) &&     \
  724     defined(HAVE_LINUX_SERIAL_H) && \
  725     defined(HAVE_SERIAL_STRUCT)
  726     {
  727         struct serial_struct serial;
  728 
  729         ret = ioctl(fd, TIOCGSERIAL, &serial);
  730 #if defined(TIOCSSERIAL)
  731         if (ret == 0)
  732             ret = ioctl(fd, TIOCSSERIAL, &serial);
  733 #endif
  734         (void)ret;
  735     }
  736 #endif
  737 
  738 #if defined(HAVE_SHIM_TERMIOS2) &&  \
  739     defined(TCGETS2)
  740     {
  741 #define termios2 shim_termios2
  742         struct termios2 t2;
  743 
  744         ret = ioctl(fd, TCGETS2, &t2);
  745         (void)ret;
  746 #if defined(TCSETS2) ||     \
  747     defined(TCSETSW2) ||    \
  748     defined(TCSETSF2)
  749         if (ret == 0) {
  750 #if defined(TCSETSF2)
  751             ret = ioctl(fd, TCSETSF2, &t2);
  752             (void)ret;
  753 #endif
  754 #if defined(TCSETSW2)
  755             ret = ioctl(fd, TCSETSW2, &t2);
  756             (void)ret;
  757 #endif
  758 #if defined(TCSETS2)
  759             ret = ioctl(fd, TCSETS2, &t2);
  760             (void)ret;
  761 #endif
  762         }
  763 #endif
  764     }
  765 #endif
  766 }
  767 #endif
  768 
  769 /*
  770  *  stress_dev_blk()
  771  *  block device specific ioctls
  772  */
  773 static void stress_dev_blk(
  774     const stress_args_t *args,
  775     const int fd,
  776     const char *devpath)
  777 {
  778     off_t offset;
  779 
  780     (void)args;
  781     (void)fd;
  782     (void)devpath;
  783 
  784 #if defined(BLKFLSBUF)
  785     {
  786         int ret;
  787         ret = ioctl(fd, BLKFLSBUF, 0);
  788         (void)ret;
  789     }
  790 #endif
  791 #if defined(BLKRAGET)
  792     /* readahead */
  793     {
  794         unsigned long ra;
  795         int ret;
  796 
  797         ret = ioctl(fd, BLKRAGET, &ra);
  798         (void)ret;
  799     }
  800 #endif
  801 #if defined(BLKROGET)
  802     /* readonly state */
  803     {
  804         int ret, ro;
  805 
  806         ret = ioctl(fd, BLKROGET, &ro);
  807         (void)ret;
  808     }
  809 #endif
  810 #if defined(BLKBSZGET)
  811     /* get block device soft block size */
  812     {
  813         int ret, sz;
  814 
  815         ret = ioctl(fd, BLKBSZGET, &sz);
  816         (void)ret;
  817     }
  818 #endif
  819 #if defined(BLKPBSZGET)
  820     /* get block device physical block size */
  821     {
  822         unsigned int sz;
  823         int ret;
  824 
  825         ret = ioctl(fd, BLKPBSZGET, &sz);
  826         (void)ret;
  827     }
  828 #endif
  829 #if defined(BLKIOMIN)
  830     {
  831         unsigned int sz;
  832         int ret;
  833 
  834         ret = ioctl(fd, BLKIOMIN, &sz);
  835         (void)ret;
  836     }
  837 #endif
  838 #if defined(BLKIOOPT)
  839     {
  840         unsigned int sz;
  841         int ret;
  842 
  843         ret = ioctl(fd, BLKIOOPT, &sz);
  844         (void)ret;
  845     }
  846 #endif
  847 #if defined(BLKALIGNOFF)
  848     {
  849         unsigned int sz;
  850         int ret;
  851 
  852         ret = ioctl(fd, BLKALIGNOFF, &sz);
  853         (void)ret;
  854     }
  855 #endif
  856 #if defined(BLKROTATIONAL)
  857     {
  858         unsigned short rotational;
  859         int ret;
  860 
  861         ret = ioctl(fd, BLKROTATIONAL, &rotational);
  862         (void)ret;
  863     }
  864 #endif
  865 #if defined(BLKSECTGET)
  866     {
  867         unsigned short max_sectors;
  868         int ret;
  869 
  870         ret = ioctl(fd, BLKSECTGET, &max_sectors);
  871         (void)ret;
  872     }
  873 #endif
  874 #if defined(BLKGETSIZE)
  875     {
  876         unsigned long sz;
  877         int ret;
  878 
  879         ret = ioctl(fd, BLKGETSIZE, &sz);
  880         (void)ret;
  881     }
  882 #endif
  883 #if defined(BLKGETSIZE64)
  884     {
  885         uint64_t sz;
  886         int ret;
  887 
  888         ret = ioctl(fd, BLKGETSIZE64, &sz);
  889         (void)ret;
  890     }
  891 #endif
  892 #if defined(BLKGETZONESZ)
  893     {
  894         uint32_t sz;
  895         int ret;
  896 
  897         ret = ioctl(fd, BLKGETZONESZ, &sz);
  898         (void)ret;
  899     }
  900 #endif
  901 #if defined(BLKGETNRZONES)
  902     {
  903         uint32_t sz;
  904         int ret;
  905 
  906         ret = ioctl(fd, BLKGETNRZONES, &sz);
  907         (void)ret;
  908     }
  909 #endif
  910     offset = lseek(fd, 0, SEEK_END);
  911     stress_uint64_put((uint64_t)offset);
  912 
  913     offset = lseek(fd, 0, SEEK_SET);
  914     stress_uint64_put((uint64_t)offset);
  915 
  916     offset = lseek(fd, 0, SEEK_CUR);
  917     stress_uint64_put((uint64_t)offset);
  918 }
  919 
  920 #if defined(__linux__)
  921 static inline const char *dev_basename(const char *devpath)
  922 {
  923     const char *ptr = devpath;
  924     const char *base = devpath;
  925 
  926     while (*ptr) {
  927         if ((*ptr == '/') && (*(ptr + 1)))
  928             base = ptr + 1;
  929         ptr++;
  930     }
  931 
  932     return base;
  933 }
  934 
  935 static inline void add_scsi_dev(const char *devpath)
  936 {
  937     int ret;
  938 
  939     ret = shim_pthread_spin_lock(&lock);
  940     if (ret)
  941         return;
  942 
  943     stress_hash_add(dev_scsi, devpath);
  944     (void)shim_pthread_spin_unlock(&lock);
  945 }
  946 
  947 static inline bool is_scsi_dev_cached(const char *devpath)
  948 {
  949     int ret;
  950     bool is_scsi = false;
  951 
  952     ret = shim_pthread_spin_lock(&lock);
  953     if (ret)
  954         return false;
  955 
  956     is_scsi = (stress_hash_get(dev_scsi, devpath) != NULL);
  957     (void)shim_pthread_spin_unlock(&lock);
  958 
  959     return is_scsi;
  960 }
  961 
  962 static inline bool is_scsi_dev(const char *devpath)
  963 {
  964     int i, n;
  965     static const char scsi_device_path[] = "/sys/class/scsi_device/";
  966     struct dirent **scsi_device_list;
  967     bool is_scsi = false;
  968     const char *devname = dev_basename(devpath);
  969 
  970     if (!*devname)
  971         return false;
  972 
  973     if (is_scsi_dev_cached(devpath))
  974         return true;
  975 
  976     scsi_device_list = NULL;
  977     n = scandir(scsi_device_path, &scsi_device_list, NULL, alphasort);
  978     if (n <= 0)
  979         return is_scsi;
  980 
  981     for (i = 0; !is_scsi && (i < n); i++) {
  982         int j, m;
  983         char scsi_block_path[PATH_MAX];
  984         struct dirent **scsi_block_list;
  985 
  986         if (scsi_device_list[i]->d_name[0] == '.')
  987             continue;
  988 
  989         (void)snprintf(scsi_block_path, sizeof(scsi_block_path),
  990             "%s/%s/device/block", scsi_device_path,
  991             scsi_device_list[i]->d_name);
  992         scsi_block_list = NULL;
  993         m = scandir(scsi_block_path, &scsi_block_list, NULL, alphasort);
  994         if (m <= 0)
  995             continue;
  996 
  997         for (j = 0; j < m; j++) {
  998             if (!strcmp(devname, scsi_block_list[j]->d_name)) {
  999                 is_scsi = true;
 1000                 break;
 1001             }
 1002         }
 1003 
 1004         stress_dirent_list_free(scsi_block_list, m);
 1005     }
 1006 
 1007     stress_dirent_list_free(scsi_device_list, n);
 1008 
 1009     if (is_scsi)
 1010         add_scsi_dev(devpath);
 1011 
 1012     return is_scsi;
 1013 }
 1014 
 1015 #else
 1016 static inline bool is_scsi_dev(const char *devpath)
 1017 {
 1018     (void)devpath;
 1019 
 1020     /* Assume not */
 1021     return false;
 1022 }
 1023 #endif
 1024 
 1025 /*
 1026  *  stress_dev_scsi_blk()
 1027  *  SCSI block device specific ioctls
 1028  */
 1029 static void stress_dev_scsi_blk(
 1030     const stress_args_t *args,
 1031     const int fd,
 1032     const char *devpath)
 1033 {
 1034     (void)args;
 1035     (void)fd;
 1036 
 1037     if (!is_scsi_dev(devpath))
 1038         return;
 1039 
 1040 #if defined(SG_GET_VERSION_NUM)
 1041     {
 1042         int ret, ver;
 1043 
 1044         ret = ioctl(fd, SG_GET_VERSION_NUM, &ver);
 1045         (void)ret;
 1046     }
 1047 #endif
 1048 #if defined(SCSI_IOCTL_GET_IDLUN)
 1049     {
 1050         int ret;
 1051         struct sng_scsi_idlun {
 1052             int four_in_one;
 1053             int host_unique_id;
 1054         } lun;
 1055 
 1056         (void)memset(&lun, 0, sizeof(lun));
 1057         ret = ioctl(fd, SCSI_IOCTL_GET_IDLUN, &lun);
 1058         (void)ret;
 1059     }
 1060 #endif
 1061 #if defined(SCSI_IOCTL_GET_BUS_NUMBER)
 1062     {
 1063         int ret, bus;
 1064 
 1065         ret = ioctl(fd, SCSI_IOCTL_GET_BUS_NUMBER, &bus);
 1066         (void)ret;
 1067     }
 1068 #endif
 1069 #if defined(SCSI_IOCTL_GET_TIMEOUT)
 1070     {
 1071         int ret;
 1072 
 1073         ret = ioctl(fd, SCSI_IOCTL_GET_TIMEOUT, 0);
 1074         (void)ret;
 1075     }
 1076 #endif
 1077 #if defined(SCSI_IOCTL_GET_RESERVED_SIZE)
 1078     {
 1079         int ret, sz;
 1080 
 1081         ret = ioctl(fd, SCSI_IOCTL_GET_RESERVED_SIZE, &sz);
 1082         (void)ret;
 1083     }
 1084 #endif
 1085 #if defined(SCSI_IOCTL_GET_PCI)
 1086     {
 1087         /* Old ioctl was 20 chars, new API 8 chars, 32 is plenty */
 1088         char pci[32];
 1089 
 1090         ret = ioctl(fd, SCSI_IOCTL_GET_PCI, pci);
 1091         (void)ret;
 1092     }
 1093 #endif
 1094 }
 1095 
 1096 #if defined(__linux__)
 1097 /*
 1098  *  stress_dev_scsi_generic_linux()
 1099  *  SCSI generic device specific ioctls for linux
 1100  */
 1101 static void stress_dev_scsi_generic_linux(
 1102     const stress_args_t *args,
 1103     const int fd,
 1104     const char *devpath)
 1105 {
 1106     (void)args;
 1107     (void)fd;
 1108     (void)devpath;
 1109 
 1110 #if defined(SG_GET_VERSION_NUM)
 1111     {
 1112         int ret, version = 0;
 1113 
 1114         ret = ioctl(fd, SG_GET_VERSION_NUM, &version);
 1115         (void)ret;
 1116     }
 1117 #endif
 1118 #if defined(SG_GET_TIMEOUT)
 1119     {
 1120         int ret;
 1121 
 1122         ret = ioctl(fd, SG_GET_TIMEOUT, 0);
 1123         (void)ret;
 1124     }
 1125 #endif
 1126 #if defined(SG_GET_LOW_DMA)
 1127     {
 1128         int ret, low;
 1129 
 1130         ret = ioctl(fd, SG_GET_LOW_DMA, &low);
 1131         (void)ret;
 1132     }
 1133 #endif
 1134 #if defined(SG_GET_PACK_ID)
 1135     {
 1136         int ret, pack_id;
 1137 
 1138         ret = ioctl(fd, SG_GET_PACK_ID, &pack_id);
 1139         (void)ret;
 1140     }
 1141 #endif
 1142 #if defined(SG_GET_NUM_WAITING)
 1143     {
 1144         int ret, n;
 1145 
 1146         ret = ioctl(fd, SG_GET_NUM_WAITING, &n);
 1147         (void)ret;
 1148     }
 1149 #endif
 1150 #if defined(SG_GET_SG_TABLESIZE)
 1151     {
 1152         int ret, size;
 1153 
 1154         ret = ioctl(fd, SG_GET_SG_TABLESIZE, &size);
 1155         (void)ret;
 1156     }
 1157 #endif
 1158 #if defined(SG_GET_RESERVED_SIZE)
 1159     {
 1160         int ret, size;
 1161 
 1162         ret = ioctl(fd, SG_GET_RESERVED_SIZE, &size);
 1163         (void)ret;
 1164     }
 1165 #endif
 1166 #if defined(SG_GET_COMMAND_Q)
 1167     {
 1168         int ret, cmd_q;
 1169 
 1170         ret = ioctl(fd, SG_GET_COMMAND_Q, &cmd_q);
 1171         (void)ret;
 1172     }
 1173 #endif
 1174 #if defined(SG_GET_ACCESS_COUNT)
 1175     {
 1176         int ret, n;
 1177 
 1178         ret = ioctl(fd, SG_GET_ACCESS_COUNT, &n);
 1179         (void)ret;
 1180     }
 1181 #endif
 1182 #if defined(SCSI_IOCTL_GET_IDLUN)
 1183     {
 1184         int ret;
 1185         struct shim_scsi_idlun {
 1186             int four_in_one;
 1187             int host_unique_id;
 1188         } idlun;
 1189 
 1190         ret = ioctl(fd, SCSI_IOCTL_GET_IDLUN, &idlun);
 1191         (void)ret;
 1192     }
 1193 #endif
 1194 #if defined(SCSI_IOCTL_GET_BUS_NUMBER)
 1195     {
 1196         int ret, bus;
 1197 
 1198         ret = ioctl(fd, SCSI_IOCTL_GET_BUS_NUMBER, &bus);
 1199         (void)ret;
 1200     }
 1201 #endif
 1202 #if defined(SCSI_GET_TRANSFORM)
 1203     {
 1204         int ret, bus;
 1205 
 1206         ret = ioctl(fd, SCSI_GET_TRANSFORM, 0);
 1207         (void)ret;
 1208     }
 1209 #endif
 1210 #if defined(SG_EMULATED_HOST)
 1211     {
 1212         int ret, emulated;
 1213 
 1214         ret = ioctl(fd, SG_EMULATED_HOST, &emulated);
 1215         (void)ret;
 1216     }
 1217 #endif
 1218 #if defined(BLKSECTGET)
 1219     {
 1220         int ret, n;
 1221 
 1222         ret = ioctl(fd, BLKSECTGET, &n);
 1223         (void)ret;
 1224     }
 1225 #endif
 1226 }
 1227 #endif
 1228 
 1229 #if defined(HAVE_LINUX_RANDOM_H)
 1230 /*
 1231  *  stress_dev_random_linux()
 1232  *  Linux /dev/random ioctls
 1233  */
 1234 static void stress_dev_random_linux(
 1235     const stress_args_t *args,
 1236     const int fd,
 1237     const char *devpath)
 1238 {
 1239     (void)args;
 1240     (void)fd;
 1241     (void)devpath;
 1242 
 1243 #if defined(RNDGETENTCNT)
 1244     {
 1245         long entropy;
 1246         int ret;
 1247 
 1248         ret = ioctl(fd, RNDGETENTCNT, &entropy);
 1249         (void)ret;
 1250     }
 1251 #endif
 1252 
 1253 #if defined(RNDRESEEDCRNG)
 1254     {
 1255         int ret;
 1256 
 1257         ret = ioctl(fd, RNDRESEEDCRNG, NULL);
 1258         (void)ret;
 1259     }
 1260 #endif
 1261 
 1262 #if defined(RNDADDENTROPY)
 1263     {
 1264         char filename[PATH_MAX];
 1265         int fd_rdwr;
 1266 
 1267         /*
 1268          *  Re-open fd with O_RDWR
 1269          */
 1270         (void)snprintf(filename, sizeof(filename), "/proc/self/fd/%d", fd);
 1271         fd_rdwr = open(filename, O_RDWR);
 1272         if (fd_rdwr != -1) {
 1273             int ret;
 1274             const uint32_t rnd = stress_mwc32();
 1275             struct shim_rand_pool_info {
 1276                 int entropy_count;
 1277                 int buf_size;
 1278                 uint8_t buf[4];
 1279             } info;
 1280             const size_t sz = sizeof(info.buf);
 1281 
 1282             info.entropy_count = sz * 8;
 1283             info.buf_size = sz;
 1284             (void)memcpy(&info.buf, &rnd, sz);
 1285 
 1286             ret = ioctl(fd_rdwr, RNDADDENTROPY, &info);
 1287             (void)ret;
 1288             (void)close(fd_rdwr);
 1289         }
 1290     }
 1291 #endif
 1292 }
 1293 #endif
 1294 
 1295 #if defined(__linux__)
 1296 /*
 1297  *  stress_dev_mem_mmap_linux()
 1298  *  Linux mmap'ing on a device
 1299  */
 1300 static void stress_dev_mem_mmap_linux(const int fd, const bool read_page)
 1301 {
 1302     void *ptr;
 1303     const size_t page_size = stress_get_pagesize();
 1304 
 1305     ptr = mmap(NULL, page_size, PROT_READ, MAP_PRIVATE, fd, 0);
 1306     if (ptr != MAP_FAILED) {
 1307         (void)munmap(ptr, page_size);
 1308     }
 1309     if (read_page) {
 1310         off_t off;
 1311 
 1312         /* Try seeking */
 1313         off = lseek(fd, (off_t)0, SEEK_SET);
 1314 #if defined(STRESS_ARCH_X86)
 1315         if (off == 0) {
 1316             char buffer[page_size];
 1317             ssize_t ret;
 1318 
 1319             /* And try reading */
 1320             ret = read(fd, buffer, page_size);
 1321             (void)ret;
 1322         }
 1323 #else
 1324         (void)off;
 1325 #endif
 1326     }
 1327 
 1328     ptr = mmap(NULL, page_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
 1329     if (ptr != MAP_FAILED) {
 1330         (void)munmap(ptr, page_size);
 1331     }
 1332 
 1333 }
 1334 
 1335 static void stress_dev_mem_linux(
 1336     const stress_args_t *args,
 1337     const int fd,
 1338     const char *devpath)
 1339 {
 1340     (void)args;
 1341     (void)devpath;
 1342 
 1343     stress_dev_mem_mmap_linux(fd, true);
 1344 }
 1345 #endif
 1346 
 1347 #if defined(__linux__)
 1348 static void stress_dev_kmem_linux(
 1349     const stress_args_t *args,
 1350     const int fd,
 1351     const char *devpath)
 1352 {
 1353     (void)args;
 1354     (void)devpath;
 1355 
 1356     stress_dev_mem_mmap_linux(fd, false);
 1357 }
 1358 #endif
 1359 
 1360 #if defined(__linux__) &&       \
 1361     defined(CDROMREADTOCENTRY) &&   \
 1362     defined(HAVE_CDROM_MSF) &&      \
 1363     defined(HAVE_CDROM_TOCENTRY)
 1364 /*
 1365  * cdrom_get_address_msf()
 1366  *      Given a track and fd, the function returns
 1367  *      the address of the track in MSF format
 1368  */
 1369 static void cdrom_get_address_msf(
 1370     const int fd,
 1371     int track,
 1372     uint8_t *min,
 1373     uint8_t *seconds,
 1374     uint8_t *frames)
 1375 {
 1376     struct cdrom_tocentry entry;
 1377 
 1378     (void)memset(&entry, 0, sizeof(entry));
 1379     entry.cdte_track = (uint8_t)track;
 1380     entry.cdte_format = CDROM_MSF;
 1381 
 1382     if (ioctl(fd, CDROMREADTOCENTRY, &entry) == 0) {
 1383         *min = entry.cdte_addr.msf.minute;
 1384         *seconds = entry.cdte_addr.msf.second;
 1385         *frames = entry.cdte_addr.msf.frame;
 1386     }
 1387 }
 1388 #endif
 1389 
 1390 #if defined(__linux__)
 1391 /*
 1392  * stress_cdrom_ioctl_msf()
 1393  *      tests all CDROM ioctl syscalls that
 1394  *      requires address argument in MSF Format
 1395  */
 1396 static void stress_cdrom_ioctl_msf(const int fd)
 1397 {
 1398     int starttrk = 0, endtrk = 0;
 1399 
 1400     (void)fd;
 1401     (void)starttrk;
 1402     (void)endtrk;
 1403 
 1404 #if defined(CDROMREADTOCHDR) && \
 1405     defined(HAVE_CDROM_MSF) &&  \
 1406     defined(HAVE_CDROM_TOCHDR)
 1407     IOCTL_TIMEOUT(0.10,
 1408     {
 1409         struct cdrom_tochdr header;
 1410         /* Reading the number of tracks on disc */
 1411 
 1412         (void)memset(&header, 0, sizeof(header));
 1413         if (ioctl(fd, CDROMREADTOCHDR, &header) == 0) {
 1414             starttrk = header.cdth_trk0;
 1415             endtrk = header.cdth_trk1;
 1416         }
 1417     }, return);
 1418 
 1419     /* Return if endtrack is not set or starttrk is invalid */
 1420     if ((endtrk == 0) && (starttrk != 0)) {
 1421         return;
 1422     }
 1423 #endif
 1424 
 1425 #if defined(CDROMPLAYTRKIND) && \
 1426     defined(HAVE_CDROM_TI) &&   \
 1427     defined(CDROMPAUSE) && 0
 1428     /* Play/pause is a bit rough on H/W, disable it for now */
 1429     IOCTL_TIMEOUT(0.10, {
 1430         struct cdrom_ti ti;
 1431         int ret;
 1432 
 1433         (void)memset(&ti, 0, sizeof(ti));
 1434         ti.cdti_trk1 = endtrk;
 1435         if (ioctl(fd, CDROMPLAYTRKIND, &ti) == 0) {
 1436             ret = ioctl(fd, CDROMPAUSE, 0);
 1437             (void)ret;
 1438         }
 1439     }, return);
 1440 #endif
 1441 
 1442 #if defined(CDROMREADTOCENTRY) &&   \
 1443     defined(HAVE_CDROM_MSF) &&      \
 1444     defined(HAVE_CDROM_TOCENTRY)
 1445     {
 1446         struct cdrom_msf msf;
 1447         int ret;
 1448 
 1449         /* Fetch address of start and end track in MSF format */
 1450         (void)memset(&msf, 0, sizeof(msf));
 1451         cdrom_get_address_msf(fd, starttrk, &msf.cdmsf_min0,
 1452             &msf.cdmsf_sec0, &msf.cdmsf_frame0);
 1453         cdrom_get_address_msf(fd, endtrk, &msf.cdmsf_min1,
 1454             &msf.cdmsf_sec1, &msf.cdmsf_frame1);
 1455 
 1456 #if defined(CDROMPLAYMSF) &&    \
 1457     defined(CDROMPAUSE)
 1458         IOCTL_TIMEOUT(0.10, {
 1459             if (ioctl(fd, CDROMPLAYMSF, &msf) == 0) {
 1460                 ret = ioctl(fd, CDROMPAUSE, 0);
 1461                 (void)ret;
 1462             }
 1463         }, return);
 1464 #endif
 1465 
 1466 #if defined(CDROMREADRAW) &&    \
 1467     defined(CD_FRAMESIZE_RAW)
 1468         IOCTL_TIMEOUT(0.10, {
 1469             union {
 1470                 struct cdrom_msf msf;       /* input */
 1471                 char buffer[CD_FRAMESIZE_RAW];  /* return */
 1472             } arg;
 1473 
 1474             arg.msf = msf;
 1475             ret = ioctl(fd, CDROMREADRAW, &arg);
 1476             (void)ret;
 1477         }, return);
 1478 #endif
 1479 
 1480 #if defined(CDROMREADMODE1) &&  \
 1481     defined(CD_FRAMESIZE)
 1482         IOCTL_TIMEOUT(0.10, {
 1483             union {
 1484                 struct cdrom_msf msf;       /* input */
 1485                 char buffer[CD_FRAMESIZE];  /* return */
 1486             } arg;
 1487 
 1488             arg.msf = msf;
 1489             ret = ioctl(fd, CDROMREADMODE1, &arg);
 1490             (void)ret;
 1491         }, return);
 1492 #endif
 1493 
 1494 #if defined(CDROMREADMODE2) &&  \
 1495     defined(CD_FRAMESIZE_RAW0)
 1496         IOCTL_TIMEOUT(0.10, {
 1497             union {
 1498                 struct cdrom_msf msf;       /* input */
 1499                 char buffer[CD_FRAMESIZE_RAW0]; /* return */
 1500             } arg;
 1501 
 1502             arg.msf = msf;
 1503             ret = ioctl(fd, CDROMREADMODE2, &arg);
 1504             (void)ret;
 1505         }, return);
 1506 #endif
 1507     }
 1508 #endif
 1509 }
 1510 #endif
 1511 
 1512 #if defined(__linux__)
 1513 static void stress_dev_cdrom_linux(
 1514     const stress_args_t *args,
 1515     const int fd,
 1516     const char *devpath)
 1517 {
 1518     (void)args;
 1519     (void)fd;
 1520     (void)devpath;
 1521 
 1522     stress_cdrom_ioctl_msf(fd);
 1523 
 1524 #if defined(CDROM_GET_MCN) &&   \
 1525     defined(HAVE_CDROM_MCN)
 1526     IOCTL_TIMEOUT(0.10, {
 1527         struct cdrom_mcn mcn;
 1528         int ret;
 1529 
 1530         (void)memset(&mcn, 0, sizeof(mcn));
 1531         ret = ioctl(fd, CDROM_GET_MCN, &mcn);
 1532         (void)ret;
 1533     }, return);
 1534 #endif
 1535 #if defined(CDROMREADTOCHDR) &&     \
 1536     defined(HAVE_CDROM_TOCHDR)
 1537     IOCTL_TIMEOUT(0.10, {
 1538         struct cdrom_tochdr header;
 1539         int ret;
 1540 
 1541         (void)memset(&header, 0, sizeof(header));
 1542         ret = ioctl(fd, CDROMREADTOCHDR, &header);
 1543         (void)ret;
 1544     }, return);
 1545 #endif
 1546 #if defined(CDROMREADTOCENTRY) &&   \
 1547     defined(HAVE_CDROM_TOCENTRY)
 1548     IOCTL_TIMEOUT(0.10, {
 1549         struct cdrom_tocentry entry;
 1550         int ret;
 1551 
 1552         (void)memset(&entry, 0, sizeof(entry));
 1553         ret = ioctl(fd, CDROMREADTOCENTRY, &entry);
 1554         (void)ret;
 1555     }, return);
 1556 #endif
 1557 #if defined(CDROMVOLREAD) &&        \
 1558     defined(CDROMVOLCTRL) &&        \
 1559     defined(HAVE_CDROM_VOLCTRL)
 1560     IOCTL_TIMEOUT(0.10, {
 1561         struct cdrom_volctrl volume;
 1562         int ret;
 1563 
 1564         (void)memset(&volume, 0, sizeof(volume));
 1565         ret = ioctl(fd, CDROMVOLREAD, &volume);
 1566         if (ret == 0)
 1567             ret = ioctl(fd, CDROMVOLCTRL, &volume);
 1568         (void)ret;
 1569     }, return);
 1570 #endif
 1571 #if defined(CDROMSUBCHNL) &&    \
 1572     defined(HAVE_CDROM_SUBCHNL)
 1573     IOCTL_TIMEOUT(0.10, {
 1574         struct cdrom_subchnl q;
 1575         int ret;
 1576 
 1577         (void)memset(&q, 0, sizeof(q));
 1578         ret = ioctl(fd, CDROMSUBCHNL, &q);
 1579         (void)ret;
 1580     }, return);
 1581 #endif
 1582 #if defined(CDROMREADAUDIO) &&  \
 1583     defined(HAVE_CDROM_READ_AUDIO)
 1584     IOCTL_TIMEOUT(0.10, {
 1585         struct cdrom_read_audio ra;
 1586         int ret;
 1587 
 1588         (void)memset(&ra, 0, sizeof(ra));
 1589         ret = ioctl(fd, CDROMREADAUDIO, &ra);
 1590         (void)ret;
 1591     }, return);
 1592 #endif
 1593 #if defined(CDROMREADCOOKED) && \
 1594     defined(CD_FRAMESIZE)
 1595     IOCTL_TIMEOUT(0.10, {
 1596         uint8_t buffer[CD_FRAMESIZE];
 1597         int ret;
 1598 
 1599         (void)memset(&buffer, 0, sizeof(buffer));
 1600         ret = ioctl(fd, CDROMREADCOOKED, buffer);
 1601         (void)ret;
 1602     }, return);
 1603 #endif
 1604 #if defined(CDROMREADALL) &&    \
 1605     defined(CD_FRAMESIZE)
 1606     IOCTL_TIMEOUT(0.10, {
 1607         uint8_t buffer[CD_FRAMESIZE];
 1608         int ret;
 1609 
 1610         (void)memset(&buffer, 0, sizeof(buffer));
 1611         ret = ioctl(fd, CDROMREADALL, buffer);
 1612         (void)ret;
 1613     }, return);
 1614 #endif
 1615 #if defined(CDROMSEEK) &&   \
 1616     defined(HAVE_CDROM_MSF)
 1617     IOCTL_TIMEOUT(0.10, {
 1618         struct cdrom_msf msf;
 1619         int ret;
 1620 
 1621         (void)memset(&msf, 0, sizeof(msf));
 1622         ret = ioctl(fd, CDROMSEEK, &msf);
 1623         (void)ret;
 1624     }, return);
 1625 #endif
 1626 #if defined(CDROMGETSPINDOWN)
 1627     {
 1628         char spindown;
 1629         int ret;
 1630 
 1631         ret = ioctl(fd, CDROMGETSPINDOWN, &spindown);
 1632 #if defined(CDROMSETSPINDOWN)
 1633         if (ret == 0) {
 1634             char bad_val = ~0;
 1635 
 1636             ret = ioctl(fd, CDROMSETSPINDOWN, &spindown);
 1637             (void)ret;
 1638 
 1639             /*
 1640              * Exercise Invalid CDROMSETSPINDOWN ioctl call with
 1641              * invalid spindown as it could contain only 4 set bits
 1642              */
 1643             ret = ioctl(fd, CDROMSETSPINDOWN, bad_val);
 1644             if (ret == 0) {
 1645                 /* Unexpected success, so set it back */
 1646                 ret = ioctl(fd, CDROMSETSPINDOWN, &spindown);
 1647             }
 1648         }
 1649 #endif
 1650         (void)ret;
 1651     }
 1652 #endif
 1653 
 1654 
 1655 #if defined(CDROM_DISC_STATUS)
 1656     IOCTL_TIMEOUT(0.10, {
 1657         int ret;
 1658 
 1659         ret = ioctl(fd, CDROM_DISC_STATUS, 0);
 1660         (void)ret;
 1661     }, return);
 1662 #endif
 1663 #if defined(CDROM_GET_CAPABILITY)
 1664     IOCTL_TIMEOUT(0.10, {
 1665         int ret;
 1666 
 1667         ret = ioctl(fd, CDROM_GET_CAPABILITY, 0);
 1668         (void)ret;
 1669     }, return);
 1670 #endif
 1671 #if defined(CDROM_CHANGER_NSLOTS)
 1672     IOCTL_TIMEOUT(0.10, {
 1673         int ret;
 1674 
 1675         ret = ioctl(fd, CDROM_CHANGER_NSLOTS, 0);
 1676         (void)ret;
 1677     }, return);
 1678 #endif
 1679 #if defined(CDROM_NEXT_WRITABLE)
 1680     IOCTL_TIMEOUT(0.10, {
 1681         int ret;
 1682         long next;
 1683 
 1684         ret = ioctl(fd, CDROM_NEXT_WRITABLE, &next);
 1685         (void)ret;
 1686     }, return);
 1687 #endif
 1688 #if defined(CDROM_LAST_WRITTEN)
 1689     IOCTL_TIMEOUT(0.10, {
 1690         int ret;
 1691         long last;
 1692 
 1693         ret = ioctl(fd, CDROM_LAST_WRITTEN, &last);
 1694         (void)ret;
 1695     }, return);
 1696 #endif
 1697 #if defined(CDROM_MEDIA_CHANGED) && 0
 1698     IOCTL_TIMEOUT(0.10, {
 1699         int ret;
 1700         int slot = 0;
 1701 
 1702         ret = ioctl(fd, CDROM_MEDIA_CHANGED, slot);
 1703         (void)ret;
 1704     }, return);
 1705 #endif
 1706 #if defined(CDSL_NONE)
 1707     IOCTL_TIMEOUT(0.10, {
 1708         int ret;
 1709         int slot = CDSL_NONE;
 1710 
 1711         ret = ioctl(fd, CDROM_MEDIA_CHANGED, slot);
 1712         (void)ret;
 1713     }, return);
 1714 #endif
 1715 #if defined(CDSL_CURRENT)
 1716     IOCTL_TIMEOUT(0.10, {
 1717         int ret;
 1718         int slot = CDSL_CURRENT;
 1719 
 1720         ret = ioctl(fd, CDROM_MEDIA_CHANGED, slot);
 1721         (void)ret;
 1722     }, return);
 1723 #endif
 1724 #if defined(CDROMPAUSE)
 1725     IOCTL_TIMEOUT(0.10, {
 1726         int ret;
 1727 
 1728         ret = ioctl(fd, CDROMPAUSE, 0);
 1729         (void)ret;
 1730     }, return);
 1731 #endif
 1732 #if defined(CDROMRESUME)
 1733     IOCTL_TIMEOUT(0.10, {
 1734         int ret;
 1735 
 1736         ret = ioctl(fd, CDROMRESUME, 0);
 1737         (void)ret;
 1738     }, return);
 1739 #endif
 1740 #if defined(CDROM_DRIVE_STATUS)
 1741     IOCTL_TIMEOUT(0.10, {
 1742         int ret;
 1743         int slot = 0;
 1744 
 1745         ret = ioctl(fd, CDROM_DRIVE_STATUS, slot);
 1746         (void)ret;
 1747     }, return);
 1748 #if defined(CDSL_NONE)
 1749     IOCTL_TIMEOUT(0.10, {
 1750         int ret;
 1751         int slot = CDSL_NONE;
 1752 
 1753         ret = ioctl(fd, CDROM_DRIVE_STATUS, slot);
 1754         (void)ret;
 1755     }, return);
 1756 #endif
 1757 #if defined(CDSL_CURRENT)
 1758     IOCTL_TIMEOUT(0.10, {
 1759         int ret;
 1760         int slot = CDSL_CURRENT;
 1761 
 1762         ret = ioctl(fd, CDROM_DRIVE_STATUS, slot);
 1763         (void)ret;
 1764     }, return);
 1765 #endif
 1766 #endif
 1767 #if defined(DVD_READ_STRUCT) && \
 1768     defined(HAVE_DVD_STRUCT)
 1769     IOCTL_TIMEOUT(0.10, {
 1770         dvd_struct s;
 1771         int ret;
 1772 
 1773         /*
 1774          *  Invalid DVD_READ_STRUCT ioctl syscall with
 1775          *  invalid layer number resulting in EINVAL
 1776          */
 1777         (void)memset(&s, 0, sizeof(s));
 1778         s.type = DVD_STRUCT_PHYSICAL;
 1779         s.physical.layer_num = UINT8_MAX;
 1780         ret = ioctl(fd, DVD_READ_STRUCT, &s);
 1781         (void)ret;
 1782 
 1783         /*
 1784          *  Exercise each DVD structure type to cover all the
 1785          *  respective functions to increase kernel coverage
 1786          */
 1787         (void)memset(&s, 0, sizeof(s));
 1788         s.type = DVD_STRUCT_PHYSICAL;
 1789         ret = ioctl(fd, DVD_READ_STRUCT, &s);
 1790         (void)ret;
 1791 
 1792         (void)memset(&s, 0, sizeof(s));
 1793         s.type = DVD_STRUCT_COPYRIGHT;
 1794         ret = ioctl(fd, DVD_READ_STRUCT, &s);
 1795         (void)ret;
 1796 
 1797         (void)memset(&s, 0, sizeof(s));
 1798         s.type = DVD_STRUCT_DISCKEY;
 1799         ret = ioctl(fd, DVD_READ_STRUCT, &s);
 1800         (void)ret;
 1801 
 1802         (void)memset(&s, 0, sizeof(s));
 1803         s.type = DVD_STRUCT_BCA;
 1804         ret = ioctl(fd, DVD_READ_STRUCT, &s);
 1805         (void)ret;
 1806 
 1807         (void)memset(&s, 0, sizeof(s));
 1808         s.type = DVD_STRUCT_MANUFACT;
 1809         ret = ioctl(fd, DVD_READ_STRUCT, &s);
 1810         (void)ret;
 1811 
 1812         /* Invalid DVD_READ_STRUCT call with invalid type argument */
 1813         (void)memset(&s, 0, sizeof(s));
 1814         s.type = UINT8_MAX;
 1815         ret = ioctl(fd, DVD_READ_STRUCT, &s);
 1816         (void)ret;
 1817     }, return);
 1818 #endif
 1819 #if defined(CDROMAUDIOBUFSIZ)
 1820     IOCTL_TIMEOUT(0.10, {
 1821         int val = INT_MIN;
 1822         int ret;
 1823 
 1824         /* Invalid CDROMAUDIOBUFSIZ call with negative buffer size */
 1825         ret = ioctl(fd, CDROMAUDIOBUFSIZ, val);
 1826         (void)ret;
 1827     }, return);
 1828 #endif
 1829 #if defined(DVD_AUTH) &&    \
 1830     defined(HAVE_DVD_AUTHINFO)
 1831     IOCTL_TIMEOUT(0.40, {
 1832         int ret;
 1833         dvd_authinfo ai;
 1834 
 1835         /* Invalid DVD_AUTH call with no credentials */
 1836         (void)memset(&ai, 0, sizeof(ai));
 1837         ret = ioctl(fd, DVD_AUTH, &ai);
 1838         (void)ret;
 1839 
 1840         /*
 1841          *  Exercise each DVD AUTH type to cover all the
 1842          *  respective code to increase kernel coverage
 1843          */
 1844         (void)memset(&ai, 0, sizeof(ai));
 1845         ai.type = DVD_LU_SEND_AGID;
 1846         ret = ioctl(fd, DVD_AUTH, &ai);
 1847         (void)ret;
 1848 
 1849         (void)memset(&ai, 0, sizeof(ai));
 1850         ai.type = DVD_LU_SEND_KEY1;
 1851         ret = ioctl(fd, DVD_AUTH, &ai);
 1852         (void)ret;
 1853 
 1854         (void)memset(&ai, 0, sizeof(ai));
 1855         ai.type = DVD_LU_SEND_CHALLENGE;
 1856         ret = ioctl(fd, DVD_AUTH, &ai);
 1857         (void)ret;
 1858 
 1859         (void)memset(&ai, 0, sizeof(ai));
 1860         ai.type = DVD_LU_SEND_TITLE_KEY;
 1861         ret = ioctl(fd, DVD_AUTH, &ai);
 1862         (void)ret;
 1863 
 1864         (void)memset(&ai, 0, sizeof(ai));
 1865         ai.type = DVD_LU_SEND_ASF;
 1866         ret = ioctl(fd, DVD_AUTH, &ai);
 1867         (void)ret;
 1868 
 1869         (void)memset(&ai, 0, sizeof(ai));
 1870         ai.type = DVD_HOST_SEND_CHALLENGE;
 1871         ret = ioctl(fd, DVD_AUTH, &ai);
 1872         (void)ret;
 1873 
 1874         (void)memset(&ai, 0, sizeof(ai));
 1875         ai.type = DVD_HOST_SEND_KEY2;
 1876         ret = ioctl(fd, DVD_AUTH, &ai);
 1877         (void)ret;
 1878 
 1879         (void)memset(&ai, 0, sizeof(ai));
 1880         ai.type = DVD_INVALIDATE_AGID;
 1881         ret = ioctl(fd, DVD_AUTH, &ai);
 1882         (void)ret;
 1883 
 1884         (void)memset(&ai, 0, sizeof(ai));
 1885         ai.type = DVD_LU_SEND_RPC_STATE;
 1886         ret = ioctl(fd, DVD_AUTH, &ai);
 1887         (void)ret;
 1888 
 1889         (void)memset(&ai, 0, sizeof(ai));
 1890         ai.type = DVD_HOST_SEND_RPC_STATE;
 1891         ret = ioctl(fd, DVD_AUTH, &ai);
 1892         (void)ret;
 1893 
 1894         /* Invalid DVD_READ_STRUCT call with invalid type argument */
 1895         (void)memset(&ai, 0, sizeof(ai));
 1896         ai.type = (uint8_t)~0;
 1897         ret = ioctl(fd, DVD_AUTH, &ai);
 1898         (void)ret;
 1899     }, return);
 1900 #endif
 1901 
 1902 #if defined(CDROM_DEBUG)
 1903     IOCTL_TIMEOUT(0.10, {
 1904         int debug;
 1905         int ret;
 1906 
 1907         /* Enable the DEBUG Messages */
 1908         debug = 1;
 1909         ret = ioctl(fd, CDROM_DEBUG, debug);
 1910         (void)ret;
 1911 
 1912         /* Disable the DEBUG Messages */
 1913         debug = 0;
 1914         ret = ioctl(fd, CDROM_DEBUG, debug);
 1915         (void)ret;
 1916     }, return);
 1917 #endif
 1918 
 1919 #if defined(CDROM_SELECT_SPEED)
 1920     IOCTL_TIMEOUT(0.10, {
 1921         unsigned int i;
 1922         unsigned int speed;
 1923         int ret;
 1924 
 1925         for (i = 8; i < 16; i++) {
 1926             speed = 1 << i;
 1927             ret = ioctl(fd, CDROM_SELECT_SPEED, speed);
 1928             (void)ret;
 1929         }
 1930     }, return);
 1931 #endif
 1932 
 1933 #if defined(CDROMPLAYBLK) &&    \
 1934     defined(HAVE_CDROM_BLK)
 1935     IOCTL_TIMEOUT(0.10, {
 1936         struct cdrom_blk blk;
 1937         int ret;
 1938 
 1939         (void)memset(&blk, 0, sizeof(blk));
 1940         ret = ioctl(fd, CDROMPLAYBLK, &blk);
 1941         (void)ret;
 1942     }, return);
 1943 #endif
 1944 }
 1945 #endif
 1946 
 1947 #if defined(__linux__)
 1948 static void stress_dev_console_linux(
 1949     const stress_args_t *args,
 1950     const int fd,
 1951     const char *devpath)
 1952 {
 1953     (void)args;
 1954     (void)fd;
 1955     (void)devpath;
 1956 
 1957 #if defined(HAVE_LINUX_KD_H) && \
 1958     defined(KDGETLED)
 1959     {
 1960         char argp;
 1961         int ret;
 1962 
 1963         ret = ioctl(fd, KDGETLED, &argp);
 1964 #if defined(KDSETLED)
 1965         if (ret == 0) {
 1966             const char bad_val = ~0;
 1967 
 1968             ret = ioctl(fd, KDSETLED, &argp);
 1969             (void)ret;
 1970 
 1971             /* Exercise Invalid KDSETLED ioctl call with invalid flags */
 1972             ret = ioctl(fd, KDSETLED, &bad_val);
 1973             if (ret == 0) {
 1974                 /* Unexpected success, so set it back */
 1975                 ret = ioctl(fd, KDSETLED, &argp);
 1976             }
 1977         }
 1978 #endif
 1979         (void)ret;
 1980     }
 1981 #endif
 1982 
 1983 #if defined(HAVE_LINUX_KD_H) && \
 1984     defined(KDGKBLED)
 1985     {
 1986         char argp;
 1987         int ret;
 1988 
 1989         ret = ioctl(fd, KDGKBLED, &argp);
 1990 #if defined(KDSKBLED)
 1991         if (ret == 0) {
 1992             unsigned long bad_val = ~0UL, val;
 1993 
 1994             val = (unsigned long)argp;
 1995             ret = ioctl(fd, KDSKBLED, val);
 1996             (void)ret;
 1997 
 1998             /* Exercise Invalid KDSKBLED ioctl call with invalid flags */
 1999             ret = ioctl(fd, KDSKBLED, bad_val);
 2000             if (ret == 0) {
 2001                 /* Unexpected success, so set it back */
 2002                 ret = ioctl(fd, KDSKBLED, val);
 2003             }
 2004         }
 2005 #endif
 2006         (void)ret;
 2007     }
 2008 #endif
 2009 
 2010 #if defined(HAVE_LINUX_KD_H) && \
 2011     defined(KDGETMODE)
 2012     {
 2013         int ret;
 2014         unsigned long argp = 0;
 2015 
 2016         ret = ioctl(fd, KDGETMODE, &argp);
 2017 #if defined(KDSETMODE)
 2018         if (ret == 0) {
 2019             unsigned long bad_val = ~0UL;
 2020 
 2021             ret = ioctl(fd, KDSETMODE, argp);
 2022             (void)ret;
 2023 
 2024             /* Exercise Invalid KDSETMODE ioctl call with invalid flags */
 2025             ret = ioctl(fd, KDSETMODE, bad_val);
 2026             if (ret == 0) {
 2027                 /* Unexpected success, so set it back */
 2028                 ret = ioctl(fd, KDSETMODE, argp);
 2029             }
 2030         }
 2031 #endif
 2032         (void)ret;
 2033     }
 2034 #endif
 2035 
 2036 #if defined(HAVE_LINUX_KD_H) && \
 2037     defined(KDGKBTYPE)
 2038     {
 2039         int val = 0, ret;
 2040 
 2041         ret = ioctl(fd, KDGKBTYPE, &val);
 2042         (void)ret;
 2043     }
 2044 #endif
 2045 
 2046 #if defined(HAVE_LINUX_KD_H) && \
 2047     defined(GIO_CMAP)
 2048     {
 2049         unsigned char colormap[3*16];
 2050         int ret;
 2051 
 2052         ret = ioctl(fd, GIO_CMAP, colormap);
 2053 #if defined(PIO_CMAP)
 2054         if (ret == 0) {
 2055             ret = ioctl(fd, PIO_CMAP, colormap);
 2056         }
 2057 #endif
 2058         (void)ret;
 2059     }
 2060 #endif
 2061 
 2062 #if defined(HAVE_LINUX_KD_H) && \
 2063     defined(GIO_FONTX) &&   \
 2064     defined(HAVE_CONSOLEFONTDESC)
 2065     {
 2066         struct consolefontdesc font;
 2067         int ret;
 2068 
 2069         (void)memset(&font, 0, sizeof(font));
 2070         ret = ioctl(fd, GIO_FONTX, &font);
 2071 #if defined(PIO_FONTX)
 2072         if (ret == 0) {
 2073             ret = ioctl(fd, PIO_FONTX, &font);
 2074         }
 2075 #endif
 2076         (void)ret;
 2077     }
 2078 #endif
 2079 
 2080 #if defined(HAVE_LINUX_KD_H) && \
 2081     defined(KDGETKEYCODE) &&    \
 2082     defined(HAVE_KBKEYCODE)
 2083     {
 2084         int ret;
 2085         struct kbkeycode argp;
 2086 
 2087         (void)memset(&argp, 0, sizeof(argp));
 2088         ret = ioctl(fd, KDGETKEYCODE, &argp);
 2089 #if defined(KDSETKEYCODE)
 2090         if (ret == 0) {
 2091             struct kbkeycode bad_arg;
 2092 
 2093             ret = ioctl(fd, KDSETKEYCODE, &argp);
 2094             (void)ret;
 2095 
 2096             /*
 2097              * Exercise Invalid KDSETKEYCODE ioctl call
 2098              * with invalid keycode having different values
 2099              * of scancode and keycode for scancode < 89
 2100              */
 2101             (void)memset(&bad_arg, 0, sizeof(bad_arg));
 2102             bad_arg.scancode = 1;
 2103             bad_arg.keycode = 2;
 2104 
 2105             ret = ioctl(fd, KDSETKEYCODE, &bad_arg);
 2106             if (ret == 0) {
 2107                 /* Unexpected success, so set it back */
 2108                 ret = ioctl(fd, KDSETKEYCODE, &argp);
 2109             }
 2110         }
 2111 #endif
 2112         (void)ret;
 2113     }
 2114 #endif
 2115 
 2116 #if defined(HAVE_LINUX_KD_H) && \
 2117     defined(GIO_FONT)
 2118     {
 2119         unsigned char argp[8192];
 2120         int ret;
 2121 
 2122         ret = ioctl(fd, GIO_FONT, argp);
 2123 #if defined(PIO_FONT)
 2124         if (ret == 0) {
 2125             ret = ioctl(fd, PIO_FONT, argp);
 2126         }
 2127 #endif
 2128         (void)ret;
 2129     }
 2130 #endif
 2131 
 2132 #if defined(HAVE_LINUX_KD_H) && \
 2133     defined(GIO_SCRNMAP) && \
 2134     defined(E_TABSZ)
 2135     {
 2136         unsigned char argp[E_TABSZ];
 2137         int ret;
 2138 
 2139         ret = ioctl(fd, GIO_SCRNMAP, argp);
 2140 #if defined(PIO_SCRNMAP)
 2141         if (ret == 0) {
 2142             ret = ioctl(fd, PIO_SCRNMAP, argp);
 2143         }
 2144 #endif
 2145         (void)ret;
 2146     }
 2147 #endif
 2148 
 2149 #if defined(HAVE_LINUX_KD_H) && \
 2150     defined(GIO_UNISCRNMAP) && \
 2151     defined(E_TABSZ)
 2152     {
 2153         unsigned short argp[E_TABSZ];
 2154         int ret;
 2155 
 2156         ret = ioctl(fd, GIO_UNISCRNMAP, argp);
 2157 #if defined(PIO_UNISCRNMAP)
 2158         if (ret == 0) {
 2159             ret = ioctl(fd, PIO_UNISCRNMAP, argp);
 2160         }
 2161 #endif
 2162         (void)ret;
 2163     }
 2164 #endif
 2165 
 2166 #if defined(HAVE_LINUX_KD_H) && \
 2167     defined(KDGKBMODE)
 2168     {
 2169         int ret;
 2170         unsigned long argp = 0;
 2171 
 2172         ret = ioctl(fd, KDGKBMODE, &argp);
 2173 #if defined(KDSKBMODE)
 2174         if (ret == 0) {
 2175             unsigned long bad_val = ~0UL;
 2176 
 2177             ret = ioctl(fd, KDSKBMODE, argp);
 2178             (void)ret;
 2179 
 2180             /* Exercise Invalid KDSKBMODE ioctl call with invalid key mode */
 2181             ret = ioctl(fd, KDSKBMODE, bad_val);
 2182             if (ret == 0) {
 2183                 /* Unexpected success, so set it back */
 2184                 ret = ioctl(fd, KDSKBMODE, argp);
 2185             }
 2186         }
 2187 #endif
 2188         (void)ret;
 2189     }
 2190 #endif
 2191 
 2192 #if defined(HAVE_LINUX_KD_H) && \
 2193     defined(KDGKBMETA)
 2194     {
 2195         int ret;
 2196         unsigned long argp = 0;
 2197 
 2198         ret = ioctl(fd, KDGKBMETA, &argp);
 2199 #if defined(KDSKBMETA)
 2200         if (ret == 0) {
 2201             unsigned long bad_val = ~0UL;
 2202 
 2203             ret = ioctl(fd, KDSKBMETA, argp);
 2204             (void)ret;
 2205 
 2206             /* Exercise Invalid KDSKBMETA ioctl call with invalid key mode */
 2207             ret = ioctl(fd, KDSKBMETA, bad_val);
 2208             if (ret == 0) {
 2209                 /* Unexpected success, so set it back */
 2210                 ret = ioctl(fd, KDSKBMETA, argp);
 2211             }
 2212         }
 2213 #endif
 2214         (void)ret;
 2215     }
 2216 #endif
 2217 
 2218 #if defined(HAVE_LINUX_KD_H) && \
 2219     defined(GIO_UNIMAP) &&  \
 2220     defined(HAVE_UNIMAPDESC)
 2221     {
 2222         int ret;
 2223         struct unimapdesc argp;
 2224 
 2225         (void)memset(&argp, 0, sizeof(argp));
 2226         ret = ioctl(fd, GIO_UNIMAP, &argp);
 2227 #if defined(PIO_UNIMAP)
 2228         if (ret == 0) {
 2229             ret = ioctl(fd, PIO_UNIMAP, &argp);
 2230             (void)ret;
 2231         }
 2232 #endif
 2233         (void)ret;
 2234     }
 2235 #endif
 2236 
 2237 #if defined(HAVE_LINUX_KD_H) && \
 2238     defined(KDGKBDIACR) &&  \
 2239     defined(HAVE_KBDIACRS)
 2240     {
 2241         int ret;
 2242         struct kbdiacrs argp;
 2243 
 2244         (void)memset(&argp, 0, sizeof(argp));
 2245         ret = ioctl(fd, KDGKBDIACR, &argp);
 2246         (void)ret;
 2247     }
 2248 #endif
 2249 
 2250 #if defined(HAVE_LINUX_KD_H) && \
 2251     defined(VT_RESIZE) &&   \
 2252     defined(HAVE_VT_SIZES) && \
 2253     defined(CAP_SYS_TTY_CONFIG)
 2254     {
 2255         int ret;
 2256         struct vt_sizes argp;
 2257         bool perm = stress_check_capability(CAP_SYS_TTY_CONFIG);
 2258 
 2259         /* Exercise only if permission is not present */
 2260         if (!perm) {
 2261             (void)memset(&argp, 0, sizeof(argp));
 2262             ret = ioctl(fd, VT_RESIZE, &argp);
 2263             (void)ret;
 2264         }
 2265     }
 2266 #endif
 2267 
 2268 #if defined(HAVE_LINUX_KD_H) && \
 2269     defined(VT_RESIZEX) &&  \
 2270     defined(HAVE_VT_CONSIZE) && \
 2271     defined(CAP_SYS_TTY_CONFIG)
 2272     {
 2273         int ret;
 2274         struct vt_consize argp;
 2275         bool perm = stress_check_capability(CAP_SYS_TTY_CONFIG);
 2276 
 2277         /* Exercise only if permission is not present */
 2278         if (!perm) {
 2279             (void)memset(&argp, 0, sizeof(argp));
 2280             ret = ioctl(fd, VT_RESIZEX, &argp);
 2281             (void)ret;
 2282         }
 2283     }
 2284 #endif
 2285 
 2286 #if defined(HAVE_LINUX_KD_H) && \
 2287     defined(KDGKBSENT) &&   \
 2288     defined(HAVE_KBSENTRY)
 2289     {
 2290         int ret;
 2291         struct kbsentry argp;
 2292 
 2293         (void)memset(&argp, 0, sizeof(argp));
 2294         ret = ioctl(fd, KDGKBSENT, &argp);
 2295 #if defined(KDSKBSENT)
 2296         if (ret == 0) {
 2297             ret = ioctl(fd, KDSKBSENT, &argp);
 2298             (void)ret;
 2299         }
 2300 #endif
 2301         (void)ret;
 2302     }
 2303 #endif
 2304 
 2305 #if defined(HAVE_LINUX_VT_H) && \
 2306     defined(VT_GETMODE) &&  \
 2307     defined(HAVE_VT_MODE)
 2308     {
 2309         int ret;
 2310         struct vt_mode mode;
 2311 
 2312         (void)memset(&mode, 0, sizeof(mode));
 2313         ret = ioctl(fd, VT_GETMODE, &mode);
 2314 #if defined(VT_SETMODE)
 2315         if (ret == 0) {
 2316             ret = ioctl(fd, VT_SETMODE, &mode);
 2317             (void)ret;
 2318         }
 2319 #endif
 2320         (void)ret;
 2321     }
 2322 #endif
 2323 
 2324 #if defined(HAVE_LINUX_KD_H) && \
 2325     defined(KDGKBENT) &&    \
 2326     defined(HAVE_KBENTRY)
 2327     {
 2328         int ret;
 2329         struct kbentry entry;
 2330 
 2331         (void)memset(&entry, 0, sizeof(entry));
 2332         ret = ioctl(fd, KDGKBENT, &entry);
 2333 #if defined(KDSKBENT)
 2334         if (ret == 0) {
 2335             ret = ioctl(fd, KDSKBENT, &entry);
 2336             (void)ret;
 2337 
 2338 #if defined(MAX_NR_KEYMAPS)
 2339             struct kbentry bad_entry;
 2340 
 2341             (void)memset(&bad_entry, 0, sizeof(bad_entry));
 2342             bad_entry.kb_table = MAX_NR_KEYMAPS;
 2343             ret = ioctl(fd, KDSKBENT, &bad_entry);
 2344             if (ret == 0) {
 2345                 /* Unexpected success, so set it back */
 2346                 ret = ioctl(fd, KDSKBENT, &entry);
 2347             }
 2348 #endif
 2349 
 2350 #if defined(HAVE_LINUX_KD_H) && \
 2351     defined(KDSKBENT) &&    \
 2352     defined(HAVE_KBENTRY) &&    \
 2353     defined(NR_KEYS)
 2354             struct kbentry bad_entry;
 2355 
 2356             (void)memset(&entry, 0, sizeof(entry));
 2357             bad_entry.kb_index = NR_KEYS;
 2358             ret = ioctl(fd, KDSKBENT, &bad_entry);
 2359             if (ret == 0) {
 2360                 /* Unexpected success, so set it back */
 2361                 ret = ioctl(fd, KDSKBENT, &entry);
 2362             }
 2363 #endif
 2364         }
 2365 #endif
 2366         (void)ret;
 2367     }
 2368 #endif
 2369 
 2370 }
 2371 #endif
 2372 
 2373 #if defined(__linux__)
 2374 static void stress_dev_kmsg_linux(
 2375     const stress_args_t *args,
 2376     const int fd,
 2377     const char *devpath)
 2378 {
 2379     (void)args;
 2380     (void)devpath;
 2381 
 2382     stress_dev_mem_mmap_linux(fd, true);
 2383 }
 2384 #endif
 2385 
 2386 #if defined(__linux__)
 2387 static void stress_dev_nvram_linux(
 2388     const stress_args_t *args,
 2389     const int fd,
 2390     const char *devpath)
 2391 {
 2392     (void)args;
 2393     (void)devpath;
 2394 
 2395     stress_dev_mem_mmap_linux(fd, true);
 2396 }
 2397 #endif
 2398 
 2399 #if defined(HAVE_LINUX_HPET_H)
 2400 static void stress_dev_hpet_linux(
 2401     const stress_args_t *args,
 2402     const int fd,
 2403     const char *devpath)
 2404 {
 2405     (void)args;
 2406     (void)fd;
 2407     (void)devpath;
 2408 
 2409     /*
 2410      *  Avoid https://bugs.xenserver.org/browse/XSO-809
 2411      */
 2412     if (linux_xen_guest())
 2413         return;
 2414 
 2415 #if defined(HPET_INFO)
 2416     {
 2417         struct hpet_info info;
 2418         int ret;
 2419 
 2420         ret = ioctl(fd, HPET_INFO, &info);
 2421         (void)ret;
 2422     }
 2423 #endif
 2424 #if defined(HPET_IRQFREQ)
 2425     {
 2426         unsigned long freq;
 2427         int ret;
 2428 
 2429         ret = ioctl(fd, HPET_IRQFREQ, &freq);
 2430         (void)ret;
 2431     }
 2432 #endif
 2433 #if defined(CDROMMULTISESSION)
 2434     {
 2435         int ret;
 2436         struct cdrom_multisession ms_info;
 2437 
 2438         /*
 2439          *  Invalid CDROMMULTISESSION ioctl syscall with
 2440          *  invalid format number resulting in EINVAL
 2441          */
 2442         (void)memset(&ms_info, 0, sizeof(ms_info));
 2443         ms_info.addr_format = UINT8_MAX;
 2444         ret = ioctl(fd, CDROMMULTISESSION, &ms_info);
 2445         (void)ret;
 2446 
 2447         /* Valid CDROMMULTISESSION with address formats */
 2448         (void)memset(&ms_info, 0, sizeof(ms_info));
 2449         ms_info.addr_format = CDROM_MSF;
 2450         ret = ioctl(fd, CDROMMULTISESSION, &ms_info);
 2451         (void)ret;
 2452 
 2453         (void)memset(&ms_info, 0, sizeof(ms_info));
 2454         ms_info.addr_format = CDROM_LBA;
 2455         ret = ioctl(fd, CDROMMULTISESSION, &ms_info);
 2456         (void)ret;
 2457     }
 2458 #endif
 2459 }
 2460 #endif
 2461 
 2462 #if defined(__linux__) &&   \
 2463     defined(STRESS_ARCH_X86)
 2464 static void stress_dev_port_linux(
 2465     const stress_args_t *args,
 2466     const int fd,
 2467     const char *devpath)
 2468 {
 2469     off_t off;
 2470     uint8_t *ptr;
 2471     const size_t page_size = stress_get_pagesize();
 2472 
 2473     (void)args;
 2474     (void)devpath;
 2475 
 2476     /* seek and read port 0x80 */
 2477     off = lseek(fd, (off_t)0x80, SEEK_SET);
 2478     if (off == 0) {
 2479         char data[1];
 2480         ssize_t ret;
 2481 
 2482         ret = read(fd, data, sizeof(data));
 2483         (void)ret;
 2484     }
 2485 
 2486     /* Should fail */
 2487     ptr = mmap(NULL, page_size, PROT_READ, MAP_PRIVATE, fd, 0);
 2488     if (ptr != MAP_FAILED)
 2489         (void)munmap(ptr, page_size);
 2490 }
 2491 #endif
 2492 
 2493 #if defined(HAVE_LINUX_HDREG_H)
 2494 static void stress_dev_hd_linux_ioctl_long(int fd, unsigned long cmd)
 2495 {
 2496     long val;
 2497     int ret;
 2498 
 2499     ret = ioctl(fd, cmd, &val);
 2500     (void)ret;
 2501 }
 2502 
 2503 /*
 2504  *  stress_dev_hd_linux()
 2505  *  Linux HDIO ioctls
 2506  */
 2507 static void stress_dev_hd_linux(
 2508     const stress_args_t *args,
 2509     const int fd,
 2510     const char *devpath)
 2511 {
 2512     (void)args;
 2513     (void)devpath;
 2514 
 2515 #if defined(HDIO_GETGEO)
 2516     {
 2517         struct hd_geometry geom;
 2518         int ret;
 2519 
 2520         ret = ioctl(fd, HDIO_GETGEO, &geom);
 2521         (void)ret;
 2522     }
 2523 #endif
 2524 
 2525 #if defined(HDIO_GET_UNMASKINTR)
 2526     stress_dev_hd_linux_ioctl_long(fd, HDIO_GET_UNMASKINTR);
 2527 #endif
 2528 
 2529 #if defined(HDIO_GET_MULTCOUNT)
 2530     {
 2531         int val, ret;
 2532 
 2533         ret = ioctl(fd, HDIO_GET_MULTCOUNT, &val);
 2534         (void)ret;
 2535     }
 2536 #endif
 2537 
 2538 #if defined(HDIO_GET_IDENTITY)
 2539     {
 2540         unsigned char identity[512];
 2541         int ret;
 2542 
 2543         ret = ioctl(fd, HDIO_GET_IDENTITY, identity);
 2544         (void)ret;
 2545     }
 2546 #endif
 2547 
 2548 #if defined(HDIO_GET_KEEPSETTINGS)
 2549     stress_dev_hd_linux_ioctl_long(fd, HDIO_GET_KEEPSETTINGS);
 2550 #endif
 2551 
 2552 #if defined(HDIO_GET_32BIT)
 2553     stress_dev_hd_linux_ioctl_long(fd, HDIO_GET_32BIT);
 2554 #endif
 2555 
 2556 #if defined(HDIO_GET_NOWERR)
 2557     stress_dev_hd_linux_ioctl_long(fd, HDIO_GET_NOWERR);
 2558 #endif
 2559 
 2560 #if defined(HDIO_GET_DMA)
 2561     stress_dev_hd_linux_ioctl_long(fd, HDIO_GET_DMA);
 2562 #endif
 2563 
 2564 #if defined(HDIO_GET_NICE)
 2565     stress_dev_hd_linux_ioctl_long(fd, HDIO_GET_NICE);
 2566 #endif
 2567 
 2568 #if defined(HDIO_GET_WCACHE)
 2569     stress_dev_hd_linux_ioctl_long(fd, HDIO_GET_WCACHE);
 2570 #endif
 2571 
 2572 #if defined(HDIO_GET_ACOUSTIC)
 2573     stress_dev_hd_linux_ioctl_long(fd, HDIO_GET_ACOUSTIC);
 2574 #endif
 2575 
 2576 #if defined(HDIO_GET_ADDRESS)
 2577     stress_dev_hd_linux_ioctl_long(fd, HDIO_GET_ADDRESS);
 2578 #endif
 2579 
 2580 #if defined(HDIO_GET_BUSSTATE)
 2581     stress_dev_hd_linux_ioctl_long(fd, HDIO_GET_BUSSTATE);
 2582 #endif
 2583 }
 2584 #endif
 2585 
 2586 static void stress_dev_null_nop(
 2587     const stress_args_t *args,
 2588     const int fd,
 2589     const char *devpath)
 2590 {
 2591     (void)args;
 2592     (void)fd;
 2593     (void)devpath;
 2594 }
 2595 
 2596 /*
 2597  *  stress_dev_ptp_linux()
 2598  *  minor exercising of the PTP device
 2599  */
 2600 static void stress_dev_ptp_linux(
 2601     const stress_args_t *args,
 2602     const int fd,
 2603     const char *devpath)
 2604 {
 2605 #if defined(HAVE_LINUX_PTP_CLOCK_H) &&  \
 2606     defined(PTP_CLOCK_GETCAPS) &&   \
 2607     defined(PTP_PIN_GETFUNC)
 2608     int ret;
 2609     struct ptp_clock_caps caps;
 2610 
 2611     (void)args;
 2612     (void)devpath;
 2613 
 2614     errno = 0;
 2615     ret = ioctl(fd, PTP_CLOCK_GETCAPS, &caps);
 2616     if (ret == 0) {
 2617         int i, pins = caps.n_pins;
 2618 
 2619         for (i = 0; i < pins; i++) {
 2620             struct ptp_pin_desc desc;
 2621 
 2622             (void)memset(&desc, 0, sizeof(desc));
 2623             desc.index = (unsigned int)i;
 2624             ret = ioctl(fd, PTP_PIN_GETFUNC, &desc);
 2625             (void)ret;
 2626         }
 2627     }
 2628 #else
 2629     (void)args;
 2630     (void)fd;
 2631     (void)devpath;
 2632 #endif
 2633 }
 2634 
 2635 #if defined(HAVE_LINUX_FD_H)
 2636 /*
 2637  *  stress_dev_fd_linux()
 2638  *  minor exercising of the floppy device
 2639  */
 2640 static void stress_dev_fd_linux(
 2641     const stress_args_t *args,
 2642     const int fd,
 2643     const char *devpath)
 2644 {
 2645     (void)args;
 2646     (void)fd;
 2647     (void)devpath;
 2648 
 2649 #if defined(FDMSGON)
 2650     {
 2651         int ret;
 2652 
 2653         ret = ioctl(fd, FDMSGON, 0);
 2654         (void)ret;
 2655     }
 2656 #endif
 2657 
 2658 #if defined(FDFLUSH)
 2659     {
 2660         int ret;
 2661 
 2662         ret = ioctl(fd, FDFLUSH, 0);
 2663         (void)ret;
 2664     }
 2665 #endif
 2666 
 2667 #if defined(FDGETPRM) &&    \
 2668     defined(HAVE_FLOPPY_STRUCT)
 2669     {
 2670         int ret;
 2671         struct floppy_struct floppy;
 2672 
 2673         ret = ioctl(fd, FDGETPRM, &floppy);
 2674         if (ret == 0) {
 2675             ret = ioctl(fd, FDSETPRM, &floppy);
 2676         }
 2677         (void)ret;
 2678     }
 2679 #endif
 2680 
 2681 #if defined(FDGETDRVSTAT) &&    \
 2682     defined(HAVE_FLOPPY_DRIVE_STRUCT)
 2683     {
 2684         int ret;
 2685         struct floppy_drive_struct drive;
 2686 
 2687         ret = ioctl(fd, FDGETDRVSTAT, &drive);
 2688         (void)ret;
 2689     }
 2690 #endif
 2691 
 2692 #if defined(FDPOLLDRVSTAT) &&   \
 2693     defined(HAVE_FLOPPY_DRIVE_STRUCT)
 2694     {
 2695         int ret;
 2696         struct floppy_drive_struct drive;
 2697 
 2698         ret = ioctl(fd, FDPOLLDRVSTAT, &drive);
 2699         (void)ret;
 2700     }
 2701 #endif
 2702 
 2703 #if defined(FDGETDRVTYP)
 2704     {
 2705         int ret;
 2706         char buf[64];
 2707 
 2708         ret = ioctl(fd, FDGETDRVTYP, buf);
 2709         (void)ret;
 2710     }
 2711 #endif
 2712 
 2713 #if defined(FDGETFDCSTAT) &&        \
 2714     defined(HAVE_FLOPPY_FDC_STATE)
 2715     {
 2716         int ret;
 2717         struct floppy_fdc_state state;
 2718 
 2719         ret = ioctl(fd, FDGETFDCSTAT, &state);
 2720         (void)ret;
 2721 
 2722     }
 2723 #endif
 2724 
 2725 #if defined(FDMSGOFF)
 2726     {
 2727         int ret;
 2728 
 2729         ret = ioctl(fd, FDMSGOFF, 0);
 2730         (void)ret;
 2731     }
 2732 #endif
 2733 }
 2734 #endif
 2735 
 2736 /*
 2737  *  stress_dev_snd_control_linux()
 2738  *  exercise Linux sound devices
 2739  */
 2740 static void stress_dev_snd_control_linux(
 2741     const stress_args_t *args,
 2742     const int fd,
 2743     const char *devpath)
 2744 {
 2745     (void)args;
 2746     (void)fd;
 2747     (void)devpath;
 2748 
 2749 #if defined(SNDRV_CTL_IOCTL_PVERSION)
 2750     {
 2751         int ret, ver;
 2752 
 2753         ret = ioctl(fd, SNDRV_CTL_IOCTL_PVERSION, &ver);
 2754         (void)ret;
 2755     }
 2756 #endif
 2757 
 2758 #if defined(SNDRV_CTL_IOCTL_CARD_INFO) &&   \
 2759     defined(HAVE_SND_CTL_CARD_INFO)
 2760     {
 2761         int ret;
 2762         struct snd_ctl_card_info card;
 2763 
 2764         ret = ioctl(fd, SNDRV_CTL_IOCTL_CARD_INFO, &card);
 2765         (void)ret;
 2766     }
 2767 #endif
 2768 
 2769 #if defined(SNDRV_CTL_IOCTL_TLV_READ) &&    \
 2770     defined(HAVE_SND_CTL_TLV)
 2771     {
 2772         int ret;
 2773         struct tlv_buf {
 2774             struct snd_ctl_tlv tlv;
 2775             unsigned int data[4];
 2776         } buf;
 2777 
 2778         /* intentionally will fail with -EINVAL */
 2779         buf.tlv.numid = 0;
 2780         buf.tlv.length = sizeof(buf.data);
 2781         ret = ioctl(fd, SNDRV_CTL_IOCTL_TLV_READ, (struct snd_ctl_tlv *)&buf.tlv);
 2782         (void)ret;
 2783 
 2784         /* intentionally will fail with -ENOENT */
 2785         buf.tlv.numid = ~0U;
 2786         buf.tlv.length = sizeof(buf.data);
 2787         ret = ioctl(fd, SNDRV_CTL_IOCTL_TLV_READ, (struct snd_ctl_tlv *)&buf.tlv);
 2788         (void)ret;
 2789     }
 2790 #endif
 2791 
 2792 #if defined(SNDRV_CTL_IOCTL_POWER_STATE)
 2793     {
 2794         int ret, state;
 2795 
 2796         ret = ioctl(fd, SNDRV_CTL_IOCTL_POWER_STATE, &state);
 2797 #if defined(SNDRV_CTL_IOCTL_POWER)
 2798         if (ret == 0)
 2799             ret = ioctl(fd, SNDRV_CTL_IOCTL_POWER, &state);
 2800 #endif
 2801         (void)ret;
 2802     }
 2803 #endif
 2804 }
 2805 
 2806 #if defined(__linux__)
 2807 /*
 2808  *   stress_dev_hwrng_linux()
 2809  *      Exercise Linux Hardware Random Number Generator
 2810  */
 2811 static void stress_dev_hwrng_linux(
 2812     const stress_args_t *args,
 2813     const int fd,
 2814     const char *devpath)
 2815 {
 2816     ssize_t ret;
 2817     off_t offset = (off_t)0;
 2818     char buffer[8];
 2819 
 2820     (void)args;
 2821     (void)devpath;
 2822 
 2823     offset = lseek(fd, offset, SEEK_SET);
 2824     (void)offset;
 2825 
 2826     ret = read(fd, buffer, sizeof(buffer));
 2827     (void)ret;
 2828 }
 2829 #endif
 2830 
 2831 #if defined(__linux__)
 2832 
 2833 #if defined(PP_IOCT) && \
 2834     !defined(PPGETTIME32)
 2835 #define PPGETTIME32     _IOR(PP_IOCTL, 0x95, int32_t[2])
 2836 #endif
 2837 #if defined(PP_IOCT) && \
 2838     !defined(PPGETTIME64)
 2839 #define PPGETTIME64     _IOR(PP_IOCTL, 0x95, int64_t[2])
 2840 #endif
 2841 
 2842 /*
 2843  *   stress_dev_parport_linux()
 2844  *      Exercise Linux parallel port
 2845  */
 2846 static void stress_dev_parport_linux(
 2847     const stress_args_t *args,
 2848     const int fd,
 2849     const char *devpath)
 2850 {
 2851 #if defined(PPCLAIM) &&     \
 2852     defined(PPRELEASE)
 2853     bool claimed = false;
 2854 #endif
 2855 
 2856     (void)args;
 2857     (void)fd;
 2858     (void)devpath;
 2859 
 2860     /*
 2861      *  We don't do a PPCLAIM or PPRELEASE on all
 2862      *  the stressor instances since this the claim
 2863      *  can indefinitely block and this stops the
 2864      *  progress of the stressor. Just do this for
 2865      *  instance 0. For other instances we run
 2866      *  run without claiming and this will cause
 2867      *  some of the ioctls to fail.
 2868      */
 2869 #if defined(PPCLAIM) && \
 2870     defined(PPRELEASE)
 2871     if (args->instance == 0) {
 2872         int ret;
 2873 
 2874         ret = shim_pthread_spin_lock(&parport_lock);
 2875         if (ret == 0) {
 2876             ret = ioctl(fd, PPCLAIM);
 2877             if (ret == 0)
 2878                 claimed = true;
 2879         }
 2880     }
 2881 #endif
 2882 
 2883 #if defined(PPGETMODE)
 2884     {
 2885         int ret, mode;
 2886 
 2887         ret = ioctl(fd, PPGETMODE, &mode);
 2888 #if defined(PPSETMODE)
 2889         errno = 0;
 2890         if (ret == 0)
 2891             ret = ioctl(fd, PPSETMODE, &mode);
 2892 #endif
 2893         (void)ret;
 2894     }
 2895 #endif
 2896 
 2897 #if defined(PPGETPHASE)
 2898     {
 2899         int ret, phase;
 2900 
 2901         ret = ioctl(fd, PPGETPHASE, &phase);
 2902 #if defined(PPSETPHASE)
 2903         errno = 0;
 2904         if (ret == 0)
 2905             ret = ioctl(fd, PPSETPHASE, &phase);
 2906 #endif
 2907         (void)ret;
 2908     }
 2909 #endif
 2910 
 2911 #if defined(PPGETMODES)
 2912     {
 2913         int ret, modes;
 2914 
 2915         ret = ioctl(fd, PPGETMODES, &modes);
 2916         (void)ret;
 2917     }
 2918 #endif
 2919 
 2920 #if defined(PPGETFLAGS)
 2921     {
 2922         int ret, uflags;
 2923 
 2924         ret = ioctl(fd, PPGETFLAGS, &uflags);
 2925 #if defined(PPSETFLAGS)
 2926         errno = 0;
 2927         if (ret == 0)
 2928             ret = ioctl(fd, PPSETFLAGS, &uflags);
 2929 #endif
 2930         (void)ret;
 2931     }
 2932 #endif
 2933 
 2934 #if defined(PPRSTATUS)
 2935     {
 2936         int ret;
 2937         char reg;
 2938 
 2939         ret = ioctl(fd, PPRSTATUS, &reg);
 2940         (void)ret;
 2941     }
 2942 #endif
 2943 
 2944 #if defined(PPRCONTROL)
 2945     {
 2946         int ret;
 2947         char reg;
 2948 
 2949         ret = ioctl(fd, PPRCONTROL, &reg);
 2950         (void)ret;
 2951     }
 2952 #endif
 2953 
 2954 #if defined(PPGETTIME32)
 2955     {
 2956         int ret;
 2957         int32_t time32[2];
 2958 
 2959         ret = ioctl(fd, PPGETTIME32, time32);
 2960         (void)ret;
 2961     }
 2962 #endif
 2963 
 2964 #if defined(PPGETTIME64)
 2965     {
 2966         int ret;
 2967         int64_t time64[2];
 2968 
 2969         ret = ioctl(fd, PPGETTIME64, time64);
 2970         (void)ret;
 2971     }
 2972 #endif
 2973 
 2974 #if defined(PPYIELD)
 2975     {
 2976         int ret;
 2977 
 2978         ret = ioctl(fd, PPYIELD);
 2979         (void)ret;
 2980     }
 2981 #endif
 2982 
 2983 
 2984 #if defined(PPCLAIM) && \
 2985     defined(PPRELEASE)
 2986     if ((args->instance == 0) && claimed) {
 2987         int ret;
 2988 
 2989         ret = ioctl(fd, PPRELEASE);
 2990         if (ret == 0)
 2991             claimed = true;
 2992         ret = shim_pthread_spin_unlock(&parport_lock);
 2993         (void)ret;
 2994     }
 2995 #endif
 2996 }
 2997 #endif
 2998 
 2999 
 3000 #define DEV_FUNC(dev, func) \
 3001     { dev, sizeof(dev) - 1, func }
 3002 
 3003 static const stress_dev_func_t dev_funcs[] = {
 3004 #if defined(__linux__) &&       \
 3005     defined(HAVE_LINUX_MEDIA_H) &&  \
 3006     defined(MEDIA_IOC_DEVICE_INFO)
 3007     DEV_FUNC("/dev/media",  stress_dev_media_linux),
 3008 #endif
 3009 #if defined(HAVE_LINUX_VT_H)
 3010     DEV_FUNC("/dev/vcs",    stress_dev_vcs_linux),
 3011 #endif
 3012 #if defined(HAVE_LINUX_DM_IOCTL_H)
 3013     DEV_FUNC("/dev/dm", stress_dev_dm_linux),
 3014 #endif
 3015 #if defined(HAVE_LINUX_VIDEODEV2_H)
 3016     DEV_FUNC("/dev/video",  stress_dev_video_linux),
 3017 #endif
 3018 #if defined(HAVE_LINUX_RANDOM_H)
 3019     DEV_FUNC("/dev/random", stress_dev_random_linux),
 3020 #endif
 3021 #if defined(__linux__)
 3022     DEV_FUNC("/dev/mem",    stress_dev_mem_linux),
 3023     DEV_FUNC("/dev/kmem",   stress_dev_kmem_linux),
 3024     DEV_FUNC("/dev/kmsg",   stress_dev_kmsg_linux),
 3025     DEV_FUNC("/dev/nvram",  stress_dev_nvram_linux),
 3026     DEV_FUNC("/dev/cdrom",  stress_dev_cdrom_linux),
 3027     DEV_FUNC("/dev/sg", stress_dev_scsi_generic_linux),
 3028     DEV_FUNC("/dev/sr0",    stress_dev_cdrom_linux),
 3029     DEV_FUNC("/dev/console",stress_dev_console_linux),
 3030 #endif
 3031 #if defined(__linux__) &&   \
 3032     defined(STRESS_ARCH_X86)
 3033     DEV_FUNC("/dev/port",   stress_dev_port_linux),
 3034 #endif
 3035 #if defined(HAVE_LINUX_HPET_H)
 3036     DEV_FUNC("/dev/hpet",   stress_dev_hpet_linux),
 3037 #endif
 3038     DEV_FUNC("/dev/null",   stress_dev_null_nop),
 3039     DEV_FUNC("/dev/ptp",    stress_dev_ptp_linux),
 3040     DEV_FUNC("/dev/snd/control",    stress_dev_snd_control_linux),
 3041 #if defined(HAVE_LINUX_FD_H) && \
 3042     defined(HAVE_FLOPPY_STRUCT)
 3043     DEV_FUNC("/dev/fd", stress_dev_fd_linux),
 3044 #endif
 3045 #if defined(__linux__)
 3046     DEV_FUNC("/dev/hwrng",  stress_dev_hwrng_linux),
 3047 #endif
 3048 #if defined(__linux__)
 3049     DEV_FUNC("/dev/parport",stress_dev_parport_linux),
 3050 #endif
 3051 };
 3052 
 3053 static void stress_dev_procname(const char *path)
 3054 {
 3055     /*
 3056      *  Set process name to enable debugging if it gets stuck
 3057      */
 3058     if (!(g_opt_flags & OPT_FLAGS_KEEP_NAME)) {
 3059         char procname[55];
 3060 
 3061         (void)snprintf(procname, sizeof(procname), "stress-ng-dev:%-40.40s", path);
 3062 #if defined(HAVE_BSD_UNISTD_H) &&       \
 3063     defined(HAVE_SETPROCTITLE)
 3064         /* Sets argv[0] */
 3065         setproctitle("-%s", procname);
 3066 #endif
 3067     }
 3068 }
 3069 
 3070 static inline int stress_dev_lock(const char *path, const int fd)
 3071 {
 3072     errno = 0;
 3073 #if defined(TIOCEXCL) &&    \
 3074     defined(TIOCNXCL)
 3075     {
 3076         int ret;
 3077 
 3078         if (strncmp(path, "/dev/tty", 8))
 3079             return 0;
 3080 
 3081         ret = ioctl(fd, TIOCEXCL);
 3082         if (ret < 0)
 3083             return ret;
 3084     }
 3085 
 3086 #if defined(LOCK_EX) && \
 3087     defined(LOCK_NB) && \
 3088     defined(LOCK_UN)
 3089     {
 3090         int ret;
 3091 
 3092         ret = flock(fd, LOCK_EX | LOCK_NB);
 3093         if (ret < 0) {
 3094             ret = ioctl(fd, TIOCNXCL);
 3095             (void)ret;
 3096             return -1;
 3097         }
 3098     }
 3099 #endif
 3100     return 0;
 3101 #else
 3102     (void)path;
 3103     (void)fd;
 3104 
 3105     return 0;
 3106 #endif
 3107 }
 3108 
 3109 static inline void stress_dev_unlock(const char *path, const int fd)
 3110 {
 3111 #if defined(TIOCEXCL) &&    \
 3112     defined(TIOCNXCL)
 3113     int ret;
 3114 
 3115     if (strncmp(path, "/dev/tty", 8))
 3116         return;
 3117 
 3118 #if defined(LOCK_EX) && \
 3119     defined(LOCK_NB) && \
 3120     defined(LOCK_UN)
 3121     ret = flock(fd, LOCK_UN);
 3122     (void)ret;
 3123 #endif
 3124     ret = ioctl(fd, TIOCNXCL);
 3125     (void)ret;
 3126 #else
 3127     (void)path;
 3128     (void)fd;
 3129 #endif
 3130 }
 3131 
 3132 static int stress_dev_open_lock(
 3133     const stress_args_t *args,
 3134     const char *path,
 3135     const int mode)
 3136 {
 3137     int fd, ret;
 3138 
 3139     fd = stress_open_timeout(args->name, path, mode, 250000000);
 3140     if (fd < 0) {
 3141         if (errno == EBUSY)
 3142             stress_hash_add(dev_open_fail, path);
 3143         return -1;
 3144     }
 3145     ret = stress_dev_lock(path, fd);
 3146     if (ret < 0) {
 3147         (void)close(fd);
 3148         return -1;
 3149     }
 3150     return fd;
 3151 }
 3152 
 3153 static int stress_dev_close_unlock(const char *path, const int fd)
 3154 {
 3155     stress_dev_unlock(path, fd);
 3156     return close(fd);
 3157 }
 3158 
 3159 /*
 3160  *  stress_dev_rw()
 3161  *  exercise a dev entry
 3162  */
 3163 static inline void stress_dev_rw(
 3164     const stress_args_t *args,
 3165     int32_t loops)
 3166 {
 3167     int fd, ret;
 3168     off_t offset;
 3169     struct stat buf;
 3170     struct pollfd fds[1];
 3171     fd_set rfds;
 3172     char path[PATH_MAX];
 3173     const double threshold = 0.25;
 3174 
 3175     while ((loops == -1) || (loops > 0)) {
 3176         double t_start;
 3177         bool timeout = false;
 3178         char *ptr;
 3179         size_t i;
 3180 #if defined(HAVE_TERMIOS_H) &&  \
 3181     defined(TCGETS) && \
 3182     defined(HAVE_TERMIOS)
 3183         struct termios tios;
 3184 #endif
 3185         ret = shim_pthread_spin_lock(&lock);
 3186         if (ret)
 3187             return;
 3188         (void)shim_strlcpy(path, dev_path, sizeof(path));
 3189         (void)shim_pthread_spin_unlock(&lock);
 3190 
 3191         if (!*path || !keep_stressing_flag())
 3192             break;
 3193 
 3194         if (stress_hash_get(dev_open_fail, path))
 3195             goto next;
 3196 
 3197         t_start = stress_time_now();
 3198 
 3199         fd = stress_dev_open_lock(args, path, O_RDONLY | O_NONBLOCK | O_NDELAY);
 3200         if (fd < 0)
 3201             goto next;
 3202 
 3203         if (stress_time_now() - t_start > threshold) {
 3204             timeout = true;
 3205             stress_dev_close_unlock(path, fd);
 3206             goto next;
 3207         }
 3208 
 3209         if (fstat(fd, &buf) < 0) {
 3210             pr_fail("%s: stat failed on %s, errno=%d (%s)\n",
 3211                 args->name, path, errno, strerror(errno));
 3212         } else {
 3213             if ((S_ISBLK(buf.st_mode) | (S_ISCHR(buf.st_mode))) == 0) {
 3214                 stress_dev_close_unlock(path, fd);
 3215                 goto next;
 3216             }
 3217         }
 3218 
 3219         if (S_ISBLK(buf.st_mode)) {
 3220             stress_dev_blk(args, fd, path);
 3221             stress_dev_scsi_blk(args, fd, path);
 3222 #if defined(HAVE_LINUX_HDREG_H)
 3223             stress_dev_hd_linux(args, fd, path);
 3224 #endif
 3225         }
 3226 #if defined(HAVE_TERMIOS_H) &&  \
 3227     defined(TCGETS) && \
 3228     defined(HAVE_TERMIOS)
 3229         if (S_ISCHR(buf.st_mode) &&
 3230             strncmp("/dev/vsock", path, 10) &&
 3231             strncmp("/dev/dri", path, 8) &&
 3232             (ioctl(fd, TCGETS, &tios) == 0))
 3233             stress_dev_tty(args, fd, path);
 3234 #endif
 3235 
 3236         offset = lseek(fd, 0, SEEK_SET);
 3237         stress_uint64_put((uint64_t)offset);
 3238         offset = lseek(fd, 0, SEEK_CUR);
 3239         stress_uint64_put((uint64_t)offset);
 3240         offset = lseek(fd, 0, SEEK_END);
 3241         stress_uint64_put((uint64_t)offset);
 3242 
 3243         if (stress_time_now() - t_start > threshold) {
 3244             timeout = true;
 3245             stress_dev_close_unlock(path, fd);
 3246             goto next;
 3247         }
 3248 
 3249         FD_ZERO(&rfds);
 3250         fds[0].fd = fd;
 3251         fds[0].events = POLLIN;
 3252         ret = poll(fds, 1, 0);
 3253         (void)ret;
 3254 
 3255         if (stress_time_now() - t_start > threshold) {
 3256             timeout = true;
 3257             stress_dev_close_unlock(path, fd);
 3258             goto next;
 3259         }
 3260 
 3261 #if !defined(__NetBSD__)
 3262         {
 3263             struct timeval tv;
 3264             fd_set wfds;
 3265 
 3266             FD_ZERO(&rfds);
 3267             FD_SET(fd, &rfds);
 3268             FD_ZERO(&wfds);
 3269             FD_SET(fd, &wfds);
 3270             tv.tv_sec = 0;
 3271             tv.tv_usec = 10000;
 3272             ret = select(fd + 1, &rfds, &wfds, NULL, &tv);
 3273             (void)ret;
 3274 
 3275             if (stress_time_now() - t_start > threshold) {
 3276                 timeout = true;
 3277                 stress_dev_close_unlock(path, fd);
 3278                 goto next;
 3279             }
 3280         }
 3281 #endif
 3282 
 3283 #if defined(F_GETFD)
 3284         ret = fcntl(fd, F_GETFD, NULL);
 3285         (void)ret;
 3286 
 3287         if (stress_time_now() - t_start > threshold) {
 3288             timeout = true;
 3289             stress_dev_close_unlock(path, fd);
 3290             goto next;
 3291         }
 3292 #endif
 3293 #if defined(F_GETFL)
 3294         ret = fcntl(fd, F_GETFL, NULL);
 3295         (void)ret;
 3296 
 3297         if (stress_time_now() - t_start > threshold) {
 3298             timeout = true;
 3299             stress_dev_close_unlock(path, fd);
 3300             goto next;
 3301         }
 3302 #endif
 3303 #if defined(F_GETSIG)
 3304         ret = fcntl(fd, F_GETSIG, NULL);
 3305         (void)ret;
 3306 
 3307         if (stress_time_now() - t_start > threshold) {
 3308             timeout = true;
 3309             stress_dev_close_unlock(path, fd);
 3310             goto next;
 3311         }
 3312 #endif
 3313         ptr = mmap(NULL, args->page_size, PROT_READ, MAP_PRIVATE, fd, 0);
 3314         if (ptr != MAP_FAILED)
 3315             (void)munmap(ptr, args->page_size);
 3316         ptr = mmap(NULL, args->page_size, PROT_READ, MAP_SHARED, fd, 0);
 3317         if (ptr != MAP_FAILED)
 3318             (void)munmap(ptr, args->page_size);
 3319         (void)stress_dev_close_unlock(path, fd);
 3320 
 3321         if (stress_time_now() - t_start > threshold) {
 3322             timeout = true;
 3323             goto next;
 3324         }
 3325 
 3326         fd = stress_dev_open_lock(args, path, O_RDONLY | O_NONBLOCK | O_NDELAY);
 3327         if (fd < 0)
 3328             goto next;
 3329 
 3330         ptr = mmap(NULL, args->page_size, PROT_WRITE, MAP_PRIVATE, fd, 0);
 3331         if (ptr != MAP_FAILED)
 3332             (void)munmap(ptr, args->page_size);
 3333         ptr = mmap(NULL, args->page_size, PROT_WRITE, MAP_SHARED, fd, 0);
 3334         if (ptr != MAP_FAILED)
 3335             (void)munmap(ptr, args->page_size);
 3336 
 3337         ret = shim_fsync(fd);
 3338         (void)ret;
 3339 
 3340         for (i = 0; i < SIZEOF_ARRAY(dev_funcs); i++) {
 3341             if (!strncmp(path, dev_funcs[i].devpath, dev_funcs[i].devpath_len))
 3342                 dev_funcs[i].func(args, fd, path);
 3343         }
 3344         stress_dev_close_unlock(path, fd);
 3345         if (stress_time_now() - t_start > threshold) {
 3346             timeout = true;
 3347             goto next;
 3348         }
 3349         /*
 3350          *   O_RDONLY | O_WRONLY allows one to
 3351          *   use the fd for ioctl() only operations
 3352          */
 3353         fd = stress_dev_open_lock(args, path, O_RDONLY | O_WRONLY);
 3354         if (fd < 0) {
 3355             if (errno == EINTR)
 3356                 stress_hash_add(dev_open_fail, path);
 3357         } else {
 3358             stress_dev_close_unlock(path, fd);
 3359         }
 3360 
 3361 next:
 3362         if (loops > 0) {
 3363             if (timeout)
 3364                 break;
 3365             loops--;
 3366         }
 3367     }
 3368 }
 3369 
 3370 /*
 3371  *  stress_dev_thread
 3372  *  keep exercising a /dev entry until
 3373  *  controlling thread triggers an exit
 3374  */
 3375 static void *stress_dev_thread(void *arg)
 3376 {
 3377     static void *nowt = NULL;
 3378     const stress_pthread_args_t *pa = (stress_pthread_args_t *)arg;
 3379     const stress_args_t *args = pa->args;
 3380 
 3381     /*
 3382      *  Block all signals, let controlling thread
 3383      *  handle these
 3384      */
 3385     (void)sigprocmask(SIG_BLOCK, &set, NULL);
 3386 
 3387     while (keep_stressing_flag())
 3388         stress_dev_rw(args, -1);
 3389 
 3390     return &nowt;
 3391 }
 3392 
 3393 /*
 3394  *  stress_dev_file()
 3395  *  stress a specific device file
 3396  */
 3397 static void stress_dev_file(const stress_args_t *args, char *path)
 3398 {
 3399     int ret;
 3400     int32_t loops = args->instance < 8 ? (int32_t)args->instance + 1 : 8;
 3401 
 3402     ret = shim_pthread_spin_lock(&lock);
 3403     if (!ret) {
 3404         dev_path = path;
 3405         (void)shim_pthread_spin_unlock(&lock);
 3406         stress_dev_rw(args, loops);
 3407         inc_counter(args);
 3408     }
 3409 }
 3410 
 3411 /*
 3412  *  stress_dev_dir()
 3413  *  read directory
 3414  */
 3415 static void stress_dev_dir(
 3416     const stress_args_t *args,
 3417     const char *path,
 3418     const bool recurse,
 3419     const int depth,
 3420     const uid_t euid,
 3421     const char *tty_name)
 3422 {
 3423     struct dirent **dlist;
 3424     const mode_t flags = S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
 3425     int32_t loops = args->instance < 8 ? (int32_t)args->instance + 1 : 8;
 3426     int i, k, n;
 3427     static int try_failed;
 3428 
 3429     if (!keep_stressing_flag())
 3430         return;
 3431 
 3432     /* Don't want to go too deep */
 3433     if (depth > 20)
 3434         return;
 3435 
 3436     dlist = NULL;
 3437     n = scandir(path, &dlist, NULL, alphasort);
 3438     if (n <= 0)
 3439         goto done;
 3440 
 3441     /*
 3442      *  Shuffle
 3443      */
 3444     for (k = 0; k < 5; k++) {
 3445         for (i = 0; i < n; i++) {
 3446             int j = stress_mwc32() % n;
 3447             struct dirent *tmp;
 3448 
 3449             tmp = dlist[j];
 3450             dlist[j] = dlist[i];
 3451             dlist[i] = tmp;
 3452         }
 3453     }
 3454 
 3455     for (i = 0; i < n; i++) {
 3456         int ret;
 3457         struct stat buf;
 3458         char filename[PATH_MAX];
 3459         char tmp[PATH_MAX];
 3460         struct dirent *d = dlist[i];
 3461         size_t len;
 3462 
 3463         if (!keep_stressing(args))
 3464             break;
 3465         if (stress_is_dot_filename(d->d_name))
 3466             continue;
 3467 
 3468         /*
 3469          *  Avoid https://bugs.xenserver.org/browse/XSO-809
 3470          *  see: LP#1741409, so avoid opening /dev/hpet
 3471          */
 3472         if (!strcmp(d->d_name, "hpet") && linux_xen_guest())
 3473             continue;
 3474         if (!strncmp(d->d_name, "ttyS", 4))
 3475             continue;
 3476         len = strlen(d->d_name);
 3477 
 3478         /*
 3479          *  Exercise no more than 3 of the same device
 3480          *  driver, e.g. ttyS0..ttyS2
 3481          */
 3482         if (len > 1) {
 3483             int dev_n;
 3484             char *ptr = d->d_name + len - 1;
 3485 
 3486             while (ptr > d->d_name && isdigit((int)*ptr))
 3487                 ptr--;
 3488             ptr++;
 3489             dev_n = atoi(ptr);
 3490             if (dev_n > 2)
 3491                 continue;
 3492         }
 3493 
 3494         (void)stress_mk_filename(tmp, sizeof(tmp), path, d->d_name);
 3495 
 3496         /*
 3497          *  Avoid any actions on owner's tty
 3498          */
 3499         if (tty_name && !strcmp(tty_name, tmp))
 3500             continue;
 3501 
 3502         switch (d->d_type) {
 3503         case DT_DIR:
 3504             if (!recurse)
 3505                 continue;
 3506             if (stress_hash_get(dev_open_fail, tmp))
 3507                 continue;
 3508             ret = stat(tmp, &buf);
 3509             if (ret < 0) {
 3510                 stress_hash_add(dev_open_fail, tmp);
 3511                 continue;
 3512             }
 3513             if ((buf.st_mode & flags) == 0) {
 3514                 stress_hash_add(dev_open_fail, tmp);
 3515                 continue;
 3516             }
 3517             inc_counter(args);
 3518             stress_dev_dir(args, tmp, recurse, depth + 1, euid, tty_name);
 3519             break;
 3520         case DT_BLK:
 3521         case DT_CHR:
 3522             if (stress_hash_get(dev_open_fail, tmp))
 3523                 continue;
 3524             if (strstr(tmp, "watchdog")) {
 3525                 stress_hash_add(dev_open_fail, tmp);
 3526                 continue;
 3527             }
 3528 
 3529             /* If it was opened OK before, no need for try_open check */
 3530             if (!stress_hash_get(dev_open_ok, tmp)) {
 3531                 /* Limit the number of locked up try failures */
 3532                 if (try_failed > STRESS_DEV_OPEN_TRIES_MAX)
 3533                     continue;
 3534                 stress_dev_procname(tmp);
 3535                 ret = stress_try_open(args, tmp, O_RDONLY | O_NONBLOCK | O_NDELAY, 1500000000);
 3536                 if (ret == STRESS_TRY_OPEN_FAIL) {
 3537                     stress_hash_add(dev_open_fail, tmp);
 3538                     try_failed++;
 3539                     continue;
 3540                 }
 3541                 if (ret == STRESS_TRY_AGAIN)
 3542                     continue;
 3543             }
 3544             ret = shim_pthread_spin_lock(&lock);
 3545             if (!ret) {
 3546                 (void)memset(filename, 0, sizeof(filename));
 3547                 (void)shim_strlcpy(filename, tmp, sizeof(filename));
 3548                 dev_path = filename;
 3549                 (void)shim_pthread_spin_unlock(&lock);
 3550                 stress_dev_procname(filename);
 3551                 stress_dev_rw(args, loops);
 3552                 inc_counter(args);
 3553             }
 3554             stress_hash_add(dev_open_ok, tmp);
 3555             break;
 3556         default:
 3557             break;
 3558         }
 3559     }
 3560 done:
 3561     stress_dirent_list_free(dlist, n);
 3562 }
 3563 
 3564 /*
 3565  *  stress_dev
 3566  *  stress reading all of /dev
 3567  */
 3568 static int stress_dev(const stress_args_t *args)
 3569 {
 3570     pthread_t pthreads[STRESS_DEV_THREADS_MAX];
 3571     int ret[STRESS_DEV_THREADS_MAX], rc = EXIT_SUCCESS;
 3572     uid_t euid = geteuid();
 3573     stress_pthread_args_t pa;
 3574     char *dev_file = NULL;
 3575     const int stdout_fd = fileno(stdout);
 3576     const char *tty_name = (stdout_fd >= 0) ? ttyname(stdout_fd) : NULL;
 3577 
 3578     dev_path = "/dev/null";
 3579     pa.args = args;
 3580     pa.data = NULL;
 3581 
 3582     (void)memset(ret, 0, sizeof(ret));
 3583 
 3584     (void)stress_get_setting("dev-file", &dev_file);
 3585     if (dev_file) {
 3586         mode_t mode;
 3587         struct stat statbuf;
 3588 
 3589         if (stat(dev_file, &statbuf) < 0) {
 3590             pr_fail("%s: cannot access file %s\n",
 3591                 args->name, dev_file);
 3592             return EXIT_FAILURE;
 3593         }
 3594         mode = statbuf.st_mode & S_IFMT;
 3595         if ((mode != S_IFBLK) && (mode != S_IFCHR)) {
 3596             pr_fail("%s: file %s is not a character or block device\n",
 3597                 args->name, dev_file);
 3598             return EXIT_FAILURE;
 3599         }
 3600     }
 3601 
 3602     stress_set_proc_state(args->name, STRESS_STATE_RUN);
 3603 
 3604     do {
 3605         pid_t pid;
 3606 
 3607 again:
 3608         pid = fork();
 3609         if (pid < 0) {
 3610             if (stress_redo_fork(errno))
 3611                 goto again;
 3612         } else if (pid > 0) {
 3613             int status, wret;
 3614 
 3615             (void)setpgid(pid, g_pgrp);
 3616             /* Parent, wait for child */
 3617             wret = waitpid(pid, &status, 0);
 3618             if (wret < 0) {
 3619                 if (errno != EINTR)
 3620                     pr_dbg("%s: waitpid(): errno=%d (%s)\n",
 3621                         args->name, errno, strerror(errno));
 3622                 /* Ring ring, time to die */
 3623                 (void)kill(pid, SIGALRM);
 3624                 wret = shim_waitpid(pid, &status, 0);
 3625                 (void)wret;
 3626             } else {
 3627                 if (WIFEXITED(status) &&
 3628                     WEXITSTATUS(status) != 0) {
 3629                     rc = EXIT_FAILURE;
 3630                     break;
 3631                 }
 3632             }
 3633         } else if (pid == 0) {
 3634             size_t i;
 3635             int r;
 3636 
 3637             dev_open_fail = stress_hash_create(251);
 3638             if (!dev_open_fail) {
 3639                 pr_err("%s: cannot create device hash table: %d (%s))\n",
 3640                     args->name, errno, strerror(errno));
 3641                 _exit(EXIT_NO_RESOURCE);
 3642             }
 3643             dev_open_ok = stress_hash_create(509);
 3644             if (!dev_open_ok) {
 3645                 pr_err("%s: cannot create device hash table: %d (%s))\n",
 3646                     args->name, errno, strerror(errno));
 3647                 stress_hash_delete(dev_open_fail);
 3648                 _exit(EXIT_NO_RESOURCE);
 3649             }
 3650 
 3651             dev_scsi = stress_hash_create(251);
 3652             if (!dev_scsi) {
 3653                 pr_err("%s: cannot create scsi device hash table: %d (%s))\n",
 3654                     args->name, errno, strerror(errno));
 3655                 stress_hash_delete(dev_open_ok);
 3656                 stress_hash_delete(dev_open_fail);
 3657                 _exit(EXIT_NO_RESOURCE);
 3658             }
 3659 
 3660             (void)setpgid(0, g_pgrp);
 3661             stress_parent_died_alarm();
 3662             (void)sched_settings_apply(true);
 3663             rc = shim_pthread_spin_init(&lock, SHIM_PTHREAD_PROCESS_SHARED);
 3664             if (rc) {
 3665                 pr_inf("%s: pthread_spin_init failed, errno=%d (%s)\n",
 3666                     args->name, rc, strerror(rc));
 3667                 _exit(EXIT_NO_RESOURCE);
 3668             }
 3669             rc = shim_pthread_spin_init(&parport_lock, SHIM_PTHREAD_PROCESS_SHARED);
 3670             if (rc) {
 3671                 pr_inf("%s: pthread_spin_init failed, errno=%d (%s)\n",
 3672                     args->name, rc, strerror(rc));
 3673                 _exit(EXIT_NO_RESOURCE);
 3674             }
 3675 
 3676             /* Make sure this is killable by OOM killer */
 3677             stress_set_oom_adjustment(args->name, true);
 3678             mixup = stress_mwc32();
 3679 
 3680             for (i = 0; i < STRESS_DEV_THREADS_MAX; i++) {
 3681                 ret[i] = pthread_create(&pthreads[i], NULL,
 3682                         stress_dev_thread, (void *)&pa);
 3683             }
 3684 
 3685             do {
 3686                 if (dev_file)
 3687                     stress_dev_file(args, dev_file);
 3688                 else
 3689                     stress_dev_dir(args, "/dev", true, 0, euid, tty_name);
 3690             } while (keep_stressing(args));
 3691 
 3692             r = shim_pthread_spin_lock(&lock);
 3693             if (r) {
 3694                 pr_dbg("%s: failed to lock spin lock for dev_path\n", args->name);
 3695             } else {
 3696                 dev_path = "";
 3697                 r = shim_pthread_spin_unlock(&lock);
 3698                 (void)r;
 3699             }
 3700 
 3701             for (i = 0; i < STRESS_DEV_THREADS_MAX; i++) {
 3702                 if (ret[i] == 0)
 3703                     (void)pthread_join(pthreads[i], NULL);
 3704             }
 3705             stress_hash_delete(dev_scsi);
 3706             stress_hash_delete(dev_open_fail);
 3707             stress_hash_delete(dev_open_ok);
 3708             _exit(EXIT_SUCCESS);
 3709         }
 3710     } while (keep_stressing(args));
 3711 
 3712     stress_set_proc_state(args->name, STRESS_STATE_DEINIT);
 3713     (void)shim_pthread_spin_destroy(&lock);
 3714 
 3715     /*
 3716      *  Ensure we don't get build warnings if these are not
 3717      *  referenced.
 3718      */
 3719     (void)ioctl_set_timeout;
 3720     (void)ioctl_clr_timeout;
 3721 
 3722     return rc;
 3723 }
 3724 stressor_info_t stress_dev_info = {
 3725     .stressor = stress_dev,
 3726     .class = CLASS_DEV | CLASS_OS,
 3727     .opt_set_funcs = opt_set_funcs,
 3728     .help = help
 3729 };
 3730 #else
 3731 stressor_info_t stress_dev_info = {
 3732     .stressor = stress_not_implemented,
 3733     .class = CLASS_DEV | CLASS_OS,
 3734     .opt_set_funcs = opt_set_funcs,
 3735     .help = help
 3736 };
 3737 #endif