Add 'logd/' from commit 'db36d01782a6b9cc7ec995f884f8c1259d79903e'

git-subtree-dir: logd
git-subtree-mainline: 38c917a56b
git-subtree-split: db36d01782
This commit is contained in:
bjorn3
2025-02-18 21:31:45 +01:00
6 changed files with 302 additions and 0 deletions
+1
View File
@@ -0,0 +1 @@
target
+65
View File
@@ -0,0 +1,65 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "bitflags"
version = "2.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
[[package]]
name = "libc"
version = "0.2.159"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5"
[[package]]
name = "libredox"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d"
dependencies = [
"bitflags",
"libc",
"redox_syscall",
]
[[package]]
name = "logd"
version = "0.1.0"
dependencies = [
"libredox",
"redox-daemon",
"redox-scheme",
"redox_syscall",
]
[[package]]
name = "redox-daemon"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fbdeffdb03cf2961b211a2023e683d71f2c225ea93404da5dc34b0dc94f0341"
dependencies = [
"libc",
"libredox",
]
[[package]]
name = "redox-scheme"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "98d040cfa6370d9c6b1a5987247272f19ea4722f1064e66ad2e077c152b82ea3"
dependencies = [
"libredox",
"redox_syscall",
]
[[package]]
name = "redox_syscall"
version = "0.5.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f"
dependencies = [
"bitflags",
]
+11
View File
@@ -0,0 +1,11 @@
[package]
name = "logd"
version = "0.1.0"
authors = ["Jeremy Soller <jackpot51@gmail.com>"]
edition = "2021"
[dependencies]
redox_syscall = "0.5"
redox-daemon = "0.1.2"
libredox = "0.1.3"
redox-scheme = "0.2.1"
+19
View File
@@ -0,0 +1,19 @@
# logd
Log daemon for collecting all log output.
## How To Contribute
To learn how to contribute to this system component you need to read the following document:
- [CONTRIBUTING.md](https://gitlab.redox-os.org/redox-os/redox/-/blob/master/CONTRIBUTING.md)
## Development
To learn how to do development with this system component inside the Redox build system you need to read the [Build System](https://doc.redox-os.org/book/build-system-reference.html) and [Coding and Building](https://doc.redox-os.org/book/coding-and-building.html) pages.
### How To Build
To build this system component you need to download the Redox build system, you can learn how to do it on the [Building Redox](https://doc.redox-os.org/book/podman-build.html) page.
This is necessary because they only work with cross-compilation to a Redox virtual machine, but you can do some testing from Linux.
+50
View File
@@ -0,0 +1,50 @@
use redox_scheme::{RequestKind, SignalBehavior, Socket, V2};
use std::env;
use std::fs::OpenOptions;
use std::process;
use crate::scheme::LogScheme;
mod scheme;
fn daemon(daemon: redox_daemon::Daemon) -> ! {
let mut files = Vec::new();
for arg in env::args().skip(1) {
eprintln!("logd: opening {:?}", arg);
match OpenOptions::new().write(true).open(&arg) {
Ok(file) => files.push(file),
Err(err) => eprintln!("logd: failed to open {:?}: {:?}", arg, err),
}
}
let socket = Socket::<V2>::create("log").expect("logd: failed to create log scheme");
libredox::call::setrens(0, 0).expect("logd: failed to enter null namespace");
eprintln!("logd: ready for logging on log:");
daemon.ready().expect("logd: failed to notify parent");
let mut scheme = LogScheme::new(files);
while let Some(request) = socket
.next_request(SignalBehavior::Restart)
.expect("logd: failed to read events from log scheme")
{
scheme.current_pid = request.context_id();
let RequestKind::Call(request) = request.kind() else {
continue;
};
let response = request.handle_scheme_mut(&mut scheme);
socket
.write_responses(&[response], SignalBehavior::Restart)
.expect("logd: failed to write responses to log scheme");
}
process::exit(0);
}
fn main() {
redox_daemon::Daemon::new(daemon).expect("logd: failed to daemonize");
}
+156
View File
@@ -0,0 +1,156 @@
use std::collections::BTreeMap;
use std::fs::File;
use std::io::Write;
use redox_scheme::SchemeMut;
use syscall::error::*;
pub struct LogHandle {
context: Box<str>,
bufs: BTreeMap<usize, Vec<u8>>,
}
pub struct LogScheme {
next_id: usize,
files: Vec<File>,
handles: BTreeMap<usize, LogHandle>,
pub current_pid: usize,
}
impl LogScheme {
pub fn new(files: Vec<File>) -> Self {
LogScheme {
next_id: 0,
files,
handles: BTreeMap::new(),
current_pid: 0,
}
}
}
impl SchemeMut for LogScheme {
fn open(&mut self, path: &str, _flags: usize, _uid: u32, _gid: u32) -> Result<usize> {
let id = self.next_id;
self.next_id += 1;
self.handles.insert(
id,
LogHandle {
context: path.to_string().into_boxed_str(),
bufs: BTreeMap::new(),
},
);
Ok(id)
}
fn dup(&mut self, old_id: usize, buf: &[u8]) -> Result<usize> {
if !buf.is_empty() {
return Err(Error::new(EINVAL));
}
let context = {
let handle = self.handles.get(&old_id).ok_or(Error::new(EBADF))?;
handle.context.clone()
};
let id = self.next_id;
self.next_id += 1;
self.handles.insert(
id,
LogHandle {
context,
bufs: BTreeMap::new(),
},
);
Ok(id)
}
fn read(&mut self, id: usize, _buf: &mut [u8], _offset: u64, _flags: u32) -> Result<usize> {
let _handle = self.handles.get(&id).ok_or(Error::new(EBADF))?;
// TODO
Ok(0)
}
fn write(&mut self, id: usize, buf: &[u8], _offset: u64, _flags: u32) -> Result<usize> {
let handle = self.handles.get_mut(&id).ok_or(Error::new(EBADF))?;
let handle_buf = handle
.bufs
.entry(self.current_pid)
.or_insert_with(|| Vec::new());
let mut i = 0;
while i < buf.len() {
let b = buf[i];
if handle_buf.is_empty() && !handle.context.is_empty() {
handle_buf.extend_from_slice(handle.context.as_bytes());
handle_buf.extend_from_slice(b": ");
}
handle_buf.push(b);
if b == b'\n' {
for file in self.files.iter_mut() {
let _ = file.write(&handle_buf);
let _ = file.flush();
}
handle_buf.clear();
}
i += 1;
}
Ok(i)
}
fn fcntl(&mut self, id: usize, _cmd: usize, _arg: usize) -> Result<usize> {
let _handle = self.handles.get(&id).ok_or(Error::new(EBADF))?;
Ok(0)
}
fn fpath(&mut self, id: usize, buf: &mut [u8]) -> Result<usize> {
let handle = self.handles.get(&id).ok_or(Error::new(EBADF))?;
let scheme_path = b"log:";
let mut i = 0;
while i < buf.len() && i < scheme_path.len() {
buf[i] = scheme_path[i];
i += 1;
}
let mut j = 0;
let context_bytes = handle.context.as_bytes();
while i < buf.len() && j < context_bytes.len() {
buf[i] = context_bytes[j];
i += 1;
j += 1;
}
Ok(i)
}
fn fsync(&mut self, id: usize) -> Result<usize> {
let _handle = self.handles.get(&id).ok_or(Error::new(EBADF))?;
//TODO: flush remaining data?
Ok(0)
}
fn close(&mut self, id: usize) -> Result<usize> {
self.handles.remove(&id).ok_or(Error::new(EBADF))?;
//TODO: flush remaining data?
Ok(0)
}
}