Skip to content

Commit a76917f

Browse files
authored
Merge pull request #16 from justxuewei/feat/virtio-net
Add support to insert virtio-net devices
2 parents b855b16 + 50f10a7 commit a76917f

8 files changed

Lines changed: 103 additions & 9 deletions

File tree

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,13 @@ edition = "2021"
66
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
77

88
[dependencies]
9-
dragonball = { git = "https://github.com/kata-containers/kata-containers", branch = "main", features=["virtio-blk", "virtio-vsock", "hotplug", "dbs-upcall" ] }
9+
dragonball = { git = "https://github.com/kata-containers/kata-containers", branch = "main", features = [
10+
"virtio-blk",
11+
"virtio-vsock",
12+
"virtio-net",
13+
"hotplug",
14+
"dbs-upcall",
15+
] }
1016
clap = { version = "4.0.27", features = ["derive"] }
1117
serde = "1.0.27"
1218
serde_derive = "1.0.27"
@@ -26,4 +32,3 @@ slog-scope = "4.4.0"
2632
slog-stdlog = "4.1.1"
2733
serde_json = "1.0.89"
2834
crossbeam-channel = "0.5.6"
29-

README.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,21 @@ Create a virtio-vsock tunnel for Guest-to-Host communication.
7474
--vsock /tmp/vsock.sock create;
7575
```
7676

77+
Create virtio-net devices.
78+
79+
> The type of the `--virnets` receives an array of VirtioNetDeviceConfigInfo in the
80+
> format of JSON.
81+
82+
```
83+
./dbs-cli \
84+
--log-file dbs-cli.log --log-level ERROR \
85+
--kernel-path ~/path/to/kernel/vmlinux.bin \
86+
--rootfs ~/path/to/rootfs/bionic.rootfs.ext4 \
87+
--boot-args "console=ttyS0 tty0 reboot=k debug panic=1 pci=off root=/dev/vda1" \
88+
--virnets "[{\"iface_id\":\"eth0\",\"host_dev_name\":\"tap0\",\"num_queues\":2,\"queue_size\":0,\"guest_mac\":\"43:2D:9C:13:71:48\",\"allow_duplicate_mac\":true}]" \
89+
create;
90+
```
91+
7792
# 2. Usage
7893

7994
## 1. Create API Server and Update VM
@@ -85,6 +100,19 @@ After api socket created, you could use `./dbs-cli --api-sock-path [socket path]
85100
Right now, we have only one command for cpu resizing, and here is the command example.
86101

87102
`sudo ./dbs-cli --api-sock-path [socket path] --vcpu-resize 2 update`
103+
104+
Create hot-plug virtio-net devices via API Server.
105+
106+
> The type of the `--hotplug-virnets` receives an array of
107+
> VirtioNetDeviceConfigInfo in the format of JSON.
108+
109+
```
110+
sudo ./dbs-cli \
111+
--api-sock-path [socket path]
112+
--hotplug-virnets "[{\"iface_id\":\"eth0\",\"host_dev_name\":\"tap0\",\"num_queues\":2,\"queue_size\":0,\"guest_mac\":\"43:2D:9C:13:71:48\",\"allow_duplicate_mac\":true}]" \
113+
update
114+
```
115+
88116
## 2. Exit vm
89117

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

src/api_client.rs

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,14 @@ use serde_json::{json, Value};
1010
use crate::parser::DBSArgs;
1111

1212
pub fn run_api_client(args: DBSArgs) -> Result<()> {
13-
let request;
1413
if let Some(vcpu_resize_num) = args.update_args.vcpu_resize {
15-
request = request_cpu_resize(vcpu_resize_num);
16-
send_request(request, args.api_sock_path)?;
14+
let request = request_cpu_resize(vcpu_resize_num);
15+
send_request(request, &args.api_sock_path)?;
16+
}
17+
if let Some(config) = args.update_args.hotplug_virnets {
18+
let request = request_virtio_net(&config);
19+
send_request(request, &args.api_sock_path)?;
1720
}
18-
1921
Ok(())
2022
}
2123

@@ -26,7 +28,15 @@ fn request_cpu_resize(vcpu_resize_num: usize) -> Value {
2628
})
2729
}
2830

