Skip to content

Commit e3098cd

Browse files
committed
Import from Firecracker
Signed-off-by: Adrian Catangiu <[email protected]>
1 parent 107cb37 commit e3098cd

File tree

6 files changed

+1899
-0
lines changed

6 files changed

+1899
-0
lines changed

Cargo.toml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
[package]
2+
name = "versionize"
3+
version = "0.1.0"
4+
authors = ["Amazon Firecracker team <[email protected]>"]
5+
6+
[dependencies]
7+
serde = ">=1.0.27"
8+
serde_derive = ">=1.0.27"
9+
bincode = "1.2.1"
10+
versionize_derive = { git = "https://github.com/firecracker-microvm/versionize_derive" }
11+
crc64 = "1.0.0"
12+
vm-memory = { version = ">=0.2.0" }
13+
vmm-sys-util = ">=0.4.0"
14+
15+
[build-dependencies]
16+
proc-macro2 = ">=1.0"
17+
quote = ">=1.0"
18+
syn = { version = ">=1.0.13", features=["default","full"]}
19+
versionize_derive = { git = "https://github.com/firecracker-microvm/versionize_derive" }

src/crc.rs

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
// Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
//! Implements readers and writers that compute a CRC64 checksum on the bytes
5+
//! read/written.
6+
7+
use crc64::crc64;
8+
use std::io::{Read, Write};
9+
10+
/// Computes CRC64 checksums from read bytes.
11+
pub struct CRC64Reader<T> {
12+
reader: T,
13+
crc64: u64,
14+
}
15+
16+
impl<T> CRC64Reader<T>
17+
where
18+
T: Read,
19+
{
20+
/// Create a new reader.
21+
pub fn new(reader: T) -> Self {
22+
CRC64Reader { crc64: 0, reader }
23+
}
24+
/// Returns the current checksum value.
25+
pub fn checksum(&self) -> u64 {
26+
self.crc64
27+
}
28+
}
29+
30+
impl<T> Read for CRC64Reader<T>
31+
where
32+
T: Read,
33+
{
34+
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
35+
let bytes_read = self.reader.read(buf)?;
36+
self.crc64 = crc64(self.crc64, &buf[..bytes_read]);
37+
Ok(bytes_read)
38+
}
39+
}
40+
41+
/// Computes CRC64 checksums from written bytes.
42+
pub struct CRC64Writer<T> {
43+
writer: T,
44+
crc64: u64,
45+
}
46+
47+
impl<T> CRC64Writer<T>
48+
where
49+
T: Write,
50+
{
51+
/// Create a new writer.
52+
pub fn new(writer: T) -> Self {
53+
CRC64Writer { crc64: 0, writer }
54+
}
55+
56+
/// Returns the current checksum value.
57+
pub fn checksum(&self) -> u64 {
58+
self.crc64
59+
}
60+
}
61+
62+
impl<T> Write for CRC64Writer<T>
63+
where
64+
T: Write,
65+
{
66+
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
67+
let bytes_written = self.writer.write(buf)?;
68+
self.crc64 = crc64(self.crc64, &buf[..bytes_written]);
69+
Ok(bytes_written)
70+
}
71+
72+
fn flush(&mut self) -> std::io::Result<()> {
73+
self.writer.flush()
74+
}
75+
}
76+
77+
#[cfg(test)]
78+
mod tests {
79+
use super::{CRC64Reader, CRC64Writer, Read, Write};
80+
81+
#[test]
82+
fn test_crc_new() {
83+
let buf = vec![1; 5];
84+
let mut slice = buf.as_slice();
85+
let crc_reader = CRC64Reader::new(&mut slice);
86+
assert_eq!(crc_reader.crc64, 0);
87+
assert_eq!(crc_reader.reader, &[1; 5]);
88+
assert_eq!(crc_reader.checksum(), 0);
89+
90+
let mut buf = vec![0; 5];
91+
let mut slice = buf.as_mut_slice();
92+
let crc_writer = CRC64Writer::new(&mut slice);
93+
assert_eq!(crc_writer.crc64, 0);
94+
assert_eq!(crc_writer.writer, &[0; 5]);
95+
assert_eq!(crc_writer.checksum(), 0);
96+
}
97+
98+
#[test]
99+
fn test_crc_read() {
100+
let buf = vec![1, 2, 3, 4, 5];
101+
let mut read_buf = vec![0; 16];
102+
103+
let mut slice = buf.as_slice();
104+
let mut crc_reader = CRC64Reader::new(&mut slice);
105+
crc_reader.read_to_end(&mut read_buf).unwrap();
106+
assert_eq!(crc_reader.checksum(), 0xFB04_60DE_0638_3654);
107+
assert_eq!(crc_reader.checksum(), crc_reader.crc64);
108+
}
109+
110+
#[test]
111+
fn test_crc_write() {
112+
let mut buf = vec![0; 16];
113+
let write_buf = vec![123; 16];
114+
115+
let mut slice = buf.as_mut_slice();
116+
let mut crc_writer = CRC64Writer::new(&mut slice);
117+
crc_writer.write_all(&write_buf.as_slice()).unwrap();
118+
crc_writer.flush().unwrap();
119+
assert_eq!(crc_writer.checksum(), 0x29D5_3572_1632_6566);
120+
assert_eq!(crc_writer.checksum(), crc_writer.crc64);
121+
}
122+
}

