mirror of
				https://github.com/edera-dev/krata.git
				synced 2025-11-03 23:29:39 +00:00 
			
		
		
		
	oh my god, we have a console
This commit is contained in:
		@ -16,8 +16,6 @@ use std::cmp::{max, min};
 | 
			
		||||
use std::ffi::c_void;
 | 
			
		||||
use std::mem::size_of;
 | 
			
		||||
use std::slice;
 | 
			
		||||
use xencall::domctl::DomainControl;
 | 
			
		||||
use xencall::memory::MemoryControl;
 | 
			
		||||
use xencall::sys::{VcpuGuestContext, MMUEXT_PIN_L4_TABLE};
 | 
			
		||||
use xencall::XenCall;
 | 
			
		||||
 | 
			
		||||
@ -41,9 +39,8 @@ pub struct BootImageInfo {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub struct BootSetup<'a> {
 | 
			
		||||
    domctl: &'a DomainControl<'a>,
 | 
			
		||||
    memctl: &'a MemoryControl<'a>,
 | 
			
		||||
    phys: PhysicalPages<'a>,
 | 
			
		||||
    call: &'a XenCall,
 | 
			
		||||
    pub phys: PhysicalPages<'a>,
 | 
			
		||||
    domid: u32,
 | 
			
		||||
    virt_alloc_end: u64,
 | 
			
		||||
    pfn_alloc_end: u64,
 | 
			
		||||
@ -55,7 +52,7 @@ pub struct BootSetup<'a> {
 | 
			
		||||
pub struct DomainSegment {
 | 
			
		||||
    vstart: u64,
 | 
			
		||||
    _vend: u64,
 | 
			
		||||
    pfn: u64,
 | 
			
		||||
    pub pfn: u64,
 | 
			
		||||
    addr: u64,
 | 
			
		||||
    size: u64,
 | 
			
		||||
    pages: u64,
 | 
			
		||||
@ -87,15 +84,9 @@ pub struct BootState {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl BootSetup<'_> {
 | 
			
		||||
    pub fn new<'a>(
 | 
			
		||||
        call: &'a XenCall,
 | 
			
		||||
        domctl: &'a DomainControl<'a>,
 | 
			
		||||
        memctl: &'a MemoryControl<'a>,
 | 
			
		||||
        domid: u32,
 | 
			
		||||
    ) -> BootSetup<'a> {
 | 
			
		||||
    pub fn new(call: &XenCall, domid: u32) -> BootSetup {
 | 
			
		||||
        BootSetup {
 | 
			
		||||
            domctl,
 | 
			
		||||
            memctl,
 | 
			
		||||
            call,
 | 
			
		||||
            phys: PhysicalPages::new(call, domid),
 | 
			
		||||
            domid,
 | 
			
		||||
            virt_alloc_end: 0,
 | 
			
		||||
@ -106,7 +97,7 @@ impl BootSetup<'_> {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn initialize_memory(&mut self, total_pages: u64) -> Result<(), XenClientError> {
 | 
			
		||||
        self.domctl.set_address_size(self.domid, 64)?;
 | 
			
		||||
        self.call.set_address_size(self.domid, 64)?;
 | 
			
		||||
 | 
			
		||||
        let mut vmemranges: Vec<VmemRange> = Vec::new();
 | 
			
		||||
        let stub = VmemRange {
 | 
			
		||||
@ -162,7 +153,7 @@ impl BootSetup<'_> {
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                let extents_init_slice = extents_init.as_slice();
 | 
			
		||||
                let extents = self.memctl.populate_physmap(
 | 
			
		||||
                let extents = self.call.populate_physmap(
 | 
			
		||||
                    self.domid,
 | 
			
		||||
                    count,
 | 
			
		||||
                    SUPERPAGE_2MB_SHIFT as u32,
 | 
			
		||||
@ -191,7 +182,7 @@ impl BootSetup<'_> {
 | 
			
		||||
                let p2m_end_idx = p2m_idx + allocsz as usize;
 | 
			
		||||
                let input_extent_starts = &p2m[p2m_idx..p2m_end_idx];
 | 
			
		||||
                let result =
 | 
			
		||||
                    self.memctl
 | 
			
		||||
                    self.call
 | 
			
		||||
                        .populate_physmap(self.domid, allocsz, 0, 0, input_extent_starts)?;
 | 
			
		||||
 | 
			
		||||
                if result.len() != allocsz as usize {
 | 
			
		||||
@ -226,7 +217,7 @@ impl BootSetup<'_> {
 | 
			
		||||
 | 
			
		||||
        let pfn = (image_info.virt_hypercall - image_info.virt_base) >> X86_PAGE_SHIFT;
 | 
			
		||||
        let mfn = self.phys.p2m[pfn as usize];
 | 
			
		||||
        self.domctl.hypercall_init(self.domid, mfn)?;
 | 
			
		||||
        self.call.hypercall_init(self.domid, mfn)?;
 | 
			
		||||
        Ok(())
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -241,8 +232,6 @@ impl BootSetup<'_> {
 | 
			
		||||
            "BootSetup initialize max_vcpus={:?} mem_mb={:?}",
 | 
			
		||||
            max_vcpus, mem_mb
 | 
			
		||||
        );
 | 
			
		||||
        self.domctl.set_max_vcpus(self.domid, max_vcpus)?;
 | 
			
		||||
        self.domctl.set_max_mem(self.domid, mem_mb * 1024)?;
 | 
			
		||||
 | 
			
		||||
        let total_pages = mem_mb << (20 - X86_PAGE_SHIFT);
 | 
			
		||||
        self.initialize_memory(total_pages)?;
 | 
			
		||||
@ -284,8 +273,8 @@ impl BootSetup<'_> {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let initrd_segment = initrd_segment.unwrap();
 | 
			
		||||
        let store_evtchn = self.domctl.call.evtchn_alloc_unbound(self.domid, 0)?;
 | 
			
		||||
        let console_evtchn = self.domctl.call.evtchn_alloc_unbound(self.domid, 0)?;
 | 
			
		||||
        let store_evtchn = self.call.evtchn_alloc_unbound(self.domid, 0)?;
 | 
			
		||||
        let console_evtchn = self.call.evtchn_alloc_unbound(self.domid, 0)?;
 | 
			
		||||
        let state = BootState {
 | 
			
		||||
            kernel_segment,
 | 
			
		||||
            start_info_segment,
 | 
			
		||||
@ -306,7 +295,7 @@ impl BootSetup<'_> {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn boot(&mut self, state: &mut BootState, cmdline: &str) -> Result<(), XenClientError> {
 | 
			
		||||
        let domain_info = self.domctl.get_domain_info(self.domid)?;
 | 
			
		||||
        let domain_info = self.call.get_domain_info(self.domid)?;
 | 
			
		||||
        let shared_info_frame = domain_info.shared_info_frame;
 | 
			
		||||
        state.shared_info_frame = shared_info_frame;
 | 
			
		||||
        self.setup_page_tables(state)?;
 | 
			
		||||
@ -317,7 +306,7 @@ impl BootSetup<'_> {
 | 
			
		||||
        self.phys.unmap(pg_pfn)?;
 | 
			
		||||
        self.phys.unmap(state.p2m_segment.pfn)?;
 | 
			
		||||
        let pg_mfn = self.phys.p2m[pg_pfn as usize];
 | 
			
		||||
        self.memctl
 | 
			
		||||
        self.call
 | 
			
		||||
            .mmuext(self.domid, MMUEXT_PIN_L4_TABLE, pg_mfn, 0)?;
 | 
			
		||||
        self.setup_shared_info(state.shared_info_frame)?;
 | 
			
		||||
 | 
			
		||||
@ -346,7 +335,7 @@ impl BootSetup<'_> {
 | 
			
		||||
        vcpu.kernel_ss = vcpu.user_regs.ss as u64;
 | 
			
		||||
        vcpu.kernel_sp = vcpu.user_regs.rsp;
 | 
			
		||||
        debug!("vcpu context: {:?}", vcpu);
 | 
			
		||||
        self.domctl.set_vcpu_context(self.domid, 0, &vcpu)?;
 | 
			
		||||
        self.call.set_vcpu_context(self.domid, 0, &vcpu)?;
 | 
			
		||||
        self.phys.unmap_all()?;
 | 
			
		||||
        self.gnttab_seed(state)?;
 | 
			
		||||
        Ok(())
 | 
			
		||||
@ -356,13 +345,10 @@ impl BootSetup<'_> {
 | 
			
		||||
        let console_gfn = self.phys.p2m[state.console_segment.pfn as usize];
 | 
			
		||||
        let xenstore_gfn = self.phys.p2m[state.xenstore_segment.pfn as usize];
 | 
			
		||||
        let addr = self
 | 
			
		||||
            .domctl
 | 
			
		||||
            .call
 | 
			
		||||
            .mmap(0, 1 << XEN_PAGE_SHIFT)
 | 
			
		||||
            .ok_or(XenClientError::new("failed to mmap for resource"))?;
 | 
			
		||||
        self.domctl
 | 
			
		||||
            .call
 | 
			
		||||
            .map_resource(self.domid, 1, 0, 0, 1, addr)?;
 | 
			
		||||
        self.call.map_resource(self.domid, 1, 0, 0, 1, addr)?;
 | 
			
		||||
        let entries = unsafe { slice::from_raw_parts_mut(addr as *mut GrantEntry, 2) };
 | 
			
		||||
        entries[0].flags = 1 << 0;
 | 
			
		||||
        entries[0].domid = 0;
 | 
			
		||||
 | 
			
		||||
@ -1,19 +1,27 @@
 | 
			
		||||
use std::collections::HashMap;
 | 
			
		||||
 | 
			
		||||
pub struct DomainConfig {
 | 
			
		||||
    vm_entries: HashMap<String, String>,
 | 
			
		||||
    domain_entries: HashMap<String, String>,
 | 
			
		||||
    pub max_vcpus: u32,
 | 
			
		||||
    pub mem_mb: u64,
 | 
			
		||||
    pub kernel_path: String,
 | 
			
		||||
    pub initrd_path: String,
 | 
			
		||||
    pub cmdline: String,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub struct PvDomainConfig {
 | 
			
		||||
pub struct PvDomainStore {
 | 
			
		||||
    kernel: String,
 | 
			
		||||
    ramdisk: Option<String>,
 | 
			
		||||
    cmdline: Option<String>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl DomainConfig {
 | 
			
		||||
    pub fn new() -> DomainConfig {
 | 
			
		||||
        DomainConfig {
 | 
			
		||||
pub struct DomainStore {
 | 
			
		||||
    vm_entries: HashMap<String, String>,
 | 
			
		||||
    domain_entries: HashMap<String, String>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl DomainStore {
 | 
			
		||||
    pub fn new() -> DomainStore {
 | 
			
		||||
        DomainStore {
 | 
			
		||||
            vm_entries: HashMap::new(),
 | 
			
		||||
            domain_entries: HashMap::new(),
 | 
			
		||||
        }
 | 
			
		||||
@ -43,7 +51,7 @@ impl DomainConfig {
 | 
			
		||||
 | 
			
		||||
    pub fn configure_cpus(&mut self, _maxvcpus: u32) {}
 | 
			
		||||
 | 
			
		||||
    pub fn configure_pv(&mut self, pv: PvDomainConfig) {
 | 
			
		||||
    pub fn configure_pv(&mut self, pv: PvDomainStore) {
 | 
			
		||||
        self.put_vm_str("image/ostype", "linux");
 | 
			
		||||
        self.put_vm("image/kernel", pv.kernel);
 | 
			
		||||
 | 
			
		||||
@ -67,15 +75,15 @@ impl DomainConfig {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Default for DomainConfig {
 | 
			
		||||
impl Default for DomainStore {
 | 
			
		||||
    fn default() -> Self {
 | 
			
		||||
        DomainConfig::new()
 | 
			
		||||
        DomainStore::new()
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl PvDomainConfig {
 | 
			
		||||
    pub fn new(kernel: String, ramdisk: Option<String>, cmdline: Option<String>) -> PvDomainConfig {
 | 
			
		||||
        PvDomainConfig {
 | 
			
		||||
impl PvDomainStore {
 | 
			
		||||
    pub fn new(kernel: String, ramdisk: Option<String>, cmdline: Option<String>) -> PvDomainStore {
 | 
			
		||||
        PvDomainStore {
 | 
			
		||||
            kernel,
 | 
			
		||||
            ramdisk,
 | 
			
		||||
            cmdline,
 | 
			
		||||
 | 
			
		||||
@ -5,16 +5,19 @@ pub mod mem;
 | 
			
		||||
pub mod sys;
 | 
			
		||||
mod x86;
 | 
			
		||||
 | 
			
		||||
use crate::boot::BootSetup;
 | 
			
		||||
use crate::create::DomainConfig;
 | 
			
		||||
use crate::elfloader::ElfImageLoader;
 | 
			
		||||
use std::error::Error;
 | 
			
		||||
use std::fmt::{Display, Formatter};
 | 
			
		||||
use std::fs::read;
 | 
			
		||||
use std::string::FromUtf8Error;
 | 
			
		||||
use xencall::domctl::DomainControl;
 | 
			
		||||
use uuid::Uuid;
 | 
			
		||||
use xencall::sys::CreateDomain;
 | 
			
		||||
use xencall::{XenCall, XenCallError};
 | 
			
		||||
use xenevtchn::EventChannelError;
 | 
			
		||||
use xenstore::bus::XsdBusError;
 | 
			
		||||
use xenstore::client::{XsdClient, XsdInterface};
 | 
			
		||||
use xenstore::client::{XsPermissions, XsdClient, XsdInterface};
 | 
			
		||||
 | 
			
		||||
pub struct XenClient {
 | 
			
		||||
    store: XsdClient,
 | 
			
		||||
@ -83,29 +86,208 @@ impl XenClient {
 | 
			
		||||
        Ok(XenClient { store, call })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn create(&mut self, config: DomainConfig) -> Result<(), XenClientError> {
 | 
			
		||||
        let domctl = DomainControl::new(&self.call);
 | 
			
		||||
        let domid = domctl.create_domain(CreateDomain::default())?;
 | 
			
		||||
        let domain = self.store.get_domain_path(domid)?;
 | 
			
		||||
        let vm = self.store.read_string(format!("{}/vm", domain).as_str())?;
 | 
			
		||||
    pub fn create(&mut self, config: DomainConfig) -> Result<u32, XenClientError> {
 | 
			
		||||
        let domain = CreateDomain {
 | 
			
		||||
            max_vcpus: config.max_vcpus,
 | 
			
		||||
            ..Default::default()
 | 
			
		||||
        };
 | 
			
		||||
        let domid = self.call.create_domain(domain)?;
 | 
			
		||||
        let dom_path = self.store.get_domain_path(domid)?;
 | 
			
		||||
        let uuid_string = Uuid::from_bytes(domain.handle).to_string();
 | 
			
		||||
        let vm_path = format!("/vm/{}", uuid_string);
 | 
			
		||||
        let libxl_path = format!("/libxl/{}", domid);
 | 
			
		||||
 | 
			
		||||
        let ro_perm = XsPermissions { id: 0, perms: 0 };
 | 
			
		||||
 | 
			
		||||
        let rw_perm = XsPermissions { id: 0, perms: 0 };
 | 
			
		||||
 | 
			
		||||
        let no_perm = XsPermissions { id: 0, perms: 0 };
 | 
			
		||||
 | 
			
		||||
        {
 | 
			
		||||
            let mut tx = self.store.transaction()?;
 | 
			
		||||
 | 
			
		||||
            tx.rm(dom_path.as_str())?;
 | 
			
		||||
            tx.mknod(dom_path.as_str(), &ro_perm)?;
 | 
			
		||||
 | 
			
		||||
            tx.rm(vm_path.as_str())?;
 | 
			
		||||
            tx.mknod(vm_path.as_str(), &ro_perm)?;
 | 
			
		||||
 | 
			
		||||
            tx.rm(libxl_path.as_str())?;
 | 
			
		||||
            tx.mknod(vm_path.as_str(), &no_perm)?;
 | 
			
		||||
            tx.mknod(format!("{}/device", vm_path).as_str(), &no_perm)?;
 | 
			
		||||
 | 
			
		||||
            tx.write_string(format!("{}/vm", dom_path).as_str(), &vm_path)?;
 | 
			
		||||
 | 
			
		||||
            tx.mknod(format!("{}/cpu", dom_path).as_str(), &ro_perm)?;
 | 
			
		||||
            tx.mknod(format!("{}/memory", dom_path).as_str(), &ro_perm)?;
 | 
			
		||||
 | 
			
		||||
            tx.mknod(format!("{}/control", dom_path).as_str(), &ro_perm)?;
 | 
			
		||||
 | 
			
		||||
            tx.mknod(format!("{}/control/shutdown", dom_path).as_str(), &rw_perm)?;
 | 
			
		||||
            tx.mknod(
 | 
			
		||||
                format!("{}/control/feature-poweroff", dom_path).as_str(),
 | 
			
		||||
                &rw_perm,
 | 
			
		||||
            )?;
 | 
			
		||||
            tx.mknod(
 | 
			
		||||
                format!("{}/control/feature-reboot", dom_path).as_str(),
 | 
			
		||||
                &rw_perm,
 | 
			
		||||
            )?;
 | 
			
		||||
            tx.mknod(
 | 
			
		||||
                format!("{}/control/feature-suspend", dom_path).as_str(),
 | 
			
		||||
                &rw_perm,
 | 
			
		||||
            )?;
 | 
			
		||||
            tx.mknod(format!("{}/control/sysrq", dom_path).as_str(), &rw_perm)?;
 | 
			
		||||
 | 
			
		||||
            tx.mknod(format!("{}/data", dom_path).as_str(), &rw_perm)?;
 | 
			
		||||
            tx.mknod(format!("{}/drivers", dom_path).as_str(), &rw_perm)?;
 | 
			
		||||
            tx.mknod(format!("{}/feature", dom_path).as_str(), &rw_perm)?;
 | 
			
		||||
            tx.mknod(format!("{}/attr", dom_path).as_str(), &rw_perm)?;
 | 
			
		||||
            tx.mknod(format!("{}/error", dom_path).as_str(), &rw_perm)?;
 | 
			
		||||
 | 
			
		||||
            tx.write_string(
 | 
			
		||||
                format!("{}/uuid", vm_path).as_str(),
 | 
			
		||||
                &Uuid::from_bytes(domain.handle).to_string(),
 | 
			
		||||
            )?;
 | 
			
		||||
            tx.write_string(
 | 
			
		||||
                format!("{}/name", vm_path).as_str(),
 | 
			
		||||
                "mycelium",
 | 
			
		||||
            )?;
 | 
			
		||||
            tx.write_string(format!("{}/type", libxl_path).as_str(), "pv")?;
 | 
			
		||||
            tx.commit()?;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        self.call.set_max_vcpus(domid, config.max_vcpus)?;
 | 
			
		||||
        self.call.set_max_mem(domid, config.mem_mb * 1024)?;
 | 
			
		||||
        let image_loader = ElfImageLoader::load_file_kernel(config.kernel_path.as_str())?;
 | 
			
		||||
 | 
			
		||||
        let console_evtchn: u32;
 | 
			
		||||
        let xenstore_evtchn: u32;
 | 
			
		||||
        let console_mfn: u64;
 | 
			
		||||
        let xenstore_mfn: u64;
 | 
			
		||||
 | 
			
		||||
        {
 | 
			
		||||
            let mut boot = BootSetup::new(&self.call, domid);
 | 
			
		||||
            let initrd = read(config.initrd_path.as_str())?;
 | 
			
		||||
            let mut state = boot.initialize(
 | 
			
		||||
                &image_loader,
 | 
			
		||||
                initrd.as_slice(),
 | 
			
		||||
                config.max_vcpus,
 | 
			
		||||
                config.mem_mb,
 | 
			
		||||
            )?;
 | 
			
		||||
            boot.boot(&mut state, config.cmdline.as_str())?;
 | 
			
		||||
            console_evtchn = state.console_evtchn;
 | 
			
		||||
            xenstore_evtchn = state.store_evtchn;
 | 
			
		||||
            console_mfn = boot.phys.p2m[state.console_segment.pfn as usize];
 | 
			
		||||
            xenstore_mfn = boot.phys.p2m[state.xenstore_segment.pfn as usize];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        {
 | 
			
		||||
            let mut tx = self.store.transaction()?;
 | 
			
		||||
            tx.write_string(
 | 
			
		||||
                format!("{}/image/os_type", vm_path).as_str(),
 | 
			
		||||
                "linux",
 | 
			
		||||
            )?;
 | 
			
		||||
            tx.write_string(
 | 
			
		||||
                format!("{}/image/kernel", vm_path).as_str(),
 | 
			
		||||
                &config.kernel_path,
 | 
			
		||||
            )?;
 | 
			
		||||
            tx.write_string(
 | 
			
		||||
                format!("{}/image/ramdisk", vm_path).as_str(),
 | 
			
		||||
                &config.initrd_path,
 | 
			
		||||
            )?;
 | 
			
		||||
            tx.write_string(
 | 
			
		||||
                format!("{}/image/cmdline", vm_path).as_str(),
 | 
			
		||||
                &config.cmdline,
 | 
			
		||||
            )?;
 | 
			
		||||
 | 
			
		||||
            tx.write_string(
 | 
			
		||||
                format!("{}/memory/static-max", dom_path).as_str(),
 | 
			
		||||
                &(config.mem_mb * 1024).to_string(),
 | 
			
		||||
            )?;
 | 
			
		||||
            tx.write_string(
 | 
			
		||||
                format!("{}/memory/target", dom_path).as_str(),
 | 
			
		||||
                &(config.mem_mb * 1024).to_string(),
 | 
			
		||||
            )?;
 | 
			
		||||
            tx.write_string(
 | 
			
		||||
                format!("{}/memory/videoram", dom_path).as_str(),
 | 
			
		||||
                "0",
 | 
			
		||||
            )?;
 | 
			
		||||
            tx.write_string(format!("{}/domid", dom_path).as_str(), &domid.to_string())?;
 | 
			
		||||
            tx.write_string(
 | 
			
		||||
                format!("{}/store/port", dom_path).as_str(),
 | 
			
		||||
                &xenstore_evtchn.to_string(),
 | 
			
		||||
            )?;
 | 
			
		||||
            tx.write_string(
 | 
			
		||||
                format!("{}/store/ring-ref", dom_path).as_str(),
 | 
			
		||||
                &xenstore_mfn.to_string(),
 | 
			
		||||
            )?;
 | 
			
		||||
            for i in 0..config.max_vcpus {
 | 
			
		||||
                tx.write_string(
 | 
			
		||||
                    format!("{}/cpu/{}/availability", dom_path, i).as_str(),
 | 
			
		||||
                    "online",
 | 
			
		||||
                )?;
 | 
			
		||||
            }
 | 
			
		||||
            tx.commit()?;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        self.console_device_add(&dom_path.to_string(), domid, console_evtchn, console_mfn)?;
 | 
			
		||||
        self.store
 | 
			
		||||
            .introduce_domain(domid, xenstore_mfn, xenstore_evtchn)?;
 | 
			
		||||
        self.call.unpause_domain(domid)?;
 | 
			
		||||
 | 
			
		||||
        Ok(domid)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn console_device_add(
 | 
			
		||||
        &mut self,
 | 
			
		||||
        dom_path: &String,
 | 
			
		||||
        domid: u32,
 | 
			
		||||
        port: u32,
 | 
			
		||||
        mfn: u64,
 | 
			
		||||
    ) -> Result<(), XenClientError> {
 | 
			
		||||
        let frontend_path = format!("{}/console", dom_path);
 | 
			
		||||
        let backend_path = format!("{}/backend/console/{}/{}", dom_path, domid, 0);
 | 
			
		||||
        let mut tx = self.store.transaction()?;
 | 
			
		||||
        tx.write_string(
 | 
			
		||||
            format!("{}/frontend-id", backend_path).as_str(),
 | 
			
		||||
            &domid.to_string(),
 | 
			
		||||
        )?;
 | 
			
		||||
        tx.write_string(
 | 
			
		||||
            format!("{}/online", backend_path).as_str(),
 | 
			
		||||
            "1",
 | 
			
		||||
        )?;
 | 
			
		||||
        tx.write_string(format!("{}/state", backend_path).as_str(), "1")?;
 | 
			
		||||
        tx.write_string(
 | 
			
		||||
            format!("{}/protocol", backend_path).as_str(),
 | 
			
		||||
            "vt100",
 | 
			
		||||
        )?;
 | 
			
		||||
 | 
			
		||||
        for (key, value) in config.clone_domain_entries() {
 | 
			
		||||
            let path = format!("{}/{}", domain, key);
 | 
			
		||||
            tx.write(path.as_str(), value.into_bytes())?;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let domid_path = format!("{}/domid", domain);
 | 
			
		||||
        tx.write(domid_path.as_str(), domid.to_string().into_bytes())?;
 | 
			
		||||
 | 
			
		||||
        for (key, value) in config.clone_domain_entries() {
 | 
			
		||||
            let path = format!("{}/{}", vm, key);
 | 
			
		||||
            tx.write(path.as_str(), value.into_bytes())?;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        tx.write_string(
 | 
			
		||||
            format!("{}/backend-id", frontend_path).as_str(),
 | 
			
		||||
            "0",
 | 
			
		||||
        )?;
 | 
			
		||||
        tx.write_string(
 | 
			
		||||
            format!("{}/limit", frontend_path).as_str(),
 | 
			
		||||
            "1048576",
 | 
			
		||||
        )?;
 | 
			
		||||
        tx.write_string(
 | 
			
		||||
            format!("{}/type", frontend_path).as_str(),
 | 
			
		||||
            "xenconsoled",
 | 
			
		||||
        )?;
 | 
			
		||||
        tx.write_string(
 | 
			
		||||
            format!("{}/output", frontend_path).as_str(),
 | 
			
		||||
            "pty",
 | 
			
		||||
        )?;
 | 
			
		||||
        tx.write_string(format!("{}/tty", frontend_path).as_str(), "")?;
 | 
			
		||||
        tx.write_string(
 | 
			
		||||
            format!("{}/port", frontend_path).as_str(),
 | 
			
		||||
            &port.to_string(),
 | 
			
		||||
        )?;
 | 
			
		||||
        tx.write_string(
 | 
			
		||||
            format!("{}/ring-ref", frontend_path).as_str(),
 | 
			
		||||
            &mfn.to_string(),
 | 
			
		||||
        )?;
 | 
			
		||||
        tx.commit()?;
 | 
			
		||||
 | 
			
		||||
        Ok(())
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user