2016-06-21 4 views
0

Я работаю над обновлением драйверов ядра для работы с linux kernel 4.4.0 на Ubuntu 16.0.4. Драйверы в последний раз работали с ядром linux 3.9.2. В одном из модулей у нас есть записи procfs, созданные для чтения/записи значений мониторинга бортового вентилятора. Мониторинг вентилятора используется для чтения/записи температуры или модуляции процессора или графического процессора и т. Д. значения.Как заменить функцию чтения для записи procfs, которая вернула EOF и количество байтов, прочитанных как?

Модуль использует следующий API для создания Procfs записей:

struct proc_dir_entry *create_proc_entry(const char *name, umode_t 
mode,struct proc_dir_entry *parent); 

Что-то вроде:

struct proc_dir_entry * proc_entry = 
create_proc_entry("fmon_gpu_temp",0644,proc_dir); 
proc_entry->read_proc = read_proc; 
proc_entry->write_proc = write_proc; 

Теперь read_proc реализуется что-то таким образом:

static int read_value(char *buf, char **start, off_t offset, int count, int *eof, void *data) { 
    int len = 0; 
    int idx = (int)data; 

    if(idx == TEMP_FANCTL) 
     len = sprintf (buf, "%d.%02d\n", fmon_readings[idx]/TEMP_SAMPLES, 
       fmon_readings[idx] % TEMP_SAMPLES * 100/TEMP_SAMPLES); 
    else if(idx == TEMP_CPU) { 
     int i; 
     len = sprintf (buf, "%d", fmon_readings[idx]); 
     for(i=0; i < FCTL_MAX_CPUS && fmon_cpu_temps[i]; i++) { 
      len += sprintf (buf+len, " CPU%d=%d",i,fmon_cpu_temps[i]); 
     } 
     len += sprintf (buf+len, "\n"); 
    } 
    else if(idx >= 0 && idx < READINGS_MAX) 
     len = sprintf (buf, "%d\n", fmon_readings[idx]); 
    *eof = 1; 
    return len; 
} 

Эта функция чтения определенно предполагает, что пользователь предоставил достаточно буферного пространства для хранения тем значение. Это правильно обрабатывается в программе пользовательского пространства. Кроме того, для каждого вызова этой функции значение считывания находится в совокупности, и поэтому для последующих чтений для одного и того же значения температуры нет необходимости/необходимости. Плюс, если я использую программу «cat» в этой записи procfs из оболочки, программа «cat» правильно отображает значение. Это поддерживается, я думаю, настройкой EOF для истинного и возвращаемого количества считанных байтов.

Новые ядра linux больше не поддерживают этот API.

Мой вопроса:

Как я могу изменить этот API для нового Procfs структуры API сохраняя функциональность так же, как: каждый чтение должно возвращать значение, программу «кот» также должно работать нормально и не вдаваться в бесконечный цикл ?

ответ

1

Основной пользовательский интерфейс для чтения файлов в Linux - read(2). Его пара в пространстве ядра .read функция в struct file_operations.

Каждого другой механизм для файла для чтения в пространстве ядра (read_proc, seq_file и т.д.) на самом деле является (параметризованной) реализация .read функции.

Единственный способ вернуть ядру индикатор EOF в пользовательское пространство возвращает 0 как количество прочитанных байтов.

Даже read_proc реализация у вас есть 3,9 ядро ​​фактически реализует eof флаг как возвращающая 0 на следующий вызов. И cat фактически выполняет второй вызов read для поиска того, что файл завершен.

(Кроме того, cat выполняет более 2 инвокации чтения: сначала с 1 в качестве графа, второй с подсчета равным размеру страницы минус 1 и последний с остальными подсчет.)

Простейший способ реализации «одноразового» чтения - использовать seq_file в режиме single_open().

+0

Я добавил реализацию функции чтения в вопрос. Я понимаю, что я могу вызывать функцию чтения столько раз из пользовательского пространства, и каждый раз, когда получаю обновленное значение температуры. правильно ? Кроме того, здесь не поддерживаются смещения файлов, поэтому каждый вызов для чтения здесь похож на чтение переменной. программа «cat» отлично работает с этой реализацией, не вдаваясь в бесконечный цикл. – Monku

+0

Проблема для меня в том, что как я реализую нечто похожее с новым ядром api. То есть, я должен иметь возможность вызывать чтение несколько раз при открытии одного файла. Если я использую seq_file с single_open, мне придется закрыть файл, прежде чем я могу позвонить во второй раз, верно? – Monku

+1

«Если я использую seq_file с single_open, мне нужно будет закрыть файл, прежде чем я могу позвонить во второй раз, правильно?» - Да, когда файл читается до EOF, вам нужно сбросить позицию чтения, прежде чем читать его снова. Это можно сделать с повторением файла ('close()' + 'open()') или с 'lseek()' в позицию 0. Но 'single_open()' не означает, что вы можете печатать только одно значение для вывода : внутри '.show' вы можете выполнять аналогичные циклы, как в вашем' read_proc'. Но лучше использовать полную силу 'seq_file' с' seq_open() 'вместо' single_open() '. – Tsyvarev

 Смежные вопросы

  • Нет связанных вопросов^_^