]>
Commit | Line | Data |
---|---|---|
2a5fcfae | 1 | #!/usr/bin/env perl |
8f5bcd61 | 2 | # SPDX-License-Identifier: LGPL-2.1-or-later |
a367f04e | 3 | |
438d4c3c | 4 | # udev test |
a367f04e GKH |
5 | # |
6 | # Provides automated testing of the udev binary. | |
7 | # The whole test is self contained in this file, except the matching sysfs tree. | |
8 | # Simply extend the @tests array, to add a new test variant. | |
9 | # | |
10 | # Every test is driven by its own temporary config file. | |
11 | # This program prepares the environment, creates the config and calls udev. | |
12 | # | |
65005a7f | 13 | # udev parses the rules, looks at the provided sysfs and |
a367f04e GKH |
14 | # first creates and then removes the device node. |
15 | # After creation and removal the result is checked against the | |
16 | # expected value and the result is printed. | |
17 | # | |
810adae9 | 18 | # Copyright © 2004 Leann Ogasawara <ogasawara@osdl.org> |
a367f04e GKH |
19 | |
20 | use warnings; | |
21 | use strict; | |
d4076383 ZJS |
22 | |
23 | BEGIN { | |
24 | my $EXIT_TEST_SKIP = 77; | |
25 | ||
26 | unless (eval "use POSIX qw(WIFEXITED WEXITSTATUS); | |
27 | use Cwd qw(getcwd abs_path); | |
28 | use IPC::Semaphore; | |
29 | use IPC::SysV qw(IPC_PRIVATE S_IRUSR S_IWUSR IPC_CREAT); | |
30 | use Time::HiRes qw(usleep); 1") { | |
31 | warn "Failed to import dependencies, skipping the test: $@"; | |
32 | exit($EXIT_TEST_SKIP); | |
33 | } | |
34 | } | |
a367f04e | 35 | |
9b80f05f | 36 | my $udev_bin = "./test-udev"; |
912541b0 | 37 | my $valgrind = 0; |
333e07b7 | 38 | my $gdb = 0; |
587751eb | 39 | my $strace = 0; |
b3f24900 | 40 | my $udev_bin_valgrind = "valgrind --tool=memcheck --leak-check=yes --track-origins=yes --quiet $udev_bin"; |
333e07b7 | 41 | my $udev_bin_gdb = "gdb --args $udev_bin"; |
587751eb | 42 | my $udev_bin_strace = "strace -efile $udev_bin"; |
6ada823a | 43 | my $udev_run = "test/run"; |
2ce8d27b | 44 | my $udev_tmpfs = "test/tmpfs"; |
21d9e3f3 EV |
45 | my $udev_sys = "${udev_tmpfs}/sys"; |
46 | my $udev_dev = "${udev_tmpfs}/dev"; | |
6ada823a KS |
47 | my $udev_rules_dir = "$udev_run/udev/rules.d"; |
48 | my $udev_rules = "$udev_rules_dir/udev-test.rules"; | |
0eb3cc88 | 49 | my $EXIT_TEST_SKIP = 77; |
a367f04e | 50 | |
bf8f7583 MP |
51 | my $rules_10k_tags = ""; |
52 | for (my $i = 1; $i <= 10000; ++$i) { | |
d3fc8bf4 | 53 | $rules_10k_tags .= 'KERNEL=="sda", TAG+="test' . $i . "\"\n"; |
bf8f7583 MP |
54 | } |
55 | ||
e37a5d90 YW |
56 | my $rules_10k_tags_continuation = "KERNEL==\"sda\", \\\n"; |
57 | for (my $i = 1; $i < 10000; ++$i) { | |
58 | $rules_10k_tags_continuation .= 'TAG+="test' . $i . "\",\\\n"; | |
1e797cf5 | 59 | } |
e37a5d90 | 60 | $rules_10k_tags_continuation .= "TAG+=\"test10000\"\\n"; |
1e797cf5 | 61 | |
eb44d715 MW |
62 | # Create a device list with all block devices under /sys |
63 | # (except virtual devices and cd-roms) | |
64 | # the optional argument exp_func returns expected and non-expected | |
65 | # symlinks for the device. | |
66 | sub all_block_devs { | |
67 | my ($exp_func) = @_; | |
68 | my @devices; | |
69 | ||
70 | foreach my $bd (glob "$udev_sys/dev/block/*") { | |
71 | my $tgt = readlink($bd); | |
72 | my ($exp, $notexp) = (undef, undef); | |
73 | ||
74 | next if ($tgt =~ m!/virtual/! || $tgt =~ m!/sr[0-9]*$!); | |
75 | ||
76 | $tgt =~ s!^\.\./\.\.!!; | |
77 | ($exp, $notexp) = $exp_func->($tgt) if defined($exp_func); | |
78 | my $device = { | |
79 | devpath => $tgt, | |
80 | exp_links => $exp, | |
81 | not_exp_links => $notexp, | |
82 | }; | |
83 | push(@devices, $device); | |
84 | } | |
85 | return \@devices; | |
86 | } | |
87 | ||
88 | # This generator returns a suitable exp_func for use with | |
89 | # all_block_devs(). | |
90 | sub expect_for_some { | |
91 | my ($pattern, $links, $donot) = @_; | |
92 | my $_expect = sub { | |
93 | my ($name) = @_; | |
94 | ||
95 | if ($name =~ /$pattern/) { | |
96 | return ($links, undef); | |
97 | } elsif ($donot) { | |
98 | return (undef, $links); | |
99 | } else { | |
100 | return (undef, undef); | |
101 | } | |
102 | }; | |
103 | return $_expect; | |
104 | } | |
105 | ||
a367f04e | 106 | my @tests = ( |
912541b0 KS |
107 | { |
108 | desc => "no rules", | |
255c05b7 MW |
109 | devices => [ |
110 | { | |
111 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", | |
255c05b7 MW |
112 | exp_rem_error => "yes", |
113 | }, | |
114 | { | |
115 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", | |
255c05b7 MW |
116 | exp_rem_error => "yes", |
117 | }], | |
912541b0 | 118 | rules => <<EOF |
5754e74c | 119 | # |
bcf44d55 | 120 | EOF |
912541b0 KS |
121 | }, |
122 | { | |
123 | desc => "label test of scsi disc", | |
255c05b7 MW |
124 | devices => [ |
125 | { | |
126 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", | |
e62acc31 | 127 | exp_links => ["boot_disk"], |
255c05b7 | 128 | }], |
912541b0 | 129 | rules => <<EOF |
0f52fdee | 130 | SUBSYSTEMS=="scsi", ATTRS{vendor}=="ATA", SYMLINK+="boot_disk%n" |
5754e74c | 131 | KERNEL=="ttyACM0", SYMLINK+="modem" |
c4edd0ad | 132 | EOF |
912541b0 KS |
133 | }, |
134 | { | |
135 | desc => "label test of scsi disc", | |
255c05b7 MW |
136 | devices => [ |
137 | { | |
138 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", | |
e62acc31 | 139 | exp_links => ["boot_disk"], |
255c05b7 | 140 | }], |
912541b0 | 141 | rules => <<EOF |
5754e74c KS |
142 | SUBSYSTEMS=="scsi", ATTRS{vendor}=="ATA", SYMLINK+="boot_disk%n" |
143 | KERNEL=="ttyACM0", SYMLINK+="modem" | |
c4edd0ad | 144 | EOF |
912541b0 KS |
145 | }, |
146 | { | |
147 | desc => "label test of scsi disc", | |
255c05b7 MW |
148 | devices => [ |
149 | { | |
150 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", | |
e62acc31 | 151 | exp_links => ["boot_disk"], |
255c05b7 | 152 | }], |
912541b0 | 153 | rules => <<EOF |
5754e74c KS |
154 | SUBSYSTEMS=="scsi", ATTRS{vendor}=="ATA", SYMLINK+="boot_disk%n" |
155 | KERNEL=="ttyACM0", SYMLINK+="modem" | |
a367f04e | 156 | EOF |
912541b0 KS |
157 | }, |
158 | { | |
159 | desc => "label test of scsi partition", | |
255c05b7 MW |
160 | devices => [ |
161 | { | |
162 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", | |
e62acc31 | 163 | exp_links => ["boot_disk1"], |
255c05b7 | 164 | }], |
912541b0 | 165 | rules => <<EOF |
5754e74c | 166 | SUBSYSTEMS=="scsi", ATTRS{vendor}=="ATA", SYMLINK+="boot_disk%n" |
83be97ba | 167 | EOF |
912541b0 KS |
168 | }, |
169 | { | |
170 | desc => "label test of pattern match", | |
255c05b7 MW |
171 | devices => [ |
172 | { | |
173 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", | |
e62acc31 MW |
174 | exp_links => ["boot_disk1", "boot_disk1-4", "boot_disk1-5"], |
175 | not_exp_links => ["boot_disk1-1", "boot_disk1-2", "boot_disk1-3"] | |
255c05b7 | 176 | }], |
912541b0 | 177 | rules => <<EOF |
5754e74c KS |
178 | SUBSYSTEMS=="scsi", ATTRS{vendor}=="?ATA", SYMLINK+="boot_disk%n-1" |
179 | SUBSYSTEMS=="scsi", ATTRS{vendor}=="ATA?", SYMLINK+="boot_disk%n-2" | |
180 | SUBSYSTEMS=="scsi", ATTRS{vendor}=="A??", SYMLINK+="boot_disk%n" | |
181 | SUBSYSTEMS=="scsi", ATTRS{vendor}=="ATAS", SYMLINK+="boot_disk%n-3" | |
e62acc31 MW |
182 | SUBSYSTEMS=="scsi", ATTRS{vendor}=="AT?", SYMLINK+="boot_disk%n-4" |
183 | SUBSYSTEMS=="scsi", ATTRS{vendor}=="??A", SYMLINK+="boot_disk%n-5" | |
358c8c20 | 184 | EOF |
912541b0 KS |
185 | }, |
186 | { | |
187 | desc => "label test of multiple sysfs files", | |
255c05b7 MW |
188 | devices => [ |
189 | { | |
190 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", | |
e62acc31 MW |
191 | exp_links => ["boot_disk1"], |
192 | not_exp_links => ["boot_diskX1"], | |
255c05b7 | 193 | }], |
912541b0 | 194 | rules => <<EOF |
5754e74c KS |
195 | SUBSYSTEMS=="scsi", ATTRS{vendor}=="ATA", ATTRS{model}=="ST910021AS X ", SYMLINK+="boot_diskX%n" |
196 | SUBSYSTEMS=="scsi", ATTRS{vendor}=="ATA", ATTRS{model}=="ST910021AS", SYMLINK+="boot_disk%n" | |
358c8c20 | 197 | EOF |
912541b0 KS |
198 | }, |
199 | { | |
200 | desc => "label test of max sysfs files (skip invalid rule)", | |
255c05b7 MW |
201 | devices => [ |
202 | { | |
203 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", | |
e62acc31 MW |
204 | exp_links => ["boot_disk1", "boot_diskXY1"], |
205 | not_exp_links => ["boot_diskXX1"], | |
255c05b7 | 206 | }], |
912541b0 | 207 | rules => <<EOF |
5754e74c | 208 | SUBSYSTEMS=="scsi", ATTRS{vendor}=="ATA", ATTRS{model}=="ST910021AS", ATTRS{scsi_level}=="6", ATTRS{rev}=="4.06", ATTRS{type}=="0", ATTRS{queue_depth}=="32", SYMLINK+="boot_diskXX%n" |
e62acc31 | 209 | SUBSYSTEMS=="scsi", ATTRS{vendor}=="ATA", ATTRS{model}=="ST910021AS", ATTRS{scsi_level}=="6", ATTRS{rev}=="4.06", ATTRS{type}=="0", ATTRS{queue_depth}=="1", SYMLINK+="boot_diskXY%n" |
5754e74c | 210 | SUBSYSTEMS=="scsi", ATTRS{vendor}=="ATA", ATTRS{model}=="ST910021AS", ATTRS{scsi_level}=="6", ATTRS{rev}=="4.06", ATTRS{type}=="0", SYMLINK+="boot_disk%n" |
0db6d4cc | 211 | EOF |
912541b0 KS |
212 | }, |
213 | { | |
214 | desc => "catch device by *", | |
255c05b7 MW |
215 | devices => [ |
216 | { | |
217 | devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", | |
e62acc31 | 218 | exp_links => ["modem/0", "catch-all"], |
255c05b7 | 219 | }], |
912541b0 | 220 | rules => <<EOF |
5754e74c | 221 | KERNEL=="ttyACM*", SYMLINK+="modem/%n" |
e62acc31 | 222 | KERNEL=="*", SYMLINK+="catch-all" |
2e317184 | 223 | EOF |
912541b0 | 224 | }, |
e62acc31 | 225 | # 10 |
912541b0 KS |
226 | { |
227 | desc => "catch device by * - take 2", | |
255c05b7 MW |
228 | devices => [ |
229 | { | |
230 | devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", | |
e62acc31 MW |
231 | exp_links => ["modem/0"], |
232 | not_exp_links => ["bad"], | |
255c05b7 | 233 | }], |
912541b0 | 234 | rules => <<EOF |
5754e74c KS |
235 | KERNEL=="*ACM1", SYMLINK+="bad" |
236 | KERNEL=="*ACM0", SYMLINK+="modem/%n" | |
9f1da361 | 237 | EOF |
912541b0 KS |
238 | }, |
239 | { | |
240 | desc => "catch device by ?", | |
255c05b7 MW |
241 | devices => [ |
242 | { | |
243 | devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", | |
e62acc31 MW |
244 | exp_links => ["modem/0"], |
245 | not_exp_links => ["modem/0-1", "modem/0-2"], | |
255c05b7 | 246 | }], |
912541b0 | 247 | rules => <<EOF |
5754e74c KS |
248 | KERNEL=="ttyACM??*", SYMLINK+="modem/%n-1" |
249 | KERNEL=="ttyACM??", SYMLINK+="modem/%n-2" | |
250 | KERNEL=="ttyACM?", SYMLINK+="modem/%n" | |
9f1da361 | 251 | EOF |
912541b0 KS |
252 | }, |
253 | { | |
254 | desc => "catch device by character class", | |
255c05b7 MW |
255 | devices => [ |
256 | { | |
257 | devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", | |
e62acc31 MW |
258 | exp_links => ["modem/0"], |
259 | not_exp_links => ["modem/0-1", "modem/0-2"], | |
255c05b7 | 260 | }], |
912541b0 | 261 | rules => <<EOF |
5754e74c KS |
262 | KERNEL=="ttyACM[A-Z]*", SYMLINK+="modem/%n-1" |
263 | KERNEL=="ttyACM?[0-9]", SYMLINK+="modem/%n-2" | |
264 | KERNEL=="ttyACM[0-9]*", SYMLINK+="modem/%n" | |
a367f04e | 265 | EOF |
912541b0 KS |
266 | }, |
267 | { | |
46bc71b2 | 268 | desc => "don't replace kernel name", |
255c05b7 MW |
269 | devices => [ |
270 | { | |
271 | devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", | |
e62acc31 | 272 | exp_links => ["modem"], |
255c05b7 | 273 | }], |
912541b0 | 274 | rules => <<EOF |
5754e74c | 275 | KERNEL=="ttyACM0", SYMLINK+="modem" |
281ff00a | 276 | EOF |
912541b0 KS |
277 | }, |
278 | { | |
46bc71b2 | 279 | desc => "Handle comment lines in config file (and don't replace kernel name)", |
255c05b7 MW |
280 | devices => [ |
281 | { | |
282 | devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", | |
e62acc31 | 283 | exp_links => ["modem"], |
255c05b7 | 284 | }], |
912541b0 | 285 | rules => <<EOF |
281ff00a | 286 | # this is a comment |
5754e74c | 287 | KERNEL=="ttyACM0", SYMLINK+="modem" |
281ff00a GKH |
288 | |
289 | EOF | |
912541b0 KS |
290 | }, |
291 | { | |
46bc71b2 | 292 | desc => "Handle comment lines in config file with whitespace (and don't replace kernel name)", |
255c05b7 MW |
293 | devices => [ |
294 | { | |
295 | devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", | |
e62acc31 | 296 | exp_links => ["modem"], |
255c05b7 | 297 | }], |
912541b0 | 298 | rules => <<EOF |
d914e445 | 299 | # this is a comment with whitespace before the comment |
5754e74c | 300 | KERNEL=="ttyACM0", SYMLINK+="modem" |
281ff00a | 301 | |
3db7fa27 | 302 | EOF |
912541b0 KS |
303 | }, |
304 | { | |
46bc71b2 | 305 | desc => "Handle whitespace only lines (and don't replace kernel name)", |
255c05b7 MW |
306 | devices => [ |
307 | { | |
308 | devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", | |
e62acc31 | 309 | exp_links => ["whitespace"], |
255c05b7 | 310 | }], |
912541b0 | 311 | rules => <<EOF |
3db7fa27 | 312 | |
3db7fa27 | 313 | |
d914e445 KS |
314 | |
315 | # this is a comment with whitespace before the comment | |
5754e74c | 316 | KERNEL=="ttyACM0", SYMLINK+="whitespace" |
3db7fa27 | 317 | |
d914e445 | 318 | |
3db7fa27 | 319 | |
281ff00a | 320 | EOF |
912541b0 KS |
321 | }, |
322 | { | |
46bc71b2 | 323 | desc => "Handle empty lines in config file (and don't replace kernel name)", |
255c05b7 MW |
324 | devices => [ |
325 | { | |
326 | devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", | |
e62acc31 | 327 | exp_links => ["modem"], |
255c05b7 | 328 | }], |
912541b0 | 329 | rules => <<EOF |
281ff00a | 330 | |
5754e74c | 331 | KERNEL=="ttyACM0", SYMLINK+="modem" |
281ff00a | 332 | |
9f8dfa19 | 333 | EOF |
912541b0 KS |
334 | }, |
335 | { | |
46bc71b2 | 336 | desc => "Handle backslashed multi lines in config file (and don't replace kernel name)", |
255c05b7 MW |
337 | devices => [ |
338 | { | |
339 | devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", | |
e62acc31 | 340 | exp_links => ["modem"], |
255c05b7 | 341 | }], |
912541b0 | 342 | rules => <<EOF |
c7fcba1b | 343 | KERNEL=="ttyACM0", \\ |
5754e74c | 344 | SYMLINK+="modem" |
9f8dfa19 | 345 | |
77313cd0 | 346 | EOF |
912541b0 KS |
347 | }, |
348 | { | |
349 | desc => "preserve backslashes, if they are not for a newline", | |
255c05b7 MW |
350 | devices => [ |
351 | { | |
352 | devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", | |
e62acc31 | 353 | exp_links => ["aaa"], |
255c05b7 | 354 | }], |
912541b0 | 355 | rules => <<EOF |
d914e445 | 356 | KERNEL=="ttyACM0", PROGRAM=="/bin/echo -e \\101", RESULT=="A", SYMLINK+="aaa" |
9f8dfa19 | 357 | EOF |
912541b0 | 358 | }, |
46bc71b2 | 359 | # 20 |
912541b0 | 360 | { |
46bc71b2 | 361 | desc => "Handle stupid backslashed multi lines in config file (and don't replace kernel name)", |
255c05b7 MW |
362 | devices => [ |
363 | { | |
364 | devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", | |
e62acc31 | 365 | exp_links => ["modem"], |
255c05b7 | 366 | }], |
912541b0 | 367 | rules => <<EOF |
9f8dfa19 KS |
368 | |
369 | # | |
370 | \\ | |
371 | ||
d960ad15 | 372 | \\ |
9f8dfa19 KS |
373 | |
374 | #\\ | |
375 | ||
c7fcba1b | 376 | KERNEL=="ttyACM0", \\ |
912541b0 | 377 | SYMLINK+="modem" |
9f8dfa19 | 378 | |
5499d319 | 379 | EOF |
912541b0 KS |
380 | }, |
381 | { | |
382 | desc => "subdirectory handling", | |
255c05b7 MW |
383 | devices => [ |
384 | { | |
385 | devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", | |
e62acc31 | 386 | exp_links => ["sub/direct/ory/modem"], |
255c05b7 | 387 | }], |
912541b0 | 388 | rules => <<EOF |
5754e74c | 389 | KERNEL=="ttyACM0", SYMLINK+="sub/direct/ory/modem" |
a367f04e | 390 | EOF |
912541b0 KS |
391 | }, |
392 | { | |
393 | desc => "parent device name match of scsi partition", | |
255c05b7 MW |
394 | devices => [ |
395 | { | |
396 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", | |
e62acc31 | 397 | exp_links => ["first_disk5"], |
255c05b7 | 398 | }], |
912541b0 | 399 | rules => <<EOF |
5754e74c | 400 | SUBSYSTEMS=="scsi", KERNELS=="0:0:0:0", SYMLINK+="first_disk%n" |
c4edd0ad | 401 | EOF |
912541b0 KS |
402 | }, |
403 | { | |
404 | desc => "test substitution chars", | |
255c05b7 MW |
405 | devices => [ |
406 | { | |
407 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", | |
e62acc31 | 408 | exp_links => ["Major:8:minor:5:kernelnumber:5:id:0:0:0:0"], |
255c05b7 | 409 | }], |
912541b0 | 410 | rules => <<EOF |
5754e74c | 411 | SUBSYSTEMS=="scsi", KERNELS=="0:0:0:0", SYMLINK+="Major:%M:minor:%m:kernelnumber:%n:id:%b" |
319c6700 | 412 | EOF |
912541b0 KS |
413 | }, |
414 | { | |
415 | desc => "import of shell-value returned from program", | |
255c05b7 MW |
416 | devices => [ |
417 | { | |
418 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", | |
e62acc31 | 419 | exp_links => ["node12345678"], |
255c05b7 | 420 | }], |
912541b0 | 421 | rules => <<EOF |
d914e445 | 422 | SUBSYSTEMS=="scsi", IMPORT{program}="/bin/echo -e \' TEST_KEY=12345678\\n TEST_key2=98765\'", SYMLINK+="node\$env{TEST_KEY}" |
5754e74c | 423 | KERNEL=="ttyACM0", SYMLINK+="modem" |
a27cd06c | 424 | EOF |
912541b0 KS |
425 | }, |
426 | { | |
d3f044dd | 427 | desc => "substitution of sysfs value (%s{file})", |
255c05b7 MW |
428 | devices => [ |
429 | { | |
430 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", | |
e62acc31 MW |
431 | exp_links => ["disk-ATA-sda"], |
432 | not_exp_links => ["modem"], | |
255c05b7 | 433 | }], |
912541b0 | 434 | rules => <<EOF |
5754e74c KS |
435 | SUBSYSTEMS=="scsi", ATTRS{vendor}=="ATA", SYMLINK+="disk-%s{vendor}-%k" |
436 | KERNEL=="ttyACM0", SYMLINK+="modem" | |
a367f04e | 437 | EOF |
912541b0 KS |
438 | }, |
439 | { | |
440 | desc => "program result substitution", | |
255c05b7 MW |
441 | devices => [ |
442 | { | |
443 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", | |
e62acc31 MW |
444 | exp_links => ["special-device-5"], |
445 | not_exp_links => ["not"], | |
255c05b7 | 446 | }], |
912541b0 | 447 | rules => <<EOF |
d914e445 KS |
448 | SUBSYSTEMS=="scsi", PROGRAM=="/bin/echo -n special-device", RESULT=="-special-*", SYMLINK+="not" |
449 | SUBSYSTEMS=="scsi", PROGRAM=="/bin/echo -n special-device", RESULT=="special-*", SYMLINK+="%c-%n" | |
bbbe503e | 450 | EOF |
912541b0 KS |
451 | }, |
452 | { | |
453 | desc => "program result substitution (newline removal)", | |
255c05b7 MW |
454 | devices => [ |
455 | { | |
456 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", | |
e62acc31 | 457 | exp_links => ["newline_removed"], |
255c05b7 | 458 | }], |
912541b0 | 459 | rules => <<EOF |
d914e445 | 460 | SUBSYSTEMS=="scsi", PROGRAM=="/bin/echo test", RESULT=="test", SYMLINK+="newline_removed" |
f3b04a2e | 461 | EOF |
912541b0 KS |
462 | }, |
463 | { | |
464 | desc => "program result substitution", | |
255c05b7 MW |
465 | devices => [ |
466 | { | |
467 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", | |
e62acc31 | 468 | exp_links => ["test-0:0:0:0"], |
255c05b7 | 469 | }], |
912541b0 | 470 | rules => <<EOF |
d914e445 | 471 | SUBSYSTEMS=="scsi", PROGRAM=="/bin/echo -n test-%b", RESULT=="test-0:0*", SYMLINK+="%c" |
dde05ccb | 472 | EOF |
912541b0 KS |
473 | }, |
474 | { | |
475 | desc => "program with lots of arguments", | |
255c05b7 MW |
476 | devices => [ |
477 | { | |
478 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", | |
e62acc31 MW |
479 | exp_links => ["foo9"], |
480 | not_exp_links => ["foo3", "foo4", "foo5", "foo6", "foo7", "foo8"], | |
255c05b7 | 481 | }], |
912541b0 | 482 | rules => <<EOF |
d914e445 | 483 | SUBSYSTEMS=="scsi", PROGRAM=="/bin/echo -n foo3 foo4 foo5 foo6 foo7 foo8 foo9", KERNEL=="sda5", SYMLINK+="%c{7}" |
35b38379 | 484 | EOF |
912541b0 KS |
485 | }, |
486 | { | |
487 | desc => "program with subshell", | |
255c05b7 MW |
488 | devices => [ |
489 | { | |
490 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", | |
e62acc31 MW |
491 | exp_links => ["bar9"], |
492 | not_exp_links => ["foo3", "foo4", "foo5", "foo6", "foo7", "foo8"], | |
255c05b7 | 493 | }], |
912541b0 | 494 | rules => <<EOF |
d914e445 | 495 | SUBSYSTEMS=="scsi", PROGRAM=="/bin/sh -c 'echo foo3 foo4 foo5 foo6 foo7 foo8 foo9 | sed s/foo9/bar9/'", KERNEL=="sda5", SYMLINK+="%c{7}" |
35b38379 | 496 | EOF |
912541b0 KS |
497 | }, |
498 | { | |
499 | desc => "program arguments combined with apostrophes", | |
255c05b7 MW |
500 | devices => [ |
501 | { | |
502 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", | |
e62acc31 MW |
503 | exp_links => ["foo7"], |
504 | not_exp_links => ["foo3", "foo4", "foo5", "foo6", "foo8"], | |
255c05b7 | 505 | }], |
912541b0 | 506 | rules => <<EOF |
d914e445 | 507 | SUBSYSTEMS=="scsi", PROGRAM=="/bin/echo -n 'foo3 foo4' 'foo5 foo6 foo7 foo8'", KERNEL=="sda5", SYMLINK+="%c{5}" |
7e760b79 FB |
508 | EOF |
509 | }, | |
510 | { | |
511 | desc => "program arguments combined with escaped double quotes, part 1", | |
255c05b7 MW |
512 | devices => [ |
513 | { | |
514 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", | |
e62acc31 MW |
515 | exp_links => ["foo2"], |
516 | not_exp_links => ["foo1"], | |
255c05b7 | 517 | }], |
7e760b79 FB |
518 | rules => <<EOF |
519 | SUBSYSTEMS=="scsi", PROGRAM=="/bin/sh -c 'printf %%s \\\"foo1 foo2\\\" | grep \\\"foo1 foo2\\\"'", KERNEL=="sda5", SYMLINK+="%c{2}" | |
520 | EOF | |
521 | }, | |
522 | { | |
523 | desc => "program arguments combined with escaped double quotes, part 2", | |
255c05b7 MW |
524 | devices => [ |
525 | { | |
526 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", | |
e62acc31 MW |
527 | exp_links => ["foo2"], |
528 | not_exp_links => ["foo1"], | |
255c05b7 | 529 | }], |
7e760b79 FB |
530 | rules => <<EOF |
531 | SUBSYSTEMS=="scsi", PROGRAM=="/bin/sh -c \\\"printf %%s 'foo1 foo2' | grep 'foo1 foo2'\\\"", KERNEL=="sda5", SYMLINK+="%c{2}" | |
532 | EOF | |
533 | }, | |
534 | { | |
535 | desc => "program arguments combined with escaped double quotes, part 3", | |
255c05b7 MW |
536 | devices => [ |
537 | { | |
538 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", | |
e62acc31 MW |
539 | exp_links => ["foo2"], |
540 | not_exp_links => ["foo1", "foo3"], | |
255c05b7 | 541 | }], |
7e760b79 FB |
542 | rules => <<EOF |
543 | SUBSYSTEMS=="scsi", PROGRAM=="/bin/sh -c 'printf \\\"%%s %%s\\\" \\\"foo1 foo2\\\" \\\"foo3\\\"| grep \\\"foo1 foo2\\\"'", KERNEL=="sda5", SYMLINK+="%c{2}" | |
56c963dc | 544 | EOF |
912541b0 KS |
545 | }, |
546 | { | |
547 | desc => "characters before the %c{N} substitution", | |
255c05b7 MW |
548 | devices => [ |
549 | { | |
550 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", | |
e62acc31 | 551 | exp_links => ["my-foo9"], |
255c05b7 | 552 | }], |
912541b0 | 553 | rules => <<EOF |
d914e445 | 554 | SUBSYSTEMS=="scsi", PROGRAM=="/bin/echo -n foo3 foo4 foo5 foo6 foo7 foo8 foo9", KERNEL=="sda5", SYMLINK+="my-%c{7}" |
56c963dc | 555 | EOF |
912541b0 KS |
556 | }, |
557 | { | |
558 | desc => "substitute the second to last argument", | |
255c05b7 MW |
559 | devices => [ |
560 | { | |
561 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", | |
e62acc31 MW |
562 | exp_links => ["my-foo8"], |
563 | not_exp_links => ["my-foo3", "my-foo4", "my-foo5", "my-foo6", "my-foo7", "my-foo9"], | |
255c05b7 | 564 | }], |
912541b0 | 565 | rules => <<EOF |
d914e445 | 566 | SUBSYSTEMS=="scsi", PROGRAM=="/bin/echo -n foo3 foo4 foo5 foo6 foo7 foo8 foo9", KERNEL=="sda5", SYMLINK+="my-%c{6}" |
bf5d2964 | 567 | EOF |
912541b0 KS |
568 | }, |
569 | { | |
570 | desc => "test substitution by variable name", | |
255c05b7 MW |
571 | devices => [ |
572 | { | |
573 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", | |
e62acc31 | 574 | exp_links => ["Major:8-minor:5-kernelnumber:5-id:0:0:0:0"], |
255c05b7 | 575 | }], |
912541b0 | 576 | rules => <<EOF |
5754e74c | 577 | SUBSYSTEMS=="scsi", KERNELS=="0:0:0:0", SYMLINK+="Major:\$major-minor:\$minor-kernelnumber:\$number-id:\$id" |
bf5d2964 | 578 | EOF |
912541b0 KS |
579 | }, |
580 | { | |
581 | desc => "test substitution by variable name 2", | |
255c05b7 MW |
582 | devices => [ |
583 | { | |
584 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", | |
e62acc31 | 585 | exp_links => ["Major:8-minor:5-kernelnumber:5-id:0:0:0:0"], |
255c05b7 | 586 | }], |
912541b0 | 587 | rules => <<EOF |
5754e74c | 588 | SUBSYSTEMS=="scsi", KERNELS=="0:0:0:0", DEVPATH=="*/sda/*", SYMLINK+="Major:\$major-minor:%m-kernelnumber:\$number-id:\$id" |
bf5d2964 | 589 | EOF |
912541b0 KS |
590 | }, |
591 | { | |
592 | desc => "test substitution by variable name 3", | |
255c05b7 MW |
593 | devices => [ |
594 | { | |
595 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", | |
e62acc31 | 596 | exp_links => ["850:0:0:05"], |
255c05b7 | 597 | }], |
912541b0 | 598 | rules => <<EOF |
5754e74c | 599 | SUBSYSTEMS=="scsi", KERNELS=="0:0:0:0", DEVPATH=="*/sda/*", SYMLINK+="%M%m%b%n" |
bf5d2964 | 600 | EOF |
912541b0 KS |
601 | }, |
602 | { | |
603 | desc => "test substitution by variable name 4", | |
255c05b7 MW |
604 | devices => [ |
605 | { | |
606 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", | |
e62acc31 | 607 | exp_links => ["855"], |
255c05b7 | 608 | }], |
912541b0 | 609 | rules => <<EOF |
5754e74c | 610 | SUBSYSTEMS=="scsi", KERNELS=="0:0:0:0", DEVPATH=="*/sda/*", SYMLINK+="\$major\$minor\$number" |
bf5d2964 | 611 | EOF |
912541b0 KS |
612 | }, |
613 | { | |
614 | desc => "test substitution by variable name 5", | |
255c05b7 MW |
615 | devices => [ |
616 | { | |
617 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", | |
e62acc31 | 618 | exp_links => ["8550:0:0:0"], |
255c05b7 | 619 | }], |
912541b0 | 620 | rules => <<EOF |
5754e74c | 621 | SUBSYSTEMS=="scsi", KERNELS=="0:0:0:0", DEVPATH=="*/sda/*", SYMLINK+="\$major%m%n\$id" |
8ff8bbba | 622 | EOF |
912541b0 KS |
623 | }, |
624 | { | |
625 | desc => "non matching SUBSYSTEMS for device with no parent", | |
255c05b7 MW |
626 | devices => [ |
627 | { | |
628 | devpath => "/devices/virtual/tty/console", | |
e62acc31 MW |
629 | exp_links => ["TTY"], |
630 | not_exp_links => ["foo"], | |
255c05b7 | 631 | }], |
912541b0 | 632 | rules => <<EOF |
d914e445 | 633 | SUBSYSTEMS=="scsi", PROGRAM=="/bin/echo -n foo", RESULT=="foo", SYMLINK+="foo" |
5754e74c | 634 | KERNEL=="console", SYMLINK+="TTY" |
1d936fbc | 635 | EOF |
912541b0 KS |
636 | }, |
637 | { | |
638 | desc => "non matching SUBSYSTEMS", | |
255c05b7 MW |
639 | devices => [ |
640 | { | |
641 | devpath => "/devices/virtual/tty/console", | |
e62acc31 MW |
642 | exp_links => ["TTY"], |
643 | not_exp_links => ["foo"], | |
255c05b7 | 644 | }], |
912541b0 | 645 | rules => <<EOF |
5754e74c KS |
646 | SUBSYSTEMS=="foo", ATTRS{dev}=="5:1", SYMLINK+="foo" |
647 | KERNEL=="console", SYMLINK+="TTY" | |
64682333 | 648 | EOF |
912541b0 KS |
649 | }, |
650 | { | |
651 | desc => "ATTRS match", | |
255c05b7 MW |
652 | devices => [ |
653 | { | |
654 | devpath => "/devices/virtual/tty/console", | |
e62acc31 | 655 | exp_links => ["foo", "TTY"], |
255c05b7 | 656 | }], |
912541b0 | 657 | rules => <<EOF |
5754e74c KS |
658 | KERNEL=="console", SYMLINK+="TTY" |
659 | ATTRS{dev}=="5:1", SYMLINK+="foo" | |
a402404f | 660 | EOF |
912541b0 KS |
661 | }, |
662 | { | |
663 | desc => "ATTR (empty file)", | |
255c05b7 MW |
664 | devices => [ |
665 | { | |
666 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", | |
e62acc31 MW |
667 | exp_links => ["empty", "not-something"], |
668 | not_exp_links => ["something", "not-empty"], | |
255c05b7 | 669 | }], |
912541b0 | 670 | rules => <<EOF |
5754e74c KS |
671 | KERNEL=="sda", ATTR{test_empty_file}=="?*", SYMLINK+="something" |
672 | KERNEL=="sda", ATTR{test_empty_file}!="", SYMLINK+="not-empty" | |
673 | KERNEL=="sda", ATTR{test_empty_file}=="", SYMLINK+="empty" | |
674 | KERNEL=="sda", ATTR{test_empty_file}!="?*", SYMLINK+="not-something" | |
a402404f | 675 | EOF |
912541b0 KS |
676 | }, |
677 | { | |
678 | desc => "ATTR (non-existent file)", | |
255c05b7 MW |
679 | devices => [ |
680 | { | |
681 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", | |
e62acc31 MW |
682 | exp_links => ["non-existent", "wrong"], |
683 | not_exp_links => ["something", "empty", "not-empty", | |
684 | "not-something", "something"], | |
255c05b7 | 685 | }], |
912541b0 | 686 | rules => <<EOF |
5754e74c KS |
687 | KERNEL=="sda", ATTR{nofile}=="?*", SYMLINK+="something" |
688 | KERNEL=="sda", ATTR{nofile}!="", SYMLINK+="not-empty" | |
689 | KERNEL=="sda", ATTR{nofile}=="", SYMLINK+="empty" | |
690 | KERNEL=="sda", ATTR{nofile}!="?*", SYMLINK+="not-something" | |
691 | KERNEL=="sda", TEST!="nofile", SYMLINK+="non-existent" | |
692 | KERNEL=="sda", SYMLINK+="wrong" | |
772558f4 | 693 | EOF |
912541b0 KS |
694 | }, |
695 | { | |
696 | desc => "program and bus type match", | |
255c05b7 MW |
697 | devices => [ |
698 | { | |
699 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", | |
e62acc31 | 700 | exp_links => ["scsi-0:0:0:0"], |
255c05b7 | 701 | }], |
912541b0 | 702 | rules => <<EOF |
d914e445 KS |
703 | SUBSYSTEMS=="usb", PROGRAM=="/bin/echo -n usb-%b", SYMLINK+="%c" |
704 | SUBSYSTEMS=="scsi", PROGRAM=="/bin/echo -n scsi-%b", SYMLINK+="%c" | |
705 | SUBSYSTEMS=="foo", PROGRAM=="/bin/echo -n foo-%b", SYMLINK+="%c" | |
50e5de03 | 706 | EOF |
912541b0 KS |
707 | }, |
708 | { | |
709 | desc => "sysfs parent hierarchy", | |
255c05b7 MW |
710 | devices => [ |
711 | { | |
712 | devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", | |
e62acc31 | 713 | exp_links => ["modem"], |
255c05b7 | 714 | }], |
912541b0 | 715 | rules => <<EOF |
5754e74c | 716 | ATTRS{idProduct}=="007b", SYMLINK+="modem" |
f0142622 | 717 | EOF |
912541b0 KS |
718 | }, |
719 | { | |
720 | desc => "name test with ! in the name", | |
255c05b7 MW |
721 | devices => [ |
722 | { | |
723 | devpath => "/devices/virtual/block/fake!blockdev0", | |
f0dccf01 | 724 | devnode => "fake/blockdev0", |
e62acc31 MW |
725 | exp_links => ["is/a/fake/blockdev0"], |
726 | not_exp_links => ["is/not/a/fake/blockdev0", "modem"], | |
255c05b7 | 727 | }], |
912541b0 | 728 | rules => <<EOF |
5754e74c KS |
729 | SUBSYSTEMS=="scsi", SYMLINK+="is/not/a/%k" |
730 | SUBSYSTEM=="block", SYMLINK+="is/a/%k" | |
731 | KERNEL=="ttyACM0", SYMLINK+="modem" | |
b9fc973b | 732 | EOF |
912541b0 KS |
733 | }, |
734 | { | |
735 | desc => "name test with ! in the name, but no matching rule", | |
255c05b7 MW |
736 | devices => [ |
737 | { | |
738 | devpath => "/devices/virtual/block/fake!blockdev0", | |
f0dccf01 | 739 | devnode => "fake/blockdev0", |
e62acc31 | 740 | not_exp_links => ["modem"], |
255c05b7 | 741 | }], |
912541b0 | 742 | rules => <<EOF |
5754e74c | 743 | KERNEL=="ttyACM0", SYMLINK+="modem" |
93656247 | 744 | EOF |
912541b0 KS |
745 | }, |
746 | { | |
747 | desc => "KERNELS rule", | |
255c05b7 MW |
748 | devices => [ |
749 | { | |
750 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", | |
e62acc31 MW |
751 | exp_links => ["scsi-0:0:0:0"], |
752 | not_exp_links => ["no-match", "short-id", "not-scsi"], | |
255c05b7 | 753 | }], |
912541b0 | 754 | rules => <<EOF |
5754e74c KS |
755 | SUBSYSTEMS=="usb", KERNELS=="0:0:0:0", SYMLINK+="not-scsi" |
756 | SUBSYSTEMS=="scsi", KERNELS=="0:0:0:1", SYMLINK+="no-match" | |
757 | SUBSYSTEMS=="scsi", KERNELS==":0", SYMLINK+="short-id" | |
758 | SUBSYSTEMS=="scsi", KERNELS=="/0:0:0:0", SYMLINK+="no-match" | |
759 | SUBSYSTEMS=="scsi", KERNELS=="0:0:0:0", SYMLINK+="scsi-0:0:0:0" | |
93656247 | 760 | EOF |
912541b0 KS |
761 | }, |
762 | { | |
763 | desc => "KERNELS wildcard all", | |
255c05b7 MW |
764 | devices => [ |
765 | { | |
766 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", | |
e62acc31 MW |
767 | exp_links => ["scsi-0:0:0:0"], |
768 | not_exp_links => ["no-match", "before"], | |
255c05b7 | 769 | }], |
912541b0 | 770 | rules => <<EOF |
5754e74c KS |
771 | SUBSYSTEMS=="scsi", KERNELS=="*:1", SYMLINK+="no-match" |
772 | SUBSYSTEMS=="scsi", KERNELS=="*:0:1", SYMLINK+="no-match" | |
773 | SUBSYSTEMS=="scsi", KERNELS=="*:0:0:1", SYMLINK+="no-match" | |
774 | SUBSYSTEMS=="scsi", KERNEL=="0:0:0:0", SYMLINK+="before" | |
775 | SUBSYSTEMS=="scsi", KERNELS=="*", SYMLINK+="scsi-0:0:0:0" | |
93656247 | 776 | EOF |
912541b0 KS |
777 | }, |
778 | { | |
779 | desc => "KERNELS wildcard partial", | |
255c05b7 MW |
780 | devices => [ |
781 | { | |
782 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", | |
e62acc31 | 783 | exp_links => ["scsi-0:0:0:0", "before"], |
255c05b7 | 784 | }], |
912541b0 | 785 | rules => <<EOF |
5754e74c KS |
786 | SUBSYSTEMS=="scsi", KERNELS=="0:0:0:0", SYMLINK+="before" |
787 | SUBSYSTEMS=="scsi", KERNELS=="*:0", SYMLINK+="scsi-0:0:0:0" | |
93656247 | 788 | EOF |
912541b0 KS |
789 | }, |
790 | { | |
791 | desc => "KERNELS wildcard partial 2", | |
255c05b7 MW |
792 | devices => [ |
793 | { | |
794 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", | |
e62acc31 | 795 | exp_links => ["scsi-0:0:0:0", "before"], |
255c05b7 MW |
796 | }], |
797 | rules => <<EOF | |
5754e74c KS |
798 | SUBSYSTEMS=="scsi", KERNELS=="0:0:0:0", SYMLINK+="before" |
799 | SUBSYSTEMS=="scsi", KERNELS=="*:0:0:0", SYMLINK+="scsi-0:0:0:0" | |
eef54479 | 800 | EOF |
912541b0 KS |
801 | }, |
802 | { | |
803 | desc => "substitute attr with link target value (first match)", | |
255c05b7 MW |
804 | devices => [ |
805 | { | |
806 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", | |
e62acc31 | 807 | exp_links => ["driver-is-sd"], |
255c05b7 | 808 | }], |
912541b0 | 809 | rules => <<EOF |
5754e74c | 810 | SUBSYSTEMS=="scsi", SYMLINK+="driver-is-\$attr{driver}" |
eef54479 | 811 | EOF |
912541b0 KS |
812 | }, |
813 | { | |
814 | desc => "substitute attr with link target value (currently selected device)", | |
255c05b7 MW |
815 | devices => [ |
816 | { | |
817 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", | |
e62acc31 | 818 | exp_links => ["driver-is-ahci"], |
255c05b7 | 819 | }], |
912541b0 | 820 | rules => <<EOF |
5754e74c | 821 | SUBSYSTEMS=="pci", SYMLINK+="driver-is-\$attr{driver}" |
d5f91372 | 822 | EOF |
912541b0 KS |
823 | }, |
824 | { | |
825 | desc => "ignore ATTRS attribute whitespace", | |
255c05b7 MW |
826 | devices => [ |
827 | { | |
828 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", | |
e62acc31 | 829 | exp_links => ["ignored"], |
255c05b7 | 830 | }], |
912541b0 | 831 | rules => <<EOF |
5754e74c | 832 | SUBSYSTEMS=="scsi", ATTRS{whitespace_test}=="WHITE SPACE", SYMLINK+="ignored" |
d5f91372 | 833 | EOF |
912541b0 KS |
834 | }, |
835 | { | |
836 | desc => "do not ignore ATTRS attribute whitespace", | |
255c05b7 MW |
837 | devices => [ |
838 | { | |
839 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", | |
e62acc31 MW |
840 | exp_links => ["matched-with-space"], |
841 | not_exp_links => ["wrong-to-ignore"], | |
255c05b7 | 842 | }], |
912541b0 | 843 | rules => <<EOF |
5754e74c KS |
844 | SUBSYSTEMS=="scsi", ATTRS{whitespace_test}=="WHITE SPACE ", SYMLINK+="wrong-to-ignore" |
845 | SUBSYSTEMS=="scsi", ATTRS{whitespace_test}=="WHITE SPACE ", SYMLINK+="matched-with-space" | |
0a5417a0 | 846 | EOF |
912541b0 KS |
847 | }, |
848 | { | |
849 | desc => "permissions USER=bad GROUP=name", | |
255c05b7 MW |
850 | devices => [ |
851 | { | |
852 | devpath => "/devices/virtual/tty/tty33", | |
255c05b7 MW |
853 | exp_perms => "0:0:0600", |
854 | }], | |
912541b0 | 855 | rules => <<EOF |
6ada823a | 856 | KERNEL=="tty33", OWNER="bad", GROUP="name" |
b8669191 | 857 | EOF |
912541b0 KS |
858 | }, |
859 | { | |
9158d03e | 860 | desc => "permissions OWNER=1", |
255c05b7 MW |
861 | devices => [ |
862 | { | |
863 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", | |
e62acc31 | 864 | exp_links => ["node"], |
255c05b7 MW |
865 | exp_perms => "1::0600", |
866 | }], | |
912541b0 | 867 | rules => <<EOF |
9158d03e | 868 | SUBSYSTEMS=="scsi", KERNEL=="sda", SYMLINK+="node", OWNER="1" |
b8669191 | 869 | EOF |
912541b0 KS |
870 | }, |
871 | { | |
9158d03e | 872 | desc => "permissions GROUP=1", |
255c05b7 MW |
873 | devices => [ |
874 | { | |
875 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", | |
e62acc31 | 876 | exp_links => ["node"], |
255c05b7 MW |
877 | exp_perms => ":1:0660", |
878 | }], | |
912541b0 | 879 | rules => <<EOF |
9158d03e | 880 | SUBSYSTEMS=="scsi", KERNEL=="sda", SYMLINK+="node", GROUP="1" |
9b434de1 | 881 | EOF |
912541b0 KS |
882 | }, |
883 | { | |
884 | desc => "textual user id", | |
255c05b7 MW |
885 | devices => [ |
886 | { | |
887 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", | |
e62acc31 | 888 | exp_links => ["node"], |
255c05b7 MW |
889 | exp_perms => "daemon::0600", |
890 | }], | |
912541b0 | 891 | rules => <<EOF |
24a01950 | 892 | SUBSYSTEMS=="scsi", KERNEL=="sda", SYMLINK+="node", OWNER="daemon" |
9b434de1 | 893 | EOF |
912541b0 KS |
894 | }, |
895 | { | |
896 | desc => "textual group id", | |
255c05b7 MW |
897 | devices => [ |
898 | { | |
899 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", | |
e62acc31 | 900 | exp_links => ["node"], |
255c05b7 MW |
901 | exp_perms => ":daemon:0660", |
902 | }], | |
912541b0 | 903 | rules => <<EOF |
5754e74c | 904 | SUBSYSTEMS=="scsi", KERNEL=="sda", SYMLINK+="node", GROUP="daemon" |
c8278763 | 905 | EOF |
912541b0 KS |
906 | }, |
907 | { | |
908 | desc => "textual user/group id", | |
255c05b7 MW |
909 | devices => [ |
910 | { | |
911 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", | |
e62acc31 | 912 | exp_links => ["node"], |
255c05b7 MW |
913 | exp_perms => "root:audio:0660", |
914 | }], | |
912541b0 | 915 | rules => <<EOF |
a9030b81 | 916 | SUBSYSTEMS=="scsi", KERNEL=="sda", SYMLINK+="node", OWNER="root", GROUP="audio" |
b8669191 | 917 | EOF |
912541b0 KS |
918 | }, |
919 | { | |
920 | desc => "permissions MODE=0777", | |
255c05b7 MW |
921 | devices => [ |
922 | { | |
923 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", | |
e62acc31 | 924 | exp_links => ["node"], |
255c05b7 MW |
925 | exp_perms => "::0777", |
926 | }], | |
912541b0 | 927 | rules => <<EOF |
5754e74c | 928 | SUBSYSTEMS=="scsi", KERNEL=="sda", SYMLINK+="node", MODE="0777" |
b8669191 | 929 | EOF |
912541b0 KS |
930 | }, |
931 | { | |
9158d03e | 932 | desc => "permissions OWNER=1 GROUP=1 MODE=0777", |
255c05b7 MW |
933 | devices => [ |
934 | { | |
935 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", | |
e62acc31 | 936 | exp_links => ["node"], |
255c05b7 MW |
937 | exp_perms => "1:1:0777", |
938 | }], | |
912541b0 | 939 | rules => <<EOF |
9158d03e | 940 | SUBSYSTEMS=="scsi", KERNEL=="sda", SYMLINK+="node", OWNER="1", GROUP="1", MODE="0777" |
b8669191 | 941 | EOF |
912541b0 KS |
942 | }, |
943 | { | |
9158d03e | 944 | desc => "permissions OWNER to 1", |
255c05b7 MW |
945 | devices => [ |
946 | { | |
947 | devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", | |
255c05b7 MW |
948 | exp_perms => "1::", |
949 | }], | |
912541b0 | 950 | rules => <<EOF |
9158d03e | 951 | KERNEL=="ttyACM[0-9]*", SYMLINK+="ttyACM%n", OWNER="1" |
b8669191 | 952 | EOF |
912541b0 KS |
953 | }, |
954 | { | |
9158d03e | 955 | desc => "permissions GROUP to 1", |
255c05b7 MW |
956 | devices => [ |
957 | { | |
958 | devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", | |
255c05b7 MW |
959 | exp_perms => ":1:0660", |
960 | }], | |
912541b0 | 961 | rules => <<EOF |
9158d03e | 962 | KERNEL=="ttyACM[0-9]*", SYMLINK+="ttyACM%n", GROUP="1" |
b8669191 | 963 | EOF |
912541b0 KS |
964 | }, |
965 | { | |
966 | desc => "permissions MODE to 0060", | |
255c05b7 MW |
967 | devices => [ |
968 | { | |
969 | devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", | |
255c05b7 MW |
970 | exp_perms => "::0060", |
971 | }], | |
912541b0 | 972 | rules => <<EOF |
5754e74c | 973 | KERNEL=="ttyACM[0-9]*", SYMLINK+="ttyACM%n", MODE="0060" |
b8669191 | 974 | EOF |
912541b0 KS |
975 | }, |
976 | { | |
977 | desc => "permissions OWNER, GROUP, MODE", | |
255c05b7 MW |
978 | devices => [ |
979 | { | |
980 | devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", | |
255c05b7 MW |
981 | exp_perms => "1:1:0777", |
982 | }], | |
912541b0 | 983 | rules => <<EOF |
9158d03e | 984 | KERNEL=="ttyACM[0-9]*", SYMLINK+="ttyACM%n", OWNER="1", GROUP="1", MODE="0777" |
e9390146 | 985 | EOF |
912541b0 KS |
986 | }, |
987 | { | |
988 | desc => "permissions only rule", | |
255c05b7 MW |
989 | devices => [ |
990 | { | |
991 | devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", | |
255c05b7 MW |
992 | exp_perms => "1:1:0777", |
993 | }], | |
912541b0 | 994 | rules => <<EOF |
9158d03e TG |
995 | KERNEL=="ttyACM[0-9]*", OWNER="1", GROUP="1", MODE="0777" |
996 | KERNEL=="ttyUSX[0-9]*", OWNER="2", GROUP="2", MODE="0444" | |
5754e74c | 997 | KERNEL=="ttyACM[0-9]*", SYMLINK+="ttyACM%n" |
eb870090 | 998 | EOF |
912541b0 KS |
999 | }, |
1000 | { | |
1001 | desc => "multiple permissions only rule", | |
255c05b7 MW |
1002 | devices => [ |
1003 | { | |
1004 | devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", | |
255c05b7 MW |
1005 | exp_perms => "1:1:0777", |
1006 | }], | |
912541b0 | 1007 | rules => <<EOF |
9158d03e TG |
1008 | SUBSYSTEM=="tty", OWNER="1" |
1009 | SUBSYSTEM=="tty", GROUP="1" | |
28ce66de | 1010 | SUBSYSTEM=="tty", MODE="0777" |
9158d03e | 1011 | KERNEL=="ttyUSX[0-9]*", OWNER="2", GROUP="2", MODE="0444" |
5754e74c | 1012 | KERNEL=="ttyACM[0-9]*", SYMLINK+="ttyACM%n" |
eb870090 | 1013 | EOF |
912541b0 KS |
1014 | }, |
1015 | { | |
1016 | desc => "permissions only rule with override at SYMLINK+ rule", | |
255c05b7 MW |
1017 | devices => [ |
1018 | { | |
1019 | devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", | |
255c05b7 MW |
1020 | exp_perms => "1:2:0777", |
1021 | }], | |
912541b0 | 1022 | rules => <<EOF |
9158d03e TG |
1023 | SUBSYSTEM=="tty", OWNER="1" |
1024 | SUBSYSTEM=="tty", GROUP="1" | |
28ce66de | 1025 | SUBSYSTEM=="tty", MODE="0777" |
9158d03e TG |
1026 | KERNEL=="ttyUSX[0-9]*", OWNER="2", GROUP="2", MODE="0444" |
1027 | KERNEL=="ttyACM[0-9]*", SYMLINK+="ttyACM%n", GROUP="2" | |
fa19f181 | 1028 | EOF |
912541b0 KS |
1029 | }, |
1030 | { | |
1031 | desc => "major/minor number test", | |
255c05b7 MW |
1032 | devices => [ |
1033 | { | |
1034 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", | |
e62acc31 | 1035 | exp_links => ["node"], |
255c05b7 MW |
1036 | exp_majorminor => "8:0", |
1037 | }], | |
912541b0 | 1038 | rules => <<EOF |
5754e74c | 1039 | SUBSYSTEMS=="scsi", KERNEL=="sda", SYMLINK+="node" |
7d12d4e1 | 1040 | EOF |
912541b0 KS |
1041 | }, |
1042 | { | |
1043 | desc => "big major number test", | |
255c05b7 MW |
1044 | devices => [ |
1045 | { | |
1046 | devpath => "/devices/virtual/misc/misc-fake1", | |
e62acc31 | 1047 | exp_links => ["node"], |
255c05b7 MW |
1048 | exp_majorminor => "4095:1", |
1049 | }], | |
1050 | rules => <<EOF | |
5754e74c | 1051 | KERNEL=="misc-fake1", SYMLINK+="node" |
7d12d4e1 | 1052 | EOF |
912541b0 KS |
1053 | }, |
1054 | { | |
1055 | desc => "big major and big minor number test", | |
255c05b7 MW |
1056 | devices => [ |
1057 | { | |
1058 | devpath => "/devices/virtual/misc/misc-fake89999", | |
e62acc31 | 1059 | exp_links => ["node"], |
255c05b7 MW |
1060 | exp_majorminor => "4095:89999", |
1061 | }], | |
912541b0 | 1062 | rules => <<EOF |
5754e74c | 1063 | KERNEL=="misc-fake89999", SYMLINK+="node" |
2b0f835c | 1064 | EOF |
912541b0 KS |
1065 | }, |
1066 | { | |
1067 | desc => "multiple symlinks with format char", | |
255c05b7 MW |
1068 | devices => [ |
1069 | { | |
1070 | devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", | |
e62acc31 | 1071 | exp_links => ["symlink1-0", "symlink2-ttyACM0", "symlink3-"], |
255c05b7 | 1072 | }], |
912541b0 | 1073 | rules => <<EOF |
5754e74c | 1074 | KERNEL=="ttyACM[0-9]*", SYMLINK="symlink1-%n symlink2-%k symlink3-%b" |
7b2bdb4b | 1075 | EOF |
912541b0 KS |
1076 | }, |
1077 | { | |
1078 | desc => "multiple symlinks with a lot of s p a c e s", | |
255c05b7 MW |
1079 | devices => [ |
1080 | { | |
1081 | devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", | |
e62acc31 MW |
1082 | exp_links => ["one", "two"], |
1083 | not_exp_links => [" "], | |
255c05b7 | 1084 | }], |
912541b0 | 1085 | rules => <<EOF |
5754e74c | 1086 | KERNEL=="ttyACM[0-9]*", SYMLINK=" one two " |
9cd7b128 DS |
1087 | EOF |
1088 | }, | |
1089 | { | |
1090 | desc => "symlink with spaces in substituted variable", | |
255c05b7 MW |
1091 | devices => [ |
1092 | { | |
1093 | devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", | |
e62acc31 MW |
1094 | exp_links => ["name-one_two_three-end"], |
1095 | not_exp_links => [" "], | |
255c05b7 | 1096 | }], |
9cd7b128 DS |
1097 | rules => <<EOF |
1098 | ENV{WITH_WS}="one two three" | |
1099 | SYMLINK="name-\$env{WITH_WS}-end" | |
1100 | EOF | |
1101 | }, | |
1102 | { | |
1103 | desc => "symlink with leading space in substituted variable", | |
255c05b7 MW |
1104 | devices => [ |
1105 | { | |
1106 | devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", | |
e62acc31 MW |
1107 | exp_links => ["name-one_two_three-end"], |
1108 | not_exp_links => [" "], | |
255c05b7 | 1109 | }], |
9cd7b128 DS |
1110 | rules => <<EOF |
1111 | ENV{WITH_WS}=" one two three" | |
1112 | SYMLINK="name-\$env{WITH_WS}-end" | |
1113 | EOF | |
1114 | }, | |
1115 | { | |
1116 | desc => "symlink with trailing space in substituted variable", | |
255c05b7 MW |
1117 | devices => [ |
1118 | { | |
1119 | devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", | |
e62acc31 MW |
1120 | exp_links => ["name-one_two_three-end"], |
1121 | not_exp_links => [" "], | |
255c05b7 | 1122 | }], |
9cd7b128 DS |
1123 | rules => <<EOF |
1124 | ENV{WITH_WS}="one two three " | |
1125 | SYMLINK="name-\$env{WITH_WS}-end" | |
1126 | EOF | |
1127 | }, | |
1128 | { | |
1129 | desc => "symlink with lots of space in substituted variable", | |
255c05b7 MW |
1130 | devices => [ |
1131 | { | |
1132 | devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", | |
e62acc31 MW |
1133 | exp_links => ["name-one_two_three-end"], |
1134 | not_exp_links => [" "], | |
255c05b7 | 1135 | }], |
9cd7b128 DS |
1136 | rules => <<EOF |
1137 | ENV{WITH_WS}=" one two three " | |
1138 | SYMLINK="name-\$env{WITH_WS}-end" | |
1139 | EOF | |
1140 | }, | |
1141 | { | |
1142 | desc => "symlink with multiple spaces in substituted variable", | |
255c05b7 MW |
1143 | devices => [ |
1144 | { | |
1145 | devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", | |
e62acc31 MW |
1146 | exp_links => ["name-one_two_three-end"], |
1147 | not_exp_links => [" "], | |
255c05b7 | 1148 | }], |
9cd7b128 DS |
1149 | rules => <<EOF |
1150 | ENV{WITH_WS}=" one two three " | |
1151 | SYMLINK="name-\$env{WITH_WS}-end" | |
1152 | EOF | |
1153 | }, | |
1154 | { | |
e62acc31 | 1155 | desc => "symlink with space and var with space", |
255c05b7 MW |
1156 | devices => [ |
1157 | { | |
1158 | devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", | |
2084fe0d MW |
1159 | exp_links => ["first", "name-one_two_three-end", |
1160 | "another_symlink", "a", "b", "c"], | |
1161 | not_exp_links => [" "], | |
255c05b7 | 1162 | }], |
9cd7b128 DS |
1163 | rules => <<EOF |
1164 | ENV{WITH_WS}=" one two three " | |
1165 | SYMLINK=" first name-\$env{WITH_WS}-end another_symlink a b c " | |
33989b96 YW |
1166 | EOF |
1167 | }, | |
1168 | { | |
1169 | desc => "symlink with env which contain slash (see #19309)", | |
1170 | devices => [ | |
1171 | { | |
1172 | devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", | |
1173 | exp_links => ["first", "name-aaa_bbb_ccc-end", | |
1174 | "another_symlink", "a", "b", "c"], | |
1175 | not_exp_links => ["ame-aaa/bbb/ccc-end"], | |
1176 | }], | |
1177 | rules => <<EOF | |
1178 | ENV{WITH_SLASH}="aaa/bbb/ccc" | |
1179 | OPTIONS="string_escape=replace", ENV{REPLACED}="\$env{WITH_SLASH}" | |
1180 | SYMLINK=" first name-\$env{REPLACED}-end another_symlink a b c " | |
b8669191 | 1181 | EOF |
912541b0 KS |
1182 | }, |
1183 | { | |
1184 | desc => "symlink creation (same directory)", | |
255c05b7 MW |
1185 | devices => [ |
1186 | { | |
1187 | devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", | |
e62acc31 | 1188 | exp_links => ["modem0"], |
255c05b7 | 1189 | }], |
912541b0 | 1190 | rules => <<EOF |
5754e74c | 1191 | KERNEL=="ttyACM[0-9]*", SYMLINK+="ttyACM%n", SYMLINK="modem%n" |
b8669191 | 1192 | EOF |
912541b0 KS |
1193 | }, |
1194 | { | |
1195 | desc => "multiple symlinks", | |
255c05b7 MW |
1196 | devices => [ |
1197 | { | |
1198 | devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", | |
e62acc31 | 1199 | exp_links => ["first-0", "second-0", "third-0"], |
255c05b7 | 1200 | }], |
912541b0 | 1201 | rules => <<EOF |
5754e74c | 1202 | KERNEL=="ttyACM0", SYMLINK="first-%n second-%n third-%n" |
b8669191 | 1203 | EOF |
912541b0 KS |
1204 | }, |
1205 | { | |
1206 | desc => "symlink name '.'", | |
255c05b7 MW |
1207 | devices => [ |
1208 | { | |
1209 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", | |
e62acc31 | 1210 | exp_links => ["."], |
255c05b7 MW |
1211 | exp_add_error => "yes", |
1212 | exp_rem_error => "yes", | |
1213 | }], | |
912541b0 | 1214 | rules => <<EOF |
5754e74c | 1215 | SUBSYSTEMS=="scsi", KERNEL=="sda", SYMLINK+="." |
b8669191 | 1216 | EOF |
912541b0 KS |
1217 | }, |
1218 | { | |
1219 | desc => "symlink node to itself", | |
255c05b7 MW |
1220 | devices => [ |
1221 | { | |
1222 | devpath => "/devices/virtual/tty/tty0", | |
e62acc31 | 1223 | exp_links => ["link"], |
255c05b7 MW |
1224 | exp_add_error => "yes", |
1225 | exp_rem_error => "yes", | |
1226 | }], | |
1227 | option => "clean", | |
912541b0 | 1228 | rules => <<EOF |
5754e74c | 1229 | KERNEL=="tty0", SYMLINK+="tty0" |
b8669191 | 1230 | EOF |
912541b0 KS |
1231 | }, |
1232 | { | |
1233 | desc => "symlink %n substitution", | |
255c05b7 MW |
1234 | devices => [ |
1235 | { | |
1236 | devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", | |
e62acc31 | 1237 | exp_links => ["symlink0"], |
255c05b7 | 1238 | }], |
912541b0 | 1239 | rules => <<EOF |
5754e74c | 1240 | KERNEL=="ttyACM[0-9]*", SYMLINK+="ttyACM%n", SYMLINK+="symlink%n" |
b8669191 | 1241 | EOF |
912541b0 KS |
1242 | }, |
1243 | { | |
1244 | desc => "symlink %k substitution", | |
255c05b7 MW |
1245 | devices => [ |
1246 | { | |
1247 | devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", | |
e62acc31 | 1248 | exp_links => ["symlink-ttyACM0"], |
255c05b7 | 1249 | }], |
912541b0 | 1250 | rules => <<EOF |
5754e74c | 1251 | KERNEL=="ttyACM[0-9]*", SYMLINK+="ttyACM%n", SYMLINK+="symlink-%k" |
b8669191 | 1252 | EOF |
912541b0 KS |
1253 | }, |
1254 | { | |
1255 | desc => "symlink %M:%m substitution", | |
255c05b7 MW |
1256 | devices => [ |
1257 | { | |
1258 | devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", | |
e62acc31 | 1259 | exp_links => ["major-166:0"], |
255c05b7 | 1260 | }], |
912541b0 | 1261 | rules => <<EOF |
5754e74c | 1262 | KERNEL=="ttyACM[0-9]*", SYMLINK+="ttyACM%n", SYMLINK+="major-%M:%m" |
b8669191 | 1263 | EOF |
912541b0 KS |
1264 | }, |
1265 | { | |
1266 | desc => "symlink %b substitution", | |
255c05b7 MW |
1267 | devices => [ |
1268 | { | |
1269 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", | |
e62acc31 | 1270 | exp_links => ["symlink-0:0:0:0"], |
255c05b7 | 1271 | }], |
912541b0 | 1272 | rules => <<EOF |
220893b3 | 1273 | SUBSYSTEMS=="scsi", KERNEL=="sda", SYMLINK+="symlink-%b" |
b8669191 | 1274 | EOF |
912541b0 KS |
1275 | }, |
1276 | { | |
1277 | desc => "symlink %c substitution", | |
255c05b7 MW |
1278 | devices => [ |
1279 | { | |
1280 | devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", | |
e62acc31 | 1281 | exp_links => ["test"], |
255c05b7 | 1282 | }], |
912541b0 | 1283 | rules => <<EOF |
d914e445 | 1284 | KERNEL=="ttyACM[0-9]*", PROGRAM=="/bin/echo test", SYMLINK+="%c" |
b8669191 | 1285 | EOF |
912541b0 KS |
1286 | }, |
1287 | { | |
1288 | desc => "symlink %c{N} substitution", | |
255c05b7 MW |
1289 | devices => [ |
1290 | { | |
1291 | devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", | |
e62acc31 MW |
1292 | exp_links => ["test"], |
1293 | not_exp_links => ["symlink", "this"], | |
255c05b7 | 1294 | }], |
912541b0 | 1295 | rules => <<EOF |
d914e445 | 1296 | KERNEL=="ttyACM[0-9]*", PROGRAM=="/bin/echo symlink test this", SYMLINK+="%c{2}" |
b8669191 | 1297 | EOF |
912541b0 KS |
1298 | }, |
1299 | { | |
1300 | desc => "symlink %c{N+} substitution", | |
255c05b7 MW |
1301 | devices => [ |
1302 | { | |
1303 | devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", | |
e62acc31 MW |
1304 | exp_links => ["test", "this"], |
1305 | not_exp_links => ["symlink"], | |
255c05b7 | 1306 | }], |
912541b0 | 1307 | rules => <<EOF |
d914e445 | 1308 | KERNEL=="ttyACM[0-9]*", PROGRAM=="/bin/echo symlink test this", SYMLINK+="%c{2+}" |
b8669191 | 1309 | EOF |
912541b0 KS |
1310 | }, |
1311 | { | |
1312 | desc => "symlink only rule with %c{N+}", | |
255c05b7 MW |
1313 | devices => [ |
1314 | { | |
1315 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", | |
e62acc31 MW |
1316 | exp_links => ["test", "this"], |
1317 | not_exp_links => ["symlink"], | |
255c05b7 | 1318 | }], |
912541b0 | 1319 | rules => <<EOF |
d914e445 | 1320 | SUBSYSTEMS=="scsi", KERNEL=="sda", PROGRAM=="/bin/echo link test this" SYMLINK+="%c{2+}" |
b8669191 | 1321 | EOF |
912541b0 KS |
1322 | }, |
1323 | { | |
1324 | desc => "symlink %s{filename} substitution", | |
255c05b7 MW |
1325 | devices => [ |
1326 | { | |
1327 | devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", | |
e62acc31 | 1328 | exp_links => ["166:0"], |
255c05b7 | 1329 | }], |
912541b0 | 1330 | rules => <<EOF |
5754e74c | 1331 | KERNEL=="ttyACM[0-9]*", SYMLINK+="%s{dev}" |
b8669191 | 1332 | EOF |
912541b0 KS |
1333 | }, |
1334 | { | |
1335 | desc => "program result substitution (numbered part of)", | |
255c05b7 MW |
1336 | devices => [ |
1337 | { | |
1338 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", | |
e62acc31 MW |
1339 | exp_links => ["link1", "link2"], |
1340 | not_exp_links => ["node"], | |
255c05b7 | 1341 | }], |
912541b0 | 1342 | rules => <<EOF |
d914e445 | 1343 | SUBSYSTEMS=="scsi", PROGRAM=="/bin/echo -n node link1 link2", RESULT=="node *", SYMLINK+="%c{2} %c{3}" |
b8669191 | 1344 | EOF |
912541b0 KS |
1345 | }, |
1346 | { | |
1347 | desc => "program result substitution (numbered part of+)", | |
255c05b7 MW |
1348 | devices => [ |
1349 | { | |
1350 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", | |
e62acc31 MW |
1351 | exp_links => ["link1", "link2", "link3", "link4"], |
1352 | not_exp_links => ["node"], | |
255c05b7 | 1353 | }], |
912541b0 | 1354 | rules => <<EOF |
d914e445 | 1355 | SUBSYSTEMS=="scsi", PROGRAM=="/bin/echo -n node link1 link2 link3 link4", RESULT=="node *", SYMLINK+="%c{2+}" |
7efa217d | 1356 | EOF |
912541b0 KS |
1357 | }, |
1358 | { | |
1359 | desc => "SUBSYSTEM match test", | |
255c05b7 MW |
1360 | devices => [ |
1361 | { | |
1362 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", | |
e62acc31 MW |
1363 | exp_links => ["node"], |
1364 | not_exp_links => ["should_not_match", "should_not_match2"], | |
255c05b7 | 1365 | }], |
912541b0 | 1366 | rules => <<EOF |
5754e74c KS |
1367 | SUBSYSTEMS=="scsi", KERNEL=="sda", SYMLINK+="should_not_match", SUBSYSTEM=="vc" |
1368 | SUBSYSTEMS=="scsi", KERNEL=="sda", SYMLINK+="node", SUBSYSTEM=="block" | |
1369 | SUBSYSTEMS=="scsi", KERNEL=="sda", SYMLINK+="should_not_match2", SUBSYSTEM=="vc" | |
2092fbcd | 1370 | EOF |
912541b0 KS |
1371 | }, |
1372 | { | |
1373 | desc => "DRIVERS match test", | |
255c05b7 MW |
1374 | devices => [ |
1375 | { | |
1376 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", | |
e62acc31 MW |
1377 | exp_links => ["node"], |
1378 | not_exp_links => ["should_not_match"] | |
255c05b7 | 1379 | }], |
912541b0 | 1380 | rules => <<EOF |
5754e74c KS |
1381 | SUBSYSTEMS=="scsi", KERNEL=="sda", SYMLINK+="should_not_match", DRIVERS=="sd-wrong" |
1382 | SUBSYSTEMS=="scsi", KERNEL=="sda", SYMLINK+="node", DRIVERS=="sd" | |
c1ab0461 | 1383 | EOF |
912541b0 KS |
1384 | }, |
1385 | { | |
1386 | desc => "devnode substitution test", | |
255c05b7 MW |
1387 | devices => [ |
1388 | { | |
1389 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", | |
e62acc31 | 1390 | exp_links => ["node"], |
255c05b7 | 1391 | }], |
912541b0 | 1392 | rules => <<EOF |
220893b3 | 1393 | SUBSYSTEMS=="scsi", KERNEL=="sda", PROGRAM=="/usr/bin/test -b %N" SYMLINK+="node" |
69aa6dfb | 1394 | EOF |
912541b0 KS |
1395 | }, |
1396 | { | |
1397 | desc => "parent node name substitution test", | |
255c05b7 MW |
1398 | devices => [ |
1399 | { | |
1400 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", | |
e62acc31 | 1401 | exp_links => ["sda-part-1"], |
255c05b7 | 1402 | }], |
912541b0 | 1403 | rules => <<EOF |
06d4d4e2 | 1404 | SUBSYSTEMS=="scsi", KERNEL=="sda1", SYMLINK+="%P-part-%n" |
69aa6dfb | 1405 | EOF |
912541b0 KS |
1406 | }, |
1407 | { | |
1408 | desc => "udev_root substitution", | |
255c05b7 MW |
1409 | devices => [ |
1410 | { | |
1411 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", | |
e62acc31 | 1412 | exp_links => ["start-/dev-end"], |
255c05b7 | 1413 | }], |
912541b0 | 1414 | rules => <<EOF |
5754e74c | 1415 | SUBSYSTEMS=="scsi", KERNEL=="sda1", SYMLINK+="start-%r-end" |
3b6ed8bb | 1416 | EOF |
912541b0 KS |
1417 | }, |
1418 | { | |
17cce031 | 1419 | # This is not supported any more |
912541b0 | 1420 | desc => "last_rule option", |
255c05b7 MW |
1421 | devices => [ |
1422 | { | |
1423 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", | |
e62acc31 | 1424 | exp_links => ["last"], |
17cce031 MW |
1425 | not_exp_links => ["very-last"], |
1426 | exp_nodev_error => "yes", | |
255c05b7 | 1427 | }], |
912541b0 | 1428 | rules => <<EOF |
c4edd0ad | 1429 | SUBSYSTEMS=="scsi", KERNEL=="sda1", SYMLINK+="last", OPTIONS="last_rule" |
5754e74c | 1430 | SUBSYSTEMS=="scsi", KERNEL=="sda1", SYMLINK+="very-last" |
28ce66de | 1431 | EOF |
912541b0 KS |
1432 | }, |
1433 | { | |
1434 | desc => "negation KERNEL!=", | |
255c05b7 MW |
1435 | devices => [ |
1436 | { | |
1437 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", | |
e62acc31 MW |
1438 | exp_links => ["match", "before"], |
1439 | not_exp_links => ["matches-but-is-negated"], | |
255c05b7 | 1440 | }], |
912541b0 | 1441 | rules => <<EOF |
5754e74c KS |
1442 | SUBSYSTEMS=="scsi", KERNEL!="sda1", SYMLINK+="matches-but-is-negated" |
1443 | SUBSYSTEMS=="scsi", KERNEL=="sda1", SYMLINK+="before" | |
1444 | SUBSYSTEMS=="scsi", KERNEL!="xsda1", SYMLINK+="match" | |
28ce66de | 1445 | EOF |
912541b0 KS |
1446 | }, |
1447 | { | |
1448 | desc => "negation SUBSYSTEM!=", | |
255c05b7 MW |
1449 | devices => [ |
1450 | { | |
1451 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", | |
e62acc31 MW |
1452 | exp_links => ["before", "not-anything"], |
1453 | not_exp_links => ["matches-but-is-negated"], | |
255c05b7 | 1454 | }], |
912541b0 | 1455 | rules => <<EOF |
5754e74c KS |
1456 | SUBSYSTEMS=="scsi", SUBSYSTEM=="block", KERNEL!="sda1", SYMLINK+="matches-but-is-negated" |
1457 | SUBSYSTEMS=="scsi", KERNEL=="sda1", SYMLINK+="before" | |
1458 | SUBSYSTEMS=="scsi", SUBSYSTEM!="anything", SYMLINK+="not-anything" | |
28ce66de | 1459 | EOF |
912541b0 KS |
1460 | }, |
1461 | { | |
1462 | desc => "negation PROGRAM!= exit code", | |
255c05b7 MW |
1463 | devices => [ |
1464 | { | |
1465 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", | |
e62acc31 | 1466 | exp_links => ["before", "nonzero-program"], |
255c05b7 | 1467 | }], |
912541b0 | 1468 | rules => <<EOF |
5754e74c | 1469 | SUBSYSTEMS=="scsi", KERNEL=="sda1", SYMLINK+="before" |
d914e445 | 1470 | KERNEL=="sda1", PROGRAM!="/bin/false", SYMLINK+="nonzero-program" |
3e5958de | 1471 | EOF |
912541b0 KS |
1472 | }, |
1473 | { | |
1474 | desc => "ENV{} test", | |
255c05b7 MW |
1475 | devices => [ |
1476 | { | |
1477 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", | |
e62acc31 MW |
1478 | exp_links => ["true"], |
1479 | not_exp_links => ["bad", "wrong"], | |
255c05b7 | 1480 | }], |
912541b0 | 1481 | rules => <<EOF |
a1af6b04 | 1482 | ENV{ENV_KEY_TEST}="test" |
5754e74c KS |
1483 | SUBSYSTEMS=="scsi", KERNEL=="sda1", ENV{ENV_KEY_TEST}=="go", SYMLINK+="wrong" |
1484 | SUBSYSTEMS=="scsi", KERNEL=="sda1", ENV{ENV_KEY_TEST}=="test", SYMLINK+="true" | |
1485 | SUBSYSTEMS=="scsi", KERNEL=="sda1", ENV{ENV_KEY_TEST}=="bad", SYMLINK+="bad" | |
3e5958de | 1486 | EOF |
912541b0 KS |
1487 | }, |
1488 | { | |
1489 | desc => "ENV{} test", | |
255c05b7 MW |
1490 | devices => [ |
1491 | { | |
1492 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", | |
e62acc31 MW |
1493 | exp_links => ["true"], |
1494 | not_exp_links => ["bad", "wrong", "no"], | |
255c05b7 | 1495 | }], |
912541b0 | 1496 | rules => <<EOF |
a1af6b04 | 1497 | ENV{ENV_KEY_TEST}="test" |
5754e74c KS |
1498 | SUBSYSTEMS=="scsi", KERNEL=="sda1", ENV{ENV_KEY_TEST}=="go", SYMLINK+="wrong" |
1499 | SUBSYSTEMS=="scsi", KERNEL=="sda1", ENV{ENV_KEY_TEST}=="yes", ENV{ACTION}=="add", ENV{DEVPATH}=="*/block/sda/sdax1", SYMLINK+="no" | |
1500 | SUBSYSTEMS=="scsi", KERNEL=="sda1", ENV{ENV_KEY_TEST}=="test", ENV{ACTION}=="add", ENV{DEVPATH}=="*/block/sda/sda1", SYMLINK+="true" | |
1501 | SUBSYSTEMS=="scsi", KERNEL=="sda1", ENV{ENV_KEY_TEST}=="bad", SYMLINK+="bad" | |
5618b561 | 1502 | EOF |
912541b0 KS |
1503 | }, |
1504 | { | |
1505 | desc => "ENV{} test (assign)", | |
255c05b7 MW |
1506 | devices => [ |
1507 | { | |
1508 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", | |
e62acc31 MW |
1509 | exp_links => ["true", "before"], |
1510 | not_exp_links => ["no"], | |
255c05b7 | 1511 | }], |
912541b0 | 1512 | rules => <<EOF |
c4edd0ad | 1513 | SUBSYSTEMS=="scsi", KERNEL=="sda1", ENV{ASSIGN}="true" |
5754e74c KS |
1514 | SUBSYSTEMS=="scsi", KERNEL=="sda1", ENV{ASSIGN}=="yes", SYMLINK+="no" |
1515 | SUBSYSTEMS=="scsi", KERNEL=="sda1", SYMLINK+="before" | |
1516 | SUBSYSTEMS=="scsi", KERNEL=="sda1", ENV{ASSIGN}=="true", SYMLINK+="true" | |
ac528431 | 1517 | EOF |
912541b0 KS |
1518 | }, |
1519 | { | |
1520 | desc => "ENV{} test (assign 2 times)", | |
255c05b7 MW |
1521 | devices => [ |
1522 | { | |
1523 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", | |
e62acc31 MW |
1524 | exp_links => ["true", "before"], |
1525 | not_exp_links => ["no", "bad"], | |
255c05b7 | 1526 | }], |
912541b0 | 1527 | rules => <<EOF |
ac528431 KS |
1528 | SUBSYSTEMS=="scsi", KERNEL=="sda1", ENV{ASSIGN}="true" |
1529 | SUBSYSTEMS=="scsi", KERNEL=="sda1", ENV{ASSIGN}="absolutely-\$env{ASSIGN}" | |
5754e74c KS |
1530 | SUBSYSTEMS=="scsi", KERNEL=="sda1", SYMLINK+="before" |
1531 | SUBSYSTEMS=="scsi", KERNEL=="sda1", ENV{ASSIGN}=="yes", SYMLINK+="no" | |
06d4d4e2 | 1532 | SUBSYSTEMS=="scsi", KERNEL=="sda1", ENV{ASSIGN}=="true", SYMLINK+="bad" |
5754e74c | 1533 | SUBSYSTEMS=="scsi", KERNEL=="sda1", ENV{ASSIGN}=="absolutely-true", SYMLINK+="true" |
5618b561 | 1534 | EOF |
912541b0 KS |
1535 | }, |
1536 | { | |
1537 | desc => "ENV{} test (assign2)", | |
255c05b7 MW |
1538 | devices => [ |
1539 | { | |
1540 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", | |
e62acc31 MW |
1541 | exp_links => ["part"], |
1542 | not_exp_links => ["disk"], | |
1543 | }, | |
06d4d4e2 MW |
1544 | { |
1545 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", | |
1546 | exp_links => ["disk"], | |
1547 | not_exp_links => ["part"], | |
1548 | }, | |
e62acc31 | 1549 | ], |
912541b0 | 1550 | rules => <<EOF |
d59c84ef KS |
1551 | SUBSYSTEM=="block", KERNEL=="*[0-9]", ENV{PARTITION}="true", ENV{MAINDEVICE}="false" |
1552 | SUBSYSTEM=="block", KERNEL=="*[!0-9]", ENV{PARTITION}="false", ENV{MAINDEVICE}="true" | |
5754e74c KS |
1553 | ENV{MAINDEVICE}=="true", SYMLINK+="disk" |
1554 | SUBSYSTEM=="block", SYMLINK+="before" | |
1555 | ENV{PARTITION}=="true", SYMLINK+="part" | |
18614ab2 | 1556 | EOF |
912541b0 KS |
1557 | }, |
1558 | { | |
1559 | desc => "untrusted string sanitize", | |
255c05b7 MW |
1560 | devices => [ |
1561 | { | |
1562 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", | |
e62acc31 | 1563 | exp_links => ["sane"], |
255c05b7 | 1564 | }], |
912541b0 | 1565 | rules => <<EOF |
d914e445 | 1566 | SUBSYSTEMS=="scsi", KERNEL=="sda1", PROGRAM=="/bin/echo -e name; (/usr/bin/badprogram)", RESULT=="name_ _/usr/bin/badprogram_", SYMLINK+="sane" |
764ce7f2 | 1567 | EOF |
912541b0 KS |
1568 | }, |
1569 | { | |
1570 | desc => "untrusted string sanitize (don't replace utf8)", | |
255c05b7 MW |
1571 | devices => [ |
1572 | { | |
1573 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", | |
e62acc31 | 1574 | exp_links => ["uber"], |
255c05b7 | 1575 | }], |
912541b0 | 1576 | rules => <<EOF |
d914e445 | 1577 | SUBSYSTEMS=="scsi", KERNEL=="sda1", PROGRAM=="/bin/echo -e \\xc3\\xbcber" RESULT=="\xc3\xbcber", SYMLINK+="uber" |
764ce7f2 | 1578 | EOF |
912541b0 KS |
1579 | }, |
1580 | { | |
1581 | desc => "untrusted string sanitize (replace invalid utf8)", | |
255c05b7 MW |
1582 | devices => [ |
1583 | { | |
1584 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", | |
e62acc31 | 1585 | exp_links => ["replaced"], |
255c05b7 | 1586 | }], |
912541b0 | 1587 | rules => <<EOF |
d914e445 | 1588 | SUBSYSTEMS=="scsi", KERNEL=="sda1", PROGRAM=="/bin/echo -e \\xef\\xe8garbage", RESULT=="__garbage", SYMLINK+="replaced" |
98bbc835 | 1589 | EOF |
912541b0 KS |
1590 | }, |
1591 | { | |
1592 | desc => "read sysfs value from parent device", | |
255c05b7 MW |
1593 | devices => [ |
1594 | { | |
1595 | devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", | |
e62acc31 | 1596 | exp_links => ["serial-354172020305000"], |
255c05b7 | 1597 | }], |
912541b0 | 1598 | rules => <<EOF |
5754e74c | 1599 | KERNEL=="ttyACM*", ATTRS{serial}=="?*", SYMLINK+="serial-%s{serial}" |
db949b02 | 1600 | EOF |
912541b0 KS |
1601 | }, |
1602 | { | |
1603 | desc => "match against empty key string", | |
255c05b7 MW |
1604 | devices => [ |
1605 | { | |
1606 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", | |
e62acc31 MW |
1607 | exp_links => ["ok"], |
1608 | not_exp_links => ["not-1-ok", "not-2-ok", "not-3-ok"], | |
255c05b7 | 1609 | }], |
912541b0 | 1610 | rules => <<EOF |
5754e74c KS |
1611 | KERNEL=="sda", ATTRS{nothing}!="", SYMLINK+="not-1-ok" |
1612 | KERNEL=="sda", ATTRS{nothing}=="", SYMLINK+="not-2-ok" | |
1613 | KERNEL=="sda", ATTRS{vendor}!="", SYMLINK+="ok" | |
1614 | KERNEL=="sda", ATTRS{vendor}=="", SYMLINK+="not-3-ok" | |
821d0ec8 | 1615 | EOF |
912541b0 KS |
1616 | }, |
1617 | { | |
1618 | desc => "check ACTION value", | |
255c05b7 MW |
1619 | devices => [ |
1620 | { | |
1621 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", | |
e62acc31 MW |
1622 | exp_links => ["ok"], |
1623 | not_exp_links => ["unknown-not-ok"], | |
255c05b7 | 1624 | }], |
912541b0 | 1625 | rules => <<EOF |
5754e74c KS |
1626 | ACTION=="unknown", KERNEL=="sda", SYMLINK+="unknown-not-ok" |
1627 | ACTION=="add", KERNEL=="sda", SYMLINK+="ok" | |
c974742b | 1628 | EOF |
912541b0 KS |
1629 | }, |
1630 | { | |
1631 | desc => "final assignment", | |
255c05b7 MW |
1632 | devices => [ |
1633 | { | |
1634 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", | |
e62acc31 | 1635 | exp_links => ["ok"], |
255c05b7 MW |
1636 | exp_perms => "root:tty:0640", |
1637 | }], | |
912541b0 | 1638 | rules => <<EOF |
d960ad15 | 1639 | KERNEL=="sda", GROUP:="tty" |
06d4d4e2 | 1640 | KERNEL=="sda", GROUP="root", MODE="0640", SYMLINK+="ok" |
c974742b | 1641 | EOF |
912541b0 KS |
1642 | }, |
1643 | { | |
1644 | desc => "final assignment 2", | |
255c05b7 MW |
1645 | devices => [ |
1646 | { | |
1647 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", | |
e62acc31 | 1648 | exp_links => ["ok"], |
255c05b7 MW |
1649 | exp_perms => "root:tty:0640", |
1650 | }], | |
912541b0 | 1651 | rules => <<EOF |
d960ad15 | 1652 | KERNEL=="sda", GROUP:="tty" |
c974742b | 1653 | SUBSYSTEM=="block", MODE:="640" |
06d4d4e2 | 1654 | KERNEL=="sda", GROUP="root", MODE="0666", SYMLINK+="ok" |
bd0ed2ff | 1655 | EOF |
912541b0 KS |
1656 | }, |
1657 | { | |
1658 | desc => "env substitution", | |
255c05b7 MW |
1659 | devices => [ |
1660 | { | |
1661 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", | |
e62acc31 | 1662 | exp_links => ["node-add-me"], |
255c05b7 | 1663 | }], |
912541b0 | 1664 | rules => <<EOF |
5754e74c | 1665 | KERNEL=="sda", MODE="0666", SYMLINK+="node-\$env{ACTION}-me" |
995aec87 | 1666 | EOF |
912541b0 KS |
1667 | }, |
1668 | { | |
1669 | desc => "reset list to current value", | |
255c05b7 MW |
1670 | devices => [ |
1671 | { | |
1672 | devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", | |
e62acc31 MW |
1673 | exp_links => ["three"], |
1674 | not_exp_links => ["two", "one"], | |
255c05b7 | 1675 | }], |
912541b0 | 1676 | rules => <<EOF |
c7fcba1b KS |
1677 | KERNEL=="ttyACM[0-9]*", SYMLINK+="one" |
1678 | KERNEL=="ttyACM[0-9]*", SYMLINK+="two" | |
1679 | KERNEL=="ttyACM[0-9]*", SYMLINK="three" | |
647f7c49 | 1680 | EOF |
912541b0 KS |
1681 | }, |
1682 | { | |
1683 | desc => "test empty SYMLINK+ (empty override)", | |
255c05b7 MW |
1684 | devices => [ |
1685 | { | |
1686 | devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", | |
e62acc31 MW |
1687 | exp_links => ["right"], |
1688 | not_exp_links => ["wrong"], | |
255c05b7 | 1689 | }], |
912541b0 | 1690 | rules => <<EOF |
5754e74c KS |
1691 | KERNEL=="ttyACM[0-9]*", SYMLINK+="wrong" |
1692 | KERNEL=="ttyACM[0-9]*", SYMLINK="" | |
1693 | KERNEL=="ttyACM[0-9]*", SYMLINK+="right" | |
0cd4ac47 | 1694 | EOF |
912541b0 KS |
1695 | }, |
1696 | { | |
1697 | desc => "test multi matches", | |
255c05b7 MW |
1698 | devices => [ |
1699 | { | |
1700 | devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", | |
e62acc31 | 1701 | exp_links => ["right", "before"], |
255c05b7 | 1702 | }], |
912541b0 | 1703 | rules => <<EOF |
5754e74c KS |
1704 | KERNEL=="ttyACM*", SYMLINK+="before" |
1705 | KERNEL=="ttyACM*|nothing", SYMLINK+="right" | |
0cd4ac47 | 1706 | EOF |
912541b0 KS |
1707 | }, |
1708 | { | |
1709 | desc => "test multi matches 2", | |
255c05b7 MW |
1710 | devices => [ |
1711 | { | |
1712 | devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", | |
e62acc31 MW |
1713 | exp_links => ["right", "before"], |
1714 | not_exp_links => ["nomatch"], | |
255c05b7 | 1715 | }], |
912541b0 | 1716 | rules => <<EOF |
5754e74c KS |
1717 | KERNEL=="dontknow*|*nothing", SYMLINK+="nomatch" |
1718 | KERNEL=="ttyACM*", SYMLINK+="before" | |
1719 | KERNEL=="dontknow*|ttyACM*|nothing*", SYMLINK+="right" | |
91a75e4a | 1720 | EOF |
912541b0 KS |
1721 | }, |
1722 | { | |
1723 | desc => "test multi matches 3", | |
255c05b7 MW |
1724 | devices => [ |
1725 | { | |
1726 | devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", | |
e62acc31 MW |
1727 | exp_links => ["right"], |
1728 | not_exp_links => ["nomatch", "wrong1", "wrong2"], | |
255c05b7 | 1729 | }], |
912541b0 | 1730 | rules => <<EOF |
5754e74c KS |
1731 | KERNEL=="dontknow|nothing", SYMLINK+="nomatch" |
1732 | KERNEL=="dontknow|ttyACM0a|nothing|attyACM0", SYMLINK+="wrong1" | |
1733 | KERNEL=="X|attyACM0|dontknow|ttyACM0a|nothing|attyACM0", SYMLINK+="wrong2" | |
1734 | KERNEL=="dontknow|ttyACM0|nothing", SYMLINK+="right" | |
91a75e4a | 1735 | EOF |
912541b0 KS |
1736 | }, |
1737 | { | |
1738 | desc => "test multi matches 4", | |
255c05b7 MW |
1739 | devices => [ |
1740 | { | |
1741 | devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", | |
e62acc31 MW |
1742 | exp_links => ["right"], |
1743 | not_exp_links => ["nomatch", "wrong1", "wrong2", "wrong3"], | |
255c05b7 | 1744 | }], |
912541b0 | 1745 | rules => <<EOF |
5754e74c KS |
1746 | KERNEL=="dontknow|nothing", SYMLINK+="nomatch" |
1747 | KERNEL=="dontknow|ttyACM0a|nothing|attyACM0", SYMLINK+="wrong1" | |
1748 | KERNEL=="X|attyACM0|dontknow|ttyACM0a|nothing|attyACM0", SYMLINK+="wrong2" | |
1749 | KERNEL=="all|dontknow|ttyACM0", SYMLINK+="right" | |
1750 | KERNEL=="ttyACM0a|nothing", SYMLINK+="wrong3" | |
48d26c90 YW |
1751 | EOF |
1752 | }, | |
1753 | { | |
255c05b7 MW |
1754 | desc => "test multi matches 5", |
1755 | devices => [ | |
1756 | { | |
1757 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", | |
e62acc31 | 1758 | exp_links => ["found"], |
255c05b7 MW |
1759 | not_exp_name => "bad", |
1760 | }], | |
48d26c90 YW |
1761 | rules => <<EOF |
1762 | KERNEL=="sda", TAG="foo" | |
1763 | TAGS=="|foo", SYMLINK+="found" | |
1764 | TAGS=="|aaa", SYMLINK+="bad" | |
1765 | EOF | |
1766 | }, | |
1767 | { | |
1768 | desc => "test multi matches 6", | |
255c05b7 MW |
1769 | devices => [ |
1770 | { | |
1771 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", | |
e62acc31 | 1772 | exp_links => ["found"], |
255c05b7 MW |
1773 | not_exp_name => "bad", |
1774 | }], | |
48d26c90 YW |
1775 | rules => <<EOF |
1776 | KERNEL=="sda", TAG="" | |
1777 | TAGS=="|foo", SYMLINK+="found" | |
1778 | TAGS=="aaa|bbb", SYMLINK+="bad" | |
1779 | EOF | |
1780 | }, | |
1781 | { | |
1782 | desc => "test multi matches 7", | |
255c05b7 MW |
1783 | devices => [ |
1784 | { | |
1785 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", | |
e62acc31 | 1786 | exp_links => ["found"], |
255c05b7 MW |
1787 | not_exp_name => "bad", |
1788 | }], | |
48d26c90 YW |
1789 | rules => <<EOF |
1790 | KERNEL=="sda", TAG="foo" | |
1791 | TAGS=="foo||bar", SYMLINK+="found" | |
1792 | TAGS=="aaa||bbb", SYMLINK+="bad" | |
1793 | EOF | |
1794 | }, | |
1795 | { | |
1796 | desc => "test multi matches 8", | |
255c05b7 MW |
1797 | devices => [ |
1798 | { | |
1799 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", | |
e62acc31 | 1800 | exp_links => ["found"], |
255c05b7 MW |
1801 | not_exp_name => "bad", |
1802 | }], | |
48d26c90 YW |
1803 | rules => <<EOF |
1804 | KERNEL=="sda", TAG="" | |
1805 | TAGS=="foo||bar", SYMLINK+="found" | |
1806 | TAGS=="aaa|bbb", SYMLINK+="bad" | |
1807 | EOF | |
1808 | }, | |
1809 | { | |
1810 | desc => "test multi matches 9", | |
255c05b7 MW |
1811 | devices => [ |
1812 | { | |
1813 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", | |
e62acc31 | 1814 | exp_links => ["found"], |
255c05b7 MW |
1815 | not_exp_name => "bad", |
1816 | }], | |
48d26c90 YW |
1817 | rules => <<EOF |
1818 | KERNEL=="sda", TAG="foo" | |
1819 | TAGS=="foo|", SYMLINK+="found" | |
1820 | TAGS=="aaa|", SYMLINK+="bad" | |
1821 | EOF | |
1822 | }, | |
1823 | { | |
1824 | desc => "test multi matches 10", | |
255c05b7 MW |
1825 | devices => [ |
1826 | { | |
1827 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", | |
e62acc31 | 1828 | exp_links => ["found"], |
255c05b7 MW |
1829 | not_exp_name => "bad", |
1830 | }], | |
48d26c90 YW |
1831 | rules => <<EOF |
1832 | KERNEL=="sda", TAG="" | |
1833 | TAGS=="foo|", SYMLINK+="found" | |
1834 | TAGS=="aaa|bbb", SYMLINK+="bad" | |
0d3a8bc7 YG |
1835 | EOF |
1836 | }, | |
1837 | { | |
1838 | desc => "test multi matches 11", | |
255c05b7 MW |
1839 | devices => [ |
1840 | { | |
1841 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", | |
e62acc31 | 1842 | exp_links => ["found"], |
255c05b7 MW |
1843 | not_exp_name => "bad", |
1844 | }], | |
0d3a8bc7 YG |
1845 | rules => <<EOF |
1846 | KERNEL=="sda", TAG="c" | |
1847 | TAGS=="foo||bar||c", SYMLINK+="found" | |
1848 | TAGS=="aaa||bbb||ccc", SYMLINK+="bad" | |
0bfb84e1 | 1849 | EOF |
912541b0 KS |
1850 | }, |
1851 | { | |
a96cd21d | 1852 | desc => "IMPORT parent test", |
255c05b7 MW |
1853 | devices => [ |
1854 | { | |
1855 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", | |
e62acc31 | 1856 | exp_links => ["parent"], |
a96cd21d | 1857 | }, |
255c05b7 MW |
1858 | { |
1859 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", | |
e62acc31 | 1860 | exp_links => ["parentenv-parent_right"], |
255c05b7 | 1861 | }], |
a96cd21d | 1862 | sleep_us => 500000, # Serialized! We need to sleep here after adding sda |
912541b0 | 1863 | rules => <<EOF |
5754e74c | 1864 | KERNEL=="sda1", IMPORT{parent}="PARENT*", SYMLINK+="parentenv-\$env{PARENT_KEY}\$env{WRONG_PARENT_KEY}" |
a96cd21d MW |
1865 | KERNEL=="sda", IMPORT{program}="/bin/echo -e \'PARENT_KEY=parent_right\\nWRONG_PARENT_KEY=parent_wrong'" |
1866 | KERNEL=="sda", SYMLINK+="parent" | |
594dd610 | 1867 | EOF |
912541b0 KS |
1868 | }, |
1869 | { | |
1870 | desc => "GOTO test", | |
255c05b7 MW |
1871 | devices => [ |
1872 | { | |
1873 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", | |
e62acc31 MW |
1874 | exp_links => ["right"], |
1875 | not_exp_test => ["wrong", "wrong2"], | |
255c05b7 | 1876 | }], |
912541b0 | 1877 | rules => <<EOF |
594dd610 | 1878 | KERNEL=="sda1", GOTO="TEST" |
5754e74c | 1879 | KERNEL=="sda1", SYMLINK+="wrong" |
6880b25d | 1880 | KERNEL=="sda1", GOTO="BAD" |
5754e74c KS |
1881 | KERNEL=="sda1", SYMLINK+="", LABEL="NO" |
1882 | KERNEL=="sda1", SYMLINK+="right", LABEL="TEST", GOTO="end" | |
1883 | KERNEL=="sda1", SYMLINK+="wrong2", LABEL="BAD" | |
9dae0e89 | 1884 | LABEL="end" |
0c377989 | 1885 | EOF |
912541b0 KS |
1886 | }, |
1887 | { | |
1888 | desc => "GOTO label does not exist", | |
255c05b7 MW |
1889 | devices => [ |
1890 | { | |
1891 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", | |
e62acc31 | 1892 | exp_links => ["right"], |
255c05b7 | 1893 | }], |
912541b0 | 1894 | rules => <<EOF |
0c377989 | 1895 | KERNEL=="sda1", GOTO="does-not-exist" |
5754e74c | 1896 | KERNEL=="sda1", SYMLINK+="right", |
0c377989 | 1897 | LABEL="exists" |
d59c84ef | 1898 | EOF |
912541b0 KS |
1899 | }, |
1900 | { | |
1901 | desc => "SYMLINK+ compare test", | |
255c05b7 MW |
1902 | devices => [ |
1903 | { | |
1904 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", | |
e62acc31 MW |
1905 | exp_links => ["right", "link"], |
1906 | not_exp_links => ["wrong"], | |
255c05b7 | 1907 | }], |
912541b0 | 1908 | rules => <<EOF |
5754e74c KS |
1909 | KERNEL=="sda1", SYMLINK+="link" |
1910 | KERNEL=="sda1", SYMLINK=="link*", SYMLINK+="right" | |
1911 | KERNEL=="sda1", SYMLINK=="nolink*", SYMLINK+="wrong" | |
d59c84ef | 1912 | EOF |
912541b0 KS |
1913 | }, |
1914 | { | |
1915 | desc => "invalid key operation", | |
255c05b7 MW |
1916 | devices => [ |
1917 | { | |
1918 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", | |
e62acc31 MW |
1919 | exp_links => ["yes"], |
1920 | not_exp_links => ["no"], | |
255c05b7 | 1921 | }], |
912541b0 | 1922 | rules => <<EOF |
5754e74c KS |
1923 | KERNEL="sda1", SYMLINK+="no" |
1924 | KERNEL=="sda1", SYMLINK+="yes" | |
864b9b5e | 1925 | EOF |
912541b0 KS |
1926 | }, |
1927 | { | |
1928 | desc => "operator chars in attribute", | |
255c05b7 MW |
1929 | devices => [ |
1930 | { | |
1931 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", | |
e62acc31 | 1932 | exp_links => ["yes"], |
255c05b7 | 1933 | }], |
912541b0 | 1934 | rules => <<EOF |
5754e74c | 1935 | KERNEL=="sda", ATTR{test:colon+plus}=="?*", SYMLINK+="yes" |
d4ae9925 | 1936 | EOF |
912541b0 KS |
1937 | }, |
1938 | { | |
1939 | desc => "overlong comment line", | |
255c05b7 MW |
1940 | devices => [ |
1941 | { | |
1942 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", | |
e62acc31 MW |
1943 | exp_links => ["yes"], |
1944 | not_exp_links => ["no"], | |
255c05b7 | 1945 | }], |
912541b0 | 1946 | rules => <<EOF |
d4ae9925 | 1947 | # 012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 |
d960ad15 | 1948 | # 012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 |
5754e74c KS |
1949 | KERNEL=="sda1", SYMLINK+=="no" |
1950 | KERNEL=="sda1", SYMLINK+="yes" | |
4ad47b2d | 1951 | EOF |
912541b0 KS |
1952 | }, |
1953 | { | |
1954 | desc => "magic subsys/kernel lookup", | |
255c05b7 MW |
1955 | devices => [ |
1956 | { | |
1957 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", | |
e62acc31 | 1958 | exp_links => ["00:16:41:e2:8d:ff"], |
255c05b7 | 1959 | }], |
912541b0 | 1960 | rules => <<EOF |
5754e74c | 1961 | KERNEL=="sda", SYMLINK+="\$attr{[net/eth0]address}" |
03f65fe6 | 1962 | EOF |
912541b0 KS |
1963 | }, |
1964 | { | |
1965 | desc => "TEST absolute path", | |
255c05b7 MW |
1966 | devices => [ |
1967 | { | |
1968 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", | |
e62acc31 MW |
1969 | exp_links => ["there"], |
1970 | not_exp_links => ["notthere"], | |
255c05b7 | 1971 | }], |
912541b0 | 1972 | rules => <<EOF |
02cd084d TG |
1973 | TEST=="/etc/machine-id", SYMLINK+="there" |
1974 | TEST!="/etc/machine-id", SYMLINK+="notthere" | |
03f65fe6 | 1975 | EOF |
912541b0 KS |
1976 | }, |
1977 | { | |
1978 | desc => "TEST subsys/kernel lookup", | |
255c05b7 MW |
1979 | devices => [ |
1980 | { | |
1981 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", | |
e62acc31 | 1982 | exp_links => ["yes"], |
255c05b7 | 1983 | }], |
912541b0 | 1984 | rules => <<EOF |
5754e74c | 1985 | KERNEL=="sda", TEST=="[net/eth0]", SYMLINK+="yes" |
03f65fe6 | 1986 | EOF |
912541b0 KS |
1987 | }, |
1988 | { | |
1989 | desc => "TEST relative path", | |
255c05b7 MW |
1990 | devices => [ |
1991 | { | |
1992 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", | |
e62acc31 | 1993 | exp_links => ["relative"], |
255c05b7 | 1994 | }], |
912541b0 | 1995 | rules => <<EOF |
5754e74c | 1996 | KERNEL=="sda", TEST=="size", SYMLINK+="relative" |
0ea5e96e | 1997 | EOF |
912541b0 KS |
1998 | }, |
1999 | { | |
2000 | desc => "TEST wildcard substitution (find queue/nr_requests)", | |
255c05b7 MW |
2001 | devices => [ |
2002 | { | |
2003 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", | |
e62acc31 | 2004 | exp_links => ["found-subdir"], |
255c05b7 | 2005 | }], |
912541b0 | 2006 | rules => <<EOF |
5754e74c | 2007 | KERNEL=="sda", TEST=="*/nr_requests", SYMLINK+="found-subdir" |
cf100ca7 | 2008 | EOF |
912541b0 KS |
2009 | }, |
2010 | { | |
2011 | desc => "TEST MODE=0000", | |
255c05b7 MW |
2012 | devices => [ |
2013 | { | |
2014 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", | |
255c05b7 MW |
2015 | exp_perms => "0:0:0000", |
2016 | exp_rem_error => "yes", | |
2017 | }], | |
912541b0 | 2018 | rules => <<EOF |
cf100ca7 | 2019 | KERNEL=="sda", MODE="0000" |
a367f04e | 2020 | EOF |
912541b0 KS |
2021 | }, |
2022 | { | |
2023 | desc => "TEST PROGRAM feeds OWNER, GROUP, MODE", | |
255c05b7 MW |
2024 | devices => [ |
2025 | { | |
2026 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", | |
255c05b7 | 2027 | exp_perms => "1:1:0400", |
255c05b7 | 2028 | }], |
912541b0 | 2029 | rules => <<EOF |
6880b25d | 2030 | KERNEL=="sda", MODE="666" |
9158d03e | 2031 | KERNEL=="sda", PROGRAM=="/bin/echo 1 1 0400", OWNER="%c{1}", GROUP="%c{2}", MODE="%c{3}" |
ff94cec3 | 2032 | EOF |
912541b0 KS |
2033 | }, |
2034 | { | |
2035 | desc => "TEST PROGRAM feeds MODE with overflow", | |
255c05b7 MW |
2036 | devices => [ |
2037 | { | |
2038 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", | |
255c05b7 MW |
2039 | exp_perms => "0:0:0440", |
2040 | exp_rem_error => "yes", | |
2041 | }], | |
912541b0 | 2042 | rules => <<EOF |
6880b25d | 2043 | KERNEL=="sda", MODE="440" |
d914e445 | 2044 | KERNEL=="sda", PROGRAM=="/bin/echo 0 0 0400letsdoabuffferoverflow0123456789012345789012345678901234567890", OWNER="%c{1}", GROUP="%c{2}", MODE="%c{3}" |
dc4c7e46 | 2045 | EOF |
912541b0 KS |
2046 | }, |
2047 | { | |
2048 | desc => "magic [subsys/sysname] attribute substitution", | |
255c05b7 MW |
2049 | devices => [ |
2050 | { | |
2051 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", | |
e62acc31 | 2052 | exp_links => ["sda-8741C4G-end"], |
255c05b7 MW |
2053 | exp_perms => "0:0:0600", |
2054 | }], | |
912541b0 | 2055 | rules => <<EOF |
0f52fdee | 2056 | KERNEL=="sda", SYMLINK+="%k-%s{[dmi/id]product_name}-end" |
d7867b31 | 2057 | EOF |
912541b0 KS |
2058 | }, |
2059 | { | |
2060 | desc => "builtin path_id", | |
255c05b7 MW |
2061 | devices => [ |
2062 | { | |
2063 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", | |
e62acc31 | 2064 | exp_links => ["disk/by-path/pci-0000:00:1f.2-scsi-0:0:0:0"], |
255c05b7 | 2065 | }], |
912541b0 | 2066 | rules => <<EOF |
d7867b31 KS |
2067 | KERNEL=="sda", IMPORT{builtin}="path_id" |
2068 | KERNEL=="sda", ENV{ID_PATH}=="?*", SYMLINK+="disk/by-path/\$env{ID_PATH}" | |
bf8f7583 MP |
2069 | EOF |
2070 | }, | |
2071 | { | |
2072 | desc => "add and match tag", | |
255c05b7 MW |
2073 | devices => [ |
2074 | { | |
2075 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", | |
e62acc31 MW |
2076 | exp_links => ["found"], |
2077 | not_exp_links => ["bad"], | |
255c05b7 | 2078 | }], |
bf8f7583 MP |
2079 | rules => <<EOF |
2080 | SUBSYSTEMS=="scsi", ATTRS{vendor}=="ATA", TAG+="green" | |
2081 | TAGS=="green", SYMLINK+="found" | |
2082 | TAGS=="blue", SYMLINK+="bad" | |
2083 | EOF | |
2084 | }, | |
2085 | { | |
2086 | desc => "don't crash with lots of tags", | |
255c05b7 MW |
2087 | devices => [ |
2088 | { | |
2089 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", | |
e62acc31 | 2090 | exp_links => ["found"], |
255c05b7 | 2091 | }], |
bf8f7583 MP |
2092 | rules => $rules_10k_tags . <<EOF |
2093 | TAGS=="test1", TAGS=="test500", TAGS=="test1234", TAGS=="test9999", TAGS=="test10000", SYMLINK+="found" | |
1e797cf5 YW |
2094 | EOF |
2095 | }, | |
2096 | { | |
d35976c6 | 2097 | desc => "continuations", |
255c05b7 MW |
2098 | devices => [ |
2099 | { | |
2100 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", | |
e62acc31 | 2101 | exp_links => ["found"], |
255c05b7 MW |
2102 | not_exp_name => "bad", |
2103 | }], | |
1e797cf5 YW |
2104 | rules => $rules_10k_tags_continuation . <<EOF |
2105 | TAGS=="test1", TAGS=="test500", TAGS=="test1234", TAGS=="test9999", TAGS=="test10000", SYMLINK+="bad" | |
d35976c6 YW |
2106 | KERNEL=="sda",\\ |
2107 | # comment in continuation | |
2108 | TAG+="hoge1",\\ | |
2109 | # space before comment | |
2110 | TAG+="hoge2",\\ | |
2111 | # spaces before and after token are dropped | |
2112 | TAG+="hoge3", \\ | |
84a0819c YW |
2113 | \\ |
2114 | \\ | |
d35976c6 YW |
2115 | TAG+="hoge4" |
2116 | TAGS=="hoge1", TAGS=="hoge2", TAGS=="hoge3", TAGS=="hoge4", SYMLINK+="found" | |
84a0819c YW |
2117 | EOF |
2118 | }, | |
2119 | { | |
2120 | desc => "continuations with empty line", | |
255c05b7 MW |
2121 | devices => [ |
2122 | { | |
2123 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", | |
e62acc31 | 2124 | exp_links => ["found"], |
255c05b7 MW |
2125 | not_exp_name => "bad", |
2126 | ||
2127 | }], | |
84a0819c YW |
2128 | rules => <<EOF |
2129 | # empty line finishes continuation | |
2130 | KERNEL=="sda", TAG+="foo" \\ | |
2131 | ||
2132 | KERNEL=="sdb", TAG+="hoge" | |
2133 | KERNEL=="sda", TAG+="aaa" \\ | |
2134 | KERNEL=="sdb", TAG+="bbb" | |
2135 | TAGS=="foo", SYMLINK+="found" | |
2136 | TAGS=="aaa", SYMLINK+="bad" | |
255c05b7 | 2137 | EOF |
84a0819c YW |
2138 | }, |
2139 | { | |
2140 | desc => "continuations with white only line", | |
255c05b7 MW |
2141 | devices => [ |
2142 | { | |
2143 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", | |
e62acc31 | 2144 | exp_links => ["found"], |
255c05b7 MW |
2145 | not_exp_name => "bad", |
2146 | }], | |
84a0819c YW |
2147 | rules => <<EOF |
2148 | # space only line finishes continuation | |
2149 | KERNEL=="sda", TAG+="foo" \\ | |
2150 | \t | |
2151 | KERNEL=="sdb", TAG+="hoge" | |
2152 | KERNEL=="sda", TAG+="aaa" \\ | |
2153 | KERNEL=="sdb", TAG+="bbb" | |
2154 | TAGS=="foo", SYMLINK+="found" | |
2155 | TAGS=="aaa", SYMLINK+="bad" | |
4a0ec82d MW |
2156 | EOF |
2157 | }, | |
2158 | { | |
2159 | desc => "multiple devices", | |
2160 | devices => [ | |
2161 | { | |
2162 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", | |
2163 | exp_links => ["part-1"], | |
2164 | }, | |
2165 | { | |
2166 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", | |
2167 | exp_links => ["part-5"], | |
2168 | }, | |
2169 | { | |
2170 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda6", | |
2171 | exp_links => ["part-6"], | |
2172 | }, | |
2173 | { | |
2174 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda7", | |
2175 | exp_links => ["part-7"], | |
2176 | }, | |
2177 | { | |
2178 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda8", | |
2179 | exp_links => ["part-8"], | |
2180 | }, | |
2181 | { | |
2182 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda9", | |
2183 | exp_links => ["part-9"], | |
2184 | }, | |
2185 | { | |
2186 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda10", | |
2187 | exp_links => ["part-10"], | |
2188 | }, | |
2189 | ], | |
2190 | rules => <<EOF | |
2191 | SUBSYSTEM=="block", SUBSYSTEMS=="scsi", KERNEL=="sda?*", ENV{DEVTYPE}=="partition", SYMLINK+="part-%n" | |
2192 | EOF | |
2193 | }, | |
2194 | { | |
2195 | desc => "multiple devices, same link name, positive prio", | |
2ab0a8d0 | 2196 | repeat => 100, |
4a0ec82d MW |
2197 | devices => [ |
2198 | { | |
2199 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", | |
2200 | exp_links => ["part-1"], | |
2201 | not_exp_links => ["partition"], | |
2202 | }, | |
2203 | { | |
2204 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", | |
2205 | exp_links => ["part-5"], | |
2206 | not_exp_links => ["partition"], | |
2207 | }, | |
2208 | { | |
2209 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda6", | |
2210 | not_exp_links => ["partition"], | |
2211 | exp_links => ["part-6"], | |
2212 | }, | |
2213 | { | |
2214 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda7", | |
2215 | exp_links => ["part-7", "partition"], | |
2216 | }, | |
2217 | { | |
2218 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda8", | |
2219 | not_exp_links => ["partition"], | |
2220 | exp_links => ["part-8"], | |
2221 | }, | |
2222 | { | |
2223 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda9", | |
2224 | not_exp_links => ["partition"], | |
2225 | exp_links => ["part-9"], | |
2226 | }, | |
2227 | { | |
2228 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda10", | |
2229 | not_exp_links => ["partition"], | |
2230 | exp_links => ["part-10"], | |
2231 | }, | |
2232 | ], | |
2233 | rules => <<EOF | |
2234 | SUBSYSTEM=="block", SUBSYSTEMS=="scsi", KERNEL=="sda?*", ENV{DEVTYPE}=="partition", SYMLINK+="part-%n" | |
2235 | SUBSYSTEM=="block", SUBSYSTEMS=="scsi", KERNEL=="sda?*", ENV{DEVTYPE}=="partition", SYMLINK+="partition" | |
2236 | KERNEL=="*7", OPTIONS+="link_priority=10" | |
2237 | EOF | |
2238 | }, | |
2239 | { | |
2240 | desc => "multiple devices, same link name, negative prio", | |
2241 | devices => [ | |
2242 | { | |
2243 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", | |
2244 | exp_links => ["part-1"], | |
2245 | not_exp_links => ["partition"], | |
2246 | }, | |
2247 | { | |
2248 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", | |
2249 | exp_links => ["part-5"], | |
2250 | not_exp_links => ["partition"], | |
2251 | }, | |
2252 | { | |
2253 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda6", | |
2254 | not_exp_links => ["partition"], | |
2255 | exp_links => ["part-6"], | |
2256 | }, | |
2257 | { | |
2258 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda7", | |
2259 | exp_links => ["part-7", "partition"], | |
2260 | }, | |
2261 | { | |
2262 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda8", | |
2263 | not_exp_links => ["partition"], | |
2264 | exp_links => ["part-8"], | |
2265 | }, | |
2266 | { | |
2267 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda9", | |
2268 | not_exp_links => ["partition"], | |
2269 | exp_links => ["part-9"], | |
2270 | }, | |
2271 | { | |
2272 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda10", | |
2273 | not_exp_links => ["partition"], | |
2274 | exp_links => ["part-10"], | |
2275 | }, | |
2276 | ], | |
2277 | rules => <<EOF | |
2278 | SUBSYSTEM=="block", SUBSYSTEMS=="scsi", KERNEL=="sda?*", ENV{DEVTYPE}=="partition", SYMLINK+="part-%n" | |
2279 | SUBSYSTEM=="block", SUBSYSTEMS=="scsi", KERNEL=="sda?*", ENV{DEVTYPE}=="partition", SYMLINK+="partition" | |
2280 | KERNEL!="*7", OPTIONS+="link_priority=-10" | |
2281 | EOF | |
2282 | }, | |
2283 | { | |
2284 | desc => "multiple devices, same link name, positive prio, sleep", | |
2285 | devices => [ | |
2286 | { | |
2287 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", | |
2288 | exp_links => ["part-1"], | |
2289 | not_exp_links => ["partition"], | |
2290 | }, | |
2291 | { | |
2292 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", | |
2293 | exp_links => ["part-5"], | |
2294 | not_exp_links => ["partition"], | |
2295 | }, | |
2296 | { | |
2297 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda6", | |
2298 | not_exp_links => ["partition"], | |
2299 | exp_links => ["part-6"], | |
2300 | }, | |
2301 | { | |
2302 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda7", | |
2303 | exp_links => ["part-7", "partition"], | |
2304 | }, | |
2305 | { | |
2306 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda8", | |
2307 | not_exp_links => ["partition"], | |
2308 | exp_links => ["part-8"], | |
2309 | }, | |
2310 | { | |
2311 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda9", | |
2312 | not_exp_links => ["partition"], | |
2313 | exp_links => ["part-9"], | |
2314 | }, | |
2315 | { | |
2316 | devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda10", | |
2317 | not_exp_links => ["partition"], | |
2318 | exp_links => ["part-10"], | |
2319 | }, | |
2320 | ], | |
2321 | sleep_us => 10000, | |
2322 | rules => <<EOF | |
2323 | SUBSYSTEM=="block", SUBSYSTEMS=="scsi", KERNEL=="sda?*", ENV{DEVTYPE}=="partition", SYMLINK+="part-%n" | |
2324 | SUBSYSTEM=="block", SUBSYSTEMS=="scsi", KERNEL=="sda?*", ENV{DEVTYPE}=="partition", SYMLINK+="partition" | |
2325 | KERNEL=="*7", OPTIONS+="link_priority=10" | |
ff94cec3 | 2326 | EOF |
912541b0 | 2327 | }, |
eb44d715 MW |
2328 | { |
2329 | desc => 'all_block_devs', | |
2330 | generator => expect_for_some("\\/sda6\$", ["blockdev"]), | |
2331 | repeat => 10, | |
2332 | rules => <<EOF | |
2333 | SUBSYSTEM=="block", SUBSYSTEMS=="scsi", KERNEL=="sd*", SYMLINK+="blockdev" | |
2334 | KERNEL=="sda6", OPTIONS+="link_priority=10" | |
2335 | EOF | |
2336 | } | |
a367f04e GKH |
2337 | ); |
2338 | ||
af7ee3ea MW |
2339 | sub create_rules { |
2340 | my ($rules) = @_; | |
a367f04e | 2341 | |
912541b0 | 2342 | # create temporary rules |
6ada823a | 2343 | system("mkdir", "-p", "$udev_rules_dir"); |
912541b0 KS |
2344 | open CONF, ">$udev_rules" || die "unable to create rules file: $udev_rules"; |
2345 | print CONF $$rules; | |
2346 | close CONF; | |
af7ee3ea MW |
2347 | } |
2348 | ||
2349 | sub udev { | |
2350 | my ($action, $devpath) = @_; | |
a367f04e | 2351 | |
912541b0 | 2352 | if ($valgrind > 0) { |
efc9f703 | 2353 | return system("$udev_bin_valgrind $action $devpath"); |
333e07b7 | 2354 | } elsif ($gdb > 0) { |
efc9f703 | 2355 | return system("$udev_bin_gdb $action $devpath"); |
587751eb | 2356 | } elsif ($strace > 0) { |
efc9f703 | 2357 | return system("$udev_bin_strace $action $devpath"); |
912541b0 | 2358 | } else { |
efc9f703 | 2359 | return system("$udev_bin", "$action", "$devpath"); |
912541b0 | 2360 | } |
a367f04e GKH |
2361 | } |
2362 | ||
e5fbfe0a | 2363 | my $error = 0; |
b95c4398 | 2364 | my $good = 0; |
cbeb23d8 | 2365 | my $exp_good = 0; |
72ffa78d | 2366 | |
b8669191 | 2367 | sub permissions_test { |
912541b0 | 2368 | my($rules, $uid, $gid, $mode) = @_; |
b8669191 | 2369 | |
912541b0 KS |
2370 | my $wrong = 0; |
2371 | my $userid; | |
2372 | my $groupid; | |
9b434de1 | 2373 | |
912541b0 KS |
2374 | $rules->{exp_perms} =~ m/^(.*):(.*):(.*)$/; |
2375 | if ($1 ne "") { | |
2376 | if (defined(getpwnam($1))) { | |
2377 | $userid = int(getpwnam($1)); | |
2378 | } else { | |
2379 | $userid = $1; | |
2380 | } | |
2381 | if ($uid != $userid) { $wrong = 1; } | |
2382 | } | |
2383 | if ($2 ne "") { | |
2384 | if (defined(getgrnam($2))) { | |
2385 | $groupid = int(getgrnam($2)); | |
2386 | } else { | |
2387 | $groupid = $2; | |
2388 | } | |
2389 | if ($gid != $groupid) { $wrong = 1; } | |
2390 | } | |
2391 | if ($3 ne "") { | |
2392 | if (($mode & 07777) != oct($3)) { $wrong = 1; }; | |
2393 | } | |
2394 | if ($wrong == 0) { | |
2395 | print "permissions: ok\n"; | |
b95c4398 | 2396 | $good++; |
912541b0 KS |
2397 | } else { |
2398 | printf " expected permissions are: %s:%s:%#o\n", $1, $2, oct($3); | |
2399 | printf " created permissions are : %i:%i:%#o\n", $uid, $gid, $mode & 07777; | |
2400 | print "permissions: error\n"; | |
2401 | $error++; | |
2402 | sleep(1); | |
2403 | } | |
b8669191 GKH |
2404 | } |
2405 | ||
2406 | sub major_minor_test { | |
912541b0 | 2407 | my($rules, $rdev) = @_; |
b8669191 | 2408 | |
912541b0 KS |
2409 | my $major = ($rdev >> 8) & 0xfff; |
2410 | my $minor = ($rdev & 0xff) | (($rdev >> 12) & 0xfff00); | |
2411 | my $wrong = 0; | |
b8669191 | 2412 | |
912541b0 KS |
2413 | $rules->{exp_majorminor} =~ m/^(.*):(.*)$/; |
2414 | if ($1 ne "") { | |
2415 | if ($major != $1) { $wrong = 1; }; | |
2416 | } | |
2417 | if ($2 ne "") { | |
2418 | if ($minor != $2) { $wrong = 1; }; | |
2419 | } | |
2420 | if ($wrong == 0) { | |
2421 | print "major:minor: ok\n"; | |
b95c4398 | 2422 | $good++; |
912541b0 KS |
2423 | } else { |
2424 | printf " expected major:minor is: %i:%i\n", $1, $2; | |
2425 | printf " created major:minor is : %i:%i\n", $major, $minor; | |
2426 | print "major:minor: error\n"; | |
2427 | $error++; | |
2428 | sleep(1); | |
2429 | } | |
b8669191 GKH |
2430 | } |
2431 | ||
6ada823a | 2432 | sub udev_setup { |
f1cb0860 | 2433 | system("umount \"$udev_tmpfs\" 2>/dev/null"); |
21d9e3f3 EV |
2434 | rmdir($udev_tmpfs); |
2435 | mkdir($udev_tmpfs) || die "unable to create udev_tmpfs: $udev_tmpfs\n"; | |
110a1320 EV |
2436 | |
2437 | if (system("mount", "-o", "rw,mode=755,nosuid,noexec", "-t", "tmpfs", "tmpfs", $udev_tmpfs)) { | |
2438 | warn "unable to mount tmpfs"; | |
2439 | return 0; | |
2440 | } | |
21d9e3f3 | 2441 | |
6ada823a KS |
2442 | mkdir($udev_dev) || die "unable to create udev_dev: $udev_dev\n"; |
2443 | # setting group and mode of udev_dev ensures the tests work | |
912541b0 | 2444 | # even if the parent directory has setgid bit enabled. |
6ada823a KS |
2445 | chown (0, 0, $udev_dev) || die "unable to chown $udev_dev\n"; |
2446 | chmod (0755, $udev_dev) || die "unable to chmod $udev_dev\n"; | |
110a1320 EV |
2447 | |
2448 | if (system("mknod", $udev_dev . "/null", "c", "1", "3")) { | |
2449 | warn "unable to create $udev_dev/null"; | |
2450 | return 0; | |
2451 | } | |
6ada823a | 2452 | |
dbfbc6c4 AB |
2453 | # check if we are permitted to create block device nodes |
2454 | my $block_device_filename = $udev_dev . "/sda"; | |
2455 | if (system("mknod", $block_device_filename, "b", "8", "0")) { | |
2456 | warn "unable to create $block_device_filename"; | |
2457 | return 0; | |
2458 | } | |
2459 | unlink $block_device_filename; | |
2460 | ||
21d9e3f3 | 2461 | system("cp", "-r", "test/sys/", $udev_sys) && die "unable to copy test/sys"; |
2ce8d27b | 2462 | |
6ada823a | 2463 | system("rm", "-rf", "$udev_run"); |
110a1320 | 2464 | |
1e5548c0 AB |
2465 | if (!mkdir($udev_run)) { |
2466 | warn "unable to create directory $udev_run"; | |
2467 | return 0; | |
2468 | } | |
2469 | ||
110a1320 | 2470 | return 1; |
ff94cec3 EK |
2471 | } |
2472 | ||
f0dccf01 MW |
2473 | sub get_devnode { |
2474 | my ($device) = @_; | |
2475 | my $devnode; | |
2476 | ||
2477 | if (defined($device->{devnode})) { | |
2478 | $devnode = "$udev_dev/$device->{devnode}"; | |
2479 | } else { | |
2480 | $devnode = "$device->{devpath}"; | |
2481 | $devnode =~ s!.*/!$udev_dev/!; | |
2482 | } | |
2483 | return $devnode; | |
2484 | } | |
2485 | ||
2486 | sub check_devnode { | |
2487 | my ($device) = @_; | |
2488 | my $devnode = get_devnode($device); | |
2489 | ||
2490 | my @st = lstat("$devnode"); | |
2491 | if (! (-b _ || -c _)) { | |
2492 | print "add $devnode: error\n"; | |
2493 | system("tree", "$udev_dev"); | |
2494 | $error++; | |
2495 | return undef; | |
2496 | } | |
2497 | ||
2498 | my ($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size, | |
2499 | $atime, $mtime, $ctime, $blksize, $blocks) = @st; | |
2500 | ||
2501 | if (defined($device->{exp_perms})) { | |
2502 | permissions_test($device, $uid, $gid, $mode); | |
2503 | } | |
2504 | if (defined($device->{exp_majorminor})) { | |
2505 | major_minor_test($device, $rdev); | |
2506 | } | |
2507 | print "add $devnode: ok\n"; | |
b95c4398 | 2508 | $good++; |
f0dccf01 MW |
2509 | return $devnode; |
2510 | } | |
2511 | ||
e62acc31 MW |
2512 | sub get_link_target { |
2513 | my ($link) = @_; | |
09a4062d | 2514 | |
e62acc31 MW |
2515 | my $cwd = getcwd(); |
2516 | my $dir = "$udev_dev/$link"; | |
2517 | my $tgt = readlink("$udev_dev/$link"); | |
2518 | $dir =~ s!/[^/]*$!!; | |
2519 | $tgt = abs_path("$dir/$tgt"); | |
2520 | $tgt =~ s!^$cwd/!!; | |
2521 | return $tgt; | |
2522 | } | |
f0dccf01 | 2523 | |
e62acc31 MW |
2524 | sub check_link_add { |
2525 | my ($link, $devnode, $err_expected) = @_; | |
f0dccf01 | 2526 | |
e62acc31 | 2527 | my @st = lstat("$udev_dev/$link"); |
997683c8 | 2528 | if (-l _) { |
e62acc31 | 2529 | my $tgt = get_link_target($link); |
997683c8 MW |
2530 | |
2531 | if ($tgt ne $devnode) { | |
e62acc31 | 2532 | print "symlink $link: error, found -> $tgt\n"; |
997683c8 MW |
2533 | $error++; |
2534 | system("tree", "$udev_dev"); | |
2535 | } else { | |
e62acc31 | 2536 | print "symlink $link: ok\n"; |
b95c4398 | 2537 | $good++; |
997683c8 | 2538 | } |
912541b0 | 2539 | } else { |
e62acc31 MW |
2540 | print "symlink $link: error"; |
2541 | if ($err_expected) { | |
912541b0 | 2542 | print " as expected\n"; |
b95c4398 | 2543 | $good++; |
912541b0 KS |
2544 | } else { |
2545 | print "\n"; | |
6ada823a | 2546 | system("tree", "$udev_dev"); |
912541b0 KS |
2547 | print "\n"; |
2548 | $error++; | |
2549 | sleep(1); | |
2550 | } | |
2551 | } | |
255c05b7 | 2552 | } |
a367f04e | 2553 | |
e62acc31 MW |
2554 | sub check_link_nonexistent { |
2555 | my ($link, $devnode, $err_expected) = @_; | |
2556 | ||
2557 | if ((-e "$udev_dev/$link") || (-l "$udev_dev/$link")) { | |
2558 | my $tgt = get_link_target($link); | |
2559 | ||
2560 | if ($tgt ne $devnode) { | |
2561 | print "nonexistent: '$link' points to other device (ok)\n"; | |
b95c4398 | 2562 | $good++; |
e62acc31 MW |
2563 | } else { |
2564 | print "nonexistent: error \'$link\' should not be there"; | |
2565 | if ($err_expected) { | |
2566 | print " (as expected)\n"; | |
b95c4398 | 2567 | $good++; |
e62acc31 MW |
2568 | } else { |
2569 | print "\n"; | |
2570 | system("tree", "$udev_dev"); | |
2571 | print "\n"; | |
2572 | $error++; | |
2573 | sleep(1); | |
2574 | } | |
2575 | } | |
2576 | } else { | |
2577 | print "nonexistent $link: ok\n"; | |
b95c4398 | 2578 | $good++; |
e62acc31 MW |
2579 | } |
2580 | } | |
2581 | ||
2582 | sub check_add { | |
2583 | my ($device) = @_; | |
2584 | my $devnode = check_devnode($device); | |
2585 | ||
2586 | if (defined($device->{exp_links})) { | |
2587 | foreach my $link (@{$device->{exp_links}}) { | |
2588 | check_link_add($link, $devnode, | |
2589 | $device->{exp_add_error}); | |
2590 | } | |
2591 | } | |
2592 | if (defined $device->{not_exp_links}) { | |
2593 | foreach my $link (@{$device->{not_exp_links}}) { | |
2594 | check_link_nonexistent($link, $devnode, | |
2595 | $device->{exp_nodev_error}); | |
2596 | } | |
2597 | } | |
2598 | } | |
2599 | ||
f0dccf01 MW |
2600 | sub check_remove_devnode { |
2601 | my ($device) = @_; | |
2602 | my $devnode = get_devnode($device); | |
2603 | ||
2604 | if (-e "$devnode") { | |
2605 | print "remove $devnode: error"; | |
2606 | print "\n"; | |
2607 | system("tree", "$udev_dev"); | |
2608 | print "\n"; | |
2609 | $error++; | |
2610 | sleep(1); | |
2611 | } else { | |
2612 | print "remove $devnode: ok\n"; | |
b95c4398 | 2613 | $good++; |
f0dccf01 MW |
2614 | } |
2615 | } | |
2616 | ||
e62acc31 MW |
2617 | sub check_link_remove { |
2618 | my ($link, $err_expected) = @_; | |
f0dccf01 | 2619 | |
e62acc31 MW |
2620 | if ((-e "$udev_dev/$link") || |
2621 | (-l "$udev_dev/$link")) { | |
2622 | print "remove $link: error"; | |
2623 | if ($err_expected) { | |
912541b0 | 2624 | print " as expected\n"; |
b95c4398 | 2625 | $good++; |
912541b0 KS |
2626 | } else { |
2627 | print "\n"; | |
6ada823a | 2628 | system("tree", "$udev_dev"); |
912541b0 KS |
2629 | print "\n"; |
2630 | $error++; | |
2631 | sleep(1); | |
2632 | } | |
2633 | } else { | |
e62acc31 | 2634 | print "remove $link: ok\n"; |
b95c4398 | 2635 | $good++; |
e62acc31 MW |
2636 | } |
2637 | } | |
2638 | ||
2639 | sub check_remove { | |
2640 | my ($device) = @_; | |
2641 | ||
2642 | check_remove_devnode($device); | |
2643 | ||
2644 | return if (!defined($device->{exp_links})); | |
2645 | ||
2646 | foreach my $link (@{$device->{exp_links}}) { | |
2647 | check_link_remove($link, $device->{exp_rem_error}); | |
255c05b7 MW |
2648 | } |
2649 | } | |
2650 | ||
09a4062d MW |
2651 | sub run_udev { |
2652 | my ($action, $dev, $sleep_us, $sema) = @_; | |
2653 | ||
2654 | # Notify main process that this worker has started | |
2655 | $sema->op(0, 1, 0); | |
2656 | ||
2657 | # Wait for start | |
2658 | $sema->op(0, 0, 0); | |
2659 | usleep($sleep_us) if defined ($sleep_us); | |
2660 | my $rc = udev($action, $dev->{devpath}); | |
2661 | exit $rc; | |
2662 | } | |
2663 | ||
2664 | sub fork_and_run_udev { | |
2665 | my ($action, $rules, $sema) = @_; | |
2666 | my @devices = @{$rules->{devices}}; | |
2667 | my $dev; | |
2668 | my $k = 0; | |
2669 | ||
2670 | $sema->setval(0, 1); | |
2671 | foreach $dev (@devices) { | |
2672 | my $pid = fork(); | |
2673 | ||
2674 | if (!$pid) { | |
2675 | run_udev($action, $dev, | |
2676 | defined($rules->{sleep_us}) ? $k * $rules->{sleep_us} : undef, | |
2677 | $sema); | |
2678 | } else { | |
2679 | $dev->{pid} = $pid; | |
2680 | } | |
2681 | $k++; | |
2682 | } | |
2683 | ||
2684 | # This operation waits for all workers to become ready, and | |
2685 | # starts them off when that's the case. | |
2686 | $sema->op(0, -($#devices + 2), 0); | |
2687 | ||
2688 | foreach $dev (@devices) { | |
2689 | my $rc; | |
2690 | my $pid; | |
2691 | ||
2692 | $pid = waitpid($dev->{pid}, 0); | |
2693 | if ($pid == -1) { | |
2694 | print "error waiting for pid dev->{pid}\n"; | |
09a4062d MW |
2695 | } |
2696 | if (WIFEXITED($?)) { | |
2697 | $rc = WEXITSTATUS($?); | |
2698 | ||
2699 | if ($rc) { | |
2700 | print "$udev_bin $action for $dev->{devpath} failed with code $rc\n"; | |
2701 | $error += 1; | |
b95c4398 MW |
2702 | } else { |
2703 | $good++; | |
09a4062d MW |
2704 | } |
2705 | } | |
2706 | } | |
2707 | } | |
2708 | ||
255c05b7 | 2709 | sub run_test { |
09a4062d | 2710 | my ($rules, $number, $sema) = @_; |
255c05b7 | 2711 | my $rc; |
eb44d715 | 2712 | my @devices; |
cbeb23d8 MW |
2713 | my $ntests; |
2714 | my $cur_good = $good; | |
2715 | my $cur_error = $error; | |
eb44d715 MW |
2716 | |
2717 | if (!defined $rules->{devices}) { | |
2718 | $rules->{devices} = all_block_devs($rules->{generator}); | |
2719 | } | |
2720 | @devices = @{$rules->{devices}}; | |
cbeb23d8 MW |
2721 | # For each device: exit status and devnode test for add & remove |
2722 | $ntests += 4 * ($#devices + 1); | |
255c05b7 | 2723 | |
cbeb23d8 MW |
2724 | foreach my $dev (@devices) { |
2725 | $ntests += 2 * ($#{$dev->{exp_links}} + 1) | |
2726 | + ($#{$dev->{not_exp_links}} + 1) | |
2727 | + (defined $dev->{exp_perms} ? 1 : 0) | |
2728 | + (defined $dev->{exp_majorminor} ? 1 : 0); | |
2729 | } | |
2730 | if (defined $rules->{repeat}) { | |
2731 | $ntests *= $rules->{repeat}; | |
2732 | } | |
2733 | $exp_good += $ntests; | |
255c05b7 | 2734 | print "TEST $number: $rules->{desc}\n"; |
af7ee3ea | 2735 | create_rules(\$rules->{rules}); |
09a4062d | 2736 | |
2ab0a8d0 | 2737 | REPEAT: |
09a4062d | 2738 | fork_and_run_udev("add", $rules, $sema); |
255c05b7 MW |
2739 | |
2740 | foreach my $dev (@devices) { | |
2741 | check_add($dev); | |
2742 | } | |
2743 | ||
2744 | if (defined($rules->{option}) && $rules->{option} eq "keep") { | |
2745 | print "\n\n"; | |
2746 | return; | |
2747 | } | |
2748 | ||
09a4062d MW |
2749 | fork_and_run_udev("remove", $rules, $sema); |
2750 | ||
255c05b7 MW |
2751 | foreach my $dev (@devices) { |
2752 | check_remove($dev); | |
912541b0 | 2753 | } |
0345b862 | 2754 | |
2ab0a8d0 MW |
2755 | if (defined($rules->{repeat}) && --($rules->{repeat}) > 0) { |
2756 | goto REPEAT; | |
2757 | } | |
cbeb23d8 MW |
2758 | printf "TEST $number: errors: %d good: %d/%d\n\n", $error-$cur_error, |
2759 | $good-$cur_good, $ntests; | |
9b434de1 | 2760 | |
912541b0 | 2761 | if (defined($rules->{option}) && $rules->{option} eq "clean") { |
6ada823a | 2762 | udev_setup(); |
912541b0 | 2763 | } |
0345b862 | 2764 | |
a367f04e GKH |
2765 | } |
2766 | ||
abb9cc50 DS |
2767 | sub cleanup { |
2768 | system("rm", "-rf", "$udev_run"); | |
2769 | system("umount", "$udev_tmpfs"); | |
2770 | rmdir($udev_tmpfs); | |
2771 | } | |
2772 | ||
800ab95b GKH |
2773 | # only run if we have root permissions |
2774 | # due to mknod restrictions | |
2775 | if (!($<==0)) { | |
912541b0 | 2776 | print "Must have root permissions to run properly.\n"; |
4d55fc5b | 2777 | exit($EXIT_TEST_SKIP); |
800ab95b GKH |
2778 | } |
2779 | ||
e4d214ef DC |
2780 | # skip the test when running in a chroot |
2781 | system("systemd-detect-virt", "-r", "-q"); | |
2782 | if ($? >> 8 == 0) { | |
ce5fcc69 ZJS |
2783 | print "Running in a chroot, skipping the test.\n"; |
2784 | exit($EXIT_TEST_SKIP); | |
e4d214ef DC |
2785 | } |
2786 | ||
110a1320 EV |
2787 | if (!udev_setup()) { |
2788 | warn "Failed to set up the environment, skipping the test"; | |
abb9cc50 | 2789 | cleanup(); |
110a1320 EV |
2790 | exit($EXIT_TEST_SKIP); |
2791 | } | |
2792 | ||
7935dae5 | 2793 | if (system($udev_bin, "check")) { |
110a1320 | 2794 | warn "$udev_bin failed to set up the environment, skipping the test"; |
abb9cc50 | 2795 | cleanup(); |
110a1320 EV |
2796 | exit($EXIT_TEST_SKIP); |
2797 | } | |
2e317184 GKH |
2798 | |
2799 | my $test_num = 1; | |
e08109cb | 2800 | my @list; |
2e317184 | 2801 | |
e08109cb | 2802 | foreach my $arg (@ARGV) { |
912541b0 KS |
2803 | if ($arg =~ m/--valgrind/) { |
2804 | $valgrind = 1; | |
2805 | printf("using valgrind\n"); | |
333e07b7 TG |
2806 | } elsif ($arg =~ m/--gdb/) { |
2807 | $gdb = 1; | |
2808 | printf("using gdb\n"); | |
587751eb ZJS |
2809 | } elsif ($arg =~ m/--strace/) { |
2810 | $strace = 1; | |
2811 | printf("using strace\n"); | |
912541b0 KS |
2812 | } else { |
2813 | push(@list, $arg); | |
2814 | } | |
e08109cb | 2815 | } |
09a4062d | 2816 | my $sema = IPC::Semaphore->new(IPC_PRIVATE, 1, S_IRUSR | S_IWUSR | IPC_CREAT); |
e08109cb KS |
2817 | |
2818 | if ($list[0]) { | |
912541b0 KS |
2819 | foreach my $arg (@list) { |
2820 | if (defined($tests[$arg-1]->{desc})) { | |
2821 | print "udev-test will run test number $arg:\n\n"; | |
09a4062d | 2822 | run_test($tests[$arg-1], $arg, $sema); |
912541b0 KS |
2823 | } else { |
2824 | print "test does not exist.\n"; | |
2825 | } | |
2826 | } | |
2e317184 | 2827 | } else { |
912541b0 KS |
2828 | # test all |
2829 | print "\nudev-test will run ".($#tests + 1)." tests:\n\n"; | |
2e317184 | 2830 | |
912541b0 | 2831 | foreach my $rules (@tests) { |
09a4062d | 2832 | run_test($rules, $test_num, $sema); |
912541b0 KS |
2833 | $test_num++; |
2834 | } | |
2e317184 GKH |
2835 | } |
2836 | ||
09a4062d | 2837 | $sema->remove; |
cbeb23d8 | 2838 | print "$error errors occurred. $good/$exp_good good results.\n\n"; |
a367f04e | 2839 | |
abb9cc50 | 2840 | cleanup(); |
a367f04e | 2841 | |
034b37c8 | 2842 | if ($error > 0) { |
d3fc8bf4 | 2843 | exit(1); |
034b37c8 AJ |
2844 | } |
2845 | exit(0); |