pmbus: Safely call std::filesystem::canonical()
There are a few different places where CALLOUT_DEVICE_PATH elog metadata
is used that passes in the result of a std::filesystem::canonical()
call.
That function will throw if the path passed in does not exist. Since
that code isn't in a try/catch block, the application will crash.
Fix that by using the version of the function that sets a
std::error_code in an output parameter to indicate failure. If it does
fail, then just use the original path given to it.
As canonical() was used for a reason, there may be side affects such as
proper error analysis not being done, but there is not much that can be
done about that.
Tested:
The app doesn't crash, and can see:
```
Failed to read sysfs file errno=2 FILENAME=/sys/kernel/debug/pmbus/status0
Could not get canonical path from /sys/bus/i2c/devices/3-006a
Failed to read from the device.
```
And in the event log
```
"CALLOUT_DEVICE_PATH" "/sys/bus/i2c/devices/3-006a"
```
Change-Id: I9ea374dc685cc325b40a1f2bb0c8ae0ce71df650
Signed-off-by: Matt Spinler <spinler@us.ibm.com>
diff --git a/pmbus.cpp b/pmbus.cpp
index 7bdda54..8b6d747 100644
--- a/pmbus.cpp
+++ b/pmbus.cpp
@@ -45,6 +45,28 @@
}
};
+/**
+ * @brief Returns the canonical path if it exists
+ * otherwise returns the path passed in.
+ *
+ * @param[in] path - The path to check
+ *
+ * @return fs::path - Either the canonical or original path
+ */
+static fs::path tryCanonical(const fs::path& path)
+{
+ std::error_code ec;
+ auto canonical = fs::canonical(path, ec);
+
+ if (ec)
+ {
+ lg2::error("Could not get canonical path from {PATH}", "PATH", path);
+ return path;
+ }
+
+ return canonical;
+}
+
std::string PMBus::insertPageNum(const std::string& templateName, size_t page)
{
auto name = templateName;
@@ -157,7 +179,7 @@
elog<ReadFailure>(
metadata::CALLOUT_ERRNO(rc),
- metadata::CALLOUT_DEVICE_PATH(fs::canonical(basePath).c_str()));
+ metadata::CALLOUT_DEVICE_PATH(tryCanonical(basePath).c_str()));
}
return value != 0;
@@ -199,7 +221,7 @@
elog<ReadFailure>(
metadata::CALLOUT_ERRNO(rc),
- metadata::CALLOUT_DEVICE_PATH(fs::canonical(basePath).c_str()));
+ metadata::CALLOUT_DEVICE_PATH(tryCanonical(basePath).c_str()));
}
else
{
@@ -236,7 +258,7 @@
elog<ReadFailure>(
metadata::CALLOUT_ERRNO(rc),
- metadata::CALLOUT_DEVICE_PATH(fs::canonical(basePath).c_str()));
+ metadata::CALLOUT_DEVICE_PATH(tryCanonical(basePath).c_str()));
}
return data;
@@ -276,7 +298,7 @@
elog<ReadFailure>(metadata::CALLOUT_ERRNO(rc),
metadata::CALLOUT_DEVICE_PATH(
- fs::canonical(basePath).c_str()));
+ tryCanonical(basePath).c_str()));
}
}
return data;
@@ -311,7 +333,7 @@
elog<WriteFailure>(
metadata::CALLOUT_ERRNO(rc),
- metadata::CALLOUT_DEVICE_PATH(fs::canonical(basePath).c_str()));
+ metadata::CALLOUT_DEVICE_PATH(tryCanonical(basePath).c_str()));
}
}
@@ -345,7 +367,7 @@
elog<WriteFailure>(
metadata::CALLOUT_ERRNO(rc),
- metadata::CALLOUT_DEVICE_PATH(fs::canonical(basePath).c_str()));
+ metadata::CALLOUT_DEVICE_PATH(tryCanonical(basePath).c_str()));
}
}