|
|
| (10 intermediate revisions by 4 users not shown) |
| Line 1: |
Line 1: |
| [[Linux]]: | | <hide> |
| [[udev]] | | [[page type::article]] |
| ==Notes==
| | [[thing type::software]] |
| This text seemed like it might be useful information, even if it
| | </hide> |
| contained some inaccuracies. Original document was published under
| | ==Navigation== |
| [http://www.gnu.org/licenses/gpl.html GNU General Public License,
| | [[computing]]: [[software]]: [[Linux]]: [[udev]] |
| Version 2], and those with appropriate knowledge should feel free to
| | ==About== |
| edit or expand the text.
| | [[udev]] is the device manager used by most popular [[Linux]] kernels, including [[Debian]]. |
| ==Original Credits
| | ==Subpages== |
| :This document is written by Daniel Drake <dan@reactivated.net>
| | * [[/writing rules]] |
| :Please do not hesitate to send feedback!
| | * [[/Palm]]: connecting to a [[Palm Pilot]] with [[JPilot]] |
| :Copyright © 2003-2005 Daniel Drake
| | ==Links== |
| :This document is licensed under the GNU General Public License,
| | * {{wikipedia}} |
| Version 2.
| | * [https://wiki.ubuntu.com/KubuntuIpod?highlight=%28mediamanager%29 KubuntuIpod] shows an example of udev usage |
| ==Edit Log== | |
| * '''2005-10-05''' Copied from
| |
| http://www.reactivated.net/writing_udev_rules.html, with minor editing
| |
| for clarity. Probably needs considerable format editing.
| |
| ==Text==
| |
| ===Why?===
| |
| As stated above, writing rules for udev is an optional process. By
| |
| default, you can plug a device in, and the a relevant node (e.g.
| |
| /dev/sda for a mass-storage device) will be there, just like in
| |
| previous /dev implementations.
| |
| However, udev allows you to customise the naming of device nodes. There
| |
| are two reasons why you might want to do this: convenience, and
| |
| persistent naming.
| |
| Take the example of using udev, so that when your printer is plugged
| |
| in, it gets named as /dev/printer and also as the usual /dev/lp0. It's
| |
| not only convenience (e.g. reading and interpreting "printer" as
| |
| opposed to "lp0"), its a solution for non-persistent naming. Say that I
| |
| have two printers - a HP laser printer and an Epson inkjet. When they
| |
| are both plugged in and on, I have /dev/lp0 and /dev/lp1.
| |
| How do I know which node refers to which printer? There is no easy way.
| |
| The first printer that got connected was assigned name "lp0", and the
| |
| second "lp1". Plugging in my printers in a different order would swap
| |
| the names here, and that would mess up my scripts that always expect my
| |
| HP laser printer to be lp1.
| |
| However, if my HP laser printer got named lp_hp (as well as lpX) and my
| |
| other printer got named lp_epson (as well as lpY), then my scripts
| |
| could just refer to those names. udev magic can control this and ensure
| |
| that these '''persistent names''' always point to the device that I
| |
| intended.
| |
| For external mass-storage devices (e.g. usb hard disks), persistent
| |
| naming is very helpful in that it allows you to hardcode accurate
| |
| device paths into your /etc/[[fstab]].
| |
| It is important to understand that writing rules is simply a means of
| |
| customizing udev behaviour. Writing rules is not a workaround for the
| |
| problem where no device nodes for your particular device exist. If no
| |
| matching rules exist, udev will create the node anyway, using the name
| |
| that was supplied by the kernel.
| |
| ===The basics of writing rules===
| |
| When populating /dev, udev decides which nodes to include, and how to
| |
| name them, by reading a series of rules files.
| |
| Default udev rules are stored in /etc/udev/rules.d/50-udev.rules. You
| |
| may find it interesting to look over this file - it includes a few
| |
| examples, and then some default rules proving a devfs-style /dev
| |
| layout. However, you should not write rules into this file directly, to
| |
| reduce hassle while updating your udev installation in the future.
| |
| Files in /etc/udev/rules.d/ are parsed in '''lexical''' order. udev
| |
| will stop processing rules as soon as it finds a matching rule in a
| |
| file for the new item of hardware that has been detected. It is
| |
| important that your own rules get processed before the udev defaults,
| |
| otherwise your own naming schemes will not take effect! I suggest that
| |
| you keep your own rules in a file at /etc/udev/rules.d/10-local.rules
| |
| (this doesn't exist by default - create it). As 10 comes before 50, you
| |
| know that your rules will be looked at first. It is important that the
| |
| filenames of your rule files end with the '''.rules''' suffix,
| |
| otherwise they will not be used.
| |
| As your own rules will effectively mask out the udev defaults which
| |
| create the base /dev layout, it is recommended that you also specify
| |
| devfs-style names/symlinks for the rules you write, so that you get the
| |
| sensible defaults plus your own names.
| |
| In rule files, lines starting with a "#" are treated as comments.
| |
| Every uncommented line in the file corresponds to a rule.
| |
| Rules are composed of keys. Keys are seperated by commas. Some keys are
| |
| used for reading and matching information, others are used for
| |
| assigning information and performing actions.
| |
| # At least one identification key should be provided, which will match
| |
| the rule to any number of devices in the system. These are listed in
| |
| the later section: [[#Identifying devices through basic keys]].
| |
| # At least one assignment key should be provided, to control how the
| |
| resultant device node is created. These include NAME, SYMLINK, OWNER,
| |
| GROUP and MODE, all of which are described in this document.
| |
| Common rules will use basic identification keys to determine the device
| |
| to name, and then have a NAME assignement key to define the device node
| |
| name. udev will only create one node for one device, so if you want it
| |
| to be accessible through multiple nodes, then you have to specify the
| |
| other nodes in the SYMLINK assignment key.
| |
| I'll take a slightly modified udev example rule to illustrate this:
| |
| BUS="usb", SYSFS{serial}="HXOLL0012202323480", NAME="lp_epson",
| |
| SYMLINK="printers/epson_stylus"
| |
| The identification keys here are BUS and SYSFS{serial}. The assignment
| |
| keys here are NAME and SYMLINK. udev will match this rule against a
| |
| device that is connected through the USB bus and with a serial number
| |
| of HXOLL0012202323480. '''Note that <u>all</u> (as opposed
| |
| to any) specified keys must be matched for udev to use the rule to name
| |
| a device.'''
| |
| udev will name this node lp_epson, and it will be located at
| |
| /dev/lp_epson.
| |
| udev will also create a symlink to /dev/lp_epson, located at
| |
| /dev/printers/epson_stylus (the printers directory will be
| |
| automatically created). You can now print to your Epson printer by
| |
| sending data to /dev/printers/epson_stylus or /dev/lp_epson.
| |
| Any rules that you have added or modified will '''not''' take effect
| |
| until you notify udev of this. Make sure you remember to run the
| |
| following every time you modify any rule files: # udevstart
| |
| ===Additional automated customisation for NAME and SYMLINK | |
| parameters===
| |
| In the NAME and SYMLINK parameters of your rules, you are able to use
| |
| basic operators to assist the naming of devices. Hackers will know this
| |
| sort of thing as ''[[printf]]-like string substitution''. There are a
| |
| number of operators which can compose some or all of your NAME/SYMLINK
| |
| parameters. These operators refer to kernel-data relating to the
| |
| device. Take this example: BUS="usb", SYSFS{vendor}="FUJIFILM",
| |
| SYSFS{model}="M100", NAME="camera%n"
| |
| The %n operator will be replaced with the "kernel number" for the
| |
| camera device, to produce a NAME such as camera0, camera1, etc.
| |
| Another common operator is %k. This represents what the kernel would
| |
| name the device, e.g. "hda1". You may often see rules which have
| |
| NAME="%k" to produce the default names for the hardware. In these
| |
| rules, customisation is usually done through the SYMLINK parameter.
| |
| A full list of operators, with explanations, can be found in the udev
| |
| man page.
| |
| ===Using shell-style pattern matching in keys===
| |
| You can use shell style pattern matching to provide even more
| |
| flexibility when writing keys. Taking a default udev rule:
| |
| KERNEL="ts*", NAME="input/%k"
| |
| The * operator is used here, which matches literally anything - zero,
| |
| one, or more characters of any kind. The rule literally says:
| |
| {| width=80% align=center
| |
| |-
| |
| |Match a device identified by a KERNEL name starting with the letters
| |
| "ts" optionally followed by anything at all, and name it with the
| |
| KERNEL name (%k) under the input directory.
| |
| |}
| |
| The ? operator is similar, and matches any single character (but not
| |
| zero characters).
| |
| You can also use square brackets [ ] to match any single character.
| |
| Direct quote from udev man page:
| |
| {| width=80% align=center
| |
| |-
| |
| |For example, the pattern string "tty[SR]" would match either "ttyS" or
| |
| "ttyR".
| |
| |}
| |
| You can also specify ranges that can be matched, e.g. [0-9] would match
| |
| any single digit. Using an example rule from a default udev
| |
| installation: KERNEL="fd[0-9]*", NAME="floppy/%n"
| |
| This rule says:
| |
| {| width=80%
| |
| |-
| |
| |Match a device identified by a KERNEL name starting with the letters
| |
| "fd", followed by any single digit, optionally followed by anything at
| |
| all. Name the device with the kernel number of the device (%n) under
| |
| the floppy directory.
| |
| |}
| |
| You can use these wildcards/pattern matches in any type of key,
| |
| including both basic keys and sysfs-based identification (see below for
| |
| explanations of these key types).
| |
| I have purposely left out some information on this topic (particularly
| |
| the flexibility of using [ ] operators) that is out of the scope of
| |
| basic rule-writing documentation. More information on this topic can be
| |
| found in the udev man page.
| |
| ===Key-writing basics===
| |
| udev provides a few basic key matching methods, and also provides
| |
| flexible ways of matching information in SYSFS. A typical rule will
| |
| match both normal keys (e.g. BUS and KERNEL), as well as SYSFS keys to
| |
| differentiate between different hardware plugged in throught the same
| |
| port.
| |
| You may be wondering, "How do I find the serial number of my printer?
| |
| What is the model of my camera?". Rule writing isn't as hard as it
| |
| sounds. The trickiest bit is finding your device in /sys, and deciding
| |
| which info to use.
| |
| ====Identifying devices through basic keys====
| |
| See the udev man page for more info on these keys.
| |
| The valid keys are:
| |
| * BUS - match the bus type of the device. | |
| * KERNEL - match the kernel device name.
| |
| * DRIVER - match the name of the kernel driver.
| |
| * SUBSYSTEM - match the kernel subsystem name.
| |
| * ID - match the device number on the bus (e.g. PCI bus ID).
| |
| * PLACE - match the physical position where the device is plugged into
| |
| (useful for USB).
| |
| The ID and PLACE keys do have their uses, but they are not commonly
| |
| used in rules. This document focuses on using BUS and KERNEL keys, as
| |
| well as SYSFS{...} keys (detailed in the next section). I will show how
| |
| to use these keys by example.
| |
| For extra flexibility, udev also provides keys to call external scripts
| |
| and examine their result, and to examine environment variables. This is
| |
| out of scope of this document. Look at the udev man page for more
| |
| details.
| |
| ====Identifying devices through SYSFS files====
| |
| Background information: SYSFS stores many small files under a tree of
| |
| directories which provide information about your hardware. One file
| |
| typically contains just one "data item" - e.g. device name,
| |
| manufacturer, or product ID.
| |
| Note that SYSFS{...} keys can be combined with the basic keys described
| |
| in the previous section.
| |
| You can use keys in the format SYSFS{filename} to match specific info
| |
| from SYSFS, where filename corresponds to a file in your SYSFS tree.
| |
| For example, when my camera is connected, there is a file located at
| |
| /sys/block/sda/device/model which contains "USB 2.0M DSC". To match
| |
| this, I could use the following key: SYSFS{model} = "USB 2.0M DSC"
| |
| '''Note that any file in sysfs can be matched in this manner, but if
| |
| you match more than one file (through multiple keys), then you must
| |
| only match files that exist in the same directory.''' Typically, there
| |
| will be several directories giving information about one device. You
| |
| cannot mix and match (as shown by example below).
| |
| Luckily, the process of rule writing does not entail hunting through
| |
| millions of files in SYSFS, the udevinfo utility does the hard work.
| |
| This program is included in the udev distribution.
| |
| The first thing you need to do is find a directory somewhere in /sys
| |
| that corresponds to your hardware, and includes a file named "dev", as
| |
| udevinfo can only work on directories of this type. These directories
| |
| are all found under either /sys/block or /sys/class - there is no point
| |
| looking anywhere else! However, udevinfo will follow links through this
| |
| directory and read info found from other sections of sysfs.
| |
| Once you have found a directory of this type, you can use the following
| |
| command to assist you in the creation of writing keys for udev rules: #
| |
| udevinfo -a -p /sys/path/to/hardware/info
| |
| You may find that finding the correct place in /sys to run udevinfo on
| |
| is not obvious. Chances are the device you just plugged in has already
| |
| careted a device node
| |
| (e.g. /dev/sda), in which case, udevinfo can be helpful! Taking the
| |
| example of my /dev/sda node, running the following command will point
| |
| you to the appropriate area of sysfs: # udevinfo -q path -n /dev/sda
| |
| /block/sda
| |
| The output of the command (shown above) is telling me that the sysfs
| |
| path to start at is /sys/block/sda. I would now run "udevinfo -a -p
| |
| /sys/block/sda". These two commands can be chained together, like so:
| |
| # udevinfo -a -p $(udevinfo -q path -n /dev/sda)
| |
| Sidenote: You may notice that we previously provided full paths
| |
| (/sys/some/path) to udevinfo beforehand, but now we are providing
| |
| sysfs-relative paths (/some/path) by chaining these commands. This does
| |
| not matter - both types of path are accepted.
| |
| Moving on to rule-writing, some snipped output of the results of my
| |
| "udevinfo -a -p /sys/block/sda" command is shown below, with colour
| |
| added.
| |
| <font color="#003300"> follow the class device's "device" looking
| |
| at the device chain at
| |
| '/sys/devices/pci0000:00/0000:00:02.1/usb3/3-3/3-3:1.0/host0/0:0:0:0':
| |
| BUS="scsi" ID="0:0:0:0" SYSFS{detach_state}="0" SYSFS{type}="0"
| |
| SYSFS{max_sectors}="240" SYSFS{device_blocked}="0"
| |
| SYSFS{queue_depth}="1" SYSFS{scsi_level}="3" SYSFS{vendor}=" "
| |
| SYSFS{model}="USB 2.0M DSC " SYSFS{rev}="1.00" SYSFS{online}="1"
| |
| </font>
| |
| <font color="#0000ff"> looking at the device chain at
| |
| '/sys/devices/pci0000:00/0000:00:02.1/usb3/3-3': BUS="usb" ID="3-3"
| |
| SYSFS{detach_state}="0" SYSFS{bNumInterfaces}=" 1"
| |
| SYSFS{bConfigurationValue}="1" SYSFS{bmAttributes}="c0"
| |
| SYSFS{bMaxPower}=" 0mA" SYSFS{idVendor}="052b" SYSFS{idProduct}="1514"
| |
| SYSFS{bcdDevice}="0100" SYSFS{bDeviceClass}="00"
| |
| SYSFS{bDeviceSubClass}="00" SYSFS{bDeviceProtocol}="00"
| |
| SYSFS{bNumConfigurations}="1" SYSFS{speed}="12"
| |
| SYSFS{manufacturer}="Tekom Technologies, Inc" SYSFS{product}="USB 2.0M
| |
| DSC"
| |
| </font>
| |
| The udevinfo tool provides a lot of information which you can simply
| |
| copy-paste as udev rules. The reason that I have colour coded the above
| |
| output is to point out that '''you generally cannot mix and match
| |
| information from different parts of the udevinfo output'''. In the
| |
| above output, I could not combine information from the different
| |
| coloured sections - this is because each section of output refers to a
| |
| different directory in SYSFS. For example, the following rule would not
| |
| work:
| |
| <font color="#003300">BUS="scsi",</font> <font
| |
| color="#0000ff">SYSFS{manufacturer}="Tekom Technologies, Inc",
| |
| NAME="%k"</font>
| |
| This rule would not work because I am combining information found in
| |
| the section beginning with BUS="scsi" (green) with information only
| |
| found in the blue section. The rule would work if I used BUS="usb",
| |
| sticking only to information found in the blue section above.
| |
| You will notice that a lot of information is not relevant for writing
| |
| basic rules (there is so much of it!), you should generally be looking
| |
| for information that you recognise and know will not change (e.g. model
| |
| name).
| |
| '''Note that if you write your own rule to identify a device, the
| |
| default devfs-style rules will not take effect!''' It is usually
| |
| sensible to use NAME="%k" and specify your own extra names in the
| |
| SYMLINK parameter so that you do not lose the default sensible names.
| |
| I will show three examples of this rule writing based on udevinfo
| |
| output process below. I will then attempt to list some device-dependant
| |
| tips and tricks for locating the correct info.
| |
| A reader wrote to me and informed me that he found KDE's control centre
| |
| useful for writing rules. Apparently, information about USB devices
| |
| (and others) can be found in the "Info Centre" section of the KDE
| |
| Control Centre. This interface shows information such as serial number,
| |
| vendor ID, etc. If you prefer a GUI-like approach, you might want to
| |
| investigate this.
| |
| The current releases of gnome-volume-manager are unable to treat
| |
| symlink-nodes as real devices. Conversely as described above, you may
| |
| wish to specify your own naming in the NAME parameter and specify %k in
| |
| the SYMLINK
| |
| parameter.
| |
| The behaviour of your own rules masking the defaults can be overcome if
| |
| you write multiple-SYMLINK style rules.
| |
| ===Using multiple SYMLINK style rules===
| |
| Another recent feature is the ability to write rules that do not
| |
| specify a NAME, but instead they simply specify SYMLINK keys. This
| |
| allows you to avoid the issue where your own rules effectively mask the
| |
| udev defaults.
| |
| Take the rule: KERNEL="hdc", SYMLINK="dvd"
| |
| When udev finds this rule, it will take a mental note of it. Upon
| |
| finding another rule matching the same device which also includes a
| |
| NAME parameter, udev will create the node as specified by the NAME
| |
| parameter, plus symbolic links as specified by the SYMLINK parameters
| |
| of both rules.
| |
| To put it into practical terms, when udev is naming nodes for my hdc
| |
| device, it will use the default rules for block devices as usual, with
| |
| the addition of my personal symlink "dvd".
| |
| Similarly to normal rules, rules of this type will only take effect if
| |
| udev is able to find them before it finds a rule specifying a NAME
| |
| parameter.
| |
| Controlling ownership and permissions
| |
| As well as controlling the naming of the device nodes which are
| |
| created, udev rules also allow you to control ownership and permission
| |
| attributes on that device node.
| |
| The GROUP key allows you to define which unix group should own the
| |
| device node. Here's an example from the udev defaults, which defines
| |
| that the video group will own framebuffer (fb) devices:
| |
| KERNEL="fb[0-9]*", NAME="fb/%n", SYMLINK="%k", GROUP="video"
| |
| The OWNER key, perhaps less useful, allows you to define which unix
| |
| user should own the device node. Assuming the slightly odd situation
| |
| where you would want "john" to own your floppy devices, you could use:
| |
| KERNEL="fd[0-9]*", OWNER="john"
| |
| You'll notice in the above rule that we didn't specify any NAME or
| |
| SYMLINK keys. This is similar to the multiple symlink style where udev
| |
| will take a mental note that we want john to own floppy nodes, and will
| |
| apply that ownership once it finds a rule which defines a NAME for the
| |
| floppy device nodes.
| |
| Building on the style mentioned above, you can do even more flashy
| |
| things. The udev defaults use the following rule to define that all the
| |
| sound device nodes shall be owned by the "audio" group:
| |
| SUBSYSTEM="sound", GROUP="audio"
| |
| This prevents the need to excessively provide a GROUP="audio" key on
| |
| every following rule which names sound devices.
| |
| udev defaults to creating nodes with unix permissions of 0660
| |
| (read/write to owner and group), which is configured by the
| |
| default_mode setting inside /etc/udev/udev.conf. There may be some
| |
| situations where you do not want to use the default permissions on your
| |
| device node. Fortunately, you can easily override the permissions in
| |
| your rules using the MODE assignment key. As an example, the following
| |
| rule defines that the inotify node shall be readable and writable to
| |
| everyone: KERNEL="inotify", NAME="misc/%k", SYMLINK="%k", MODE="0666"
| |
| Example: Writing a rule for my USB printer
| |
| After plugging in my printer, I started looking around some /sys
| |
| directories for a relevant place to start. I didn't get anywhere, but I
| |
| noticed that my printer had been given device node /dev/lp0. udevinfo
| |
| was able to provide me with a useful path: # udevinfo -q path -n
| |
| /dev/lp0 /class/usb/lp0
| |
| Running "udevinfo -a -p /sys/class/usb/lp0" provided me with a heap of
| |
| info, as usual. I picked out the relevant bits for unique device
| |
| identification:
| |
| looking at the device chain at
| |
| '/sys/devices/pci0000:00/0000:00:02.1/usb3/3-3': BUS="usb"
| |
| SYSFS{manufacturer}="EPSON" SYSFS{product}="USB Printer"
| |
| SYSFS{serial}="L72010011070626380"
| |
| My udev rule becomes: BUS="usb", SYSFS{serial}="L72010011070626380",
| |
| NAME="%k", SYMLINK="epson_680"
| |
| And my printer nodes exist at /dev/lp0 (or /dev/lp1 if another printer
| |
| was plugged in beforehand) and /dev/epson_680 always points at the
| |
| device node for that particular printer.
| |
| Example: Writing a rule for my USB-Storage digital camera
| |
| Quick Intro: My camera identifies itself as an external SCSI hard disk
| |
| (it uses the usb-storage driver which is also
| |
| used by devices such as USB hard disks and flash-card readers). I can
| |
| then mount the partition on that disk and copy images over. Not all
| |
| cameras work like this - many require external software (e.g. gphoto2)
| |
| to be able to access photos.
| |
| This one is a bit tricky. Several nodes are created by default when my
| |
| camera is connected : /dev/sda and /dev/sda1, and possibly even
| |
| /dev/sg1. This is an example where specifity is important - if your
| |
| rule is not specific enough, it could match any of the above 3 nodes.
| |
| sda1 is the node that I would like as my /dev/camera, as that is what
| |
| gets mounted. udevinfo did not point out any useful differences between
| |
| sda, sda1, and sg1. I decided that a reliable way to differentiate
| |
| between these 3 nodes would be to look at the KERNEL name.
| |
| A key such as KERNEL="sd?1" would match KERNEL names such as "sda1",
| |
| "sdb1", "sdc1", and equally importantly, it will not match KERNEL names
| |
| such as sda, sdb, or sg1. The purpose of this key is to ignore the
| |
| /dev/sda and /dev/sg1 nodes. The device is a digital camera - I would
| |
| not dream of fdisking it or anything like that, so these 2 nodes are
| |
| pretty useless to me. The key attempts to capture the /dev/sda1 node,
| |
| which is mountable and therefore useful!
| |
| As this node (sda1) is treated as a block device, looking in /sys/block
| |
| would be a good place to start.
| |
| In my /sys/block, I have a directory named sda. In my /sys/block/sda, I
| |
| have a directory named sda1. Both of these directories have dev files
| |
| in, so they are OK to run udevinfo on. Running the following dumps a
| |
| lot of information about my camera and the USB port it is connected
| |
| through.
| |
| # udevinfo -a -p /sys/block/sda/sda1
| |
| In the udevinfo output, I also noticed this bit of useful and
| |
| understandable information:
| |
| SYSFS{product}="USB 2.0M DSC"
| |
| So that gives me my rule. For completeness, I also include a BUS key
| |
| (this was also found in the udevinfo output).
| |
| BUS="usb", SYSFS{product}="USB 2.0M DSC", KERNEL="sd?1", NAME="%k",
| |
| SYMLINK="camera"
| |
| Now, when my camera is plugged in, it will be named /dev/sda1 (or, if
| |
| sda1 isnt available, it might be called /dev/sdb1) and will always be
| |
| correctly linked to from /dev/camera. The /dev/sda (or sdb) node still
| |
| appears as normal, but the important thing is that my custom persistent
| |
| "camera" symlink points to the mountable partition.
| |
| Additional notes on writing rules for USB storage
| |
| Carl Streeter, the owner of a large USB hard disk, wrote to me and
| |
| explained that unlike in my digital camera example, the /dev/sda node
| |
| is useful to him. He pointed out that he does occasionally need to use
| |
| tools such as fdisk and hdparm on that node.
| |
| Carl's rule is:
| |
| BUS="usb", KERNEL="sd*", SYSFS{product}="USB 2.0 Storage Device",
| |
| NAME="%k", SYMLINK="usbhd%n"
| |
| This rule creates symlinks such as:
| |
| * /dev/usbhd - The fdiskable node
| |
| * /dev/usbhd1 - The first partition (mountable)
| |
| * /dev/usbhd2 - The second partition (mountable)
| |
| We agreed that depending on the situation and device in question, there
| |
| are reasons for both wanting and not wanting the non-mountable /dev/sda
| |
| node. Use whichever setup suits you best.
| |
| Another difficult situation is having a multiple-slot USB-storage card
| |
| reader. These types of device generally do not inform the host when new
| |
| cards are plugged in or out, so plugging a card into an unused slot
| |
| while the reader is plugged in will not create the extra device node
| |
| needed for mounting!
| |
| This problem also applies to other USB disks - e.g. if you create a new
| |
| partition, the new partition node will not appear until you re-plug the
| |
| device.
| |
| udev provides a solution here - it is able to create nodes for all
| |
| partitions of a block device. For every rule that you specify, the
| |
| block device will have all 16 partition nodes created. To achieve this,
| |
| you can simply modify the NAME key, as shown below: BUS="usb",
| |
| SYSFS{product}="USB 2.0 Storage Device", NAME{all_partitions}="usbhd"
| |
| You will now have nodes named: usbhd, usbhd1, usbhd2, usbhd3, ...,
| |
| usbhd15.
| |
| ===Examples===
| |
| ====Writing convenience rules for my CD drives====
| |
| I have two CD drives in my PC - a DVD reader, and a CD rewriter. My
| |
| DVD is hdc and my CDRW is hdd. I would not expect this to change,
| |
| unless I manually changed the cabling of my system.
| |
| Still, some people (myself included) like to have nodes such as
| |
| /dev/dvd and /dev/cdrw for convenience. Since we know the "hdX" values
| |
| for these drives, writing rules is simple. The examples below should be
| |
| self explanatory. BUS="ide", KERNEL="hdc", NAME="%k", SYMLINK="dvd
| |
| cdroms/cdrom%n" BUS="ide", KERNEL="hdd", NAME="%k", SYMLINK="cdrw
| |
| cdroms/cdrom%n"
| |
| You may have noticed that the default 50-udev.rules file contains a
| |
| rule which runs a script to produces names for block devices. Do not be
| |
| confused by this - as usual, because your own rules are located in a
| |
| file which is processed before the default rules, the defaults will not
| |
| be used when naming the hardware you have written rules for.
| |
| ====Writing a rule for your USB Visor Palm Pilot====
| |
| These devices work as USB-serial devices, so by default, you only get
| |
| the ttyUSB1 node. The user-space palm utilities rely on /dev/pilot, so
| |
| you need to use a rule to create this. The following rule will do the
| |
| job: BUS="usb", SYSFS{product}="Palm Handheld", KERNEL="ttyUSB*",
| |
| SYMLINK="pilot"
| |
| This was adapted from Carsten Clasohm's blog entry, which includes a
| |
| useful discussion of the situation. You may also wish to add ownership
| |
| and permission keys to the rule to suit your setup.
| |
| ====Writing a rule to name my network interface====
| |
| An interesting new feature in recent udev versions is the ability to
| |
| rename your network interfaces, like the nameif utility does. Network
| |
| interfaces do not show up in /dev, but they are generally referenced by
| |
| names (e.g. with ifconfig). Despite the differences, the rule writing
| |
| process is almost identical.
| |
| As usual, udevinfo comes to our aid in rule-writing. In my example, I
| |
| wish to rename my "eth0" network device (the following output is
| |
| snipped): # udevinfo -a -p /sys/class/net/eth0/ looking at class device
| |
| '/sys/class/net/eth0': SYSFS{address}="00:52:8b:d5:04:48"
| |
| Every network adapter has its own unique MAC-address, so I chose to use
| |
| this when writing my rule. This will not change, unless you change your
| |
| network card. There is one caveat here: make sure you use the MAC
| |
| address you obtain from udevinfo (as above), because it is case
| |
| sensitive. Be careful when using utilities such as ifconfig as they
| |
| will capitalize the letters.
| |
| An example rule is shown below: KERNEL="eth*",
| |
| SYSFS{address}="00:52:8b:d5:04:48", NAME="lan"
| |
| You will need to reload the net driver for this rule to take effect.
| |
| You can either unload and reload the module, or simply reboot the
| |
| system. You will also need to reconfigure your system to use "lan"
| |
| rather than "eth0". I had some troubles getting this going (the
| |
| interface wasn't being renamed) until I had completely dropped all
| |
| references to eth0.
| |
| After that, you should be able to use "lan" instead of "eth0" in any
| |
| calls to ifconfig or similar utilities.
| |
| ===Tips for finding the appropriate places in SYSFS===
| |
| I'm looking for some more device specific tips here. Please contact me
| |
| with any you can provide.
| |
| * If the device you are looking to write rules for has created a device
| |
| node under /dev, then you are in luck! Run the following command to get
| |
| an appropriate /sys path: udevinfo -q path -n /dev/yournode
| |
| * Always use udevinfo to assist the rule-writing process. Always use
| |
| udevinfo to look under /sys/block or /sys/class (it will not start
| |
| reading a chain from anywhere else).
| |
| * If you get totally stuck, use the following command to find all "dev"
| |
| files under /sys (udevinfo can work on directories containing this
| |
| file): find /sys -iname dev
| |
| * If your device is a flash-card reader, usb flash-drive, or digital
| |
| camera that acts as usb-storage, that is created as /dev/sdX, then
| |
| start looking in /sys/block/sdX.
| |
| * If applicable, make sure you identify the difference between sdX and
| |
| sdX1 in the above situation. This can be done with the key
| |
| KERNEL="sd?1" to match sdX1, or KERNEL="sd?" to match sdX.
| |
| * For USB printers that are created as /dev/lpX, then you should start
| |
| looking in /sys/class/usb/lpX.
| |
| * The usb scanner driver has recently been removed from the kernel and
| |
| re-implemented in userspace (as part of the SANE package). You do not
| |
| (and can not) write rules for this hardware as it does not rely on
| |
| specific kernel drivers.
| |
| * Remember that unfortunately, the kernel does not export information
| |
| for all devices into sysfs, meaning that you simply can't write rules
| |
| for some devices yet. On 20/02/04, the udev author stated that there
| |
| are 162 drivers left to convert to sysfs.
| |
| ===Debugging your rules===
| |
| If you have written rules and remembered to run udevstart but they do
| |
| not appear to be taking effect, there are a couple of ways you can
| |
| debug them.
| |
| The file /etc/udev/udev.conf contains a udev_log option. Setting this
| |
| option to yes will cause udev to log some useful information about
| |
| which rules are being applied to which nodes into the system logger.
| |
| The logs will be included in /var/log/messages for most users.
| |
| Additionally, if you know the path in sysfs for the node you want to
| |
| create, you can use udevtest to see a rundown on what udev would do
| |
| with the node. For example: # udevtest /sys/class/sound/dsp/ version
| |
| 056 looking at '/class/sound/dsp/' opened class_dev->name='dsp'
| |
| configured rule in '/etc/udev/rules.d/50-udev.rules[132]' applied,
| |
| added symlink '%k' configured rule in
| |
| '/etc/udev/rules.d/50-udev.rules[132]' applied, 'dsp' becomes
| |
| 'sound/%k' creating device node '/dev/sound/dsp', major = '14', minor =
| |
| '3', mode = '0660', uid = '0', gid = '18'
| |
| udevtest is only a debugging/testing tool - it does not actually create
| |
| the device node, even though it says it doing so!
| |