1
0
mirror of https://github.com/systemd/systemd synced 2026-04-26 08:54:50 +02:00

Compare commits

...

13 Commits

Author SHA1 Message Date
Yu Watanabe
01af366ef9
Merge pull request #23291 from yuwata/udev-rule-fix-regression
udev: fix parent token handling
2022-05-07 04:58:20 +09:00
Yu Watanabe
0139026b3e
Merge pull request #23290 from keszybz/three-fixes
Three fixes
2022-05-07 04:57:36 +09:00
Yu Watanabe
af2ff171e0
Merge pull request #23272 from keszybz/logind-man-and-rules
Logind man and rules
2022-05-07 04:23:02 +09:00
Yu Watanabe
d94802e988 test: add testcase for #23288 2022-05-07 02:51:31 +09:00
Yu Watanabe
eba782d59b udev: fix parent token handling
This fixes a bug introduced by 03677889f0ef42cdc534bf3b31265a054b20a354.

Fixes #23288.
2022-05-07 02:51:21 +09:00
Zbigniew Jędrzejewski-Szmek
b38a9d2d77 basic/strv: fix splitting of strings with escape characters
Plain strv_split() should not care if the strings contains backslashes
or quote characters. But extract_first_word() interprets backslashes
unless EXTRACT_RETAIN_ESCAPE is given.

I wonder how it's possible that nobody noticed this before. I think this
code was introduced in 0645b83a40d1c782f173c4d8440ab2fc82a75006.
2022-05-06 18:26:30 +02:00
Zbigniew Jędrzejewski-Szmek
34c2d32cf9 shared/terminal-util: don't use $COLORTERM to force colors
Fixup for a5efbf468c96190c9562bc8121eda32310dfd112: if $COLORTERM was set, we'd
unconditionally turn on colors, which is unexpected and wrong. It even breaks
our own tests when executed in gnome-terminal.
2022-05-06 18:26:26 +02:00
Zbigniew Jędrzejewski-Szmek
e447f9ac0b docs/RELEASE: typo in target name 2022-05-05 19:49:26 +02:00
Zbigniew Jędrzejewski-Szmek
e8a5b13e45 meson: move vconsole rules to rules.d/ 2022-05-05 11:51:44 +02:00
Zbigniew Jędrzejewski-Szmek
155078c835 meson: move udev rules to rules.d/ 2022-05-05 11:51:44 +02:00
Zbigniew Jędrzejewski-Szmek
4a5f779f0e TODO: add entry about boot entries on the bus
Something like this is needed to allow integration with graphical envs and
fully unprivileged operation.
2022-05-05 11:51:44 +02:00
Zbigniew Jędrzejewski-Szmek
e4239a34d7 man: deduplicate dbus versioning ref 2022-05-05 11:48:22 +02:00
Zbigniew Jędrzejewski-Szmek
01942823ae man: beef up o.fd.login1 page a bit and recommend busctl too
gdbus is an external program, so it makes sense to recommend busctl.
2022-05-05 11:48:22 +02:00
28 changed files with 178 additions and 170 deletions

5
TODO
View File

@ -1399,8 +1399,9 @@ Features:
- follow PropertiesChanged state more closely, to deal with quick logouts and - follow PropertiesChanged state more closely, to deal with quick logouts and
relogins relogins
- (optionally?) spawn seat-manager@$SEAT.service whenever a seat shows up that as CanGraphical set - (optionally?) spawn seat-manager@$SEAT.service whenever a seat shows up that as CanGraphical set
- expose details of boot entries on the bus. In particular, it should be possible
* move logind udev rules to top-level rule.d/ directory to query the list of boot entry titles that bootctl / sd-boot would show.
Currently we only expose their identifiers.
* move multiseat vid/pid matches from logind udev rule to hwdb * move multiseat vid/pid matches from logind udev rule to hwdb

View File

@ -11,7 +11,7 @@ SPDX-License-Identifier: LGPL-2.1-or-later
2. Update the contributors list in NEWS (`ninja -C build git-contrib`) 2. Update the contributors list in NEWS (`ninja -C build git-contrib`)
3. Update the time and place in NEWS 3. Update the time and place in NEWS
4. Update hwdb (`ninja -C build update-hwdb`, `ninja -C build update-hwdb-autosuspend`, commit separately). 4. Update hwdb (`ninja -C build update-hwdb`, `ninja -C build update-hwdb-autosuspend`, commit separately).
5. Update syscall numbers (`ninja -C build update-syscall-tables update-syscall-headers`). 5. Update syscall numbers (`ninja -C build update-syscall-tables update-syscall-header`).
6. [RC1] Update version and library numbers in `meson.build` 6. [RC1] Update version and library numbers in `meson.build`
7. Check dbus docs with `ninja -C build update-dbus-docs` 7. Check dbus docs with `ninja -C build update-dbus-docs`
8. Tag the release: `version=vXXX-rcY && git tag -s "${version}" -m "systemd ${version}"` 8. Tag the release: `version=vXXX-rcY && git tag -s "${version}" -m "systemd ${version}"`

View File

@ -514,12 +514,7 @@ node /org/freedesktop/home1/home {
</refsect2> </refsect2>
</refsect1> </refsect1>
<refsect1> <xi:include href="org.freedesktop.locale1.xml" xpointer="versioning"/>
<title>Versioning</title>
<para>These D-Bus interfaces follow <ulink url="http://0pointer.de/blog/projects/versioning-dbus.html">
the usual interface versioning guidelines</ulink>.</para>
</refsect1>
<refsect1> <refsect1>
<title>See Also</title> <title>See Also</title>

View File

@ -379,12 +379,7 @@ node /org/freedesktop/hostname1 {
name.</para> name.</para>
</refsect1> </refsect1>
<refsect1> <xi:include href="org.freedesktop.locale1.xml" xpointer="versioning"/>
<title>Versioning</title>
<para>These D-Bus interfaces follow <ulink url="http://0pointer.de/blog/projects/versioning-dbus.html">
the usual interface versioning guidelines</ulink>.</para>
</refsect1>
<refsect1> <refsect1>
<title>Examples</title> <title>Examples</title>

View File

@ -339,10 +339,5 @@ node /org/freedesktop/import1/transfer/_1 {
</example> </example>
</refsect1> </refsect1>
<refsect1> <xi:include href="org.freedesktop.locale1.xml" xpointer="versioning"/>
<title>Versioning</title>
<para>These D-Bus interfaces follow <ulink url="http://0pointer.de/blog/projects/versioning-dbus.html">
the usual interface versioning guidelines</ulink>.</para>
</refsect1>
</refentry> </refentry>

View File

@ -179,7 +179,7 @@ $ gdbus introspect --system \
</example> </example>
</refsect1> </refsect1>
<refsect1> <refsect1 id="versioning">
<title>Versioning</title> <title>Versioning</title>
<para>These D-Bus interfaces follow <ulink url="http://0pointer.de/blog/projects/versioning-dbus.html"> <para>These D-Bus interfaces follow <ulink url="http://0pointer.de/blog/projects/versioning-dbus.html">

View File

@ -1415,27 +1415,46 @@ node /org/freedesktop/login1/session/1 {
<title>Examples</title> <title>Examples</title>
<example> <example>
<title>Introspect <interfacename>org.freedesktop.login1.Manager</interfacename> on the bus</title> <title>Introspect the logind manager on the bus</title>
<programlisting>$ gdbus introspect --system --dest org.freedesktop.login1 \ <programlisting>$ gdbus introspect --system --dest org.freedesktop.login1 \
--object-path /org/freedesktop/login1 --object-path /org/freedesktop/login1
</programlisting> </programlisting>
</example>
<example> <para>or</para>
<title>Introspect <interfacename>org.freedesktop.login1.Seat</interfacename> on the bus</title>
<programlisting>$ gdbus introspect --system --dest org.freedesktop.login1 \ <programlisting>$ busctl introspect org.freedesktop.login1 /org/freedesktop/login1
--object-path /org/freedesktop/login1/seat/seat0
</programlisting> </programlisting>
</example> </example>
<example> <example>
<title>Introspect <interfacename>org.freedesktop.login1.User</interfacename> on the bus</title> <title>Introspect the default seat on the bus</title>
<programlisting>$ gdbus introspect --system --dest org.freedesktop.login1 \
--object-path /org/freedesktop/login1/seat/seat0
</programlisting>
<para>or</para>
<programlisting>$ busctl introspect org.freedesktop.login1 /org/freedesktop/login1/seat/seat0
</programlisting>
<para>Seat <literal>seat0</literal> is the default seat, so it'll be present unless local configuation
is made to reassign all devices to a different seat. The list of seats and users can be acquired with
<command>loginctl list-sessions</command>.</para>
</example>
<example>
<title>Introspect a single user on the bus</title>
<programlisting>$ gdbus introspect --system --dest org.freedesktop.login1 \ <programlisting>$ gdbus introspect --system --dest org.freedesktop.login1 \
--object-path /org/freedesktop/login1/user/_1000 --object-path /org/freedesktop/login1/user/_1000
</programlisting> </programlisting>
<para>or</para>
<programlisting>$ busctl introspect org.freedesktop.login1 /org/freedesktop/login1/user/_1000
</programlisting>
</example> </example>
<example> <example>
@ -1444,13 +1463,13 @@ node /org/freedesktop/login1/session/1 {
<programlisting>$ gdbus introspect --system --dest org.freedesktop.login1 \ <programlisting>$ gdbus introspect --system --dest org.freedesktop.login1 \
--object-path /org/freedesktop/login1/session/45 --object-path /org/freedesktop/login1/session/45
</programlisting> </programlisting>
<para>or</para>
<programlisting>$ busctl introspect org.freedesktop.login1 /org/freedesktop/login1/session/45
</programlisting>
</example> </example>
</refsect1> </refsect1>
<refsect1> <xi:include href="org.freedesktop.locale1.xml" xpointer="versioning"/>
<title>Versioning</title>
<para>These D-Bus interfaces follow <ulink url="http://0pointer.de/blog/projects/versioning-dbus.html">
the usual interface versioning guidelines</ulink>.</para>
</refsect1>
</refentry> </refentry>

View File

@ -639,10 +639,5 @@ $ gdbus introspect --system \
</example> </example>
</refsect1> </refsect1>
<refsect1> <xi:include href="org.freedesktop.locale1.xml" xpointer="versioning"/>
<title>Versioning</title>
<para>These D-Bus interfaces follow <ulink url="http://0pointer.de/blog/projects/versioning-dbus.html">
the usual interface versioning guidelines</ulink>.</para>
</refsect1>
</refentry> </refentry>

View File

@ -498,10 +498,5 @@ $ gdbus introspect --system \
</example> </example>
</refsect1> </refsect1>
<refsect1> <xi:include href="org.freedesktop.locale1.xml" xpointer="versioning"/>
<title>Versioning</title>
<para>These D-Bus interfaces follow <ulink url="http://0pointer.de/blog/projects/versioning-dbus.html">
the usual interface versioning guidelines</ulink>.</para>
</refsect1>
</refentry> </refentry>

View File

@ -65,10 +65,5 @@ node /org/freedesktop/oom1 {
</refsect2> </refsect2>
</refsect1> </refsect1>
<refsect1> <xi:include href="org.freedesktop.locale1.xml" xpointer="versioning"/>
<title>Versioning</title>
<para>These D-Bus interfaces follow <ulink url="http://0pointer.de/blog/projects/versioning-dbus.html">
the usual interface versioning guidelines</ulink>.</para>
</refsect1>
</refentry> </refentry>

View File

@ -559,10 +559,5 @@ node /org/freedesktop/portable1 {
</refsect2> </refsect2>
</refsect1> </refsect1>
<refsect1> <xi:include href="org.freedesktop.locale1.xml" xpointer="versioning"/>
<title>Versioning</title>
<para>These D-Bus interfaces follow <ulink url="http://0pointer.de/blog/projects/versioning-dbus.html">
the usual interface versioning guidelines</ulink>.</para>
</refsect1>
</refentry> </refentry>

View File

@ -891,10 +891,5 @@ $ gdbus introspect --system \
</example> </example>
</refsect1> </refsect1>
<refsect1> <xi:include href="org.freedesktop.locale1.xml" xpointer="versioning"/>
<title>Versioning</title>
<para>These D-Bus interfaces follow <ulink url="http://0pointer.de/blog/projects/versioning-dbus.html">
the usual interface versioning guidelines</ulink>.</para>
</refsect1>
</refentry> </refentry>

View File

@ -10656,10 +10656,5 @@ $ gdbus introspect --system --dest org.freedesktop.systemd1 \
</example> </example>
</refsect1> </refsect1>
<refsect1> <xi:include href="org.freedesktop.locale1.xml" xpointer="versioning"/>
<title>Versioning</title>
<para>These D-Bus interfaces follow <ulink url="http://0pointer.de/blog/projects/versioning-dbus.html">
the usual interface versioning guidelines</ulink>.</para>
</refsect1>
</refentry> </refentry>

View File

@ -190,12 +190,7 @@ $ gdbus introspect --system \
</example> </example>
</refsect1> </refsect1>
<refsect1> <xi:include href="org.freedesktop.locale1.xml" xpointer="versioning"/>
<title>Versioning</title>
<para>These D-Bus interfaces follow <ulink url="http://0pointer.de/blog/projects/versioning-dbus.html">
the usual interface versioning guidelines</ulink>.</para>
</refsect1>
<refsect1> <refsect1>
<title>See also</title> <title>See also</title>

View File

@ -2068,7 +2068,6 @@ subdir('src/timedate')
subdir('src/timesync') subdir('src/timesync')
subdir('src/tmpfiles') subdir('src/tmpfiles')
subdir('src/userdb') subdir('src/userdb')
subdir('src/vconsole')
subdir('src/xdg-autostart-generator') subdir('src/xdg-autostart-generator')
subdir('src/systemd') subdir('src/systemd')

View File

@ -4,8 +4,8 @@ install_data(
'README', 'README',
install_dir : udevrulesdir) install_dir : udevrulesdir)
rules = files( rules = [
'60-autosuspend.rules', [files('60-autosuspend.rules',
'60-block.rules', '60-block.rules',
'60-cdrom_id.rules', '60-cdrom_id.rules',
'60-drm.rules', '60-drm.rules',
@ -27,31 +27,50 @@ rules = files(
'75-probe_mtd.rules', '75-probe_mtd.rules',
'78-sound-card.rules', '78-sound-card.rules',
'80-net-setup-link.rules', '80-net-setup-link.rules',
'81-net-dhcp.rules') '81-net-dhcp.rules',
)],
if conf.get('HAVE_KMOD') == 1 [files('80-drivers.rules'),
rules += files('80-drivers.rules') conf.get('HAVE_KMOD') == 1],
endif
if dmi_arches.contains(host_machine.cpu_family()) [files('70-memory.rules'),
rules += files('70-memory.rules') dmi_arches.contains(host_machine.cpu_family())],
endif ]
install_data(rules, all_rules = []
install_dir : udevrulesdir)
foreach tuple : rules
all_rules = rules if tuple.length() == 1 or tuple[1]
install_data(tuple[0],
rules_in = ['50-udev-default.rules',
'64-btrfs.rules',
'99-systemd.rules']
foreach file : rules_in
all_rules += custom_target(
file,
input : file + '.in',
output: file,
command : [jinja2_cmdline, '@INPUT@', '@OUTPUT@'],
install : true,
install_dir : udevrulesdir) install_dir : udevrulesdir)
all_rules += tuple[0]
endif
endforeach
rules_in = [
['50-udev-default.rules'],
['64-btrfs.rules'],
['99-systemd.rules'],
['70-uaccess.rules', enable_logind and conf.get('HAVE_ACL') == 1],
['71-seat.rules', enable_logind],
['73-seat-late.rules', enable_logind],
['90-vconsole.rules', conf.get('ENABLE_VCONSOLE') == 1],
]
foreach tuple : rules_in
want = tuple.length() == 1 or tuple[1]
rule = custom_target(
tuple[0],
input : tuple[0] + '.in',
output: tuple[0],
command : [jinja2_cmdline, '@INPUT@', '@OUTPUT@'],
install : want,
install_dir : udevrulesdir)
if want
all_rules += rule
endif
endforeach endforeach

View File

@ -77,7 +77,7 @@ int strv_split_full(char ***t, const char *s, const char *separators, ExtractFla
static inline char** strv_split(const char *s, const char *separators) { static inline char** strv_split(const char *s, const char *separators) {
char **ret; char **ret;
if (strv_split_full(&ret, s, separators, 0) < 0) if (strv_split_full(&ret, s, separators, EXTRACT_RETAIN_ESCAPE) < 0)
return NULL; return NULL;
return ret; return ret;

View File

@ -1278,12 +1278,7 @@ ColorMode get_color_mode(void) {
/* We only check for the presence of the variable; value is ignored. */ /* We only check for the presence of the variable; value is ignored. */
cached_color_mode = COLOR_OFF; cached_color_mode = COLOR_OFF;
else if (STRPTR_IN_SET(getenv("COLORTERM"), else if (getpid_cached() == 1) {
"truecolor",
"24bit"))
cached_color_mode = COLOR_24BIT;
else if (getpid_cached() == 1)
/* PID1 outputs to the console without holding it open all the time. /* PID1 outputs to the console without holding it open all the time.
* *
* Note that the Linux console can only display 16 colors. We still enable 256 color * Note that the Linux console can only display 16 colors. We still enable 256 color
@ -1292,9 +1287,23 @@ ColorMode get_color_mode(void) {
* map them to the closest color in the 16 color palette (since kernel 3.16). Doing * map them to the closest color in the 16 color palette (since kernel 3.16). Doing
* 256 colors is nice for people who invoke systemd in a container or via a serial * 256 colors is nice for people who invoke systemd in a container or via a serial
* link or such, and use a true 256 color terminal to do so. */ * link or such, and use a true 256 color terminal to do so. */
cached_color_mode = getenv_terminal_is_dumb() ? COLOR_OFF : COLOR_256; if (getenv_terminal_is_dumb())
cached_color_mode = COLOR_OFF;
} else {
if (terminal_is_dumb())
cached_color_mode = COLOR_OFF;
}
if (cached_color_mode < 0) {
/* We failed to figure out any reason to *disable* colors.
* Let's see how many colors we shall use. */
if (STRPTR_IN_SET(getenv("COLORTERM"),
"truecolor",
"24bit"))
cached_color_mode = COLOR_24BIT;
else else
cached_color_mode = terminal_is_dumb() ? COLOR_OFF : COLOR_256; cached_color_mode = COLOR_256;
}
} }
return cached_color_mode; return cached_color_mode;

View File

@ -65,25 +65,22 @@ pam_systemd_sym = 'src/login/pam_systemd.sym'
pam_systemd_c = files('pam_systemd.c') pam_systemd_c = files('pam_systemd.c')
enable_logind = conf.get('ENABLE_LOGIND') == 1 enable_logind = conf.get('ENABLE_LOGIND') == 1
in_files = [
['logind.conf', pkgsysconfdir, enable_logind and install_sysconfdir_samples],
['70-uaccess.rules', udevrulesdir, enable_logind and conf.get('HAVE_ACL') == 1],
['71-seat.rules', udevrulesdir, enable_logind],
['73-seat-late.rules', udevrulesdir, enable_logind],
['systemd-user', pamconfdir, enable_logind]]
foreach tuple : in_files custom_target(
file = tuple[0] 'logind.conf',
dir = tuple[1] input : 'logind.conf.in',
install = (dir == pkgsysconfdir) ? install_sysconfdir_samples : (dir != 'no') output : 'logind.conf',
custom_target(
file,
input : file + '.in',
output: file,
command : [jinja2_cmdline, '@INPUT@', '@OUTPUT@'], command : [jinja2_cmdline, '@INPUT@', '@OUTPUT@'],
install : tuple[2] and install, install : enable_logind and install_sysconfdir_samples and pkgsysconfdir != 'no',
install_dir : dir) install_dir : pkgsysconfdir)
endforeach
custom_target(
'systemd-user',
input : 'systemd-user.in',
output : 'systemd-user',
command : [jinja2_cmdline, '@INPUT@', '@OUTPUT@'],
install : enable_logind and pamconfdir != 'no',
install_dir : pamconfdir)
if enable_logind if enable_logind
install_data('org.freedesktop.login1.conf', install_data('org.freedesktop.login1.conf',
@ -92,8 +89,6 @@ if enable_logind
install_dir : dbussystemservicedir) install_dir : dbussystemservicedir)
install_data('org.freedesktop.login1.policy', install_data('org.freedesktop.login1.policy',
install_dir : polkitpolicydir) install_dir : polkitpolicydir)
install_data('70-power-switch.rules',
install_dir : udevrulesdir)
endif endif
############################################################ ############################################################

View File

@ -317,6 +317,21 @@ TEST(strv_split) {
assert_se(strv_split_full(&l, "\\", NULL, EXTRACT_UNQUOTE | EXTRACT_RELAX | EXTRACT_UNESCAPE_RELAX) == 1); assert_se(strv_split_full(&l, "\\", NULL, EXTRACT_UNQUOTE | EXTRACT_RELAX | EXTRACT_UNESCAPE_RELAX) == 1);
assert_se(strv_equal(l, STRV_MAKE("\\"))); assert_se(strv_equal(l, STRV_MAKE("\\")));
l = strv_free_erase(l);
assert_se(l = strv_split("\\", NULL));
assert_se(strv_equal(l, STRV_MAKE("\\")));
l = strv_free_erase(l);
assert_se(l = strv_split("aa\\ bb\\", NULL));
assert_se(strv_equal(l, STRV_MAKE("aa\\", "bb\\")));
l = strv_free_erase(l);
assert_se(l = strv_split("aa\" bb'", NULL));
assert_se(strv_equal(l, STRV_MAKE("aa\"", "bb'")));
} }
TEST(strv_split_empty) { TEST(strv_split_empty) {

View File

@ -2425,11 +2425,15 @@ static int udev_rule_apply_parent_token_to_event(
UdevRuleToken *head; UdevRuleToken *head;
int r; int r;
line = rules->current_file->current_line; assert(rules);
head = rules->current_file->current_line->current_token; assert(rules->current_file);
event->dev_parent = event->dev; assert(event);
line = ASSERT_PTR(rules->current_file->current_line);
head = ASSERT_PTR(rules->current_file->current_line->current_token);
event->dev_parent = ASSERT_PTR(event->dev);
for (;;) { for (;;) {
line->current_token = NULL;
LIST_FOREACH(tokens, token, head) { LIST_FOREACH(tokens, token, head) {
if (!token_is_for_parents(token)) if (!token_is_for_parents(token))
return true; /* All parent tokens match. */ return true; /* All parent tokens match. */
@ -2441,8 +2445,8 @@ static int udev_rule_apply_parent_token_to_event(
if (r == 0) if (r == 0)
break; break;
} }
if (!line->current_token) if (r > 0)
/* All parent tokens match. But no assign tokens in the line. Hmm... */ /* All parent tokens match, and no more token (except for GOTO) in the line. */
return true; return true;
if (sd_device_get_parent(event->dev_parent, &event->dev_parent) < 0) { if (sd_device_get_parent(event->dev_parent, &event->dev_parent) < 0) {

View File

@ -1,9 +0,0 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
custom_target(
'90-vconsole.rules',
input : '90-vconsole.rules.in',
output : '90-vconsole.rules',
command : [jinja2_cmdline, '@INPUT@', '@OUTPUT@'],
install : conf.get('ENABLE_VCONSOLE') == 1,
install_dir : udevrulesdir)

View File

@ -176,7 +176,7 @@ EOF
{ {
devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1",
exp_links => ["boot_disk1", "boot_disk1-4", "boot_disk1-5"], exp_links => ["boot_disk1", "boot_disk1-4", "boot_disk1-5"],
not_exp_links => ["boot_disk1-1", "boot_disk1-2", "boot_disk1-3"] not_exp_links => ["boot_disk1-1", "boot_disk1-2", "boot_disk1-3", "boot_disk1-6", "boot_disk1-7"]
}], }],
rules => <<EOF rules => <<EOF
SUBSYSTEMS=="scsi", ATTRS{vendor}=="?ATA", SYMLINK+="boot_disk%n-1" SUBSYSTEMS=="scsi", ATTRS{vendor}=="?ATA", SYMLINK+="boot_disk%n-1"
@ -185,6 +185,12 @@ SUBSYSTEMS=="scsi", ATTRS{vendor}=="A??", SYMLINK+="boot_disk%n"
SUBSYSTEMS=="scsi", ATTRS{vendor}=="ATAS", SYMLINK+="boot_disk%n-3" SUBSYSTEMS=="scsi", ATTRS{vendor}=="ATAS", SYMLINK+="boot_disk%n-3"
SUBSYSTEMS=="scsi", ATTRS{vendor}=="AT?", SYMLINK+="boot_disk%n-4" SUBSYSTEMS=="scsi", ATTRS{vendor}=="AT?", SYMLINK+="boot_disk%n-4"
SUBSYSTEMS=="scsi", ATTRS{vendor}=="??A", SYMLINK+="boot_disk%n-5" SUBSYSTEMS=="scsi", ATTRS{vendor}=="??A", SYMLINK+="boot_disk%n-5"
SUBSYSTEMS=="scsi", ATTRS{vendor}=="ATA", GOTO="skip-6"
SUBSYSTEMS=="scsi", ATTRS{vendor}=="ATA", SYMLINK+="boot_disk%n-6"
LABEL="skip-6"
SUBSYSTEMS=="scsi", GOTO="skip-7"
SUBSYSTEMS=="scsi", ATTRS{vendor}=="ATA", SYMLINK+="boot_disk%n-7"
LABEL="skip-7"
EOF EOF
}, },
{ {