blob: c52bf77e2a11a38d7a931595a921dd2da8576987 [file] [log] [blame]
// Copyright 2025 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 <fidl/fuchsia.virtualization.guest.interaction/cpp/fidl.h>
#include <fidl/fuchsia.virtualization/cpp/fidl.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/component/incoming/cpp/protocol.h>
#include <lib/component/outgoing/cpp/outgoing_directory.h>
#include <lib/syslog/cpp/macros.h>
#include "src/virtualization/lib/guest_interaction/interactive_debian_guest/interactive_debian_guest_impl.h"
using DebianGuestManager = fuchsia_virtualization::DebianGuestManager;
using InteractiveDebianGuest = fuchsia_virtualization_guest_interaction::InteractiveDebianGuest;
int main() {
FX_LOGS(INFO) << "Bootstrapping the InteractiveDebianGuest component.";
async::Loop loop(&kAsyncLoopConfigNeverAttachToThread);
async_dispatcher_t* dispatcher = loop.dispatcher();
component::OutgoingDirectory outgoing = component::OutgoingDirectory(dispatcher);
// Spin up and connect to the GuestManager
zx::result result = outgoing.ServeFromStartupInfo();
FX_CHECK(result.is_ok()) << std::format("Failed to serve outgoing directory with status: {}",
result.status_string());
zx::result guest_manager_client_end = component::Connect<DebianGuestManager>();
FX_CHECK(guest_manager_client_end.is_ok())
<< std::format("Failed to connect to the DebianGuestManager protocol with status: {}",
guest_manager_client_end.status_string());
fidl::SyncClient<DebianGuestManager> guest_manager_sync =
fidl::SyncClient<DebianGuestManager>({std::move(*guest_manager_client_end)});
// Create and serve the InteractiveDebianGuest
bool already_bound = false;
interactive_debian_guest::InteractiveDebianGuestImpl interactive_debian_guest_impl(
loop, std::move(guest_manager_sync));
const auto incoming_request_handler = [dispatcher, &interactive_debian_guest_impl,
&already_bound](
fidl::ServerEnd<InteractiveDebianGuest> server_end) {
FX_LOGS(INFO) << "Incoming connection for "
<< fidl::DiscoverableProtocolName<InteractiveDebianGuest>;
if (already_bound) {
FX_LOGS(ERROR)
<< "The interactive Debian guest cannot gracefully handle multiple requests, and is already bound. Closing the incoming request.";
server_end.Close(ZX_ERR_ALREADY_BOUND);
return;
}
fidl::BindServer(dispatcher, std::move(server_end), &interactive_debian_guest_impl);
already_bound = true;
};
result = outgoing.AddUnmanagedProtocol<InteractiveDebianGuest>(incoming_request_handler);
FX_CHECK(result.is_ok()) << std::format(
"Failed to register InteractiveDebianGuest protocol with status: {}", result.status_string());
FX_LOGS(INFO) << "Running the InteractiveDebianGuest component.";
return loop.Run();
}