«proc_fops» имеет неполный тип «struct proc_ops»

Я пытаюсь собрать модуль ядра Linux, и, в частности, у меня есть эти файлы в одной папке:

  • syscalls.h/.c
  • user.h/.c
  • proc.h/.c
  • module.h/.c

Я хочу разместить файл конфигурации в каталоге /proc, поэтому в файлах proc.h/.c я определил драйвер для правильного управления им:

проц.ч

#include <linux/proc_fs.h>

extern struct proc_ops proc_fops;

ssize_t read_proc(struct file *filp, char *buf, size_t count, loff_t *offp );
ssize_t write_proc(struct file *filp, const char *buf, size_t count, loff_t *offp );

proc.c

#include "proc.h"

#if LINUX_VERSION_CODE < KERNEL_VERSION(5,6,0)
struct file_operations proc_fops = {
        .read = read_proc,
        .write = write_proc
};
#else
struct proc_ops proc_fops= {
        .proc_read =  read_proc,
        .proc_write =  write_proc
};
#endif

//...

ssize_t write_proc(struct file *filp, const char *buf, size_t count, loff_t *offp ) {
    //...
}
ssize_t read_proc(struct file *filp, char *buf, size_t count, loff_t *offp ) {
    //...
}

Я записал его в отдельный блок кода «proc», потому что хочу, чтобы файл управлялся как user.c, так и syscalls.c.

Я реализовал только вызов user.c, то есть:

proc_create(PROCFILE, 0, NULL, proc_fops);

но я получаю эту ошибку:

error: ‘proc_fops’ has an incomplete type ‘struct proc_ops’
  182 |     proc_create(PROCFILE, 0, NULL, proc_fops);
      |                                             ^~~~~~~~~

и не могу найти в чем проблема. У кого-нибудь есть какие-нибудь подсказки? Моя версия ядра (uname -r) — 5.4.0-192-generic.

Ваш #ifdef неверен; Ядра 5.4 (и 5.5) все еще используют struct file_operations, proc_ops является новым для 5.6 и более поздних версий. Учитывая, что "proc.h" не является включенным в ядро ​​Linux, и вы предоставляете там пустое предварительное объявление, возникнет эта ошибка. Вы должны получить правильное определение из proc_fs.h, если оно есть в версии ядра, для которой вы собираете.

FrankH. 21.08.2024 13:35

Привет, спасибо за ваш ответ. Учитывая исправленный #ifdef (теперь правильный в отредактированном посте), не могли бы вы объяснить, что вы имеете в виду? У меня есть #include <linux/proc_fs.h> и в proc.h, и в proc.c.

G. Ianni 21.08.2024 13:50
owner: THIS_MODULE Что это должно быть? Очередное утомительное расширение GNU или...?
Lundin 21.08.2024 14:41

На самом деле скопировано из другого кода: P, но комментирование не меняет результат (кстати: теперь удалено из сообщения)

G. Ianni 21.08.2024 14:48

Я имел в виду запятую. Это неверный синтаксис C внутри списка инициализаторов. Судя по всему, это расширение GNU, которое устарело в какой-то момент еще в меловой период.

Lundin 21.08.2024 15:20

Вы имели в виду использование обозначения .read=read_proc вместо обозначения read:read_proc? В таком случае менять наверняка правильно, но проблема все равно остается - ОТРЕДАКТИРОВАНО В ПОСТЕ

G. Ianni 21.08.2024 15:28

Глядя на этот код на Github, может показаться, что определение структуры находится ни в proc.h, ни в proc.c, а предположительно в каком-то другом заголовке, включенном в proc.h? #include <machine/proc.h> вероятно, так что, возможно, тогда его не хватает.

Lundin 21.08.2024 15:34

Возможно, это связано: stackoverflow.com/questions/18564550/…

Lundin 21.08.2024 15:35

На самом деле proc.h и proc.c — это файлы, которые я определил, они не существуют в ядре Linux. Единственная ссылка на ядро ​​— это импорт в proc_fs.h

