>весь драйвер - слоистый (непосредственно контрол железки - мультиплексор - интерфейсный модуль,
>модуль доступа юзерей[с ним собссно щас и парюсь]), а так как
>BSD не жалует такие фичи (ну или я не нашел ничего
>билт-ин как слои реализовывать) то сделал еще свой манагер всех загруженых
>модулей. Модуль доступа юзверей - как понимаю, интерфейс (API) для управления из пользовательского режима.
>смысл примерно такой:
>при старте системы манагер стартует первым и потом каждый загружающийся модуль (из
>входящих в мой драйвер) регистрируется у него (отдает структуру с указателями
>на свои io/ctl функции и параметры ) взамен получает указатель на
>соответствующие функции манагера.
>т.е. весь трафик в ядре идет через манагер.. может это и медленнее
>зато более структурно и легче ресурсы шарить.
На стадии установки параметров скорость работы не принципиальна - это да. И ориентация на модульность - это хорошо.
>когда загружается модуль доступа из юзермода вобщем то никаких действий не происходит..
>
>создается мутекс там.. память выделяется под структуры и под будущий лист клиентов..
>
>и создается ОДИН!!! cdev. один - потому что неизвесно сколько пользователей может
Извини, но это зря. Иначе d_open и d_close будут с ума сходить, то переоткрывая уже используемые рессурсы, то перезакрывая не принадлежащий им.. Смысл cdev - это файловый дескриптор. По другому - поток управления и данных, который может быть зашарен на несколько процессов. Если ты попытаешься из одного процесса установить два и более соединения к этому модулю, то система между ними не будет видеть никакой разницы. В каком порядке должен в этом случае выполняться d_close, и как должен поступать в этом случае d_open, открывая второй дескриптор ? Ядро не передает дополнительной информации об этом, кроме той, что указана в cdev и в proc.
Кстати, чисто принципиально возможно посроить зловредный код, если проверка выполняется только по одному pid и файловый дескриптор мог быть передан потомку без закрытия. К сожалению структура proc другой идентифицирующей информацией не располагает, что процесс именно тот, что изначально его открыл, а не маскируется его идентификатором
>быть и в каком порядке они будут появлятся/изщезать.
>можно было бы наделать клонов(для сетевых интерфейсов так и делаю).. но клоны
>нада будет еще из юзерспайса менеджерить.. создавать их, удалять.. а не
>факт что клиент будет рутовыми правами обладать.
Чтобы автоматически создавать девайс, не нужно никакого управления из вне. Достаточно правильно настроить eventhandler с dev_clone параметром. Хотя я думаю, ты уже что то подобное уже делал. Создание клонов можно возложить на d_open, а удаление, на d_close. Вернее dev_clone создает свободный cdev для того, чтобы к нему можно было обратиться через d_open.
cdev считается неиспользуемым системой, если cdev->si_drv1 == NULL. Но зато к нему теперь можно обращаться как к "/dev/newdevice123", и если он не используется, то разрешить вызов d_open (хотя на самом деле это d_open проверяет, используется он, или нет).
>када юзер в клиентской программе делает open - создается структура с его
>параметрами(пока только access mode), она регистрируется у манагера. B вносится в
>лист активных клиентов
>типа так
>
>extern struct mru_softc *sc;
>
>int mru_open(struct cdev *dev, int flag, int mode, struct thread *td)
>{
> struct proc *procp = td->td_proc;
> struct usrcl *cl
> = NULL;
>.
>.
> MALLOC(cl, struct usrcl*, sizeof(*cl), M_TKR_MRU_SC, M_WAITOK | M_ZERO);
> if(cl == NULL) {
> ...
> }
> cl->id = procp->p_pid;
>.
>.
> if((err = tkr_modregister(cl->id, "name", (void*)(cl))))
> return err;
>
> sc->clcnt++;
> LIST_INSERT_HEAD(sc->cldb, cl, cl_next); // insert to client list
>.
>.
>}
все это в MP-Safe ? (d_flag|D_NEEDGIANT) == 0 ?
>ну тока эт не все канечна.. мутексом там все закрыто критическое.
да, без мутексов в ядре - никуда
С такими большими сообщениями наверно лучше удалиться в почту или в аську ?