Separate context and process IDs.
This commit is contained in:
@@ -114,7 +114,7 @@ impl super::Context {
|
||||
pub fn set_userspace_io_allowed(&mut self, allowed: bool) {
|
||||
self.arch.userspace_io_allowed = allowed;
|
||||
|
||||
if self.id == super::context_id() {
|
||||
if self.cid == super::current_cid() {
|
||||
unsafe {
|
||||
crate::gdt::set_userspace_io_allowed(crate::gdt::pcr(), allowed);
|
||||
}
|
||||
|
||||
+10
-7
@@ -131,8 +131,10 @@ impl Eq for WaitpidKey {}
|
||||
/// A context, which identifies either a process or a thread
|
||||
#[derive(Debug)]
|
||||
pub struct Context {
|
||||
/// The ID of this context
|
||||
pub id: ContextId,
|
||||
/// The internal context ID of this context
|
||||
pub cid: ContextId,
|
||||
/// The process ID of this context
|
||||
pub pid: ContextId,
|
||||
/// The group ID of this context
|
||||
pub pgid: ContextId,
|
||||
/// The ID of the parent context
|
||||
@@ -231,10 +233,11 @@ pub struct SignalState {
|
||||
}
|
||||
|
||||
impl Context {
|
||||
pub fn new(id: ContextId) -> Result<Context> {
|
||||
pub fn new(cid: ContextId, pid: ContextId) -> Result<Context> {
|
||||
let this = Context {
|
||||
id,
|
||||
pgid: id,
|
||||
cid,
|
||||
pid,
|
||||
pgid: pid,
|
||||
ppid: ContextId::from(0),
|
||||
session_id: ContextId::from(0),
|
||||
ruid: 0,
|
||||
@@ -409,7 +412,7 @@ impl Context {
|
||||
return addr_space;
|
||||
};
|
||||
|
||||
if self.id == super::context_id() {
|
||||
if self.cid == super::current_cid() {
|
||||
// TODO: Share more code with context::arch::switch_to.
|
||||
let this_percpu = PercpuBlock::current();
|
||||
|
||||
@@ -449,7 +452,7 @@ impl Context {
|
||||
}
|
||||
pub fn caller_ctx(&self) -> CallerCtx {
|
||||
CallerCtx {
|
||||
pid: self.id.into(),
|
||||
pid: self.pid.into(),
|
||||
uid: self.euid,
|
||||
gid: self.egid,
|
||||
}
|
||||
|
||||
+3
-2
@@ -50,7 +50,7 @@ impl ContextList {
|
||||
|
||||
/// Get the current context.
|
||||
pub fn current(&self) -> Option<&Arc<RwSpinlock<Context>>> {
|
||||
self.map.get(&super::context_id())
|
||||
self.map.get(&super::current_cid())
|
||||
}
|
||||
|
||||
pub fn iter(
|
||||
@@ -72,7 +72,8 @@ impl ContextList {
|
||||
) -> Result<&Arc<RwSpinlock<Context>>> {
|
||||
assert!(self
|
||||
.map
|
||||
.insert(id, Arc::new(RwSpinlock::new(Context::new(id)?)))
|
||||
// TODO
|
||||
.insert(id, Arc::new(RwSpinlock::new(Context::new(id, id)?)))
|
||||
.is_none());
|
||||
|
||||
Ok(self
|
||||
|
||||
+4
-4
@@ -85,8 +85,8 @@ pub fn init() {
|
||||
|
||||
unsafe {
|
||||
let percpu = PercpuBlock::current();
|
||||
percpu.switch_internals.set_context_id(context.id);
|
||||
percpu.switch_internals.set_idle_id(context.id);
|
||||
percpu.switch_internals.set_current_cid(context.cid);
|
||||
percpu.switch_internals.set_idle_id(context.cid);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,8 +100,8 @@ pub fn contexts_mut() -> RwLockWriteGuard<'static, ContextList> {
|
||||
CONTEXTS.write()
|
||||
}
|
||||
|
||||
pub fn context_id() -> ContextId {
|
||||
PercpuBlock::current().switch_internals.context_id()
|
||||
pub fn current_cid() -> ContextId {
|
||||
PercpuBlock::current().switch_internals.current_cid()
|
||||
}
|
||||
|
||||
pub fn current() -> Result<Arc<RwSpinlock<Context>>> {
|
||||
|
||||
+10
-10
@@ -133,11 +133,11 @@ pub fn switch() -> SwitchResult {
|
||||
// Locate next context
|
||||
for (pid, next_context_lock) in contexts
|
||||
// Include all contexts with IDs greater than the current...
|
||||
.range((Bound::Excluded(prev_context_guard.id), Bound::Unbounded))
|
||||
.range((Bound::Excluded(prev_context_guard.cid), Bound::Unbounded))
|
||||
.chain(
|
||||
contexts
|
||||
// ... and all contexts with IDs less than the current...
|
||||
.range((Bound::Unbounded, Bound::Excluded(prev_context_guard.id))),
|
||||
.range((Bound::Unbounded, Bound::Excluded(prev_context_guard.cid))),
|
||||
)
|
||||
.chain(
|
||||
contexts
|
||||
@@ -184,7 +184,7 @@ pub fn switch() -> SwitchResult {
|
||||
next_context.switch_time = switch_time;
|
||||
|
||||
let percpu = PercpuBlock::current();
|
||||
percpu.switch_internals.context_id.set(next_context.id);
|
||||
percpu.switch_internals.current_cid.set(next_context.cid);
|
||||
|
||||
// FIXME set th switch result in arch::switch_to instead
|
||||
let prev_context =
|
||||
@@ -201,7 +201,7 @@ pub fn switch() -> SwitchResult {
|
||||
}));
|
||||
|
||||
let (ptrace_session, ptrace_flags) = if let Some((session, bp)) = ptrace::sessions()
|
||||
.get(&next_context.id)
|
||||
.get(&next_context.pid)
|
||||
.map(|s| (Arc::downgrade(s), s.data.lock().breakpoint))
|
||||
{
|
||||
(Some(session), bp.map_or(PtraceFlags::empty(), |f| f.flags))
|
||||
@@ -251,8 +251,8 @@ pub struct ContextSwitchPercpu {
|
||||
switch_result: Cell<Option<SwitchResultInner>>,
|
||||
pit_ticks: Cell<usize>,
|
||||
|
||||
/// Unique ID of the currently running context.
|
||||
context_id: Cell<ContextId>,
|
||||
/// Unique context ID of the currently running context.
|
||||
current_cid: Cell<ContextId>,
|
||||
|
||||
// The ID of the idle process
|
||||
idle_id: Cell<ContextId>,
|
||||
@@ -260,11 +260,11 @@ pub struct ContextSwitchPercpu {
|
||||
pub(crate) being_sigkilled: Cell<bool>,
|
||||
}
|
||||
impl ContextSwitchPercpu {
|
||||
pub fn context_id(&self) -> ContextId {
|
||||
self.context_id.get()
|
||||
pub fn current_cid(&self) -> ContextId {
|
||||
self.current_cid.get()
|
||||
}
|
||||
pub unsafe fn set_context_id(&self, new: ContextId) {
|
||||
self.context_id.set(new)
|
||||
pub unsafe fn set_current_cid(&self, new: ContextId) {
|
||||
self.current_cid.set(new)
|
||||
}
|
||||
pub fn idle_id(&self) -> ContextId {
|
||||
self.idle_id.get()
|
||||
|
||||
+1
-1
@@ -263,7 +263,7 @@ pub fn ksignal(signal: usize) {
|
||||
"SIGNAL {}, CPU {}, PID {:?}",
|
||||
signal,
|
||||
cpu_id(),
|
||||
context::context_id()
|
||||
context::current_cid()
|
||||
);
|
||||
{
|
||||
let contexts = context::contexts();
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@ fn rust_begin_unwind(info: &PanicInfo) -> ! {
|
||||
interrupt::stack_trace();
|
||||
}
|
||||
|
||||
println!("CPU {}, PID {:?}", cpu_id(), context::context_id());
|
||||
println!("CPU {}, CID {:?}", cpu_id(), context::current_cid());
|
||||
|
||||
// This could deadlock, but at this point we are going to halt anyways
|
||||
{
|
||||
|
||||
+2
-2
@@ -175,7 +175,7 @@ pub fn send_event(event: PtraceEvent) -> Option<()> {
|
||||
let contexts = context::contexts();
|
||||
let context = contexts.current()?;
|
||||
let context = context.read();
|
||||
context.id
|
||||
context.pid
|
||||
};
|
||||
|
||||
let sessions = sessions();
|
||||
@@ -295,7 +295,7 @@ pub fn next_breakpoint() -> Option<PtraceFlags> {
|
||||
let context = context.read();
|
||||
|
||||
let sessions = sessions();
|
||||
let session = sessions.get(&context.id)?;
|
||||
let session = sessions.get(&context.pid)?;
|
||||
let data = session.data.lock();
|
||||
let breakpoint = data.breakpoint?;
|
||||
|
||||
|
||||
+14
-11
@@ -75,7 +75,7 @@ fn try_stop_context<F, T>(pid: ContextId, callback: F) -> Result<T>
|
||||
where
|
||||
F: FnOnce(&mut Context) -> Result<T>,
|
||||
{
|
||||
if pid == context::context_id() {
|
||||
if pid == context::current_cid() {
|
||||
return Err(Error::new(EBADF));
|
||||
}
|
||||
// Stop process
|
||||
@@ -215,6 +215,7 @@ impl OperationData {
|
||||
#[derive(Clone)]
|
||||
struct Info {
|
||||
pid: ContextId,
|
||||
cid: ContextId,
|
||||
flags: usize,
|
||||
|
||||
// Important: Operation must never change. Search for:
|
||||
@@ -344,7 +345,7 @@ impl<const FULL: bool> ProcScheme<FULL> {
|
||||
let current = current.read();
|
||||
|
||||
// Are we the process?
|
||||
if target.id != current.id {
|
||||
if target.pid != current.pid {
|
||||
// Do we own the process?
|
||||
if uid != target.euid && gid != target.egid {
|
||||
return Err(Error::new(EPERM));
|
||||
@@ -354,13 +355,13 @@ impl<const FULL: bool> ProcScheme<FULL> {
|
||||
// bypass this check.
|
||||
match contexts
|
||||
.ancestors(target.ppid)
|
||||
.find(|&(id, _context)| id == current.id)
|
||||
.find(|&(id, _context)| pid == current.pid)
|
||||
{
|
||||
Some((id, context)) => {
|
||||
// Paranoid sanity check, as ptrace security holes
|
||||
// wouldn't be fun
|
||||
assert_eq!(id, current.id);
|
||||
assert_eq!(id, context.read().id);
|
||||
assert_eq!(id, current.pid);
|
||||
assert_eq!(id, context.read().pid);
|
||||
}
|
||||
None => return Err(Error::new(EPERM)),
|
||||
}
|
||||
@@ -400,6 +401,7 @@ impl<const FULL: bool> ProcScheme<FULL> {
|
||||
flags,
|
||||
pid,
|
||||
operation: operation.clone(),
|
||||
cid: pid,
|
||||
},
|
||||
data,
|
||||
},
|
||||
@@ -471,7 +473,7 @@ impl<const FULL: bool> ProcScheme<FULL> {
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
fn read_env_regs(&self, info: &Info) -> Result<EnvRegisters> {
|
||||
// TODO: Avoid rdmsr if fsgsbase is not enabled, if this is worth optimizing for.
|
||||
let (fsbase, gsbase) = if info.pid == context::context_id() {
|
||||
let (fsbase, gsbase) = if info.cid == context::current_cid() {
|
||||
unsafe {
|
||||
(
|
||||
x86::msr::rdmsr(x86::msr::IA32_FS_BASE),
|
||||
@@ -551,7 +553,7 @@ impl<const FULL: bool> ProcScheme<FULL> {
|
||||
return Err(Error::new(EINVAL));
|
||||
}
|
||||
|
||||
if info.pid == context::context_id() {
|
||||
if info.pid == context::current_cid() {
|
||||
unsafe {
|
||||
x86::msr::wrmsr(x86::msr::IA32_FS_BASE, regs.fsbase as u64);
|
||||
// We have to write to KERNEL_GSBASE, because when the kernel returns to
|
||||
@@ -587,7 +589,7 @@ impl<const FULL: bool> KernelScheme for ProcScheme<FULL> {
|
||||
let pid_str = parts.next().ok_or(Error::new(ENOENT))?;
|
||||
|
||||
let pid = if pid_str == "current" {
|
||||
context::context_id()
|
||||
context::current_cid()
|
||||
} else if pid_str == "new" {
|
||||
inherit_context()?
|
||||
} else if !FULL {
|
||||
@@ -630,7 +632,7 @@ impl<const FULL: bool> KernelScheme for ProcScheme<FULL> {
|
||||
let mut handle = HANDLES.write().remove(&id).ok_or(Error::new(EBADF))?;
|
||||
handle.continue_ignored_children();
|
||||
|
||||
let stop_context = if handle.info.pid == context::context_id() {
|
||||
let stop_context = if handle.info.cid == context::current_cid() {
|
||||
with_context_mut
|
||||
} else {
|
||||
try_stop_context
|
||||
@@ -1439,6 +1441,7 @@ impl<const FULL: bool> KernelScheme for ProcScheme<FULL> {
|
||||
info: Info {
|
||||
flags: 0,
|
||||
pid: info.pid,
|
||||
cid: info.cid,
|
||||
operation,
|
||||
},
|
||||
data,
|
||||
@@ -1578,12 +1581,12 @@ fn inherit_context() -> Result<ContextId> {
|
||||
new_context.rgid = current_context.rgid;
|
||||
new_context.ens = current_context.ens;
|
||||
new_context.rns = current_context.rns;
|
||||
new_context.ppid = current_context.id;
|
||||
new_context.ppid = current_context.pid;
|
||||
new_context.pgid = current_context.pgid;
|
||||
new_context.session_id = current_context.session_id;
|
||||
new_context.umask = current_context.umask;
|
||||
|
||||
new_context.id
|
||||
new_context.cid
|
||||
};
|
||||
|
||||
if ptrace::send_event(crate::syscall::ptrace_event!(
|
||||
|
||||
@@ -106,7 +106,7 @@ pub fn resource() -> Result<Vec<u8>> {
|
||||
|
||||
string.push_str(&format!(
|
||||
"{:<6}{:<6}{:<6}{:<6}{:<6}{:<6}{:<6}{:<6}{:<6}{:<6}{:<6}{:<6}{:<11}{:<12}{:<8}{}\n",
|
||||
context.id.get(),
|
||||
context.pid.get(),
|
||||
context.pgid.get(),
|
||||
context.ppid.get(),
|
||||
context.session_id.get(),
|
||||
|
||||
+2
-2
@@ -855,7 +855,7 @@ impl UserInner {
|
||||
0,
|
||||
uid_gid_hack_merge(current_uid_gid()?),
|
||||
],
|
||||
caller: context::context_id().get() as u64,
|
||||
caller: context::current()?.read().pid.get() as u64,
|
||||
});
|
||||
event::trigger(self.root_id, self.handle_id, EVENT_READ);
|
||||
|
||||
@@ -1104,7 +1104,7 @@ impl UserInner {
|
||||
}
|
||||
}
|
||||
let desc = desc_res?;
|
||||
(context.id, desc.description)
|
||||
(context.pid, desc.description)
|
||||
};
|
||||
|
||||
let response = self.call_extended_inner(
|
||||
|
||||
@@ -38,7 +38,7 @@ impl WaitCondition {
|
||||
|
||||
// Wait until notified. Unlocks guard when blocking is ready. Returns false if resumed by a signal or the notify_signal function
|
||||
pub fn wait<T>(&self, guard: MutexGuard<T>, reason: &'static str) -> bool {
|
||||
let id;
|
||||
let cid;
|
||||
{
|
||||
let context_lock = {
|
||||
let contexts = context::contexts();
|
||||
@@ -53,7 +53,7 @@ impl WaitCondition {
|
||||
{
|
||||
return false;
|
||||
}
|
||||
id = context.id;
|
||||
cid = context.cid;
|
||||
context.block(reason);
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@ impl WaitCondition {
|
||||
while i < contexts.len() {
|
||||
let remove = {
|
||||
let context = contexts[i].read();
|
||||
context.id == id
|
||||
context.cid == cid
|
||||
};
|
||||
|
||||
if remove {
|
||||
|
||||
+2
-2
@@ -56,7 +56,7 @@ const PATH_MAX: usize = PAGE_SIZE;
|
||||
pub fn open(raw_path: UserSliceRo, flags: usize) -> Result<FileHandle> {
|
||||
let (pid, uid, gid, scheme_ns, umask) = match context::current()?.read() {
|
||||
ref context => (
|
||||
context.id.into(),
|
||||
context.pid.into(),
|
||||
context.euid,
|
||||
context.egid,
|
||||
context.ens,
|
||||
@@ -361,7 +361,7 @@ pub fn frename(fd: FileHandle, raw_path: UserSliceRo) -> Result<()> {
|
||||
CallerCtx {
|
||||
uid: context.euid,
|
||||
gid: context.egid,
|
||||
pid: context.id.get(),
|
||||
pid: context.pid.get(),
|
||||
},
|
||||
context.ens,
|
||||
),
|
||||
|
||||
@@ -48,7 +48,7 @@ pub fn exit(status: usize) -> ! {
|
||||
.and_then(|a| Arc::try_unwrap(a).ok());
|
||||
drop(context.syscall_head.take());
|
||||
drop(context.syscall_tail.take());
|
||||
context.id
|
||||
context.pid
|
||||
};
|
||||
|
||||
// Files must be closed while context is valid so that messages can be passed
|
||||
@@ -114,7 +114,7 @@ pub fn exit(status: usize) -> ! {
|
||||
}
|
||||
|
||||
pub fn getpid() -> Result<ContextId> {
|
||||
Ok(context::context_id())
|
||||
Ok(context::current()?.read().pid)
|
||||
}
|
||||
|
||||
pub fn getpgid(pid: ContextId) -> Result<ContextId> {
|
||||
@@ -178,7 +178,7 @@ pub fn kill(pid: ContextId, sig: usize, parent_sigchld: bool) -> Result<usize> {
|
||||
}
|
||||
|
||||
let mut send = |context: &mut context::Context| -> SendResult {
|
||||
let is_self = context.id == context::context_id();
|
||||
let is_self = context.cid == context::current_cid();
|
||||
|
||||
// Non-root users cannot kill arbitrarily.
|
||||
if euid != 0 && euid != context.ruid && ruid != context.ruid {
|
||||
@@ -312,7 +312,7 @@ pub fn kill(pid: ContextId, sig: usize, parent_sigchld: bool) -> Result<usize> {
|
||||
for (pid, context_lock) in contexts.iter() {
|
||||
let mut context = context_lock.write();
|
||||
|
||||
if context.id.get() <= 2 {
|
||||
if context.pid.get() <= 2 {
|
||||
continue;
|
||||
}
|
||||
found += 1;
|
||||
@@ -373,7 +373,7 @@ pub fn setpgid(pid: ContextId, pgid: ContextId) -> Result<usize> {
|
||||
let current_pid = {
|
||||
let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
|
||||
let context = context_lock.read();
|
||||
context.id
|
||||
context.pid
|
||||
};
|
||||
|
||||
let context_lock = if pid.get() == 0 {
|
||||
@@ -383,9 +383,9 @@ pub fn setpgid(pid: ContextId, pgid: ContextId) -> Result<usize> {
|
||||
};
|
||||
|
||||
let mut context = context_lock.write();
|
||||
if context.id == current_pid || context.ppid == current_pid {
|
||||
if context.pid == current_pid || context.ppid == current_pid {
|
||||
if pgid.get() == 0 {
|
||||
context.pgid = context.id;
|
||||
context.pgid = context.pid;
|
||||
} else {
|
||||
context.pgid = pgid;
|
||||
}
|
||||
@@ -439,7 +439,7 @@ pub fn waitpid(
|
||||
let contexts = context::contexts();
|
||||
let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
|
||||
let context = context_lock.read();
|
||||
(context.id, Arc::clone(&context.waitpid))
|
||||
(context.pid, Arc::clone(&context.waitpid))
|
||||
};
|
||||
let write_status = |value| {
|
||||
status_ptr
|
||||
@@ -543,7 +543,7 @@ pub fn waitpid(
|
||||
if context.ppid != ppid {
|
||||
println!(
|
||||
"TODO: Hack for rustc - changing ppid of {} from {} to {}",
|
||||
context.id.get(),
|
||||
context.pid.get(),
|
||||
context.ppid.get(),
|
||||
ppid.get()
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user