G. Ianni 21.08.2024 15:38

В любом случае у вас должно быть где-то определение структуры, иначе вы получите сообщение об ошибке «неполный тип».

Lundin 21.08.2024 15:49

Разве определения extern struct proc_ops proc_fops; (proc.h) недостаточно? (Я имею в виду, нет, это риторика, но почему?

G. Ianni 21.08.2024 16:10

Это предварительное заявление, а не определение. Отсюда неполный тип: вы сообщаете компилятору, что «пока вот структура, о деталях расскажу позже (в той же единице перевода)»

Lundin 21.08.2024 16:15

Хорошо, возможно, основная причина проблемы — отсутствие определения. Не могли бы вы показать пример? Чтобы я мог узнать, что делать и как все организовать, чтобы решить проблему.

G. Ianni 21.08.2024 16:19
proc_create(PROCFILE, 0, NULL, proc_fops); должно быть proc_create(PROCFILE, 0, NULL, &proc_fops);. (Но proc_fops мог быть объявлен с неправильным типом #include "proc.h", в зависимости от версии ядра.)
Ian Abbott 21.08.2024 16:25

Это действительно базовые вещи... struct proc_ops { int proc_read ; int proc_write; /* ... */ }; Или какие бы типы они ни имели — я ничего не знаю о том, что должен делать этот код.

Lundin 21.08.2024 16:27

Примечательно, что struct proc_ops proc_fops= { .proc_read = read_proc, .proc_write = write_proc }; — это просто объявление переменной со списком инициализаторов. Он не определяет структуру. Возможно, это источник путаницы.

Lundin 21.08.2024 16:28

Действительно ли «user.c» должен знать о proc_fops? Разве вы не можете просто вызвать proc_create из функции интерфейса в «proc.c» (вызываемой из «user.c») и объявить proc_fops, proc_read и proc_writestatic?

Ian Abbott 21.08.2024 16:34

Вам нужно #include <linux/version.h>, чтобы определить макросы LINUX_VERSION_CODE и KERNEL_VERSION(a,b,c).

Ian Abbott 21.08.2024 16:39

Прежде всего, спасибо за вашу помощь, я очень ценю ваш вклад. У меня есть обновление: поскольку моя версия ядра <5.6.0, мне приходится использовать file_operations (импортировано из fs.h) вместо proc_ops (импортировано из proc_fs.h). Итак, при изменении объявления в proc.h с proc_ops на files_operations оно компилируется без ошибок. Я все еще экспериментирую, но это может быть способом решения (и это имеет смысл). Возможно, я мог бы использовать тот же #if, что и в proc.c.

G. Ianni 21.08.2024 16:42

@IanAbbott, спасибо, уже включено (вырезал пост для удобства чтения)

G. Ianni 21.08.2024 16:42

Не имеет значения, имеет ли proc_fops неполный тип при вызове proc_create, если он имеет правильный неполный тип. Вы просто называете это неправильно. Он ожидает указателя.

Ian Abbott 21.08.2024 16:46

Забыл упомянуть: теперь вызов proc_create — это proc_create(PROCFILE, 0, NULL, &proc_fops); (теперь с &). Это тот указатель, на который вы ссылаетесь?

G. Ianni 21.08.2024 16:53

Решено (см. ответ). Спасибо всем за вашу поддержку!

G. Ianni 23.08.2024 19:52
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
23
72
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Решена, проблема заключалась в том, что объявление в proc.h содержало только объявление для типа proc_ops, действительное только для версии ядра выше 5.6.0. Итак, для полного соответствия, я просто изменил его на:

проц.ч

#if LINUX_VERSION_CODE < KERNEL_VERSION(5,6,0)
extern struct file_operations proc_fops;
#else
extern struct proc_ops proc_fops;
#endif

а также правильно указать указатель с & в:

proc.c

proc_create(PROCFILE, 0, NULL, &proc_fops);

Другие вопросы по теме