discover daemon state dir from cmdline when environ is unreadable
When the daemon runs as a different user (e.g. via systemd), the client cannot read /proc/<pid>/environ due to permissions. Fall back to parsing the cmdline for -D / --state-dir flags, which are world-readable. Fixes 'error: no logs for <service>' when client and daemon run as different users. v0.1.1
This commit is contained in:
parent
032f0ded69
commit
e4aea785ee
2 changed files with 32 additions and 7 deletions
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "rss"
|
||||
version = "0.1.0"
|
||||
version = "0.1.1"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
|
|
|
|||
37
src/state.rs
37
src/state.rs
|
|
@ -30,16 +30,41 @@ fn discover_daemon_state_dir() -> Option<PathBuf> {
|
|||
if !args.contains(&"daemon") {
|
||||
continue;
|
||||
}
|
||||
let environ = std::fs::read(format!("/proc/{}/environ", pid)).ok()?;
|
||||
for var in environ.split(|&b| b == 0) {
|
||||
if let Ok(var_str) = std::str::from_utf8(var) {
|
||||
if let Some(val) = var_str.strip_prefix("RSS_STATE_DIR=") {
|
||||
if !val.is_empty() {
|
||||
return Some(PathBuf::from(val));
|
||||
// Try RSS_STATE_DIR from environ first
|
||||
if let Ok(environ) = std::fs::read(format!("/proc/{}/environ", pid)) {
|
||||
for var in environ.split(|&b| b == 0) {
|
||||
if let Ok(var_str) = std::str::from_utf8(var) {
|
||||
if let Some(val) = var_str.strip_prefix("RSS_STATE_DIR=") {
|
||||
if !val.is_empty() {
|
||||
return Some(PathBuf::from(val));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Fallback: parse cmdline for -D / --state-dir (works across users)
|
||||
let mut i = 0;
|
||||
while i < args.len() {
|
||||
let next = if args[i] == "-D" || args[i] == "--state-dir" {
|
||||
args.get(i + 1).map(|s| s.to_string())
|
||||
} else if let Some(val) = args[i].strip_prefix("--state-dir=") {
|
||||
Some(val.to_string())
|
||||
} else if let Some(val) = args[i].strip_prefix("-D") {
|
||||
if val.is_empty() {
|
||||
args.get(i + 1).map(|s| s.to_string())
|
||||
} else {
|
||||
Some(val.to_string())
|
||||
}
|
||||
} else {
|
||||
None
|
||||
};
|
||||
if let Some(dir) = next {
|
||||
if !dir.is_empty() {
|
||||
return Some(PathBuf::from(dir));
|
||||
}
|
||||
}
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue