Los sistemas Linux actuales tienen ciertos procesos que ejecutan código del kernel Linux, pero son manejados como procesos del espacio usuario en lo que respecta a planificación (scheduling). Sin embargo no respetan las reglas típicas de manejo de memoria ya que corren código del kernel.

Estos procesos son creados por kthreadd, el cual es una especie de init para procesos del kernel. Es posible reconocerlos porque usualmente la herramienta ps los lista con un nombre entre corchetes:

root@debian9:~# ps -ef | grep '\[' | head -n 10
root         1     0  0  2018 ?        00:01:38 init [2]
root         2     0  0  2018 ?        00:00:23 [kthreadd]
root         3     2  0  2018 ?        00:00:00 [rcu_gp]
root         7     2  0  2018 ?        00:00:00 [mm_percpu_wq]
root         8     2  0  2018 ?        00:00:13 [ksoftirqd/0]
root         9     2  0  2018 ?        00:41:15 [rcu_sched]
root        10     2  0  2018 ?        00:00:00 [rcu_bh]
root        11     2  0  2018 ?        00:00:00 [migration/0]
root        12     2  0  2018 ?        00:00:24 [watchdog/0]
root        13     2  0  2018 ?        00:00:00 [cpuhp/0]

Los hilos del kernel no son hijos de init ya que pueden ser iniciados antes de que arranque el espacio usuario (userland, PID 1 en adelante). Estos procesos típicamente se encargan de manejar hardware, por eso son gestionados directamente por el kernel y tienen alta prioridad.

Este artículo demuestra cómo ocultar estos procesos en la salida de ps.

Más allá de los corchetes en la salida de ps, es posible reconocer de forma más precisa a los hilos del kernel por el hecho de que todos son hijos del proceso kthreadd, cuyo PID es igual a 2. Al mismo tiempo, dado que corren código del kernel, /proc/PID/exe (normalmente un enlace simbólico al ejecutable) no puede ser leído:

root@debian9:~# ll /proc/3/exe
ls: cannot read symbolic link '/proc/3/exe': No such file or directory
lrwxrwxrwx 1 root root 0 Feb 14 07:04 /proc/3/exe

Como otro dato curioso, tanto init (PID 1) como kthreadd (PID 2) no tienen padre (PPID igual a 0) pues son creados por el kernel (no por otro proceso).

A fin de ocultar estos procesos de la salida de ps, es necesario excluir a todos los procesos hijos de PID 2 (kthreadd). La herramienta ps cuenta con una opción para invertir la selección indicada como parámetro. Por ende, si se seleccionan todos los procesos cuyo padre es PID 2 (--ppid 2) y luego se invierte la selección (-N), se logra el efecto deseado:

root@debian9:~# ps a --ppid 2 -N
  PID TTY      STAT   TIME COMMAND
    1 ?        Ss     1:38 init [2]
    2 ?        S      0:23 [kthreadd]
  830 ?        Ss     0:00 /lib/systemd/systemd-udevd --daemon
 1956 ?        S<     2:15 /usr/sbin/atopacctd
 1960 ?        Ss     0:00 /lib/startpar/startpar -f -- atopacct
 2044 ?        Ss     0:00 /sbin/lvmetad
 2353 ?        Ss     0:22 /usr/sbin/cron
 2410 ?        S      0:20 /usr/sbin/chronyd
 2481 ?        Ss     0:00 /usr/bin/dbus-daemon --system
 2735 ?        Ss     0:00 nginx: master process /usr/local/nginx/sbin/nginx
 2788 ?        S      7:18 /usr/local/pgsql/bin/postgres
 2846 ?        Ss     0:00 postgres: logger process   
 2848 ?        Ss     0:14 postgres: logger process   
 2856 ?        Ss     0:07 postgres: checkpointer process   
 2857 ?        Ss     1:58 postgres: writer process   
 2858 ?        Ss     2:03 postgres: wal writer process   
 2859 ?        Ss     5:53 postgres: autovacuum launcher process   
 2860 ?        Ss    12:32 postgres: stats collector process   
 2861 ?        Ss     0:09 postgres: bgworker: logical replication launcher   
 6726 ?        S     19:52 /usr/bin/vmtoolsd
 9323 ?        Ssl    0:01 /usr/sbin/bacula-fd -u root -g root -c /etc/bacula/bacula-fd.conf
10411 ?        Ss     0:04 /usr/sbin/sshd
10856 ?        S      0:00 /lib/systemd/systemd-udevd
14887 ?        Ss     0:02 /usr/sbin/exim4 -bd -q30m
14932 ?        Ssl    2:06 /usr/sbin/rsyslogd
15511 ?        S      0:00 nginx: worker process
15512 ?        S      0:00 nginx: worker process
15513 ?        S      0:00 nginx: worker process
15514 ?        S      0:00 nginx: worker process
15686 ?        Ss     0:15 postgres: checkpointer process   
15687 ?        Ss     1:23 postgres: writer process   
15688 ?        Ss     1:29 postgres: wal writer process   
15689 ?        Ss     4:22 postgres: autovacuum launcher process   
15690 ?        Ss     9:03 postgres: stats collector process   
15691 ?        Ss     0:11 postgres: bgworker: logical replication launcher   
17038 ?        S      0:00 /usr/sbin/CRON
17039 ?        Ss     0:00 /bin/sh -c /usr/share/atop/atop.daily \&
17040 ?        S<L    0:06 /usr/bin/atop -a -R -w /var/log/atop/atop_20190220 600
17896 ?        S      0:01 php-fpm: pool www
17901 ?        S      0:01 php-fpm: pool www
19917 ?        S      0:02 php-fpm: pool www
24003 ?        Ss     6:23 php-fpm: master process (/usr/local/etc/php/php-fpm.conf)

Otros comandos que permiten emular la salida de ps aux, pero sin mostrar los hilos del kernel, son algunos de los siguientes:

ps -o user,pid,%cpu,%mem,vsz,rss,tty,stat,start,time,cmd --ppid 2 -N 
ps -o user,pid,%cpu,%mem,vsz,rss,tty,stat,bsdstart,time,command --ppid 2 -N
ps -o user,pid,%cpu,%mem,vsz,rss,tname,stat,bsdstart,time,command --ppid 2 -N

Referencias


Tal vez pueda interesarte


Compartí este artículo