Compare commits

..

No commits in common. "c2c193f79a1be094f42d548ace0390472075b963" and "8db8f99eb93682658dad5466eac8890c1cf3d80a" have entirely different histories.

27 changed files with 169 additions and 390 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" CFLAGS="-Werror" CXXFLAGS="-Werror" meson -Dtests=unsafe -Dslow-tests=true --werror $args build; then if ! AR="$AR" CC="$CC" CXX="$CXX" 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,12 +87,6 @@ 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
@ -544,6 +538,8 @@ 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

@ -1,44 +0,0 @@
# 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,9 +1,6 @@
# SPDX-License-Identifier: LGPL-2.1+ # SPDX-License-Identifier: LGPL-2.1+
# Those files right now are not supported by the grammar. Also, hwdb_files = files('''
# 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
@ -15,10 +12,6 @@ hwdb_files_notest = 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
@ -30,16 +23,7 @@ hwdb_files_test = files('''
'''.split()) '''.split())
if conf.get('ENABLE_HWDB') == 1 if conf.get('ENABLE_HWDB') == 1
auto_suspend_rules = custom_target( install_data(hwdb_files,
'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',
@ -48,15 +32,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')
test('parse-hwdb', parse_hwdb_py = find_program('parse_hwdb.py')
parse_hwdb_py, if want_tests != 'false'
args : [hwdb_files_test, test('parse-hwdb',
auto_suspend_rules], parse_hwdb_py,
timeout : 90) timeout : 90)
endif
endif endif
############################################################ ############################################################

View File

@ -59,7 +59,6 @@ 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'),
@ -69,27 +68,13 @@ 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)
@ -117,7 +102,6 @@ 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,28 +67,20 @@
<varlistentry> <varlistentry>
<term><varname>Domains=</varname></term> <term><varname>Domains=</varname></term>
<listitem><para>A space-separated list of domains optionally prefixed with <literal>~</literal>, <listitem><para>A space-separated list of domains. These domains are used as search suffixes when resolving
used for two distinct purposes described below. Defaults to the empty list.</para> single-label hostnames (domain names which contain no dot), in order to qualify them into fully-qualified
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>Any domains <emphasis>not</emphasis> prefixed with <literal>~</literal> are used as search <para>Specified domain names may optionally be prefixed with <literal>~</literal>. In this case they do not
suffixes when resolving single-label hostnames (domain names which contain no dot), in order to define a search path, but preferably direct DNS queries for the indicated domains to the DNS servers configured
qualify them into fully-qualified domain names (FQDNs). These "search domains" are strictly processed with the system <varname>DNS=</varname> setting (see above), in case additional, suitable per-link DNS servers
in the order they are specified in, until the name with the suffix appended is found. For are known. If no per-link DNS servers are known using the <literal>~</literal> syntax has no effect. Use the
compatibility reasons, if this setting is not specified, the search domains listed in construct <literal>~.</literal> (which is composed of <literal>~</literal> to indicate a routing domain and
<filename>/etc/resolv.conf</filename> with the <varname>search</varname> keyword are used instead, if <literal>.</literal> to indicate the DNS root domain that is the implied suffix of all DNS domains) to use the
that file exists and any domains are configured in it.</para> system DNS server defined with <varname>DNS=</varname> preferably for all domains.</para></listitem>
<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>
@ -266,28 +258,11 @@
<varlistentry> <varlistentry>
<term><varname>ReadEtcHosts=</varname></term> <term><varname>ReadEtcHosts=</varname></term>
<listitem><para>Takes a boolean argument. If <literal>yes</literal> (the default), <listitem><para>Takes a boolean argument. If <literal>yes</literal> (the default), the DNS stub resolver will read
<command>systemd-resolved</command> will read <filename>/etc/hosts</filename>, and try to resolve <filename>/etc/hosts</filename>, and try to resolve hosts or address by using the entries in the file before
hosts or address by using the entries in the file before sending query to DNS servers. sending query to DNS servers.</para></listitem>
</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,16 +135,14 @@
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 allowed for non-top-level domains. This means MulticastDNS) for non-synthesized single-label names is only allowed for non-top-level domains. This
that such records can be resolved when search domains are defined. For any interface which defines means that such records can only be resolved when search domains are defined. For any interface which
search domains, such look-ups are routed to that interface, suffixed with each of the search domains defines search domains, such look-ups are routed to that interface, suffixed with each of the search
defined on that interface in turn. When global search domains are defined, such look-ups are routed to domains defined on that interface in turn. When global search domains are defined, such look-ups are
all interfaces, suffixed by each of the global search domains in turn. Additionally, lookup of routed to all interfaces, suffixed by each of the global search domains in turn. The details of which
single-label names via unicast DNS may be enabled with the servers are queried and how the final reply is chosen are described below. Note that this means that
<varname>ResolveUnicastSingleLabel=yes</varname> setting. The details of which servers are queried and address queries for single-label names are never sent out to remote DNS servers, and if no search
how the final reply is chosen are described below. Note that this means that address queries for domains are defined, resolution will fail.</para></listitem>
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,9 +10,8 @@ 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", GOTO="default_hwdb_imported" SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", IMPORT{builtin}="usb_id", IMPORT{builtin}="hwdb --subsystem=usb"
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

@ -1,14 +0,0 @@
# 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,9 +4,8 @@ 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}"
# We already ran the hwdb builtin for devices with MODALIAS in 50-default.rules. SUBSYSTEMS=="pci", IMPORT{builtin}="hwdb --subsystem=pci"
# Let's cover the remaining case here, where we walk up the tree to find a node with $MODALIAS. SUBSYSTEMS=="usb", IMPORT{builtin}="usb_id", IMPORT{builtin}="hwdb --subsystem=usb"
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

@ -0,0 +1,19 @@
# 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,7 +1,6 @@
# 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
@ -15,6 +14,7 @@ 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,3 +45,11 @@ 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,7 +7,6 @@
#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>
@ -220,32 +219,6 @@ 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;
@ -265,7 +238,9 @@ int log_open(void) {
return 0; return 0;
} }
if (log_target != LOG_TARGET_AUTO || getpid_cached() == 1 || stderr_is_journal()) { if (log_target != LOG_TARGET_AUTO ||
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,12 +234,14 @@ 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);
return sd_bus_message_append(reply, "b", manager_get_show_status_on(m)); b = IN_SET(m->show_status, SHOW_STATUS_TEMPORARY, SHOW_STATUS_YES);
return sd_bus_message_append_basic(reply, 'b', &b);
} }
static int property_get_runtime_watchdog( static int property_get_runtime_watchdog(
@ -309,7 +311,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_override_watchdog(m, type, timeout); return manager_set_watchdog_overridden(m, type, timeout);
} }
static int property_set_runtime_watchdog( static int property_set_runtime_watchdog(
@ -2450,30 +2452,6 @@ 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),
@ -2808,12 +2786,6 @@ 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,8 +779,6 @@ 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,
@ -2761,11 +2759,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_override_show_status(m, SHOW_STATUS_YES, "signal"); manager_set_show_status(m, SHOW_STATUS_YES, "signal");
break; break;
case 21: case 21:
manager_override_show_status(m, SHOW_STATUS_NO, "signal"); manager_set_show_status(m, SHOW_STATUS_NO, "signal");
break; break;
case 22: case 22:
@ -3221,9 +3219,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);
if (m->show_status_overridden != _SHOW_STATUS_INVALID) t = show_status_to_string(m->show_status);
(void) serialize_item(f, "show-status-overridden", if (t)
show_status_to_string(m->show_status_overridden)); (void) serialize_item(f, "show-status", t);
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());
@ -3401,7 +3399,7 @@ void manager_set_watchdog(Manager *m, WatchdogType t, usec_t timeout) {
m->watchdog[t] = timeout; m->watchdog[t] = timeout;
} }
int manager_override_watchdog(Manager *m, WatchdogType t, usec_t timeout) { int manager_set_watchdog_overridden(Manager *m, WatchdogType t, usec_t timeout) {
int r = 0; int r = 0;
assert(m); assert(m);
@ -3570,14 +3568,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-overridden="))) { } else if ((val = startswith(l, "show-status="))) {
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-overridden flag '%s', ignoring.", val); log_notice("Failed to parse show-status flag '%s', ignoring.", val);
else else
manager_override_show_status(m, s, "deserialize"); manager_set_show_status(m, s, "deserialization");
} else if ((val = startswith(l, "log-level-override="))) { } else if ((val = startswith(l, "log-level-override="))) {
int level; int level;
@ -3603,7 +3601,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_override_watchdog(m, WATCHDOG_RUNTIME, t); manager_set_watchdog_overridden(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;
@ -3611,7 +3609,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_override_watchdog(m, WATCHDOG_REBOOT, t); manager_set_watchdog_overridden(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;
@ -3619,7 +3617,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_override_watchdog(m, WATCHDOG_KEXEC, t); manager_set_watchdog_overridden(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);
@ -4266,78 +4264,49 @@ void manager_recheck_journal(Manager *m) {
log_open(); log_open();
} }
static ShowStatus manager_get_show_status(Manager *m) {
assert(m);
if (MANAGER_IS_USER(m))
return _SHOW_STATUS_INVALID;
if (m->show_status_overridden != _SHOW_STATUS_INVALID)
return m->show_status_overridden;
return m->show_status;
}
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");
else
(void) unlink("/run/systemd/show-status");
}
void manager_set_show_status(Manager *m, ShowStatus mode, const char *reason) { 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); assert(mode >= 0 && mode < _SHOW_STATUS_MAX);
if (MANAGER_IS_USER(m)) if (!MANAGER_IS_SYSTEM(m))
return; return;
if (mode == m->show_status) if (mode == m->show_status)
return; return;
if (m->show_status_overridden == _SHOW_STATUS_INVALID) { bool enabled = IN_SET(mode, SHOW_STATUS_TEMPORARY, SHOW_STATUS_YES);
bool enabled;
enabled = show_status_on(mode);
log_debug("%s (%s) showing of status (%s).",
enabled ? "Enabling" : "Disabling",
strna(show_status_to_string(mode)),
reason);
set_show_status_marker(enabled);
}
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).", log_debug("%s (%s) showing of status (%s).",
m->show_status_overridden != _SHOW_STATUS_INVALID ? "Overriding" : "Restoring", enabled ? "Enabling" : "Disabling",
strna(show_status_to_string(mode)), strna(show_status_to_string(mode)),
reason); reason);
m->show_status = mode;
set_show_status_marker(show_status_on(mode)); if (enabled)
(void) touch("/run/systemd/show-status");
else
(void) unlink("/run/systemd/show-status");
}
static bool manager_get_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 show_status_on(m->show_status);
} }
const char *manager_get_confirm_spawn(Manager *m) { const char *manager_get_confirm_spawn(Manager *m) {
@ -4412,34 +4381,12 @@ 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_should_show_status(m, type)) if (m && !manager_get_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,7 +335,6 @@ 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;
@ -513,10 +512,7 @@ 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);
@ -557,7 +553,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_override_watchdog(Manager *m, WatchdogType t, usec_t timeout); int manager_set_watchdog_overridden(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,10 +318,6 @@
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) {
_cleanup_(dns_query_candidate_freep) DnsQueryCandidate *c = NULL; DnsQueryCandidate *c;
int r; int r;
assert(q); assert(q);
@ -524,21 +524,24 @@ 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 (!FLAGS_SET(q->flags, SD_RESOLVED_NO_SEARCH) && if ((q->flags & SD_RESOLVED_NO_SEARCH) == 0 &&
dns_scope_name_wants_search_domain(s, dns_question_first_name(q->question_idna))) { dns_scope_name_needs_search_domain(s, dns_question_first_name(q->question_idna))) {
/* OK, we want a search domain now. Let's find one for this scope */ /* OK, we need 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 (r <= 0) /* if there's no search domain, then we won't add any transaction. */
return r; goto fail;
} }
r = dns_query_candidate_setup_transactions(c); r = dns_query_candidate_setup_transactions(c);
if (r < 0) if (r < 0)
return r; goto fail;
TAKE_PTR(c);
return 0; return 0;
fail:
dns_query_candidate_free(c);
return r;
} }
static int dns_query_synthesize_reply(DnsQuery *q, DnsTransactionState *state) { static int dns_query_synthesize_reply(DnsQuery *q, DnsTransactionState *state) {

View File

@ -102,8 +102,6 @@ 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
* particularly relevant as it means a "." route on some * particular 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,21 +651,20 @@ 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 fine. (Specifically, we want to /* On classic DNS, looking up non-address RRs is always
* permit looking up DNSKEY and DS records on the root and top-level domains.) */ * fine. (Specifically, we want to permit looking up
* 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;
/* Unless explicitly overridden, we refuse to look up A and AAAA RRs on the root and /* However, we refuse to look up A and AAAA RRs on the
* single-label domains, under the assumption that those should be resolved via LLMNR or * root and single-label domains, under the assumption
* search path only, and should not be leaked onto the internet. */ * that those should be resolved via LLMNR or search
const char* name = dns_resource_key_name(key); * path only, and should not be leaked onto the
* internet. */
if (!s->manager->resolve_unicast_single_label && return !(dns_name_is_single_label(dns_resource_key_name(key)) ||
dns_name_is_single_label(name)) dns_name_is_root(dns_resource_key_name(key)));
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
@ -1170,7 +1169,7 @@ DnsSearchDomain *dns_scope_get_search_domains(DnsScope *s) {
return s->manager->search_domains; return s->manager->search_domains;
} }
bool dns_scope_name_wants_search_domain(DnsScope *s, const char *name) { bool dns_scope_name_needs_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_wants_search_domain(DnsScope *s, const char *name); bool dns_scope_name_needs_search_domain(DnsScope *s, const char *name);
bool dns_scope_network_good(DnsScope *s); bool dns_scope_network_good(DnsScope *s);

View File

@ -18,14 +18,13 @@ struct ConfigPerfItem;
%struct-type %struct-type
%includes %includes
%% %%
Resolve.DNS, config_parse_dns_servers, DNS_SERVER_SYSTEM, 0 Resolve.DNS, config_parse_dns_servers, DNS_SERVER_SYSTEM, 0
Resolve.FallbackDNS, config_parse_dns_servers, DNS_SERVER_FALLBACK, 0 Resolve.FallbackDNS, config_parse_dns_servers, DNS_SERVER_FALLBACK, 0
Resolve.Domains, config_parse_search_domains, 0, 0 Resolve.Domains, config_parse_search_domains, 0, 0
Resolve.LLMNR, config_parse_resolve_support, 0, offsetof(Manager, llmnr_support) Resolve.LLMNR, config_parse_resolve_support, 0, offsetof(Manager, llmnr_support)
Resolve.MulticastDNS, config_parse_resolve_support, 0, offsetof(Manager, mdns_support) Resolve.MulticastDNS, config_parse_resolve_support, 0, offsetof(Manager, mdns_support)
Resolve.DNSSEC, config_parse_dnssec_mode, 0, offsetof(Manager, dnssec_mode) Resolve.DNSSEC, config_parse_dnssec_mode, 0, offsetof(Manager, dnssec_mode)
Resolve.DNSOverTLS, config_parse_dns_over_tls_mode, 0, offsetof(Manager, dns_over_tls_mode) Resolve.DNSOverTLS, config_parse_dns_over_tls_mode, 0, offsetof(Manager, dns_over_tls_mode)
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,10 +70,9 @@ struct Manager {
LIST_HEAD(DnsSearchDomain, search_domains); LIST_HEAD(DnsSearchDomain, search_domains);
unsigned n_search_domains; unsigned n_search_domains;
bool need_builtin_fallbacks; bool need_builtin_fallbacks:1;
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,4 +22,3 @@
#Cache=yes #Cache=yes
#DNSStubListener=yes #DNSStubListener=yes
#ReadEtcHosts=yes #ReadEtcHosts=yes
#ResolveUnicastSingleLabel=no

View File

@ -115,7 +115,9 @@ 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>&1 | tail -n1 > $TESTDIR/tmp/err systemd-sysusers --root=$TESTDIR 2> /dev/null
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,24 +1,14 @@
#!/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 tested to work properly # Generate autosuspend rules for devices that have been whitelisted (IE tested)
# with autosuspend by the Chromium OS team. Based on # by the Chromium OS team. Please keep this script in sync with:
# 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
print('# pci:v<00VENDOR>d<00DEVICE> (8 uppercase hexadecimal digits twice)') if __name__ == '__main__':
for entry in chromiumos.gen_autosuspend_rules.PCI_IDS: if len(sys.argv) > 1:
vendor, device = entry.split(':') sys.stdout = open(sys.argv[1], 'w')
vendor = int(vendor, 16) chromiumos.gen_autosuspend_rules.main()
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')