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 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_temperature_t temp; 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(&temp, sizeof (temp)); 77 if (ioctl(fd, SENSOR_IOCTL_TEMPERATURE, &temp) != 0) { 78 warn("failed to get sensor temp on %s", buf); 79 } 80 81 if (temp.sit_unit != SENSOR_UNIT_CELSIUS) { 82 warnx("data from sensor %s looks off, expected sensor " 83 "to indicate Celsius, but instead %u", 84 temp.sit_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