src/lib.rs

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
// Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
#![deny(missing_docs)]
4+
5+
//! Provides version tolerant serialization and deserialization facilities and
6+
//! implements a persistent storage format for Firecracker state snapshots.
7+
//! The `Versionize` trait defines a generic interface that serializable state structures
8+
//! need to implement.
9+
//!
10+
//! `VersionMap` exposes an API that maps the individual structure versions to
11+
//! a root version (see above: the data version for example). This mapping is required
12+
//! both when serializing or deserializing structures as we need to know which version of structure
13+
//! to serialize for a given target **data version
14+
//!
15+
extern crate bincode;
16+
extern crate crc64;
17+
extern crate serde;
18+
extern crate serde_derive;
19+
extern crate versionize_derive;
20+
extern crate vm_memory;
21+
extern crate vmm_sys_util;
22+
23+
pub mod crc;
24+
mod primitives;
25+
pub mod version_map;
26+
27+
use std::any::TypeId;
28+
use std::io::{Read, Write};
29+
pub use version_map::VersionMap;
30+
use versionize_derive::Versionize;
31+
32+
/// Versioned serialization error definitions.
33+
#[derive(Debug, PartialEq)]
34+
pub enum VersionizeError {
35+
/// An IO error occured.
36+
Io(i32),
37+
/// A serialization error.
38+
Serialize(String),
39+
/// A deserialization error.
40+
Deserialize(String),
41+
/// A user generated semantic error.
42+
Semantic(String),
43+
}
44+
45+
/// Versioned serialization/deserialization result.
46+
pub type VersionizeResult<T> = std::result::Result<T, VersionizeError>;
47+
48+
/// Trait that provides an interface for version aware serialization and deserialization.
49+
pub trait Versionize {
50+
/// Serializes `self` to `target_verion` using the specficifed `writer` and `version_map`.
51+
fn serialize<W: Write>(
52+
&self,
53+
writer: &mut W,
54+
version_map: &VersionMap,
55+
target_version: u16,
56+
) -> VersionizeResult<()>;
57+
58+
/// Returns a new instance of `Self` by deserialzing from `source_version` using the
59+
/// specficifed `reader` and `version_map`.
60+
fn deserialize<R: Read>(
61+
reader: &mut R,
62+
version_map: &VersionMap,
63+
source_version: u16,
64+
) -> VersionizeResult<Self>
65+
where
66+
Self: Sized;
67+
68+
/// Returns the `Self` type id.
69+
fn type_id() -> std::any::TypeId
70+
where
71+
Self: 'static,
72+
{
73+
TypeId::of::<Self>()
74+
}
75+
76+
/// Returns latest `Self` version number.
77+
fn version() -> u16;
78+
}

0 commit comments

Comments
 (0)