Skip to content

Commit

Permalink
pci: add pci device support in dbs-cli
Browse files Browse the repository at this point in the history
1. attach pci device during the boot time of Dragonball.
2. hot plug pci device when the Dragonball is running.
3. prepare to hot unplug pci device when the Dragonball is running.
4. hot unplug pci device when the Dragonball is running.

fixes: #29

Signed-off-by: Chao Wu <[email protected]>
  • Loading branch information
studychao committed Jan 22, 2024
1 parent d720702 commit a2053fc
Show file tree
Hide file tree
Showing 12 changed files with 229 additions and 69 deletions.
6 changes: 5 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,8 @@
**/*.rs.bk

# log files
**/*.log
**/*.log

.idea*

.vscode*
79 changes: 71 additions & 8 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
dragonball = { path = "/root/kata-containers/src/dragonball", features = [
dragonball = { git = "https://github.com/kata-containers/kata-containers", branch = "main", features = [
"virtio-blk",
"virtio-fs",
"virtio-vsock",
Expand All @@ -15,7 +15,7 @@ dragonball = { path = "/root/kata-containers/src/dragonball", features = [
"hotplug",
"dbs-upcall",
"vhost-user-net",
"vhost-user-net"
"host-device"
] }
clap = { version = "4.0.27", features = ["derive"] }
serde = "1.0.27"
Expand Down
41 changes: 41 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,30 @@ The supported network devices include:
}
```

### PCI Device

You can choose to attach a pci device during the boot time of Dragonball.
Please note that hostdev_id and bus_slot_func are the must parameters for attaching pci device.
Please make sure that pci device is binded to `vfio-pci` driver.

```
./dbs-cli create --kernel-path $KERNEL_PATH --rootfs $ROOTFS_PATH --boot-args "console=ttyS0 tty0 reboot=k debug panic=1 root=/dev/vda1" --hostdev-id $HOST_DEVICE_ID --bus-slot-func $BUS_SLOT_FUNC
```

#### How to get hostdev_id and bus_slot_func?

hostdev_id: This is an id you pick for each pci device attaching into VM. So name it whatever number you want.

bus_slot_func: take a network device as the example, you could use `lspci | grep "network device"` and you could get something like
```
[root@xxx ~]# lspci | grep "network device"
5d:00.0 Ethernet controller: Red Hat, Inc. Virtio network device
5e:00.0 Ethernet controller: Red Hat, Inc. Virtio network device
```
`5d:00.0` is the bus_slot_func.

As an alternative way to insert a host device, you can use upcall to hotplug / hot-unplug a pci device into Dragonball while Dragonball is running, for more details please go to advanced usage part of this document.

## Advanced Usage

### Create API Server and Update VM
Expand Down Expand Up @@ -153,6 +177,23 @@ sudo ./dbs-cli \
--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}]' \
```

Hotplug a pci device into Dragonball
```
./dbs-cli --api-sock-path $API_SOCK_PATH update --bus-slot-func $BUS_SLOT_FUNC --hostdev-id $HOST_DEVICE_ID
```

Prepare hot-unplug a pci device into Dragonball (must do before hotunplug)

```
./dbs-cli --api-sock-path ./sock update --prepare-remove-host-device $HOST_DEVICE_ID
```

Hot-unplug a pci device into Dragonball

```
./dbs-cli --api-sock-path ./sock update --remove-host-device $HOST_DEVICE_ID
```

TODO : add document for hot-plug virtio-fs

### Exit VM
Expand Down
44 changes: 43 additions & 1 deletion src/api_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,25 +7,45 @@ use std::os::unix::net::UnixStream;
use anyhow::{Context, Result};
use serde_json::{json, Value};

use crate::parser::args::UpdateArgs;
use crate::parser::args::{HostDeviceArgs, UpdateArgs};

pub fn run_api_client(args: UpdateArgs, api_sock_path: &str) -> Result<()> {
if let Some(vcpu_resize_num) = args.vcpu_resize {
let request = request_cpu_resize(vcpu_resize_num);
send_request(request, api_sock_path)?;
}

if let Some(config) = args.virnets {
let request = request_virtio_net(&config);
send_request(request, api_sock_path)?;
}

if let Some(config) = args.virblks {
let request = request_virtio_blk(&config);
send_request(request, api_sock_path)?;
}

if let Some(config) = args.patch_fs {
let request = request_patch_fs(&config);
send_request(request, api_sock_path)?;
}

if let Some(host_device_args) = args.insert_host_device {
if host_device_args.bus_slot_func.is_some() {
let request = request_insert_host_device(host_device_args.clone());
send_request(request, api_sock_path)?;
}
}

if let Some(host_device_id) = args.prepare_remove_host_device {
let request = request_prepare_remove_host_device(host_device_id.clone());
send_request(request, api_sock_path)?;
}

if let Some(host_device_id) = args.remove_host_device {
let request = request_remove_host_device(host_device_id.clone());
send_request(request, api_sock_path)?;
}
Ok(())
}

Expand Down Expand Up @@ -59,6 +79,28 @@ fn request_patch_fs(patch_fs_config: &str) -> Value {
})
}

fn request_insert_host_device(host_device_args: HostDeviceArgs) -> Value {
json!({
"action": "insert_host_device",
"hostdev-id": host_device_args.hostdev_id.expect("host device arg should be provided to insert host device."),
"bus-slot-func": host_device_args.bus_slot_func.expect("bus_slot_func should be provided to insert host device."),
})
}

fn request_prepare_remove_host_device(host_device_id: String) -> Value {
json!({
"action": "prepare_remove_host_device",
"hostdev-id": host_device_id.clone(),
})
}

fn request_remove_host_device(host_device_id: String) -> Value {
json!({
"action": "remove_host_device",
"hostdev-id": host_device_id.clone(),
})
}

fn send_request(request: Value, api_sock_path: &str) -> Result<()> {
let mut unix_stream = UnixStream::connect(api_sock_path).context("Could not create stream")?;

Expand Down
Loading

0 comments on commit a2053fc

Please sign in to comment.