Tim Detwiler | 566cf25 | 2018-04-12 12:20:19 -0700 | [diff] [blame] | 1 | // Copyright 2018 The Fuchsia Authors. All rights reserved. |
| 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
| 5 | #include "garnet/bin/guest/mgr/guest_environment_impl.h" |
| 6 | |
| 7 | #include "lib/fxl/logging.h" |
| 8 | |
| 9 | namespace guestmgr { |
| 10 | |
Tim Detwiler | 566cf25 | 2018-04-12 12:20:19 -0700 | [diff] [blame] | 11 | GuestEnvironmentImpl::GuestEnvironmentImpl( |
Alhaad Gokhale | dbcca20 | 2018-06-01 10:51:01 -0700 | [diff] [blame] | 12 | uint32_t id, const std::string& label, |
| 13 | fuchsia::sys::StartupContext* context, |
Tim Detwiler | dd15a81 | 2018-05-17 16:25:51 -0700 | [diff] [blame] | 14 | fidl::InterfaceRequest<fuchsia::guest::GuestEnvironment> request) |
Tim Detwiler | 8c437da | 2018-05-08 23:11:34 -0700 | [diff] [blame] | 15 | : id_(id), |
| 16 | label_(label), |
| 17 | context_(context), |
Tim Detwiler | dd15a81 | 2018-05-17 16:25:51 -0700 | [diff] [blame] | 18 | host_socket_endpoint_(fuchsia::guest::kHostCid) { |
Alhaad Gokhale | 34d9e9e | 2018-05-24 14:41:46 -0700 | [diff] [blame] | 19 | CreateEnvironment(label); |
Tim Detwiler | 212fbf6 | 2018-05-05 13:19:52 -0700 | [diff] [blame] | 20 | AddBinding(std::move(request)); |
Tim Detwiler | 8c437da | 2018-05-08 23:11:34 -0700 | [diff] [blame] | 21 | FXL_CHECK(socket_server_.AddEndpoint(&host_socket_endpoint_) == ZX_OK); |
Tim Detwiler | 566cf25 | 2018-04-12 12:20:19 -0700 | [diff] [blame] | 22 | } |
Tim Detwiler | 212fbf6 | 2018-05-05 13:19:52 -0700 | [diff] [blame] | 23 | |
Tim Detwiler | 566cf25 | 2018-04-12 12:20:19 -0700 | [diff] [blame] | 24 | GuestEnvironmentImpl::~GuestEnvironmentImpl() = default; |
| 25 | |
Tim Detwiler | 212fbf6 | 2018-05-05 13:19:52 -0700 | [diff] [blame] | 26 | void GuestEnvironmentImpl::AddBinding( |
| 27 | fidl::InterfaceRequest<GuestEnvironment> request) { |
| 28 | bindings_.AddBinding(this, std::move(request)); |
Tim Detwiler | 566cf25 | 2018-04-12 12:20:19 -0700 | [diff] [blame] | 29 | } |
| 30 | |
Tim Detwiler | 2c4510a | 2018-05-16 11:05:56 -0700 | [diff] [blame] | 31 | void GuestEnvironmentImpl::set_unbound_handler(std::function<void()> handler) { |
| 32 | bindings_.set_empty_set_handler(std::move(handler)); |
| 33 | } |
| 34 | |
Tim Detwiler | 566cf25 | 2018-04-12 12:20:19 -0700 | [diff] [blame] | 35 | void GuestEnvironmentImpl::LaunchGuest( |
Tim Detwiler | dd15a81 | 2018-05-17 16:25:51 -0700 | [diff] [blame] | 36 | fuchsia::guest::GuestLaunchInfo launch_info, |
| 37 | fidl::InterfaceRequest<fuchsia::guest::GuestController> controller, |
Tim Detwiler | fa560b3 | 2018-05-03 19:32:51 -0700 | [diff] [blame] | 38 | LaunchGuestCallback callback) { |
Ankur Mittal | f36f68e | 2018-05-29 14:21:08 -0700 | [diff] [blame] | 39 | fuchsia::sys::Services guest_services; |
| 40 | fuchsia::sys::ComponentControllerPtr guest_component_controller; |
| 41 | fuchsia::sys::LaunchInfo guest_launch_info; |
Tim Detwiler | 566cf25 | 2018-04-12 12:20:19 -0700 | [diff] [blame] | 42 | guest_launch_info.url = launch_info.url; |
| 43 | guest_launch_info.arguments = std::move(launch_info.vmm_args); |
| 44 | guest_launch_info.directory_request = guest_services.NewRequest(); |
| 45 | guest_launch_info.flat_namespace = std::move(launch_info.flat_namespace); |
Alhaad Gokhale | dbcca20 | 2018-06-01 10:51:01 -0700 | [diff] [blame] | 46 | launcher_->CreateComponent(std::move(guest_launch_info), |
| 47 | guest_component_controller.NewRequest()); |
Tim Detwiler | 566cf25 | 2018-04-12 12:20:19 -0700 | [diff] [blame] | 48 | |
Tim Detwiler | fa560b3 | 2018-05-03 19:32:51 -0700 | [diff] [blame] | 49 | // Setup Socket Endpoint |
Tim Detwiler | fa560b3 | 2018-05-03 19:32:51 -0700 | [diff] [blame] | 50 | uint32_t cid = next_guest_cid_++; |
Tim Detwiler | 8c437da | 2018-05-08 23:11:34 -0700 | [diff] [blame] | 51 | auto vsock_endpoint = std::make_unique<RemoteVsockEndpoint>(cid); |
| 52 | zx_status_t status = socket_server_.AddEndpoint(vsock_endpoint.get()); |
Tim Detwiler | fa560b3 | 2018-05-03 19:32:51 -0700 | [diff] [blame] | 53 | if (status != ZX_OK) { |
| 54 | FXL_LOG(ERROR) << "Failed to allocate socked endpoint on CID " << cid |
| 55 | << ": " << status; |
Tim Detwiler | dd15a81 | 2018-05-17 16:25:51 -0700 | [diff] [blame] | 56 | callback(fuchsia::guest::GuestInfo()); |
Tim Detwiler | fa560b3 | 2018-05-03 19:32:51 -0700 | [diff] [blame] | 57 | return; |
| 58 | } |
Tim Detwiler | dd15a81 | 2018-05-17 16:25:51 -0700 | [diff] [blame] | 59 | fuchsia::guest::SocketEndpointPtr remote_endpoint; |
Tim Detwiler | fa560b3 | 2018-05-03 19:32:51 -0700 | [diff] [blame] | 60 | guest_services.ConnectToService(remote_endpoint.NewRequest()); |
| 61 | vsock_endpoint->BindSocketEndpoint(std::move(remote_endpoint)); |
| 62 | |
Alhaad Gokhale | 2165f89 | 2018-05-25 11:53:30 -0700 | [diff] [blame] | 63 | guest_component_controller.set_error_handler( |
| 64 | [this, cid] { guests_.erase(cid); }); |
Tim Detwiler | 566cf25 | 2018-04-12 12:20:19 -0700 | [diff] [blame] | 65 | auto& label = launch_info.label ? launch_info.label : launch_info.url; |
Tim Detwiler | fa560b3 | 2018-05-03 19:32:51 -0700 | [diff] [blame] | 66 | auto holder = std::make_unique<GuestHolder>( |
| 67 | cid, label, std::move(vsock_endpoint), std::move(guest_services), |
Alhaad Gokhale | 2165f89 | 2018-05-25 11:53:30 -0700 | [diff] [blame] | 68 | std::move(guest_component_controller)); |
Tim Detwiler | 212fbf6 | 2018-05-05 13:19:52 -0700 | [diff] [blame] | 69 | holder->AddBinding(std::move(controller)); |
Tim Detwiler | fa560b3 | 2018-05-03 19:32:51 -0700 | [diff] [blame] | 70 | guests_.insert({cid, std::move(holder)}); |
| 71 | |
Tim Detwiler | dd15a81 | 2018-05-17 16:25:51 -0700 | [diff] [blame] | 72 | fuchsia::guest::GuestInfo info; |
Tim Detwiler | fa560b3 | 2018-05-03 19:32:51 -0700 | [diff] [blame] | 73 | info.cid = cid; |
| 74 | info.label = label; |
| 75 | callback(std::move(info)); |
Tim Detwiler | 566cf25 | 2018-04-12 12:20:19 -0700 | [diff] [blame] | 76 | } |
| 77 | |
Tim Detwiler | 8c437da | 2018-05-08 23:11:34 -0700 | [diff] [blame] | 78 | void GuestEnvironmentImpl::GetHostSocketEndpoint( |
Tim Detwiler | dd15a81 | 2018-05-17 16:25:51 -0700 | [diff] [blame] | 79 | fidl::InterfaceRequest<fuchsia::guest::ManagedSocketEndpoint> request) { |
Tim Detwiler | 8c437da | 2018-05-08 23:11:34 -0700 | [diff] [blame] | 80 | host_socket_endpoint_.AddBinding(std::move(request)); |
Tim Detwiler | 566cf25 | 2018-04-12 12:20:19 -0700 | [diff] [blame] | 81 | } |
| 82 | |
Tim Detwiler | dd15a81 | 2018-05-17 16:25:51 -0700 | [diff] [blame] | 83 | fidl::VectorPtr<fuchsia::guest::GuestInfo> GuestEnvironmentImpl::ListGuests() { |
| 84 | fidl::VectorPtr<fuchsia::guest::GuestInfo> guest_infos = |
| 85 | fidl::VectorPtr<fuchsia::guest::GuestInfo>::New(0); |
Tim Detwiler | 212fbf6 | 2018-05-05 13:19:52 -0700 | [diff] [blame] | 86 | for (const auto& it : guests_) { |
Tim Detwiler | dd15a81 | 2018-05-17 16:25:51 -0700 | [diff] [blame] | 87 | fuchsia::guest::GuestInfo guest_info; |
Tim Detwiler | fa560b3 | 2018-05-03 19:32:51 -0700 | [diff] [blame] | 88 | guest_info.cid = it.first; |
Tim Detwiler | 212fbf6 | 2018-05-05 13:19:52 -0700 | [diff] [blame] | 89 | guest_info.label = it.second->label(); |
| 90 | guest_infos.push_back(std::move(guest_info)); |
| 91 | } |
| 92 | return guest_infos; |
| 93 | } |
| 94 | |
| 95 | void GuestEnvironmentImpl::ListGuests(ListGuestsCallback callback) { |
| 96 | callback(ListGuests()); |
| 97 | } |
| 98 | |
| 99 | void GuestEnvironmentImpl::ConnectToGuest( |
Tim Detwiler | dd15a81 | 2018-05-17 16:25:51 -0700 | [diff] [blame] | 100 | uint32_t id, |
| 101 | fidl::InterfaceRequest<fuchsia::guest::GuestController> request) { |
Tim Detwiler | 212fbf6 | 2018-05-05 13:19:52 -0700 | [diff] [blame] | 102 | const auto& it = guests_.find(id); |
| 103 | if (it == guests_.end()) { |
| 104 | return; |
| 105 | } |
| 106 | it->second->AddBinding(std::move(request)); |
| 107 | } |
| 108 | |
Alhaad Gokhale | 34d9e9e | 2018-05-24 14:41:46 -0700 | [diff] [blame] | 109 | void GuestEnvironmentImpl::CreateEnvironment(const std::string& label) { |
Tim Detwiler | 566cf25 | 2018-04-12 12:20:19 -0700 | [diff] [blame] | 110 | context_->environment()->CreateNestedEnvironment( |
| 111 | service_provider_bridge_.OpenAsDirectory(), env_.NewRequest(), |
| 112 | env_controller_.NewRequest(), label); |
Alhaad Gokhale | dbcca20 | 2018-06-01 10:51:01 -0700 | [diff] [blame] | 113 | env_->GetLauncher(launcher_.NewRequest()); |
Tim Detwiler | 566cf25 | 2018-04-12 12:20:19 -0700 | [diff] [blame] | 114 | zx::channel h1, h2; |
| 115 | if (zx::channel::create(0, &h1, &h2) < 0) { |
| 116 | return; |
| 117 | } |
| 118 | context_->environment()->GetDirectory(std::move(h1)); |
| 119 | service_provider_bridge_.set_backing_dir(std::move(h2)); |
| 120 | } |
| 121 | |
| 122 | } // namespace guestmgr |