Full Process Name from Task_Struct

Full process name from task_struct

Did you mean exe file name? You can get the exe of current process as follows :

char *pathname,*p;
mm = current->mm;
if (mm) {
down_read(&mm->mmap_sem);
if (mm->exe_file) {
pathname = kmalloc(PATH_MAX, GFP_ATOMIC);
if (pathname) {
p = d_path(&mm->exe_file->f_path, pathname, PATH_MAX);
/*Now you have the path name of exe in p*/
}
}
up_read(&mm->mmap_sem);
}

How to get process name from PID using C

To find the task_struct of a process we can make use of the function pid_task defined in kernel/pid.c .

struct task_struct *pid_task(struct pid *pid, enum pid_type type)

Arguments:

pid : Pointer to the struct pid of the process. 
pid_type: PIDTYPE_PID,
PIDTYPE_PGID,
PIDTYPE_SID,
PIDTYPE_MAX

To find the pid structure if we have the pid of a process we can use the functionfind_get_pid which is also defined in kernel/pid.c

struct pid *find_get_pid(pid_t nr)

In the below module we create a read/write proc entry named task_by_pid. Which ever process we want to find the task_struct of using its pid we can write to number into the proc entry.

When we read the proc entry, it will display the name of the process corresponding to the pid we wrote into it.

proc_task_pid:

#include <linux/module.h>
#include <linux/kernel.h>
#include <asm/uaccess.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/proc_fs.h>
#include <linux/pid.h>

#include <linux/pid_namespace.h>
int p_id;
struct pid *pid_struct;
struct task_struct *task;
static struct proc_dir_entry *proc_write_entry;
char *proc_name="task_by_pid";

int read_proc(char *buf,char **start,off_t offset,int count,int *eof,void *data )
{
int len=0;
pid_struct = find_get_pid(p_id);
task = pid_task(pid_struct,PIDTYPE_PID);

len = sprintf(buf,"\nname %s\n ",task->comm);

return len;
}

int write_proc(struct file *file,const char *buf,int count,void *data )
{
int ret;
char *id;
id = (char *)kmalloc(1000*sizeof(char),GFP_KERNEL);
printk(KERN_INFO "buf passed %s",buf);
if(copy_from_user(id,buf,count))
return -EFAULT;
printk(KERN_INFO "id passed %s",id);
p_id = simple_strtoul(id,NULL,0);
printk(KERN_INFO "pid %d ret %d",p_id,ret);
return sizeof(buf);
}

void create_new_proc_entry()
{
proc_write_entry = create_proc_entry(proc_name,0666,NULL);
if(!proc_write_entry)
{
printk(KERN_INFO "Error creating proc entry");
return -ENOMEM;
}
proc_write_entry->read_proc = read_proc ;
proc_write_entry->write_proc = write_proc;
printk(KERN_INFO "proc initialized");

}

int proc_init (void) {
create_new_proc_entry();
return 0;
}

void proc_cleanup(void) {
printk(KERN_INFO " Inside cleanup_module\n");
remove_proc_entry(proc_name,NULL);
}
MODULE_LICENSE("GPL");
module_init(proc_init);
module_exit(proc_cleanup);

Use the following make file to compile it:

ifneq ($(KERNELRELEASE),) 
obj-m := proc_task_pid.o
else

KERNELDIR ?= /lib/modules/$(shell uname -r)/build

PWD := $(shell pwd)

default:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
endif
clean:
$(MAKE) -C $(KERNELDIR) M=$(PWD) clean

Compile it using

$make

Insert it into the kernel:

$ insmod proc_task_pid.ko 

Now let us try to find the name of the process with pid "1", which is always init.

$ printf "1" > /proc/task_by_pid 
$ cat /proc/task_by_pid
name init

As expected the output is "init". Thus we can find the task_struct of any process using its pid.

Source code from here.

linux get process name from pid within kernel

struct task_struct contains a member called comm, it contains executable name excluding path.

Get current macro from this file will get you the name of the program that launched the current process (as in insmod / modprobe).

Using above info you can use get the name info.

get _complete_ process name from pid

You could always look at how the kernel does it. You'll see the function:

proc_pid_cmdline(struct task_struct *task, char * buffer)

It's fairly easy to follow but once you have the task_struct for the process you are interested in you use access_process_vm() to slurp the bits you want from mm->arg_start.

printing the comm field of the `current` task_struct, Linux kernel

What you see is exactly the process name, the swapper process runs each instance per CPU on a SMP system, and they are distinguished by appending the process number to it, so on the 1st CPU, the process is swapper/0, on the 2nd it would be swapper/1, and so on.
You can find out in the kernel source:

