Repository navigation
Expand file tree
/
Copy path002-fix-qemu-cmdline.patch
More file actions
159 lines (148 loc) · 5.49 KB
/
Copy path002-fix-qemu-cmdline.patch
File metadata and controls
159 lines (148 loc) · 5.49 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
diff --git a/pbs-buildcfg/src/lib.rs b/pbs-buildcfg/src/lib.rs
index 3d087015..ba3b5702 100644
--- a/pbs-buildcfg/src/lib.rs
+++ b/pbs-buildcfg/src/lib.rs
@@ -53,8 +53,9 @@ macro_rules! PROXMOX_BACKUP_CACHE_DIR_M {
#[macro_export]
macro_rules! PROXMOX_BACKUP_FILE_RESTORE_BIN_DIR_M {
- () => {
- "/usr/lib/x86_64-linux-gnu/proxmox-backup/file-restore"
+ ($arch:expr) => {
+ // Different architectures have different paths.
+ format!("/usr/lib/{}-linux-gnu/proxmox-backup/file-restore", $arch)
};
}
@@ -93,8 +94,16 @@ pub const PROXMOX_BACKUP_INITRAMFS_DBG_FN: &str = concat!(
);
/// filename of the kernel to use for booting single file restore VMs
-pub const PROXMOX_BACKUP_KERNEL_FN: &str =
- concat!(PROXMOX_BACKUP_FILE_RESTORE_BIN_DIR_M!(), "/bzImage");
+pub fn PROXMOX_BACKUP_KERNEL_FN() -> String {
+ let arch = std::env::consts::ARCH;
+ let file_restore_dir = PROXMOX_BACKUP_FILE_RESTORE_BIN_DIR_M!(arch);
+
+ if arch == "x86_64" {
+ format!("{}/bzImage", file_restore_dir)
+ } else {
+ format!("{}/Image", file_restore_dir)
+ }
+}
pub const PROXMOX_BACKUP_SUBSCRIPTION_FN: &str = configdir!("/subscription");
diff --git a/proxmox-file-restore/src/qemu_helper.rs b/proxmox-file-restore/src/qemu_helper.rs
index e0e16911..b9ae95b5 100644
--- a/proxmox-file-restore/src/qemu_helper.rs
+++ b/proxmox-file-restore/src/qemu_helper.rs
@@ -4,6 +4,7 @@ use std::io::prelude::*;
use std::os::unix::io::AsRawFd;
use std::path::PathBuf;
use std::time::{Duration, Instant};
+use std::env;
use anyhow::{bail, format_err, Error};
use serde_json::json;
@@ -52,7 +53,7 @@ fn create_restore_log_dir() -> Result<String, Error> {
}
fn validate_img_existence(debug: bool) -> Result<(), Error> {
- let kernel = PathBuf::from(pbs_buildcfg::PROXMOX_BACKUP_KERNEL_FN);
+ let kernel = PathBuf::from(pbs_buildcfg::PROXMOX_BACKUP_KERNEL_FN());
let initramfs = PathBuf::from(if debug {
pbs_buildcfg::PROXMOX_BACKUP_INITRAMFS_DBG_FN
} else {
@@ -255,7 +256,7 @@ pub async fn start_vm(
"none",
"-enable-kvm",
"-kernel",
- pbs_buildcfg::PROXMOX_BACKUP_KERNEL_FN,
+ &pbs_buildcfg::PROXMOX_BACKUP_KERNEL_FN(),
"-initrd",
&ramfs_path,
"-append",
@@ -294,38 +295,64 @@ pub async fn start_vm(
"driver=pbs,repository={}{},snapshot={},archive={}{},read-only=on,node-name=drive{}",
details.repo, namespace, details.snapshot, file, keyfile, id
));
-
+ let arch = std::env::consts::ARCH;
// a PCI bus can only support 32 devices, so add a new one every 32
let bus = (id / 32) + 2;
- if id % 32 == 0 {
- drives.push("-device".to_owned());
- drives.push(format!("pci-bridge,id=bridge{bus},chassis_nr={bus}"));
+ if arch == "x86_64" {
+ if id % 32 == 0 {
+ drives.push("-device".to_owned());
+ drives.push(format!("pci-bridge,id=bridge{bus},chassis_nr={bus}"));
+ }
}
drives.push("-device".to_owned());
// drive serial is used by VM to map .fidx files to /dev paths
let serial = file.strip_suffix(".img.fidx").unwrap_or(&file);
- drives.push(format!(
- "virtio-blk-pci,drive=drive{id},serial={serial},bus=bridge{bus}"
- ));
+ if arch == "x86_64" {
+ drives.push(format!(
+ "virtio-blk-pci,drive=drive{id},serial={serial},bus=bridge{bus}"
+ ));
+ } else {
+ drives.push(format!(
+ // We use virtio-blk-device because QEMU will automatically assigns PCI addresses.
+ "virtio-blk-device,drive=drive{id},serial={serial}"
+ ));
+ }
id += 1;
}
- let ram = if debug {
+ let arch = std::env::consts::ARCH;
+
+ let mut ram = if debug {
1024
} else {
// add more RAM if many drives are given
+ // We need more memory for !x86 device
match id {
- f if f < 10 => 192,
- f if f < 20 => 256,
- _ => 384,
+ f if f < 10 => 512,
+ f if f < 20 => 768,
+ _ => 1024,
}
};
+ // loongarch minimum memeory is 1024
+ if arch == "loongarch64" {
+ ram = 1024;
+ }
+
+ let edk2_path = match arch {
+ "loongarch64" => "/usr/share/pve-edk2-firmware/LOONGARCH64_VIRT_CODE.fd",
+ "aarch64" => "/usr/share/pve-edk2-firmware/AAVMF_CODE.fd",
+ "riscv64" => "/usr/share/pve-edk2-firmware/RISCV_VIRT_CODE.fd",
+ _ => "/usr/share/pve-edk2-firmware/bios.fd",
+ };
+
+
// Try starting QEMU in a loop to retry if we fail because of a bad 'cid' value
+ let qemu_bin = format!("qemu-system-{}", arch);
let mut attempts = 0;
loop {
- let mut qemu_cmd = std::process::Command::new("qemu-system-x86_64");
+ let mut qemu_cmd = std::process::Command::new(&qemu_bin);
qemu_cmd.args(base_args.iter());
qemu_cmd.arg("-m");
qemu_cmd.arg(format!(
@@ -346,6 +373,16 @@ pub async fn start_vm(
qemu_cmd.arg("-mon");
qemu_cmd.arg("chardev=qmp,mode=control");
+ // Use virt and tcg to start file-restore.
+ if arch != "x86_64" {
+ qemu_cmd.arg("-M");
+ qemu_cmd.arg("virt");
+ qemu_cmd.arg("-cpu");
+ qemu_cmd.arg("max");
+ qemu_cmd.arg("-bios");
+ qemu_cmd.arg(format!("{}",edk2_path));
+ }
+
if debug {
let debug_args = [
"-chardev",