Я работаю над обновлением драйверов ядра для работы с 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 сохраняя функциональность так же, как: каждый чтение должно возвращать значение, программу «кот» также должно работать нормально и не вдаваться в бесконечный цикл ?
Я добавил реализацию функции чтения в вопрос. Я понимаю, что я могу вызывать функцию чтения столько раз из пользовательского пространства, и каждый раз, когда получаю обновленное значение температуры. правильно ? Кроме того, здесь не поддерживаются смещения файлов, поэтому каждый вызов для чтения здесь похож на чтение переменной. программа «cat» отлично работает с этой реализацией, не вдаваясь в бесконечный цикл. – Monku
Проблема для меня в том, что как я реализую нечто похожее с новым ядром api. То есть, я должен иметь возможность вызывать чтение несколько раз при открытии одного файла. Если я использую seq_file с single_open, мне придется закрыть файл, прежде чем я могу позвонить во второй раз, верно? – Monku
«Если я использую seq_file с single_open, мне нужно будет закрыть файл, прежде чем я могу позвонить во второй раз, правильно?» - Да, когда файл читается до EOF, вам нужно сбросить позицию чтения, прежде чем читать его снова. Это можно сделать с повторением файла ('close()' + 'open()') или с 'lseek()' в позицию 0. Но 'single_open()' не означает, что вы можете печатать только одно значение для вывода : внутри '.show' вы можете выполнять аналогичные циклы, как в вашем' read_proc'. Но лучше использовать полную силу 'seq_file' с' seq_open() 'вместо' single_open() '. – Tsyvarev