Hi,

getting hints and ideas from Laurent and Natanael, I found we can get most flexibility, when when try to do some modularization of the steps done by mdev.

At fist there are two different kinds of work to deal with:

1) The overall operation and usage of netlink
2) Extending the mdev.conf syntax

Both are independent so first look at the overall operation ... and we are currently looking at operation/functionality. This neither means they are all separate programs/applets. We may put several functionalities in one applet and distinguish by some options. First look at, what to do, then decide how to implement:

mdev needs to do the following steps:

- on startup the sys file system is scanned for device entries

- as a hotplug handler for each event a process is forked passing information in environment variables

- when using netlink a long lived daemon read event messages from a network socket to assemble same information as the hotplug handler

- when all information for an event has been gathered, mdev needs to search it's configuration table for the required entry, and then ...

- ... do the required operations for the device entry


That is scanning the sys file system, hotplug event handler and netlink event daemon trigger operation of the mdev parser. Forking a conf file parser for each event is much overhead on system startup, when many event arrive in short amount of time. There we would benefit from a single process reading from a pipe, dieing when there are no more events and reestablish when new events arrive.

Both the sys file system scanner and a netlink daemon could easily establish a pipe and then send device commands to the parser. The parser reads mdev.conf once and creates a in memory table, then reads commands from the pipe and scans the memory table for the right entry. When EOF on pipe read, the parser can exit successfully.

The sys file system scanner (startup = mdev -s) can create the pipe, then scan the sysfs and send the commands to the parser. When done, the pipe can be closed and after waiting for the parser process just exit.

The netlink daemon, can establish the netlink socket, then read events an sanitize the messages. When there is any message for the parser, a pipe is created and messages can be passed to the parser. When netlink is idle for some amount of time, it can close the pipe and check the child status.

Confusion arise only on the hotplug handler part, as here a new process is started for every event by the kernel. Forking a pipe to send this to the parser would double the overhead. But leaving the parser running for some amount of time, would only work with a named fifo, startup of the parser when required and adds timeout management to the parser ...

... but ok, do we look at an alternative: Consider a small long lived daemon, which create a named fifo and then poll this fifo until data get available. On hotplug event a small helper is started, which read it's information, serializes then write the command to the fifo and exit. The long lived daemon sees the data (but does not read), then forks a parser and gives the read end of the pipe to the the parser. The parser reads mdev.conv once, then processes commands from the fifo. Now we are at the situation where the timeout needs to be checked in the parser. When there are no more events on the fifo the parser just dies successfully (freeing used memory). This will be detected by the small long lived daemon, which check the exit status and can act on failures (e.g. run a failure script). On successful exit of the parser the daemon starts again waiting for data on the fifo (which he still hold open for reading and writing). This way the hotplug helper will benefit from a single run parser on startup, but memory used by the conf parser is freed during normal system operation. The doubling of the timeout management in netlink daemon and parser can be intentional when different timeouts are used. Where a small duration for the idle timeout of netlink can be chosen, the parser itself does use a higher timeout, which only triggers when the hotplug helper method is used.

yes, there are some rough corners, but we are at the phase of brain storming. Beside those corners do we get a modular system, which avoid respawning/rereading the conf table for every event, but frees memory when there are no more events. Even the hotplug helper method will benefit, as the helper process can exit, as soon as the command has been written to the fifo. The parser reads serialized commands from the pipe and process required actions.

May be we should consider using that small parser helper daemon and the named fifo in all cases. sys file system scanner, hotplug helper and netlink daemon will then just use the fifo. This would even allow to use the same fifo to activate the mdev parser from a user space program (including single parser start for multiple events).

Don't be afraid about the many functions. We can put this together in one program and make mdev a wrapper around this. The question is, do we want to do this? the memory usage may be smaller when the fifo helper daemon and/or the netlink reader daemon are separate programs. On the other side the code of BB will always be loaded and should be reused, even on NOMMU systems, so the code size does not matter much, only stack and data sizes. The data sizes are kept es small as possible in the long lived processes, but the BB infrastructure may add some overhead (how many? does that matter?).

With mdev as a wrapper we could have:

mdev (no parameter)
  - hotplug helper
    (how to get FIFO_PATH? use always default?)

mdev -i
  - do the initial operations from mdev.conf
    (e.g. mounts, subdirs, symlinks)

mdev -f [FIFO_PATH]
  - start the fifo helper daemon and create the fifo
    (suggesting default FIFO_PATH /dev/ctl/mdev)

mdev -h [FIFO_PATH]
  - install mdev as a hotplug helper
    (needs to give FIFO_PATH to the hotplug helper, how?)

mdev -n [FIFO_PATH]
  - start the netlink reader daemon

mdev -s [FIFO_PATH]
  - scan the sys file system and populate device filesystem

mdev -p
  - mdev.conf parser, reading from stdin (no fifo, no helper daemons)
This way you may implement your own hotplug handling but continue to use the mdev.conf functionality.

The options i f h and s may be combined, same for i f n and s, for which will allow to startup the system with a single call, doing init, loading required daemon(s), and scan sys file system for initial population. h n and s include f, when fifo does not exist.

Alternative to FIFO_PATH: Setting "#fifo" option in /etc/mdev.conf and let all programs use this value. As default use /dev/ctl/mdev or /dev/.mdev-fifo (when /dev/ctl does not exist). Don't use /run, /var/run, or /tmp as default, are they writable at this time? /dev should be, as we are populating the device nodes. Sound simple but needs to look in mdev.conf for fifo name on every hotplug event -> better to always use /dev/.mdev-fifo? Suggestions?


Also Natanaels idea of modprobe has not bean dropped. This could be done in a similar way. May be it is wise to synchronize this with the mdev parser and use only one fifo to the parser, forwarding the requests to modprobe (simple pipe, modprobe reads from pipe until EOF).

--
Harald

_______________________________________________
busybox mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/busybox

Reply via email to