udev-test.pl 64.9 KB
Newer Older
1 2
#!/usr/bin/perl

3
# udev test
4 5 6 7 8 9 10 11
#
# Provides automated testing of the udev binary.
# The whole test is self contained in this file, except the matching sysfs tree.
# Simply extend the @tests array, to add a new test variant.
#
# Every test is driven by its own temporary config file.
# This program prepares the environment, creates the config and calls udev.
#
12
# udev parses the rules, looks at the provided sysfs and
13 14 15 16
# first creates and then removes the device node.
# After creation and removal the result is checked against the
# expected value and the result is printed.
#
17
# Copyright (C) 2004-2012 Kay Sievers <kay.sievers@vrfy.org>
18
# Copyright (C) 2004 Leann Ogasawara <ogasawara@osdl.org>
19 20 21 22

use warnings;
use strict;

23
my $udev_bin            = "./test-udev";
24 25
my $valgrind            = 0;
my $udev_bin_valgrind   = "valgrind --tool=memcheck --leak-check=yes --quiet $udev_bin";
26 27 28 29
my $udev_dev            = "test/dev";
my $udev_run            = "test/run";
my $udev_rules_dir      = "$udev_run/udev/rules.d";
my $udev_rules          = "$udev_rules_dir/udev-test.rules";
30 31

