Linux进程管理内核API

__task_pid_nr_ns

头文件

#include <linux/sched.h>

函数定义

pid_t  __task_pid_nr_ns (struct task_struct* task, enum pid_type, struct pid_namespace* ns);

功能

此函数用于获取进程的进程号,此进程应该满足以下约束条件:

  1. 如果参数 type 不等于 PIDTYPE_PID,则参数 task 用其所属任务组中的第一个任务赋值,否则保持task不变

  2. 此进程是参数 task 任务描述符中的进程

  3. 保证进程描述符的 pid_namespace 和参数 ns 相同

返回符合条件的进程的进程号。

输入参数说明:

  • task 是 struct task_struct 型变量,用于保存任务的基本信息,其定义在文件 sched.h 中

  • type 是 pid_type 类型变量,此变量是一个枚举变量,定义如下:

enum pid_type
{
    PIDTYPE_PID,        // 进程的进程号
    PIDTYPE_PGID,       // 进程组,领头进程的进程号
    PIDTYPE_SID,        // 会话领头进程的进程号
    PIDTYPE_MAX
};
  • ns 是 struct pid_namespace 型变量,是对进程命名空间信息的描述,其定义如下:

struct pid_namespace
{
    struct kref kref;   // 引用计数,表示此命名空间在多少进程中被使用
    struct pidmap pidmap[PIDMAP_ENTRIES];   // 记录当前系统的PID使用情况
    int last_pid;       // 记录上一次分配给进程的 PID 值
    struct task_struct* child_reaper;   // 保存了指向该进程的 task_struct 指针
    struct kmem_cache*  pid_cachep; // 指向该进程在 cache 中分配的空间
    unsigned int level;     // 表示当前命名空间在命名空间层次结构中的深度,初始命名空间的level为0,该命名空间的子空间level为1,下一层的子空间level为2。level比较高的命名空间中的ID对level比较低的命名空间来说是可见的。从给定的level设置,内核可以推断进程会关联多少个ID。
    struct pid_namespace* parent;   // 指向父命名空间的指针
#ifdef CONFIG_PROC_FS
    struct vfsmount*        proc_mnt;
#endif

#ifdef CONFIG_BSD_PROCESS_ACCT
    struct bsd_acct_struct* bacct;
#endif
};

find_get_pid

头文件

#include <linux/pid.h>

功能

此函数用于根据提供的进程号获取对应的进程描述符,并使进程描述符中的字段 count 的值加1。即进程的用户数加1.

返回参数说明

struct pid
{
    atomic_t count;             // 当前使用此进程的任务数量
    unsigned int level;         // 对应字段 number[] 数组的下表
    /* 当前pid所属任务的链表 */
    struct hlist_head tasks[PIDTYPE_MAX];   // tasks 是当前使用此进程的任务列表
    struct rcu_head rcu;        // 
    struct upid numbers[1];     // 保存进程相关信息
};

struct upid
{
    int nr;
    struct pid_namespace* ns;
    struct hlist_node pid_chain;
};

find_pid_ns

头文件

#include <linux/pid.h>

功能

此函数用于获取进程的进程描述符,此进程应该满足以下约束条件:

  1. 进程的进程号和参数nr相同

  2. 保证进程描述符的 pid_namespace 和参数ns相同

find_task_by_pid_ns

头文件

#include <linux/sched.h>

功能

此函数用于获取任务描述符信息,此任务的任务描述符应满足以下约束条件:

  1. 在任务描述符包含的进程组中含有进程的进程号与参数nr相同

  2. 在任务描述符包含的进程组中含有进程的pid_namespace值与参数ns相同

find_task_by_pid_type_ns

头文件

#include <linux/sched.h>

功能

此函数用于获取任务描述符信息,此任务的任务描述符应满足以下约束条件:

  1. 在进行信息匹配时候需要参考参数 type 的值,从而决定是按进程号进行匹配,还是按进程组进程号进行匹配,或是按会话号进行匹配

  2. 在任务描述符包含的进程组中含有进程的进程号应与参数nr相同

  3. 在任务描述符包含的进程组中含有的进程的pid_namespace值应与参数ns相同

find_task_by_vpid

头文件

#include <linux/sched.h>

功能

此函数用于获取任务描述符信息,此任务的任务描述符应满足以下约束条件:任务描述符包含的进程组中含有进程的进程号和参数nr相同,其中nr代表进程的局部进程号。

find_vpid

头文件

#include <linux/sched.h>

功能

此函数用于根据提供的局部进程号获取对应的进程描述符。

get_pid

头文件

#include <linux/pid.h>

功能

此函数用于改变进程描述符的count字段值,使 count 字段的值增加1,此进程描述符是函数的输入参数。

定义

static inline struct pid* get_pid (struct pid* pid)
{
    if (pid) {
        atomic_inc (&pid->count);
    }
    return pid;
}

get_task_mm

头文件

#include <linux/sched.h>

功能

此函数用于根据提供的任务描述符信息,获取其对应的内存信息,此内存信息保存在mm_struct结构体类型的变量中。

is_container_init

头文件

#include <linux/sched.h>

功能

此函数用于判断输入参数所代表任务的进程号是否为1,对于在同一个任务中的所有进程的进程号都是相同的。

kernel_thread

头文件

#include <linux/sched.h>

功能

此函数用于创建一个新的内核线程,即完成在内核态创建一个子进程。

函数的实现过程为:首先在内核地址空间为此进程分配内存空间,然后初始化与此进程相关的变量,最后调用 do_fork() 函数创建一个新的进程,并返回新进程的进程号。

mmput

头文件

#include <linux/sched.h>

功能

此函数用于减少任务对应的内存空间的用户的数量,并在当用户数量减少到0的时候释放任务所占用的内存空间

ns_of_pid

头文件

#include <linux/pid.h>

功能

此函数用于获取进程命名空间的信息,根据参数(进程描述符)获得信息

pid_nr

头文件

#include <linux/pid.h>

功能

函数 pid_nr() 用于获取进程的全局进程号,并根据输入参数所代表的基础南横描述符获取全局进程号

pid_task

头文件

#include <linux/pid.h>

功能

此函数用于获取任务的任务描述符信息,此任务在任务进程 pid 的使用链表中,并且搜索链表的其实元素的下标为参数 type 的值。

pid_vnr

头文件

#include <linux/pid.h>

功能

函数 pid_vnr 用于根据输入参数,获取进程的局部进程号。

put_pid

头文件

#include <linux/pid.h>

功能

此函数用于释放进程所占 cache 空间,但不是每次执行都总是成功,因为只有在进程的用户数量降为1时,即目前没有任何其它任务在使用此进程时,才可以释放此进程所占用的cache空间;当进程用户的数量大于1时,此函数会使进程描述符字段count的值减1.

task_active_pid_ns

头文件

#include <linux/pid_namespace.h>

功能

此函数用于获取任务中包含进程的命名空间信息,函数执行过程如下:

首先调用函数 task_pid 获得任务字段 pids[PIDTYPE_PID] 的pid值,然后调用函数 ns_of_pid 获取函数 task_pid 返回值的命名空间信息。

task_tgid_nr_ns

头文件

#include <linux/sched.h>

功能

此函数用于获取满足一定条件的进程的PID,函数执行过程如下:

首先调用函数 task_tgid 获取参数 task 包含进程组中的领头进程的进程描述符,然后调用函数 pid_nr_ns 获得进程的进程号,并必须保证此进程的进程命名空间值和参数ns相同。