Skip to content

Commit 14e89ea

Browse files
adamqqqplaywllenyj
authored andcommitted
Add support to insert virtio-blk devices
This PR gives the users two ways to insert virtio-blk devices: 1. Insert before VMM launched. The parameter is `--virblks '[{"drive_id":"testblk","device_type":"RawBlock","path_on_host":"/path/to/test.img","is_root_device":false,"is_read_only":false,"is_direct":false,"no_drop":false,"num_queues":1,"queue_size":1024}]'`. 2. Insert hotplug devices after VMM launched. The parameter is `--hotplug-virblks '[{"drive_id":"testblk","device_type":"RawBlock","path_on_host":"/path/to/test.img","is_root_device":false,"is_read_only":false,"is_direct":false,"no_drop":false,"num_queues":1,"queue_size":1024}]'` Both of these parameters receive an array of BlockDeviceConfigInfo in the format of JSON to make them more configurable. Fixes: #19 Signed-off-by: Qinqi Qu <quqinqi@linux.alibaba.com>
1 parent bd3082f commit 14e89ea

6 files changed

Lines changed: 90 additions & 0 deletions

File tree

README.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,21 @@ Create virtio-net devices.
8989
create;
9090
```
9191

92+
Create virtio-blk devices.
93+
94+
> The type of the `--virblks` receives an array of BlockDeviceConfigInfo in the
95+
> format of JSON.
96+
97+
```
98+
./dbs-cli \
99+
--log-file dbs-cli.log --log-level ERROR \
100+
--kernel-path ~/path/to/kernel/vmlinux.bin \
101+
--rootfs ~/path/to/rootfs/bionic.rootfs.ext4 \
102+
--boot-args "console=ttyS0 tty0 reboot=k debug panic=1 pci=off root=/dev/vda1" \
103+
--virblks '[{"drive_id":"testblk","device_type":"RawBlock","path_on_host":"/path/to/test.img","is_root_device":false,"is_read_only":false,"is_direct":false,"no_drop":false,"num_queues":1,"queue_size":1024}]' \
104+
create;
105+
```
106+
92107
# 2. Usage
93108

94109
## 1. Create API Server and Update VM
@@ -113,6 +128,18 @@ sudo ./dbs-cli \
113128
update
114129
```
115130

131+
Create hot-plug virtio-blk devices via API Server.
132+
133+
> The type of the `--hotplug-virblks` receives an array of
134+
> BlockDeviceConfigInfo in the format of JSON.
135+
136+
```
137+
sudo ./dbs-cli \
138+
--api-sock-path [socket path]
139+
--hotplug-virblks '[{"drive_id":"testblk","device_type":"RawBlock","path_on_host":"/path/to/test.img","is_root_device":false,"is_read_only":false,"is_direct":false,"no_drop":false,"num_queues":1,"queue_size":1024}]' \
140+
update
141+
```
142+
116143
## 2. Exit vm
117144

118145
> If you want to exit vm, just input `reboot` in vm's console.

src/api_client.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ pub fn run_api_client(args: DBSArgs) -> Result<()> {
1818
let request = request_virtio_net(&config);
1919
send_request(request, &args.api_sock_path)?;
2020
}
21+
if let Some(config) = args.update_args.hotplug_virblks {
22+
let request = request_virtio_blk(&config);
23+
send_request(request, &args.api_sock_path)?;
24+
}
2125
Ok(())
2226
}
2327

@@ -36,6 +40,14 @@ fn request_virtio_net(virtio_net_config: &str) -> Value {
3640
})
3741
}
3842

