More advanced setns syscall

This commit is contained in:
Jeremy Soller 2016-11-16 22:14:02 -07:00
parent d294d56b52
commit b551b30300
7 changed files with 88 additions and 35 deletions

View file

@ -84,27 +84,18 @@ pub struct SchemeList {
impl SchemeList {
/// Create a new scheme list.
pub fn new() -> Self {
SchemeList {
let mut list = SchemeList {
map: BTreeMap::new(),
names: BTreeMap::new(),
next_ns: 0,
next_id: 1
}
}
/// Initialize the root namespace
fn init(&mut self) {
// Do common namespace initialization
let ns = self.new_ns();
// Debug, Initfs and IRQ are only available in the root namespace. Pipe is special
self.insert(ns, Box::new(*b"debug"), |scheme_id| Arc::new(Box::new(DebugScheme::new(scheme_id)))).unwrap();
self.insert(ns, Box::new(*b"initfs"), |_| Arc::new(Box::new(InitFsScheme::new()))).unwrap();
self.insert(ns, Box::new(*b"irq"), |scheme_id| Arc::new(Box::new(IrqScheme::new(scheme_id)))).unwrap();
self.insert(ns, Box::new(*b"pipe"), |scheme_id| Arc::new(Box::new(PipeScheme::new(scheme_id)))).unwrap();
};
list.new_root();
list
}
/// Initialize a new namespace
pub fn new_ns(&mut self) -> SchemeNamespace {
fn new_ns(&mut self) -> SchemeNamespace {
let ns = SchemeNamespace(self.next_ns);
self.next_ns += 1;
self.names.insert(ns, BTreeMap::new());
@ -119,6 +110,40 @@ impl SchemeList {
ns
}
/// Initialize the root namespace
fn new_root(&mut self) {
// Do common namespace initialization
let ns = self.new_ns();
// Debug, Initfs and IRQ are only available in the root namespace. Pipe is special
self.insert(ns, Box::new(*b"debug"), |scheme_id| Arc::new(Box::new(DebugScheme::new(scheme_id)))).unwrap();
self.insert(ns, Box::new(*b"initfs"), |_| Arc::new(Box::new(InitFsScheme::new()))).unwrap();
self.insert(ns, Box::new(*b"irq"), |scheme_id| Arc::new(Box::new(IrqScheme::new(scheme_id)))).unwrap();
self.insert(ns, Box::new(*b"pipe"), |scheme_id| Arc::new(Box::new(PipeScheme::new(scheme_id)))).unwrap();
}
pub fn setns(&mut self, from: SchemeNamespace, names: &[&[u8]]) -> Result<SchemeNamespace> {
// Create an empty namespace
let to = self.new_ns();
// Copy requested scheme IDs
for name in names.iter() {
let id = if let Some((id, _scheme)) = self.get_name(from, name) {
id
} else {
return Err(Error::new(ENODEV));
};
if let Some(ref mut names) = self.names.get_mut(&to) {
assert!(names.insert(name.to_vec().into_boxed_slice(), id).is_none());
} else {
panic!("scheme namespace not found");
}
}
Ok(to)
}
pub fn iter(&self) -> ::collections::btree_map::Iter<SchemeId, Arc<Box<Scheme + Send + Sync>>> {
self.map.iter()
}
@ -182,9 +207,7 @@ static SCHEMES: Once<RwLock<SchemeList>> = Once::new();
/// Initialize schemes, called if needed
fn init_schemes() -> RwLock<SchemeList> {
let mut list: SchemeList = SchemeList::new();
list.init();
RwLock::new(list)
RwLock::new(SchemeList::new())
}
/// Get the global schemes list, const