1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
// #![feature(async_drop)] -- enable with async-drop
// expect nightly for doc
//! Provides access to VM image formats.
//!
//! Simple example (requires the `sync-wrappers` feature):
//! ```no_run
//! # #[cfg(feature = "sync-wrappers")]
//! # || -> std::io::Result<()> {
//! use imago::file::File;
//! use imago::qcow2::Qcow2;
//! use imago::{FormatDriverBuilder, PermissiveImplicitOpenGate, SyncFormatAccess};
//! use std::fs::OpenOptions;
//!
//! // Produce read-only qcow2 instance using purely `File` for storage
//! let mut qcow2 = Qcow2::<File>::builder_path("image.qcow2")
//! .open_sync(PermissiveImplicitOpenGate::default())?;
//!
//! let qcow2 = SyncFormatAccess::new(qcow2)?;
//!
//! let mut buf = vec![0u8; 512];
//! qcow2.read(&mut buf, 0)?;
//! # Ok::<(), std::io::Error>(())
//! # };
//! ```
//!
//! Another example, using the native async interface instead of sync wrapper functions, explicitly
//! overriding the implicit references contained in qcow2 files, and showcasing using different
//! types of storage (specifically normal files and null storage):
//! ```no_run
//! # let _ = async {
//! use imago::file::File;
//! use imago::null::Null;
//! use imago::qcow2::Qcow2;
//! use imago::raw::Raw;
//! use imago::{
//! DenyImplicitOpenGate, DynStorage, FormatAccess, FormatDriverBuilder,
//! PermissiveImplicitOpenGate, Storage, StorageOpenOptions,
//! };
//! use std::sync::Arc;
//!
//! // Produce qcow2 instance with arbitrary (and potentially mixed) storage instances
//! // (By using `Box<dyn DynStorage>` as the `Storage` type.)
//!
//! let backing_storage: Box<dyn DynStorage> = Box::new(Null::new(0));
//! let backing = Raw::builder(backing_storage)
//! .open(DenyImplicitOpenGate::default())
//! .await?;
//! let backing = Arc::new(FormatAccess::new(backing));
//!
//! // `Box<dyn DynStorage>::open()` defaults to using the `imago::file::File` driver, so we can
//! // use paths with `Box<dyn DynStorage>`, too.
//! // Despite explicitly setting a backing image, we still need `PermissiveImplicitOpenGate`
//! // instead of `DenyImplicitOpenGate`, because `builder_path()` will need to implicitly open
//! // that storage object. Passing an explicitly opened storage object via `builder()` would
//! // remedy that.
//! let qcow2 = Qcow2::builder_path("image.qcow2")
//! .storage_open_options(StorageOpenOptions::new().direct(true))
//! .write(true)
//! .backing(Some(Arc::clone(&backing)))
//! .open(PermissiveImplicitOpenGate::default())
//! .await?;
//!
//! let qcow2 = FormatAccess::new(qcow2);
//!
//! let mut buf = vec![0u8; 512];
//! qcow2.read(&mut buf, 0).await?;
//!
//! qcow2.flush().await?;
//! # Ok::<(), std::io::Error>(())
//! # };
//! ```
//!
//! # Flushing
//!
//! Given that `AsyncDrop` is not stable yet (and probably will not be stable for a long time),
//! callers must ensure that images are properly flushed before dropping them, i.e. call
//! `.flush().await` on any image that is not read-only.
//!
//! (The synchronous wrapper [`SyncFormatAccess`] does perform a synchronous flush in its `Drop`
//! implementation.)
//!
//! # Features
//!
//! - `sync-wrappers`: Provide synchronous wrappers for the native `async` interface. Note that
//! these build a `tokio` runtime in which they run the `async` functions, so using the `async`
//! interface is definitely preferred.
//!
//! - `vm-memory`: Provide conversion functions
//! [`IoVector::from_volatile_slice`](io_buffers::IoVector::from_volatile_slice) and
//! [`IoVectorMut::from_volatile_slice`](io_buffers::IoVectorMut::from_volatile_slice) to convert
//! the vm-memory crate’s `[VolatileSlice]` arrays into imago’s native I/O vectors.
pub use ;
pub use ;
pub use ShallowMapping;
pub use ;
pub use SyncFormatAccess;
pub use StorageExt;
pub use ;