Look up realm by pid.

Added RealmManager::realm_by_pid() and dbus method RealmFromCitadelPid
This commit is contained in:
Bruce Leidl 2019-08-26 18:14:37 -04:00
parent 1365054c45
commit 4ce5d439d8
2 changed files with 40 additions and 1 deletions

View File

@ -1,6 +1,6 @@
use std::collections::HashSet; use std::collections::HashSet;
use std::fs; use std::fs;
use std::path::Path; use std::path::{Path, PathBuf};
use std::sync::{Arc, RwLock, RwLockReadGuard, RwLockWriteGuard}; use std::sync::{Arc, RwLock, RwLockReadGuard, RwLockWriteGuard};
use crate::{Mountpoint, Activation,Result, Realms, RealmFS, Realm, util}; use crate::{Mountpoint, Activation,Result, Realms, RealmFS, Realm, util};
@ -330,6 +330,28 @@ impl RealmManager {
self.inner().realms.by_name(name) self.inner().realms.by_name(name)
} }
pub fn realm_by_pid(&self, pid: u32) -> Option<Realm> {
match Self::read_realm_name_by_pid(pid) {
Ok(name) => self.realm_by_name(name.as_str()),
Err(_) => None,
}
}
fn read_realm_name_by_pid(pid: u32) -> Result<String> {
let run = PathBuf::from(format!("/proc/{}/root/run", pid));
let realm_name = run.join("realm-name");
// ensure that /proc/pid/root/run and /proc/pid/root/run/realm-name
// are not symlinks
let run_meta = run.symlink_metadata()?;
let name_meta = realm_name.symlink_metadata()?;
if !run_meta.file_type().is_dir() || !name_meta.file_type().is_file() {
bail!("invalid path");
}
let bytes = fs::read(realm_name)?;
Ok(String::from_utf8(bytes)?)
}
pub fn rescan_realms(&self) -> Result<(Vec<Realm>,Vec<Realm>)> { pub fn rescan_realms(&self) -> Result<(Vec<Realm>,Vec<Realm>)> {
self.inner_mut().realms.rescan_realms() self.inner_mut().realms.rescan_realms()
} }

View File

@ -62,6 +62,10 @@ impl DbusServer {
.in_arg(("name", "s")) .in_arg(("name", "s"))
.in_arg(("args", "as"))) .in_arg(("args", "as")))
.add_m(f.method("RealmFromCitadelPid", (), Self::do_pid_to_realm)
.in_arg(("pid", "u"))
.out_arg(("realm", "s")))
// Signals // Signals
.add_s(f.signal("RealmStarted", ()) .add_s(f.signal("RealmStarted", ())
.arg(("realm", "s"))) .arg(("realm", "s")))
@ -168,6 +172,18 @@ impl DbusServer {
Ok(vec![m.msg.method_return()]) Ok(vec![m.msg.method_return()])
} }
fn do_pid_to_realm(m: &MethodInfo) -> MethodResult {
let pid = m.msg.read1::<u32>()?;
let manager = m.tree.get_data().manager();
let ret = m.msg.method_return();
let msg = match manager.realm_by_pid(pid) {
Some(realm) => ret.append(realm.name()),
None => ret.append(""),
};
Ok(vec![msg])
}
pub fn start(&self) -> Result<()> { pub fn start(&self) -> Result<()> {
let tree = self.build_tree(); let tree = self.build_tree();
self.connection.register_name(BUS_NAME, NameFlag::ReplaceExisting as u32)?; self.connection.register_name(BUS_NAME, NameFlag::ReplaceExisting as u32)?;
@ -219,6 +235,7 @@ impl DbusServer {
let member = dbus::Member::new(name).unwrap(); let member = dbus::Member::new(name).unwrap();
Message::signal(&path, &iface, &member) Message::signal(&path, &iface, &member)
} }
} }
/// Wraps a connection instance and only expose the send() method. /// Wraps a connection instance and only expose the send() method.