1 /*
2 * This file and its contents are supplied under the terms of the
3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 * You may only use this file in accordance with the terms of version
5 * 1.0 of the CDDL.
6 *
7 * A full copy of the text of the CDDL should have accompanied this
8 * source. A copy of the CDDL is also available via the Internet at
9 * http://www.illumos.org/license/CDDL.
10 */
11
12 /*
13 * Copyright 2020 Oxide Computer Company
14 */
15
16 /*
17 * Basic program that reads random sensors, mostly ignoring errors. This is in
18 * support of the stress test program.
19 */
20
21 #include <sys/types.h>
22 #include <sys/stat.h>
23 #include <fcntl.h>
24 #include <stdlib.h>
25 #include <sys/sensors.h>
26 #include <unistd.h>
27 #include <string.h>
28 #include <err.h>
29 #include <limits.h>
30 #include <strings.h>
31
32 /*
33 * Wait for a random amount in 1500 ms, but make sure to wait at least 10ms.
34 */
35 static uint32_t timeout = 1500;
36 static uint32_t skew = 10;
37
38 int
main(int argc,const char * argv[])39 main(int argc, const char *argv[])
40 {
41 int nsensors = 0, ninst = 0;
42 uint32_t ms;
43
44 if (argc != 3) {
45 errx(EXIT_FAILURE, "missing required args: ninstance, "
46 "nsensors");
47 }
48
49 nsensors = atoi(argv[1]);
50 ninst = atoi(argv[2]);
51 if (nsensors <= 0 || ninst <= 0) {
52 errx(EXIT_FAILURE, "got bad values for some of nesnsors (%u), "
53 "ninst (%u)", nsensors, ninst);
54 }
55
56 for (;;) {
57 int fd;
58 char buf[PATH_MAX];
59 uint32_t sens, inst;
60 struct timespec ts;
61 sensor_ioctl_scalar_t scalar;
62
63 /* 0s based */
64 sens = arc4random_uniform(nsensors);
65 /* 1s based */
66 inst = arc4random_uniform(ninst) + 1;
67 (void) snprintf(buf, sizeof (buf),
68 "/dev/sensors/test/test.temp.%u.%u", sens, inst);
69
70 fd = open(buf, O_RDONLY);
71 if (fd < 0) {
72 warn("failed to open %s", buf);
73 goto wait;
74 }
75
76 bzero(&scalar, sizeof (scalar));
77 if (ioctl(fd, SENSOR_IOCTL_SCALAR, &scalar) != 0) {
78 warn("failed to get sensor temperature on %s", buf);
79 }
80
81 if (scalar.sis_unit != SENSOR_UNIT_CELSIUS) {
82 warnx("data from sensor %s looks off, expected sensor "
83 "to indicate Celsius, but instead %u", buf,
84 scalar.sis_unit);
85 }
86
87 (void) close(fd);
88 wait:
89 ms = arc4random_uniform(timeout) + skew;
90 ts.tv_sec = ms / 1000;
91 ts.tv_nsec = (ms % 1000) * (NANOSEC / MILLISEC);
92 (void) nanosleep(&ts, NULL);
93 }
94 return (0);
95 }
96