mirror of
https://github.com/rustfs/rustfs.git
synced 2026-08-25 05:26:50 +00:00
fix(filemeta): accept nil legacy pool metadata (#2459)
This commit is contained in:
@@ -1133,6 +1133,32 @@ mod test {
|
|||||||
assert!(fi.is_latest);
|
assert!(fi.is_latest);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_issue_2434_legacy_meta_v2_pool_compatibility() {
|
||||||
|
let data = create_issue_2434_legacy_meta_v2_pool_xlmeta().expect("Failed to load issue #2434 pool fixture");
|
||||||
|
let (major, minor, header_ver, meta_ver) = FileMeta::read_format_versions(&data).unwrap();
|
||||||
|
assert_eq!((major, minor, header_ver, meta_ver), (1, 3, 3, 2));
|
||||||
|
|
||||||
|
let fm = FileMeta::load(&data).expect("Failed to parse legacy issue #2434 pool xl.meta");
|
||||||
|
assert_eq!(fm.meta_ver, 2);
|
||||||
|
assert_eq!(fm.versions.len(), 1);
|
||||||
|
assert_eq!(fm.versions[0].header.version_type, VersionType::Object);
|
||||||
|
|
||||||
|
let fi = fm
|
||||||
|
.into_fileinfo(".rustfs.sys", "pool.bin", "", true, false, true)
|
||||||
|
.expect("Failed to extract file info from legacy issue #2434 pool xl.meta");
|
||||||
|
assert_eq!(fi.size, 48);
|
||||||
|
assert_eq!(fi.num_versions, 1);
|
||||||
|
assert_eq!(fi.version_id, None);
|
||||||
|
assert_eq!(fi.metadata.get("etag").map(String::as_str), Some("8d270d7a184cfa30cc0bf09ea74fd964"));
|
||||||
|
assert_eq!(
|
||||||
|
fi.data_dir.map(|id| id.to_string()).as_deref(),
|
||||||
|
Some("2bcefaca-44dd-4f01-a79e-63eeb0dda396")
|
||||||
|
);
|
||||||
|
assert!(fi.uses_legacy_checksum);
|
||||||
|
assert!(fi.is_latest);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_legacy_v1_object_xlmeta_compatibility() {
|
fn test_legacy_v1_object_xlmeta_compatibility() {
|
||||||
let data = create_legacy_v1_object_xlmeta().expect("Failed to create legacy v1 object xl.meta");
|
let data = create_legacy_v1_object_xlmeta().expect("Failed to create legacy v1 object xl.meta");
|
||||||
|
|||||||
@@ -54,6 +54,62 @@ fn read_msgp_bin<R: std::io::Read>(rd: &mut R) -> Result<Vec<u8>> {
|
|||||||
Ok(buf)
|
Ok(buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn deserialize_legacy_uuid_bytes<'de, D>(deserializer: D) -> std::result::Result<Vec<u8>, D::Error>
|
||||||
|
where
|
||||||
|
D: serde::Deserializer<'de>,
|
||||||
|
{
|
||||||
|
struct LegacyUuidBytesVisitor;
|
||||||
|
|
||||||
|
impl<'de> serde::de::Visitor<'de> for LegacyUuidBytesVisitor {
|
||||||
|
type Value = Vec<u8>;
|
||||||
|
|
||||||
|
fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
formatter.write_str("nil or binary UUID bytes")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_none<E>(self) -> std::result::Result<Self::Value, E>
|
||||||
|
where
|
||||||
|
E: serde::de::Error,
|
||||||
|
{
|
||||||
|
Ok(Vec::new())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_unit<E>(self) -> std::result::Result<Self::Value, E>
|
||||||
|
where
|
||||||
|
E: serde::de::Error,
|
||||||
|
{
|
||||||
|
Ok(Vec::new())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_bytes<E>(self, value: &[u8]) -> std::result::Result<Self::Value, E>
|
||||||
|
where
|
||||||
|
E: serde::de::Error,
|
||||||
|
{
|
||||||
|
Ok(value.to_vec())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_byte_buf<E>(self, value: Vec<u8>) -> std::result::Result<Self::Value, E>
|
||||||
|
where
|
||||||
|
E: serde::de::Error,
|
||||||
|
{
|
||||||
|
Ok(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_seq<A>(self, mut seq: A) -> std::result::Result<Self::Value, A::Error>
|
||||||
|
where
|
||||||
|
A: serde::de::SeqAccess<'de>,
|
||||||
|
{
|
||||||
|
let mut value = Vec::new();
|
||||||
|
while let Some(byte) = seq.next_element()? {
|
||||||
|
value.push(byte);
|
||||||
|
}
|
||||||
|
Ok(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
deserializer.deserialize_any(LegacyUuidBytesVisitor)
|
||||||
|
}
|
||||||
|
|
||||||
fn decode_msgp_time_payload(ext_type: i8, payload: &[u8]) -> Result<OffsetDateTime> {
|
fn decode_msgp_time_payload(ext_type: i8, payload: &[u8]) -> Result<OffsetDateTime> {
|
||||||
let (secs, nanos) = match (ext_type, payload.len()) {
|
let (secs, nanos) = match (ext_type, payload.len()) {
|
||||||
(MSGPACK_TIME_EXT_LEGACY, 12) => {
|
(MSGPACK_TIME_EXT_LEGACY, 12) => {
|
||||||
@@ -179,7 +235,9 @@ struct LegacyMetaV2Version {
|
|||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
struct LegacyMetaV2Object {
|
struct LegacyMetaV2Object {
|
||||||
|
#[serde(default, deserialize_with = "deserialize_legacy_uuid_bytes")]
|
||||||
version_id: Vec<u8>,
|
version_id: Vec<u8>,
|
||||||
|
#[serde(default, deserialize_with = "deserialize_legacy_uuid_bytes")]
|
||||||
data_dir: Vec<u8>,
|
data_dir: Vec<u8>,
|
||||||
erasure_algorithm: String,
|
erasure_algorithm: String,
|
||||||
erasure_m: usize,
|
erasure_m: usize,
|
||||||
@@ -201,6 +259,7 @@ struct LegacyMetaV2Object {
|
|||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
struct LegacyMetaV2DeleteMarker {
|
struct LegacyMetaV2DeleteMarker {
|
||||||
|
#[serde(default, deserialize_with = "deserialize_legacy_uuid_bytes")]
|
||||||
version_id: Vec<u8>,
|
version_id: Vec<u8>,
|
||||||
mod_time: Option<OffsetDateTime>,
|
mod_time: Option<OffsetDateTime>,
|
||||||
meta_sys: HashMap<String, Vec<u8>>,
|
meta_sys: HashMap<String, Vec<u8>>,
|
||||||
|
|||||||
@@ -145,6 +145,11 @@ pub fn create_issue_2265_legacy_meta_v2_config_xlmeta() -> Result<Vec<u8>> {
|
|||||||
decode_hex_fixture(include_str!("../tests/fixtures/issue_2265_legacy_meta_v2_config.hex"))
|
decode_hex_fixture(include_str!("../tests/fixtures/issue_2265_legacy_meta_v2_config.hex"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Legacy pool xl.meta captured in issue #2434. Header/meta versions are 3/2.
|
||||||
|
pub fn create_issue_2434_legacy_meta_v2_pool_xlmeta() -> Result<Vec<u8>> {
|
||||||
|
decode_hex_fixture(include_str!("../tests/fixtures/issue_2434_legacy_meta_v2_pool.hex"))
|
||||||
|
}
|
||||||
|
|
||||||
fn write_legacy_time(wr: &mut Vec<u8>, ts: OffsetDateTime) {
|
fn write_legacy_time(wr: &mut Vec<u8>, ts: OffsetDateTime) {
|
||||||
wr.push(MSGPACK_EXT8);
|
wr.push(MSGPACK_EXT8);
|
||||||
wr.push(12);
|
wr.push(12);
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
584c322001000300c6000000d6030201c42697c41000000000000000000000000000000000d3184f6c224d6172f1c4040000000001020001c4a994a64f626a656374dc0012c0c4102bcefaca44dd4f01a79e63eeb0dda396ab52656564536f6c6f6d6f6e0100ce00100000019101ab4869676877617948617368910191d92038643237306437613138346366613330636330626630396561373466643936349130913091c4003099cd07e9ccba112f36ce26f10ef10000008081a465746167d9203864323730643761313834636661333063633062663039656137346664393634c000ce66d2a556
|
||||||
Reference in New Issue
Block a user