ready for merge in master (#964)

uevent should be format

Enum of smoltcp socket should be optimized.

need to add interface for routing subsys

actix is still not abled to run.

clean some casual added code to other places
This commit is contained in:
2024-10-10 17:53:39 +08:00
committed by GitHub
parent 79eda4bcf9
commit 40d9375b6b
102 changed files with 10497 additions and 3303 deletions

View File

@ -0,0 +1,2 @@
[build]
target = "x86_64-unknown-linux-musl"

3
user/apps/test-uevent/.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
/target
Cargo.lock
/install/

View File

@ -0,0 +1,12 @@
[package]
name = "test-uevent"
version = "0.1.0"
edition = "2021"
description = "test for uevent"
authors = [ "val213 <val213666@gmail.com>" ]
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
netlink-sys = "0.5"
nix = "0.24"

View File

@ -0,0 +1,56 @@
TOOLCHAIN="+nightly-2023-08-15-x86_64-unknown-linux-gnu"
RUSTFLAGS+=""
ifdef DADK_CURRENT_BUILD_DIR
# 如果是在dadk中编译那么安装到dadk的安装目录中
INSTALL_DIR = $(DADK_CURRENT_BUILD_DIR)
else
# 如果是在本地编译那么安装到当前目录下的install目录中
INSTALL_DIR = ./install
endif
ifeq ($(ARCH), x86_64)
export RUST_TARGET=x86_64-unknown-linux-musl
else ifeq ($(ARCH), riscv64)
export RUST_TARGET=riscv64gc-unknown-linux-gnu
else
# 默认为x86_86用于本地编译
export RUST_TARGET=x86_64-unknown-linux-musl
endif
run:
RUSTFLAGS=$(RUSTFLAGS) cargo $(TOOLCHAIN) run --target $(RUST_TARGET)
build:
RUSTFLAGS=$(RUSTFLAGS) cargo $(TOOLCHAIN) build --target $(RUST_TARGET)
clean:
RUSTFLAGS=$(RUSTFLAGS) cargo $(TOOLCHAIN) clean --target $(RUST_TARGET)
test:
RUSTFLAGS=$(RUSTFLAGS) cargo $(TOOLCHAIN) test --target $(RUST_TARGET)
doc:
RUSTFLAGS=$(RUSTFLAGS) cargo $(TOOLCHAIN) doc --target $(RUST_TARGET)
fmt:
RUSTFLAGS=$(RUSTFLAGS) cargo $(TOOLCHAIN) fmt
fmt-check:
RUSTFLAGS=$(RUSTFLAGS) cargo $(TOOLCHAIN) fmt --check
run-release:
RUSTFLAGS=$(RUSTFLAGS) cargo $(TOOLCHAIN) run --target $(RUST_TARGET) --release
build-release:
RUSTFLAGS=$(RUSTFLAGS) cargo $(TOOLCHAIN) build --target $(RUST_TARGET) --release
clean-release:
RUSTFLAGS=$(RUSTFLAGS) cargo $(TOOLCHAIN) clean --target $(RUST_TARGET) --release
test-release:
RUSTFLAGS=$(RUSTFLAGS) cargo $(TOOLCHAIN) test --target $(RUST_TARGET) --release
.PHONY: install
install:
RUSTFLAGS=$(RUSTFLAGS) cargo $(TOOLCHAIN) install --target $(RUST_TARGET) --path . --no-track --root $(INSTALL_DIR) --force

View File

@ -0,0 +1,14 @@
# DragonOS Rust-Application Template
您可以使用此模板来创建DragonOS应用程序。
## 使用方法
1. 使用DragonOS的tools目录下的`bootstrap.sh`脚本初始化环境
2. 在终端输入`cargo install cargo-generate`
3. 在终端输入`cargo generate --git https://github.com/DragonOS-Community/Rust-App-Template`即可创建项目
如果您的网络较慢,请使用镜像站`cargo generate --git https://git.mirrors.dragonos.org/DragonOS-Community/Rust-App-Template`
4. 使用`cargo run`来运行项目
5. 在DragonOS的`user/dadk/config`目录下,使用`dadk new`命令,创建编译配置,安装到DragonOS的`/`目录下。
(在dadk的编译命令选项处请使用Makefile里面的`make install`配置进行编译、安装)
6. 编译DragonOS即可安装

View File

@ -0,0 +1,150 @@
use libc::{sockaddr, sockaddr_storage, recvfrom, bind, sendto, socket, AF_NETLINK, SOCK_DGRAM, SOCK_CLOEXEC, getpid, c_void};
use nix::libc;
use std::os::unix::io::RawFd;
use std::{ mem, io};
#[repr(C)]
struct Nlmsghdr {
nlmsg_len: u32,
nlmsg_type: u16,
nlmsg_flags: u16,
nlmsg_seq: u32,
nlmsg_pid: u32,
}
fn create_netlink_socket() -> io::Result<RawFd> {
let sockfd = unsafe {
socket(AF_NETLINK, SOCK_DGRAM | SOCK_CLOEXEC, libc::NETLINK_KOBJECT_UEVENT)
};
if sockfd < 0 {
println!("Error: {}", io::Error::last_os_error());
return Err(io::Error::last_os_error());
}
Ok(sockfd)
}
fn bind_netlink_socket(sock: RawFd) -> io::Result<()> {
let pid = unsafe { getpid() };
let mut addr: libc::sockaddr_nl = unsafe { mem::zeroed() };
addr.nl_family = AF_NETLINK as u16;
addr.nl_pid = pid as u32;
addr.nl_groups = 0;
let ret = unsafe {
bind(sock, &addr as *const _ as *const sockaddr, mem::size_of::<libc::sockaddr_nl>() as u32)
};
if ret < 0 {
println!("Error: {}", io::Error::last_os_error());
return Err(io::Error::last_os_error());
}
Ok(())
}
fn send_uevent(sock: RawFd, message: &str) -> io::Result<()> {
let mut addr: libc::sockaddr_nl = unsafe { mem::zeroed() };
addr.nl_family = AF_NETLINK as u16;
addr.nl_pid = 0;
addr.nl_groups = 0;
let nlmsghdr = Nlmsghdr {
nlmsg_len: (mem::size_of::<Nlmsghdr>() + message.len()) as u32,
nlmsg_type: 0,
nlmsg_flags: 0,
nlmsg_seq: 0,
nlmsg_pid: 0,
};
let mut buffer = Vec::with_capacity(nlmsghdr.nlmsg_len as usize);
buffer.extend_from_slice(unsafe {
std::slice::from_raw_parts(
&nlmsghdr as *const Nlmsghdr as *const u8,
mem::size_of::<Nlmsghdr>(),
)
});
buffer.extend_from_slice(message.as_bytes());
let ret = unsafe {
sendto(
sock,
buffer.as_ptr() as *const c_void,
buffer.len(),
0,
&addr as *const _ as *const sockaddr,
mem::size_of::<libc::sockaddr_nl>() as u32,
)
};
if ret < 0 {
println!("Error: {}", io::Error::last_os_error());
return Err(io::Error::last_os_error());
}
Ok(())
}
fn receive_uevent(sock: RawFd) -> io::Result<String> {
// 检查套接字文件描述符是否有效
if sock < 0 {
println!("Invalid socket file descriptor: {}", sock);
return Err(io::Error::new(io::ErrorKind::InvalidInput, "Invalid socket file descriptor"));
}
let mut buf = [0u8; 1024];
// let mut addr: sockaddr_storage = unsafe { mem::zeroed() };
// let mut addr_len = mem::size_of::<sockaddr_storage>() as u32;
// 检查缓冲区指针和长度是否有效
if buf.is_empty() {
println!("Buffer is empty");
return Err(io::Error::new(io::ErrorKind::InvalidInput, "Buffer is empty"));
}
let len = unsafe {
recvfrom(
sock,
buf.as_mut_ptr() as *mut c_void,
buf.len(),
0,
core::ptr::null_mut(), // 不接收发送方地址
core::ptr::null_mut(), // 不接收发送方地址长度
)
};
println!("Received {} bytes", len);
println!("Received message: {:?}", &buf[..len as usize]);
if len < 0 {
println!("Error: {}", io::Error::last_os_error());
return Err(io::Error::last_os_error());
}
let nlmsghdr_size = mem::size_of::<Nlmsghdr>();
if (len as usize) < nlmsghdr_size {
println!("Received message is too short");
return Err(io::Error::new(io::ErrorKind::InvalidData, "Received message is too short"));
}
let nlmsghdr = unsafe { &*(buf.as_ptr() as *const Nlmsghdr) };
if nlmsghdr.nlmsg_len as isize > len {
println!("Received message is incomplete");
return Err(io::Error::new(io::ErrorKind::InvalidData, "Received message is incomplete"));
}
let message_data = &buf[nlmsghdr_size..nlmsghdr.nlmsg_len as usize];
Ok(String::from_utf8_lossy(message_data).to_string())
}
fn main() {
let socket = create_netlink_socket().expect("Failed to create Netlink socket");
println!("Netlink socket created successfully");
bind_netlink_socket(socket).expect("Failed to bind Netlink socket");
println!("Netlink socket created and bound successfully");
send_uevent(socket, "add@/devices/virtual/block/loop0").expect("Failed to send uevent message");
println!("Custom uevent message sent successfully");
let message = receive_uevent(socket).expect("Failed to receive uevent message");
println!("Received uevent message: {}", message);
}