循环进程的父进程,Linux内核

时间:2016-04-15 18:29:48

标签: loops linux-kernel

以下代码循环遍历curr_task的祖先,一直到swapper进程(即任何Linux进程的“最遥远的”祖先),它停止,因为{{1} }。

swapper == swapper->parent

问题是我还想获得while (curr_task != curr_task->parent) ...get curr_task info curr_task = curr_task->parent 进程的信息。有几种明显的方法可以做到这一点(例如,在while循环之后的swapper语句,或者在获得goto信息的循环之后的单个if语句。但是,这些显而易见的解决方案似乎相当不优雅,因此我正在寻找一种更简洁的解决方案,它不涉及备受much swapper或复制/粘贴代码。

3 个答案:

答案 0 :(得分:2)

使用某些功能执行以下操作。

walk_tasks_backwards_from(current);

功能跟随......

static void walk_tasks_backwards_from(struct task_struct *pos);
static void process_tasks(struct task_struct *parent, struct task_struct *child);

static void process_tasks(struct task_struct *parent, struct task_struct *child) {
  pr_alert("parent process: %s, PID: %d\n", parent->comm, parent->pid);
  pr_alert("child  process: %s, PID: %d\n", child->comm , child->pid);
}

static void walk_tasks_backwards_from(struct task_struct *pos) {
  struct task_struct *parent; ; 
  do {
    parent = pos->parent;
    process_tasks(parent, pos);
    pos = parent;
  } while(parent->pid != 0); 
}

您可以使用当前或任何想要走的任务来调用该函数,即

  walk_tasks_backwards_from(current);

这会在我的机器上产生以下输出,我有一个玩具内核模块,我可以使用cat /dev/toy

触发
[161769.300609] parent process: bash, PID: 918
[161769.301299] child  process: cat, PID: 2803 
[161769.301973] parent process: login, PID: 626
[161769.302632] child  process: bash, PID: 918
[161769.303216] parent process: systemd, PID: 1
[161769.303797] child  process: login, PID: 626
[161769.304355] parent process: swapper/0, PID: 0
[161769.304978] child  process: systemd, PID: 1

或者您可以使用以下任何一种......

使用do {} while

task = current;// Get current process
printk(KERN_INFO "process: %s, PID: %d", task->comm, task->pid);
do {

  task = task->parent;
  printk(KERN_INFO "process: %s, PID: %d", task->comm, task->pid);

} while (task->pid != 0);
//task here has pid == 0;

或使用while循环。

task = current;// Get current process
while (task->pid != 0) {

  printk(KERN_INFO "process: %s, PID: %d", task->comm, task->pid);
  task = task->parent;

}
//task here has pid == 0;
printk(KERN_INFO "process: %s, PID: %d", task->comm, task->pid);

循环所有

struct task_struct task;
for_each_process(task) {
  printk(KERN_INFO "process: %s, PID: %d", task->comm, task->pid);
}

答案 1 :(得分:2)

这是一种方法:使用另一个变量。

struct task_struct *t, *prev;
t = current;
do {
    // do something with t
    prev = t;
    t = t->parent;
} while (prev->pid != 0);

或者将其移入函数:

int move_up(struct task **tp) {
    int was_swapper = ((*tp)->pid == 0);
    *tp = (*tp)->parent;
    return was_swapper;
}

// ...

struct task_struct *t = current;
do {
     // do something with t
} while (move_up(&t));

答案 2 :(得分:0)

实际上,我们需要RCU锁来保护我们免于崩溃:

 public Object alienProxy() {
    try {
        System.setProperty("https.proxyUser", user);
        System.setProperty("https.proxyPassword", pass);
        System.setProperty("https.proxyHost", host);
        System.setProperty("https.proxyPort", port);
        System.setProperty("jdk.http.auth.tunneling.disabledSchemes", "");
        System.setProperty("jdk.http.auth.proxying.disabledSchemes", "");

        URL server = new URL(myURL);

        HttpURLConnection connection = (HttpURLConnection) server.openConnection();
        Authenticator.setDefault(new Authenticator() {
            @Override
            public PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(user, pass);
            }
        });
        try {
            connection.connect();
        } catch (Exception e) {
            e.printStackTrace();            
            System.clearProperty("https.proxyUser");
            System.clearProperty("https.proxyPassword");
            System.clearProperty("https.proxyHost");
            System.clearProperty("https.proxyPort");
            return "Invalid prxy";
        }
        connection.disconnect();
        System.clearProperty("https.proxyUser");
        System.clearProperty("https.proxyPassword");
        System.clearProperty("https.proxyHost");
        System.clearProperty("https.proxyPort");
        return service1();
    } catch (Exception e) {
        e.printStackTrace();
    }
    return false;
}

}`