在 solaris 内核模块中获取进程 ID 和父进程
get process id and parent process in solaris kernel module
在solaris 11.0 kernel module driver中,我需要获取父进程id和启动时间,然后继续做——这样向上爬进程树。
在我的 Linux 内核中 struct_task 包含进程 ID、启动时间。
struct_task 的等价物是什么?我如何在进程上下文中获取它?
谢谢
我看到了我需要的东西,但 userspace。但是 "open" 不能在内核中使用 space..
char psfile[64];
pid_t pid;
int fd;
psinfo_t psinfo;
pid = getpid();
sprintf(psfile, "/proc/%d/psinfo", pid);
if ((fd = open(psfile, O_RDONLY)) >= 0) {
if (read(fd, &psinfo, sizeof(psinfo_t)) != -1) {
printf("Pid: %ld\n", psinfo.pr_pid);
printf("Up Start: (%ld, %ld)\n", psinfo.pr_start.tv_sec,
psinfo.pr_start.tv_nsec);
printf("Command: %s\n", psinfo.pr_fname);
return 0;
}
} else {
perror("Open psfino");
}
/proc/procid/psinfo 的整个概念是允许用户space 进程读取内核数据。因为我在内核 space,我需要从 /proc/procid/psinfo 获取数据,如果我在内核 space,这是我避免的磁盘 IO...
如果您 look in /usr/include/sys/thread.h
,您将看到定义的宏 currproc
:
#define curproc (ttoproc(curthread)) /* current process pointer */
那returns一个struct proc *
那如果非空指的是当前进程。
struct proc
的定义可以是found in /usr/include/sys/proc.h
:
/*
* One structure allocated per active process. It contains all
* data needed about the process while the process may be swapped
* out. Other per-process data (user.h) is also inside the proc structure.
* Lightweight-process data (lwp.h) and the kernel stack may be swapped out.
*/
typedef struct proc {
/*
* Fields requiring no explicit locking
*/
struct vnode *p_exec; /* pointer to a.out vnode */
struct as *p_as; /* process address space pointer */
struct plock *p_lockp; /* ptr to proc struct's mutex lock */
kmutex_t p_crlock; /* lock for p_cred */
struct cred *p_cred; /* process credentials */
/*
* Fields protected by pidlock
*/
int p_swapcnt; /* number of swapped out lwps */
char p_stat; /* status of process */
char p_wcode; /* current wait code */
ushort_t p_pidflag; /* flags protected only by pidlock */
int p_wdata; /* current wait return value */
pid_t p_ppid; /* process id of parent */
struct proc *p_link; /* forward link */
struct proc *p_parent; /* ptr to parent process */
struct proc *p_child; /* ptr to first child process */
struct proc *p_sibling; /* ptr to next sibling proc on chain */
struct proc *p_psibling; /* ptr to prev sibling proc on chain */
struct proc *p_sibling_ns; /* prt to siblings with new state */
struct proc *p_child_ns; /* prt to children with new state */
struct proc *p_next; /* active chain link next */
struct proc *p_prev; /* active chain link prev */
struct proc *p_nextofkin; /* gets accounting info at exit */
struct proc *p_orphan;
struct proc *p_nextorph;
struct proc *p_pglink; /* process group hash chain link next */
struct proc *p_ppglink; /* process group hash chain link prev */
struct sess *p_sessp; /* session information */
struct pid *p_pidp; /* process ID info */
struct pid *p_pgidp; /* process group ID info */
/*
* Fields protected by p_lock
*/
kcondvar_t p_cv; /* proc struct's condition variable */
kcondvar_t p_flag_cv;
kcondvar_t p_lwpexit; /* waiting for some lwp to exit */
kcondvar_t p_holdlwps; /* process is waiting for its lwps */
/* to to be held. */
uint_t p_proc_flag; /* /proc-related flags */
uint_t p_flag; /* protected while set. */
/* flags defined below */
clock_t p_utime; /* user time, this process */
clock_t p_stime; /* system time, this process */
clock_t p_cutime; /* sum of children's user time */
clock_t p_cstime; /* sum of children's system time */
avl_tree_t *p_segacct; /* System V shared segment list */
avl_tree_t *p_semacct; /* System V semaphore undo list */
caddr_t p_bssbase; /* base addr of last bss below heap */
caddr_t p_brkbase; /* base addr of heap */
size_t p_brksize; /* heap size in bytes */
uint_t p_brkpageszc; /* preferred heap max page size code */
/*
* Per process signal stuff.
*/
k_sigset_t p_sig; /* signals pending to this process */
k_sigset_t p_extsig; /* signals sent from another contract */
k_sigset_t p_ignore; /* ignore when generated */
k_sigset_t p_siginfo; /* gets signal info with signal */
void *p_sigfd; /* signalfd support state */
struct sigqueue *p_sigqueue; /* queued siginfo structures */
struct sigqhdr *p_sigqhdr; /* hdr to sigqueue structure pool */
struct sigqhdr *p_signhdr; /* hdr to signotify structure pool */
uchar_t p_stopsig; /* jobcontrol stop signal */
/*
* Special per-process flag when set will fix misaligned memory
* references.
*/
char p_fixalignment;
/*
* Per process lwp and kernel thread stuff
*/
id_t p_lwpid; /* most recently allocated lwpid */
int p_lwpcnt; /* number of lwps in this process */
int p_lwprcnt; /* number of not stopped lwps */
int p_lwpdaemon; /* number of TP_DAEMON lwps */
int p_lwpwait; /* number of lwps in lwp_wait() */
int p_lwpdwait; /* number of daemons in lwp_wait() */
int p_zombcnt; /* number of zombie lwps */
kthread_t *p_tlist; /* circular list of threads */
lwpdir_t *p_lwpdir; /* thread (lwp) directory */
lwpdir_t *p_lwpfree; /* p_lwpdir free list */
tidhash_t *p_tidhash; /* tid (lwpid) lookup hash table */
uint_t p_lwpdir_sz; /* number of p_lwpdir[] entries */
uint_t p_tidhash_sz; /* number of p_tidhash[] entries */
ret_tidhash_t *p_ret_tidhash; /* retired tidhash hash tables */
uint64_t p_lgrpset; /* unprotected hint of set of lgrps */
/* on which process has threads */
volatile lgrp_id_t p_t1_lgrpid; /* main's thread lgroup id */
volatile lgrp_id_t p_tr_lgrpid; /* text replica's lgroup id */
#if defined(_LP64)
uintptr_t p_lgrpres2; /* reserved for lgrp migration */
#endif
/*
* /proc (process filesystem) debugger interface stuff.
*/
k_sigset_t p_sigmask; /* mask of traced signals (/proc) */
k_fltset_t p_fltmask; /* mask of traced faults (/proc) */
struct vnode *p_trace; /* pointer to primary /proc vnode */
struct vnode *p_plist; /* list of /proc vnodes for process */
kthread_t *p_agenttp; /* thread ptr for /proc agent lwp */
avl_tree_t p_warea; /* list of watched areas */
avl_tree_t p_wpage; /* remembered watched pages (vfork) */
watched_page_t *p_wprot; /* pages that need to have prot set */
int p_mapcnt; /* number of active pr_mappage()s */
kmutex_t p_maplock; /* lock for pr_mappage() */
struct proc *p_rlink; /* linked list for server */
kcondvar_t p_srwchan_cv;
size_t p_stksize; /* process stack size in bytes */
uint_t p_stkpageszc; /* preferred stack max page size code */
/*
* Microstate accounting, resource usage, and real-time profiling
*/
hrtime_t p_mstart; /* hi-res process start time */
hrtime_t p_mterm; /* hi-res process termination time */
hrtime_t p_mlreal; /* elapsed time sum over defunct lwps */
hrtime_t p_acct[NMSTATES]; /* microstate sum over defunct lwps */
hrtime_t p_cacct[NMSTATES]; /* microstate sum over child procs */
struct lrusage p_ru; /* lrusage sum over defunct lwps */
struct lrusage p_cru; /* lrusage sum over child procs */
struct itimerval p_rprof_timer; /* ITIMER_REALPROF interval timer */
uintptr_t p_rprof_cyclic; /* ITIMER_REALPROF cyclic */
uint_t p_defunct; /* number of defunct lwps */
/*
* profiling. A lock is used in the event of multiple lwp's
* using the same profiling base/size.
*/
kmutex_t p_pflock; /* protects user profile arguments */
struct prof p_prof; /* profile arguments */
/*
* Doors.
*/
door_pool_t p_server_threads; /* common thread pool */
struct door_node *p_door_list; /* active doors */
struct door_node *p_unref_list;
kcondvar_t p_unref_cv;
char p_unref_thread; /* unref thread created */
/*
* Kernel probes
*/
uchar_t p_tnf_flags;
/*
* Solaris Audit
*/
struct p_audit_data *p_audit_data; /* per process audit structure */
pctxop_t *p_pctx;
#if defined(__x86)
/*
* LDT support.
*/
kmutex_t p_ldtlock; /* protects the following fields */
user_desc_t *p_ldt; /* Pointer to private LDT */
system_desc_t p_ldt_desc; /* segment descriptor for private LDT */
ushort_t p_ldtlimit; /* highest selector used */
#endif
size_t p_swrss; /* resident set size before last swap */
struct aio *p_aio; /* pointer to async I/O struct */
struct itimer **p_itimer; /* interval timers */
timeout_id_t p_alarmid; /* alarm's timeout id */
caddr_t p_usrstack; /* top of the process stack */
uint_t p_stkprot; /* stack memory protection */
uint_t p_datprot; /* data memory protection */
model_t p_model; /* data model determined at exec time */
struct lwpchan_data *p_lcp; /* lwpchan cache */
kmutex_t p_lcp_lock; /* protects assignments to p_lcp */
utrap_handler_t *p_utraps; /* pointer to user trap handlers */
struct corectl_path *p_corefile; /* pattern for core file */
struct task *p_task; /* our containing task */
struct proc *p_taskprev; /* ptr to previous process in task */
struct proc *p_tasknext; /* ptr to next process in task */
kmutex_t p_sc_lock; /* protects p_pagep */
struct sc_page_ctl *p_pagep; /* list of process's shared pages */
struct rctl_set *p_rctls; /* resource controls for this process */
rlim64_t p_stk_ctl; /* currently enforced stack size */
rlim64_t p_fsz_ctl; /* currently enforced file size */
rlim64_t p_vmem_ctl; /* currently enforced addr-space size */
rlim64_t p_fno_ctl; /* currently enforced file-desc limit */
pid_t p_ancpid; /* ancestor pid, used by exacct */
struct itimerval p_realitimer; /* real interval timer */
timeout_id_t p_itimerid; /* real interval timer's timeout id */
struct corectl_content *p_content; /* content of core file */
avl_tree_t p_ct_held; /* held contracts */
struct ct_equeue **p_ct_equeue; /* process-type event queues */
struct cont_process *p_ct_process; /* process contract */
list_node_t p_ct_member; /* process contract membership */
sigqueue_t *p_killsqp; /* sigqueue pointer for SIGKILL */
int p_dtrace_probes; /* are there probes for this proc? */
uint64_t p_dtrace_count; /* number of DTrace tracepoints */
/* (protected by P_PR_LOCK) */
void *p_dtrace_helpers; /* DTrace helpers, if any */
struct pool *p_pool; /* pointer to containing pool */
kcondvar_t p_poolcv; /* synchronization with pools */
uint_t p_poolcnt; /* # threads inside pool barrier */
uint_t p_poolflag; /* pool-related flags (see below) */
uintptr_t p_portcnt; /* event ports counter */
struct zone *p_zone; /* zone in which process lives */
struct vnode *p_execdir; /* directory that p_exec came from */
struct brand *p_brand; /* process's brand */
void *p_brand_data; /* per-process brand state */
psecflags_t p_secflags; /* per-process security flags */
/* additional lock to protect p_sessp (but not its contents) */
kmutex_t p_splock;
rctl_qty_t p_locked_mem; /* locked memory charged to proc */
/* protected by p_lock */
rctl_qty_t p_crypto_mem; /* /dev/crypto memory charged to proc */
/* protected by p_lock */
clock_t p_ttime; /* buffered task time */
/*
* The user structure
*/
struct user p_user; /* (see sys/user.h) */
} proc_t;
所以你当前的进程id是curproc->p_pidp->pid_id
,父进程id是curproc->p_ppid
。
在solaris 11.0 kernel module driver中,我需要获取父进程id和启动时间,然后继续做——这样向上爬进程树。
在我的 Linux 内核中 struct_task 包含进程 ID、启动时间。
struct_task 的等价物是什么?我如何在进程上下文中获取它?
谢谢
我看到了我需要的东西,但 userspace。但是 "open" 不能在内核中使用 space..
char psfile[64];
pid_t pid;
int fd;
psinfo_t psinfo;
pid = getpid();
sprintf(psfile, "/proc/%d/psinfo", pid);
if ((fd = open(psfile, O_RDONLY)) >= 0) {
if (read(fd, &psinfo, sizeof(psinfo_t)) != -1) {
printf("Pid: %ld\n", psinfo.pr_pid);
printf("Up Start: (%ld, %ld)\n", psinfo.pr_start.tv_sec,
psinfo.pr_start.tv_nsec);
printf("Command: %s\n", psinfo.pr_fname);
return 0;
}
} else {
perror("Open psfino");
}
/proc/procid/psinfo 的整个概念是允许用户space 进程读取内核数据。因为我在内核 space,我需要从 /proc/procid/psinfo 获取数据,如果我在内核 space,这是我避免的磁盘 IO...
如果您 look in /usr/include/sys/thread.h
,您将看到定义的宏 currproc
:
#define curproc (ttoproc(curthread)) /* current process pointer */
那returns一个struct proc *
那如果非空指的是当前进程。
struct proc
的定义可以是found in /usr/include/sys/proc.h
:
/*
* One structure allocated per active process. It contains all
* data needed about the process while the process may be swapped
* out. Other per-process data (user.h) is also inside the proc structure.
* Lightweight-process data (lwp.h) and the kernel stack may be swapped out.
*/
typedef struct proc {
/*
* Fields requiring no explicit locking
*/
struct vnode *p_exec; /* pointer to a.out vnode */
struct as *p_as; /* process address space pointer */
struct plock *p_lockp; /* ptr to proc struct's mutex lock */
kmutex_t p_crlock; /* lock for p_cred */
struct cred *p_cred; /* process credentials */
/*
* Fields protected by pidlock
*/
int p_swapcnt; /* number of swapped out lwps */
char p_stat; /* status of process */
char p_wcode; /* current wait code */
ushort_t p_pidflag; /* flags protected only by pidlock */
int p_wdata; /* current wait return value */
pid_t p_ppid; /* process id of parent */
struct proc *p_link; /* forward link */
struct proc *p_parent; /* ptr to parent process */
struct proc *p_child; /* ptr to first child process */
struct proc *p_sibling; /* ptr to next sibling proc on chain */
struct proc *p_psibling; /* ptr to prev sibling proc on chain */
struct proc *p_sibling_ns; /* prt to siblings with new state */
struct proc *p_child_ns; /* prt to children with new state */
struct proc *p_next; /* active chain link next */
struct proc *p_prev; /* active chain link prev */
struct proc *p_nextofkin; /* gets accounting info at exit */
struct proc *p_orphan;
struct proc *p_nextorph;
struct proc *p_pglink; /* process group hash chain link next */
struct proc *p_ppglink; /* process group hash chain link prev */
struct sess *p_sessp; /* session information */
struct pid *p_pidp; /* process ID info */
struct pid *p_pgidp; /* process group ID info */
/*
* Fields protected by p_lock
*/
kcondvar_t p_cv; /* proc struct's condition variable */
kcondvar_t p_flag_cv;
kcondvar_t p_lwpexit; /* waiting for some lwp to exit */
kcondvar_t p_holdlwps; /* process is waiting for its lwps */
/* to to be held. */
uint_t p_proc_flag; /* /proc-related flags */
uint_t p_flag; /* protected while set. */
/* flags defined below */
clock_t p_utime; /* user time, this process */
clock_t p_stime; /* system time, this process */
clock_t p_cutime; /* sum of children's user time */
clock_t p_cstime; /* sum of children's system time */
avl_tree_t *p_segacct; /* System V shared segment list */
avl_tree_t *p_semacct; /* System V semaphore undo list */
caddr_t p_bssbase; /* base addr of last bss below heap */
caddr_t p_brkbase; /* base addr of heap */
size_t p_brksize; /* heap size in bytes */
uint_t p_brkpageszc; /* preferred heap max page size code */
/*
* Per process signal stuff.
*/
k_sigset_t p_sig; /* signals pending to this process */
k_sigset_t p_extsig; /* signals sent from another contract */
k_sigset_t p_ignore; /* ignore when generated */
k_sigset_t p_siginfo; /* gets signal info with signal */
void *p_sigfd; /* signalfd support state */
struct sigqueue *p_sigqueue; /* queued siginfo structures */
struct sigqhdr *p_sigqhdr; /* hdr to sigqueue structure pool */
struct sigqhdr *p_signhdr; /* hdr to signotify structure pool */
uchar_t p_stopsig; /* jobcontrol stop signal */
/*
* Special per-process flag when set will fix misaligned memory
* references.
*/
char p_fixalignment;
/*
* Per process lwp and kernel thread stuff
*/
id_t p_lwpid; /* most recently allocated lwpid */
int p_lwpcnt; /* number of lwps in this process */
int p_lwprcnt; /* number of not stopped lwps */
int p_lwpdaemon; /* number of TP_DAEMON lwps */
int p_lwpwait; /* number of lwps in lwp_wait() */
int p_lwpdwait; /* number of daemons in lwp_wait() */
int p_zombcnt; /* number of zombie lwps */
kthread_t *p_tlist; /* circular list of threads */
lwpdir_t *p_lwpdir; /* thread (lwp) directory */
lwpdir_t *p_lwpfree; /* p_lwpdir free list */
tidhash_t *p_tidhash; /* tid (lwpid) lookup hash table */
uint_t p_lwpdir_sz; /* number of p_lwpdir[] entries */
uint_t p_tidhash_sz; /* number of p_tidhash[] entries */
ret_tidhash_t *p_ret_tidhash; /* retired tidhash hash tables */
uint64_t p_lgrpset; /* unprotected hint of set of lgrps */
/* on which process has threads */
volatile lgrp_id_t p_t1_lgrpid; /* main's thread lgroup id */
volatile lgrp_id_t p_tr_lgrpid; /* text replica's lgroup id */
#if defined(_LP64)
uintptr_t p_lgrpres2; /* reserved for lgrp migration */
#endif
/*
* /proc (process filesystem) debugger interface stuff.
*/
k_sigset_t p_sigmask; /* mask of traced signals (/proc) */
k_fltset_t p_fltmask; /* mask of traced faults (/proc) */
struct vnode *p_trace; /* pointer to primary /proc vnode */
struct vnode *p_plist; /* list of /proc vnodes for process */
kthread_t *p_agenttp; /* thread ptr for /proc agent lwp */
avl_tree_t p_warea; /* list of watched areas */
avl_tree_t p_wpage; /* remembered watched pages (vfork) */
watched_page_t *p_wprot; /* pages that need to have prot set */
int p_mapcnt; /* number of active pr_mappage()s */
kmutex_t p_maplock; /* lock for pr_mappage() */
struct proc *p_rlink; /* linked list for server */
kcondvar_t p_srwchan_cv;
size_t p_stksize; /* process stack size in bytes */
uint_t p_stkpageszc; /* preferred stack max page size code */
/*
* Microstate accounting, resource usage, and real-time profiling
*/
hrtime_t p_mstart; /* hi-res process start time */
hrtime_t p_mterm; /* hi-res process termination time */
hrtime_t p_mlreal; /* elapsed time sum over defunct lwps */
hrtime_t p_acct[NMSTATES]; /* microstate sum over defunct lwps */
hrtime_t p_cacct[NMSTATES]; /* microstate sum over child procs */
struct lrusage p_ru; /* lrusage sum over defunct lwps */
struct lrusage p_cru; /* lrusage sum over child procs */
struct itimerval p_rprof_timer; /* ITIMER_REALPROF interval timer */
uintptr_t p_rprof_cyclic; /* ITIMER_REALPROF cyclic */
uint_t p_defunct; /* number of defunct lwps */
/*
* profiling. A lock is used in the event of multiple lwp's
* using the same profiling base/size.
*/
kmutex_t p_pflock; /* protects user profile arguments */
struct prof p_prof; /* profile arguments */
/*
* Doors.
*/
door_pool_t p_server_threads; /* common thread pool */
struct door_node *p_door_list; /* active doors */
struct door_node *p_unref_list;
kcondvar_t p_unref_cv;
char p_unref_thread; /* unref thread created */
/*
* Kernel probes
*/
uchar_t p_tnf_flags;
/*
* Solaris Audit
*/
struct p_audit_data *p_audit_data; /* per process audit structure */
pctxop_t *p_pctx;
#if defined(__x86)
/*
* LDT support.
*/
kmutex_t p_ldtlock; /* protects the following fields */
user_desc_t *p_ldt; /* Pointer to private LDT */
system_desc_t p_ldt_desc; /* segment descriptor for private LDT */
ushort_t p_ldtlimit; /* highest selector used */
#endif
size_t p_swrss; /* resident set size before last swap */
struct aio *p_aio; /* pointer to async I/O struct */
struct itimer **p_itimer; /* interval timers */
timeout_id_t p_alarmid; /* alarm's timeout id */
caddr_t p_usrstack; /* top of the process stack */
uint_t p_stkprot; /* stack memory protection */
uint_t p_datprot; /* data memory protection */
model_t p_model; /* data model determined at exec time */
struct lwpchan_data *p_lcp; /* lwpchan cache */
kmutex_t p_lcp_lock; /* protects assignments to p_lcp */
utrap_handler_t *p_utraps; /* pointer to user trap handlers */
struct corectl_path *p_corefile; /* pattern for core file */
struct task *p_task; /* our containing task */
struct proc *p_taskprev; /* ptr to previous process in task */
struct proc *p_tasknext; /* ptr to next process in task */
kmutex_t p_sc_lock; /* protects p_pagep */
struct sc_page_ctl *p_pagep; /* list of process's shared pages */
struct rctl_set *p_rctls; /* resource controls for this process */
rlim64_t p_stk_ctl; /* currently enforced stack size */
rlim64_t p_fsz_ctl; /* currently enforced file size */
rlim64_t p_vmem_ctl; /* currently enforced addr-space size */
rlim64_t p_fno_ctl; /* currently enforced file-desc limit */
pid_t p_ancpid; /* ancestor pid, used by exacct */
struct itimerval p_realitimer; /* real interval timer */
timeout_id_t p_itimerid; /* real interval timer's timeout id */
struct corectl_content *p_content; /* content of core file */
avl_tree_t p_ct_held; /* held contracts */
struct ct_equeue **p_ct_equeue; /* process-type event queues */
struct cont_process *p_ct_process; /* process contract */
list_node_t p_ct_member; /* process contract membership */
sigqueue_t *p_killsqp; /* sigqueue pointer for SIGKILL */
int p_dtrace_probes; /* are there probes for this proc? */
uint64_t p_dtrace_count; /* number of DTrace tracepoints */
/* (protected by P_PR_LOCK) */
void *p_dtrace_helpers; /* DTrace helpers, if any */
struct pool *p_pool; /* pointer to containing pool */
kcondvar_t p_poolcv; /* synchronization with pools */
uint_t p_poolcnt; /* # threads inside pool barrier */
uint_t p_poolflag; /* pool-related flags (see below) */
uintptr_t p_portcnt; /* event ports counter */
struct zone *p_zone; /* zone in which process lives */
struct vnode *p_execdir; /* directory that p_exec came from */
struct brand *p_brand; /* process's brand */
void *p_brand_data; /* per-process brand state */
psecflags_t p_secflags; /* per-process security flags */
/* additional lock to protect p_sessp (but not its contents) */
kmutex_t p_splock;
rctl_qty_t p_locked_mem; /* locked memory charged to proc */
/* protected by p_lock */
rctl_qty_t p_crypto_mem; /* /dev/crypto memory charged to proc */
/* protected by p_lock */
clock_t p_ttime; /* buffered task time */
/*
* The user structure
*/
struct user p_user; /* (see sys/user.h) */
} proc_t;
所以你当前的进程id是curproc->p_pidp->pid_id
,父进程id是curproc->p_ppid
。