mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-19 17:26:31 +00:00
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:
2
user/apps/test-uevent/.cargo/config.toml
Normal file
2
user/apps/test-uevent/.cargo/config.toml
Normal file
@ -0,0 +1,2 @@
|
||||
[build]
|
||||
target = "x86_64-unknown-linux-musl"
|
3
user/apps/test-uevent/.gitignore
vendored
Normal file
3
user/apps/test-uevent/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
/target
|
||||
Cargo.lock
|
||||
/install/
|
12
user/apps/test-uevent/Cargo.toml
Normal file
12
user/apps/test-uevent/Cargo.toml
Normal 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"
|
56
user/apps/test-uevent/Makefile
Normal file
56
user/apps/test-uevent/Makefile
Normal 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
|
14
user/apps/test-uevent/README.md
Normal file
14
user/apps/test-uevent/README.md
Normal 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即可安装
|
150
user/apps/test-uevent/src/main.rs
Normal file
150
user/apps/test-uevent/src/main.rs
Normal 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);
|
||||
}
|
Reference in New Issue
Block a user