Tweets by @markusgattol |
Gadgets of various kinds without the ability to connect to each another and share data as well as computations1 are pointless. In order for gadgets to be able to exchange information with humans and/or other non-human entities they either need to fully configure and manage themselves or someone/something needs to do it. This page is not going to cover all necessary things like software communication protocols, information theory, hardware related issues, communication theory, physics, communication standards or whatever else is necessary in order for gadgets being able to exchange information with other entities. This page will just focus on how to manage and configure a gadget for use with today's (Anno Domini + 2008 years) common computers running DebianGNU/Linux, enabling it to exchange information with the computer and/or enabling it to directly or indirectly (via other gadgets) exchange information with other gadgets and therefor become a good and useful fellow to humans. Theory PartWhat happens, if someone with a recent Linux kernel (series 2.6), plugs a device (external HDD (Hard Disk Drive), portable music player, camcorder, printer, etc.) to his running computer or boots his computer with, say his digital camera already connected to his computer via the USB cable? Furthermore, for those who know what happens in such cases, how exactly can one influence those things in order to customize them to his personal benefit? The reader who knows all this can skip this section, anyone else might continue reading. Udev - What is it?Udev is a device manager, a piece of software that does something if something happens in a way we can influence. In order to understand what udev is, let us consider why someone, back in time, might have thought that something like udev is needed. Nowadays, almost everybody who owns a computer, also has got another device that can be, or needs to be connected to the computer in order to make serve us well. Without the Linux Kernel and udev, no device would be noticed by the computer. The Linux Kernel and udev work together hand in hand in order to notice devices and make them usable. The predecessor of udev was roughly speaking the Linux Kernel itself. This approach turned out to be rather problematic and complicated for various reasons. That in mind, and full of ambitions, folks put their heads together and invented a new, rather different approach to cope with the relationship computer/attached devices. In fact, that is what we nowadays know as udev and uevent2. Udev is targeted at Linux kernels 2.6 and beyond to provide a
userspace solution for a dynamic Over the years, the things that we might use udev rules for have changed, as well as the flexibility of rules themselves. On a modern system, udev provides persistent naming for some device types out of the box, eliminating the need for custom rules for those devices. However, some users will still require/desire the extra level of customization. We assume, that one has already installed udev. With DebianGNU/Linux,
just issue
Udev - How does it work?Udev basically consists the parts listed below
Kernel device event managementOn an udev system, besides the maintenance of the dynamic Event processingThe udev daemon (udevd) reads and parses all provided rules from the
recv(4, "addclass/input/input9/mouse2\0ACTION=add\0 DEVPATH=/class/input/input9/mouse2\0SUBSYSTEM=input\0 SEQNUM=1064\0PHYSDEVPATH=/devices/pci0000:00/0000:00:1d.1/usb2/2-2/2-2:1.0\0 PHYSDEVBUS=usb\0PHYSDEVDRIVER=usbhid\0MAJOR=13\0MINOR=34\0", 2048, 0) = 221 An udev rule can match on any property the kernel adds to the event itself, exports in sysfs or the rule can request additional information from external programs. The rules syntax and the provided keys to match or import data is described in the udev man pages. An advanced example is the persistent device naming, implemented to provide stable names for all disks devices - regardless of their order of recognition or the connection used to plug the device: 1 sa@pc1:~$ ls -lR /dev/disk 2 /dev/disk: 3 total 0 4 drwxr-xr-x 2 root root 300 2006-11-22 17:36 by-id 5 drwxr-xr-x 2 root root 100 2006-11-22 06:50 by-label 6 drwxr-xr-x 2 root root 300 2006-11-22 17:36 by-path 7 drwxr-xr-x 2 root root 120 2006-11-22 06:50 by-uuid 8 Udev provides out-of-the-box persistent naming for storage devices
within the The command in line 1 lists directory contents recursively. As we can
see, 9 /dev/disk/by-id: 10 total 0 11 lrwxrwxrwx 1 root root 9 2006-11-22 06:50 ata-HITACHI_DK23EA-60_7L0725 -> ../../hda 12 lrwxrwxrwx 1 root root 10 2006-11-22 06:50 ata-HITACHI_DK23EA-60_7L0725-part1 -> ../../hda1 13 lrwxrwxrwx 1 root root 10 2006-11-22 06:50 ata-HITACHI_DK23EA-60_7L0725-part2 -> ../../hda2 14 lrwxrwxrwx 1 root root 10 2006-11-22 06:50 ata-HITACHI_DK23EA-60_7L0725-part3 -> ../../hda3 15 lrwxrwxrwx 1 root root 10 2006-11-22 06:50 ata-HITACHI_DK23EA-60_7L0725-part4 -> ../../hda4 16 lrwxrwxrwx 1 root root 10 2006-11-22 06:50 ata-HITACHI_DK23EA-60_7L0725-part5 -> ../../hda5 17 lrwxrwxrwx 1 root root 9 2006-11-22 06:50 ata-HITACHI_DK23EA-60_8P2936 -> ../../hdb 18 lrwxrwxrwx 1 root root 10 2006-11-22 06:50 ata-HITACHI_DK23EA-60_8P2936-part1 -> ../../hdb1 19 lrwxrwxrwx 1 root root 10 2006-11-22 06:50 ata-HITACHI_DK23EA-60_8P2936-part2 -> ../../hdb2 20 lrwxrwxrwx 1 root root 9 2006-11-22 06:50 ata-TOSHIBA_DVD-ROM_SD-R6012_X25S407429 -> ../../hdc 21 lrwxrwxrwx 1 root root 9 2006-11-22 17:36 usb-Maxtor_6_B250R0_DEF107679C83 -> ../../sdb 22 lrwxrwxrwx 1 root root 10 2006-11-22 17:36 usb-Maxtor_6_B250R0_DEF107679C83-part2 -> ../../sdb2 23 lrwxrwxrwx 1 root root 9 2006-11-22 06:50 usb-NEWTREND_MMC_READER_BULK -> ../../sda 24 Line 9 to 23 lists device nodes and corresponding mount-points per ID
(Identifier). Note, that I could for example bind mount (see 25 /dev/disk/by-label: 26 total 0 27 lrwxrwxrwx 1 root root 10 2006-11-22 06:50 boot -> ../../hda1 28 lrwxrwxrwx 1 root root 10 2006-11-22 06:50 homemedia -> ../../hdb2 29 lrwxrwxrwx 1 root root 10 2006-11-22 06:50 tmp -> ../../hda5 30 Line 25 to 29 lists device nodes and corresponding mount-points per label. 31 /dev/disk/by-path: 32 total 0 33 lrwxrwxrwx 1 root root 9 2006-11-22 06:50 pci-0000:00:1d.0-usb-0:2:1.0-scsi-0:0:0:0 -> ../../sda 34 lrwxrwxrwx 1 root root 9 2006-11-22 06:50 pci-0000:00:1f.1-ide-0:0 -> ../../hda 35 lrwxrwxrwx 1 root root 10 2006-11-22 06:50 pci-0000:00:1f.1-ide-0:0-part1 -> ../../hda1 36 lrwxrwxrwx 1 root root 10 2006-11-22 06:50 pci-0000:00:1f.1-ide-0:0-part2 -> ../../hda2 37 lrwxrwxrwx 1 root root 10 2006-11-22 06:50 pci-0000:00:1f.1-ide-0:0-part3 -> ../../hda3 38 lrwxrwxrwx 1 root root 10 2006-11-22 06:50 pci-0000:00:1f.1-ide-0:0-part4 -> ../../hda4 39 lrwxrwxrwx 1 root root 10 2006-11-22 06:50 pci-0000:00:1f.1-ide-0:0-part5 -> ../../hda5 40 lrwxrwxrwx 1 root root 9 2006-11-22 06:50 pci-0000:00:1f.1-ide-0:1 -> ../../hdb 41 lrwxrwxrwx 1 root root 10 2006-11-22 06:50 pci-0000:00:1f.1-ide-0:1-part1 -> ../../hdb1 42 lrwxrwxrwx 1 root root 10 2006-11-22 06:50 pci-0000:00:1f.1-ide-0:1-part2 -> ../../hdb2 43 lrwxrwxrwx 1 root root 9 2006-11-22 06:50 pci-0000:00:1f.1-ide-1:0 -> ../../hdc 44 lrwxrwxrwx 1 root root 9 2006-11-22 17:36 pci-0000:02:05.2-usb-0:2:1.0-scsi-0:0:0:0 -> ../../sdb 45 lrwxrwxrwx 1 root root 10 2006-11-22 17:36 pci-0000:02:05.2-usb-0:2:1.0-scsi-0:0:0:0-part2 -> ../.. 46 /sdb2 Line 31 to 46 lists device nodes and corresponding mount-points per path. 47 /dev/disk/by-uuid: 48 total 0 49 lrwxrwxrwx 1 root root 10 2006-11-22 06:50 3440df43-900c-4e92-9962-f980fd7b57f9 -> ../../hda5 50 lrwxrwxrwx 1 root root 10 2006-11-22 06:50 6a77635b-973d-4623-b288-fbebb3eb8624 -> ../../hda1 51 lrwxrwxrwx 1 root root 10 2006-11-22 06:50 a2ee5d89-dab9-45c5-96b7-bb2734f7fe58 -> ../../hdb2 52 lrwxrwxrwx 1 root root 9 2006-11-22 06:50 ca82dc09-c720-4dcf-a4b4-3ad32559db7c -> ../../md0 53 sa@pc1:~$ Line 47 to 53 lists device nodes and corresponding mount-points per uuid. Event queue managementThe udev daemon takes care of the right order of event execution and serializes events for devices which depend on other events. Events for child devices will be delayed until the event for the parent device has returned. That way, partition events will wait for the main block device event to finish, so the partition event can import the parents information, already stored in the udev database. Udevd throttles the execution of events and limits the running
processes, if there are already too many in running state. If the
event carries a The current state of the event queue is visible in Booting and Cold-pluggingAll device events happening during the boot process until the udev
daemon is running are obviously lost, because the infrastructure to
handle these events lives on the root file system and is not available
at that time. To cover that hole, the kernel now provides an uevent
file for every device in the sysfs file system . By writing From userspace, there is no difference between a device coldplug
sequence and a device discovery during run time. In both cases, the
same rules are used to match and the same configured programs are run.
This replaces the former Certain steps during bootup will need to synchronize with the kernel
event handling. This can be accomplished by watching the event queue
directory at Kernel module loadingThe kernel bus drivers probe for devices. For every detected device,
the kernel creates an internal device structure and the driver core
sends an event to udev. Devices identify themselves by an ID
(Identifier), which tells what kind of device it is. Usually these
IDs consist of vendor and product id and other susbsytem specific
values. Every bus has its own scheme for these id's. The kernel takes
this information, composes a Every device driver carries a list of known IDs for devices it can
handle. The list is contained in the kernel module file itself. The
program Udev - What are its Use Cases?Udev rules are flexible and very powerful. Here are some of the things we can use rules for:
Writing rules is not a workaround for the problem where no device nodes for a articular device exist. Even if there are no matching rules, udev will create the device node with the default name supplied by the kernel. Having persistently named device nodes has several advantages. Assume we own two USB storage devices which might for example be a digital camera and a USB flash drive. These devices are typically assigned device nodes For example, one has stored all his mp3s files on his external USB
HDD and his music application software searches for those files using
a particular device node. Which device node entry should he create for
the music player to search for stored music? Is it This is exactly one of the moments where folks learn to love udev and
the ability to write udev rules in order to create persistent device
nodes. For example, one could write an udev rule that takes care for
the HDD with mp3 music files always appearing as
By the moment, device nodes for any particular device become
persistent, mounting devices to fixed places within the file system
tree (e.g. Writing udev rulesWriting udev rules is nothing complicated but there are three prerequisites for writing udev rules:
Rule files:When deciding how to name a device and which additional actions to
perform, udev reads a series of rules from files. These files are kept
in the Files in Within a rules file, lines starting with One device can be matched by more than one rule. This has it is practical advantages, for example, we can write two rules which match the same device, where each one provides its own alternate name for the device. Both alternate names will be created, even if the rules are in separate files. It is important to understand that udev will not stop processing when it finds a matching rule, it will continue searching and attempt to apply every rule that it knows about. This behavior can also be disabled4. Rule syntax:Each rule is constructed from a series of key-value pairs, which are separated by commas. Match keys are conditions used to identify the device which the rule is acting upon. When all match keys in a rule correspond to the device being handled, then the rule is applied and the actions of the assignment keys are invoked. Every rule should consist of at least one match key and at least one assignment key. Here is an example rule to illustrate the above: KERNEL=="hdb", NAME="my_spare_disk" The above rule includes one match key ( Basic Rules:Udev provides several different match keys which can be used to write rules which match devices very precisely.
After we have used a series of match keys to precisely match a device, udev gives us fine control over what happens next, through a range of assignment keys.
As hinted above, udev only creates one true device node for one
device. If we wish to provide alternate names for this device node, we
need to use the symbolic link functionality. With the KERNEL=="hdb", NAME="my_spare_disk" The above rule says: match a device which was named by the kernel as
hdb, and instead of calling it hdb, name the device node as
my_spare_disk. The device node appears at KERNEL=="hdb", DRIVER=="ide-disk", SYMLINK+="sparedisk" The above rule says: match a device which was named by the kernel as
hdb AND where the driver is ide-disk. Name the device node with the
default name and create a symbolic link to it named sparedisk. Note
that we did not specify a device node name, so udev uses the default.
In order to preserve the standard KERNEL=="hdc", SYMLINK+="cdrom cdrom0" The above rule is probably more typical of the types of rules one
might be writing. It creates two symbolic links at Matching sysfs attributes:The match keys introduced so far only provide limited matching capabilities. Realistically we require much finer control. We want to identify devices based on advanced properties such as vendor codes, exact product numbers, serial numbers, storage capacities, number of partitions, etc. Many drivers export information like this into sysfs, and udev allows
us to incorporate sysfs-matching into our rules, using the SUBSYSTEM=="block", ATTR{size}=="212941575", ATTRS{model}=="B250R0*",SYMLINK:="usb/usb_disk_backup" String substitutions:When writing rules which will potentially handle multiple similar devices, udev's printf-like string substitution operators are very useful. We can simply include these operators in any assignments our rule makes, and udev will evaluate them when they are executed. The most common operators are There is also an alternative syntax for these operators - KERNEL=="mice", NAME="input/%k" KERNEL=="loop0", NAME="loop/%n", SYMLINK+="%k" The first rule ensures that the mice device node appears exclusively
in the String matching:As well as matching strings exactly, udev allows us to use shell-style pattern matching. There are 3 patterns supported:
Here are some examples which incorporate the above patterns. Note the use of the string substitution operators. KERNEL=="fd[0-9]*", NAME="floppy/%n", SYMLINK+="%k" KERNEL=="hiddev*", NAME="usb/%k" The first rule matches all floppy disk drives, and ensures that the
device nodes are placed in the Practical PartAs opposed to the theoretical (vital to know!) part, this one is going to show how to actually use that former gained knowledge to set up and configure devices and gadgets using udev. Gathering InformationThis subsection is about how to gather the information necessary to write udev rules. The sysfs Tree:The concept of using interesting information from sysfs was briefly touched upon above. In order to write rules based on this information, we first need to know the names of the attributes and their current values. Sysfs is actually a very simple structure. It is logically divided into directories. Each directory contains a number of files (attributes) which typically contain just one value. Some symbolic links are present, which link various parts of the tree together. Some directories are referred to as top-level device paths. These
directories act as the top-level glue which chain other parts of sysfs
to the device in question. Top-level device paths can be classified as
sysfs directories which contain a dev file e.g. For example, on my system, the When we write rules based on sysfs information, we are simply matching attribute contents of some files in one part of the chain i.e. I can determine the size of my hard disk (partition) as follows: sa@pc1:~$ cat /sys/block/hda/size 117210240 sa@pc1:~$ In an udev rule, I could use udevinfo:With DebianGNU/Linux, if the package udev is installed (line 7 below,
the 1 sa@pc1:~$ dpkg -l udev 2 Desired=Unknown/Install/Remove/Purge/Hold 3 | Status=Not/Installed/Config-files/Unpacked/Failed-config/Half-installed 4 |/ Err?=(none)/Hold/Reinst-required/X=both-problems (Status,Err: uppercase=bad) 5 ||/ Name Version Description 6 +++-====================-====================-======================================================== 7 ii udev 0.100-2.3 /dev/ and hotplug management daemon 8 sa@pc1:~$ apt-file list udev | grep bin 9 udev: sbin/scsi_id 10 udev: sbin/udevcontrol 11 udev: sbin/udevd 12 udev: sbin/udevsettle 13 udev: sbin/udevtrigger 14 udev: usr/bin/udevinfo 15 udev: usr/bin/udevtest 16 udev: usr/sbin/udevmonitor 17 sa@pc1:~$ Line 9 to 16 above show all files which are contained within the udev
package AND which contain the string sa@pc1:~$ udevinfo -a -p /sys/block/hda | head -n 25 Udevinfo starts with the device specified by the devpath and then walks up the chain of parent devices. It prints for every device found, all possible attributes in the udev rules key format. A rule to match, can be composed by the attributes of the device and the attributes from one single parent device. looking at device '/block/hda': KERNEL=="hda" SUBSYSTEM=="block" DRIVER=="" ATTR{stat}==" 24776 1698 650729 359804 42230 109624 1249854 8888792 0 542312 9248596" ATTR{size}=="117210240" ATTR{removable}=="0" ATTR{range}=="64" ATTR{dev}=="3:0" looking at parent device '/devices/pci0000:00/0000:00:1f.1/ide0/0.0': KERNELS=="0.0" SUBSYSTEMS=="ide" DRIVERS=="ide-disk" ATTRS{modalias}=="ide:m-disk" ATTRS{drivename}=="hda" ATTRS{media}=="disk" sa@pc1:~$ As we can see, udevinfo simply produces a list of attributes we can use as-is as match keys in our udev rules. From the above udevinfo output, I could produce the following rule for this device: SUBSYSTEM=="block", ATTR{size}=="117210240", NAME="my_hard_disk" We are usually provided with a large number of attributes, and we must
pick a number of them to construct a rule. In general, we want to
choose attributes which identify our device in a persistent and
human-recognisable way. In the examples above, I chose the size of my
disk. I did not use meaningless stuff such as Another point to note is that it is common for text attributes
appearing in udevinfo output to be padded with spaces (e.g.
The only tricky thing using udevinfo is that we are required to know
the top-level device path ( sa@pc1:~$ udevinfo -a -p `udevinfo -q path -n /dev/hda` Udevinfo starts with the device specified by the devpath and then walks up the chain of parent devices. It prints for every device found, all possible attributes in the udev rules key format. A rule to match, can be composed by the attributes of the device and the attributes from one single parent device. looking at device '/block/hda': KERNEL=="hda" SUBSYSTEM=="block" DRIVER=="" ATTR{stat}==" 25142 1703 655793 367320 61293 140074 1664590 11570192 0 695884 11937512" ATTR{size}=="117210240" ATTR{removable}=="0" ATTR{range}=="64" ATTR{dev}=="3:0" looking at parent device '/devices/pci0000:00/0000:00:1f.1/ide0/0.0': KERNELS=="0.0" SUBSYSTEMS=="ide" DRIVERS=="ide-disk" ATTRS{modalias}=="ide:m-disk" ATTRS{drivename}=="hda" ATTRS{media}=="disk" looking at parent device '/devices/pci0000:00/0000:00:1f.1/ide0': KERNELS=="ide0" SUBSYSTEMS=="" DRIVERS=="" looking at parent device '/devices/pci0000:00/0000:00:1f.1': KERNELS=="0000:00:1f.1" SUBSYSTEMS=="pci" DRIVERS=="PIIX_IDE" ATTRS{modalias}=="pci:v00008086d0000248Asv00000000sd00000000bc01sc01i8a" ATTRS{local_cpus}=="ff" ATTRS{irq}=="10" ATTRS{class}=="0x01018a" ATTRS{subsystem_device}=="0x0000" ATTRS{subsystem_vendor}=="0x0000" ATTRS{device}=="0x248a" ATTRS{vendor}=="0x8086" looking at parent device '/devices/pci0000:00': KERNELS=="pci0000:00" SUBSYSTEMS=="" DRIVERS=="" sa@pc1:~$ Advanced TopicsThis subsection covers some advanced topics which, at least from my point of view, are very practical in real-world scenarios. Controlling permissions and ownership:Udev allows us to use additional assignments in rules to control ownership and permission attributes on each device. The KERNEL=="fb[0-9]*", NAME="fb/%n", SYMLINK+="%k", GROUP="video" The KERNEL=="fd[0-9]*", OWNER="john" Udev defaults to creating nodes with Unix permissions of KERNEL=="inotify", NAME="misc/%k", SYMLINK+="%k", MODE="0666" Using external programs to name devices:Under some circumstances, we may require more flexibility than
standard udev rules can provide. In this case, we can use udev to run
a program and use the standard output from that program to provide
device naming. In order to use this functionality, we simply specify
the absolute path of the program to run (and any parameters) in the
The following examples refer to a fictional program found at
In our first example, we assume that KERNEL=="hda", PROGRAM="/bin/device_namer %k", SYMLINK+="%c" The next example assumes that KERNEL=="hda", PROGRAM="/bin/device_namer %k", NAME="%c{1}", SYMLINK+="%c{2}" The next example assumes that KERNEL=="hda", PROGRAM="/bin/device_namer %k", NAME="%c{1}", SYMLINK+="%c{2+}" Output parts can be used in any assignment key, not only KERNEL=="hda", PROGRAM="/bin/who_owns_device %k", GROUP="%c" Running external programs upon certain events:Yet another reason for writing udev rules is to run a particular program when a device is connected or disconnected. For example, we might want to execute a script to automatically download all of our photos from our digital camera when it is connected or we want to trigger a backup from the local HDD to the external HDD as soon as we plug the external HDD to the computer. I will provide an example for the latter case – see
The functionality introduced here allows you to run a program after the device node is put in place. This program can act on the device, however it must not run for any extended period of time, because udev is effectively paused while these programs are running. One workaround for this limitation is to make sure your program immediately detaches itself. Here is an example rule which demonstrates the use of the KERNEL=="sdb", RUN+="/usr/bin/my_program" When Environment interaction:Udev provides an KERNEL=="fd0", SYMLINK+="floppy", ENV{some_var}="value" In the matching case, we can ensure that rules only run depending on the value of an environment variable. Note that the environment that udev sees will not be the same user environment as one gets on the console. A fictional rule involving an environment match is shown below. KERNEL=="fd0", ENV{an_env_var}=="yes", SYMLINK+="floppy" The above rule only creates the Additional options:Another assignment which can prove useful is the
For example, the rule below sets the group ownership on my hard disk node, and ensures that no later rule can have any effect: KERNEL=="sda", GROUP="disk", OPTIONS+="last_rule" Testing and DebuggingThis section provides some information useful while writing udev rules since it is about some tools to debug rules and look behind the curtain what is going on in order to react to possible issues. udevtrigger:Assuming we are on a recent kernel with inotify5 support, udev will automatically monitor our rules directory and automatically pick up any modifications we make to the rule files. Despite this, udev will not automatically reprocess all devices and
attempt to apply the new rule(s). For example, if we write a rule to
add an extra symbolic link for our camera while the camera is plugged,
we cannot expect the extra symbolic link to show up right away. To
make the symbolic link show up, we can either disconnect and reconnect
our camera, or alternatively in the case of non-removable devices, we
can run udevtrigger – see If your kernel does not have inotify support, new rules will not be
detected automatically. In this situation, you must run udevtest:If we know the top-level device path in sysfs, we can use udevtest to
show the actions which udev would take. This may help us debug our
rules. For example, assuming we want to debug a rule which acts on
pc1:/home/sa# udevtest /block/sdb This program is for debugging only, it does not create any node, or run any program specified by a RUN key. It may show incorrect results, if rules match against subsystem specfic kernel event variables. main: looking at device '/block/sdb' from subsystem 'block' run_program: 'usb_id -x' run_program: '/lib/udev/usb_id' (stdout) 'ID_VENDOR=Maxtor_6' run_program: '/lib/udev/usb_id' (stdout) 'ID_MODEL=B250R0' run_program: '/lib/udev/usb_id' (stdout) 'ID_REVISION=0000' run_program: '/lib/udev/usb_id' (stdout) 'ID_SERIAL=Maxtor_6_B250R0_DEF107679C83' run_program: '/lib/udev/usb_id' (stdout) 'ID_TYPE=disk' run_program: '/lib/udev/usb_id' (stdout) 'ID_BUS=usb' run_program: '/lib/udev/usb_id' returned with status 0 run_program: 'edd_id --export /dev/.tmp-8-16' run_program: '/lib/udev/edd_id' (stderr) 'no kernel EDD support' run_program: '/lib/udev/edd_id' returned with status 2 run_program: 'path_id /block/sdb' run_program: '/lib/udev/path_id' (stdout) 'ID_PATH=pci-0000:02:05.2-usb-0:2:1.0-scsi-0:0:0:0' run_program: '/lib/udev/path_id' returned with status 0 udev_rules_get_name: add symlink 'disk/by-id/usb-Maxtor_6_B250R0_DEF107679C83' udev_rules_get_name: add symlink 'disk/by-path/pci-0000:02:05.2-usb-0:2:1.0-scsi-0:0:0:0' run_program: 'vol_id --export /dev/.tmp-8-16' run_program: '/lib/udev/vol_id' (stderr) '/dev/.tmp-8-16: unknown volume type' run_program: '/lib/udev/vol_id' returned with status 4 udev_rules_get_name: no node name set, will use kernel name 'sdb' udev_device_event: device '/block/sdb' already in database, validate currently present symlinks udev_node_add: creating device node '/dev/sdb', major = '8', minor = '16', mode = '0660', uid = '0', gid = '6' udev_node_add: creating symlink '/dev/disk/by-id/usb-Maxtor_6_B250R0_DEF107679C83' to '../../sdb' udev_node_add: creating symlink '/dev/disk/by-path/pci-0000:02:05.2-usb-0:2:1.0-scsi-0:0:0:0' to '../../sdb' main: run: 'socket:/org/kernel/udev/monitor' main: run: '/usr/share/usbmount/usbmount add' main: run: 'socket:/org/freedesktop/hal/udev_event' pc1:/home/sa# Note the 1. The technology we have in place today (early 21st century) always moves around data over different kinds of networks in different ways. The computation never moves around but stays where it is (could be our iPod, notebook or cell – computing happens locally). There have been and there are proposals to move around computations as well in cases where it makes sense. Nobody really picked that idea up so far... 2. The kernel interface used to exchange information between udev and the Linux Kernel. 3. For example, plug or unplugging a device to a computer creates an event. 4. Putting 5. I also strongly recommend using the powers of |