Compare commits
No commits in common. "c2c193f79a1be094f42d548ace0390472075b963" and "8db8f99eb93682658dad5466eac8890c1cf3d80a" have entirely different histories.
c2c193f79a
...
8db8f99eb9
|
@ -102,7 +102,7 @@ for args in "${ARGS[@]}"; do
|
|||
SECONDS=0
|
||||
|
||||
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"
|
||||
fi
|
||||
|
||||
|
|
8
NEWS
8
NEWS
|
@ -87,12 +87,6 @@ CHANGES WITH 246 in spe:
|
|||
used, the DNS-over-TLS certificate is validated to match the
|
||||
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
|
||||
systemd-coredump to save core files for suid processes. When saving
|
||||
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
|
||||
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)
|
||||
gained support for growing XFS partitions. Previously it supported
|
||||
only ext4 and btrfs partitions.
|
||||
|
|
|
@ -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
|
|
@ -1,9 +1,6 @@
|
|||
# SPDX-License-Identifier: LGPL-2.1+
|
||||
|
||||
# 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('''
|
||||
hwdb_files = files('''
|
||||
20-pci-vendor-model.hwdb
|
||||
20-pci-classes.hwdb
|
||||
20-usb-vendor-model.hwdb
|
||||
|
@ -15,10 +12,6 @@ hwdb_files_notest = files('''
|
|||
20-OUI.hwdb
|
||||
20-net-ifname.hwdb
|
||||
20-vmbus-class.hwdb
|
||||
'''.split())
|
||||
|
||||
hwdb_files_test = files('''
|
||||
60-autosuspend.hwdb
|
||||
60-evdev.hwdb
|
||||
60-input-id.hwdb
|
||||
60-keyboard.hwdb
|
||||
|
@ -30,16 +23,7 @@ hwdb_files_test = files('''
|
|||
'''.split())
|
||||
|
||||
if conf.get('ENABLE_HWDB') == 1
|
||||
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_data(hwdb_files,
|
||||
install_dir : udevhwdbdir)
|
||||
|
||||
meson.add_install_script('sh', '-c',
|
||||
|
@ -48,16 +32,16 @@ if conf.get('ENABLE_HWDB') == 1
|
|||
meson.add_install_script('sh', '-c',
|
||||
'test -n "$DESTDIR" || @0@/systemd-hwdb update'
|
||||
.format(rootbindir))
|
||||
endif
|
||||
|
||||
############################################################
|
||||
|
||||
if want_tests != 'false'
|
||||
parse_hwdb_py = find_program('parse_hwdb.py')
|
||||
if want_tests != 'false'
|
||||
test('parse-hwdb',
|
||||
parse_hwdb_py,
|
||||
args : [hwdb_files_test,
|
||||
auto_suspend_rules],
|
||||
timeout : 90)
|
||||
endif
|
||||
endif
|
||||
|
||||
############################################################
|
||||
|
||||
|
|
|
@ -59,7 +59,6 @@ REAL = Combine((INTEGER + Optional('.' + Optional(INTEGER))) ^ ('.' + INTEGER))
|
|||
SIGNED_REAL = Combine(Optional(Word('-+')) + REAL)
|
||||
UDEV_TAG = Word(string.ascii_uppercase, alphanums + '_')
|
||||
|
||||
# Those patterns are used in type-specific matches
|
||||
TYPES = {'mouse': ('usb', 'bluetooth', 'ps2', '*'),
|
||||
'evdev': ('name', 'atkbd', 'input'),
|
||||
'id-input': ('modalias'),
|
||||
|
@ -69,27 +68,13 @@ TYPES = {'mouse': ('usb', 'bluetooth', 'ps2', '*'),
|
|||
'sensor': ('modalias', ),
|
||||
}
|
||||
|
||||
# Patterns that are used to set general properties on a device
|
||||
GENERAL_MATCHES = {'acpi',
|
||||
'bluetooth',
|
||||
'usb',
|
||||
'pci',
|
||||
'sdio',
|
||||
'vmbus',
|
||||
'OUI',
|
||||
}
|
||||
|
||||
@lru_cache()
|
||||
def hwdb_grammar():
|
||||
ParserElement.setDefaultWhitespaceChars('')
|
||||
|
||||
prefix = Or(category + ':' + Or(conn) + ':'
|
||||
for category, conn in TYPES.items())
|
||||
|
||||
matchline_typed = Combine(prefix + Word(printables + ' ' + '®'))
|
||||
matchline_general = Combine(Or(GENERAL_MATCHES) + ':' + Word(printables))
|
||||
matchline = (matchline_typed | matchline_general) + EOL
|
||||
|
||||
matchline = Combine(prefix + Word(printables + ' ' + '®')) + EOL
|
||||
propertyline = (White(' ', exact=1).suppress() +
|
||||
Combine(UDEV_TAG - '=' - Word(alphanums + '_=:@*.!-;, "') - Optional(pythonStyleComment)) +
|
||||
EOL)
|
||||
|
@ -117,7 +102,6 @@ def property_grammar():
|
|||
('MOUSE_WHEEL_CLICK_ANGLE_HORIZONTAL', INTEGER),
|
||||
('MOUSE_WHEEL_CLICK_COUNT', INTEGER),
|
||||
('MOUSE_WHEEL_CLICK_COUNT_HORIZONTAL', INTEGER),
|
||||
('ID_AUTOSUSPEND', Literal('1')),
|
||||
('ID_INPUT', Literal('1')),
|
||||
('ID_INPUT_ACCELEROMETER', Literal('1')),
|
||||
('ID_INPUT_JOYSTICK', Literal('1')),
|
||||
|
|
|
@ -67,28 +67,20 @@
|
|||
|
||||
<varlistentry>
|
||||
<term><varname>Domains=</varname></term>
|
||||
<listitem><para>A space-separated list of domains optionally prefixed with <literal>~</literal>,
|
||||
used for two distinct purposes described below. Defaults to the empty list.</para>
|
||||
<listitem><para>A space-separated list of domains. These domains are used as search suffixes when resolving
|
||||
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
|
||||
suffixes when resolving single-label hostnames (domain names which contain no dot), in order to
|
||||
qualify them into fully-qualified domain names (FQDNs). These "search domains" are strictly processed
|
||||
in the order they are specified in, 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> with the <varname>search</varname> keyword are used instead, if
|
||||
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>
|
||||
<para>Specified domain names may optionally be prefixed with <literal>~</literal>. In this case they do not
|
||||
define a search path, but preferably direct DNS queries for the indicated domains to the DNS servers configured
|
||||
with the system <varname>DNS=</varname> setting (see above), in case additional, suitable per-link DNS servers
|
||||
are known. If no per-link DNS servers are known using the <literal>~</literal> syntax has no effect. Use the
|
||||
construct <literal>~.</literal> (which is composed of <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
|
||||
system DNS server defined with <varname>DNS=</varname> preferably for all domains.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
|
@ -266,28 +258,11 @@
|
|||
|
||||
<varlistentry>
|
||||
<term><varname>ReadEtcHosts=</varname></term>
|
||||
<listitem><para>Takes a boolean argument. If <literal>yes</literal> (the default),
|
||||
<command>systemd-resolved</command> will read <filename>/etc/hosts</filename>, and try to resolve
|
||||
hosts or address by using the entries in the file before sending query to DNS servers.
|
||||
</para></listitem>
|
||||
<listitem><para>Takes a boolean argument. If <literal>yes</literal> (the default), the DNS stub resolver will read
|
||||
<filename>/etc/hosts</filename>, and try to resolve hosts or address by using the entries in the file before
|
||||
sending query to DNS servers.</para></listitem>
|
||||
</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>
|
||||
</refsect1>
|
||||
|
||||
|
|
|
@ -135,16 +135,14 @@
|
|||
IPv6.</para></listitem>
|
||||
|
||||
<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
|
||||
that such records can be resolved when search domains are defined. For any interface which defines
|
||||
search domains, such look-ups are routed to that interface, suffixed with each of the search domains
|
||||
defined on that interface in turn. When global search domains are defined, such look-ups are routed to
|
||||
all interfaces, suffixed by each of the global search domains in turn. Additionally, lookup of
|
||||
single-label names via unicast DNS may be enabled with the
|
||||
<varname>ResolveUnicastSingleLabel=yes</varname> setting. The details of which servers are queried and
|
||||
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>
|
||||
MulticastDNS) for non-synthesized single-label names is only allowed for non-top-level domains. This
|
||||
means that such records can only be resolved when search domains are defined. For any interface which
|
||||
defines search domains, such look-ups are routed to that interface, suffixed with each of the search
|
||||
domains defined on that interface in turn. When global search domains are defined, such look-ups are
|
||||
routed to all interfaces, suffixed by each of the global search domains in turn. The details of which
|
||||
servers are queried and 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, 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
|
||||
configured, plus the globally configured DNS servers if there are any. Note that by default, lookups for
|
||||
|
|
|
@ -10,9 +10,8 @@ SUBSYSTEM=="virtio-ports", KERNEL=="vport*", ATTR{name}=="?*", SYMLINK+="virtio-
|
|||
SUBSYSTEM=="rtc", ATTR{hctosys}=="1", SYMLINK+="rtc"
|
||||
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}"
|
||||
LABEL="default_hwdb_imported"
|
||||
|
||||
ACTION!="add", GOTO="default_end"
|
||||
|
||||
|
|
|
@ -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"
|
|
@ -4,9 +4,8 @@ ACTION=="remove", 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}"
|
||||
# We already ran the hwdb builtin for devices with MODALIAS in 50-default.rules.
|
||||
# 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"
|
||||
SUBSYSTEMS=="pci", IMPORT{builtin}="hwdb --subsystem=pci"
|
||||
SUBSYSTEMS=="usb", IMPORT{builtin}="usb_id", IMPORT{builtin}="hwdb --subsystem=usb"
|
||||
|
||||
# /dev/serial/by-path/, /dev/serial/by-id/ for USB devices
|
||||
KERNEL!="ttyUSB[0-9]*|ttyACM[0-9]*", GOTO="serial_end"
|
||||
|
|
|
@ -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"
|
|
@ -1,7 +1,6 @@
|
|||
# SPDX-License-Identifier: LGPL-2.1+
|
||||
|
||||
rules = files('''
|
||||
60-autosuspend.rules
|
||||
60-block.rules
|
||||
60-cdrom_id.rules
|
||||
60-drm.rules
|
||||
|
@ -15,6 +14,7 @@ rules = files('''
|
|||
60-persistent-v4l.rules
|
||||
60-sensor.rules
|
||||
60-serial.rules
|
||||
61-autosuspend-manual.rules
|
||||
70-joystick.rules
|
||||
70-mouse.rules
|
||||
70-touchpad.rules
|
||||
|
@ -45,3 +45,11 @@ foreach file : rules_in
|
|||
install_dir : udevrulesdir)
|
||||
all_rules += gen
|
||||
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])
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
#include <sys/signalfd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/uio.h>
|
||||
#include <sys/un.h>
|
||||
|
@ -220,32 +219,6 @@ fail:
|
|||
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 r;
|
||||
|
||||
|
@ -265,7 +238,9 @@ int log_open(void) {
|
|||
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 &&
|
||||
IN_SET(log_target, LOG_TARGET_AUTO,
|
||||
|
|
|
@ -234,12 +234,14 @@ static int property_get_show_status(
|
|||
sd_bus_error *error) {
|
||||
|
||||
Manager *m = userdata;
|
||||
int b;
|
||||
|
||||
assert(m);
|
||||
assert(bus);
|
||||
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(
|
||||
|
@ -309,7 +311,7 @@ static int property_set_watchdog(Manager *m, WatchdogType type, sd_bus_message *
|
|||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return manager_override_watchdog(m, type, timeout);
|
||||
return manager_set_watchdog_overridden(m, type, timeout);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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[] = {
|
||||
SD_BUS_VTABLE_START(0),
|
||||
|
||||
|
@ -2808,12 +2786,6 @@ const sd_bus_vtable bus_manager_vtable[] = {
|
|||
NULL,
|
||||
method_reset_failed,
|
||||
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",
|
||||
NULL,,
|
||||
"a(ssssssouso)",
|
||||
|
|
|
@ -779,8 +779,6 @@ int manager_new(UnitFileScope scope, ManagerTestRunFlags test_run_flags, Manager
|
|||
.watchdog_overridden[WATCHDOG_REBOOT] = USEC_INFINITY,
|
||||
.watchdog_overridden[WATCHDOG_KEXEC] = USEC_INFINITY,
|
||||
|
||||
.show_status_overridden = _SHOW_STATUS_INVALID,
|
||||
|
||||
.notify_fd = -1,
|
||||
.cgroups_agent_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) {
|
||||
|
||||
case 20:
|
||||
manager_override_show_status(m, SHOW_STATUS_YES, "signal");
|
||||
manager_set_show_status(m, SHOW_STATUS_YES, "signal");
|
||||
break;
|
||||
|
||||
case 21:
|
||||
manager_override_show_status(m, SHOW_STATUS_NO, "signal");
|
||||
manager_set_show_status(m, SHOW_STATUS_NO, "signal");
|
||||
break;
|
||||
|
||||
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. */
|
||||
(void) serialize_bool(f, "honor-device-enumeration", !switching_root);
|
||||
|
||||
if (m->show_status_overridden != _SHOW_STATUS_INVALID)
|
||||
(void) serialize_item(f, "show-status-overridden",
|
||||
show_status_to_string(m->show_status_overridden));
|
||||
t = show_status_to_string(m->show_status);
|
||||
if (t)
|
||||
(void) serialize_item(f, "show-status", t);
|
||||
|
||||
if (m->log_level_overridden)
|
||||
(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;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
assert(m);
|
||||
|
@ -3570,14 +3568,14 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
|
|||
else
|
||||
m->honor_device_enumeration = b;
|
||||
|
||||
} else if ((val = startswith(l, "show-status-overridden="))) {
|
||||
} else if ((val = startswith(l, "show-status="))) {
|
||||
ShowStatus s;
|
||||
|
||||
s = show_status_from_string(val);
|
||||
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
|
||||
manager_override_show_status(m, s, "deserialize");
|
||||
manager_set_show_status(m, s, "deserialization");
|
||||
|
||||
} else if ((val = startswith(l, "log-level-override="))) {
|
||||
int level;
|
||||
|
@ -3603,7 +3601,7 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
|
|||
if (deserialize_usec(val, &t) < 0)
|
||||
log_notice("Failed to parse runtime-watchdog-overridden value '%s', ignoring.", val);
|
||||
else
|
||||
manager_override_watchdog(m, WATCHDOG_RUNTIME, t);
|
||||
manager_set_watchdog_overridden(m, WATCHDOG_RUNTIME, t);
|
||||
|
||||
} else if ((val = startswith(l, "reboot-watchdog-overridden="))) {
|
||||
usec_t t;
|
||||
|
@ -3611,7 +3609,7 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
|
|||
if (deserialize_usec(val, &t) < 0)
|
||||
log_notice("Failed to parse reboot-watchdog-overridden value '%s', ignoring.", val);
|
||||
else
|
||||
manager_override_watchdog(m, WATCHDOG_REBOOT, t);
|
||||
manager_set_watchdog_overridden(m, WATCHDOG_REBOOT, t);
|
||||
|
||||
} else if ((val = startswith(l, "kexec-watchdog-overridden="))) {
|
||||
usec_t t;
|
||||
|
@ -3619,7 +3617,7 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
|
|||
if (deserialize_usec(val, &t) < 0)
|
||||
log_notice("Failed to parse kexec-watchdog-overridden value '%s', ignoring.", val);
|
||||
else
|
||||
manager_override_watchdog(m, WATCHDOG_KEXEC, t);
|
||||
manager_set_watchdog_overridden(m, WATCHDOG_KEXEC, t);
|
||||
|
||||
} else if (startswith(l, "env=")) {
|
||||
r = deserialize_environment(l + 4, &m->client_environment);
|
||||
|
@ -4266,78 +4264,49 @@ void manager_recheck_journal(Manager *m) {
|
|||
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) {
|
||||
assert(m);
|
||||
assert(reason);
|
||||
assert(mode >= 0 && mode < _SHOW_STATUS_MAX);
|
||||
|
||||
if (MANAGER_IS_USER(m))
|
||||
if (!MANAGER_IS_SYSTEM(m))
|
||||
return;
|
||||
|
||||
if (mode == m->show_status)
|
||||
return;
|
||||
|
||||
if (m->show_status_overridden == _SHOW_STATUS_INVALID) {
|
||||
bool enabled;
|
||||
|
||||
enabled = show_status_on(mode);
|
||||
bool enabled = IN_SET(mode, SHOW_STATUS_TEMPORARY, SHOW_STATUS_YES);
|
||||
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;
|
||||
|
||||
if (enabled)
|
||||
(void) touch("/run/systemd/show-status");
|
||||
else
|
||||
(void) unlink("/run/systemd/show-status");
|
||||
}
|
||||
|
||||
void manager_override_show_status(Manager *m, ShowStatus mode, const char *reason) {
|
||||
static bool manager_get_show_status(Manager *m, StatusType type) {
|
||||
assert(m);
|
||||
assert(mode < _SHOW_STATUS_MAX);
|
||||
|
||||
if (MANAGER_IS_USER(m))
|
||||
return;
|
||||
if (!MANAGER_IS_SYSTEM(m))
|
||||
return false;
|
||||
|
||||
if (mode == m->show_status_overridden)
|
||||
return;
|
||||
if (m->no_console_output)
|
||||
return false;
|
||||
|
||||
m->show_status_overridden = mode;
|
||||
if (!IN_SET(manager_state(m), MANAGER_INITIALIZING, MANAGER_STARTING, MANAGER_STOPPING))
|
||||
return false;
|
||||
|
||||
if (mode == _SHOW_STATUS_INVALID)
|
||||
mode = m->show_status;
|
||||
/* If we cannot find out the status properly, just proceed. */
|
||||
if (type != STATUS_TYPE_EMERGENCY && manager_check_ask_password(m) > 0)
|
||||
return false;
|
||||
|
||||
log_debug("%s (%s) showing of status (%s).",
|
||||
m->show_status_overridden != _SHOW_STATUS_INVALID ? "Overriding" : "Restoring",
|
||||
strna(show_status_to_string(mode)),
|
||||
reason);
|
||||
if (type == STATUS_TYPE_NOTICE && m->show_status != SHOW_STATUS_NO)
|
||||
return true;
|
||||
|
||||
set_show_status_marker(show_status_on(mode));
|
||||
return show_status_on(m->show_status);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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, ...) {
|
||||
va_list ap;
|
||||
|
||||
/* 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;
|
||||
|
||||
/* XXX We should totally drop the check for ephemeral here
|
||||
|
|
|
@ -335,7 +335,6 @@ struct Manager {
|
|||
uint8_t return_value;
|
||||
|
||||
ShowStatus show_status;
|
||||
ShowStatus show_status_overridden;
|
||||
StatusUnitFormat status_unit_format;
|
||||
char *confirm_spawn;
|
||||
bool no_console_output;
|
||||
|
@ -513,10 +512,7 @@ void disable_printk_ratelimit(void);
|
|||
void manager_recheck_dbus(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_override_show_status(Manager *m, ShowStatus mode, const char *reason);
|
||||
|
||||
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);
|
||||
|
@ -557,7 +553,7 @@ ManagerTimestamp manager_timestamp_initrd_mangle(ManagerTimestamp s);
|
|||
|
||||
usec_t manager_get_watchdog(Manager *m, WatchdogType t);
|
||||
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_;
|
||||
OOMPolicy oom_policy_from_string(const char *s) _pure_;
|
||||
|
|
|
@ -318,10 +318,6 @@
|
|||
send_interface="org.freedesktop.systemd1.Manager"
|
||||
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 -->
|
||||
|
||||
<allow send_destination="org.freedesktop.systemd1"
|
||||
|
|
|
@ -1065,7 +1065,7 @@ static int dhcp6_assign_delegated_prefix(Link *link,
|
|||
address->in_addr.in6 = *prefix;
|
||||
|
||||
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 {
|
||||
r = generate_ipv6_eui_64_address(link, &address->in_addr.in6);
|
||||
if (r < 0)
|
||||
|
|
|
@ -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) {
|
||||
_cleanup_(dns_query_candidate_freep) DnsQueryCandidate *c = NULL;
|
||||
DnsQueryCandidate *c;
|
||||
int r;
|
||||
|
||||
assert(q);
|
||||
|
@ -524,21 +524,24 @@ static int dns_query_add_candidate(DnsQuery *q, DnsScope *s) {
|
|||
return r;
|
||||
|
||||
/* 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) &&
|
||||
dns_scope_name_wants_search_domain(s, dns_question_first_name(q->question_idna))) {
|
||||
/* OK, we want a search domain now. Let's find one for this scope */
|
||||
if ((q->flags & SD_RESOLVED_NO_SEARCH) == 0 &&
|
||||
dns_scope_name_needs_search_domain(s, dns_question_first_name(q->question_idna))) {
|
||||
/* OK, we need a search domain now. Let's find one for this scope */
|
||||
|
||||
r = dns_query_candidate_next_search_domain(c);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r <= 0) /* if there's no search domain, then we won't add any transaction. */
|
||||
goto fail;
|
||||
}
|
||||
|
||||
r = dns_query_candidate_setup_transactions(c);
|
||||
if (r < 0)
|
||||
return r;
|
||||
goto fail;
|
||||
|
||||
TAKE_PTR(c);
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
dns_query_candidate_free(c);
|
||||
return r;
|
||||
}
|
||||
|
||||
static int dns_query_synthesize_reply(DnsQuery *q, DnsTransactionState *state) {
|
||||
|
|
|
@ -102,8 +102,6 @@ enum {
|
|||
};
|
||||
|
||||
DnsQueryCandidate* dns_query_candidate_free(DnsQueryCandidate *c);
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(DnsQueryCandidate*, dns_query_candidate_free);
|
||||
|
||||
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);
|
||||
|
|
|
@ -619,7 +619,7 @@ DnsScopeMatch dns_scope_good_domain(
|
|||
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
|
||||
* 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
|
||||
* us. (If people actually want to pull traffic away
|
||||
* 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) {
|
||||
|
||||
/* On classic DNS, looking up non-address RRs is always fine. (Specifically, we want to
|
||||
* permit looking up DNSKEY and DS records on the root and top-level domains.) */
|
||||
/* On classic DNS, looking up non-address RRs is always
|
||||
* 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))
|
||||
return true;
|
||||
|
||||
/* Unless explicitly overridden, we refuse to look up A and AAAA RRs on the root and
|
||||
* single-label domains, under the assumption that those should be resolved via LLMNR or
|
||||
* search path only, and should not be leaked onto the internet. */
|
||||
const char* name = dns_resource_key_name(key);
|
||||
|
||||
if (!s->manager->resolve_unicast_single_label &&
|
||||
dns_name_is_single_label(name))
|
||||
return false;
|
||||
|
||||
return !dns_name_is_root(name);
|
||||
/* However, we refuse to look up A and AAAA RRs on the
|
||||
* root and single-label domains, under the assumption
|
||||
* that those should be resolved via LLMNR or search
|
||||
* path only, and should not be leaked onto the
|
||||
* internet. */
|
||||
return !(dns_name_is_single_label(dns_resource_key_name(key)) ||
|
||||
dns_name_is_root(dns_resource_key_name(key)));
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
if (s->protocol != DNS_PROTOCOL_DNS)
|
||||
|
|
|
@ -99,7 +99,7 @@ void dns_scope_dump(DnsScope *s, FILE *f);
|
|||
|
||||
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);
|
||||
|
||||
|
|
|
@ -28,4 +28,3 @@ 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.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.ResolveUnicastSingleLabel, config_parse_bool, 0, offsetof(Manager, resolve_unicast_single_label)
|
||||
|
|
|
@ -70,10 +70,9 @@ struct Manager {
|
|||
LIST_HEAD(DnsSearchDomain, search_domains);
|
||||
unsigned n_search_domains;
|
||||
|
||||
bool need_builtin_fallbacks;
|
||||
bool read_resolv_conf;
|
||||
bool resolve_unicast_single_label;
|
||||
bool need_builtin_fallbacks:1;
|
||||
|
||||
bool read_resolv_conf:1;
|
||||
struct stat resolv_conf_stat;
|
||||
|
||||
DnsTrustAnchor trust_anchor;
|
||||
|
|
|
@ -22,4 +22,3 @@
|
|||
#Cache=yes
|
||||
#DNSStubListener=yes
|
||||
#ReadEtcHosts=yes
|
||||
#ResolveUnicastSingleLabel=no
|
||||
|
|
|
@ -115,7 +115,9 @@ test_run() {
|
|||
echo "*** Running test $f"
|
||||
prepare_testdir ${f%.input}
|
||||
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
|
||||
echo "**** Unexpected error output for $f"
|
||||
cat $TESTDIR/tmp/err
|
||||
|
|
|
@ -1,24 +1,14 @@
|
|||
#!/usr/bin/env python3
|
||||
# SPDX-License-Identifier: LGPL-2.1+
|
||||
|
||||
# Generate autosuspend rules for devices that have been tested to work properly
|
||||
# with autosuspend by the Chromium OS team. Based on
|
||||
# Generate autosuspend rules for devices that have been whitelisted (IE tested)
|
||||
# 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
|
||||
|
||||
import sys
|
||||
import chromiumos.gen_autosuspend_rules
|
||||
|
||||
print('# pci:v<00VENDOR>d<00DEVICE> (8 uppercase hexadecimal digits twice)')
|
||||
for entry in chromiumos.gen_autosuspend_rules.PCI_IDS:
|
||||
vendor, device = entry.split(':')
|
||||
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')
|
||||
if __name__ == '__main__':
|
||||
if len(sys.argv) > 1:
|
||||
sys.stdout = open(sys.argv[1], 'w')
|
||||
chromiumos.gen_autosuspend_rules.main()
|
||||
|
|
Loading…
Reference in New Issue