blob: 89d3044e9f80c8704958718096cf4ddbaeb03866 [file] [log] [blame]
// Copyright 2018 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "diagnostics/diagnosticsd/diagnosticsd_grpc_service.h"
#include <string>
#include <utility>
#include <base/files/file_util.h>
#include <base/logging.h>
namespace diagnostics {
namespace {
// Makes a dump of the specified file. Returns whether the dumping succeeded.
bool MakeFileDump(const base::FilePath& file_path,
grpc_api::FileDump* file_dump) {
std::string file_contents;
if (!base::ReadFileToString(file_path, &file_contents)) {
VPLOG(2) << "Failed to read from " << file_path.value();
return false;
}
const base::FilePath canonical_file_path =
base::MakeAbsoluteFilePath(file_path);
if (canonical_file_path.empty()) {
PLOG(ERROR) << "Failed to obtain canonical path for " << file_path.value();
return false;
}
VLOG(2) << "Read " << file_contents.size() << " bytes from "
<< file_path.value() << " with canonical path "
<< canonical_file_path.value();
file_dump->set_path(file_path.value());
file_dump->set_canonical_path(canonical_file_path.value());
file_dump->set_contents(std::move(file_contents));
return true;
}
} // namespace
DiagnosticsdGrpcService::DiagnosticsdGrpcService(Delegate* delegate)
: delegate_(delegate) {
DCHECK(delegate_);
}
DiagnosticsdGrpcService::~DiagnosticsdGrpcService() = default;
void DiagnosticsdGrpcService::SendMessageToUi(
std::unique_ptr<grpc_api::SendMessageToUiRequest> request,
const SendMessageToUiCallback& callback) {
NOTIMPLEMENTED();
}
void DiagnosticsdGrpcService::GetProcData(
std::unique_ptr<grpc_api::GetProcDataRequest> request,
const GetProcDataCallback& callback) {
DCHECK(request);
auto reply = std::make_unique<grpc_api::GetProcDataResponse>();
switch (request->type()) {
case grpc_api::GetProcDataRequest::FILE_UPTIME:
AddFileDump(base::FilePath("proc/uptime"), reply->mutable_file_dump());
break;
case grpc_api::GetProcDataRequest::FILE_MEMINFO:
AddFileDump(base::FilePath("proc/meminfo"), reply->mutable_file_dump());
break;
case grpc_api::GetProcDataRequest::FILE_LOADAVG:
AddFileDump(base::FilePath("proc/loadavg"), reply->mutable_file_dump());
break;
case grpc_api::GetProcDataRequest::FILE_STAT:
AddFileDump(base::FilePath("proc/stat"), reply->mutable_file_dump());
break;
case grpc_api::GetProcDataRequest::FILE_NET_NETSTAT:
AddFileDump(base::FilePath("proc/net/netstat"),
reply->mutable_file_dump());
break;
case grpc_api::GetProcDataRequest::FILE_NET_DEV:
AddFileDump(base::FilePath("proc/net/dev"), reply->mutable_file_dump());
break;
default:
LOG(ERROR) << "GetProcData gRPC request type unset or invalid: "
<< request->type();
// Error is designated by a reply with the empty list of entries.
callback.Run(std::move(reply));
return;
}
VLOG(1) << "Completing GetProcData gRPC request of type " << request->type()
<< ", returning " << reply->file_dump_size() << " items";
callback.Run(std::move(reply));
}
void DiagnosticsdGrpcService::AddFileDump(
const base::FilePath& relative_file_path,
google::protobuf::RepeatedPtrField<grpc_api::FileDump>* file_dumps) {
DCHECK(!relative_file_path.IsAbsolute());
grpc_api::FileDump file_dump;
if (!MakeFileDump(root_dir_.Append(relative_file_path), &file_dump)) {
// When a file is failed to be dumped, it's just omitted from the returned
// list of entries.
return;
}
file_dumps->Add()->Swap(&file_dump);
}
} // namespace diagnostics