[pbs-devel] [PATCH v4 stable-2 pxar] format/decoder/accessor: backport PXAR_FORMAT_VERSION header

Christian Ebner c.ebner at proxmox.com
Thu Jun 6 12:32:56 CEST 2024


Backports the PXAR_FORMAT_VERSION header, introduced with version
0.11 of the pxar library in order to early bail for decoder and
accessor instances not supporting the updated pxar format version.

Signed-off-by: Christian Ebner <c.ebner at proxmox.com>
---
changes since version 3:
- dropped unneeded mut in AccessorImpl, pass input by immutalbe
  reference
- drop unneeded setting of current header in decoder for format
  version entry, will bail anyway

 examples/mk-format-hashes.rs |  5 +++++
 src/accessor/mod.rs          | 12 ++++++++++++
 src/decoder/mod.rs           |  3 +++
 src/format/mod.rs            |  4 ++++
 4 files changed, 24 insertions(+)

diff --git a/examples/mk-format-hashes.rs b/examples/mk-format-hashes.rs
index 6e00654..afd0924 100644
--- a/examples/mk-format-hashes.rs
+++ b/examples/mk-format-hashes.rs
@@ -1,6 +1,11 @@
 use pxar::format::hash_filename;
 
 const CONSTANTS: &[(&str, &str, &str)] = &[
+    (
+        "Pxar format version entry, fallback to version 1 if not present",
+        "PXAR_FORMAT_VERSION",
+        "__PROXMOX_FORMAT_VERSION__",
+    ),
     (
         "Beginning of an entry (current version).",
         "PXAR_ENTRY",
diff --git a/src/accessor/mod.rs b/src/accessor/mod.rs
index 6a2de73..118681c 100644
--- a/src/accessor/mod.rs
+++ b/src/accessor/mod.rs
@@ -190,6 +190,18 @@ impl<T: ReadAt> AccessorImpl<T> {
             io_bail!("too small to contain a pxar archive");
         }
 
+        let header: format::Header = read_entry_at(&input, 0).await?;
+        header.check_header_size()?;
+
+        if header.htype == format::PXAR_FORMAT_VERSION {
+            let version: u64 = read_entry_at(
+                &input,
+                size_of::<format::Header>() as u64,
+            )
+            .await?;
+            io_bail!("format version {version} not compatible with this client");
+        }
+
         Ok(Self {
             input,
             size,
diff --git a/src/decoder/mod.rs b/src/decoder/mod.rs
index d1fb911..d8bdc9c 100644
--- a/src/decoder/mod.rs
+++ b/src/decoder/mod.rs
@@ -374,6 +374,9 @@ impl<I: SeqRead> DecoderImpl<I> {
             self.entry.kind = EntryKind::Hardlink(self.read_hardlink().await?);
 
             Ok(Some(self.entry.take()))
+        } else if header.htype == format::PXAR_FORMAT_VERSION {
+            let version: u64 = seq_read_entry(&mut self.input).await?;
+            io_bail!("format version {version} not compatible with this client");
         } else if header.htype == format::PXAR_ENTRY || header.htype == format::PXAR_ENTRY_V1 {
             if header.htype == format::PXAR_ENTRY {
                 self.entry.metadata = Metadata {
diff --git a/src/format/mod.rs b/src/format/mod.rs
index bfea9f6..50d0e26 100644
--- a/src/format/mod.rs
+++ b/src/format/mod.rs
@@ -6,6 +6,7 @@
 //! item data.
 //!
 //! An archive contains items in the following order:
+//!  * `FORMAT_VERSION`     -- (optional for v1), version of encoding format
 //!  * `ENTRY`              -- containing general stat() data and related bits
 //!   * `XATTR`             -- one extended attribute
 //!   * ...                 -- more of these when there are multiple defined
@@ -79,6 +80,8 @@ pub mod mode {
 }
 
 // Generated by `cargo run --example mk-format-hashes`
+/// Pxar format version entry, fallback to version 1 if not present
+pub const PXAR_FORMAT_VERSION: u64 = 0x730f6c75df16a40d;
 /// Beginning of an entry (current version).
 pub const PXAR_ENTRY: u64 = 0xd5956474e588acef;
 /// Previous version of the entry struct
@@ -177,6 +180,7 @@ impl Header {
 impl Display for Header {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         let readable = match self.htype {
+            PXAR_FORMAT_VERSION => "FORMAT_VERSION",
             PXAR_FILENAME => "FILENAME",
             PXAR_SYMLINK => "SYMLINK",
             PXAR_HARDLINK => "HARDLINK",
-- 
2.30.2





More information about the pbs-devel mailing list