blob: 75921894bc96dddfb68b7208797b4f1125d8fc9d [file] [log] [blame] [edit]
#include "baremetal_callback.h"
#include <unistd.h>
#include <cstdlib>
#include <filesystem> // NOLINT
#include <fstream>
#include <sstream>
#include <string>
#include <system_error> // NOLINT
#include <thread>
#include "absl/log/log.h"
#include "grpcpp/server_context.h"
#include "grpcpp/support/status.h"
namespace blobs {
grpc::Status BaremetalTransferServiceImpl::BmModeTransfer(
[[maybe_unused]] grpc::ServerContext* context,
[[maybe_unused]] const phosphor::baremetal::BmModeRequest* request,
phosphor::baremetal::BmModeResponse* response) {
/*
enum BmMode {
BMMODE_UNKNOWN = 0;
BMMODE_NON_BM = 1;
BMMODE_BM = 2;
BMMODE_STEADY_STATE = 3;
}
*/
std::error_code ec;
if (std::filesystem::exists(
std::string(bmDriveCleaningDoneAckFlagPath) + instanceString, ec)) {
LOG(INFO) << "We acked cleaning done and must be in BM mode";
response->set_bm_mode(phosphor::baremetal::BmMode::BMMODE_BM);
return grpc::Status::OK;
}
if (std::filesystem::exists(
std::string(bmDriveCleaningDoneFlagPath) + instanceString, ec)) {
std::filesystem::rename(
std::string(bmDriveCleaningDoneFlagPath) + instanceString,
std::string(bmDriveCleaningDoneAckFlagPath) + instanceString, ec);
LOG(INFO) << "We just finished cleaning and must be in BM mode";
response->set_bm_mode(phosphor::baremetal::BmMode::BMMODE_BM);
return grpc::Status::OK;
}
if (std::filesystem::exists(std::string(bmSignalPath), ec)) {
if (!std::filesystem::exists(
std::string(bmDriveCleaningFlagPath) + instanceString, ec)) {
std::ofstream file(std::string(bmDriveCleaningFlagPath) + instanceString);
}
LOG(INFO) << "We must be in BM cleaning mode";
response->set_bm_mode(phosphor::baremetal::BmMode::BMMODE_STEADY_STATE);
return grpc::Status::OK;
}
// Set default response
LOG(INFO) << "We must not be in BM mode";
response->set_bm_mode(phosphor::baremetal::BmMode::BMMODE_NON_BM);
return grpc::Status::OK;
}
grpc::Status BaremetalTransferServiceImpl::LinuxBootDone(
[[maybe_unused]] grpc::ServerContext* context,
[[maybe_unused]] const phosphor::baremetal::LinuxBootDoneRequest* request,
[[maybe_unused]] phosphor::baremetal::LinuxBootDoneResponse* response) {
LOG(INFO) << "LinuxBootDone on this instance number: " << instanceNumber;
// Asynchronously start the systemd targets that will disable communication
// with the host.
std::thread systemd_thread([this]() {
std::stringstream bm_prep_stream;
// Use instanceString instead of instanceNumber because the instanceString
// variables are "1" and "2", whereas instanceNumber is 0 and 1
bm_prep_stream << "gbmc-bare-metal-prep@" << this->instanceString
<< ".target";
std::string bm_prep_target = bm_prep_stream.str();
// Start the bare metal prep target. This can be used to monitor the
// ethernet connection to the host and wait until the CN shuts down the PCIe
// connection.
// Note: Use "systemctl restart" in case the target was already started on a
// previous CN boot.
int ret = system(("systemctl restart " + bm_prep_target).c_str());
if (ret != 0) {
LOG(ERROR) << "Failed to start target: " << bm_prep_target
<< " error: " << ret;
} else {
LOG(INFO) << "Successfully started target: " << bm_prep_target;
}
// Now we'll start the gbmc-bare-metal-active target.
std::stringstream bm_active_stream;
bm_active_stream << "gbmc-bare-metal-active@" << this->instanceString
<< ".target";
std::string bm_active_target = bm_active_stream.str();
ret = system(("systemctl start " + bm_active_target).c_str());
if (ret != 0) {
LOG(ERROR) << "Failed to start target: " << bm_active_target
<< " error: " << ret;
} else {
LOG(INFO) << "Successfully started target: " << bm_active_target;
}
});
systemd_thread.detach();
return grpc::Status::OK;
}
grpc::Status BaremetalTransferServiceImpl::BMInstancePropertiesTransfer(
[[maybe_unused]] grpc::ServerContext* context,
[[maybe_unused]] const phosphor::baremetal::
BMInstancePropertiesTransferRequest* request,
phosphor::baremetal::BMInstancePropertiesTransferResponse* response) {
LOG(INFO) << "BMInstancePropertiesTransfer on this instance number: "
<< instanceNumber;
response->set_asset_tag(readBMInstanceFromFile(
std::string(bmInstanceBasePath) + "asset-tag" + instanceString));
response->set_board_serial_number(
readBMInstanceFromFile(std::string(bmInstanceBasePath) +
"board-serial-number" + instanceString));
response->set_family(readBMInstanceFromFile(std::string(bmInstanceBasePath) +
"family" + instanceString));
response->set_product_name(readBMInstanceFromFile(
std::string(bmInstanceBasePath) + "product-name" + instanceString));
response->set_sku(readBMInstanceFromFile(std::string(bmInstanceBasePath) +
"sku" + instanceString));
response->set_system_serial_number(
readBMInstanceFromFile(std::string(bmInstanceBasePath) +
"system-serial-number" + instanceString));
response->set_uuid(readBMInstanceFromFile(std::string(bmInstanceBasePath) +
"uuid" + instanceString));
return grpc::Status::OK;
}
std::string BaremetalTransferServiceImpl::readBMInstanceFromFile(
const std::string& bmInstancePath) {
// If the path doesn't exist, set it to an empty string
if (!std::filesystem::exists(bmInstancePath)) {
return {};
}
std::ifstream ifs;
ifs.exceptions(std::ifstream::failbit);
std::string property;
try {
ifs.open(bmInstancePath);
std::getline(ifs, property);
} catch (const std::ios_base::failure& fail) {
return {};
}
return property;
}
} // namespace blobs