Update init logging implementation

Use less std::fs
This commit is contained in:
topjohnwu 2024-02-26 17:49:11 -08:00
parent 8f7d2e38f7
commit af6965eefa

View File

@ -1,58 +1,54 @@
use std::fs;
use std::fs::File; use std::fs::File;
use std::io::{IoSlice, Write}; use std::io::{IoSlice, Write};
use std::sync::OnceLock;
use base::libc::{ use base::libc::{
close, makedev, mknod, open, syscall, unlink, SYS_dup3, O_CLOEXEC, O_RDWR, STDERR_FILENO, makedev, mknod, syscall, SYS_dup3, O_CLOEXEC, O_RDWR, O_WRONLY, STDERR_FILENO, STDIN_FILENO,
STDIN_FILENO, STDOUT_FILENO, S_IFCHR, STDOUT_FILENO, S_IFCHR,
}; };
use base::{cstr, exit_on_error, raw_cstr, LogLevel, Logger, Utf8CStr, LOGGER}; use base::{cstr, exit_on_error, open_fd, raw_cstr, FsPath, LogLevel, Logger, Utf8CStr, LOGGER};
static KMSG: OnceLock<File> = OnceLock::new(); // SAFETY: magiskinit is single threaded
static mut KMSG: Option<File> = None;
pub fn setup_klog() { pub fn setup_klog() {
// Shut down first 3 fds
unsafe { unsafe {
let mut fd = open(raw_cstr!("/dev/null"), O_RDWR | O_CLOEXEC); // Shut down first 3 fds
if fd < 0 { let mut fd = open_fd!(cstr!("/dev/null"), O_RDWR | O_CLOEXEC);
if fd.is_err() {
mknod(raw_cstr!("/null"), S_IFCHR | 0o666, makedev(1, 3)); mknod(raw_cstr!("/null"), S_IFCHR | 0o666, makedev(1, 3));
fd = open(raw_cstr!("/null"), O_RDWR | O_CLOEXEC); fd = open_fd!(cstr!("/null"), O_RDWR | O_CLOEXEC);
fs::remove_file("/null").ok(); FsPath::from(cstr!("/null")).remove().ok();
}
if let Ok(ref fd) = fd {
syscall(SYS_dup3, fd, STDIN_FILENO, O_CLOEXEC);
syscall(SYS_dup3, fd, STDOUT_FILENO, O_CLOEXEC);
syscall(SYS_dup3, fd, STDERR_FILENO, O_CLOEXEC);
} }
syscall(SYS_dup3, fd, STDIN_FILENO, O_CLOEXEC); // Then open kmsg fd
syscall(SYS_dup3, fd, STDOUT_FILENO, O_CLOEXEC); let mut fd = open_fd!(cstr!("/dev/kmsg"), O_WRONLY | O_CLOEXEC);
syscall(SYS_dup3, fd, STDERR_FILENO, O_CLOEXEC); if fd.is_err() {
if fd > STDERR_FILENO {
close(fd);
}
}
if let Ok(kmsg) = File::options().write(true).open("/dev/kmsg") {
KMSG.set(kmsg).ok();
} else {
unsafe {
mknod(raw_cstr!("/kmsg"), S_IFCHR | 0o666, makedev(1, 11)); mknod(raw_cstr!("/kmsg"), S_IFCHR | 0o666, makedev(1, 11));
KMSG.set(File::options().write(true).open("/kmsg").unwrap()) fd = open_fd!(cstr!("/kmsg"), O_WRONLY | O_CLOEXEC);
.ok(); FsPath::from(cstr!("/kmsg")).remove().ok();
unlink(raw_cstr!("/kmsg"));
} }
KMSG = fd.map(|fd| fd.into()).ok();
} }
// Disable kmsg rate limiting // Disable kmsg rate limiting
if let Ok(mut rate) = File::options() if let Ok(rate) = open_fd!(
.write(true) cstr!("/proc/sys/kernel/printk_devkmsg"),
.open("/proc/sys/kernel/printk_devkmsg") O_WRONLY | O_CLOEXEC
{ ) {
let mut rate = File::from(rate);
writeln!(rate, "on").ok(); writeln!(rate, "on").ok();
} }
fn kmsg_log_write(_: LogLevel, msg: &Utf8CStr) { fn kmsg_log_write(_: LogLevel, msg: &Utf8CStr) {
if let Some(kmsg) = KMSG.get().as_mut() { if let Some(kmsg) = unsafe { &mut KMSG } {
let io1 = IoSlice::new("magiskinit: ".as_bytes()); let io1 = IoSlice::new("magiskinit: ".as_bytes());
let io2 = IoSlice::new(msg.as_bytes()); let io2 = IoSlice::new(msg.as_bytes());
kmsg.write_vectored(&[io1, io2]).ok(); let _ = kmsg.write_vectored(&[io1, io2]).ok();
} }
} }