Search code examples
csolariskernel-module

get process id and parent process in solaris kernel module


In solaris 11.0 kernel module driver, I need to get the parent process id and start time, and continue doing it - climb up the process tree this way.

in Linux kernel I have struct_task contains process id, start time.
What is equivelant to struct_task, and how I can get it within process context ?

Thanks

I saw something like what i need but for userspace. but "open" cannot be used in kernel 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");
}

the whole concept of /proc/procid/psinfo is to allow userspace processes to read kernel data. Since im at kernel space, i need to get the data from /proc/procid/psinfo if im on kernel space, this is disk IO i avoid...


Solution

  • If you look in /usr/include/sys/thread.h, you'll see the macro currproc defined:

    #define curproc     (ttoproc(curthread))    /* current process pointer */
    

    That returns a struct proc * that if non-null refers to the current process.

    The definition of struct proc can be 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;
    

    So your current process id is curproc->p_pidp->pid_id and the parent process id is curproc->p_ppid.