mirror of
https://git.proxmox.com/git/proxmox-backup
synced 2025-08-12 10:52:09 +00:00
Merge branch '3.2.6'
branched off to avoid a breaking change on master
This commit is contained in:
commit
1d36b502f5
@ -1,5 +1,5 @@
|
|||||||
[workspace.package]
|
[workspace.package]
|
||||||
version = "3.2.5"
|
version = "3.2.6"
|
||||||
authors = [
|
authors = [
|
||||||
"Dietmar Maurer <dietmar@proxmox.com>",
|
"Dietmar Maurer <dietmar@proxmox.com>",
|
||||||
"Dominik Csapak <d.csapak@proxmox.com>",
|
"Dominik Csapak <d.csapak@proxmox.com>",
|
||||||
@ -86,7 +86,7 @@ proxmox-uuid = "1"
|
|||||||
# other proxmox crates
|
# other proxmox crates
|
||||||
pathpatterns = "0.3"
|
pathpatterns = "0.3"
|
||||||
proxmox-acme = "0.5"
|
proxmox-acme = "0.5"
|
||||||
pxar = "0.11.1"
|
pxar = "0.12"
|
||||||
|
|
||||||
# PBS workspace
|
# PBS workspace
|
||||||
pbs-api-types = { path = "pbs-api-types" }
|
pbs-api-types = { path = "pbs-api-types" }
|
||||||
|
12
debian/changelog
vendored
12
debian/changelog
vendored
@ -1,3 +1,15 @@
|
|||||||
|
rust-proxmox-backup (3.2.6-1) bookworm; urgency=medium
|
||||||
|
|
||||||
|
* tape: disable Programmable Early Warning Zone (PEWZ)
|
||||||
|
|
||||||
|
* tape: handle PEWZ like regular early warning
|
||||||
|
|
||||||
|
* docs: add note for not using remote storages
|
||||||
|
|
||||||
|
* client: pxar: fix fuse mount performance for split archives
|
||||||
|
|
||||||
|
-- Proxmox Support Team <support@proxmox.com> Mon, 17 Jun 2024 10:18:13 +0200
|
||||||
|
|
||||||
rust-proxmox-backup (3.2.5-1) bookworm; urgency=medium
|
rust-proxmox-backup (3.2.5-1) bookworm; urgency=medium
|
||||||
|
|
||||||
* pxar: add support for split archives
|
* pxar: add support for split archives
|
||||||
|
2
debian/control
vendored
2
debian/control
vendored
@ -103,7 +103,7 @@ Build-Depends: bash-completion,
|
|||||||
librust-proxmox-time-1+default-dev (>= 1.1.6-~~),
|
librust-proxmox-time-1+default-dev (>= 1.1.6-~~),
|
||||||
librust-proxmox-uuid-1+default-dev,
|
librust-proxmox-uuid-1+default-dev,
|
||||||
librust-proxmox-uuid-1+serde-dev,
|
librust-proxmox-uuid-1+serde-dev,
|
||||||
librust-pxar-0.11+default-dev (>= 0.11.1-~~),
|
librust-pxar-0.12+default-dev,
|
||||||
librust-regex-1+default-dev (>= 1.5.5-~~),
|
librust-regex-1+default-dev (>= 1.5.5-~~),
|
||||||
librust-rustyline-9+default-dev,
|
librust-rustyline-9+default-dev,
|
||||||
librust-serde-1+default-dev,
|
librust-serde-1+default-dev,
|
||||||
|
@ -373,11 +373,8 @@ where
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(true, EntryKind::File { size, .. }) => {
|
(true, EntryKind::File { size, .. }) => match self.decoder.contents() {
|
||||||
let contents = self.decoder.contents();
|
Ok(Some(mut contents)) => self.extractor.extract_file(
|
||||||
|
|
||||||
if let Some(mut contents) = contents {
|
|
||||||
self.extractor.extract_file(
|
|
||||||
&file_name,
|
&file_name,
|
||||||
metadata,
|
metadata,
|
||||||
*size,
|
*size,
|
||||||
@ -385,14 +382,13 @@ where
|
|||||||
self.extractor
|
self.extractor
|
||||||
.overwrite_flags
|
.overwrite_flags
|
||||||
.contains(OverwriteFlags::FILE),
|
.contains(OverwriteFlags::FILE),
|
||||||
)
|
),
|
||||||
} else {
|
Ok(None) => Err(format_err!(
|
||||||
Err(format_err!(
|
|
||||||
"found regular file entry without contents in archive"
|
"found regular file entry without contents in archive"
|
||||||
))
|
)),
|
||||||
}
|
Err(err) => Err(err.into()),
|
||||||
.context(PxarExtractContext::ExtractFile)
|
|
||||||
}
|
}
|
||||||
|
.context(PxarExtractContext::ExtractFile),
|
||||||
(false, _) => Ok(()), // skip this
|
(false, _) => Ok(()), // skip this
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -872,7 +868,8 @@ where
|
|||||||
match entry.kind() {
|
match entry.kind() {
|
||||||
EntryKind::File { .. } => {
|
EntryKind::File { .. } => {
|
||||||
let size = decoder.content_size().unwrap_or(0);
|
let size = decoder.content_size().unwrap_or(0);
|
||||||
tar_add_file(&mut tarencoder, decoder.contents(), size, metadata, path).await?
|
let contents = decoder.contents().await?;
|
||||||
|
tar_add_file(&mut tarencoder, contents, size, metadata, path).await?
|
||||||
}
|
}
|
||||||
EntryKind::Hardlink(link) => {
|
EntryKind::Hardlink(link) => {
|
||||||
if !link.data.is_empty() {
|
if !link.data.is_empty() {
|
||||||
@ -894,13 +891,8 @@ where
|
|||||||
path
|
path
|
||||||
} else {
|
} else {
|
||||||
let size = decoder.content_size().unwrap_or(0);
|
let size = decoder.content_size().unwrap_or(0);
|
||||||
tar_add_file(
|
let contents = decoder.contents().await?;
|
||||||
&mut tarencoder,
|
tar_add_file(&mut tarencoder, contents, size, metadata, path)
|
||||||
decoder.contents(),
|
|
||||||
size,
|
|
||||||
metadata,
|
|
||||||
path,
|
|
||||||
)
|
|
||||||
.await?;
|
.await?;
|
||||||
hardlinks.insert(realpath.to_owned(), path.to_owned());
|
hardlinks.insert(realpath.to_owned(), path.to_owned());
|
||||||
continue;
|
continue;
|
||||||
@ -1038,7 +1030,8 @@ where
|
|||||||
metadata.stat.mode as u16,
|
metadata.stat.mode as u16,
|
||||||
true,
|
true,
|
||||||
);
|
);
|
||||||
zip.add_entry(entry, decoder.contents())
|
let contents = decoder.contents().await?;
|
||||||
|
zip.add_entry(entry, contents)
|
||||||
.await
|
.await
|
||||||
.context("could not send file entry")?;
|
.context("could not send file entry")?;
|
||||||
}
|
}
|
||||||
@ -1056,7 +1049,8 @@ where
|
|||||||
metadata.stat.mode as u16,
|
metadata.stat.mode as u16,
|
||||||
true,
|
true,
|
||||||
);
|
);
|
||||||
zip.add_entry(entry, decoder.contents())
|
let contents = decoder.contents().await?;
|
||||||
|
zip.add_entry(entry, contents)
|
||||||
.await
|
.await
|
||||||
.context("could not send file entry")?;
|
.context("could not send file entry")?;
|
||||||
}
|
}
|
||||||
@ -1279,14 +1273,16 @@ where
|
|||||||
.with_context(|| format!("error at entry {file_name_os:?}"))?;
|
.with_context(|| format!("error at entry {file_name_os:?}"))?;
|
||||||
}
|
}
|
||||||
EntryKind::File { size, .. } => {
|
EntryKind::File { size, .. } => {
|
||||||
|
let mut contents = decoder
|
||||||
|
.contents()
|
||||||
|
.await?
|
||||||
|
.context("found regular file entry without contents in archive")?;
|
||||||
extractor
|
extractor
|
||||||
.async_extract_file(
|
.async_extract_file(
|
||||||
&file_name,
|
&file_name,
|
||||||
metadata,
|
metadata,
|
||||||
*size,
|
*size,
|
||||||
&mut decoder
|
&mut contents,
|
||||||
.contents()
|
|
||||||
.context("found regular file entry without contents in archive")?,
|
|
||||||
extractor.overwrite_flags.contains(OverwriteFlags::FILE),
|
extractor.overwrite_flags.contains(OverwriteFlags::FILE),
|
||||||
)
|
)
|
||||||
.await?
|
.await?
|
||||||
|
@ -5,7 +5,6 @@ use std::ffi::{OsStr, OsString};
|
|||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::ops::Range;
|
|
||||||
use std::os::unix::ffi::OsStrExt;
|
use std::os::unix::ffi::OsStrExt;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::pin::Pin;
|
use std::pin::Pin;
|
||||||
@ -20,7 +19,7 @@ use futures::sink::SinkExt;
|
|||||||
use futures::stream::{StreamExt, TryStreamExt};
|
use futures::stream::{StreamExt, TryStreamExt};
|
||||||
|
|
||||||
use proxmox_io::vec;
|
use proxmox_io::vec;
|
||||||
use pxar::accessor::{self, EntryRangeInfo, ReadAt};
|
use pxar::accessor::{self, ContentRange, EntryRangeInfo, ReadAt};
|
||||||
|
|
||||||
use proxmox_fuse::requests::{self, FuseRequest};
|
use proxmox_fuse::requests::{self, FuseRequest};
|
||||||
use proxmox_fuse::{EntryParam, Fuse, ReplyBufState, Request, ROOT_ID};
|
use proxmox_fuse::{EntryParam, Fuse, ReplyBufState, Request, ROOT_ID};
|
||||||
@ -130,7 +129,7 @@ struct Lookup {
|
|||||||
inode: u64,
|
inode: u64,
|
||||||
parent: u64,
|
parent: u64,
|
||||||
entry_range_info: EntryRangeInfo,
|
entry_range_info: EntryRangeInfo,
|
||||||
content_range: Option<Range<u64>>,
|
content_range: Option<ContentRange>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Lookup {
|
impl Lookup {
|
||||||
@ -138,7 +137,7 @@ impl Lookup {
|
|||||||
inode: u64,
|
inode: u64,
|
||||||
parent: u64,
|
parent: u64,
|
||||||
entry_range_info: EntryRangeInfo,
|
entry_range_info: EntryRangeInfo,
|
||||||
content_range: Option<Range<u64>>,
|
content_range: Option<ContentRange>,
|
||||||
) -> Box<Lookup> {
|
) -> Box<Lookup> {
|
||||||
Box::new(Self {
|
Box::new(Self {
|
||||||
refs: AtomicUsize::new(1),
|
refs: AtomicUsize::new(1),
|
||||||
@ -433,13 +432,17 @@ impl SessionImpl {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn open_content(&self, lookup: &LookupRef) -> Result<FileContents, Error> {
|
async fn open_content<'a>(&'a self, lookup: &'a LookupRef<'a>) -> Result<FileContents, Error> {
|
||||||
if is_dir_inode(lookup.inode) {
|
if is_dir_inode(lookup.inode) {
|
||||||
io_return!(libc::EISDIR);
|
io_return!(libc::EISDIR);
|
||||||
}
|
}
|
||||||
|
|
||||||
match lookup.content_range.clone() {
|
match &lookup.content_range {
|
||||||
Some(range) => Ok(unsafe { self.accessor.open_contents_at_range(range) }),
|
Some(range) => self
|
||||||
|
.accessor
|
||||||
|
.open_contents_at_range(range)
|
||||||
|
.await
|
||||||
|
.map_err(|err| err.into()),
|
||||||
None => io_return!(libc::EBADF),
|
None => io_return!(libc::EBADF),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -581,7 +584,7 @@ impl SessionImpl {
|
|||||||
|
|
||||||
async fn read(&self, inode: u64, len: usize, offset: u64) -> Result<Vec<u8>, Error> {
|
async fn read(&self, inode: u64, len: usize, offset: u64) -> Result<Vec<u8>, Error> {
|
||||||
let file = self.get_lookup(inode)?;
|
let file = self.get_lookup(inode)?;
|
||||||
let content = self.open_content(&file)?;
|
let content = self.open_content(&file).await?;
|
||||||
let mut buf = vec::undefined(len);
|
let mut buf = vec::undefined(len);
|
||||||
let mut pos = 0;
|
let mut pos = 0;
|
||||||
// fuse' read is different from normal read - no short reads allowed except for EOF!
|
// fuse' read is different from normal read - no short reads allowed except for EOF!
|
||||||
|
@ -1748,7 +1748,7 @@ fn try_restore_snapshot_archive<R: pxar::decoder::SeqRead>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
let filename = entry.file_name();
|
let filename = entry.file_name();
|
||||||
let mut contents = match decoder.contents() {
|
let mut contents = match decoder.contents()? {
|
||||||
None => bail!("missing file content"),
|
None => bail!("missing file content"),
|
||||||
Some(contents) => contents,
|
Some(contents) => contents,
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user