[asterisk-dev] hotplug DAHDI

Tzafrir Cohen tzafrir.cohen at xorcom.com
Mon Oct 14 08:54:07 CDT 2013


Hi folks,

Hotplug support in DAHDI has been merged (really, this time) and I'd
like to solicit testing and feedback.

Long email follows.

Ingridients
===========

* DAHDI Linux >= 2.7
  There are some fixes after that, but things should basically work.

* DAHDI-tools git master branch
  2.7 should have included the required scriptary, but it didn't. In
  recent commits we have greatly modified versions of those along with a
  small improvement in dahdi_cfg.

* Asterisk 12
  Asterisk 12 includes the ability to include new channels that were not
  present at module load time (but are present in the configuratoin
  file). Alternatively you can apply the following two patches on
  Asterisk 11:
  http://patch-tracker.debian.org/patch/series/view/asterisk/1:11.5.1~dfsg1-1/dahdi_pri_event_removed
  http://patch-tracker.debian.org/patch/series/view/asterisk/1:11.5.1~dfsg1-1/dahdi_create_channels
  (basically: trivial backports)
  Maybe also patch Asterisk to change the default of
  ignore_failed_channels.


DAHDI Startup: Present
======================
When a DAHDI span appears, it registers with DAHDI. DAHDI gives it the
first availble span number and channel numbers (for its channels). Thus
if you have several DAHDI devices you have to make sure that they
register with DAHDI at a specific order (explicit module load order,
dahdi_registration of xpp, whatever).

In order to guarantee a specific order between moduels, most DAHDI
driver modules were blacklisted in modprobe (that is: they may only be
loaded when modprobed for their exact names. Not for an alias of the
module. Aliases are typically used for the automatic module loading for
discovered hardware).

Before a span is ready it needs to be configured using dahdi_cfg.
dahdi_cfg uses data from /etc/dahdi/system.conf . dahdi_cfg will fail if
some spans are missing, and thus needs to be run only after all spans
were registered.

Only at this point can we start Asterisk, as chan_dahdi will normally
only open DAHDI channels if they are available at startup. It also well
get very annoyed if any of them is missing.

Thus the module loading (except, maybe, that of xpp) and running of
dahdi_cfg is done in the dahdi init script. That script can only end
when modules have finished loading and spans are fully configured. Only
after that can Asterisk start.


New Kernel Interfaces
=====================
As of DAHDI 2.6 spans are part of a different entity called "DAHDI
device". A DAHDI device represents the hardware device. It may have
several spans. All those devices are listed in SysFS under
/sys/bus/dahdi_devices/devices . Each span has a SysFS node (directory)
under that node. The spans are listed there by their relative number
("port number").

low-level DAHDI drivers don't regiater spans in a newly discovered device.
Rather, they create a dahdi_device kernel object and (which also
includes the spans) and register it with DAHDI. By default the DAHDI
core will, at this stage, register all spans as before (give them the
first available span and channel numbers). In order to avoid the
duplicate meaning of "registration" (devices and spans) we call the
registration of the span *assignment*.

However, if the module parameter dahdi.auto_assign_spans is not set, the
spans will not be assigned and will just lurk there. This gives
userspace the opportunity to ask them to be assigned at some explicit
span and channel numbers. This ability is called "span pinning".

See http://docs.tzafrir.org.il/dahdi-linux/#_span_assignments and the
interface itself under
http://docs.tzafrir.org.il/dahdi-linux/#_devices_bus .

There is one span parameter that must be set (if at all) before
assignment: the "span type": if it is an E1/T1/J1 port, changing it from
E1 to T1 changes the number of channels in the span and thus cannot be
done once the span is assigned. This is read and set using the
"spantype" file in the device's node.

In both 'spantype' and 'assign' userspace can change the settings for a
span of the device. As the span is not yet assigned, it cannot be
identified by its span number. It can only be identified by its "port
number" - local number within the device. Thus in order to assign the
second port of DAHDI device do-do-do-de to be span 4 and start at
channel number 40, you'd use:

  echo 2:4:40 >/sys/bus/dahdi_devices/devices/do-do-do-de/assign-span


DAHDI Startup: Hotplug
======================
So, let's assume we unset dahdi.auto_assign_spans and get rid if the
DAHDI init script. What do we need to do to get the system configured?

DAHDI devices and DAHDI spans are now proper kernel object. They are
represented in SysFS and when they appear, an event is sent to userspace
(handled by udev).

DAHDI-tools has the following udev rules configuration file
(dahdi.rules):

  # DAHDI devices with ownership/permissions for running as non-root
  SUBSYSTEM=="dahdi",         OWNER="asterisk", GROUP="asterisk", MODE="0660"

  # handle hot-plugging:
  SUBSYSTEM=="dahdi_devices", RUN="/usr/share/dahdi/handle_device"
  SUBSYSTEM=="dahdi_spans",   RUN="/usr/share/dahdi/span_config"