29-
fn send_request(request: Value, api_sock_path: String) -> Result<()> {
31+
/// Insert virtio-net devices
32+
fn request_virtio_net(virtio_net_config: &str) -> Value {
33+
json!({
34+
"action": "insert_virnets",
35+
"config": virtio_net_config,
36+
})
37+
}
38+
39+
fn send_request(request: Value, api_sock_path: &str) -> Result<()> {
3040
let mut unix_stream = UnixStream::connect(api_sock_path).context("Could not create stream")?;
3141

3242
unix_stream

src/api_server.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ use std::sync::{Arc, Mutex};
88
use std::io::prelude::*;
99
use std::os::unix::net::{UnixListener, UnixStream};
1010

11-
use anyhow::{Context, Result};
11+
use anyhow::{anyhow, Context, Result};
12+
use dragonball::device_manager::virtio_net_dev_mgr::VirtioNetDeviceConfigInfo;
1213

1314
use crate::vmm_comm_trait::VMMComm;
1415
use dragonball::api::v1::{VmmRequest, VmmResponse};
@@ -79,6 +80,18 @@ impl ApiServer {
7980
};
8081
return self.resize_vcpu(resize_vcpu_cfg);
8182
}
83+
Some("insert_virnets") => {
84+
let config_json = match v["config"].as_str() {
85+
Some(config_json) => config_json,
86+
None => return Err(anyhow!("The config of virtio-net device is required")),
87+
};
88+
let configs: Vec<VirtioNetDeviceConfigInfo> = serde_json::from_str(config_json)
89+
.context("Parse virtio-net device config from json")?;
90+
for config in configs.iter() {
91+
self.insert_virnet(config.clone())
92+
.context("Insert a virtio-net device to the Dragonball")?;
93+
}
94+
}
8295
_ => {
8396
println!("Unknown Actions");
8497
}

src/cli_instance.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ use dragonball::{
2020
BlockDeviceConfigInfo, BootSourceConfig, InstanceInfo, VmmRequest, VmmResponse,
2121
VsockDeviceConfigInfo,
2222
},
23+
device_manager::virtio_net_dev_mgr::VirtioNetDeviceConfigInfo,
2324
vm::{CpuTopology, VmConfigInfo},
2425
};
2526

@@ -154,6 +155,16 @@ impl CliInstance {
154155
.expect("failed to set vsock socket path");
155156
}
156157

158+
if !args.create_args.virnets.is_empty() {
159+
let configs: Vec<VirtioNetDeviceConfigInfo> =
160+
serde_json::from_str(&args.create_args.virnets)
161+
.expect("failed to parse virtio-net devices from JSON");
162+
for config in configs.into_iter() {
163+
self.insert_virnet(config)
164+
.expect("failed to insert a virtio-net device");
165+
}
166+
}
167+
157168
// start micro-vm
158169
self.instance_start().expect("failed to start micro-vm");
159170

src/parser/args.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,17 @@ pub struct CreateArgs {
206206
display_order = 2
207207
)]
208208
pub vsock: String,
209+
210+
#[clap(
211+
long,
212+
value_parser,
213+
default_value = "",
214+
help = r#"Insert virtio-net devices into the Dragonball.
215+
The type of it is an array of VirtioNetDeviceConfigInfo, e.g.
216+
--virnets '[{"iface_id":"eth0","host_dev_name":"tap0","num_queues":2,"queue_size":0,"allow_duplicate_mac":true}]'"#,
217+
display_order = 2
218+
)]
219+
pub virnets: String,
209220
}
210221

211222
/// Config boot source including rootfs file path
@@ -255,4 +266,13 @@ pub struct UpdateArgs {
255266
display_order = 2
256267
)]
257268
pub vcpu_resize: Option<usize>,
269+
#[clap(
270+
long,
271+
value_parser,
272+
help = r#"Insert hotplug virtio-net devices into the Dragonball.
273+
The type of it is an array of VirtioNetDeviceConfigInfo, e.g.
274+
--hotplug-virnets '[{"iface_id":"eth0","host_dev_name":"tap0","num_queues":2,"queue_size":0,"allow_duplicate_mac":true}]'"#,
275+
display_order = 2
276+
)]
277+
pub hotplug_virnets: Option<String>,
258278
}

src/vmm_comm_trait.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use dragonball::{
99
BlockDeviceConfigInfo, BootSourceConfig, VmmAction, VmmActionError, VmmData, VmmRequest,
1010
VmmResponse, VsockDeviceConfigInfo,
1111
},
12+
device_manager::virtio_net_dev_mgr::VirtioNetDeviceConfigInfo,
1213
vcpu::VcpuResizeInfo,
1314
vm::VmConfigInfo,
1415
};
@@ -132,4 +133,10 @@ pub trait VMMComm {
132133
.with_context(|| format!("Failed to resize vcpu {resize_vcpu_cfg:?}"))?;
133134
Ok(())
134135
}
136+
137+
fn insert_virnet(&self, config: VirtioNetDeviceConfigInfo) -> Result<()> {
138+
self.handle_request(Request::Sync(VmmAction::InsertNetworkDevice(config)))
139+
.context("Request to insert a virtio-net device")?;
140+
Ok(())
141+
}
135142
}

0 commit comments

Comments
 (0)