]>
Commit | Line | Data |
---|---|---|
f47e0357 DM |
1 | //! File format definitions and implementations for data written to |
2 | //! tapes | |
3 | ||
b2065dc7 WB |
4 | use std::collections::HashMap; |
5 | ||
b2065dc7 WB |
6 | use endian_trait::Endian; |
7 | use serde::{Deserialize, Serialize}; | |
8 | ||
6ef1b649 | 9 | use proxmox_uuid::Uuid; |
b2065dc7 WB |
10 | |
11 | use pbs_api_types::Fingerprint; | |
12 | ||
f47e0357 DM |
13 | mod chunk_archive; |
14 | pub use chunk_archive::*; | |
15 | ||
16 | mod snapshot_archive; | |
17 | pub use snapshot_archive::*; | |
edda5039 | 18 | |
32b75d36 DM |
19 | mod catalog_archive; |
20 | pub use catalog_archive::*; | |
21 | ||
983e929e DM |
22 | mod multi_volume_writer; |
23 | pub use multi_volume_writer::*; | |
24 | ||
25 | mod multi_volume_reader; | |
26 | pub use multi_volume_reader::*; | |
27 | ||
8c15560b | 28 | // openssl::sha::sha256(b"Proxmox Backup Tape Label v1.0")[0..8]; |
a78348ac | 29 | pub const PROXMOX_BACKUP_MEDIA_LABEL_MAGIC_1_0: [u8; 8] = [42, 5, 191, 60, 176, 48, 170, 57]; |
8c15560b DM |
30 | // openssl::sha::sha256(b"Proxmox Backup MediaSet Label v1.0") |
31 | pub const PROXMOX_BACKUP_MEDIA_SET_LABEL_MAGIC_1_0: [u8; 8] = [8, 96, 99, 249, 47, 151, 83, 216]; | |
32 | ||
33 | // openssl::sha::sha256(b"Proxmox Backup Chunk Archive v1.0")[0..8] | |
54722aca | 34 | // only used in unreleased version - no longer supported |
8c15560b | 35 | pub const PROXMOX_BACKUP_CHUNK_ARCHIVE_MAGIC_1_0: [u8; 8] = [62, 173, 167, 95, 49, 76, 6, 110]; |
54722aca DM |
36 | // openssl::sha::sha256(b"Proxmox Backup Chunk Archive v1.1")[0..8] |
37 | pub const PROXMOX_BACKUP_CHUNK_ARCHIVE_MAGIC_1_1: [u8; 8] = [109, 49, 99, 109, 215, 2, 131, 191]; | |
38 | ||
8c15560b DM |
39 | // openssl::sha::sha256(b"Proxmox Backup Chunk Archive Entry v1.0")[0..8] |
40 | pub const PROXMOX_BACKUP_CHUNK_ARCHIVE_ENTRY_MAGIC_1_0: [u8; 8] = [72, 87, 109, 242, 222, 66, 143, 220]; | |
41 | ||
42 | // openssl::sha::sha256(b"Proxmox Backup Snapshot Archive v1.0")[0..8]; | |
54722aca | 43 | // only used in unreleased version - no longer supported |
8c15560b | 44 | pub const PROXMOX_BACKUP_SNAPSHOT_ARCHIVE_MAGIC_1_0: [u8; 8] = [9, 182, 2, 31, 125, 232, 114, 133]; |
54722aca DM |
45 | // openssl::sha::sha256(b"Proxmox Backup Snapshot Archive v1.1")[0..8]; |
46 | pub const PROXMOX_BACKUP_SNAPSHOT_ARCHIVE_MAGIC_1_1: [u8; 8] = [218, 22, 21, 208, 17, 226, 154, 98]; | |
8c15560b | 47 | |
6ee30355 DM |
48 | // openssl::sha::sha256(b"Proxmox Backup Catalog Archive v1.0")[0..8]; |
49 | pub const PROXMOX_BACKUP_CATALOG_ARCHIVE_MAGIC_1_0: [u8; 8] = [183, 207, 199, 37, 158, 153, 30, 115]; | |
50 | ||
ac461bd6 | 51 | lazy_static::lazy_static!{ |
f47e0357 DM |
52 | // Map content magic numbers to human readable names. |
53 | static ref PROXMOX_TAPE_CONTENT_NAME: HashMap<&'static [u8;8], &'static str> = { | |
ac461bd6 | 54 | let mut map = HashMap::new(); |
a78348ac | 55 | map.insert(&PROXMOX_BACKUP_MEDIA_LABEL_MAGIC_1_0, "Proxmox Backup Tape Label v1.0"); |
ac461bd6 DM |
56 | map.insert(&PROXMOX_BACKUP_MEDIA_SET_LABEL_MAGIC_1_0, "Proxmox Backup MediaSet Label v1.0"); |
57 | map.insert(&PROXMOX_BACKUP_CHUNK_ARCHIVE_MAGIC_1_0, "Proxmox Backup Chunk Archive v1.0"); | |
54722aca | 58 | map.insert(&PROXMOX_BACKUP_CHUNK_ARCHIVE_MAGIC_1_1, "Proxmox Backup Chunk Archive v1.1"); |
ac461bd6 | 59 | map.insert(&PROXMOX_BACKUP_SNAPSHOT_ARCHIVE_MAGIC_1_0, "Proxmox Backup Snapshot Archive v1.0"); |
54722aca | 60 | map.insert(&PROXMOX_BACKUP_SNAPSHOT_ARCHIVE_MAGIC_1_1, "Proxmox Backup Snapshot Archive v1.1"); |
6ee30355 | 61 | map.insert(&PROXMOX_BACKUP_CATALOG_ARCHIVE_MAGIC_1_0, "Proxmox Backup Catalog Archive v1.0"); |
ac461bd6 DM |
62 | map |
63 | }; | |
64 | } | |
65 | ||
f47e0357 DM |
66 | /// Map content magic numbers to human readable names. |
67 | pub fn proxmox_tape_magic_to_text(magic: &[u8; 8]) -> Option<String> { | |
68 | PROXMOX_TAPE_CONTENT_NAME.get(magic).map(|s| String::from(*s)) | |
69 | } | |
70 | ||
8c15560b | 71 | |
54722aca DM |
72 | #[derive(Deserialize, Serialize)] |
73 | /// Header for chunk archives | |
74 | pub struct ChunkArchiveHeader { | |
75 | // Datastore name | |
76 | pub store: String, | |
77 | } | |
78 | ||
410611b4 DM |
79 | #[derive(Endian)] |
80 | #[repr(C,packed)] | |
0b7432ae | 81 | /// Header for data blobs inside a chunk archive |
410611b4 | 82 | pub struct ChunkArchiveEntryHeader { |
dd59e3c2 | 83 | /// fixed value `PROXMOX_BACKUP_CHUNK_ARCHIVE_ENTRY_MAGIC_1_0` |
410611b4 | 84 | pub magic: [u8; 8], |
0b7432ae | 85 | /// Chunk digest |
410611b4 | 86 | pub digest: [u8; 32], |
0b7432ae | 87 | /// Chunk size |
410611b4 DM |
88 | pub size: u64, |
89 | } | |
90 | ||
54722aca DM |
91 | #[derive(Deserialize, Serialize)] |
92 | /// Header for snapshot archives | |
93 | pub struct SnapshotArchiveHeader { | |
94 | /// Snapshot name | |
95 | pub snapshot: String, | |
96 | /// Datastore name | |
97 | pub store: String, | |
98 | } | |
99 | ||
237314ad DM |
100 | #[derive(Deserialize, Serialize)] |
101 | /// Header for Catalog archives | |
102 | pub struct CatalogArchiveHeader { | |
103 | /// The uuid of the media the catalog is for | |
104 | pub uuid: Uuid, | |
105 | /// The media set uuid the catalog is for | |
106 | pub media_set_uuid: Uuid, | |
107 | /// Media sequence number | |
108 | pub seq_nr: u64, | |
109 | } | |
110 | ||
8c15560b | 111 | #[derive(Serialize,Deserialize,Clone,Debug)] |
a78348ac | 112 | /// Media Label |
410611b4 | 113 | /// |
a78348ac | 114 | /// Media labels are used to uniquely identify a media. They are |
410611b4 | 115 | /// stored as first file on the tape. |
a78348ac | 116 | pub struct MediaLabel { |
8c15560b DM |
117 | /// Unique ID |
118 | pub uuid: Uuid, | |
8446fbca DM |
119 | /// Media label text (or Barcode) |
120 | pub label_text: String, | |
8c15560b DM |
121 | /// Creation time stamp |
122 | pub ctime: i64, | |
123 | } | |
124 | ||
125 | ||
126 | #[derive(Serialize,Deserialize,Clone,Debug)] | |
dd59e3c2 | 127 | /// `MediaSet` Label |
410611b4 | 128 | /// |
dd59e3c2 | 129 | /// Used to uniquely identify a `MediaSet`. They are stored as second |
410611b4 | 130 | /// file on the tape. |
8c15560b | 131 | pub struct MediaSetLabel { |
dd59e3c2 | 132 | /// The associated `MediaPool` |
8c15560b | 133 | pub pool: String, |
dd59e3c2 | 134 | /// Uuid. We use the all-zero Uuid to reseve an empty media for a specific pool |
8c15560b | 135 | pub uuid: Uuid, |
dd59e3c2 | 136 | /// Media sequence number |
8c15560b DM |
137 | pub seq_nr: u64, |
138 | /// Creation time stamp | |
139 | pub ctime: i64, | |
8a0046f5 DM |
140 | /// Encryption key finkerprint (if encryped) |
141 | #[serde(skip_serializing_if="Option::is_none")] | |
142 | pub encryption_key_fingerprint: Option<Fingerprint>, | |
8c15560b DM |
143 | } |
144 | ||
145 | impl MediaSetLabel { | |
146 | ||
8a0046f5 DM |
147 | pub fn with_data( |
148 | pool: &str, | |
149 | uuid: Uuid, | |
150 | seq_nr: u64, | |
151 | ctime: i64, | |
152 | encryption_key_fingerprint: Option<Fingerprint>, | |
153 | ) -> Self { | |
8c15560b DM |
154 | Self { |
155 | pool: pool.to_string(), | |
156 | uuid, | |
157 | seq_nr, | |
158 | ctime, | |
8a0046f5 | 159 | encryption_key_fingerprint, |
8c15560b DM |
160 | } |
161 | } | |
162 | } | |
a84050c1 | 163 |