GNU/Linux >> Tutoriales Linux >  >> Linux

Manera eficiente de encontrar task_struct por pid

Hay una mejor manera de obtener la instancia de task_struct de un módulo. Siempre intente usar la función de envoltura/rutinas auxiliares porque están diseñadas de tal manera que si el programador del controlador se perdió algo, el núcleo puede encargarse por sí mismo. Por ejemplo:manejo de errores, verificación de condiciones, etc.

/* Use below API and you will get a pointer of (struct task_struct *) */

taskp = get_pid_task(pid, PIDTYPE_PID);

y para obtener el PID de tipo pid_t. necesita usar la siguiente API -

find_get_pid(pid_no);

No necesita usar "rcu_read_lock() " y "rcu_read_unlock() " al llamar a estas API porque "get_pid_task() " llama internamente a rcu_read_lock(),rcu_read_unlock() antes de llamar a "pid_task() " y maneja la concurrencia correctamente. Es por eso que he dicho anteriormente que use este tipo de contenedor siempre.

Fragmento de la función get_pid_task() y find_get_pid() a continuación:-

struct task_struct *get_pid_task(struct pid *pid, enum pid_type type)
{
    struct task_struct *result;
    rcu_read_lock();
    result = pid_task(pid, type);
    if (result)
        get_task_struct(result);
    rcu_read_unlock();
    return result;
}
EXPORT_SYMBOL_GPL(get_pid_task);

struct pid *find_get_pid(pid_t nr)
{
    struct pid *pid;

    rcu_read_lock();
    pid = get_pid(find_vpid(nr));
    rcu_read_unlock();

    return pid;
}
EXPORT_SYMBOL_GPL(find_get_pid);

En un módulo del núcleo, también puede usar la función contenedora de la siguiente manera -

taskp = get_pid_task(find_get_pid(PID),PIDTYPE_PID);

PD:para obtener más información sobre las API, puede consultar kernel/pid.c


Si quieres encontrar el task_struct de un módulo, find_task_by_vpid(pid_t nr) etc. no van a funcionar ya que estas funciones no se exportan.

En un módulo, puede usar la siguiente función en su lugar:

pid_task(find_vpid(pid), PIDTYPE_PID);

Nadie mencionó que el pid_task() función y el puntero (que obtiene de él) debe usarse dentro de la sección crítica de RCU (porque utiliza una estructura de datos protegida por RCU). De lo contrario puede haber ERROR de usar después de liberar .
Hay muchos casos de uso de pid_task() en las fuentes del kernel de Linux (por ejemplo, en posix_timer_event() ).
Por ejemplo:

rcu_read_lock();
/* search through the global namespace */
task = pid_task(find_pid_ns(pid_num, &init_pid_ns), PIDTYPE_PID);
if (task)
    printk(KERN_INFO "1. pid: %d, state: %#lx\n",
           pid_num, task->state); /* valid task dereference */
rcu_read_unlock(); /* after it returns - task pointer becomes invalid! */

if (task)
    printk(KERN_INFO "2. pid: %d, state: %#lx\n",
           pid_num, task->state); /* may be successful,
                                   * but is buggy (task dereference is INVALID!) */

Obtenga más información sobre la API de RCU en Kernel.org

PD también puede usar las funciones especiales de la API como find_task_by_pid_ns() y find_task_by_vpid() bajo el rcu_read_lock() .

El primero es para buscar a través del espacio de nombres particular:

task = find_task_by_pid_ns(pid_num, &init_pid_ns); /* e.g. init namespace */

El segundo es para buscar a través del espacio de nombres de current tarea.


¿Qué tiene de malo usar uno de los siguientes?

extern struct task_struct *find_task_by_vpid(pid_t nr);
extern struct task_struct *find_task_by_pid_ns(pid_t nr,
            struct pid_namespace *ns);

Linux
  1. ¿Cómo encuentro la identificación del proceso en Ubuntu?

  2. ¿Hay alguna forma de verificar si hay enlaces simbólicos que apuntan a un directorio?

  3. ¿Hay alguna manera de encontrar el tiempo de ejecución del último comando ejecutado en el shell?

  4. busque y elimine archivos con espacio usando el comando de búsqueda en Linux

  5. La forma más eficiente de copiar un archivo en Linux

Cómo encontrar un nombre de proceso usando el número PID en Linux

¿Manera confiable de encarcelar procesos secundarios usando `nsenter:`?

Manera de averiguar si el sistema es compatible con Intel Amt?

¿N manera fácil de reemplazar archivos duplicados con enlaces duros?

Cómo encontrar el nombre del proceso a partir de su PID

Cómo encontrar el PID y PPID de un proceso en Linux