mirror of
https://git.proxmox.com/git/proxmox-backup
synced 2025-05-02 17:44:42 +00:00
file restore: move allow-memory-hotplug param from CLI to environment
avoid the need to loop a parameter through a dozen function which all don't care about it at all; iff this should be a global oncecell or lock guarded param. Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
This commit is contained in:
parent
fa1c3eaea1
commit
69e3beb941
@ -43,7 +43,6 @@ pub trait BlockRestoreDriver {
|
|||||||
details: SnapRestoreDetails,
|
details: SnapRestoreDetails,
|
||||||
img_file: String,
|
img_file: String,
|
||||||
path: Vec<u8>,
|
path: Vec<u8>,
|
||||||
auto_memory_hotplug: bool,
|
|
||||||
) -> Async<Result<Vec<ArchiveEntry>, Error>>;
|
) -> Async<Result<Vec<ArchiveEntry>, Error>>;
|
||||||
|
|
||||||
/// pxar=true:
|
/// pxar=true:
|
||||||
@ -58,7 +57,6 @@ pub trait BlockRestoreDriver {
|
|||||||
path: Vec<u8>,
|
path: Vec<u8>,
|
||||||
format: Option<FileRestoreFormat>,
|
format: Option<FileRestoreFormat>,
|
||||||
zstd: bool,
|
zstd: bool,
|
||||||
auto_memory_hotplug: bool,
|
|
||||||
) -> Async<Result<Box<dyn tokio::io::AsyncRead + Unpin + Send>, Error>>;
|
) -> Async<Result<Box<dyn tokio::io::AsyncRead + Unpin + Send>, Error>>;
|
||||||
|
|
||||||
/// Return status of all running/mapped images, result value is (id, extra data), where id must
|
/// Return status of all running/mapped images, result value is (id, extra data), where id must
|
||||||
@ -94,12 +92,9 @@ pub async fn data_list(
|
|||||||
details: SnapRestoreDetails,
|
details: SnapRestoreDetails,
|
||||||
img_file: String,
|
img_file: String,
|
||||||
path: Vec<u8>,
|
path: Vec<u8>,
|
||||||
auto_memory_hotplug: bool,
|
|
||||||
) -> Result<Vec<ArchiveEntry>, Error> {
|
) -> Result<Vec<ArchiveEntry>, Error> {
|
||||||
let driver = driver.unwrap_or(DEFAULT_DRIVER).resolve();
|
let driver = driver.unwrap_or(DEFAULT_DRIVER).resolve();
|
||||||
driver
|
driver.data_list(details, img_file, path).await
|
||||||
.data_list(details, img_file, path, auto_memory_hotplug)
|
|
||||||
.await
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn data_extract(
|
pub async fn data_extract(
|
||||||
@ -109,11 +104,10 @@ pub async fn data_extract(
|
|||||||
path: Vec<u8>,
|
path: Vec<u8>,
|
||||||
format: Option<FileRestoreFormat>,
|
format: Option<FileRestoreFormat>,
|
||||||
zstd: bool,
|
zstd: bool,
|
||||||
auto_memory_hotplug: bool,
|
|
||||||
) -> Result<Box<dyn tokio::io::AsyncRead + Send + Unpin>, Error> {
|
) -> Result<Box<dyn tokio::io::AsyncRead + Send + Unpin>, Error> {
|
||||||
let driver = driver.unwrap_or(DEFAULT_DRIVER).resolve();
|
let driver = driver.unwrap_or(DEFAULT_DRIVER).resolve();
|
||||||
driver
|
driver
|
||||||
.data_extract(details, img_file, path, format, zstd, auto_memory_hotplug)
|
.data_extract(details, img_file, path, format, zstd)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ use pbs_datastore::catalog::ArchiveEntry;
|
|||||||
|
|
||||||
use super::block_driver::*;
|
use super::block_driver::*;
|
||||||
use crate::get_user_run_dir;
|
use crate::get_user_run_dir;
|
||||||
use crate::qemu_helper::set_auto_memory_hotplug;
|
use crate::qemu_helper;
|
||||||
|
|
||||||
const RESTORE_VM_MAP: &str = "restore-vm-map.json";
|
const RESTORE_VM_MAP: &str = "restore-vm-map.json";
|
||||||
|
|
||||||
@ -198,6 +198,20 @@ fn path_is_zfs(path: &[u8]) -> bool {
|
|||||||
part == OsStr::new("zpool") && components.next().is_some()
|
part == OsStr::new("zpool") && components.next().is_some()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn handle_extra_guest_memory_needs(cid: i32, path: &[u8]) {
|
||||||
|
use std::env::var;
|
||||||
|
match var("PBS_FILE_RESTORE_MEM_HOTPLUG_ALLOW").ok().as_deref() {
|
||||||
|
Some("true") => (),
|
||||||
|
_ => return, // this is opt-in
|
||||||
|
}
|
||||||
|
|
||||||
|
if path_is_zfs(path) {
|
||||||
|
if let Err(err) = qemu_helper::set_dynamic_memory(cid, None).await {
|
||||||
|
log::error!("could not increase memory: {err}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async fn start_vm(cid_request: i32, details: &SnapRestoreDetails) -> Result<VMState, Error> {
|
async fn start_vm(cid_request: i32, details: &SnapRestoreDetails) -> Result<VMState, Error> {
|
||||||
let ticket = new_ticket();
|
let ticket = new_ticket();
|
||||||
let files = details
|
let files = details
|
||||||
@ -218,18 +232,13 @@ impl BlockRestoreDriver for QemuBlockDriver {
|
|||||||
details: SnapRestoreDetails,
|
details: SnapRestoreDetails,
|
||||||
img_file: String,
|
img_file: String,
|
||||||
mut path: Vec<u8>,
|
mut path: Vec<u8>,
|
||||||
auto_memory_hotplug: bool,
|
|
||||||
) -> Async<Result<Vec<ArchiveEntry>, Error>> {
|
) -> Async<Result<Vec<ArchiveEntry>, Error>> {
|
||||||
async move {
|
async move {
|
||||||
let (cid, client) = ensure_running(&details).await?;
|
let (cid, client) = ensure_running(&details).await?;
|
||||||
if !path.is_empty() && path[0] != b'/' {
|
if !path.is_empty() && path[0] != b'/' {
|
||||||
path.insert(0, b'/');
|
path.insert(0, b'/');
|
||||||
}
|
}
|
||||||
if path_is_zfs(&path) && auto_memory_hotplug {
|
handle_extra_guest_memory_needs(cid, &path).await;
|
||||||
if let Err(err) = set_auto_memory_hotplug(cid, None).await {
|
|
||||||
log::error!("could not increase memory: {err}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let path = base64::encode(img_file.bytes().chain(path).collect::<Vec<u8>>());
|
let path = base64::encode(img_file.bytes().chain(path).collect::<Vec<u8>>());
|
||||||
let mut result = client
|
let mut result = client
|
||||||
.get("api2/json/list", Some(json!({ "path": path })))
|
.get("api2/json/list", Some(json!({ "path": path })))
|
||||||
@ -246,18 +255,13 @@ impl BlockRestoreDriver for QemuBlockDriver {
|
|||||||
mut path: Vec<u8>,
|
mut path: Vec<u8>,
|
||||||
format: Option<FileRestoreFormat>,
|
format: Option<FileRestoreFormat>,
|
||||||
zstd: bool,
|
zstd: bool,
|
||||||
auto_memory_hotplug: bool,
|
|
||||||
) -> Async<Result<Box<dyn tokio::io::AsyncRead + Unpin + Send>, Error>> {
|
) -> Async<Result<Box<dyn tokio::io::AsyncRead + Unpin + Send>, Error>> {
|
||||||
async move {
|
async move {
|
||||||
let (cid, client) = ensure_running(&details).await?;
|
let (cid, client) = ensure_running(&details).await?;
|
||||||
if !path.is_empty() && path[0] != b'/' {
|
if !path.is_empty() && path[0] != b'/' {
|
||||||
path.insert(0, b'/');
|
path.insert(0, b'/');
|
||||||
}
|
}
|
||||||
if path_is_zfs(&path) && auto_memory_hotplug {
|
handle_extra_guest_memory_needs(cid, &path).await;
|
||||||
if let Err(err) = set_auto_memory_hotplug(cid, None).await {
|
|
||||||
log::error!("could not increase memory: {err}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let path = base64::encode(img_file.bytes().chain(path).collect::<Vec<u8>>());
|
let path = base64::encode(img_file.bytes().chain(path).collect::<Vec<u8>>());
|
||||||
let (mut tx, rx) = tokio::io::duplex(1024 * 4096);
|
let (mut tx, rx) = tokio::io::duplex(1024 * 4096);
|
||||||
let mut data = json!({ "path": path, "zstd": zstd });
|
let mut data = json!({ "path": path, "zstd": zstd });
|
||||||
|
@ -96,7 +96,6 @@ fn keyfile_path(param: &Value) -> Option<String> {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::too_many_arguments)]
|
|
||||||
async fn list_files(
|
async fn list_files(
|
||||||
repo: BackupRepository,
|
repo: BackupRepository,
|
||||||
namespace: BackupNamespace,
|
namespace: BackupNamespace,
|
||||||
@ -105,7 +104,6 @@ async fn list_files(
|
|||||||
crypt_config: Option<Arc<CryptConfig>>,
|
crypt_config: Option<Arc<CryptConfig>>,
|
||||||
keyfile: Option<String>,
|
keyfile: Option<String>,
|
||||||
driver: Option<BlockDriverType>,
|
driver: Option<BlockDriverType>,
|
||||||
auto_memory_hotplug: bool,
|
|
||||||
) -> Result<Vec<ArchiveEntry>, Error> {
|
) -> Result<Vec<ArchiveEntry>, Error> {
|
||||||
let client = connect(&repo)?;
|
let client = connect(&repo)?;
|
||||||
let client = BackupReader::start(
|
let client = BackupReader::start(
|
||||||
@ -172,7 +170,7 @@ async fn list_files(
|
|||||||
snapshot,
|
snapshot,
|
||||||
keyfile,
|
keyfile,
|
||||||
};
|
};
|
||||||
data_list(driver, details, file, path, auto_memory_hotplug).await
|
data_list(driver, details, file, path).await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -228,12 +226,6 @@ async fn list_files(
|
|||||||
minimum: 1,
|
minimum: 1,
|
||||||
optional: true,
|
optional: true,
|
||||||
},
|
},
|
||||||
"auto-memory-hotplug": {
|
|
||||||
type: Boolean,
|
|
||||||
description: "If enabled, automatically hot-plugs memory for started VM if a ZFS pool is accessed.",
|
|
||||||
default: false,
|
|
||||||
optional: true,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
returns: {
|
returns: {
|
||||||
@ -251,7 +243,6 @@ async fn list(
|
|||||||
path: String,
|
path: String,
|
||||||
base64: bool,
|
base64: bool,
|
||||||
timeout: Option<u64>,
|
timeout: Option<u64>,
|
||||||
auto_memory_hotplug: bool,
|
|
||||||
param: Value,
|
param: Value,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
let repo = extract_repository_from_value(¶m)?;
|
let repo = extract_repository_from_value(¶m)?;
|
||||||
@ -281,16 +272,7 @@ async fn list(
|
|||||||
let result = if let Some(timeout) = timeout {
|
let result = if let Some(timeout) = timeout {
|
||||||
match tokio::time::timeout(
|
match tokio::time::timeout(
|
||||||
std::time::Duration::from_secs(timeout),
|
std::time::Duration::from_secs(timeout),
|
||||||
list_files(
|
list_files(repo, ns, snapshot, path, crypt_config, keyfile, driver),
|
||||||
repo,
|
|
||||||
ns,
|
|
||||||
snapshot,
|
|
||||||
path,
|
|
||||||
crypt_config,
|
|
||||||
keyfile,
|
|
||||||
driver,
|
|
||||||
auto_memory_hotplug,
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
@ -298,17 +280,7 @@ async fn list(
|
|||||||
Err(_) => Err(http_err!(SERVICE_UNAVAILABLE, "list not finished in time")),
|
Err(_) => Err(http_err!(SERVICE_UNAVAILABLE, "list not finished in time")),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
list_files(
|
list_files(repo, ns, snapshot, path, crypt_config, keyfile, driver).await
|
||||||
repo,
|
|
||||||
ns,
|
|
||||||
snapshot,
|
|
||||||
path,
|
|
||||||
crypt_config,
|
|
||||||
keyfile,
|
|
||||||
driver,
|
|
||||||
auto_memory_hotplug,
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let output_format = get_output_format(¶m);
|
let output_format = get_output_format(¶m);
|
||||||
@ -415,12 +387,6 @@ async fn list(
|
|||||||
type: BlockDriverType,
|
type: BlockDriverType,
|
||||||
optional: true,
|
optional: true,
|
||||||
},
|
},
|
||||||
"auto-memory-hotplug": {
|
|
||||||
type: Boolean,
|
|
||||||
description: "If enabled, automatically hot-plugs memory for started VM if a ZFS pool is accessed.",
|
|
||||||
default: false,
|
|
||||||
optional: true,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)]
|
)]
|
||||||
@ -434,7 +400,6 @@ async fn extract(
|
|||||||
target: Option<String>,
|
target: Option<String>,
|
||||||
format: Option<FileRestoreFormat>,
|
format: Option<FileRestoreFormat>,
|
||||||
zstd: bool,
|
zstd: bool,
|
||||||
auto_memory_hotplug: bool,
|
|
||||||
param: Value,
|
param: Value,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
let repo = extract_repository_from_value(¶m)?;
|
let repo = extract_repository_from_value(¶m)?;
|
||||||
@ -516,7 +481,6 @@ async fn extract(
|
|||||||
path.clone(),
|
path.clone(),
|
||||||
Some(FileRestoreFormat::Pxar),
|
Some(FileRestoreFormat::Pxar),
|
||||||
false,
|
false,
|
||||||
auto_memory_hotplug,
|
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
let decoder = Decoder::from_tokio(reader).await?;
|
let decoder = Decoder::from_tokio(reader).await?;
|
||||||
@ -529,16 +493,8 @@ async fn extract(
|
|||||||
format_err!("unable to remove temporary .pxarexclude-cli file - {}", e)
|
format_err!("unable to remove temporary .pxarexclude-cli file - {}", e)
|
||||||
})?;
|
})?;
|
||||||
} else {
|
} else {
|
||||||
let mut reader = data_extract(
|
let mut reader =
|
||||||
driver,
|
data_extract(driver, details, file, path.clone(), format, zstd).await?;
|
||||||
details,
|
|
||||||
file,
|
|
||||||
path.clone(),
|
|
||||||
format,
|
|
||||||
zstd,
|
|
||||||
auto_memory_hotplug,
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
tokio::io::copy(&mut reader, &mut tokio::io::stdout()).await?;
|
tokio::io::copy(&mut reader, &mut tokio::io::stdout()).await?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user