2016-02-18 2 views
2

Je souhaite appeler périodiquement un programme d'espace utilisateur à partir d'un module noyau. Mais le programme noyau gèle le système, pendant que j'essaie de le charger. Voici le programme,Module de noyau appelant périodiquement le programme d'espace utilisateur

#include <linux/module.h> /* Needed by all modules */ 
#include <linux/kernel.h> /* Needed for KERN_INFO */ 
#include <linux/init.h>  /* Needed for the macros */ 
#include <linux/jiffies.h> 
#include <linux/time.h> 
#include <linux/proc_fs.h> 
#include <asm/uaccess.h> 
#include <linux/hrtimer.h> 
#include <linux/sched.h> 
#include <linux/delay.h> 

#define TIME_PERIOD 50000 

static struct hrtimer hr_timer; 
static ktime_t ktime_period_ns; 

static enum hrtimer_restart timer_callback(struct hrtimer *timer){ 
    char userprog[] = "test.sh"; 
    char *argv[] = {userprog, "2", NULL }; 
    char *envp[] = {"HOME=/", "PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL }; 
printk("\n Timer is running"); 
hrtimer_forward_now(&hr_timer, ktime_period_ns); 

printk("callmodule: %s\n", userprog); 
call_usermodehelper(userprog, argv, envp, UMH_WAIT_PROC); 
return HRTIMER_RESTART; 
} 

static int __init timer_init() { 
    ktime_period_ns= ktime_set(0, TIME_PERIOD); 
    hrtimer_init (&hr_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); 
    hr_timer.function = timer_callback; 
    hrtimer_start(&hr_timer, ktime_period_ns, HRTIMER_MODE_REL); 
    return 0; 
} 


static int __exit timer_exit(){ 

    int cancelled = hrtimer_cancel(&hr_timer); 

    if (cancelled) 
     printk(KERN_ERR "Timer is still running\n"); 
    else 
     printk(KERN_ERR "Timer is cancelled\n"); 

} 
module_init(timer_init); 
module_exit(timer_exit); 

MODULE_LICENSE("GPL"); 

test.sh est un script qui fait écho à un commentaire. J'ai testé individuellement la partie call_usermodehelper et la partie timer et cela fonctionne correctement. Mais pendant que je combine les deux codes, le système se bloque. Quelqu'un peut-il m'aider s'il vous plaît à résoudre le problème.

+0

Vous appelez votre minuteur toutes les 50 minutes, êtes-vous sûr que c'est correct? Essayez avec une période d'une seconde ou plus, pour voir si cela fonctionne. – HappyCactus

+1

Le rappel pour * hrtimer * est exécuté dans le contexte * atomic *, il ne devrait donc pas bloquer. 'call_usermodehelper' bloque le processus appelant jusqu'à ce que le programme appelle les retours. Vous pouvez utiliser 'delayed_work' au lieu de hrtimer pour exécuter périodiquement des tâches de blocage. – Tsyvarev

+0

Oui .... call_usermodehelper bloque le code. Mais test.sh est juste un écho "testing". Aucune idée, alors qu'il n'en sort pas. – BusyTraveller

Répondre

0

Un rapide coup d'œil autour suggère fortement que les callbacks hrtimer sont exécutés à partir d'un contexte irq, ce qui est attendu - sinon comment allez-vous obtenir une résolution élevée? Mais cela signifie également que vous ne devez pas bloquer, alors que votre callback peut bloquer en raison de call_usermodehelper indépendamment de NOWAIT passé.

Il semble donc que vous testez votre module sur un noyau avec le débogage désactivé, ce qui est fondamentalement faux. Mais ceci est moins pertinent car la chose que vous essayez d'accomplir en premier lieu semble fondamentalement erronée.

Je ne peux que vous recommander d'élaborer quel est le problème réel. Il y a absolument maintenant que forking + execing a quelque chose à voir avec quelque chose qui nécessite une minuterie haute résolution.

+0

Je ferai ma demande très claire. Je veux que le module noyau vérifie périodiquement si un processus utilisateur particulier est en cours d'exécution, et s'il ne fonctionne pas, il suffit de le déclencher.Le délai peut être de 5 à 10 secondes. Un minuteur haute résolution n'est donc pas requis. Mais même si j'avais essayé avec la minuterie normale (linux/timer.h), le résultat est le même. – BusyTraveller

+0

Que veut dire «déclencher» et pourquoi le noyau le ferait-il en premier lieu? Pourquoi ne pouvez-vous pas rester dans l'espace utilisateur? En ce qui concerne l'échec, étant donné le manque d'informations de débogage, il est impossible de dire ce qui aurait pu se passer d'autre. –

+0

En fait, il s'agit d'une exigence spécifique à l'application. Je vais essayer d'obtenir les informations de débogage. – BusyTraveller