2017-05-04 1 views
0

Je fais un appel système qui boucle tous les processus avec un certain statut (passé au syscall en tant que paramètre) et affiche leur nom, PID, UID et le nom de leurs enfants . Voilà ce que j'ai jusqu'à présent:Appel système qui montre les processus filtrés par leur statut

asmlinkage int sys_procinfo(int state){ 
    struct task_struct *task; 
    struct task_struct *child_ptr; 
    struct list_head *list; 


    for_each_process(task) { 
     if(task->state == state){ 
      /* print info about the parent */ 
      printk(KERN_INFO "nombre:%s[pid:%d]estado:%ld[uid:%d]\n", task->comm, task->pid, task->state, task->uid); 


      list_for_each(list, &task->children) { 
       child_ptr = list_entry(list, struct task_struct, sibling); 
       /* child_ptr now points to one of current's children */ 
       printk(KERN_INFO "Hijo %s\n", child_ptr->comm); 
      } 
     } 
    } 
    return 0; 
} 

Cette affiche tous les processus et leurs enfants du système, en ignorant complètement la condition if (task-> état == état), ce qui est très bizarre pour moi. Je n'ai besoin d'imprimer que les informations des processus qui sont dans l'état 'state' (par exemple TASK_RUNNING = 0, EXIT_ZOMBIE = 32, TASK_WAKING = 256, TASK_INTERRUPTIBLE = 1, etc.). Oh, et je voudrais aussi que le syscall retourne son numéro syscall, mais je l'ai défini pour deux systèmes: 32 et 64bits, et leurs nombres dans les tables syscall_32.tbl et syscall_64.tbl sont différents, donc je pense Je ne peux pas coder en dur le numéro de syscall. Existe-t-il une macro que je peux utiliser pour renvoyer cette valeur?

Merci. PS: Je travaille sur kubuntu 16.04LTS, et j'utilise le noyau "linux-3.16.43.tar.xz" à partir des archives du noyau Linux

+0

Veuillez fournir plus d'informations pour rendre votre problème reproductible. Je ne suis plus un gourou Linux (même pas un programmeur Linux) mais (avec l'aide de google) je pourrais être en mesure de fournir une réponse (comme je l'ai déjà fait dans le passé). Un [exemple minimal, complet et vérifiable] (http://stackoverflow.com/help/mcve) fournirait l'en-tête nécessaire qui me conduirait aux bonnes pages de manuel. 'for_each_process()' et 'list_for_each()' peuvent être des macros qui sont définies dans votre code non-présenté ou incluses ailleurs. Cela semble intéressant, mais il manque trop de réponses ... – Scheff

+0

Eh bien, c'est en fait le code, et c'est dans le fichier sys.c du noyau. Ces macros sont dans le noyau, je ne les ai pas définies. Quoi qu'il en soit, j'ai trouvé la réponse et je l'afficherai. – Sebasuraa

Répondre

1

Je pense que le problème était que 'tâche' wasn ' t initialisé, mais c'est un peu bizarre car il aurait dû pointer vers tous les processus de toute façon dans la macro for_each_process(). Ce que j'ai fait était de pointer d'abord vers le processus init (ou systemd) et de faire ensuite une boucle sur chaque processus et leurs enfants. C'est le fichier sys.c dans le noyau et il imprime le nom de chaque processus exécuté dans l'état 'state' (si c'est un état valide) le long de leur PID et UID, plus le nom de leurs enfants. Il peut être appelé comme syscall (SYS_procinfo_64, state);

asmlinkage int sys_procinfo(int state) { 
    struct task_struct *tarea; 
    struct task_struct *hijo; 
    struct list_head *lista_procesos; 

    if(state != 0 && state != 1 && state != 2 && state != 4 && state != 8 && state != 16 && state != 32 
     && state != 64 && state != 128 && state != 256 && state != 512 && state != 1024 && state != 2048 
     && state != 4096){ 
     /* Si el estado ingresado no es valido, retornar -1 */ 
     return -1; 
    } 
    /* tarea apunta hacia init para recorrer los procesos */ 
    for (tarea = current; tarea != &init_task; tarea = tarea->parent) 
     ; 
    /* recorrer todos los procesos con el puntero tarea */ 
    for_each_process(tarea) { 
     /* mostrar informacion de procesos en el estado 'state' */ 
     if(tarea->state == state || task->exit_state == state) { 
      /* informacion del padre */ 
      printk(KERN_INFO "Proceso %s  pid: %d uid: %u\n", tarea->comm, tarea->pid, current_uid().val); 
      /* informacion de los hijos */ 
      list_for_each(lista_procesos, &tarea->children) { 
       hijo = list_entry(lista_procesos, struct task_struct, sibling); 
       printk(KERN_INFO "Hijo %s\n", hijo->comm); 
      } 
     } 
    } 
    return state; 
}