blob: 2466d084aa557955a9163fd9c4cd1f53d607c1b5 [file] [log] [blame]
// Copyright 2019 The Fuchsia 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 "src/cobalt/bin/system-metrics/memory_stats_fetcher_impl.h"
#include <fcntl.h>
#include <fuchsia/cobalt/cpp/fidl.h>
#include <fuchsia/sysinfo/c/fidl.h>
#include <lib/fdio/fdio.h>
#include <lib/zx/resource.h>
#include <trace/event.h>
#include <zircon/status.h>
#include "src/lib/fxl/logging.h"
namespace cobalt {
MemoryStatsFetcherImpl::MemoryStatsFetcherImpl() {
InitializeRootResourceHandle();
}
bool MemoryStatsFetcherImpl::FetchMemoryStats(zx_info_kmem_stats_t* mem_stats) {
TRACE_DURATION("system_metrics", "MemoryStatsFetcherImpl::FetchMemoryStats");
if (root_resource_handle_ == ZX_HANDLE_INVALID) {
FXL_LOG(ERROR) << "MemoryStatsFetcherImpl: No root resource"
<< "present. Reconnecting...";
InitializeRootResourceHandle();
return false;
}
zx_status_t err =
zx_object_get_info(root_resource_handle_, ZX_INFO_KMEM_STATS, mem_stats,
sizeof(*mem_stats), NULL, NULL);
if (err != ZX_OK) {
FXL_LOG(ERROR) << "MemoryStatsFetcherImpl: Fetching "
<< "ZX_INFO_KMEM_STATS through syscall returns "
<< zx_status_get_string(err);
return false;
}
return true;
}
// TODO(CF-691) When Component Stats (CS) supports memory metrics,
// switch to Component Stats / iquery, by creating a new class with the
// interface MemoryStatsFetcher.
void MemoryStatsFetcherImpl::InitializeRootResourceHandle() {
static const char kSysInfo[] = "/dev/misc/sysinfo";
int fd = open(kSysInfo, O_RDWR);
if (fd < 0) {
FXL_LOG(ERROR)
<< "Cobalt SystemMetricsDaemon: Error getting root_resource_handle_. "
<< "Cannot open sysinfo: " << strerror(errno);
return;
}
zx::channel channel;
zx_status_t status =
fdio_get_service_handle(fd, channel.reset_and_get_address());
if (status != ZX_OK) {
FXL_LOG(ERROR)
<< "Cobalt SystemMetricsDaemon: Error getting root_resource_handle_. "
<< "Cannot obtain sysinfo channel: " << zx_status_get_string(status);
return;
}
zx_status_t fidl_status = fuchsia_sysinfo_DeviceGetRootResource(
channel.get(), &status, &root_resource_handle_);
if (fidl_status != ZX_OK) {
FXL_LOG(ERROR)
<< "Cobalt SystemMetricsDaemon: Error getting root_resource_handle_. "
<< zx_status_get_string(fidl_status);
return;
} else if (status != ZX_OK) {
FXL_LOG(ERROR)
<< "Cobalt SystemMetricsDaemon: Error getting root_resource_handle_. "
<< zx_status_get_string(status);
return;
} else if (root_resource_handle_ == ZX_HANDLE_INVALID) {
FXL_LOG(ERROR)
<< "Cobalt SystemMetricsDaemon: Failed to get root_resource_handle_.";
return;
}
}
} // namespace cobalt