2016-07-12 3 views
0

Ich versuche, eine Konfigurationsdatei (die sich an einem bestimmten Ort im Kernel befindet/generiert) für ein Modul zu lesen, das ich arbeite.Read Config File Zeile für Zeile in Kernel

Ich kann die Datei als Ganzes lesen, indem ich filp_open mit O_RDONLY-Flag (schreibgeschützt), aber ich kann mir nicht vorstellen, eine Möglichkeit, es Zeile für Zeile zu lesen.

aktuellen Code

f = filp_open("/etc/my_module",O_RDONLY, 0); 

if (f==NULL) { 
    printk("Error in loading config for birdge.\n"); 
    return 1; 
} else { 
    fs = get_fs(); 
    set_fs(get_ds()); 

    /* read line config here */ 
    f->f_op->read(f, buf, 128, &f->f_pos); 

    set_fs(fs); 
    printk("buf:%s\n",buf); 
} 

Linux Kernel Version: 3.8.0-29-generic

Was ich versuche, jede (n) Zeile in einen Puffer-Array (char * buf zu erreichen setzt [ 128] [128]) und später werde ich den Parameter und Wert mit reinem c zerstückeln.

Auf diese Weise können die Variablen aus der Konfigurationsdatei in der Laufzeit des Moduls verwendet werden und natürlich werde ich einige Bedingungen überprüfen, ob die Konfigurationen in Ordnung sind oder nicht.

Dank

+0

Nein, und das ist ziemlich genau der falsche Weg, es zu tun. –

+0

Sie sollten lesen, wie man fragt. Das ist eine schreckliche Frage. –

+0

Zur Inspiration für die Konfiguration komplexer Dinge schauen Sie sich an, wie der Kernel Netzwerk, Routing und Firewall konfiguriert. –

Antwort

2

[TL; DR: Vermeiden Sie das Lesen von Datei-System-Dateien direkt aus dem Kernel-Raum, so etwas zu tun.]

Sie haben es fast geschafft.

Das einzige, was Sie gerade brauchen, ist ein Array von Strings zuzuweisen mit kcalloc() (calloc() ähnlich wie libc, mit einem zusätzlichen Argument, das Sie [zum Zwecke des Beispiels] als GFP_KERNEL einstellen können), und dann die Schleife über die Datei mit f->f_op->read(f, &chr, 1, &f->f_pos); (lesen Char von Char, ähnlich wie Libc read(f, &chr, 1) ... Sie können dies später optimieren, indem Sie die Datei in Chunks lesen und die Chunks verarbeiten, um Tonnen von Lesevorgängen im Kernelraum zu vermeiden).

Dies gibt Ihnen einen ähnlichen Ansatz zu fgetc() unter Kernel Land, sowie eine ähnliche Schnittstelle zu calloc() für Ihre char *buf[] Array.

Sie können auch realisieren einen eigenen (schlecht optimiert) kfgetc() wie:

int kfgetc(struct file *f) { 
    char chr = 0; 

    f->f_op->read(f, &chr, 1, &f->f_pos); 

    return chr; 
} 

Und mit diesem Beispiel können Sie leicht eine kfgets() (nur Schleife mit kfgetc() erstellen, bis Sie einen finden, ‚\ n‘ oder es gibt nichts anderes zu lesen).

Beachten Sie, dass das, was Sie tun, im Allgemeinen keine gute Übung zu sein (um ehrlich zu sein, es ist eine wirklich schlechte Idee), aber beiseite legen (wie ich nicht weiß, warum Sie Ich mache es, das oben genannte ist ein guter Anfang, um es zum Laufen zu bringen. Wenn es funktioniert, dann schauen Sie, wo Sie es optimieren können (sehen Sie auch, wie andere Kernel-Komponenten Konfigurationen abrufen, wie von @ZanLynx angegeben). Einige andere nützliche Speicherverteilern für Ihren Fall

(seit kcalloc() kann Ihr Problem nicht lösen, wenn Sie nicht wissen, wie viele Zeilen auf die Datei ist): kmalloc() und krealloc() (ähnlich libc malloc() und realloc()).

4

Parsing Konfigurationsdateien im Kernel ist chaotisch und gefährlich. Tu das nicht.

Wenn Ihr Kernelmodul konfiguriert werden muss, geschieht dies in der Regel, indem Argumente übergeben werden, wenn das Modul geladen wird, z. insmod example.ko foo=123. Sie können diese Argumente in Ihrem Modul mit dem Makro module_param deklarieren.Informationen dazu finden Sie unter the Linux Kernel Module Programming Guide.

Wenn Ihr Modul eine komplexere Konfiguration erfordert, als dies mit Modulargumenten möglich ist, kann es für Ihr Modul sinnvoll sein, Endpunkte in sysfs für diese Konfiguration zu erstellen. Beachten Sie, dass dies bedeutet, dass Ihr Modul höchstwahrscheinlich ein Userspace-Hilfsskript benötigt, um es zu konfigurieren. Das ist normal und in Ordnung. Das Schreiben dieses Skripts in den Benutzerbereich ist viel einfacher und sicherer, als wenn es im Kernel ausgeführt wird.