Add Mutex Guard around open in sendPackage
The `fd` is current thread unsafe and could potentially be
access/overridden by multiple thread. Add the mutex around the open() in
sendPackage to make sure it is only called once.
Tested: Added unit tests to make sure we are thread safe.
Change-Id: I2801bace2c816ed3454c3f79b57609aa8f6ecc33
Signed-off-by: Willy Tu <wltu@google.com>
diff --git a/src/ipmiblob/ipmi_handler.cpp b/src/ipmiblob/ipmi_handler.cpp
index b51718a..3ce5d92 100644
--- a/src/ipmiblob/ipmi_handler.cpp
+++ b/src/ipmiblob/ipmi_handler.cpp
@@ -27,7 +27,9 @@
#include <atomic>
#include <cstdint>
#include <cstring>
+#include <functional>
#include <memory>
+#include <mutex>
#include <sstream>
#include <string>
#include <vector>
@@ -42,11 +44,16 @@
void IpmiHandler::open()
{
- const int device = 0;
- const std::vector<std::string> formats = {"/dev/ipmi", "/dev/ipmi/",
- "/dev/ipmidev/"};
+ std::lock_guard<std::mutex> guard(openMutex);
+ if (fd >= 0)
+ {
+ return;
+ }
- for (const auto& format : formats)
+ constexpr int device = 0;
+ const std::array<std::string, 3> formats = {"/dev/ipmi", "/dev/ipmi/",
+ "/dev/ipmidev/"};
+ for (const std::string& format : formats)
{
std::ostringstream path;
path << format << device;
@@ -69,10 +76,7 @@
IpmiHandler::sendPacket(std::uint8_t netfn, std::uint8_t cmd,
std::vector<std::uint8_t>& data)
{
- if (fd < 0)
- {
- open();
- }
+ open();
constexpr int ipmiOEMLun = 0;
constexpr int fifteenMs = 15 * 1000;
@@ -126,7 +130,7 @@
{
continue;
}
- throw IpmiException("Error occurred.");
+ throw IpmiException("Polling Error occurred.");
}
else if (rc == 0)
{
diff --git a/src/ipmiblob/ipmi_handler.hpp b/src/ipmiblob/ipmi_handler.hpp
index fedc068..2564e37 100644
--- a/src/ipmiblob/ipmi_handler.hpp
+++ b/src/ipmiblob/ipmi_handler.hpp
@@ -5,6 +5,7 @@
#include <atomic>
#include <memory>
+#include <mutex>
#include <vector>
namespace ipmiblob
@@ -49,6 +50,9 @@
int fd = -1;
/* The last IPMI sequence number we used. */
std::atomic_int sequence = 0;
+
+ // Protect the open fd between different threads
+ std::mutex openMutex;
};
} // namespace ipmiblob