blob: 2c3dd2d40c7a77ba6205c503cd32027ac468b6fd [file] [log] [blame]
// Copyright 2022 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.
#ifndef SRC_VIRTUALIZATION_BIN_GUEST_MANAGER_GUEST_MANAGER_H_
#define SRC_VIRTUALIZATION_BIN_GUEST_MANAGER_GUEST_MANAGER_H_
#include <fuchsia/virtualization/cpp/fidl.h>
#include <lib/fidl/cpp/binding_set.h>
#include <lib/sys/cpp/component_context.h>
#include <lib/zx/result.h>
#include <zircon/types.h>
#include "src/virtualization/bin/guest_manager/memory_pressure_handler.h"
#include "src/virtualization/lib/guest_config/guest_config.h"
enum class GuestNetworkState {
// There are at least enough virtual device interfaces to match the guest configuration, and
// if there is a bridged configuration, there's at least one bridged interface. This doesn't
// guarantee working networking, but means that the system state is likely correct.
OK = 0,
// This guest wasn't started with a network device, so no networking is expected.
NO_NETWORK_DEVICE = 1,
// Failed to query network interfaces. Note that if there's no guest network device, ability to
// query network interfaces is irrelevant.
FAILED_TO_QUERY = 2,
// Host doesn't have a WLAN or ethernet interface, so there's probably no guest networking.
NO_HOST_NETWORKING = 3,
// There's at least one missing virtual interface that was expected to be present. Check
// virtio-net device logs for a failure.
MISSING_VIRTUAL_INTERFACES = 4,
// An interface is bridged, there's an ethernet interface to bridge against, but the
// bridge hasn't been created yet. This might be a transient issue while the bridge is created.
NO_BRIDGE_CREATED = 5,
// An interface is bridged, and there's no ethernet to bridge against, but the host is
// connected to WLAN. This is a common user misconfiguration.
ATTEMPTED_TO_BRIDGE_WITH_WLAN = 6,
};
class GuestManager : public fuchsia::virtualization::GuestManager {
public:
GuestManager(async_dispatcher_t* dispatcher, sys::ComponentContext* context,
std::string config_pkg_dir_path, std::string config_path);
GuestManager(async_dispatcher_t* dispatcher, sys::ComponentContext* context)
: GuestManager(dispatcher, context, "/guest_pkg/", "data/guest.cfg") {}
// |fuchsia::virtualization::GuestManager|
void Launch(fuchsia::virtualization::GuestConfig user_config,
fidl::InterfaceRequest<fuchsia::virtualization::Guest> controller,
LaunchCallback callback) override;
void ForceShutdown(ForceShutdownCallback callback) override;
void Connect(fidl::InterfaceRequest<fuchsia::virtualization::Guest> controller,
ConnectCallback) override;
void GetInfo(GetInfoCallback callback) override;
// Store a subset of the configuration. This can be queried while the guest is running using
// the GuestManager::GetInfo FIDL message.
void SnapshotConfig(const fuchsia::virtualization::GuestConfig& config);
// Attempt to query the guest network state by iterating over the host network interfaces.
GuestNetworkState QueryGuestNetworkState();
static std::string GuestNetworkStateToStringExplanation(GuestNetworkState state);
// Check for suspected problems with a running guest.
std::vector<std::string> CheckForProblems();
// Returns true if the guest was started, but hasn't stopped.
bool is_guest_started() const;
protected:
virtual fit::result<::fuchsia::virtualization::GuestManagerError,
::fuchsia::virtualization::GuestConfig>
GetDefaultGuestConfig();
virtual void OnGuestLaunched() {}
virtual void OnGuestStopped() {}
private:
void HandleCreateResult(::fuchsia::virtualization::GuestLifecycle_Create_Result result,
bool balloon_enabled, LaunchCallback callback);
void HandleRunResult(::fuchsia::virtualization::GuestLifecycle_Run_Result result);
void HandleGuestStopped(fit::result<::fuchsia::virtualization::GuestError> err);
async_dispatcher_t* dispatcher_;
sys::ComponentContext* context_;
fidl::BindingSet<fuchsia::virtualization::GuestManager> manager_bindings_;
std::string config_pkg_dir_path_;
std::string config_path_;
// The VMM lifecycle control channel. If closed, this will terminate the VMM component.
::fuchsia::virtualization::GuestLifecyclePtr lifecycle_;
// Cached error reported by the VMM upon stopping if not stopped due to a clean shutdown.
std::optional<fuchsia::virtualization::GuestError> last_error_;
// Used to calculate the guest's uptime for guest info reporting.
zx::time start_time_ = zx::time::infinite_past();
zx::time stop_time_ = zx::time::infinite_past();
// Snapshot of some of the configuration settings used to start this guest. This is
// informational only, and sent in response to a GetInfo call.
fuchsia::virtualization::GuestDescriptor guest_descriptor_;
// Current state of the guest.
fuchsia::virtualization::GuestStatus state_ = fuchsia::virtualization::GuestStatus::NOT_STARTED;
// Inflates / deflates the guest balloon in response to the host memory pressure events
std::unique_ptr<MemoryPressureHandler> memory_pressure_handler_;
// Callbacks that should be triggered when the guest enters a STOPPED state. The guest shutting
// down is an asynchronous process, so multiple penidng callbacks can be registered while the
// guest spins down.
std::vector<ForceShutdownCallback> pending_force_shutdowns_;
};
#endif // SRC_VIRTUALIZATION_BIN_GUEST_MANAGER_GUEST_MANAGER_H_