1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
|
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE sect1 PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd" [
<!ENTITY % general-entities SYSTEM "../general.ent">
%general-entities;
]>
<sect1 id="ch-scripts-symlinks">
<?dbhtml filename="symlinks.html"?>
<title>Creating Custom Symlinks to Devices</title>
<sect2>
<title>CD-ROM symlinks</title>
<para>Some software that you may want to install later (e.g., various
media players) expect the /dev/cdrom and /dev/dvd symlinks to exist.
Also, it may be convenient to put references to those symlinks into
<filename>/etc/fstab</filename>. For each of your CD-ROM devices,
find the corresponding directory under
<filename class="directory">/sys</filename> (e.g., this can be
<filename class="directory">/sys/block/hdd</filename>) and
run a command similar to the following:</para>
<screen role="nodump"><userinput>udevtest /block/hdd</userinput></screen>
<para>Look at the lines containing the output of various *_id programs.</para>
<para>There are two approaches to creating symlinks. The first one is to
use the model name and the serial number, the second one is based on the
location of the device on the bus. If you are going to use the first
approach, create a file similar to the following:</para>
<screen role="nodump"><userinput>cat > /etc/udev/rules.d/70-persistent-cd.rules << EOF
<literal>
# Custom CD-ROM symlinks
SUBSYSTEM=="block", ENV{ID_MODEL}=="SAMSUNG_CD-ROM_SC-148F", \
ENV{ID_REVISION}=="PS05", ENV{GENERATED}="1", SYMLINK+="cdrom"
SUBSYSTEM=="block", ENV{ID_MODEL}=="PHILIPS_CDD5301", \
ENV{ID_SERIAL}=="5VO1306DM00190", ENV{GENERATED}="1", SYMLINK+="cdrom1 dvd"
</literal>
EOF</userinput></screen>
<note>
<para>Be aware that Udev does not recognize the backslash for line
continuation. The examples in this book work properly because both
the backslash and newline are ignored by the shell. This makes the
shell send each rule to cat on only one line. (The shell ignores
this sequence because the EOF string used in the here-document
redirection is not enclosed in either double or single quotes. For
more details, see the bash(1) manpage, and search it for "Here
Documents".)</para>
<para>If modifying Udev rules with an editor, be sure to leave each
rule on one physical line.</para>
</note>
<para>This way, the symlinks will stay correct even if you move the drives
to different positions on the IDE bus, but the
<filename>/dev/cdrom</filename> symlink won't be created if you replace
the old SAMSUNG CD-ROM with a new drive.</para>
<!-- The symlinks in the first approach survive even the transition
to libata for IDE drives, but that is not for the book. -->
<para>The SUBSYSTEM=="block" key is needed in order to avoid
matching SCSI generic devices. Without it, in the case with SCSI
CD-ROMs, the symlinks will sometimes point to the correct
<filename>/dev/srX</filename> devices, and sometimes to
<filename>/dev/sgX</filename>, which is wrong.</para>
<para>The ENV{GENERATED}="1" key is needed to prevent the Udev
75-cd-aliases-generator.rules file from overriding your custom
rules.</para>
<para>The second approach yields:</para>
<screen role="nodump"><userinput>cat > /etc/udev/rules.d/70-persistent-cd.rules << EOF
<literal>
# Custom CD-ROM symlinks
SUBSYSTEM=="block", ENV{ID_TYPE}=="cd", \
ENV{ID_PATH}=="pci-0000:00:07.1-ide-0:1", \
ENV{GENERATED}="1", SYMLINK+="cdrom"
SUBSYSTEM=="block", ENV{ID_TYPE}=="cd", \
ENV{ID_PATH}=="pci-0000:00:07.1-ide-1:1", \
ENV{GENERATED}="1", SYMLINK+="cdrom1 dvd"
</literal>
EOF</userinput></screen>
<para>This way, the symlinks will stay correct even if you replace drives
with different models, but place them to the old positions on the IDE
bus. The ENV{ID_TYPE}=="cd" key makes sure that the symlink
disappears if you put something other than a CD-ROM in that position on
the bus.</para>
<para>Of course, it is possible to mix the two approaches.</para>
</sect2>
<sect2>
<title>Dealing with duplicate devices</title>
<para>As explained in <xref linkend="ch-scripts-udev"/>, the order in
which devices with the same function appear in
<filename class="directory">/dev</filename> is essentially random.
E.g., if you have a USB web camera and a TV tuner, sometimes
<filename>/dev/video0</filename> refers to the camera and
<filename>/dev/video1</filename> refers to the tuner, and sometimes
after a reboot the order changes to the opposite one.
For all classes of hardware except sound cards and network cards, this is
fixable by creating udev rules for custom persistent symlinks.
The case of network cards is covered separately in
<xref linkend="ch-scripts-network"/>, and sound card configuration can
be found in <ulink url="&blfs-root;">BLFS</ulink>.</para>
<para>For each of your devices that is likely to have this problem
(even if the problem doesn't exist in your current Linux distribution),
find the corresponding directory under
<filename class="directory">/sys/class</filename> or
<filename class="directory">/sys/block</filename>.
For video devices, this may be
<filename
class="directory">/sys/class/video4linux/video<replaceable>X</replaceable></filename>.
Figure out the attributes that identify the device uniquely (usually,
vendor and product IDs and/or serial numbers work):</para>
<screen role="nodump"><userinput>udevinfo -a -p /sys/class/video4linux/video0</userinput></screen>
<para>Then write rules that create the symlinks, e.g.:</para>
<screen role="nodump"><userinput>cat > /etc/udev/rules.d/83-duplicate_devs.rules << EOF
<literal>
# Persistent symlinks for webcam and tuner
KERNEL=="video*", SYSFS{idProduct}=="1910", SYSFS{idVendor}=="0d81", \
SYMLINK+="webcam"
KERNEL=="video*", SYSFS{device}=="0x036f", SYSFS{vendor}=="0x109e", \
SYMLINK+="tvtuner"
</literal>
EOF</userinput></screen>
<para>The result is that <filename>/dev/video0</filename> and
<filename>/dev/video1</filename> devices still refer randomly to the tuner
and the web camera (and thus should never be used directly), but there are
symlinks <filename>/dev/tvtuner</filename> and
<filename>/dev/webcam</filename> that always point to the correct
device.</para>
<para>More information on writing Udev rules can be found in
<filename>/usr/share/doc/udev-&udev-version;/index.html</filename>.</para>
</sect2>
</sect1>
|