http://lxr.free-electrons.com/source/kernel/sched/core.c?v=3.5#L5136

#if defined(CONFIG_SMP)
sprintf(idle->comm, "%s/%d", INIT_TASK_COMM, cpu);
#endif

Here INIT_TASK_COMMON is defined as "swapper" in header file, and cpu is current cpu number.

How does the kernel use task_struct?

Yes, the task_struct structure contains all the information about a process. You can obtain a pointer to the structure that describes the current process using the current macro as follows:

struct task_struct *p = current;

If you want to get the structure that describes a process given a pid, you can use the find_task_by_vpid function as follows:

read_lock(&tasklist_lock);
p = find_task_by_vpid(pid);
if (p) get_task_struct(p);
read_unlock(&tasklist_lock);
if (p == NULL) {
// Task not found.
}

// Later, once you're finished with the task, execute:
put_task_struct(p);

Finally, if you want to iterate over all processes, you can use for_each_process as follows:

read_lock(&tasklist_lock);
for_each_process(p) {
// p is a pointer to a task_struct instance.
}
read_unlock(&tasklist_lock);

If you want to an exclusive access to the task list to be able to make changes to one or more fields in the structure, write_lock_irqsave must be used instead of read_lock.

Siblings of `struct task_struct current` always include a process with `pid = 0`

Here is an illustration of how two sibling child processes are linked into their parent process's list of children:

     PARENT              CHILD 1             CHILD 2
====== ======= =======

task_struct task_struct
+-------------+ +-------------+
| | | |
task_struct ~ ~ ~ ~
+-------------+ | | | |
| | |-------------| |-------------|
~ ~ | children | | children |
| | | | | |
. . |-------------| . . |-------------| . . |-------------| . .
| children | | sibling | | sibling |
X==>| prev | next |<===>| prev | next |<===>| prev | next |<==X
. . |-------------| . . |-------------| . . |-------------| . .
| sibling | | | | |
| | ~ ~ ~ ~
|-------------| | | | |
| | +-------------+ +-------------+
~ ~
| | 'X's are joined together, making
+-------------+ a doubly linked, circular list.

Although children and sibling are both of type struct list_head, children is being used as an actual list head (linking to its list of child processes), whereas sibling is being used as a list entry.

The parent's children.next link points to child 1's sibling member, child 1's sibling.next link points to child 2's sibling member, and child 2's sibling.next link points back to the parent's children member (the list head). Similarly, the parent's children.prev link points to child 2's sibling member, child 2's sibling.prev link points to child 1's sibling member, and child 1's sibling.prev link points back to the parent's children member.

The list_for_each(pos, head) macro visits each node pos in the list, starting at head->next, while pos != head.

Normally, the head parameter of list_for_each(pos, head) should be an actual list head, but the macro cannot tell the difference between a list head and a list entry. They are both the same type and all the nodes are linked together circularly. (The whole list consists of a list head with zero or more list entries linked in a circle. For an empty list, the list head just links back to itself.) The list_for_each macro will just iterate around the doubly linked list until it get back to where it started.

If list_for_each(pos, head) was called with head pointing to the parent's children member, then pos would point to child 1's sibling member in the first iteration, and would point to child 2's sibling member in the second iteration, and would terminate the loop with pos pointing back to the parent's children member. Inside the loop, list_entry(pos, struct task_struct, sibling) would correctly point to the beginning of the struct task_struct for the child process.

Let us say that child 1 is the current process. OP's code is using list_for_each(pos, head) with head pointing to child 1's sibling member. Therefore, pos would point to child 2's sibling member in the first iteration, and would point to the parent's children member in the second iteration, and would terminate the loop with pos pointing back to child 1's sibling member. Inside the loop, list_entry(pos, struct task_struct, sibling) would correctly point to the beginning of child 2's struct task_struct in the first iteration, but pos would point to somewhere before the beginning of the parent's struct task_struct in the second iteration. That is the where the problem lies in OP's code.

Where does task_struct get initialized in the Linux kernel?

Since the only way to create a new process in Linux is through the clone() syscall (or other variants like fork()), there is no real function to "create a new task" from scratch, but there sure is a function to duplicate an existing task, applying the needed modifications. The function used for this is copy_process(), which uses dup_task_struct() to duplicate the associated struct task_struct.

There is however one special exception to this rule: the init process (the first process created after booting) is created by the kernel itself (every other process is then created by init or by some child of init through clone() + execve()). The task_struct for the init task is statically defined at compile time (see here). You can look at this other answer if you want to know more.



Related Topics



Leave a reply



Submit