presence: Hard code JSON config file locations
Instead of using locations provided at configure time to retrieve the
JSON config file, hard code the directory paths and the dbus
interface/property used. This simplifies what's required to be given at
configure time and eliminates complexities in the possible locations the
JSON config files could be stored in.
The expected value retrieved from dbus is a relative location to the
base path /usr/share/phosphor-fan-presence/presence/[DBUS_VALUE]
Tested:
Config file is able to loaded from each location
Dbus property value used relative to base path location
Change-Id: I831647f78887b3948ce35be4015fd7762748838d
Signed-off-by: Matthew Barth <msbarth@us.ibm.com>
diff --git a/presence/json_config.cpp b/presence/json_config.cpp
index 59d452a..deccbf1 100644
--- a/presence/json_config.cpp
+++ b/presence/json_config.cpp
@@ -18,12 +18,15 @@
#include <fstream>
#include <nlohmann/json.hpp>
#include <phosphor-logging/log.hpp>
+#include <sdbusplus/bus.hpp>
#include "json_config.hpp"
+#include "config.h"
#include "tach.hpp"
#include "gpio.hpp"
#include "anyof.hpp"
#include "fallback.hpp"
+#include "sdbusplus.hpp"
namespace phosphor
{
@@ -48,19 +51,13 @@
{"fallback", rpolicy::getFallback}
};
-JsonConfig::JsonConfig(const std::string& jsonConfigPath) :
- _defaultFile(fs::path(fs::path{jsonConfigPath} / jsonFileName))
+JsonConfig::JsonConfig(sdbusplus::bus::bus& bus) :
+ _bus(bus)
{
- if (!_defaultFile.empty())
- {
- // Load and process the json configuration
- load();
- }
- else
- {
- log<level::ERR>("No JSON config file provided");
- throw std::runtime_error("No JSON config file provided");
- }
+ // Determine the configuration file to use
+ _confFile = getConfFile();
+ // Load and process the json configuration
+ load();
}
const policies& JsonConfig::get()
@@ -73,6 +70,10 @@
{
try
{
+ // Determine the configuration file to use
+ _confFile = getConfFile();
+ log<level::INFO>("Loading configuration",
+ entry("JSON_FILE=%s", _confFile.c_str()));
// Load and process the json configuration
load();
for (auto& p: _policies)
@@ -88,24 +89,69 @@
}
}
-void JsonConfig::load()
+const fs::path JsonConfig::getConfFile()
{
- fs::path confFile{fs::path{jsonOverridePath} / jsonFileName};
- if (!fs::exists(confFile))
+ // Check override location
+ fs::path confFile = fs::path{confOverridePath} / confFileName;
+ if (fs::exists(confFile))
{
- confFile = _defaultFile;
+ return confFile;
+ }
+
+ // Check base path location
+ confFile = fs::path{confBasePath} / confFileName;
+ if (fs::exists(confFile))
+ {
+ return confFile;
+ }
+
+ // Check dbus interface & property
+ // Use first object returned in the subtree
+ // (Should really be only one object with the config interface)
+ auto objects = util::SDBusPlus::getSubTreeRaw(_bus, "/", confDbusIntf, 0);
+ auto itObj = objects.begin();
+ if (itObj != objects.end())
+ {
+ auto itServ = itObj->second.begin();
+ if (itServ != itObj->second.end())
+ {
+ // Retrieve json config relative path location from dbus
+ auto relPathLoc = util::SDBusPlus::getProperty<std::string>(
+ _bus, itServ->first, itObj->first,
+ confDbusIntf, confDbusProp);
+ confFile = fs::path{confBasePath} / relPathLoc / confFileName;
+ if (!fs::exists(confFile))
+ {
+ log<level::ERR>("No JSON config file found",
+ entry("NO_FILE=%s", confFile.c_str()));
+ throw std::runtime_error("No JSON config file found");
+ }
+ }
+ else
+ {
+ log<level::ERR>("No JSON config file found",
+ entry("NO_SERVICE=%s", itObj->first.c_str()));
+ throw std::runtime_error("No JSON config file found");
+ }
}
else
{
- log<level::INFO>("Loading alternate configuration",
- entry("JSON_FILE=%s", confFile.c_str()));
+ log<level::ERR>("No JSON config file found",
+ entry("NO_INTERFACE=%s", confDbusIntf));
+ throw std::runtime_error("No JSON config file found");
}
+
+ return confFile;
+}
+
+void JsonConfig::load()
+{
std::ifstream file;
json jsonConf;
- if (fs::exists(confFile))
+ if (fs::exists(_confFile))
{
- file.open(confFile);
+ file.open(_confFile);
try
{
jsonConf = json::parse(file);
@@ -113,7 +159,7 @@
catch (std::exception& e)
{
log<level::ERR>("Failed to parse JSON config file",
- entry("JSON_FILE=%s", confFile.c_str()),
+ entry("JSON_FILE=%s", _confFile.c_str()),
entry("JSON_ERROR=%s", e.what()));
throw std::runtime_error("Failed to parse JSON config file");
}
@@ -121,7 +167,7 @@
else
{
log<level::ERR>("Unable to open JSON config file",
- entry("JSON_FILE=%s", confFile.c_str()));
+ entry("JSON_FILE=%s", _confFile.c_str()));
throw std::runtime_error("Unable to open JSON config file");
}
diff --git a/presence/json_config.hpp b/presence/json_config.hpp
index 206b290..1e31939 100644
--- a/presence/json_config.hpp
+++ b/presence/json_config.hpp
@@ -6,6 +6,7 @@
#include <nlohmann/json.hpp>
#include <filesystem>
#include <sdeventplus/source/signal.hpp>
+#include <sdbusplus/bus.hpp>
#include "config.h"
#include "rpolicy.hpp"
@@ -22,8 +23,11 @@
namespace fs = std::filesystem;
using json = nlohmann::json;
-constexpr auto jsonFileName = "config.json";
-constexpr auto jsonOverridePath = "/etc/phosphor-fan-presence/presence";
+constexpr auto confFileName = "config.json";
+constexpr auto confOverridePath = "/etc/phosphor-fan-presence/presence";
+constexpr auto confBasePath = "/usr/share/phosphor-fan-presence/presence";
+constexpr auto confDbusIntf = "xyz.openbmc_project.Configs.ThermalApps";
+constexpr auto confDbusProp = "FanPresence";
using policies = std::vector<std::unique_ptr<RedundancyPolicy>>;
@@ -53,9 +57,9 @@
* Constructor
* Parses and populates the fan presence policies from a json file
*
- * @param[in] jsonConfigPath - json configuration path
+ * @param[in] bus - sdbusplus bus object
*/
- explicit JsonConfig(const std::string& jsonConfigPath);
+ explicit JsonConfig(sdbusplus::bus::bus& bus);
/**
* @brief Get the json config based fan presence policies
@@ -79,8 +83,11 @@
/* Fan presence policies */
static policies _policies;
- /* Default json configuration file */
- const fs::path _defaultFile;
+ /* The sdbusplus bus object */
+ sdbusplus::bus::bus& _bus;
+
+ /* Config file to be used */
+ fs::path _confFile;
/* List of Fan objects to have presence policies */
std::vector<fanPolicy> _fans;
@@ -95,6 +102,17 @@
static const std::map<std::string, rpolicyHandler> _rpolicies;
/**
+ * Get the json configuration file. The first location found to contain
+ * the json config file is used from the following locations in order.
+ * 1.) confOverridePath ("/etc/phosphor-fan-presence/presence")
+ * 2.) confBasePath ("/usr/share/phosphor-fan-presence/presence")
+ * 3.) From first dbus object found hosting
+ * interface = Interface set in confDbusIntf
+ * property = Property set in confDbusProp
+ */
+ const fs::path getConfFile();
+
+ /**
* @brief Load the json config file
*/
void load();
diff --git a/presence/tach_detect.cpp b/presence/tach_detect.cpp
index 1636b9a..e374c12 100644
--- a/presence/tach_detect.cpp
+++ b/presence/tach_detect.cpp
@@ -14,13 +14,11 @@
* limitations under the License.
*/
#include "config.h"
-#if defined(PRESENCE_JSON_FILE) || \
- (defined(PRESENCE_JSON_DBUS_INTF) && defined(PRESENCE_JSON_DBUS_PROP))
+#ifdef PRESENCE_USE_JSON
#include "json_config.hpp"
#else
#include "generated.hpp"
#endif
-#include "sdbusplus.hpp"
#include <sdeventplus/event.hpp>
#include <functional>
#include <stdplus/signal.hpp>
@@ -34,32 +32,9 @@
auto event = sdeventplus::Event::get_default();
bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
-#ifdef PRESENCE_JSON_FILE
+#ifdef PRESENCE_USE_JSON
// Use json file for presence config
- presence::JsonConfig config(PRESENCE_JSON_FILE);
-#elif defined(PRESENCE_JSON_DBUS_INTF) && defined(PRESENCE_JSON_DBUS_PROP)
- // Use first object returned in the subtree
- // (There should really only be one object with the config interface)
- std::string jsonFile = "";
- auto objects = util::SDBusPlus::getSubTree(
- bus, "/", PRESENCE_JSON_DBUS_INTF, 0);
- auto itObj = objects.begin();
- if (itObj != objects.end())
- {
- auto itServ = itObj->second.begin();
- if (itServ != itObj->second.end())
- {
- // Retrieve json config file location from dbus
- jsonFile = util::SDBusPlus::getProperty<std::string>(
- bus, itServ->first, itObj->first,
- PRESENCE_JSON_DBUS_INTF, PRESENCE_JSON_DBUS_PROP);
- }
- }
- presence::JsonConfig config(jsonFile);
-#endif
-
-#if defined(PRESENCE_JSON_FILE) || \
- (defined(PRESENCE_JSON_DBUS_INTF) && defined(PRESENCE_JSON_DBUS_PROP))
+ presence::JsonConfig config(bus);
for (auto& p: presence::JsonConfig::get())
{
p->monitor();