Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pci: add pci device support in dbs-cli #30

Merged
merged 2 commits into from
Jan 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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*
96 changes: 78 additions & 18 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ dragonball = { git = "https://github.com/kata-containers/kata-containers", branc
"hotplug",
"dbs-upcall",
"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
Loading