1 // Copyright 2022 The ChromiumOS Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #[cfg(feature = "gpu")]
6 pub(crate) mod gpu;
7
8 use std::io::Result;
9 use std::mem::size_of;
10 use std::path::Path;
11
12 use base::error;
13 use base::named_pipes::BlockingMode;
14 use base::named_pipes::FramingMode;
15 use base::named_pipes::MultiPartMessagePipe;
16 use base::named_pipes::OverlappedWrapper;
17 use base::Error;
18 use base::Event;
19 use base::PipeTube;
20 use hypervisor::MemCacheType;
21 use hypervisor::MemSlot;
22 use hypervisor::Vm;
23 use resources::Alloc;
24 use resources::SystemAllocator;
25
26 use crate::client::HandleRequestResult;
27 use crate::VmRequest;
28
29 pub const SERVICE_MESSAGE_HEADER_SIZE: usize = size_of::<u32>();
30
handle_request<T: AsRef<Path> + std::fmt::Debug>( request: &VmRequest, socket_path: T, ) -> HandleRequestResult31 pub fn handle_request<T: AsRef<Path> + std::fmt::Debug>(
32 request: &VmRequest,
33 socket_path: T,
34 ) -> HandleRequestResult {
35 match base::named_pipes::create_client_pipe(
36 socket_path
37 .as_ref()
38 .to_str()
39 .expect("socket path must be a string"),
40 &FramingMode::Message,
41 &BlockingMode::Wait,
42 /* overlapped= */ false,
43 ) {
44 Ok(pipe) => {
45 let tube = PipeTube::from(pipe, None);
46 if let Err(e) = tube.send(request) {
47 error!(
48 "failed to send request to pipe at '{:?}': {}",
49 socket_path, e
50 );
51 return Err(());
52 }
53 match tube.recv() {
54 Ok(response) => Ok(response),
55 Err(e) => {
56 error!(
57 "failed to recv response from pipe at '{:?}': {}",
58 socket_path, e
59 );
60 Err(())
61 }
62 }
63 }
64 Err(e) => {
65 error!("failed to connect to socket at '{:?}': {}", socket_path, e);
66 Err(())
67 }
68 }
69 }
70
71 /// Send the size header first and then the protbuf message.
72 ///
73 /// A helper function to keep communication with service consistent across crosvm code.
send_service_message( connection: &MultiPartMessagePipe, message: &[u8], overlapped_wrapper: &mut OverlappedWrapper, ) -> Result<()>74 pub fn send_service_message(
75 connection: &MultiPartMessagePipe,
76 message: &[u8],
77 overlapped_wrapper: &mut OverlappedWrapper,
78 ) -> Result<()> {
79 let size_in_bytes = message.len() as u32;
80 connection.write_overlapped_blocking_message(
81 &size_in_bytes.to_be_bytes(),
82 message,
83 overlapped_wrapper,
84 )
85 }
86
87 /// Read and wait for the header to arrive in the named pipe. Once header is available, use the
88 /// size to fetch the message.
89 ///
90 /// A helper function to keep communication with service consistent across crosvm code.
recv_service_message( connection: &MultiPartMessagePipe, overlapped_wrapper: &mut OverlappedWrapper, exit_event: &Event, ) -> Result<Vec<u8>>91 pub fn recv_service_message(
92 connection: &MultiPartMessagePipe,
93 overlapped_wrapper: &mut OverlappedWrapper,
94 exit_event: &Event,
95 ) -> Result<Vec<u8>> {
96 connection.read_overlapped_blocking_message(
97 SERVICE_MESSAGE_HEADER_SIZE,
98 |bytes: &[u8]| {
99 assert_eq!(bytes.len(), SERVICE_MESSAGE_HEADER_SIZE);
100 u32::from_be_bytes(bytes.try_into().expect("failed to get array from slice")) as usize
101 },
102 overlapped_wrapper,
103 exit_event,
104 )
105 }
106
should_prepare_memory_region() -> bool107 pub fn should_prepare_memory_region() -> bool {
108 false
109 }
110
prepare_shared_memory_region( _vm: &mut dyn Vm, _allocator: &mut SystemAllocator, _alloc: Alloc, _cache: MemCacheType, ) -> std::result::Result<(u64, MemSlot), Error>111 pub fn prepare_shared_memory_region(
112 _vm: &mut dyn Vm,
113 _allocator: &mut SystemAllocator,
114 _alloc: Alloc,
115 _cache: MemCacheType,
116 ) -> std::result::Result<(u64, MemSlot), Error> {
117 unimplemented!()
118 }
119