fix: udev-shim panic, sessiond duplicate, scheme Bad-fd handling
- udev-shim: replace .expect() with graceful errors (no more panic on Broken pipe) - P4-initfs: remove duplicate sessiond (conflicted with config) - accessibility/ime/keymapd: break instead of exit(1) on EBADF - P6 driver patches rebased - Docs: archive old reports, add implementation master plan
This commit is contained in:
@@ -40,28 +40,50 @@ fn init_logging(level: LevelFilter) {
|
||||
log::set_max_level(level);
|
||||
}
|
||||
|
||||
unsafe fn get_init_notify_fd() -> RawFd {
|
||||
let fd: RawFd = env::var("INIT_NOTIFY")
|
||||
.expect("udev-shim: INIT_NOTIFY not set")
|
||||
.parse()
|
||||
.expect("udev-shim: INIT_NOTIFY is not a valid fd");
|
||||
libc::fcntl(fd, libc::F_SETFD, libc::FD_CLOEXEC);
|
||||
fd
|
||||
unsafe fn get_init_notify_fd() -> Option<RawFd> {
|
||||
let fd_str = match env::var("INIT_NOTIFY") {
|
||||
Ok(v) => v,
|
||||
Err(_) => {
|
||||
warn!("udev-shim: INIT_NOTIFY not set; init notification skipped");
|
||||
return None;
|
||||
}
|
||||
};
|
||||
match fd_str.parse::<RawFd>() {
|
||||
Ok(fd) => {
|
||||
libc::fcntl(fd, libc::F_SETFD, libc::FD_CLOEXEC);
|
||||
Some(fd)
|
||||
}
|
||||
Err(_) => {
|
||||
warn!("udev-shim: INIT_NOTIFY is not a valid fd: {fd_str}");
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn notify_scheme_ready(notify_fd: RawFd, socket: &Socket, scheme: &mut UdevScheme) {
|
||||
let cap_id = scheme.scheme_root().expect("udev-shim: scheme_root failed");
|
||||
let cap_fd = socket
|
||||
.create_this_scheme_fd(0, cap_id, 0, 0)
|
||||
.expect("udev-shim: create_this_scheme_fd failed");
|
||||
let cap_id = match scheme.scheme_root() {
|
||||
Ok(id) => id,
|
||||
Err(e) => {
|
||||
error!("udev-shim: scheme_root failed: {e:?}");
|
||||
return;
|
||||
}
|
||||
};
|
||||
let cap_fd = match socket.create_this_scheme_fd(0, cap_id, 0, 0) {
|
||||
Ok(fd) => fd,
|
||||
Err(e) => {
|
||||
error!("udev-shim: create_this_scheme_fd failed: {e:?}");
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
syscall::call_wo(
|
||||
if let Err(e) = syscall::call_wo(
|
||||
notify_fd as usize,
|
||||
&libredox::Fd::new(cap_fd).into_raw().to_ne_bytes(),
|
||||
syscall::CallFlags::FD,
|
||||
&[],
|
||||
)
|
||||
.expect("udev-shim: failed to notify init that scheme is ready");
|
||||
) {
|
||||
warn!("udev-shim: init notification failed: {e:?}");
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
@@ -85,17 +107,25 @@ fn main() {
|
||||
Err(err) => warn!("udev-shim: failed to write default rules: {err}"),
|
||||
}
|
||||
|
||||
let notify_fd = unsafe { get_init_notify_fd() };
|
||||
let socket = Socket::create().expect("udev-shim: failed to create udev scheme");
|
||||
let socket = match Socket::create() {
|
||||
Ok(s) => s,
|
||||
Err(e) => {
|
||||
error!("udev-shim: failed to create udev scheme: {e:?}");
|
||||
std::process::exit(1);
|
||||
}
|
||||
};
|
||||
let mut state = SchemeState::new();
|
||||
|
||||
notify_scheme_ready(notify_fd, &socket, &mut scheme);
|
||||
if let Some(notify_fd) = unsafe { get_init_notify_fd() } {
|
||||
notify_scheme_ready(notify_fd, &socket, &mut scheme);
|
||||
}
|
||||
|
||||
libredox::call::setrens(0, 0).expect("udev-shim: failed to enter null namespace");
|
||||
if let Err(e) = libredox::call::setrens(0, 0) {
|
||||
error!("udev-shim: failed to enter null namespace: {e:?}");
|
||||
}
|
||||
|
||||
info!("udev-shim: registered scheme:udev");
|
||||
|
||||
// Hotplug polling: periodically check driver-manager for device changes
|
||||
let scheme = Arc::new(Mutex::new(scheme));
|
||||
let scheme_clone = Arc::clone(&scheme);
|
||||
thread::spawn(move || {
|
||||
@@ -111,28 +141,37 @@ fn main() {
|
||||
}
|
||||
});
|
||||
|
||||
while let Some(request) = socket
|
||||
.next_request(SignalBehavior::Restart)
|
||||
.expect("udev-shim: failed to read scheme request")
|
||||
{
|
||||
match request.kind() {
|
||||
redox_scheme::RequestKind::Call(request) => {
|
||||
let response = {
|
||||
let mut guard = match scheme.lock() {
|
||||
Ok(guard) => guard,
|
||||
Err(poisoned) => {
|
||||
error!("udev-shim: recovering from poisoned scheme lock");
|
||||
poisoned.into_inner()
|
||||
}
|
||||
};
|
||||
loop {
|
||||
match socket.next_request(SignalBehavior::Restart) {
|
||||
Ok(Some(request)) => {
|
||||
match request.kind() {
|
||||
redox_scheme::RequestKind::Call(request) => {
|
||||
let response = {
|
||||
let mut guard = match scheme.lock() {
|
||||
Ok(guard) => guard,
|
||||
Err(poisoned) => {
|
||||
error!("udev-shim: recovering from poisoned scheme lock");
|
||||
poisoned.into_inner()
|
||||
}
|
||||
};
|
||||
|
||||
request.handle_sync(&mut *guard, &mut state)
|
||||
};
|
||||
socket
|
||||
.write_response(response, SignalBehavior::Restart)
|
||||
.expect("udev-shim: failed to write response");
|
||||
request.handle_sync(&mut *guard, &mut state)
|
||||
};
|
||||
if let Err(e) = socket.write_response(response, SignalBehavior::Restart) {
|
||||
error!("udev-shim: failed to write response: {e:?}");
|
||||
}
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
Ok(None) => {
|
||||
info!("udev-shim: scheme unmounted, exiting");
|
||||
break;
|
||||
}
|
||||
Err(e) => {
|
||||
error!("udev-shim: failed to read scheme request: {e:?}");
|
||||
break;
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user