13ce53722SRobert Mustacchi /*
23ce53722SRobert Mustacchi  * This file and its contents are supplied under the terms of the
33ce53722SRobert Mustacchi  * Common Development and Distribution License ("CDDL"), version 1.0.
43ce53722SRobert Mustacchi  * You may only use this file in accordance with the terms of version
53ce53722SRobert Mustacchi  * 1.0 of the CDDL.
63ce53722SRobert Mustacchi  *
73ce53722SRobert Mustacchi  * A full copy of the text of the CDDL should have accompanied this
83ce53722SRobert Mustacchi  * source.  A copy of the CDDL is also available via the Internet at
93ce53722SRobert Mustacchi  * http://www.illumos.org/license/CDDL.
103ce53722SRobert Mustacchi  */
113ce53722SRobert Mustacchi 
123ce53722SRobert Mustacchi /*
133ce53722SRobert Mustacchi  * Copyright 2020 Oxide Computer Company
143ce53722SRobert Mustacchi  */
153ce53722SRobert Mustacchi 
163ce53722SRobert Mustacchi /*
173ce53722SRobert Mustacchi  * Basic program that reads random sensors, mostly ignoring errors. This is in
183ce53722SRobert Mustacchi  * support of the stress test program.
193ce53722SRobert Mustacchi  */
203ce53722SRobert Mustacchi 
213ce53722SRobert Mustacchi #include <sys/types.h>
223ce53722SRobert Mustacchi #include <sys/stat.h>
233ce53722SRobert Mustacchi #include <fcntl.h>
243ce53722SRobert Mustacchi #include <stdlib.h>
253ce53722SRobert Mustacchi #include <sys/sensors.h>
263ce53722SRobert Mustacchi #include <unistd.h>
273ce53722SRobert Mustacchi #include <string.h>
283ce53722SRobert Mustacchi #include <err.h>
293ce53722SRobert Mustacchi #include <limits.h>
303ce53722SRobert Mustacchi #include <strings.h>
313ce53722SRobert Mustacchi 
323ce53722SRobert Mustacchi /*
333ce53722SRobert Mustacchi  * Wait for a random amount in 1500 ms, but make sure to wait at least 10ms.
343ce53722SRobert Mustacchi  */
353ce53722SRobert Mustacchi static uint32_t timeout = 1500;
363ce53722SRobert Mustacchi static uint32_t skew = 10;
373ce53722SRobert Mustacchi 
383ce53722SRobert Mustacchi int
main(int argc,const char * argv[])393ce53722SRobert Mustacchi main(int argc, const char *argv[])
403ce53722SRobert Mustacchi {
413ce53722SRobert Mustacchi 	int nsensors = 0, ninst = 0;
423ce53722SRobert Mustacchi 	uint32_t ms;
433ce53722SRobert Mustacchi 
443ce53722SRobert Mustacchi 	if (argc != 3) {
453ce53722SRobert Mustacchi 		errx(EXIT_FAILURE, "missing required args: ninstance, "
463ce53722SRobert Mustacchi 		    "nsensors");
473ce53722SRobert Mustacchi 	}
483ce53722SRobert Mustacchi 
493ce53722SRobert Mustacchi 	nsensors = atoi(argv[1]);
503ce53722SRobert Mustacchi 	ninst = atoi(argv[2]);
513ce53722SRobert Mustacchi 	if (nsensors <= 0 || ninst <= 0) {
523ce53722SRobert Mustacchi 		errx(EXIT_FAILURE, "got bad values for some of nesnsors (%u), "
533ce53722SRobert Mustacchi 		    "ninst (%u)", nsensors, ninst);
543ce53722SRobert Mustacchi 	}
553ce53722SRobert Mustacchi 
563ce53722SRobert Mustacchi 	for (;;) {
573ce53722SRobert Mustacchi 		int fd;
583ce53722SRobert Mustacchi 		char buf[PATH_MAX];
593ce53722SRobert Mustacchi 		uint32_t sens, inst;
603ce53722SRobert Mustacchi 		struct timespec ts;
611045e13aSRobert Mustacchi 		sensor_ioctl_scalar_t scalar;
623ce53722SRobert Mustacchi 
633ce53722SRobert Mustacchi 		/* 0s based */
643ce53722SRobert Mustacchi 		sens = arc4random_uniform(nsensors);
653ce53722SRobert Mustacchi 		/* 1s based */
663ce53722SRobert Mustacchi 		inst = arc4random_uniform(ninst) + 1;
673ce53722SRobert Mustacchi 		(void) snprintf(buf, sizeof (buf),
683ce53722SRobert Mustacchi 		    "/dev/sensors/test/test.temp.%u.%u", sens, inst);
693ce53722SRobert Mustacchi 
703ce53722SRobert Mustacchi 		fd = open(buf, O_RDONLY);
713ce53722SRobert Mustacchi 		if (fd < 0) {
723ce53722SRobert Mustacchi 			warn("failed to open %s", buf);
733ce53722SRobert Mustacchi 			goto wait;
743ce53722SRobert Mustacchi 		}
753ce53722SRobert Mustacchi 
761045e13aSRobert Mustacchi 		bzero(&scalar, sizeof (scalar));
771045e13aSRobert Mustacchi 		if (ioctl(fd, SENSOR_IOCTL_SCALAR, &scalar) != 0) {
781045e13aSRobert Mustacchi 			warn("failed to get sensor temperature on %s", buf);
793ce53722SRobert Mustacchi 		}
803ce53722SRobert Mustacchi 
811045e13aSRobert Mustacchi 		if (scalar.sis_unit != SENSOR_UNIT_CELSIUS) {
823ce53722SRobert Mustacchi 			warnx("data from sensor %s looks off, expected sensor "
83*1e56f352SRobert Mustacchi 			    "to indicate Celsius, but instead %u", buf,
841045e13aSRobert Mustacchi 			    scalar.sis_unit);
853ce53722SRobert Mustacchi 		}
863ce53722SRobert Mustacchi 
873ce53722SRobert Mustacchi 		(void) close(fd);
883ce53722SRobert Mustacchi wait:
893ce53722SRobert Mustacchi 		ms = arc4random_uniform(timeout) + skew;
903ce53722SRobert Mustacchi 		ts.tv_sec = ms / 1000;
913ce53722SRobert Mustacchi 		ts.tv_nsec = (ms % 1000) * (NANOSEC / MILLISEC);
923ce53722SRobert Mustacchi 		(void) nanosleep(&ts, NULL);
933ce53722SRobert Mustacchi 	}
943ce53722SRobert Mustacchi 	return (0);
953ce53722SRobert Mustacchi }
96