Skip to content

Commit

Permalink
Merge pull request syswonder#146 from lhw2002426/multiprocess-loopback
Browse files Browse the repository at this point in the history
Multiprocess loopback
  • Loading branch information
ken4647 authored Nov 26, 2024
2 parents 698e1fa + 2dba7dc commit 029a431
Show file tree
Hide file tree
Showing 39 changed files with 451 additions and 119 deletions.
2 changes: 1 addition & 1 deletion api/ruxos_posix_api/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ multitask = ["ruxfeat/multitask", "ruxtask/multitask", "dep:ruxfutex"]
fd = ["alloc"]
fs = ["dep:ruxfs", "ruxfeat/fs", "fd"]
net = ["dep:ruxnet", "ruxfeat/net", "fd"]
signal = ["ruxruntime/signal"]
signal = ["ruxruntime/signal", "ruxhal/signal"]
pipe = ["fd"]
select = ["fd"]
epoll = ["fd"]
Expand Down
3 changes: 2 additions & 1 deletion api/ruxos_posix_api/src/imp/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ pub mod getrandom;
pub mod io;
pub mod prctl;
pub mod resources;
pub mod rt_sig;
pub mod stat;
pub mod sys;
pub mod task;
Expand All @@ -39,6 +38,8 @@ pub mod pipe;
#[cfg(feature = "multitask")]
pub mod pthread;
#[cfg(feature = "signal")]
pub mod rt_sig;
#[cfg(feature = "signal")]
pub mod signal;

/// Invalid syscall
Expand Down
2 changes: 1 addition & 1 deletion api/ruxos_posix_api/src/imp/pipe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* See the Mulan PSL v2 for more details.
*/

use alloc::sync::{Weak, Arc};
use alloc::sync::{Arc, Weak};
use core::ffi::c_int;

