// Copyright 2017 The Chromium OS Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. use devices::virtio::remote::RemotePciCapability; use devices::virtio::virtualized::{Request, Response}; use devices::virtio::{ InterruptProxy, InterruptProxyEvent, Params, VirtioDevice, VirtioDeviceNew, Wl, }; use msg_socket::MsgSocket; use std::collections::BTreeMap; use std::fs::remove_file; use std::io::prelude::*; use std::io::stdout; use std::os::unix::prelude::*; use std::process; use sys_util::{error, net::UnixSeqpacketListener, GuestMemory}; use vm_control::MaybeOwnedFd; #[cfg(any(target_arch = "arm", target_arch = "aarch64"))] pub use aarch64::arch_memory_regions; #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] pub use x86_64::arch_memory_regions; type Socket = msg_socket2::Socket; fn main() { eprintln!("hello world"); // Create and display the socket. let mut path = std::env::var_os("XDG_RUNTIME_DIR").expect("XDG_RUNTIME_DIR missing"); path.push("/crosvm_wl-"); path.push(process::id().to_string()); path.push(".sock"); let _ = remove_file(&path); let server = UnixSeqpacketListener::bind(&path).expect("failed to create control socket"); match stdout().write_all(path.as_bytes()) { Ok(()) => println!(), Err(e) => eprintln!("{}", e), } // Receive connection from crosvm. let conn = server.accept().expect("accept failed"); let msg_socket: Socket = msg_socket2::Socket::new(conn); let (memory_params, ext_socket) = match msg_socket.recv() { Ok(Request::Create { memory_params, ext_socket, }) => (memory_params, ext_socket), Ok(msg) => { panic!("received unexpected message: {:?}", msg); } Err(e) => { panic!("recv error: {}", e); } }; let mut wayland_paths = BTreeMap::new(); wayland_paths.insert("".into(), "/run/user/1000/wayland-0".into()); let mut wl = Wl::new(Params { wayland_paths, vm_socket: MsgSocket::new(ext_socket), resource_bridge: None, }) .unwrap(); loop { match dbg!(msg_socket.recv()) { Ok(Request::DebugLabel) => { let result = wl.debug_label(); if let Err(e) = msg_socket.send(Response::DebugLabel(result)) { panic!("responding to DebugLabel failed: {}", e); } } Ok(Request::DeviceType) => { let result = wl.device_type(); if let Err(e) = msg_socket.send(Response::DeviceType(result)) { panic!("responding to DeviceType failed: {}", e); } } Ok(Request::QueueMaxSizes) => { let result = wl.queue_max_sizes(); if let Err(e) = msg_socket.send(dbg!(Response::QueueMaxSizes(result))) { panic!("responding to QueueMaxSizes failed: {}", e); } } Ok(Request::Features) => { let result = wl.features(); if let Err(e) = msg_socket.send(Response::Features(result)) { panic!("responding to Features failed: {}", e); } } Ok(Request::AckFeatures(value)) => wl.ack_features(value), Ok(Request::ReadConfig { offset, len }) => { let mut data = vec![0; len]; wl.read_config(offset, &mut data); if let Err(e) = msg_socket.send(Response::ReadConfig(data)) { panic!("responding to ReadConfig failed: {}", e); } } Ok(Request::WriteConfig { offset, ref data }) => wl.write_config(offset, data), Ok(Request::Activate { shm, interrupt, interrupt_resample_evt, queues, queue_evts, }) => { let shm = shm.owned(); let regions = arch_memory_regions(memory_params); let mem = GuestMemory::with_memfd(®ions, shm).expect("GuestMemory::with_memfd failed"); let interrupt: MsgSocket = MsgSocket::new(interrupt.owned()); wl.activate( mem, Box::new(InterruptProxy::new( interrupt, interrupt_resample_evt.owned(), )), queues, queue_evts.into_iter().map(MaybeOwnedFd::owned).collect(), ); println!("activated Wl"); } Ok(Request::Reset) => { let result = wl.reset(); if let Err(e) = msg_socket.send(dbg!(Response::Reset(result))) { panic!("responding to Reset failed: {}", e); } } Ok(Request::GetDeviceBars(address)) => { let result = wl.get_device_bars(address); if let Err(e) = msg_socket.send(Response::GetDeviceBars(result)) { panic!("responding to GetDeviceBars failed: {}", e); } } Ok(Request::GetDeviceCaps) => { let result = wl .get_device_caps() .into_iter() .map(|c| RemotePciCapability::from(&*c)) .collect(); if let Err(e) = msg_socket.send(Response::GetDeviceCaps(result)) { panic!("responding to GetDeviceCaps failed: {}", e); } } Ok(Request::Kill) => { // Will block until worker shuts down. drop(wl); if let Err(e) = msg_socket.send(Response::Kill) { error!("responding to Kill failed: {}", e); } break; } Ok(msg @ Request::Create { .. }) => panic!("unexpected message {:?}", msg), Err(e) => panic!("recv failed: {}", e), } } }