pages tagged udevyakkinghttp://yakking.branchable.com/tags/udev/yakkingikiwiki2015-04-15T11:00:16Zsystemd for the uninformed - udev device managementhttp://yakking.branchable.com/posts/systemd-2-udevd/Richard Maw2015-04-15T11:00:16Z2015-04-15T11:00:10Z
<p><a href="http://www.freedesktop.org/software/systemd/man/udev.html">udev(8)</a> is the latest development in the complicated history of
device management in Linux. It has not been entirely uncontroversial. It
was previously hated for its decision to change syntax. Its integration
into systemd caused the <a href="http://www.gentoo.org/proj/en/eudev/">eudev</a> fork to happen, and the decision to
remove firmware loading support made Linus grumble.</p>
<p>This article isn't about that though, this is about what <a href="http://www.freedesktop.org/software/systemd/man/udev.html">udev(8)</a>
is, what it can do, and how you would use it.</p>
<p><a href="http://www.freedesktop.org/software/systemd/man/udev.html">udev(8)</a> is for managing the contents of <code>/dev</code> to handle permissions
of which users and groups may access devices under which names, and
providing an API for other services to use to recieve notification of
when devices change.</p>
<p>You tend not to need to interact with <a href="http://www.freedesktop.org/software/systemd/man/udev.html">udev(8)</a> directly unless you
have obscure hardware that you need to categorise, or you need to perform
actions when a device appears.</p>
<h2>Granting permission to access devices</h2>
<p>If the device has already been processed such that there's an entry in
<code>/dev</code>, then you can use <a href="http://www.freedesktop.org/software/systemd/man/udevadm.html">udevadm(8)</a> and the steps in this ArchLinux
wiki page on <a href="https://wiki.archlinux.org/index.php/udev#Writing_udev_rules">writing udev rules</a> to work out how to create a persistent
symlink.</p>
<p>To change the owner of the file, so you don't need to be root to use it,
you can add <code>GROUP="GROUPNAME"</code>, subtituting the group name wanted, and
set file permission bits with <code>MODE="0660"</code> to make that group able to
read or write to that device.</p>
<h2>Performing actions when a device appears</h2>
<h3>Short, simple scripts</h3>
<p>The simplest way to do this is to add <code>RUN+="/path/to/your/script"</code>
to your <a href="http://www.freedesktop.org/software/systemd/man/udev.html">udev(8)</a> rule, however this is only suitable for short-lived
scripts, as they will be killed if they are stil running after a timeout
period.</p>
<h3>Starting a daemon per-device</h3>
<p>If you need a longer-running service, then you should integrate it with
a systemd unit, by defining the unit like:</p>
<pre><code>cat >/etc/systemd/system/my-service@.service <<'EOF'
[Unit]
Description=My Service
[Service]
Type=simple
ExecStart=/path/to/your/script %I
EOF
</code></pre>
<p>And add <code>ENV{SYSTEMD_WANTS}="my-service@%k.service"</code> to the udev rule.</p>
<p>This will run <code>/path/to/your/script</code> and pass it the path to the device
that has just appeared.</p>
<h3>Handling device events from a currently-running daemon</h3>
<p>Sometimes it is not appropriate to have a model where there is an instance
of your service running for every device that is added. In this case,
it is more appropriate to have your service listen for udev events and
handle the devices when they appear itself.</p>
<p>The details on how to do this vary with the programming language bindings,
but the general flow is:</p>
<ol>
<li>Initialize the udev library context</li>
<li>Create a udev monitor</li>
<li>Configure the monitor to filter it to the class of devices you care about</li>
<li>Add the monitor to an event loop</li>
<li>Wait for udev to have a matching entry for you</li>
<li>Read the device entry out of udev and process the event</li>
</ol>
<p>Depending on your programming language of choice, you may want a guide
for how to <a href="http://www.signal11.us/oss/udev/udev_example.c">listen for devices with libudev</a>, or <a href="http://pyudev.readthedocs.org/en/latest/guide.html">pyudev</a>.</p>