2016-02-18 3 views
2

Я хочу периодически вызывать программу пространства пользователя из модуля ядра. Но программа ядра замораживает систему, а я пытаюсь ее загрузить. Ниже приводится программа,Модуль ядра, периодически вызывающий программу пользовательского пространства

#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 представляет собой скрипт, который просто повторяет комментарий. Я проверил часть call_usermodehelper и часть таймера отдельно, и он работает нормально. Но когда я совмещаю два кода, система зависает. Может кто-нибудь, пожалуйста, помогите мне решить проблему.

+0

Вы звоните в свой таймер каждые 50 лет, вы уверены, что это правильно? Попробуйте с одной секундой или более периодом, чтобы убедиться, что если он работает. – HappyCactus

+1

Обратный звонок для * hrtimer * выполняется в * атомном * контексте, поэтому он не должен блокироваться. 'call_usermodehelper' блокирует процесс вызова, пока вызываемая программа не вернется. Вы можете использовать 'delayed_work' вместо hrtimer для периодического выполнения задач блокировки. – Tsyvarev

+0

Да .... call_usermodehelper блокирует код. Но test.sh - это просто «тестирование» эха. Не знаю, пока он не выходит из этого. – BusyTraveller

ответ

0

Быстрый поиск вокруг предполагает, что обратные вызовы hrtimer выполняются из контекста irq, который ожидается - как еще вы получите высокий уровень разрешения?

Но это также означает, что вы не должны блокировать, в то время как ваш обратный вызов может блокироваться из-за call_usermodehelper независимо от того, прошел ли NOWAIT.

Так что, похоже, вы тестируете свой модуль на ядре с отключенной отладкой, что в корне неверно.

Но это менее актуально, поскольку вещь, которую вы пытаетесь достичь, в первую очередь выглядит принципиально неправильной.

Я могу только посоветовать вам уточнить, в чем проблема. Совершенно верно, что forking + execing имеет какое-то отношение к чему-то, требующему таймера с высоким разрешением.

+0

Я сделаю свое требование очень ясным. Я хочу, чтобы модуль ядра периодически проверял, работает ли какой-либо конкретный пользовательский процесс, и если он не запускается, просто запускайте его. Период может составлять от 5 до 10 секунд. Поэтому таймер с высоким разрешением не требуется. Но даже когда я пытался с обычным таймером (linux/timer.h), результат был таким же. – BusyTraveller

+0

Что означает «триггер» и почему ядро ​​это делает в первую очередь? Почему вы не можете придерживаться пользовательского пространства? Что касается отказа, учитывая отсутствие отладочной информации, невозможно сказать, что еще могло произойти. –

+0

На самом деле, это специфическое требование для приложения. Я попытаюсь получить отладочную информацию. – BusyTraveller