1
0
mirror of https://github.com/systemd/systemd synced 2026-04-25 16:34:50 +02:00

Compare commits

..

20 Commits

Author SHA1 Message Date
Yu Watanabe
b0c3d2b76b
Merge pull request #23107 from yuwata/man-network-numeric-prefix
man: recommend that .network or friends should have a numeric prefix
2022-04-18 07:02:10 +09:00
Yu Watanabe
915774ecb8
Merge pull request #23101 from yuwata/sd-device-cleanups
sd-device: several cleanups
2022-04-18 07:01:42 +09:00
Yu Watanabe
98e5a6c93c resolve: fix typo in dns_class_is_pseudo() 2022-04-18 07:01:17 +09:00
Luca Boccassi
cd3c6322db compression: add build-time option to select default
Compression and decompression are controlled by the same build flag,
so if one wants to use, say, LZ4 to compress, ZSTD has to be disabled,
which means one loses the ability to read zstd-compressed journals.

Add a default-compression meson option, that allows to select any of
the available compression algorithms as the default.
2022-04-18 05:43:59 +09:00
Yu Watanabe
23d20adc05 sd-device: rename arguments and variables 2022-04-18 04:34:14 +09:00
Yu Watanabe
9c5d7151c1 sd-device: fix possible use-of-uninitialized-value 2022-04-18 04:34:14 +09:00
Yu Watanabe
17761fb3bf sd-device: use ERRNO_IS_DEVICE_ABSENT() at one more place 2022-04-18 04:34:14 +09:00
Yu Watanabe
d82827a107 sd-device: rename function arguments for storing results 2022-04-18 04:34:14 +09:00
Yu Watanabe
c77c1cc201 sd-device: use correct type and parser for device node uid and gid 2022-04-18 04:34:14 +09:00
Yu Watanabe
d37c69c1bf sd-device: shorten code a bit 2022-04-18 04:34:14 +09:00
Yu Watanabe
ce1d08ba94 sd-device: use path_extract_filename() at one more place
This also does several cleanups.
2022-04-18 04:34:14 +09:00
Yu Watanabe
60e50fb20d sd-device: reset sysname and sysnum on renaming 2022-04-18 04:34:14 +09:00
Yu Watanabe
f5a75f2027 sd-device: reduce indentation 2022-04-18 04:34:14 +09:00
Yu Watanabe
ff58f2ae2a sd-device: verify new syspath on renaming 2022-04-18 04:34:14 +09:00
Yu Watanabe
625d71b9ae man: DHCPPrefixDelegation= needs to be enabled on downstream side for assigning delegated prefixes
Closes #23041.
2022-04-18 04:30:56 +09:00
Yu Watanabe
cc9b6bdc96 man: recommend that .network or friends should have a numeric prefix
Closes #23105.
2022-04-18 04:30:49 +09:00
Yu Watanabe
bd4297e761 udevadm: info: also show parent devices by --tree 2022-04-17 21:27:33 +02:00
Luca Boccassi
ee5b175b8c
Merge pull request #23100 from yuwata/network-fix-tunnel-address-parser
network: fix tunnel address parser
2022-04-17 21:24:38 +02:00
Yu Watanabe
5984b92726 network: l2tp: refuse null address 2022-04-17 09:31:35 +09:00
Yu Watanabe
96d96ec4e7 network: tunnel: handle null address as "any"
Fixes oss-fuzz#44881 (https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=44881).

Fixes #23098.
2022-04-17 09:31:30 +09:00
20 changed files with 359 additions and 239 deletions

View File

