| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 9434 人关注过本帖
标题:计算机
只看楼主 加入收藏
madfrogme
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:21
帖 子:1160
专家分:1106
注 册:2009-6-24
收藏
得分:0 
it is possible to obtain the process descriptor of its parent with the following code:

struct task_struct *my_parent = current->parent;

Similarly, it is possible to iterate over a process's children with

struct task_struct *task;
struct list_head *list;
list_for_each(list, &current->children) {
    task = list_entry(list, struct task_struct, sibling);
    /* task now points to one of current's children */
}


user/include/linux/list.h 中
#define list_entry(ptr, type, member) \
((type *)((char *)(ptr) – (unsigned long)(&((type *)0)->member)))


[ 本帖最后由 madfrogme 于 2012-9-22 19:28 编辑 ]

The quieter you become, the more you can hear
2012-09-22 18:16
madfrogme
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:21
帖 子:1160
专家分:1106
注 册:2009-6-24
收藏
得分:0 
enum pid_type
{
    PIDTYPE_PID,   进程的PID
    PIDTYPE_PGID,  进程组ID
    PIDTYPE_SID,   会话ID
    PIDTYPE_MAX
};

搞这么多个组是因为有需要给一个组同时发信号,
比如有时,使用 kill -9 杀一个程序,有了组的概念,就比较方便杀死相关的线程和进程。
会话也一样,你退出了telnet,就必须杀死你登录时创建的所有非后台进程。有了会话id,杀就非常方便。

The quieter you become, the more you can hear
2012-09-23 00:36
madfrogme
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:21
帖 子:1160
专家分:1106
注 册:2009-6-24
收藏
得分:0 
pid 结构体中嵌套着upid结构体, upid结构体中又嵌套着pid_namespace 结构体

The quieter you become, the more you can hear
2012-09-23 00:43
madfrogme
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:21
帖 子:1160
专家分:1106
注 册:2009-6-24
收藏
得分:0 
如何将task_struct 实例变为数字ID,

这个过程包含下面两个步骤

1. 获得与task_struct 关联的pid 实例,辅助函数task_pid, task_tgid, task_pgrp 和 task_session 分别用于取得 不同类型的ID.
<sched.h>
static inline struct pid *task_pid(struct task_struct *task)
{
        return task->pids[PIDTYPE_PID].pid;
}

kernel/pid.c
在获得pid 实例之后, 从struct pid 的 numbers 数组中的 uid 信息, 即可获得数字ID
pid_t pid_nr_ns ( struct pid *pid, struct pid_namespace *ns)
{
        struct upid *upid;
        pid_t nr = 0;
        if( pid && ns->level <= pid->level) {
                upid = &pid->numbers[ns->level];
                if(upid->ns == ns )
                        nr = upid->nr;
        }
        return nr;
}

因为父命名空间可以看到子命名空间的PID, 反过来却不行,

内核必须确保当前命名空间的level 小于或等于产生局部PID的命名空间的level

同样重要的是, 内核只需要关注产生全局PID

The quieter you become, the more you can hear
2012-09-23 01:06
madfrogme
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:21
帖 子:1160
专家分:1106
注 册:2009-6-24
收藏
得分:0 
可以使用如下方法查看页的大小, 单位是字节,一般linux的结果是4096
$ getconf PAGESIZE

或者
$ getconf PAGE_SIZE


[ 本帖最后由 madfrogme 于 2012-9-24 10:50 编辑 ]

The quieter you become, the more you can hear
2012-09-24 09:49
madfrogme
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:21
帖 子:1160
专家分:1106
注 册:2009-6-24
收藏
得分:0 
alloc_pidmap()函数,这个函数的功能就是分配新的空闲PID号,
其中有一句
offset = pid & BITS_PER_PAGE_MASK;

BITS_PER_PAGE_MASK的定义为如下

kernel/pid.c
53 #define BITS_PER_PAGE           (PAGE_SIZE*8)
54 #define BITS_PER_PAGE_MASK      (BITS_PER_PAGE-1)

PAGE_SIZE查到是4096, 所以BITS_PER_PAGE 就是32768, 2^15 (1,000,000,000,000,000)

所以BITS_PER_PAGE_MASK 就是( 0,111,111,111,111,111)了

于是pid & BITS_PER_PAGE_MASK; 就是取 pid的下15位了
所以offset 最大只能为32767


[ 本帖最后由 madfrogme 于 2012-9-24 11:02 编辑 ]

The quieter you become, the more you can hear
2012-09-24 09:59
madfrogme
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:21
帖 子:1160
专家分:1106
注 册:2009-6-24
收藏
得分:0 
几个和pid 有关的定义
include/linux/pid_namespace.h 中
 struct pidmap {
        atomic_t nr_free;
        void *page;
 };

