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