runtime-rs: Handle initdata block device config during sandbox start

Retrieve the Initdata string content from the security_info of the
Configuration. Based on the Protection Platform type, calculate the
digest of the Initdata. Write the Initdata content to the block
device. Subsequently, construct the BlockConfig based on this block
device information.

Signed-off-by: alex.lyn <alex.lyn@antgroup.com>
This commit is contained in:
alex.lyn 2025-06-13 17:30:23 +08:00
parent 6ea1494701
commit 5c8170dbb9

View File

@ -37,13 +37,19 @@ use kata_types::capabilities::CapabilityBits;
use kata_types::config::hypervisor::Hypervisor as HypervisorConfig;
use kata_types::config::hypervisor::HYPERVISOR_NAME_CH;
use kata_types::config::TomlConfig;
use kata_types::initdata::{calculate_initdata_digest, ProtectedPlatform};
use oci_spec::runtime as oci;
use persist::{self, sandbox_persist::Persist};
use protobuf::SpecialFields;
use resource::coco_data::initdata::{
InitDataConfig, KATA_INIT_DATA_IMAGE, KATA_SHARED_INIT_DATA_PATH,
};
use resource::coco_data::initdata_block;
use resource::manager::ManagerArgs;
use resource::network::{dan_config_path, DanNetworkConfig, NetworkConfig, NetworkWithNetNsConfig};
use resource::{ResourceConfig, ResourceManager};
use runtime_spec as spec;
use std::path::Path;
use std::sync::Arc;
use strum::Display;
use tokio::sync::{mpsc::Sender, Mutex, RwLock};
@ -157,6 +163,19 @@ impl VirtSandbox {
resource_configs.push(vm_rootfs);
}
// prepare protection device config
let _init_data = if let Some(initdata) = self
.prepare_initdata_device_config(&self.hypervisor.hypervisor_config().await)
.await
.context("failed to prepare initdata device config")?
{
resource_configs.push(ResourceConfig::InitData(initdata.0));
Some(initdata.1)
} else {
None
};
// prepare protection device config
if let Some(protection_dev_config) = self
.prepare_protection_device_config(&self.hypervisor.hypervisor_config().await)
@ -411,6 +430,55 @@ impl VirtSandbox {
}
}
async fn prepare_initdata_device_config(
&self,
hypervisor_config: &HypervisorConfig,
) -> Result<Option<InitDataConfig>> {
let initdata = hypervisor_config.security_info.initdata.clone();
if initdata.is_empty() {
return Ok(None);
}
info!(sl!(), "Init Data Content String: {:?}", &initdata);
let available_protection = available_guest_protection()?;
info!(
sl!(),
"sandbox: available protection: {:?}", available_protection
);
let initdata_digest = match available_protection {
GuestProtection::Tdx => calculate_initdata_digest(&initdata, ProtectedPlatform::Tdx)?,
GuestProtection::Snp(_details) => {
calculate_initdata_digest(&initdata, ProtectedPlatform::Snp)?
}
// TODO: there's more `GuestProtection` types to be supported.
_ => return Ok(None),
};
info!(
sl!(),
"calculate initdata: {:?} with initdata digest {:?}", &initdata, &initdata_digest
);
// initdata within compressed rawblock
let image_path = Path::new(KATA_SHARED_INIT_DATA_PATH)
.join(&self.sid)
.join(KATA_INIT_DATA_IMAGE);
initdata_block::push_data(&image_path, &initdata)?;
info!(
sl!(),
"initdata push data into compressed block: {:?}", &image_path
);
let block_driver = &hypervisor_config.boot_info.vm_rootfs_driver;
let block_config = BlockConfig {
path_on_host: image_path.display().to_string(),
is_readonly: true,
driver_option: block_driver.clone(),
..Default::default()
};
let initdata_config = InitDataConfig(block_config, initdata_digest);
info!(sl!(), "initdata config: {:?}", initdata_config.clone());
Ok(Some(initdata_config))
}
fn has_prestart_hooks(
&self,
prestart_hooks: &[oci::Hook],