mirror of
https://github.com/systemd/systemd
synced 2026-04-25 08:25:12 +02:00
Compare commits
20 Commits
bf93f24ad8
...
b0c3d2b76b
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b0c3d2b76b | ||
|
|
915774ecb8 | ||
|
|
98e5a6c93c | ||
|
|
cd3c6322db | ||
|
|
23d20adc05 | ||
|
|
9c5d7151c1 | ||
|
|
17761fb3bf | ||
|
|
d82827a107 | ||
|
|
c77c1cc201 | ||
|
|
d37c69c1bf | ||
|
|
ce1d08ba94 | ||
|
|
60e50fb20d | ||
|
|
f5a75f2027 | ||
|
|
ff58f2ae2a | ||
|
|
625d71b9ae | ||
|
|
cc9b6bdc96 | ||
|
|
bd4297e761 | ||
|
|
ee5b175b8c | ||
|
|
5984b92726 | ||
|
|
96d96ec4e7 |
@ -32,15 +32,19 @@
|
|||||||
<citerefentry><refentrytitle>systemd.syntax</refentrytitle><manvolnum>7</manvolnum></citerefentry> for a
|
<citerefentry><refentrytitle>systemd.syntax</refentrytitle><manvolnum>7</manvolnum></citerefentry> for a
|
||||||
general description of the syntax.</para>
|
general description of the syntax.</para>
|
||||||
|
|
||||||
<para>The link files are read from the files located in the system network directory
|
<para>The <filename>.link</filename> files are read from the files located in the system network
|
||||||
<filename>/usr/lib/systemd/network</filename>, the volatile runtime network directory
|
directory <filename>/usr/lib/systemd/network</filename> and
|
||||||
|
<filename>/usr/local/lib/systemd/network</filename>, the volatile runtime network directory
|
||||||
<filename>/run/systemd/network</filename>, and the local administration network directory
|
<filename>/run/systemd/network</filename>, and the local administration network directory
|
||||||
<filename>/etc/systemd/network</filename>. Link files must have the extension
|
<filename>/etc/systemd/network</filename>. All configuration files are collectively sorted and
|
||||||
<filename>.link</filename>; other extensions are ignored. All link files are collectively sorted
|
processed in alphanumeric order, regardless of the directories in which they live. However, files
|
||||||
and processed in lexical order, regardless of the directories in which they live. However, files
|
with identical filenames replace each other. It is recommended that each filename is prefixed with
|
||||||
with identical filenames replace each other. Files in <filename>/etc/</filename> have the highest
|
a number (e.g. <filename>10-eth0.link</filename>). Otherwise, the default
|
||||||
priority, files in <filename>/run/</filename> take precedence over files with the same name in
|
<filename>.link</filename> files or those generated by
|
||||||
<filename>/usr/lib/</filename>. This can be used to override a system-supplied link file with a
|
<citerefentry><refentrytitle>systemd-network-generator.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
|
||||||
|
may take precedence over user configured files. Files in <filename>/etc/</filename> have the
|
||||||
|
highest priority, files in <filename>/run/</filename> take precedence over files with the same name
|
||||||
|
in <filename>/usr/lib/</filename>. This can be used to override a system-supplied link file with a
|
||||||
local file if needed. As a special case, an empty file (file size 0) or symlink with the same name
|
local file if needed. As a special case, an empty file (file size 0) or symlink with the same name
|
||||||
pointing to <filename>/dev/null</filename> disables the configuration file entirely (it is
|
pointing to <filename>/dev/null</filename> disables the configuration file entirely (it is
|
||||||
"masked").</para>
|
"masked").</para>
|
||||||
@ -71,13 +75,13 @@
|
|||||||
<refsect1>
|
<refsect1>
|
||||||
<title>[Match] Section Options</title>
|
<title>[Match] Section Options</title>
|
||||||
|
|
||||||
<para>A link file is said to match a device if all matches specified by the
|
<para>A link file is said to match an interface if all matches specified by the [Match] section are
|
||||||
[Match] section are satisfied. When a link file does not contain valid settings
|
satisfied. When a link file does not contain valid settings in [Match] section, then the file will
|
||||||
in [Match] section, then the file will match all devices and
|
match all interfaces and <command>systemd-udevd</command> warns about that. Hint: to avoid the
|
||||||
<command>systemd-udevd</command> warns about that. Hint: to avoid the warning and to make it clear
|
warning and to make it clear that all interfaces shall be matched, add the following:
|
||||||
that all interfaces shall be matched, add the following:
|
|
||||||
<programlisting>OriginalName=*</programlisting>
|
<programlisting>OriginalName=*</programlisting>
|
||||||
The following keys are accepted:</para>
|
The first (in alphanumeric order) of the link files that matches a given interface is applied, all
|
||||||
|
later files are ignored, even if they match as well. The following keys are accepted:</para>
|
||||||
|
|
||||||
<variablelist class='network-directives'>
|
<variablelist class='network-directives'>
|
||||||
<!-- This list is reused in systemd.network(3), hence maintain a specific order:
|
<!-- This list is reused in systemd.network(3), hence maintain a specific order:
|
||||||
@ -1211,6 +1215,9 @@ MACAddress=cb:a9:87:65:43:21</programlisting>
|
|||||||
</citerefentry>,
|
</citerefentry>,
|
||||||
<citerefentry>
|
<citerefentry>
|
||||||
<refentrytitle>systemd.network</refentrytitle><manvolnum>5</manvolnum>
|
<refentrytitle>systemd.network</refentrytitle><manvolnum>5</manvolnum>
|
||||||
|
</citerefentry>,
|
||||||
|
<citerefentry>
|
||||||
|
<refentrytitle>systemd-network-generator.service</refentrytitle><manvolnum>8</manvolnum>
|
||||||
</citerefentry>
|
</citerefentry>
|
||||||
</para>
|
</para>
|
||||||
</refsect1>
|
</refsect1>
|
||||||
|
|||||||
@ -39,17 +39,22 @@
|
|||||||
than create its own. Note that the settings of the pre-existing netdev will not be changed by
|
than create its own. Note that the settings of the pre-existing netdev will not be changed by
|
||||||
networkd.</para>
|
networkd.</para>
|
||||||
|
|
||||||
<para>The <filename>.netdev</filename> files are read from the files located in the system
|
<para>The <filename>.netdev</filename> files are read from the files located in the system network
|
||||||
network directory <filename>/usr/lib/systemd/network</filename>, the volatile runtime network
|
directory <filename>/usr/lib/systemd/network</filename> and
|
||||||
directory <filename>/run/systemd/network</filename> and the local administration network
|
<filename>/usr/local/lib/systemd/network</filename>, the volatile runtime network directory
|
||||||
directory <filename>/etc/systemd/network</filename>. All configuration files are collectively
|
<filename>/run/systemd/network</filename> and the local administration network directory
|
||||||
sorted and processed in lexical order, regardless of the directories in which they live.
|
<filename>/etc/systemd/network</filename>. All configuration files are collectively sorted and
|
||||||
However, files with identical filenames replace each other. Files in <filename>/etc/</filename>
|
processed in alphanumeric order, regardless of the directories in which they live. However, files
|
||||||
have the highest priority, files in <filename>/run/</filename> take precedence over files with
|
with identical filenames replace each other. It is recommended that each filename is prefixed with
|
||||||
the same name in <filename>/usr/lib/</filename>. This can be used to override a system-supplied
|
a number (e.g. <filename>10-vlan.netdev</filename>). Otherwise, <filename>.netdev</filename> files
|
||||||
configuration file with a local file if needed. As a special case, an empty file (file size 0)
|
generated by
|
||||||
or symlink with the same name pointing to <filename>/dev/null</filename> disables the
|
<citerefentry><refentrytitle>systemd-network-generator.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
|
||||||
configuration file entirely (it is "masked").</para>
|
may take precedence over user configured files. Files in <filename>/etc/</filename> have the
|
||||||
|
highest priority, files in <filename>/run/</filename> take precedence over files with the same name
|
||||||
|
in <filename>/usr/lib/</filename>. This can be used to override a system-supplied configuration
|
||||||
|
file with a local file if needed. As a special case, an empty file (file size 0) or symlink with
|
||||||
|
the same name pointing to <filename>/dev/null</filename> disables the configuration file entirely
|
||||||
|
(it is "masked").</para>
|
||||||
|
|
||||||
<para>Along with the netdev file <filename>foo.netdev</filename>, a "drop-in" directory
|
<para>Along with the netdev file <filename>foo.netdev</filename>, a "drop-in" directory
|
||||||
<filename>foo.netdev.d/</filename> may exist. All files with the suffix <literal>.conf</literal>
|
<filename>foo.netdev.d/</filename> may exist. All files with the suffix <literal>.conf</literal>
|
||||||
@ -2433,7 +2438,8 @@ Independent=yes</programlisting>
|
|||||||
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
|
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
|
||||||
<citerefentry><refentrytitle>systemd-networkd</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
|
<citerefentry><refentrytitle>systemd-networkd</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
|
||||||
<citerefentry><refentrytitle>systemd.link</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
|
<citerefentry><refentrytitle>systemd.link</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
|
||||||
<citerefentry><refentrytitle>systemd.network</refentrytitle><manvolnum>5</manvolnum></citerefentry>
|
<citerefentry><refentrytitle>systemd.network</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
|
||||||
|
<citerefentry><refentrytitle>systemd-network-generator.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
|
||||||
</para>
|
</para>
|
||||||
</refsect1>
|
</refsect1>
|
||||||
|
|
||||||
|
|||||||
@ -42,8 +42,12 @@
|
|||||||
<filename>/usr/local/lib/systemd/network</filename>, the volatile runtime network directory
|
<filename>/usr/local/lib/systemd/network</filename>, the volatile runtime network directory
|
||||||
<filename>/run/systemd/network</filename> and the local administration network directory
|
<filename>/run/systemd/network</filename> and the local administration network directory
|
||||||
<filename>/etc/systemd/network</filename>. All configuration files are collectively sorted and
|
<filename>/etc/systemd/network</filename>. All configuration files are collectively sorted and
|
||||||
processed in lexical order, regardless of the directories in which they live. However, files with
|
processed in alphanumeric order, regardless of the directories in which they live. However, files
|
||||||
identical filenames replace each other. Files in <filename>/etc/</filename> have the highest
|
with identical filenames replace each other. It is recommended that each filename is prefixed with
|
||||||
|
a number (e.g. <filename>10-eth0.network</filename>). Otherwise, the default
|
||||||
|
<filename>.network</filename> files or those generated by
|
||||||
|
<citerefentry><refentrytitle>systemd-network-generator.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
|
||||||
|
may take precedence over user configured files. Files in <filename>/etc/</filename> have the highest
|
||||||
priority, files in <filename>/run/</filename> take precedence over files with the same name under
|
priority, files in <filename>/run/</filename> take precedence over files with the same name under
|
||||||
<filename>/usr/</filename>. This can be used to override a system-supplied configuration file with
|
<filename>/usr/</filename>. This can be used to override a system-supplied configuration file with
|
||||||
a local file if needed. As a special case, an empty file (file size 0) or symlink with the same
|
a local file if needed. As a special case, an empty file (file size 0) or symlink with the same
|
||||||
@ -69,9 +73,9 @@
|
|||||||
<title>[Match] Section Options</title>
|
<title>[Match] Section Options</title>
|
||||||
|
|
||||||
<para>The network file contains a [Match] section, which determines if a given network file may
|
<para>The network file contains a [Match] section, which determines if a given network file may
|
||||||
be applied to a given device; and a [Network] section specifying how the device should be
|
be applied to a given interface; and a [Network] section specifying how the interface should be
|
||||||
configured. The first (in lexical order) of the network files that matches a given device is
|
configured. The first (in alphanumeric order) of the network files that matches a given interface
|
||||||
applied, all later files are ignored, even if they match as well.</para>
|
is applied, all later files are ignored, even if they match as well.</para>
|
||||||
|
|
||||||
<para>A network file is said to match a network interface if all matches specified by the [Match]
|
<para>A network file is said to match a network interface if all matches specified by the [Match]
|
||||||
section are satisfied. When a network file does not contain valid settings in [Match] section, then
|
section are satisfied. When a network file does not contain valid settings in [Match] section, then
|
||||||
@ -2145,7 +2149,7 @@ Table=1234</programlisting></para>
|
|||||||
<listitem>
|
<listitem>
|
||||||
<para>When true (the default), the client will request the DHCPv6 server to delegate
|
<para>When true (the default), the client will request the DHCPv6 server to delegate
|
||||||
prefixes. If the server provides prefixes to be delegated, then subnets of the prefixes are
|
prefixes. If the server provides prefixes to be delegated, then subnets of the prefixes are
|
||||||
assigned to the interfaces which enables <varname>DHCPPrefixDelegation=</varname>.
|
assigned to the interfaces that have <varname>DHCPPrefixDelegation=yes</varname>.
|
||||||
See also the <varname>DHCPPrefixDelegation=</varname> setting in the [Network] section,
|
See also the <varname>DHCPPrefixDelegation=</varname> setting in the [Network] section,
|
||||||
settings in the [DHCPPrefixDelegation] section, and
|
settings in the [DHCPPrefixDelegation] section, and
|
||||||
<ulink url="https://www.rfc-editor.org/rfc/rfc8415.html#section-6.3">RFC 8415</ulink>.
|
<ulink url="https://www.rfc-editor.org/rfc/rfc8415.html#section-6.3">RFC 8415</ulink>.
|
||||||
@ -4774,6 +4778,7 @@ Xfrm=xfrm0</programlisting>
|
|||||||
<citerefentry><refentrytitle>systemd-networkd.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
|
<citerefentry><refentrytitle>systemd-networkd.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
|
||||||
<citerefentry><refentrytitle>systemd.link</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
|
<citerefentry><refentrytitle>systemd.link</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
|
||||||
<citerefentry><refentrytitle>systemd.netdev</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
|
<citerefentry><refentrytitle>systemd.netdev</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
|
||||||
|
<citerefentry><refentrytitle>systemd-network-generator.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
|
||||||
<citerefentry><refentrytitle>systemd-resolved.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
|
<citerefentry><refentrytitle>systemd-resolved.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
|
||||||
</para>
|
</para>
|
||||||
</refsect1>
|
</refsect1>
|
||||||
|
|||||||
@ -165,7 +165,7 @@
|
|||||||
<term><option>--tree</option></term>
|
<term><option>--tree</option></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>Display a sysfs tree. This recursively iterates through the sysfs hierarchy and displays it
|
<para>Display a sysfs tree. This recursively iterates through the sysfs hierarchy and displays it
|
||||||
in a tree structure. If a path is specified only the subtree below that directory is
|
in a tree structure. If a path is specified only the subtree below and its parent directories are
|
||||||
shown. This will show both device and subsystem items.</para>
|
shown. This will show both device and subsystem items.</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|||||||
24
meson.build
24
meson.build
@ -1452,6 +1452,30 @@ conf.set10('HAVE_ZSTD', have_zstd)
|
|||||||
|
|
||||||
conf.set10('HAVE_COMPRESSION', have_xz or have_lz4 or have_zstd)
|
conf.set10('HAVE_COMPRESSION', have_xz or have_lz4 or have_zstd)
|
||||||
|
|
||||||
|
compression = get_option('default-compression')
|
||||||
|
if compression == 'auto'
|
||||||
|
if have_zstd
|
||||||
|
compression = 'zstd'
|
||||||
|
elif have_lz4
|
||||||
|
compression = 'lz4'
|
||||||
|
elif have_xz
|
||||||
|
compression = 'xz'
|
||||||
|
else
|
||||||
|
compression = 'none'
|
||||||
|
endif
|
||||||
|
elif compression == 'zstd' and not have_zstd
|
||||||
|
error('default-compression=zstd requires zstd')
|
||||||
|
elif compression == 'lz4' and not have_lz4
|
||||||
|
error('default-compression=lz4 requires lz4')
|
||||||
|
elif compression == 'xz' and not have_xz
|
||||||
|
error('default-compression=xz requires xz')
|
||||||
|
endif
|
||||||
|
conf.set('OBJECT_COMPRESSED_NONE', 0)
|
||||||
|
conf.set('OBJECT_COMPRESSED_XZ', 1)
|
||||||
|
conf.set('OBJECT_COMPRESSED_LZ4', 2)
|
||||||
|
conf.set('OBJECT_COMPRESSED_ZSTD', 4)
|
||||||
|
conf.set('DEFAULT_COMPRESSION', 'OBJECT_COMPRESSED_@0@'.format(compression.to_upper()))
|
||||||
|
|
||||||
want_xkbcommon = get_option('xkbcommon')
|
want_xkbcommon = get_option('xkbcommon')
|
||||||
if want_xkbcommon != 'false' and not skip_deps
|
if want_xkbcommon != 'false' and not skip_deps
|
||||||
libxkbcommon = dependency('xkbcommon',
|
libxkbcommon = dependency('xkbcommon',
|
||||||
|
|||||||
@ -411,6 +411,8 @@ option('lz4', type : 'combo', choices : ['auto', 'true', 'false'],
|
|||||||
description : 'lz4 compression support')
|
description : 'lz4 compression support')
|
||||||
option('zstd', type : 'combo', choices : ['auto', 'true', 'false'],
|
option('zstd', type : 'combo', choices : ['auto', 'true', 'false'],
|
||||||
description : 'zstd compression support')
|
description : 'zstd compression support')
|
||||||
|
option('default-compression', type : 'combo', choices : ['auto', 'zstd', 'lz4', 'xz'], value: 'auto',
|
||||||
|
description : 'default compression algorithm')
|
||||||
option('xkbcommon', type : 'combo', choices : ['auto', 'true', 'false'],
|
option('xkbcommon', type : 'combo', choices : ['auto', 'true', 'false'],
|
||||||
description : 'xkbcommon keymap support')
|
description : 'xkbcommon keymap support')
|
||||||
option('pcre2', type : 'combo', choices : ['auto', 'true', 'false'],
|
option('pcre2', type : 'combo', choices : ['auto', 'true', 'false'],
|
||||||
|
|||||||
@ -16,6 +16,7 @@ int device_enumerator_scan_devices(sd_device_enumerator *enumerator);
|
|||||||
int device_enumerator_scan_subsystems(sd_device_enumerator *enumerator);
|
int device_enumerator_scan_subsystems(sd_device_enumerator *enumerator);
|
||||||
int device_enumerator_scan_devices_and_subsystems(sd_device_enumerator *enumerator);
|
int device_enumerator_scan_devices_and_subsystems(sd_device_enumerator *enumerator);
|
||||||
int device_enumerator_add_device(sd_device_enumerator *enumerator, sd_device *device);
|
int device_enumerator_add_device(sd_device_enumerator *enumerator, sd_device *device);
|
||||||
|
int device_enumerator_add_parent_devices(sd_device_enumerator *enumerator, sd_device *device);
|
||||||
int device_enumerator_add_match_is_initialized(sd_device_enumerator *enumerator, MatchInitializedType type);
|
int device_enumerator_add_match_is_initialized(sd_device_enumerator *enumerator, MatchInitializedType type);
|
||||||
int device_enumerator_add_match_parent_incremental(sd_device_enumerator *enumerator, sd_device *parent);
|
int device_enumerator_add_match_parent_incremental(sd_device_enumerator *enumerator, sd_device *parent);
|
||||||
int device_enumerator_add_prioritized_subsystem(sd_device_enumerator *enumerator, const char *subsystem);
|
int device_enumerator_add_prioritized_subsystem(sd_device_enumerator *enumerator, const char *subsystem);
|
||||||
|
|||||||
@ -549,7 +549,8 @@ static int match_initialized(sd_device_enumerator *enumerator, sd_device *device
|
|||||||
|
|
||||||
static int test_matches(
|
static int test_matches(
|
||||||
sd_device_enumerator *enumerator,
|
sd_device_enumerator *enumerator,
|
||||||
sd_device *device) {
|
sd_device *device,
|
||||||
|
bool ignore_parent_match) {
|
||||||
|
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
@ -562,7 +563,8 @@ static int test_matches(
|
|||||||
if (r <= 0)
|
if (r <= 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
if (!device_match_parent(device, enumerator->match_parent, NULL))
|
if (!ignore_parent_match &&
|
||||||
|
!device_match_parent(device, enumerator->match_parent, NULL))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!match_tag(enumerator, device))
|
if (!match_tag(enumerator, device))
|
||||||
@ -599,6 +601,71 @@ static bool match_subsystem(sd_device_enumerator *enumerator, const char *subsys
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int enumerator_add_parent_devices(
|
||||||
|
sd_device_enumerator *enumerator,
|
||||||
|
sd_device *device,
|
||||||
|
bool ignore_parent_match) {
|
||||||
|
|
||||||
|
int k, r = 0;
|
||||||
|
|
||||||
|
assert(enumerator);
|
||||||
|
assert(device);
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
const char *ss, *usn;
|
||||||
|
|
||||||
|
k = sd_device_get_parent(device, &device);
|
||||||
|
if (k == -ENOENT) /* Reached the top? */
|
||||||
|
break;
|
||||||
|
if (k < 0) {
|
||||||
|
r = k;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
k = sd_device_get_subsystem(device, &ss);
|
||||||
|
if (k == -ENOENT) /* Has no subsystem? */
|
||||||
|
continue;
|
||||||
|
if (k < 0) {
|
||||||
|
r = k;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!match_subsystem(enumerator, ss))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
k = sd_device_get_sysname(device, &usn);
|
||||||
|
if (k < 0) {
|
||||||
|
r = k;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!match_sysname(enumerator, usn))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
k = test_matches(enumerator, device, ignore_parent_match);
|
||||||
|
if (k < 0) {
|
||||||
|
r = k;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (k == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
k = device_enumerator_add_device(enumerator, device);
|
||||||
|
if (k < 0) {
|
||||||
|
r = k;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (k == 0) /* Exists already? Then no need to go further up. */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
int device_enumerator_add_parent_devices(sd_device_enumerator *enumerator, sd_device *device) {
|
||||||
|
return enumerator_add_parent_devices(enumerator, device, /* ignore_parent_match = */ true);
|
||||||
|
}
|
||||||
|
|
||||||
static bool relevant_sysfs_subdir(const struct dirent *de) {
|
static bool relevant_sysfs_subdir(const struct dirent *de) {
|
||||||
assert(de);
|
assert(de);
|
||||||
|
|
||||||
@ -639,7 +706,6 @@ static int enumerator_scan_dir_and_add_devices(
|
|||||||
FOREACH_DIRENT_ALL(de, dir, return -errno) {
|
FOREACH_DIRENT_ALL(de, dir, return -errno) {
|
||||||
_cleanup_(sd_device_unrefp) sd_device *device = NULL;
|
_cleanup_(sd_device_unrefp) sd_device *device = NULL;
|
||||||
char syspath[strlen(path) + 1 + strlen(de->d_name) + 1];
|
char syspath[strlen(path) + 1 + strlen(de->d_name) + 1];
|
||||||
sd_device *upwards;
|
|
||||||
|
|
||||||
if (!relevant_sysfs_subdir(de))
|
if (!relevant_sysfs_subdir(de))
|
||||||
continue;
|
continue;
|
||||||
@ -658,7 +724,7 @@ static int enumerator_scan_dir_and_add_devices(
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
k = test_matches(enumerator, device);
|
k = test_matches(enumerator, device, /* ignore_parent_match = */ false);
|
||||||
if (k <= 0) {
|
if (k <= 0) {
|
||||||
if (k < 0)
|
if (k < 0)
|
||||||
r = k;
|
r = k;
|
||||||
@ -672,50 +738,9 @@ static int enumerator_scan_dir_and_add_devices(
|
|||||||
/* Also include all potentially matching parent devices in the enumeration. These are things
|
/* Also include all potentially matching parent devices in the enumeration. These are things
|
||||||
* like root busses — e.g. /sys/devices/pci0000:00/ or /sys/devices/pnp0/, which ar not
|
* like root busses — e.g. /sys/devices/pci0000:00/ or /sys/devices/pnp0/, which ar not
|
||||||
* linked from /sys/class/ or /sys/bus/, hence pick them up explicitly here. */
|
* linked from /sys/class/ or /sys/bus/, hence pick them up explicitly here. */
|
||||||
upwards = device;
|
k = enumerator_add_parent_devices(enumerator, device, /* ignore_parent_match = */ false);
|
||||||
for (;;) {
|
|
||||||
const char *ss, *usn;
|
|
||||||
|
|
||||||
k = sd_device_get_parent(upwards, &upwards);
|
|
||||||
if (k == -ENOENT) /* Reached the top? */
|
|
||||||
break;
|
|
||||||
if (k < 0) {
|
|
||||||
r = k;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
k = sd_device_get_subsystem(upwards, &ss);
|
|
||||||
if (k == -ENOENT) /* Has no subsystem? */
|
|
||||||
continue;
|
|
||||||
if (k < 0) {
|
|
||||||
r = k;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!match_subsystem(enumerator, ss))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
k = sd_device_get_sysname(upwards, &usn);
|
|
||||||
if (k < 0) {
|
|
||||||
r = k;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!match_sysname(enumerator, usn))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
k = test_matches(enumerator, upwards);
|
|
||||||
if (k < 0)
|
|
||||||
break;
|
|
||||||
if (k == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
k = device_enumerator_add_device(enumerator, upwards);
|
|
||||||
if (k < 0)
|
if (k < 0)
|
||||||
r = k;
|
r = k;
|
||||||
else if (k == 0) /* Exists already? Then no need to go further up. */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
|
|||||||
@ -111,7 +111,7 @@ uint64_t device_get_devlinks_generation(sd_device *device) {
|
|||||||
return device->devlinks_generation;
|
return device->devlinks_generation;
|
||||||
}
|
}
|
||||||
|
|
||||||
int device_get_devnode_mode(sd_device *device, mode_t *mode) {
|
int device_get_devnode_mode(sd_device *device, mode_t *ret) {
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(device);
|
assert(device);
|
||||||
@ -123,13 +123,13 @@ int device_get_devnode_mode(sd_device *device, mode_t *mode) {
|
|||||||
if (device->devmode == MODE_INVALID)
|
if (device->devmode == MODE_INVALID)
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
|
|
||||||
if (mode)
|
if (ret)
|
||||||
*mode = device->devmode;
|
*ret = device->devmode;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int device_get_devnode_uid(sd_device *device, uid_t *uid) {
|
int device_get_devnode_uid(sd_device *device, uid_t *ret) {
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(device);
|
assert(device);
|
||||||
@ -141,20 +141,20 @@ int device_get_devnode_uid(sd_device *device, uid_t *uid) {
|
|||||||
if (device->devuid == UID_INVALID)
|
if (device->devuid == UID_INVALID)
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
|
|
||||||
if (uid)
|
if (ret)
|
||||||
*uid = device->devuid;
|
*ret = device->devuid;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int device_set_devuid(sd_device *device, const char *uid) {
|
static int device_set_devuid(sd_device *device, const char *uid) {
|
||||||
unsigned u;
|
uid_t u;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(device);
|
assert(device);
|
||||||
assert(uid);
|
assert(uid);
|
||||||
|
|
||||||
r = safe_atou(uid, &u);
|
r = parse_uid(uid, &u);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
@ -167,7 +167,7 @@ static int device_set_devuid(sd_device *device, const char *uid) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int device_get_devnode_gid(sd_device *device, gid_t *gid) {
|
int device_get_devnode_gid(sd_device *device, gid_t *ret) {
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(device);
|
assert(device);
|
||||||
@ -179,20 +179,20 @@ int device_get_devnode_gid(sd_device *device, gid_t *gid) {
|
|||||||
if (device->devgid == GID_INVALID)
|
if (device->devgid == GID_INVALID)
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
|
|
||||||
if (gid)
|
if (ret)
|
||||||
*gid = device->devgid;
|
*ret = device->devgid;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int device_set_devgid(sd_device *device, const char *gid) {
|
static int device_set_devgid(sd_device *device, const char *gid) {
|
||||||
unsigned g;
|
gid_t g;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(device);
|
assert(device);
|
||||||
assert(gid);
|
assert(gid);
|
||||||
|
|
||||||
r = safe_atou(gid, &g);
|
r = parse_gid(gid, &g);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
@ -593,17 +593,17 @@ int device_get_properties_strv(sd_device *device, char ***strv) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int device_get_devlink_priority(sd_device *device, int *priority) {
|
int device_get_devlink_priority(sd_device *device, int *ret) {
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(device);
|
assert(device);
|
||||||
assert(priority);
|
|
||||||
|
|
||||||
r = device_read_db(device);
|
r = device_read_db(device);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
*priority = device->devlink_priority;
|
if (ret)
|
||||||
|
*ret = device->devlink_priority;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -747,62 +747,72 @@ int device_new_from_watch_handle_at(sd_device **ret, int dirfd, int wd) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int device_rename(sd_device *device, const char *name) {
|
int device_rename(sd_device *device, const char *name) {
|
||||||
_cleanup_free_ char *dirname = NULL;
|
_cleanup_free_ char *new_syspath = NULL;
|
||||||
const char *new_syspath, *interface;
|
const char *interface;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(device);
|
assert(device);
|
||||||
assert(name);
|
assert(name);
|
||||||
|
|
||||||
dirname = dirname_malloc(device->syspath);
|
if (!filename_is_valid(name))
|
||||||
if (!dirname)
|
return -EINVAL;
|
||||||
|
|
||||||
|
r = path_extract_directory(device->syspath, &new_syspath);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
if (!path_extend(&new_syspath, name))
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
new_syspath = prefix_roota(dirname, name);
|
if (!path_is_safe(new_syspath))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
/* the user must trust that the new name is correct */
|
/* At the time this is called, the renamed device may not exist yet. Hence, we cannot validate
|
||||||
|
* the new syspath. */
|
||||||
r = device_set_syspath(device, new_syspath, false);
|
r = device_set_syspath(device, new_syspath, false);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
/* Here, only clear the sysname and sysnum. They will be set when requested. */
|
||||||
|
device->sysnum = NULL;
|
||||||
|
device->sysname = mfree(device->sysname);
|
||||||
|
|
||||||
r = sd_device_get_property_value(device, "INTERFACE", &interface);
|
r = sd_device_get_property_value(device, "INTERFACE", &interface);
|
||||||
if (r >= 0) {
|
if (r == -ENOENT)
|
||||||
|
return 0;
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
/* like DEVPATH_OLD, INTERFACE_OLD is not saved to the db, but only stays around for the current event */
|
/* like DEVPATH_OLD, INTERFACE_OLD is not saved to the db, but only stays around for the current event */
|
||||||
r = device_add_property_internal(device, "INTERFACE_OLD", interface);
|
r = device_add_property_internal(device, "INTERFACE_OLD", interface);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
r = device_add_property_internal(device, "INTERFACE", name);
|
return device_add_property_internal(device, "INTERFACE", name);
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
} else if (r != -ENOENT)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int device_shallow_clone(sd_device *old_device, sd_device **new_device) {
|
int device_shallow_clone(sd_device *device, sd_device **ret) {
|
||||||
_cleanup_(sd_device_unrefp) sd_device *ret = NULL;
|
_cleanup_(sd_device_unrefp) sd_device *dest = NULL;
|
||||||
const char *val;
|
const char *val = NULL;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(old_device);
|
assert(device);
|
||||||
assert(new_device);
|
assert(ret);
|
||||||
|
|
||||||
r = device_new_aux(&ret);
|
r = device_new_aux(&dest);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
r = device_set_syspath(ret, old_device->syspath, false);
|
r = device_set_syspath(dest, device->syspath, false);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
(void) sd_device_get_subsystem(old_device, &val);
|
(void) sd_device_get_subsystem(device, &val);
|
||||||
r = device_set_subsystem(ret, val);
|
r = device_set_subsystem(dest, val);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
if (streq_ptr(val, "drivers")) {
|
if (streq_ptr(val, "drivers")) {
|
||||||
r = free_and_strdup(&ret->driver_subsystem, old_device->driver_subsystem);
|
r = free_and_strdup(&dest->driver_subsystem, device->driver_subsystem);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@ -810,49 +820,47 @@ int device_shallow_clone(sd_device *old_device, sd_device **new_device) {
|
|||||||
/* The device may be already removed. Let's copy minimal set of information to make
|
/* The device may be already removed. Let's copy minimal set of information to make
|
||||||
* device_get_device_id() work without uevent file. */
|
* device_get_device_id() work without uevent file. */
|
||||||
|
|
||||||
if (sd_device_get_property_value(old_device, "IFINDEX", &val) >= 0) {
|
if (sd_device_get_property_value(device, "IFINDEX", &val) >= 0) {
|
||||||
r = device_set_ifindex(ret, val);
|
r = device_set_ifindex(dest, val);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sd_device_get_property_value(old_device, "MAJOR", &val) >= 0) {
|
if (sd_device_get_property_value(device, "MAJOR", &val) >= 0) {
|
||||||
const char *minor = NULL;
|
const char *minor = NULL;
|
||||||
|
|
||||||
(void) sd_device_get_property_value(old_device, "MINOR", &minor);
|
(void) sd_device_get_property_value(device, "MINOR", &minor);
|
||||||
r = device_set_devnum(ret, val, minor);
|
r = device_set_devnum(dest, val, minor);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* And then read uevent file, but ignore errors, as some devices seem to return a spurious
|
r = device_read_uevent_file(dest);
|
||||||
* error on read, e.g. -ENODEV, and even if ifindex or devnum is set in the above,
|
if (r < 0)
|
||||||
* sd_device_get_ifindex() or sd_device_get_devnum() fails. See. #19788. */
|
return r;
|
||||||
(void) device_read_uevent_file(ret);
|
|
||||||
|
|
||||||
*new_device = TAKE_PTR(ret);
|
*ret = TAKE_PTR(dest);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int device_clone_with_db(sd_device *old_device, sd_device **new_device) {
|
int device_clone_with_db(sd_device *device, sd_device **ret) {
|
||||||
_cleanup_(sd_device_unrefp) sd_device *ret = NULL;
|
_cleanup_(sd_device_unrefp) sd_device *dest = NULL;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(old_device);
|
assert(device);
|
||||||
assert(new_device);
|
assert(ret);
|
||||||
|
|
||||||
r = device_shallow_clone(old_device, &ret);
|
r = device_shallow_clone(device, &dest);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
r = device_read_db(ret);
|
r = device_read_db(dest);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
ret->sealed = true;
|
dest->sealed = true;
|
||||||
|
|
||||||
*new_device = TAKE_PTR(ret);
|
|
||||||
|
|
||||||
|
*ret = TAKE_PTR(dest);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -923,15 +931,11 @@ static int device_tag(sd_device *device, const char *tag, bool add) {
|
|||||||
|
|
||||||
path = strjoina("/run/udev/tags/", tag, "/", id);
|
path = strjoina("/run/udev/tags/", tag, "/", id);
|
||||||
|
|
||||||
if (add) {
|
if (add)
|
||||||
r = touch_file(path, true, USEC_INFINITY, UID_INVALID, GID_INVALID, 0444);
|
return touch_file(path, true, USEC_INFINITY, UID_INVALID, GID_INVALID, 0444);
|
||||||
if (r < 0)
|
|
||||||
return r;
|
if (unlink(path) < 0 && errno != ENOENT)
|
||||||
} else {
|
|
||||||
r = unlink(path);
|
|
||||||
if (r < 0 && errno != ENOENT)
|
|
||||||
return -errno;
|
return -errno;
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -940,16 +944,14 @@ int device_tag_index(sd_device *device, sd_device *device_old, bool add) {
|
|||||||
const char *tag;
|
const char *tag;
|
||||||
int r = 0, k;
|
int r = 0, k;
|
||||||
|
|
||||||
if (add && device_old) {
|
if (add && device_old)
|
||||||
/* delete possible left-over tags */
|
/* delete possible left-over tags */
|
||||||
FOREACH_DEVICE_TAG(device_old, tag) {
|
FOREACH_DEVICE_TAG(device_old, tag)
|
||||||
if (!sd_device_has_tag(device, tag)) {
|
if (!sd_device_has_tag(device, tag)) {
|
||||||
k = device_tag(device_old, tag, false);
|
k = device_tag(device_old, tag, false);
|
||||||
if (r >= 0 && k < 0)
|
if (r >= 0 && k < 0)
|
||||||
r = k;
|
r = k;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FOREACH_DEVICE_TAG(device, tag) {
|
FOREACH_DEVICE_TAG(device, tag) {
|
||||||
k = device_tag(device, tag, add);
|
k = device_tag(device, tag, add);
|
||||||
@ -1007,8 +1009,7 @@ int device_update_db(sd_device *device) {
|
|||||||
|
|
||||||
/* do not store anything for otherwise empty devices */
|
/* do not store anything for otherwise empty devices */
|
||||||
if (!has_info && major(device->devnum) == 0 && device->ifindex == 0) {
|
if (!has_info && major(device->devnum) == 0 && device->ifindex == 0) {
|
||||||
r = unlink(path);
|
if (unlink(path) < 0 && errno != ENOENT)
|
||||||
if (r < 0 && errno != ENOENT)
|
|
||||||
return -errno;
|
return -errno;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -1096,8 +1097,7 @@ int device_delete_db(sd_device *device) {
|
|||||||
|
|
||||||
path = strjoina("/run/udev/data/", id);
|
path = strjoina("/run/udev/data/", id);
|
||||||
|
|
||||||
r = unlink(path);
|
if (unlink(path) < 0 && errno != ENOENT)
|
||||||
if (r < 0 && errno != ENOENT)
|
|
||||||
return -errno;
|
return -errno;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@ -18,11 +18,11 @@ static inline int device_new_from_watch_handle(sd_device **ret, int wd) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int device_get_device_id(sd_device *device, const char **ret);
|
int device_get_device_id(sd_device *device, const char **ret);
|
||||||
int device_get_devlink_priority(sd_device *device, int *priority);
|
int device_get_devlink_priority(sd_device *device, int *ret);
|
||||||
int device_get_watch_handle(sd_device *device);
|
int device_get_watch_handle(sd_device *device);
|
||||||
int device_get_devnode_mode(sd_device *device, mode_t *mode);
|
int device_get_devnode_mode(sd_device *device, mode_t *ret);
|
||||||
int device_get_devnode_uid(sd_device *device, uid_t *uid);
|
int device_get_devnode_uid(sd_device *device, uid_t *ret);
|
||||||
int device_get_devnode_gid(sd_device *device, gid_t *gid);
|
int device_get_devnode_gid(sd_device *device, gid_t *ret);
|
||||||
|
|
||||||
int device_cache_sysattr_value(sd_device *device, const char *key, char *value);
|
int device_cache_sysattr_value(sd_device *device, const char *key, char *value);
|
||||||
int device_get_cached_sysattr_value(sd_device *device, const char *key, const char **ret_value);
|
int device_get_cached_sysattr_value(sd_device *device, const char *key, const char **ret_value);
|
||||||
@ -51,8 +51,8 @@ int device_get_properties_nulstr(sd_device *device, const uint8_t **nulstr, size
|
|||||||
int device_get_properties_strv(sd_device *device, char ***strv);
|
int device_get_properties_strv(sd_device *device, char ***strv);
|
||||||
|
|
||||||
int device_rename(sd_device *device, const char *name);
|
int device_rename(sd_device *device, const char *name);
|
||||||
int device_shallow_clone(sd_device *old_device, sd_device **new_device);
|
int device_shallow_clone(sd_device *device, sd_device **ret);
|
||||||
int device_clone_with_db(sd_device *old_device, sd_device **new_device);
|
int device_clone_with_db(sd_device *device, sd_device **ret);
|
||||||
int device_copy_properties(sd_device *device_dst, sd_device *device_src);
|
int device_copy_properties(sd_device *device_dst, sd_device *device_src);
|
||||||
|
|
||||||
int device_tag_index(sd_device *dev, sd_device *dev_old, bool add);
|
int device_tag_index(sd_device *dev, sd_device *dev_old, bool add);
|
||||||
|
|||||||
@ -724,11 +724,14 @@ int device_read_uevent_file(sd_device *device) {
|
|||||||
path = strjoina(syspath, "/uevent");
|
path = strjoina(syspath, "/uevent");
|
||||||
|
|
||||||
r = read_full_virtual_file(path, &uevent, &uevent_len);
|
r = read_full_virtual_file(path, &uevent, &uevent_len);
|
||||||
if (IN_SET(r, -EACCES, -ENOENT))
|
if (r < 0) {
|
||||||
/* The uevent files may be write-only, or the device may not have uevent file. */
|
/* The uevent files may be write-only, the device may be already removed, or the device
|
||||||
|
* may not have the uevent file. */
|
||||||
|
if (r == -EACCES || ERRNO_IS_DEVICE_ABSENT(r))
|
||||||
return 0;
|
return 0;
|
||||||
if (r < 0)
|
|
||||||
return log_device_debug_errno(device, r, "sd-device: Failed to read uevent file '%s': %m", path);
|
return log_device_debug_errno(device, r, "sd-device: Failed to read uevent file '%s': %m", path);
|
||||||
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < uevent_len; i++)
|
for (size_t i = 0; i < uevent_len; i++)
|
||||||
switch (state) {
|
switch (state) {
|
||||||
@ -1437,37 +1440,30 @@ int device_get_device_id(sd_device *device, const char **ret) {
|
|||||||
return r;
|
return r;
|
||||||
|
|
||||||
if (sd_device_get_devnum(device, &devnum) >= 0) {
|
if (sd_device_get_devnum(device, &devnum) >= 0) {
|
||||||
assert(subsystem);
|
|
||||||
|
|
||||||
/* use dev_t — b259:131072, c254:0 */
|
/* use dev_t — b259:131072, c254:0 */
|
||||||
r = asprintf(&id, "%c%u:%u",
|
if (asprintf(&id, "%c%u:%u",
|
||||||
streq(subsystem, "block") ? 'b' : 'c',
|
streq(subsystem, "block") ? 'b' : 'c',
|
||||||
major(devnum), minor(devnum));
|
major(devnum), minor(devnum)) < 0)
|
||||||
if (r < 0)
|
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
} else if (sd_device_get_ifindex(device, &ifindex) >= 0) {
|
} else if (sd_device_get_ifindex(device, &ifindex) >= 0) {
|
||||||
/* use netdev ifindex — n3 */
|
/* use netdev ifindex — n3 */
|
||||||
r = asprintf(&id, "n%u", (unsigned) ifindex);
|
if (asprintf(&id, "n%u", (unsigned) ifindex) < 0)
|
||||||
if (r < 0)
|
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
} else {
|
} else {
|
||||||
|
_cleanup_free_ char *sysname = NULL;
|
||||||
|
|
||||||
/* use $subsys:$sysname — pci:0000:00:1f.2
|
/* use $subsys:$sysname — pci:0000:00:1f.2
|
||||||
* sysname() has '!' translated, get it from devpath
|
* sd_device_get_sysname() has '!' translated, get it from devpath */
|
||||||
*/
|
r = path_extract_filename(device->devpath, &sysname);
|
||||||
const char *sysname;
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
sysname = basename(device->devpath);
|
if (streq(subsystem, "drivers")) {
|
||||||
if (!sysname)
|
/* the 'drivers' pseudo-subsystem is special, and needs the real
|
||||||
return -EINVAL;
|
* subsystem encoded as well */
|
||||||
|
assert(device->driver_subsystem);
|
||||||
if (!subsystem)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
if (streq(subsystem, "drivers"))
|
|
||||||
/* the 'drivers' pseudo-subsystem is special, and needs the real subsystem
|
|
||||||
* encoded as well */
|
|
||||||
id = strjoin("+drivers:", device->driver_subsystem, ":", sysname);
|
id = strjoin("+drivers:", device->driver_subsystem, ":", sysname);
|
||||||
else
|
} else
|
||||||
id = strjoin("+", subsystem, ":", sysname);
|
id = strjoin("+", subsystem, ":", sysname);
|
||||||
if (!id)
|
if (!id)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|||||||
@ -18,15 +18,15 @@ int compress_blob_zstd(const void *src, uint64_t src_size,
|
|||||||
static inline int compress_blob(const void *src, uint64_t src_size,
|
static inline int compress_blob(const void *src, uint64_t src_size,
|
||||||
void *dst, size_t dst_alloc_size, size_t *dst_size) {
|
void *dst, size_t dst_alloc_size, size_t *dst_size) {
|
||||||
int r;
|
int r;
|
||||||
#if HAVE_ZSTD
|
#if DEFAULT_COMPRESSION == OBJECT_COMPRESSED_ZSTD
|
||||||
r = compress_blob_zstd(src, src_size, dst, dst_alloc_size, dst_size);
|
r = compress_blob_zstd(src, src_size, dst, dst_alloc_size, dst_size);
|
||||||
if (r == 0)
|
if (r == 0)
|
||||||
return OBJECT_COMPRESSED_ZSTD;
|
return OBJECT_COMPRESSED_ZSTD;
|
||||||
#elif HAVE_LZ4
|
#elif DEFAULT_COMPRESSION == OBJECT_COMPRESSED_LZ4
|
||||||
r = compress_blob_lz4(src, src_size, dst, dst_alloc_size, dst_size);
|
r = compress_blob_lz4(src, src_size, dst, dst_alloc_size, dst_size);
|
||||||
if (r == 0)
|
if (r == 0)
|
||||||
return OBJECT_COMPRESSED_LZ4;
|
return OBJECT_COMPRESSED_LZ4;
|
||||||
#elif HAVE_XZ
|
#elif DEFAULT_COMPRESSION == OBJECT_COMPRESSED_XZ
|
||||||
r = compress_blob_xz(src, src_size, dst, dst_alloc_size, dst_size);
|
r = compress_blob_xz(src, src_size, dst, dst_alloc_size, dst_size);
|
||||||
if (r == 0)
|
if (r == 0)
|
||||||
return OBJECT_COMPRESSED_XZ;
|
return OBJECT_COMPRESSED_XZ;
|
||||||
@ -72,13 +72,13 @@ int decompress_stream_xz(int fdf, int fdt, uint64_t max_size);
|
|||||||
int decompress_stream_lz4(int fdf, int fdt, uint64_t max_size);
|
int decompress_stream_lz4(int fdf, int fdt, uint64_t max_size);
|
||||||
int decompress_stream_zstd(int fdf, int fdt, uint64_t max_size);
|
int decompress_stream_zstd(int fdf, int fdt, uint64_t max_size);
|
||||||
|
|
||||||
#if HAVE_ZSTD
|
#if DEFAULT_COMPRESSION == OBJECT_COMPRESSED_ZSTD
|
||||||
# define compress_stream compress_stream_zstd
|
# define compress_stream compress_stream_zstd
|
||||||
# define COMPRESSED_EXT ".zst"
|
# define COMPRESSED_EXT ".zst"
|
||||||
#elif HAVE_LZ4
|
#elif DEFAULT_COMPRESSION == OBJECT_COMPRESSED_LZ4
|
||||||
# define compress_stream compress_stream_lz4
|
# define compress_stream compress_stream_lz4
|
||||||
# define COMPRESSED_EXT ".lz4"
|
# define COMPRESSED_EXT ".lz4"
|
||||||
#elif HAVE_XZ
|
#elif DEFAULT_COMPRESSION == OBJECT_COMPRESSED_XZ
|
||||||
# define compress_stream compress_stream_xz
|
# define compress_stream compress_stream_xz
|
||||||
# define COMPRESSED_EXT ".xz"
|
# define COMPRESSED_EXT ".xz"
|
||||||
#else
|
#else
|
||||||
|
|||||||
@ -42,11 +42,9 @@ typedef enum ObjectType {
|
|||||||
_OBJECT_TYPE_MAX
|
_OBJECT_TYPE_MAX
|
||||||
} ObjectType;
|
} ObjectType;
|
||||||
|
|
||||||
/* Object flags */
|
/* Object flags
|
||||||
|
* The per-compression enums are defined in meson.build so that config.h is self-contained */
|
||||||
enum {
|
enum {
|
||||||
OBJECT_COMPRESSED_XZ = 1 << 0,
|
|
||||||
OBJECT_COMPRESSED_LZ4 = 1 << 1,
|
|
||||||
OBJECT_COMPRESSED_ZSTD = 1 << 2,
|
|
||||||
OBJECT_COMPRESSION_MASK = (OBJECT_COMPRESSED_XZ | OBJECT_COMPRESSED_LZ4 | OBJECT_COMPRESSED_ZSTD),
|
OBJECT_COMPRESSION_MASK = (OBJECT_COMPRESSED_XZ | OBJECT_COMPRESSED_LZ4 | OBJECT_COMPRESSED_ZSTD),
|
||||||
_OBJECT_COMPRESSED_MAX = OBJECT_COMPRESSION_MASK,
|
_OBJECT_COMPRESSED_MAX = OBJECT_COMPRESSION_MASK,
|
||||||
};
|
};
|
||||||
|
|||||||
@ -3359,11 +3359,11 @@ int journal_file_open(
|
|||||||
.open_flags = open_flags,
|
.open_flags = open_flags,
|
||||||
.writable = (open_flags & O_ACCMODE) != O_RDONLY,
|
.writable = (open_flags & O_ACCMODE) != O_RDONLY,
|
||||||
|
|
||||||
#if HAVE_ZSTD
|
#if DEFAULT_COMPRESSION == OBJECT_COMPRESSED_ZSTD
|
||||||
.compress_zstd = FLAGS_SET(file_flags, JOURNAL_COMPRESS),
|
.compress_zstd = FLAGS_SET(file_flags, JOURNAL_COMPRESS),
|
||||||
#elif HAVE_LZ4
|
#elif DEFAULT_COMPRESSION == OBJECT_COMPRESSED_LZ4
|
||||||
.compress_lz4 = FLAGS_SET(file_flags, JOURNAL_COMPRESS),
|
.compress_lz4 = FLAGS_SET(file_flags, JOURNAL_COMPRESS),
|
||||||
#elif HAVE_XZ
|
#elif DEFAULT_COMPRESSION == OBJECT_COMPRESSED_XZ
|
||||||
.compress_xz = FLAGS_SET(file_flags, JOURNAL_COMPRESS),
|
.compress_xz = FLAGS_SET(file_flags, JOURNAL_COMPRESS),
|
||||||
#endif
|
#endif
|
||||||
.compress_threshold_bytes = compress_threshold_bytes == UINT64_MAX ?
|
.compress_threshold_bytes = compress_threshold_bytes == UINT64_MAX ?
|
||||||
|
|||||||
@ -486,7 +486,8 @@ int config_parse_l2tp_tunnel_local_address(
|
|||||||
L2tpLocalAddressType type;
|
L2tpLocalAddressType type;
|
||||||
L2tpTunnel *t = userdata;
|
L2tpTunnel *t = userdata;
|
||||||
const char *p = rvalue;
|
const char *p = rvalue;
|
||||||
int r;
|
union in_addr_union a;
|
||||||
|
int r, f;
|
||||||
|
|
||||||
assert(filename);
|
assert(filename);
|
||||||
assert(lvalue);
|
assert(lvalue);
|
||||||
@ -539,16 +540,27 @@ int config_parse_l2tp_tunnel_local_address(
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (t->family == AF_UNSPEC)
|
r = in_addr_from_string_auto(rvalue, &f, &a);
|
||||||
r = in_addr_from_string_auto(rvalue, &t->family, &t->local);
|
|
||||||
else
|
|
||||||
r = in_addr_from_string(t->family, rvalue, &t->local);
|
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||||
"Invalid L2TP Tunnel address specified in %s=, ignoring assignment: %s", lvalue, rvalue);
|
"Invalid L2TP Tunnel local address specified, ignoring assignment: %s", rvalue);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (in_addr_is_null(f, &a)) {
|
||||||
|
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||||
|
"L2TP Tunnel local address cannot be null, ignoring assignment: %s", rvalue);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (t->family != AF_UNSPEC && t->family != f) {
|
||||||
|
log_syntax(unit, LOG_WARNING, filename, line, 0,
|
||||||
|
"Address family does not match the previous assignment, ignoring assignment: %s", rvalue);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
t->family = f;
|
||||||
|
t->local = a;
|
||||||
free_and_replace(t->local_ifname, ifname);
|
free_and_replace(t->local_ifname, ifname);
|
||||||
t->local_address_type = _NETDEV_L2TP_LOCAL_ADDRESS_INVALID;
|
t->local_address_type = _NETDEV_L2TP_LOCAL_ADDRESS_INVALID;
|
||||||
return 0;
|
return 0;
|
||||||
@ -567,7 +579,8 @@ int config_parse_l2tp_tunnel_remote_address(
|
|||||||
void *userdata) {
|
void *userdata) {
|
||||||
|
|
||||||
L2tpTunnel *t = userdata;
|
L2tpTunnel *t = userdata;
|
||||||
int r;
|
union in_addr_union a;
|
||||||
|
int r, f;
|
||||||
|
|
||||||
assert(filename);
|
assert(filename);
|
||||||
assert(lvalue);
|
assert(lvalue);
|
||||||
@ -584,16 +597,27 @@ int config_parse_l2tp_tunnel_remote_address(
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (t->family == AF_UNSPEC)
|
r = in_addr_from_string_auto(rvalue, &f, &a);
|
||||||
r = in_addr_from_string_auto(rvalue, &t->family, &t->remote);
|
|
||||||
else
|
|
||||||
r = in_addr_from_string(t->family, rvalue, &t->remote);
|
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||||
"Invalid L2TP Tunnel address specified in %s=, ignoring assignment: %s", lvalue, rvalue);
|
"Invalid L2TP Tunnel remote address specified, ignoring assignment: %s", rvalue);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (in_addr_is_null(f, &a)) {
|
||||||
|
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||||
|
"L2TP Tunnel remote address cannot be null, ignoring assignment: %s", rvalue);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (t->family != AF_UNSPEC && t->family != f) {
|
||||||
|
log_syntax(unit, LOG_WARNING, filename, line, 0,
|
||||||
|
"Address family does not match the previous assignment, ignoring assignment: %s", rvalue);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
t->family = f;
|
||||||
|
t->remote = a;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -7,6 +7,7 @@
|
|||||||
#include <linux/ip.h>
|
#include <linux/ip.h>
|
||||||
#include <linux/ip6_tunnel.h>
|
#include <linux/ip6_tunnel.h>
|
||||||
|
|
||||||
|
#include "af-list.h"
|
||||||
#include "conf-parser.h"
|
#include "conf-parser.h"
|
||||||
#include "hexdecoct.h"
|
#include "hexdecoct.h"
|
||||||
#include "missing_network.h"
|
#include "missing_network.h"
|
||||||
@ -737,6 +738,20 @@ static int netdev_tunnel_verify(NetDev *netdev, const char *filename) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int unset_local(Tunnel *t) {
|
||||||
|
assert(t);
|
||||||
|
|
||||||
|
/* Unset the previous assignment. */
|
||||||
|
t->local = IN_ADDR_NULL;
|
||||||
|
t->local_type = _NETDEV_LOCAL_ADDRESS_TYPE_INVALID;
|
||||||
|
|
||||||
|
/* If the remote address is not specified, also clear the address family. */
|
||||||
|
if (!in_addr_is_set(t->family, &t->remote))
|
||||||
|
t->family = AF_UNSPEC;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int config_parse_tunnel_local_address(
|
int config_parse_tunnel_local_address(
|
||||||
const char *unit,
|
const char *unit,
|
||||||
const char *filename,
|
const char *filename,
|
||||||
@ -759,16 +774,8 @@ int config_parse_tunnel_local_address(
|
|||||||
assert(rvalue);
|
assert(rvalue);
|
||||||
assert(userdata);
|
assert(userdata);
|
||||||
|
|
||||||
if (isempty(rvalue) || streq(rvalue, "any")) {
|
if (isempty(rvalue) || streq(rvalue, "any"))
|
||||||
/* Unset the previous assignment. */
|
return unset_local(t);
|
||||||
t->local = IN_ADDR_NULL;
|
|
||||||
t->local_type = _NETDEV_LOCAL_ADDRESS_TYPE_INVALID;
|
|
||||||
|
|
||||||
/* If the remote address is not specified, also clear the address family. */
|
|
||||||
if (!in_addr_is_set(t->family, &t->remote))
|
|
||||||
t->family = AF_UNSPEC;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
type = netdev_local_address_type_from_string(rvalue);
|
type = netdev_local_address_type_from_string(rvalue);
|
||||||
if (IN_SET(type, NETDEV_LOCAL_ADDRESS_IPV4LL, NETDEV_LOCAL_ADDRESS_DHCP4))
|
if (IN_SET(type, NETDEV_LOCAL_ADDRESS_IPV4LL, NETDEV_LOCAL_ADDRESS_DHCP4))
|
||||||
@ -783,6 +790,9 @@ int config_parse_tunnel_local_address(
|
|||||||
"Tunnel address \"%s\" invalid, ignoring assignment: %m", rvalue);
|
"Tunnel address \"%s\" invalid, ignoring assignment: %m", rvalue);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (in_addr_is_null(f, &buffer))
|
||||||
|
return unset_local(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (t->family != AF_UNSPEC && t->family != f) {
|
if (t->family != AF_UNSPEC && t->family != f) {
|
||||||
@ -797,6 +807,20 @@ int config_parse_tunnel_local_address(
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int unset_remote(Tunnel *t) {
|
||||||
|
assert(t);
|
||||||
|
|
||||||
|
/* Unset the previous assignment. */
|
||||||
|
t->remote = IN_ADDR_NULL;
|
||||||
|
|
||||||
|
/* If the local address is not specified, also clear the address family. */
|
||||||
|
if (t->local_type == _NETDEV_LOCAL_ADDRESS_TYPE_INVALID &&
|
||||||
|
!in_addr_is_set(t->family, &t->local))
|
||||||
|
t->family = AF_UNSPEC;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int config_parse_tunnel_remote_address(
|
int config_parse_tunnel_remote_address(
|
||||||
const char *unit,
|
const char *unit,
|
||||||
const char *filename,
|
const char *filename,
|
||||||
@ -818,16 +842,8 @@ int config_parse_tunnel_remote_address(
|
|||||||
assert(rvalue);
|
assert(rvalue);
|
||||||
assert(userdata);
|
assert(userdata);
|
||||||
|
|
||||||
if (isempty(rvalue) || streq(rvalue, "any")) {
|
if (isempty(rvalue) || streq(rvalue, "any"))
|
||||||
/* Unset the previous assignment. */
|
return unset_remote(t);
|
||||||
t->remote = IN_ADDR_NULL;
|
|
||||||
|
|
||||||
/* If the local address is not specified, also clear the address family. */
|
|
||||||
if (t->local_type == _NETDEV_LOCAL_ADDRESS_TYPE_INVALID &&
|
|
||||||
!in_addr_is_set(t->family, &t->local))
|
|
||||||
t->family = AF_UNSPEC;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
r = in_addr_from_string_auto(rvalue, &f, &buffer);
|
r = in_addr_from_string_auto(rvalue, &f, &buffer);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
@ -836,6 +852,9 @@ int config_parse_tunnel_remote_address(
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (in_addr_is_null(f, &buffer))
|
||||||
|
return unset_remote(t);
|
||||||
|
|
||||||
if (t->family != AF_UNSPEC && t->family != f) {
|
if (t->family != AF_UNSPEC && t->family != f) {
|
||||||
log_syntax(unit, LOG_WARNING, filename, line, 0,
|
log_syntax(unit, LOG_WARNING, filename, line, 0,
|
||||||
"Address family does not match the previous assignment, ignoring assignment: %s", rvalue);
|
"Address family does not match the previous assignment, ignoring assignment: %s", rvalue);
|
||||||
|
|||||||
@ -60,7 +60,7 @@ bool dns_type_is_pseudo(uint16_t type) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool dns_class_is_pseudo(uint16_t class) {
|
bool dns_class_is_pseudo(uint16_t class) {
|
||||||
return class == DNS_TYPE_ANY;
|
return class == DNS_CLASS_ANY;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool dns_type_is_valid_query(uint16_t type) {
|
bool dns_type_is_valid_query(uint16_t type) {
|
||||||
|
|||||||
@ -869,15 +869,21 @@ int udev_event_spawn(
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int rename_netif(UdevEvent *event) {
|
static int rename_netif(UdevEvent *event) {
|
||||||
sd_device *dev = event->dev;
|
|
||||||
const char *oldname;
|
const char *oldname;
|
||||||
|
sd_device *dev;
|
||||||
unsigned flags;
|
unsigned flags;
|
||||||
int ifindex, r;
|
int ifindex, r;
|
||||||
|
|
||||||
|
assert(event);
|
||||||
|
|
||||||
if (!event->name)
|
if (!event->name)
|
||||||
return 0; /* No new name is requested. */
|
return 0; /* No new name is requested. */
|
||||||
|
|
||||||
r = sd_device_get_sysname(dev, &oldname);
|
dev = ASSERT_PTR(event->dev);
|
||||||
|
|
||||||
|
/* Read sysname from cloned sd-device object, otherwise use-after-free is triggered, as the
|
||||||
|
* main object will be renamed and dev->sysname will be freed in device_rename(). */
|
||||||
|
r = sd_device_get_sysname(event->dev_db_clone, &oldname);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_device_error_errno(dev, r, "Failed to get sysname: %m");
|
return log_device_error_errno(dev, r, "Failed to get sysname: %m");
|
||||||
|
|
||||||
|
|||||||
@ -637,6 +637,13 @@ static int print_tree(sd_device* below) {
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_error_errno(r, "Failed to scan for devices and subsystems: %m");
|
return log_error_errno(r, "Failed to scan for devices and subsystems: %m");
|
||||||
|
|
||||||
|
if (below) {
|
||||||
|
/* This must be called after device_enumerator_scan_devices_and_subsystems(). */
|
||||||
|
r = device_enumerator_add_parent_devices(e, below);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to add parent devices: %m");
|
||||||
|
}
|
||||||
|
|
||||||
assert_se(array = device_enumerator_get_devices(e, &n));
|
assert_se(array = device_enumerator_get_devices(e, &n));
|
||||||
|
|
||||||
if (n == 0) {
|
if (n == 0) {
|
||||||
|
|||||||
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user