mirror of
https://github.com/systemd/systemd
synced 2025-09-30 17:24:46 +02:00
Compare commits
18 Commits
1edebb0b89
...
71311efe23
Author | SHA1 | Date | |
---|---|---|---|
![]() |
71311efe23 | ||
![]() |
83ce3b1944 | ||
![]() |
0886999416 | ||
![]() |
5e8bc852d5 | ||
![]() |
c78735eb79 | ||
![]() |
bb3443d4f6 | ||
![]() |
79dbbb261d | ||
![]() |
986eeaeb55 | ||
![]() |
5185d4ddff | ||
![]() |
bf843b0bd4 | ||
![]() |
bde69bbd89 | ||
![]() |
ed8a48c9b6 | ||
![]() |
7130db9155 | ||
![]() |
6d76b5d7f0 | ||
![]() |
860f154fa3 | ||
![]() |
d41a9e4fc1 | ||
![]() |
3b5ab02119 | ||
![]() |
3aa5765843 |
@ -43,5 +43,3 @@ jobs:
|
|||||||
- fedora-rawhide-aarch64
|
- fedora-rawhide-aarch64
|
||||||
- fedora-rawhide-i386
|
- fedora-rawhide-i386
|
||||||
- fedora-rawhide-x86_64
|
- fedora-rawhide-x86_64
|
||||||
- fedora-eln-aarch64
|
|
||||||
- fedora-eln-x86_64
|
|
||||||
|
7
TODO
7
TODO
@ -20,6 +20,13 @@ Janitorial Clean-ups:
|
|||||||
|
|
||||||
Features:
|
Features:
|
||||||
|
|
||||||
|
* Hook up journald's FSS logic with TPM2: seal the verification disk by
|
||||||
|
time-based policy, so that the verification key can remain on host and ve
|
||||||
|
validated via TPM.
|
||||||
|
|
||||||
|
* sd-event: port to new kernel API epoll_wait2() (new in 5.11), to get more
|
||||||
|
accurate wait timeouts
|
||||||
|
|
||||||
* sd-boot: define a drop-in dir in the ESP that may contain X.509
|
* sd-boot: define a drop-in dir in the ESP that may contain X.509
|
||||||
certificates. If the firmware is detected to be in setup mode, automatically
|
certificates. If the firmware is detected to be in setup mode, automatically
|
||||||
enroll them as PK/KEK/db, turn off setup mode and proceed. Optionally,
|
enroll them as PK/KEK/db, turn off setup mode and proceed. Optionally,
|
||||||
|
@ -662,7 +662,7 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnHPEliteBookFolio1040G2:*
|
|||||||
# HP EliteBook Folio G1
|
# HP EliteBook Folio G1
|
||||||
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHP:pnHPEliteBookFolioG1:*
|
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHP:pnHPEliteBookFolioG1:*
|
||||||
KEYBOARD_KEY_64=calendar
|
KEYBOARD_KEY_64=calendar
|
||||||
KEYBOARD_KEY_81=micmute
|
KEYBOARD_KEY_81=f20
|
||||||
|
|
||||||
# HP ProBook 650
|
# HP ProBook 650
|
||||||
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnHP*ProBook*650*:*
|
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnHP*ProBook*650*:*
|
||||||
|
@ -354,10 +354,16 @@ int unit_file_build_name_map(
|
|||||||
|
|
||||||
/* Check if the symlink goes outside of our search path.
|
/* Check if the symlink goes outside of our search path.
|
||||||
* If yes, it's a linked unit file or mask, and we don't care about the target name.
|
* If yes, it's a linked unit file or mask, and we don't care about the target name.
|
||||||
* Let's just store the link destination directly.
|
* Let's just store the link source directly.
|
||||||
* If not, let's verify that it's a good symlink. */
|
* If not, let's verify that it's a good symlink. */
|
||||||
char *tail = path_startswith_strv(simplified, lp->search_path);
|
char *tail = path_startswith_strv(simplified, lp->search_path);
|
||||||
if (tail) {
|
if (!tail) {
|
||||||
|
log_debug("%s: linked unit file: %s → %s",
|
||||||
|
__func__, filename, simplified);
|
||||||
|
|
||||||
|
dst = filename;
|
||||||
|
} else {
|
||||||
|
|
||||||
bool self_alias;
|
bool self_alias;
|
||||||
|
|
||||||
dst = basename(simplified);
|
dst = basename(simplified);
|
||||||
@ -380,10 +386,6 @@ int unit_file_build_name_map(
|
|||||||
}
|
}
|
||||||
|
|
||||||
log_debug("%s: alias: %s/%s → %s", __func__, *dir, de->d_name, dst);
|
log_debug("%s: alias: %s/%s → %s", __func__, *dir, de->d_name, dst);
|
||||||
} else {
|
|
||||||
dst = simplified;
|
|
||||||
|
|
||||||
log_debug("%s: linked unit file: %s/%s → %s", __func__, *dir, de->d_name, dst);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
@ -5536,10 +5536,11 @@ int unit_load_fragment(Unit *u) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We do the merge dance here because for some unit types, the unit might have aliases which are not
|
/* Call merge_by_names with the name derived from the fragment path as the preferred name.
|
||||||
|
*
|
||||||
|
* We do the merge dance here because for some unit types, the unit might have aliases which are not
|
||||||
* declared in the file system. In particular, this is true (and frequent) for device and swap units.
|
* declared in the file system. In particular, this is true (and frequent) for device and swap units.
|
||||||
*/
|
*/
|
||||||
Unit *merged;
|
|
||||||
const char *id = u->id;
|
const char *id = u->id;
|
||||||
_cleanup_free_ char *free_id = NULL;
|
_cleanup_free_ char *free_id = NULL;
|
||||||
|
|
||||||
@ -5556,7 +5557,7 @@ int unit_load_fragment(Unit *u) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
merged = u;
|
Unit *merged = u;
|
||||||
r = merge_by_names(&merged, names, id);
|
r = merge_by_names(&merged, names, id);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
@ -82,7 +82,7 @@ struct DnsPacket {
|
|||||||
bool canonical_form:1;
|
bool canonical_form:1;
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline uint8_t* DNS_PACKET_DATA(DnsPacket *p) {
|
static inline uint8_t* DNS_PACKET_DATA(const DnsPacket *p) {
|
||||||
if (_unlikely_(!p))
|
if (_unlikely_(!p))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
@ -382,6 +382,13 @@ DnsQuery *dns_query_free(DnsQuery *q) {
|
|||||||
varlink_unref(q->varlink_request);
|
varlink_unref(q->varlink_request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (q->request_packet)
|
||||||
|
hashmap_remove_value(q->stub_listener_extra ?
|
||||||
|
q->stub_listener_extra->queries_by_packet :
|
||||||
|
q->manager->stub_queries_by_packet,
|
||||||
|
q->request_packet,
|
||||||
|
q);
|
||||||
|
|
||||||
dns_packet_unref(q->request_packet);
|
dns_packet_unref(q->request_packet);
|
||||||
dns_answer_unref(q->reply_answer);
|
dns_answer_unref(q->reply_answer);
|
||||||
dns_answer_unref(q->reply_authoritative);
|
dns_answer_unref(q->reply_authoritative);
|
||||||
|
@ -153,16 +153,19 @@ unsigned dns_scope_get_n_dns_servers(DnsScope *s) {
|
|||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
void dns_scope_next_dns_server(DnsScope *s) {
|
void dns_scope_next_dns_server(DnsScope *s, DnsServer *if_current) {
|
||||||
assert(s);
|
assert(s);
|
||||||
|
|
||||||
if (s->protocol != DNS_PROTOCOL_DNS)
|
if (s->protocol != DNS_PROTOCOL_DNS)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
/* Changes to the next DNS server in the list. If 'if_current' is passed will do so only if the
|
||||||
|
* current DNS server still matches it. */
|
||||||
|
|
||||||
if (s->link)
|
if (s->link)
|
||||||
link_next_dns_server(s->link);
|
link_next_dns_server(s->link, if_current);
|
||||||
else
|
else
|
||||||
manager_next_dns_server(s->manager);
|
manager_next_dns_server(s->manager, if_current);
|
||||||
}
|
}
|
||||||
|
|
||||||
void dns_scope_packet_received(DnsScope *s, usec_t rtt) {
|
void dns_scope_packet_received(DnsScope *s, usec_t rtt) {
|
||||||
@ -459,7 +462,7 @@ int dns_scope_socket_tcp(DnsScope *s, int family, const union in_addr_union *add
|
|||||||
return dns_scope_socket(s, SOCK_STREAM, family, address, server, port, ret_socket_address);
|
return dns_scope_socket(s, SOCK_STREAM, family, address, server, port, ret_socket_address);
|
||||||
}
|
}
|
||||||
|
|
||||||
static DnsScopeMatch accept_link_local_reverse_lookups(const char *domain) {
|
static DnsScopeMatch match_link_local_reverse_lookups(const char *domain) {
|
||||||
assert(domain);
|
assert(domain);
|
||||||
|
|
||||||
if (dns_name_endswith(domain, "254.169.in-addr.arpa") > 0)
|
if (dns_name_endswith(domain, "254.169.in-addr.arpa") > 0)
|
||||||
@ -568,29 +571,25 @@ DnsScopeMatch dns_scope_good_domain(
|
|||||||
return DNS_SCOPE_YES_BASE + n_best;
|
return DNS_SCOPE_YES_BASE + n_best;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* See if this scope is suitable as default route. */
|
/* Exclude link-local IP ranges */
|
||||||
|
if (match_link_local_reverse_lookups(domain) >= DNS_SCOPE_YES_BASE ||
|
||||||
|
/* If networks use .local in their private setups, they are supposed to also add .local
|
||||||
|
* to their search domains, which we already checked above. Otherwise, we consider .local
|
||||||
|
* specific to mDNS and won't send such queries ordinary DNS servers. */
|
||||||
|
dns_name_endswith(domain, "local") > 0)
|
||||||
|
return DNS_SCOPE_NO;
|
||||||
|
|
||||||
|
/* If there was no match at all, then see if this scope is suitable as default route. */
|
||||||
if (!dns_scope_is_default_route(s))
|
if (!dns_scope_is_default_route(s))
|
||||||
return DNS_SCOPE_NO;
|
return DNS_SCOPE_NO;
|
||||||
|
|
||||||
/* Exclude link-local IP ranges */
|
return DNS_SCOPE_MAYBE;
|
||||||
if (dns_name_endswith(domain, "254.169.in-addr.arpa") == 0 &&
|
|
||||||
dns_name_endswith(domain, "8.e.f.ip6.arpa") == 0 &&
|
|
||||||
dns_name_endswith(domain, "9.e.f.ip6.arpa") == 0 &&
|
|
||||||
dns_name_endswith(domain, "a.e.f.ip6.arpa") == 0 &&
|
|
||||||
dns_name_endswith(domain, "b.e.f.ip6.arpa") == 0 &&
|
|
||||||
/* If networks use .local in their private setups, they are supposed to also add .local to their search
|
|
||||||
* domains, which we already checked above. Otherwise, we consider .local specific to mDNS and won't
|
|
||||||
* send such queries ordinary DNS servers. */
|
|
||||||
dns_name_endswith(domain, "local") == 0)
|
|
||||||
return DNS_SCOPE_MAYBE;
|
|
||||||
|
|
||||||
return DNS_SCOPE_NO;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case DNS_PROTOCOL_MDNS: {
|
case DNS_PROTOCOL_MDNS: {
|
||||||
DnsScopeMatch m;
|
DnsScopeMatch m;
|
||||||
|
|
||||||
m = accept_link_local_reverse_lookups(domain);
|
m = match_link_local_reverse_lookups(domain);
|
||||||
if (m >= 0)
|
if (m >= 0)
|
||||||
return m;
|
return m;
|
||||||
|
|
||||||
@ -609,7 +608,7 @@ DnsScopeMatch dns_scope_good_domain(
|
|||||||
case DNS_PROTOCOL_LLMNR: {
|
case DNS_PROTOCOL_LLMNR: {
|
||||||
DnsScopeMatch m;
|
DnsScopeMatch m;
|
||||||
|
|
||||||
m = accept_link_local_reverse_lookups(domain);
|
m = match_link_local_reverse_lookups(domain);
|
||||||
if (m >= 0)
|
if (m >= 0)
|
||||||
return m;
|
return m;
|
||||||
|
|
||||||
|
@ -80,7 +80,7 @@ bool dns_scope_good_key(DnsScope *s, const DnsResourceKey *key);
|
|||||||
|
|
||||||
DnsServer *dns_scope_get_dns_server(DnsScope *s);
|
DnsServer *dns_scope_get_dns_server(DnsScope *s);
|
||||||
unsigned dns_scope_get_n_dns_servers(DnsScope *s);
|
unsigned dns_scope_get_n_dns_servers(DnsScope *s);
|
||||||
void dns_scope_next_dns_server(DnsScope *s);
|
void dns_scope_next_dns_server(DnsScope *s, DnsServer *if_current);
|
||||||
|
|
||||||
int dns_scope_llmnr_membership(DnsScope *s, bool b);
|
int dns_scope_llmnr_membership(DnsScope *s, bool b);
|
||||||
int dns_scope_mdns_membership(DnsScope *s, bool b);
|
int dns_scope_mdns_membership(DnsScope *s, bool b);
|
||||||
|
@ -771,23 +771,25 @@ DnsServer *manager_get_dns_server(Manager *m) {
|
|||||||
return m->current_dns_server;
|
return m->current_dns_server;
|
||||||
}
|
}
|
||||||
|
|
||||||
void manager_next_dns_server(Manager *m) {
|
void manager_next_dns_server(Manager *m, DnsServer *if_current) {
|
||||||
assert(m);
|
assert(m);
|
||||||
|
|
||||||
/* If there's currently no DNS server set, then the next
|
/* If the DNS server is already a different one than the one specified in 'if_current' don't do anything */
|
||||||
* manager_get_dns_server() will find one */
|
if (if_current && m->current_dns_server != if_current)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* If there's currently no DNS server set, then the next manager_get_dns_server() will find one */
|
||||||
if (!m->current_dns_server)
|
if (!m->current_dns_server)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Change to the next one, but make sure to follow the linked
|
/* Change to the next one, but make sure to follow the linked list only if the server is still
|
||||||
* list only if the server is still linked. */
|
* linked. */
|
||||||
if (m->current_dns_server->linked && m->current_dns_server->servers_next) {
|
if (m->current_dns_server->linked && m->current_dns_server->servers_next) {
|
||||||
manager_set_dns_server(m, m->current_dns_server->servers_next);
|
manager_set_dns_server(m, m->current_dns_server->servers_next);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If there was no next one, then start from the beginning of
|
/* If there was no next one, then start from the beginning of the list */
|
||||||
* the list */
|
|
||||||
if (m->current_dns_server->type == DNS_SERVER_FALLBACK)
|
if (m->current_dns_server->type == DNS_SERVER_FALLBACK)
|
||||||
manager_set_dns_server(m, m->fallback_dns_servers);
|
manager_set_dns_server(m, m->fallback_dns_servers);
|
||||||
else
|
else
|
||||||
|
@ -143,7 +143,7 @@ DnsServer *manager_get_first_dns_server(Manager *m, DnsServerType t);
|
|||||||
|
|
||||||
DnsServer *manager_set_dns_server(Manager *m, DnsServer *s);
|
DnsServer *manager_set_dns_server(Manager *m, DnsServer *s);
|
||||||
DnsServer *manager_get_dns_server(Manager *m);
|
DnsServer *manager_get_dns_server(Manager *m);
|
||||||
void manager_next_dns_server(Manager *m);
|
void manager_next_dns_server(Manager *m, DnsServer *if_current);
|
||||||
|
|
||||||
DnssecMode dns_server_get_dnssec_mode(DnsServer *s);
|
DnssecMode dns_server_get_dnssec_mode(DnsServer *s);
|
||||||
DnsOverTlsMode dns_server_get_dns_over_tls_mode(DnsServer *s);
|
DnsOverTlsMode dns_server_get_dns_over_tls_mode(DnsServer *s);
|
||||||
|
@ -82,6 +82,8 @@ DnsStubListenerExtra *dns_stub_listener_extra_free(DnsStubListenerExtra *p) {
|
|||||||
p->udp_event_source = sd_event_source_unref(p->udp_event_source);
|
p->udp_event_source = sd_event_source_unref(p->udp_event_source);
|
||||||
p->tcp_event_source = sd_event_source_unref(p->tcp_event_source);
|
p->tcp_event_source = sd_event_source_unref(p->tcp_event_source);
|
||||||
|
|
||||||
|
hashmap_free(p->queries_by_packet);
|
||||||
|
|
||||||
return mfree(p);
|
return mfree(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,6 +96,47 @@ uint16_t dns_stub_listener_extra_port(DnsStubListenerExtra *p) {
|
|||||||
return 53;
|
return 53;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void stub_packet_hash_func(const DnsPacket *p, struct siphash *state) {
|
||||||
|
assert(p);
|
||||||
|
|
||||||
|
siphash24_compress(&p->protocol, sizeof(p->protocol), state);
|
||||||
|
siphash24_compress(&p->family, sizeof(p->family), state);
|
||||||
|
siphash24_compress(&p->sender, sizeof(p->sender), state);
|
||||||
|
siphash24_compress(&p->ipproto, sizeof(p->ipproto), state);
|
||||||
|
siphash24_compress(&p->sender_port, sizeof(p->sender_port), state);
|
||||||
|
siphash24_compress(DNS_PACKET_HEADER(p), sizeof(DnsPacketHeader), state);
|
||||||
|
|
||||||
|
/* We don't bother hashing the full packet here, just the header */
|
||||||
|
}
|
||||||
|
|
||||||
|
static int stub_packet_compare_func(const DnsPacket *x, const DnsPacket *y) {
|
||||||
|
int r;
|
||||||
|
|
||||||
|
r = CMP(x->protocol, y->protocol);
|
||||||
|
if (r != 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
r = CMP(x->family, y->family);
|
||||||
|
if (r != 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
r = memcmp(&x->sender, &y->sender, sizeof(x->sender));
|
||||||
|
if (r != 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
r = CMP(x->ipproto, y->ipproto);
|
||||||
|
if (r != 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
r = CMP(x->sender_port, y->sender_port);
|
||||||
|
if (r != 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
return memcmp(DNS_PACKET_HEADER(x), DNS_PACKET_HEADER(y), sizeof(DnsPacketHeader));
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFINE_HASH_OPS(stub_packet_hash_ops, DnsPacket, stub_packet_hash_func, stub_packet_compare_func);
|
||||||
|
|
||||||
static int dns_stub_collect_answer_by_question(
|
static int dns_stub_collect_answer_by_question(
|
||||||
DnsAnswer **reply,
|
DnsAnswer **reply,
|
||||||
DnsAnswer *answer,
|
DnsAnswer *answer,
|
||||||
@ -685,6 +728,8 @@ static int dns_stub_stream_complete(DnsStream *s, int error) {
|
|||||||
|
|
||||||
static void dns_stub_process_query(Manager *m, DnsStubListenerExtra *l, DnsStream *s, DnsPacket *p) {
|
static void dns_stub_process_query(Manager *m, DnsStubListenerExtra *l, DnsStream *s, DnsPacket *p) {
|
||||||
_cleanup_(dns_query_freep) DnsQuery *q = NULL;
|
_cleanup_(dns_query_freep) DnsQuery *q = NULL;
|
||||||
|
Hashmap **queries_by_packet;
|
||||||
|
DnsQuery *existing;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(m);
|
assert(m);
|
||||||
@ -703,6 +748,13 @@ static void dns_stub_process_query(Manager *m, DnsStubListenerExtra *l, DnsStrea
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
queries_by_packet = l ? &l->queries_by_packet : &m->stub_queries_by_packet;
|
||||||
|
existing = hashmap_get(*queries_by_packet, p);
|
||||||
|
if (existing && dns_packet_equal(existing->request_packet, p)) {
|
||||||
|
log_debug("Got repeat packet from client, ignoring.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
r = dns_packet_extract(p);
|
r = dns_packet_extract(p);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
log_debug_errno(r, "Failed to extract resources from incoming packet, ignoring packet: %m");
|
log_debug_errno(r, "Failed to extract resources from incoming packet, ignoring packet: %m");
|
||||||
@ -735,6 +787,12 @@ static void dns_stub_process_query(Manager *m, DnsStubListenerExtra *l, DnsStrea
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
r = hashmap_ensure_allocated(queries_by_packet, &stub_packet_hash_ops);
|
||||||
|
if (r < 0) {
|
||||||
|
log_oom();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (DNS_PACKET_DO(p) && DNS_PACKET_CD(p)) {
|
if (DNS_PACKET_DO(p) && DNS_PACKET_CD(p)) {
|
||||||
log_debug("Got request with DNSSEC checking disabled, enabling bypass logic.");
|
log_debug("Got request with DNSSEC checking disabled, enabling bypass logic.");
|
||||||
|
|
||||||
@ -774,6 +832,11 @@ static void dns_stub_process_query(Manager *m, DnsStubListenerExtra *l, DnsStrea
|
|||||||
assert(r > 0);
|
assert(r > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Add the query to the hash table we use to determine repeat packets now. We don't care about
|
||||||
|
* failures here, since in the worst case we'll not recognize duplicate incoming requests, which
|
||||||
|
* isn't particularly bad. */
|
||||||
|
(void) hashmap_put(*queries_by_packet, q->request_packet, q);
|
||||||
|
|
||||||
r = dns_query_go(q);
|
r = dns_query_go(q);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
log_error_errno(r, "Failed to start query: %m");
|
log_error_errno(r, "Failed to start query: %m");
|
||||||
|
@ -27,6 +27,8 @@ struct DnsStubListenerExtra {
|
|||||||
|
|
||||||
sd_event_source *udp_event_source;
|
sd_event_source *udp_event_source;
|
||||||
sd_event_source *tcp_event_source;
|
sd_event_source *tcp_event_source;
|
||||||
|
|
||||||
|
Hashmap *queries_by_packet;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern const struct hash_ops dns_stub_listener_extra_hash_ops;
|
extern const struct hash_ops dns_stub_listener_extra_hash_ops;
|
||||||
|
@ -484,7 +484,7 @@ static void dns_transaction_retry(DnsTransaction *t, bool next_server) {
|
|||||||
|
|
||||||
/* Before we try again, switch to a new server. */
|
/* Before we try again, switch to a new server. */
|
||||||
if (next_server)
|
if (next_server)
|
||||||
dns_scope_next_dns_server(t->scope);
|
dns_scope_next_dns_server(t->scope, t->server);
|
||||||
|
|
||||||
r = dns_transaction_go(t);
|
r = dns_transaction_go(t);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
@ -1859,7 +1859,7 @@ int dns_transaction_go(DnsTransaction *t) {
|
|||||||
/* One of our own stub listeners */
|
/* One of our own stub listeners */
|
||||||
log_debug_errno(r, "Detected that specified DNS server is our own extra listener, switching DNS servers.");
|
log_debug_errno(r, "Detected that specified DNS server is our own extra listener, switching DNS servers.");
|
||||||
|
|
||||||
dns_scope_next_dns_server(t->scope);
|
dns_scope_next_dns_server(t->scope, t->server);
|
||||||
|
|
||||||
if (dns_scope_get_dns_server(t->scope) == t->server) {
|
if (dns_scope_get_dns_server(t->scope) == t->server) {
|
||||||
log_debug_errno(r, "Still pointing to extra listener after switching DNS servers, refusing operation.");
|
log_debug_errno(r, "Still pointing to extra listener after switching DNS servers, refusing operation.");
|
||||||
@ -1890,7 +1890,7 @@ int dns_transaction_go(DnsTransaction *t) {
|
|||||||
return r;
|
return r;
|
||||||
|
|
||||||
/* Couldn't send? Try immediately again, with a new server */
|
/* Couldn't send? Try immediately again, with a new server */
|
||||||
dns_scope_next_dns_server(t->scope);
|
dns_scope_next_dns_server(t->scope, t->server);
|
||||||
|
|
||||||
return dns_transaction_go(t);
|
return dns_transaction_go(t);
|
||||||
}
|
}
|
||||||
|
@ -731,19 +731,27 @@ DnsServer *link_get_dns_server(Link *l) {
|
|||||||
return l->current_dns_server;
|
return l->current_dns_server;
|
||||||
}
|
}
|
||||||
|
|
||||||
void link_next_dns_server(Link *l) {
|
void link_next_dns_server(Link *l, DnsServer *if_current) {
|
||||||
assert(l);
|
assert(l);
|
||||||
|
|
||||||
|
/* If the current server of the transaction is specified, and we already are at a different one,
|
||||||
|
* don't do anything */
|
||||||
|
if (if_current && l->current_dns_server != if_current)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* If currently have no DNS server, then don't do anything, we'll pick it lazily the next time a DNS
|
||||||
|
* server is needed. */
|
||||||
if (!l->current_dns_server)
|
if (!l->current_dns_server)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Change to the next one, but make sure to follow the linked
|
/* Change to the next one, but make sure to follow the linked list only if this server is actually
|
||||||
* list only if this server is actually still linked. */
|
* still linked. */
|
||||||
if (l->current_dns_server->linked && l->current_dns_server->servers_next) {
|
if (l->current_dns_server->linked && l->current_dns_server->servers_next) {
|
||||||
link_set_dns_server(l, l->current_dns_server->servers_next);
|
link_set_dns_server(l, l->current_dns_server->servers_next);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Pick the first one again, after we reached the end */
|
||||||
link_set_dns_server(l, l->dns_servers);
|
link_set_dns_server(l, l->dns_servers);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,7 +91,7 @@ void link_allocate_scopes(Link *l);
|
|||||||
|
|
||||||
DnsServer* link_set_dns_server(Link *l, DnsServer *s);
|
DnsServer* link_set_dns_server(Link *l, DnsServer *s);
|
||||||
DnsServer* link_get_dns_server(Link *l);
|
DnsServer* link_get_dns_server(Link *l);
|
||||||
void link_next_dns_server(Link *l);
|
void link_next_dns_server(Link *l, DnsServer *if_current);
|
||||||
|
|
||||||
DnssecMode link_get_dnssec_mode(Link *l);
|
DnssecMode link_get_dnssec_mode(Link *l);
|
||||||
bool link_dnssec_supported(Link *l);
|
bool link_dnssec_supported(Link *l);
|
||||||
|
@ -739,6 +739,8 @@ Manager *manager_free(Manager *m) {
|
|||||||
while (m->dns_queries)
|
while (m->dns_queries)
|
||||||
dns_query_free(m->dns_queries);
|
dns_query_free(m->dns_queries);
|
||||||
|
|
||||||
|
m->stub_queries_by_packet = hashmap_free(m->stub_queries_by_packet);
|
||||||
|
|
||||||
dns_scope_free(m->unicast_scope);
|
dns_scope_free(m->unicast_scope);
|
||||||
|
|
||||||
/* At this point only orphaned streams should remain. All others should have been freed already by their
|
/* At this point only orphaned streams should remain. All others should have been freed already by their
|
||||||
|
@ -59,6 +59,7 @@ struct Manager {
|
|||||||
Hashmap *dns_transactions;
|
Hashmap *dns_transactions;
|
||||||
LIST_HEAD(DnsQuery, dns_queries);
|
LIST_HEAD(DnsQuery, dns_queries);
|
||||||
unsigned n_dns_queries;
|
unsigned n_dns_queries;
|
||||||
|
Hashmap *stub_queries_by_packet;
|
||||||
|
|
||||||
LIST_HEAD(DnsStream, dns_streams);
|
LIST_HEAD(DnsStream, dns_streams);
|
||||||
unsigned n_dns_streams[_DNS_STREAM_TYPE_MAX];
|
unsigned n_dns_streams[_DNS_STREAM_TYPE_MAX];
|
||||||
@ -97,13 +98,12 @@ struct Manager {
|
|||||||
/* mDNS */
|
/* mDNS */
|
||||||
int mdns_ipv4_fd;
|
int mdns_ipv4_fd;
|
||||||
int mdns_ipv6_fd;
|
int mdns_ipv6_fd;
|
||||||
|
sd_event_source *mdns_ipv4_event_source;
|
||||||
|
sd_event_source *mdns_ipv6_event_source;
|
||||||
|
|
||||||
/* DNS-SD */
|
/* DNS-SD */
|
||||||
Hashmap *dnssd_services;
|
Hashmap *dnssd_services;
|
||||||
|
|
||||||
sd_event_source *mdns_ipv4_event_source;
|
|
||||||
sd_event_source *mdns_ipv6_event_source;
|
|
||||||
|
|
||||||
/* dbus */
|
/* dbus */
|
||||||
sd_bus *bus;
|
sd_bus *bus;
|
||||||
|
|
||||||
|
@ -1398,7 +1398,7 @@ int show_journal(
|
|||||||
if (line == 0 && noaccess)
|
if (line == 0 && noaccess)
|
||||||
fprintf(f, "Warning: some journal files were not opened due to insufficient permissions.");
|
fprintf(f, "Warning: some journal files were not opened due to insufficient permissions.");
|
||||||
else if (!noaccess)
|
else if (!noaccess)
|
||||||
fprintf(f, "Warning: journal has been rotated since unit was started, output may be incomplete.\n");
|
fprintf(f, "Notice: journal has been rotated since unit was started, output may be incomplete.\n");
|
||||||
else
|
else
|
||||||
fprintf(f, "Warning: journal has been rotated since unit was started and some journal "
|
fprintf(f, "Warning: journal has been rotated since unit was started and some journal "
|
||||||
"files were not opened due to insufficient permissions, output may be incomplete.\n");
|
"files were not opened due to insufficient permissions, output may be incomplete.\n");
|
||||||
|
@ -912,57 +912,53 @@ int systemctl_dispatch_parse_argv(int argc, char *argv[]) {
|
|||||||
assert(argc >= 0);
|
assert(argc >= 0);
|
||||||
assert(argv);
|
assert(argv);
|
||||||
|
|
||||||
if (program_invocation_short_name) {
|
if (strstr_ptr(argv[0], "halt")) {
|
||||||
|
arg_action = ACTION_HALT;
|
||||||
|
return halt_parse_argv(argc, argv);
|
||||||
|
|
||||||
if (strstr(program_invocation_short_name, "halt")) {
|
} else if (strstr_ptr(argv[0], "poweroff")) {
|
||||||
arg_action = ACTION_HALT;
|
arg_action = ACTION_POWEROFF;
|
||||||
return halt_parse_argv(argc, argv);
|
return halt_parse_argv(argc, argv);
|
||||||
|
|
||||||
} else if (strstr(program_invocation_short_name, "poweroff")) {
|
} else if (strstr_ptr(argv[0], "reboot")) {
|
||||||
arg_action = ACTION_POWEROFF;
|
if (kexec_loaded())
|
||||||
return halt_parse_argv(argc, argv);
|
arg_action = ACTION_KEXEC;
|
||||||
|
else
|
||||||
|
arg_action = ACTION_REBOOT;
|
||||||
|
return halt_parse_argv(argc, argv);
|
||||||
|
|
||||||
} else if (strstr(program_invocation_short_name, "reboot")) {
|
} else if (strstr_ptr(argv[0], "shutdown")) {
|
||||||
if (kexec_loaded())
|
arg_action = ACTION_POWEROFF;
|
||||||
arg_action = ACTION_KEXEC;
|
return shutdown_parse_argv(argc, argv);
|
||||||
else
|
|
||||||
arg_action = ACTION_REBOOT;
|
|
||||||
return halt_parse_argv(argc, argv);
|
|
||||||
|
|
||||||
} else if (strstr(program_invocation_short_name, "shutdown")) {
|
} else if (strstr_ptr(argv[0], "init")) {
|
||||||
arg_action = ACTION_POWEROFF;
|
|
||||||
return shutdown_parse_argv(argc, argv);
|
|
||||||
|
|
||||||
} else if (strstr(program_invocation_short_name, "init")) {
|
/* Matches invocations as "init" as well as "telinit", which are synonymous when run
|
||||||
|
* as PID != 1 on SysV.
|
||||||
|
*
|
||||||
|
* On SysV "telinit" was the official command to communicate with PID 1, but "init" would
|
||||||
|
* redirect itself to "telinit" if called with PID != 1. We follow the same logic here still,
|
||||||
|
* though we add one level of indirection, as we implement "telinit" in "systemctl". Hence,
|
||||||
|
* for us if you invoke "init" you get "systemd", but it will execve() "systemctl"
|
||||||
|
* immediately with argv[] unmodified if PID is != 1. If you invoke "telinit" you directly
|
||||||
|
* get "systemctl". In both cases we shall do the same thing, which is why we do
|
||||||
|
* strstr_ptr(argv[0], "init") here, as a quick way to match both.
|
||||||
|
*
|
||||||
|
* Also see redirect_telinit() in src/core/main.c. */
|
||||||
|
|
||||||
/* Matches invocations as "init" as well as "telinit", which are synonymous when run
|
if (sd_booted() > 0) {
|
||||||
* as PID != 1 on SysV.
|
arg_action = _ACTION_INVALID;
|
||||||
*
|
return telinit_parse_argv(argc, argv);
|
||||||
* On SysV "telinit" was the official command to communicate with PID 1, but "init" would
|
} else {
|
||||||
* redirect itself to "telinit" if called with PID != 1. We follow the same logic here still,
|
/* Hmm, so some other init system is running, we need to forward this request to it.
|
||||||
* though we add one level of indirection, as we implement "telinit" in "systemctl". Hence, for
|
*/
|
||||||
* us if you invoke "init" you get "systemd", but it will execve() "systemctl" immediately with
|
arg_action = ACTION_TELINIT;
|
||||||
* argv[] unmodified if PID is != 1. If you invoke "telinit" you directly get "systemctl". In
|
return 1;
|
||||||
* both cases we shall do the same thing, which is why we do strstr(p_i_s_n, "init") here, as a
|
|
||||||
* quick way to match both.
|
|
||||||
*
|
|
||||||
* Also see redirect_telinit() in src/core/main.c. */
|
|
||||||
|
|
||||||
if (sd_booted() > 0) {
|
|
||||||
arg_action = _ACTION_INVALID;
|
|
||||||
return telinit_parse_argv(argc, argv);
|
|
||||||
} else {
|
|
||||||
/* Hmm, so some other init system is running, we need to forward this request
|
|
||||||
* to it. */
|
|
||||||
|
|
||||||
arg_action = ACTION_TELINIT;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if (strstr(program_invocation_short_name, "runlevel")) {
|
|
||||||
arg_action = ACTION_RUNLEVEL;
|
|
||||||
return runlevel_parse_argv(argc, argv);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} else if (strstr_ptr(argv[0], "runlevel")) {
|
||||||
|
arg_action = ACTION_RUNLEVEL;
|
||||||
|
return runlevel_parse_argv(argc, argv);
|
||||||
}
|
}
|
||||||
|
|
||||||
arg_action = ACTION_SYSTEMCTL;
|
arg_action = ACTION_SYSTEMCTL;
|
||||||
|
Binary file not shown.
@ -124,6 +124,32 @@ EOF
|
|||||||
clear_services test15-a test15-b test15-c
|
clear_services test15-a test15-b test15-c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test_linked_units () {
|
||||||
|
echo "Testing linked units..."
|
||||||
|
echo "*** test linked unit (same basename)"
|
||||||
|
|
||||||
|
create_service test15-a
|
||||||
|
mv /etc/systemd/system/test15-a.service /
|
||||||
|
ln -s /test15-a.service /etc/systemd/system/
|
||||||
|
ln -s test15-a.service /etc/systemd/system/test15-b.service
|
||||||
|
|
||||||
|
check_ok test15-a Names test15-a.service
|
||||||
|
check_ok test15-a Names test15-b.service
|
||||||
|
|
||||||
|
echo "*** test linked unit (cross basename)"
|
||||||
|
|
||||||
|
mv /test15-a.service /test15-a@.scope
|
||||||
|
ln -fs /test15-a@.scope /etc/systemd/system/test15-a.service
|
||||||
|
systemctl daemon-reload
|
||||||
|
|
||||||
|
check_ok test15-a Names test15-a.service
|
||||||
|
check_ok test15-a Names test15-b.service
|
||||||
|
check_ko test15-a Names test15-b@
|
||||||
|
|
||||||
|
rm /test15-a@.scope
|
||||||
|
clear_services test15-a test15-b
|
||||||
|
}
|
||||||
|
|
||||||
test_hierarchical_dropins () {
|
test_hierarchical_dropins () {
|
||||||
echo "Testing hierarchical dropins..."
|
echo "Testing hierarchical dropins..."
|
||||||
echo "*** test service.d/ top level drop-in"
|
echo "*** test service.d/ top level drop-in"
|
||||||
@ -465,6 +491,7 @@ test_invalid_dropins () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
test_basic_dropins
|
test_basic_dropins
|
||||||
|
test_linked_units
|
||||||
test_hierarchical_dropins
|
test_hierarchical_dropins
|
||||||
test_template_dropins
|
test_template_dropins
|
||||||
test_alias_dropins
|
test_alias_dropins
|
||||||
|
Loading…
x
Reference in New Issue
Block a user