diff --git a/os/StarryOS/kernel/src/syscall/net/opt.rs b/os/StarryOS/kernel/src/syscall/net/opt.rs index 79ab1a66ae..63a9c858fd 100644 --- a/os/StarryOS/kernel/src/syscall/net/opt.rs +++ b/os/StarryOS/kernel/src/syscall/net/opt.rs @@ -89,27 +89,45 @@ macro_rules! call_dispatch { call_dispatch! { $dispatch, $pat, + // ---- Implemented socket options ---- (SOL_SOCKET, SO_REUSEADDR) => ReuseAddress as IntBool, (SOL_SOCKET, SO_ERROR) => Error, - (SOL_SOCKET, SO_DONTROUTE) => DontRoute as IntBool, - (SOL_SOCKET, SO_SNDBUF) => SendBuffer as Int, - (SOL_SOCKET, SO_RCVBUF) => ReceiveBuffer as Int, + (SOL_SOCKET, SO_DONTROUTE) => DontRoute as IntBool, // stored but routing logic ignores it + (SOL_SOCKET, SO_SNDBUF) => SendBuffer as Int, // TODO: set is no-op, smoltcp uses fixed buffer + (SOL_SOCKET, SO_RCVBUF) => ReceiveBuffer as Int,// TODO: set is no-op, smoltcp uses fixed buffer (SOL_SOCKET, SO_KEEPALIVE) => KeepAlive as IntBool, (SOL_SOCKET, SO_RCVTIMEO) => ReceiveTimeout as Duration, (SOL_SOCKET, SO_SNDTIMEO) => SendTimeout as Duration, - (SOL_SOCKET, SO_PASSCRED) => PassCredentials as IntBool, + (SOL_SOCKET, SO_PASSCRED) => PassCredentials as IntBool, // TODO: set accepted but no-op for non-unix (SOL_SOCKET, SO_PEERCRED) => PeerCredentials as Ucred, + (SOL_SOCKET, SO_TYPE) => SocketType as Int, // read-only + (SOL_SOCKET, SO_PROTOCOL) => SocketProtocol as Int,// read-only + (SOL_SOCKET, SO_DOMAIN) => SocketDomain as Int, // read-only (PROTO_TCP, TCP_NODELAY) => NoDelay as IntBool, - (PROTO_TCP, TCP_MAXSEG) => MaxSegment as Int, + (PROTO_TCP, TCP_MAXSEG) => MaxSegment as Int, // TODO: hardcoded 1460, get actual MSS (PROTO_TCP, TCP_KEEPIDLE) => TcpKeepIdle as Int, (PROTO_TCP, TCP_KEEPINTVL) => TcpKeepInterval as Int, (PROTO_TCP, TCP_KEEPCNT) => TcpKeepCount as Int, (PROTO_TCP, TCP_USER_TIMEOUT) => TcpUserTimeout as Int, - (PROTO_TCP, TCP_INFO) => TcpInfo, + (PROTO_TCP, TCP_INFO) => TcpInfo, // TODO: stub, returns empty struct (PROTO_IP, IP_TTL) => Ttl as Int, - (PROTO_IP, IP_RECVERR) => RecvErr as IntBool, + (PROTO_IP, IP_RECVERR) => RecvErr as IntBool, // TODO: hardcoded false, no errqueue support + // ---- Not yet implemented (add as needed) ---- + // (SOL_SOCKET, SO_LINGER) => ..., // TODO: needs close() linger semantics + // (SOL_SOCKET, SO_REUSEPORT) => ..., // TODO: needs kernel support + // (SOL_SOCKET, SO_PRIORITY) => ..., // TODO: needs kernel support + // (SOL_SOCKET, SO_RCVLOWAT) => ..., // TODO: needs kernel support + // (SOL_SOCKET, SO_SNDLOWAT) => ..., // TODO: needs kernel support + // (PROTO_TCP, TCP_CORK) => ..., // TODO: needs smoltcp support + // (PROTO_TCP, TCP_DEFER_ACCEPT) => ..., // TODO: needs kernel support + // (PROTO_TCP, TCP_QUICKACK) => ..., // TODO: needs kernel support + // (PROTO_TCP, TCP_SYNCNT) => ..., // TODO: needs kernel support + // (PROTO_TCP, TCP_WINDOW_CLAMP) => ..., // TODO: needs kernel support + // (PROTO_IP, IP_TOS) => ..., // TODO: needs kernel support + // (PROTO_IP, IP_OPTIONS) => ..., // TODO: needs kernel support + // (IPPROTO_IPV6, IPV6_V6ONLY) => ..., // TODO: currently hardcoded inline } }}; ($dispatch:ident, $in:expr, $($pat:pat => $which:ident $(as $conv:ty)?),* $(,)?) => { diff --git a/os/arceos/modules/axnet-ng/src/general.rs b/os/arceos/modules/axnet-ng/src/general.rs index b24f895012..b1c4d89500 100644 --- a/os/arceos/modules/axnet-ng/src/general.rs +++ b/os/arceos/modules/axnet-ng/src/general.rs @@ -1,10 +1,10 @@ use core::{ - sync::atomic::{AtomicBool, AtomicU32, AtomicU64, Ordering}, + sync::atomic::{AtomicBool, AtomicI32, AtomicU32, AtomicU64, Ordering}, task::Waker, time::Duration, }; -use ax_errno::AxResult; +use ax_errno::{AxError, AxResult, LinuxError}; use ax_task::future::{block_on, poll_io, timeout}; use axpoll::{IoEvents, Pollable}; @@ -24,14 +24,20 @@ pub(crate) struct GeneralOptions { recv_timeout_nanos: AtomicU64, device_mask: AtomicU32, -} -impl Default for GeneralOptions { - fn default() -> Self { - Self::new() - } + + /// Socket type: SOCK_STREAM (1), SOCK_DGRAM (2), SOCK_RAW (3). + socket_type: AtomicI32, + /// Socket domain: AF_INET (2), AF_UNIX (1), AF_VSOCK (40). + domain: i32, + /// IP protocol: IPPROTO_TCP (6), IPPROTO_UDP (17), IPPROTO_ICMP (1), etc. + protocol: i32, } impl GeneralOptions { - pub fn new() -> Self { + /// Create new GeneralOptions. `socket_type` is the SOCK_* constant + /// (e.g. SOCK_STREAM=1, SOCK_DGRAM=2, SOCK_RAW=3). + /// `domain` is the AF_* constant (e.g. AF_INET=2, AF_UNIX=1, AF_VSOCK=40). + /// `protocol` is the IPPROTO_* constant (e.g. IPPROTO_TCP=6, IPPROTO_UDP=17, IPPROTO_ICMP=1). + pub fn new(socket_type: i32, domain: i32, protocol: i32) -> Self { Self { nonblock: AtomicBool::new(false), reuse_address: AtomicBool::new(false), @@ -40,6 +46,10 @@ impl GeneralOptions { recv_timeout_nanos: AtomicU64::new(0), device_mask: AtomicU32::new(0), + + socket_type: AtomicI32::new(socket_type), + domain, + protocol, } } @@ -152,6 +162,15 @@ impl Configurable for GeneralOptions { O::RecvErr(val) => { **val = false; } + O::SocketType(t) => { + **t = self.socket_type.load(Ordering::Relaxed); + } + O::SocketProtocol(proto) => { + **proto = self.protocol; + } + O::SocketDomain(domain) => { + **domain = self.domain; + } _ => return Ok(false), } Ok(true) @@ -181,6 +200,10 @@ impl Configurable for GeneralOptions { O::RecvErr(_) => { // TODO: Retrieve ICMP errors via errqueue } + O::SocketType(_) | O::SocketProtocol(_) | O::SocketDomain(_) => { + // Read-only options + return Err(AxError::from(LinuxError::ENOPROTOOPT)); + } _ => return Ok(false), } Ok(true) diff --git a/os/arceos/modules/axnet-ng/src/options.rs b/os/arceos/modules/axnet-ng/src/options.rs index 354e30a884..608aa79a67 100644 --- a/os/arceos/modules/axnet-ng/src/options.rs +++ b/os/arceos/modules/axnet-ng/src/options.rs @@ -64,6 +64,9 @@ define_options! { SendBufferForce(usize), PassCredentials(bool), PeerCredentials(UnixCredentials), + SocketType(i32), + SocketProtocol(i32), + SocketDomain(i32), // --- TCP level options (TCP_*) ---- NoDelay(bool), diff --git a/os/arceos/modules/axnet-ng/src/raw.rs b/os/arceos/modules/axnet-ng/src/raw.rs index b232148b25..1f52f70320 100644 --- a/os/arceos/modules/axnet-ng/src/raw.rs +++ b/os/arceos/modules/axnet-ng/src/raw.rs @@ -61,7 +61,7 @@ impl RawSocket { /// Creates a raw socket for the given IP version and protocol. pub fn new(ip_version: IpVersion, ip_protocol: IpProtocol) -> Self { let handle = SOCKET_SET.add(new_raw_socket(ip_version, ip_protocol)); - let general = GeneralOptions::new(); + let general = GeneralOptions::new(3, 2, u8::from(ip_protocol) as i32); // SOCK_RAW general.set_device_mask(u32::MAX); Self { handle, diff --git a/os/arceos/modules/axnet-ng/src/tcp.rs b/os/arceos/modules/axnet-ng/src/tcp.rs index 96a64e66a0..6a5ef72bac 100644 --- a/os/arceos/modules/axnet-ng/src/tcp.rs +++ b/os/arceos/modules/axnet-ng/src/tcp.rs @@ -74,7 +74,7 @@ impl TcpSocket { peer_endpoint: Mutex::new(None), bound_registered: AtomicBool::new(false), - general: GeneralOptions::new(), + general: GeneralOptions::new(1, 2, 6), // SOCK_STREAM pending_error: AtomicI32::new(0), keep_idle_secs: AtomicU32::new(TCP_KEEPIDLE_DEFAULT_SECS), keep_interval_secs: AtomicU32::new(TCP_KEEPINTVL_DEFAULT_SECS), @@ -98,7 +98,7 @@ impl TcpSocket { peer_endpoint: Mutex::new(Some(remote_endpoint)), bound_registered: AtomicBool::new(false), - general: GeneralOptions::new(), + general: GeneralOptions::new(1, 2, 6), // SOCK_STREAM pending_error: AtomicI32::new(0), keep_idle_secs: AtomicU32::new(TCP_KEEPIDLE_DEFAULT_SECS), keep_interval_secs: AtomicU32::new(TCP_KEEPINTVL_DEFAULT_SECS), diff --git a/os/arceos/modules/axnet-ng/src/udp.rs b/os/arceos/modules/axnet-ng/src/udp.rs index cfe810ef9b..4ed47be5fc 100644 --- a/os/arceos/modules/axnet-ng/src/udp.rs +++ b/os/arceos/modules/axnet-ng/src/udp.rs @@ -68,7 +68,7 @@ impl UdpSocket { local_addr: RwLock::new(None), peer_addr: RwLock::new(None), - general: GeneralOptions::new(), + general: GeneralOptions::new(2, 2, 17), // SOCK_DGRAM cork: Mutex::new(None), } } diff --git a/os/arceos/modules/axnet-ng/src/unix/dgram.rs b/os/arceos/modules/axnet-ng/src/unix/dgram.rs index 389cedbdc0..34d28b7abc 100644 --- a/os/arceos/modules/axnet-ng/src/unix/dgram.rs +++ b/os/arceos/modules/axnet-ng/src/unix/dgram.rs @@ -58,7 +58,7 @@ impl DgramTransport { connected: RwLock::new(None), local_addr: RwLock::new(UnixSocketAddr::Unnamed), poll_state: Arc::default(), - general: GeneralOptions::default(), + general: GeneralOptions::new(2, 1, 0), // SOCK_DGRAM pid, } } @@ -73,7 +73,7 @@ impl DgramTransport { connected: RwLock::new(Some(connected)), local_addr: RwLock::new(UnixSocketAddr::Unnamed), poll_state: Arc::default(), - general: GeneralOptions::default(), + general: GeneralOptions::new(2, 1, 0), // SOCK_DGRAM pid, } } diff --git a/os/arceos/modules/axnet-ng/src/unix/stream.rs b/os/arceos/modules/axnet-ng/src/unix/stream.rs index 2c5b7ebabf..2c31a2f44c 100644 --- a/os/arceos/modules/axnet-ng/src/unix/stream.rs +++ b/os/arceos/modules/axnet-ng/src/unix/stream.rs @@ -156,7 +156,7 @@ impl StreamTransport { channel: Mutex::new(channel), conn_rx: Mutex::new(None), poll_state: PollSet::new(), - general: GeneralOptions::default(), + general: GeneralOptions::new(1, 1, 0), // SOCK_STREAM pid, rx_closed: AtomicBool::new(false), tx_closed: AtomicBool::new(false), diff --git a/os/arceos/modules/axnet-ng/src/vsock/stream.rs b/os/arceos/modules/axnet-ng/src/vsock/stream.rs index 5579b3e13c..da9db79f0e 100644 --- a/os/arceos/modules/axnet-ng/src/vsock/stream.rs +++ b/os/arceos/modules/axnet-ng/src/vsock/stream.rs @@ -31,7 +31,7 @@ impl VsockStreamTransport { conn_id: Mutex::new(None), connection: Mutex::new(None), state: StateLock::new(State::Idle), - general: GeneralOptions::new(), + general: GeneralOptions::new(1, 40, 0), // SOCK_STREAM } } @@ -122,7 +122,7 @@ impl VsockTransportOps for VsockStreamTransport { conn_id: Mutex::new(Some(conn_id)), connection: Mutex::new(Some(conn)), state: StateLock::new(State::Connected), - general: GeneralOptions::default(), + general: GeneralOptions::new(1, 40, 0), // SOCK_STREAM }; Ok((VsockTransport::Stream(new_transport), peer_addr)) diff --git a/test-suit/starryos/normal/qemu-smp1/test-sockopt/c/CMakeLists.txt b/test-suit/starryos/normal/qemu-smp1/test-sockopt/c/CMakeLists.txt new file mode 100644 index 0000000000..45e79a4649 --- /dev/null +++ b/test-suit/starryos/normal/qemu-smp1/test-sockopt/c/CMakeLists.txt @@ -0,0 +1,9 @@ +cmake_minimum_required(VERSION 3.20) +project(test-sockopt C) +set(CMAKE_C_STANDARD 11) +set(CMAKE_C_STANDARD_REQUIRED ON) +set(CMAKE_C_EXTENSIONS OFF) +add_executable(test-sockopt src/main.c) +target_include_directories(test-sockopt PRIVATE src) +target_compile_options(test-sockopt PRIVATE -Wall -Wextra -Werror) +install(TARGETS test-sockopt RUNTIME DESTINATION usr/bin) diff --git a/test-suit/starryos/normal/qemu-smp1/test-sockopt/c/src/main.c b/test-suit/starryos/normal/qemu-smp1/test-sockopt/c/src/main.c new file mode 100644 index 0000000000..fb63d52d08 --- /dev/null +++ b/test-suit/starryos/normal/qemu-smp1/test-sockopt/c/src/main.c @@ -0,0 +1,153 @@ +/* + * test-sockopt — getsockopt / setsockopt 控制面系统调用测试 + * + * 覆盖 SO_TYPE / SO_PROTOCOL / SO_DOMAIN 三个只读 socket option。 + * 依据: Linux man-pages 7 socket(7) getsockopt(2)。 + * + * ===================================================================== + * 手册摘要 (man 7 socket, man 2 getsockopt) + * ===================================================================== + * + * ── SO_TYPE ─────────────────────────────────────────────────────────── + * int type; + * getsockopt(fd, SOL_SOCKET, SO_TYPE, &type, &len); + * + * 返回 socket 创建时的类型参数 (SOCK_STREAM=1, SOCK_DGRAM=2, SOCK_RAW=3)。 + * 只读; setsockopt 返回 ENOPROTOOPT。 + * + * ── SO_PROTOCOL ────────────────────────────────────────────────────── + * int proto; + * getsockopt(fd, SOL_SOCKET, SO_PROTOCOL, &proto, &len); + * + * 返回 socket 创建时的协议号 (IPPROTO_TCP=6, IPPROTO_UDP=17, 等)。 + * 只读; setsockopt 返回 ENOPROTOOPT。 + * Linux 3.13+ 可用。 + * + * ── SO_DOMAIN ──────────────────────────────────────────────────────── + * int domain; + * getsockopt(fd, SOL_SOCKET, SO_DOMAIN, &domain, &len); + * + * 返回 socket 创建时的地址族 (AF_INET=2, AF_UNIX=1, AF_VSOCK=40, 等)。 + * 只读; setsockopt 返回 ENOPROTOOPT。 + * Linux 3.13+ 可用。 + */ + +#include "test_framework.h" + +#include +#include +#include +#include +#include + +/* ---- SO_TYPE (3) ---- */ + +static void test_so_type(void) { + TEST_START("SO_TYPE"); + + int fd_tcp = socket(AF_INET, SOCK_STREAM, 0); + int fd_udp = socket(AF_INET, SOCK_DGRAM, 0); + CHECK(fd_tcp >= 0, "socket(TCP)"); + CHECK(fd_udp >= 0, "socket(UDP)"); + + /* TCP: SO_TYPE == SOCK_STREAM (1) */ + int type = -1; + socklen_t len = sizeof(type); + CHECK_RET(getsockopt(fd_tcp, SOL_SOCKET, SO_TYPE, &type, &len), 0, + "getsockopt(SO_TYPE) on TCP"); + CHECK(type == SOCK_STREAM, "TCP: SO_TYPE == SOCK_STREAM (1)"); + + /* UDP: SO_TYPE == SOCK_DGRAM (2) */ + type = -1; + len = sizeof(type); + CHECK_RET(getsockopt(fd_udp, SOL_SOCKET, SO_TYPE, &type, &len), 0, + "getsockopt(SO_TYPE) on UDP"); + CHECK(type == SOCK_DGRAM, "UDP: SO_TYPE == SOCK_DGRAM (2)"); + + /* 只读: setsockopt 必须拒绝 */ + int val = 1; + CHECK_ERR(setsockopt(fd_tcp, SOL_SOCKET, SO_TYPE, &val, sizeof(val)), + ENOPROTOOPT, "setsockopt(SO_TYPE) returns ENOPROTOOPT"); + + close(fd_tcp); + close(fd_udp); +} + +/* ---- SO_PROTOCOL (3) ---- */ + +static void test_so_protocol(void) { + TEST_START("SO_PROTOCOL"); + + int fd_tcp = socket(AF_INET, SOCK_STREAM, 0); + int fd_udp = socket(AF_INET, SOCK_DGRAM, 0); + CHECK(fd_tcp >= 0, "socket(TCP)"); + CHECK(fd_udp >= 0, "socket(UDP)"); + + /* TCP: SO_PROTOCOL == IPPROTO_TCP (6) */ + int proto = -1; + socklen_t len = sizeof(proto); + CHECK_RET(getsockopt(fd_tcp, SOL_SOCKET, SO_PROTOCOL, &proto, &len), 0, + "getsockopt(SO_PROTOCOL) on TCP"); + CHECK(proto == 6, "TCP: SO_PROTOCOL == IPPROTO_TCP (6)"); + + /* UDP: SO_PROTOCOL == IPPROTO_UDP (17) */ + proto = -1; + len = sizeof(proto); + CHECK_RET(getsockopt(fd_udp, SOL_SOCKET, SO_PROTOCOL, &proto, &len), 0, + "getsockopt(SO_PROTOCOL) on UDP"); + CHECK(proto == 17, "UDP: SO_PROTOCOL == IPPROTO_UDP (17)"); + + /* 只读: setsockopt 必须拒绝 */ + int val = 1; + CHECK_ERR(setsockopt(fd_tcp, SOL_SOCKET, SO_PROTOCOL, &val, sizeof(val)), + ENOPROTOOPT, "setsockopt(SO_PROTOCOL) returns ENOPROTOOPT"); + + close(fd_tcp); + close(fd_udp); +} + +/* ---- SO_DOMAIN (3) ---- */ + +static void test_so_domain(void) { + TEST_START("SO_DOMAIN"); + + int fd_tcp = socket(AF_INET, SOCK_STREAM, 0); + int fd_udp = socket(AF_INET, SOCK_DGRAM, 0); + CHECK(fd_tcp >= 0, "socket(TCP)"); + CHECK(fd_udp >= 0, "socket(UDP)"); + + /* TCP: SO_DOMAIN == AF_INET (2) */ + int domain = -1; + socklen_t len = sizeof(domain); + CHECK_RET(getsockopt(fd_tcp, SOL_SOCKET, SO_DOMAIN, &domain, &len), 0, + "getsockopt(SO_DOMAIN) on TCP"); + CHECK(domain == AF_INET, "TCP: SO_DOMAIN == AF_INET (2)"); + + /* UDP: SO_DOMAIN == AF_INET (2) */ + domain = -1; + len = sizeof(domain); + CHECK_RET(getsockopt(fd_udp, SOL_SOCKET, SO_DOMAIN, &domain, &len), 0, + "getsockopt(SO_DOMAIN) on UDP"); + CHECK(domain == AF_INET, "UDP: SO_DOMAIN == AF_INET (2)"); + + /* 只读: setsockopt 必须拒绝 */ + int val = 1; + CHECK_ERR(setsockopt(fd_tcp, SOL_SOCKET, SO_DOMAIN, &val, sizeof(val)), + ENOPROTOOPT, "setsockopt(SO_DOMAIN) returns ENOPROTOOPT"); + + close(fd_tcp); + close(fd_udp); +} + +/* ---- Main ---- */ + +int main(void) { + /* P0: pip blocker */ + test_so_type(); + + /* P1: protocol / domain */ + test_so_protocol(); + test_so_domain(); + + TEST_DONE(); +} diff --git a/test-suit/starryos/normal/qemu-smp1/test-sockopt/c/src/test_framework.h b/test-suit/starryos/normal/qemu-smp1/test-sockopt/c/src/test_framework.h new file mode 100644 index 0000000000..b697580a68 --- /dev/null +++ b/test-suit/starryos/normal/qemu-smp1/test-sockopt/c/src/test_framework.h @@ -0,0 +1,85 @@ +#pragma once + +/* 必须在最前面定义,确保 pipe2/gettid 等可用 */ +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif + +/* + * StarryOS Syscall Test Framework + * + * 极简独立测试框架:每个文件测一个 syscall,独立编译运行。 + * 目标:出错时精确定位到 源文件:行号 -> 哪个调用 -> 什么结果 + * + * 用法: + * TEST_START("测试名"); + * CHECK(call == expected, "描述"); + * CHECK_ERR(call, EBADF, "描述"); + * TEST_DONE(); + */ + +#include +#include +#include +#include + +static int __pass = 0; +static int __fail = 0; + +/* ---- 核心: 带文件名+行号的检查宏 ---- */ + +/* 检查条件为真 */ +#define CHECK(cond, msg) do { \ + if (cond) { \ + printf(" PASS | %s:%d | %s\n", __FILE__, __LINE__, msg); \ + __pass++; \ + } else { \ + printf(" FAIL | %s:%d | %s | errno=%d (%s)\n", \ + __FILE__, __LINE__, msg, errno, strerror(errno)); \ + __fail++; \ + } \ +} while(0) + +/* 检查 syscall 返回特定值 */ +#define CHECK_RET(call, expected, msg) do { \ + errno = 0; \ + long _r = (long)(call); \ + long _e = (long)(expected); \ + if (_r == _e) { \ + printf(" PASS | %s:%d | %s (ret=%ld)\n", \ + __FILE__, __LINE__, msg, _r); \ + __pass++; \ + } else { \ + printf(" FAIL | %s:%d | %s | expected=%ld got=%ld | errno=%d (%s)\n", \ + __FILE__, __LINE__, msg, _e, _r, errno, strerror(errno));\ + __fail++; \ + } \ +} while(0) + +/* 检查 syscall 失败且 errno 符合预期 */ +#define CHECK_ERR(call, exp_errno, msg) do { \ + errno = 0; \ + long _r = (long)(call); \ + if (_r == -1 && errno == (exp_errno)) { \ + printf(" PASS | %s:%d | %s (errno=%d as expected)\n", \ + __FILE__, __LINE__, msg, errno); \ + __pass++; \ + } else { \ + printf(" FAIL | %s:%d | %s | expected errno=%d got ret=%ld errno=%d (%s)\n", \ + __FILE__, __LINE__, msg, (int)(exp_errno), _r, errno, strerror(errno));\ + __fail++; \ + } \ +} while(0) + +/* ---- 测试边界 ---- */ +#define TEST_START(name) \ + printf("================================================\n"); \ + printf(" TEST: %s\n", name); \ + printf(" FILE: %s\n", __FILE__); \ + printf("================================================\n") + +#define TEST_DONE() \ + printf("------------------------------------------------\n"); \ + printf(" DONE: %d pass, %d fail\n", __pass, __fail); \ + printf("================================================\n\n"); \ + return __fail > 0 ? 1 : 0 diff --git a/test-suit/starryos/normal/qemu-smp1/test-sockopt/qemu-aarch64.toml b/test-suit/starryos/normal/qemu-smp1/test-sockopt/qemu-aarch64.toml new file mode 100644 index 0000000000..e9d0e6b588 --- /dev/null +++ b/test-suit/starryos/normal/qemu-smp1/test-sockopt/qemu-aarch64.toml @@ -0,0 +1,16 @@ +args = [ + "-nographic", + "-cpu", "cortex-a53", + "-device", "virtio-blk-pci,drive=disk0", + "-drive", "id=disk0,if=none,format=raw,file=${workspace}/target/rootfs/rootfs-aarch64-alpine.img", + "-device", "virtio-net-pci,netdev=net0", + "-netdev", "user,id=net0", +] +uefi = false +to_bin = true +shell_prefix = "root@starry:" +shell_init_cmd = "/usr/bin/test-sockopt" +success_regex = ["DONE: [0-9]+ pass, 0 fail"] +fail_regex = ["FAIL:", "panic", "panicked"] + +timeout = 30 diff --git a/test-suit/starryos/normal/qemu-smp1/test-sockopt/qemu-loongarch64.toml b/test-suit/starryos/normal/qemu-smp1/test-sockopt/qemu-loongarch64.toml new file mode 100644 index 0000000000..8b0ef42f62 --- /dev/null +++ b/test-suit/starryos/normal/qemu-smp1/test-sockopt/qemu-loongarch64.toml @@ -0,0 +1,18 @@ +args = [ + "-machine", "virt", + "-cpu", "la464", + "-nographic", + "-m", "128M", + "-device", "virtio-blk-pci,drive=disk0", + "-drive", "id=disk0,if=none,format=raw,file=${workspace}/target/rootfs/rootfs-loongarch64-alpine.img", + "-device", "virtio-net-pci,netdev=net0", + "-netdev", "user,id=net0", +] +uefi = false +to_bin = true +shell_prefix = "root@starry:" +shell_init_cmd = "/usr/bin/test-sockopt" +success_regex = ["DONE: [0-9]+ pass, 0 fail"] +fail_regex = ["FAIL:", "panic", "panicked"] + +timeout = 30 diff --git a/test-suit/starryos/normal/qemu-smp1/test-sockopt/qemu-riscv64.toml b/test-suit/starryos/normal/qemu-smp1/test-sockopt/qemu-riscv64.toml new file mode 100644 index 0000000000..50b2c4dd5f --- /dev/null +++ b/test-suit/starryos/normal/qemu-smp1/test-sockopt/qemu-riscv64.toml @@ -0,0 +1,14 @@ +args = [ + "-nographic", "-cpu", "rv64", + "-device", "virtio-blk-pci,drive=disk0", + "-drive", "id=disk0,if=none,format=raw,file=${workspace}/target/rootfs/rootfs-riscv64-alpine.img", + "-device", "virtio-net-pci,netdev=net0", + "-netdev", "user,id=net0", +] +uefi = false +to_bin = true +shell_prefix = "root@starry:" +shell_init_cmd = "/usr/bin/test-sockopt" +success_regex = ["DONE: [0-9]+ pass, 0 fail"] +fail_regex = ["FAIL:", "panic", "panicked"] +timeout = 30 diff --git a/test-suit/starryos/normal/qemu-smp1/test-sockopt/qemu-x86_64.toml b/test-suit/starryos/normal/qemu-smp1/test-sockopt/qemu-x86_64.toml new file mode 100644 index 0000000000..3395af22b3 --- /dev/null +++ b/test-suit/starryos/normal/qemu-smp1/test-sockopt/qemu-x86_64.toml @@ -0,0 +1,15 @@ +args = [ + "-nographic", + "-device", "virtio-blk-pci,drive=disk0", + "-drive", "id=disk0,if=none,format=raw,file=${workspace}/target/rootfs/rootfs-x86_64-alpine.img", + "-device", "virtio-net-pci,netdev=net0", + "-netdev", "user,id=net0", +] +uefi = false +to_bin = false +shell_prefix = "root@starry:" +shell_init_cmd = "/usr/bin/test-sockopt" +success_regex = ["DONE: [0-9]+ pass, 0 fail"] +fail_regex = ["FAIL:", "panic", "panicked"] + +timeout = 30