Ich versuche einen Signalaufruf von einem ladbaren Kernelmodul in eine Benutzeranwendung zu implementieren. Die Anwendung verwendet sigaction
, um den Signalaufruf zu verarbeiten, und später muss sie sival_int
verwenden, um verschiedene Aktionen von switch
und case
zu behandeln.Kernel: mit sigqueue-Funktionen
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);
...
}
auf Kernel-Seite versuche ich (mit sigqueue_alloc()
und sigqueue_free()
zusammen) send_sigqueue()
zu verwenden. Dies wird in include/linux/sched.h, line 2320 als extern
deklariert und in kernel/signal.c, line 1560 definiert. Aber die Linker sagt diese Funktionen nicht definiert sind:
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))
Hier kommt die verkürzte Quelle des 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);
...
}
Warum es nicht verknüpfbar ist? Ist meine Vorgehensweise falsch?
Um im Kernelmodul verwendbar zu sein, sollte das Symbol ** exportiert werden (EXPORT_SYMBOL). Einfache Definition in Header-Datei als * extern * ist nicht ausreichend. – Tsyvarev
@Tsyvarev Ja, ich weiß. Aber die Funktion ist auch definiert. Aber warum verlinkt es nicht? – Alex44
Ihr Modul ist nicht kompiliert mit 'kernel/signal.c', welches * die angegebene Funktion definiert. Das Modul sieht nur Header-Dateien, die es nur deklariert. In der 'modpost'-Phase, die dem * linking * des Moduls ähnelt, werden nur * exportierte * Symbole aufgelöst. Deshalb erhalten Sie * undefined symbol * error (warning) - angegebene Funktion wird weder von Ihrem Modul definiert, noch in der Modpost-Phase gelöst. – Tsyvarev