@ -32,15 +32,19 @@
<citerefentry><refentrytitle>systemd.syntax</refentrytitle><manvolnum>7</manvolnum></citerefentry> for a
general description of the syntax.</para>
<para>The link files are read from the files located in the system network directory
<filename>/usr/lib/systemd/network</filename>, the volatile runtime network directory
<para>The <filename>.link</filename> files are read from the files located in the system network
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>/etc/systemd/network</filename>. Link files must have the extension
<filename>.link</filename>; other extensions are ignored. All link files are collectively sorted
and processed in lexical order, regardless of the directories in which they live. However, files
with identical filenames replace each other. 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
<filename>/etc/systemd/network</filename>. All configuration files are collectively sorted and
processed in alphanumeric 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
a number (e.g. <filename>10-eth0.link</filename>). Otherwise, the default
<filename>.link</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
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
pointing to <filename>/dev/null</filename> disables the configuration file entirely (it is
"masked").</para>
@ -71,13 +75,13 @@
<refsect1>
<title>[Match] Section Options</title>
<para>A link file is said to match a device if all matches specified by the
[Match] section are satisfied. When a link file does not contain valid settings
in [Match] section, then the file will match all devices and
<command>systemd-udevd</command> warns about that. Hint: to avoid the warning and to make it clear
that all interfaces shall be matched, add the following:
<para>A link file is said to match an interface if all matches specified by the [Match] section are
satisfied. When a link file does not contain valid settings in [Match] section, then the file will
match all interfaces and <command>systemd-udevd</command> warns about that. Hint: to avoid the
warning and to make it clear that all interfaces shall be matched, add the following:
<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'>
<!-- 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>
<refentrytitle>systemd.network</refentrytitle><manvolnum>5</manvolnum>
</citerefentry>,
<citerefentry>
<refentrytitle>systemd-network-generator.service</refentrytitle><manvolnum>8</manvolnum>
</citerefentry>
</para>
</refsect1>

View File

@ -39,17 +39,22 @@
than create its own. Note that the settings of the pre-existing netdev will not be changed by
networkd.</para>
<para>The <filename>.netdev</filename> files are read from the files located in the system
network directory <filename>/usr/lib/systemd/network</filename>, the volatile runtime 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 processed in lexical order, regardless of the directories in which they live.
However, files with identical filenames replace each other. 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>The <filename>.netdev</filename> files are read from the files located in the system network
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>/etc/systemd/network</filename>. All configuration files are collectively sorted and
processed in alphanumeric 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
a number (e.g. <filename>10-vlan.netdev</filename>). Otherwise, <filename>.netdev</filename> files
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
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
<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-networkd</refentrytitle><manvolnum>8</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>
</refsect1>

View File

@ -42,8 +42,12 @@
<filename>/usr/local/lib/systemd/network</filename>, the volatile runtime 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
processed in lexical order, regardless of the directories in which they live. However, files with
identical filenames replace each other. Files in <filename>/etc/</filename> have the highest
processed in alphanumeric 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
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
<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
@ -69,9 +73,9 @@
<title>[Match] Section Options</title>
<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
configured. The first (in lexical order) of the network files that matches a given device is
applied, all later files are ignored, even if they match as well.</para>
be applied to a given interface; and a [Network] section specifying how the interface should be
configured. The first (in alphanumeric order) of the network files that matches a given interface
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]
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>
<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
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,
settings in the [DHCPPrefixDelegation] section, and
<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.link</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>
</para>
</refsect1>

View File

@ -165,7 +165,7 @@
<term><option>--tree</option></term>
<listitem>
<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>
</listitem>
</varlistentry>

View File

