blob: 534127d3248942f7d00a965edbb401fff56f3973 [file]
#pragma once
#include <sys/eventfd.h>
#include <array>
#include <atomic>
#include <cassert>
#include <chrono>
#include <cstddef>
#include <cstdint>
#include <memory>
#include <optional>
#include <queue>
#include <span>
#include <string>
#include <string_view>
#include <thread>
#include <tuple>
#include <type_traits>
#include <unordered_map>
#include <utility>
#include <variant>
#include <vector>
#include "absl/base/attributes.h"
#include "absl/base/thread_annotations.h"
#include "absl/container/flat_hash_map.h"
#include "absl/container/flat_hash_set.h"
#include "absl/functional/any_invocable.h"
#include "absl/functional/bind_front.h"
#include "absl/strings/string_view.h"
#include "absl/synchronization/mutex.h"
#include "boost/asio/error.hpp"
#include "boost/asio/io_context.hpp"
#include "boost/asio/posix/basic_stream_descriptor.hpp"
#include "boost/asio/post.hpp" // NOLINT
#include "boost/asio/steady_timer.hpp"
#include "boost/container/flat_map.hpp" // NOLINT(readability/boost)
#include "boost/system/error_code.hpp"
#include "subscription.h"
#include "dbus_utility.hpp"
#include <nlohmann/json.hpp>
#include "tlbmc/hal/system_registry.h"
#include "managed_store_types.hpp"
#include "sdbusplus/asio/connection.hpp"
#include "sdbusplus/bus/match.hpp"
#include "sdbusplus/message.hpp"
#include "sdbusplus/message/native_types.hpp"
#include "sdbusplus/message/types.hpp"
namespace managedStore {
// This is a helper class to ensure that a callable is only called once.
// This is useful for constructing a std::function from absl::AnyInvocable.
//
// Example:
//
// absl::AnyInvocable<void(int)> f = ...;
// std::function<void(int)> g = CallableOnce(std::move(f));
// Reference: http://google3/util/functional/callable_once.h
// We cannot use the google3 version because it is not open-sourced.
namespace internal {
// Encapsulates a functor and whether it was called or not.
template <class Functor>
struct CalledState {
template <class... Args>
explicit CalledState([[maybe_unused]] int dummy, Args&&... args) // NOLINT
: functor(absl::bind_front(std::forward<Args>(args)...)) {}
std::atomic<bool> called{false};
Functor functor;
};
// Encapsulates a functor and whether it was called or not, it also check fails
// at destruction if never called.
template <class Functor>
struct CheckCalledState : public CalledState<Functor> {
using CalledState<Functor>::CalledState;
~CheckCalledState() {
[[maybe_unused]] const bool check =
this->called.load(std::memory_order_relaxed);
assert(check && "Functor was never called.");
}
};
// Encapsulates a Functor state giving it shared semantics and forwards
// operator() const to operator() &&.
template <class Functor, class State>
class SharedCallWrapperAtMostOnce {
public:
// The int is to limit overtriggering and to ensure that the copy/move
// constructors are called when we want to copy/move, rather than this one.
template <class... Args>
explicit SharedCallWrapperAtMostOnce([[maybe_unused]] int dummy,
Args&&... args) // NOLINT
: internal_(std::make_shared<State>(0, std::forward<Args>(args)...)) {}
// We use the std::void_t and decltype(auto) to avoid having the
// decltype() expression of the return type as part of the mangled name.
template <class... Args,
typename = ::std::void_t<
decltype(std::declval<Functor>()(std::declval<Args>()...))>>
decltype(auto) operator()(Args&&... args) const { // NOLINT
[[maybe_unused]] const bool called =
internal_->called.exchange(true, std::memory_order_relaxed);
assert(!called && "Functor was already called");
return std::move(internal_->functor)(std::forward<Args>(args)...);
}
private:
std::shared_ptr<State> internal_;
};
template <class... Args>
using CallAtMostOnceT = internal::SharedCallWrapperAtMostOnce<
decltype(absl::bind_front(std::declval<Args>()...)),
internal::CalledState<decltype(absl::bind_front(std::declval<Args>()...))>>;
template <typename Functor>
CallAtMostOnceT<Functor> CallAtMostOnce(Functor&& functor) {
return CallAtMostOnceT<Functor>(0, std::forward<Functor>(functor));
}
template <class... Args>
using CallExactlyOnceT = internal::SharedCallWrapperAtMostOnce<
decltype(absl::bind_front(std::declval<Args>()...)),
internal::CheckCalledState<decltype(absl::bind_front(
std::declval<Args>()...))>>;
template <class... Args>
CallExactlyOnceT<Args...> CallExactlyOnce(Args&&... args) { // NOLINT
return CallExactlyOnceT<Args...>(0, std::forward<Args>(args)...);
}
} // namespace internal
constexpr std::string_view serializationFilePath =
"/tmp/gBMCwebManagedStore.json";
// forward declaration:
class ManagedObjectStoreHttp;
// ManagedObjectStore caches all responses to GetManagedObjects in memory.
// This store aims to provide O(1) access to ManagedObjectType objects to save
// the round trip latency to query data from each DBus connection.
// A background async task using boost::asio::steady_timer ensures freshness of
// managed objects in store.
class ManagedObjectStore {
public:
friend class ManagedObjectStoreHttp;
explicit ManagedObjectStore(
const ManagedObjectStoreConfig& cfg, boost::asio::io_context& io,
std::thread::id main_thread_id,
const std::shared_ptr<boost::asio::io_context>& io_context_worker_threads,
ecclesia::SubscriptionService* ss = nullptr,
sdbusplus::asio::connection* systemBus = nullptr,
std::shared_ptr<milotic_tlbmc::SystemRegistry> system_registry = nullptr)
: config(cfg),
timer(io),
managedStoreTracker(cfg.pendingDbusResponsesMax),
time_trace_array_(nlohmann::json::array()),
subscription_service_(ss),
io_context_main_thread_(io),
main_thread_id_(main_thread_id),
io_context_worker_threads_(io_context_worker_threads),
system_bus_(systemBus),
system_registry_(system_registry) {}
virtual ~ManagedObjectStore() {}
using GetManagedObjectsCb =
absl::AnyInvocable<void(const boost::system::error_code&,
const dbus::utility::ManagedObjectType&)>;
using GetManagedMapperObjectCb = absl::AnyInvocable<void(
const boost::system::error_code&, const dbus::utility::MapperGetObject&)>;
using GetManagedSystemdListUnitsCb =
absl::AnyInvocable<void(const boost::system::error_code&,
const dbus::utility::SystemdListUnits&)>;
using GetManagedPropertyMapCb =
absl::AnyInvocable<void(const boost::system::error_code&,
const ::dbus::utility::DBusPropertiesMap&)>;
using GetManagedPropertyCb =
absl::AnyInvocable<void(const boost::system::error_code&,
const dbus::utility::DbusVariantType&, uint64_t)>;
using GetManagedSubtreeCb =
absl::AnyInvocable<void(const boost::system::error_code&,
const dbus::utility::MapperGetSubTreeResponse&)>;
using GetManagedSubtreePathsCb = absl::AnyInvocable<void(
const boost::system::error_code&,
const dbus::utility::MapperGetSubTreePathsResponse&)>;
using SetPropertyCb =
absl::AnyInvocable<void(const boost::system::error_code&)>;
// Callback used to move managed objects/properties within the store.
// This allows the store to operate on ValueType instead of specific
// dbus::utility::DbusVariantType, dbus::utility::ManagedObjectType.
using ManagedStoreCb =
absl::AnyInvocable<void(const std::shared_ptr<ValueType>&)>;
// Maps ManagedStore key to request callback.
using ManagedStoreCallbackMap =
std::unordered_map<std::string, std::queue<ManagedStoreCb>>;
// call the 'callback' with cached/fetched object
void getManagedObjectsWithContext(
const std::string& service, const sdbusplus::message::object_path& path,
const ManagedObjectStoreContext& requestContext,
GetManagedObjectsCb callback);
// call the 'callback' with cached/fetched property
void getProperty(const KeyType& keyType,
const ManagedObjectStoreContext& requestContext,
GetManagedPropertyCb callback);
void getDbusObject(const std::string& path,
std::span<const std::string_view> interfaces,
const ManagedObjectStoreContext& requestContext,
GetManagedMapperObjectCb callback);
void listUnits(const ManagedObjectStoreContext& requestContext,
GetManagedSystemdListUnitsCb callback);
void getAllProperties(const std::string& service,
const std::string& objectPath,
const std::string& interface,
const ManagedObjectStoreContext& requestContext,
GetManagedPropertyMapCb callback);
void getSubTree(const std::string& path, int32_t depth,
std::span<const std::string_view> interfaces,
const ManagedObjectStoreContext& requestContext,
GetManagedSubtreeCb callback);
void getSubTree(const std::string& path, int32_t depth,
const std::vector<std::string>& interfaces,
const ManagedObjectStoreContext& requestContext,
GetManagedSubtreeCb callback);
void getSubTreePaths(const std::string& path, int32_t depth,
std::span<const std::string_view> interfaces,
const ManagedObjectStoreContext& requestContext,
GetManagedSubtreePathsCb callback);
void getAssociatedSubTree(
const sdbusplus::message::object_path& associatedPath,
const sdbusplus::message::object_path& path, int32_t depth,
const std::vector<std::string>& interfaces,
const ManagedObjectStoreContext& requestContext,
GetManagedSubtreeCb callback);
void getAssociatedSubTree(
const sdbusplus::message::object_path& associatedPath,
const sdbusplus::message::object_path& path, int32_t depth,
std::span<const std::string_view> interfaces,
const ManagedObjectStoreContext& requestContext,
GetManagedSubtreeCb callback);
void getAssociatedSubTreePaths(
const sdbusplus::message::object_path& associatedPath,
const sdbusplus::message::object_path& path, int32_t depth,
std::span<const std::string_view> interfaces,
const ManagedObjectStoreContext& requestContext,
GetManagedSubtreePathsCb callback);
template <typename PropertyType>
void setProperty(const std::string& service, const std::string& path,
const std::string& interface,
const std::string& propertyName,
PropertyType&& propertyValue, SetPropertyCb&& callback) {
boost::asio::post(
io_context_main_thread_,
[this, service, path, interface, propertyName,
propertyValue(std::forward<PropertyType>(propertyValue)),
callback(std::forward<SetPropertyCb>(callback))]() mutable {
system_bus_->async_method_call(
std::forward<decltype(callback)>(callback), service, path,
"org.freedesktop.DBus.Properties", "Set", interface, propertyName,
std::variant<std::decay_t<PropertyType>>(
std::forward<PropertyType>(propertyValue)));
});
}
template <typename Callback, typename... DbusCallArgs>
void PostDbusCallToIoContextThreadSafe(
[[maybe_unused]] const std::shared_ptr<boost::asio::io_context::strand>&
strand,
Callback&& callback, const std::string& service,
const std::string& objpath, const std::string& interface,
const std::string& method, DbusCallArgs&&... dbusCallArgs) {
// Since everything is in a strand, we don't have to worry about
// data races.
boost::asio::post(
io_context_main_thread_,
[this, callback(std::forward<Callback>(callback)), service, objpath,
interface, method,
... dbusCallArgs(std::forward<DbusCallArgs>(dbusCallArgs))]() mutable {
system_bus_->async_method_call(
std::forward<decltype(callback)>(callback), service, objpath,
interface, method,
std::forward<decltype(dbusCallArgs)>(dbusCallArgs)...);
});
}
// SignCSR in google_service_root.h
virtual void PostDbusCallWithObjectPathAndTwoStrings(
[[maybe_unused]] const std::shared_ptr<boost::asio::io_context::strand>&
strand,
absl::AnyInvocable<void(const boost::system::error_code&,
const std::string&)>&& callback,
const std::string& service, const std::string& objpath,
const std::string& interface, const std::string& method,
const sdbusplus::message::object_path& arg1, const std::string& arg2,
const std::string& arg3) {
boost::asio::post(io_context_main_thread_,
[this, cb = std::move(callback), service, objpath,
interface, method, arg1, arg2, arg3]() mutable {
system_bus_->async_method_call(
std::move(cb), service, objpath, interface, method,
arg1, arg2, arg3);
});
}
// executeRootOfTrustCommand in google_service_root.h
virtual void PostDbusCallWithObjectPath(
[[maybe_unused]] const std::shared_ptr<boost::asio::io_context::strand>&
strand,
absl::AnyInvocable<void(const boost::system::error_code&,
const std::string&)>&& callback,
const std::string& service, const std::string& objpath,
const std::string& interface, const std::string& method,
const sdbusplus::message::object_path& arg1) {
boost::asio::post(
io_context_main_thread_, [this, cb = std::move(callback), service,
objpath, interface, method, arg1]() mutable {
system_bus_->async_method_call(std::move(cb), service, objpath,
interface, method, arg1);
});
}
// nvmeMetricFetcher returning unix_fd in nvme_metric_utils.h
virtual void PostDbusCallWithStringRetMsgAndFd(
[[maybe_unused]] const std::shared_ptr<boost::asio::io_context::strand>&
strand,
absl::AnyInvocable<void(const boost::system::error_code&,
const sdbusplus::message_t&,
const sdbusplus::message::unix_fd&)>&& callback,
const std::string& service, const std::string& objpath,
const std::string& interface, const std::string& method,
const std::string& arg1) {
boost::asio::post(
io_context_main_thread_, [this, cb = std::move(callback), service,
objpath, interface, method, arg1]() mutable {
system_bus_->async_method_call(std::move(cb), service, objpath,
interface, method, arg1);
});
}
boost::asio::io_context& GetIoContext() const {
return io_context_main_thread_;
}
boost::asio::io_context& GetWorkerThreadsIoContext() const {
return *io_context_worker_threads_;
}
bool IsInMainThread() const {
return std::this_thread::get_id() == main_thread_id_;
}
// DO NOT USE THIS METHOD IF YOU ARE HANDLING A GET REQUEST
// Get requests will be multithreaded and using system bus in multiple threads
// will lead to a data race.
// This method only exists for legacy code.
// NOTE: currently only get requests are multithreaded
// system bus usage should be minimized
sdbusplus::asio::connection* GetDeprecatedThreadUnsafeSystemBus() const {
return system_bus_;
}
ManagedStoreTracker getStoreTracker() const {
absl::MutexLock lock(managed_store_tracker_mutex_);
return this->managedStoreTracker;
}
// TODO(rahulkpr): migrate calls to subscribeToInterfacesAdded().
void subscribe([[maybe_unused]] const ManagedObjectStoreContext& context,
[[maybe_unused]] const std::string& path,
[[maybe_unused]] const std::string& interface = "") {}
// Subscribe to `InterfacesAdded` signal from D-Bus.
void subscribeToInterfacesAdded(
const std::string& object_path,
const ManagedObjectStoreContext& request_context);
using HealthChangeCallback = absl::AnyInvocable<void(const std::string&)>;
using EntityManagerChangeCallback =
absl::AnyInvocable<void(const std::string&)>;
// Subscribe to signal from HealthMonitor D-Bus service.
virtual void subscribeToHealthMonitor(const std::string& object_path,
HealthChangeCallback callback);
// Subscribe to signal from EntityManager.
virtual void subscribeToEntityManagerChange(
EntityManagerChangeCallback callback);
// check if the store is enabled:
bool isEnabled() const { return config.isEnabled; }
// get the current config
const ManagedObjectStoreConfig& getConfig() const { return config; }
void storeTimeTrace(const nlohmann::json& tTrace);
void clearTimeTrace();
bool serialize(std::string_view filePath = serializationFilePath);
bool deserialize(std::string_view filePath = serializationFilePath);
bool toJson(nlohmann::json& obj);
bool fromJson(const nlohmann::json& obj);
nlohmann::json GetSubscriptionsToJSON();
nlohmann::json GetEventsToJSON();
nlohmann::json GetDBusMonitorsToJSON();
nlohmann::json GetEventsBySubscriptionIdToJSON(size_t subscription_id);
nlohmann::json ClearEventStore();
std::shared_ptr<milotic_tlbmc::SystemRegistry> GetSystemRegistry() {
return system_registry_;
}
void SetSystemRegistry(
std::shared_ptr<milotic_tlbmc::SystemRegistry> registry) {
system_registry_ = std::move(registry);
}
// protected APIs (SPI):
protected:
// We want to unify PostDbusCallToIoContextThreadSafe into one method such
// that we dont expose a threadsafe and non-threadsafe method. However, we
// need to be able to distinguish between different dbus calls. Get calls can
// be multithreaded, but all other calls will not be multithreaded. This means
// we need a mechanism at compile time to distinguish between different dbus
// calls. We can use the return type of the dbus call to do this.
// The dbus calls that can be multithreaded are:
// 1. The dbus callback must have 2 parameters
// 2. sdbusplus can compile the return type
// If these conditions are not met, we cant not use template deduction for
// callback return type or else compilation will fail.
template <typename Callback, typename... DbusCallArgs>
static constexpr bool DbusCallbackIsCompilable() {
// All Dbus Get calls have 2 args:
// 1. error_code
// 2. return value
if constexpr (std::tuple_size<
boost::callable_traits::args_t<Callback>>::value != 2) {
return false;
} else {
using CallbackReturnType = std::decay_t<
std::tuple_element_t<1, boost::callable_traits::args_t<Callback>>>;
using undefined_type_id =
sdbusplus::message::types::details::undefined_type_id;
// Sdbus requires dbus object return types to be defined.
// This static assert is done here:
// https://github.com/openbmc/sdbusplus/blob/master/include/sdbusplus/message/types.hpp#L278
// We need to do it here as the yield_method_call requires the return type
// to be defined.
return !std::is_base_of_v<
undefined_type_id,
sdbusplus::message::types::details::type_id<CallbackReturnType>>;
}
}
// clear/flush all managed objects:
void clearAllObjects();
// Subscribe to DBus signals with specific `match_expression`.
// Uses given `event_source_id` to associate D-Bus match created.
void subscribe(const ManagedObjectStoreContext& requestContext,
const std::string& match_expression,
ecclesia::EventSourceId event_source_id);
// Calls into dbus service to get managed objects.
// Virtual to allow unit testing and possible derived implementations of
// managedStore.
virtual void getManagedObjectsFromDbusService(
const std::shared_ptr<boost::asio::io_context::strand>& strand,
const std::string& service, const sdbusplus::message::object_path& path,
ManagedStoreCb callback, std::optional<uint64_t> refresh_interval);
// Calls into dbus service to get Dbus object.
virtual void getManagedMapperObjectFromDbusService(
const std::shared_ptr<boost::asio::io_context::strand>& strand,
const sdbusplus::message::object_path& path,
const std::vector<std::string>& interfaces, ManagedStoreCb callback,
std::optional<uint64_t> refresh_interval);
// Calls into dbus service to get managed properties.
virtual void getManagedPropertiesFromDbusService(
const std::shared_ptr<boost::asio::io_context::strand>& strand,
const std::string& service, const sdbusplus::message::object_path& path,
const std::string& interface, const std::string& property,
ManagedStoreCb callback, std::optional<uint64_t> refresh_interval);
// Calls into dbus service to getAllProperties.
virtual void getManagedPropertiesMapFromDbusService(
const std::shared_ptr<boost::asio::io_context::strand>& strand,
const std::string& service, const sdbusplus::message::object_path& path,
const std::string& interface, ManagedStoreCb callback,
std::optional<uint64_t> refresh_interval);
// Calls into dbus service to get subtree.
virtual void getManagedSubtreeFromDbusService(
const std::shared_ptr<boost::asio::io_context::strand>& strand,
const sdbusplus::message::object_path& path, int32_t depth,
const std::vector<std::string>& interfaces, ManagedStoreCb callback,
std::optional<uint64_t> refresh_interval);
// Calls into dbus service to get subtree paths.
virtual void getManagedSubtreePathsFromDbusService(
const std::shared_ptr<boost::asio::io_context::strand>& strand,
const sdbusplus::message::object_path& path, int32_t depth,
const std::vector<std::string>& interfaces, ManagedStoreCb callback,
std::optional<uint64_t> refresh_interval);
virtual void getManagedAssociatedSubtreeFromDbusService(
const std::shared_ptr<boost::asio::io_context::strand>& strand,
const sdbusplus::message::object_path& associatedPath,
const sdbusplus::message::object_path& path, int32_t depth,
const std::vector<std::string>& interfaces, ManagedStoreCb callback,
std::optional<uint64_t> refresh_interval);
virtual void getManagedAssociatedSubtreePathsFromDbusService(
const std::shared_ptr<boost::asio::io_context::strand>& strand,
const sdbusplus::message::object_path& associatedPath,
const sdbusplus::message::object_path& path, int32_t depth,
const std::vector<std::string>& interfaces, ManagedStoreCb callback,
std::optional<uint64_t> refresh_interval);
virtual void getSystemdUnitsFromDbusService(
const std::shared_ptr<boost::asio::io_context::strand>& strand,
ManagedStoreCb callback, std::optional<uint64_t> refresh_interval);
// These are in protected because the subclass needs to access them for unit
// tests.
// Stores ManagedObjectType objects with D-Bus interface and connection
// as key along with other metadata necessary for scheduling data refresh.
mutable absl::Mutex managed_objects_mutex_;
ManagedObjectsMap managedObjects ABSL_GUARDED_BY(managed_objects_mutex_);
// schedule the next refresh event (timer):
void scheduleRefresh();
// fetch the given object from DBUS:
// Refresh operation is considered high priority when isReadThroughRequest
// is set to true i.e the refresh is not subject to the pending i/o
// threshold invariant.
// If `strand` is set, the callback will be posted to its original thread.
void refreshObject(
const KeyType& key, bool isReadThroughRequest = false,
const std::shared_ptr<boost::asio::io_context::strand>& strand = nullptr);
// Process dbus response after refreshObject(), invokes given callback if
// valid.
void processDbusResponse(const KeyType& keyType,
const std::shared_ptr<ValueType>& managedValue,
bool isReadThroughRequest,
std::optional<uint64_t> refresh_interval);
// Get managed entities (properties / objects) from store.
// Triggers refresh if not in store.
void getStoredOrReadThrough(const KeyType& keyType,
const ManagedObjectStoreContext& requestContext,
ManagedStoreCb callback);
// Compares two managed store values and returns true if they are different
static bool DetectChange(const ValueType& valueA, const ValueType& valueB);
// Stores keys that have custom refresh interval.
absl::Mutex keys_to_custom_interval_mutex_;
absl::flat_hash_map<std::string, uint64_t> keys_to_custom_interval_
ABSL_GUARDED_BY(keys_to_custom_interval_mutex_);
// `pq` is only accessed by the io_context thread.
// priority queue of refreshes:
ManagedStorePriorityQueue pq;
// Tracks callback for incoming requests.
absl::Mutex request_cb_map_mutex_;
ManagedStoreCallbackMap requestCbMap ABSL_GUARDED_BY(request_cb_map_mutex_);
// `key_to_pq_entry_` is only accessed by the io_context thread.
// Tracks number of priority queue entries per managedStore key.
absl::flat_hash_map<std::string, size_t> key_to_pq_entry_;
// runtime config for the store
const ManagedObjectStoreConfig config;
// `timer` is only accessed by the io_context thread.
// A single timer object is used to asynchronously wait for a fixed duration
// before refreshing ManagedObject in store with the shortest deadline.
boost::asio::steady_timer timer;
// Flag set to true when scheduler has scheduled a refresh operation.
bool isSchedulerActive = false;
// Tracks state of managed object store.
mutable absl::Mutex managed_store_tracker_mutex_
ABSL_ACQUIRED_AFTER(managed_objects_mutex_);
ManagedStoreTracker managedStoreTracker
ABSL_GUARDED_BY(managed_store_tracker_mutex_);
// Mutex to protect signal_monitors_
absl::Mutex signal_monitor_mutex_;
// Tracks signal monitors
absl::flat_hash_map<ecclesia::EventSourceId,
std::unique_ptr<sdbusplus::bus::match_t>>
signal_monitors_ ABSL_GUARDED_BY(signal_monitor_mutex_);
// Tracks health monitor
absl::flat_hash_map<std::string, std::unique_ptr<sdbusplus::bus::match_t>>
health_monitors_;
// Tracks entity manager monitor
std::unique_ptr<sdbusplus::bus::match_t> entity_manager_monitor_;
// Time Trace
mutable absl::Mutex time_trace_array_mutex_;
nlohmann::json time_trace_array_ ABSL_GUARDED_BY(time_trace_array_mutex_);
// Pointer to a SubscriptionService that's used to publish a change in
// an observed resource via the service's Notify callback.
// Not owned.
ecclesia::SubscriptionService* subscription_service_;
// The main thread that's runs dbus calls, priority queue refresh.
boost::asio::io_context& io_context_main_thread_;
// The thread id of the main thread
const std::thread::id main_thread_id_;
// The worker threads that's runs processing of cache hits.
// Only used when `multi_thread_get` is set to true.
std::shared_ptr<boost::asio::io_context> io_context_worker_threads_;
sdbusplus::asio::connection* system_bus_;
std::shared_ptr<milotic_tlbmc::SystemRegistry> system_registry_;
// Deprecated: dangerous and not thread-safe should not be used other than
// unit tests.
ABSL_DEPRECATED("Use GetManagedObjectsMetrics instead")
const ManagedObjectsMap& getManagedObjects() const
ABSL_LOCKS_EXCLUDED(managed_objects_mutex_) {
absl::MutexLock lock(managed_objects_mutex_);
return managedObjects;
}
// Returns a json object with metrics about the managed objects.
nlohmann::json GetManagedObjectsMetrics(
std::chrono::steady_clock::time_point now) const
ABSL_LOCKS_EXCLUDED(managed_objects_mutex_);
// Returns the estimated size in bytes of the cached states.
std::size_t GetSnapshotSizeInBytes() const
ABSL_LOCKS_EXCLUDED(managed_objects_mutex_);
// Updates an object with updated time points and refresh status if it already
// exists within managed store. Otherwise, it adds a new object to managed
// store.
void UpdateOrInsertManagedObjects(const std::string& key_id,
const std::shared_ptr<ValueType>& value);
// Increments numRefreshScheduled value of an object with thread-safety if it
// exists.
void UpdateNumRefreshesScheduled(std::string& key_id);
// Checks if an object is still tracked within managed store.
bool IsManagedObjectTracked(const std::string& key_id) {
absl::MutexLock lock(managed_objects_mutex_);
return managedObjects.find(key_id) != managedObjects.end();
}
// Evicts an object by key_id from managed store if it exists with
// thread-safety.
void EvictManagedObject(const std::string& key_id) {
absl::MutexLock lock(managed_objects_mutex_);
// Early return if Managed Object is no longer tracked.
if (managedObjects.find(key_id) == managedObjects.end()) return;
// Only evict Managed Object if it is still tracked.
managedObjects.erase(key_id);
}
// Checks if an object is current and still tracked within managed store with
// thread-safety.
// If true, the cached object shared pointer is copied into `copied_object`,
// which extends the lifecycle. If false, the stabled object is erased from
// the store, and nullptr is returned.
virtual std::shared_ptr<ValueType> IsManagedObjectCurrentAndTracked(
const std::string& key_id, const KeyType& keyType,
const ManagedObjectStoreContext& requestContextValueType);
std::optional<uint64_t> GetRefreshInterval(const std::string& key_id)
ABSL_LOCKS_EXCLUDED(keys_to_custom_interval_mutex_) {
// Note: we might get a outdated refresh interval here, but it's ok. The
// next call will use the updated one.
absl::MutexLock lock(keys_to_custom_interval_mutex_);
auto it = keys_to_custom_interval_.find(key_id);
if (it == keys_to_custom_interval_.end()) {
return std::nullopt;
}
return it->second;
}
void SetRefreshInterval(const std::string& key_id, uint64_t refresh_interval)
ABSL_LOCKS_EXCLUDED(keys_to_custom_interval_mutex_) {
absl::MutexLock lock(keys_to_custom_interval_mutex_);
keys_to_custom_interval_[key_id] = refresh_interval;
}
// Returns false if the `key_id` is already in the map which means no refresh
// call is required.
// The combination of `InsertCallbackIntoRequestCbMapAndReturnTrueIfNew` and
// `GetCallbacksFromRequestCbMap` should make sure no callbacks are lost.
bool InsertCallbackIntoRequestCbMapAndReturnTrueIfNew(
const std::string& key_id, ManagedStoreCb callback)
ABSL_LOCKS_EXCLUDED(request_cb_map_mutex_) {
absl::MutexLock lock(request_cb_map_mutex_);
auto cb_map_iter = requestCbMap.find(key_id);
if (cb_map_iter != requestCbMap.end()) {
// Request collapsing - Combine multiple requests for the same dbus object
// into a single request and use the resulting response to satisfy all
// duplicate requests.
cb_map_iter->second.push(std::move(callback));
return false;
}
requestCbMap[key_id].push(std::move(callback));
return true;
}
std::queue<ManagedStoreCb> GetCallbacksFromRequestCbMap(
const std::string& key_id) ABSL_LOCKS_EXCLUDED(request_cb_map_mutex_) {
std::queue<ManagedStoreCb> callbacks;
absl::MutexLock lock(request_cb_map_mutex_);
auto cb_map_iter = requestCbMap.find(key_id);
if (cb_map_iter != requestCbMap.end()) {
callbacks = std::move(cb_map_iter->second);
requestCbMap.erase(cb_map_iter);
}
return callbacks;
}
// Deprecated: dangerous and not thread-safe should not be used other than
// unit tests.
ABSL_DEPRECATED("Use GetPriorityQueueMetrics instead")
const ManagedStorePriorityQueue& getPriorityQueue() const { return pq; }
// Fetches the current priority queue, generates a json object and feeds it
// into the callback.
void GetPriorityQueueMetrics(
absl::AnyInvocable<void(const nlohmann::json&)> callback) {
// Priority queue should only be accessed by the io_context thread.
boost::asio::post(
io_context_main_thread_,
[this, callback = std::move(callback)]() mutable {
auto jsonObjPqArray = nlohmann::json::array();
size_t entries = 0;
// Max number of PQ Entries that should be exported for debug.
constexpr size_t kPQExportLimit = 20000;
ManagedStorePriorityQueue pq_copy = pq;
while (!pq_copy.empty() && entries++ < kPQExportLimit) {
const auto& entry = pq_copy.top();
jsonObjPqArray.push_back(entry.managedStoreKey.toString());
pq_copy.pop();
}
std::move(callback)(jsonObjPqArray);
});
}
// Inserts a new entry into the priority queue. Should only be called by the
// io_context thread and used in unit tests.
void InsertPriorityQueueEntry(const PriorityQueueEntry& entry) {
// Priority queue should only be accessed by the io_context thread.
boost::asio::post(io_context_main_thread_,
[this, &entry]() { pq.push(entry); });
}
void GetPriorityQueueSize(absl::AnyInvocable<void(size_t)> callback) {
// Priority queue should only be accessed by the io_context thread.
boost::asio::post(io_context_main_thread_,
[this, callback = std::move(callback)]() mutable {
std::move(callback)(pq.size());
});
}
nlohmann::json getTimeTrace() const
ABSL_LOCKS_EXCLUDED(time_trace_array_mutex_) {
absl::MutexLock lock(time_trace_array_mutex_);
return time_trace_array_;
}
// Disable copy constructors (singelton)
ManagedObjectStore(const ManagedObjectStore&) = delete;
ManagedObjectStore& operator=(const ManagedObjectStore&) = delete;
// Not yet: https://gbmc-private-review.git.corp.google.com/c/gbmcweb/+/3520
// ManagedObjectStore(ManagedObjectStore&&) = delete;
// ManagedObjectStore& operator=(ManagedObjectStore&&) = delete;
// TODO: use this macro / template ^
// https://www.boost.org/doc/libs/1_81_0/libs/serialization/doc/singleton.html
#ifdef UNIT_TEST_BUILD
// We have to make this a virtual function so that we can mock it in unit
// tests in g3. Please note you should extend this with more mock functions
// and only place them after this comment.
public:
using GetAncestorsResponseType = std::array<const char*, 1>;
using ResolveHostnameCb = absl::AnyInvocable<void(
const boost::system::error_code&,
const std::vector<std::tuple<int32_t, int32_t, std::vector<uint8_t>>>&,
const std::string&, const uint64_t)>;
using PostCodeEntry = std::tuple<uint64_t, std::vector<uint8_t>>;
using CreateDumpParamVec =
std::vector<std::pair<std::string, std::variant<std::string, uint64_t>>>;
using NumericThresholdParams =
std::tuple<std::string, uint64_t, std::string, double>;
using SPDMGetSignedMeasurmentsCb = absl::AnyInvocable<void(
const boost::system::error_code&, const sdbusplus::message::object_path&,
const std::string&, const std::string&, const std::string&,
const std::string&, const std::string&)>;
using DiscreteThresholdParams =
std::tuple<std::string, std::string, uint64_t, std::string>;
using TriggerThresholdParamsExt =
std::variant<std::monostate, std::vector<NumericThresholdParams>,
std::vector<DiscreteThresholdParams>>;
using TriggerSensorsParams =
std::vector<std::pair<sdbusplus::message::object_path, std::string>>;
using TriggerGetParamsVariant =
std::variant<std::monostate, bool, std::string, TriggerThresholdParamsExt,
TriggerSensorsParams, std::vector<std::string>,
std::vector<sdbusplus::message::object_path>>;
using TriggerGetAllCb = absl::AnyInvocable<void(
const boost::system::error_code&,
const std::vector<std::pair<std::string, TriggerGetParamsVariant>>&)>;
using PostPackageRepairStatusParam =
std::vector<std::tuple<uint16_t, uint16_t, uint16_t, uint16_t,
std::vector<uint16_t>>>;
using ReadingParameters =
std::vector<std::tuple<sdbusplus::message::object_path, std::string,
std::string, std::string>>;
// setProperty in storage_utils.h, log_services.cc
virtual void setProperty(const std::string& service, const std::string& path,
const std::string& interface,
const std::string& propertyName,
const std::string& propertyValue,
SetPropertyCb&& callback) {
boost::asio::post(
io_context_main_thread_,
[this, service, path, interface, propertyName, propertyValue,
callback(std::forward<SetPropertyCb>(callback))]() mutable {
system_bus_->async_method_call(
std::forward<decltype(callback)>(callback), service, path,
"org.freedesktop.DBus.Properties", "Set", interface, propertyName,
std::variant<std::string>(propertyValue));
});
}
// setProperty (bool) in storage.h (e.g., setCustomSSDOemGpio)
virtual void setProperty(const std::string& service, const std::string& path,
const std::string& interface,
const std::string& propertyName, bool propertyValue,
SetPropertyCb&& callback) {
boost::asio::post(
io_context_main_thread_,
[this, service, path, interface, propertyName, propertyValue,
callback(std::forward<SetPropertyCb>(callback))]() mutable {
system_bus_->async_method_call(
std::forward<decltype(callback)>(callback), service, path,
"org.freedesktop.DBus.Properties", "Set", interface, propertyName,
std::variant<bool>(propertyValue));
});
}
// setProperty (uint32_t) in storage_utils.h, sensors.h
virtual void setProperty(const std::string& service, const std::string& path,
const std::string& interface,
const std::string& propertyName,
uint32_t propertyValue, SetPropertyCb&& callback) {
boost::asio::post(
io_context_main_thread_,
[this, service, path, interface, propertyName, propertyValue,
callback(std::forward<SetPropertyCb>(callback))]() mutable {
system_bus_->async_method_call(
std::forward<decltype(callback)>(callback), service, path,
"org.freedesktop.DBus.Properties", "Set", interface, propertyName,
std::variant<uint32_t>(propertyValue));
});
}
// setProperty (double) in sensors.h
virtual void setProperty(const std::string& service, const std::string& path,
const std::string& interface,
const std::string& propertyName,
double propertyValue, SetPropertyCb&& callback) {
boost::asio::post(
io_context_main_thread_,
[this, service, path, interface, propertyName, propertyValue,
callback(std::forward<SetPropertyCb>(callback))]() mutable {
system_bus_->async_method_call(
std::forward<decltype(callback)>(callback), service, path,
"org.freedesktop.DBus.Properties", "Set", interface, propertyName,
std::variant<double>(propertyValue));
});
}
// setProperty (DbusVariantType) in systems.h, chassis.h, managers.h
virtual void setProperty(const std::string& service, const std::string& path,
const std::string& interface,
const std::string& propertyName,
dbus::utility::DbusVariantType&& propertyValue,
SetPropertyCb&& callback) {
boost::asio::post(
io_context_main_thread_,
[this, service, path, interface, propertyName,
propertyValue(std::move(propertyValue)),
callback(std::forward<SetPropertyCb>(callback))]() mutable {
system_bus_->async_method_call(
std::forward<decltype(callback)>(callback), service, path,
"org.freedesktop.DBus.Properties", "Set", interface, propertyName,
std::move(propertyValue));
});
}
// Generic D-Bus call with no arguments (e.g., doNMI in systems.h,
// resetChassis in chassis.h)
virtual void PostDbusCallToIoContextThreadSafe(
[[maybe_unused]] const std::shared_ptr<boost::asio::io_context::strand>&
strand,
absl::AnyInvocable<void(const boost::system::error_code&)>&& callback,
const std::string& service, const std::string& objpath,
const std::string& interf, const std::string& method) {
boost::asio::post(
io_context_main_thread_, [this, callback(std::move(callback)), service,
objpath, interf, method]() mutable {
system_bus_->async_method_call(std::move(callback), service, objpath,
interf, method);
});
}
// Introspect in openbmc_dbus_rest.h, log_services.cc
virtual void PostDbusCallToIoContextThreadSafe(
[[maybe_unused]] const std::shared_ptr<boost::asio::io_context::strand>&
strand,
absl::AnyInvocable<void(const boost::system::error_code&,
const std::string&)>&& callback,
const std::string& service, const std::string& objpath,
const std::string& interface, const std::string& method) {
boost::asio::post(
io_context_main_thread_, [this, callback(std::move(callback)), service,
objpath, interface, method]() mutable {
system_bus_->async_method_call(std::move(callback), service, objpath,
interface, method);
});
}
// Introspect with interfaces in openbmc_dbus_rest.h
virtual void PostDbusCallToIoContextThreadSafe(
[[maybe_unused]] const std::shared_ptr<boost::asio::io_context::strand>&
strand,
absl::AnyInvocable<void(const boost::system::error_code&,
const std::string&)>&& callback,
const std::string& service, const std::string& objpath,
const std::string& interface, const std::string& method,
const std::string& object, const std::vector<std::string>& interfaces) {
boost::asio::post(
io_context_main_thread_,
[this, callback(std::move(callback)), service, objpath, interface,
method, object, interfaces(std::move(interfaces))]() mutable {
system_bus_->async_method_call(std::move(callback), service, objpath,
interface, method, object,
std::move(interfaces));
});
}
// ListNames in openbmc_dbus_rest.h
virtual void PostDbusCallToIoContextThreadSafe(
[[maybe_unused]] const std::shared_ptr<boost::asio::io_context::strand>&
strand,
absl::AnyInvocable<void(const boost::system::error_code&,
std::vector<std::string>&)>&& callback,
const std::string& service, const std::string& objpath,
const std::string& interface, const std::string& method) {
boost::asio::post(
io_context_main_thread_, [this, callback(std::move(callback)), service,
objpath, interface, method]() mutable {
system_bus_->async_method_call(std::move(callback), service, objpath,
interface, method);
});
}
// ListNames with interfaces in openbmc_dbus_rest.h
virtual void PostDbusCallToIoContextThreadSafe(
[[maybe_unused]] const std::shared_ptr<boost::asio::io_context::strand>&
strand,
absl::AnyInvocable<void(const boost::system::error_code&,
const std::vector<std::string>&)>&& callback,
const std::string& service, const std::string& objpath,
const std::string& interface, const std::string& method,
const std::string& object, const std::vector<std::string>& interfaces) {
boost::asio::post(
io_context_main_thread_,
[this, callback(std::move(callback)), service, objpath, interface,
method, object, interfaces(std::move(interfaces))]() mutable {
system_bus_->async_method_call(std::move(callback), service, objpath,
interface, method, object,
std::move(interfaces));
});
}
// GetObject in storage_utils.h, certificate_service.h
virtual void PostDbusCallToIoContextThreadSafe(
[[maybe_unused]] const std::shared_ptr<boost::asio::io_context::strand>&
strand,
absl::AnyInvocable<void(const boost::system::error_code&,
const dbus::utility::MapperGetObject&)>&&
callback,
const std::string& service, const std::string& objpath,
const std::string& interface, const std::string& method,
const std::string& path, const std::vector<std::string>& interfaces) {
boost::asio::post(io_context_main_thread_,
[this, callback(std::move(callback)), service, objpath,
interface, method, path, interfaces]() mutable {
system_bus_->async_method_call(
std::move(callback), service, objpath, interface,
method, path, interfaces);
});
}
// GetAssociatedSubTree in storage_utils.h
virtual void PostDbusCallToIoContextThreadSafe(
[[maybe_unused]] const std::shared_ptr<boost::asio::io_context::strand>&
strand,
absl::AnyInvocable<void(const boost::system::error_code&,
const dbus::utility::MapperGetSubTreeResponse&)>&&
callback,
const std::string& service, const std::string& objpath,
const std::string& interface, const std::string& method,
const sdbusplus::message::object_path& associatedPath,
const sdbusplus::message::object_path& path, int32_t depth,
const std::vector<std::string>& interfaces) {
boost::asio::post(
io_context_main_thread_,
[this, callback(std::move(callback)), service, objpath, interface,
method, associatedPath, path, depth, interfaces]() mutable {
system_bus_->async_method_call(std::move(callback), service, objpath,
interface, method, associatedPath,
path, depth, interfaces);
});
}
// GetAssociatedSubTreePaths in storage_utils.h
virtual void PostDbusCallToIoContextThreadSafe(
[[maybe_unused]] const std::shared_ptr<boost::asio::io_context::strand>&
strand,
absl::AnyInvocable<
void(const boost::system::error_code&,
const dbus::utility::MapperGetSubTreePathsResponse&)>&& callback,
const std::string& service, const std::string& objpath,
const std::string& interface, const std::string& method,
const sdbusplus::message::object_path& associatedPath,
const sdbusplus::message::object_path& path, int32_t depth,
const std::vector<std::string>& interfaces) {
boost::asio::post(
io_context_main_thread_,
[this, callback(std::move(callback)), service, objpath, interface,
method, associatedPath, path, depth, interfaces]() mutable {
system_bus_->async_method_call(std::move(callback), service, objpath,
interface, method, associatedPath,
path, depth, interfaces);
});
}
// GetAncestors in log_services.cc, storage_utils.h
virtual void PostDbusCallToIoContextThreadSafe(
[[maybe_unused]] const std::shared_ptr<boost::asio::io_context::strand>&
strand,
absl::AnyInvocable<
void(const boost::system::error_code&,
const dbus::utility::MapperGetAncestorsResponse&)>&& callback,
const std::string& service, const std::string& objpath,
const std::string& interface, const std::string& method,
const std::string& obj_name, const GetAncestorsResponseType& interfaces) {
boost::asio::post(io_context_main_thread_,
[this, callback(std::move(callback)), service, objpath,
interface, method, obj_name, interfaces]() mutable {
system_bus_->async_method_call(
std::move(callback), service, objpath, interface,
method, obj_name, interfaces);
});
}
// RestartUnit / StartUnit / StopUnit from systemd in log_services.cc,
// network_protocol.h
virtual void PostDbusCallToIoContextThreadSafe(
[[maybe_unused]] const std::shared_ptr<boost::asio::io_context::strand>&
strand,
absl::AnyInvocable<void(const boost::system::error_code&)>&& callback,
const std::string& service, const std::string& objpath,
const std::string& interface, const std::string& method,
const std::string& service_name, const std::string& command) {
boost::asio::post(io_context_main_thread_,
[this, callback(std::move(callback)), service, objpath,
interface, method, service_name, command]() mutable {
system_bus_->async_method_call(
std::move(callback), service, objpath, interface,
method, service_name, command);
});
}
// getProperty (org.freedesktop.DBus.Properties.Get) in storage_utils.h
virtual void PostDbusCallToIoContextThreadSafe(
[[maybe_unused]] const std::shared_ptr<boost::asio::io_context::strand>&
strand,
absl::AnyInvocable<void(const boost::system::error_code&,
const dbus::utility::DbusVariantType&)>&&
callback,
const std::string& service, const std::string& objpath,
const std::string& interface, const std::string& get,
const std::string& get_interf, const std::string& property) {
boost::asio::post(io_context_main_thread_,
[this, callback(std::move(callback)), service, objpath,
interface, get, get_interf, property]() mutable {
system_bus_->async_method_call(
std::move(callback), service, objpath, interface,
get, get_interf, property);
});
}
// setProperty (org.freedesktop.DBus.Properties.Set) in systems.h (e.g.,
// setBootType, sendPowerSystemCommand)
virtual void PostDbusCallToIoContextThreadSafe(
[[maybe_unused]] const std::shared_ptr<boost::asio::io_context::strand>&
strand,
absl::AnyInvocable<void(const boost::system::error_code&)>&& callback,
const std::string& service, const std::string& objpath,
const std::string& interface, const std::string& set,
const std::string& set_interf, const std::string& property_name,
dbus::utility::DbusVariantType&& property) {
boost::asio::post(
io_context_main_thread_,
[this, callback(std::move(callback)), service, objpath, interface, set,
set_interf, property_name, property(std::move(property))]() mutable {
system_bus_->async_method_call(std::move(callback), service, objpath,
interface, set, set_interf,
property_name, std::move(property));
});
}
// setProperty returning sdbusplus::message_t in power.h, sensors.h
virtual void PostDbusCallToIoContextThreadSafe(
[[maybe_unused]] const std::shared_ptr<boost::asio::io_context::strand>&
strand,
absl::AnyInvocable<void(const boost::system::error_code&,
const sdbusplus::message_t&)>&& callback,
const std::string& service, const std::string& objpath,
const std::string& interface, const std::string& set,
const std::string& set_interf, const std::string& property_name,
dbus::utility::DbusVariantType property) {
boost::asio::post(
io_context_main_thread_,
[this, callback(std::move(callback)), service, objpath, interface, set,
set_interf, property_name, property(std::move(property))]() mutable {
system_bus_->async_method_call(std::move(callback), service, objpath,
interface, set, set_interf,
property_name, std::move(property));
});
}
// asyncResolve in async_resolve.h
virtual void PostDbusCallToIoContextThreadSafe(
[[maybe_unused]] const std::shared_ptr<boost::asio::io_context::strand>&
strand,
ResolveHostnameCb&& callback, const std::string& service,
const std::string& objpath, const std::string& interface,
const std::string& method, int param1, const std::string& param2,
int param3, uint64_t param4) {
boost::asio::post(
io_context_main_thread_,
[this, callback(std::move(callback)), service, objpath, interface,
method, param1, param2, param3, param4]() mutable {
system_bus_->async_method_call(std::move(callback), service, objpath,
interface, method, param1, param2,
param3, param4);
});
}
// createVLAN in ethernet.h
virtual void PostDbusCallToIoContextThreadSafe(
[[maybe_unused]] const std::shared_ptr<boost::asio::io_context::strand>&
strand,
absl::AnyInvocable<void(const boost::system::error_code&)>&& callback,
const std::string& service, const std::string& objpath,
const std::string& interface, const std::string& method,
const std::string& param1, uint32_t param2) {
boost::asio::post(io_context_main_thread_,
[this, callback(std::move(callback)), service, objpath,
interface, method, param1, param2]() mutable {
system_bus_->async_method_call(
std::move(callback), service, objpath, interface,
method, param1, param2);
});
}
// createIPv4 / createIPv6 in ethernet.h
virtual void PostDbusCallToIoContextThreadSafe(
[[maybe_unused]] const std::shared_ptr<boost::asio::io_context::strand>&
strand,
absl::AnyInvocable<void(const boost::system::error_code&)>&& callback,
const std::string& service, const std::string& objpath,
const std::string& interface, const std::string& create_ip,
const std::string& protocol, const std::string& address,
uint8_t prefix_length, const std::string& param4) {
boost::asio::post(
io_context_main_thread_,
[this, callback(std::move(callback)), service, objpath, interface,
create_ip, protocol, address, prefix_length, param4]() mutable {
system_bus_->async_method_call(std::move(callback), service, objpath,
interface, create_ip, protocol,
address, prefix_length, param4);
});
}
// getPostCodeData (GetPostCodes) in log_services.cc
virtual void PostDbusCallToIoContextThreadSafe(
[[maybe_unused]] const std::shared_ptr<boost::asio::io_context::strand>&
strand,
absl::AnyInvocable<void(const boost::system::error_code&,
const std::vector<PostCodeEntry>&)>&& callback,
const std::string& service, const std::string& objpath,
const std::string& interface, const std::string& get_postcodes,
uint16_t param1) {
boost::asio::post(io_context_main_thread_,
[this, callback(std::move(callback)), service, objpath,
interface, get_postcodes, param1]() mutable {
system_bus_->async_method_call(
std::move(callback), service, objpath, interface,
get_postcodes, param1);
});
}
// getPostPackageRepairStatus in log_services.cc
virtual void PostDbusCallToIoContextThreadSafe(
[[maybe_unused]] const std::shared_ptr<boost::asio::io_context::strand>&
strand,
absl::AnyInvocable<void(const boost::system::error_code&,
const PostPackageRepairStatusParam&)>&& callback,
const std::string& service, const std::string& objpath,
const std::string& interface, const std::string& method) {
boost::asio::post(
io_context_main_thread_, [this, callback(std::move(callback)), service,
objpath, interface, method]() mutable {
system_bus_->async_method_call(std::move(callback), service, objpath,
interface, method);
});
}
// getPostPackageRepairConfig in log_services.cc
virtual void PostDbusCallToIoContextThreadSafe(
[[maybe_unused]] const std::shared_ptr<boost::asio::io_context::strand>&
strand,
absl::AnyInvocable<void(const boost::system::error_code&,
const std::vector<uint16_t>&)>&& callback,
const std::string& service, const std::string& objpath,
const std::string& interface, const std::string& method) {
boost::asio::post(
io_context_main_thread_, [this, callback(std::move(callback)), service,
objpath, interface, method]() mutable {
system_bus_->async_method_call(std::move(callback), service, objpath,
interface, method);
});
}
// getPostCodeData (GetPostCodesTS returning flat_map) in log_services.cc
virtual void PostDbusCallToIoContextThreadSafe(
[[maybe_unused]] const std::shared_ptr<boost::asio::io_context::strand>&
strand,
absl::AnyInvocable<
void(const boost::system::error_code&,
const boost::container::flat_map<uint64_t, PostCodeEntry>&)>&&
callback,
const std::string& service, const std::string& objpath,
const std::string& interface, const std::string& get_postcodes,
uint16_t param1) {
boost::asio::post(io_context_main_thread_,
[this, callback(std::move(callback)), service, objpath,
interface, get_postcodes, param1]() mutable {
system_bus_->async_method_call(
std::move(callback), service, objpath, interface,
get_postcodes, param1);
});
}
// deleteLogEntry in log_services.cc, certificate_service.h
virtual void PostDbusCallToIoContextThreadSafe(
[[maybe_unused]] const std::shared_ptr<boost::asio::io_context::strand>&
strand,
absl::AnyInvocable<void(const boost::system::error_code&,
const sdbusplus::message_t&)>&& callback,
const std::string& service, const std::string& objpath,
const std::string& interface, const std::string& method) {
boost::asio::post(
io_context_main_thread_, [this, callback(std::move(callback)), service,
objpath, interface, method]() mutable {
system_bus_->async_method_call(std::move(callback), service, objpath,
interface, method);
});
}
// getLogEntry in log_services.cc
virtual void PostDbusCallToIoContextThreadSafe(
[[maybe_unused]] const std::shared_ptr<boost::asio::io_context::strand>&
strand,
absl::AnyInvocable<void(const boost::system::error_code&,
const sdbusplus::message::unix_fd&)>&& callback,
const std::string& service, const std::string& objpath,
const std::string& interface, const std::string& get_entry) {
boost::asio::post(
io_context_main_thread_, [this, callback(std::move(callback)), service,
objpath, interface, get_entry]() mutable {
system_bus_->async_method_call(std::move(callback), service, objpath,
interface, get_entry);
});
}
// createDump in log_services.cc
virtual void PostDbusCallToIoContextThreadSafe(
[[maybe_unused]] const std::shared_ptr<boost::asio::io_context::strand>&
strand,
absl::AnyInvocable<
void(const boost::system::error_code&, const sdbusplus::message_t&,
const sdbusplus::message::object_path&)>&& callback,
const std::string& service, const std::string& objpath,
const std::string& interface, const std::string& create_dump,
const CreateDumpParamVec& create_dump_param_vec) {
boost::asio::post(
io_context_main_thread_,
[this, callback(std::move(callback)), service, objpath, interface,
create_dump,
create_dump_param_vec(std::move(create_dump_param_vec))]() mutable {
system_bus_->async_method_call(std::move(callback), service, objpath,
interface, create_dump,
std::move(create_dump_param_vec));
});
}
// getUserInfo in user_monitor.h, openbmc_dbus_rest.h
virtual void PostDbusCallToIoContextThreadSafe(
[[maybe_unused]] const std::shared_ptr<boost::asio::io_context::strand>&
strand,
absl::AnyInvocable<void(const boost::system::error_code&,
const dbus::utility::DBusPropertiesMap&)>&&
callback,
const std::string& service, const std::string& objpath,
const std::string& interface, const std::string& get_user_info,
const std::string& username) {
boost::asio::post(io_context_main_thread_,
[this, callback(std::move(callback)), service, objpath,
interface, get_user_info, username]() mutable {
system_bus_->async_method_call(
std::move(callback), service, objpath, interface,
get_user_info, username);
});
}
// readFruData in managers.h
virtual void PostDbusCallToIoContextThreadSafe(
[[maybe_unused]] const std::shared_ptr<boost::asio::io_context::strand>&
strand,
absl::AnyInvocable<void(const boost::system::error_code&,
const std::vector<uint8_t>&)>&& callback,
const std::string& service, const std::string& objpath,
const std::string& interface, const std::string& method, uint16_t bus,
uint8_t address) {
boost::asio::post(io_context_main_thread_,
[this, callback(std::move(callback)), service, objpath,
interface, method, bus, address]() mutable {
system_bus_->async_method_call(
std::move(callback), service, objpath, interface,
method, bus, address);
});
}
// SendHostCommand in google_service_root.h
virtual void PostDbusCallToIoContextThreadSafe(
[[maybe_unused]] const std::shared_ptr<boost::asio::io_context::strand>&
strand,
absl::AnyInvocable<void(const boost::system::error_code&,
const std::vector<uint8_t>&)>&& callback,
const std::string& service, const std::string& objpath,
const std::string& interface, const std::string& send_host_command,
const std::vector<unsigned char>& payload) {
boost::asio::post(
io_context_main_thread_,
[this, callback(std::move(callback)), service, objpath, interface,
send_host_command, payload(std::move(payload))]() mutable {
system_bus_->async_method_call(std::move(callback), service, objpath,
interface, send_host_command,
std::move(payload));
});
}
// GetLogPage in google_service_nvme.h
virtual void PostDbusCallToIoContextThreadSafe(
[[maybe_unused]] const std::shared_ptr<boost::asio::io_context::strand>&
strand,
absl::AnyInvocable<void(const boost::system::error_code&,
const sdbusplus::message::unix_fd&)>&& callback,
const std::string& service, const std::string& objpath,
const std::string& interface, const std::string& get_log_page,
uint8_t lid, uint32_t nsid, uint8_t lsp, uint16_t lsi) {
boost::asio::post(io_context_main_thread_,
[this, callback(std::move(callback)), service, objpath,
interface, get_log_page, lid, nsid, lsp, lsi]() mutable {
system_bus_->async_method_call(
std::move(callback), service, objpath, interface,
get_log_page, lid, nsid, lsp, lsi);
});
}
// LockdownInband in google_service_nvme.h
virtual void PostDbusCallToIoContextThreadSafe(
[[maybe_unused]] const std::shared_ptr<boost::asio::io_context::strand>&
strand,
absl::AnyInvocable<void(
const boost::system::error_code&, const sdbusplus::message_t& msg,
const std::tuple<uint32_t, uint32_t, uint32_t, std::string,
uint32_t>&)>&& callback,
const std::string& service, const std::string& objpath,
const std::string& interface, const std::string& lockdown_inband,
const uint8_t prohibit, const std::vector<uint8_t>& admin_cmds,
const std::vector<uint8_t>& features,
const std::vector<uint8_t>& log_pages) {
boost::asio::post(
io_context_main_thread_,
[this, callback(std::move(callback)), service, objpath, interface,
lockdown_inband, prohibit, admin_cmds(std::move(admin_cmds)),
features(std::move(features)),
log_pages(std::move(log_pages))]() mutable {
system_bus_->async_method_call(
std::move(callback), service, objpath, interface, lockdown_inband,
prohibit, std::move(admin_cmds), std::move(features),
std::move(log_pages));
});
}
// Identify in google_service_nvme.h
virtual void PostDbusCallToIoContextThreadSafe(
[[maybe_unused]] const std::shared_ptr<boost::asio::io_context::strand>&
strand,
absl::AnyInvocable<void(const boost::system::error_code&,
const sdbusplus::message::unix_fd&)>&& callback,
const std::string& service, const std::string& objpath,
const std::string& interface, const std::string& identify, uint8_t cns,
uint32_t nsid, uint16_t cntid) {
boost::asio::post(io_context_main_thread_,
[this, callback(std::move(callback)), service, objpath,
interface, identify, cns, nsid, cntid]() mutable {
system_bus_->async_method_call(
std::move(callback), service, objpath, interface,
identify, cns, nsid, cntid);
});
}
// executeRde in redfish_aggregator.h
virtual void PostDbusCallToIoContextThreadSafe(
[[maybe_unused]] const std::shared_ptr<boost::asio::io_context::strand>&
strand,
absl::AnyInvocable<void(const boost::system::error_code&,
const std::string&)>&& callback,
const std::string& service, const std::string& objpath,
const std::string& interface, const std::string& execute_rde, int random,
uint8_t id, const std::string& uri, const std::string& udev_id,
const std::string& payload) {
boost::asio::post(
io_context_main_thread_,
[this, callback(std::move(callback)), service, objpath, interface,
execute_rde, random, id, uri, udev_id, payload]() mutable {
system_bus_->async_method_call(std::move(callback), service, objpath,
interface, execute_rde, random, id,
uri, udev_id, payload);
});
}
// createStorageVolume in storage.h
virtual void PostDbusCallToIoContextThreadSafe(
[[maybe_unused]] const std::shared_ptr<boost::asio::io_context::strand>&
strand,
absl::AnyInvocable<
void(const boost::system::error_code&, const sdbusplus::message_t&,
const sdbusplus::message::object_path&)>&& callback,
const std::string& service, const std::string& objpath,
const std::string& interface, const std::string& create_volume,
uint64_t size, size_t lba_index, bool metadata_at_end) {
boost::asio::post(
io_context_main_thread_,
[this, callback(std::move(callback)), service, objpath, interface,
create_volume, size, lba_index, metadata_at_end]() mutable {
system_bus_->async_method_call(std::move(callback), service, objpath,
interface, create_volume, size,
lba_index, metadata_at_end);
});
}
// storageApplyAttachDetach (AttachVolume/DetachVolume) in storage.h
virtual void PostDbusCallToIoContextThreadSafe(
[[maybe_unused]] const std::shared_ptr<boost::asio::io_context::strand>&
strand,
absl::AnyInvocable<void(const boost::system::error_code&,
const sdbusplus::message_t&)>&& callback,
const std::string& service, const std::string& objpath,
const std::string& interface, const std::string& attach_volume,
const sdbusplus::message::object_path& v) {
boost::asio::post(io_context_main_thread_,
[this, callback(std::move(callback)), service, objpath,
interface, attach_volume, v]() mutable {
system_bus_->async_method_call(
std::move(callback), service, objpath, interface,
attach_volume, v);
});
}
// securitySendAction in storage.h
virtual void PostDbusCallToIoContextThreadSafe(
[[maybe_unused]] const std::shared_ptr<boost::asio::io_context::strand>&
strand,
absl::AnyInvocable<void(const boost::system::error_code&,
const sdbusplus::message_t&)>&& callback,
const std::string& service, const std::string& objpath,
const std::string& interface, const std::string& security_send,
uint8_t proto, uint16_t proto_specific,
const std::vector<uint8_t>& data) {
boost::asio::post(io_context_main_thread_,
[this, callback(std::move(callback)), service, objpath,
interface, security_send, proto, proto_specific,
data(std::move(data))]() mutable {
system_bus_->async_method_call(
std::move(callback), service, objpath, interface,
security_send, proto, proto_specific,
std::move(data));
});
}
// securityReceiveAction in storage.h
virtual void PostDbusCallToIoContextThreadSafe(
[[maybe_unused]] const std::shared_ptr<boost::asio::io_context::strand>&
strand,
absl::AnyInvocable<void(const boost::system::error_code&,
const sdbusplus::message_t&,
const std::vector<uint8_t>&)>&& callback,
const std::string& service, const std::string& objpath,
const std::string& interface, const std::string& security_recieve,
uint8_t proto, uint16_t proto_specific, uint32_t transfer_length) {
boost::asio::post(
io_context_main_thread_,
[this, callback(std::move(callback)), service, objpath, interface,
security_recieve, proto, proto_specific, transfer_length]() mutable {
system_bus_->async_method_call(std::move(callback), service, objpath,
interface, security_recieve, proto,
proto_specific, transfer_length);
});
}
// eraseDrive in storage.h
virtual void PostDbusCallToIoContextThreadSafe(
[[maybe_unused]] const std::shared_ptr<boost::asio::io_context::strand>&
strand,
absl::AnyInvocable<void(const boost::system::error_code&,
const sdbusplus::message_t&)>&& callback,
const std::string& service, const std::string& objpath,
const std::string& interface, const std::string& drive_erase,
const std::string& action_name) {
boost::asio::post(io_context_main_thread_,
[this, callback(std::move(callback)), service, objpath,
interface, drive_erase, action_name]() mutable {
system_bus_->async_method_call(
std::move(callback), service, objpath, interface,
drive_erase, action_name);
});
}
// addObject in managers.h
virtual void PostDbusCallToIoContextThreadSafe(
[[maybe_unused]] const std::shared_ptr<boost::asio::io_context::strand>&
strand,
absl::AnyInvocable<void(const boost::system::error_code&)>&& callback,
const std::string& service, const std::string& objpath,
const std::string& interface, const std::string& add_object,
const dbus::utility::DBusPropertiesMap& output) {
boost::asio::post(
io_context_main_thread_,
[this, callback(std::move(callback)), service, objpath, interface,
add_object, output(std::move(output))]() mutable {
system_bus_->async_method_call(std::move(callback), service, objpath,
interface, add_object,
std::move(output));
});
}
// installCertificate in certificate_service.h
virtual void PostDbusCallToIoContextThreadSafe(
[[maybe_unused]] const std::shared_ptr<boost::asio::io_context::strand>&
strand,
absl::AnyInvocable<void(const boost::system::error_code&,
const std::string&)>&& callback,
const std::string& service, const std::string& objpath,
const std::string& interface, const std::string& install,
const std::string& file_path) {
boost::asio::post(io_context_main_thread_,
[this, callback(std::move(callback)), service, objpath,
interface, install, file_path]() mutable {
system_bus_->async_method_call(
std::move(callback), service, objpath, interface,
install, file_path);
});
}
// replaceCertificate in certificate_service.h
virtual void PostDbusCallToIoContextThreadSafe(
[[maybe_unused]] const std::shared_ptr<boost::asio::io_context::strand>&
strand,
absl::AnyInvocable<void(const boost::system::error_code&)>&& callback,
const std::string& service, const std::string& objpath,
const std::string& interface, const std::string& replace,
const std::string& file_path) {
boost::asio::post(io_context_main_thread_,
[this, callback(std::move(callback)), service, objpath,
interface, replace, file_path]() mutable {
system_bus_->async_method_call(
std::move(callback), service, objpath, interface,
replace, file_path);
});
}
// getSignedMeasurements (SPDMGetSignedMeasurements) in component_integrity.h
virtual void PostDbusCallToIoContextThreadSafe(
[[maybe_unused]] const std::shared_ptr<boost::asio::io_context::strand>&
strand,
SPDMGetSignedMeasurmentsCb&& callback, const std::string& service,
const std::string& objpath, const std::string& interface,
const std::string& replace,
const std::vector<size_t>& opt_measurement_indexes,
const std::string& opt_nonce, size_t opt_slot_id) {
boost::asio::post(
io_context_main_thread_,
[this, callback(std::move(callback)), service, objpath, interface,
replace, opt_measurement_indexes(std::move(opt_measurement_indexes)),
opt_nonce, opt_slot_id]() mutable {
system_bus_->async_method_call(
std::move(callback), service, objpath, interface, replace,
std::move(opt_measurement_indexes), opt_nonce, opt_slot_id);
});
}
// getBootTimeCheckpointLogEntries in log_services.cc
virtual void PostDbusCallToIoContextThreadSafe(
[[maybe_unused]] const std::shared_ptr<boost::asio::io_context::strand>&
strand,
absl::AnyInvocable<
void(const boost::system::error_code&,
const std::vector<std::tuple<std::string, int64_t, int64_t>>&)>&&
callback,
const std::string& service, const std::string& objpath,
const std::string& interface, const std::string& method) {
boost::asio::post(
io_context_main_thread_, [this, callback(std::move(callback)), service,
objpath, interface, method]() mutable {
system_bus_->async_method_call(std::move(callback), service, objpath,
interface, method);
});
}
// getBootTimeDurationLogEntries in log_services.cc
virtual void PostDbusCallToIoContextThreadSafe(
[[maybe_unused]] const std::shared_ptr<boost::asio::io_context::strand>&
strand,
absl::AnyInvocable<void(
const boost::system::error_code&,
const std::vector<std::tuple<std::string, int64_t>>&)>&& callback,
const std::string& service, const std::string& objpath,
const std::string& interface, const std::string& method) {
boost::asio::post(
io_context_main_thread_, [this, callback(std::move(callback)), service,
objpath, interface, method]() mutable {
system_bus_->async_method_call(std::move(callback), service, objpath,
interface, method);
});
}
// PLDMd reload file and sync cache for VMTPPR in bios.h
virtual void PostDbusCallToIoContextThreadSafe(
[[maybe_unused]] const std::shared_ptr<boost::asio::io_context::strand>&
strand,
absl::AnyInvocable<void(const boost::system::error_code&)>&& callback,
const std::string& service, const std::string& objpath,
const std::string& interface, const std::string& method,
uint16_t file_handle) {
boost::asio::post(io_context_main_thread_,
[this, callback(std::move(callback)), service, objpath,
interface, method, file_handle]() mutable {
system_bus_->async_method_call(
std::move(callback), service, objpath, interface,
method, file_handle);
});
}
// GetAll in trigger.h, telemetry_service.h
virtual void PostDbusCallToIoContextThreadSafe(
[[maybe_unused]] const std::shared_ptr<boost::asio::io_context::strand>&
strand,
TriggerGetAllCb&& callback, const std::string& service,
const std::string& objpath, const std::string& interface,
const std::string& get_all, const std::string& target_interface) {
boost::asio::post(io_context_main_thread_,
[this, callback(std::move(callback)), service, objpath,
interface, get_all, target_interface]() mutable {
system_bus_->async_method_call(
std::move(callback), service, objpath, interface,
get_all, target_interface);
});
}
// setPostPackageRepairConfig in log_services.cc
virtual void PostDbusCallToIoContextThreadSafe(
[[maybe_unused]] const std::shared_ptr<boost::asio::io_context::strand>&
strand,
absl::AnyInvocable<void(const boost::system::error_code&, const bool&)>&&
callback,
const std::string& service, const std::string& objpath,
const std::string& interface, const std::string& method,
const std::uint16_t& flag, const bool& data) {
boost::asio::post(io_context_main_thread_,
[this, callback(std::move(callback)), service, objpath,
interface, method, flag, data]() mutable {
system_bus_->async_method_call(
std::move(callback), service, objpath, interface,
method, flag, data);
});
}
// setPostPackageRepairData in log_services.cc
virtual void PostDbusCallToIoContextThreadSafe(
[[maybe_unused]] const std::shared_ptr<boost::asio::io_context::strand>&
strand,
absl::AnyInvocable<void(const boost::system::error_code&, const bool&)>&&
callback,
const std::string& service, const std::string& objpath,
const std::string& interface, const std::string& method,
const uint16_t repairEntryNum, const uint16_t repairType,
const uint16_t socNum, const std::vector<uint16_t>& payload) {
boost::asio::post(io_context_main_thread_,
[this, callback(std::move(callback)), service, objpath,
interface, method, repairEntryNum, repairType, socNum,
payload(std::move(payload))]() mutable {
system_bus_->async_method_call(
std::move(callback), service, objpath, interface,
method, repairEntryNum, repairType, socNum,
std::move(payload));
});
}
// startRuntimeRepair in log_services.cc
virtual void PostDbusCallToIoContextThreadSafe(
[[maybe_unused]] const std::shared_ptr<boost::asio::io_context::strand>&
strand,
absl::AnyInvocable<void(const boost::system::error_code&,
const uint32_t&)>&& callback,
const std::string& service, const std::string& objpath,
const std::string& interface, const std::string& method,
const uint16_t Index) {
boost::asio::post(
io_context_main_thread_, [this, callback(std::move(callback)), service,
objpath, interface, method, Index]() mutable {
system_bus_->async_method_call(std::move(callback), service, objpath,
interface, method, Index);
});
}
// nvmeMetricFetcher returning unix_fd in nvme_metric_utils.h
virtual void PostDbusCallToIoContextThreadSafe(
[[maybe_unused]] const std::shared_ptr<boost::asio::io_context::strand>&
strand,
absl::AnyInvocable<void(const boost::system::error_code&,
const sdbusplus::message::unix_fd&)>&& callback,
const std::string& service, const std::string& objpath,
const std::string& interface, const std::string& method,
const std::string& arg) {
boost::asio::post(
io_context_main_thread_, [this, callback(std::move(callback)), service,
objpath, interface, method, arg]() mutable {
system_bus_->async_method_call(std::move(callback), service, objpath,
interface, method, arg);
});
}
// nvmeMetricFetcher returning message_t and unix_fd in nvme_metric_utils.h
virtual void PostDbusCallToIoContextThreadSafe(
[[maybe_unused]] const std::shared_ptr<boost::asio::io_context::strand>&
strand,
absl::AnyInvocable<void(const boost::system::error_code&,
const sdbusplus::message_t& msg,
const sdbusplus::message::unix_fd&)>&& callback,
const std::string& service, const std::string& objpath,
const std::string& interface, const std::string& method,
const std::string& arg) {
boost::asio::post(
io_context_main_thread_, [this, callback(std::move(callback)), service,
objpath, interface, method, arg]() mutable {
system_bus_->async_method_call(std::move(callback), service, objpath,
interface, method, arg);
});
}
// GetFeature in nvme_features.h
virtual void PostDbusCallToIoContextThreadSafe(
[[maybe_unused]] const std::shared_ptr<boost::asio::io_context::strand>&
strand,
absl::AnyInvocable<void(const boost::system::error_code&,
const sdbusplus::message_t&,
const std::vector<uint8_t>&)>&& callback,
const std::string& service, const std::string& objpath,
const std::string& interface, const std::string& method,
const std::string& arg) {
boost::asio::post(
io_context_main_thread_, [this, callback(std::move(callback)), service,
objpath, interface, method, arg]() mutable {
system_bus_->async_method_call(std::move(callback), service, objpath,
interface, method, arg);
});
}
// SetFeature in nvme_features.h
virtual void PostDbusCallToIoContextThreadSafe(
[[maybe_unused]] const std::shared_ptr<boost::asio::io_context::strand>&
strand,
absl::AnyInvocable<void(const boost::system::error_code&,
const sdbusplus::message_t&)>&& callback,
const std::string& service, const std::string& objpath,
const std::string& interface, const std::string& method,
const std::string& feature_name, const std::vector<uint8_t>& payload) {
boost::asio::post(io_context_main_thread_,
[this, callback(std::move(callback)), service, objpath,
interface, method, feature_name, payload]() mutable {
system_bus_->async_method_call(
std::move(callback), service, objpath, interface,
method, feature_name, payload);
});
}
// AddReport in metric_report_definition.h
virtual void PostDbusCallToIoContextThreadSafe(
[[maybe_unused]] const std::shared_ptr<boost::asio::io_context::strand>&
strand,
absl::AnyInvocable<void(const boost::system::error_code&,
const std::string&)>&& callback,
const std::string& service, const std::string& objpath,
const std::string& interface, const std::string& method,
const std::string& report_id, const std::string& reporting_type,
bool emits_readings_update, bool log_to_metric_reports_collection,
uint64_t interval, const ReadingParameters& reading_parameters) {
boost::asio::post(
io_context_main_thread_,
[this, callback(std::move(callback)), service, objpath, interface,
method, report_id, reporting_type, emits_readings_update,
log_to_metric_reports_collection, interval,
reading_parameters]() mutable {
system_bus_->async_method_call(
std::move(callback), service, objpath, interface, method,
report_id, reporting_type, emits_readings_update,
log_to_metric_reports_collection, interval, reading_parameters);
});
}
// SignCSR in google_service_root.h
virtual void PostDbusCallToIoContextThreadSafe(
[[maybe_unused]] const std::shared_ptr<boost::asio::io_context::strand>&
strand,
absl::AnyInvocable<
void(const boost::system::error_code&, const std::string&,
const std::string&, const std::string&, const std::string&,
const std::string&, const std::string&)>&& callback,
const std::string& service, const std::string& objpath,
const std::string& interface, const std::string& method,
const std::string& arg1, const std::string& arg2,
const std::string& arg3) {
boost::asio::post(io_context_main_thread_,
[this, callback(std::move(callback)), service, objpath,
interface, method, arg1, arg2, arg3]() mutable {
system_bus_->async_method_call(
std::move(callback), service, objpath, interface,
method, arg1, arg2, arg3);
});
}
#endif
};
// ManagedStore type is an alias to ManagedObjectStore
using ManagedStore = managedStore::ManagedObjectStore;
// Sets the ManagedObjectStore instance for testing.
void SetManagedStoreInstanceForTesting(ManagedObjectStore* instance);
// Only initialize if cfg and io are not null
// TODO(rahulkpr): Call InitializeManagedStore() instead from webserver_main.
ManagedStore* InitializeManagedStore(
const ManagedObjectStoreConfig* cfg,
boost::asio::io_context* io_main_thread,
const std::shared_ptr<boost::asio::io_context>& io_context_worker_threads,
ecclesia::SubscriptionService* subscription_service,
sdbusplus::asio::connection* systemBus,
std::shared_ptr<milotic_tlbmc::SystemRegistry> system_registry);
ManagedStore* InitializeManagedStore(
const ManagedObjectStoreConfig* cfg,
boost::asio::io_context* io_main_thread,
const std::shared_ptr<boost::asio::io_context>& io_context_worker_threads,
ecclesia::SubscriptionService* subscription_service,
sdbusplus::asio::connection* systemBus);
// If ManagedObjectStore is initialized, then return it, if not return nullptr
ManagedStore* GetManagedObjectStore();
} // namespace managedStore