mirror of
https://github.com/edera-dev/krata.git
synced 2025-08-02 21:00:55 +00:00
xenclient: auto-retry mmapbatch when paging state issues occur
This commit is contained in:
parent
83264839dd
commit
001c22fd69
@ -13,7 +13,7 @@ use crate::sys::{
|
|||||||
XEN_DOMCTL_SET_ADDRESS_SIZE, XEN_DOMCTL_UNPAUSEDOMAIN, XEN_MEM_MEMORY_MAP,
|
XEN_DOMCTL_SET_ADDRESS_SIZE, XEN_DOMCTL_UNPAUSEDOMAIN, XEN_MEM_MEMORY_MAP,
|
||||||
XEN_MEM_POPULATE_PHYSMAP,
|
XEN_MEM_POPULATE_PHYSMAP,
|
||||||
};
|
};
|
||||||
use libc::{c_int, mmap, MAP_FAILED, MAP_SHARED, PROT_READ, PROT_WRITE};
|
use libc::{c_int, mmap, usleep, MAP_FAILED, MAP_SHARED, PROT_READ, PROT_WRITE};
|
||||||
use log::trace;
|
use log::trace;
|
||||||
use nix::errno::Errno;
|
use nix::errno::Errno;
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
@ -224,8 +224,62 @@ impl XenCall {
|
|||||||
mfns: mfns.as_mut_ptr(),
|
mfns: mfns.as_mut_ptr(),
|
||||||
errors: errors.as_mut_ptr(),
|
errors: errors.as_mut_ptr(),
|
||||||
};
|
};
|
||||||
let result = sys::mmapbatch(self.handle.as_raw_fd(), &mut batch)?;
|
|
||||||
Ok(result as c_long)
|
let result = sys::mmapbatch(self.handle.as_raw_fd(), &mut batch);
|
||||||
|
if let Err(errno) = result {
|
||||||
|
if errno != Errno::ENOENT {
|
||||||
|
return Err(errno)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
usleep(100);
|
||||||
|
|
||||||
|
let mut i: usize = 0;
|
||||||
|
let mut paged: usize = 0;
|
||||||
|
loop {
|
||||||
|
if errors[i] != libc::ENOENT {
|
||||||
|
i += 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
paged += 1;
|
||||||
|
let mut batch = MmapBatch {
|
||||||
|
num: 1,
|
||||||
|
domid: domid as u16,
|
||||||
|
addr: addr + ((i as u64) << 12),
|
||||||
|
mfns: mfns.as_mut_ptr().add(i),
|
||||||
|
errors: errors.as_mut_ptr().add(i),
|
||||||
|
};
|
||||||
|
|
||||||
|
loop {
|
||||||
|
i += 1;
|
||||||
|
if i < num as usize {
|
||||||
|
if errors[i] != libc::ENOENT {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
batch.num += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let result = sys::mmapbatch(self.handle.as_raw_fd(), &mut batch);
|
||||||
|
if let Err(n) = result {
|
||||||
|
if n != Errno::ENOENT {
|
||||||
|
return Err(n)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if i < num as usize {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
let count = result.unwrap();
|
||||||
|
if count <= 0 {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Ok(paged as c_long);
|
||||||
|
}
|
||||||
|
Ok(result.unwrap() as c_long)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,6 +110,23 @@ impl XenClient {
|
|||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
let domid = self.call.create_domain(domain)?;
|
let domid = self.call.create_domain(domain)?;
|
||||||
|
match self.init(domid, &domain, config) {
|
||||||
|
Ok(_) => Ok(domid),
|
||||||
|
Err(err) => {
|
||||||
|
// ignore since destroying a domain is best
|
||||||
|
// effort when an error occurs
|
||||||
|
let _ = self.call.destroy_domain(domid);
|
||||||
|
Err(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn init(
|
||||||
|
&mut self,
|
||||||
|
domid: u32,
|
||||||
|
domain: &CreateDomain,
|
||||||
|
config: &DomainConfig,
|
||||||
|
) -> Result<(), XenClientError> {
|
||||||
let backend_dom_path = self.store.get_domain_path(0)?;
|
let backend_dom_path = self.store.get_domain_path(0)?;
|
||||||
let dom_path = self.store.get_domain_path(domid)?;
|
let dom_path = self.store.get_domain_path(domid)?;
|
||||||
let uuid_string = Uuid::from_bytes(domain.handle).to_string();
|
let uuid_string = Uuid::from_bytes(domain.handle).to_string();
|
||||||
@ -281,8 +298,7 @@ impl XenClient {
|
|||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
self.call.unpause_domain(domid)?;
|
self.call.unpause_domain(domid)?;
|
||||||
|
Ok(())
|
||||||
Ok(domid)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn disk_device_add(
|
fn disk_device_add(
|
||||||
|
@ -86,7 +86,14 @@ impl XsdClient {
|
|||||||
|
|
||||||
fn rm(&mut self, tx: u32, path: &str) -> Result<bool, XsdBusError> {
|
fn rm(&mut self, tx: u32, path: &str) -> Result<bool, XsdBusError> {
|
||||||
trace!("rm tx={tx} path={path}");
|
trace!("rm tx={tx} path={path}");
|
||||||
self.socket.send_single(tx, XSD_RM, path)?.parse_bool()
|
let result = self.socket.send_single(tx, XSD_RM, path);
|
||||||
|
if let Err(error) = result {
|
||||||
|
if error.to_string() == "ENOENT" {
|
||||||
|
return Ok(true);
|
||||||
|
}
|
||||||
|
return Err(error);
|
||||||
|
}
|
||||||
|
result.unwrap().parse_bool()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_perms(
|
fn set_perms(
|
||||||
|
Loading…
Reference in New Issue
Block a user