implémenter une liste d’opérations de lecture dans debugfs

J’implémente un module de kernel. en utilisant plusieurs techniques. L’un d’entre eux est de donner en lecture / écriture à différentes variables de module. J’ai été capable de lire / écrire toutes les variables sauf la liste que j’ai dans mon module. la liste liée:

static struct node { struct list_head list; unsigned int x; struct tm time; }; 

Je voudrais avoir un fichier correspondant dans debugfs qui imprimera la liste complète. J’ai essayé toutes les fonctions de lecture ‘simples’, mais aucune d’entre elles ne fonctionne réellement .. 🙁

Vous pouvez lire la liste en utilisant une fonction similaire à celle-ci:

 struct k_list { struct list_head links; int data; }; struct k_list my_list; static ssize_t pop_queue(struct file * file, char *buf, size_t count, loff_t *ppos) { struct list_head *pos, *q; struct k_list *tmp; printk(KERN_INFO "--Listing inserted numbers--"); list_for_each_safe(pos, q, &my_list.links) { tmp = list_entry(pos, struct k_list, links); printk(KERN_INFO "object: %d ", tmp->data); } printk(KERN_INFO "--End of list--"); return count; } 

Le kernel Linux fournit une interface seq_file pour implémenter facilement les fichiers énumérés, tels que les listes.

Tout ce dont vous avez besoin est de fournir jusqu’à 4 fonctions qui encapsulent une énumération:

 // Assume this is the head of your list. static struct my_list; // Start iteration static void *my_start (struct seq_file *m, loff_t *pos) { // Use ready-made helper for lists. return seq_list_start(&my_list, *pos); } // Next iteration static void * my_next(struct seq_file *m, void *v, loff_t *pos) { // Use ready-made helper for lists. return seq_list_next(v, &my_list, pos); } // Output on single iteration static int my_show (struct seq_file *m, void *v) { // Get original structure struct node* node = list_entry(v, struct node, list); // Eg, print content of 'x' field seq_printf(m, "%u,", node->x); return 0; // Success } static struct seq_operations my_seq_ops = { .start = &my_start, .stop = NULL, // Not needed in this case .next = &my_next, .show = &my_show }; 

La structure avec ces fonctions doit être passée à seq_open() lors de l’ouverture du fichier:

 static int my_open(struct inode* inode, struct file* filp) { return seq_open(filp, &my_seq_ops); } 

Et utilisez seq_read tant que fonction .read dans les opérations sur les fichiers:

 static struct file_operations my_file_ops = { .open = &my_open, .read = &seq_read, }; 

Notez que l’ écriture dans un tel fichier que vous devez implémenter manuellement , seq_lock ne vous aide pas.