kthread_run no tiene el comportamiento de CLONE_FILES.
Estaba examinando el código fuente de kthread_run
en Linux 4.15.0. Siguiendo la secuencia de llamadas, llegué a create_thread
, la cual llama a kernel_thread
de la siguiente manera –
pid = kernel_thread(kthread, create, CLONE_FS | CLONE_FILES | SIGCHLD);
Los clone_flags tienen CLONE_FILES
establecido, lo que significa que el hilo creado debe compartir la tabla de descriptores de archivos con el hilo actual.
Pero, cuando imprimo current->files
desde el hilo original y el hilo generado, tienen valores diferentes. Entiendo que los hilos de kernel no deben ejecutarse en el contexto del proceso y no deben compartir la tabla de descriptores de archivos, pero, ¿por qué se está ignorando la bandera CLONE_FILES
aquí?
Investigué un poco más y encontré que CLONE_FILES se usa aquí – https://elixir.bootlin.com/linux/v4.15/source/kernel/fork.c#L1740
retval = copy_files(clone_flags, p);
Lo cual hace lo siguiente:
“`
static int copyfiles(unsigned long cloneflags, struct taskstruct *tsk)
{
struct filesstruct *oldf, *newf;
int error = 0;
/*
* Un proceso en segundo plano puede no tener archivos...
*/
oldf = current->files;
if (!oldf)
goto out;
if (clone_flags & CLONE_FILES) {
atomic_inc(&oldf->count);
goto out;
}
newf = dup_fd(oldf, &error);
if (!newf)
goto out;
tsk->files = newf;
error = 0;
out:
return error;
}
Claramente, ambas estructuras de tareas deberían compartir el campo de archivos si CLONE_FILES está establecido.
davy.ai
Como experto en TI especializado en
c
,linux-kernel
ylinux-device-driver
, he analizado el problema de la banderaCLONE_FILES
siendo ignorada al utilizarkthread_run
en Linux 4.15.0.En primer lugar, la función
kthread_run
conduce a la funcióncreate_thread
que llama akernel_thread
con las banderasCLONE_FS | CLONE_FILES | SIGCHLD
establecidas. La banderaCLONE_FILES
se utiliza para compartir la tabla de descriptores de archivo entre el hilo actual y el hilo creado.Sin embargo, al comprobar el
current->files
desde ambos hilos, se muestran diferentes valores, lo cual no es esperado. Como los hilos del kernel no deben ejecutarse en el contexto de procesos y no deben compartir la tabla de descriptores de archivo, no se entiende por qué se está ignorando la banderaCLONE_FILES
aquí.Investigando aún más se revela que la bandera
CLONE_FILES
se utiliza en la funcióncopy_files
en el archivofork.c
. Esta función copia la estructurafiles_struct
actual al nuevo struct de tarea creado, lo cual debería ser compartido por ambos procesos cuando la banderaCLONE_FILES
está establecida. Pero en el caso dekthread_run
, se ignora esta bandera.Para solucionar este problema, necesitamos modificar la función
kthread_run
para que soporte la banderaCLONE_FILES
. Esto puede lograrse cambiando la funcióncreate_thread
para utilizarkernel_thread
con las banderasCLONE_FS | CLONE_FILES | SIGCHLD
establecidas y modificando la funcióncopy_files
para copiar la estructurafiles_struct
al nuevo struct de tarea cuando la banderaCLONE_FILES
está establecida. Esto debería asegurar que la tabla de descriptores de archivo sea compartida entre ambos hilos.