接著上一節我們繼續學習程序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 是這個體系結構所需要的真實...