1use std::cmp;
6use std::io;
7use std::io::Write;
8use std::iter::FromIterator;
9use std::marker::PhantomData;
10use std::mem::size_of;
11use std::mem::MaybeUninit;
12use std::ptr::copy_nonoverlapping;
13use std::sync::Arc;
14
15use anyhow::Context;
16use base::FileReadWriteAtVolatile;
17use base::FileReadWriteVolatile;
18use base::VolatileSlice;
19use cros_async::IoOptions;
20use cros_async::MemRegion;
21use cros_async::MemRegionIter;
22use data_model::Le16;
23use data_model::Le32;
24use data_model::Le64;
25use disk::AsyncDisk;
26use smallvec::SmallVec;
27use vm_memory::GuestAddress;
28use vm_memory::GuestMemory;
29use zerocopy::FromBytes;
30use zerocopy::Immutable;
31use zerocopy::IntoBytes;
32use zerocopy::KnownLayout;
33
34use super::DescriptorChain;
35use crate::virtio::SplitDescriptorChain;
36
37struct DescriptorChainRegions {
38 regions: SmallVec<[MemRegion; 2]>,
39
40 current_region_index: usize,
42
43 current_region_offset: usize,
45
46 bytes_consumed: usize,
48}
49
50impl DescriptorChainRegions {
51 fn new(regions: SmallVec<[MemRegion; 2]>) -> Self {
52 DescriptorChainRegions {
53 regions,
54 current_region_index: 0,
55 current_region_offset: 0,
56 bytes_consumed: 0,
57 }
58 }
59
60 fn available_bytes(&self) -> usize {
61 self.get_remaining_regions()
64 .fold(0usize, |count, region| count + region.len)
65 }
66
67 fn bytes_consumed(&self) -> usize {
68 self.bytes_consumed
69 }
70
71 fn get_remaining_regions(&self) -> MemRegionIter {
76 MemRegionIter::new(&self.regions[self.current_region_index..])
77 .skip_bytes(self.current_region_offset)
78 }
79
80 fn get_remaining_regions_with_count(&self, count: usize) -> MemRegionIter {
85 MemRegionIter::new(&self.regions[self.current_region_index..])
86 .skip_bytes(self.current_region_offset)
87 .take_bytes(count)
88 }
89
90 fn get_remaining<'mem>(&self, mem: &'mem GuestMemory) -> SmallVec<[VolatileSlice<'mem>; 16]> {
95 self.get_remaining_regions()
96 .filter_map(|region| {
97 mem.get_slice_at_addr(GuestAddress(region.offset), region.len)
98 .ok()
99 })
100 .collect()
101 }
102
103 fn get_remaining_with_count<'mem>(
106 &self,
107 mem: &'mem GuestMemory,
108 count: usize,
109 ) -> SmallVec<[VolatileSlice<'mem>; 16]> {
110 self.get_remaining_regions_with_count(count)
111 .filter_map(|region| {
112 mem.get_slice_at_addr(GuestAddress(region.offset), region.len)
113 .ok()
114 })
115 .collect()
116 }
117
118 fn consume(&mut self, mut count: usize) {
121 while let Some(region) = self.regions.get(self.current_region_index) {
122 let region_remaining = region.len - self.current_region_offset;
123 if count < region_remaining {
124 self.current_region_offset += count;
128 self.bytes_consumed += count;
129 return;
130 }
131
132 self.current_region_index += 1;
134 self.current_region_offset = 0;
135
136 self.bytes_consumed += region_remaining;
137 count -= region_remaining;
138 }
139 }
140
141 fn split_at(&mut self, offset: usize) -> DescriptorChainRegions {
142 let mut other = DescriptorChainRegions {
143 regions: self.regions.clone(),
144 current_region_index: self.current_region_index,
145 current_region_offset: self.current_region_offset,
146 bytes_consumed: self.bytes_consumed,
147 };
148 other.consume(offset);
149 other.bytes_consumed = 0;
150
151 let mut rem = offset;
152 let mut end = self.current_region_index;
153 for region in &mut self.regions[self.current_region_index..] {
154 if rem <= region.len {
155 region.len = rem;
156 break;
157 }
158
159 end += 1;
160 rem -= region.len;
161 }
162
163 self.regions.truncate(end + 1);
164
165 other
166 }
167}
168
169pub struct Reader {
177 mem: GuestMemory,
178 regions: DescriptorChainRegions,
179}
180
181pub struct ReaderIterator<'a, T: FromBytes> {
183 reader: &'a mut Reader,
184 phantom: PhantomData<T>,
185}
186
187impl<T: FromBytes> Iterator for ReaderIterator<'_, T> {
188 type Item = io::Result<T>;
189
190 fn next(&mut self) -> Option<io::Result<T>> {
191 if self.reader.available_bytes() == 0 {
192 None
193 } else {
194 Some(self.reader.read_obj())
195 }
196 }
197}
198
199impl Reader {
200 pub fn new_from_regions(
202 mem: &GuestMemory,
203 readable_regions: SmallVec<[MemRegion; 2]>,
204 ) -> Reader {
205 Reader {
206 mem: mem.clone(),
207 regions: DescriptorChainRegions::new(readable_regions),
208 }
209 }
210
211 pub fn peek_obj<T: FromBytes>(&self) -> io::Result<T> {
213 let mut obj = MaybeUninit::uninit();
214
215 let copied = unsafe {
217 copy_regions_to_mut_ptr(
218 &self.mem,
219 self.get_remaining_regions(),
220 obj.as_mut_ptr() as *mut u8,
221 size_of::<T>(),
222 )?
223 };
224 if copied != size_of::<T>() {
225 return Err(io::Error::from(io::ErrorKind::UnexpectedEof));
226 }
227
228 Ok(unsafe { obj.assume_init() })
231 }
232
233 pub fn read_obj<T: FromBytes>(&mut self) -> io::Result<T> {
235 let obj = self.peek_obj::<T>()?;
236 self.consume(size_of::<T>());
237 Ok(obj)
238 }
239
240 pub fn collect<C: FromIterator<io::Result<T>>, T: FromBytes>(&mut self) -> C {
244 self.iter().collect()
245 }
246
247 pub fn iter<T: FromBytes>(&mut self) -> ReaderIterator<T> {
251 ReaderIterator {
252 reader: self,
253 phantom: PhantomData,
254 }
255 }
256
257 pub fn read_to_volatile_slice(&mut self, slice: VolatileSlice) -> usize {
260 let mut read = 0usize;
261 let mut dst = slice;
262 for src in self.get_remaining() {
263 src.copy_to_volatile_slice(dst);
264 let copied = std::cmp::min(src.size(), dst.size());
265 read += copied;
266 dst = match dst.offset(copied) {
267 Ok(v) => v,
268 Err(_) => break, };
270 }
271 self.regions.consume(read);
272 read
273 }
274
275 pub fn read_to_cb<C: FnOnce(&[VolatileSlice]) -> usize>(
278 &mut self,
279 cb: C,
280 count: usize,
281 ) -> usize {
282 let iovs = self.regions.get_remaining_with_count(&self.mem, count);
283 let written = cb(&iovs[..]);
284 self.regions.consume(written);
285 written
286 }
287
288 pub fn read_to<F: FileReadWriteVolatile>(
293 &mut self,
294 mut dst: F,
295 count: usize,
296 ) -> io::Result<usize> {
297 let iovs = self.regions.get_remaining_with_count(&self.mem, count);
298 let written = dst.write_vectored_volatile(&iovs[..])?;
299 self.regions.consume(written);
300 Ok(written)
301 }
302
303 pub fn read_to_at<F: FileReadWriteAtVolatile>(
308 &mut self,
309 dst: &F,
310 count: usize,
311 off: u64,
312 ) -> io::Result<usize> {
313 let iovs = self.regions.get_remaining_with_count(&self.mem, count);
314 let written = dst.write_vectored_at_volatile(&iovs[..], off)?;
315 self.regions.consume(written);
316 Ok(written)
317 }
318
319 pub fn read_exact_to<F: FileReadWriteVolatile>(
322 &mut self,
323 mut dst: F,
324 mut count: usize,
325 ) -> io::Result<()> {
326 while count > 0 {
327 match self.read_to(&mut dst, count) {
328 Ok(0) => {
329 return Err(io::Error::new(
330 io::ErrorKind::UnexpectedEof,
331 "failed to fill whole buffer",
332 ))
333 }
334 Ok(n) => count -= n,
335 Err(ref e) if e.kind() == io::ErrorKind::Interrupted => {}
336 Err(e) => return Err(e),
337 }
338 }
339
340 Ok(())
341 }
342
343 pub fn read_exact_to_at<F: FileReadWriteAtVolatile>(
346 &mut self,
347 dst: &F,
348 mut count: usize,
349 mut off: u64,
350 ) -> io::Result<()> {
351 while count > 0 {
352 match self.read_to_at(dst, count, off) {
353 Ok(0) => {
354 return Err(io::Error::new(
355 io::ErrorKind::UnexpectedEof,
356 "failed to fill whole buffer",
357 ))
358 }
359 Ok(n) => {
360 count -= n;
361 off += n as u64;
362 }
363 Err(ref e) if e.kind() == io::ErrorKind::Interrupted => {}
364 Err(e) => return Err(e),
365 }
366 }
367
368 Ok(())
369 }
370
371 pub async fn read_to_at_fut<F: AsyncDisk + ?Sized>(
376 &mut self,
377 dst: &F,
378 count: usize,
379 off: u64,
380 options: IoOptions,
381 ) -> disk::Result<usize> {
382 let written = dst
383 .write_from_mem(
384 off,
385 Arc::new(self.mem.clone()),
386 self.regions.get_remaining_regions_with_count(count),
387 options,
388 )
389 .await?;
390 self.regions.consume(written);
391 Ok(written)
392 }
393
394 pub async fn read_exact_to_at_fut<F: AsyncDisk + ?Sized>(
397 &mut self,
398 dst: &F,
399 mut count: usize,
400 mut off: u64,
401 options: IoOptions,
402 ) -> disk::Result<()> {
403 while count > 0 {
404 let nread = self.read_to_at_fut(dst, count, off, options).await?;
405 if nread == 0 {
406 return Err(disk::Error::ReadingData(io::Error::new(
407 io::ErrorKind::UnexpectedEof,
408 "failed to write whole buffer",
409 )));
410 }
411 count -= nread;
412 off += nread as u64;
413 }
414
415 Ok(())
416 }
417
418 pub fn available_bytes(&self) -> usize {
421 self.regions.available_bytes()
422 }
423
424 pub fn bytes_read(&self) -> usize {
426 self.regions.bytes_consumed()
427 }
428
429 pub fn get_remaining_regions(&self) -> MemRegionIter {
430 self.regions.get_remaining_regions()
431 }
432
433 pub fn get_remaining(&self) -> SmallVec<[VolatileSlice; 16]> {
437 self.regions.get_remaining(&self.mem)
438 }
439
440 pub fn consume(&mut self, amt: usize) {
443 self.regions.consume(amt)
444 }
445
446 pub fn split_at(&mut self, offset: usize) -> Reader {
451 Reader {
452 mem: self.mem.clone(),
453 regions: self.regions.split_at(offset),
454 }
455 }
456}
457
458unsafe fn copy_regions_to_mut_ptr(
470 mem: &GuestMemory,
471 src: MemRegionIter,
472 dst: *mut u8,
473 size: usize,
474) -> io::Result<usize> {
475 let mut copied = 0;
476 for src_region in src {
477 if copied >= size {
478 break;
479 }
480
481 let remaining = size - copied;
482 let count = cmp::min(remaining, src_region.len);
483
484 let vslice = mem
485 .get_slice_at_addr(GuestAddress(src_region.offset), count)
486 .map_err(|_e| io::Error::from(io::ErrorKind::InvalidData))?;
487
488 unsafe {
491 copy_nonoverlapping(vslice.as_ptr(), dst.add(copied), count);
492 }
493
494 copied += count;
495 }
496
497 Ok(copied)
498}
499
500impl io::Read for Reader {
501 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
502 let total = unsafe {
504 copy_regions_to_mut_ptr(
505 &self.mem,
506 self.regions.get_remaining_regions(),
507 buf.as_mut_ptr(),
508 buf.len(),
509 )?
510 };
511 self.regions.consume(total);
512 Ok(total)
513 }
514}
515
516#[cfg(any(target_os = "android", target_os = "linux"))]
517impl fuse::Reader for Reader {}
518
519#[cfg(any(target_os = "android", target_os = "linux"))]
520impl fuse::filesystem::ZeroCopyReader for Reader {
521 fn read_to(&mut self, f: &mut std::fs::File, count: usize, off: u64) -> io::Result<usize> {
522 self.read_to_at(f, count, off)
523 }
524}
525
526pub struct Writer {
534 mem: GuestMemory,
535 regions: DescriptorChainRegions,
536}
537
538impl Writer {
539 pub fn new_from_regions(
541 mem: &GuestMemory,
542 writable_regions: SmallVec<[MemRegion; 2]>,
543 ) -> Writer {
544 Writer {
545 mem: mem.clone(),
546 regions: DescriptorChainRegions::new(writable_regions),
547 }
548 }
549
550 pub fn write_obj<T: Immutable + IntoBytes>(&mut self, val: T) -> io::Result<()> {
552 self.write_all(val.as_bytes())
553 }
554
555 pub fn write_iter<T: Immutable + IntoBytes, I: Iterator<Item = T>>(
560 &mut self,
561 mut iter: I,
562 ) -> io::Result<()> {
563 iter.try_for_each(|v| self.write_obj(v))
564 }
565
566 pub fn consume<T: Immutable + IntoBytes, C: IntoIterator<Item = T>>(
568 &mut self,
569 vals: C,
570 ) -> io::Result<()> {
571 self.write_iter(vals.into_iter())
572 }
573
574 pub fn available_bytes(&self) -> usize {
577 self.regions.available_bytes()
578 }
579
580 pub fn write_from_volatile_slice(&mut self, slice: VolatileSlice) -> usize {
583 let mut written = 0usize;
584 let mut src = slice;
585 for dst in self.get_remaining() {
586 src.copy_to_volatile_slice(dst);
587 let copied = std::cmp::min(src.size(), dst.size());
588 written += copied;
589 src = match src.offset(copied) {
590 Ok(v) => v,
591 Err(_) => break, };
593 }
594 self.regions.consume(written);
595 written
596 }
597
598 pub fn write_from<F: FileReadWriteVolatile>(
603 &mut self,
604 mut src: F,
605 count: usize,
606 ) -> io::Result<usize> {
607 let iovs = self.regions.get_remaining_with_count(&self.mem, count);
608 let read = src.read_vectored_volatile(&iovs[..])?;
609 self.regions.consume(read);
610 Ok(read)
611 }
612
613 pub fn write_from_at<F: FileReadWriteAtVolatile>(
618 &mut self,
619 src: &F,
620 count: usize,
621 off: u64,
622 ) -> io::Result<usize> {
623 let iovs = self.regions.get_remaining_with_count(&self.mem, count);
624 let read = src.read_vectored_at_volatile(&iovs[..], off)?;
625 self.regions.consume(read);
626 Ok(read)
627 }
628
629 pub fn write_all_from<F: FileReadWriteVolatile>(
630 &mut self,
631 mut src: F,
632 mut count: usize,
633 ) -> io::Result<()> {
634 while count > 0 {
635 match self.write_from(&mut src, count) {
636 Ok(0) => {
637 return Err(io::Error::new(
638 io::ErrorKind::WriteZero,
639 "failed to write whole buffer",
640 ))
641 }
642 Ok(n) => count -= n,
643 Err(ref e) if e.kind() == io::ErrorKind::Interrupted => {}
644 Err(e) => return Err(e),
645 }
646 }
647
648 Ok(())
649 }
650
651 pub fn write_all_from_at<F: FileReadWriteAtVolatile>(
652 &mut self,
653 src: &F,
654 mut count: usize,
655 mut off: u64,
656 ) -> io::Result<()> {
657 while count > 0 {
658 match self.write_from_at(src, count, off) {
659 Ok(0) => {
660 return Err(io::Error::new(
661 io::ErrorKind::WriteZero,
662 "failed to write whole buffer",
663 ))
664 }
665 Ok(n) => {
666 count -= n;
667 off += n as u64;
668 }
669 Err(ref e) if e.kind() == io::ErrorKind::Interrupted => {}
670 Err(e) => return Err(e),
671 }
672 }
673 Ok(())
674 }
675 pub async fn write_from_at_fut<F: AsyncDisk + ?Sized>(
680 &mut self,
681 src: &F,
682 count: usize,
683 off: u64,
684 options: IoOptions,
685 ) -> disk::Result<usize> {
686 let read = src
687 .read_to_mem(
688 off,
689 Arc::new(self.mem.clone()),
690 self.regions.get_remaining_regions_with_count(count),
691 options,
692 )
693 .await?;
694 self.regions.consume(read);
695 Ok(read)
696 }
697
698 pub async fn write_all_from_at_fut<F: AsyncDisk + ?Sized>(
699 &mut self,
700 src: &F,
701 mut count: usize,
702 mut off: u64,
703 options: IoOptions,
704 ) -> disk::Result<()> {
705 while count > 0 {
706 let nwritten = self.write_from_at_fut(src, count, off, options).await?;
707 if nwritten == 0 {
708 return Err(disk::Error::WritingData(io::Error::new(
709 io::ErrorKind::UnexpectedEof,
710 "failed to write whole buffer",
711 )));
712 }
713 count -= nwritten;
714 off += nwritten as u64;
715 }
716 Ok(())
717 }
718
719 pub fn bytes_written(&self) -> usize {
721 self.regions.bytes_consumed()
722 }
723
724 pub fn get_remaining_regions(&self) -> MemRegionIter {
725 self.regions.get_remaining_regions()
726 }
727
728 pub fn get_remaining(&self) -> SmallVec<[VolatileSlice; 16]> {
734 self.regions.get_remaining(&self.mem)
735 }
736
737 pub fn consume_bytes(&mut self, amt: usize) {
740 self.regions.consume(amt)
741 }
742
743 pub fn split_at(&mut self, offset: usize) -> Writer {
748 Writer {
749 mem: self.mem.clone(),
750 regions: self.regions.split_at(offset),
751 }
752 }
753}
754
755impl io::Write for Writer {
756 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
757 let mut rem = buf;
758 let mut total = 0;
759 for b in self.regions.get_remaining(&self.mem) {
760 if rem.is_empty() {
761 break;
762 }
763
764 let count = cmp::min(rem.len(), b.size());
765 unsafe {
768 copy_nonoverlapping(rem.as_ptr(), b.as_mut_ptr(), count);
769 }
770 rem = &rem[count..];
771 total += count;
772 }
773
774 self.regions.consume(total);
775 Ok(total)
776 }
777
778 fn flush(&mut self) -> io::Result<()> {
779 Ok(())
781 }
782}
783
784#[cfg(any(target_os = "android", target_os = "linux"))]
785impl fuse::Writer for Writer {
786 type ClosureWriter = Self;
787
788 fn write_at<F>(&mut self, offset: usize, f: F) -> io::Result<usize>
789 where
790 F: Fn(&mut Self) -> io::Result<usize>,
791 {
792 f(&mut self.split_at(offset))
793 }
794
795 fn has_sufficient_buffer(&self, size: u32) -> bool {
796 self.available_bytes() >= size as usize
797 }
798}
799
800#[cfg(any(target_os = "android", target_os = "linux"))]
801impl fuse::filesystem::ZeroCopyWriter for Writer {
802 fn write_from(&mut self, f: &mut std::fs::File, count: usize, off: u64) -> io::Result<usize> {
803 self.write_from_at(f, count, off)
804 }
805}
806
807const VIRTQ_DESC_F_NEXT: u16 = 0x1;
808const VIRTQ_DESC_F_WRITE: u16 = 0x2;
809
810#[derive(Copy, Clone, PartialEq, Eq)]
811pub enum DescriptorType {
812 Readable,
813 Writable,
814}
815
816#[derive(Copy, Clone, Debug, FromBytes, Immutable, IntoBytes, KnownLayout)]
817#[repr(C)]
818struct virtq_desc {
819 addr: Le64,
820 len: Le32,
821 flags: Le16,
822 next: Le16,
823}
824
825pub fn create_descriptor_chain(
827 memory: &GuestMemory,
828 descriptor_array_addr: GuestAddress,
829 mut buffers_start_addr: GuestAddress,
830 descriptors: Vec<(DescriptorType, u32)>,
831 spaces_between_regions: u32,
832) -> anyhow::Result<DescriptorChain> {
833 let descriptors_len = descriptors.len();
834 for (index, (type_, size)) in descriptors.into_iter().enumerate() {
835 let mut flags = 0;
836 if let DescriptorType::Writable = type_ {
837 flags |= VIRTQ_DESC_F_WRITE;
838 }
839 if index + 1 < descriptors_len {
840 flags |= VIRTQ_DESC_F_NEXT;
841 }
842
843 let index = index as u16;
844 let desc = virtq_desc {
845 addr: buffers_start_addr.offset().into(),
846 len: size.into(),
847 flags: flags.into(),
848 next: (index + 1).into(),
849 };
850
851 let offset = size + spaces_between_regions;
852 buffers_start_addr = buffers_start_addr
853 .checked_add(offset as u64)
854 .context("Invalid buffers_start_addr)")?;
855
856 let _ = memory.write_obj_at_addr(
857 desc,
858 descriptor_array_addr
859 .checked_add(index as u64 * std::mem::size_of::<virtq_desc>() as u64)
860 .context("Invalid descriptor_array_addr")?,
861 );
862 }
863
864 let chain = SplitDescriptorChain::new(memory, descriptor_array_addr, 0x100, 0);
865 DescriptorChain::new(chain, memory, 0)
866}
867
868#[cfg(test)]
869mod tests {
870 use std::fs::File;
871 use std::io::Read;
872
873 use cros_async::Executor;
874 use tempfile::tempfile;
875 use tempfile::NamedTempFile;
876
877 use super::*;
878
879 #[test]
880 fn reader_test_simple_chain() {
881 use DescriptorType::*;
882
883 let memory_start_addr = GuestAddress(0x0);
884 let memory = GuestMemory::new(&[(memory_start_addr, 0x10000)]).unwrap();
885
886 let mut chain = create_descriptor_chain(
887 &memory,
888 GuestAddress(0x0),
889 GuestAddress(0x100),
890 vec![
891 (Readable, 8),
892 (Readable, 16),
893 (Readable, 18),
894 (Readable, 64),
895 ],
896 0,
897 )
898 .expect("create_descriptor_chain failed");
899 let reader = &mut chain.reader;
900 assert_eq!(reader.available_bytes(), 106);
901 assert_eq!(reader.bytes_read(), 0);
902
903 let mut buffer = [0u8; 64];
904 reader
905 .read_exact(&mut buffer)
906 .expect("read_exact should not fail here");
907
908 assert_eq!(reader.available_bytes(), 42);
909 assert_eq!(reader.bytes_read(), 64);
910
911 match reader.read(&mut buffer) {
912 Err(_) => panic!("read should not fail here"),
913 Ok(length) => assert_eq!(length, 42),
914 }
915
916 assert_eq!(reader.available_bytes(), 0);
917 assert_eq!(reader.bytes_read(), 106);
918 }
919
920 #[test]
921 fn writer_test_simple_chain() {
922 use DescriptorType::*;
923
924 let memory_start_addr = GuestAddress(0x0);
925 let memory = GuestMemory::new(&[(memory_start_addr, 0x10000)]).unwrap();
926
927 let mut chain = create_descriptor_chain(
928 &memory,
929 GuestAddress(0x0),
930 GuestAddress(0x100),
931 vec![
932 (Writable, 8),
933 (Writable, 16),
934 (Writable, 18),
935 (Writable, 64),
936 ],
937 0,
938 )
939 .expect("create_descriptor_chain failed");
940 let writer = &mut chain.writer;
941 assert_eq!(writer.available_bytes(), 106);
942 assert_eq!(writer.bytes_written(), 0);
943
944 let buffer = [0; 64];
945 writer
946 .write_all(&buffer)
947 .expect("write_all should not fail here");
948
949 assert_eq!(writer.available_bytes(), 42);
950 assert_eq!(writer.bytes_written(), 64);
951
952 match writer.write(&buffer) {
953 Err(_) => panic!("write should not fail here"),
954 Ok(length) => assert_eq!(length, 42),
955 }
956
957 assert_eq!(writer.available_bytes(), 0);
958 assert_eq!(writer.bytes_written(), 106);
959 }
960
961 #[test]
962 fn reader_test_incompatible_chain() {
963 use DescriptorType::*;
964
965 let memory_start_addr = GuestAddress(0x0);
966 let memory = GuestMemory::new(&[(memory_start_addr, 0x10000)]).unwrap();
967
968 let mut chain = create_descriptor_chain(
969 &memory,
970 GuestAddress(0x0),
971 GuestAddress(0x100),
972 vec![(Writable, 8)],
973 0,
974 )
975 .expect("create_descriptor_chain failed");
976 let reader = &mut chain.reader;
977 assert_eq!(reader.available_bytes(), 0);
978 assert_eq!(reader.bytes_read(), 0);
979
980 assert!(reader.read_obj::<u8>().is_err());
981
982 assert_eq!(reader.available_bytes(), 0);
983 assert_eq!(reader.bytes_read(), 0);
984 }
985
986 #[test]
987 fn writer_test_incompatible_chain() {
988 use DescriptorType::*;
989
990 let memory_start_addr = GuestAddress(0x0);
991 let memory = GuestMemory::new(&[(memory_start_addr, 0x10000)]).unwrap();
992
993 let mut chain = create_descriptor_chain(
994 &memory,
995 GuestAddress(0x0),
996 GuestAddress(0x100),
997 vec![(Readable, 8)],
998 0,
999 )
1000 .expect("create_descriptor_chain failed");
1001 let writer = &mut chain.writer;
1002 assert_eq!(writer.available_bytes(), 0);
1003 assert_eq!(writer.bytes_written(), 0);
1004
1005 assert!(writer.write_obj(0u8).is_err());
1006
1007 assert_eq!(writer.available_bytes(), 0);
1008 assert_eq!(writer.bytes_written(), 0);
1009 }
1010
1011 #[test]
1012 fn reader_failing_io() {
1013 use DescriptorType::*;
1014
1015 let memory_start_addr = GuestAddress(0x0);
1016 let memory = GuestMemory::new(&[(memory_start_addr, 0x10000)]).unwrap();
1017
1018 let mut chain = create_descriptor_chain(
1019 &memory,
1020 GuestAddress(0x0),
1021 GuestAddress(0x100),
1022 vec![(Readable, 256), (Readable, 256)],
1023 0,
1024 )
1025 .expect("create_descriptor_chain failed");
1026
1027 let reader = &mut chain.reader;
1028
1029 let device_file = if cfg!(windows) { "NUL" } else { "/dev/zero" };
1031 let mut ro_file = File::open(device_file).expect("failed to open device file");
1032
1033 reader
1034 .read_exact_to(&mut ro_file, 512)
1035 .expect_err("successfully read more bytes than SharedMemory size");
1036
1037 assert_eq!(reader.available_bytes(), 512);
1039 assert_eq!(reader.bytes_read(), 0);
1040 }
1041
1042 #[test]
1043 fn writer_failing_io() {
1044 use DescriptorType::*;
1045
1046 let memory_start_addr = GuestAddress(0x0);
1047 let memory = GuestMemory::new(&[(memory_start_addr, 0x10000)]).unwrap();
1048
1049 let mut chain = create_descriptor_chain(
1050 &memory,
1051 GuestAddress(0x0),
1052 GuestAddress(0x100),
1053 vec![(Writable, 256), (Writable, 256)],
1054 0,
1055 )
1056 .expect("create_descriptor_chain failed");
1057
1058 let writer = &mut chain.writer;
1059
1060 let mut file = tempfile().unwrap();
1061
1062 file.set_len(384).unwrap();
1063
1064 writer
1065 .write_all_from(&mut file, 512)
1066 .expect_err("successfully wrote more bytes than in SharedMemory");
1067
1068 assert_eq!(writer.available_bytes(), 128);
1069 assert_eq!(writer.bytes_written(), 384);
1070 }
1071
1072 #[test]
1073 fn reader_writer_shared_chain() {
1074 use DescriptorType::*;
1075
1076 let memory_start_addr = GuestAddress(0x0);
1077 let memory = GuestMemory::new(&[(memory_start_addr, 0x10000)]).unwrap();
1078
1079 let mut chain = create_descriptor_chain(
1080 &memory,
1081 GuestAddress(0x0),
1082 GuestAddress(0x100),
1083 vec![
1084 (Readable, 16),
1085 (Readable, 16),
1086 (Readable, 96),
1087 (Writable, 64),
1088 (Writable, 1),
1089 (Writable, 3),
1090 ],
1091 0,
1092 )
1093 .expect("create_descriptor_chain failed");
1094 let reader = &mut chain.reader;
1095 let writer = &mut chain.writer;
1096
1097 assert_eq!(reader.bytes_read(), 0);
1098 assert_eq!(writer.bytes_written(), 0);
1099
1100 let mut buffer = Vec::with_capacity(200);
1101
1102 assert_eq!(
1103 reader
1104 .read_to_end(&mut buffer)
1105 .expect("read should not fail here"),
1106 128
1107 );
1108
1109 writer
1111 .write_all(&buffer[..68])
1112 .expect("write should not fail here");
1113
1114 assert_eq!(reader.available_bytes(), 0);
1115 assert_eq!(reader.bytes_read(), 128);
1116 assert_eq!(writer.available_bytes(), 0);
1117 assert_eq!(writer.bytes_written(), 68);
1118 }
1119
1120 #[test]
1121 fn reader_writer_shattered_object() {
1122 use DescriptorType::*;
1123
1124 let memory_start_addr = GuestAddress(0x0);
1125 let memory = GuestMemory::new(&[(memory_start_addr, 0x10000)]).unwrap();
1126
1127 let secret: Le32 = 0x12345678.into();
1128
1129 let mut chain_writer = create_descriptor_chain(
1131 &memory,
1132 GuestAddress(0x0),
1133 GuestAddress(0x100),
1134 vec![(Writable, 1), (Writable, 1), (Writable, 1), (Writable, 1)],
1135 123,
1136 )
1137 .expect("create_descriptor_chain failed");
1138 let writer = &mut chain_writer.writer;
1139 writer
1140 .write_obj(secret)
1141 .expect("write_obj should not fail here");
1142
1143 let mut chain_reader = create_descriptor_chain(
1145 &memory,
1146 GuestAddress(0x0),
1147 GuestAddress(0x100),
1148 vec![(Readable, 1), (Readable, 1), (Readable, 1), (Readable, 1)],
1149 123,
1150 )
1151 .expect("create_descriptor_chain failed");
1152 let reader = &mut chain_reader.reader;
1153 match reader.read_obj::<Le32>() {
1154 Err(_) => panic!("read_obj should not fail here"),
1155 Ok(read_secret) => assert_eq!(read_secret, secret),
1156 }
1157 }
1158
1159 #[test]
1160 fn reader_unexpected_eof() {
1161 use DescriptorType::*;
1162
1163 let memory_start_addr = GuestAddress(0x0);
1164 let memory = GuestMemory::new(&[(memory_start_addr, 0x10000)]).unwrap();
1165
1166 let mut chain = create_descriptor_chain(
1167 &memory,
1168 GuestAddress(0x0),
1169 GuestAddress(0x100),
1170 vec![(Readable, 256), (Readable, 256)],
1171 0,
1172 )
1173 .expect("create_descriptor_chain failed");
1174
1175 let reader = &mut chain.reader;
1176
1177 let mut buf = vec![0; 1024];
1178
1179 assert_eq!(
1180 reader
1181 .read_exact(&mut buf[..])
1182 .expect_err("read more bytes than available")
1183 .kind(),
1184 io::ErrorKind::UnexpectedEof
1185 );
1186 }
1187
1188 #[test]
1189 fn split_border() {
1190 use DescriptorType::*;
1191
1192 let memory_start_addr = GuestAddress(0x0);
1193 let memory = GuestMemory::new(&[(memory_start_addr, 0x10000)]).unwrap();
1194
1195 let mut chain = create_descriptor_chain(
1196 &memory,
1197 GuestAddress(0x0),
1198 GuestAddress(0x100),
1199 vec![
1200 (Readable, 16),
1201 (Readable, 16),
1202 (Readable, 96),
1203 (Writable, 64),
1204 (Writable, 1),
1205 (Writable, 3),
1206 ],
1207 0,
1208 )
1209 .expect("create_descriptor_chain failed");
1210 let reader = &mut chain.reader;
1211
1212 let other = reader.split_at(32);
1213 assert_eq!(reader.available_bytes(), 32);
1214 assert_eq!(other.available_bytes(), 96);
1215 }
1216
1217 #[test]
1218 fn split_middle() {
1219 use DescriptorType::*;
1220
1221 let memory_start_addr = GuestAddress(0x0);
1222 let memory = GuestMemory::new(&[(memory_start_addr, 0x10000)]).unwrap();
1223
1224 let mut chain = create_descriptor_chain(
1225 &memory,
1226 GuestAddress(0x0),
1227 GuestAddress(0x100),
1228 vec![
1229 (Readable, 16),
1230 (Readable, 16),
1231 (Readable, 96),
1232 (Writable, 64),
1233 (Writable, 1),
1234 (Writable, 3),
1235 ],
1236 0,
1237 )
1238 .expect("create_descriptor_chain failed");
1239 let reader = &mut chain.reader;
1240
1241 let other = reader.split_at(24);
1242 assert_eq!(reader.available_bytes(), 24);
1243 assert_eq!(other.available_bytes(), 104);
1244 }
1245
1246 #[test]
1247 fn split_end() {
1248 use DescriptorType::*;
1249
1250 let memory_start_addr = GuestAddress(0x0);
1251 let memory = GuestMemory::new(&[(memory_start_addr, 0x10000)]).unwrap();
1252
1253 let mut chain = create_descriptor_chain(
1254 &memory,
1255 GuestAddress(0x0),
1256 GuestAddress(0x100),
1257 vec![
1258 (Readable, 16),
1259 (Readable, 16),
1260 (Readable, 96),
1261 (Writable, 64),
1262 (Writable, 1),
1263 (Writable, 3),
1264 ],
1265 0,
1266 )
1267 .expect("create_descriptor_chain failed");
1268 let reader = &mut chain.reader;
1269
1270 let other = reader.split_at(128);
1271 assert_eq!(reader.available_bytes(), 128);
1272 assert_eq!(other.available_bytes(), 0);
1273 }
1274
1275 #[test]
1276 fn split_beginning() {
1277 use DescriptorType::*;
1278
1279 let memory_start_addr = GuestAddress(0x0);
1280 let memory = GuestMemory::new(&[(memory_start_addr, 0x10000)]).unwrap();
1281
1282 let mut chain = create_descriptor_chain(
1283 &memory,
1284 GuestAddress(0x0),
1285 GuestAddress(0x100),
1286 vec![
1287 (Readable, 16),
1288 (Readable, 16),
1289 (Readable, 96),
1290 (Writable, 64),
1291 (Writable, 1),
1292 (Writable, 3),
1293 ],
1294 0,
1295 )
1296 .expect("create_descriptor_chain failed");
1297 let reader = &mut chain.reader;
1298
1299 let other = reader.split_at(0);
1300 assert_eq!(reader.available_bytes(), 0);
1301 assert_eq!(other.available_bytes(), 128);
1302 }
1303
1304 #[test]
1305 fn split_outofbounds() {
1306 use DescriptorType::*;
1307
1308 let memory_start_addr = GuestAddress(0x0);
1309 let memory = GuestMemory::new(&[(memory_start_addr, 0x10000)]).unwrap();
1310
1311 let mut chain = create_descriptor_chain(
1312 &memory,
1313 GuestAddress(0x0),
1314 GuestAddress(0x100),
1315 vec![
1316 (Readable, 16),
1317 (Readable, 16),
1318 (Readable, 96),
1319 (Writable, 64),
1320 (Writable, 1),
1321 (Writable, 3),
1322 ],
1323 0,
1324 )
1325 .expect("create_descriptor_chain failed");
1326 let reader = &mut chain.reader;
1327
1328 let other = reader.split_at(256);
1329 assert_eq!(
1330 other.available_bytes(),
1331 0,
1332 "Reader returned from out-of-bounds split still has available bytes"
1333 );
1334 }
1335
1336 #[test]
1337 fn read_full() {
1338 use DescriptorType::*;
1339
1340 let memory_start_addr = GuestAddress(0x0);
1341 let memory = GuestMemory::new(&[(memory_start_addr, 0x10000)]).unwrap();
1342
1343 let mut chain = create_descriptor_chain(
1344 &memory,
1345 GuestAddress(0x0),
1346 GuestAddress(0x100),
1347 vec![(Readable, 16), (Readable, 16), (Readable, 16)],
1348 0,
1349 )
1350 .expect("create_descriptor_chain failed");
1351 let reader = &mut chain.reader;
1352
1353 let mut buf = [0u8; 64];
1354 assert_eq!(
1355 reader.read(&mut buf[..]).expect("failed to read to buffer"),
1356 48
1357 );
1358 }
1359
1360 #[test]
1361 fn write_full() {
1362 use DescriptorType::*;
1363
1364 let memory_start_addr = GuestAddress(0x0);
1365 let memory = GuestMemory::new(&[(memory_start_addr, 0x10000)]).unwrap();
1366
1367 let mut chain = create_descriptor_chain(
1368 &memory,
1369 GuestAddress(0x0),
1370 GuestAddress(0x100),
1371 vec![(Writable, 16), (Writable, 16), (Writable, 16)],
1372 0,
1373 )
1374 .expect("create_descriptor_chain failed");
1375 let writer = &mut chain.writer;
1376
1377 let buf = [0xdeu8; 64];
1378 assert_eq!(
1379 writer.write(&buf[..]).expect("failed to write from buffer"),
1380 48
1381 );
1382 }
1383
1384 #[test]
1385 fn consume_collect() {
1386 use DescriptorType::*;
1387
1388 let memory_start_addr = GuestAddress(0x0);
1389 let memory = GuestMemory::new(&[(memory_start_addr, 0x10000)]).unwrap();
1390 let vs: Vec<Le64> = vec![
1391 0x0101010101010101.into(),
1392 0x0202020202020202.into(),
1393 0x0303030303030303.into(),
1394 ];
1395
1396 let mut write_chain = create_descriptor_chain(
1397 &memory,
1398 GuestAddress(0x0),
1399 GuestAddress(0x100),
1400 vec![(Writable, 24)],
1401 0,
1402 )
1403 .expect("create_descriptor_chain failed");
1404 let writer = &mut write_chain.writer;
1405 writer
1406 .consume(vs.clone())
1407 .expect("failed to consume() a vector");
1408
1409 let mut read_chain = create_descriptor_chain(
1410 &memory,
1411 GuestAddress(0x0),
1412 GuestAddress(0x100),
1413 vec![(Readable, 24)],
1414 0,
1415 )
1416 .expect("create_descriptor_chain failed");
1417 let reader = &mut read_chain.reader;
1418 let vs_read = reader
1419 .collect::<io::Result<Vec<Le64>>, _>()
1420 .expect("failed to collect() values");
1421 assert_eq!(vs, vs_read);
1422 }
1423
1424 #[test]
1425 fn get_remaining_region_with_count() {
1426 use DescriptorType::*;
1427
1428 let memory_start_addr = GuestAddress(0x0);
1429 let memory = GuestMemory::new(&[(memory_start_addr, 0x10000)]).unwrap();
1430
1431 let chain = create_descriptor_chain(
1432 &memory,
1433 GuestAddress(0x0),
1434 GuestAddress(0x100),
1435 vec![
1436 (Readable, 16),
1437 (Readable, 16),
1438 (Readable, 96),
1439 (Writable, 64),
1440 (Writable, 1),
1441 (Writable, 3),
1442 ],
1443 0,
1444 )
1445 .expect("create_descriptor_chain failed");
1446
1447 let Reader {
1448 mem: _,
1449 mut regions,
1450 } = chain.reader;
1451
1452 let drain = regions
1453 .get_remaining_regions_with_count(usize::MAX)
1454 .fold(0usize, |total, region| total + region.len);
1455 assert_eq!(drain, 128);
1456
1457 let exact = regions
1458 .get_remaining_regions_with_count(32)
1459 .fold(0usize, |total, region| total + region.len);
1460 assert!(exact > 0);
1461 assert!(exact <= 32);
1462
1463 let split = regions
1464 .get_remaining_regions_with_count(24)
1465 .fold(0usize, |total, region| total + region.len);
1466 assert!(split > 0);
1467 assert!(split <= 24);
1468
1469 regions.consume(64);
1470
1471 let first = regions
1472 .get_remaining_regions_with_count(8)
1473 .fold(0usize, |total, region| total + region.len);
1474 assert!(first > 0);
1475 assert!(first <= 8);
1476 }
1477
1478 #[test]
1479 fn get_remaining_with_count() {
1480 use DescriptorType::*;
1481
1482 let memory_start_addr = GuestAddress(0x0);
1483 let memory = GuestMemory::new(&[(memory_start_addr, 0x10000)]).unwrap();
1484
1485 let chain = create_descriptor_chain(
1486 &memory,
1487 GuestAddress(0x0),
1488 GuestAddress(0x100),
1489 vec![
1490 (Readable, 16),
1491 (Readable, 16),
1492 (Readable, 96),
1493 (Writable, 64),
1494 (Writable, 1),
1495 (Writable, 3),
1496 ],
1497 0,
1498 )
1499 .expect("create_descriptor_chain failed");
1500 let Reader {
1501 mem: _,
1502 mut regions,
1503 } = chain.reader;
1504
1505 let drain = regions
1506 .get_remaining_with_count(&memory, usize::MAX)
1507 .iter()
1508 .fold(0usize, |total, iov| total + iov.size());
1509 assert_eq!(drain, 128);
1510
1511 let exact = regions
1512 .get_remaining_with_count(&memory, 32)
1513 .iter()
1514 .fold(0usize, |total, iov| total + iov.size());
1515 assert!(exact > 0);
1516 assert!(exact <= 32);
1517
1518 let split = regions
1519 .get_remaining_with_count(&memory, 24)
1520 .iter()
1521 .fold(0usize, |total, iov| total + iov.size());
1522 assert!(split > 0);
1523 assert!(split <= 24);
1524
1525 regions.consume(64);
1526
1527 let first = regions
1528 .get_remaining_with_count(&memory, 8)
1529 .iter()
1530 .fold(0usize, |total, iov| total + iov.size());
1531 assert!(first > 0);
1532 assert!(first <= 8);
1533 }
1534
1535 #[test]
1536 fn reader_peek_obj() {
1537 use DescriptorType::*;
1538
1539 let memory_start_addr = GuestAddress(0x0);
1540 let memory = GuestMemory::new(&[(memory_start_addr, 0x10000)]).unwrap();
1541
1542 memory
1544 .write_obj_at_addr(Le16::from(0xBEEF), GuestAddress(0x100))
1545 .unwrap();
1546 memory
1547 .write_obj_at_addr(Le16::from(0xDEAD), GuestAddress(0x200))
1548 .unwrap();
1549
1550 let mut chain_reader = create_descriptor_chain(
1551 &memory,
1552 GuestAddress(0x0),
1553 GuestAddress(0x100),
1554 vec![(Readable, 2), (Readable, 2)],
1555 0x100 - 2,
1556 )
1557 .expect("create_descriptor_chain failed");
1558 let reader = &mut chain_reader.reader;
1559
1560 let peek1 = reader.peek_obj::<Le16>().unwrap();
1562 assert_eq!(peek1, Le16::from(0xBEEF));
1563
1564 let peek2 = reader.peek_obj::<Le16>().unwrap();
1566 assert_eq!(peek2, Le16::from(0xBEEF));
1567
1568 let peek3 = reader.peek_obj::<Le32>().unwrap();
1570 assert_eq!(peek3, Le32::from(0xDEADBEEF));
1571
1572 let read1 = reader.read_obj::<Le16>().unwrap();
1574 assert_eq!(read1, Le16::from(0xBEEF));
1575
1576 reader
1578 .peek_obj::<Le32>()
1579 .expect_err("peek_obj past end of chain");
1580
1581 let read2 = reader.read_obj::<Le16>().unwrap();
1583 assert_eq!(read2, Le16::from(0xDEAD));
1584
1585 reader
1587 .peek_obj::<Le16>()
1588 .expect_err("peek_obj past end of chain");
1589 }
1590
1591 #[test]
1592 fn region_reader_failing_io() {
1593 let ex = Executor::new().unwrap();
1594 ex.run_until(region_reader_failing_io_async(&ex)).unwrap();
1595 }
1596 async fn region_reader_failing_io_async(ex: &Executor) {
1597 use DescriptorType::*;
1598
1599 let memory_start_addr = GuestAddress(0x0);
1600 let memory = GuestMemory::new(&[(memory_start_addr, 0x10000)]).unwrap();
1601
1602 let mut chain = create_descriptor_chain(
1603 &memory,
1604 GuestAddress(0x0),
1605 GuestAddress(0x100),
1606 vec![(Readable, 256), (Readable, 256)],
1607 0,
1608 )
1609 .expect("create_descriptor_chain failed");
1610
1611 let reader = &mut chain.reader;
1612
1613 let named_temp_file = NamedTempFile::new().expect("failed to create temp file");
1615 let ro_file =
1616 File::open(named_temp_file.path()).expect("failed to open temp file read only");
1617 let async_ro_file = disk::SingleFileDisk::new(ro_file, ex).expect("Failed to crate SFD");
1618
1619 reader
1620 .read_exact_to_at_fut(&async_ro_file, 512, 0, Default::default())
1621 .await
1622 .expect_err("successfully read more bytes than SingleFileDisk size");
1623
1624 assert_eq!(reader.available_bytes(), 512);
1626 assert_eq!(reader.bytes_read(), 0);
1627 }
1628
1629 #[test]
1630 fn region_writer_failing_io() {
1631 let ex = Executor::new().unwrap();
1632 ex.run_until(region_writer_failing_io_async(&ex)).unwrap()
1633 }
1634 async fn region_writer_failing_io_async(ex: &Executor) {
1635 use DescriptorType::*;
1636
1637 let memory_start_addr = GuestAddress(0x0);
1638 let memory = GuestMemory::new(&[(memory_start_addr, 0x10000)]).unwrap();
1639
1640 let mut chain = create_descriptor_chain(
1641 &memory,
1642 GuestAddress(0x0),
1643 GuestAddress(0x100),
1644 vec![(Writable, 256), (Writable, 256)],
1645 0,
1646 )
1647 .expect("create_descriptor_chain failed");
1648
1649 let writer = &mut chain.writer;
1650
1651 let file = tempfile().expect("failed to create temp file");
1652
1653 file.set_len(384).unwrap();
1654 let async_file = disk::SingleFileDisk::new(file, ex).expect("Failed to crate SFD");
1655
1656 writer
1657 .write_all_from_at_fut(&async_file, 512, 0, Default::default())
1658 .await
1659 .expect_err("successfully wrote more bytes than in SingleFileDisk");
1660
1661 assert_eq!(writer.available_bytes(), 128);
1662 assert_eq!(writer.bytes_written(), 384);
1663 }
1664}