From owner-freebsd-arch Sat Jun 30 1: 8: 1 2001 Delivered-To: freebsd-arch@freebsd.org Received: from critter.freebsd.dk (critter.freebsd.dk [212.242.86.163]) by hub.freebsd.org (Postfix) with ESMTP id 3524937B405 for ; Sat, 30 Jun 2001 01:07:56 -0700 (PDT) (envelope-from phk@critter.freebsd.dk) Received: from critter (localhost [127.0.0.1]) by critter.freebsd.dk (8.11.3/8.11.3) with ESMTP id f5U87in33347 for ; Sat, 30 Jun 2001 10:07:46 +0200 (CEST) (envelope-from phk@critter.freebsd.dk) To: arch@freebsd.org Subject: DEVFS, devd and all that... From: Poul-Henning Kamp Date: Sat, 30 Jun 2001 10:07:44 +0200 Message-ID: <33345.993888464@critter> Sender: owner-freebsd-arch@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG Unfortunately I will not be able to attend online today, so instead you'll have to take this email as my input in the DEVFS/devd discussion. Considering the infrequency of device create events and the fact that nobody so far has come up with a good example which cannot be handled otherwise I prefer that devd does not need to be involved in all device creates. I'm also in favour of being able to run without devd on lightweight systems (picobsd, jails...) My ideas there for is this: The device driver, in make_dev() specifies: a device type ("disk", "tape", "tty", "special") a device name (as now: fd0a, ttyq3 etc) We implement a list of rules which is used to define what should happen at device create: name="ad0s1a" : mode=0600 owner=root group=wheel name="fd0*" : mode=0666 owner root group=wheel chown_on_open=yes type="disk" : mode=0640 owner=root group=operator type="pty" : mode = 0666 owner=root group=operator chown_on_open=yes type="tty" : mode = 0600 owner=root group=tty That way we have a flexible and configurable policy even running without devd and we have a means for devd to express special wishes. One particular action could be: type="ttyd*" : ask_devd=yes which would not enter the devicename into the directory, until devd has told os what to do. These rules can also be used to provide the filtering of devices in a jail: type="*" : ignore=yes We may need more than name and class though, maybe an attachment: attachment="usb" : ask_devd=yes As much as it looks like BASIC, I propose to use linenumbers to order and specify the sequence of the rules. Sets of rules have a name, and a given mountpoint can be associated with a given rule-set: mount -t devfd -o rules=jailrules devfs /home/jail01/dev Regarding "arrive" and "depart" events and devd. It has correctly been observed that we need to enforce a strict ordering to make sure we don't have a device re-arriving while devd is still dettaching the previos instance. There is no correct way to solve this problem, except not reusing unit numbers until devd releases them. Problem with that is that the driver is stuck in destroy_dev until devd (and any subprocesses) return. This obviously doesn't work in practice. In particular not if it's the disk driver getting stuck and devd tries to access the disk... One solution would be to add a new driver entrypoint so that destroy_dev() only queues the request, and all further cleanup happens when driver->cleanup() is called by devfs after devd returns ... messy. Another solution would be to simply not recycle unit numbers. This has some serious disadvantages too. The best I have come up with so far is to hide the magic in devfs we add a state called "hidden" which means that the dev_t will is not yet discovered by the filesystem side of devfs. make_dev() on parsing the rules described above finds a "ask_devd=yes" entry and sets the hidden bit on the dev_t. devd is notified and it uses some magic to "unhide" the device which makes it appear in the directories. Devd subsequently does what needs done for that device. life goes on. driver calls destroy_dev(). The dev_t is turned into a "dead_dev_t" which has a cdevsw[] which returns ENXIO or whatever is correct, the dev_t is marked "recycling" and devd is notified. If the driver calls make_dev again at this point, a new dev_t is created as per above, and chained off the dev_t in "recycling" state but otherwise not acted on and not visible unless you have the pointer to it. When devd says the "recycling" dev_t is "done", that dev_t is destroyed and the "new" dev_t hanging off it is found and we start over from above. For this to work, drivers need to be very careful to chose one "master" dev_t for each conceptual "foo" they have, and even more careful to chain other dev_t's off that dev_t. Otherwise there will be no way to remain consistent and sane during the above gyrations. The disadvantage which could require some kind of "DWIM" superuser tool is that a device could be stuck in limbo of devd gets confused or stuck. This may be a devd implementation issue. Input most welcome... -- Poul-Henning Kamp | UNIX since Zilog Zeus 3.20 phk@FreeBSD.ORG | TCP/IP since RFC 956 FreeBSD committer | BSD since 4.3-tahoe Never attribute to malice what can adequately be explained by incompetence. To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-arch" in the body of the message