More advanced setns syscall
This commit is contained in:
parent
d294d56b52
commit
b551b30300
|
@ -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
|
||||
|
|
|
@ -60,16 +60,18 @@ pub extern fn syscall(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize
|
|||
_ => unreachable!()
|
||||
},
|
||||
_ => match a {
|
||||
SYS_YIELD => sched_yield(),
|
||||
SYS_NANOSLEEP => nanosleep(validate_slice(b as *const TimeSpec, 1).map(|req| &req[0])?, validate_slice_mut(c as *mut TimeSpec, 1).ok().map(|rem| &mut rem[0])),
|
||||
SYS_CLOCK_GETTIME => clock_gettime(b, validate_slice_mut(c as *mut TimeSpec, 1).map(|time| &mut time[0])?),
|
||||
SYS_FUTEX => futex(validate_slice_mut(b as *mut i32, 1).map(|uaddr| &mut uaddr[0])?, c, d as i32, e, f as *mut i32),
|
||||
SYS_BRK => brk(b),
|
||||
SYS_EXIT => exit(b),
|
||||
SYS_WAITPID => waitpid(ContextId::from(b), c, d).map(ContextId::into),
|
||||
SYS_EXECVE => exec(validate_slice(b as *const u8, c)?, validate_slice(d as *const [usize; 2], e)?),
|
||||
SYS_CHDIR => chdir(validate_slice(b as *const u8, c)?),
|
||||
SYS_GETPID => getpid().map(ContextId::into),
|
||||
SYS_BRK => brk(b),
|
||||
SYS_IOPL => iopl(b),
|
||||
SYS_CLONE => clone(b, stack).map(ContextId::into),
|
||||
SYS_YIELD => sched_yield(),
|
||||
SYS_NANOSLEEP => nanosleep(validate_slice(b as *const TimeSpec, 1).map(|req| &req[0])?, validate_slice_mut(c as *mut TimeSpec, 1).ok().map(|rem| &mut rem[0])),
|
||||
SYS_GETCWD => getcwd(validate_slice_mut(b as *mut u8, c)?),
|
||||
SYS_GETUID => getuid(),
|
||||
SYS_GETGID => getgid(),
|
||||
|
@ -77,8 +79,7 @@ pub extern fn syscall(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize
|
|||
SYS_GETEGID => getegid(),
|
||||
SYS_SETUID => setuid(b as u32),
|
||||
SYS_SETGID => setgid(b as u32),
|
||||
SYS_CLOCK_GETTIME => clock_gettime(b, validate_slice_mut(c as *mut TimeSpec, 1).map(|time| &mut time[0])?),
|
||||
SYS_FUTEX => futex(validate_slice_mut(b as *mut i32, 1).map(|uaddr| &mut uaddr[0])?, c, d as i32, e, f as *mut i32),
|
||||
SYS_SETNS => setns(validate_slice(b as *const [usize; 2], c)?),
|
||||
SYS_PIPE2 => pipe2(validate_slice_mut(b as *mut usize, 2)?, c),
|
||||
SYS_PHYSALLOC => physalloc(b),
|
||||
SYS_PHYSFREE => physfree(b, c),
|
||||
|
|
|
@ -19,7 +19,7 @@ use scheme::{self, FileHandle};
|
|||
use syscall;
|
||||
use syscall::data::Stat;
|
||||
use syscall::error::*;
|
||||
use syscall::flag::{CLONE_VFORK, CLONE_VM, CLONE_FS, CLONE_FILES, CLONE_NEWNS, MAP_WRITE, MAP_WRITE_COMBINE, WNOHANG};
|
||||
use syscall::flag::{CLONE_VFORK, CLONE_VM, CLONE_FS, CLONE_FILES, MAP_WRITE, MAP_WRITE_COMBINE, WNOHANG};
|
||||
use syscall::validate::{validate_slice, validate_slice_mut};
|
||||
|
||||
pub fn brk(address: usize) -> Result<usize> {
|
||||
|
@ -223,11 +223,7 @@ pub fn clone(flags: usize, stack_base: usize) -> Result<ContextId> {
|
|||
name = Arc::new(Mutex::new(context.name.lock().clone()));
|
||||
}
|
||||
|
||||
if flags & CLONE_NEWNS == CLONE_NEWNS {
|
||||
scheme_ns = scheme::schemes_mut().new_ns();
|
||||
} else {
|
||||
scheme_ns = context.scheme_ns;
|
||||
}
|
||||
|
||||
if flags & CLONE_FS == CLONE_FS {
|
||||
cwd = context.cwd.clone();
|
||||
|
@ -1058,6 +1054,31 @@ pub fn setuid(uid: u32) -> Result<usize> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn setns(name_ptrs: &[[usize; 2]]) -> Result<usize> {
|
||||
let mut names = Vec::new();
|
||||
for name_ptr in name_ptrs {
|
||||
names.push(validate_slice(name_ptr[0] as *const u8, name_ptr[1])?);
|
||||
}
|
||||
|
||||
let from = {
|
||||
let contexts = context::contexts();
|
||||
let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
|
||||
let context = context_lock.read();
|
||||
context.scheme_ns
|
||||
};
|
||||
|
||||
let to = scheme::schemes_mut().setns(from, &names)?;
|
||||
|
||||
{
|
||||
let contexts = context::contexts();
|
||||
let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
|
||||
let mut context = context_lock.write();
|
||||
context.scheme_ns = to;
|
||||
}
|
||||
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
pub fn virttophys(virtual_address: usize) -> Result<usize> {
|
||||
let active_table = unsafe { ActivePageTable::new() };
|
||||
match active_table.translate(VirtualAddress::new(virtual_address)) {
|
||||
|
|
|
@ -1,18 +1,27 @@
|
|||
extern crate syscall;
|
||||
|
||||
use std::fs::File;
|
||||
use std::io::{BufRead, BufReader};
|
||||
use std::io::{BufRead, BufReader, Read};
|
||||
|
||||
pub fn main() {
|
||||
let pid = unsafe { syscall::clone(syscall::CLONE_NEWNS).unwrap() };
|
||||
let pid = unsafe { syscall::clone(0).unwrap() };
|
||||
if pid == 0 {
|
||||
let rand = b"rand";
|
||||
syscall::setns(&[[rand.as_ptr() as usize, rand.len()]]).unwrap();
|
||||
|
||||
println!("Child Namespace:");
|
||||
let file = BufReader::new(File::open("sys:scheme").unwrap());
|
||||
for line in file.lines() {
|
||||
let line = line.unwrap();
|
||||
println!("{}", line);
|
||||
}
|
||||
println!("");
|
||||
|
||||
let mut rand = File::open("rand:").unwrap();
|
||||
|
||||
let mut byte = [0];
|
||||
rand.read(&mut byte).unwrap();
|
||||
|
||||
println!("Rand: {}", byte[0]);
|
||||
} else {
|
||||
let mut status = 0;
|
||||
syscall::waitpid(pid, &mut status, 0).unwrap();
|
||||
|
@ -23,6 +32,5 @@ pub fn main() {
|
|||
let line = line.unwrap();
|
||||
println!("{}", line);
|
||||
}
|
||||
println!("");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 425b264ed7f1df10eeaff7c71191f0e2989da719
|
||||
Subproject commit b9db33d81aea2d40cc88432926558d146363b4a1
|
|
@ -1 +1 @@
|
|||
Subproject commit d44639145bbadeae57066aecaec146f7d3e8c645
|
||||
Subproject commit 5f9ff4d19ec299cd9cc70e4c04e0b6a8ee1fa57f
|
2
syscall
2
syscall
|
@ -1 +1 @@
|
|||
Subproject commit f87cbb53130a6a9652e2ed8dd066fa7fa97c8e42
|
||||
Subproject commit 7b8cc598909189526d8c0caa8057e4a6b23f0fdc
|
Loading…
Reference in a new issue