Implement O_DIRECTORY, switch to open for mkdir

This commit is contained in:
Jeremy Soller 2016-11-25 18:24:38 -07:00
parent 09fb7d1d69
commit c018bfe5ef
10 changed files with 33 additions and 44 deletions

View file

@ -93,9 +93,9 @@ pub fn cpu_count() -> usize {
pub extern fn userspace_init() { pub extern fn userspace_init() {
assert_eq!(syscall::chdir(b"initfs:bin"), Ok(0)); assert_eq!(syscall::chdir(b"initfs:bin"), Ok(0));
assert_eq!(syscall::open(b"debug:", 0).map(FileHandle::into), Ok(0)); assert_eq!(syscall::open(b"debug:", syscall::flag::O_RDONLY).map(FileHandle::into), Ok(0));
assert_eq!(syscall::open(b"debug:", 0).map(FileHandle::into), Ok(1)); assert_eq!(syscall::open(b"debug:", syscall::flag::O_WRONLY).map(FileHandle::into), Ok(1));
assert_eq!(syscall::open(b"debug:", 0).map(FileHandle::into), Ok(2)); assert_eq!(syscall::open(b"debug:", syscall::flag::O_WRONLY).map(FileHandle::into), Ok(2));
syscall::exec(b"initfs:bin/init", &[]).expect("failed to execute initfs:init"); syscall::exec(b"initfs:bin/init", &[]).expect("failed to execute initfs:init");

View file

@ -224,14 +224,6 @@ impl Scheme for UserScheme {
result result
} }
fn mkdir(&self, path: &[u8], mode: u16, _uid: u32, _gid: u32) -> Result<usize> {
let inner = self.inner.upgrade().ok_or(Error::new(ENODEV))?;
let address = inner.capture(path)?;
let result = inner.call(SYS_MKDIR, address, path.len(), mode as usize);
let _ = inner.release(address);
result
}
fn chmod(&self, path: &[u8], mode: u16, _uid: u32, _gid: u32) -> Result<usize> { fn chmod(&self, path: &[u8], mode: u16, _uid: u32, _gid: u32) -> Result<usize> {
let inner = self.inner.upgrade().ok_or(Error::new(ENODEV))?; let inner = self.inner.upgrade().ok_or(Error::new(ENODEV))?;
let address = inner.capture(path)?; let address = inner.capture(path)?;

View file

@ -49,7 +49,7 @@ pub fn file_op_mut_slice(a: usize, fd: FileHandle, slice: &mut [u8]) -> Result<u
/// Change the current working directory /// Change the current working directory
pub fn chdir(path: &[u8]) -> Result<usize> { pub fn chdir(path: &[u8]) -> Result<usize> {
let fd = open(path, 0)?; let fd = open(path, syscall::flag::O_RDONLY | syscall::flag::O_DIRECTORY)?;
let mut stat = Stat::default(); let mut stat = Stat::default();
let stat_res = file_op_mut_slice(syscall::number::SYS_FSTAT, fd, &mut stat); let stat_res = file_op_mut_slice(syscall::number::SYS_FSTAT, fd, &mut stat);
let _ = close(fd); let _ = close(fd);
@ -144,28 +144,6 @@ pub fn pipe2(fds: &mut [usize], flags: usize) -> Result<usize> {
} }
} }
/// mkdir syscall
pub fn mkdir(path: &[u8], mode: u16) -> Result<usize> {
let (path_canon, uid, gid, scheme_ns) = {
let contexts = context::contexts();
let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
let context = context_lock.read();
(context.canonicalize(path), context.euid, context.egid, context.ens)
};
let mut parts = path_canon.splitn(2, |&b| b == b':');
let scheme_name_opt = parts.next();
let reference_opt = parts.next();
let scheme_name = scheme_name_opt.ok_or(Error::new(ENODEV))?;
let scheme = {
let schemes = scheme::schemes();
let (_scheme_id, scheme) = schemes.get_name(scheme_ns, scheme_name).ok_or(Error::new(ENODEV))?;
scheme.clone()
};
scheme.mkdir(reference_opt.unwrap_or(b""), mode, uid, gid)
}
/// chmod syscall /// chmod syscall
pub fn chmod(path: &[u8], mode: u16) -> Result<usize> { pub fn chmod(path: &[u8], mode: u16) -> Result<usize> {
let (path_canon, uid, gid, scheme_ns) = { let (path_canon, uid, gid, scheme_ns) = {

View file

@ -61,7 +61,6 @@ pub extern fn syscall(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize
}, },
SYS_CLASS_PATH => match a { SYS_CLASS_PATH => match a {
SYS_OPEN => open(validate_slice(b as *const u8, c)?, d).map(FileHandle::into), SYS_OPEN => open(validate_slice(b as *const u8, c)?, d).map(FileHandle::into),
SYS_MKDIR => mkdir(validate_slice(b as *const u8, c)?, d as u16),
SYS_CHMOD => chmod(validate_slice(b as *const u8, c)?, d as u16), SYS_CHMOD => chmod(validate_slice(b as *const u8, c)?, d as u16),
SYS_RMDIR => rmdir(validate_slice(b as *const u8, c)?), SYS_RMDIR => rmdir(validate_slice(b as *const u8, c)?),
SYS_UNLINK => unlink(validate_slice(b as *const u8, c)?), SYS_UNLINK => unlink(validate_slice(b as *const u8, c)?),

View file

@ -468,7 +468,7 @@ pub fn exec(path: &[u8], arg_ptrs: &[[usize; 2]]) -> Result<usize> {
(context.euid, context.egid, context.canonicalize(path)) (context.euid, context.egid, context.canonicalize(path))
}; };
let file = syscall::open(&canonical, 0)?; let file = syscall::open(&canonical, syscall::flag::O_RDONLY)?;
let mut stat = Stat::default(); let mut stat = Stat::default();
syscall::file_op_mut_slice(syscall::number::SYS_FSTAT, file, &mut stat)?; syscall::file_op_mut_slice(syscall::number::SYS_FSTAT, file, &mut stat)?;

View file

@ -9,7 +9,7 @@ pub use self::syscall::error::*;
pub use self::syscall::flag::*; pub use self::syscall::flag::*;
pub use self::syscall::{ pub use self::syscall::{
clock_gettime, clone, execve as exec, exit, futex, getpid, kill, nanosleep, setregid, setreuid, waitpid, clock_gettime, clone, execve as exec, exit, futex, getpid, kill, nanosleep, setregid, setreuid, waitpid,
chdir, chmod, getcwd, open, mkdir, rmdir, unlink, dup, pipe2, chdir, chmod, getcwd, open, rmdir, unlink, dup, pipe2,
read, write, fcntl, fpath, fstat, fsync, ftruncate, lseek, close read, write, fcntl, fpath, fstat, fsync, ftruncate, lseek, close
}; };

View file

@ -1,13 +1,13 @@
extern crate syscall; extern crate syscall;
use std::env; use std::{env, thread};
use std::os::unix::process::CommandExt; use std::os::unix::process::CommandExt;
use std::process::Command; use std::process::Command;
pub fn main() { pub fn main() {
let mut args = env::args().skip(1); let mut args = env::args().skip(1);
let root = args.next(); let root_opt = args.next();
let cmd = args.next().unwrap_or("sh".to_string()); let cmd = args.next().unwrap_or("sh".to_string());
@ -16,8 +16,8 @@ pub fn main() {
"tcp", "tcp",
"udp" "udp"
]; ];
if root.is_none() { if root_opt.is_none() {
names.push("file"); names.push("file");
} }
@ -28,6 +28,26 @@ pub fn main() {
let new_ns = syscall::mkns(&name_ptrs).unwrap(); let new_ns = syscall::mkns(&name_ptrs).unwrap();
let root_thread = if let Some(root) = root_opt {
Some(thread::spawn(move || {
syscall::setrens(-1isize as usize, new_ns).unwrap();
let scheme_fd = syscall::open(":file", syscall::O_CREAT | syscall::O_RDWR | syscall::O_CLOEXEC).unwrap();
syscall::setrens(-1isize as usize, syscall::getns().unwrap()).unwrap();
loop {
let mut packet = syscall::Packet::default();
if syscall::read(scheme_fd, &mut packet).unwrap() == 0 {
break;
}
println!("{:?}", packet);
}
let _ = syscall::close(scheme_fd);
}))
} else {
None
};
let pid = unsafe { syscall::clone(0).unwrap() }; let pid = unsafe { syscall::clone(0).unwrap() };
if pid == 0 { if pid == 0 {
syscall::setrens(new_ns, new_ns).unwrap(); syscall::setrens(new_ns, new_ns).unwrap();

2
rust

@ -1 +1 @@
Subproject commit 6733074c847767fd3e0425fcefb73226bde1f6a1 Subproject commit 3a1bb2ba26a85bbea4c9be813a9a13d48ab448ac

@ -1 +1 @@
Subproject commit dcaf5c76be265bbfa5013cf131f14fa79680a634 Subproject commit 25fe6d382641184b447645d6a784316652eaed95

@ -1 +1 @@
Subproject commit 2835586ee671b0777ef1a98ced9237269c472941 Subproject commit 1908eea7e91142a058ae99c06edb2a9dd7efd692