Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Missing syscalls for musl libc #26

Open
coolyjg opened this issue Nov 24, 2023 · 13 comments
Open

Missing syscalls for musl libc #26

coolyjg opened this issue Nov 24, 2023 · 13 comments

Comments

@coolyjg
Copy link
Contributor

coolyjg commented Nov 24, 2023

This issue is intended to collect problems/requirements/demands for syscalls in rukos when integrating apps. Here, you can add:

  • What syscalls are missing for your app, and what the parameter types are. You can add your implementations/code here as well.
  • Wrong implementations for some syscalls, and the right semantic.
@coolyjg
Copy link
Contributor Author

coolyjg commented Nov 29, 2023

#29 Add renameat, readv, fdatasync. Please note that fsync and fdatasync is not really implemented.

@MrRobertYuan
Copy link
Contributor

For python update openat and add readlinkat
First add a struct Directory at fs.rs

pub struct Directory {
    inner: Mutex<axfs::fops::Directory>,
}

impl Directory {
    fn new(inner: axfs::fops::Directory) -> Self {
        Self {
            inner: Mutex::new(inner),
        }
    }

    fn add_to_fd_table(self) -> LinuxResult<c_int> {
        super::fd_ops::add_file_like(Arc::new(self))
    }

    fn from_fd(fd: c_int) -> LinuxResult<Arc<Self>> {
        let f = super::fd_ops::get_file_like(fd)?;
        f.into_any()
            .downcast::<Self>()
            .map_err(|_| LinuxError::EINVAL)
    }
}

impl FileLike for Directory {
    fn read(&self, buf: &mut [u8]) -> LinuxResult<usize> {
        Err(LinuxError::EACCES)
    }

    fn write(&self, buf: &[u8]) -> LinuxResult<usize> {
        Err(LinuxError::EACCES)
    }

    fn stat(&self) -> LinuxResult<ctypes::stat> {
        Err(LinuxError::EACCES)
    }

    fn into_any(self: Arc<Self>) -> Arc<dyn core::any::Any + Send + Sync> {
        self
    }

    fn poll(&self) -> LinuxResult<PollState> {
        Ok(PollState {
            readable: true,
            writable: true,
        })
    }

    fn set_nonblocking(&self, _nonblocking: bool) -> LinuxResult {
        Ok(())
    }
}

modify openat make it can open a dir

/// Open a file under a specific dir
///
///
pub fn sys_openat(_fd: usize, path: *const c_char, flags: c_int, mode: ctypes::mode_t) -> c_int {
    let path = char_ptr_to_str(path);
    debug!("sys_openat <= {:?}, {:#o} {:#o}", path, flags, mode);
    syscall_body!(sys_openat, {
        let options = flags_to_options(flags, mode);
        if (flags as u32) & ctypes::O_DIRECTORY != 0 {
            let dir = axfs::fops::Directory::open_dir(path?, &options)?;
            Directory::new(dir).add_to_fd_table()
        }
        else{
            let file = axfs::fops::File::open(path?, &options)?;
            File::new(file).add_to_fd_table()
        }
    })
}

add readlinkat

/// read value of a symbolic link relative to directory file descriptor
///
/// 
pub fn sys_readlinkat(fd: c_int, pathname: *const c_char, buf: *mut c_char, bufsize: usize) -> usize {
    let path = char_ptr_to_str(pathname);
    debug!("sys_readlinkat <= path = {:?}, fd = {:}, bufsize = {:}", path, fd, bufsize);
    syscall_body!(sys_readlinkat, {
        let mut options = OpenOptions::new();
        options.read(true);
        let dst = unsafe { core::slice::from_raw_parts_mut(buf as *mut u8, bufsize as _) };
        // if fd == AT_FDCWD then readat the relative path
        if fd == ctypes::AT_FDCWD as c_int {
            let file = axfs::fops::File::open(path?, &options)?;
            let mut file = File::new(file);
            Ok(file.read(dst)?)
        }
        else{
            let dir = Directory::from_fd(fd)?;
            let mut file = dir.inner.lock().open_file_at(path?, &options)?;
            Ok(file.read(dst)?)
        }
    })
}

@minminm
Copy link
Contributor

minminm commented Dec 14, 2023

