核心原始碼閱讀(五)程序ID

2021-08-06 08:10:04 字數 3653 閱讀 1759

接著上一節我們繼續學習程序id。

在上一節中我們提到了node是乙個雜湊表元素,對於這個雜湊表並未做過多解釋,在這裡我們給出更加詳細的描述。

這個雜湊表是為了在給定的命名空間中查詢對應與指定pid數值的pid陣列的pid結構例項。

static struct hlist_head *pid_hash;

上面的hlist_head是乙個核心的標準資料結構,用於建立雙向雜湊表。

pid_hash是乙個hlist_head陣列,全域性pid雜湊表,桶數目介於16-4096之間,由系統可用記憶體決定 ,pidhash_init()用於計算並分配合適的所需記憶體。

假如我們已經分配了乙個新pid例項,並設定id型別,可使用下面的函式將其和程序關聯起來。

int fastcall attach_pid(struct task_struct *task, enum pid_type type,

struct pid *pid)

下面我們將關注如何通過上節的資料結構來獲取區域性的id,如task_pid,task_tgid等,以及命名空間區域性數字id和task_struct的相互轉換過程。

struct task_struct *find_task_by_pid_type_ns(int type, int

nr,struct pid_namespace *ns)

export_symbol(find_task_by_pid_type_ns);

/** * 通過全域性pid查詢任務

*/struct task_struct *find_task_by_pid(pid_t nr)

export_symbol(find_task_by_pid);

/** * 在當前程序的命名空間中,查詢特定程序號的程序

*/struct task_struct *find_task_by_vpid(pid_t vnr)

export_symbol(find_task_by_vpid);

/** * 根據id在命名空間中查詢程序

*/struct task_struct *find_task_by_pid_ns(pid_t nr, struct pid_namespace *ns)

export_symbol(find_task_by_pid_ns);

struct pid *get_task_pid(struct task_struct *task, enum pid_type type)

pid_t task_pid_nr_ns(struct task_struct *tsk, struct pid_namespace *ns)

export_symbol(task_pid_nr_ns);

pid_t task_tgid_nr_ns(struct task_struct *tsk, struct pid_namespace *ns)

export_symbol(task_tgid_nr_ns);

pid_t task_pgrp_nr_ns(struct task_struct *tsk, struct pid_namespace *ns)

export_symbol(task_pgrp_nr_ns);

pid_t task_session_nr_ns(struct task_struct *tsk, struct pid_namespace *ns)

export_symbol(task_session_nr_ns);

struct pid *get_task_pid(struct task_struct *task, enum pid_type type)

struct task_struct *fastcall get_pid_task(struct pid *pid, enum pid_type type)

下面將介紹如何生成唯一的pid。

核心採用了乙個大的位圖來對pid進行管理和跟蹤,每個pid用乙個位元來標識,空閒置0,反之置1即可。

在這裡需要注意在進行pid分配建立乙個新程序時,由於程序可能在多明敏空間中可見,則必須生成區域性pid,這個需先在alloc_pid()中處理,然後才能呼叫alloc_pidmap()去分配pid,釋放的時候同樣。

struct pid *alloc_pid(struct pid_namespace *ns)

get_pid_ns(ns);

pid->level = ns->level;

atomic_set(&pid->count, 1);

for (type = 0; type < pidtype_max; ++type)

init_hlist_head(&pid->tasks[type]);

spin_lock_irq(&pidmap_lock);

for (i = ns->level; i >= 0; i--)

spin_unlock_irq(&pidmap_lock);

out:

return pid;

out_free:

for (i++; i <= ns->level; i++)

free_pidmap(pid->numbers[i].ns, pid->numbers[i].nr);

kmem_cache_free(ns->pid_cachep, pid);

pid = null;

goto out;

}/**

* 在命名空間中,查詢並分配乙個可用的pid號

*/static int alloc_pidmap(struct pid_namespace *pid_ns)

if (likely(atomic_read(&map->nr_free)))

offset = find_next_offset(map, offset);

pid = mk_pid(pid_ns, map, offset);

/** find_next_offset() found a bit, the pid from it

* is in-bounds, and if we fell back to the last

* bitmap block and the final block was the same

* as the starting point, pid is before last_pid.

*/} while (offset < bits_per_page && pid < pid_max &&

(i != max_scan || pid < last ||

!((last+1) & bits_per_page_mask)));

}if (map

< &pid_ns->pidmap[(pid_max-1)/bits_per_page]) else

pid = mk_pid(pid_ns, map, offset);

}return -1;

}

fastcall void free_pid(struct pid *pid)

/** * 在命名空間中,釋放乙個可用的pid號

*/static fastcall void free_pidmap(struct pid_namespace *pid_ns, int pid)

核心原始碼閱讀(一)程序

1.程序分為實時程序和非實時程序。硬實時程序有嚴格的時間限制,某些任務必須在指定的時限內完成。軟實時程序是硬實時程序的一種弱化形式。大多數程序沒有特定時間約束的普通程序。cpu時間分配簡圖如2.1所示。圖2.1時間片分配cpu時間 搶占式多工處理 各個程序都分配到一定時間段可以移植,當時間到期後,核...

怎樣閱讀核心原始碼

1.獲取核心 2.目錄結構 在閱讀原始碼之前,還應知道linux核心原始碼的整體分布情況。現代的作業系統一般由程序管理 記憶體管理 文件系統 驅動程式和網路等組成。linux核心原始碼的各個目錄大致和此相對應,其組成如下 假設相對於linux 2.4.23目錄 arch目錄包括了任何和體系結構相關的...

Linux核心原始碼 閱讀方法

url 通常linux會有以下目錄 arch 子目錄包括所有和體系結構相關的核心 它還有更深的子目錄,每乙個代表一種支援的體系結構 include 子目錄包括編譯核心所需要的大部分 include 檔案。它也有更深的子目錄,每乙個支援的體系結構乙個。include asm 是這個體系結構所需要的真實...