use axerrno::{LinuxError, LinuxResult};
Expand Down
2 changes: 1 addition & 1 deletion api/ruxos_posix_api/src/imp/pthread/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ pub fn sys_exit_group(status: c_int) -> ! {
debug!("sys_exit_group <= status: {:#?}", status);

// TODO: exit all threads, send signal to all threads

// drop all file opened by current task
current().fs.lock().as_mut().unwrap().close_all_files();

Expand Down
42 changes: 37 additions & 5 deletions api/ruxos_posix_api/src/imp/rt_sig.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@
use axerrno::LinuxError;

use crate::ctypes;
use crate::{
ctypes::{self, k_sigaction},
sys_sigaction,
};
use core::{
ffi::c_int,
sync::atomic::{AtomicUsize, Ordering},
Expand Down Expand Up @@ -84,12 +87,41 @@ pub fn sys_rt_sigprocmask(
}

/// sigaction syscall for A64 musl
pub fn sys_rt_sigaction(
///
/// TODO: if sa is 0, return now action
pub unsafe fn sys_rt_sigaction(
sig: c_int,
_sa: *const ctypes::sigaction,
_old: *mut ctypes::sigaction,
sa: *const ctypes::sigaction,
old: *mut ctypes::sigaction,
_sigsetsize: ctypes::size_t,
) -> c_int {
debug!("sys_rt_sigaction <= sig: {}", sig);
syscall_body!(sys_rt_sigaction, Ok(0))
syscall_body!(sys_rt_sigaction, {
if sa as u64 == 0 || old as u64 == 0 {
Err(LinuxError::EFAULT)
} else {
let sa = unsafe { *sa };
let old = unsafe { *old };
let sa = k_sigaction::from(sa);
let mut old_sa = k_sigaction::from(old);
sys_sigaction(sig as _, Some(&sa), Some(&mut old_sa));
Ok(0)
}
})
}

impl From<ctypes::sigaction> for k_sigaction {
fn from(sa: ctypes::sigaction) -> Self {
let mut ret = Self {
..Default::default()
};
ret.flags = sa.sa_flags as _;
let mask = sa.sa_mask.__bits[0]; // only get the first 64 signals
ret.mask[0] = mask as _;
ret.mask[1] = (mask >> 32) as _;

ret.handler = unsafe { sa.__sa_handler.sa_handler };
ret.restorer = sa.sa_restorer;
ret
}
}
18 changes: 15 additions & 3 deletions api/ruxos_posix_api/src/imp/signal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,20 @@ pub unsafe fn sys_sigaltstack(
syscall_body!(sys_sigaltstack, Ok(0))
}

/// TODO: send a signal to a process
pub unsafe fn sys_kill(pid: pid_t, sig: c_int) -> c_int {
/// send a signal to a process
pub fn sys_kill(pid: pid_t, sig: c_int) -> c_int {
debug!("sys_kill <= pid {} sig {}", pid, sig);
syscall_body!(sys_kill, Ok(0))
syscall_body!(sys_kill, {
match Signal::signal(sig as _, true) {
None => Err(LinuxError::EINVAL),
Some(_) => Ok(0),
}
})
}

/// send a signal to a thread
/// TODO: send to the specified thread.
pub fn sys_tkill(tid: pid_t, sig: c_int) -> c_int {
debug!("sys_tkill <= tid {} sig {}", tid, sig);
sys_kill(tid, sig)
}
4 changes: 2 additions & 2 deletions api/ruxos_posix_api/src/imp/task.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ pub fn sys_wait4(
// lower 8 bits of exit_code is the signal number, while upper 8 bits of exit_code is the exit status
// according to "bits/waitstatus.h" in glibc source code.
// TODO: add signal number to wstatus
wstatus.write(task.exit_code()<<8);
wstatus.write(task.exit_code() << 8);
}
process_map.remove(&(pid as u64));
return pid;
Expand Down Expand Up @@ -108,7 +108,7 @@ pub fn sys_wait4(
// lower 8 bits of exit_code is the signal number, while upper 8 bits of exit_code is the exit status
// according to "bits/waitstatus.h" in glibc source code.
// TODO: add signal number to wstatus
wstatus.write(task.exit_code()<<8);
wstatus.write(task.exit_code() << 8);
}
let _ = to_remove.insert(*child_pid);
break;
Expand Down
11 changes: 8 additions & 3 deletions api/ruxos_posix_api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ pub use imp::getrandom::{sys_getrandom, sys_rand, sys_random, sys_srand};
pub use imp::io::{sys_read, sys_readv, sys_write, sys_writev};
pub use imp::prctl::{sys_arch_prctl, sys_prctl};
pub use imp::resources::{sys_getrlimit, sys_prlimit64, sys_setrlimit};
pub use imp::rt_sig::{sys_rt_sigaction, sys_rt_sigprocmask};
pub use imp::stat::{
sys_getegid, sys_geteuid, sys_getgid, sys_getpgid, sys_getuid, sys_setgid, sys_setpgid,
sys_setuid, sys_umask,
Expand Down Expand Up @@ -108,7 +107,11 @@ pub use imp::pthread::{
sys_pthread_setspecific,
};
#[cfg(feature = "signal")]
pub use imp::signal::{sys_getitimer, sys_kill, sys_setitimer, sys_sigaction, sys_sigaltstack};
pub use imp::rt_sig::{sys_rt_sigaction, sys_rt_sigprocmask};
#[cfg(feature = "signal")]
pub use imp::signal::{
sys_getitimer, sys_kill, sys_setitimer, sys_sigaction, sys_sigaltstack, sys_tkill,
};

#[cfg(feature = "multitask")]
pub use imp::pthread::futex::sys_futex;
Expand All @@ -117,7 +120,9 @@ pub use imp::pthread::sys_clone;
#[cfg(all(feature = "multitask", feature = "musl"))]
pub use imp::pthread::sys_set_tid_address;
#[cfg(feature = "multitask")]
pub use imp::pthread::{sys_pthread_create, sys_pthread_exit, sys_exit_group, sys_pthread_join, sys_pthread_self};
pub use imp::pthread::{
sys_exit_group, sys_pthread_create, sys_pthread_exit, sys_pthread_join, sys_pthread_self,
};

#[cfg(feature = "fs")]
pub use imp::execve::sys_execve;
7 changes: 6 additions & 1 deletion apps/c/httpclient/expect_info.out
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,12 @@ Initialize platform devices...
Initialize device drivers...
registered a new Net device at .\+: "virtio-net"
Initialize network subsystem...
use NIC 0: "virtio-net"
net stack: smoltcp
use NIC: "loopback"
created net interface "loopback":
ether: 00-00-00-00-00-00
ip: 127.0.0.1/24
use NIC: "virtio-net"
created net interface "eth0":
ether: 52-54-00-12-34-56
ip: 10.0.2.15/24
Expand Down
1 change: 1 addition & 0 deletions crates/driver_net/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ documentation = "https://rcore-os.github.io/arceos/driver_net/index.html"

[features]
default = []
loopback = []
ixgbe = ["dep:ixgbe-driver"]

[dependencies]
Expand Down
3 changes: 3 additions & 0 deletions crates/driver_net/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ use alloc::sync::Arc;
#[cfg(feature = "ixgbe")]
/// ixgbe NIC device driver.
pub mod ixgbe;
#[cfg(feature = "loopback")]
/// loopback device driver
pub mod loopback;
mod net_buf;

use core::ptr::NonNull;
Expand Down
131 changes: 131 additions & 0 deletions crates/driver_net/src/loopback.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
/* Copyright (c) [2023] [Syswonder Community]
* [Ruxos] is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
use crate::{EthernetAddress, NetBuf, NetBufBox, NetBufPool, NetBufPtr, NetDriverOps};
use alloc::collections::VecDeque;
use alloc::sync::Arc;
use driver_common::{BaseDriverOps, DevError, DevResult, DeviceType};

extern crate alloc;

const NET_BUF_LEN: usize = 1526;

/// The VirtIO network device driver.
///
/// `QS` is the VirtIO queue size.
pub struct LoopbackDevice {
mac_address: EthernetAddress,
pub(crate) queue: VecDeque<NetBufBox>,
buf_pool: Arc<NetBufPool>,
}

unsafe impl Send for LoopbackDevice {}
unsafe impl Sync for LoopbackDevice {}

impl LoopbackDevice {
/// Creates a new driver instance and initializes the device
pub fn new(mac_address: Option<[u8; 6]>) -> Self {
let buf_pool = match NetBufPool::new(1024, NET_BUF_LEN) {
Ok(pool) => pool,
Err(_) => {
panic!("fail to create netbufpool");
}
};
Self {
mac_address: match mac_address {
Some(address) => EthernetAddress(address),
None => EthernetAddress([0; 6]),
},
queue: VecDeque::new(),
buf_pool: buf_pool,
}
}
}

impl BaseDriverOps for LoopbackDevice {
fn device_name(&self) -> &str {
"loopback"
}

fn device_type(&self) -> DeviceType {
DeviceType::Net
}
}

use log::info;

impl NetDriverOps for LoopbackDevice {
#[inline]
fn mac_address(&self) -> EthernetAddress {
EthernetAddress(self.mac_address.0)
}

#[inline]
fn can_transmit(&self) -> bool {
true
}

#[inline]
fn can_receive(&self) -> bool {
!self.queue.is_empty()
}

#[inline]
fn rx_queue_size(&self) -> usize {
self.queue.len()
}

#[inline]
fn tx_queue_size(&self) -> usize {
self.queue.len()
}

fn fill_rx_buffers(&mut self, buf_pool: &Arc<NetBufPool>) -> DevResult {
Ok(())
}

fn recycle_rx_buffer(&mut self, rx_buf: NetBufPtr) -> DevResult {
Ok(())
}

fn recycle_tx_buffers(&mut self) -> DevResult {
Ok(())
}

fn prepare_tx_buffer(&self, tx_buf: &mut NetBuf, pkt_len: usize) -> DevResult {
Ok(())
}

fn transmit(&mut self, tx_buf: NetBufPtr) -> DevResult {
unsafe { self.queue.push_back(NetBuf::from_buf_ptr(tx_buf)) }
Ok(())
}

fn receive(&mut self) -> DevResult<NetBufPtr> {
if let Some(token) = self.queue.pop_front() {
Ok(token.into_buf_ptr())
} else {
Err(DevError::Again)
}
}

fn alloc_tx_buffer(&mut self, size: usize) -> DevResult<NetBufPtr> {
let mut net_buf = self.buf_pool.alloc_boxed().ok_or(DevError::NoMemory)?;
let pkt_len = size;

// 1. Check if the buffer is large enough.
let hdr_len = net_buf.header_len();
if hdr_len + pkt_len > net_buf.capacity() {
return Err(DevError::InvalidParam);
}
net_buf.set_packet_len(pkt_len);

// 2. Return the buffer.
Ok(net_buf.into_buf_ptr())
}
}
5 changes: 1 addition & 4 deletions crates/lwip_rust/build.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use std::path::PathBuf;

fn main() {
println!("cargo:rustc-link-lib=lwip");
println!("cargo:rerun-if-changed=custom");
Expand Down Expand Up @@ -28,9 +26,8 @@ fn generate_lwip_bindings() {
.generate()
.expect("Unable to generate bindings");

let out_path = PathBuf::from("src");
bindings
.write_to_file(out_path.join("bindings.rs"))
.write_to_file("src/bindings.rs")
.expect("Couldn't write bindings!");
}

Expand Down
4 changes: 2 additions & 2 deletions crates/lwip_rust/custom/lwipopts.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@
#define LWIP_TCP 1
#define LWIP_CALLBACK_API 1
#define LWIP_NETIF_API 0
#define LWIP_NETIF_LOOPBACK 0
#define LWIP_HAVE_LOOPIF 1
#define LWIP_NETIF_LOOPBACK 1
#define LWIP_HAVE_LOOPIF 0
#define LWIP_HAVE_SLIPIF 0
#define LWIP_NETCONN 0
#define LWIP_SOCKET 0
Expand Down
1 change: 1 addition & 0 deletions modules/ruxdriver/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ virtio-9p = ["_9p","virtio", "driver_virtio/v9p"]
ramdisk = ["block", "driver_block/ramdisk"]
bcm2835-sdhci = ["block", "driver_block/bcm2835-sdhci"]
ixgbe = ["net", "driver_net/ixgbe", "dep:axalloc", "dep:ruxhal"]
loopback = ["driver_net/loopback", "dyn"]
# more devices example: e1000 = ["net", "driver_net/e1000"]

default = ["bus-mmio"]
Expand Down
2 changes: 1 addition & 1 deletion modules/ruxdriver/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* See the Mulan PSL v2 for more details.
*/

const NET_DEV_FEATURES: &[&str] = &["ixgbe", "virtio-net"];
const NET_DEV_FEATURES: &[&str] = &["ixgbe", "virtio-net", "loopback"];
const BLOCK_DEV_FEATURES: &[&str] = &["ramdisk", "bcm2835-sdhci", "virtio-blk"];
const DISPLAY_DEV_FEATURES: &[&str] = &["virtio-gpu"];
const _9P_DEV_FEATURES: &[&str] = &["virtio-9p"];
Expand Down
Loading

0 comments on commit 029a431

Please sign in to comment.