@ -1452,6 +1452,30 @@ conf.set10('HAVE_ZSTD', 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')
if want_xkbcommon != 'false' and not skip_deps
libxkbcommon = dependency('xkbcommon',

View File

@ -411,6 +411,8 @@ option('lz4', type : 'combo', choices : ['auto', 'true', 'false'],
description : 'lz4 compression support')
option('zstd', type : 'combo', choices : ['auto', 'true', 'false'],
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'],
description : 'xkbcommon keymap support')
option('pcre2', type : 'combo', choices : ['auto', 'true', 'false'],

View File

@ -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_devices_and_subsystems(sd_device_enumerator *enumerator);
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_parent_incremental(sd_device_enumerator *enumerator, sd_device *parent);
int device_enumerator_add_prioritized_subsystem(sd_device_enumerator *enumerator, const char *subsystem);

View File

@ -549,7 +549,8 @@ static int match_initialized(sd_device_enumerator *enumerator, sd_device *device
static int test_matches(
sd_device_enumerator *enumerator,
sd_device *device) {
sd_device *device,
bool ignore_parent_match) {
int r;
@ -562,7 +563,8 @@ static int test_matches(
if (r <= 0)
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;
if (!match_tag(enumerator, device))
@ -599,6 +601,71 @@ static bool match_subsystem(sd_device_enumerator *enumerator, const char *subsys
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) {
assert(de);
@ -639,7 +706,6 @@ static int enumerator_scan_dir_and_add_devices(
FOREACH_DIRENT_ALL(de, dir, return -errno) {
_cleanup_(sd_device_unrefp) sd_device *device = NULL;
char syspath[strlen(path) + 1 + strlen(de->d_name) + 1];
sd_device *upwards;
if (!relevant_sysfs_subdir(de))
continue;
@ -658,7 +724,7 @@ static int enumerator_scan_dir_and_add_devices(
continue;
}
k = test_matches(enumerator, device);
k = test_matches(enumerator, device, /* ignore_parent_match = */ false);
if (k <= 0) {
if (k < 0)
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
* 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. */
upwards = device;
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);
k = enumerator_add_parent_devices(enumerator, device, /* ignore_parent_match = */ false);
if (k < 0)
r = k;
else if (k == 0) /* Exists already? Then no need to go further up. */
break;
}
}
return r;

View File

@ -111,7 +111,7 @@ uint64_t device_get_devlinks_generation(sd_device *device) {
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;
assert(device);
@ -123,13 +123,13 @@ int device_get_devnode_mode(sd_device *device, mode_t *mode) {
if (device->devmode == MODE_INVALID)
return -ENOENT;
if (mode)
*mode = device->devmode;
if (ret)
*ret = device->devmode;
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;
assert(device);
@ -141,20 +141,20 @@ int device_get_devnode_uid(sd_device *device, uid_t *uid) {
if (device->devuid == UID_INVALID)
return -ENOENT;
if (uid)
*uid = device->devuid;
if (ret)
*ret = device->devuid;
return 0;
}
static int device_set_devuid(sd_device *device, const char *uid) {
unsigned u;
uid_t u;
int r;
assert(device);
assert(uid);
r = safe_atou(uid, &u);
r = parse_uid(uid, &u);
if (r < 0)
return r;
@ -167,7 +167,7 @@ static int device_set_devuid(sd_device *device, const char *uid) {
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;
assert(device);
@ -179,20 +179,20 @@ int device_get_devnode_gid(sd_device *device, gid_t *gid) {
if (device->devgid == GID_INVALID)
return -ENOENT;
if (gid)
*gid = device->devgid;
if (ret)
*ret = device->devgid;
return 0;
}
static int device_set_devgid(sd_device *device, const char *gid) {
unsigned g;
gid_t g;
int r;
assert(device);
assert(gid);
r = safe_atou(gid, &g);
r = parse_gid(gid, &g);
if (r < 0)
return r;
@ -593,17 +593,17 @@ int device_get_properties_strv(sd_device *device, char ***strv) {
return 0;
}
int device_get_devlink_priority(sd_device *device, int *priority) {
int device_get_devlink_priority(sd_device *device, int *ret) {
int r;
assert(device);
assert(priority);
r = device_read_db(device);
if (r < 0)
return r;
*priority = device->devlink_priority;
if (ret)
*ret = device->devlink_priority;
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) {
_cleanup_free_ char *dirname = NULL;
const char *new_syspath, *interface;
_cleanup_free_ char *new_syspath = NULL;
const char *interface;
int r;
assert(device);
assert(name);
dirname = dirname_malloc(device->syspath);
if (!dirname)
if (!filename_is_valid(name))
return -EINVAL;
r = path_extract_directory(device->syspath, &new_syspath);
if (r < 0)
return r;
if (!path_extend(&new_syspath, name))
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);
if (r < 0)
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);
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 */
r = device_add_property_internal(device, "INTERFACE_OLD", interface);
if (r < 0)
return r;
r = device_add_property_internal(device, "INTERFACE", name);
if (r < 0)
return r;
} else if (r != -ENOENT)
return r;
return 0;
return device_add_property_internal(device, "INTERFACE", name);
}
int device_shallow_clone(sd_device *old_device, sd_device **new_device) {
_cleanup_(sd_device_unrefp) sd_device *ret = NULL;
const char *val;
int device_shallow_clone(sd_device *device, sd_device **ret) {
_cleanup_(sd_device_unrefp) sd_device *dest = NULL;
const char *val = NULL;
int r;
assert(old_device);
assert(new_device);
assert(device);
assert(ret);
r = device_new_aux(&ret);
r = device_new_aux(&dest);
if (r < 0)
return r;
r = device_set_syspath(ret, old_device->syspath, false);
r = device_set_syspath(dest, device->syspath, false);
if (r < 0)
return r;
(void) sd_device_get_subsystem(old_device, &val);
r = device_set_subsystem(ret, val);
(void) sd_device_get_subsystem(device, &val);
r = device_set_subsystem(dest, val);
if (r < 0)
return r;
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)
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
* device_get_device_id() work without uevent file. */
if (sd_device_get_property_value(old_device, "IFINDEX", &val) >= 0) {
r = device_set_ifindex(ret, val);
if (sd_device_get_property_value(device, "IFINDEX", &val) >= 0) {
r = device_set_ifindex(dest, val);
if (r < 0)
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;
(void) sd_device_get_property_value(old_device, "MINOR", &minor);
r = device_set_devnum(ret, val, minor);
(void) sd_device_get_property_value(device, "MINOR", &minor);
r = device_set_devnum(dest, val, minor);
if (r < 0)
return r;
}
/* And then read uevent file, but ignore errors, as some devices seem to return a spurious
* error on read, e.g. -ENODEV, and even if ifindex or devnum is set in the above,
* sd_device_get_ifindex() or sd_device_get_devnum() fails. See. #19788. */
(void) device_read_uevent_file(ret);
r = device_read_uevent_file(dest);
if (r < 0)
return r;
*new_device = TAKE_PTR(ret);
*ret = TAKE_PTR(dest);
return 0;
}
int device_clone_with_db(sd_device *old_device, sd_device **new_device) {
_cleanup_(sd_device_unrefp) sd_device *ret = NULL;
int device_clone_with_db(sd_device *device, sd_device **ret) {
_cleanup_(sd_device_unrefp) sd_device *dest = NULL;
int r;
assert(old_device);
assert(new_device);
assert(device);
assert(ret);
r = device_shallow_clone(old_device, &ret);
r = device_shallow_clone(device, &dest);
if (r < 0)
return r;
r = device_read_db(ret);
r = device_read_db(dest);
if (r < 0)
return r;
ret->sealed = true;
*new_device = TAKE_PTR(ret);
dest->sealed = true;
*ret = TAKE_PTR(dest);
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);
if (add) {
r = touch_file(path, true, USEC_INFINITY, UID_INVALID, GID_INVALID, 0444);
if (r < 0)
return r;
} else {
r = unlink(path);
if (r < 0 && errno != ENOENT)
if (add)
return touch_file(path, true, USEC_INFINITY, UID_INVALID, GID_INVALID, 0444);
if (unlink(path) < 0 && errno != ENOENT)
return -errno;
}
return 0;
}
@ -940,16 +944,14 @@ int device_tag_index(sd_device *device, sd_device *device_old, bool add) {
const char *tag;
int r = 0, k;
if (add && device_old) {
if (add && device_old)
/* delete possible left-over tags */
FOREACH_DEVICE_TAG(device_old, tag) {
FOREACH_DEVICE_TAG(device_old, tag)
if (!sd_device_has_tag(device, tag)) {
k = device_tag(device_old, tag, false);
if (r >= 0 && k < 0)
r = k;
}
}
}
FOREACH_DEVICE_TAG(device, tag) {
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 */
if (!has_info && major(device->devnum) == 0 && device->ifindex == 0) {
r = unlink(path);
if (r < 0 && errno != ENOENT)
if (unlink(path) < 0 && errno != ENOENT)
return -errno;
return 0;
@ -1096,8 +1097,7 @@ int device_delete_db(sd_device *device) {
path = strjoina("/run/udev/data/", id);
r = unlink(path);
if (r < 0 && errno != ENOENT)
if (unlink(path) < 0 && errno != ENOENT)
return -errno;
return 0;

View File

@ -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_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_devnode_mode(sd_device *device, mode_t *mode);
int device_get_devnode_uid(sd_device *device, uid_t *uid);
int device_get_devnode_gid(sd_device *device, gid_t *gid);
int device_get_devnode_mode(sd_device *device, mode_t *ret);
int device_get_devnode_uid(sd_device *device, uid_t *ret);
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_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_rename(sd_device *device, const char *name);
int device_shallow_clone(sd_device *old_device, sd_device **new_device);
int device_clone_with_db(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 *device, sd_device **ret);
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);

View File

@ -724,11 +724,14 @@ int device_read_uevent_file(sd_device *device) {
path = strjoina(syspath, "/uevent");
r = read_full_virtual_file(path, &uevent, &uevent_len);
if (IN_SET(r, -EACCES, -ENOENT))
/* The uevent files may be write-only, or the device may not have uevent file. */
if (r < 0) {
/* 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;
if (r < 0)
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++)
switch (state) {
@ -1437,37 +1440,30 @@ int device_get_device_id(sd_device *device, const char **ret) {
return r;
if (sd_device_get_devnum(device, &devnum) >= 0) {
assert(subsystem);
/* use dev_t — b259:131072, c254:0 */
r = asprintf(&id, "%c%u:%u",
if (asprintf(&id, "%c%u:%u",
streq(subsystem, "block") ? 'b' : 'c',
major(devnum), minor(devnum));
if (r < 0)
major(devnum), minor(devnum)) < 0)
return -ENOMEM;
} else if (sd_device_get_ifindex(device, &ifindex) >= 0) {
/* use netdev ifindex — n3 */
r = asprintf(&id, "n%u", (unsigned) ifindex);
if (r < 0)
if (asprintf(&id, "n%u", (unsigned) ifindex) < 0)
return -ENOMEM;
} else {
_cleanup_free_ char *sysname = NULL;
/* use $subsys:$sysname — pci:0000:00:1f.2
* sysname() has '!' translated, get it from devpath
*/
const char *sysname;
* sd_device_get_sysname() has '!' translated, get it from devpath */
r = path_extract_filename(device->devpath, &sysname);
if (r < 0)
return r;
sysname = basename(device->devpath);
if (!sysname)
return -EINVAL;
if (!subsystem)
return -EINVAL;
if (streq(subsystem, "drivers"))
/* the 'drivers' pseudo-subsystem is special, and needs the real subsystem
* encoded as well */
if (streq(subsystem, "drivers")) {
/* the 'drivers' pseudo-subsystem is special, and needs the real
* subsystem encoded as well */
assert(device->driver_subsystem);
id = strjoin("+drivers:", device->driver_subsystem, ":", sysname);
else
} else
id = strjoin("+", subsystem, ":", sysname);
if (!id)
return -ENOMEM;

View File

@ -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,
void *dst, size_t dst_alloc_size, size_t *dst_size) {
int r;
#if HAVE_ZSTD
#if DEFAULT_COMPRESSION == OBJECT_COMPRESSED_ZSTD
r = compress_blob_zstd(src, src_size, dst, dst_alloc_size, dst_size);
if (r == 0)
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);
if (r == 0)
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);
if (r == 0)
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_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 COMPRESSED_EXT ".zst"
#elif HAVE_LZ4
#elif DEFAULT_COMPRESSION == OBJECT_COMPRESSED_LZ4
# define compress_stream compress_stream_lz4
# define COMPRESSED_EXT ".lz4"
#elif HAVE_XZ
#elif DEFAULT_COMPRESSION == OBJECT_COMPRESSED_XZ
# define compress_stream compress_stream_xz
# define COMPRESSED_EXT ".xz"
#else

View File

@ -42,11 +42,9 @@ typedef enum ObjectType {
_OBJECT_TYPE_MAX
} ObjectType;
/* Object flags */
/* Object flags
* The per-compression enums are defined in meson.build so that config.h is self-contained */
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_COMPRESSED_MAX = OBJECT_COMPRESSION_MASK,
};

View File

@ -3359,11 +3359,11 @@ int journal_file_open(
.open_flags = open_flags,
.writable = (open_flags & O_ACCMODE) != O_RDONLY,
#if HAVE_ZSTD
#if DEFAULT_COMPRESSION == OBJECT_COMPRESSED_ZSTD
.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),
#elif HAVE_XZ
#elif DEFAULT_COMPRESSION == OBJECT_COMPRESSED_XZ
.compress_xz = FLAGS_SET(file_flags, JOURNAL_COMPRESS),
#endif
.compress_threshold_bytes = compress_threshold_bytes == UINT64_MAX ?

View File

@ -486,7 +486,8 @@ int config_parse_l2tp_tunnel_local_address(
L2tpLocalAddressType type;
L2tpTunnel *t = userdata;
const char *p = rvalue;
int r;
union in_addr_union a;
int r, f;
assert(filename);
assert(lvalue);
@ -539,16 +540,27 @@ int config_parse_l2tp_tunnel_local_address(
return 0;
}
if (t->family == AF_UNSPEC)
r = in_addr_from_string_auto(rvalue, &t->family, &t->local);
else
r = in_addr_from_string(t->family, rvalue, &t->local);
r = in_addr_from_string_auto(rvalue, &f, &a);
if (r < 0) {
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;
}
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);
t->local_address_type = _NETDEV_L2TP_LOCAL_ADDRESS_INVALID;
return 0;
@ -567,7 +579,8 @@ int config_parse_l2tp_tunnel_remote_address(
void *userdata) {
L2tpTunnel *t = userdata;
int r;
union in_addr_union a;
int r, f;
assert(filename);
assert(lvalue);
@ -584,16 +597,27 @@ int config_parse_l2tp_tunnel_remote_address(
return 0;
}
if (t->family == AF_UNSPEC)
r = in_addr_from_string_auto(rvalue, &t->family, &t->remote);
else
r = in_addr_from_string(t->family, rvalue, &t->remote);
r = in_addr_from_string_auto(rvalue, &f, &a);
if (r < 0) {
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;
}
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;
}

View File

@ -7,6 +7,7 @@
#include <linux/ip.h>
#include <linux/ip6_tunnel.h>
#include "af-list.h"
#include "conf-parser.h"
#include "hexdecoct.h"
#include "missing_network.h"
@ -737,6 +738,20 @@ static int netdev_tunnel_verify(NetDev *netdev, const char *filename) {
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(
const char *unit,
const char *filename,
@ -759,16 +774,8 @@ int config_parse_tunnel_local_address(
assert(rvalue);
assert(userdata);
if (isempty(rvalue) || streq(rvalue, "any")) {
/* 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;
}
if (isempty(rvalue) || streq(rvalue, "any"))
return unset_local(t);
type = netdev_local_address_type_from_string(rvalue);
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);
return 0;
}
if (in_addr_is_null(f, &buffer))
return unset_local(t);
}
if (t->family != AF_UNSPEC && t->family != f) {
@ -797,6 +807,20 @@ int config_parse_tunnel_local_address(
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(
const char *unit,
const char *filename,
@ -818,16 +842,8 @@ int config_parse_tunnel_remote_address(
assert(rvalue);
assert(userdata);
if (isempty(rvalue) || streq(rvalue, "any")) {
/* 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;
}
if (isempty(rvalue) || streq(rvalue, "any"))
return unset_remote(t);
r = in_addr_from_string_auto(rvalue, &f, &buffer);
if (r < 0) {
@ -836,6 +852,9 @@ int config_parse_tunnel_remote_address(
return 0;
}
if (in_addr_is_null(f, &buffer))
return unset_remote(t);
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);

View File

@ -60,7 +60,7 @@ bool dns_type_is_pseudo(uint16_t type) {
}
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) {

View File

@ -869,15 +869,21 @@ int udev_event_spawn(
}
static int rename_netif(UdevEvent *event) {
sd_device *dev = event->dev;
const char *oldname;
sd_device *dev;
unsigned flags;
int ifindex, r;
assert(event);
if (!event->name)
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)
return log_device_error_errno(dev, r, "Failed to get sysname: %m");

View File

@ -637,6 +637,13 @@ static int print_tree(sd_device* below) {
if (r < 0)
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));
if (n == 0) {