]> git.proxmox.com Git - proxmox-backup.git/blobdiff - src/bin/proxmox-backup-client.rs
src/client/remote_chunk_reader.rs: implement simple caching
[proxmox-backup.git] / src / bin / proxmox-backup-client.rs
index 53456c4c6e7387ee05e42182d1a541859c8e1385..2ddd7f5b97ef4a53d8d27ac0cbebfc9c9bf0d5e1 100644 (file)
@@ -626,9 +626,13 @@ fn restore(
         }
     };
 
-    if !archive_name.ends_with(".pxar") {
-        bail!("unknown file extensions - unable to restore '{}'", archive_name);
-    }
+    let server_archive_name = if archive_name.ends_with(".pxar") {
+        format!("{}.didx", archive_name)
+    } else if archive_name.ends_with(".img") {
+        format!("{}.fidx", archive_name)
+    } else {
+        bail!("unknown archive file extension (expected .pxar of .img)");
+    };
 
     let client = client.start_backup_reader(repo.store(), &backup_type, &backup_id, backup_time, true).wait()?;
 
@@ -640,23 +644,50 @@ fn restore(
         .custom_flags(libc::O_TMPFILE)
         .open("/tmp")?;
 
-    let tmpfile = client.download(&format!("{}.didx", archive_name), tmpfile).wait()?;
+    if server_archive_name.ends_with(".didx") {
+        let tmpfile = client.download(&server_archive_name, tmpfile).wait()?;
 
-    let index = DynamicIndexReader::new(tmpfile)?;
+        let index = DynamicIndexReader::new(tmpfile)
+            .map_err(|err| format_err!("unable to read dynamic index '{}' - {}", archive_name, err))?;
 
-    let chunk_reader = RemoteChunkReader::new(client.clone(), crypt_config);
+        let most_used = index.find_most_used_chunks(8);
 
-    let mut reader = BufferedDynamicReader::new(index, chunk_reader);
+        let chunk_reader = RemoteChunkReader::new(client.clone(), crypt_config, most_used);
 
-    let feature_flags = pxar::CA_FORMAT_DEFAULT;
-    let mut decoder = pxar::SequentialDecoder::new(&mut reader, feature_flags);
+        let mut reader = BufferedDynamicReader::new(index, chunk_reader);
 
-    decoder.restore(Path::new(target), & |path| {
-        if verbose {
-            println!("{:?}", path);
-        }
-        Ok(())
-    })?;
+        let feature_flags = pxar::CA_FORMAT_DEFAULT;
+        let mut decoder = pxar::SequentialDecoder::new(&mut reader, feature_flags, |path| {
+            if verbose {
+                println!("{:?}", path);
+            }
+            Ok(())
+        });
+
+        decoder.restore(Path::new(target))?;
+
+    } else if server_archive_name.ends_with(".fidx") {
+        let tmpfile = client.download(&server_archive_name, tmpfile).wait()?;
+
+        let index = FixedIndexReader::new(tmpfile)
+            .map_err(|err| format_err!("unable to read fixed index '{}' - {}", archive_name, err))?;
+
+        let most_used = index.find_most_used_chunks(8);
+
+        let chunk_reader = RemoteChunkReader::new(client.clone(), crypt_config, most_used);
+
+        let mut reader = BufferedFixedReader::new(index, chunk_reader);
+
+        let mut writer = std::fs::OpenOptions::new()
+            .write(true)
+            .create(true)
+            .create_new(true)
+            .open(target)
+            .map_err(|err| format_err!("unable to create target file {:?} - {}", target, err))?;
+
+        std::io::copy(&mut reader, &mut writer)
+            .map_err(|err| format_err!("unable to store data - {}", err))?;
+    }
 
     Ok(Value::Null)
 }