[asterisk-dev] zaptel sysfs / device model

MENEAULT Maxime maxmeneault at free.fr
Wed Oct 31 05:11:26 CDT 2007


Well You already know my feelings about all that but I will try to 
answer anyway.

> where meneault has started his own implementation of sysfs support.
If you have any questions about my implementation please ask. I know 
that the code uses a lot of CPP power which is hard to understand when
not properly commented that's why my comments are quite verbose.

For the ones that are not aware of my implementation, the idea
is to export via sysfs a lot of information (at least as read-only 
attributes) for spans and channels so that user-space applications
like (udev, startup scripts, asterisk) could benefit from it.

The main issue we are dealing with here is to get as much as information 
as to know if a channel is properly configured or not and to guess some 
information so a to auto-configure it.

Please note that the exporting information via sysfs may go far beyond 
this simple scope and may give user-space applications some useful 
information to track the state of channels/spans (without opening the 
channel) and react accordingly.
(e.g watchdog program)

> This raises a number of issues with the sysfs support:
> 
> The current sysfs support has a number of major problems:
> 
> 1. spans are not represented in any way. Just channels.
> 2. And even channels are not really represented. Only just enough to
> create device files. But they don't get to have their own attributes.
> 3. The device class interface is considered deprecated and will
> eventually be removed from the kernel.
I completely agree, current sysfs implementation in zaptel is minimal,
that's what my sysfs implementation (and yours) tries to fix.

Point 3 would only be a question of replacing class_device with device
on newer kernels.

My implementation tries to keep backward compatibility with existing 
zaptel config/udev scripts (adding new information on the same minimal 
layout) so as to add this new feature without breaking distributions and 
user's scripts.

> For instance, /etc/{sysconfig,default}/zaptel will contain overrides to
> the defualt configuration (the default will be ks to analog ports and
> some combination of timing priorities with bchan and dchan channels for
> digital - this default will be used if the sysadmin has not configured
> the system yet).
> 
> At span registration a zaptel config script gets an event from udev after
> files under udev have been generated for the span and its channels. Thus
> this can even be a simple shell script. This config script will
> eventually generate a partial zaptel.conf and run ztcfg for it.

I think that:
At span registration when the udev event is generated for each channel
then the user's udev script would be responsible to get from sysfs some 
values (e.g signalling capabilities of channel) and then simply calls a 
script that would build a zaptel.conf possibly merging it with an 
existing /etc/zaptel.conf if user already configured something.

Unfortunately I don't think we could run ztcfg directly from the 
response of the udev event, because programs run by udev should be short
to execute. Moreover this would open some races on zaptel drivers 
because they are not safe to start-up race conditions (this could be 
fixed too).
As you see udev is maybe not the good solution after all.

We could simply let udev create the devices under /dev and then later on
during boot process do the real work.
(If we don't want to be limited to boot process then the udev event 
user's script may add a cron job to call the zaptel configuration script 
later on).

The zaptel configuration script would fetch information from sysfs and
from an existing zaptel.conf (if any) and then deduce the good 
configuration and call ztcfg on it.


> Another thing to consider is how to generate the device files. Those
> have to be generated by udev and not statically as /dev is not static
> anymore on most systems. The current udev rules, which are already
> widely deployed by users and integrated in distributions, use the
> "zaptel" class name.
  I wasn't aware about that -- I thought that udev rules were only
  relying on zap%n zaptranscode zapctl... (but maybe not relying on 
"zaptel" class name).

> Maybe we should move that task to the same span
> config script? 
Generating devices from udev rules is the right approach, that's why
udev has been created after all.

Maybe this can prevent strange issues with the timing of
> the generation of the device file.

I don't know any timing issue about the generation of the device file.
You're probably talking about the 'sleep' command present in the init 
scripts after loading zaptel main driver.
Even if devices would be generated by our span config script we still 
would have to do this sleep because ztcfg needs /dev/zap/zapctl to be 
present -- so before calling ztcfg we would still need to wait for
/dev/zap and this timing issue would still apply.

The sleep after loading zaptel drivers to wait for /proc/zaptel/1
could be simply removed because if you are sure that you've zaptel
hardware you can simply pass this test.

However the sleep may still be needed because of drivers startup races.
I haven't checked which driver is prone to these races and It would
certainly hard to do so and even if they would they could perfectly run 
without crashing. Conceptually thinking I would say that most zaptel
drivers are prone to these races. I know how to fix that but that's out 
of scope for now.

> 
> And this brings the issue of asynchronic events. We loaded a bunch of
> drivers. How can we tell that they are fully configured? Will it be
> possible to avoid a sleep?
> 
You can assume that they have been fully configured if ztcfg returns 
without failing -- we could export something to sysfs saying -- hey 
channel was configured but I can't see the point.

Avoid a sleep for now is not possible, even if things would have been
done nicely this sleep would have to be replaced by a blocking wait

For sure we would wait the exact time for things to set-up but
the work that we would have to do to get this is simply non-sense.
Here are some solutions...

Sol1:
- init script would have to call C a program talking with zaptel
- zaptel would put C program in a queue (or whatever)
- zaptel would have to be notified that driver is ready to wait 
configuration events
- zaptel then would wake-up the C program
- C program returning
- script would then call ztcfg

And this wouldn't prevent us to wait for /dev/zap/ at the beginning...
(Oh yes unless you want to make a C program hooking on some udev fs
callbacks).

Sol2:
We could even do a zaptel event framework that would notify
user-space application of that kind of events but well is it worth the pane?

Sol3:
- init script will only be responsible for loading a watchdog C program
   and zaptel modules.
- in our udev rules we will call a short C client program waking up our 
watchdog program.
The responsibility of the watchdog program would be to receive such
events and update its state accordingly.
When the state is considered stable then call ztcfg.
How to consider the state stable??? We wouldn't be aware of zaptel 
drivers startup timing considerations so this design has still a lot
of caveats.

















More information about the asterisk-dev mailing list