Mercurial > illumos > git > illumos-joyent
view usr/src/lib/fm/topo/modules/common/shared/topo_sensor.c @ 25635:ce2b70e7aab0
[illumos-gate merge]
commit 0a554e9f2c0d440dc40a97fae2d18f1d428ca786
13404 man page spelling errors
commit 9f76c6ed5b6ee0cc0bf631daca15ac3dc5fc70c4
13400 zfs-tests: implicit conversion from 'enum dmu_objset_type' to 'enum lzc_dataset_type'
commit ef96fc31fc4f4306719704352d5c3e33573c039f
13399 zfs: error: implicit conversion from 'boolean_t' to 'ds_hold_flags_t'
commit 56870e8c76c2675bcef1fcee5d519585ce9c768e
13393 cheetah: case value '47616' not in enumerated type
commit 8247326397b1a16f37e70cf13f5b7a4f50d06712
13403 zfs: symbol 'g_zfs' is multiply-defined
commit 436b964b19ef06803ad9165542d80d9d731d6486
13402 zpool: symbol 'g_zfs' is multiply-defined
commit 99308ed0417a2b8ab73c5856a8a5345ce2a7aea7
13396 PoolsExecption typo in resource pools javadoc
commit 1575b751c16622553e958c1e5c45e59c86b15c6e
13392 px: case value '3' not in enumerated type
commit 9b0429a10eec9313ec782d8421272aff70adbfdc
13339 Add support for Hygon Dhyana Family 18h processor
commit d20422bd742384b77102bb3bd09e0dc4b7372e50
13351 loader: vbe_find_mode_xydm() is using wrong safety and iteration is buggy
commit 174b8e455f9a6974e69fa4e28792580acde0892d
13311 uptime(1) dazed and confused for a minute after boot
commit f816551bb187d104fbf2757703d7a5d2189a3a18
13401 eeprom: 'lv' may be used uninitialized in this function
commit 5e96da73c99d9d17ff5a58b793fff2ab6dcadf25
13391 fm: build errors with gcc 7 on SPARC
commit 58b55f701e285559e4799354996fd284238ed0d4
13398 libstand: xdrproc_t should return bool
commit c6a28d7650029501a356f7b75b2a10a5c4430cef
13394 fhc: case value '4294967295' not in enumerated type
commit 58d4b16fe601073f2408de78e3db7e9bfa9abfd2
13355 remove topo module warning gags
commit 1473b8d60e902819558a8b0e8a257eb0d754c3c3
13388 ZFS list bookmark not working on zvols
commit 4bba12ca5cd6f92aaf0d4c0d19d05528110bc095
13368 libbe_py should support temporary BE activation
commit a92282e44f968185a6bba094d1e5fece2da819cf
13376 fm: variable may be used uninitialized
commit 8b1df8bf71b7b62e7e4d46fe6b457d4d6447b2b8
13367 beadm activate -t should not promote new BE datasets
commit 9704bf7fb82e71b685e194a967937ff03843e73a
13317 Decrease contention on dn_struct_rwlock
commit 88a08813800ed7ba7c927986421cee437f7f2233
13363 ctfconvert could support more granular ignore for missing debug data
commit 3dd4cd56e7843e01a8ab147a0d102cd4f6d732c1
13342 ctfconvert could encode _Float128 for 32-bit objects
commit 73197b540cc5f0434c409b68ca9e1a514a6ce91b
13336 ctfconvert should be able to unconditionally attempt conversion
commit dd4422524768709a579a2a93a10c78a88a6b0ecb
13280 CTF: provide option to truncate and continue
Conflicts & other fixes (with help from Jason King <jbk@joyent.com>):
usr/src/lib/fm/topo/modules/common/ipmi/ipmi_enum.c
usr/src/lib/libctf/common/ctf_convert.c
usr/src/lib/libctf/common/ctf_lib.c
usr/src/lib/libctf/common/libctf.h
usr/src/lib/libproc/common/Psymtab.c
usr/src/man/man1/ld.so.1.1
usr/src/man/man4/process.4
author | Dan McDonald <danmcd@joyent.com> |
---|---|
date | Mon, 04 Jan 2021 14:49:49 -0500 |
parents | 39e726bb90a9 a87c414f8206 |
children |
line wrap: on
line source
/* * This file and its contents are supplied under the terms of the * Common Development and Distribution License ("CDDL"), version 1.0. * You may only use this file in accordance with the terms of version * 1.0 of the CDDL. * * A full copy of the text of the CDDL should have accompanied this * source. A copy of the CDDL is also available via the Internet at * http://www.illumos.org/license/CDDL. */ /* * Copyright 2019, Joyent, Inc. * Copyright 2020 Oxide Computer Company */ /* * This file provides routines to interact with the kernel sensor framework. * Currently, modules that require interacting with a kernel sensor need to * build this file as part of the module. This takes care of all the work of * setting up and creating the sensor, given a path to that sensor. */ #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <stdio.h> #include <string.h> #include <unistd.h> #include <libnvpair.h> #include <sys/sensors.h> #include <sys/fm/protocol.h> #include <fm/topo_mod.h> #define TOPO_METH_TOPO_SENSOR_SCALAR "topo_sensor_scalar_reading" #define TOPO_METH_TOPO_SENSOR_SCALAR_DESC "Kernel Sensor Scalar Reading" #define TOPO_METH_TOPO_SENSOR_SCALAR_VERSION 0 static int topo_sensor_scalar_read(topo_mod_t *mod, tnode_t *node, topo_version_t vers, nvlist_t *in, nvlist_t **out) { int fd = -1, ret; nvlist_t *args, *nvl; char *path; sensor_ioctl_scalar_t scalar; double value; if (vers != TOPO_METH_TOPO_SENSOR_SCALAR_VERSION) { return (topo_mod_seterrno(mod, ETOPO_METHOD_VERNEW)); } if (nvlist_lookup_nvlist(in, TOPO_PROP_ARGS, &args) != 0 || nvlist_lookup_string(args, TOPO_IO_DEV_PATH, &path) != 0) { topo_mod_dprintf(mod, "failed to lookup sensor path from " "property %s", TOPO_IO_DEV_PATH); return (topo_mod_seterrno(mod, EMOD_NVL_INVAL)); } if ((fd = open(path, O_RDONLY)) < 0) { topo_mod_dprintf(mod, "failed to open sensor path %s: %s", path, strerror(errno)); return (topo_mod_seterrno(mod, EMOD_UNKNOWN)); } (void) memset(&scalar, '\0', sizeof (scalar)); if (ioctl(fd, SENSOR_IOCTL_SCALAR, &scalar) != 0) { topo_mod_dprintf(mod, "failed to read sensor %s: %s", path, strerror(errno)); ret = topo_mod_seterrno(mod, EMOD_UNKNOWN); goto out; } /* * Check to see if we need to change the value to get it into an * accurate reading. Positive granularities indicate that the sensor * reading is in a fractional number of units and that each unit * contains scalar.sis_gran steps. A negative number means that the * sensor reading represents scalar.sis_gran units. */ value = (double)scalar.sis_value; if (scalar.sis_gran > 1) { value /= (double)scalar.sis_gran; } else if (scalar.sis_gran < -1) { value *= (double)labs(scalar.sis_gran); } if (topo_mod_nvalloc(mod, &nvl, NV_UNIQUE_NAME) != 0) { topo_mod_dprintf(mod, "failed to allocate output nvl"); ret = topo_mod_seterrno(mod, EMOD_NOMEM); goto out; } if (nvlist_add_string(nvl, TOPO_PROP_VAL_NAME, TOPO_SENSOR_READING) != 0 || nvlist_add_uint32(nvl, TOPO_PROP_VAL_TYPE, TOPO_TYPE_DOUBLE) != 0 || nvlist_add_double(nvl, TOPO_PROP_VAL_VAL, value) != 0) { topo_mod_dprintf(mod, "failed to add members to output " "sensor nvlist"); nvlist_free(nvl); ret = topo_mod_seterrno(mod, EMOD_NOMEM); goto out; } *out = nvl; ret = 0; out: if (fd >= 0) { (void) close(fd); } return (ret); } static const topo_method_t topo_sensor_scalar_fac_methods[] = { { TOPO_METH_TOPO_SENSOR_SCALAR, TOPO_METH_TOPO_SENSOR_SCALAR_DESC, TOPO_METH_TOPO_SENSOR_SCALAR_VERSION, TOPO_STABILITY_INTERNAL, topo_sensor_scalar_read }, { NULL } }; static topo_sensor_unit_t topo_sensor_units(const sensor_ioctl_scalar_t *scalar) { switch (scalar->sis_unit) { case SENSOR_UNIT_CELSIUS: return (TOPO_SENSOR_UNITS_DEGREES_C); case SENSOR_UNIT_FAHRENHEIT: return (TOPO_SENSOR_UNITS_DEGREES_F); case SENSOR_UNIT_KELVIN: return (TOPO_SENSOR_UNITS_DEGREES_K); case SENSOR_UNIT_VOLTS: return (TOPO_SENSOR_UNITS_VOLTS); case SENSOR_UNIT_AMPS: return (TOPO_SENSOR_UNITS_AMPS); default: return (TOPO_SENSOR_UNITS_UNSPECIFIED); } } int topo_sensor_create_scalar_sensor(topo_mod_t *mod, tnode_t *pnode, const char *path, const char *fname) { int fd, ret, err; sensor_ioctl_kind_t sik; sensor_ioctl_scalar_t scalar; uint32_t topo_type; tnode_t *fnode = NULL; topo_pgroup_info_t pgi; nvlist_t *reader_arg = NULL; topo_mod_dprintf(mod, "attempting to create sensor for %s at %s", topo_node_name(pnode), path); (void) memset(&sik, '\0', sizeof (sik)); (void) memset(&scalar, '\0', sizeof (scalar)); if ((fd = open(path, O_RDONLY)) < 0) { topo_mod_dprintf(mod, "failed to open sensor path %s: %s", path, strerror(errno)); /* * We always try to create sensors; however, they may not exist * or be supported on the system in question. Therefore ENOENT * is totally acceptable. */ if (errno == ENOENT) { return (0); } return (topo_mod_seterrno(mod, EMOD_UNKNOWN)); } if (ioctl(fd, SENSOR_IOCTL_KIND, &sik) != 0) { topo_mod_dprintf(mod, "failed to verify sensor kind for sensor " "%s: %s", path, strerror(errno)); ret = topo_mod_seterrno(mod, EMOD_UNKNOWN); goto out; } switch (sik.sik_kind) { case SENSOR_KIND_TEMPERATURE: topo_type = TOPO_SENSOR_TYPE_TEMP; break; case SENSOR_KIND_VOLTAGE: topo_type = TOPO_SENSOR_TYPE_VOLTAGE; break; case SENSOR_KIND_CURRENT: topo_type = TOPO_SENSOR_TYPE_CURRENT; break; default: topo_mod_dprintf(mod, "unknown sensor kind for %s, found 0x%x", path, sik.sik_kind); ret = topo_mod_seterrno(mod, EMOD_UNKNOWN); goto out; } if (ioctl(fd, SENSOR_IOCTL_SCALAR, &scalar) != 0) { topo_mod_dprintf(mod, "failed to read scalar sensor %s: %s", path, strerror(errno)); ret = topo_mod_seterrno(mod, EMOD_UNKNOWN); goto out; } (void) close(fd); fd = -1; if ((fnode = topo_node_facbind(mod, pnode, fname, TOPO_FAC_TYPE_SENSOR)) == NULL) { topo_mod_dprintf(mod, "failed to bind sensor facility " "node to %s: %d", path, topo_mod_errno(mod)); ret = -1; goto out; } pgi.tpi_name = TOPO_PGROUP_FACILITY; pgi.tpi_namestab = TOPO_STABILITY_PRIVATE; pgi.tpi_datastab = TOPO_STABILITY_PRIVATE; pgi.tpi_version = 1; if (topo_pgroup_create(fnode, &pgi, &err) != 0) { topo_mod_dprintf(mod, "failed to create facility pgroup: %s", topo_strerror(err)); ret = topo_mod_seterrno(mod, err); goto out; } if (topo_prop_set_string(fnode, TOPO_PGROUP_FACILITY, TOPO_SENSOR_CLASS, TOPO_PROP_IMMUTABLE, TOPO_SENSOR_CLASS_THRESHOLD, &err) != 0 || topo_prop_set_uint32(fnode, TOPO_PGROUP_FACILITY, TOPO_FACILITY_TYPE, TOPO_PROP_IMMUTABLE, topo_type, &err) != 0 || topo_prop_set_uint32(fnode, TOPO_PGROUP_FACILITY, TOPO_SENSOR_UNITS, TOPO_PROP_IMMUTABLE, topo_sensor_units(&scalar), &err) != 0) { topo_mod_dprintf(mod, "failed to set properties for sensor " "%s: %s", path, topo_strerror(err)); ret = topo_mod_seterrno(mod, err); goto out; } if (topo_method_register(mod, fnode, topo_sensor_scalar_fac_methods) < 0) { topo_mod_dprintf(mod, "failed to register reading methods on " "%s", path); ret = -1; goto out; } if (topo_mod_nvalloc(mod, &reader_arg, NV_UNIQUE_NAME) != 0 || nvlist_add_string(reader_arg, TOPO_IO_DEV_PATH, path) != 0) { topo_mod_dprintf(mod, "Failed to set up reader argument nvl"); ret = topo_mod_seterrno(mod, EMOD_NOMEM); goto out; } if (topo_prop_method_register(fnode, TOPO_PGROUP_FACILITY, TOPO_SENSOR_READING, TOPO_TYPE_DOUBLE, TOPO_METH_TOPO_SENSOR_SCALAR, reader_arg, &err) != 0) { topo_mod_dprintf(mod, "failed to set argument for sensor %s: " "%s", path, topo_strerror(err)); ret = topo_mod_seterrno(mod, err); goto out; } topo_mod_dprintf(mod, "created sensor at %s", path); nvlist_free(reader_arg); return (0); out: if (fd >= 0) { (void) close(fd); } topo_node_unbind(fnode); nvlist_free(reader_arg); return (ret); }