Skip to content

petri: use com3 for kmsg logs #1176

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

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
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
13 changes: 10 additions & 3 deletions flowey/flowey_lib_hvlite/src/init_hyperv_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,18 @@ impl FlowNode for Node {
|_| {
let sh = xshell::Shell::new()?;

// TODO: add this to the initial CI image (and maybe the reg keys too)
// TODO: perform these operation on the reference CI image

// Install the Hyper-V Powershell commands
xshell::cmd!(sh, "DISM /Online /Norestart /Enable-Feature /All /FeatureName:Microsoft-Hyper-V-Management-PowerShell").run()?;

let firmware_load_path = r#"HKLM\Software\Microsoft\Windows NT\CurrentVersion\Virtualization"#;
xshell::cmd!(sh, "reg add {firmware_load_path} /v AllowFirmwareLoadFromFile /t REG_DWORD /d 1 /f").run()?;
let virt_reg_path = r#"HKLM\Software\Microsoft\Windows NT\CurrentVersion\Virtualization"#;

// Allow loading IGVM from file (to run custom OpenHCL firmware)
xshell::cmd!(sh, "reg add {virt_reg_path} /v AllowFirmwareLoadFromFile /t REG_DWORD /d 1 /f").run()?;

// Enable COM3 and COM4 for Hyper-V VMs so we can get the OpenHCL KMSG logs over serial
xshell::cmd!(sh, "reg add {virt_reg_path} /v EnableAdditionalComPorts /t REG_DWORD /d 1 /f").run()?;

Ok(())
}
Expand Down
61 changes: 46 additions & 15 deletions petri/src/vm/hyperv/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -342,14 +342,14 @@ impl PetriVmConfigHyperV {

let mut log_tasks = Vec::new();

let serial_pipe_path = vm.set_vm_com_port(1)?;
let guest_serial_pipe_path = vm.set_vm_com_port(1)?;
let serial_log_file = self.log_source.log_file("guest")?;
log_tasks.push(self.driver.spawn("guest-log", {
let driver = self.driver.clone();
async move {
let serial = diag_client::hyperv::open_serial_port(
&driver,
diag_client::hyperv::ComPortAccessInfo::PortPipePath(&serial_pipe_path),
diag_client::hyperv::ComPortAccessInfo::PortPipePath(&guest_serial_pipe_path),
)
.await?;
crate::log_stream(serial_log_file, PolledPipe::new(&driver, serial)?).await
Expand All @@ -358,21 +358,52 @@ impl PetriVmConfigHyperV {

let openhcl_diag_handler = if self.openhcl_igvm.is_some() {
let openhcl_log_file = self.log_source.log_file("openhcl")?;
log_tasks.push(self.driver.spawn("openhcl-log", {
let driver = self.driver.clone();
let vmid = *vm.vmid();
async move {
let diag_client = diag_client::DiagClient::from_hyperv_id(driver.clone(), vmid);
loop {
diag_client.wait_for_server().await?;
crate::kmsg_log_task(
openhcl_log_file.clone(),
diag_client.kmsg(true).await?,

// Attempt to enable COM3 and use that to get KMSG logs, otherwise
// fall back to use diag_client.
//
// Hyper-V VBS VMs don't work with COM3 enabled for some reason.
let is_not_vbs = !matches!(
self.guest_state_isolation_type,
powershell::HyperVGuestStateIsolationType::Vbs
);
let openhcl_serial_pipe_path = is_not_vbs.then(|| vm.set_vm_com_port(3).ok()).flatten();

if let Some(openhcl_serial_pipe_path) = openhcl_serial_pipe_path {
log_tasks.push(self.driver.spawn("openhcl-log", {
let driver = self.driver.clone();
async move {
let serial = diag_client::hyperv::open_serial_port(
&driver,
diag_client::hyperv::ComPortAccessInfo::PortPipePath(
&openhcl_serial_pipe_path,
),
)
.await?
.await?;
crate::log_stream(openhcl_log_file, PolledPipe::new(&driver, serial)?).await
}
}
}));
}));
} else {
tracing::warn!("falling back to getting kmsg logs from diag_client");

log_tasks.push(self.driver.spawn("openhcl-log", {
let driver = self.driver.clone();
let vmid = *vm.vmid();
async move {
let diag_client =
diag_client::DiagClient::from_hyperv_id(driver.clone(), vmid);
loop {
diag_client.wait_for_server().await?;
crate::kmsg_log_task(
openhcl_log_file.clone(),
diag_client.kmsg(true).await?,
)
.await?
}
}
}));
}

Some(OpenHclDiagHandler::new(
diag_client::DiagClient::from_hyperv_id(self.driver.clone(), *vm.vmid()),
))
Expand Down