For python add getdents64
First add type ino_t, dirent in api/arceos_posix_api/build.rs

fn gen_c_to_rust_bindings(in_file: &str, out_file: &str) {

    let allow_types = [
        "stat",
        "size_t",
        "ssize_t",
        ...
        "ino_t",  // new line
        "dirent", // new line
    ];

    ...
}

Then add sys_getdents64 in fs.rs

type LinuxDirent64 = ctypes::dirent;

fn convert_name_to_array(name: &[u8]) -> [i8; 256] {
    let mut array = [0i8; 256];
    let len = name.len();
    let name_ptr = name.as_ptr() as *const i8;
    let array_ptr = array.as_mut_ptr();
    
    unsafe {
        core::ptr::copy_nonoverlapping(name_ptr, array_ptr, len);
    }

    array
}

/// Read directory entries from a directory file descriptor.
/// 
/// TODO: check errors
pub unsafe fn sys_getdents64(fd: c_uint, dirent: *mut LinuxDirent64, count: c_uint) -> c_long {
    debug!(
        "sys_getdents64 <= fd: {}, dirent: {:p}, count: {}",
        fd, dirent, count
    );

    syscall_body!(sys_getdents64, {
        let expect_entries = count as usize / 280;        
        let dir = Directory::from_fd(fd as i32)?;
        let mut my_dirent: Vec<DirEntry> = (0..expect_entries).map(|_| DirEntry::default()).collect();

        let n = dir.inner.lock().read_dir(&mut my_dirent)?;       
        
        for (i, entry) in my_dirent.iter().enumerate() {
            let linux_dirent = LinuxDirent64 {
                d_ino: 1, 
                d_off: 280,
                d_reclen: 280,
                d_type: entry.entry_type() as u8, 
                d_name: convert_name_to_array(&entry.name_as_bytes()), 
            };

            unsafe {
                core::ptr::write(dirent.add(i), linux_dirent);
            }
        }

        Ok(n * 280)
    })
}

@Miochyann
Copy link
Contributor

Missing syscall :SYS_linkat , the system call number is 37

@AuYang261
Copy link
Contributor

AuYang261 commented Mar 5, 2024

Missing syscall: SYS_getrandom, whose number is 278 in aarch64.

@coolyjg
Copy link
Contributor Author

coolyjg commented Mar 7, 2024

Missing syscall: SYS_getrandom, whose number is 278 in aarch64.

Maybe ulib/ruxlibc/src/rand.rs should be put under ruxos-posix-api/

@AuYang261
Copy link
Contributor

Missing syscall: SYS_preadv, whose number is 69 in aarch64.

@AuYang261
Copy link
Contributor

Missing the implement of syscall SYS_mremap, which needed by WAMR.

@coolyjg
Copy link
Contributor Author

coolyjg commented Mar 8, 2024

Missing the implement of syscall SYS_mremap, which needed by WAMR.

You can use munmap + mmap to do a fake implementation temporarily. True implementation should wait for @ken4647 's work.

@coolyjg
Copy link
Contributor Author

coolyjg commented Mar 15, 2024

Previous readlinkat implementation is wrong. Now it is changed to #61

@TheSayOL
Copy link
Contributor

TheSayOL commented Apr 1, 2024

A bug in system call SYS_ppoll: argument timeout could be NULL, and should be checked before using it.

below is new version:

/// `ppoll` used by A64. Currently ignore signal
pub unsafe fn sys_ppoll(
    fds: *mut ctypes::pollfd,
    nfds: ctypes::nfds_t,
    timeout: *const ctypes::timespec,
    _sig_mask: *const ctypes::sigset_t,
    _sig_num: ctypes::size_t,
) -> c_int {
    let to = if timeout.is_null(){
        -1
    } else {
        Duration::from(*timeout).as_millis() as c_int
    };
    debug!("sys_ppoll <= nfds: {} timeout: {:?}", nfds, to);
    sys_poll(fds, nfds, to)
}

@TheSayOL
Copy link
Contributor

TheSayOL commented Apr 7, 2024

missing SYS_kill and SYS_times.

@TheSayOL
Copy link
Contributor

missing SYS_timerfd_create, SYS_timerfd_settime and SYS_timerfd_gettime.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants