implement fcntl & ioctl for socket. fix lighttpd performance

This commit is contained in:
WangRunji 2019-04-23 01:43:41 +08:00
parent 1326924dbb
commit 26189dddaa
8 changed files with 91 additions and 30 deletions

@ -3,7 +3,6 @@ use std;
use std::borrow::BorrowMut; use std::borrow::BorrowMut;
use std::fmt; use std::fmt;
use std::io::SeekFrom; use std::io::SeekFrom;
use std::any::Any;
pub trait File: Debug + Sync + Send + Any { pub trait File: Debug + Sync + Send + Any {
fn read(&self, buf: &mut [u8]) -> Result<usize, Error>; fn read(&self, buf: &mut [u8]) -> Result<usize, Error>;
@ -18,7 +17,7 @@ pub trait File: Debug + Sync + Send + Any {
fn sync_all(&self) -> Result<(), Error>; fn sync_all(&self) -> Result<(), Error>;
fn sync_data(&self) -> Result<(), Error>; fn sync_data(&self) -> Result<(), Error>;
fn read_entry(&self) -> Result<String, Error>; fn read_entry(&self) -> Result<String, Error>;
fn as_any(&self) -> &Any { unimplemented!() } fn as_any(&self) -> &Any;
} }
pub type FileRef = Arc<Box<File>>; pub type FileRef = Arc<Box<File>>;
@ -116,6 +115,10 @@ impl File for SgxFile {
fn read_entry(&self) -> Result<String, Error> { fn read_entry(&self) -> Result<String, Error> {
unimplemented!() unimplemented!()
} }
fn as_any(&self) -> &Any {
self
}
} }
#[derive(Clone)] #[derive(Clone)]
@ -379,6 +382,10 @@ impl File for StdoutFile {
fn read_entry(&self) -> Result<String, Error> { fn read_entry(&self) -> Result<String, Error> {
unimplemented!() unimplemented!()
} }
fn as_any(&self) -> &Any {
self
}
} }
impl Debug for StdoutFile { impl Debug for StdoutFile {
@ -476,6 +483,10 @@ impl File for StdinFile {
fn read_entry(&self) -> Result<String, Error> { fn read_entry(&self) -> Result<String, Error> {
unimplemented!() unimplemented!()
} }
fn as_any(&self) -> &Any {
self
}
} }
impl Debug for StdinFile { impl Debug for StdinFile {

@ -154,6 +154,10 @@ impl File for INodeFile {
*offset += 1; *offset += 1;
Ok(name) Ok(name)
} }
fn as_any(&self) -> &Any {
self
}
} }
impl INodeFile { impl INodeFile {

@ -16,6 +16,7 @@ pub use self::io_multiplexing::*;
pub use self::access::{AccessModes, AccessFlags, AT_FDCWD, do_access, do_faccessat}; pub use self::access::{AccessModes, AccessFlags, AT_FDCWD, do_access, do_faccessat};
use self::null::NullFile; use self::null::NullFile;
use std::mem::uninitialized; use std::mem::uninitialized;
use std::any::Any;
mod file; mod file;
mod file_table; mod file_table;
@ -468,6 +469,8 @@ bitflags! {
const TRUNCATE = 1 << 9; const TRUNCATE = 1 << 9;
/// append on each write /// append on each write
const APPEND = 1 << 10; const APPEND = 1 << 10;
/// non block
const NONBLOCK = 1 << 11;
/// close on exec /// close on exec
const CLOEXEC = 1 << 19; const CLOEXEC = 1 << 19;
} }
@ -694,28 +697,19 @@ pub enum FcntlCmd {
/// Get the file status flags /// Get the file status flags
GetFl(), GetFl(),
/// Set the file status flags /// Set the file status flags
SetFl(OpenFlags), SetFl(u32),
} }
pub const F_DUPFD : u32 = 0;
pub const F_GETFD : u32 = 1;
pub const F_SETFD : u32 = 2;
pub const F_GETFL : u32 = 3;
pub const F_SETFL : u32 = 4;
pub const F_DUPFD_CLOEXEC : u32 = 1030;
pub const FD_CLOEXEC : u32 = 1;
impl FcntlCmd { impl FcntlCmd {
#[deny(unreachable_patterns)] #[deny(unreachable_patterns)]
pub fn from_raw(cmd: u32, arg: u64) -> Result<FcntlCmd, Error> { pub fn from_raw(cmd: u32, arg: u64) -> Result<FcntlCmd, Error> {
Ok(match cmd { Ok(match cmd as c_int {
F_DUPFD => FcntlCmd::DupFd(arg as FileDesc), libc::F_DUPFD => FcntlCmd::DupFd(arg as FileDesc),
F_DUPFD_CLOEXEC => FcntlCmd::DupFdCloexec(arg as FileDesc), libc::F_DUPFD_CLOEXEC => FcntlCmd::DupFdCloexec(arg as FileDesc),
F_GETFD => FcntlCmd::GetFd(), libc::F_GETFD => FcntlCmd::GetFd(),
F_SETFD => FcntlCmd::SetFd(arg as u32), libc::F_SETFD => FcntlCmd::SetFd(arg as u32),
F_GETFL => FcntlCmd::GetFl(), libc::F_GETFL => FcntlCmd::GetFl(),
F_SETFL => FcntlCmd::SetFl(OpenFlags::from_bits_truncate(arg as u32)), libc::F_SETFL => FcntlCmd::SetFl(arg as u32),
_ => return errno!(EINVAL, "invalid command"), _ => return errno!(EINVAL, "invalid command"),
}) })
} }
@ -739,7 +733,7 @@ pub fn do_fcntl(fd: FileDesc, cmd: &FcntlCmd) -> Result<isize, Error> {
FcntlCmd::GetFd() => { FcntlCmd::GetFd() => {
let entry = files.get_entry(fd)?; let entry = files.get_entry(fd)?;
let fd_flags = if entry.is_close_on_spawn() { let fd_flags = if entry.is_close_on_spawn() {
FD_CLOEXEC libc::FD_CLOEXEC
} else { } else {
0 0
}; };
@ -747,19 +741,33 @@ pub fn do_fcntl(fd: FileDesc, cmd: &FcntlCmd) -> Result<isize, Error> {
}, },
FcntlCmd::SetFd(fd_flags) => { FcntlCmd::SetFd(fd_flags) => {
let entry = files.get_entry_mut(fd)?; let entry = files.get_entry_mut(fd)?;
entry.set_close_on_spawn((fd_flags & FD_CLOEXEC) != 0); entry.set_close_on_spawn((fd_flags & libc::FD_CLOEXEC as u32) != 0);
0 0
}, },
FcntlCmd::GetFl() => { FcntlCmd::GetFl() => {
let _ = files.get_entry_mut(fd)?; let file = files.get(fd)?;
warn!("fcntl.getfl is unimplemented"); if let Ok(socket) = file.as_socket() {
0 let ret = try_libc!(libc::ocall::fcntl_arg0(socket.fd(), libc::F_GETFL));
}, ret as isize
} else {
warn!("fcntl.getfl is unimplemented");
0
}
}
FcntlCmd::SetFl(flags) => { FcntlCmd::SetFl(flags) => {
let _ = files.get_entry_mut(fd)?; let file = files.get(fd)?;
warn!("fcntl.setfl is unimplemented"); if let Ok(socket) = file.as_socket() {
0 let ret = try_libc!(libc::ocall::fcntl_arg1(
}, socket.fd(),
libc::F_SETFL,
*flags as c_int
));
ret as isize
} else {
warn!("fcntl.setfl is unimplemented");
0
}
}
}) })
} }

