Compare commits

...

31 Commits

Author SHA1 Message Date
Evgeny Vereshchagin b18573e16f ci: bring back Coverity part 2
It's just a follow-up to https://github.com/systemd/systemd/pull/16266.

Currently the Coverity stage is failing with
```
Starting container systemd-fedora-latest
2db425228e1addbce607c7e47e492a0faef2c2c4e85701c6c239a50de95944eb
Error: No such container: bash
The command "$CI_MANAGERS/fedora.sh SETUP" failed and exited with 1 during .
Your build has been stopped.
```

https://travis-ci.org/github/systemd/systemd/builds/701798193
2020-06-24 22:58:17 +02:00
Evgeny Vereshchagin 595cb4211a ci: bring back Coverity
Looks like DOCKER_EXEC got lost somewhere along the way, which, in
turn, caused the "coverity" job to fail with
```
$ $DOCKER_EXEC meson cov-build -Dman=false
Command 'meson' not found, but can be installed with:
apt install meson
Please ask your administrator.
```

https://travis-ci.org/github/systemd/systemd/builds/701705788
2020-06-24 22:32:56 +02:00
Lennart Poettering c4e90266db
Merge pull request #16093 from yuwata/network-htb-add-settings-15213
network: tc: add several settings for HTB
2020-06-24 19:07:41 +02:00
Lennart Poettering f9044b74c5
Merge pull request #16106 from yuwata/network-tc-ets
network: tc: introduce ETS
2020-06-24 19:04:43 +02:00
Zbigniew Jędrzejewski-Szmek f83803a649
Merge pull request #16238 from keszybz/set-handling-more
Fix handling of cases where a duplicate item is added to a set and related cleanups
2020-06-24 17:42:13 +02:00
Filipe Brandenburger 41d1f469cf log: introduce log_parse_environment_cli() and log_setup_cli()
Presently, CLI utilities such as systemctl will check whether they have a tty
attached or not to decide whether to parse /proc/cmdline or EFI variable
SystemdOptions looking for systemd.log_* entries.

But this check will be misleading if these tools are being launched by a
daemon, such as a monitoring daemon or automation service that runs in
background.

Make log handling of CLI tools uniform by never checking /proc/cmdline or EFI
variables to determine the logging level.

Furthermore, introduce a new log_setup_cli() shortcut to set up common options
used by most command-line utilities.
2020-06-24 16:49:26 +02:00
Zbigniew Jędrzejewski-Szmek e198eba7c2 sysv-generator: reduce scope of variables 2020-06-24 10:38:15 +02:00
Zbigniew Jędrzejewski-Szmek 80ce54adaf socket-proxy: use structured initialization in one place 2020-06-24 10:38:15 +02:00
Zbigniew Jędrzejewski-Szmek add74e8929 basic/hashmap,set: propagate allocation location info in _copy()
Also use double space before the tracking args at the end. Without
the comma this looks ugly, but it's a bit better with the double space.
At least it doesn't look like a variable with a type.
2020-06-24 10:38:15 +02:00
Zbigniew Jędrzejewski-Szmek 35e601d4f9 tree-wide: use set_ensure_consume() in various places
No funtional change.
2020-06-24 10:38:15 +02:00
Zbigniew Jędrzejewski-Szmek 39dbd0c74c networkd: take ref immediately after storing item in set
I'm not sure if I understand the code correctly, but it seems that if
storig in the second set failed, we'd return with the first set having
no reference on the link object, and the link object could be freed in the
future, leaving the set with a dangling reference.
2020-06-24 10:38:15 +02:00
Zbigniew Jędrzejewski-Szmek d02fd8b1c6 core/bpf-firewall: use the correct cleanup function
On error, we'd just free the object, and not close the fd.

While at it, let's use set_ensure_consume() to make sure we don't leak
the object if it was already in the set. I'm not sure if that condition
can be achieved.
2020-06-24 10:38:15 +02:00
Zbigniew Jędrzejewski-Szmek 648c339c49 logind: fix possible memleak of message if the message was already in the set
I'm not sure if it is actually possible to encounter this condition. But
let's make the handling correct regardless.
2020-06-24 10:38:15 +02:00
Zbigniew Jędrzejewski-Szmek d378ef708b portable: rework set handling in portable_detach()
_cleanup_set_free_ is enough for unit_files, because unit_files is
allocated in set_put_strdup(), which uses string_hash_ops_free.

This fixes a leak if marker was already present in the table.
2020-06-24 10:38:15 +02:00
Zbigniew Jędrzejewski-Szmek ab9dd0b997 resolved: fix memleak on duplicate host lines in /etc/hosts 2020-06-24 10:38:15 +02:00
Zbigniew Jędrzejewski-Szmek ceb17827fa resolved: simplify allocation failure handling in dns_stub_process_query()
Old code was correct, but let's make things more explicit.
2020-06-24 10:38:15 +02:00
Zbigniew Jędrzejewski-Szmek b8b46b1ce5 basic/set,hashmap: pass through allocation info in more cases 2020-06-24 10:38:15 +02:00
Zbigniew Jędrzejewski-Szmek fcc1d0315d basic/set: add set_ensure_consume()
This combines set_ensure_allocated() with set_consume(). The cool thing is that
because we know the hash ops, we can correctly free the item if appropriate.
Similarly to set_consume(), the goal is to simplify handling of the case where
the item needs to be freed on error and if already present in the set.
2020-06-24 10:38:15 +02:00
Zbigniew Jędrzejewski-Szmek 6cd55d6f74 shared/bus-util: fix misleading error handling
set_put()/set_ensure_put() return 0, not -EEXIST, if the entry is already
found in the set. In this case this does not make any difference, but let's
not confuse the reader.
2020-06-22 16:32:37 +02:00
Zbigniew Jędrzejewski-Szmek e2ab8e09c8 udevadm-monitor: simplify creation of arg_tag_filter set
This version is more efficient, which doesn't matter, but it allows us
to remove a bunch of error handling, which is always nice.
2020-06-22 16:32:37 +02:00
Zbigniew Jędrzejewski-Szmek 804a436582 fuzz-netdev-parser: add test case for earlier version of preceding patches
AddressSanitizer:DEADLYSIGNAL
=================================================================
==12==ERROR: AddressSanitizer: ABRT on unknown address 0x00000000000c (pc 0x7f0a518b3428 bp 0x7fffa463bfd0 sp 0x7fffa463be68 T0)
SCARINESS: 10 (signal)
    #0 0x7f0a518b3428 in raise (/lib/x86_64-linux-gnu/libc.so.6+0x35428)
    #1 0x7f0a518b5029 in abort (/lib/x86_64-linux-gnu/libc.so.6+0x37029)
    #2 0x7f0a52ca635a in log_assert_failed_realm /work/build/../../src/systemd/src/basic/log.c:819:9
    #3 0x4eea92 in config_parse_wireguard_endpoint /work/build/../../src/systemd/src/network/netdev/wireguard.c:808:9
    #4 0x7f0a52b2f74e in next_assignment /work/build/../../src/systemd/src/shared/conf-parser.c:133:32
    #5 0x7f0a52b2954e in parse_line /work/build/../../src/systemd/src/shared/conf-parser.c:242:16
    #6 0x7f0a52b28911 in config_parse /work/build/../../src/systemd/src/shared/conf-parser.c:377:21
    #7 0x7f0a52b29ec6 in config_parse_many_files /work/build/../../src/systemd/src/shared/conf-parser.c:439:21
    #8 0x7f0a52b2a5a6 in config_parse_many /work/build/../../src/systemd/src/shared/conf-parser.c:507:16
    #9 0x4d8d6c in netdev_load_one /work/build/../../src/systemd/src/network/netdev/netdev.c:732:13
    #10 0x4d3e2b in LLVMFuzzerTestOneInput /work/build/../../src/systemd/src/network/fuzz-netdev-parser.c:23:16
    #11 0x6b3266 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) /src/libfuzzer/FuzzerLoop.cpp:558:15
    #12 0x6af860 in fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long, bool, fuzzer::InputInfo*, bool*) /src/libfuzzer/FuzzerLoop.cpp:470:3
    #13 0x6b6970 in fuzzer::Fuzzer::ReadAndExecuteSeedCorpora(std::__1::vector<fuzzer::SizedFile, fuzzer::fuzzer_allocator<fuzzer::SizedFile> >&) /src/libfuzzer/FuzzerLoop.cpp:770:7
    #14 0x6b7376 in fuzzer::Fuzzer::Loop(std::__1::vector<fuzzer::SizedFile, fuzzer::fuzzer_allocator<fuzzer::SizedFile> >&) /src/libfuzzer/FuzzerLoop.cpp:799:3
    #15 0x67573f in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) /src/libfuzzer/FuzzerDriver.cpp:846:6
    #16 0x667097 in main /src/libfuzzer/FuzzerMain.cpp:19:10
    #17 0x7f0a5189e82f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
    #18 0x4295a8 in _start (out/fuzz-netdev-parser+0x4295a8)

DEDUP_TOKEN: raise--abort--log_assert_failed_realm
AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: ABRT (/lib/x86_64-linux-gnu/libc.so.6+0x35428) in raise
==12==ABORTING
2020-06-22 16:32:37 +02:00
Zbigniew Jędrzejewski-Szmek 44e9342078 netdev/wireguard: do not invalidate peer on invalid syntax
We would say "ignoring", but invalidate the peer anyway.
Let's only do that if we modified the peer irreperably.

Also add comments explaining allocation handling.
2020-06-22 16:32:37 +02:00
Zbigniew Jędrzejewski-Szmek de7fef4b6e tree-wide: use set_ensure_put()
Patch contains a coccinelle script, but it only works in some cases. Many
parts were converted by hand.

Note: I did not fix errors in return value handing. This will be done separate
to keep the patch comprehensible. No functional change is intended in this
patch.
2020-06-22 16:32:37 +02:00
Zbigniew Jędrzejewski-Szmek 0f9ccd9552 basic/set: add set_ensure_put()
It's such a common operation to allocate the set and put an item in it,
that it deserves a helper. set_ensure_put() has the same return values
as set_put().

Comes with tests!
2020-06-22 16:32:37 +02:00
Zbigniew Jędrzejewski-Szmek aaffd34933 sd-device: use set_put_strdup() in one more place 2020-06-22 16:32:37 +02:00
Zbigniew Jędrzejewski-Szmek 29bd6012f1 resolved: introduce dns_transaction_gcp() 2020-06-22 16:32:37 +02:00
Yu Watanabe b753e8358c test-network: add tests for ETS 2020-06-19 01:10:51 +09:00
Yu Watanabe d474aa51bf network: tc: introduce Enhanced Transmission Selection (ETS)
Closes #15264.
2020-06-19 01:07:45 +09:00
Yu Watanabe 4dec921889 sd-netlink: add netlink properties of Enhanced Transmission Selection (ETS) 2020-06-19 00:47:55 +09:00
Yu Watanabe 2ee7e54b9e test-network: add tests for HTB settings 2020-06-17 16:52:03 +09:00
Yu Watanabe d9eacc1cdd network: tc: add more settings for HTB
Closes #15213.
2020-06-17 16:49:46 +09:00
90 changed files with 1156 additions and 617 deletions

View File

@ -47,6 +47,8 @@ jobs:
env:
- FEDORA_RELEASE="latest"
- TOOL_BASE="/var/tmp/coverity-scan-analysis"
- CONT_NAME="coverity-fedora-$FEDORA_RELEASE"
- DOCKER_EXEC="docker exec -ti $CONT_NAME"
- DOCKER_RUN="docker run -v $TOOL_BASE:$TOOL_BASE:rw --env-file .cov-env"
# Coverity env variables
- PLATFORM="$(uname)"

View File

@ -0,0 +1,18 @@
@@
local idexpression r;
expression p, k, x;
@@
- r = set_ensure_allocated(&p, k);
- if (r < 0)
- return ...;
- r = set_put(p, x);
+ r = set_ensure_put(&p, k, x);
@@
local idexpression r;
expression p, k, x;
@@
- r = set_ensure_allocated(p, k);
- if (r < 0)
- return ...;
- r = set_put(*p, x);
+ r = set_ensure_put(p, k, x);

View File

@ -2929,6 +2929,58 @@
</variablelist>
</refsect1>
<refsect1>
<title>[EnhancedTransmissionSelection] Section Options</title>
<para>The <literal>[EnhancedTransmissionSelection]</literal> section manages the queueing discipline (qdisc) of
Enhanced Transmission Selection (ETS).</para>
<variablelist class='network-directives'>
<xi:include href="tc.xml" xpointer="qdisc-parent" />
<xi:include href="tc.xml" xpointer="qdisc-handle" />
<varlistentry>
<term><varname>Bands=</varname></term>
<listitem>
<para>Specifies the number of bands. An unsigned integer ranges 1 to 16. This value has to be
at least large enough to cover the strict bands specified through the
<varname>StrictBands=</varname> and bandwidth-sharing bands specified in
<varname>QuantumBytes=</varname>.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>StrictBands=</varname></term>
<listitem>
<para>Specifies the number of bands that should be created in strict mode. An unsigned integer
ranges 1 to 16.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>QuantumBytes=</varname></term>
<listitem>
<para>Specifies the white-space separated list of quantum used in band-sharing bands. When
suffixed with K, M, or G, the specified size is parsed as Kilobytes, Megabytes, or Gigabytes,
respectively, to the base of 1024. This setting can be specified multiple times. If an empty
string is assigned, then the all previous assignments are cleared.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>PriorityMap=</varname></term>
<listitem>
<para>The priority map maps the priority of a packet to a band. The argument is a white-space
separated list of numbers. The first number indicates which band the packets with priority
0 should be put to, the second is for priority 1, and so on. There can be up to 16 numbers in
the list. If there are fewer, the default band that traffic with one of the unmentioned
priorities goes to is the last one. Each band number must be 0..255. This setting can be
specified multiple times. If an empty string is assigned, then the all previous assignments
are cleared.</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1>
<title>[GenericRandomEarlyDetection] Section Options</title>
<para>The <literal>[GenericRandomEarlyDetection]</literal> section manages the queueing discipline
@ -3166,6 +3218,14 @@
to the class. Defaults to unset.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>RateToQuantum=</varname></term>
<listitem>
<para>Takes an unsigned integer. The DRR quantums are calculated by dividing the value
configured in <varname>Rate=</varname> by <varname>RateToQuantum=</varname>.</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
@ -3182,7 +3242,33 @@
<term><varname>Priority=</varname></term>
<listitem>
<para>Specifies the priority of the class. In the round-robin process, classes with the lowest
priority field are tried for packets first. This setting is mandatory.</para>
priority field are tried for packets first.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>QuantumBytes=</varname></term>
<listitem>
<para>Specifies how many bytes to serve from leaf at once. When suffixed with K, M, or G, the
specified size is parsed as Kilobytes, Megabytes, or Gigabytes, respectively, to the base of
1024.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>MTUBytes=</varname></term>
<listitem>
<para>Specifies the maximum packet size we create. When suffixed with K, M, or G, the specified
size is parsed as Kilobytes, Megabytes, or Gigabytes, respectively, to the base of 1024.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>OverheadBytes=</varname></term>
<listitem>
<para>Takes an unsigned integer which specifies per-packet size overhead used in rate
computations. When suffixed with K, M, or G, the specified size is parsed as Kilobytes,
Megabytes, or Gigabytes, respectively, to the base of 1024.</para>
</listitem>
</varlistentry>
@ -3204,6 +3290,24 @@
is used.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>BufferBytes=</varname></term>
<listitem>
<para>Specifies the maximum bytes burst which can be accumulated during idle period. When suffixed
with K, M, or G, the specified size is parsed as Kilobytes, Megabytes, or Gigabytes, respectively,
to the base of 1024.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>CeilBufferBytes=</varname></term>
<listitem>
<para>Specifies the maximum bytes burst for ceil which can be accumulated during idle period.
When suffixed with K, M, or G, the specified size is parsed as Kilobytes, Megabytes, or Gigabytes,
respectively, to the base of 1024.</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>

