1use std::cmp;
42use std::collections::VecDeque;
43use std::io::{self, IoSlice, Write};
44use std::ops::Deref;
45use std::ptr::copy_nonoverlapping;
46
47use virtio_queue::DescriptorChain;
48use vm_memory::bitmap::{BitmapSlice, MS};
49use vm_memory::{Address, ByteValued, GuestMemory, GuestMemoryRegion, MemoryRegionAddress};
50
51use super::{Error, FileReadWriteVolatile, FileVolatileSlice, IoBuffers, Reader, Result, Writer};
52
53impl<S: BitmapSlice> IoBuffers<'_, S> {
54 fn consume_for_write<F>(&mut self, count: usize, f: F) -> io::Result<usize>
56 where
57 F: FnOnce(&[FileVolatileSlice]) -> io::Result<usize>,
58 {
59 self.consume(true, count, f)
60 }
61}
62
63impl<'a> Reader<'a> {
64 pub fn from_descriptor_chain<M>(
66 mem: &'a M::Target,
67 desc_chain: DescriptorChain<M>,
68 ) -> Result<Reader<'a, MS<'a, M::Target>>>
69 where
70 M: Deref,
71 M::Target: GuestMemory + Sized,
72 {
73 let mut total_len: usize = 0;
74 let mut buffers = VecDeque::with_capacity(64);
77 for desc in desc_chain.readable() {
78 total_len = total_len
82 .checked_add(desc.len() as usize)
83 .ok_or(Error::DescriptorChainOverflow)?;
84
85 let region = mem
86 .find_region(desc.addr())
87 .ok_or(Error::FindMemoryRegion)?;
88 let offset = desc
89 .addr()
90 .checked_sub(region.start_addr().raw_value())
91 .unwrap();
92
93 buffers.push_back(
94 region
95 .get_slice(MemoryRegionAddress(offset.raw_value()), desc.len() as usize)
96 .map_err(Error::GuestMemoryError)?,
97 );
98 }
99
100 Ok(Reader {
101 buffers: IoBuffers {
102 buffers,
103 bytes_consumed: 0,
104 },
105 })
106 }
107}
108
109#[derive(Clone)]
117pub struct VirtioFsWriter<'a, S = ()> {
118 buffers: IoBuffers<'a, S>,
119}
120
121impl<'a> VirtioFsWriter<'a> {
122 pub fn new<M>(
124 mem: &'a M::Target,
125 desc_chain: DescriptorChain<M>,
126 ) -> Result<VirtioFsWriter<'a, MS<'a, M::Target>>>
127 where
128 M: Deref,
129 M::Target: GuestMemory + Sized,
130 {
131 let mut total_len: usize = 0;
132 let mut buffers = VecDeque::with_capacity(64);
135 for desc in desc_chain.writable() {
136 total_len = total_len
140 .checked_add(desc.len() as usize)
141 .ok_or(Error::DescriptorChainOverflow)?;
142
143 let region = mem
144 .find_region(desc.addr())
145 .ok_or(Error::FindMemoryRegion)?;
146 let offset = desc
147 .addr()
148 .checked_sub(region.start_addr().raw_value())
149 .unwrap();
150
151 buffers.push_back(
152 region
153 .get_slice(MemoryRegionAddress(offset.raw_value()), desc.len() as usize)
154 .map_err(Error::GuestMemoryError)?,
155 )
156 }
157
158 Ok(VirtioFsWriter {
159 buffers: IoBuffers {
160 buffers,
161 bytes_consumed: 0,
162 },
163 })
164 }
165}
166
167impl<'a, S: BitmapSlice> VirtioFsWriter<'a, S> {
168 pub fn write_obj<T: ByteValued>(&mut self, val: T) -> io::Result<()> {
170 self.write_all(val.as_slice())
171 }
172
173 pub fn write_from<F: FileReadWriteVolatile>(
177 &mut self,
178 mut src: F,
179 count: usize,
180 ) -> io::Result<usize> {
181 self.check_available_space(count, 0, 0)?;
182 self.buffers
183 .consume_for_write(count, |bufs| src.read_vectored_volatile(bufs))
184 }
185
186 pub fn write_from_at<F: FileReadWriteVolatile>(
190 &mut self,
191 mut src: F,
192 count: usize,
193 off: u64,
194 ) -> io::Result<usize> {
195 self.check_available_space(count, 0, 0)?;
196 self.buffers
197 .consume_for_write(count, |bufs| src.read_vectored_at_volatile(bufs, off))
198 }
199
200 pub fn write_all_from<F: FileReadWriteVolatile>(
202 &mut self,
203 mut src: F,
204 mut count: usize,
205 ) -> io::Result<()> {
206 self.check_available_space(count, 0, 0)?;
207 while count > 0 {
208 match self.write_from(&mut src, count) {
209 Ok(0) => {
210 return Err(io::Error::new(
211 io::ErrorKind::WriteZero,
212 "failed to write whole buffer",
213 ))
214 }
215 Ok(n) => count -= n,
216 Err(ref e) if e.kind() == io::ErrorKind::Interrupted => {}
217 Err(e) => return Err(e),
218 }
219 }
220
221 Ok(())
222 }
223
224 pub fn available_bytes(&self) -> usize {
229 self.buffers.available_bytes()
230 }
231
232 pub fn bytes_written(&self) -> usize {
234 self.buffers.bytes_consumed()
235 }
236
237 pub fn split_at(&mut self, offset: usize) -> Result<Self> {
242 self.buffers
243 .split_at(offset)
244 .map(|buffers| VirtioFsWriter { buffers })
245 }
246
247 pub fn commit(&mut self, _other: Option<&Writer<'a, S>>) -> io::Result<usize> {
251 Ok(0)
252 }
253
254 fn check_available_space(&self, len1: usize, len2: usize, len3: usize) -> io::Result<()> {
255 let len = len1
256 .checked_add(len2)
257 .ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, "buffer size is too big"))?;
258 let len = len
259 .checked_add(len3)
260 .ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, "buffer size is too big"))?;
261 if len > self.available_bytes() {
262 Err(io::Error::new(
263 io::ErrorKind::InvalidData,
264 format!(
265 "data out of range, available {} requested {}",
266 self.available_bytes(),
267 len
268 ),
269 ))
270 } else {
271 Ok(())
272 }
273 }
274}
275
276impl<S: BitmapSlice> io::Write for VirtioFsWriter<'_, S> {
277 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
278 self.check_available_space(buf.len(), 0, 0)?;
279
280 self.buffers.consume_for_write(buf.len(), |bufs| {
281 let mut rem = buf;
282 let mut total = 0;
283 for buf in bufs {
284 let copy_len = cmp::min(rem.len(), buf.len());
285
286 unsafe {
288 copy_nonoverlapping(rem.as_ptr(), buf.as_ptr(), copy_len);
289 }
290 rem = &rem[copy_len..];
291 total += copy_len;
292 }
293 Ok(total)
294 })
295 }
296
297 fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
298 self.check_available_space(bufs.iter().fold(0, |acc, x| acc + x.len()), 0, 0)?;
299
300 let mut count = 0;
301 for buf in bufs.iter().filter(|b| !b.is_empty()) {
302 count += self.write(buf)?;
303 }
304 Ok(count)
305 }
306
307 fn flush(&mut self) -> io::Result<()> {
308 Ok(())
310 }
311}
312
313#[cfg(feature = "async-io")]
316mod async_io {
317 use super::*;
318 use crate::transport::AsyncFileReadWriteVolatile;
319
320 impl<'a, S: BitmapSlice> VirtioFsWriter<'a, S> {
321 pub async fn async_write(&mut self, data: &[u8]) -> io::Result<usize> {
323 self.write(data)
324 }
325
326 pub async fn async_write2(&mut self, data: &[u8], data2: &[u8]) -> io::Result<usize> {
328 self.check_available_space(data.len(), data2.len(), 0)?;
329 let mut cnt = self.write(data)?;
330 cnt += self.write(data2)?;
331
332 Ok(cnt)
333 }
334
335 pub async fn async_write3(
337 &mut self,
338 data: &[u8],
339 data2: &[u8],
340 data3: &[u8],
341 ) -> io::Result<usize> {
342 self.check_available_space(data.len(), data2.len(), data3.len())?;
343 let mut cnt = self.write(data)?;
344 cnt += self.write(data2)?;
345 cnt += self.write(data3)?;
346
347 Ok(cnt)
348 }
349
350 pub async fn async_write_all(&mut self, buf: &[u8]) -> io::Result<()> {
352 self.write_all(buf)
353 }
354
355 pub async fn async_write_from_at<F: AsyncFileReadWriteVolatile>(
358 &mut self,
359 src: &F,
360 count: usize,
361 off: u64,
362 ) -> io::Result<usize> {
363 self.check_available_space(count, 0, 0)?;
364 let bufs = unsafe { self.buffers.prepare_mut_io_buf(count) };
366 if bufs.is_empty() {
367 Ok(0)
368 } else {
369 let (res, _) = src.async_read_vectored_at_volatile(bufs, off).await;
370 match res {
371 Ok(cnt) => {
372 self.buffers.mark_dirty(cnt);
373 self.buffers.mark_used(cnt)?;
374 Ok(cnt)
375 }
376 Err(e) => Err(e),
377 }
378 }
379 }
380
381 pub async fn async_commit(&mut self, other: Option<&Writer<'a, S>>) -> io::Result<usize> {
384 self.commit(other)
385 }
386 }
387}
388
389#[cfg(testff)]
392mod tests {
393 use super::*;
394 use std::io::{Read, Seek, SeekFrom, Write};
395 use vm_memory::{Address, ByteValued, Bytes, GuestAddress, GuestMemoryMmap, Le16, Le32, Le64};
396 use vmm_sys_util::tempfile::TempFile;
397
398 const VIRTQ_DESC_F_NEXT: u16 = 0x1;
399 const VIRTQ_DESC_F_WRITE: u16 = 0x2;
400
401 #[derive(Copy, Clone, PartialEq, Eq)]
402 pub enum DescriptorType {
403 Readable,
404 Writable,
405 }
406
407 #[derive(Copy, Clone, Debug, Default)]
408 #[repr(C)]
409 struct virtq_desc {
410 addr: Le64,
411 len: Le32,
412 flags: Le16,
413 next: Le16,
414 }
415
416 unsafe impl ByteValued for virtq_desc {}
418
419 pub fn create_descriptor_chain(
421 memory: &GuestMemoryMmap,
422 descriptor_array_addr: GuestAddress,
423 mut buffers_start_addr: GuestAddress,
424 descriptors: Vec<(DescriptorType, u32)>,
425 spaces_between_regions: u32,
426 ) -> Result<DescriptorChain<GuestMemoryMmap>> {
427 let descriptors_len = descriptors.len();
428 for (index, (type_, size)) in descriptors.into_iter().enumerate() {
429 let mut flags = 0;
430 if let DescriptorType::Writable = type_ {
431 flags |= VIRTQ_DESC_F_WRITE;
432 }
433 if index + 1 < descriptors_len {
434 flags |= VIRTQ_DESC_F_NEXT;
435 }
436
437 let index = index as u16;
438 let desc = virtq_desc {
439 addr: buffers_start_addr.raw_value().into(),
440 len: size.into(),
441 flags: flags.into(),
442 next: (index + 1).into(),
443 };
444
445 let offset = size + spaces_between_regions;
446 buffers_start_addr = buffers_start_addr
447 .checked_add(u64::from(offset))
448 .ok_or(Error::InvalidChain)?;
449
450 let _ = memory.write_obj(
451 desc,
452 descriptor_array_addr
453 .checked_add(u64::from(index) * std::mem::size_of::<virtq_desc>() as u64)
454 .ok_or(Error::InvalidChain)?,
455 );
456 }
457
458 DescriptorChain::<&GuestMemoryMmap>::new(memory, descriptor_array_addr, 0x100, 0)
459 .ok_or(Error::InvalidChain)
460 }
461
462 #[test]
463 fn reader_test_simple_chain() {
464 use DescriptorType::*;
465
466 let memory_start_addr = GuestAddress(0x0);
467 let memory = GuestMemoryMmap::from_ranges(&vec![(memory_start_addr, 0x10000)]).unwrap();
468
469 let chain = create_descriptor_chain(
470 &memory,
471 GuestAddress(0x0),
472 GuestAddress(0x100),
473 vec![
474 (Readable, 8),
475 (Readable, 16),
476 (Readable, 18),
477 (Readable, 64),
478 ],
479 0,
480 )
481 .expect("create_descriptor_chain failed");
482 let mut reader = Reader::new(&memory, chain).expect("failed to create Reader");
483 assert_eq!(reader.available_bytes(), 106);
484 assert_eq!(reader.bytes_read(), 0);
485
486 let mut buffer = [0 as u8; 64];
487 if let Err(_) = reader.read_exact(&mut buffer) {
488 panic!("read_exact should not fail here");
489 }
490
491 assert_eq!(reader.available_bytes(), 42);
492 assert_eq!(reader.bytes_read(), 64);
493
494 match reader.read(&mut buffer) {
495 Err(_) => panic!("read should not fail here"),
496 Ok(length) => assert_eq!(length, 42),
497 }
498
499 assert_eq!(reader.available_bytes(), 0);
500 assert_eq!(reader.bytes_read(), 106);
501 }
502
503 #[test]
504 fn writer_test_simple_chain() {
505 use DescriptorType::*;
506
507 let memory_start_addr = GuestAddress(0x0);
508 let memory = GuestMemoryMmap::from_ranges(&vec![(memory_start_addr, 0x10000)]).unwrap();
509
510 let chain = create_descriptor_chain(
511 &memory,
512 GuestAddress(0x0),
513 GuestAddress(0x100),
514 vec![
515 (Writable, 8),
516 (Writable, 16),
517 (Writable, 18),
518 (Writable, 64),
519 ],
520 0,
521 )
522 .expect("create_descriptor_chain failed");
523 let mut writer = VirtioFsWriter::new(&memory, chain).expect("failed to create Writer");
524 assert_eq!(writer.available_bytes(), 106);
525 assert_eq!(writer.bytes_written(), 0);
526
527 let mut buffer = [0 as u8; 64];
528 if let Err(_) = writer.write_all(&mut buffer) {
529 panic!("write_all should not fail here");
530 }
531
532 assert_eq!(writer.available_bytes(), 42);
533 assert_eq!(writer.bytes_written(), 64);
534
535 let mut buffer = [0 as u8; 42];
536 match writer.write(&mut buffer) {
537 Err(_) => panic!("write should not fail here"),
538 Ok(length) => assert_eq!(length, 42),
539 }
540
541 assert_eq!(writer.available_bytes(), 0);
542 assert_eq!(writer.bytes_written(), 106);
543 }
544
545 #[test]
546 fn reader_test_incompatible_chain() {
547 use DescriptorType::*;
548
549 let memory_start_addr = GuestAddress(0x0);
550 let memory = GuestMemoryMmap::from_ranges(&vec![(memory_start_addr, 0x10000)]).unwrap();
551
552 let chain = create_descriptor_chain(
553 &memory,
554 GuestAddress(0x0),
555 GuestAddress(0x100),
556 vec![(Writable, 8)],
557 0,
558 )
559 .expect("create_descriptor_chain failed");
560 let mut reader = Reader::new(&memory, chain).expect("failed to create Reader");
561 assert_eq!(reader.available_bytes(), 0);
562 assert_eq!(reader.bytes_read(), 0);
563
564 assert!(reader.read_obj::<u8>().is_err());
565
566 assert_eq!(reader.available_bytes(), 0);
567 assert_eq!(reader.bytes_read(), 0);
568 }
569
570 #[test]
571 fn writer_test_incompatible_chain() {
572 use DescriptorType::*;
573
574 let memory_start_addr = GuestAddress(0x0);
575 let memory = GuestMemoryMmap::from_ranges(&vec![(memory_start_addr, 0x10000)]).unwrap();
576
577 let chain = create_descriptor_chain(
578 &memory,
579 GuestAddress(0x0),
580 GuestAddress(0x100),
581 vec![(Readable, 8)],
582 0,
583 )
584 .expect("create_descriptor_chain failed");
585 let mut writer = VirtioFsWriter::new(&memory, chain).expect("failed to create Writer");
586 assert_eq!(writer.available_bytes(), 0);
587 assert_eq!(writer.bytes_written(), 0);
588
589 assert!(writer.write_obj(0u8).is_err());
590
591 assert_eq!(writer.available_bytes(), 0);
592 assert_eq!(writer.bytes_written(), 0);
593 }
594
595 #[test]
596 fn reader_writer_shared_chain() {
597 use DescriptorType::*;
598
599 let memory_start_addr = GuestAddress(0x0);
600 let memory = GuestMemoryMmap::from_ranges(&vec![(memory_start_addr, 0x10000)]).unwrap();
601
602 let chain = create_descriptor_chain(
603 &memory,
604 GuestAddress(0x0),
605 GuestAddress(0x100),
606 vec![
607 (Readable, 16),
608 (Readable, 16),
609 (Readable, 96),
610 (Writable, 64),
611 (Writable, 1),
612 (Writable, 3),
613 ],
614 0,
615 )
616 .expect("create_descriptor_chain failed");
617 let mut reader = Reader::new(&memory, chain.clone()).expect("failed to create Reader");
618 let mut writer = VirtioFsWriter::new(&memory, chain).expect("failed to create Writer");
619
620 assert_eq!(reader.bytes_read(), 0);
621 assert_eq!(writer.bytes_written(), 0);
622
623 let mut buffer = Vec::with_capacity(200);
624
625 assert_eq!(
626 reader
627 .read_to_end(&mut buffer)
628 .expect("read should not fail here"),
629 128
630 );
631
632 writer
634 .write_all(&buffer[..68])
635 .expect("write should not fail here");
636
637 assert_eq!(reader.available_bytes(), 0);
638 assert_eq!(reader.bytes_read(), 128);
639 assert_eq!(writer.available_bytes(), 0);
640 assert_eq!(writer.bytes_written(), 68);
641 }
642
643 #[test]
644 fn reader_writer_shattered_object() {
645 use DescriptorType::*;
646
647 let memory_start_addr = GuestAddress(0x0);
648 let memory = GuestMemoryMmap::from_ranges(&vec![(memory_start_addr, 0x10000)]).unwrap();
649
650 let secret: Le32 = 0x12345678.into();
651
652 let chain_writer = create_descriptor_chain(
654 &memory,
655 GuestAddress(0x0),
656 GuestAddress(0x100),
657 vec![(Writable, 1), (Writable, 1), (Writable, 1), (Writable, 1)],
658 123,
659 )
660 .expect("create_descriptor_chain failed");
661 let mut writer =
662 VirtioFsWriter::new(&memory, chain_writer).expect("failed to create Writer");
663 assert!(writer.flush().is_ok());
664 if let Err(_) = writer.write_obj(secret) {
665 panic!("write_obj should not fail here");
666 }
667 assert!(writer.flush().is_ok());
668
669 let chain_reader = create_descriptor_chain(
671 &memory,
672 GuestAddress(0x0),
673 GuestAddress(0x100),
674 vec![(Readable, 1), (Readable, 1), (Readable, 1), (Readable, 1)],
675 123,
676 )
677 .expect("create_descriptor_chain failed");
678 let mut reader = Reader::new(&memory, chain_reader).expect("failed to create Reader");
679 match reader.read_obj::<Le32>() {
680 Err(_) => panic!("read_obj should not fail here"),
681 Ok(read_secret) => assert_eq!(read_secret, secret),
682 }
683 }
684
685 #[test]
686 fn reader_unexpected_eof() {
687 use DescriptorType::*;
688
689 let memory_start_addr = GuestAddress(0x0);
690 let memory = GuestMemoryMmap::from_ranges(&vec![(memory_start_addr, 0x10000)]).unwrap();
691
692 let chain = create_descriptor_chain(
693 &memory,
694 GuestAddress(0x0),
695 GuestAddress(0x100),
696 vec![(Readable, 256), (Readable, 256)],
697 0,
698 )
699 .expect("create_descriptor_chain failed");
700
701 let mut reader = Reader::new(&memory, chain).expect("failed to create Reader");
702
703 let mut buf = Vec::with_capacity(1024);
704 buf.resize(1024, 0);
705
706 assert_eq!(
707 reader
708 .read_exact(&mut buf[..])
709 .expect_err("read more bytes than available")
710 .kind(),
711 io::ErrorKind::UnexpectedEof
712 );
713 }
714
715 #[test]
716 fn split_border() {
717 use DescriptorType::*;
718
719 let memory_start_addr = GuestAddress(0x0);
720 let memory = GuestMemoryMmap::from_ranges(&vec![(memory_start_addr, 0x10000)]).unwrap();
721
722 let chain = create_descriptor_chain(
723 &memory,
724 GuestAddress(0x0),
725 GuestAddress(0x100),
726 vec![
727 (Readable, 16),
728 (Readable, 16),
729 (Readable, 96),
730 (Writable, 64),
731 (Writable, 1),
732 (Writable, 3),
733 ],
734 0,
735 )
736 .expect("create_descriptor_chain failed");
737 let mut reader = Reader::new(&memory, chain).expect("failed to create Reader");
738
739 let other = reader.split_at(32).expect("failed to split Reader");
740 assert_eq!(reader.available_bytes(), 32);
741 assert_eq!(other.available_bytes(), 96);
742 }
743
744 #[test]
745 fn split_middle() {
746 use DescriptorType::*;
747
748 let memory_start_addr = GuestAddress(0x0);
749 let memory = GuestMemoryMmap::from_ranges(&vec![(memory_start_addr, 0x10000)]).unwrap();
750
751 let chain = create_descriptor_chain(
752 &memory,
753 GuestAddress(0x0),
754 GuestAddress(0x100),
755 vec![
756 (Readable, 16),
757 (Readable, 16),
758 (Readable, 96),
759 (Writable, 64),
760 (Writable, 1),
761 (Writable, 3),
762 ],
763 0,
764 )
765 .expect("create_descriptor_chain failed");
766 let mut reader = Reader::new(&memory, chain).expect("failed to create Reader");
767
768 let other = reader.split_at(24).expect("failed to split Reader");
769 assert_eq!(reader.available_bytes(), 24);
770 assert_eq!(other.available_bytes(), 104);
771 }
772
773 #[test]
774 fn split_end() {
775 use DescriptorType::*;
776
777 let memory_start_addr = GuestAddress(0x0);
778 let memory = GuestMemoryMmap::from_ranges(&vec![(memory_start_addr, 0x10000)]).unwrap();
779
780 let chain = create_descriptor_chain(
781 &memory,
782 GuestAddress(0x0),
783 GuestAddress(0x100),
784 vec![
785 (Readable, 16),
786 (Readable, 16),
787 (Readable, 96),
788 (Writable, 64),
789 (Writable, 1),
790 (Writable, 3),
791 ],
792 0,
793 )
794 .expect("create_descriptor_chain failed");
795 let mut reader = Reader::new(&memory, chain).expect("failed to create Reader");
796
797 let other = reader.split_at(128).expect("failed to split Reader");
798 assert_eq!(reader.available_bytes(), 128);
799 assert_eq!(other.available_bytes(), 0);
800 }
801
802 #[test]
803 fn split_beginning() {
804 use DescriptorType::*;
805
806 let memory_start_addr = GuestAddress(0x0);
807 let memory = GuestMemoryMmap::from_ranges(&vec![(memory_start_addr, 0x10000)]).unwrap();
808
809 let chain = create_descriptor_chain(
810 &memory,
811 GuestAddress(0x0),
812 GuestAddress(0x100),
813 vec![
814 (Readable, 16),
815 (Readable, 16),
816 (Readable, 96),
817 (Writable, 64),
818 (Writable, 1),
819 (Writable, 3),
820 ],
821 0,
822 )
823 .expect("create_descriptor_chain failed");
824 let mut reader = Reader::new(&memory, chain).expect("failed to create Reader");
825
826 let other = reader.split_at(0).expect("failed to split Reader");
827 assert_eq!(reader.available_bytes(), 0);
828 assert_eq!(other.available_bytes(), 128);
829 }
830
831 #[test]
832 fn split_outofbounds() {
833 use DescriptorType::*;
834
835 let memory_start_addr = GuestAddress(0x0);
836 let memory = GuestMemoryMmap::from_ranges(&vec![(memory_start_addr, 0x10000)]).unwrap();
837
838 let chain = create_descriptor_chain(
839 &memory,
840 GuestAddress(0x0),
841 GuestAddress(0x100),
842 vec![
843 (Readable, 16),
844 (Readable, 16),
845 (Readable, 96),
846 (Writable, 64),
847 (Writable, 1),
848 (Writable, 3),
849 ],
850 0,
851 )
852 .expect("create_descriptor_chain failed");
853 let mut reader = Reader::new(&memory, chain).expect("failed to create Reader");
854
855 if let Ok(_) = reader.split_at(256) {
856 panic!("successfully split Reader with out of bounds offset");
857 }
858 }
859
860 #[test]
861 fn read_full() {
862 use DescriptorType::*;
863
864 let memory_start_addr = GuestAddress(0x0);
865 let memory = GuestMemoryMmap::from_ranges(&vec![(memory_start_addr, 0x10000)]).unwrap();
866
867 let chain = create_descriptor_chain(
868 &memory,
869 GuestAddress(0x0),
870 GuestAddress(0x100),
871 vec![(Readable, 16), (Readable, 16), (Readable, 16)],
872 0,
873 )
874 .expect("create_descriptor_chain failed");
875 let mut reader = Reader::new(&memory, chain).expect("failed to create Reader");
876
877 let mut buf = vec![0u8; 64];
878 assert_eq!(
879 reader.read(&mut buf[..]).expect("failed to read to buffer"),
880 48
881 );
882 }
883
884 #[test]
885 fn write_full() {
886 use DescriptorType::*;
887
888 let memory_start_addr = GuestAddress(0x0);
889 let memory = GuestMemoryMmap::from_ranges(&vec![(memory_start_addr, 0x10000)]).unwrap();
890
891 let chain = create_descriptor_chain(
892 &memory,
893 GuestAddress(0x0),
894 GuestAddress(0x100),
895 vec![(Writable, 16), (Writable, 16), (Writable, 16)],
896 0,
897 )
898 .expect("create_descriptor_chain failed");
899 let mut writer = VirtioFsWriter::new(&memory, chain).expect("failed to create Writer");
900
901 let buf = vec![0xdeu8; 40];
902 assert_eq!(
903 writer.write(&buf[..]).expect("failed to write from buffer"),
904 40
905 );
906 assert_eq!(writer.available_bytes(), 8);
907 assert_eq!(writer.bytes_written(), 40);
908
909 writer.write(&buf[..]).unwrap_err();
911 assert_eq!(writer.available_bytes(), 8);
912 assert_eq!(writer.bytes_written(), 40);
913 }
914
915 #[test]
916 fn write_vectored() {
917 use DescriptorType::*;
918
919 let memory_start_addr = GuestAddress(0x0);
920 let memory = GuestMemoryMmap::from_ranges(&vec![(memory_start_addr, 0x10000)]).unwrap();
921
922 let chain = create_descriptor_chain(
923 &memory,
924 GuestAddress(0x0),
925 GuestAddress(0x100),
926 vec![(Writable, 16), (Writable, 16), (Writable, 16)],
927 0,
928 )
929 .expect("create_descriptor_chain failed");
930 let mut writer = VirtioFsWriter::new(&memory, chain).expect("failed to create Writer");
931
932 let buf = vec![0xdeu8; 48];
933 let slices = [
934 IoSlice::new(&buf[..32]),
935 IoSlice::new(&buf[32..40]),
936 IoSlice::new(&buf[40..]),
937 ];
938 assert_eq!(
939 writer
940 .write_vectored(&slices)
941 .expect("failed to write from buffer"),
942 48
943 );
944 assert_eq!(writer.available_bytes(), 0);
945 assert_eq!(writer.bytes_written(), 48);
946
947 let buf = vec![0xdeu8; 40];
949 writer.write(&buf[..]).unwrap_err();
950 assert_eq!(writer.available_bytes(), 0);
951 assert_eq!(writer.bytes_written(), 48);
952 }
953
954 #[test]
955 fn read_exact_to() {
956 use DescriptorType::*;
957
958 let memory_start_addr = GuestAddress(0x0);
959 let memory = GuestMemoryMmap::from_ranges(&vec![(memory_start_addr, 0x10000)]).unwrap();
960
961 let chain = create_descriptor_chain(
962 &memory,
963 GuestAddress(0x0),
964 GuestAddress(0x100),
965 vec![(Readable, 16), (Readable, 16), (Readable, 16)],
966 0,
967 )
968 .expect("create_descriptor_chain failed");
969 let mut reader = Reader::new(&memory, chain).expect("failed to create Writer");
970
971 let mut file = TempFile::new().unwrap().into_file();
972 reader
973 .read_exact_to(&mut file, 47)
974 .expect("failed to read to file");
975
976 assert_eq!(reader.available_bytes(), 1);
977 assert_eq!(reader.bytes_read(), 47);
978 }
979
980 #[test]
981 fn read_to_at() {
982 use DescriptorType::*;
983
984 let memory_start_addr = GuestAddress(0x0);
985 let memory = GuestMemoryMmap::from_ranges(&vec![(memory_start_addr, 0x10000)]).unwrap();
986
987 let chain = create_descriptor_chain(
988 &memory,
989 GuestAddress(0x0),
990 GuestAddress(0x100),
991 vec![(Readable, 16), (Readable, 16), (Readable, 16)],
992 0,
993 )
994 .expect("create_descriptor_chain failed");
995 let mut reader = Reader::new(&memory, chain).expect("failed to create Writer");
996
997 let mut file = TempFile::new().unwrap().into_file();
998 assert_eq!(
999 reader
1000 .read_to_at(&mut file, 48, 16)
1001 .expect("failed to read to file"),
1002 48
1003 );
1004
1005 assert_eq!(reader.available_bytes(), 0);
1006 assert_eq!(reader.bytes_read(), 48);
1007 }
1008
1009 #[test]
1010 fn write_all_from() {
1011 use DescriptorType::*;
1012
1013 let memory_start_addr = GuestAddress(0x0);
1014 let memory = GuestMemoryMmap::from_ranges(&vec![(memory_start_addr, 0x10000)]).unwrap();
1015
1016 let chain = create_descriptor_chain(
1017 &memory,
1018 GuestAddress(0x0),
1019 GuestAddress(0x100),
1020 vec![(Writable, 16), (Writable, 16), (Writable, 16)],
1021 0,
1022 )
1023 .expect("create_descriptor_chain failed");
1024 let mut writer = VirtioFsWriter::new(&memory, chain).expect("failed to create Writer");
1025
1026 let mut file = TempFile::new().unwrap().into_file();
1027 let buf = vec![0xdeu8; 64];
1028 file.write_all(&buf).unwrap();
1029 file.seek(SeekFrom::Start(0)).unwrap();
1030 writer
1031 .write_all_from(&mut file, 47)
1032 .expect("failed to write from buffer");
1033
1034 assert_eq!(writer.available_bytes(), 1);
1035 assert_eq!(writer.bytes_written(), 47);
1036 }
1037
1038 #[test]
1039 fn write_from_at() {
1040 use DescriptorType::*;
1041
1042 let memory_start_addr = GuestAddress(0x0);
1043 let memory = GuestMemoryMmap::from_ranges(&vec![(memory_start_addr, 0x10000)]).unwrap();
1044
1045 let chain = create_descriptor_chain(
1046 &memory,
1047 GuestAddress(0x0),
1048 GuestAddress(0x100),
1049 vec![(Writable, 16), (Writable, 16), (Writable, 16)],
1050 0,
1051 )
1052 .expect("create_descriptor_chain failed");
1053 let mut writer = VirtioFsWriter::new(&memory, chain).expect("failed to create Writer");
1054
1055 let mut file = TempFile::new().unwrap().into_file();
1056 let buf = vec![0xdeu8; 64];
1057 file.write_all(&buf).unwrap();
1058 file.seek(SeekFrom::Start(0)).unwrap();
1059 assert_eq!(
1060 writer
1061 .write_from_at(&mut file, 48, 16)
1062 .expect("failed to write from buffer"),
1063 48
1064 );
1065
1066 assert_eq!(writer.available_bytes(), 0);
1067 assert_eq!(writer.bytes_written(), 48);
1068 }
1069
1070 #[cfg(feature = "async-io")]
1071 mod async_io {
1072 use futures::executor::{block_on, ThreadPool};
1073 use futures::task::SpawnExt;
1074 use ringbahn::drive::demo::DemoDriver;
1075 use std::os::unix::io::AsRawFd;
1076
1077 use super::*;
1078
1079 #[test]
1080 fn async_read_to_at() {
1081 let file = TempFile::new().unwrap().into_file();
1082 let fd = file.as_raw_fd();
1083 let executor = ThreadPool::new().unwrap();
1084
1085 let handle = executor
1086 .spawn_with_handle(async move {
1087 use DescriptorType::*;
1088
1089 let memory_start_addr = GuestAddress(0x0);
1090 let memory =
1091 GuestMemoryMmap::from_ranges(&vec![(memory_start_addr, 0x10000)]).unwrap();
1092
1093 let chain = create_descriptor_chain(
1094 &memory,
1095 GuestAddress(0x0),
1096 GuestAddress(0x100),
1097 vec![(Readable, 16), (Readable, 16), (Readable, 16)],
1098 0,
1099 )
1100 .expect("create_descriptor_chain failed");
1101 let mut reader = Reader::new(&memory, chain).expect("failed to create Writer");
1102 let drive = DemoDriver::default();
1103
1104 reader.async_read_to_at(drive, fd, 48, 16).await
1105 })
1106 .unwrap();
1107 assert_eq!(block_on(handle).unwrap(), 48);
1108 }
1109
1110 #[test]
1111 fn async_write() {
1112 let executor = ThreadPool::new().unwrap();
1113 let handle = executor
1114 .spawn_with_handle(async move {
1115 use DescriptorType::*;
1116
1117 let memory_start_addr = GuestAddress(0x0);
1118 let memory =
1119 GuestMemoryMmap::from_ranges(&vec![(memory_start_addr, 0x10000)]).unwrap();
1120
1121 let chain = create_descriptor_chain(
1122 &memory,
1123 GuestAddress(0x0),
1124 GuestAddress(0x100),
1125 vec![(Writable, 16), (Writable, 16), (Writable, 16)],
1126 0,
1127 )
1128 .expect("create_descriptor_chain failed");
1129 let mut writer =
1130 VirtioFsWriter::new(&memory, chain).expect("failed to create Writer");
1131 let drive = DemoDriver::default();
1132 let buf = vec![0xdeu8; 64];
1133
1134 writer.async_write(drive, &buf[..]).await
1135 })
1136 .unwrap();
1137 block_on(handle).unwrap_err();
1139
1140 let handle = executor
1141 .spawn_with_handle(async move {
1142 use DescriptorType::*;
1143
1144 let memory_start_addr = GuestAddress(0x0);
1145 let memory =
1146 GuestMemoryMmap::from_ranges(&vec![(memory_start_addr, 0x10000)]).unwrap();
1147
1148 let chain = create_descriptor_chain(
1149 &memory,
1150 GuestAddress(0x0),
1151 GuestAddress(0x100),
1152 vec![(Writable, 16), (Writable, 16), (Writable, 16)],
1153 0,
1154 )
1155 .expect("create_descriptor_chain failed");
1156 let mut writer =
1157 VirtioFsWriter::new(&memory, chain).expect("failed to create Writer");
1158 let drive = DemoDriver::default();
1159
1160 let buf = vec![0xdeu8; 48];
1161 writer.async_write(drive, &buf[..]).await
1162 })
1163 .unwrap();
1164
1165 assert_eq!(block_on(handle).unwrap(), 48);
1166 }
1167
1168 #[test]
1169 fn async_write2() {
1170 let executor = ThreadPool::new().unwrap();
1171 let handle = executor
1172 .spawn_with_handle(async move {
1173 use DescriptorType::*;
1174
1175 let memory_start_addr = GuestAddress(0x0);
1176 let memory =
1177 GuestMemoryMmap::from_ranges(&vec![(memory_start_addr, 0x10000)]).unwrap();
1178
1179 let chain = create_descriptor_chain(
1180 &memory,
1181 GuestAddress(0x0),
1182 GuestAddress(0x100),
1183 vec![(Writable, 16), (Writable, 16), (Writable, 16)],
1184 0,
1185 )
1186 .expect("create_descriptor_chain failed");
1187 let mut writer =
1188 VirtioFsWriter::new(&memory, chain).expect("failed to create Writer");
1189 let drive = DemoDriver::default();
1190 let buf = vec![0xdeu8; 48];
1191
1192 writer.async_write2(drive, &buf[..32], &buf[32..]).await
1193 })
1194 .unwrap();
1195
1196 assert_eq!(block_on(handle).unwrap(), 48);
1197 }
1198
1199 #[test]
1200 fn async_write3() {
1201 let executor = ThreadPool::new().unwrap();
1202 let handle = executor
1203 .spawn_with_handle(async move {
1204 use DescriptorType::*;
1205
1206 let memory_start_addr = GuestAddress(0x0);
1207 let memory =
1208 GuestMemoryMmap::from_ranges(&vec![(memory_start_addr, 0x10000)]).unwrap();
1209
1210 let chain = create_descriptor_chain(
1211 &memory,
1212 GuestAddress(0x0),
1213 GuestAddress(0x100),
1214 vec![(Writable, 16), (Writable, 16), (Writable, 16)],
1215 0,
1216 )
1217 .expect("create_descriptor_chain failed");
1218 let mut writer =
1219 VirtioFsWriter::new(&memory, chain).expect("failed to create Writer");
1220 let drive = DemoDriver::default();
1221 let buf = vec![0xdeu8; 48];
1222
1223 writer
1224 .async_write3(drive, &buf[..32], &buf[32..40], &buf[40..])
1225 .await
1226 })
1227 .unwrap();
1228
1229 assert_eq!(block_on(handle).unwrap(), 48);
1230 }
1231
1232 #[test]
1233 fn async_write_from_at() {
1234 let mut file = TempFile::new().unwrap().into_file();
1235 let fd = file.as_raw_fd();
1236 let buf = vec![0xdeu8; 64];
1237
1238 file.write_all(&buf).unwrap();
1239 file.seek(SeekFrom::Start(0)).unwrap();
1240
1241 let executor = ThreadPool::new().unwrap();
1242 let handle = executor
1243 .spawn_with_handle(async move {
1244 use DescriptorType::*;
1245
1246 let memory_start_addr = GuestAddress(0x0);
1247 let memory =
1248 GuestMemoryMmap::from_ranges(&vec![(memory_start_addr, 0x10000)]).unwrap();
1249
1250 let chain = create_descriptor_chain(
1251 &memory,
1252 GuestAddress(0x0),
1253 GuestAddress(0x100),
1254 vec![(Writable, 16), (Writable, 16), (Writable, 16)],
1255 0,
1256 )
1257 .expect("create_descriptor_chain failed");
1258 let mut writer =
1259 VirtioFsWriter::new(&memory, chain).expect("failed to create Writer");
1260 let drive = DemoDriver::default();
1261
1262 writer.async_write_from_at(drive, fd, 40, 16).await
1263 })
1264 .unwrap();
1265
1266 assert_eq!(block_on(handle).unwrap(), 40);
1267 }
1268 }
1269}