@ -51,4 +51,8 @@ impl File for NullFile {
fn read_entry(&self) -> Result<String, Error> { fn read_entry(&self) -> Result<String, Error> {
unimplemented!() unimplemented!()
} }
fn as_any(&self) -> &Any {
self
}
} }

@ -99,6 +99,10 @@ impl File for PipeReader {
fn read_entry(&self) -> Result<String, Error> { fn read_entry(&self) -> Result<String, Error> {
unimplemented!() unimplemented!()
} }
fn as_any(&self) -> &Any {
self
}
} }
unsafe impl Send for PipeReader {} unsafe impl Send for PipeReader {}
@ -177,6 +181,10 @@ impl File for PipeWriter {
fn read_entry(&self) -> Result<String, Error> { fn read_entry(&self) -> Result<String, Error> {
unimplemented!() unimplemented!()
} }
fn as_any(&self) -> &Any {
self
}
} }
unsafe impl Send for PipeWriter {} unsafe impl Send for PipeWriter {}

@ -5,7 +5,7 @@ use xmas_elf::{header, program, sections, ElfFile};
pub const DEFAULT_STACK_SIZE: usize = 1 * 1024 * 1024; pub const DEFAULT_STACK_SIZE: usize = 1 * 1024 * 1024;
pub const DEFAULT_HEAP_SIZE: usize = 2 * 1024 * 1024; pub const DEFAULT_HEAP_SIZE: usize = 2 * 1024 * 1024;
pub const DEFAULT_MMAP_SIZE: usize = 2 * 1024 * 1024; pub const DEFAULT_MMAP_SIZE: usize = 8 * 1024 * 1024;
pub fn do_init(elf_file: &ElfFile, elf_buf: &[u8]) -> Result<ProcessVM, Error> { pub fn do_init(elf_file: &ElfFile, elf_buf: &[u8]) -> Result<ProcessVM, Error> {
let mut code_seg = get_code_segment(elf_file)?; let mut code_seg = get_code_segment(elf_file)?;

@ -101,6 +101,7 @@ pub extern "C" fn dispatch_syscall(
arg3 as usize, arg3 as usize,
), ),
SYS_FCNTL => do_fcntl(arg0 as FileDesc, arg1 as u32, arg2 as u64), SYS_FCNTL => do_fcntl(arg0 as FileDesc, arg1 as u32, arg2 as u64),
SYS_IOCTL => do_ioctl(arg0 as FileDesc, arg1 as c_int, arg2 as *mut c_int),
// IO multiplexing // IO multiplexing
SYS_SELECT => do_select( SYS_SELECT => do_select(
@ -280,6 +281,7 @@ pub extern "C" fn dispatch_syscall(
match ret { match ret {
Ok(code) => code as isize, Ok(code) => code as isize,
Err(e) if e.errno.as_retval() == 0 => panic!("undefined errno"),
Err(e) => e.errno.as_retval() as isize, Err(e) => e.errno.as_retval() as isize,
} }
} }
@ -900,6 +902,23 @@ fn do_fcntl(fd: FileDesc, cmd: u32, arg: u64) -> Result<isize, Error> {
fs::do_fcntl(fd, &cmd) fs::do_fcntl(fd, &cmd)
} }
fn do_ioctl(fd: FileDesc, cmd: c_int, argp: *mut c_int) -> Result<isize, Error> {
info!(
"ioctl: fd: {}, cmd: {}, argp: {:?}",
fd, cmd, argp
);
let current_ref = process::get_current();
let mut proc = current_ref.lock().unwrap();
let file_ref = proc.get_files().lock().unwrap().get(fd as FileDesc)?;
if let Ok(socket) = file_ref.as_socket() {
let ret = try_libc!(libc::ocall::ioctl_arg1(socket.fd(), cmd, argp));
Ok(ret as isize)
} else {
warn!("ioctl is unimplemented");
errno!(ENOSYS, "ioctl is unimplemented")
}
}
fn do_arch_prctl(code: u32, addr: *mut usize) -> Result<isize, Error> { fn do_arch_prctl(code: u32, addr: *mut usize) -> Result<isize, Error> {
let code = process::ArchPrctlCode::from_u32(code)?; let code = process::ArchPrctlCode::from_u32(code)?;
check_mut_ptr(addr)?; check_mut_ptr(addr)?;

@ -16,6 +16,7 @@ pub use self::process_vm::ProcessVM;
// TODO: separate proc and flags // TODO: separate proc and flags
// TODO: accept fd and offset // TODO: accept fd and offset
pub fn do_mmap(addr: usize, size: usize, flags: VMAreaFlags) -> Result<usize, Error> { pub fn do_mmap(addr: usize, size: usize, flags: VMAreaFlags) -> Result<usize, Error> {
info!("mmap: addr: {:#x}, size: {:#x}, flags: {:?}", addr, size, flags);
let current_ref = get_current(); let current_ref = get_current();
let current_process = current_ref.lock().unwrap(); let current_process = current_ref.lock().unwrap();
let current_vm_ref = current_process.get_vm(); let current_vm_ref = current_process.get_vm();
@ -24,6 +25,7 @@ pub fn do_mmap(addr: usize, size: usize, flags: VMAreaFlags) -> Result<usize, Er
} }
pub fn do_munmap(addr: usize, size: usize) -> Result<(), Error> { pub fn do_munmap(addr: usize, size: usize) -> Result<(), Error> {
info!("munmap: addr: {:#x}, size: {:#x}", addr, size);
let current_ref = get_current(); let current_ref = get_current();
let current_process = current_ref.lock().unwrap(); let current_process = current_ref.lock().unwrap();
let current_vm_ref = current_process.get_vm(); let current_vm_ref = current_process.get_vm();
@ -37,6 +39,10 @@ pub fn do_mremap(
old_size: usize, old_size: usize,
options: &VMResizeOptions, options: &VMResizeOptions,
) -> Result<usize, Error> { ) -> Result<usize, Error> {
info!(
"mremap: oldaddr: {:#x}, oldsize: {:#x}, options: {:?}",
old_addr, old_size, options
);
let current_ref = get_current(); let current_ref = get_current();
let current_process = current_ref.lock().unwrap(); let current_process = current_ref.lock().unwrap();
let current_vm_ref = current_process.get_vm(); let current_vm_ref = current_process.get_vm();
@ -45,6 +51,7 @@ pub fn do_mremap(
} }
pub fn do_brk(addr: usize) -> Result<usize, Error> { pub fn do_brk(addr: usize) -> Result<usize, Error> {
info!("brk: addr: {:#x}", addr);
let current_ref = get_current(); let current_ref = get_current();
let current_process = current_ref.lock().unwrap(); let current_process = current_ref.lock().unwrap();
let current_vm_ref = current_process.get_vm(); let current_vm_ref = current_process.get_vm();