summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/ENVIRONMENT.md6
-rw-r--r--src/basic/locale-util.c10
-rw-r--r--src/dissect/dissect.c6
-rw-r--r--src/resolve/resolvectl.c37
-rw-r--r--src/resolve/resolved-link-bus.c6
-rw-r--r--src/resolve/resolved-link.c50
-rw-r--r--src/resolve/resolved-link.h3
-rw-r--r--src/shared/dissect-image.c26
-rw-r--r--src/shared/dissect-image.h1
-rw-r--r--src/shared/format-table.c4
-rw-r--r--src/shared/json.c11
-rw-r--r--src/shared/json.h4
-rw-r--r--src/shared/resolve-util.h3
-rwxr-xr-xtest/units/testsuite-58.sh22
-rwxr-xr-xtest/units/testsuite-75.sh77
15 files changed, 223 insertions, 43 deletions
diff --git a/docs/ENVIRONMENT.md b/docs/ENVIRONMENT.md
index ab3add6031..61ad075085 100644
--- a/docs/ENVIRONMENT.md
+++ b/docs/ENVIRONMENT.md
@@ -85,6 +85,12 @@ All tools:
* `$SYSTEMD_MEMPOOL=0` — if set, the internal memory caching logic employed by
hash tables is turned off, and libc `malloc()` is used for all allocations.
+* `$SYSTEMD_UTF8=` — takes a boolean value, and overrides whether to generate
+ non-ASCII special glyphs at various places (i.e. "→" instead of
+ "->"). Usually this is deterined automatically, based on $LC_CTYPE, but in
+ scenarios where locale definitions are not installed it might make sense to
+ override this check explicitly.
+
* `$SYSTEMD_EMOJI=0` — if set, tools such as `systemd-analyze security` will
not output graphical smiley emojis, but ASCII alternatives instead. Note that
this only controls use of Unicode emoji glyphs, and has no effect on other
diff --git a/src/basic/locale-util.c b/src/basic/locale-util.c
index 2f486a4d92..40c6e46ab8 100644
--- a/src/basic/locale-util.c
+++ b/src/basic/locale-util.c
@@ -286,8 +286,9 @@ void init_gettext(void) {
}
bool is_locale_utf8(void) {
- const char *set;
static int cached_answer = -1;
+ const char *set;
+ int r;
/* Note that we default to 'true' here, since today UTF8 is
* pretty much supported everywhere. */
@@ -295,6 +296,13 @@ bool is_locale_utf8(void) {
if (cached_answer >= 0)
goto out;
+ r = getenv_bool_secure("SYSTEMD_UTF8");
+ if (r >= 0) {
+ cached_answer = r;
+ goto out;
+ } else if (r != -ENXIO)
+ log_debug_errno(r, "Failed to parse $SYSTEMD_UTF8, ignoring: %m");
+
if (!setlocale(LC_ALL, "")) {
cached_answer = true;
goto out;
diff --git a/src/dissect/dissect.c b/src/dissect/dissect.c
index 81764690e9..1ee4119d4f 100644
--- a/src/dissect/dissect.c
+++ b/src/dissect/dissect.c
@@ -568,7 +568,7 @@ static int action_dissect(DissectedImage *m, LoopDevice *d) {
pager_open(arg_pager_flags);
if (arg_json_format_flags & JSON_FORMAT_OFF)
- printf(" Name: %s\n", bn);
+ printf(" Name: %s%s%s\n", ansi_highlight(), bn, ansi_normal());
if (ioctl(d->fd, BLKGETSIZE64, &size) < 0)
log_debug_errno(errno, "Failed to query size of loopback device: %m");
@@ -594,6 +594,9 @@ static int action_dissect(DissectedImage *m, LoopDevice *d) {
else if (arg_json_format_flags & JSON_FORMAT_OFF) {
_cleanup_strv_free_ char **sysext_scopes = NULL;
+ if (!sd_id128_is_null(m->image_uuid))
+ printf("Image UUID: %s\n", SD_ID128_TO_UUID_STRING(m->image_uuid));
+
if (m->hostname)
printf(" Hostname: %s\n", m->hostname);
@@ -673,6 +676,7 @@ static int action_dissect(DissectedImage *m, LoopDevice *d) {
r = json_build(&v, JSON_BUILD_OBJECT(
JSON_BUILD_PAIR("name", JSON_BUILD_STRING(bn)),
+ JSON_BUILD_PAIR_CONDITION(!sd_id128_is_null(m->image_uuid), "imageUuid", JSON_BUILD_UUID(m->image_uuid)),
JSON_BUILD_PAIR("size", JSON_BUILD_INTEGER(size)),
JSON_BUILD_PAIR_CONDITION(m->hostname, "hostname", JSON_BUILD_STRING(m->hostname)),
JSON_BUILD_PAIR_CONDITION(!sd_id128_is_null(m->machine_id), "machineId", JSON_BUILD_ID128(m->machine_id)),
diff --git a/src/resolve/resolvectl.c b/src/resolve/resolvectl.c
index bba9492d07..ff645fc0d7 100644
--- a/src/resolve/resolvectl.c
+++ b/src/resolve/resolvectl.c
@@ -33,6 +33,7 @@
#include "pretty-print.h"
#include "process-util.h"
#include "resolvconf-compat.h"
+#include "resolve-util.h"
#include "resolvectl.h"
#include "resolved-def.h"
#include "resolved-dns-packet.h"
@@ -2273,6 +2274,8 @@ static int verb_default_route(int argc, char **argv, void *userdata) {
static int verb_llmnr(int argc, char **argv, void *userdata) {
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
+ _cleanup_free_ char *global_llmnr_support_str = NULL;
+ ResolveSupport global_llmnr_support, llmnr_support;
sd_bus *bus = ASSERT_PTR(userdata);
int r;
@@ -2288,6 +2291,22 @@ static int verb_llmnr(int argc, char **argv, void *userdata) {
if (argc < 3)
return status_ifindex(bus, arg_ifindex, NULL, STATUS_LLMNR, NULL);
+ llmnr_support = resolve_support_from_string(argv[2]);
+ if (llmnr_support < 0)
+ return log_error_errno(llmnr_support, "Invalid LLMNR setting: %s", argv[2]);
+
+ r = bus_get_property_string(bus, bus_resolve_mgr, "LLMNR", &error, &global_llmnr_support_str);
+ if (r < 0)
+ return log_error_errno(r, "Failed to get the global LLMNR support state: %s", bus_error_message(&error, r));
+
+ global_llmnr_support = resolve_support_from_string(global_llmnr_support_str);
+ if (global_llmnr_support < 0)
+ return log_error_errno(global_llmnr_support, "Received invalid global LLMNR setting: %s", global_llmnr_support_str);
+
+ if (global_llmnr_support < llmnr_support)
+ log_warning("Setting LLMNR support level \"%s\" for \"%s\", but the global support level is \"%s\".",
+ argv[2], arg_ifname, global_llmnr_support_str);
+
r = bus_call_method(bus, bus_resolve_mgr, "SetLinkLLMNR", &error, NULL, "is", arg_ifindex, argv[2]);
if (r < 0 && sd_bus_error_has_name(&error, BUS_ERROR_LINK_BUSY)) {
sd_bus_error_free(&error);
@@ -2307,6 +2326,8 @@ static int verb_llmnr(int argc, char **argv, void *userdata) {
static int verb_mdns(int argc, char **argv, void *userdata) {
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
+ _cleanup_free_ char *global_mdns_support_str = NULL;
+ ResolveSupport global_mdns_support, mdns_support;
sd_bus *bus = ASSERT_PTR(userdata);
int r;
@@ -2322,6 +2343,22 @@ static int verb_mdns(int argc, char **argv, void *userdata) {
if (argc < 3)
return status_ifindex(bus, arg_ifindex, NULL, STATUS_MDNS, NULL);
+ mdns_support = resolve_support_from_string(argv[2]);
+ if (mdns_support < 0)
+ return log_error_errno(mdns_support, "Invalid mDNS setting: %s", argv[2]);
+
+ r = bus_get_property_string(bus, bus_resolve_mgr, "MulticastDNS", &error, &global_mdns_support_str);
+ if (r < 0)
+ return log_error_errno(r, "Failed to get the global mDNS support state: %s", bus_error_message(&error, r));
+
+ global_mdns_support = resolve_support_from_string(global_mdns_support_str);
+ if (global_mdns_support < 0)
+ return log_error_errno(global_mdns_support, "Received invalid global mDNS setting: %s", global_mdns_support_str);
+
+ if (global_mdns_support < mdns_support)
+ log_warning("Setting mDNS support level \"%s\" for \"%s\", but the global support level is \"%s\".",
+ argv[2], arg_ifname, global_mdns_support_str);
+
r = bus_call_method(bus, bus_resolve_mgr, "SetLinkMulticastDNS", &error, NULL, "is", arg_ifindex, argv[2]);
if (r < 0 && sd_bus_error_has_name(&error, BUS_ERROR_LINK_BUSY)) {
sd_bus_error_free(&error);
diff --git a/src/resolve/resolved-link-bus.c b/src/resolve/resolved-link-bus.c
index 5b1096daf6..9b6d14f20c 100644
--- a/src/resolve/resolved-link-bus.c
+++ b/src/resolve/resolved-link-bus.c
@@ -22,6 +22,8 @@
static BUS_DEFINE_PROPERTY_GET(property_get_dnssec_supported, "b", Link, link_dnssec_supported);
static BUS_DEFINE_PROPERTY_GET2(property_get_dnssec_mode, "s", Link, link_get_dnssec_mode, dnssec_mode_to_string);
+static BUS_DEFINE_PROPERTY_GET2(property_get_llmnr_support, "s", Link, link_get_llmnr_support, resolve_support_to_string);
+static BUS_DEFINE_PROPERTY_GET2(property_get_mdns_support, "s", Link, link_get_mdns_support, resolve_support_to_string);
static int property_get_dns_over_tls_mode(
sd_bus *bus,
@@ -864,8 +866,8 @@ static const sd_bus_vtable link_vtable[] = {
SD_BUS_PROPERTY("CurrentDNSServerEx", "(iayqs)", property_get_current_dns_server_ex, offsetof(Link, current_dns_server), 0),
SD_BUS_PROPERTY("Domains", "a(sb)", property_get_domains, 0, 0),
SD_BUS_PROPERTY("DefaultRoute", "b", property_get_default_route, 0, 0),
- SD_BUS_PROPERTY("LLMNR", "s", bus_property_get_resolve_support, offsetof(Link, llmnr_support), 0),
- SD_BUS_PROPERTY("MulticastDNS", "s", bus_property_get_resolve_support, offsetof(Link, mdns_support), 0),
+ SD_BUS_PROPERTY("LLMNR", "s", property_get_llmnr_support, 0, 0),
+ SD_BUS_PROPERTY("MulticastDNS", "s", property_get_mdns_support, 0, 0),
SD_BUS_PROPERTY("DNSOverTLS", "s", property_get_dns_over_tls_mode, 0, 0),
SD_BUS_PROPERTY("DNSSEC", "s", property_get_dnssec_mode, 0, 0),
SD_BUS_PROPERTY("DNSSECNegativeTrustAnchors", "as", property_get_ntas, 0, 0),
diff --git a/src/resolve/resolved-link.c b/src/resolve/resolved-link.c
index 5b34677cbe..d41f6f3e54 100644
--- a/src/resolve/resolved-link.c
+++ b/src/resolve/resolved-link.c
@@ -140,8 +140,7 @@ void link_allocate_scopes(Link *l) {
l->unicast_scope = dns_scope_free(l->unicast_scope);
if (link_relevant(l, AF_INET, true) &&
- l->llmnr_support != RESOLVE_SUPPORT_NO &&
- l->manager->llmnr_support != RESOLVE_SUPPORT_NO) {
+ link_get_llmnr_support(l) != RESOLVE_SUPPORT_NO) {
if (!l->llmnr_ipv4_scope) {
r = dns_scope_new(l->manager, &l->llmnr_ipv4_scope, l, DNS_PROTOCOL_LLMNR, AF_INET);
if (r < 0)
@@ -151,9 +150,7 @@ void link_allocate_scopes(Link *l) {
l->llmnr_ipv4_scope = dns_scope_free(l->llmnr_ipv4_scope);
if (link_relevant(l, AF_INET6, true) &&
- l->llmnr_support != RESOLVE_SUPPORT_NO &&
- l->manager->llmnr_support != RESOLVE_SUPPORT_NO &&
- socket_ipv6_is_supported()) {
+ link_get_llmnr_support(l) != RESOLVE_SUPPORT_NO) {
if (!l->llmnr_ipv6_scope) {
r = dns_scope_new(l->manager, &l->llmnr_ipv6_scope, l, DNS_PROTOCOL_LLMNR, AF_INET6);
if (r < 0)
@@ -163,8 +160,7 @@ void link_allocate_scopes(Link *l) {
l->llmnr_ipv6_scope = dns_scope_free(l->llmnr_ipv6_scope);
if (link_relevant(l, AF_INET, true) &&
- l->mdns_support != RESOLVE_SUPPORT_NO &&
- l->manager->mdns_support != RESOLVE_SUPPORT_NO) {
+ link_get_mdns_support(l) != RESOLVE_SUPPORT_NO) {
if (!l->mdns_ipv4_scope) {
r = dns_scope_new(l->manager, &l->mdns_ipv4_scope, l, DNS_PROTOCOL_MDNS, AF_INET);
if (r < 0)
@@ -174,8 +170,7 @@ void link_allocate_scopes(Link *l) {
l->mdns_ipv4_scope = dns_scope_free(l->mdns_ipv4_scope);
if (link_relevant(l, AF_INET6, true) &&
- l->mdns_support != RESOLVE_SUPPORT_NO &&
- l->manager->mdns_support != RESOLVE_SUPPORT_NO) {
+ link_get_mdns_support(l) != RESOLVE_SUPPORT_NO) {
if (!l->mdns_ipv6_scope) {
r = dns_scope_new(l->manager, &l->mdns_ipv6_scope, l, DNS_PROTOCOL_MDNS, AF_INET6);
if (r < 0)
@@ -192,8 +187,7 @@ void link_add_rrs(Link *l, bool force_remove) {
link_address_add_rrs(a, force_remove);
if (!force_remove &&
- l->mdns_support == RESOLVE_SUPPORT_YES &&
- l->manager->mdns_support == RESOLVE_SUPPORT_YES) {
+ link_get_mdns_support(l) == RESOLVE_SUPPORT_YES) {
if (l->mdns_ipv4_scope) {
r = dns_scope_add_dnssd_services(l->mdns_ipv4_scope);
@@ -652,13 +646,13 @@ int link_update(Link *l) {
if (r < 0)
return r;
- if (l->llmnr_support != RESOLVE_SUPPORT_NO) {
+ if (link_get_llmnr_support(l) != RESOLVE_SUPPORT_NO) {
r = manager_llmnr_start(l->manager);
if (r < 0)
return r;
}
- if (l->mdns_support != RESOLVE_SUPPORT_NO) {
+ if (link_get_mdns_support(l) != RESOLVE_SUPPORT_NO) {
r = manager_mdns_start(l->manager);
if (r < 0)
return r;
@@ -803,6 +797,24 @@ bool link_dnssec_supported(Link *l) {
return true;
}
+ResolveSupport link_get_llmnr_support(Link *link) {
+ assert(link);
+ assert(link->manager);
+
+ /* This provides the effective LLMNR support level for the link, instead of the 'internal' per-link setting. */
+
+ return MIN(link->llmnr_support, link->manager->llmnr_support);
+}
+
+ResolveSupport link_get_mdns_support(Link *link) {
+ assert(link);
+ assert(link->manager);
+
+ /* This provides the effective mDNS support level for the link, instead of the 'internal' per-link setting. */
+
+ return MIN(link->mdns_support, link->manager->mdns_support);
+}
+
int link_address_new(Link *l, LinkAddress **ret, int family, const union in_addr_union *in_addr) {
LinkAddress *a;
@@ -886,8 +898,7 @@ void link_address_add_rrs(LinkAddress *a, bool force_remove) {
if (!force_remove &&
link_address_relevant(a, true) &&
a->link->llmnr_ipv4_scope &&
- a->link->llmnr_support == RESOLVE_SUPPORT_YES &&
- a->link->manager->llmnr_support == RESOLVE_SUPPORT_YES) {
+ link_get_llmnr_support(a->link) == RESOLVE_SUPPORT_YES) {
if (!a->link->manager->llmnr_host_ipv4_key) {
a->link->manager->llmnr_host_ipv4_key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_A, a->link->manager->llmnr_hostname);
@@ -940,8 +951,7 @@ void link_address_add_rrs(LinkAddress *a, bool force_remove) {
if (!force_remove &&
link_address_relevant(a, true) &&
a->link->mdns_ipv4_scope &&
- a->link->mdns_support == RESOLVE_SUPPORT_YES &&
- a->link->manager->mdns_support == RESOLVE_SUPPORT_YES) {
+ link_get_mdns_support(a->link) == RESOLVE_SUPPORT_YES) {
if (!a->link->manager->mdns_host_ipv4_key) {
a->link->manager->mdns_host_ipv4_key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_A, a->link->manager->mdns_hostname);
if (!a->link->manager->mdns_host_ipv4_key) {
@@ -996,8 +1006,7 @@ void link_address_add_rrs(LinkAddress *a, bool force_remove) {
if (!force_remove &&
link_address_relevant(a, true) &&
a->link->llmnr_ipv6_scope &&
- a->link->llmnr_support == RESOLVE_SUPPORT_YES &&
- a->link->manager->llmnr_support == RESOLVE_SUPPORT_YES) {
+ link_get_llmnr_support(a->link) == RESOLVE_SUPPORT_YES) {
if (!a->link->manager->llmnr_host_ipv6_key) {
a->link->manager->llmnr_host_ipv6_key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_AAAA, a->link->manager->llmnr_hostname);
@@ -1050,8 +1059,7 @@ void link_address_add_rrs(LinkAddress *a, bool force_remove) {
if (!force_remove &&
link_address_relevant(a, true) &&
a->link->mdns_ipv6_scope &&
- a->link->mdns_support == RESOLVE_SUPPORT_YES &&
- a->link->manager->mdns_support == RESOLVE_SUPPORT_YES) {
+ link_get_mdns_support(a->link) == RESOLVE_SUPPORT_YES) {
if (!a->link->manager->mdns_host_ipv6_key) {
a->link->manager->mdns_host_ipv6_key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_AAAA, a->link->manager->mdns_hostname);
diff --git a/src/resolve/resolved-link.h b/src/resolve/resolved-link.h
index b5299e0b5b..d2043a1000 100644
--- a/src/resolve/resolved-link.h
+++ b/src/resolve/resolved-link.h
@@ -104,6 +104,9 @@ bool link_dnssec_supported(Link *l);
DnsOverTlsMode link_get_dns_over_tls_mode(Link *l);
+ResolveSupport link_get_llmnr_support(Link *link);
+ResolveSupport link_get_mdns_support(Link *link);
+
int link_save_user(Link *l);
int link_load_user(Link *l);
void link_remove_user(Link *l);
diff --git a/src/shared/dissect-image.c b/src/shared/dissect-image.c
index 2f19031216..1d338fe352 100644
--- a/src/shared/dissect-image.c
+++ b/src/shared/dissect-image.c
@@ -349,7 +349,7 @@ static int dissect_image(
_cleanup_(blkid_free_probep) blkid_probe b = NULL;
_cleanup_free_ char *generic_node = NULL;
sd_id128_t generic_uuid = SD_ID128_NULL;
- const char *pttype = NULL;
+ const char *pttype = NULL, *sptuuid = NULL;
blkid_partlist pl;
int r, generic_nr = -1, n_partitions;
@@ -410,7 +410,7 @@ static int dissect_image(
if ((flags & DISSECT_IMAGE_GPT_ONLY) == 0) {
/* Look for file system superblocks, unless we only shall look for GPT partition tables */
blkid_probe_enable_superblocks(b, 1);
- blkid_probe_set_superblocks_flags(b, BLKID_SUBLKS_TYPE|BLKID_SUBLKS_USAGE);
+ blkid_probe_set_superblocks_flags(b, BLKID_SUBLKS_TYPE|BLKID_SUBLKS_USAGE|BLKID_SUBLKS_UUID);
}
blkid_probe_enable_partitions(b, 1);
@@ -433,8 +433,9 @@ static int dissect_image(
(void) blkid_probe_lookup_value(b, "USAGE", &usage, NULL);
if (STRPTR_IN_SET(usage, "filesystem", "crypto")) {
_cleanup_free_ char *t = NULL, *n = NULL, *o = NULL;
- const char *fstype = NULL, *options = NULL;
+ const char *fstype = NULL, *options = NULL, *suuid = NULL;
_cleanup_close_ int mount_node_fd = -1;
+ sd_id128_t uuid = SD_ID128_NULL;
if (FLAGS_SET(flags, DISSECT_IMAGE_OPEN_PARTITION_DEVICES)) {
mount_node_fd = open_partition(devname, /* is_partition = */ false, m->loop);
@@ -444,6 +445,7 @@ static int dissect_image(
/* OK, we have found a file system, that's our root partition then. */
(void) blkid_probe_lookup_value(b, "TYPE", &fstype, NULL);
+ (void) blkid_probe_lookup_value(b, "UUID", &suuid, NULL);
if (fstype) {
t = strdup(fstype);
@@ -451,6 +453,15 @@ static int dissect_image(
return -ENOMEM;
}
+ if (suuid) {
+ /* blkid will return FAT's serial number as UUID, hence it is quite possible
+ * that parsing this will fail. We'll ignore the ID, since it's just too
+ * short to be useful as tru identifier. */
+ r = sd_id128_from_string(suuid, &uuid);
+ if (r < 0)
+ log_debug_errno(r, "Failed to parse file system UUID '%s', ignoring: %m", suuid);
+ }
+
n = strdup(devname);
if (!n)
return -ENOMEM;
@@ -467,6 +478,8 @@ static int dissect_image(
m->verity_sig_ready = m->verity_ready &&
verity->root_hash_sig;
+ m->image_uuid = uuid;
+
options = mount_options_from_designator(mount_options, PARTITION_ROOT);
if (options) {
o = strdup(options);
@@ -515,6 +528,13 @@ static int dissect_image(
return -EPROTONOSUPPORT;
}
+ (void) blkid_probe_lookup_value(b, "PTUUID", &sptuuid, NULL);
+ if (sptuuid) {
+ r = sd_id128_from_string(sptuuid, &m->image_uuid);
+ if (r < 0)
+ log_debug_errno(r, "Failed to parse partition table UUID '%s', ignoring: %m", sptuuid);
+ }
+
errno = 0;
pl = blkid_probe_get_partitions(b);
if (!pl)
diff --git a/src/shared/dissect-image.h b/src/shared/dissect-image.h
index 46675d22ab..ccdc4d6f35 100644
--- a/src/shared/dissect-image.h
+++ b/src/shared/dissect-image.h
@@ -229,6 +229,7 @@ struct DissectedImage {
/* Meta information extracted from /etc/os-release and similar */
char *image_name;
+ sd_id128_t image_uuid;
char *hostname;
sd_id128_t machine_id;
char **machine_info;
diff --git a/src/shared/format-table.c b/src/shared/format-table.c
index d333bcf90b..2a3defeb7c 100644
--- a/src/shared/format-table.c
+++ b/src/shared/format-table.c
@@ -2627,10 +2627,10 @@ static int table_data_to_json(TableData *d, JsonVariant **ret) {
return json_variant_new_array_bytes(ret, &d->address, FAMILY_ADDRESS_SIZE(AF_INET6));
case TABLE_ID128:
- return json_variant_new_string(ret, SD_ID128_TO_STRING(d->id128));
+ return json_variant_new_id128(ret, d->id128);
case TABLE_UUID:
- return json_variant_new_string(ret, SD_ID128_TO_UUID_STRING(d->id128));
+ return json_variant_new_uuid(ret, d->id128);
case TABLE_UID:
if (!uid_is_valid(d->uid))
diff --git a/src/shared/json.c b/src/shared/json.c
index eda7bb1956..94d7b31557 100644
--- a/src/shared/json.c
+++ b/src/shared/json.c
@@ -481,6 +481,10 @@ int json_variant_new_id128(JsonVariant **ret, sd_id128_t id) {
return json_variant_new_string(ret, SD_ID128_TO_STRING(id));
}
+int json_variant_new_uuid(JsonVariant **ret, sd_id128_t id) {
+ return json_variant_new_string(ret, SD_ID128_TO_UUID_STRING(id));
+}
+
static void json_variant_set(JsonVariant *a, JsonVariant *b) {
assert(a);
@@ -3609,7 +3613,8 @@ int json_buildv(JsonVariant **ret, va_list ap) {
break;
}
- case _JSON_BUILD_ID128: {
+ case _JSON_BUILD_ID128:
+ case _JSON_BUILD_UUID: {
const sd_id128_t *id;
if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
@@ -3620,7 +3625,9 @@ int json_buildv(JsonVariant **ret, va_list ap) {
assert_se(id = va_arg(ap, sd_id128_t*));
if (current->n_suppress == 0) {
- r = json_variant_new_id128(&add, *id);
+ r = command == _JSON_BUILD_ID128 ?
+ json_variant_new_id128(&add, *id) :
+ json_variant_new_uuid(&add, *id);
if (r < 0)
goto finish;
}
diff --git a/src/shared/json.h b/src/shared/json.h
index 5993e05299..c5f052a9d5 100644
--- a/src/shared/json.h
+++ b/src/shared/json.h
@@ -75,6 +75,7 @@ int json_variant_new_array_strv(JsonVariant **ret, char **l);
int json_variant_new_object(JsonVariant **ret, JsonVariant **array, size_t n);
int json_variant_new_null(JsonVariant **ret);
int json_variant_new_id128(JsonVariant **ret, sd_id128_t id);
+int json_variant_new_uuid(JsonVariant **ret, sd_id128_t id);
static inline int json_variant_new_string(JsonVariant **ret, const char *s) {
return json_variant_new_stringn(ret, s, SIZE_MAX);
@@ -251,6 +252,7 @@ enum {
_JSON_BUILD_HEX,
_JSON_BUILD_OCTESCAPE,
_JSON_BUILD_ID128,
+ _JSON_BUILD_UUID,
_JSON_BUILD_BYTE_ARRAY,
_JSON_BUILD_HW_ADDR,
_JSON_BUILD_PAIR_UNSIGNED_NON_ZERO,
@@ -288,6 +290,7 @@ enum {
#define JSON_BUILD_HEX(p, n) _JSON_BUILD_HEX, (const void*) { p }, (size_t) { n }
#define JSON_BUILD_OCTESCAPE(p, n) _JSON_BUILD_OCTESCAPE, (const void*) { p }, (size_t) { n }
#define JSON_BUILD_ID128(id) _JSON_BUILD_ID128, (const sd_id128_t*) { &(id) }
+#define JSON_BUILD_UUID(id) _JSON_BUILD_UUID, (const sd_id128_t*) { &(id) }
#define JSON_BUILD_BYTE_ARRAY(v, n) _JSON_BUILD_BYTE_ARRAY, (const void*) { v }, (size_t) { n }
#define JSON_BUILD_CONST_STRING(s) _JSON_BUILD_VARIANT, JSON_VARIANT_STRING_CONST(s)
#define JSON_BUILD_IN4_ADDR(v) JSON_BUILD_BYTE_ARRAY((const struct in_addr*) { v }, sizeof(struct in_addr))
@@ -313,6 +316,7 @@ enum {
#define JSON_BUILD_PAIR_BASE64(name, p, n) JSON_BUILD_PAIR(name, JSON_BUILD_BASE64(p, n))
#define JSON_BUILD_PAIR_HEX(name, p, n) JSON_BUILD_PAIR(name, JSON_BUILD_HEX(p, n))
#define JSON_BUILD_PAIR_ID128(name, id) JSON_BUILD_PAIR(name, JSON_BUILD_ID128(id))
+#define JSON_BUILD_PAIR_UUID(name, id) JSON_BUILD_PAIR(name, JSON_BUILD_UUID(id))
#define JSON_BUILD_PAIR_BYTE_ARRAY(name, v, n) JSON_BUILD_PAIR(name, JSON_BUILD_BYTE_ARRAY(v, n))
#define JSON_BUILD_PAIR_IN4_ADDR(name, v) JSON_BUILD_PAIR(name, JSON_BUILD_IN4_ADDR(v))
#define JSON_BUILD_PAIR_IN6_ADDR(name, v) JSON_BUILD_PAIR(name, JSON_BUILD_IN6_ADDR(v))
diff --git a/src/shared/resolve-util.h b/src/shared/resolve-util.h
index d9ab387301..e58173d864 100644
--- a/src/shared/resolve-util.h
+++ b/src/shared/resolve-util.h
@@ -25,10 +25,11 @@ typedef enum ResolveSupport ResolveSupport;
typedef enum DnssecMode DnssecMode;
typedef enum DnsOverTlsMode DnsOverTlsMode;
+/* Do not change the order, see link_get_llmnr_support() or link_get_mdns_support(). */
enum ResolveSupport {
RESOLVE_SUPPORT_NO,
- RESOLVE_SUPPORT_YES,
RESOLVE_SUPPORT_RESOLVE,
+ RESOLVE_SUPPORT_YES,
_RESOLVE_SUPPORT_MAX,
_RESOLVE_SUPPORT_INVALID = -EINVAL,
};
diff --git a/test/units/testsuite-58.sh b/test/units/testsuite-58.sh
index f41069ee04..5a515d9c01 100755
--- a/test/units/testsuite-58.sh
+++ b/test/units/testsuite-58.sh
@@ -14,6 +14,9 @@ fi
export SYSTEMD_LOG_LEVEL=debug
export PAGER=cat
+# Disable use of special glyphs such as →
+export SYSTEMD_UTF8=0
+
seed=750b6cd5c4ae4012a15e7be3c29e6a47
if ! systemd-detect-virt --quiet --container; then
@@ -327,7 +330,7 @@ EOF
output=$(systemd-repart --definitions="$defs" --empty=create --size=100M --json=pretty "$imgs/zzz")
- diff <(echo "$output") - <<EOF
+ diff -u <(echo "$output") - <<EOF
[
{
"type" : "swap",
@@ -338,10 +341,10 @@ EOF
"offset" : 1048576,
"old_size" : 0,
"raw_size" : 33554432,
- "size" : "→ 32.0M",
+ "size" : "-> 32.0M",
"old_padding" : 0,
"raw_padding" : 0,
- "padding" : "→ 0B",
+ "padding" : "-> 0B",
"activity" : "create",
"drop-in_files" : [
"$defs/root.conf.d/override1.conf",
@@ -382,7 +385,7 @@ EOF
output=$(systemd-repart --definitions="$defs/1" --definitions="$defs/2" --empty=create --size=100M --json=pretty "$imgs/zzz")
- diff <(echo "$output") - <<EOF
+ diff -u <(echo "$output") - <<EOF
[
{
"type" : "swap",
@@ -393,10 +396,10 @@ EOF
"offset" : 1048576,
"old_size" : 0,
"raw_size" : 33554432,
- "size" : "→ 32.0M",
+ "size" : "-> 32.0M",
"old_padding" : 0,
"raw_padding" : 0,
- "padding" : "→ 0B",
+ "padding" : "-> 0B",
"activity" : "create"
},
{
@@ -408,10 +411,10 @@ EOF
"offset" : 34603008,
"old_size" : 0,
"raw_size" : 33554432,
- "size" : "→ 32.0M",
+ "size" : "-> 32.0M",
"old_padding" : 0,
"raw_padding" : 0,
- "padding" : "→ 0B",
+ "padding" : "-> 0B",
"activity" : "create"
}
]
@@ -766,9 +769,10 @@ EOF
roothash=$(jq -r ".[] | select(.type == \"root-${architecture}-verity\") | .roothash" <<< "$output")
- # Check that we can dissect, mount and unmount a repart verity image.
+ # Check that we can dissect, mount and unmount a repart verity image. (and that the image UUID is deterministic)
systemd-dissect "$imgs/verity" --root-hash "$roothash"
+ systemd-dissect "$imgs/verity" --root-hash "$roothash" --json=short | grep -q '"imageUuid":"1d2ce291-7cce-4f7d-bc83-fdb49ad74ebd"'
systemd-dissect "$imgs/verity" --root-hash "$roothash" -M "$imgs/mnt"
systemd-dissect -U "$imgs/mnt"
}
diff --git a/test/units/testsuite-75.sh b/test/units/testsuite-75.sh
index 04a8b6e9cc..1a656fcdc1 100755
--- a/test/units/testsuite-75.sh
+++ b/test/units/testsuite-75.sh
@@ -55,6 +55,79 @@ echo nameserver 10.0.3.1 10.0.3.2 | "$RESOLVCONF" -a hoge.inet.ipsec.192.168.35
echo nameserver 10.0.3.3 10.0.3.4 | "$RESOLVCONF" -a hoge.foo.dhcp
assert_in '10.0.3.1 10.0.3.2' "$(resolvectl dns hoge)"
assert_in '10.0.3.3 10.0.3.4' "$(resolvectl dns hoge.foo)"
+
+# Tests for mDNS and LLMNR settings
+mkdir -p /run/systemd/resolved.conf.d
+{
+ echo "[Resolve]"
+ echo "MulticastDNS=yes"
+ echo "LLMNR=yes"
+} >/run/systemd/resolved.conf.d/mdns-llmnr.conf
+systemctl restart systemd-resolved.service
+systemctl service-log-level systemd-resolved.service debug
+# make sure networkd is not running.
+systemctl stop systemd-networkd.service
+# defaults to yes (both the global and per-link settings are yes)
+assert_in 'yes' "$(resolvectl mdns hoge)"
+assert_in 'yes' "$(resolvectl llmnr hoge)"
+# set per-link setting
+resolvectl mdns hoge yes
+resolvectl llmnr hoge yes
+assert_in 'yes' "$(resolvectl mdns hoge)"
+assert_in 'yes' "$(resolvectl llmnr hoge)"
+resolvectl mdns hoge resolve
+resolvectl llmnr hoge resolve
+assert_in 'resolve' "$(resolvectl mdns hoge)"
+assert_in 'resolve' "$(resolvectl llmnr hoge)"
+resolvectl mdns hoge no
+resolvectl llmnr hoge no
+assert_in 'no' "$(resolvectl mdns hoge)"
+assert_in 'no' "$(resolvectl llmnr hoge)"
+# downgrade global setting to resolve
+{
+ echo "[Resolve]"
+ echo "MulticastDNS=resolve"
+ echo "LLMNR=resolve"
+} >/run/systemd/resolved.conf.d/mdns-llmnr.conf
+systemctl restart systemd-resolved.service
+systemctl service-log-level systemd-resolved.service debug
+# set per-link setting
+resolvectl mdns hoge yes
+resolvectl llmnr hoge yes
+assert_in 'resolve' "$(resolvectl mdns hoge)"
+assert_in 'resolve' "$(resolvectl llmnr hoge)"
+resolvectl mdns hoge resolve
+resolvectl llmnr hoge resolve
+assert_in 'resolve' "$(resolvectl mdns hoge)"
+assert_in 'resolve' "$(resolvectl llmnr hoge)"
+resolvectl mdns hoge no
+resolvectl llmnr hoge no
+assert_in 'no' "$(resolvectl mdns hoge)"
+assert_in 'no' "$(resolvectl llmnr hoge)"
+# downgrade global setting to no
+{
+ echo "[Resolve]"
+ echo "MulticastDNS=no"
+ echo "LLMNR=no"
+} >/run/systemd/resolved.conf.d/mdns-llmnr.conf
+systemctl restart systemd-resolved.service
+systemctl service-log-level systemd-resolved.service debug
+# set per-link setting
+resolvectl mdns hoge yes
+resolvectl llmnr hoge yes
+assert_in 'no' "$(resolvectl mdns hoge)"
+assert_in 'no' "$(resolvectl llmnr hoge)"
+resolvectl mdns hoge resolve
+resolvectl llmnr hoge resolve
+assert_in 'no' "$(resolvectl mdns hoge)"
+assert_in 'no' "$(resolvectl llmnr hoge)"
+resolvectl mdns hoge no
+resolvectl llmnr hoge no
+assert_in 'no' "$(resolvectl mdns hoge)"
+assert_in 'no' "$(resolvectl llmnr hoge)"
+
+# Cleanup
+rm -f /run/systemd/resolved.conf.d/mdns-llmnr.conf
ip link del hoge
ip link del hoge.foo
@@ -79,11 +152,13 @@ DNSSEC=allow-downgrade
DNS=10.0.0.1
EOF
+mkdir -p /run/systemd/resolved.conf.d
{
+ echo "[Resolve]"
echo "FallbackDNS="
echo "DNSSEC=allow-downgrade"
echo "DNSOverTLS=opportunistic"
-} >>/etc/systemd/resolved.conf
+} >/run/systemd/resolved.conf.d/test.conf
ln -svf /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf
# Override the default NTA list, which turns off DNSSEC validation for (among
# others) the test. domain