my @tests = (
32 33 34 35 36 37
        {
                desc            => "no rules",
                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
                exp_name        => "sda" ,
                exp_rem_error   => "yes",
                rules           => <<EOF
Kay Sievers's avatar
Kay Sievers committed
38
#
39
EOF
40 41 42 43 44 45
        },
        {
                desc            => "label test of scsi disc",
                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
                exp_name        => "boot_disk" ,
                rules           => <<EOF
46
SUBSYSTEMS=="scsi", ATTRS{vendor}=="ATA", SYMLINK+="boot_disk%n"
Kay Sievers's avatar
Kay Sievers committed
47
KERNEL=="ttyACM0", SYMLINK+="modem"
48
EOF
49 50 51 52 53 54
        },
        {
                desc            => "label test of scsi disc",
                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
                exp_name        => "boot_disk" ,
                rules           => <<EOF
Kay Sievers's avatar
Kay Sievers committed
55 56
SUBSYSTEMS=="scsi", ATTRS{vendor}=="ATA", SYMLINK+="boot_disk%n"
KERNEL=="ttyACM0", SYMLINK+="modem"
57
EOF
58 59 60 61 62 63
        },
        {
                desc            => "label test of scsi disc",
                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
                exp_name        => "boot_disk" ,
                rules           => <<EOF
Kay Sievers's avatar
Kay Sievers committed
64 65
SUBSYSTEMS=="scsi", ATTRS{vendor}=="ATA", SYMLINK+="boot_disk%n"
KERNEL=="ttyACM0", SYMLINK+="modem"
66
EOF
67 68 69 70 71 72
        },
        {
                desc            => "label test of scsi partition",
                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1",
                exp_name        => "boot_disk1" ,
                rules           => <<EOF
Kay Sievers's avatar
Kay Sievers committed
73
SUBSYSTEMS=="scsi", ATTRS{vendor}=="ATA", SYMLINK+="boot_disk%n"
74
EOF
75 76 77 78 79 80
        },
        {
                desc            => "label test of pattern match",
                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1",
                exp_name        => "boot_disk1" ,
                rules           => <<EOF
Kay Sievers's avatar
Kay Sievers committed
81 82 83 84
SUBSYSTEMS=="scsi", ATTRS{vendor}=="?ATA", SYMLINK+="boot_disk%n-1"
SUBSYSTEMS=="scsi", ATTRS{vendor}=="ATA?", SYMLINK+="boot_disk%n-2"
SUBSYSTEMS=="scsi", ATTRS{vendor}=="A??", SYMLINK+="boot_disk%n"
SUBSYSTEMS=="scsi", ATTRS{vendor}=="ATAS", SYMLINK+="boot_disk%n-3"
85
EOF
86 87 88 89 90 91
        },
        {
                desc            => "label test of multiple sysfs files",
                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1",
                exp_name        => "boot_disk1" ,
                rules           => <<EOF
Kay Sievers's avatar
Kay Sievers committed
92 93
SUBSYSTEMS=="scsi", ATTRS{vendor}=="ATA", ATTRS{model}=="ST910021AS X ", SYMLINK+="boot_diskX%n"
SUBSYSTEMS=="scsi", ATTRS{vendor}=="ATA", ATTRS{model}=="ST910021AS", SYMLINK+="boot_disk%n"
94
EOF
95 96 97 98 99 100
        },
        {
                desc            => "label test of max sysfs files (skip invalid rule)",
                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1",
                exp_name        => "boot_disk1" ,
                rules           => <<EOF
Kay Sievers's avatar
Kay Sievers committed
101 102
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"
SUBSYSTEMS=="scsi", ATTRS{vendor}=="ATA", ATTRS{model}=="ST910021AS", ATTRS{scsi_level}=="6", ATTRS{rev}=="4.06", ATTRS{type}=="0", SYMLINK+="boot_disk%n"
103
EOF
104 105 106 107 108 109
        },
        {
                desc            => "catch device by *",
                devpath         => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
                exp_name        => "modem/0" ,
                rules           => <<EOF
Kay Sievers's avatar
Kay Sievers committed
110
KERNEL=="ttyACM*", SYMLINK+="modem/%n"
111
EOF
112 113 114 115 116 117
        },
        {
                desc            => "catch device by * - take 2",
                devpath         => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
                exp_name        => "modem/0" ,
                rules           => <<EOF
Kay Sievers's avatar
Kay Sievers committed
118 119
KERNEL=="*ACM1", SYMLINK+="bad"
KERNEL=="*ACM0", SYMLINK+="modem/%n"
120
EOF
121 122 123 124 125 126
        },
        {
                desc            => "catch device by ?",
                devpath         => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
                exp_name        => "modem/0" ,
                rules           => <<EOF
Kay Sievers's avatar
Kay Sievers committed
127 128 129
KERNEL=="ttyACM??*", SYMLINK+="modem/%n-1"
KERNEL=="ttyACM??", SYMLINK+="modem/%n-2"
KERNEL=="ttyACM?", SYMLINK+="modem/%n"
130
EOF
131 132 133 134 135 136
        },
        {
                desc            => "catch device by character class",
                devpath         => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
                exp_name        => "modem/0" ,
                rules           => <<EOF
Kay Sievers's avatar
Kay Sievers committed
137 138 139
KERNEL=="ttyACM[A-Z]*", SYMLINK+="modem/%n-1"
KERNEL=="ttyACM?[0-9]", SYMLINK+="modem/%n-2"
KERNEL=="ttyACM[0-9]*", SYMLINK+="modem/%n"
140
EOF
141 142 143 144 145 146
        },
        {
                desc            => "replace kernel name",
                devpath         => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
                exp_name        => "modem" ,
                rules           => <<EOF
Kay Sievers's avatar
Kay Sievers committed
147
KERNEL=="ttyACM0", SYMLINK+="modem"
148
EOF
149 150 151 152 153 154
        },
        {
                desc            => "Handle comment lines in config file (and replace kernel name)",
                devpath         => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
                exp_name        => "modem" ,
                rules           => <<EOF
155
# this is a comment
Kay Sievers's avatar
Kay Sievers committed
156
KERNEL=="ttyACM0", SYMLINK+="modem"
157 158

EOF
159 160 161 162 163 164
        },
        {
                desc            => "Handle comment lines in config file with whitespace (and replace kernel name)",
                devpath         => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
                exp_name        => "modem" ,
                rules           => <<EOF
165
 # this is a comment with whitespace before the comment
Kay Sievers's avatar
Kay Sievers committed
166
KERNEL=="ttyACM0", SYMLINK+="modem"
167

168
EOF
169 170 171 172 173 174
        },
        {
                desc            => "Handle whitespace only lines (and replace kernel name)",
                devpath         => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
                exp_name        => "whitespace" ,
                rules           => <<EOF
175 176


177 178

 # this is a comment with whitespace before the comment
Kay Sievers's avatar
Kay Sievers committed
179
KERNEL=="ttyACM0", SYMLINK+="whitespace"
180

181

182

183
EOF
184 185 186 187 188 189
        },
        {
                desc            => "Handle empty lines in config file (and replace kernel name)",
                devpath         => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
                exp_name        => "modem" ,
                rules           => <<EOF
190

Kay Sievers's avatar
Kay Sievers committed
191
KERNEL=="ttyACM0", SYMLINK+="modem"
192

193
EOF
194 195 196 197 198 199
        },
        {
                desc            => "Handle backslashed multi lines in config file (and replace kernel name)",
                devpath         => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
                exp_name        => "modem" ,
                rules           => <<EOF
200
KERNEL=="ttyACM0", \\
Kay Sievers's avatar
Kay Sievers committed
201
SYMLINK+="modem"
202

203
EOF
204 205 206 207 208 209
        },
        {
                desc            => "preserve backslashes, if they are not for a newline",
                devpath         => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
                exp_name        => "aaa",
                rules           => <<EOF
210
KERNEL=="ttyACM0", PROGRAM=="/bin/echo -e \\101", RESULT=="A", SYMLINK+="aaa"
211
EOF
212 213 214 215 216 217
        },
        {
                desc            => "Handle stupid backslashed multi lines in config file (and replace kernel name)",
                devpath         => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
                exp_name        => "modem" ,
                rules           => <<EOF
218 219 220 221

#
\\

222
\\
223 224 225

#\\

226
KERNEL=="ttyACM0", \\
227
        SYMLINK+="modem"
228

229
EOF
230 231 232 233 234 235
        },
        {
                desc            => "subdirectory handling",
                devpath         => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
                exp_name        => "sub/direct/ory/modem" ,
                rules           => <<EOF
Kay Sievers's avatar
Kay Sievers committed
236
KERNEL=="ttyACM0", SYMLINK+="sub/direct/ory/modem"
237
EOF
238 239 240 241 242 243
        },
        {
                desc            => "parent device name match of scsi partition",
                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5",
                exp_name        => "first_disk5" ,
                rules           => <<EOF
Kay Sievers's avatar
Kay Sievers committed
244
SUBSYSTEMS=="scsi", KERNELS=="0:0:0:0", SYMLINK+="first_disk%n"
245
EOF
246 247 248 249 250 251
        },
        {
                desc            => "test substitution chars",
                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5",
                exp_name        => "Major:8:minor:5:kernelnumber:5:id:0:0:0:0" ,
                rules           => <<EOF
Kay Sievers's avatar
Kay Sievers committed
252
SUBSYSTEMS=="scsi", KERNELS=="0:0:0:0", SYMLINK+="Major:%M:minor:%m:kernelnumber:%n:id:%b"
253
EOF
254 255 256 257 258 259
        },
        {
                desc            => "import of shell-value returned from program",
                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
                exp_name        => "node12345678",
                rules           => <<EOF
260
SUBSYSTEMS=="scsi", IMPORT{program}="/bin/echo -e \' TEST_KEY=12345678\\n  TEST_key2=98765\'", SYMLINK+="node\$env{TEST_KEY}"
Kay Sievers's avatar
Kay Sievers committed
261
KERNEL=="ttyACM0", SYMLINK+="modem"
262
EOF
263 264 265 266 267 268
        },
        {
                desc            => "sustitution of sysfs value (%s{file})",
                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
                exp_name        => "disk-ATA-sda" ,
                rules           => <<EOF
Kay Sievers's avatar
Kay Sievers committed
269 270
SUBSYSTEMS=="scsi", ATTRS{vendor}=="ATA", SYMLINK+="disk-%s{vendor}-%k"
KERNEL=="ttyACM0", SYMLINK+="modem"
271
EOF
272 273 274 275 276 277 278
        },
        {
                desc            => "program result substitution",
                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5",
                exp_name        => "special-device-5" ,
                not_exp_name    => "not" ,
                rules           => <<EOF
279 280
SUBSYSTEMS=="scsi", PROGRAM=="/bin/echo -n special-device", RESULT=="-special-*", SYMLINK+="not"
SUBSYSTEMS=="scsi", PROGRAM=="/bin/echo -n special-device", RESULT=="special-*", SYMLINK+="%c-%n"
281
EOF
282 283 284 285 286 287
        },
        {
                desc            => "program result substitution (newline removal)",
                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5",
                exp_name        => "newline_removed" ,
                rules           => <<EOF
288
SUBSYSTEMS=="scsi", PROGRAM=="/bin/echo test", RESULT=="test", SYMLINK+="newline_removed"
289
EOF
290 291 292 293 294 295
        },
        {
                desc            => "program result substitution",
                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5",
                exp_name        => "test-0:0:0:0" ,
                rules           => <<EOF
296
SUBSYSTEMS=="scsi", PROGRAM=="/bin/echo -n test-%b", RESULT=="test-0:0*", SYMLINK+="%c"
297
EOF
298 299 300 301 302 303
        },
        {
                desc            => "program with lots of arguments",
                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5",
                exp_name        => "foo9" ,
                rules           => <<EOF
304
SUBSYSTEMS=="scsi", PROGRAM=="/bin/echo -n foo3 foo4 foo5 foo6 foo7 foo8 foo9", KERNEL=="sda5", SYMLINK+="%c{7}"
305
EOF
306 307 308 309 310 311
        },
        {
                desc            => "program with subshell",
                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5",
                exp_name        => "bar9" ,
                rules           => <<EOF
312
SUBSYSTEMS=="scsi", PROGRAM=="/bin/sh -c 'echo foo3 foo4 foo5 foo6 foo7 foo8 foo9 | sed  s/foo9/bar9/'", KERNEL=="sda5", SYMLINK+="%c{7}"
313
EOF
314 315 316 317 318 319
        },
        {
                desc            => "program arguments combined with apostrophes",
                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5",
                exp_name        => "foo7" ,
                rules           => <<EOF
320
SUBSYSTEMS=="scsi", PROGRAM=="/bin/echo -n 'foo3 foo4'   'foo5   foo6   foo7 foo8'", KERNEL=="sda5", SYMLINK+="%c{5}"
321
EOF
322 323 324 325 326 327
        },
        {
                desc            => "characters before the %c{N} substitution",
                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5",
                exp_name        => "my-foo9" ,
                rules           => <<EOF
328
SUBSYSTEMS=="scsi", PROGRAM=="/bin/echo -n foo3 foo4 foo5 foo6 foo7 foo8 foo9", KERNEL=="sda5", SYMLINK+="my-%c{7}"
329
EOF
330 331 332 333 334 335
        },
        {
                desc            => "substitute the second to last argument",
                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5",
                exp_name        => "my-foo8" ,
                rules           => <<EOF
336
SUBSYSTEMS=="scsi", PROGRAM=="/bin/echo -n foo3 foo4 foo5 foo6 foo7 foo8 foo9", KERNEL=="sda5", SYMLINK+="my-%c{6}"
337
EOF
338 339 340 341 342 343
        },
        {
                desc            => "test substitution by variable name",
                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5",
                exp_name        => "Major:8-minor:5-kernelnumber:5-id:0:0:0:0",
                rules           => <<EOF
Kay Sievers's avatar
Kay Sievers committed
344
SUBSYSTEMS=="scsi", KERNELS=="0:0:0:0", SYMLINK+="Major:\$major-minor:\$minor-kernelnumber:\$number-id:\$id"
345
EOF
346 347 348 349 350 351
        },
        {
                desc            => "test substitution by variable name 2",
                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5",
                exp_name        => "Major:8-minor:5-kernelnumber:5-id:0:0:0:0",
                rules           => <<EOF
Kay Sievers's avatar
Kay Sievers committed
352
SUBSYSTEMS=="scsi", KERNELS=="0:0:0:0", DEVPATH=="*/sda/*", SYMLINK+="Major:\$major-minor:%m-kernelnumber:\$number-id:\$id"
353
EOF
354 355 356 357 358 359
        },
        {
                desc            => "test substitution by variable name 3",
                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5",
                exp_name        => "850:0:0:05" ,
                rules           => <<EOF
Kay Sievers's avatar
Kay Sievers committed
360
SUBSYSTEMS=="scsi", KERNELS=="0:0:0:0", DEVPATH=="*/sda/*", SYMLINK+="%M%m%b%n"
361
EOF
362 363 364 365 366 367
        },
        {
                desc            => "test substitution by variable name 4",
                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5",
                exp_name        => "855" ,
                rules           => <<EOF
Kay Sievers's avatar
Kay Sievers committed
368
SUBSYSTEMS=="scsi", KERNELS=="0:0:0:0", DEVPATH=="*/sda/*", SYMLINK+="\$major\$minor\$number"
369
EOF
370 371 372 373 374 375
        },
        {
                desc            => "test substitution by variable name 5",
                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5",
                exp_name        => "8550:0:0:0" ,
                rules           => <<EOF
Kay Sievers's avatar
Kay Sievers committed
376
SUBSYSTEMS=="scsi", KERNELS=="0:0:0:0", DEVPATH=="*/sda/*", SYMLINK+="\$major%m%n\$id"
377
EOF
378 379 380 381 382 383
        },
        {
                desc            => "non matching SUBSYSTEMS for device with no parent",
                devpath         => "/devices/virtual/tty/console",
                exp_name        => "TTY",
                rules           => <<EOF
384
SUBSYSTEMS=="scsi", PROGRAM=="/bin/echo -n foo", RESULT=="foo", SYMLINK+="foo"
Kay Sievers's avatar
Kay Sievers committed
385
KERNEL=="console", SYMLINK+="TTY"
386
EOF
387 388 389 390 391 392
        },
        {
                desc            => "non matching SUBSYSTEMS",
                devpath         => "/devices/virtual/tty/console",
                exp_name        => "TTY" ,
                rules                => <<EOF
Kay Sievers's avatar
Kay Sievers committed
393 394
SUBSYSTEMS=="foo", ATTRS{dev}=="5:1", SYMLINK+="foo"
KERNEL=="console", SYMLINK+="TTY"
395
EOF
396 397 398 399 400 401
        },
        {
                desc            => "ATTRS match",
                devpath         => "/devices/virtual/tty/console",
                exp_name        => "foo" ,
                rules           => <<EOF
Kay Sievers's avatar
Kay Sievers committed
402 403
KERNEL=="console", SYMLINK+="TTY"
ATTRS{dev}=="5:1", SYMLINK+="foo"
404
EOF
405 406 407 408 409 410
        },
        {
                desc            => "ATTR (empty file)",
                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
                exp_name        => "empty" ,
                rules           => <<EOF
Kay Sievers's avatar
Kay Sievers committed
411 412 413 414
KERNEL=="sda", ATTR{test_empty_file}=="?*", SYMLINK+="something"
KERNEL=="sda", ATTR{test_empty_file}!="", SYMLINK+="not-empty"
KERNEL=="sda", ATTR{test_empty_file}=="", SYMLINK+="empty"
KERNEL=="sda", ATTR{test_empty_file}!="?*", SYMLINK+="not-something"
415
EOF
416 417 418 419 420 421
        },
        {
                desc            => "ATTR (non-existent file)",
                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
                exp_name        => "non-existent" ,
                rules           => <<EOF
Kay Sievers's avatar
Kay Sievers committed
422 423 424 425 426 427
KERNEL=="sda", ATTR{nofile}=="?*", SYMLINK+="something"
KERNEL=="sda", ATTR{nofile}!="", SYMLINK+="not-empty"
KERNEL=="sda", ATTR{nofile}=="", SYMLINK+="empty"
KERNEL=="sda", ATTR{nofile}!="?*", SYMLINK+="not-something"
KERNEL=="sda", TEST!="nofile", SYMLINK+="non-existent"
KERNEL=="sda", SYMLINK+="wrong"
428
EOF
429 430 431 432 433 434
        },
        {
                desc            => "program and bus type match",
                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
                exp_name        => "scsi-0:0:0:0" ,
                rules           => <<EOF
435 436 437
SUBSYSTEMS=="usb", PROGRAM=="/bin/echo -n usb-%b", SYMLINK+="%c"
SUBSYSTEMS=="scsi", PROGRAM=="/bin/echo -n scsi-%b", SYMLINK+="%c"
SUBSYSTEMS=="foo", PROGRAM=="/bin/echo -n foo-%b", SYMLINK+="%c"
438
EOF
439 440 441 442 443 444
        },
        {
                desc            => "sysfs parent hierarchy",
                devpath         => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
                exp_name        => "modem" ,
                rules           => <<EOF
Kay Sievers's avatar
Kay Sievers committed
445
ATTRS{idProduct}=="007b", SYMLINK+="modem"
446
EOF
447 448 449 450 451 452
        },
        {
                desc            => "name test with ! in the name",
                devpath         => "/devices/virtual/block/fake!blockdev0",
                exp_name        => "is/a/fake/blockdev0" ,
                rules           => <<EOF
Kay Sievers's avatar
Kay Sievers committed
453 454 455
SUBSYSTEMS=="scsi", SYMLINK+="is/not/a/%k"
SUBSYSTEM=="block", SYMLINK+="is/a/%k"
KERNEL=="ttyACM0", SYMLINK+="modem"
456
EOF
457 458 459 460 461 462 463
        },
        {
                desc            => "name test with ! in the name, but no matching rule",
                devpath         => "/devices/virtual/block/fake!blockdev0",
                exp_name        => "fake/blockdev0" ,
                exp_rem_error   => "yes",
                rules           => <<EOF
Kay Sievers's avatar
Kay Sievers committed
464
KERNEL=="ttyACM0", SYMLINK+="modem"
465
EOF
466 467 468 469 470 471
        },
        {
                desc            => "KERNELS rule",
                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
                exp_name        => "scsi-0:0:0:0",
                rules           => <<EOF
Kay Sievers's avatar
Kay Sievers committed
472 473 474 475 476
SUBSYSTEMS=="usb", KERNELS=="0:0:0:0", SYMLINK+="not-scsi"
SUBSYSTEMS=="scsi", KERNELS=="0:0:0:1", SYMLINK+="no-match"
SUBSYSTEMS=="scsi", KERNELS==":0", SYMLINK+="short-id"
SUBSYSTEMS=="scsi", KERNELS=="/0:0:0:0", SYMLINK+="no-match"
SUBSYSTEMS=="scsi", KERNELS=="0:0:0:0", SYMLINK+="scsi-0:0:0:0"
477
EOF
478 479 480 481 482 483
        },
        {
                desc            => "KERNELS wildcard all",
                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
                exp_name        => "scsi-0:0:0:0",
                rules           => <<EOF
Kay Sievers's avatar
Kay Sievers committed
484 485 486 487 488
SUBSYSTEMS=="scsi", KERNELS=="*:1", SYMLINK+="no-match"
SUBSYSTEMS=="scsi", KERNELS=="*:0:1", SYMLINK+="no-match"
SUBSYSTEMS=="scsi", KERNELS=="*:0:0:1", SYMLINK+="no-match"
SUBSYSTEMS=="scsi", KERNEL=="0:0:0:0", SYMLINK+="before"
SUBSYSTEMS=="scsi", KERNELS=="*", SYMLINK+="scsi-0:0:0:0"
489
EOF
490 491 492 493 494 495
        },
        {
                desc            => "KERNELS wildcard partial",
                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
                exp_name        => "scsi-0:0:0:0",
                rules           => <<EOF
Kay Sievers's avatar
Kay Sievers committed
496 497
SUBSYSTEMS=="scsi", KERNELS=="0:0:0:0", SYMLINK+="before"
SUBSYSTEMS=="scsi", KERNELS=="*:0", SYMLINK+="scsi-0:0:0:0"
498
EOF
499 500 501 502 503 504
        },
        {
                desc            => "KERNELS wildcard partial 2",
                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
                exp_name        => "scsi-0:0:0:0",
                rules                => <<EOF
Kay Sievers's avatar
Kay Sievers committed
505 506
SUBSYSTEMS=="scsi", KERNELS=="0:0:0:0", SYMLINK+="before"
SUBSYSTEMS=="scsi", KERNELS=="*:0:0:0", SYMLINK+="scsi-0:0:0:0"
507
EOF
508 509 510 511 512 513
        },
        {
                desc            => "substitute attr with link target value (first match)",
                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
                exp_name        => "driver-is-sd",
                rules           => <<EOF
Kay Sievers's avatar
Kay Sievers committed
514
SUBSYSTEMS=="scsi", SYMLINK+="driver-is-\$attr{driver}"
515
EOF
516 517 518 519 520 521
        },
        {
                desc            => "substitute attr with link target value (currently selected device)",
                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
                exp_name        => "driver-is-ahci",
                rules           => <<EOF
Kay Sievers's avatar
Kay Sievers committed
522
SUBSYSTEMS=="pci", SYMLINK+="driver-is-\$attr{driver}"
523
EOF
524 525 526 527 528 529
        },
        {
                desc            => "ignore ATTRS attribute whitespace",
                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
                exp_name        => "ignored",
                rules           => <<EOF
Kay Sievers's avatar
Kay Sievers committed
530
SUBSYSTEMS=="scsi", ATTRS{whitespace_test}=="WHITE  SPACE", SYMLINK+="ignored"
531
EOF
532 533 534 535 536 537
        },
        {
                desc            => "do not ignore ATTRS attribute whitespace",
                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
                exp_name        => "matched-with-space",
                rules           => <<EOF
Kay Sievers's avatar
Kay Sievers committed
538 539
SUBSYSTEMS=="scsi", ATTRS{whitespace_test}=="WHITE  SPACE ", SYMLINK+="wrong-to-ignore"
SUBSYSTEMS=="scsi", ATTRS{whitespace_test}=="WHITE  SPACE   ", SYMLINK+="matched-with-space"
540
EOF
541 542 543 544 545 546 547
        },
        {
                desc            => "permissions USER=bad GROUP=name",
                devpath         => "/devices/virtual/tty/tty33",
                exp_name        => "tty33",
                exp_perms       => "0:0:0600",
                rules           => <<EOF
548
KERNEL=="tty33", OWNER="bad", GROUP="name"
549
EOF
550 551 552 553 554 555 556
        },
        {
                desc            => "permissions OWNER=5000",
                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
                exp_name        => "node",
                exp_perms       => "5000::0600",
                rules           => <<EOF
Kay Sievers's avatar
Kay Sievers committed
557
SUBSYSTEMS=="scsi", KERNEL=="sda", SYMLINK+="node", OWNER="5000"
558
EOF
559 560 561 562 563 564 565
        },
        {
                desc            => "permissions GROUP=100",
                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
                exp_name        => "node",
                exp_perms       => ":100:0660",
                rules           => <<EOF
Kay Sievers's avatar
Kay Sievers committed
566
SUBSYSTEMS=="scsi", KERNEL=="sda", SYMLINK+="node", GROUP="100"
567
EOF
568 569 570 571 572 573 574
        },
        {
                desc            => "textual user id",
                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
                exp_name        => "node",
                exp_perms       => "nobody::0600",
                rules           => <<EOF
Kay Sievers's avatar
Kay Sievers committed
575
SUBSYSTEMS=="scsi", KERNEL=="sda", SYMLINK+="node", OWNER="nobody"
576
EOF
577 578 579 580 581 582 583
        },
        {
                desc            => "textual group id",
                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
                exp_name        => "node",
                exp_perms       => ":daemon:0660",
                rules           => <<EOF
Kay Sievers's avatar
Kay Sievers committed
584
SUBSYSTEMS=="scsi", KERNEL=="sda", SYMLINK+="node", GROUP="daemon"
585
EOF
586 587 588 589 590 591 592
        },
        {
                desc            => "textual user/group id",
                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
                exp_name        => "node",
                exp_perms       => "root:mail:0660",
                rules           => <<EOF
Kay Sievers's avatar
Kay Sievers committed
593
SUBSYSTEMS=="scsi", KERNEL=="sda", SYMLINK+="node", OWNER="root", GROUP="mail"
594
EOF
595 596 597 598 599 600 601
        },
        {
                desc            => "permissions MODE=0777",
                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
                exp_name        => "node",
                exp_perms       => "::0777",
                rules           => <<EOF
Kay Sievers's avatar
Kay Sievers committed
602
SUBSYSTEMS=="scsi", KERNEL=="sda", SYMLINK+="node", MODE="0777"
603
EOF
604 605 606 607 608 609 610
        },
        {
                desc            => "permissions OWNER=5000 GROUP=100 MODE=0777",
                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
                exp_name        => "node",
                exp_perms       => "5000:100:0777",
                rules           => <<EOF
Kay Sievers's avatar
Kay Sievers committed
611
SUBSYSTEMS=="scsi", KERNEL=="sda", SYMLINK+="node", OWNER="5000", GROUP="100", MODE="0777"
612
EOF
613 614 615 616 617 618 619
        },
        {
                desc            => "permissions OWNER to 5000",
                devpath         => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
                exp_name        => "ttyACM0",
                exp_perms       => "5000::",
                rules           => <<EOF
Kay Sievers's avatar
Kay Sievers committed
620
KERNEL=="ttyACM[0-9]*", SYMLINK+="ttyACM%n", OWNER="5000"
621
EOF
622 623 624 625 626 627 628
        },
        {
                desc            => "permissions GROUP to 100",
                devpath         => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
                exp_name        => "ttyACM0",
                exp_perms       => ":100:0660",
                rules           => <<EOF
Kay Sievers's avatar
Kay Sievers committed
629
KERNEL=="ttyACM[0-9]*", SYMLINK+="ttyACM%n", GROUP="100"
630
EOF
631 632 633 634 635 636 637
        },
        {
                desc            => "permissions MODE to 0060",
                devpath         => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
                exp_name        => "ttyACM0",
                exp_perms       => "::0060",
                rules           => <<EOF
Kay Sievers's avatar
Kay Sievers committed
638
KERNEL=="ttyACM[0-9]*", SYMLINK+="ttyACM%n", MODE="0060"
639
EOF
640 641 642 643 644 645 646
        },
        {
                desc            => "permissions OWNER, GROUP, MODE",
                devpath         => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
                exp_name        => "ttyACM0",
                exp_perms       => "5000:100:0777",
                rules           => <<EOF
Kay Sievers's avatar
Kay Sievers committed
647
KERNEL=="ttyACM[0-9]*", SYMLINK+="ttyACM%n", OWNER="5000", GROUP="100", MODE="0777"
648
EOF
649 650 651 652 653 654 655
        },
        {
                desc            => "permissions only rule",
                devpath         => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
                exp_name        => "ttyACM0",
                exp_perms       => "5000:100:0777",
                rules           => <<EOF
656
KERNEL=="ttyACM[0-9]*", OWNER="5000", GROUP="100", MODE="0777"
657
KERNEL=="ttyUSX[0-9]*", OWNER="5001", GROUP="101", MODE="0444"
Kay Sievers's avatar
Kay Sievers committed
658
KERNEL=="ttyACM[0-9]*", SYMLINK+="ttyACM%n"
659
EOF
660 661 662 663 664 665 666
        },
        {
                desc            => "multiple permissions only rule",
                devpath         => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
                exp_name        => "ttyACM0",
                exp_perms       => "3000:4000:0777",
                rules           => <<EOF
667 668 669 670
SUBSYSTEM=="tty", OWNER="3000"
SUBSYSTEM=="tty", GROUP="4000"
SUBSYSTEM=="tty", MODE="0777"
KERNEL=="ttyUSX[0-9]*", OWNER="5001", GROUP="101", MODE="0444"
Kay Sievers's avatar
Kay Sievers committed
671
KERNEL=="ttyACM[0-9]*", SYMLINK+="ttyACM%n"
672
EOF
673 674 675 676 677 678 679
        },
        {
                desc            => "permissions only rule with override at SYMLINK+ rule",
                devpath         => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
                exp_name        => "ttyACM0",
                exp_perms       => "3000:8000:0777",
                rules           => <<EOF
680 681 682 683
SUBSYSTEM=="tty", OWNER="3000"
SUBSYSTEM=="tty", GROUP="4000"
SUBSYSTEM=="tty", MODE="0777"
KERNEL=="ttyUSX[0-9]*", OWNER="5001", GROUP="101", MODE="0444"
Kay Sievers's avatar
Kay Sievers committed
684
KERNEL=="ttyACM[0-9]*", SYMLINK+="ttyACM%n", GROUP="8000"
685
EOF
686 687 688 689 690 691 692
        },
        {
                desc            => "major/minor number test",
                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
                exp_name        => "node",
                exp_majorminor  => "8:0",
                rules           => <<EOF
Kay Sievers's avatar
Kay Sievers committed
693
SUBSYSTEMS=="scsi", KERNEL=="sda", SYMLINK+="node"
694
EOF
695 696 697 698 699 700 701
        },
        {
                desc            => "big major number test",
                devpath         => "/devices/virtual/misc/misc-fake1",
                exp_name        => "node",
                exp_majorminor  => "4095:1",
                rules                => <<EOF
Kay Sievers's avatar
Kay Sievers committed
702
KERNEL=="misc-fake1", SYMLINK+="node"
703
EOF
704 705 706 707 708 709 710
        },
        {
                desc            => "big major and big minor number test",
                devpath         => "/devices/virtual/misc/misc-fake89999",
                exp_name        => "node",
                exp_majorminor  => "4095:89999",
                rules           => <<EOF
Kay Sievers's avatar
Kay Sievers committed
711
KERNEL=="misc-fake89999", SYMLINK+="node"
712
EOF
713 714 715 716 717 718
        },
        {
                desc            => "multiple symlinks with format char",
                devpath         => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
                exp_name        => "symlink2-ttyACM0",
                rules           => <<EOF
Kay Sievers's avatar
Kay Sievers committed
719
KERNEL=="ttyACM[0-9]*", SYMLINK="symlink1-%n symlink2-%k symlink3-%b"
720
EOF
721 722 723 724 725 726 727
        },
        {
                desc            => "multiple symlinks with a lot of s p a c e s",
                devpath         => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
                exp_name        => "one",
                not_exp_name        => " ",
                rules           => <<EOF
Kay Sievers's avatar
Kay Sievers committed
728
KERNEL=="ttyACM[0-9]*", SYMLINK="  one     two        "
729
EOF
730 731 732 733 734 735
        },
        {
                desc            => "symlink creation (same directory)",
                devpath         => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
                exp_name        => "modem0",
                rules           => <<EOF
Kay Sievers's avatar
Kay Sievers committed
736
KERNEL=="ttyACM[0-9]*", SYMLINK+="ttyACM%n", SYMLINK="modem%n"
737
EOF
738 739 740 741 742 743
        },
        {
                desc            => "multiple symlinks",
                devpath         => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
                exp_name        => "second-0" ,
                rules           => <<EOF
Kay Sievers's avatar
Kay Sievers committed
744
KERNEL=="ttyACM0", SYMLINK="first-%n second-%n third-%n"
745
EOF
746 747 748 749 750 751 752 753
        },
        {
                desc            => "symlink name '.'",
                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
                exp_name        => ".",
                exp_add_error        => "yes",
                exp_rem_error        => "yes",
                rules           => <<EOF
Kay Sievers's avatar
Kay Sievers committed
754
SUBSYSTEMS=="scsi", KERNEL=="sda", SYMLINK+="."
755
EOF
756 757 758 759 760 761 762 763 764
        },
        {
                desc            => "symlink node to itself",
                devpath         => "/devices/virtual/tty/tty0",
                exp_name        => "link",
                exp_add_error        => "yes",
                exp_rem_error        => "yes",
                option                => "clean",
                rules           => <<EOF
Kay Sievers's avatar
Kay Sievers committed
765
KERNEL=="tty0", SYMLINK+="tty0"
766
EOF
767 768 769 770 771 772
        },
        {
                desc            => "symlink %n substitution",
                devpath         => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
                exp_name        => "symlink0",
                rules           => <<EOF
Kay Sievers's avatar
Kay Sievers committed
773
KERNEL=="ttyACM[0-9]*", SYMLINK+="ttyACM%n", SYMLINK+="symlink%n"
774
EOF
775 776 777 778 779 780
        },
        {
                desc            => "symlink %k substitution",
                devpath         => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
                exp_name        => "symlink-ttyACM0",
                rules           => <<EOF
Kay Sievers's avatar
Kay Sievers committed
781
KERNEL=="ttyACM[0-9]*", SYMLINK+="ttyACM%n", SYMLINK+="symlink-%k"
782
EOF
783 784 785 786 787 788
        },
        {
                desc            => "symlink %M:%m substitution",
                devpath         => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
                exp_name        => "major-166:0",
                rules           => <<EOF
Kay Sievers's avatar
Kay Sievers committed
789
KERNEL=="ttyACM[0-9]*", SYMLINK+="ttyACM%n", SYMLINK+="major-%M:%m"
790
EOF
791 792 793 794 795 796
        },
        {
                desc            => "symlink %b substitution",
                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
                exp_name        => "symlink-0:0:0:0",
                rules           => <<EOF
797
SUBSYSTEMS=="scsi", KERNEL=="sda", SYMLINK+="symlink-%b"
798
EOF
799 800 801 802 803 804
        },
        {
                desc            => "symlink %c substitution",
                devpath         => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
                exp_name        => "test",
                rules           => <<EOF
805
KERNEL=="ttyACM[0-9]*", PROGRAM=="/bin/echo test", SYMLINK+="%c"
806
EOF
807 808 809 810 811 812
        },
        {
                desc            => "symlink %c{N} substitution",
                devpath         => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
                exp_name        => "test",
                rules           => <<EOF
813
KERNEL=="ttyACM[0-9]*", PROGRAM=="/bin/echo symlink test this", SYMLINK+="%c{2}"
814
EOF
815 816 817 818 819 820
        },
        {
                desc            => "symlink %c{N+} substitution",
                devpath         => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
                exp_name        => "this",
                rules           => <<EOF
821
KERNEL=="ttyACM[0-9]*", PROGRAM=="/bin/echo symlink test this", SYMLINK+="%c{2+}"
822
EOF
823 824 825 826 827 828
        },
        {
                desc            => "symlink only rule with %c{N+}",
                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
                exp_name        => "test",
                rules           => <<EOF
829
SUBSYSTEMS=="scsi", KERNEL=="sda", PROGRAM=="/bin/echo link test this" SYMLINK+="%c{2+}"
830
EOF
831 832 833 834 835 836
        },
        {
                desc            => "symlink %s{filename} substitution",
                devpath         => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
                exp_name        => "166:0",
                rules           => <<EOF
Kay Sievers's avatar
Kay Sievers committed
837
KERNEL=="ttyACM[0-9]*", SYMLINK+="%s{dev}"
838
EOF
839 840 841 842 843 844
        },
        {
                desc            => "program result substitution (numbered part of)",
                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5",
                exp_name        => "link1",
                rules           => <<EOF
845
SUBSYSTEMS=="scsi", PROGRAM=="/bin/echo -n node link1 link2", RESULT=="node *", SYMLINK+="%c{2} %c{3}"
846
EOF
847 848 849 850 851 852
        },
        {
                desc            => "program result substitution (numbered part of+)",
                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5",
                exp_name        => "link4",
                rules           => <<EOF
853
SUBSYSTEMS=="scsi", PROGRAM=="/bin/echo -n node link1 link2 link3 link4", RESULT=="node *", SYMLINK+="%c{2+}"
854
EOF
855 856 857 858 859 860
        },
        {
                desc            => "SUBSYSTEM match test",
                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
                exp_name        => "node",
                rules           => <<EOF
Kay Sievers's avatar
Kay Sievers committed
861 862 863
SUBSYSTEMS=="scsi", KERNEL=="sda", SYMLINK+="should_not_match", SUBSYSTEM=="vc"
SUBSYSTEMS=="scsi", KERNEL=="sda", SYMLINK+="node", SUBSYSTEM=="block"
SUBSYSTEMS=="scsi", KERNEL=="sda", SYMLINK+="should_not_match2", SUBSYSTEM=="vc"
864
EOF
865 866 867 868 869 870
        },
        {
                desc            => "DRIVERS match test",
                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
                exp_name        => "node",
                rules           => <<EOF
Kay Sievers's avatar
Kay Sievers committed
871 872
SUBSYSTEMS=="scsi", KERNEL=="sda", SYMLINK+="should_not_match", DRIVERS=="sd-wrong"
SUBSYSTEMS=="scsi", KERNEL=="sda", SYMLINK+="node", DRIVERS=="sd"
873
EOF
874 875 876 877 878 879
        },
        {
                desc            => "devnode substitution test",
                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
                exp_name        => "node",
                rules           => <<EOF
880
SUBSYSTEMS=="scsi", KERNEL=="sda", PROGRAM=="/usr/bin/test -b %N" SYMLINK+="node"
881
EOF
882 883 884 885 886 887
        },
        {
                desc            => "parent node name substitution test",
                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1",
                exp_name        => "sda-part-1",
                rules           => <<EOF
Kay Sievers's avatar
Kay Sievers committed
888
SUBSYSTEMS=="scsi", KERNEL=="sda1", SYMLINK+="%P-part-1"
889
EOF
890 891 892 893
        },
        {
                desc            => "udev_root substitution",
                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1",
894
                exp_name        => "start-test/dev-end",
895
                rules           => <<EOF
Kay Sievers's avatar
Kay Sievers committed
896
SUBSYSTEMS=="scsi", KERNEL=="sda1", SYMLINK+="start-%r-end"
897
EOF
898 899 900 901 902 903
        },
        {
                desc            => "last_rule option",
                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1",
                exp_name        => "last",
                rules           => <<EOF
904
SUBSYSTEMS=="scsi", KERNEL=="sda1", SYMLINK+="last", OPTIONS="last_rule"
Kay Sievers's avatar
Kay Sievers committed
905
SUBSYSTEMS=="scsi", KERNEL=="sda1", SYMLINK+="very-last"
906
EOF
907 908 909 910 911 912
        },
        {
                desc            => "negation KERNEL!=",
                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1",
                exp_name        => "match",
                rules           => <<EOF
Kay Sievers's avatar
Kay Sievers committed
913 914 915
SUBSYSTEMS=="scsi", KERNEL!="sda1", SYMLINK+="matches-but-is-negated"
SUBSYSTEMS=="scsi", KERNEL=="sda1", SYMLINK+="before"
SUBSYSTEMS=="scsi", KERNEL!="xsda1", SYMLINK+="match"
916
EOF
917 918 919 920 921 922
        },
        {
                desc            => "negation SUBSYSTEM!=",
                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1",
                exp_name        => "not-anything",
                rules           => <<EOF
Kay Sievers's avatar
Kay Sievers committed
923 924 925
SUBSYSTEMS=="scsi", SUBSYSTEM=="block", KERNEL!="sda1", SYMLINK+="matches-but-is-negated"
SUBSYSTEMS=="scsi", KERNEL=="sda1", SYMLINK+="before"
SUBSYSTEMS=="scsi", SUBSYSTEM!="anything", SYMLINK+="not-anything"
926
EOF
927 928 929 930 931 932
        },
        {
                desc            => "negation PROGRAM!= exit code",
                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1",
                exp_name        => "nonzero-program",
                rules           => <<EOF
Kay Sievers's avatar
Kay Sievers committed
933
SUBSYSTEMS=="scsi", KERNEL=="sda1", SYMLINK+="before"
934
KERNEL=="sda1", PROGRAM!="/bin/false", SYMLINK+="nonzero-program"
935
EOF
936 937 938 939 940 941
        },
        {
                desc            => "test for whitespace between the operator",
                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1",
                exp_name        => "true",
                rules           => <<EOF
Kay Sievers's avatar
Kay Sievers committed
942 943
SUBSYSTEMS=="scsi", KERNEL=="sda1", SYMLINK+="before"
KERNEL   ==   "sda1"     ,    SYMLINK+   =    "true"
944
EOF
945 946 947 948 949 950
        },
        {
                desc            => "ENV{} test",
                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1",
                exp_name        => "true",
                rules           => <<EOF
951
ENV{ENV_KEY_TEST}="test"
Kay Sievers's avatar
Kay Sievers committed
952 953 954
SUBSYSTEMS=="scsi", KERNEL=="sda1", ENV{ENV_KEY_TEST}=="go", SYMLINK+="wrong"
SUBSYSTEMS=="scsi", KERNEL=="sda1", ENV{ENV_KEY_TEST}=="test", SYMLINK+="true"
SUBSYSTEMS=="scsi", KERNEL=="sda1", ENV{ENV_KEY_TEST}=="bad", SYMLINK+="bad"
955
EOF
956 957 958 959 960 961
        },
        {
                desc            => "ENV{} test",
                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1",
                exp_name        => "true",
                rules           => <<EOF
962
ENV{ENV_KEY_TEST}="test"
Kay Sievers's avatar
Kay Sievers committed
963 964 965 966
SUBSYSTEMS=="scsi", KERNEL=="sda1", ENV{ENV_KEY_TEST}=="go", SYMLINK+="wrong"
SUBSYSTEMS=="scsi", KERNEL=="sda1", ENV{ENV_KEY_TEST}=="yes", ENV{ACTION}=="add", ENV{DEVPATH}=="*/block/sda/sdax1", SYMLINK+="no"
SUBSYSTEMS=="scsi", KERNEL=="sda1", ENV{ENV_KEY_TEST}=="test", ENV{ACTION}=="add", ENV{DEVPATH}=="*/block/sda/sda1", SYMLINK+="true"
SUBSYSTEMS=="scsi", KERNEL=="sda1", ENV{ENV_KEY_TEST}=="bad", SYMLINK+="bad"
967
EOF
968 969 970 971 972 973
        },
        {
                desc            => "ENV{} test (assign)",
                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1",
                exp_name        => "true",
                rules           => <<EOF
974
SUBSYSTEMS=="scsi", KERNEL=="sda1", ENV{ASSIGN}="true"
Kay Sievers's avatar
Kay Sievers committed
975 976 977
SUBSYSTEMS=="scsi", KERNEL=="sda1", ENV{ASSIGN}=="yes", SYMLINK+="no"
SUBSYSTEMS=="scsi", KERNEL=="sda1", SYMLINK+="before"
SUBSYSTEMS=="scsi", KERNEL=="sda1", ENV{ASSIGN}=="true", SYMLINK+="true"
978
EOF
979 980 981 982 983 984
        },
        {
                desc            => "ENV{} test (assign 2 times)",
                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1",
                exp_name        => "true",
                rules           => <<EOF
985 986
SUBSYSTEMS=="scsi", KERNEL=="sda1", ENV{ASSIGN}="true"
SUBSYSTEMS=="scsi", KERNEL=="sda1", ENV{ASSIGN}="absolutely-\$env{ASSIGN}"
Kay Sievers's avatar
Kay Sievers committed
987 988 989
SUBSYSTEMS=="scsi", KERNEL=="sda1", SYMLINK+="before"
SUBSYSTEMS=="scsi", KERNEL=="sda1", ENV{ASSIGN}=="yes", SYMLINK+="no"
SUBSYSTEMS=="scsi", KERNEL=="sda1", ENV{ASSIGN}=="absolutely-true", SYMLINK+="true"
990
EOF
991 992 993 994 995 996
        },
        {
                desc            => "ENV{} test (assign2)",
                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1",
                exp_name        => "part",
                rules           => <<EOF
997 998
SUBSYSTEM=="block", KERNEL=="*[0-9]", ENV{PARTITION}="true", ENV{MAINDEVICE}="false"
SUBSYSTEM=="block", KERNEL=="*[!0-9]", ENV{PARTITION}="false", ENV{MAINDEVICE}="true"
Kay Sievers's avatar
Kay Sievers committed
999 1000 1001
ENV{MAINDEVICE}=="true", SYMLINK+="disk"
SUBSYSTEM=="block", SYMLINK+="before"
ENV{PARTITION}=="true", SYMLINK+="part"
1002
EOF
1003 1004 1005 1006 1007 1008
        },
        {
                desc            => "untrusted string sanitize",
                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1",
                exp_name        => "sane",
                rules           => <<EOF
1009
SUBSYSTEMS=="scsi", KERNEL=="sda1", PROGRAM=="/bin/echo -e name; (/usr/bin/badprogram)", RESULT=="name_ _/usr/bin/badprogram_", SYMLINK+="sane"
1010
EOF
1011 1012 1013 1014 1015 1016
        },
        {
                desc            => "untrusted string sanitize (don't replace utf8)",
                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1",
                exp_name        => "uber",
                rules           => <<EOF
1017
SUBSYSTEMS=="scsi", KERNEL=="sda1", PROGRAM=="/bin/echo -e \\xc3\\xbcber" RESULT=="\xc3\xbcber", SYMLINK+="uber"
1018
EOF
1019 1020 1021 1022 1023 1024
        },
        {
                desc            => "untrusted string sanitize (replace invalid utf8)",
                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1",
                exp_name        => "replaced",
                rules           => <<EOF
1025
SUBSYSTEMS=="scsi", KERNEL=="sda1", PROGRAM=="/bin/echo -e \\xef\\xe8garbage", RESULT=="__garbage", SYMLINK+="replaced"
1026
EOF
1027 1028 1029 1030 1031 1032
        },
        {
                desc            => "read sysfs value from parent device",
                devpath         => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
                exp_name        => "serial-354172020305000",
                rules           => <<EOF
Kay Sievers's avatar
Kay Sievers committed
1033
KERNEL=="ttyACM*", ATTRS{serial}=="?*", SYMLINK+="serial-%s{serial}"
1034
EOF
1035 1036 1037 1038 1039 1040
        },
        {
                desc            => "match against empty key string",
                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
                exp_name        => "ok",
                rules           => <<EOF
Kay Sievers's avatar
Kay Sievers committed
1041 1042 1043 1044
KERNEL=="sda", ATTRS{nothing}!="", SYMLINK+="not-1-ok"
KERNEL=="sda", ATTRS{nothing}=="", SYMLINK+="not-2-ok"
KERNEL=="sda", ATTRS{vendor}!="", SYMLINK+="ok"
KERNEL=="sda", ATTRS{vendor}=="", SYMLINK+="not-3-ok"
1045
EOF
1046 1047 1048 1049 1050 1051
        },
        {
                desc            => "check ACTION value",
                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
                exp_name        => "ok",
                rules           => <<EOF
Kay Sievers's avatar
Kay Sievers committed
1052 1053
ACTION=="unknown", KERNEL=="sda", SYMLINK+="unknown-not-ok"
ACTION=="add", KERNEL=="sda", SYMLINK+="ok"
1054
EOF
1055 1056 1057 1058 1059 1060 1061
        },
        {
                desc            => "final assignment",
                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
                exp_name        => "ok",
                exp_perms       => "root:tty:0640",
                rules           => <<EOF
1062
KERNEL=="sda", GROUP:="tty"
Kay Sievers's avatar
Kay Sievers committed
1063
KERNEL=="sda", GROUP="not-ok", MODE="0640", SYMLINK+="ok"
1064
EOF
1065 1066 1067 1068 1069 1070 1071
        },
        {
                desc            => "final assignment 2",
                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
                exp_name        => "ok",
                exp_perms       => "root:tty:0640",
                rules           => <<EOF
1072
KERNEL=="sda", GROUP:="tty"
1073
SUBSYSTEM=="block", MODE:="640"
Kay Sievers's avatar
Kay Sievers committed
1074
KERNEL=="sda", GROUP="not-ok", MODE="0666", SYMLINK+="ok"
1075
EOF
1076 1077 1078 1079 1080 1081
        },
        {
                desc            => "env substitution",
                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
                exp_name        => "node-add-me",
                rules           => <<EOF
Kay Sievers's avatar
Kay Sievers committed
1082
KERNEL=="sda", MODE="0666", SYMLINK+="node-\$env{ACTION}-me"
1083
EOF
1084 1085 1086 1087 1088 1089 1090
        },
        {
                desc            => "reset list to current value",
                devpath         => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
                exp_name        => "three",
                not_exp_name    => "two",
                rules           => <<EOF
1091 1092 1093
KERNEL=="ttyACM[0-9]*", SYMLINK+="one"
KERNEL=="ttyACM[0-9]*", SYMLINK+="two"
KERNEL=="ttyACM[0-9]*", SYMLINK="three"
Kay Sievers's avatar
Kay Sievers committed
1094
EOF
1095 1096 1097 1098 1099 1100 1101
        },
        {
                desc            => "test empty SYMLINK+ (empty override)",
                devpath         => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
                exp_name        => "right",
                not_exp_name    => "wrong",
                rules           => <<EOF
Kay Sievers's avatar
Kay Sievers committed
1102 1103 1104
KERNEL=="ttyACM[0-9]*", SYMLINK+="wrong"
KERNEL=="ttyACM[0-9]*", SYMLINK=""
KERNEL=="ttyACM[0-9]*", SYMLINK+="right"
1105
EOF
1106 1107 1108 1109 1110 1111
        },
        {
                desc            => "test multi matches",
                devpath         => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
                exp_name        => "right",
                rules           => <<EOF
Kay Sievers's avatar
Kay Sievers committed
1112 1113
KERNEL=="ttyACM*", SYMLINK+="before"
KERNEL=="ttyACM*|nothing", SYMLINK+="right"
1114
EOF
1115 1116 1117 1118 1119 1120
        },
        {
                desc            => "test multi matches 2",
                devpath         => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
                exp_name        => "right",
                rules           => <<EOF
Kay Sievers's avatar
Kay Sievers committed
1121 1122 1123
KERNEL=="dontknow*|*nothing", SYMLINK+="nomatch"
KERNEL=="ttyACM*", SYMLINK+="before"
KERNEL=="dontknow*|ttyACM*|nothing*", SYMLINK+="right"
1124
EOF
1125 1126 1127 1128 1129 1130
        },
        {
                desc            => "test multi matches 3",
                devpath         => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
                exp_name        => "right",
                rules           => <<EOF
Kay Sievers's avatar
Kay Sievers committed
1131 1132 1133 1134
KERNEL=="dontknow|nothing", SYMLINK+="nomatch"
KERNEL=="dontknow|ttyACM0a|nothing|attyACM0", SYMLINK+="wrong1"
KERNEL=="X|attyACM0|dontknow|ttyACM0a|nothing|attyACM0", SYMLINK+="wrong2"
KERNEL=="dontknow|ttyACM0|nothing", SYMLINK+="right"
1135
EOF
1136 1137 1138 1139 1140 1141
        },
        {
                desc            => "test multi matches 4",
                devpath         => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
                exp_name        => "right",
                rules           => <<EOF
Kay Sievers's avatar
Kay Sievers committed
1142 1143 1144 1145 1146
KERNEL=="dontknow|nothing", SYMLINK+="nomatch"
KERNEL=="dontknow|ttyACM0a|nothing|attyACM0", SYMLINK+="wrong1"
KERNEL=="X|attyACM0|dontknow|ttyACM0a|nothing|attyACM0", SYMLINK+="wrong2"
KERNEL=="all|dontknow|ttyACM0", SYMLINK+="right"
KERNEL=="ttyACM0a|nothing", SYMLINK+="wrong3"
1147
EOF
1148 1149 1150 1151 1152 1153 1154
        },
        {
                desc            => "IMPORT parent test sequence 1/2 (keep)",
                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
                exp_name        => "parent",
                option          => "keep",
                rules           => <<EOF
1155
KERNEL=="sda", IMPORT{program}="/bin/echo -e \'PARENT_KEY=parent_right\\nWRONG_PARENT_KEY=parent_wrong'"
Kay Sievers's avatar
Kay Sievers committed
1156
KERNEL=="sda", SYMLINK+="parent"
1157
EOF
1158 1159 1160 1161 1162 1163 1164
        },
        {
                desc            => "IMPORT parent test sequence 2/2 (keep)",
                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1",
                exp_name        => "parentenv-parent_right",
                option          => "clean",
                rules           => <<EOF
Kay Sievers's avatar
Kay Sievers committed
1165
KERNEL=="sda1", IMPORT{parent}="PARENT*", SYMLINK+="parentenv-\$env{PARENT_KEY}\$env{WRONG_PARENT_KEY}"
1166
EOF
1167 1168 1169 1170 1171 1172
        },
        {
                desc            => "GOTO test",
                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1",
                exp_name        => "right",
                rules           => <<EOF
1173
KERNEL=="sda1", GOTO="TEST"
Kay Sievers's avatar
Kay Sievers committed
1174
KERNEL=="sda1", SYMLINK+="wrong"
1175
KERNEL=="sda1", GOTO="BAD"
Kay Sievers's avatar
Kay Sievers committed
1176 1177 1178
KERNEL=="sda1", SYMLINK+="", LABEL="NO"
KERNEL=="sda1", SYMLINK+="right", LABEL="TEST", GOTO="end"
KERNEL=="sda1", SYMLINK+="wrong2", LABEL="BAD"
1179
LABEL="end"
1180
EOF
1181 1182 1183 1184 1185 1186
        },
        {
                desc            => "GOTO label does not exist",
                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1",
                exp_name        => "right",
                rules           => <<EOF
1187
KERNEL=="sda1", GOTO="does-not-exist"
Kay Sievers's avatar
Kay Sievers committed
1188
KERNEL=="sda1", SYMLINK+="right",
1189
LABEL="exists"
1190
EOF
1191 1192 1193 1194 1195 1196 1197
        },
        {
                desc            => "SYMLINK+ compare test",
                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1",
                exp_name        => "right",
                not_exp_name    => "wrong",
                rules           => <<EOF
Kay Sievers's avatar
Kay Sievers committed
1198 1199 1200
KERNEL=="sda1", SYMLINK+="link"
KERNEL=="sda1", SYMLINK=="link*", SYMLINK+="right"
KERNEL=="sda1", SYMLINK=="nolink*", SYMLINK+="wrong"
1201
EOF
1202 1203 1204 1205 1206 1207
        },
        {
                desc            => "invalid key operation",
                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1",
                exp_name        => "yes",
                rules           => <<EOF
Kay Sievers's avatar
Kay Sievers committed
1208 1209
KERNEL="sda1", SYMLINK+="no"
KERNEL=="sda1", SYMLINK+="yes"
1210
EOF
1211 1212 1213 1214 1215 1216
        },
        {
                desc            => "operator chars in attribute",
                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
                exp_name        => "yes",
                rules           => <<EOF
Kay Sievers's avatar
Kay Sievers committed
1217
KERNEL=="sda", ATTR{test:colon+plus}=="?*", SYMLINK+="yes"
1218
EOF
1219 1220 1221 1222 1223 1224
        },
        {
                desc            => "overlong comment line",
                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1",
                exp_name        => "yes",
                rules           => <<EOF
1225
# 012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
1226
   # 012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
Kay Sievers's avatar
Kay Sievers committed
1227 1228
KERNEL=="sda1", SYMLINK+=="no"
KERNEL=="sda1", SYMLINK+="yes"
1229
EOF
1230 1231 1232 1233 1234 1235
        },
        {
                desc            => "magic subsys/kernel lookup",
                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
                exp_name        => "00:16:41:e2:8d:ff",
                rules           => <<EOF
Kay Sievers's avatar
Kay Sievers committed
1236
KERNEL=="sda", SYMLINK+="\$attr{[net/eth0]address}"
Kay Sievers's avatar
Kay Sievers committed
1237
EOF