all lists on lists.proxmox.com
 help / color / mirror / Atom feed
* [pbs-devel] [PATCH proxmox-backup 1/2] pbs-client: extract: rewrite create_zip with sequential decoder
@ 2022-04-19 10:28 Dominik Csapak
  2022-04-19 10:28 ` [pbs-devel] [PATCH proxmox-backup 2/2] pbs-client: extract: add top-level dir in tar.zst Dominik Csapak
  2022-04-22  9:43 ` [pbs-devel] applied: [PATCH proxmox-backup 1/2] pbs-client: extract: rewrite create_zip with sequential decoder Wolfgang Bumiller
  0 siblings, 2 replies; 3+ messages in thread
From: Dominik Csapak @ 2022-04-19 10:28 UTC (permalink / raw)
  To: pbs-devel

instead of an async recursive function. Not only is it less code,
recursive futures are not really nice and it should be faster too.

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
 pbs-client/src/pxar/extract.rs | 154 ++++++++++++++++-----------------
 1 file changed, 74 insertions(+), 80 deletions(-)

diff --git a/pbs-client/src/pxar/extract.rs b/pbs-client/src/pxar/extract.rs
index 7898e255..90ce88bd 100644
--- a/pbs-client/src/pxar/extract.rs
+++ b/pbs-client/src/pxar/extract.rs
@@ -7,11 +7,9 @@ use std::io;
 use std::os::unix::ffi::OsStrExt;
 use std::os::unix::io::{AsRawFd, FromRawFd, RawFd};
 use std::path::{Path, PathBuf};
-use std::pin::Pin;
 use std::sync::{Arc, Mutex};
 
 use anyhow::{bail, format_err, Error};
-use futures::future::Future;
 use nix::dir::Dir;
 use nix::fcntl::OFlag;
 use nix::sys::stat::Mode;
@@ -699,7 +697,7 @@ where
 
 pub async fn create_zip<T, W, P>(
     output: W,
-    decoder: Accessor<T>,
+    accessor: Accessor<T>,
     path: P,
     verbose: bool,
 ) -> Result<(), Error>
@@ -708,7 +706,7 @@ where
     W: tokio::io::AsyncWrite + Unpin + Send + 'static,
     P: AsRef<Path>,
 {
-    let root = decoder.open_root().await?;
+    let root = accessor.open_root().await?;
     let file = root
         .lookup(&path)
         .await?
@@ -720,88 +718,84 @@ where
         components.as_path().to_owned()
     };
 
-    let mut zipencoder = ZipEncoder::new(output);
-    let mut decoder = decoder;
-    recurse_files_zip(&mut zipencoder, &mut decoder, &prefix, file, verbose)
-        .await
-        .map_err(|err| {
-            eprintln!("error during creating of zip: {}", err);
-            err
-        })?;
+    let mut zip = ZipEncoder::new(output);
 