As you can see, in the case of "dahdi" (DAHDI channel device files), the
rule sets permissions. However in the case of dahdi devices or dahdi
spans, they are handled by scripts. The script may handle any action
(not just 'ADD'. We may have some handling for span removal. Though this
is not currently needed).

The scripts we have are intended to handle two types of systems:

Complex Systems
---------------
The scripts (handle_device and span_config) were written with a eye
towards systems with multiple DAHDI devices that will require specific
and pinned configuration.

handle_device is run to assign the spans of the device that has just
been registered, and apply some settings that are needed before
assignment (right now: just span type: E1/T1/J1). 

The setting itself is done using the following two scripts:

* span_assignments: http://docs.tzafrir.org.il/dahdi-tools/man/span_assignments.8.html
* span_types: http://docs.tzafrir.org.il/dahdi-tools/man/span_types.8.html

Those scripts are installed to /usr/sbin, as they may be used from the
command line to generate the configuration and show the status.

Those two configuration files have a similar format. line-based, where
each line has the following format:

device-id		span-spec [span-spec ...]

'device-id' is a string that should match the DAHDI device. Following it
is one or more 'span-spec' - specifying the configuration to apply to
the spans of the device. A span spec begins with a relative span id (the
port number) and is applied as is to the SysFS interface of the node
identified by the device-id.

device-id can match to any of the following:
* hwid: the device's serial number or similar, if readable from
        software.
* location: The "location" field of the device, as set by its driver.
* devpath: the full path to the sysfs node.

When running from a udev hook script, devpath (except the preceeding
'/sys') is available in the varable $DEVPATH. It is often handy to use
wildcards to match just part of it, for instance, the devpath of an
Astribank may be:

  /sys/devices/pci0000:00/0000:00:10.4/usb1/1-3/xbus-01/astribanks:xbus-01

but the anything past the 'xbus' depends on the load order, and thus
better be written as:

  /sys/devices/pci0000:00/0000:00:10.4/usb1/1-3/*

or maybe just as:

  */usb1/1-3/*

The configuration files are /etc/dahdi/span-types.conf and
/etc/dahdi/pinned-spans.conf (for span_assignments).


Once the span have been assigned, a span is created in the kernel, and
an 'ADD' event for it is emitted. This triggers the script span_config.

This script runs 'dahdi_cfg -s <span_num> -c <chan_range>'. This applies
only the settings related to the span and its channels and avoids
configuring other spans and channels.

Once this is done, it runs

  asterisk -rx 'dahdi create channels $first $last'

to have Asterisk add those channels. This requires the channels to be
configured in chan_dahdi.conf. It also helps to set
'ignore_failed_channels = true' for all channels, as otherwise
chan_dahdi would fail loading if channels are missing.


Simpler Systems
---------------
The above procedure requires that the system already has
/etc/asterisk/chan_dahdi.conf, /etc/dahdi/system.conf and
/etc/dahdi/pinned-spans.conf (a new configuration file: more work!).
What can we do to avoid needing to provide them?

* /etc/dahdi/span-types.conf: do nothing if it does not exist. It is
  optional.

* /etc/dahdi/pinned-spans.conf: If missing, assign spans automatically
  (in the order they appeared). This works well for a single-device
  system. But you can still set E1/T1 type in span-types.conf .
  If you have more than one device, you should probably make the order
  of spans explicit and provide the file.

* /etc/dahdi/system.conf: If missing, try generating a temporary one
  for the span (using dahdi_genconf) and applying it. This should work
  for many (most?) devices. If it doesn't work for you, you can't use
  the default and must provide your own system.conf.

* /etc/asterisk/chan_dahdi.conf: If missing, asterisk will fail to load
  chan_dahdi.so :-(. Was there any talk about generating configurations
  outside of Asterisk?

Packagers: don't install default span-types.conf and pinned-spans.conf.
Consider not installing system.conf as well.


Issues
======
1. What about dahdi-freebsd? Anybody working on it? Did the changes in
dahdi-tools break anything there? What are your thoughts regarding an
asynchronous startup of DAHDI?

2. Dynamic spans will still need to have dahdi_cfg run at startup. How
do those changes work with dynamic spans?

3. We have quite a few configuration files now. Could we do with less?
Note that span-types.conf and pinned-spans.conf are quiree different
than system.conf (operate on devices and port numbers inside them,
rather than on span numbers and channel numbers). Do you think that
there's actually a point in converting dahdi_cfg to use a similar format
(and mode of operation)?

-- 
               Tzafrir Cohen
icq#16849755              jabber:tzafrir.cohen at xorcom.com
+972-50-7952406           mailto:tzafrir.cohen at xorcom.com
http://www.xorcom.com



More information about the asterisk-dev mailing list