blob: 90a5c730dd27a952c97741df25a7591b08fb6aa0 [file] [log] [blame]
// Copyright 2018 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/virtualization/bin/guest/balloon.h"
#include <fuchsia/virtualization/cpp/fidl.h>
#include <lib/syslog/cpp/macros.h>
#include <zircon/status.h>
#include <iostream>
#include <virtio/balloon.h>
#include "src/virtualization/bin/guest/services.h"
namespace {
zx::status<fuchsia::virtualization::BalloonControllerSyncPtr> ConnectToBalloon(
sys::ComponentContext* context, uint32_t env_id, uint32_t cid) {
zx::status<fuchsia::virtualization::RealmSyncPtr> env_ptr = ConnectToEnvironment(context, env_id);
if (env_ptr.is_error()) {
return env_ptr.take_error();
}
fuchsia::virtualization::BalloonControllerSyncPtr balloon_controller;
zx_status_t status = env_ptr->ConnectToBalloon(cid, balloon_controller.NewRequest());
if (status != ZX_OK) {
std::cout << "Could not connect to balloon controller: " << zx_status_get_string(status)
<< ".\n";
return zx::error(status);
}
return zx::ok(std::move(balloon_controller));
}
} // namespace
zx_status_t handle_balloon(uint32_t env_id, uint32_t cid, uint32_t num_pages,
sys::ComponentContext* context) {
zx::status<fuchsia::virtualization::BalloonControllerSyncPtr> balloon_controller =
ConnectToBalloon(context, env_id, cid);
if (balloon_controller.is_error()) {
return balloon_controller.error_value();
}
zx_status_t status = balloon_controller->RequestNumPages(num_pages);
if (status != ZX_OK) {
std::cout << "Could not query balloon controller:" << zx_status_get_string(status) << ".\n";
return status;
}
std::cout << "Resizing the memory balloon to " << num_pages << " pages\n";
return ZX_OK;
}
static const char* tag_name(uint16_t tag) {
switch (tag) {
case VIRTIO_BALLOON_S_SWAP_IN:
return "swap-in: ";
case VIRTIO_BALLOON_S_SWAP_OUT:
return "swap-out: ";
case VIRTIO_BALLOON_S_MAJFLT:
return "major-faults: ";
case VIRTIO_BALLOON_S_MINFLT:
return "minor-faults: ";
case VIRTIO_BALLOON_S_MEMFREE:
return "free-memory: ";
case VIRTIO_BALLOON_S_MEMTOT:
return "total-memory: ";
case VIRTIO_BALLOON_S_AVAIL:
return "available-memory: ";
case VIRTIO_BALLOON_S_CACHES:
return "disk-caches: ";
case VIRTIO_BALLOON_S_HTLB_PGALLOC:
return "hugetlb-allocations: ";
case VIRTIO_BALLOON_S_HTLB_PGFAIL:
return "hugetlb-failures: ";
default:
return "unknown: ";
}
}
zx_status_t handle_balloon_stats(uint32_t env_id, uint32_t cid, sys::ComponentContext* context) {
// Connect to balloon controller.
zx::status<fuchsia::virtualization::BalloonControllerSyncPtr> balloon_controller =
ConnectToBalloon(context, env_id, cid);
if (balloon_controller.is_error()) {
return balloon_controller.error_value();
}
// Fetch the statistics.
zx_status_t status;
fidl::VectorPtr<fuchsia::virtualization::MemStat> mem_stats;
balloon_controller->GetMemStats(&status, &mem_stats);
if (status != ZX_OK) {
std::cerr << "Failed to get memory statistics " << status << '\n';
return status;
}
for (auto& mem_stat : *mem_stats) {
std::cout << tag_name(mem_stat.tag) << mem_stat.val << '\n';
}
return ZX_OK;
}