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
- init process: ancestor of all processes?
man ps
- torvalds/linux - linux/kernel/kthread.c
- torvalds/linux - linux/include/linux/kthread.h