-    zipencoder.finish().await.map_err(|err| {
-        eprintln!("error during finishing of zip: {}", err);
-        err
-    })
-}
+    if let Ok(dir) = file.enter_directory().await {
+        let entry = dir.lookup_self().await?;
+        let path = entry.path().strip_prefix(&prefix)?;
+        if path != Path::new("/") {
+            let metadata = entry.metadata();
+            let entry = ZipEntry::new(
+                path,
+                metadata.stat.mtime.secs,
+                metadata.stat.mode as u16,
+                false,
+            );
+            zip.add_entry::<FileContents<T>>(entry, None).await?;
+        }
 
-fn recurse_files_zip<'a, T, W>(
-    zip: &'a mut ZipEncoder<W>,
-    decoder: &'a mut Accessor<T>,
-    prefix: &'a Path,
-    file: FileEntry<T>,
-    verbose: bool,
-) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'a>>
-where
-    T: Clone + pxar::accessor::ReadAt + Unpin + Send + Sync + 'static,
-    W: tokio::io::AsyncWrite + Unpin + Send + 'static,
-{
-    Box::pin(async move {
-        let metadata = file.entry().metadata();
-        let path = file.entry().path().strip_prefix(&prefix)?;
-
-        match file.kind() {
-            EntryKind::File { .. } => {
-                if verbose {
-                    eprintln!("adding '{}' to zip", path.display());
-                }
-                let entry = ZipEntry::new(
-                    path,
-                    metadata.stat.mtime.secs,
-                    metadata.stat.mode as u16,
-                    true,
-                );
-                zip.add_entry(entry, Some(file.contents().await?))
-                    .await
-                    .map_err(|err| format_err!("could not send file entry: {}", err))?;
-            }
-            EntryKind::Hardlink(_) => {
-                let realfile = decoder.follow_hardlink(&file).await?;
-                if verbose {
-                    eprintln!("adding '{}' to zip", path.display());
+        let mut decoder = dir.decode_full().await?;
+        decoder.enable_goodbye_entries(false);
+        while let Some(entry) = decoder.next().await {
+            let entry = entry?;
+            let metadata = entry.metadata();
+            let path = entry.path().strip_prefix(&prefix)?;
+
+            match entry.kind() {
+                EntryKind::File { .. } => {
+                    if verbose {
+                        eprintln!("adding '{}' to zip", path.display());
+                    }
+                    let entry = ZipEntry::new(
+                        path,
+                        metadata.stat.mtime.secs,
+                        metadata.stat.mode as u16,
+                        true,
+                    );
+                    zip.add_entry(entry, decoder.contents())
+                        .await
+                        .map_err(|err| format_err!("could not send file entry: {}", err))?;
                 }
-                let entry = ZipEntry::new(
-                    path,
-                    metadata.stat.mtime.secs,
-                    metadata.stat.mode as u16,
-                    true,
-                );
-                zip.add_entry(entry, Some(realfile.contents().await?))
-                    .await
-                    .map_err(|err| format_err!("could not send file entry: {}", err))?;
-            }
-            EntryKind::Directory => {
-                let dir = file.enter_directory().await?;
-                let mut readdir = dir.read_dir();
-                if verbose {
-                    eprintln!("adding '{}' to zip", path.display());
+                EntryKind::Hardlink(_) => {
+                    let entry = root
+                        .lookup(&path)
+                        .await?
+                        .ok_or(format_err!("error looking up '{:?}'", path))?;
+                    let realfile = accessor.follow_hardlink(&entry).await?;
+                    let metadata = realfile.entry().metadata();
+                    if verbose {
+                        eprintln!("adding '{}' to zip", path.display());
+                    }
+                    let entry = ZipEntry::new(
+                        path,
+                        metadata.stat.mtime.secs,
+                        metadata.stat.mode as u16,
+                        true,
+                    );
+                    zip.add_entry(entry, decoder.contents())
+                        .await
+                        .map_err(|err| format_err!("could not send file entry: {}", err))?;
                 }
-                let entry = ZipEntry::new(
-                    path,
-                    metadata.stat.mtime.secs,
-                    metadata.stat.mode as u16,
-                    false,
-                );
-                zip.add_entry::<FileContents<T>>(entry, None).await?;
-                while let Some(entry) = readdir.next().await {
-                    let entry = entry?.decode_entry().await?;
-                    recurse_files_zip(zip, decoder, prefix, entry, verbose).await?;
+                EntryKind::Directory => {
+                    if verbose {
+                        eprintln!("adding '{}' to zip", path.display());
+                    }
+                    let entry = ZipEntry::new(
+                        path,
+                        metadata.stat.mtime.secs,
+                        metadata.stat.mode as u16,
+                        false,
+                    );
+                    zip.add_entry::<FileContents<T>>(entry, None).await?;
                 }
-            }
-            _ => {} // ignore all else
-        };
+                _ => {} // ignore all else
+            };
+        }
+    }
 
-        Ok(())
+    zip.finish().await.map_err(|err| {
+        eprintln!("error during finishing of zip: {}", err);
+        err
     })
 }
 
-- 
2.30.2





^ permalink raw reply	[flat|nested] 3+ messages in thread

* [pbs-devel] [PATCH proxmox-backup 2/2] pbs-client: extract: add top-level dir in tar.zst
  2022-04-19 10:28 [pbs-devel] [PATCH proxmox-backup 1/2] pbs-client: extract: rewrite create_zip with sequential decoder Dominik Csapak
@ 2022-04-19 10:28 ` Dominik Csapak
  2022-04-22  9:43 ` [pbs-devel] applied: [PATCH proxmox-backup 1/2] pbs-client: extract: rewrite create_zip with sequential decoder Wolfgang Bumiller
  1 sibling, 0 replies; 3+ messages in thread
From: Dominik Csapak @ 2022-04-19 10:28 UTC (permalink / raw)
  To: pbs-devel

when download a folder, include that folder as first entry (except '/')

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
 pbs-client/src/pxar/extract.rs | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/pbs-client/src/pxar/extract.rs b/pbs-client/src/pxar/extract.rs
index 90ce88bd..f18fc7d4 100644
--- a/pbs-client/src/pxar/extract.rs
+++ b/pbs-client/src/pxar/extract.rs
@@ -557,6 +557,22 @@ where
     let mut hardlinks: HashMap<PathBuf, PathBuf> = HashMap::new();
 
     if let Ok(dir) = file.enter_directory().await {
+        let entry = dir.lookup_self().await?;
+        let path = entry.path().strip_prefix(prefix)?;
+
+        if path != Path::new("/") {
+            let metadata = entry.metadata();
+            let mut header = tar::Header::new_gnu();
+            header.set_entry_type(tar::EntryType::Directory);
+            add_metadata_to_header(&mut header, metadata);
+            header.set_size(0);
+            header.set_cksum();
+            tarencoder
+                .add_entry(&mut header, path, tokio::io::empty())
+                .await
+                .map_err(|err| format_err!("could not send dir entry: {}", err))?;
+        }
+
         let mut decoder = dir.decode_full().await?;
         decoder.enable_goodbye_entries(false);
         while let Some(entry) = decoder.next().await {
-- 
2.30.2





^ permalink raw reply	[flat|nested] 3+ messages in thread

* [pbs-devel] applied: [PATCH proxmox-backup 1/2] pbs-client: extract: rewrite create_zip with sequential decoder
  2022-04-19 10:28 [pbs-devel] [PATCH proxmox-backup 1/2] pbs-client: extract: rewrite create_zip with sequential decoder Dominik Csapak
  2022-04-19 10:28 ` [pbs-devel] [PATCH proxmox-backup 2/2] pbs-client: extract: add top-level dir in tar.zst Dominik Csapak
@ 2022-04-22  9:43 ` Wolfgang Bumiller
  1 sibling, 0 replies; 3+ messages in thread
From: Wolfgang Bumiller @ 2022-04-22  9:43 UTC (permalink / raw)
  To: Dominik Csapak; +Cc: pbs-devel

applied both patches




^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2022-04-22  9:43 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-04-19 10:28 [pbs-devel] [PATCH proxmox-backup 1/2] pbs-client: extract: rewrite create_zip with sequential decoder Dominik Csapak
2022-04-19 10:28 ` [pbs-devel] [PATCH proxmox-backup 2/2] pbs-client: extract: add top-level dir in tar.zst Dominik Csapak
2022-04-22  9:43 ` [pbs-devel] applied: [PATCH proxmox-backup 1/2] pbs-client: extract: rewrite create_zip with sequential decoder Wolfgang Bumiller

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal