в продолжение темы загрузка/выгрузка драйверов во фре
:))необходимо реализовать такую фичу:
есть драйвер висящий в кернеле как чарактер девайс.
нужно чтобы когда юзер делает
ptr = open("/dev/somedev",0);
сздавался /dev/somedev0
если до закрытия /dev/somedev0 юзер еще раз вызывает
ptr = open("/dev/somedev",0);
сздавался /dev/somedev1
и т.д.
а при закрытии дескриптора юзером somedeN удалялся, ну или помечался неиспользуемым чтобы при следующем open'е открывался неиспользуемый девайс.
тоесть, короче нужно чтобы дескрипторы открывались в монопольном режиме.
докапался до того что это делается с помощью dev_clone, но никак не пойму всей глубины мыслей разработчиков этой фичи.
делаю следующее:
при загрузке своего модуля регистрирую евент-хендлер
clone_setup(&sc->mruclones);
sc->eh_tag = EVENTHANDLER_REGISTER(dev_clone, mru_clone, 0, 1000);
функция mru_clone делает следующее
... mru_clone(...)
{
int unit, i;
if (*dev != NULL) return;
if (strcmp(name, "mru") == 0)
unit = -1;
else if (dev_stdclone(name, NULL, "mru", &unit) != 1) return;
if (unit != -1 && unit > MRU_MAXUNIT) return;
i = clone_create(&sc->mruclones, sc->mru_sw, &unit, dev, 0);
if (i)
*dev = make_dev(sc->mru_sw, unit2minor(unit), UID_ROOT, GID_WHEEL, 0600, "mru%d", unit);
if (*dev != NULL) {
dev_ref(*dev);
(*dev)->si_flags |= SI_CHEAPCLONE;
dev->si_drv1 = NULL;
}
}
тоесть девайс проклонировали, флаг клонера ему поставили.
тогда при открытии делаю следующее
int mru_open(struct cdev *dev, int flag, int mode, struct thread *td)
{
struct usrcl *cl = NULL;
cl = dev->si_drv1;
if(!cl) {
malloc(cl,...);
dev->si_drv1 = cl;
}
}
тоесть, как тут мне посоветовали, система считает девайс незанятым пока у него dev->si_drv1 == NULL. так я так и делаю - при клонировании обнуляю это поле. при открытии - заполняю его своими данными.
только вот фича в том что если я в юзермоде сделаю один раз open("/dev/mru",0) - все ок.
mru_clone вызывается, /dev/mru0 клонер создается и т.д., но делая второй open до закрытия первого оказывается что сразу же (без никаких клонирований вызывается d_open для ранее созданного /dev/mru0)
подскажите плз в чем грабли..
понимаю что чегото я нетак делаю.. но вот что??
заранее спасибо.