View File

@ -2376,9 +2376,7 @@ static int run(int argc, char *argv[]) {
setlocale(LC_ALL, "");
setlocale(LC_NUMERIC, "C"); /* we want to format/parse floats in C style */
log_show_color(true);
log_parse_environment();
log_open();
log_setup_cli();
r = parse_argv(argc, argv);
if (r <= 0)

View File

@ -768,7 +768,7 @@ static void reset_direct_storage(HashmapBase *h) {
memset(p, DIB_RAW_INIT, sizeof(dib_raw_t) * hi->n_direct_buckets);
}
static struct HashmapBase *hashmap_base_new(const struct hash_ops *hash_ops, enum HashmapType type HASHMAP_DEBUG_PARAMS) {
static struct HashmapBase *hashmap_base_new(const struct hash_ops *hash_ops, enum HashmapType type HASHMAP_DEBUG_PARAMS) {
HashmapBase *h;
const struct hashmap_type_info *hi = &hashmap_type_info[type];
bool up;
@ -808,19 +808,19 @@ static struct HashmapBase *hashmap_base_new(const struct hash_ops *hash_ops, enu
}
Hashmap *_hashmap_new(const struct hash_ops *hash_ops HASHMAP_DEBUG_PARAMS) {
return (Hashmap*) hashmap_base_new(hash_ops, HASHMAP_TYPE_PLAIN HASHMAP_DEBUG_PASS_ARGS);
return (Hashmap*) hashmap_base_new(hash_ops, HASHMAP_TYPE_PLAIN HASHMAP_DEBUG_PASS_ARGS);
}
OrderedHashmap *_ordered_hashmap_new(const struct hash_ops *hash_ops HASHMAP_DEBUG_PARAMS) {
return (OrderedHashmap*) hashmap_base_new(hash_ops, HASHMAP_TYPE_ORDERED HASHMAP_DEBUG_PASS_ARGS);
return (OrderedHashmap*) hashmap_base_new(hash_ops, HASHMAP_TYPE_ORDERED HASHMAP_DEBUG_PASS_ARGS);
}
Set *_set_new(const struct hash_ops *hash_ops HASHMAP_DEBUG_PARAMS) {
return (Set*) hashmap_base_new(hash_ops, HASHMAP_TYPE_SET HASHMAP_DEBUG_PASS_ARGS);
return (Set*) hashmap_base_new(hash_ops, HASHMAP_TYPE_SET HASHMAP_DEBUG_PASS_ARGS);
}
static int hashmap_base_ensure_allocated(HashmapBase **h, const struct hash_ops *hash_ops,
enum HashmapType type HASHMAP_DEBUG_PARAMS) {
enum HashmapType type HASHMAP_DEBUG_PARAMS) {
HashmapBase *q;
assert(h);
@ -828,7 +828,7 @@ static int hashmap_base_ensure_allocated(HashmapBase **h, const struct hash_ops
if (*h)
return 0;
q = hashmap_base_new(hash_ops, type HASHMAP_DEBUG_PASS_ARGS);
q = hashmap_base_new(hash_ops, type HASHMAP_DEBUG_PASS_ARGS);
if (!q)
return -ENOMEM;
@ -837,15 +837,15 @@ static int hashmap_base_ensure_allocated(HashmapBase **h, const struct hash_ops
}
int _hashmap_ensure_allocated(Hashmap **h, const struct hash_ops *hash_ops HASHMAP_DEBUG_PARAMS) {
return hashmap_base_ensure_allocated((HashmapBase**)h, hash_ops, HASHMAP_TYPE_PLAIN HASHMAP_DEBUG_PASS_ARGS);
return hashmap_base_ensure_allocated((HashmapBase**)h, hash_ops, HASHMAP_TYPE_PLAIN HASHMAP_DEBUG_PASS_ARGS);
}
int _ordered_hashmap_ensure_allocated(OrderedHashmap **h, const struct hash_ops *hash_ops HASHMAP_DEBUG_PARAMS) {
return hashmap_base_ensure_allocated((HashmapBase**)h, hash_ops, HASHMAP_TYPE_ORDERED HASHMAP_DEBUG_PASS_ARGS);
return hashmap_base_ensure_allocated((HashmapBase**)h, hash_ops, HASHMAP_TYPE_ORDERED HASHMAP_DEBUG_PASS_ARGS);
}
int _set_ensure_allocated(Set **s, const struct hash_ops *hash_ops HASHMAP_DEBUG_PARAMS) {
return hashmap_base_ensure_allocated((HashmapBase**)s, hash_ops, HASHMAP_TYPE_SET HASHMAP_DEBUG_PASS_ARGS);
return hashmap_base_ensure_allocated((HashmapBase**)s, hash_ops, HASHMAP_TYPE_SET HASHMAP_DEBUG_PASS_ARGS);
}
static void hashmap_free_no_clear(HashmapBase *h) {
@ -1247,6 +1247,30 @@ int set_put(Set *s, const void *key) {
return hashmap_put_boldly(s, hash, &swap, true);
}
int _set_ensure_put(Set **s, const struct hash_ops *hash_ops, const void *key HASHMAP_DEBUG_PARAMS) {
int r;
r = _set_ensure_allocated(s, hash_ops HASHMAP_DEBUG_PASS_ARGS);
if (r < 0)
return r;
return set_put(*s, key);
}
int _set_ensure_consume(Set **s, const struct hash_ops *hash_ops, void *key HASHMAP_DEBUG_PARAMS) {
int r;
r = _set_ensure_put(s, hash_ops, key HASHMAP_DEBUG_PASS_ARGS);
if (r <= 0) {
if (hash_ops && hash_ops->free_key)
hash_ops->free_key(key);
else
free(key);
}
return r;
}
int hashmap_replace(Hashmap *h, const void *key, void *value) {
struct swap_entries swap;
struct plain_hashmap_entry *e;
@ -1687,13 +1711,13 @@ int _hashmap_move_one(HashmapBase *h, HashmapBase *other, const void *key) {
return 0;
}
HashmapBase *_hashmap_copy(HashmapBase *h) {
HashmapBase *_hashmap_copy(HashmapBase *h HASHMAP_DEBUG_PARAMS) {
HashmapBase *copy;
int r;
assert(h);
copy = hashmap_base_new(h->hash_ops, h->type HASHMAP_DEBUG_SRC_ARGS);
copy = hashmap_base_new(h->hash_ops, h->type HASHMAP_DEBUG_PASS_ARGS);
if (!copy)
return NULL;
@ -1709,10 +1733,8 @@ HashmapBase *_hashmap_copy(HashmapBase *h) {
assert_not_reached("Unknown hashmap type");
}
if (r < 0) {
_hashmap_free(copy, false, false);
return NULL;
}
if (r < 0)
return _hashmap_free(copy, false, false);
return copy;
}
@ -1765,10 +1787,10 @@ int set_consume(Set *s, void *value) {
return r;
}
int hashmap_put_strdup(Hashmap **h, const char *k, const char *v) {
int _hashmap_put_strdup(Hashmap **h, const char *k, const char *v HASHMAP_DEBUG_PARAMS) {
int r;
r = hashmap_ensure_allocated(h, &string_hash_ops_free_free);
r = _hashmap_ensure_allocated(h, &string_hash_ops_free_free HASHMAP_DEBUG_PASS_ARGS);
if (r < 0)
return r;
@ -1799,14 +1821,14 @@ int hashmap_put_strdup(Hashmap **h, const char *k, const char *v) {
return r;
}
int set_put_strdup(Set **s, const char *p) {
int _set_put_strdup(Set **s, const char *p HASHMAP_DEBUG_PARAMS) {
char *c;
int r;
assert(s);
assert(p);
r = set_ensure_allocated(s, &string_hash_ops_free);
r = _set_ensure_allocated(s, &string_hash_ops_free HASHMAP_DEBUG_PASS_ARGS);
if (r < 0)
return r;
@ -1820,14 +1842,14 @@ int set_put_strdup(Set **s, const char *p) {
return set_consume(*s, c);
}
int set_put_strdupv(Set **s, char **l) {
int _set_put_strdupv(Set **s, char **l HASHMAP_DEBUG_PARAMS) {
int n = 0, r;
char **i;
assert(s);
STRV_FOREACH(i, l) {
r = set_put_strdup(s, *i);
r = _set_put_strdup(s, *i HASHMAP_DEBUG_PASS_ARGS);
if (r < 0)
return r;

View File

@ -128,13 +128,9 @@ static inline OrderedHashmap *ordered_hashmap_free_free_free(OrderedHashmap *h)
IteratedCache *iterated_cache_free(IteratedCache *cache);
int iterated_cache_get(IteratedCache *cache, const void ***res_keys, const void ***res_values, unsigned *res_n_entries);
HashmapBase *_hashmap_copy(HashmapBase *h);
static inline Hashmap *hashmap_copy(Hashmap *h) {
return (Hashmap*) _hashmap_copy(HASHMAP_BASE(h));
}
static inline OrderedHashmap *ordered_hashmap_copy(OrderedHashmap *h) {
return (OrderedHashmap*) _hashmap_copy(HASHMAP_BASE(h));
}
HashmapBase *_hashmap_copy(HashmapBase *h HASHMAP_DEBUG_PARAMS);
#define hashmap_copy(h) ((Hashmap*) _hashmap_copy(HASHMAP_BASE(h) HASHMAP_DEBUG_SRC_ARGS))
#define ordered_hashmap_copy(h) ((OrderedHashmap*) _hashmap_copy(HASHMAP_BASE(h) HASHMAP_DEBUG_SRC_ARGS))
int _hashmap_ensure_allocated(Hashmap **h, const struct hash_ops *hash_ops HASHMAP_DEBUG_PARAMS);
int _ordered_hashmap_ensure_allocated(OrderedHashmap **h, const struct hash_ops *hash_ops HASHMAP_DEBUG_PARAMS);
@ -154,7 +150,8 @@ static inline int ordered_hashmap_put(OrderedHashmap *h, const void *key, void *
return hashmap_put(PLAIN_HASHMAP(h), key, value);
}
int hashmap_put_strdup(Hashmap **h, const char *k, const char *v);
int _hashmap_put_strdup(Hashmap **h, const char *k, const char *v HASHMAP_DEBUG_PARAMS);
#define hashmap_put_strdup(h, k, v) _hashmap_put_strdup(h, k, v HASHMAP_DEBUG_SRC_ARGS)
int hashmap_update(Hashmap *h, const void *key, void *value);
static inline int ordered_hashmap_update(OrderedHashmap *h, const void *key, void *value) {

View File

@ -1146,16 +1146,20 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat
}
void log_parse_environment_realm(LogRealm realm) {
/* Do not call from library code. */
const char *e;
if (getpid_cached() == 1 || get_ctty_devnr(0, NULL) < 0)
/* Only try to read the command line in daemons. We assume that anything that has a
* controlling tty is user stuff. For PID1 we do a special check in case it hasn't
* closed the console yet. */
(void) proc_cmdline_parse(parse_proc_cmdline_item, NULL, PROC_CMDLINE_STRIP_RD_PREFIX);
log_parse_environment_cli_realm(realm);
}
void log_parse_environment_cli_realm(LogRealm realm) {
/* Do not call from library code. */
const char *e;
e = getenv("SYSTEMD_LOG_TARGET");
if (e && log_set_target_from_string(e) < 0)
log_warning("Failed to parse log target '%s'. Ignoring.", e);
@ -1430,3 +1434,11 @@ void log_setup_service(void) {
log_parse_environment();
(void) log_open();
}
void log_setup_cli(void) {
/* Sets up logging the way it is most appropriate for running a program as a CLI utility. */
log_show_color(true);
log_parse_environment_cli();
(void) log_open();
}

View File

@ -84,8 +84,11 @@ void log_close(void);
void log_forget_fds(void);
void log_parse_environment_realm(LogRealm realm);
void log_parse_environment_cli_realm(LogRealm realm);
#define log_parse_environment() \
log_parse_environment_realm(LOG_REALM)
#define log_parse_environment_cli() \
log_parse_environment_cli_realm(LOG_REALM)
int log_dispatch_internal(
int level,
@ -341,3 +344,4 @@ int log_syntax_invalid_utf8_internal(
#define DEBUG_LOGGING _unlikely_(log_get_max_level() >= LOG_DEBUG)
void log_setup_service(void);
void log_setup_cli(void);

View File

@ -26,9 +26,7 @@ static inline Set *set_free_free(Set *s) {
/* no set_free_free_free */
static inline Set *set_copy(Set *s) {
return (Set*) _hashmap_copy(HASHMAP_BASE(s));
}
#define set_copy(s) ((Set*) _hashmap_copy(HASHMAP_BASE(h) HASHMAP_DEBUG_SRC_ARGS))
int _set_ensure_allocated(Set **s, const struct hash_ops *hash_ops HASHMAP_DEBUG_PARAMS);
#define set_ensure_allocated(h, ops) _set_ensure_allocated(h, ops HASHMAP_DEBUG_SRC_ARGS)
@ -120,9 +118,19 @@ static inline char **set_get_strv(Set *s) {
return _hashmap_get_strv(HASHMAP_BASE(s));
}
int _set_ensure_put(Set **s, const struct hash_ops *hash_ops, const void *key HASHMAP_DEBUG_PARAMS);
#define set_ensure_put(s, hash_ops, key) _set_ensure_put(s, hash_ops, key HASHMAP_DEBUG_SRC_ARGS)
int _set_ensure_consume(Set **s, const struct hash_ops *hash_ops, void *key HASHMAP_DEBUG_PARAMS);
#define set_ensure_consume(s, hash_ops, key) _set_ensure_consume(s, hash_ops, key HASHMAP_DEBUG_SRC_ARGS)
int set_consume(Set *s, void *value);
int set_put_strdup(Set **s, const char *p);
int set_put_strdupv(Set **s, char **l);
int _set_put_strdup(Set **s, const char *p HASHMAP_DEBUG_PARAMS);
#define set_put_strdup(s, p) _set_put_strdup(s, p HASHMAP_DEBUG_SRC_ARGS)
int _set_put_strdupv(Set **s, char **l HASHMAP_DEBUG_PARAMS);
#define set_put_strdupv(s, l) _set_put_strdupv(s, l HASHMAP_DEBUG_SRC_ARGS)
int set_put_strsplit(Set *s, const char *v, const char *separators, ExtractFlags flags);
#define SET_FOREACH(e, s, i) \

View File

@ -2598,9 +2598,7 @@ static int busctl_main(int argc, char *argv[]) {
static int run(int argc, char *argv[]) {
int r;
log_show_color(true);
log_parse_environment();
log_open();
log_setup_cli();
r = parse_argv(argc, argv);
if (r <= 0)

View File

@ -164,9 +164,7 @@ static void show_cg_info(const char *controller, const char *path) {
static int run(int argc, char *argv[]) {
int r, output_flags;
log_show_color(true);
log_parse_environment();
log_open();
log_setup_cli();
r = parse_argv(argc, argv);
if (r <= 0)

View File

@ -908,9 +908,7 @@ static int run(int argc, char *argv[]) {
CGroupMask mask;
int r;
log_show_color(true);
log_parse_environment();
log_open();
log_setup_cli();
r = parse_argv(argc, argv);
if (r <= 0)

View File

@ -912,13 +912,7 @@ static int automount_deserialize_item(Unit *u, const char *key, const char *valu
if (safe_atou(value, &token) < 0)
log_unit_debug(u, "Failed to parse token value: %s", value);
else {
r = set_ensure_allocated(&a->tokens, NULL);
if (r < 0) {
log_oom();
return 0;
}
r = set_put(a->tokens, UINT_TO_PTR(token));
r = set_ensure_put(&a->tokens, NULL, UINT_TO_PTR(token));
if (r < 0)
log_unit_error_errno(u, r, "Failed to add token to set: %m");
}
@ -928,13 +922,7 @@ static int automount_deserialize_item(Unit *u, const char *key, const char *valu
if (safe_atou(value, &token) < 0)
log_unit_debug(u, "Failed to parse token value: %s", value);
else {
r = set_ensure_allocated(&a->expire_tokens, NULL);
if (r < 0) {
log_oom();
return 0;
}
r = set_put(a->expire_tokens, UINT_TO_PTR(token));
r = set_ensure_put(&a->expire_tokens, NULL, UINT_TO_PTR(token));
if (r < 0)
log_unit_error_errno(u, r, "Failed to add expire token to set: %m");
}
@ -1010,13 +998,7 @@ static int automount_dispatch_io(sd_event_source *s, int fd, uint32_t events, vo
} else
log_unit_debug(UNIT(a), "Got direct mount request on %s", a->where);
r = set_ensure_allocated(&a->tokens, NULL);
if (r < 0) {
log_unit_error(UNIT(a), "Failed to allocate token set.");
goto fail;
}
r = set_put(a->tokens, UINT_TO_PTR(packet.v5_packet.wait_queue_token));
r = set_ensure_put(&a->tokens, NULL, UINT_TO_PTR(packet.v5_packet.wait_queue_token));
if (r < 0) {
log_unit_error_errno(UNIT(a), r, "Failed to remember token: %m");
goto fail;
@ -1030,13 +1012,7 @@ static int automount_dispatch_io(sd_event_source *s, int fd, uint32_t events, vo
automount_stop_expire(a);
r = set_ensure_allocated(&a->expire_tokens, NULL);
if (r < 0) {
log_unit_error(UNIT(a), "Failed to allocate token set.");
goto fail;
}
r = set_put(a->expire_tokens, UINT_TO_PTR(packet.v5_packet.wait_queue_token));
r = set_ensure_put(&a->expire_tokens, NULL, UINT_TO_PTR(packet.v5_packet.wait_queue_token));
if (r < 0) {
log_unit_error_errno(UNIT(a), r, "Failed to remember token: %m");
goto fail;

View File

@ -595,7 +595,7 @@ static int load_bpf_progs_from_fs_to_set(Unit *u, char **filter_paths, Set **set
set_clear(*set);
STRV_FOREACH(bpf_fs_path, filter_paths) {
_cleanup_free_ BPFProgram *prog = NULL;
_cleanup_(bpf_program_unrefp) BPFProgram *prog = NULL;
int r;
r = bpf_program_new(BPF_PROG_TYPE_CGROUP_SKB, &prog);
@ -606,14 +606,9 @@ static int load_bpf_progs_from_fs_to_set(Unit *u, char **filter_paths, Set **set
if (r < 0)
return log_unit_error_errno(u, r, "Loading of ingress BPF program %s failed: %m", *bpf_fs_path);
r = set_ensure_allocated(set, &filter_prog_hash_ops);
if (r < 0)
return log_unit_error_errno(u, r, "Can't allocate BPF program set: %m");
r = set_put(*set, prog);
r = set_ensure_consume(set, &filter_prog_hash_ops, TAKE_PTR(prog));
if (r < 0)
return log_unit_error_errno(u, r, "Can't add program to BPF program set: %m");
TAKE_PTR(prog);
}
return 0;
@ -662,12 +657,9 @@ static int attach_custom_bpf_progs(Unit *u, const char *path, int attach_type, S
r = bpf_program_cgroup_attach(prog, attach_type, path, BPF_F_ALLOW_MULTI);
if (r < 0)
return log_unit_error_errno(u, r, "Attaching custom egress BPF program to cgroup %s failed: %m", path);
/* Remember that these BPF programs are installed now. */
r = set_ensure_allocated(set_installed, &filter_prog_hash_ops);
if (r < 0)
return log_unit_error_errno(u, r, "Can't allocate BPF program set: %m");
r = set_put(*set_installed, prog);
/* Remember that these BPF programs are installed now. */
r = set_ensure_put(set_installed, &filter_prog_hash_ops, prog);
if (r < 0)
return log_unit_error_errno(u, r, "Can't add program to BPF program set: %m");
bpf_program_ref(prog);

View File

@ -1768,10 +1768,6 @@ int bus_exec_context_set_transient_property(
else {
char **s;
r = set_ensure_allocated(&c->syscall_archs, NULL);
if (r < 0)
return r;
STRV_FOREACH(s, l) {
uint32_t a;
@ -1779,7 +1775,7 @@ int bus_exec_context_set_transient_property(
if (r < 0)
return r;
r = set_put(c->syscall_archs, UINT32_TO_PTR(a + 1));
r = set_ensure_put(&c->syscall_archs, NULL, UINT32_TO_PTR(a + 1));
if (r < 0)
return r;
}

View File

@ -3102,10 +3102,6 @@ int config_parse_syscall_archs(
return 0;
}
r = set_ensure_allocated(archs, NULL);
if (r < 0)
return log_oom();
for (;;) {
_cleanup_free_ char *word = NULL;
uint32_t a;
@ -3128,7 +3124,7 @@ int config_parse_syscall_archs(
continue;
}
r = set_put(*archs, UINT32_TO_PTR(a + 1));
r = set_ensure_put(archs, NULL, UINT32_TO_PTR(a + 1));
if (r < 0)
return log_oom();
}

View File

@ -4474,12 +4474,9 @@ int manager_update_failed_units(Manager *m, Unit *u, bool failed) {
size = set_size(m->failed_units);
if (failed) {
r = set_ensure_allocated(&m->failed_units, NULL);
r = set_ensure_put(&m->failed_units, NULL, u);
if (r < 0)
return log_oom();
if (set_put(m->failed_units, u) < 0)
return log_oom();
} else
(void) set_remove(m->failed_units, u);

View File

@ -1591,7 +1591,6 @@ static int unit_add_mount_dependencies(Unit *u) {
static int unit_add_startup_units(Unit *u) {
CGroupContext *c;
int r;
c = unit_get_cgroup_context(u);
if (!c)
@ -1602,11 +1601,7 @@ static int unit_add_startup_units(Unit *u) {
c->startup_blockio_weight == CGROUP_BLKIO_WEIGHT_INVALID)
return 0;
r = set_ensure_allocated(&u->manager->startup_units, NULL);
if (r < 0)
return r;
return set_put(u->manager->startup_units, u);
return set_ensure_put(&u->manager->startup_units, NULL, u);
}
int unit_load(Unit *u) {

View File

@ -1091,9 +1091,7 @@ static int run(int argc, char *argv[]) {
int r, units_active;
setlocale(LC_ALL, "");
log_show_color(true);
log_parse_environment();
log_open();
log_setup_cli();
/* The journal merging logic potentially needs a lot of fds. */
(void) rlimit_nofile_bump(HIGH_RLIMIT_NOFILE);

View File

@ -643,9 +643,7 @@ static int parse_argv(int argc, char *argv[]) {
static int run(int argc, char *argv[]) {
int r, k, n_found = 0;
log_show_color(true);
log_parse_environment();
log_open();
log_setup_cli();
r = parse_argv(argc, argv);
if (r <= 0)

View File

@ -128,9 +128,7 @@ static int run(int argc, char *argv[]) {
* to detect whether we are being run in a virtualized
* environment or not */
log_show_color(true);
log_parse_environment();
log_open();
log_setup_cli();
r = parse_argv(argc, argv);
if (r <= 0)

View File

@ -159,9 +159,7 @@ static int run(int argc, char *argv[]) {
char **i;
int r;
log_show_color(true);
log_parse_environment();
log_open();
log_setup_cli();
r = parse_argv(argc, argv);
if (r <= 0)

View File

@ -3489,9 +3489,7 @@ static int run(int argc, char *argv[]) {
int r;
log_show_color(true);
log_parse_environment();
log_open();
log_setup_cli();
r = parse_argv(argc, argv);
if (r <= 0)

View File

@ -436,9 +436,7 @@ static int run(int argc, char *argv[]) {
int r;
setlocale(LC_ALL, "");
log_show_color(true);
log_parse_environment();
log_open();
log_setup_cli();
r = parse_argv(argc, argv);
if (r <= 0)

View File

@ -249,9 +249,7 @@ static int id128_main(int argc, char *argv[]) {
static int run(int argc, char *argv[]) {
int r;
log_show_color(true);
log_parse_environment();
log_open();
log_setup_cli();
r = parse_argv(argc, argv);
if (r <= 0)

View File

@ -1110,7 +1110,7 @@ static int run(int argc, char **argv) {
int r;
log_show_color(true);
log_parse_environment();
log_parse_environment_cli();
/* The journal merging logic potentially needs a lot of fds. */
(void) rlimit_nofile_bump(HIGH_RLIMIT_NOFILE);

View File

@ -821,7 +821,7 @@ static int run(int argc, char **argv) {
int r;
log_show_color(true);
log_parse_environment();
log_parse_environment_cli();
/* The journal merging logic potentially needs a lot of fds. */
(void) rlimit_nofile_bump(HIGH_RLIMIT_NOFILE);

View File

@ -129,9 +129,7 @@ static int run(int argc, char *argv[]) {
_cleanup_close_ int outfd = -1, errfd = -1, saved_stderr = -1;
int r;
log_show_color(true);
log_parse_environment();
log_open();
log_setup_cli();
r = parse_argv(argc, argv);
if (r <= 0)

View File

@ -875,12 +875,7 @@ static int parse_argv(int argc, char *argv[]) {
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"Bad --facility= argument \"%s\".", fac);
r = set_ensure_allocated(&arg_facilities, NULL);
if (r < 0)
return log_oom();
r = set_put(arg_facilities, INT_TO_PTR(num));
if (r < 0)
if (set_ensure_put(&arg_facilities, NULL, INT_TO_PTR(num)) < 0)
return log_oom();
}
@ -2115,9 +2110,7 @@ int main(int argc, char *argv[]) {
int n_shown = 0, r, poll_fd = -1;
setlocale(LC_ALL, "");
log_show_color(true);
log_parse_environment();
log_open();
log_setup_cli();
/* Increase max number of open files if we can, we might needs this when browsing journal files, which might be
* split up into many files. */

View File

@ -759,30 +759,13 @@ _public_ int sd_device_monitor_filter_add_match_subsystem_devtype(sd_device_moni
}
_public_ int sd_device_monitor_filter_add_match_tag(sd_device_monitor *m, const char *tag) {
_cleanup_free_ char *t = NULL;
int r;
assert_return(m, -EINVAL);
assert_return(tag, -EINVAL);
t = strdup(tag);
if (!t)
return -ENOMEM;
r = set_ensure_allocated(&m->tag_filter, &string_hash_ops);
if (r < 0)
return r;
r = set_put(m->tag_filter, t);
if (r == -EEXIST)
return 0;
if (r < 0)
return r;
TAKE_PTR(t);
m->filter_uptodate = false;
return 0;
int r = set_put_strdup(&m->tag_filter, tag);
if (r > 0)
m->filter_uptodate = false;
return r;
}
_public_ int sd_device_monitor_filter_remove(sd_device_monitor *m) {

View File

@ -1450,10 +1450,6 @@ _public_ int sd_event_add_post(
assert_return(e->state != SD_EVENT_FINISHED, -ESTALE);
assert_return(!event_pid_changed(e), -ECHILD);
r = set_ensure_allocated(&e->post_sources, NULL);
if (r < 0)
return r;
s = source_new(e, !ret, SOURCE_POST);
if (!s)
return -ENOMEM;
@ -1462,9 +1458,10 @@ _public_ int sd_event_add_post(
s->userdata = userdata;
s->enabled = SD_EVENT_ON;
r = set_put(e->post_sources, s);
r = set_ensure_put(&e->post_sources, NULL, s);
if (r < 0)
return r;
assert(r > 0);
if (ret)
*ret = s;

View File

@ -762,6 +762,32 @@ static const NLType rtnl_tca_option_data_drr_types[] = {
[TCA_DRR_QUANTUM] = { .type = NETLINK_TYPE_U32 },
};
static const NLType rtnl_tca_option_data_ets_quanta_types[] = {
[TCA_ETS_QUANTA_BAND] = { .type = NETLINK_TYPE_U32, },
};
static const NLTypeSystem rtnl_tca_option_data_ets_quanta_type_system = {
.count = ELEMENTSOF(rtnl_tca_option_data_ets_quanta_types),
.types = rtnl_tca_option_data_ets_quanta_types,
};
static const NLType rtnl_tca_option_data_ets_prio_types[] = {
[TCA_ETS_PRIOMAP_BAND] = { .type = NETLINK_TYPE_U8, },
};
static const NLTypeSystem rtnl_tca_option_data_ets_prio_type_system = {
.count = ELEMENTSOF(rtnl_tca_option_data_ets_prio_types),
.types = rtnl_tca_option_data_ets_prio_types,
};
static const NLType rtnl_tca_option_data_ets_types[] = {
[TCA_ETS_NBANDS] = { .type = NETLINK_TYPE_U8 },
[TCA_ETS_NSTRICT] = { .type = NETLINK_TYPE_U8 },
[TCA_ETS_QUANTA] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_tca_option_data_ets_quanta_type_system },
[TCA_ETS_PRIOMAP] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_tca_option_data_ets_prio_type_system },
[TCA_ETS_QUANTA_BAND] = { .type = NETLINK_TYPE_U32 },
};
static const NLType rtnl_tca_option_data_fq_types[] = {
[TCA_FQ_PLIMIT] = { .type = NETLINK_TYPE_U32 },
[TCA_FQ_FLOW_PLIMIT] = { .type = NETLINK_TYPE_U32 },
@ -833,6 +859,7 @@ static const char* const nl_union_tca_option_data_table[] = {
[NL_UNION_TCA_OPTION_DATA_CAKE] = "cake",
[NL_UNION_TCA_OPTION_DATA_CODEL] = "codel",
[NL_UNION_TCA_OPTION_DATA_DRR] = "drr",
[NL_UNION_TCA_OPTION_DATA_ETS] = "ets",
[NL_UNION_TCA_OPTION_DATA_FQ] = "fq",
[NL_UNION_TCA_OPTION_DATA_FQ_CODEL] = "fq_codel",
[NL_UNION_TCA_OPTION_DATA_GRED] = "gred",
@ -853,6 +880,8 @@ static const NLTypeSystem rtnl_tca_option_data_type_systems[] = {
.types = rtnl_tca_option_data_codel_types },
[NL_UNION_TCA_OPTION_DATA_DRR] = { .count = ELEMENTSOF(rtnl_tca_option_data_drr_types),
.types = rtnl_tca_option_data_drr_types },
[NL_UNION_TCA_OPTION_DATA_ETS] = { .count = ELEMENTSOF(rtnl_tca_option_data_ets_types),
.types = rtnl_tca_option_data_ets_types },
[NL_UNION_TCA_OPTION_DATA_FQ] = { .count = ELEMENTSOF(rtnl_tca_option_data_fq_types),
.types = rtnl_tca_option_data_fq_types },
[NL_UNION_TCA_OPTION_DATA_FQ_CODEL] = { .count = ELEMENTSOF(rtnl_tca_option_data_fq_codel_types),

View File

@ -99,6 +99,7 @@ typedef enum NLUnionTCAOptionData {
NL_UNION_TCA_OPTION_DATA_CAKE,
NL_UNION_TCA_OPTION_DATA_CODEL,
NL_UNION_TCA_OPTION_DATA_DRR,
NL_UNION_TCA_OPTION_DATA_ETS,
NL_UNION_TCA_OPTION_DATA_FQ,
NL_UNION_TCA_OPTION_DATA_FQ_CODEL,
NL_UNION_TCA_OPTION_DATA_GRED,

View File

@ -502,9 +502,7 @@ static int run(int argc, char *argv[]) {
int r;
setlocale(LC_ALL, "");
log_show_color(true);
log_parse_environment();
log_open();
log_setup_cli();
r = parse_argv(argc, argv);
if (r <= 0)

View File

@ -1460,9 +1460,7 @@ static int run(int argc, char *argv[]) {
int r;
setlocale(LC_ALL, "");
log_show_color(true);
log_parse_environment();
log_open();
log_setup_cli();
/* The journal merging logic potentially needs a lot of fds. */
(void) rlimit_nofile_bump(HIGH_RLIMIT_NOFILE);

View File

@ -174,15 +174,11 @@ static int set_add_message(Set **set, sd_bus_message *message) {
if (r <= 0)
return r;
r = set_ensure_allocated(set, &bus_message_hash_ops);
if (r < 0)
r = set_ensure_put(set, &bus_message_hash_ops, message);
if (r <= 0)
return r;
r = set_put(*set, message);
if (r < 0)
return r;
sd_bus_message_ref(message);
return 1;
}

View File

@ -2882,9 +2882,7 @@ static int run(int argc, char *argv[]) {
int r;
setlocale(LC_ALL, "");
log_show_color(true);
log_parse_environment();
log_open();
log_setup_cli();
/* The journal merging logic potentially needs a lot of fds. */
(void) rlimit_nofile_bump(HIGH_RLIMIT_NOFILE);

View File

@ -115,6 +115,8 @@ sources = files('''
tc/codel.h
tc/drr.c
tc/drr.h
tc/ets.c
tc/ets.h
tc/fifo.c
tc/fifo.h
tc/fq.c

View File

@ -348,14 +348,7 @@ static int wireguard_resolve_handler(sd_resolve_query *q,
if (ret != 0) {
log_netdev_error(netdev, "Failed to resolve host '%s:%s': %s", peer->endpoint_host, peer->endpoint_port, gai_strerror(ret));
r = set_ensure_allocated(&w->peers_with_failed_endpoint, NULL);
if (r < 0) {
log_oom();
peer->section->invalid = true;
goto resolve_next;
}
r = set_put(w->peers_with_failed_endpoint, peer);
r = set_ensure_put(&w->peers_with_failed_endpoint, NULL, peer);
if (r < 0) {
log_netdev_error(netdev, "Failed to save a peer, dropping the peer: %m");
peer->section->invalid = true;
@ -580,7 +573,7 @@ int config_parse_wireguard_preshared_key(
void *data,
void *userdata) {
_cleanup_(wireguard_peer_free_or_set_invalidp) WireguardPeer *peer = NULL;
WireguardPeer *peer;
Wireguard *w;
int r;
@ -592,12 +585,7 @@ int config_parse_wireguard_preshared_key(
if (r < 0)
return r;
r = wireguard_decode_key_and_warn(rvalue, peer->preshared_key, unit, filename, line, lvalue);
if (r < 0)
return r;
TAKE_PTR(peer);
return 0;
return wireguard_decode_key_and_warn(rvalue, peer->preshared_key, unit, filename, line, lvalue);
}
int config_parse_wireguard_preshared_key_file(
@ -766,10 +754,6 @@ int config_parse_wireguard_endpoint(
w = WIREGUARD(data);
assert(w);
r = wireguard_peer_new_static(w, filename, section_line, &peer);
if (r < 0)
return r;
if (rvalue[0] == '[') {
begin = &rvalue[1];
end = strchr(rvalue, ']');
@ -801,6 +785,10 @@ int config_parse_wireguard_endpoint(
++end;
}
r = wireguard_peer_new_static(w, filename, section_line, &peer);
if (r < 0)
return r;
r = free_and_strndup(&peer->endpoint_host, begin, len);
if (r < 0)
return log_oom();
@ -809,15 +797,11 @@ int config_parse_wireguard_endpoint(
if (r < 0)
return log_oom();
r = set_ensure_allocated(&w->peers_with_unresolved_endpoint, NULL);
r = set_ensure_put(&w->peers_with_unresolved_endpoint, NULL, peer);
if (r < 0)
return log_oom();
TAKE_PTR(peer); /* The peer may already have been in the hash map, that is fine too. */
r = set_put(w->peers_with_unresolved_endpoint, peer);
if (r < 0)
return r;
TAKE_PTR(peer);
return 0;
}
@ -833,7 +817,7 @@ int config_parse_wireguard_keepalive(
void *data,
void *userdata) {
_cleanup_(wireguard_peer_free_or_set_invalidp) WireguardPeer *peer = NULL;
WireguardPeer *peer;
uint16_t keepalive = 0;
Wireguard *w;
int r;
@ -854,15 +838,13 @@ int config_parse_wireguard_keepalive(
r = safe_atou16(rvalue, &keepalive);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r,
"The persistent keepalive interval must be 0-65535. Ignore assignment: %s",
"Failed to parse \"%s\" as keepalive interval (range 065535), ignoring assignment: %m",
rvalue);
return 0;
}
}
peer->persistent_keepalive_interval = keepalive;
TAKE_PTR(peer);
return 0;
}

View File

@ -2818,9 +2818,7 @@ static void warn_networkd_missing(void) {
static int run(int argc, char* argv[]) {
int r;
log_show_color(true);
log_parse_environment();
log_open();
log_setup_cli();
r = parse_argv(argc, argv);
if (r <= 0)

View File

@ -266,11 +266,7 @@ static int address_add_internal(Link *link, Set **addresses,
/* Consider address tentative until we get the real flags from the kernel */
address->flags = IFA_F_TENTATIVE;
r = set_ensure_allocated(addresses, &address_hash_ops);
if (r < 0)
return r;
r = set_put(*addresses, address);
r = set_ensure_put(addresses, &address_hash_ops, address);
if (r < 0)
return r;
if (r == 0)
@ -280,9 +276,7 @@ static int address_add_internal(Link *link, Set **addresses,
if (ret)
*ret = address;
address = NULL;
TAKE_PTR(address);
return 0;
}
@ -302,11 +296,7 @@ int address_add(Link *link, int family, const union in_addr_union *in_addr, unsi
return r;
} else if (r == 0) {
/* Take over a foreign address */
r = set_ensure_allocated(&link->addresses, &address_hash_ops);
if (r < 0)
return r;
r = set_put(link->addresses, address);
r = set_ensure_put(&link->addresses, &address_hash_ops, address);
if (r < 0)
return r;

View File

@ -664,17 +664,8 @@ int config_parse_dhcp_request_options(
continue;
}
if (ltype == AF_INET)
r = set_ensure_allocated(&network->dhcp_request_options, NULL);
else
r = set_ensure_allocated(&network->dhcp6_request_options, NULL);
if (r < 0)
return log_oom();
if (ltype == AF_INET)
r = set_put(network->dhcp_request_options, UINT32_TO_PTR(i));
else
r = set_put(network->dhcp6_request_options, UINT32_TO_PTR(i));
r = set_ensure_put(ltype == AF_INET ? &network->dhcp_request_options : &network->dhcp6_request_options,
NULL, UINT32_TO_PTR(i));
if (r < 0)
log_syntax(unit, LOG_ERR, filename, line, r,
"Failed to store DHCP request option '%s', ignoring assignment: %m", n);

View File

@ -1564,7 +1564,6 @@ int config_parse_dhcp_black_listed_ip_address(
void *userdata) {
Network *network = data;
const char *p;
int r;
assert(filename);
@ -1577,7 +1576,7 @@ int config_parse_dhcp_black_listed_ip_address(
return 0;
}
for (p = rvalue;;) {
for (const char *p = rvalue;;) {
_cleanup_free_ char *n = NULL;
union in_addr_union ip;
@ -1598,11 +1597,7 @@ int config_parse_dhcp_black_listed_ip_address(
continue;
}
r = set_ensure_allocated(&network->dhcp_black_listed_ip, NULL);
if (r < 0)
return log_oom();
r = set_put(network->dhcp_black_listed_ip, UINT32_TO_PTR(ip.in.s_addr));
r = set_ensure_put(&network->dhcp_black_listed_ip, NULL, UINT32_TO_PTR(ip.in.s_addr));
if (r < 0)
log_syntax(unit, LOG_ERR, filename, line, r,
"Failed to store DHCP black listed ip address '%s', ignoring assignment: %m", n);

View File

@ -2125,11 +2125,7 @@ static int link_append_to_master(Link *link, NetDev *netdev) {
if (r < 0)
return r;
r = set_ensure_allocated(&master->slaves, NULL);
if (r < 0)
return r;
r = set_put(master->slaves, link);
r = set_ensure_put(&master->slaves, NULL, link);
if (r <= 0)
return r;
@ -3133,12 +3129,12 @@ static int link_configure_duid(Link *link) {
r = set_put(m->links_requesting_uuid, link);
if (r < 0)
return log_oom();
if (r > 0)
link_ref(link);
r = set_put(m->duids_requesting_uuid, duid);
if (r < 0)
return log_oom();
link_ref(link);
}
return 0;
@ -4413,16 +4409,10 @@ void link_dirty(Link *link) {
/* mark manager dirty as link is dirty */
manager_dirty(link->manager);
r = set_ensure_allocated(&link->manager->dirty_links, NULL);
if (r < 0)
/* allocation errors are ignored */
return;
r = set_put(link->manager->dirty_links, link);
r = set_ensure_put(&link->manager->dirty_links, NULL, link);
if (r <= 0)
/* don't take another ref if the link was already dirty */
/* Ignore allocation errors and don't take another ref if the link was already dirty */
return;
link_ref(link);
}

View File

@ -2309,23 +2309,15 @@ int manager_request_product_uuid(Manager *m, Link *link) {
assert_se(duid = link_get_duid(link));
r = set_ensure_allocated(&m->links_requesting_uuid, NULL);
r = set_ensure_put(&m->links_requesting_uuid, NULL, link);
if (r < 0)
return log_oom();
if (r > 0)
link_ref(link);
r = set_ensure_allocated(&m->duids_requesting_uuid, NULL);
r = set_ensure_put(&m->duids_requesting_uuid, NULL, duid);
if (r < 0)
return log_oom();
r = set_put(m->links_requesting_uuid, link);
if (r < 0)
return log_oom();
r = set_put(m->duids_requesting_uuid, duid);
if (r < 0)
return log_oom();
link_ref(link);
}
if (!m->bus || sd_bus_is_ready(m->bus) <= 0) {

View File

@ -591,10 +591,6 @@ static int ndisc_router_process_rdnss(Link *link, sd_ndisc_router *rt) {
continue;
}
r = set_ensure_allocated(&link->ndisc_rdnss, &ndisc_rdnss_hash_ops);
if (r < 0)
return log_oom();
x = new(NDiscRDNSS, 1);
if (!x)
return log_oom();
@ -604,13 +600,11 @@ static int ndisc_router_process_rdnss(Link *link, sd_ndisc_router *rt) {
.valid_until = time_now + lifetime * USEC_PER_SEC,
};
r = set_put(link->ndisc_rdnss, x);
r = set_ensure_consume(&link->ndisc_rdnss, &ndisc_rdnss_hash_ops, TAKE_PTR(x));
if (r < 0)
return log_oom();
TAKE_PTR(x);
assert(r > 0);
link_dirty(link);
}
@ -686,22 +680,15 @@ static void ndisc_router_process_dnssl(Link *link, sd_ndisc_router *rt) {
continue;
}
r = set_ensure_allocated(&link->ndisc_dnssl, &ndisc_dnssl_hash_ops);
if (r < 0) {
log_oom();
return;
}
s->valid_until = time_now + lifetime * USEC_PER_SEC;
r = set_put(link->ndisc_dnssl, s);
r = set_ensure_consume(&link->ndisc_dnssl, &ndisc_dnssl_hash_ops, TAKE_PTR(s));
if (r < 0) {
log_oom();
return;
}
s = NULL;
assert(r > 0);
link_dirty(link);
}
}
@ -979,22 +966,13 @@ int config_parse_ndisc_black_listed_prefix(
if (set_contains(network->ndisc_black_listed_prefix, &ip.in6))
continue;
r = set_ensure_allocated(&network->ndisc_black_listed_prefix, &in6_addr_hash_ops);
if (r < 0)
return log_oom();
a = newdup(struct in6_addr, &ip.in6, 1);
if (!a)
return log_oom();
r = set_put(network->ndisc_black_listed_prefix, a);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r,
"Failed to store NDISC black listed prefix '%s', ignoring assignment: %m", n);
continue;
}
TAKE_PTR(a);
r = set_ensure_consume(&network->ndisc_black_listed_prefix, &in6_addr_hash_ops, TAKE_PTR(a));
if (r < 0)
return log_oom();
}
return 0;

View File

@ -300,11 +300,7 @@ static int neighbor_add_internal(Link *link, Set **neighbors, int family, const
.lladdr_size = lladdr_size,
};
r = set_ensure_allocated(neighbors, &neighbor_hash_ops);
if (r < 0)
return r;
r = set_put(*neighbors, neighbor);
r = set_ensure_put(neighbors, &neighbor_hash_ops, neighbor);
if (r < 0)
return r;
if (r == 0)
@ -314,8 +310,7 @@ static int neighbor_add_internal(Link *link, Set **neighbors, int family, const
if (ret)
*ret = neighbor;
neighbor = NULL;
TAKE_PTR(neighbor);
return 0;
}
@ -332,11 +327,7 @@ int neighbor_add(Link *link, int family, const union in_addr_union *addr, const
return r;
} else if (r == 0) {
/* Neighbor is foreign, claim it as recognized */
r = set_ensure_allocated(&link->neighbors, &neighbor_hash_ops);
if (r < 0)
return r;
r = set_put(link->neighbors, neighbor);
r = set_ensure_put(&link->neighbors, &neighbor_hash_ops, neighbor);
if (r < 0)
return r;

View File

@ -309,6 +309,12 @@ DeficitRoundRobinScheduler.Handle, config_parse_qdisc_handle,
DeficitRoundRobinSchedulerClass.Parent, config_parse_tclass_parent, TCLASS_KIND_DRR, 0
DeficitRoundRobinSchedulerClass.ClassId, config_parse_tclass_classid, TCLASS_KIND_DRR, 0
DeficitRoundRobinSchedulerClass.Quantum, config_parse_drr_size, TCLASS_KIND_DRR, 0
EnhancedTransmissionSelection.Parent, config_parse_qdisc_parent, QDISC_KIND_ETS, 0
EnhancedTransmissionSelection.Handle, config_parse_qdisc_handle, QDISC_KIND_ETS, 0
EnhancedTransmissionSelection.Bands, config_parse_ets_u8, QDISC_KIND_ETS, 0
EnhancedTransmissionSelection.StrictBands, config_parse_ets_u8, QDISC_KIND_ETS, 0
EnhancedTransmissionSelection.QuantumBytes, config_parse_ets_quanta, QDISC_KIND_ETS, 0
EnhancedTransmissionSelection.PriorityMap, config_parse_ets_prio, QDISC_KIND_ETS, 0
PFIFO.Parent, config_parse_qdisc_parent, QDISC_KIND_PFIFO, 0
PFIFO.Handle, config_parse_qdisc_handle, QDISC_KIND_PFIFO, 0
PFIFO.PacketLimit, config_parse_pfifo_size, QDISC_KIND_PFIFO, 0
@ -355,11 +361,17 @@ HeavyHitterFilter.PacketLimit, config_parse_heavy_hitter_filter_pa
HierarchyTokenBucket.Parent, config_parse_qdisc_parent, QDISC_KIND_HTB, 0
HierarchyTokenBucket.Handle, config_parse_qdisc_handle, QDISC_KIND_HTB, 0
HierarchyTokenBucket.DefaultClass, config_parse_hierarchy_token_bucket_default_class, QDISC_KIND_HTB, 0
HierarchyTokenBucket.RateToQuantum, config_parse_hierarchy_token_bucket_u32, QDISC_KIND_HTB, 0
HierarchyTokenBucketClass.Parent, config_parse_tclass_parent, TCLASS_KIND_HTB, 0
HierarchyTokenBucketClass.ClassId, config_parse_tclass_classid, TCLASS_KIND_HTB, 0
HierarchyTokenBucketClass.Priority, config_parse_hierarchy_token_bucket_u32, TCLASS_KIND_HTB, 0
HierarchyTokenBucketClass.Rate, config_parse_hierarchy_token_bucket_rate, TCLASS_KIND_HTB, 0
HierarchyTokenBucketClass.CeilRate, config_parse_hierarchy_token_bucket_rate, TCLASS_KIND_HTB, 0
HierarchyTokenBucketClass.Priority, config_parse_hierarchy_token_bucket_class_u32, TCLASS_KIND_HTB, 0
HierarchyTokenBucketClass.QuantumBytes, config_parse_hierarchy_token_bucket_class_size, TCLASS_KIND_HTB, 0
HierarchyTokenBucketClass.MTUBytes, config_parse_hierarchy_token_bucket_class_size, TCLASS_KIND_HTB, 0
HierarchyTokenBucketClass.OverheadBytes, config_parse_hierarchy_token_bucket_class_size, TCLASS_KIND_HTB, 0
HierarchyTokenBucketClass.Rate, config_parse_hierarchy_token_bucket_class_rate, TCLASS_KIND_HTB, 0
HierarchyTokenBucketClass.CeilRate, config_parse_hierarchy_token_bucket_class_rate, TCLASS_KIND_HTB, 0
HierarchyTokenBucketClass.BufferBytes, config_parse_hierarchy_token_bucket_class_size, TCLASS_KIND_HTB, 0
HierarchyTokenBucketClass.CeilBufferBytes, config_parse_hierarchy_token_bucket_class_size, TCLASS_KIND_HTB, 0
NetworkEmulator.Parent, config_parse_qdisc_parent, QDISC_KIND_NETEM, 0
NetworkEmulator.Handle, config_parse_qdisc_handle, QDISC_KIND_NETEM, 0
NetworkEmulator.DelaySec, config_parse_network_emulator_delay, QDISC_KIND_NETEM, 0

View File

@ -512,6 +512,7 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi
"ControlledDelay\0"
"DeficitRoundRobinScheduler\0"
"DeficitRoundRobinSchedulerClass\0"
"EnhancedTransmissionSelection\0"
"FairQueueing\0"
"FairQueueingControlledDelay\0"
"GenericRandomEarlyDetection\0"
@ -1268,15 +1269,9 @@ int config_parse_dnssec_negative_trust_anchors(
continue;
}
r = set_ensure_allocated(&n->dnssec_negative_trust_anchors, &dns_name_hash_ops);
r = set_ensure_consume(&n->dnssec_negative_trust_anchors, &dns_name_hash_ops, TAKE_PTR(w));
if (r < 0)
return log_oom();
r = set_put(n->dnssec_negative_trust_anchors, w);
if (r < 0)
return log_oom();
if (r > 0)
w = NULL;
}
return 0;

View File

@ -209,11 +209,7 @@ static int nexthop_add_internal(Link *link, Set **nexthops, NextHop *in, NextHop
nexthop->family = in->family;
nexthop->gw = in->gw;
r = set_ensure_allocated(nexthops, &nexthop_hash_ops);
if (r < 0)
return r;
r = set_put(*nexthops, nexthop);
r = set_ensure_put(nexthops, &nexthop_hash_ops, nexthop);
if (r < 0)
return r;
if (r == 0)
@ -245,11 +241,7 @@ int nexthop_add(Link *link, NextHop *in, NextHop **ret) {
return r;
} else if (r == 0) {
/* Take over a foreign nexthop */
r = set_ensure_allocated(&link->nexthops, &nexthop_hash_ops);
if (r < 0)
return r;
r = set_put(link->nexthops, nexthop);
r = set_ensure_put(&link->nexthops, &nexthop_hash_ops, nexthop);
if (r < 0)
return r;

View File

@ -331,11 +331,7 @@ static int route_add_internal(Link *link, Set **routes, Route *in, Route **ret)
route->initrwnd = in->initrwnd;
route->lifetime = in->lifetime;
r = set_ensure_allocated(routes, &route_hash_ops);
if (r < 0)
return r;
r = set_put(*routes, route);
r = set_ensure_put(routes, &route_hash_ops, route);
if (r < 0)
return r;
if (r == 0)
@ -368,11 +364,7 @@ int route_add(Link *link, Route *in, Route **ret) {
return r;
} else if (r == 0) {
/* Take over a foreign route */
r = set_ensure_allocated(&link->routes, &route_hash_ops);
if (r < 0)
return r;
r = set_put(link->routes, route);
r = set_ensure_put(&link->routes, &route_hash_ops, route);
if (r < 0)
return r;

View File

@ -263,11 +263,7 @@ int routing_policy_rule_make_local(Manager *m, RoutingPolicyRule *rule) {
if (set_contains(m->rules_foreign, rule)) {
set_remove(m->rules_foreign, rule);
r = set_ensure_allocated(&m->rules, &routing_policy_rule_hash_ops);
if (r < 0)
return r;
r = set_put(m->rules, rule);
r = set_ensure_put(&m->rules, &routing_policy_rule_hash_ops, rule);
if (r < 0)
return r;
if (r == 0)
@ -295,11 +291,7 @@ static int routing_policy_rule_add_internal(Manager *m, Set **rules, RoutingPoli
if (r < 0)
return r;
r = set_ensure_allocated(rules, &routing_policy_rule_hash_ops);
if (r < 0)
return r;
r = set_put(*rules, rule);
r = set_ensure_put(rules, &routing_policy_rule_hash_ops, rule);
if (r < 0)
return r;
if (r == 0)
@ -1328,10 +1320,6 @@ int routing_policy_load_rules(const char *state_file, Set **rules) {
if (!l)
return -ENOMEM;
r = set_ensure_allocated(rules, &routing_policy_rule_hash_ops);
if (r < 0)
return r;
STRV_FOREACH(i, l) {
_cleanup_(routing_policy_rule_freep) RoutingPolicyRule *rule = NULL;
@ -1461,7 +1449,7 @@ int routing_policy_load_rules(const char *state_file, Set **rules) {
}
}
r = set_put(*rules, rule);
r = set_ensure_put(rules, &routing_policy_rule_hash_ops, rule);
if (r < 0) {
log_warning_errno(r, "Failed to add RPDB rule to saved DB, ignoring: %s", p);
continue;

338
src/network/tc/ets.c Normal file
View File

@ -0,0 +1,338 @@
/* SPDX-License-Identifier: LGPL-2.1+ */
#include <linux/pkt_sched.h>
#include "alloc-util.h"
#include "conf-parser.h"
#include "ets.h"
#include "memory-util.h"
#include "netlink-util.h"
#include "parse-util.h"
#include "qdisc.h"
#include "string-util.h"
#include "tc-util.h"
static int enhanced_transmission_selection_fill_message(Link *link, QDisc *qdisc, sd_netlink_message *req) {
EnhancedTransmissionSelection *ets;
int r;
assert(link);
assert(qdisc);
assert(req);
ets = ETS(qdisc);
r = sd_netlink_message_open_container_union(req, TCA_OPTIONS, "ets");
if (r < 0)
return log_link_error_errno(link, r, "Could not open container TCA_OPTIONS: %m");
r = sd_netlink_message_append_u8(req, TCA_ETS_NBANDS, ets->n_bands);
if (r < 0)
return log_link_error_errno(link, r, "Could not append TCA_ETS_NBANDS attribute: %m");
if (ets->n_strict > 0) {
r = sd_netlink_message_append_u8(req, TCA_ETS_NSTRICT, ets->n_strict);
if (r < 0)
return log_link_error_errno(link, r, "Could not append TCA_ETS_NSTRICT attribute: %m");
}
if (ets->n_quanta > 0) {
r = sd_netlink_message_open_container(req, TCA_ETS_QUANTA);
if (r < 0)
return log_link_error_errno(link, r, "Could not open container TCA_ETS_QUANTA: %m");
for (unsigned i = 0; i < ets->n_quanta; i++) {
r = sd_netlink_message_append_u32(req, TCA_ETS_QUANTA_BAND, ets->quanta[i]);
if (r < 0)
return log_link_error_errno(link, r, "Could not append TCA_ETS_QUANTA_BAND attribute: %m");
}
r = sd_netlink_message_close_container(req);
if (r < 0)
return log_link_error_errno(link, r, "Could not close container TCA_ETS_QUANTA: %m");
}
if (ets->n_prio > 0) {
r = sd_netlink_message_open_container(req, TCA_ETS_PRIOMAP);
if (r < 0)
return log_link_error_errno(link, r, "Could not open container TCA_ETS_PRIOMAP: %m");
for (unsigned i = 0; i < ets->n_prio; i++) {
r = sd_netlink_message_append_u8(req, TCA_ETS_PRIOMAP_BAND, ets->prio[i]);
if (r < 0)
return log_link_error_errno(link, r, "Could not append TCA_ETS_PRIOMAP_BAND attribute: %m");
}
r = sd_netlink_message_close_container(req);
if (r < 0)
return log_link_error_errno(link, r, "Could not close container TCA_ETS_PRIOMAP: %m");
}
r = sd_netlink_message_close_container(req);
if (r < 0)
return log_link_error_errno(link, r, "Could not close container TCA_OPTIONS: %m");
return 0;
}
int config_parse_ets_u8(
const char *unit,
const char *filename,
unsigned line,
const char *section,
unsigned section_line,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
_cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL;
EnhancedTransmissionSelection *ets;
Network *network = data;
uint8_t v, *p;
int r;
assert(filename);
assert(lvalue);
assert(rvalue);
assert(data);
r = qdisc_new_static(QDISC_KIND_ETS, network, filename, section_line, &qdisc);
if (r == -ENOMEM)
return log_oom();
if (r < 0)
return log_syntax(unit, LOG_ERR, filename, line, r,
"More than one kind of queueing discipline, ignoring assignment: %m");
ets = ETS(qdisc);
if (streq(lvalue, "Bands"))
p = &ets->n_bands;
else if (streq(lvalue, "StrictBands"))
p = &ets->n_strict;
else
assert_not_reached("Invalid lvalue.");
if (isempty(rvalue)) {
*p = 0;
qdisc = NULL;
return 0;
}
r = safe_atou8(rvalue, &v);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r,
"Failed to parse '%s=', ignoring assignment: %s",
lvalue, rvalue);
return 0;
}
if (v > TCQ_ETS_MAX_BANDS) {
log_syntax(unit, LOG_ERR, filename, line, 0,
"Invalid '%s='. The value must be <= %d, ignoring assignment: %s",
lvalue, TCQ_ETS_MAX_BANDS, rvalue);
return 0;
}
*p = v;
qdisc = NULL;
return 0;
}
int config_parse_ets_quanta(
const char *unit,
const char *filename,
unsigned line,
const char *section,
unsigned section_line,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
_cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL;
EnhancedTransmissionSelection *ets;
Network *network = data;
int r;
assert(filename);
assert(lvalue);
assert(rvalue);
assert(data);
r = qdisc_new_static(QDISC_KIND_ETS, network, filename, section_line, &qdisc);
if (r == -ENOMEM)
return log_oom();
if (r < 0)
return log_syntax(unit, LOG_ERR, filename, line, r,
"More than one kind of queueing discipline, ignoring assignment: %m");
ets = ETS(qdisc);
if (isempty(rvalue)) {
memzero(ets->quanta, sizeof(uint32_t) * TCQ_ETS_MAX_BANDS);
ets->n_quanta = 0;
qdisc = NULL;
return 0;
}
for (const char *p = rvalue;;) {
_cleanup_free_ char *word = NULL;
uint64_t v;
r = extract_first_word(&p, &word, NULL, 0);
if (r == -ENOMEM)
return log_oom();
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r,
"Failed to extract next value, ignoring: %m");
continue;
}
if (r == 0)
break;
r = parse_size(word, 1024, &v);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r,
"Failed to parse '%s=', ignoring assignment: %s",
lvalue, word);
continue;
}
if (v == 0 || v > UINT32_MAX) {
log_syntax(unit, LOG_ERR, filename, line, 0,
"Invalid '%s=', ignoring assignment: %s",
lvalue, word);
continue;
}
if (ets->n_quanta >= TCQ_ETS_MAX_BANDS) {
log_syntax(unit, LOG_ERR, filename, line, 0,
"Too many quanta in '%s=', ignoring assignment: %s",
lvalue, word);
continue;
}
ets->quanta[ets->n_quanta++] = v;
}
qdisc = NULL;
return 0;
}
int config_parse_ets_prio(
const char *unit,
const char *filename,
unsigned line,
const char *section,
unsigned section_line,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
_cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL;
EnhancedTransmissionSelection *ets;
Network *network = data;
int r;
assert(filename);
assert(lvalue);
assert(rvalue);
assert(data);
r = qdisc_new_static(QDISC_KIND_ETS, network, filename, section_line, &qdisc);
if (r == -ENOMEM)
return log_oom();
if (r < 0)
return log_syntax(unit, LOG_ERR, filename, line, r,
"More than one kind of queueing discipline, ignoring assignment: %m");
ets = ETS(qdisc);
if (isempty(rvalue)) {
memzero(ets->prio, sizeof(uint8_t) * (TC_PRIO_MAX + 1));
ets->n_prio = 0;
qdisc = NULL;
return 0;
}
for (const char *p = rvalue;;) {
_cleanup_free_ char *word = NULL;
uint8_t v;
r = extract_first_word(&p, &word, NULL, 0);
if (r == -ENOMEM)
return log_oom();
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r,
"Failed to extract next value, ignoring: %m");
continue;
}
if (r == 0)
break;
r = safe_atou8(word, &v);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r,
"Failed to parse '%s=', ignoring assignment: %s",
lvalue, word);
continue;
}
if (ets->n_quanta > TC_PRIO_MAX) {
log_syntax(unit, LOG_ERR, filename, line, 0,
"Too many priomap in '%s=', ignoring assignment: %s",
lvalue, word);
continue;
}
ets->prio[ets->n_prio++] = v;
}
qdisc = NULL;
return 0;
}
static int enhanced_transmission_selection_verify(QDisc *qdisc) {
EnhancedTransmissionSelection *ets;
assert(qdisc);
ets = ETS(qdisc);
if (ets->n_bands == 0)
ets->n_bands = ets->n_strict + ets->n_quanta;
if (ets->n_bands == 0)
return log_warning_errno(SYNTHETIC_ERRNO(EINVAL),
"%s: At least one of Band=, Strict=, or Quanta= must be specified. "
"Ignoring [EnhancedTransmissionSelection] section from line %u.",
qdisc->section->filename, qdisc->section->line);
if (ets->n_bands < ets->n_strict + ets->n_quanta)
return log_warning_errno(SYNTHETIC_ERRNO(EINVAL),
"%s: Not enough total bands to cover all the strict bands and quanta. "
"Ignoring [EnhancedTransmissionSelection] section from line %u.",
qdisc->section->filename, qdisc->section->line);
for (unsigned i = 0; i < ets->n_prio; i++)
if (ets->prio[i] >= ets->n_bands)
return log_warning_errno(SYNTHETIC_ERRNO(EINVAL),
"%s: PriorityMap= element is out of bands. "
"Ignoring [EnhancedTransmissionSelection] section from line %u.",
qdisc->section->filename, qdisc->section->line);
return 0;
}
const QDiscVTable ets_vtable = {
.object_size = sizeof(EnhancedTransmissionSelection),
.tca_kind = "ets",
.fill_message = enhanced_transmission_selection_fill_message,
.verify = enhanced_transmission_selection_verify,
};

25
src/network/tc/ets.h Normal file
View File

@ -0,0 +1,25 @@
/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
#include <linux/pkt_sched.h>
#include "conf-parser.h"
#include "qdisc.h"
typedef struct EnhancedTransmissionSelection {
QDisc meta;
uint8_t n_bands;
uint8_t n_strict;
unsigned n_quanta;
uint32_t quanta[TCQ_ETS_MAX_BANDS];
unsigned n_prio;
uint8_t prio[TC_PRIO_MAX + 1];
} EnhancedTransmissionSelection;
DEFINE_QDISC_CAST(ETS, EnhancedTransmissionSelection);
extern const QDiscVTable ets_vtable;
CONFIG_PARSER_PROTOTYPE(config_parse_ets_u8);
CONFIG_PARSER_PROTOTYPE(config_parse_ets_quanta);
CONFIG_PARSER_PROTOTYPE(config_parse_ets_prio);

View File

@ -11,10 +11,12 @@
#include "string-util.h"
#include "tc-util.h"
#define HTB_DEFAULT_RATE_TO_QUANTUM 10
#define HTB_DEFAULT_MTU 1600 /* Ethernet packet length */
static int hierarchy_token_bucket_fill_message(Link *link, QDisc *qdisc, sd_netlink_message *req) {
HierarchyTokenBucket *htb;
struct tc_htb_glob opt = {
.rate2quantum = 10,
.version = 3,
};
int r;
@ -25,6 +27,7 @@ static int hierarchy_token_bucket_fill_message(Link *link, QDisc *qdisc, sd_netl
htb = HTB(qdisc);
opt.rate2quantum = htb->rate_to_quantum;
opt.defcls = htb->default_class;
r = sd_netlink_message_open_container_union(req, TCA_OPTIONS, "htb");
@ -92,16 +95,80 @@ int config_parse_hierarchy_token_bucket_default_class(
return 0;
}
int config_parse_hierarchy_token_bucket_u32(
const char *unit,
const char *filename,
unsigned line,
const char *section,
unsigned section_line,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
_cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL;
HierarchyTokenBucket *htb;
Network *network = data;
int r;
assert(filename);
assert(lvalue);
assert(rvalue);
assert(data);
r = qdisc_new_static(QDISC_KIND_HTB, network, filename, section_line, &qdisc);
if (r == -ENOMEM)
return log_oom();
if (r < 0)
return log_syntax(unit, LOG_ERR, filename, line, r,
"More than one kind of queueing discipline, ignoring assignment: %m");
htb = HTB(qdisc);
if (isempty(rvalue)) {
htb->rate_to_quantum = HTB_DEFAULT_RATE_TO_QUANTUM;
qdisc = NULL;
return 0;
}
r = safe_atou32(rvalue, &htb->rate_to_quantum);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r,
"Failed to parse '%s=', ignoring assignment: %s",
lvalue, rvalue);
return 0;
}
qdisc = NULL;
return 0;
}
static int hierarchy_token_bucket_init(QDisc *qdisc) {
HierarchyTokenBucket *htb;
assert(qdisc);
htb = HTB(qdisc);
htb->rate_to_quantum = HTB_DEFAULT_RATE_TO_QUANTUM;
return 0;
}
const QDiscVTable htb_vtable = {
.object_size = sizeof(HierarchyTokenBucket),
.tca_kind = "htb",
.fill_message = hierarchy_token_bucket_fill_message,
.init = hierarchy_token_bucket_init,
};
static int hierarchy_token_bucket_class_fill_message(Link *link, TClass *tclass, sd_netlink_message *req) {
HierarchyTokenBucketClass *htb;
struct tc_htb_opt opt = {};
uint32_t rtab[256], ctab[256], mtu = 1600; /* Ethernet packet length */
uint32_t rtab[256], ctab[256];
int r;
assert(link);
@ -110,25 +177,26 @@ static int hierarchy_token_bucket_class_fill_message(Link *link, TClass *tclass,
htb = TCLASS_TO_HTB(tclass);
if (htb->ceil_rate == 0)
htb->ceil_rate = htb->rate;
opt.prio = htb->priority;
opt.quantum = htb->quantum;
opt.rate.rate = (htb->rate >= (1ULL << 32)) ? ~0U : htb->rate;
opt.ceil.rate = (htb->ceil_rate >= (1ULL << 32)) ? ~0U : htb->ceil_rate;
r = tc_transmit_time(htb->rate, mtu, &opt.buffer);
opt.rate.overhead = htb->overhead;
opt.ceil.overhead = htb->overhead;
r = tc_transmit_time(htb->rate, htb->buffer, &opt.buffer);
if (r < 0)
return log_link_error_errno(link, r, "Failed to calculate buffer size: %m");
r = tc_transmit_time(htb->ceil_rate, mtu, &opt.cbuffer);
r = tc_transmit_time(htb->ceil_rate, htb->ceil_buffer, &opt.cbuffer);
if (r < 0)
return log_link_error_errno(link, r, "Failed to calculate ceil buffer size: %m");
r = tc_fill_ratespec_and_table(&opt.rate, rtab, mtu);
r = tc_fill_ratespec_and_table(&opt.rate, rtab, htb->mtu);
if (r < 0)
return log_link_error_errno(link, r, "Failed to calculate rate table: %m");
r = tc_fill_ratespec_and_table(&opt.ceil, ctab, mtu);
r = tc_fill_ratespec_and_table(&opt.ceil, ctab, htb->mtu);
if (r < 0)
return log_link_error_errno(link, r, "Failed to calculate ceil rate table: %m");
@ -166,7 +234,7 @@ static int hierarchy_token_bucket_class_fill_message(Link *link, TClass *tclass,
return 0;
}
int config_parse_hierarchy_token_bucket_u32(
int config_parse_hierarchy_token_bucket_class_u32(
const char *unit,
const char *filename,
unsigned line,
@ -181,6 +249,7 @@ int config_parse_hierarchy_token_bucket_u32(
_cleanup_(tclass_free_or_set_invalidp) TClass *tclass = NULL;
HierarchyTokenBucketClass *htb;
Network *network = data;
uint32_t v;
int r;
assert(filename);
@ -197,12 +266,11 @@ int config_parse_hierarchy_token_bucket_u32(
if (isempty(rvalue)) {
htb->priority = 0;
tclass = NULL;
return 0;
}
r = safe_atou32(rvalue, &htb->priority);
r = safe_atou32(rvalue, &v);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r,
"Failed to parse '%s=', ignoring assignment: %s",
@ -210,12 +278,93 @@ int config_parse_hierarchy_token_bucket_u32(
return 0;
}
htb->priority = v;
tclass = NULL;
return 0;
}
int config_parse_hierarchy_token_bucket_rate(
int config_parse_hierarchy_token_bucket_class_size(
const char *unit,
const char *filename,
unsigned line,
const char *section,
unsigned section_line,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
_cleanup_(tclass_free_or_set_invalidp) TClass *tclass = NULL;
HierarchyTokenBucketClass *htb;
Network *network = data;
uint64_t v;
int r;
assert(filename);
assert(lvalue);
assert(rvalue);
assert(data);
r = tclass_new_static(TCLASS_KIND_HTB, network, filename, section_line, &tclass);
if (r < 0)
return log_syntax(unit, LOG_ERR, filename, line, r,
"Failed to create traffic control class, ignoring assignment: %m");
htb = TCLASS_TO_HTB(tclass);
if (isempty(rvalue)) {
if (streq(lvalue, "QuantumBytes"))
htb->quantum = 0;
else if (streq(lvalue, "MTUBytes"))
htb->mtu = HTB_DEFAULT_MTU;
else if (streq(lvalue, "OverheadBytes"))
htb->overhead = 0;
else if (streq(lvalue, "BufferBytes"))
htb->buffer = 0;
else if (streq(lvalue, "CeilBufferBytes"))
htb->ceil_buffer = 0;
else
assert_not_reached("Invalid lvalue");
tclass = NULL;
return 0;
}
r = parse_size(rvalue, 1024, &v);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r,
"Failed to parse '%s=', ignoring assignment: %s",
lvalue, rvalue);
return 0;
}
if ((streq(lvalue, "OverheadBytes") && v > UINT16_MAX) || v > UINT32_MAX) {
log_syntax(unit, LOG_ERR, filename, line, 0,
"Invalid '%s=', ignoring assignment: %s",
lvalue, rvalue);
return 0;
}
if (streq(lvalue, "QuantumBytes"))
htb->quantum = v;
else if (streq(lvalue, "OverheadBytes"))
htb->overhead = v;
else if (streq(lvalue, "MTUBytes"))
htb->mtu = v;
else if (streq(lvalue, "BufferBytes"))
htb->buffer = v;
else if (streq(lvalue, "CeilBufferBytes"))
htb->ceil_buffer = v;
else
assert_not_reached("Invalid lvalue");
tclass = NULL;
return 0;
}
int config_parse_hierarchy_token_bucket_class_rate(
const char *unit,
const char *filename,
unsigned line,
@ -272,8 +421,53 @@ int config_parse_hierarchy_token_bucket_rate(
return 0;
}
static int hierarchy_token_bucket_class_init(TClass *tclass) {
HierarchyTokenBucketClass *htb;
assert(tclass);
htb = TCLASS_TO_HTB(tclass);
htb->mtu = HTB_DEFAULT_MTU;
return 0;
}
static int hierarchy_token_bucket_class_verify(TClass *tclass) {
HierarchyTokenBucketClass *htb;
uint32_t hz;
int r;
assert(tclass);
htb = TCLASS_TO_HTB(tclass);
if (htb->rate == 0)
return log_warning_errno(SYNTHETIC_ERRNO(EINVAL),
"%s: Rate= is mandatory. "
"Ignoring [HierarchyTokenBucketClass] section from line %u.",
tclass->section->filename, tclass->section->line);
/* if CeilRate= setting is missing, use the same as Rate= */
if (htb->ceil_rate == 0)
htb->ceil_rate = htb->rate;
r = tc_init(NULL, &hz);
if (r < 0)
return log_error_errno(r, "Failed to read /proc/net/psched: %m");
if (htb->buffer == 0)
htb->buffer = htb->rate / hz + htb->mtu;
if (htb->ceil_buffer == 0)
htb->ceil_buffer = htb->ceil_rate / hz + htb->mtu;
return 0;
}
const TClassVTable htb_tclass_vtable = {
.object_size = sizeof(HierarchyTokenBucketClass),
.tca_kind = "htb",
.fill_message = hierarchy_token_bucket_class_fill_message,
.init = hierarchy_token_bucket_class_init,
.verify = hierarchy_token_bucket_class_verify,
};

View File

@ -9,23 +9,31 @@ typedef struct HierarchyTokenBucket {
QDisc meta;
uint32_t default_class;
uint32_t rate_to_quantum;
} HierarchyTokenBucket;
DEFINE_QDISC_CAST(HTB, HierarchyTokenBucket);
extern const QDiscVTable htb_vtable;
CONFIG_PARSER_PROTOTYPE(config_parse_hierarchy_token_bucket_default_class);
CONFIG_PARSER_PROTOTYPE(config_parse_hierarchy_token_bucket_u32);
typedef struct HierarchyTokenBucketClass {
TClass meta;
uint32_t priority;
uint32_t quantum;
uint32_t mtu;
uint16_t overhead;
uint64_t rate;
uint32_t buffer;
uint64_t ceil_rate;
uint32_t ceil_buffer;
} HierarchyTokenBucketClass;
DEFINE_TCLASS_CAST(HTB, HierarchyTokenBucketClass);
extern const TClassVTable htb_tclass_vtable;
CONFIG_PARSER_PROTOTYPE(config_parse_hierarchy_token_bucket_u32);
CONFIG_PARSER_PROTOTYPE(config_parse_hierarchy_token_bucket_rate);
CONFIG_PARSER_PROTOTYPE(config_parse_hierarchy_token_bucket_class_u32);
CONFIG_PARSER_PROTOTYPE(config_parse_hierarchy_token_bucket_class_size);
CONFIG_PARSER_PROTOTYPE(config_parse_hierarchy_token_bucket_class_rate);

View File

@ -20,6 +20,7 @@ const QDiscVTable * const qdisc_vtable[_QDISC_KIND_MAX] = {
[QDISC_KIND_CAKE] = &cake_vtable,
[QDISC_KIND_CODEL] = &codel_vtable,
[QDISC_KIND_DRR] = &drr_vtable,
[QDISC_KIND_ETS] = &ets_vtable,
[QDISC_KIND_FQ] = &fq_vtable,
[QDISC_KIND_FQ_CODEL] = &fq_codel_vtable,
[QDISC_KIND_GRED] = &gred_vtable,

View File

@ -13,6 +13,7 @@ typedef enum QDiscKind {
QDISC_KIND_CAKE,
QDISC_KIND_CODEL,
QDISC_KIND_DRR,
QDISC_KIND_ETS,
QDISC_KIND_FQ,
QDISC_KIND_FQ_CODEL,
QDISC_KIND_GRED,
@ -87,6 +88,7 @@ CONFIG_PARSER_PROTOTYPE(config_parse_qdisc_handle);
#include "cake.h"
#include "codel.h"
#include "ets.h"
#include "fifo.h"
#include "fq-codel.h"
#include "fq.h"

View File

@ -8,38 +8,46 @@
#include "tc-util.h"
#include "time-util.h"
static int tc_init(double *ticks_in_usec) {
uint32_t clock_resolution, ticks_to_usec, usec_to_ticks;
_cleanup_free_ char *line = NULL;
double clock_factor;
int r;
int tc_init(double *ret_ticks_in_usec, uint32_t *ret_hz) {
static double ticks_in_usec = -1;
static uint32_t hz;
r = read_one_line_file("/proc/net/psched", &line);
if (r < 0)
return r;
if (ticks_in_usec < 0) {
uint32_t clock_resolution, ticks_to_usec, usec_to_ticks;
_cleanup_free_ char *line = NULL;
double clock_factor;
int r;
r = sscanf(line, "%08x%08x%08x", &ticks_to_usec, &usec_to_ticks, &clock_resolution);
if (r < 3)
return -EIO;
r = read_one_line_file("/proc/net/psched", &line);
if (r < 0)
return r;
clock_factor = (double) clock_resolution / USEC_PER_SEC;
*ticks_in_usec = (double) ticks_to_usec / usec_to_ticks * clock_factor;
r = sscanf(line, "%08x%08x%08x%08x", &ticks_to_usec, &usec_to_ticks, &clock_resolution, &hz);
if (r < 4)
return -EIO;
clock_factor = (double) clock_resolution / USEC_PER_SEC;
ticks_in_usec = (double) ticks_to_usec / usec_to_ticks * clock_factor;
}
if (ret_ticks_in_usec)
*ret_ticks_in_usec = ticks_in_usec;
if (ret_hz)
*ret_hz = hz;
return 0;
}
int tc_time_to_tick(usec_t t, uint32_t *ret) {
static double ticks_in_usec = -1;
double ticks_in_usec;
usec_t a;
int r;
assert(ret);
if (ticks_in_usec < 0) {
r = tc_init(&ticks_in_usec);
if (r < 0)
return r;
}
r = tc_init(&ticks_in_usec, NULL);
if (r < 0)
return r;
a = t * ticks_in_usec;
if (a > UINT32_MAX)

View File

@ -6,6 +6,7 @@
#include "time-util.h"
int tc_init(double *ret_ticks_in_usec, uint32_t *ret_hz);
int tc_time_to_tick(usec_t t, uint32_t *ret);
int parse_tc_percent(const char *s, uint32_t *percent);
int tc_transmit_time(uint64_t rate, uint32_t size, uint32_t *ret);

View File

@ -1125,7 +1125,7 @@ int portable_detach(
sd_bus_error *error) {
_cleanup_(lookup_paths_free) LookupPaths paths = {};
_cleanup_set_free_free_ Set *unit_files = NULL, *markers = NULL;
_cleanup_set_free_ Set *unit_files = NULL, *markers = NULL;
_cleanup_closedir_ DIR *d = NULL;
const char *where, *item;
Iterator iterator;
@ -1149,10 +1149,6 @@ int portable_detach(
return log_debug_errno(errno, "Failed to open '%s' directory: %m", where);
}
markers = set_new(&path_hash_ops);
if (!markers)
return -ENOMEM;
FOREACH_DIRENT(de, d, return log_debug_errno(errno, "Failed to enumerate '%s' directory: %m", where)) {
_cleanup_free_ char *marker = NULL;
UnitFileState state;
@ -1193,15 +1189,9 @@ int portable_detach(
if (path_is_absolute(marker) &&
!image_in_search_path(IMAGE_PORTABLE, marker)) {
r = set_ensure_allocated(&markers, &path_hash_ops);
r = set_ensure_consume(&markers, &path_hash_ops_free, TAKE_PTR(marker));
if (r < 0)
return r;
r = set_put(markers, marker);
if (r >= 0)
marker = NULL;
else if (r != -EEXIST)
return r;
}
}

View File

@ -1119,9 +1119,7 @@ static int run(int argc, char *argv[]) {
int r;
log_show_color(true);
log_parse_environment();
log_open();
log_setup_cli();
r = parse_argv(argc, argv);
if (r <= 0)

View File

@ -3174,9 +3174,7 @@ static int run(int argc, char **argv) {
int r;
setlocale(LC_ALL, "");
log_show_color(true);
log_parse_environment();
log_open();
log_setup_cli();
if (streq(program_invocation_short_name, "resolvconf"))
r = resolvconf_parse_argv(argc, argv);

View File

@ -94,7 +94,7 @@ static int dns_query_candidate_next_search_domain(DnsQueryCandidate *c) {
}
static int dns_query_candidate_add_transaction(DnsQueryCandidate *c, DnsResourceKey *key) {
DnsTransaction *t;
_cleanup_(dns_transaction_gcp) DnsTransaction *t = NULL;
int r;
assert(c);
@ -105,39 +105,26 @@ static int dns_query_candidate_add_transaction(DnsQueryCandidate *c, DnsResource
r = dns_transaction_new(&t, c->scope, key);
if (r < 0)
return r;
} else {
if (set_contains(c->transactions, t))
return 0;
}
r = set_ensure_allocated(&c->transactions, NULL);
if (r < 0)
goto gc;
r = set_ensure_allocated(&t->notify_query_candidates, NULL);
if (r < 0)
goto gc;
} else if (set_contains(c->transactions, t))
return 0;
r = set_ensure_allocated(&t->notify_query_candidates_done, NULL);
if (r < 0)
goto gc;
return r;
r = set_put(t->notify_query_candidates, c);
r = set_ensure_put(&t->notify_query_candidates, NULL, c);
if (r < 0)
goto gc;
return r;
r = set_put(c->transactions, t);
r = set_ensure_put(&c->transactions, NULL, t);
if (r < 0) {
(void) set_remove(t->notify_query_candidates, c);
goto gc;
return r;
}
t->clamp_ttl = c->query->clamp_ttl;
TAKE_PTR(t);
return 1;
gc:
dns_transaction_gc(t);
return r;
}
static int dns_query_candidate_go(DnsQueryCandidate *c) {

View File

@ -1254,11 +1254,7 @@ int dns_scope_announce(DnsScope *scope, bool goodbye) {
if (!scope->announced &&
dns_resource_key_is_dnssd_ptr(z->rr->key)) {
if (!set_contains(types, dns_resource_key_name(z->rr->key))) {
r = set_ensure_allocated(&types, &dns_name_hash_ops);
if (r < 0)
return log_debug_errno(r, "Failed to allocate set: %m");
r = set_put(types, dns_resource_key_name(z->rr->key));
r = set_ensure_put(&types, &dns_name_hash_ops, dns_resource_key_name(z->rr->key));
if (r < 0)
return log_debug_errno(r, "Failed to add item to set: %m");
}

View File

@ -278,7 +278,7 @@ static int dns_stub_stream_complete(DnsStream *s, int error) {
}
static void dns_stub_process_query(Manager *m, DnsStream *s, DnsPacket *p) {
DnsQuery *q = NULL;
_cleanup_(dns_query_freep) DnsQuery *q = NULL;
int r;
assert(m);
@ -289,52 +289,52 @@ static void dns_stub_process_query(Manager *m, DnsStream *s, DnsPacket *p) {
in_addr_is_localhost(p->family, &p->destination) <= 0) {
log_error("Got packet on unexpected IP range, refusing.");
dns_stub_send_failure(m, s, p, DNS_RCODE_SERVFAIL, false);
goto fail;
return;
}
r = dns_packet_extract(p);
if (r < 0) {
log_debug_errno(r, "Failed to extract resources from incoming packet, ignoring packet: %m");
dns_stub_send_failure(m, s, p, DNS_RCODE_FORMERR, false);
goto fail;
return;
}
if (!DNS_PACKET_VERSION_SUPPORTED(p)) {
log_debug("Got EDNS OPT field with unsupported version number.");
dns_stub_send_failure(m, s, p, DNS_RCODE_BADVERS, false);
goto fail;
return;
}
if (dns_type_is_obsolete(p->question->keys[0]->type)) {
log_debug("Got message with obsolete key type, refusing.");
dns_stub_send_failure(m, s, p, DNS_RCODE_NOTIMP, false);
goto fail;
return;
}
if (dns_type_is_zone_transer(p->question->keys[0]->type)) {
log_debug("Got request for zone transfer, refusing.");
dns_stub_send_failure(m, s, p, DNS_RCODE_NOTIMP, false);
goto fail;
return;
}
if (!DNS_PACKET_RD(p)) {
/* If the "rd" bit is off (i.e. recursion was not requested), then refuse operation */
log_debug("Got request with recursion disabled, refusing.");
dns_stub_send_failure(m, s, p, DNS_RCODE_REFUSED, false);
goto fail;
return;
}
if (DNS_PACKET_DO(p) && DNS_PACKET_CD(p)) {
log_debug("Got request with DNSSEC CD bit set, refusing.");
dns_stub_send_failure(m, s, p, DNS_RCODE_NOTIMP, false);
goto fail;
return;
}
r = dns_query_new(m, &q, p->question, p->question, 0, SD_RESOLVED_PROTOCOLS_ALL|SD_RESOLVED_NO_SEARCH);
if (r < 0) {
log_error_errno(r, "Failed to generate query object: %m");
dns_stub_send_failure(m, s, p, DNS_RCODE_SERVFAIL, false);
goto fail;
return;
}
/* Request that the TTL is corrected by the cached time for this lookup, so that we return vaguely useful TTLs */
@ -348,30 +348,23 @@ static void dns_stub_process_query(Manager *m, DnsStream *s, DnsPacket *p) {
/* Remember which queries belong to this stream, so that we can cancel them when the stream
* is disconnected early */
r = set_ensure_allocated(&s->queries, &trivial_hash_ops);
r = set_ensure_put(&s->queries, NULL, q);
if (r < 0) {
log_oom();
goto fail;
}
if (set_put(s->queries, q) < 0) {
log_oom();
goto fail;
return;
}
assert(r > 0);
}
r = dns_query_go(q);
if (r < 0) {
log_error_errno(r, "Failed to start query: %m");
dns_stub_send_failure(m, s, p, DNS_RCODE_SERVFAIL, false);
goto fail;
return;
}
log_debug("Processing query...");
return;
fail:
dns_query_free(q);
TAKE_PTR(q);
}
static int on_dns_stub_packet(sd_event_source *s, int fd, uint32_t revents, void *userdata) {

View File

@ -1501,11 +1501,7 @@ static int dns_transaction_make_packet_mdns(DnsTransaction *t) {
add_known_answers = true;
if (t->key->type == DNS_TYPE_ANY) {
r = set_ensure_allocated(&keys, &dns_resource_key_hash_ops);
if (r < 0)
return r;
r = set_put(keys, t->key);
r = set_ensure_put(&keys, &dns_resource_key_hash_ops, t->key);
if (r < 0)
return r;
}
@ -1571,11 +1567,7 @@ static int dns_transaction_make_packet_mdns(DnsTransaction *t) {
add_known_answers = true;
if (other->key->type == DNS_TYPE_ANY) {
r = set_ensure_allocated(&keys, &dns_resource_key_hash_ops);
if (r < 0)
return r;
r = set_put(keys, other->key);
r = set_ensure_put(&keys, &dns_resource_key_hash_ops, other->key);
if (r < 0)
return r;
}
@ -1800,7 +1792,7 @@ static int dns_transaction_find_cyclic(DnsTransaction *t, DnsTransaction *aux) {
}
static int dns_transaction_add_dnssec_transaction(DnsTransaction *t, DnsResourceKey *key, DnsTransaction **ret) {
DnsTransaction *aux;
_cleanup_(dns_transaction_gcp) DnsTransaction *aux = NULL;
int r;
assert(t);
@ -1833,34 +1825,22 @@ static int dns_transaction_add_dnssec_transaction(DnsTransaction *t, DnsResource
}
}
r = set_ensure_allocated(&t->dnssec_transactions, NULL);
if (r < 0)
goto gc;
r = set_ensure_allocated(&aux->notify_transactions, NULL);
if (r < 0)
goto gc;
r = set_ensure_allocated(&aux->notify_transactions_done, NULL);
if (r < 0)
goto gc;
return r;
r = set_put(t->dnssec_transactions, aux);
r = set_ensure_put(&t->dnssec_transactions, NULL, aux);
if (r < 0)
goto gc;
return r;;
r = set_put(aux->notify_transactions, t);
r = set_ensure_put(&aux->notify_transactions, NULL, t);
if (r < 0) {
(void) set_remove(t->dnssec_transactions, aux);
goto gc;
return r;
}
*ret = aux;
*ret = TAKE_PTR(aux);
return 1;
gc:
dns_transaction_gc(aux);
return r;
}
static int dns_transaction_request_dnssec_rr(DnsTransaction *t, DnsResourceKey *key) {

View File

@ -138,6 +138,8 @@ int dns_transaction_new(DnsTransaction **ret, DnsScope *s, DnsResourceKey *key);
DnsTransaction* dns_transaction_free(DnsTransaction *t);
bool dns_transaction_gc(DnsTransaction *t);
DEFINE_TRIVIAL_CLEANUP_FUNC(DnsTransaction*, dns_transaction_gc);
int dns_transaction_go(DnsTransaction *t);
void dns_transaction_process_reply(DnsTransaction *t, DnsPacket *p);

View File

@ -393,16 +393,10 @@ static int dns_trust_anchor_load_negative(DnsTrustAnchor *d, const char *path, u
return -EINVAL;
}
r = set_ensure_allocated(&d->negative_by_name, &dns_name_hash_ops);
r = set_ensure_consume(&d->negative_by_name, &dns_name_hash_ops, TAKE_PTR(domain));
if (r < 0)
return log_oom();
r = set_put(d->negative_by_name, domain);
if (r < 0)
return log_oom();
if (r > 0)
domain = NULL;
return 0;
}
@ -592,11 +586,7 @@ static int dns_trust_anchor_revoked_put(DnsTrustAnchor *d, DnsResourceRecord *rr
assert(d);
r = set_ensure_allocated(&d->revoked_by_rr, &dns_resource_record_hash_ops);
if (r < 0)
return r;
r = set_put(d->revoked_by_rr, rr);
r = set_ensure_put(&d->revoked_by_rr, &dns_resource_record_hash_ops, rr);
if (r < 0)
return r;
if (r > 0)

View File

@ -162,7 +162,7 @@ static int dns_zone_link_item(DnsZone *z, DnsZoneItem *i) {
}
static int dns_zone_item_probe_start(DnsZoneItem *i) {
DnsTransaction *t;
_cleanup_(dns_transaction_gcp) DnsTransaction *t = NULL;
int r;
assert(i);
@ -183,25 +183,20 @@ static int dns_zone_item_probe_start(DnsZoneItem *i) {
return r;
}
r = set_ensure_allocated(&t->notify_zone_items, NULL);
if (r < 0)
goto gc;
r = set_ensure_allocated(&t->notify_zone_items_done, NULL);
if (r < 0)
goto gc;
return r;
r = set_put(t->notify_zone_items, i);
r = set_ensure_put(&t->notify_zone_items, NULL, i);
if (r < 0)
goto gc;
return r;
i->probe_transaction = t;
t->probing = true;
i->probe_transaction = TAKE_PTR(t);
if (t->state == DNS_TRANSACTION_NULL) {
if (i->probe_transaction->state == DNS_TRANSACTION_NULL) {
i->block_ready++;
r = dns_transaction_go(t);
r = dns_transaction_go(i->probe_transaction);
i->block_ready--;
if (r < 0) {
@ -212,10 +207,6 @@ static int dns_zone_item_probe_start(DnsZoneItem *i) {
dns_zone_item_notify(i);
return 0;
gc:
dns_transaction_gc(t);
return r;
}
int dns_zone_put(DnsZone *z, DnsScope *s, DnsResourceRecord *rr, bool probe) {

View File

@ -120,15 +120,10 @@ static int parse_line(EtcHosts *hosts, unsigned nr, const char *line) {
/* Optimize the case where we don't need to store any addresses, by storing
* only the name in a dedicated Set instead of the hashmap */
r = set_ensure_allocated(&hosts->no_address, &dns_name_hash_ops);
if (r < 0)
return log_oom();
r = set_put(hosts->no_address, name);
r = set_ensure_consume(&hosts->no_address, &dns_name_hash_ops, TAKE_PTR(name));
if (r < 0)
return r;
TAKE_PTR(name);
continue;
}

View File

@ -613,13 +613,9 @@ int bus_message_print_all_properties(
return r;
if (found_properties) {
r = set_ensure_allocated(found_properties, &string_hash_ops);
r = set_ensure_put(found_properties, &string_hash_ops, name);
if (r < 0)
return log_oom();
r = set_put(*found_properties, name);
if (r < 0 && r != -EEXIST)
return log_oom();
}
name_with_equal = strjoin(name, "=");

View File

@ -1742,17 +1742,13 @@ int seccomp_restrict_archs(Set *archs) {
return 0;
}
int parse_syscall_archs(char **l, Set **archs) {
_cleanup_set_free_ Set *_archs = NULL;
int parse_syscall_archs(char **l, Set **ret_archs) {
_cleanup_set_free_ Set *archs = NULL;
char **s;
int r;
assert(l);
assert(archs);
r = set_ensure_allocated(&_archs, NULL);
if (r < 0)
return r;
assert(ret_archs);
STRV_FOREACH(s, l) {
uint32_t a;
@ -1761,13 +1757,12 @@ int parse_syscall_archs(char **l, Set **archs) {
if (r < 0)
return -EINVAL;
r = set_put(_archs, UINT32_TO_PTR(a + 1));
r = set_ensure_put(&archs, NULL, UINT32_TO_PTR(a + 1));
if (r < 0)
return -ENOMEM;
}
*archs = TAKE_PTR(_archs);
*ret_archs = TAKE_PTR(archs);
return 0;
}

View File

@ -105,6 +105,6 @@ extern const uint32_t seccomp_local_archs[];
DEFINE_TRIVIAL_CLEANUP_FUNC(scmp_filter_ctx, seccomp_release);
int parse_syscall_archs(char **l, Set **archs);
int parse_syscall_archs(char **l, Set **ret_archs);
uint32_t scmp_act_kill_process(void);

View File

@ -377,15 +377,9 @@ static int userdb_connect(
if (r < 0)
return log_debug_errno(r, "Failed to invoke varlink method: %m");
r = set_ensure_allocated(&iterator->links, &link_hash_ops);
if (r < 0)
return log_debug_errno(r, "Failed to allocate set: %m");
r = set_put(iterator->links, vl);
r = set_ensure_consume(&iterator->links, &link_hash_ops, TAKE_PTR(vl));
if (r < 0)
return log_debug_errno(r, "Failed to add varlink connection to set: %m");
TAKE_PTR(vl);
return r;
}

View File

@ -480,25 +480,21 @@ static int add_connection_socket(Context *context, int fd) {
log_warning_errno(r, "Unable to disable idle timer, continuing: %m");
}
r = set_ensure_allocated(&context->connections, NULL);
if (r < 0) {
log_oom();
return 0;
}
c = new0(Connection, 1);
c = new(Connection, 1);
if (!c) {
log_oom();
return 0;
}
c->context = context;
c->server_fd = fd;
c->client_fd = -1;
c->server_to_client_buffer[0] = c->server_to_client_buffer[1] = -1;
c->client_to_server_buffer[0] = c->client_to_server_buffer[1] = -1;
*c = (Connection) {
.context = context,
.server_fd = fd,
.client_fd = -1,
.server_to_client_buffer = {-1, -1},
.client_to_server_buffer = {-1, -1},
};
r = set_put(context->connections, c);
r = set_ensure_put(&context->connections, NULL, c);
if (r < 0) {
free(c);
log_oom();
@ -550,12 +546,6 @@ static int add_listen_socket(Context *context, int fd) {
assert(context);
assert(fd >= 0);
r = set_ensure_allocated(&context->listen, NULL);
if (r < 0) {
log_oom();
return r;
}
r = sd_is_socket(fd, 0, SOCK_STREAM, 1);
if (r < 0)
return log_error_errno(r, "Failed to determine socket type: %m");
@ -571,7 +561,7 @@ static int add_listen_socket(Context *context, int fd) {
if (r < 0)
return log_error_errno(r, "Failed to add event source: %m");
r = set_put(context->listen, source);
r = set_ensure_put(&context->listen, NULL, source);
if (r < 0) {
log_error_errno(r, "Failed to add source to set: %m");
sd_event_source_unref(source);

View File

@ -9207,7 +9207,7 @@ static int run(int argc, char *argv[]) {
int r;
setlocale(LC_ALL, "");
log_parse_environment();
log_parse_environment_cli();
log_open();
/* The journal merging logic potentially needs a lot of fds. */

View File

@ -817,7 +817,6 @@ static int set_dependencies_from_rcnd(const LookupPaths *lp, Hashmap *all_servic
Set *runlevel_services[ELEMENTSOF(rcnd_table)] = {};
_cleanup_strv_free_ char **sysvrcnd_path = NULL;
SysvStub *service;
unsigned i;
Iterator j;
char **p;
int r;
@ -828,9 +827,8 @@ static int set_dependencies_from_rcnd(const LookupPaths *lp, Hashmap *all_servic
if (r < 0)
return r;
STRV_FOREACH(p, sysvrcnd_path) {
for (i = 0; i < ELEMENTSOF(rcnd_table); i ++) {
STRV_FOREACH(p, sysvrcnd_path)
for (unsigned i = 0; i < ELEMENTSOF(rcnd_table); i ++) {
_cleanup_closedir_ DIR *d = NULL;
_cleanup_free_ char *path = NULL;
struct dirent *de;
@ -885,22 +883,15 @@ static int set_dependencies_from_rcnd(const LookupPaths *lp, Hashmap *all_servic
service->sysv_start_priority = MAX(a*10 + b, service->sysv_start_priority);
r = set_ensure_allocated(&runlevel_services[i], NULL);
if (r < 0) {
log_oom();
goto finish;
}
r = set_put(runlevel_services[i], service);
r = set_ensure_put(&runlevel_services[i], NULL, service);
if (r < 0) {
log_oom();
goto finish;
}
}
}
}
for (i = 0; i < ELEMENTSOF(rcnd_table); i ++)
for (unsigned i = 0; i < ELEMENTSOF(rcnd_table); i++)
SET_FOREACH(service, runlevel_services[i], j) {
r = strv_extend(&service->before, rcnd_table[i].target);
if (r < 0) {
@ -917,7 +908,7 @@ static int set_dependencies_from_rcnd(const LookupPaths *lp, Hashmap *all_servic
r = 0;
finish:
for (i = 0; i < ELEMENTSOF(rcnd_table); i++)
for (unsigned i = 0; i < ELEMENTSOF(rcnd_table); i++)
set_free(runlevel_services[i]);
return r;

View File

@ -84,9 +84,7 @@ static int parse_argv(int argc, char *argv[]) {
static int run(int argc, char **argv) {
int r;
log_show_color(true);
log_parse_environment();
log_open();
log_setup_cli();
r = parse_argv(argc, argv);
if (r <= 0)

View File

@ -107,6 +107,49 @@ static void test_set_put_strdupv(void) {
assert_se(set_size(m) == 3);
}
static void test_set_ensure_allocated(void) {
_cleanup_set_free_ Set *m = NULL;
assert_se(set_ensure_allocated(&m, &string_hash_ops) == 1);
assert_se(set_ensure_allocated(&m, &string_hash_ops) == 0);
assert_se(set_ensure_allocated(&m, NULL) == 0);
assert_se(set_size(m) == 0);
}
static void test_set_ensure_put(void) {
_cleanup_set_free_ Set *m = NULL;
assert_se(set_ensure_put(&m, &string_hash_ops, "a") == 1);
assert_se(set_ensure_put(&m, &string_hash_ops, "a") == 0);
assert_se(set_ensure_put(&m, NULL, "a") == 0);
assert_se(set_ensure_put(&m, &string_hash_ops, "b") == 1);
assert_se(set_ensure_put(&m, &string_hash_ops, "b") == 0);
assert_se(set_ensure_put(&m, &string_hash_ops, "a") == 0);
assert_se(set_size(m) == 2);
}
static void test_set_ensure_consume(void) {
_cleanup_set_free_ Set *m = NULL;
char *s, *t;
assert_se(s = strdup("a"));
assert_se(set_ensure_consume(&m, &string_hash_ops_free, s) == 1);
assert_se(t = strdup("a"));
assert_se(set_ensure_consume(&m, &string_hash_ops_free, t) == 0);
assert_se(t = strdup("a"));
assert_se(set_ensure_consume(&m, &string_hash_ops_free, t) == 0);
assert_se(t = strdup("b"));
assert_se(set_ensure_consume(&m, &string_hash_ops_free, t) == 1);
assert_se(t = strdup("b"));
assert_se(set_ensure_consume(&m, &string_hash_ops_free, t) == 0);
assert_se(set_size(m) == 2);
}
int main(int argc, const char *argv[]) {
test_set_steal_first();
test_set_free_with_destructor();
@ -114,6 +157,9 @@ int main(int argc, const char *argv[]) {
test_set_put();
test_set_put_strdup();
test_set_put_strdupv();
test_set_ensure_allocated();
test_set_ensure_put();
test_set_ensure_consume();
return 0;
}

View File

@ -1052,9 +1052,7 @@ static int run(int argc, char *argv[]) {
int r;
setlocale(LC_ALL, "");
log_show_color(true);
log_parse_environment();
log_open();
log_setup_cli();
r = parse_argv(argc, argv);
if (r <= 0)

View File

@ -3196,11 +3196,7 @@ static int link_parent(ItemArray *a) {
if (!j)
j = ordered_hashmap_get(globs, prefix);
if (j) {
r = set_ensure_allocated(&j->children, NULL);
if (r < 0)
return log_oom();
r = set_put(j->children, a);
r = set_ensure_put(&j->children, NULL, a);
if (r < 0)
return log_oom();

View File

@ -169,24 +169,13 @@ static int parse_argv(int argc, char *argv[]) {
subsystem = devtype = NULL;
break;
}
case 't': {
_cleanup_free_ char *tag = NULL;
r = set_ensure_allocated(&arg_tag_filter, &string_hash_ops);
case 't':
/* optarg is stored in argv[], so we don't need to copy it */
r = set_ensure_put(&arg_tag_filter, &string_hash_ops, optarg);
if (r < 0)
return r;
tag = strdup(optarg);
if (!tag)
return -ENOMEM;
r = set_put(arg_tag_filter, tag);
if (r < 0)
return r;
tag = NULL;
break;
}
case 'V':
return print_version();
case 'h':
@ -260,7 +249,7 @@ int monitor_main(int argc, char *argv[], void *userdata) {
finalize:
hashmap_free_free_free(arg_subsystem_filter);
set_free_free(arg_tag_filter);
set_free(arg_tag_filter);
return r;
}

View File

@ -761,9 +761,7 @@ static int run(int argc, char *argv[]) {
int r;
log_show_color(true);
log_parse_environment();
log_open();
log_setup_cli();
r = parse_argv(argc, argv);
if (r <= 0)

View File

@ -0,0 +1,6 @@
[NetDev]
Name=w
Kind=wireguard
[WireGuardPeer]
Endpoint=:0
Endpoint=:8

View File

@ -381,12 +381,18 @@ Id=
Parent=
Handle=
DefaultClass=
RateToQuantum=
[HierarchyTokenBucketClass]
Parent=
ClassId=
Priority=
QuantumBytes=
MTUBytes=
OverheadBytes=
Rate=
CeilRate=
BufferBytes=
CeilBufferBytes=
[BFIFO]
Parent=
Handle=
@ -431,6 +437,13 @@ Handle=
Parent=
ClassId=
Quantum=
[EnhancedTransmissionSelection]
Parent=
Handle=
Bands=
StrictBands=
QuantumBytes=
PriorityMap=
[HeavyHitterFilter]
Parent=
Handle=

View File

@ -0,0 +1,2 @@
[Network]
DNSSECNegativeTrustAnchors=i i

View File

@ -12,13 +12,19 @@ Parent=clsact
Parent=root
Handle=0002
DefaultClass=30
RateToQuantum=20
[HierarchyTokenBucketClass]
Parent=root
ClassId=0002:0030
Priority=1
QuantumBytes=4000
MTUBytes=1700
OverheadBytes=100
Rate=1M
BufferBytes=123456
CeilRate=0.5M
CeilBufferBytes=123457
[NetworkEmulator]
Parent=2:30

View File

@ -0,0 +1,20 @@
[Match]
Name=dummy98
[Network]
IPv6AcceptRA=no
Address=10.1.2.3/16
[EnhancedTransmissionSelection]
Parent=root
Handle=3a
Bands=10
StrictBands=3
QuantumBytes=2 4 6
QuantumBytes=
QuantumBytes=1 2 3
QuantumBytes=4 5
PriorityMap=8 7 6 5
PriorityMap=
PriorityMap=3 4 5
PriorityMap=6 7

View File

@ -194,6 +194,18 @@ def expectedFailureIfHHFIsNotAvailable():
return f
def expectedFailureIfETSIsNotAvailable():
def f(func):
call('ip link add dummy98 type dummy', stderr=subprocess.DEVNULL)
rc = call('tc qdisc add dev dummy98 parent root ets bands 10', stderr=subprocess.DEVNULL)
call('ip link del dummy98', stderr=subprocess.DEVNULL)
if rc == 0:
return func
else:
return unittest.expectedFailure(func)
return f
def setUpModule():
global running_units
@ -1673,6 +1685,7 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
'25-qdisc-cake.network',
'25-qdisc-clsact-and-htb.network',
'25-qdisc-drr.network',
'25-qdisc-ets.network',
'25-qdisc-hhf.network',
'25-qdisc-ingress-netem-compat.network',
'25-qdisc-pie.network',
@ -2407,7 +2420,7 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
self.assertRegex(output, 'qdisc pfifo_fast 3c: parent 2:3c')
output = check_output('tc class show dev dummy98')
output = check_output('tc -d class show dev dummy98')
print(output)
self.assertRegex(output, 'class htb 2:30 root leaf 30:')
self.assertRegex(output, 'class htb 2:31 root leaf 31:')
@ -2422,7 +2435,9 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
self.assertRegex(output, 'class htb 2:3a root leaf 3a:')
self.assertRegex(output, 'class htb 2:3b root leaf 3b:')
self.assertRegex(output, 'class htb 2:3c root leaf 3c:')
self.assertRegex(output, 'prio 1 rate 1Mbit ceil 500Kbit')
self.assertRegex(output, 'prio 1 quantum 4000 rate 1Mbit overhead 100 ceil 500Kbit')
self.assertRegex(output, 'burst 123456')
self.assertRegex(output, 'cburst 123457')
def test_qdisc2(self):
copy_unit_to_networkd_unit_path('25-qdisc-drr.network', '12-dummy.netdev',
@ -2480,6 +2495,19 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
self.assertRegex(output, 'qdisc hhf 3a: root')
self.assertRegex(output, 'limit 1022p')
@expectedFailureIfETSIsNotAvailable()
def test_qdisc_ets(self):
copy_unit_to_networkd_unit_path('25-qdisc-ets.network', '12-dummy.netdev')
start_networkd()
self.wait_online(['dummy98:routable'])
output = check_output('tc qdisc show dev dummy98')
print(output)
self.assertRegex(output, 'qdisc ets 3a: root')
self.assertRegex(output, 'bands 10 strict 3')
self.assertRegex(output, 'quanta 1 2 3 4 5')
self.assertRegex(output, 'priomap 3 4 5 6 7')
class NetworkdStateFileTests(unittest.TestCase, Utilities):
links = [
'dummy98',