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 use std::time::Duration;
12
13 use base::error;
14 use base::named_pipes::BlockingMode;
15 use base::named_pipes::FramingMode;
16 use base::named_pipes::MultiPartMessagePipe;
17 use base::named_pipes::OverlappedWrapper;
18 use base::Error;
19 use base::Event;
20 use base::PipeTube;
21 use hypervisor::MemCacheType;
22 use hypervisor::Vm;
23 use resources::Alloc;
24 use resources::SystemAllocator;
25
26 use crate::client::HandleRequestResult;
27 use crate::VmMappedMemoryRegion;
28 use crate::VmRequest;
29
30 pub const SERVICE_MESSAGE_HEADER_SIZE: usize = size_of::<u32>();
31
handle_request<T: AsRef<Path> + std::fmt::Debug>( request: &VmRequest, socket_path: T, ) -> HandleRequestResult32 pub fn handle_request<T: AsRef<Path> + std::fmt::Debug>(
33 request: &VmRequest,
34 socket_path: T,
35 ) -> HandleRequestResult {
36 match base::named_pipes::create_client_pipe(
37 socket_path
38 .as_ref()
39 .to_str()
40 .expect("socket path must be a string"),
41 &FramingMode::Message,
42 &BlockingMode::Wait,
43 /* overlapped= */ false,
44 ) {
45 Ok(pipe) => {
46 let tube = PipeTube::from(pipe, None);
47 if let Err(e) = tube.send(request) {
48 error!(
49 "failed to send request to pipe at '{:?}': {}",
50 socket_path, e
51 );
52 return Err(());
53 }
54 match tube.recv() {
55 Ok(response) => Ok(response),
56 Err(e) => {
57 error!(
58 "failed to recv response from pipe at '{:?}': {}",
59 socket_path, e
60 );
61 Err(())
62 }
63 }
64 }
65 Err(e) => {
66 error!("failed to connect to socket at '{:?}': {}", socket_path, e);
67 Err(())
68 }
69 }
70 }
71
handle_request_with_timeout<T: AsRef<Path> + std::fmt::Debug>( request: &VmRequest, socket_path: T, timeout: Option<Duration>, ) -> HandleRequestResult72 pub fn handle_request_with_timeout<T: AsRef<Path> + std::fmt::Debug>(
73 request: &VmRequest,
74 socket_path: T,
75 timeout: Option<Duration>,
76 ) -> HandleRequestResult {
77 if timeout.is_none() {
78 handle_request(request, socket_path)
79 } else {
80 error!("handle_request_with_timeout() not implemented for Windows");
81 Err(())
82 }
83 }
84
85 /// Send the size header first and then the protbuf message.
86 ///
87 /// A helper function to keep communication with service consistent across crosvm code.
send_service_message( connection: &MultiPartMessagePipe, message: &[u8], overlapped_wrapper: &mut OverlappedWrapper, ) -> Result<()>88 pub fn send_service_message(
89 connection: &MultiPartMessagePipe,
90 message: &[u8],
91 overlapped_wrapper: &mut OverlappedWrapper,
92 ) -> Result<()> {
93 let size_in_bytes = message.len() as u32;
94 connection.write_overlapped_blocking_message(
95 &size_in_bytes.to_be_bytes(),
96 message,
97 overlapped_wrapper,
98 )
99 }
100
101 /// Read and wait for the header to arrive in the named pipe. Once header is available, use the
102 /// size to fetch the message.
103 ///
104 /// 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>>105 pub fn recv_service_message(
106 connection: &MultiPartMessagePipe,
107 overlapped_wrapper: &mut OverlappedWrapper,
108 exit_event: &Event,
109 ) -> Result<Vec<u8>> {
110 connection.read_overlapped_blocking_message(
111 SERVICE_MESSAGE_HEADER_SIZE,
112 |bytes: &[u8]| {
113 assert_eq!(bytes.len(), SERVICE_MESSAGE_HEADER_SIZE);
114 u32::from_be_bytes(bytes.try_into().expect("failed to get array from slice")) as usize
115 },
116 overlapped_wrapper,
117 exit_event,
118 )
119 }
120
should_prepare_memory_region() -> bool121 pub fn should_prepare_memory_region() -> bool {
122 false
123 }
124
prepare_shared_memory_region( _vm: &mut dyn Vm, _allocator: &mut SystemAllocator, _alloc: Alloc, _cache: MemCacheType, ) -> std::result::Result<VmMappedMemoryRegion, Error>125 pub fn prepare_shared_memory_region(
126 _vm: &mut dyn Vm,
127 _allocator: &mut SystemAllocator,
128 _alloc: Alloc,
129 _cache: MemCacheType,
130 ) -> std::result::Result<VmMappedMemoryRegion, Error> {
131 unimplemented!()
132 }
133
134 /// State of a specific audio device on boot.
135 pub struct InitialAudioSessionState {
136 // Uniquely identify an audio device. In ALSA terminology, this is the card_index as opposed to
137 // a device index.
138 pub card_index: usize,
139 // GUID assigned to the device's IAudioClient
140 pub audio_client_guid: String,
141 }
142