| #include "tlbmc/hal/fru_scanner_usb.h" |
| |
| #include <glob.h> |
| |
| #include <filesystem> // NOLINT: filesystem is available on BMC |
| #include <memory> |
| #include <string> |
| #include <utility> |
| #include <vector> |
| |
| #include "absl/memory/memory.h" |
| #include "absl/status/status.h" |
| #include "absl/status/statusor.h" |
| #include "absl/strings/str_cat.h" |
| #include "tlbmc/hal/fru_scanner.h" |
| #include "status.pb.h" |
| |
| namespace milotic_tlbmc { |
| |
| std::unique_ptr<FruScannerUsb> FruScannerUsb::Create(const Options& options) { |
| return absl::WrapUnique( |
| new FruScannerUsb(options.soc_path, options.components)); |
| } |
| |
| absl::StatusOr<std::vector<std::unique_ptr<UsbFruInfo>>> |
| FruScannerUsb::ScanAllUsbFrus() const { |
| std::vector<std::unique_ptr<UsbFruInfo>> usb_frus; |
| |
| usb_frus.reserve(usb_components_.size()); |
| for (const auto& component : usb_components_) { |
| auto usb_fru = std::make_unique<UsbFruInfo>(); |
| usb_fru->expected_barepath = component.barepath(); |
| |
| std::string rel_path = component.sysfs_path(); |
| if (!rel_path.empty() && rel_path[0] == '/') { |
| rel_path = rel_path.substr(1); |
| } |
| std::string full_pattern = |
| (std::filesystem::path(soc_path_) / rel_path).string(); |
| |
| glob_t glob_result = {}; |
| int ret = glob(full_pattern.c_str(), GLOB_NOSORT | GLOB_ERR, nullptr, |
| &glob_result); |
| if (ret == 0) { |
| usb_fru->presence_status = PresenceStatus::PRESENCE_STATUS_PRESENT; |
| globfree(&glob_result); |
| } else if (ret == GLOB_NOMATCH) { |
| usb_fru->presence_status = PresenceStatus::PRESENCE_STATUS_NOT_FOUND; |
| globfree(&glob_result); |
| } else { |
| globfree(&glob_result); |
| return absl::InternalError( |
| absl::StrCat("glob() failed when scanning USB FRU path '", |
| full_pattern, "' with error code: ", ret)); |
| } |
| usb_frus.push_back(std::move(usb_fru)); |
| } |
| return usb_frus; |
| } |
| |
| } // namespace milotic_tlbmc |