43+
/// Insert virtio-blk devices
44+
fn request_virtio_blk(virtio_blk_config: &str) -> Value {
45+
json!({
46+
"action": "insert_virblks",
47+
"config": virtio_blk_config,
48+
})
49+
}
50+
3951
fn send_request(request: Value, api_sock_path: &str) -> Result<()> {
4052
let mut unix_stream = UnixStream::connect(api_sock_path).context("Could not create stream")?;
4153

src/api_server.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use std::io::prelude::*;
99
use std::os::unix::net::{UnixListener, UnixStream};
1010

1111
use anyhow::{anyhow, Context, Result};
12+
use dragonball::device_manager::blk_dev_mgr::BlockDeviceConfigInfo;
1213
use dragonball::device_manager::virtio_net_dev_mgr::VirtioNetDeviceConfigInfo;
1314

1415
use crate::vmm_comm_trait::VMMComm;
@@ -92,6 +93,18 @@ impl ApiServer {
9293
.context("Insert a virtio-net device to the Dragonball")?;
9394
}
9495
}
96+
Some("insert_virblks") => {
97+
let config_json = match v["config"].as_str() {
98+
Some(config_json) => config_json,
99+
None => return Err(anyhow!("The config of virtio-blk device is required")),
100+
};
101+
let configs: Vec<BlockDeviceConfigInfo> = serde_json::from_str(config_json)
102+
.context("Parse virtio-blk device config from json")?;
103+
for config in configs.iter() {
104+
self.insert_virblk(config.clone())
105+
.context("Insert a virtio-blk device to the Dragonball")?;
106+
}
107+
}
95108
_ => {
96109
println!("Unknown Actions");
97110
}

src/cli_instance.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,16 @@ impl CliInstance {
165165
}
166166
}
167167

168+
if !args.create_args.virblks.is_empty() {
169+
let configs: Vec<BlockDeviceConfigInfo> =
170+
serde_json::from_str(&args.create_args.virblks)
171+
.expect("failed to parse virtio-blk devices from JSON");
172+
for config in configs.into_iter() {
173+
self.insert_virblk(config)
174+
.expect("failed to insert a virtio-blk device");
175+
}
176+
}
177+
168178
// start micro-vm
169179
self.instance_start().expect("failed to start micro-vm");
170180

src/parser/args.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,17 @@ The type of it is an array of VirtioNetDeviceConfigInfo, e.g.
217217
display_order = 2
218218
)]
219219
pub virnets: String,
220+
221+
#[clap(
222+
long,
223+
value_parser,
224+
default_value = "",
225+
help = r#"Insert virtio-blk devices into the Dragonball.
226+
The type of it is an array of BlockDeviceConfigInfo, e.g.
227+
--virblks '[{"drive_id":"testblk","device_type":"RawBlock","path_on_host":"/path/to/test.img","is_root_device":false,"is_read_only":false,"is_direct":false,"no_drop":false,"num_queues":1,"queue_size":1024}]'"#,
228+
display_order = 2
229+
)]
230+
pub virblks: String,
220231
}
221232

222233
/// Config boot source including rootfs file path
@@ -266,6 +277,7 @@ pub struct UpdateArgs {
266277
display_order = 2
267278
)]
268279
pub vcpu_resize: Option<usize>,
280+
269281
#[clap(
270282
long,
271283
value_parser,
@@ -275,4 +287,14 @@ The type of it is an array of VirtioNetDeviceConfigInfo, e.g.
275287
display_order = 2
276288
)]
277289
pub hotplug_virnets: Option<String>,
290+
291+
#[clap(
292+
long,
293+
value_parser,
294+
help = r#"Insert virtio-blk devices into the Dragonball.
295+
The type of it is an array of BlockDeviceConfigInfo, e.g.
296+
--hotplug-virblks '[{"drive_id":"testblk","device_type":"RawBlock","path_on_host":"/path/to/test.img","is_root_device":false,"is_read_only":false,"is_direct":false,"no_drop":false,"num_queues":1,"queue_size":1024}]'"#,
297+
display_order = 2
298+
)]
299+
pub hotplug_virblks: Option<String>,
278300
}

src/vmm_comm_trait.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,4 +139,10 @@ pub trait VMMComm {
139139
.context("Request to insert a virtio-net device")?;
140140
Ok(())
141141
}
142+
143+
fn insert_virblk(&self, blk_cfg: BlockDeviceConfigInfo) -> Result<()> {
144+
self.handle_request(Request::Sync(VmmAction::InsertBlockDevice(blk_cfg.clone())))
145+
.with_context(|| format!("Failed to insert virtio-blk device {:?}", blk_cfg))?;
146+
Ok(())
147+
}
142148
}

0 commit comments

Comments
 (0)