diff --git a/proxmox-file-restore/src/block_driver.rs b/proxmox-file-restore/src/block_driver.rs index 39e0ebfbe..01cc4e180 100644 --- a/proxmox-file-restore/src/block_driver.rs +++ b/proxmox-file-restore/src/block_driver.rs @@ -43,7 +43,6 @@ pub trait BlockRestoreDriver { details: SnapRestoreDetails, img_file: String, path: Vec, - auto_memory_hotplug: bool, ) -> Async, Error>>; /// pxar=true: @@ -58,7 +57,6 @@ pub trait BlockRestoreDriver { path: Vec, format: Option, zstd: bool, - auto_memory_hotplug: bool, ) -> Async, Error>>; /// 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, img_file: String, path: Vec, - auto_memory_hotplug: bool, ) -> Result, Error> { let driver = driver.unwrap_or(DEFAULT_DRIVER).resolve(); - driver - .data_list(details, img_file, path, auto_memory_hotplug) - .await + driver.data_list(details, img_file, path).await } pub async fn data_extract( @@ -109,11 +104,10 @@ pub async fn data_extract( path: Vec, format: Option, zstd: bool, - auto_memory_hotplug: bool, ) -> Result, Error> { let driver = driver.unwrap_or(DEFAULT_DRIVER).resolve(); driver - .data_extract(details, img_file, path, format, zstd, auto_memory_hotplug) + .data_extract(details, img_file, path, format, zstd) .await } diff --git a/proxmox-file-restore/src/block_driver_qemu.rs b/proxmox-file-restore/src/block_driver_qemu.rs index cdff83f62..c915f3cfe 100644 --- a/proxmox-file-restore/src/block_driver_qemu.rs +++ b/proxmox-file-restore/src/block_driver_qemu.rs @@ -19,7 +19,7 @@ use pbs_datastore::catalog::ArchiveEntry; use super::block_driver::*; 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"; @@ -198,6 +198,20 @@ fn path_is_zfs(path: &[u8]) -> bool { 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 { let ticket = new_ticket(); let files = details @@ -218,18 +232,13 @@ impl BlockRestoreDriver for QemuBlockDriver { details: SnapRestoreDetails, img_file: String, mut path: Vec, - auto_memory_hotplug: bool, ) -> Async, Error>> { async move { let (cid, client) = ensure_running(&details).await?; if !path.is_empty() && path[0] != b'/' { path.insert(0, b'/'); } - if path_is_zfs(&path) && auto_memory_hotplug { - if let Err(err) = set_auto_memory_hotplug(cid, None).await { - log::error!("could not increase memory: {err}"); - } - } + handle_extra_guest_memory_needs(cid, &path).await; let path = base64::encode(img_file.bytes().chain(path).collect::>()); let mut result = client .get("api2/json/list", Some(json!({ "path": path }))) @@ -246,18 +255,13 @@ impl BlockRestoreDriver for QemuBlockDriver { mut path: Vec, format: Option, zstd: bool, - auto_memory_hotplug: bool, ) -> Async, Error>> { async move { let (cid, client) = ensure_running(&details).await?; if !path.is_empty() && path[0] != b'/' { path.insert(0, b'/'); } - if path_is_zfs(&path) && auto_memory_hotplug { - if let Err(err) = set_auto_memory_hotplug(cid, None).await { - log::error!("could not increase memory: {err}"); - } - } + handle_extra_guest_memory_needs(cid, &path).await; let path = base64::encode(img_file.bytes().chain(path).collect::>()); let (mut tx, rx) = tokio::io::duplex(1024 * 4096); let mut data = json!({ "path": path, "zstd": zstd }); diff --git a/proxmox-file-restore/src/main.rs b/proxmox-file-restore/src/main.rs index 15a328f5f..2f941e5aa 100644 --- a/proxmox-file-restore/src/main.rs +++ b/proxmox-file-restore/src/main.rs @@ -96,7 +96,6 @@ fn keyfile_path(param: &Value) -> Option { None } -#[allow(clippy::too_many_arguments)] async fn list_files( repo: BackupRepository, namespace: BackupNamespace, @@ -105,7 +104,6 @@ async fn list_files( crypt_config: Option>, keyfile: Option, driver: Option, - auto_memory_hotplug: bool, ) -> Result, Error> { let client = connect(&repo)?; let client = BackupReader::start( @@ -172,7 +170,7 @@ async fn list_files( snapshot, 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, 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: { @@ -251,7 +243,6 @@ async fn list( path: String, base64: bool, timeout: Option, - auto_memory_hotplug: bool, param: Value, ) -> Result<(), Error> { let repo = extract_repository_from_value(¶m)?; @@ -281,16 +272,7 @@ async fn list( let result = if let Some(timeout) = timeout { match tokio::time::timeout( std::time::Duration::from_secs(timeout), - list_files( - repo, - ns, - snapshot, - path, - crypt_config, - keyfile, - driver, - auto_memory_hotplug, - ), + list_files(repo, ns, snapshot, path, crypt_config, keyfile, driver), ) .await { @@ -298,17 +280,7 @@ async fn list( Err(_) => Err(http_err!(SERVICE_UNAVAILABLE, "list not finished in time")), } } else { - list_files( - repo, - ns, - snapshot, - path, - crypt_config, - keyfile, - driver, - auto_memory_hotplug, - ) - .await + list_files(repo, ns, snapshot, path, crypt_config, keyfile, driver).await }; let output_format = get_output_format(¶m); @@ -415,12 +387,6 @@ async fn list( type: BlockDriverType, 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, format: Option, zstd: bool, - auto_memory_hotplug: bool, param: Value, ) -> Result<(), Error> { let repo = extract_repository_from_value(¶m)?; @@ -516,7 +481,6 @@ async fn extract( path.clone(), Some(FileRestoreFormat::Pxar), false, - auto_memory_hotplug, ) .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) })?; } else { - let mut reader = data_extract( - driver, - details, - file, - path.clone(), - format, - zstd, - auto_memory_hotplug, - ) - .await?; + let mut reader = + data_extract(driver, details, file, path.clone(), format, zstd).await?; tokio::io::copy(&mut reader, &mut tokio::io::stdout()).await?; } }