hwmontemp: add labels attribute support
Adds Labels support to Hwmontemp. The behavior is meant to be identical
to the behavior of Labels from PSUSensors.
Labels has the following behavior:
When discovering Name, Name1...NameX attributes from the configuration
and an associated temp is found
If tempX_label exists and its contents is in the Labels attribute then
create the sensor
If tempX_label does not exist but tempX is in the Labels attribute then
create the sensor
If Labels attribute is not present or is an empty list then create the
sensor
Tested:
Had a simple , publically available MAX6581 sensor that has
temp1, temp2, temp3, temp4, temp5
and tested with
Labels = ["temp1", "temp2", "temp3", "temp4", "temp5"]
├─/xyz/openbmc_project/sensors/temperature/max6581_1
├─/xyz/openbmc_project/sensors/temperature/max6581_2
├─/xyz/openbmc_project/sensors/temperature/max6581_3
├─/xyz/openbmc_project/sensors/temperature/max6581_4
├─/xyz/openbmc_project/sensors/temperature/max6581_5
Labels omitted
├─/xyz/openbmc_project/sensors/temperature/max6581_1
├─/xyz/openbmc_project/sensors/temperature/max6581_2
├─/xyz/openbmc_project/sensors/temperature/max6581_3
├─/xyz/openbmc_project/sensors/temperature/max6581_4
├─/xyz/openbmc_project/sensors/temperature/max6581_5
Labels containing temp2,temp5
Results:
├─/xyz/openbmc_project/sensors/temperature/max6581_2
├─/xyz/openbmc_project/sensors/temperature/max6581_5
And a similar test with a device that has temperature labels
"Labels": [
"device_label_A",
"device_label_B",
"device_label_C"
],
├─/xyz/openbmc_project/sensors/temperature/device1_label_A
├─/xyz/openbmc_project/sensors/temperature/device1_label_B
├─/xyz/openbmc_project/sensors/temperature/device1_label_C
Signed-off-by: Jason Ling <jasonling@google.com>
Change-Id: I6cb9edb0c7ae68fe01663d4ee1be0070715e9f82
diff --git a/src/Utils.cpp b/src/Utils.cpp
index b8e4506..899ec98 100644
--- a/src/Utils.cpp
+++ b/src/Utils.cpp
@@ -40,6 +40,93 @@
static std::unique_ptr<sdbusplus::bus::match::match> powerMatch = nullptr;
static std::unique_ptr<sdbusplus::bus::match::match> postMatch = nullptr;
+/**
+ * return the contents of a file
+ * @param[in] hwmonFile - the path to the file to read
+ * @return the contents of the file as a string or nullopt if the file could not
+ * be opened.
+ */
+
+std::optional<std::string> openAndRead(const std::string& hwmonFile)
+{
+ std::string fileVal;
+ std::ifstream fileStream(hwmonFile);
+ if (!fileStream.is_open())
+ {
+ return std::nullopt;
+ }
+ std::getline(fileStream, fileVal);
+ return fileVal;
+}
+
+/**
+ * given a hwmon temperature base name if valid return the full path else
+ * nullopt
+ * @param[in] directory - the hwmon sysfs directory
+ * @param[in] permitSet - a set of labels or hwmon basenames to permit. If this
+ * is empty then *everything* is permitted.
+ * @return a string to the full path of the file to create a temp sensor with or
+ * nullopt to indicate that no sensor should be created for this basename.
+ */
+std::optional<std::string>
+ getFullHwmonFilePath(const std::string& directory,
+ const std::string& hwmonBaseName,
+ const std::set<std::string>& permitSet)
+{
+ std::optional<std::string> result;
+ std::string filename;
+ if (permitSet.empty())
+ {
+ result = directory + "/" + hwmonBaseName + "_input";
+ return result;
+ }
+ filename = directory + "/" + hwmonBaseName + "_label";
+ auto searchVal = openAndRead(filename);
+ if (!searchVal)
+ {
+ /* if the hwmon temp doesn't have a corresponding label file
+ * then use the hwmon temperature base name
+ */
+ searchVal = hwmonBaseName;
+ }
+ if (permitSet.find(*searchVal) != permitSet.end())
+ {
+ result = directory + "/" + hwmonBaseName + "_input";
+ }
+ return result;
+}
+
+/**
+ * retrieve a set of basenames and labels to allow sensor creation for.
+ * @param[in] config - a map representing the configuration for a specific
+ * device
+ * @return a set of basenames and labels to allow sensor creation for. An empty
+ * set indicates that everything is permitted.
+ */
+std::set<std::string> getPermitSet(const SensorBaseConfigMap& config)
+{
+ auto permitAttribute = config.find("Labels");
+ std::set<std::string> permitSet;
+ if (permitAttribute != config.end())
+ {
+ try
+ {
+ auto val =
+ std::get<std::vector<std::string>>(permitAttribute->second);
+
+ permitSet.insert(std::make_move_iterator(val.begin()),
+ std::make_move_iterator(val.end()));
+ }
+ catch (const std::bad_variant_access& err)
+ {
+ std::cerr << err.what()
+ << ":PermitList does not contain a list, wrong "
+ "variant type.\n";
+ }
+ }
+ return permitSet;
+}
+
bool getSensorConfiguration(
const std::string& type,
const std::shared_ptr<sdbusplus::asio::connection>& dbusConnection,