J'essaie d'implémenter un appel de signal depuis un module noyau chargeable vers une application utilisateur. L'application utilise sigaction
pour gérer l'appel de signal et plus tard, elle doit utiliser sival_int
pour gérer différentes actions par switch
et case
.Noyau: utilisation des fonctions sigqueue
void signalHandler_function (int signum,
siginfo_t *siginfo,
void *ucontext)
{
printf("signum: %i\n", signum);
printf("sigval: %d\n", siginfo->si_value.sival_int);
}
int main(){
int ret;
int pid = getpid();
char pidc[4];
struct sigaction sig;
memcpy(pidc,&pid,4);
// configure signal handler
sig.sa_flags = SA_SIGINFO;
sig.sa_sigaction = signalHandler_function;
sigaction(SIGIO, &sig, NULL);
g_fdCharDev = open(EXPDEV_DEVPATHNAME, O_RDWR);
printf("My process ID : %d\n", pid);
ret = write(g_fdCharDev, &pid, 1);
...
}
Sur le côté du noyau j'essaie d'utiliser send_sigqueue()
(avec sigqueue_alloc()
et sigqueue_free()
). Ceci est déclaré au include/linux/sched.h, line 2320 sous la forme extern
et défini dans kernel/signal.c, line 1560. Mais l'éditeur de liens dit cette fonction ne sont pas définies:
make -C /lib/modules/3.19.0-58-generic/build/ M=/home/alex/git/Kernel3/SignalHandling modules
make[1]: Verzeichnis »/usr/src/linux-headers-3.19.0-58-generic« wird betreten
CC [M] /home/alex/git/Kernel3/SignalHandling/ExpDev.o
Building modules, stage 2.
MODPOST 1 modules
WARNING: "sigqueue_free" [/home/alex/git/Kernel3/SignalHandling/ExpDev.ko] undefined!
WARNING: "sigqueue_alloc" [/home/alex/git/Kernel3/SignalHandling/ExpDev.ko] undefined!
WARNING: "send_sigqueue" [/home/alex/git/Kernel3/SignalHandling/ExpDev.ko] undefined!
CC /home/alex/git/Kernel3/SignalHandling/ExpDev.mod.o
LD [M] /home/alex/git/Kernel3/SignalHandling/ExpDev.ko
make[1]: Verzeichnis »/usr/src/linux-headers-3.19.0-58-generic« wird verlassen
Process terminated with status 0 (0 minute(s), 0 second(s))
0 error(s), 0 warning(s) (0 minute(s), 0 second(s))
vient ici la source raccourcie du LKM:
#include <linux/init.h> /// Macros used to mark up functions e.g. __init __exit
#include <linux/module.h> /// Core header for loading LKMs into the kernel
#include <linux/device.h> /// Header to support the kernel Driver Model
#include <linux/kernel.h> /// Contains types, macros, functions for the kernel
#include <linux/fs.h> /// Header for the Linux file system support
#include <asm/uaccess.h> /// Required for the copy to user function
#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/rcupdate.h>
#include <linux/slab.h>
struct siginfo *g_sig_info;
static struct sigqueue *g_sigqueue;
int g_usp_pid;
struct task_struct *g_sig_task;
static int __init expdev_init(void)
{
...
// setup signal
g_sigqueue = sigqueue_alloc();
g_sigqueue->info.si_signo = SIGIO;
g_sigqueue->info.si_signo = SI_QUEUE;
g_sigqueue->info.si_errno = 0;
...
}
static void __exit expdev_exit(void)
{
sigqueue_free(g_sigqueue);
...
}
static ssize_t dev_write(struct file *filep,
const char *buffer,
size_t len,
loff_t *offset)
{
...
memcpy(&g_usp_pid,buffer,4); // we know the PID comes with the buffer
// find task to the given PID
rcu_read_lock();
g_sig_task = pid_task(find_pid_ns(g_usp_pid, &init_pid_ns),
PIDTYPE_PID);
//send signal to user land
g_sigqueue->info.si_value.sival_int = 33;
ret = send_sigqueue(g_sigqueue, g_sig_task, 0);
...
}
Pourquoi est-il pas liable? Mon approche est-elle incorrecte?
Pour être utilisable dans le module noyau, le symbole doit être ** exporté ** (EXPORT_SYMBOL). La définition simple dans le fichier d'en-tête comme * extern * n'est pas suffisante. – Tsyvarev
@Tsyvarev Oui, je sais. Mais la fonction est également définie. Mais pourquoi ça ne lie pas? – Alex44
Votre module n'est pas compilé avec 'kernel/signal.c', qui * définit * la fonction donnée. Le module ne voit que les fichiers d'en-têtes, qui le déclarent simplement. À l'étape 'modpost', qui est en quelque sorte similaire à * relier * le module, seuls les symboles * exportés * sont résolus. C'est pourquoi vous obtenez * undefined symbol * error (warning) - la fonction donnée n'est ni définie par votre module, ni résolue à l'étape modpost. – Tsyvarev