#define PIDMAP_ENTRIES         ((PID_MAX_LIMIT + 8*PAGE_SIZE - 1)/PAGE_SIZE/8)

struct pid_namespace {
  ...
         struct pidmap pidmap[PIDMAP_ENTRIES];
         int last_pid;
         struct task_struct *child_reaper;
         struct kmem_cache *pid_cachep;
         unsigned int level;
         struct pid_namespace *parent;
 ...
}

include/linux/threads.h 文件

#ifndef _LINUX_THREADS_H
#define _LINUX_THREADS_H


/*
 * The default limit for the nr of threads is now in
 * /proc/sys/kernel/threads-max.
 */

/*
 * Maximum supported processors.  Setting this smaller saves quite a
 * bit of memory.  Use nr_cpu_ids instead of this except for static bitmaps.
 */
#ifndef CONFIG_NR_CPUS
/* FIXME: This should be fixed in the arch's Kconfig */
#define CONFIG_NR_CPUS    1
#endif

/* Places which use this should consider cpumask_var_t. */
#define NR_CPUS        CONFIG_NR_CPUS

#define MIN_THREADS_LEFT_FOR_ROOT 4

/*
 * This controls the default maximum pid allocated to a process
 */
#define PID_MAX_DEFAULT (CONFIG_BASE_SMALL ? 0x1000 : 0x8000)

/*
 * A maximum of 4 million PIDs should be enough for a while.
 * [NOTE: PID/TIDs are limited to 2^29 ~= 500+ million, see futex.h.]
 */
#define PID_MAX_LIMIT (CONFIG_BASE_SMALL ? PAGE_SIZE * 8 : \
    (sizeof(long) > 4 ? 4 * 1024 * 1024 : PID_MAX_DEFAULT))

#endif

The quieter you become, the more you can hear
2012-09-24 10:24
madfrogme
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:21
帖 子:1160
专家分:1106
注 册:2009-6-24
收藏
得分:0 
arch/x86/kernel/process.c 中
sys_fork 的定义

 int sys_fork(struct pt_regs *regs)
 {
         return do_fork(SIGCHLD, regs->sp, regs, 0, NULL, NULL);
 }

pt_regs 结构体在arch/x86/include/asm/ptrace.h中有定义

struct pt_regs {
    long ebx;
    long ecx;
    long edx;
    long esi;
    long edi;
    long ebp;
    long eax;
    int  xds;
    int  xes;
    int  xfs;
    int  xgs;
    long orig_eax;
    long eip;
    int  xcs;
    long eflags;
    long esp;
    int  xss;
};

実際にはシステムコール側の関数の引数宣言がどのような 形になっていてもスタックに積まれている値は struct pt_regs の形式になっており,

通常は最初の 5 個のうちのいくつかがシステムコール側で使用されるようになって います.

すべてのシステムコールは int 0x80 で entry.S の ENTRY(system_call) を 経由してカーネルの関数が呼び出されるため,

実はどのシステムコールでも同じ 情報を受け取っていることになります

The quieter you become, the more you can hear
2012-09-24 23:50
madfrogme
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:21
帖 子:1160
专家分:1106
注 册:2009-6-24
收藏
得分:0 
execve システムコールではレジスタに以下のような情報を渡す必要があります.

    ebx : (char *)filename,
    ecx : char ** argv,
    edx : char ** envp

なぜなら,sys_execve 中では do_execve に次のように情報を渡しています

do_execve(filename, (char **) regs.ecx, (char **) regs.edx, &regs);

The quieter you become, the more you can hear
2012-09-24 23:52
madfrogme
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:21
帖 子:1160
专家分:1106
注 册:2009-6-24
收藏
得分:0 
Page Table Entries (PTE)

A page table entry is what represents a page.

We will not cover the page table until a little later so dont worry too much about it.

However we will need to look at what an entry in the table looks like now. T

he x86 architecture defines a specific bit format for working with pages, so lets take a look at it.

Bit 0 (P): Present flag
0: Page is not in memory
1: Page is present (in memory)

Bit 1 (R/W): Read/Write flag
0: Page is read only
1: Page is writable

Bit 2 (U/S):User mode/Supervisor mode flag
0: Page is kernel (supervisor) mode
1: Page is user mode. Cannot read or write supervisor pages

Bits 3-4 (RSVD): Reserved by Intel

Bit 5 (A): Access flag. Set by processor
0: Page has not been accessed
1: Page has been accessed

Bit 6 (D): Dirty flag. Set by processor
0: Page has not been written to
1: Page has been written to

Bits 7-8 (RSVD): Reserved

Bits 9-11 (AVAIL): Available for use

Bits 12-31 (FRAME): Frame address


[ 本帖最后由 madfrogme 于 2012-9-25 11:45 编辑 ]

The quieter you become, the more you can hear
2012-09-25 10:38
快速回复:计算机
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.022705 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved