Compare commits

..

25 Commits

Author SHA1 Message Date
Lennart Poettering c2c193f79a
Merge pull request #16179 from keszybz/auto-suspend-hwdb
Convert autosuspend rules to hwdb
2020-06-22 17:38:42 +02:00
Zbigniew Jędrzejewski-Szmek 7b33ff7388 make-autosuspend-rules: remove one instance of "whitelist"
Let's be clear what we mean exactly. Also see https://lwn.net/Articles/823224/
for general justification.
2020-06-22 14:47:49 +02:00
Zbigniew Jędrzejewski-Szmek 88936ed6f9 rules: remove 61-autosuspend-manual.rules
It doesn't hurt, but there's no point in keeping it now. Any changes
can be added to 60-autosuspend.hwdb.
2020-06-22 14:45:20 +02:00
Zbigniew Jędrzejewski-Szmek 39d5b72e32 hwdb: enable autosuspend for Wacom Pen and EMV Smartcard Reader
Replaces #16113.
2020-06-22 14:45:20 +02:00
Zbigniew Jędrzejewski-Szmek aa549ff397 test: also verify the generated autosuspend hwdb file
Hint: meson test -C build parse-hwdb -v
2020-06-22 14:45:20 +02:00
Zbigniew Jędrzejewski-Szmek 79dc5d35dd tools: rewrite make-autosuspend-rules.py and add udev rules
Concatenating strings is not a very efficient approach. And in this case fully
unnecessary. We also need some rules to make use of those hwdb entries.

PCI needs to be 8 characters, not 4. And we need to use uppercase hexadecimal
for both. With udev rules this made no difference, but hwdb match is case
sensitive.

Fixes #16119.
2020-06-22 14:45:20 +02:00
Zbigniew Jędrzejewski-Szmek 5fde0607a8
Merge pull request #16235 from yuwata/network-fix-warning-16224
network: fix compile error
2020-06-22 14:29:50 +02:00
Daan De Meyer bc694c06e6 log: Prefer logging to CLI unless JOURNAL_STREAM is set 2020-06-22 14:23:48 +02:00
Lennart Poettering 7830b5c103
Merge pull request #16059 from keszybz/resolve-single-label-names
Optionally resolve single label names
2020-06-22 14:00:31 +02:00
Lennart Poettering b7e8286b4a
Merge pull request #15926 from fbuihuu/rework-show-status
Rework show status
2020-06-22 13:55:06 +02:00
Evgeny Vereshchagin e6175fbe45 ci: pass -Werror using CFLAGS
Judging by https://github.com/systemd/systemd/issues/16224, it seems
`--werror` doesn't work with `-Db_lto=true`
2020-06-22 12:15:08 +09:00
Yu Watanabe 8d9982e30d network: drop unnecessary "&"
This confuses gcc-10 with -O3 -flto.

Closes #16224.
2020-06-22 12:13:24 +09:00
Zbigniew Jędrzejewski-Szmek 2bd5e1b272 man: document the new option
Also correct "stub resolver" → "systemd-resolved" in one other option.
2020-06-18 21:28:52 +02:00
Zbigniew Jędrzejewski-Szmek 3b5bd7d6b8 resolved: optionally allow single-label A/AAAA queries 2020-06-18 21:26:20 +02:00
Zbigniew Jędrzejewski-Szmek c2f1e83e27 resolved: drop bit-field annotations for fields in Manager
Access to bit fields is less efficient, and since the Manager is a singleton,
a byte or two of space in the structure doesn't matter at all. (And in this
particular case, because of alignment issues, we wouldn't save anything
anyway.)
2020-06-18 21:26:20 +02:00
Zbigniew Jędrzejewski-Szmek 7877e5ca7c resolved: add dns_query_candidate_freep() 2020-06-18 21:26:20 +02:00
Zbigniew Jędrzejewski-Szmek 801d25ef0f man: rework description of Domains=
We said that ~domains "do not define a search path", which is mighty confusing,
because this is exactly what they do. So let's try to make this a bit easier
for the reader: start by saying that there are two things going on here, and
describe each one from user's POV.
2020-06-18 21:26:20 +02:00
Zbigniew Jędrzejewski-Szmek 876c75fe87 udev: do not execute hwdb builtin import twice or thrice
Running the import more than once shouldn't matter, but it's a bit confusing
and causes a slowdown too. This patch reworks the rules to avoid duplicted runs,
but tries to keep the same imports. (E.g. import for pci devices without MODALIAS
is only done for tty devices.)

Note that this is only about hwdb import with argument, which uses MODALIAS as
the lookup key. There are other imports done with different lookup keys.
2020-06-18 18:25:15 +02:00
Lennart Poettering b4564641be hwdb: generate a hwdb file instead of rules for autosuspend 2020-06-13 20:00:23 +02:00
Franck Bui 43bba15ac8 pid1: rename manager_set_{show_status,watchdog}_overridden() into manager_override_(show_status,watchdog}
No functional change.
2020-06-11 12:00:32 +02:00
Franck Bui 0bb007f7a2 pid1: add a new SetShowStatus() bus call to override/restore show status mode
The only way to control "ShowStatus" property programmatically was to use the
signal API and wait until the property "ShowStatus" switched to the new value.

This interface is rather cumbersome to use and doesn't allow to temporarily
override the current setting and later restore the overridden value in
race-free manner.

The new method also accepts the empty string as argument which allows to
restore the initial value of ShowStatus, ie the value before it was overridden
by this method.

Fixes: #11447.
2020-06-11 12:00:32 +02:00
Franck Bui 3ceb347130 pid1: introduce an helper to handle the show-status marker
No functional change.
2020-06-11 12:00:16 +02:00
Franck Bui 44a419540e pid1: rework handling of m->show_status
The fact that m->show_status was serialized/deserialized made impossible any
further customisation of this setting via system.conf. IOW the value was
basically always locked unless it was changed via signals.

This patch reworks the handling of m->show_status but also makes sure that if a
new value was changed via the signal API then this value is kept and preserved
accross PID1 reexecuting or reloading.

Note: this effectively means that once the value is set via the signal
interface, it can be changed again only through the signal API.
2020-06-09 09:16:54 +02:00
Franck Bui 0d6d3cf055 pid1: rename manager_get_show_status() to manager_should_show_status()
The name 'manager_get_show_status()' suggests that the function simply reads
the property 'show_status' of the manager and hence returns a 'StatusType'
value.

However it was doing more than that since it contained the logic (based on
'show_status' but also on the state of the manager) to figure out if status
message could be emitted to the console.

Hence this patch renames the function to 'manager_should_show_status()'. The
previous name will be reused in a later patch to effectively return the value
of 'show_status' property.

No functional change.
2020-06-09 09:16:54 +02:00
Franck Bui b309078ab9 pid1: make more use of show_status_on()
No functional change.
2020-06-09 09:16:54 +02:00
27 changed files with 386 additions and 165 deletions

View File

@ -102,7 +102,7 @@ for args in "${ARGS[@]}"; do
SECONDS=0 SECONDS=0
info "Checking build with $args" info "Checking build with $args"
if ! AR="$AR" CC="$CC" CXX="$CXX" meson -Dtests=unsafe -Dslow-tests=true --werror $args build; then if ! AR="$AR" CC="$CC" CXX="$CXX" CFLAGS="-Werror" CXXFLAGS="-Werror" meson -Dtests=unsafe -Dslow-tests=true --werror $args build; then
fatal "meson failed with $args" fatal "meson failed with $args"
fi fi

8
NEWS
View File

@ -87,6 +87,12 @@ CHANGES WITH 246 in spe:
used, the DNS-over-TLS certificate is validated to match the used, the DNS-over-TLS certificate is validated to match the
specified hostname. specified hostname.
* systemd-resolved may be configured to forward single-label DNS names.
This is not standard-conformant, but may make sense in setups where
public DNS servers are not used.
* systemd-resolved's DNS-over-TLS support gained SNI validation.
* The fs.suid_dumpable sysctl is set to 2 / "suidsafe". This allows * The fs.suid_dumpable sysctl is set to 2 / "suidsafe". This allows
systemd-coredump to save core files for suid processes. When saving systemd-coredump to save core files for suid processes. When saving
the core file, systemd-coredump will use the effective uid and gid of the core file, systemd-coredump will use the effective uid and gid of
@ -538,8 +544,6 @@ CHANGES WITH 245:
* systemd-sysusers gained support for creating users with the primary * systemd-sysusers gained support for creating users with the primary
group named differently than the user. group named differently than the user.
* systemd-resolved's DNS-over-TLS support gained SNI validation.
* systemd-growfs (i.e. the x-systemd.growfs mount option in /etc/fstab) * systemd-growfs (i.e. the x-systemd.growfs mount option in /etc/fstab)
gained support for growing XFS partitions. Previously it supported gained support for growing XFS partitions. Previously it supported
only ext4 and btrfs partitions. only ext4 and btrfs partitions.

View File

@ -0,0 +1,44 @@
# This file is part of systemd.
#
# The lookup keys are $MODALIAS strings, see udev's hwdb builtin.
#
# Match string formats:
# <subsystem>:<modalias>
#
# pci:v<vendor>d<device>
# usb:v<vendor>p<product>
#
# To add local entries, create a new file
# /etc/udev/hwdb.d/61-autosuspend-local.hwdb
# and add your rules there. To load the new rules execute (as root):
# systemd-hwdb update
# udevadm trigger /dev/…
#
# If your changes are generally applicable, preferably send them as a pull
# request to
# https://github.com/systemd/systemd
# or create a bug report on https://github.com/systemd/systemd/issues and
# include your new rules, a description of the device, and the output of
# udevadm info
# the device.
#
# Allowed properties are:
# ID_AUTOSUSPEND=1
#
# Sort by brand, model
#########################################
# Alcor
#########################################
# AU9540 Smartcard Reader
usb:v058Fp9540*
ID_AUTOSUSPEND=1
#########################################
# Wacom
#########################################
usb:v056Ap51A0*
ID_AUTOSUSPEND=1

View File

@ -1,6 +1,9 @@
# SPDX-License-Identifier: LGPL-2.1+ # SPDX-License-Identifier: LGPL-2.1+
hwdb_files = files(''' # Those files right now are not supported by the grammar. Also,
# they are very long but quite repetitive and the parser is not very fast.
# So we don't "test" them.
hwdb_files_notest = files('''
20-pci-vendor-model.hwdb 20-pci-vendor-model.hwdb
20-pci-classes.hwdb 20-pci-classes.hwdb
20-usb-vendor-model.hwdb 20-usb-vendor-model.hwdb
@ -12,6 +15,10 @@ hwdb_files = files('''
20-OUI.hwdb 20-OUI.hwdb
20-net-ifname.hwdb 20-net-ifname.hwdb
20-vmbus-class.hwdb 20-vmbus-class.hwdb
'''.split())
hwdb_files_test = files('''
60-autosuspend.hwdb
60-evdev.hwdb 60-evdev.hwdb
60-input-id.hwdb 60-input-id.hwdb
60-keyboard.hwdb 60-keyboard.hwdb
@ -23,7 +30,16 @@ hwdb_files = files('''
'''.split()) '''.split())
if conf.get('ENABLE_HWDB') == 1 if conf.get('ENABLE_HWDB') == 1
install_data(hwdb_files, auto_suspend_rules = custom_target(
'60-autosuspend-chromiumos.hwdb',
output : '60-autosuspend-chromiumos.hwdb',
command : make_autosuspend_rules_py,
capture : true,
install : true,
install_dir: udevhwdbdir)
install_data(hwdb_files_notest,
hwdb_files_test,
install_dir : udevhwdbdir) install_dir : udevhwdbdir)
meson.add_install_script('sh', '-c', meson.add_install_script('sh', '-c',
@ -32,15 +48,15 @@ if conf.get('ENABLE_HWDB') == 1
meson.add_install_script('sh', '-c', meson.add_install_script('sh', '-c',
'test -n "$DESTDIR" || @0@/systemd-hwdb update' 'test -n "$DESTDIR" || @0@/systemd-hwdb update'
.format(rootbindir)) .format(rootbindir))
endif
############################################################ if want_tests != 'false'
parse_hwdb_py = find_program('parse_hwdb.py')
parse_hwdb_py = find_program('parse_hwdb.py')
if want_tests != 'false'
test('parse-hwdb', test('parse-hwdb',
parse_hwdb_py, parse_hwdb_py,
args : [hwdb_files_test,
auto_suspend_rules],
timeout : 90) timeout : 90)
endif
endif endif
############################################################ ############################################################

View File

@ -59,6 +59,7 @@ REAL = Combine((INTEGER + Optional('.' + Optional(INTEGER))) ^ ('.' + INTEGER))
SIGNED_REAL = Combine(Optional(Word('-+')) + REAL) SIGNED_REAL = Combine(Optional(Word('-+')) + REAL)
UDEV_TAG = Word(string.ascii_uppercase, alphanums + '_') UDEV_TAG = Word(string.ascii_uppercase, alphanums + '_')
# Those patterns are used in type-specific matches
TYPES = {'mouse': ('usb', 'bluetooth', 'ps2', '*'), TYPES = {'mouse': ('usb', 'bluetooth', 'ps2', '*'),
'evdev': ('name', 'atkbd', 'input'), 'evdev': ('name', 'atkbd', 'input'),
'id-input': ('modalias'), 'id-input': ('modalias'),
@ -68,13 +69,27 @@ TYPES = {'mouse': ('usb', 'bluetooth', 'ps2', '*'),
'sensor': ('modalias', ), 'sensor': ('modalias', ),
} }
# Patterns that are used to set general properties on a device
GENERAL_MATCHES = {'acpi',
'bluetooth',
'usb',
'pci',
'sdio',
'vmbus',
'OUI',
}
@lru_cache() @lru_cache()
def hwdb_grammar(): def hwdb_grammar():
ParserElement.setDefaultWhitespaceChars('') ParserElement.setDefaultWhitespaceChars('')
prefix = Or(category + ':' + Or(conn) + ':' prefix = Or(category + ':' + Or(conn) + ':'
for category, conn in TYPES.items()) for category, conn in TYPES.items())
matchline = Combine(prefix + Word(printables + ' ' + '®')) + EOL
matchline_typed = Combine(prefix + Word(printables + ' ' + '®'))
matchline_general = Combine(Or(GENERAL_MATCHES) + ':' + Word(printables))
matchline = (matchline_typed | matchline_general) + EOL
propertyline = (White(' ', exact=1).suppress() + propertyline = (White(' ', exact=1).suppress() +
Combine(UDEV_TAG - '=' - Word(alphanums + '_=:@*.!-;, "') - Optional(pythonStyleComment)) + Combine(UDEV_TAG - '=' - Word(alphanums + '_=:@*.!-;, "') - Optional(pythonStyleComment)) +
EOL) EOL)
@ -102,6 +117,7 @@ def property_grammar():
('MOUSE_WHEEL_CLICK_ANGLE_HORIZONTAL', INTEGER), ('MOUSE_WHEEL_CLICK_ANGLE_HORIZONTAL', INTEGER),
('MOUSE_WHEEL_CLICK_COUNT', INTEGER), ('MOUSE_WHEEL_CLICK_COUNT', INTEGER),
('MOUSE_WHEEL_CLICK_COUNT_HORIZONTAL', INTEGER), ('MOUSE_WHEEL_CLICK_COUNT_HORIZONTAL', INTEGER),
('ID_AUTOSUSPEND', Literal('1')),
('ID_INPUT', Literal('1')), ('ID_INPUT', Literal('1')),
('ID_INPUT_ACCELEROMETER', Literal('1')), ('ID_INPUT_ACCELEROMETER', Literal('1')),
('ID_INPUT_JOYSTICK', Literal('1')), ('ID_INPUT_JOYSTICK', Literal('1')),

View File

@ -67,20 +67,28 @@
<varlistentry> <varlistentry>
<term><varname>Domains=</varname></term> <term><varname>Domains=</varname></term>
<listitem><para>A space-separated list of domains. These domains are used as search suffixes when resolving <listitem><para>A space-separated list of domains optionally prefixed with <literal>~</literal>,
single-label hostnames (domain names which contain no dot), in order to qualify them into fully-qualified used for two distinct purposes described below. Defaults to the empty list.</para>
domain names (FQDNs). Search domains are strictly processed in the order they are specified, until the name
with the suffix appended is found. For compatibility reasons, if this setting is not specified, the search
domains listed in <filename>/etc/resolv.conf</filename> are used instead, if that file exists and any domains
are configured in it. This setting defaults to the empty list.</para>
<para>Specified domain names may optionally be prefixed with <literal>~</literal>. In this case they do not <para>Any domains <emphasis>not</emphasis> prefixed with <literal>~</literal> are used as search
define a search path, but preferably direct DNS queries for the indicated domains to the DNS servers configured suffixes when resolving single-label hostnames (domain names which contain no dot), in order to
with the system <varname>DNS=</varname> setting (see above), in case additional, suitable per-link DNS servers qualify them into fully-qualified domain names (FQDNs). These "search domains" are strictly processed
are known. If no per-link DNS servers are known using the <literal>~</literal> syntax has no effect. Use the in the order they are specified in, until the name with the suffix appended is found. For
construct <literal>~.</literal> (which is composed of <literal>~</literal> to indicate a routing domain and compatibility reasons, if this setting is not specified, the search domains listed in
<literal>.</literal> to indicate the DNS root domain that is the implied suffix of all DNS domains) to use the <filename>/etc/resolv.conf</filename> with the <varname>search</varname> keyword are used instead, if
system DNS server defined with <varname>DNS=</varname> preferably for all domains.</para></listitem> that file exists and any domains are configured in it.</para>
<para>The domains prefixed with <literal>~</literal> are called "routing domains". All domains listed
here (both search domains and routing domains after removing the <literal>~</literal> prefix) define
a search path that preferably directs DNS queries to this inteface. This search path has an effect
only when suitable per-link DNS servers are known. Such servers may be defined through the
<varname>DNS=</varname> setting (see above) and dynamically at run time, for example from DHCP
leases. If no per-link DNS servers are known, routing domains have no effect.</para>
<para>Use the construct <literal>~.</literal> (which is composed from <literal>~</literal> to
indicate a routing domain and <literal>.</literal> to indicate the DNS root domain that is the
implied suffix of all DNS domains) to use the DNS servers defined for this link preferably for all
domains.</para></listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
@ -258,11 +266,28 @@
<varlistentry> <varlistentry>
<term><varname>ReadEtcHosts=</varname></term> <term><varname>ReadEtcHosts=</varname></term>
<listitem><para>Takes a boolean argument. If <literal>yes</literal> (the default), the DNS stub resolver will read <listitem><para>Takes a boolean argument. If <literal>yes</literal> (the default),
<filename>/etc/hosts</filename>, and try to resolve hosts or address by using the entries in the file before <command>systemd-resolved</command> will read <filename>/etc/hosts</filename>, and try to resolve
sending query to DNS servers.</para></listitem> hosts or address by using the entries in the file before sending query to DNS servers.
</para></listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><varname>ResolveUnicastSingleLabel=</varname></term>
<listitem><para>Takes a boolean argument. When false (the default),
<command>systemd-resolved</command> will not resolve A and AAAA queries for single-label names over
classic DNS. Note that such names may still be resolved if search domains are specified (see
<varname>Domains=</varname> above), or using other mechanisms, in particular via LLMNR or from
<filename>/etc/hosts</filename>. When true, queries for single-label names will be forwarded to
global DNS servers even if no search domains are defined.
</para>
<para>This option is provided for compatibility with configurations where <emphasis>public DNS
servers are not used</emphasis>. Forwarding single-label names to servers not under your control is
not standard-conformant, see <ulink
url="https://www.iab.org/documents/correspondence-reports-documents/2013-2/iab-statement-dotless-domains-considered-harmful/">IAB
Statement</ulink>, and may create a privacy and security risk.</para></listitem>
</varlistentry>
</variablelist> </variablelist>
</refsect1> </refsect1>

View File

@ -135,14 +135,16 @@
IPv6.</para></listitem> IPv6.</para></listitem>
<listitem><para>Resolution of address records (A and AAAA) via unicast DNS (i.e. not LLMNR or <listitem><para>Resolution of address records (A and AAAA) via unicast DNS (i.e. not LLMNR or
MulticastDNS) for non-synthesized single-label names is only allowed for non-top-level domains. This MulticastDNS) for non-synthesized single-label names is allowed for non-top-level domains. This means
means that such records can only be resolved when search domains are defined. For any interface which that such records can be resolved when search domains are defined. For any interface which defines
defines search domains, such look-ups are routed to that interface, suffixed with each of the search search domains, such look-ups are routed to that interface, suffixed with each of the search domains
domains defined on that interface in turn. When global search domains are defined, such look-ups are defined on that interface in turn. When global search domains are defined, such look-ups are routed to
routed to all interfaces, suffixed by each of the global search domains in turn. The details of which all interfaces, suffixed by each of the global search domains in turn. Additionally, lookup of
servers are queried and how the final reply is chosen are described below. Note that this means that single-label names via unicast DNS may be enabled with the
address queries for single-label names are never sent out to remote DNS servers, and if no search <varname>ResolveUnicastSingleLabel=yes</varname> setting. The details of which servers are queried and
domains are defined, resolution will fail.</para></listitem> how the final reply is chosen are described below. Note that this means that address queries for
single-label names are never sent out to remote DNS servers by default, and if no search domains are
defined, resolution will fail.</para></listitem>
<listitem><para>Other multi-label names are routed to all local interfaces that have a DNS server <listitem><para>Other multi-label names are routed to all local interfaces that have a DNS server
configured, plus the globally configured DNS servers if there are any. Note that by default, lookups for configured, plus the globally configured DNS servers if there are any. Note that by default, lookups for

View File

@ -10,8 +10,9 @@ SUBSYSTEM=="virtio-ports", KERNEL=="vport*", ATTR{name}=="?*", SYMLINK+="virtio-
SUBSYSTEM=="rtc", ATTR{hctosys}=="1", SYMLINK+="rtc" SUBSYSTEM=="rtc", ATTR{hctosys}=="1", SYMLINK+="rtc"
SUBSYSTEM=="rtc", KERNEL=="rtc0", SYMLINK+="rtc", OPTIONS+="link_priority=-100" SUBSYSTEM=="rtc", KERNEL=="rtc0", SYMLINK+="rtc", OPTIONS+="link_priority=-100"
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", IMPORT{builtin}="usb_id", IMPORT{builtin}="hwdb --subsystem=usb" SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", IMPORT{builtin}="usb_id", IMPORT{builtin}="hwdb --subsystem=usb", GOTO="default_hwdb_imported"
ENV{MODALIAS}!="", IMPORT{builtin}="hwdb --subsystem=$env{SUBSYSTEM}" ENV{MODALIAS}!="", IMPORT{builtin}="hwdb --subsystem=$env{SUBSYSTEM}"
LABEL="default_hwdb_imported"
ACTION!="add", GOTO="default_end" ACTION!="add", GOTO="default_end"

View File

@ -0,0 +1,14 @@
# do not edit this file, it will be overwritten on update
ACTION!="add", GOTO="autosuspend_end"
# I2C rules
SUBSYSTEM=="i2c", ATTR{name}=="cyapa", \
ATTR{power/control}="on", GOTO="autosuspend_end"
# Enable autosuspend if hwdb says so. Here we are relying on
# the hwdb import done earlier based on MODALIAS.
ENV{ID_AUTOSUSPEND}=="1", TEST=="power/control", \
ATTR{power/control}="auto"
LABEL="autosuspend_end"

View File

@ -4,8 +4,9 @@ ACTION=="remove", GOTO="serial_end"
SUBSYSTEM!="tty", GOTO="serial_end" SUBSYSTEM!="tty", GOTO="serial_end"
SUBSYSTEMS=="pci", ENV{ID_BUS}="pci", ENV{ID_VENDOR_ID}="$attr{vendor}", ENV{ID_MODEL_ID}="$attr{device}" SUBSYSTEMS=="pci", ENV{ID_BUS}="pci", ENV{ID_VENDOR_ID}="$attr{vendor}", ENV{ID_MODEL_ID}="$attr{device}"
SUBSYSTEMS=="pci", IMPORT{builtin}="hwdb --subsystem=pci" # We already ran the hwdb builtin for devices with MODALIAS in 50-default.rules.
SUBSYSTEMS=="usb", IMPORT{builtin}="usb_id", IMPORT{builtin}="hwdb --subsystem=usb" # Let's cover the remaining case here, where we walk up the tree to find a node with $MODALIAS.
ENV{MODALIAS}=="", SUBSYSTEMS=="pci", IMPORT{builtin}="hwdb --subsystem=pci"
# /dev/serial/by-path/, /dev/serial/by-id/ for USB devices # /dev/serial/by-path/, /dev/serial/by-id/ for USB devices
KERNEL!="ttyUSB[0-9]*|ttyACM[0-9]*", GOTO="serial_end" KERNEL!="ttyUSB[0-9]*|ttyACM[0-9]*", GOTO="serial_end"

View File

@ -1,19 +0,0 @@
# This udev rule is for any devices that should enter automatic suspend
# but are not already included in generated rules from Chromium OS via
# tools/make-autosuspend-rules.py
#
ACTION!="add", GOTO="autosuspend_manual_end"
SUBSYSTEM!="usb", GOTO="autosuspend_manual_end"
SUBSYSTEM=="usb", GOTO="autosuspend_manual_usb"
# USB rules
LABEL="autosuspend_manual_usb"
GOTO="autosuspend_manual_end"
# Enable autosuspend
LABEL="autosuspend_manual_enable"
TEST=="power/control", ATTR{power/control}="auto", GOTO="autosuspend_manual_end"
LABEL="autosuspend_manual_end"

View File

@ -1,6 +1,7 @@
# SPDX-License-Identifier: LGPL-2.1+ # SPDX-License-Identifier: LGPL-2.1+
rules = files(''' 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
@ -14,7 +15,6 @@ rules = files('''
60-persistent-v4l.rules 60-persistent-v4l.rules
60-sensor.rules 60-sensor.rules
60-serial.rules 60-serial.rules
61-autosuspend-manual.rules
70-joystick.rules 70-joystick.rules
70-mouse.rules 70-mouse.rules
70-touchpad.rules 70-touchpad.rules
@ -45,11 +45,3 @@ foreach file : rules_in
install_dir : udevrulesdir) install_dir : udevrulesdir)
all_rules += gen all_rules += gen
endforeach endforeach
auto_suspend_rules = custom_target(
'60-autosuspend-chromiumos.rules',
output : '60-autosuspend-chromiumos.rules',
command : make_autosuspend_rules_py,
capture : true,
install : true,
install_dir: [udevrulesdir])

View File

@ -7,6 +7,7 @@
#include <stdarg.h> #include <stdarg.h>
#include <stddef.h> #include <stddef.h>
#include <sys/signalfd.h> #include <sys/signalfd.h>
#include <sys/stat.h>
#include <sys/time.h> #include <sys/time.h>
#include <sys/uio.h> #include <sys/uio.h>
#include <sys/un.h> #include <sys/un.h>
@ -219,6 +220,32 @@ fail:
return r; return r;
} }
static bool stderr_is_journal(void) {
_cleanup_free_ char *w = NULL;
const char *e;
uint64_t dev, ino;
struct stat st;
e = getenv("JOURNAL_STREAM");
if (!e)
return false;
if (extract_first_word(&e, &w, ":", EXTRACT_DONT_COALESCE_SEPARATORS) <= 0)
return false;
if (!e)
return false;
if (safe_atou64(w, &dev) < 0)
return false;
if (safe_atou64(e, &ino) < 0)
return false;
if (fstat(STDERR_FILENO, &st) < 0)
return false;
return st.st_dev == dev && st.st_ino == ino;
}
int log_open(void) { int log_open(void) {
int r; int r;
@ -238,9 +265,7 @@ int log_open(void) {
return 0; return 0;
} }
if (log_target != LOG_TARGET_AUTO || if (log_target != LOG_TARGET_AUTO || getpid_cached() == 1 || stderr_is_journal()) {
getpid_cached() == 1 ||
isatty(STDERR_FILENO) <= 0) {
if (!prohibit_ipc && if (!prohibit_ipc &&
IN_SET(log_target, LOG_TARGET_AUTO, IN_SET(log_target, LOG_TARGET_AUTO,

View File

@ -234,14 +234,12 @@ static int property_get_show_status(
sd_bus_error *error) { sd_bus_error *error) {
Manager *m = userdata; Manager *m = userdata;
int b;
assert(m);
assert(bus); assert(bus);
assert(reply); assert(reply);
assert(m);
b = IN_SET(m->show_status, SHOW_STATUS_TEMPORARY, SHOW_STATUS_YES); return sd_bus_message_append(reply, "b", manager_get_show_status_on(m));
return sd_bus_message_append_basic(reply, 'b', &b);
} }
static int property_get_runtime_watchdog( static int property_get_runtime_watchdog(
@ -311,7 +309,7 @@ static int property_set_watchdog(Manager *m, WatchdogType type, sd_bus_message *
if (r < 0) if (r < 0)
return r; return r;
return manager_set_watchdog_overridden(m, type, timeout); return manager_override_watchdog(m, type, timeout);
} }
static int property_set_runtime_watchdog( static int property_set_runtime_watchdog(
@ -2452,6 +2450,30 @@ static int method_abandon_scope(sd_bus_message *message, void *userdata, sd_bus_
return bus_scope_method_abandon(message, u, error); return bus_scope_method_abandon(message, u, error);
} }
static int method_set_show_status(sd_bus_message *message, void *userdata, sd_bus_error *error) {
Manager *m = userdata;
ShowStatus mode = _SHOW_STATUS_INVALID;
const char *t;
int r;
assert(m);
assert(message);
r = sd_bus_message_read(message, "s", &t);
if (r < 0)
return r;
if (!isempty(t)) {
mode = show_status_from_string(t);
if (mode < 0)
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid show status '%s'", t);
}
manager_override_show_status(m, mode, "bus");
return sd_bus_reply_method_return(message, NULL);
}
const sd_bus_vtable bus_manager_vtable[] = { const sd_bus_vtable bus_manager_vtable[] = {
SD_BUS_VTABLE_START(0), SD_BUS_VTABLE_START(0),
@ -2786,6 +2808,12 @@ const sd_bus_vtable bus_manager_vtable[] = {
NULL, NULL,
method_reset_failed, method_reset_failed,
SD_BUS_VTABLE_UNPRIVILEGED), SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_NAMES("SetShowStatus",
"s",
SD_BUS_PARAM(mode),
NULL,,
method_set_show_status,
SD_BUS_VTABLE_CAPABILITY(CAP_SYS_ADMIN)),
SD_BUS_METHOD_WITH_NAMES("ListUnits", SD_BUS_METHOD_WITH_NAMES("ListUnits",
NULL,, NULL,,
"a(ssssssouso)", "a(ssssssouso)",

View File

@ -779,6 +779,8 @@ int manager_new(UnitFileScope scope, ManagerTestRunFlags test_run_flags, Manager
.watchdog_overridden[WATCHDOG_REBOOT] = USEC_INFINITY, .watchdog_overridden[WATCHDOG_REBOOT] = USEC_INFINITY,
.watchdog_overridden[WATCHDOG_KEXEC] = USEC_INFINITY, .watchdog_overridden[WATCHDOG_KEXEC] = USEC_INFINITY,
.show_status_overridden = _SHOW_STATUS_INVALID,
.notify_fd = -1, .notify_fd = -1,
.cgroups_agent_fd = -1, .cgroups_agent_fd = -1,
.signal_fd = -1, .signal_fd = -1,
@ -2759,11 +2761,11 @@ static int manager_dispatch_signal_fd(sd_event_source *source, int fd, uint32_t
switch (sfsi.ssi_signo - SIGRTMIN) { switch (sfsi.ssi_signo - SIGRTMIN) {
case 20: case 20:
manager_set_show_status(m, SHOW_STATUS_YES, "signal"); manager_override_show_status(m, SHOW_STATUS_YES, "signal");
break; break;
case 21: case 21:
manager_set_show_status(m, SHOW_STATUS_NO, "signal"); manager_override_show_status(m, SHOW_STATUS_NO, "signal");
break; break;
case 22: case 22:
@ -3219,9 +3221,9 @@ int manager_serialize(
/* After switching root, udevd has not been started yet. So, enumeration results should not be emitted. */ /* After switching root, udevd has not been started yet. So, enumeration results should not be emitted. */
(void) serialize_bool(f, "honor-device-enumeration", !switching_root); (void) serialize_bool(f, "honor-device-enumeration", !switching_root);
t = show_status_to_string(m->show_status); if (m->show_status_overridden != _SHOW_STATUS_INVALID)
if (t) (void) serialize_item(f, "show-status-overridden",
(void) serialize_item(f, "show-status", t); show_status_to_string(m->show_status_overridden));
if (m->log_level_overridden) if (m->log_level_overridden)
(void) serialize_item_format(f, "log-level-override", "%i", log_get_max_level()); (void) serialize_item_format(f, "log-level-override", "%i", log_get_max_level());
@ -3399,7 +3401,7 @@ void manager_set_watchdog(Manager *m, WatchdogType t, usec_t timeout) {
m->watchdog[t] = timeout; m->watchdog[t] = timeout;
} }
int manager_set_watchdog_overridden(Manager *m, WatchdogType t, usec_t timeout) { int manager_override_watchdog(Manager *m, WatchdogType t, usec_t timeout) {
int r = 0; int r = 0;
assert(m); assert(m);
@ -3568,14 +3570,14 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
else else
m->honor_device_enumeration = b; m->honor_device_enumeration = b;
} else if ((val = startswith(l, "show-status="))) { } else if ((val = startswith(l, "show-status-overridden="))) {
ShowStatus s; ShowStatus s;
s = show_status_from_string(val); s = show_status_from_string(val);
if (s < 0) if (s < 0)
log_notice("Failed to parse show-status flag '%s', ignoring.", val); log_notice("Failed to parse show-status-overridden flag '%s', ignoring.", val);
else else
manager_set_show_status(m, s, "deserialization"); manager_override_show_status(m, s, "deserialize");
} else if ((val = startswith(l, "log-level-override="))) { } else if ((val = startswith(l, "log-level-override="))) {
int level; int level;
@ -3601,7 +3603,7 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
if (deserialize_usec(val, &t) < 0) if (deserialize_usec(val, &t) < 0)
log_notice("Failed to parse runtime-watchdog-overridden value '%s', ignoring.", val); log_notice("Failed to parse runtime-watchdog-overridden value '%s', ignoring.", val);
else else
manager_set_watchdog_overridden(m, WATCHDOG_RUNTIME, t); manager_override_watchdog(m, WATCHDOG_RUNTIME, t);
} else if ((val = startswith(l, "reboot-watchdog-overridden="))) { } else if ((val = startswith(l, "reboot-watchdog-overridden="))) {
usec_t t; usec_t t;
@ -3609,7 +3611,7 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
if (deserialize_usec(val, &t) < 0) if (deserialize_usec(val, &t) < 0)
log_notice("Failed to parse reboot-watchdog-overridden value '%s', ignoring.", val); log_notice("Failed to parse reboot-watchdog-overridden value '%s', ignoring.", val);
else else
manager_set_watchdog_overridden(m, WATCHDOG_REBOOT, t); manager_override_watchdog(m, WATCHDOG_REBOOT, t);
} else if ((val = startswith(l, "kexec-watchdog-overridden="))) { } else if ((val = startswith(l, "kexec-watchdog-overridden="))) {
usec_t t; usec_t t;
@ -3617,7 +3619,7 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
if (deserialize_usec(val, &t) < 0) if (deserialize_usec(val, &t) < 0)
log_notice("Failed to parse kexec-watchdog-overridden value '%s', ignoring.", val); log_notice("Failed to parse kexec-watchdog-overridden value '%s', ignoring.", val);
else else
manager_set_watchdog_overridden(m, WATCHDOG_KEXEC, t); manager_override_watchdog(m, WATCHDOG_KEXEC, t);
} else if (startswith(l, "env=")) { } else if (startswith(l, "env=")) {
r = deserialize_environment(l + 4, &m->client_environment); r = deserialize_environment(l + 4, &m->client_environment);
@ -4264,49 +4266,78 @@ void manager_recheck_journal(Manager *m) {
log_open(); log_open();
} }
void manager_set_show_status(Manager *m, ShowStatus mode, const char *reason) { static ShowStatus manager_get_show_status(Manager *m) {
assert(m); assert(m);
assert(mode >= 0 && mode < _SHOW_STATUS_MAX);
if (!MANAGER_IS_SYSTEM(m)) if (MANAGER_IS_USER(m))
return; return _SHOW_STATUS_INVALID;
if (mode == m->show_status) if (m->show_status_overridden != _SHOW_STATUS_INVALID)
return; return m->show_status_overridden;
bool enabled = IN_SET(mode, SHOW_STATUS_TEMPORARY, SHOW_STATUS_YES); return m->show_status;
log_debug("%s (%s) showing of status (%s).", }
enabled ? "Enabling" : "Disabling",
strna(show_status_to_string(mode)),
reason);
m->show_status = mode;
if (enabled) bool manager_get_show_status_on(Manager *m) {
assert(m);
return show_status_on(manager_get_show_status(m));
}
static void set_show_status_marker(bool b) {
if (b)
(void) touch("/run/systemd/show-status"); (void) touch("/run/systemd/show-status");
else else
(void) unlink("/run/systemd/show-status"); (void) unlink("/run/systemd/show-status");
} }
static bool manager_get_show_status(Manager *m, StatusType type) { void manager_set_show_status(Manager *m, ShowStatus mode, const char *reason) {
assert(m); assert(m);
assert(reason);
assert(mode >= 0 && mode < _SHOW_STATUS_MAX);
if (!MANAGER_IS_SYSTEM(m)) if (MANAGER_IS_USER(m))
return false; return;
if (m->no_console_output) if (mode == m->show_status)
return false; return;
if (!IN_SET(manager_state(m), MANAGER_INITIALIZING, MANAGER_STARTING, MANAGER_STOPPING)) if (m->show_status_overridden == _SHOW_STATUS_INVALID) {
return false; bool enabled;
/* If we cannot find out the status properly, just proceed. */ enabled = show_status_on(mode);
if (type != STATUS_TYPE_EMERGENCY && manager_check_ask_password(m) > 0) log_debug("%s (%s) showing of status (%s).",
return false; enabled ? "Enabling" : "Disabling",
strna(show_status_to_string(mode)),
reason);
if (type == STATUS_TYPE_NOTICE && m->show_status != SHOW_STATUS_NO) set_show_status_marker(enabled);
return true; }
return show_status_on(m->show_status); m->show_status = mode;
}
void manager_override_show_status(Manager *m, ShowStatus mode, const char *reason) {
assert(m);
assert(mode < _SHOW_STATUS_MAX);
if (MANAGER_IS_USER(m))
return;
if (mode == m->show_status_overridden)
return;
m->show_status_overridden = mode;
if (mode == _SHOW_STATUS_INVALID)
mode = m->show_status;
log_debug("%s (%s) showing of status (%s).",
m->show_status_overridden != _SHOW_STATUS_INVALID ? "Overriding" : "Restoring",
strna(show_status_to_string(mode)),
reason);
set_show_status_marker(show_status_on(mode));
} }
const char *manager_get_confirm_spawn(Manager *m) { const char *manager_get_confirm_spawn(Manager *m) {
@ -4381,12 +4412,34 @@ bool manager_is_confirm_spawn_disabled(Manager *m) {
return access("/run/systemd/confirm_spawn_disabled", F_OK) >= 0; return access("/run/systemd/confirm_spawn_disabled", F_OK) >= 0;
} }
static bool manager_should_show_status(Manager *m, StatusType type) {
assert(m);
if (!MANAGER_IS_SYSTEM(m))
return false;
if (m->no_console_output)
return false;
if (!IN_SET(manager_state(m), MANAGER_INITIALIZING, MANAGER_STARTING, MANAGER_STOPPING))
return false;
/* If we cannot find out the status properly, just proceed. */
if (type != STATUS_TYPE_EMERGENCY && manager_check_ask_password(m) > 0)
return false;
if (type == STATUS_TYPE_NOTICE && m->show_status != SHOW_STATUS_NO)
return true;
return manager_get_show_status_on(m);
}
void manager_status_printf(Manager *m, StatusType type, const char *status, const char *format, ...) { void manager_status_printf(Manager *m, StatusType type, const char *status, const char *format, ...) {
va_list ap; va_list ap;
/* If m is NULL, assume we're after shutdown and let the messages through. */ /* If m is NULL, assume we're after shutdown and let the messages through. */
if (m && !manager_get_show_status(m, type)) if (m && !manager_should_show_status(m, type))
return; return;
/* XXX We should totally drop the check for ephemeral here /* XXX We should totally drop the check for ephemeral here

View File

@ -335,6 +335,7 @@ struct Manager {
uint8_t return_value; uint8_t return_value;
ShowStatus show_status; ShowStatus show_status;
ShowStatus show_status_overridden;
StatusUnitFormat status_unit_format; StatusUnitFormat status_unit_format;
char *confirm_spawn; char *confirm_spawn;
bool no_console_output; bool no_console_output;
@ -512,7 +513,10 @@ void disable_printk_ratelimit(void);
void manager_recheck_dbus(Manager *m); void manager_recheck_dbus(Manager *m);
void manager_recheck_journal(Manager *m); void manager_recheck_journal(Manager *m);
bool manager_get_show_status_on(Manager *m);
void manager_set_show_status(Manager *m, ShowStatus mode, const char *reason); void manager_set_show_status(Manager *m, ShowStatus mode, const char *reason);
void manager_override_show_status(Manager *m, ShowStatus mode, const char *reason);
void manager_set_first_boot(Manager *m, bool b); void manager_set_first_boot(Manager *m, bool b);
void manager_status_printf(Manager *m, StatusType type, const char *status, const char *format, ...) _printf_(4,5); void manager_status_printf(Manager *m, StatusType type, const char *status, const char *format, ...) _printf_(4,5);
@ -553,7 +557,7 @@ ManagerTimestamp manager_timestamp_initrd_mangle(ManagerTimestamp s);
usec_t manager_get_watchdog(Manager *m, WatchdogType t); usec_t manager_get_watchdog(Manager *m, WatchdogType t);
void manager_set_watchdog(Manager *m, WatchdogType t, usec_t timeout); void manager_set_watchdog(Manager *m, WatchdogType t, usec_t timeout);
int manager_set_watchdog_overridden(Manager *m, WatchdogType t, usec_t timeout); int manager_override_watchdog(Manager *m, WatchdogType t, usec_t timeout);
const char* oom_policy_to_string(OOMPolicy i) _const_; const char* oom_policy_to_string(OOMPolicy i) _const_;
OOMPolicy oom_policy_from_string(const char *s) _pure_; OOMPolicy oom_policy_from_string(const char *s) _pure_;

View File

@ -318,6 +318,10 @@
send_interface="org.freedesktop.systemd1.Manager" send_interface="org.freedesktop.systemd1.Manager"
send_member="AddDependencyUnitFiles"/> send_member="AddDependencyUnitFiles"/>
<allow send_destination="org.freedesktop.systemd1"
send_interface="org.freedesktop.systemd1.Manager"
send_member="SetShowStatus"/>
<!-- Managed via polkit or other criteria: org.freedesktop.systemd1.Job interface --> <!-- Managed via polkit or other criteria: org.freedesktop.systemd1.Job interface -->
<allow send_destination="org.freedesktop.systemd1" <allow send_destination="org.freedesktop.systemd1"

View File

@ -1065,7 +1065,7 @@ static int dhcp6_assign_delegated_prefix(Link *link,
address->in_addr.in6 = *prefix; address->in_addr.in6 = *prefix;
if (!in_addr_is_null(AF_INET6, &link->network->dhcp6_delegation_prefix_token)) if (!in_addr_is_null(AF_INET6, &link->network->dhcp6_delegation_prefix_token))
memcpy(&address->in_addr.in6.s6_addr + 8, &link->network->dhcp6_delegation_prefix_token.in6.s6_addr + 8, 8); memcpy(address->in_addr.in6.s6_addr + 8, link->network->dhcp6_delegation_prefix_token.in6.s6_addr + 8, 8);
else { else {
r = generate_ipv6_eui_64_address(link, &address->in_addr.in6); r = generate_ipv6_eui_64_address(link, &address->in_addr.in6);
if (r < 0) if (r < 0)

View File

@ -513,7 +513,7 @@ static int on_query_timeout(sd_event_source *s, usec_t usec, void *userdata) {
} }
static int dns_query_add_candidate(DnsQuery *q, DnsScope *s) { static int dns_query_add_candidate(DnsQuery *q, DnsScope *s) {
DnsQueryCandidate *c; _cleanup_(dns_query_candidate_freep) DnsQueryCandidate *c = NULL;
int r; int r;
assert(q); assert(q);
@ -524,24 +524,21 @@ static int dns_query_add_candidate(DnsQuery *q, DnsScope *s) {
return r; return r;
/* If this a single-label domain on DNS, we might append a suitable search domain first. */ /* If this a single-label domain on DNS, we might append a suitable search domain first. */
if ((q->flags & SD_RESOLVED_NO_SEARCH) == 0 && if (!FLAGS_SET(q->flags, SD_RESOLVED_NO_SEARCH) &&
dns_scope_name_needs_search_domain(s, dns_question_first_name(q->question_idna))) { dns_scope_name_wants_search_domain(s, dns_question_first_name(q->question_idna))) {
/* OK, we need a search domain now. Let's find one for this scope */ /* OK, we want a search domain now. Let's find one for this scope */
r = dns_query_candidate_next_search_domain(c); r = dns_query_candidate_next_search_domain(c);
if (r <= 0) /* if there's no search domain, then we won't add any transaction. */ if (r < 0)
goto fail; return r;
} }
r = dns_query_candidate_setup_transactions(c); r = dns_query_candidate_setup_transactions(c);
if (r < 0) if (r < 0)
goto fail;
return 0;
fail:
dns_query_candidate_free(c);
return r; return r;
TAKE_PTR(c);
return 0;
} }
static int dns_query_synthesize_reply(DnsQuery *q, DnsTransactionState *state) { static int dns_query_synthesize_reply(DnsQuery *q, DnsTransactionState *state) {

View File

@ -102,6 +102,8 @@ enum {
}; };
DnsQueryCandidate* dns_query_candidate_free(DnsQueryCandidate *c); DnsQueryCandidate* dns_query_candidate_free(DnsQueryCandidate *c);
DEFINE_TRIVIAL_CLEANUP_FUNC(DnsQueryCandidate*, dns_query_candidate_free);
void dns_query_candidate_notify(DnsQueryCandidate *c); void dns_query_candidate_notify(DnsQueryCandidate *c);
int dns_query_new(Manager *m, DnsQuery **q, DnsQuestion *question_utf8, DnsQuestion *question_idna, int family, uint64_t flags); int dns_query_new(Manager *m, DnsQuery **q, DnsQuestion *question_utf8, DnsQuestion *question_idna, int family, uint64_t flags);

View File

@ -619,7 +619,7 @@ DnsScopeMatch dns_scope_good_domain(
manager_is_own_hostname(s->manager, domain) <= 0)) /* never resolve the local hostname via LLMNR */ manager_is_own_hostname(s->manager, domain) <= 0)) /* never resolve the local hostname via LLMNR */
return DNS_SCOPE_YES_BASE + 1; /* Return +1, as we consider ourselves authoritative return DNS_SCOPE_YES_BASE + 1; /* Return +1, as we consider ourselves authoritative
* for single-label names, i.e. one label. This is * for single-label names, i.e. one label. This is
* particular relevant as it means a "." route on some * particularly relevant as it means a "." route on some
* other scope won't pull all traffic away from * other scope won't pull all traffic away from
* us. (If people actually want to pull traffic away * us. (If people actually want to pull traffic away
* from us they should turn off LLMNR on the * from us they should turn off LLMNR on the
@ -651,20 +651,21 @@ bool dns_scope_good_key(DnsScope *s, const DnsResourceKey *key) {
if (s->protocol == DNS_PROTOCOL_DNS) { if (s->protocol == DNS_PROTOCOL_DNS) {
/* On classic DNS, looking up non-address RRs is always /* On classic DNS, looking up non-address RRs is always fine. (Specifically, we want to
* fine. (Specifically, we want to permit looking up * permit looking up DNSKEY and DS records on the root and top-level domains.) */
* DNSKEY and DS records on the root and top-level
* domains.) */
if (!dns_resource_key_is_address(key)) if (!dns_resource_key_is_address(key))
return true; return true;
/* However, we refuse to look up A and AAAA RRs on the /* Unless explicitly overridden, we refuse to look up A and AAAA RRs on the root and
* root and single-label domains, under the assumption * single-label domains, under the assumption that those should be resolved via LLMNR or
* that those should be resolved via LLMNR or search * search path only, and should not be leaked onto the internet. */
* path only, and should not be leaked onto the const char* name = dns_resource_key_name(key);
* internet. */
return !(dns_name_is_single_label(dns_resource_key_name(key)) || if (!s->manager->resolve_unicast_single_label &&
dns_name_is_root(dns_resource_key_name(key))); dns_name_is_single_label(name))
return false;
return !dns_name_is_root(name);
} }
/* On mDNS and LLMNR, send A and AAAA queries only on the /* On mDNS and LLMNR, send A and AAAA queries only on the
@ -1169,7 +1170,7 @@ DnsSearchDomain *dns_scope_get_search_domains(DnsScope *s) {
return s->manager->search_domains; return s->manager->search_domains;
} }
bool dns_scope_name_needs_search_domain(DnsScope *s, const char *name) { bool dns_scope_name_wants_search_domain(DnsScope *s, const char *name) {
assert(s); assert(s);
if (s->protocol != DNS_PROTOCOL_DNS) if (s->protocol != DNS_PROTOCOL_DNS)

View File

@ -99,7 +99,7 @@ void dns_scope_dump(DnsScope *s, FILE *f);
DnsSearchDomain *dns_scope_get_search_domains(DnsScope *s); DnsSearchDomain *dns_scope_get_search_domains(DnsScope *s);
bool dns_scope_name_needs_search_domain(DnsScope *s, const char *name); bool dns_scope_name_wants_search_domain(DnsScope *s, const char *name);
bool dns_scope_network_good(DnsScope *s); bool dns_scope_network_good(DnsScope *s);

View File

@ -28,3 +28,4 @@ Resolve.DNSOverTLS, config_parse_dns_over_tls_mode, 0,
Resolve.Cache, config_parse_dns_cache_mode, DNS_CACHE_MODE_YES, offsetof(Manager, enable_cache) Resolve.Cache, config_parse_dns_cache_mode, DNS_CACHE_MODE_YES, offsetof(Manager, enable_cache)
Resolve.DNSStubListener, config_parse_dns_stub_listener_mode, 0, offsetof(Manager, dns_stub_listener_mode) Resolve.DNSStubListener, config_parse_dns_stub_listener_mode, 0, offsetof(Manager, dns_stub_listener_mode)
Resolve.ReadEtcHosts, config_parse_bool, 0, offsetof(Manager, read_etc_hosts) Resolve.ReadEtcHosts, config_parse_bool, 0, offsetof(Manager, read_etc_hosts)
Resolve.ResolveUnicastSingleLabel, config_parse_bool, 0, offsetof(Manager, resolve_unicast_single_label)

View File

@ -70,9 +70,10 @@ struct Manager {
LIST_HEAD(DnsSearchDomain, search_domains); LIST_HEAD(DnsSearchDomain, search_domains);
unsigned n_search_domains; unsigned n_search_domains;
bool need_builtin_fallbacks:1; bool need_builtin_fallbacks;
bool read_resolv_conf;
bool resolve_unicast_single_label;
bool read_resolv_conf:1;
struct stat resolv_conf_stat; struct stat resolv_conf_stat;
DnsTrustAnchor trust_anchor; DnsTrustAnchor trust_anchor;

View File

@ -22,3 +22,4 @@
#Cache=yes #Cache=yes
#DNSStubListener=yes #DNSStubListener=yes
#ReadEtcHosts=yes #ReadEtcHosts=yes
#ResolveUnicastSingleLabel=no

View File

@ -115,9 +115,7 @@ test_run() {
echo "*** Running test $f" echo "*** Running test $f"
prepare_testdir ${f%.input} prepare_testdir ${f%.input}
cp $f $TESTDIR/usr/lib/sysusers.d/test.conf cp $f $TESTDIR/usr/lib/sysusers.d/test.conf
systemd-sysusers --root=$TESTDIR 2> /dev/null systemd-sysusers --root=$TESTDIR 2>&1 | tail -n1 > $TESTDIR/tmp/err
journalctl --sync
journalctl -t systemd-sysusers -o cat | tail -n1 > $TESTDIR/tmp/err
if ! diff -u $TESTDIR/tmp/err ${f%.*}.expected-err; then if ! diff -u $TESTDIR/tmp/err ${f%.*}.expected-err; then
echo "**** Unexpected error output for $f" echo "**** Unexpected error output for $f"
cat $TESTDIR/tmp/err cat $TESTDIR/tmp/err

View File

@ -1,14 +1,24 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# SPDX-License-Identifier: LGPL-2.1+ # SPDX-License-Identifier: LGPL-2.1+
# Generate autosuspend rules for devices that have been whitelisted (IE tested) # Generate autosuspend rules for devices that have been tested to work properly
# by the Chromium OS team. Please keep this script in sync with: # with autosuspend by the Chromium OS team. Based on
# https://chromium.googlesource.com/chromiumos/platform2/+/master/power_manager/udev/gen_autosuspend_rules.py # https://chromium.googlesource.com/chromiumos/platform2/+/master/power_manager/udev/gen_autosuspend_rules.py
import sys
import chromiumos.gen_autosuspend_rules import chromiumos.gen_autosuspend_rules
if __name__ == '__main__': print('# pci:v<00VENDOR>d<00DEVICE> (8 uppercase hexadecimal digits twice)')
if len(sys.argv) > 1: for entry in chromiumos.gen_autosuspend_rules.PCI_IDS:
sys.stdout = open(sys.argv[1], 'w') vendor, device = entry.split(':')
chromiumos.gen_autosuspend_rules.main() vendor = int(vendor, 16)
device = int(device, 16)
print(f'pci:v{vendor:08X}d{device:08X}*')
print('# usb:v<VEND>p<PROD> (4 uppercase hexadecimal digits twice')
for entry in chromiumos.gen_autosuspend_rules.USB_IDS:
vendor, product = entry.split(':')
vendor = int(vendor, 16)
product = int(product, 16)
print(f'usb:v{vendor:04X}p{product:04X}*')
print(' ID_AUTOSUSPEND=1')